[Pkg-javascript-commits] [dojo] 01/18: Imported Upstream version 1.3.2+dfsg

David Prévot taffit at alioth.debian.org
Fri Oct 25 19:58:57 UTC 2013


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository dojo.

commit d897e1f6c653518c9481e4a489b3353b0d56d080
Author: David Prévot <taffit at debian.org>
Date:   Thu Oct 24 18:19:58 2013 -0400

    Imported Upstream version 1.3.2+dfsg
---
 dijit/CheckedMenuItem.js                           |   24 +
 dijit/ColorPalette.js                              |  110 +
 dijit/Declaration.js                               |   36 +
 dijit/Dialog.js                                    |  211 +
 dijit/DialogUnderlay.js                            |   45 +
 dijit/Editor.js                                    |  356 +
 dijit/InlineEditBox.js                             |  208 +
 dijit/LICENSE                                      |  195 +
 dijit/Menu.js                                      |  218 +
 dijit/MenuBar.js                                   |   33 +
 dijit/MenuBarItem.js                               |   14 +
 dijit/MenuItem.js                                  |   58 +
 dijit/MenuSeparator.js                             |   19 +
 dijit/PopupMenuBarItem.js                          |   14 +
 dijit/PopupMenuItem.js                             |   40 +
 dijit/ProgressBar.js                               |   51 +
 dijit/TitlePane.js                                 |   90 +
 dijit/Toolbar.js                                   |   24 +
 dijit/ToolbarSeparator.js                          |   18 +
 dijit/Tooltip.js                                   |  160 +
 dijit/TooltipDialog.js                             |   64 +
 dijit/Tree.js                                      |  535 +
 dijit/_Calendar.js                                 |  179 +
 dijit/_Contained.js                                |   41 +
 dijit/_Container.js                                |   73 +
 dijit/_DialogMixin.js                              |   26 +
 dijit/_KeyNavContainer.js                          |  130 +
 dijit/_Templated.js                                |  156 +
 dijit/_TimePicker.js                               |  257 +
 dijit/_Widget.js                                   |  301 +
 dijit/_base.js                                     |   20 +
 dijit/_base/focus.js                               |  238 +
 dijit/_base/manager.js                             |  160 +
 dijit/_base/place.js                               |   91 +
 dijit/_base/popup.js                               |  150 +
 dijit/_base/scroll.js                              |  169 +
 dijit/_base/sniff.js                               |   34 +
 dijit/_base/typematic.js                           |   85 +
 dijit/_base/wai.js                                 |   79 +
 dijit/_base/window.js                              |   20 +
 dijit/_editor/RichText.js                          | 1013 +
 dijit/_editor/_Plugin.js                           |   78 +
 dijit/_editor/html.js                              |  106 +
 dijit/_editor/nls/FontChoice.js                    |    1 +
 dijit/_editor/nls/LinkDialog.js                    |    1 +
 dijit/_editor/nls/ar/FontChoice.js                 |    1 +
 dijit/_editor/nls/ar/LinkDialog.js                 |    1 +
 dijit/_editor/nls/ar/commands.js                   |    1 +
 dijit/_editor/nls/ca/FontChoice.js                 |    1 +
 dijit/_editor/nls/ca/LinkDialog.js                 |    1 +
 dijit/_editor/nls/ca/commands.js                   |    1 +
 dijit/_editor/nls/commands.js                      |    1 +
 dijit/_editor/nls/cs/FontChoice.js                 |    1 +
 dijit/_editor/nls/cs/LinkDialog.js                 |    1 +
 dijit/_editor/nls/cs/commands.js                   |    1 +
 dijit/_editor/nls/da/FontChoice.js                 |    1 +
 dijit/_editor/nls/da/LinkDialog.js                 |    1 +
 dijit/_editor/nls/da/commands.js                   |    1 +
 dijit/_editor/nls/de/FontChoice.js                 |    1 +
 dijit/_editor/nls/de/LinkDialog.js                 |    1 +
 dijit/_editor/nls/de/commands.js                   |    1 +
 dijit/_editor/nls/el/FontChoice.js                 |    1 +
 dijit/_editor/nls/el/LinkDialog.js                 |    1 +
 dijit/_editor/nls/el/commands.js                   |    1 +
 dijit/_editor/nls/es/FontChoice.js                 |    1 +
 dijit/_editor/nls/es/LinkDialog.js                 |    1 +
 dijit/_editor/nls/es/commands.js                   |    1 +
 dijit/_editor/nls/fi/FontChoice.js                 |    1 +
 dijit/_editor/nls/fi/LinkDialog.js                 |    1 +
 dijit/_editor/nls/fi/commands.js                   |    1 +
 dijit/_editor/nls/fr/FontChoice.js                 |    1 +
 dijit/_editor/nls/fr/LinkDialog.js                 |    1 +
 dijit/_editor/nls/fr/commands.js                   |    1 +
 dijit/_editor/nls/he/FontChoice.js                 |    1 +
 dijit/_editor/nls/he/LinkDialog.js                 |    1 +
 dijit/_editor/nls/he/commands.js                   |    1 +
 dijit/_editor/nls/hu/FontChoice.js                 |    1 +
 dijit/_editor/nls/hu/LinkDialog.js                 |    1 +
 dijit/_editor/nls/hu/commands.js                   |    1 +
 dijit/_editor/nls/it/FontChoice.js                 |    1 +
 dijit/_editor/nls/it/LinkDialog.js                 |    1 +
 dijit/_editor/nls/it/commands.js                   |    1 +
 dijit/_editor/nls/ja/FontChoice.js                 |    1 +
 dijit/_editor/nls/ja/LinkDialog.js                 |    1 +
 dijit/_editor/nls/ja/commands.js                   |    1 +
 dijit/_editor/nls/ko/FontChoice.js                 |    1 +
 dijit/_editor/nls/ko/LinkDialog.js                 |    1 +
 dijit/_editor/nls/ko/commands.js                   |    1 +
 dijit/_editor/nls/nb/FontChoice.js                 |    1 +
 dijit/_editor/nls/nb/LinkDialog.js                 |    1 +
 dijit/_editor/nls/nb/commands.js                   |    1 +
 dijit/_editor/nls/nl/FontChoice.js                 |    1 +
 dijit/_editor/nls/nl/LinkDialog.js                 |    1 +
 dijit/_editor/nls/nl/commands.js                   |    1 +
 dijit/_editor/nls/pl/FontChoice.js                 |    1 +
 dijit/_editor/nls/pl/LinkDialog.js                 |    1 +
 dijit/_editor/nls/pl/commands.js                   |    1 +
 dijit/_editor/nls/pt-pt/FontChoice.js              |    1 +
 dijit/_editor/nls/pt-pt/LinkDialog.js              |    1 +
 dijit/_editor/nls/pt-pt/commands.js                |    1 +
 dijit/_editor/nls/pt/FontChoice.js                 |    1 +
 dijit/_editor/nls/pt/LinkDialog.js                 |    1 +
 dijit/_editor/nls/pt/commands.js                   |    1 +
 dijit/_editor/nls/ru/FontChoice.js                 |    1 +
 dijit/_editor/nls/ru/LinkDialog.js                 |    1 +
 dijit/_editor/nls/ru/commands.js                   |    1 +
 dijit/_editor/nls/sk/FontChoice.js                 |    1 +
 dijit/_editor/nls/sk/LinkDialog.js                 |    1 +
 dijit/_editor/nls/sk/commands.js                   |    1 +
 dijit/_editor/nls/sl/FontChoice.js                 |    1 +
 dijit/_editor/nls/sl/LinkDialog.js                 |    1 +
 dijit/_editor/nls/sl/commands.js                   |    1 +
 dijit/_editor/nls/sv/FontChoice.js                 |    1 +
 dijit/_editor/nls/sv/LinkDialog.js                 |    1 +
 dijit/_editor/nls/sv/commands.js                   |    1 +
 dijit/_editor/nls/th/FontChoice.js                 |    1 +
 dijit/_editor/nls/th/LinkDialog.js                 |    1 +
 dijit/_editor/nls/th/commands.js                   |    1 +
 dijit/_editor/nls/tr/FontChoice.js                 |    1 +
 dijit/_editor/nls/tr/LinkDialog.js                 |    1 +
 dijit/_editor/nls/tr/commands.js                   |    1 +
 dijit/_editor/nls/zh-tw/FontChoice.js              |    1 +
 dijit/_editor/nls/zh-tw/LinkDialog.js              |    1 +
 dijit/_editor/nls/zh-tw/commands.js                |    1 +
 dijit/_editor/nls/zh/FontChoice.js                 |    1 +
 dijit/_editor/nls/zh/LinkDialog.js                 |    1 +
 dijit/_editor/nls/zh/commands.js                   |    1 +
 dijit/_editor/plugins/AlwaysShowToolbar.js         |  121 +
 dijit/_editor/plugins/EnterKeyHandling.js          |  395 +
 dijit/_editor/plugins/FontChoice.js                |  111 +
 dijit/_editor/plugins/LinkDialog.js                |   74 +
 dijit/_editor/plugins/TabIndent.js                 |   51 +
 dijit/_editor/plugins/TextColor.js                 |   29 +
 dijit/_editor/plugins/ToggleDir.js                 |   31 +
 dijit/_editor/range.js                             |  453 +
 dijit/_editor/selection.js                         |  202 +
 dijit/_tree/dndContainer.js                        |   51 +
 dijit/_tree/dndSelector.js                         |  131 +
 dijit/_tree/dndSource.js                           |  231 +
 dijit/dijit-all.js                                 |   16 +
 dijit/dijit-all.js.uncompressed.js                 |22089 ++++++++++++++++++++
 dijit/dijit.js                                     |   16 +
 dijit/dijit.js.uncompressed.js                     | 4977 +++++
 dijit/form/Button.js                               |  232 +
 dijit/form/CheckBox.js                             |   65 +
 dijit/form/ComboBox.js                             |  601 +
 dijit/form/ComboButton.js                          |   12 +
 dijit/form/CurrencyTextBox.js                      |   17 +
 dijit/form/DateTextBox.js                          |   14 +
 dijit/form/DropDownButton.js                       |   12 +
 dijit/form/FilteringSelect.js                      |  102 +
 dijit/form/Form.js                                 |   62 +
 dijit/form/HorizontalRule.js                       |   38 +
 dijit/form/HorizontalRuleLabels.js                 |   38 +
 dijit/form/HorizontalSlider.js                     |  202 +
 dijit/form/MappedTextBox.js                        |   12 +
 dijit/form/MultiSelect.js                          |   49 +
 dijit/form/NumberSpinner.js                        |   38 +
 dijit/form/NumberTextBox.js                        |   82 +
 dijit/form/RadioButton.js                          |   12 +
 dijit/form/RangeBoundTextBox.js                    |   12 +
 dijit/form/SimpleTextarea.js                       |   57 +
 dijit/form/Slider.js                               |   18 +
 dijit/form/TextBox.js                              |  152 +
 dijit/form/Textarea.js                             |   98 +
 dijit/form/TimeTextBox.js                          |   14 +
 dijit/form/ToggleButton.js                         |   12 +
 dijit/form/ValidationTextBox.js                    |  207 +
 dijit/form/VerticalRule.js                         |   13 +
 dijit/form/VerticalRuleLabels.js                   |   15 +
 dijit/form/VerticalSlider.js                       |   39 +
 dijit/form/_DateTimeTextBox.js                     |  128 +
 dijit/form/_FormMixin.js                           |  148 +
 dijit/form/_FormWidget.js                          |  214 +
 dijit/form/_Spinner.js                             |   77 +
 dijit/form/nls/ComboBox.js                         |    1 +
 dijit/form/nls/Textarea.js                         |    1 +
 dijit/form/nls/ar/ComboBox.js                      |    1 +
 dijit/form/nls/ar/Textarea.js                      |    1 +
 dijit/form/nls/ar/validate.js                      |    1 +
 dijit/form/nls/ca/ComboBox.js                      |    1 +
 dijit/form/nls/ca/Textarea.js                      |    1 +
 dijit/form/nls/ca/validate.js                      |    1 +
 dijit/form/nls/cs/ComboBox.js                      |    1 +
 dijit/form/nls/cs/Textarea.js                      |    1 +
 dijit/form/nls/cs/validate.js                      |    1 +
 dijit/form/nls/da/ComboBox.js                      |    1 +
 dijit/form/nls/da/Textarea.js                      |    1 +
 dijit/form/nls/da/validate.js                      |    1 +
 dijit/form/nls/de/ComboBox.js                      |    1 +
 dijit/form/nls/de/Textarea.js                      |    1 +
 dijit/form/nls/de/validate.js                      |    1 +
 dijit/form/nls/el/ComboBox.js                      |    1 +
 dijit/form/nls/el/Textarea.js                      |    1 +
 dijit/form/nls/el/validate.js                      |    1 +
 dijit/form/nls/es/ComboBox.js                      |    1 +
 dijit/form/nls/es/Textarea.js                      |    1 +
 dijit/form/nls/es/validate.js                      |    1 +
 dijit/form/nls/fi/ComboBox.js                      |    1 +
 dijit/form/nls/fi/Textarea.js                      |    1 +
 dijit/form/nls/fi/validate.js                      |    1 +
 dijit/form/nls/fr/ComboBox.js                      |    1 +
 dijit/form/nls/fr/Textarea.js                      |    1 +
 dijit/form/nls/fr/validate.js                      |    1 +
 dijit/form/nls/he/ComboBox.js                      |    1 +
 dijit/form/nls/he/Textarea.js                      |    1 +
 dijit/form/nls/he/validate.js                      |    1 +
 dijit/form/nls/hu/ComboBox.js                      |    1 +
 dijit/form/nls/hu/Textarea.js                      |    1 +
 dijit/form/nls/hu/validate.js                      |    1 +
 dijit/form/nls/it/ComboBox.js                      |    1 +
 dijit/form/nls/it/Textarea.js                      |    1 +
 dijit/form/nls/it/validate.js                      |    1 +
 dijit/form/nls/ja/ComboBox.js                      |    1 +
 dijit/form/nls/ja/Textarea.js                      |    1 +
 dijit/form/nls/ja/validate.js                      |    1 +
 dijit/form/nls/ko/ComboBox.js                      |    1 +
 dijit/form/nls/ko/Textarea.js                      |    1 +
 dijit/form/nls/ko/validate.js                      |    1 +
 dijit/form/nls/nb/ComboBox.js                      |    1 +
 dijit/form/nls/nb/Textarea.js                      |    1 +
 dijit/form/nls/nb/validate.js                      |    1 +
 dijit/form/nls/nl/ComboBox.js                      |    1 +
 dijit/form/nls/nl/Textarea.js                      |    1 +
 dijit/form/nls/nl/validate.js                      |    1 +
 dijit/form/nls/pl/ComboBox.js                      |    1 +
 dijit/form/nls/pl/Textarea.js                      |    1 +
 dijit/form/nls/pl/validate.js                      |    1 +
 dijit/form/nls/pt-pt/ComboBox.js                   |    1 +
 dijit/form/nls/pt-pt/Textarea.js                   |    1 +
 dijit/form/nls/pt-pt/validate.js                   |    1 +
 dijit/form/nls/pt/ComboBox.js                      |    1 +
 dijit/form/nls/pt/Textarea.js                      |    1 +
 dijit/form/nls/pt/validate.js                      |    1 +
 dijit/form/nls/ru/ComboBox.js                      |    1 +
 dijit/form/nls/ru/Textarea.js                      |    1 +
 dijit/form/nls/ru/validate.js                      |    1 +
 dijit/form/nls/sk/ComboBox.js                      |    1 +
 dijit/form/nls/sk/Textarea.js                      |    1 +
 dijit/form/nls/sk/validate.js                      |    1 +
 dijit/form/nls/sl/ComboBox.js                      |    1 +
 dijit/form/nls/sl/Textarea.js                      |    1 +
 dijit/form/nls/sl/validate.js                      |    1 +
 dijit/form/nls/sv/ComboBox.js                      |    1 +
 dijit/form/nls/sv/Textarea.js                      |    1 +
 dijit/form/nls/sv/validate.js                      |    1 +
 dijit/form/nls/th/ComboBox.js                      |    1 +
 dijit/form/nls/th/Textarea.js                      |    1 +
 dijit/form/nls/th/validate.js                      |    1 +
 dijit/form/nls/tr/ComboBox.js                      |    1 +
 dijit/form/nls/tr/Textarea.js                      |    1 +
 dijit/form/nls/tr/validate.js                      |    1 +
 dijit/form/nls/validate.js                         |    1 +
 dijit/form/nls/zh-tw/ComboBox.js                   |    1 +
 dijit/form/nls/zh-tw/Textarea.js                   |    1 +
 dijit/form/nls/zh-tw/validate.js                   |    1 +
 dijit/form/nls/zh/ComboBox.js                      |    1 +
 dijit/form/nls/zh/Textarea.js                      |    1 +
 dijit/form/nls/zh/validate.js                      |    1 +
 dijit/layout/AccordionContainer.js                 |  158 +
 dijit/layout/AccordionPane.js                      |   16 +
 dijit/layout/BorderContainer.js                    |  346 +
 dijit/layout/ContentPane.js                        |  256 +
 dijit/layout/LayoutContainer.js                    |   28 +
 dijit/layout/LinkPane.js                           |   20 +
 dijit/layout/SplitContainer.js                     |  349 +
 dijit/layout/StackContainer.js                     |  147 +
 dijit/layout/StackController.js                    |  176 +
 dijit/layout/TabContainer.js                       |   63 +
 dijit/layout/TabController.js                      |   47 +
 dijit/layout/_LayoutWidget.js                      |  133 +
 dijit/nls/ar/common.js                             |    1 +
 dijit/nls/ar/loading.js                            |    1 +
 dijit/nls/ca/common.js                             |    1 +
 dijit/nls/ca/loading.js                            |    1 +
 dijit/nls/common.js                                |    1 +
 dijit/nls/cs/common.js                             |    1 +
 dijit/nls/cs/loading.js                            |    1 +
 dijit/nls/da/common.js                             |    1 +
 dijit/nls/da/loading.js                            |    1 +
 dijit/nls/de/common.js                             |    1 +
 dijit/nls/de/loading.js                            |    1 +
 dijit/nls/dijit-all_ROOT.js                        |    1 +
 dijit/nls/dijit-all_ar.js                          |    1 +
 dijit/nls/dijit-all_ca.js                          |    1 +
 dijit/nls/dijit-all_cs.js                          |    1 +
 dijit/nls/dijit-all_da.js                          |    1 +
 dijit/nls/dijit-all_de-de.js                       |    1 +
 dijit/nls/dijit-all_de.js                          |    1 +
 dijit/nls/dijit-all_el.js                          |    1 +
 dijit/nls/dijit-all_en-gb.js                       |    1 +
 dijit/nls/dijit-all_en-us.js                       |    1 +
 dijit/nls/dijit-all_en.js                          |    1 +
 dijit/nls/dijit-all_es-es.js                       |    1 +
 dijit/nls/dijit-all_es.js                          |    1 +
 dijit/nls/dijit-all_fi-fi.js                       |    1 +
 dijit/nls/dijit-all_fi.js                          |    1 +
 dijit/nls/dijit-all_fr-fr.js                       |    1 +
 dijit/nls/dijit-all_fr.js                          |    1 +
 dijit/nls/dijit-all_he-il.js                       |    1 +
 dijit/nls/dijit-all_he.js                          |    1 +
 dijit/nls/dijit-all_hu.js                          |    1 +
 dijit/nls/dijit-all_it-it.js                       |    1 +
 dijit/nls/dijit-all_it.js                          |    1 +
 dijit/nls/dijit-all_ja-jp.js                       |    1 +
 dijit/nls/dijit-all_ja.js                          |    1 +
 dijit/nls/dijit-all_ko-kr.js                       |    1 +
 dijit/nls/dijit-all_ko.js                          |    1 +
 dijit/nls/dijit-all_nl-nl.js                       |    1 +
 dijit/nls/dijit-all_nl.js                          |    1 +
 dijit/nls/dijit-all_no.js                          |    1 +
 dijit/nls/dijit-all_pl.js                          |    1 +
 dijit/nls/dijit-all_pt-br.js                       |    1 +
 dijit/nls/dijit-all_pt-pt.js                       |    1 +
 dijit/nls/dijit-all_pt.js                          |    1 +
 dijit/nls/dijit-all_ru.js                          |    1 +
 dijit/nls/dijit-all_sk.js                          |    1 +
 dijit/nls/dijit-all_sl.js                          |    1 +
 dijit/nls/dijit-all_sv.js                          |    1 +
 dijit/nls/dijit-all_th.js                          |    1 +
 dijit/nls/dijit-all_tr.js                          |    1 +
 dijit/nls/dijit-all_xx.js                          |    1 +
 dijit/nls/dijit-all_zh-cn.js                       |    1 +
 dijit/nls/dijit-all_zh-tw.js                       |    1 +
 dijit/nls/dijit-all_zh.js                          |    1 +
 dijit/nls/el/common.js                             |    1 +
 dijit/nls/el/loading.js                            |    1 +
 dijit/nls/es/common.js                             |    1 +
 dijit/nls/es/loading.js                            |    1 +
 dijit/nls/fi/common.js                             |    1 +
 dijit/nls/fi/loading.js                            |    1 +
 dijit/nls/fr/common.js                             |    1 +
 dijit/nls/fr/loading.js                            |    1 +
 dijit/nls/he/common.js                             |    1 +
 dijit/nls/he/loading.js                            |    1 +
 dijit/nls/hu/common.js                             |    1 +
 dijit/nls/hu/loading.js                            |    1 +
 dijit/nls/it/common.js                             |    1 +
 dijit/nls/it/loading.js                            |    1 +
 dijit/nls/ja/common.js                             |    1 +
 dijit/nls/ja/loading.js                            |    1 +
 dijit/nls/ko/common.js                             |    1 +
 dijit/nls/ko/loading.js                            |    1 +
 dijit/nls/loading.js                               |    1 +
 dijit/nls/nb/common.js                             |    1 +
 dijit/nls/nb/loading.js                            |    1 +
 dijit/nls/nl/common.js                             |    1 +
 dijit/nls/nl/loading.js                            |    1 +
 dijit/nls/pl/common.js                             |    1 +
 dijit/nls/pl/loading.js                            |    1 +
 dijit/nls/pt-pt/common.js                          |    1 +
 dijit/nls/pt-pt/loading.js                         |    1 +
 dijit/nls/pt/common.js                             |    1 +
 dijit/nls/pt/loading.js                            |    1 +
 dijit/nls/ru/common.js                             |    1 +
 dijit/nls/ru/loading.js                            |    1 +
 dijit/nls/sk/common.js                             |    1 +
 dijit/nls/sk/loading.js                            |    1 +
 dijit/nls/sl/common.js                             |    1 +
 dijit/nls/sl/loading.js                            |    1 +
 dijit/nls/sv/common.js                             |    1 +
 dijit/nls/sv/loading.js                            |    1 +
 dijit/nls/th/common.js                             |    1 +
 dijit/nls/th/loading.js                            |    1 +
 dijit/nls/tr/common.js                             |    1 +
 dijit/nls/tr/loading.js                            |    1 +
 dijit/nls/zh-tw/common.js                          |    1 +
 dijit/nls/zh-tw/loading.js                         |    1 +
 dijit/nls/zh/common.js                             |    1 +
 dijit/nls/zh/loading.js                            |    1 +
 dijit/resources/_modules.js                        |    7 +
 dijit/robot.js                                     |   19 +
 dijit/robotx.js                                    |   24 +
 dijit/themes/a11y/README.txt                       |    3 +
 dijit/themes/a11y/colors3x4.png                    |  Bin 0 -> 786 bytes
 dijit/themes/a11y/colors7x10.png                   |  Bin 0 -> 2641 bytes
 dijit/themes/a11y/indeterminate_progress.gif       |  Bin 0 -> 2907 bytes
 dijit/themes/dijit.css                             | 1301 ++
 dijit/themes/dijit_rtl.css                         |   76 +
 dijit/themes/nihilo/Calendar.css                   |  131 +
 dijit/themes/nihilo/Calendar_rtl.css               |    7 +
 dijit/themes/nihilo/ColorPalette.css               |    5 +
 dijit/themes/nihilo/Common.css                     |   19 +
 dijit/themes/nihilo/Dialog.css                     |  131 +
 dijit/themes/nihilo/Dialog_rtl.css                 |    5 +
 dijit/themes/nihilo/Editor.css                     |   61 +
 dijit/themes/nihilo/Editor_rtl.css                 |   10 +
 dijit/themes/nihilo/Menu.css                       |   62 +
 dijit/themes/nihilo/Menu_rtl.css                   |    8 +
 dijit/themes/nihilo/ProgressBar.css                |   24 +
 dijit/themes/nihilo/TimePicker.css                 |   50 +
 dijit/themes/nihilo/TitlePane.css                  |   68 +
 dijit/themes/nihilo/TitlePane_rtl.css              |    6 +
 dijit/themes/nihilo/Toolbar.css                    |   58 +
 dijit/themes/nihilo/Tree.css                       |   87 +
 dijit/themes/nihilo/Tree_rtl.css                   |   22 +
 dijit/themes/nihilo/form/Button.css                |   86 +
 dijit/themes/nihilo/form/Button_rtl.css            |    3 +
 dijit/themes/nihilo/form/Checkbox.css              |   40 +
 dijit/themes/nihilo/form/ComboBox.css              |   10 +
 dijit/themes/nihilo/form/Common.css                |   88 +
 dijit/themes/nihilo/form/Common_rtl.css            |    7 +
 dijit/themes/nihilo/form/RadioButton.css           |   40 +
 dijit/themes/nihilo/form/Slider.css                |  115 +
 dijit/themes/nihilo/form/Slider_rtl.css            |   29 +
 dijit/themes/nihilo/form/TimeTextBox.css           |    1 +
 dijit/themes/nihilo/images/accordionItemActive.png |  Bin 0 -> 148 bytes
 dijit/themes/nihilo/images/buttonActive.png        |  Bin 0 -> 139 bytes
 dijit/themes/nihilo/images/buttonDisabled.png      |  Bin 0 -> 139 bytes
 dijit/themes/nihilo/images/buttonEnabled.png       |  Bin 0 -> 135 bytes
 dijit/themes/nihilo/images/buttonHover.png         |  Bin 0 -> 134 bytes
 dijit/themes/nihilo/images/dndCopy.png             |  Bin 0 -> 777 bytes
 dijit/themes/nihilo/images/dndMove.png             |  Bin 0 -> 726 bytes
 dijit/themes/nihilo/images/dndNoCopy.png           |  Bin 0 -> 699 bytes
 dijit/themes/nihilo/images/dndNoMove.png           |  Bin 0 -> 677 bytes
 dijit/themes/nihilo/images/editor.gif              |  Bin 0 -> 3963 bytes
 dijit/themes/nihilo/images/editorDisabled.gif      |  Bin 0 -> 4336 bytes
 dijit/themes/nihilo/images/editorDisabled_rtl.gif  |  Bin 0 -> 4270 bytes
 dijit/themes/nihilo/images/editor_rtl.gif          |  Bin 0 -> 3961 bytes
 dijit/themes/nihilo/images/no.gif                  |  Bin 0 -> 179 bytes
 dijit/themes/nihilo/images/preciseSliderThumb.gif  |  Bin 0 -> 258 bytes
 dijit/themes/nihilo/images/preciseSliderThumb.png  |  Bin 0 -> 413 bytes
 .../nihilo/images/preciseSliderThumbFocus.gif      |  Bin 0 -> 258 bytes
 .../nihilo/images/preciseSliderThumbFocus.png      |  Bin 0 -> 434 bytes
 dijit/themes/nihilo/images/progressBarAnim.gif     |  Bin 0 -> 7064 bytes
 dijit/themes/nihilo/images/progressBarEmpty.png    |  Bin 0 -> 314 bytes
 dijit/themes/nihilo/images/progressBarFull.png     |  Bin 0 -> 746 bytes
 dijit/themes/nihilo/images/sliderEmpty.png         |  Bin 0 -> 114 bytes
 dijit/themes/nihilo/images/sliderEmptyVertical.png |  Bin 0 -> 114 bytes
 dijit/themes/nihilo/images/sliderFull.png          |  Bin 0 -> 130 bytes
 dijit/themes/nihilo/images/sliderFullFocus.png     |  Bin 0 -> 132 bytes
 dijit/themes/nihilo/images/sliderFullVertical.png  |  Bin 0 -> 126 bytes
 .../nihilo/images/sliderFullVerticalFocus.png      |  Bin 0 -> 126 bytes
 dijit/themes/nihilo/images/sliderThumb.gif         |  Bin 0 -> 238 bytes
 dijit/themes/nihilo/images/sliderThumb.png         |  Bin 0 -> 413 bytes
 dijit/themes/nihilo/images/sliderThumbFocus.gif    |  Bin 0 -> 238 bytes
 dijit/themes/nihilo/images/sliderThumbFocus.png    |  Bin 0 -> 421 bytes
 .../nihilo/images/splitContainerSizerH-thumb.png   |  Bin 0 -> 127 bytes
 .../themes/nihilo/images/splitContainerSizerH.png  |  Bin 0 -> 121 bytes
 .../nihilo/images/splitContainerSizerV-thumb.png   |  Bin 0 -> 129 bytes
 .../themes/nihilo/images/splitContainerSizerV.png  |  Bin 0 -> 116 bytes
 dijit/themes/nihilo/images/spriteArrows.gif        |  Bin 0 -> 446 bytes
 dijit/themes/nihilo/images/spriteArrows.png        |  Bin 0 -> 720 bytes
 dijit/themes/nihilo/images/spriteCheckbox.gif      |  Bin 0 -> 774 bytes
 dijit/themes/nihilo/images/spriteCheckbox.png      |  Bin 0 -> 707 bytes
 dijit/themes/nihilo/images/spriteDivIcons.gif      |  Bin 0 -> 875 bytes
 dijit/themes/nihilo/images/spriteDivIcons.png      |  Bin 0 -> 1062 bytes
 dijit/themes/nihilo/images/spriteRadio.gif         |  Bin 0 -> 1137 bytes
 dijit/themes/nihilo/images/spriteRadio.png         |  Bin 0 -> 1073 bytes
 .../nihilo/images/spriteRoundedIconsSmall.gif      |  Bin 0 -> 1863 bytes
 .../nihilo/images/spriteRoundedIconsSmall.png      |  Bin 0 -> 2195 bytes
 dijit/themes/nihilo/images/spriteTree.gif          |  Bin 0 -> 233 bytes
 dijit/themes/nihilo/images/spriteTree.png          |  Bin 0 -> 337 bytes
 dijit/themes/nihilo/images/spriteTree_rtl.gif      |  Bin 0 -> 233 bytes
 dijit/themes/nihilo/images/spriteTree_rtl.png      |  Bin 0 -> 335 bytes
 dijit/themes/nihilo/images/tabBottomActiveC.gif    |  Bin 0 -> 518 bytes
 .../nihilo/images/tabBottomActiveSpriteLR.gif      |  Bin 0 -> 291 bytes
 dijit/themes/nihilo/images/tabBottomEnabledC.gif   |  Bin 0 -> 511 bytes
 .../nihilo/images/tabBottomEnabledSpriteLR.gif     |  Bin 0 -> 266 bytes
 dijit/themes/nihilo/images/tabBottomHoverC.gif     |  Bin 0 -> 542 bytes
 .../nihilo/images/tabBottomHoverSpriteLR.gif       |  Bin 0 -> 388 bytes
 dijit/themes/nihilo/images/tabContainerSprite.gif  |  Bin 0 -> 1285 bytes
 dijit/themes/nihilo/images/tabLeftChecked.gif      |  Bin 0 -> 303 bytes
 dijit/themes/nihilo/images/tabRightChecked.gif     |  Bin 0 -> 300 bytes
 dijit/themes/nihilo/images/tabStripe.gif           |  Bin 0 -> 54 bytes
 dijit/themes/nihilo/images/tabStripeBottom.gif     |  Bin 0 -> 432 bytes
 dijit/themes/nihilo/images/tabStripeLeft.gif       |  Bin 0 -> 432 bytes
 dijit/themes/nihilo/images/tabStripeRight.gif      |  Bin 0 -> 432 bytes
 dijit/themes/nihilo/images/titleBar.png            |  Bin 0 -> 136 bytes
 dijit/themes/nihilo/images/titleBarActive.png      |  Bin 0 -> 148 bytes
 .../themes/nihilo/images/tooltipConnectorDown.gif  |  Bin 0 -> 205 bytes
 .../themes/nihilo/images/tooltipConnectorDown.png  |  Bin 0 -> 342 bytes
 .../themes/nihilo/images/tooltipConnectorLeft.gif  |  Bin 0 -> 205 bytes
 .../themes/nihilo/images/tooltipConnectorLeft.png  |  Bin 0 -> 361 bytes
 .../themes/nihilo/images/tooltipConnectorRight.gif |  Bin 0 -> 204 bytes
 .../themes/nihilo/images/tooltipConnectorRight.png |  Bin 0 -> 205 bytes
 dijit/themes/nihilo/images/tooltipConnectorUp.gif  |  Bin 0 -> 205 bytes
 dijit/themes/nihilo/images/tooltipConnectorUp.png  |  Bin 0 -> 319 bytes
 dijit/themes/nihilo/images/treeExpand_loading.gif  |  Bin 0 -> 662 bytes
 dijit/themes/nihilo/images/treeHover.png           |  Bin 0 -> 112 bytes
 dijit/themes/nihilo/images/treeI.gif               |  Bin 0 -> 71 bytes
 dijit/themes/nihilo/images/treeI_half.gif          |  Bin 0 -> 65 bytes
 dijit/themes/nihilo/images/treeI_half_rtl.gif      |  Bin 0 -> 66 bytes
 dijit/themes/nihilo/images/treeI_rtl.gif           |  Bin 0 -> 72 bytes
 dijit/themes/nihilo/images/validationInputBg.gif   |  Bin 0 -> 93 bytes
 dijit/themes/nihilo/images/validationInputBg.png   |  Bin 0 -> 126 bytes
 dijit/themes/nihilo/images/warning.png             |  Bin 0 -> 1275 bytes
 dijit/themes/nihilo/layout/AccordionContainer.css  |   37 +
 .../nihilo/layout/AccordionContainer_rtl.css       |    7 +
 dijit/themes/nihilo/layout/BorderContainer.css     |   59 +
 dijit/themes/nihilo/layout/ContentPane.css         |   17 +
 dijit/themes/nihilo/layout/SplitContainer.css      |   27 +
 dijit/themes/nihilo/layout/TabContainer.css        |  277 +
 dijit/themes/nihilo/layout/TabContainer_rtl.css    |   37 +
 dijit/themes/nihilo/nihilo.css                     | 1480 ++
 dijit/themes/nihilo/nihilo_rtl.css                 |  212 +
 dijit/themes/soria/Calendar.css                    |  130 +
 dijit/themes/soria/Calendar_rtl.css                |    7 +
 dijit/themes/soria/ColorPalette.css                |    5 +
 dijit/themes/soria/Common.css                      |   19 +
 dijit/themes/soria/Dialog.css                      |  132 +
 dijit/themes/soria/Dialog_rtl.css                  |    5 +
 dijit/themes/soria/Editor.css                      |   61 +
 dijit/themes/soria/Editor_rtl.css                  |   10 +
 dijit/themes/soria/Menu.css                        |   62 +
 dijit/themes/soria/Menu_rtl.css                    |    8 +
 dijit/themes/soria/ProgressBar.css                 |   24 +
 dijit/themes/soria/TimePicker.css                  |   50 +
 dijit/themes/soria/TitlePane.css                   |   68 +
 dijit/themes/soria/TitlePane_rtl.css               |    6 +
 dijit/themes/soria/Toolbar.css                     |   58 +
 dijit/themes/soria/Tree.css                        |   90 +
 dijit/themes/soria/Tree_rtl.css                    |   17 +
 dijit/themes/soria/form/Button.css                 |   88 +
 dijit/themes/soria/form/Button_rtl.css             |    3 +
 dijit/themes/soria/form/Checkbox.css               |   40 +
 dijit/themes/soria/form/ComboBox.css               |   10 +
 dijit/themes/soria/form/Common.css                 |   88 +
 dijit/themes/soria/form/Common_rtl.css             |    7 +
 dijit/themes/soria/form/RadioButton.css            |   40 +
 dijit/themes/soria/form/Slider.css                 |  117 +
 dijit/themes/soria/form/Slider_rtl.css             |   29 +
 dijit/themes/soria/form/TimeTextBox.css            |    1 +
 dijit/themes/soria/images/accordionItemActive.gif  |  Bin 0 -> 174 bytes
 dijit/themes/soria/images/accordionItemActive.png  |  Bin 0 -> 171 bytes
 dijit/themes/soria/images/buttonActive.png         |  Bin 0 -> 187 bytes
 dijit/themes/soria/images/buttonDisabled.png       |  Bin 0 -> 187 bytes
 dijit/themes/soria/images/buttonEnabled.png        |  Bin 0 -> 174 bytes
 dijit/themes/soria/images/buttonHover.png          |  Bin 0 -> 160 bytes
 dijit/themes/soria/images/dndCopy.png              |  Bin 0 -> 777 bytes
 dijit/themes/soria/images/dndMove.png              |  Bin 0 -> 726 bytes
 dijit/themes/soria/images/dndNoCopy.png            |  Bin 0 -> 699 bytes
 dijit/themes/soria/images/dndNoMove.png            |  Bin 0 -> 677 bytes
 dijit/themes/soria/images/editor.gif               |  Bin 0 -> 3963 bytes
 dijit/themes/soria/images/editorDisabled.gif       |  Bin 0 -> 4336 bytes
 dijit/themes/soria/images/editorDisabled_rtl.gif   |  Bin 0 -> 4270 bytes
 dijit/themes/soria/images/editor_rtl.gif           |  Bin 0 -> 3961 bytes
 dijit/themes/soria/images/preciseSliderThumb.gif   |  Bin 0 -> 258 bytes
 dijit/themes/soria/images/preciseSliderThumb.png   |  Bin 0 -> 413 bytes
 .../soria/images/preciseSliderThumbFocus.gif       |  Bin 0 -> 258 bytes
 .../soria/images/preciseSliderThumbFocus.png       |  Bin 0 -> 434 bytes
 dijit/themes/soria/images/progressBarAnim.gif      |  Bin 0 -> 9304 bytes
 dijit/themes/soria/images/progressBarEmpty.png     |  Bin 0 -> 232 bytes
 dijit/themes/soria/images/progressBarFull.png      |  Bin 0 -> 251 bytes
 dijit/themes/soria/images/sliderEmpty.png          |  Bin 0 -> 114 bytes
 dijit/themes/soria/images/sliderEmptyVertical.png  |  Bin 0 -> 114 bytes
 dijit/themes/soria/images/sliderFull.png           |  Bin 0 -> 131 bytes
 dijit/themes/soria/images/sliderFullFocus.png      |  Bin 0 -> 146 bytes
 dijit/themes/soria/images/sliderFullVertical.png   |  Bin 0 -> 127 bytes
 .../soria/images/sliderFullVerticalFocus.png       |  Bin 0 -> 143 bytes
 dijit/themes/soria/images/sliderThumb.gif          |  Bin 0 -> 238 bytes
 dijit/themes/soria/images/sliderThumb.png          |  Bin 0 -> 413 bytes
 dijit/themes/soria/images/sliderThumbFocus.gif     |  Bin 0 -> 238 bytes
 dijit/themes/soria/images/sliderThumbFocus.png     |  Bin 0 -> 421 bytes
 .../soria/images/splitContainerSizerH-thumb.png    |  Bin 0 -> 125 bytes
 dijit/themes/soria/images/splitContainerSizerH.png |  Bin 0 -> 127 bytes
 .../soria/images/splitContainerSizerV-thumb.png    |  Bin 0 -> 121 bytes
 dijit/themes/soria/images/splitContainerSizerV.png |  Bin 0 -> 124 bytes
 dijit/themes/soria/images/spriteArrows.gif         |  Bin 0 -> 446 bytes
 dijit/themes/soria/images/spriteArrows.png         |  Bin 0 -> 720 bytes
 dijit/themes/soria/images/spriteCheckbox.gif       |  Bin 0 -> 774 bytes
 dijit/themes/soria/images/spriteCheckbox.png       |  Bin 0 -> 707 bytes
 dijit/themes/soria/images/spriteDivIcons.gif       |  Bin 0 -> 884 bytes
 dijit/themes/soria/images/spriteDivIcons.png       |  Bin 0 -> 1114 bytes
 dijit/themes/soria/images/spriteRadio.gif          |  Bin 0 -> 1137 bytes
 dijit/themes/soria/images/spriteRadio.png          |  Bin 0 -> 1073 bytes
 .../soria/images/spriteRoundedIconsSmall.gif       |  Bin 0 -> 1937 bytes
 .../soria/images/spriteRoundedIconsSmall.png       |  Bin 0 -> 3187 bytes
 .../soria/images/spriteRoundedIconsSmallBl.gif     |  Bin 0 -> 1907 bytes
 .../soria/images/spriteRoundedIconsSmallBl.png     |  Bin 0 -> 3010 bytes
 dijit/themes/soria/images/spriteTree.gif           |  Bin 0 -> 233 bytes
 dijit/themes/soria/images/spriteTree.png           |  Bin 0 -> 337 bytes
 dijit/themes/soria/images/spriteTree_rtl.gif       |  Bin 0 -> 233 bytes
 dijit/themes/soria/images/spriteTree_rtl.png       |  Bin 0 -> 335 bytes
 dijit/themes/soria/images/tabBottomActiveC.gif     |  Bin 0 -> 482 bytes
 .../soria/images/tabBottomActiveSpriteLR.gif       |  Bin 0 -> 741 bytes
 dijit/themes/soria/images/tabBottomEnabledC.gif    |  Bin 0 -> 337 bytes
 .../soria/images/tabBottomEnabledSpriteLR.gif      |  Bin 0 -> 676 bytes
 dijit/themes/soria/images/tabBottomHoverC.gif      |  Bin 0 -> 280 bytes
 .../themes/soria/images/tabBottomHoverSpriteLR.gif |  Bin 0 -> 569 bytes
 dijit/themes/soria/images/tabContainerSprite.gif   |  Bin 0 -> 2570 bytes
 dijit/themes/soria/images/tabLeftChecked.gif       |  Bin 0 -> 795 bytes
 dijit/themes/soria/images/tabRightChecked.gif      |  Bin 0 -> 793 bytes
 dijit/themes/soria/images/tabStripe.gif            |  Bin 0 -> 54 bytes
 dijit/themes/soria/images/tabStripeBottom.gif      |  Bin 0 -> 54 bytes
 dijit/themes/soria/images/tabStripeLeft.gif        |  Bin 0 -> 54 bytes
 dijit/themes/soria/images/tabStripeRight.gif       |  Bin 0 -> 54 bytes
 dijit/themes/soria/images/titleBar.png             |  Bin 0 -> 175 bytes
 dijit/themes/soria/images/titleBarActive.png       |  Bin 0 -> 171 bytes
 dijit/themes/soria/images/tooltipConnectorDown.gif |  Bin 0 -> 205 bytes
 dijit/themes/soria/images/tooltipConnectorDown.png |  Bin 0 -> 342 bytes
 dijit/themes/soria/images/tooltipConnectorLeft.gif |  Bin 0 -> 205 bytes
 dijit/themes/soria/images/tooltipConnectorLeft.png |  Bin 0 -> 361 bytes
 .../themes/soria/images/tooltipConnectorRight.gif  |  Bin 0 -> 204 bytes
 .../themes/soria/images/tooltipConnectorRight.png  |  Bin 0 -> 1005 bytes
 dijit/themes/soria/images/tooltipConnectorUp.gif   |  Bin 0 -> 205 bytes
 dijit/themes/soria/images/tooltipConnectorUp.png   |  Bin 0 -> 319 bytes
 dijit/themes/soria/images/treeExpand_loading.gif   |  Bin 0 -> 662 bytes
 dijit/themes/soria/images/treeHover.png            |  Bin 0 -> 112 bytes
 dijit/themes/soria/images/treeI.gif                |  Bin 0 -> 71 bytes
 dijit/themes/soria/images/treeI_half.gif           |  Bin 0 -> 65 bytes
 dijit/themes/soria/images/treeI_half_rtl.gif       |  Bin 0 -> 66 bytes
 dijit/themes/soria/images/treeI_rtl.gif            |  Bin 0 -> 72 bytes
 dijit/themes/soria/images/validationInputBg.gif    |  Bin 0 -> 93 bytes
 dijit/themes/soria/images/validationInputBg.png    |  Bin 0 -> 126 bytes
 dijit/themes/soria/images/warning.png              |  Bin 0 -> 1275 bytes
 dijit/themes/soria/layout/AccordionContainer.css   |   38 +
 .../themes/soria/layout/AccordionContainer_rtl.css |    7 +
 dijit/themes/soria/layout/BorderContainer.css      |   59 +
 dijit/themes/soria/layout/ContentPane.css          |   17 +
 dijit/themes/soria/layout/SplitContainer.css       |   27 +
 dijit/themes/soria/layout/TabContainer.css         |  276 +
 dijit/themes/soria/layout/TabContainer_rtl.css     |   37 +
 dijit/themes/soria/soria.css                       | 1487 ++
 dijit/themes/soria/soria_rtl.css                   |  207 +
 dijit/themes/tundra/Calendar.css                   |  128 +
 dijit/themes/tundra/Calendar_rtl.css               |    7 +
 dijit/themes/tundra/ColorPalette.css               |    5 +
 dijit/themes/tundra/Common.css                     |   27 +
 dijit/themes/tundra/Dialog.css                     |  143 +
 dijit/themes/tundra/Dialog_rtl.css                 |    5 +
 dijit/themes/tundra/Editor.css                     |   61 +
 dijit/themes/tundra/Editor_rtl.css                 |   10 +
 dijit/themes/tundra/Menu.css                       |   61 +
 dijit/themes/tundra/Menu_rtl.css                   |    7 +
 dijit/themes/tundra/ProgressBar.css                |   23 +
 dijit/themes/tundra/TimePicker.css                 |   50 +
 dijit/themes/tundra/TitlePane.css                  |   60 +
 dijit/themes/tundra/TitlePane_rtl.css              |    3 +
 dijit/themes/tundra/Toolbar.css                    |   58 +
 dijit/themes/tundra/Tree.css                       |   85 +
 dijit/themes/tundra/Tree_rtl.css                   |   13 +
 dijit/themes/tundra/form/Button.css                |  116 +
 dijit/themes/tundra/form/Checkbox.css              |   45 +
 dijit/themes/tundra/form/Common.css                |  119 +
 dijit/themes/tundra/form/Common_rtl.css            |    6 +
 dijit/themes/tundra/form/RadioButton.css           |   44 +
 dijit/themes/tundra/form/Slider.css                |  126 +
 dijit/themes/tundra/form/Slider_rtl.css            |   26 +
 dijit/themes/tundra/images/accordionItemActive.gif |  Bin 0 -> 107 bytes
 dijit/themes/tundra/images/accordionItemHover.gif  |  Bin 0 -> 171 bytes
 dijit/themes/tundra/images/buttonActive.png        |  Bin 0 -> 129 bytes
 dijit/themes/tundra/images/buttonDisabled.png      |  Bin 0 -> 135 bytes
 dijit/themes/tundra/images/buttonEnabled.png       |  Bin 0 -> 120 bytes
 dijit/themes/tundra/images/buttonHover.png         |  Bin 0 -> 144 bytes
 dijit/themes/tundra/images/calendarDayLabel.png    |  Bin 0 -> 161 bytes
 dijit/themes/tundra/images/calendarMonthLabel.png  |  Bin 0 -> 162 bytes
 dijit/themes/tundra/images/calendarYearLabel.png   |  Bin 0 -> 172 bytes
 dijit/themes/tundra/images/checkmark.gif           |  Bin 0 -> 2060 bytes
 dijit/themes/tundra/images/checkmark.png           |  Bin 0 -> 5529 bytes
 dijit/themes/tundra/images/checkmarkNoBorder.gif   |  Bin 0 -> 1658 bytes
 dijit/themes/tundra/images/checkmarkNoBorder.png   |  Bin 0 -> 4401 bytes
 dijit/themes/tundra/images/circleIcon.gif          |  Bin 0 -> 204 bytes
 dijit/themes/tundra/images/circleIcon.png          |  Bin 0 -> 2975 bytes
 dijit/themes/tundra/images/comboArrowDown.gif      |  Bin 0 -> 49 bytes
 .../themes/tundra/images/dijitProgressBarAnim.gif  |  Bin 0 -> 1676 bytes
 .../themes/tundra/images/dijitProgressBarAnim.psd  |  Bin 0 -> 40142 bytes
 dijit/themes/tundra/images/dndCopy.png             |  Bin 0 -> 777 bytes
 dijit/themes/tundra/images/dndMove.png             |  Bin 0 -> 726 bytes
 dijit/themes/tundra/images/dndNoCopy.png           |  Bin 0 -> 699 bytes
 dijit/themes/tundra/images/dndNoMove.png           |  Bin 0 -> 677 bytes
 .../themes/tundra/images/dojoTundraGradientBg.gif  |  Bin 0 -> 65 bytes
 .../themes/tundra/images/dojoTundraGradientBg.png  |  Bin 0 -> 135 bytes
 dijit/themes/tundra/images/doubleArrowDown.png     |  Bin 0 -> 152 bytes
 dijit/themes/tundra/images/doubleArrowUp.png       |  Bin 0 -> 158 bytes
 dijit/themes/tundra/images/editor.gif              |  Bin 0 -> 3963 bytes
 dijit/themes/tundra/images/editorDisabled.gif      |  Bin 0 -> 4336 bytes
 dijit/themes/tundra/images/editorDisabled_rtl.gif  |  Bin 0 -> 4270 bytes
 dijit/themes/tundra/images/editor_rtl.gif          |  Bin 0 -> 3961 bytes
 dijit/themes/tundra/images/folderClosed.gif        |  Bin 0 -> 933 bytes
 dijit/themes/tundra/images/folderOpened.gif        |  Bin 0 -> 941 bytes
 dijit/themes/tundra/images/i.gif                   |  Bin 0 -> 48 bytes
 dijit/themes/tundra/images/i_half.gif              |  Bin 0 -> 63 bytes
 dijit/themes/tundra/images/i_half_rtl.gif          |  Bin 0 -> 61 bytes
 dijit/themes/tundra/images/i_rtl.gif               |  Bin 0 -> 48 bytes
 dijit/themes/tundra/images/leaf.gif                |  Bin 0 -> 403 bytes
 dijit/themes/tundra/images/loading.gif             |  Bin 0 -> 751 bytes
 dijit/themes/tundra/images/menu.png                |  Bin 0 -> 140 bytes
 dijit/themes/tundra/images/minusButton.gif         |  Bin 0 -> 148 bytes
 dijit/themes/tundra/images/no.gif                  |  Bin 0 -> 179 bytes
 dijit/themes/tundra/images/noX.gif                 |  Bin 0 -> 80 bytes
 dijit/themes/tundra/images/plusButton.gif          |  Bin 0 -> 212 bytes
 dijit/themes/tundra/images/popupMenuBg.gif         |  Bin 0 -> 151 bytes
 dijit/themes/tundra/images/preciseSliderThumb.gif  |  Bin 0 -> 212 bytes
 dijit/themes/tundra/images/preciseSliderThumb.png  |  Bin 0 -> 248 bytes
 .../tundra/images/preciseSliderThumbFocus.gif      |  Bin 0 -> 212 bytes
 .../tundra/images/preciseSliderThumbFocus.png      |  Bin 0 -> 281 bytes
 dijit/themes/tundra/images/progressBarAnim-1.png   |  Bin 0 -> 288 bytes
 dijit/themes/tundra/images/progressBarAnim-2.png   |  Bin 0 -> 289 bytes
 dijit/themes/tundra/images/progressBarAnim-3.png   |  Bin 0 -> 288 bytes
 dijit/themes/tundra/images/progressBarAnim-4.png   |  Bin 0 -> 287 bytes
 dijit/themes/tundra/images/progressBarAnim-5.png   |  Bin 0 -> 283 bytes
 dijit/themes/tundra/images/progressBarAnim-6.png   |  Bin 0 -> 283 bytes
 dijit/themes/tundra/images/progressBarAnim-7.png   |  Bin 0 -> 284 bytes
 dijit/themes/tundra/images/progressBarAnim-8.png   |  Bin 0 -> 286 bytes
 dijit/themes/tundra/images/progressBarAnim-9.png   |  Bin 0 -> 289 bytes
 dijit/themes/tundra/images/progressBarAnim.gif     |  Bin 0 -> 2624 bytes
 dijit/themes/tundra/images/progressBarAnim.psd     |  Bin 0 -> 40142 bytes
 dijit/themes/tundra/images/progressBarEmpty.png    |  Bin 0 -> 164 bytes
 dijit/themes/tundra/images/progressBarFull.png     |  Bin 0 -> 160 bytes
 dijit/themes/tundra/images/radioButtonActive.png   |  Bin 0 -> 550 bytes
 .../tundra/images/radioButtonActiveDisabled.png    |  Bin 0 -> 517 bytes
 .../tundra/images/radioButtonActiveHover.png       |  Bin 0 -> 646 bytes
 dijit/themes/tundra/images/radioButtonDisabled.png |  Bin 0 -> 403 bytes
 dijit/themes/tundra/images/radioButtonEnabled.png  |  Bin 0 -> 487 bytes
 dijit/themes/tundra/images/radioButtonHover.png    |  Bin 0 -> 497 bytes
 dijit/themes/tundra/images/sliderEmpty.png         |  Bin 0 -> 124 bytes
 dijit/themes/tundra/images/sliderEmptyVertical.png |  Bin 0 -> 88 bytes
 dijit/themes/tundra/images/sliderFull.png          |  Bin 0 -> 135 bytes
 dijit/themes/tundra/images/sliderFullFocus.png     |  Bin 0 -> 163 bytes
 dijit/themes/tundra/images/sliderFullVertical.png  |  Bin 0 -> 99 bytes
 .../tundra/images/sliderFullVerticalFocus.png      |  Bin 0 -> 164 bytes
 dijit/themes/tundra/images/sliderThumb.png         |  Bin 0 -> 241 bytes
 dijit/themes/tundra/images/sliderThumbFocus.gif    |  Bin 0 -> 216 bytes
 dijit/themes/tundra/images/sliderThumbFocus.png    |  Bin 0 -> 288 bytes
 dijit/themes/tundra/images/smallArrowDown.png      |  Bin 0 -> 134 bytes
 dijit/themes/tundra/images/smallArrowUp.png        |  Bin 0 -> 134 bytes
 .../tundra/images/splitContainerSizerH-thumb.png   |  Bin 0 -> 127 bytes
 .../themes/tundra/images/splitContainerSizerH.png  |  Bin 0 -> 140 bytes
 .../tundra/images/splitContainerSizerV-thumb.png   |  Bin 0 -> 129 bytes
 .../themes/tundra/images/splitContainerSizerV.png  |  Bin 0 -> 135 bytes
 dijit/themes/tundra/images/spriteArrows.gif        |  Bin 0 -> 116 bytes
 dijit/themes/tundra/images/spriteArrows.png        |  Bin 0 -> 338 bytes
 .../tundra/images/spriteRoundedIconsSmall.gif      |  Bin 0 -> 1863 bytes
 .../tundra/images/spriteRoundedIconsSmall.png      |  Bin 0 -> 2195 bytes
 dijit/themes/tundra/images/tabActive.png           |  Bin 0 -> 155 bytes
 dijit/themes/tundra/images/tabClose.gif            |  Bin 0 -> 193 bytes
 dijit/themes/tundra/images/tabClose.png            |  Bin 0 -> 220 bytes
 dijit/themes/tundra/images/tabCloseHover.gif       |  Bin 0 -> 193 bytes
 dijit/themes/tundra/images/tabCloseHover.png       |  Bin 0 -> 220 bytes
 dijit/themes/tundra/images/tabDisabled.png         |  Bin 0 -> 139 bytes
 dijit/themes/tundra/images/tabEnabled.png          |  Bin 0 -> 142 bytes
 dijit/themes/tundra/images/tabHover.gif            |  Bin 0 -> 156 bytes
 dijit/themes/tundra/images/tabHover.png            |  Bin 0 -> 154 bytes
 dijit/themes/tundra/images/titleBar.png            |  Bin 0 -> 143 bytes
 dijit/themes/tundra/images/titleBarBg.gif          |  Bin 0 -> 97 bytes
 .../themes/tundra/images/tooltipConnectorDown.gif  |  Bin 0 -> 179 bytes
 .../themes/tundra/images/tooltipConnectorDown.png  |  Bin 0 -> 410 bytes
 .../themes/tundra/images/tooltipConnectorLeft.gif  |  Bin 0 -> 193 bytes
 .../themes/tundra/images/tooltipConnectorLeft.png  |  Bin 0 -> 3106 bytes
 .../themes/tundra/images/tooltipConnectorRight.gif |  Bin 0 -> 194 bytes
 .../themes/tundra/images/tooltipConnectorRight.png |  Bin 0 -> 3121 bytes
 dijit/themes/tundra/images/tooltipConnectorUp.gif  |  Bin 0 -> 184 bytes
 dijit/themes/tundra/images/tooltipConnectorUp.png  |  Bin 0 -> 3092 bytes
 dijit/themes/tundra/images/treeExpand_leaf.gif     |  Bin 0 -> 839 bytes
 dijit/themes/tundra/images/treeExpand_leaf_rtl.gif |  Bin 0 -> 841 bytes
 dijit/themes/tundra/images/treeExpand_loading.gif  |  Bin 0 -> 1944 bytes
 dijit/themes/tundra/images/treeExpand_minus.gif    |  Bin 0 -> 211 bytes
 .../themes/tundra/images/treeExpand_minus_rtl.gif  |  Bin 0 -> 210 bytes
 dijit/themes/tundra/images/treeExpand_mius.gif     |  Bin 0 -> 211 bytes
 dijit/themes/tundra/images/treeExpand_plus.gif     |  Bin 0 -> 216 bytes
 dijit/themes/tundra/images/treeExpand_plus_rtl.gif |  Bin 0 -> 215 bytes
 dijit/themes/tundra/images/treeHover.png           |  Bin 0 -> 112 bytes
 dijit/themes/tundra/images/validationInputBg.gif   |  Bin 0 -> 109 bytes
 dijit/themes/tundra/images/validationInputBg.png   |  Bin 0 -> 165 bytes
 dijit/themes/tundra/images/warning.png             |  Bin 0 -> 1275 bytes
 dijit/themes/tundra/layout/AccordionContainer.css  |   22 +
 dijit/themes/tundra/layout/BorderContainer.css     |   55 +
 dijit/themes/tundra/layout/ContentPane.css         |   17 +
 dijit/themes/tundra/layout/SplitContainer.css      |   31 +
 dijit/themes/tundra/layout/TabContainer.css        |  174 +
 dijit/themes/tundra/layout/TabContainer_rtl.css    |   30 +
 dijit/themes/tundra/tundra.css                     | 1614 ++
 dijit/tree/ForestStoreModel.js                     |   74 +
 dijit/tree/TreeStoreModel.js                       |  122 +
 dijit/tree/model.js                                |   18 +
 dojo/AdapterRegistry.js                            |   39 +
 dojo/DeferredList.js                               |   69 +
 dojo/LICENSE                                       |  195 +
 dojo/NodeList-fx.js                                |   40 +
 dojo/NodeList-html.js                              |   21 +
 dojo/OpenAjax.js                                   |  155 +
 dojo/_base.js                                      |   19 +
 dojo/_base/Color.js                                |  102 +
 dojo/_base/Deferred.js                             |  132 +
 dojo/_base/NodeList.js                             |  164 +
 dojo/_base/_loader/bootstrap.js                    |  108 +
 dojo/_base/_loader/hostenv_browser.js              |  234 +
 dojo/_base/_loader/hostenv_ff_ext.js               |  177 +
 dojo/_base/_loader/hostenv_rhino.js                |  163 +
 dojo/_base/_loader/hostenv_spidermonkey.js         |   50 +
 dojo/_base/_loader/loader.js                       |  301 +
 dojo/_base/_loader/loader_debug.js                 |   59 +
 dojo/_base/_loader/loader_xd.js                    |  456 +
 dojo/_base/array.js                                |   78 +
 dojo/_base/browser.js                              |   22 +
 dojo/_base/connect.js                              |   85 +
 dojo/_base/declare.js                              |  128 +
 dojo/_base/event.js                                |  342 +
 dojo/_base/fx.js                                   |  296 +
 dojo/_base/html.js                                 |  715 +
 dojo/_base/json.js                                 |   81 +
 dojo/_base/lang.js                                 |  139 +
 dojo/_base/query-sizzle.js                         |  628 +
 dojo/_base/query.js                                |  793 +
 dojo/_base/window.js                               |   46 +
 dojo/_base/xhr.js                                  |  377 +
 dojo/_firebug/LICENSE                              |   37 +
 dojo/_firebug/errorIcon.png                        |  Bin 0 -> 457 bytes
 dojo/_firebug/firebug.css                          |  208 +
 dojo/_firebug/firebug.js                           |  894 +
 dojo/_firebug/infoIcon.png                         |  Bin 0 -> 524 bytes
 dojo/_firebug/tab_lft_norm.png                     |  Bin 0 -> 193 bytes
 dojo/_firebug/tab_lft_over.png                     |  Bin 0 -> 196 bytes
 dojo/_firebug/tab_rgt_norm.png                     |  Bin 0 -> 208 bytes
 dojo/_firebug/tab_rgt_over.png                     |  Bin 0 -> 208 bytes
 dojo/_firebug/warningIcon.png                      |  Bin 0 -> 516 bytes
 dojo/back.js                                       |  254 +
 dojo/behavior.js                                   |   94 +
 dojo/build.txt                                     |  317 +
 dojo/cldr/LICENSE                                  |   29 +
 dojo/cldr/README                                   |   18 +
 dojo/cldr/monetary.js                              |   23 +
 dojo/cldr/nls/ar/currency.js                       |    1 +
 dojo/cldr/nls/ar/gregorian.js                      |    1 +
 dojo/cldr/nls/ar/islamic-civil.js                  |    1 +
 dojo/cldr/nls/ar/islamic.js                        |    1 +
 dojo/cldr/nls/ar/number.js                         |    1 +
 dojo/cldr/nls/ca/currency.js                       |    1 +
 dojo/cldr/nls/ca/gregorian.js                      |    1 +
 dojo/cldr/nls/ca/number.js                         |    1 +
 dojo/cldr/nls/cs/currency.js                       |    1 +
 dojo/cldr/nls/cs/gregorian.js                      |    1 +
 dojo/cldr/nls/cs/number.js                         |    1 +
 dojo/cldr/nls/currency.js                          |    1 +
 dojo/cldr/nls/da/currency.js                       |    1 +
 dojo/cldr/nls/da/gregorian.js                      |    1 +
 dojo/cldr/nls/da/number.js                         |    1 +
 dojo/cldr/nls/de-de/number.js                      |    1 +
 dojo/cldr/nls/de/currency.js                       |    1 +
 dojo/cldr/nls/de/gregorian.js                      |    1 +
 dojo/cldr/nls/de/number.js                         |    1 +
 dojo/cldr/nls/el/currency.js                       |    1 +
 dojo/cldr/nls/el/gregorian.js                      |    1 +
 dojo/cldr/nls/el/number.js                         |    1 +
 dojo/cldr/nls/en-au/currency.js                    |    1 +
 dojo/cldr/nls/en-au/gregorian.js                   |    1 +
 dojo/cldr/nls/en-au/number.js                      |    1 +
 dojo/cldr/nls/en-ca/currency.js                    |    1 +
 dojo/cldr/nls/en-ca/gregorian.js                   |    1 +
 dojo/cldr/nls/en-gb/gregorian.js                   |    1 +
 dojo/cldr/nls/en-gb/number.js                      |    1 +
 dojo/cldr/nls/en-us/currency.js                    |    1 +
 dojo/cldr/nls/en-us/number.js                      |    1 +
 dojo/cldr/nls/en/currency.js                       |    1 +
 dojo/cldr/nls/en/gregorian.js                      |    1 +
 dojo/cldr/nls/en/number.js                         |    1 +
 dojo/cldr/nls/es-es/gregorian.js                   |    1 +
 dojo/cldr/nls/es-es/number.js                      |    1 +
 dojo/cldr/nls/es/currency.js                       |    1 +
 dojo/cldr/nls/es/gregorian.js                      |    1 +
 dojo/cldr/nls/es/number.js                         |    1 +
 dojo/cldr/nls/fi/currency.js                       |    1 +
 dojo/cldr/nls/fi/gregorian.js                      |    1 +
 dojo/cldr/nls/fi/number.js                         |    1 +
 dojo/cldr/nls/fr/currency.js                       |    1 +
 dojo/cldr/nls/fr/gregorian.js                      |    1 +
 dojo/cldr/nls/fr/number.js                         |    1 +
 dojo/cldr/nls/gregorian.js                         |    1 +
 dojo/cldr/nls/he/currency.js                       |    1 +
 dojo/cldr/nls/he/gregorian.js                      |    1 +
 dojo/cldr/nls/he/hebrew.js                         |    1 +
 dojo/cldr/nls/he/number.js                         |    1 +
 dojo/cldr/nls/hebrew.js                            |    1 +
 dojo/cldr/nls/hu/currency.js                       |    1 +
 dojo/cldr/nls/hu/gregorian.js                      |    1 +
 dojo/cldr/nls/hu/number.js                         |    1 +
 dojo/cldr/nls/islamic-civil.js                     |    1 +
 dojo/cldr/nls/islamic.js                           |    1 +
 dojo/cldr/nls/it-it/gregorian.js                   |    1 +
 dojo/cldr/nls/it/currency.js                       |    1 +
 dojo/cldr/nls/it/gregorian.js                      |    1 +
 dojo/cldr/nls/it/number.js                         |    1 +
 dojo/cldr/nls/ja-jp/number.js                      |    1 +
 dojo/cldr/nls/ja/currency.js                       |    1 +
 dojo/cldr/nls/ja/gregorian.js                      |    1 +
 dojo/cldr/nls/ja/number.js                         |    1 +
 dojo/cldr/nls/ko-kr/gregorian.js                   |    1 +
 dojo/cldr/nls/ko-kr/number.js                      |    1 +
 dojo/cldr/nls/ko/currency.js                       |    1 +
 dojo/cldr/nls/ko/gregorian.js                      |    1 +
 dojo/cldr/nls/ko/number.js                         |    1 +
 dojo/cldr/nls/nb/currency.js                       |    1 +
 dojo/cldr/nls/nb/gregorian.js                      |    1 +
 dojo/cldr/nls/nb/number.js                         |    1 +
 dojo/cldr/nls/nl/currency.js                       |    1 +
 dojo/cldr/nls/nl/gregorian.js                      |    1 +
 dojo/cldr/nls/nl/number.js                         |    1 +
 dojo/cldr/nls/number.js                            |    1 +
 dojo/cldr/nls/pl/currency.js                       |    1 +
 dojo/cldr/nls/pl/gregorian.js                      |    1 +
 dojo/cldr/nls/pl/number.js                         |    1 +
 dojo/cldr/nls/pt-br/gregorian.js                   |    1 +
 dojo/cldr/nls/pt-pt/gregorian.js                   |    1 +
 dojo/cldr/nls/pt-pt/number.js                      |    1 +
 dojo/cldr/nls/pt/currency.js                       |    1 +
 dojo/cldr/nls/pt/gregorian.js                      |    1 +
 dojo/cldr/nls/pt/number.js                         |    1 +
 dojo/cldr/nls/ru/currency.js                       |    1 +
 dojo/cldr/nls/ru/gregorian.js                      |    1 +
 dojo/cldr/nls/ru/number.js                         |    1 +
 dojo/cldr/nls/sk/currency.js                       |    1 +
 dojo/cldr/nls/sk/gregorian.js                      |    1 +
 dojo/cldr/nls/sk/number.js                         |    1 +
 dojo/cldr/nls/sl/currency.js                       |    1 +
 dojo/cldr/nls/sl/gregorian.js                      |    1 +
 dojo/cldr/nls/sl/number.js                         |    1 +
 dojo/cldr/nls/sv/currency.js                       |    1 +
 dojo/cldr/nls/sv/gregorian.js                      |    1 +
 dojo/cldr/nls/sv/number.js                         |    1 +
 dojo/cldr/nls/th/currency.js                       |    1 +
 dojo/cldr/nls/th/gregorian.js                      |    1 +
 dojo/cldr/nls/th/number.js                         |    1 +
 dojo/cldr/nls/tr/currency.js                       |    1 +
 dojo/cldr/nls/tr/gregorian.js                      |    1 +
 dojo/cldr/nls/tr/number.js                         |    1 +
 dojo/cldr/nls/zh-cn/gregorian.js                   |    1 +
 dojo/cldr/nls/zh-cn/number.js                      |    1 +
 dojo/cldr/nls/zh-tw/currency.js                    |    1 +
 dojo/cldr/nls/zh-tw/gregorian.js                   |    1 +
 dojo/cldr/nls/zh-tw/number.js                      |    1 +
 dojo/cldr/nls/zh/currency.js                       |    1 +
 dojo/cldr/nls/zh/gregorian.js                      |    1 +
 dojo/cldr/nls/zh/number.js                         |    1 +
 dojo/cldr/supplemental.js                          |   45 +
 dojo/colors.js                                     |   76 +
 dojo/cookie.js                                     |   50 +
 dojo/currency.js                                   |   36 +
 dojo/data/ItemFileReadStore.js                     |  514 +
 dojo/data/ItemFileWriteStore.js                    |  526 +
 dojo/data/api/Identity.js                          |   26 +
 dojo/data/api/Notification.js                      |   21 +
 dojo/data/api/Read.js                              |   55 +
 dojo/data/api/Request.js                           |   14 +
 dojo/data/api/Write.js                             |   39 +
 dojo/data/util/filter.js                           |   52 +
 dojo/data/util/simpleFetch.js                      |   64 +
 dojo/data/util/sorter.js                           |   64 +
 dojo/date.js                                       |  218 +
 dojo/date/locale.js                                |  490 +
 dojo/date/stamp.js                                 |   85 +
 dojo/dnd/Avatar.js                                 |   47 +
 dojo/dnd/Container.js                              |  233 +
 dojo/dnd/Manager.js                                |  128 +
 dojo/dnd/Moveable.js                               |   77 +
 dojo/dnd/Mover.js                                  |   65 +
 dojo/dnd/Selector.js                               |  239 +
 dojo/dnd/Source.js                                 |  297 +
 dojo/dnd/TimedMoveable.js                          |   40 +
 dojo/dnd/autoscroll.js                             |   99 +
 dojo/dnd/common.js                                 |   38 +
 dojo/dnd/move.js                                   |  125 +
 dojo/dojo.js                                       |   16 +
 dojo/dojo.js.uncompressed.js                       | 9439 +++++++++
 dojo/fx.js                                         |  253 +
 dojo/fx/Toggler.js                                 |   30 +
 dojo/fx/easing.js                                  |  166 +
 dojo/gears.js                                      |   45 +
 dojo/html.js                                       |  177 +
 dojo/i18n.js                                       |  171 +
 dojo/io/iframe.js                                  |  258 +
 dojo/io/script.js                                  |  108 +
 dojo/jaxer.js                                      |   19 +
 dojo/nls/ar/colors.js                              |    1 +
 dojo/nls/ca/colors.js                              |    1 +
 dojo/nls/colors.js                                 |    1 +
 dojo/nls/cs/colors.js                              |    1 +
 dojo/nls/da/colors.js                              |    1 +
 dojo/nls/de/colors.js                              |    1 +
 dojo/nls/el/colors.js                              |    1 +
 dojo/nls/es/colors.js                              |    1 +
 dojo/nls/fi/colors.js                              |    1 +
 dojo/nls/fr/colors.js                              |    1 +
 dojo/nls/he/colors.js                              |    1 +
 dojo/nls/hu/colors.js                              |    1 +
 dojo/nls/it/colors.js                              |    1 +
 dojo/nls/ja/colors.js                              |    1 +
 dojo/nls/ko/colors.js                              |    1 +
 dojo/nls/nb/colors.js                              |    1 +
 dojo/nls/nl/colors.js                              |    1 +
 dojo/nls/pl/colors.js                              |    1 +
 dojo/nls/pt-pt/colors.js                           |    1 +
 dojo/nls/pt/colors.js                              |    1 +
 dojo/nls/ru/colors.js                              |    1 +
 dojo/nls/sk/colors.js                              |    1 +
 dojo/nls/sl/colors.js                              |    1 +
 dojo/nls/sv/colors.js                              |    1 +
 dojo/nls/th/colors.js                              |    1 +
 dojo/nls/tr/colors.js                              |    1 +
 dojo/nls/zh-tw/colors.js                           |    1 +
 dojo/nls/zh/colors.js                              |    1 +
 dojo/number.js                                     |  324 +
 dojo/parser.js                                     |  228 +
 dojo/regexp.js                                     |   32 +
 dojo/resources/LICENSE                             |   30 +
 dojo/resources/_modules.js                         |    7 +
 dojo/resources/blank.gif                           |  Bin 0 -> 43 bytes
 dojo/resources/blank.html                          |    1 +
 dojo/resources/dnd.css                             |    9 +
 dojo/resources/dojo.css                            |   99 +
 dojo/resources/iframe_history.html                 |   79 +
 dojo/resources/images/dndCopy.png                  |  Bin 0 -> 814 bytes
 dojo/resources/images/dndMove.png                  |  Bin 0 -> 785 bytes
 dojo/resources/images/dndNoCopy.png                |  Bin 0 -> 756 bytes
 dojo/resources/images/dndNoMove.png                |  Bin 0 -> 750 bytes
 dojo/robot.js                                      |   49 +
 dojo/robotx.js                                     |   80 +
 dojo/rpc/JsonService.js                            |   37 +
 dojo/rpc/JsonpService.js                           |   32 +
 dojo/rpc/RpcService.js                             |   89 +
 dojo/string.js                                     |   57 +
 dojox/LICENSE                                      |  195 +
 dojox/analytics.js                                 |   12 +
 dojox/analytics/README                             |  139 +
 dojox/analytics/Urchin.js                          |   34 +
 dojox/analytics/_base.js                           |   82 +
 dojox/analytics/logger/JSON.php                    |  724 +
 dojox/analytics/logger/dojoxAnalytics.php          |   31 +
 dojox/analytics/plugins/consoleMessages.js         |   25 +
 dojox/analytics/plugins/dojo.js                    |   22 +
 dojox/analytics/plugins/idle.js                    |   35 +
 dojox/analytics/plugins/mouseClick.js              |   51 +
 dojox/analytics/plugins/mouseOver.js               |   76 +
 dojox/analytics/plugins/window.js                  |   36 +
 dojox/analytics/profiles/analytics.profile.js      |    8 +
 .../analytics/profiles/analyticsInBase.profile.js  |    8 +
 dojox/atom/README                                  |   53 +
 dojox/atom/io/Connection.js                        |  267 +
 dojox/atom/io/model.js                             |  938 +
 dojox/atom/widget/FeedEntryEditor.js               |  735 +
 dojox/atom/widget/FeedEntryViewer.js               |  395 +
 dojox/atom/widget/FeedViewer.js                    |  410 +
 dojox/atom/widget/nls/FeedEntryEditor.js           |    1 +
 dojox/atom/widget/nls/FeedEntryViewer.js           |    1 +
 dojox/atom/widget/nls/FeedViewerEntry.js           |    1 +
 dojox/atom/widget/nls/PeopleEditor.js              |    1 +
 dojox/atom/widget/nls/ar/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/ar/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/ar/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/ar/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/ca/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/ca/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/ca/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/ca/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/cs/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/cs/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/cs/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/cs/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/da/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/da/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/da/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/da/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/de/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/de/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/de/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/de/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/el/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/el/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/el/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/el/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/es/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/es/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/es/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/es/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/fi/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/fi/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/fi/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/fi/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/fr/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/fr/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/fr/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/fr/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/he/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/he/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/he/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/he/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/hu/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/hu/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/hu/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/hu/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/it/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/it/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/it/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/it/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/ja/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/ja/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/ja/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/ja/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/ko/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/ko/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/ko/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/ko/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/nb/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/nb/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/nb/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/nb/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/nl/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/nl/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/nl/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/nl/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/pl/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/pl/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/pl/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/pl/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/pt-pt/FeedEntryEditor.js     |    1 +
 dojox/atom/widget/nls/pt-pt/FeedEntryViewer.js     |    1 +
 dojox/atom/widget/nls/pt-pt/FeedViewerEntry.js     |    1 +
 dojox/atom/widget/nls/pt-pt/PeopleEditor.js        |    1 +
 dojox/atom/widget/nls/pt/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/pt/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/pt/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/pt/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/ru/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/ru/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/ru/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/ru/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/sk/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/sk/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/sk/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/sk/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/sl/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/sl/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/sl/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/sl/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/sv/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/sv/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/sv/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/sv/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/th/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/th/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/th/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/th/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/tr/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/tr/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/tr/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/tr/PeopleEditor.js           |    1 +
 dojox/atom/widget/nls/zh-tw/FeedEntryEditor.js     |    1 +
 dojox/atom/widget/nls/zh-tw/FeedEntryViewer.js     |    1 +
 dojox/atom/widget/nls/zh-tw/FeedViewerEntry.js     |    1 +
 dojox/atom/widget/nls/zh-tw/PeopleEditor.js        |    1 +
 dojox/atom/widget/nls/zh/FeedEntryEditor.js        |    1 +
 dojox/atom/widget/nls/zh/FeedEntryViewer.js        |    1 +
 dojox/atom/widget/nls/zh/FeedViewerEntry.js        |    1 +
 dojox/atom/widget/nls/zh/PeopleEditor.js           |    1 +
 dojox/atom/widget/templates/EntryHeader.html       |    1 +
 dojox/atom/widget/templates/FeedEntryEditor.html   |  195 +
 dojox/atom/widget/templates/FeedEntryViewer.html   |  158 +
 dojox/atom/widget/templates/FeedViewer.html        |    6 +
 dojox/atom/widget/templates/FeedViewerEntry.html   |   15 +
 .../atom/widget/templates/FeedViewerGrouping.html  |    4 +
 dojox/atom/widget/templates/PeopleEditor.html      |    6 +
 dojox/atom/widget/templates/css/EntryHeader.css    |   27 +
 .../widget/templates/css/HtmlFeedEntryEditor.css   |   84 +
 .../widget/templates/css/HtmlFeedEntryViewer.css   |   90 +
 dojox/atom/widget/templates/css/HtmlFeedViewer.css |   14 +
 .../widget/templates/css/HtmlFeedViewerEntry.css   |   60 +
 .../templates/css/HtmlFeedViewerGrouping.css       |    8 +
 dojox/charting/Chart2D.js                          |  373 +
 dojox/charting/Chart3D.js                          |   73 +
 dojox/charting/DataChart.js                        |  220 +
 dojox/charting/Element.js                          |   53 +
 dojox/charting/README                              |   31 +
 dojox/charting/Series.js                           |   23 +
 dojox/charting/Theme.js                            |   82 +
 dojox/charting/action2d/Base.js                    |   45 +
 dojox/charting/action2d/Highlight.js               |   76 +
 dojox/charting/action2d/Magnify.js                 |   68 +
 dojox/charting/action2d/MoveSlice.js               |   63 +
 dojox/charting/action2d/Shake.js                   |   65 +
 dojox/charting/action2d/Tooltip.js                 |   93 +
 dojox/charting/axis2d/Base.js                      |   29 +
 dojox/charting/axis2d/Default.js                   |  242 +
 dojox/charting/axis2d/common.js                    |   63 +
 dojox/charting/plot2d/Areas.js                     |   16 +
 dojox/charting/plot2d/Bars.js                      |   78 +
 dojox/charting/plot2d/Base.js                      |   90 +
 dojox/charting/plot2d/Bubble.js                    |   98 +
 dojox/charting/plot2d/ClusteredBars.js             |   62 +
 dojox/charting/plot2d/ClusteredColumns.js          |   62 +
 dojox/charting/plot2d/Columns.js                   |   76 +
 dojox/charting/plot2d/Default.js                   |  150 +
 dojox/charting/plot2d/Grid.js                      |   85 +
 dojox/charting/plot2d/Lines.js                     |   15 +
 dojox/charting/plot2d/Markers.js                   |   15 +
 dojox/charting/plot2d/MarkersOnly.js               |   16 +
 dojox/charting/plot2d/Pie.js                       |  207 +
 dojox/charting/plot2d/Scatter.js                   |   16 +
 dojox/charting/plot2d/Stacked.js                   |  150 +
 dojox/charting/plot2d/StackedAreas.js              |   16 +
 dojox/charting/plot2d/StackedBars.js               |   92 +
 dojox/charting/plot2d/StackedColumns.js            |   90 +
 dojox/charting/plot2d/StackedLines.js              |   15 +
 dojox/charting/plot2d/common.js                    |  210 +
 dojox/charting/plot3d/Bars.js                      |   64 +
 dojox/charting/plot3d/Base.js                      |   22 +
 dojox/charting/plot3d/Cylinders.js                 |   68 +
 dojox/charting/scaler/common.js                    |   56 +
 dojox/charting/scaler/linear.js                    |  217 +
 dojox/charting/scaler/primitive.js                 |   26 +
 dojox/charting/themes/Adobebricks.js               |   16 +
 dojox/charting/themes/Algae.js                     |   16 +
 dojox/charting/themes/Bahamation.js                |   16 +
 dojox/charting/themes/BlueDusk.js                  |   16 +
 dojox/charting/themes/CubanShirts.js               |   16 +
 dojox/charting/themes/Desert.js                    |   16 +
 dojox/charting/themes/Dollar.js                    |   16 +
 dojox/charting/themes/ET/greys.js                  |   17 +
 dojox/charting/themes/Grasshopper.js               |   16 +
 dojox/charting/themes/Grasslands.js                |   16 +
 dojox/charting/themes/GreySkies.js                 |   16 +
 dojox/charting/themes/IndigoNation.js              |   16 +
 dojox/charting/themes/Ireland.js                   |   16 +
 dojox/charting/themes/MiamiNice.js                 |   16 +
 dojox/charting/themes/Midwest.js                   |   16 +
 dojox/charting/themes/Minty.js                     |   16 +
 dojox/charting/themes/PlotKit/README               |   11 +
 dojox/charting/themes/PlotKit/blue.js              |   17 +
 dojox/charting/themes/PlotKit/cyan.js              |   17 +
 dojox/charting/themes/PlotKit/green.js             |   17 +
 dojox/charting/themes/PlotKit/orange.js            |   17 +
 dojox/charting/themes/PlotKit/purple.js            |   17 +
 dojox/charting/themes/PlotKit/red.js               |   17 +
 dojox/charting/themes/PurpleRain.js                |   16 +
 dojox/charting/themes/README                       |    5 +
 dojox/charting/themes/RoyalPurples.js              |   16 +
 dojox/charting/themes/SageToLime.js                |   16 +
 dojox/charting/themes/Shrooms.js                   |   16 +
 dojox/charting/themes/Tufte.js                     |   16 +
 dojox/charting/themes/WatersEdge.js                |   16 +
 dojox/charting/themes/Wetland.js                   |   16 +
 dojox/charting/widget/Chart2D.js                   |   16 +
 dojox/charting/widget/Chart2D.js.uncompressed.js   |12543 +++++++++++
 dojox/charting/widget/Legend.js                    |  121 +
 dojox/charting/widget/Sparkline.js                 |   33 +
 dojox/collections.js                               |   12 +
 dojox/collections/ArrayList.js                     |  104 +
 dojox/collections/BinaryTree.js                    |  255 +
 dojox/collections/Dictionary.js                    |   91 +
 dojox/collections/Queue.js                         |   57 +
 dojox/collections/README                           |   39 +
 dojox/collections/Set.js                           |   84 +
 dojox/collections/SortedList.js                    |  161 +
 dojox/collections/Stack.js                         |   57 +
 dojox/collections/_base.js                         |   71 +
 dojox/color.js                                     |   12 +
 dojox/color/Colorspace.js                          |  472 +
 dojox/color/Palette.js                             |  175 +
 dojox/color/README                                 |   41 +
 dojox/color/_base.js                               |  180 +
 dojox/cometd.js                                    |   14 +
 dojox/cometd/HttpChannels.js                       |   14 +
 dojox/cometd/README                                |   29 +
 dojox/cometd/RestChannels.js                       |  338 +
 dojox/cometd/_base.js                              |  404 +
 dojox/cometd/ack.js                                |   46 +
 dojox/cometd/callbackPollTransport.js              |   74 +
 dojox/cometd/longPollTransport.js                  |   12 +
 dojox/cometd/longPollTransportFormEncoded.js       |  118 +
 dojox/cometd/longPollTransportJsonEncoded.js       |  119 +
 dojox/cometd/timestamp.js                          |   16 +
 dojox/cometd/timesync.js                           |   75 +
 dojox/data/AndOrReadStore.js                       |  617 +
 dojox/data/AndOrWriteStore.js                      |  526 +
 dojox/data/AppStore.js                             |  550 +
 dojox/data/AtomReadStore.js                        |  339 +
 dojox/data/ClientFilter.js                         |  171 +
 dojox/data/CouchDBRestStore.js                     |   64 +
 dojox/data/CssClassStore.js                        |  104 +
 dojox/data/CssRuleStore.js                         |  336 +
 dojox/data/CsvStore.js                             |  424 +
 dojox/data/FileStore.js                            |  239 +
 dojox/data/FlickrRestStore.js                      |  289 +
 dojox/data/FlickrStore.js                          |  147 +
 dojox/data/GoogleFeedStore.js                      |   24 +
 dojox/data/GoogleSearchStore.js                    |  239 +
 dojox/data/HtmlStore.js                            |  313 +
 dojox/data/HtmlTableStore.js                       |  267 +
 dojox/data/ItemExplorer.js                         |  461 +
 dojox/data/JsonQueryRestStore.js                   |   17 +
 dojox/data/JsonRestStore.js                        |  195 +
 dojox/data/KeyValueStore.js                        |  222 +
 dojox/data/OpenSearchStore.js                      |  216 +
 dojox/data/OpmlStore.js                            |  326 +
 dojox/data/PersevereStore.js                       |   78 +
 dojox/data/PicasaStore.js                          |  161 +
 dojox/data/QueryReadStore.js                       |  255 +
 dojox/data/README                                  |  127 +
 dojox/data/RailsStore.js                           |  121 +
 dojox/data/S3Store.js                              |   29 +
 dojox/data/ServiceStore.js                         |  145 +
 dojox/data/SnapLogicStore.js                       |  183 +
 dojox/data/StoreExplorer.js                        |  148 +
 dojox/data/WikipediaStore.js                       |   63 +
 dojox/data/XmlStore.js                             |  917 +
 dojox/data/css.js                                  |   91 +
 dojox/data/dom.js                                  |   42 +
 dojox/data/jsonPathStore.js                        |  670 +
 dojox/data/restListener.js                         |   36 +
 dojox/data/s3/README                               |   41 +
 dojox/data/s3/proxy.example-php                    |   74 +
 dojox/data/util/JsonQuery.js                       |   88 +
 dojox/date/HebrewDate.js                           |  641 +
 dojox/date/HebrewLocale.js                         |  411 +
 dojox/date/HebrewNumerals.js                       |  158 +
 dojox/date/IslamicDate.js                          |  314 +
 dojox/date/README                                  |   40 +
 dojox/date/php.js                                  |  185 +
 dojox/date/posix.js                                |  218 +
 dojox/dtl.js                                       |   16 +
 dojox/dtl.js.uncompressed.js                       | 2856 +++
 dojox/dtl/Context.js                               |   63 +
 dojox/dtl/DomInline.js                             |   35 +
 dojox/dtl/HtmlInline.js                            |   15 +
 dojox/dtl/Inline.js                                |   31 +
 dojox/dtl/README                                   |  207 +
 dojox/dtl/_DomTemplated.js                         |   61 +
 dojox/dtl/_HtmlTemplated.js                        |   15 +
 dojox/dtl/_Templated.js                            |   71 +
 dojox/dtl/_base.js                                 |  574 +
 dojox/dtl/contrib/data.js                          |  121 +
 dojox/dtl/contrib/dijit.js                         |  184 +
 dojox/dtl/contrib/dom.js                           |  131 +
 dojox/dtl/contrib/html.js                          |   13 +
 dojox/dtl/contrib/objects.js                       |   15 +
 dojox/dtl/dom.js                                   |  864 +
 dojox/dtl/ext-dojo/NodeList.js                     |   29 +
 dojox/dtl/filter/dates.js                          |   59 +
 dojox/dtl/filter/htmlstrings.js                    |   37 +
 dojox/dtl/filter/integers.js                       |   28 +
 dojox/dtl/filter/lists.js                          |   95 +
 dojox/dtl/filter/logic.js                          |   33 +
 dojox/dtl/filter/misc.js                           |   52 +
 dojox/dtl/filter/strings.js                        |  270 +
 dojox/dtl/html.js                                  |   14 +
 dojox/dtl/render/dom.js                            |   35 +
 dojox/dtl/render/html.js                           |   13 +
 dojox/dtl/tag/date.js                              |   33 +
 dojox/dtl/tag/loader.js                            |  260 +
 dojox/dtl/tag/logic.js                             |  247 +
 dojox/dtl/tag/loop.js                              |  164 +
 dojox/dtl/tag/misc.js                              |  223 +
 dojox/dtl/utils/date.js                            |   59 +
 dojox/editor/README                                |   44 +
 dojox/editor/plugins/TablePlugins.js               |  609 +
 dojox/editor/plugins/UploadImage.js                |   54 +
 dojox/editor/plugins/nls/TableDialog.js            |    1 +
 dojox/editor/plugins/nls/ar/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/ca/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/cs/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/da/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/de/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/el/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/es/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/fi/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/fr/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/he/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/hu/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/it/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/ja/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/ko/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/nb/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/nl/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/pl/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/pt-pt/TableDialog.js      |    1 +
 dojox/editor/plugins/nls/pt/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/ru/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/sk/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/sl/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/sv/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/th/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/tr/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/zh-tw/TableDialog.js      |    1 +
 dojox/editor/plugins/nls/zh/TableDialog.js         |    1 +
 dojox/editor/plugins/resources/editorPlugins.css   |  142 +
 dojox/editor/plugins/resources/images/busy.gif     |  Bin 0 -> 9052 bytes
 dojox/editor/plugins/resources/images/cellpad.png  |  Bin 0 -> 147 bytes
 .../editor/plugins/resources/images/cellspace.png  |  Bin 0 -> 135 bytes
 .../editor/plugins/resources/images/tableIcons.png |  Bin 0 -> 704 bytes
 .../plugins/resources/images/uploadImageIcon.gif   |  Bin 0 -> 255 bytes
 dojox/editor/plugins/resources/insertTable.html    |   41 +
 dojox/editor/plugins/resources/modifyTable.html    |   50 +
 dojox/embed/Flash.js                               |  264 +
 dojox/embed/IE/flash.js                            |   22 +
 dojox/embed/Object.js                              |   39 +
 dojox/embed/Quicktime.js                           |  139 +
 dojox/embed/README                                 |   44 +
 dojox/embed/flashVars.js                           |   37 +
 dojox/embed/resources/version.mov                  |  Bin 0 -> 1667 bytes
 dojox/encoding/LICENSE                             |   14 +
 dojox/encoding/README                              |   35 +
 dojox/encoding/_base.js                            |   11 +
 dojox/encoding/ascii85.js                          |   71 +
 dojox/encoding/base64.js                           |   70 +
 dojox/encoding/bits.js                             |   64 +
 dojox/encoding/compression/lzw.js                  |   83 +
 dojox/encoding/compression/splay.js                |   65 +
 dojox/encoding/crypto/Blowfish.js                  |  275 +
 dojox/encoding/crypto/SimpleAES.js                 |  236 +
 dojox/encoding/crypto/_base.js                     |   16 +
 dojox/encoding/digests/MD5.js                      |  158 +
 dojox/encoding/digests/SHA1.js                     |  137 +
 dojox/encoding/digests/_base.js                    |   57 +
 dojox/encoding/easy64.js                           |   47 +
 dojox/flash.js                                     |   12 +
 dojox/flash/DojoExternalInterface.as               |  177 +
 dojox/flash/ExpressInstall.as                      |   71 +
 dojox/flash/README                                 |   31 +
 dojox/flash/_base.js                               |  299 +
 dojox/form/BusyButton.js                           |   79 +
 dojox/form/CheckedMultiSelect.js                   |   99 +
 dojox/form/DateTextBox.js                          |   58 +
 dojox/form/DropDownSelect.js                       |  133 +
 dojox/form/DropDownStack.js                        |   14 +
 dojox/form/FileInput.js                            |   42 +
 dojox/form/FileInputAuto.js                        |   95 +
 dojox/form/FilePickerTextBox.js                    |  264 +
 dojox/form/FileUploader.js                         |  681 +
 dojox/form/Manager.js                              |   35 +
 dojox/form/MultiComboBox.js                        |   46 +
 dojox/form/PasswordValidator.js                    |  153 +
 dojox/form/README                                  |   70 +
 dojox/form/RadioStack.js                           |   14 +
 dojox/form/RangeSlider.js                          |  330 +
 dojox/form/Rating.js                               |   56 +
 dojox/form/TimeSpinner.js                          |   28 +
 dojox/form/_FormSelectWidget.js                    |  211 +
 dojox/form/_HasDropDown.js                         |  179 +
 dojox/form/_SelectStackMixin.js                    |  108 +
 dojox/form/manager/_ClassMixin.js                  |   31 +
 dojox/form/manager/_DisplayMixin.js                |   27 +
 dojox/form/manager/_EnableMixin.js                 |   43 +
 dojox/form/manager/_FormMixin.js                   |   70 +
 dojox/form/manager/_Mixin.js                       |  274 +
 dojox/form/manager/_NodeMixin.js                   |  239 +
 dojox/form/manager/_ValueMixin.js                  |   48 +
 dojox/form/nls/PasswordValidator.js                |    1 +
 dojox/form/nls/ar/PasswordValidator.js             |    1 +
 dojox/form/nls/ca/PasswordValidator.js             |    1 +
 dojox/form/nls/cs/PasswordValidator.js             |    1 +
 dojox/form/nls/da/PasswordValidator.js             |    1 +
 dojox/form/nls/de/PasswordValidator.js             |    1 +
 dojox/form/nls/el/PasswordValidator.js             |    1 +
 dojox/form/nls/es/PasswordValidator.js             |    1 +
 dojox/form/nls/fi/PasswordValidator.js             |    1 +
 dojox/form/nls/fr/PasswordValidator.js             |    1 +
 dojox/form/nls/he/PasswordValidator.js             |    1 +
 dojox/form/nls/hu/PasswordValidator.js             |    1 +
 dojox/form/nls/it/PasswordValidator.js             |    1 +
 dojox/form/nls/ja/PasswordValidator.js             |    1 +
 dojox/form/nls/ko/PasswordValidator.js             |    1 +
 dojox/form/nls/nb/PasswordValidator.js             |    1 +
 dojox/form/nls/nl/PasswordValidator.js             |    1 +
 dojox/form/nls/pl/PasswordValidator.js             |    1 +
 dojox/form/nls/pt-pt/PasswordValidator.js          |    1 +
 dojox/form/nls/pt/PasswordValidator.js             |    1 +
 dojox/form/nls/ru/PasswordValidator.js             |    1 +
 dojox/form/nls/sk/PasswordValidator.js             |    1 +
 dojox/form/nls/sl/PasswordValidator.js             |    1 +
 dojox/form/nls/sv/PasswordValidator.js             |    1 +
 dojox/form/nls/th/PasswordValidator.js             |    1 +
 dojox/form/nls/tr/PasswordValidator.js             |    1 +
 dojox/form/nls/zh-tw/PasswordValidator.js          |    1 +
 dojox/form/nls/zh/PasswordValidator.js             |    1 +
 dojox/form/resources/BusyButton.css                |    8 +
 dojox/form/resources/CheckedMultiSelect.css        |   66 +
 dojox/form/resources/CheckedMultiSelect.html       |    4 +
 dojox/form/resources/DropDownSelect.css            |  202 +
 dojox/form/resources/DropDownSelect.html           |   14 +
 dojox/form/resources/FileInput.css                 |   88 +
 dojox/form/resources/FileInput.html                |    9 +
 dojox/form/resources/FileInputAuto.html            |    9 +
 dojox/form/resources/FilePickerTextBox.css         |  468 +
 dojox/form/resources/FilePickerTextBox.html        |   18 +
 dojox/form/resources/FileUploader.css              |   61 +
 dojox/form/resources/HorizontalRangeSlider.html    |   39 +
 dojox/form/resources/PasswordValidator.html        |    3 +
 dojox/form/resources/RangeSlider.css               |   18 +
 dojox/form/resources/Rating.css                    |   20 +
 dojox/form/resources/RecieveFile.php               |   37 +
 dojox/form/resources/UploadFile.php                |  226 +
 dojox/form/resources/VerticalRangeSlider.html      |   50 +
 dojox/form/resources/_CheckedMultiSelectItem.html  |    5 +
 dojox/form/resources/cLOG.php                      |   54 +
 dojox/form/resources/images/loading_wheel.gif      |  Bin 0 -> 1266 bytes
 dojox/form/resources/images/nihiloFolderSprite.gif |  Bin 0 -> 331 bytes
 dojox/form/resources/images/rating_empty.gif       |  Bin 0 -> 934 bytes
 dojox/form/resources/images/rating_full.gif        |  Bin 0 -> 936 bytes
 dojox/form/resources/images/soriaFolderSprite.gif  |  Bin 0 -> 335 bytes
 dojox/form/resources/images/tundraFolderSprite.gif |  Bin 0 -> 318 bytes
 dojox/form/resources/uploader.swf                  |  Bin 0 -> 19253 bytes
 dojox/fx.js                                        |   12 +
 dojox/fx/README                                    |   75 +
 dojox/fx/Shadow.js                                 |  119 +
 dojox/fx/_arg.js                                   |   19 +
 dojox/fx/_base.js                                  |  122 +
 dojox/fx/_core.js                                  |   32 +
 dojox/fx/easing.js                                 |   14 +
 dojox/fx/ext-dojo/NodeList.js                      |   25 +
 dojox/fx/flip.js                                   |  183 +
 dojox/fx/resources/shadowB.png                     |  Bin 0 -> 470 bytes
 dojox/fx/resources/shadowBL.png                    |  Bin 0 -> 272 bytes
 dojox/fx/resources/shadowBR.png                    |  Bin 0 -> 271 bytes
 dojox/fx/resources/shadowL.png                     |  Bin 0 -> 148 bytes
 dojox/fx/resources/shadowR.png                     |  Bin 0 -> 149 bytes
 dojox/fx/resources/shadowT.png                     |  Bin 0 -> 152 bytes
 dojox/fx/resources/shadowTL.png                    |  Bin 0 -> 271 bytes
 dojox/fx/resources/shadowTR.png                    |  Bin 0 -> 287 bytes
 dojox/fx/scroll.js                                 |   33 +
 dojox/fx/split.js                                  |  317 +
 dojox/fx/style.js                                  |   69 +
 dojox/fx/text.js                                   |  256 +
 dojox/gfx.js                                       |   16 +
 dojox/gfx.js.uncompressed.js                       |  926 +
 dojox/gfx/Moveable.js                              |   53 +
 dojox/gfx/Mover.js                                 |   38 +
 dojox/gfx/README                                   |  102 +
 dojox/gfx/VectorText.js                            |  366 +
 dojox/gfx/_base.js                                 |  218 +
 dojox/gfx/arc.js                                   |   65 +
 dojox/gfx/attach.js                                |   12 +
 dojox/gfx/canvas.js                                |  498 +
 dojox/gfx/canvas_attach.js                         |   12 +
 dojox/gfx/decompose.js                             |  106 +
 dojox/gfx/fx.js                                    |  227 +
 dojox/gfx/matrix.js                                |  168 +
 dojox/gfx/move.js                                  |   13 +
 dojox/gfx/path.js                                  |  277 +
 dojox/gfx/resources/Gillius.svg                    | 1272 ++
 dojox/gfx/resources/README                         |    3 +
 dojox/gfx/shape.js                                 |  366 +
 dojox/gfx/silverlight.js                           |  499 +
 dojox/gfx/silverlight_attach.js                    |   73 +
 dojox/gfx/svg.js                                   |  446 +
 dojox/gfx/svg_attach.js                            |  191 +
 dojox/gfx/utils.js                                 |   84 +
 dojox/gfx/vml.js                                   |  900 +
 dojox/gfx/vml_attach.js                            |  300 +
 dojox/gfx3d.js                                     |   14 +
 dojox/gfx3d/README                                 |   36 +
 dojox/gfx3d/_base.js                               |   12 +
 dojox/gfx3d/gradient.js                            |   28 +
 dojox/gfx3d/lighting.js                            |  158 +
 dojox/gfx3d/matrix.js                              |  158 +
 dojox/gfx3d/object.js                              |  614 +
 dojox/gfx3d/scheduler.js                           |   93 +
 dojox/gfx3d/vector.js                              |   61 +
 dojox/grid/DataGrid.js                             |   16 +
 dojox/grid/DataGrid.js.uncompressed.js             |14589 +++++++++++++
 dojox/grid/DataSelection.js                        |   68 +
 dojox/grid/Grid.js                                 |   13 +
 dojox/grid/README                                  |   44 +
 dojox/grid/Selection.js                            |  189 +
 dojox/grid/VirtualGrid.js                          |   13 +
 dojox/grid/_Builder.js                             |  469 +
 dojox/grid/_EditManager.js                         |  129 +
 dojox/grid/_Events.js                              |  218 +
 dojox/grid/_FocusManager.js                        |  356 +
 dojox/grid/_Grid.js                                |  706 +
 dojox/grid/_Layout.js                              |  213 +
 dojox/grid/_RowManager.js                          |   46 +
 dojox/grid/_RowSelector.js                         |   41 +
 dojox/grid/_Scroller.js                            |  378 +
 dojox/grid/_View.js                                |  501 +
 dojox/grid/_ViewManager.js                         |  189 +
 dojox/grid/_grid/Grid.css                          |  201 +
 dojox/grid/_grid/Grid_rtl.css                      |    8 +
 dojox/grid/_grid/nihiloGrid.css                    |  211 +
 dojox/grid/_grid/soriaGrid.css                     |  212 +
 dojox/grid/_grid/tundraGrid.css                    |  215 +
 dojox/grid/cells.js                                |   12 +
 dojox/grid/cells/_base.js                          |  236 +
 dojox/grid/cells/dijit.js                          |  178 +
 dojox/grid/compat/Grid.js                          |  197 +
 dojox/grid/compat/README                           |   39 +
 dojox/grid/compat/VirtualGrid.js                   |  408 +
 dojox/grid/compat/_data/dijitEditors.js            |  128 +
 dojox/grid/compat/_data/editors.js                 |  122 +
 dojox/grid/compat/_data/fields.js                  |   84 +
 dojox/grid/compat/_data/model.js                   |  490 +
 dojox/grid/compat/_grid/Grid.css                   |  201 +
 dojox/grid/compat/_grid/Grid_rtl.css               |    8 +
 dojox/grid/compat/_grid/builder.js                 |  353 +
 dojox/grid/compat/_grid/cell.js                    |   44 +
 dojox/grid/compat/_grid/drag.js                    |   91 +
 dojox/grid/compat/_grid/edit.js                    |  128 +
 dojox/grid/compat/_grid/focus.js                   |  137 +
 .../grid/compat/_grid/images/grid_dx_gradient.gif  |  Bin 0 -> 267 bytes
 dojox/grid/compat/_grid/images/grid_sort_down.gif  |  Bin 0 -> 49 bytes
 dojox/grid/compat/_grid/images/grid_sort_up.gif    |  Bin 0 -> 48 bytes
 .../compat/_grid/images/tabEnabled_rotated.png     |  Bin 0 -> 94 bytes
 .../grid/compat/_grid/images/tabHover_rotated.png  |  Bin 0 -> 106 bytes
 dojox/grid/compat/_grid/layout.js                  |   56 +
 dojox/grid/compat/_grid/lib.js                     |  184 +
 dojox/grid/compat/_grid/nihiloGrid.css             |  211 +
 dojox/grid/compat/_grid/publicEvents.js            |  182 +
 dojox/grid/compat/_grid/rowbar.js                  |   41 +
 dojox/grid/compat/_grid/rows.js                    |   42 +
 dojox/grid/compat/_grid/scroller.js                |  373 +
 dojox/grid/compat/_grid/selection.js               |  153 +
 dojox/grid/compat/_grid/soriaGrid.css              |  212 +
 dojox/grid/compat/_grid/tundraGrid.css             |  215 +
 dojox/grid/compat/_grid/view.js                    |  214 +
 dojox/grid/compat/_grid/views.js                   |  190 +
 dojox/grid/compat/resources/GridView.html          |   12 +
 dojox/grid/compat/resources/VirtualGrid.html       |    5 +
 dojox/grid/compat/tests/databaseModel.js           |  337 +
 dojox/grid/compat/tests/images/closed.gif          |  Bin 0 -> 907 bytes
 dojox/grid/compat/tests/images/flatScreen.gif      |  Bin 0 -> 824 bytes
 dojox/grid/compat/tests/images/open.gif            |  Bin 0 -> 907 bytes
 dojox/grid/compat/tests/support/books.xml          |  103 +
 dojox/grid/compat/tests/support/data.php           |  379 +
 dojox/grid/compat/tests/support/geography.xml      |   51 +
 dojox/grid/compat/tests/support/json.php           |  794 +
 dojox/grid/compat/tests/support/movies.csv         |    9 +
 dojox/grid/compat/tests/support/test_data.js       |   30 +
 .../grid/compat/tests/support/test_data_objects.js |   31 +
 dojox/grid/compat/tests/support/testtbl.sql        |  944 +
 dojox/grid/compat/tests/support/yahoo_search.js    |  131 +
 dojox/grid/compat/tests/test_change_structure.html |  124 +
 dojox/grid/compat/tests/test_custom_sort.html      |   86 +
 dojox/grid/compat/tests/test_dojo_data_edit.html   |  124 +
 dojox/grid/compat/tests/test_dojo_data_empty.html  |   63 +
 dojox/grid/compat/tests/test_dojo_data_model.html  |   84 +
 .../tests/test_dojo_data_model_EmptyResultSet.html |   57 +
 .../tests/test_dojo_data_model_multiStores.html    |  291 +
 .../tests/test_dojo_data_model_processError.html   |   65 +
 .../compat/tests/test_dojo_data_notification.html  |  114 +
 dojox/grid/compat/tests/test_edit.html             |  149 +
 dojox/grid/compat/tests/test_edit_canEdit.html     |  156 +
 dojox/grid/compat/tests/test_edit_dijit.html       |  137 +
 dojox/grid/compat/tests/test_events.html           |  174 +
 dojox/grid/compat/tests/test_expand.html           |  107 +
 dojox/grid/compat/tests/test_grid.html             |   49 +
 dojox/grid/compat/tests/test_grid_dlg.html         |   88 +
 .../grid/compat/tests/test_grid_headerHeight.html  |   84 +
 dojox/grid/compat/tests/test_grid_layout.html      |  112 +
 .../tests/test_grid_layout_LayoutContainer.html    |   87 +
 .../tests/test_grid_layout_borderContainer.html    |   98 +
 .../tests/test_grid_object_model_change.html       |   86 +
 .../grid/compat/tests/test_grid_programmatic.html  |   65 +
 .../tests/test_grid_programmatic_layout.html       |   74 +
 dojox/grid/compat/tests/test_grid_rtl.html         |   71 +
 dojox/grid/compat/tests/test_grid_themes.html      |  118 +
 .../grid/compat/tests/test_grid_tooltip_menu.html  |  162 +
 dojox/grid/compat/tests/test_keyboard.html         |   90 +
 dojox/grid/compat/tests/test_markup.html           |  112 +
 dojox/grid/compat/tests/test_mysql_edit.html       |  155 +
 dojox/grid/compat/tests/test_sizing.html           |  175 +
 dojox/grid/compat/tests/test_sizing_100rows.html   |  168 +
 .../compat/tests/test_sizing_ResizeHandle.html     |  113 +
 dojox/grid/compat/tests/test_styling.html          |  131 +
 dojox/grid/compat/tests/test_subgrid.html          |  179 +
 dojox/grid/compat/tests/test_tundra_edit.html      |  139 +
 dojox/grid/compat/tests/test_yahoo_images.html     |  148 +
 dojox/grid/compat/tests/test_yahoo_search.html     |  141 +
 dojox/grid/compat/tests/yahooSearch.js             |  137 +
 dojox/grid/nls/DataGrid_ROOT.js                    |    1 +
 dojox/grid/nls/DataGrid_ar.js                      |    1 +
 dojox/grid/nls/DataGrid_ca.js                      |    1 +
 dojox/grid/nls/DataGrid_cs.js                      |    1 +
 dojox/grid/nls/DataGrid_da.js                      |    1 +
 dojox/grid/nls/DataGrid_de-de.js                   |    1 +
 dojox/grid/nls/DataGrid_de.js                      |    1 +
 dojox/grid/nls/DataGrid_el.js                      |    1 +
 dojox/grid/nls/DataGrid_en-gb.js                   |    1 +
 dojox/grid/nls/DataGrid_en-us.js                   |    1 +
 dojox/grid/nls/DataGrid_en.js                      |    1 +
 dojox/grid/nls/DataGrid_es-es.js                   |    1 +
 dojox/grid/nls/DataGrid_es.js                      |    1 +
 dojox/grid/nls/DataGrid_fi-fi.js                   |    1 +
 dojox/grid/nls/DataGrid_fi.js                      |    1 +
 dojox/grid/nls/DataGrid_fr-fr.js                   |    1 +
 dojox/grid/nls/DataGrid_fr.js                      |    1 +
 dojox/grid/nls/DataGrid_he-il.js                   |    1 +
 dojox/grid/nls/DataGrid_he.js                      |    1 +
 dojox/grid/nls/DataGrid_hu.js                      |    1 +
 dojox/grid/nls/DataGrid_it-it.js                   |    1 +
 dojox/grid/nls/DataGrid_it.js                      |    1 +
 dojox/grid/nls/DataGrid_ja-jp.js                   |    1 +
 dojox/grid/nls/DataGrid_ja.js                      |    1 +
 dojox/grid/nls/DataGrid_ko-kr.js                   |    1 +
 dojox/grid/nls/DataGrid_ko.js                      |    1 +
 dojox/grid/nls/DataGrid_nl-nl.js                   |    1 +
 dojox/grid/nls/DataGrid_nl.js                      |    1 +
 dojox/grid/nls/DataGrid_no.js                      |    1 +
 dojox/grid/nls/DataGrid_pl.js                      |    1 +
 dojox/grid/nls/DataGrid_pt-br.js                   |    1 +
 dojox/grid/nls/DataGrid_pt-pt.js                   |    1 +
 dojox/grid/nls/DataGrid_pt.js                      |    1 +
 dojox/grid/nls/DataGrid_ru.js                      |    1 +
 dojox/grid/nls/DataGrid_sk.js                      |    1 +
 dojox/grid/nls/DataGrid_sl.js                      |    1 +
 dojox/grid/nls/DataGrid_sv.js                      |    1 +
 dojox/grid/nls/DataGrid_th.js                      |    1 +
 dojox/grid/nls/DataGrid_tr.js                      |    1 +
 dojox/grid/nls/DataGrid_xx.js                      |    1 +
 dojox/grid/nls/DataGrid_zh-cn.js                   |    1 +
 dojox/grid/nls/DataGrid_zh-tw.js                   |    1 +
 dojox/grid/nls/DataGrid_zh.js                      |    1 +
 dojox/grid/resources/Grid.css                      |  269 +
 dojox/grid/resources/Grid_rtl.css                  |   11 +
 dojox/grid/resources/View.html                     |   12 +
 dojox/grid/resources/_Grid.html                    |    6 +
 dojox/grid/resources/images/grid_dx_gradient.gif   |  Bin 0 -> 267 bytes
 dojox/grid/resources/images/grid_sort_down.gif     |  Bin 0 -> 49 bytes
 dojox/grid/resources/images/grid_sort_up.gif       |  Bin 0 -> 48 bytes
 dojox/grid/resources/images/tabEnabled_rotated.png |  Bin 0 -> 94 bytes
 dojox/grid/resources/images/tabHover_rotated.png   |  Bin 0 -> 106 bytes
 dojox/grid/resources/nihiloGrid.css                |  399 +
 dojox/grid/resources/soriaGrid.css                 |  400 +
 dojox/grid/resources/tundraGrid.css                |  423 +
 dojox/grid/util.js                                 |   65 +
 dojox/help/README                                  |   35 +
 dojox/help/_base.js                                |  388 +
 dojox/help/console.js                              |   88 +
 dojox/highlight.js                                 |   12 +
 dojox/highlight/README                             |   31 +
 dojox/highlight/_base.js                           |  327 +
 dojox/highlight/languages/_all.js                  |   14 +
 dojox/highlight/languages/_dynamic.js              |   12 +
 dojox/highlight/languages/_static.js               |   13 +
 dojox/highlight/languages/_www.js                  |   16 +
 dojox/highlight/languages/cpp.js                   |   16 +
 dojox/highlight/languages/css.js                   |   17 +
 dojox/highlight/languages/delphi.js                |   18 +
 dojox/highlight/languages/django.js                |   18 +
 dojox/highlight/languages/html.js                  |   21 +
 dojox/highlight/languages/javascript.js            |   16 +
 dojox/highlight/languages/pygments/_html.js        |   12 +
 dojox/highlight/languages/pygments/_www.js         |   15 +
 dojox/highlight/languages/pygments/css.js          |   17 +
 dojox/highlight/languages/pygments/html.js         |   21 +
 dojox/highlight/languages/pygments/javascript.js   |   16 +
 dojox/highlight/languages/pygments/xml.js          |   14 +
 dojox/highlight/languages/python.js                |   16 +
 dojox/highlight/languages/sql.js                   |   17 +
 dojox/highlight/languages/xml.js                   |   19 +
 dojox/highlight/resources/highlight.css            |   51 +
 dojox/highlight/resources/pygments/autumn.css      |   22 +
 dojox/highlight/resources/pygments/borland.css     |   11 +
 dojox/highlight/resources/pygments/colorful.css    |   37 +
 dojox/highlight/resources/pygments/default.css     |   28 +
 dojox/highlight/resources/pygments/emacs.css       |   29 +
 dojox/highlight/resources/pygments/friendly.css    |   29 +
 dojox/highlight/resources/pygments/fruity.css      |   14 +
 dojox/highlight/resources/pygments/manni.css       |   30 +
 dojox/highlight/resources/pygments/murphy.css      |   37 +
 dojox/highlight/resources/pygments/native.css      |   21 +
 dojox/highlight/resources/pygments/pastie.css      |   30 +
 dojox/highlight/resources/pygments/perldoc.css     |   23 +
 dojox/highlight/resources/pygments/trac.css        |   20 +
 dojox/html.js                                      |   12 +
 dojox/html/README                                  |   46 +
 dojox/html/_base.js                                |  177 +
 dojox/html/metrics.js                              |  141 +
 dojox/html/styles.js                               |  194 +
 dojox/image.js                                     |   12 +
 dojox/image/Badge.js                               |  103 +
 dojox/image/FlickrBadge.js                         |   60 +
 dojox/image/Gallery.js                             |   60 +
 dojox/image/Lightbox.js                            |  246 +
 dojox/image/LightboxNano.js                        |  110 +
 dojox/image/Magnifier.js                           |   41 +
 dojox/image/MagnifierLite.js                       |   53 +
 dojox/image/README                                 |   88 +
 dojox/image/SlideShow.js                           |  371 +
 dojox/image/ThumbnailPicker.js                     |  300 +
 dojox/image/_base.js                               |   27 +
 dojox/image/resources/Badge.css                    |   30 +
 dojox/image/resources/Gallery.css                  |    5 +
 dojox/image/resources/Gallery.html                 |    4 +
 dojox/image/resources/Lightbox.css                 |   82 +
 dojox/image/resources/Lightbox.html                |   13 +
 dojox/image/resources/Magnifier.css                |    5 +
 dojox/image/resources/SlideShow.css                |  104 +
 dojox/image/resources/SlideShow.html               |   14 +
 dojox/image/resources/ThumbnailPicker.css          |  108 +
 dojox/image/resources/ThumbnailPicker.html         |   11 +
 dojox/image/resources/image.css                    |  330 +
 dojox/image/resources/images/buttons.gif           |  Bin 0 -> 4620 bytes
 dojox/image/resources/images/buttons.png           |  Bin 0 -> 9259 bytes
 dojox/image/resources/images/close.gif             |  Bin 0 -> 936 bytes
 dojox/image/resources/images/close.png             |  Bin 0 -> 675 bytes
 dojox/image/resources/images/close_dark.png        |  Bin 0 -> 711 bytes
 dojox/image/resources/images/left.gif              |  Bin 0 -> 921 bytes
 dojox/image/resources/images/left.png              |  Bin 0 -> 626 bytes
 dojox/image/resources/images/loading.gif           |  Bin 0 -> 4178 bytes
 dojox/image/resources/images/right.gif             |  Bin 0 -> 920 bytes
 dojox/image/resources/images/right.png             |  Bin 0 -> 621 bytes
 dojox/image/resources/images/warning.png           |  Bin 0 -> 995 bytes
 dojox/io/OAuth.js                                  |  174 +
 dojox/io/README                                    |   82 +
 dojox/io/httpParse.js                              |   66 +
 dojox/io/proxy/README                              |   82 +
 dojox/io/proxy/tests/frag.xml                      |    4 +
 dojox/io/proxy/tests/xip.html                      |   62 +
 dojox/io/proxy/xip.js                              |  260 +
 dojox/io/proxy/xip_client.html                     |  102 +
 dojox/io/proxy/xip_server.html                     |  382 +
 dojox/io/scriptFrame.js                            |   52 +
 dojox/io/windowName.js                             |  156 +
 dojox/io/xhrMultiPart.js                           |   71 +
 dojox/io/xhrPlugins.js                             |  110 +
 dojox/io/xhrScriptPlugin.js                        |   28 +
 dojox/io/xhrWindowNamePlugin.js                    |   37 +
 dojox/json/README                                  |   42 +
 dojox/json/query.js                                |  142 +
 dojox/json/ref.js                                  |  233 +
 dojox/json/schema.js                               |  174 +
 dojox/jsonPath.js                                  |   12 +
 dojox/jsonPath/README                              |  126 +
 dojox/jsonPath/query.js                            |  204 +
 dojox/lang/LICENSE                                 |   21 +
 dojox/lang/README                                  |   50 +
 dojox/lang/aspect.js                               |  212 +
 dojox/lang/aspect/cflow.js                         |   43 +
 dojox/lang/aspect/counter.js                       |   27 +
 dojox/lang/aspect/memoizer.js                      |   47 +
 dojox/lang/aspect/memoizerGuard.js                 |   35 +
 dojox/lang/aspect/profiler.js                      |   30 +
 dojox/lang/aspect/timer.js                         |   30 +
 dojox/lang/aspect/tracer.js                        |   38 +
 dojox/lang/functional.js                           |   14 +
 dojox/lang/functional/array.js                     |  161 +
 dojox/lang/functional/binrec.js                    |   62 +
 dojox/lang/functional/curry.js                     |   64 +
 dojox/lang/functional/fold.js                      |  104 +
 dojox/lang/functional/lambda.js                    |   89 +
 dojox/lang/functional/linrec.js                    |   62 +
 dojox/lang/functional/listcomp.js                  |   33 +
 dojox/lang/functional/multirec.js                  |   62 +
 dojox/lang/functional/numrec.js                    |   33 +
 dojox/lang/functional/object.js                    |   64 +
 dojox/lang/functional/reversed.js                  |   72 +
 dojox/lang/functional/scan.js                      |   98 +
 dojox/lang/functional/sequence.js                  |   32 +
 dojox/lang/functional/tailrec.js                   |   52 +
 dojox/lang/functional/util.js                      |   33 +
 dojox/lang/functional/zip.js                       |   28 +
 dojox/lang/observable.js                           |  153 +
 dojox/lang/oo/Decorator.js                         |   24 +
 dojox/lang/oo/Filter.js                            |   28 +
 dojox/lang/oo/aop.js                               |   55 +
 dojox/lang/oo/declare.js                           |  173 +
 dojox/lang/oo/general.js                           |   49 +
 dojox/lang/oo/mixin.js                             |   67 +
 dojox/lang/oo/rearrange.js                         |   25 +
 dojox/lang/utils.js                                |   59 +
 dojox/layout/BorderContainer.js                    |   12 +
 dojox/layout/ContentPane.js                        |   84 +
 dojox/layout/DragPane.js                           |   36 +
 dojox/layout/ExpandoPane.js                        |  125 +
 dojox/layout/FloatingPane.js                       |  222 +
 dojox/layout/GridContainer.js                      |  829 +
 dojox/layout/README                                |  115 +
 dojox/layout/RadioGroup.js                         |  139 +
 dojox/layout/ResizeHandle.js                       |  173 +
 dojox/layout/RotatorContainer.js                   |  207 +
 dojox/layout/ScrollPane.js                         |   82 +
 dojox/layout/ToggleSplitter.js                     |  131 +
 dojox/layout/dnd/Avatar.js                         |   34 +
 dojox/layout/dnd/PlottedDnd.js                     |  401 +
 .../ext-dijit/layout/StackContainer-touch.js       |   47 +
 dojox/layout/nls/GridContainer.js                  |    1 +
 dojox/layout/nls/en/GridContainer.js               |    1 +
 dojox/layout/nls/fr/GridContainer.js               |    1 +
 dojox/layout/resources/DndGridContainer.css        |   10 +
 dojox/layout/resources/ExpandoPane.css             |  166 +
 dojox/layout/resources/ExpandoPane.html            |    9 +
 dojox/layout/resources/FloatingPane.css            |  154 +
 dojox/layout/resources/FloatingPane.html           |   14 +
 dojox/layout/resources/GridContainer.css           |   73 +
 dojox/layout/resources/GridContainer.html          |    7 +
 dojox/layout/resources/RadioGroup.css              |   40 +
 dojox/layout/resources/ResizeHandle.css            |   28 +
 dojox/layout/resources/RotatorContainer.css        |   82 +
 dojox/layout/resources/ScrollPane.css              |   21 +
 dojox/layout/resources/ScrollPane.html             |    6 +
 dojox/layout/resources/ToggleSplitter.css          |   80 +
 dojox/layout/resources/icons/grip_bg.gif           |  Bin 0 -> 46 bytes
 dojox/layout/resources/icons/pixel.gif             |  Bin 0 -> 64 bytes
 dojox/layout/resources/icons/resize.png            |  Bin 0 -> 319 bytes
 dojox/layout/resources/icons/rotator.png           |  Bin 0 -> 1895 bytes
 dojox/math.js                                      |   12 +
 dojox/math/README                                  |   38 +
 dojox/math/_base.js                                |   88 +
 dojox/math/curves.js                               |  194 +
 dojox/math/matrix.js                               |  251 +
 dojox/math/round.js                                |   30 +
 dojox/off.js                                       |   12 +
 dojox/off/README                                   |   28 +
 dojox/off/_common.js                               |  178 +
 dojox/off/docs/bookmarklets.html                   |   10 +
 dojox/off/files.js                                 |  238 +
 dojox/off/network_check.txt                        |    1 +
 dojox/off/offline.js                               |   16 +
 dojox/off/offline.js.uncompressed.js               | 6243 ++++++
 dojox/off/resources/checkmark.png                  |  Bin 0 -> 27329 bytes
 dojox/off/resources/greenball.png                  |  Bin 0 -> 27414 bytes
 dojox/off/resources/learnhow.html                  |   43 +
 dojox/off/resources/learnhow.js                    |   39 +
 dojox/off/resources/offline-widget.css             |   88 +
 dojox/off/resources/offline-widget.html            |   40 +
 dojox/off/resources/redball.png                    |  Bin 0 -> 27409 bytes
 dojox/off/resources/roller.gif                     |  Bin 0 -> 7462 bytes
 dojox/off/sync.js                                  |  209 +
 dojox/off/ui.js                                    |  358 +
 dojox/resources/README.template                    |   42 +
 dojox/resources/_modules.js                        |    7 +
 dojox/resources/explore.php                        |  149 +
 dojox/robot/README                                 |   59 +
 dojox/robot/recorder.js                            |  330 +
 dojox/rpc/Client.js                                |   21 +
 dojox/rpc/JsonRPC.js                               |   39 +
 dojox/rpc/JsonRest.js                              |  278 +
 dojox/rpc/OfflineRest.js                           |  188 +
 dojox/rpc/ProxiedPath.js                           |   30 +
 dojox/rpc/README                                   |   62 +
 dojox/rpc/Rest.js                                  |   76 +
 dojox/rpc/SMDLibrary/dojo-api.smd                  |   30 +
 dojox/rpc/SMDLibrary/geonames.smd                  |  263 +
 dojox/rpc/SMDLibrary/google.smd                    |  129 +
 dojox/rpc/SMDLibrary/wikipedia.smd                 |   49 +
 dojox/rpc/SMDLibrary/yahoo.smd                     |  497 +
 dojox/rpc/Service.js                               |  217 +
 dojox/rpc/test.txt                                 |    1 +
 dojox/secure/DOM.js                                |  235 +
 dojox/secure/README                                |   50 +
 dojox/secure/capability.js                         |  102 +
 dojox/secure/sandbox.js                            |  231 +
 dojox/sketch.js                                    |   15 +
 dojox/sketch/Anchor.js                             |   69 +
 dojox/sketch/Annotation.js                         |  249 +
 dojox/sketch/DoubleArrowAnnotation.js              |  178 +
 dojox/sketch/Figure.js                             |  462 +
 dojox/sketch/LeadAnnotation.js                     |  151 +
 dojox/sketch/PreexistingAnnotation.js              |  141 +
 dojox/sketch/README                                |   58 +
 dojox/sketch/SingleArrowAnnotation.js              |  185 +
 dojox/sketch/Slider.js                             |   32 +
 dojox/sketch/Toolbar.js                            |   78 +
 dojox/sketch/UnderlineAnnotation.js                |  103 +
 dojox/sketch/UndoStack.js                          |   71 +
 dojox/sketch/_Plugin.js                            |   51 +
 dojox/sketch/resources/images/icons.gif            |  Bin 0 -> 600 bytes
 dojox/sketch/resources/sketch.css                  |   17 +
 dojox/sql.js                                       |   12 +
 dojox/sql/LICENSE                                  |    9 +
 dojox/sql/README                                   |   32 +
 dojox/sql/_base.js                                 |  333 +
 dojox/sql/_crypto.js                               |  293 +
 dojox/storage.js                                   |   12 +
 dojox/storage/AirDBStorageProvider.js              |  180 +
 dojox/storage/AirEncryptedLocalStorageProvider.js  |  170 +
 dojox/storage/AirFileStorageProvider.js            |  177 +
 dojox/storage/FlashStorageProvider.js              |  211 +
 dojox/storage/GearsStorageProvider.js              |  233 +
 dojox/storage/Provider.js                          |   69 +
 dojox/storage/README                               |   76 +
 dojox/storage/Storage.as                           |  402 +
 dojox/storage/Storage.swf                          |  Bin 0 -> 3325 bytes
 dojox/storage/WhatWGStorageProvider.js             |  158 +
 dojox/storage/_common.js                           |   17 +
 dojox/storage/buildFlashStorage.sh                 |    4 +
 dojox/storage/manager.js                           |  118 +
 dojox/storage/storage_dialog.fla                   |  Bin 0 -> 344064 bytes
 dojox/storage/storage_dialog.swf                   |  Bin 0 -> 26980 bytes
 dojox/string/BidiComplex.js                        |  246 +
 dojox/string/Builder.js                            |   91 +
 dojox/string/README                                |   39 +
 dojox/string/sprintf.js                            |  280 +
 dojox/string/tokenize.js                           |   40 +
 dojox/testing/DocTest.js                           |   91 +
 dojox/testing/README                               |   41 +
 dojox/timing.js                                    |   12 +
 dojox/timing/README                                |   63 +
 dojox/timing/Sequence.js                           |   87 +
 dojox/timing/Streamer.js                           |   64 +
 dojox/timing/ThreadPool.js                         |  142 +
 dojox/timing/_base.js                              |   41 +
 dojox/timing/doLater.js                            |   24 +
 dojox/uuid.js                                      |   12 +
 dojox/uuid/README                                  |   43 +
 dojox/uuid/Uuid.js                                 |   99 +
 dojox/uuid/_base.js                                |  136 +
 dojox/uuid/generateRandomUuid.js                   |   34 +
 dojox/uuid/generateTimeBasedUuid.js                |  197 +
 dojox/validate.js                                  |   12 +
 dojox/validate/README                              |   60 +
 dojox/validate/_base.js                            |   68 +
 dojox/validate/ca.js                               |   24 +
 dojox/validate/check.js                            |  230 +
 dojox/validate/creditCard.js                       |   48 +
 dojox/validate/isbn.js                             |   40 +
 dojox/validate/regexp.js                           |  164 +
 dojox/validate/us.js                               |   28 +
 dojox/validate/web.js                              |   40 +
 dojox/widget/AnalogGauge.js                        |  246 +
 dojox/widget/BarGauge.js                           |  194 +
 dojox/widget/Calendar.js                           |  485 +
 dojox/widget/Calendar/Calendar.css                 |  260 +
 dojox/widget/Calendar/Calendar.html                |   24 +
 dojox/widget/Calendar/CalendarDay.html             |   23 +
 dojox/widget/Calendar/CalendarMonth.html           |   12 +
 dojox/widget/Calendar/CalendarMonthYear.html       |   31 +
 dojox/widget/Calendar/CalendarYear.html            |   12 +
 dojox/widget/CalendarFx.js                         |   18 +
 dojox/widget/CalendarViews.js                      |   59 +
 dojox/widget/ColorPicker.js                        |  168 +
 dojox/widget/ColorPicker/ColorPicker.css           |   93 +
 dojox/widget/ColorPicker/ColorPicker.html          |   31 +
 dojox/widget/ColorPicker/images/hue.png            |  Bin 0 -> 1991 bytes
 dojox/widget/ColorPicker/images/hueHandle.png      |  Bin 0 -> 280 bytes
 dojox/widget/ColorPicker/images/pickerPointer.png  |  Bin 0 -> 228 bytes
 dojox/widget/ColorPicker/images/underlay.png       |  Bin 0 -> 10788 bytes
 dojox/widget/Dialog.js                             |   81 +
 dojox/widget/Dialog/Dialog.css                     |   86 +
 dojox/widget/Dialog/Dialog.html                    |   11 +
 dojox/widget/Dialog/images/dialogCloseButton.gif   |  Bin 0 -> 1408 bytes
 dojox/widget/Dialog/images/dialogCloseButton.png   |  Bin 0 -> 1357 bytes
 dojox/widget/DocTester.js                          |   70 +
 dojox/widget/DocTester/DocTester.css               |   30 +
 dojox/widget/DocTester/DocTester.html              |   10 +
 dojox/widget/FilePicker.js                         |  160 +
 dojox/widget/FilePicker/FilePicker.css             |  207 +
 dojox/widget/FilePicker/_FileInfoPane.html         |   19 +
 dojox/widget/FilePicker/images/nihiloFileIcons.gif |  Bin 0 -> 986 bytes
 dojox/widget/FilePicker/images/soriaFileIcons.gif  |  Bin 0 -> 986 bytes
 dojox/widget/FilePicker/images/tundraFileIcons.gif |  Bin 0 -> 986 bytes
 dojox/widget/FisheyeList.js                        |  428 +
 dojox/widget/FisheyeList/FisheyeList.css           |   24 +
 dojox/widget/FisheyeLite.js                        |   42 +
 dojox/widget/Iterator.js                           |   83 +
 dojox/widget/Loader.js                             |   49 +
 dojox/widget/Loader/Loader.css                     |   24 +
 dojox/widget/Loader/icons/loading.gif              |  Bin 0 -> 751 bytes
 dojox/widget/Pager.js                              |  387 +
 dojox/widget/Pager/Pager.css                       |   73 +
 dojox/widget/Pager/Pager.html                      |   13 +
 dojox/widget/Pager/images/hNext.png                |  Bin 0 -> 496 bytes
 dojox/widget/Pager/images/hPrevious.png            |  Bin 0 -> 502 bytes
 dojox/widget/Pager/images/pageActive.png           |  Bin 0 -> 276 bytes
 dojox/widget/Pager/images/pageInactive.png         |  Bin 0 -> 288 bytes
 dojox/widget/Pager/images/vNext.png                |  Bin 0 -> 500 bytes
 dojox/widget/Pager/images/vPrevious.png            |  Bin 0 -> 512 bytes
 dojox/widget/PlaceholderMenuItem.js                |   75 +
 dojox/widget/README                                |  168 +
 dojox/widget/Roller.js                             |   84 +
 dojox/widget/RollingList.js                        |  914 +
 dojox/widget/RollingList/RollingList.css           |  140 +
 dojox/widget/RollingList/RollingList.html          |   10 +
 dojox/widget/SortList.js                           |   86 +
 dojox/widget/SortList/SortList.css                 |   57 +
 dojox/widget/SortList/SortList.html                |    9 +
 dojox/widget/Standby.js                            |  138 +
 dojox/widget/Standby/Standby.css                   |   16 +
 dojox/widget/Standby/Standby.html                  |    6 +
 dojox/widget/Standby/images/loading.gif            |  Bin 0 -> 4178 bytes
 dojox/widget/Toaster.js                            |  176 +
 dojox/widget/Toaster/Toaster.css                   |   39 +
 dojox/widget/Wizard.js                             |  108 +
 dojox/widget/Wizard/Wizard.css                     |   19 +
 dojox/widget/Wizard/Wizard.html                    |    9 +
 dojox/widget/gauge/AnalogArcIndicator.js           |   69 +
 dojox/widget/gauge/AnalogArrowIndicator.js         |   28 +
 dojox/widget/gauge/AnalogNeedleIndicator.js        |   30 +
 dojox/widget/gauge/BarIndicator.js                 |   80 +
 dojox/widget/gauge/_Gauge.css                      |   51 +
 dojox/widget/gauge/_Gauge.html                     |    5 +
 dojox/widget/gauge/_Gauge.js                       |  304 +
 dojox/widget/gauge/_Indicator.html                 |    4 +
 dojox/widget/nls/FilePicker.js                     |    1 +
 dojox/widget/nls/RollingList.js                    |    1 +
 dojox/widget/nls/Wizard.js                         |    1 +
 dojox/widget/nls/ar/FilePicker.js                  |    1 +
 dojox/widget/nls/ar/Wizard.js                      |    1 +
 dojox/widget/nls/ca/FilePicker.js                  |    1 +
 dojox/widget/nls/ca/RollingList.js                 |    1 +
 dojox/widget/nls/ca/Wizard.js                      |    1 +
 dojox/widget/nls/cs/FilePicker.js                  |    1 +
 dojox/widget/nls/cs/Wizard.js                      |    1 +
 dojox/widget/nls/da/FilePicker.js                  |    1 +
 dojox/widget/nls/da/Wizard.js                      |    1 +
 dojox/widget/nls/de/FilePicker.js                  |    1 +
 dojox/widget/nls/de/Wizard.js                      |    1 +
 dojox/widget/nls/el/FilePicker.js                  |    1 +
 dojox/widget/nls/el/Wizard.js                      |    1 +
 dojox/widget/nls/es/FilePicker.js                  |    1 +
 dojox/widget/nls/es/Wizard.js                      |    1 +
 dojox/widget/nls/fi/FilePicker.js                  |    1 +
 dojox/widget/nls/fi/Wizard.js                      |    1 +
 dojox/widget/nls/fr/FilePicker.js                  |    1 +
 dojox/widget/nls/fr/Wizard.js                      |    1 +
 dojox/widget/nls/he/FilePicker.js                  |    1 +
 dojox/widget/nls/he/Wizard.js                      |    1 +
 dojox/widget/nls/hu/FilePicker.js                  |    1 +
 dojox/widget/nls/hu/Wizard.js                      |    1 +
 dojox/widget/nls/it/FilePicker.js                  |    1 +
 dojox/widget/nls/it/Wizard.js                      |    1 +
 dojox/widget/nls/ja/FilePicker.js                  |    1 +
 dojox/widget/nls/ja/Wizard.js                      |    1 +
 dojox/widget/nls/ko/FilePicker.js                  |    1 +
 dojox/widget/nls/ko/Wizard.js                      |    1 +
 dojox/widget/nls/nb/FilePicker.js                  |    1 +
 dojox/widget/nls/nb/Wizard.js                      |    1 +
 dojox/widget/nls/nl/FilePicker.js                  |    1 +
 dojox/widget/nls/nl/Wizard.js                      |    1 +
 dojox/widget/nls/pl/FilePicker.js                  |    1 +
 dojox/widget/nls/pl/Wizard.js                      |    1 +
 dojox/widget/nls/pt-pt/FilePicker.js               |    1 +
 dojox/widget/nls/pt-pt/Wizard.js                   |    1 +
 dojox/widget/nls/pt/FilePicker.js                  |    1 +
 dojox/widget/nls/pt/Wizard.js                      |    1 +
 dojox/widget/nls/ru/FilePicker.js                  |    1 +
 dojox/widget/nls/ru/Wizard.js                      |    1 +
 dojox/widget/nls/sk/FilePicker.js                  |    1 +
 dojox/widget/nls/sk/RollingList.js                 |    1 +
 dojox/widget/nls/sk/Wizard.js                      |    1 +
 dojox/widget/nls/sl/FilePicker.js                  |    1 +
 dojox/widget/nls/sl/RollingList.js                 |    1 +
 dojox/widget/nls/sl/Wizard.js                      |    1 +
 dojox/widget/nls/sv/FilePicker.js                  |    1 +
 dojox/widget/nls/sv/Wizard.js                      |    1 +
 dojox/widget/nls/th/FilePicker.js                  |    1 +
 dojox/widget/nls/th/RollingList.js                 |    1 +
 dojox/widget/nls/th/Wizard.js                      |    1 +
 dojox/widget/nls/tr/FilePicker.js                  |    1 +
 dojox/widget/nls/tr/Wizard.js                      |    1 +
 dojox/widget/nls/zh-tw/FilePicker.js               |    1 +
 dojox/widget/nls/zh-tw/Wizard.js                   |    1 +
 dojox/widget/nls/zh/FilePicker.js                  |    1 +
 dojox/widget/nls/zh/Wizard.js                      |    1 +
 dojox/wire.js                                      |   12 +
 dojox/wire/CompositeWire.js                        |   44 +
 dojox/wire/DataWire.js                             |   84 +
 dojox/wire/README                                  |   54 +
 dojox/wire/TableAdapter.js                         |   37 +
 dojox/wire/TextAdapter.js                          |   40 +
 dojox/wire/TreeAdapter.js                          |   88 +
 dojox/wire/Wire.js                                 |  231 +
 dojox/wire/XmlWire.js                              |  135 +
 dojox/wire/_base.js                                |  102 +
 dojox/wire/ml/Action.js                            |  113 +
 dojox/wire/ml/Data.js                              |   81 +
 dojox/wire/ml/DataStore.js                         |   45 +
 dojox/wire/ml/Invocation.js                        |  109 +
 dojox/wire/ml/Service.js                           |  170 +
 dojox/wire/ml/Transfer.js                          |  122 +
 dojox/wire/ml/util.js                              |  213 +
 dojox/xml/DomParser.js                             |  325 +
 dojox/xml/README                                   |   40 +
 dojox/xml/Script.js                                |   16 +
 dojox/xml/parser.js                                |  137 +
 dojox/xml/widgetParser.js                          |   69 +
 dojox/xmpp/ChatService.js                          |   90 +
 dojox/xmpp/PresenceService.js                      |  163 +
 dojox/xmpp/README                                  |   32 +
 dojox/xmpp/RosterService.js                        |  210 +
 dojox/xmpp/TransportSession.js                     |  308 +
 dojox/xmpp/UserService.js                          |   76 +
 dojox/xmpp/sasl.js                                 |   32 +
 dojox/xmpp/util.js                                 |  167 +
 dojox/xmpp/widget/ChatSession.js                   |   28 +
 dojox/xmpp/widget/templates/ChatSession.html       |    5 +
 dojox/xmpp/xmppSession.js                          |  525 +
 2165 files changed, 209664 insertions(+)

diff --git a/dijit/CheckedMenuItem.js b/dijit/CheckedMenuItem.js
new file mode 100644
index 0000000..6aa5d3b
--- /dev/null
+++ b/dijit/CheckedMenuItem.js
@@ -0,0 +1,24 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.CheckedMenuItem"]){
+dojo._hasResource["dijit.CheckedMenuItem"]=true;
+dojo.provide("dijit.CheckedMenuItem");
+dojo.require("dijit.MenuItem");
+dojo.declare("dijit.CheckedMenuItem",dijit.MenuItem,{templateString:"<tr class=\"dijitReset dijitMenuItem\" dojoAttachPoint=\"focusNode\" waiRole=\"menuitemcheckbox\" tabIndex=\"-1\"\n\t\tdojoAttachEvent=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset\" waiRole=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon dijitCheckedMenuItemIcon\" dojoAttachPoint=\"iconNode\">\n\t\t<span class=\"dijitCheckedMenuIte [...]
+dojo.toggleClass(this.domNode,"dijitCheckedMenuItemChecked",_1);
+dijit.setWaiState(this.domNode,"checked",_1);
+this.checked=_1;
+},onChange:function(_2){
+},_onClick:function(e){
+if(!this.disabled){
+this.attr("checked",!this.checked);
+this.onChange(this.checked);
+}
+this.inherited(arguments);
+}});
+}
diff --git a/dijit/ColorPalette.js b/dijit/ColorPalette.js
new file mode 100644
index 0000000..4891585
--- /dev/null
+++ b/dijit/ColorPalette.js
@@ -0,0 +1,110 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.ColorPalette"]){
+dojo._hasResource["dijit.ColorPalette"]=true;
+dojo.provide("dijit.ColorPalette");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dojo.colors");
+dojo.require("dojo.i18n");
+dojo.requireLocalization("dojo","colors",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.declare("dijit.ColorPalette",[dijit._Widget,dijit._Templated],{defaultTimeout:500,timeoutChangeRate:0.9,palette:"7x10",value:null,_currentFocus:0,_xDim:null,_yDim:null,_palettes:{"7x10":[["white","seashell","cornsilk","lemonchiffon","lightyellow","palegreen","paleturquoise","lightcyan","lavender","plum"],["lightgray","pink","bisque","moccasin","khaki","lightgreen","lightseagreen","lightskyblue","cornflowerblue","violet"],["silver","lightcoral","sandybrown","orange","palegoldenrod"," [...]
+dojo.mixin(this.divNode.style,this._paletteDims[this.palette]);
+this.imageNode.setAttribute("src",this._imagePaths[this.palette]);
+var _1=this._palettes[this.palette];
+this.domNode.style.position="relative";
+this._cellNodes=[];
+this.colorNames=dojo.i18n.getLocalization("dojo","colors",this.lang);
+var _2=this._blankGif,_3=new dojo.Color(),_4=this._paletteCoords;
+for(var _5=0;_5<_1.length;_5++){
+for(var _6=0;_6<_1[_5].length;_6++){
+var _7=_1[_5][_6],_8=_3.setColor(dojo.Color.named[_7]);
+var _9=dojo.create("span",{"class":"dijitPaletteCell","tabindex":"-1",title:this.colorNames[_7],style:{top:_4.topOffset+(_5*_4.cHeight)+"px",left:_4.leftOffset+(_6*_4.cWidth)+"px"}});
+var _a=dojo.create("img",{src:_2,"class":"dijitPaletteImg",alt:this.colorNames[_7]},_9);
+_a.color=_8.toHex();
+var _b=_a.style;
+_b.color=_b.backgroundColor=_a.color;
+dojo.forEach(["Dijitclick","MouseEnter","Focus","Blur"],function(_c){
+this.connect(_9,"on"+_c.toLowerCase(),"_onCell"+_c);
+},this);
+dojo.place(_9,this.divNode);
+dijit.setWaiRole(_9,"gridcell");
+_9.index=this._cellNodes.length;
+this._cellNodes.push(_9);
+}
+}
+this._xDim=_1[0].length;
+this._yDim=_1.length;
+this.connect(this.divNode,"onfocus","_onDivNodeFocus");
+var _d={UP_ARROW:-this._xDim,DOWN_ARROW:this._xDim,RIGHT_ARROW:1,LEFT_ARROW:-1};
+for(var _e in _d){
+this._connects.push(dijit.typematic.addKeyListener(this.domNode,{charOrCode:dojo.keys[_e],ctrlKey:false,altKey:false,shiftKey:false},this,function(){
+var _f=_d[_e];
+return function(_10){
+this._navigateByKey(_f,_10);
+};
+}(),this.timeoutChangeRate,this.defaultTimeout));
+}
+},focus:function(){
+this._focusFirst();
+},onChange:function(_11){
+},_focusFirst:function(){
+this._currentFocus=0;
+var _12=this._cellNodes[this._currentFocus];
+window.setTimeout(function(){
+dijit.focus(_12);
+},0);
+},_onDivNodeFocus:function(evt){
+if(evt.target===this.divNode){
+this._focusFirst();
+}
+},_onFocus:function(){
+dojo.attr(this.divNode,"tabindex","-1");
+},_onBlur:function(){
+this._removeCellHighlight(this._currentFocus);
+dojo.attr(this.divNode,"tabindex",this.tabIndex);
+},_onCellDijitclick:function(evt){
+var _15=evt.currentTarget;
+if(this._currentFocus!=_15.index){
+this._currentFocus=_15.index;
+window.setTimeout(function(){
+dijit.focus(_15);
+},0);
+}
+this._selectColor(_15);
+dojo.stopEvent(evt);
+},_onCellMouseEnter:function(evt){
+var _17=evt.currentTarget;
+this._setCurrent(_17);
+window.setTimeout(function(){
+dijit.focus(_17);
+},0);
+},_onCellFocus:function(evt){
+this._setCurrent(evt.currentTarget);
+},_setCurrent:function(_19){
+this._removeCellHighlight(this._currentFocus);
+this._currentFocus=_19.index;
+dojo.addClass(_19,"dijitPaletteCellHighlight");
+},_onCellBlur:function(evt){
+this._removeCellHighlight(this._currentFocus);
+},_removeCellHighlight:function(_1b){
+dojo.removeClass(this._cellNodes[_1b],"dijitPaletteCellHighlight");
+},_selectColor:function(_1c){
+var img=_1c.getElementsByTagName("img")[0];
+this.onChange(this.value=img.color);
+},_navigateByKey:function(_1e,_1f){
+if(_1f==-1){
+return;
+}
+var _20=this._currentFocus+_1e;
+if(_20<this._cellNodes.length&&_20>-1){
+var _21=this._cellNodes[_20];
+_21.focus();
+}
+}});
+}
diff --git a/dijit/Declaration.js b/dijit/Declaration.js
new file mode 100644
index 0000000..f90ae68
--- /dev/null
+++ b/dijit/Declaration.js
@@ -0,0 +1,36 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.Declaration"]){
+dojo._hasResource["dijit.Declaration"]=true;
+dojo.provide("dijit.Declaration");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.declare("dijit.Declaration",dijit._Widget,{_noScript:true,widgetClass:"",defaults:null,mixins:[],buildRendering:function(){
+var _1=this.srcNodeRef.parentNode.removeChild(this.srcNodeRef),_2=dojo.query("> script[type^='dojo/method'][event]",_1).orphan(),_3=dojo.query("> script[type^='dojo/method']",_1).orphan(),_4=dojo.query("> script[type^='dojo/connect']",_1).orphan(),_5=_1.nodeName;
+var _6=this.defaults||{};
+dojo.forEach(_2,function(s){
+var _8=s.getAttribute("event"),_9=dojo.parser._functionFromScript(s);
+_6[_8]=_9;
+});
+this.mixins=this.mixins.length?dojo.map(this.mixins,function(_a){
+return dojo.getObject(_a);
+}):[dijit._Widget,dijit._Templated];
+_6.widgetsInTemplate=true;
+_6._skipNodeCache=true;
+_6.templateString="<"+_5+" class='"+_1.className+"' dojoAttachPoint='"+(_1.getAttribute("dojoAttachPoint")||"")+"' dojoAttachEvent='"+(_1.getAttribute("dojoAttachEvent")||"")+"' >"+_1.innerHTML.replace(/\%7B/g,"{").replace(/\%7D/g,"}")+"</"+_5+">";
+dojo.query("[dojoType]",_1).forEach(function(_b){
+_b.removeAttribute("dojoType");
+});
+var wc=dojo.declare(this.widgetClass,this.mixins,_6);
+var _d=_4.concat(_3);
+dojo.forEach(_d,function(s){
+var _f=s.getAttribute("event")||"postscript",_10=dojo.parser._functionFromScript(s);
+dojo.connect(wc.prototype,_f,_10);
+});
+}});
+}
diff --git a/dijit/Dialog.js b/dijit/Dialog.js
new file mode 100644
index 0000000..6284e6f
--- /dev/null
+++ b/dijit/Dialog.js
@@ -0,0 +1,211 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.Dialog"]){
+dojo._hasResource["dijit.Dialog"]=true;
+dojo.provide("dijit.Dialog");
+dojo.require("dojo.dnd.move");
+dojo.require("dojo.dnd.TimedMoveable");
+dojo.require("dojo.fx");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dijit.form._FormMixin");
+dojo.require("dijit._DialogMixin");
+dojo.require("dijit.DialogUnderlay");
+dojo.require("dijit.layout.ContentPane");
+dojo.requireLocalization("dijit","common",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.declare("dijit.Dialog",[dijit.layout.ContentPane,dijit._Templated,dijit.form._FormMixin,dijit._DialogMixin],{templateString:null,templateString:"<div class=\"dijitDialog\" tabindex=\"-1\" waiRole=\"dialog\" waiState=\"labelledby-${id}_title\">\n\t<div dojoAttachPoint=\"titleBar\" class=\"dijitDialogTitleBar\">\n\t<span dojoAttachPoint=\"titleNode\" class=\"dijitDialogTitle\" id=\"${id}_title\"></span>\n\t<span dojoAttachPoint=\"closeButtonNode\" class=\"dijitDialogCloseIcon\" dojoAt [...]
+var _1=dojo.i18n.getLocalization("dijit","common");
+dojo.mixin(this,_1);
+this.inherited(arguments);
+},postCreate:function(){
+dojo.style(this.domNode,{visibility:"hidden",position:"absolute",display:"",top:"-9999px"});
+dojo.body().appendChild(this.domNode);
+this.inherited(arguments);
+this.connect(this,"onExecute","hide");
+this.connect(this,"onCancel","hide");
+this._modalconnects=[];
+},onLoad:function(){
+this._position();
+this.inherited(arguments);
+},_endDrag:function(e){
+if(e&&e.node&&e.node===this.domNode){
+var vp=dijit.getViewport();
+var p=e._leftTop||dojo.coords(e.node,true);
+this._relativePosition={t:p.t-vp.t,l:p.l-vp.l};
+}
+},_setup:function(){
+var _5=this.domNode;
+if(this.titleBar&&this.draggable){
+this._moveable=(dojo.isIE==6)?new dojo.dnd.TimedMoveable(_5,{handle:this.titleBar}):new dojo.dnd.Moveable(_5,{handle:this.titleBar,timeout:0});
+dojo.subscribe("/dnd/move/stop",this,"_endDrag");
+}else{
+dojo.addClass(_5,"dijitDialogFixed");
+}
+var _6={dialogId:this.id,"class":dojo.map(this["class"].split(/\s/),function(s){
+return s+"_underlay";
+}).join(" ")};
+var _8=dijit._underlay;
+if(!_8){
+_8=dijit._underlay=new dijit.DialogUnderlay(_6);
+}
+this._fadeIn=dojo.fadeIn({node:_5,duration:this.duration,beforeBegin:function(){
+_8.attr(_6);
+_8.show();
+},onEnd:dojo.hitch(this,function(){
+if(this.autofocus){
+this._getFocusItems(this.domNode);
+dijit.focus(this._firstFocusItem);
+}
+})});
+this._fadeOut=dojo.fadeOut({node:_5,duration:this.duration,onEnd:function(){
+_5.style.visibility="hidden";
+_5.style.top="-9999px";
+dijit._underlay.hide();
+}});
+},uninitialize:function(){
+var _9=false;
+if(this._fadeIn&&this._fadeIn.status()=="playing"){
+_9=true;
+this._fadeIn.stop();
+}
+if(this._fadeOut&&this._fadeOut.status()=="playing"){
+_9=true;
+this._fadeOut.stop();
+}
+if(this.open||_9){
+dijit._underlay.hide();
+}
+if(this._moveable){
+this._moveable.destroy();
+}
+},_size:function(){
+var mb=dojo.marginBox(this.domNode);
+var _b=dijit.getViewport();
+if(mb.w>=_b.w||mb.h>=_b.h){
+dojo.style(this.containerNode,{width:Math.min(mb.w,Math.floor(_b.w*0.75))+"px",height:Math.min(mb.h,Math.floor(_b.h*0.75))+"px",overflow:"auto",position:"relative"});
+}
+},_position:function(){
+if(!dojo.hasClass(dojo.body(),"dojoMove")){
+var _c=this.domNode;
+var _d=dijit.getViewport();
+var p=this._relativePosition;
+var mb=p?null:dojo.marginBox(_c);
+dojo.style(_c,{left:Math.floor(_d.l+(p?p.l:(_d.w-mb.w)/2))+"px",top:Math.floor(_d.t+(p?p.t:(_d.h-mb.h)/2))+"px"});
+}
+},_onKey:function(evt){
+if(evt.charOrCode){
+var dk=dojo.keys;
+var _12=evt.target;
+if(evt.charOrCode===dk.TAB){
+this._getFocusItems(this.domNode);
+}
+var _13=(this._firstFocusItem==this._lastFocusItem);
+if(_12==this._firstFocusItem&&evt.shiftKey&&evt.charOrCode===dk.TAB){
+if(!_13){
+dijit.focus(this._lastFocusItem);
+}
+dojo.stopEvent(evt);
+}else{
+if(_12==this._lastFocusItem&&evt.charOrCode===dk.TAB&&!evt.shiftKey){
+if(!_13){
+dijit.focus(this._firstFocusItem);
+}
+dojo.stopEvent(evt);
+}else{
+while(_12){
+if(_12==this.domNode){
+if(evt.charOrCode==dk.ESCAPE){
+this.onCancel();
+}else{
+return;
+}
+}
+_12=_12.parentNode;
+}
+if(evt.charOrCode!==dk.TAB){
+dojo.stopEvent(evt);
+}else{
+if(!dojo.isOpera){
+try{
+this._firstFocusItem.focus();
+}
+catch(e){
+}
+}
+}
+}
+}
+}
+},show:function(){
+if(this.open){
+return;
+}
+if(!this._alreadyInitialized){
+this._setup();
+this._alreadyInitialized=true;
+}
+if(this._fadeOut.status()=="playing"){
+this._fadeOut.stop();
+}
+this._modalconnects.push(dojo.connect(window,"onscroll",this,"layout"));
+this._modalconnects.push(dojo.connect(window,"onresize",this,function(){
+var _14=dijit.getViewport();
+if(!this._oldViewport||_14.h!=this._oldViewport.h||_14.w!=this._oldViewport.w){
+this.layout();
+this._oldViewport=_14;
+}
+}));
+this._modalconnects.push(dojo.connect(dojo.doc.documentElement,"onkeypress",this,"_onKey"));
+dojo.style(this.domNode,{opacity:0,visibility:""});
+if(this._fixSizes){
+dojo.style(this.containerNode,{width:"auto",height:"auto"});
+}
+this.open=true;
+this._onShow();
+this._size();
+this._position();
+this._fadeIn.play();
+this._savedFocus=dijit.getFocus(this);
+},hide:function(){
+if(!this._alreadyInitialized){
+return;
+}
+if(this._fadeIn.status()=="playing"){
+this._fadeIn.stop();
+}
+this._fadeOut.play();
+if(this._scrollConnected){
+this._scrollConnected=false;
+}
+dojo.forEach(this._modalconnects,dojo.disconnect);
+this._modalconnects=[];
+if(this.refocus){
+this.connect(this._fadeOut,"onEnd",dojo.hitch(dijit,"focus",this._savedFocus));
+}
+if(this._relativePosition){
+delete this._relativePosition;
+}
+this.open=false;
+},layout:function(){
+if(this.domNode.style.visibility!="hidden"){
+dijit._underlay.layout();
+this._position();
+}
+},destroy:function(){
+dojo.forEach(this._modalconnects,dojo.disconnect);
+if(this.refocus&&this.open){
+setTimeout(dojo.hitch(dijit,"focus",this._savedFocus),25);
+}
+this.inherited(arguments);
+},_onCloseEnter:function(){
+dojo.addClass(this.closeButtonNode,"dijitDialogCloseIcon-hover");
+},_onCloseLeave:function(){
+dojo.removeClass(this.closeButtonNode,"dijitDialogCloseIcon-hover");
+}});
+dojo.require("dijit.TooltipDialog");
+}
diff --git a/dijit/DialogUnderlay.js b/dijit/DialogUnderlay.js
new file mode 100644
index 0000000..e1b897a
--- /dev/null
+++ b/dijit/DialogUnderlay.js
@@ -0,0 +1,45 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.DialogUnderlay"]){
+dojo._hasResource["dijit.DialogUnderlay"]=true;
+dojo.provide("dijit.DialogUnderlay");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.declare("dijit.DialogUnderlay",[dijit._Widget,dijit._Templated],{templateString:"<div class='dijitDialogUnderlayWrapper'><div class='dijitDialogUnderlay' dojoAttachPoint='node'></div></div>",dialogId:"","class":"",attributeMap:{id:"domNode"},_setDialogIdAttr:function(id){
+dojo.attr(this.node,"id",id+"_underlay");
+},_setClassAttr:function(_2){
+this.node.className="dijitDialogUnderlay "+_2;
+},postCreate:function(){
+dojo.body().appendChild(this.domNode);
+this.bgIframe=new dijit.BackgroundIframe(this.domNode);
+},layout:function(){
+var is=this.node.style,os=this.domNode.style;
+os.display="none";
+var _5=dijit.getViewport();
+os.top=_5.t+"px";
+os.left=_5.l+"px";
+is.width=_5.w+"px";
+is.height=_5.h+"px";
+os.display="block";
+},show:function(){
+this.domNode.style.display="block";
+this.layout();
+if(this.bgIframe.iframe){
+this.bgIframe.iframe.style.display="block";
+}
+},hide:function(){
+this.domNode.style.display="none";
+if(this.bgIframe.iframe){
+this.bgIframe.iframe.style.display="none";
+}
+},uninitialize:function(){
+if(this.bgIframe){
+this.bgIframe.destroy();
+}
+}});
+}
diff --git a/dijit/Editor.js b/dijit/Editor.js
new file mode 100644
index 0000000..e63aa26
--- /dev/null
+++ b/dijit/Editor.js
@@ -0,0 +1,356 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.Editor"]){
+dojo._hasResource["dijit.Editor"]=true;
+dojo.provide("dijit.Editor");
+dojo.require("dijit._editor.RichText");
+dojo.require("dijit.Toolbar");
+dojo.require("dijit.ToolbarSeparator");
+dojo.require("dijit._editor._Plugin");
+dojo.require("dijit._editor.plugins.EnterKeyHandling");
+dojo.require("dijit._editor.range");
+dojo.require("dijit._Container");
+dojo.require("dojo.i18n");
+dojo.requireLocalization("dijit._editor","commands",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.declare("dijit.Editor",dijit._editor.RichText,{plugins:null,extraPlugins:null,constructor:function(){
+if(!dojo.isArray(this.plugins)){
+this.plugins=["undo","redo","|","cut","copy","paste","|","bold","italic","underline","strikethrough","|","insertOrderedList","insertUnorderedList","indent","outdent","|","justifyLeft","justifyRight","justifyCenter","justifyFull","dijit._editor.plugins.EnterKeyHandling"];
+}
+this._plugins=[];
+this._editInterval=this.editActionInterval*1000;
+if(dojo.isIE){
+this.events.push("onBeforeDeactivate");
+}
+},postCreate:function(){
+if(this.customUndo){
+dojo["require"]("dijit._editor.range");
+this._steps=this._steps.slice(0);
+this._undoedSteps=this._undoedSteps.slice(0);
+}
+if(dojo.isArray(this.extraPlugins)){
+this.plugins=this.plugins.concat(this.extraPlugins);
+}
+this.inherited(arguments);
+this.commands=dojo.i18n.getLocalization("dijit._editor","commands",this.lang);
+if(!this.toolbar){
+this.toolbar=new dijit.Toolbar({});
+dojo.place(this.toolbar.domNode,this.editingArea,"before");
+}
+dojo.forEach(this.plugins,this.addPlugin,this);
+this.onNormalizedDisplayChanged();
+this.toolbar.startup();
+},destroy:function(){
+dojo.forEach(this._plugins,function(p){
+if(p&&p.destroy){
+p.destroy();
+}
+});
+this._plugins=[];
+this.toolbar.destroyRecursive();
+delete this.toolbar;
+this.inherited(arguments);
+},addPlugin:function(_2,_3){
+var _4=dojo.isString(_2)?{name:_2}:_2;
+if(!_4.setEditor){
+var o={"args":_4,"plugin":null,"editor":this};
+dojo.publish(dijit._scopeName+".Editor.getPlugin",[o]);
+if(!o.plugin){
+var pc=dojo.getObject(_4.name);
+if(pc){
+o.plugin=new pc(_4);
+}
+}
+if(!o.plugin){
+console.warn("Cannot find plugin",_2);
+return;
+}
+_2=o.plugin;
+}
+if(arguments.length>1){
+this._plugins[_3]=_2;
+}else{
+this._plugins.push(_2);
+}
+_2.setEditor(this);
+if(dojo.isFunction(_2.setToolbar)){
+_2.setToolbar(this.toolbar);
+}
+},startup:function(){
+},resize:function(_7){
+dijit.layout._LayoutWidget.prototype.resize.apply(this,arguments);
+},layout:function(){
+this.editingArea.style.height=(this._contentBox.h-dojo.marginBox(this.toolbar.domNode).h)+"px";
+if(this.iframe){
+this.iframe.style.height="100%";
+}
+this._layoutMode=true;
+},_onIEMouseDown:function(e){
+delete this._savedSelection;
+if(e.target.tagName=="BODY"){
+setTimeout(dojo.hitch(this,"placeCursorAtEnd"),0);
+}
+this.inherited(arguments);
+},onBeforeDeactivate:function(e){
+if(this.customUndo){
+this.endEditing(true);
+}
+this._saveSelection();
+},customUndo:dojo.isIE,editActionInterval:3,beginEditing:function(_a){
+if(!this._inEditing){
+this._inEditing=true;
+this._beginEditing(_a);
+}
+if(this.editActionInterval>0){
+if(this._editTimer){
+clearTimeout(this._editTimer);
+}
+this._editTimer=setTimeout(dojo.hitch(this,this.endEditing),this._editInterval);
+}
+},_steps:[],_undoedSteps:[],execCommand:function(_b){
+if(this.customUndo&&(_b=="undo"||_b=="redo")){
+return this[_b]();
+}else{
+if(this.customUndo){
+this.endEditing();
+this._beginEditing();
+}
+try{
+var r=this.inherited("execCommand",arguments);
+if(dojo.isWebKit&&_b=="paste"&&!r){
+throw {code:1011};
+}
+}
+catch(e){
+if(e.code==1011&&/copy|cut|paste/.test(_b)){
+var _d=dojo.string.substitute,_e={cut:"X",copy:"C",paste:"V"},_f=navigator.userAgent.indexOf("Macintosh")!=-1;
+alert(_d(this.commands.systemShortcut,[this.commands[_b],_d(this.commands[_f?"appleKey":"ctrlKey"],[_e[_b]])]));
+}
+r=false;
+}
+if(this.customUndo){
+this._endEditing();
+}
+return r;
+}
+},queryCommandEnabled:function(cmd){
+if(this.customUndo&&(cmd=="undo"||cmd=="redo")){
+return cmd=="undo"?(this._steps.length>1):(this._undoedSteps.length>0);
+}else{
+return this.inherited("queryCommandEnabled",arguments);
+}
+},focus:function(){
+var _11=0;
+if(this._savedSelection&&dojo.isIE){
+_11=dijit._curFocus!=this.editNode;
+}
+this.inherited(arguments);
+if(_11){
+this._restoreSelection();
+}
+},_moveToBookmark:function(b){
+var _13=b;
+if(dojo.isIE){
+if(dojo.isArray(b)){
+_13=[];
+dojo.forEach(b,function(n){
+_13.push(dijit.range.getNode(n,this.editNode));
+},this);
+}
+}else{
+var r=dijit.range.create();
+r.setStart(dijit.range.getNode(b.startContainer,this.editNode),b.startOffset);
+r.setEnd(dijit.range.getNode(b.endContainer,this.editNode),b.endOffset);
+_13=r;
+}
+dojo.withGlobal(this.window,"moveToBookmark",dijit,[_13]);
+},_changeToStep:function(_16,to){
+this.setValue(to.text);
+var b=to.bookmark;
+if(!b){
+return;
+}
+this._moveToBookmark(b);
+},undo:function(){
+this.endEditing(true);
+var s=this._steps.pop();
+if(this._steps.length>0){
+this.focus();
+this._changeToStep(s,this._steps[this._steps.length-1]);
+this._undoedSteps.push(s);
+this.onDisplayChanged();
+return true;
+}
+return false;
+},redo:function(){
+this.endEditing(true);
+var s=this._undoedSteps.pop();
+if(s&&this._steps.length>0){
+this.focus();
+this._changeToStep(this._steps[this._steps.length-1],s);
+this._steps.push(s);
+this.onDisplayChanged();
+return true;
+}
+return false;
+},endEditing:function(_1b){
+if(this._editTimer){
+clearTimeout(this._editTimer);
+}
+if(this._inEditing){
+this._endEditing(_1b);
+this._inEditing=false;
+}
+},_getBookmark:function(){
+var b=dojo.withGlobal(this.window,dijit.getBookmark);
+var tmp=[];
+if(dojo.isIE){
+if(dojo.isArray(b)){
+dojo.forEach(b,function(n){
+tmp.push(dijit.range.getIndex(n,this.editNode).o);
+},this);
+b=tmp;
+}
+}else{
+tmp=dijit.range.getIndex(b.startContainer,this.editNode).o;
+b={startContainer:tmp,startOffset:b.startOffset,endContainer:b.endContainer===b.startContainer?tmp:dijit.range.getIndex(b.endContainer,this.editNode).o,endOffset:b.endOffset};
+}
+return b;
+},_beginEditing:function(cmd){
+if(this._steps.length===0){
+this._steps.push({"text":this.savedContent,"bookmark":this._getBookmark()});
+}
+},_endEditing:function(_20){
+var v=this.getValue(true);
+this._undoedSteps=[];
+this._steps.push({text:v,bookmark:this._getBookmark()});
+},onKeyDown:function(e){
+if(!dojo.isIE&&!this.iframe&&e.keyCode==dojo.keys.TAB&&!this.tabIndent){
+this._saveSelection();
+}
+if(!this.customUndo){
+this.inherited(arguments);
+return;
+}
+var k=e.keyCode,ks=dojo.keys;
+if(e.ctrlKey&&!e.altKey){
+if(k==90||k==122){
+dojo.stopEvent(e);
+this.undo();
+return;
+}else{
+if(k==89||k==121){
+dojo.stopEvent(e);
+this.redo();
+return;
+}
+}
+}
+this.inherited(arguments);
+switch(k){
+case ks.ENTER:
+case ks.BACKSPACE:
+case ks.DELETE:
+this.beginEditing();
+break;
+case 88:
+case 86:
+if(e.ctrlKey&&!e.altKey&&!e.metaKey){
+this.endEditing();
+if(e.keyCode==88){
+this.beginEditing("cut");
+setTimeout(dojo.hitch(this,this.endEditing),1);
+}else{
+this.beginEditing("paste");
+setTimeout(dojo.hitch(this,this.endEditing),1);
+}
+break;
+}
+default:
+if(!e.ctrlKey&&!e.altKey&&!e.metaKey&&(e.keyCode<dojo.keys.F1||e.keyCode>dojo.keys.F15)){
+this.beginEditing();
+break;
+}
+case ks.ALT:
+this.endEditing();
+break;
+case ks.UP_ARROW:
+case ks.DOWN_ARROW:
+case ks.LEFT_ARROW:
+case ks.RIGHT_ARROW:
+case ks.HOME:
+case ks.END:
+case ks.PAGE_UP:
+case ks.PAGE_DOWN:
+this.endEditing(true);
+break;
+case ks.CTRL:
+case ks.SHIFT:
+case ks.TAB:
+break;
+}
+},_onBlur:function(){
+this.inherited("_onBlur",arguments);
+this.endEditing(true);
+},_saveSelection:function(){
+this._savedSelection=this._getBookmark();
+},_restoreSelection:function(){
+if(this._savedSelection){
+if(dojo.withGlobal(this.window,"isCollapsed",dijit)){
+this._moveToBookmark(this._savedSelection);
+}
+delete this._savedSelection;
+}
+},_onFocus:function(){
+setTimeout(dojo.hitch(this,"_restoreSelection"),0);
+this.inherited(arguments);
+},onClick:function(){
+this.endEditing(true);
+this.inherited(arguments);
+}});
+dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
+if(o.plugin){
+return;
+}
+var _26=o.args,p;
+var _p=dijit._editor._Plugin;
+var _29=_26.name;
+switch(_29){
+case "undo":
+case "redo":
+case "cut":
+case "copy":
+case "paste":
+case "insertOrderedList":
+case "insertUnorderedList":
+case "indent":
+case "outdent":
+case "justifyCenter":
+case "justifyFull":
+case "justifyLeft":
+case "justifyRight":
+case "delete":
+case "selectAll":
+case "removeFormat":
+case "unlink":
+case "insertHorizontalRule":
+p=new _p({command:_29});
+break;
+case "bold":
+case "italic":
+case "underline":
+case "strikethrough":
+case "subscript":
+case "superscript":
+p=new _p({buttonClass:dijit.form.ToggleButton,command:_29});
+break;
+case "|":
+p=new _p({button:new dijit.ToolbarSeparator()});
+}
+o.plugin=p;
+});
+}
diff --git a/dijit/InlineEditBox.js b/dijit/InlineEditBox.js
new file mode 100644
index 0000000..6a13b40
--- /dev/null
+++ b/dijit/InlineEditBox.js
@@ -0,0 +1,208 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.InlineEditBox"]){
+dojo._hasResource["dijit.InlineEditBox"]=true;
+dojo.provide("dijit.InlineEditBox");
+dojo.require("dojo.i18n");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Container");
+dojo.require("dijit.form.Button");
+dojo.require("dijit.form.TextBox");
+dojo.requireLocalization("dijit","common",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.declare("dijit.InlineEditBox",dijit._Widget,{editing:false,autoSave:true,buttonSave:"",buttonCancel:"",renderAsHtml:false,editor:"dijit.form.TextBox",editorParams:{},onChange:function(_1){
+},onCancel:function(){
+},width:"100%",value:"",noValueIndicator:"<span style='font-family: wingdings; text-decoration: underline;'>    &#x270d;    </span>",constructor:function(){
+this.editorParams={};
+},postMixInProperties:function(){
+this.inherited(arguments);
+this.displayNode=this.srcNodeRef;
+var _2={ondijitclick:"_onClick",onmouseover:"_onMouseOver",onmouseout:"_onMouseOut",onfocus:"_onMouseOver",onblur:"_onMouseOut"};
+for(var _3 in _2){
+this.connect(this.displayNode,_3,_2[_3]);
+}
+dijit.setWaiRole(this.displayNode,"button");
+if(!this.displayNode.getAttribute("tabIndex")){
+this.displayNode.setAttribute("tabIndex",0);
+}
+this.attr("value",this.value||this.displayNode.innerHTML);
+},setDisabled:function(_4){
+dojo.deprecated("dijit.InlineEditBox.setDisabled() is deprecated.  Use attr('disabled', bool) instead.","","2.0");
+this.attr("disabled",_4);
+},_setDisabledAttr:function(_5){
+this.disabled=_5;
+dijit.setWaiState(this.domNode,"disabled",_5);
+},_onMouseOver:function(){
+dojo.addClass(this.displayNode,this.disabled?"dijitDisabledClickableRegion":"dijitClickableRegion");
+},_onMouseOut:function(){
+dojo.removeClass(this.displayNode,this.disabled?"dijitDisabledClickableRegion":"dijitClickableRegion");
+},_onClick:function(e){
+if(this.disabled){
+return;
+}
+if(e){
+dojo.stopEvent(e);
+}
+this._onMouseOut();
+setTimeout(dojo.hitch(this,"edit"),0);
+},edit:function(){
+if(this.disabled||this.editing){
+return;
+}
+this.editing=true;
+var _7=(this.renderAsHtml?this.value:this.value.replace(/\s*\r?\n\s*/g,"").replace(/<br\/?>/gi,"\n").replace(/>/g,">").replace(/</g,"<").replace(/&/g,"&").replace(/"/g,"\""));
+var _8=dojo.create("span",null,this.domNode,"before");
+var ew=this.editWidget=new dijit._InlineEditor({value:dojo.trim(_7),autoSave:this.autoSave,buttonSave:this.buttonSave,buttonCancel:this.buttonCancel,renderAsHtml:this.renderAsHtml,editor:this.editor,editorParams:this.editorParams,sourceStyle:dojo.getComputedStyle(this.displayNode),save:dojo.hitch(this,"save"),cancel:dojo.hitch(this,"cancel"),width:this.width},_8);
+var _a=ew.domNode.style;
+this.displayNode.style.display="none";
+_a.position="static";
+_a.visibility="visible";
+this.domNode=ew.domNode;
+setTimeout(function(){
+ew.focus();
+ew._resetValue=ew.getValue();
+},100);
+},_showText:function(_b){
+this.displayNode.style.display="";
+var ew=this.editWidget;
+var _d=ew.domNode.style;
+_d.position="absolute";
+_d.visibility="hidden";
+this.domNode=this.displayNode;
+if(_b){
+dijit.focus(this.displayNode);
+}
+_d.display="none";
+setTimeout(function(){
+ew.destroy();
+delete ew;
+if(dojo.isIE){
+dijit.focus(dijit.getFocus());
+}
+},1000);
+},save:function(_e){
+if(this.disabled||!this.editing){
+return;
+}
+this.editing=false;
+var _f=this.editWidget.getValue()+"";
+this.attr("value",this.renderAsHtml?_f:_f.replace(/&/gm,"&").replace(/</gm,"<").replace(/>/gm,">").replace(/"/gm,""").replace(/\n/g,"<br>"));
+this.onChange(_f);
+this._showText(_e);
+},setValue:function(val){
+dojo.deprecated("dijit.InlineEditBox.setValue() is deprecated.  Use attr('value', ...) instead.","","2.0");
+return this.attr("value",val);
+},_setValueAttr:function(val){
+this.value=val;
+this.displayNode.innerHTML=dojo.trim(val)||this.noValueIndicator;
+},getValue:function(){
+dojo.deprecated("dijit.InlineEditBox.getValue() is deprecated.  Use attr('value') instead.","","2.0");
+return this.attr("value");
+},cancel:function(_12){
+this.editing=false;
+this.onCancel();
+this._showText(_12);
+}});
+dojo.declare("dijit._InlineEditor",[dijit._Widget,dijit._Templated],{templateString:"<span dojoAttachPoint=\"editNode\" waiRole=\"presentation\" style=\"position: absolute; visibility:hidden\" class=\"dijitReset dijitInline\"\n\tdojoAttachEvent=\"onkeypress: _onKeyPress\" \n\t><span dojoAttachPoint=\"editorPlaceholder\"></span\n\t><span dojoAttachPoint=\"buttonContainer\"\n\t\t><button class='saveButton' dojoAttachPoint=\"saveButton\" dojoType=\"dijit.form.Button\" dojoAttachEvent=\"onCl [...]
+this.inherited(arguments);
+this.messages=dojo.i18n.getLocalization("dijit","common",this.lang);
+dojo.forEach(["buttonSave","buttonCancel"],function(_13){
+if(!this[_13]){
+this[_13]=this.messages[_13];
+}
+},this);
+},postCreate:function(){
+var cls=dojo.getObject(this.editor);
+var _15=this.sourceStyle;
+var _16="line-height:"+_15.lineHeight+";";
+dojo.forEach(["Weight","Family","Size","Style"],function(_17){
+_16+="font-"+_17+":"+_15["font"+_17]+";";
+},this);
+dojo.forEach(["marginTop","marginBottom","marginLeft","marginRight"],function(_18){
+this.domNode.style[_18]=_15[_18];
+},this);
+if(this.width=="100%"){
+_16+="width:100%;";
+this.domNode.style.display="block";
+}else{
+_16+="width:"+(this.width+(Number(this.width)==this.width?"px":""))+";";
+}
+this.editorParams.style=_16;
+this.editorParams["displayedValue" in cls.prototype?"displayedValue":"value"]=this.value;
+var ew=this.editWidget=new cls(this.editorParams,this.editorPlaceholder);
+this.connect(ew,"onChange","_onChange");
+this.connect(ew,"onKeyPress","_onKeyPress");
+this.connect(ew,"onKeyUp","_onKeyPress");
+if(this.autoSave){
+this.buttonContainer.style.display="none";
+}
+},destroy:function(){
+this.editWidget.destroy();
+this.inherited(arguments);
+},getValue:function(){
+var ew=this.editWidget;
+return ew.attr("displayedValue" in ew?"displayedValue":"value");
+},_onKeyPress:function(e){
+if(this._exitInProgress){
+return;
+}
+if(this.autoSave){
+if(e.altKey||e.ctrlKey){
+return;
+}
+if(e.charOrCode==dojo.keys.ESCAPE){
+dojo.stopEvent(e);
+this._exitInProgress=true;
+this.cancel(true);
+}else{
+if(e.charOrCode==dojo.keys.ENTER&&this.editWidget.focusNode.tagName=="INPUT"){
+dojo.stopEvent(e);
+this._exitInProgress=true;
+this.save(true);
+}else{
+if(e.charOrCode===dojo.keys.TAB){
+this._exitInProgress=true;
+setTimeout(dojo.hitch(this,"save",false),0);
+}
+}
+}
+}else{
+var _1c=this;
+setTimeout(function(){
+_1c._onChange();
+},100);
+}
+},_onBlur:function(){
+this.inherited(arguments);
+if(this._exitInProgress){
+return;
+}
+if(this.autoSave){
+this._exitInProgress=true;
+if(this.getValue()==this._resetValue){
+this.cancel(false);
+}else{
+this.save(false);
+}
+}
+},_onChange:function(){
+if(this._exitInProgress){
+return;
+}
+if(this.autoSave){
+this._exitInProgress=true;
+this.save(true);
+}else{
+this.saveButton.attr("disabled",(this.getValue()==this._resetValue)||!this.enableSave());
+}
+},enableSave:function(){
+return this.editWidget.isValid?this.editWidget.isValid():true;
+},focus:function(){
+this.editWidget.focus();
+dijit.selectInputText(this.editWidget.focusNode);
+}});
+}
diff --git a/dijit/LICENSE b/dijit/LICENSE
new file mode 100644
index 0000000..ad1676a
--- /dev/null
+++ b/dijit/LICENSE
@@ -0,0 +1,195 @@
+Dojo is available under *either* the terms of the modified BSD license *or* the
+Academic Free License version 2.1. As a recipient of Dojo, you may choose which
+license to receive this code under (except as noted in per-module LICENSE
+files). Some modules may not be the copyright of the Dojo Foundation. These
+modules contain explicit declarations of copyright in both the LICENSE files in
+the directories in which they reside and in the code itself. No external
+contributions are allowed under licenses which are fundamentally incompatible
+with the AFL or BSD licenses that Dojo is distributed under.
+
+The text of the AFL and BSD licenses is reproduced below. 
+
+-------------------------------------------------------------------------------
+The "New" BSD License:
+**********************
+
+Copyright (c) 2005-2009, The Dojo Foundation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice, this
+    list of conditions and the following disclaimer.
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+  * Neither the name of the Dojo Foundation nor the names of its contributors
+    may be used to endorse or promote products derived from this software
+    without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+-------------------------------------------------------------------------------
+The Academic Free License, v. 2.1:
+**********************************
+
+This Academic Free License (the "License") applies to any original work of
+authorship (the "Original Work") whose owner (the "Licensor") has placed the
+following notice immediately following the copyright notice for the Original
+Work:
+
+Licensed under the Academic Free License version 2.1
+
+1) Grant of Copyright License. Licensor hereby grants You a world-wide,
+royalty-free, non-exclusive, perpetual, sublicenseable license to do the
+following:
+
+a) to reproduce the Original Work in copies;
+
+b) to prepare derivative works ("Derivative Works") based upon the Original
+Work;
+
+c) to distribute copies of the Original Work and Derivative Works to the
+public;
+
+d) to perform the Original Work publicly; and
+
+e) to display the Original Work publicly.
+
+2) Grant of Patent License. Licensor hereby grants You a world-wide,
+royalty-free, non-exclusive, perpetual, sublicenseable license, under patent
+claims owned or controlled by the Licensor that are embodied in the Original
+Work as furnished by the Licensor, to make, use, sell and offer for sale the
+Original Work and Derivative Works.
+
+3) Grant of Source Code License. The term "Source Code" means the preferred
+form of the Original Work for making modifications to it and all available
+documentation describing how to modify the Original Work. Licensor hereby
+agrees to provide a machine-readable copy of the Source Code of the Original
+Work along with each copy of the Original Work that Licensor distributes.
+Licensor reserves the right to satisfy this obligation by placing a
+machine-readable copy of the Source Code in an information repository
+reasonably calculated to permit inexpensive and convenient access by You for as
+long as Licensor continues to distribute the Original Work, and by publishing
+the address of that information repository in a notice immediately following
+the copyright notice that applies to the Original Work.
+
+4) Exclusions From License Grant. Neither the names of Licensor, nor the names
+of any contributors to the Original Work, nor any of their trademarks or
+service marks, may be used to endorse or promote products derived from this
+Original Work without express prior written permission of the Licensor. Nothing
+in this License shall be deemed to grant any rights to trademarks, copyrights,
+patents, trade secrets or any other intellectual property of Licensor except as
+expressly stated herein. No patent license is granted to make, use, sell or
+offer to sell embodiments of any patent claims other than the licensed claims
+defined in Section 2. No right is granted to the trademarks of Licensor even if
+such marks are included in the Original Work. Nothing in this License shall be
+interpreted to prohibit Licensor from licensing under different terms from this
+License any Original Work that Licensor otherwise would have a right to
+license.
+
+5) This section intentionally omitted.
+
+6) Attribution Rights. You must retain, in the Source Code of any Derivative
+Works that You create, all copyright, patent or trademark notices from the
+Source Code of the Original Work, as well as any notices of licensing and any
+descriptive text identified therein as an "Attribution Notice." You must cause
+the Source Code for any Derivative Works that You create to carry a prominent
+Attribution Notice reasonably calculated to inform recipients that You have
+modified the Original Work.
+
+7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that
+the copyright in and to the Original Work and the patent rights granted herein
+by Licensor are owned by the Licensor or are sublicensed to You under the terms
+of this License with the permission of the contributor(s) of those copyrights
+and patent rights. Except as expressly stated in the immediately proceeding
+sentence, the Original Work is provided under this License on an "AS IS" BASIS
+and WITHOUT WARRANTY, either express or implied, including, without limitation,
+the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU.
+This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No
+license to Original Work is granted hereunder except under this disclaimer.
+
+8) Limitation of Liability. Under no circumstances and under no legal theory,
+whether in tort (including negligence), contract, or otherwise, shall the
+Licensor be liable to any person for any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License
+or the use of the Original Work including, without limitation, damages for loss
+of goodwill, work stoppage, computer failure or malfunction, or any and all
+other commercial damages or losses. This limitation of liability shall not
+apply to liability for death or personal injury resulting from Licensor's
+negligence to the extent applicable law prohibits such limitation. Some
+jurisdictions do not allow the exclusion or limitation of incidental or
+consequential damages, so this exclusion and limitation may not apply to You.
+
+9) Acceptance and Termination. If You distribute copies of the Original Work or
+a Derivative Work, You must make a reasonable effort under the circumstances to
+obtain the express assent of recipients to the terms of this License. Nothing
+else but this License (or another written agreement between Licensor and You)
+grants You permission to create Derivative Works based upon the Original Work
+or to exercise any of the rights granted in Section 1 herein, and any attempt
+to do so except under the terms of this License (or another written agreement
+between Licensor and You) is expressly prohibited by U.S. copyright law, the
+equivalent laws of other countries, and by international treaty. Therefore, by
+exercising any of the rights granted to You in Section 1 herein, You indicate
+Your acceptance of this License and all of its terms and conditions.
+
+10) Termination for Patent Action. This License shall terminate automatically
+and You may no longer exercise any of the rights granted to You by this License
+as of the date You commence an action, including a cross-claim or counterclaim,
+against Licensor or any licensee alleging that the Original Work infringes a
+patent. This termination provision shall not apply for an action alleging
+patent infringement by combinations of the Original Work with other software or
+hardware.
+
+11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this
+License may be brought only in the courts of a jurisdiction wherein the
+Licensor resides or in which Licensor conducts its primary business, and under
+the laws of that jurisdiction excluding its conflict-of-law provisions. The
+application of the United Nations Convention on Contracts for the International
+Sale of Goods is expressly excluded. Any use of the Original Work outside the
+scope of this License or after its termination shall be subject to the
+requirements and penalties of the U.S. Copyright Act, 17 U.S.C. § 101 et
+seq., the equivalent laws of other countries, and international treaty. This
+section shall survive the termination of this License.
+
+12) Attorneys Fees. In any action to enforce the terms of this License or
+seeking damages relating thereto, the prevailing party shall be entitled to
+recover its costs and expenses, including, without limitation, reasonable
+attorneys' fees and costs incurred in connection with such action, including
+any appeal of such action. This section shall survive the termination of this
+License.
+
+13) Miscellaneous. This License represents the complete agreement concerning
+the subject matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent necessary to
+make it enforceable.
+
+14) Definition of "You" in This License. "You" throughout this License, whether
+in upper or lower case, means an individual or a legal entity exercising rights
+under, and complying with all of the terms of, this License. For legal
+entities, "You" includes any entity that controls, is controlled by, or is
+under common control with you. For purposes of this definition, "control" means
+(i) the power, direct or indirect, to cause the direction or management of such
+entity, whether by contract or otherwise, or (ii) ownership of fifty percent
+(50%) or more of the outstanding shares, or (iii) beneficial ownership of such
+entity.
+
+15) Right to Use. You may use the Original Work in all ways not otherwise
+restricted or conditioned by this License or by law, and Licensor promises not
+to interfere with or be responsible for such uses by You.
+
+This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved.
+Permission is hereby granted to copy and distribute this license without
+modification. This license may not be modified without the express written
+permission of its copyright owner.
diff --git a/dijit/Menu.js b/dijit/Menu.js
new file mode 100644
index 0000000..a54d6fa
--- /dev/null
+++ b/dijit/Menu.js
@@ -0,0 +1,218 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.Menu"]){
+dojo._hasResource["dijit.Menu"]=true;
+dojo.provide("dijit.Menu");
+dojo.require("dijit._Widget");
+dojo.require("dijit._KeyNavContainer");
+dojo.require("dijit._Templated");
+dojo.declare("dijit._MenuBase",[dijit._Widget,dijit._Templated,dijit._KeyNavContainer],{parentMenu:null,popupDelay:500,startup:function(){
+if(this._started){
+return;
+}
+dojo.forEach(this.getChildren(),function(_1){
+_1.startup();
+});
+this.startupKeyNavChildren();
+this.inherited(arguments);
+},onExecute:function(){
+},onCancel:function(_2){
+},_moveToPopup:function(_3){
+if(this.focusedChild&&this.focusedChild.popup&&!this.focusedChild.disabled){
+this.focusedChild._onClick(_3);
+}else{
+var _4=this._getTopMenu();
+if(_4&&_4._isMenuBar){
+_4.focusNext();
+}
+}
+},onItemHover:function(_5){
+if(this.isActive){
+this.focusChild(_5);
+if(this.focusedChild.popup&&!this.focusedChild.disabled&&!this.hover_timer){
+this.hover_timer=setTimeout(dojo.hitch(this,"_openPopup"),this.popupDelay);
+}
+}
+},_onChildBlur:function(_6){
+_6._setSelected(false);
+dijit.popup.close(_6.popup);
+this._stopPopupTimer();
+},onItemUnhover:function(_7){
+if(this.isActive){
+this._stopPopupTimer();
+}
+},_stopPopupTimer:function(){
+if(this.hover_timer){
+clearTimeout(this.hover_timer);
+this.hover_timer=null;
+}
+},_getTopMenu:function(){
+for(var _8=this;_8.parentMenu;_8=_8.parentMenu){
+}
+return _8;
+},onItemClick:function(_9,_a){
+if(_9.disabled){
+return false;
+}
+this.focusChild(_9);
+if(_9.popup){
+if(!this.is_open){
+this._openPopup();
+}
+}else{
+this.onExecute();
+_9.onClick(_a);
+}
+},_openPopup:function(){
+this._stopPopupTimer();
+var _b=this.focusedChild;
+var _c=_b.popup;
+if(_c.isShowingNow){
+return;
+}
+_c.parentMenu=this;
+var _d=this;
+dijit.popup.open({parent:this,popup:_c,around:_b.domNode,orient:this._orient||(this.isLeftToRight()?{"TR":"TL","TL":"TR"}:{"TL":"TR","TR":"TL"}),onCancel:function(){
+dijit.popup.close(_c);
+_b.focus();
+_d.currentPopup=null;
+},onExecute:dojo.hitch(this,"_onDescendantExecute")});
+this.currentPopup=_c;
+if(_c.focus){
+setTimeout(dojo.hitch(_c,"focus"),0);
+}
+},onOpen:function(e){
+this.isShowingNow=true;
+},onClose:function(){
+this._stopPopupTimer();
+this.parentMenu=null;
+this.isShowingNow=false;
+this.currentPopup=null;
+if(this.focusedChild){
+this._onChildBlur(this.focusedChild);
+this.focusedChild=null;
+}
+},_onFocus:function(){
+this.isActive=true;
+dojo.addClass(this.domNode,"dijitMenuActive");
+dojo.removeClass(this.domNode,"dijitMenuPassive");
+this.inherited(arguments);
+},_onBlur:function(){
+this.isActive=false;
+dojo.removeClass(this.domNode,"dijitMenuActive");
+dojo.addClass(this.domNode,"dijitMenuPassive");
+this.onClose();
+this.inherited(arguments);
+},_onDescendantExecute:function(){
+this.onClose();
+}});
+dojo.declare("dijit.Menu",dijit._MenuBase,{constructor:function(){
+this._bindings=[];
+},templateString:"<table class=\"dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable\" waiRole=\"menu\" tabIndex=\"${tabIndex}\" dojoAttachEvent=\"onkeypress:_onKeyPress\">\n\t<tbody class=\"dijitReset\" dojoAttachPoint=\"containerNode\"></tbody>\n</table>\n",targetNodeIds:[],contextMenuForWindow:false,leftClickToOpen:false,_contextMenuWithMouse:false,postCreate:function(){
+if(this.contextMenuForWindow){
+this.bindDomNode(dojo.body());
+}else{
+dojo.forEach(this.targetNodeIds,this.bindDomNode,this);
+}
+var k=dojo.keys,l=this.isLeftToRight();
+this._openSubMenuKey=l?k.RIGHT_ARROW:k.LEFT_ARROW;
+this._closeSubMenuKey=l?k.LEFT_ARROW:k.RIGHT_ARROW;
+this.connectKeyNavHandlers([k.UP_ARROW],[k.DOWN_ARROW]);
+},_onKeyPress:function(evt){
+if(evt.ctrlKey||evt.altKey){
+return;
+}
+switch(evt.charOrCode){
+case this._openSubMenuKey:
+this._moveToPopup(evt);
+dojo.stopEvent(evt);
+break;
+case this._closeSubMenuKey:
+if(this.parentMenu){
+if(this.parentMenu._isMenuBar){
+this.parentMenu.focusPrev();
+}else{
+this.onCancel(false);
+}
+}else{
+dojo.stopEvent(evt);
+}
+break;
+}
+},_iframeContentWindow:function(_12){
+var win=dijit.getDocumentWindow(dijit.Menu._iframeContentDocument(_12))||dijit.Menu._iframeContentDocument(_12)["__parent__"]||(_12.name&&dojo.doc.frames[_12.name])||null;
+return win;
+},_iframeContentDocument:function(_14){
+var doc=_14.contentDocument||(_14.contentWindow&&_14.contentWindow.document)||(_14.name&&dojo.doc.frames[_14.name]&&dojo.doc.frames[_14.name].document)||null;
+return doc;
+},bindDomNode:function(_16){
+_16=dojo.byId(_16);
+var win=dijit.getDocumentWindow(_16.ownerDocument);
+if(_16.tagName.toLowerCase()=="iframe"){
+win=this._iframeContentWindow(_16);
+_16=dojo.withGlobal(win,dojo.body);
+}
+var cn=(_16==dojo.body()?dojo.doc:_16);
+_16[this.id]=this._bindings.push([dojo.connect(cn,(this.leftClickToOpen)?"onclick":"oncontextmenu",this,"_openMyself"),dojo.connect(cn,"onkeydown",this,"_contextKey"),dojo.connect(cn,"onmousedown",this,"_contextMouse")]);
+},unBindDomNode:function(_19){
+var _1a=dojo.byId(_19);
+if(_1a){
+var bid=_1a[this.id]-1,b=this._bindings[bid];
+dojo.forEach(b,dojo.disconnect);
+delete this._bindings[bid];
+}
+},_contextKey:function(e){
+this._contextMenuWithMouse=false;
+if(e.keyCode==dojo.keys.F10){
+dojo.stopEvent(e);
+if(e.shiftKey&&e.type=="keydown"){
+var _e={target:e.target,pageX:e.pageX,pageY:e.pageY};
+_e.preventDefault=_e.stopPropagation=function(){
+};
+window.setTimeout(dojo.hitch(this,function(){
+this._openMyself(_e);
+}),1);
+}
+}
+},_contextMouse:function(e){
+this._contextMenuWithMouse=true;
+},_openMyself:function(e){
+if(this.leftClickToOpen&&e.button>0){
+return;
+}
+dojo.stopEvent(e);
+var x,y;
+if(dojo.isSafari||this._contextMenuWithMouse){
+x=e.pageX;
+y=e.pageY;
+}else{
+var _23=dojo.coords(e.target,true);
+x=_23.x+10;
+y=_23.y+10;
+}
+var _24=this;
+var _25=dijit.getFocus(this);
+function _26(){
+dijit.focus(_25);
+dijit.popup.close(_24);
+};
+dijit.popup.open({popup:this,x:x,y:y,onExecute:_26,onCancel:_26,orient:this.isLeftToRight()?"L":"R"});
+this.focus();
+this._onBlur=function(){
+this.inherited("_onBlur",arguments);
+dijit.popup.close(this);
+};
+},uninitialize:function(){
+dojo.forEach(this.targetNodeIds,this.unBindDomNode,this);
+this.inherited(arguments);
+}});
+dojo.require("dijit.MenuItem");
+dojo.require("dijit.PopupMenuItem");
+dojo.require("dijit.CheckedMenuItem");
+dojo.require("dijit.MenuSeparator");
+}
diff --git a/dijit/MenuBar.js b/dijit/MenuBar.js
new file mode 100644
index 0000000..dfe1203
--- /dev/null
+++ b/dijit/MenuBar.js
@@ -0,0 +1,33 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.MenuBar"]){
+dojo._hasResource["dijit.MenuBar"]=true;
+dojo.provide("dijit.MenuBar");
+dojo.require("dijit.Menu");
+dojo.declare("dijit.MenuBar",dijit._MenuBase,{templateString:"<div class=\"dijitMenuBar dijitMenuPassive\" dojoAttachPoint=\"containerNode\"  waiRole=\"menubar\" tabIndex=\"${tabIndex}\" dojoAttachEvent=\"onkeypress: _onKeyPress\"></div>\n",_isMenuBar:true,constructor:function(){
+this._orient=this.isLeftToRight()?{BL:"TL"}:{BR:"TR"};
+},postCreate:function(){
+var k=dojo.keys,l=this.isLeftToRight();
+this.connectKeyNavHandlers(l?[k.LEFT_ARROW]:[k.RIGHT_ARROW],l?[k.RIGHT_ARROW]:[k.LEFT_ARROW]);
+},focusChild:function(_3){
+var _4=this.focusedChild,_5=_4&&_4.popup&&_4.popup.isShowingNow;
+this.inherited(arguments);
+if(_5&&!_3.disabled){
+this._openPopup();
+}
+},_onKeyPress:function(_6){
+if(_6.ctrlKey||_6.altKey){
+return;
+}
+switch(_6.charOrCode){
+case dojo.keys.DOWN_ARROW:
+this._moveToPopup(_6);
+dojo.stopEvent(_6);
+}
+}});
+}
diff --git a/dijit/MenuBarItem.js b/dijit/MenuBarItem.js
new file mode 100644
index 0000000..138074a
--- /dev/null
+++ b/dijit/MenuBarItem.js
@@ -0,0 +1,14 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.MenuBarItem"]){
+dojo._hasResource["dijit.MenuBarItem"]=true;
+dojo.provide("dijit.MenuBarItem");
+dojo.require("dijit.MenuItem");
+dojo.declare("dijit._MenuBarItemMixin",null,{templateString:"<div class=\"dijitReset dijitInline dijitMenuItem dijitMenuItemLabel\" dojoAttachPoint=\"focusNode\" waiRole=\"menuitem\" tabIndex=\"-1\"'\n\t\tdojoAttachEvent=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<span dojoAttachPoint=\"containerNode\"></span>\n</div>\n",attributeMap:dojo.delegate(dijit._Widget.prototype.attributeMap,{label:{node:"containerNode",type:"innerHTML"}})});
+dojo.declare("dijit.MenuBarItem",[dijit.MenuItem,dijit._MenuBarItemMixin],{});
+}
diff --git a/dijit/MenuItem.js b/dijit/MenuItem.js
new file mode 100644
index 0000000..a275173
--- /dev/null
+++ b/dijit/MenuItem.js
@@ -0,0 +1,58 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.MenuItem"]){
+dojo._hasResource["dijit.MenuItem"]=true;
+dojo.provide("dijit.MenuItem");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dijit._Contained");
+dojo.declare("dijit.MenuItem",[dijit._Widget,dijit._Templated,dijit._Contained],{templateString:"<tr class=\"dijitReset dijitMenuItem\" dojoAttachPoint=\"focusNode\" waiRole=\"menuitem\" tabIndex=\"-1\"\n\t\tdojoAttachEvent=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset\" waiRole=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon\" dojoAttachPoint=\"iconNode\">\n\t</td>\n\t<td class=\"dijitReset dijitMen [...]
+if(_1&&!("label" in this.params)){
+this.attr("label",_1.innerHTML);
+}
+},postCreate:function(){
+dojo.setSelectable(this.domNode,false);
+dojo.attr(this.containerNode,"id",this.id+"_text");
+dijit.setWaiState(this.domNode,"labelledby",this.id+"_text");
+},_onHover:function(){
+dojo.addClass(this.domNode,"dijitMenuItemHover");
+this.getParent().onItemHover(this);
+},_onUnhover:function(){
+dojo.removeClass(this.domNode,"dijitMenuItemHover");
+this.getParent().onItemUnhover(this);
+},_onClick:function(_2){
+this.getParent().onItemClick(this,_2);
+dojo.stopEvent(_2);
+},onClick:function(_3){
+},focus:function(){
+try{
+dijit.focus(this.focusNode);
+}
+catch(e){
+}
+},_onFocus:function(){
+this._setSelected(true);
+},_setSelected:function(_4){
+dojo.toggleClass(this.domNode,"dijitMenuItemSelected",_4);
+},setLabel:function(_5){
+dojo.deprecated("dijit.MenuItem.setLabel() is deprecated.  Use attr('label', ...) instead.","","2.0");
+this.attr("label",_5);
+},setDisabled:function(_6){
+dojo.deprecated("dijit.Menu.setDisabled() is deprecated.  Use attr('disabled', bool) instead.","","2.0");
+this.attr("disabled",_6);
+},_setDisabledAttr:function(_7){
+this.disabled=_7;
+dojo[_7?"addClass":"removeClass"](this.domNode,"dijitMenuItemDisabled");
+dijit.setWaiState(this.focusNode,"disabled",_7?"true":"false");
+},_setAccelKeyAttr:function(_8){
+this.accelKey=_8;
+this.accelKeyNode.style.display=_8?"":"none";
+this.accelKeyNode.innerHTML=_8;
+dojo.attr(this.containerNode,"colSpan",_8?"1":"2");
+}});
+}
diff --git a/dijit/MenuSeparator.js b/dijit/MenuSeparator.js
new file mode 100644
index 0000000..1218172
--- /dev/null
+++ b/dijit/MenuSeparator.js
@@ -0,0 +1,19 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.MenuSeparator"]){
+dojo._hasResource["dijit.MenuSeparator"]=true;
+dojo.provide("dijit.MenuSeparator");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dijit._Contained");
+dojo.declare("dijit.MenuSeparator",[dijit._Widget,dijit._Templated,dijit._Contained],{templateString:"<tr class=\"dijitMenuSeparator\">\n\t<td colspan=\"4\">\n\t\t<div class=\"dijitMenuSeparatorTop\"></div>\n\t\t<div class=\"dijitMenuSeparatorBottom\"></div>\n\t</td>\n</tr>\n",postCreate:function(){
+dojo.setSelectable(this.domNode,false);
+},isFocusable:function(){
+return false;
+}});
+}
diff --git a/dijit/PopupMenuBarItem.js b/dijit/PopupMenuBarItem.js
new file mode 100644
index 0000000..e6181f0
--- /dev/null
+++ b/dijit/PopupMenuBarItem.js
@@ -0,0 +1,14 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.PopupMenuBarItem"]){
+dojo._hasResource["dijit.PopupMenuBarItem"]=true;
+dojo.provide("dijit.PopupMenuBarItem");
+dojo.require("dijit.PopupMenuItem");
+dojo.require("dijit.MenuBarItem");
+dojo.declare("dijit.PopupMenuBarItem",[dijit.PopupMenuItem,dijit._MenuBarItemMixin],{});
+}
diff --git a/dijit/PopupMenuItem.js b/dijit/PopupMenuItem.js
new file mode 100644
index 0000000..226aa8f
--- /dev/null
+++ b/dijit/PopupMenuItem.js
@@ -0,0 +1,40 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.PopupMenuItem"]){
+dojo._hasResource["dijit.PopupMenuItem"]=true;
+dojo.provide("dijit.PopupMenuItem");
+dojo.require("dijit.MenuItem");
+dojo.declare("dijit.PopupMenuItem",dijit.MenuItem,{_fillContent:function(){
+if(this.srcNodeRef){
+var _1=dojo.query("*",this.srcNodeRef);
+dijit.PopupMenuItem.superclass._fillContent.call(this,_1[0]);
+this.dropDownContainer=this.srcNodeRef;
+}
+},startup:function(){
+if(this._started){
+return;
+}
+this.inherited(arguments);
+if(!this.popup){
+var _2=dojo.query("[widgetId]",this.dropDownContainer)[0];
+this.popup=dijit.byNode(_2);
+}
+dojo.body().appendChild(this.popup.domNode);
+this.popup.domNode.style.display="none";
+if(this.arrowWrapper){
+dojo.style(this.arrowWrapper,"visibility","");
+}
+dijit.setWaiState(this.focusNode,"haspopup","true");
+},destroyDescendants:function(){
+if(this.popup){
+this.popup.destroyRecursive();
+delete this.popup;
+}
+this.inherited(arguments);
+}});
+}
diff --git a/dijit/ProgressBar.js b/dijit/ProgressBar.js
new file mode 100644
index 0000000..c02d8a9
--- /dev/null
+++ b/dijit/ProgressBar.js
@@ -0,0 +1,51 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.ProgressBar"]){
+dojo._hasResource["dijit.ProgressBar"]=true;
+dojo.provide("dijit.ProgressBar");
+dojo.require("dojo.fx");
+dojo.require("dojo.number");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.declare("dijit.ProgressBar",[dijit._Widget,dijit._Templated],{progress:"0",maximum:100,places:0,indeterminate:false,templateString:"<div class=\"dijitProgressBar dijitProgressBarEmpty\"\n\t><div waiRole=\"progressbar\" tabindex=\"0\" dojoAttachPoint=\"internalProgress\" class=\"dijitProgressBarFull\"\n\t\t><div class=\"dijitProgressBarTile\"></div\n\t\t><span style=\"visibility:hidden\"> </span\n\t></div\n\t><div dojoAttachPoint=\"label\" class=\"dijitProgressBarLabel\" id=\"${ [...]
+this.inherited(arguments);
+this.indeterminateHighContrastImage.setAttribute("src",this._indeterminateHighContrastImagePath);
+this.update();
+},update:function(_1){
+dojo.mixin(this,_1||{});
+var _2=this.internalProgress;
+var _3=1,_4;
+if(this.indeterminate){
+_4="addClass";
+dijit.removeWaiState(_2,"valuenow");
+dijit.removeWaiState(_2,"valuemin");
+dijit.removeWaiState(_2,"valuemax");
+}else{
+_4="removeClass";
+if(String(this.progress).indexOf("%")!=-1){
+_3=Math.min(parseFloat(this.progress)/100,1);
+this.progress=_3*this.maximum;
+}else{
+this.progress=Math.min(this.progress,this.maximum);
+_3=this.progress/this.maximum;
+}
+var _5=this.report(_3);
+this.label.firstChild.nodeValue=_5;
+dijit.setWaiState(_2,"describedby",this.label.id);
+dijit.setWaiState(_2,"valuenow",this.progress);
+dijit.setWaiState(_2,"valuemin",0);
+dijit.setWaiState(_2,"valuemax",this.maximum);
+}
+dojo[_4](this.domNode,"dijitProgressBarIndeterminate");
+_2.style.width=(_3*100)+"%";
+this.onChange();
+},report:function(_6){
+return dojo.number.format(_6,{type:"percent",places:this.places,locale:this.lang});
+},onChange:function(){
+}});
+}
diff --git a/dijit/TitlePane.js b/dijit/TitlePane.js
new file mode 100644
index 0000000..1cd71cd
--- /dev/null
+++ b/dijit/TitlePane.js
@@ -0,0 +1,90 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.TitlePane"]){
+dojo._hasResource["dijit.TitlePane"]=true;
+dojo.provide("dijit.TitlePane");
+dojo.require("dojo.fx");
+dojo.require("dijit._Templated");
+dojo.require("dijit.layout.ContentPane");
+dojo.declare("dijit.TitlePane",[dijit.layout.ContentPane,dijit._Templated],{title:"",open:true,duration:dijit.defaultDuration,baseClass:"dijitTitlePane",templateString:"<div class=\"${baseClass}\">\n\t<div dojoAttachEvent=\"onclick:toggle, onkeypress:_onTitleKey, onfocus:_handleFocus, onblur:_handleFocus, onmouseenter:_onTitleEnter, onmouseleave:_onTitleLeave\" tabindex=\"0\"\n\t\t\twaiRole=\"button\" class=\"dijitTitlePaneTitle\" dojoAttachPoint=\"titleBarNode,focusNode\">\n\t\t<img src [...]
+if(!this.open){
+this.hideNode.style.display=this.wipeNode.style.display="none";
+}
+this._setCss();
+dojo.setSelectable(this.titleNode,false);
+dijit.setWaiState(this.containerNode,"labelledby",this.titleNode.id);
+dijit.setWaiState(this.focusNode,"haspopup","true");
+var _1=this.hideNode,_2=this.wipeNode;
+this._wipeIn=dojo.fx.wipeIn({node:this.wipeNode,duration:this.duration,beforeBegin:function(){
+_1.style.display="";
+}});
+this._wipeOut=dojo.fx.wipeOut({node:this.wipeNode,duration:this.duration,onEnd:function(){
+_1.style.display="none";
+}});
+this.inherited(arguments);
+},_setOpenAttr:function(_3){
+if(this.open!==_3){
+this.toggle();
+}
+},_setContentAttr:function(_4){
+if(!this.open||!this._wipeOut||this._wipeOut.status()=="playing"){
+this.inherited(arguments);
+}else{
+if(this._wipeIn&&this._wipeIn.status()=="playing"){
+this._wipeIn.stop();
+}
+dojo.marginBox(this.wipeNode,{h:dojo.marginBox(this.wipeNode).h});
+this.inherited(arguments);
+if(this._wipeIn){
+this._wipeIn.play();
+}else{
+this.hideNode.style.display="";
+}
+}
+},toggle:function(){
+dojo.forEach([this._wipeIn,this._wipeOut],function(_5){
+if(_5&&_5.status()=="playing"){
+_5.stop();
+}
+});
+var _6=this[this.open?"_wipeOut":"_wipeIn"];
+if(_6){
+_6.play();
+}else{
+this.hideNode.style.display=this.open?"":"none";
+}
+this.open=!this.open;
+this._onShow();
+this._setCss();
+},_setCss:function(){
+var _7=["dijitClosed","dijitOpen"];
+var _8=this.open;
+var _9=this.titleBarNode||this.focusNode;
+dojo.removeClass(_9,_7[!_8+0]);
+_9.className+=" "+_7[_8+0];
+this.arrowNodeInner.innerHTML=this.open?"-":"+";
+},_onTitleKey:function(e){
+if(e.charOrCode==dojo.keys.ENTER||e.charOrCode==" "){
+this.toggle();
+}else{
+if(e.charOrCode==dojo.keys.DOWN_ARROW&&this.open){
+this.containerNode.focus();
+e.preventDefault();
+}
+}
+},_onTitleEnter:function(){
+dojo.addClass(this.focusNode,"dijitTitlePaneTitle-hover");
+},_onTitleLeave:function(){
+dojo.removeClass(this.focusNode,"dijitTitlePaneTitle-hover");
+},_handleFocus:function(e){
+dojo[(e.type=="focus"?"addClass":"removeClass")](this.focusNode,this.baseClass+"Focused");
+},setTitle:function(_c){
+dojo.deprecated("dijit.TitlePane.setTitle() is deprecated.  Use attr('title', ...) instead.","","2.0");
+this.titleNode.innerHTML=_c;
+}});
+}
diff --git a/dijit/Toolbar.js b/dijit/Toolbar.js
new file mode 100644
index 0000000..70480cd
--- /dev/null
+++ b/dijit/Toolbar.js
@@ -0,0 +1,24 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.Toolbar"]){
+dojo._hasResource["dijit.Toolbar"]=true;
+dojo.provide("dijit.Toolbar");
+dojo.require("dijit._Widget");
+dojo.require("dijit._KeyNavContainer");
+dojo.require("dijit._Templated");
+dojo.declare("dijit.Toolbar",[dijit._Widget,dijit._Templated,dijit._KeyNavContainer],{templateString:"<div class=\"dijit dijitToolbar\" waiRole=\"toolbar\" tabIndex=\"${tabIndex}\" dojoAttachPoint=\"containerNode\">"+"</div>",postCreate:function(){
+this.connectKeyNavHandlers(this.isLeftToRight()?[dojo.keys.LEFT_ARROW]:[dojo.keys.RIGHT_ARROW],this.isLeftToRight()?[dojo.keys.RIGHT_ARROW]:[dojo.keys.LEFT_ARROW]);
+},startup:function(){
+if(this._started){
+return;
+}
+this.startupKeyNavChildren();
+this.inherited(arguments);
+}});
+dojo.require("dijit.ToolbarSeparator");
+}
diff --git a/dijit/ToolbarSeparator.js b/dijit/ToolbarSeparator.js
new file mode 100644
index 0000000..76644d9
--- /dev/null
+++ b/dijit/ToolbarSeparator.js
@@ -0,0 +1,18 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.ToolbarSeparator"]){
+dojo._hasResource["dijit.ToolbarSeparator"]=true;
+dojo.provide("dijit.ToolbarSeparator");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.declare("dijit.ToolbarSeparator",[dijit._Widget,dijit._Templated],{templateString:"<div class=\"dijitToolbarSeparator dijitInline\"></div>",postCreate:function(){
+dojo.setSelectable(this.domNode,false);
+},isFocusable:function(){
+return false;
+}});
+}
diff --git a/dijit/Tooltip.js b/dijit/Tooltip.js
new file mode 100644
index 0000000..fb4e2ac
--- /dev/null
+++ b/dijit/Tooltip.js
@@ -0,0 +1,160 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.Tooltip"]){
+dojo._hasResource["dijit.Tooltip"]=true;
+dojo.provide("dijit.Tooltip");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.declare("dijit._MasterTooltip",[dijit._Widget,dijit._Templated],{duration:dijit.defaultDuration,templateString:"<div class=\"dijitTooltip dijitTooltipLeft\" id=\"dojoTooltip\">\n\t<div class=\"dijitTooltipContainer dijitTooltipContents\" dojoAttachPoint=\"containerNode\" waiRole='alert'></div>\n\t<div class=\"dijitTooltipConnector\"></div>\n</div>\n",postCreate:function(){
+dojo.body().appendChild(this.domNode);
+this.bgIframe=new dijit.BackgroundIframe(this.domNode);
+this.fadeIn=dojo.fadeIn({node:this.domNode,duration:this.duration,onEnd:dojo.hitch(this,"_onShow")});
+this.fadeOut=dojo.fadeOut({node:this.domNode,duration:this.duration,onEnd:dojo.hitch(this,"_onHide")});
+},show:function(_1,_2,_3){
+if(this.aroundNode&&this.aroundNode===_2){
+return;
+}
+if(this.fadeOut.status()=="playing"){
+this._onDeck=arguments;
+return;
+}
+this.containerNode.innerHTML=_1;
+this.domNode.style.top=(this.domNode.offsetTop+1)+"px";
+var _4={};
+var _5=this.isLeftToRight();
+dojo.forEach((_3&&_3.length)?_3:dijit.Tooltip.defaultPosition,function(_6){
+switch(_6){
+case "after":
+_4[_5?"BR":"BL"]=_5?"BL":"BR";
+break;
+case "before":
+_4[_5?"BL":"BR"]=_5?"BR":"BL";
+break;
+case "below":
+_4[_5?"BL":"BR"]=_5?"TL":"TR";
+_4[_5?"BR":"BL"]=_5?"TR":"TL";
+break;
+case "above":
+default:
+_4[_5?"TL":"TR"]=_5?"BL":"BR";
+_4[_5?"TR":"TL"]=_5?"BR":"BL";
+break;
+}
+});
+var _7=dijit.placeOnScreenAroundElement(this.domNode,_2,_4,dojo.hitch(this,"orient"));
+dojo.style(this.domNode,"opacity",0);
+this.fadeIn.play();
+this.isShowingNow=true;
+this.aroundNode=_2;
+},orient:function(_8,_9,_a){
+_8.className="dijitTooltip "+{"BL-TL":"dijitTooltipBelow dijitTooltipABLeft","TL-BL":"dijitTooltipAbove dijitTooltipABLeft","BR-TR":"dijitTooltipBelow dijitTooltipABRight","TR-BR":"dijitTooltipAbove dijitTooltipABRight","BR-BL":"dijitTooltipRight","BL-BR":"dijitTooltipLeft"}[_9+"-"+_a];
+},_onShow:function(){
+if(dojo.isIE){
+this.domNode.style.filter="";
+}
+},hide:function(_b){
+if(this._onDeck&&this._onDeck[1]==_b){
+this._onDeck=null;
+}else{
+if(this.aroundNode===_b){
+this.fadeIn.stop();
+this.isShowingNow=false;
+this.aroundNode=null;
+this.fadeOut.play();
+}else{
+}
+}
+},_onHide:function(){
+this.domNode.style.cssText="";
+if(this._onDeck){
+this.show.apply(this,this._onDeck);
+this._onDeck=null;
+}
+}});
+dijit.showTooltip=function(_c,_d,_e){
+if(!dijit._masterTT){
+dijit._masterTT=new dijit._MasterTooltip();
+}
+return dijit._masterTT.show(_c,_d,_e);
+};
+dijit.hideTooltip=function(_f){
+if(!dijit._masterTT){
+dijit._masterTT=new dijit._MasterTooltip();
+}
+return dijit._masterTT.hide(_f);
+};
+dojo.declare("dijit.Tooltip",dijit._Widget,{label:"",showDelay:400,connectId:[],position:[],_setConnectIdAttr:function(ids){
+this._connectNodes=[];
+this.connectId=dojo.isArrayLike(ids)?ids:[ids];
+dojo.forEach(this.connectId,function(id){
+var _12=dojo.byId(id);
+if(_12){
+this._connectNodes.push(_12);
+dojo.forEach(["onMouseEnter","onMouseLeave","onFocus","onBlur"],function(_13){
+this.connect(_12,_13.toLowerCase(),"_"+_13);
+},this);
+if(dojo.isIE){
+_12.style.zoom=1;
+}
+}
+},this);
+},postCreate:function(){
+dojo.addClass(this.domNode,"dijitTooltipData");
+},_onMouseEnter:function(e){
+this._onHover(e);
+},_onMouseLeave:function(e){
+this._onUnHover(e);
+},_onFocus:function(e){
+this._focus=true;
+this._onHover(e);
+this.inherited(arguments);
+},_onBlur:function(e){
+this._focus=false;
+this._onUnHover(e);
+this.inherited(arguments);
+},_onHover:function(e){
+if(!this._showTimer){
+var _19=e.target;
+this._showTimer=setTimeout(dojo.hitch(this,function(){
+this.open(_19);
+}),this.showDelay);
+}
+},_onUnHover:function(e){
+if(this._focus){
+return;
+}
+if(this._showTimer){
+clearTimeout(this._showTimer);
+delete this._showTimer;
+}
+this.close();
+},open:function(_1b){
+_1b=_1b||this._connectNodes[0];
+if(!_1b){
+return;
+}
+if(this._showTimer){
+clearTimeout(this._showTimer);
+delete this._showTimer;
+}
+dijit.showTooltip(this.label||this.domNode.innerHTML,_1b,this.position);
+this._connectNode=_1b;
+},close:function(){
+if(this._connectNode){
+dijit.hideTooltip(this._connectNode);
+delete this._connectNode;
+}
+if(this._showTimer){
+clearTimeout(this._showTimer);
+delete this._showTimer;
+}
+},uninitialize:function(){
+this.close();
+}});
+dijit.Tooltip.defaultPosition=["after","before"];
+}
diff --git a/dijit/TooltipDialog.js b/dijit/TooltipDialog.js
new file mode 100644
index 0000000..6ab4f4c
--- /dev/null
+++ b/dijit/TooltipDialog.js
@@ -0,0 +1,64 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.TooltipDialog"]){
+dojo._hasResource["dijit.TooltipDialog"]=true;
+dojo.provide("dijit.TooltipDialog");
+dojo.require("dijit.layout.ContentPane");
+dojo.require("dijit._Templated");
+dojo.require("dijit.form._FormMixin");
+dojo.require("dijit._DialogMixin");
+dojo.declare("dijit.TooltipDialog",[dijit.layout.ContentPane,dijit._Templated,dijit.form._FormMixin,dijit._DialogMixin],{title:"",doLayout:false,autofocus:true,baseClass:"dijitTooltipDialog",_firstFocusItem:null,_lastFocusItem:null,templateString:null,templateString:"<div waiRole=\"presentation\">\n\t<div class=\"dijitTooltipContainer\" waiRole=\"presentation\">\n\t\t<div class =\"dijitTooltipContents dijitTooltipFocusNode\" dojoAttachPoint=\"containerNode\" tabindex=\"-1\" waiRole=\"dia [...]
+this.inherited(arguments);
+this.connect(this.containerNode,"onkeypress","_onKey");
+this.containerNode.title=this.title;
+},orient:function(_1,_2,_3){
+var c=this._currentOrientClass;
+if(c){
+dojo.removeClass(this.domNode,c);
+}
+c="dijitTooltipAB"+(_3.charAt(1)=="L"?"Left":"Right")+" dijitTooltip"+(_3.charAt(0)=="T"?"Below":"Above");
+dojo.addClass(this.domNode,c);
+this._currentOrientClass=c;
+},onOpen:function(_5){
+this.orient(this.domNode,_5.aroundCorner,_5.corner);
+this._onShow();
+if(this.autofocus){
+this._getFocusItems(this.containerNode);
+dijit.focus(this._firstFocusItem);
+}
+},_onKey:function(_6){
+var _7=_6.target;
+var dk=dojo.keys;
+if(_6.charOrCode===dk.TAB){
+this._getFocusItems(this.containerNode);
+}
+var _9=(this._firstFocusItem==this._lastFocusItem);
+if(_6.charOrCode==dk.ESCAPE){
+this.onCancel();
+dojo.stopEvent(_6);
+}else{
+if(_7==this._firstFocusItem&&_6.shiftKey&&_6.charOrCode===dk.TAB){
+if(!_9){
+dijit.focus(this._lastFocusItem);
+}
+dojo.stopEvent(_6);
+}else{
+if(_7==this._lastFocusItem&&_6.charOrCode===dk.TAB&&!_6.shiftKey){
+if(!_9){
+dijit.focus(this._firstFocusItem);
+}
+dojo.stopEvent(_6);
+}else{
+if(_6.charOrCode===dk.TAB){
+_6.stopPropagation();
+}
+}
+}
+}
+}});
+}
diff --git a/dijit/Tree.js b/dijit/Tree.js
new file mode 100644
index 0000000..70db003
--- /dev/null
+++ b/dijit/Tree.js
@@ -0,0 +1,535 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.Tree"]){
+dojo._hasResource["dijit.Tree"]=true;
+dojo.provide("dijit.Tree");
+dojo.require("dojo.fx");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dijit._Container");
+dojo.require("dijit._Contained");
+dojo.require("dojo.cookie");
+dojo.declare("dijit._TreeNode",[dijit._Widget,dijit._Templated,dijit._Container,dijit._Contained],{item:null,isTreeNode:true,label:"",isExpandable:null,isExpanded:false,state:"UNCHECKED",templateString:"<div class=\"dijitTreeNode\" waiRole=\"presentation\"\n\t><div dojoAttachPoint=\"rowNode\" class=\"dijitTreeRow\" waiRole=\"presentation\" dojoAttachEvent=\"onmouseenter:_onMouseEnter, onmouseleave:_onMouseLeave\"\n\t\t><img src=\"${_blankGif}\" alt=\"\" dojoAttachPoint=\"expandoNode\" cl [...]
+this.setLabelNode(this.label);
+this._setExpando();
+this._updateItemClasses(this.item);
+if(this.isExpandable){
+dijit.setWaiState(this.labelNode,"expanded",this.isExpanded);
+if(this==this.tree.rootNode){
+dijit.setWaitState(this.tree.domNode,"expanded",this.isExpanded);
+}
+}
+},_setIndentAttr:function(_1){
+this.indent=_1;
+var _2=(Math.max(_1,0)*19)+"px";
+dojo.style(this.domNode,"backgroundPosition",_2+" 0px");
+dojo.style(this.rowNode,dojo._isBodyLtr()?"paddingLeft":"paddingRight",_2);
+dojo.forEach(this.getChildren(),function(_3){
+_3.attr("indent",_1+1);
+});
+},markProcessing:function(){
+this.state="LOADING";
+this._setExpando(true);
+},unmarkProcessing:function(){
+this._setExpando(false);
+},_updateItemClasses:function(_4){
+var _5=this.tree,_6=_5.model;
+if(_5._v10Compat&&_4===_6.root){
+_4=null;
+}
+if(this._iconClass){
+dojo.removeClass(this.iconNode,this._iconClass);
+}
+this._iconClass=_5.getIconClass(_4,this.isExpanded);
+if(this._iconClass){
+dojo.addClass(this.iconNode,this._iconClass);
+}
+dojo.style(this.iconNode,_5.getIconStyle(_4,this.isExpanded)||{});
+if(this._labelClass){
+dojo.removeClass(this.labelNode,this._labelClass);
+}
+this._labelClass=_5.getLabelClass(_4,this.isExpanded);
+if(this._labelClass){
+dojo.addClass(this.labelNode,this._labelClass);
+}
+dojo.style(this.labelNode,_5.getLabelStyle(_4,this.isExpanded)||{});
+},_updateLayout:function(){
+var _7=this.getParent();
+if(!_7||_7.rowNode.style.display=="none"){
+dojo.addClass(this.domNode,"dijitTreeIsRoot");
+}else{
+dojo.toggleClass(this.domNode,"dijitTreeIsLast",!this.getNextSibling());
+}
+},_setExpando:function(_8){
+var _9=["dijitTreeExpandoLoading","dijitTreeExpandoOpened","dijitTreeExpandoClosed","dijitTreeExpandoLeaf"];
+var _a=["*","-","+","*"];
+var _b=_8?0:(this.isExpandable?(this.isExpanded?1:2):3);
+dojo.forEach(_9,function(s){
+dojo.removeClass(this.expandoNode,s);
+},this);
+dojo.addClass(this.expandoNode,_9[_b]);
+this.expandoNodeText.innerHTML=_a[_b];
+},expand:function(){
+if(this.isExpanded){
+return;
+}
+this._wipeOut&&this._wipeOut.stop();
+this.isExpanded=true;
+dijit.setWaiState(this.labelNode,"expanded","true");
+dijit.setWaiRole(this.containerNode,"group");
+dojo.addClass(this.contentNode,"dijitTreeContentExpanded");
+this._setExpando();
+this._updateItemClasses(this.item);
+if(this==this.tree.rootNode){
+dijit.setWaiState(this.tree.domNode,"expanded","true");
+}
+if(!this._wipeIn){
+this._wipeIn=dojo.fx.wipeIn({node:this.containerNode,duration:dijit.defaultDuration});
+}
+this._wipeIn.play();
+},collapse:function(){
+if(!this.isExpanded){
+return;
+}
+this._wipeIn&&this._wipeIn.stop();
+this.isExpanded=false;
+dijit.setWaiState(this.labelNode,"expanded","false");
+if(this==this.tree.rootNode){
+dijit.setWaiState(this.tree.domNode,"expanded","false");
+}
+dojo.removeClass(this.contentNode,"dijitTreeContentExpanded");
+this._setExpando();
+this._updateItemClasses(this.item);
+if(!this._wipeOut){
+this._wipeOut=dojo.fx.wipeOut({node:this.containerNode,duration:dijit.defaultDuration});
+}
+this._wipeOut.play();
+},setLabelNode:function(_d){
+this.labelNode.innerHTML="";
+this.labelNode.appendChild(dojo.doc.createTextNode(_d));
+},indent:0,setChildItems:function(_e){
+var _f=this.tree,_10=_f.model;
+this.getChildren().forEach(function(_11){
+dijit._Container.prototype.removeChild.call(this,_11);
+},this);
+this.state="LOADED";
+if(_e&&_e.length>0){
+this.isExpandable=true;
+dojo.forEach(_e,function(_12){
+var id=_10.getIdentity(_12),_14=_f._itemNodeMap[id],_15=(_14&&!_14.getParent())?_14:this.tree._createTreeNode({item:_12,tree:_f,isExpandable:_10.mayHaveChildren(_12),label:_f.getLabel(_12),indent:this.indent+1});
+if(_14){
+_14.attr("indent",this.indent+1);
+}
+this.addChild(_15);
+_f._itemNodeMap[id]=_15;
+if(this.tree._state(_12)){
+_f._expandNode(_15);
+}
+},this);
+dojo.forEach(this.getChildren(),function(_16,idx){
+_16._updateLayout();
+});
+}else{
+this.isExpandable=false;
+}
+if(this._setExpando){
+this._setExpando(false);
+}
+if(this==_f.rootNode){
+var fc=this.tree.showRoot?this:this.getChildren()[0];
+if(fc){
+fc.setSelected(true);
+_f.lastFocused=fc;
+}else{
+_f.domNode.setAttribute("tabIndex","0");
+}
+}
+},removeChild:function(_19){
+this.inherited(arguments);
+var _1a=this.getChildren();
+if(_1a.length==0){
+this.isExpandable=false;
+this.collapse();
+}
+dojo.forEach(_1a,function(_1b){
+_1b._updateLayout();
+});
+},makeExpandable:function(){
+this.isExpandable=true;
+this._setExpando(false);
+},_onLabelFocus:function(evt){
+dojo.addClass(this.labelNode,"dijitTreeLabelFocused");
+this.tree._onNodeFocus(this);
+},_onLabelBlur:function(evt){
+dojo.removeClass(this.labelNode,"dijitTreeLabelFocused");
+},setSelected:function(_1e){
+var _1f=this.labelNode;
+_1f.setAttribute("tabIndex",_1e?"0":"-1");
+dijit.setWaiState(_1f,"selected",_1e);
+dojo.toggleClass(this.rowNode,"dijitTreeNodeSelected",_1e);
+},_onMouseEnter:function(evt){
+dojo.addClass(this.rowNode,"dijitTreeNodeHover");
+this.tree._onNodeMouseEnter(this,evt);
+},_onMouseLeave:function(evt){
+dojo.removeClass(this.rowNode,"dijitTreeNodeHover");
+this.tree._onNodeMouseLeave(this,evt);
+}});
+dojo.declare("dijit.Tree",[dijit._Widget,dijit._Templated],{store:null,model:null,query:null,label:"",showRoot:true,childrenAttr:["children"],openOnClick:false,openOnDblClick:false,templateString:"<div class=\"dijitTreeContainer\" waiRole=\"tree\"\n\tdojoAttachEvent=\"onclick:_onClick,onkeypress:_onKeyPress,ondblclick:_onDblClick\">\n</div>\n",isExpandable:true,isTree:true,persist:true,dndController:null,dndParams:["onDndDrop","itemCreator","onDndCancel","checkAcceptance","checkItemAccep [...]
+dojo.publish(this.id,[dojo.mixin({tree:this,event:_22},_23||{})]);
+},postMixInProperties:function(){
+this.tree=this;
+this._itemNodeMap={};
+if(!this.cookieName){
+this.cookieName=this.id+"SaveStateCookie";
+}
+},postCreate:function(){
+this._initState();
+if(!this.model){
+this._store2model();
+}
+this.connect(this.model,"onChange","_onItemChange");
+this.connect(this.model,"onChildrenChange","_onItemChildrenChange");
+this.connect(this.model,"onDelete","_onItemDelete");
+this._load();
+this.inherited(arguments);
+if(this.dndController){
+if(dojo.isString(this.dndController)){
+this.dndController=dojo.getObject(this.dndController);
+}
+var _24={};
+for(var i=0;i<this.dndParams.length;i++){
+if(this[this.dndParams[i]]){
+_24[this.dndParams[i]]=this[this.dndParams[i]];
+}
+}
+this.dndController=new this.dndController(this,_24);
+}
+},_store2model:function(){
+this._v10Compat=true;
+dojo.deprecated("Tree: from version 2.0, should specify a model object rather than a store/query");
+var _26={id:this.id+"_ForestStoreModel",store:this.store,query:this.query,childrenAttrs:this.childrenAttr};
+if(this.params.mayHaveChildren){
+_26.mayHaveChildren=dojo.hitch(this,"mayHaveChildren");
+}
+if(this.params.getItemChildren){
+_26.getChildren=dojo.hitch(this,function(_27,_28,_29){
+this.getItemChildren((this._v10Compat&&_27===this.model.root)?null:_27,_28,_29);
+});
+}
+this.model=new dijit.tree.ForestStoreModel(_26);
+this.showRoot=Boolean(this.label);
+},_load:function(){
+this.model.getRoot(dojo.hitch(this,function(_2a){
+var rn=this.rootNode=this.tree._createTreeNode({item:_2a,tree:this,isExpandable:true,label:this.label||this.getLabel(_2a),indent:this.showRoot?0:-1});
+if(!this.showRoot){
+rn.rowNode.style.display="none";
+}
+this.domNode.appendChild(rn.domNode);
+this._itemNodeMap[this.model.getIdentity(_2a)]=rn;
+rn._updateLayout();
+this._expandNode(rn);
+}),function(err){
+console.error(this,": error loading root: ",err);
+});
+},mayHaveChildren:function(_2d){
+},getItemChildren:function(_2e,_2f){
+},getLabel:function(_30){
+return this.model.getLabel(_30);
+},getIconClass:function(_31,_32){
+return (!_31||this.model.mayHaveChildren(_31))?(_32?"dijitFolderOpened":"dijitFolderClosed"):"dijitLeaf";
+},getLabelClass:function(_33,_34){
+},getIconStyle:function(_35,_36){
+},getLabelStyle:function(_37,_38){
+},_onKeyPress:function(e){
+if(e.altKey){
+return;
+}
+var dk=dojo.keys;
+var _3b=dijit.getEnclosingWidget(e.target);
+if(!_3b){
+return;
+}
+var key=e.charOrCode;
+if(typeof key=="string"){
+if(!e.altKey&&!e.ctrlKey&&!e.shiftKey&&!e.metaKey){
+this._onLetterKeyNav({node:_3b,key:key.toLowerCase()});
+dojo.stopEvent(e);
+}
+}else{
+var map=this._keyHandlerMap;
+if(!map){
+map={};
+map[dk.ENTER]="_onEnterKey";
+map[this.isLeftToRight()?dk.LEFT_ARROW:dk.RIGHT_ARROW]="_onLeftArrow";
+map[this.isLeftToRight()?dk.RIGHT_ARROW:dk.LEFT_ARROW]="_onRightArrow";
+map[dk.UP_ARROW]="_onUpArrow";
+map[dk.DOWN_ARROW]="_onDownArrow";
+map[dk.HOME]="_onHomeKey";
+map[dk.END]="_onEndKey";
+this._keyHandlerMap=map;
+}
+if(this._keyHandlerMap[key]){
+this[this._keyHandlerMap[key]]({node:_3b,item:_3b.item});
+dojo.stopEvent(e);
+}
+}
+},_onEnterKey:function(_3e){
+this._publish("execute",{item:_3e.item,node:_3e.node});
+this.onClick(_3e.item,_3e.node);
+},_onDownArrow:function(_3f){
+var _40=this._getNextNode(_3f.node);
+if(_40&&_40.isTreeNode){
+this.focusNode(_40);
+}
+},_onUpArrow:function(_41){
+var _42=_41.node;
+var _43=_42.getPreviousSibling();
+if(_43){
+_42=_43;
+while(_42.isExpandable&&_42.isExpanded&&_42.hasChildren()){
+var _44=_42.getChildren();
+_42=_44[_44.length-1];
+}
+}else{
+var _45=_42.getParent();
+if(!(!this.showRoot&&_45===this.rootNode)){
+_42=_45;
+}
+}
+if(_42&&_42.isTreeNode){
+this.focusNode(_42);
+}
+},_onRightArrow:function(_46){
+var _47=_46.node;
+if(_47.isExpandable&&!_47.isExpanded){
+this._expandNode(_47);
+}else{
+if(_47.hasChildren()){
+_47=_47.getChildren()[0];
+if(_47&&_47.isTreeNode){
+this.focusNode(_47);
+}
+}
+}
+},_onLeftArrow:function(_48){
+var _49=_48.node;
+if(_49.isExpandable&&_49.isExpanded){
+this._collapseNode(_49);
+}else{
+var _4a=_49.getParent();
+if(_4a&&_4a.isTreeNode&&!(!this.showRoot&&_4a===this.rootNode)){
+this.focusNode(_4a);
+}
+}
+},_onHomeKey:function(){
+var _4b=this._getRootOrFirstNode();
+if(_4b){
+this.focusNode(_4b);
+}
+},_onEndKey:function(_4c){
+var _4d=this.rootNode;
+while(_4d.isExpanded){
+var c=_4d.getChildren();
+_4d=c[c.length-1];
+}
+if(_4d&&_4d.isTreeNode){
+this.focusNode(_4d);
+}
+},_onLetterKeyNav:function(_4f){
+var _50=_4f.node,_51=_50,key=_4f.key;
+do{
+_50=this._getNextNode(_50);
+if(!_50){
+_50=this._getRootOrFirstNode();
+}
+}while(_50!==_51&&(_50.label.charAt(0).toLowerCase()!=key));
+if(_50&&_50.isTreeNode){
+if(_50!==_51){
+this.focusNode(_50);
+}
+}
+},_onClick:function(e){
+var _54=e.target;
+var _55=dijit.getEnclosingWidget(_54);
+if(!_55||!_55.isTreeNode){
+return;
+}
+if((this.openOnClick&&_55.isExpandable)||(_54==_55.expandoNode||_54==_55.expandoNodeText)){
+if(_55.isExpandable){
+this._onExpandoClick({node:_55});
+}
+}else{
+this._publish("execute",{item:_55.item,node:_55});
+this.onClick(_55.item,_55);
+this.focusNode(_55);
+}
+dojo.stopEvent(e);
+},_onDblClick:function(e){
+var _57=e.target;
+var _58=dijit.getEnclosingWidget(_57);
+if(!_58||!_58.isTreeNode){
+return;
+}
+if((this.openOnDblClick&&_58.isExpandable)||(_57==_58.expandoNode||_57==_58.expandoNodeText)){
+if(_58.isExpandable){
+this._onExpandoClick({node:_58});
+}
+}else{
+this._publish("execute",{item:_58.item,node:_58});
+this.onDblClick(_58.item,_58);
+this.focusNode(_58);
+}
+dojo.stopEvent(e);
+},_onExpandoClick:function(_59){
+var _5a=_59.node;
+this.focusNode(_5a);
+if(_5a.isExpanded){
+this._collapseNode(_5a);
+}else{
+this._expandNode(_5a);
+}
+},onClick:function(_5b,_5c){
+},onDblClick:function(_5d,_5e){
+},onOpen:function(_5f,_60){
+},onClose:function(_61,_62){
+},_getNextNode:function(_63){
+if(_63.isExpandable&&_63.isExpanded&&_63.hasChildren()){
+return _63.getChildren()[0];
+}else{
+while(_63&&_63.isTreeNode){
+var _64=_63.getNextSibling();
+if(_64){
+return _64;
+}
+_63=_63.getParent();
+}
+return null;
+}
+},_getRootOrFirstNode:function(){
+return this.showRoot?this.rootNode:this.rootNode.getChildren()[0];
+},_collapseNode:function(_65){
+if(_65.isExpandable){
+if(_65.state=="LOADING"){
+return;
+}
+_65.collapse();
+this.onClose(_65.item,_65);
+if(_65.item){
+this._state(_65.item,false);
+this._saveState();
+}
+}
+},_expandNode:function(_66){
+if(!_66.isExpandable){
+return;
+}
+var _67=this.model,_68=_66.item;
+switch(_66.state){
+case "LOADING":
+return;
+case "UNCHECKED":
+_66.markProcessing();
+var _69=this;
+_67.getChildren(_68,function(_6a){
+_66.unmarkProcessing();
+_66.setChildItems(_6a);
+_69._expandNode(_66);
+},function(err){
+console.error(_69,": error loading root children: ",err);
+});
+break;
+default:
+_66.expand();
+this.onOpen(_66.item,_66);
+if(_68){
+this._state(_68,true);
+this._saveState();
+}
+}
+},focusNode:function(_6c){
+_6c.labelNode.focus();
+},_onNodeFocus:function(_6d){
+if(_6d){
+if(_6d!=this.lastFocused){
+this.lastFocused.setSelected(false);
+}
+_6d.setSelected(true);
+this.lastFocused=_6d;
+}
+},_onNodeMouseEnter:function(_6e){
+},_onNodeMouseLeave:function(_6f){
+},_onItemChange:function(_70){
+var _71=this.model,_72=_71.getIdentity(_70),_73=this._itemNodeMap[_72];
+if(_73){
+_73.setLabelNode(this.getLabel(_70));
+_73._updateItemClasses(_70);
+}
+},_onItemChildrenChange:function(_74,_75){
+var _76=this.model,_77=_76.getIdentity(_74),_78=this._itemNodeMap[_77];
+if(_78){
+_78.setChildItems(_75);
+}
+},_onItemDelete:function(_79){
+var _7a=this.model,_7b=_7a.getIdentity(_79),_7c=this._itemNodeMap[_7b];
+if(_7c){
+var _7d=_7c.getParent();
+if(_7d){
+_7d.removeChild(_7c);
+}
+_7c.destroyRecursive();
+delete this._itemNodeMap[_7b];
+}
+},_initState:function(){
+if(this.persist){
+var _7e=dojo.cookie(this.cookieName);
+this._openedItemIds={};
+if(_7e){
+dojo.forEach(_7e.split(","),function(_7f){
+this._openedItemIds[_7f]=true;
+},this);
+}
+}
+},_state:function(_80,_81){
+if(!this.persist){
+return false;
+}
+var id=this.model.getIdentity(_80);
+if(arguments.length===1){
+return this._openedItemIds[id];
+}
+if(_81){
+this._openedItemIds[id]=true;
+}else{
+delete this._openedItemIds[id];
+}
+},_saveState:function(){
+if(!this.persist){
+return;
+}
+var ary=[];
+for(var id in this._openedItemIds){
+ary.push(id);
+}
+dojo.cookie(this.cookieName,ary.join(","),{expires:365});
+},destroy:function(){
+if(this.rootNode){
+this.rootNode.destroyRecursive();
+}
+if(this.dndController&&!dojo.isString(this.dndController)){
+this.dndController.destroy();
+}
+this.rootNode=null;
+this.inherited(arguments);
+},destroyRecursive:function(){
+this.destroy();
+},_createTreeNode:function(_85){
+return new dijit._TreeNode(_85);
+}});
+dojo.require("dijit.tree.TreeStoreModel");
+dojo.require("dijit.tree.ForestStoreModel");
+}
diff --git a/dijit/_Calendar.js b/dijit/_Calendar.js
new file mode 100644
index 0000000..2d367f8
--- /dev/null
+++ b/dijit/_Calendar.js
@@ -0,0 +1,179 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._Calendar"]){
+dojo._hasResource["dijit._Calendar"]=true;
+dojo.provide("dijit._Calendar");
+dojo.require("dojo.cldr.supplemental");
+dojo.require("dojo.date");
+dojo.require("dojo.date.locale");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.declare("dijit._Calendar",[dijit._Widget,dijit._Templated],{templateString:"<table cellspacing=\"0\" cellpadding=\"0\" class=\"dijitCalendarContainer\">\n\t<thead>\n\t\t<tr class=\"dijitReset dijitCalendarMonthContainer\" valign=\"top\">\n\t\t\t<th class='dijitReset' dojoAttachPoint=\"decrementMonth\">\n\t\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitCalendarIncrementControl dijitCalendarDecrease\" waiRole=\"presentation\">\n\t\t\t\t<span dojoAttachPoint=\"decreaseArrowNode\ [...]
+dojo.deprecated("dijit.Calendar:setValue() is deprecated.  Use attr('value', ...) instead.","","2.0");
+this.attr("value",_1);
+},_getValueAttr:function(_2){
+var _2=new Date(this.value);
+_2.setHours(0,0,0,0);
+if(_2.getDate()<this.value.getDate()){
+_2=dojo.date.add(_2,"hour",1);
+}
+return _2;
+},_setValueAttr:function(_3){
+if(!this.value||dojo.date.compare(_3,this.value)){
+_3=new Date(_3);
+_3.setHours(1);
+this.displayMonth=new Date(_3);
+if(!this.isDisabledDate(_3,this.lang)){
+this.value=_3;
+this.onChange(this.attr("value"));
+}
+this._populateGrid();
+}
+},_setText:function(_4,_5){
+while(_4.firstChild){
+_4.removeChild(_4.firstChild);
+}
+_4.appendChild(dojo.doc.createTextNode(_5));
+},_populateGrid:function(){
+var _6=this.displayMonth;
+_6.setDate(1);
+var _7=_6.getDay();
+var _8=dojo.date.getDaysInMonth(_6);
+var _9=dojo.date.getDaysInMonth(dojo.date.add(_6,"month",-1));
+var _a=new Date();
+var _b=this.value;
+var _c=dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
+if(_c>_7){
+_c-=7;
+}
+dojo.query(".dijitCalendarDateTemplate",this.domNode).forEach(function(_d,i){
+i+=_c;
+var _f=new Date(_6);
+var _10,_11="dijitCalendar",adj=0;
+if(i<_7){
+_10=_9-_7+i+1;
+adj=-1;
+_11+="Previous";
+}else{
+if(i>=(_7+_8)){
+_10=i-_7-_8+1;
+adj=1;
+_11+="Next";
+}else{
+_10=i-_7+1;
+_11+="Current";
+}
+}
+if(adj){
+_f=dojo.date.add(_f,"month",adj);
+}
+_f.setDate(_10);
+if(!dojo.date.compare(_f,_a,"date")){
+_11="dijitCalendarCurrentDate "+_11;
+}
+if(!dojo.date.compare(_f,_b,"date")){
+_11="dijitCalendarSelectedDate "+_11;
+}
+if(this.isDisabledDate(_f,this.lang)){
+_11="dijitCalendarDisabledDate "+_11;
+}
+var _13=this.getClassForDate(_f,this.lang);
+if(_13){
+_11=_13+" "+_11;
+}
+_d.className=_11+"Month dijitCalendarDateTemplate";
+_d.dijitDateValue=_f.valueOf();
+var _14=dojo.query(".dijitCalendarDateLabel",_d)[0];
+this._setText(_14,_f.getDate());
+},this);
+var _15=dojo.date.locale.getNames("months","wide","standAlone",this.lang);
+this._setText(this.monthLabelNode,_15[_6.getMonth()]);
+var y=_6.getFullYear()-1;
+var d=new Date();
+dojo.forEach(["previous","current","next"],function(_18){
+d.setFullYear(y++);
+this._setText(this[_18+"YearLabelNode"],dojo.date.locale.format(d,{selector:"year",locale:this.lang}));
+},this);
+var _19=this;
+var _1a=function(_1b,_1c,adj){
+_19._connects.push(dijit.typematic.addMouseListener(_19[_1b],_19,function(_1e){
+if(_1e>=0){
+_19._adjustDisplay(_1c,adj);
+}
+},0.8,500));
+};
+_1a("incrementMonth","month",1);
+_1a("decrementMonth","month",-1);
+_1a("nextYearLabelNode","year",1);
+_1a("previousYearLabelNode","year",-1);
+},goToToday:function(){
+this.attr("value",new Date());
+},postCreate:function(){
+this.inherited(arguments);
+dojo.setSelectable(this.domNode,false);
+var _1f=dojo.hitch(this,function(_20,n){
+var _22=dojo.query(_20,this.domNode)[0];
+for(var i=0;i<n;i++){
+_22.parentNode.appendChild(_22.cloneNode(true));
+}
+});
+_1f(".dijitCalendarDayLabelTemplate",6);
+_1f(".dijitCalendarDateTemplate",6);
+_1f(".dijitCalendarWeekTemplate",5);
+var _24=dojo.date.locale.getNames("days",this.dayWidth,"standAlone",this.lang);
+var _25=dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
+dojo.query(".dijitCalendarDayLabel",this.domNode).forEach(function(_26,i){
+this._setText(_26,_24[(i+_25)%7]);
+},this);
+var _28=dojo.date.locale.getNames("months","wide","standAlone",this.lang);
+dojo.forEach(_28,function(_29){
+var _2a=dojo.create("div",null,this.monthLabelSpacer);
+this._setText(_2a,_29);
+},this);
+this.value=null;
+this.attr("value",new Date());
+},_adjustDisplay:function(_2b,_2c){
+this.displayMonth=dojo.date.add(this.displayMonth,_2b,_2c);
+this._populateGrid();
+},_onDayClick:function(evt){
+dojo.stopEvent(evt);
+for(var _2e=evt.target;_2e&&!_2e.dijitDateValue;_2e=_2e.parentNode){
+}
+if(_2e&&!dojo.hasClass(_2e,"dijitCalendarDisabledDate")){
+this.attr("value",_2e.dijitDateValue);
+this.onValueSelected(this.attr("value"));
+}
+},_onDayMouseOver:function(evt){
+var _30=evt.target;
+if(_30&&(_30.dijitDateValue||_30==this.previousYearLabelNode||_30==this.nextYearLabelNode)){
+dojo.addClass(_30,"dijitCalendarHoveredDate");
+this._currentNode=_30;
+}
+},_onDayMouseOut:function(evt){
+if(!this._currentNode){
+return;
+}
+for(var _32=evt.relatedTarget;_32;){
+if(_32==this._currentNode){
+return;
+}
+try{
+_32=_32.parentNode;
+}
+catch(x){
+_32=null;
+}
+}
+dojo.removeClass(this._currentNode,"dijitCalendarHoveredDate");
+this._currentNode=null;
+},onValueSelected:function(_33){
+},onChange:function(_34){
+},isDisabledDate:function(_35,_36){
+},getClassForDate:function(_37,_38){
+}});
+}
diff --git a/dijit/_Contained.js b/dijit/_Contained.js
new file mode 100644
index 0000000..6d8aaaa
--- /dev/null
+++ b/dijit/_Contained.js
@@ -0,0 +1,41 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._Contained"]){
+dojo._hasResource["dijit._Contained"]=true;
+dojo.provide("dijit._Contained");
+dojo.declare("dijit._Contained",null,{getParent:function(){
+for(var p=this.domNode.parentNode;p;p=p.parentNode){
+var id=p.getAttribute&&p.getAttribute("widgetId");
+if(id){
+var _3=dijit.byId(id);
+return _3.isContainer?_3:null;
+}
+}
+return null;
+},_getSibling:function(_4){
+var _5=this.domNode;
+do{
+_5=_5[_4+"Sibling"];
+}while(_5&&_5.nodeType!=1);
+if(!_5){
+return null;
+}
+var id=_5.getAttribute("widgetId");
+return dijit.byId(id);
+},getPreviousSibling:function(){
+return this._getSibling("previous");
+},getNextSibling:function(){
+return this._getSibling("next");
+},getIndexInParent:function(){
+var p=this.getParent();
+if(!p||!p.getIndexOfChild){
+return -1;
+}
+return p.getIndexOfChild(this);
+}});
+}
diff --git a/dijit/_Container.js b/dijit/_Container.js
new file mode 100644
index 0000000..2c0100d
--- /dev/null
+++ b/dijit/_Container.js
@@ -0,0 +1,73 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._Container"]){
+dojo._hasResource["dijit._Container"]=true;
+dojo.provide("dijit._Container");
+dojo.declare("dijit._Container",null,{isContainer:true,buildRendering:function(){
+this.inherited(arguments);
+if(!this.containerNode){
+this.containerNode=this.domNode;
+}
+},addChild:function(_1,_2){
+var _3=this.containerNode;
+if(_2&&typeof _2=="number"){
+var _4=this.getChildren();
+if(_4&&_4.length>=_2){
+_3=_4[_2-1].domNode;
+_2="after";
+}
+}
+dojo.place(_1.domNode,_3,_2);
+if(this._started&&!_1._started){
+_1.startup();
+}
+},removeChild:function(_5){
+if(typeof _5=="number"&&_5>0){
+_5=this.getChildren()[_5];
+}
+if(!_5||!_5.domNode){
+return;
+}
+var _6=_5.domNode;
+_6.parentNode.removeChild(_6);
+},_nextElement:function(_7){
+do{
+_7=_7.nextSibling;
+}while(_7&&_7.nodeType!=1);
+return _7;
+},_firstElement:function(_8){
+_8=_8.firstChild;
+if(_8&&_8.nodeType!=1){
+_8=this._nextElement(_8);
+}
+return _8;
+},getChildren:function(){
+return dojo.query("> [widgetId]",this.containerNode).map(dijit.byNode);
+},hasChildren:function(){
+return !!this._firstElement(this.containerNode);
+},destroyDescendants:function(_9){
+dojo.forEach(this.getChildren(),function(_a){
+_a.destroyRecursive(_9);
+});
+},_getSiblingOfChild:function(_b,_c){
+var _d=_b.domNode;
+var _e=(_c>0?"nextSibling":"previousSibling");
+do{
+_d=_d[_e];
+}while(_d&&(_d.nodeType!=1||!dijit.byNode(_d)));
+return _d?dijit.byNode(_d):null;
+},getIndexOfChild:function(_f){
+var _10=this.getChildren();
+for(var i=0,c;c=_10[i];i++){
+if(c==_f){
+return i;
+}
+}
+return -1;
+}});
+}
diff --git a/dijit/_DialogMixin.js b/dijit/_DialogMixin.js
new file mode 100644
index 0000000..ef40cab
--- /dev/null
+++ b/dijit/_DialogMixin.js
@@ -0,0 +1,26 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._DialogMixin"]){
+dojo._hasResource["dijit._DialogMixin"]=true;
+dojo.provide("dijit._DialogMixin");
+dojo.declare("dijit._DialogMixin",null,{attributeMap:dijit._Widget.prototype.attributeMap,execute:function(_1){
+},onCancel:function(){
+},onExecute:function(){
+},_onSubmit:function(){
+this.onExecute();
+this.execute(this.attr("value"));
+},_getFocusItems:function(_2){
+var _3=dijit._getTabNavigable(dojo.byId(_2));
+this._firstFocusItem=_3.lowest||_3.first||_2;
+this._lastFocusItem=_3.last||_3.highest||this._firstFocusItem;
+if(dojo.isMoz&&this._firstFocusItem.tagName.toLowerCase()=="input"&&dojo.attr(this._firstFocusItem,"type").toLowerCase()=="file"){
+dojo.attr(_2,"tabindex","0");
+this._firstFocusItem=_2;
+}
+}});
+}
diff --git a/dijit/_KeyNavContainer.js b/dijit/_KeyNavContainer.js
new file mode 100644
index 0000000..06b556f
--- /dev/null
+++ b/dijit/_KeyNavContainer.js
@@ -0,0 +1,130 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._KeyNavContainer"]){
+dojo._hasResource["dijit._KeyNavContainer"]=true;
+dojo.provide("dijit._KeyNavContainer");
+dojo.require("dijit._Container");
+dojo.declare("dijit._KeyNavContainer",[dijit._Container],{tabIndex:"0",_keyNavCodes:{},connectKeyNavHandlers:function(_1,_2){
+var _3=this._keyNavCodes={};
+var _4=dojo.hitch(this,this.focusPrev);
+var _5=dojo.hitch(this,this.focusNext);
+dojo.forEach(_1,function(_6){
+_3[_6]=_4;
+});
+dojo.forEach(_2,function(_7){
+_3[_7]=_5;
+});
+this.connect(this.domNode,"onkeypress","_onContainerKeypress");
+this.connect(this.domNode,"onfocus","_onContainerFocus");
+},startupKeyNavChildren:function(){
+dojo.forEach(this.getChildren(),dojo.hitch(this,"_startupChild"));
+},addChild:function(_8,_9){
+dijit._KeyNavContainer.superclass.addChild.apply(this,arguments);
+this._startupChild(_8);
+},focus:function(){
+this.focusFirstChild();
+},focusFirstChild:function(){
+this.focusChild(this._getFirstFocusableChild());
+},focusNext:function(){
+if(this.focusedChild&&this.focusedChild.hasNextFocalNode&&this.focusedChild.hasNextFocalNode()){
+this.focusedChild.focusNext();
+return;
+}
+var _a=this._getNextFocusableChild(this.focusedChild,1);
+if(_a.getFocalNodes){
+this.focusChild(_a,_a.getFocalNodes()[0]);
+}else{
+this.focusChild(_a);
+}
+},focusPrev:function(){
+if(this.focusedChild&&this.focusedChild.hasPrevFocalNode&&this.focusedChild.hasPrevFocalNode()){
+this.focusedChild.focusPrev();
+return;
+}
+var _b=this._getNextFocusableChild(this.focusedChild,-1);
+if(_b.getFocalNodes){
+var _c=_b.getFocalNodes();
+this.focusChild(_b,_c[_c.length-1]);
+}else{
+this.focusChild(_b);
+}
+},focusChild:function(_d,_e){
+if(_d){
+if(this.focusedChild&&_d!==this.focusedChild){
+this._onChildBlur(this.focusedChild);
+}
+this.focusedChild=_d;
+if(_e&&_d.focusFocalNode){
+_d.focusFocalNode(_e);
+}else{
+_d.focus();
+}
+}
+},_startupChild:function(_f){
+if(_f.getFocalNodes){
+dojo.forEach(_f.getFocalNodes(),function(_10){
+dojo.attr(_10,"tabindex",-1);
+this._connectNode(_10);
+},this);
+}else{
+var _11=_f.focusNode||_f.domNode;
+if(_f.isFocusable()){
+dojo.attr(_11,"tabindex",-1);
+}
+this._connectNode(_11);
+}
+},_connectNode:function(_12){
+this.connect(_12,"onfocus","_onNodeFocus");
+this.connect(_12,"onblur","_onNodeBlur");
+},_onContainerFocus:function(evt){
+if(evt.target!==this.domNode){
+return;
+}
+this.focusFirstChild();
+dojo.removeAttr(this.domNode,"tabIndex");
+},_onBlur:function(evt){
+if(this.tabIndex){
+dojo.attr(this.domNode,"tabindex",this.tabIndex);
+}
+},_onContainerKeypress:function(evt){
+if(evt.ctrlKey||evt.altKey){
+return;
+}
+var _16=this._keyNavCodes[evt.charOrCode];
+if(_16){
+_16();
+dojo.stopEvent(evt);
+}
+},_onNodeFocus:function(evt){
+var _18=dijit.getEnclosingWidget(evt.target);
+if(_18&&_18.isFocusable()){
+this.focusedChild=_18;
+}
+dojo.stopEvent(evt);
+},_onNodeBlur:function(evt){
+dojo.stopEvent(evt);
+},_onChildBlur:function(_1a){
+},_getFirstFocusableChild:function(){
+return this._getNextFocusableChild(null,1);
+},_getNextFocusableChild:function(_1b,dir){
+if(_1b){
+_1b=this._getSiblingOfChild(_1b,dir);
+}
+var _1d=this.getChildren();
+for(var i=0;i<_1d.length;i++){
+if(!_1b){
+_1b=_1d[(dir>0)?0:(_1d.length-1)];
+}
+if(_1b.isFocusable()){
+return _1b;
+}
+_1b=this._getSiblingOfChild(_1b,dir);
+}
+return null;
+}});
+}
diff --git a/dijit/_Templated.js b/dijit/_Templated.js
new file mode 100644
index 0000000..72eb905
--- /dev/null
+++ b/dijit/_Templated.js
@@ -0,0 +1,156 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._Templated"]){
+dojo._hasResource["dijit._Templated"]=true;
+dojo.provide("dijit._Templated");
+dojo.require("dijit._Widget");
+dojo.require("dojo.string");
+dojo.require("dojo.parser");
+dojo.declare("dijit._Templated",null,{templateString:null,templatePath:null,widgetsInTemplate:false,_skipNodeCache:false,_stringRepl:function(_1){
+var _2=this.declaredClass,_3=this;
+return dojo.string.substitute(_1,this,function(_4,_5){
+if(_5.charAt(0)=="!"){
+_4=dojo.getObject(_5.substr(1),false,_3);
+}
+if(typeof _4=="undefined"){
+throw new Error(_2+" template:"+_5);
+}
+if(_4==null){
+return "";
+}
+return _5.charAt(0)=="!"?_4:_4.toString().replace(/"/g,""");
+},this);
+},buildRendering:function(){
+var _6=dijit._Templated.getCachedTemplate(this.templatePath,this.templateString,this._skipNodeCache);
+var _7;
+if(dojo.isString(_6)){
+_7=dojo._toDom(this._stringRepl(_6));
+}else{
+_7=_6.cloneNode(true);
+}
+this.domNode=_7;
+this._attachTemplateNodes(_7);
+if(this.widgetsInTemplate){
+var cw=(this._supportingWidgets=dojo.parser.parse(_7));
+this._attachTemplateNodes(cw,function(n,p){
+return n[p];
+});
+}
+this._fillContent(this.srcNodeRef);
+},_fillContent:function(_b){
+var _c=this.containerNode;
+if(_b&&_c){
+while(_b.hasChildNodes()){
+_c.appendChild(_b.firstChild);
+}
+}
+},_attachTemplateNodes:function(_d,_e){
+_e=_e||function(n,p){
+return n.getAttribute(p);
+};
+var _11=dojo.isArray(_d)?_d:(_d.all||_d.getElementsByTagName("*"));
+var x=dojo.isArray(_d)?0:-1;
+for(;x<_11.length;x++){
+var _13=(x==-1)?_d:_11[x];
+if(this.widgetsInTemplate&&_e(_13,"dojoType")){
+continue;
+}
+var _14=_e(_13,"dojoAttachPoint");
+if(_14){
+var _15,_16=_14.split(/\s*,\s*/);
+while((_15=_16.shift())){
+if(dojo.isArray(this[_15])){
+this[_15].push(_13);
+}else{
+this[_15]=_13;
+}
+}
+}
+var _17=_e(_13,"dojoAttachEvent");
+if(_17){
+var _18,_19=_17.split(/\s*,\s*/);
+var _1a=dojo.trim;
+while((_18=_19.shift())){
+if(_18){
+var _1b=null;
+if(_18.indexOf(":")!=-1){
+var _1c=_18.split(":");
+_18=_1a(_1c[0]);
+_1b=_1a(_1c[1]);
+}else{
+_18=_1a(_18);
+}
+if(!_1b){
+_1b=_18;
+}
+this.connect(_13,_18,_1b);
+}
+}
+}
+var _1d=_e(_13,"waiRole");
+if(_1d){
+dijit.setWaiRole(_13,_1d);
+}
+var _1e=_e(_13,"waiState");
+if(_1e){
+dojo.forEach(_1e.split(/\s*,\s*/),function(_1f){
+if(_1f.indexOf("-")!=-1){
+var _20=_1f.split("-");
+dijit.setWaiState(_13,_20[0],_20[1]);
+}
+});
+}
+}
+}});
+dijit._Templated._templateCache={};
+dijit._Templated.getCachedTemplate=function(_21,_22,_23){
+var _24=dijit._Templated._templateCache;
+var key=_22||_21;
+var _26=_24[key];
+if(_26){
+if(!_26.ownerDocument||_26.ownerDocument==dojo.doc){
+return _26;
+}
+dojo.destroy(_26);
+}
+if(!_22){
+_22=dijit._Templated._sanitizeTemplateString(dojo.trim(dojo._getText(_21)));
+}
+_22=dojo.string.trim(_22);
+if(_23||_22.match(/\$\{([^\}]+)\}/g)){
+return (_24[key]=_22);
+}else{
+return (_24[key]=dojo._toDom(_22));
+}
+};
+dijit._Templated._sanitizeTemplateString=function(_27){
+if(_27){
+_27=_27.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,"");
+var _28=_27.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
+if(_28){
+_27=_28[1];
+}
+}else{
+_27="";
+}
+return _27;
+};
+if(dojo.isIE){
+dojo.addOnWindowUnload(function(){
+var _29=dijit._Templated._templateCache;
+for(var key in _29){
+var _2b=_29[key];
+if(!isNaN(_2b.nodeType)){
+dojo.destroy(_2b);
+}
+delete _29[key];
+}
+});
+}
+dojo.extend(dijit._Widget,{dojoAttachEvent:"",dojoAttachPoint:"",waiRole:"",waiState:""});
+}
diff --git a/dijit/_TimePicker.js b/dijit/_TimePicker.js
new file mode 100644
index 0000000..6c5e472
--- /dev/null
+++ b/dijit/_TimePicker.js
@@ -0,0 +1,257 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._TimePicker"]){
+dojo._hasResource["dijit._TimePicker"]=true;
+dojo.provide("dijit._TimePicker");
+dojo.require("dijit.form._FormWidget");
+dojo.require("dojo.date.locale");
+dojo.declare("dijit._TimePicker",[dijit._Widget,dijit._Templated],{templateString:"<div id=\"widget_${id}\" class=\"dijitMenu ${baseClass}\"\n    ><div dojoAttachPoint=\"upArrow\" class=\"dijitButtonNode dijitUpArrowButton\" dojoAttachEvent=\"onmouseenter:_buttonMouse,onmouseleave:_buttonMouse\"\n\t\t><div class=\"dijitReset dijitInline dijitArrowButtonInner\" wairole=\"presentation\" role=\"presentation\"> </div\n\t\t><div class=\"dijitArrowButtonChar\">▲</div></div\n    ><di [...]
+dojo.deprecated("dijit._TimePicker:setValue() is deprecated.  Use attr('value') instead.","","2.0");
+this.attr("value",_1);
+},_setValueAttr:function(_2){
+this.value=_2;
+this._showText();
+},onOpen:function(_3){
+if(this._beenOpened&&this.domNode.parentNode){
+var p=dijit.byId(this.domNode.parentNode.dijitPopupParent);
+if(p){
+var _5=p.getDisplayedValue();
+if(_5&&!p.parse(_5,p.constraints)){
+this._filterString=_5;
+}else{
+this._filterString="";
+}
+this._showText();
+}
+}
+this._beenOpened=true;
+},isDisabledDate:function(_6,_7){
+return false;
+},_getFilteredNodes:function(_8,_9,_a){
+var _b=[],n,i=_8,_e=this._maxIncrement+Math.abs(i),_f=_a?-1:1,dec=_a?1:0,inc=_a?0:1;
+do{
+i=i-dec;
+n=this._createOption(i);
+if(n){
+_b.push(n);
+}
+i=i+inc;
+}while(_b.length<_9&&(i*_f)<_e);
+if(_a){
+_b.reverse();
+}
+return _b;
+},_showText:function(){
+this.timeMenu.innerHTML="";
+var _12=dojo.date.stamp.fromISOString;
+this._clickableIncrementDate=_12(this.clickableIncrement);
+this._visibleIncrementDate=_12(this.visibleIncrement);
+this._visibleRangeDate=_12(this.visibleRange);
+var _13=function(_14){
+return _14.getHours()*60*60+_14.getMinutes()*60+_14.getSeconds();
+};
+var _15=_13(this._clickableIncrementDate);
+var _16=_13(this._visibleIncrementDate);
+var _17=_13(this._visibleRangeDate);
+var _18=this.value.getTime();
+this._refDate=new Date(_18-_18%(_16*1000));
+this._refDate.setFullYear(1970,0,1);
+this._clickableIncrement=1;
+this._totalIncrements=_17/_15;
+this._visibleIncrement=_16/_15;
+this._maxIncrement=(60*60*24)/_15;
+var _19=this._getFilteredNodes(0,this._totalIncrements>>1,true);
+var _1a=this._getFilteredNodes(0,this._totalIncrements>>1,false);
+if(_19.length<this._totalIncrements>>1){
+_19=_19.slice(_19.length/2);
+_1a=_1a.slice(0,_1a.length/2);
+}
+dojo.forEach(_19.concat(_1a),function(n){
+this.timeMenu.appendChild(n);
+},this);
+},postCreate:function(){
+if(this.constraints===dijit._TimePicker.prototype.constraints){
+this.constraints={};
+}
+dojo.mixin(this,this.constraints);
+if(!this.constraints.locale){
+this.constraints.locale=this.lang;
+}
+this.connect(this.timeMenu,dojo.isIE?"onmousewheel":"DOMMouseScroll","_mouseWheeled");
+var _1c=this;
+var _1d=function(){
+_1c._connects.push(dijit.typematic.addMouseListener.apply(null,arguments));
+};
+_1d(this.upArrow,this,this._onArrowUp,1,50);
+_1d(this.downArrow,this,this._onArrowDown,1,50);
+var _1e=function(cb){
+return function(cnt){
+if(cnt>0){
+cb.call(this,arguments);
+}
+};
+};
+var _21=function(_22,cb){
+return function(e){
+dojo.stopEvent(e);
+dijit.typematic.trigger(e,this,_22,_1e(cb),_22,1,50);
+};
+};
+this.connect(this.upArrow,"onmouseover",_21(this.upArrow,this._onArrowUp));
+this.connect(this.downArrow,"onmouseover",_21(this.downArrow,this._onArrowDown));
+this.inherited(arguments);
+},_buttonMouse:function(e){
+dojo.toggleClass(e.currentTarget,"dijitButtonNodeHover",e.type=="mouseover");
+},_createOption:function(_26){
+var _27=new Date(this._refDate);
+var _28=this._clickableIncrementDate;
+_27.setHours(_27.getHours()+_28.getHours()*_26,_27.getMinutes()+_28.getMinutes()*_26,_27.getSeconds()+_28.getSeconds()*_26);
+var _29=dojo.date.locale.format(_27,this.constraints);
+if(this._filterString&&_29.toLowerCase().indexOf(this._filterString)!==0){
+return null;
+}
+var div=dojo.create("div",{"class":this.baseClass+"Item"});
+div.date=_27;
+div.index=_26;
+dojo.create("div",{"class":this.baseClass+"ItemInner",innerHTML:_29},div);
+if(_26%this._visibleIncrement<1&&_26%this._visibleIncrement>-1){
+dojo.addClass(div,this.baseClass+"Marker");
+}else{
+if(!(_26%this._clickableIncrement)){
+dojo.addClass(div,this.baseClass+"Tick");
+}
+}
+if(this.isDisabledDate(_27)){
+dojo.addClass(div,this.baseClass+"ItemDisabled");
+}
+if(!dojo.date.compare(this.value,_27,this.constraints.selector)){
+div.selected=true;
+dojo.addClass(div,this.baseClass+"ItemSelected");
+if(dojo.hasClass(div,this.baseClass+"Marker")){
+dojo.addClass(div,this.baseClass+"MarkerSelected");
+}else{
+dojo.addClass(div,this.baseClass+"TickSelected");
+}
+}
+return div;
+},_onOptionSelected:function(tgt){
+var _2c=tgt.target.date||tgt.target.parentNode.date;
+if(!_2c||this.isDisabledDate(_2c)){
+return;
+}
+this._highlighted_option=null;
+this.attr("value",_2c);
+this.onValueSelected(_2c);
+},onValueSelected:function(_2d){
+},_highlightOption:function(_2e,_2f){
+if(!_2e){
+return;
+}
+if(_2f){
+if(this._highlighted_option){
+this._highlightOption(this._highlighted_option,false);
+}
+this._highlighted_option=_2e;
+}else{
+if(this._highlighted_option!==_2e){
+return;
+}else{
+this._highlighted_option=null;
+}
+}
+dojo.toggleClass(_2e,this.baseClass+"ItemHover",_2f);
+if(dojo.hasClass(_2e,this.baseClass+"Marker")){
+dojo.toggleClass(_2e,this.baseClass+"MarkerHover",_2f);
+}else{
+dojo.toggleClass(_2e,this.baseClass+"TickHover",_2f);
+}
+},onmouseover:function(e){
+var tgr=(e.target.parentNode===this.timeMenu)?e.target:e.target.parentNode;
+if(!dojo.hasClass(tgr,this.baseClass+"Item")){
+return;
+}
+this._highlightOption(tgr,true);
+},onmouseout:function(e){
+var tgr=(e.target.parentNode===this.timeMenu)?e.target:e.target.parentNode;
+this._highlightOption(tgr,false);
+},_mouseWheeled:function(e){
+dojo.stopEvent(e);
+var _35=(dojo.isIE?e.wheelDelta:-e.detail);
+this[(_35>0?"_onArrowUp":"_onArrowDown")]();
+},_onArrowUp:function(_36){
+if(typeof _36=="number"&&_36==-1){
+return;
+}
+if(!this.timeMenu.childNodes.length){
+return;
+}
+var _37=this.timeMenu.childNodes[0].index;
+var _38=this._getFilteredNodes(_37,1,true);
+if(_38.length){
+this.timeMenu.removeChild(this.timeMenu.childNodes[this.timeMenu.childNodes.length-1]);
+this.timeMenu.insertBefore(_38[0],this.timeMenu.childNodes[0]);
+}
+},_onArrowDown:function(_39){
+if(typeof _39=="number"&&_39==-1){
+return;
+}
+if(!this.timeMenu.childNodes.length){
+return;
+}
+var _3a=this.timeMenu.childNodes[this.timeMenu.childNodes.length-1].index+1;
+var _3b=this._getFilteredNodes(_3a,1,false);
+if(_3b.length){
+this.timeMenu.removeChild(this.timeMenu.childNodes[0]);
+this.timeMenu.appendChild(_3b[0]);
+}
+},handleKey:function(e){
+var dk=dojo.keys;
+if(e.keyChar||e.charOrCode===dk.BACKSPACE||e.charOrCode==dk.DELETE){
+setTimeout(dojo.hitch(this,function(){
+this._filterString=e.target.value.toLowerCase();
+this._showText();
+}),1);
+}else{
+if(e.charOrCode==dk.DOWN_ARROW||e.charOrCode==dk.UP_ARROW){
+dojo.stopEvent(e);
+if(this._highlighted_option&&!this._highlighted_option.parentNode){
+this._highlighted_option=null;
+}
+var _3e=this.timeMenu,tgt=this._highlighted_option||dojo.query("."+this.baseClass+"ItemSelected",_3e)[0];
+if(!tgt){
+tgt=_3e.childNodes[0];
+}else{
+if(_3e.childNodes.length){
+if(e.charOrCode==dk.DOWN_ARROW&&!tgt.nextSibling){
+this._onArrowDown();
+}else{
+if(e.charOrCode==dk.UP_ARROW&&!tgt.previousSibling){
+this._onArrowUp();
+}
+}
+if(e.charOrCode==dk.DOWN_ARROW){
+tgt=tgt.nextSibling;
+}else{
+tgt=tgt.previousSibling;
+}
+}
+}
+this._highlightOption(tgt,true);
+}else{
+if(this._highlighted_option&&(e.charOrCode==dk.ENTER||e.charOrCode===dk.TAB)){
+if(e.charOrCode==dk.ENTER){
+dojo.stopEvent(e);
+}
+setTimeout(dojo.hitch(this,function(){
+this._onOptionSelected({target:this._highlighted_option});
+}),1);
+}
+}
+}
+}});
+}
diff --git a/dijit/_Widget.js b/dijit/_Widget.js
new file mode 100644
index 0000000..407d4af
--- /dev/null
+++ b/dijit/_Widget.js
@@ -0,0 +1,301 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._Widget"]){
+dojo._hasResource["dijit._Widget"]=true;
+dojo.provide("dijit._Widget");
+dojo.require("dijit._base");
+dojo.connect(dojo,"connect",function(_1,_2){
+if(_1&&dojo.isFunction(_1._onConnect)){
+_1._onConnect(_2);
+}
+});
+dijit._connectOnUseEventHandler=function(_3){
+};
+(function(){
+var _4={};
+var _5=function(dc){
+if(!_4[dc]){
+var r=[];
+var _8;
+var _9=dojo.getObject(dc).prototype;
+for(var _a in _9){
+if(dojo.isFunction(_9[_a])&&(_8=_a.match(/^_set([a-zA-Z]*)Attr$/))&&_8[1]){
+r.push(_8[1].charAt(0).toLowerCase()+_8[1].substr(1));
+}
+}
+_4[dc]=r;
+}
+return _4[dc]||[];
+};
+dojo.declare("dijit._Widget",null,{id:"",lang:"",dir:"","class":"",style:"",title:"",srcNodeRef:null,domNode:null,containerNode:null,attributeMap:{id:"",dir:"",lang:"","class":"",style:"",title:""},_deferredConnects:{onClick:"",onDblClick:"",onKeyDown:"",onKeyPress:"",onKeyUp:"",onMouseMove:"",onMouseDown:"",onMouseOut:"",onMouseOver:"",onMouseLeave:"",onMouseEnter:"",onMouseUp:""},onClick:dijit._connectOnUseEventHandler,onDblClick:dijit._connectOnUseEventHandler,onKeyDown:dijit._connect [...]
+this.create(_b,_c);
+},create:function(_d,_e){
+this.srcNodeRef=dojo.byId(_e);
+this._connects=[];
+this._deferredConnects=dojo.clone(this._deferredConnects);
+for(var _f in this.attributeMap){
+delete this._deferredConnects[_f];
+}
+for(_f in this._deferredConnects){
+if(this[_f]!==dijit._connectOnUseEventHandler){
+delete this._deferredConnects[_f];
+}
+}
+if(this.srcNodeRef&&(typeof this.srcNodeRef.id=="string")){
+this.id=this.srcNodeRef.id;
+}
+if(_d){
+this.params=_d;
+dojo.mixin(this,_d);
+}
+this.postMixInProperties();
+if(!this.id){
+this.id=dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
+}
+dijit.registry.add(this);
+this.buildRendering();
+if(this.domNode){
+this._applyAttributes();
+var _10=this.srcNodeRef;
+if(_10&&_10.parentNode){
+_10.parentNode.replaceChild(this.domNode,_10);
+}
+for(_f in this.params){
+this._onConnect(_f);
+}
+}
+if(this.domNode){
+this.domNode.setAttribute("widgetId",this.id);
+}
+this.postCreate();
+if(this.srcNodeRef&&!this.srcNodeRef.parentNode){
+delete this.srcNodeRef;
+}
+this._created=true;
+},_applyAttributes:function(){
+var _11=function(_12,_13){
+if((_13.params&&_12 in _13.params)||_13[_12]){
+_13.attr(_12,_13[_12]);
+}
+};
+for(var _14 in this.attributeMap){
+_11(_14,this);
+}
+dojo.forEach(_5(this.declaredClass),function(a){
+if(!(a in this.attributeMap)){
+_11(a,this);
+}
+},this);
+},postMixInProperties:function(){
+},buildRendering:function(){
+this.domNode=this.srcNodeRef||dojo.create("div");
+},postCreate:function(){
+},startup:function(){
+this._started=true;
+},destroyRecursive:function(_16){
+this.destroyDescendants(_16);
+this.destroy(_16);
+},destroy:function(_17){
+this.uninitialize();
+dojo.forEach(this._connects,function(_18){
+dojo.forEach(_18,dojo.disconnect);
+});
+dojo.forEach(this._supportingWidgets||[],function(w){
+if(w.destroy){
+w.destroy();
+}
+});
+this.destroyRendering(_17);
+dijit.registry.remove(this.id);
+},destroyRendering:function(_1a){
+if(this.bgIframe){
+this.bgIframe.destroy(_1a);
+delete this.bgIframe;
+}
+if(this.domNode){
+if(_1a){
+dojo.removeAttr(this.domNode,"widgetId");
+}else{
+dojo.destroy(this.domNode);
+}
+delete this.domNode;
+}
+if(this.srcNodeRef){
+if(!_1a){
+dojo.destroy(this.srcNodeRef);
+}
+delete this.srcNodeRef;
+}
+},destroyDescendants:function(_1b){
+dojo.forEach(this.getChildren(),function(_1c){
+if(_1c.destroyRecursive){
+_1c.destroyRecursive(_1b);
+}
+});
+},uninitialize:function(){
+return false;
+},onFocus:function(){
+},onBlur:function(){
+},_onFocus:function(e){
+this.onFocus();
+},_onBlur:function(){
+this.onBlur();
+},_onConnect:function(_1e){
+if(_1e in this._deferredConnects){
+var _1f=this[this._deferredConnects[_1e]||"domNode"];
+this.connect(_1f,_1e.toLowerCase(),_1e);
+delete this._deferredConnects[_1e];
+}
+},_setClassAttr:function(_20){
+var _21=this[this.attributeMap["class"]||"domNode"];
+dojo.removeClass(_21,this["class"]);
+this["class"]=_20;
+dojo.addClass(_21,_20);
+},_setStyleAttr:function(_22){
+var _23=this[this.attributeMap["style"]||"domNode"];
+if(dojo.isObject(_22)){
+dojo.style(_23,_22);
+}else{
+if(_23.style.cssText){
+_23.style.cssText+="; "+_22;
+}else{
+_23.style.cssText=_22;
+}
+}
+this["style"]=_22;
+},setAttribute:function(_24,_25){
+dojo.deprecated(this.declaredClass+"::setAttribute() is deprecated. Use attr() instead.","","2.0");
+this.attr(_24,_25);
+},_attrToDom:function(_26,_27){
+var _28=this.attributeMap[_26];
+dojo.forEach(dojo.isArray(_28)?_28:[_28],function(_29){
+var _2a=this[_29.node||_29||"domNode"];
+var _2b=_29.type||"attribute";
+switch(_2b){
+case "attribute":
+if(dojo.isFunction(_27)){
+_27=dojo.hitch(this,_27);
+}
+if(/^on[A-Z][a-zA-Z]*$/.test(_26)){
+_26=_26.toLowerCase();
+}
+dojo.attr(_2a,_26,_27);
+break;
+case "innerHTML":
+_2a.innerHTML=_27;
+break;
+case "class":
+dojo.removeClass(_2a,this[_26]);
+dojo.addClass(_2a,_27);
+break;
+}
+},this);
+this[_26]=_27;
+},attr:function(_2c,_2d){
+var _2e=arguments.length;
+if(_2e==1&&!dojo.isString(_2c)){
+for(var x in _2c){
+this.attr(x,_2c[x]);
+}
+return this;
+}
+var _30=this._getAttrNames(_2c);
+if(_2e==2){
+if(this[_30.s]){
+return this[_30.s](_2d)||this;
+}else{
+if(_2c in this.attributeMap){
+this._attrToDom(_2c,_2d);
+}
+this[_2c]=_2d;
+}
+return this;
+}else{
+if(this[_30.g]){
+return this[_30.g]();
+}else{
+return this[_2c];
+}
+}
+},_attrPairNames:{},_getAttrNames:function(_31){
+var apn=this._attrPairNames;
+if(apn[_31]){
+return apn[_31];
+}
+var uc=_31.charAt(0).toUpperCase()+_31.substr(1);
+return apn[_31]={n:_31+"Node",s:"_set"+uc+"Attr",g:"_get"+uc+"Attr"};
+},toString:function(){
+return "[Widget "+this.declaredClass+", "+(this.id||"NO ID")+"]";
+},getDescendants:function(){
+if(this.containerNode){
+var _34=dojo.query("[widgetId]",this.containerNode);
+return _34.map(dijit.byNode);
+}else{
+return [];
+}
+},getChildren:function(){
+if(this.containerNode){
+return dijit.findWidgets(this.containerNode);
+}else{
+return [];
+}
+},nodesWithKeyClick:["input","button"],connect:function(obj,_36,_37){
+var d=dojo;
+var dc=dojo.connect;
+var _3a=[];
+if(_36=="ondijitclick"){
+if(!this.nodesWithKeyClick[obj.nodeName]){
+var m=d.hitch(this,_37);
+_3a.push(dc(obj,"onkeydown",this,function(e){
+if(!d.isFF&&e.keyCode==d.keys.ENTER&&!e.ctrlKey&&!e.shiftKey&&!e.altKey&&!e.metaKey){
+return m(e);
+}else{
+if(e.keyCode==d.keys.SPACE){
+d.stopEvent(e);
+}
+}
+}),dc(obj,"onkeyup",this,function(e){
+if(e.keyCode==d.keys.SPACE&&!e.ctrlKey&&!e.shiftKey&&!e.altKey&&!e.metaKey){
+return m(e);
+}
+}));
+if(d.isFF){
+_3a.push(dc(obj,"onkeypress",this,function(e){
+if(e.keyCode==d.keys.ENTER&&!e.ctrlKey&&!e.shiftKey&&!e.altKey&&!e.metaKey){
+return m(e);
+}
+}));
+}
+}
+_36="onclick";
+}
+_3a.push(dc(obj,_36,this,_37));
+this._connects.push(_3a);
+return _3a;
+},disconnect:function(_3f){
+for(var i=0;i<this._connects.length;i++){
+if(this._connects[i]==_3f){
+dojo.forEach(_3f,dojo.disconnect);
+this._connects.splice(i,1);
+return;
+}
+}
+},isLeftToRight:function(){
+return dojo._isBodyLtr();
+},isFocusable:function(){
+return this.focus&&(dojo.style(this.domNode,"display")!="none");
+},placeAt:function(_41,_42){
+if(_41["declaredClass"]&&_41["addChild"]){
+_41.addChild(this,_42);
+}else{
+dojo.place(this.domNode,_41,_42);
+}
+return this;
+}});
+})();
+}
diff --git a/dijit/_base.js b/dijit/_base.js
new file mode 100644
index 0000000..9c173e0
--- /dev/null
+++ b/dijit/_base.js
@@ -0,0 +1,20 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._base"]){
+dojo._hasResource["dijit._base"]=true;
+dojo.provide("dijit._base");
+dojo.require("dijit._base.focus");
+dojo.require("dijit._base.manager");
+dojo.require("dijit._base.place");
+dojo.require("dijit._base.popup");
+dojo.require("dijit._base.scroll");
+dojo.require("dijit._base.sniff");
+dojo.require("dijit._base.typematic");
+dojo.require("dijit._base.wai");
+dojo.require("dijit._base.window");
+}
diff --git a/dijit/_base/focus.js b/dijit/_base/focus.js
new file mode 100644
index 0000000..3df8226
--- /dev/null
+++ b/dijit/_base/focus.js
@@ -0,0 +1,238 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._base.focus"]){
+dojo._hasResource["dijit._base.focus"]=true;
+dojo.provide("dijit._base.focus");
+dojo.mixin(dijit,{_curFocus:null,_prevFocus:null,isCollapsed:function(){
+var _1=dojo.doc;
+if(_1.selection){
+var s=_1.selection;
+if(s.type=="Text"){
+return !s.createRange().htmlText.length;
+}else{
+return !s.createRange().length;
+}
+}else{
+var _3=dojo.global;
+var _4=_3.getSelection();
+if(dojo.isString(_4)){
+return !_4;
+}else{
+return !_4||_4.isCollapsed||!_4.toString();
+}
+}
+},getBookmark:function(){
+var _5,_6=dojo.doc.selection;
+if(_6){
+var _7=_6.createRange();
+if(_6.type.toUpperCase()=="CONTROL"){
+if(_7.length){
+_5=[];
+var i=0,_9=_7.length;
+while(i<_9){
+_5.push(_7.item(i++));
+}
+}else{
+_5=null;
+}
+}else{
+_5=_7.getBookmark();
+}
+}else{
+if(window.getSelection){
+_6=dojo.global.getSelection();
+if(_6){
+_7=_6.getRangeAt(0);
+_5=_7.cloneRange();
+}
+}else{
+console.warn("No idea how to store the current selection for this browser!");
+}
+}
+return _5;
+},moveToBookmark:function(_a){
+var _b=dojo.doc;
+if(_b.selection){
+var _c;
+if(dojo.isArray(_a)){
+_c=_b.body.createControlRange();
+dojo.forEach(_a,function(n){
+_c.addElement(n);
+});
+}else{
+_c=_b.selection.createRange();
+_c.moveToBookmark(_a);
+}
+_c.select();
+}else{
+var _e=dojo.global.getSelection&&dojo.global.getSelection();
+if(_e&&_e.removeAllRanges){
+_e.removeAllRanges();
+_e.addRange(_a);
+}else{
+console.warn("No idea how to restore selection for this browser!");
+}
+}
+},getFocus:function(_f,_10){
+return {node:_f&&dojo.isDescendant(dijit._curFocus,_f.domNode)?dijit._prevFocus:dijit._curFocus,bookmark:!dojo.withGlobal(_10||dojo.global,dijit.isCollapsed)?dojo.withGlobal(_10||dojo.global,dijit.getBookmark):null,openedForWindow:_10};
+},focus:function(_11){
+if(!_11){
+return;
+}
+var _12="node" in _11?_11.node:_11,_13=_11.bookmark,_14=_11.openedForWindow;
+if(_12){
+var _15=(_12.tagName.toLowerCase()=="iframe")?_12.contentWindow:_12;
+if(_15&&_15.focus){
+try{
+_15.focus();
+}
+catch(e){
+}
+}
+dijit._onFocusNode(_12);
+}
+if(_13&&dojo.withGlobal(_14||dojo.global,dijit.isCollapsed)){
+if(_14){
+_14.focus();
+}
+try{
+dojo.withGlobal(_14||dojo.global,dijit.moveToBookmark,null,[_13]);
+}
+catch(e){
+}
+}
+},_activeStack:[],registerIframe:function(_16){
+dijit.registerWin(_16.contentWindow,_16);
+},registerWin:function(_17,_18){
+dojo.connect(_17.document,"onmousedown",function(evt){
+dijit._justMouseDowned=true;
+setTimeout(function(){
+dijit._justMouseDowned=false;
+},0);
+dijit._onTouchNode(_18||evt.target||evt.srcElement);
+});
+var doc=_17.document;
+if(doc){
+if(dojo.isIE){
+doc.attachEvent("onactivate",function(evt){
+if(evt.srcElement.tagName.toLowerCase()!="#document"){
+dijit._onFocusNode(_18||evt.srcElement);
+}
+});
+doc.attachEvent("ondeactivate",function(evt){
+dijit._onBlurNode(_18||evt.srcElement);
+});
+}else{
+doc.addEventListener("focus",function(evt){
+dijit._onFocusNode(_18||evt.target);
+},true);
+doc.addEventListener("blur",function(evt){
+dijit._onBlurNode(_18||evt.target);
+},true);
+}
+}
+doc=null;
+},_onBlurNode:function(_1f){
+dijit._prevFocus=dijit._curFocus;
+dijit._curFocus=null;
+if(dijit._justMouseDowned){
+return;
+}
+if(dijit._clearActiveWidgetsTimer){
+clearTimeout(dijit._clearActiveWidgetsTimer);
+}
+dijit._clearActiveWidgetsTimer=setTimeout(function(){
+delete dijit._clearActiveWidgetsTimer;
+dijit._setStack([]);
+dijit._prevFocus=null;
+},100);
+},_onTouchNode:function(_20){
+if(dijit._clearActiveWidgetsTimer){
+clearTimeout(dijit._clearActiveWidgetsTimer);
+delete dijit._clearActiveWidgetsTimer;
+}
+var _21=[];
+try{
+while(_20){
+if(_20.dijitPopupParent){
+_20=dijit.byId(_20.dijitPopupParent).domNode;
+}else{
+if(_20.tagName&&_20.tagName.toLowerCase()=="body"){
+if(_20===dojo.body()){
+break;
+}
+_20=dijit.getDocumentWindow(_20.ownerDocument).frameElement;
+}else{
+var id=_20.getAttribute&&_20.getAttribute("widgetId");
+if(id){
+_21.unshift(id);
+}
+_20=_20.parentNode;
+}
+}
+}
+}
+catch(e){
+}
+dijit._setStack(_21);
+},_onFocusNode:function(_23){
+if(!_23){
+return;
+}
+if(_23.nodeType==9){
+return;
+}
+dijit._onTouchNode(_23);
+if(_23==dijit._curFocus){
+return;
+}
+if(dijit._curFocus){
+dijit._prevFocus=dijit._curFocus;
+}
+dijit._curFocus=_23;
+dojo.publish("focusNode",[_23]);
+},_setStack:function(_24){
+var _25=dijit._activeStack;
+dijit._activeStack=_24;
+for(var _26=0;_26<Math.min(_25.length,_24.length);_26++){
+if(_25[_26]!=_24[_26]){
+break;
+}
+}
+for(var i=_25.length-1;i>=_26;i--){
+var _28=dijit.byId(_25[i]);
+if(_28){
+_28._focused=false;
+_28._hasBeenBlurred=true;
+if(_28._onBlur){
+_28._onBlur();
+}
+if(_28._setStateClass){
+_28._setStateClass();
+}
+dojo.publish("widgetBlur",[_28]);
+}
+}
+for(i=_26;i<_24.length;i++){
+_28=dijit.byId(_24[i]);
+if(_28){
+_28._focused=true;
+if(_28._onFocus){
+_28._onFocus();
+}
+if(_28._setStateClass){
+_28._setStateClass();
+}
+dojo.publish("widgetFocus",[_28]);
+}
+}
+}});
+dojo.addOnLoad(function(){
+dijit.registerWin(window);
+});
+}
diff --git a/dijit/_base/manager.js b/dijit/_base/manager.js
new file mode 100644
index 0000000..d6b3dbb
--- /dev/null
+++ b/dijit/_base/manager.js
@@ -0,0 +1,160 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._base.manager"]){
+dojo._hasResource["dijit._base.manager"]=true;
+dojo.provide("dijit._base.manager");
+dojo.declare("dijit.WidgetSet",null,{constructor:function(){
+this._hash={};
+},add:function(_1){
+if(this._hash[_1.id]){
+throw new Error("Tried to register widget with id=="+_1.id+" but that id is already registered");
+}
+this._hash[_1.id]=_1;
+},remove:function(id){
+delete this._hash[id];
+},forEach:function(_3){
+for(var id in this._hash){
+_3(this._hash[id]);
+}
+},filter:function(_5){
+var _6=new dijit.WidgetSet();
+this.forEach(function(_7){
+if(_5(_7)){
+_6.add(_7);
+}
+});
+return _6;
+},byId:function(id){
+return this._hash[id];
+},byClass:function(_9){
+return this.filter(function(_a){
+return _a.declaredClass==_9;
+});
+}});
+dijit.registry=new dijit.WidgetSet();
+dijit._widgetTypeCtr={};
+dijit.getUniqueId=function(_b){
+var id;
+do{
+id=_b+"_"+(_b in dijit._widgetTypeCtr?++dijit._widgetTypeCtr[_b]:dijit._widgetTypeCtr[_b]=0);
+}while(dijit.byId(id));
+return id;
+};
+dijit.findWidgets=function(_d){
+var _e=[];
+function _f(_10){
+var _11=dojo.isIE?_10.children:_10.childNodes,i=0,_13;
+while(_13=_11[i++]){
+if(_13.nodeType!=1){
+continue;
+}
+var _14=_13.getAttribute("widgetId");
+if(_14){
+var _15=dijit.byId(_14);
+_e.push(_15);
+}else{
+_f(_13);
+}
+}
+};
+_f(_d);
+return _e;
+};
+if(dojo.isIE){
+dojo.addOnWindowUnload(function(){
+dojo.forEach(dijit.findWidgets(dojo.body()),function(_16){
+if(_16.destroyRecursive){
+_16.destroyRecursive();
+}else{
+if(_16.destroy){
+_16.destroy();
+}
+}
+});
+});
+}
+dijit.byId=function(id){
+return (dojo.isString(id))?dijit.registry.byId(id):id;
+};
+dijit.byNode=function(_18){
+return dijit.registry.byId(_18.getAttribute("widgetId"));
+};
+dijit.getEnclosingWidget=function(_19){
+while(_19){
+if(_19.getAttribute&&_19.getAttribute("widgetId")){
+return dijit.registry.byId(_19.getAttribute("widgetId"));
+}
+_19=_19.parentNode;
+}
+return null;
+};
+dijit._tabElements={area:true,button:true,input:true,object:true,select:true,textarea:true};
+dijit._isElementShown=function(_1a){
+var _1b=dojo.style(_1a);
+return (_1b.visibility!="hidden")&&(_1b.visibility!="collapsed")&&(_1b.display!="none")&&(dojo.attr(_1a,"type")!="hidden");
+};
+dijit.isTabNavigable=function(_1c){
+if(dojo.hasAttr(_1c,"disabled")){
+return false;
+}
+var _1d=dojo.hasAttr(_1c,"tabindex");
+var _1e=dojo.attr(_1c,"tabindex");
+if(_1d&&_1e>=0){
+return true;
+}
+var _1f=_1c.nodeName.toLowerCase();
+if(((_1f=="a"&&dojo.hasAttr(_1c,"href"))||dijit._tabElements[_1f])&&(!_1d||_1e>=0)){
+return true;
+}
+return false;
+};
+dijit._getTabNavigable=function(_20){
+var _21,_22,_23,_24,_25,_26;
+var _27=function(_28){
+dojo.query("> *",_28).forEach(function(_29){
+var _2a=dijit._isElementShown(_29);
+if(_2a&&dijit.isTabNavigable(_29)){
+var _2b=dojo.attr(_29,"tabindex");
+if(!dojo.hasAttr(_29,"tabindex")||_2b==0){
+if(!_21){
+_21=_29;
+}
+_22=_29;
+}else{
+if(_2b>0){
+if(!_23||_2b<_24){
+_24=_2b;
+_23=_29;
+}
+if(!_25||_2b>=_26){
+_26=_2b;
+_25=_29;
+}
+}
+}
+}
+if(_2a&&_29.nodeName.toUpperCase()!="SELECT"){
+_27(_29);
+}
+});
+};
+if(dijit._isElementShown(_20)){
+_27(_20);
+}
+return {first:_21,last:_22,lowest:_23,highest:_25};
+};
+dijit.getFirstInTabbingOrder=function(_2c){
+var _2d=dijit._getTabNavigable(dojo.byId(_2c));
+return _2d.lowest?_2d.lowest:_2d.first;
+};
+dijit.getLastInTabbingOrder=function(_2e){
+var _2f=dijit._getTabNavigable(dojo.byId(_2e));
+return _2f.last?_2f.last:_2f.highest;
+};
+dijit.defaultDuration=dojo.config["defaultDuration"]||200;
+}
diff --git a/dijit/_base/place.js b/dijit/_base/place.js
new file mode 100644
index 0000000..4bef81b
--- /dev/null
+++ b/dijit/_base/place.js
@@ -0,0 +1,91 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._base.place"]){
+dojo._hasResource["dijit._base.place"]=true;
+dojo.provide("dijit._base.place");
+dojo.require("dojo.AdapterRegistry");
+dijit.getViewport=function(){
+var _1=(dojo.doc.compatMode=="BackCompat")?dojo.body():dojo.doc.documentElement;
+var _2=dojo._docScroll();
+return {w:_1.clientWidth,h:_1.clientHeight,l:_2.x,t:_2.y};
+};
+dijit.placeOnScreen=function(_3,_4,_5,_6){
+var _7=dojo.map(_5,function(_8){
+var c={corner:_8,pos:{x:_4.x,y:_4.y}};
+if(_6){
+c.pos.x+=_8.charAt(1)=="L"?_6.x:-_6.x;
+c.pos.y+=_8.charAt(0)=="T"?_6.y:-_6.y;
+}
+return c;
+});
+return dijit._place(_3,_7);
+};
+dijit._place=function(_a,_b,_c){
+var _d=dijit.getViewport();
+if(!_a.parentNode||String(_a.parentNode.tagName).toLowerCase()!="body"){
+dojo.body().appendChild(_a);
+}
+var _e=null;
+dojo.some(_b,function(_f){
+var _10=_f.corner;
+var pos=_f.pos;
+if(_c){
+_c(_a,_f.aroundCorner,_10);
+}
+var _12=_a.style;
+var _13=_12.display;
+var _14=_12.visibility;
+_12.visibility="hidden";
+_12.display="";
+var mb=dojo.marginBox(_a);
+_12.display=_13;
+_12.visibility=_14;
+var _16=(_10.charAt(1)=="L"?pos.x:Math.max(_d.l,pos.x-mb.w)),_17=(_10.charAt(0)=="T"?pos.y:Math.max(_d.t,pos.y-mb.h)),_18=(_10.charAt(1)=="L"?Math.min(_d.l+_d.w,_16+mb.w):pos.x),_19=(_10.charAt(0)=="T"?Math.min(_d.t+_d.h,_17+mb.h):pos.y),_1a=_18-_16,_1b=_19-_17,_1c=(mb.w-_1a)+(mb.h-_1b);
+if(_e==null||_1c<_e.overflow){
+_e={corner:_10,aroundCorner:_f.aroundCorner,x:_16,y:_17,w:_1a,h:_1b,overflow:_1c};
+}
+return !_1c;
+});
+_a.style.left=_e.x+"px";
+_a.style.top=_e.y+"px";
+if(_e.overflow&&_c){
+_c(_a,_e.aroundCorner,_e.corner);
+}
+return _e;
+};
+dijit.placeOnScreenAroundNode=function(_1d,_1e,_1f,_20){
+_1e=dojo.byId(_1e);
+var _21=_1e.style.display;
+_1e.style.display="";
+var _22=_1e.offsetWidth;
+var _23=_1e.offsetHeight;
+var _24=dojo.coords(_1e,true);
+_1e.style.display=_21;
+return dijit._placeOnScreenAroundRect(_1d,_24.x,_24.y,_22,_23,_1f,_20);
+};
+dijit.placeOnScreenAroundRectangle=function(_25,_26,_27,_28){
+return dijit._placeOnScreenAroundRect(_25,_26.x,_26.y,_26.width,_26.height,_27,_28);
+};
+dijit._placeOnScreenAroundRect=function(_29,x,y,_2c,_2d,_2e,_2f){
+var _30=[];
+for(var _31 in _2e){
+_30.push({aroundCorner:_31,corner:_2e[_31],pos:{x:x+(_31.charAt(1)=="L"?0:_2c),y:y+(_31.charAt(0)=="T"?0:_2d)}});
+}
+return dijit._place(_29,_30,_2f);
+};
+dijit.placementRegistry=new dojo.AdapterRegistry();
+dijit.placementRegistry.register("node",function(n,x){
+return typeof x=="object"&&typeof x.offsetWidth!="undefined"&&typeof x.offsetHeight!="undefined";
+},dijit.placeOnScreenAroundNode);
+dijit.placementRegistry.register("rect",function(n,x){
+return typeof x=="object"&&"x" in x&&"y" in x&&"width" in x&&"height" in x;
+},dijit.placeOnScreenAroundRectangle);
+dijit.placeOnScreenAroundElement=function(_36,_37,_38,_39){
+return dijit.placementRegistry.match.apply(dijit.placementRegistry,arguments);
+};
+}
diff --git a/dijit/_base/popup.js b/dijit/_base/popup.js
new file mode 100644
index 0000000..6e7937e
--- /dev/null
+++ b/dijit/_base/popup.js
@@ -0,0 +1,150 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._base.popup"]){
+dojo._hasResource["dijit._base.popup"]=true;
+dojo.provide("dijit._base.popup");
+dojo.require("dijit._base.focus");
+dojo.require("dijit._base.place");
+dojo.require("dijit._base.window");
+dijit.popup=new function(){
+var _1=[],_2=1000,_3=1;
+this.prepare=function(_4){
+var s=_4.style;
+s.visibility="hidden";
+s.position="absolute";
+s.top="-9999px";
+if(s.display=="none"){
+s.display="";
+}
+dojo.body().appendChild(_4);
+};
+this.open=function(_6){
+var _7=_6.popup,_8=_6.orient||{"BL":"TL","TL":"BL"},_9=_6.around,id=(_6.around&&_6.around.id)?(_6.around.id+"_dropdown"):("popup_"+_3++);
+var _b=dojo.create("div",{id:id,"class":"dijitPopup",style:{zIndex:_2+_1.length,visibility:"hidden"}},dojo.body());
+dijit.setWaiRole(_b,"presentation");
+_b.style.left=_b.style.top="0px";
+if(_6.parent){
+_b.dijitPopupParent=_6.parent.id;
+}
+var s=_7.domNode.style;
+s.display="";
+s.visibility="";
+s.position="";
+s.top="0px";
+_b.appendChild(_7.domNode);
+var _d=new dijit.BackgroundIframe(_b);
+var _e=_9?dijit.placeOnScreenAroundElement(_b,_9,_8,_7.orient?dojo.hitch(_7,"orient"):null):dijit.placeOnScreen(_b,_6,_8=="R"?["TR","BR","TL","BL"]:["TL","BL","TR","BR"],_6.padding);
+_b.style.visibility="visible";
+var _f=[];
+var _10=function(){
+for(var pi=_1.length-1;pi>0&&_1[pi].parent===_1[pi-1].widget;pi--){
+}
+return _1[pi];
+};
+_f.push(dojo.connect(_b,"onkeypress",this,function(evt){
+if(evt.charOrCode==dojo.keys.ESCAPE&&_6.onCancel){
+dojo.stopEvent(evt);
+_6.onCancel();
+}else{
+if(evt.charOrCode===dojo.keys.TAB){
+dojo.stopEvent(evt);
+var _13=_10();
+if(_13&&_13.onCancel){
+_13.onCancel();
+}
+}
+}
+}));
+if(_7.onCancel){
+_f.push(dojo.connect(_7,"onCancel",null,_6.onCancel));
+}
+_f.push(dojo.connect(_7,_7.onExecute?"onExecute":"onChange",null,function(){
+var _14=_10();
+if(_14&&_14.onExecute){
+_14.onExecute();
+}
+}));
+_1.push({wrapper:_b,iframe:_d,widget:_7,parent:_6.parent,onExecute:_6.onExecute,onCancel:_6.onCancel,onClose:_6.onClose,handlers:_f});
+if(_7.onOpen){
+_7.onOpen(_e);
+}
+return _e;
+};
+this.close=function(_15){
+while(dojo.some(_1,function(_16){
+return _16.widget==_15;
+})){
+var top=_1.pop(),_18=top.wrapper,_19=top.iframe,_1a=top.widget,_1b=top.onClose;
+if(_1a.onClose){
+_1a.onClose();
+}
+dojo.forEach(top.handlers,dojo.disconnect);
+if(!_1a||!_1a.domNode){
+return;
+}
+this.prepare(_1a.domNode);
+_19.destroy();
+dojo.destroy(_18);
+if(_1b){
+_1b();
+}
+}
+};
+}();
+dijit._frames=new function(){
+var _1c=[];
+this.pop=function(){
+var _1d;
+if(_1c.length){
+_1d=_1c.pop();
+_1d.style.display="";
+}else{
+if(dojo.isIE){
+var _1e=dojo.config["dojoBlankHtmlUrl"]||(dojo.moduleUrl("dojo","resources/blank.html")+"")||"javascript:\"\"";
+var _1f="<iframe src='"+_1e+"'"+" style='position: absolute; left: 0px; top: 0px;"+"z-index: -1; filter:Alpha(Opacity=\"0\");'>";
+_1d=dojo.doc.createElement(_1f);
+}else{
+_1d=dojo.create("iframe");
+_1d.src="javascript:\"\"";
+_1d.className="dijitBackgroundIframe";
+}
+_1d.tabIndex=-1;
+dojo.body().appendChild(_1d);
+}
+return _1d;
+};
+this.push=function(_20){
+_20.style.display="none";
+if(dojo.isIE){
+_20.style.removeExpression("width");
+_20.style.removeExpression("height");
+}
+_1c.push(_20);
+};
+}();
+dijit.BackgroundIframe=function(_21){
+if(!_21.id){
+throw new Error("no id");
+}
+if(dojo.isIE<7||(dojo.isFF<3&&dojo.hasClass(dojo.body(),"dijit_a11y"))){
+var _22=dijit._frames.pop();
+_21.appendChild(_22);
+if(dojo.isIE){
+_22.style.setExpression("width",dojo._scopeName+".doc.getElementById('"+_21.id+"').offsetWidth");
+_22.style.setExpression("height",dojo._scopeName+".doc.getElementById('"+_21.id+"').offsetHeight");
+}
+this.iframe=_22;
+}
+};
+dojo.extend(dijit.BackgroundIframe,{destroy:function(){
+if(this.iframe){
+dijit._frames.push(this.iframe);
+delete this.iframe;
+}
+}});
+}
diff --git a/dijit/_base/scroll.js b/dijit/_base/scroll.js
new file mode 100644
index 0000000..4c564c3
--- /dev/null
+++ b/dijit/_base/scroll.js
@@ -0,0 +1,169 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._base.scroll"]){
+dojo._hasResource["dijit._base.scroll"]=true;
+dojo.provide("dijit._base.scroll");
+dijit.scrollIntoView=function(_1){
+try{
+_1=dojo.byId(_1);
+var _2=dojo.doc;
+var _3=dojo.body();
+var _4=_3.parentNode;
+if((!(dojo.isFF>=3||dojo.isIE||dojo.isWebKit)||_1==_3||_1==_4)&&(typeof _1.scrollIntoView=="function")){
+_1.scrollIntoView(false);
+return;
+}
+var _5=dojo._isBodyLtr();
+var _6=dojo.isIE>=8&&!_7;
+var _8=!_5&&!_6;
+var _9=_3;
+var _7=_2.compatMode=="BackCompat";
+if(_7){
+_4._offsetWidth=_4._clientWidth=_3._offsetWidth=_3.clientWidth;
+_4._offsetHeight=_4._clientHeight=_3._offsetHeight=_3.clientHeight;
+}else{
+if(dojo.isWebKit){
+_3._offsetWidth=_3._clientWidth=_4.clientWidth;
+_3._offsetHeight=_3._clientHeight=_4.clientHeight;
+}else{
+_9=_4;
+}
+_4._offsetHeight=_4.clientHeight;
+_4._offsetWidth=_4.clientWidth;
+}
+function _a(_b){
+var ie=dojo.isIE;
+return ((ie<=6||(ie>=7&&_7))?false:(dojo.style(_b,"position").toLowerCase()=="fixed"));
+};
+function _d(_e){
+var _f=_e.parentNode;
+var _10=_e.offsetParent;
+if(_10==null||_a(_e)){
+_10=_4;
+_f=(_e==_3)?_4:null;
+}
+_e._offsetParent=_10;
+_e._parent=_f;
+var bp=dojo._getBorderExtents(_e);
+_e._borderStart={H:(_6&&!_5)?(bp.w-bp.l):bp.l,V:bp.t};
+_e._borderSize={H:bp.w,V:bp.h};
+_e._scrolledAmount={H:_e.scrollLeft,V:_e.scrollTop};
+_e._offsetSize={H:_e._offsetWidth||_e.offsetWidth,V:_e._offsetHeight||_e.offsetHeight};
+_e._offsetStart={H:(_6&&!_5)?_10.clientWidth-_e.offsetLeft-_e._offsetSize.H:_e.offsetLeft,V:_e.offsetTop};
+_e._clientSize={H:_e._clientWidth||_e.clientWidth,V:_e._clientHeight||_e.clientHeight};
+if(_e!=_3&&_e!=_4&&_e!=_1){
+for(var dir in _e._offsetSize){
+var _13=_e._offsetSize[dir]-_e._clientSize[dir]-_e._borderSize[dir];
+var _14=_e._clientSize[dir]>0&&_13>0;
+if(_14){
+_e._offsetSize[dir]-=_13;
+if(dojo.isIE&&_8&&dir=="H"){
+_e._offsetStart[dir]+=_13;
+}
+}
+}
+}
+};
+var _15=_1;
+while(_15!=null){
+if(_a(_15)){
+_1.scrollIntoView(false);
+return;
+}
+_d(_15);
+_15=_15._parent;
+}
+if(dojo.isIE&&_1._parent){
+var _16=_1._offsetParent;
+_1._offsetStart.H+=_16._borderStart.H;
+_1._offsetStart.V+=_16._borderStart.V;
+}
+if(dojo.isIE>=7&&_9==_4&&_8&&_3._offsetStart&&_3._offsetStart.H==0){
+var _17=_4.scrollWidth-_4._offsetSize.H;
+if(_17>0){
+_3._offsetStart.H=-_17;
+}
+}
+if(dojo.isIE<=6&&!_7){
+_4._offsetSize.H+=_4._borderSize.H;
+_4._offsetSize.V+=_4._borderSize.V;
+}
+if(_8&&_3._offsetStart&&_9==_4&&_4._scrolledAmount){
+var ofs=_3._offsetStart.H;
+if(ofs<0){
+_4._scrolledAmount.H+=ofs;
+_3._offsetStart.H=0;
+}
+}
+_15=_1;
+while(_15){
+var _19=_15._parent;
+if(!_19){
+break;
+}
+if(_19.tagName=="TD"){
+var _1a=_19._parent._parent._parent;
+if(_19!=_15._offsetParent&&_19._offsetParent!=_15._offsetParent){
+_19=_1a;
+}
+}
+var _1b=_15._offsetParent==_19;
+for(var dir in _15._offsetStart){
+var _1d=dir=="H"?"V":"H";
+if(_8&&dir=="H"&&(_19!=_4)&&(_19!=_3)&&(dojo.isIE||dojo.isWebKit)&&_19._clientSize.H>0&&_19.scrollWidth>_19._clientSize.H){
+var _1e=_19.scrollWidth-_19._clientSize.H;
+if(_1e>0){
+_19._scrolledAmount.H-=_1e;
+}
+}
+if(_19._offsetParent.tagName=="TABLE"){
+if(dojo.isIE){
+_19._offsetStart[dir]-=_19._offsetParent._borderStart[dir];
+_19._borderStart[dir]=_19._borderSize[dir]=0;
+}else{
+_19._offsetStart[dir]+=_19._offsetParent._borderStart[dir];
+}
+}
+if(dojo.isIE){
+_19._offsetStart[dir]+=_19._offsetParent._borderStart[dir];
+}
+var _1f=_15._offsetStart[dir]-_19._scrolledAmount[dir]-(_1b?0:_19._offsetStart[dir])-_19._borderStart[dir];
+var _20=_1f+_15._offsetSize[dir]-_19._offsetSize[dir]+_19._borderSize[dir];
+var _21=(dir=="H")?"scrollLeft":"scrollTop";
+var _22=dir=="H"&&_8;
+var _23=_22?-_20:_1f;
+var _24=_22?-_1f:_20;
+var _25=(_23*_24<=0)?0:Math[(_23<0)?"max":"min"](_23,_24);
+if(_25!=0){
+var _26=_19[_21];
+_19[_21]+=(_22)?-_25:_25;
+var _27=_19[_21]-_26;
+}
+if(_1b){
+_15._offsetStart[dir]+=_19._offsetStart[dir];
+}
+_15._offsetStart[dir]-=_19[_21];
+}
+_15._parent=_19._parent;
+_15._offsetParent=_19._offsetParent;
+}
+_19=_1;
+var _28;
+while(_19&&_19.removeAttribute){
+_28=_19.parentNode;
+_19.removeAttribute("_offsetParent");
+_19.removeAttribute("_parent");
+_19=_28;
+}
+}
+catch(error){
+console.error("scrollIntoView: "+error);
+_1.scrollIntoView(false);
+}
+};
+}
diff --git a/dijit/_base/sniff.js b/dijit/_base/sniff.js
new file mode 100644
index 0000000..1119d1f
--- /dev/null
+++ b/dijit/_base/sniff.js
@@ -0,0 +1,34 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._base.sniff"]){
+dojo._hasResource["dijit._base.sniff"]=true;
+dojo.provide("dijit._base.sniff");
+(function(){
+var d=dojo,_2=d.doc.documentElement,ie=d.isIE,_4=d.isOpera,_5=Math.floor,ff=d.isFF,_7=d.boxModel.replace(/-/,""),_8={dj_ie:ie,dj_ie6:_5(ie)==6,dj_ie7:_5(ie)==7,dj_iequirks:ie&&d.isQuirks,dj_opera:_4,dj_opera8:_5(_4)==8,dj_opera9:_5(_4)==9,dj_khtml:d.isKhtml,dj_webkit:d.isWebKit,dj_safari:d.isSafari,dj_gecko:d.isMozilla,dj_ff2:_5(ff)==2,dj_ff3:_5(ff)==3};
+_8["dj_"+_7]=true;
+for(var p in _8){
+if(_8[p]){
+if(_2.className){
+_2.className+=" "+p;
+}else{
+_2.className=p;
+}
+}
+}
+dojo._loaders.unshift(function(){
+if(!dojo._isBodyLtr()){
+_2.className+=" dijitRtl";
+for(var p in _8){
+if(_8[p]){
+_2.className+=" "+p+"-rtl";
+}
+}
+}
+});
+})();
+}
diff --git a/dijit/_base/typematic.js b/dijit/_base/typematic.js
new file mode 100644
index 0000000..f688bdf
--- /dev/null
+++ b/dijit/_base/typematic.js
@@ -0,0 +1,85 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._base.typematic"]){
+dojo._hasResource["dijit._base.typematic"]=true;
+dojo.provide("dijit._base.typematic");
+dijit.typematic={_fireEventAndReload:function(){
+this._timer=null;
+this._callback(++this._count,this._node,this._evt);
+this._currentTimeout=(this._currentTimeout<0)?this._initialDelay:((this._subsequentDelay>1)?this._subsequentDelay:Math.round(this._currentTimeout*this._subsequentDelay));
+this._timer=setTimeout(dojo.hitch(this,"_fireEventAndReload"),this._currentTimeout);
+},trigger:function(_1,_2,_3,_4,_5,_6,_7){
+if(_5!=this._obj){
+this.stop();
+this._initialDelay=_7||500;
+this._subsequentDelay=_6||0.9;
+this._obj=_5;
+this._evt=_1;
+this._node=_3;
+this._currentTimeout=-1;
+this._count=-1;
+this._callback=dojo.hitch(_2,_4);
+this._fireEventAndReload();
+}
+},stop:function(){
+if(this._timer){
+clearTimeout(this._timer);
+this._timer=null;
+}
+if(this._obj){
+this._callback(-1,this._node,this._evt);
+this._obj=null;
+}
+},addKeyListener:function(_8,_9,_a,_b,_c,_d){
+if(_9.keyCode){
+_9.charOrCode=_9.keyCode;
+dojo.deprecated("keyCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.","","2.0");
+}else{
+if(_9.charCode){
+_9.charOrCode=String.fromCharCode(_9.charCode);
+dojo.deprecated("charCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.","","2.0");
+}
+}
+return [dojo.connect(_8,"onkeypress",this,function(_e){
+if(_e.charOrCode==_9.charOrCode&&(_9.ctrlKey===undefined||_9.ctrlKey==_e.ctrlKey)&&(_9.altKey===undefined||_9.altKey==_e.ctrlKey)&&(_9.shiftKey===undefined||_9.shiftKey==_e.ctrlKey)){
+dojo.stopEvent(_e);
+dijit.typematic.trigger(_9,_a,_8,_b,_9,_c,_d);
+}else{
+if(dijit.typematic._obj==_9){
+dijit.typematic.stop();
+}
+}
+}),dojo.connect(_8,"onkeyup",this,function(_f){
+if(dijit.typematic._obj==_9){
+dijit.typematic.stop();
+}
+})];
+},addMouseListener:function(_10,_11,_12,_13,_14){
+var dc=dojo.connect;
+return [dc(_10,"mousedown",this,function(evt){
+dojo.stopEvent(evt);
+dijit.typematic.trigger(evt,_11,_10,_12,_10,_13,_14);
+}),dc(_10,"mouseup",this,function(evt){
+dojo.stopEvent(evt);
+dijit.typematic.stop();
+}),dc(_10,"mouseout",this,function(evt){
+dojo.stopEvent(evt);
+dijit.typematic.stop();
+}),dc(_10,"mousemove",this,function(evt){
+dojo.stopEvent(evt);
+}),dc(_10,"dblclick",this,function(evt){
+dojo.stopEvent(evt);
+if(dojo.isIE){
+dijit.typematic.trigger(evt,_11,_10,_12,_10,_13,_14);
+setTimeout(dojo.hitch(this,dijit.typematic.stop),50);
+}
+})];
+},addListener:function(_1b,_1c,_1d,_1e,_1f,_20,_21){
+return this.addKeyListener(_1c,_1d,_1e,_1f,_20,_21).concat(this.addMouseListener(_1b,_1e,_1f,_20,_21));
+}};
+}
diff --git a/dijit/_base/wai.js b/dijit/_base/wai.js
new file mode 100644
index 0000000..7f37a68
--- /dev/null
+++ b/dijit/_base/wai.js
@@ -0,0 +1,79 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._base.wai"]){
+dojo._hasResource["dijit._base.wai"]=true;
+dojo.provide("dijit._base.wai");
+dijit.wai={onload:function(){
+var _1=dojo.create("div",{id:"a11yTestNode",style:{cssText:"border: 1px solid;"+"border-color:red green;"+"position: absolute;"+"height: 5px;"+"top: -999px;"+"background-image: url(\""+(dojo.config.blankGif||dojo.moduleUrl("dojo","resources/blank.gif"))+"\");"}},dojo.body());
+var cs=dojo.getComputedStyle(_1);
+if(cs){
+var _3=cs.backgroundImage;
+var _4=(cs.borderTopColor==cs.borderRightColor)||(_3!=null&&(_3=="none"||_3=="url(invalid-url:)"));
+dojo[_4?"addClass":"removeClass"](dojo.body(),"dijit_a11y");
+if(dojo.isIE){
+_1.outerHTML="";
+}else{
+dojo.body().removeChild(_1);
+}
+}
+}};
+if(dojo.isIE||dojo.isMoz){
+dojo._loaders.unshift(dijit.wai.onload);
+}
+dojo.mixin(dijit,{_XhtmlRoles:/banner|contentinfo|definition|main|navigation|search|note|secondary|seealso/,hasWaiRole:function(_5,_6){
+var _7=this.getWaiRole(_5);
+return _6?(_7.indexOf(_6)>-1):(_7.length>0);
+},getWaiRole:function(_8){
+return dojo.trim((dojo.attr(_8,"role")||"").replace(this._XhtmlRoles,"").replace("wairole:",""));
+},setWaiRole:function(_9,_a){
+var _b=dojo.attr(_9,"role")||"";
+if(dojo.isFF<3||!this._XhtmlRoles.test(_b)){
+dojo.attr(_9,"role",dojo.isFF<3?"wairole:"+_a:_a);
+}else{
+if((" "+_b+" ").indexOf(" "+_a+" ")<0){
+var _c=dojo.trim(_b.replace(this._XhtmlRoles,""));
+var _d=dojo.trim(_b.replace(_c,""));
+dojo.attr(_9,"role",_d+(_d?" ":"")+_a);
+}
+}
+},removeWaiRole:function(_e,_f){
+var _10=dojo.attr(_e,"role");
+if(!_10){
+return;
+}
+if(_f){
+var _11=dojo.isFF<3?"wairole:"+_f:_f;
+var t=dojo.trim((" "+_10+" ").replace(" "+_11+" "," "));
+dojo.attr(_e,"role",t);
+}else{
+_e.removeAttribute("role");
+}
+},hasWaiState:function(_13,_14){
+if(dojo.isFF<3){
+return _13.hasAttributeNS("http://www.w3.org/2005/07/aaa",_14);
+}
+return _13.hasAttribute?_13.hasAttribute("aria-"+_14):!!_13.getAttribute("aria-"+_14);
+},getWaiState:function(_15,_16){
+if(dojo.isFF<3){
+return _15.getAttributeNS("http://www.w3.org/2005/07/aaa",_16);
+}
+return _15.getAttribute("aria-"+_16)||"";
+},setWaiState:function(_17,_18,_19){
+if(dojo.isFF<3){
+_17.setAttributeNS("http://www.w3.org/2005/07/aaa","aaa:"+_18,_19);
+}else{
+_17.setAttribute("aria-"+_18,_19);
+}
+},removeWaiState:function(_1a,_1b){
+if(dojo.isFF<3){
+_1a.removeAttributeNS("http://www.w3.org/2005/07/aaa",_1b);
+}else{
+_1a.removeAttribute("aria-"+_1b);
+}
+}});
+}
diff --git a/dijit/_base/window.js b/dijit/_base/window.js
new file mode 100644
index 0000000..65c50cc
--- /dev/null
+++ b/dijit/_base/window.js
@@ -0,0 +1,20 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._base.window"]){
+dojo._hasResource["dijit._base.window"]=true;
+dojo.provide("dijit._base.window");
+dijit.getDocumentWindow=function(_1){
+if(dojo.isIE&&window!==document.parentWindow&&!_1._parentWindow){
+_1.parentWindow.execScript("document._parentWindow = window;","Javascript");
+var _2=_1._parentWindow;
+_1._parentWindow=null;
+return _2;
+}
+return _1._parentWindow||_1.parentWindow||_1.defaultView;
+};
+}
diff --git a/dijit/_editor/RichText.js b/dijit/_editor/RichText.js
new file mode 100644
index 0000000..50e8d81
--- /dev/null
+++ b/dijit/_editor/RichText.js
@@ -0,0 +1,1013 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._editor.RichText"]){
+dojo._hasResource["dijit._editor.RichText"]=true;
+dojo.provide("dijit._editor.RichText");
+dojo.require("dijit._Widget");
+dojo.require("dijit._editor.selection");
+dojo.require("dijit._editor.range");
+dojo.require("dijit._editor.html");
+dojo.require("dojo.i18n");
+dojo.requireLocalization("dijit.form","Textarea",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+if(!dojo.config["useXDomain"]||dojo.config["allowXdRichTextSave"]){
+if(dojo._postLoad){
+(function(){
+var _1=dojo.doc.createElement("textarea");
+_1.id=dijit._scopeName+"._editor.RichText.savedContent";
+dojo.style(_1,{display:"none",position:"absolute",top:"-100px",height:"3px",width:"3px"});
+dojo.body().appendChild(_1);
+})();
+}else{
+try{
+dojo.doc.write("<textarea id=\""+dijit._scopeName+"._editor.RichText.savedContent\" "+"style=\"display:none;position:absolute;top:-100px;left:-100px;height:3px;width:3px;overflow:hidden;\"></textarea>");
+}
+catch(e){
+}
+}
+}
+dojo.declare("dijit._editor.RichText",dijit._Widget,{constructor:function(_2){
+this.contentPreFilters=[];
+this.contentPostFilters=[];
+this.contentDomPreFilters=[];
+this.contentDomPostFilters=[];
+this.editingAreaStyleSheets=[];
+this._keyHandlers={};
+this.contentPreFilters.push(dojo.hitch(this,"_preFixUrlAttributes"));
+if(dojo.isMoz){
+this.contentPreFilters.push(this._fixContentForMoz);
+this.contentPostFilters.push(this._removeMozBogus);
+}
+if(dojo.isSafari){
+this.contentPostFilters.push(this._removeSafariBogus);
+}
+this.onLoadDeferred=new dojo.Deferred();
+},inheritWidth:false,focusOnLoad:false,name:"",styleSheets:"",_content:"",height:"300px",minHeight:"1em",isClosed:true,isLoaded:false,_SEPARATOR:"@@**%%__RICHTEXTBOUNDRY__%%**@@",onLoadDeferred:null,isTabIndent:false,disableSpellCheck:false,postCreate:function(){
+if("textarea"==this.domNode.tagName.toLowerCase()){
+console.warn("RichText should not be used with the TEXTAREA tag.  See dijit._editor.RichText docs.");
+}
+dojo.publish(dijit._scopeName+"._editor.RichText::init",[this]);
+this.open();
+this.setupDefaultShortcuts();
+},setupDefaultShortcuts:function(){
+var _3=dojo.hitch(this,function(_4,_5){
+return function(){
+return !this.execCommand(_4,_5);
+};
+});
+var _6={b:_3("bold"),i:_3("italic"),u:_3("underline"),a:_3("selectall"),s:function(){
+this.save(true);
+},m:function(){
+this.isTabIndent=!this.isTabIndent;
+},"1":_3("formatblock","h1"),"2":_3("formatblock","h2"),"3":_3("formatblock","h3"),"4":_3("formatblock","h4"),"\\":_3("insertunorderedlist")};
+if(!dojo.isIE){
+_6.Z=_3("redo");
+}
+for(var _7 in _6){
+this.addKeyHandler(_7,true,false,_6[_7]);
+}
+},events:["onKeyPress","onKeyDown","onKeyUp","onClick"],captureEvents:[],_editorCommandsLocalized:false,_localizeEditorCommands:function(){
+if(this._editorCommandsLocalized){
+return;
+}
+this._editorCommandsLocalized=true;
+var _8=["div","p","pre","h1","h2","h3","h4","h5","h6","ol","ul","address"];
+var _9="",_a,i=0;
+while((_a=_8[i++])){
+if(_a.charAt(1)!="l"){
+_9+="<"+_a+"><span>content</span></"+_a+"><br/>";
+}else{
+_9+="<"+_a+"><li>content</li></"+_a+"><br/>";
+}
+}
+var _c=dojo.doc.createElement("div");
+dojo.style(_c,{position:"absolute",top:"-2000px"});
+dojo.doc.body.appendChild(_c);
+_c.innerHTML=_9;
+var _d=_c.firstChild;
+while(_d){
+dijit._editor.selection.selectElement(_d.firstChild);
+dojo.withGlobal(this.window,"selectElement",dijit._editor.selection,[_d.firstChild]);
+var _e=_d.tagName.toLowerCase();
+this._local2NativeFormatNames[_e]=document.queryCommandValue("formatblock");
+this._native2LocalFormatNames[this._local2NativeFormatNames[_e]]=_e;
+_d=_d.nextSibling.nextSibling;
+}
+dojo.body().removeChild(_c);
+},open:function(_f){
+if(!this.onLoadDeferred||this.onLoadDeferred.fired>=0){
+this.onLoadDeferred=new dojo.Deferred();
+}
+if(!this.isClosed){
+this.close();
+}
+dojo.publish(dijit._scopeName+"._editor.RichText::open",[this]);
+this._content="";
+if(arguments.length==1&&_f.nodeName){
+this.domNode=_f;
+}
+var dn=this.domNode;
+var _11;
+if(dn.nodeName&&dn.nodeName.toLowerCase()=="textarea"){
+var ta=(this.textarea=dn);
+this.name=ta.name;
+_11=this._preFilterContent(ta.value);
+dn=this.domNode=dojo.doc.createElement("div");
+dn.setAttribute("widgetId",this.id);
+ta.removeAttribute("widgetId");
+dn.cssText=ta.cssText;
+dn.className+=" "+ta.className;
+dojo.place(dn,ta,"before");
+var _13=dojo.hitch(this,function(){
+dojo.style(ta,{display:"block",position:"absolute",top:"-1000px"});
+if(dojo.isIE){
+var s=ta.style;
+this.__overflow=s.overflow;
+s.overflow="hidden";
+}
+});
+if(dojo.isIE){
+setTimeout(_13,10);
+}else{
+_13();
+}
+if(ta.form){
+dojo.connect(ta.form,"onsubmit",this,function(){
+ta.value=this.getValue();
+});
+}
+}else{
+_11=this._preFilterContent(dijit._editor.getChildrenHtml(dn));
+dn.innerHTML="";
+}
+var _15=dojo.contentBox(dn);
+this._oldHeight=_15.h;
+this._oldWidth=_15.w;
+this.savedContent=_11;
+if(dn.nodeName&&dn.nodeName=="LI"){
+dn.innerHTML=" <br>";
+}
+this.editingArea=dn.ownerDocument.createElement("div");
+dn.appendChild(this.editingArea);
+if(this.name!=""&&(!dojo.config["useXDomain"]||dojo.config["allowXdRichTextSave"])){
+var _16=dojo.byId(dijit._scopeName+"._editor.RichText.savedContent");
+if(_16.value!=""){
+var _17=_16.value.split(this._SEPARATOR),i=0,dat;
+while((dat=_17[i++])){
+var _1a=dat.split(":");
+if(_1a[0]==this.name){
+_11=_1a[1];
+_17.splice(i,1);
+break;
+}
+}
+}
+this.connect(window,"onbeforeunload","_saveContent");
+}
+this.isClosed=false;
+if(dojo.isIE||dojo.isWebKit||dojo.isOpera){
+var ifr=(this.editorObject=this.iframe=dojo.doc.createElement("iframe"));
+ifr.id=this.id+"_iframe";
+this._iframeSrc=this._getIframeDocTxt(_11);
+ifr.style.border="none";
+ifr.style.width="100%";
+if(this._layoutMode){
+ifr.style.height="100%";
+}else{
+if(dojo.isIE>=7){
+if(this.height){
+ifr.style.height=this.height;
+}
+if(this.minHeight){
+ifr.style.minHeight=this.minHeight;
+}
+}else{
+ifr.style.height=this.height?this.height:this.minHeight;
+}
+}
+ifr.frameBorder=0;
+ifr._loadFunc=dojo.hitch(this,function(win){
+this.window=win;
+this.document=this.window.document;
+if(dojo.isIE){
+this._localizeEditorCommands();
+}
+this.onLoad();
+this.savedContent=this.getValue(true);
+});
+var s="javascript:parent."+dijit._scopeName+".byId(\""+this.id+"\")._iframeSrc";
+ifr.setAttribute("src",s);
+this.editingArea.appendChild(ifr);
+if(dojo.isWebKit){
+setTimeout(function(){
+ifr.setAttribute("src",s);
+},0);
+}
+}else{
+this._drawIframe(_11);
+this.savedContent=this.getValue(true);
+}
+if(dn.nodeName=="LI"){
+dn.lastChild.style.marginTop="-1.2em";
+}
+if(this.domNode.nodeName=="LI"){
+this.domNode.lastChild.style.marginTop="-1.2em";
+}
+dojo.addClass(this.domNode,"RichTextEditable");
+},_local2NativeFormatNames:{},_native2LocalFormatNames:{},_localizedIframeTitles:null,_getIframeDocTxt:function(_1e){
+var _cs=dojo.getComputedStyle(this.domNode);
+if(dojo.isIE||(!this.height&&!dojo.isMoz)){
+_1e="<div>"+_1e+"</div>";
+}
+var _20=[_cs.fontWeight,_cs.fontSize,_cs.fontFamily].join(" ");
+var _21=_cs.lineHeight;
+if(_21.indexOf("px")>=0){
+_21=parseFloat(_21)/parseFloat(_cs.fontSize);
+}else{
+if(_21.indexOf("em")>=0){
+_21=parseFloat(_21);
+}else{
+_21="1.0";
+}
+}
+var _22="";
+this.style.replace(/(^|;)(line-|font-?)[^;]+/g,function(_23){
+_22+=_23.replace(/^;/g,"")+";";
+});
+var d=dojo.doc;
+var _25=d.charset||d.characterSet||d.defaultCharset||"UTF-8";
+return [this.isLeftToRight()?"<html><head>":"<html dir='rtl'><head>",(dojo.isMoz?"<title>"+this._localizedIframeTitles.iframeEditTitle+"</title>":""),"<meta http-equiv='Content-Type' content='text/html; charset="+_25+"'>","<style>","body,html {","\tbackground:transparent;","\tpadding: 1em 0 0 0;","\tmargin: -1em 0 0 0;","}","body{","\ttop:0px; left:0px; right:0px;","\tfont:",_20,";",((this.height||dojo.isOpera)?"":"position: fixed;"),"\tmin-height:",this.minHeight,";","\tline-height:",_2 [...]
+},_drawIframe:function(_26){
+if(!this.iframe){
+var ifr=(this.iframe=dojo.doc.createElement("iframe"));
+ifr.id=this.id+"_iframe";
+var _28=ifr.style;
+_28.border="none";
+_28.lineHeight="0";
+_28.verticalAlign="bottom";
+this.editorObject=this.iframe;
+this._localizedIframeTitles=dojo.i18n.getLocalization("dijit.form","Textarea");
+var _29=dojo.query("label[for=\""+this.id+"\"]");
+if(_29.length){
+this._localizedIframeTitles.iframeEditTitle=_29[0].innerHTML+" "+this._localizedIframeTitles.iframeEditTitle;
+}
+ifr._loadFunc=function(win){
+};
+}
+this.iframe.style.width=this.inheritWidth?this._oldWidth:"100%";
+if(this._layoutMode){
+this.iframe.style.height="100%";
+}else{
+if(this.height){
+this.iframe.style.height=this.height;
+}else{
+this.iframe.height=this._oldHeight;
+}
+}
+var _2b;
+if(this.textarea){
+_2b=this.srcNodeRef;
+}else{
+_2b=dojo.doc.createElement("div");
+_2b.style.display="none";
+_2b.innerHTML=_26;
+this.editingArea.appendChild(_2b);
+}
+this.editingArea.appendChild(this.iframe);
+var _2c=dojo.hitch(this,function(){
+if(!this.editNode){
+if(!this.document){
+try{
+if(this.iframe.contentWindow){
+this.window=this.iframe.contentWindow;
+this.document=this.iframe.contentWindow.document;
+}else{
+if(this.iframe.contentDocument){
+this.window=this.iframe.contentDocument.window;
+this.document=this.iframe.contentDocument;
+}
+}
+}
+catch(e){
+}
+if(!this.document){
+setTimeout(_2c,50);
+return;
+}
+var _2d=this.document;
+_2d.open();
+if(dojo.isAIR){
+_2d.body.innerHTML=_26;
+}else{
+_2d.write(this._getIframeDocTxt(_26));
+}
+_2d.close();
+dojo.destroy(_2b);
+}
+if(!this.document.body){
+setTimeout(_2c,50);
+return;
+}
+this.onLoad();
+}else{
+dojo.destroy(_2b);
+this.editNode.innerHTML=_26;
+this.onDisplayChanged();
+}
+this._preDomFilterContent(this.editNode);
+});
+_2c();
+},_applyEditingAreaStyleSheets:function(){
+var _2e=[];
+if(this.styleSheets){
+_2e=this.styleSheets.split(";");
+this.styleSheets="";
+}
+_2e=_2e.concat(this.editingAreaStyleSheets);
+this.editingAreaStyleSheets=[];
+var _2f="",i=0,url;
+while((url=_2e[i++])){
+var _32=(new dojo._Url(dojo.global.location,url)).toString();
+this.editingAreaStyleSheets.push(_32);
+_2f+="<link rel=\"stylesheet\" type=\"text/css\" href=\""+_32+"\"/>";
+}
+return _2f;
+},addStyleSheet:function(uri){
+var url=uri.toString();
+if(url.charAt(0)=="."||(url.charAt(0)!="/"&&!uri.host)){
+url=(new dojo._Url(dojo.global.location,url)).toString();
+}
+if(dojo.indexOf(this.editingAreaStyleSheets,url)>-1){
+return;
+}
+this.editingAreaStyleSheets.push(url);
+if(this.document.createStyleSheet){
+this.document.createStyleSheet(url);
+}else{
+var _35=this.document.getElementsByTagName("head")[0];
+var _36=this.document.createElement("link");
+_36.rel="stylesheet";
+_36.type="text/css";
+_36.href=url;
+_35.appendChild(_36);
+}
+},removeStyleSheet:function(uri){
+var url=uri.toString();
+if(url.charAt(0)=="."||(url.charAt(0)!="/"&&!uri.host)){
+url=(new dojo._Url(dojo.global.location,url)).toString();
+}
+var _39=dojo.indexOf(this.editingAreaStyleSheets,url);
+if(_39==-1){
+return;
+}
+delete this.editingAreaStyleSheets[_39];
+dojo.withGlobal(this.window,"query",dojo,["link:[href=\""+url+"\"]"]).orphan();
+},disabled:false,_mozSettingProps:{"styleWithCSS":false},_setDisabledAttr:function(_3a){
+this.disabled=_3a;
+if(!this.isLoaded){
+return;
+}
+_3a=!!_3a;
+if(dojo.isIE||dojo.isWebKit||dojo.isOpera){
+var _3b=dojo.isIE&&(this.isLoaded||!this.focusOnLoad);
+if(_3b){
+this.editNode.unselectable="on";
+}
+this.editNode.contentEditable=!_3a;
+if(_3b){
+var _3c=this;
+setTimeout(function(){
+_3c.editNode.unselectable="off";
+},0);
+}
+}else{
+try{
+this.document.designMode=(_3a?"off":"on");
+}
+catch(e){
+return;
+}
+if(!_3a&&this._mozSettingProps){
+var ps=this._mozSettingProps;
+for(var n in ps){
+if(ps.hasOwnProperty(n)){
+try{
+this.document.execCommand(n,false,ps[n]);
+}
+catch(e){
+}
+}
+}
+}
+}
+this._disabledOK=true;
+},_isResized:function(){
+return false;
+},onLoad:function(e){
+if(!this.window.__registeredWindow){
+this.window.__registeredWindow=true;
+dijit.registerIframe(this.iframe);
+}
+if(!dojo.isIE&&(this.height||dojo.isMoz)){
+this.editNode=this.document.body;
+}else{
+this.editNode=this.document.body.firstChild;
+var _40=this;
+if(dojo.isIE){
+var _41=(this.tabStop=dojo.doc.createElement("<div tabIndex=-1>"));
+this.editingArea.appendChild(_41);
+this.iframe.onfocus=function(){
+_40.editNode.setActive();
+};
+}
+}
+this.focusNode=this.editNode;
+this._preDomFilterContent(this.editNode);
+var _42=this.events.concat(this.captureEvents);
+var ap=this.iframe?this.document:this.editNode;
+dojo.forEach(_42,function(_44){
+this.connect(ap,_44.toLowerCase(),_44);
+},this);
+if(dojo.isIE){
+this.connect(this.document,"onmousedown","_onIEMouseDown");
+this.editNode.style.zoom=1;
+}
+if(dojo.isWebKit){
+this._webkitListener=this.connect(this.document,"onmouseup","onDisplayChanged");
+}
+this.isLoaded=true;
+this.attr("disabled",this.disabled);
+if(this.onLoadDeferred){
+this.onLoadDeferred.callback(true);
+}
+this.onDisplayChanged(e);
+if(this.focusOnLoad){
+dojo.addOnLoad(dojo.hitch(this,function(){
+setTimeout(dojo.hitch(this,"focus"),this.updateInterval);
+}));
+}
+},onKeyDown:function(e){
+if(e.keyCode===dojo.keys.TAB&&this.isTabIndent){
+dojo.stopEvent(e);
+if(this.queryCommandEnabled((e.shiftKey?"outdent":"indent"))){
+this.execCommand((e.shiftKey?"outdent":"indent"));
+}
+}
+if(dojo.isIE){
+if(e.keyCode==dojo.keys.TAB&&!this.isTabIndent){
+if(e.shiftKey&&!e.ctrlKey&&!e.altKey){
+this.iframe.focus();
+}else{
+if(!e.shiftKey&&!e.ctrlKey&&!e.altKey){
+this.tabStop.focus();
+}
+}
+}else{
+if(e.keyCode===dojo.keys.BACKSPACE&&this.document.selection.type==="Control"){
+dojo.stopEvent(e);
+this.execCommand("delete");
+}else{
+if((65<=e.keyCode&&e.keyCode<=90)||(e.keyCode>=37&&e.keyCode<=40)){
+e.charCode=e.keyCode;
+this.onKeyPress(e);
+}
+}
+}
+}else{
+if(dojo.isMoz&&!this.isTabIndent){
+if(e.keyCode==dojo.keys.TAB&&!e.shiftKey&&!e.ctrlKey&&!e.altKey&&this.iframe){
+var _46=dojo.isFF<3?this.iframe.contentDocument:this.iframe;
+_46.title=this._localizedIframeTitles.iframeFocusTitle;
+this.iframe.focus();
+dojo.stopEvent(e);
+}else{
+if(e.keyCode==dojo.keys.TAB&&e.shiftKey){
+if(this.toolbar){
+this.toolbar.focus();
+}
+dojo.stopEvent(e);
+}
+}
+}
+}
+return true;
+},onKeyUp:function(e){
+return;
+},setDisabled:function(_48){
+dojo.deprecated("dijit.Editor::setDisabled is deprecated","use dijit.Editor::attr(\"disabled\",boolean) instead",2);
+this.attr("disabled",_48);
+},_setValueAttr:function(_49){
+this.setValue(_49);
+},_getDisableSpellCheckAttr:function(){
+return !dojo.attr(this.document.body,"spellcheck");
+},_setDisableSpellCheckAttr:function(_4a){
+if(this.document){
+dojo.attr(this.document.body,"spellcheck",!_4a);
+}else{
+this.onLoadDeferred.addCallback(dojo.hitch(this,function(){
+dojo.attr(this.document.body,"spellcheck",!_4a);
+}));
+}
+},onKeyPress:function(e){
+var c=(e.keyChar&&e.keyChar.toLowerCase())||e.keyCode;
+var _4d=this._keyHandlers[c];
+var _4e=arguments;
+if(_4d&&!e.altKey){
+dojo.forEach(_4d,function(h){
+if((!!h.shift==!!e.shiftKey)&&(!!h.ctrl==!!e.ctrlKey)){
+if(!h.handler.apply(this,_4e)){
+e.preventDefault();
+}
+}
+},this);
+}
+if(!this._onKeyHitch){
+this._onKeyHitch=dojo.hitch(this,"onKeyPressed");
+}
+setTimeout(this._onKeyHitch,1);
+return true;
+},addKeyHandler:function(key,_51,_52,_53){
+if(!dojo.isArray(this._keyHandlers[key])){
+this._keyHandlers[key]=[];
+}
+this._keyHandlers[key].push({shift:_52||false,ctrl:_51||false,handler:_53});
+},onKeyPressed:function(){
+this.onDisplayChanged();
+},onClick:function(e){
+this.onDisplayChanged(e);
+},_onIEMouseDown:function(e){
+if(!this._focused&&!this.disabled){
+this.focus();
+}
+},_onBlur:function(e){
+this.inherited(arguments);
+var _c=this.getValue(true);
+if(_c!=this.savedContent){
+this.onChange(_c);
+this.savedContent=_c;
+}
+if(dojo.isMoz&&this.iframe){
+var _58=dojo.isFF<3?this.iframe.contentDocument:this.iframe;
+_58.title=this._localizedIframeTitles.iframeEditTitle;
+}
+},_onFocus:function(e){
+if(!this.disabled){
+if(!this._disabledOK){
+this.attr("disabled",false);
+}
+this.inherited(arguments);
+}
+},blur:function(){
+if(!dojo.isIE&&this.window.document.documentElement&&this.window.document.documentElement.focus){
+this.window.document.documentElement.focus();
+}else{
+if(dojo.doc.body.focus){
+dojo.doc.body.focus();
+}
+}
+},focus:function(){
+if(!dojo.isIE){
+dijit.focus(this.iframe);
+}else{
+if(this.editNode&&this.editNode.focus){
+this.iframe.fireEvent("onfocus",document.createEventObject());
+}
+}
+},updateInterval:200,_updateTimer:null,onDisplayChanged:function(e){
+if(this._updateTimer){
+clearTimeout(this._updateTimer);
+}
+if(!this._updateHandler){
+this._updateHandler=dojo.hitch(this,"onNormalizedDisplayChanged");
+}
+this._updateTimer=setTimeout(this._updateHandler,this.updateInterval);
+},onNormalizedDisplayChanged:function(){
+delete this._updateTimer;
+},onChange:function(_5b){
+},_normalizeCommand:function(cmd){
+var _5d=cmd.toLowerCase();
+if(_5d=="formatblock"){
+if(dojo.isSafari){
+_5d="heading";
+}
+}else{
+if(_5d=="hilitecolor"&&!dojo.isMoz){
+_5d="backcolor";
+}
+}
+return _5d;
+},_qcaCache:{},queryCommandAvailable:function(_5e){
+var ca=this._qcaCache[_5e];
+if(ca!=undefined){
+return ca;
+}
+return (this._qcaCache[_5e]=this._queryCommandAvailable(_5e));
+},_queryCommandAvailable:function(_60){
+var ie=1;
+var _62=1<<1;
+var _63=1<<2;
+var _64=1<<3;
+var _65=1<<4;
+var _66=dojo.isWebKit;
+function _67(_68){
+return {ie:Boolean(_68&ie),mozilla:Boolean(_68&_62),webkit:Boolean(_68&_63),webkit420:Boolean(_68&_65),opera:Boolean(_68&_64)};
+};
+var _69=null;
+switch(_60.toLowerCase()){
+case "bold":
+case "italic":
+case "underline":
+case "subscript":
+case "superscript":
+case "fontname":
+case "fontsize":
+case "forecolor":
+case "hilitecolor":
+case "justifycenter":
+case "justifyfull":
+case "justifyleft":
+case "justifyright":
+case "delete":
+case "selectall":
+case "toggledir":
+_69=_67(_62|ie|_63|_64);
+break;
+case "createlink":
+case "unlink":
+case "removeformat":
+case "inserthorizontalrule":
+case "insertimage":
+case "insertorderedlist":
+case "insertunorderedlist":
+case "indent":
+case "outdent":
+case "formatblock":
+case "inserthtml":
+case "undo":
+case "redo":
+case "strikethrough":
+case "tabindent":
+_69=_67(_62|ie|_64|_65);
+break;
+case "blockdirltr":
+case "blockdirrtl":
+case "dirltr":
+case "dirrtl":
+case "inlinedirltr":
+case "inlinedirrtl":
+_69=_67(ie);
+break;
+case "cut":
+case "copy":
+case "paste":
+_69=_67(ie|_62|_65);
+break;
+case "inserttable":
+_69=_67(_62|ie);
+break;
+case "insertcell":
+case "insertcol":
+case "insertrow":
+case "deletecells":
+case "deletecols":
+case "deleterows":
+case "mergecells":
+case "splitcell":
+_69=_67(ie|_62);
+break;
+default:
+return false;
+}
+return (dojo.isIE&&_69.ie)||(dojo.isMoz&&_69.mozilla)||(dojo.isWebKit&&_69.webkit)||(dojo.isWebKit>420&&_69.webkit420)||(dojo.isOpera&&_69.opera);
+},execCommand:function(_6a,_6b){
+var _6c;
+this.focus();
+_6a=this._normalizeCommand(_6a);
+if(_6b!=undefined){
+if(_6a=="heading"){
+throw new Error("unimplemented");
+}else{
+if((_6a=="formatblock")&&dojo.isIE){
+_6b="<"+_6b+">";
+}
+}
+}
+if(_6a=="inserthtml"){
+_6b=this._preFilterContent(_6b);
+_6c=true;
+if(dojo.isIE){
+var _6d=this.document.selection.createRange();
+if(this.document.selection.type.toUpperCase()=="CONTROL"){
+var n=_6d.item(0);
+while(_6d.length){
+_6d.remove(_6d.item(0));
+}
+n.outerHTML=_6b;
+}else{
+_6d.pasteHTML(_6b);
+}
+_6d.select();
+}else{
+if(dojo.isMoz&&!_6b.length){
+this._sCall("remove");
+}else{
+_6c=this.document.execCommand(_6a,false,_6b);
+}
+}
+}else{
+if((_6a=="unlink")&&(this.queryCommandEnabled("unlink"))&&(dojo.isMoz||dojo.isWebKit)){
+var a=this._sCall("getAncestorElement",["a"]);
+this._sCall("selectElement",[a]);
+_6c=this.document.execCommand("unlink",false,null);
+}else{
+if((_6a=="hilitecolor")&&(dojo.isMoz)){
+this.document.execCommand("styleWithCSS",false,true);
+_6c=this.document.execCommand(_6a,false,_6b);
+this.document.execCommand("styleWithCSS",false,false);
+}else{
+if((dojo.isIE)&&((_6a=="backcolor")||(_6a=="forecolor"))){
+_6b=arguments.length>1?_6b:null;
+_6c=this.document.execCommand(_6a,false,_6b);
+}else{
+_6b=arguments.length>1?_6b:null;
+if(_6b||_6a!="createlink"){
+_6c=this.document.execCommand(_6a,false,_6b);
+}
+}
+}
+}
+}
+this.onDisplayChanged();
+return _6c;
+},queryCommandEnabled:function(_70){
+if(this.disabled||!this._disabledOK){
+return false;
+}
+_70=this._normalizeCommand(_70);
+if(dojo.isMoz||dojo.isWebKit){
+if(_70=="unlink"){
+this._sCall("hasAncestorElement",["a"]);
+}else{
+if(_70=="inserttable"){
+return true;
+}
+}
+}
+if(dojo.isWebKit){
+if(_70=="copy"){
+_70="cut";
+}else{
+if(_70=="paste"){
+return true;
+}
+}
+}
+var _71=dojo.isIE?this.document.selection.createRange():this.document;
+return _71.queryCommandEnabled(_70);
+},queryCommandState:function(_72){
+if(this.disabled||!this._disabledOK){
+return false;
+}
+_72=this._normalizeCommand(_72);
+return this.document.queryCommandState(_72);
+},queryCommandValue:function(_73){
+if(this.disabled||!this._disabledOK){
+return false;
+}
+var r;
+_73=this._normalizeCommand(_73);
+if(dojo.isIE&&_73=="formatblock"){
+r=this._native2LocalFormatNames[this.document.queryCommandValue(_73)];
+}else{
+r=this.document.queryCommandValue(_73);
+}
+return r;
+},_sCall:function(_75,_76){
+return dojo.withGlobal(this.window,_75,dijit._editor.selection,_76);
+},placeCursorAtStart:function(){
+this.focus();
+var _77=false;
+if(dojo.isMoz){
+var _78=this.editNode.firstChild;
+while(_78){
+if(_78.nodeType==3){
+if(_78.nodeValue.replace(/^\s+|\s+$/g,"").length>0){
+_77=true;
+this._sCall("selectElement",[_78]);
+break;
+}
+}else{
+if(_78.nodeType==1){
+_77=true;
+this._sCall("selectElementChildren",[_78]);
+break;
+}
+}
+_78=_78.nextSibling;
+}
+}else{
+_77=true;
+this._sCall("selectElementChildren",[this.editNode]);
+}
+if(_77){
+this._sCall("collapse",[true]);
+}
+},placeCursorAtEnd:function(){
+this.focus();
+var _79=false;
+if(dojo.isMoz){
+var _7a=this.editNode.lastChild;
+while(_7a){
+if(_7a.nodeType==3){
+if(_7a.nodeValue.replace(/^\s+|\s+$/g,"").length>0){
+_79=true;
+this._sCall("selectElement",[_7a]);
+break;
+}
+}else{
+if(_7a.nodeType==1){
+_79=true;
+if(_7a.lastChild){
+this._sCall("selectElement",[_7a.lastChild]);
+}else{
+this._sCall("selectElement",[_7a]);
+}
+break;
+}
+}
+_7a=_7a.previousSibling;
+}
+}else{
+_79=true;
+this._sCall("selectElementChildren",[this.editNode]);
+}
+if(_79){
+this._sCall("collapse",[false]);
+}
+},getValue:function(_7b){
+if(this.textarea){
+if(this.isClosed||!this.isLoaded){
+return this.textarea.value;
+}
+}
+return this._postFilterContent(null,_7b);
+},_getValueAttr:function(){
+return this.getValue();
+},setValue:function(_7c){
+if(!this.isLoaded){
+this.onLoadDeferred.addCallback(dojo.hitch(this,function(){
+this.setValue(_7c);
+}));
+return;
+}
+if(this.textarea&&(this.isClosed||!this.isLoaded)){
+this.textarea.value=_7c;
+}else{
+_7c=this._preFilterContent(_7c);
+var _7d=this.isClosed?this.domNode:this.editNode;
+_7d.innerHTML=_7c;
+this._preDomFilterContent(_7d);
+}
+this.onDisplayChanged();
+},replaceValue:function(_7e){
+if(this.isClosed){
+this.setValue(_7e);
+}else{
+if(this.window&&this.window.getSelection&&!dojo.isMoz){
+this.setValue(_7e);
+}else{
+if(this.window&&this.window.getSelection){
+_7e=this._preFilterContent(_7e);
+this.execCommand("selectall");
+if(dojo.isMoz&&!_7e){
+_7e=" ";
+}
+this.execCommand("inserthtml",_7e);
+this._preDomFilterContent(this.editNode);
+}else{
+if(this.document&&this.document.selection){
+this.setValue(_7e);
+}
+}
+}
+}
+},_preFilterContent:function(_7f){
+var ec=_7f;
+dojo.forEach(this.contentPreFilters,function(ef){
+if(ef){
+ec=ef(ec);
+}
+});
+return ec;
+},_preDomFilterContent:function(dom){
+dom=dom||this.editNode;
+dojo.forEach(this.contentDomPreFilters,function(ef){
+if(ef&&dojo.isFunction(ef)){
+ef(dom);
+}
+},this);
+},_postFilterContent:function(dom,_85){
+var ec;
+if(!dojo.isString(dom)){
+dom=dom||this.editNode;
+if(this.contentDomPostFilters.length){
+if(_85){
+dom=dojo.clone(dom);
+}
+dojo.forEach(this.contentDomPostFilters,function(ef){
+dom=ef(dom);
+});
+}
+ec=dijit._editor.getChildrenHtml(dom);
+}else{
+ec=dom;
+}
+if(!dojo.trim(ec.replace(/^\xA0\xA0*/,"").replace(/\xA0\xA0*$/,"")).length){
+ec="";
+}
+dojo.forEach(this.contentPostFilters,function(ef){
+ec=ef(ec);
+});
+return ec;
+},_saveContent:function(e){
+var _8a=dojo.byId(dijit._scopeName+"._editor.RichText.savedContent");
+_8a.value+=this._SEPARATOR+this.name+":"+this.getValue();
+},escapeXml:function(str,_8c){
+str=str.replace(/&/gm,"&").replace(/</gm,"<").replace(/>/gm,">").replace(/"/gm,""");
+if(!_8c){
+str=str.replace(/'/gm,"'");
+}
+return str;
+},getNodeHtml:function(_8d){
+dojo.deprecated("dijit.Editor::getNodeHtml is deprecated","use dijit._editor.getNodeHtml instead",2);
+return dijit._editor.getNodeHtml(_8d);
+},getNodeChildrenHtml:function(dom){
+dojo.deprecated("dijit.Editor::getNodeChildrenHtml is deprecated","use dijit._editor.getChildrenHtml instead",2);
+return dijit._editor.getChildrenHtml(dom);
+},close:function(_8f,_90){
+if(this.isClosed){
+return false;
+}
+if(!arguments.length){
+_8f=true;
+}
+this._content=this.getValue();
+var _91=(this.savedContent!=this._content);
+if(this.interval){
+clearInterval(this.interval);
+}
+if(this._webkitListener){
+this.disconnect(this._webkitListener);
+delete this._webkitListener;
+}
+if(dojo.isIE){
+this.iframe.onfocus=null;
+}
+this.iframe._loadFunc=null;
+if(this.textarea){
+var s=this.textarea.style;
+s.position="";
+s.left=s.top="";
+if(dojo.isIE){
+s.overflow=this.__overflow;
+this.__overflow=null;
+}
+this.textarea.value=_8f?this._content:this.savedContent;
+dojo.destroy(this.domNode);
+this.domNode=this.textarea;
+}else{
+this.domNode.innerHTML=_8f?this._content:this.savedContent;
+}
+dojo.removeClass(this.domNode,"RichTextEditable");
+this.isClosed=true;
+this.isLoaded=false;
+delete this.editNode;
+if(this.window&&this.window._frameElement){
+this.window._frameElement=null;
+}
+this.window=null;
+this.document=null;
+this.editingArea=null;
+this.editorObject=null;
+return _91;
+},destroyRendering:function(){
+},destroy:function(){
+this.destroyRendering();
+if(!this.isClosed){
+this.close(false);
+}
+this.inherited(arguments);
+},_removeMozBogus:function(_93){
+return _93.replace(/\stype="_moz"/gi,"").replace(/\s_moz_dirty=""/gi,"");
+},_removeSafariBogus:function(_94){
+return _94.replace(/\sclass="webkit-block-placeholder"/gi,"");
+},_fixContentForMoz:function(_95){
+return _95.replace(/<(\/)?strong([ \>])/gi,"<$1b$2").replace(/<(\/)?em([ \>])/gi,"<$1i$2");
+},_preFixUrlAttributes:function(_96){
+return _96.replace(/(?:(<a(?=\s).*?\shref=)("|')(.*?)\2)|(?:(<a\s.*?href=)([^"'][^ >]+))/gi,"$1$4$2$3$5$2 _djrealurl=$2$3$5$2").replace(/(?:(<img(?=\s).*?\ssrc=)("|')(.*?)\2)|(?:(<img\s.*?src=)([^"'][^ >]+))/gi,"$1$4$2$3$5$2 _djrealurl=$2$3$5$2");
+}});
+}
diff --git a/dijit/_editor/_Plugin.js b/dijit/_editor/_Plugin.js
new file mode 100644
index 0000000..98d0788
--- /dev/null
+++ b/dijit/_editor/_Plugin.js
@@ -0,0 +1,78 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._editor._Plugin"]){
+dojo._hasResource["dijit._editor._Plugin"]=true;
+dojo.provide("dijit._editor._Plugin");
+dojo.require("dijit._Widget");
+dojo.require("dijit.Editor");
+dojo.require("dijit.form.Button");
+dojo.declare("dijit._editor._Plugin",null,{constructor:function(_1,_2){
+if(_1){
+dojo.mixin(this,_1);
+}
+this._connects=[];
+},editor:null,iconClassPrefix:"dijitEditorIcon",button:null,queryCommand:null,command:"",commandArg:null,useDefaultCommand:true,buttonClass:dijit.form.Button,getLabel:function(_3){
+return this.editor.commands[_3];
+},_initButton:function(_4){
+if(this.command.length){
+var _5=this.getLabel(this.command);
+var _6=this.iconClassPrefix+" "+this.iconClassPrefix+this.command.charAt(0).toUpperCase()+this.command.substr(1);
+if(!this.button){
+_4=dojo.mixin({label:_5,showLabel:false,iconClass:_6,dropDown:this.dropDown,tabIndex:"-1"},_4||{});
+this.button=new this.buttonClass(_4);
+}
+}
+},destroy:function(f){
+dojo.forEach(this._connects,dojo.disconnect);
+if(this.dropDown){
+this.dropDown.destroyRecursive();
+}
+},connect:function(o,f,tf){
+this._connects.push(dojo.connect(o,f,this,tf));
+},updateState:function(){
+var e=this.editor,c=this.command,_d,_e;
+if(!e||!e.isLoaded||!c.length){
+return;
+}
+if(this.button){
+try{
+_e=e.queryCommandEnabled(c);
+if(this.enabled!==_e){
+this.enabled=_e;
+this.button.attr("disabled",!_e);
+}
+if(typeof this.button.checked=="boolean"){
+_d=e.queryCommandState(c);
+if(this.checked!==_d){
+this.checked=_d;
+this.button.attr("checked",e.queryCommandState(c));
+}
+}
+}
+catch(e){
+
+}
+}
+},setEditor:function(_f){
+this.editor=_f;
+this._initButton();
+if(this.command.length&&!this.editor.queryCommandAvailable(this.command)){
+if(this.button){
+this.button.domNode.style.display="none";
+}
+}
+if(this.button&&this.useDefaultCommand){
+this.connect(this.button,"onClick",dojo.hitch(this.editor,"execCommand",this.command,this.commandArg));
+}
+this.connect(this.editor,"onNormalizedDisplayChanged","updateState");
+},setToolbar:function(_10){
+if(this.button){
+_10.addChild(this.button);
+}
+}});
+}
diff --git a/dijit/_editor/html.js b/dijit/_editor/html.js
new file mode 100644
index 0000000..e7523b2
--- /dev/null
+++ b/dijit/_editor/html.js
@@ -0,0 +1,106 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._editor.html"]){
+dojo._hasResource["dijit._editor.html"]=true;
+dojo.provide("dijit._editor.html");
+dijit._editor.escapeXml=function(_1,_2){
+_1=_1.replace(/&/gm,"&").replace(/</gm,"<").replace(/>/gm,">").replace(/"/gm,""");
+if(!_2){
+_1=_1.replace(/'/gm,"'");
+}
+return _1;
+};
+dijit._editor.getNodeHtml=function(_3){
+var _4;
+switch(_3.nodeType){
+case 1:
+_4="<"+_3.nodeName.toLowerCase();
+var _5=[];
+if(dojo.isIE&&_3.outerHTML){
+var s=_3.outerHTML;
+s=s.substr(0,s.indexOf(">")).replace(/(['"])[^"']*\1/g,"");
+var _7=/([^\s=]+)=/g;
+var m,_9;
+while((m=_7.exec(s))){
+_9=m[1];
+if(_9.substr(0,3)!="_dj"){
+if(_9=="src"||_9=="href"){
+if(_3.getAttribute("_djrealurl")){
+_5.push([_9,_3.getAttribute("_djrealurl")]);
+continue;
+}
+}
+var _a;
+switch(_9){
+case "style":
+_a=_3.style.cssText.toLowerCase();
+break;
+case "class":
+_a=_3.className;
+break;
+default:
+_a=_3.getAttribute(_9);
+}
+_5.push([_9,_a.toString()]);
+}
+}
+}else{
+var _b,i=0;
+while((_b=_3.attributes[i++])){
+var n=_b.name;
+if(n.substr(0,3)!="_dj"){
+var v=_b.value;
+if(n=="src"||n=="href"){
+if(_3.getAttribute("_djrealurl")){
+v=_3.getAttribute("_djrealurl");
+}
+}
+_5.push([n,v]);
+}
+}
+}
+_5.sort(function(a,b){
+return a[0]<b[0]?-1:(a[0]==b[0]?0:1);
+});
+var j=0;
+while((_b=_5[j++])){
+_4+=" "+_b[0]+"=\""+(dojo.isString(_b[1])?dijit._editor.escapeXml(_b[1],true):_b[1])+"\"";
+}
+if(_3.childNodes.length){
+_4+=">"+dijit._editor.getChildrenHtml(_3)+"</"+_3.nodeName.toLowerCase()+">";
+}else{
+_4+=" />";
+}
+break;
+case 3:
+_4=dijit._editor.escapeXml(_3.nodeValue,true);
+break;
+case 8:
+_4="<!--"+dijit._editor.escapeXml(_3.nodeValue,true)+"-->";
+break;
+default:
+_4="<!-- Element not recognized - Type: "+_3.nodeType+" Name: "+_3.nodeName+"-->";
+}
+return _4;
+};
+dijit._editor.getChildrenHtml=function(dom){
+var out="";
+if(!dom){
+return out;
+}
+var _14=dom["childNodes"]||dom;
+var _15=!dojo.isIE||_14!==dom;
+var _16,i=0;
+while((_16=_14[i++])){
+if(!_15||_16.parentNode==dom){
+out+=dijit._editor.getNodeHtml(_16);
+}
+}
+return out;
+};
+}
diff --git a/dijit/_editor/nls/FontChoice.js b/dijit/_editor/nls/FontChoice.js
new file mode 100644
index 0000000..71da48d
--- /dev/null
+++ b/dijit/_editor/nls/FontChoice.js
@@ -0,0 +1 @@
+({"1":"xx-small","2":"x-small","formatBlock":"Format","3":"small","4":"medium","5":"large","6":"x-large","7":"xx-large","fantasy":"fantasy","serif":"serif","p":"Paragraph","pre":"Pre-formatted","sans-serif":"sans-serif","fontName":"Font","h1":"Heading","h2":"Subheading","h3":"Sub-subheading","monospace":"monospace","fontSize":"Size","cursive":"cursive"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/LinkDialog.js b/dijit/_editor/nls/LinkDialog.js
new file mode 100644
index 0000000..3e1b917
--- /dev/null
+++ b/dijit/_editor/nls/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Set","text":"Description:","insertImageTitle":"Image Properties","url":"URL:","createLinkTitle":"Link Properties"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/ar/FontChoice.js b/dijit/_editor/nls/ar/FontChoice.js
new file mode 100644
index 0000000..78c3ed9
--- /dev/null
+++ b/dijit/_editor/nls/ar/FontChoice.js
@@ -0,0 +1 @@
+({"1":"صغير جدا جدا","2":"صغير جدا","formatBlock":"النسق","3":"صغير","4":"متوسط","5":"كبير","6":"كبير جدا","7":"كبير جدا جدا","fantasy":"خيالي","serif":"serif","p":"فقرة","pre":"منسق بصفة مسبقة","sans-serif":"sans-serif","fontName":"طاقم طباعة","h1":"عنوان","h2":"عنوان فرعي","h3":"فرعي-عنوان فرعي","monospace":"أحادي المسافة","fontSize":"الحجم","cursive":"كتابة بحروف متصلة"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/ar/LinkDialog.js b/dijit/_editor/nls/ar/LinkDialog.js
new file mode 100644
index 0000000..28d0f9d
--- /dev/null
+++ b/dijit/_editor/nls/ar/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"تحديد","text":"الوصف:","insertImageTitle":"خصائص الصورة","url":"عنوان URL:","createLinkTitle":"خصائص الوصلة"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/ar/commands.js b/dijit/_editor/nls/ar/commands.js
new file mode 100644
index 0000000..0134576
--- /dev/null
+++ b/dijit/_editor/nls/ar/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"ازالة النسق","copy":"نسخ","paste":"لصق","selectAll":"اختيار كل","insertOrderedList":"‏كشف مرقم‏","insertTable":"ادراج/تحرير جدول","underline":"تسطير","foreColor":"لون الواجهة الأمامية","htmlToggle":"مصدر HTML","formatBlock":"نمط الفقرة","insertHorizontalRule":"مسطرة أفقية","delete":"حذف","insertUnorderedList":"كشف نقطي","tableProp":"خصائص الجدول","insertImage":"ادراج صورة","superscript":"رمز علوي","subscript":"رمز سفلي","createLink":"تكوين وصلة","undo":"تراجع","italic": [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/ca/FontChoice.js b/dijit/_editor/nls/ca/FontChoice.js
new file mode 100644
index 0000000..8d3dabe
--- /dev/null
+++ b/dijit/_editor/nls/ca/FontChoice.js
@@ -0,0 +1 @@
+({"1":"xx-petit","2":"x-petit","formatBlock":"Format","3":"petit","4":"mitjà","5":"gran","6":"x-gran","7":"xx-gran","fantasy":"Fantasia","serif":"serif","p":"Paràgraf","pre":"Format previ","sans-serif":"sans-serif","fontName":"Tipus de lletra","h1":"Títol","h2":"Subtítol","h3":"Subsubtítol","monospace":"monoespai","fontSize":"Mida","cursive":"Cursiva"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/ca/LinkDialog.js b/dijit/_editor/nls/ca/LinkDialog.js
new file mode 100644
index 0000000..3c09f35
--- /dev/null
+++ b/dijit/_editor/nls/ca/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Defineix","text":"Descripció:","insertImageTitle":"Propietats de la imatge","url":"URL:","createLinkTitle":"Propietats de l'enllaç"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/ca/commands.js b/dijit/_editor/nls/ca/commands.js
new file mode 100644
index 0000000..fe154ad
--- /dev/null
+++ b/dijit/_editor/nls/ca/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Elimina el format","copy":"Copia","paste":"Enganxa","selectAll":"Selecciona-ho tot","insertOrderedList":"Llista numerada","insertTable":"Insereix/edita la taula","underline":"Subratllat","foreColor":"Color de primer pla","htmlToggle":"Font HTML","formatBlock":"Estil de paràgraf","insertHorizontalRule":"Regle horitzontal","delete":"Suprimeix","insertUnorderedList":"Llista de vinyetes","tableProp":"Propietat de taula","insertImage":"Insereix imatge","superscript":"Superín [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/commands.js b/dijit/_editor/nls/commands.js
new file mode 100644
index 0000000..be10087
--- /dev/null
+++ b/dijit/_editor/nls/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Remove Format","copy":"Copy","paste":"Paste","selectAll":"Select All","insertOrderedList":"Numbered List","insertTable":"Insert/Edit Table","underline":"Underline","foreColor":"Foreground Color","htmlToggle":"HTML Source","formatBlock":"Paragraph Style","insertHorizontalRule":"Horizontal Rule","delete":"Delete","appleKey":"⌘${0}","insertUnorderedList":"Bullet List","tableProp":"Table Property","insertImage":"Insert Image","superscript":"Superscript","subscript":"Subscri [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/cs/FontChoice.js b/dijit/_editor/nls/cs/FontChoice.js
new file mode 100644
index 0000000..4f82895
--- /dev/null
+++ b/dijit/_editor/nls/cs/FontChoice.js
@@ -0,0 +1 @@
+({"1":"extra malé","2":"velmi malé","formatBlock":"Formát","3":"malé","4":"střední","5":"velké","6":"velmi velké","7":"extra velké","fantasy":"fantasy","serif":"serif","p":"Odstavec","pre":"Předformátované","sans-serif":"sans-serif","fontName":"Písmo","h1":"Nadpis","h2":"Podnadpis","h3":"Podnadpis 2","monospace":"monospace","fontSize":"Velikost","cursive":"cursive"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/cs/LinkDialog.js b/dijit/_editor/nls/cs/LinkDialog.js
new file mode 100644
index 0000000..cf124d5
--- /dev/null
+++ b/dijit/_editor/nls/cs/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Nastavit","text":"Popis:","insertImageTitle":"Vlastnosti obrázku","url":"Adresa URL:","createLinkTitle":"Vlastnosti odkazu"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/cs/commands.js b/dijit/_editor/nls/cs/commands.js
new file mode 100644
index 0000000..3e8dcd1
--- /dev/null
+++ b/dijit/_editor/nls/cs/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Odebrat formát","copy":"Kopírovat","paste":"Vložit","selectAll":"Vybrat vše","insertOrderedList":"Číslovaný seznam","insertTable":"Vložit/upravit tabulku","underline":"Podtržení","foreColor":"Barva popředí","htmlToggle":"Zdroj HTML","formatBlock":"Styl odstavce","insertHorizontalRule":"Vodorovná čára","delete":"Odstranit","insertUnorderedList":"Seznam s odrážkami","tableProp":"Vlastnost tabulky","insertImage":"Vložit obrázek","superscript":"Horní index","subscript":"Dol [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/da/FontChoice.js b/dijit/_editor/nls/da/FontChoice.js
new file mode 100644
index 0000000..2ecab08
--- /dev/null
+++ b/dijit/_editor/nls/da/FontChoice.js
@@ -0,0 +1 @@
+({"1":"xx-small","2":"x-small","formatBlock":"Format","3":"small","4":"medium","5":"large","6":"x-large","7":"xx-large","fantasy":"fantasy","serif":"serif","p":"Afsnit","pre":"Forudformateret","sans-serif":"sans-serif","fontName":"Skrifttype","h1":"Overskrift","h2":"Underoverskrift","h3":"Underunderoverskrift","monospace":"monospace","fontSize":"Størrelse","cursive":"kursiv"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/da/LinkDialog.js b/dijit/_editor/nls/da/LinkDialog.js
new file mode 100644
index 0000000..87fd8a9
--- /dev/null
+++ b/dijit/_editor/nls/da/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Definér","text":"Beskrivelse:","insertImageTitle":"Billedegenskaber","url":"URL:","createLinkTitle":"Linkegenskaber"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/da/commands.js b/dijit/_editor/nls/da/commands.js
new file mode 100644
index 0000000..3751628
--- /dev/null
+++ b/dijit/_editor/nls/da/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Fjern format","copy":"Kopiér","paste":"Sæt ind","selectAll":"Markér alle","insertOrderedList":"Nummereret liste","insertTable":"Indsæt/redigér tabel","underline":"Understreget","foreColor":"Forgrundsfarve","htmlToggle":"HTML-kilde","formatBlock":"Afsnitstypografi","insertHorizontalRule":"Vandret linje","delete":"Slet","insertUnorderedList":"Punktliste","tableProp":"Tabelegenskab","insertImage":"Indsæt billede","superscript":"Hævet skrift","subscript":"Sænket skrift","cr [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/de/FontChoice.js b/dijit/_editor/nls/de/FontChoice.js
new file mode 100644
index 0000000..f16b312
--- /dev/null
+++ b/dijit/_editor/nls/de/FontChoice.js
@@ -0,0 +1 @@
+({"1":"XXS","2":"XS","formatBlock":"Format","3":"S","4":"M","5":"L","6":"XL","7":"XXL","fantasy":"Fantasie","serif":"Serife","p":"Absatz","pre":"Vorformatiert","sans-serif":"Serifenlos","fontName":"Schriftart","h1":"Überschrift","h2":"Unterüberschrift","h3":"Unterunterüberschrift","monospace":"Monospaceschrift","fontSize":"Größe","cursive":"Kursiv"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/de/LinkDialog.js b/dijit/_editor/nls/de/LinkDialog.js
new file mode 100644
index 0000000..0bc01cb
--- /dev/null
+++ b/dijit/_editor/nls/de/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Festlegen","text":"Beschreibung:","insertImageTitle":"Grafikeigenschaften","url":"URL:","createLinkTitle":"Linkeigenschaften"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/de/commands.js b/dijit/_editor/nls/de/commands.js
new file mode 100644
index 0000000..f085780
--- /dev/null
+++ b/dijit/_editor/nls/de/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Formatierung entfernen","copy":"Kopieren","paste":"Einfügen","selectAll":"Alles auswählen","insertOrderedList":"Nummerierung","insertTable":"Tabelle einfügen/bearbeiten","underline":"Unterstrichen","foreColor":"Vordergrundfarbe","htmlToggle":"HTML-Quelltext","formatBlock":"Absatzstil","insertHorizontalRule":"Horizontaler Strich","delete":"Löschen","insertUnorderedList":"Aufzählungszeichen","tableProp":"Tabelleneigenschaft","insertImage":"Grafik einfügen","superscript":" [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/el/FontChoice.js b/dijit/_editor/nls/el/FontChoice.js
new file mode 100644
index 0000000..2d51628
--- /dev/null
+++ b/dijit/_editor/nls/el/FontChoice.js
@@ -0,0 +1 @@
+({"1":"xx-μικρά","2":"x-μικρά","formatBlock":"Μορφή","3":"μικρά","4":"μεσαία","5":"μεγάλα","6":"x-μεγάλα","7":"xx-μεγάλα","fantasy":"φαντασίας","serif":"με πατούρες (serif)","p":"Παράγραφος","pre":"Προ-μορφοποιημένο","sans-serif":"χωρίς πατούρες (sans-serif)","fontName":"Γραμματοσειρά","h1":"Επικεφαλίδα","h2":"Δευτερεύουσα επικεφαλίδα","h3":"Δευτερεύουσα επικεφαλίδα τρίτου επιπέδου","monospace":"σταθερού πλάτους","fontSize":"Μέγεθος","cursive":"πλάγιοι"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/el/LinkDialog.js b/dijit/_editor/nls/el/LinkDialog.js
new file mode 100644
index 0000000..a615aeb
--- /dev/null
+++ b/dijit/_editor/nls/el/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Ορισμός","text":"Περιγραφή:","insertImageTitle":"Ιδιότητες εικόνας","url":"Διεύθυνση URL:","createLinkTitle":"Ιδιότητες διασύνδεσης"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/el/commands.js b/dijit/_editor/nls/el/commands.js
new file mode 100644
index 0000000..4c41931
--- /dev/null
+++ b/dijit/_editor/nls/el/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Αφαίρεση μορφοποίησης","copy":"Αντιγραφή","paste":"Επικόλληση","selectAll":"Επιλογή όλων","insertOrderedList":"Αριθμημένη λίστα","insertTable":"Εισαγωγή/Τροποποίηση πίνακα","underline":"Υπογράμμιση","foreColor":"Χρώμα προσκηνίου","htmlToggle":"Πρωτογενής κώδικας HTML","formatBlock":"Στυλ παραγράφου","insertHorizontalRule":"Οριζόντια γραμμή","delete":"Διαγραφή","insertUnorderedList":"Λίστα με κουκίδες","tableProp":"Ιδιότητα πίνακα","insertImage":"Εισαγωγή εικόνας","super [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/es/FontChoice.js b/dijit/_editor/nls/es/FontChoice.js
new file mode 100644
index 0000000..bacacf0
--- /dev/null
+++ b/dijit/_editor/nls/es/FontChoice.js
@@ -0,0 +1 @@
+({"1":"xx-pequeño","2":"x-pequeño","formatBlock":"Formato","3":"pequeño","4":"medio","5":"grande","6":"x-grande","7":"xx-grande","fantasy":"fantasía","serif":"serif","p":"Párrafo","pre":"Preformateado","sans-serif":"sans-serif","fontName":"Font","h1":"Cabecera","h2":"Subcabecera","h3":"Sub-subcabecera","monospace":"espacio sencillo","fontSize":"Tamaño","cursive":"cursiva"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/es/LinkDialog.js b/dijit/_editor/nls/es/LinkDialog.js
new file mode 100644
index 0000000..8dfe95f
--- /dev/null
+++ b/dijit/_editor/nls/es/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Establecer","text":"Descripción:","insertImageTitle":"Propiedades de la imagen","url":"URL:","createLinkTitle":"Propiedades del enlace"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/es/commands.js b/dijit/_editor/nls/es/commands.js
new file mode 100644
index 0000000..de2cea7
--- /dev/null
+++ b/dijit/_editor/nls/es/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Eliminar formato","copy":"Copiar","paste":"Pegar","selectAll":"Seleccionar todo","insertOrderedList":"Lista numerada","insertTable":"Insertar/Editar tabla","underline":"Subrayado","foreColor":"Color de primer plano","htmlToggle":"Fuente HTML","formatBlock":"Estilo de párrafo","insertHorizontalRule":"Regla horizontal","delete":"Suprimir","insertUnorderedList":"Lista con viñetas","tableProp":"Propiedad de tabla","insertImage":"Insertar imagen","superscript":"Superíndice", [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/fi/FontChoice.js b/dijit/_editor/nls/fi/FontChoice.js
new file mode 100644
index 0000000..37d3962
--- /dev/null
+++ b/dijit/_editor/nls/fi/FontChoice.js
@@ -0,0 +1 @@
+({"1":"xx-small","2":"x-small","formatBlock":"Muoto","3":"small","4":"medium","5":"large","6":"x-large","7":"xx-large","fantasy":"fantasy","serif":"serif","p":"Kappale","pre":"Esimuotoiltu","sans-serif":"sans-serif","fontName":"Fontti","h1":"Otsikko","h2":"Alatason otsikko","h3":"Alimman tason otsikko","monospace":"monospace","fontSize":"Koko","cursive":"cursive"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/fi/LinkDialog.js b/dijit/_editor/nls/fi/LinkDialog.js
new file mode 100644
index 0000000..dba80b6
--- /dev/null
+++ b/dijit/_editor/nls/fi/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Aseta","text":"Kuvaus:","insertImageTitle":"Kuvan ominaisuudet","url":"URL-osoite:","createLinkTitle":"Linkin ominaisuudet"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/fi/commands.js b/dijit/_editor/nls/fi/commands.js
new file mode 100644
index 0000000..5448d11
--- /dev/null
+++ b/dijit/_editor/nls/fi/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Poista muotoilu","copy":"Kopioi","paste":"Liitä","selectAll":"Valitse kaikki","insertOrderedList":"Numeroitu luettelo","insertTable":"Lisää taulukko/muokkaa taulukkoa","underline":"Alleviivaus","foreColor":"Edustaväri","htmlToggle":"HTML-lähde","formatBlock":"Kappaletyyli","insertHorizontalRule":"Vaakasuuntainen viiva","delete":"Poista","insertUnorderedList":"Numeroimaton luettelo","tableProp":"Taulukon ominaisuudet","insertImage":"Lisää kuva","superscript":"Korotettu", [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/fr/FontChoice.js b/dijit/_editor/nls/fr/FontChoice.js
new file mode 100644
index 0000000..9063de8
--- /dev/null
+++ b/dijit/_editor/nls/fr/FontChoice.js
@@ -0,0 +1 @@
+({"1":"xxs","2":"xs","formatBlock":"Mise en forme","3":"s","4":"m","5":"l","6":"xl","7":"xxl","fantasy":"fantaisie","serif":"serif","p":"Paragraphe","pre":"Pré-mise en forme","sans-serif":"sans serif","fontName":"Police","h1":"En-tête","h2":"Sous-en-tête","h3":"Sous-sous-en-tête","monospace":"espacement fixe","fontSize":"Taille","cursive":"cursive"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/fr/LinkDialog.js b/dijit/_editor/nls/fr/LinkDialog.js
new file mode 100644
index 0000000..d3d8728
--- /dev/null
+++ b/dijit/_editor/nls/fr/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Définir","text":"Description :","insertImageTitle":"Propriétés de l'image","url":"URL :","createLinkTitle":"Propriétés du lien"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/fr/commands.js b/dijit/_editor/nls/fr/commands.js
new file mode 100644
index 0000000..4fee663
--- /dev/null
+++ b/dijit/_editor/nls/fr/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Supprimer la mise en forme","copy":"Copier","paste":"Coller","selectAll":"Sélectionner tout","insertOrderedList":"Liste numérotée","insertTable":"Insérer/Modifier un tableau","underline":"Souligner","foreColor":"Couleur d'avant-plan","htmlToggle":"Source HTML","formatBlock":"Style de paragraphe","insertHorizontalRule":"Règle horizontale","delete":"Supprimer","insertUnorderedList":"Liste à puces","tableProp":"Propriété du tableau","insertImage":"Insérer une image","super [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/he/FontChoice.js b/dijit/_editor/nls/he/FontChoice.js
new file mode 100644
index 0000000..9f1b213
--- /dev/null
+++ b/dijit/_editor/nls/he/FontChoice.js
@@ -0,0 +1 @@
+({"1":"קטן ביות","2":"קטן מאוד","formatBlock":"עיצוב","3":"קטן","4":"בינוני","5":"גדול","6":"גדול מאוד","7":"גדול ביותר","fantasy":"fantasy","serif":"serif","p":"פיסקה","pre":"מעוצב מראש","sans-serif":"sans-serif","fontName":"גופן","h1":"כותרת","h2":"תת-כותרת","h3":"תת-תת-כותרת","monospace":"monospace","fontSize":"גודל","cursive":"cursive"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/he/LinkDialog.js b/dijit/_editor/nls/he/LinkDialog.js
new file mode 100644
index 0000000..71bbc23
--- /dev/null
+++ b/dijit/_editor/nls/he/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"הגדרה","text":"תיאור:","insertImageTitle":"תכונות תמונה","url":"URL:‏","createLinkTitle":"תכונות קישור"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/he/commands.js b/dijit/_editor/nls/he/commands.js
new file mode 100644
index 0000000..2435c0c
--- /dev/null
+++ b/dijit/_editor/nls/he/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"סילוק עיצוב","copy":"העתקה","paste":"הדבקה","selectAll":"בחירת הכל","insertOrderedList":"רשימה ממוספרת","insertTable":"הוספת/עריכת טבלה","underline":"קו תחתי","foreColor":"צבע חזית","htmlToggle":"מקור HTML","formatBlock":"סגנון פיסקה","insertHorizontalRule":"קו אופקי","delete":"מחיקה","insertUnorderedList":"רשימה עם תבליטים","tableProp":"תכונת טבלה","insertImage":"הוספת תמונה","superscript":"כתב עילי","subscript":"כתב תחתי","createLink":"יצירת קישור","undo":"ביטול פעולה [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/hu/FontChoice.js b/dijit/_editor/nls/hu/FontChoice.js
new file mode 100644
index 0000000..858d77a
--- /dev/null
+++ b/dijit/_editor/nls/hu/FontChoice.js
@@ -0,0 +1 @@
+({"1":"xx-kicsi","2":"x-kicsi","formatBlock":"Formátum","3":"kicsi","4":"közepes","5":"nagy","6":"x-nagy","7":"xx-nagy","fantasy":"fantázia","serif":"talpas","p":"Bekezdés","pre":"Előformázott","sans-serif":"talpatlan","fontName":"Betűtípus","h1":"Címsor","h2":"Alcím","h3":"Al-alcím","monospace":"rögzített szélességű","fontSize":"Méret","cursive":"kurzív"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/hu/LinkDialog.js b/dijit/_editor/nls/hu/LinkDialog.js
new file mode 100644
index 0000000..8662cf2
--- /dev/null
+++ b/dijit/_editor/nls/hu/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Beállítás","text":"Leírás:","insertImageTitle":"Kép tulajdonságai","url":"URL:","createLinkTitle":"Hivatkozás tulajdonságai"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/hu/commands.js b/dijit/_editor/nls/hu/commands.js
new file mode 100644
index 0000000..ee1aab0
--- /dev/null
+++ b/dijit/_editor/nls/hu/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Formázás eltávolítása","copy":"Másolás","paste":"Beillesztés","selectAll":"Összes kijelölése","insertOrderedList":"Számozott lista","insertTable":"Táblázat beszúrása/szerkesztése","underline":"Aláhúzott","foreColor":"Előtérszín","htmlToggle":"HTML forrás","formatBlock":"Bekezdés stílusa","insertHorizontalRule":"Vízszintes vonalzó","delete":"Törlés","insertUnorderedList":"Felsorolásjeles lista","tableProp":"Táblázat tulajdonságai","insertImage":"Kép beszúrása","superscri [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/it/FontChoice.js b/dijit/_editor/nls/it/FontChoice.js
new file mode 100644
index 0000000..1a180df
--- /dev/null
+++ b/dijit/_editor/nls/it/FontChoice.js
@@ -0,0 +1 @@
+({"1":"xx-small","2":"x-small","formatBlock":"Formato","3":"small","4":"medium","5":"large","6":"x-large","7":"xx-large","fantasy":"fantasy","serif":"serif","p":"Paragrafo","pre":"Preformattato","sans-serif":"sans-serif","fontName":"Carattere","h1":"Intestazione","h2":"Sottointestazione","h3":"Sottointestazione secondaria","monospace":"spaziatura fissa","fontSize":"Dimensione","cursive":"corsivo"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/it/LinkDialog.js b/dijit/_editor/nls/it/LinkDialog.js
new file mode 100644
index 0000000..72f76e4
--- /dev/null
+++ b/dijit/_editor/nls/it/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Imposta","text":"Descrizione:","insertImageTitle":"Proprietà immagine","url":"URL:","createLinkTitle":"Proprietà collegamento"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/it/commands.js b/dijit/_editor/nls/it/commands.js
new file mode 100644
index 0000000..342daa0
--- /dev/null
+++ b/dijit/_editor/nls/it/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Rimuovi formato","copy":"Copia","paste":"Incolla","selectAll":"Seleziona tutto","insertOrderedList":"Elenco numerato","insertTable":"Inserisci/Modifica tabella","underline":"Sottolineato","foreColor":"Colore primo piano","htmlToggle":"Origine HTML","formatBlock":"Stile paragrafo","insertHorizontalRule":"Righello orizzontale","delete":"Elimina","insertUnorderedList":"Elenco puntato","tableProp":"Proprietà tabella","insertImage":"Inserisci immagine","superscript":"Apice", [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/ja/FontChoice.js b/dijit/_editor/nls/ja/FontChoice.js
new file mode 100644
index 0000000..a938d6b
--- /dev/null
+++ b/dijit/_editor/nls/ja/FontChoice.js
@@ -0,0 +1 @@
+({"1":"超極小","2":"極小","formatBlock":"フォーマット","3":"小","4":"標準","5":"大","6":"特大","7":"超特大","fantasy":"fantasy","serif":"serif","p":"段落","pre":"事前フォーマット済み","sans-serif":"sans-serif","fontName":"フォント","h1":"見出し","h2":"副見出し","h3":"副見出しの副見出し","monospace":"monospace","fontSize":"サイズ","cursive":"cursive"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/ja/LinkDialog.js b/dijit/_editor/nls/ja/LinkDialog.js
new file mode 100644
index 0000000..2fc7a63
--- /dev/null
+++ b/dijit/_editor/nls/ja/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"設定","text":"説明:","insertImageTitle":"イメージ・プロパティー","url":"URL:","createLinkTitle":"リンク・プロパティー"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/ja/commands.js b/dijit/_editor/nls/ja/commands.js
new file mode 100644
index 0000000..7f359c2
--- /dev/null
+++ b/dijit/_editor/nls/ja/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"形式の除去","copy":"コピー","paste":"貼り付け","selectAll":"すべて選択","insertOrderedList":"番号付きリスト","insertTable":"テーブルの挿入/編集","underline":"下線","foreColor":"テキストの色","htmlToggle":"HTML ソース","formatBlock":"段落スタイル","insertHorizontalRule":"水平罫線","delete":"削除","insertUnorderedList":"黒丸付きリスト","tableProp":"テーブル・プロパティー","insertImage":"イメージの挿入","superscript":"上付き文字","subscript":"下付き文字","createLink":"リンクの作成","undo":"元に戻す","italic":"イタリック","fontName":"フォント名","justifyLeft":"左揃え","unlink":"リンクの除去" [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/ko/FontChoice.js b/dijit/_editor/nls/ko/FontChoice.js
new file mode 100644
index 0000000..2603063
--- /dev/null
+++ b/dijit/_editor/nls/ko/FontChoice.js
@@ -0,0 +1 @@
+({"1":"가장 작게","2":"조금 작게","formatBlock":"서식","3":"작게","4":"중간","5":"크게","6":"조금 크게","7":"가장 크게","fantasy":"fantasy","serif":"serif","p":"단락","pre":"서식이 지정됨","sans-serif":"sans-serif","fontName":"글꼴","h1":"제목","h2":"부제목","h3":"하위 부제목","monospace":"monospace","fontSize":"크기","cursive":"cursive"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/ko/LinkDialog.js b/dijit/_editor/nls/ko/LinkDialog.js
new file mode 100644
index 0000000..c8d10c3
--- /dev/null
+++ b/dijit/_editor/nls/ko/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"설정","text":"설명:","insertImageTitle":"이미지 등록 정보","url":"URL:","createLinkTitle":"링크 등록 정보"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/ko/commands.js b/dijit/_editor/nls/ko/commands.js
new file mode 100644
index 0000000..546f12e
--- /dev/null
+++ b/dijit/_editor/nls/ko/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"형식 제거","copy":"복사","paste":"붙여넣기","selectAll":"모두 선택","insertOrderedList":"번호 목록","insertTable":"테이블 삽입/편집","underline":"밑줄","foreColor":"전경색","htmlToggle":"HTML 소스","formatBlock":"단락 양식","insertHorizontalRule":"수평 자","delete":"삭제","insertUnorderedList":"글머리표 목록","tableProp":"테이블 특성","insertImage":"이미지 삽입","superscript":"위첨자","subscript":"아래첨자","createLink":"링크 작성","undo":"실행 취소","italic":"이탤릭체","fontName":"글꼴 이름","justifyLeft":"왼쪽 맞춤","unlink":"링크 제거","toggleTableBorde [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/nb/FontChoice.js b/dijit/_editor/nls/nb/FontChoice.js
new file mode 100644
index 0000000..f22d972
--- /dev/null
+++ b/dijit/_editor/nls/nb/FontChoice.js
@@ -0,0 +1 @@
+({"1":"xx-liten","2":"x-liten","formatBlock":"Format","3":"liten","4":"middels","5":"stor","6":"x-stor","7":"xx-stor","fantasy":"fantasi","serif":"serif","p":"Avsnitt","pre":"Forhåndsformatert","sans-serif":"sans-serif","fontName":"Skrift","h1":"Overskrift","h2":"Undertittel","h3":"Under-undertittel","monospace":"monospace","fontSize":"Størrelse","cursive":"kursiv"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/nb/LinkDialog.js b/dijit/_editor/nls/nb/LinkDialog.js
new file mode 100644
index 0000000..1f26a40
--- /dev/null
+++ b/dijit/_editor/nls/nb/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Definer","text":"Beskrivelse:","insertImageTitle":"Bildeegenskaper","url":"URL:","createLinkTitle":"Koblingsegenskaper"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/nb/commands.js b/dijit/_editor/nls/nb/commands.js
new file mode 100644
index 0000000..76e02b1
--- /dev/null
+++ b/dijit/_editor/nls/nb/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Fjern format","copy":"Kopier","paste":"Lim inn","selectAll":"Velg alle","insertOrderedList":"Nummerert liste","insertTable":"Sett inn/rediger tabell","underline":"Understreking","foreColor":"Forgrunnsfarge","htmlToggle":"HTML-kilde","formatBlock":"Avsnittsstil","insertHorizontalRule":"Vannrett strek","delete":"Slett","insertUnorderedList":"Punktliste","tableProp":"Tabellegenskap","insertImage":"Sett inn bilde","superscript":"Hevet skrift","subscript":"Senket skrift","cr [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/nl/FontChoice.js b/dijit/_editor/nls/nl/FontChoice.js
new file mode 100644
index 0000000..e6811aa
--- /dev/null
+++ b/dijit/_editor/nls/nl/FontChoice.js
@@ -0,0 +1 @@
+({"1":"xx-klein","2":"x-klein","formatBlock":"Opmaak","3":"klein","4":"gemiddeld","5":"groot","6":"x-groot","7":"xx-groot","fantasy":"fantasy","serif":"serif","p":"Alinea","pre":"Vooraf opgemaakt","sans-serif":"sans-serif","fontName":"Lettertype","h1":"Kop","h2":"Subkop","h3":"Sub-subkop","monospace":"monospace","fontSize":"Grootte","cursive":"cursief"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/nl/LinkDialog.js b/dijit/_editor/nls/nl/LinkDialog.js
new file mode 100644
index 0000000..5f89113
--- /dev/null
+++ b/dijit/_editor/nls/nl/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Instellen","text":"Beschrijving:","insertImageTitle":"Afbeeldingseigenschappen","url":"URL:","createLinkTitle":"Linkeigenschappen"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/nl/commands.js b/dijit/_editor/nls/nl/commands.js
new file mode 100644
index 0000000..9296d51
--- /dev/null
+++ b/dijit/_editor/nls/nl/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Opmaak verwijderen","copy":"Kopiëren","paste":"Plakken","selectAll":"Alles selecteren","insertOrderedList":"Genummerde lijst","insertTable":"Tabel invoegen/bewerken","underline":"Onderstrepen","foreColor":"Voorgrondkleur","htmlToggle":"HTML-bron","formatBlock":"Alineastijl","insertHorizontalRule":"Horizontale liniaal","delete":"Wissen","insertUnorderedList":"Lijst met opsommingstekens","tableProp":"Tabeleigenschap","insertImage":"Afbeelding invoegen","superscript":"Supe [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/pl/FontChoice.js b/dijit/_editor/nls/pl/FontChoice.js
new file mode 100644
index 0000000..3c03893
--- /dev/null
+++ b/dijit/_editor/nls/pl/FontChoice.js
@@ -0,0 +1 @@
+({"1":"najmniejsza","2":"mniejsza","formatBlock":"Format","3":"mała","4":"średnia","5":"duża","6":"większa","7":"największa","fantasy":"fantazyjna","serif":"szeryfowa","p":"Akapit","pre":"Wstępnie sformatowane","sans-serif":"bezszeryfowa","fontName":"Czcionka","h1":"Nagłówek","h2":"Nagłówek 2-go poziomu","h3":"Nagłówek 3-go poziomu","monospace":"czcionka o stałej szerokości","fontSize":"Wielkość","cursive":"kursywa"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/pl/LinkDialog.js b/dijit/_editor/nls/pl/LinkDialog.js
new file mode 100644
index 0000000..9d6c182
--- /dev/null
+++ b/dijit/_editor/nls/pl/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Ustaw","text":"Opis:","insertImageTitle":"Właściwości obrazu","url":"Adres URL:","createLinkTitle":"Właściwości odsyłacza"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/pl/commands.js b/dijit/_editor/nls/pl/commands.js
new file mode 100644
index 0000000..3beb6cb
--- /dev/null
+++ b/dijit/_editor/nls/pl/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Usuń formatowanie","copy":"Kopiuj","paste":"Wklej","selectAll":"Wybierz wszystko","insertOrderedList":"Lista numerowana","insertTable":"Wstaw/edytuj tabelę","underline":"Podkreślenie","foreColor":"Kolor pierwszego planu","htmlToggle":"Kod źródłowy HTML","formatBlock":"Styl akapitu","insertHorizontalRule":"Linia pozioma","delete":"Usuń","insertUnorderedList":"Lista wypunktowana","tableProp":"Właściwość tabeli","insertImage":"Wstaw obraz","superscript":"Indeks górny","sub [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/pt-pt/FontChoice.js b/dijit/_editor/nls/pt-pt/FontChoice.js
new file mode 100644
index 0000000..c72a102
--- /dev/null
+++ b/dijit/_editor/nls/pt-pt/FontChoice.js
@@ -0,0 +1 @@
+({"1":"xxs","2":"xs","formatBlock":"Formato","3":"small","4":"medium","5":"large","6":"xl","7":"xxl","fantasy":"fantasy","serif":"serif","p":"Parágrafo","pre":"Pré-formatado","sans-serif":"sans-serif","fontName":"Tipo de letra","h1":"Título","h2":"Sub-título","h3":"Sub-subtítulo","monospace":"monospace","fontSize":"Tamanho","cursive":"cursive"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/pt-pt/LinkDialog.js b/dijit/_editor/nls/pt-pt/LinkDialog.js
new file mode 100644
index 0000000..98e5f2d
--- /dev/null
+++ b/dijit/_editor/nls/pt-pt/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Definir","text":"Descrição:","insertImageTitle":"Propriedades da imagem","url":"URL:","createLinkTitle":"Propriedades da ligação"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/pt-pt/commands.js b/dijit/_editor/nls/pt-pt/commands.js
new file mode 100644
index 0000000..68f3d6d
--- /dev/null
+++ b/dijit/_editor/nls/pt-pt/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Remover formato","copy":"Copiar","paste":"Colar","selectAll":"Seleccionar tudo","insertOrderedList":"Lista numerada","insertTable":"Inserir/Editar tabela","underline":"Sublinhado","foreColor":"Cor de primeiro plano","htmlToggle":"Origem HTML","formatBlock":"Estilo de parágrafo","insertHorizontalRule":"Régua horizontal","delete":"Eliminar","insertUnorderedList":"Lista marcada","tableProp":"Propriedades da tabela","insertImage":"Inserir imagem","superscript":"Superior à l [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/pt/FontChoice.js b/dijit/_editor/nls/pt/FontChoice.js
new file mode 100644
index 0000000..5919b43
--- /dev/null
+++ b/dijit/_editor/nls/pt/FontChoice.js
@@ -0,0 +1 @@
+({"1":"extra-extra-pequeno","2":"extra-pequeno","formatBlock":"Formatar","3":"pequena","4":"médio","5":"grande","6":"extra-grande","7":"extra-extra-grande","fantasy":"fantasy","serif":"serif","p":"Parágrafo","pre":"Pré-formatado","sans-serif":"sans-serif","fontName":"Fonte","h1":"Título","h2":"Subtítulo","h3":"Sub-subtítulo","monospace":"espaço simples","fontSize":"Tamanho","cursive":"cursiva"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/pt/LinkDialog.js b/dijit/_editor/nls/pt/LinkDialog.js
new file mode 100644
index 0000000..1c89058
--- /dev/null
+++ b/dijit/_editor/nls/pt/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Definir","text":"Descrição: ","insertImageTitle":"Propriedades de Imagem","url":"URL:","createLinkTitle":"Propriedades de Link"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/pt/commands.js b/dijit/_editor/nls/pt/commands.js
new file mode 100644
index 0000000..9c4a66c
--- /dev/null
+++ b/dijit/_editor/nls/pt/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Remover Formato","copy":"Copiar","paste":"Colar","selectAll":"Selecionar Tudo","insertOrderedList":"Lista Numerada","insertTable":"Inserir/Editar Tabela","underline":"Sublinhado","foreColor":"Cor de Primeiro Plano","htmlToggle":"Fonte HTML","formatBlock":"Estilo de Parágrafo","insertHorizontalRule":"Régua Horizontal","delete":"Excluir","insertUnorderedList":"Lista com Marcadores","tableProp":"Propriedade da Tabela","insertImage":"Inserir Imagem","superscript":"Sobrescri [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/ru/FontChoice.js b/dijit/_editor/nls/ru/FontChoice.js
new file mode 100644
index 0000000..cebf574
--- /dev/null
+++ b/dijit/_editor/nls/ru/FontChoice.js
@@ -0,0 +1 @@
+({"1":"самый маленький","2":"очень маленький","formatBlock":"Формат","3":"маленький","4":"средний","5":"большой","6":"очень большой","7":"самый большой","fantasy":"артистический","serif":"с засечками","p":"Абзац","pre":"Заранее отформатированный","sans-serif":"без засечек","fontName":"Шрифт","h1":"Заголовок","h2":"Подзаголовок","h3":"Вложенный подзаголовок","monospace":"непропорциональный","fontSize":"Размер","cursive":"курсив"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/ru/LinkDialog.js b/dijit/_editor/nls/ru/LinkDialog.js
new file mode 100644
index 0000000..42a6826
--- /dev/null
+++ b/dijit/_editor/nls/ru/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Задать","text":"Описание:","insertImageTitle":"Свойства изображения","url":"URL:","createLinkTitle":"Свойства ссылки"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/ru/commands.js b/dijit/_editor/nls/ru/commands.js
new file mode 100644
index 0000000..f8b17bc
--- /dev/null
+++ b/dijit/_editor/nls/ru/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Удалить формат","copy":"Копировать","paste":"Вставить","selectAll":"Выбрать все","insertOrderedList":"Нумерованный список","insertTable":"Вставить/изменить таблицу","underline":"Подчеркивание","foreColor":"Цвет текста","htmlToggle":"Исходный текст HTML","formatBlock":"Стиль абзаца","insertHorizontalRule":"Горизонтальная линейка","delete":"Удалить","insertUnorderedList":"Список с маркерами","tableProp":"Свойства таблицы","insertImage":"Вставить изображение","superscript" [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/sk/FontChoice.js b/dijit/_editor/nls/sk/FontChoice.js
new file mode 100644
index 0000000..9f8dc09
--- /dev/null
+++ b/dijit/_editor/nls/sk/FontChoice.js
@@ -0,0 +1 @@
+({"1":"xx-small","2":"x-small","formatBlock":"Formát","3":"small","4":"medium","5":"large","6":"x-large","7":"xx-large","fantasy":"fantasy","serif":"serif","p":"Odsek","pre":"Predformátované","sans-serif":"sans-serif","fontName":"Písmo","h1":"Hlavička","h2":"Podhlavička","h3":"Pod-podhlavička","monospace":"monospace","fontSize":"Veľkosť","cursive":"cursive"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/sk/LinkDialog.js b/dijit/_editor/nls/sk/LinkDialog.js
new file mode 100644
index 0000000..e039781
--- /dev/null
+++ b/dijit/_editor/nls/sk/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Nastaviť","text":"Popis:","insertImageTitle":"Vlastnosti obrázku","url":"URL:","createLinkTitle":"Vlastnosti odkazu"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/sk/commands.js b/dijit/_editor/nls/sk/commands.js
new file mode 100644
index 0000000..14c7cca
--- /dev/null
+++ b/dijit/_editor/nls/sk/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Odstrániť formát","copy":"Kopírovať","paste":"Nalepiť","selectAll":"Vybrať všetko","insertOrderedList":"Číslovaný zoznam","insertTable":"Vložiť/upraviť tabuľku","underline":"Podčiarknuť","foreColor":"Farba popredia","htmlToggle":"Zdroj HTML","formatBlock":"Štýl odseku","insertHorizontalRule":"Horizontálna čiara","delete":"Vymazať","insertUnorderedList":"Zoznam s odrážkami","tableProp":"Vlastnosť tabuľky","insertImage":"Vložiť obrázok","superscript":"Horný index","subscr [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/sl/FontChoice.js b/dijit/_editor/nls/sl/FontChoice.js
new file mode 100644
index 0000000..3a7094c
--- /dev/null
+++ b/dijit/_editor/nls/sl/FontChoice.js
@@ -0,0 +1 @@
+({"1":"xx-majhno","2":"x-majhno","formatBlock":"Oblika","3":"majhno","4":"srednje","5":"veliko","6":"x-veliko","7":"xx-veliko","fantasy":"fantasy","serif":"serif","p":"Odstavek","pre":"Vnaprej oblikovano","sans-serif":"sans-serif","fontName":"Pisava","h1":"Naslov","h2":"Podnaslov","h3":"Pod podnaslov","monospace":"monospace","fontSize":"Velikost","cursive":"cursive"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/sl/LinkDialog.js b/dijit/_editor/nls/sl/LinkDialog.js
new file mode 100644
index 0000000..8fc7cfd
--- /dev/null
+++ b/dijit/_editor/nls/sl/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Nastavi","text":"Opis:","insertImageTitle":"Lastnosti slike","url":"URL:","createLinkTitle":"Lastnosti povezave"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/sl/commands.js b/dijit/_editor/nls/sl/commands.js
new file mode 100644
index 0000000..49d7928
--- /dev/null
+++ b/dijit/_editor/nls/sl/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Odstrani obliko zapisa","copy":"Prekopiraj","paste":"Prilepi","selectAll":"Izberi vse","insertOrderedList":"Oštevilčen seznam","insertTable":"Vstavi/Uredi tabelo","underline":"Podčrtano","foreColor":"Barva ospredja","htmlToggle":"Izvor HTML","formatBlock":"Slog odstavka","insertHorizontalRule":"Horizontalno pravilo","delete":"Izbriši","insertUnorderedList":"Naštevni seznam","tableProp":"Lastnost tabele","insertImage":"Vstavi sliko","superscript":"Nadpisano","subscript": [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/sv/FontChoice.js b/dijit/_editor/nls/sv/FontChoice.js
new file mode 100644
index 0000000..106f020
--- /dev/null
+++ b/dijit/_editor/nls/sv/FontChoice.js
@@ -0,0 +1 @@
+({"1":"mycket, mycket litet","2":"mycket litet","formatBlock":"Format","3":"litet","4":"medelstort","5":"stort","6":"extra stort","7":"extra extra stort","fantasy":"fantasy","serif":"serif","p":"Stycke","pre":"Förformaterat","sans-serif":"sans-serif","fontName":"Teckensnitt","h1":"Rubrik","h2":"Underrubrik","h3":"Underunderrubrik","monospace":"monospace","fontSize":"Storlek","cursive":"kursivt"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/sv/LinkDialog.js b/dijit/_editor/nls/sv/LinkDialog.js
new file mode 100644
index 0000000..64e8cfb
--- /dev/null
+++ b/dijit/_editor/nls/sv/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Ange","text":"Beskrivning:","insertImageTitle":"Bildegenskaper","url":"URL-adress:","createLinkTitle":"Länkegenskaper"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/sv/commands.js b/dijit/_editor/nls/sv/commands.js
new file mode 100644
index 0000000..e662fd6
--- /dev/null
+++ b/dijit/_editor/nls/sv/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Ta bort format","copy":"Kopiera","paste":"Klistra in","selectAll":"Markera allt","insertOrderedList":"Numrerad lista","insertTable":"Infoga/redigera tabell","underline":"Understrykning","foreColor":"Förgrundsfärg","htmlToggle":"HTML-källkod","formatBlock":"Styckeformat","insertHorizontalRule":"Horisontell linjal","delete":"Ta bort","insertUnorderedList":"Punktlista","tableProp":"Tabellegenskap","insertImage":"Infoga bild","superscript":"Upphöjt","subscript":"Nedsänkt"," [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/th/FontChoice.js b/dijit/_editor/nls/th/FontChoice.js
new file mode 100644
index 0000000..63613a4
--- /dev/null
+++ b/dijit/_editor/nls/th/FontChoice.js
@@ -0,0 +1 @@
+({"1":"xx-small","2":"x-small","formatBlock":"รูปแบบ","3":"small","4":"medium","5":"large","6":"x-large","7":"xx-large","fantasy":"fantasy","serif":"serif","p":"ย่อหน้า","pre":"การกำหนดรูปแบบล่วงหน้า","sans-serif":"sans-serif","fontName":"ฟอนต์","h1":"ส่วนหัว","h2":"ส่วนหัวย่อย","h3":"ส่วนย่อยของส่วนหัวย่อย","monospace":"monospace","fontSize":"ขนาด","cursive":"cursive"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/th/LinkDialog.js b/dijit/_editor/nls/th/LinkDialog.js
new file mode 100644
index 0000000..e916dfb
--- /dev/null
+++ b/dijit/_editor/nls/th/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"ตั้งค่า","text":"รายละเอียด","insertImageTitle":"คุณสมบัติอิมเมจ","url":"URL:","createLinkTitle":"คุณสมบัติลิงก์"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/th/commands.js b/dijit/_editor/nls/th/commands.js
new file mode 100644
index 0000000..cdc88b5
--- /dev/null
+++ b/dijit/_editor/nls/th/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"ลบรูปแบบออก","copy":"คัดลอก","paste":"วาง","selectAll":"เลือกทั้งหมด","insertOrderedList":"ลำดับเลข","insertTable":"แทรก/แก้ไข ตาราง","underline":"ขีดเส้นใต้","foreColor":"สีพื้นหน้า","htmlToggle":"ซอร์ส HTML","formatBlock":"ลักษณะย่อหน้า","insertHorizontalRule":"ไม้บรรทัดแนวนอน","delete":"ลบ","insertUnorderedList":"หัวข้อย่อย","tableProp":"คุณสมบัติตาราง","insertImage":"แทรกอิมเมจ","superscript":"ตัวยก","subscript":"ตัวห้อย","createLink":"สร้างลิงก์","undo":"เลิกทำ","i [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/tr/FontChoice.js b/dijit/_editor/nls/tr/FontChoice.js
new file mode 100644
index 0000000..d2ca7c4
--- /dev/null
+++ b/dijit/_editor/nls/tr/FontChoice.js
@@ -0,0 +1 @@
+({"1":"xx-küçük","2":"x-küçük","formatBlock":"Biçim","3":"küçük","4":"orta","5":"büyük","6":"x-büyük","7":"xx-büyük","fantasy":"fantazi","serif":"serif","p":"Paragraf","pre":"Önceden Biçimlendirilmiş","sans-serif":"sans-serif","fontName":"Yazı Tipi","h1":"Başlık","h2":"Alt Başlık","h3":"Alt Alt Başlık","monospace":"tek aralıklı","fontSize":"Boyut","cursive":"el yazısı"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/tr/LinkDialog.js b/dijit/_editor/nls/tr/LinkDialog.js
new file mode 100644
index 0000000..7f5856d
--- /dev/null
+++ b/dijit/_editor/nls/tr/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"Ayarla","text":"Açıklama:","insertImageTitle":"Resim Özellikleri","url":"URL:","createLinkTitle":"Bağlantı Özellikleri"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/tr/commands.js b/dijit/_editor/nls/tr/commands.js
new file mode 100644
index 0000000..2a71faa
--- /dev/null
+++ b/dijit/_editor/nls/tr/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"Biçimi Kaldır","copy":"Kopyala","paste":"Yapıştır","selectAll":"Tümünü Seç","insertOrderedList":"Numaralı Liste","insertTable":"Tablo Ekle/Düzenle","underline":"Altı Çizili","foreColor":"Ön Plan Rengi","htmlToggle":"HTML Kaynağı","formatBlock":"Paragraf Stili","insertHorizontalRule":"Yatay Kural","delete":"Sil","insertUnorderedList":"Madde İşaretli Liste","tableProp":"Tablo Özelliği","insertImage":"Resim Ekle","superscript":"Üst Simge","subscript":"Alt Simge","createLin [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/zh-tw/FontChoice.js b/dijit/_editor/nls/zh-tw/FontChoice.js
new file mode 100644
index 0000000..d32e163
--- /dev/null
+++ b/dijit/_editor/nls/zh-tw/FontChoice.js
@@ -0,0 +1 @@
+({"1":"最小","2":"較小","formatBlock":"格式","3":"小","4":"中","5":"大","6":"較大","7":"最大","fantasy":"Fantasy","serif":"新細明體","p":"段落","pre":"預先格式化","sans-serif":"新細明體","fontName":"字型","h1":"標題","h2":"子標題","h3":"次子標題","monospace":"等寬","fontSize":"大小","cursive":"Cursive"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/zh-tw/LinkDialog.js b/dijit/_editor/nls/zh-tw/LinkDialog.js
new file mode 100644
index 0000000..fb74fb6
--- /dev/null
+++ b/dijit/_editor/nls/zh-tw/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"設定","text":"說明:","insertImageTitle":"影像檔內容","url":"URL:","createLinkTitle":"鏈結內容"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/zh-tw/commands.js b/dijit/_editor/nls/zh-tw/commands.js
new file mode 100644
index 0000000..65d24d6
--- /dev/null
+++ b/dijit/_editor/nls/zh-tw/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"移除格式","copy":"複製","paste":"貼上","selectAll":"全選","insertOrderedList":"編號清單","insertTable":"插入/編輯表格","underline":"底線","foreColor":"前景顏色","htmlToggle":"HTML 原始檔","formatBlock":"段落樣式","insertHorizontalRule":"水平尺規","delete":"刪除","insertUnorderedList":"項目符號清單","tableProp":"表格內容","insertImage":"插入影像","superscript":"上標","subscript":"下標","createLink":"建立鏈結","undo":"復原","italic":"斜體","fontName":"字型名稱","justifyLeft":"靠左對齊","unlink":"移除鏈結","toggleTableBorder":"切換表格邊框","fontSize":"字 [...]
\ No newline at end of file
diff --git a/dijit/_editor/nls/zh/FontChoice.js b/dijit/_editor/nls/zh/FontChoice.js
new file mode 100644
index 0000000..c5d8510
--- /dev/null
+++ b/dijit/_editor/nls/zh/FontChoice.js
@@ -0,0 +1 @@
+({"1":"XXS 号","2":"XS 号","formatBlock":"格式","3":"S 号","4":"M 号","5":"L 号","6":"XL 号","7":"XXL 号","fantasy":"虚线","serif":"有衬线","p":"段落","pre":"预设有格式的","sans-serif":"无衬线","fontName":"字体","h1":"标题","h2":"子标题","h3":"二级子标题","monospace":"等宽字体","fontSize":"大小","cursive":"草书"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/zh/LinkDialog.js b/dijit/_editor/nls/zh/LinkDialog.js
new file mode 100644
index 0000000..a2148bc
--- /dev/null
+++ b/dijit/_editor/nls/zh/LinkDialog.js
@@ -0,0 +1 @@
+({"set":"设置","text":"说明:","insertImageTitle":"图像属性","url":"URL:","createLinkTitle":"链接属性"})
\ No newline at end of file
diff --git a/dijit/_editor/nls/zh/commands.js b/dijit/_editor/nls/zh/commands.js
new file mode 100644
index 0000000..48f9553
--- /dev/null
+++ b/dijit/_editor/nls/zh/commands.js
@@ -0,0 +1 @@
+({"removeFormat":"除去格式","copy":"拷贝","paste":"粘贴","selectAll":"全选","insertOrderedList":"编号列表","insertTable":"插入/编辑表","underline":"下划线","foreColor":"前景色","htmlToggle":"HTML 源代码","formatBlock":"段落样式","insertHorizontalRule":"水平线","delete":"删除","insertUnorderedList":"符号列表","tableProp":"表属性","insertImage":"插入图像","superscript":"上标","subscript":"下标","createLink":"创建链接","undo":"撤销","italic":"斜体","fontName":"字体名称","justifyLeft":"左对齐","unlink":"除去链接","toggleTableBorder":"切换表边框","fontSize":"字体大小","s [...]
\ No newline at end of file
diff --git a/dijit/_editor/plugins/AlwaysShowToolbar.js b/dijit/_editor/plugins/AlwaysShowToolbar.js
new file mode 100644
index 0000000..827b4df
--- /dev/null
+++ b/dijit/_editor/plugins/AlwaysShowToolbar.js
@@ -0,0 +1,121 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._editor.plugins.AlwaysShowToolbar"]){
+dojo._hasResource["dijit._editor.plugins.AlwaysShowToolbar"]=true;
+dojo.provide("dijit._editor.plugins.AlwaysShowToolbar");
+dojo.declare("dijit._editor.plugins.AlwaysShowToolbar",dijit._editor._Plugin,{_handleScroll:true,setEditor:function(e){
+if(!e.iframe){
+
+return;
+}
+this.editor=e;
+e.onLoadDeferred.addCallback(dojo.hitch(this,this.enable));
+},enable:function(d){
+this._updateHeight();
+this.connect(window,"onscroll","globalOnScrollHandler");
+this.connect(this.editor,"onNormalizedDisplayChanged","_updateHeight");
+return d;
+},_updateHeight:function(){
+var e=this.editor;
+if(!e.isLoaded){
+return;
+}
+if(e.height){
+return;
+}
+var _4=dojo.marginBox(e.editNode).h;
+if(dojo.isOpera){
+_4=e.editNode.scrollHeight;
+}
+if(!_4){
+_4=dojo.marginBox(e.document.body).h;
+}
+if(_4==0){
+
+return;
+}
+if(dojo.isIE<=7&&this.editor.minHeight){
+var _5=parseInt(this.editor.minHeight);
+if(_4<_5){
+_4=_5;
+}
+}
+if(_4!=this._lastHeight){
+this._lastHeight=_4;
+dojo.marginBox(e.iframe,{h:this._lastHeight});
+}
+},_lastHeight:0,globalOnScrollHandler:function(){
+var _6=dojo.isIE<7;
+if(!this._handleScroll){
+return;
+}
+var _7=this.editor.toolbar.domNode;
+var db=dojo.body;
+if(!this._scrollSetUp){
+this._scrollSetUp=true;
+this._scrollThreshold=dojo._abs(_7,true).y;
+}
+var _9=dojo._docScroll().y;
+var s=_7.style;
+if(_9>this._scrollThreshold&&_9<this._scrollThreshold+this._lastHeight){
+if(!this._fixEnabled){
+var _b=dojo.marginBox(_7);
+this.editor.iframe.style.marginTop=_b.h+"px";
+if(_6){
+s.left=dojo._abs(_7).x;
+if(_7.previousSibling){
+this._IEOriginalPos=["after",_7.previousSibling];
+}else{
+if(_7.nextSibling){
+this._IEOriginalPos=["before",_7.nextSibling];
+}else{
+this._IEOriginalPos=["last",_7.parentNode];
+}
+}
+dojo.body().appendChild(_7);
+dojo.addClass(_7,"dijitIEFixedToolbar");
+}else{
+s.position="fixed";
+s.top="0px";
+}
+dojo.marginBox(_7,{w:_b.w});
+s.zIndex=2000;
+this._fixEnabled=true;
+}
+var _c=(this.height)?parseInt(this.editor.height):this.editor._lastHeight;
+s.display=(_9>this._scrollThreshold+_c)?"none":"";
+}else{
+if(this._fixEnabled){
+this.editor.iframe.style.marginTop="";
+s.position="";
+s.top="";
+s.zIndex="";
+s.display="";
+if(_6){
+s.left="";
+dojo.removeClass(_7,"dijitIEFixedToolbar");
+if(this._IEOriginalPos){
+dojo.place(_7,this._IEOriginalPos[1],this._IEOriginalPos[0]);
+this._IEOriginalPos=null;
+}else{
+dojo.place(_7,this.editor.iframe,"before");
+}
+}
+s.width="";
+this._fixEnabled=false;
+}
+}
+},destroy:function(){
+this._IEOriginalPos=null;
+this._handleScroll=false;
+dojo.forEach(this._connects,dojo.disconnect);
+if(dojo.isIE<7){
+dojo.removeClass(this.editor.toolbar.domNode,"dijitIEFixedToolbar");
+}
+}});
+}
diff --git a/dijit/_editor/plugins/EnterKeyHandling.js b/dijit/_editor/plugins/EnterKeyHandling.js
new file mode 100644
index 0000000..e3ddb36
--- /dev/null
+++ b/dijit/_editor/plugins/EnterKeyHandling.js
@@ -0,0 +1,395 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._editor.plugins.EnterKeyHandling"]){
+dojo._hasResource["dijit._editor.plugins.EnterKeyHandling"]=true;
+dojo.provide("dijit._editor.plugins.EnterKeyHandling");
+dojo.declare("dijit._editor.plugins.EnterKeyHandling",dijit._editor._Plugin,{blockNodeForEnter:"BR",constructor:function(_1){
+if(_1){
+dojo.mixin(this,_1);
+}
+},setEditor:function(_2){
+this.editor=_2;
+if(this.blockNodeForEnter=="BR"){
+if(dojo.isIE){
+_2.contentDomPreFilters.push(dojo.hitch(this,"regularPsToSingleLinePs"));
+_2.contentDomPostFilters.push(dojo.hitch(this,"singleLinePsToRegularPs"));
+_2.onLoadDeferred.addCallback(dojo.hitch(this,"_fixNewLineBehaviorForIE"));
+}else{
+_2.onLoadDeferred.addCallback(dojo.hitch(this,function(d){
+try{
+this.editor.document.execCommand("insertBrOnReturn",false,true);
+}
+catch(e){
+}
+return d;
+}));
+}
+}else{
+if(this.blockNodeForEnter){
+dojo["require"]("dijit._editor.range");
+var h=dojo.hitch(this,this.handleEnterKey);
+_2.addKeyHandler(13,0,0,h);
+_2.addKeyHandler(13,0,1,h);
+this.connect(this.editor,"onKeyPressed","onKeyPressed");
+}
+}
+},connect:function(o,f,tf){
+if(!this._connects){
+this._connects=[];
+}
+this._connects.push(dojo.connect(o,f,this,tf));
+},destroy:function(){
+dojo.forEach(this._connects,dojo.disconnect);
+this._connects=[];
+},onKeyPressed:function(e){
+if(this._checkListLater){
+if(dojo.withGlobal(this.editor.window,"isCollapsed",dijit)){
+var _9=dojo.withGlobal(this.editor.window,"getAncestorElement",dijit._editor.selection,["LI"]);
+if(!_9){
+dijit._editor.RichText.prototype.execCommand.call(this.editor,"formatblock",this.blockNodeForEnter);
+var _a=dojo.withGlobal(this.editor.window,"getAncestorElement",dijit._editor.selection,[this.blockNodeForEnter]);
+if(_a){
+_a.innerHTML=this.bogusHtmlContent;
+if(dojo.isIE){
+var r=this.editor.document.selection.createRange();
+r.move("character",-1);
+r.select();
+}
+}else{
+alert("onKeyPressed: Can not find the new block node");
+}
+}else{
+if(dojo.isMoz){
+if(_9.parentNode.parentNode.nodeName=="LI"){
+_9=_9.parentNode.parentNode;
+}
+}
+var fc=_9.firstChild;
+if(fc&&fc.nodeType==1&&(fc.nodeName=="UL"||fc.nodeName=="OL")){
+_9.insertBefore(fc.ownerDocument.createTextNode(" "),fc);
+var _d=dijit.range.create();
+_d.setStart(_9.firstChild,0);
+var _e=dijit.range.getSelection(this.editor.window,true);
+_e.removeAllRanges();
+_e.addRange(_d);
+}
+}
+}
+this._checkListLater=false;
+}
+if(this._pressedEnterInBlock){
+if(this._pressedEnterInBlock.previousSibling){
+this.removeTrailingBr(this._pressedEnterInBlock.previousSibling);
+}
+delete this._pressedEnterInBlock;
+}
+},bogusHtmlContent:" ",blockNodes:/^(?:P|H1|H2|H3|H4|H5|H6|LI)$/,handleEnterKey:function(e){
+if(!this.blockNodeForEnter){
+return true;
+}
+var _10,_11,_12,doc=this.editor.document,br;
+if(e.shiftKey||this.blockNodeForEnter=="BR"){
+var _15=dojo.withGlobal(this.editor.window,"getParentElement",dijit._editor.selection);
+var _16=dijit.range.getAncestor(_15,this.blockNodes);
+if(_16){
+if(!e.shiftKey&&_16.tagName=="LI"){
+return true;
+}
+_10=dijit.range.getSelection(this.editor.window);
+_11=_10.getRangeAt(0);
+if(!_11.collapsed){
+_11.deleteContents();
+}
+if(dijit.range.atBeginningOfContainer(_16,_11.startContainer,_11.startOffset)){
+if(e.shiftKey){
+br=doc.createElement("br");
+_12=dijit.range.create();
+_16.insertBefore(br,_16.firstChild);
+_12.setStartBefore(br.nextSibling);
+_10.removeAllRanges();
+_10.addRange(_12);
+}else{
+dojo.place(br,_16,"before");
+}
+}else{
+if(dijit.range.atEndOfContainer(_16,_11.startContainer,_11.startOffset)){
+_12=dijit.range.create();
+br=doc.createElement("br");
+if(e.shiftKey){
+_16.appendChild(br);
+_16.appendChild(doc.createTextNode(" "));
+_12.setStart(_16.lastChild,0);
+}else{
+dojo.place(br,_16,"after");
+_12.setStartAfter(_16);
+}
+_10.removeAllRanges();
+_10.addRange(_12);
+}else{
+return true;
+}
+}
+}else{
+dijit._editor.RichText.prototype.execCommand.call(this.editor,"inserthtml","<br>");
+}
+return false;
+}
+var _17=true;
+_10=dijit.range.getSelection(this.editor.window);
+_11=_10.getRangeAt(0);
+if(!_11.collapsed){
+_11.deleteContents();
+}
+var _18=dijit.range.getBlockAncestor(_11.endContainer,null,this.editor.editNode);
+var _19=_18.blockNode;
+if((this._checkListLater=(_19&&(_19.nodeName=="LI"||_19.parentNode.nodeName=="LI")))){
+if(dojo.isMoz){
+this._pressedEnterInBlock=_19;
+}
+if(/^(?:\s| )$/.test(_19.innerHTML)){
+_19.innerHTML="";
+}
+return true;
+}
+if(!_18.blockNode||_18.blockNode===this.editor.editNode){
+dijit._editor.RichText.prototype.execCommand.call(this.editor,"formatblock",this.blockNodeForEnter);
+_18={blockNode:dojo.withGlobal(this.editor.window,"getAncestorElement",dijit._editor.selection,[this.blockNodeForEnter]),blockContainer:this.editor.editNode};
+if(_18.blockNode){
+if(!(_18.blockNode.textContent||_18.blockNode.innerHTML).replace(/^\s+|\s+$/g,"").length){
+this.removeTrailingBr(_18.blockNode);
+return false;
+}
+}else{
+_18.blockNode=this.editor.editNode;
+}
+_10=dijit.range.getSelection(this.editor.window);
+_11=_10.getRangeAt(0);
+}
+var _1a=doc.createElement(this.blockNodeForEnter);
+_1a.innerHTML=this.bogusHtmlContent;
+this.removeTrailingBr(_18.blockNode);
+if(dijit.range.atEndOfContainer(_18.blockNode,_11.endContainer,_11.endOffset)){
+if(_18.blockNode===_18.blockContainer){
+_18.blockNode.appendChild(_1a);
+}else{
+dojo.place(_1a,_18.blockNode,"after");
+}
+_17=false;
+_12=dijit.range.create();
+_12.setStart(_1a,0);
+_10.removeAllRanges();
+_10.addRange(_12);
+if(this.editor.height){
+_1a.scrollIntoView(false);
+}
+}else{
+if(dijit.range.atBeginningOfContainer(_18.blockNode,_11.startContainer,_11.startOffset)){
+dojo.place(_1a,_18.blockNode,_18.blockNode===_18.blockContainer?"first":"before");
+if(_1a.nextSibling&&this.editor.height){
+_1a.nextSibling.scrollIntoView(false);
+}
+_17=false;
+}else{
+if(dojo.isMoz){
+this._pressedEnterInBlock=_18.blockNode;
+}
+}
+}
+return _17;
+},removeTrailingBr:function(_1b){
+var _1c=/P|DIV|LI/i.test(_1b.tagName)?_1b:dijit._editor.selection.getParentOfType(_1b,["P","DIV","LI"]);
+if(!_1c){
+return;
+}
+if(_1c.lastChild){
+if((_1c.childNodes.length>1&&_1c.lastChild.nodeType==3&&/^[\s\xAD]*$/.test(_1c.lastChild.nodeValue))||(_1c.lastChild&&_1c.lastChild.tagName=="BR")){
+dojo.destroy(_1c.lastChild);
+}
+}
+if(!_1c.childNodes.length){
+_1c.innerHTML=this.bogusHtmlContent;
+}
+},_fixNewLineBehaviorForIE:function(d){
+if(this.editor.document.__INSERTED_EDITIOR_NEWLINE_CSS===undefined){
+var _1e="p{margin:0 !important;}";
+var _1f=function(_20,doc,URI){
+if(!_20){
+return null;
+}
+if(!doc){
+doc=document;
+}
+var _23=doc.createElement("style");
+_23.setAttribute("type","text/css");
+var _24=doc.getElementsByTagName("head")[0];
+if(!_24){
+
+return null;
+}else{
+_24.appendChild(_23);
+}
+if(_23.styleSheet){
+var _25=function(){
+try{
+_23.styleSheet.cssText=_20;
+}
+catch(e){
+
+}
+};
+if(_23.styleSheet.disabled){
+setTimeout(_25,10);
+}else{
+_25();
+}
+}else{
+var _26=doc.createTextNode(_20);
+_23.appendChild(_26);
+}
+return _23;
+};
+_1f(_1e,this.editor.document);
+this.editor.document.__INSERTED_EDITIOR_NEWLINE_CSS=true;
+return d;
+}
+return null;
+},regularPsToSingleLinePs:function(_27,_28){
+function _29(el){
+function _2b(_2c){
+var _2d=_2c[0].ownerDocument.createElement("p");
+_2c[0].parentNode.insertBefore(_2d,_2c[0]);
+dojo.forEach(_2c,function(_2e){
+_2d.appendChild(_2e);
+});
+};
+var _2f=0;
+var _30=[];
+var _31;
+while(_2f<el.childNodes.length){
+_31=el.childNodes[_2f];
+if(_31.nodeType==3||(_31.nodeType==1&&_31.nodeName!="BR"&&dojo.style(_31,"display")!="block")){
+_30.push(_31);
+}else{
+var _32=_31.nextSibling;
+if(_30.length){
+_2b(_30);
+_2f=(_2f+1)-_30.length;
+if(_31.nodeName=="BR"){
+dojo.destroy(_31);
+}
+}
+_30=[];
+}
+_2f++;
+}
+if(_30.length){
+_2b(_30);
+}
+};
+function _33(el){
+var _35=null;
+var _36=[];
+var _37=el.childNodes.length-1;
+for(var i=_37;i>=0;i--){
+_35=el.childNodes[i];
+if(_35.nodeName=="BR"){
+var _39=_35.ownerDocument.createElement("p");
+dojo.place(_39,el,"after");
+if(_36.length==0&&i!=_37){
+_39.innerHTML=" ";
+}
+dojo.forEach(_36,function(_3a){
+_39.appendChild(_3a);
+});
+dojo.destroy(_35);
+_36=[];
+}else{
+_36.unshift(_35);
+}
+}
+};
+var _3b=[];
+var ps=_27.getElementsByTagName("p");
+dojo.forEach(ps,function(p){
+_3b.push(p);
+});
+dojo.forEach(_3b,function(p){
+if((p.previousSibling)&&(p.previousSibling.nodeName=="P"||dojo.style(p.previousSibling,"display")!="block")){
+var _3f=p.parentNode.insertBefore(this.document.createElement("p"),p);
+_3f.innerHTML=_28?"":" ";
+}
+_33(p);
+},this.editor);
+_29(_27);
+return _27;
+},singleLinePsToRegularPs:function(_40){
+function _41(_42){
+var ps=_42.getElementsByTagName("p");
+var _44=[];
+for(var i=0;i<ps.length;i++){
+var p=ps[i];
+var _47=false;
+for(var k=0;k<_44.length;k++){
+if(_44[k]===p.parentNode){
+_47=true;
+break;
+}
+}
+if(!_47){
+_44.push(p.parentNode);
+}
+}
+return _44;
+};
+function _49(_4a){
+if(_4a.nodeType!=1||_4a.tagName!="P"){
+return dojo.style(_4a,"display")=="block";
+}else{
+if(!_4a.childNodes.length||_4a.innerHTML==" "){
+return true;
+}
+}
+return false;
+};
+var _4b=_41(_40);
+for(var i=0;i<_4b.length;i++){
+var _4d=_4b[i];
+var _4e=null;
+var _4f=_4d.firstChild;
+var _50=null;
+while(_4f){
+if(_4f.nodeType!="1"||_4f.tagName!="P"){
+_4e=null;
+}else{
+if(_49(_4f)){
+_50=_4f;
+_4e=null;
+}else{
+if(_4e==null){
+_4e=_4f;
+}else{
+if((!_4e.lastChild||_4e.lastChild.nodeName!="BR")&&(_4f.firstChild)&&(_4f.firstChild.nodeName!="BR")){
+_4e.appendChild(this.editor.document.createElement("br"));
+}
+while(_4f.firstChild){
+_4e.appendChild(_4f.firstChild);
+}
+_50=_4f;
+}
+}
+}
+_4f=_4f.nextSibling;
+if(_50){
+dojo.destroy(_50);
+_50=null;
+}
+}
+}
+return _40;
+}});
+}
diff --git a/dijit/_editor/plugins/FontChoice.js b/dijit/_editor/plugins/FontChoice.js
new file mode 100644
index 0000000..099189f
--- /dev/null
+++ b/dijit/_editor/plugins/FontChoice.js
@@ -0,0 +1,111 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._editor.plugins.FontChoice"]){
+dojo._hasResource["dijit._editor.plugins.FontChoice"]=true;
+dojo.provide("dijit._editor.plugins.FontChoice");
+dojo.require("dijit._editor._Plugin");
+dojo.require("dijit.form.FilteringSelect");
+dojo.require("dojo.data.ItemFileReadStore");
+dojo.require("dojo.i18n");
+dojo.requireLocalization("dijit._editor","FontChoice",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.declare("dijit._editor.plugins.FontChoice",dijit._editor._Plugin,{_uniqueId:0,buttonClass:dijit.form.FilteringSelect,useDefaultCommand:false,_initButton:function(){
+var _1=this.command;
+var _2=this.custom||{fontName:this.generic?["serif","sans-serif","monospace","cursive","fantasy"]:["Arial","Times New Roman","Comic Sans MS","Courier New"],fontSize:[1,2,3,4,5,6,7],formatBlock:["p","h1","h2","h3","pre"]}[_1];
+this._availableValues=_2;
+var _3=dojo.i18n.getLocalization("dijit._editor","FontChoice");
+var _4=dojo.map(_2,function(_5){
+var _6=_3[_5]||_5;
+var _7=_6;
+switch(_1){
+case "fontName":
+_7="<div style='font-family: "+_5+"'>"+_6+"</div>";
+break;
+case "fontSize":
+_7="<font size="+_5+"'>"+_6+"</font>";
+break;
+case "formatBlock":
+_7="<"+_5+">"+_6+"</"+_5+">";
+}
+return {label:_7,name:_6,value:_5};
+});
+this.inherited(arguments,[{required:false,labelType:"html",labelAttr:"label",searchAttr:"name",store:new dojo.data.ItemFileReadStore({data:{identifier:"value",items:_4}})}]);
+this.button.attr("value","");
+this.connect(this.button,"onChange",function(_8){
+if(this.updating){
+return;
+}
+if(dojo.isIE||!this._focusHandle){
+this.editor.focus();
+}else{
+dijit.focus(this._focusHandle);
+}
+if(this.command=="fontName"&&_8.indexOf(" ")!=-1){
+_8="'"+_8+"'";
+}
+this.editor.execCommand(this.editor._normalizeCommand(this.command),_8);
+});
+},updateState:function(){
+this.inherited(arguments);
+var _e=this.editor;
+var _c=this.command;
+if(!_e||!_e.isLoaded||!_c.length){
+return;
+}
+if(this.button){
+var _b;
+try{
+_b=_e.queryCommandValue(_c)||"";
+}
+catch(e){
+_b="";
+}
+var _c=dojo.isString(_b)&&_b.match(/'([^']*)'/);
+if(_c){
+_b=_c[1];
+}
+if(this.generic&&_c=="fontName"){
+var _d={"Arial":"sans-serif","Helvetica":"sans-serif","Myriad":"sans-serif","Times":"serif","Times New Roman":"serif","Comic Sans MS":"cursive","Apple Chancery":"cursive","Courier":"monospace","Courier New":"monospace","Papyrus":"fantasy"};
+_b=_d[_b]||_b;
+}else{
+if(_c=="fontSize"&&_b.indexOf&&_b.indexOf("px")!=-1){
+var _e=parseInt(_b);
+_b={10:1,13:2,16:3,18:4,24:5,32:6,48:7}[_e]||_b;
+}
+}
+this.updating=true;
+this.button.attr("value",dojo.indexOf(this._availableValues,_b)<0?"":_b);
+delete this.updating;
+}
+if(this.editor.iframe){
+this._focusHandle=dijit.getFocus(this.editor.iframe);
+}
+},setToolbar:function(){
+this.inherited(arguments);
+var _f=this.button;
+if(!_f.id){
+_f.id=dijit._scopeName+"EditorButton-"+this.command+(this._uniqueId++);
+}
+var _10=dojo.doc.createElement("label");
+dojo.addClass(_10,"dijit dijitReset dijitLeft dijitInline");
+_10.setAttribute("for",_f.id);
+var _11=dojo.i18n.getLocalization("dijit._editor","FontChoice");
+_10.appendChild(dojo.doc.createTextNode(_11[this.command]));
+dojo.place(_10,this.button.domNode,"before");
+}});
+dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
+if(o.plugin){
+return;
+}
+switch(o.args.name){
+case "fontName":
+case "fontSize":
+case "formatBlock":
+o.plugin=new dijit._editor.plugins.FontChoice({command:o.args.name});
+}
+});
+}
diff --git a/dijit/_editor/plugins/LinkDialog.js b/dijit/_editor/plugins/LinkDialog.js
new file mode 100644
index 0000000..cd2c754
--- /dev/null
+++ b/dijit/_editor/plugins/LinkDialog.js
@@ -0,0 +1,74 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._editor.plugins.LinkDialog"]){
+dojo._hasResource["dijit._editor.plugins.LinkDialog"]=true;
+dojo.provide("dijit._editor.plugins.LinkDialog");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dijit._editor._Plugin");
+dojo.require("dijit.TooltipDialog");
+dojo.require("dijit.form.Button");
+dojo.require("dijit.form.ValidationTextBox");
+dojo.require("dojo.i18n");
+dojo.require("dojo.string");
+dojo.requireLocalization("dijit._editor","LinkDialog",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.declare("dijit._editor.plugins.LinkDialog",dijit._editor._Plugin,{buttonClass:dijit.form.DropDownButton,useDefaultCommand:false,urlRegExp:"((https?|ftps?)\\://|)(((?:(?:[\\da-zA-Z](?:[-\\da-zA-Z]{0,61}[\\da-zA-Z])?)\\.)*(?:[a-zA-Z](?:[-\\da-zA-Z]{0,6}[\\da-zA-Z])?)\\.?)|(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])|(0[xX]0*[\\da-fA-F]?[\\da-fA-F]\\.){3}0[xX]0*[\\da-fA-F]?[\\da-fA-F]|(0+[0-3][0-7][0-7]\\.){3}0+[0-3][0-7][0-7]|(0|[1-9]\\d{0, [...]
+var _1=this;
+this.tag=this.command=="insertImage"?"img":"a";
+var _2=dojo.i18n.getLocalization("dijit._editor","LinkDialog",this.lang);
+var _3=(this.dropDown=new dijit.TooltipDialog({title:_2[this.command+"Title"],execute:dojo.hitch(this,"setValue"),onOpen:function(){
+_1._onOpenDialog();
+dijit.TooltipDialog.prototype.onOpen.apply(this,arguments);
+},onCancel:function(){
+setTimeout(dojo.hitch(_1,"_onCloseDialog"),0);
+},onClose:dojo.hitch(this,"_onCloseDialog")}));
+_2.urlRegExp=this.urlRegExp;
+_2.id=dijit.getUniqueId(this.editor.id);
+this._setContent(_3.title+"<div style='border-bottom: 1px black solid;padding-bottom:2pt;margin-bottom:4pt'></div>"+dojo.string.substitute(this.linkDialogTemplate,_2));
+_3.startup();
+this.inherited(arguments);
+},_setContent:function(_4){
+this.dropDown.attr("content",_4);
+},setValue:function(_5){
+this._onCloseDialog();
+if(dojo.isIE){
+var a=dojo.withGlobal(this.editor.window,"getAncestorElement",dijit._editor.selection,[this.tag]);
+if(a){
+dojo.withGlobal(this.editor.window,"selectElement",dijit._editor.selection,[a]);
+}
+}
+_5.tag=this.tag;
+_5.refAttr=this.tag=="img"?"src":"href";
+var _7="<${tag} ${refAttr}='${urlInput}' _djrealurl='${urlInput}'"+(_5.tag=="img"?" alt='${textInput}'>":">${textInput}")+"</${tag}>";
+this.editor.execCommand("inserthtml",dojo.string.substitute(_7,_5));
+},_onCloseDialog:function(){
+this.editor.focus();
+},_onOpenDialog:function(){
+var a=dojo.withGlobal(this.editor.window,"getAncestorElement",dijit._editor.selection,[this.tag]);
+var _9,_a;
+if(a){
+_9=a.getAttribute("_djrealurl");
+_a=this.tag=="img"?a.getAttribute("alt"):a.textContent||a.innerText;
+dojo.withGlobal(this.editor.window,"selectElement",dijit._editor.selection,[a,true]);
+}else{
+_a=dojo.withGlobal(this.editor.window,dijit._editor.selection.getSelectedText);
+}
+this.dropDown.reset();
+this.dropDown.setValues({urlInput:_9||"",textInput:_a||""});
+}});
+dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
+if(o.plugin){
+return;
+}
+switch(o.args.name){
+case "createLink":
+case "insertImage":
+o.plugin=new dijit._editor.plugins.LinkDialog({command:o.args.name});
+}
+});
+}
diff --git a/dijit/_editor/plugins/TabIndent.js b/dijit/_editor/plugins/TabIndent.js
new file mode 100644
index 0000000..a57a274
--- /dev/null
+++ b/dijit/_editor/plugins/TabIndent.js
@@ -0,0 +1,51 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._editor.plugins.TabIndent"]){
+dojo._hasResource["dijit._editor.plugins.TabIndent"]=true;
+dojo.provide("dijit._editor.plugins.TabIndent");
+dojo.experimental("dijit._editor.plugins.TabIndent");
+dojo.require("dijit._editor._Plugin");
+dojo.declare("dijit._editor.plugins.TabIndent",dijit._editor._Plugin,{useDefaultCommand:false,buttonClass:dijit.form.ToggleButton,command:"tabIndent",_initButton:function(){
+this.inherited("_initButton",arguments);
+this.connect(this.button,"onClick",this._tabIndent);
+},updateState:function(){
+var _e=this.editor;
+var _c=this.command;
+if(!_e){
+return;
+}
+if(!_e.isLoaded){
+return;
+}
+if(!_c.length){
+return;
+}
+if(this.button){
+try{
+var _3=_e.isTabIndent;
+if(typeof this.button.checked=="boolean"){
+this.button.attr("checked",_3);
+}
+}
+catch(e){
+
+}
+}
+},_tabIndent:function(){
+this.editor.isTabIndent=!this.editor.isTabIndent;
+}});
+dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
+if(o.plugin){
+return;
+}
+switch(o.args.name){
+case "tabIndent":
+o.plugin=new dijit._editor.plugins.TabIndent({command:o.args.name});
+}
+});
+}
diff --git a/dijit/_editor/plugins/TextColor.js b/dijit/_editor/plugins/TextColor.js
new file mode 100644
index 0000000..5f0ac31
--- /dev/null
+++ b/dijit/_editor/plugins/TextColor.js
@@ -0,0 +1,29 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._editor.plugins.TextColor"]){
+dojo._hasResource["dijit._editor.plugins.TextColor"]=true;
+dojo.provide("dijit._editor.plugins.TextColor");
+dojo.require("dijit._editor._Plugin");
+dojo.require("dijit.ColorPalette");
+dojo.declare("dijit._editor.plugins.TextColor",dijit._editor._Plugin,{buttonClass:dijit.form.DropDownButton,constructor:function(){
+this.dropDown=new dijit.ColorPalette();
+this.connect(this.dropDown,"onChange",function(_1){
+this.editor.execCommand(this.command,_1);
+});
+}});
+dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
+if(o.plugin){
+return;
+}
+switch(o.args.name){
+case "foreColor":
+case "hiliteColor":
+o.plugin=new dijit._editor.plugins.TextColor({command:o.args.name});
+}
+});
+}
diff --git a/dijit/_editor/plugins/ToggleDir.js b/dijit/_editor/plugins/ToggleDir.js
new file mode 100644
index 0000000..dc3dc4a
--- /dev/null
+++ b/dijit/_editor/plugins/ToggleDir.js
@@ -0,0 +1,31 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._editor.plugins.ToggleDir"]){
+dojo._hasResource["dijit._editor.plugins.ToggleDir"]=true;
+dojo.provide("dijit._editor.plugins.ToggleDir");
+dojo.experimental("dijit._editor.plugins.ToggleDir");
+dojo.require("dijit._editor._Plugin");
+dojo.declare("dijit._editor.plugins.ToggleDir",dijit._editor._Plugin,{useDefaultCommand:false,command:"toggleDir",_initButton:function(){
+this.inherited("_initButton",arguments);
+this.connect(this.button,"onClick",this._toggleDir);
+},updateState:function(){
+},_toggleDir:function(){
+var _1=this.editor.editorObject.contentWindow.document.documentElement;
+var _2=dojo.getComputedStyle(_1).direction=="ltr";
+_1.dir=_2?"rtl":"ltr";
+}});
+dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
+if(o.plugin){
+return;
+}
+switch(o.args.name){
+case "toggleDir":
+o.plugin=new dijit._editor.plugins.ToggleDir({command:o.args.name});
+}
+});
+}
diff --git a/dijit/_editor/range.js b/dijit/_editor/range.js
new file mode 100644
index 0000000..c85da1e
--- /dev/null
+++ b/dijit/_editor/range.js
@@ -0,0 +1,453 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._editor.range"]){
+dojo._hasResource["dijit._editor.range"]=true;
+dojo.provide("dijit._editor.range");
+dijit.range={};
+dijit.range.getIndex=function(_1,_2){
+var _3=[],_4=[];
+var _5=_2;
+var _6=_1;
+var _7,n;
+while(_1!=_5){
+var i=0;
+_7=_1.parentNode;
+while((n=_7.childNodes[i++])){
+if(n===_1){
+--i;
+break;
+}
+}
+if(i>=_7.childNodes.length){
+dojo.debug("Error finding index of a node in dijit.range.getIndex");
+}
+_3.unshift(i);
+_4.unshift(i-_7.childNodes.length);
+_1=_7;
+}
+if(_3.length>0&&_6.nodeType==3){
+n=_6.previousSibling;
+while(n&&n.nodeType==3){
+_3[_3.length-1]--;
+n=n.previousSibling;
+}
+n=_6.nextSibling;
+while(n&&n.nodeType==3){
+_4[_4.length-1]++;
+n=n.nextSibling;
+}
+}
+return {o:_3,r:_4};
+};
+dijit.range.getNode=function(_a,_b){
+if(!dojo.isArray(_a)||_a.length==0){
+return _b;
+}
+var _c=_b;
+dojo.every(_a,function(i){
+if(i>=0&&i<_c.childNodes.length){
+_c=_c.childNodes[i];
+}else{
+_c=null;
+
+return false;
+}
+return true;
+});
+return _c;
+};
+dijit.range.getCommonAncestor=function(n1,n2){
+var _10=function(n){
+var as=[];
+while(n){
+as.unshift(n);
+if(n.nodeName!="BODY"){
+n=n.parentNode;
+}else{
+break;
+}
+}
+return as;
+};
+var _13=_10(n1);
+var _14=_10(n2);
+var m=Math.min(_13.length,_14.length);
+var com=_13[0];
+for(var i=1;i<m;i++){
+if(_13[i]===_14[i]){
+com=_13[i];
+}else{
+break;
+}
+}
+return com;
+};
+dijit.range.getAncestor=function(_18,_19,_1a){
+_1a=_1a||_18.ownerDocument.body;
+while(_18&&_18!==_1a){
+var _1b=_18.nodeName.toUpperCase();
+if(_19.test(_1b)){
+return _18;
+}
+_18=_18.parentNode;
+}
+return null;
+};
+dijit.range.BlockTagNames=/^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/;
+dijit.range.getBlockAncestor=function(_1c,_1d,_1e){
+_1e=_1e||_1c.ownerDocument.body;
+_1d=_1d||dijit.range.BlockTagNames;
+var _1f=null,_20;
+while(_1c&&_1c!==_1e){
+var _21=_1c.nodeName.toUpperCase();
+if(!_1f&&_1d.test(_21)){
+_1f=_1c;
+}
+if(!_20&&(/^(?:BODY|TD|TH|CAPTION)$/).test(_21)){
+_20=_1c;
+}
+_1c=_1c.parentNode;
+}
+return {blockNode:_1f,blockContainer:_20||_1c.ownerDocument.body};
+};
+dijit.range.atBeginningOfContainer=function(_22,_23,_24){
+var _25=false;
+var _26=(_24==0);
+if(!_26&&_23.nodeType==3){
+if(dojo.trim(_23.nodeValue.substr(0,_24))==0){
+_26=true;
+}
+}
+if(_26){
+var _27=_23;
+_25=true;
+while(_27&&_27!==_22){
+if(_27.previousSibling){
+_25=false;
+break;
+}
+_27=_27.parentNode;
+}
+}
+return _25;
+};
+dijit.range.atEndOfContainer=function(_28,_29,_2a){
+var _2b=false;
+var _2c=(_2a==(_29.length||_29.childNodes.length));
+if(!_2c&&_29.nodeType==3){
+if(dojo.trim(_29.nodeValue.substr(_2a))==0){
+_2c=true;
+}
+}
+if(_2c){
+var _2d=_29;
+_2b=true;
+while(_2d&&_2d!==_28){
+if(_2d.nextSibling){
+_2b=false;
+break;
+}
+_2d=_2d.parentNode;
+}
+}
+return _2b;
+};
+dijit.range.adjacentNoneTextNode=function(_2e,_2f){
+var _30=_2e;
+var len=(0-_2e.length)||0;
+var _32=_2f?"nextSibling":"previousSibling";
+while(_30){
+if(_30.nodeType!=3){
+break;
+}
+len+=_30.length;
+_30=_30[_32];
+}
+return [_30,len];
+};
+dijit.range._w3c=Boolean(window["getSelection"]);
+dijit.range.create=function(){
+if(dijit.range._w3c){
+return dojo.doc.createRange();
+}else{
+return new dijit.range.W3CRange;
+}
+};
+dijit.range.getSelection=function(win,_34){
+if(dijit.range._w3c){
+return win.getSelection();
+}else{
+var s=new dijit.range.ie.selection(win);
+if(!_34){
+s._getCurrentSelection();
+}
+return s;
+}
+};
+if(!dijit.range._w3c){
+dijit.range.ie={cachedSelection:{},selection:function(win){
+this._ranges=[];
+this.addRange=function(r,_38){
+this._ranges.push(r);
+if(!_38){
+r._select();
+}
+this.rangeCount=this._ranges.length;
+};
+this.removeAllRanges=function(){
+this._ranges=[];
+this.rangeCount=0;
+};
+var _39=function(){
+var r=win.document.selection.createRange();
+var _3b=win.document.selection.type.toUpperCase();
+if(_3b=="CONTROL"){
+return new dijit.range.W3CRange(dijit.range.ie.decomposeControlRange(r));
+}else{
+return new dijit.range.W3CRange(dijit.range.ie.decomposeTextRange(r));
+}
+};
+this.getRangeAt=function(i){
+return this._ranges[i];
+};
+this._getCurrentSelection=function(){
+this.removeAllRanges();
+var r=_39();
+if(r){
+this.addRange(r,true);
+}
+};
+},decomposeControlRange:function(_3e){
+var _3f=_3e.item(0),_40=_3e.item(_3e.length-1);
+var _41=_3f.parentNode,_42=_40.parentNode;
+var _43=dijit.range.getIndex(_3f,_41).o;
+var _44=dijit.range.getIndex(_40,_42).o+1;
+return [_41,_43,_42,_44];
+},getEndPoint:function(_45,end){
+var _47=_45.duplicate();
+_47.collapse(!end);
+var _48="EndTo"+(end?"End":"Start");
+var _49=_47.parentElement();
+var _4a,_4b,_4c;
+if(_49.childNodes.length>0){
+dojo.every(_49.childNodes,function(_4d,i){
+var _4f;
+if(_4d.nodeType!=3){
+_47.moveToElementText(_4d);
+if(_47.compareEndPoints(_48,_45)>0){
+_4a=_4d.previousSibling;
+if(_4c&&_4c.nodeType==3){
+_4a=_4c;
+_4f=true;
+}else{
+_4a=_49;
+_4b=i;
+return false;
+}
+}else{
+if(i==_49.childNodes.length-1){
+_4a=_49;
+_4b=_49.childNodes.length;
+return false;
+}
+}
+}else{
+if(i==_49.childNodes.length-1){
+_4a=_4d;
+_4f=true;
+}
+}
+if(_4f&&_4a){
+var _50=dijit.range.adjacentNoneTextNode(_4a)[0];
+if(_50){
+_4a=_50.nextSibling;
+}else{
+_4a=_49.firstChild;
+}
+var _51=dijit.range.adjacentNoneTextNode(_4a);
+_50=_51[0];
+var _52=_51[1];
+if(_50){
+_47.moveToElementText(_50);
+_47.collapse(false);
+}else{
+_47.moveToElementText(_49);
+}
+_47.setEndPoint(_48,_45);
+_4b=_47.text.length-_52;
+return false;
+}
+_4c=_4d;
+return true;
+});
+}else{
+_4a=_49;
+_4b=0;
+}
+if(!end&&_4a.nodeType!=3&&_4b==_4a.childNodes.length){
+if(_4a.nextSibling&&_4a.nextSibling.nodeType==3){
+_4a=_4a.nextSibling;
+_4b=0;
+}
+}
+return [_4a,_4b];
+},setEndPoint:function(_53,_54,_55){
+var _56=_53.duplicate(),_57,len;
+if(_54.nodeType!=3){
+if(_55>0){
+_57=_54.childNodes[_55-1];
+if(_57.nodeType==3){
+_54=_57;
+_55=_57.length;
+}else{
+if(_57.nextSibling&&_57.nextSibling.nodeType==3){
+_54=_57.nextSibling;
+_55=0;
+}else{
+_56.moveToElementText(_57.nextSibling?_57:_54);
+var _59=_57.parentNode.insertBefore(document.createTextNode(" "),_57.nextSibling);
+_56.collapse(false);
+_59.parentNode.removeChild(_59);
+}
+}
+}else{
+_56.moveToElementText(_54);
+_56.collapse(true);
+}
+}
+if(_54.nodeType==3){
+var _5a=dijit.range.adjacentNoneTextNode(_54);
+var _5b=_5a[0];
+len=_5a[1];
+if(_5b){
+_56.moveToElementText(_5b);
+_56.collapse(false);
+if(_5b.contentEditable!="inherit"){
+len++;
+}
+}else{
+_56.moveToElementText(_54.parentNode);
+_56.collapse(true);
+}
+_55+=len;
+if(_55>0){
+if(_56.move("character",_55)!=_55){
+console.error("Error when moving!");
+}
+}
+}
+return _56;
+},decomposeTextRange:function(_5c){
+var _5d=dijit.range.ie.getEndPoint(_5c);
+var _5e=_5d[0],_5f=_5d[1];
+var _60=_5d[0],_61=_5d[1];
+if(_5c.htmlText.length){
+if(_5c.htmlText==_5c.text){
+_61=_5f+_5c.text.length;
+}else{
+_5d=dijit.range.ie.getEndPoint(_5c,true);
+_60=_5d[0],_61=_5d[1];
+}
+}
+return [_5e,_5f,_60,_61];
+},setRange:function(_62,_63,_64,_65,_66,_67){
+var _68=dijit.range.ie.setEndPoint(_62,_63,_64);
+_62.setEndPoint("StartToStart",_68);
+if(!_67){
+var end=dijit.range.ie.setEndPoint(_62,_65,_66);
+}
+_62.setEndPoint("EndToEnd",end||_68);
+return _62;
+}};
+dojo.declare("dijit.range.W3CRange",null,{constructor:function(){
+if(arguments.length>0){
+this.setStart(arguments[0][0],arguments[0][1]);
+this.setEnd(arguments[0][2],arguments[0][3]);
+}else{
+this.commonAncestorContainer=null;
+this.startContainer=null;
+this.startOffset=0;
+this.endContainer=null;
+this.endOffset=0;
+this.collapsed=true;
+}
+},_updateInternal:function(){
+if(this.startContainer!==this.endContainer){
+this.commonAncestorContainer=dijit.range.getCommonAncestor(this.startContainer,this.endContainer);
+}else{
+this.commonAncestorContainer=this.startContainer;
+}
+this.collapsed=(this.startContainer===this.endContainer)&&(this.startOffset==this.endOffset);
+},setStart:function(_6a,_6b){
+_6b=parseInt(_6b);
+if(this.startContainer===_6a&&this.startOffset==_6b){
+return;
+}
+delete this._cachedBookmark;
+this.startContainer=_6a;
+this.startOffset=_6b;
+if(!this.endContainer){
+this.setEnd(_6a,_6b);
+}else{
+this._updateInternal();
+}
+},setEnd:function(_6c,_6d){
+_6d=parseInt(_6d);
+if(this.endContainer===_6c&&this.endOffset==_6d){
+return;
+}
+delete this._cachedBookmark;
+this.endContainer=_6c;
+this.endOffset=_6d;
+if(!this.startContainer){
+this.setStart(_6c,_6d);
+}else{
+this._updateInternal();
+}
+},setStartAfter:function(_6e,_6f){
+this._setPoint("setStart",_6e,_6f,1);
+},setStartBefore:function(_70,_71){
+this._setPoint("setStart",_70,_71,0);
+},setEndAfter:function(_72,_73){
+this._setPoint("setEnd",_72,_73,1);
+},setEndBefore:function(_74,_75){
+this._setPoint("setEnd",_74,_75,0);
+},_setPoint:function(_76,_77,_78,ext){
+var _7a=dijit.range.getIndex(_77,_77.parentNode).o;
+this[_76](_77.parentNode,_7a.pop()+ext);
+},_getIERange:function(){
+var r=(this._body||this.endContainer.ownerDocument.body).createTextRange();
+dijit.range.ie.setRange(r,this.startContainer,this.startOffset,this.endContainer,this.endOffset,this.collapsed);
+return r;
+},getBookmark:function(_7c){
+this._getIERange();
+return this._cachedBookmark;
+},_select:function(){
+var r=this._getIERange();
+r.select();
+},deleteContents:function(){
+var r=this._getIERange();
+r.pasteHTML("");
+this.endContainer=this.startContainer;
+this.endOffset=this.startOffset;
+this.collapsed=true;
+},cloneRange:function(){
+var r=new dijit.range.W3CRange([this.startContainer,this.startOffset,this.endContainer,this.endOffset]);
+r._body=this._body;
+return r;
+},detach:function(){
+this._body=null;
+this.commonAncestorContainer=null;
+this.startContainer=null;
+this.startOffset=0;
+this.endContainer=null;
+this.endOffset=0;
+this.collapsed=true;
+}});
+}
+}
diff --git a/dijit/_editor/selection.js b/dijit/_editor/selection.js
new file mode 100644
index 0000000..edb0aac
--- /dev/null
+++ b/dijit/_editor/selection.js
@@ -0,0 +1,202 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._editor.selection"]){
+dojo._hasResource["dijit._editor.selection"]=true;
+dojo.provide("dijit._editor.selection");
+dojo.mixin(dijit._editor.selection,{getType:function(){
+if(dojo.doc.selection){
+return dojo.doc.selection.type.toLowerCase();
+}else{
+var _1="text";
+var _2;
+try{
+_2=dojo.global.getSelection();
+}
+catch(e){
+}
+if(_2&&_2.rangeCount==1){
+var _3=_2.getRangeAt(0);
+if((_3.startContainer==_3.endContainer)&&((_3.endOffset-_3.startOffset)==1)&&(_3.startContainer.nodeType!=3)){
+_1="control";
+}
+}
+return _1;
+}
+},getSelectedText:function(){
+if(dojo.doc.selection){
+if(dijit._editor.selection.getType()=="control"){
+return null;
+}
+return dojo.doc.selection.createRange().text;
+}else{
+var _4=dojo.global.getSelection();
+if(_4){
+return _4.toString();
+}
+}
+return "";
+},getSelectedHtml:function(){
+if(dojo.doc.selection){
+if(dijit._editor.selection.getType()=="control"){
+return null;
+}
+return dojo.doc.selection.createRange().htmlText;
+}else{
+var _5=dojo.global.getSelection();
+if(_5&&_5.rangeCount){
+var _6=_5.getRangeAt(0).cloneContents();
+var _7=dojo.doc.createElement("div");
+_7.appendChild(_6);
+return _7.innerHTML;
+}
+return null;
+}
+},getSelectedElement:function(){
+if(dijit._editor.selection.getType()=="control"){
+if(dojo.doc.selection){
+var _8=dojo.doc.selection.createRange();
+if(_8&&_8.item){
+return dojo.doc.selection.createRange().item(0);
+}
+}else{
+var _9=dojo.global.getSelection();
+return _9.anchorNode.childNodes[_9.anchorOffset];
+}
+}
+return null;
+},getParentElement:function(){
+if(dijit._editor.selection.getType()=="control"){
+var p=this.getSelectedElement();
+if(p){
+return p.parentNode;
+}
+}else{
+if(dojo.doc.selection){
+var r=dojo.doc.selection.createRange();
+r.collapse(true);
+return r.parentElement();
+}else{
+var _c=dojo.global.getSelection();
+if(_c){
+var _d=_c.anchorNode;
+while(_d&&(_d.nodeType!=1)){
+_d=_d.parentNode;
+}
+return _d;
+}
+}
+}
+return null;
+},hasAncestorElement:function(_e){
+return this.getAncestorElement.apply(this,arguments)!=null;
+},getAncestorElement:function(_f){
+var _10=this.getSelectedElement()||this.getParentElement();
+return this.getParentOfType(_10,arguments);
+},isTag:function(_11,_12){
+if(_11&&_11.tagName){
+var _13=_11.tagName.toLowerCase();
+for(var i=0;i<_12.length;i++){
+var _15=String(_12[i]).toLowerCase();
+if(_13==_15){
+return _15;
+}
+}
+}
+return "";
+},getParentOfType:function(_16,_17){
+while(_16){
+if(this.isTag(_16,_17).length){
+return _16;
+}
+_16=_16.parentNode;
+}
+return null;
+},collapse:function(_18){
+if(window["getSelection"]){
+var _19=dojo.global.getSelection();
+if(_19.removeAllRanges){
+if(_18){
+_19.collapseToStart();
+}else{
+_19.collapseToEnd();
+}
+}else{
+_19.collapse(_18);
+}
+}else{
+if(dojo.doc.selection){
+var _1a=dojo.doc.selection.createRange();
+_1a.collapse(_18);
+_1a.select();
+}
+}
+},remove:function(){
+var _s=dojo.doc.selection;
+if(_s){
+if(_s.type.toLowerCase()!="none"){
+_s.clear();
+}
+return _s;
+}else{
+_s=dojo.global.getSelection();
+_s.deleteFromDocument();
+return _s;
+}
+},selectElementChildren:function(_1c,_1d){
+var _1e=dojo.global;
+var _1f=dojo.doc;
+_1c=dojo.byId(_1c);
+if(_1f.selection&&dojo.body().createTextRange){
+var _20=_1c.ownerDocument.body.createTextRange();
+_20.moveToElementText(_1c);
+if(!_1d){
+try{
+_20.select();
+}
+catch(e){
+}
+}
+}else{
+if(_1e.getSelection){
+var _21=_1e.getSelection();
+if(_21.setBaseAndExtent){
+_21.setBaseAndExtent(_1c,0,_1c,_1c.innerText.length-1);
+}else{
+if(_21.selectAllChildren){
+_21.selectAllChildren(_1c);
+}
+}
+}
+}
+},selectElement:function(_22,_23){
+var _24,_25=dojo.doc;
+_22=dojo.byId(_22);
+if(_25.selection&&dojo.body().createTextRange){
+try{
+_24=dojo.body().createControlRange();
+_24.addElement(_22);
+if(!_23){
+_24.select();
+}
+}
+catch(e){
+this.selectElementChildren(_22,_23);
+}
+}else{
+if(dojo.global.getSelection){
+var _26=dojo.global.getSelection();
+if(_26.removeAllRanges){
+_24=_25.createRange();
+_24.selectNode(_22);
+_26.removeAllRanges();
+_26.addRange(_24);
+}
+}
+}
+}});
+}
diff --git a/dijit/_tree/dndContainer.js b/dijit/_tree/dndContainer.js
new file mode 100644
index 0000000..d8c09ee
--- /dev/null
+++ b/dijit/_tree/dndContainer.js
@@ -0,0 +1,51 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._tree.dndContainer"]){
+dojo._hasResource["dijit._tree.dndContainer"]=true;
+dojo.provide("dijit._tree.dndContainer");
+dojo.require("dojo.dnd.common");
+dojo.require("dojo.dnd.Container");
+dojo.declare("dijit._tree.dndContainer",null,{constructor:function(_1,_2){
+this.tree=_1;
+this.node=_1.domNode;
+dojo.mixin(this,_2);
+this.map={};
+this.current=null;
+this.containerState="";
+dojo.addClass(this.node,"dojoDndContainer");
+if(!(_2&&_2._skipStartup)){
+this.startup();
+}
+this.events=[dojo.connect(this.node,"onmouseenter",this,"onOverEvent"),dojo.connect(this.node,"onmouseleave",this,"onOutEvent"),dojo.connect(this.tree,"_onNodeMouseEnter",this,"onMouseOver"),dojo.connect(this.tree,"_onNodeMouseLeave",this,"onMouseOut"),dojo.connect(this.node,"ondragstart",dojo,"stopEvent"),dojo.connect(this.node,"onselectstart",dojo,"stopEvent")];
+},getItem:function(_3){
+return this.selection[_3];
+},destroy:function(){
+dojo.forEach(this.events,dojo.disconnect);
+this.node=this.parent=null;
+},onMouseOver:function(_4,_5){
+this.current=_4.rowNode;
+this.currentWidget=_4;
+},onMouseOut:function(_6,_7){
+this.current=null;
+this.currentWidget=null;
+},_changeState:function(_8,_9){
+var _a="dojoDnd"+_8;
+var _b=_8.toLowerCase()+"State";
+dojo.removeClass(this.node,_a+this[_b]);
+dojo.addClass(this.node,_a+_9);
+this[_b]=_9;
+},_addItemClass:function(_c,_d){
+dojo.addClass(_c,"dojoDndItem"+_d);
+},_removeItemClass:function(_e,_f){
+dojo.removeClass(_e,"dojoDndItem"+_f);
+},onOverEvent:function(){
+this._changeState("Container","Over");
+},onOutEvent:function(){
+this._changeState("Container","");
+}});
+}
diff --git a/dijit/_tree/dndSelector.js b/dijit/_tree/dndSelector.js
new file mode 100644
index 0000000..fc10f1b
--- /dev/null
+++ b/dijit/_tree/dndSelector.js
@@ -0,0 +1,131 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._tree.dndSelector"]){
+dojo._hasResource["dijit._tree.dndSelector"]=true;
+dojo.provide("dijit._tree.dndSelector");
+dojo.require("dojo.dnd.common");
+dojo.require("dijit._tree.dndContainer");
+dojo.declare("dijit._tree.dndSelector",dijit._tree.dndContainer,{constructor:function(_1,_2){
+this.selection={};
+this.anchor=null;
+this.simpleSelection=false;
+this.events.push(dojo.connect(this.tree.domNode,"onmousedown",this,"onMouseDown"),dojo.connect(this.tree.domNode,"onmouseup",this,"onMouseUp"));
+},singular:false,getSelectedItems:function(){
+var _3=[];
+for(var i in this.selection){
+_3.push(dijit.getEnclosingWidget(this.selection[i]).item);
+}
+return _3;
+},getSelectedNodes:function(){
+return this.selection;
+},selectNone:function(){
+return this._removeSelection()._removeAnchor();
+},insertItems:function(_5,_6){
+},destroy:function(){
+dijit._tree.dndSelector.superclass.destroy.call(this);
+this.selection=this.anchor=null;
+},onMouseDown:function(e){
+if(!this.current){
+return;
+}
+if(e.button==2){
+return;
+}
+var _8=dijit.getEnclosingWidget(this.current).item;
+var id=this.tree.model.getIdentity(_8);
+if(!this.current.id){
+this.current.id=id;
+}
+if(!this.current.type){
+this.current.type="data";
+}
+if(!this.singular&&!dojo.dnd.getCopyKeyState(e)&&!e.shiftKey&&(this.current.id in this.selection)){
+this.simpleSelection=true;
+dojo.stopEvent(e);
+return;
+}
+if(this.singular){
+if(this.anchor==this.current){
+if(dojo.dnd.getCopyKeyState(e)){
+this.selectNone();
+}
+}else{
+this.selectNone();
+this.anchor=this.current;
+this._addItemClass(this.anchor,"Anchor");
+this.selection[this.current.id]=this.current;
+}
+}else{
+if(!this.singular&&e.shiftKey){
+if(dojo.dnd.getCopyKeyState(e)){
+}else{
+}
+}else{
+if(dojo.dnd.getCopyKeyState(e)){
+if(this.anchor==this.current){
+delete this.selection[this.anchor.id];
+this._removeAnchor();
+}else{
+if(this.current.id in this.selection){
+this._removeItemClass(this.current,"Selected");
+delete this.selection[this.current.id];
+}else{
+if(this.anchor){
+this._removeItemClass(this.anchor,"Anchor");
+this._addItemClass(this.anchor,"Selected");
+}
+this.anchor=this.current;
+this._addItemClass(this.current,"Anchor");
+this.selection[this.current.id]=this.current;
+}
+}
+}else{
+var _8=dijit.getEnclosingWidget(this.current).item;
+var id=this.tree.model.getIdentity(_8);
+if(!(id in this.selection)){
+this.selectNone();
+this.anchor=this.current;
+this._addItemClass(this.current,"Anchor");
+this.selection[id]=this.current;
+}
+}
+}
+}
+dojo.stopEvent(e);
+},onMouseUp:function(e){
+if(!this.simpleSelection){
+return;
+}
+this.simpleSelection=false;
+this.selectNone();
+if(this.current){
+this.anchor=this.current;
+this._addItemClass(this.anchor,"Anchor");
+this.selection[this.current.id]=this.current;
+}
+},_removeSelection:function(){
+var e=dojo.dnd._empty;
+for(var i in this.selection){
+if(i in e){
+continue;
+}
+var _d=dojo.byId(i);
+if(_d){
+this._removeItemClass(_d,"Selected");
+}
+}
+this.selection={};
+return this;
+},_removeAnchor:function(){
+if(this.anchor){
+this._removeItemClass(this.anchor,"Anchor");
+this.anchor=null;
+}
+return this;
+}});
+}
diff --git a/dijit/_tree/dndSource.js b/dijit/_tree/dndSource.js
new file mode 100644
index 0000000..9cf7658
--- /dev/null
+++ b/dijit/_tree/dndSource.js
@@ -0,0 +1,231 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit._tree.dndSource"]){
+dojo._hasResource["dijit._tree.dndSource"]=true;
+dojo.provide("dijit._tree.dndSource");
+dojo.require("dijit._tree.dndSelector");
+dojo.require("dojo.dnd.Manager");
+dojo.declare("dijit._tree.dndSource",dijit._tree.dndSelector,{isSource:true,accept:["text"],copyOnly:false,dragThreshold:0,betweenThreshold:0,skipForm:false,constructor:function(_1,_2){
+if(!_2){
+_2={};
+}
+dojo.mixin(this,_2);
+this.isSource=typeof _2.isSource=="undefined"?true:_2.isSource;
+var _3=_2.accept instanceof Array?_2.accept:["text"];
+this.accept=null;
+if(_3.length){
+this.accept={};
+for(var i=0;i<_3.length;++i){
+this.accept[_3[i]]=1;
+}
+}
+this.isDragging=false;
+this.mouseDown=false;
+this.targetAnchor=null;
+this.targetBox=null;
+this.dropPosition="";
+this._lastX=0;
+this._lastY=0;
+this.sourceState="";
+if(this.isSource){
+dojo.addClass(this.node,"dojoDndSource");
+}
+this.targetState="";
+if(this.accept){
+dojo.addClass(this.node,"dojoDndTarget");
+}
+this.topics=[dojo.subscribe("/dnd/source/over",this,"onDndSourceOver"),dojo.subscribe("/dnd/start",this,"onDndStart"),dojo.subscribe("/dnd/drop",this,"onDndDrop"),dojo.subscribe("/dnd/cancel",this,"onDndCancel")];
+this.events.push(dojo.connect(this.node,"onmousemove",this,"onMouseMove"));
+},startup:function(){
+},checkAcceptance:function(_5,_6){
+return true;
+},copyState:function(_7){
+return this.copyOnly||_7;
+},destroy:function(){
+this.inherited("destroy",arguments);
+dojo.forEach(this.topics,dojo.unsubscribe);
+this.targetAnchor=null;
+},_onDragMouse:function(e){
+var m=dojo.dnd.manager(),_a=this.targetAnchor,_b=this.current,_c=this.currentWidget,_d=this.dropPosition;
+var _e="Over";
+if(_b&&this.betweenThreshold>0){
+if(!this.targetBox||_a!=_b){
+this.targetBox={xy:dojo.coords(_b,true),w:_b.offsetWidth,h:_b.offsetHeight};
+}
+if((e.pageY-this.targetBox.xy.y)<=this.betweenThreshold){
+_e="Before";
+}else{
+if((e.pageY-this.targetBox.xy.y)>=(this.targetBox.h-this.betweenThreshold)){
+_e="After";
+}
+}
+}
+if(_b!=_a||_e!=_d){
+if(_a){
+this._removeItemClass(_a,_d);
+}
+if(_b){
+this._addItemClass(_b,_e);
+}
+if(!_b){
+m.canDrop(false);
+}else{
+if(_c==this.tree.rootNode&&_e!="Over"){
+m.canDrop(false);
+}else{
+if(m.source==this&&(_b.id in this.selection)){
+m.canDrop(false);
+}else{
+if(this.checkItemAcceptance(_b,m.source,_e.toLowerCase())){
+m.canDrop(true);
+}else{
+m.canDrop(false);
+}
+}
+}
+}
+this.targetAnchor=_b;
+this.dropPosition=_e;
+}
+},onMouseMove:function(e){
+if(this.isDragging&&this.targetState=="Disabled"){
+return;
+}
+var m=dojo.dnd.manager();
+if(this.isDragging){
+if(this.betweenThreshold>0){
+this._onDragMouse(e);
+}
+}else{
+if(this.mouseDown&&this.isSource&&(Math.abs(e.pageX-this._lastX)>=this.dragThreshold||Math.abs(e.pageY-this._lastY)>=this.dragThreshold)){
+var n=this.getSelectedNodes();
+var _12=[];
+for(var i in n){
+_12.push(n[i]);
+}
+if(_12.length){
+m.startDrag(this,_12,this.copyState(dojo.dnd.getCopyKeyState(e)));
+}
+}
+}
+},onMouseDown:function(e){
+this.mouseDown=true;
+this.mouseButton=e.button;
+this._lastX=e.pageX;
+this._lastY=e.pageY;
+this.inherited("onMouseDown",arguments);
+},onMouseUp:function(e){
+if(this.mouseDown){
+this.mouseDown=false;
+this.inherited("onMouseUp",arguments);
+}
+},onMouseOver:function(_16,e){
+this.inherited(arguments);
+if(this.isDragging){
+this._onDragMouse(e);
+}
+},onMouseOut:function(){
+this.inherited(arguments);
+this._unmarkTargetAnchor();
+},checkItemAcceptance:function(_18,_19,_1a){
+return true;
+},onDndSourceOver:function(_1b){
+if(this!=_1b){
+this.mouseDown=false;
+this._unmarkTargetAnchor();
+}else{
+if(this.isDragging){
+var m=dojo.dnd.manager();
+m.canDrop(false);
+}
+}
+},onDndStart:function(_1d,_1e,_1f){
+if(this.isSource){
+this._changeState("Source",this==_1d?(_1f?"Copied":"Moved"):"");
+}
+var _20=this.checkAcceptance(_1d,_1e);
+this._changeState("Target",_20?"":"Disabled");
+if(_20){
+dojo.dnd.manager().overSource(this);
+}
+this.isDragging=true;
+},itemCreator:function(_21){
+return dojo.map(_21,function(_22){
+return {"id":_22.id,"name":_22.textContent||_22.innerText||""};
+});
+},onDndDrop:function(_23,_24,_25){
+if(this.containerState=="Over"){
+var _26=this.tree,_27=_26.model,_28=this.targetAnchor,_29=false;
+this.isDragging=false;
+var _2a=dijit.getEnclosingWidget(_28);
+var _2b;
+var _2c;
+_2b=(_2a&&_2a.item)||_26.item;
+if(this.dropPosition=="Before"||this.dropPosition=="After"){
+_2b=(_2a.getParent()&&_2a.getParent().item)||_26.item;
+_2c=_2a.getIndexInParent();
+if(this.dropPosition=="After"){
+_2c=_2a.getIndexInParent()+1;
+}
+}else{
+_2b=(_2a&&_2a.item)||_26.item;
+}
+var _2d;
+if(_23!=this){
+_2d=this.itemCreator(_24,_28);
+}
+dojo.forEach(_24,function(_2e,idx){
+if(_23==this){
+var _30=dijit.getEnclosingWidget(_2e),_31=_30.item,_32=_30.getParent().item;
+if(typeof _2c=="number"){
+if(_2b==_32&&_30.getIndexInParent()<_2c){
+_2c-=1;
+}
+}
+_27.pasteItem(_31,_32,_2b,_25,_2c);
+}else{
+_27.newItem(_2d[idx],_2b);
+}
+},this);
+this.tree._expandNode(_2a);
+}
+this.onDndCancel();
+},onDndCancel:function(){
+this._unmarkTargetAnchor();
+this.isDragging=false;
+this.mouseDown=false;
+delete this.mouseButton;
+this._changeState("Source","");
+this._changeState("Target","");
+},onOverEvent:function(){
+this.inherited(arguments);
+dojo.dnd.manager().overSource(this);
+},onOutEvent:function(){
+this._unmarkTargetAnchor();
+var m=dojo.dnd.manager();
+if(this.isDragging){
+m.canDrop(false);
+}
+m.outSource(this);
+this.inherited(arguments);
+},_unmarkTargetAnchor:function(){
+if(!this.targetAnchor){
+return;
+}
+this._removeItemClass(this.targetAnchor,this.dropPosition);
+this.targetAnchor=null;
+this.targetBox=null;
+this.dropPosition=null;
+},_markDndStatus:function(_34){
+this._changeState("Source",_34?"Copied":"Moved");
+}});
+dojo.declare("dijit._tree.dndTarget",dijit._tree.dndSource,{constructor:function(_35,_36){
+this.isSource=false;
+dojo.removeClass(this.node,"dojoDndSource");
+}});
+}
diff --git a/dijit/dijit-all.js b/dijit/dijit-all.js
new file mode 100644
index 0000000..6d74312
--- /dev/null
+++ b/dijit/dijit-all.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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 a compiled version of Dojo, built for deployment and not for
+	development. To get an editable version, please visit:
+
+		http://dojotoolkit.org
+
+	for documentation and information on getting the source.
+*/
+
+if(!dojo._hasResource["dojo.colors"]){dojo._hasResource["dojo.colors"]=true;dojo.provide("dojo.colors");(function(){var _1=function(m1,m2,h){if(h<0){++h;}if(h>1){--h;}var h6=6*h;if(h6<1){return m1+(m2-m1)*h6;}if(2*h<1){return m2;}if(3*h<2){return m1+(m2-m1)*(2/3-h)*6;}return m1;};dojo.colorFromRgb=function(_6,_7){var m=_6.toLowerCase().match(/^(rgba?|hsla?)\(([\s\.\-,%0-9]+)\)/);if(m){var c=m[2].split(/\s*,\s*/),l=c.length,t=m[1],a;if((t=="rgb"&&l==3)||(t=="rgba"&&l==4)){var r=c[0];if(r. [...]
diff --git a/dijit/dijit-all.js.uncompressed.js b/dijit/dijit-all.js.uncompressed.js
new file mode 100644
index 0000000..b7a45ed
--- /dev/null
+++ b/dijit/dijit-all.js.uncompressed.js
@@ -0,0 +1,22089 @@
+/*
+	Copyright (c) 2004-2009, 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 a compiled version of Dojo, built for deployment and not for
+	development. To get an editable version, please visit:
+
+		http://dojotoolkit.org
+
+	for documentation and information on getting the source.
+*/
+
+if(!dojo._hasResource["dojo.colors"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.colors"] = true;
+dojo.provide("dojo.colors");
+
+//TODO: this module appears to break naming conventions
+
+/*=====
+dojo.colors = {
+	// summary: Color utilities
+}
+=====*/
+
+(function(){
+	// this is a standard conversion prescribed by the CSS3 Color Module
+	var hue2rgb = function(m1, m2, h){
+		if(h < 0){ ++h; }
+		if(h > 1){ --h; }
+		var h6 = 6 * h;
+		if(h6 < 1){ return m1 + (m2 - m1) * h6; }
+		if(2 * h < 1){ return m2; }
+		if(3 * h < 2){ return m1 + (m2 - m1) * (2 / 3 - h) * 6; }
+		return m1;
+	};
+	
+	dojo.colorFromRgb = function(/*String*/ color, /*dojo.Color?*/ obj){
+		// summary:
+		//		get rgb(a) array from css-style color declarations
+		// description:
+		//		this function can handle all 4 CSS3 Color Module formats: rgb,
+		//		rgba, hsl, hsla, including rgb(a) with percentage values.
+		var m = color.toLowerCase().match(/^(rgba?|hsla?)\(([\s\.\-,%0-9]+)\)/);
+		if(m){
+			var c = m[2].split(/\s*,\s*/), l = c.length, t = m[1], a;
+			if((t == "rgb" && l == 3) || (t == "rgba" && l == 4)){
+				var r = c[0];
+				if(r.charAt(r.length - 1) == "%"){
+					// 3 rgb percentage values
+					a = dojo.map(c, function(x){
+						return parseFloat(x) * 2.56;
+					});
+					if(l == 4){ a[3] = c[3]; }
+					return dojo.colorFromArray(a, obj);	// dojo.Color
+				}
+				return dojo.colorFromArray(c, obj);	// dojo.Color
+			}
+			if((t == "hsl" && l == 3) || (t == "hsla" && l == 4)){
+				// normalize hsl values
+				var H = ((parseFloat(c[0]) % 360) + 360) % 360 / 360,
+					S = parseFloat(c[1]) / 100,
+					L = parseFloat(c[2]) / 100,
+					// calculate rgb according to the algorithm 
+					// recommended by the CSS3 Color Module 
+					m2 = L <= 0.5 ? L * (S + 1) : L + S - L * S, 
+					m1 = 2 * L - m2;
+				a = [
+					hue2rgb(m1, m2, H + 1 / 3) * 256,
+					hue2rgb(m1, m2, H) * 256,
+					hue2rgb(m1, m2, H - 1 / 3) * 256,
+					1
+				];
+				if(l == 4){ a[3] = c[3]; }
+				return dojo.colorFromArray(a, obj);	// dojo.Color
+			}
+		}
+		return null;	// dojo.Color
+	};
+	
+	var confine = function(c, low, high){
+		// summary:
+		//		sanitize a color component by making sure it is a number,
+		//		and clamping it to valid values
+		c = Number(c);
+		return isNaN(c) ? high : c < low ? low : c > high ? high : c;	// Number
+	};
+	
+	dojo.Color.prototype.sanitize = function(){
+		// summary: makes sure that the object has correct attributes
+		var t = this;
+		t.r = Math.round(confine(t.r, 0, 255));
+		t.g = Math.round(confine(t.g, 0, 255));
+		t.b = Math.round(confine(t.b, 0, 255));
+		t.a = confine(t.a, 0, 1);
+		return this;	// dojo.Color
+	};
+})();
+
+
+dojo.colors.makeGrey = function(/*Number*/ g, /*Number?*/ a){
+	// summary: creates a greyscale color with an optional alpha
+	return dojo.colorFromArray([g, g, g, a]);
+};
+
+// mixin all CSS3 named colors not already in _base, along with SVG 1.0 variant spellings
+dojo.mixin(dojo.Color.named, {
+	aliceblue:	[240,248,255],
+	antiquewhite:	[250,235,215],
+	aquamarine:	[127,255,212],
+	azure:	[240,255,255],
+	beige:	[245,245,220],
+	bisque:	[255,228,196],
+	blanchedalmond:	[255,235,205],
+	blueviolet:	[138,43,226],
+	brown:	[165,42,42],
+	burlywood:	[222,184,135],
+	cadetblue:	[95,158,160],
+	chartreuse:	[127,255,0],
+	chocolate:	[210,105,30],
+	coral:	[255,127,80],
+	cornflowerblue:	[100,149,237],
+	cornsilk:	[255,248,220],
+	crimson:	[220,20,60],
+	cyan:	[0,255,255],
+	darkblue:	[0,0,139],
+	darkcyan:	[0,139,139],
+	darkgoldenrod:	[184,134,11],
+	darkgray:	[169,169,169],
+	darkgreen:	[0,100,0],
+	darkgrey:	[169,169,169],
+	darkkhaki:	[189,183,107],
+	darkmagenta:	[139,0,139],
+	darkolivegreen:	[85,107,47],
+	darkorange:	[255,140,0],
+	darkorchid:	[153,50,204],
+	darkred:	[139,0,0],
+	darksalmon:	[233,150,122],
+	darkseagreen:	[143,188,143],
+	darkslateblue:	[72,61,139],
+	darkslategray:	[47,79,79],
+	darkslategrey:	[47,79,79],
+	darkturquoise:	[0,206,209],
+	darkviolet:	[148,0,211],
+	deeppink:	[255,20,147],
+	deepskyblue:	[0,191,255],
+	dimgray:	[105,105,105],
+	dimgrey:	[105,105,105],
+	dodgerblue:	[30,144,255],
+	firebrick:	[178,34,34],
+	floralwhite:	[255,250,240],
+	forestgreen:	[34,139,34],
+	gainsboro:	[220,220,220],
+	ghostwhite:	[248,248,255],
+	gold:	[255,215,0],
+	goldenrod:	[218,165,32],
+	greenyellow:	[173,255,47],
+	grey:	[128,128,128],
+	honeydew:	[240,255,240],
+	hotpink:	[255,105,180],
+	indianred:	[205,92,92],
+	indigo:	[75,0,130],
+	ivory:	[255,255,240],
+	khaki:	[240,230,140],
+	lavender:	[230,230,250],
+	lavenderblush:	[255,240,245],
+	lawngreen:	[124,252,0],
+	lemonchiffon:	[255,250,205],
+	lightblue:	[173,216,230],
+	lightcoral:	[240,128,128],
+	lightcyan:	[224,255,255],
+	lightgoldenrodyellow:	[250,250,210],
+	lightgray:	[211,211,211],
+	lightgreen:	[144,238,144],
+	lightgrey:	[211,211,211],
+	lightpink:	[255,182,193],
+	lightsalmon:	[255,160,122],
+	lightseagreen:	[32,178,170],
+	lightskyblue:	[135,206,250],
+	lightslategray:	[119,136,153],
+	lightslategrey:	[119,136,153],
+	lightsteelblue:	[176,196,222],
+	lightyellow:	[255,255,224],
+	limegreen:	[50,205,50],
+	linen:	[250,240,230],
+	magenta:	[255,0,255],
+	mediumaquamarine:	[102,205,170],
+	mediumblue:	[0,0,205],
+	mediumorchid:	[186,85,211],
+	mediumpurple:	[147,112,219],
+	mediumseagreen:	[60,179,113],
+	mediumslateblue:	[123,104,238],
+	mediumspringgreen:	[0,250,154],
+	mediumturquoise:	[72,209,204],
+	mediumvioletred:	[199,21,133],
+	midnightblue:	[25,25,112],
+	mintcream:	[245,255,250],
+	mistyrose:	[255,228,225],
+	moccasin:	[255,228,181],
+	navajowhite:	[255,222,173],
+	oldlace:	[253,245,230],
+	olivedrab:	[107,142,35],
+	orange:	[255,165,0],
+	orangered:	[255,69,0],
+	orchid:	[218,112,214],
+	palegoldenrod:	[238,232,170],
+	palegreen:	[152,251,152],
+	paleturquoise:	[175,238,238],
+	palevioletred:	[219,112,147],
+	papayawhip:	[255,239,213],
+	peachpuff:	[255,218,185],
+	peru:	[205,133,63],
+	pink:	[255,192,203],
+	plum:	[221,160,221],
+	powderblue:	[176,224,230],
+	rosybrown:	[188,143,143],
+	royalblue:	[65,105,225],
+	saddlebrown:	[139,69,19],
+	salmon:	[250,128,114],
+	sandybrown:	[244,164,96],
+	seagreen:	[46,139,87],
+	seashell:	[255,245,238],
+	sienna:	[160,82,45],
+	skyblue:	[135,206,235],
+	slateblue:	[106,90,205],
+	slategray:	[112,128,144],
+	slategrey:	[112,128,144],
+	snow:	[255,250,250],
+	springgreen:	[0,255,127],
+	steelblue:	[70,130,180],
+	tan:	[210,180,140],
+	thistle:	[216,191,216],
+	tomato:	[255,99,71],
+	transparent: [0, 0, 0, 0],
+	turquoise:	[64,224,208],
+	violet:	[238,130,238],
+	wheat:	[245,222,179],
+	whitesmoke:	[245,245,245],
+	yellowgreen:	[154,205,50]
+});
+
+}
+
+if(!dojo._hasResource["dojo.i18n"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.i18n"] = true;
+dojo.provide("dojo.i18n");
+
+/*=====
+dojo.i18n = {
+	// summary: Utility classes to enable loading of resources for internationalization (i18n)
+};
+=====*/
+
+dojo.i18n.getLocalization = function(/*String*/packageName, /*String*/bundleName, /*String?*/locale){
+	//	summary:
+	//		Returns an Object containing the localization for a given resource
+	//		bundle in a package, matching the specified locale.
+	//	description:
+	//		Returns a hash containing name/value pairs in its prototypesuch
+	//		that values can be easily overridden.  Throws an exception if the
+	//		bundle is not found.  Bundle must have already been loaded by
+	//		`dojo.requireLocalization()` or by a build optimization step.  NOTE:
+	//		try not to call this method as part of an object property
+	//		definition (`var foo = { bar: dojo.i18n.getLocalization() }`).  In
+	//		some loading situations, the bundle may not be available in time
+	//		for the object definition.  Instead, call this method inside a
+	//		function that is run after all modules load or the page loads (like
+	//		in `dojo.addOnLoad()`), or in a widget lifecycle method.
+	//	packageName:
+	//		package which is associated with this resource
+	//	bundleName:
+	//		the base filename of the resource bundle (without the ".js" suffix)
+	//	locale:
+	//		the variant to load (optional).  By default, the locale defined by
+	//		the host environment: dojo.locale
+
+	locale = dojo.i18n.normalizeLocale(locale);
+
+	// look for nearest locale match
+	var elements = locale.split('-');
+	var module = [packageName,"nls",bundleName].join('.');
+	var bundle = dojo._loadedModules[module];
+	if(bundle){
+		var localization;
+		for(var i = elements.length; i > 0; i--){
+			var loc = elements.slice(0, i).join('_');
+			if(bundle[loc]){
+				localization = bundle[loc];
+				break;
+			}
+		}
+		if(!localization){
+			localization = bundle.ROOT;
+		}
+
+		// make a singleton prototype so that the caller won't accidentally change the values globally
+		if(localization){
+			var clazz = function(){};
+			clazz.prototype = localization;
+			return new clazz(); // Object
+		}
+	}
+
+	throw new Error("Bundle not found: " + bundleName + " in " + packageName+" , locale=" + locale);
+};
+
+dojo.i18n.normalizeLocale = function(/*String?*/locale){
+	//	summary:
+	//		Returns canonical form of locale, as used by Dojo.
+	//
+	//  description:
+	//		All variants are case-insensitive and are separated by '-' as specified in [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt).
+	//		If no locale is specified, the dojo.locale is returned.  dojo.locale is defined by
+	//		the user agent's locale unless overridden by djConfig.
+
+	var result = locale ? locale.toLowerCase() : dojo.locale;
+	if(result == "root"){
+		result = "ROOT";
+	}
+	return result; // String
+};
+
+dojo.i18n._requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String?*/availableFlatLocales){
+	//	summary:
+	//		See dojo.requireLocalization()
+	//	description:
+	// 		Called by the bootstrap, but factored out so that it is only
+	// 		included in the build when needed.
+
+	var targetLocale = dojo.i18n.normalizeLocale(locale);
+ 	var bundlePackage = [moduleName, "nls", bundleName].join(".");
+	// NOTE: 
+	//		When loading these resources, the packaging does not match what is
+	//		on disk.  This is an implementation detail, as this is just a
+	//		private data structure to hold the loaded resources.  e.g.
+	//		`tests/hello/nls/en-us/salutations.js` is loaded as the object
+	//		`tests.hello.nls.salutations.en_us={...}` The structure on disk is
+	//		intended to be most convenient for developers and translators, but
+	//		in memory it is more logical and efficient to store in a different
+	//		order.  Locales cannot use dashes, since the resulting path will
+	//		not evaluate as valid JS, so we translate them to underscores.
+	
+	//Find the best-match locale to load if we have available flat locales.
+	var bestLocale = "";
+	if(availableFlatLocales){
+		var flatLocales = availableFlatLocales.split(",");
+		for(var i = 0; i < flatLocales.length; i++){
+			//Locale must match from start of string.
+			//Using ["indexOf"] so customBase builds do not see
+			//this as a dojo._base.array dependency.
+			if(targetLocale["indexOf"](flatLocales[i]) == 0){
+				if(flatLocales[i].length > bestLocale.length){
+					bestLocale = flatLocales[i];
+				}
+			}
+		}
+		if(!bestLocale){
+			bestLocale = "ROOT";
+		}		
+	}
+
+	//See if the desired locale is already loaded.
+	var tempLocale = availableFlatLocales ? bestLocale : targetLocale;
+	var bundle = dojo._loadedModules[bundlePackage];
+	var localizedBundle = null;
+	if(bundle){
+		if(dojo.config.localizationComplete && bundle._built){return;}
+		var jsLoc = tempLocale.replace(/-/g, '_');
+		var translationPackage = bundlePackage+"."+jsLoc;
+		localizedBundle = dojo._loadedModules[translationPackage];
+	}
+
+	if(!localizedBundle){
+		bundle = dojo["provide"](bundlePackage);
+		var syms = dojo._getModuleSymbols(moduleName);
+		var modpath = syms.concat("nls").join("/");
+		var parent;
+
+		dojo.i18n._searchLocalePath(tempLocale, availableFlatLocales, function(loc){
+			var jsLoc = loc.replace(/-/g, '_');
+			var translationPackage = bundlePackage + "." + jsLoc;
+			var loaded = false;
+			if(!dojo._loadedModules[translationPackage]){
+				// Mark loaded whether it's found or not, so that further load attempts will not be made
+				dojo["provide"](translationPackage);
+				var module = [modpath];
+				if(loc != "ROOT"){module.push(loc);}
+				module.push(bundleName);
+				var filespec = module.join("/") + '.js';
+				loaded = dojo._loadPath(filespec, null, function(hash){
+					// Use singleton with prototype to point to parent bundle, then mix-in result from loadPath
+					var clazz = function(){};
+					clazz.prototype = parent;
+					bundle[jsLoc] = new clazz();
+					for(var j in hash){ bundle[jsLoc][j] = hash[j]; }
+				});
+			}else{
+				loaded = true;
+			}
+			if(loaded && bundle[jsLoc]){
+				parent = bundle[jsLoc];
+			}else{
+				bundle[jsLoc] = parent;
+			}
+			
+			if(availableFlatLocales){
+				//Stop the locale path searching if we know the availableFlatLocales, since
+				//the first call to this function will load the only bundle that is needed.
+				return true;
+			}
+		});
+	}
+
+	//Save the best locale bundle as the target locale bundle when we know the
+	//the available bundles.
+	if(availableFlatLocales && targetLocale != bestLocale){
+		bundle[targetLocale.replace(/-/g, '_')] = bundle[bestLocale.replace(/-/g, '_')];
+	}
+};
+
+(function(){
+	// If other locales are used, dojo.requireLocalization should load them as
+	// well, by default. 
+	// 
+	// Override dojo.requireLocalization to do load the default bundle, then
+	// iterate through the extraLocale list and load those translations as
+	// well, unless a particular locale was requested.
+
+	var extra = dojo.config.extraLocale;
+	if(extra){
+		if(!extra instanceof Array){
+			extra = [extra];
+		}
+
+		var req = dojo.i18n._requireLocalization;
+		dojo.i18n._requireLocalization = function(m, b, locale, availableFlatLocales){
+			req(m,b,locale, availableFlatLocales);
+			if(locale){return;}
+			for(var i=0; i<extra.length; i++){
+				req(m,b,extra[i], availableFlatLocales);
+			}
+		};
+	}
+})();
+
+dojo.i18n._searchLocalePath = function(/*String*/locale, /*Boolean*/down, /*Function*/searchFunc){
+	//	summary:
+	//		A helper method to assist in searching for locale-based resources.
+	//		Will iterate through the variants of a particular locale, either up
+	//		or down, executing a callback function.  For example, "en-us" and
+	//		true will try "en-us" followed by "en" and finally "ROOT".
+
+	locale = dojo.i18n.normalizeLocale(locale);
+
+	var elements = locale.split('-');
+	var searchlist = [];
+	for(var i = elements.length; i > 0; i--){
+		searchlist.push(elements.slice(0, i).join('-'));
+	}
+	searchlist.push(false);
+	if(down){searchlist.reverse();}
+
+	for(var j = searchlist.length - 1; j >= 0; j--){
+		var loc = searchlist[j] || "ROOT";
+		var stop = searchFunc(loc);
+		if(stop){ break; }
+	}
+};
+
+dojo.i18n._preloadLocalizations = function(/*String*/bundlePrefix, /*Array*/localesGenerated){
+	//	summary:
+	//		Load built, flattened resource bundles, if available for all
+	//		locales used in the page. Only called by built layer files.
+
+	function preload(locale){
+		locale = dojo.i18n.normalizeLocale(locale);
+		dojo.i18n._searchLocalePath(locale, true, function(loc){
+			for(var i=0; i<localesGenerated.length;i++){
+				if(localesGenerated[i] == loc){
+					dojo["require"](bundlePrefix+"_"+loc);
+					return true; // Boolean
+				}
+			}
+			return false; // Boolean
+		});
+	}
+	preload();
+	var extra = dojo.config.extraLocale||[];
+	for(var i=0; i<extra.length; i++){
+		preload(extra[i]);
+	}
+};
+
+}
+
+if(!dojo._hasResource["dijit.ColorPalette"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.ColorPalette"] = true;
+dojo.provide("dijit.ColorPalette");
+
+
+
+
+
+
+
+dojo.declare("dijit.ColorPalette",
+	[dijit._Widget, dijit._Templated],
+	{
+	// summary:
+	//		A keyboard accessible color-picking widget
+	// description:
+	//		Grid showing various colors, so the user can pick a certain color
+	//		Can be used standalone, or as a popup.
+	//
+	// example:
+	// |	<div dojoType="dijit.ColorPalette"></div>
+	//
+	// example:
+	// |    var picker = new dijit.ColorPalette({ },srcNode);
+	// |	picker.startup();
+
+	// defaultTimeout: Number
+	//		Number of milliseconds before a held key or button becomes typematic
+	defaultTimeout: 500,
+
+	// timeoutChangeRate: Number
+	//		Fraction of time used to change the typematic timer between events
+	//		1.0 means that each typematic event fires at defaultTimeout intervals
+	//		< 1.0 means that each typematic event fires at an increasing faster rate
+	timeoutChangeRate: 0.90,
+
+	// palette: String
+	//		Size of grid, either "7x10" or "3x4".
+	palette: "7x10",
+
+	// value: String
+	//		The value of the selected color.
+	value: null,
+
+	// _currentFocus: [private] Integer
+	//		Index of the currently focused color.
+	_currentFocus: 0,
+
+	// _xDim: [protected] Integer
+	//		This is the number of colors horizontally across.
+	_xDim: null,
+
+	// _yDim: [protected] Integer
+	///		This is the number of colors vertically down.
+	_yDim: null,
+
+	// _palettes: [protected] Map
+	// 		This represents the value of the colors.
+	//		The first level is a hashmap of the different arrays available
+	//		The next two dimensions represent the columns and rows of colors.
+	_palettes: {
+
+		"7x10":	[["white", "seashell", "cornsilk", "lemonchiffon","lightyellow", "palegreen", "paleturquoise", "lightcyan",	"lavender", "plum"],
+				["lightgray", "pink", "bisque", "moccasin", "khaki", "lightgreen", "lightseagreen", "lightskyblue", "cornflowerblue", "violet"],
+				["silver", "lightcoral", "sandybrown", "orange", "palegoldenrod", "chartreuse", "mediumturquoise", 	"skyblue", "mediumslateblue","orchid"],
+				["gray", "red", "orangered", "darkorange", "yellow", "limegreen", 	"darkseagreen", "royalblue", "slateblue", "mediumorchid"],
+				["dimgray", "crimson", 	"chocolate", "coral", "gold", "forestgreen", "seagreen", "blue", "blueviolet", "darkorchid"],
+				["darkslategray","firebrick","saddlebrown", "sienna", "olive", "green", "darkcyan", "mediumblue","darkslateblue", "darkmagenta" ],
+				["black", "darkred", "maroon", "brown", "darkolivegreen", "darkgreen", "midnightblue", "navy", "indigo", 	"purple"]],
+
+		"3x4": [["white", "lime", "green", "blue"],
+			["silver", "yellow", "fuchsia", "navy"],
+			["gray", "red", "purple", "black"]]	
+
+	},
+
+	// _imagePaths: [protected] Map
+	//		This is stores the path to the palette images
+	_imagePaths: {
+		"7x10": dojo.moduleUrl("dijit.themes", "a11y/colors7x10.png"),
+		"3x4": dojo.moduleUrl("dijit.themes", "a11y/colors3x4.png")
+	},
+
+	// _paletteCoords: [protected] Map
+	//		This is a map that is used to calculate the coordinates of the
+	//		images that make up the palette.
+	_paletteCoords: {
+		"leftOffset": 3, "topOffset": 3,
+		"cWidth": 20, "cHeight": 20
+		
+	},
+
+	// templatePath: String
+	//		Path to the template of this widget.
+	templateString:"<div class=\"dijitInline dijitColorPalette\">\n\t<div class=\"dijitColorPaletteInner\" dojoAttachPoint=\"divNode\" waiRole=\"grid\" tabIndex=\"${tabIndex}\">\n\t\t<img class=\"dijitColorPaletteUnder\" dojoAttachPoint=\"imageNode\" waiRole=\"presentation\">\n\t</div>\t\n</div>\n",
+
+	// _paletteDims: [protected] Object
+	//		Size of the supported palettes for alignment purposes.
+	_paletteDims: {
+		"7x10": {"width": "206px", "height": "145px"},
+		"3x4": {"width": "86px", "height": "64px"}
+	},
+
+	// tabIndex: String
+	//		Widget tab index.
+	tabIndex: "0",
+
+	postCreate: function(){
+		// A name has to be given to the colorMap, this needs to be unique per Palette.
+		dojo.mixin(this.divNode.style, this._paletteDims[this.palette]);
+		this.imageNode.setAttribute("src", this._imagePaths[this.palette]);
+		var choices = this._palettes[this.palette];	
+		this.domNode.style.position = "relative";
+		this._cellNodes = [];	
+		this.colorNames = dojo.i18n.getLocalization("dojo", "colors", this.lang);
+		var url = this._blankGif,
+            colorObject = new dojo.Color(),
+		    coords = this._paletteCoords;
+		for(var row=0; row < choices.length; row++){
+			for(var col=0; col < choices[row].length; col++) {
+
+                var color = choices[row][col],
+                        colorValue = colorObject.setColor(dojo.Color.named[color])
+				;
+
+                var cellNode = dojo.create("span", {
+					"class":"dijitPaletteCell",
+					"tabindex":"-1",
+					title: this.colorNames[color],
+					style:{
+						top: coords.topOffset + (row * coords.cHeight) + "px",
+						left: coords.leftOffset + (col * coords.cWidth) + "px"
+					}
+				});
+				
+				var imgNode = dojo.create("img",{
+					src: url, 
+					"class":"dijitPaletteImg",
+					alt: this.colorNames[color]
+				}, cellNode);
+				
+				// FIXME: color is an attribute of img?
+				imgNode.color = colorValue.toHex();
+				var imgStyle = imgNode.style;
+				imgStyle.color = imgStyle.backgroundColor = imgNode.color;
+
+                dojo.forEach(["Dijitclick", "MouseEnter", "Focus", "Blur"], function(handler) {
+                    this.connect(cellNode, "on" + handler.toLowerCase(), "_onCell" + handler);
+                }, this);
+
+				dojo.place(cellNode, this.divNode);
+
+                dijit.setWaiRole(cellNode, "gridcell");
+                cellNode.index = this._cellNodes.length;
+                this._cellNodes.push(cellNode);
+            }
+		}
+		this._xDim = choices[0].length;
+		this._yDim = choices.length;
+		this.connect(this.divNode, "onfocus", "_onDivNodeFocus");
+
+		// Now set all events
+		// The palette itself is navigated to with the tab key on the keyboard
+		// Keyboard navigation within the Palette is with the arrow keys
+		// Spacebar selects the color.
+		// For the up key the index is changed by negative the x dimension.		
+
+		var keyIncrementMap = {
+			UP_ARROW: -this._xDim,
+			// The down key the index is increase by the x dimension.	
+			DOWN_ARROW: this._xDim,
+			// Right and left move the index by 1.
+			RIGHT_ARROW: 1,
+			LEFT_ARROW: -1
+		};
+		for(var key in keyIncrementMap){
+			this._connects.push(dijit.typematic.addKeyListener(this.domNode,
+				{charOrCode:dojo.keys[key], ctrlKey:false, altKey:false, shiftKey:false},
+				this,
+				function(){
+					var increment = keyIncrementMap[key];
+					return function(count){ this._navigateByKey(increment, count); };
+				}(),
+				this.timeoutChangeRate, this.defaultTimeout));
+		}
+	},
+
+	focus: function(){
+		// summary:
+		//		Focus this ColorPalette.  Puts focus on the first swatch.
+		this._focusFirst();
+	},
+
+	onChange: function(color){
+		// summary:
+		//		Callback when a color is selected.
+		// color: String
+		//		Hex value corresponding to color.
+//		
+	},
+
+	_focusFirst: function(){
+		// summary:
+		//		Focus the first cell in the color picker,
+		//		or the previously selected cell, if there is one
+		// tags:
+		//		private
+		this._currentFocus = 0;
+		var cellNode = this._cellNodes[this._currentFocus];
+		window.setTimeout(function(){dijit.focus(cellNode)}, 0);
+	},
+
+	_onDivNodeFocus: function(evt){
+		// summary:
+		//		Handler for when focus goes to the ColorPalette itself.
+		//		Shifts focus to the first color or the previously selected
+		//		color.
+		// tags:
+		//		private
+
+		// focus bubbles on Firefox 2, so just make sure that focus has really
+		// gone to the container
+		if(evt.target === this.divNode){
+			this._focusFirst();
+		}
+	},
+
+	_onFocus: function(){
+		// summary:
+		//		Handler for when the ColorPalette or a color cell inside of it get focus
+		// tags:
+		//		protected
+
+		// While focus is on the palette, set its tabindex to -1 so that on a
+		// shift-tab from a cell, the container is not in the tab order
+		dojo.attr(this.divNode, "tabindex", "-1");
+	},
+
+	_onBlur: function(){
+		// summary:
+		//		Handler for when the ColorPalette and the color cell inside of it lose focus
+		// tags:
+		//		protected
+
+		this._removeCellHighlight(this._currentFocus);
+
+		// when focus leaves the palette, restore its tabindex, since it was
+		// modified by _onFocus().
+		dojo.attr(this.divNode, "tabindex", this.tabIndex);
+	},
+
+	_onCellDijitclick: function(/*Event*/ evt){
+		// summary:
+		//		Handler for click, enter key & space key. Selects the color.
+		// evt:
+		//		The event.
+		// tags:
+		//		private
+
+		var target = evt.currentTarget;
+		if (this._currentFocus != target.index){
+			this._currentFocus = target.index;
+			window.setTimeout(function(){dijit.focus(target)}, 0);
+		}
+		this._selectColor(target);
+		dojo.stopEvent(evt);
+	},
+
+	_onCellMouseEnter: function(/*Event*/ evt){
+		// summary:
+		//		Handler for onMouseOver. Put focus on the color under the mouse.
+		// evt:
+		//		The mouse event.
+		// tags:
+		//		private
+
+		var target = evt.currentTarget;
+		this._setCurrent(target);	// redundant, but needed per safari bug where onCellFocus never called
+		window.setTimeout(function(){dijit.focus(target)}, 0);
+	},
+
+	_onCellFocus: function(/*Event*/ evt){
+		// summary:
+		//		Handler for onFocus of a cell. Removes highlight of
+		//		the color that just lost focus, and highlights
+		//		the new color.
+		// evt:
+		//		The focus event.
+		// tags:
+		//		private
+
+		this._setCurrent(evt.currentTarget);
+	},
+
+	_setCurrent: function(/*Node*/ node){
+		// summary:
+		//		Called when a color is hovered or focused.
+		// description:
+		//		Removes highlight of the old color, and highlights
+		//		the new color.
+		// tags:
+		//		protected
+		this._removeCellHighlight(this._currentFocus);
+		this._currentFocus = node.index;
+		dojo.addClass(node, "dijitPaletteCellHighlight");		
+	},
+
+	_onCellBlur: function(/*Event*/ evt){
+		// summary:
+		//		needed for Firefox 2 on Mac OS X
+		// tags:
+		//		private
+		this._removeCellHighlight(this._currentFocus);
+	},
+
+	_removeCellHighlight: function(index){
+		// summary:
+		//		Removes the hover CSS class for the specified cell
+		// tags:
+		//		private
+		dojo.removeClass(this._cellNodes[index], "dijitPaletteCellHighlight");
+	},
+
+	_selectColor: function(selectNode){	
+		// summary:
+		// 		This selects a color. It triggers the onChange event
+		// area:
+		//		The area node that covers the color being selected.
+		// tags:
+		//		private
+		var img = selectNode.getElementsByTagName("img")[0];
+		this.onChange(this.value = img.color);
+	},
+
+	_navigateByKey: function(increment, typeCount){
+		// summary:
+		// 	  	This is the callback for typematic.
+		// 		It changes the focus and the highlighed color.
+		// increment:
+		// 		How much the key is navigated.
+		// typeCount:
+		//		How many times typematic has fired.
+		// tags:
+		//		private
+
+		// typecount == -1 means the key is released.
+		if(typeCount == -1){ return; }
+
+		var newFocusIndex = this._currentFocus + increment;
+		if(newFocusIndex < this._cellNodes.length && newFocusIndex > -1)
+		{
+			var focusNode = this._cellNodes[newFocusIndex];
+			focusNode.focus();
+		}
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit.Declaration"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.Declaration"] = true;
+dojo.provide("dijit.Declaration");
+
+
+
+dojo.declare(
+	"dijit.Declaration",
+	dijit._Widget,
+	{
+		// summary:
+		//		The Declaration widget allows a developer to declare new widget
+		//		classes directly from a snippet of markup.
+
+		// _noScript: [private] Boolean
+		//		Flag to parser to leave alone the script tags contained inside of me
+		_noScript: true,
+
+		// widgetClass: String
+		//		Name of class being declared, ex: "acme.myWidget"
+		widgetClass: "",
+
+		// propList: Object
+		//		Set of attributes for this widget along with default values, ex:
+		//		{delay: 100, title: "hello world"}
+		defaults: null,
+
+		// mixins: String[]
+		//		List containing the prototype for this widget, and also any mixins,
+		//		ex: ["dijit._Widget", "dijit._Container"]
+		mixins: [],
+
+		buildRendering: function(){
+			var src = this.srcNodeRef.parentNode.removeChild(this.srcNodeRef),
+				methods = dojo.query("> script[type^='dojo/method'][event]", src).orphan(),
+				postscriptConnects = dojo.query("> script[type^='dojo/method']", src).orphan(),
+				regularConnects = dojo.query("> script[type^='dojo/connect']", src).orphan(),
+				srcType = src.nodeName;
+
+			var propList = this.defaults||{};
+
+			// For all methods defined like <script type="dojo/method" event="foo">,
+			// add that method to prototype
+			dojo.forEach(methods, function(s){
+				var evt = s.getAttribute("event"),
+					func = dojo.parser._functionFromScript(s);
+				propList[evt] = func;
+			});
+
+			// map array of strings like [ "dijit.form.Button" ] to array of mixin objects
+			// (note that dojo.map(this.mixins, dojo.getObject) doesn't work because it passes
+			// a bogus third argument to getObject(), confusing it)
+			this.mixins = this.mixins.length ?
+				dojo.map(this.mixins, function(name){ return dojo.getObject(name); } ) :
+				[ dijit._Widget, dijit._Templated ];
+
+			propList.widgetsInTemplate = true;
+			propList._skipNodeCache = true;
+			propList.templateString = "<"+srcType+" class='"+src.className+"' dojoAttachPoint='"+(src.getAttribute("dojoAttachPoint")||'')+"' dojoAttachEvent='"+(src.getAttribute("dojoAttachEvent")||'')+"' >"+src.innerHTML.replace(/\%7B/g,"{").replace(/\%7D/g,"}")+"</"+srcType+">";
+
+			// strip things so we don't create stuff under us in the initial setup phase
+			dojo.query("[dojoType]", src).forEach(function(node){
+				node.removeAttribute("dojoType");
+			});
+
+			// create the new widget class
+			var wc = dojo.declare(
+				this.widgetClass,
+				this.mixins,
+				propList
+			);
+
+			// Handle <script> blocks of form:
+			//		<script type="dojo/connect" event="foo">
+			// and
+			//		<script type="dojo/method">
+			// (Note that the second one is just shorthand for a dojo/connect to postscript)
+			// Since this is a connect in the declaration, we are actually connection to the method
+			// in the _prototype_.
+			var connects = regularConnects.concat(postscriptConnects);
+			dojo.forEach(connects, function(s){
+				var evt = s.getAttribute("event")||"postscript",
+					func = dojo.parser._functionFromScript(s);
+				dojo.connect(wc.prototype, evt, func);
+			});
+		}
+	}
+);
+
+}
+
+if(!dojo._hasResource["dojo.dnd.common"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.common"] = true;
+dojo.provide("dojo.dnd.common");
+
+dojo.dnd._isMac = navigator.appVersion.indexOf("Macintosh") >= 0;
+dojo.dnd._copyKey = dojo.dnd._isMac ? "metaKey" : "ctrlKey";
+
+dojo.dnd.getCopyKeyState = function(e) {
+	// summary: abstracts away the difference between selection on Mac and PC,
+	//	and returns the state of the "copy" key to be pressed.
+	// e: Event: mouse event
+	return e[dojo.dnd._copyKey];	// Boolean
+};
+
+dojo.dnd._uniqueId = 0;
+dojo.dnd.getUniqueId = function(){
+	// summary: returns a unique string for use with any DOM element
+	var id;
+	do{
+		id = dojo._scopeName + "Unique" + (++dojo.dnd._uniqueId);
+	}while(dojo.byId(id));
+	return id;
+};
+
+dojo.dnd._empty = {};
+
+dojo.dnd.isFormElement = function(/*Event*/ e){
+	// summary: returns true, if user clicked on a form element
+	var t = e.target;
+	if(t.nodeType == 3 /*TEXT_NODE*/){
+		t = t.parentNode;
+	}
+	return " button textarea input select option ".indexOf(" " + t.tagName.toLowerCase() + " ") >= 0;	// Boolean
+};
+
+// doesn't take into account when multiple buttons are pressed
+dojo.dnd._lmb = dojo.isIE ? 1 : 0;	// left mouse button
+
+dojo.dnd._isLmbPressed = dojo.isIE ?
+	function(e){ return e.button & 1; } : // intentional bit-and
+	function(e){ return e.button === 0; };
+
+}
+
+if(!dojo._hasResource["dojo.dnd.autoscroll"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.autoscroll"] = true;
+dojo.provide("dojo.dnd.autoscroll");
+
+dojo.dnd.getViewport = function(){
+	// summary: returns a viewport size (visible part of the window)
+
+	// FIXME: need more docs!!
+	var d = dojo.doc, dd = d.documentElement, w = window, b = dojo.body();
+	if(dojo.isMozilla){
+		return {w: dd.clientWidth, h: w.innerHeight};	// Object
+	}else if(!dojo.isOpera && w.innerWidth){
+		return {w: w.innerWidth, h: w.innerHeight};		// Object
+	}else if (!dojo.isOpera && dd && dd.clientWidth){
+		return {w: dd.clientWidth, h: dd.clientHeight};	// Object
+	}else if (b.clientWidth){
+		return {w: b.clientWidth, h: b.clientHeight};	// Object
+	}
+	return null;	// Object
+};
+
+dojo.dnd.V_TRIGGER_AUTOSCROLL = 32;
+dojo.dnd.H_TRIGGER_AUTOSCROLL = 32;
+
+dojo.dnd.V_AUTOSCROLL_VALUE = 16;
+dojo.dnd.H_AUTOSCROLL_VALUE = 16;
+
+dojo.dnd.autoScroll = function(e){
+	// summary:
+	//		a handler for onmousemove event, which scrolls the window, if
+	//		necesary
+	// e: Event:
+	//		onmousemove event
+
+	// FIXME: needs more docs!
+	var v = dojo.dnd.getViewport(), dx = 0, dy = 0;
+	if(e.clientX < dojo.dnd.H_TRIGGER_AUTOSCROLL){
+		dx = -dojo.dnd.H_AUTOSCROLL_VALUE;
+	}else if(e.clientX > v.w - dojo.dnd.H_TRIGGER_AUTOSCROLL){
+		dx = dojo.dnd.H_AUTOSCROLL_VALUE;
+	}
+	if(e.clientY < dojo.dnd.V_TRIGGER_AUTOSCROLL){
+		dy = -dojo.dnd.V_AUTOSCROLL_VALUE;
+	}else if(e.clientY > v.h - dojo.dnd.V_TRIGGER_AUTOSCROLL){
+		dy = dojo.dnd.V_AUTOSCROLL_VALUE;
+	}
+	window.scrollBy(dx, dy);
+};
+
+dojo.dnd._validNodes = {"div": 1, "p": 1, "td": 1};
+dojo.dnd._validOverflow = {"auto": 1, "scroll": 1};
+
+dojo.dnd.autoScrollNodes = function(e){
+	// summary:
+	//		a handler for onmousemove event, which scrolls the first avaialble
+	//		Dom element, it falls back to dojo.dnd.autoScroll()
+	// e: Event:
+	//		onmousemove event
+
+	// FIXME: needs more docs!
+	for(var n = e.target; n;){
+		if(n.nodeType == 1 && (n.tagName.toLowerCase() in dojo.dnd._validNodes)){
+			var s = dojo.getComputedStyle(n);
+			if(s.overflow.toLowerCase() in dojo.dnd._validOverflow){
+				var b = dojo._getContentBox(n, s), t = dojo._abs(n, true);
+				//
+				var w = Math.min(dojo.dnd.H_TRIGGER_AUTOSCROLL, b.w / 2), 
+					h = Math.min(dojo.dnd.V_TRIGGER_AUTOSCROLL, b.h / 2),
+					rx = e.pageX - t.x, ry = e.pageY - t.y, dx = 0, dy = 0;
+				if(dojo.isWebKit || dojo.isOpera){
+					// FIXME: this code should not be here, it should be taken into account 
+					// either by the event fixing code, or the dojo._abs()
+					// FIXME: this code doesn't work on Opera 9.5 Beta
+					rx += dojo.body().scrollLeft, ry += dojo.body().scrollTop;
+				}
+				if(rx > 0 && rx < b.w){
+					if(rx < w){
+						dx = -w;
+					}else if(rx > b.w - w){
+						dx = w;
+					}
+				}
+				//
+				if(ry > 0 && ry < b.h){
+					if(ry < h){
+						dy = -h;
+					}else if(ry > b.h - h){
+						dy = h;
+					}
+				}
+				var oldLeft = n.scrollLeft, oldTop = n.scrollTop;
+				n.scrollLeft = n.scrollLeft + dx;
+				n.scrollTop  = n.scrollTop  + dy;
+				if(oldLeft != n.scrollLeft || oldTop != n.scrollTop){ return; }
+			}
+		}
+		try{
+			n = n.parentNode;
+		}catch(x){
+			n = null;
+		}
+	}
+	dojo.dnd.autoScroll(e);
+};
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Mover"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Mover"] = true;
+dojo.provide("dojo.dnd.Mover");
+
+
+
+
+dojo.declare("dojo.dnd.Mover", null, {
+	constructor: function(node, e, host){
+		// summary: an object, which makes a node follow the mouse, 
+		//	used as a default mover, and as a base class for custom movers
+		// node: Node: a node (or node's id) to be moved
+		// e: Event: a mouse event, which started the move;
+		//	only pageX and pageY properties are used
+		// host: Object?: object which implements the functionality of the move,
+		//	 and defines proper events (onMoveStart and onMoveStop)
+		this.node = dojo.byId(node);
+		this.marginBox = {l: e.pageX, t: e.pageY};
+		this.mouseButton = e.button;
+		var h = this.host = host, d = node.ownerDocument, 
+			firstEvent = dojo.connect(d, "onmousemove", this, "onFirstMove");
+		this.events = [
+			dojo.connect(d, "onmousemove", this, "onMouseMove"),
+			dojo.connect(d, "onmouseup",   this, "onMouseUp"),
+			// cancel text selection and text dragging
+			dojo.connect(d, "ondragstart",   dojo.stopEvent),
+			dojo.connect(d.body, "onselectstart", dojo.stopEvent),
+			firstEvent
+		];
+		// notify that the move has started
+		if(h && h.onMoveStart){
+			h.onMoveStart(this);
+		}
+	},
+	// mouse event processors
+	onMouseMove: function(e){
+		// summary: event processor for onmousemove
+		// e: Event: mouse event
+		dojo.dnd.autoScroll(e);
+		var m = this.marginBox;
+		this.host.onMove(this, {l: m.l + e.pageX, t: m.t + e.pageY});
+		dojo.stopEvent(e);
+	},
+	onMouseUp: function(e){
+		if(dojo.isWebKit && dojo.dnd._isMac && this.mouseButton == 2 ? 
+				e.button == 0 : this.mouseButton == e.button){
+			this.destroy();
+		}
+		dojo.stopEvent(e);
+	},
+	// utilities
+	onFirstMove: function(){
+		// summary: makes the node absolute; it is meant to be called only once. 
+		// 	relative and absolutely positioned nodes are assumed to use pixel units
+		var s = this.node.style, l, t, h = this.host;
+		switch(s.position){
+			case "relative":
+			case "absolute":
+				// assume that left and top values are in pixels already
+				l = Math.round(parseFloat(s.left));
+				t = Math.round(parseFloat(s.top));
+				break;
+			default:
+				s.position = "absolute";	// enforcing the absolute mode
+				var m = dojo.marginBox(this.node);
+				// event.pageX/pageY (which we used to generate the initial
+				// margin box) includes padding and margin set on the body.
+				// However, setting the node's position to absolute and then
+				// doing dojo.marginBox on it *doesn't* take that additional
+				// space into account - so we need to subtract the combined
+				// padding and margin.  We use getComputedStyle and
+				// _getMarginBox/_getContentBox to avoid the extra lookup of
+				// the computed style. 
+				var b = dojo.doc.body;
+				var bs = dojo.getComputedStyle(b);
+				var bm = dojo._getMarginBox(b, bs);
+				var bc = dojo._getContentBox(b, bs);
+				l = m.l - (bc.l - bm.l);
+				t = m.t - (bc.t - bm.t);
+				break;
+		}
+		this.marginBox.l = l - this.marginBox.l;
+		this.marginBox.t = t - this.marginBox.t;
+		if(h && h.onFirstMove){
+			h.onFirstMove(this);
+		}
+		dojo.disconnect(this.events.pop());
+	},
+	destroy: function(){
+		// summary: stops the move, deletes all references, so the object can be garbage-collected
+		dojo.forEach(this.events, dojo.disconnect);
+		// undo global settings
+		var h = this.host;
+		if(h && h.onMoveStop){
+			h.onMoveStop(this);
+		}
+		// destroy objects
+		this.events = this.node = this.host = null;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Moveable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Moveable"] = true;
+dojo.provide("dojo.dnd.Moveable");
+
+
+
+dojo.declare("dojo.dnd.Moveable", null, {
+	// object attributes (for markup)
+	handle: "",
+	delay: 0,
+	skip: false,
+	
+	constructor: function(node, params){
+		// summary: an object, which makes a node moveable
+		// node: Node: a node (or node's id) to be moved
+		// params: Object: an optional object with additional parameters;
+		//	following parameters are recognized:
+		//		handle: Node: a node (or node's id), which is used as a mouse handle
+		//			if omitted, the node itself is used as a handle
+		//		delay: Number: delay move by this number of pixels
+		//		skip: Boolean: skip move of form elements
+		//		mover: Object: a constructor of custom Mover
+		this.node = dojo.byId(node);
+		if(!params){ params = {}; }
+		this.handle = params.handle ? dojo.byId(params.handle) : null;
+		if(!this.handle){ this.handle = this.node; }
+		this.delay = params.delay > 0 ? params.delay : 0;
+		this.skip  = params.skip;
+		this.mover = params.mover ? params.mover : dojo.dnd.Mover;
+		this.events = [
+			dojo.connect(this.handle, "onmousedown", this, "onMouseDown"),
+			// cancel text selection and text dragging
+			dojo.connect(this.handle, "ondragstart",   this, "onSelectStart"),
+			dojo.connect(this.handle, "onselectstart", this, "onSelectStart")
+		];
+	},
+
+	// markup methods
+	markupFactory: function(params, node){
+		return new dojo.dnd.Moveable(node, params);
+	},
+
+	// methods
+	destroy: function(){
+		// summary: stops watching for possible move, deletes all references, so the object can be garbage-collected
+		dojo.forEach(this.events, dojo.disconnect);
+		this.events = this.node = this.handle = null;
+	},
+	
+	// mouse event processors
+	onMouseDown: function(e){
+		// summary: event processor for onmousedown, creates a Mover for the node
+		// e: Event: mouse event
+		if(this.skip && dojo.dnd.isFormElement(e)){ return; }
+		if(this.delay){
+			this.events.push(
+				dojo.connect(this.handle, "onmousemove", this, "onMouseMove"),
+				dojo.connect(this.handle, "onmouseup", this, "onMouseUp")
+			);
+			this._lastX = e.pageX;
+			this._lastY = e.pageY;
+		}else{
+			this.onDragDetected(e);
+		}
+		dojo.stopEvent(e);
+	},
+	onMouseMove: function(e){
+		// summary: event processor for onmousemove, used only for delayed drags
+		// e: Event: mouse event
+		if(Math.abs(e.pageX - this._lastX) > this.delay || Math.abs(e.pageY - this._lastY) > this.delay){
+			this.onMouseUp(e);
+			this.onDragDetected(e);
+		}
+		dojo.stopEvent(e);
+	},
+	onMouseUp: function(e){
+		// summary: event processor for onmouseup, used only for delayed drags
+		// e: Event: mouse event
+		for(var i = 0; i < 2; ++i){
+			dojo.disconnect(this.events.pop());
+		}
+		dojo.stopEvent(e);
+	},
+	onSelectStart: function(e){
+		// summary: event processor for onselectevent and ondragevent
+		// e: Event: mouse event
+		if(!this.skip || !dojo.dnd.isFormElement(e)){
+			dojo.stopEvent(e);
+		}
+	},
+	
+	// local events
+	onDragDetected: function(/* Event */ e){
+		// summary: called when the drag is detected,
+		// responsible for creation of the mover
+		new this.mover(this.node, e, this);
+	},
+	onMoveStart: function(/* dojo.dnd.Mover */ mover){
+		// summary: called before every move operation
+		dojo.publish("/dnd/move/start", [mover]);
+		dojo.addClass(dojo.body(), "dojoMove"); 
+		dojo.addClass(this.node, "dojoMoveItem"); 
+	},
+	onMoveStop: function(/* dojo.dnd.Mover */ mover){
+		// summary: called after every move operation
+		dojo.publish("/dnd/move/stop", [mover]);
+		dojo.removeClass(dojo.body(), "dojoMove");
+		dojo.removeClass(this.node, "dojoMoveItem");
+	},
+	onFirstMove: function(/* dojo.dnd.Mover */ mover){
+		// summary: called during the very first move notification,
+		//	can be used to initialize coordinates, can be overwritten.
+		
+		// default implementation does nothing
+	},
+	onMove: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
+		// summary: called during every move notification,
+		//	should actually move the node, can be overwritten.
+		this.onMoving(mover, leftTop);
+		var s = mover.node.style;
+		s.left = leftTop.l + "px";
+		s.top  = leftTop.t + "px";
+		this.onMoved(mover, leftTop);
+	},
+	onMoving: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
+		// summary: called before every incremental move,
+		//	can be overwritten.
+		
+		// default implementation does nothing
+	},
+	onMoved: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
+		// summary: called after every incremental move,
+		//	can be overwritten.
+		
+		// default implementation does nothing
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojo.dnd.move"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.move"] = true;
+dojo.provide("dojo.dnd.move");
+
+
+
+
+dojo.declare("dojo.dnd.move.constrainedMoveable", dojo.dnd.Moveable, {
+	// object attributes (for markup)
+	constraints: function(){},
+	within: false,
+	
+	// markup methods
+	markupFactory: function(params, node){
+		return new dojo.dnd.move.constrainedMoveable(node, params);
+	},
+
+	constructor: function(node, params){
+		// summary: an object, which makes a node moveable
+		// node: Node: a node (or node's id) to be moved
+		// params: Object: an optional object with additional parameters;
+		//	following parameters are recognized:
+		//		constraints: Function: a function, which calculates a constraint box,
+		//			it is called in a context of the moveable object.
+		//		within: Boolean: restrict move within boundaries.
+		//	the rest is passed to the base class
+		if(!params){ params = {}; }
+		this.constraints = params.constraints;
+		this.within = params.within;
+	},
+	onFirstMove: function(/* dojo.dnd.Mover */ mover){
+		// summary: called during the very first move notification,
+		//	can be used to initialize coordinates, can be overwritten.
+		var c = this.constraintBox = this.constraints.call(this, mover);
+		c.r = c.l + c.w;
+		c.b = c.t + c.h;
+		if(this.within){
+			var mb = dojo.marginBox(mover.node);
+			c.r -= mb.w;
+			c.b -= mb.h;
+		}
+	},
+	onMove: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
+		// summary: called during every move notification,
+		//	should actually move the node, can be overwritten.
+		var c = this.constraintBox, s = mover.node.style;
+		s.left = (leftTop.l < c.l ? c.l : c.r < leftTop.l ? c.r : leftTop.l) + "px";
+		s.top  = (leftTop.t < c.t ? c.t : c.b < leftTop.t ? c.b : leftTop.t) + "px";
+	}
+});
+
+dojo.declare("dojo.dnd.move.boxConstrainedMoveable", dojo.dnd.move.constrainedMoveable, {
+	// object attributes (for markup)
+	box: {},
+	
+	// markup methods
+	markupFactory: function(params, node){
+		return new dojo.dnd.move.boxConstrainedMoveable(node, params);
+	},
+
+	constructor: function(node, params){
+		// summary: an object, which makes a node moveable
+		// node: Node: a node (or node's id) to be moved
+		// params: Object: an optional object with additional parameters;
+		//	following parameters are recognized:
+		//		box: Object: a constraint box
+		//	the rest is passed to the base class
+		var box = params && params.box;
+		this.constraints = function(){ return box; };
+	}
+});
+
+dojo.declare("dojo.dnd.move.parentConstrainedMoveable", dojo.dnd.move.constrainedMoveable, {
+	// object attributes (for markup)
+	area: "content",
+
+	// markup methods
+	markupFactory: function(params, node){
+		return new dojo.dnd.move.parentConstrainedMoveable(node, params);
+	},
+
+	constructor: function(node, params){
+		// summary: an object, which makes a node moveable
+		// node: Node: a node (or node's id) to be moved
+		// params: Object: an optional object with additional parameters;
+		//	following parameters are recognized:
+		//		area: String: a parent's area to restrict the move,
+		//			can be "margin", "border", "padding", or "content".
+		//	the rest is passed to the base class
+		var area = params && params.area;
+		this.constraints = function(){
+			var n = this.node.parentNode, 
+				s = dojo.getComputedStyle(n), 
+				mb = dojo._getMarginBox(n, s);
+			if(area == "margin"){
+				return mb;	// Object
+			}
+			var t = dojo._getMarginExtents(n, s);
+			mb.l += t.l, mb.t += t.t, mb.w -= t.w, mb.h -= t.h;
+			if(area == "border"){
+				return mb;	// Object
+			}
+			t = dojo._getBorderExtents(n, s);
+			mb.l += t.l, mb.t += t.t, mb.w -= t.w, mb.h -= t.h;
+			if(area == "padding"){
+				return mb;	// Object
+			}
+			t = dojo._getPadExtents(n, s);
+			mb.l += t.l, mb.t += t.t, mb.w -= t.w, mb.h -= t.h;
+			return mb;	// Object
+		};
+	}
+});
+
+// WARNING: below are obsolete objects, instead of custom movers use custom moveables (above)
+
+dojo.dnd.move.constrainedMover = function(fun, within){
+	// summary: returns a constrained version of dojo.dnd.Mover
+	// description: this function produces n object, which will put a constraint on 
+	//	the margin box of dragged object in absolute coordinates
+	// fun: Function: called on drag, and returns a constraint box
+	// within: Boolean: if true, constraints the whole dragged object withtin the rectangle, 
+	//	otherwise the constraint is applied to the left-top corner
+	dojo.deprecated("dojo.dnd.move.constrainedMover, use dojo.dnd.move.constrainedMoveable instead");
+	var mover = function(node, e, notifier){
+		dojo.dnd.Mover.call(this, node, e, notifier);
+	};
+	dojo.extend(mover, dojo.dnd.Mover.prototype);
+	dojo.extend(mover, {
+		onMouseMove: function(e){
+			// summary: event processor for onmousemove
+			// e: Event: mouse event
+			dojo.dnd.autoScroll(e);
+			var m = this.marginBox, c = this.constraintBox,
+				l = m.l + e.pageX, t = m.t + e.pageY;
+			l = l < c.l ? c.l : c.r < l ? c.r : l;
+			t = t < c.t ? c.t : c.b < t ? c.b : t;
+			this.host.onMove(this, {l: l, t: t});
+		},
+		onFirstMove: function(){
+			// summary: called once to initialize things; it is meant to be called only once
+			dojo.dnd.Mover.prototype.onFirstMove.call(this);
+			var c = this.constraintBox = fun.call(this);
+			c.r = c.l + c.w;
+			c.b = c.t + c.h;
+			if(within){
+				var mb = dojo.marginBox(this.node);
+				c.r -= mb.w;
+				c.b -= mb.h;
+			}
+		}
+	});
+	return mover;	// Object
+};
+
+dojo.dnd.move.boxConstrainedMover = function(box, within){
+	// summary: a specialization of dojo.dnd.constrainedMover, which constrains to the specified box
+	// box: Object: a constraint box (l, t, w, h)
+	// within: Boolean: if true, constraints the whole dragged object withtin the rectangle, 
+	//	otherwise the constraint is applied to the left-top corner
+	dojo.deprecated("dojo.dnd.move.boxConstrainedMover, use dojo.dnd.move.boxConstrainedMoveable instead");
+	return dojo.dnd.move.constrainedMover(function(){ return box; }, within);	// Object
+};
+
+dojo.dnd.move.parentConstrainedMover = function(area, within){
+	// summary: a specialization of dojo.dnd.constrainedMover, which constrains to the parent node
+	// area: String: "margin" to constrain within the parent's margin box, "border" for the border box,
+	//	"padding" for the padding box, and "content" for the content box; "content" is the default value.
+	// within: Boolean: if true, constraints the whole dragged object withtin the rectangle, 
+	//	otherwise the constraint is applied to the left-top corner
+	dojo.deprecated("dojo.dnd.move.parentConstrainedMover, use dojo.dnd.move.parentConstrainedMoveable instead");
+	var fun = function(){
+		var n = this.node.parentNode, 
+			s = dojo.getComputedStyle(n), 
+			mb = dojo._getMarginBox(n, s);
+		if(area == "margin"){
+			return mb;	// Object
+		}
+		var t = dojo._getMarginExtents(n, s);
+		mb.l += t.l, mb.t += t.t, mb.w -= t.w, mb.h -= t.h;
+		if(area == "border"){
+			return mb;	// Object
+		}
+		t = dojo._getBorderExtents(n, s);
+		mb.l += t.l, mb.t += t.t, mb.w -= t.w, mb.h -= t.h;
+		if(area == "padding"){
+			return mb;	// Object
+		}
+		t = dojo._getPadExtents(n, s);
+		mb.l += t.l, mb.t += t.t, mb.w -= t.w, mb.h -= t.h;
+		return mb;	// Object
+	};
+	return dojo.dnd.move.constrainedMover(fun, within);	// Object
+};
+
+// patching functions one level up for compatibility
+
+dojo.dnd.constrainedMover = dojo.dnd.move.constrainedMover;
+dojo.dnd.boxConstrainedMover = dojo.dnd.move.boxConstrainedMover;
+dojo.dnd.parentConstrainedMover = dojo.dnd.move.parentConstrainedMover;
+
+}
+
+if(!dojo._hasResource["dojo.dnd.TimedMoveable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.TimedMoveable"] = true;
+dojo.provide("dojo.dnd.TimedMoveable");
+
+
+
+(function(){
+	// precalculate long expressions
+	var oldOnMove = dojo.dnd.Moveable.prototype.onMove;
+		
+	dojo.declare("dojo.dnd.TimedMoveable", dojo.dnd.Moveable, {
+		// summary:
+		//	A specialized version of Moveable to support an FPS throttling.
+		//	This class puts an upper restriction on FPS, which may reduce 
+		//	the CPU load. The additional parameter "timeout" regulates
+		//	the delay before actually moving the moveable object.
+		
+		// object attributes (for markup)
+		timeout: 40,	// in ms, 40ms corresponds to 25 fps
+	
+		constructor: function(node, params){
+			// summary: an object, which makes a node moveable with a timer
+			// node: Node: a node (or node's id) to be moved
+			// params: Object: an optional object with additional parameters.
+			//	See dojo.dnd.Moveable for details on general parameters.
+			//	Following parameters are specific for this class:
+			//		timeout: Number: delay move by this number of ms
+			//			accumulating position changes during the timeout
+			
+			// sanitize parameters
+			if(!params){ params = {}; }
+			if(params.timeout && typeof params.timeout == "number" && params.timeout >= 0){
+				this.timeout = params.timeout;
+			}
+		},
+	
+		// markup methods
+		markupFactory: function(params, node){
+			return new dojo.dnd.TimedMoveable(node, params);
+		},
+	
+		onMoveStop: function(/* dojo.dnd.Mover */ mover){
+			if(mover._timer){
+				// stop timer
+				clearTimeout(mover._timer)
+				// reflect the last received position
+				oldOnMove.call(this, mover, mover._leftTop)
+			}
+			dojo.dnd.Moveable.prototype.onMoveStop.apply(this, arguments);
+		},
+		onMove: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
+			mover._leftTop = leftTop;
+			if(!mover._timer){
+				var _t = this;	// to avoid using dojo.hitch()
+				mover._timer = setTimeout(function(){
+					// we don't have any pending requests
+					mover._timer = null;
+					// reflect the last received position
+					oldOnMove.call(_t, mover, mover._leftTop);
+				}, this.timeout);
+			}
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojo.fx.Toggler"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.fx.Toggler"] = true;
+dojo.provide("dojo.fx.Toggler");
+
+dojo.declare("dojo.fx.Toggler", null, {
+	// summary:
+	//		class constructor for an animation toggler. It accepts a packed
+	//		set of arguments about what type of animation to use in each
+	//		direction, duration, etc.
+	//
+	// example:
+	//	|	var t = new dojo.fx.Toggler({
+	//	|		node: "nodeId",
+	//	|		showDuration: 500,
+	//	|		// hideDuration will default to "200"
+	//	|		showFunc: dojo.wipeIn, 
+	//	|		// hideFunc will default to "fadeOut"
+	//	|	});
+	//	|	t.show(100); // delay showing for 100ms
+	//	|	// ...time passes...
+	//	|	t.hide();
+
+	// FIXME: need a policy for where the toggler should "be" the next
+	// time show/hide are called if we're stopped somewhere in the
+	// middle.
+
+	constructor: function(args){
+		var _t = this;
+
+		dojo.mixin(_t, args);
+		_t.node = args.node;
+		_t._showArgs = dojo.mixin({}, args);
+		_t._showArgs.node = _t.node;
+		_t._showArgs.duration = _t.showDuration;
+		_t.showAnim = _t.showFunc(_t._showArgs);
+
+		_t._hideArgs = dojo.mixin({}, args);
+		_t._hideArgs.node = _t.node;
+		_t._hideArgs.duration = _t.hideDuration;
+		_t.hideAnim = _t.hideFunc(_t._hideArgs);
+
+		dojo.connect(_t.showAnim, "beforeBegin", dojo.hitch(_t.hideAnim, "stop", true));
+		dojo.connect(_t.hideAnim, "beforeBegin", dojo.hitch(_t.showAnim, "stop", true));
+	},
+
+	// node: DomNode
+	//	the node to toggle
+	node: null,
+
+	// showFunc: Function
+	//	The function that returns the dojo._Animation to show the node
+	showFunc: dojo.fadeIn,
+
+	// hideFunc: Function	
+	//	The function that returns the dojo._Animation to hide the node
+	hideFunc: dojo.fadeOut,
+
+	// showDuration:
+	//	Time in milliseconds to run the show Animation
+	showDuration: 200,
+
+	// hideDuration:
+	//	Time in milliseconds to run the hide Animation
+	hideDuration: 200,
+
+	/*=====
+	_showArgs: null,
+	_showAnim: null,
+
+	_hideArgs: null,
+	_hideAnim: null,
+
+	_isShowing: false,
+	_isHiding: false,
+	=====*/
+
+	show: function(delay){
+		// summary: Toggle the node to showing
+		return this.showAnim.play(delay || 0);
+	},
+
+	hide: function(delay){
+		// summary: Toggle the node to hidden
+		return this.hideAnim.play(delay || 0);
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojo.fx"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.fx"] = true;
+dojo.provide("dojo.fx");
+
+/*=====
+dojo.fx = {
+	// summary: Effects library on top of Base animations
+};
+=====*/
+(function(){
+	
+	var d = dojo, 
+		_baseObj = {
+			_fire: function(evt, args){
+				if(this[evt]){
+					this[evt].apply(this, args||[]);
+				}
+				return this;
+			}
+		};
+
+	var _chain = function(animations){
+		this._index = -1;
+		this._animations = animations||[];
+		this._current = this._onAnimateCtx = this._onEndCtx = null;
+
+		this.duration = 0;
+		d.forEach(this._animations, function(a){
+			this.duration += a.duration;
+			if(a.delay){ this.duration += a.delay; }
+		}, this);
+	};
+	d.extend(_chain, {
+		_onAnimate: function(){
+			this._fire("onAnimate", arguments);
+		},
+		_onEnd: function(){
+			d.disconnect(this._onAnimateCtx);
+			d.disconnect(this._onEndCtx);
+			this._onAnimateCtx = this._onEndCtx = null;
+			if(this._index + 1 == this._animations.length){
+				this._fire("onEnd");
+			}else{
+				// switch animations
+				this._current = this._animations[++this._index];
+				this._onAnimateCtx = d.connect(this._current, "onAnimate", this, "_onAnimate");
+				this._onEndCtx = d.connect(this._current, "onEnd", this, "_onEnd");
+				this._current.play(0, true);
+			}
+		},
+		play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
+			if(!this._current){ this._current = this._animations[this._index = 0]; }
+			if(!gotoStart && this._current.status() == "playing"){ return this; }
+			var beforeBegin = d.connect(this._current, "beforeBegin", this, function(){
+					this._fire("beforeBegin");
+				}),
+				onBegin = d.connect(this._current, "onBegin", this, function(arg){
+					this._fire("onBegin", arguments);
+				}),
+				onPlay = d.connect(this._current, "onPlay", this, function(arg){
+					this._fire("onPlay", arguments);
+					d.disconnect(beforeBegin);
+					d.disconnect(onBegin);
+					d.disconnect(onPlay);
+				});
+			if(this._onAnimateCtx){
+				d.disconnect(this._onAnimateCtx);
+			}
+			this._onAnimateCtx = d.connect(this._current, "onAnimate", this, "_onAnimate");
+			if(this._onEndCtx){
+				d.disconnect(this._onEndCtx);
+			}
+			this._onEndCtx = d.connect(this._current, "onEnd", this, "_onEnd");
+			this._current.play.apply(this._current, arguments);
+			return this;
+		},
+		pause: function(){
+			if(this._current){
+				var e = d.connect(this._current, "onPause", this, function(arg){
+						this._fire("onPause", arguments);
+						d.disconnect(e);
+					});
+				this._current.pause();
+			}
+			return this;
+		},
+		gotoPercent: function(/*Decimal*/percent, /*Boolean?*/ andPlay){
+			this.pause();
+			var offset = this.duration * percent;
+			this._current = null;
+			d.some(this._animations, function(a){
+				if(a.duration <= offset){
+					this._current = a;
+					return true;
+				}
+				offset -= a.duration;
+				return false;
+			});
+			if(this._current){
+				this._current.gotoPercent(offset / this._current.duration, andPlay);
+			}
+			return this;
+		},
+		stop: function(/*boolean?*/ gotoEnd){
+			if(this._current){
+				if(gotoEnd){
+					for(; this._index + 1 < this._animations.length; ++this._index){
+						this._animations[this._index].stop(true);
+					}
+					this._current = this._animations[this._index];
+				}
+				var e = d.connect(this._current, "onStop", this, function(arg){
+						this._fire("onStop", arguments);
+						d.disconnect(e);
+					});
+				this._current.stop();
+			}
+			return this;
+		},
+		status: function(){
+			return this._current ? this._current.status() : "stopped";
+		},
+		destroy: function(){
+			if(this._onAnimateCtx){ d.disconnect(this._onAnimateCtx); }
+			if(this._onEndCtx){ d.disconnect(this._onEndCtx); }
+		}
+	});
+	d.extend(_chain, _baseObj);
+
+	dojo.fx.chain = function(/*dojo._Animation[]*/ animations){
+		// summary: Chain a list of dojo._Animation s to run in sequence
+		// example:
+		//	|	dojo.fx.chain([
+		//	|		dojo.fadeIn({ node:node }),
+		//	|		dojo.fadeOut({ node:otherNode })
+		//	|	]).play();
+		//
+		return new _chain(animations) // dojo._Animation
+	};
+
+	var _combine = function(animations){
+		this._animations = animations||[];
+		this._connects = [];
+		this._finished = 0;
+
+		this.duration = 0;
+		d.forEach(animations, function(a){
+			var duration = a.duration;
+			if(a.delay){ duration += a.delay; }
+			if(this.duration < duration){ this.duration = duration; }
+			this._connects.push(d.connect(a, "onEnd", this, "_onEnd"));
+		}, this);
+		
+		this._pseudoAnimation = new d._Animation({curve: [0, 1], duration: this.duration});
+		var self = this;
+		d.forEach(["beforeBegin", "onBegin", "onPlay", "onAnimate", "onPause", "onStop"], 
+			function(evt){
+				self._connects.push(d.connect(self._pseudoAnimation, evt,
+					function(){ self._fire(evt, arguments); }
+				));
+			}
+		);
+	};
+	d.extend(_combine, {
+		_doAction: function(action, args){
+			d.forEach(this._animations, function(a){
+				a[action].apply(a, args);
+			});
+			return this;
+		},
+		_onEnd: function(){
+			if(++this._finished == this._animations.length){
+				this._fire("onEnd");
+			}
+		},
+		_call: function(action, args){
+			var t = this._pseudoAnimation;
+			t[action].apply(t, args);
+		},
+		play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
+			this._finished = 0;
+			this._doAction("play", arguments);
+			this._call("play", arguments);
+			return this;
+		},
+		pause: function(){
+			this._doAction("pause", arguments);
+			this._call("pause", arguments);
+			return this;
+		},
+		gotoPercent: function(/*Decimal*/percent, /*Boolean?*/ andPlay){
+			var ms = this.duration * percent;
+			d.forEach(this._animations, function(a){
+				a.gotoPercent(a.duration < ms ? 1 : (ms / a.duration), andPlay);
+			});
+			this._call("gotoPercent", arguments);
+			return this;
+		},
+		stop: function(/*boolean?*/ gotoEnd){
+			this._doAction("stop", arguments);
+			this._call("stop", arguments);
+			return this;
+		},
+		status: function(){
+			return this._pseudoAnimation.status();
+		},
+		destroy: function(){
+			d.forEach(this._connects, dojo.disconnect);
+		}
+	});
+	d.extend(_combine, _baseObj);
+
+	dojo.fx.combine = function(/*dojo._Animation[]*/ animations){
+		// summary: Combine an array of `dojo._Animation`s to run in parallel
+		//
+		// description:
+		//		Combine an array of `dojo._Animation`s to run in parallel, 
+		//		providing a new `dojo._Animation` instance encompasing each
+		//		animation, firing standard animation events.
+		//
+		// example:
+		//	|	dojo.fx.combine([
+		//	|		dojo.fadeIn({ node:node }),
+		//	|		dojo.fadeOut({ node:otherNode })
+		//	|	]).play();
+		//
+		// example:
+		//	When the longest animation ends, execute a function:
+		//	| 	var anim = dojo.fx.combine([
+		//	|		dojo.fadeIn({ node: n, duration:700 }),
+		//	|		dojo.fadeOut({ node: otherNode, duration: 300 })
+		//	|	]);
+		//	|	dojo.connect(anim, "onEnd", function(){
+		//	|		// overall animation is done.
+		//	|	});
+		//	|	anim.play(); // play the animation
+		//
+		return new _combine(animations); // dojo._Animation
+	};
+
+	dojo.fx.wipeIn = function(/*Object*/ args){
+		// summary:
+		//		Returns an animation that will expand the
+		//		node defined in 'args' object from it's current height to
+		//		it's natural height (with no scrollbar).
+		//		Node must have no margin/border/padding.
+		args.node = d.byId(args.node);
+		var node = args.node, s = node.style, o;
+
+		var anim = d.animateProperty(d.mixin({
+			properties: {
+				height: {
+					// wrapped in functions so we wait till the last second to query (in case value has changed)
+					start: function(){
+						// start at current [computed] height, but use 1px rather than 0
+						// because 0 causes IE to display the whole panel
+						o = s.overflow;
+						s.overflow="hidden";
+						if(s.visibility=="hidden"||s.display=="none"){
+							s.height="1px";
+							s.display="";
+							s.visibility="";
+							return 1;
+						}else{
+							var height = d.style(node, "height");
+							return Math.max(height, 1);
+						}
+					},
+					end: function(){
+						return node.scrollHeight;
+					}
+				}
+			}
+		}, args));
+
+		d.connect(anim, "onEnd", function(){ 
+			s.height = "auto";
+			s.overflow = o;
+		});
+
+		return anim; // dojo._Animation
+	}
+
+	dojo.fx.wipeOut = function(/*Object*/ args){
+		// summary:
+		//		Returns an animation that will shrink node defined in "args"
+		//		from it's current height to 1px, and then hide it.
+		var node = args.node = d.byId(args.node), s = node.style, o;
+		
+		var anim = d.animateProperty(d.mixin({
+			properties: {
+				height: {
+					end: 1 // 0 causes IE to display the whole panel
+				}
+			}
+		}, args));
+
+		d.connect(anim, "beforeBegin", function(){
+			o = s.overflow;
+			s.overflow = "hidden";
+			s.display = "";
+		});
+		d.connect(anim, "onEnd", function(){
+			s.overflow = o;
+			s.height = "auto";
+			s.display = "none";
+		});
+
+		return anim; // dojo._Animation
+	}
+
+	dojo.fx.slideTo = function(/*Object?*/ args){
+		// summary:
+		//		Returns an animation that will slide "node" 
+		//		defined in args Object from its current position to
+		//		the position defined by (args.left, args.top).
+		// example:
+		//	|	dojo.fx.slideTo({ node: node, left:"40", top:"50", unit:"px" }).play()
+
+		var node = args.node = d.byId(args.node), 
+			top = null, left = null;
+
+		var init = (function(n){
+			return function(){
+				var cs = d.getComputedStyle(n);
+				var pos = cs.position;
+				top = (pos == 'absolute' ? n.offsetTop : parseInt(cs.top) || 0);
+				left = (pos == 'absolute' ? n.offsetLeft : parseInt(cs.left) || 0);
+				if(pos != 'absolute' && pos != 'relative'){
+					var ret = d.coords(n, true);
+					top = ret.y;
+					left = ret.x;
+					n.style.position="absolute";
+					n.style.top=top+"px";
+					n.style.left=left+"px";
+				}
+			};
+		})(node);
+		init();
+
+		var anim = d.animateProperty(d.mixin({
+			properties: {
+				top: args.top || 0,
+				left: args.left || 0
+			}
+		}, args));
+		d.connect(anim, "beforeBegin", anim, init);
+
+		return anim; // dojo._Animation
+	}
+
+})();
+
+}
+
+if(!dojo._hasResource["dijit.form._FormMixin"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form._FormMixin"] = true;
+dojo.provide("dijit.form._FormMixin");
+
+dojo.declare("dijit.form._FormMixin", null,
+	{
+	// summary:
+	//		Mixin for containers of form widgets (i.e. widgets that represent a single value
+	//		and can be children of a <form> node or dijit.form.Form widget)
+	// description:
+	//		Can extract all the form widgets
+	//		values and combine them into a single javascript object, or alternately
+	//		take such an object and set the values for all the contained
+	//		form widgets
+
+/*=====
+    // value: Object
+	//		Name/value hash for each form element.
+	//		If there are multiple elements w/the same name, value is an array,
+	//		unless they are radio buttons in which case value is a scalar since only
+	//		one can be checked at a time.
+	//
+	//		If the name is a dot separated list (like a.b.c.d), it's a nested structure.
+	//		Only works on widget form elements.
+	// example:
+	//	| { name: "John Smith", interests: ["sports", "movies"] }
+=====*/
+	
+	//	TODO:
+	//	* Repeater
+	//	* better handling for arrays.  Often form elements have names with [] like
+	//	* people[3].sex (for a list of people [{name: Bill, sex: M}, ...])
+	//
+	//	
+
+		reset: function(){
+			dojo.forEach(this.getDescendants(), function(widget){
+				if(widget.reset){
+					widget.reset();
+				}
+			});
+		},
+
+		validate: function(){
+			// summary: returns if the form is valid - same as isValid - but
+			//			provides a few additional (ui-specific) features.
+			//			1 - it will highlight any sub-widgets that are not
+			//				valid
+			//			2 - it will call focus() on the first invalid 
+			//				sub-widget
+			var didFocus = false;
+			return dojo.every(dojo.map(this.getDescendants(), function(widget){
+				// Need to set this so that "required" widgets get their 
+				// state set.
+				widget._hasBeenBlurred = true;
+				var valid = widget.disabled || !widget.validate || widget.validate();
+				if (!valid && !didFocus) {
+					// Set focus of the first non-valid widget
+					dijit.scrollIntoView(widget.containerNode||widget.domNode);
+					widget.focus();
+					didFocus = true;
+				}
+	 			return valid;
+	 		}), function(item) { return item; });
+		},
+	
+		setValues: function(val){
+			dojo.deprecated(this.declaredClass+"::setValues() is deprecated. Use attr('value', val) instead.", "", "2.0");
+			return this.attr('value', val);
+		},
+		_setValueAttr: function(/*object*/obj){
+			// summary: Fill in form values from according to an Object (in the format returned by attr('value'))
+
+			// generate map from name --> [list of widgets with that name]
+			var map = { };
+			dojo.forEach(this.getDescendants(), function(widget){
+				if(!widget.name){ return; }
+				var entry = map[widget.name] || (map[widget.name] = [] );
+				entry.push(widget);
+			});
+
+			for(var name in map){
+				if(!map.hasOwnProperty(name)){
+					continue;
+				}
+				var widgets = map[name],						// array of widgets w/this name
+					values = dojo.getObject(name, false, obj);	// list of values for those widgets
+
+				if(values===undefined){
+					continue;
+				}
+				if(!dojo.isArray(values)){
+					values = [ values ];
+				}
+				if(typeof widgets[0].checked == 'boolean'){
+					// for checkbox/radio, values is a list of which widgets should be checked
+					dojo.forEach(widgets, function(w, i){
+						w.attr('value', dojo.indexOf(values, w.value) != -1);
+					});
+				}else if(widgets[0]._multiValue){
+					// it takes an array (e.g. multi-select)
+					widgets[0].attr('value', values);
+				}else{
+					// otherwise, values is a list of values to be assigned sequentially to each widget
+					dojo.forEach(widgets, function(w, i){
+						w.attr('value', values[i]);
+					});					
+				}
+			}
+
+			/***
+			 * 	TODO: code for plain input boxes (this shouldn't run for inputs that are part of widgets)
+
+			dojo.forEach(this.containerNode.elements, function(element){
+				if (element.name == ''){return};	// like "continue"	
+				var namePath = element.name.split(".");
+				var myObj=obj;
+				var name=namePath[namePath.length-1];
+				for(var j=1,len2=namePath.length;j<len2;++j){
+					var p=namePath[j - 1];
+					// repeater support block
+					var nameA=p.split("[");
+					if (nameA.length > 1){
+						if(typeof(myObj[nameA[0]]) == "undefined"){
+							myObj[nameA[0]]=[ ];
+						} // if
+
+						nameIndex=parseInt(nameA[1]);
+						if(typeof(myObj[nameA[0]][nameIndex]) == "undefined"){
+							myObj[nameA[0]][nameIndex] = { };
+						}
+						myObj=myObj[nameA[0]][nameIndex];
+						continue;
+					} // repeater support ends
+
+					if(typeof(myObj[p]) == "undefined"){
+						myObj=undefined;
+						break;
+					};
+					myObj=myObj[p];
+				}
+
+				if (typeof(myObj) == "undefined"){
+					return;		// like "continue"
+				}
+				if (typeof(myObj[name]) == "undefined" && this.ignoreNullValues){
+					return;		// like "continue"
+				}
+
+				// TODO: widget values (just call attr('value', ...) on the widget)
+
+				switch(element.type){
+					case "checkbox":
+						element.checked = (name in myObj) &&
+							dojo.some(myObj[name], function(val){ return val==element.value; });
+						break;
+					case "radio":
+						element.checked = (name in myObj) && myObj[name]==element.value;
+						break;
+					case "select-multiple":
+						element.selectedIndex=-1;
+						dojo.forEach(element.options, function(option){
+							option.selected = dojo.some(myObj[name], function(val){ return option.value == val; });
+						});
+						break;
+					case "select-one":
+						element.selectedIndex="0";
+						dojo.forEach(element.options, function(option){
+							option.selected = option.value == myObj[name];
+						});
+						break;
+					case "hidden":
+					case "text":
+					case "textarea":
+					case "password":
+						element.value = myObj[name] || "";
+						break;
+				}
+	  		});
+	  		*/
+		},
+
+		getValues: function(){
+			dojo.deprecated(this.declaredClass+"::getValues() is deprecated. Use attr('value') instead.", "", "2.0");
+			return this.attr('value');
+		},
+		_getValueAttr: function(){
+			// summary:
+			// 		Returns Object representing form values.
+			// description:
+			//		Returns name/value hash for each form element.
+			//		If there are multiple elements w/the same name, value is an array,
+			//		unless they are radio buttons in which case value is a scalar since only
+			//		one can be checked at a time.
+			//
+			//		If the name is a dot separated list (like a.b.c.d), creates a nested structure.
+			//		Only works on widget form elements.
+			// example:
+			//		| { name: "John Smith", interests: ["sports", "movies"] }
+
+			// get widget values
+			var obj = { };
+			dojo.forEach(this.getDescendants(), function(widget){
+				var name = widget.name;
+				if(!name||widget.disabled){ return; }
+
+				// Single value widget (checkbox, radio, or plain <input> type widget
+				var value = widget.attr('value');
+
+				// Store widget's value(s) as a scalar, except for checkboxes which are automatically arrays
+				if(typeof widget.checked == 'boolean'){
+					if(/Radio/.test(widget.declaredClass)){
+						// radio button
+						if(value !== false){
+							dojo.setObject(name, value, obj);
+						}else{
+							// give radio widgets a default of null
+							value = dojo.getObject(name, false, obj);
+							if(value === undefined){
+								dojo.setObject(name, null, obj);
+							}
+						}
+					}else{
+						// checkbox/toggle button
+						var ary=dojo.getObject(name, false, obj);
+						if(!ary){
+							ary=[];
+							dojo.setObject(name, ary, obj);
+						}
+						if(value !== false){
+							ary.push(value);
+						}
+					}
+				}else{
+					// plain input
+					dojo.setObject(name, value, obj);
+				}
+			});
+
+			/***
+			 * code for plain input boxes (see also dojo.formToObject, can we use that instead of this code?
+			 * but it doesn't understand [] notation, presumably)
+			var obj = { };
+			dojo.forEach(this.containerNode.elements, function(elm){
+				if (!elm.name)	{
+					return;		// like "continue"
+				}
+				var namePath = elm.name.split(".");
+				var myObj=obj;
+				var name=namePath[namePath.length-1];
+				for(var j=1,len2=namePath.length;j<len2;++j){
+					var nameIndex = null;
+					var p=namePath[j - 1];
+					var nameA=p.split("[");
+					if (nameA.length > 1){
+						if(typeof(myObj[nameA[0]]) == "undefined"){
+							myObj[nameA[0]]=[ ];
+						} // if
+						nameIndex=parseInt(nameA[1]);
+						if(typeof(myObj[nameA[0]][nameIndex]) == "undefined"){
+							myObj[nameA[0]][nameIndex] = { };
+						}
+					} else if(typeof(myObj[nameA[0]]) == "undefined"){
+						myObj[nameA[0]] = { }
+					} // if
+
+					if (nameA.length == 1){
+						myObj=myObj[nameA[0]];
+					} else{
+						myObj=myObj[nameA[0]][nameIndex];
+					} // if
+				} // for
+
+				if ((elm.type != "select-multiple" && elm.type != "checkbox" && elm.type != "radio") || (elm.type=="radio" && elm.checked)){
+					if(name == name.split("[")[0]){
+						myObj[name]=elm.value;
+					} else{
+						// can not set value when there is no name
+					}
+				} else if (elm.type == "checkbox" && elm.checked){
+					if(typeof(myObj[name]) == 'undefined'){
+						myObj[name]=[ ];
+					}
+					myObj[name].push(elm.value);
+				} else if (elm.type == "select-multiple"){
+					if(typeof(myObj[name]) == 'undefined'){
+						myObj[name]=[ ];
+					}
+					for (var jdx=0,len3=elm.options.length; jdx<len3; ++jdx){
+						if (elm.options[jdx].selected){
+							myObj[name].push(elm.options[jdx].value);
+						}
+					}
+				} // if
+				name=undefined;
+			}); // forEach
+			***/
+			return obj;
+		},
+
+		// TODO: ComboBox might need time to process a recently input value.  This should be async?
+	 	isValid: function(){
+	 		// summary:
+	 		//		Returns true if all of the widgets are valid
+	 		
+	 		// This also populate this._invalidWidgets[] array with list of invalid widgets...
+	 		// TODO: put that into separate function?   It's confusing to have that as a side effect
+	 		// of a method named isValid().
+
+			this._invalidWidgets = dojo.filter(this.getDescendants(), function(widget){
+				return !widget.disabled && widget.isValid && !widget.isValid();
+	 		});
+			return !this._invalidWidgets.length;
+		},
+		
+		
+		onValidStateChange: function(isValid){
+			// summary:
+			//		Stub function to connect to if you want to do something
+			//		(like disable/enable a submit button) when the valid 
+			//		state changes on the form as a whole.
+		},
+		
+		_widgetChange: function(widget){
+			// summary:
+			//		Connected to a widget's onChange function - update our 
+			//		valid state, if needed.
+			var isValid = this._lastValidState;
+			if(!widget || this._lastValidState===undefined){
+				// We have passed a null widget, or we haven't been validated
+				// yet - let's re-check all our children
+				// This happens when we connect (or reconnect) our children
+				isValid = this.isValid();
+				if(this._lastValidState===undefined){
+					// Set this so that we don't fire an onValidStateChange 
+					// the first time
+					this._lastValidState = isValid;
+				}
+			}else if(widget.isValid){
+				this._invalidWidgets = dojo.filter(this._invalidWidgets||[], function(w){
+					return (w != widget);
+				}, this);
+				if(!widget.isValid() && !widget.attr("disabled")){
+					this._invalidWidgets.push(widget);
+				}
+				isValid = (this._invalidWidgets.length === 0);
+			}
+			if (isValid !== this._lastValidState){
+				this._lastValidState = isValid;
+				this.onValidStateChange(isValid);
+			}
+		},
+		
+		connectChildren: function(){
+			// summary:
+			//		Connects to the onChange function of all children to
+			//		track valid state changes.  You can call this function
+			//		directly, ex. in the event that you programmatically
+			//		add a widget to the form *after* the form has been
+			//		initialized.
+			dojo.forEach(this._changeConnections, dojo.hitch(this, "disconnect"));
+			var _this = this;
+			
+			// we connect to validate - so that it better reflects the states
+			// of the widgets - also, we only connect if it has a validate
+			// function (to avoid too many unneeded connections)
+			var conns = this._changeConnections = [];
+			dojo.forEach(dojo.filter(this.getDescendants(),
+				function(item){ return item.validate; }
+			),
+			function(widget){
+				// We are interested in whenever the widget is validated - or
+				// whenever the disabled attribute on that widget is changed
+				conns.push(_this.connect(widget, "validate", 
+									dojo.hitch(_this, "_widgetChange", widget)));
+				conns.push(_this.connect(widget, "_setDisabledAttr", 
+									dojo.hitch(_this, "_widgetChange", widget)));
+			});
+
+			// Call the widget change function to update the valid state, in 
+			// case something is different now.
+			this._widgetChange(null);
+		},
+		
+		startup: function(){
+			this.inherited(arguments);
+			// Initialize our valid state tracking.  Needs to be done in startup
+			// because it's not guaranteed that our children are initialized 
+			// yet.
+			this._changeConnections = [];
+			this.connectChildren();
+		}
+	});
+
+}
+
+if(!dojo._hasResource["dijit._DialogMixin"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._DialogMixin"] = true;
+dojo.provide("dijit._DialogMixin");
+
+dojo.declare("dijit._DialogMixin", null,
+	{
+		// summary:
+		//		This provides functions useful to Dialog and TooltipDialog
+
+		attributeMap: dijit._Widget.prototype.attributeMap,
+
+		execute: function(/*Object*/ formContents){
+			// summary:
+			//		Callback when the user hits the submit button.
+			//		Override this method to handle Dialog execution.
+			// description:
+			//		After the user has pressed the submit button, the Dialog
+			//		first calls onExecute() to notify the container to hide the
+			//		dialog and restore focus to wherever it used to be.
+			//
+			//		*Then* this method is called.
+			// type:
+			//		callback
+		},
+
+		onCancel: function(){
+			// summary:
+			//	    Called when user has pressed the Dialog's cancel button, to notify container.
+			// description:
+			//	    Developer shouldn't override or connect to this method;
+			//		it's a private communication device between the TooltipDialog
+			//		and the thing that opened it (ex: `dijit.form.DropDownButton`)
+			// type:
+			//		protected
+		},
+
+		onExecute: function(){
+			// summary:
+			//	    Called when user has pressed the dialog's OK button, to notify container.
+			// description:
+			//	    Developer shouldn't override or connect to this method;
+			//		it's a private communication device between the TooltipDialog
+			//		and the thing that opened it (ex: `dijit.form.DropDownButton`)
+			// type:
+			//		protected
+		},
+
+		_onSubmit: function(){
+			// summary:
+			//		Callback when user hits submit button
+			// type:
+			//		protected
+			this.onExecute();	// notify container that we are about to execute
+			this.execute(this.attr('value'));
+		},
+
+		_getFocusItems: function(/*Node*/ dialogNode){
+			// summary:
+			//		Find focusable Items each time a dialog is opened,
+			//		setting _firstFocusItem and _lastFocusItem
+			// tags:
+			//		protected
+			
+			var elems = dijit._getTabNavigable(dojo.byId(dialogNode));
+			this._firstFocusItem = elems.lowest || elems.first || dialogNode;
+			this._lastFocusItem = elems.last || elems.highest || this._firstFocusItem;
+			if(dojo.isMoz && this._firstFocusItem.tagName.toLowerCase() == "input" && dojo.attr(this._firstFocusItem, "type").toLowerCase() == "file"){
+					//FF doesn't behave well when first element is input type=file, set first focusable to dialog container
+					dojo.attr(dialogNode, "tabindex", "0");
+					this._firstFocusItem = dialogNode;
+			}
+		}
+	}
+);
+
+}
+
+if(!dojo._hasResource["dijit.DialogUnderlay"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.DialogUnderlay"] = true;
+dojo.provide("dijit.DialogUnderlay");
+
+
+
+
+dojo.declare(
+	"dijit.DialogUnderlay",
+	[dijit._Widget, dijit._Templated],
+	{
+		// summary: The component that blocks the screen behind a `dijit.Dialog`
+		//
+		// description:
+		// 		A component used to block input behind a `dijit.Dialog`. Only a single
+		//		instance of this widget is created by `dijit.Dialog`, and saved as 
+		//		a reference to be shared between all Dialogs as `dijit._underlay`
+		//	
+		//		The underlay itself can be styled based on and id:
+		//	|	#myDialog_underlay { background-color:red; }
+		//
+		//		In the case of `dijit.Dialog`, this id is based on the id of the Dialog,
+		//		suffixed with _underlay. 
+		
+		// Template has two divs; outer div is used for fade-in/fade-out, and also to hold background iframe.
+		// Inner div has opacity specified in CSS file.
+		templateString: "<div class='dijitDialogUnderlayWrapper'><div class='dijitDialogUnderlay' dojoAttachPoint='node'></div></div>",
+
+		// Parameters on creation or updatable later
+
+		// dialogId: String
+		//		Id of the dialog.... DialogUnderlay's id is based on this id
+		dialogId: "",
+
+		// class: String
+		//		This class name is used on the DialogUnderlay node, in addition to dijitDialogUnderlay
+		"class": "",
+
+		attributeMap: { id: "domNode" },
+
+		_setDialogIdAttr: function(id){
+			dojo.attr(this.node, "id", id + "_underlay");
+		},
+
+		_setClassAttr: function(clazz){
+			this.node.className = "dijitDialogUnderlay " + clazz;
+		},
+
+		postCreate: function(){
+			// summary:
+			//		Append the underlay to the body
+			dojo.body().appendChild(this.domNode);
+			this.bgIframe = new dijit.BackgroundIframe(this.domNode);
+		},
+
+		layout: function(){
+			// summary:
+			//		Sets the background to the size of the viewport
+			//
+			// description:
+			//		Sets the background to the size of the viewport (rather than the size
+			//		of the document) since we need to cover the whole browser window, even
+			//		if the document is only a few lines long.
+			// tags:
+			//		private
+
+			var is = this.node.style,
+				os = this.domNode.style;
+
+			// hide the background temporarily, so that the background itself isn't
+			// causing scrollbars to appear (might happen when user shrinks browser
+			// window and then we are called to resize)
+			os.display = "none";
+
+			// then resize and show
+			var viewport = dijit.getViewport();
+			os.top = viewport.t + "px";
+			os.left = viewport.l + "px";
+			is.width = viewport.w + "px";
+			is.height = viewport.h + "px";
+			os.display = "block";
+		},
+
+		show: function(){
+			// summary:
+			//		Show the dialog underlay
+			this.domNode.style.display = "block";
+			this.layout();
+			if(this.bgIframe.iframe){
+				this.bgIframe.iframe.style.display = "block";
+			}
+		},
+
+		hide: function(){
+			// summary:
+			//		Hides the dialog underlay
+			this.domNode.style.display = "none";
+			if(this.bgIframe.iframe){
+				this.bgIframe.iframe.style.display = "none";
+			}
+		},
+
+		uninitialize: function(){
+			if(this.bgIframe){
+				this.bgIframe.destroy();
+			}
+		}
+	}
+);
+
+}
+
+if(!dojo._hasResource["dojo.html"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.html"] = true;
+dojo.provide("dojo.html");
+
+// the parser might be needed..
+ 
+
+(function(){ // private scope, sort of a namespace
+
+	// idCounter is incremented with each instantiation to allow asignment of a unique id for tracking, logging purposes
+	var idCounter = 0; 
+
+	dojo.html._secureForInnerHtml = function(/*String*/ cont){
+		// summary:
+		//		removes !DOCTYPE and title elements from the html string.
+		// 
+		//		khtml is picky about dom faults, you can't attach a style or <title> node as child of body
+		//		must go into head, so we need to cut out those tags
+		//	cont:
+		//		An html string for insertion into the dom
+		//	
+		return cont.replace(/(?:\s*<!DOCTYPE\s[^>]+>|<title[^>]*>[\s\S]*?<\/title>)/ig, ""); // String
+	};
+
+/*====
+	dojo.html._emptyNode = function(node){
+		// summary:
+		//		removes all child nodes from the given node
+		//	node: DOMNode
+		//		the parent element
+	};
+=====*/
+	dojo.html._emptyNode = dojo.empty;
+
+	dojo.html._setNodeContent = function(/* DomNode */ node, /* String|DomNode|NodeList */ cont, /* Boolean? */ shouldEmptyFirst){
+		// summary:
+		//		inserts the given content into the given node
+		//		overlaps similiar functionality in dijit.layout.ContentPane._setContent
+		//	node:
+		//		the parent element
+		//	content:
+		//		the content to be set on the parent element. 
+		//		This can be an html string, a node reference or a NodeList, dojo.NodeList, Array or other enumerable list of nodes
+		// shouldEmptyFirst
+		//		if shouldEmptyFirst is true, the node will first be emptied of all content before the new content is inserted
+		//		defaults to false
+		if(shouldEmptyFirst){
+			dojo.html._emptyNode(node); 
+		}
+
+		if(typeof cont == "string"){
+			// there's some hoops to jump through before we can set innerHTML on the would-be parent element. 
+	
+			// rationale for this block:
+			// if node is a table derivate tag, some browsers dont allow innerHTML on those
+			// TODO: <select>, <dl>? what other elements will give surprises if you naively set innerHTML?
+			
+			var pre = '', post = '', walk = 0, name = node.nodeName.toLowerCase();
+			switch(name){
+				case 'tr':
+					pre = '<tr>'; post = '</tr>';
+					walk += 1;//fallthrough
+				case 'tbody': case 'thead':// children of THEAD is of same type as TBODY
+					pre = '<tbody>' + pre; post += '</tbody>';
+					walk += 1;// falltrough
+				case 'table':
+					pre = '<table>' + pre; post += '</table>';
+					walk += 1;
+					break;
+			}
+			if(walk){
+				var n = node.ownerDocument.createElement('div');
+				n.innerHTML = pre + cont + post;
+				do{
+					n = n.firstChild;
+				}while(--walk);
+				// now we can safely add the child nodes...
+				dojo.forEach(n.childNodes, function(n){
+					node.appendChild(n.cloneNode(true));
+				});
+			}else{
+				// innerHTML the content as-is into the node (element)
+				// should we ever support setting content on non-element node types? 
+				// e.g. text nodes, comments, etc.?
+				node.innerHTML = cont;
+			}
+
+		}else{
+			// DomNode or NodeList
+			if(cont.nodeType){ // domNode (htmlNode 1 or textNode 3)
+				node.appendChild(cont);
+			}else{// nodelist or array such as dojo.Nodelist
+				dojo.forEach(cont, function(n){
+					node.appendChild(n.cloneNode(true));
+				});
+			}
+		}
+		// return DomNode
+		return node;
+	};
+
+	// we wrap up the content-setting operation in a object
+	dojo.declare("dojo.html._ContentSetter", null, 
+		{
+			// node: DomNode|String
+			//		An node which will be the parent element that we set content into
+			node: "",
+
+			// content: String|DomNode|DomNode[]
+			//		The content to be placed in the node. Can be an HTML string, a node reference, or a enumerable list of nodes
+			content: "",
+			
+			// id: String?
+			//		Usually only used internally, and auto-generated with each instance 
+			id: "",
+
+			// cleanContent: Boolean
+			//		Should the content be treated as a full html document, 
+			//		and the real content stripped of <html>, <body> wrapper before injection
+			cleanContent: false,
+			
+			// extractContent: Boolean
+			//		Should the content be treated as a full html document, and the real content stripped of <html>, <body> wrapper before injection
+			extractContent: false,
+
+			// parseContent: Boolean
+			//		Should the node by passed to the parser after the new content is set
+			parseContent: false,
+			
+			// lifecyle methods
+			constructor: function(/* Object */params, /* String|DomNode */node){
+				//	summary:
+				//		Provides a configurable, extensible object to wrap the setting on content on a node
+				//		call the set() method to actually set the content..
+ 
+				// the original params are mixed directly into the instance "this"
+				dojo.mixin(this, params || {});
+
+				// give precedence to params.node vs. the node argument
+				// and ensure its a node, not an id string
+				node = this.node = dojo.byId( this.node || node );
+	
+				if(!this.id){
+					this.id = [
+						"Setter",
+						(node) ? node.id || node.tagName : "", 
+						idCounter++
+					].join("_");
+				}
+
+				if(! (this.node || node)){
+					new Error(this.declaredClass + ": no node provided to " + this.id);
+				}
+			},
+			set: function(/* String|DomNode|NodeList? */ cont, /* Object? */ params){
+				// summary:
+				//		front-end to the set-content sequence 
+				//	cont:
+				//		An html string, node or enumerable list of nodes for insertion into the dom
+				//		If not provided, the object's content property will be used
+				if(undefined !== cont){
+					this.content = cont;
+				}
+				// in the re-use scenario, set needs to be able to mixin new configuration
+				if(params){
+					this._mixin(params);
+				}
+
+				this.onBegin();
+				this.setContent();
+				this.onEnd();
+
+				return this.node;
+			},
+			setContent: function(){
+				// summary:
+				//		sets the content on the node 
+
+				var node = this.node; 
+				if(!node) {
+					console.error("setContent given no node");
+				}
+				try{
+					node = dojo.html._setNodeContent(node, this.content);
+				}catch(e){
+					// check if a domfault occurs when we are appending this.errorMessage
+					// like for instance if domNode is a UL and we try append a DIV
+	
+					// FIXME: need to allow the user to provide a content error message string
+					var errMess = this.onContentError(e); 
+					try{
+						node.innerHTML = errMess;
+					}catch(e){
+						console.error('Fatal ' + this.declaredClass + '.setContent could not change content due to '+e.message, e);
+					}
+				}
+				// always put back the node for the next method
+				this.node = node; // DomNode
+			},
+			
+			empty: function() {
+				// summary
+				//	cleanly empty out existing content
+
+				// destroy any widgets from a previous run
+				// NOTE: if you dont want this you'll need to empty 
+				// the parseResults array property yourself to avoid bad things happenning
+				if(this.parseResults && this.parseResults.length) {
+					dojo.forEach(this.parseResults, function(w) {
+						if(w.destroy){
+							w.destroy();
+						}
+					});
+					delete this.parseResults;
+				}
+				// this is fast, but if you know its already empty or safe, you could 
+				// override empty to skip this step
+				dojo.html._emptyNode(this.node);
+			},
+	
+			onBegin: function(){
+				// summary
+				//		Called after instantiation, but before set(); 
+				//		It allows modification of any of the object properties 
+				//		- including the node and content provided - before the set operation actually takes place
+				//		This default implementation checks for cleanContent and extractContent flags to 
+				//		optionally pre-process html string content
+				var cont = this.content;
+	
+				if(dojo.isString(cont)){
+					if(this.cleanContent){
+						cont = dojo.html._secureForInnerHtml(cont);
+					}
+  
+					if(this.extractContent){
+						var match = cont.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
+						if(match){ cont = match[1]; }
+					}
+				}
+
+				// clean out the node and any cruft associated with it - like widgets
+				this.empty();
+				
+				this.content = cont;
+				return this.node; /* DomNode */
+			},
+	
+			onEnd: function(){
+				// summary
+				//		Called after set(), when the new content has been pushed into the node
+				//		It provides an opportunity for post-processing before handing back the node to the caller
+				//		This default implementation checks a parseContent flag to optionally run the dojo parser over the new content
+				if(this.parseContent){
+					// populates this.parseResults if you need those..
+					this._parse();
+				}
+				return this.node; /* DomNode */
+			},
+	
+			tearDown: function(){
+				// summary
+				//		manually reset the Setter instance if its being re-used for example for another set()
+				// description
+				//		tearDown() is not called automatically. 
+				//		In normal use, the Setter instance properties are simply allowed to fall out of scope
+				//		but the tearDown method can be called to explicitly reset this instance.
+				delete this.parseResults; 
+				delete this.node; 
+				delete this.content; 
+			},
+  
+			onContentError: function(err){
+				return "Error occured setting content: " + err; 
+			},
+			
+			_mixin: function(params){
+				// mix properties/methods into the instance
+				// TODO: the intention with tearDown is to put the Setter's state 
+				// back to that of the original constructor (vs. deleting/resetting everything regardless of ctor params)
+				// so we could do something here to move the original properties aside for later restoration
+				var empty = {}, key;
+				for(key in params){
+					if(key in empty){ continue; }
+					// TODO: here's our opportunity to mask the properties we dont consider configurable/overridable
+					// .. but history shows we'll almost always guess wrong
+					this[key] = params[key]; 
+				}
+			},
+			_parse: function(){
+				// summary: 
+				//		runs the dojo parser over the node contents, storing any results in this.parseResults
+				//		Any errors resulting from parsing are passed to _onError for handling
+
+				var rootNode = this.node;
+				try{
+					// store the results (widgets, whatever) for potential retrieval
+					this.parseResults = dojo.parser.parse(rootNode, true);
+				}catch(e){
+					this._onError('Content', e, "Error parsing in _ContentSetter#"+this.id);
+				}
+			},
+  
+			_onError: function(type, err, consoleText){
+				// summary:
+				//		shows user the string that is returned by on[type]Error
+				//		overide/implement on[type]Error and return your own string to customize
+				var errText = this['on' + type + 'Error'].call(this, err);
+				if(consoleText){
+					console.error(consoleText, err);
+				}else if(errText){ // a empty string won't change current content
+					dojo.html._setNodeContent(this.node, errText, true);
+				}
+			}
+	}); // end dojo.declare()
+
+	dojo.html.set = function(/* DomNode */ node, /* String|DomNode|NodeList */ cont, /* Object? */ params){
+			// summary:
+			//		inserts (replaces) the given content into the given node. dojo.place(cont, node, "only")
+			//		may be a better choice for simple HTML insertion.
+			// description:
+			//		Unless you need to use the params capabilities of this method, you should use
+			//		dojo.place(cont, node, "only"). dojo.place() has more robust support for injecting
+			//		an HTML string into the DOM, but it only handles inserting an HTML string as DOM
+			//		elements, or inserting a DOM node. dojo.place does not handle NodeList insertions
+			//		or the other capabilities as defined by the params object for this method.
+			//	node:
+			//		the parent element that will receive the content
+			//	cont:
+			//		the content to be set on the parent element. 
+			//		This can be an html string, a node reference or a NodeList, dojo.NodeList, Array or other enumerable list of nodes
+			//	params: 
+			//		Optional flags/properties to configure the content-setting. See dojo.html._ContentSetter
+			//	example:
+			//		A safe string/node/nodelist content replacement/injection with hooks for extension
+			//		Example Usage: 
+			//		dojo.html.set(node, "some string"); 
+			//		dojo.html.set(node, contentNode, {options}); 
+			//		dojo.html.set(node, myNode.childNodes, {options}); 
+		if(undefined == cont){
+			console.warn("dojo.html.set: no cont argument provided, using empty string");
+			cont = "";
+		}	
+		if(!params){
+			// simple and fast
+			return dojo.html._setNodeContent(node, cont, true);
+		}else{ 
+			// more options but slower
+			// note the arguments are reversed in order, to match the convention for instantiation via the parser
+			var op = new dojo.html._ContentSetter(dojo.mixin( 
+					params, 
+					{ content: cont, node: node } 
+			));
+			return op.set();
+		}
+	};
+})();
+
+}
+
+if(!dojo._hasResource["dijit.layout.ContentPane"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.layout.ContentPane"] = true;
+dojo.provide("dijit.layout.ContentPane");
+
+
+
+	// for dijit.layout.marginBox2contentBox()
+
+
+
+
+
+
+dojo.declare(
+	"dijit.layout.ContentPane", dijit._Widget,
+{
+	// summary:
+	//		A widget that acts as a container for mixed HTML and widgets, and includes an Ajax interface
+	// description:
+	//		A widget that can be used as a standalone widget
+	//		or as a baseclass for other widgets
+	//		Handles replacement of document fragment using either external uri or javascript
+	//		generated markup or DOM content, instantiating widgets within that content.
+	//		Don't confuse it with an iframe, it only needs/wants document fragments.
+	//		It's useful as a child of LayoutContainer, SplitContainer, or TabContainer.
+	//		But note that those classes can contain any widget as a child.
+	// example:
+	//		Some quick samples:
+	//		To change the innerHTML use .attr('content', '<b>new content</b>')
+	//
+	//		Or you can send it a NodeList, .attr('content', dojo.query('div [class=selected]', userSelection))
+	//		please note that the nodes in NodeList will copied, not moved
+	//
+	//		To do a ajax update use .attr('href', url)
+
+	// href: String
+	//		The href of the content that displays now.
+	//		Set this at construction if you want to load data externally when the
+	//		pane is shown.	(Set preload=true to load it immediately.)
+	//		Changing href after creation doesn't have any effect; use attr('href', ...);
+	href: "",
+
+/*=====
+	// content: String || DomNode || NodeList || dijit._Widget
+	//		The innerHTML of the ContentPane.
+	//		Note that the initialization parameter / argument to attr("content", ...)
+	//		can be a String, DomNode, Nodelist, or _Widget.
+	content: "",
+=====*/
+
+	// extractContent: Boolean
+	//		Extract visible content from inside of <body> .... </body>.
+	//		I.e., strip <html> and <head> (and it's contents) from the href
+	extractContent: false,
+
+	// parseOnLoad: Boolean
+	//		Parse content and create the widgets, if any.
+	parseOnLoad:	true,
+
+	// preventCache: Boolean
+	//		Prevent caching of data from href's by appending a timestamp to the href.
+	preventCache:	false,
+
+	// preload: Boolean
+	//		Force load of data on initialization even if pane is hidden.
+	preload: false,
+
+	// refreshOnShow: Boolean
+	//		Refresh (re-download) content when pane goes from hidden to shown
+	refreshOnShow: false,
+
+	// loadingMessage: String
+	//		Message that shows while downloading
+	loadingMessage: "<span class='dijitContentPaneLoading'>${loadingState}</span>", 
+
+	// errorMessage: String
+	//		Message that shows if an error occurs
+	errorMessage: "<span class='dijitContentPaneError'>${errorState}</span>", 
+
+	// isLoaded: [readonly] Boolean
+	//		True if the ContentPane has data in it, either specified
+	//		during initialization (via href or inline content), or set
+	//		via attr('content', ...) / attr('href', ...)
+	//
+	//		False if it doesn't have any content, or if ContentPane is
+	//		still in the process of downloading href.
+	isLoaded: false,
+
+	baseClass: "dijitContentPane",
+
+	// doLayout: Boolean
+	//		- false - don't adjust size of children
+	//		- true - if there is a single visible child widget, set it's size to
+	//				however big the ContentPane is
+	doLayout: true,
+
+	// ioArgs: Object
+	//		Parameters to pass to xhrGet() request, for example:
+	// |	<div dojoType="dijit.layout.ContentPane" href="./bar" ioArgs="{timeout: 500}">
+	ioArgs: {},
+
+	// isContainer: [protected] Boolean
+	//		Just a flag indicating that this widget will call resize() on
+	//		its children.   _LayoutWidget based widgets check for
+	//
+	//	|		if(!this.getParent || !this.getParent()){
+	//
+	//		and if getParent() returns false because !parent.isContainer,
+	//		then they resize themselves on initialization.
+	isContainer: true,
+
+	postMixInProperties: function(){
+		this.inherited(arguments);
+		var messages = dojo.i18n.getLocalization("dijit", "loading", this.lang);
+		this.loadingMessage = dojo.string.substitute(this.loadingMessage, messages);
+		this.errorMessage = dojo.string.substitute(this.errorMessage, messages);
+		
+		// Detect if we were initialized with data
+		if(!this.href && this.srcNodeRef && this.srcNodeRef.innerHTML){
+			this.isLoaded = true;
+		}
+	},
+
+	buildRendering: function(){
+		// Overrides Widget.buildRendering().
+		// Since we have no template we need to set this.containerNode ourselves.
+		// For subclasses of ContentPane do have a template, does nothing.
+		this.inherited(arguments);
+		if(!this.containerNode){
+			// make getDescendants() work
+			this.containerNode = this.domNode;
+		}
+	},
+
+	postCreate: function(){
+		// remove the title attribute so it doesn't show up when hovering
+		// over a node
+		this.domNode.title = "";
+
+		if (!dojo.attr(this.domNode,"role")){
+			dijit.setWaiRole(this.domNode, "group");
+		}
+
+		dojo.addClass(this.domNode, this.baseClass);
+	},
+
+	startup: function(){
+		// summary:
+		//		See `dijit.layout._LayoutWidget.startup` for description.
+		//		Although ContentPane doesn't extend _LayoutWidget, it does implement
+		//		the same API.
+		if(this._started){ return; }
+
+		if(this.isLoaded){
+			dojo.forEach(this.getChildren(), function(child){
+				child.startup();
+			});
+
+			// If we have static content in the content pane (specified during
+			// initialization) then we need to do layout now... unless we are
+			// a child of a TabContainer etc. in which case wait until the TabContainer
+			// calls resize() on us.
+			if(this.doLayout){
+				this._checkIfSingleChild();
+			}
+			if(!this._singleChild || !dijit._Contained.prototype.getParent.call(this)){
+				this._scheduleLayout();
+			}
+		}
+		
+		// If we have an href then check if we should load it now
+		this._loadCheck();
+
+		this.inherited(arguments);
+	},
+
+	_checkIfSingleChild: function(){
+		// summary:
+		//		Test if we have exactly one visible widget as a child,
+		//		and if so assume that we are a container for that widget,
+		//		and should propogate startup() and resize() calls to it.
+		//		Skips over things like data stores since they aren't visible.
+
+		var childNodes = dojo.query(">", this.containerNode),
+			childWidgetNodes = childNodes.filter(function(node){
+				return dojo.hasAttr(node, "dojoType") || dojo.hasAttr(node, "widgetId");
+			}),
+			candidateWidgets = dojo.filter(childWidgetNodes.map(dijit.byNode), function(widget){
+				return widget && widget.domNode && widget.resize;
+			});
+
+		if(
+			// all child nodes are widgets
+			childNodes.length == childWidgetNodes.length &&
+
+			// all but one are invisible (like dojo.data)
+			candidateWidgets.length == 1
+		){
+			this._singleChild = candidateWidgets[0];
+		}else{
+			delete this._singleChild;
+		}
+	},
+
+	setHref: function(/*String|Uri*/ href){
+		// summary:
+		//		Deprecated.   Use attr('href', ...) instead.
+		dojo.deprecated("dijit.layout.ContentPane.setHref() is deprecated. Use attr('href', ...) instead.", "", "2.0");
+		return this.attr("href", href);
+	},
+	_setHrefAttr: function(/*String|Uri*/ href){
+		// summary:
+		//		Hook so attr("href", ...) works.
+		// description:
+		//		Reset the (external defined) content of this pane and replace with new url
+		//		Note: It delays the download until widget is shown if preload is false.
+		//	href:
+		//		url to the page you want to get, must be within the same domain as your mainpage
+
+		// Cancel any in-flight requests (an attr('href') will cancel any in-flight attr('href', ...))
+		this.cancel();
+
+		this.href = href;
+
+		// _setHrefAttr() is called during creation and by the user, after creation.
+		// only in the second case do we actually load the URL; otherwise it's done in startup()
+		if(this._created && (this.preload || this._isShown())){
+			// we return result of refresh() here to avoid code dup. in dojox.layout.ContentPane
+			return this.refresh();
+		}else{
+			// Set flag to indicate that href needs to be loaded the next time the
+			// ContentPane is made visible
+			this._hrefChanged = true;
+		}
+	},
+
+	setContent: function(/*String|DomNode|Nodelist*/data){
+		// summary:
+		//		Deprecated.   Use attr('content', ...) instead.
+		dojo.deprecated("dijit.layout.ContentPane.setContent() is deprecated.  Use attr('content', ...) instead.", "", "2.0");
+		this.attr("content", data);
+	},
+	_setContentAttr: function(/*String|DomNode|Nodelist*/data){
+		// summary:
+		//		Hook to make attr("content", ...) work.
+		//		Replaces old content with data content, include style classes from old content
+		//	data:
+		//		the new Content may be String, DomNode or NodeList
+		//
+		//		if data is a NodeList (or an array of nodes) nodes are copied
+		//		so you can import nodes from another document implicitly
+
+		// clear href so we can't run refresh and clear content
+		// refresh should only work if we downloaded the content
+		this.href = "";
+
+		// Cancel any in-flight requests (an attr('content') will cancel any in-flight attr('href', ...))
+		this.cancel();
+
+		this._setContent(data || "");
+
+		this._isDownloaded = false; // mark that content is from a attr('content') not an attr('href')
+	},
+	_getContentAttr: function(){
+		// summary:
+		//		Hook to make attr("content") work
+		return this.containerNode.innerHTML;
+	},
+
+	cancel: function(){
+		// summary:
+		//		Cancels an in-flight download of content
+		if(this._xhrDfd && (this._xhrDfd.fired == -1)){
+			this._xhrDfd.cancel();
+		}
+		delete this._xhrDfd; // garbage collect
+	},
+
+	uninitialize: function(){
+		if(this._beingDestroyed){
+			this.cancel();
+		}
+	},
+
+	destroyRecursive: function(/*Boolean*/ preserveDom){
+		// summary:
+		//		Destroy the ContentPane and its contents
+
+		// if we have multiple controllers destroying us, bail after the first
+		if(this._beingDestroyed){
+			return;
+		}
+		this._beingDestroyed = true;
+		this.inherited(arguments);
+	},
+
+	resize: function(size){
+		// summary:
+		//		See `dijit.layout._LayoutWidget.resize` for description.
+		//		Although ContentPane doesn't extend _LayoutWidget, it does implement
+		//		the same API.
+
+		dojo.marginBox(this.domNode, size);
+
+		// Compute content box size in case we [later] need to size child
+		// If either height or width wasn't specified by the user, then query node for it.
+		// But note that setting the margin box and then immediately querying dimensions may return
+		// inaccurate results, so try not to depend on it.
+		var node = this.containerNode,
+			mb = dojo.mixin(dojo.marginBox(node), size||{});
+
+		var cb = (this._contentBox = dijit.layout.marginBox2contentBox(node, mb));
+
+		// If we have a single widget child then size it to fit snugly within my borders
+		if(this._singleChild && this._singleChild.resize){
+			// note: if widget has padding this._contentBox will have l and t set,
+			// but don't pass them to resize() or it will doubly-offset the child
+			this._singleChild.resize({w: cb.w, h: cb.h});
+		}
+	},
+
+	_isShown: function(){
+		// summary:
+		//		Returns true if the content is currently shown
+		if("open" in this){
+			return this.open;		// for TitlePane, etc.
+		}else{
+			var node = this.domNode;
+			return (node.style.display != 'none')  && (node.style.visibility != 'hidden') && !dojo.hasClass(node, "dijitHidden");
+		}
+	},
+
+	_onShow: function(){
+		// summary:
+		//		Called when the ContentPane is made visible
+		// description:
+		//		For a plain ContentPane, this is called on initialization, from startup().
+		//		If the ContentPane is a hidden pane of a TabContainer etc., then it's
+		//		called whever the pane is made visible.
+		//
+		//		Does processing necessary, including href download and layout/resize of
+		//		child widget(s)
+
+		if(this._needLayout){
+			// If a layout has been scheduled for when we become visible, do it now
+			this._layoutChildren();
+		}
+
+		// Do lazy-load of URL
+		this._loadCheck();
+
+		// call onShow, if we have one
+		if(this.onShow){
+			this.onShow();
+		}
+	},
+
+	_loadCheck: function(){
+		// summary:
+		//		Call this to load href contents if necessary.
+		// description:
+		//		Call when !ContentPane has been made visible [from prior hidden state],
+		//		or href has been changed, or on startup, etc.
+
+		if(
+			(this.href && !this._xhrDfd) &&		// if there's an href that isn't already being loaded
+			(!this.isLoaded || this._hrefChanged || this.refreshOnShow) && 	// and we need a [re]load
+			(this.preload || this._isShown())	// and now is the time to [re]load
+		){
+			delete this._hrefChanged;
+			this.refresh();
+		}
+	},
+
+	refresh: function(){
+		// summary:
+		//		[Re]download contents of href and display
+		// description:
+		//		1. cancels any currently in-flight requests
+		//		2. posts "loading..." message
+		//		3. sends XHR to download new data
+
+		// cancel possible prior inflight request
+		this.cancel();
+
+		// display loading message
+		this._setContent(this.onDownloadStart(), true);
+
+		var self = this;
+		var getArgs = {
+			preventCache: (this.preventCache || this.refreshOnShow),
+			url: this.href,
+			handleAs: "text"
+		};
+		if(dojo.isObject(this.ioArgs)){
+			dojo.mixin(getArgs, this.ioArgs);
+		}
+
+		var hand = (this._xhrDfd = (this.ioMethod || dojo.xhrGet)(getArgs));
+
+		hand.addCallback(function(html){
+			try{
+				self._isDownloaded = true;
+				self._setContent(html, false);
+				self.onDownloadEnd();
+			}catch(err){
+				self._onError('Content', err); // onContentError
+			}
+			delete self._xhrDfd;
+			return html;
+		});
+
+		hand.addErrback(function(err){
+			if(!hand.canceled){
+				// show error message in the pane
+				self._onError('Download', err); // onDownloadError
+			}
+			delete self._xhrDfd;
+			return err;
+		});
+	},
+
+	_onLoadHandler: function(data){
+		// summary:
+		//		This is called whenever new content is being loaded
+		this.isLoaded = true;
+		try{
+			this.onLoad(data);			
+		}catch(e){
+			console.error('Error '+this.widgetId+' running custom onLoad code: ' + e.message);
+		}
+	},
+
+	_onUnloadHandler: function(){
+		// summary:
+		//		This is called whenever the content is being unloaded
+		this.isLoaded = false;
+		try{
+			this.onUnload();
+		}catch(e){
+			console.error('Error '+this.widgetId+' running custom onUnload code: ' + e.message);
+		}
+	},
+
+	destroyDescendants: function(){
+		// summary:
+		//		Destroy all the widgets inside the ContentPane and empty containerNode
+
+		// Make sure we call onUnload (but only when the ContentPane has real content)
+		if(this.isLoaded){
+			this._onUnloadHandler();
+		}
+
+		// Even if this.isLoaded == false there might still be a "Loading..." message
+		// to erase, so continue...
+
+		// For historical reasons we need to delete all widgets under this.containerNode,
+		// even ones that the user has created manually.
+		var setter = this._contentSetter;
+		dojo.forEach(this.getChildren(), function(widget){
+			if(widget.destroyRecursive){
+				widget.destroyRecursive();
+			}
+		});
+		if(setter){
+			// Most of the widgets in setter.parseResults have already been destroyed, but
+			// things like Menu that have been moved to <body> haven't yet
+			dojo.forEach(setter.parseResults, function(widget){
+				if(widget.destroyRecursive && widget.domNode && widget.domNode.parentNode == dojo.body()){
+					widget.destroyRecursive();
+				}
+			});
+			delete setter.parseResults;
+		}
+		
+		// And then clear away all the DOM nodes
+		dojo.html._emptyNode(this.containerNode);
+	},
+
+	_setContent: function(cont, isFakeContent){
+		// summary: 
+		//		Insert the content into the container node
+
+		// first get rid of child widgets
+		this.destroyDescendants();
+
+		// Delete any state information we have about current contents
+		delete this._singleChild;
+
+		// dojo.html.set will take care of the rest of the details
+		// we provide an overide for the error handling to ensure the widget gets the errors 
+		// configure the setter instance with only the relevant widget instance properties
+		// NOTE: unless we hook into attr, or provide property setters for each property, 
+		// we need to re-configure the ContentSetter with each use
+		var setter = this._contentSetter; 
+		if(! (setter && setter instanceof dojo.html._ContentSetter)) {
+			setter = this._contentSetter = new dojo.html._ContentSetter({
+				node: this.containerNode,
+				_onError: dojo.hitch(this, this._onError),
+				onContentError: dojo.hitch(this, function(e){
+					// fires if a domfault occurs when we are appending this.errorMessage
+					// like for instance if domNode is a UL and we try append a DIV
+					var errMess = this.onContentError(e);
+					try{
+						this.containerNode.innerHTML = errMess;
+					}catch(e){
+						console.error('Fatal '+this.id+' could not change content due to '+e.message, e);
+					}
+				})/*,
+				_onError */
+			});
+		};
+
+		var setterParams = dojo.mixin({
+			cleanContent: this.cleanContent, 
+			extractContent: this.extractContent, 
+			parseContent: this.parseOnLoad 
+		}, this._contentSetterParams || {});
+		
+		dojo.mixin(setter, setterParams); 
+
+		setter.set( (dojo.isObject(cont) && cont.domNode) ? cont.domNode : cont );
+
+		// setter params must be pulled afresh from the ContentPane each time
+		delete this._contentSetterParams;
+
+		if(!isFakeContent){
+			dojo.forEach(this.getChildren(), function(child){
+				child.startup();
+			});
+
+			if(this.doLayout){
+				this._checkIfSingleChild();
+			}
+
+			// Call resize() on each of my child layout widgets,
+			// or resize() on my single child layout widget...
+			// either now (if I'm currently visible)
+			// or when I become visible
+			this._scheduleLayout();
+			
+			this._onLoadHandler(cont);
+		}
+	},
+
+	_onError: function(type, err, consoleText){
+		// shows user the string that is returned by on[type]Error
+		// overide on[type]Error and return your own string to customize
+		var errText = this['on' + type + 'Error'].call(this, err);
+		if(consoleText){
+			console.error(consoleText, err);
+		}else if(errText){// a empty string won't change current content
+			this._setContent(errText, true);
+		}
+	},
+	
+	_scheduleLayout: function(){
+		// summary:
+		//		Call resize() on each of my child layout widgets, either now
+		//		(if I'm currently visible) or when I become visible
+		if(this._isShown()){
+			this._layoutChildren();
+		}else{
+			this._needLayout = true;
+		}
+	},
+
+	_layoutChildren: function(){
+		// summary:
+		//		Since I am a Container widget, each of my children expects me to
+		//		call resize() or layout() on them.
+		// description:
+		//		Should be called on initialization and also whenever we get new content
+		//		(from an href, or from attr('content', ...))... but deferred until
+		//		the ContentPane is visible
+
+		if(this._singleChild && this._singleChild.resize){
+			var cb = this._contentBox || dojo.contentBox(this.containerNode);
+			this._singleChild.resize({w: cb.w, h: cb.h});
+		}else{
+			// All my child widgets are independently sized (rather than matching my size),
+			// but I still need to call resize() on each child to make it layout.
+			dojo.forEach(this.getChildren(), function(widget){
+				if(widget.resize){
+					widget.resize();
+				}
+			});
+		}
+		delete this._needLayout;
+	},
+
+	// EVENT's, should be overide-able
+	onLoad: function(data){
+		// summary:
+		//		Event hook, is called after everything is loaded and widgetified
+		// tags:
+		//		callback
+	},
+
+	onUnload: function(){
+		// summary:
+		//		Event hook, is called before old content is cleared
+		// tags:
+		//		callback
+	},
+
+	onDownloadStart: function(){
+		// summary:
+		//		Called before download starts.
+		// description:
+		//		The string returned by this function will be the html
+		//		that tells the user we are loading something.
+		//		Override with your own function if you want to change text.
+		// tags:
+		//		extension
+		return this.loadingMessage;
+	},
+
+	onContentError: function(/*Error*/ error){
+		// summary:
+		//		Called on DOM faults, require faults etc. in content.
+		//
+		//		In order to display an error message in the pane, return
+		//		the error message from this method, as an HTML string.
+		//
+		//		By default (if this method is not overriden), it returns
+		//		nothing, so the error message is just printed to the console.
+		// tags:
+		//		extension
+	},
+
+	onDownloadError: function(/*Error*/ error){
+		// summary:
+		//		Called when download error occurs.
+		//
+		//		In order to display an error message in the pane, return
+		//		the error message from this method, as an HTML string.
+		//
+		//		Default behavior (if this method is not overriden) is to display
+		//		the error message inside the pane.
+		// tags:
+		//		extension
+		return this.errorMessage;
+	},
+
+	onDownloadEnd: function(){
+		// summary:
+		//		Called when download is finished.
+		// tags:
+		//		callback
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit.TooltipDialog"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.TooltipDialog"] = true;
+dojo.provide("dijit.TooltipDialog");
+
+
+
+
+
+
+dojo.declare(
+		"dijit.TooltipDialog",
+		[dijit.layout.ContentPane, dijit._Templated, dijit.form._FormMixin, dijit._DialogMixin],
+		{
+			// summary:
+			//		Pops up a dialog that appears like a Tooltip
+
+			// title: String
+			// 		Description of tooltip dialog (required for a11y)
+			title: "",
+
+			// doLayout: [protected] Boolean
+			//		Don't change this parameter from the default value.
+			//		This ContentPane parameter doesn't make sense for TooltipDialog, since TooltipDialog
+			//		is never a child of a layout container, nor can you specify the size of
+			//		TooltipDialog in order to control the size of an inner widget. 
+			doLayout: false,
+
+			// autofocus: Boolean
+			// 		A Toggle to modify the default focus behavior of a Dialog, which
+			// 		is to focus on the first dialog element after opening the dialog.
+			//		False will disable autofocusing. Default: true
+			autofocus: true,
+
+			// baseClass: [protected] String
+			//		The root className to use for the various states of this widget
+			baseClass: "dijitTooltipDialog",
+
+			// _firstFocusItem: [private] [readonly] DomNode
+			//		The pointer to the first focusable node in the dialog.
+			//		Set by `dijit._DialogMixin._getFocusItems`.
+			_firstFocusItem: null,
+
+			// _lastFocusItem: [private] [readonly] DomNode
+			//		The pointer to which node has focus prior to our dialog.
+			//		Set by `dijit._DialogMixin._getFocusItems`.
+			_lastFocusItem: null,
+
+			templateString: null,
+			templateString:"<div waiRole=\"presentation\">\n\t<div class=\"dijitTooltipContainer\" waiRole=\"presentation\">\n\t\t<div class =\"dijitTooltipContents dijitTooltipFocusNode\" dojoAttachPoint=\"containerNode\" tabindex=\"-1\" waiRole=\"dialog\"></div>\n\t</div>\n\t<div class=\"dijitTooltipConnector\" waiRole=\"presentation\"></div>\n</div>\n",
+
+			postCreate: function(){
+				this.inherited(arguments);
+				this.connect(this.containerNode, "onkeypress", "_onKey");
+				this.containerNode.title = this.title;
+			},
+
+			orient: function(/*DomNode*/ node, /*String*/ aroundCorner, /*String*/ corner){
+				// summary:
+				//		Configure widget to be displayed in given position relative to the button.
+				//		This is called from the dijit.popup code, and should not be called
+				//		directly.
+				// tags:
+				//		protected
+				var c = this._currentOrientClass;
+				if(c){
+					dojo.removeClass(this.domNode, c);
+				}
+				c = "dijitTooltipAB"+(corner.charAt(1)=='L'?"Left":"Right")+" dijitTooltip"+(corner.charAt(0)=='T' ? "Below" : "Above");
+				dojo.addClass(this.domNode, c);
+				this._currentOrientClass = c;
+			},
+
+			onOpen: function(/*Object*/ pos){
+				// summary:
+				//		Called when dialog is displayed.
+				//		This is called from the dijit.popup code, and should not be called directly.
+				// tags:
+				//		protected
+			
+				this.orient(this.domNode,pos.aroundCorner, pos.corner);
+				this._onShow(); // lazy load trigger
+				
+				if(this.autofocus){
+					this._getFocusItems(this.containerNode);
+					dijit.focus(this._firstFocusItem);
+				}
+			},
+			
+			_onKey: function(/*Event*/ evt){
+				// summary:
+				//		Handler for keyboard events
+				// description:
+				//		Keep keyboard focus in dialog; close dialog on escape key
+				// tags:
+				//		private
+
+				var node = evt.target;
+				var dk = dojo.keys;
+				if (evt.charOrCode === dk.TAB){
+					this._getFocusItems(this.containerNode);
+				}
+				var singleFocusItem = (this._firstFocusItem == this._lastFocusItem);
+				if(evt.charOrCode == dk.ESCAPE){
+					this.onCancel();
+					dojo.stopEvent(evt);
+				}else if(node == this._firstFocusItem && evt.shiftKey && evt.charOrCode === dk.TAB){
+					if(!singleFocusItem){
+						dijit.focus(this._lastFocusItem); // send focus to last item in dialog
+					}
+					dojo.stopEvent(evt);
+				}else if(node == this._lastFocusItem && evt.charOrCode === dk.TAB && !evt.shiftKey){
+					if(!singleFocusItem){
+						dijit.focus(this._firstFocusItem); // send focus to first item in dialog
+					}
+					dojo.stopEvent(evt);
+				}else if(evt.charOrCode === dk.TAB){
+					// we want the browser's default tab handling to move focus
+					// but we don't want the tab to propagate upwards
+					evt.stopPropagation();
+				}
+			}
+		}	
+	);
+
+}
+
+if(!dojo._hasResource["dijit.Dialog"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.Dialog"] = true;
+dojo.provide("dijit.Dialog");
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*=====
+dijit._underlay = function(kwArgs){
+	// summary:
+	//		A shared instance of a `dijit.DialogUnderlay`
+	//
+	// description: 
+	//		A shared instance of a `dijit.DialogUnderlay` created and
+	//		used by `dijit.Dialog`, though never created until some Dialog
+	//		or subclass thereof is shown.
+};
+=====*/
+
+dojo.declare(
+	"dijit.Dialog",
+	[dijit.layout.ContentPane, dijit._Templated, dijit.form._FormMixin, dijit._DialogMixin],
+	{
+		// summary:
+		//		A modal dialog Widget
+		//
+		// description:
+		//		Pops up a modal dialog window, blocking access to the screen
+		//		and also graying out the screen Dialog is extended from
+		//		ContentPane so it supports all the same parameters (href, etc.)
+		//
+		// example:
+		// |	<div dojoType="dijit.Dialog" href="test.html"></div>
+		//
+		// example:
+		// |	var foo = new dijit.Dialog({ title: "test dialog", content: "test content" };
+		// |	dojo.body().appendChild(foo.domNode);
+		// |	foo.startup();
+		
+		templateString: null,
+		templateString:"<div class=\"dijitDialog\" tabindex=\"-1\" waiRole=\"dialog\" waiState=\"labelledby-${id}_title\">\n\t<div dojoAttachPoint=\"titleBar\" class=\"dijitDialogTitleBar\">\n\t<span dojoAttachPoint=\"titleNode\" class=\"dijitDialogTitle\" id=\"${id}_title\"></span>\n\t<span dojoAttachPoint=\"closeButtonNode\" class=\"dijitDialogCloseIcon\" dojoAttachEvent=\"onclick: onCancel, onmouseenter: _onCloseEnter, onmouseleave: _onCloseLeave\" title=\"${buttonCancel}\">\n\t\t<span dojo [...]
+		attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
+			title: [
+				{ node: "titleNode", type: "innerHTML" }, 
+				{ node: "titleBar", type: "attribute" }
+			]
+		}),
+
+		// open: Boolean
+		//		True if Dialog is currently displayed on screen.
+		open: false,
+
+		// duration: Integer
+		//		The time in milliseconds it takes the dialog to fade in and out
+		duration: dijit.defaultDuration,
+
+		// refocus: Boolean
+		// 		A Toggle to modify the default focus behavior of a Dialog, which
+		// 		is to re-focus the element which had focus before being opened.
+		//		False will disable refocusing. Default: true
+		refocus: true,
+		
+		// autofocus: Boolean
+		// 		A Toggle to modify the default focus behavior of a Dialog, which
+		// 		is to focus on the first dialog element after opening the dialog.
+		//		False will disable autofocusing. Default: true
+		autofocus: true,
+
+		// _firstFocusItem: [private] [readonly] DomNode
+		//		The pointer to the first focusable node in the dialog.
+		//		Set by `dijit._DialogMixin._getFocusItems`.
+		_firstFocusItem: null,
+		
+		// _lastFocusItem: [private] [readonly] DomNode
+		//		The pointer to which node has focus prior to our dialog.
+		//		Set by `dijit._DialogMixin._getFocusItems`.
+		_lastFocusItem: null,
+
+		// doLayout: [protected] Boolean
+		//		Don't change this parameter from the default value.
+		//		This ContentPane parameter doesn't make sense for Dialog, since Dialog
+		//		is never a child of a layout container, nor can you specify the size of
+		//		Dialog in order to control the size of an inner widget. 
+		doLayout: false,
+
+		// draggable: Boolean
+		//		Toggles the moveable aspect of the Dialog. If true, Dialog
+		//		can be dragged by it's title. If false it will remain centered
+		//		in the viewport.
+		draggable: true,
+
+		// _fixSizes: Boolean
+		//		Does this Dialog attempt to restore the width and height after becoming too small?
+		_fixSizes: true,
+
+		postMixInProperties: function(){
+			var _nlsResources = dojo.i18n.getLocalization("dijit", "common");
+			dojo.mixin(this, _nlsResources);
+			this.inherited(arguments);
+		},
+
+		postCreate: function(){
+			dojo.style(this.domNode, {
+				visibility:"hidden",
+				position:"absolute",
+				display:"",
+				top:"-9999px"
+			});
+			dojo.body().appendChild(this.domNode);
+
+			this.inherited(arguments);
+
+			this.connect(this, "onExecute", "hide");
+			this.connect(this, "onCancel", "hide");
+			this._modalconnects = [];
+		},
+
+		onLoad: function(){
+			// summary:
+			//		Called when data has been loaded from an href.
+			//		Unlike most other callbacks, this function can be connected to (via `dojo.connect`)
+			//		but should *not* be overriden.
+			// tags:
+			//		callback
+			
+			// when href is specified we need to reposition the dialog after the data is loaded
+			this._position();
+			this.inherited(arguments);
+		},
+
+		_endDrag: function(e){
+			// summary:
+			//		Called after dragging the Dialog. Calculates the relative offset
+			//		of the Dialog in relation to the viewport.
+			// tags:
+			//		private
+			if(e && e.node && e.node === this.domNode){
+				var vp = dijit.getViewport(); 
+				var p = e._leftTop || dojo.coords(e.node,true);
+				this._relativePosition = {
+					t: p.t - vp.t,
+					l: p.l - vp.l
+				}			
+			}
+		},
+		
+		_setup: function(){
+			// summary: 
+			//		Stuff we need to do before showing the Dialog for the first
+			//		time (but we defer it until right beforehand, for
+			//		performance reasons).
+			// tags:
+			//		private
+
+			var node = this.domNode;
+
+			if(this.titleBar && this.draggable){
+				this._moveable = (dojo.isIE == 6) ?
+					new dojo.dnd.TimedMoveable(node, { handle: this.titleBar }) :	// prevent overload, see #5285
+					new dojo.dnd.Moveable(node, { handle: this.titleBar, timeout: 0 });
+				dojo.subscribe("/dnd/move/stop",this,"_endDrag");
+			}else{
+				dojo.addClass(node,"dijitDialogFixed"); 
+			}
+			
+			var underlayAttrs = {
+				dialogId: this.id,
+				"class": dojo.map(this["class"].split(/\s/), function(s){ return s+"_underlay"; }).join(" ")
+			};
+			
+			var underlay = dijit._underlay;
+			if(!underlay){ 
+				underlay = dijit._underlay = new dijit.DialogUnderlay(underlayAttrs); 
+			}
+			
+			this._fadeIn = dojo.fadeIn({
+				node: node,
+				duration: this.duration,
+				beforeBegin: function(){
+					underlay.attr(underlayAttrs);
+					underlay.show();
+				},
+				onEnd:	dojo.hitch(this, function(){
+					if(this.autofocus){
+						// find focusable Items each time dialog is shown since if dialog contains a widget the 
+						// first focusable items can change
+						this._getFocusItems(this.domNode);
+						dijit.focus(this._firstFocusItem);
+					}
+				})
+			 });
+
+			this._fadeOut = dojo.fadeOut({
+				node: node,
+				duration: this.duration,
+				onEnd: function(){
+					node.style.visibility="hidden";
+					node.style.top = "-9999px";
+					dijit._underlay.hide();
+				}
+			 });
+		},
+
+		uninitialize: function(){
+			var wasPlaying = false;
+			if(this._fadeIn && this._fadeIn.status() == "playing"){
+				wasPlaying = true;
+				this._fadeIn.stop();
+			}
+			if(this._fadeOut && this._fadeOut.status() == "playing"){
+				wasPlaying = true;
+				this._fadeOut.stop();
+			}
+			if(this.open || wasPlaying){
+				dijit._underlay.hide();
+			}
+			if(this._moveable){
+				this._moveable.destroy();
+			}
+		},
+
+		_size: function(){
+			// summary:
+			// 		Make sure the dialog is small enough to fit in viewport.
+			// tags:
+			//		private
+
+			var mb = dojo.marginBox(this.domNode);
+			var viewport = dijit.getViewport();
+			if(mb.w >= viewport.w || mb.h >= viewport.h){
+				dojo.style(this.containerNode, {
+					width: Math.min(mb.w, Math.floor(viewport.w * 0.75))+"px",
+					height: Math.min(mb.h, Math.floor(viewport.h * 0.75))+"px",
+					overflow: "auto",
+					position: "relative"	// workaround IE bug moving scrollbar or dragging dialog
+				});
+			}
+		},
+
+		_position: function(){
+			// summary:
+			//		Position modal dialog in the viewport. If no relative offset
+			//		in the viewport has been determined (by dragging, for instance),
+			//		center the node. Otherwise, use the Dialog's stored relative offset,
+			//		and position the node to top: left: values based on the viewport.
+			// tags:
+			//		private
+			if(!dojo.hasClass(dojo.body(),"dojoMove")){
+				var node = this.domNode;
+				var viewport = dijit.getViewport();
+					var p = this._relativePosition;
+					var mb = p ? null : dojo.marginBox(node);
+					dojo.style(node,{
+						left: Math.floor(viewport.l + (p ? p.l : (viewport.w - mb.w) / 2)) + "px",
+						top: Math.floor(viewport.t + (p ? p.t : (viewport.h - mb.h) / 2)) + "px"
+					});
+				}
+
+		},
+
+		_onKey: function(/*Event*/ evt){
+			// summary:
+			//		Handles the keyboard events for accessibility reasons
+			// tags:
+			//		private
+			if(evt.charOrCode){
+				var dk = dojo.keys;
+				var node = evt.target;
+				if (evt.charOrCode === dk.TAB){
+					this._getFocusItems(this.domNode);
+				}
+				var singleFocusItem = (this._firstFocusItem == this._lastFocusItem);
+				// see if we are shift-tabbing from first focusable item on dialog
+				if(node == this._firstFocusItem && evt.shiftKey && evt.charOrCode === dk.TAB){
+					if(!singleFocusItem){
+						dijit.focus(this._lastFocusItem); // send focus to last item in dialog
+					}
+					dojo.stopEvent(evt);
+				}else if(node == this._lastFocusItem && evt.charOrCode === dk.TAB && !evt.shiftKey){
+					if (!singleFocusItem){
+						dijit.focus(this._firstFocusItem); // send focus to first item in dialog
+					}
+					dojo.stopEvent(evt);
+				}else{
+					// see if the key is for the dialog
+					while(node){
+						if(node == this.domNode){
+							if(evt.charOrCode == dk.ESCAPE){
+								this.onCancel(); 
+							}else{
+								return; // just let it go
+							}
+						}
+						node = node.parentNode;
+					}
+					// this key is for the disabled document window
+					if(evt.charOrCode !== dk.TAB){ // allow tabbing into the dialog for a11y
+						dojo.stopEvent(evt);
+					// opera won't tab to a div
+					}else if(!dojo.isOpera){
+						try{
+							this._firstFocusItem.focus();
+						}catch(e){ /*squelch*/ }
+					}
+				}
+			}
+		},
+
+		show: function(){
+			// summary:
+			//		Display the dialog
+			if(this.open){ return; }
+			
+			// first time we show the dialog, there's some initialization stuff to do			
+			if(!this._alreadyInitialized){
+				this._setup();
+				this._alreadyInitialized=true;
+			}
+
+			if(this._fadeOut.status() == "playing"){
+				this._fadeOut.stop();
+			}
+
+			this._modalconnects.push(dojo.connect(window, "onscroll", this, "layout"));
+			this._modalconnects.push(dojo.connect(window, "onresize", this, function(){
+				// IE gives spurious resize events and can actually get stuck
+				// in an infinite loop if we don't ignore them
+				var viewport = dijit.getViewport();
+				if(!this._oldViewport ||
+						viewport.h != this._oldViewport.h ||
+						viewport.w != this._oldViewport.w){
+					this.layout();
+					this._oldViewport = viewport;
+				}
+			}));
+			this._modalconnects.push(dojo.connect(dojo.doc.documentElement, "onkeypress", this, "_onKey"));
+
+			dojo.style(this.domNode, {
+				opacity:0,
+				visibility:""
+			});
+			
+			if(this._fixSizes){
+				dojo.style(this.containerNode, { // reset width and height so that _size():marginBox works correctly
+					width:"auto",
+					height:"auto"
+				});
+			}
+			
+			this.open = true;
+			this._onShow(); // lazy load trigger
+
+			this._size();
+			this._position();
+
+			this._fadeIn.play();
+
+			this._savedFocus = dijit.getFocus(this);
+		},
+
+		hide: function(){
+			// summary:
+			//		Hide the dialog
+
+			// if we haven't been initialized yet then we aren't showing and we can just return		
+			if(!this._alreadyInitialized){
+				return;
+			}
+
+			if(this._fadeIn.status() == "playing"){
+				this._fadeIn.stop();
+			}
+			this._fadeOut.play();
+
+			if (this._scrollConnected){
+				this._scrollConnected = false;
+			}
+			dojo.forEach(this._modalconnects, dojo.disconnect);
+			this._modalconnects = [];
+			if(this.refocus){
+				this.connect(this._fadeOut,"onEnd",dojo.hitch(dijit,"focus",this._savedFocus));
+			}
+			if(this._relativePosition){
+				delete this._relativePosition;	
+			}
+			this.open = false;
+		},
+
+		layout: function() {
+			// summary:
+			//		Position the Dialog and the underlay
+			// tags:
+			//		private
+			if(this.domNode.style.visibility != "hidden"){
+				dijit._underlay.layout();
+				this._position();
+			}
+		},
+		
+		destroy: function(){
+			dojo.forEach(this._modalconnects, dojo.disconnect);
+			if(this.refocus && this.open){
+				setTimeout(dojo.hitch(dijit,"focus",this._savedFocus), 25);
+			}
+			this.inherited(arguments);			
+		},
+
+		_onCloseEnter: function(){
+			// summary:
+			//		Called when user hovers over close icon
+			// tags:
+			//		private
+			dojo.addClass(this.closeButtonNode, "dijitDialogCloseIcon-hover");
+		},
+
+		_onCloseLeave: function(){
+			// summary:
+			//		Called when user stops hovering over close icon
+			// tags:
+			//		private
+			dojo.removeClass(this.closeButtonNode, "dijitDialogCloseIcon-hover");
+		}
+	}
+);
+
+// For back-compat.  TODO: remove in 2.0
+
+
+
+}
+
+if(!dojo._hasResource["dijit._editor.selection"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._editor.selection"] = true;
+dojo.provide("dijit._editor.selection");
+
+// FIXME:
+//		all of these methods branch internally for IE. This is probably
+//		sub-optimal in terms of runtime performance. We should investigate the
+//		size difference for differentiating at definition time.
+
+dojo.mixin(dijit._editor.selection, {
+	getType: function(){
+		// summary: Get the selection type (like dojo.doc.select.type in IE).
+		if(dojo.doc.selection){ //IE
+			return dojo.doc.selection.type.toLowerCase();
+		}else{
+			var stype = "text";
+
+			// Check if the actual selection is a CONTROL (IMG, TABLE, HR, etc...).
+			var oSel;
+			try{
+				oSel = dojo.global.getSelection();
+			}catch(e){ /*squelch*/ }
+
+			if(oSel && oSel.rangeCount==1){
+				var oRange = oSel.getRangeAt(0);
+				if(	(oRange.startContainer == oRange.endContainer) &&
+					((oRange.endOffset - oRange.startOffset) == 1) &&
+					(oRange.startContainer.nodeType != 3 /* text node*/)
+				){
+					stype = "control";
+				}
+			}
+			return stype;
+		}
+	},
+
+	getSelectedText: function(){
+		// summary:
+		//		Return the text (no html tags) included in the current selection or null if no text is selected
+		if(dojo.doc.selection){ //IE
+			if(dijit._editor.selection.getType() == 'control'){
+				return null;
+			}
+			return dojo.doc.selection.createRange().text;
+		}else{
+			var selection = dojo.global.getSelection();
+			if(selection){
+				return selection.toString();
+			}
+		}
+		return ''
+	},
+
+	getSelectedHtml: function(){
+		// summary:
+		//		Return the html of the current selection or null if unavailable
+		if(dojo.doc.selection){ //IE
+			if(dijit._editor.selection.getType() == 'control'){
+				return null;
+			}
+			return dojo.doc.selection.createRange().htmlText;
+		}else{
+			var selection = dojo.global.getSelection();
+			if(selection && selection.rangeCount){
+				var frag = selection.getRangeAt(0).cloneContents();
+				var div = dojo.doc.createElement("div");
+				div.appendChild(frag);
+				return div.innerHTML;
+			}
+			return null;
+		}
+	},
+
+	getSelectedElement: function(){
+		// summary:
+		//		Retrieves the selected element (if any), just in the case that
+		//		a single element (object like and image or a table) is
+		//		selected.
+		if(dijit._editor.selection.getType() == "control"){
+			if(dojo.doc.selection){ //IE
+				var range = dojo.doc.selection.createRange();
+				if(range && range.item){
+					return dojo.doc.selection.createRange().item(0);
+				}
+			}else{
+				var selection = dojo.global.getSelection();
+				return selection.anchorNode.childNodes[ selection.anchorOffset ];
+			}
+		}
+		return null;
+	},
+
+	getParentElement: function(){
+		// summary:
+		//		Get the parent element of the current selection
+		if(dijit._editor.selection.getType() == "control"){
+			var p = this.getSelectedElement();
+			if(p){ return p.parentNode; }
+		}else{
+			if(dojo.doc.selection){ //IE
+				var r=dojo.doc.selection.createRange();
+				r.collapse(true);
+				return r.parentElement();
+			}else{
+				var selection = dojo.global.getSelection();
+				if(selection){
+					var node = selection.anchorNode;
+
+					while(node && (node.nodeType != 1)){ // not an element
+						node = node.parentNode;
+					}
+
+					return node;
+				}
+			}
+		}
+		return null;
+	},
+
+	hasAncestorElement: function(/*String*/tagName /* ... */){
+		// summary:
+		// 		Check whether current selection has a  parent element which is
+		// 		of type tagName (or one of the other specified tagName)
+		return this.getAncestorElement.apply(this, arguments) != null;
+	},
+
+	getAncestorElement: function(/*String*/tagName /* ... */){
+		// summary:
+		//		Return the parent element of the current selection which is of
+		//		type tagName (or one of the other specified tagName)
+
+		var node = this.getSelectedElement() || this.getParentElement();
+		return this.getParentOfType(node, arguments);
+	},
+
+	isTag: function(/*DomNode*/node, /*Array*/tags){
+		if(node && node.tagName){
+			var _nlc = node.tagName.toLowerCase();
+			for(var i=0; i<tags.length; i++){
+				var _tlc = String(tags[i]).toLowerCase();
+				if(_nlc == _tlc){
+					return _tlc;
+				}
+			}
+		}
+		return "";
+	},
+
+	getParentOfType: function(/*DomNode*/node, /*Array*/tags){
+		while(node){
+			if(this.isTag(node, tags).length){
+				return node;
+			}
+			node = node.parentNode;
+		}
+		return null;
+	},
+
+	collapse: function(/*Boolean*/beginning) {
+		// summary: clear current selection
+	  if(window['getSelection']){
+	          var selection = dojo.global.getSelection();
+	          if(selection.removeAllRanges){ // Mozilla
+	                  if(beginning){
+	                          selection.collapseToStart();
+	                  }else{
+	                          selection.collapseToEnd();
+	                  }
+	          }else{ // Safari
+	                  // pulled from WebCore/ecma/kjs_window.cpp, line 2536
+	                   selection.collapse(beginning);
+	          }
+	  }else if(dojo.doc.selection){ // IE
+	          var range = dojo.doc.selection.createRange();
+	          range.collapse(beginning);
+	          range.select();
+	  }
+	},
+
+	remove: function(){
+		// summary: delete current selection
+		var _s = dojo.doc.selection;
+		if(_s){ //IE
+			if(_s.type.toLowerCase() != "none"){
+				_s.clear();
+			}
+			return _s;
+		}else{
+			_s = dojo.global.getSelection();
+			_s.deleteFromDocument();
+			return _s;
+		}
+	},
+
+	selectElementChildren: function(/*DomNode*/element,/*Boolean?*/nochangefocus){
+		// summary:
+		//		clear previous selection and select the content of the node
+		//		(excluding the node itself)
+		var _window = dojo.global;
+		var _document = dojo.doc;
+		element = dojo.byId(element);
+		if(_document.selection && dojo.body().createTextRange){ // IE
+			var range = element.ownerDocument.body.createTextRange();
+			range.moveToElementText(element);
+			if(!nochangefocus){
+				try{
+					range.select(); // IE throws an exception here if the widget is hidden.  See #5439
+				}catch(e){ /* squelch */}
+			}
+		}else if(_window.getSelection){
+			var selection = _window.getSelection();
+			if(selection.setBaseAndExtent){ // Safari
+				selection.setBaseAndExtent(element, 0, element, element.innerText.length - 1);
+			}else if(selection.selectAllChildren){ // Mozilla
+				selection.selectAllChildren(element);
+			}
+		}
+	},
+
+	selectElement: function(/*DomNode*/element,/*Boolean?*/nochangefocus){
+		// summary:
+		//		clear previous selection and select element (including all its children)
+		var range, _document = dojo.doc;
+		element = dojo.byId(element);
+		if(_document.selection && dojo.body().createTextRange){ // IE
+			try{
+				range = dojo.body().createControlRange();
+				range.addElement(element);
+				if(!nochangefocus){
+					range.select();
+				}
+			}catch(e){
+				this.selectElementChildren(element,nochangefocus);
+			}
+		}else if(dojo.global.getSelection){
+			var selection = dojo.global.getSelection();
+			// FIXME: does this work on Safari?
+			if(selection.removeAllRanges){ // Mozilla
+				range = _document.createRange();
+				range.selectNode(element);
+				selection.removeAllRanges();
+				selection.addRange(range);
+			}
+		}
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit._editor.range"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._editor.range"] = true;
+dojo.provide("dijit._editor.range");
+
+dijit.range={};
+
+dijit.range.getIndex=function(/*DomNode*/node, /*DomNode*/parent){
+//	dojo.profile.start("dijit.range.getIndex");
+	var ret=[], retR=[];
+	var stop = parent;
+	var onode = node;
+
+	var pnode, n;
+	while(node != stop){
+		var i = 0;
+		pnode = node.parentNode;
+		while((n=pnode.childNodes[i++])){
+			if(n===node){
+				--i;
+				break;
+			}
+		}
+		if(i>=pnode.childNodes.length){
+			dojo.debug("Error finding index of a node in dijit.range.getIndex");
+		}
+		ret.unshift(i);
+		retR.unshift(i-pnode.childNodes.length);
+		node = pnode;
+	}
+
+	//normalized() can not be called so often to prevent
+	//invalidating selection/range, so we have to detect
+	//here that any text nodes in a row
+	if(ret.length>0 && onode.nodeType==3){
+		n = onode.previousSibling;
+		while(n && n.nodeType==3){
+			ret[ret.length-1]--;
+			n = n.previousSibling;
+		}
+		n = onode.nextSibling;
+		while(n && n.nodeType==3){
+			retR[retR.length-1]++;
+			n = n.nextSibling;
+		}
+	}
+//	dojo.profile.end("dijit.range.getIndex");
+	return {o: ret, r:retR};
+}
+
+dijit.range.getNode = function(/*Array*/index, /*DomNode*/parent){
+	if(!dojo.isArray(index) || index.length==0){
+		return parent;
+	}
+	var node = parent;
+//	if(!node)debugger
+	dojo.every(index, function(i){
+		if(i>=0&&i< node.childNodes.length){
+			node = node.childNodes[i];
+		}else{
+			node = null;
+			
+			return false; //terminate dojo.every
+		}
+		return true; //carry on the every loop
+	});
+
+	return node;
+}
+
+dijit.range.getCommonAncestor = function(n1,n2){
+	var getAncestors = function(n){
+		var as=[];
+		while(n){
+			as.unshift(n);
+			if(n.nodeName!='BODY'){
+				n = n.parentNode;
+			}else{
+				break;
+			}
+		}
+		return as;
+	};
+	var n1as = getAncestors(n1);
+	var n2as = getAncestors(n2);
+
+	var m = Math.min(n1as.length,n2as.length);
+	var com = n1as[0]; //at least, one element should be in the array: the root (BODY by default)
+	for(var i=1;i<m;i++){
+		if(n1as[i]===n2as[i]){
+			com = n1as[i]
+		}else{
+			break;
+		}
+	}
+	return com;
+}
+
+dijit.range.getAncestor = function(/*DomNode*/node, /*RegEx?*/regex, /*DomNode?*/root){
+	root = root || node.ownerDocument.body;
+	while(node && node !== root){
+		var name = node.nodeName.toUpperCase() ;
+		if(regex.test(name)){
+			return node;
+		}
+
+		node = node.parentNode;
+	}
+	return null;
+}
+
+dijit.range.BlockTagNames = /^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/;
+dijit.range.getBlockAncestor = function(/*DomNode*/node, /*RegEx?*/regex, /*DomNode?*/root){
+	root = root || node.ownerDocument.body;
+	regex = regex || dijit.range.BlockTagNames;
+	var block=null, blockContainer;
+	while(node && node !== root){
+		var name = node.nodeName.toUpperCase() ;
+		if(!block && regex.test(name)){
+			block = node;
+		}
+		if(!blockContainer && (/^(?:BODY|TD|TH|CAPTION)$/).test(name)){
+			blockContainer = node;
+		}
+
+		node = node.parentNode;
+	}
+	return {blockNode:block, blockContainer:blockContainer || node.ownerDocument.body};
+}
+
+dijit.range.atBeginningOfContainer = function(/*DomNode*/container, /*DomNode*/node, /*Int*/offset){
+	var atBeginning = false;
+	var offsetAtBeginning = (offset == 0);
+	if(!offsetAtBeginning && node.nodeType==3){ //if this is a text node, check whether the left part is all space
+		if(dojo.trim(node.nodeValue.substr(0,offset))==0){
+			offsetAtBeginning = true;
+		}
+	}
+	if(offsetAtBeginning){
+		var cnode = node;
+		atBeginning = true;
+		while(cnode && cnode !== container){
+			if(cnode.previousSibling){
+				atBeginning = false;
+				break;
+			}
+			cnode = cnode.parentNode;
+		}
+	}
+	return atBeginning;
+}
+
+dijit.range.atEndOfContainer = function(/*DomNode*/container, /*DomNode*/node, /*Int*/offset){
+	var atEnd = false;
+	var offsetAtEnd = (offset == (node.length || node.childNodes.length));
+	if(!offsetAtEnd && node.nodeType==3){ //if this is a text node, check whether the right part is all space
+		if(dojo.trim(node.nodeValue.substr(offset))==0){
+			offsetAtEnd = true;
+		}
+	}
+	if(offsetAtEnd){
+		var cnode = node;
+		atEnd = true;
+		while(cnode && cnode !== container){
+			if(cnode.nextSibling){
+				atEnd = false;
+				break;
+			}
+			cnode = cnode.parentNode;
+		}
+	}
+	return atEnd;
+}
+
+dijit.range.adjacentNoneTextNode=function(startnode, next){
+	var node = startnode;
+	var len = (0-startnode.length) || 0;
+	var prop = next?'nextSibling':'previousSibling';
+	while(node){
+		if(node.nodeType!=3){
+			break;
+		}
+		len += node.length
+		node = node[prop];
+	}
+	return [node,len];
+}
+
+dijit.range._w3c = Boolean(window['getSelection']);
+dijit.range.create = function(){
+	if(dijit.range._w3c){
+		return dojo.doc.createRange();
+	}else{//IE
+		return new dijit.range.W3CRange;
+	}
+}
+
+dijit.range.getSelection = function(win, /*Boolean?*/ignoreUpdate){
+	if(dijit.range._w3c){
+		return win.getSelection();
+	}else{//IE
+		var s = new dijit.range.ie.selection(win);
+		if(!ignoreUpdate){
+			s._getCurrentSelection();
+		}
+		return s;
+	}
+}
+
+if(!dijit.range._w3c){
+	dijit.range.ie={
+		cachedSelection: {},
+		selection: function(win){
+			this._ranges = [];
+			this.addRange = function(r, /*boolean*/internal){
+				this._ranges.push(r);
+				if(!internal){
+					r._select();
+				}
+				this.rangeCount = this._ranges.length;
+			};
+			this.removeAllRanges = function(){
+				//don't detach, the range may be used later
+//				for(var i=0;i<this._ranges.length;i++){
+//					this._ranges[i].detach();
+//				}
+				this._ranges = [];
+				this.rangeCount = 0;
+			};
+			var _initCurrentRange = function(){
+				var r = win.document.selection.createRange();
+				var type=win.document.selection.type.toUpperCase();
+				if(type == "CONTROL"){
+					//TODO: multiple range selection(?)
+					return new dijit.range.W3CRange(dijit.range.ie.decomposeControlRange(r));
+				}else{
+					return new dijit.range.W3CRange(dijit.range.ie.decomposeTextRange(r));
+				}
+			};
+			this.getRangeAt = function(i){
+				return this._ranges[i];
+			};
+			this._getCurrentSelection = function(){
+				this.removeAllRanges();
+				var r=_initCurrentRange();
+				if(r){
+					this.addRange(r, true);
+				}
+			};
+		},
+		decomposeControlRange: function(range){
+			var firstnode = range.item(0), lastnode = range.item(range.length-1)
+			var startContainer = firstnode.parentNode, endContainer = lastnode.parentNode;
+			var startOffset = dijit.range.getIndex(firstnode, startContainer).o;
+			var endOffset = dijit.range.getIndex(lastnode, endContainer).o+1;
+			return [startContainer, startOffset,endContainer, endOffset];
+		},
+		getEndPoint: function(range, end){
+			var atmrange = range.duplicate();
+			atmrange.collapse(!end);
+			var cmpstr = 'EndTo' + (end?'End':'Start');
+			var parentNode = atmrange.parentElement();
+
+			var startnode, startOffset, lastNode;
+			if(parentNode.childNodes.length>0){
+				dojo.every(parentNode.childNodes, function(node,i){
+					var calOffset;
+					if(node.nodeType != 3){
+						atmrange.moveToElementText(node);
+
+						if(atmrange.compareEndPoints(cmpstr,range) > 0){
+							startnode = node.previousSibling;
+							if(lastNode && lastNode.nodeType == 3){
+								//where share we put the start? in the text node or after?
+								startnode = lastNode;
+								calOffset = true;
+							}else{
+								startnode = parentNode;
+								startOffset = i;
+								return false;
+							}
+						}else{
+							if(i==parentNode.childNodes.length-1){
+								startnode = parentNode;
+								startOffset = parentNode.childNodes.length;
+								return false;
+							}
+						}
+					}else{
+						if(i==parentNode.childNodes.length-1){//at the end of this node
+							startnode = node;
+							calOffset = true;
+						}
+					}
+		//			try{
+						if(calOffset && startnode){
+							var prevnode = dijit.range.adjacentNoneTextNode(startnode)[0];
+							if(prevnode){
+								startnode = prevnode.nextSibling;
+							}else{
+								startnode = parentNode.firstChild; //firstChild must be a text node
+							}
+							var prevnodeobj = dijit.range.adjacentNoneTextNode(startnode);
+							prevnode = prevnodeobj[0];
+							var lenoffset = prevnodeobj[1];
+							if(prevnode){
+								atmrange.moveToElementText(prevnode);
+								atmrange.collapse(false);
+							}else{
+								atmrange.moveToElementText(parentNode);
+							}
+							atmrange.setEndPoint(cmpstr, range);
+							startOffset = atmrange.text.length-lenoffset;
+
+							return false;
+						}
+		//			}catch(e){ debugger }
+					lastNode = node;
+					return true;
+				});
+			}else{
+				startnode = parentNode;
+				startOffset = 0;
+			}
+
+			//if at the end of startnode and we are dealing with start container, then
+			//move the startnode to nextSibling if it is a text node
+			//TODO: do this for end container?
+			if(!end && startnode.nodeType!=3 && startOffset == startnode.childNodes.length){
+				if(startnode.nextSibling && startnode.nextSibling.nodeType==3){
+					startnode = startnode.nextSibling;
+					startOffset = 0;
+				}
+			}
+			return [startnode, startOffset];
+		},
+		setEndPoint: function(range, container, offset){
+			//text node
+			var atmrange = range.duplicate(), node, len;
+			if(container.nodeType!=3){ //normal node
+				if(offset > 0){
+					node = container.childNodes[offset-1];
+					if(node.nodeType==3){
+						container = node;
+						offset = node.length;
+						//pass through
+					}else{
+						if(node.nextSibling && node.nextSibling.nodeType==3){
+							container=node.nextSibling;
+							offset=0;
+							//pass through
+						}else{
+							atmrange.moveToElementText(node.nextSibling?node:container);
+							var tempnode=node.parentNode.insertBefore(document.createTextNode(' '),node.nextSibling);
+							atmrange.collapse(false);
+							tempnode.parentNode.removeChild(tempnode);
+						}
+					}
+				}else{
+					atmrange.moveToElementText(container);
+					atmrange.collapse(true);
+				}
+			}
+			if(container.nodeType==3){
+				var prevnodeobj = dijit.range.adjacentNoneTextNode(container);
+				var prevnode = prevnodeobj[0];
+				len = prevnodeobj[1];
+				if(prevnode){
+					atmrange.moveToElementText(prevnode);
+					atmrange.collapse(false);
+					//if contentEditable is not inherit, the above collapse won't make the end point
+					//in the correctly position: it always has a -1 offset, so compensate it
+					if(prevnode.contentEditable!='inherit'){
+						len++;
+					}
+				}else{
+					atmrange.moveToElementText(container.parentNode);
+					atmrange.collapse(true);
+				}
+
+				offset += len;
+				if(offset>0){
+					if(atmrange.move('character',offset) != offset){
+						console.error('Error when moving!');
+					}
+				}
+			}
+
+			return atmrange;
+		},
+		decomposeTextRange: function(range){
+			var tmpary = dijit.range.ie.getEndPoint(range);
+			var startContainter = tmpary[0], startOffset = tmpary[1];
+			var endContainter = tmpary[0], endOffset = tmpary[1];
+
+			if(range.htmlText.length){
+				if(range.htmlText == range.text){ //in the same text node
+					endOffset = startOffset+range.text.length;
+				}else{
+					tmpary = dijit.range.ie.getEndPoint(range,true);
+					endContainter = tmpary[0], endOffset = tmpary[1];
+				}
+			}
+			return [startContainter, startOffset,endContainter, endOffset];
+		},
+		setRange: function(range, startContainter,
+			startOffset, endContainter, endOffset, collapsed){
+			var start=dijit.range.ie.setEndPoint(range, startContainter, startOffset);
+
+			range.setEndPoint('StartToStart',start);
+			if(!collapsed){
+				var end=dijit.range.ie.setEndPoint(range, endContainter, endOffset);	
+			}
+			range.setEndPoint('EndToEnd',end||start);
+
+			return range;
+		}
+	}
+
+dojo.declare("dijit.range.W3CRange",null, {
+	constructor: function(){
+		if(arguments.length>0){
+			this.setStart(arguments[0][0],arguments[0][1]);
+			this.setEnd(arguments[0][2],arguments[0][3]);
+		}else{
+			this.commonAncestorContainer = null;
+			this.startContainer = null;
+			this.startOffset = 0;
+			this.endContainer = null;
+			this.endOffset = 0;
+			this.collapsed = true;
+		}
+	},
+	_updateInternal: function(){
+		if(this.startContainer !== this.endContainer){
+			this.commonAncestorContainer = dijit.range.getCommonAncestor(this.startContainer, this.endContainer);
+		}else{
+			this.commonAncestorContainer = this.startContainer;
+		}
+		this.collapsed = (this.startContainer === this.endContainer) && (this.startOffset == this.endOffset);
+	},
+	setStart: function(node, offset){
+		offset=parseInt(offset);
+		if(this.startContainer === node && this.startOffset == offset){
+			return;
+		}
+		delete this._cachedBookmark;
+
+		this.startContainer = node;
+		this.startOffset = offset;
+		if(!this.endContainer){
+			this.setEnd(node, offset);
+		}else{
+			this._updateInternal();
+		}
+	},
+	setEnd: function(node, offset){
+		offset=parseInt(offset);
+		if(this.endContainer === node && this.endOffset == offset){
+			return;
+		}
+		delete this._cachedBookmark;
+
+		this.endContainer = node;
+		this.endOffset = offset;
+		if(!this.startContainer){
+			this.setStart(node, offset);
+		}else{
+			this._updateInternal();
+		}
+	},
+	setStartAfter: function(node, offset){
+		this._setPoint('setStart', node, offset, 1);
+	},
+	setStartBefore: function(node, offset){
+		this._setPoint('setStart', node, offset, 0);
+	},
+	setEndAfter: function(node, offset){
+		this._setPoint('setEnd', node, offset, 1);
+	},
+	setEndBefore: function(node, offset){
+		this._setPoint('setEnd', node, offset, 0);
+	},
+	_setPoint: function(what, node, offset, ext){
+		var index = dijit.range.getIndex(node, node.parentNode).o;
+		this[what](node.parentNode, index.pop()+ext);
+	},
+	_getIERange: function(){
+		var r=(this._body||this.endContainer.ownerDocument.body).createTextRange();
+		dijit.range.ie.setRange(r, this.startContainer, this.startOffset, this.endContainer, this.endOffset, this.collapsed);
+		return r;
+	},
+	getBookmark: function(body){
+		this._getIERange();
+		return this._cachedBookmark;
+	},
+	_select: function(){
+		var r = this._getIERange();
+		r.select();
+	},
+	deleteContents: function(){
+		var r = this._getIERange();
+		r.pasteHTML('');
+		this.endContainer = this.startContainer;
+		this.endOffset = this.startOffset;
+		this.collapsed = true;
+	},
+	cloneRange: function(){
+		var r = new dijit.range.W3CRange([this.startContainer,this.startOffset,
+			this.endContainer,this.endOffset]);
+		r._body = this._body;
+		return r;
+	},
+	detach: function(){
+		this._body = null;
+		this.commonAncestorContainer = null;
+		this.startContainer = null;
+		this.startOffset = 0;
+		this.endContainer = null;
+		this.endOffset = 0;
+		this.collapsed = true;
+}
+});
+} //if(!dijit.range._w3c)
+
+}
+
+if(!dojo._hasResource["dijit._editor.html"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._editor.html"] = true;
+dojo.provide("dijit._editor.html");
+
+dijit._editor.escapeXml=function(/*String*/str, /*Boolean?*/noSingleQuotes){
+	//summary:
+	//		Adds escape sequences for special characters in XML: &<>"'
+	//		Optionally skips escapes for single quotes
+	str = str.replace(/&/gm, "&").replace(/</gm, "<").replace(/>/gm, ">").replace(/"/gm, """);
+	if(!noSingleQuotes){
+		str = str.replace(/'/gm, "'");
+	}
+	return str; // string
+};
+
+dijit._editor.getNodeHtml=function(/* DomNode */node){
+	var output;
+	switch(node.nodeType){
+		case 1: //element node
+			output = '<' + node.nodeName.toLowerCase();
+
+			//store the list of attributes and sort it to have the
+			//attributes appear in the dictionary order
+			var attrarray = [];
+			if(dojo.isIE && node.outerHTML){
+				var s = node.outerHTML;
+				s = s.substr(0, s.indexOf('>'))
+					.replace(/(['"])[^"']*\1/g, ''); //to make the following regexp safe
+				var reg = /([^\s=]+)=/g;
+				var m, key;
+				while((m = reg.exec(s))){
+					key = m[1];
+					if(key.substr(0,3) != '_dj'){
+						if(key == 'src' || key == 'href'){
+							if(node.getAttribute('_djrealurl')){
+								attrarray.push([key,node.getAttribute('_djrealurl')]);
+								continue;
+							}
+						}
+						var val;
+						switch(key){
+							case 'style':
+								val = node.style.cssText.toLowerCase();
+								break;
+							case 'class':
+								val = node.className;
+								break;
+							default:
+								val = node.getAttribute(key);
+						}
+						attrarray.push([key, val.toString()]);
+					}
+				}
+			}else{
+				var attr, i = 0;
+				while((attr = node.attributes[i++])){
+					//ignore all attributes starting with _dj which are
+					//internal temporary attributes used by the editor
+					var n = attr.name;
+					if(n.substr(0,3) != '_dj' /*&&
+						(attr.specified == undefined || attr.specified)*/){
+						var v = attr.value;
+						if(n == 'src' || n == 'href'){
+							if(node.getAttribute('_djrealurl')){
+								v = node.getAttribute('_djrealurl');
+							}
+						}
+						attrarray.push([n,v]);
+					}
+				}
+			}
+			attrarray.sort(function(a,b){
+				return a[0]<b[0]?-1:(a[0]==b[0]?0:1);
+			});
+			var j = 0;
+			while((attr = attrarray[j++])){
+				output += ' ' + attr[0] + '="' +
+					(dojo.isString(attr[1]) ? dijit._editor.escapeXml(attr[1], true) : attr[1]) + '"';
+			}
+			if(node.childNodes.length){
+				output += '>' + dijit._editor.getChildrenHtml(node)+'</'+node.nodeName.toLowerCase()+'>';
+			}else{
+				output += ' />';
+			}
+			break;
+		case 3: //text
+			// FIXME:
+			output = dijit._editor.escapeXml(node.nodeValue, true);
+			break;
+		case 8: //comment
+			// FIXME:
+			output = '<!--' + dijit._editor.escapeXml(node.nodeValue, true) + '-->';
+			break;
+		default:
+			output = "<!-- Element not recognized - Type: " + node.nodeType + " Name: " + node.nodeName + "-->";
+	}
+	return output;
+};
+
+dijit._editor.getChildrenHtml = function(/* DomNode */dom){
+	// summary: Returns the html content of a DomNode and children
+	var out = "";
+	if(!dom){ return out; }
+	var nodes = dom["childNodes"] || dom;
+
+	//IE issue.
+	//If we have an actual node we can check parent relationships on for IE, 
+	//We should check, as IE sometimes builds invalid DOMS.  If no parent, we can't check
+	//And should just process it and hope for the best.
+	var checkParent = !dojo.isIE || nodes !== dom;
+
+	var node, i = 0;
+	while((node = nodes[i++])){
+		//IE is broken.  DOMs are supposed to be a tree.  But in the case of malformed HTML, IE generates a graph
+		//meaning one node ends up with multiple references (multiple parents).  This is totally wrong and invalid, but
+		//such is what it is.  We have to keep track and check for this because otherise the source output HTML will have dups.
+		//No other browser generates a graph.  Leave it to IE to break a fundamental DOM rule.  So, we check the parent if we can
+		//If we can't, nothing more we can do other than walk it.
+		if(!checkParent || node.parentNode == dom){
+			out += dijit._editor.getNodeHtml(node);
+		}
+	}
+	return out; // String
+};
+
+}
+
+if(!dojo._hasResource["dijit._editor.RichText"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._editor.RichText"] = true;
+dojo.provide("dijit._editor.RichText");
+
+
+
+
+
+
+
+
+// used to restore content when user leaves this page then comes back
+// but do not try doing dojo.doc.write if we are using xd loading.
+// dojo.doc.write will only work if RichText.js is included in the dojo.js
+// file. If it is included in dojo.js and you want to allow rich text saving
+// for back/forward actions, then set dojo.config.allowXdRichTextSave = true.
+if(!dojo.config["useXDomain"] || dojo.config["allowXdRichTextSave"]){
+	if(dojo._postLoad){
+		(function(){
+			var savetextarea = dojo.doc.createElement('textarea');
+			savetextarea.id = dijit._scopeName + "._editor.RichText.savedContent";
+			dojo.style(savetextarea, {
+				display:'none',
+				position:'absolute',
+				top:"-100px",
+				height:"3px",
+				width:"3px"
+			});
+			dojo.body().appendChild(savetextarea);
+		})();
+	}else{
+		//dojo.body() is not available before onLoad is fired
+		try {
+			dojo.doc.write('<textarea id="' + dijit._scopeName + '._editor.RichText.savedContent" ' +
+				'style="display:none;position:absolute;top:-100px;left:-100px;height:3px;width:3px;overflow:hidden;"></textarea>');
+		}catch(e){ }
+	}
+}
+
+dojo.declare("dijit._editor.RichText", dijit._Widget, {
+	constructor: function(params){
+		// summary:
+		//		dijit._editor.RichText is the core of dijit.Editor, which provides basic
+		//		WYSIWYG editing features.
+		//
+		// description:
+		//		dijit._editor.RichText is the core of dijit.Editor, which provides basic
+		//		WYSIWYG editing features. It also encapsulates the differences
+		//		of different js engines for various browsers.  Do not use this widget
+		//		with an HTML <TEXTAREA> tag, since the browser unescapes XML escape characters,
+		//		like <.  This can have unexpected behavior and lead to security issues
+		//		such as scripting attacks.
+		//
+		// tags:
+		//		private
+
+		// contentPreFilters: Function(String)[]
+		//		Pre content filter function register array.
+		//		these filters will be executed before the actual
+		//		editing area gets the html content.
+		this.contentPreFilters = [];
+
+		// contentPostFilters: Function(String)[]
+		//		post content filter function register array.
+		//		These will be used on the resulting html
+		//		from contentDomPostFilters. The resulting
+		//		content is the final html (returned by getValue()).
+		this.contentPostFilters = [];
+
+		// contentDomPreFilters: Function(DomNode)[]
+		//		Pre content dom filter function register array.
+		//		These filters are applied after the result from
+		//		contentPreFilters are set to the editing area.
+		this.contentDomPreFilters = [];
+
+		// contentDomPostFilters: Function(DomNode)[]
+		//		Post content dom filter function register array.
+		//		These filters are executed on the editing area dom.
+		//		The result from these will be passed to contentPostFilters.
+		this.contentDomPostFilters = [];
+
+		// editingAreaStyleSheets: dojo._URL[]
+		//		array to store all the stylesheets applied to the editing area
+		this.editingAreaStyleSheets=[];
+
+		this._keyHandlers = {};
+		this.contentPreFilters.push(dojo.hitch(this, "_preFixUrlAttributes"));
+		if(dojo.isMoz){
+			this.contentPreFilters.push(this._fixContentForMoz);
+			this.contentPostFilters.push(this._removeMozBogus);
+		}
+		if(dojo.isSafari){
+			this.contentPostFilters.push(this._removeSafariBogus);
+		}
+		//this.contentDomPostFilters.push(this._postDomFixUrlAttributes);
+
+		this.onLoadDeferred = new dojo.Deferred();
+	},
+
+	// inheritWidth: Boolean
+	//		whether to inherit the parent's width or simply use 100%
+	inheritWidth: false,
+
+	// focusOnLoad: [deprecated] Boolean
+	//		Focus into this widget when the page is loaded
+	focusOnLoad: false,
+
+	// name: String?
+	//		Specifies the name of a (hidden) <textarea> node on the page that's used to save
+	//		the editor content on page leave.   Used to restore editor contents after navigating
+	//		to a new page and then hitting the back button.
+	name: "",
+
+	// styleSheets: [const] String
+	//		semicolon (";") separated list of css files for the editing area
+	styleSheets: "",
+
+	// _content: [private] String
+	//		temporary content storage
+	_content: "",
+
+	// height: String
+	//		Set height to fix the editor at a specific height, with scrolling.
+	//		By default, this is 300px.  If you want to have the editor always
+	//		resizes to accommodate the content, use AlwaysShowToolbar plugin
+	//		and set height="".  If this editor is used within a layout widget,
+	//		set height="100%".
+	height: "300px",
+
+	// minHeight: String
+	//		The minimum height that the editor should have.
+	minHeight: "1em",
+	
+	// isClosed: [private] Boolean
+	isClosed: true,
+
+	// isLoaded: [private] Boolean
+	isLoaded: false,
+
+	// _SEPARATOR: [private] String
+	//		Used to concat contents from multiple editors into a single string,
+	//		so they can be saved into a single <textarea> node.  See "name" attribute.
+	_SEPARATOR: "@@**%%__RICHTEXTBOUNDRY__%%**@@",
+
+	// onLoadDeferred: [protected] dojo.Deferred
+	//		Deferred which is fired when the editor finishes loading
+	onLoadDeferred: null,
+	
+	// isTabIndent: Boolean
+	//		Make tab key and shift-tab indent and outdent rather than navigating.
+	//		Caution: sing this makes web pages inaccessible to users unable to use a mouse.
+	isTabIndent: false,
+
+	// disableSpellCheck: [const] Boolean
+	//		When true, disables the browser's native spell checking, if supported.
+	//		Works only in Firefox.
+	disableSpellCheck: false,
+
+	postCreate: function(){
+		if("textarea" == this.domNode.tagName.toLowerCase()){
+			console.warn("RichText should not be used with the TEXTAREA tag.  See dijit._editor.RichText docs.");
+		}
+		dojo.publish(dijit._scopeName + "._editor.RichText::init", [this]);
+		this.open();
+		this.setupDefaultShortcuts();
+	},
+
+	setupDefaultShortcuts: function(){
+		// summary:
+		//		Add some default key handlers
+		// description:
+		// 		Overwrite this to setup your own handlers. The default
+		// 		implementation does not use Editor commands, but directly
+		//		executes the builtin commands within the underlying browser
+		//		support.
+		// tags:
+		//		protected
+		var exec = dojo.hitch(this, function(cmd, arg){
+			return function(){
+				return !this.execCommand(cmd,arg);
+			};
+		});
+
+		var ctrlKeyHandlers = { 
+			b: exec("bold"),
+			i: exec("italic"),
+			u: exec("underline"),
+			a: exec("selectall"),
+			s: function(){ this.save(true); },
+			m: function(){ this.isTabIndent = !this.isTabIndent; },
+
+			"1": exec("formatblock", "h1"),
+			"2": exec("formatblock", "h2"),
+			"3": exec("formatblock", "h3"),
+			"4": exec("formatblock", "h4"),
+
+			"\\": exec("insertunorderedlist")
+		};
+
+		if(!dojo.isIE){
+			ctrlKeyHandlers.Z = exec("redo"); //FIXME: undo?
+		}
+
+		for(var key in ctrlKeyHandlers){
+			this.addKeyHandler(key, true, false, ctrlKeyHandlers[key]);
+		}
+	},
+
+	// events: [private] String[]
+	//		 events which should be connected to the underlying editing area
+	events: ["onKeyPress", "onKeyDown", "onKeyUp", "onClick"],
+
+	// captureEvents: [deprecated] String[]
+	//		 Events which should be connected to the underlying editing
+	//		 area, events in this array will be addListener with
+	//		 capture=true.
+	// TODO: looking at the code I don't see any distinction between events and captureEvents,
+	// so get rid of this for 2.0 if not sooner
+	captureEvents: [],
+
+	_editorCommandsLocalized: false,
+	_localizeEditorCommands: function(){
+		// summary:
+		//		When IE is running in a non-English locale, the API actually changes,
+		//		so that we have to say (for example) danraku instead of p (for paragraph).
+		//		Handle that here.
+		// tags:
+		//		private
+		if(this._editorCommandsLocalized){
+			return;
+		}
+		this._editorCommandsLocalized = true;
+
+		//in IE, names for blockformat is locale dependent, so we cache the values here
+
+		//if the normal way fails, we try the hard way to get the list
+
+		//do not use _cacheLocalBlockFormatNames here, as it will
+		//trigger security warning in IE7
+
+		//put p after div, so if IE returns Normal, we show it as paragraph
+		//We can distinguish p and div if IE returns Normal, however, in order to detect that,
+		//we have to call this.document.selection.createRange().parentElement() or such, which
+		//could slow things down. Leave it as it is for now
+		var formats = ['div', 'p', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'ul', 'address'];
+		var localhtml = "", format, i=0;
+		while((format=formats[i++])){
+			//append a <br> after each element to separate the elements more reliably
+			if(format.charAt(1) != 'l'){
+				localhtml += "<"+format+"><span>content</span></"+format+"><br/>";
+			}else{
+				localhtml += "<"+format+"><li>content</li></"+format+"><br/>";
+			}
+		}
+		//queryCommandValue returns empty if we hide editNode, so move it out of screen temporary
+		var div = dojo.doc.createElement('div');
+		dojo.style(div, {
+			position: "absolute",
+			top: "-2000px"
+		});
+		dojo.doc.body.appendChild(div);
+		div.innerHTML = localhtml;
+		var node = div.firstChild;
+		while(node){
+			dijit._editor.selection.selectElement(node.firstChild);
+			dojo.withGlobal(this.window, "selectElement", dijit._editor.selection, [node.firstChild]);
+			var nativename = node.tagName.toLowerCase();
+			this._local2NativeFormatNames[nativename] = document.queryCommandValue("formatblock");
+			//this.queryCommandValue("formatblock");
+			this._native2LocalFormatNames[this._local2NativeFormatNames[nativename]] = nativename;
+			node = node.nextSibling.nextSibling;
+		}
+		dojo.body().removeChild(div);
+	},
+
+	open: function(/*DomNode?*/ element){
+		//	summary:
+		//		Transforms the node referenced in this.domNode into a rich text editing
+		//		node. 
+		//	description:
+		//		Sets up the editing area asynchronously. This will result in
+		//		the creation and replacement with an <iframe> if
+		//		designMode(FF)/contentEditable(IE) is used and stylesheets are
+		//		specified, if we're in a browser that doesn't support
+		//		contentEditable.
+		//
+		//		A dojo.Deferred object is created at this.onLoadDeferred, and
+		//		users may attach to it to be informed when the rich-text area
+		//		initialization is finalized.
+		// tags:
+		//		private
+
+		if(!this.onLoadDeferred || this.onLoadDeferred.fired >= 0){
+			this.onLoadDeferred = new dojo.Deferred();
+		}
+
+		if(!this.isClosed){ this.close(); }
+		dojo.publish(dijit._scopeName + "._editor.RichText::open", [ this ]);
+
+		this._content = "";
+		if(arguments.length == 1 && element.nodeName){ // else unchanged
+			this.domNode = element; 
+		} 
+
+		var dn = this.domNode;
+
+		var html;
+		if(dn.nodeName && dn.nodeName.toLowerCase() == "textarea"){
+			// if we were created from a textarea, then we need to create a
+			// new editing harness node.
+			var ta = (this.textarea = dn);
+			this.name = ta.name;
+			html = this._preFilterContent(ta.value);
+			dn = this.domNode = dojo.doc.createElement("div");
+			dn.setAttribute('widgetId', this.id);
+			ta.removeAttribute('widgetId');
+			dn.cssText = ta.cssText;
+			dn.className += " " + ta.className;
+			dojo.place(dn, ta, "before");
+			var tmpFunc = dojo.hitch(this, function(){
+				//some browsers refuse to submit display=none textarea, so
+				//move the textarea out of screen instead
+				dojo.style(ta, {
+					display: "block",
+					position: "absolute",
+					top: "-1000px"
+				});
+
+				if(dojo.isIE){ //nasty IE bug: abnormal formatting if overflow is not hidden
+					var s = ta.style;
+					this.__overflow = s.overflow;
+					s.overflow = "hidden";
+				}
+			});
+			if(dojo.isIE){
+				setTimeout(tmpFunc, 10);
+			}else{
+				tmpFunc();
+			}
+
+			// this.domNode.innerHTML = html;
+
+			if(ta.form){
+				dojo.connect(ta.form, "onsubmit", this, function(){
+					// FIXME: should we be calling close() here instead?
+					ta.value = this.getValue();
+				});
+			}
+		}else{
+			html = this._preFilterContent(dijit._editor.getChildrenHtml(dn));
+			dn.innerHTML = "";
+		}
+
+		var content = dojo.contentBox(dn);
+		// var content = dojo.contentBox(this.srcNodeRef);
+		this._oldHeight = content.h;
+		this._oldWidth = content.w;
+
+		this.savedContent = html;
+
+		// If we're a list item we have to put in a blank line to force the
+		// bullet to nicely align at the top of text
+		if(dn.nodeName && dn.nodeName == "LI"){
+			dn.innerHTML = " <br>";
+		}
+
+		this.editingArea = dn.ownerDocument.createElement("div");
+		dn.appendChild(this.editingArea);
+
+		if(this.name != "" && (!dojo.config["useXDomain"] || dojo.config["allowXdRichTextSave"])){
+			var saveTextarea = dojo.byId(dijit._scopeName + "._editor.RichText.savedContent");
+			if(saveTextarea.value != ""){
+				var datas = saveTextarea.value.split(this._SEPARATOR), i=0, dat;
+				while((dat=datas[i++])){
+					var data = dat.split(":");
+					if(data[0] == this.name){
+						html = data[1];
+						datas.splice(i, 1);
+						break;
+					}
+				}
+			}
+
+			// FIXME: need to do something different for Opera/Safari
+			this.connect(window, "onbeforeunload", "_saveContent");
+			// dojo.connect(window, "onunload", this, "_saveContent");
+		}
+
+		this.isClosed = false;
+
+		// Safari's selections go all out of whack if we do it inline,
+		// so for now IE is our only hero
+		//if(typeof dojo.doc.body.contentEditable != "undefined")
+		if(dojo.isIE || dojo.isWebKit || dojo.isOpera){
+			// In 0.4, this was the contentEditable code path, but now it creates an iframe, same as for Firefox.
+			// However, firefox's iframe is handled by _drawIframe() rather than this code for some reason :-(
+			var ifr = (this.editorObject = this.iframe = dojo.doc.createElement('iframe'));
+			ifr.id = this.id+"_iframe";
+			this._iframeSrc = this._getIframeDocTxt(html);
+			ifr.style.border = "none";
+			ifr.style.width = "100%";
+			if(this._layoutMode){
+				// iframe should be 100% height, thus getting it's height from surrounding
+				// <div> (which has the correct height set by Editor
+				ifr.style.height = "100%";
+			}else{
+				if(dojo.isIE >= 7){
+					if(this.height){
+						ifr.style.height = this.height;
+					}
+					if(this.minHeight){
+						ifr.style.minHeight = this.minHeight;
+					}
+				}else{
+					ifr.style.height = this.height ? this.height : this.minHeight;
+				}
+			}
+			ifr.frameBorder = 0;
+			// ifr.style.scrolling = this.height ? "auto" : "vertical";
+			ifr._loadFunc = dojo.hitch( this, function(win){
+				this.window = win;
+				this.document = this.window.document;
+
+				if(dojo.isIE){
+					this._localizeEditorCommands();
+				}
+
+				this.onLoad();
+				this.savedContent = this.getValue(true);
+			});
+			var s = 'javascript:parent.' + dijit._scopeName + '.byId("'+this.id+'")._iframeSrc';
+			ifr.setAttribute('src', s);
+			this.editingArea.appendChild(ifr);
+			if(dojo.isWebKit){ // Safari seems to always append iframe with src=about:blank
+				setTimeout(function(){ifr.setAttribute('src', s)},0);
+			}
+		}else{
+			// Firefox code path
+			this._drawIframe(html);
+			this.savedContent = this.getValue(true);
+		}
+		
+		// TODO: this is a guess at the default line-height, kinda works
+		if(dn.nodeName == "LI"){
+			dn.lastChild.style.marginTop = "-1.2em";
+		}
+
+		if(this.domNode.nodeName == "LI"){ this.domNode.lastChild.style.marginTop = "-1.2em"; }
+		dojo.addClass(this.domNode, "RichTextEditable");
+	},
+
+	//static cache variables shared among all instance of this class
+	_local2NativeFormatNames: {},
+	_native2LocalFormatNames: {},
+	_localizedIframeTitles: null,
+
+	_getIframeDocTxt: function(/* String */ html){
+		// summary:
+		//		Generates text of the document inside the iframe (ie, <html>....editor content...</html>
+		// tags:
+		//		private
+		var _cs = dojo.getComputedStyle(this.domNode);
+		if(dojo.isIE || (!this.height && !dojo.isMoz)){
+			html="<div>"+html+"</div>";
+		}
+		var font = [ _cs.fontWeight, _cs.fontSize, _cs.fontFamily ].join(" ");
+		
+		// line height is tricky - applying a units value will mess things up.
+		// if we can't get a non-units value, bail out.
+		var lineHeight = _cs.lineHeight;
+		if(lineHeight.indexOf("px") >= 0){
+			lineHeight = parseFloat(lineHeight)/parseFloat(_cs.fontSize);
+			// 
+		}else if(lineHeight.indexOf("em")>=0){
+			lineHeight = parseFloat(lineHeight);
+		}else{
+			lineHeight = "1.0";
+		}
+		var userStyle = "";
+		this.style.replace(/(^|;)(line-|font-?)[^;]+/g, function(match){ userStyle += match.replace(/^;/g,"") + ';' });
+
+		/*
+		 * On IE the iframe needs to have the same codepage as the main page does, or the
+		 * src=javascript:..._iframeSrc won't handle non-ascii characters correctly
+		 */
+		var d = dojo.doc;
+		var charset =
+			/*IE*/ d.charset || 
+			/*FF, Webkit, Opera, etc */ d.characterSet || 
+			/*nothing, look for defaults */ d.defaultCharset || "UTF-8";
+
+		return [
+			this.isLeftToRight() ? "<html><head>" : "<html dir='rtl'><head>",
+			(dojo.isMoz ? "<title>" + this._localizedIframeTitles.iframeEditTitle + "</title>" : ""),
+			"<meta http-equiv='Content-Type' content='text/html; charset=" + charset + "'>",
+			"<style>",
+			"body,html {",
+			"\tbackground:transparent;",
+			"\tpadding: 1em 0 0 0;",
+			"\tmargin: -1em 0 0 0;", // remove extraneous vertical scrollbar on safari and firefox
+			"}",
+			// TODO: left positioning will cause contents to disappear out of view
+			//	   if it gets too wide for the visible area
+			"body{",
+			"\ttop:0px; left:0px; right:0px;",
+			"\tfont:", font, ";",
+				((this.height||dojo.isOpera) ? "" : "position: fixed;"),
+			// FIXME: IE 6 won't understand min-height?
+			"\tmin-height:", this.minHeight, ";",
+			"\tline-height:", lineHeight,
+			"}",
+			"p{ margin: 1em 0 !important; }",
+			(this.height ? // height:auto undoes the height:100%
+				"" : "body,html{overflow-y:hidden;/*for IE*/} body > div {overflow-x:auto;/*FF:horizontal scrollbar*/ overflow-y:hidden;/*safari*/ min-height:"+this.minHeight+";/*safari*/}"
+			),
+			"li > ul:-moz-first-node, li > ol:-moz-first-node{ padding-top: 1.2em; } ",
+			"li{ min-height:1.2em; }",
+			"</style>",
+			this._applyEditingAreaStyleSheets(),
+			"</head><body onload='frameElement._loadFunc(window,document)' style='"+userStyle+"'>"+html+"</body></html>"
+		].join(""); // String
+	},
+
+	_drawIframe: function(/*String*/ html){
+		// summary:
+		//		Draws an iFrame using the existing one if one exists.
+		//		Used by Firefox only.  See open() for code for other browsers.
+		// tags:
+		//		private
+
+		if(!this.iframe){
+			var ifr = (this.iframe = dojo.doc.createElement("iframe"));
+			ifr.id=this.id+"_iframe";
+			// this.iframe.src = "about:blank";
+			// dojo.doc.body.appendChild(this.iframe);
+			// 
+			// dojo.body().appendChild(this.iframe);
+			var ifrs = ifr.style;
+			// ifrs.border = "1px solid black";
+			ifrs.border = "none";
+			ifrs.lineHeight = "0"; // squash line height
+			ifrs.verticalAlign = "bottom";
+			// ifrs.scrolling = this.height ? "auto" : "vertical";
+			this.editorObject = this.iframe;
+			// get screen reader text for mozilla here, too
+			this._localizedIframeTitles = dojo.i18n.getLocalization("dijit.form", "Textarea");
+			// need to find any associated label element and update iframe document title
+			var label=dojo.query('label[for="'+this.id+'"]');
+			if(label.length){
+				this._localizedIframeTitles.iframeEditTitle = label[0].innerHTML + " " + this._localizedIframeTitles.iframeEditTitle;
+			}
+			ifr._loadFunc = function(win){}; // TODO: drawIframe should be refactored to use this event handler instead of janky setTimeout loops
+		}
+		// opera likes this to be outside the with block
+		//	this.iframe.src = "javascript:void(0)";//dojo.uri.dojoUri("src/widget/templates/richtextframe.html") + ((dojo.doc.domain != currentDomain) ? ("#"+dojo.doc.domain) : "");
+		this.iframe.style.width = this.inheritWidth ? this._oldWidth : "100%";
+
+		if(this._layoutMode){
+			// iframe should be 100% height, thus getting it's height from surrounding
+			// <div> (which has the correct height set by Editor
+			this.iframe.style.height = "100%";
+		}else{
+			if(this.height){
+				this.iframe.style.height = this.height;
+			}else{
+				this.iframe.height = this._oldHeight;
+			}
+		}
+
+		var tmpContent;
+		if(this.textarea){
+			tmpContent = this.srcNodeRef;
+		}else{
+			tmpContent = dojo.doc.createElement('div');
+			tmpContent.style.display="none";
+			tmpContent.innerHTML = html;
+			//append tmpContent to under the current domNode so that the margin
+			//calculation below is correct
+			this.editingArea.appendChild(tmpContent);
+		}
+		this.editingArea.appendChild(this.iframe);
+
+		//do we want to show the content before the editing area finish loading here?
+		//if external style sheets are used for the editing area, the appearance now
+		//and after loading of the editing area won't be the same (and padding/margin
+		//calculation above may not be accurate)
+		//	tmpContent.style.display = "none";
+		//	this.editingArea.appendChild(this.iframe);
+
+
+		// now we wait for the iframe to load. Janky hack!
+		var ifrFunc = dojo.hitch(this, function(){
+			if(!this.editNode){
+				// Iframe hasn't been loaded yet.
+				// First deal w/the document to be available (may have to wait for it)
+				if(!this.document){
+					try{
+						if(this.iframe.contentWindow){
+							this.window = this.iframe.contentWindow;
+							this.document = this.iframe.contentWindow.document
+						}else if(this.iframe.contentDocument){
+							// for opera
+							// TODO: this method is only being called for FF2; can we remove this?
+							this.window = this.iframe.contentDocument.window;
+							this.document = this.iframe.contentDocument;
+						}
+					}catch(e){}
+					if(!this.document){
+						setTimeout(ifrFunc,50);
+						return;
+					}
+					// note that on Safari lower than 420+, we have to get the iframe
+					// by ID in order to get something w/ a contentDocument property
+					var contentDoc = this.document;
+					contentDoc.open();
+					if(dojo.isAIR){
+						contentDoc.body.innerHTML = html;
+					}else{
+						contentDoc.write(this._getIframeDocTxt(html));
+					}
+					contentDoc.close();
+					
+					dojo.destroy(tmpContent);
+				}
+
+				// Wait for body to be available
+				// Writing into contentDoc (above) can make <body> temporarily unavailable, may have to delay again
+				if(!this.document.body){
+					//
+					setTimeout(ifrFunc,50);
+					return;
+				}
+
+				this.onLoad();
+			}else{
+				// Iframe is already loaded, we are just switching the content
+				dojo.destroy(tmpContent);
+				this.editNode.innerHTML = html;
+				this.onDisplayChanged();
+			}
+			this._preDomFilterContent(this.editNode);
+		});
+
+		ifrFunc();
+	},
+
+	_applyEditingAreaStyleSheets: function(){
+		// summary:
+		//		apply the specified css files in styleSheets
+		// tags:
+		//		private
+		var files = [];
+		if(this.styleSheets){
+			files = this.styleSheets.split(';');
+			this.styleSheets = '';
+		}
+
+		//empty this.editingAreaStyleSheets here, as it will be filled in addStyleSheet
+		files = files.concat(this.editingAreaStyleSheets);
+		this.editingAreaStyleSheets = [];
+
+		var text='', i=0, url;
+		while((url=files[i++])){
+			var abstring = (new dojo._Url(dojo.global.location, url)).toString();
+			this.editingAreaStyleSheets.push(abstring);
+			text += '<link rel="stylesheet" type="text/css" href="'+abstring+'"/>'
+		}
+		return text;
+	},
+
+	addStyleSheet: function(/*dojo._Url*/ uri){
+		// summary:
+		//		add an external stylesheet for the editing area
+		// uri:
+		//		A dojo.uri.Uri pointing to the url of the external css file
+		var url=uri.toString();
+
+		//if uri is relative, then convert it to absolute so that it can be resolved correctly in iframe
+		if(url.charAt(0) == '.' || (url.charAt(0) != '/' && !uri.host)){
+			url = (new dojo._Url(dojo.global.location, url)).toString();
+		}
+
+		if(dojo.indexOf(this.editingAreaStyleSheets, url) > -1){
+//			
+			return;
+		}
+
+		this.editingAreaStyleSheets.push(url);
+		if(this.document.createStyleSheet){ //IE
+			this.document.createStyleSheet(url);
+		}else{ //other browser
+			var head = this.document.getElementsByTagName("head")[0];
+			var stylesheet = this.document.createElement("link");
+			stylesheet.rel="stylesheet";
+			stylesheet.type="text/css";
+			stylesheet.href=url;
+			head.appendChild(stylesheet);
+		}
+	},
+
+	removeStyleSheet: function(/*dojo._Url*/ uri){
+		// summary:
+		//		remove an external stylesheet for the editing area
+		var url=uri.toString();
+		//if uri is relative, then convert it to absolute so that it can be resolved correctly in iframe
+		if(url.charAt(0) == '.' || (url.charAt(0) != '/' && !uri.host)){
+			url = (new dojo._Url(dojo.global.location, url)).toString();
+		}
+		var index = dojo.indexOf(this.editingAreaStyleSheets, url);
+		if(index == -1){
+//			
+			return;
+		}
+		delete this.editingAreaStyleSheets[index];
+		dojo.withGlobal(this.window,'query', dojo, ['link:[href="'+url+'"]']).orphan()
+	},
+
+	// disabled: Boolean
+	// 		The editor is disabled; the text cannot be changed.
+	disabled: false,
+
+	_mozSettingProps: {'styleWithCSS':false},
+	_setDisabledAttr: function(/*Boolean*/ value){
+		this.disabled = value;
+		if(!this.isLoaded){ return; } // this method requires init to be complete
+		value = !!value;
+		if(dojo.isIE || dojo.isWebKit || dojo.isOpera){
+			var preventIEfocus = dojo.isIE && (this.isLoaded || !this.focusOnLoad);
+			if(preventIEfocus){ this.editNode.unselectable = "on"; }
+			this.editNode.contentEditable = !value;
+			if(preventIEfocus){
+				var _this = this;
+				setTimeout(function(){ _this.editNode.unselectable = "off"; }, 0);
+			}
+		}else{ //moz
+			try{
+				this.document.designMode=(value?'off':'on');
+			}catch(e){ return; } // ! _disabledOK
+			if(!value && this._mozSettingProps){
+				var ps = this._mozSettingProps;
+				for(var n in ps){
+					if(ps.hasOwnProperty(n)){
+						try{
+							this.document.execCommand(n,false,ps[n]);
+						}catch(e){}
+					}
+				}
+			}
+//			this.document.execCommand('contentReadOnly', false, value);
+//				if(value){
+//					this.blur(); //to remove the blinking caret
+//				}
+		}
+		this._disabledOK = true;
+	},
+
+/* Event handlers
+ *****************/
+
+	// TODO: _isResized seems to be unused anywhere; remove for 2.0
+	_isResized: function(){ return false; },
+
+	onLoad: function(/* Event */ e){
+		// summary:
+		//		Handler after the content of the document finishes loading.
+		// tags:
+		//		protected
+
+		// TODO: rename this to _onLoad, make empty public onLoad() method, deprecate/make protected onLoadDeferred handler?
+
+		if(!this.window.__registeredWindow){
+			this.window.__registeredWindow = true;
+			dijit.registerIframe(this.iframe);
+		}
+		if(!dojo.isIE && (this.height || dojo.isMoz)){
+			this.editNode=this.document.body;
+		}else{
+			this.editNode=this.document.body.firstChild;
+			var _this = this;
+			if(dojo.isIE){ // #4996 IE wants to focus the BODY tag
+				var tabStop = (this.tabStop = dojo.doc.createElement('<div tabIndex=-1>'));
+				this.editingArea.appendChild(tabStop);
+				this.iframe.onfocus = function(){ _this.editNode.setActive(); }
+			}
+		}
+		this.focusNode = this.editNode; // for InlineEditBox
+
+		this._preDomFilterContent(this.editNode);
+
+		var events = this.events.concat(this.captureEvents);
+		var ap = this.iframe ? this.document : this.editNode;
+		dojo.forEach(events, function(item){
+			// dojo.connect(ap, item.toLowerCase(), console, "debug");
+			this.connect(ap, item.toLowerCase(), item);
+		}, this);
+
+		if(dojo.isIE){ // IE contentEditable
+			// give the node Layout on IE
+			this.connect(this.document, "onmousedown", "_onIEMouseDown"); // #4996 fix focus
+			this.editNode.style.zoom = 1.0;
+		}
+
+		if(dojo.isWebKit){ 
+			//WebKit sometimes doesn't fire right on selections, so the toolbar
+			//doesn't update right.  Therefore, help it out a bit with an additional
+			//listener.  A mouse up will typically indicate a display change, so fire this
+			//and get the toolbar to adapt.  Reference: #9532 
+			this._webkitListener = this.connect(this.document, "onmouseup", "onDisplayChanged");
+		}
+
+		this.isLoaded = true;
+
+		this.attr('disabled', this.disabled); // initialize content to editable (or not)
+
+		if(this.onLoadDeferred){
+			this.onLoadDeferred.callback(true);
+		}
+
+		this.onDisplayChanged(e);
+
+		if(this.focusOnLoad){
+			// after the document loads, then set focus after updateInterval expires so that 
+			// onNormalizedDisplayChanged has run to avoid input caret issues
+			dojo.addOnLoad(dojo.hitch(this, function(){ setTimeout(dojo.hitch(this, "focus"), this.updateInterval) }));
+		}
+	},
+
+	onKeyDown: function(/* Event */ e){
+		// summary:
+		//		Handler for onkeydown event
+		// tags:
+		//		protected
+
+		// we need this event at the moment to get the events from control keys
+		// such as the backspace. It might be possible to add this to Dojo, so that
+		// keyPress events can be emulated by the keyDown and keyUp detection.
+		
+		if(e.keyCode === dojo.keys.TAB && this.isTabIndent ){
+			dojo.stopEvent(e); //prevent tab from moving focus out of editor
+
+			// FIXME: this is a poor-man's indent/outdent. It would be
+			// better if it added 4 " " chars in an undoable way.
+			// Unfortunately pasteHTML does not prove to be undoable
+			if(this.queryCommandEnabled((e.shiftKey ? "outdent" : "indent"))){
+				this.execCommand((e.shiftKey ? "outdent" : "indent"));
+			}			
+		}
+		if(dojo.isIE){
+			if(e.keyCode == dojo.keys.TAB && !this.isTabIndent){
+				if(e.shiftKey && !e.ctrlKey && !e.altKey){
+					// focus the BODY so the browser will tab away from it instead
+					this.iframe.focus();
+				}else if(!e.shiftKey && !e.ctrlKey && !e.altKey){
+					// focus the BODY so the browser will tab away from it instead
+					this.tabStop.focus();
+				}
+			}else if(e.keyCode === dojo.keys.BACKSPACE && this.document.selection.type === "Control"){
+				// IE has a bug where if a non-text object is selected in the editor,
+				// hitting backspace would act as if the browser's back button was
+				// clicked instead of deleting the object. see #1069
+				dojo.stopEvent(e);
+				this.execCommand("delete");
+			}else if((65 <= e.keyCode&&e.keyCode <= 90) ||
+				(e.keyCode>=37&&e.keyCode<=40) // FIXME: get this from connect() instead!
+			){ //arrow keys
+				e.charCode = e.keyCode;
+				this.onKeyPress(e);
+			}
+		}else if(dojo.isMoz  && !this.isTabIndent){
+			if(e.keyCode == dojo.keys.TAB && !e.shiftKey && !e.ctrlKey && !e.altKey && this.iframe){
+				// update iframe document title for screen reader
+				var titleObj = dojo.isFF<3 ? this.iframe.contentDocument : this.iframe;
+			 	titleObj.title = this._localizedIframeTitles.iframeFocusTitle;
+				// Place focus on the iframe. A subsequent tab or shift tab will put focus
+				// on the correct control.
+				this.iframe.focus();  // this.focus(); won't work
+				dojo.stopEvent(e);
+			}else if(e.keyCode == dojo.keys.TAB && e.shiftKey){
+				// if there is a toolbar, set focus to it, otherwise ignore
+				if(this.toolbar){
+					this.toolbar.focus();
+				}
+				dojo.stopEvent(e);
+			}
+		}
+		return true;
+	},
+
+	onKeyUp: function(e){
+		// summary:
+		//		Handler for onkeyup event
+		// tags:
+		//      callback
+		return;
+	},
+
+	setDisabled: function(/*Boolean*/ disabled){
+		// summary:
+		//		Deprecated, use attr('disabled', ...) instead.
+		// tags:
+		//		deprecated
+		dojo.deprecated('dijit.Editor::setDisabled is deprecated','use dijit.Editor::attr("disabled",boolean) instead', 2.0);
+		this.attr('disabled',disabled);
+	},
+	_setValueAttr: function(/*String*/ value){
+		// summary:
+		//      Registers that attr("value", foo) should call setValue(foo)
+		this.setValue(value);
+	},
+	_getDisableSpellCheckAttr: function(){
+		return !dojo.attr(this.document.body, "spellcheck");
+	},
+	_setDisableSpellCheckAttr: function(/*Boolean*/ disabled){
+		if(this.document){
+			dojo.attr(this.document.body, "spellcheck", !disabled);
+		}else{
+			// try again after the editor is finished loading 
+			this.onLoadDeferred.addCallback(dojo.hitch(this, function(){
+				dojo.attr(this.document.body, "spellcheck", !disabled);
+			}));
+		}
+	},
+
+	onKeyPress: function(e){
+		// summary:
+		//		Handle the various key events
+		// tags:
+		//		protected
+
+		//
+		var c = (e.keyChar && e.keyChar.toLowerCase()) || e.keyCode
+		var handlers = this._keyHandlers[c];
+		//
+		var args = arguments;
+		if(handlers && !e.altKey){
+			dojo.forEach(handlers, function(h){
+				if((!!h.shift == !!e.shiftKey)&&(!!h.ctrl == !!e.ctrlKey)){
+					if(!h.handler.apply(this, args)){
+						e.preventDefault();
+					}
+					// break;
+				}
+			}, this);
+		}
+
+		// function call after the character has been inserted
+		if(!this._onKeyHitch){
+			this._onKeyHitch=dojo.hitch(this, "onKeyPressed");
+		}
+		setTimeout(this._onKeyHitch, 1);
+		return true;
+	},
+
+	addKeyHandler: function(/*String*/ key, /*Boolean*/ ctrl, /*Boolean*/ shift, /*Function*/ handler){
+		// summary:
+		//		Add a handler for a keyboard shortcut
+		// description:
+		//		The key argument should be in lowercase if it is a letter character
+		// tags:
+		//		protected
+		if(!dojo.isArray(this._keyHandlers[key])){
+			this._keyHandlers[key] = [];
+		}
+		this._keyHandlers[key].push({
+			shift: shift || false,
+			ctrl: ctrl || false,
+			handler: handler
+		});
+	},
+
+	onKeyPressed: function(){
+		// summary:
+		//		Handler for after the user has pressed a key, and the display has been updated.
+		//		(Runs on a timer so that it runs after the display is updated)
+		// tags:
+		//		private
+		this.onDisplayChanged(/*e*/); // can't pass in e
+	},
+
+	onClick: function(/*Event*/ e){
+		// summary:
+		//		Handler for when the user clicks.
+		// tags:
+		//		private
+
+		// 
+		this.onDisplayChanged(e);
+	},
+
+	_onIEMouseDown: function(/*Event*/ e){
+		// summary:
+		//		IE only to prevent 2 clicks to focus
+		// tags:
+		//		protected
+
+		if(!this._focused && !this.disabled){
+			this.focus();
+		}
+	},
+
+	_onBlur: function(e){
+		// summary:
+		//		Called from focus manager when focus has moved away from this editor
+		// tags:
+		//		protected
+
+		// 
+
+		this.inherited(arguments);
+		var _c=this.getValue(true);
+		
+		if(_c!=this.savedContent){
+			this.onChange(_c);
+			this.savedContent=_c;
+		}
+		if(dojo.isMoz && this.iframe){
+			var titleObj = dojo.isFF<3 ? this.iframe.contentDocument : this.iframe;
+			 titleObj.title = this._localizedIframeTitles.iframeEditTitle;
+		} 
+
+	},
+	_onFocus: function(/*Event*/ e){
+		// summary:
+		//		Called from focus manager when focus has moved into this editor
+		// tags:
+		//		protected
+
+		// 
+		if(!this.disabled){
+			if(!this._disabledOK){
+				this.attr('disabled', false);
+			}
+			this.inherited(arguments);
+		}
+	},
+
+	// TODO: why is this needed - should we deprecate this ?
+	blur: function(){
+		// summary:
+		//		Remove focus from this instance.
+		// tags:
+		//		deprecated
+		if(!dojo.isIE && this.window.document.documentElement && this.window.document.documentElement.focus){
+			this.window.document.documentElement.focus();
+		}else if(dojo.doc.body.focus){
+			dojo.doc.body.focus();
+		}
+	},
+
+	focus: function(){
+		// summary:
+		//		Move focus to this editor
+		if(!dojo.isIE){
+			dijit.focus(this.iframe);
+		}else if(this.editNode && this.editNode.focus){
+			// editNode may be hidden in display:none div, lets just punt in this case
+			//this.editNode.focus(); -> causes IE to scroll always (strict and quirks mode) to the top the Iframe 
+			// if we fire the event manually and let the browser handle the focusing, the latest  
+			// cursor position is focused like in FF                         
+			this.iframe.fireEvent('onfocus', document.createEventObject()); // createEventObject only in IE 
+		//	}else{
+		// 	// TODO: should we throw here?
+		//	
+		}
+	},
+
+	// _lastUpdate: 0,
+	updateInterval: 200,
+	_updateTimer: null,
+	onDisplayChanged: function(/*Event*/ e){
+		// summary:
+		//		This event will be fired everytime the display context
+		//		changes and the result needs to be reflected in the UI.
+		// description:
+		//		If you don't want to have update too often,
+		//		onNormalizedDisplayChanged should be used instead
+		// tags:
+		//		private
+
+		// var _t=new Date();
+		if(this._updateTimer){
+			clearTimeout(this._updateTimer);
+		}
+		if(!this._updateHandler){
+			this._updateHandler = dojo.hitch(this,"onNormalizedDisplayChanged");
+		}
+		this._updateTimer = setTimeout(this._updateHandler, this.updateInterval);
+	},
+	onNormalizedDisplayChanged: function(){
+		// summary:
+		//		This event is fired every updateInterval ms or more
+		// description:
+		//		If something needs to happen immediately after a
+		//		user change, please use onDisplayChanged instead.
+		// tags:
+		//		private
+		delete this._updateTimer;
+	},
+	onChange: function(newContent){
+		// summary:
+		//		This is fired if and only if the editor loses focus and
+		//		the content is changed.
+	},
+	_normalizeCommand: function(/*String*/ cmd){
+		// summary:
+		//		Used as the advice function by dojo.connect to map our
+		//		normalized set of commands to those supported by the target
+		//		browser.
+		// tags:
+		//		private
+
+		var command = cmd.toLowerCase();
+		if(command == "formatblock"){
+			if(dojo.isSafari){ command = "heading"; }
+		}else if(command == "hilitecolor" && !dojo.isMoz){
+			command = "backcolor";
+		}
+
+		return command;
+	},
+
+	_qcaCache: {},
+	queryCommandAvailable: function(/*String*/ command){
+		// summary:
+		//		Tests whether a command is supported by the host. Clients
+		//		SHOULD check whether a command is supported before attempting
+		//		to use it, behaviour for unsupported commands is undefined.
+		// command:
+		//		The command to test for
+		// tags:
+		//		private
+
+		// memoizing version. See _queryCommandAvailable for computing version
+		var ca = this._qcaCache[command];
+		if(ca != undefined){ return ca; }
+		return (this._qcaCache[command] = this._queryCommandAvailable(command));
+	},
+	
+	_queryCommandAvailable: function(/*String*/ command){
+		// summary:
+		//		See queryCommandAvailable().
+		// tags:
+		//		private
+
+		var ie = 1;
+		var mozilla = 1 << 1;
+		var webkit = 1 << 2;
+		var opera = 1 << 3;
+		var webkit420 = 1 << 4;
+
+		var gt420 = dojo.isWebKit;
+
+		function isSupportedBy(browsers){
+			return {
+				ie: Boolean(browsers & ie),
+				mozilla: Boolean(browsers & mozilla),
+				webkit: Boolean(browsers & webkit),
+				webkit420: Boolean(browsers & webkit420),
+				opera: Boolean(browsers & opera)
+			}
+		}
+
+		var supportedBy = null;
+
+		switch(command.toLowerCase()){
+			case "bold": case "italic": case "underline":
+			case "subscript": case "superscript":
+			case "fontname": case "fontsize":
+			case "forecolor": case "hilitecolor":
+			case "justifycenter": case "justifyfull": case "justifyleft":
+			case "justifyright": case "delete": case "selectall": case "toggledir":
+				supportedBy = isSupportedBy(mozilla | ie | webkit | opera);
+				break;
+
+			case "createlink": case "unlink": case "removeformat":
+			case "inserthorizontalrule": case "insertimage":
+			case "insertorderedlist": case "insertunorderedlist":
+			case "indent": case "outdent": case "formatblock":
+			case "inserthtml": case "undo": case "redo": case "strikethrough": case "tabindent":
+				supportedBy = isSupportedBy(mozilla | ie | opera | webkit420);
+				break;
+
+			case "blockdirltr": case "blockdirrtl":
+			case "dirltr": case "dirrtl":
+			case "inlinedirltr": case "inlinedirrtl":
+				supportedBy = isSupportedBy(ie);
+				break;
+			case "cut": case "copy": case "paste":
+				supportedBy = isSupportedBy( ie | mozilla | webkit420);
+				break;
+
+			case "inserttable":
+				supportedBy = isSupportedBy(mozilla | ie);
+				break;
+
+			case "insertcell": case "insertcol": case "insertrow":
+			case "deletecells": case "deletecols": case "deleterows":
+			case "mergecells": case "splitcell":
+				supportedBy = isSupportedBy(ie | mozilla);
+				break;
+
+			default: return false;
+		}
+
+		return (dojo.isIE && supportedBy.ie) ||
+			(dojo.isMoz && supportedBy.mozilla) ||
+			(dojo.isWebKit && supportedBy.webkit) ||
+			(dojo.isWebKit > 420 && supportedBy.webkit420) ||
+			(dojo.isOpera && supportedBy.opera);  // Boolean return true if the command is supported, false otherwise
+	},
+
+	execCommand: function(/*String*/ command, argument){
+		// summary:
+		//		Executes a command in the Rich Text area
+		// command:
+		//		The command to execute
+		// argument:
+		//		An optional argument to the command
+		// tags:
+		//		protected
+
+		var returnValue;
+
+		//focus() is required for IE to work
+		//In addition, focus() makes sure after the execution of
+		//the command, the editor receives the focus as expected
+		this.focus();
+
+		command = this._normalizeCommand(command);
+
+		if(argument != undefined){
+			if(command == "heading"){
+				throw new Error("unimplemented");
+			}else if((command == "formatblock") && dojo.isIE){
+				argument = '<'+argument+'>';
+			}
+		}
+		if(command == "inserthtml"){
+			//TODO: we shall probably call _preDomFilterContent here as well
+			argument = this._preFilterContent(argument);
+			returnValue = true;
+			if(dojo.isIE){
+				var insertRange = this.document.selection.createRange();
+				if(this.document.selection.type.toUpperCase()=='CONTROL'){
+					var n=insertRange.item(0);
+					while(insertRange.length){
+						insertRange.remove(insertRange.item(0));
+					}
+					n.outerHTML=argument;
+				}else{
+					insertRange.pasteHTML(argument);
+				}
+				insertRange.select();
+				//insertRange.collapse(true);
+			}else if(dojo.isMoz && !argument.length){
+				//mozilla can not inserthtml an empty html to delete current selection
+				//so we delete the selection instead in this case
+				this._sCall("remove"); // FIXME
+			}else{
+				returnValue = this.document.execCommand(command, false, argument);
+			}
+		}else if(
+			(command == "unlink")&&
+			(this.queryCommandEnabled("unlink"))&&
+			(dojo.isMoz || dojo.isWebKit)
+		){
+			// fix up unlink in Mozilla to unlink the link and not just the selection
+
+			// grab selection
+			// Mozilla gets upset if we just store the range so we have to
+			// get the basic properties and recreate to save the selection
+			//	var selection = this.window.getSelection();
+
+			//	var selectionRange = selection.getRangeAt(0);
+			//	var selectionStartContainer = selectionRange.startContainer;
+			//	var selectionStartOffset = selectionRange.startOffset;
+			//	var selectionEndContainer = selectionRange.endContainer;
+			//	var selectionEndOffset = selectionRange.endOffset;
+
+			// select our link and unlink
+			var a = this._sCall("getAncestorElement", [ "a" ]);
+			this._sCall("selectElement", [ a ]);
+
+			returnValue = this.document.execCommand("unlink", false, null);
+		}else if((command == "hilitecolor")&&(dojo.isMoz)){
+			// mozilla doesn't support hilitecolor properly when useCSS is
+			// set to false (bugzilla #279330)
+
+			this.document.execCommand("styleWithCSS", false, true);
+			returnValue = this.document.execCommand(command, false, argument);
+			this.document.execCommand("styleWithCSS", false, false);
+
+		}else if((dojo.isIE)&&( (command == "backcolor")||(command == "forecolor") )){
+			// Tested under IE 6 XP2, no problem here, comment out
+			// IE weirdly collapses ranges when we exec these commands, so prevent it
+			//	var tr = this.document.selection.createRange();
+			argument = arguments.length > 1 ? argument : null;
+			returnValue = this.document.execCommand(command, false, argument);
+
+			// timeout is workaround for weird IE behavior were the text
+			// selection gets correctly re-created, but subsequent input
+			// apparently isn't bound to it
+			//	setTimeout(function(){tr.select();}, 1);
+		}else{
+			argument = arguments.length > 1 ? argument : null;
+			//	if(dojo.isMoz){
+			//		this.document = this.iframe.contentWindow.document
+			//	}
+
+//			
+			if(argument || command!="createlink"){
+				returnValue = this.document.execCommand(command, false, argument);
+			}
+		}
+
+		this.onDisplayChanged();
+		return returnValue;
+	},
+
+	queryCommandEnabled: function(/*String*/ command){
+		// summary:
+		//		Check whether a command is enabled or not.
+		// tags:
+		//		protected
+		if(this.disabled || !this._disabledOK){ return false; }
+		command = this._normalizeCommand(command);
+		if(dojo.isMoz || dojo.isWebKit){
+			if(command == "unlink"){ // mozilla returns true always
+				// 
+				this._sCall("hasAncestorElement", ["a"]);
+			}else if(command == "inserttable"){
+				return true;
+			}
+		}
+		//see #4109
+		if(dojo.isWebKit){
+			if(command == "copy"){
+				command = "cut";
+			}else if(command == "paste"){
+				return true;
+			}
+		}
+		// return this.document.queryCommandEnabled(command);
+		var elem = dojo.isIE ? this.document.selection.createRange() : this.document;
+		return elem.queryCommandEnabled(command);
+	},
+
+	queryCommandState: function(command){
+		// summary:
+		//		Check the state of a given command and returns true or false.
+		// tags:
+		//		protected
+
+		if(this.disabled || !this._disabledOK){ return false; }
+		command = this._normalizeCommand(command);
+		// try{
+			//this.editNode.contentEditable = true;
+			return this.document.queryCommandState(command);
+		// }catch(e){
+		// 	
+		// 	return false;
+		// }
+	},
+
+	queryCommandValue: function(command){
+		// summary:
+		//		Check the value of a given command. This matters most for
+		//		custom selections and complex values like font value setting.
+		// tags:
+		//		protected
+
+		if(this.disabled || !this._disabledOK){ return false; }
+		var r;
+		command = this._normalizeCommand(command);
+		if(dojo.isIE && command == "formatblock"){
+			r = this._native2LocalFormatNames[this.document.queryCommandValue(command)];
+		}else{
+			r = this.document.queryCommandValue(command);
+		}
+		return r;
+	},
+
+	// Misc.
+
+	_sCall: function(name, args){
+		// summary:
+		//		Run the named method of dijit._editor.selection over the
+		//		current editor instance's window, with the passed args.
+		// tags:
+		//		private
+		return dojo.withGlobal(this.window, name, dijit._editor.selection, args);
+	},
+
+	// FIXME: this is a TON of code duplication. Why?
+
+	placeCursorAtStart: function(){
+		// summary:
+		//		Place the cursor at the start of the editing area.
+		// tags:
+		//		private
+
+		this.focus();
+
+		//see comments in placeCursorAtEnd
+		var isvalid=false;
+		if(dojo.isMoz){
+			var first=this.editNode.firstChild;
+			while(first){
+				if(first.nodeType == 3){
+					if(first.nodeValue.replace(/^\s+|\s+$/g, "").length>0){
+						isvalid=true;
+						this._sCall("selectElement", [ first ]);
+						break;
+					}
+				}else if(first.nodeType == 1){
+					isvalid=true;
+					this._sCall("selectElementChildren", [ first ]);
+					break;
+				}
+				first = first.nextSibling;
+			}
+		}else{
+			isvalid=true;
+			this._sCall("selectElementChildren", [ this.editNode ]);
+		}
+		if(isvalid){
+			this._sCall("collapse", [ true ]);
+		}
+	},
+
+	placeCursorAtEnd: function(){
+		// summary:
+		//		Place the cursor at the end of the editing area.
+		// tags:
+		//		private
+
+		this.focus();
+
+		//In mozilla, if last child is not a text node, we have to use
+		// selectElementChildren on this.editNode.lastChild otherwise the
+		// cursor would be placed at the end of the closing tag of
+		//this.editNode.lastChild
+		var isvalid=false;
+		if(dojo.isMoz){
+			var last=this.editNode.lastChild;
+			while(last){
+				if(last.nodeType == 3){
+					if(last.nodeValue.replace(/^\s+|\s+$/g, "").length>0){
+						isvalid=true;
+						this._sCall("selectElement", [ last ]);
+						break;
+					}
+				}else if(last.nodeType == 1){
+					isvalid=true;
+					if(last.lastChild){
+						this._sCall("selectElement", [ last.lastChild ]);
+					}else{
+						this._sCall("selectElement", [ last ]);
+					}
+					break;
+				}
+				last = last.previousSibling;
+			}
+		}else{
+			isvalid=true;
+			this._sCall("selectElementChildren", [ this.editNode ]);
+		}
+		if(isvalid){
+			this._sCall("collapse", [ false ]);
+		}
+	},
+
+	getValue: function(/*Boolean?*/ nonDestructive){
+		// summary:
+		//		Return the current content of the editing area (post filters
+		//		are applied).  Users should call attr('value') instead.
+		//	nonDestructive:
+		//		defaults to false. Should the post-filtering be run over a copy
+		//		of the live DOM? Most users should pass "true" here unless they
+		//		*really* know that none of the installed filters are going to
+		//		mess up the editing session.
+		// tags:
+		//		private
+		if(this.textarea){
+			if(this.isClosed || !this.isLoaded){
+				return this.textarea.value;
+			}
+		}
+
+		return this._postFilterContent(null, nonDestructive);
+	},
+	_getValueAttr: function(){
+		// summary:
+		//		Hook to make attr("value") work
+		return this.getValue();
+	},
+
+	setValue: function(/*String*/ html){
+		// summary:
+		//		This function sets the content. No undo history is preserved.
+		//		Users should use attr('value', ...) instead.
+		// tags:
+		//		deprecated
+
+		// TODO: remove this and getValue() for 2.0, and move code to _setValueAttr()
+
+		if(!this.isLoaded){ 
+			// try again after the editor is finished loading 
+			this.onLoadDeferred.addCallback(dojo.hitch(this, function(){ 
+				this.setValue(html); 
+			})); 
+			return;
+		} 
+		if(this.textarea && (this.isClosed || !this.isLoaded)){
+			this.textarea.value=html;
+		}else{
+			html = this._preFilterContent(html);
+			var node = this.isClosed ? this.domNode : this.editNode;
+			node.innerHTML = html;
+			this._preDomFilterContent(node);
+		}
+		this.onDisplayChanged();
+	},
+
+	replaceValue: function(/*String*/ html){
+		// summary:
+		//		This function set the content while trying to maintain the undo stack
+		//		(now only works fine with Moz, this is identical to setValue in all
+		//		other browsers)
+		// tags:
+		//		protected
+
+		if(this.isClosed){
+			this.setValue(html);
+		}else if(this.window && this.window.getSelection && !dojo.isMoz){ // Safari
+			// look ma! it's a totally f'd browser!
+			this.setValue(html);
+		}else if(this.window && this.window.getSelection){ // Moz
+			html = this._preFilterContent(html);
+			this.execCommand("selectall");
+			if(dojo.isMoz && !html){ html = " " }
+			this.execCommand("inserthtml", html);
+			this._preDomFilterContent(this.editNode);
+		}else if(this.document && this.document.selection){//IE
+			//In IE, when the first element is not a text node, say
+			//an <a> tag, when replacing the content of the editing
+			//area, the <a> tag will be around all the content
+			//so for now, use setValue for IE too
+			this.setValue(html);
+		}
+	},
+
+	_preFilterContent: function(/*String*/ html){
+		// summary:
+		//		Filter the input before setting the content of the editing
+		//		area. DOM pre-filtering may happen after this
+		//		string-based filtering takes place but as of 1.2, this is not
+		//		guaranteed for operations such as the inserthtml command.
+		// tags:
+		//		private
+
+		var ec = html;
+		dojo.forEach(this.contentPreFilters, function(ef){ if(ef){ ec = ef(ec); } });
+		return ec;
+	},
+	_preDomFilterContent: function(/*DomNode*/ dom){
+		// summary:
+		//		filter the input's live DOM. All filter operations should be
+		//		considered to be "live" and operating on the DOM that the user
+		//		will be interacting with in their editing session.
+		// tags:
+		//		private
+		dom = dom || this.editNode;
+		dojo.forEach(this.contentDomPreFilters, function(ef){
+			if(ef && dojo.isFunction(ef)){
+				ef(dom);
+			}
+		}, this);
+	},
+
+	_postFilterContent: function(
+		/*DomNode|DomNode[]|String?*/ dom,
+		/*Boolean?*/ nonDestructive){
+		// summary:
+		//		filter the output after getting the content of the editing area
+		//
+		//	description:
+		//		post-filtering allows plug-ins and users to specify any number
+		//		of transforms over the editor's content, enabling many common
+		//		use-cases such as transforming absolute to relative URLs (and
+		//		vice-versa), ensuring conformance with a particular DTD, etc.
+		//		The filters are registered in the contentDomPostFilters and
+		//		contentPostFilters arrays. Each item in the
+		//		contentDomPostFilters array is a function which takes a DOM
+		//		Node or array of nodes as its only argument and returns the
+		//		same. It is then passed down the chain for further filtering.
+		//		The contentPostFilters array behaves the same way, except each
+		//		member operates on strings. Together, the DOM and string-based
+		//		filtering allow the full range of post-processing that should
+		//		be necessaray to enable even the most agressive of post-editing
+		//		conversions to take place.
+		//
+		//		If nonDestructive is set to "true", the nodes are cloned before
+		//		filtering proceeds to avoid potentially destructive transforms
+		//		to the content which may still needed to be edited further.
+		//		Once DOM filtering has taken place, the serialized version of
+		//		the DOM which is passed is run through each of the
+		//		contentPostFilters functions.
+		//
+		//	dom:
+		//		a node, set of nodes, which to filter using each of the current
+		//		members of the contentDomPostFilters and contentPostFilters arrays. 
+		//
+		//	nonDestructive:
+		//		defaults to "false". If true, ensures that filtering happens on
+		//		a clone of the passed-in content and not the actual node
+		//		itself.
+		//
+		// tags:
+		//		private
+
+		var ec;
+		if(!dojo.isString(dom)){
+			dom = dom || this.editNode;
+			if(this.contentDomPostFilters.length){
+				if(nonDestructive){
+					dom = dojo.clone(dom);
+				}
+				dojo.forEach(this.contentDomPostFilters, function(ef){
+					dom = ef(dom);
+				});
+			}
+			ec = dijit._editor.getChildrenHtml(dom);
+		}else{
+			ec = dom;
+		}
+
+		if(!dojo.trim(ec.replace(/^\xA0\xA0*/, '').replace(/\xA0\xA0*$/, '')).length){
+			ec = "";
+		}
+
+		//	if(dojo.isIE){
+		//		//removing appended <P> </P> for IE
+		//		ec = ec.replace(/(?:<p> </p>[\n\r]*)+$/i,"");
+		//	}
+		dojo.forEach(this.contentPostFilters, function(ef){
+			ec = ef(ec);
+		});
+
+		return ec;
+	},
+
+	_saveContent: function(/*Event*/ e){
+		// summary:
+		//		Saves the content in an onunload event if the editor has not been closed
+		// tags:
+		//		private
+
+		var saveTextarea = dojo.byId(dijit._scopeName + "._editor.RichText.savedContent");
+		saveTextarea.value += this._SEPARATOR + this.name + ":" + this.getValue();
+	},
+
+
+	escapeXml: function(/*String*/ str, /*Boolean*/ noSingleQuotes){
+		// summary:
+		//		Adds escape sequences for special characters in XML: &<>"'
+		//		Optionally skips escapes for single quotes
+		// tags:
+		//		private
+
+		str = str.replace(/&/gm, "&").replace(/</gm, "<").replace(/>/gm, ">").replace(/"/gm, """);
+		if(!noSingleQuotes){
+			str = str.replace(/'/gm, "'");
+		}
+		return str; // string
+	},
+
+	getNodeHtml: function(/* DomNode */ node){
+		// summary:
+		//		Deprecated.   Use dijit._editor._getNodeHtml() instead.
+		// tags:
+		//		deprecated
+		dojo.deprecated('dijit.Editor::getNodeHtml is deprecated','use dijit._editor.getNodeHtml instead', 2);
+		return dijit._editor.getNodeHtml(node); // String
+	},
+
+	getNodeChildrenHtml: function(/* DomNode */ dom){
+		// summary:
+		//		Deprecated.   Use dijit._editor.getChildrenHtml() instead.
+		// tags:
+		//		deprecated
+		dojo.deprecated('dijit.Editor::getNodeChildrenHtml is deprecated','use dijit._editor.getChildrenHtml instead', 2);
+		return dijit._editor.getChildrenHtml(dom);
+	},
+
+	close: function(/*Boolean*/ save, /*Boolean*/ force){
+		// summary:
+		//		Kills the editor and optionally writes back the modified contents to the
+		//		element from which it originated.
+		// save:
+		//		Whether or not to save the changes. If false, the changes are discarded.
+		// force: Boolean
+		//		Unused.  TODO: remove for 2.0
+		// tags:
+		//		private
+
+		if(this.isClosed){return false; }
+
+		if(!arguments.length){ save = true; }
+		this._content = this.getValue();
+		var changed = (this.savedContent != this._content);
+
+		// line height is squashed for iframes
+		// FIXME: why was this here? if (this.iframe){ this.domNode.style.lineHeight = null; }
+
+		if(this.interval){ clearInterval(this.interval); }
+
+		if(this._webkitListener){
+			//Cleaup of WebKit fix: #9532
+			this.disconnect(this._webkitListener);
+			delete this._webkitListener;
+		}
+
+		// Guard against memory leaks on IE (see #9268)
+		if(dojo.isIE){
+		   this.iframe.onfocus = null;
+		}
+		this.iframe._loadFunc = null;
+
+		if(this.textarea){
+			var s = this.textarea.style;
+			s.position = "";
+			s.left = s.top = "";
+			if(dojo.isIE){
+				s.overflow = this.__overflow;
+				this.__overflow = null;
+			}
+			this.textarea.value = save ? this._content : this.savedContent;
+			dojo.destroy(this.domNode);
+			this.domNode = this.textarea;
+		}else{
+			// if(save){
+			// why we treat moz differently? comment out to fix #1061
+			//		if(dojo.isMoz){
+			//			var nc = dojo.doc.createElement("span");
+			//			this.domNode.appendChild(nc);
+			//			nc.innerHTML = this.editNode.innerHTML;
+			//		}else{
+			//			this.domNode.innerHTML = this._content;
+			//		}
+			// }
+			this.domNode.innerHTML = save ? this._content : this.savedContent;
+		}
+
+		dojo.removeClass(this.domNode, "RichTextEditable");
+		this.isClosed = true;
+		this.isLoaded = false;
+		// FIXME: is this always the right thing to do?
+		delete this.editNode;
+
+		if(this.window && this.window._frameElement){
+			this.window._frameElement = null;
+		}
+
+		this.window = null;
+		this.document = null;
+		this.editingArea = null;
+		this.editorObject = null;
+
+		return changed; // Boolean: whether the content has been modified
+	},
+
+	destroyRendering: function(){
+		// summary: stub	
+	}, 
+
+	destroy: function(){
+		this.destroyRendering();
+		if(!this.isClosed){ this.close(false); }
+		this.inherited(arguments);
+	},
+
+	_removeMozBogus: function(/* String */ html){
+		// summary:
+		//		Post filter to remove unwanted HTML attributes generated by mozilla
+		// tags:
+		//		private
+		return html.replace(/\stype="_moz"/gi, '').replace(/\s_moz_dirty=""/gi, ''); // String
+	},
+	_removeSafariBogus: function(/* String */ html){
+		// summary:
+		//		Post filter to remove unwanted HTML attributes generated by webkit
+		// tags:
+		//		private
+		return html.replace(/\sclass="webkit-block-placeholder"/gi, ''); // String
+	},
+	_fixContentForMoz: function(/* String */ html){
+		// summary:
+		//		Pre-filter for mozilla.
+		// description:
+		//		Moz can not handle strong/em tags correctly, convert them to b/i
+		// tags:
+		//		private
+		return html.replace(/<(\/)?strong([ \>])/gi, '<$1b$2')
+			.replace(/<(\/)?em([ \>])/gi, '<$1i$2' ); // String
+	},
+
+	_preFixUrlAttributes: function(/* String */ html){
+		// summary:
+		//		Pre-filter to do fixing to href attributes on <a> and <img> tags
+		// tags:
+		//		private
+		return html.replace(/(?:(<a(?=\s).*?\shref=)("|')(.*?)\2)|(?:(<a\s.*?href=)([^"'][^ >]+))/gi, 
+				'$1$4$2$3$5$2 _djrealurl=$2$3$5$2')
+			.replace(/(?:(<img(?=\s).*?\ssrc=)("|')(.*?)\2)|(?:(<img\s.*?src=)([^"'][^ >]+))/gi, 
+				'$1$4$2$3$5$2 _djrealurl=$2$3$5$2'); // String
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit._KeyNavContainer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._KeyNavContainer"] = true;
+dojo.provide("dijit._KeyNavContainer");
+
+
+dojo.declare("dijit._KeyNavContainer",
+	[dijit._Container],
+	{
+
+		// summary:
+		//		A _Container with keyboard navigation of its children.
+		// description:
+		//		To use this mixin, call connectKeyNavHandlers() in
+		//		postCreate() and call startupKeyNavChildren() in startup().
+		//		It provides normalized keyboard and focusing code for Container
+		//		widgets.
+/*=====
+		// focusedChild: [protected] Widget
+		//		The currently focused child widget, or null if there isn't one
+		focusedChild: null,
+=====*/
+
+		// tabIndex: Integer
+		//		Tab index of the container; same as HTML tabindex attribute.
+		//		Note then when user tabs into the container, focus is immediately
+		//		moved to the first item in the container.
+		tabIndex: "0",
+
+
+		_keyNavCodes: {},
+
+		connectKeyNavHandlers: function(/*dojo.keys[]*/ prevKeyCodes, /*dojo.keys[]*/ nextKeyCodes){
+			// summary:
+			//		Call in postCreate() to attach the keyboard handlers
+			//		to the container.
+			// preKeyCodes: dojo.keys[]
+			//		Key codes for navigating to the previous child.
+			// nextKeyCodes: dojo.keys[]
+			//		Key codes for navigating to the next child.
+			// tags:
+			//		protected
+
+			var keyCodes = this._keyNavCodes = {};
+			var prev = dojo.hitch(this, this.focusPrev);
+			var next = dojo.hitch(this, this.focusNext);
+			dojo.forEach(prevKeyCodes, function(code){ keyCodes[code] = prev; });
+			dojo.forEach(nextKeyCodes, function(code){ keyCodes[code] = next; });
+			this.connect(this.domNode, "onkeypress", "_onContainerKeypress");
+			this.connect(this.domNode, "onfocus", "_onContainerFocus");
+		},
+
+		startupKeyNavChildren: function(){
+			// summary:
+			//		Call in startup() to set child tabindexes to -1
+			// tags:
+			//		protected
+			dojo.forEach(this.getChildren(), dojo.hitch(this, "_startupChild"));
+		},
+
+		addChild: function(/*Widget*/ widget, /*int?*/ insertIndex){
+			// summary:
+			//		Add a child to our _Container
+			dijit._KeyNavContainer.superclass.addChild.apply(this, arguments);
+			this._startupChild(widget);
+		},
+
+		focus: function(){
+			// summary:
+			//		Default focus() implementation: focus the first child.
+			this.focusFirstChild();
+		},
+
+		focusFirstChild: function(){
+			// summary:
+			//		Focus the first focusable child in the container.
+			// tags:
+			//		protected
+			this.focusChild(this._getFirstFocusableChild());
+		},
+
+		focusNext: function(){
+			// summary:
+			//		Focus the next widget or focal node (for widgets
+			//		with multiple focal nodes) within this container.
+			// tags:
+			//		protected
+			if(this.focusedChild && this.focusedChild.hasNextFocalNode
+					&& this.focusedChild.hasNextFocalNode()){
+				this.focusedChild.focusNext();
+				return;
+			}
+			var child = this._getNextFocusableChild(this.focusedChild, 1);
+			if(child.getFocalNodes){
+				this.focusChild(child, child.getFocalNodes()[0]);
+			}else{
+				this.focusChild(child);
+			}
+		},
+
+		focusPrev: function(){
+			// summary:
+			//		Focus the previous widget or focal node (for widgets
+			//		with multiple focal nodes) within this container.
+			// tags:
+			//		protected
+			if(this.focusedChild && this.focusedChild.hasPrevFocalNode
+					&& this.focusedChild.hasPrevFocalNode()){
+				this.focusedChild.focusPrev();
+				return;
+			}
+			var child = this._getNextFocusableChild(this.focusedChild, -1);
+			if(child.getFocalNodes){
+				var nodes = child.getFocalNodes();
+				this.focusChild(child, nodes[nodes.length-1]);
+			}else{
+				this.focusChild(child);
+			}
+		},
+
+		focusChild: function(/*Widget*/ widget, /*Node?*/ node){
+			// summary:
+			//		Focus widget. Optionally focus 'node' within widget.
+			// tags:
+			//		protected
+			if(widget){
+				if(this.focusedChild && widget !== this.focusedChild){
+					this._onChildBlur(this.focusedChild);
+				}
+				this.focusedChild = widget;
+				if(node && widget.focusFocalNode){
+					widget.focusFocalNode(node);
+				}else{
+					widget.focus();
+				}
+			}
+		},
+
+		_startupChild: function(/*Widget*/ widget){
+			// summary:
+			//		Set tabindex="-1" on focusable widgets so that we
+			// 		can focus them programmatically and by clicking.
+			//		Connect focus and blur handlers.
+			// tags:
+			//		private
+			if(widget.getFocalNodes){
+				dojo.forEach(widget.getFocalNodes(), function(node){
+					dojo.attr(node, "tabindex", -1);
+					this._connectNode(node);
+				}, this);
+			}else{
+				var node = widget.focusNode || widget.domNode;
+				if(widget.isFocusable()){
+					dojo.attr(node, "tabindex", -1);
+				}
+				this._connectNode(node);
+			}
+		},
+
+		_connectNode: function(/*Element*/ node){
+			// summary:
+			//		Monitor focus and blur events on the node
+			// tags:
+			//		private
+			this.connect(node, "onfocus", "_onNodeFocus");
+			this.connect(node, "onblur", "_onNodeBlur");
+		},
+
+		_onContainerFocus: function(evt){
+			// summary:
+			//		Handler for when the container gets focus
+			// description:
+			//		Initially the container itself has a tabIndex, but when it gets
+			//		focus, switch focus to first child...
+			// tags:
+			//		private
+
+			// Note that we can't use _onFocus() because switching focus from the
+			// _onFocus() handler confuses the focus.js code
+			// (because it causes _onFocusNode() to be called recursively)
+
+			// focus bubbles on Firefox,
+			// so just make sure that focus has really gone to the container
+			if(evt.target !== this.domNode){ return; }
+
+			this.focusFirstChild();
+			
+			// and then remove the container's tabIndex,
+			// so that tab or shift-tab will go to the fields after/before
+			// the container, rather than the container itself
+			dojo.removeAttr(this.domNode, "tabIndex");
+		},
+
+		_onBlur: function(evt){
+			// When focus is moved away the container, and it's descendant (popup) widgets,
+			// then restore the container's tabIndex so that user can tab to it again.
+			// Note that using _onBlur() so that this doesn't happen when focus is shifted
+			// to one of my child widgets (typically a popup)
+			if(this.tabIndex){
+				dojo.attr(this.domNode, "tabindex", this.tabIndex);
+			}
+			// TODO: this.inherited(arguments);
+		},
+
+		_onContainerKeypress: function(evt){
+			// summary:
+			//		When a key is pressed, if it's an arrow key etc. then
+			//		it's handled here.
+			// tags:
+			//		private
+			if(evt.ctrlKey || evt.altKey){ return; }
+			var func = this._keyNavCodes[evt.charOrCode];
+			if(func){
+				func();
+				dojo.stopEvent(evt);
+			}
+		},
+
+		_onNodeFocus: function(evt){
+			// summary:
+			//		Handler for onfocus event on a child node
+			// tags:
+			//		private
+
+			// record the child that has been focused
+			var widget = dijit.getEnclosingWidget(evt.target);
+			if(widget && widget.isFocusable()){
+				this.focusedChild = widget;
+			}
+			dojo.stopEvent(evt);
+		},
+
+		_onNodeBlur: function(evt){
+			// summary:
+			//		Handler for onblur event on a child node
+			// tags:
+			//		private
+			dojo.stopEvent(evt);
+		},
+
+		_onChildBlur: function(/*Widget*/ widget){
+			// summary:
+			//		Called when focus leaves a child widget to go
+			//		to a sibling widget.
+			// tags:
+			//		protected
+		},
+
+		_getFirstFocusableChild: function(){
+			// summary:
+			//		Returns first child that can be focused
+			return this._getNextFocusableChild(null, 1);
+		},
+
+		_getNextFocusableChild: function(child, dir){
+			// summary:
+			//		Returns the next or previous focusable child, compared
+			//		to "child"
+			// child: Widget
+			//		The current widget
+			// dir: Integer
+			//		* 1 = after
+			//		* -1 = before
+			if(child){
+				child = this._getSiblingOfChild(child, dir);
+			}
+			var children = this.getChildren();
+			for(var i=0; i < children.length; i++){
+				if(!child){
+					child = children[(dir>0) ? 0 : (children.length-1)];
+				}
+				if(child.isFocusable()){
+					return child;
+				}
+				child = this._getSiblingOfChild(child, dir);
+			}
+			// no focusable child found
+			return null;
+		}
+	}
+);
+
+}
+
+if(!dojo._hasResource["dijit.ToolbarSeparator"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.ToolbarSeparator"] = true;
+dojo.provide("dijit.ToolbarSeparator");
+
+
+
+
+dojo.declare("dijit.ToolbarSeparator",
+		[ dijit._Widget, dijit._Templated ],
+		{
+		// summary:
+		//		A spacer between two `dijit.Toolbar` items
+		templateString: '<div class="dijitToolbarSeparator dijitInline"></div>',
+		postCreate: function(){ dojo.setSelectable(this.domNode, false); },
+		isFocusable: function(){ 
+			// summary:
+			//		This widget isn't focusable, so pass along that fact.
+			// tags:
+			//		protected
+			return false; 
+		}
+
+	});
+
+
+
+}
+
+if(!dojo._hasResource["dijit.Toolbar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.Toolbar"] = true;
+dojo.provide("dijit.Toolbar");
+
+
+
+
+
+dojo.declare("dijit.Toolbar",
+	[dijit._Widget, dijit._Templated, dijit._KeyNavContainer],
+	{
+	// summary:
+	//		A Toolbar widget, used to hold things like `dijit.Editor` buttons
+
+	templateString:
+		'<div class="dijit dijitToolbar" waiRole="toolbar" tabIndex="${tabIndex}" dojoAttachPoint="containerNode">' +
+		//	'<table style="table-layout: fixed" class="dijitReset dijitToolbarTable">' + // factor out style
+		//		'<tr class="dijitReset" dojoAttachPoint="containerNode"></tr>'+
+		//	'</table>' +
+		'</div>',
+
+	postCreate: function(){
+		this.connectKeyNavHandlers(
+			this.isLeftToRight() ? [dojo.keys.LEFT_ARROW] : [dojo.keys.RIGHT_ARROW],
+			this.isLeftToRight() ? [dojo.keys.RIGHT_ARROW] : [dojo.keys.LEFT_ARROW]
+		);
+	},
+
+	startup: function(){
+		if(this._started){ return; }
+
+		this.startupKeyNavChildren();
+
+		this.inherited(arguments);
+	}
+}
+);
+
+// For back-compat, remove for 2.0
+
+
+}
+
+if(!dojo._hasResource["dijit.form.Button"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.Button"] = true;
+dojo.provide("dijit.form.Button");
+
+
+
+
+dojo.declare("dijit.form.Button",
+	dijit.form._FormWidget,
+	{
+	// summary:
+	//		Basically the same thing as a normal HTML button, but with special styling.
+	// description:
+	//		Buttons can display a label, an icon, or both.
+	//		A label should always be specified (through innerHTML) or the label
+	//		attribute.  It can be hidden via showLabel=false.
+	// example:
+	// |	<button dojoType="dijit.form.Button" onClick="...">Hello world</button>
+	// 
+	// example:
+	// |	var button1 = new dijit.form.Button({label: "hello world", onClick: foo});
+	// |	dojo.body().appendChild(button1.domNode);
+
+	// label: HTML String
+	//		Text to display in button.
+	//		If the label is hidden (showLabel=false) then and no title has
+	//		been specified, then label is also set as title attribute of icon.
+	label: "",
+
+	// showLabel: Boolean
+	//		Set this to true to hide the label text and display only the icon.
+	//		(If showLabel=false then iconClass must be specified.)
+	//		Especially useful for toolbars.  
+	//		If showLabel=true, the label will become the title (a.k.a. tooltip/hint) of the icon.
+	//
+	//		The exception case is for computers in high-contrast mode, where the label
+	//		will still be displayed, since the icon doesn't appear.
+	showLabel: true,
+
+	// iconClass: String
+	//		Class to apply to div in button to make it display an icon
+	iconClass: "",
+
+	// type: String
+	//		Defines the type of button.  "button", "submit", or "reset".
+	type: "button",
+
+	baseClass: "dijitButton",
+
+	templateString:"<span class=\"dijit dijitReset dijitLeft dijitInline\"\n\tdojoAttachEvent=\"ondijitclick:_onButtonClick,onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\"\n\t><span class=\"dijitReset dijitRight dijitInline\"\n\t\t><span class=\"dijitReset dijitInline dijitButtonNode\"\n\t\t\t><button class=\"dijitReset dijitStretch dijitButtonContents\"\n\t\t\t\tdojoAttachPoint=\"titleNode,focusNode\" \n\t\t\t\t${nameAttrSetting} type=\"${type}\" value=\"${value}\" waiRo [...]
+
+	attributeMap: dojo.delegate(dijit.form._FormWidget.prototype.attributeMap, {
+		label: { node: "containerNode", type: "innerHTML" },
+		iconClass: { node: "iconNode", type: "class" }
+	}),
+		
+
+	_onClick: function(/*Event*/ e){
+		// summary:
+		//		Internal function to handle click actions
+		if(this.disabled || this.readOnly){
+			return false;
+		}
+		this._clicked(); // widget click actions
+		return this.onClick(e); // user click actions
+	},
+
+	_onButtonClick: function(/*Event*/ e){
+		// summary:
+		//		Handler when the user activates the button portion.
+		//		If is activated via a keystroke, stop the event unless is submit or reset.
+		if(e.type!='click' && !(this.type=="submit" || this.type=="reset")){
+			dojo.stopEvent(e);
+		}
+		if(this._onClick(e) === false){ // returning nothing is same as true
+			e.preventDefault(); // needed for checkbox
+		}else if(this.type=="submit" && !this.focusNode.form){ // see if a nonform widget needs to be signalled
+			for(var node=this.domNode; node.parentNode/*#5935*/; node=node.parentNode){
+				var widget=dijit.byNode(node);
+				if(widget && typeof widget._onSubmit == "function"){
+					widget._onSubmit(e);
+					break;
+				}
+			}
+		}
+	},
+
+	_setValueAttr: function(/*String*/ value){
+		// Verify that value cannot be set for BUTTON elements.
+		var attr = this.attributeMap.value || '';
+		if(this[attr.node||attr||'domNode'].tagName == 'BUTTON'){
+			// On IE, setting value actually overrides innerHTML, so disallow for everyone for consistency
+			if(value != this.value){
+				
+			}
+		}
+	},
+
+	_fillContent: function(/*DomNode*/ source){
+		// Overrides _Templated._fillcContent().
+		// If button label is specified as srcNodeRef.innerHTML rather than
+		// this.params.label, handle it here.
+		if(source && !("label" in this.params)){
+			this.attr('label', source.innerHTML);
+		}
+	},
+
+	postCreate: function(){
+		if (this.showLabel == false){
+			dojo.addClass(this.containerNode,"dijitDisplayNone");
+		}
+		dojo.setSelectable(this.focusNode, false);
+		this.inherited(arguments);
+	},
+
+	onClick: function(/*Event*/ e){
+		// summary:
+		//		Callback for when button is clicked.
+		//		If type="submit", return true to perform submit, or false to cancel it.
+		// type:
+		//		callback
+		return true;		// Boolean
+	},
+
+	_clicked: function(/*Event*/ e){
+		// summary:
+		//		Internal overridable function for when the button is clicked
+	},
+
+	setLabel: function(/*String*/ content){
+		// summary:
+		//		Deprecated.  Use attr('label', ...) instead.
+		dojo.deprecated("dijit.form.Button.setLabel() is deprecated.  Use attr('label', ...) instead.", "", "2.0");
+		this.attr("label", content);
+	},
+	_setLabelAttr: function(/*String*/ content){
+		// summary:
+		//		Hook for attr('label', ...) to work.
+		// description:
+		//		Set the label (text) of the button; takes an HTML string.
+		this.containerNode.innerHTML = this.label = content;
+		this._layoutHack();
+		if (this.showLabel == false && !this.params.title){
+			this.titleNode.title = dojo.trim(this.containerNode.innerText || this.containerNode.textContent || '');
+		}
+	}		
+});
+
+
+dojo.declare("dijit.form.DropDownButton", [dijit.form.Button, dijit._Container], {
+	// summary:
+	//		A button with a drop down
+	//
+	// example:
+	// |	<button dojoType="dijit.form.DropDownButton" label="Hello world">
+	// |		<div dojotype="dijit.Menu">...</div>
+	// |	</button>
+	//
+	// example:
+	// |	var button1 = new dijit.form.DropDownButton({ label: "hi", dropDown: new dijit.Menu(...) });
+	// |	dojo.body().appendChild(button1);
+	// 	
+	
+	baseClass : "dijitDropDownButton",
+
+	templateString:"<span class=\"dijit dijitReset dijitLeft dijitInline\"\n\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse,onclick:_onDropDownClick,onkeydown:_onDropDownKeydown,onblur:_onDropDownBlur,onkeypress:_onKey\"\n\t><span class='dijitReset dijitRight dijitInline'\n\t\t><span class='dijitReset dijitInline dijitButtonNode'\n\t\t\t><button class=\"dijitReset dijitStretch dijitButtonContents\" \n\t\t\t\t${nameAttrSetting} type=\"${type}\" value=\"${ [...]
+
+	_fillContent: function(){
+		// Overrides Button._fillContent().
+		//
+		// My inner HTML contains both the button contents and a drop down widget, like
+		// <DropDownButton>  <span>push me</span>  <Menu> ... </Menu> </DropDownButton>
+		// The first node is assumed to be the button content. The widget is the popup.
+
+		if(this.srcNodeRef){ // programatically created buttons might not define srcNodeRef
+			//FIXME: figure out how to filter out the widget and use all remaining nodes as button
+			//	content, not just nodes[0]
+			var nodes = dojo.query("*", this.srcNodeRef);
+			dijit.form.DropDownButton.superclass._fillContent.call(this, nodes[0]);
+
+			// save pointer to srcNode so we can grab the drop down widget after it's instantiated
+			this.dropDownContainer = this.srcNodeRef;
+		}
+	},
+
+	startup: function(){
+		if(this._started){ return; }
+
+		// the child widget from srcNodeRef is the dropdown widget.  Insert it in the page DOM,
+		// make it invisible, and store a reference to pass to the popup code.
+		if(!this.dropDown){
+			var dropDownNode = dojo.query("[widgetId]", this.dropDownContainer)[0];
+			this.dropDown = dijit.byNode(dropDownNode);
+			delete this.dropDownContainer;
+		}
+		dijit.popup.prepare(this.dropDown.domNode);
+
+		this.inherited(arguments);
+	},
+
+	destroyDescendants: function(){
+		if(this.dropDown){
+			this.dropDown.destroyRecursive();
+			delete this.dropDown;
+		}
+		this.inherited(arguments);
+	},
+
+	_onArrowClick: function(/*Event*/ e){
+		// summary:
+		//		Handler for when the user mouse clicks on menu popup node
+		if(this.disabled || this.readOnly){ return; }
+		this._toggleDropDown();
+	},
+
+	_onDropDownClick: function(/*Event*/ e){
+		// on Firefox 2 on the Mac it is possible to fire onclick
+		// by pressing enter down on a second element and transferring
+		// focus to the DropDownButton;
+		// we want to prevent opening our menu in this situation
+		// and only do so if we have seen a keydown on this button;
+		// e.detail != 0 means that we were fired by mouse
+		var isMacFFlessThan3 = dojo.isFF && dojo.isFF < 3
+			&& navigator.appVersion.indexOf("Macintosh") != -1;
+		if(!isMacFFlessThan3 || e.detail != 0 || this._seenKeydown){
+			this._onArrowClick(e);
+		}
+		this._seenKeydown = false;
+	},
+
+	_onDropDownKeydown: function(/*Event*/ e){
+		this._seenKeydown = true;
+	},
+
+	_onDropDownBlur: function(/*Event*/ e){
+		this._seenKeydown = false;
+	},
+
+	_onKey: function(/*Event*/ e){
+		// summary:
+		//		Handler when the user presses a key on drop down widget
+		if(this.disabled || this.readOnly){ return; }
+		if(e.charOrCode == dojo.keys.DOWN_ARROW){
+			if(!this.dropDown || this.dropDown.domNode.style.visibility=="hidden"){
+				dojo.stopEvent(e);
+				this._toggleDropDown();
+			}
+		}
+	},
+
+	_onBlur: function(){
+		// summary:
+		//		Called magically when focus has shifted away from this widget and it's dropdown
+		this._closeDropDown();
+		// don't focus on button.  the user has explicitly focused on something else.
+		this.inherited(arguments);
+	},
+
+	_toggleDropDown: function(){
+		// summary:
+		//		Toggle the drop-down widget; if it is up, close it; if not, open it.
+		if(this.disabled || this.readOnly){ return; }
+		dijit.focus(this.popupStateNode);
+		var dropDown = this.dropDown;
+		if(!dropDown){ return; }
+		if(!this._opened){
+			// If there's an href, then load that first, so we don't get a flicker
+			if(dropDown.href && !dropDown.isLoaded){
+				var self = this;
+				var handler = dojo.connect(dropDown, "onLoad", function(){
+					dojo.disconnect(handler);
+					self._openDropDown();
+				});
+				dropDown.refresh();
+				return;
+			}else{
+				this._openDropDown();
+			}
+		}else{
+			this._closeDropDown();
+		}
+	},
+
+	_openDropDown: function(){
+		var dropDown = this.dropDown;
+		var oldWidth=dropDown.domNode.style.width;
+		var self = this;
+
+		dijit.popup.open({
+			parent: this,
+			popup: dropDown,
+			around: this.domNode,
+			orient:
+				// TODO: add user-defined positioning option, like in Tooltip.js
+				this.isLeftToRight() ? {'BL':'TL', 'BR':'TR', 'TL':'BL', 'TR':'BR'}
+				: {'BR':'TR', 'BL':'TL', 'TR':'BR', 'TL':'BL'},
+			onExecute: function(){
+				self._closeDropDown(true);
+			},
+			onCancel: function(){
+				self._closeDropDown(true);
+			},
+			onClose: function(){
+				dropDown.domNode.style.width = oldWidth;
+				self.popupStateNode.removeAttribute("popupActive");
+				self._opened = false;
+			}
+		});
+		if(this.domNode.offsetWidth > dropDown.domNode.offsetWidth){
+			var adjustNode = null;
+			if(!this.isLeftToRight()){
+				adjustNode = dropDown.domNode.parentNode;
+				var oldRight = adjustNode.offsetLeft + adjustNode.offsetWidth;
+			}
+			// make menu at least as wide as the button
+			dojo.marginBox(dropDown.domNode, {w: this.domNode.offsetWidth});
+			if(adjustNode){
+				adjustNode.style.left = oldRight - this.domNode.offsetWidth + "px";
+			}
+		}
+		this.popupStateNode.setAttribute("popupActive", "true");
+		this._opened=true;
+		if(dropDown.focus){
+			dropDown.focus();
+		}
+		// TODO: set this.checked and call setStateClass(), to affect button look while drop down is shown
+	},
+	
+	_closeDropDown: function(/*Boolean*/ focus){
+		if(this._opened){
+			dijit.popup.close(this.dropDown);
+			if(focus){ this.focus(); }
+			this._opened = false;			
+		}
+	}
+});
+
+dojo.declare("dijit.form.ComboButton", dijit.form.DropDownButton, {
+	// summary:
+	//		A combination button and drop-down button.
+	//		Users can click one side to "press" the button, or click an arrow
+	//		icon to display the drop down.
+	//
+	// example:
+	// |	<button dojoType="dijit.form.ComboButton" onClick="...">
+	// |		<span>Hello world</span>
+	// |		<div dojoType="dijit.Menu">...</div>
+	// |	</button>
+	//
+	// example:
+	// |	var button1 = new dijit.form.ComboButton({label: "hello world", onClick: foo, dropDown: "myMenu"});
+	// |	dojo.body().appendChild(button1.domNode);
+	// 
+
+	templateString:"<table class='dijit dijitReset dijitInline dijitLeft'\n\tcellspacing='0' cellpadding='0' waiRole=\"presentation\"\n\t><tbody waiRole=\"presentation\"><tr waiRole=\"presentation\"\n\t\t><td class=\"dijitReset dijitStretch dijitButtonContents dijitButtonNode\"\n\t\t\tdojoAttachEvent=\"ondijitclick:_onButtonClick,onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\"  dojoAttachPoint=\"titleNode\"\n\t\t\twaiRole=\"button\" waiState=\"labelledby-${id}_label\"\n\t [...]
+
+	attributeMap: dojo.mixin(dojo.clone(dijit.form.Button.prototype.attributeMap), {
+		id:"",
+		tabIndex: ["focusNode", "titleNode"]
+	}),
+
+	// optionsTitle: String
+	//		Text that describes the options menu (accessibility)
+	optionsTitle: "",
+
+	baseClass: "dijitComboButton",
+
+	_focusedNode: null,
+
+	postCreate: function(){
+		this.inherited(arguments);
+		this._focalNodes = [this.titleNode, this.popupStateNode];
+		dojo.forEach(this._focalNodes, dojo.hitch(this, function(node){
+			if(dojo.isIE){
+				this.connect(node, "onactivate", this._onNodeFocus);
+				this.connect(node, "ondeactivate", this._onNodeBlur);
+			}else{
+				this.connect(node, "onfocus", this._onNodeFocus);
+				this.connect(node, "onblur", this._onNodeBlur);
+			}
+		}));
+	},
+
+	focusFocalNode: function(node){
+		// summary:
+		//		Focus the focal node node.
+		// description:
+		//		Called by _KeyNavContainer for (when example) this button is in a toolbar.
+		// tags:
+		//		protected
+		this._focusedNode = node;
+		dijit.focus(node);
+	},
+
+	hasNextFocalNode: function(){
+		// summary:
+		//		Returns true if this widget has no node currently
+		//		focused or if there is a node following the focused one.
+		//		False is returned if the last node has focus.
+		// description:
+		//		Called by _KeyNavContainer for (when example) this button is in a toolbar.
+		// tags:
+		//		protected
+		return this._focusedNode !== this.getFocalNodes()[1];
+	},
+
+	focusNext: function(){
+		// summary:
+		//		Focus the focal node following the current node with focus,
+		//		or the first one if no node currently has focus.
+		// description:
+		//		Called by _KeyNavContainer for (when example) this button is in a toolbar.
+		// tags:
+		//		protected
+		this._focusedNode = this.getFocalNodes()[this._focusedNode ? 1 : 0];
+		dijit.focus(this._focusedNode);
+	},
+
+	hasPrevFocalNode: function(){
+		// summary:
+		//		Returns true if this widget has no node currently
+		//		focused or if there is a node before the focused one.
+		//		False is returned if the first node has focus.
+		// description:
+		//		Called by _KeyNavContainer for (when example) this button is in a toolbar.
+		// tags:
+		//		protected
+		return this._focusedNode !== this.getFocalNodes()[0];
+	},
+
+	focusPrev: function(){
+		// summary:
+		//		Focus the focal node before the current node with focus
+		//		or the last one if no node currently has focus.
+		// description:
+		//		Called by _KeyNavContainer for (when example) this button is in a toolbar.
+		// tags:
+		//		protected
+		this._focusedNode = this.getFocalNodes()[this._focusedNode ? 0 : 1];
+		dijit.focus(this._focusedNode);
+	},
+
+	getFocalNodes: function(){
+		// summary:
+		//		Returns an array of focal nodes for this widget.
+		// description:
+		//		Called by _KeyNavContainer for (when example) this button is in a toolbar.
+		// tags:
+		//		protected
+		return this._focalNodes;
+	},
+
+	_onNodeFocus: function(evt){
+		this._focusedNode = evt.currentTarget;
+		var fnc = this._focusedNode == this.focusNode ? "dijitDownArrowButtonFocused" : "dijitButtonContentsFocused";
+		dojo.addClass(this._focusedNode, fnc);
+	},
+
+	_onNodeBlur: function(evt){
+		var fnc = evt.currentTarget == this.focusNode ? "dijitDownArrowButtonFocused" : "dijitButtonContentsFocused";
+		dojo.removeClass(evt.currentTarget, fnc);
+	},
+
+	_onBlur: function(){
+		this.inherited(arguments);
+		this._focusedNode = null;
+	}
+});
+
+dojo.declare("dijit.form.ToggleButton", dijit.form.Button, {
+	// summary:
+	//		A button that can be in two states (checked or not).
+	//		Can be base class for things like tabs or checkbox or radio buttons
+
+	baseClass: "dijitToggleButton",
+
+	// checked: Boolean
+	//		Corresponds to the native HTML <input> element's attribute.
+	//		In markup, specified as "checked='checked'" or just "checked".
+	//		True if the button is depressed, or the checkbox is checked,
+	//		or the radio button is selected, etc.
+	checked: false,
+
+	attributeMap: dojo.mixin(dojo.clone(dijit.form.Button.prototype.attributeMap),
+		{checked:"focusNode"}),
+
+	_clicked: function(/*Event*/ evt){
+		this.attr('checked', !this.checked);
+	},
+
+	_setCheckedAttr: function(/*Boolean*/ value){
+		this.checked = value;
+		dojo.attr(this.focusNode || this.domNode, "checked", value);
+		dijit.setWaiState(this.focusNode || this.domNode, "pressed", value);
+		this._setStateClass();		
+		this._handleOnChange(value, true);
+	},
+
+	setChecked: function(/*Boolean*/ checked){
+		// summary:
+		//		Deprecated.   Use attr('checked', true/false) instead.
+		dojo.deprecated("setChecked("+checked+") is deprecated. Use attr('checked',"+checked+") instead.", "", "2.0");
+		this.attr('checked', checked);
+	},
+	
+	reset: function(){
+		// summary:
+		//		Reset the widget's value to what it was at initialization time
+
+		this._hasBeenBlurred = false;
+
+		// set checked state to original setting
+		this.attr('checked', this.params.checked || false);
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit._editor._Plugin"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._editor._Plugin"] = true;
+dojo.provide("dijit._editor._Plugin");
+
+
+
+
+dojo.declare("dijit._editor._Plugin", null, {
+	// summary
+	//		Base class for a "plugin" to the editor, which is usually
+	//		a single button on the Toolbar and some associated code
+
+	constructor: function(/*Object?*/args, /*DomNode?*/node){
+		if(args){
+			dojo.mixin(this, args);
+		}
+		this._connects=[];
+	},
+
+	// editor: [const] dijit.Editor
+	//		Points to the parent editor
+	editor: null,
+
+	// iconClassPrefix: [const] String
+	//		The CSS class name for the button node is formed from `iconClassPrefix` and `command`
+	iconClassPrefix: "dijitEditorIcon",
+
+	// button: dijit._Widget?
+	//		Pointer to `dijit.form.Button` or other widget (ex: `dijit.form.FilteringSelect`) that controls this plugin.
+	//		If not specified, will be created on initialization according to `buttonClass`
+	button: null,
+
+	// queryCommand: ???
+	//		TODO: unused, remove
+	queryCommand: null,
+
+	// command: String
+	//		String like "insertUnorderedList", "outdent", "justifyCenter", etc. that represents an editor command.
+	//		Passed to editor.execCommand() if `useDefaultCommand` is true.
+	command: "",
+
+	// commandArg: anything
+	//		Argument to execCommand() after command.
+	//		TODO: unused, remove
+	commandArg: null,
+
+	// useDefaultCommand: Boolean
+	//		If true, this plugin executes by calling Editor.execCommand() with the argument specified in `command`.
+	useDefaultCommand: true,
+
+	// buttonClass: Widget Class
+	//		Class for button to control this plugin.   This is used to instantiate the button, unless `button` itself
+	//		is specified directly.
+	buttonClass: dijit.form.Button,
+
+	getLabel: function(/*String*/key){
+		// summary:
+		//		Returns the label to use for the button
+		// tags:
+		//		private
+		return this.editor.commands[key];		// String
+	},
+
+	_initButton: function(props){
+		// summary:
+		//		Initialize the button that will control this plugin.
+		//		This code only works for plugins controlling built-in commands in the editor.
+		// tags:
+		//		protected extension
+		if(this.command.length){
+			var label = this.getLabel(this.command);
+			var className = this.iconClassPrefix+" "+this.iconClassPrefix + this.command.charAt(0).toUpperCase() + this.command.substr(1);
+			if(!this.button){
+				props = dojo.mixin({
+					label: label,
+					showLabel: false,
+					iconClass: className,
+					dropDown: this.dropDown,
+					tabIndex: "-1"
+				}, props || {});
+				this.button = new this.buttonClass(props);
+			}
+		}
+	},
+
+	destroy: function(f){
+		// summary:
+		//		Destroy this plugin
+
+		// TODO: remove f parameter, it's unused
+
+		dojo.forEach(this._connects, dojo.disconnect);
+		if(this.dropDown){
+			this.dropDown.destroyRecursive();
+		}
+	},
+
+	connect: function(o, f, tf){
+		// summary:
+		//		Make a dojo.connect() that is automatically disconnected when this plugin is destroyed.
+		//		Similar to `dijit._Widget.connect`.
+		// tags:
+		//		protected
+		this._connects.push(dojo.connect(o, f, this, tf));
+	},
+
+	updateState: function(){
+		// summary:
+		//		Change state of the plugin to respond to events in the editor.
+		// description:
+		//		This is called on meaningful events in the editor, such as change of selection
+		//		or caret position (but not simple typing of alphanumeric keys).   It gives the
+		//		plugin a chance to update the CSS of its button.
+		//
+		//		For example, the "bold" plugin will highlight/unhighlight the bold button depending on whether the
+		//		characters next to the caret are bold or not.
+		//
+		//		Only makes sense when `useDefaultCommand` is true, as it calls Editor.queryCommandEnabled(`command`).
+		var e = this.editor,
+			c = this.command,
+			checked, enabled;
+		if(!e || !e.isLoaded || !c.length){ return; }
+		if(this.button){
+			try{
+				enabled = e.queryCommandEnabled(c);
+				if(this.enabled !== enabled){
+					this.enabled = enabled;
+					this.button.attr('disabled', !enabled);
+				}
+				if(typeof this.button.checked == 'boolean'){
+					checked = e.queryCommandState(c);
+					if(this.checked !== checked){
+						this.checked = checked;
+						this.button.attr('checked', e.queryCommandState(c));
+					}
+				}
+			}catch(e){
+				 // FIXME: we shouldn't have debug statements in our code.  Log as an error?
+			}
+		}
+	},
+
+	setEditor: function(/*dijit.Editor*/ editor){
+		// summary:
+		//		Tell the plugin which Editor it is associated with.
+
+		// TODO: refactor code to just pass editor to constructor.
+
+		// FIXME: detatch from previous editor!!
+		this.editor = editor;
+
+		// FIXME: prevent creating this if we don't need to (i.e., editor can't handle our command)
+		this._initButton();
+
+		// FIXME: wire up editor to button here!
+		if(this.command.length &&
+			!this.editor.queryCommandAvailable(this.command)){
+			// 
+			if(this.button){
+				this.button.domNode.style.display = "none";
+			}
+		}
+		if(this.button && this.useDefaultCommand){
+			this.connect(this.button, "onClick",
+				dojo.hitch(this.editor, "execCommand", this.command, this.commandArg)
+			);
+		}
+		this.connect(this.editor, "onNormalizedDisplayChanged", "updateState");
+	},
+
+	setToolbar: function(/*dijit.Toolbar*/ toolbar){
+		// summary:
+		//		Tell the plugin to add itself to the toolbar (if there is a button associated with the plugin).
+
+		// TODO: refactor code to just pass toolbar to constructor.
+
+		if(this.button){
+			toolbar.addChild(this.button);
+		}
+		// 
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit._editor.plugins.EnterKeyHandling"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._editor.plugins.EnterKeyHandling"] = true;
+dojo.provide("dijit._editor.plugins.EnterKeyHandling");
+
+dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
+	// summary:
+	//		This plugin tries to make all browsers have identical behavior
+	//		when the user presses the ENTER key.
+	//		Specifically, it fixes the double-spaced line problem on IE.
+	// description:
+	//		On IE the ENTER key creates a new paragraph, which visually looks
+	//		bad (ie, "double-spaced") and is also different than FF, which
+	//		makes a <br> in that.
+	//
+	//		In this plugin's default operation, where blockNodeForEnter==BR, it
+	//		makes the Editor on IE appear to work like other browsers, by:
+	//			1. changing the CSS for the <p> node to not have top/bottom margins,
+	//				thus eliminating the double-spaced appearance.
+	//			2. adds the singleLinePsToRegularPs callback when the
+	//				editor writes out it's data, in order to convert adjacent <p>
+	//				nodes into a single node
+	//		There's also a pre-filter to convert a single <p> with <br> line breaks
+	//		 into separate <p> nodes, to mirror the post-filter.
+	//
+	//		(Note: originally based on http://bugs.dojotoolkit.org/ticket/2859)
+	//
+	//		If you set the blockNodeForEnter option to another value, then this
+	//		plugin will monitor keystrokes (as they are typed) and apparently
+	//		update the editor's content on the fly so that the ENTER key will
+	//		either create a new <div>, or a new <p>.
+	//
+	//		This is useful because in some cases, you need the editor content to be
+	//		consistent with the serialized html even while the user is editing
+	//		(such as in a collaboration mode extension to the editor).
+	//
+	//		The handleEnterKey() code was mainly written for the IE double-spacing
+	//		issue that is now handled in the pre/post filters.  And it has some
+	//		issues... on IE setting blockNodeForEnter to P or BR
+	//		causes screen jumps as you type (making it unusable), and on safari
+	//		it just has no effect (safari creates a <div> every time the user
+	//		hits the enter key).  But apparently useful for case mentioned above.
+	//
+	//		(Note: originally based on http://bugs.dojotoolkit.org/ticket/1331)
+
+	// blockNodeForEnter: String
+	//		this property decides the behavior of Enter key. It can be either P,
+	//		DIV, BR, or empty (which means disable this feature). Anything else
+	//		will trigger errors.
+	blockNodeForEnter: 'BR',
+
+	constructor: function(args){
+		if(args){
+			dojo.mixin(this,args);
+		}
+	},
+
+	setEditor: function(editor){
+		// Overrides _Plugin.setEditor().
+		this.editor = editor;
+		if(this.blockNodeForEnter == 'BR'){
+			if(dojo.isIE){
+				editor.contentDomPreFilters.push(dojo.hitch(this, "regularPsToSingleLinePs"));
+				editor.contentDomPostFilters.push(dojo.hitch(this, "singleLinePsToRegularPs"));
+				editor.onLoadDeferred.addCallback(dojo.hitch(this, "_fixNewLineBehaviorForIE"));
+			}else{
+				editor.onLoadDeferred.addCallback(dojo.hitch(this,function(d){
+					try{
+						this.editor.document.execCommand("insertBrOnReturn", false, true);
+					}catch(e){}
+					return d;
+				}));
+			}
+		}else if(this.blockNodeForEnter){
+			//add enter key handler
+			// FIXME: need to port to the new event code!!
+			dojo['require']('dijit._editor.range');
+			var h = dojo.hitch(this,this.handleEnterKey);
+			editor.addKeyHandler(13, 0, 0, h); //enter
+			editor.addKeyHandler(13, 0, 1, h); //shift+enter
+			this.connect(this.editor,'onKeyPressed','onKeyPressed');
+		}
+	},
+	connect: function(o,f,tf){
+		// Overrides _Plugin.connect().
+		// TODO: Remove.  Method in _Plugin does the same thing.
+		if(!this._connects){
+			this._connects=[];
+		}
+		this._connects.push(dojo.connect(o,f,this,tf));
+	},
+	destroy: function(){
+		// Overrides _Plugin.destroy().
+		// TODO: Remove.  Method in _Plugin does the same thing.
+		dojo.forEach(this._connects,dojo.disconnect);
+		this._connects=[];
+	},
+	onKeyPressed: function(e){
+		// summary:
+		//		Handler for keypress events.
+		// tags:
+		//		private
+		if(this._checkListLater){
+			if(dojo.withGlobal(this.editor.window, 'isCollapsed', dijit)){
+				var liparent=dojo.withGlobal(this.editor.window, 'getAncestorElement', dijit._editor.selection, ['LI']);
+				if(!liparent){
+					//circulate the undo detection code by calling RichText::execCommand directly
+					dijit._editor.RichText.prototype.execCommand.call(this.editor, 'formatblock',this.blockNodeForEnter);
+					//set the innerHTML of the new block node
+					var block = dojo.withGlobal(this.editor.window, 'getAncestorElement', dijit._editor.selection, [this.blockNodeForEnter]);
+					if(block){
+						block.innerHTML=this.bogusHtmlContent;
+						if(dojo.isIE){
+							//the following won't work, it will move the caret to the last list item in the previous list
+							/*var newrange = dijit.range.create();
+							newrange.setStart(block.firstChild,0);
+							var selection = dijit.range.getSelection(this.editor.window)
+							selection.removeAllRanges();
+							selection.addRange(newrange);*/
+							//move to the start by move backward one char
+							var r = this.editor.document.selection.createRange();
+							r.move('character',-1);
+							r.select();
+						}
+					}else{
+						alert('onKeyPressed: Can not find the new block node'); //FIXME
+					}
+				}else{
+					
+					if(dojo.isMoz){
+						if(liparent.parentNode.parentNode.nodeName=='LI'){
+							liparent=liparent.parentNode.parentNode;
+						}
+					}
+					var fc=liparent.firstChild;
+					if(fc && fc.nodeType==1 && (fc.nodeName=='UL' || fc.nodeName=='OL')){
+						liparent.insertBefore(fc.ownerDocument.createTextNode('\xA0'),fc);
+						var newrange = dijit.range.create();
+						newrange.setStart(liparent.firstChild,0);
+						var selection = dijit.range.getSelection(this.editor.window,true)
+						selection.removeAllRanges();
+						selection.addRange(newrange);
+					}
+				}
+			}
+			this._checkListLater = false;
+		}
+		if(this._pressedEnterInBlock){
+			//the new created is the original current P, so we have previousSibling below
+			if(this._pressedEnterInBlock.previousSibling){
+			    this.removeTrailingBr(this._pressedEnterInBlock.previousSibling);
+			}
+			delete this._pressedEnterInBlock;
+		}
+	},
+
+	// bogusHtmlContent: [private] String
+	//		HTML to stick into a new empty block
+	bogusHtmlContent: ' ',
+
+	// blockNodes: [private] Regex
+	//		Regex for testing if a given tag is a block level (display:block) tag
+	blockNodes: /^(?:P|H1|H2|H3|H4|H5|H6|LI)$/,
+
+	handleEnterKey: function(e){
+		// summary:
+		//		Handler for enter key events.
+		// description:
+		//		Manually handle enter key event to make the behavior consistent across
+		//		all supported browsers. See property blockNodeForEnter for available options
+		// tags:
+		//		private
+		
+		 // let browser handle this
+		// TODO: delete.  this code will never fire because 
+		// onKeyPress --> handleEnterKey is only called when blockNodeForEnter != null
+		if(!this.blockNodeForEnter){ return true; }
+
+		var selection, range, newrange, doc=this.editor.document,br;
+		if(e.shiftKey  //shift+enter always generates <br>
+			|| this.blockNodeForEnter=='BR'){
+			// TODO: above condition 'this.blockNodeForEnter=='BR'' is meaningless,
+			// onKeyPress --> handleEnterKey is only called when blockNodeForEnter != BR
+			var parent = dojo.withGlobal(this.editor.window, "getParentElement", dijit._editor.selection);
+			var header = dijit.range.getAncestor(parent,this.blockNodes);
+			if(header){
+				if(!e.shiftKey && header.tagName=='LI'){
+					return true; //let brower handle
+				}
+				selection = dijit.range.getSelection(this.editor.window);
+				range = selection.getRangeAt(0);
+				if(!range.collapsed){
+					range.deleteContents();
+				}
+				if(dijit.range.atBeginningOfContainer(header, range.startContainer, range.startOffset)){
+					if(e.shiftKey){
+						br=doc.createElement('br');
+						newrange = dijit.range.create();
+						header.insertBefore(br,header.firstChild);
+						newrange.setStartBefore(br.nextSibling);
+						selection.removeAllRanges();
+						selection.addRange(newrange);
+					}else{
+						dojo.place(br, header, "before");
+					}
+				}else if(dijit.range.atEndOfContainer(header, range.startContainer, range.startOffset)){
+					newrange = dijit.range.create();
+					br=doc.createElement('br');
+					if(e.shiftKey){
+						header.appendChild(br);
+						header.appendChild(doc.createTextNode('\xA0'));
+						newrange.setStart(header.lastChild,0);
+					}else{
+						dojo.place(br, header, "after");
+						newrange.setStartAfter(header);
+					}
+
+					selection.removeAllRanges();
+					selection.addRange(newrange);
+				}else{
+					return true; //let brower handle
+				}
+			}else{
+				//don't change this: do not call this.execCommand, as that may have other logic in subclass
+				// FIXME
+				dijit._editor.RichText.prototype.execCommand.call(this.editor, 'inserthtml', '<br>');
+			}
+			return false;
+		}
+		var _letBrowserHandle = true;
+		//blockNodeForEnter is either P or DIV
+		//first remove selection
+		selection = dijit.range.getSelection(this.editor.window);
+		range = selection.getRangeAt(0);
+		if(!range.collapsed){
+			range.deleteContents();
+		}
+
+		var block = dijit.range.getBlockAncestor(range.endContainer, null, this.editor.editNode);
+		var blockNode = block.blockNode;
+
+		//if this is under a LI or the parent of the blockNode is LI, just let browser to handle it
+		if((this._checkListLater = (blockNode && (blockNode.nodeName == 'LI' || blockNode.parentNode.nodeName == 'LI')))){
+			
+		    if(dojo.isMoz){
+				//press enter in middle of P may leave a trailing <br/>, let's remove it later
+				this._pressedEnterInBlock = blockNode;
+			}
+			//if this li only contains spaces, set the content to empty so the browser will outdent this item
+			if(/^(?:\s| )$/.test(blockNode.innerHTML)){
+				blockNode.innerHTML='';
+			}
+
+			return true;
+		}
+
+		//text node directly under body, let's wrap them in a node
+		if(!block.blockNode || block.blockNode===this.editor.editNode){
+			dijit._editor.RichText.prototype.execCommand.call(this.editor, 'formatblock',this.blockNodeForEnter);
+			//get the newly created block node
+			// FIXME
+			block = {blockNode:dojo.withGlobal(this.editor.window, "getAncestorElement", dijit._editor.selection, [this.blockNodeForEnter]),
+					blockContainer: this.editor.editNode};
+			if(block.blockNode){
+				if(!(block.blockNode.textContent || block.blockNode.innerHTML).replace(/^\s+|\s+$/g, "").length){
+					this.removeTrailingBr(block.blockNode);
+					return false;
+				}
+			}else{
+				block.blockNode = this.editor.editNode;
+			}
+			selection = dijit.range.getSelection(this.editor.window);
+			range = selection.getRangeAt(0);
+		}
+
+		var newblock = doc.createElement(this.blockNodeForEnter);
+		newblock.innerHTML=this.bogusHtmlContent;
+		this.removeTrailingBr(block.blockNode);
+		if(dijit.range.atEndOfContainer(block.blockNode, range.endContainer, range.endOffset)){
+			if(block.blockNode === block.blockContainer){
+				block.blockNode.appendChild(newblock);
+			}else{
+				dojo.place(newblock, block.blockNode, "after");
+			}
+			_letBrowserHandle = false;
+			//lets move caret to the newly created block
+			newrange = dijit.range.create();
+			newrange.setStart(newblock,0);
+			selection.removeAllRanges();
+			selection.addRange(newrange);
+			if(this.editor.height){
+				newblock.scrollIntoView(false);
+			}
+		}else if(dijit.range.atBeginningOfContainer(block.blockNode,
+				range.startContainer, range.startOffset)){
+			dojo.place(newblock, block.blockNode, block.blockNode === block.blockContainer ? "first" : "before");
+			if(newblock.nextSibling && this.editor.height){
+				//browser does not scroll the caret position into view, do it manually
+				newblock.nextSibling.scrollIntoView(false);
+			}
+			_letBrowserHandle = false;
+		}else{ //press enter in the middle of P
+			if(dojo.isMoz){
+				//press enter in middle of P may leave a trailing <br/>, let's remove it later
+				this._pressedEnterInBlock = block.blockNode;
+			}
+		}
+		return _letBrowserHandle;
+	},
+
+	removeTrailingBr: function(container){
+		// summary:
+		//		If last child of container is a <br>, then remove it.
+		// tags:
+		//		private
+		var para = /P|DIV|LI/i.test(container.tagName) ?
+			container : dijit._editor.selection.getParentOfType(container,['P','DIV','LI']);
+
+		if(!para){ return; }
+		if(para.lastChild){
+			if((para.childNodes.length > 1 && para.lastChild.nodeType == 3 && /^[\s\xAD]*$/.test(para.lastChild.nodeValue)) ||
+				(para.lastChild && para.lastChild.tagName=='BR')){
+
+				dojo.destroy(para.lastChild);
+			}
+		}
+		if(!para.childNodes.length){
+			para.innerHTML=this.bogusHtmlContent;
+		}
+	},
+	_fixNewLineBehaviorForIE: function(d){
+		// summary:
+		//		Insert CSS so <p> nodes don't have spacing around them,
+		//		thus hiding the fact that ENTER key on IE is creating new
+		//		paragraphs
+		if(this.editor.document.__INSERTED_EDITIOR_NEWLINE_CSS === undefined){
+			var lineFixingStyles = "p{margin:0 !important;}";
+			var insertCssText = function(
+				/*String*/ cssStr,
+				/*Document*/ doc,
+				/*String*/ URI)
+			{
+				//	summary:
+				//		Attempt to insert CSS rules into the document through inserting a
+				//		style element
+
+				// DomNode Style  = insertCssText(String ".dojoMenu {color: green;}"[, DomDoc document, dojo.uri.Uri Url ])
+				if(!cssStr){
+					return null; //	HTMLStyleElement
+				}
+				if(!doc){ doc = document; }
+//					if(URI){// fix paths in cssStr
+//						cssStr = dojo.html.fixPathsInCssText(cssStr, URI);
+//					}
+				var style = doc.createElement("style");
+				style.setAttribute("type", "text/css");
+				// IE is b0rken enough to require that we add the element to the doc
+				// before changing it's properties
+				var head = doc.getElementsByTagName("head")[0];
+				if(!head){ // must have a head tag
+					
+					return null;	//	HTMLStyleElement
+				}else{
+					head.appendChild(style);
+				}
+				if(style.styleSheet){// IE
+					var setFunc = function(){
+						try{
+							style.styleSheet.cssText = cssStr;
+						}catch(e){  }
+					};
+					if(style.styleSheet.disabled){
+						setTimeout(setFunc, 10);
+					}else{
+						setFunc();
+					}
+				}else{ // w3c
+					var cssText = doc.createTextNode(cssStr);
+					style.appendChild(cssText);
+				}
+				return style;	//	HTMLStyleElement
+			}
+			insertCssText(lineFixingStyles, this.editor.document);
+			this.editor.document.__INSERTED_EDITIOR_NEWLINE_CSS = true;
+			// this.regularPsToSingleLinePs(this.editNode);
+			return d;
+		}
+		return null;
+	},
+	regularPsToSingleLinePs: function(element, noWhiteSpaceInEmptyP){
+		// summary:
+		//		Converts a <p> node containing <br>'s into multiple <p> nodes.
+		// description:
+		//		See singleLinePsToRegularPs().   This method does the
+		//		opposite thing, and is used as a pre-filter when loading the
+		//		editor, to mirror the effects of the post-filter at end of edit.
+		// tags:
+		//		private
+		function wrapLinesInPs(el){
+		  // move "lines" of top-level text nodes into ps
+			function wrapNodes(nodes){
+				// nodes are assumed to all be siblings
+				var newP = nodes[0].ownerDocument.createElement('p'); // FIXME: not very idiomatic
+				nodes[0].parentNode.insertBefore(newP, nodes[0]);
+				dojo.forEach(nodes, function(node){
+					newP.appendChild(node);
+				});
+			}
+
+			var currentNodeIndex = 0;
+			var nodesInLine = [];
+			var currentNode;
+			while(currentNodeIndex < el.childNodes.length){
+				currentNode = el.childNodes[currentNodeIndex];
+				if( currentNode.nodeType==3 ||	// text node
+					(currentNode.nodeType==1 && currentNode.nodeName!='BR' && dojo.style(currentNode, "display")!="block")
+				){
+					nodesInLine.push(currentNode);
+				}else{
+					// hit line delimiter; process nodesInLine if there are any
+					var nextCurrentNode = currentNode.nextSibling;
+					if(nodesInLine.length){
+						wrapNodes(nodesInLine);
+						currentNodeIndex = (currentNodeIndex+1)-nodesInLine.length;
+						if(currentNode.nodeName=="BR"){
+							dojo.destroy(currentNode);
+						}
+					}
+					nodesInLine = [];
+				}
+				currentNodeIndex++;
+			}
+			if(nodesInLine.length){ wrapNodes(nodesInLine); }
+		}
+
+		function splitP(el){
+			// split a paragraph into seperate paragraphs at BRs
+			var currentNode = null;
+			var trailingNodes = [];
+			var lastNodeIndex = el.childNodes.length-1;
+			for(var i=lastNodeIndex; i>=0; i--){
+				currentNode = el.childNodes[i];
+				if(currentNode.nodeName=="BR"){
+					var newP = currentNode.ownerDocument.createElement('p');
+					dojo.place(newP, el, "after");
+					if (trailingNodes.length==0 && i != lastNodeIndex) {
+						newP.innerHTML = " "
+					}
+					dojo.forEach(trailingNodes, function(node){
+						newP.appendChild(node);
+					});
+					dojo.destroy(currentNode);
+					trailingNodes = [];
+				}else{
+					trailingNodes.unshift(currentNode);
+				}
+			}
+		}
+
+		var pList = [];
+		var ps = element.getElementsByTagName('p');
+		dojo.forEach(ps, function(p){ pList.push(p); });
+		dojo.forEach(pList, function(p){
+			if(	(p.previousSibling) &&
+				(p.previousSibling.nodeName == 'P' || dojo.style(p.previousSibling, 'display') != 'block')
+			){
+				var newP = p.parentNode.insertBefore(this.document.createElement('p'), p);
+				// this is essential to prevent IE from losing the P.
+				// if it's going to be innerHTML'd later we need
+				// to add the   to _really_ force the issue
+				newP.innerHTML = noWhiteSpaceInEmptyP ? "" : " ";
+			}
+			splitP(p);
+	  },this.editor);
+		wrapLinesInPs(element);
+		return element;
+	},
+
+	singleLinePsToRegularPs: function(element){
+		// summary:
+		//		Called as post-filter.
+		//		Apparently collapses adjacent <p> nodes into a single <p>
+		//		nodes with <br> separating each line.
+		//
+		//	example:
+		//		Given this input:
+		//	|	<p>line 1</p>
+		//	|	<p>line 2</p>
+		//	|	<ol>
+		//	|		<li>item 1
+		//	|		<li>item 2
+		//	|	</ol>
+		//	|	<p>line 3</p>
+		//	|	<p>line 4</p>
+		//
+		//		Will convert to:
+		//	|	<p>line 1<br>line 2</p>
+		//	|	<ol>
+		//	|		<li>item 1
+		//	|		<li>item 2
+		//	|	</ol>
+		//	|	<p>line 3<br>line 4</p>
+		//
+		//		Not sure why this situation would even come up after the pre-filter and
+		//		the enter-key-handling code.
+		//
+		// tags:
+		//		private
+	
+		function getParagraphParents(node){
+			// summary:
+			//		Used to get list of all nodes that contain paragraphs.
+			//		Seems like that would just be the very top node itself, but apparently not.
+			var ps = node.getElementsByTagName('p');
+			var parents = [];
+			for(var i=0; i<ps.length; i++){
+				var p = ps[i];
+				var knownParent = false;
+				for(var k=0; k < parents.length; k++){
+					if(parents[k] === p.parentNode){
+						knownParent = true;
+						break;
+					}
+				}
+				if(!knownParent){
+					parents.push(p.parentNode);
+				}
+			}
+			return parents;
+		}
+
+		function isParagraphDelimiter(node){
+			if(node.nodeType != 1 || node.tagName != 'P'){
+				return dojo.style(node, 'display') == 'block';
+			}else{
+				if(!node.childNodes.length || node.innerHTML==" "){ return true; }
+				//return node.innerHTML.match(/^(<br\ ?\/?>| |\&nbsp\;)$/i);
+			}
+			return false;
+		}
+
+		var paragraphContainers = getParagraphParents(element);
+		for(var i=0; i<paragraphContainers.length; i++){
+			var container = paragraphContainers[i];
+			var firstPInBlock = null;
+			var node = container.firstChild;
+			var deleteNode = null;
+			while(node){
+				if(node.nodeType != "1" || node.tagName != 'P'){
+					firstPInBlock = null;
+				}else if (isParagraphDelimiter(node)){
+					deleteNode = node;
+					firstPInBlock = null;
+				}else{
+					if(firstPInBlock == null){
+						firstPInBlock = node;
+					}else{
+						if( (!firstPInBlock.lastChild || firstPInBlock.lastChild.nodeName != 'BR') &&
+							(node.firstChild) &&
+							(node.firstChild.nodeName != 'BR')
+						){
+							firstPInBlock.appendChild(this.editor.document.createElement('br'));
+						}
+						while(node.firstChild){
+							firstPInBlock.appendChild(node.firstChild);
+						}
+						deleteNode = node;
+					}
+				}
+				node = node.nextSibling;
+				if(deleteNode){
+					dojo.destroy(deleteNode);
+					deleteNode = null;
+				}
+			}
+		}
+		return element;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit.Editor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.Editor"] = true;
+dojo.provide("dijit.Editor");
+
+
+
+
+
+
+
+
+
+
+dojo.declare(
+	"dijit.Editor",
+	dijit._editor.RichText,
+	{
+		// summary:
+		//		A rich text Editing widget
+		//
+		// description:
+		//		This widget provides basic WYSIWYG editing features, based on the browser's
+		//		underlying rich text editing capability, accompanied by a toolbar (dijit.Toolbar).
+		//		A plugin model is available to extend the editor's capabilities as well as the
+		//		the options available in the toolbar.  Content generation may vary across
+		//		browsers, and clipboard operations may have different results, to name
+		//		a few limitations.  Note: this widget should not be used with the HTML
+		//		<TEXTAREA> tag -- see dijit._editor.RichText for details.
+
+		// plugins: String[]
+		//		A list of plugin names (as strings) or instances (as objects)
+		//		for this widget.
+		plugins: null,
+
+		// extraPlugins: String[]
+		//		A list of extra plugin names which will be appended to plugins array
+		extraPlugins: null,
+
+		constructor: function(){
+			// summary:
+			//		Runs on widget initialization to setup arrays etc.
+			// tags:
+			//		private
+
+			if(!dojo.isArray(this.plugins)){
+				this.plugins=["undo","redo","|","cut","copy","paste","|","bold","italic","underline","strikethrough","|",
+				"insertOrderedList","insertUnorderedList","indent","outdent","|","justifyLeft","justifyRight","justifyCenter","justifyFull",
+				"dijit._editor.plugins.EnterKeyHandling" /*, "createLink"*/];
+			}
+
+			this._plugins=[];
+			this._editInterval = this.editActionInterval * 1000;
+
+			//IE will always lose focus when other element gets focus, while for FF and safari,
+			//when no iframe is used, focus will be lost whenever another element gets focus.
+			//For IE, we can connect to onBeforeDeactivate, which will be called right before
+			//the focus is lost, so we can obtain the selected range. For other browsers,
+			//no equivelent of onBeforeDeactivate, so we need to do two things to make sure 
+			//selection is properly saved before focus is lost: 1) when user clicks another 
+			//element in the page, in which case we listen to mousedown on the entire page and
+			//see whether user clicks out of a focus editor, if so, save selection (focus will
+			//only lost after onmousedown event is fired, so we can obtain correct caret pos.)
+			//2) when user tabs away from the editor, which is handled in onKeyDown below.
+			if(dojo.isIE){
+				this.events.push("onBeforeDeactivate");
+			}
+		},
+
+		postCreate: function(){
+			//for custom undo/redo
+			if(this.customUndo){
+				dojo['require']("dijit._editor.range");
+				this._steps=this._steps.slice(0);
+				this._undoedSteps=this._undoedSteps.slice(0);
+//				this.addKeyHandler('z',this.KEY_CTRL,this.undo);
+//				this.addKeyHandler('y',this.KEY_CTRL,this.redo);
+			}
+			if(dojo.isArray(this.extraPlugins)){
+				this.plugins=this.plugins.concat(this.extraPlugins);
+			}
+
+//			try{
+			this.inherited(arguments);
+//			dijit.Editor.superclass.postCreate.apply(this, arguments);
+
+			this.commands = dojo.i18n.getLocalization("dijit._editor", "commands", this.lang);
+
+			if(!this.toolbar){
+				// if we haven't been assigned a toolbar, create one
+				this.toolbar = new dijit.Toolbar({});
+				dojo.place(this.toolbar.domNode, this.editingArea, "before");
+			}
+
+			dojo.forEach(this.plugins, this.addPlugin, this);
+			this.onNormalizedDisplayChanged(); //update toolbar button status
+//			}catch(e){  }
+
+			this.toolbar.startup();
+		},
+		destroy: function(){
+			dojo.forEach(this._plugins, function(p){
+				if(p && p.destroy){
+					p.destroy();
+				}
+			});
+			this._plugins=[];
+			this.toolbar.destroyRecursive();
+			delete this.toolbar;
+			this.inherited(arguments);
+		},
+		addPlugin: function(/*String||Object*/plugin, /*Integer?*/index){
+			// summary:
+			//		takes a plugin name as a string or a plugin instance and
+			//		adds it to the toolbar and associates it with this editor
+			//		instance. The resulting plugin is added to the Editor's
+			//		plugins array. If index is passed, it's placed in the plugins
+			//		array at that index. No big magic, but a nice helper for
+			//		passing in plugin names via markup.
+			//
+			// plugin: String, args object or plugin instance
+			//
+			// args:
+			//		This object will be passed to the plugin constructor
+			//
+			// index: Integer
+			//		Used when creating an instance from
+			//		something already in this.plugins. Ensures that the new
+			//		instance is assigned to this.plugins at that index.
+			var args=dojo.isString(plugin)?{name:plugin}:plugin;
+			if(!args.setEditor){
+				var o={"args":args,"plugin":null,"editor":this};
+				dojo.publish(dijit._scopeName + ".Editor.getPlugin",[o]);
+				if(!o.plugin){
+					var pc = dojo.getObject(args.name);
+					if(pc){
+						o.plugin=new pc(args);
+					}
+				}
+				if(!o.plugin){
+					console.warn('Cannot find plugin',plugin);
+					return;
+				}
+				plugin=o.plugin;
+			}
+			if(arguments.length > 1){
+				this._plugins[index] = plugin;
+			}else{
+				this._plugins.push(plugin);
+			}
+			plugin.setEditor(this);
+			if(dojo.isFunction(plugin.setToolbar)){
+				plugin.setToolbar(this.toolbar);
+			}
+		},
+		//the following 3 functions are required to make the editor play nice under a layout widget, see #4070
+		startup: function(){
+			// summary:
+			//		Exists to make Editor work as a child of a layout widget.
+			//		Developers don't need to call this method.
+			// tags:
+			//		protected
+			//
+		},
+		resize: function(size){
+			// summary:
+			//		Resize the editor to the specified size, see `dijit.layout._LayoutWidget.resize`
+			dijit.layout._LayoutWidget.prototype.resize.apply(this,arguments);
+		},
+		layout: function(){
+			// summary:
+			//		Called from `dijit.layout._LayoutWidget.resize`.  This shouldn't be called directly
+			// tags:
+			//		protected
+			this.editingArea.style.height=(this._contentBox.h - dojo.marginBox(this.toolbar.domNode).h)+"px";
+			if(this.iframe){
+				this.iframe.style.height="100%";
+			}
+			this._layoutMode = true;
+		},
+		_onIEMouseDown: function(/*Event*/ e){
+			// summary:
+			//		IE only to prevent 2 clicks to focus
+			// tags:
+			//		private
+			delete this._savedSelection; // new mouse position overrides old selection
+			if(e.target.tagName == "BODY"){
+				setTimeout(dojo.hitch(this, "placeCursorAtEnd"), 0);
+			}
+			this.inherited(arguments);
+		},
+		onBeforeDeactivate: function(e){
+			// summary:
+			//		Called on IE right before focus is lost.   Saves the selected range.
+			// tags:
+			//		private
+			if(this.customUndo){
+				this.endEditing(true);
+			}
+			//in IE, the selection will be lost when other elements get focus,
+			//let's save focus before the editor is deactivated
+			this._saveSelection();
+	        //
+		},
+
+		/* beginning of custom undo/redo support */
+
+		// customUndo: Boolean
+		//		Whether we shall use custom undo/redo support instead of the native
+		//		browser support. By default, we only enable customUndo for IE, as it
+		//		has broken native undo/redo support. Note: the implementation does
+		//		support other browsers which have W3C DOM2 Range API implemented.
+		customUndo: dojo.isIE,
+
+		// editActionInterval: Integer
+		//		When using customUndo, not every keystroke will be saved as a step.
+		//		Instead typing (including delete) will be grouped together: after
+		//		a user stops typing for editActionInterval seconds, a step will be
+		//		saved; if a user resume typing within editActionInterval seconds,
+		//		the timeout will be restarted. By default, editActionInterval is 3
+		//		seconds.
+		editActionInterval: 3,
+
+		beginEditing: function(cmd){
+			// summary:
+			//		Called to note that the user has started typing alphanumeric characters, if it's not already noted.
+			//		Deals with saving undo; see editActionInterval parameter.
+			// tags:
+			//		private
+			if(!this._inEditing){
+				this._inEditing=true;
+				this._beginEditing(cmd);
+			}
+			if(this.editActionInterval>0){
+				if(this._editTimer){
+					clearTimeout(this._editTimer);
+				}
+				this._editTimer = setTimeout(dojo.hitch(this, this.endEditing), this._editInterval);
+			}
+		},
+		_steps:[],
+		_undoedSteps:[],
+		execCommand: function(cmd){
+			// summary:
+			//		Main handler for executing any commands to the editor, like paste, bold, etc.
+			//      Called by plugins, but not meant to be called by end users.
+			// tags:
+			//		protected
+			if(this.customUndo && (cmd=='undo' || cmd=='redo')){
+				return this[cmd]();
+			}else{
+				if(this.customUndo){
+					this.endEditing();
+					this._beginEditing();
+				}
+				try{
+					var r = this.inherited('execCommand', arguments);
+                    if(dojo.isWebKit && cmd=='paste' && !r){ //see #4598: safari does not support invoking paste from js
+						throw { code: 1011 }; // throw an object like Mozilla's error
+                    }
+				}catch(e){
+					//TODO: when else might we get an exception?  Do we need the Mozilla test below?
+					if(e.code == 1011 /* Mozilla: service denied */ && /copy|cut|paste/.test(cmd)){
+						// Warn user of platform limitation.  Cannot programmatically access clipboard. See ticket #4136
+						var sub = dojo.string.substitute,
+							accel = {cut:'X', copy:'C', paste:'V'},
+							isMac = navigator.userAgent.indexOf("Macintosh") != -1;
+						alert(sub(this.commands.systemShortcut,
+							[this.commands[cmd], sub(this.commands[isMac ? 'appleKey' : 'ctrlKey'], [accel[cmd]])]));
+					}
+					r = false;
+				}
+				if(this.customUndo){
+					this._endEditing();
+				}
+				return r;
+			}
+		},
+		queryCommandEnabled: function(cmd){
+			// summary:
+			//		Returns true if specified editor command is enabled.
+			//      Used by the plugins to know when to highlight/not highlight buttons.
+			// tags:
+			//		protected
+			if(this.customUndo && (cmd=='undo' || cmd=='redo')){
+				return cmd=='undo'?(this._steps.length>1):(this._undoedSteps.length>0);
+			}else{
+				return this.inherited('queryCommandEnabled',arguments);
+			}
+		},
+
+		focus: function(){
+			// summary:
+			//		Set focus inside the editor
+			var restore=0;
+			//
+			if(this._savedSelection && dojo.isIE){
+				restore = dijit._curFocus!=this.editNode;
+			}
+		    this.inherited(arguments);
+		    if(restore){
+		    	this._restoreSelection();
+		    }
+		},
+		_moveToBookmark: function(b){
+			// summary:
+			//		Selects the text specified in bookmark b
+			// tags:
+			//		private
+			var bookmark=b;
+			if(dojo.isIE){
+				if(dojo.isArray(b)){//IE CONTROL
+					bookmark=[];
+					dojo.forEach(b,function(n){
+						bookmark.push(dijit.range.getNode(n,this.editNode));
+					},this);
+				}
+			}else{//w3c range
+				var r=dijit.range.create();
+				r.setStart(dijit.range.getNode(b.startContainer,this.editNode),b.startOffset);
+				r.setEnd(dijit.range.getNode(b.endContainer,this.editNode),b.endOffset);
+				bookmark=r;
+			}
+			dojo.withGlobal(this.window,'moveToBookmark',dijit,[bookmark]);
+		},
+		_changeToStep: function(from, to){
+			// summary:
+			//		Reverts editor to "to" setting, from the undo stack.
+			// tags:
+			//		private
+			this.setValue(to.text);
+			var b=to.bookmark;
+			if(!b){ return; }
+			this._moveToBookmark(b);
+		},
+		undo: function(){
+			// summary:
+			//		Handler for editor undo (ex: ctrl-z) operation
+			// tags:
+			//		private
+//			
+			this.endEditing(true);
+			var s=this._steps.pop();
+			if(this._steps.length>0){
+				this.focus();
+				this._changeToStep(s,this._steps[this._steps.length-1]);
+				this._undoedSteps.push(s);
+				this.onDisplayChanged();
+				return true;
+			}
+			return false;
+		},
+		redo: function(){
+			// summary:
+			//		Handler for editor redo (ex: ctrl-y) operation
+			// tags:
+			//		private
+
+//			
+			this.endEditing(true);
+			var s=this._undoedSteps.pop();
+			if(s && this._steps.length>0){
+				this.focus();
+				this._changeToStep(this._steps[this._steps.length-1],s);
+				this._steps.push(s);
+				this.onDisplayChanged();
+				return true;
+			}
+			return false;
+		},
+		endEditing: function(ignore_caret){
+			// summary:
+			//		Called to note that the user has stopped typing alphanumeric characters, if it's not already noted.
+			//		Deals with saving undo; see editActionInterval parameter.
+			// tags:
+			//		private
+			if(this._editTimer){
+				clearTimeout(this._editTimer);
+			}
+			if(this._inEditing){
+				this._endEditing(ignore_caret);
+				this._inEditing=false;
+			}
+		},
+		_getBookmark: function(){
+			// summary:
+			//		Get the currently selected text
+			// tags:
+			//		protected
+			var b=dojo.withGlobal(this.window,dijit.getBookmark);
+			var tmp=[];
+			if(dojo.isIE){
+				if(dojo.isArray(b)){//CONTROL
+					dojo.forEach(b,function(n){
+						tmp.push(dijit.range.getIndex(n,this.editNode).o);
+					},this);
+					b=tmp;
+				}
+			}else{//w3c range
+				tmp=dijit.range.getIndex(b.startContainer,this.editNode).o;
+				b={startContainer:tmp,
+					startOffset:b.startOffset,
+					endContainer:b.endContainer===b.startContainer?tmp:dijit.range.getIndex(b.endContainer,this.editNode).o,
+					endOffset:b.endOffset};
+			}
+			return b;
+		},
+		_beginEditing: function(cmd){
+			// summary:
+			//		Called when the user starts typing alphanumeric characters.
+			//		Deals with saving undo; see editActionInterval parameter.
+			// tags:
+			//		private
+			if(this._steps.length===0){
+				this._steps.push({'text':this.savedContent,'bookmark':this._getBookmark()});
+			}
+		},
+		_endEditing: function(ignore_caret){
+			// summary:
+			//		Called when the user stops typing alphanumeric characters.
+			//		Deals with saving undo; see editActionInterval parameter.
+			// tags:
+			//		private
+			var v=this.getValue(true);
+
+			this._undoedSteps=[];//clear undoed steps
+			this._steps.push({text: v, bookmark: this._getBookmark()});
+		},
+		onKeyDown: function(e){
+			// summary:
+			//		Handler for onkeydown event.
+			// tags:
+			//		private
+
+			//We need to save selection if the user TAB away from this editor
+			//no need to call _saveSelection for IE, as that will be taken care of in onBeforeDeactivate
+			if(!dojo.isIE && !this.iframe && e.keyCode==dojo.keys.TAB && !this.tabIndent){
+				this._saveSelection();
+			}
+			if(!this.customUndo){
+				this.inherited(arguments);
+				return;
+			}
+			var k = e.keyCode, ks = dojo.keys;
+			if(e.ctrlKey && !e.altKey){//undo and redo only if the special right Alt + z/y are not pressed #5892
+				if(k == 90 || k == 122){ //z
+					dojo.stopEvent(e);
+					this.undo();
+					return;
+				}else if(k == 89 || k == 121){ //y
+					dojo.stopEvent(e);
+					this.redo();
+					return;
+				}
+			}
+			this.inherited(arguments);
+
+			switch(k){
+					case ks.ENTER:
+					case ks.BACKSPACE:
+					case ks.DELETE:
+						this.beginEditing();
+						break;
+					case 88: //x
+					case 86: //v
+						if(e.ctrlKey && !e.altKey && !e.metaKey){
+							this.endEditing();//end current typing step if any
+							if(e.keyCode == 88){
+								this.beginEditing('cut');
+								//use timeout to trigger after the cut is complete
+								setTimeout(dojo.hitch(this, this.endEditing), 1);
+							}else{
+								this.beginEditing('paste');
+								//use timeout to trigger after the paste is complete
+								setTimeout(dojo.hitch(this, this.endEditing), 1);
+							}
+							break;
+						}
+						//pass through
+					default:
+						if(!e.ctrlKey && !e.altKey && !e.metaKey && (e.keyCode<dojo.keys.F1 || e.keyCode>dojo.keys.F15)){
+							this.beginEditing();
+							break;
+						}
+						//pass through
+					case ks.ALT:
+						this.endEditing();
+						break;
+					case ks.UP_ARROW:
+					case ks.DOWN_ARROW:
+					case ks.LEFT_ARROW:
+					case ks.RIGHT_ARROW:
+					case ks.HOME:
+					case ks.END:
+					case ks.PAGE_UP:
+					case ks.PAGE_DOWN:
+						this.endEditing(true);
+						break;
+					//maybe ctrl+backspace/delete, so don't endEditing when ctrl is pressed
+					case ks.CTRL:
+					case ks.SHIFT:
+					case ks.TAB:
+						break;
+				}
+		},
+		_onBlur: function(){
+			// summary:
+			//		Called from focus manager when focus has moved away from this editor
+			// tags:
+			//		protected
+
+			//this._saveSelection();
+			this.inherited('_onBlur',arguments);
+			this.endEditing(true);
+		},
+		_saveSelection: function(){
+			// summary:
+			//		Save the currently selected text in _savedSelection attribute
+			// tags:
+			//		private
+			this._savedSelection=this._getBookmark();
+			//
+		},
+		_restoreSelection: function(){
+			// summary:
+			//		Re-select the text specified in _savedSelection attribute;
+			//		see _saveSelection().
+			// tags:
+			//		private
+			if(this._savedSelection){
+				//only restore the selection if the current range is collapsed
+    				//if not collapsed, then it means the editor does not lose 
+    				//selection and there is no need to restore it
+    				if(dojo.withGlobal(this.window,'isCollapsed',dijit)){
+    					//
+					this._moveToBookmark(this._savedSelection);
+				}
+				delete this._savedSelection;
+			}
+		},
+		_onFocus: function(){
+			// summary:
+			//		Called from focus manager when focus has moved into this editor
+			// tags:
+			//		protected
+
+			//
+			setTimeout(dojo.hitch(this, "_restoreSelection"), 0); // needs input caret first
+			this.inherited(arguments);
+		},
+
+		onClick: function(){
+			// summary:
+			//		Handler for when editor is clicked
+			// tags:
+			//		protected
+			this.endEditing(true);
+			this.inherited(arguments);
+		}
+		/* end of custom undo/redo support */
+	}
+);
+
+// Register the "default plugins", ie, the built-in editor commands
+dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
+	if(o.plugin){ return; }
+	var args = o.args, p;
+	var _p = dijit._editor._Plugin;
+	var name = args.name;
+	switch(name){
+		case "undo": case "redo": case "cut": case "copy": case "paste": case "insertOrderedList":
+		case "insertUnorderedList": case "indent": case "outdent": case "justifyCenter":
+		case "justifyFull": case "justifyLeft": case "justifyRight": case "delete":
+		case "selectAll": case "removeFormat": case "unlink":
+		case "insertHorizontalRule":
+			p = new _p({ command: name });
+			break;
+
+		case "bold": case "italic": case "underline": case "strikethrough":
+		case "subscript": case "superscript":
+			p = new _p({ buttonClass: dijit.form.ToggleButton, command: name });
+			break;
+		case "|":
+			p = new _p({ button: new dijit.ToolbarSeparator() });
+	}
+//	
+	o.plugin=p;
+});
+
+}
+
+if(!dojo._hasResource["dijit.MenuItem"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.MenuItem"] = true;
+dojo.provide("dijit.MenuItem");
+
+
+
+
+
+dojo.declare("dijit.MenuItem",
+		[dijit._Widget, dijit._Templated, dijit._Contained],
+		{
+		// summary:
+		//		A line item in a Menu Widget
+
+		// Make 3 columns
+		// icon, label, and expand arrow (BiDi-dependent) indicating sub-menu
+		templateString:"<tr class=\"dijitReset dijitMenuItem\" dojoAttachPoint=\"focusNode\" waiRole=\"menuitem\" tabIndex=\"-1\"\n\t\tdojoAttachEvent=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset\" waiRole=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon\" dojoAttachPoint=\"iconNode\">\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" dojoAttachPoint=\"containerNode\"></td>\n\t<td class [...]
+
+		attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
+			label: { node: "containerNode", type: "innerHTML" },
+			iconClass: { node: "iconNode", type: "class" }
+		}),
+
+		// label: String
+		//		Menu text
+		label: '',
+
+		// iconClass: String
+		//		Class to apply to DOMNode to make it display an icon.
+		iconClass: "",
+
+		// accelKey: String
+		//		Text for the accelerator (shortcut) key combination.
+		//		Note that although Menu can display accelerator keys there
+		//		is no infrastructure to actually catch and execute these
+		//		accelerators.
+		accelKey: "",
+
+		// disabled: Boolean
+		//		If true, the menu item is disabled.
+		//		If false, the menu item is enabled.
+		disabled: false,
+
+		_fillContent: function(/*DomNode*/ source){
+			// If button label is specified as srcNodeRef.innerHTML rather than
+			// this.params.label, handle it here.
+			if(source && !("label" in this.params)){
+				this.attr('label', source.innerHTML);
+			}
+		},
+
+		postCreate: function(){
+			dojo.setSelectable(this.domNode, false);
+			dojo.attr(this.containerNode, "id", this.id+"_text");
+			dijit.setWaiState(this.domNode, "labelledby", this.id+"_text");
+		},
+
+		_onHover: function(){
+			// summary:
+			//		Handler when mouse is moved onto menu item
+			// tags:
+			//		protected
+			dojo.addClass(this.domNode, 'dijitMenuItemHover');
+			this.getParent().onItemHover(this);
+		},
+
+		_onUnhover: function(){
+			// summary:
+			//		Handler when mouse is moved off of menu item,
+			//		possibly to a child menu, or maybe to a sibling
+			//		menuitem or somewhere else entirely.
+			// tags:
+			//		protected
+
+			// if we are unhovering the currently selected item
+			// then unselect it
+			dojo.removeClass(this.domNode, 'dijitMenuItemHover');
+			this.getParent().onItemUnhover(this);
+		},
+
+		_onClick: function(evt){
+			// summary:
+			//		Internal handler for click events on MenuItem.
+			// tags:
+			//		private
+			this.getParent().onItemClick(this, evt);
+			dojo.stopEvent(evt);
+		},
+
+		onClick: function(/*Event*/ evt){
+			// summary:
+			//		User defined function to handle clicks
+			// tags:
+			//		callback
+		},
+
+		focus: function(){
+			// summary:
+			//		Focus on this MenuItem
+			try{
+				dijit.focus(this.focusNode);
+			}catch(e){
+				// this throws on IE (at least) in some scenarios
+			}
+		},
+
+		_onFocus: function(){
+			// summary:
+			//		This is called by the focus manager when focus
+			//		goes to this MenuItem or a child menu.
+			// tags:
+			//		protected
+			this._setSelected(true);
+
+			// TODO: this.inherited(arguments);
+		},
+
+		_setSelected: function(selected){
+			// summary:
+			//		Indicate that this node is the currently selected one
+			// tags:
+			//		private
+
+			/***
+			 * TODO: remove this method and calls to it, when _onBlur() is working for MenuItem.
+			 * Currently _onBlur() gets called when focus is moved from the MenuItem to a child menu.
+			 * That's not supposed to happen, but the problem is:
+			 * In order to allow dijit.popup's getTopPopup() to work,a sub menu's popupParent
+			 * points to the parent Menu, bypassing the parent MenuItem... thus the
+			 * MenuItem is not in the chain of active widgets and gets a premature call to
+			 * _onBlur()
+			 */
+			
+			dojo.toggleClass(this.domNode, "dijitMenuItemSelected", selected);
+		},
+
+		setLabel: function(/*String*/ content){
+			// summary:
+			//		Deprecated.   Use attr('label', ...) instead.
+			// tags:
+			//		deprecated
+			dojo.deprecated("dijit.MenuItem.setLabel() is deprecated.  Use attr('label', ...) instead.", "", "2.0");
+			this.attr("label", content);
+		},
+
+		setDisabled: function(/*Boolean*/ disabled){
+			// summary:
+			//		Deprecated.   Use attr('disabled', bool) instead.
+			// tags:
+			//		deprecated
+			dojo.deprecated("dijit.Menu.setDisabled() is deprecated.  Use attr('disabled', bool) instead.", "", "2.0");
+			this.attr('disabled', disabled);
+		},
+		_setDisabledAttr: function(/*Boolean*/ value){
+			// summary:
+			//		Hook for attr('disabled', ...) to work.
+			//		Enable or disable this menu item.
+			this.disabled = value;
+			dojo[value ? "addClass" : "removeClass"](this.domNode, 'dijitMenuItemDisabled');
+			dijit.setWaiState(this.focusNode, 'disabled', value ? 'true' : 'false');
+		},
+		_setAccelKeyAttr: function(/*String*/ value){
+			// summary:
+			//		Hook for attr('accelKey', ...) to work.
+			//		Set accelKey on this menu item.
+			this.accelKey=value;
+
+			this.accelKeyNode.style.display=value?"":"none";
+			this.accelKeyNode.innerHTML=value;
+			//have to use colSpan to make it work in IE
+			dojo.attr(this.containerNode,'colSpan',value?"1":"2");
+		}
+	});
+
+}
+
+if(!dojo._hasResource["dijit.PopupMenuItem"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.PopupMenuItem"] = true;
+dojo.provide("dijit.PopupMenuItem");
+
+
+
+dojo.declare("dijit.PopupMenuItem",
+		dijit.MenuItem,
+		{
+		_fillContent: function(){
+			// summary: 
+			//		When Menu is declared in markup, this code gets the menu label and
+			//		the popup widget from the srcNodeRef.
+			// description:
+			//		srcNodeRefinnerHTML contains both the menu item text and a popup widget
+			//		The first part holds the menu item text and the second part is the popup
+			// example: 
+			// |	<div dojoType="dijit.PopupMenuItem">
+			// |		<span>pick me</span>
+			// |		<popup> ... </popup>
+			// |	</div>
+			// tags:
+			//		protected
+
+			if(this.srcNodeRef){
+				var nodes = dojo.query("*", this.srcNodeRef);
+				dijit.PopupMenuItem.superclass._fillContent.call(this, nodes[0]);
+
+				// save pointer to srcNode so we can grab the drop down widget after it's instantiated
+				this.dropDownContainer = this.srcNodeRef;
+			}
+		},
+
+		startup: function(){
+			if(this._started){ return; }
+			this.inherited(arguments);
+
+			// we didn't copy the dropdown widget from the this.srcNodeRef, so it's in no-man's
+			// land now.  move it to dojo.doc.body.
+			if(!this.popup){
+				var node = dojo.query("[widgetId]", this.dropDownContainer)[0];
+				this.popup = dijit.byNode(node);
+			}
+			dojo.body().appendChild(this.popup.domNode);
+
+			this.popup.domNode.style.display="none";
+			if(this.arrowWrapper){
+				dojo.style(this.arrowWrapper, "visibility", "");
+			}
+			dijit.setWaiState(this.focusNode, "haspopup", "true");
+		},
+		
+		destroyDescendants: function(){
+			if(this.popup){
+				this.popup.destroyRecursive();
+				delete this.popup;
+			}
+			this.inherited(arguments);
+		}
+	});
+
+
+}
+
+if(!dojo._hasResource["dijit.CheckedMenuItem"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.CheckedMenuItem"] = true;
+dojo.provide("dijit.CheckedMenuItem");
+
+
+
+dojo.declare("dijit.CheckedMenuItem",
+		dijit.MenuItem,
+		{
+		// summary:
+		//		A checkbox-like menu item for toggling on and off
+		
+		templateString:"<tr class=\"dijitReset dijitMenuItem\" dojoAttachPoint=\"focusNode\" waiRole=\"menuitemcheckbox\" tabIndex=\"-1\"\n\t\tdojoAttachEvent=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset\" waiRole=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon dijitCheckedMenuItemIcon\" dojoAttachPoint=\"iconNode\">\n\t\t<span class=\"dijitCheckedMenuItemIconChar\">✓</span>\n\t</td>\n\t<td class=\ [...]
+
+		// checked: Boolean
+		//		Our checked state
+		checked: false,
+		_setCheckedAttr: function(/*Boolean*/ checked){
+			// summary:
+			//		Hook so attr('checked', bool) works.
+			//		Sets the class and state for the check box.
+			dojo.toggleClass(this.domNode, "dijitCheckedMenuItemChecked", checked);
+			dijit.setWaiState(this.domNode, "checked", checked);
+			this.checked = checked;
+		},
+
+		onChange: function(/*Boolean*/ checked){
+			// summary:
+			//		User defined function to handle check/uncheck events
+			// tags:
+			//		callback
+		},
+
+		_onClick: function(/*Event*/ e){
+			// summary:
+			//		Clicking this item just toggles its state
+			// tags:
+			//		private
+			if(!this.disabled){
+				this.attr("checked", !this.checked);
+				this.onChange(this.checked);
+			}
+			this.inherited(arguments);
+		}
+	});
+
+}
+
+if(!dojo._hasResource["dijit.MenuSeparator"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.MenuSeparator"] = true;
+dojo.provide("dijit.MenuSeparator");
+
+
+
+
+
+dojo.declare("dijit.MenuSeparator",
+		[dijit._Widget, dijit._Templated, dijit._Contained],
+		{
+		// summary:
+		//		A line between two menu items
+
+		templateString:"<tr class=\"dijitMenuSeparator\">\n\t<td colspan=\"4\">\n\t\t<div class=\"dijitMenuSeparatorTop\"></div>\n\t\t<div class=\"dijitMenuSeparatorBottom\"></div>\n\t</td>\n</tr>\n",
+
+		postCreate: function(){
+			dojo.setSelectable(this.domNode, false);
+		},
+		
+		isFocusable: function(){
+			// summary:
+			//		Override to always return false
+			// tags:
+			//		protected
+
+			return false; // Boolean
+		}
+	});
+
+
+}
+
+if(!dojo._hasResource["dijit.Menu"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.Menu"] = true;
+dojo.provide("dijit.Menu");
+
+
+
+
+
+dojo.declare("dijit._MenuBase",
+	[dijit._Widget, dijit._Templated, dijit._KeyNavContainer],
+{
+	// summary:
+	//		Base class for Menu and MenuBar
+
+	// parentMenu: [readonly] Widget
+	//		pointer to menu that displayed me
+	parentMenu: null,
+
+	// popupDelay: Integer
+	//		number of milliseconds before hovering (without clicking) causes the popup to automatically open.
+	popupDelay: 500,
+
+	startup: function(){
+		if(this._started){ return; }
+
+		dojo.forEach(this.getChildren(), function(child){ child.startup(); });
+		this.startupKeyNavChildren();
+
+		this.inherited(arguments);
+	},
+
+	onExecute: function(){
+		// summary:
+		//		Attach point for notification about when a menu item has been executed.
+		//		This is an internal mechanism used for Menus to signal to their parent to
+		//		close them, because they are about to execute the onClick handler.   In
+		//		general developers should not attach to or override this method.
+		// tags:
+		//		protected
+	},
+
+	onCancel: function(/*Boolean*/ closeAll){
+		// summary:
+		//		Attach point for notification about when the user cancels the current menu
+		//		This is an internal mechanism used for Menus to signal to their parent to
+		//		close them.  In general developers should not attach to or override this method.
+		// tags:
+		//		protected
+	},
+
+	_moveToPopup: function(/*Event*/ evt){
+		// summary:
+		//		This handles the right arrow key (left arrow key on RTL systems),
+		//		which will either open a submenu, or move to the next item in the
+		//		ancestor MenuBar
+		// tags:
+		//		private
+
+		if(this.focusedChild && this.focusedChild.popup && !this.focusedChild.disabled){
+			this.focusedChild._onClick(evt);
+		}else{
+			var topMenu = this._getTopMenu();
+			if(topMenu && topMenu._isMenuBar){
+				topMenu.focusNext();
+			}
+		}
+	},
+
+	onItemHover: function(/*MenuItem*/ item){
+		// summary:
+		//		Called when cursor is over a MenuItem.
+		// tags:
+		//		protected
+
+		// Don't do anything unless user has "activated" the menu by:
+		//		1) clicking it
+		//		2) tabbing into it
+		//		3) opening it from a parent menu (which automatically focuses it)
+		if(this.isActive){
+			this.focusChild(item);
+	
+			if(this.focusedChild.popup && !this.focusedChild.disabled && !this.hover_timer){
+				this.hover_timer = setTimeout(dojo.hitch(this, "_openPopup"), this.popupDelay);
+			}
+		}
+	},
+
+	_onChildBlur: function(item){
+		// summary:
+		//		Called when a child MenuItem becomes inactive because focus
+		//		has been removed from the MenuItem *and* it's descendant menus.
+		// tags:
+		//		private
+
+		item._setSelected(false);
+
+		// Close all popups that are open and descendants of this menu
+		dijit.popup.close(item.popup);
+		this._stopPopupTimer();
+	},
+
+	onItemUnhover: function(/*MenuItem*/ item){
+		// summary:
+		//		Callback fires when mouse exits a MenuItem
+		// tags:
+		//		protected
+		if(this.isActive){
+			this._stopPopupTimer();
+		}
+	},
+
+	_stopPopupTimer: function(){
+		// summary:
+		//		Cancels the popup timer because the user has stop hovering
+		//		on the MenuItem, etc.
+		// tags:
+		//		private
+		if(this.hover_timer){
+			clearTimeout(this.hover_timer);
+			this.hover_timer = null;
+		}
+	},
+
+	_getTopMenu: function(){
+		// summary:
+		//		Returns the top menu in this chain of Menus
+		// tags:
+		//		private
+		for(var top=this; top.parentMenu; top=top.parentMenu);
+		return top;
+	},
+
+	onItemClick: function(/*Widget*/ item, /*Event*/ evt){
+		// summary:
+		//		Handle clicks on an item.
+		// tags:
+		//		private
+		if(item.disabled){ return false; }
+
+		this.focusChild(item);
+
+		if(item.popup){
+			if(!this.is_open){
+				this._openPopup();
+			}
+		}else{
+			// before calling user defined handler, close hierarchy of menus
+			// and restore focus to place it was when menu was opened
+			this.onExecute();
+
+			// user defined handler for click
+			item.onClick(evt);
+		}
+	},
+
+	_openPopup: function(){
+		// summary:
+		//		Open the popup to the side of/underneath the current menu item
+		// tags:
+		//		protected
+
+		this._stopPopupTimer();
+		var from_item = this.focusedChild;
+		var popup = from_item.popup;
+
+		if(popup.isShowingNow){ return; }
+		popup.parentMenu = this;
+		var self = this;
+		dijit.popup.open({
+			parent: this,
+			popup: popup,
+			around: from_item.domNode,
+			orient: this._orient || (this.isLeftToRight() ? {'TR': 'TL', 'TL': 'TR'} : {'TL': 'TR', 'TR': 'TL'}),
+			onCancel: function(){
+				// called when the child menu is canceled
+				dijit.popup.close(popup);
+				from_item.focus();	// put focus back on my node
+				self.currentPopup = null;
+			},
+			onExecute: dojo.hitch(this, "_onDescendantExecute")
+		});
+
+		this.currentPopup = popup;
+
+		if(popup.focus){
+			// If user is opening the popup via keyboard (right arrow, or down arrow for MenuBar),
+			// if the cursor happens to collide with the popup, it will generate an onmouseover event
+			// even though the mouse wasn't moved.   Use a setTimeout() to call popup.focus so that
+			// our focus() call overrides the onmouseover event, rather than vice-versa.  (#8742)
+			setTimeout(dojo.hitch(popup, "focus"), 0);
+		}
+	},
+
+	onOpen: function(/*Event*/ e){
+		// summary:
+		//		Callback when this menu is opened.
+		//		This is called by the popup manager as notification that the menu
+		//		was opened.
+		// tags:
+		//		private
+
+		this.isShowingNow = true;
+	},
+
+	onClose: function(){
+		// summary:
+		//		Callback when this menu is closed.
+		//		This is called by the popup manager as notification that the menu
+		//		was closed.
+		// tags:
+		//		private
+
+		this._stopPopupTimer();
+		this.parentMenu = null;
+		this.isShowingNow = false;
+		this.currentPopup = null;
+		if(this.focusedChild){
+			this._onChildBlur(this.focusedChild);
+			this.focusedChild = null;
+		}
+	},
+
+	_onFocus: function(){
+		// summary:
+		//		Called when this Menu gets focus from:
+		//			1) clicking it
+		//			2) tabbing into it
+		//			3) being opened by a parent menu.
+		//		This is not called just from mouse hover.
+		// tags:
+		//		protected
+		this.isActive = true;
+		dojo.addClass(this.domNode, "dijitMenuActive");
+		dojo.removeClass(this.domNode, "dijitMenuPassive");
+		this.inherited(arguments);
+	},
+	
+	_onBlur: function(){
+		// summary:
+		//		Called when focus is moved away from this Menu and it's submenus.
+		// tags:
+		//		protected
+		this.isActive = false;
+		dojo.removeClass(this.domNode, "dijitMenuActive");
+		dojo.addClass(this.domNode, "dijitMenuPassive");
+
+		// If user blurs/clicks away from a MenuBar (or always visible Menu), then close all popped up submenus etc.
+		this.onClose();
+
+		this.inherited(arguments);
+	},
+
+	_onDescendantExecute: function(){
+		// summary:
+		//		Called when submenu is clicked.  Close hierarchy of menus.
+		// tags:
+		//		private
+		this.onClose();
+	}
+});
+
+dojo.declare("dijit.Menu",
+	dijit._MenuBase,
+	{
+	// summary
+	//		A context menu you can assign to multiple elements
+
+	// TODO: most of the code in here is just for context menu (right-click menu)
+	// support.  In retrospect that should have been a separate class (dijit.ContextMenu).
+	// Split them for 2.0
+
+	constructor: function(){
+		this._bindings = [];
+	},
+
+	templateString:"<table class=\"dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable\" waiRole=\"menu\" tabIndex=\"${tabIndex}\" dojoAttachEvent=\"onkeypress:_onKeyPress\">\n\t<tbody class=\"dijitReset\" dojoAttachPoint=\"containerNode\"></tbody>\n</table>\n",
+
+	// targetNodeIds: [const] String[]
+	//		Array of dom node ids of nodes to attach to.
+	//		Fill this with nodeIds upon widget creation and it becomes context menu for those nodes.
+	targetNodeIds: [],
+
+	// contextMenuForWindow: [const] Boolean
+	//		If true, right clicking anywhere on the window will cause this context menu to open.
+	//		If false, must specify targetNodeIds.
+	contextMenuForWindow: false,
+
+	// leftClickToOpen: [const] Boolean
+	//		If true, menu will open on left click instead of right click, similiar to a file menu.
+	leftClickToOpen: false,
+	
+	// _contextMenuWithMouse: [private] Boolean
+	//		Used to record mouse and keyboard events to determine if a context
+	//		menu is being opened with the keyboard or the mouse.
+	_contextMenuWithMouse: false,
+
+	postCreate: function(){
+		if(this.contextMenuForWindow){
+			this.bindDomNode(dojo.body());
+		}else{
+			dojo.forEach(this.targetNodeIds, this.bindDomNode, this);
+		}
+		var k = dojo.keys, l = this.isLeftToRight();
+		this._openSubMenuKey = l ? k.RIGHT_ARROW : k.LEFT_ARROW;
+		this._closeSubMenuKey = l ? k.LEFT_ARROW : k.RIGHT_ARROW;
+		this.connectKeyNavHandlers([k.UP_ARROW], [k.DOWN_ARROW]);
+	},
+
+	_onKeyPress: function(/*Event*/ evt){
+		// summary:
+		//		Handle keyboard based menu navigation.
+		// tags:
+		//		protected
+
+		if(evt.ctrlKey || evt.altKey){ return; }
+
+		switch(evt.charOrCode){
+			case this._openSubMenuKey:
+				this._moveToPopup(evt);
+				dojo.stopEvent(evt);
+				break;
+			case this._closeSubMenuKey:
+				if(this.parentMenu){
+					if(this.parentMenu._isMenuBar){
+						this.parentMenu.focusPrev();
+					}else{
+						this.onCancel(false);
+					}
+				}else{
+					dojo.stopEvent(evt);
+				}
+				break;
+		}
+	},
+
+	// thanks burstlib!
+	_iframeContentWindow: function(/* HTMLIFrameElement */iframe_el){
+		// summary:
+		//		Returns the window reference of the passed iframe
+		// tags:
+		//		private
+		var win = dijit.getDocumentWindow(dijit.Menu._iframeContentDocument(iframe_el)) ||
+			// Moz. TODO: is this available when defaultView isn't?
+			dijit.Menu._iframeContentDocument(iframe_el)['__parent__'] ||
+			(iframe_el.name && dojo.doc.frames[iframe_el.name]) || null;
+		return win;	//	Window
+	},
+
+	_iframeContentDocument: function(/* HTMLIFrameElement */iframe_el){
+		// summary:
+		//		Returns a reference to the document object inside iframe_el
+		// tags:
+		//		protected
+		var doc = iframe_el.contentDocument // W3
+			|| (iframe_el.contentWindow && iframe_el.contentWindow.document) // IE
+			|| (iframe_el.name && dojo.doc.frames[iframe_el.name] && dojo.doc.frames[iframe_el.name].document)
+			|| null;
+		return doc;	//	HTMLDocument
+	},
+
+	bindDomNode: function(/*String|DomNode*/ node){
+		// summary:
+		//		Attach menu to given node
+		node = dojo.byId(node);
+
+		//TODO: this is to support context popups in Editor.  Maybe this shouldn't be in dijit.Menu
+		var win = dijit.getDocumentWindow(node.ownerDocument);
+		if(node.tagName.toLowerCase()=="iframe"){
+			win = this._iframeContentWindow(node);
+			node = dojo.withGlobal(win, dojo.body);
+		}
+
+		// to capture these events at the top level,
+		// attach to document, not body
+		var cn = (node == dojo.body() ? dojo.doc : node);
+
+		node[this.id] = this._bindings.push([
+			dojo.connect(cn, (this.leftClickToOpen)?"onclick":"oncontextmenu", this, "_openMyself"),
+			dojo.connect(cn, "onkeydown", this, "_contextKey"),
+			dojo.connect(cn, "onmousedown", this, "_contextMouse")
+		]);
+	},
+
+	unBindDomNode: function(/*String|DomNode*/ nodeName){
+		// summary:
+		//		Detach menu from given node
+		var node = dojo.byId(nodeName);
+		if(node){
+			var bid = node[this.id]-1, b = this._bindings[bid];
+			dojo.forEach(b, dojo.disconnect);
+			delete this._bindings[bid];
+		}
+	},
+
+	_contextKey: function(e){
+		// summary:
+		//		Code to handle popping up editor using F10 key rather than mouse
+		// tags:
+		//		private
+		this._contextMenuWithMouse = false;
+		if(e.keyCode == dojo.keys.F10){
+			dojo.stopEvent(e);
+			if(e.shiftKey && e.type=="keydown"){
+				// FF: copying the wrong property from e will cause the system
+				// context menu to appear in spite of stopEvent. Don't know
+				// exactly which properties cause this effect.
+				var _e = { target: e.target, pageX: e.pageX, pageY: e.pageY };
+				_e.preventDefault = _e.stopPropagation = function(){};
+				// IE: without the delay, focus work in "open" causes the system
+				// context menu to appear in spite of stopEvent.
+				window.setTimeout(dojo.hitch(this, function(){ this._openMyself(_e); }), 1);
+			}
+		}
+	},
+
+	_contextMouse: function(e){
+		// summary:
+		//		Helper to remember when we opened the context menu with the mouse instead
+		//		of with the keyboard
+		// tags:
+		//		private
+		this._contextMenuWithMouse = true;
+	},
+
+	_openMyself: function(/*Event*/ e){
+		// summary:
+		//		Internal function for opening myself when the user
+		//		does a right-click or something similar
+		// tags:
+		//		private
+
+		if(this.leftClickToOpen&&e.button>0){
+			return;
+		}
+		dojo.stopEvent(e);
+
+		// Get coordinates.
+		// if we are opening the menu with the mouse or on safari open
+		// the menu at the mouse cursor
+		// (Safari does not have a keyboard command to open the context menu
+		// and we don't currently have a reliable way to determine
+		// _contextMenuWithMouse on Safari)
+		var x,y;
+		if(dojo.isSafari || this._contextMenuWithMouse){
+			x=e.pageX;
+			y=e.pageY;
+		}else{
+			// otherwise open near e.target
+			var coords = dojo.coords(e.target, true);
+			x = coords.x + 10;
+			y = coords.y + 10;
+		}
+
+		var self=this;
+		var savedFocus = dijit.getFocus(this);
+		function closeAndRestoreFocus(){
+			// user has clicked on a menu or popup
+			dijit.focus(savedFocus);
+			dijit.popup.close(self);
+		}
+		dijit.popup.open({
+			popup: this,
+			x: x,
+			y: y,
+			onExecute: closeAndRestoreFocus,
+			onCancel: closeAndRestoreFocus,
+			orient: this.isLeftToRight() ? 'L' : 'R'
+		});
+		this.focus();
+
+		this._onBlur = function(){
+			this.inherited('_onBlur', arguments);
+			// Usually the parent closes the child widget but if this is a context
+			// menu then there is no parent
+			dijit.popup.close(this);
+			// don't try to restore focus; user has clicked another part of the screen
+			// and set focus there
+		};
+	},
+
+	uninitialize: function(){
+ 		dojo.forEach(this.targetNodeIds, this.unBindDomNode, this);
+ 		this.inherited(arguments);
+	}
+}
+);
+
+// Back-compat (TODO: remove in 2.0)
+
+
+
+
+
+
+}
+
+if(!dojo._hasResource["dijit.MenuBar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.MenuBar"] = true;
+dojo.provide("dijit.MenuBar");
+
+
+
+dojo.declare("dijit.MenuBar", dijit._MenuBase, {
+	// summary:
+	//		A menu bar, listing menu choices horizontally, like the "File" menu in most desktop applications
+
+	templateString:"<div class=\"dijitMenuBar dijitMenuPassive\" dojoAttachPoint=\"containerNode\"  waiRole=\"menubar\" tabIndex=\"${tabIndex}\" dojoAttachEvent=\"onkeypress: _onKeyPress\"></div>\n",
+
+	// _isMenuBar: [protected] Boolean
+	//		This is a MenuBar widget, not a (vertical) Menu widget.
+	_isMenuBar: true,
+
+	constructor: function(){
+		// summary:
+		//		Sets up local variables etc.
+		// tags:
+		//		private
+
+		// parameter to dijit.popup.open() about where to put popup (relative to this.domNode)
+		this._orient = this.isLeftToRight() ? {BL: 'TL'} : {BR: 'TR'};
+	},
+
+	postCreate: function(){
+		var k = dojo.keys, l = this.isLeftToRight();
+		this.connectKeyNavHandlers(
+			l ? [k.LEFT_ARROW] : [k.RIGHT_ARROW],
+			l ? [k.RIGHT_ARROW] : [k.LEFT_ARROW]
+		);
+	},
+
+	focusChild: function(item){
+		// overload focusChild so that whenever the focus is moved to a new item,
+		// check the previous focused whether it has its popup open, if so, after 
+		// focusing the new item, open its submenu immediately
+		var from_item = this.focusedChild,
+			showpopup = from_item && from_item.popup && from_item.popup.isShowingNow;
+		this.inherited(arguments);
+		if(showpopup && !item.disabled){
+			this._openPopup();		// TODO: on down arrow, _openPopup() is called here and in onItemClick()
+		}
+	},
+	
+	_onKeyPress: function(/*Event*/ evt){
+		// summary:
+		//		Handle keyboard based menu navigation.
+		// tags:
+		//		protected
+
+		if(evt.ctrlKey || evt.altKey){ return; }
+
+		switch(evt.charOrCode){
+			case dojo.keys.DOWN_ARROW:
+				this._moveToPopup(evt);
+				dojo.stopEvent(evt);
+		}
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit.MenuBarItem"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.MenuBarItem"] = true;
+dojo.provide("dijit.MenuBarItem");
+
+
+
+dojo.declare("dijit._MenuBarItemMixin", null, {
+	templateString:"<div class=\"dijitReset dijitInline dijitMenuItem dijitMenuItemLabel\" dojoAttachPoint=\"focusNode\" waiRole=\"menuitem\" tabIndex=\"-1\"'\n\t\tdojoAttachEvent=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<span dojoAttachPoint=\"containerNode\"></span>\n</div>\n",
+
+	// overriding attributeMap because we don't have icon
+	attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
+		label: { node: "containerNode", type: "innerHTML" }
+	})
+});
+
+dojo.declare("dijit.MenuBarItem", [dijit.MenuItem, dijit._MenuBarItemMixin], {
+	// summary:
+	//		Item in a MenuBar that's clickable, and doesn't spawn a submenu when pressed (or hovered)
+		
+});
+
+}
+
+if(!dojo._hasResource["dijit.PopupMenuBarItem"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.PopupMenuBarItem"] = true;
+dojo.provide("dijit.PopupMenuBarItem");
+
+
+
+
+dojo.declare("dijit.PopupMenuBarItem", [dijit.PopupMenuItem, dijit._MenuBarItemMixin], {
+	// summary:
+	//		Item in a MenuBar like "File" or "Edit", that spawns a submenu when pressed (or hovered)
+});
+
+
+}
+
+if(!dojo._hasResource["dojo.regexp"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.regexp"] = true;
+dojo.provide("dojo.regexp");
+
+/*=====
+dojo.regexp = {
+	// summary: Regular expressions and Builder resources
+};
+=====*/
+
+dojo.regexp.escapeString = function(/*String*/str, /*String?*/except){
+	//	summary:
+	//		Adds escape sequences for special characters in regular expressions
+	// except:
+	//		a String with special characters to be left unescaped
+
+	return str.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, function(ch){
+		if(except && except.indexOf(ch) != -1){
+			return ch;
+		}
+		return "\\" + ch;
+	}); // String
+}
+
+dojo.regexp.buildGroupRE = function(/*Object|Array*/arr, /*Function*/re, /*Boolean?*/nonCapture){
+	//	summary:
+	//		Builds a regular expression that groups subexpressions
+	//	description:
+	//		A utility function used by some of the RE generators. The
+	//		subexpressions are constructed by the function, re, in the second
+	//		parameter.  re builds one subexpression for each elem in the array
+	//		a, in the first parameter. Returns a string for a regular
+	//		expression that groups all the subexpressions.
+	// arr:
+	//		A single value or an array of values.
+	// re:
+	//		A function. Takes one parameter and converts it to a regular
+	//		expression. 
+	// nonCapture:
+	//		If true, uses non-capturing match, otherwise matches are retained
+	//		by regular expression. Defaults to false
+
+	// case 1: a is a single value.
+	if(!(arr instanceof Array)){
+		return re(arr); // String
+	}
+
+	// case 2: a is an array
+	var b = [];
+	for(var i = 0; i < arr.length; i++){
+		// convert each elem to a RE
+		b.push(re(arr[i]));
+	}
+
+	 // join the REs as alternatives in a RE group.
+	return dojo.regexp.group(b.join("|"), nonCapture); // String
+}
+
+dojo.regexp.group = function(/*String*/expression, /*Boolean?*/nonCapture){
+	// summary:
+	//		adds group match to expression
+	// nonCapture:
+	//		If true, uses non-capturing match, otherwise matches are retained
+	//		by regular expression. 
+	return "(" + (nonCapture ? "?:":"") + expression + ")"; // String
+}
+
+}
+
+if(!dojo._hasResource["dojo.number"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.number"] = true;
+dojo.provide("dojo.number");
+
+
+
+
+
+
+
+/*=====
+dojo.number = {
+	// summary: localized formatting and parsing routines for Number
+}
+
+dojo.number.__FormatOptions = function(){
+	//	pattern: String?
+	//		override [formatting pattern](http://www.unicode.org/reports/tr35/#Number_Format_Patterns)
+	//		with this string
+	//	type: String?
+	//		choose a format type based on the locale from the following:
+	//		decimal, scientific, percent, currency. decimal by default.
+	//	places: Number?
+	//		fixed number of decimal places to show.  This overrides any
+	//		information in the provided pattern.
+	//	round: Number?
+	//		5 rounds to nearest .5; 0 rounds to nearest whole (default). -1
+	//		means do not round.
+	//	currency: String?
+	//		an [ISO4217](http://en.wikipedia.org/wiki/ISO_4217) currency code, a three letter sequence like "USD"
+	//	symbol: String?
+	//		localized currency symbol
+	//	locale: String?
+	//		override the locale used to determine formatting rules
+	this.pattern = pattern;
+	this.type = type;
+	this.places = places;
+	this.round = round;
+	this.currency = currency;
+	this.symbol = symbol;
+	this.locale = locale;
+}
+=====*/
+
+dojo.number.format = function(/*Number*/value, /*dojo.number.__FormatOptions?*/options){
+	// summary:
+	//		Format a Number as a String, using locale-specific settings
+	// description:
+	//		Create a string from a Number using a known localized pattern.
+	//		Formatting patterns appropriate to the locale are chosen from the
+	//		[CLDR](http://unicode.org/cldr) as well as the appropriate symbols and
+	//		delimiters.  See <http://www.unicode.org/reports/tr35/#Number_Elements>
+	//		If value is Infinity, -Infinity, or is not a valid JavaScript number, return null.
+	// value:
+	//		the number to be formatted
+
+	options = dojo.mixin({}, options || {});
+	var locale = dojo.i18n.normalizeLocale(options.locale);
+	var bundle = dojo.i18n.getLocalization("dojo.cldr", "number", locale);
+	options.customs = bundle;
+	var pattern = options.pattern || bundle[(options.type || "decimal") + "Format"];
+	if(isNaN(value) || Math.abs(value) == Infinity){ return null; } // null
+	return dojo.number._applyPattern(value, pattern, options); // String
+};
+
+//dojo.number._numberPatternRE = /(?:[#0]*,?)*[#0](?:\.0*#*)?/; // not precise, but good enough
+dojo.number._numberPatternRE = /[#0,]*[#0](?:\.0*#*)?/; // not precise, but good enough
+
+dojo.number._applyPattern = function(/*Number*/value, /*String*/pattern, /*dojo.number.__FormatOptions?*/options){
+	// summary:
+	//		Apply pattern to format value as a string using options. Gives no
+	//		consideration to local customs.
+	// value:
+	//		the number to be formatted.
+	// pattern:
+	//		a pattern string as described by
+	//		[unicode.org TR35](http://www.unicode.org/reports/tr35/#Number_Format_Patterns)
+	// options: dojo.number.__FormatOptions?
+	//		_applyPattern is usually called via `dojo.number.format()` which
+	//		populates an extra property in the options parameter, "customs".
+	//		The customs object specifies group and decimal parameters if set.
+
+	//TODO: support escapes
+	options = options || {};
+	var group = options.customs.group;
+	var decimal = options.customs.decimal;
+
+	var patternList = pattern.split(';');
+	var positivePattern = patternList[0];
+	pattern = patternList[(value < 0) ? 1 : 0] || ("-" + positivePattern);
+
+	//TODO: only test against unescaped
+	if(pattern.indexOf('%') != -1){
+		value *= 100;
+	}else if(pattern.indexOf('\u2030') != -1){
+		value *= 1000; // per mille
+	}else if(pattern.indexOf('\u00a4') != -1){
+		group = options.customs.currencyGroup || group;//mixins instead?
+		decimal = options.customs.currencyDecimal || decimal;// Should these be mixins instead?
+		pattern = pattern.replace(/\u00a4{1,3}/, function(match){
+			var prop = ["symbol", "currency", "displayName"][match.length-1];
+			return options[prop] || options.currency || "";
+		});
+	}else if(pattern.indexOf('E') != -1){
+		throw new Error("exponential notation not supported");
+	}
+	
+	//TODO: support @ sig figs?
+	var numberPatternRE = dojo.number._numberPatternRE;
+	var numberPattern = positivePattern.match(numberPatternRE);
+	if(!numberPattern){
+		throw new Error("unable to find a number expression in pattern: "+pattern);
+	}
+	if(options.fractional === false){ options.places = 0; }
+	return pattern.replace(numberPatternRE,
+		dojo.number._formatAbsolute(value, numberPattern[0], {decimal: decimal, group: group, places: options.places, round: options.round}));
+}
+
+dojo.number.round = function(/*Number*/value, /*Number?*/places, /*Number?*/increment){
+	//	summary:
+	//		Rounds to the nearest value with the given number of decimal places, away from zero
+	//	description:
+	//		Rounds to the nearest value with the given number of decimal places, away from zero if equal.
+	//		Similar to Number.toFixed(), but compensates for browser quirks. Rounding can be done by
+	//		fractional increments also, such as the nearest quarter.
+	//		NOTE: Subject to floating point errors.  See dojox.math.round for experimental workaround.
+	//	value:
+	//		The number to round
+	//	places:
+	//		The number of decimal places where rounding takes place.  Defaults to 0 for whole rounding.
+	//		Must be non-negative.
+	//	increment:
+	//		Rounds next place to nearest value of increment/10.  10 by default.
+	//	example:
+	//		>>> dojo.number.round(-0.5)
+	//		-1
+	//		>>> dojo.number.round(162.295, 2)
+	//		162.29  // note floating point error.  Should be 162.3
+	//		>>> dojo.number.round(10.71, 0, 2.5)
+	//		10.75
+	var factor = 10 / (increment || 10);
+	return (factor * +value).toFixed(places) / factor; // Number
+}
+
+if((0.9).toFixed() == 0){
+	// (isIE) toFixed() bug workaround: Rounding fails on IE when most significant digit
+	// is just after the rounding place and is >=5
+	(function(){
+		var round = dojo.number.round;
+		dojo.number.round = function(v, p, m){
+			var d = Math.pow(10, -p || 0), a = Math.abs(v);
+			if(!v || a >= d || a * Math.pow(10, p + 1) < 5){
+				d = 0;
+			}
+			return round(v, p, m) + (v > 0 ? d : -d);
+		}
+	})();
+}
+
+/*=====
+dojo.number.__FormatAbsoluteOptions = function(){
+	//	decimal: String?
+	//		the decimal separator
+	//	group: String?
+	//		the group separator
+	//	places: Integer?|String?
+	//		number of decimal places.  the range "n,m" will format to m places.
+	//	round: Number?
+	//		5 rounds to nearest .5; 0 rounds to nearest whole (default). -1
+	//		means don't round.
+	this.decimal = decimal;
+	this.group = group;
+	this.places = places;
+	this.round = round;
+}
+=====*/
+
+dojo.number._formatAbsolute = function(/*Number*/value, /*String*/pattern, /*dojo.number.__FormatAbsoluteOptions?*/options){
+	// summary: 
+	//		Apply numeric pattern to absolute value using options. Gives no
+	//		consideration to local customs.
+	// value:
+	//		the number to be formatted, ignores sign
+	// pattern:
+	//		the number portion of a pattern (e.g. `#,##0.00`)
+	options = options || {};
+	if(options.places === true){options.places=0;}
+	if(options.places === Infinity){options.places=6;} // avoid a loop; pick a limit
+
+	var patternParts = pattern.split(".");
+	var maxPlaces = (options.places >= 0) ? options.places : (patternParts[1] && patternParts[1].length) || 0;
+	if(!(options.round < 0)){
+		value = dojo.number.round(value, maxPlaces, options.round);
+	}
+
+	var valueParts = String(Math.abs(value)).split(".");
+	var fractional = valueParts[1] || "";
+	if(options.places){
+		var comma = dojo.isString(options.places) && options.places.indexOf(",");
+		if(comma){
+			options.places = options.places.substring(comma+1);
+		}
+		valueParts[1] = dojo.string.pad(fractional.substr(0, options.places), options.places, '0', true);
+	}else if(patternParts[1] && options.places !== 0){
+		// Pad fractional with trailing zeros
+		var pad = patternParts[1].lastIndexOf("0") + 1;
+		if(pad > fractional.length){
+			valueParts[1] = dojo.string.pad(fractional, pad, '0', true);
+		}
+
+		// Truncate fractional
+		var places = patternParts[1].length;
+		if(places < fractional.length){
+			valueParts[1] = fractional.substr(0, places);
+		}
+	}else{
+		if(valueParts[1]){ valueParts.pop(); }
+	}
+
+	// Pad whole with leading zeros
+	var patternDigits = patternParts[0].replace(',', '');
+	pad = patternDigits.indexOf("0");
+	if(pad != -1){
+		pad = patternDigits.length - pad;
+		if(pad > valueParts[0].length){
+			valueParts[0] = dojo.string.pad(valueParts[0], pad);
+		}
+
+		// Truncate whole
+		if(patternDigits.indexOf("#") == -1){
+			valueParts[0] = valueParts[0].substr(valueParts[0].length - pad);
+		}
+	}
+
+	// Add group separators
+	var index = patternParts[0].lastIndexOf(',');
+	var groupSize, groupSize2;
+	if(index != -1){
+		groupSize = patternParts[0].length - index - 1;
+		var remainder = patternParts[0].substr(0, index);
+		index = remainder.lastIndexOf(',');
+		if(index != -1){
+			groupSize2 = remainder.length - index - 1;
+		}
+	}
+	var pieces = [];
+	for(var whole = valueParts[0]; whole;){
+		var off = whole.length - groupSize;
+		pieces.push((off > 0) ? whole.substr(off) : whole);
+		whole = (off > 0) ? whole.slice(0, off) : "";
+		if(groupSize2){
+			groupSize = groupSize2;
+			delete groupSize2;
+		}
+	}
+	valueParts[0] = pieces.reverse().join(options.group || ",");
+
+	return valueParts.join(options.decimal || ".");
+};
+
+/*=====
+dojo.number.__RegexpOptions = function(){
+	//	pattern: String?
+	//		override pattern with this string.  Default is provided based on
+	//		locale.
+	//	type: String?
+	//		choose a format type based on the locale from the following:
+	//		decimal, scientific, percent, currency. decimal by default.
+	//	locale: String?
+	//		override the locale used to determine formatting rules
+	//	strict: Boolean?
+	//		strict parsing, false by default
+	//	places: Number|String?
+	//		number of decimal places to accept: Infinity, a positive number, or
+	//		a range "n,m".  Defined by pattern or Infinity if pattern not provided.
+	this.pattern = pattern;
+	this.type = type;
+	this.locale = locale;
+	this.strict = strict;
+	this.places = places;
+}
+=====*/
+dojo.number.regexp = function(/*dojo.number.__RegexpOptions?*/options){
+	//	summary:
+	//		Builds the regular needed to parse a number
+	//	description:
+	//		Returns regular expression with positive and negative match, group
+	//		and decimal separators
+	return dojo.number._parseInfo(options).regexp; // String
+}
+
+dojo.number._parseInfo = function(/*Object?*/options){
+	options = options || {};
+	var locale = dojo.i18n.normalizeLocale(options.locale);
+	var bundle = dojo.i18n.getLocalization("dojo.cldr", "number", locale);
+	var pattern = options.pattern || bundle[(options.type || "decimal") + "Format"];
+//TODO: memoize?
+	var group = bundle.group;
+	var decimal = bundle.decimal;
+	var factor = 1;
+
+	if(pattern.indexOf('%') != -1){
+		factor /= 100;
+	}else if(pattern.indexOf('\u2030') != -1){
+		factor /= 1000; // per mille
+	}else{
+		var isCurrency = pattern.indexOf('\u00a4') != -1;
+		if(isCurrency){
+			group = bundle.currencyGroup || group;
+			decimal = bundle.currencyDecimal || decimal;
+		}
+	}
+
+	//TODO: handle quoted escapes
+	var patternList = pattern.split(';');
+	if(patternList.length == 1){
+		patternList.push("-" + patternList[0]);
+	}
+
+	var re = dojo.regexp.buildGroupRE(patternList, function(pattern){
+		pattern = "(?:"+dojo.regexp.escapeString(pattern, '.')+")";
+		return pattern.replace(dojo.number._numberPatternRE, function(format){
+			var flags = {
+				signed: false,
+				separator: options.strict ? group : [group,""],
+				fractional: options.fractional,
+				decimal: decimal,
+				exponent: false};
+			var parts = format.split('.');
+			var places = options.places;
+			if(parts.length == 1 || places === 0){flags.fractional = false;}
+			else{
+				if(places === undefined){ places = options.pattern ? parts[1].lastIndexOf('0')+1 : Infinity; }
+				if(places && options.fractional == undefined){flags.fractional = true;} // required fractional, unless otherwise specified
+				if(!options.places && (places < parts[1].length)){ places += "," + parts[1].length; }
+				flags.places = places;
+			}
+			var groups = parts[0].split(',');
+			if(groups.length>1){
+				flags.groupSize = groups.pop().length;
+				if(groups.length>1){
+					flags.groupSize2 = groups.pop().length;
+				}
+			}
+			return "("+dojo.number._realNumberRegexp(flags)+")";
+		});
+	}, true);
+
+	if(isCurrency){
+		// substitute the currency symbol for the placeholder in the pattern
+		re = re.replace(/([\s\xa0]*)(\u00a4{1,3})([\s\xa0]*)/g, function(match, before, target, after){
+			var prop = ["symbol", "currency", "displayName"][target.length-1];
+			var symbol = dojo.regexp.escapeString(options[prop] || options.currency || "");
+			before = before ? "[\\s\\xa0]" : "";
+			after = after ? "[\\s\\xa0]" : "";
+			if(!options.strict){
+				if(before){before += "*";}
+				if(after){after += "*";}
+				return "(?:"+before+symbol+after+")?";
+			}
+			return before+symbol+after;
+		});
+	}
+
+//TODO: substitute localized sign/percent/permille/etc.?
+
+	// normalize whitespace and return
+	return {regexp: re.replace(/[\xa0 ]/g, "[\\s\\xa0]"), group: group, decimal: decimal, factor: factor}; // Object
+}
+
+/*=====
+dojo.number.__ParseOptions = function(){
+	//	pattern: String
+	//		override pattern with this string.  Default is provided based on
+	//		locale.
+	//	type: String?
+	//		choose a format type based on the locale from the following:
+	//		decimal, scientific, percent, currency. decimal by default.
+	//	locale: String
+	//		override the locale used to determine formatting rules
+	//	strict: Boolean?
+	//		strict parsing, false by default
+	//	currency: Object
+	//		object with currency information
+	this.pattern = pattern;
+	this.type = type;
+	this.locale = locale;
+	this.strict = strict;
+	this.currency = currency;
+}
+=====*/
+dojo.number.parse = function(/*String*/expression, /*dojo.number.__ParseOptions?*/options){
+	// summary:
+	//		Convert a properly formatted string to a primitive Number, using
+	//		locale-specific settings.
+	// description:
+	//		Create a Number from a string using a known localized pattern.
+	//		Formatting patterns are chosen appropriate to the locale
+	//		and follow the syntax described by
+	//		[unicode.org TR35](http://www.unicode.org/reports/tr35/#Number_Format_Patterns)
+	// expression:
+	//		A string representation of a Number
+	var info = dojo.number._parseInfo(options);
+	var results = (new RegExp("^"+info.regexp+"$")).exec(expression);
+	if(!results){
+		return NaN; //NaN
+	}
+	var absoluteMatch = results[1]; // match for the positive expression
+	if(!results[1]){
+		if(!results[2]){
+			return NaN; //NaN
+		}
+		// matched the negative pattern
+		absoluteMatch =results[2];
+		info.factor *= -1;
+	}
+
+	// Transform it to something Javascript can parse as a number.  Normalize
+	// decimal point and strip out group separators or alternate forms of whitespace
+	absoluteMatch = absoluteMatch.
+		replace(new RegExp("["+info.group + "\\s\\xa0"+"]", "g"), "").
+		replace(info.decimal, ".");
+	// Adjust for negative sign, percent, etc. as necessary
+	return absoluteMatch * info.factor; //Number
+};
+
+/*=====
+dojo.number.__RealNumberRegexpFlags = function(){
+	//	places: Number?
+	//		The integer number of decimal places or a range given as "n,m".  If
+	//		not given, the decimal part is optional and the number of places is
+	//		unlimited.
+	//	decimal: String?
+	//		A string for the character used as the decimal point.  Default
+	//		is ".".
+	//	fractional: Boolean|Array?
+	//		Whether decimal places are allowed.  Can be true, false, or [true,
+	//		false].  Default is [true, false]
+	//	exponent: Boolean|Array?
+	//		Express in exponential notation.  Can be true, false, or [true,
+	//		false]. Default is [true, false], (i.e. will match if the
+	//		exponential part is present are not).
+	//	eSigned: Boolean|Array?
+	//		The leading plus-or-minus sign on the exponent.  Can be true,
+	//		false, or [true, false].  Default is [true, false], (i.e. will
+	//		match if it is signed or unsigned).  flags in regexp.integer can be
+	//		applied.
+	this.places = places;
+	this.decimal = decimal;
+	this.fractional = fractional;
+	this.exponent = exponent;
+	this.eSigned = eSigned;
+}
+=====*/
+
+dojo.number._realNumberRegexp = function(/*dojo.number.__RealNumberRegexpFlags?*/flags){
+	// summary:
+	//		Builds a regular expression to match a real number in exponential
+	//		notation
+
+	// assign default values to missing paramters
+	flags = flags || {};
+	//TODO: use mixin instead?
+	if(!("places" in flags)){ flags.places = Infinity; }
+	if(typeof flags.decimal != "string"){ flags.decimal = "."; }
+	if(!("fractional" in flags) || /^0/.test(flags.places)){ flags.fractional = [true, false]; }
+	if(!("exponent" in flags)){ flags.exponent = [true, false]; }
+	if(!("eSigned" in flags)){ flags.eSigned = [true, false]; }
+
+	// integer RE
+	var integerRE = dojo.number._integerRegexp(flags);
+
+	// decimal RE
+	var decimalRE = dojo.regexp.buildGroupRE(flags.fractional,
+		function(q){
+			var re = "";
+			if(q && (flags.places!==0)){
+				re = "\\" + flags.decimal;
+				if(flags.places == Infinity){ 
+					re = "(?:" + re + "\\d+)?"; 
+				}else{
+					re += "\\d{" + flags.places + "}"; 
+				}
+			}
+			return re;
+		},
+		true
+	);
+
+	// exponent RE
+	var exponentRE = dojo.regexp.buildGroupRE(flags.exponent,
+		function(q){ 
+			if(q){ return "([eE]" + dojo.number._integerRegexp({ signed: flags.eSigned}) + ")"; }
+			return ""; 
+		}
+	);
+
+	// real number RE
+	var realRE = integerRE + decimalRE;
+	// allow for decimals without integers, e.g. .25
+	if(decimalRE){realRE = "(?:(?:"+ realRE + ")|(?:" + decimalRE + "))";}
+	return realRE + exponentRE; // String
+};
+
+/*=====
+dojo.number.__IntegerRegexpFlags = function(){
+	//	signed: Boolean?
+	//		The leading plus-or-minus sign. Can be true, false, or `[true,false]`.
+	//		Default is `[true, false]`, (i.e. will match if it is signed
+	//		or unsigned).
+	//	separator: String?
+	//		The character used as the thousands separator. Default is no
+	//		separator. For more than one symbol use an array, e.g. `[",", ""]`,
+	//		makes ',' optional.
+	//	groupSize: Number?
+	//		group size between separators
+	//	groupSize2: Number?
+	//		second grouping, where separators 2..n have a different interval than the first separator (for India)
+	this.signed = signed;
+	this.separator = separator;
+	this.groupSize = groupSize;
+	this.groupSize2 = groupSize2;
+}
+=====*/
+
+dojo.number._integerRegexp = function(/*dojo.number.__IntegerRegexpFlags?*/flags){
+	// summary: 
+	//		Builds a regular expression that matches an integer
+
+	// assign default values to missing paramters
+	flags = flags || {};
+	if(!("signed" in flags)){ flags.signed = [true, false]; }
+	if(!("separator" in flags)){
+		flags.separator = "";
+	}else if(!("groupSize" in flags)){
+		flags.groupSize = 3;
+	}
+	// build sign RE
+	var signRE = dojo.regexp.buildGroupRE(flags.signed,
+		function(q){ return q ? "[-+]" : ""; },
+		true
+	);
+
+	// number RE
+	var numberRE = dojo.regexp.buildGroupRE(flags.separator,
+		function(sep){
+			if(!sep){
+				return "(?:\\d+)";
+			}
+
+			sep = dojo.regexp.escapeString(sep);
+			if(sep == " "){ sep = "\\s"; }
+			else if(sep == "\xa0"){ sep = "\\s\\xa0"; }
+
+			var grp = flags.groupSize, grp2 = flags.groupSize2;
+			//TODO: should we continue to enforce that numbers with separators begin with 1-9?  See #6933
+			if(grp2){
+				var grp2RE = "(?:0|[1-9]\\d{0," + (grp2-1) + "}(?:[" + sep + "]\\d{" + grp2 + "})*[" + sep + "]\\d{" + grp + "})";
+				return ((grp-grp2) > 0) ? "(?:" + grp2RE + "|(?:0|[1-9]\\d{0," + (grp-1) + "}))" : grp2RE;
+			}
+			return "(?:0|[1-9]\\d{0," + (grp-1) + "}(?:[" + sep + "]\\d{" + grp + "})*)";
+		},
+		true
+	);
+
+	// integer RE
+	return signRE + numberRE; // String
+}
+
+}
+
+if(!dojo._hasResource["dijit.ProgressBar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.ProgressBar"] = true;
+dojo.provide("dijit.ProgressBar");
+
+
+
+
+
+
+
+dojo.declare("dijit.ProgressBar", [dijit._Widget, dijit._Templated], {
+	// summary:
+	//		A progress indication widget, showing the amount completed
+	//		(often the percentage completed) of a task.
+	//
+	// example:
+	// |	<div dojoType="ProgressBar"
+	// |		 places="0"
+	// |		 progress="..." maximum="...">
+	// |	</div>
+	//
+	// description:
+	//		Note that the progress bar is updated via (a non-standard)
+	//		update() method, rather than via attr() like other widgets.
+
+	// progress: [const] String (Percentage or Number)
+	//		Number or percentage indicating amount of task completed.
+	// 		With "%": percentage value, 0% <= progress <= 100%, or
+	// 		without "%": absolute value, 0 <= progress <= maximum
+	// TODO: rename to value for 2.0
+	progress: "0",
+
+	// maximum: [const] Float
+	//		Max sample number
+	maximum: 100,
+
+	// places: [const] Number
+	//		Number of places to show in values; 0 by default
+	places: 0,
+
+	// indeterminate: [const] Boolean
+	// 		If false: show progress value (number or percentage).
+	// 		If true: show that a process is underway but that the amount completed is unknown.
+	indeterminate: false,
+
+	templateString:"<div class=\"dijitProgressBar dijitProgressBarEmpty\"\n\t><div waiRole=\"progressbar\" tabindex=\"0\" dojoAttachPoint=\"internalProgress\" class=\"dijitProgressBarFull\"\n\t\t><div class=\"dijitProgressBarTile\"></div\n\t\t><span style=\"visibility:hidden\"> </span\n\t></div\n\t><div dojoAttachPoint=\"label\" class=\"dijitProgressBarLabel\" id=\"${id}_label\"> </div\n\t><img dojoAttachPoint=\"indeterminateHighContrastImage\" class=\"dijitProgressBarIndeterminat [...]
+
+	// _indeterminateHighContrastImagePath: [private] dojo._URL
+	//		URL to image to use for indeterminate progress bar when display is in high contrast mode
+	_indeterminateHighContrastImagePath:
+		dojo.moduleUrl("dijit", "themes/a11y/indeterminate_progress.gif"),
+
+	// public functions
+	postCreate: function(){
+		this.inherited(arguments);
+		this.indeterminateHighContrastImage.setAttribute("src",
+			this._indeterminateHighContrastImagePath);
+		this.update();
+	},
+
+	update: function(/*Object?*/attributes){
+		// summary:
+		//		Change attributes of ProgressBar, similar to attr(hash).
+		//
+		// attributes:
+		//		May provide progress and/or maximum properties on this parameter;
+		//		see attribute specs for details.
+		//
+		// example:
+		//	|	myProgressBar.update({'indeterminate': true});
+		//	|	myProgressBar.update({'progress': 80});
+
+		// TODO: deprecate this method and use attr() instead
+
+		dojo.mixin(this, attributes || {});
+		var tip = this.internalProgress;
+		var percent = 1, classFunc;
+		if(this.indeterminate){
+			classFunc = "addClass";
+			dijit.removeWaiState(tip, "valuenow");
+			dijit.removeWaiState(tip, "valuemin");
+			dijit.removeWaiState(tip, "valuemax");
+		}else{
+			classFunc = "removeClass";
+			if(String(this.progress).indexOf("%") != -1){
+				percent = Math.min(parseFloat(this.progress)/100, 1);
+				this.progress = percent * this.maximum;
+			}else{
+				this.progress = Math.min(this.progress, this.maximum);
+				percent = this.progress / this.maximum;
+			}
+			var text = this.report(percent);
+			this.label.firstChild.nodeValue = text;
+			dijit.setWaiState(tip, "describedby", this.label.id);
+			dijit.setWaiState(tip, "valuenow", this.progress);
+			dijit.setWaiState(tip, "valuemin", 0);
+			dijit.setWaiState(tip, "valuemax", this.maximum);
+		}
+		dojo[classFunc](this.domNode, "dijitProgressBarIndeterminate");
+		tip.style.width = (percent * 100) + "%";
+		this.onChange();
+	},
+
+	report: function(/*float*/percent){
+		// summary:
+		//		Generates message to show inside progress bar (normally indicating amount of task completed).
+		//		May be overridden.
+		// tags:
+		//		extension
+
+		return dojo.number.format(percent, { type: "percent", places: this.places, locale: this.lang });
+	},
+
+	onChange: function(){
+		// summary:
+		//		Callback fired when progress updates.
+		// tags:
+		//		progress
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit.TitlePane"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.TitlePane"] = true;
+dojo.provide("dijit.TitlePane");
+
+
+
+
+
+
+dojo.declare(
+	"dijit.TitlePane",
+	[dijit.layout.ContentPane, dijit._Templated],
+{
+	// summary:
+	//		A pane with a title on top, that can be expanded or collapsed.
+	//
+	// description:
+	//		An accessible container with a Title Heading, and a content
+	//		section that slides open and closed. TitlePane is an extension to 
+	//		`dijit.layout.ContentPane`, providing all the usesful content-control aspects from it.
+	//
+	// example:
+	// | 	// load a TitlePane from remote file:
+	// |	var foo = new dijit.TitlePane({ href: "foobar.html", title:"Title" });
+	// |	foo.startup();
+	//
+	// example:
+	// |	<!-- markup href example: -->
+	// |	<div dojoType="dijit.TitlePane" href="foobar.html" title="Title"></div>
+	// 
+	// example:
+	// |	<!-- markup with inline data -->
+	// | 	<div dojoType="dijit.TitlePane" title="Title">
+	// |		<p>I am content</p>
+	// |	</div>
+
+	// title: String
+	//		Title of the pane
+	title: "",
+
+	// open: Boolean
+	//		Whether pane is opened or closed.
+	open: true,
+
+	// duration: Integer
+	//		Time in milliseconds to fade in/fade out
+	duration: dijit.defaultDuration,
+
+	// baseClass: [protected] String
+	//		The root className to use for the various states of this widget
+	baseClass: "dijitTitlePane",
+
+	templateString:"<div class=\"${baseClass}\">\n\t<div dojoAttachEvent=\"onclick:toggle, onkeypress:_onTitleKey, onfocus:_handleFocus, onblur:_handleFocus, onmouseenter:_onTitleEnter, onmouseleave:_onTitleLeave\" tabindex=\"0\"\n\t\t\twaiRole=\"button\" class=\"dijitTitlePaneTitle\" dojoAttachPoint=\"titleBarNode,focusNode\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" dojoAttachPoint=\"arrowNode\" class=\"dijitArrowNode\" waiRole=\"presentation\"\n\t\t><span dojoAttachPoint=\"arrowNodeInner\ [...]
+
+	attributeMap: dojo.delegate(dijit.layout.ContentPane.prototype.attributeMap, {
+		title: { node: "titleNode", type: "innerHTML" }
+	}),
+
+	postCreate: function(){
+		if(!this.open){
+			this.hideNode.style.display = this.wipeNode.style.display = "none";
+		}
+		this._setCss();
+		dojo.setSelectable(this.titleNode, false);
+		dijit.setWaiState(this.containerNode, "labelledby", this.titleNode.id);
+		dijit.setWaiState(this.focusNode, "haspopup", "true");
+
+		// setup open/close animations
+		var hideNode = this.hideNode, wipeNode = this.wipeNode;
+		this._wipeIn = dojo.fx.wipeIn({
+			node: this.wipeNode,
+			duration: this.duration,
+			beforeBegin: function(){
+				hideNode.style.display="";
+			}
+		});
+		this._wipeOut = dojo.fx.wipeOut({
+			node: this.wipeNode,
+			duration: this.duration,
+			onEnd: function(){
+				hideNode.style.display="none";
+			}
+		});
+		this.inherited(arguments);
+	},
+
+	_setOpenAttr: function(/* Boolean */ open){
+		// summary:
+		//		Hook to make attr("open", boolean) control the open/closed state of the pane.
+		// open: Boolean
+		//		True if you want to open the pane, false if you want to close it.
+		if(this.open !== open){ this.toggle(); }
+	},
+
+	_setContentAttr: function(content){
+		// summary:
+		//		Hook to make attr("content", ...) work.
+		// 		Typically called when an href is loaded.  Our job is to make the animation smooth.
+
+		if(!this.open || !this._wipeOut || this._wipeOut.status() == "playing"){
+			// we are currently *closing* the pane (or the pane is closed), so just let that continue
+			this.inherited(arguments);
+		}else{
+			if(this._wipeIn && this._wipeIn.status() == "playing"){
+				this._wipeIn.stop();
+			}
+
+			// freeze container at current height so that adding new content doesn't make it jump
+			dojo.marginBox(this.wipeNode, { h: dojo.marginBox(this.wipeNode).h });
+
+			// add the new content (erasing the old content, if any)
+			this.inherited(arguments);
+
+			// call _wipeIn.play() to animate from current height to new height
+			if(this._wipeIn){
+				this._wipeIn.play();
+			}else{
+				this.hideNode.style.display = "";
+			}
+		}
+	},
+
+	toggle: function(){
+		// summary:
+		//		Switches between opened and closed state
+		// tags:
+		//		private
+
+		dojo.forEach([this._wipeIn, this._wipeOut], function(animation){
+			if(animation && animation.status() == "playing"){
+				animation.stop();
+			}
+		});
+
+		var anim = this[this.open ? "_wipeOut" : "_wipeIn"]
+		if(anim){
+			anim.play();
+		}else{
+			this.hideNode.style.display = this.open ? "" : "none";
+		}
+		this.open =! this.open;
+
+		// load content (if this is the first time we are opening the TitlePane
+		// and content is specified as an href, or href was set when hidden)
+		this._onShow();
+
+		this._setCss();
+	},
+
+	_setCss: function(){
+		// summary:
+		//		Set the open/close css state for the TitlePane
+		// tags:
+		//		private
+
+		var classes = ["dijitClosed", "dijitOpen"];
+		var boolIndex = this.open;
+		var node = this.titleBarNode || this.focusNode;
+		dojo.removeClass(node, classes[!boolIndex+0]);
+		node.className += " " + classes[boolIndex+0];
+
+		// provide a character based indicator for images-off mode
+		this.arrowNodeInner.innerHTML = this.open ? "-" : "+";
+	},
+
+	_onTitleKey: function(/*Event*/ e){
+		// summary:
+		//		Handler for when user hits a key
+		// tags:
+		//		private
+
+		if(e.charOrCode == dojo.keys.ENTER || e.charOrCode == ' '){
+			this.toggle();
+		}else if(e.charOrCode == dojo.keys.DOWN_ARROW && this.open){
+			this.containerNode.focus();
+			e.preventDefault();
+	 	}
+	},
+	
+	_onTitleEnter: function(){
+		// summary:
+		//		Handler for when someone hovers over my title
+		// tags:
+		//		private
+		dojo.addClass(this.focusNode, "dijitTitlePaneTitle-hover");
+	},
+
+	_onTitleLeave: function(){
+		// summary:
+		//		Handler when someone stops hovering over my title
+		// tags:
+		//		private
+		dojo.removeClass(this.focusNode, "dijitTitlePaneTitle-hover");
+	},
+
+	_handleFocus: function(/*Event*/ e){
+		// summary:
+		//		Handle blur and focus for this widget
+		// tags:
+		//		private
+		
+		// add/removeClass is safe to call without hasClass in this case
+		dojo[(e.type == "focus" ? "addClass" : "removeClass")](this.focusNode, this.baseClass + "Focused");
+	},
+
+	setTitle: function(/*String*/ title){
+		// summary:
+		//		Deprecated.  Use attr('title', ...) instead.
+		// tags:
+		//		deprecated
+		dojo.deprecated("dijit.TitlePane.setTitle() is deprecated.  Use attr('title', ...) instead.", "", "2.0");
+		this.titleNode.innerHTML = title;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit.Tooltip"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.Tooltip"] = true;
+dojo.provide("dijit.Tooltip");
+
+
+
+
+dojo.declare(
+	"dijit._MasterTooltip",
+	[dijit._Widget, dijit._Templated],
+	{
+		// summary:
+		//		Internal widget that holds the actual tooltip markup,
+		//		which occurs once per page.
+		//		Called by Tooltip widgets which are just containers to hold
+		//		the markup
+		// tags:
+		//		protected
+
+		// duration: Integer
+		//		Milliseconds to fade in/fade out
+		duration: dijit.defaultDuration,
+
+		templateString:"<div class=\"dijitTooltip dijitTooltipLeft\" id=\"dojoTooltip\">\n\t<div class=\"dijitTooltipContainer dijitTooltipContents\" dojoAttachPoint=\"containerNode\" waiRole='alert'></div>\n\t<div class=\"dijitTooltipConnector\"></div>\n</div>\n",
+
+		postCreate: function(){
+			dojo.body().appendChild(this.domNode);
+
+			this.bgIframe = new dijit.BackgroundIframe(this.domNode);
+
+			// Setup fade-in and fade-out functions.
+			this.fadeIn = dojo.fadeIn({ node: this.domNode, duration: this.duration, onEnd: dojo.hitch(this, "_onShow") });
+			this.fadeOut = dojo.fadeOut({ node: this.domNode, duration: this.duration, onEnd: dojo.hitch(this, "_onHide") });
+
+		},
+
+		show: function(/*String*/ innerHTML, /*DomNode*/ aroundNode, /*String[]?*/ position){
+			// summary:
+			//		Display tooltip w/specified contents to right of specified node
+			//		(To left if there's no space on the right, or if LTR==right)
+
+			if(this.aroundNode && this.aroundNode === aroundNode){
+				return;
+			}
+
+			if(this.fadeOut.status() == "playing"){
+				// previous tooltip is being hidden; wait until the hide completes then show new one
+				this._onDeck=arguments;
+				return;
+			}
+			this.containerNode.innerHTML=innerHTML;
+
+			// Firefox bug. when innerHTML changes to be shorter than previous
+			// one, the node size will not be updated until it moves.
+			this.domNode.style.top = (this.domNode.offsetTop + 1) + "px";
+
+			// position the element and change CSS according to position[] (a list of positions to try)
+			var align = {};
+			var ltr = this.isLeftToRight();
+			dojo.forEach( (position && position.length) ? position : dijit.Tooltip.defaultPosition, function(pos){
+				switch(pos){
+					case "after":				
+						align[ltr ? "BR" : "BL"] = ltr ? "BL" : "BR";
+						break;
+					case "before":
+						align[ltr ? "BL" : "BR"] = ltr ? "BR" : "BL";
+						break;
+					case "below":
+						// first try to align left borders, next try to align right borders (or reverse for RTL mode)
+						align[ltr ? "BL" : "BR"] = ltr ? "TL" : "TR";
+						align[ltr ? "BR" : "BL"] = ltr ? "TR" : "TL";
+						break;
+					case "above":
+					default:
+						// first try to align left borders, next try to align right borders (or reverse for RTL mode)
+						align[ltr ? "TL" : "TR"] = ltr ? "BL" : "BR";
+						align[ltr ? "TR" : "TL"] = ltr ? "BR" : "BL";
+						break;
+				}
+			});
+			var pos = dijit.placeOnScreenAroundElement(this.domNode, aroundNode, align, dojo.hitch(this, "orient"));
+
+			// show it
+			dojo.style(this.domNode, "opacity", 0);
+			this.fadeIn.play();
+			this.isShowingNow = true;
+			this.aroundNode = aroundNode;
+		},
+
+		orient: function(/* DomNode */ node, /* String */ aroundCorner, /* String */ tooltipCorner){
+			// summary:
+			//		Private function to set CSS for tooltip node based on which position it's in.
+			//		This is called by the dijit popup code.
+			// tags:
+			//		protected
+
+			node.className = "dijitTooltip " +
+				{
+					"BL-TL": "dijitTooltipBelow dijitTooltipABLeft",
+					"TL-BL": "dijitTooltipAbove dijitTooltipABLeft",
+					"BR-TR": "dijitTooltipBelow dijitTooltipABRight",
+					"TR-BR": "dijitTooltipAbove dijitTooltipABRight",
+					"BR-BL": "dijitTooltipRight",
+					"BL-BR": "dijitTooltipLeft"
+				}[aroundCorner + "-" + tooltipCorner];
+		},
+
+		_onShow: function(){
+			// summary:
+			//		Called at end of fade-in operation
+			// tags:
+			//		protected
+			if(dojo.isIE){
+				// the arrow won't show up on a node w/an opacity filter
+				this.domNode.style.filter="";
+			}
+		},
+
+		hide: function(aroundNode){
+			// summary:
+			//		Hide the tooltip
+			if(this._onDeck && this._onDeck[1] == aroundNode){
+				// this hide request is for a show() that hasn't even started yet;
+				// just cancel the pending show()
+				this._onDeck=null;
+			}else if(this.aroundNode === aroundNode){
+				// this hide request is for the currently displayed tooltip
+				this.fadeIn.stop();
+				this.isShowingNow = false;
+				this.aroundNode = null;
+				this.fadeOut.play();
+			}else{
+				// just ignore the call, it's for a tooltip that has already been erased
+			}
+		},
+
+		_onHide: function(){
+			// summary:
+			//		Called at end of fade-out operation
+			// tags:
+			//		protected
+
+			this.domNode.style.cssText="";	// to position offscreen again
+			if(this._onDeck){
+				// a show request has been queued up; do it now
+				this.show.apply(this, this._onDeck);
+				this._onDeck=null;
+			}
+		}
+
+	}
+);
+
+dijit.showTooltip = function(/*String*/ innerHTML, /*DomNode*/ aroundNode, /*String[]?*/ position){
+	// summary:
+	//		Display tooltip w/specified contents in specified position.
+	//		See description of dijit.Tooltip.defaultPosition for details on position parameter.
+	//		If position is not specified then dijit.Tooltip.defaultPosition is used.
+	if(!dijit._masterTT){ dijit._masterTT = new dijit._MasterTooltip(); }
+	return dijit._masterTT.show(innerHTML, aroundNode, position);
+};
+
+dijit.hideTooltip = function(aroundNode){
+	// summary:
+	//		Hide the tooltip
+	if(!dijit._masterTT){ dijit._masterTT = new dijit._MasterTooltip(); }
+	return dijit._masterTT.hide(aroundNode);
+};
+
+dojo.declare(
+	"dijit.Tooltip",
+	dijit._Widget,
+	{
+		// summary
+		//		Pops up a tooltip (a help message) when you hover over a node.
+
+		// label: String
+		//		Text to display in the tooltip.
+		//		Specified as innerHTML when creating the widget from markup.
+		label: "",
+
+		// showDelay: Integer
+		//		Number of milliseconds to wait after hovering over/focusing on the object, before
+		//		the tooltip is displayed.
+		showDelay: 400,
+
+		// connectId: [const] String[]
+		//		Id's of domNodes to attach the tooltip to.
+		//		When user hovers over any of the specified dom nodes, the tooltip will appear.
+		//
+		//		Note: Currently connectId can only be specified on initialization, it cannot
+		//		be changed via attr('connectId', ...)
+		//
+		//		Note: in 2.0 this will be renamed to connectIds for less confusion.
+		connectId: [],
+
+		// position: String[]
+		//		See description of `dijit.Tooltip.defaultPosition` for details on position parameter.
+		position: [],
+
+		_setConnectIdAttr: function(ids){
+			// TODO: erase old conections
+
+			this._connectNodes = [];
+
+			// TODO: rename connectId to connectIds for 2.0, and remove this code converting from string to array
+			this.connectId = dojo.isArrayLike(ids) ? ids : [ids];
+			
+			dojo.forEach(this.connectId, function(id) {
+				var node = dojo.byId(id);
+				if (node) {
+					this._connectNodes.push(node);
+					dojo.forEach(["onMouseEnter", "onMouseLeave", "onFocus", "onBlur"], function(event){
+						this.connect(node, event.toLowerCase(), "_"+event);
+					}, this);
+					if(dojo.isIE){
+						// BiDi workaround
+						node.style.zoom = 1;
+					}
+				}
+			}, this);
+		},
+
+		postCreate: function(){	
+			dojo.addClass(this.domNode,"dijitTooltipData");
+		},
+
+		_onMouseEnter: function(/*Event*/ e){
+			// summary:
+			//		Handler for mouseenter event on the target node
+			// tags:
+			//		private
+			this._onHover(e);
+		},
+
+		_onMouseLeave: function(/*Event*/ e){
+			// summary:
+			//		Handler for mouseleave event on the target node
+			// tags:
+			//		private
+			this._onUnHover(e);
+		},
+
+		_onFocus: function(/*Event*/ e){
+			// summary:
+			//		Handler for focus event on the target node
+			// tags:
+			//		private
+
+			// TODO: this is dangerously named, as the dijit focus manager calls
+			// _onFocus() on any widget that gets focus (whereas in this class we
+			// are connecting onfocus on the *target* DOM node to this method
+
+			this._focus = true;
+			this._onHover(e);
+			this.inherited(arguments);
+		},
+		
+		_onBlur: function(/*Event*/ e){
+			// summary:
+			//		Handler for blur event on the target node
+			// tags:
+			//		private
+
+			// TODO: rename; see above comment
+
+			this._focus = false;
+			this._onUnHover(e);
+			this.inherited(arguments);
+		},
+
+		_onHover: function(/*Event*/ e){
+			// summary:
+			//		Despite the name of this method, it actually handles both hover and focus
+			//		events on the target node, setting a timer to show the tooltip.
+			// tags:
+			//		private
+			if(!this._showTimer){
+				var target = e.target;
+				this._showTimer = setTimeout(dojo.hitch(this, function(){this.open(target)}), this.showDelay);
+			}
+		},
+
+		_onUnHover: function(/*Event*/ e){
+			// summary:
+			//		Despite the name of this method, it actually handles both mouseleave and blur
+			//		events on the target node, hiding the tooltip.
+			// tags:
+			//		private
+
+			// keep a tooltip open if the associated element still has focus (even though the
+			// mouse moved away)
+			if(this._focus){ return; }
+
+			if(this._showTimer){
+				clearTimeout(this._showTimer);
+				delete this._showTimer;
+			}
+			this.close();
+		},
+
+		open: function(/*DomNode*/ target){
+ 			// summary:
+			//		Display the tooltip; usually not called directly.
+			// tags:
+			//		private
+
+			target = target || this._connectNodes[0];
+			if(!target){ return; }
+
+			if(this._showTimer){
+				clearTimeout(this._showTimer);
+				delete this._showTimer;
+			}
+			dijit.showTooltip(this.label || this.domNode.innerHTML, target, this.position);
+			
+			this._connectNode = target;
+		},
+
+		close: function(){
+			// summary:
+			//		Hide the tooltip or cancel timer for show of tooltip
+			// tags:
+			//		private
+
+			if(this._connectNode){
+				// if tooltip is currently shown
+				dijit.hideTooltip(this._connectNode);
+				delete this._connectNode;
+			}
+			if(this._showTimer){
+				// if tooltip is scheduled to be shown (after a brief delay)
+				clearTimeout(this._showTimer);
+				delete this._showTimer;
+			}
+		},
+
+		uninitialize: function(){
+			this.close();
+		}
+	}
+);
+
+// dijit.Tooltip.defaultPosition: String[]
+//		This variable controls the position of tooltips, if the position is not specified to
+//		the Tooltip widget or *TextBox widget itself.  It's an array of strings with the following values:
+//
+//			* before: places tooltip to the left of the target node/widget, or to the right in
+//			  the case of RTL scripts like Hebrew and Arabic
+//			* after: places tooltip to the right of the target node/widget, or to the left in
+//			  the case of RTL scripts like Hebrew and Arabic
+//			* above: tooltip goes above target node
+//			* below: tooltip goes below target node
+//
+//		The list is positions is tried, in order, until a position is found where the tooltip fits
+//		within the viewport.
+//
+//		Be careful setting this parameter.  A value of "above" may work fine until the user scrolls
+//		the screen so that there's no room above the target node.   Nodes with drop downs, like
+//		DropDownButton or FilteringSelect, are especially problematic, in that you need to be sure
+//		that the drop down and tooltip don't overlap, even when the viewport is scrolled so that there
+//		is only room below (or above) the target node, but not both.
+dijit.Tooltip.defaultPosition = ["after", "before"];
+
+}
+
+if(!dojo._hasResource["dojo.cookie"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.cookie"] = true;
+dojo.provide("dojo.cookie");
+
+
+
+/*=====
+dojo.__cookieProps = function(){
+	//	expires: Date|String|Number?
+	//		If a number, the number of days from today at which the cookie
+	//		will expire. If a date, the date past which the cookie will expire.
+	//		If expires is in the past, the cookie will be deleted.
+	//		If expires is omitted or is 0, the cookie will expire when the browser closes. << FIXME: 0 seems to disappear right away? FF3.
+	//	path: String?
+	//		The path to use for the cookie.
+	//	domain: String?
+	//		The domain to use for the cookie.
+	//	secure: Boolean?
+	//		Whether to only send the cookie on secure connections
+	this.expires = expires;
+	this.path = path;
+	this.domain = domain;
+	this.secure = secure;
+}
+=====*/
+
+
+dojo.cookie = function(/*String*/name, /*String?*/value, /*dojo.__cookieProps?*/props){
+	//	summary: 
+	//		Get or set a cookie.
+	//	description:
+	// 		If one argument is passed, returns the value of the cookie
+	// 		For two or more arguments, acts as a setter.
+	//	name:
+	//		Name of the cookie
+	//	value:
+	//		Value for the cookie
+	//	props: 
+	//		Properties for the cookie
+	//	example:
+	//		set a cookie with the JSON-serialized contents of an object which
+	//		will expire 5 days from now:
+	//	|	dojo.cookie("configObj", dojo.toJson(config), { expires: 5 });
+	//	
+	//	example:
+	//		de-serialize a cookie back into a JavaScript object:
+	//	|	var config = dojo.fromJson(dojo.cookie("configObj"));
+	//	
+	//	example:
+	//		delete a cookie:
+	//	|	dojo.cookie("configObj", null, {expires: -1});
+	var c = document.cookie;
+	if(arguments.length == 1){
+		var matches = c.match(new RegExp("(?:^|; )" + dojo.regexp.escapeString(name) + "=([^;]*)"));
+		return matches ? decodeURIComponent(matches[1]) : undefined; // String or undefined
+	}else{
+		props = props || {};
+// FIXME: expires=0 seems to disappear right away, not on close? (FF3)  Change docs?
+		var exp = props.expires;
+		if(typeof exp == "number"){ 
+			var d = new Date();
+			d.setTime(d.getTime() + exp*24*60*60*1000);
+			exp = props.expires = d;
+		}
+		if(exp && exp.toUTCString){ props.expires = exp.toUTCString(); }
+
+		value = encodeURIComponent(value);
+		var updatedCookie = name + "=" + value, propName;
+		for(propName in props){
+			updatedCookie += "; " + propName;
+			var propValue = props[propName];
+			if(propValue !== true){ updatedCookie += "=" + propValue; }
+		}
+		document.cookie = updatedCookie;
+	}
+};
+
+dojo.cookie.isSupported = function(){
+	//	summary:
+	//		Use to determine if the current browser supports cookies or not.
+	//		
+	//		Returns true if user allows cookies.
+	//		Returns false if user doesn't allow cookies.
+
+	if(!("cookieEnabled" in navigator)){
+		this("__djCookieTest__", "CookiesAllowed");
+		navigator.cookieEnabled = this("__djCookieTest__") == "CookiesAllowed";
+		if(navigator.cookieEnabled){
+			this("__djCookieTest__", "", {expires: -1});
+		}
+	}
+	return navigator.cookieEnabled;
+};
+
+}
+
+if(!dojo._hasResource["dijit.tree.TreeStoreModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.tree.TreeStoreModel"] = true;
+dojo.provide("dijit.tree.TreeStoreModel");
+
+dojo.declare(
+		"dijit.tree.TreeStoreModel",
+		null,
+	{
+		// summary:
+		//		Implements dijit.Tree.model connecting to a store with a single
+		//		root item.  Any methods passed into the constructor will override
+		//		the ones defined here.
+
+		// store: dojo.data.Store
+		//		Underlying store
+		store: null,
+
+		// childrenAttrs: String[]
+		//		One or more attribute names (attributes in the dojo.data item) that specify that item's children
+		childrenAttrs: ["children"],
+
+		// labelAttr: String
+		//		If specified, get label for tree node from this attribute, rather
+		//		than by calling store.getLabel()
+		labelAttr: "",
+	 
+	 	// root: [readonly] dojo.data.Item
+		//		Pointer to the root item (read only, not a parameter)
+		root: null,
+
+		// query: anything
+		//		Specifies datastore query to return the root item for the tree.
+		//		Must only return a single item.   Alternately can just pass in pointer
+		//		to root item.
+		// example:
+		//	|	{id:'ROOT'}
+		query: null,
+
+		constructor: function(/* Object */ args){
+			// summary:
+			//		Passed the arguments listed above (store, etc)
+			// tags:
+			//		private
+
+			dojo.mixin(this, args);
+
+			this.connects = [];
+
+			var store = this.store;
+			if(!store.getFeatures()['dojo.data.api.Identity']){
+				throw new Error("dijit.Tree: store must support dojo.data.Identity");
+			}
+
+			// if the store supports Notification, subscribe to the notification events
+			if(store.getFeatures()['dojo.data.api.Notification']){
+				this.connects = this.connects.concat([
+					dojo.connect(store, "onNew", this, "_onNewItem"),
+					dojo.connect(store, "onDelete", this, "_onDeleteItem"),
+					dojo.connect(store, "onSet", this, "_onSetItem")
+				]);
+			}
+		},
+
+		destroy: function(){
+			dojo.forEach(this.connects, dojo.disconnect);
+			// TODO: should cancel any in-progress processing of getRoot(), getChildren()
+		},
+
+		// =======================================================================
+		// Methods for traversing hierarchy
+
+		getRoot: function(onItem, onError){
+			// summary:
+			//		Calls onItem with the root item for the tree, possibly a fabricated item.
+			//		Calls onError on error.
+			if(this.root){
+				onItem(this.root);
+			}else{
+				this.store.fetch({
+					query: this.query,
+					onComplete: dojo.hitch(this, function(items){
+						if(items.length != 1){
+							throw new Error(this.declaredClass + ": query " + dojo.toJson(this.query) + " returned " + items.length +
+							 	" items, but must return exactly one item");
+						}
+						this.root = items[0];
+						onItem(this.root);
+					}),
+					onError: onError
+				});
+			}
+		},
+
+		mayHaveChildren: function(/*dojo.data.Item*/ item){
+			// summary:
+			//		Tells if an item has or may have children.  Implementing logic here
+			//		avoids showing +/- expando icon for nodes that we know don't have children.
+			//		(For efficiency reasons we may not want to check if an element actually
+			//		has children until user clicks the expando node)
+			return dojo.some(this.childrenAttrs, function(attr){
+				return this.store.hasAttribute(item, attr);
+			}, this);
+		},
+
+		getChildren: function(/*dojo.data.Item*/ parentItem, /*function(items)*/ onComplete, /*function*/ onError){
+			// summary:
+			// 		Calls onComplete() with array of child items of given parent item, all loaded.
+
+			var store = this.store;
+
+			// get children of specified item
+			var childItems = [];
+			for (var i=0; i<this.childrenAttrs.length; i++){
+				var vals = store.getValues(parentItem, this.childrenAttrs[i]);
+				childItems = childItems.concat(vals);
+			}
+
+			// count how many items need to be loaded
+			var _waitCount = 0;
+			dojo.forEach(childItems, function(item){ if(!store.isItemLoaded(item)){ _waitCount++; } });
+
+			if(_waitCount == 0){
+				// all items are already loaded.  proceed...
+				onComplete(childItems);
+			}else{
+				// still waiting for some or all of the items to load
+				var onItem = function onItem(item){
+					if(--_waitCount == 0){
+						// all nodes have been loaded, send them to the tree
+						onComplete(childItems);
+					}
+				}
+				dojo.forEach(childItems, function(item){
+					if(!store.isItemLoaded(item)){
+						store.loadItem({
+							item: item,
+							onItem: onItem,
+							onError: onError
+						});
+					}
+				});
+			}
+		},
+
+		// =======================================================================
+		// Inspecting items
+
+		getIdentity: function(/* item */ item){
+			return this.store.getIdentity(item);	// Object
+		},
+
+		getLabel: function(/*dojo.data.Item*/ item){
+			// summary:
+			//		Get the label for an item
+			if(this.labelAttr){
+				return this.store.getValue(item,this.labelAttr);	// String
+			}else{
+				return this.store.getLabel(item);	// String
+			}
+		},
+
+		// =======================================================================
+		// Write interface
+
+		newItem: function(/* Object? */ args, /*Item*/ parent){
+			// summary:
+			//		Creates a new item.   See `dojo.data.api.Write` for details on args.
+			//		Used in drag & drop when item from external source dropped onto tree.
+			var pInfo = {parent: parent, attribute: this.childrenAttrs[0]};
+			return this.store.newItem(args, pInfo);
+		},
+
+		pasteItem: function(/*Item*/ childItem, /*Item*/ oldParentItem, /*Item*/ newParentItem, /*Boolean*/ bCopy, /*int?*/ insertIndex){
+			// summary:
+			//		Move or copy an item from one parent item to another.
+			//		Used in drag & drop
+			var store = this.store,
+				parentAttr = this.childrenAttrs[0];	// name of "children" attr in parent item
+
+			// remove child from source item, and record the attributee that child occurred in	
+			if(oldParentItem){
+				dojo.forEach(this.childrenAttrs, function(attr){
+					if(store.containsValue(oldParentItem, attr, childItem)){
+						if(!bCopy){
+							var values = dojo.filter(store.getValues(oldParentItem, attr), function(x){
+								return x != childItem;
+							});
+							store.setValues(oldParentItem, attr, values);
+						}
+						parentAttr = attr;
+					}
+				});
+			}
+
+			// modify target item's children attribute to include this item
+			if(newParentItem){
+				if(typeof insertIndex == "number"){
+					var childItems = store.getValues(newParentItem, parentAttr);
+					childItems.splice(insertIndex, 0, childItem);
+					store.setValues(newParentItem, parentAttr, childItems);
+				}else{
+				store.setValues(newParentItem, parentAttr,
+					store.getValues(newParentItem, parentAttr).concat(childItem));
+			}
+			}
+		},
+
+		// =======================================================================
+		// Callbacks
+		
+		onChange: function(/*dojo.data.Item*/ item){
+			// summary:
+			//		Callback whenever an item has changed, so that Tree
+			//		can update the label, icon, etc.   Note that changes
+			//		to an item's children or parent(s) will trigger an
+			//		onChildrenChange() so you can ignore those changes here.
+			// tags:
+			//		callback
+		},
+
+		onChildrenChange: function(/*dojo.data.Item*/ parent, /*dojo.data.Item[]*/ newChildrenList){
+			// summary:
+			//		Callback to do notifications about new, updated, or deleted items.
+			// tags:
+			//		callback
+		},
+
+		onDelete: function(/*dojo.data.Item*/ parent, /*dojo.data.Item[]*/ newChildrenList){
+			// summary:
+			//		Callback when an item has been deleted.
+			// description:
+			//		Note that there will also be an onChildrenChange() callback for the parent
+			//		of this item.
+			// tags:
+			//		callback
+		},
+
+		// =======================================================================
+		///Events from data store
+
+		_onNewItem: function(/* dojo.data.Item */ item, /* Object */ parentInfo){
+			// summary:
+			//		Handler for when new items appear in the store.
+
+			//	In this case there's no correspond onSet() call on the parent of this
+			//	item, so need to get the new children list of the parent manually somehow.
+			if(!parentInfo){
+				return;
+			}
+			this.getChildren(parentInfo.item, dojo.hitch(this, function(children){
+				// NOTE: maybe can be optimized since parentInfo contains the new and old attribute value
+				this.onChildrenChange(parentInfo.item, children);
+			}));
+		},
+		
+		_onDeleteItem: function(/*Object*/ item){
+			// summary:
+			//		Handler for delete notifications from underlying store
+			this.onDelete(item);
+		},
+
+		_onSetItem: function(/* item */ item, 
+						/* attribute-name-string */ attribute, 
+						/* object | array */ oldValue,
+						/* object | array */ newValue){
+			// summary:
+			//		Set data event on an item in the store
+		
+			if(dojo.indexOf(this.childrenAttrs, attribute) != -1){
+				// item's children list changed
+				this.getChildren(item, dojo.hitch(this, function(children){
+					// NOTE: maybe can be optimized since parentInfo contains the new and old attribute value
+					this.onChildrenChange(item, children);
+				}));
+			}else{
+				// item's label/icon/etc. changed.
+				this.onChange(item);
+			}
+		}
+	});
+
+
+
+}
+
+if(!dojo._hasResource["dijit.tree.ForestStoreModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.tree.ForestStoreModel"] = true;
+dojo.provide("dijit.tree.ForestStoreModel");
+
+
+
+dojo.declare("dijit.tree.ForestStoreModel", dijit.tree.TreeStoreModel, {
+	// summary:
+	//		Interface between Tree and a dojo.store that doesn't have a root item,
+	//		i.e. has multiple "top level" items.
+	//
+	// description
+	//		Use this class to wrap a dojo.store, making all the items matching the specified query
+	//		appear as children of a fabricated "root item".  If no query is specified then all the
+	//		items returned by fetch() on the underlying store become children of the root item.
+	//		It allows dijit.Tree to assume a single root item, even if the store doesn't have one.
+
+	// Parameters to constructor
+
+	// rootId: String
+	//		ID of fabricated root item
+	rootId: "$root$",
+
+	// rootLabel: String
+	//		Label of fabricated root item
+	rootLabel: "ROOT",
+
+	// query: String
+	//		Specifies the set of children of the root item.
+	// example:
+	//	|	{type:'continent'}
+	query: null,
+
+	// End of parameters to constructor
+
+	constructor: function(params){
+		// summary:
+		//		Sets up variables, etc.
+		// tags:
+		//		private
+
+		// Make dummy root item
+		this.root = {
+			store: this,
+			root: true,
+			id: params.rootId,
+			label: params.rootLabel,
+			children: params.rootChildren	// optional param
+		};
+	},
+
+	// =======================================================================
+	// Methods for traversing hierarchy
+
+	mayHaveChildren: function(/*dojo.data.Item*/ item){
+		// summary:
+		//		Tells if an item has or may have children.  Implementing logic here
+		//		avoids showing +/- expando icon for nodes that we know don't have children.
+		//		(For efficiency reasons we may not want to check if an element actually
+		//		has children until user clicks the expando node)
+		// tags:
+		//		extension
+		return item === this.root || this.inherited(arguments);
+	},
+
+	getChildren: function(/*dojo.data.Item*/ parentItem, /*function(items)*/ callback, /*function*/ onError){
+		// summary:
+		// 		Calls onComplete() with array of child items of given parent item, all loaded.
+		if(parentItem === this.root){
+			if(this.root.children){
+				// already loaded, just return
+				callback(this.root.children);
+			}else{
+				this.store.fetch({
+					query: this.query,
+					onComplete: dojo.hitch(this, function(items){
+						this.root.children = items;
+						callback(items);
+					}),
+					onError: onError
+				});
+			}
+		}else{
+			this.inherited(arguments);
+		}
+	},
+
+	// =======================================================================
+	// Inspecting items
+
+	getIdentity: function(/* item */ item){
+		return (item === this.root) ? this.root.id : this.inherited(arguments);
+	},
+
+	getLabel: function(/* item */ item){
+		return	(item === this.root) ? this.root.label : this.inherited(arguments);
+	},
+
+	// =======================================================================
+	// Write interface
+
+	newItem: function(/* Object? */ args, /*Item*/ parent){
+		// summary:
+		//		Creates a new item.   See dojo.data.api.Write for details on args.
+		//		Used in drag & drop when item from external source dropped onto tree.
+		if(parent===this.root){
+			this.onNewRootItem(args);
+			return this.store.newItem(args);
+		}else{
+			return this.inherited(arguments);
+		}
+	},
+ 
+	onNewRootItem: function(args){
+		// summary:
+		//		User can override this method to modify a new element that's being
+		//		added to the root of the tree, for example to add a flag like root=true
+	},
+
+	pasteItem: function(/*Item*/ childItem, /*Item*/ oldParentItem, /*Item*/ newParentItem, /*Boolean*/ bCopy, /*int?*/ insertIndex){
+		// summary:
+		//		Move or copy an item from one parent item to another.
+		//		Used in drag & drop
+		if(oldParentItem === this.root){
+			if(!bCopy){
+				// It's onLeaveRoot()'s responsibility to modify the item so it no longer matches
+				// this.query... thus triggering an onChildrenChange() event to notify the Tree
+				// that this element is no longer a child of the root node
+				this.onLeaveRoot(childItem);
+			}
+		}
+		dijit.tree.TreeStoreModel.prototype.pasteItem.call(this, childItem,
+			oldParentItem === this.root ? null : oldParentItem,
+			newParentItem === this.root ? null : newParentItem,
+			bCopy,
+			insertIndex
+		);
+		if(newParentItem === this.root){
+			// It's onAddToRoot()'s responsibility to modify the item so it matches
+			// this.query... thus triggering an onChildrenChange() event to notify the Tree
+			// that this element is now a child of the root node
+			this.onAddToRoot(childItem);
+		}
+	},
+
+	// =======================================================================
+	// Handling for top level children
+	
+	onAddToRoot: function(/* item */ item){
+		// summary:
+		//		Called when item added to root of tree; user must override this method
+		//		to modify the item so that it matches the query for top level items
+		// example:
+		//	|	store.setValue(item, "root", true);
+		// tags:
+		//		extension
+		
+	},
+
+	onLeaveRoot: function(/* item */ item){
+		// summary:
+		//		Called when item removed from root of tree; user must override this method
+		//		to modify the item so it doesn't match the query for top level items
+		// example:
+		// 	|	store.unsetAttribute(item, "root");
+		// tags:
+		//		extension
+		
+	},
+	
+	// =======================================================================
+	// Events from data store
+
+	_requeryTop: function(){
+		// reruns the query for the children of the root node,
+		// sending out an onSet notification if those children have changed
+		var oldChildren = this.root.children || [];
+		this.store.fetch({
+			query: this.query,
+			onComplete: dojo.hitch(this, function(newChildren){
+				this.root.children = newChildren;
+
+				// If the list of children or the order of children has changed...	
+				if(oldChildren.length != newChildren.length ||
+					dojo.some(oldChildren, function(item, idx){ return newChildren[idx] != item;})){
+					this.onChildrenChange(this.root, newChildren);
+				}
+			})
+		});
+	},
+
+	_onNewItem: function(/* dojo.data.Item */ item, /* Object */ parentInfo){
+		// summary:
+		//		Handler for when new items appear in the store.
+
+		//		In theory, any new item could be a top level item.
+		//		Do the safe but inefficient thing by requerying the top
+		//		level items.   User can override this function to do something
+		//		more efficient.
+		this._requeryTop();
+
+		this.inherited(arguments);
+	},
+
+	_onDeleteItem: function(/*Object*/ item){
+		// summary:
+		//		Handler for delete notifications from underlying store
+
+		// check if this was a child of root, and if so send notification that root's children
+		// have changed
+		if(dojo.indexOf(this.root.children, item) != -1){
+			this._requeryTop();
+		}
+
+		this.inherited(arguments);
+	}
+});
+
+
+
+}
+
+if(!dojo._hasResource["dijit.Tree"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.Tree"] = true;
+dojo.provide("dijit.Tree");
+
+
+
+
+
+
+
+
+
+dojo.declare(
+	"dijit._TreeNode",
+	[dijit._Widget, dijit._Templated, dijit._Container, dijit._Contained],
+{
+	// summary:
+	//		Single node within a tree.   This class is used internally
+	//		by Tree and should not be accessed directly.
+	// tags:
+	//		private
+
+	// item: dojo.data.Item
+	//		the dojo.data entry this tree represents
+	item: null,	
+
+	// isTreeNode: [protected] Boolean
+	//		Indicates that this is a TreeNode.   Used by `dijit.Tree` only,
+	//		should not be accessed directly.
+	isTreeNode: true,
+
+	// label: String
+	//		Text of this tree node
+	label: "",
+
+	// isExpandable: [private] Boolean
+	//		This node has children, so show the expando node (+ sign)
+	isExpandable: null,
+
+	// isExpanded: [readonly] Boolean
+	//		This node is currently expanded (ie, opened)
+	isExpanded: false,
+
+	// state: [private] String
+	//		Dynamic loading-related stuff.
+	//		When an empty folder node appears, it is "UNCHECKED" first,
+	//		then after dojo.data query it becomes "LOADING" and, finally "LOADED"	
+	state: "UNCHECKED",
+	
+	templateString:"<div class=\"dijitTreeNode\" waiRole=\"presentation\"\n\t><div dojoAttachPoint=\"rowNode\" class=\"dijitTreeRow\" waiRole=\"presentation\" dojoAttachEvent=\"onmouseenter:_onMouseEnter, onmouseleave:_onMouseLeave\"\n\t\t><img src=\"${_blankGif}\" alt=\"\" dojoAttachPoint=\"expandoNode\" class=\"dijitTreeExpando\" waiRole=\"presentation\"\n\t\t><span dojoAttachPoint=\"expandoNodeText\" class=\"dijitExpandoText\" waiRole=\"presentation\"\n\t\t></span\n\t\t><span dojoAttachP [...]
+
+	postCreate: function(){
+		// set label, escaping special characters
+		this.setLabelNode(this.label);
+
+		// set expand icon for leaf
+		this._setExpando();
+
+		// set icon and label class based on item
+		this._updateItemClasses(this.item);
+
+		if(this.isExpandable){
+			dijit.setWaiState(this.labelNode, "expanded", this.isExpanded);
+			if(this == this.tree.rootNode){
+				dijit.setWaitState(this.tree.domNode, "expanded", this.isExpanded);
+			}
+		}		
+	},
+
+	_setIndentAttr: function(indent){
+		// summary:
+		//		Tell this node how many levels it should be indented
+		// description:
+		//		0 for top level nodes, 1 for their children, 2 for their
+		//		grandchildren, etc.
+		this.indent = indent;
+
+		// Math.max() is to prevent negative padding on hidden root node (when indent == -1)
+		// 19 is the width of the expandoIcon (TODO: get this from CSS instead of hardcoding)
+		var pixels = (Math.max(indent, 0) * 19) + "px";	
+
+		dojo.style(this.domNode, "backgroundPosition",  pixels + " 0px");
+		dojo.style(this.rowNode, dojo._isBodyLtr() ? "paddingLeft" : "paddingRight", pixels);
+ 
+		dojo.forEach(this.getChildren(), function(child){
+        	child.attr("indent", indent+1);
+        });
+	},
+
+	markProcessing: function(){
+		// summary:
+		//		Visually denote that tree is loading data, etc.
+		// tags:
+		//		private
+		this.state = "LOADING";
+		this._setExpando(true);	
+	},
+
+	unmarkProcessing: function(){
+		// summary:
+		//		Clear markup from markProcessing() call
+		// tags:
+		//		private
+		this._setExpando(false);	
+	},
+
+	_updateItemClasses: function(item){
+		// summary:
+		//		Set appropriate CSS classes for icon and label dom node
+		//		(used to allow for item updates to change respective CSS)
+		// tags:
+		//		private
+		var tree = this.tree, model = tree.model;
+		if(tree._v10Compat && item === model.root){
+			// For back-compat with 1.0, need to use null to specify root item (TODO: remove in 2.0)
+			item = null;
+		}
+
+		if(this._iconClass){
+			dojo.removeClass(this.iconNode, this._iconClass);
+		}
+		this._iconClass = tree.getIconClass(item, this.isExpanded);
+		if(this._iconClass){
+			dojo.addClass(this.iconNode, this._iconClass);
+		}
+		dojo.style(this.iconNode, tree.getIconStyle(item, this.isExpanded) || {});
+
+		if(this._labelClass){
+			dojo.removeClass(this.labelNode, this._labelClass);
+		}
+		this._labelClass = tree.getLabelClass(item, this.isExpanded);
+		if(this._labelClass){
+			dojo.addClass(this.labelNode, this._labelClass);
+		}
+		dojo.style(this.labelNode, tree.getLabelStyle(item, this.isExpanded) || {});
+	},
+
+	_updateLayout: function(){
+		// summary:
+		//		Set appropriate CSS classes for this.domNode
+		// tags:
+		//		private
+		var parent = this.getParent();
+		if(!parent || parent.rowNode.style.display == "none"){
+			/* if we are hiding the root node then make every first level child look like a root node */
+			dojo.addClass(this.domNode, "dijitTreeIsRoot");
+		}else{
+			dojo.toggleClass(this.domNode, "dijitTreeIsLast", !this.getNextSibling());
+		}
+	},
+
+	_setExpando: function(/*Boolean*/ processing){
+		// summary:
+		//		Set the right image for the expando node
+		// tags:
+		//		private
+
+		// apply the appropriate class to the expando node
+		var styles = ["dijitTreeExpandoLoading", "dijitTreeExpandoOpened",
+			"dijitTreeExpandoClosed", "dijitTreeExpandoLeaf"];
+		var _a11yStates = ["*","-","+","*"];
+		
+		var idx = processing ? 0 : (this.isExpandable ?	(this.isExpanded ? 1 : 2) : 3);
+		dojo.forEach(styles,
+			function(s){
+				dojo.removeClass(this.expandoNode, s);
+			}, this
+		);
+		dojo.addClass(this.expandoNode, styles[idx]);
+
+		// provide a non-image based indicator for images-off mode
+		this.expandoNodeText.innerHTML = _a11yStates[idx];
+
+	},	
+
+	expand: function(){
+		// summary:
+		//		Show my children
+		if(this.isExpanded){ return; }
+		// cancel in progress collapse operation
+
+		this._wipeOut && this._wipeOut.stop();
+
+		this.isExpanded = true;
+		dijit.setWaiState(this.labelNode, "expanded", "true");
+		dijit.setWaiRole(this.containerNode, "group");
+		dojo.addClass(this.contentNode,'dijitTreeContentExpanded');
+		this._setExpando();
+		this._updateItemClasses(this.item);
+		if(this == this.tree.rootNode){
+			dijit.setWaiState(this.tree.domNode, "expanded", "true");
+		}
+
+		if(!this._wipeIn){
+			this._wipeIn = dojo.fx.wipeIn({
+				node: this.containerNode, duration: dijit.defaultDuration
+			});
+		}
+		this._wipeIn.play();
+	},
+
+	collapse: function(){
+		// summary:
+		//		Collapse this node (if it's expanded)
+
+		if(!this.isExpanded){ return; }
+
+		// cancel in progress expand operation
+		this._wipeIn && this._wipeIn.stop();
+
+		this.isExpanded = false;
+		dijit.setWaiState(this.labelNode, "expanded", "false");
+		if(this == this.tree.rootNode){
+			dijit.setWaiState(this.tree.domNode, "expanded", "false");
+		}
+		dojo.removeClass(this.contentNode,'dijitTreeContentExpanded');
+		this._setExpando();
+		this._updateItemClasses(this.item);
+
+		if(!this._wipeOut){
+			this._wipeOut = dojo.fx.wipeOut({
+				node: this.containerNode, duration: dijit.defaultDuration
+			});
+		}
+		this._wipeOut.play();
+	},
+
+	setLabelNode: function(label){
+		// summary:
+		//		Sets the label
+		this.labelNode.innerHTML = "";
+		this.labelNode.appendChild(dojo.doc.createTextNode(label));
+	},
+
+	// indent: Integer
+	//		Levels from this node to the root node
+	indent: 0,
+
+	setChildItems: function(/* Object[] */ items){
+		// summary:
+		//		Sets the child items of this node, removing/adding nodes
+		//		from current children to match specified items[] array.
+
+		var tree = this.tree,
+			model = tree.model;
+
+		// Orphan all my existing children.
+		// If items contains some of the same items as before then we will reattach them.
+		// Don't call this.removeChild() because that will collapse the tree etc.
+		this.getChildren().forEach(function(child){
+			dijit._Container.prototype.removeChild.call(this, child);
+		}, this);
+
+		this.state = "LOADED";
+
+		if(items && items.length > 0){
+			this.isExpandable = true;
+
+			// Create _TreeNode widget for each specified tree node, unless one already
+			// exists and isn't being used (presumably it's from a DnD move and was recently
+			// released
+			dojo.forEach(items, function(item){
+				var id = model.getIdentity(item),
+					existingNode = tree._itemNodeMap[id],
+					node = 
+						( existingNode && !existingNode.getParent() ) ?
+						existingNode :
+						this.tree._createTreeNode({
+							item: item,
+							tree: tree,
+							isExpandable: model.mayHaveChildren(item),
+							label: tree.getLabel(item),
+							indent: this.indent + 1
+						});
+				if(existingNode){
+					existingNode.attr('indent', this.indent+1);
+				}
+				this.addChild(node);
+				// note: this won't work if there are two nodes for one item (multi-parented items); will be fixed later
+				tree._itemNodeMap[id] = node;
+				if(this.tree._state(item)){
+					tree._expandNode(node);
+				}
+			}, this);
+
+			// note that updateLayout() needs to be called on each child after
+			// _all_ the children exist
+			dojo.forEach(this.getChildren(), function(child, idx){
+				child._updateLayout();
+			});
+		}else{
+			this.isExpandable=false;
+		}
+
+		if(this._setExpando){
+			// change expando to/from dot or + icon, as appropriate
+			this._setExpando(false);
+		}
+
+		// On initial tree show, make the selected TreeNode as either the root node of the tree,
+		// or the first child, if the root node is hidden
+		if(this == tree.rootNode){
+			var fc = this.tree.showRoot ? this : this.getChildren()[0];
+			if(fc){
+				fc.setSelected(true);
+				tree.lastFocused = fc;
+			}else{
+				// fallback: no nodes in tree so focus on Tree <div> itself
+				tree.domNode.setAttribute("tabIndex", "0");
+			}
+		}
+	},
+
+	removeChild: function(/* treeNode */ node){
+		this.inherited(arguments);
+
+		var children = this.getChildren();		
+		if(children.length == 0){
+			this.isExpandable = false;
+			this.collapse();
+		}
+
+		dojo.forEach(children, function(child){
+				child._updateLayout();
+		});
+	},
+
+	makeExpandable: function(){
+		//summary:
+		//		if this node wasn't already showing the expando node,
+		//		turn it into one and call _setExpando()
+
+		// TODO: hmm this isn't called from anywhere, maybe should remove it for 2.0
+
+		this.isExpandable = true;
+		this._setExpando(false);
+	},
+
+	_onLabelFocus: function(evt){
+		// summary:
+		//		Called when this node is focused (possibly programatically)
+		// tags:
+		//		private
+		dojo.addClass(this.labelNode, "dijitTreeLabelFocused");
+		this.tree._onNodeFocus(this);
+	},
+
+	_onLabelBlur: function(evt){
+		// summary:
+		//		Called when focus was moved away from this node, either to
+		//		another TreeNode or away from the Tree entirely.
+		//		Note that we aren't using _onFocus/_onBlur builtin to dijit
+		//		because _onBlur() isn't called when focus is moved to my child TreeNode.
+		// tags:
+		//		private
+		dojo.removeClass(this.labelNode, "dijitTreeLabelFocused");
+	},
+
+	setSelected: function(/*Boolean*/ selected){
+		// summary:
+		//		A Tree has a (single) currently selected node.
+		//		Mark that this node is/isn't that currently selected node.
+		// description:
+		//		In particular, setting a node as selected involves setting tabIndex 
+		//		so that when user tabs to the tree, focus will go to that node (only).
+		var labelNode = this.labelNode;
+		labelNode.setAttribute("tabIndex", selected ? "0" : "-1");
+		dijit.setWaiState(labelNode, "selected", selected);
+		dojo.toggleClass(this.rowNode, "dijitTreeNodeSelected", selected);
+	},
+
+	_onMouseEnter: function(evt){
+		// summary:
+		//		Handler for onmouseenter event on a node
+		// tags:
+		//		private
+		dojo.addClass(this.rowNode, "dijitTreeNodeHover");
+		this.tree._onNodeMouseEnter(this, evt);
+	},
+
+	_onMouseLeave: function(evt){
+		// summary:
+		//		Handler for onmouseenter event on a node
+		// tags:
+		//		private
+		dojo.removeClass(this.rowNode, "dijitTreeNodeHover");
+		this.tree._onNodeMouseLeave(this, evt);
+	}
+});
+
+dojo.declare(
+	"dijit.Tree",
+	[dijit._Widget, dijit._Templated],
+{
+	// summary:
+	//		This widget displays hierarchical data from a store.
+
+	// store: [deprecated] String||dojo.data.Store
+	//		Deprecated.  Use "model" parameter instead.
+	//		The store to get data to display in the tree.
+	store: null,
+
+	// model: dijit.Tree.model
+	//		Interface to read tree data, get notifications of changes to tree data,
+	//		and for handling drop operations (i.e drag and drop onto the tree)
+	model: null,
+
+	// query: [deprecated] anything
+	//		Deprecated.  User should specify query to the model directly instead.
+	//		Specifies datastore query to return the root item or top items for the tree.
+	query: null,
+
+	// label: [deprecated] String
+	//		Deprecated.  Use dijit.tree.ForestStoreModel directly instead.
+	//		Used in conjunction with query parameter.
+	//		If a query is specified (rather than a root node id), and a label is also specified,
+	//		then a fake root node is created and displayed, with this label.
+	label: "",
+
+	// showRoot: [const] Boolean
+	//		Should the root node be displayed, or hidden?
+	showRoot: true,
+
+	// childrenAttr: [deprecated] String[]
+	//		Deprecated.   This information should be specified in the model.
+	//		One ore more attributes that holds children of a tree node
+	childrenAttr: ["children"],
+
+	// openOnClick: Boolean
+	//		If true, clicking a folder node's label will open it, rather than calling onClick()
+	openOnClick: false,
+	
+	// openOnDblClick: Boolean
+	//		If true, double-clicking a folder node's label will open it, rather than calling onDblClick()
+	openOnDblClick: false,
+
+	templateString:"<div class=\"dijitTreeContainer\" waiRole=\"tree\"\n\tdojoAttachEvent=\"onclick:_onClick,onkeypress:_onKeyPress,ondblclick:_onDblClick\">\n</div>\n",
+
+	// isExpandable: [private deprecated] Boolean
+	//		TODO: this appears to be vestigal, back from when Tree extended TreeNode.  Remove.
+	isExpandable: true,
+
+	// isTree: [private deprecated] Boolean
+	//		TODO: this appears to be vestigal.  Remove.
+	isTree: true,
+
+	// persist: Boolean
+	//		Enables/disables use of cookies for state saving.
+	persist: true,
+	
+	// dndController: [protected] String
+	//		Class name to use as as the dnd controller.  Specifying this class enables DnD.
+	//		Generally you should specify this as "dijit._tree.dndSource".
+	dndController: null,
+
+	// parameters to pull off of the tree and pass on to the dndController as its params
+	dndParams: ["onDndDrop","itemCreator","onDndCancel","checkAcceptance", "checkItemAcceptance", "dragThreshold", "betweenThreshold"],
+
+	//declare the above items so they can be pulled from the tree's markup
+
+	// onDndDrop: [protected] Function
+	//		Parameter to dndController, see `dijit._tree.dndSource.onDndDrop`.
+	//		Generally this doesn't need to be set.
+	onDndDrop: null,
+
+	// itemCreator: [protected] Function
+	//		Parameter to dndController, see `dijit._tree.dndSource.itemCreator`.
+	//		Generally this doesn't need to be set.
+	itemCreator: null,
+
+	// onDndCancel: [protected] Function
+	//		Parameter to dndController, see `dijit._tree.dndSource.onDndCancel`.
+	//		Generally this doesn't need to be set.
+	onDndCancel: null,
+
+/*=====
+	checkAcceptance: function(source, nodes){
+		// summary:
+		//		Checks if the Tree itself can accept nodes from this source
+		// source: dijit.tree._dndSource
+		//		The source which provides items
+		// nodes: DOMNode[]
+		//		Array of DOM nodes corresponding to nodes being dropped, dijitTreeRow nodes if
+		//		source is a dijit.Tree.
+		// tags:
+		//		extension
+		return true;	// Boolean
+	},
+=====*/
+	checkAcceptance: null,
+
+/*=====
+	checkItemAcceptance: function(target, source, position){
+		// summary:
+		//		Stub function to be overridden if one wants to check for the ability to drop at the node/item level
+		// description:
+		//		In the base case, this is called to check if target can become a child of source.
+		//		When betweenThreshold is set, position="before" or "after" means that we
+		//		are asking if the source node can be dropped before/after the target node.
+		// target: DOMNode
+		//		The dijitTreeRoot DOM node inside of the TreeNode that we are dropping on to
+		//		Use dijit.getEnclosingWidget(target) to get the TreeNode.
+		// source: dijit._tree.dndSource
+		//		The (set of) nodes we are dropping
+		// position: String
+		//		"over", "before", or "after"
+		// tags:
+		//		extension
+		return true;	// Boolean
+	},
+=====*/
+	checkItemAcceptance: null,
+	
+	// dragThreshold: Integer
+	//		Number of pixels mouse moves before it's considered the start of a drag operation
+	dragThreshold: 0,
+	
+	// betweenThreshold: Integer
+	//		Set to a positive value to allow drag and drop "between" nodes.
+	//
+	//		If during DnD mouse is over a (target) node but less than betweenThreshold
+	//		pixels from the bottom edge, dropping the the dragged node will make it
+	//		the next sibling of the target node, rather than the child.
+	//
+	//		Similarly, if mouse is over a target node but less that betweenThreshold
+	//		pixels from the top edge, dropping the dragged node will make it
+	//		the target node's previous sibling rather than the target node's child.
+	betweenThreshold: 0,
+
+	_publish: function(/*String*/ topicName, /*Object*/ message){
+		// summary:
+		//		Publish a message for this widget/topic
+		dojo.publish(this.id, [dojo.mixin({tree: this, event: topicName}, message||{})]);
+	},
+
+	postMixInProperties: function(){
+		this.tree = this;
+
+		this._itemNodeMap={};
+
+		if(!this.cookieName){
+			this.cookieName = this.id + "SaveStateCookie";
+		}
+
+		// TODO: this.inherited(arguments)
+	},
+
+	postCreate: function(){
+		this._initState();
+		
+		// Create glue between store and Tree, if not specified directly by user
+		if(!this.model){
+			this._store2model();
+		}
+
+		// monitor changes to items
+		this.connect(this.model, "onChange", "_onItemChange");
+		this.connect(this.model, "onChildrenChange", "_onItemChildrenChange");
+		this.connect(this.model, "onDelete", "_onItemDelete");
+
+		this._load();
+
+		this.inherited(arguments);
+
+		if(this.dndController){
+			if(dojo.isString(this.dndController)){
+				this.dndController = dojo.getObject(this.dndController);
+			}	
+			var params={};
+			for (var i=0; i<this.dndParams.length;i++){
+				if(this[this.dndParams[i]]){
+					params[this.dndParams[i]] = this[this.dndParams[i]];
+				}
+			}
+			this.dndController = new this.dndController(this, params);
+		}
+	},
+
+	_store2model: function(){
+		// summary:
+		//		User specified a store&query rather than model, so create model from store/query
+		this._v10Compat = true;
+		dojo.deprecated("Tree: from version 2.0, should specify a model object rather than a store/query");
+
+		var modelParams = {
+			id: this.id + "_ForestStoreModel",
+			store: this.store,
+			query: this.query,
+			childrenAttrs: this.childrenAttr
+		};
+
+		// Only override the model's mayHaveChildren() method if the user has specified an override
+		if(this.params.mayHaveChildren){
+			modelParams.mayHaveChildren = dojo.hitch(this, "mayHaveChildren");
+		}
+					
+		if(this.params.getItemChildren){
+			modelParams.getChildren = dojo.hitch(this, function(item, onComplete, onError){
+				this.getItemChildren((this._v10Compat && item === this.model.root) ? null : item, onComplete, onError);
+			});
+		}
+		this.model = new dijit.tree.ForestStoreModel(modelParams);
+		
+		// For backwards compatibility, the visibility of the root node is controlled by
+		// whether or not the user has specified a label
+		this.showRoot = Boolean(this.label);
+	},
+
+	_load: function(){
+		// summary:
+		//		Initial load of the tree.
+		//		Load root node (possibly hidden) and it's children.
+		this.model.getRoot(
+			dojo.hitch(this, function(item){
+				var rn = this.rootNode = this.tree._createTreeNode({
+					item: item,
+					tree: this,
+					isExpandable: true,
+					label: this.label || this.getLabel(item),
+					indent: this.showRoot ? 0 : -1
+				});
+				if(!this.showRoot){
+					rn.rowNode.style.display="none";
+				}
+				this.domNode.appendChild(rn.domNode);
+				this._itemNodeMap[this.model.getIdentity(item)] = rn;
+
+				rn._updateLayout();		// sets "dijitTreeIsRoot" CSS classname
+
+				// load top level children
+				this._expandNode(rn);
+			}),
+			function(err){
+				console.error(this, ": error loading root: ", err);
+			}
+		);
+	},
+
+	////////////// Data store related functions //////////////////////
+	// These just get passed to the model; they are here for back-compat
+
+	mayHaveChildren: function(/*dojo.data.Item*/ item){
+		// summary:
+		//		Deprecated.   This should be specified on the model itself.
+		//
+		//		Overridable function to tell if an item has or may have children.
+		//		Controls whether or not +/- expando icon is shown.
+		//		(For efficiency reasons we may not want to check if an element actually
+		//		has children until user clicks the expando node)
+		// tags:
+		//		deprecated
+	},
+
+	getItemChildren: function(/*dojo.data.Item*/ parentItem, /*function(items)*/ onComplete){
+		// summary:
+		//		Deprecated.   This should be specified on the model itself.
+		//
+		// 		Overridable function that return array of child items of given parent item,
+		//		or if parentItem==null then return top items in tree
+		// tags:
+		//		deprecated
+	},
+
+	///////////////////////////////////////////////////////
+	// Functions for converting an item to a TreeNode
+	getLabel: function(/*dojo.data.Item*/ item){
+		// summary:
+		//		Overridable function to get the label for a tree node (given the item)
+		// tags:
+		//		extension
+		return this.model.getLabel(item);	// String
+	},
+
+	getIconClass: function(/*dojo.data.Item*/ item, /*Boolean*/ opened){
+		// summary:
+		//		Overridable function to return CSS class name to display icon
+		// tags:
+		//		extension
+		return (!item || this.model.mayHaveChildren(item)) ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "dijitLeaf"
+	},
+
+	getLabelClass: function(/*dojo.data.Item*/ item, /*Boolean*/ opened){
+		// summary:
+		//		Overridable function to return CSS class name to display label
+		// tags:
+		//		extension
+	},
+	
+	getIconStyle: function(/*dojo.data.Item*/ item, /*Boolean*/ opened){
+		// summary:
+		//		Overridable function to return CSS styles to display icon
+		// returns:
+		//		Object suitable for input to dojo.style() like {backgroundImage: "url(...)"}
+		// tags:
+		//		extension
+	},
+
+	getLabelStyle: function(/*dojo.data.Item*/ item, /*Boolean*/ opened){
+		// summary:
+		//		Overridable function to return CSS styles to display label
+		// returns:
+		//		Object suitable for input to dojo.style() like {color: "red", background: "green"}
+		// tags:
+		//		extension
+	},
+
+	/////////// Keyboard and Mouse handlers ////////////////////
+
+	_onKeyPress: function(/*Event*/ e){
+		// summary:
+		//		Translates keypress events into commands for the controller
+		if(e.altKey){ return; }
+		var dk = dojo.keys;
+		var treeNode = dijit.getEnclosingWidget(e.target);
+		if(!treeNode){ return; }
+
+		var key = e.charOrCode;
+		if(typeof key == "string"){  // handle printables (letter navigation)
+			// Check for key navigation.
+			if(!e.altKey && !e.ctrlKey && !e.shiftKey && !e.metaKey){
+				this._onLetterKeyNav( { node: treeNode, key: key.toLowerCase() } );
+				dojo.stopEvent(e);
+			}
+		}else{  // handle non-printables (arrow keys)
+			var map = this._keyHandlerMap;
+			if(!map){
+				// setup table mapping keys to events
+				map = {};
+				map[dk.ENTER]="_onEnterKey";
+				map[this.isLeftToRight() ? dk.LEFT_ARROW : dk.RIGHT_ARROW]="_onLeftArrow";
+				map[this.isLeftToRight() ? dk.RIGHT_ARROW : dk.LEFT_ARROW]="_onRightArrow";
+				map[dk.UP_ARROW]="_onUpArrow";
+				map[dk.DOWN_ARROW]="_onDownArrow";
+				map[dk.HOME]="_onHomeKey";
+				map[dk.END]="_onEndKey";
+				this._keyHandlerMap = map;
+			}
+			if(this._keyHandlerMap[key]){
+				this[this._keyHandlerMap[key]]( { node: treeNode, item: treeNode.item } );	
+				dojo.stopEvent(e);
+			}
+		}
+	},
+
+	_onEnterKey: function(/*Object*/ message){
+		this._publish("execute", { item: message.item, node: message.node} );
+		this.onClick(message.item, message.node);
+	},
+
+	_onDownArrow: function(/*Object*/ message){
+		// summary: down arrow pressed; get next visible node, set focus there
+		var node = this._getNextNode(message.node);
+		if(node && node.isTreeNode){
+			this.focusNode(node);
+		}	
+	},
+
+	_onUpArrow: function(/*Object*/ message){
+		// summary:
+		//		Up arrow pressed; move to previous visible node
+
+		var node = message.node;
+
+		// if younger siblings		
+		var previousSibling = node.getPreviousSibling();
+		if(previousSibling){
+			node = previousSibling;
+			// if the previous node is expanded, dive in deep
+			while(node.isExpandable && node.isExpanded && node.hasChildren()){
+				// move to the last child
+				var children = node.getChildren();
+				node = children[children.length-1];
+			}
+		}else{
+			// if this is the first child, return the parent
+			// unless the parent is the root of a tree with a hidden root
+			var parent = node.getParent();
+			if(!(!this.showRoot && parent === this.rootNode)){
+				node = parent;
+			}
+		}
+
+		if(node && node.isTreeNode){
+			this.focusNode(node);
+		}
+	},
+
+	_onRightArrow: function(/*Object*/ message){
+		// summary:
+		//		Right arrow pressed; go to child node
+		var node = message.node;
+
+		// if not expanded, expand, else move to 1st child
+		if(node.isExpandable && !node.isExpanded){
+			this._expandNode(node);
+		}else if(node.hasChildren()){
+			node = node.getChildren()[0];
+			if(node && node.isTreeNode){
+				this.focusNode(node);
+			}
+		}
+	},
+
+	_onLeftArrow: function(/*Object*/ message){
+		// summary:
+		//		Left arrow pressed.
+		//		If not collapsed, collapse, else move to parent.
+
+		var node = message.node;
+
+		if(node.isExpandable && node.isExpanded){
+			this._collapseNode(node);
+		}else{
+			var parent = node.getParent();
+			if(parent && parent.isTreeNode && !(!this.showRoot && parent === this.rootNode)){
+				this.focusNode(parent);
+			}
+		}
+	},
+
+	_onHomeKey: function(){
+		// summary:
+		//		Home key pressed; get first visible node, and set focus there
+		var node = this._getRootOrFirstNode();
+		if(node){
+			this.focusNode(node);
+		}
+	},
+
+	_onEndKey: function(/*Object*/ message){
+		// summary:
+		//		End key pressed; go to last visible node.
+
+		var node = this.rootNode;
+		while(node.isExpanded){
+			var c = node.getChildren();
+			node = c[c.length - 1];
+		}
+
+		if(node && node.isTreeNode){
+			this.focusNode(node);
+		}
+	},
+
+	_onLetterKeyNav: function(message){
+		// summary:
+		//		Letter key pressed; search for node starting with first char = key
+		var node = message.node, startNode = node, 
+			key = message.key;
+		do{
+			node = this._getNextNode(node);
+			//check for last node, jump to first node if necessary
+			if(!node){
+				node = this._getRootOrFirstNode();
+			}
+		}while(node !== startNode && (node.label.charAt(0).toLowerCase() != key));
+		if(node && node.isTreeNode){
+			// no need to set focus if back where we started
+			if(node !== startNode){
+				this.focusNode(node);
+			}
+		}
+	},
+
+	_onClick: function(/*Event*/ e){
+		// summary:
+		//		Translates click events into commands for the controller to process
+		var domElement = e.target;
+
+		// find node
+		var nodeWidget = dijit.getEnclosingWidget(domElement);	
+		if(!nodeWidget || !nodeWidget.isTreeNode){
+			return;
+		}
+
+		if( (this.openOnClick && nodeWidget.isExpandable) ||
+			(domElement == nodeWidget.expandoNode || domElement == nodeWidget.expandoNodeText) ){
+			// expando node was clicked, or label of a folder node was clicked; open it
+			if(nodeWidget.isExpandable){
+				this._onExpandoClick({node:nodeWidget});
+			}
+		}else{
+			this._publish("execute", { item: nodeWidget.item, node: nodeWidget} );
+			this.onClick(nodeWidget.item, nodeWidget);
+			this.focusNode(nodeWidget);
+		}
+		dojo.stopEvent(e);
+	},
+	_onDblClick: function(/*Event*/ e){
+		// summary:
+		//		Translates double-click events into commands for the controller to process
+		var domElement = e.target;
+
+		// find node
+		var nodeWidget = dijit.getEnclosingWidget(domElement);	
+		if(!nodeWidget || !nodeWidget.isTreeNode){
+			return;
+		}
+
+		if( (this.openOnDblClick && nodeWidget.isExpandable) ||
+			(domElement == nodeWidget.expandoNode || domElement == nodeWidget.expandoNodeText) ){
+			// expando node was clicked, or label of a folder node was clicked; open it
+			if(nodeWidget.isExpandable){
+				this._onExpandoClick({node:nodeWidget});
+			}
+		}else{
+			this._publish("execute", { item: nodeWidget.item, node: nodeWidget} );
+			this.onDblClick(nodeWidget.item, nodeWidget);
+			this.focusNode(nodeWidget);
+		}
+		dojo.stopEvent(e);
+	},
+
+	_onExpandoClick: function(/*Object*/ message){
+		// summary:
+		//		User clicked the +/- icon; expand or collapse my children.
+		var node = message.node;
+		
+		// If we are collapsing, we might be hiding the currently focused node.
+		// Also, clicking the expando node might have erased focus from the current node.
+		// For simplicity's sake just focus on the node with the expando.
+		this.focusNode(node);
+
+		if(node.isExpanded){
+			this._collapseNode(node);
+		}else{
+			this._expandNode(node);
+		}
+	},
+
+	onClick: function(/* dojo.data */ item, /*TreeNode*/ node){
+		// summary:
+		//		Callback when a tree node is clicked
+		// tags:
+		//		callback
+	},
+	onDblClick: function(/* dojo.data */ item, /*TreeNode*/ node){
+		// summary:
+		//		Callback when a tree node is double-clicked
+		// tags:
+		//		callback
+	},
+	onOpen: function(/* dojo.data */ item, /*TreeNode*/ node){
+		// summary:
+		//		Callback when a node is opened
+		// tags:
+		//		callback
+	},
+	onClose: function(/* dojo.data */ item, /*TreeNode*/ node){
+		// summary:
+		//		Callback when a node is closed
+		// tags:
+		//		callback
+	},
+
+	_getNextNode: function(node){
+		// summary:
+		//		Get next visible node
+
+		if(node.isExpandable && node.isExpanded && node.hasChildren()){
+			// if this is an expanded node, get the first child
+			return node.getChildren()[0];		// _TreeNode	
+		}else{
+			// find a parent node with a sibling
+			while(node && node.isTreeNode){
+				var returnNode = node.getNextSibling();
+				if(returnNode){
+					return returnNode;		// _TreeNode
+				}
+				node = node.getParent();
+			}
+			return null;
+		}
+	},
+
+	_getRootOrFirstNode: function(){
+		// summary:
+		//		Get first visible node
+		return this.showRoot ? this.rootNode : this.rootNode.getChildren()[0];
+	},
+
+	_collapseNode: function(/*_TreeNode*/ node){
+		// summary:
+		//		Called when the user has requested to collapse the node
+
+		if(node.isExpandable){
+			if(node.state == "LOADING"){
+				// ignore clicks while we are in the process of loading data
+				return;
+			}
+
+			node.collapse();
+			this.onClose(node.item, node);
+
+			if(node.item){
+				this._state(node.item,false);
+				this._saveState();
+			}
+		}
+	},
+
+	_expandNode: function(/*_TreeNode*/ node){
+		// summary:
+		//		Called when the user has requested to expand the node
+
+		if(!node.isExpandable){
+			return;
+		}
+
+		var model = this.model,
+			item = node.item;
+
+		switch(node.state){
+			case "LOADING":
+				// ignore clicks while we are in the process of loading data
+				return;
+
+			case "UNCHECKED":
+				// need to load all the children, and then expand
+				node.markProcessing();
+				var _this = this;
+				model.getChildren(item, function(items){
+						node.unmarkProcessing();
+						node.setChildItems(items);
+						_this._expandNode(node);
+					},
+					function(err){
+						console.error(_this, ": error loading root children: ", err);
+					});
+				break;
+
+			default:
+				// data is already loaded; just proceed
+				node.expand();
+				this.onOpen(node.item, node);
+
+				if(item){
+					this._state(item,true);
+					this._saveState();
+				}
+		}
+	},
+
+	////////////////// Miscellaneous functions ////////////////
+
+	focusNode: function(/* _tree.Node */ node){
+		// summary:
+		//		Focus on the specified node (which must be visible)
+		// tags:
+		//		protected
+
+		// set focus so that the label will be voiced using screen readers
+		node.labelNode.focus();
+	},
+
+	_onNodeFocus: function(/*Widget*/ node){
+		// summary:
+		//		Called when a TreeNode gets focus, either by user clicking
+		//		it, or programatically by arrow key handling code.
+		// description:
+		//		It marks that the current node is the selected one, and the previously
+		//		selected node no longer is.
+
+		if (node){
+			if(node != this.lastFocused){
+				// mark that the previously selected node is no longer the selected one
+				this.lastFocused.setSelected(false);
+			}
+
+			// mark that the new node is the currently selected one
+			node.setSelected(true);
+			this.lastFocused = node;
+		}
+	},
+
+	_onNodeMouseEnter: function(/*Widget*/ node){
+		// summary:
+		//		Called when mouse is over a node (onmouseenter event)
+	},
+
+	_onNodeMouseLeave: function(/*Widget*/ node){
+		// summary:
+		//		Called when mouse is over a node (onmouseenter event)
+	},
+
+	//////////////// Events from the model //////////////////////////
+	
+	_onItemChange: function(/*Item*/ item){
+		// summary:
+		//		Processes notification of a change to an item's scalar values like label
+		var model = this.model,
+			identity = model.getIdentity(item),
+			node = this._itemNodeMap[identity];
+
+		if(node){
+			node.setLabelNode(this.getLabel(item));
+			node._updateItemClasses(item);
+		}
+	},
+
+	_onItemChildrenChange: function(/*dojo.data.Item*/ parent, /*dojo.data.Item[]*/ newChildrenList){
+		// summary:
+		//		Processes notification of a change to an item's children
+		var model = this.model,
+			identity = model.getIdentity(parent),
+			parentNode = this._itemNodeMap[identity];
+
+		if(parentNode){
+			parentNode.setChildItems(newChildrenList);
+		}
+	},
+
+	_onItemDelete: function(/*Item*/ item){
+		// summary:
+		//		Processes notification of a deletion of an item
+		var model = this.model,
+			identity = model.getIdentity(item),
+			node = this._itemNodeMap[identity];
+
+		if(node){
+			var parent = node.getParent();
+			if(parent){
+				// if node has not already been orphaned from a _onSetItem(parent, "children", ..) call...
+				parent.removeChild(node);
+			}
+			node.destroyRecursive();
+			delete this._itemNodeMap[identity];
+		}
+	},
+
+	/////////////// Miscellaneous funcs
+	
+	_initState: function(){
+		// summary:
+		//		Load in which nodes should be opened automatically
+		if(this.persist){
+			var cookie = dojo.cookie(this.cookieName);
+			this._openedItemIds = {};
+			if(cookie){
+				dojo.forEach(cookie.split(','), function(item){
+					this._openedItemIds[item] = true;
+				}, this);
+			}
+		}
+	},
+	_state: function(item,expanded){
+		// summary:
+		//		Query or set expanded state for an item,
+		if(!this.persist){
+			return false;
+		}
+		var id=this.model.getIdentity(item);
+		if(arguments.length===1){
+			return this._openedItemIds[id];
+		}
+		if(expanded){
+			this._openedItemIds[id] = true;
+		}else{
+			delete this._openedItemIds[id];
+		}
+	},
+	_saveState: function(){
+		// summary:
+		//		Create and save a cookie with the currently expanded nodes identifiers
+		if(!this.persist){
+			return;
+		}
+		var ary = [];
+		for(var id in this._openedItemIds){
+			ary.push(id);
+		}
+		dojo.cookie(this.cookieName, ary.join(","), {expires:365});
+	},
+
+	destroy: function(){
+		if(this.rootNode){
+			this.rootNode.destroyRecursive();
+		}
+		if(this.dndController && !dojo.isString(this.dndController)){
+			this.dndController.destroy();
+		}
+		this.rootNode = null;
+		this.inherited(arguments);
+	},
+	
+	destroyRecursive: function(){
+		// A tree is treated as a leaf, not as a node with children (like a grid),
+		// but defining destroyRecursive for back-compat.
+		this.destroy();
+	},
+
+	_createTreeNode: function(/*Object*/ args){
+		// summary:
+		//		creates a TreeNode
+		// description:
+		//		Developers can override this method to define their own TreeNode class;
+		//		However it will probably be removed in a future release in favor of a way
+		//		of just specifying a widget for the label, rather than one that contains
+		//		the children too.
+		return new dijit._TreeNode(args);
+	}
+});
+
+// For back-compat.  TODO: remove in 2.0
+
+
+
+}
+
+if(!dojo._hasResource["dijit.form.TextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.TextBox"] = true;
+dojo.provide("dijit.form.TextBox");
+
+
+
+dojo.declare(
+	"dijit.form.TextBox",
+	dijit.form._FormValueWidget,
+	{
+		//	summary:
+		//		A base class for textbox form inputs
+
+		//	trim: Boolean
+		//		Removes leading and trailing whitespace if true.  Default is false.
+		trim: false,
+
+		//	uppercase: Boolean
+		//		Converts all characters to uppercase if true.  Default is false.
+		uppercase: false,
+
+		//	lowercase: Boolean
+		//		Converts all characters to lowercase if true.  Default is false.
+		lowercase: false,
+
+		//	propercase: Boolean
+		//		Converts the first character of each word to uppercase if true.
+		propercase: false,
+
+		//	maxLength: String
+		//		HTML INPUT tag maxLength declaration.
+		maxLength: "",
+
+		templateString:"<input class=\"dijit dijitReset dijitLeft\" dojoAttachPoint='textbox,focusNode'\n\tdojoAttachEvent='onmouseenter:_onMouse,onmouseleave:_onMouse'\n\tautocomplete=\"off\" type=\"${type}\" ${nameAttrSetting}\n\t/>\n",
+		baseClass: "dijitTextBox",
+
+		attributeMap: dojo.delegate(dijit.form._FormValueWidget.prototype.attributeMap, {
+			maxLength: "focusNode" 
+		}),
+
+		_getValueAttr: function(){
+			// summary:
+			//		Hook so attr('value') works as we like.
+			// description:
+			//		For `dijit.form.TextBox` this basically returns the value of the <input>.
+			//
+			//		For `dijit.form.MappedTextBox` subclasses, which have both
+			//		a "displayed value" and a separate "submit value",
+			//		This treats the "displayed value" as the master value, computing the
+			//		submit value from it via this.parse().
+			return this.parse(this.attr('displayedValue'), this.constraints);
+		},
+
+		_setValueAttr: function(value, /*Boolean?*/ priorityChange, /*String?*/ formattedValue){
+			// summary:
+			//		Hook so attr('value', ...) works.
+			//
+			// description: 
+			//		Sets the value of the widget to "value" which can be of
+			//		any type as determined by the widget.
+			//
+			// value:
+			//		The visual element value is also set to a corresponding,
+			//		but not necessarily the same, value.
+			//
+			// formattedValue:
+			//		If specified, used to set the visual element value,
+			//		otherwise a computed visual value is used.
+			//
+			// priorityChange:
+			//		If true, an onChange event is fired immediately instead of 
+			//		waiting for the next blur event.
+
+			var filteredValue;
+			if(value !== undefined){
+				// TODO: this is calling filter() on both the display value and the actual value.
+				// I added a comment to the filter() definition about this, but it should be changed.
+				filteredValue = this.filter(value);
+				if(typeof formattedValue != "string"){
+					if(filteredValue !== null && ((typeof filteredValue != "number") || !isNaN(filteredValue))){
+						formattedValue = this.filter(this.format(filteredValue, this.constraints));
+					}else{ formattedValue = ''; }
+				}
+			}
+			if(formattedValue != null && formattedValue != undefined && ((typeof formattedValue) != "number" || !isNaN(formattedValue)) && this.textbox.value != formattedValue){
+				this.textbox.value = formattedValue;
+			}
+			this.inherited(arguments, [filteredValue, priorityChange]);
+		},
+
+		// displayedValue: String
+		//		For subclasses like ComboBox where the displayed value
+		//		(ex: Kentucky) and the serialized value (ex: KY) are different,
+		//		this represents the displayed value.
+		//
+		//		Setting 'displayedValue' through attr('displayedValue', ...)
+		//		updates 'value', and vice-versa.  Othewise 'value' is updated
+		//		from 'displayedValue' periodically, like onBlur etc.
+		//
+		//		TODO: move declaration to MappedTextBox?
+		//		Problem is that ComboBox references displayedValue,
+		//		for benefit of FilteringSelect.
+		displayedValue: "",
+
+		getDisplayedValue: function(){
+			// summary:
+			//		Deprecated.   Use attr('displayedValue') instead.
+			// tags:
+			//		deprecated
+			dojo.deprecated(this.declaredClass+"::getDisplayedValue() is deprecated. Use attr('displayedValue') instead.", "", "2.0");
+			return this.attr('displayedValue');
+		},
+
+		_getDisplayedValueAttr: function(){
+			// summary:
+			//		Hook so attr('displayedValue') works.
+			// description:
+			//		Returns the displayed value (what the user sees on the screen),
+			// 		after filtering (ie, trimming spaces etc.).
+			//
+			//		For some subclasses of TextBox (like ComboBox), the displayed value
+			//		is different from the serialized value that's actually 
+			//		sent to the server (see dijit.form.ValidationTextBox.serialize)
+			
+			return this.filter(this.textbox.value);
+		},
+
+		setDisplayedValue: function(/*String*/value){
+			// summary:
+			//		Deprecated.   Use attr('displayedValue', ...) instead.
+			// tags:
+			//		deprecated
+			dojo.deprecated(this.declaredClass+"::setDisplayedValue() is deprecated. Use attr('displayedValue', ...) instead.", "", "2.0");
+			this.attr('displayedValue', value);
+		},
+			
+		_setDisplayedValueAttr: function(/*String*/value){
+			// summary:
+			//		Hook so attr('displayedValue', ...) works.
+			//	description: 
+			//		Sets the value of the visual element to the string "value".
+			//		The widget value is also set to a corresponding,
+			//		but not necessarily the same, value.
+
+			if(value === null || value === undefined){ value = '' }
+			else if(typeof value != "string"){ value = String(value) }
+			this.textbox.value = value;
+			this._setValueAttr(this.attr('value'), undefined, value);
+		},
+
+		format: function(/* String */ value, /* Object */ constraints){
+			// summary:
+			//		Replacable function to convert a value to a properly formatted string.
+			// tags:
+			//		protected extension
+			return ((value == null || value == undefined) ? "" : (value.toString ? value.toString() : value));
+		},
+
+		parse: function(/* String */ value, /* Object */ constraints){
+			// summary:
+			//		Replacable function to convert a formatted string to a value
+			// tags:
+			//		protected extension
+
+			return value;	// String
+		},
+
+		_refreshState: function(){
+			// summary:
+			//		After the user types some characters, etc., this method is
+			//		called to check the field for validity etc.  The base method
+			//		in `dijit.form.TextBox` does nothing, but subclasses override.
+			// tags:
+			//		protected
+		},
+
+		_onInput: function(e){
+			if(e && e.type && /key/i.test(e.type) && e.keyCode){
+				switch(e.keyCode){
+					case dojo.keys.SHIFT:
+					case dojo.keys.ALT:
+					case dojo.keys.CTRL:
+					case dojo.keys.TAB:
+						return;
+				}
+			}
+			if(this.intermediateChanges){
+				var _this = this;
+				// the setTimeout allows the key to post to the widget input box
+				setTimeout(function(){ _this._handleOnChange(_this.attr('value'), false); }, 0);
+			}
+			this._refreshState();
+		},
+
+		postCreate: function(){
+			// setting the value here is needed since value="" in the template causes "undefined"
+			// and setting in the DOM (instead of the JS object) helps with form reset actions
+			this.textbox.setAttribute("value", this.textbox.value); // DOM and JS values shuld be the same
+			this.inherited(arguments);
+			if(dojo.isMoz || dojo.isOpera){
+				this.connect(this.textbox, "oninput", this._onInput);
+			}else{
+				this.connect(this.textbox, "onkeydown", this._onInput);
+				this.connect(this.textbox, "onkeyup", this._onInput);
+				this.connect(this.textbox, "onpaste", this._onInput);
+				this.connect(this.textbox, "oncut", this._onInput);
+			}
+
+			/*#5297:if(this.srcNodeRef){
+				dojo.style(this.textbox, "cssText", this.style);
+				this.textbox.className += " " + this["class"];
+			}*/
+			this._layoutHack();
+		},
+
+		_blankValue: '', // if the textbox is blank, what value should be reported
+		filter: function(val){
+			// summary:
+			//		Auto-corrections (such as trimming) that are applied to textbox
+			//		value on blur or form submit.
+			// description:
+			//		For MappedTextBox subclasses, this is called twice
+			// 			- once with the display value
+			//			- once the value as set/returned by attr('value', ...)
+			//		and attr('value'), ex: a Number for NumberTextBox.
+			//
+			//		In the latter case it does corrections like converting null to NaN.  In
+			//		the former case the NumberTextBox.filter() method calls this.inherited()
+			//		to execute standard trimming code in TextBox.filter().
+			//
+			//		TODO: break this into two methods in 2.0
+			//
+			// tags:
+			//		protected extension
+			if(val === null){ return this._blankValue; }
+			if(typeof val != "string"){ return val; }
+			if(this.trim){
+				val = dojo.trim(val);
+			}
+			if(this.uppercase){
+				val = val.toUpperCase();
+			}
+			if(this.lowercase){
+				val = val.toLowerCase();
+			}
+			if(this.propercase){
+				val = val.replace(/[^\s]+/g, function(word){
+					return word.substring(0,1).toUpperCase() + word.substring(1);
+				});
+			}
+			return val;
+		},
+
+		_setBlurValue: function(){
+			this._setValueAttr(this.attr('value'), true);
+		},
+
+		_onBlur: function(e){
+			if(this.disabled){ return; }
+			this._setBlurValue();
+			this.inherited(arguments);
+		},
+
+		_onFocus: function(e){
+			if(this.disabled){ return; }
+			this._refreshState();
+			this.inherited(arguments);
+		},
+
+		reset: function(){
+			// Overrides dijit._FormWidget.reset().
+			// Additionally resets the displayed textbox value to ''
+			this.textbox.value = '';
+			this.inherited(arguments);
+		}
+	}
+);
+
+dijit.selectInputText = function(/*DomNode*/element, /*Number?*/ start, /*Number?*/ stop){
+	// summary:
+	//		Select text in the input element argument, from start (default 0), to stop (default end).
+
+	// TODO: use functions in _editor/selection.js?
+	var _window = dojo.global;
+	var _document = dojo.doc;
+	element = dojo.byId(element);
+	if(isNaN(start)){ start = 0; }
+	if(isNaN(stop)){ stop = element.value ? element.value.length : 0; }
+	element.focus();
+	if(_document["selection"] && dojo.body()["createTextRange"]){ // IE
+		if(element.createTextRange){
+			var range = element.createTextRange();
+			with(range){
+				collapse(true);
+				moveStart("character", start);
+				moveEnd("character", stop);
+				select();
+			}
+		}
+	}else if(_window["getSelection"]){
+		var selection = _window.getSelection();	// TODO: unused, remove
+		// FIXME: does this work on Safari?
+		if(element.setSelectionRange){
+			element.setSelectionRange(start, stop);
+		}
+	}
+};
+
+}
+
+if(!dojo._hasResource["dijit.InlineEditBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.InlineEditBox"] = true;
+dojo.provide("dijit.InlineEditBox");
+
+
+
+
+
+
+
+
+
+
+dojo.declare("dijit.InlineEditBox",
+	dijit._Widget,
+	{
+	// summary:
+	//		An element with in-line edit capabilitites
+	//
+	// description:
+	//		Behavior for an existing node (`<p>`, `<div>`, `<span>`, etc.) so that
+	// 		when you click it, an editor shows up in place of the original
+	//		text.  Optionally, Save and Cancel button are displayed below the edit widget.
+	//		When Save is clicked, the text is pulled from the edit
+	//		widget and redisplayed and the edit widget is again hidden.
+	//		By default a plain Textarea widget is used as the editor (or for
+	//		inline values a TextBox), but you can specify an editor such as
+	//		dijit.Editor (for editing HTML) or a Slider (for adjusting a number).
+	//		An edit widget must support the following API to be used:
+	//			- displayedValue or value as initialization parameter,
+	//			and available through attr('displayedValue') / attr('value')
+	//			- void focus()
+	//			- DOM-node focusNode = node containing editable text
+
+	// editing: [readonly] Boolean
+	//		Is the node currently in edit mode?
+	editing: false,
+
+	// autoSave: Boolean
+	//		Changing the value automatically saves it; don't have to push save button
+	//		(and save button isn't even displayed)
+	autoSave: true,
+
+	// buttonSave: String
+	//		Save button label
+	buttonSave: "",
+
+	// buttonCancel: String
+	//		Cancel button label
+	buttonCancel: "",
+
+	// renderAsHtml: Boolean
+	//		Set this to true if the specified Editor's value should be interpreted as HTML
+	//		rather than plain text (ex: `dijit.Editor`)
+	renderAsHtml: false,
+
+	// editor: String
+	//		Class name for Editor widget
+	editor: "dijit.form.TextBox",
+
+	// editorParams: Object
+	//		Set of parameters for editor, like {required: true}
+	editorParams: {},
+
+	onChange: function(value){
+		// summary:
+		//		Set this handler to be notified of changes to value.
+		// tags:
+		//		callback
+	},
+	
+	onCancel: function(){
+		// summary:
+		//		Set this handler to be notified when editing is cancelled.
+		// tags:
+		//		callback
+	},
+
+	// width: String
+	//		Width of editor.  By default it's width=100% (ie, block mode).
+	width: "100%",
+
+	// value: String
+	//		The display value of the widget in read-only mode
+	value: "",
+
+	// noValueIndicator: [const] String
+	//		The text that gets displayed when there is no value (so that the user has a place to click to edit)
+	noValueIndicator: "<span style='font-family: wingdings; text-decoration: underline;'>    &#x270d;    </span>",
+
+	constructor: function(){
+		// summary:
+		//		Sets up private arrays etc.
+		// tags:
+		//		private
+		this.editorParams = {};
+	},
+
+	postMixInProperties: function(){
+		this.inherited(arguments);
+
+		// save pointer to original source node, since Widget nulls-out srcNodeRef
+		this.displayNode = this.srcNodeRef;
+
+		// connect handlers to the display node
+		var events = {
+			ondijitclick: "_onClick",
+			onmouseover: "_onMouseOver",
+			onmouseout: "_onMouseOut",
+			onfocus: "_onMouseOver",
+			onblur: "_onMouseOut"			
+		};
+		for(var name in events){
+			this.connect(this.displayNode, name, events[name]);
+		}
+		dijit.setWaiRole(this.displayNode, "button");
+		if(!this.displayNode.getAttribute("tabIndex")){
+			this.displayNode.setAttribute("tabIndex", 0);
+		}
+
+		this.attr('value', this.value || this.displayNode.innerHTML);
+	},
+
+	setDisabled: function(/*Boolean*/ disabled){
+		// summary:
+		//		Deprecated.   Use attr('disable', ...) instead.
+		// tags:
+		//		deprecated
+		dojo.deprecated("dijit.InlineEditBox.setDisabled() is deprecated.  Use attr('disabled', bool) instead.", "", "2.0");
+		this.attr('disabled', disabled);
+	},
+	_setDisabledAttr: function(/*Boolean*/ disabled){
+		// summary: 
+		//		Hook to make attr("disabled", ...) work.
+		//		Set disabled state of widget.
+		this.disabled = disabled;
+		dijit.setWaiState(this.domNode, "disabled", disabled);
+	},
+
+	_onMouseOver: function(){
+		// summary:
+		//		Handler for onmouseover event.
+		// tags:
+		//		private
+		dojo.addClass(this.displayNode, this.disabled ? "dijitDisabledClickableRegion" : "dijitClickableRegion");
+	},
+
+	_onMouseOut: function(){
+		// summary:
+		//		Handler for onmouseout event.
+		// tags:
+		//		private
+		dojo.removeClass(this.displayNode, this.disabled ? "dijitDisabledClickableRegion" : "dijitClickableRegion");
+	},
+
+	_onClick: function(/*Event*/ e){
+		// summary:
+		//		Handler for onclick event.
+		// tags:
+		//		private
+		if(this.disabled){ return; }
+		if(e){ dojo.stopEvent(e); }
+		this._onMouseOut();
+
+		// Since FF gets upset if you move a node while in an event handler for that node...
+		setTimeout(dojo.hitch(this, "edit"), 0);
+	},
+
+	edit: function(){
+		// summary:
+		//		Display the editor widget in place of the original (read only) markup.
+		// tags:
+		//		private
+
+		if(this.disabled || this.editing){ return; }
+		this.editing = true;
+
+		var editValue = 
+				(this.renderAsHtml ?
+				this.value :
+				this.value.replace(/\s*\r?\n\s*/g,"").replace(/<br\/?>/gi,"\n").replace(/>/g,">").replace(/</g,"<").replace(/&/g,"&").replace(/"/g,"\""));
+
+		// Placeholder for edit widget
+		// Put place holder (and eventually editWidget) before the display node so that it's positioned correctly
+		// when Calendar dropdown appears, which happens automatically on focus.
+		var placeholder = dojo.create("span", null, this.domNode, "before");
+
+		var ew = this.editWidget = new dijit._InlineEditor({
+			value: dojo.trim(editValue),
+			autoSave: this.autoSave,
+			buttonSave: this.buttonSave,
+			buttonCancel: this.buttonCancel,
+			renderAsHtml: this.renderAsHtml,
+			editor: this.editor,
+			editorParams: this.editorParams,
+			sourceStyle: dojo.getComputedStyle(this.displayNode),
+			save: dojo.hitch(this, "save"),
+			cancel: dojo.hitch(this, "cancel"),
+			width: this.width
+		}, placeholder);
+
+		// to avoid screen jitter, we first create the editor with position:absolute, visibility:hidden,
+		// and then when it's finished rendering, we switch from display mode to editor
+		var ews = ew.domNode.style;
+		this.displayNode.style.display="none";
+		ews.position = "static";
+		ews.visibility = "visible";
+
+		// Replace the display widget with edit widget, leaving them both displayed for a brief time so that
+		// focus can be shifted without incident.  (browser may needs some time to render the editor.)
+		this.domNode = ew.domNode;
+		setTimeout(function(){
+			ew.focus();
+			ew._resetValue = ew.getValue();
+		}, 100);
+	},
+
+	_showText: function(/*Boolean*/ focus){
+		// summary:
+		//		Revert to display mode, and optionally focus on display node
+		// tags:
+		//		private
+
+		// display the read-only text and then quickly hide the editor (to avoid screen jitter)
+		this.displayNode.style.display="";
+		var ew = this.editWidget;
+		var ews = ew.domNode.style;
+		ews.position="absolute";
+		ews.visibility="hidden";
+
+		this.domNode = this.displayNode;
+
+		if(focus){
+			dijit.focus(this.displayNode);
+		}
+		ews.display = "none";
+		// give the browser some time to render the display node and then shift focus to it
+		// and hide the edit widget before garbage collecting the edit widget
+		setTimeout(function(){
+			ew.destroy();
+			delete ew;
+			if(dojo.isIE){
+				// messing with the DOM tab order can cause IE to focus the body - so restore
+				dijit.focus(dijit.getFocus());
+			}
+		}, 1000); // no hurry - wait for things to quiesce
+	},
+
+	save: function(/*Boolean*/ focus){
+		// summary:
+		//		Save the contents of the editor and revert to display mode.
+		// focus: Boolean
+		//		Focus on the display mode text
+		// tags:
+		//		private
+		if(this.disabled || !this.editing){ return; }
+		this.editing = false;
+
+		var value = this.editWidget.getValue() + "";
+		this.attr('value', this.renderAsHtml? value
+			: value.replace(/&/gm, "&").replace(/</gm, "<").replace(/>/gm, ">").replace(/"/gm, """).replace(/\n/g, "<br>")
+		);
+
+		// tell the world that we have changed
+		this.onChange(value);
+
+		this._showText(focus);	
+	},
+
+	setValue: function(/*String*/ val){
+		// summary:
+		//		Deprecated.   Use attr('value', ...) instead.
+		// tags:
+		//		deprecated
+		dojo.deprecated("dijit.InlineEditBox.setValue() is deprecated.  Use attr('value', ...) instead.", "", "2.0");
+		return this.attr("value", val);
+	},
+	_setValueAttr: function(/*String*/ val){
+		// summary:
+		// 		Hook to make attr("value", ...) work.
+		//		Inserts specified HTML value into this node, or an "input needed" character if node is blank.
+		this.value = val;
+		this.displayNode.innerHTML = dojo.trim(val) || this.noValueIndicator;
+	},
+
+	getValue: function(){
+		// summary:
+		//		Deprecated.   Use attr('value') instead.
+		// tags:
+		//		deprecated
+		dojo.deprecated("dijit.InlineEditBox.getValue() is deprecated.  Use attr('value') instead.", "", "2.0");
+		return this.attr("value");
+	},
+
+	cancel: function(/*Boolean*/ focus){
+		// summary:
+		//		Revert to display mode, discarding any changes made in the editor
+		// tags:
+		//		private
+
+		this.editing = false;
+		
+		// tell the world that we have no changes
+		this.onCancel();
+		
+		this._showText(focus);
+	}
+});
+
+dojo.declare(
+	"dijit._InlineEditor",
+	 [dijit._Widget, dijit._Templated],
+{
+	// summary:
+	// 		Internal widget used by InlineEditBox, displayed when in editing mode
+	//		to display the editor and maybe save/cancel buttons.  Calling code should
+	//		connect to save/cancel methods to detect when editing is finished
+	//
+	//		Has mainly the same parameters as InlineEditBox, plus these values:
+	//
+	// style: Object
+	//		Set of CSS attributes of display node, to replicate in editor
+	//
+	// value: String
+	//		Value as an HTML string or plain text string, depending on renderAsHTML flag
+
+	templateString:"<span dojoAttachPoint=\"editNode\" waiRole=\"presentation\" style=\"position: absolute; visibility:hidden\" class=\"dijitReset dijitInline\"\n\tdojoAttachEvent=\"onkeypress: _onKeyPress\" \n\t><span dojoAttachPoint=\"editorPlaceholder\"></span\n\t><span dojoAttachPoint=\"buttonContainer\"\n\t\t><button class='saveButton' dojoAttachPoint=\"saveButton\" dojoType=\"dijit.form.Button\" dojoAttachEvent=\"onClick:save\" disabled=\"true\" label=\"${buttonSave}\"></button\n\t\t> [...]
+	widgetsInTemplate: true,
+
+	postMixInProperties: function(){
+		this.inherited(arguments);
+		this.messages = dojo.i18n.getLocalization("dijit", "common", this.lang);
+		dojo.forEach(["buttonSave", "buttonCancel"], function(prop){
+			if(!this[prop]){ this[prop] = this.messages[prop]; }
+		}, this);
+	},
+
+	postCreate: function(){
+		// Create edit widget in place in the template
+		var cls = dojo.getObject(this.editor);
+
+		// Copy the style from the source
+		// Don't copy ALL properties though, just the necessary/applicable ones
+		var srcStyle = this.sourceStyle;
+		var editStyle = "line-height:" + srcStyle.lineHeight + ";";
+		dojo.forEach(["Weight","Family","Size","Style"], function(prop){
+			editStyle += "font-"+prop+":"+srcStyle["font"+prop]+";";
+		}, this);
+		dojo.forEach(["marginTop","marginBottom","marginLeft", "marginRight"], function(prop){
+			this.domNode.style[prop] = srcStyle[prop];
+		}, this);
+		if(this.width=="100%"){
+			// block mode
+			editStyle += "width:100%;";
+			this.domNode.style.display = "block";
+		}else{
+			// inline-block mode
+			editStyle += "width:" + (this.width + (Number(this.width)==this.width ? "px" : "")) + ";";
+		}
+		this.editorParams.style = editStyle;
+		this.editorParams[ "displayedValue" in cls.prototype ? "displayedValue" : "value"] = this.value;
+		var ew = this.editWidget = new cls(this.editorParams, this.editorPlaceholder);
+
+		this.connect(ew, "onChange", "_onChange");
+
+		// Monitor keypress on the edit widget.   Note that edit widgets do a stopEvent() on ESC key (to
+		// prevent Dialog from closing when the user just wants to revert the value in the edit widget),
+		// so this is the only way we can see the key press event.
+		this.connect(ew, "onKeyPress", "_onKeyPress");
+		this.connect(ew, "onKeyUp", "_onKeyPress"); // in case ESC was eaten but changed value
+
+		if(this.autoSave){
+			this.buttonContainer.style.display="none";
+		}
+	},
+
+	destroy: function(){
+		this.editWidget.destroy();
+		this.inherited(arguments);
+	},
+
+	getValue: function(){
+		// summary:
+		//		Return the [display] value of the edit widget
+		var ew = this.editWidget;
+		return ew.attr("displayedValue" in ew ? "displayedValue" : "value");
+	},
+
+	_onKeyPress: function(e){
+		// summary:
+		//		Handler for keypress in the edit box (see template).
+		// description:
+		//		For autoSave widgets, if Esc/Enter, call cancel/save.
+		//		For non-autoSave widgets, enable save button if the text value is
+		//		different than the original value.
+		// tags:
+		//		private
+
+		if(this._exitInProgress){
+			return;
+		}
+		if(this.autoSave){
+			if(e.altKey || e.ctrlKey){ return; }
+			// If Enter/Esc pressed, treat as save/cancel.
+			if(e.charOrCode == dojo.keys.ESCAPE){
+				dojo.stopEvent(e);
+				this._exitInProgress = true;
+				this.cancel(true);
+			}else if(e.charOrCode == dojo.keys.ENTER && this.editWidget.focusNode.tagName == "INPUT"){
+				dojo.stopEvent(e);
+				this._exitInProgress = true;
+				this.save(true);
+			}else if(e.charOrCode === dojo.keys.TAB){
+				this._exitInProgress = true;
+				// allow the TAB to change focus before we mess with the DOM: #6227
+				// Expounding by request:
+				// 	The current focus is on the edit widget input field.
+				//	save() will hide and destroy this widget.
+				//	We want the focus to jump from the currently hidden
+				//	displayNode, but since it's hidden, it's impossible to
+				//	unhide it, focus it, and then have the browser focus
+				//	away from it to the next focusable element since each
+				//	of these events is asynchronous and the focus-to-next-element
+				//	is already queued.
+				//	So we allow the browser time to unqueue the move-focus event 
+				//	before we do all the hide/show stuff.
+				setTimeout(dojo.hitch(this, "save", false), 0);
+			}
+		}else{
+			var _this = this;
+			// Delay before calling getValue().
+			// The delay gives the browser a chance to update the native value.
+			setTimeout(
+				function(){
+					_this._onChange(); // handle save button
+				}, 100);
+		}
+	},
+
+	_onBlur: function(){
+		// summary:
+		//		Called when focus moves outside the editor
+		// tags:
+		//		private
+
+		this.inherited(arguments);
+		if(this._exitInProgress){
+			// when user clicks the "save" button, focus is shifted back to display text, causing this
+			// function to be called, but in that case don't do anything
+			return;
+		}
+		if(this.autoSave){
+			this._exitInProgress = true;
+			if(this.getValue() == this._resetValue){
+				this.cancel(false);
+			}else{
+				this.save(false);
+			}
+		}
+	},
+
+	_onChange: function(){
+		// summary:
+		//		Called when the underlying widget fires an onChange event,
+		//		which means that the user has finished entering the value
+		// tags:
+		//		private
+
+		if(this._exitInProgress){
+			// TODO: the onChange event might happen after the return key for an async widget
+			// like FilteringSelect.  Shouldn't be deleting the edit widget on end-of-edit
+			return;
+		}
+		if(this.autoSave){
+			this._exitInProgress = true;
+			this.save(true);
+		}else{
+			// in case the keypress event didn't get through (old problem with Textarea that has been fixed
+			// in theory) or if the keypress event comes too quickly and the value inside the Textarea hasn't
+			// been updated yet)
+			this.saveButton.attr("disabled", (this.getValue() == this._resetValue) || !this.enableSave());
+		}
+	},
+	
+	enableSave: function(){
+		// summary:
+		//		User overridable function returning a Boolean to indicate
+		// 		if the Save button should be enabled or not - usually due to invalid conditions
+		// tags:
+		//		extension
+		return this.editWidget.isValid ? this.editWidget.isValid() : true;
+	},
+
+	focus: function(){
+		// summary:
+		//		Focus on the edit widget.
+		this.editWidget.focus();
+		dijit.selectInputText(this.editWidget.focusNode);
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit.form.CheckBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.CheckBox"] = true;
+dojo.provide("dijit.form.CheckBox");
+
+
+
+dojo.declare(
+	"dijit.form.CheckBox",
+	dijit.form.ToggleButton,
+	{
+		// summary:
+		// 		Same as an HTML checkbox, but with fancy styling.
+		//
+		// description:
+		// User interacts with real html inputs.
+		// On onclick (which occurs by mouse click, space-bar, or
+		// using the arrow keys to switch the selected radio button),
+		// we update the state of the checkbox/radio.
+		//
+		// There are two modes:
+		//   1. High contrast mode
+		//   2. Normal mode
+		// In case 1, the regular html inputs are shown and used by the user.
+		// In case 2, the regular html inputs are invisible but still used by
+		// the user. They are turned quasi-invisible and overlay the background-image.
+
+		templateString:"<div class=\"dijitReset dijitInline\" waiRole=\"presentation\"\n\t><input\n\t \t${nameAttrSetting} type=\"${type}\" ${checkedAttrSetting}\n\t\tclass=\"dijitReset dijitCheckBoxInput\"\n\t\tdojoAttachPoint=\"focusNode\"\n\t \tdojoAttachEvent=\"onmouseover:_onMouse,onmouseout:_onMouse,onclick:_onClick\"\n/></div>\n",
+
+		baseClass: "dijitCheckBox",
+
+		// type: [private] String
+		//		type attribute on <input> node.
+		//		Overrides `dijit.form.Button.type`.   Users should not change this value.
+		type: "checkbox",
+
+		// value: String
+		//		As an initialization parameter, equivalent to value field on normal checkbox
+		//		(if checked, the value is passed as the value when form is submitted).
+		//
+		//		However, attr('value') will return either the string or false depending on
+		//		whether or not the checkbox is checked.
+		//
+		//		attr('value', string) will check the checkbox and change the value to the
+		//		specified string
+		//
+		//		attr('value', boolean) will change the checked state.
+		value: "on",
+
+		_setValueAttr: function(/*String or Boolean*/ newValue){
+			// summary:
+			//		Handler for value= attribute to constructor, and also calls to
+			//		attr('value', val).
+			// description:
+			//		During initialization, just saves as attribute to the <input type=checkbox>.
+			//		
+			//		After initialization,
+			//		when passed a boolean, controls whether or not the CheckBox is checked.
+			//		If passed a string, changes the value attribute of the CheckBox (the one
+			//		specified as "value" when the CheckBox was constructed (ex: <input
+			//		dojoType="dijit.CheckBox" value="chicken">)
+			if(typeof newValue == "string"){
+				this.value = newValue;
+				dojo.attr(this.focusNode, 'value', newValue);
+				newValue = true;
+			}
+			if(this._created){
+				this.attr('checked', newValue);
+			}
+		},
+		_getValueAttr: function(){
+			// summary:
+			//		Hook so attr('value') works.
+			// description:
+			//		If the CheckBox is checked, returns the value attribute.
+			//		Otherwise returns false.
+			return (this.checked ? this.value : false);
+		},
+
+		postMixInProperties: function(){
+			if(this.value == ""){
+				this.value = "on";
+			}
+
+			// Need to set initial checked state as part of template, so that form submit works.
+			// dojo.attr(node, "checked", bool) doesn't work on IEuntil node has been attached
+			// to <body>, see #8666
+			this.checkedAttrSetting = this.checked ? "checked" : "";
+
+			this.inherited(arguments);
+		},
+		
+		 _fillContent: function(/*DomNode*/ source){
+			// Override Button::_fillContent() since it doesn't make sense for CheckBox,
+			// since CheckBox doesn't even have a container
+		},
+
+		reset: function(){
+			// Override ToggleButton.reset()
+
+			this._hasBeenBlurred = false;
+
+			this.attr('checked', this.params.checked || false);
+
+			// Handle unlikely event that the <input type=checkbox> value attribute has changed
+			this.value = this.params.value || "on";
+			dojo.attr(this.focusNode, 'value', this.value);
+		},
+		
+		_onFocus: function(){
+			if(this.id){
+				dojo.query("label[for='"+this.id+"']").addClass("dijitFocusedLabel");
+			}
+		},
+
+		_onBlur: function(){
+			if(this.id){
+				dojo.query("label[for='"+this.id+"']").removeClass("dijitFocusedLabel");
+			}
+		}
+	}
+);
+
+dojo.declare(
+	"dijit.form.RadioButton",
+	dijit.form.CheckBox,
+	{
+		// summary:
+		// 		Same as an HTML radio, but with fancy styling.
+
+		type: "radio",
+		baseClass: "dijitRadio",
+
+		_setCheckedAttr: function(/*Boolean*/ value){
+			// If I am being checked then have to deselect currently checked radio button
+			this.inherited(arguments);
+			if(!this._created){ return; }
+			if(value){
+				var _this = this;
+				// search for radio buttons with the same name that need to be unchecked
+				dojo.query("INPUT[type=radio]", this.focusNode.form||dojo.doc).forEach( // can't use name= since dojo.query doesn't support [] in the name
+					function(inputNode){
+						if(inputNode.name == _this.name && inputNode != _this.focusNode && inputNode.form == _this.focusNode.form){
+							var widget = dijit.getEnclosingWidget(inputNode);
+							if(widget && widget.checked){
+								widget.attr('checked', false);
+							}
+						}
+					}
+				);
+			}
+		},
+
+		_clicked: function(/*Event*/ e){
+			if(!this.checked){
+				this.attr('checked', true);
+			}
+		}
+	}
+);
+
+}
+
+if(!dojo._hasResource["dijit.form.ValidationTextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.ValidationTextBox"] = true;
+dojo.provide("dijit.form.ValidationTextBox");
+
+
+
+
+
+
+
+
+/*=====
+	dijit.form.ValidationTextBox.__Constraints = function(){
+		// locale: String
+		//		locale used for validation, picks up value from this widget's lang attribute
+		// _flags_: anything
+		//		various flags passed to regExpGen function
+		this.locale = "";
+		this._flags_ = "";
+	}
+=====*/
+
+dojo.declare(
+	"dijit.form.ValidationTextBox",
+	dijit.form.TextBox,
+	{
+		// summary:
+		//		Base class for textbox widgets with the ability to validate content of various types and provide user feedback.
+		// tags:
+		//		protected
+
+		templateString:"<div class=\"dijit dijitReset dijitInlineTable dijitLeft\"\n\tid=\"widget_${id}\"\n\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\" waiRole=\"presentation\"\n\t><div style=\"overflow:hidden;\"\n\t\t><div class=\"dijitReset dijitValidationIcon\"><br></div\n\t\t><div class=\"dijitReset dijitValidationIconText\">Χ</div\n\t\t><div class=\"dijitReset dijitInputField\"\n\t\t\t><input class=\"dijitReset\" dojoAttachPoint='textbox,focus [...]
+		baseClass: "dijitTextBox",
+
+		// required: Boolean
+		//		User is required to enter data into this field.
+		required: false,
+
+		// promptMessage: String
+		//		If defined, display this hint string immediately on focus to the textbox, if empty.
+		//		Think of this like a tooltip that tells the user what to do, not an error message
+		//		that tells the user what they've done wrong.
+		//
+		//		Message disappears when user starts typing.
+		promptMessage: "",
+
+		// invalidMessage: String
+		// 		The message to display if value is invalid.
+		invalidMessage: "$_unset_$", // read from the message file if not overridden
+
+		// constraints: dijit.form.ValidationTextBox.__Constraints
+		//		user-defined object needed to pass parameters to the validator functions
+		constraints: {},
+
+		// regExp: [extension protected] String
+		//		regular expression string used to validate the input
+		//		Do not specify both regExp and regExpGen
+		regExp: ".*",
+
+		regExpGen: function(/*dijit.form.ValidationTextBox.__Constraints*/constraints){
+			// summary:
+			//		Overridable function used to generate regExp when dependent on constraints.
+			//		Do not specify both regExp and regExpGen.
+			// tags:
+			//		extension protected
+			return this.regExp;     // String
+		},
+
+		// state: [readonly] String
+		//		Shows current state (ie, validation result) of input (Normal, Warning, or Error)
+		state: "",
+
+		// tooltipPosition: String[]
+		//		See description of `dijit.Tooltip.defaultPosition` for details on this parameter.
+		tooltipPosition: [],
+
+		_setValueAttr: function(){
+			// summary:
+			//		Hook so attr('value', ...) works.
+			this.inherited(arguments);
+			this.validate(this._focused);
+		},
+
+		validator: function(/*anything*/value, /*dijit.form.ValidationTextBox.__Constraints*/constraints){
+			// summary:
+			//		Overridable function used to validate the text input against the regular expression.
+			// tags:
+			//		protected
+			return (new RegExp("^(?:" + this.regExpGen(constraints) + ")"+(this.required?"":"?")+"$")).test(value) &&
+				(!this.required || !this._isEmpty(value)) &&
+				(this._isEmpty(value) || this.parse(value, constraints) !== undefined); // Boolean
+		},
+
+		_isValidSubset: function(){
+			// summary:
+			//		Returns true if the value is either already valid or could be made valid by appending characters.
+			//		This is used for validation while the user [may be] still typing.
+			return this.textbox.value.search(this._partialre) == 0;
+		},
+
+		isValid: function(/*Boolean*/ isFocused){
+			// summary:
+			//		Tests if value is valid.
+			//		Can override with your own routine in a subclass.
+			// tags:
+			//		protected
+			return this.validator(this.textbox.value, this.constraints);
+		},
+
+		_isEmpty: function(value){
+			// summary:
+			//		Checks for whitespace
+			return /^\s*$/.test(value); // Boolean
+		},
+
+		getErrorMessage: function(/*Boolean*/ isFocused){
+			// summary:
+			//		Return an error message to show if appropriate
+			// tags:
+			//		protected
+			return this.invalidMessage; // String
+		},
+
+		getPromptMessage: function(/*Boolean*/ isFocused){
+			// summary:
+			//		Return a hint message to show when widget is first focused
+			// tags:
+			//		protected
+			return this.promptMessage; // String
+		},
+
+		_maskValidSubsetError: true,
+		validate: function(/*Boolean*/ isFocused){
+			// summary:
+			//		Called by oninit, onblur, and onkeypress.
+			// description:
+			//		Show missing or invalid messages if appropriate, and highlight textbox field.
+			// tags:
+			//		protected
+			var message = "";
+			var isValid = this.disabled || this.isValid(isFocused);
+			if(isValid){ this._maskValidSubsetError = true; }
+			var isValidSubset = !isValid && isFocused && this._isValidSubset();
+			var isEmpty = this._isEmpty(this.textbox.value);
+			this.state = (isValid || (!this._hasBeenBlurred && isEmpty) || isValidSubset) ? "" : "Error";
+			if(this.state == "Error"){ this._maskValidSubsetError = false; }
+			this._setStateClass();
+			dijit.setWaiState(this.focusNode, "invalid", isValid ? "false" : "true");
+			if(isFocused){
+				if(isEmpty){
+					message = this.getPromptMessage(true);
+				}
+				if(!message && (this.state == "Error" || (isValidSubset && !this._maskValidSubsetError))){
+					message = this.getErrorMessage(true);
+				}
+			}
+			this.displayMessage(message);
+			return isValid;
+		},
+
+		// _message: String
+		//		Currently displayed message
+		_message: "",
+
+		displayMessage: function(/*String*/ message){
+			// summary:
+			//		Overridable method to display validation errors/hints.
+			//		By default uses a tooltip.
+			// tags:
+			//		extension
+			if(this._message == message){ return; }
+			this._message = message;
+			dijit.hideTooltip(this.domNode);
+			if(message){
+				dijit.showTooltip(message, this.domNode, this.tooltipPosition);
+			}
+		},
+
+		_refreshState: function(){
+			// Overrides TextBox._refreshState()
+			this.validate(this._focused);
+			this.inherited(arguments);
+		},
+
+		//////////// INITIALIZATION METHODS ///////////////////////////////////////
+
+		constructor: function(){
+			this.constraints = {};
+		},
+
+		postMixInProperties: function(){
+			this.inherited(arguments);
+			this.constraints.locale = this.lang;
+			this.messages = dojo.i18n.getLocalization("dijit.form", "validate", this.lang);
+			if(this.invalidMessage == "$_unset_$"){ this.invalidMessage = this.messages.invalidMessage; }
+			var p = this.regExpGen(this.constraints);
+			this.regExp = p;
+			var partialre = "";
+			// parse the regexp and produce a new regexp that matches valid subsets
+			// if the regexp is .* then there's no use in matching subsets since everything is valid
+			if(p != ".*"){ this.regExp.replace(/\\.|\[\]|\[.*?[^\\]{1}\]|\{.*?\}|\(\?[=:!]|./g,
+				function (re){
+					switch(re.charAt(0)){
+						case '{':
+						case '+':
+						case '?':
+						case '*':
+						case '^':
+						case '$':
+						case '|':
+						case '(': partialre += re; break;
+						case ")": partialre += "|$)"; break;
+						 default: partialre += "(?:"+re+"|$)"; break;
+					}
+				}
+			);}
+			try{ // this is needed for now since the above regexp parsing needs more test verification
+				"".search(partialre);
+			}catch(e){ // should never be here unless the original RE is bad or the parsing is bad
+				partialre = this.regExp;
+				console.warn('RegExp error in ' + this.declaredClass + ': ' + this.regExp);
+			} // should never be here unless the original RE is bad or the parsing is bad
+			this._partialre = "^(?:" + partialre + ")$";
+		},
+
+		_setDisabledAttr: function(/*Boolean*/ value){
+			this.inherited(arguments);	// call FormValueWidget._setDisabledAttr()
+			if(this.valueNode){
+				this.valueNode.disabled = value;
+			}
+			this._refreshState();
+		},
+		
+		_setRequiredAttr: function(/*Boolean*/ value){
+			this.required = value;
+			dijit.setWaiState(this.focusNode,"required", value);
+			this._refreshState();				
+		},
+
+		postCreate: function(){
+			if(dojo.isIE){ // IE INPUT tag fontFamily has to be set directly using STYLE
+				var s = dojo.getComputedStyle(this.focusNode);
+				if(s){
+					var ff = s.fontFamily;
+					if(ff){
+						this.focusNode.style.fontFamily = ff;
+					}
+				}
+			}
+			this.inherited(arguments);
+		},
+
+		reset:function(){
+			// Overrides dijit.form.TextBox.reset() by also
+			// hiding errors about partial matches
+			this._maskValidSubsetError = true;
+			this.inherited(arguments);
+		}
+	}
+);
+
+dojo.declare(
+	"dijit.form.MappedTextBox",
+	dijit.form.ValidationTextBox,
+	{
+		// summary:
+		//		A dijit.form.ValidationTextBox subclass which provides a base class for widgets that have
+		//		a visible formatted display value, and a serializable
+		//		value in a hidden input field which is actually sent to the server.
+		// description:
+		//		The visible display may
+		//		be locale-dependent and interactive.  The value sent to the server is stored in a hidden
+		//		input field which uses the `name` attribute declared by the original widget.  That value sent
+		//		to the server is defined by the dijit.form.MappedTextBox.serialize method and is typically
+		//		locale-neutral.
+		// tags:
+		//		protected
+
+		postMixInProperties: function(){
+			this.inherited(arguments);
+			
+			// we want the name attribute to go to the hidden <input>, not the displayed <input>,
+			// so override _FormWidget.postMixInProperties() setting of nameAttrSetting
+			this.nameAttrSetting = "";
+		},
+
+		serialize: function(/*anything*/val, /*Object?*/options){
+			// summary:
+			//		Overridable function used to convert the attr('value') result to a canonical
+			//		(non-localized) string.  For example, will print dates in ISO format, and
+			//		numbers the same way as they are represented in javascript.
+			// tags:
+			//		protected extension
+			return val.toString ? val.toString() : ""; // String
+		},
+
+		toString: function(){
+			// summary:
+			//		Returns widget as a printable string using the widget's value
+			// tags:
+			//		protected
+			var val = this.filter(this.attr('value')); // call filter in case value is nonstring and filter has been customized
+			return val != null ? (typeof val == "string" ? val : this.serialize(val, this.constraints)) : ""; // String
+		},
+
+		validate: function(){
+			// Overrides `dijit.form.TextBox.validate`
+			this.valueNode.value = this.toString();
+			return this.inherited(arguments);
+		},
+
+		buildRendering: function(){
+			// Overrides `dijit._Templated.buildRendering`
+
+			this.inherited(arguments);
+
+			// Create a hidden <input> node with the serialized value used for submit
+			// (as opposed to the displayed value)
+			this.valueNode = dojo.create("input", {
+				style: { display: "none" },
+				type: this.type,
+				name: this.name
+			}, this.textbox, "after");
+		},
+
+		_setDisabledAttr: function(/*Boolean*/ value){
+			this.inherited(arguments);
+			dojo.attr(this.valueNode, 'disabled', value);
+		},
+
+		reset:function(){
+			// Overrides `dijit.form.ValidationTextBox.reset` to
+			// reset the hidden textbox value to ''
+			this.valueNode.value = '';
+			this.inherited(arguments);
+		}
+	}
+);
+
+/*=====
+	dijit.form.RangeBoundTextBox.__Constraints = function(){
+		// min: Number
+		//		Minimum signed value.  Default is -Infinity
+		// max: Number
+		//		Maximum signed value.  Default is +Infinity
+		this.min = min;
+		this.max = max;
+	}
+=====*/
+
+dojo.declare(
+	"dijit.form.RangeBoundTextBox",
+	dijit.form.MappedTextBox,
+	{
+		// summary:
+		//		Base class for textbox form widgets which defines a range of valid values.
+
+		// rangeMessage: String
+		//		The message to display if value is out-of-range
+		rangeMessage: "",
+
+		/*=====
+		// constraints: dijit.form.RangeBoundTextBox.__Constraints
+		constraints: {},
+		======*/
+
+		rangeCheck: function(/*Number*/ primitive, /*dijit.form.RangeBoundTextBox.__Constraints*/ constraints){
+			// summary:
+			//		Overridable function used to validate the range of the numeric input value.
+			// tags:
+			//		protected
+			var isMin = "min" in constraints;
+			var isMax = "max" in constraints;
+			if(isMin || isMax){
+				return (!isMin || this.compare(primitive,constraints.min) >= 0) &&
+					(!isMax || this.compare(primitive,constraints.max) <= 0);
+			}
+			return true; // Boolean
+		},
+
+		isInRange: function(/*Boolean*/ isFocused){
+			// summary:
+			//		Tests if the value is in the min/max range specified in constraints
+			// tags:
+			//		protected
+			return this.rangeCheck(this.attr('value'), this.constraints);
+		},
+
+		_isDefinitelyOutOfRange: function(){
+			// summary:
+			//		Returns true if the value is out of range and will remain
+			//		out of range even if the user types more characters
+			var val = this.attr('value');
+			var isTooLittle = false;
+			var isTooMuch = false;
+			if("min" in this.constraints){
+				var min = this.constraints.min;
+				val = this.compare(val, ((typeof min == "number") && min >= 0 && val !=0)? 0 : min);
+				isTooLittle = (typeof val == "number") && val < 0;
+			}
+			if("max" in this.constraints){
+				var max = this.constraints.max;
+				val = this.compare(val, ((typeof max != "number") || max > 0)? max : 0);
+				isTooMuch = (typeof val == "number") && val > 0;
+			}
+			return isTooLittle || isTooMuch;
+		},
+
+		_isValidSubset: function(){
+			// summary:
+			//		Overrides `dijit.form.ValidationTextBox._isValidSubset`.
+			//		Returns true if the input is syntactically valid, and either within
+			//		range or could be made in range by more typing.
+			return this.inherited(arguments) && !this._isDefinitelyOutOfRange();
+		},
+
+		isValid: function(/*Boolean*/ isFocused){
+			// Overrides dijit.form.ValidationTextBox.isValid to check that the value is also in range.
+			return this.inherited(arguments) &&
+				((this._isEmpty(this.textbox.value) && !this.required) || this.isInRange(isFocused)); // Boolean
+		},
+
+		getErrorMessage: function(/*Boolean*/ isFocused){
+			// Overrides dijit.form.ValidationTextBox.getErrorMessage to print "out of range" message if appropriate
+			if(dijit.form.RangeBoundTextBox.superclass.isValid.call(this, false) && !this.isInRange(isFocused)){ return this.rangeMessage; } // String
+			return this.inherited(arguments);
+		},
+
+		postMixInProperties: function(){
+			this.inherited(arguments);
+			if(!this.rangeMessage){
+				this.messages = dojo.i18n.getLocalization("dijit.form", "validate", this.lang);
+				this.rangeMessage = this.messages.rangeMessage;
+			}
+		},
+
+		postCreate: function(){
+			this.inherited(arguments);
+			if(this.constraints.min !== undefined){
+				dijit.setWaiState(this.focusNode, "valuemin", this.constraints.min);
+			}
+			if(this.constraints.max !== undefined){
+				dijit.setWaiState(this.focusNode, "valuemax", this.constraints.max);
+			}
+		},
+		
+		_setValueAttr: function(/*Number*/ value, /*Boolean?*/ priorityChange){
+			// summary:
+			//		Hook so attr('value', ...) works.
+
+			dijit.setWaiState(this.focusNode, "valuenow", value);
+			this.inherited(arguments);
+		}
+	}
+);
+
+}
+
+if(!dojo._hasResource["dojo.data.util.sorter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.data.util.sorter"] = true;
+dojo.provide("dojo.data.util.sorter");
+
+dojo.data.util.sorter.basicComparator = function(	/*anything*/ a, 
+													/*anything*/ b){
+	//	summary:  
+	//		Basic comparision function that compares if an item is greater or less than another item
+	//	description:  
+	//		returns 1 if a > b, -1 if a < b, 0 if equal.
+	//		'null' values (null, undefined) are treated as larger values so that they're pushed to the end of the list.
+	//		And compared to each other, null is equivalent to undefined.
+	
+	//null is a problematic compare, so if null, we set to undefined.
+	//Makes the check logic simple, compact, and consistent
+	//And (null == undefined) === true, so the check later against null
+	//works for undefined and is less bytes.
+	var r = -1;
+	if(a === null){
+		a = undefined;
+	}
+	if(b === null){
+		b = undefined;
+	}
+	if(a == b){
+		r = 0; 
+	}else if(a > b || a == null){
+		r = 1; 
+	}
+	return r; //int {-1,0,1}
+};
+
+dojo.data.util.sorter.createSortFunction = function(	/* attributes array */sortSpec,
+														/*dojo.data.core.Read*/ store){
+	//	summary:  
+	//		Helper function to generate the sorting function based off the list of sort attributes.
+	//	description:  
+	//		The sort function creation will look for a property on the store called 'comparatorMap'.  If it exists
+	//		it will look in the mapping for comparisons function for the attributes.  If one is found, it will
+	//		use it instead of the basic comparator, which is typically used for strings, ints, booleans, and dates.
+	//		Returns the sorting function for this particular list of attributes and sorting directions.
+	//
+	//	sortSpec: array
+	//		A JS object that array that defines out what attribute names to sort on and whether it should be descenting or asending.
+	//		The objects should be formatted as follows:
+	//		{
+	//			attribute: "attributeName-string" || attribute,
+	//			descending: true|false;   // Default is false.
+	//		}
+	//	store: object
+	//		The datastore object to look up item values from.
+	//
+	var sortFunctions=[];   
+
+	function createSortFunction(attr, dir){
+		return function(itemA, itemB){
+			var a = store.getValue(itemA, attr);
+			var b = store.getValue(itemB, attr);
+			//See if we have a override for an attribute comparison.
+			var comparator = null;
+			if(store.comparatorMap){
+				if(typeof attr !== "string"){
+					 attr = store.getIdentity(attr);
+				}
+				comparator = store.comparatorMap[attr]||dojo.data.util.sorter.basicComparator;
+			}
+			comparator = comparator||dojo.data.util.sorter.basicComparator; 
+			return dir * comparator(a,b); //int
+		};
+	}
+	var sortAttribute;
+	for(var i = 0; i < sortSpec.length; i++){
+		sortAttribute = sortSpec[i];
+		if(sortAttribute.attribute){
+			var direction = (sortAttribute.descending) ? -1 : 1;
+			sortFunctions.push(createSortFunction(sortAttribute.attribute, direction));
+		}
+	}
+
+	return function(rowA, rowB){
+		var i=0;
+		while(i < sortFunctions.length){
+			var ret = sortFunctions[i++](rowA, rowB);
+			if(ret !== 0){
+				return ret;//int
+			}
+		}
+		return 0; //int  
+	};  //  Function
+};
+
+}
+
+if(!dojo._hasResource["dojo.data.util.simpleFetch"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.data.util.simpleFetch"] = true;
+dojo.provide("dojo.data.util.simpleFetch");
+
+
+dojo.data.util.simpleFetch.fetch = function(/* Object? */ request){
+	//	summary:
+	//		The simpleFetch mixin is designed to serve as a set of function(s) that can
+	//		be mixed into other datastore implementations to accelerate their development.  
+	//		The simpleFetch mixin should work well for any datastore that can respond to a _fetchItems() 
+	//		call by returning an array of all the found items that matched the query.  The simpleFetch mixin
+	//		is not designed to work for datastores that respond to a fetch() call by incrementally
+	//		loading items, or sequentially loading partial batches of the result
+	//		set.  For datastores that mixin simpleFetch, simpleFetch 
+	//		implements a fetch method that automatically handles eight of the fetch()
+	//		arguments -- onBegin, onItem, onComplete, onError, start, count, sort and scope
+	//		The class mixing in simpleFetch should not implement fetch(),
+	//		but should instead implement a _fetchItems() method.  The _fetchItems() 
+	//		method takes three arguments, the keywordArgs object that was passed 
+	//		to fetch(), a callback function to be called when the result array is
+	//		available, and an error callback to be called if something goes wrong.
+	//		The _fetchItems() method should ignore any keywordArgs parameters for
+	//		start, count, onBegin, onItem, onComplete, onError, sort, and scope.  
+	//		The _fetchItems() method needs to correctly handle any other keywordArgs
+	//		parameters, including the query parameter and any optional parameters 
+	//		(such as includeChildren).  The _fetchItems() method should create an array of 
+	//		result items and pass it to the fetchHandler along with the original request object 
+	//		-- or, the _fetchItems() method may, if it wants to, create an new request object 
+	//		with other specifics about the request that are specific to the datastore and pass 
+	//		that as the request object to the handler.
+	//
+	//		For more information on this specific function, see dojo.data.api.Read.fetch()
+	request = request || {};
+	if(!request.store){
+		request.store = this;
+	}
+	var self = this;
+
+	var _errorHandler = function(errorData, requestObject){
+		if(requestObject.onError){
+			var scope = requestObject.scope || dojo.global;
+			requestObject.onError.call(scope, errorData, requestObject);
+		}
+	};
+
+	var _fetchHandler = function(items, requestObject){
+		var oldAbortFunction = requestObject.abort || null;
+		var aborted = false;
+
+		var startIndex = requestObject.start?requestObject.start:0;
+		var endIndex   = (requestObject.count && (requestObject.count !== Infinity))?(startIndex + requestObject.count):items.length;
+
+		requestObject.abort = function(){
+			aborted = true;
+			if(oldAbortFunction){
+				oldAbortFunction.call(requestObject);
+			}
+		};
+
+		var scope = requestObject.scope || dojo.global;
+		if(!requestObject.store){
+			requestObject.store = self;
+		}
+		if(requestObject.onBegin){
+			requestObject.onBegin.call(scope, items.length, requestObject);
+		}
+		if(requestObject.sort){
+			items.sort(dojo.data.util.sorter.createSortFunction(requestObject.sort, self));
+		}
+		if(requestObject.onItem){
+			for(var i = startIndex; (i < items.length) && (i < endIndex); ++i){
+				var item = items[i];
+				if(!aborted){
+					requestObject.onItem.call(scope, item, requestObject);
+				}
+			}
+		}
+		if(requestObject.onComplete && !aborted){
+			var subset = null;
+			if (!requestObject.onItem) {
+				subset = items.slice(startIndex, endIndex);
+			}
+			requestObject.onComplete.call(scope, subset, requestObject);   
+		}
+	};
+	this._fetchItems(request, _fetchHandler, _errorHandler);
+	return request;	// Object
+};
+
+}
+
+if(!dojo._hasResource["dojo.data.util.filter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.data.util.filter"] = true;
+dojo.provide("dojo.data.util.filter");
+
+dojo.data.util.filter.patternToRegExp = function(/*String*/pattern, /*boolean?*/ ignoreCase){
+	//	summary:  
+	//		Helper function to convert a simple pattern to a regular expression for matching.
+	//	description:
+	//		Returns a regular expression object that conforms to the defined conversion rules.
+	//		For example:  
+	//			ca*   -> /^ca.*$/
+	//			*ca*  -> /^.*ca.*$/
+	//			*c\*a*  -> /^.*c\*a.*$/
+	//			*c\*a?*  -> /^.*c\*a..*$/
+	//			and so on.
+	//
+	//	pattern: string
+	//		A simple matching pattern to convert that follows basic rules:
+	//			* Means match anything, so ca* means match anything starting with ca
+	//			? Means match single character.  So, b?b will match to bob and bab, and so on.
+	//      	\ is an escape character.  So for example, \* means do not treat * as a match, but literal character *.
+	//				To use a \ as a character in the string, it must be escaped.  So in the pattern it should be 
+	//				represented by \\ to be treated as an ordinary \ character instead of an escape.
+	//
+	//	ignoreCase:
+	//		An optional flag to indicate if the pattern matching should be treated as case-sensitive or not when comparing
+	//		By default, it is assumed case sensitive.
+
+	var rxp = "^";
+	var c = null;
+	for(var i = 0; i < pattern.length; i++){
+		c = pattern.charAt(i);
+		switch (c) {
+			case '\\':
+				rxp += c;
+				i++;
+				rxp += pattern.charAt(i);
+				break;
+			case '*':
+				rxp += ".*"; break;
+			case '?':
+				rxp += "."; break;
+			case '$':
+			case '^':
+			case '/':
+			case '+':
+			case '.':
+			case '|':
+			case '(':
+			case ')':
+			case '{':
+			case '}':
+			case '[':
+			case ']':
+				rxp += "\\"; //fallthrough
+			default:
+				rxp += c;
+		}
+	}
+	rxp += "$";
+	if(ignoreCase){
+		return new RegExp(rxp,"mi"); //RegExp
+	}else{
+		return new RegExp(rxp,"m"); //RegExp
+	}
+	
+};
+
+}
+
+if(!dojo._hasResource["dijit.form.ComboBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.ComboBox"] = true;
+dojo.provide("dijit.form.ComboBox");
+
+
+
+
+
+
+
+
+dojo.declare(
+	"dijit.form.ComboBoxMixin",
+	null,
+	{
+		// summary:
+		//		Implements the base functionality for ComboBox/FilteringSelect
+		// description:
+		//		All widgets that mix in dijit.form.ComboBoxMixin must extend dijit.form._FormValueWidget
+		// tags:
+		//		protected
+
+		// item: Object
+		//		This is the item returned by the dojo.data.store implementation that
+		//		provides the data for this cobobox, it's the currently selected item.
+		item: null,
+
+		// pageSize: Integer
+		//		Argument to data provider.
+		//		Specifies number of search results per page (before hitting "next" button)
+		pageSize: Infinity,
+
+		// store: Object
+		//		Reference to data provider object used by this ComboBox
+		store: null,
+
+		// fetchProperties: Object
+		//		Mixin to the dojo.data store's fetch.
+		//		For example, to set the sort order of the ComboBox menu, pass:
+		//		{sort:{attribute:"name",descending: true}}
+		fetchProperties:{},
+
+		// query: Object
+		//		A query that can be passed to 'store' to initially filter the items,
+		//		before doing further filtering based on `searchAttr` and the key.
+		//		Any reference to the `searchAttr` is ignored.
+		query: {},
+
+		// autoComplete: Boolean
+		//		If user types in a partial string, and then tab out of the `<input>` box,
+		//		automatically copy the first entry displayed in the drop down list to
+		//		the `<input>` field
+		autoComplete: true,
+
+		// highlightMatch: String
+		// 		One of: "first", "all" or "none".
+		//
+		//		If the ComboBox/FilteringSelect opens with the search results and the searched
+		//		string can be found, it will be highlighted.  If set to "all"
+		//		then will probably want to change `queryExpr` parameter to '*${0}*'
+		//
+		//		Highlighting is only performed when `labelType` is "text", so as to not
+		//		interfere with any HTML markup an HTML label might contain.
+		highlightMatch: "first",
+		
+		// searchDelay: Integer
+		//		Delay in milliseconds between when user types something and we start
+		//		searching based on that value
+		searchDelay: 100,
+
+		// searchAttr: String
+		//		Search for items in the data store where this attribute (in the item)
+		//		matches what the user typed
+		searchAttr: "name",
+
+		// labelAttr: String?
+		//		The entries in the drop down list come from this attribute in the
+		//		dojo.data items.
+		//		If not specified, the searchAttr attribute is used instead.
+		labelAttr: "",
+
+		// labelType: String
+		//		Specifies how to interpret the labelAttr in the data store items.
+		//		Can be "html" or "text".
+		labelType: "text",
+
+		// queryExpr: String
+		//		This specifies what query ComboBox/FilteringSelect sends to the data store,
+		//		based on what the user has typed.  Changing this expression will modify
+		//		whether the drop down shows only exact matches, a "starting with" match,
+		//		etc.   Use it in conjunction with highlightMatch.
+		//		dojo.data query expression pattern.
+		//		`${0}` will be substituted for the user text.
+		//		`*` is used for wildcards.
+		//		`${0}*` means "starts with", `*${0}*` means "contains", `${0}` means "is"
+		queryExpr: "${0}*",
+
+		// ignoreCase: Boolean
+		//		Set true if the ComboBox/FilteringSelect should ignore case when matching possible items
+		ignoreCase: true,
+
+		// hasDownArrow: Boolean
+		//		Set this textbox to have a down arrow button, to display the drop down list.
+		//		Defaults to true.
+		hasDownArrow: true,
+
+		templateString:"<div class=\"dijit dijitReset dijitInlineTable dijitLeft\"\n\tid=\"widget_${id}\"\n\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\" dojoAttachPoint=\"comboNode\" waiRole=\"combobox\" tabIndex=\"-1\"\n\t><div style=\"overflow:hidden;\"\n\t\t><div class='dijitReset dijitRight dijitButtonNode dijitArrowButton dijitDownArrowButton'\n\t\t\tdojoAttachPoint=\"downArrowNode\" waiRole=\"presentation\"\n\t\t\tdojoAttachEvent=\"onmousedown:_on [...]
+
+		baseClass:"dijitComboBox",
+
+		_getCaretPos: function(/*DomNode*/ element){
+			// khtml 3.5.2 has selection* methods as does webkit nightlies from 2005-06-22
+			var pos = 0;
+			if(typeof(element.selectionStart)=="number"){
+				// FIXME: this is totally borked on Moz < 1.3. Any recourse?
+				pos = element.selectionStart;
+			}else if(dojo.isIE){
+				// in the case of a mouse click in a popup being handled,
+				// then the dojo.doc.selection is not the textarea, but the popup
+				// var r = dojo.doc.selection.createRange();
+				// hack to get IE 6 to play nice. What a POS browser.
+				var tr = dojo.doc.selection.createRange().duplicate();
+				var ntr = element.createTextRange();
+				tr.move("character",0);
+				ntr.move("character",0);
+				try{
+					// If control doesnt have focus, you get an exception.
+					// Seems to happen on reverse-tab, but can also happen on tab (seems to be a race condition - only happens sometimes).
+					// There appears to be no workaround for this - googled for quite a while.
+					ntr.setEndPoint("EndToEnd", tr);
+					pos = String(ntr.text).replace(/\r/g,"").length;
+				}catch(e){
+					// If focus has shifted, 0 is fine for caret pos.
+				}
+			}
+			return pos;
+		},
+
+		_setCaretPos: function(/*DomNode*/ element, /*Number*/ location){
+			location = parseInt(location);
+			dijit.selectInputText(element, location, location);
+		},
+
+		_setDisabledAttr: function(/*Boolean*/ value){
+			// Additional code to set disabled state of combobox node.
+			// Overrides _FormValueWidget._setDisabledAttr() or ValidationTextBox._setDisabledAttr().
+			this.inherited(arguments);
+			dijit.setWaiState(this.comboNode, "disabled", value);
+		},	
+		
+		_onKeyPress: function(/*Event*/ evt){
+			// summary:
+			//		Handles keyboard events
+			var key = evt.charOrCode;
+			//except for cutting/pasting case - ctrl + x/v
+			if(evt.altKey || (evt.ctrlKey && (key != 'x' && key != 'v')) || evt.key == dojo.keys.SHIFT){
+				return; // throw out weird key combinations and spurious events
+			}
+			var doSearch = false;
+			var pw = this._popupWidget;
+			var dk = dojo.keys;
+			var highlighted = null;
+			if(this._isShowingNow){
+				pw.handleKey(key);
+				highlighted = pw.getHighlightedOption();
+			}
+			switch(key){
+				case dk.PAGE_DOWN:
+				case dk.DOWN_ARROW:
+					if(!this._isShowingNow||this._prev_key_esc){
+						this._arrowPressed();
+						doSearch=true;
+					}else if(highlighted){
+						this._announceOption(highlighted);
+					}
+					dojo.stopEvent(evt);
+					this._prev_key_backspace = false;
+					this._prev_key_esc = false;
+					break;
+
+				case dk.PAGE_UP:
+				case dk.UP_ARROW:
+					if(this._isShowingNow){
+						this._announceOption(highlighted);
+					}
+					dojo.stopEvent(evt);
+					this._prev_key_backspace = false;
+					this._prev_key_esc = false;
+					break;
+
+				case dk.ENTER:
+					// prevent submitting form if user presses enter. Also
+					// prevent accepting the value if either Next or Previous
+					// are selected
+					if(highlighted){
+						// only stop event on prev/next
+						if(highlighted == pw.nextButton){
+							this._nextSearch(1);
+							dojo.stopEvent(evt);
+							break;
+						}else if(highlighted == pw.previousButton){
+							this._nextSearch(-1);
+							dojo.stopEvent(evt);
+							break;
+						}
+					}else{
+						// Update 'value' (ex: KY) according to currently displayed text
+						this._setDisplayedValueAttr(this.attr('displayedValue'), true);
+					}
+					// default case:
+					// prevent submit, but allow event to bubble
+					evt.preventDefault();
+					// fall through
+
+				case dk.TAB:
+					var newvalue = this.attr('displayedValue');
+					// #4617: 
+					//		if the user had More Choices selected fall into the
+					//		_onBlur handler
+					if(pw && (
+						newvalue == pw._messages["previousMessage"] ||
+						newvalue == pw._messages["nextMessage"])
+					){
+						break;
+					}
+					if(this._isShowingNow){
+						this._prev_key_backspace = false;
+						this._prev_key_esc = false;
+						if(highlighted){
+							pw.attr('value', { target: highlighted });
+						}
+						this._lastQuery = null; // in case results come back later
+						this._hideResultList();
+					}
+					break;
+
+				case ' ':
+					this._prev_key_backspace = false;
+					this._prev_key_esc = false;
+					if(highlighted){
+						dojo.stopEvent(evt);
+						this._selectOption();
+						this._hideResultList();
+					}else{
+						doSearch = true;
+					}
+					break;
+
+				case dk.ESCAPE:
+					this._prev_key_backspace = false;
+					this._prev_key_esc = true;
+					if(this._isShowingNow){
+						dojo.stopEvent(evt);
+						this._hideResultList();
+					}
+					break;
+
+				case dk.DELETE:
+				case dk.BACKSPACE:
+					this._prev_key_esc = false;
+					this._prev_key_backspace = true;
+					doSearch = true;
+					break;
+
+				case dk.RIGHT_ARROW: // fall through
+				case dk.LEFT_ARROW: 
+					this._prev_key_backspace = false;
+					this._prev_key_esc = false;
+					break;
+
+				default: // non char keys (F1-F12 etc..)  shouldn't open list
+					this._prev_key_backspace = false;
+					this._prev_key_esc = false;
+					doSearch = typeof key == 'string';
+			}
+			if(this.searchTimer){
+				clearTimeout(this.searchTimer);
+			}
+			if(doSearch){
+				// need to wait a tad before start search so that the event
+				// bubbles through DOM and we have value visible
+				setTimeout(dojo.hitch(this, "_startSearchFromInput"),1);
+			}
+		},
+
+		_autoCompleteText: function(/*String*/ text){
+			// summary:
+			// 		Fill in the textbox with the first item from the drop down
+			// 		list, and highlight the characters that were
+			// 		auto-completed. For example, if user typed "CA" and the
+			// 		drop down list appeared, the textbox would be changed to
+			// 		"California" and "ifornia" would be highlighted.
+
+			var fn = this.focusNode;
+
+			// IE7: clear selection so next highlight works all the time
+			dijit.selectInputText(fn, fn.value.length);
+			// does text autoComplete the value in the textbox?
+			var caseFilter = this.ignoreCase? 'toLowerCase' : 'substr';
+			if(text[caseFilter](0).indexOf(this.focusNode.value[caseFilter](0)) == 0){
+				var cpos = this._getCaretPos(fn);
+				// only try to extend if we added the last character at the end of the input
+				if((cpos+1) > fn.value.length){
+					// only add to input node as we would overwrite Capitalisation of chars
+					// actually, that is ok
+					fn.value = text;//.substr(cpos);
+					// visually highlight the autocompleted characters
+					dijit.selectInputText(fn, cpos);
+				}
+			}else{
+				// text does not autoComplete; replace the whole value and highlight
+				fn.value = text;
+				dijit.selectInputText(fn);
+			}
+		},
+
+		_openResultList: function(/*Object*/ results, /*Object*/ dataObject){
+			if(	this.disabled || 
+				this.readOnly || 
+				(dataObject.query[this.searchAttr] != this._lastQuery)
+			){
+				return;
+			}
+			this._popupWidget.clearResultList();
+			if(!results.length){
+				this._hideResultList();
+				return;
+			}
+
+			// Fill in the textbox with the first item from the drop down list,
+			// and highlight the characters that were auto-completed. For
+			// example, if user typed "CA" and the drop down list appeared, the
+			// textbox would be changed to "California" and "ifornia" would be
+			// highlighted.
+
+			this.item = null;
+			var zerothvalue = new String(this.store.getValue(results[0], this.searchAttr));
+			if(zerothvalue && this.autoComplete && !this._prev_key_backspace &&
+				(dataObject.query[this.searchAttr] != "*")){
+				// when the user clicks the arrow button to show the full list,
+				// startSearch looks for "*".
+				// it does not make sense to autocomplete
+				// if they are just previewing the options available.
+				this.item = results[0];
+				this._autoCompleteText(zerothvalue);
+			}
+			dataObject._maxOptions = this._maxOptions;
+			this._popupWidget.createOptions(
+				results, 
+				dataObject, 
+				dojo.hitch(this, "_getMenuLabelFromItem")
+			);
+
+			// show our list (only if we have content, else nothing)
+			this._showResultList();
+
+			// #4091:
+			//		tell the screen reader that the paging callback finished by
+			//		shouting the next choice
+			if(dataObject.direction){
+				if(1 == dataObject.direction){
+					this._popupWidget.highlightFirstOption();
+				}else if(-1 == dataObject.direction){
+					this._popupWidget.highlightLastOption();
+				}
+				this._announceOption(this._popupWidget.getHighlightedOption());
+			}
+		},
+
+		_showResultList: function(){
+			this._hideResultList();
+			var items = this._popupWidget.getItems(),
+				visibleCount = Math.min(items.length,this.maxListLength);   // TODO: unused, remove
+			this._arrowPressed();
+			// hide the tooltip
+			this.displayMessage("");
+			
+			// Position the list and if it's too big to fit on the screen then
+			// size it to the maximum possible height
+			// Our dear friend IE doesnt take max-height so we need to
+			// calculate that on our own every time
+
+			// TODO: want to redo this, see 
+			//		http://trac.dojotoolkit.org/ticket/3272
+			//	and
+			//		http://trac.dojotoolkit.org/ticket/4108
+
+
+			// natural size of the list has changed, so erase old
+			// width/height settings, which were hardcoded in a previous
+			// call to this function (via dojo.marginBox() call)
+			dojo.style(this._popupWidget.domNode, {width: "", height: ""});
+
+			var best = this.open();
+			// #3212:
+			//		only set auto scroll bars if necessary prevents issues with
+			//		scroll bars appearing when they shouldn't when node is made
+			//		wider (fractional pixels cause this)
+			var popupbox = dojo.marginBox(this._popupWidget.domNode);
+			this._popupWidget.domNode.style.overflow = 
+				((best.h==popupbox.h)&&(best.w==popupbox.w)) ? "hidden" : "auto";
+			// #4134:
+			//		borrow TextArea scrollbar test so content isn't covered by
+			//		scrollbar and horizontal scrollbar doesn't appear
+			var newwidth = best.w;
+			if(best.h < this._popupWidget.domNode.scrollHeight){
+				newwidth += 16;
+			}
+			dojo.marginBox(this._popupWidget.domNode, {
+				h: best.h,
+				w: Math.max(newwidth, this.domNode.offsetWidth)
+			});
+			dijit.setWaiState(this.comboNode, "expanded", "true");
+		},
+
+		_hideResultList: function(){
+			if(this._isShowingNow){
+				dijit.popup.close(this._popupWidget);
+				this._arrowIdle();
+				this._isShowingNow=false;
+				dijit.setWaiState(this.comboNode, "expanded", "false");
+				dijit.removeWaiState(this.focusNode,"activedescendant");
+			}
+		},
+
+		_setBlurValue: function(){
+			// if the user clicks away from the textbox OR tabs away, set the
+			// value to the textbox value
+			// #4617: 
+			//		if value is now more choices or previous choices, revert
+			//		the value
+			var newvalue=this.attr('displayedValue');
+			var pw = this._popupWidget;
+			if(pw && (
+				newvalue == pw._messages["previousMessage"] ||
+				newvalue == pw._messages["nextMessage"]
+				)
+			){
+				this._setValueAttr(this._lastValueReported, true);
+			}else{
+				// Update 'value' (ex: KY) according to currently displayed text
+				this.attr('displayedValue', newvalue);
+			}
+		},
+
+		_onBlur: function(){
+			// summary:
+			//		Called magically when focus has shifted away from this widget and it's drop down
+			this._hideResultList();
+			this._arrowIdle();
+			this.inherited(arguments);
+		},
+
+		_announceOption: function(/*Node*/ node){
+			// summary:
+			//		a11y code that puts the highlighted option in the textbox.
+			//		This way screen readers will know what is happening in the
+			//		menu.
+
+			if(node == null){
+				return;
+			}
+			// pull the text value from the item attached to the DOM node
+			var newValue;
+			if( node == this._popupWidget.nextButton ||
+				node == this._popupWidget.previousButton){
+				newValue = node.innerHTML;
+			}else{
+				newValue = this.store.getValue(node.item, this.searchAttr);
+			}
+			// get the text that the user manually entered (cut off autocompleted text)
+			this.focusNode.value = this.focusNode.value.substring(0, this._getCaretPos(this.focusNode));
+			//set up ARIA activedescendant
+			dijit.setWaiState(this.focusNode, "activedescendant", dojo.attr(node, "id")); 
+			// autocomplete the rest of the option to announce change
+			this._autoCompleteText(newValue);
+		},
+
+		_selectOption: function(/*Event*/ evt){
+			var tgt = null;
+			if(!evt){
+				evt ={ target: this._popupWidget.getHighlightedOption()};
+			}
+				// what if nothing is highlighted yet?
+			if(!evt.target){
+				// handle autocompletion where the the user has hit ENTER or TAB
+				this.attr('displayedValue', this.attr('displayedValue'));
+				return;
+			// otherwise the user has accepted the autocompleted value
+			}else{
+				tgt = evt.target;
+			}
+			if(!evt.noHide){
+				this._hideResultList();
+				this._setCaretPos(this.focusNode, this.store.getValue(tgt.item, this.searchAttr).length);
+			}
+			this._doSelect(tgt);
+		},
+
+		_doSelect: function(tgt){
+			// summary:
+			//		Menu callback function, called when an item in the menu is selected.
+			this.item = tgt.item;
+			this.attr('value', this.store.getValue(tgt.item, this.searchAttr));
+		},
+
+		_onArrowMouseDown: function(evt){
+			// summary:
+			//		Callback when arrow is clicked
+			if(this.disabled || this.readOnly){
+				return;
+			}
+			dojo.stopEvent(evt);
+			this.focus();
+			if(this._isShowingNow){
+				this._hideResultList();
+			}else{
+				// forces full population of results, if they click
+				// on the arrow it means they want to see more options
+				this._startSearch("");
+			}
+		},
+
+		_startSearchFromInput: function(){
+			this._startSearch(this.focusNode.value.replace(/([\\\*\?])/g, "\\$1"));
+		},
+
+		_getQueryString: function(/*String*/ text){
+			return dojo.string.substitute(this.queryExpr, [text]);
+		},
+
+		_startSearch: function(/*String*/ key){
+			if(!this._popupWidget){
+				var popupId = this.id + "_popup";
+				this._popupWidget = new dijit.form._ComboBoxMenu({
+					onChange: dojo.hitch(this, this._selectOption),
+					id: popupId
+				});
+				dijit.removeWaiState(this.focusNode,"activedescendant");
+				dijit.setWaiState(this.textbox,"owns",popupId); // associate popup with textbox
+			}
+			// create a new query to prevent accidentally querying for a hidden
+			// value from FilteringSelect's keyField
+			this.item = null; // #4872
+			var query = dojo.clone(this.query); // #5970
+			this._lastInput = key; // Store exactly what was entered by the user.
+			this._lastQuery = query[this.searchAttr] = this._getQueryString(key);
+			// #5970: set _lastQuery, *then* start the timeout
+			// otherwise, if the user types and the last query returns before the timeout,
+			// _lastQuery won't be set and their input gets rewritten
+			this.searchTimer=setTimeout(dojo.hitch(this, function(query, _this){
+				var fetch = {
+					queryOptions: {
+						ignoreCase: this.ignoreCase, 
+						deep: true
+					},
+					query: query,
+					onBegin: dojo.hitch(this, "_setMaxOptions"),
+					onComplete: dojo.hitch(this, "_openResultList"), 
+					onError: function(errText){
+						console.error('dijit.form.ComboBox: ' + errText);
+						dojo.hitch(_this, "_hideResultList")();
+					},
+					start: 0,
+					count: this.pageSize
+				};
+				dojo.mixin(fetch, _this.fetchProperties);
+				var dataObject = _this.store.fetch(fetch);
+
+				var nextSearch = function(dataObject, direction){
+					dataObject.start += dataObject.count*direction;
+					// #4091:
+					//		tell callback the direction of the paging so the screen
+					//		reader knows which menu option to shout
+					dataObject.direction = direction;
+					this.store.fetch(dataObject);
+				};
+				this._nextSearch = this._popupWidget.onPage = dojo.hitch(this, nextSearch, dataObject);
+			}, query, this), this.searchDelay);
+		},
+
+		_setMaxOptions: function(size, request){
+			 this._maxOptions = size;
+		},
+
+		_getValueField: function(){
+			// summmary:
+			//		Helper for postMixInProperties() to set this.value based on data inlined into the markup.
+			//		Returns the attribute name in the item (in dijit.form._ComboBoxDataStore) to use as the value.
+			return this.searchAttr;
+		},
+
+		/////////////// Event handlers /////////////////////
+
+		_arrowPressed: function(){
+			if(!this.disabled && !this.readOnly && this.hasDownArrow){
+				dojo.addClass(this.downArrowNode, "dijitArrowButtonActive");
+			}
+		},
+
+		_arrowIdle: function(){
+			if(!this.disabled && !this.readOnly && this.hasDownArrow){
+				dojo.removeClass(this.downArrowNode, "dojoArrowButtonPushed");
+			}
+		},
+
+		// FIXME: For 2.0, rename to "_compositionEnd"
+		compositionend: function(/*Event*/ evt){
+			// summary:
+			//		When inputting characters using an input method, such as
+			//		Asian languages, it will generate this event instead of
+			//		onKeyDown event.
+			//		Note: this event is only triggered in FF (not in IE)
+			// tags:
+			//		private
+			this._onKeyPress({charCode:-1});
+		},
+
+		//////////// INITIALIZATION METHODS ///////////////////////////////////////
+
+		constructor: function(){
+			this.query={};
+			this.fetchProperties={};
+		},
+
+		postMixInProperties: function(){
+			if(!this.hasDownArrow){
+				this.baseClass = "dijitTextBox";
+			}
+			if(!this.store){
+				var srcNodeRef = this.srcNodeRef;
+
+				// if user didn't specify store, then assume there are option tags
+				this.store = new dijit.form._ComboBoxDataStore(srcNodeRef);
+
+				// if there is no value set and there is an option list, set
+				// the value to the first value to be consistent with native
+				// Select
+
+				// Firefox and Safari set value
+				// IE6 and Opera set selectedIndex, which is automatically set
+				// by the selected attribute of an option tag
+				// IE6 does not set value, Opera sets value = selectedIndex
+				if(	!this.value || (
+						(typeof srcNodeRef.selectedIndex == "number") && 
+						srcNodeRef.selectedIndex.toString() === this.value)
+				){
+					var item = this.store.fetchSelectedItem();
+					if(item){
+						this.value = this.store.getValue(item, this._getValueField());
+					}
+				}
+			}
+			this.inherited(arguments);
+		},
+		
+		postCreate: function(){
+			// summary:
+			//		Subclasses must call this method from their postCreate() methods
+			// tags: protected
+
+			//find any associated label element and add to combobox node.
+			var label=dojo.query('label[for="'+this.id+'"]');
+			if(label.length){
+				label[0].id = (this.id+"_label");
+				var cn=this.comboNode;
+				dijit.setWaiState(cn, "labelledby", label[0].id);
+				
+			}
+			this.inherited(arguments);
+		},
+
+		uninitialize: function(){
+			if(this._popupWidget){
+				this._hideResultList();
+				this._popupWidget.destroy();
+			}
+		},
+
+		_getMenuLabelFromItem: function(/*Item*/ item){
+			var label = this.store.getValue(item, this.labelAttr || this.searchAttr);
+			var labelType = this.labelType;
+			// If labelType is not "text" we don't want to screw any markup ot whatever.
+			if (this.highlightMatch!="none" && this.labelType=="text" && this._lastInput){
+				label = this.doHighlight(label, this._escapeHtml(this._lastInput));
+				labelType = "html";
+			}
+			return {html: labelType=="html", label: label};
+		},
+		
+		doHighlight: function(/*String*/label, /*String*/find){
+			// summary:
+			//		Highlights the string entered by the user in the menu.  By default this
+			//		highlights the first occurence found. Override this method
+			//		to implement your custom highlighing.
+			// tags:
+			//		protected
+
+			// Add greedy when this.highlightMatch=="all"
+			var modifiers = "i"+(this.highlightMatch=="all"?"g":"");
+			var escapedLabel = this._escapeHtml(label);
+			find = dojo.regexp.escapeString(find); // escape regexp special chars
+			var ret = escapedLabel.replace(new RegExp("(^|\\s)("+ find +")", modifiers),
+					'$1<span class="dijitComboBoxHighlightMatch">$2</span>');
+			return ret;// returns String, (almost) valid HTML (entities encoded)
+		},
+		
+		_escapeHtml: function(/*string*/str){
+			// TODO Should become dojo.html.entities(), when exists use instead
+			// summary:
+			//		Adds escape sequences for special characters in XML: &<>"'
+			str = String(str).replace(/&/gm, "&").replace(/</gm, "<")
+				.replace(/>/gm, ">").replace(/"/gm, """);
+			return str; // string
+		},
+
+		open: function(){
+			// summary:
+			//		Opens the drop down menu.  TODO: rename to _open.
+			// tags:
+			//		private
+			this._isShowingNow=true;
+			return dijit.popup.open({
+				popup: this._popupWidget,
+				around: this.domNode,
+				parent: this
+			});
+		},
+		
+		reset: function(){
+			// Overrides the _FormWidget.reset().
+			// Additionally reset the .item (to clean up).
+			this.item = null;
+			this.inherited(arguments);
+		}
+		
+	}
+);
+
+dojo.declare(
+	"dijit.form._ComboBoxMenu",
+	[dijit._Widget, dijit._Templated],
+	{
+		// summary:
+		//		Focus-less menu for internal use in `dijit.form.ComboBox`
+		// tags:
+		//		private
+
+		templateString: "<ul class='dijitReset dijitMenu' dojoAttachEvent='onmousedown:_onMouseDown,onmouseup:_onMouseUp,onmouseover:_onMouseOver,onmouseout:_onMouseOut' tabIndex='-1' style='overflow: \"auto\"; overflow-x: \"hidden\";'>"
+				+"<li class='dijitMenuItem dijitMenuPreviousButton' dojoAttachPoint='previousButton' waiRole='option'></li>"
+				+"<li class='dijitMenuItem dijitMenuNextButton' dojoAttachPoint='nextButton' waiRole='option'></li>"
+			+"</ul>",
+
+		// _messages: Object
+		//		Holds "next" and "previous" text for paging buttons on drop down
+		_messages: null,
+
+		postMixInProperties: function(){
+			this._messages = dojo.i18n.getLocalization("dijit.form", "ComboBox", this.lang);
+			this.inherited(arguments);
+		},
+
+		_setValueAttr: function(/*Object*/ value){
+			this.value = value;
+			this.onChange(value);
+		},
+
+		// stubs
+		onChange: function(/*Object*/ value){
+			// summary:
+			//		Notifies ComboBox/FilteringSelect that user clicked an option in the drop down menu.
+			//		Probably should be called onSelect.
+			// tags:
+			//		callback
+		},
+		onPage: function(/*Number*/ direction){
+			// summary:
+			//		Notifies ComboBox/FilteringSelect that user clicked to advance to next/previous page.
+			// tags:
+			//		callback
+		},
+
+		postCreate: function(){
+			// fill in template with i18n messages
+			this.previousButton.innerHTML = this._messages["previousMessage"];
+			this.nextButton.innerHTML = this._messages["nextMessage"];
+			this.inherited(arguments);
+		},
+
+		onClose: function(){
+			// summary:
+			//		Callback from dijit.popup code to this widget, notifying it that it closed
+			// tags:
+			//		private
+			this._blurOptionNode();
+		},
+
+		_createOption: function(/*Object*/ item, labelFunc){
+			// summary: 
+			//		Creates an option to appear on the popup menu subclassed by
+			//		`dijit.form.FilteringSelect`.
+
+			var labelObject = labelFunc(item);
+			var menuitem = dojo.doc.createElement("li");
+			dijit.setWaiRole(menuitem, "option");
+			if(labelObject.html){
+				menuitem.innerHTML = labelObject.label;
+			}else{
+				menuitem.appendChild(
+					dojo.doc.createTextNode(labelObject.label)
+				);
+			}
+			// #3250: in blank options, assign a normal height
+			if(menuitem.innerHTML == ""){
+				menuitem.innerHTML = " ";
+			}
+			menuitem.item=item;
+			return menuitem;
+		},
+
+		createOptions: function(results, dataObject, labelFunc){
+			// summary:
+			//		Fills in the items in the drop down list
+			// results:
+			//		Array of dojo.data items
+			// dataObject:
+			//		dojo.data store
+			// labelFunc:
+			//		Function to produce a label in the drop down list from a dojo.data item
+
+			//this._dataObject=dataObject;
+			//this._dataObject.onComplete=dojo.hitch(comboBox, comboBox._openResultList);
+			// display "Previous . . ." button
+			this.previousButton.style.display = (dataObject.start == 0) ? "none" : "";
+			dojo.attr(this.previousButton, "id", this.id + "_prev");
+			// create options using _createOption function defined by parent
+			// ComboBox (or FilteringSelect) class
+			// #2309:
+			//		iterate over cache nondestructively
+			dojo.forEach(results, function(item, i){
+				var menuitem = this._createOption(item, labelFunc);
+				menuitem.className = "dijitReset dijitMenuItem";
+				dojo.attr(menuitem, "id", this.id + i);
+				this.domNode.insertBefore(menuitem, this.nextButton);
+			}, this);
+			// display "Next . . ." button
+			var displayMore = false;
+			//Try to determine if we should show 'more'...
+			if(dataObject._maxOptions && dataObject._maxOptions != -1){
+				if((dataObject.start + dataObject.count) < dataObject._maxOptions){
+					displayMore = true;
+				}else if((dataObject.start + dataObject.count) > (dataObject._maxOptions - 1)){
+					//Weird return from a datastore, where a start + count > maxOptions
+					//implies maxOptions isn't really valid and we have to go into faking it.
+					//And more or less assume more if count == results.length
+					if(dataObject.count == results.length){
+						displayMore = true;
+					}
+				}
+			}else if(dataObject.count == results.length){
+				//Don't know the size, so we do the best we can based off count alone.
+				//So, if we have an exact match to count, assume more.
+				displayMore = true;
+			}
+
+			this.nextButton.style.display = displayMore ? "" : "none";
+			dojo.attr(this.nextButton,"id", this.id + "_next");
+		},
+
+		clearResultList: function(){
+			// summary:
+			//		Clears the entries in the drop down list, but of course keeps the previous and next buttons.
+			while(this.domNode.childNodes.length>2){
+				this.domNode.removeChild(this.domNode.childNodes[this.domNode.childNodes.length-2]);
+			}
+		},
+
+		// these functions are called in showResultList
+		getItems: function(){
+			// summary:
+			//		Called from _showResultList().   Returns DOM Nodes representing the items in the drop down list.
+			return this.domNode.childNodes;
+		},
+
+		getListLength: function(){
+			// summary:
+			//		Called from _showResultList().   Returns number of  items in the drop down list,
+			//		not including next and previous buttons.
+			return this.domNode.childNodes.length-2;
+		},
+
+		_onMouseDown: function(/*Event*/ evt){
+			dojo.stopEvent(evt);
+		},
+
+		_onMouseUp: function(/*Event*/ evt){
+			if(evt.target === this.domNode){
+				return;
+			}else if(evt.target==this.previousButton){
+				this.onPage(-1);
+			}else if(evt.target==this.nextButton){
+				this.onPage(1);
+			}else{
+				var tgt = evt.target;
+				// while the clicked node is inside the div
+				while(!tgt.item){
+					// recurse to the top
+					tgt = tgt.parentNode;
+				}
+				this._setValueAttr({ target: tgt }, true);
+			}
+		},
+
+		_onMouseOver: function(/*Event*/ evt){
+			if(evt.target === this.domNode){ return; }
+			var tgt = evt.target;
+			if(!(tgt == this.previousButton || tgt == this.nextButton)){
+				// while the clicked node is inside the div
+				while(!tgt.item){
+					// recurse to the top
+					tgt = tgt.parentNode;
+				}
+			}
+			this._focusOptionNode(tgt);
+		},
+
+		_onMouseOut: function(/*Event*/ evt){
+			if(evt.target === this.domNode){ return; }
+			this._blurOptionNode();
+		},
+
+		_focusOptionNode: function(/*DomNode*/ node){
+			// summary:
+			//		Does the actual highlight.
+			if(this._highlighted_option != node){
+				this._blurOptionNode();
+				this._highlighted_option = node;
+				dojo.addClass(this._highlighted_option, "dijitMenuItemSelected");
+			}
+		},
+
+		_blurOptionNode: function(){
+			// summary:
+			//		Removes highlight on highlighted option.
+			if(this._highlighted_option){
+				dojo.removeClass(this._highlighted_option, "dijitMenuItemSelected");
+				this._highlighted_option = null;
+			}
+		},
+
+		_highlightNextOption: function(){
+			//	summary:
+			// 		Highlight the item just below the current selection.
+			// 		If nothing selected, highlight first option.
+
+			// because each press of a button clears the menu,
+			// the highlighted option sometimes becomes detached from the menu!
+			// test to see if the option has a parent to see if this is the case.
+			var fc = this.domNode.firstChild;
+			if(!this.getHighlightedOption()){
+				this._focusOptionNode(fc.style.display=="none" ? fc.nextSibling : fc);
+			}else{
+				var ns = this._highlighted_option.nextSibling;
+				if(ns && ns.style.display!="none"){
+					this._focusOptionNode(ns);
+				}
+			}
+			// scrollIntoView is called outside of _focusOptionNode because in IE putting it inside causes the menu to scroll up on mouseover
+			dijit.scrollIntoView(this._highlighted_option);
+		},
+
+		highlightFirstOption: function(){
+			//	summary:
+			// 		Highlight the first real item in the list (not Previous Choices).
+			this._focusOptionNode(this.domNode.firstChild.nextSibling);
+			dijit.scrollIntoView(this._highlighted_option);
+		},
+
+		highlightLastOption: function(){
+			//	summary:
+			// 		Highlight the last real item in the list (not More Choices).
+			this._focusOptionNode(this.domNode.lastChild.previousSibling);
+			dijit.scrollIntoView(this._highlighted_option);
+		},
+
+		_highlightPrevOption: function(){
+			//	summary:
+			// 		Highlight the item just above the current selection.
+			// 		If nothing selected, highlight last option (if
+			// 		you select Previous and try to keep scrolling up the list).
+			var lc = this.domNode.lastChild;
+			if(!this.getHighlightedOption()){
+				this._focusOptionNode(lc.style.display == "none" ? lc.previousSibling : lc);
+			}else{
+				var ps = this._highlighted_option.previousSibling;
+				if(ps && ps.style.display != "none"){
+					this._focusOptionNode(ps);
+				}
+			}
+			dijit.scrollIntoView(this._highlighted_option);
+		},
+
+		_page: function(/*Boolean*/ up){
+			// summary:
+			//		Handles page-up and page-down keypresses
+
+			var scrollamount = 0;
+			var oldscroll = this.domNode.scrollTop;
+			var height = dojo.style(this.domNode, "height");
+			// if no item is highlighted, highlight the first option
+			if(!this.getHighlightedOption()){
+				this._highlightNextOption();
+			}
+			while(scrollamount<height){
+				if(up){
+					// stop at option 1
+					if(!this.getHighlightedOption().previousSibling ||
+						this._highlighted_option.previousSibling.style.display == "none"){
+						break;
+					}
+					this._highlightPrevOption();
+				}else{
+					// stop at last option
+					if(!this.getHighlightedOption().nextSibling ||
+						this._highlighted_option.nextSibling.style.display == "none"){
+						break;
+					}
+					this._highlightNextOption();
+				}
+				// going backwards
+				var newscroll=this.domNode.scrollTop;
+				scrollamount+=(newscroll-oldscroll)*(up ? -1:1);
+				oldscroll=newscroll;
+			}
+		},
+
+		pageUp: function(){
+			// summary:
+			//		Handles pageup keypress.
+			//		TODO: just call _page directly from handleKey().
+			// tags:
+			//		private
+			this._page(true);
+		},
+
+		pageDown: function(){
+			// summary:
+			//		Handles pagedown keypress.
+			//		TODO: just call _page directly from handleKey().
+			// tags:
+			//		private
+			this._page(false);
+		},
+
+		getHighlightedOption: function(){
+			//	summary:
+			//		Returns the highlighted option.
+			var ho = this._highlighted_option;
+			return (ho && ho.parentNode) ? ho : null;
+		},
+
+		handleKey: function(key){
+			switch(key){
+				case dojo.keys.DOWN_ARROW:
+					this._highlightNextOption();
+					break;
+				case dojo.keys.PAGE_DOWN:
+					this.pageDown();
+					break;	
+				case dojo.keys.UP_ARROW:
+					this._highlightPrevOption();
+					break;
+				case dojo.keys.PAGE_UP:
+					this.pageUp();
+					break;	
+			}
+		}
+	}
+);
+
+dojo.declare(
+	"dijit.form.ComboBox",
+	[dijit.form.ValidationTextBox, dijit.form.ComboBoxMixin],
+	{
+		//	summary:
+		//		Auto-completing text box, and base class for dijit.form.FilteringSelect.
+		// 
+		//	description:
+		//		The drop down box's values are populated from an class called
+		//		a data provider, which returns a list of values based on the characters
+		//		that the user has typed into the input box.
+		//		If OPTION tags are used as the data provider via markup,
+		//		then the OPTION tag's child text node is used as the widget value 
+		//		when selected.  The OPTION tag's value attribute is ignored.
+		//		To set the default value when using OPTION tags, specify the selected 
+		//		attribute on 1 of the child OPTION tags.
+		// 
+		//		Some of the options to the ComboBox are actually arguments to the data
+		//		provider.
+
+		_setValueAttr: function(/*String*/ value, /*Boolean?*/ priorityChange){
+			// summary:
+			//		Hook so attr('value', value) works.
+			// description:
+			//		Sets the value of the select.
+			if(!value){ value = ''; } // null translates to blank
+			dijit.form.ValidationTextBox.prototype._setValueAttr.call(this, value, priorityChange);
+		}
+	}
+);
+
+dojo.declare("dijit.form._ComboBoxDataStore", null, {
+	//	summary:
+	//		Inefficient but small data store specialized for inlined `dijit.form.ComboBox` data
+	//
+	//	description:
+	//		Provides a store for inlined data like:
+	//
+	//	|	<select>
+	//	|		<option value="AL">Alabama</option>
+	//	|		...
+	//
+	//		Actually. just implements the subset of dojo.data.Read/Notification
+	//		needed for ComboBox and FilteringSelect to work.
+	//
+	//		Note that an item is just a pointer to the <option> DomNode.
+
+	constructor: function( /*DomNode*/ root){
+		this.root = root;
+
+		dojo.query("> option", root).forEach(function(node){
+			//	TODO: this was added in #3858 but unclear why/if it's needed;  doesn't seem to be.
+			//	If it is needed then can we just hide the select itself instead?
+			//node.style.display="none";
+			node.innerHTML = dojo.trim(node.innerHTML);
+		});
+
+	},
+
+	getValue: function(	/* item */ item, 
+						/* attribute-name-string */ attribute, 
+						/* value? */ defaultValue){
+		return (attribute == "value") ? item.value : (item.innerText || item.textContent || '');
+	},
+
+	isItemLoaded: function(/* anything */ something) {
+		return true;
+	},
+
+	getFeatures: function(){
+		return {"dojo.data.api.Read": true, "dojo.data.api.Identity": true};
+	},
+	
+	_fetchItems: function(	/* Object */ args,
+							/* Function */ findCallback, 
+							/* Function */ errorCallback){
+		//	summary: 
+		//		See dojo.data.util.simpleFetch.fetch()
+		if(!args.query){ args.query = {}; }
+		if(!args.query.name){ args.query.name = ""; }
+		if(!args.queryOptions){ args.queryOptions = {}; }
+		var matcher = dojo.data.util.filter.patternToRegExp(args.query.name, args.queryOptions.ignoreCase),
+			items = dojo.query("> option", this.root).filter(function(option){
+				return (option.innerText || option.textContent || '').match(matcher);
+			} );
+		if(args.sort){
+			items.sort(dojo.data.util.sorter.createSortFunction(args.sort, this));
+		}
+		findCallback(items, args);
+	},
+
+	close: function(/*dojo.data.api.Request || args || null */ request){
+		return;
+	},
+
+	getLabel: function(/* item */ item){
+		return item.innerHTML;
+	},
+
+	getIdentity: function(/* item */ item){
+		return dojo.attr(item, "value");
+	},
+
+	fetchItemByIdentity: function(/* Object */ args){
+		//	summary:
+		//		Given the identity of an item, this method returns the item that has
+		//		that identity through the onItem callback.
+		//		Refer to dojo.data.api.Identity.fetchItemByIdentity() for more details.
+		//
+		//	description:
+		//		Given arguments like:
+		//
+		//	|		{identity: "CA", onItem: function(item){...}
+		//
+		//		Call `onItem()` with the DOM node `<option value="CA">California</option>`
+		var item = dojo.query("option[value='" + args.identity + "']", this.root)[0];
+		args.onItem(item);
+	},
+	
+	fetchSelectedItem: function(){
+		//	summary:
+		//		Get the option marked as selected, like `<option selected>`.
+		//		Not part of dojo.data API.
+		var root = this.root,
+			si = root.selectedIndex;
+		return dojo.query("> option:nth-child(" +
+			(si != -1 ? si+1 : 1) + ")",
+			root)[0];	// dojo.data.Item
+	}
+});
+//Mix in the simple fetch implementation to this class. 
+dojo.extend(dijit.form._ComboBoxDataStore,dojo.data.util.simpleFetch);
+
+}
+
+if(!dojo._hasResource["dojo.cldr.monetary"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.cldr.monetary"] = true;
+dojo.provide("dojo.cldr.monetary");
+
+dojo.cldr.monetary.getData = function(/*String*/code){
+// summary: A mapping of currency code to currency-specific formatting information. Returns a unique object with properties: places, round.
+// code: an [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) currency code
+
+// from http://www.unicode.org/cldr/data/common/supplemental/supplementalData.xml:supplementalData/currencyData/fractions
+
+	var placesData = {
+		ADP:0,BHD:3,BIF:0,BYR:0,CLF:0,CLP:0,DJF:0,ESP:0,GNF:0,
+		IQD:3,ITL:0,JOD:3,JPY:0,KMF:0,KRW:0,KWD:3,LUF:0,LYD:3,
+		MGA:0,MGF:0,OMR:3,PYG:0,RWF:0,TND:3,TRL:0,VUV:0,XAF:0,
+		XOF:0,XPF:0
+	};
+
+	var roundingData = {CHF:5};
+
+	var places = placesData[code], round = roundingData[code];
+	if(typeof places == "undefined"){ places = 2; }
+	if(typeof round == "undefined"){ round = 0; }
+
+	return {places: places, round: round}; // Object
+};
+
+}
+
+if(!dojo._hasResource["dojo.currency"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.currency"] = true;
+dojo.provide("dojo.currency");
+
+
+
+
+
+
+/*=====
+dojo.currency = {
+	// summary: localized formatting and parsing routines for currencies
+}
+=====*/
+
+dojo.currency._mixInDefaults = function(options){
+	options = options || {};
+	options.type = "currency";
+
+	// Get locale-depenent currency data, like the symbol
+	var bundle = dojo.i18n.getLocalization("dojo.cldr", "currency", options.locale) || {};
+
+	// Mixin locale-independent currency data, like # of places
+	var iso = options.currency;
+	var data = dojo.cldr.monetary.getData(iso);
+
+	dojo.forEach(["displayName","symbol","group","decimal"], function(prop){
+		data[prop] = bundle[iso+"_"+prop];
+	});
+
+	data.fractional = [true, false];
+
+	// Mixin with provided options
+	return dojo.mixin(data, options);
+}
+
+dojo.currency.format = function(/*Number*/value, /*dojo.number.__FormatOptions?*/options){
+// summary:
+//		Format a Number as a currency, using locale-specific settings
+//
+// description:
+//		Create a string from a Number using a known, localized pattern.
+//		[Formatting patterns](http://www.unicode.org/reports/tr35/#Number_Elements) appropriate to the locale are chosen from the [CLDR](http://unicode.org/cldr)
+//		as well as the appropriate symbols and delimiters.
+//
+// value:
+//		the number to be formatted.
+
+	return dojo.number.format(value, dojo.currency._mixInDefaults(options));
+}
+
+dojo.currency.regexp = function(/*dojo.number.__RegexpOptions?*/options){
+//
+// summary:
+//		Builds the regular needed to parse a currency value
+//
+// description:
+//		Returns regular expression with positive and negative match, group and decimal separators
+//		Note: the options.places default, the number of decimal places to accept, is defined by the currency type.
+	return dojo.number.regexp(dojo.currency._mixInDefaults(options)); // String
+}
+
+/*=====
+dojo.declare("dojo.currency.__ParseOptions", [dojo.number.__ParseOptions], {
+	//	type: String?
+	//		currency, set by default.
+	//	symbol: String?
+	//		override currency symbol. Normally, will be looked up in table of supported currencies,
+	//		and ISO currency code will be used if not found.  See dojo.i18n.cldr.nls->currency.js
+	//	places: Number?
+	//		number of decimal places to accept.  Default is defined by currency.
+	//	fractional: Boolean?|Array?
+	//		where places are implied by pattern or explicit 'places' parameter, whether to include the fractional portion.
+	//		By default for currencies, it the fractional portion is optional.
+	type: "",
+	symbol: "",
+	places: "",
+	fractional: ""
+});
+=====*/
+
+dojo.currency.parse = function(/*String*/expression, /*dojo.currency.__ParseOptions?*/options){
+	//
+	// summary:
+	//		Convert a properly formatted currency string to a primitive Number,
+	//		using locale-specific settings.
+	//
+	// description:
+	//		Create a Number from a string using a known, localized pattern.
+	//		[Formatting patterns](http://www.unicode.org/reports/tr35/#Number_Format_Patterns) are chosen appropriate to the locale.
+	//
+	// expression: A string representation of a Number
+
+	return dojo.number.parse(expression, dojo.currency._mixInDefaults(options));
+}
+
+}
+
+if(!dojo._hasResource["dijit.form.NumberTextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.NumberTextBox"] = true;
+dojo.provide("dijit.form.NumberTextBox");
+
+
+
+
+/*=====
+dojo.declare(
+	"dijit.form.NumberTextBox.__Constraints",
+	[dijit.form.RangeBoundTextBox.__Constraints, dojo.number.__FormatOptions, dojo.number.__ParseOptions]
+);
+=====*/
+
+dojo.declare("dijit.form.NumberTextBoxMixin",
+	null,
+	{
+		// summary:
+		//		A mixin for all number textboxes
+		// tags:
+		//		protected
+
+		// Override ValidationTextBox.regExpGen().... we use a reg-ex generating function rather
+		// than a straight regexp to deal with locale (plus formatting options too?)
+		regExpGen: dojo.number.regexp,
+
+		/*=====
+		// constraints: dijit.form.NumberTextBox.__Constraints
+		//		Minimum/maximum allowed values.
+		constraints: {},
+		======*/
+
+		// value: Number
+		//		The value of this NumberTextBox as a javascript Number (ie, not a String).
+		//		If the displayed value is blank, the value is NaN, and if the user types in
+		//		an gibberish value (like "hello world"), the value is undefined
+		//		(i.e. attr('value') returns undefined).
+		//
+		//		Symetrically, attr('value', NaN) will clear the displayed value,
+		//		whereas attr('value', undefined) will have no effect.
+		value: NaN,
+
+		// editOptions: [protected] Object
+		//		Properties to mix into constraints when the value is being edited.
+		//		This is here because we edit the number in the format "12345", which is
+		//		different than the display value (ex: "12,345")
+		editOptions: { pattern: '#.######' },
+
+		/*=====
+		_formatter: function(value, options){
+			// summary:
+			//		_formatter() is called by format().   It's the base routine for formatting a number,
+			//		as a string, for example converting 12345 into "12,345".
+			// value: Number
+			//		The number to be converted into a string.
+			// options: dojo.number.__FormatOptions?
+			//		Formatting options
+			// tags:
+			//		protected extension
+
+			return "12345";		// String
+		},
+		 =====*/
+		_formatter: dojo.number.format,
+
+		postMixInProperties: function(){
+			if(typeof this.constraints.max != "number"){
+				this.constraints.max = 9e+15;
+			}
+			this.inherited(arguments);
+		},
+
+		_onFocus: function(){
+			if(this.disabled){ return; }
+			var val = this.attr('value');
+			if(typeof val == "number" && !isNaN(val)){
+				var formattedValue = this.format(val, this.constraints);
+				if(formattedValue !== undefined){
+					this.textbox.value = formattedValue;
+				}
+			}
+			this.inherited(arguments);
+		},
+
+		format: function(/*Number*/ value, /*dojo.number.__FormatOptions*/ constraints){
+			// summary:
+			//		Formats the value as a Number, according to constraints.
+			// tags:
+			//		protected
+
+			if(typeof value != "number") { return String(value) }
+			if(isNaN(value)){ return ""; }
+			if(("rangeCheck" in this) && !this.rangeCheck(value, constraints)){ return String(value) }
+			if(this.editOptions && this._focused){
+				constraints = dojo.mixin(dojo.mixin({}, this.editOptions), constraints);
+			}
+			return this._formatter(value, constraints);
+		},
+
+		/*=====
+		parse: function(value, constraints){
+			// summary:
+			//		Parses the string value as a Number, according to constraints.
+			// value: String
+			//		String representing a number
+			// constraints: dojo.number.__ParseOptions
+			//		Formatting options
+			// tags:
+			//		protected
+
+			return 123.45;		// Number
+		},
+		=====*/
+		parse: dojo.number.parse,
+
+		_getDisplayedValueAttr: function(){
+			var v = this.inherited(arguments); 
+			return isNaN(v) ? this.textbox.value : v;
+		},
+
+		filter: function(/*Number*/ value){
+			// summary:
+			//		This is called with both the display value (string), and the actual value (a number).
+			//		When called with the actual value it does corrections so that '' etc. are represented as NaN.
+			//		Otherwise it dispatches to the superclass's filter() method.
+			//
+			//		See `dijit.form.TextBox.filter` for more details.
+			return (value === null || value === '' || value === undefined) ? NaN : this.inherited(arguments); // attr('value', null||''||undefined) should fire onChange(NaN)
+		},
+
+		serialize: function(/*Number*/ value, /*Object?*/options){
+			// summary:
+			//		Convert value (a Number) into a canonical string (ie, how the number literal is written in javascript/java/C/etc.)
+			// tags:
+			//		protected
+			return (typeof value != "number" || isNaN(value))? '' : this.inherited(arguments);
+		},
+
+		_setValueAttr: function(/*Number*/ value, /*Boolean?*/ priorityChange, /*String?*/formattedValue){
+			// summary:
+			//		Hook so attr('value', ...) works.
+			if(value !== undefined && formattedValue === undefined){
+				if(typeof value == "number"){
+					if(isNaN(value)){ formattedValue = '' }
+					else if(("rangeCheck" in this) && !this.rangeCheck(value, this.constraints)){
+						formattedValue = String(value);
+					}
+				}else if(!value){ // 0 processed in if branch above, ''|null|undefined flow thru here
+					formattedValue = '';
+					value = NaN;
+				}else{ // non-numeric values
+					formattedValue = String(value);
+					value = undefined;
+				}
+			}
+			this.inherited(arguments, [value, priorityChange, formattedValue]);
+		},
+
+
+		_getValueAttr: function(){
+			// summary:
+			//		Hook so attr('value') works.
+			//		Returns Number, NaN for '', or undefined for unparsable text
+			var v = this.inherited(arguments); // returns Number for all values accepted by parse() or NaN for all other displayed values
+
+			// If the displayed value of the textbox is gibberish (ex: "hello world"), this.inherited() above
+			// returns NaN; this if() branch converts the return value to undefined.
+			// Returning undefined prevents user text from being overwritten when doing _setValueAttr(_getValueAttr()).
+			// A blank displayed value is still returned as NaN.
+			if(isNaN(v) && this.textbox.value !== ''){ // if displayed value other than ''
+				var n = Number(this.textbox.value); // check for exponential notation that parse() rejected (erroneously?)
+				return (String(n)===this.textbox.value)? n : undefined; // return exponential Number or undefined for random text
+			}else{ return v } // Number or NaN for ''
+		}
+	}
+);
+
+dojo.declare("dijit.form.NumberTextBox",
+	[dijit.form.RangeBoundTextBox,dijit.form.NumberTextBoxMixin],
+	{
+		// summary:
+		//		A validating, serializable, range-bound text box.
+	}
+);
+
+}
+
+if(!dojo._hasResource["dijit.form.CurrencyTextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.CurrencyTextBox"] = true;
+dojo.provide("dijit.form.CurrencyTextBox");
+
+//FIXME: dojo.experimental throws an unreadable exception?
+//dojo.experimental("dijit.form.CurrencyTextBox");
+
+
+
+
+/*=====
+dojo.declare(
+	"dijit.form.CurrencyTextBox.__Constraints",
+	[dijit.form.NumberTextBox.__Constraints, dojo.currency.__FormatOptions, dojo.currency.__ParseOptions]
+);
+=====*/
+
+dojo.declare(
+	"dijit.form.CurrencyTextBox",
+	dijit.form.NumberTextBox,
+	{
+		// summary:
+		//		A validating currency textbox
+
+		// currency: String
+		//		the [ISO4217](http://en.wikipedia.org/wiki/ISO_4217) currency code, a three letter sequence like "USD"
+		currency: "",
+
+		/*=====
+		// constraints: dijit.form.CurrencyTextBox.__Constraints
+		//		Minimum/maximum amount allowed.
+		constraints: {},
+		======*/
+
+		// Override regExpGen ValidationTextBox.regExpGen().... we use a reg-ex generating function rather
+		// than a straight regexp to deal with locale  (plus formatting options too?)
+		regExpGen: dojo.currency.regexp,
+
+		// Override NumberTextBox._formatter to deal with currencies, ex: converts "123.45" to "$123.45"
+		_formatter: dojo.currency.format,
+
+/*=====
+		parse: function(value, constraints){
+			// summary:
+			//		Parses string as a Currency, according to constraints
+			// value: String
+			//		The currency represented as a string
+			// constraints: dojo.currency.__ParseOptions
+			// tags:
+			//		protected
+
+			return 123.45;		// Number
+		},
+=====*/
+		parse: dojo.currency.parse,
+
+		postMixInProperties: function(){
+			this.constraints.currency = this.currency;
+			this.inherited(arguments);
+		}
+	}
+);
+
+}
+
+if(!dojo._hasResource["dojo.cldr.supplemental"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.cldr.supplemental"] = true;
+dojo.provide("dojo.cldr.supplemental");
+
+
+
+dojo.cldr.supplemental.getFirstDayOfWeek = function(/*String?*/locale){
+// summary: Returns a zero-based index for first day of the week
+// description:
+//		Returns a zero-based index for first day of the week, as used by the local (Gregorian) calendar.
+//		e.g. Sunday (returns 0), or Monday (returns 1)
+
+	// from http://www.unicode.org/cldr/data/common/supplemental/supplementalData.xml:supplementalData/weekData/firstDay
+	var firstDay = {/*default is 1=Monday*/
+		mv:5,
+		ae:6,af:6,bh:6,dj:6,dz:6,eg:6,er:6,et:6,iq:6,ir:6,jo:6,ke:6,kw:6,lb:6,ly:6,ma:6,om:6,qa:6,sa:6,
+		sd:6,so:6,tn:6,ye:6,
+		as:0,au:0,az:0,bw:0,ca:0,cn:0,fo:0,ge:0,gl:0,gu:0,hk:0,ie:0,il:0,is:0,jm:0,jp:0,kg:0,kr:0,la:0,
+		mh:0,mo:0,mp:0,mt:0,nz:0,ph:0,pk:0,sg:0,th:0,tt:0,tw:0,um:0,us:0,uz:0,vi:0,za:0,zw:0,
+		et:0,mw:0,ng:0,tj:0,
+// variant. do not use?		gb:0,
+		sy:4
+	};
+
+	var country = dojo.cldr.supplemental._region(locale);
+	var dow = firstDay[country];
+	return (dow === undefined) ? 1 : dow; /*Number*/
+};
+
+dojo.cldr.supplemental._region = function(/*String?*/locale){
+	locale = dojo.i18n.normalizeLocale(locale);
+	var tags = locale.split('-');
+	var region = tags[1];
+	if(!region){
+		// IE often gives language only (#2269)
+		// Arbitrary mappings of language-only locales to a country:
+		region = {de:"de", en:"us", es:"es", fi:"fi", fr:"fr", he:"il", hu:"hu", it:"it",
+			ja:"jp", ko:"kr", nl:"nl", pt:"br", sv:"se", zh:"cn"}[tags[0]];
+	}else if(region.length == 4){
+		// The ISO 3166 country code is usually in the second position, unless a
+		// 4-letter script is given. See http://www.ietf.org/rfc/rfc4646.txt
+		region = tags[2];
+	}
+	return region;
+}
+
+dojo.cldr.supplemental.getWeekend = function(/*String?*/locale){
+// summary: Returns a hash containing the start and end days of the weekend
+// description:
+//		Returns a hash containing the start and end days of the weekend according to local custom using locale,
+//		or by default in the user's locale.
+//		e.g. {start:6, end:0}
+
+	// from http://www.unicode.org/cldr/data/common/supplemental/supplementalData.xml:supplementalData/weekData/weekend{Start,End}
+	var weekendStart = {/*default is 6=Saturday*/
+		eg:5,il:5,sy:5,
+		'in':0,
+		ae:4,bh:4,dz:4,iq:4,jo:4,kw:4,lb:4,ly:4,ma:4,om:4,qa:4,sa:4,sd:4,tn:4,ye:4		
+	};
+
+	var weekendEnd = {/*default is 0=Sunday*/
+		ae:5,bh:5,dz:5,iq:5,jo:5,kw:5,lb:5,ly:5,ma:5,om:5,qa:5,sa:5,sd:5,tn:5,ye:5,af:5,ir:5,
+		eg:6,il:6,sy:6
+	};
+
+	var country = dojo.cldr.supplemental._region(locale);
+	var start = weekendStart[country];
+	var end = weekendEnd[country];
+	if(start === undefined){start=6;}
+	if(end === undefined){end=0;}
+	return {start:start, end:end}; /*Object {start,end}*/
+};
+
+}
+
+if(!dojo._hasResource["dojo.date"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.date"] = true;
+dojo.provide("dojo.date");
+
+/*=====
+dojo.date = {
+	// summary: Date manipulation utilities
+}
+=====*/
+
+dojo.date.getDaysInMonth = function(/*Date*/dateObject){
+	//	summary:
+	//		Returns the number of days in the month used by dateObject
+	var month = dateObject.getMonth();
+	var days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+	if(month == 1 && dojo.date.isLeapYear(dateObject)){ return 29; } // Number
+	return days[month]; // Number
+}
+
+dojo.date.isLeapYear = function(/*Date*/dateObject){
+	//	summary:
+	//		Determines if the year of the dateObject is a leap year
+	//	description:
+	//		Leap years are years with an additional day YYYY-02-29, where the
+	//		year number is a multiple of four with the following exception: If
+	//		a year is a multiple of 100, then it is only a leap year if it is
+	//		also a multiple of 400. For example, 1900 was not a leap year, but
+	//		2000 is one.
+
+	var year = dateObject.getFullYear();
+	return !(year%400) || (!(year%4) && !!(year%100)); // Boolean
+}
+
+// FIXME: This is not localized
+dojo.date.getTimezoneName = function(/*Date*/dateObject){
+	//	summary:
+	//		Get the user's time zone as provided by the browser
+	// dateObject:
+	//		Needed because the timezone may vary with time (daylight savings)
+	//	description:
+	//		Try to get time zone info from toString or toLocaleString method of
+	//		the Date object -- UTC offset is not a time zone.  See
+	//		http://www.twinsun.com/tz/tz-link.htm Note: results may be
+	//		inconsistent across browsers.
+
+	var str = dateObject.toString(); // Start looking in toString
+	var tz = ''; // The result -- return empty string if nothing found
+	var match;
+
+	// First look for something in parentheses -- fast lookup, no regex
+	var pos = str.indexOf('(');
+	if(pos > -1){
+		tz = str.substring(++pos, str.indexOf(')'));
+	}else{
+		// If at first you don't succeed ...
+		// If IE knows about the TZ, it appears before the year
+		// Capital letters or slash before a 4-digit year 
+		// at the end of string
+		var pat = /([A-Z\/]+) \d{4}$/;
+		if((match = str.match(pat))){
+			tz = match[1];
+		}else{
+		// Some browsers (e.g. Safari) glue the TZ on the end
+		// of toLocaleString instead of putting it in toString
+			str = dateObject.toLocaleString();
+			// Capital letters or slash -- end of string, 
+			// after space
+			pat = / ([A-Z\/]+)$/;
+			if((match = str.match(pat))){
+				tz = match[1];
+			}
+		}
+	}
+
+	// Make sure it doesn't somehow end up return AM or PM
+	return (tz == 'AM' || tz == 'PM') ? '' : tz; // String
+}
+
+// Utility methods to do arithmetic calculations with Dates
+
+dojo.date.compare = function(/*Date*/date1, /*Date?*/date2, /*String?*/portion){
+	//	summary:
+	//		Compare two date objects by date, time, or both.
+	//	description:
+	//  	Returns 0 if equal, positive if a > b, else negative.
+	//	date1:
+	//		Date object
+	//	date2:
+	//		Date object.  If not specified, the current Date is used.
+	//	portion:
+	//		A string indicating the "date" or "time" portion of a Date object.
+	//		Compares both "date" and "time" by default.  One of the following:
+	//		"date", "time", "datetime"
+
+	// Extra step required in copy for IE - see #3112
+	date1 = new Date(Number(date1));
+	date2 = new Date(Number(date2 || new Date()));
+
+	if(portion !== "undefined"){
+		if(portion == "date"){
+			// Ignore times and compare dates.
+			date1.setHours(0, 0, 0, 0);
+			date2.setHours(0, 0, 0, 0);
+		}else if(portion == "time"){
+			// Ignore dates and compare times.
+			date1.setFullYear(0, 0, 0);
+			date2.setFullYear(0, 0, 0);
+		}
+	}
+	
+	if(date1 > date2){ return 1; } // int
+	if(date1 < date2){ return -1; } // int
+	return 0; // int
+};
+
+dojo.date.add = function(/*Date*/date, /*String*/interval, /*int*/amount){
+	//	summary:
+	//		Add to a Date in intervals of different size, from milliseconds to years
+	//	date: Date
+	//		Date object to start with
+	//	interval:
+	//		A string representing the interval.  One of the following:
+	//			"year", "month", "day", "hour", "minute", "second",
+	//			"millisecond", "quarter", "week", "weekday"
+	//	amount:
+	//		How much to add to the date.
+
+	var sum = new Date(Number(date)); // convert to Number before copying to accomodate IE (#3112)
+	var fixOvershoot = false;
+	var property = "Date";
+
+	switch(interval){
+		case "day":
+			break;
+		case "weekday":
+			//i18n FIXME: assumes Saturday/Sunday weekend, but this is not always true.  see dojo.cldr.supplemental
+
+			// Divide the increment time span into weekspans plus leftover days
+			// e.g., 8 days is one 5-day weekspan / and two leftover days
+			// Can't have zero leftover days, so numbers divisible by 5 get
+			// a days value of 5, and the remaining days make up the number of weeks
+			var days, weeks;
+			var mod = amount % 5;
+			if(!mod){
+				days = (amount > 0) ? 5 : -5;
+				weeks = (amount > 0) ? ((amount-5)/5) : ((amount+5)/5);
+			}else{
+				days = mod;
+				weeks = parseInt(amount/5);
+			}
+			// Get weekday value for orig date param
+			var strt = date.getDay();
+			// Orig date is Sat / positive incrementer
+			// Jump over Sun
+			var adj = 0;
+			if(strt == 6 && amount > 0){
+				adj = 1;
+			}else if(strt == 0 && amount < 0){
+			// Orig date is Sun / negative incrementer
+			// Jump back over Sat
+				adj = -1;
+			}
+			// Get weekday val for the new date
+			var trgt = strt + days;
+			// New date is on Sat or Sun
+			if(trgt == 0 || trgt == 6){
+				adj = (amount > 0) ? 2 : -2;
+			}
+			// Increment by number of weeks plus leftover days plus
+			// weekend adjustments
+			amount = (7 * weeks) + days + adj;
+			break;
+		case "year":
+			property = "FullYear";
+			// Keep increment/decrement from 2/29 out of March
+			fixOvershoot = true;
+			break;
+		case "week":
+			amount *= 7;
+			break;
+		case "quarter":
+			// Naive quarter is just three months
+			amount *= 3;
+			// fallthrough...
+		case "month":
+			// Reset to last day of month if you overshoot
+			fixOvershoot = true;
+			property = "Month";
+			break;
+		case "hour":
+		case "minute":
+		case "second":
+		case "millisecond":
+			property = "UTC"+interval.charAt(0).toUpperCase() + interval.substring(1) + "s";
+	}
+
+	if(property){
+		sum["set"+property](sum["get"+property]()+amount);
+	}
+
+	if(fixOvershoot && (sum.getDate() < date.getDate())){
+		sum.setDate(0);
+	}
+
+	return sum; // Date
+};
+
+dojo.date.difference = function(/*Date*/date1, /*Date?*/date2, /*String?*/interval){
+	//	summary:
+	//		Get the difference in a specific unit of time (e.g., number of
+	//		months, weeks, days, etc.) between two dates, rounded to the
+	//		nearest integer.
+	//	date1:
+	//		Date object
+	//	date2:
+	//		Date object.  If not specified, the current Date is used.
+	//	interval:
+	//		A string representing the interval.  One of the following:
+	//			"year", "month", "day", "hour", "minute", "second",
+	//			"millisecond", "quarter", "week", "weekday"
+	//		Defaults to "day".
+
+	date2 = date2 || new Date();
+	interval = interval || "day";
+	var yearDiff = date2.getFullYear() - date1.getFullYear();
+	var delta = 1; // Integer return value
+
+	switch(interval){
+		case "quarter":
+			var m1 = date1.getMonth();
+			var m2 = date2.getMonth();
+			// Figure out which quarter the months are in
+			var q1 = Math.floor(m1/3) + 1;
+			var q2 = Math.floor(m2/3) + 1;
+			// Add quarters for any year difference between the dates
+			q2 += (yearDiff * 4);
+			delta = q2 - q1;
+			break;
+		case "weekday":
+			var days = Math.round(dojo.date.difference(date1, date2, "day"));
+			var weeks = parseInt(dojo.date.difference(date1, date2, "week"));
+			var mod = days % 7;
+
+			// Even number of weeks
+			if(mod == 0){
+				days = weeks*5;
+			}else{
+				// Weeks plus spare change (< 7 days)
+				var adj = 0;
+				var aDay = date1.getDay();
+				var bDay = date2.getDay();
+
+				weeks = parseInt(days/7);
+				mod = days % 7;
+				// Mark the date advanced by the number of
+				// round weeks (may be zero)
+				var dtMark = new Date(date1);
+				dtMark.setDate(dtMark.getDate()+(weeks*7));
+				var dayMark = dtMark.getDay();
+
+				// Spare change days -- 6 or less
+				if(days > 0){
+					switch(true){
+						// Range starts on Sat
+						case aDay == 6:
+							adj = -1;
+							break;
+						// Range starts on Sun
+						case aDay == 0:
+							adj = 0;
+							break;
+						// Range ends on Sat
+						case bDay == 6:
+							adj = -1;
+							break;
+						// Range ends on Sun
+						case bDay == 0:
+							adj = -2;
+							break;
+						// Range contains weekend
+						case (dayMark + mod) > 5:
+							adj = -2;
+					}
+				}else if(days < 0){
+					switch(true){
+						// Range starts on Sat
+						case aDay == 6:
+							adj = 0;
+							break;
+						// Range starts on Sun
+						case aDay == 0:
+							adj = 1;
+							break;
+						// Range ends on Sat
+						case bDay == 6:
+							adj = 2;
+							break;
+						// Range ends on Sun
+						case bDay == 0:
+							adj = 1;
+							break;
+						// Range contains weekend
+						case (dayMark + mod) < 0:
+							adj = 2;
+					}
+				}
+				days += adj;
+				days -= (weeks*2);
+			}
+			delta = days;
+			break;
+		case "year":
+			delta = yearDiff;
+			break;
+		case "month":
+			delta = (date2.getMonth() - date1.getMonth()) + (yearDiff * 12);
+			break;
+		case "week":
+			// Truncate instead of rounding
+			// Don't use Math.floor -- value may be negative
+			delta = parseInt(dojo.date.difference(date1, date2, "day")/7);
+			break;
+		case "day":
+			delta /= 24;
+			// fallthrough
+		case "hour":
+			delta /= 60;
+			// fallthrough
+		case "minute":
+			delta /= 60;
+			// fallthrough
+		case "second":
+			delta /= 1000;
+			// fallthrough
+		case "millisecond":
+			delta *= date2.getTime() - date1.getTime();
+	}
+
+	// Round for fractional values and DST leaps
+	return Math.round(delta); // Number (integer)
+};
+
+}
+
+if(!dojo._hasResource["dojo.date.locale"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.date.locale"] = true;
+dojo.provide("dojo.date.locale");
+
+// Localization methods for Date.   Honor local customs using locale-dependent dojo.cldr data.
+
+
+
+
+
+
+
+// Load the bundles containing localization information for
+// names and formats
+
+
+//NOTE: Everything in this module assumes Gregorian calendars.
+// Other calendars will be implemented in separate modules.
+
+(function(){
+	// Format a pattern without literals
+	function formatPattern(dateObject, bundle, fullYear, pattern){
+		return pattern.replace(/([a-z])\1*/ig, function(match){
+			var s, pad;
+			var c = match.charAt(0);
+			var l = match.length;
+			var widthList = ["abbr", "wide", "narrow"];
+			switch(c){
+				case 'G':
+					s = bundle[(l < 4) ? "eraAbbr" : "eraNames"][dateObject.getFullYear() < 0 ? 0 : 1];
+					break;
+				case 'y':
+					s = dateObject.getFullYear();
+					switch(l){
+						case 1:
+							break;
+						case 2:
+							if(!fullYear){
+								s = String(s); s = s.substr(s.length - 2);
+								break;
+							}
+							// fallthrough
+						default:
+							pad = true;
+					}
+					break;
+				case 'Q':
+				case 'q':
+					s = Math.ceil((dateObject.getMonth()+1)/3);
+//					switch(l){
+//						case 1: case 2:
+							pad = true;
+//							break;
+//						case 3: case 4: // unimplemented
+//					}
+					break;
+				case 'M':
+					var m = dateObject.getMonth();
+					if(l<3){
+						s = m+1; pad = true;
+					}else{
+						var propM = ["months", "format", widthList[l-3]].join("-");
+						s = bundle[propM][m];
+					}
+					break;
+				case 'w':
+					var firstDay = 0;
+					s = dojo.date.locale._getWeekOfYear(dateObject, firstDay); pad = true;
+					break;
+				case 'd':
+					s = dateObject.getDate(); pad = true;
+					break;
+				case 'D':
+					s = dojo.date.locale._getDayOfYear(dateObject); pad = true;
+					break;
+				case 'E':
+					var d = dateObject.getDay();
+					if(l<3){
+						s = d+1; pad = true;
+					}else{
+						var propD = ["days", "format", widthList[l-3]].join("-");
+						s = bundle[propD][d];
+					}
+					break;
+				case 'a':
+					var timePeriod = (dateObject.getHours() < 12) ? 'am' : 'pm';
+					s = bundle[timePeriod];
+					break;
+				case 'h':
+				case 'H':
+				case 'K':
+				case 'k':
+					var h = dateObject.getHours();
+					// strange choices in the date format make it impossible to write this succinctly
+					switch (c){
+						case 'h': // 1-12
+							s = (h % 12) || 12;
+							break;
+						case 'H': // 0-23
+							s = h;
+							break;
+						case 'K': // 0-11
+							s = (h % 12);
+							break;
+						case 'k': // 1-24
+							s = h || 24;
+							break;
+					}
+					pad = true;
+					break;
+				case 'm':
+					s = dateObject.getMinutes(); pad = true;
+					break;
+				case 's':
+					s = dateObject.getSeconds(); pad = true;
+					break;
+				case 'S':
+					s = Math.round(dateObject.getMilliseconds() * Math.pow(10, l-3)); pad = true;
+					break;
+				case 'v': // FIXME: don't know what this is. seems to be same as z?
+				case 'z':
+					// We only have one timezone to offer; the one from the browser
+					s = dojo.date.getTimezoneName(dateObject);
+					if(s){break;}
+					l=4;
+					// fallthrough... use GMT if tz not available
+				case 'Z':
+					var offset = dateObject.getTimezoneOffset();
+					var tz = [
+						(offset<=0 ? "+" : "-"),
+						dojo.string.pad(Math.floor(Math.abs(offset)/60), 2),
+						dojo.string.pad(Math.abs(offset)% 60, 2)
+					];
+					if(l==4){
+						tz.splice(0, 0, "GMT");
+						tz.splice(3, 0, ":");
+					}
+					s = tz.join("");
+					break;
+//				case 'Y': case 'u': case 'W': case 'F': case 'g': case 'A': case 'e':
+//					
+				default:
+					throw new Error("dojo.date.locale.format: invalid pattern char: "+pattern);
+			}
+			if(pad){ s = dojo.string.pad(s, l); }
+			return s;
+		});
+	}
+
+/*=====
+	dojo.date.locale.__FormatOptions = function(){
+	//	selector: String
+	//		choice of 'time','date' (default: date and time)
+	//	formatLength: String
+	//		choice of long, short, medium or full (plus any custom additions).  Defaults to 'short'
+	//	datePattern:String
+	//		override pattern with this string
+	//	timePattern:String
+	//		override pattern with this string
+	//	am: String
+	//		override strings for am in times
+	//	pm: String
+	//		override strings for pm in times
+	//	locale: String
+	//		override the locale used to determine formatting rules
+	//	fullYear: Boolean
+	//		(format only) use 4 digit years whenever 2 digit years are called for
+	//	strict: Boolean
+	//		(parse only) strict parsing, off by default
+		this.selector = selector;
+		this.formatLength = formatLength;
+		this.datePattern = datePattern;
+		this.timePattern = timePattern;
+		this.am = am;
+		this.pm = pm;
+		this.locale = locale;
+		this.fullYear = fullYear;
+		this.strict = strict;
+	}
+=====*/
+
+dojo.date.locale.format = function(/*Date*/dateObject, /*dojo.date.locale.__FormatOptions?*/options){
+	// summary:
+	//		Format a Date object as a String, using locale-specific settings.
+	//
+	// description:
+	//		Create a string from a Date object using a known localized pattern.
+	//		By default, this method formats both date and time from dateObject.
+	//		Formatting patterns are chosen appropriate to the locale.  Different
+	//		formatting lengths may be chosen, with "full" used by default.
+	//		Custom patterns may be used or registered with translations using
+	//		the dojo.date.locale.addCustomFormats method.
+	//		Formatting patterns are implemented using [the syntax described at
+	//		unicode.org](http://www.unicode.org/reports/tr35/tr35-4.html#Date_Format_Patterns)
+	//
+	// dateObject:
+	//		the date and/or time to be formatted.  If a time only is formatted,
+	//		the values in the year, month, and day fields are irrelevant.  The
+	//		opposite is true when formatting only dates.
+
+	options = options || {};
+
+	var locale = dojo.i18n.normalizeLocale(options.locale);
+	var formatLength = options.formatLength || 'short';
+	var bundle = dojo.date.locale._getGregorianBundle(locale);
+	var str = [];
+	var sauce = dojo.hitch(this, formatPattern, dateObject, bundle, options.fullYear);
+	if(options.selector == "year"){
+		// Special case as this is not yet driven by CLDR data
+		var year = dateObject.getFullYear();
+		if(locale.match(/^zh|^ja/)){
+			year += "\u5E74";
+		}
+		return year;
+	}
+	if(options.selector != "time"){
+		var datePattern = options.datePattern || bundle["dateFormat-"+formatLength];
+		if(datePattern){str.push(_processPattern(datePattern, sauce));}
+	}
+	if(options.selector != "date"){
+		var timePattern = options.timePattern || bundle["timeFormat-"+formatLength];
+		if(timePattern){str.push(_processPattern(timePattern, sauce));}
+	}
+	var result = str.join(" "); //TODO: use locale-specific pattern to assemble date + time
+	return result; // String
+};
+
+dojo.date.locale.regexp = function(/*dojo.date.locale.__FormatOptions?*/options){
+	// summary:
+	//		Builds the regular needed to parse a localized date
+
+	return dojo.date.locale._parseInfo(options).regexp; // String
+};
+
+dojo.date.locale._parseInfo = function(/*dojo.date.locale.__FormatOptions?*/options){
+	options = options || {};
+	var locale = dojo.i18n.normalizeLocale(options.locale);
+	var bundle = dojo.date.locale._getGregorianBundle(locale);
+	var formatLength = options.formatLength || 'short';
+	var datePattern = options.datePattern || bundle["dateFormat-" + formatLength];
+	var timePattern = options.timePattern || bundle["timeFormat-" + formatLength];
+	var pattern;
+	if(options.selector == 'date'){
+		pattern = datePattern;
+	}else if(options.selector == 'time'){
+		pattern = timePattern;
+	}else{
+		pattern = datePattern + ' ' + timePattern; //TODO: use locale-specific pattern to assemble date + time
+	}
+
+	var tokens = [];
+	var re = _processPattern(pattern, dojo.hitch(this, _buildDateTimeRE, tokens, bundle, options));
+	return {regexp: re, tokens: tokens, bundle: bundle};
+};
+
+dojo.date.locale.parse = function(/*String*/value, /*dojo.date.locale.__FormatOptions?*/options){
+	// summary:
+	//		Convert a properly formatted string to a primitive Date object,
+	//		using locale-specific settings.
+	//
+	// description:
+	//		Create a Date object from a string using a known localized pattern.
+	//		By default, this method parses looking for both date and time in the string.
+	//		Formatting patterns are chosen appropriate to the locale.  Different
+	//		formatting lengths may be chosen, with "full" used by default.
+	//		Custom patterns may be used or registered with translations using
+	//		the dojo.date.locale.addCustomFormats method.
+	//	
+	//		Formatting patterns are implemented using [the syntax described at
+	//		unicode.org](http://www.unicode.org/reports/tr35/tr35-4.html#Date_Format_Patterns)
+	//		When two digit years are used, a century is chosen according to a sliding 
+	//		window of 80 years before and 20 years after present year, for both `yy` and `yyyy` patterns.
+	//		year < 100CE requires strict mode.
+	//
+	// value:
+	//		A string representation of a date
+
+	var info = dojo.date.locale._parseInfo(options);
+	var tokens = info.tokens, bundle = info.bundle;
+	var re = new RegExp("^" + info.regexp + "$", info.strict ? "" : "i");
+	var match = re.exec(value);
+	if(!match){ return null; } // null
+
+	var widthList = ['abbr', 'wide', 'narrow'];
+	var result = [1970,0,1,0,0,0,0]; // will get converted to a Date at the end
+	var amPm = "";
+	var valid = dojo.every(match, function(v, i){
+		if(!i){return true;}
+		var token=tokens[i-1];
+		var l=token.length;
+		switch(token.charAt(0)){
+			case 'y':
+				if(l != 2 && options.strict){
+					//interpret year literally, so '5' would be 5 A.D.
+					result[0] = v;
+				}else{
+					if(v<100){
+						v = Number(v);
+						//choose century to apply, according to a sliding window
+						//of 80 years before and 20 years after present year
+						var year = '' + new Date().getFullYear();
+						var century = year.substring(0, 2) * 100;
+						var cutoff = Math.min(Number(year.substring(2, 4)) + 20, 99);
+						var num = (v < cutoff) ? century + v : century - 100 + v;
+						result[0] = num;
+					}else{
+						//we expected 2 digits and got more...
+						if(options.strict){
+							return false;
+						}
+						//interpret literally, so '150' would be 150 A.D.
+						//also tolerate '1950', if 'yyyy' input passed to 'yy' format
+						result[0] = v;
+					}
+				}
+				break;
+			case 'M':
+				if(l>2){
+					var months = bundle['months-format-' + widthList[l-3]].concat();
+					if(!options.strict){
+						//Tolerate abbreviating period in month part
+						//Case-insensitive comparison
+						v = v.replace(".","").toLowerCase();
+						months = dojo.map(months, function(s){ return s.replace(".","").toLowerCase(); } );
+					}
+					v = dojo.indexOf(months, v);
+					if(v == -1){
+//						
+						return false;
+					}
+				}else{
+					v--;
+				}
+				result[1] = v;
+				break;
+			case 'E':
+			case 'e':
+				var days = bundle['days-format-' + widthList[l-3]].concat();
+				if(!options.strict){
+					//Case-insensitive comparison
+					v = v.toLowerCase();
+					days = dojo.map(days, function(d){return d.toLowerCase();});
+				}
+				v = dojo.indexOf(days, v);
+				if(v == -1){
+//					
+					return false;
+				}
+
+				//TODO: not sure what to actually do with this input,
+				//in terms of setting something on the Date obj...?
+				//without more context, can't affect the actual date
+				//TODO: just validate?
+				break;
+			case 'D':
+				result[1] = 0;
+				// fallthrough...
+			case 'd':
+				result[2] = v;
+				break;
+			case 'a': //am/pm
+				var am = options.am || bundle.am;
+				var pm = options.pm || bundle.pm;
+				if(!options.strict){
+					var period = /\./g;
+					v = v.replace(period,'').toLowerCase();
+					am = am.replace(period,'').toLowerCase();
+					pm = pm.replace(period,'').toLowerCase();
+				}
+				if(options.strict && v != am && v != pm){
+//					
+					return false;
+				}
+
+				// we might not have seen the hours field yet, so store the state and apply hour change later
+				amPm = (v == pm) ? 'p' : (v == am) ? 'a' : '';
+				break;
+			case 'K': //hour (1-24)
+				if(v == 24){ v = 0; }
+				// fallthrough...
+			case 'h': //hour (1-12)
+			case 'H': //hour (0-23)
+			case 'k': //hour (0-11)
+				//TODO: strict bounds checking, padding
+				if(v > 23){
+//					
+					return false;
+				}
+
+				//in the 12-hour case, adjusting for am/pm requires the 'a' part
+				//which could come before or after the hour, so we will adjust later
+				result[3] = v;
+				break;
+			case 'm': //minutes
+				result[4] = v;
+				break;
+			case 's': //seconds
+				result[5] = v;
+				break;
+			case 'S': //milliseconds
+				result[6] = v;
+//				break;
+//			case 'w':
+//TODO				var firstDay = 0;
+//			default:
+//TODO: throw?
+//				
+		}
+		return true;
+	});
+
+	var hours = +result[3];
+	if(amPm === 'p' && hours < 12){
+		result[3] = hours + 12; //e.g., 3pm -> 15
+	}else if(amPm === 'a' && hours == 12){
+		result[3] = 0; //12am -> 0
+	}
+
+	//TODO: implement a getWeekday() method in order to test 
+	//validity of input strings containing 'EEE' or 'EEEE'...
+
+	var dateObject = new Date(result[0], result[1], result[2], result[3], result[4], result[5], result[6]); // Date
+	if(options.strict){
+		dateObject.setFullYear(result[0]);
+	}
+
+	// Check for overflow.  The Date() constructor normalizes things like April 32nd...
+	//TODO: why isn't this done for times as well?
+	var allTokens = tokens.join(""),
+		dateToken = allTokens.indexOf('d') != -1,
+		monthToken = allTokens.indexOf('M') != -1;
+
+	if(!valid ||
+		(monthToken && dateObject.getMonth() > result[1]) ||
+		(dateToken && dateObject.getDate() > result[2])){
+		return null;
+	}
+
+	// Check for underflow, due to DST shifts.  See #9366
+	// This assumes a 1 hour dst shift correction at midnight
+	// We could compare the timezone offset after the shift and add the difference instead.
+	if((monthToken && dateObject.getMonth() < result[1]) ||
+		(dateToken && dateObject.getDate() < result[2])){
+		dateObject = dojo.date.add(dateObject, "hour", 1);
+	}
+
+	return dateObject; // Date
+};
+
+function _processPattern(pattern, applyPattern, applyLiteral, applyAll){
+	//summary: Process a pattern with literals in it
+
+	// Break up on single quotes, treat every other one as a literal, except '' which becomes '
+	var identity = function(x){return x;};
+	applyPattern = applyPattern || identity;
+	applyLiteral = applyLiteral || identity;
+	applyAll = applyAll || identity;
+
+	//split on single quotes (which escape literals in date format strings) 
+	//but preserve escaped single quotes (e.g., o''clock)
+	var chunks = pattern.match(/(''|[^'])+/g); 
+	var literal = pattern.charAt(0) == "'";
+
+	dojo.forEach(chunks, function(chunk, i){
+		if(!chunk){
+			chunks[i]='';
+		}else{
+			chunks[i]=(literal ? applyLiteral : applyPattern)(chunk);
+			literal = !literal;
+		}
+	});
+	return applyAll(chunks.join(''));
+}
+
+function _buildDateTimeRE(tokens, bundle, options, pattern){
+	pattern = dojo.regexp.escapeString(pattern);
+	if(!options.strict){ pattern = pattern.replace(" a", " ?a"); } // kludge to tolerate no space before am/pm
+	return pattern.replace(/([a-z])\1*/ig, function(match){
+		// Build a simple regexp.  Avoid captures, which would ruin the tokens list
+		var s;
+		var c = match.charAt(0);
+		var l = match.length;
+		var p2 = '', p3 = '';
+		if(options.strict){
+			if(l > 1){ p2 = '0' + '{'+(l-1)+'}'; }
+			if(l > 2){ p3 = '0' + '{'+(l-2)+'}'; }
+		}else{
+			p2 = '0?'; p3 = '0{0,2}';
+		}
+		switch(c){
+			case 'y':
+				s = '\\d{2,4}';
+				break;
+			case 'M':
+				s = (l>2) ? '\\S+?' : p2+'[1-9]|1[0-2]';
+				break;
+			case 'D':
+				s = p2+'[1-9]|'+p3+'[1-9][0-9]|[12][0-9][0-9]|3[0-5][0-9]|36[0-6]';
+				break;
+			case 'd':
+				s = '[12]\\d|'+p2+'[1-9]|3[01]';
+				break;
+			case 'w':
+				s = p2+'[1-9]|[1-4][0-9]|5[0-3]';
+				break;
+		    case 'E':
+				s = '\\S+';
+				break;
+			case 'h': //hour (1-12)
+				s = p2+'[1-9]|1[0-2]';
+				break;
+			case 'k': //hour (0-11)
+				s = p2+'\\d|1[01]';
+				break;
+			case 'H': //hour (0-23)
+				s = p2+'\\d|1\\d|2[0-3]';
+				break;
+			case 'K': //hour (1-24)
+				s = p2+'[1-9]|1\\d|2[0-4]';
+				break;
+			case 'm':
+			case 's':
+				s = '[0-5]\\d';
+				break;
+			case 'S':
+				s = '\\d{'+l+'}';
+				break;
+			case 'a':
+				var am = options.am || bundle.am || 'AM';
+				var pm = options.pm || bundle.pm || 'PM';
+				if(options.strict){
+					s = am + '|' + pm;
+				}else{
+					s = am + '|' + pm;
+					if(am != am.toLowerCase()){ s += '|' + am.toLowerCase(); }
+					if(pm != pm.toLowerCase()){ s += '|' + pm.toLowerCase(); }
+					if(s.indexOf('.') != -1){ s += '|' + s.replace(/\./g, ""); }
+				}
+				s = s.replace(/\./g, "\\.");
+				break;
+			default:
+			// case 'v':
+			// case 'z':
+			// case 'Z':
+				s = ".*";
+//				
+		}
+
+		if(tokens){ tokens.push(match); }
+
+		return "(" + s + ")"; // add capture
+	}).replace(/[\xa0 ]/g, "[\\s\\xa0]"); // normalize whitespace.  Need explicit handling of \xa0 for IE.
+}
+})();
+
+(function(){
+var _customFormats = [];
+dojo.date.locale.addCustomFormats = function(/*String*/packageName, /*String*/bundleName){
+	// summary:
+	//		Add a reference to a bundle containing localized custom formats to be
+	//		used by date/time formatting and parsing routines.
+	//
+	// description:
+	//		The user may add custom localized formats where the bundle has properties following the
+	//		same naming convention used by dojo.cldr: `dateFormat-xxxx` / `timeFormat-xxxx`
+	//		The pattern string should match the format used by the CLDR.
+	//		See dojo.date.locale.format() for details.
+	//		The resources must be loaded by dojo.requireLocalization() prior to use
+
+	_customFormats.push({pkg:packageName,name:bundleName});
+};
+
+dojo.date.locale._getGregorianBundle = function(/*String*/locale){
+	var gregorian = {};
+	dojo.forEach(_customFormats, function(desc){
+		var bundle = dojo.i18n.getLocalization(desc.pkg, desc.name, locale);
+		gregorian = dojo.mixin(gregorian, bundle);
+	}, this);
+	return gregorian; /*Object*/
+};
+})();
+
+dojo.date.locale.addCustomFormats("dojo.cldr","gregorian");
+
+dojo.date.locale.getNames = function(/*String*/item, /*String*/type, /*String?*/context, /*String?*/locale){
+	// summary:
+	//		Used to get localized strings from dojo.cldr for day or month names.
+	//
+	// item:
+	//	'months' || 'days'
+	// type:
+	//	'wide' || 'narrow' || 'abbr' (e.g. "Monday", "Mon", or "M" respectively, in English)
+	// context:
+	//	'standAlone' || 'format' (default)
+	// locale:
+	//	override locale used to find the names
+
+	var label;
+	var lookup = dojo.date.locale._getGregorianBundle(locale);
+	var props = [item, context, type];
+	if(context == 'standAlone'){
+		var key = props.join('-');
+		label = lookup[key];
+		// Fall back to 'format' flavor of name
+		if(label[0] == 1){ label = undefined; } // kludge, in the absense of real aliasing support in dojo.cldr
+	}
+	props[1] = 'format';
+
+	// return by copy so changes won't be made accidentally to the in-memory model
+	return (label || lookup[props.join('-')]).concat(); /*Array*/
+};
+
+dojo.date.locale.isWeekend = function(/*Date?*/dateObject, /*String?*/locale){
+	// summary:
+	//	Determines if the date falls on a weekend, according to local custom.
+
+	var weekend = dojo.cldr.supplemental.getWeekend(locale);
+	var day = (dateObject || new Date()).getDay();
+	if(weekend.end < weekend.start){
+		weekend.end += 7;
+		if(day < weekend.start){ day += 7; }
+	}
+	return day >= weekend.start && day <= weekend.end; // Boolean
+};
+
+// These are used only by format and strftime.  Do they need to be public?  Which module should they go in?
+
+dojo.date.locale._getDayOfYear = function(/*Date*/dateObject){
+	// summary: gets the day of the year as represented by dateObject
+	return dojo.date.difference(new Date(dateObject.getFullYear(), 0, 1, dateObject.getHours()), dateObject) + 1; // Number
+};
+
+dojo.date.locale._getWeekOfYear = function(/*Date*/dateObject, /*Number*/firstDayOfWeek){
+	if(arguments.length == 1){ firstDayOfWeek = 0; } // Sunday
+
+	var firstDayOfYear = new Date(dateObject.getFullYear(), 0, 1).getDay();
+	var adj = (firstDayOfYear - firstDayOfWeek + 7) % 7;
+	var week = Math.floor((dojo.date.locale._getDayOfYear(dateObject) + adj - 1) / 7);
+
+	// if year starts on the specified day, start counting weeks at 1
+	if(firstDayOfYear == firstDayOfWeek){ week++; }
+
+	return week; // Number
+};
+
+}
+
+if(!dojo._hasResource["dijit._Calendar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._Calendar"] = true;
+dojo.provide("dijit._Calendar");
+
+
+
+
+
+
+
+
+dojo.declare(
+	"dijit._Calendar",
+	[dijit._Widget, dijit._Templated],
+	{
+	// summary:
+	//		A simple GUI for choosing a date in the context of a monthly calendar.
+	//
+	// description:
+	//		A simple GUI for choosing a date in the context of a monthly calendar.
+	//		This widget is used internally by other widgets and is not accessible
+	//		as a standalone widget.
+	//		This widget can't be used in a form because it doesn't serialize the date to an
+	//		`<input>` field.  For a form element, use dijit.form.DateTextBox instead.
+	//
+	//		Note that the parser takes all dates attributes passed in the
+	//		[RFC 3339 format](http://www.faqs.org/rfcs/rfc3339.html), e.g. `2005-06-30T08:05:00-07:00`
+	//		so that they are serializable and locale-independent.
+	//
+	// example:
+	//	|	var calendar = new dijit._Calendar({}, dojo.byId("calendarNode"));
+	//
+	//	example:
+	//	|	<div dojoType="dijit._Calendar"></div>
+
+		templateString:"<table cellspacing=\"0\" cellpadding=\"0\" class=\"dijitCalendarContainer\">\n\t<thead>\n\t\t<tr class=\"dijitReset dijitCalendarMonthContainer\" valign=\"top\">\n\t\t\t<th class='dijitReset' dojoAttachPoint=\"decrementMonth\">\n\t\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitCalendarIncrementControl dijitCalendarDecrease\" waiRole=\"presentation\">\n\t\t\t\t<span dojoAttachPoint=\"decreaseArrowNode\" class=\"dijitA11ySideArrow\">-</span>\n\t\t\t</th>\n\t\t\t<th [...]
+
+		// value: Date
+		//		The currently selected Date
+		value: new Date(),
+
+		// dayWidth: String
+		//		How to represent the days of the week in the calendar header. See dojo.date.locale
+		dayWidth: "narrow",
+
+		setValue: function(/*Date*/ value){
+			// summary:
+			//      Deprecated.   Used attr('value', ...) instead.
+			// tags:
+			//      deprecated
+			dojo.deprecated("dijit.Calendar:setValue() is deprecated.  Use attr('value', ...) instead.", "", "2.0");
+			this.attr('value', value);
+		},
+
+		_getValueAttr: function(/*String*/ value){
+			// summary:
+			//		Hook so attr('value') works.
+			var value = new Date(this.value);
+			value.setHours(0, 0, 0, 0); // return midnight, local time for back-compat
+
+			// If daylight savings pushes midnight to the previous date, fix the Date
+			// object to point at 1am so it will represent the correct day. See #9366
+			if(value.getDate() < this.value.getDate()){
+				value = dojo.date.add(value, "hour", 1);
+			}
+			return value;
+		},
+
+		_setValueAttr: function(/*Date*/ value){
+			// summary:
+			//		Hook to make attr("value", ...) work.
+			// description:
+			// 		Set the current date and update the UI.  If the date is disabled, the selection will
+			//		not change, but the display will change to the corresponding month.
+			// tags:
+			//      protected
+			if(!this.value || dojo.date.compare(value, this.value)){
+				value = new Date(value);
+				value.setHours(1); // to avoid issues when DST shift occurs at midnight, see #8521, #9366
+				this.displayMonth = new Date(value);
+				if(!this.isDisabledDate(value, this.lang)){
+					this.value = value;
+					this.onChange(this.attr('value'));
+				}
+				this._populateGrid();
+			}
+		},
+
+		_setText: function(node, text){
+			// summary:
+			//		This just sets the content of node to the specified text.
+			//		Can't do "node.innerHTML=text" because of an IE bug w/tables, see #3434.
+			// tags:
+			//      private
+			while(node.firstChild){
+				node.removeChild(node.firstChild);
+			}
+			node.appendChild(dojo.doc.createTextNode(text));
+		},
+
+		_populateGrid: function(){
+			// summary:
+			//      Fills in the calendar grid with each day (1-31)
+			// tags:
+			//      private
+			var month = this.displayMonth;
+			month.setDate(1);
+			var firstDay = month.getDay();
+			var daysInMonth = dojo.date.getDaysInMonth(month);
+			var daysInPreviousMonth = dojo.date.getDaysInMonth(dojo.date.add(month, "month", -1));
+			var today = new Date();
+			var selected = this.value;
+
+			var dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
+			if(dayOffset > firstDay){ dayOffset -= 7; }
+
+			// Iterate through dates in the calendar and fill in date numbers and style info
+			dojo.query(".dijitCalendarDateTemplate", this.domNode).forEach(function(template, i){
+				i += dayOffset;
+				var date = new Date(month);
+				var number, clazz = "dijitCalendar", adj = 0;
+
+				if(i < firstDay){
+					number = daysInPreviousMonth - firstDay + i + 1;
+					adj = -1;
+					clazz += "Previous";
+				}else if(i >= (firstDay + daysInMonth)){
+					number = i - firstDay - daysInMonth + 1;
+					adj = 1;
+					clazz += "Next";
+				}else{
+					number = i - firstDay + 1;
+					clazz += "Current";
+				}
+
+				if(adj){
+					date = dojo.date.add(date, "month", adj);
+				}
+				date.setDate(number);
+
+				if(!dojo.date.compare(date, today, "date")){
+					clazz = "dijitCalendarCurrentDate " + clazz;
+				}
+
+				if(!dojo.date.compare(date, selected, "date")){
+					clazz = "dijitCalendarSelectedDate " + clazz;
+				}
+
+				if(this.isDisabledDate(date, this.lang)){
+					clazz = "dijitCalendarDisabledDate " + clazz;
+				}
+
+				var clazz2 = this.getClassForDate(date, this.lang);
+				if(clazz2){
+					clazz = clazz2 + " " + clazz;
+				}
+
+				template.className =  clazz + "Month dijitCalendarDateTemplate";
+				template.dijitDateValue = date.valueOf();
+				var label = dojo.query(".dijitCalendarDateLabel", template)[0];
+				this._setText(label, date.getDate());
+			}, this);
+
+			// Fill in localized month name
+			var monthNames = dojo.date.locale.getNames('months', 'wide', 'standAlone', this.lang);
+			this._setText(this.monthLabelNode, monthNames[month.getMonth()]);
+
+			// Fill in localized prev/current/next years
+			var y = month.getFullYear() - 1;
+			var d = new Date();
+			dojo.forEach(["previous", "current", "next"], function(name){
+				d.setFullYear(y++);
+				this._setText(this[name+"YearLabelNode"],
+					dojo.date.locale.format(d, {selector:'year', locale:this.lang}));
+			}, this);
+
+			// Set up repeating mouse behavior
+			var _this = this;
+			var typematic = function(nodeProp, dateProp, adj){
+				_this._connects.push(
+					dijit.typematic.addMouseListener(_this[nodeProp], _this, function(count){
+						if(count >= 0){ _this._adjustDisplay(dateProp, adj); }
+					}, 0.8, 500)
+				);
+			};
+			typematic("incrementMonth", "month", 1);
+			typematic("decrementMonth", "month", -1);
+			typematic("nextYearLabelNode", "year", 1);
+			typematic("previousYearLabelNode", "year", -1);
+		},
+
+		goToToday: function(){
+			// summary:
+			//      Sets calendar's value to today's date
+			this.attr('value', new Date());
+		},
+
+		postCreate: function(){
+			this.inherited(arguments);
+			dojo.setSelectable(this.domNode, false);
+
+			var cloneClass = dojo.hitch(this, function(clazz, n){
+				var template = dojo.query(clazz, this.domNode)[0];
+	 			for(var i=0; i<n; i++){
+					template.parentNode.appendChild(template.cloneNode(true));
+				}
+			});
+
+			// clone the day label and calendar day templates 6 times to make 7 columns
+			cloneClass(".dijitCalendarDayLabelTemplate", 6);
+			cloneClass(".dijitCalendarDateTemplate", 6);
+
+			// now make 6 week rows
+			cloneClass(".dijitCalendarWeekTemplate", 5);
+
+			// insert localized day names in the header
+			var dayNames = dojo.date.locale.getNames('days', this.dayWidth, 'standAlone', this.lang);
+			var dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
+			dojo.query(".dijitCalendarDayLabel", this.domNode).forEach(function(label, i){
+				this._setText(label, dayNames[(i + dayOffset) % 7]);
+			}, this);
+
+			// Fill in spacer element with all the month names (invisible) so that the maximum width will affect layout
+			var monthNames = dojo.date.locale.getNames('months', 'wide', 'standAlone', this.lang);
+			dojo.forEach(monthNames, function(name){
+				var monthSpacer = dojo.create("div", null, this.monthLabelSpacer);
+				this._setText(monthSpacer, name);
+			}, this);
+
+			this.value = null;
+			this.attr('value', new Date());
+		},
+
+		_adjustDisplay: function(/*String*/ part, /*int*/ amount){
+			// summary:
+			//      Moves calendar forwards or backwards by months or years
+			// part:
+			//      "month" or "year"
+			// amount:
+			//      Number of months or years
+			// tags:
+			//      private
+			this.displayMonth = dojo.date.add(this.displayMonth, part, amount);
+			this._populateGrid();
+		},
+
+		_onDayClick: function(/*Event*/ evt){
+			// summary:
+			//      Handler for when user clicks a day
+			// tags:
+			//      protected
+			dojo.stopEvent(evt);
+			for(var node = evt.target; node && !node.dijitDateValue; node = node.parentNode);
+			if(node && !dojo.hasClass(node, "dijitCalendarDisabledDate")){
+				this.attr('value', node.dijitDateValue);
+				this.onValueSelected(this.attr('value'));
+			}
+		},
+
+		_onDayMouseOver: function(/*Event*/ evt){
+			// summary:
+			//      Handler for when user clicks a day
+			// tags:
+			//      protected
+			var node = evt.target;
+			if(node && (node.dijitDateValue || node == this.previousYearLabelNode || node == this.nextYearLabelNode) ){
+				dojo.addClass(node, "dijitCalendarHoveredDate");
+				this._currentNode = node;
+			}
+		},
+
+		_onDayMouseOut: function(/*Event*/ evt){
+			// summary:
+			//      Handler for when user clicks a day
+			// tags:
+			//      protected
+			if(!this._currentNode){ return; }
+			for(var node = evt.relatedTarget; node;){
+				if(node == this._currentNode){ return; }
+				try{
+					node = node.parentNode;
+				}catch(x){
+					node = null;
+				}
+			}
+			dojo.removeClass(this._currentNode, "dijitCalendarHoveredDate");
+			this._currentNode = null;
+		},
+
+		onValueSelected: function(/*Date*/ date){
+			// summary:
+			//		Notification that a date cell was selected.  It may be the same as the previous value.
+			// description:
+			//      Used by `dijit.form._DateTimeTextBox` (and thus `dijit.form.DateTextBox`)
+			//      to get notification when the user has clicked a date.
+			// tags:
+			//      protected
+		},
+
+		onChange: function(/*Date*/ date){
+			// summary:
+			//		Called only when the selected date has changed
+		},
+
+		isDisabledDate: function(/*Date*/ dateObject, /*String?*/ locale){
+			// summary:
+			//		May be overridden to disable certain dates in the calendar e.g. `isDisabledDate=dojo.date.locale.isWeekend`
+			// tags:
+			//      extension
+/*=====
+			return false; // Boolean
+=====*/
+		},
+
+		getClassForDate: function(/*Date*/ dateObject, /*String?*/ locale){
+			// summary:
+			//		May be overridden to return CSS classes to associate with the date entry for the given dateObject,
+			//		for example to indicate a holiday in specified locale.
+			// tags:
+			//      extension
+
+/*=====
+			return ""; // String
+=====*/
+		}
+	}
+);
+
+}
+
+if(!dojo._hasResource["dijit.form._DateTimeTextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form._DateTimeTextBox"] = true;
+dojo.provide("dijit.form._DateTimeTextBox");
+
+
+
+
+
+
+/*=====
+dojo.declare(
+	"dijit.form._DateTimeTextBox.__Constraints",
+	[dijit.form.RangeBoundTextBox.__Constraints, dojo.date.locale.__FormatOptions]
+);
+=====*/
+
+dojo.declare(
+	"dijit.form._DateTimeTextBox",
+	dijit.form.RangeBoundTextBox,
+	{
+		// summary:
+		//		Base class for validating, serializable, range-bound date or time text box.
+
+		/*=====
+		// constraints: dijit.form._DateTimeTextBox.__Constraints
+		//		Starting / ending dates or times allowed
+		constraints: {},
+		======*/
+
+		// Override ValidationTextBox.regExpGen().... we use a reg-ex generating function rather
+		// than a straight regexp to deal with locale  (plus formatting options too?)
+		regExpGen: dojo.date.locale.regexp,
+
+		// Override _FormWidget.compare() to work for dates/times
+		compare: dojo.date.compare,
+
+		format: function(/*Date*/ value, /*dojo.date.locale.__FormatOptions*/ constraints){
+			// summary:
+			//		Formats the value as a Date, according to specified locale (second argument)
+			// tags:
+			//		protected
+			if(!value){ return ''; }
+			return dojo.date.locale.format(value, constraints);
+		},
+
+		parse: function(/*String*/ value, /*dojo.date.locale.__FormatOptions*/ constraints){
+			// summary:
+			//		Parses as string as a Date, according to constraints
+			// tags:
+			//		protected
+
+			return dojo.date.locale.parse(value, constraints) || (this._isEmpty(value)? null : undefined);	 // Date
+		},
+
+		// Overrides ValidationTextBox.serialize() to serialize a date in canonical ISO format.
+		serialize: dojo.date.stamp.toISOString,
+
+		//	value: Date
+		//		The value of this widget as a JavaScript Date object.  Use attr("value") / attr("value", val) to manipulate.
+		//		When passed to the parser in markup, must be specified according to `dojo.date.stamp.fromISOString`
+		value: new Date(""),	// value.toString()="NaN"
+		_blankValue: null,    // used by filter() when the textbox is blank
+
+		//	popupClass: [protected extension] String
+		//		Name of the popup widget class used to select a date/time.
+		//		Subclasses should specify this.
+		popupClass: "", // default is no popup = text only
+
+
+		// _selector: [protected extension] String
+		//		Specifies constraints.selector passed to dojo.date functions, should be either
+		//		"date" or "time".
+		//		Subclass must specify this.
+		_selector: "",
+
+		postMixInProperties: function(){
+			//dijit.form.RangeBoundTextBox.prototype.postMixInProperties.apply(this, arguments);
+			this.inherited(arguments);
+			if(!this.value || this.value.toString() == dijit.form._DateTimeTextBox.prototype.value.toString()){
+				this.value = null;
+			}
+			var constraints = this.constraints;
+			constraints.selector = this._selector;
+			constraints.fullYear = true; // see #5465 - always format with 4-digit years
+			var fromISO = dojo.date.stamp.fromISOString;
+			if(typeof constraints.min == "string"){ constraints.min = fromISO(constraints.min); }
+ 			if(typeof constraints.max == "string"){ constraints.max = fromISO(constraints.max); }
+		},
+		
+		_onFocus: function(/*Event*/ evt){
+			// summary:
+			//		open the TimePicker popup
+			this._open();
+		},
+
+		_setValueAttr: function(/*Date*/ value, /*Boolean?*/ priorityChange, /*String?*/ formattedValue){
+			// summary:
+			//		Sets the date on this textbox.  Note that `value` must be a Javascript Date object.
+			this.inherited(arguments);
+			if(this._picker){
+				// #3948: fix blank date on popup only
+				if(!value){value=new Date();}
+				this._picker.attr('value', value);
+			}
+		},
+
+		_open: function(){
+			// summary:
+			//		opens the TimePicker, and sets the onValueSelected value
+
+			if(this.disabled || this.readOnly || !this.popupClass){return;}
+
+			var textBox = this;
+
+			if(!this._picker){
+				var PopupProto=dojo.getObject(this.popupClass, false);
+				this._picker = new PopupProto({
+					onValueSelected: function(value){
+						if(textBox._tabbingAway){
+							delete textBox._tabbingAway;
+						}else{
+							textBox.focus(); // focus the textbox before the popup closes to avoid reopening the popup
+						}
+						setTimeout(dojo.hitch(textBox, "_close"), 1); // allow focus time to take
+
+						// this will cause InlineEditBox and other handlers to do stuff so make sure it's last
+						dijit.form._DateTimeTextBox.superclass._setValueAttr.call(textBox, value, true);
+					},
+					lang: textBox.lang,
+					constraints: textBox.constraints,
+					isDisabledDate: function(/*Date*/ date){
+						// summary:
+						// 	disables dates outside of the min/max of the _DateTimeTextBox
+						var compare = dojo.date.compare;
+						var constraints = textBox.constraints;
+						return constraints && (constraints.min && (compare(constraints.min, date, "date") > 0) || 
+							(constraints.max && compare(constraints.max, date, "date") < 0));
+					}
+				});
+				this._picker.attr('value', this.attr('value') || new Date());
+			}
+			if(!this._opened){
+				dijit.popup.open({
+					parent: this,
+					popup: this._picker,
+					around: this.domNode,
+					onCancel: dojo.hitch(this, this._close),
+					onClose: function(){ textBox._opened=false; }
+				});
+				this._opened=true;
+			}
+			
+			dojo.marginBox(this._picker.domNode,{ w:this.domNode.offsetWidth });
+		},
+
+		_close: function(){
+			if(this._opened){
+				dijit.popup.close(this._picker);
+				this._opened=false;
+			}			
+		},
+
+		_onBlur: function(){
+			// summary:
+			//		Called magically when focus has shifted away from this widget and it's dropdown
+			this._close();
+			if(this._picker){
+				// teardown so that constraints will be rebuilt next time (redundant reference: #6002)
+				this._picker.destroy();
+				delete this._picker;
+			}
+			this.inherited(arguments);
+			// don't focus on <input>.  the user has explicitly focused on something else.
+		},
+
+		_getDisplayedValueAttr: function(){
+			return this.textbox.value;
+		},
+
+		_setDisplayedValueAttr: function(/*String*/ value, /*Boolean?*/ priorityChange){
+			this._setValueAttr(this.parse(value, this.constraints), priorityChange, value);
+		},
+
+		destroy: function(){
+			if(this._picker){
+				this._picker.destroy();
+				delete this._picker;
+			}
+			this.inherited(arguments);
+		},
+
+		postCreate: function(){
+			this.inherited(arguments);
+			this.connect(this.focusNode, 'onkeypress', this._onKeyPress);
+		},
+
+		_onKeyPress: function(/*Event*/ e){
+			// summary:
+			//		Handler for keypress events
+
+			var p = this._picker, dk = dojo.keys;
+			// Handle the key in the picker, if it has a handler.  If the handler
+			// returns false, then don't handle any other keys.
+			if(p && this._opened && p.handleKey){
+				if(p.handleKey(e) === false){ return; }
+			}
+			if(this._opened && e.charOrCode == dk.ESCAPE && !e.shiftKey && !e.ctrlKey && !e.altKey){
+				this._close();
+				dojo.stopEvent(e);
+			}else if(!this._opened && e.charOrCode == dk.DOWN_ARROW){
+				this._open();
+				dojo.stopEvent(e);
+			}else if(e.charOrCode === dk.TAB){
+				this._tabbingAway = true;
+			}else if(this._opened && (e.keyChar || e.charOrCode === dk.BACKSPACE || e.charOrCode == dk.DELETE)){
+				// Replace the element - but do it after a delay to allow for 
+				// filtering to occur
+				setTimeout(dojo.hitch(this, function(){
+					dijit.placeOnScreenAroundElement(p.domNode.parentNode, this.domNode, {'BL':'TL', 'TL':'BL'}, p.orient ? dojo.hitch(p, "orient") : null);
+				}), 1);
+			}
+		}
+	}
+);
+
+}
+
+if(!dojo._hasResource["dijit.form.DateTextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.DateTextBox"] = true;
+dojo.provide("dijit.form.DateTextBox");
+
+
+
+
+dojo.declare(
+	"dijit.form.DateTextBox",
+	dijit.form._DateTimeTextBox,
+	{
+		// summary:
+		//		A validating, serializable, range-bound date text box with a drop down calendar
+
+		baseClass: "dijitTextBox dijitDateTextBox",
+		popupClass: "dijit._Calendar",
+		_selector: "date",
+
+		//	value: Date
+		//		The value of this widget as a JavaScript Date object, with only year/month/day specified.
+		//
+		//		Example:
+		// |	new dijit.form.DateTextBox({value: new Date(2009,1,20)})
+		//
+		//		When passed to the parser in markup, must be specified according to locale-independent
+		//		`dojo.date.stamp.fromISOString` format.
+		//
+		//		Example:
+		// |	<input dojotype='dijit.form.DateTextBox' value='2009-01-20'>
+		value: new Date("")	// value.toString()="NaN"
+
+	}
+);
+
+}
+
+if(!dojo._hasResource["dijit.form.FilteringSelect"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.FilteringSelect"] = true;
+dojo.provide("dijit.form.FilteringSelect");
+
+
+
+dojo.declare(
+	"dijit.form.FilteringSelect",
+	[dijit.form.MappedTextBox, dijit.form.ComboBoxMixin],
+	{
+		// summary:
+		//		An enhanced version of the HTML SELECT tag, populated dynamically
+		//
+		// description:
+		//		An enhanced version of the HTML SELECT tag, populated dynamically. It works
+		//		very nicely with very large data sets because it can load and page data as needed.
+		//		It also resembles ComboBox, but does not allow values outside of the provided ones.
+		//		If OPTION tags are used as the data provider via markup, then the
+		//		OPTION tag's child text node is used as the displayed value when selected
+		//		while the OPTION tag's value attribute is used as the widget value on form submit.
+		//		To set the default value when using OPTION tags, specify the selected
+		//		attribute on 1 of the child OPTION tags.
+		//
+		//		Similar features:
+		//			- There is a drop down list of possible values.
+		//			- You can only enter a value from the drop down list.  (You can't
+		//				enter an arbitrary value.)
+		//			- The value submitted with the form is the hidden value (ex: CA),
+		//				not the displayed value a.k.a. label (ex: California)
+		// 
+		//		Enhancements over plain HTML version:
+		//			- If you type in some text then it will filter down the list of
+		//				possible values in the drop down list.
+		//			- List can be specified either as a static list or via a javascript
+		//				function (that can get the list from a server)
+
+		_isvalid: true,
+
+		// required: Boolean
+		//		True if user is required to enter a value into this field.
+		required: true,
+
+		_lastDisplayedValue: "",
+
+		isValid: function(){
+			// Overrides ValidationTextBox.isValid()
+			return this._isvalid || (!this.required && this.attr('displayedValue') == ""); // #5974
+		},
+
+		_callbackSetLabel: function(	/*Array*/ result, 
+						/*Object*/ dataObject, 
+						/*Boolean?*/ priorityChange){
+			// summary:
+			//		Callback function that dynamically sets the label of the
+			//		ComboBox
+
+			// setValue does a synchronous lookup,
+			// so it calls _callbackSetLabel directly,
+			// and so does not pass dataObject
+			// still need to test against _lastQuery in case it came too late
+			if((dataObject && dataObject.query[this.searchAttr] != this._lastQuery)||(!dataObject && result.length && this.store.getIdentity(result[0])!= this._lastQuery)){
+				return;
+			}
+			if(!result.length){
+				//#3268: do nothing on bad input
+				//this._setValue("", "");
+				//#3285: change CSS to indicate error
+				this.valueNode.value = "";
+				dijit.form.TextBox.superclass._setValueAttr.call(this, "", priorityChange || (priorityChange===undefined && !this._focused));
+				this._isvalid = false;
+				this.validate(this._focused);
+				this.item = null;
+			}else{
+				this._setValueFromItem(result[0], priorityChange);
+			}
+		},
+
+		_openResultList: function(/*Object*/ results, /*Object*/ dataObject){
+			// Overrides ComboBox._openResultList()
+
+			// #3285: tap into search callback to see if user's query resembles a match
+			if(dataObject.query[this.searchAttr] != this._lastQuery){
+				return;
+			}
+			this._isvalid = results.length != 0; // FIXME: should this be greater-than?
+			this.validate(true);
+			dijit.form.ComboBoxMixin.prototype._openResultList.apply(this, arguments);
+		},
+
+		_getValueAttr: function(){
+			// summary:
+			//		Hook for attr('value') to work.
+
+			// don't get the textbox value but rather the previously set hidden value
+			// TODO: seems suspicious that we need this; how is FilteringSelect different
+			// than another MappedTextBox widget?
+			return this.valueNode.value;
+		},
+
+		_getValueField: function(){
+			// Overrides ComboBox._getValueField()
+			return "value";
+		},
+
+		_setValue: function(	/*String*/ value, 
+					/*String*/ displayedValue,
+					/*Boolean?*/ priorityChange){
+			// summary:
+			//		Internal function for setting the displayed value and hidden value.
+			//		Differs from _setValueAttr() in that _setValueAttr() only takes a single
+			//		value argument, and has to look up the displayed value from that.
+			// tags:
+			//		private
+			this.valueNode.value = value;
+			dijit.form.FilteringSelect.superclass._setValueAttr.call(this, value, priorityChange, displayedValue);
+			this._lastDisplayedValue = displayedValue;
+		},
+
+		_setValueAttr: function(/*String*/ value, /*Boolean?*/ priorityChange){
+			// summary:
+			//		Hook so attr('value', value) works.
+			// description:
+			//		Sets the value of the select.
+			//		Also sets the label to the corresponding value by reverse lookup.
+			if(!this._onChangeActive){ priorityChange = null; }
+			this._lastQuery = value;
+
+			if(value === null || value === ''){
+				this._setDisplayedValueAttr('', priorityChange);
+				return;
+			}
+
+			//#3347: fetchItemByIdentity if no keyAttr specified
+			var self = this;
+			var handleFetchByIdentity = function(item, priorityChange){
+				if(item){
+					if(self.store.isItemLoaded(item)){
+						self._callbackSetLabel([item], undefined, priorityChange);
+					}else{
+						self.store.loadItem({
+							item: item, 
+							onItem: function(result, dataObject){
+								self._callbackSetLabel(result, dataObject, priorityChange);
+							}
+						});
+					}
+				}else{
+					self._isvalid = false;
+					// prevent errors from Tooltip not being created yet
+					self.validate(false);
+				}
+			};
+			this.store.fetchItemByIdentity({
+				identity: value, 
+				onItem: function(item){
+					handleFetchByIdentity(item, priorityChange);
+				}
+			});
+		},
+
+		_setValueFromItem: function(/*item*/ item, /*Boolean?*/ priorityChange){
+			//	summary:
+			//		Set the displayed valued in the input box, and the hidden value
+			//		that gets submitted, based on a dojo.data store item.
+			//	description:
+			//		Users shouldn't call this function; they should be calling
+			//		attr('displayedValue', value) or attr('value', ...) instead
+			// tags:
+			//		private
+			this._isvalid = true;
+			this.item = item; // Fix #6381
+			this._setValue(	this.store.getIdentity(item), 
+							this.labelFunc(item, this.store), 
+							priorityChange);
+		},
+
+		labelFunc: function(/*item*/ item, /*dojo.data.store*/ store){
+			// summary:
+			//		Computes the label to display based on the dojo.data store item.
+			// returns:
+			//		The label that the ComboBox should display
+			// tags:
+			//		private
+			return store.getValue(item, this.searchAttr);
+		},
+
+		_doSelect: function(/*Event*/ tgt){
+			// summary:
+			//		Overrides ComboBox._doSelect(), the method called when an item in the menu is selected.
+			//	description:
+			//		FilteringSelect overrides this to set both the visible and
+			//		hidden value from the information stored in the menu.
+			this._setValueFromItem(tgt.item, true);
+		},
+
+		_setDisplayedValueAttr: function(/*String*/ label, /*Boolean?*/ priorityChange){
+			// summary:
+			//		Hook so attr('displayedValue', label) works.
+			// description:
+			//		Sets textbox to display label. Also performs reverse lookup
+			//		to set the hidden value.
+
+			// When this is called during initialization it'll ping the datastore
+			// for reverse lookup, and when that completes (after an XHR request)
+			// will call setValueAttr()... but that shouldn't trigger an onChange()
+			// event, even when it happens after creation has finished
+			if(!this._created){
+				priorityChange = false;
+			}
+
+			if(this.store){
+				var query = dojo.clone(this.query); // #6196: populate query with user-specifics
+				// escape meta characters of dojo.data.util.filter.patternToRegExp().
+				this._lastQuery = query[this.searchAttr] = label.replace(/([\\\*\?])/g, "\\$1");
+				// if the label is not valid, the callback will never set it,
+				// so the last valid value will get the warning textbox set the
+				// textbox value now so that the impending warning will make
+				// sense to the user
+				this.textbox.value = label;
+				this._lastDisplayedValue = label;
+				var _this = this;
+				var fetch = {
+					query: query, 
+					queryOptions: {
+						ignoreCase: this.ignoreCase, 
+						deep: true
+					}, 
+					onComplete: function(result, dataObject){
+						        dojo.hitch(_this, "_callbackSetLabel")(result, dataObject, priorityChange);
+					},
+					onError: function(errText){
+						console.error('dijit.form.FilteringSelect: ' + errText);
+						dojo.hitch(_this, "_setValue")("", label, false);
+					}
+				};
+				dojo.mixin(fetch, this.fetchProperties);
+				this.store.fetch(fetch);
+			}
+		},
+
+		postMixInProperties: function(){
+			this.inherited(arguments);
+			this._isvalid = !this.required;
+		},
+
+		undo: function(){
+			this.attr('displayedValue', this._lastDisplayedValue);
+		}
+	}
+);
+
+}
+
+if(!dojo._hasResource["dijit.form._Spinner"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form._Spinner"] = true;
+dojo.provide("dijit.form._Spinner");
+
+
+
+dojo.declare(
+	"dijit.form._Spinner",
+	dijit.form.RangeBoundTextBox,
+	{
+		// summary:
+		//		Mixin for validation widgets with a spinner.
+		// description:
+		//		This class basically (conceptually) extends `dijit.form.ValidationTextBox`.
+		//		It modifies the template to have up/down arrows, and provides related handling code.
+
+		// defaultTimeout: Number
+		//		Number of milliseconds before a held arrow key or up/down button becomes typematic
+		defaultTimeout: 500,
+
+		// timeoutChangeRate: Number
+		//		Fraction of time used to change the typematic timer between events.
+		//		1.0 means that each typematic event fires at defaultTimeout intervals.
+		//		< 1.0 means that each typematic event fires at an increasing faster rate.
+		timeoutChangeRate: 0.90,
+
+		// smallDelta: Number
+		//	  Adjust the value by this much when spinning using the arrow keys/buttons
+		smallDelta: 1,
+
+		// largeDelta: Number
+		//	  Adjust the value by this much when spinning using the PgUp/Dn keys
+		largeDelta: 10,
+
+		templateString:"<div class=\"dijit dijitReset dijitInlineTable dijitLeft\"\n\tid=\"widget_${id}\"\n\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\" waiRole=\"presentation\"\n\t><div class=\"dijitInputLayoutContainer\"\n\t\t><div class=\"dijitReset dijitSpinnerButtonContainer\"\n\t\t\t> <div class=\"dijitReset dijitLeft dijitButtonNode dijitArrowButton dijitUpArrowButton\"\n\t\t\t\tdojoAttachPoint=\"upArrowNode\"\n\t\t\t\tdojoAttachEvent=\"onmo [...]
+		baseClass: "dijitSpinner",
+
+		adjust: function(/* Object */ val, /*Number*/ delta){
+			// summary:
+			//		Overridable function used to adjust a primitive value(Number/Date/...) by the delta amount specified.
+			// 		The val is adjusted in a way that makes sense to the object type.
+			// tags:
+			//		protected extension
+			return val;
+		},
+
+		_arrowState: function(/*Node*/ node, /*Boolean*/ pressed){
+			// summary:
+			//		Called when an arrow key is pressed to update the relevant CSS classes
+			this._active = pressed;
+			this.stateModifier = node.getAttribute("stateModifier") || "";
+			this._setStateClass();
+		},
+
+		_arrowPressed: function(/*Node*/ nodePressed, /*Number*/ direction, /*Number*/ increment){
+			// summary:
+			//		Handler for arrow button or arrow key being pressed
+			if(this.disabled || this.readOnly){ return; }
+			this._arrowState(nodePressed, true);
+			this._setValueAttr(this.adjust(this.attr('value'), direction*increment), false);
+			dijit.selectInputText(this.textbox, this.textbox.value.length);
+		},
+
+		_arrowReleased: function(/*Node*/ node){
+			// summary:
+			//		Handler for arrow button or arrow key being released
+			this._wheelTimer = null;
+			if(this.disabled || this.readOnly){ return; }
+			this._arrowState(node, false);
+		},
+
+		_typematicCallback: function(/*Number*/ count, /*DOMNode*/ node, /*Event*/ evt){
+			var inc=this.smallDelta;
+			if(node == this.textbox){
+				var k=dojo.keys;
+				var key = evt.charOrCode; 
+				inc = (key == k.PAGE_UP || key == k.PAGE_DOWN) ? this.largeDelta : this.smallDelta;
+				node = (key == k.UP_ARROW ||key == k.PAGE_UP) ? this.upArrowNode : this.downArrowNode;
+			}
+			if(count == -1){ this._arrowReleased(node); }
+			else{ this._arrowPressed(node, (node == this.upArrowNode) ? 1 : -1, inc); }
+		},
+
+		_wheelTimer: null,
+		_mouseWheeled: function(/*Event*/ evt){
+			// summary:
+			//		Mouse wheel listener where supported
+
+			dojo.stopEvent(evt);	
+			// FIXME: Safari bubbles
+
+			// be nice to DOH and scroll as much as the event says to
+			var scrollAmount = evt.detail ? (evt.detail * -1) : (evt.wheelDelta / 120);
+			if(scrollAmount !== 0){
+				var node = this[(scrollAmount > 0 ? "upArrowNode" : "downArrowNode" )];
+				
+				this._arrowPressed(node, scrollAmount, this.smallDelta);
+
+				if(!this._wheelTimer){
+					clearTimeout(this._wheelTimer);
+				}
+				this._wheelTimer = setTimeout(dojo.hitch(this,"_arrowReleased",node), 50);
+			}
+			
+		},
+
+		postCreate: function(){
+			this.inherited(arguments);
+
+			// extra listeners
+			this.connect(this.domNode, !dojo.isMozilla ? "onmousewheel" : 'DOMMouseScroll', "_mouseWheeled");
+			this._connects.push(dijit.typematic.addListener(this.upArrowNode, this.textbox, {charOrCode:dojo.keys.UP_ARROW,ctrlKey:false,altKey:false,shiftKey:false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout));
+			this._connects.push(dijit.typematic.addListener(this.downArrowNode, this.textbox, {charOrCode:dojo.keys.DOWN_ARROW,ctrlKey:false,altKey:false,shiftKey:false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout));
+			this._connects.push(dijit.typematic.addListener(this.upArrowNode, this.textbox, {charOrCode:dojo.keys.PAGE_UP,ctrlKey:false,altKey:false,shiftKey:false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout));
+			this._connects.push(dijit.typematic.addListener(this.downArrowNode, this.textbox, {charOrCode:dojo.keys.PAGE_DOWN,ctrlKey:false,altKey:false,shiftKey:false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout));
+			if(dojo.isIE){
+				var _this = this;
+				this.connect(this.domNode, "onresize",
+					function(){ setTimeout(dojo.hitch(_this,
+						function(){
+				        		var sz = this.upArrowNode.parentNode.offsetHeight;
+							if(sz){
+								this.upArrowNode.style.height = sz >> 1;
+								this.downArrowNode.style.height = sz - (sz >> 1);
+								this.focusNode.parentNode.style.height = sz;
+							}
+							// cause IE to rerender when spinner is moved from hidden to visible
+							this._setStateClass();
+						}), 0);
+					}
+				);
+			}
+		}
+});
+
+}
+
+if(!dojo._hasResource["dijit.form.NumberSpinner"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.NumberSpinner"] = true;
+dojo.provide("dijit.form.NumberSpinner");
+
+
+
+
+dojo.declare("dijit.form.NumberSpinner",
+	[dijit.form._Spinner, dijit.form.NumberTextBoxMixin],
+	{
+	// summary:
+	//		Extends NumberTextBox to add up/down arrows and pageup/pagedown for incremental change to the value
+	//
+	// description:
+	//		A `dijit.form.NumberTextBox` extension to provide keyboard accessible value selection
+	//		as well as icons for spinning direction. When using the keyboard, the typematic rules
+	//		apply, meaning holding the key will gradually increarease or decrease the value and
+	// 		accelerate.
+	//		
+	// example:
+	//	| new dijit.form.NumberSpinner({ constraints:{ max:300, min:100 }}, "someInput");
+
+	// Override required=false from ValidationTextBox
+	required: true,
+
+	adjust: function(/* Object */val, /* Number*/delta){
+		// summary:
+		//		Change Number val by the given amount
+		// tags:
+		//		protected
+
+		var tc = this.constraints, 
+			v = isNaN(val), 
+			gotMax = !isNaN(tc.max), 
+			gotMin = !isNaN(tc.min)
+		;
+		if(v && delta != 0){ // blank or invalid value and they want to spin, so create defaults
+			val = (delta > 0) ? 
+				gotMin ? tc.min : gotMax ? tc.max : 0 :
+				gotMax ? this.constraints.max : gotMin ? tc.min : 0
+			;
+		}
+		var newval = val + delta;
+		if(v || isNaN(newval)){ return val; }
+		if(gotMax && (newval > tc.max)){
+			newval = tc.max;
+		}
+		if(gotMin && (newval < tc.min)){
+			newval = tc.min;
+		}
+		return newval;
+	},
+	
+	_onKeyPress: function(e){
+		if((e.charOrCode == dojo.keys.HOME || e.charOrCode == dojo.keys.END) && !e.ctrlKey && !e.altKey){
+			var value = this.constraints[(e.charOrCode == dojo.keys.HOME ? "min" : "max")];
+			if(value){
+				this._setValueAttr(value,true);
+			}
+			// eat home or end key whether we change the value or not
+			dojo.stopEvent(e);
+		}
+	}
+	
+});
+
+}
+
+if(!dojo._hasResource["dijit.form.HorizontalSlider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.HorizontalSlider"] = true;
+dojo.provide("dijit.form.HorizontalSlider");
+
+
+
+
+
+
+
+
+dojo.declare(
+	"dijit.form.HorizontalSlider",
+	[dijit.form._FormValueWidget, dijit._Container],
+{
+	// summary:
+	//		A form widget that allows one to select a value with a horizontally draggable handle
+
+	templateString:"<table class=\"dijit dijitReset dijitSlider\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" rules=\"none\" dojoAttachEvent=\"onkeypress:_onKeyPress\"\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset\" colspan=\"2\"></td\n\t\t><td dojoAttachPoint=\"containerNode,topDecoration\" class=\"dijitReset\" style=\"text-align:center;width:100%;\"></td\n\t\t><td class=\"dijitReset\" colspan=\"2\"></td\n\t></tr\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset di [...]
+
+	// Overrides FormValueWidget.value to indicate numeric value
+	value: 0,
+
+	// showButtons: Boolean
+	//		Show increment/decrement buttons at the ends of the slider?
+	showButtons: true,
+
+	// minimum:: Integer
+	//		The minimum value the slider can be set to.
+	minimum: 0,
+
+	// maximum: Integer
+	//		The maximum value the slider can be set to.
+	maximum: 100,
+
+	// discreteValues: Integer
+	//		If specified, indicates that the slider handle has only 'discreteValues' possible positions,
+	//      and that after dragging the handle, it will snap to the nearest possible position.
+	//      Thus, the slider has only 'discreteValues' possible values.
+	//
+	//		For example, if minimum=10, maxiumum=30, and discreteValues=3, then the slider handle has
+	//		three possible positions, representing values 10, 20, or 30.
+	//
+	//		If discreteValues is not specified or if it's value is higher than the number of pixels
+	//		in the slider bar, then the slider handle can be moved freely, and the slider's value will be
+	//		computed/reported based on pixel position (in this case it will likely be fractional,
+	//      such as 123.456789).
+	discreteValues: Infinity,
+
+	// pageIncrement: Integer
+	//		If discreteValues is also specified, this indicates the amount of clicks (ie, snap positions)
+	//      that the slider handle is moved via pageup/pagedown keys.
+    //      If discreteValues is not specified, it indicates the number of pixels.
+	pageIncrement: 2,
+
+	// clickSelect: Boolean
+	//		If clicking the slider bar changes the value or not
+	clickSelect: true,
+
+	// slideDuration: Number
+	//		The time in ms to take to animate the slider handle from 0% to 100%,
+	//		when clicking the slider bar to make the handle move.
+	slideDuration: dijit.defaultDuration,
+
+	// Flag to _Templated
+	widgetsInTemplate: true,
+
+	attributeMap: dojo.delegate(dijit.form._FormWidget.prototype.attributeMap, {
+		id: ""
+	}),
+
+	baseClass: "dijitSlider",
+
+	_mousePixelCoord: "pageX",
+	_pixelCount: "w",
+	_startingPixelCoord: "x",
+	_startingPixelCount: "l",
+	_handleOffsetCoord: "left",
+	_progressPixelSize: "width",
+
+	_onKeyPress: function(/*Event*/ e){
+		if(this.disabled || this.readOnly || e.altKey || e.ctrlKey){ return; }
+		switch(e.charOrCode){
+			case dojo.keys.HOME:
+				this._setValueAttr(this.minimum, true);
+				break;
+			case dojo.keys.END:
+				this._setValueAttr(this.maximum, true);
+				break;
+			// this._descending === false: if ascending vertical (min on top)
+			// (this._descending || this.isLeftToRight()): if left-to-right horizontal or descending vertical
+			case ((this._descending || this.isLeftToRight()) ? dojo.keys.RIGHT_ARROW : dojo.keys.LEFT_ARROW):
+			case (this._descending === false ? dojo.keys.DOWN_ARROW : dojo.keys.UP_ARROW):
+			case (this._descending === false ? dojo.keys.PAGE_DOWN : dojo.keys.PAGE_UP):
+				this.increment(e);
+				break;
+			case ((this._descending || this.isLeftToRight()) ? dojo.keys.LEFT_ARROW : dojo.keys.RIGHT_ARROW):
+			case (this._descending === false ? dojo.keys.UP_ARROW : dojo.keys.DOWN_ARROW):
+			case (this._descending === false ? dojo.keys.PAGE_UP : dojo.keys.PAGE_DOWN):
+				this.decrement(e);
+				break;
+			default:
+				return;
+		}
+		dojo.stopEvent(e);
+	},
+
+	_onHandleClick: function(e){
+		if(this.disabled || this.readOnly){ return; }
+		if(!dojo.isIE){
+			// make sure you get focus when dragging the handle
+			// (but don't do on IE because it causes a flicker on mouse up (due to blur then focus)
+			dijit.focus(this.sliderHandle);
+		}
+		dojo.stopEvent(e);
+	},
+	
+	_isReversed: function(){
+		// summary:
+		//		Returns true if direction is from right to left
+		// tags:
+		//		protected extension
+		return !this.isLeftToRight();
+	},
+
+	_onBarClick: function(e){
+		if(this.disabled || this.readOnly || !this.clickSelect){ return; }
+		dijit.focus(this.sliderHandle);
+		dojo.stopEvent(e);
+		var abspos = dojo.coords(this.sliderBarContainer, true);
+		var pixelValue = e[this._mousePixelCoord] - abspos[this._startingPixelCoord];
+		this._setPixelValue(this._isReversed() ? (abspos[this._pixelCount] - pixelValue) : pixelValue, abspos[this._pixelCount], true);
+		this._movable.onMouseDown(e);
+	},
+
+	_setPixelValue: function(/*Number*/ pixelValue, /*Number*/ maxPixels, /*Boolean, optional*/ priorityChange){
+		if(this.disabled || this.readOnly){ return; }
+		pixelValue = pixelValue < 0 ? 0 : maxPixels < pixelValue ? maxPixels : pixelValue;
+		var count = this.discreteValues;
+		if(count <= 1 || count == Infinity){ count = maxPixels; }
+		count--;
+		var pixelsPerValue = maxPixels / count;
+		var wholeIncrements = Math.round(pixelValue / pixelsPerValue);
+		this._setValueAttr((this.maximum-this.minimum)*wholeIncrements/count + this.minimum, priorityChange);
+	},
+
+	_setValueAttr: function(/*Number*/ value, /*Boolean, optional*/ priorityChange){
+		// summary:
+		//		Hook so attr('value', value) works.
+		this.valueNode.value = this.value = value;
+		dijit.setWaiState(this.focusNode, "valuenow", value);
+		this.inherited(arguments);
+		var percent = (value - this.minimum) / (this.maximum - this.minimum);
+		var progressBar = (this._descending === false) ? this.remainingBar : this.progressBar;
+		var remainingBar = (this._descending === false) ? this.progressBar : this.remainingBar;
+		if(this._inProgressAnim && this._inProgressAnim.status != "stopped"){
+			this._inProgressAnim.stop(true);
+		}
+		if(priorityChange && this.slideDuration > 0 && progressBar.style[this._progressPixelSize]){
+			// animate the slider
+			var _this = this;
+			var props = {};
+			var start = parseFloat(progressBar.style[this._progressPixelSize]);
+			var duration = this.slideDuration * (percent-start/100);
+			if(duration == 0){ return; }
+			if(duration < 0){ duration = 0 - duration; }
+			props[this._progressPixelSize] = { start: start, end: percent*100, units:"%" };
+			this._inProgressAnim = dojo.animateProperty({ node: progressBar, duration: duration, 
+				onAnimate: function(v){ remainingBar.style[_this._progressPixelSize] = (100-parseFloat(v[_this._progressPixelSize])) + "%"; },
+				onEnd: function(){ delete _this._inProgressAnim; },
+				properties: props
+			})
+			this._inProgressAnim.play();
+		}
+		else{
+			progressBar.style[this._progressPixelSize] = (percent*100) + "%";
+			remainingBar.style[this._progressPixelSize] = ((1-percent)*100) + "%";
+		}
+	},
+
+	_bumpValue: function(signedChange){
+		if(this.disabled || this.readOnly){ return; }
+		var s = dojo.getComputedStyle(this.sliderBarContainer);
+		var c = dojo._getContentBox(this.sliderBarContainer, s);
+		var count = this.discreteValues;
+		if(count <= 1 || count == Infinity){ count = c[this._pixelCount]; }
+		count--;
+		var value = (this.value - this.minimum) * count / (this.maximum - this.minimum) + signedChange;
+		if(value < 0){ value = 0; }
+		if(value > count){ value = count; }
+		value = value * (this.maximum - this.minimum) / count + this.minimum;
+		this._setValueAttr(value, true);
+	},
+
+	_onClkBumper: function(val){
+		if(this.disabled || this.readOnly || !this.clickSelect){ return; }
+		this._setValueAttr(val, true);
+	},
+
+	_onClkIncBumper: function(){
+		this._onClkBumper(this._descending === false ? this.minimum : this.maximum);
+	},
+
+	_onClkDecBumper: function(){
+		this._onClkBumper(this._descending === false ? this.maximum : this.minimum);
+	},
+
+	decrement: function(e){
+		// summary:
+		//		Decrement slider by 1 unit
+		// tags:
+		//		private
+		this._bumpValue(e.charOrCode == dojo.keys.PAGE_DOWN ? -this.pageIncrement : -1);
+	},
+
+	increment: function(e){
+		// summary:
+		//		Increment slider by 1 unit
+		// tags:
+		//		private
+		this._bumpValue(e.charOrCode == dojo.keys.PAGE_UP ? this.pageIncrement : 1);
+	},
+
+	_mouseWheeled: function(/*Event*/ evt){
+		// summary:
+		//		Event handler for mousewheel where supported
+		dojo.stopEvent(evt);
+		// FIXME: this adds mouse wheel support for safari, though stopEvent doesn't prevent
+		// it from bleeding to window?!
+		var janky = !dojo.isMozilla;
+		var scroll = evt[(janky ? "wheelDelta" : "detail")] * (janky ? 1 : -1);
+		this[(scroll < 0 ? "decrement" : "increment")](evt);
+	},
+
+	startup: function(){
+		dojo.forEach(this.getChildren(), function(child){
+			if(this[child.container] != this.containerNode){
+				this[child.container].appendChild(child.domNode);
+			}
+		}, this);
+	},
+
+	_typematicCallback: function(/*Number*/ count, /*Object*/ button, /*Event*/ e){
+		if(count == -1){ return; }
+		this[(button == (this._descending? this.incrementButton : this.decrementButton))? "decrement" : "increment"](e);
+	},
+
+	postCreate: function(){
+		if(this.showButtons){
+			this.incrementButton.style.display="";
+			this.decrementButton.style.display="";
+			this._connects.push(dijit.typematic.addMouseListener(
+				this.decrementButton, this, "_typematicCallback", 25, 500));
+			this._connects.push(dijit.typematic.addMouseListener(
+				this.incrementButton, this, "_typematicCallback", 25, 500));
+		}
+		this.connect(this.domNode, !dojo.isMozilla ? "onmousewheel" : "DOMMouseScroll", "_mouseWheeled");
+
+		// define a custom constructor for a SliderMover that points back to me
+		var _self = this;
+		var mover = function(){
+			dijit.form._SliderMover.apply(this, arguments);
+			this.widget = _self;
+		};
+		dojo.extend(mover, dijit.form._SliderMover.prototype);
+
+		this._movable = new dojo.dnd.Moveable(this.sliderHandle, {mover: mover});
+		//find any associated label element and add to slider focusnode.
+		var label=dojo.query('label[for="'+this.id+'"]');
+		if(label.length){
+			label[0].id = (this.id+"_label");
+			dijit.setWaiState(this.focusNode, "labelledby", label[0].id);
+		}
+		dijit.setWaiState(this.focusNode, "valuemin", this.minimum);
+		dijit.setWaiState(this.focusNode, "valuemax", this.maximum);
+
+		this.inherited(arguments);
+	},
+
+	destroy: function(){
+		this._movable.destroy();
+		if(this._inProgressAnim && this._inProgressAnim.status != "stopped"){
+			this._inProgressAnim.stop(true);
+		}
+		this.inherited(arguments);	
+	}
+});
+
+dojo.declare("dijit.form._SliderMover",
+	dojo.dnd.Mover,
+{
+	onMouseMove: function(e){
+		var widget = this.widget;
+		var abspos = widget._abspos;
+		if(!abspos){
+			abspos = widget._abspos = dojo.coords(widget.sliderBarContainer, true);
+			widget._setPixelValue_ = dojo.hitch(widget, "_setPixelValue");
+			widget._isReversed_ = widget._isReversed();
+		}
+		var pixelValue = e[widget._mousePixelCoord] - abspos[widget._startingPixelCoord];
+		widget._setPixelValue_(widget._isReversed_ ? (abspos[widget._pixelCount]-pixelValue) : pixelValue, abspos[widget._pixelCount], false);
+	},
+	
+	destroy: function(e){
+		dojo.dnd.Mover.prototype.destroy.apply(this, arguments);
+		var widget = this.widget;
+		widget._abspos = null;
+		widget._setValueAttr(widget.value, true);
+	}
+});
+
+
+
+}
+
+if(!dojo._hasResource["dijit.form.VerticalSlider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.VerticalSlider"] = true;
+dojo.provide("dijit.form.VerticalSlider");
+
+
+
+dojo.declare(
+	"dijit.form.VerticalSlider",
+	dijit.form.HorizontalSlider,
+{
+	// summary:
+	//		A form widget that allows one to select a value with a vertically draggable handle
+
+	templateString:"<table class=\"dijitReset dijitSlider\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" rules=\"none\" dojoAttachEvent=\"onkeypress:_onKeyPress\"\n><tbody class=\"dijitReset\"\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset\"></td\n\t\t><td class=\"dijitReset dijitSliderButtonContainer dijitSliderButtonContainerV\"\n\t\t\t><div class=\"dijitSliderIncrementIconV\" tabIndex=\"-1\" style=\"display:none\" dojoAttachPoint=\"decrementButton\"><span class=\"dijitSlid [...]
+	_mousePixelCoord: "pageY",
+	_pixelCount: "h",
+	_startingPixelCoord: "y",
+	_startingPixelCount: "t",
+	_handleOffsetCoord: "top",
+	_progressPixelSize: "height",
+
+	// _descending: Boolean
+	//	   Specifies if the slider values go from high-on-top (true), or low-on-top (false)
+	//	TODO: expose this in 1.2 - the css progress/remaining bar classes need to be reversed
+	_descending: true,
+
+	startup: function(){
+		if(this._started){ return; }
+
+		if(!this.isLeftToRight() && dojo.isMoz){
+			if(this.leftDecoration){this._rtlRectify(this.leftDecoration);}
+			if(this.rightDecoration){this._rtlRectify(this.rightDecoration);}
+		}
+
+		this.inherited(arguments);
+	},
+		
+	_isReversed: function(){
+		// summary:
+		//		Overrides HorizontalSlider._isReversed.
+		//		Indicates if values are high on top (with low numbers on the bottom).
+		return this._descending;
+	},
+
+	_rtlRectify: function(decorationNode/*NodeList*/){
+		// summary:
+		//	    Helper function on gecko.
+		//		Rectify children nodes for left/right decoration in rtl case.
+		//		Simply switch the rule and label child for each decoration node.
+		// tags:
+		//		private
+		var childNodes = [];
+		while(decorationNode.firstChild){
+				childNodes.push(decorationNode.firstChild);
+				decorationNode.removeChild(decorationNode.firstChild);
+		}
+		for(var i = childNodes.length-1; i >=0; i--){
+			if(childNodes[i]){
+				decorationNode.appendChild(childNodes[i]);
+			}
+		}
+	}
+});
+
+
+}
+
+if(!dojo._hasResource["dijit.form.HorizontalRule"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.HorizontalRule"] = true;
+dojo.provide("dijit.form.HorizontalRule");
+
+
+
+
+dojo.declare("dijit.form.HorizontalRule", [dijit._Widget, dijit._Templated],
+{
+	// summary:
+	//		Hash marks for `dijit.form.HorizontalSlider`
+
+	templateString: '<div class="dijitRuleContainer dijitRuleContainerH"></div>',
+
+	// count: Integer
+	//		Number of hash marks to generate
+	count: 3,
+
+	// container: String
+	//		For HorizontalSlider, this is either "topDecoration" or "bottomDecoration",
+	//		and indicates whether this rule goes above or below the slider.
+	container: "containerNode",
+
+	// ruleStyle: String
+	//		CSS style to apply to individual hash marks
+	ruleStyle: "",
+
+	_positionPrefix: '<div class="dijitRuleMark dijitRuleMarkH" style="left:',
+	_positionSuffix: '%;',
+	_suffix: '"></div>',
+
+	_genHTML: function(pos, ndx){
+		return this._positionPrefix + pos + this._positionSuffix + this.ruleStyle + this._suffix;
+	},
+
+	// _isHorizontal: [protected extension] Boolean
+	//		VerticalRule will override this...
+	_isHorizontal: true,
+
+	postCreate: function(){
+		var innerHTML;
+		if(this.count==1){
+			innerHTML = this._genHTML(50, 0);
+		}else{
+			var i;
+			var interval = 100 / (this.count-1);
+			if(!this._isHorizontal || this.isLeftToRight()){
+				innerHTML = this._genHTML(0, 0);
+				for(i=1; i < this.count-1; i++){
+					innerHTML += this._genHTML(interval*i, i);
+				}
+				innerHTML += this._genHTML(100, this.count-1);
+			}else{
+				innerHTML = this._genHTML(100, 0);
+				for(i=1; i < this.count-1; i++){
+					innerHTML += this._genHTML(100-interval*i, i);
+				}
+				innerHTML += this._genHTML(0, this.count-1);
+			}
+		}
+		this.domNode.innerHTML = innerHTML;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit.form.VerticalRule"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.VerticalRule"] = true;
+dojo.provide("dijit.form.VerticalRule");
+
+
+
+dojo.declare("dijit.form.VerticalRule", dijit.form.HorizontalRule,
+{
+	// summary:
+	//		Hash marks for the `dijit.form.VerticalSlider`
+
+	templateString: '<div class="dijitRuleContainer dijitRuleContainerV"></div>',
+	_positionPrefix: '<div class="dijitRuleMark dijitRuleMarkV" style="top:',
+
+/*=====
+	// container: String
+	//		This is either "leftDecoration" or "rightDecoration",
+	//		to indicate whether this rule goes to the left or to the right of the slider.
+	//		Note that on RTL system, "leftDecoration" would actually go to the right, and vice-versa.
+	container: "",
+=====*/
+
+	// Overrides HorizontalRule._isHorizontal
+	_isHorizontal: false
+
+});
+
+
+}
+
+if(!dojo._hasResource["dijit.form.HorizontalRuleLabels"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.HorizontalRuleLabels"] = true;
+dojo.provide("dijit.form.HorizontalRuleLabels");
+
+
+
+dojo.declare("dijit.form.HorizontalRuleLabels", dijit.form.HorizontalRule,
+{
+	// summary:
+	//		Labels for `dijit.form.HorizontalSlider`
+
+	templateString: '<div class="dijitRuleContainer dijitRuleContainerH dijitRuleLabelsContainer dijitRuleLabelsContainerH"></div>',
+
+	// labelStyle: String
+	//		CSS style to apply to individual text labels
+	labelStyle: "",
+
+	// labels: String[]?
+	//		Array of text labels to render - evenly spaced from left-to-right or bottom-to-top.
+	//		Alternately, minimum and maximum can be specified, to get numeric labels.
+	labels: [],
+
+	// numericMargin: Integer
+	//		Number of generated numeric labels that should be rendered as '' on the ends when labels[] are not specified
+	numericMargin: 0,
+
+	// numericMinimum: Integer
+	//		Leftmost label value for generated numeric labels when labels[] are not specified
+	minimum: 0,
+
+	// numericMaximum: Integer
+	//		Rightmost label value for generated numeric labels when labels[] are not specified
+	maximum: 1,
+
+	// constraints: Object
+	//		pattern, places, lang, et al (see dojo.number) for generated numeric labels when labels[] are not specified
+	constraints: {pattern:"#%"},
+
+	_positionPrefix: '<div class="dijitRuleLabelContainer dijitRuleLabelContainerH" style="left:',
+	_labelPrefix: '"><span class="dijitRuleLabel dijitRuleLabelH">',
+	_suffix: '</span></div>',
+
+	_calcPosition: function(pos){
+		// summary:
+		//		Returns the value to be used in HTML for the label as part of the left: attribute
+		// tags:
+		//		protected extension
+		return pos;
+	},
+
+	_genHTML: function(pos, ndx){
+		return this._positionPrefix + this._calcPosition(pos) + this._positionSuffix + this.labelStyle + this._labelPrefix + this.labels[ndx] + this._suffix;
+	},
+
+	getLabels: function(){
+		// summary:
+		//		Overridable function to return array of labels to use for this slider.
+		//		Can specify a getLabels() method instead of a labels[] array, or min/max attributes.
+		// tags:
+		//		protected extension
+
+		// if the labels array was not specified directly, then see if <li> children were
+		var labels = this.labels;
+		if(!labels.length){
+			// for markup creation, labels are specified as child elements
+			labels = dojo.query("> li", this.srcNodeRef).map(function(node){
+				return String(node.innerHTML);
+			});
+		}
+		this.srcNodeRef.innerHTML = '';
+		// if the labels were not specified directly and not as <li> children, then calculate numeric labels
+		if(!labels.length && this.count > 1){
+			var start = this.minimum;
+			var inc = (this.maximum - start) / (this.count-1);
+			for (var i=0; i < this.count; i++){
+				labels.push((i<this.numericMargin||i>=(this.count-this.numericMargin))? '' : dojo.number.format(start, this.constraints));
+				start += inc;
+			}
+		}
+		return labels;
+	},
+
+	postMixInProperties: function(){
+		this.inherited(arguments);
+		this.labels = this.getLabels();
+		this.count = this.labels.length;
+	}
+});
+
+
+
+}
+
+if(!dojo._hasResource["dijit.form.VerticalRuleLabels"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.VerticalRuleLabels"] = true;
+dojo.provide("dijit.form.VerticalRuleLabels");
+
+
+
+dojo.declare("dijit.form.VerticalRuleLabels", dijit.form.HorizontalRuleLabels,
+{
+	// summary:
+	//		Labels for the `dijit.form.VerticalSlider`
+
+	templateString: '<div class="dijitRuleContainer dijitRuleContainerV dijitRuleLabelsContainer dijitRuleLabelsContainerV"></div>',
+
+	_positionPrefix: '<div class="dijitRuleLabelContainer dijitRuleLabelContainerV" style="top:',
+	_labelPrefix: '"><span class="dijitRuleLabel dijitRuleLabelV">',
+
+	_calcPosition: function(pos){
+		// Overrides HorizontalRuleLabel._calcPosition()
+		return 100-pos;
+	},
+
+	// TODO: remove this.   Apparently it's not used.
+	_isHorizontal: false
+});
+
+}
+
+if(!dojo._hasResource["dijit.form.SimpleTextarea"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.SimpleTextarea"] = true;
+dojo.provide("dijit.form.SimpleTextarea");
+
+
+
+dojo.declare("dijit.form.SimpleTextarea",
+	dijit.form.TextBox,
+	{
+	// summary:
+	//		A simple textarea that degrades, and responds to
+	// 		minimal LayoutContainer usage, and works with dijit.form.Form.
+	//		Doesn't automatically size according to input, like Textarea.
+	//
+	// example:
+	//	|	<textarea dojoType="dijit.form.SimpleTextarea" name="foo" value="bar" rows=30 cols=40></textarea>
+	//
+	// example:
+	//	|	new dijit.form.SimpleTextarea({ rows:20, cols:30 }, "foo");
+
+	baseClass: "dijitTextArea",
+
+	attributeMap: dojo.delegate(dijit.form._FormValueWidget.prototype.attributeMap, {
+		rows:"textbox", cols: "textbox"
+	}),
+
+	// rows: Number
+	//		The number of rows of text.
+	rows: "3",
+
+	// rows: Number
+	//		The number of characters per line.
+	cols: "20",
+
+	templatePath: null,
+	templateString: "<textarea ${nameAttrSetting} dojoAttachPoint='focusNode,containerNode,textbox' autocomplete='off'></textarea>",
+
+	postMixInProperties: function(){
+		// Copy value from srcNodeRef, unless user specified a value explicitly (or there is no srcNodeRef)
+		if(!this.value && this.srcNodeRef){
+			this.value = this.srcNodeRef.value;
+		}
+		this.inherited(arguments);
+	},
+
+	filter: function(/*String*/ value){
+		// Override TextBox.filter to deal with newlines... specifically (IIRC) this is for IE which writes newlines
+		// as \r\n instead of just \n
+		if(value){
+			value = value.replace(/\r/g,"");
+		}
+		return this.inherited(arguments);
+	},
+
+	postCreate: function(){
+		this.inherited(arguments);
+		if(dojo.isIE && this.cols){ // attribute selectors is not supported in IE6
+			dojo.addClass(this.domNode, "dijitTextAreaCols");
+		}
+	},
+
+	_previousValue: "",
+	_onInput: function(e){
+		// Override TextBox._onInput() to enforce maxLength restriction
+		if(this.maxLength){
+			var maxLength = parseInt(this.maxLength);
+			var value = this.textbox.value.replace(/\r/g,'');
+			var overflow = value.length - maxLength;
+			if(overflow > 0){
+				dojo.stopEvent(e);
+				var textarea = this.textbox;
+				if(textarea.selectionStart){
+					var pos = textarea.selectionStart;
+					var cr = 0;
+					if(dojo.isOpera){
+						cr = (this.textbox.value.substring(0,pos).match(/\r/g)||[]).length;
+					}
+					this.textbox.value = value.substring(0,pos-overflow-cr)+value.substring(pos-cr);
+					textarea.setSelectionRange(pos-overflow, pos-overflow);
+				}else if(dojo.doc.selection){ //IE
+					textarea.focus();
+					var range = dojo.doc.selection.createRange();
+					// delete overflow characters
+					range.moveStart("character", -overflow);
+					range.text = '';
+					// show cursor
+					range.select();
+				}
+			}
+			this._previousValue = this.textbox.value;
+		}
+		this.inherited(arguments);
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit.form.Textarea"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.Textarea"] = true;
+dojo.provide("dijit.form.Textarea");
+
+
+
+dojo.declare(
+	"dijit.form.Textarea",
+	dijit.form.SimpleTextarea,
+	{
+	// summary:
+	//		A textarea widget that adjusts it's height according to the amount of data.
+	//
+	// description:
+	//		A textarea that dynamically expands/contracts (changing it's height) as
+	//		the user types, to display all the text without requiring a scroll bar.
+	//
+	//		Takes nearly all the parameters (name, value, etc.) that a vanilla textarea takes.
+	//		Rows is not supported since this widget adjusts the height.
+	//
+	// example:
+	// |	<textarea dojoType="dijit.form.TextArea">...</textarea>
+
+
+	// Override SimpleTextArea.cols to default to width:100%, for backward compatibility
+	cols: "",
+
+	_previousNewlines: 0,
+	_strictMode: (dojo.doc.compatMode != 'BackCompat'), // not the same as !dojo.isQuirks
+
+	_getHeight: function(textarea){
+		var newH = textarea.scrollHeight;
+		if(dojo.isIE){
+			newH += textarea.offsetHeight - textarea.clientHeight - ((dojo.isIE < 8 && this._strictMode)? dojo._getPadBorderExtents(textarea).h : 0);
+		}else if(dojo.isMoz){
+			newH += textarea.offsetHeight - textarea.clientHeight; // creates room for horizontal scrollbar
+		}else if(dojo.isWebKit && !(dojo.isSafari < 4)){ // Safari 4.0 && Chrome
+			newH += dojo._getBorderExtents(textarea).h;
+		}else{ // Safari 3.x and Opera 9.6
+			newH += dojo._getPadBorderExtents(textarea).h;
+		}
+		return newH;
+	},
+
+	_estimateHeight: function(textarea){
+		// summary:
+		// 		Approximate the height when the textarea is invisible with the number of lines in the text.
+		// 		Fails when someone calls setValue with a long wrapping line, but the layout fixes itself when the user clicks inside so . . .
+		// 		In IE, the resize event is supposed to fire when the textarea becomes visible again and that will correct the size automatically.
+		//
+		textarea.style.maxHeight = "";
+		textarea.style.height = "auto";
+		// #rows = #newlines+1
+		// Note: on Moz, the following #rows appears to be 1 too many.
+		// Actually, Moz is reserving room for the scrollbar.
+		// If you increase the font size, this behavior becomes readily apparent as the last line gets cut off without the +1.
+		textarea.rows = (textarea.value.match(/\n/g) || []).length + 1;
+	},
+
+	_needsHelpShrinking: dojo.isMoz || dojo.isWebKit,
+
+	_onInput: function(){
+		// Override SimpleTextArea._onInput() to deal with height adjustment
+		this.inherited(arguments);
+		if(this._busyResizing){ return; }
+		this._busyResizing = true;
+		var textarea = this.textbox;
+		if(textarea.scrollHeight){
+			var newH = this._getHeight(textarea) + "px";
+			if(textarea.style.height != newH){
+				textarea.style.maxHeight = textarea.style.height = newH;
+			}
+			if(this._needsHelpShrinking){
+				if(this._setTimeoutHandle){
+					clearTimeout(this._setTimeoutHandle);
+				}
+				this._setTimeoutHandle = setTimeout(dojo.hitch(this, "_shrink"), 0); // try to collapse multiple shrinks into 1
+			}
+		}else{
+			// hidden content of unknown size
+			this._estimateHeight(textarea);
+		}
+		this._busyResizing = false;
+	},
+
+	_busyResizing: false,
+	_shrink: function(){
+		// grow paddingBottom to see if scrollHeight shrinks (when it is unneccesarily big)
+		this._setTimeoutHandle = null;
+		if(this._needsHelpShrinking && !this._busyResizing){
+			this._busyResizing = true;
+			var textarea = this.textbox;
+			var empty = false;
+			if(textarea.value == ''){
+				textarea.value = ' '; // prevent collapse all the way back to 0
+				empty = true;
+			}
+			var scrollHeight = textarea.scrollHeight;
+			if(!scrollHeight){
+				this._estimateHeight(textarea);
+			}else{
+				var oldPadding = textarea.style.paddingBottom;
+				var newPadding = dojo._getPadExtents(textarea);
+				newPadding = newPadding.h - newPadding.t;
+				textarea.style.paddingBottom = newPadding + 1 + "px"; // tweak padding to see if height can be reduced
+				var newH = this._getHeight(textarea) - 1 + "px"; // see if the height changed by the 1px added
+				if(textarea.style.maxHeight != newH){ // if can be reduced, so now try a big chunk
+					textarea.style.paddingBottom = newPadding + scrollHeight + "px";
+					textarea.scrollTop = 0;
+					textarea.style.maxHeight = this._getHeight(textarea) - scrollHeight + "px"; // scrollHeight is the added padding
+				}
+				textarea.style.paddingBottom = oldPadding;
+			}
+			if(empty){
+				textarea.value = '';
+			}
+			this._busyResizing = false;
+		}
+	},
+
+	resize: function(){
+		// summary:
+		//		Resizes the textarea vertically (should be called after a style/value change)
+		this._onInput();
+	},
+
+	_setValueAttr: function(){
+		this.inherited(arguments);
+		this.resize();
+	},
+
+	postCreate: function(){
+		this.inherited(arguments);
+		// tweak textarea style to reduce browser differences
+		dojo.style(this.textbox, { overflowY: 'hidden', overflowX: 'auto', boxSizing: 'border-box', MsBoxSizing: 'border-box', WebkitBoxSizing: 'border-box', MozBoxSizing: 'border-box' });
+		this.connect(this.textbox, "onscroll", this._onInput);
+		this.connect(this.textbox, "onresize", this._onInput);
+		this.connect(this.textbox, "onfocus", this._onInput); // useful when a previous estimate was off a bit
+		setTimeout(dojo.hitch(this, "resize"), 0);
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit.form.ToggleButton"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.ToggleButton"] = true;
+dojo.provide("dijit.form.ToggleButton");
+
+
+}
+
+if(!dojo._hasResource["dijit.layout.StackController"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.layout.StackController"] = true;
+dojo.provide("dijit.layout.StackController");
+
+
+
+
+
+
+
+
+dojo.declare(
+		"dijit.layout.StackController",
+		[dijit._Widget, dijit._Templated, dijit._Container],
+		{
+		// summary:
+		//		Set of buttons to select a page in a page list.
+		// description:
+		//		Monitors the specified StackContainer, and whenever a page is
+		//		added, deleted, or selected, updates itself accordingly.
+
+			templateString: "<span wairole='tablist' dojoAttachEvent='onkeypress' class='dijitStackController'></span>",
+
+			// containerId: [const] String
+			//		The id of the page container that I point to
+			containerId: "",
+
+			// buttonWidget: [const] String
+			//		The name of the button widget to create to correspond to each page
+			buttonWidget: "dijit.layout._StackButton",
+
+			postCreate: function(){
+				dijit.setWaiRole(this.domNode, "tablist");
+
+				// TODO: change key from object to id, to get more separation from StackContainer
+				this.pane2button = {};		// mapping from panes to buttons
+				this.pane2handles = {};		// mapping from panes to dojo.connect() handles
+				this.pane2menu = {};		// mapping from panes to close menu
+
+				this._subscriptions=[
+					dojo.subscribe(this.containerId+"-startup", this, "onStartup"),
+					dojo.subscribe(this.containerId+"-addChild", this, "onAddChild"),
+					dojo.subscribe(this.containerId+"-removeChild", this, "onRemoveChild"),
+					dojo.subscribe(this.containerId+"-selectChild", this, "onSelectChild"),
+					dojo.subscribe(this.containerId+"-containerKeyPress", this, "onContainerKeyPress")
+				];
+			},
+
+			onStartup: function(/*Object*/ info){
+				// summary:
+				//		Called after StackContainer has finished initializing
+				// tags:
+				//		private
+				dojo.forEach(info.children, this.onAddChild, this);
+				this.onSelectChild(info.selected);
+			},
+
+			destroy: function(){
+				for(var pane in this.pane2button){
+					this.onRemoveChild(pane);
+				}
+				dojo.forEach(this._subscriptions, dojo.unsubscribe);
+				this.inherited(arguments);
+			},
+
+			onAddChild: function(/*Widget*/ page, /*Integer?*/ insertIndex){
+				// summary:
+				//		Called whenever a page is added to the container.
+				//		Create button corresponding to the page.
+				// tags:
+				//		private
+
+				// add a node that will be promoted to the button widget
+				var refNode = dojo.doc.createElement("span");
+				this.domNode.appendChild(refNode);
+				// create an instance of the button widget
+				var cls = dojo.getObject(this.buttonWidget);
+				var button = new cls({label: page.title, closeButton: page.closable}, refNode);
+				this.addChild(button, insertIndex);
+				this.pane2button[page] = button;
+				page.controlButton = button;	// this value might be overwritten if two tabs point to same container
+
+				var handles = [];
+				handles.push(dojo.connect(button, "onClick", dojo.hitch(this,"onButtonClick",page)));
+				if(page.closable){
+					handles.push(dojo.connect(button, "onClickCloseButton", dojo.hitch(this,"onCloseButtonClick",page)));
+					// add context menu onto title button
+					var _nlsResources = dojo.i18n.getLocalization("dijit", "common");
+					var closeMenu = new dijit.Menu({targetNodeIds:[button.id], id:button.id+"_Menu"});
+					var mItem = new dijit.MenuItem({label:_nlsResources.itemClose});
+					handles.push(dojo.connect(mItem, "onClick", dojo.hitch(this, "onCloseButtonClick", page)));
+					closeMenu.addChild(mItem);
+					this.pane2menu[page] = closeMenu;
+				}
+				this.pane2handles[page] = handles;
+				if(!this._currentChild){ // put the first child into the tab order
+					button.focusNode.setAttribute("tabIndex", "0");
+					this._currentChild = page;
+				}
+				//make sure all tabs have the same length
+				if(!this.isLeftToRight() && dojo.isIE && this._rectifyRtlTabList){
+					this._rectifyRtlTabList();
+				}
+			},
+
+			onRemoveChild: function(/*Widget*/ page){
+				// summary:
+				//		Called whenever a page is removed from the container.
+				//		Remove the button corresponding to the page.
+				// tags:
+				//		private
+
+				if(this._currentChild === page){ this._currentChild = null; }
+				dojo.forEach(this.pane2handles[page], dojo.disconnect);
+				delete this.pane2handles[page];
+				var menu = this.pane2menu[page];
+				if (menu){
+					menu.destroyRecursive();
+					delete this.pane2menu[page];
+				}
+				var button = this.pane2button[page];
+				if(button){
+					// TODO? if current child { reassign }
+					button.destroy();
+					delete this.pane2button[page];
+				}
+			},
+
+			onSelectChild: function(/*Widget*/ page){
+				// summary:
+				//		Called when a page has been selected in the StackContainer, either by me or by another StackController
+				// tags:
+				//		private
+
+				if(!page){ return; }
+
+				if(this._currentChild){
+					var oldButton=this.pane2button[this._currentChild];
+					oldButton.attr('checked', false);
+					oldButton.focusNode.setAttribute("tabIndex", "-1");
+				}
+
+				var newButton=this.pane2button[page];
+				newButton.attr('checked', true);
+				this._currentChild = page;
+				newButton.focusNode.setAttribute("tabIndex", "0");
+				var container = dijit.byId(this.containerId);
+				dijit.setWaiState(container.containerNode, "labelledby", newButton.id);
+			},
+
+			onButtonClick: function(/*Widget*/ page){
+				// summary:
+				//		Called whenever one of my child buttons is pressed in an attempt to select a page
+				// tags:
+				//		private
+
+				var container = dijit.byId(this.containerId);	// TODO: do this via topics?
+				container.selectChild(page); 
+			},
+
+			onCloseButtonClick: function(/*Widget*/ page){
+				// summary:
+				//		Called whenever one of my child buttons [X] is pressed in an attempt to close a page
+				// tags:
+				//		private
+
+				var container = dijit.byId(this.containerId);
+				container.closeChild(page);
+				var b = this.pane2button[this._currentChild];
+				if(b){
+					dijit.focus(b.focusNode || b.domNode);
+				}
+			},
+			
+			// TODO: this is a bit redundant with forward, back api in StackContainer
+			adjacent: function(/*Boolean*/ forward){
+				// summary:
+				//		Helper for onkeypress to find next/previous button
+				// tags:
+				//		private
+
+				if(!this.isLeftToRight() && (!this.tabPosition || /top|bottom/.test(this.tabPosition))){ forward = !forward; }
+				// find currently focused button in children array
+				var children = this.getChildren();
+				var current = dojo.indexOf(children, this.pane2button[this._currentChild]);
+				// pick next button to focus on
+				var offset = forward ? 1 : children.length - 1;
+				return children[ (current + offset) % children.length ]; // dijit._Widget
+			},
+
+			onkeypress: function(/*Event*/ e){
+				// summary:
+				//		Handle keystrokes on the page list, for advancing to next/previous button
+				//		and closing the current page if the page is closable.
+				// tags:
+				//		private
+
+				if(this.disabled || e.altKey ){ return; }
+				var forward = null;
+				if(e.ctrlKey || !e._djpage){
+					var k = dojo.keys;
+					switch(e.charOrCode){
+						case k.LEFT_ARROW:
+						case k.UP_ARROW:
+							if(!e._djpage){ forward = false; }
+							break;
+						case k.PAGE_UP:
+							if(e.ctrlKey){ forward = false; }
+							break;
+						case k.RIGHT_ARROW:
+						case k.DOWN_ARROW:
+							if(!e._djpage){ forward = true; }
+							break;
+						case k.PAGE_DOWN:
+							if(e.ctrlKey){ forward = true; }
+							break;
+						case k.DELETE:
+							if(this._currentChild.closable){
+								this.onCloseButtonClick(this._currentChild);
+							}
+							dojo.stopEvent(e);
+							break;
+						default:
+							if(e.ctrlKey){
+								if(e.charOrCode === k.TAB){
+									this.adjacent(!e.shiftKey).onClick();
+									dojo.stopEvent(e);
+								}else if(e.charOrCode == "w"){
+									if(this._currentChild.closable){
+										this.onCloseButtonClick(this._currentChild);
+									}
+									dojo.stopEvent(e); // avoid browser tab closing.
+								}
+							}
+					}
+					// handle page navigation
+					if(forward !== null){
+						this.adjacent(forward).onClick();
+						dojo.stopEvent(e);
+					}
+				}
+			},
+
+			onContainerKeyPress: function(/*Object*/ info){
+				// summary:
+				//		Called when there was a keypress on the container
+				// tags:
+				//		private
+				info.e._djpage = info.page;
+				this.onkeypress(info.e);
+			}
+	});
+
+
+dojo.declare("dijit.layout._StackButton",
+		dijit.form.ToggleButton,
+		{
+		// summary:
+		//		Internal widget used by StackContainer.
+		// description:
+		//		The button-like or tab-like object you click to select or delete a page
+		// tags:
+		//		private
+
+		// Override _FormWidget.tabIndex.
+		// StackContainer buttons are not in the tab order by default.
+		// TODO: unclear if we need this; doesn't _KeyNavContainer (superclass of StackController) do it for us?
+		tabIndex: "-1",
+		
+		postCreate: function(/*Event*/ evt){
+			dijit.setWaiRole((this.focusNode || this.domNode), "tab");
+			this.inherited(arguments);
+		},
+		
+		onClick: function(/*Event*/ evt){
+			// summary:
+			//		This is for TabContainer where the tabs are <span> rather than button,
+			//		so need to set focus explicitly (on some browsers)
+			//		Note that you shouldn't override this method, but you can connect to it.
+			dijit.focus(this.focusNode);
+
+			// ... now let StackController catch the event and tell me what to do
+		},
+
+		onClickCloseButton: function(/*Event*/ evt){
+			// summary:
+			//		StackContainer connects to this function; if your widget contains a close button
+			//		then clicking it should call this function.
+			//		Note that you shouldn't override this method, but you can connect to it.
+			evt.stopPropagation();
+		}
+	});
+
+
+}
+
+if(!dojo._hasResource["dijit.layout.StackContainer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.layout.StackContainer"] = true;
+dojo.provide("dijit.layout.StackContainer");
+
+
+
+
+
+
+dojo.declare(
+	"dijit.layout.StackContainer",
+	dijit.layout._LayoutWidget,
+	{
+	// summary: 
+	//		A container that has multiple children, but shows only
+	//		one child at a time
+	//
+	// description:
+	//		A container for widgets (ContentPanes, for example) That displays
+	//		only one Widget at a time.
+	//	
+	//		Publishes topics [widgetId]-addChild, [widgetId]-removeChild, and [widgetId]-selectChild
+	//
+	//		Can be base class for container, Wizard, Show, etc.
+
+	// doLayout: Boolean
+	//		If true, change the size of my currently displayed child to match my size
+	doLayout: true,
+
+	// persist: Boolean
+	//		Remembers the selected child across sessions
+	persist: false,	// Boolean
+	
+	baseClass: "dijitStackContainer",
+
+	// _started: Boolean
+	//		startup() has completed.
+	//	TODO: comment this section out, it's just needed for documentation.
+	//	Plus, move it to _Widget
+	_started: false,
+
+/*=====
+	// selectedChildWidget: Widget
+	//		References the currently selected child widget, if any
+	//
+	selectedChildWidget: null,
+=====*/
+
+	postCreate: function(){
+		this.inherited(arguments);
+		dojo.addClass(this.domNode, "dijitLayoutContainer");
+		dijit.setWaiRole(this.containerNode, "tabpanel");
+		this.connect(this.domNode, "onkeypress", this._onKeyPress);
+	},
+
+	startup: function(){
+		if(this._started){ return; }
+
+		var children = this.getChildren();
+
+		// Setup each page panel to be initially hidden
+		dojo.forEach(children, this._setupChild, this);
+
+		// Figure out which child to initially display, defaulting to first one
+		if(this.persist){
+			this.selectedChildWidget = dijit.byId(dojo.cookie(this.id + "_selectedChild"));
+		}else{
+			dojo.some(children, function(child){
+				if(child.selected){
+					this.selectedChildWidget = child;
+				}
+				return child.selected;
+			}, this);
+		}
+		var selected = this.selectedChildWidget;
+		if(!selected && children[0]){
+			selected = this.selectedChildWidget = children[0];
+			selected.selected = true;
+		}
+
+		// Publish information about myself so any StackControllers can initialize.
+		// This needs to happen before this.inherited(arguments) so that for
+		// TabContainer, this._contentBox doesn't include the space for the tab labels.
+		dojo.publish(this.id+"-startup", [{children: children, selected: selected}]);
+
+		// Show the initially selected child (do this before this.inherited() call,
+		// because child can't size correctly if it's hidden).
+		// TODO: this will call onShow() on the child widget before startup() which is weird.
+		if(selected){
+			this._showChild(selected);
+		}
+
+		// Startup each child widget, and do initial layout like setting this._contentBox,
+		// then calls this.resize() which does the initial sizing on the selected child.
+		this.inherited(arguments);
+	},
+
+	_setupChild: function(/*Widget*/ child){
+		// Overrides _LayoutWidget._setupChild()
+
+		this.inherited(arguments);
+
+		dojo.removeClass(child.domNode, "dijitVisible");
+		dojo.addClass(child.domNode, "dijitHidden");
+
+		// remove the title attribute so it doesn't show up when i hover
+		// over a node
+		child.domNode.title = "";
+
+		return child; // dijit._Widget		(TODO: remove this, return code is unused)
+	},
+
+	addChild: function(/*Widget*/ child, /*Integer?*/ insertIndex){
+		// Overrides _Container.addChild() to do layout and publish events
+		 
+		this.inherited(arguments);
+
+		if(this._started){
+			dojo.publish(this.id+"-addChild", [child, insertIndex]);
+
+			// in case the tab titles have overflowed from one line to two lines
+			// (or, if this if first child, from zero lines to one line)
+			this.layout();
+
+			// if this is the first child, then select it
+			if(!this.selectedChildWidget){
+				this.selectChild(child);
+			}
+		}
+	},
+
+	removeChild: function(/*Widget*/ page){
+		// Overrides _Container.removeChild() to do layout and publish events
+
+		this.inherited(arguments);
+
+		// If we are being destroyed than don't run the code below (to select another page), because we are deleting
+		// every page one by one
+		if(this._beingDestroyed){ return; }
+
+		if(this._started){
+			// this will notify any tablists to remove a button; do this first because it may affect sizing
+			dojo.publish(this.id+"-removeChild", [page]);
+
+			// in case the tab titles now take up one line instead of two lines
+			this.layout();
+		}
+
+		if(this.selectedChildWidget === page){
+			this.selectedChildWidget = undefined;
+			if(this._started){
+				var children = this.getChildren();
+				if(children.length){
+					this.selectChild(children[0]);
+				}
+			}
+		}
+	},
+
+	selectChild: function(/*Widget*/ page){
+		// summary:
+		//		Show the given widget (which must be one of my children)
+
+		page = dijit.byId(page);
+
+		if(this.selectedChildWidget != page){
+			// Deselect old page and select new one
+			this._transition(page, this.selectedChildWidget);
+			this.selectedChildWidget = page;
+			dojo.publish(this.id+"-selectChild", [page]);
+
+			if(this.persist){
+				dojo.cookie(this.id + "_selectedChild", this.selectedChildWidget.id);
+			}
+		}
+	},
+
+	_transition: function(/*Widget*/newWidget, /*Widget*/oldWidget){
+		// summary:
+		//		Hide the old widget and display the new widget.
+		//		Subclasses should override this.
+		// tags:
+		//		protected extension
+		if(oldWidget){
+			this._hideChild(oldWidget);
+		}
+		this._showChild(newWidget);
+
+		// Size the new widget, in case this is the first time it's being shown,
+		// or I have been resized since the last time it was shown.
+		// Note that page must be visible for resizing to work. 
+		if(this.doLayout && newWidget.resize){
+			newWidget.resize(this._containerContentBox || this._contentBox);
+		}
+	},
+
+	_adjacent: function(/*Boolean*/ forward){
+		// summary:
+		//		Gets the next/previous child widget in this container from the current selection.
+		var children = this.getChildren();
+		var index = dojo.indexOf(children, this.selectedChildWidget);
+		index += forward ? 1 : children.length - 1;
+		return children[ index % children.length ]; // dijit._Widget
+	},
+
+	forward: function(){
+		// summary:
+		//		Advance to next page.
+		this.selectChild(this._adjacent(true));
+	},
+
+	back: function(){
+		// summary:
+		//		Go back to previous page.
+		this.selectChild(this._adjacent(false));
+	},
+
+	_onKeyPress: function(e){
+		dojo.publish(this.id+"-containerKeyPress", [{ e: e, page: this}]);
+	},
+
+	layout: function(){
+		// Implement _LayoutWidget.layout() virtual method.
+		if(this.doLayout && this.selectedChildWidget && this.selectedChildWidget.resize){
+			this.selectedChildWidget.resize(this._contentBox);
+		}
+	},
+
+	_showChild: function(/*Widget*/ page){
+		// summary:
+		//		Show the specified child by changing it's CSS, and call _onShow()/onShow() so
+		//		it can do any updates it needs regarding loading href's etc.
+		var children = this.getChildren();
+		page.isFirstChild = (page == children[0]);
+		page.isLastChild = (page == children[children.length-1]);
+		page.selected = true;
+
+		dojo.removeClass(page.domNode, "dijitHidden");
+		dojo.addClass(page.domNode, "dijitVisible");
+
+		if(page._onShow){
+			page._onShow(); // trigger load in ContentPane
+		}else if(page.onShow){
+			page.onShow();
+		}
+	},
+
+	_hideChild: function(/*Widget*/ page){
+		// summary:
+		//		Hide the specified child by changing it's CSS, and call _onHide() so
+		//		it's notified.
+		page.selected=false;
+		dojo.removeClass(page.domNode, "dijitVisible");
+		dojo.addClass(page.domNode, "dijitHidden");
+
+		if(page.onHide){
+			page.onHide();
+		}
+	},
+
+	closeChild: function(/*Widget*/ page){
+		// summary:
+		//		Callback when user clicks the [X] to remove a page.
+		//		If onClose() returns true then remove and destroy the child.
+		// tags:
+		//		private
+		var remove = page.onClose(this, page);
+		if(remove){
+			this.removeChild(page);
+			// makes sure we can clean up executeScripts in ContentPane onUnLoad
+			page.destroyRecursive();
+		}
+	},
+
+	destroy: function(){
+		this._beingDestroyed = true;
+		this.inherited(arguments);
+	}
+});
+
+// For back-compat, remove for 2.0
+
+
+
+// These arguments can be specified for the children of a StackContainer.
+// Since any widget can be specified as a StackContainer child, mix them
+// into the base widget class.  (This is a hack, but it's effective.)
+dojo.extend(dijit._Widget, {
+	// title: String
+	//		Title of this widget.  Used by TabContainer to the name the tab, etc.
+	// TODO: remove this, it's in _Widget already.
+	title: "",
+
+	// selected: Boolean
+	//		Is this child currently selected?
+	selected: false,
+
+	// closable: Boolean
+	//		True if user can close (destroy) this child, such as (for example) clicking the X on the tab.
+	closable: false,	// true if user can close this tab pane
+
+	onClose: function(){
+		// summary:
+		//		Callback if someone tries to close the child, child will be closed if func returns true
+		// tags:
+		//		extension
+
+		return true;		// Boolean
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit.layout.AccordionPane"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.layout.AccordionPane"] = true;
+dojo.provide("dijit.layout.AccordionPane");
+
+
+
+dojo.declare("dijit.layout.AccordionPane", dijit.layout.ContentPane, {
+	// summary:
+	//		Deprecated widget.   Use `dijit.layout.ContentPane` instead.
+	// tags:
+	//		deprecated
+
+	constructor: function(){
+		dojo.deprecated("dijit.layout.AccordionPane deprecated, use ContentPane instead", "", "2.0");
+	},
+
+	onSelected: function(){
+		// summary: called when this pane is selected
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit.layout.AccordionContainer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.layout.AccordionContainer"] = true;
+dojo.provide("dijit.layout.AccordionContainer");
+
+
+
+
+
+
+
+
+	// for back compat
+
+dojo.declare(
+	"dijit.layout.AccordionContainer",
+	dijit.layout.StackContainer,
+	{
+		// summary:
+		//		Holds a set of panes where every pane's title is visible, but only one pane's content is visible at a time,
+		//		and switching between panes is visualized by sliding the other panes up/down.
+		// example:
+		// | 	<div dojoType="dijit.layout.AccordionContainer">
+		// |		<div dojoType="dijit.layout.AccordionPane" title="pane 1">
+		// |			<div dojoType="dijit.layout.ContentPane">...</div>
+		// | 	</div>
+		// |		<div dojoType="dijit.layout.AccordionPane" title="pane 2">
+		// |			<p>This is some text</p>
+		// ||		...
+		// |	</div>
+
+		// duration: Integer
+		//		Amount of time (in ms) it takes to slide panes
+		duration: dijit.defaultDuration,
+
+		// _verticalSpace: Number
+		//		Pixels of space available for the open pane
+		//		(my content box size minus the cumulative size of all the title bars)
+		_verticalSpace: 0,
+
+		baseClass: "dijitAccordionContainer",
+		
+		postCreate: function(){
+			this.domNode.style.overflow = "hidden";
+			this.inherited(arguments); 
+			dijit.setWaiRole(this.domNode, "tablist");
+		},
+
+		startup: function(){
+			if(this._started){ return; }
+			this.inherited(arguments);	
+			if(this.selectedChildWidget){
+				var style = this.selectedChildWidget.containerNode.style;
+				style.display = "";
+				style.overflow = "auto";
+				this.selectedChildWidget._buttonWidget._setSelectedState(true);
+			}
+		},
+		
+		_getTargetHeight: function(/* Node */ node){
+			// summary:
+			//		For the given node, returns the height that should be
+			//		set to achieve our vertical space (subtract any padding
+			//		we may have).
+			//
+			//		This is used by the animations.
+			//
+			//		TODO: I don't think this works correctly in IE quirks when an elements
+			//		style.height including padding and borders
+			var cs = dojo.getComputedStyle(node);
+			return Math.max(this._verticalSpace - dojo._getPadBorderExtents(node, cs).h, 0);
+		},
+
+		layout: function(){
+			// Implement _LayoutWidget.layout() virtual method.
+			// Set the height of the open pane based on what room remains.
+
+			var openPane = this.selectedChildWidget;
+
+			// get cumulative height of all the title bars
+			var totalCollapsedHeight = 0;
+			dojo.forEach(this.getChildren(), function(child){
+				totalCollapsedHeight += child._buttonWidget.getTitleHeight();
+			});
+			var mySize = this._contentBox;
+			this._verticalSpace = mySize.h - totalCollapsedHeight;
+
+			// Memo size to make displayed child
+			this._containerContentBox = {
+				h: this._verticalSpace,
+				w: mySize.w
+			};
+
+			if(openPane){
+				openPane.resize(this._containerContentBox);
+			}
+		},
+
+		_setupChild: function(child){
+			// Overrides _LayoutWidget._setupChild().
+			// Setup clickable title to sit above the child widget,
+			// and stash pointer to it inside the widget itself.
+
+			child._buttonWidget = new dijit.layout._AccordionButton({
+				contentWidget: child,
+				title: child.title,
+				id: child.id + "_button",
+				parent: this
+			});
+			dojo.place(child._buttonWidget.domNode, child.domNode, "before");
+
+			this.inherited(arguments);
+		},
+
+		removeChild: function(child){
+			// Overrides _LayoutWidget.removeChild().
+			child._buttonWidget.destroy();
+			this.inherited(arguments);
+		},
+
+		getChildren: function(){
+			// Overrides _Container.getChildren() to ignore titles and only look at panes.
+			return dojo.filter(this.inherited(arguments), function(child){
+				return child.declaredClass != "dijit.layout._AccordionButton";
+			});
+		},
+
+		destroy: function(){
+			dojo.forEach(this.getChildren(), function(child){
+				child._buttonWidget.destroy();
+			});
+			this.inherited(arguments);
+		},
+		
+		_transition: function(/*Widget?*/newWidget, /*Widget?*/oldWidget){
+			// Overrides StackContainer._transition() to provide sliding of title bars etc.
+
+//TODO: should be able to replace this with calls to slideIn/slideOut
+			if(this._inTransition){ return; }
+			this._inTransition = true;
+			var animations = [];
+			var paneHeight = this._verticalSpace;
+			if(newWidget){
+				newWidget._buttonWidget.setSelected(true);
+
+				this._showChild(newWidget);	// prepare widget to be slid in
+
+				// Size the new widget, in case this is the first time it's being shown,
+				// or I have been resized since the last time it was shown.
+				// Note that page must be visible for resizing to work. 
+				if(this.doLayout && newWidget.resize){
+					newWidget.resize(this._containerContentBox);
+				}
+				
+				var newContents = newWidget.domNode;
+				dojo.addClass(newContents, "dijitVisible");
+				dojo.removeClass(newContents, "dijitHidden");
+				var newContentsOverflow = newContents.style.overflow;
+				newContents.style.overflow = "hidden";
+				animations.push(dojo.animateProperty({
+					node: newContents,
+					duration: this.duration,
+					properties: {
+						height: { start: 1, end: this._getTargetHeight(newContents) }
+					},
+					onEnd: dojo.hitch(this, function(){
+						newContents.style.overflow = newContentsOverflow;
+						delete this._inTransition;
+					})
+				}));
+			}
+			if(oldWidget){
+				oldWidget._buttonWidget.setSelected(false);
+				var oldContents = oldWidget.domNode,
+					oldContentsOverflow = oldContents.style.overflow;
+				oldContents.style.overflow = "hidden";
+				animations.push(dojo.animateProperty({
+					node: oldContents,
+					duration: this.duration,
+					properties: {
+						height: { start: this._getTargetHeight(oldContents), end: 1 }
+					},
+					onEnd: function(){
+						dojo.addClass(oldContents, "dijitHidden");
+						dojo.removeClass(oldContents, "dijitVisible");
+						oldContents.style.overflow = oldContentsOverflow;
+						if(oldWidget.onHide){
+							oldWidget.onHide();
+						}
+					}
+				}));
+			}
+
+			dojo.fx.combine(animations).play();
+		},
+
+		// note: we are treating the container as controller here
+		_onKeyPress: function(/*Event*/ e, /*Widget*/ fromTitle){
+			// summary:
+			//		Handle keypress events
+			// description:
+			//		This is called from a handler on AccordionContainer.domNode
+			//		(setup in StackContainer), and is also called directly from
+			//		the click handler for accordion labels
+			if(this._inTransition || this.disabled || e.altKey || !(fromTitle || e.ctrlKey)){
+				if(this._inTransition){
+					dojo.stopEvent(e);
+				}
+				return;
+			}
+			var k = dojo.keys,
+				c = e.charOrCode;
+			if((fromTitle && (c == k.LEFT_ARROW || c == k.UP_ARROW)) ||
+					(e.ctrlKey && c == k.PAGE_UP)){
+				this._adjacent(false)._buttonWidget._onTitleClick();
+				dojo.stopEvent(e);
+			}else if((fromTitle && (c == k.RIGHT_ARROW || c == k.DOWN_ARROW)) ||
+					(e.ctrlKey && (c == k.PAGE_DOWN || c == k.TAB))){
+				this._adjacent(true)._buttonWidget._onTitleClick();
+				dojo.stopEvent(e);
+			}
+		}
+	}
+);
+
+dojo.declare("dijit.layout._AccordionButton",
+	[dijit._Widget, dijit._Templated],
+	{
+	// summary:
+	//		The title bar to click to open up an accordion pane.
+	//		Internal widget used by AccordionContainer.
+	// tags:
+	//		private
+
+	templateString:"<div dojoAttachPoint='titleNode,focusNode' dojoAttachEvent='ondijitclick:_onTitleClick,onkeypress:_onTitleKeyPress,onfocus:_handleFocus,onblur:_handleFocus,onmouseenter:_onTitleEnter,onmouseleave:_onTitleLeave'\n\t\tclass='dijitAccordionTitle' wairole=\"tab\" waiState=\"expanded-false\"\n\t\t><span class='dijitInline dijitAccordionArrow' waiRole=\"presentation\"></span\n\t\t><span class='arrowTextUp' waiRole=\"presentation\">+</span\n\t\t><span class='arrowTextDown' waiR [...]
+	attributeMap: dojo.mixin(dojo.clone(dijit.layout.ContentPane.prototype.attributeMap), {
+		title: {node: "titleTextNode", type: "innerHTML" }
+	}),
+
+	baseClass: "dijitAccordionTitle",
+
+	getParent: function(){
+		// summary:
+		//		Returns the parent.
+		// tags:
+		//		private
+		return this.parent;
+	},
+
+	postCreate: function(){
+		this.inherited(arguments);
+		dojo.setSelectable(this.domNode, false);
+		this.setSelected(this.selected);
+		var titleTextNodeId = dojo.attr(this.domNode,'id').replace(' ','_');
+		dojo.attr(this.titleTextNode, "id", titleTextNodeId+"_title");
+		dijit.setWaiState(this.focusNode, "labelledby", dojo.attr(this.titleTextNode, "id"));
+	},
+
+	getTitleHeight: function(){
+		// summary:
+		//		Returns the height of the title dom node.
+		return dojo.marginBox(this.titleNode).h;	// Integer
+	},
+
+	_onTitleClick: function(){
+		// summary:
+		//		Callback when someone clicks my title.
+		var parent = this.getParent();
+		if(!parent._inTransition){
+			parent.selectChild(this.contentWidget);
+			dijit.focus(this.focusNode);
+		}
+	},
+
+	_onTitleEnter: function(){
+		// summary:
+		//		Callback when someone hovers over my title.
+		dojo.addClass(this.focusNode, "dijitAccordionTitle-hover");
+	},
+
+	_onTitleLeave: function(){
+		// summary:
+		//		Callback when someone stops hovering over my title.
+		dojo.removeClass(this.focusNode, "dijitAccordionTitle-hover");
+	},
+
+	_onTitleKeyPress: function(/*Event*/ evt){
+		return this.getParent()._onKeyPress(evt, this.contentWidget);
+	},
+
+	_setSelectedState: function(/*Boolean*/ isSelected){
+		this.selected = isSelected;
+		dojo[(isSelected ? "addClass" : "removeClass")](this.titleNode,"dijitAccordionTitle-selected");
+		dijit.setWaiState(this.focusNode, "expanded", isSelected);
+		dijit.setWaiState(this.focusNode, "selected", isSelected);
+		this.focusNode.setAttribute("tabIndex", isSelected ? "0" : "-1");
+	},
+
+	_handleFocus: function(/*Event*/e){
+		// summary:
+		//		Handle the blur and focus state of this widget.
+		dojo[(e.type=="focus" ? "addClass" : "removeClass")](this.focusNode,"dijitAccordionFocused");		
+	},
+
+	setSelected: function(/*Boolean*/ isSelected){
+		// summary:
+		//		Change the selected state on this pane.
+		this._setSelectedState(isSelected);
+		if(isSelected){
+			var cw = this.contentWidget;
+			if(cw.onSelected){ cw.onSelected(); }
+		}
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit.layout.BorderContainer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.layout.BorderContainer"] = true;
+dojo.provide("dijit.layout.BorderContainer");
+
+
+
+
+dojo.declare(
+	"dijit.layout.BorderContainer",
+	dijit.layout._LayoutWidget,
+{
+	// summary:
+	//		Provides layout in up to 5 regions, a mandatory center with optional borders along its 4 sides.
+	//
+	// description:
+	//		A BorderContainer is a box with a specified size, such as style="width: 500px; height: 500px;",
+	//		that contains a child widget marked region="center" and optionally children widgets marked
+	//		region equal to "top", "bottom", "leading", "trailing", "left" or "right".
+	//		Children along the edges will be laid out according to width or height dimensions and may
+	//		include optional splitters (splitter="true") to make them resizable by the user.  The remaining
+	//		space is designated for the center region.
+	//
+	//		NOTE: Splitters must not be more than 50 pixels in width.
+	//
+	//		The outer size must be specified on the BorderContainer node.  Width must be specified for the sides
+	//		and height for the top and bottom, respectively.  No dimensions should be specified on the center;
+	//		it will fill the remaining space.  Regions named "leading" and "trailing" may be used just like
+	//		"left" and "right" except that they will be reversed in right-to-left environments.
+	//
+	// example:
+	// |	<div dojoType="dijit.layout.BorderContainer" design="sidebar" gutters="false"
+	// |            style="width: 400px; height: 300px;">
+	// |		<div dojoType="ContentPane" region="top">header text</div>
+	// |		<div dojoType="ContentPane" region="right" splitter="true" style="width: 200px;">table of contents</div>
+	// |		<div dojoType="ContentPane" region="center">client area</div>
+	// |	</div>
+
+	// design: String
+	//		Which design is used for the layout:
+	//			- "headline" (default) where the top and bottom extend
+	//				the full width of the container
+	//			- "sidebar" where the left and right sides extend from top to bottom.
+	design: "headline",
+
+	// gutters: Boolean
+	//		Give each pane a border and margin.
+	//		Margin determined by domNode.paddingLeft.
+	//		When false, only resizable panes have a gutter (i.e. draggable splitter) for resizing.
+	gutters: true,
+
+	// liveSplitters: Boolean
+	//		Specifies whether splitters resize as you drag (true) or only upon mouseup (false)
+	liveSplitters: true,
+
+	// persist: Boolean
+	//		Save splitter positions in a cookie.
+	persist: false,
+
+	baseClass: "dijitBorderContainer",
+
+	// _splitterClass: String
+	// 		Optional hook to override the default Splitter widget used by BorderContainer
+	_splitterClass: "dijit.layout._Splitter",
+
+	postMixInProperties: function(){
+		// change class name to indicate that BorderContainer is being used purely for
+		// layout (like LayoutContainer) rather than for pretty formatting.
+		if(!this.gutters){
+			this.baseClass += "NoGutter";
+		}
+		this.inherited(arguments);
+	},
+
+	postCreate: function(){
+		this.inherited(arguments);
+
+		this._splitters = {};
+		this._splitterThickness = {};
+	},
+
+	startup: function(){
+		if(this._started){ return; }
+		dojo.forEach(this.getChildren(), this._setupChild, this);
+		this.inherited(arguments);
+	},
+
+	_setupChild: function(/*Widget*/child){
+		// Override _LayoutWidget._setupChild().
+
+		var region = child.region;
+		if(region){
+			this.inherited(arguments);
+
+			dojo.addClass(child.domNode, this.baseClass+"Pane");
+
+			var ltr = this.isLeftToRight();
+			if(region == "leading"){ region = ltr ? "left" : "right"; }
+			if(region == "trailing"){ region = ltr ? "right" : "left"; }
+
+			//FIXME: redundant?
+			this["_"+region] = child.domNode;
+			this["_"+region+"Widget"] = child;
+
+			// Create draggable splitter for resizing pane,
+			// or alternately if splitter=false but BorderContainer.gutters=true then
+			// insert dummy div just for spacing
+			if((child.splitter || this.gutters) && !this._splitters[region]){
+				var _Splitter = dojo.getObject(child.splitter ? this._splitterClass : "dijit.layout._Gutter");
+				var flip = {left:'right', right:'left', top:'bottom', bottom:'top', leading:'trailing', trailing:'leading'};
+				var splitter = new _Splitter({
+					container: this,
+					child: child,
+					region: region,
+//					oppNode: dojo.query('[region=' + flip[child.region] + ']', this.domNode)[0],
+					oppNode: this["_" + flip[child.region]],
+					live: this.liveSplitters
+				});
+				splitter.isSplitter = true;
+				this._splitters[region] = splitter.domNode;
+				dojo.place(this._splitters[region], child.domNode, "after");
+
+				// Splitters arent added as Contained children, so we need to call startup explicitly
+				splitter.startup();
+			}
+			child.region = region;
+		}
+	},
+
+	_computeSplitterThickness: function(region){
+		this._splitterThickness[region] = this._splitterThickness[region] ||
+			dojo.marginBox(this._splitters[region])[(/top|bottom/.test(region) ? 'h' : 'w')];
+	},
+
+	layout: function(){
+		// Implement _LayoutWidget.layout() virtual method.
+		for(var region in this._splitters){ this._computeSplitterThickness(region); }
+		this._layoutChildren();
+	},
+
+	addChild: function(/*Widget*/ child, /*Integer?*/ insertIndex){
+		// Override _LayoutWidget.addChild().
+		this.inherited(arguments);
+		if(this._started){
+			this._layoutChildren(); //OPT
+		}
+	},
+
+	removeChild: function(/*Widget*/ child){
+		// Override _LayoutWidget.removeChild().
+		var region = child.region;
+		var splitter = this._splitters[region];
+		if(splitter){
+			dijit.byNode(splitter).destroy();
+			delete this._splitters[region];
+			delete this._splitterThickness[region];
+		}
+		this.inherited(arguments);
+		delete this["_"+region];
+		delete this["_" +region+"Widget"];
+		if(this._started){
+			this._layoutChildren(child.region);
+		}
+		dojo.removeClass(child.domNode, this.baseClass+"Pane");
+	},
+
+	getChildren: function(){
+		// Override _LayoutWidget.getChildren() to only return real children, not the splitters.
+		return dojo.filter(this.inherited(arguments), function(widget){
+			return !widget.isSplitter;
+		});
+	},
+
+	getSplitter: function(/*String*/region){
+		// summary:
+		//		Returns the widget responsible for rendering the splitter associated with region 
+		var splitter = this._splitters[region];
+		return splitter ? dijit.byNode(splitter) : null;
+	},
+
+	resize: function(newSize, currentSize){
+		// Overrides _LayoutWidget.resize().
+
+		// resetting potential padding to 0px to provide support for 100% width/height + padding
+		// TODO: this hack doesn't respect the box model and is a temporary fix
+		if (!this.cs || !this.pe){
+			var node = this.domNode;
+			this.cs = dojo.getComputedStyle(node);
+			this.pe = dojo._getPadExtents(node, this.cs);
+			this.pe.r = dojo._toPixelValue(node, this.cs.paddingRight);
+			this.pe.b = dojo._toPixelValue(node, this.cs.paddingBottom);
+
+			dojo.style(node, "padding", "0px");
+		}
+
+		this.inherited(arguments);
+	},
+
+	_layoutChildren: function(/*String?*/changedRegion){
+		// summary:
+		//		This is the main routine for setting size/position of each child
+
+		if(!this._borderBox || !this._borderBox.h){
+			// We are currently hidden, or we haven't been sized by our parent yet.
+			// Abort.   Someone will resize us later.
+			return;
+		}
+
+		var sidebarLayout = (this.design == "sidebar");
+		var topHeight = 0, bottomHeight = 0, leftWidth = 0, rightWidth = 0;
+		var topStyle = {}, leftStyle = {}, rightStyle = {}, bottomStyle = {},
+			centerStyle = (this._center && this._center.style) || {};
+
+		var changedSide = /left|right/.test(changedRegion);
+
+		var layoutSides = !changedRegion || (!changedSide && !sidebarLayout);
+		var layoutTopBottom = !changedRegion || (changedSide && sidebarLayout);
+
+		// Ask browser for width/height of side panes.
+		// Would be nice to cache this but height can change according to width
+		// (because words wrap around).  I don't think width will ever change though
+		// (except when the user drags a splitter). 
+		if(this._top){
+			topStyle = layoutTopBottom && this._top.style;
+			topHeight = dojo.marginBox(this._top).h;
+		}
+		if(this._left){
+			leftStyle = layoutSides && this._left.style;
+			leftWidth = dojo.marginBox(this._left).w;
+		}
+		if(this._right){
+			rightStyle = layoutSides && this._right.style;
+			rightWidth = dojo.marginBox(this._right).w;
+		}
+		if(this._bottom){
+			bottomStyle = layoutTopBottom && this._bottom.style;
+			bottomHeight = dojo.marginBox(this._bottom).h;
+		}
+
+		var splitters = this._splitters;
+		var topSplitter = splitters.top, bottomSplitter = splitters.bottom,
+			leftSplitter = splitters.left, rightSplitter = splitters.right;
+		var splitterThickness = this._splitterThickness;
+		var topSplitterThickness = splitterThickness.top || 0,
+			leftSplitterThickness = splitterThickness.left || 0,
+			rightSplitterThickness = splitterThickness.right || 0,
+			bottomSplitterThickness = splitterThickness.bottom || 0;
+
+		// Check for race condition where CSS hasn't finished loading, so
+		// the splitter width == the viewport width (#5824)
+		if(leftSplitterThickness > 50 || rightSplitterThickness > 50){
+			setTimeout(dojo.hitch(this, function(){
+				// Results are invalid.  Clear them out.
+				this._splitterThickness = {};
+
+				for(var region in this._splitters){
+					this._computeSplitterThickness(region);
+				}
+				this._layoutChildren();
+			}), 50);
+			return false;
+		}
+
+		var pe = this.pe;
+
+		var splitterBounds = {
+			left: (sidebarLayout ? leftWidth + leftSplitterThickness: 0) + pe.l + "px",
+			right: (sidebarLayout ? rightWidth + rightSplitterThickness: 0) + pe.r + "px"
+		};
+
+		if(topSplitter){
+			dojo.mixin(topSplitter.style, splitterBounds);
+			topSplitter.style.top = topHeight + pe.t + "px";
+		}
+
+		if(bottomSplitter){
+			dojo.mixin(bottomSplitter.style, splitterBounds);
+			bottomSplitter.style.bottom = bottomHeight + pe.b + "px";
+		}
+
+		splitterBounds = {
+			top: (sidebarLayout ? 0 : topHeight + topSplitterThickness) + pe.t + "px",
+			bottom: (sidebarLayout ? 0 : bottomHeight + bottomSplitterThickness) + pe.b + "px"
+		};
+
+		if(leftSplitter){
+			dojo.mixin(leftSplitter.style, splitterBounds);
+			leftSplitter.style.left = leftWidth + pe.l + "px";
+		}
+
+		if(rightSplitter){
+			dojo.mixin(rightSplitter.style, splitterBounds);
+			rightSplitter.style.right = rightWidth + pe.r +  "px";
+		}
+
+		dojo.mixin(centerStyle, {
+			top: pe.t + topHeight + topSplitterThickness + "px",
+			left: pe.l + leftWidth + leftSplitterThickness + "px",
+			right: pe.r + rightWidth + rightSplitterThickness + "px",
+			bottom: pe.b + bottomHeight + bottomSplitterThickness + "px"
+		});
+
+		var bounds = {
+			top: sidebarLayout ? pe.t + "px" : centerStyle.top,
+			bottom: sidebarLayout ? pe.b + "px" : centerStyle.bottom
+		};
+		dojo.mixin(leftStyle, bounds);
+		dojo.mixin(rightStyle, bounds);
+		leftStyle.left = pe.l + "px"; rightStyle.right = pe.r + "px"; topStyle.top = pe.t + "px"; bottomStyle.bottom = pe.b + "px";
+		if(sidebarLayout){
+			topStyle.left = bottomStyle.left = leftWidth + leftSplitterThickness + pe.l + "px";
+			topStyle.right = bottomStyle.right = rightWidth + rightSplitterThickness + pe.r + "px";
+		}else{
+			topStyle.left = bottomStyle.left = pe.l + "px";
+			topStyle.right = bottomStyle.right = pe.r + "px";
+		}
+
+		// More calculations about sizes of panes
+		var containerHeight = this._borderBox.h - pe.t - pe.b,
+			middleHeight = containerHeight - ( topHeight + topSplitterThickness + bottomHeight + bottomSplitterThickness),
+			sidebarHeight = sidebarLayout ? containerHeight : middleHeight;
+
+		var containerWidth = this._borderBox.w - pe.l - pe.r,
+			middleWidth = containerWidth - (leftWidth  + leftSplitterThickness + rightWidth + rightSplitterThickness),
+			sidebarWidth = sidebarLayout ? middleWidth : containerWidth;
+
+		// New margin-box size of each pane
+		var dim = {
+			top:	{ w: sidebarWidth, h: topHeight },
+			bottom: { w: sidebarWidth, h: bottomHeight },
+			left:	{ w: leftWidth, h: sidebarHeight },
+			right:	{ w: rightWidth, h: sidebarHeight },
+			center:	{ h: middleHeight, w: middleWidth }
+		};
+
+		// Nodes in IE<8 don't respond to t/l/b/r, and TEXTAREA doesn't respond in any browser
+		var janky = dojo.isIE < 8 || (dojo.isIE && dojo.isQuirks) || dojo.some(this.getChildren(), function(child){
+			return child.domNode.tagName == "TEXTAREA" || child.domNode.tagName == "INPUT";
+		});
+		if(janky){
+			// Set the size of the children the old fashioned way, by setting
+			// CSS width and height
+
+			var resizeWidget = function(widget, changes, result){
+				if(widget){
+					(widget.resize ? widget.resize(changes, result) : dojo.marginBox(widget.domNode, changes));
+				}
+			};
+
+			if(leftSplitter){ leftSplitter.style.height = sidebarHeight; }
+			if(rightSplitter){ rightSplitter.style.height = sidebarHeight; }
+			resizeWidget(this._leftWidget, {h: sidebarHeight}, dim.left);
+			resizeWidget(this._rightWidget, {h: sidebarHeight}, dim.right);
+
+			if(topSplitter){ topSplitter.style.width = sidebarWidth; }
+			if(bottomSplitter){ bottomSplitter.style.width = sidebarWidth; }
+			resizeWidget(this._topWidget, {w: sidebarWidth}, dim.top);
+			resizeWidget(this._bottomWidget, {w: sidebarWidth}, dim.bottom);
+
+			resizeWidget(this._centerWidget, dim.center);
+		}else{
+			// We've already sized the children by setting style.top/bottom/left/right...
+			// Now just need to call resize() on those children telling them their new size,
+			// so they can re-layout themselves
+
+			// Calculate which panes need a notification
+			var resizeList = {};
+			if(changedRegion){
+				resizeList[changedRegion] = resizeList.center = true;
+				if(/top|bottom/.test(changedRegion) && this.design != "sidebar"){
+					resizeList.left = resizeList.right = true;
+				}else if(/left|right/.test(changedRegion) && this.design == "sidebar"){
+					resizeList.top = resizeList.bottom = true;
+				}
+			}
+
+			dojo.forEach(this.getChildren(), function(child){
+				if(child.resize && (!changedRegion || child.region in resizeList)){
+					child.resize(null, dim[child.region]);
+				}
+			}, this);
+		}
+	},
+
+	destroy: function(){
+		for(var region in this._splitters){
+			var splitter = this._splitters[region];
+			dijit.byNode(splitter).destroy();
+			dojo.destroy(splitter);
+		}
+		delete this._splitters;
+		delete this._splitterThickness;
+		this.inherited(arguments);
+	}
+});
+
+// This argument can be specified for the children of a BorderContainer.
+// Since any widget can be specified as a LayoutContainer child, mix it
+// into the base widget class.  (This is a hack, but it's effective.)
+dojo.extend(dijit._Widget, {
+	// region: String
+	//		"top", "bottom", "leading", "trailing", "left", "right", "center".
+	//		See the BorderContainer description for details on this parameter.
+	region: '',
+
+	// splitter: Boolean
+	//		If true, puts a draggable splitter on this widget to resize when used
+	//		inside a border container edge region.
+	splitter: false,
+
+	// minSize: Number
+	//		Specifies a minimum size for this widget when resized by a splitter
+	minSize: 0,
+
+	// maxSize: Number
+	//		Specifies a maximum size for this widget when resized by a splitter
+	maxSize: Infinity
+});
+
+
+
+dojo.declare("dijit.layout._Splitter", [ dijit._Widget, dijit._Templated ],
+{
+	// summary:
+	//		A draggable spacer between two items in a `dijit.layout.BorderContainer`.
+	// description:
+	//		This is instantiated by `dijit.layout.BorderContainer`.  Users should not
+	//		create it directly.
+	// tags:
+	//		private
+
+/*=====
+ 	// container: [const] dijit.layout.BorderContainer
+ 	//		Pointer to the parent BorderContainer
+	container: null,
+
+	// child: [const] dijit.layout._LayoutWidget
+	//		Pointer to the pane associated with this splitter
+	child: null,
+
+	// region: String
+	//		Region of pane associated with this splitter.
+	//		"top", "bottom", "left", "right".
+	region: null,
+=====*/
+
+	// live: [const] Boolean
+	//		If true, the child's size changes and the child widget is redrawn as you drag the splitter;
+	//		otherwise, the size doesn't change until you drop the splitter (by mouse-up)
+	live: true,
+
+	templateString: '<div class="dijitSplitter" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_startDrag" tabIndex="0" waiRole="separator"><div class="dijitSplitterThumb"></div></div>',
+
+	postCreate: function(){
+		this.inherited(arguments);
+		this.horizontal = /top|bottom/.test(this.region);
+		dojo.addClass(this.domNode, "dijitSplitter" + (this.horizontal ? "H" : "V"));
+//		dojo.addClass(this.child.domNode, "dijitSplitterPane");
+//		dojo.setSelectable(this.domNode, false); //TODO is this necessary?
+
+		this._factor = /top|left/.test(this.region) ? 1 : -1;
+		this._minSize = this.child.minSize;
+
+		// trigger constraints calculations
+		this.child.domNode._recalc = true;
+		this.connect(this.container, "resize", function(){ this.child.domNode._recalc = true; });
+
+		this._cookieName = this.container.id + "_" + this.region;
+		if(this.container.persist){
+			// restore old size
+			var persistSize = dojo.cookie(this._cookieName);
+			if(persistSize){
+				this.child.domNode.style[this.horizontal ? "height" : "width"] = persistSize;
+			}
+		}
+	},
+
+	_computeMaxSize: function(){
+		var dim = this.horizontal ? 'h' : 'w',
+			thickness = this.container._splitterThickness[this.region];
+		var available = dojo.contentBox(this.container.domNode)[dim] -
+			(this.oppNode ? dojo.marginBox(this.oppNode)[dim] : 0) -
+			20 - thickness * 2;
+		this._maxSize = Math.min(this.child.maxSize, available);
+	},
+
+	_startDrag: function(e){
+		if(this.child.domNode._recalc){
+			this._computeMaxSize();
+			this.child.domNode._recalc = false;
+		}
+
+		if(!this.cover){
+			this.cover = dojo.doc.createElement('div');
+			dojo.addClass(this.cover, "dijitSplitterCover");
+			dojo.place(this.cover, this.child.domNode, "after");
+		}
+		dojo.addClass(this.cover, "dijitSplitterCoverActive");
+
+		// Safeguard in case the stop event was missed.  Shouldn't be necessary if we always get the mouse up.
+		if(this.fake){ dojo.destroy(this.fake); }
+		if(!(this._resize = this.live)){ //TODO: disable live for IE6?
+			// create fake splitter to display at old position while we drag
+			(this.fake = this.domNode.cloneNode(true)).removeAttribute("id");
+			dojo.addClass(this.domNode, "dijitSplitterShadow");
+			dojo.place(this.fake, this.domNode, "after");
+		}
+		dojo.addClass(this.domNode, "dijitSplitterActive");
+
+		//Performance: load data info local vars for onmousevent function closure
+		var factor = this._factor,
+			max = this._maxSize,
+			min = this._minSize || 20,
+			isHorizontal = this.horizontal,
+			axis = isHorizontal ? "pageY" : "pageX",
+			pageStart = e[axis],
+			splitterStyle = this.domNode.style,
+			dim = isHorizontal ? 'h' : 'w',
+			childStart = dojo.marginBox(this.child.domNode)[dim],
+			region = this.region,
+			splitterStart = parseInt(this.domNode.style[region], 10),
+			resize = this._resize,
+			mb = {},
+			childNode = this.child.domNode,
+			layoutFunc = dojo.hitch(this.container, this.container._layoutChildren),
+			de = dojo.doc.body;
+
+		this._handlers = (this._handlers || []).concat([
+			dojo.connect(de, "onmousemove", this._drag = function(e, forceResize){
+				var delta = e[axis] - pageStart,
+					childSize = factor * delta + childStart,
+					boundChildSize = Math.max(Math.min(childSize, max), min);
+
+				if(resize || forceResize){
+					mb[dim] = boundChildSize;
+					// TODO: inefficient; we set the marginBox here and then immediately layoutFunc() needs to query it
+					dojo.marginBox(childNode, mb);
+					layoutFunc(region);
+				}
+				splitterStyle[region] = factor * delta + splitterStart + (boundChildSize - childSize) + "px";
+			}),
+			dojo.connect(dojo.doc, "ondragstart",   dojo.stopEvent),
+			dojo.connect(dojo.body(), "onselectstart", dojo.stopEvent),
+			dojo.connect(de, "onmouseup", this, "_stopDrag")
+		]);
+		dojo.stopEvent(e);
+	},
+
+	_stopDrag: function(e){
+		try{
+			if(this.cover){
+				dojo.removeClass(this.cover, "dijitSplitterCoverActive");
+			}
+			if(this.fake){ dojo.destroy(this.fake); }
+			dojo.removeClass(this.domNode, "dijitSplitterActive");
+			dojo.removeClass(this.domNode, "dijitSplitterShadow");
+			this._drag(e); //TODO: redundant with onmousemove?
+			this._drag(e, true);
+		}finally{
+			this._cleanupHandlers();
+			if(this.oppNode){ this.oppNode._recalc = true; }
+			delete this._drag;
+		}
+
+		if(this.container.persist){
+			dojo.cookie(this._cookieName, this.child.domNode.style[this.horizontal ? "height" : "width"], {expires:365});
+		}
+	},
+
+	_cleanupHandlers: function(){
+		dojo.forEach(this._handlers, dojo.disconnect);
+		delete this._handlers;
+	},
+
+	_onKeyPress: function(/*Event*/ e){
+		if(this.child.domNode._recalc){
+			this._computeMaxSize();
+			this.child.domNode._recalc = false;
+		}
+
+		// should we apply typematic to this?
+		this._resize = true;
+		var horizontal = this.horizontal;
+		var tick = 1;
+		var dk = dojo.keys;
+		switch(e.charOrCode){
+			case horizontal ? dk.UP_ARROW : dk.LEFT_ARROW:
+				tick *= -1;
+//				break;
+			case horizontal ? dk.DOWN_ARROW : dk.RIGHT_ARROW:
+				break;
+			default:
+//				this.inherited(arguments);
+				return;
+		}
+		var childSize = dojo.marginBox(this.child.domNode)[ horizontal ? 'h' : 'w' ] + this._factor * tick;
+		var mb = {};
+		mb[ this.horizontal ? "h" : "w"] = Math.max(Math.min(childSize, this._maxSize), this._minSize);
+		dojo.marginBox(this.child.domNode, mb);
+		if(this.oppNode){ this.oppNode._recalc = true; }
+		this.container._layoutChildren(this.region);
+		dojo.stopEvent(e);
+	},
+
+	destroy: function(){
+		this._cleanupHandlers();
+		delete this.child;
+		delete this.container;
+		delete this.cover;
+		delete this.fake;
+		this.inherited(arguments);
+	}
+});
+
+dojo.declare("dijit.layout._Gutter", [dijit._Widget, dijit._Templated ],
+{
+	// summary:
+	// 		Just a spacer div to separate side pane from center pane.
+	//		Basically a trick to lookup the gutter/splitter width from the theme.
+	// description:
+	//		Instantiated by `dijit.layout.BorderContainer`.  Users should not
+	//		create directly.
+	// tags:
+	//		private
+
+	templateString: '<div class="dijitGutter" waiRole="presentation"></div>',
+
+	postCreate: function(){
+		this.horizontal = /top|bottom/.test(this.region);
+		dojo.addClass(this.domNode, "dijitGutter" + (this.horizontal ? "H" : "V"));
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit.layout.LayoutContainer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.layout.LayoutContainer"] = true;
+dojo.provide("dijit.layout.LayoutContainer");
+
+
+
+dojo.declare("dijit.layout.LayoutContainer",
+	dijit.layout._LayoutWidget,
+	{
+	// summary:
+	//		Deprecated.  Use `dijit.layout.BorderContainer` instead.
+	//
+	// description:
+	//		Provides Delphi-style panel layout semantics.
+	//
+	//		A LayoutContainer is a box with a specified size (like style="width: 500px; height: 500px;"),
+	//		that contains children widgets marked with "layoutAlign" of "left", "right", "bottom", "top", and "client".
+	//		It takes it's children marked as left/top/bottom/right, and lays them out along the edges of the box,
+	//		and then it takes the child marked "client" and puts it into the remaining space in the middle.
+	//
+	//		Left/right positioning is similar to CSS's "float: left" and "float: right",
+	//		and top/bottom positioning would be similar to "float: top" and "float: bottom", if there were such
+	//		CSS.
+	//
+	//		Note that there can only be one client element, but there can be multiple left, right, top,
+	//		or bottom elements.
+	//
+	// example:
+	// |	<style>
+	// |		html, body{ height: 100%; width: 100%; }
+	// |	</style>
+	// |	<div dojoType="dijit.layout.LayoutContainer" style="width: 100%; height: 100%">
+	// |		<div dojoType="dijit.layout.ContentPane" layoutAlign="top">header text</div>
+	// |		<div dojoType="dijit.layout.ContentPane" layoutAlign="left" style="width: 200px;">table of contents</div>
+	// |		<div dojoType="dijit.layout.ContentPane" layoutAlign="client">client area</div>
+	// |	</div>
+	//
+	//		Lays out each child in the natural order the children occur in.
+	//		Basically each child is laid out into the "remaining space", where "remaining space" is initially
+	//		the content area of this widget, but is reduced to a smaller rectangle each time a child is added.
+	// tags:
+	//		deprecated
+
+	baseClass: "dijitLayoutContainer",
+
+	constructor: function(){
+		dojo.deprecated("dijit.layout.LayoutContainer is deprecated", "use BorderContainer instead", 2.0);
+	},
+
+	layout: function(){
+		dijit.layout.layoutChildren(this.domNode, this._contentBox, this.getChildren());
+	},
+
+	addChild: function(/*Widget*/ child, /*Integer?*/ insertIndex){
+		this.inherited(arguments);
+		if(this._started){
+			dijit.layout.layoutChildren(this.domNode, this._contentBox, this.getChildren());
+		}
+	},
+
+	removeChild: function(/*Widget*/ widget){
+		this.inherited(arguments);
+		if(this._started){
+			dijit.layout.layoutChildren(this.domNode, this._contentBox, this.getChildren());
+		}
+	}
+});
+
+// This argument can be specified for the children of a LayoutContainer.
+// Since any widget can be specified as a LayoutContainer child, mix it
+// into the base widget class.  (This is a hack, but it's effective.)
+dojo.extend(dijit._Widget, {
+	// layoutAlign: String
+	//		"none", "left", "right", "bottom", "top", and "client".
+	//		See the LayoutContainer description for details on this parameter.
+	layoutAlign: 'none'
+});
+
+}
+
+if(!dojo._hasResource["dijit.layout.LinkPane"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.layout.LinkPane"] = true;
+dojo.provide("dijit.layout.LinkPane");
+
+
+
+
+dojo.declare("dijit.layout.LinkPane",
+	[dijit.layout.ContentPane, dijit._Templated],
+	{
+	// summary: 
+	//		A ContentPane with an href where (when declared in markup)
+	//		the title is specified as innerHTML rather than as a title attribute.
+	// description:
+	//		LinkPane is just a ContentPane that is declared in markup similarly
+	//		to an anchor.  The anchor's body (the words between `<a>` and `</a>`)
+	//		become the title of the widget (used for TabContainer, AccordionContainer, etc.)
+	// example:
+	//	| <a href="foo.html">my title</a>
+
+	// I'm using a template because the user may specify the input as
+	// <a href="foo.html">title</a>, in which case we need to get rid of the
+	// <a> because we don't want a link.
+	templateString: '<div class="dijitLinkPane" dojoAttachPoint="containerNode"></div>',
+
+	postMixInProperties: function(){
+		// If user has specified node contents, they become the title
+		// (the link must be plain text)
+		if(this.srcNodeRef){
+			this.title += this.srcNodeRef.innerHTML;
+		}
+		this.inherited(arguments);
+	},
+
+	_fillContent: function(/*DomNode*/ source){
+		// Overrides _Templated._fillContent().
+
+		// _Templated._fillContent() relocates srcNodeRef innerHTML to templated container node,
+		// but in our case the srcNodeRef innerHTML is the title, so shouldn't be
+		// copied
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit.layout.SplitContainer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.layout.SplitContainer"] = true;
+dojo.provide("dijit.layout.SplitContainer");
+
+//
+// FIXME: make it prettier
+// FIXME: active dragging upwards doesn't always shift other bars (direction calculation is wrong in this case)
+//
+
+
+
+
+dojo.declare("dijit.layout.SplitContainer",
+	dijit.layout._LayoutWidget,
+	{
+	// summary: 
+	//		Deprecated.  Use `dijit.layout.BorderContainer` instead.
+	// description:
+	//		A Container widget with sizing handles in-between each child.
+	//		Contains multiple children widgets, all of which are displayed side by side
+	//		(either horizontally or vertically); there's a bar between each of the children,
+	//		and you can adjust the relative size of each child by dragging the bars.
+	//
+	//		You must specify a size (width and height) for the SplitContainer.
+	// tags:
+	//		deprecated
+
+	constructor: function(){
+		dojo.deprecated("dijit.layout.SplitContainer is deprecated", "use BorderContainer with splitter instead", 2.0);
+	},
+
+	// activeSizing: Boolean
+	//		If true, the children's size changes as you drag the bar;
+	//		otherwise, the sizes don't change until you drop the bar (by mouse-up)
+	activeSizing: false,
+
+	// sizerWidth: Integer
+	//		Size in pixels of the bar between each child
+	sizerWidth: 7, // FIXME: this should be a CSS attribute (at 7 because css wants it to be 7 until we fix to css)
+
+	// orientation: String
+	//		either 'horizontal' or vertical; indicates whether the children are
+	//		arranged side-by-side or up/down.
+	orientation: 'horizontal',
+
+	// persist: Boolean
+	//		Save splitter positions in a cookie
+	persist: true,
+
+	baseClass: "dijitSplitContainer",
+
+	postMixInProperties: function(){
+		this.inherited("postMixInProperties",arguments);
+		this.isHorizontal = (this.orientation == 'horizontal');
+	},
+
+	postCreate: function(){
+		this.inherited(arguments);
+		this.sizers = [];
+
+		// overflow has to be explicitly hidden for splitContainers using gekko (trac #1435)
+		// to keep other combined css classes from inadvertantly making the overflow visible
+		if(dojo.isMozilla){
+			this.domNode.style.overflow = '-moz-scrollbars-none'; // hidden doesn't work
+		}
+
+		// create the fake dragger
+		if(typeof this.sizerWidth == "object"){
+			try{ //FIXME: do this without a try/catch
+				this.sizerWidth = parseInt(this.sizerWidth.toString());
+			}catch(e){ this.sizerWidth = 7; }
+		}
+		var sizer = dojo.doc.createElement('div');
+		this.virtualSizer = sizer;
+		sizer.style.position = 'relative';
+
+		// #1681: work around the dreaded 'quirky percentages in IE' layout bug
+		// If the splitcontainer's dimensions are specified in percentages, it
+		// will be resized when the virtualsizer is displayed in _showSizingLine
+		// (typically expanding its bounds unnecessarily). This happens because
+		// we use position: relative for .dijitSplitContainer.
+		// The workaround: instead of changing the display style attribute,
+		// switch to changing the zIndex (bring to front/move to back)
+
+		sizer.style.zIndex = 10;
+		sizer.className = this.isHorizontal ? 'dijitSplitContainerVirtualSizerH' : 'dijitSplitContainerVirtualSizerV';
+		this.domNode.appendChild(sizer);
+		dojo.setSelectable(sizer, false);
+	},
+
+	destroy: function(){
+		delete this.virtualSizer;
+		dojo.forEach(this._ownconnects, dojo.disconnect);
+		this.inherited(arguments);
+	},
+	startup: function(){
+		if(this._started){ return; }
+
+		dojo.forEach(this.getChildren(), function(child, i, children){
+			// attach the children and create the draggers
+			this._setupChild(child);
+
+			if(i < children.length-1){
+				this._addSizer();
+			}
+		}, this);
+
+		if(this.persist){
+			this._restoreState();
+		}
+
+		this.inherited(arguments); 
+	},
+
+	_setupChild: function(/*Widget*/ child){
+		this.inherited(arguments);
+		child.domNode.style.position = "absolute";
+		dojo.addClass(child.domNode, "dijitSplitPane");
+	},
+
+	_onSizerMouseDown: function(e){
+		if(e.target.id){
+			for(var i=0;i<this.sizers.length;i++){
+				if(this.sizers[i].id==e.target.id){
+					break;
+				}
+			}
+			if(i<this.sizers.length){
+				this.beginSizing(e,i);
+			}
+		}
+	},
+	_addSizer: function(index){
+		index = index===undefined?this.sizers.length:index;
+
+		// TODO: use a template for this!!!
+		var sizer = dojo.doc.createElement('div');
+		sizer.id=dijit.getUniqueId('dijit_layout_SplitterContainer_Splitter');
+		this.sizers.splice(index,0,sizer);
+		this.domNode.appendChild(sizer);
+
+		sizer.className = this.isHorizontal ? 'dijitSplitContainerSizerH' : 'dijitSplitContainerSizerV';
+
+		// add the thumb div
+		var thumb = dojo.doc.createElement('div');
+		thumb.className = 'thumb';
+		thumb.id = sizer.id;
+		sizer.appendChild(thumb);
+
+		// FIXME: are you serious? why aren't we using mover start/stop combo?
+		this.connect(sizer, "onmousedown", '_onSizerMouseDown');
+		
+		dojo.setSelectable(sizer, false);
+	},
+
+	removeChild: function(widget){
+		// summary: Remove sizer, but only if widget is really our child and
+		// we have at least one sizer to throw away
+		if(this.sizers.length){
+			var i=dojo.indexOf(this.getChildren(), widget)
+			if(i != -1){
+				if(i==this.sizers.length){
+					i--;
+				}
+				dojo.destroy(this.sizers[i]);
+				this.sizers.splice(i,1);
+			}
+		}
+
+		// Remove widget and repaint
+		this.inherited(arguments); 
+		if(this._started){
+			this.layout();
+		}
+	},
+
+	addChild: function(/*Widget*/ child, /*Integer?*/ insertIndex){
+		// summary:
+		//		Add a child widget to the container
+		// child:
+		//		a widget to add
+		// insertIndex:
+		//		postion in the "stack" to add the child widget
+		
+		this.inherited(arguments); 
+
+		if(this._started){
+			// Do the stuff that startup() does for each widget
+			var children = this.getChildren();
+			if(children.length > 1){
+				this._addSizer(insertIndex);
+			}
+
+			// and then reposition (ie, shrink) every pane to make room for the new guy
+			this.layout();
+		}
+	},
+
+	layout: function(){
+		// summary:
+		//		Do layout of panels
+
+		// base class defines this._contentBox on initial creation and also
+		// on resize
+		this.paneWidth = this._contentBox.w;
+		this.paneHeight = this._contentBox.h;
+
+		var children = this.getChildren();
+		if(!children.length){ return; }
+
+		//
+		// calculate space
+		//
+
+		var space = this.isHorizontal ? this.paneWidth : this.paneHeight;
+		if(children.length > 1){
+			space -= this.sizerWidth * (children.length - 1);
+		}
+
+		//
+		// calculate total of SizeShare values
+		//
+		var outOf = 0;
+		dojo.forEach(children, function(child){
+			outOf += child.sizeShare;
+		});
+
+		//
+		// work out actual pixels per sizeshare unit
+		//
+		var pixPerUnit = space / outOf;
+
+		//
+		// set the SizeActual member of each pane
+		//
+		var totalSize = 0;
+		dojo.forEach(children.slice(0, children.length - 1), function(child){
+			var size = Math.round(pixPerUnit * child.sizeShare);
+			child.sizeActual = size;
+			totalSize += size;
+		});
+
+		children[children.length-1].sizeActual = space - totalSize;
+
+		//
+		// make sure the sizes are ok
+		//
+		this._checkSizes();
+
+		//
+		// now loop, positioning each pane and letting children resize themselves
+		//
+
+		var pos = 0;
+		var size = children[0].sizeActual;
+		this._movePanel(children[0], pos, size);
+		children[0].position = pos;
+		pos += size;
+
+		// if we don't have any sizers, our layout method hasn't been called yet
+		// so bail until we are called..TODO: REVISIT: need to change the startup
+		// algorithm to guaranteed the ordering of calls to layout method
+		if(!this.sizers){
+			return;
+		}
+
+		dojo.some(children.slice(1), function(child, i){
+			// error-checking
+			if(!this.sizers[i]){
+				return true;
+			}
+			// first we position the sizing handle before this pane
+			this._moveSlider(this.sizers[i], pos, this.sizerWidth);
+			this.sizers[i].position = pos;
+			pos += this.sizerWidth;
+
+			size = child.sizeActual;
+			this._movePanel(child, pos, size);
+			child.position = pos;
+			pos += size;
+		}, this);
+	},
+
+	_movePanel: function(panel, pos, size){
+		if(this.isHorizontal){
+			panel.domNode.style.left = pos + 'px';	// TODO: resize() takes l and t parameters too, don't need to set manually
+			panel.domNode.style.top = 0;
+			var box = {w: size, h: this.paneHeight};
+			if(panel.resize){
+				panel.resize(box);
+			}else{
+				dojo.marginBox(panel.domNode, box);
+			}
+		}else{
+			panel.domNode.style.left = 0;	// TODO: resize() takes l and t parameters too, don't need to set manually
+			panel.domNode.style.top = pos + 'px';
+			var box = {w: this.paneWidth, h: size};
+			if(panel.resize){
+				panel.resize(box);
+			}else{
+				dojo.marginBox(panel.domNode, box);
+			}
+		}
+	},
+
+	_moveSlider: function(slider, pos, size){
+		if(this.isHorizontal){
+			slider.style.left = pos + 'px';
+			slider.style.top = 0;
+			dojo.marginBox(slider, { w: size, h: this.paneHeight });
+		}else{
+			slider.style.left = 0;
+			slider.style.top = pos + 'px';
+			dojo.marginBox(slider, { w: this.paneWidth, h: size });
+		}
+	},
+
+	_growPane: function(growth, pane){
+		if(growth > 0){
+			if(pane.sizeActual > pane.sizeMin){
+				if((pane.sizeActual - pane.sizeMin) > growth){
+
+					// stick all the growth in this pane
+					pane.sizeActual = pane.sizeActual - growth;
+					growth = 0;
+				}else{
+					// put as much growth in here as we can
+					growth -= pane.sizeActual - pane.sizeMin;
+					pane.sizeActual = pane.sizeMin;
+				}
+			}
+		}
+		return growth;
+	},
+
+	_checkSizes: function(){
+
+		var totalMinSize = 0;
+		var totalSize = 0;
+		var children = this.getChildren();
+
+		dojo.forEach(children, function(child){
+			totalSize += child.sizeActual;
+			totalMinSize += child.sizeMin;
+		});
+
+		// only make adjustments if we have enough space for all the minimums
+
+		if(totalMinSize <= totalSize){
+
+			var growth = 0;
+
+			dojo.forEach(children, function(child){
+				if(child.sizeActual < child.sizeMin){
+					growth += child.sizeMin - child.sizeActual;
+					child.sizeActual = child.sizeMin;
+				}
+			});
+
+			if(growth > 0){
+				var list = this.isDraggingLeft ? children.reverse() : children;
+				dojo.forEach(list, function(child){
+					growth = this._growPane(growth, child);
+				}, this);
+			}
+		}else{
+			dojo.forEach(children, function(child){
+				child.sizeActual = Math.round(totalSize * (child.sizeMin / totalMinSize));
+			});
+		}
+	},
+
+	beginSizing: function(e, i){
+		var children = this.getChildren();
+		this.paneBefore = children[i];
+		this.paneAfter = children[i+1];
+
+		this.isSizing = true;
+		this.sizingSplitter = this.sizers[i];
+
+		if(!this.cover){
+			this.cover = dojo.create('div', {
+					style: {
+						position:'absolute',
+						zIndex:5,
+						top: 0,
+						left: 0,
+						width: "100%",
+						height: "100%"
+					}
+				}, this.domNode);
+		}else{
+			this.cover.style.zIndex = 5;
+		}
+		this.sizingSplitter.style.zIndex = 6;
+
+		// TODO: REVISIT - we want MARGIN_BOX and core hasn't exposed that yet (but can't we use it anyway if we pay attention? we do elsewhere.)
+		this.originPos = dojo.coords(children[0].domNode, true);
+		if(this.isHorizontal){
+			var client = e.layerX || e.offsetX || 0;
+			var screen = e.pageX;
+			this.originPos = this.originPos.x;
+		}else{
+			var client = e.layerY || e.offsetY || 0;
+			var screen = e.pageY;
+			this.originPos = this.originPos.y;
+		}
+		this.startPoint = this.lastPoint = screen;
+		this.screenToClientOffset = screen - client;
+		this.dragOffset = this.lastPoint - this.paneBefore.sizeActual - this.originPos - this.paneBefore.position;
+
+		if(!this.activeSizing){
+			this._showSizingLine();
+		}
+
+		//					
+		// attach mouse events
+		//
+		this._ownconnects = [];
+		this._ownconnects.push(dojo.connect(dojo.doc.documentElement, "onmousemove", this, "changeSizing"));
+		this._ownconnects.push(dojo.connect(dojo.doc.documentElement, "onmouseup", this, "endSizing"));
+
+		dojo.stopEvent(e);
+	},
+
+	changeSizing: function(e){
+		if(!this.isSizing){ return; }
+		this.lastPoint = this.isHorizontal ? e.pageX : e.pageY;
+		this.movePoint();
+		if(this.activeSizing){
+			this._updateSize();
+		}else{
+			this._moveSizingLine();
+		}
+		dojo.stopEvent(e);
+	},
+
+	endSizing: function(e){
+		if(!this.isSizing){ return; }
+		if(this.cover){
+			this.cover.style.zIndex = -1;
+		}
+		if(!this.activeSizing){
+			this._hideSizingLine();
+		}
+
+		this._updateSize();
+
+		this.isSizing = false;
+
+		if(this.persist){
+			this._saveState(this);
+		}
+
+		dojo.forEach(this._ownconnects,dojo.disconnect); 
+	},
+
+	movePoint: function(){
+
+		// make sure lastPoint is a legal point to drag to
+		var p = this.lastPoint - this.screenToClientOffset;
+
+		var a = p - this.dragOffset;
+		a = this.legaliseSplitPoint(a);
+		p = a + this.dragOffset;
+
+		this.lastPoint = p + this.screenToClientOffset;
+	},
+
+	legaliseSplitPoint: function(a){
+
+		a += this.sizingSplitter.position;
+
+		this.isDraggingLeft = !!(a > 0);
+
+		if(!this.activeSizing){
+			var min = this.paneBefore.position + this.paneBefore.sizeMin;
+			if(a < min){
+				a = min;
+			}
+
+			var max = this.paneAfter.position + (this.paneAfter.sizeActual - (this.sizerWidth + this.paneAfter.sizeMin));
+			if(a > max){
+				a = max;
+			}
+		}
+
+		a -= this.sizingSplitter.position;
+
+		this._checkSizes();
+
+		return a;
+	},
+
+	_updateSize: function(){
+	//FIXME: sometimes this.lastPoint is NaN
+		var pos = this.lastPoint - this.dragOffset - this.originPos;
+
+		var start_region = this.paneBefore.position;
+		var end_region   = this.paneAfter.position + this.paneAfter.sizeActual;
+
+		this.paneBefore.sizeActual = pos - start_region;
+		this.paneAfter.position	= pos + this.sizerWidth;
+		this.paneAfter.sizeActual  = end_region - this.paneAfter.position;
+
+		dojo.forEach(this.getChildren(), function(child){
+			child.sizeShare = child.sizeActual;
+		});
+
+		if(this._started){
+			this.layout();
+		}
+	},
+
+	_showSizingLine: function(){
+
+		this._moveSizingLine();
+
+		dojo.marginBox(this.virtualSizer,
+			this.isHorizontal ? { w: this.sizerWidth, h: this.paneHeight } : { w: this.paneWidth, h: this.sizerWidth });
+
+		this.virtualSizer.style.display = 'block';
+	},
+
+	_hideSizingLine: function(){
+		this.virtualSizer.style.display = 'none';
+	},
+
+	_moveSizingLine: function(){
+		var pos = (this.lastPoint - this.startPoint) + this.sizingSplitter.position;
+		dojo.style(this.virtualSizer,(this.isHorizontal ? "left" : "top"),pos+"px");
+		// this.virtualSizer.style[ this.isHorizontal ? "left" : "top" ] = pos + 'px'; // FIXME: remove this line if the previous is better
+	},
+
+	_getCookieName: function(i){
+		return this.id + "_" + i;
+	},
+
+	_restoreState: function(){
+		dojo.forEach(this.getChildren(), function(child, i){
+			var cookieName = this._getCookieName(i);
+			var cookieValue = dojo.cookie(cookieName);
+			if(cookieValue){
+				var pos = parseInt(cookieValue);
+				if(typeof pos == "number"){
+					child.sizeShare = pos;
+				}
+			}
+		}, this);
+	},
+
+	_saveState: function(){
+		if(!this.persist){
+			return;
+		}
+		dojo.forEach(this.getChildren(), function(child, i){
+			dojo.cookie(this._getCookieName(i), child.sizeShare, {expires:365});
+		}, this);
+	}
+});
+
+// These arguments can be specified for the children of a SplitContainer.
+// Since any widget can be specified as a SplitContainer child, mix them
+// into the base widget class.  (This is a hack, but it's effective.)
+dojo.extend(dijit._Widget, {
+	// sizeMin: Integer
+	//		Minimum size (width or height) of a child of a SplitContainer.
+	//		The value is relative to other children's sizeShare properties.
+	sizeMin: 10,
+
+	// sizeShare: Integer
+	//		Size (width or height) of a child of a SplitContainer.
+	//		The value is relative to other children's sizeShare properties.
+	//		For example, if there are two children and each has sizeShare=10, then
+	//		each takes up 50% of the available space.
+	sizeShare: 10
+});
+
+}
+
+if(!dojo._hasResource["dijit.layout.TabController"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.layout.TabController"] = true;
+dojo.provide("dijit.layout.TabController");
+
+
+
+
+//TODO: make private for 2.0?
+dojo.declare("dijit.layout.TabController",
+	dijit.layout.StackController,
+	{
+	// summary:
+	// 		Set of tabs (the things with titles and a close button, that you click to show a tab panel).
+	//		Used internally by `dijit.layout.TabContainer`.
+	// description:
+	//		Lets the user select the currently shown pane in a TabContainer or StackContainer.
+	//		TabController also monitors the TabContainer, and whenever a pane is
+	//		added or deleted updates itself accordingly.
+	// tags:
+	//		private
+
+	templateString: "<div wairole='tablist' dojoAttachEvent='onkeypress:onkeypress'></div>",
+
+	// tabPosition: String
+	//		Defines where tabs go relative to the content.
+	//		"top", "bottom", "left-h", "right-h"
+	tabPosition: "top",
+
+	// doLayout: Boolean
+	//		TODO: unused, remove
+	doLayout: true,
+
+	// buttonWidget: String
+	//		The name of the tab widget to create to correspond to each page
+	buttonWidget: "dijit.layout._TabButton",
+
+	_rectifyRtlTabList: function(){
+		//summary: Rectify the width of all tabs in rtl, otherwise the tab widths are different in IE
+		if(0 >= this.tabPosition.indexOf('-h')){ return; }
+		if(!this.pane2button){ return; }
+
+		var maxWidth = 0;
+		for(var pane in this.pane2button){
+			var ow = this.pane2button[pane].innerDiv.scrollWidth;
+			maxWidth = Math.max(maxWidth, ow);
+		}
+		//unify the length of all the tabs
+		for(pane in this.pane2button){
+			this.pane2button[pane].innerDiv.style.width = maxWidth + 'px';
+		}	
+	}
+});
+
+dojo.declare("dijit.layout._TabButton",
+	dijit.layout._StackButton,
+	{
+	// summary:
+	//		A tab (the thing you click to select a pane).
+	// description:
+	//		Contains the title of the pane, and optionally a close-button to destroy the pane.
+	//		This is an internal widget and should not be instantiated directly.
+	// tags:
+	//		private
+
+	baseClass: "dijitTab",
+
+	templateString:"<div waiRole=\"presentation\" dojoAttachEvent='onclick:onClick,onmouseenter:_onMouse,onmouseleave:_onMouse'>\n    <div waiRole=\"presentation\" class='dijitTabInnerDiv' dojoAttachPoint='innerDiv'>\n        <div waiRole=\"presentation\" class='dijitTabContent' dojoAttachPoint='tabContent'>\n\t        <span dojoAttachPoint='containerNode,focusNode' class='tabLabel'>${!label}</span><img class =\"dijitTabButtonSpacer\" src=\"${_blankGif}\" />\n\t        <span class=\"closeBu [...]
+
+	// Override _FormWidget.scrollOnFocus.
+	// Don't scroll the whole tab container into view when the button is focused.
+	scrollOnFocus: false,
+
+	postCreate: function(){
+		if(this.closeButton){
+			dojo.addClass(this.innerDiv, "dijitClosable");
+			var _nlsResources = dojo.i18n.getLocalization("dijit", "common");
+			if(this.closeNode){
+				dojo.attr(this.closeNode,"title", _nlsResources.itemClose);
+				// IE needs title set directly on image
+				dojo.attr(this.closeIcon,"title", _nlsResources.itemClose);
+			}
+		}else{
+			this.closeNode.style.display="none";		
+		}
+		this.inherited(arguments); 
+		dojo.setSelectable(this.containerNode, false);
+	},
+
+	_onCloseButtonEnter: function(){
+		// summary:
+		//		Handler when mouse is moved over the close icon (the X)
+		dojo.addClass(this.closeNode, "closeButton-hover");
+	},
+
+	_onCloseButtonLeave: function(){
+		// summary:
+		//		Handler when mouse is moved off the close icon (the X)
+		dojo.removeClass(this.closeNode, "closeButton-hover");
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit.layout.TabContainer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.layout.TabContainer"] = true;
+dojo.provide("dijit.layout.TabContainer");
+
+
+
+
+
+dojo.declare("dijit.layout.TabContainer",
+	[dijit.layout.StackContainer, dijit._Templated],
+	{	
+	// summary: 
+	//		A Container with tabs to select each child (only one of which is displayed at a time).
+	// description:
+	//		A TabContainer is a container that has multiple panes, but shows only
+	//		one pane at a time.  There are a set of tabs corresponding to each pane,
+	//		where each tab has the title (aka title) of the pane, and optionally a close button.
+	//
+	//		Publishes topics [widgetId]-addChild, [widgetId]-removeChild, and [widgetId]-selectChild
+	//		(where [widgetId] is the id of the TabContainer itself.
+
+	// tabPosition: String
+	//		Defines where tabs go relative to tab content.
+	//		"top", "bottom", "left-h", "right-h"
+	tabPosition: "top",
+
+	baseClass: "dijitTabContainer",
+	
+	// tabStrip: Boolean
+	//		Defines whether the tablist gets an extra class for layouting, putting a border/shading
+	//		around the set of tabs.
+	tabStrip: false,
+
+	// nested: Boolean
+	//		If true, use styling for a TabContainer nested inside another TabContainer.
+	//		For tundra etc., makes tabs look like links, and hides the outer
+	//		border since the outer TabContainer already has a border.
+	nested: false,
+
+	templateString: null,	// override setting in StackContainer
+	templateString:"<div class=\"dijitTabContainer\">\n\t<div dojoAttachPoint=\"tablistNode\"></div>\n\t<div dojoAttachPoint=\"tablistSpacer\" class=\"dijitTabSpacer ${baseClass}-spacer\"></div>\n\t<div class=\"dijitTabPaneWrapper ${baseClass}-container\" dojoAttachPoint=\"containerNode\"></div>\n</div>\n",
+
+	// _controllerWidget: String
+	//		An optional parameter to overrider the default TabContainer controller used.
+	_controllerWidget: "dijit.layout.TabController",
+
+	postMixInProperties: function(){
+		// set class name according to tab position, ex: dijiTabContainerTop
+		this.baseClass += this.tabPosition.charAt(0).toUpperCase() + this.tabPosition.substr(1).replace(/-.*/, "");
+		this.inherited(arguments);
+	},
+
+	postCreate: function(){
+		this.inherited(arguments);
+
+		// create the tab list that will have a tab (a.k.a. tab button) for each tab panel
+		var TabController = dojo.getObject(this._controllerWidget);
+		this.tablist = new TabController({
+			id: this.id + "_tablist",
+			tabPosition: this.tabPosition,
+			doLayout: this.doLayout,
+			containerId: this.id,
+			"class": this.baseClass + "-tabs" + (this.doLayout ? "" : " dijitTabNoLayout")
+		}, this.tablistNode);
+		
+		// add Class for tabstrip
+		if (this.tabStrip){	dojo.addClass(this.tablist.domNode, this.baseClass+"Strip"); }		
+		
+		if(!this.doLayout){ dojo.addClass(this.domNode, "dijitTabContainerNoLayout"); }
+		
+		if(this.nested){
+			/* workaround IE's lack of support for "a > b" selectors by
+			 * tagging each node in the template.
+			 */
+			dojo.addClass(this.domNode, "dijitTabContainerNested");
+			dojo.addClass(this.tablist.domNode, "dijitTabContainerTabListNested");
+			dojo.addClass(this.tablistSpacer, "dijitTabContainerSpacerNested");
+			dojo.addClass(this.containerNode, "dijitTabPaneWrapperNested");
+		}
+	},
+
+	_setupChild: function(/* Widget */tab){
+		// Overrides StackContainer._setupChild().
+		dojo.addClass(tab.domNode, "dijitTabPane");
+		this.inherited(arguments);
+		return tab; // Widget		(TODO: remove this, return code is unused)
+	},
+
+	startup: function(){
+		if(this._started){ return; }
+
+		// wire up the tablist and its tabs
+		this.tablist.startup();
+		this.inherited(arguments);
+	},
+
+	layout: function(){
+		// Overrides StackContainer.layout().
+		// Configure the content pane to take up all the space except for where the tabs are
+		if(!this.doLayout){ return; }
+
+		// position and size the titles and the container node
+		var titleAlign = this.tabPosition.replace(/-h/,"");
+		var children = [
+			{ domNode: this.tablist.domNode, layoutAlign: titleAlign },
+			{ domNode: this.tablistSpacer, layoutAlign: titleAlign },
+			{ domNode: this.containerNode, layoutAlign: "client" }
+		];
+		dijit.layout.layoutChildren(this.domNode, this._contentBox, children);
+
+		// Compute size to make each of my children.
+		// children[2] is the margin-box size of this.containerNode, set by layoutChildren() call above
+		this._containerContentBox = dijit.layout.marginBox2contentBox(this.containerNode, children[2]);
+
+		if(this.selectedChildWidget){
+			this._showChild(this.selectedChildWidget);
+			if(this.doLayout && this.selectedChildWidget.resize){
+				this.selectedChildWidget.resize(this._containerContentBox);
+			}
+		}
+	},
+
+	destroy: function(){
+		if(this.tablist){
+			this.tablist.destroy();
+		}
+		this.inherited(arguments);
+	}
+});
+
+
+}
+
+if(!dojo._hasResource["dijit.dijit-all"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.dijit-all"] = true;
+console.warn("dijit-all may include much more code than your application actually requires. We strongly recommend that you investigate a custom build or the web build tool");
+dojo.provide("dijit.dijit-all");
+
+/*=====
+dijit["dijit-all"] = { 
+	// summary: A rollup that includes every dijit. You probably don't need this.
+};
+=====*/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// slider files
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ //deprecated
+
+ //deprecated
+
+
+
+
+}
+
+
+dojo.i18n._preloadLocalizations("dijit.nls.dijit-all", ["ROOT","ar","ca","cs","da","de","de-de","el","en","en-gb","en-us","es","es-es","fi","fi-fi","fr","fr-fr","he","he-il","hu","it","it-it","ja","ja-jp","ko","ko-kr","nl","nl-nl","no","pl","pt","pt-br","pt-pt","ru","sk","sl","sv","th","tr","xx","zh","zh-cn","zh-tw"]);
diff --git a/dijit/dijit.js b/dijit/dijit.js
new file mode 100644
index 0000000..a2dbbde
--- /dev/null
+++ b/dijit/dijit.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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 a compiled version of Dojo, built for deployment and not for
+	development. To get an editable version, please visit:
+
+		http://dojotoolkit.org
+
+	for documentation and information on getting the source.
+*/
+
+if(!dojo._hasResource["dijit._base.focus"]){dojo._hasResource["dijit._base.focus"]=true;dojo.provide("dijit._base.focus");dojo.mixin(dijit,{_curFocus:null,_prevFocus:null,isCollapsed:function(){var _1=dojo.doc;if(_1.selection){var s=_1.selection;if(s.type=="Text"){return !s.createRange().htmlText.length;}else{return !s.createRange().length;}}else{var _3=dojo.global;var _4=_3.getSelection();if(dojo.isString(_4)){return !_4;}else{return !_4||_4.isCollapsed||!_4.toString();}}},getBookmark:f [...]
diff --git a/dijit/dijit.js.uncompressed.js b/dijit/dijit.js.uncompressed.js
new file mode 100644
index 0000000..868dd5f
--- /dev/null
+++ b/dijit/dijit.js.uncompressed.js
@@ -0,0 +1,4977 @@
+/*
+	Copyright (c) 2004-2009, 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 a compiled version of Dojo, built for deployment and not for
+	development. To get an editable version, please visit:
+
+		http://dojotoolkit.org
+
+	for documentation and information on getting the source.
+*/
+
+if(!dojo._hasResource["dijit._base.focus"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.focus"] = true;
+dojo.provide("dijit._base.focus");
+
+// summary:
+//		These functions are used to query or set the focus and selection.
+//
+//		Also, they trace when widgets become actived/deactivated,
+//		so that the widget can fire _onFocus/_onBlur events.
+//		"Active" here means something similar to "focused", but
+//		"focus" isn't quite the right word because we keep track of
+//		a whole stack of "active" widgets.  Example:  Combobutton --> Menu -->
+//		MenuItem.   The onBlur event for Combobutton doesn't fire due to focusing
+//		on the Menu or a MenuItem, since they are considered part of the
+//		Combobutton widget.  It only happens when focus is shifted
+//		somewhere completely different.
+
+dojo.mixin(dijit,
+{
+	// _curFocus: DomNode
+	//		Currently focused item on screen
+	_curFocus: null,
+
+	// _prevFocus: DomNode
+	//		Previously focused item on screen
+	_prevFocus: null,
+
+	isCollapsed: function(){
+		// summary:
+		//		Returns true if there is no text selected
+		var _document = dojo.doc;
+		if(_document.selection){ // IE
+			var s=_document.selection;
+			if(s.type=='Text'){
+				return !s.createRange().htmlText.length; // Boolean
+			}else{ //Control range
+				return !s.createRange().length; // Boolean
+			}
+		}else{
+			var _window = dojo.global;
+			var selection = _window.getSelection();
+			
+			if(dojo.isString(selection)){ // Safari
+				// TODO: this is dead code; safari is taking the else branch.  remove after 1.3.
+				return !selection; // Boolean
+			}else{ // Mozilla/W3
+				return !selection || selection.isCollapsed || !selection.toString(); // Boolean
+			}
+		}
+	},
+
+	getBookmark: function(){
+		// summary:
+		//		Retrieves a bookmark that can be used with moveToBookmark to return to the same range
+		var bookmark, selection = dojo.doc.selection;
+		if(selection){ // IE
+			var range = selection.createRange();
+			if(selection.type.toUpperCase()=='CONTROL'){
+				if(range.length){
+					bookmark=[];
+					var i=0,len=range.length;
+					while(i<len){
+						bookmark.push(range.item(i++));
+					}
+				}else{
+					bookmark=null;
+				}
+			}else{
+				bookmark = range.getBookmark();
+			}
+		}else{
+			if(window.getSelection){
+				selection = dojo.global.getSelection();
+				if(selection){
+					range = selection.getRangeAt(0);
+					bookmark = range.cloneRange();
+				}
+			}else{
+				console.warn("No idea how to store the current selection for this browser!");
+			}
+		}
+		return bookmark; // Array
+	},
+
+	moveToBookmark: function(/*Object*/bookmark){
+		// summary:
+		//		Moves current selection to a bookmark
+		// bookmark:
+		//		This should be a returned object from dojo.html.selection.getBookmark()
+		var _document = dojo.doc;
+		if(_document.selection){ // IE
+			var range;
+			if(dojo.isArray(bookmark)){
+				range = _document.body.createControlRange();
+				//range.addElement does not have call/apply method, so can not call it directly
+				//range is not available in "range.addElement(item)", so can't use that either
+				dojo.forEach(bookmark, function(n){
+					range.addElement(n);
+				});
+			}else{
+				range = _document.selection.createRange();
+				range.moveToBookmark(bookmark);
+			}
+			range.select();
+		}else{ //Moz/W3C
+			var selection = dojo.global.getSelection && dojo.global.getSelection();
+			if(selection && selection.removeAllRanges){
+				selection.removeAllRanges();
+				selection.addRange(bookmark);
+			}else{
+				console.warn("No idea how to restore selection for this browser!");
+			}
+		}
+	},
+
+	getFocus: function(/*Widget?*/menu, /*Window?*/openedForWindow){
+		// summary:
+		//		Returns the current focus and selection.
+		//		Called when a popup appears (either a top level menu or a dialog),
+		//		or when a toolbar/menubar receives focus
+		//
+		// menu:
+		//		The menu that's being opened
+		//
+		// openedForWindow:
+		//		iframe in which menu was opened
+		//
+		// returns:
+		//		A handle to restore focus/selection
+
+		return {
+			// Node to return focus to
+			node: menu && dojo.isDescendant(dijit._curFocus, menu.domNode) ? dijit._prevFocus : dijit._curFocus,
+
+			// Previously selected text
+			bookmark:
+				!dojo.withGlobal(openedForWindow||dojo.global, dijit.isCollapsed) ?
+				dojo.withGlobal(openedForWindow||dojo.global, dijit.getBookmark) :
+				null,
+
+			openedForWindow: openedForWindow
+		}; // Object
+	},
+
+	focus: function(/*Object || DomNode */ handle){
+		// summary:
+		//		Sets the focused node and the selection according to argument.
+		//		To set focus to an iframe's content, pass in the iframe itself.
+		// handle:
+		//		object returned by get(), or a DomNode
+
+		if(!handle){ return; }
+
+		var node = "node" in handle ? handle.node : handle,		// because handle is either DomNode or a composite object
+			bookmark = handle.bookmark,
+			openedForWindow = handle.openedForWindow;
+
+		// Set the focus
+		// Note that for iframe's we need to use the <iframe> to follow the parentNode chain,
+		// but we need to set focus to iframe.contentWindow
+		if(node){
+			var focusNode = (node.tagName.toLowerCase()=="iframe") ? node.contentWindow : node;
+			if(focusNode && focusNode.focus){
+				try{
+					// Gecko throws sometimes if setting focus is impossible,
+					// node not displayed or something like that
+					focusNode.focus();
+				}catch(e){/*quiet*/}
+			}			
+			dijit._onFocusNode(node);
+		}
+
+		// set the selection
+		// do not need to restore if current selection is not empty
+		// (use keyboard to select a menu item)
+		if(bookmark && dojo.withGlobal(openedForWindow||dojo.global, dijit.isCollapsed)){
+			if(openedForWindow){
+				openedForWindow.focus();
+			}
+			try{
+				dojo.withGlobal(openedForWindow||dojo.global, dijit.moveToBookmark, null, [bookmark]);
+			}catch(e){
+				/*squelch IE internal error, see http://trac.dojotoolkit.org/ticket/1984 */
+			}
+		}
+	},
+
+	// _activeStack: Array
+	//		List of currently active widgets (focused widget and it's ancestors)
+	_activeStack: [],
+
+	registerIframe: function(/*DomNode*/ iframe){
+		// summary:
+		//		Registers listeners on the specified iframe so that any click
+		//		or focus event on that iframe (or anything in it) is reported
+		//		as a focus/click event on the <iframe> itself.
+		// description:
+		//		Currently only used by editor.
+		dijit.registerWin(iframe.contentWindow, iframe);
+	},
+		
+
+	registerWin: function(/*Window?*/targetWindow, /*DomNode?*/ effectiveNode){
+		// summary:
+		//		Registers listeners on the specified window (either the main
+		//		window or an iframe's window) to detect when the user has clicked somewhere
+		//		or focused somewhere.
+		// description:
+		//		Users should call registerIframe() instead of this method.
+		// targetWindow:
+		//		If specified this is the window associated with the iframe,
+		//		i.e. iframe.contentWindow.
+		// effectiveNode:
+		//		If specified, report any focus events inside targetWindow as
+		//		an event on effectiveNode, rather than on evt.target.
+
+		// TODO: make this function private in 2.0; Editor/users should call registerIframe(),
+		// or if Editor stops using <iframe> altogether than we can probably just drop
+		// the whole public API.
+
+		dojo.connect(targetWindow.document, "onmousedown", function(evt){
+			dijit._justMouseDowned = true;
+			setTimeout(function(){ dijit._justMouseDowned = false; }, 0);
+			dijit._onTouchNode(effectiveNode||evt.target||evt.srcElement);
+		});
+		//dojo.connect(targetWindow, "onscroll", ???);
+
+		// Listen for blur and focus events on targetWindow's document.
+		// IIRC, I'm using attachEvent() rather than dojo.connect() because focus/blur events don't bubble
+		// through dojo.connect(), and also maybe to catch the focus events early, before onfocus handlers
+		// fire.
+		var doc = targetWindow.document;
+		if(doc){
+			if(dojo.isIE){
+				doc.attachEvent('onactivate', function(evt){
+					if(evt.srcElement.tagName.toLowerCase() != "#document"){
+						dijit._onFocusNode(effectiveNode||evt.srcElement);
+					}
+				});
+				doc.attachEvent('ondeactivate', function(evt){
+					dijit._onBlurNode(effectiveNode||evt.srcElement);
+				});
+			}else{
+				doc.addEventListener('focus', function(evt){
+					dijit._onFocusNode(effectiveNode||evt.target);
+				}, true);
+				doc.addEventListener('blur', function(evt){
+					dijit._onBlurNode(effectiveNode||evt.target);
+				}, true);
+			}
+		}
+		doc = null;	// prevent memory leak (apparent circular reference via closure)
+	},
+
+	_onBlurNode: function(/*DomNode*/ node){
+		// summary:
+		// 		Called when focus leaves a node.
+		//		Usually ignored, _unless_ it *isn't* follwed by touching another node,
+		//		which indicates that we tabbed off the last field on the page,
+		//		in which case every widget is marked inactive
+		dijit._prevFocus = dijit._curFocus;
+		dijit._curFocus = null;
+
+		if(dijit._justMouseDowned){
+			// the mouse down caused a new widget to be marked as active; this blur event
+			// is coming late, so ignore it.
+			return;
+		}
+
+		// if the blur event isn't followed by a focus event then mark all widgets as inactive.
+		if(dijit._clearActiveWidgetsTimer){
+			clearTimeout(dijit._clearActiveWidgetsTimer);
+		}
+		dijit._clearActiveWidgetsTimer = setTimeout(function(){
+			delete dijit._clearActiveWidgetsTimer;
+			dijit._setStack([]);
+			dijit._prevFocus = null;
+		}, 100);
+	},
+
+	_onTouchNode: function(/*DomNode*/ node){
+		// summary:
+		//		Callback when node is focused or mouse-downed
+
+		// ignore the recent blurNode event
+		if(dijit._clearActiveWidgetsTimer){
+			clearTimeout(dijit._clearActiveWidgetsTimer);
+			delete dijit._clearActiveWidgetsTimer;
+		}
+
+		// compute stack of active widgets (ex: ComboButton --> Menu --> MenuItem)
+		var newStack=[];
+		try{
+			while(node){
+				if(node.dijitPopupParent){
+					node=dijit.byId(node.dijitPopupParent).domNode;
+				}else if(node.tagName && node.tagName.toLowerCase()=="body"){
+					// is this the root of the document or just the root of an iframe?
+					if(node===dojo.body()){
+						// node is the root of the main document
+						break;
+					}
+					// otherwise, find the iframe this node refers to (can't access it via parentNode,
+					// need to do this trick instead). window.frameElement is supported in IE/FF/Webkit
+					node=dijit.getDocumentWindow(node.ownerDocument).frameElement;
+				}else{
+					var id = node.getAttribute && node.getAttribute("widgetId");
+					if(id){
+						newStack.unshift(id);
+					}
+					node=node.parentNode;
+				}
+			}
+		}catch(e){ /* squelch */ }
+
+		dijit._setStack(newStack);
+	},
+
+	_onFocusNode: function(/*DomNode*/ node){
+		// summary:
+		//		Callback when node is focused
+
+		if(!node){
+			return;
+		}
+
+		if(node.nodeType == 9){
+			// Ignore focus events on the document itself.  This is here so that
+			// (for example) clicking the up/down arrows of a spinner
+			// (which don't get focus) won't cause that widget to blur. (FF issue)
+			return;
+		}
+
+		dijit._onTouchNode(node);
+
+		if(node==dijit._curFocus){ return; }
+		if(dijit._curFocus){
+			dijit._prevFocus = dijit._curFocus;
+		}
+		dijit._curFocus = node;
+		dojo.publish("focusNode", [node]);
+	},
+
+	_setStack: function(newStack){
+		// summary:
+		//		The stack of active widgets has changed.  Send out appropriate events and records new stack.
+
+		var oldStack = dijit._activeStack;
+		dijit._activeStack = newStack;
+
+		// compare old stack to new stack to see how many elements they have in common
+		for(var nCommon=0; nCommon<Math.min(oldStack.length, newStack.length); nCommon++){
+			if(oldStack[nCommon] != newStack[nCommon]){
+				break;
+			}
+		}
+
+		// for all elements that have gone out of focus, send blur event
+		for(var i=oldStack.length-1; i>=nCommon; i--){
+			var widget = dijit.byId(oldStack[i]);
+			if(widget){
+				widget._focused = false;
+				widget._hasBeenBlurred = true;
+				if(widget._onBlur){
+					widget._onBlur();
+				}
+				if (widget._setStateClass){
+					widget._setStateClass();
+				}
+				dojo.publish("widgetBlur", [widget]);
+			}
+		}
+
+		// for all element that have come into focus, send focus event
+		for(i=nCommon; i<newStack.length; i++){
+			widget = dijit.byId(newStack[i]);
+			if(widget){
+				widget._focused = true;
+				if(widget._onFocus){
+					widget._onFocus();
+				}
+				if (widget._setStateClass){
+					widget._setStateClass();
+				}
+				dojo.publish("widgetFocus", [widget]);
+			}
+		}
+	}
+});
+
+// register top window and all the iframes it contains
+dojo.addOnLoad(function(){dijit.registerWin(window); });
+
+}
+
+if(!dojo._hasResource["dijit._base.manager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.manager"] = true;
+dojo.provide("dijit._base.manager");
+
+dojo.declare("dijit.WidgetSet", null, {
+	// summary:
+	//		A set of widgets indexed by id. A default instance of this class is 
+	//		available as `dijit.registry`
+	//
+	// example:
+	//		Create a small list of widgets:
+	//		|	var ws = new dijit.WidgetSet();
+	//		|	ws.add(dijit.byId("one"));
+	//		| 	ws.add(dijit.byId("two"));
+	//		|	// destroy both:
+	//		|	ws.forEach(function(w){ w.destroy(); });
+	//
+	// example:
+	//		Using dijit.registry:
+	//		|	dijit.registry.forEach(function(w){ /* do something */ });
+	
+	constructor: function(){
+		this._hash = {};
+	},
+
+	add: function(/*Widget*/ widget){
+		// summary:
+		//		Add a widget to this list. If a duplicate ID is detected, a error is thrown.
+		//
+		// widget: dijit._Widget
+		//		Any dijit._Widget subclass.
+		if(this._hash[widget.id]){
+			throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered");
+		}
+		this._hash[widget.id]=widget;
+	},
+
+	remove: function(/*String*/ id){
+		// summary:
+		//		Remove a widget from this WidgetSet. Does not destroy the widget; simply
+		//		removes the reference.
+		delete this._hash[id];
+	},
+
+	forEach: function(/*Function*/ func){
+		// summary:
+		//		Call specified function for each widget in this set.
+		//
+		// func:
+		//		A callback function to run for each item. Is passed a the widget.
+		//
+		// example:
+		//		Using the default `dijit.registry` instance:
+		//		|	dijit.registry.forEach(function(widget){
+		//		|			
+		//		|	});
+		for(var id in this._hash){
+			func(this._hash[id]);
+		}
+	},
+
+	filter: function(/*Function*/ filter){
+		// summary:
+		//		Filter down this WidgetSet to a smaller new WidgetSet
+		//		Works the same as `dojo.filter` and `dojo.NodeList.filter`
+		//		
+		// filter:
+		//		Callback function to test truthiness.
+		//
+		// example:
+		//		Arbitrary: select the odd widgets in this list
+		//		|	var i = 0;
+		//		|	dijit.registry.filter(function(w){
+		//		|		return ++i % 2 == 0;
+		//		|	}).forEach(function(w){ /* odd ones */ });
+
+		var res = new dijit.WidgetSet();
+		this.forEach(function(widget){
+			if(filter(widget)){ res.add(widget); }
+		});
+		return res; // dijit.WidgetSet
+	},
+
+	byId: function(/*String*/ id){
+		// summary:
+		//		Find a widget in this list by it's id. 
+		// example:
+		//		Test if an id is in a particular WidgetSet
+		//		| var ws = new dijit.WidgetSet();
+		//		| ws.add(dijit.byId("bar"));
+		//		| var t = ws.byId("bar") // returns a widget
+		//		| var x = ws.byId("foo"); // returns undefined
+		
+		return this._hash[id];	// dijit._Widget
+	},
+
+	byClass: function(/*String*/ cls){
+		// summary:
+		//		Reduce this widgetset to a new WidgetSet of a particular declaredClass
+		// 
+		// example:
+		//		Find all titlePane's in a page:
+		//		|	dijit.registry.byClass("dijit.TitlePane").forEach(function(tp){ tp.close(); });
+		
+		return this.filter(function(widget){ return widget.declaredClass==cls; });	// dijit.WidgetSet
+	}
+	
+});
+
+/*=====
+dijit.registry = {
+	// summary: A list of widgets on a page.
+	// description: Is an instance of `dijit.WidgetSet`
+};
+=====*/
+dijit.registry = new dijit.WidgetSet();
+
+dijit._widgetTypeCtr = {};
+
+dijit.getUniqueId = function(/*String*/widgetType){
+	// summary: Generates a unique id for a given widgetType
+
+	var id;
+	do{
+		id = widgetType + "_" +
+			(widgetType in dijit._widgetTypeCtr ?
+				++dijit._widgetTypeCtr[widgetType] : dijit._widgetTypeCtr[widgetType] = 0);
+	}while(dijit.byId(id));
+	return id; // String
+};
+
+dijit.findWidgets = function(/*DomNode*/ root){
+	// summary:
+	//		Search subtree under root, putting found widgets in outAry.
+	//		Doesn't search for nested widgets (ie, widgets inside other widgets)
+	
+	var outAry = [];
+
+	function getChildrenHelper(root){
+		var list = dojo.isIE ? root.children : root.childNodes, i = 0, node;
+		while(node = list[i++]){
+			if(node.nodeType != 1){ continue; }
+			var widgetId = node.getAttribute("widgetId");
+			if(widgetId){
+				var widget = dijit.byId(widgetId);
+				outAry.push(widget);
+			}else{
+				getChildrenHelper(node);
+			}
+		}
+	}
+
+	getChildrenHelper(root);
+	return outAry;
+};
+
+if(dojo.isIE){
+	// Only run this for IE because we think it's only necessary in that case,
+	// and because it causes problems on FF.  See bug #3531 for details.
+	dojo.addOnWindowUnload(function(){
+		dojo.forEach(dijit.findWidgets(dojo.body()), function(widget){
+			if(widget.destroyRecursive){
+				widget.destroyRecursive();
+			}else if(widget.destroy){
+				widget.destroy();
+			}
+		});
+	});
+}
+
+dijit.byId = function(/*String|Widget*/id){
+	// summary:
+	//		Returns a widget by it's id, or if passed a widget, no-op (like dojo.byId())
+	return (dojo.isString(id)) ? dijit.registry.byId(id) : id; // Widget
+};
+
+dijit.byNode = function(/* DOMNode */ node){
+	// summary:
+	//		Returns the widget corresponding to the given DOMNode
+	return dijit.registry.byId(node.getAttribute("widgetId")); // Widget
+};
+
+dijit.getEnclosingWidget = function(/* DOMNode */ node){
+	// summary:
+	//		Returns the widget whose DOM tree contains the specified DOMNode, or null if
+	//		the node is not contained within the DOM tree of any widget
+	while(node){
+		if(node.getAttribute && node.getAttribute("widgetId")){
+			return dijit.registry.byId(node.getAttribute("widgetId"));
+		}
+		node = node.parentNode;
+	}
+	return null;
+};
+
+// elements that are tab-navigable if they have no tabindex value set
+// (except for "a", which must have an href attribute)
+dijit._tabElements = {
+	area: true,
+	button: true,
+	input: true,
+	object: true,
+	select: true,
+	textarea: true
+};
+
+dijit._isElementShown = function(/*Element*/elem){
+	var style = dojo.style(elem);
+	return (style.visibility != "hidden")
+		&& (style.visibility != "collapsed")
+		&& (style.display != "none")
+		&& (dojo.attr(elem, "type") != "hidden");
+}
+
+dijit.isTabNavigable = function(/*Element*/elem){
+	// summary:
+	//		Tests if an element is tab-navigable
+	if(dojo.hasAttr(elem, "disabled")){ return false; }
+	var hasTabindex = dojo.hasAttr(elem, "tabindex");
+	var tabindex = dojo.attr(elem, "tabindex");
+	if(hasTabindex && tabindex >= 0) {
+		return true; // boolean
+	}
+	var name = elem.nodeName.toLowerCase();
+	if(((name == "a" && dojo.hasAttr(elem, "href"))
+			|| dijit._tabElements[name])
+		&& (!hasTabindex || tabindex >= 0)){
+		return true; // boolean
+	}
+	return false; // boolean
+};
+
+dijit._getTabNavigable = function(/*DOMNode*/root){
+	// summary:
+	//		Finds descendants of the specified root node.
+	//
+	// description:
+	//		Finds the following descendants of the specified root node:
+	//		* the first tab-navigable element in document order
+	//		  without a tabindex or with tabindex="0"
+	//		* the last tab-navigable element in document order
+	//		  without a tabindex or with tabindex="0"
+	//		* the first element in document order with the lowest
+	//		  positive tabindex value
+	//		* the last element in document order with the highest
+	//		  positive tabindex value
+	var first, last, lowest, lowestTabindex, highest, highestTabindex;
+	var walkTree = function(/*DOMNode*/parent){
+		dojo.query("> *", parent).forEach(function(child){
+			var isShown = dijit._isElementShown(child);
+			if(isShown && dijit.isTabNavigable(child)){
+				var tabindex = dojo.attr(child, "tabindex");
+				if(!dojo.hasAttr(child, "tabindex") || tabindex == 0){
+					if(!first){ first = child; }
+					last = child;
+				}else if(tabindex > 0){
+					if(!lowest || tabindex < lowestTabindex){
+						lowestTabindex = tabindex;
+						lowest = child;
+					}
+					if(!highest || tabindex >= highestTabindex){
+						highestTabindex = tabindex;
+						highest = child;
+					}
+				}
+			}
+			if(isShown && child.nodeName.toUpperCase() != 'SELECT'){ walkTree(child) }
+		});
+	};
+	if(dijit._isElementShown(root)){ walkTree(root) }
+	return { first: first, last: last, lowest: lowest, highest: highest };
+}
+dijit.getFirstInTabbingOrder = function(/*String|DOMNode*/root){
+	// summary:
+	//		Finds the descendant of the specified root node
+	//		that is first in the tabbing order
+	var elems = dijit._getTabNavigable(dojo.byId(root));
+	return elems.lowest ? elems.lowest : elems.first; // DomNode
+};
+
+dijit.getLastInTabbingOrder = function(/*String|DOMNode*/root){
+	// summary:
+	//		Finds the descendant of the specified root node
+	//		that is last in the tabbing order
+	var elems = dijit._getTabNavigable(dojo.byId(root));
+	return elems.last ? elems.last : elems.highest; // DomNode
+};
+
+/*=====
+dojo.mixin(dijit, {
+	// defaultDuration: Integer
+	//		The default animation speed (in ms) to use for all Dijit
+	//		transitional animations, unless otherwise specified 
+	//		on a per-instance basis. Defaults to 200, overrided by 
+	//		`djConfig.defaultDuration`
+	defaultDuration: 300
+});
+=====*/
+
+dijit.defaultDuration = dojo.config["defaultDuration"] || 200;
+
+}
+
+if(!dojo._hasResource["dojo.AdapterRegistry"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.AdapterRegistry"] = true;
+dojo.provide("dojo.AdapterRegistry");
+
+dojo.AdapterRegistry = function(/*Boolean?*/ returnWrappers){
+	//	summary:
+	//		A registry to make contextual calling/searching easier.
+	//	description:
+	//		Objects of this class keep list of arrays in the form [name, check,
+	//		wrap, directReturn] that are used to determine what the contextual
+	//		result of a set of checked arguments is. All check/wrap functions
+	//		in this registry should be of the same arity.
+	//	example:
+	//	|	// create a new registry
+	//	|	var reg = new dojo.AdapterRegistry();
+	//	|	reg.register("handleString",
+	//	|		dojo.isString,
+	//	|		function(str){
+	//	|			// do something with the string here
+	//	|		}
+	//	|	);
+	//	|	reg.register("handleArr",
+	//	|		dojo.isArray,
+	//	|		function(arr){
+	//	|			// do something with the array here
+	//	|		}
+	//	|	);
+	//	|
+	//	|	// now we can pass reg.match() *either* an array or a string and
+	//	|	// the value we pass will get handled by the right function
+	//	|	reg.match("someValue"); // will call the first function
+	//	|	reg.match(["someValue"]); // will call the second
+
+	this.pairs = [];
+	this.returnWrappers = returnWrappers || false; // Boolean
+}
+
+dojo.extend(dojo.AdapterRegistry, {
+	register: function(/*String*/ name, /*Function*/ check, /*Function*/ wrap, /*Boolean?*/ directReturn, /*Boolean?*/ override){
+		//	summary: 
+		//		register a check function to determine if the wrap function or
+		//		object gets selected
+		//	name:
+		//		a way to identify this matcher.
+		//	check:
+		//		a function that arguments are passed to from the adapter's
+		//		match() function.  The check function should return true if the
+		//		given arguments are appropriate for the wrap function.
+		//	directReturn:
+		//		If directReturn is true, the value passed in for wrap will be
+		//		returned instead of being called. Alternately, the
+		//		AdapterRegistry can be set globally to "return not call" using
+		//		the returnWrappers property. Either way, this behavior allows
+		//		the registry to act as a "search" function instead of a
+		//		function interception library.
+		//	override:
+		//		If override is given and true, the check function will be given
+		//		highest priority. Otherwise, it will be the lowest priority
+		//		adapter.
+		this.pairs[((override) ? "unshift" : "push")]([name, check, wrap, directReturn]);
+	},
+
+	match: function(/* ... */){
+		// summary:
+		//		Find an adapter for the given arguments. If no suitable adapter
+		//		is found, throws an exception. match() accepts any number of
+		//		arguments, all of which are passed to all matching functions
+		//		from the registered pairs.
+		for(var i = 0; i < this.pairs.length; i++){
+			var pair = this.pairs[i];
+			if(pair[1].apply(this, arguments)){
+				if((pair[3])||(this.returnWrappers)){
+					return pair[2];
+				}else{
+					return pair[2].apply(this, arguments);
+				}
+			}
+		}
+		throw new Error("No match found");
+	},
+
+	unregister: function(name){
+		// summary: Remove a named adapter from the registry
+
+		// FIXME: this is kind of a dumb way to handle this. On a large
+		// registry this will be slow-ish and we can use the name as a lookup
+		// should we choose to trade memory for speed.
+		for(var i = 0; i < this.pairs.length; i++){
+			var pair = this.pairs[i];
+			if(pair[0] == name){
+				this.pairs.splice(i, 1);
+				return true;
+			}
+		}
+		return false;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit._base.place"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.place"] = true;
+dojo.provide("dijit._base.place");
+
+
+
+// ported from dojo.html.util
+
+dijit.getViewport = function(){
+	// summary:
+	//		Returns the dimensions and scroll position of the viewable area of a browser window
+
+	var scrollRoot = (dojo.doc.compatMode == 'BackCompat')? dojo.body() : dojo.doc.documentElement;
+
+	// get scroll position
+	var scroll = dojo._docScroll(); // scrollRoot.scrollTop/Left should work
+	return { w: scrollRoot.clientWidth, h: scrollRoot.clientHeight, l: scroll.x, t: scroll.y };
+};
+
+/*=====
+dijit.__Position = function(){
+	// x: Integer
+	//		horizontal coordinate in pixels, relative to document body
+	// y: Integer
+	//		vertical coordinate in pixels, relative to document body
+
+	thix.x = x;
+	this.y = y;
+}
+=====*/
+
+
+dijit.placeOnScreen = function(
+	/* DomNode */			node,
+	/* dijit.__Position */	pos,
+	/* String[] */			corners,
+	/* dijit.__Position? */	padding){
+	//	summary:
+	//		Positions one of the node's corners at specified position
+	//		such that node is fully visible in viewport.
+	//	description:
+	//		NOTE: node is assumed to be absolutely or relatively positioned.
+	//	pos:
+	//		Object like {x: 10, y: 20}
+	//	corners:
+	//		Array of Strings representing order to try corners in, like ["TR", "BL"].
+	//		Possible values are:
+	//			* "BL" - bottom left
+	//			* "BR" - bottom right
+	//			* "TL" - top left
+	//			* "TR" - top right
+	//	padding:
+	//		set padding to put some buffer around the element you want to position.
+	//	example:	
+	//		Try to place node's top right corner at (10,20).
+	//		If that makes node go (partially) off screen, then try placing
+	//		bottom left corner at (10,20).
+	//	|	placeOnScreen(node, {x: 10, y: 20}, ["TR", "BL"])
+
+	var choices = dojo.map(corners, function(corner){
+		var c = { corner: corner, pos: {x:pos.x,y:pos.y} };
+		if(padding){
+			c.pos.x += corner.charAt(1) == 'L' ? padding.x : -padding.x;
+			c.pos.y += corner.charAt(0) == 'T' ? padding.y : -padding.y;
+		}
+		return c; 
+	});
+
+	return dijit._place(node, choices);
+}
+
+dijit._place = function(/*DomNode*/ node, /* Array */ choices, /* Function */ layoutNode){
+	// summary:
+	//		Given a list of spots to put node, put it at the first spot where it fits,
+	//		of if it doesn't fit anywhere then the place with the least overflow
+	// choices: Array
+	//		Array of elements like: {corner: 'TL', pos: {x: 10, y: 20} }
+	//		Above example says to put the top-left corner of the node at (10,20)
+	// layoutNode: Function(node, aroundNodeCorner, nodeCorner)
+	//		for things like tooltip, they are displayed differently (and have different dimensions)
+	//		based on their orientation relative to the parent.   This adjusts the popup based on orientation.
+
+	// get {x: 10, y: 10, w: 100, h:100} type obj representing position of
+	// viewport over document
+	var view = dijit.getViewport();
+
+	// This won't work if the node is inside a <div style="position: relative">,
+	// so reattach it to dojo.doc.body.   (Otherwise, the positioning will be wrong
+	// and also it might get cutoff)
+	if(!node.parentNode || String(node.parentNode.tagName).toLowerCase() != "body"){
+		dojo.body().appendChild(node);
+	}
+
+	var best = null;
+	dojo.some(choices, function(choice){
+		var corner = choice.corner;
+		var pos = choice.pos;
+
+		// configure node to be displayed in given position relative to button
+		// (need to do this in order to get an accurate size for the node, because
+		// a tooltips size changes based on position, due to triangle)
+		if(layoutNode){
+			layoutNode(node, choice.aroundCorner, corner);
+		}
+
+		// get node's size
+		var style = node.style;
+		var oldDisplay = style.display;
+		var oldVis = style.visibility;
+		style.visibility = "hidden";
+		style.display = "";
+		var mb = dojo.marginBox(node);
+		style.display = oldDisplay;
+		style.visibility = oldVis;
+
+		// coordinates and size of node with specified corner placed at pos,
+		// and clipped by viewport
+		var startX = (corner.charAt(1) == 'L' ? pos.x : Math.max(view.l, pos.x - mb.w)),
+			startY = (corner.charAt(0) == 'T' ? pos.y : Math.max(view.t, pos.y -  mb.h)),
+			endX = (corner.charAt(1) == 'L' ? Math.min(view.l + view.w, startX + mb.w) : pos.x),
+			endY = (corner.charAt(0) == 'T' ? Math.min(view.t + view.h, startY + mb.h) : pos.y),
+			width = endX - startX,
+			height = endY - startY,
+			overflow = (mb.w - width) + (mb.h - height);
+
+		if(best == null || overflow < best.overflow){
+			best = {
+				corner: corner,
+				aroundCorner: choice.aroundCorner,
+				x: startX,
+				y: startY,
+				w: width,
+				h: height,
+				overflow: overflow
+			};
+		}
+		return !overflow;
+	});
+
+	node.style.left = best.x + "px";
+	node.style.top = best.y + "px";
+	if(best.overflow && layoutNode){
+		layoutNode(node, best.aroundCorner, best.corner);
+	}
+	return best;
+}
+
+dijit.placeOnScreenAroundNode = function(
+	/* DomNode */		node,
+	/* DomNode */		aroundNode,
+	/* Object */		aroundCorners,
+	/* Function? */		layoutNode){
+
+	// summary:
+	//		Position node adjacent or kitty-corner to aroundNode
+	//		such that it's fully visible in viewport.
+	//
+	// description:
+	//		Place node such that corner of node touches a corner of
+	//		aroundNode, and that node is fully visible.
+	//
+	// aroundCorners:
+	//		Ordered list of pairs of corners to try matching up.
+	//		Each pair of corners is represented as a key/value in the hash,
+	//		where the key corresponds to the aroundNode's corner, and
+	//		the value corresponds to the node's corner:
+	//
+	//	|	{ aroundNodeCorner1: nodeCorner1, aroundNodeCorner2: nodeCorner2,  ...}
+	//
+	//		The following strings are used to represent the four corners:
+	//			* "BL" - bottom left
+	//			* "BR" - bottom right
+	//			* "TL" - top left
+	//			* "TR" - top right
+	//
+	// layoutNode: Function(node, aroundNodeCorner, nodeCorner)
+	//		For things like tooltip, they are displayed differently (and have different dimensions)
+	//		based on their orientation relative to the parent.   This adjusts the popup based on orientation.
+	//
+	// example:
+	//	|	dijit.placeOnScreenAroundNode(node, aroundNode, {'BL':'TL', 'TR':'BR'}); 
+	//		This will try to position node such that node's top-left corner is at the same position
+	//		as the bottom left corner of the aroundNode (ie, put node below
+	//		aroundNode, with left edges aligned).  If that fails it will try to put
+	// 		the bottom-right corner of node where the top right corner of aroundNode is
+	//		(ie, put node above aroundNode, with right edges aligned)
+	//
+
+	// get coordinates of aroundNode
+	aroundNode = dojo.byId(aroundNode);
+	var oldDisplay = aroundNode.style.display;
+	aroundNode.style.display="";
+	// #3172: use the slightly tighter border box instead of marginBox
+	var aroundNodeW = aroundNode.offsetWidth; //mb.w; 
+	var aroundNodeH = aroundNode.offsetHeight; //mb.h;
+	var aroundNodePos = dojo.coords(aroundNode, true);
+	aroundNode.style.display=oldDisplay;
+
+	// place the node around the calculated rectangle
+	return dijit._placeOnScreenAroundRect(node, 
+		aroundNodePos.x, aroundNodePos.y, aroundNodeW, aroundNodeH,	// rectangle
+		aroundCorners, layoutNode);
+};
+
+/*=====
+dijit.__Rectangle = function(){
+	// x: Integer
+	//		horizontal offset in pixels, relative to document body
+	// y: Integer
+	//		vertical offset in pixels, relative to document body
+	// width: Integer
+	//		width in pixels
+	// height: Integer
+	//		height in pixels
+
+	thix.x = x;
+	this.y = y;
+	thix.width = width;
+	this.height = height;
+}
+=====*/
+
+
+dijit.placeOnScreenAroundRectangle = function(
+	/* DomNode */			node,
+	/* dijit.__Rectangle */	aroundRect,
+	/* Object */			aroundCorners,
+	/* Function */			layoutNode){
+
+	// summary:
+	//		Like dijit.placeOnScreenAroundNode(), except that the "around"
+	//		parameter is an arbitrary rectangle on the screen (x, y, width, height)
+	//		instead of a dom node.
+
+	return dijit._placeOnScreenAroundRect(node, 
+		aroundRect.x, aroundRect.y, aroundRect.width, aroundRect.height,	// rectangle
+		aroundCorners, layoutNode);
+};
+
+dijit._placeOnScreenAroundRect = function(
+	/* DomNode */		node,
+	/* Number */		x,
+	/* Number */		y,
+	/* Number */		width,
+	/* Number */		height,
+	/* Object */		aroundCorners,
+	/* Function */		layoutNode){
+
+	// summary:
+	//		Like dijit.placeOnScreenAroundNode(), except it accepts coordinates
+	//		of a rectangle to place node adjacent to.
+
+	// TODO: combine with placeOnScreenAroundRectangle()
+
+	// Generate list of possible positions for node
+	var choices = [];
+	for(var nodeCorner in aroundCorners){
+		choices.push( {
+			aroundCorner: nodeCorner,
+			corner: aroundCorners[nodeCorner],
+			pos: {
+				x: x + (nodeCorner.charAt(1) == 'L' ? 0 : width),
+				y: y + (nodeCorner.charAt(0) == 'T' ? 0 : height)
+			}
+		});
+	}
+
+	return dijit._place(node, choices, layoutNode);
+};
+
+dijit.placementRegistry = new dojo.AdapterRegistry();
+dijit.placementRegistry.register("node",
+	function(n, x){
+		return typeof x == "object" &&
+			typeof x.offsetWidth != "undefined" && typeof x.offsetHeight != "undefined";
+	},
+	dijit.placeOnScreenAroundNode);
+dijit.placementRegistry.register("rect",
+	function(n, x){
+		return typeof x == "object" &&
+			"x" in x && "y" in x && "width" in x && "height" in x;
+	},
+	dijit.placeOnScreenAroundRectangle);
+
+dijit.placeOnScreenAroundElement = function(
+	/* DomNode */		node,
+	/* Object */		aroundElement,
+	/* Object */		aroundCorners,
+	/* Function */		layoutNode){
+
+	// summary:
+	//		Like dijit.placeOnScreenAroundNode(), except it accepts an arbitrary object
+	//		for the "around" argument and finds a proper processor to place a node.
+
+	return dijit.placementRegistry.match.apply(dijit.placementRegistry, arguments);
+};
+
+}
+
+if(!dojo._hasResource["dijit._base.window"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.window"] = true;
+dojo.provide("dijit._base.window");
+
+// TODO: remove this in 2.0, it's not used anymore, or at least not internally
+
+dijit.getDocumentWindow = function(doc){
+	// summary:
+	// 		Get window object associated with document doc
+
+	// In some IE versions (at least 6.0), document.parentWindow does not return a
+	// reference to the real window object (maybe a copy), so we must fix it as well
+	// We use IE specific execScript to attach the real window reference to
+	// document._parentWindow for later use
+	if(dojo.isIE && window !== document.parentWindow && !doc._parentWindow){
+		/*
+		In IE 6, only the variable "window" can be used to connect events (others
+		may be only copies).
+		*/
+		doc.parentWindow.execScript("document._parentWindow = window;", "Javascript");
+		//to prevent memory leak, unset it after use
+		//another possibility is to add an onUnload handler which seems overkill to me (liucougar)
+		var win = doc._parentWindow;
+		doc._parentWindow = null;
+		return win;	//	Window
+	}
+
+	return doc._parentWindow || doc.parentWindow || doc.defaultView;	//	Window
+}
+
+}
+
+if(!dojo._hasResource["dijit._base.popup"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.popup"] = true;
+dojo.provide("dijit._base.popup");
+
+
+
+
+
+dijit.popup = new function(){
+	// summary:
+	//		This class is used to show/hide widgets as popups.
+
+	var stack = [],
+		beginZIndex=1000,
+		idGen = 1;
+
+	this.prepare = function(/*DomNode*/ node){
+		// summary:
+		//		Prepares a node to be used as a popup
+		//
+		// description:
+		//		Attaches node to dojo.doc.body, and
+		//		positions it off screen, but not display:none, so that
+		//		the widget doesn't appear in the page flow and/or cause a blank
+		//		area at the bottom of the viewport (making scrollbar longer), but
+		//		initialization of contained widgets works correctly
+
+		var s = node.style;
+		s.visibility = "hidden";	// so TAB key doesn't navigate to hidden popup
+		s.position = "absolute";
+		s.top = "-9999px";
+		if(s.display == "none"){
+			s.display="";
+		}
+		dojo.body().appendChild(node);
+	};
+
+/*=====
+dijit.popup.__OpenArgs = function(){
+	// popup: Widget
+	//		widget to display
+	// parent: Widget
+	//		the button etc. that is displaying this popup
+	// around: DomNode
+	//		DOM node (typically a button); place popup relative to this node.  (Specify this *or* "x" and "y" parameters.)
+	// x: Integer
+	//		Absolute horizontal position (in pixels) to place node at.  (Specify this *or* "around" parameter.)
+	// y: Integer
+	//		Absolute vertical position (in pixels) to place node at.  (Specity this *or* "around" parameter.)
+	// orient: Object || String
+	//		When the around parameter is specified, orient should be an 
+	//		ordered list of tuples of the form (around-node-corner, popup-node-corner).
+	//		dijit.popup.open() tries to position the popup according to each tuple in the list, in order,
+	//		until the popup appears fully within the viewport.
+	//
+	//		The default value is {BL:'TL', TL:'BL'}, which represents a list of two tuples:
+	//			1. (BL, TL)
+	//			2. (TL, BL)
+	//		where BL means "bottom left" and "TL" means "top left".
+	//		So by default, it first tries putting the popup below the around node, left-aligning them,
+	//		and then tries to put it above the around node, still left-aligning them.   Note that the
+	//		default is horizontally reversed when in RTL mode.
+	//
+	//		When an (x,y) position is specified rather than an around node, orient is either
+	//		"R" or "L".  R (for right) means that it tries to put the popup to the right of the mouse,
+	//		specifically positioning the popup's top-right corner at the mouse position, and if that doesn't
+	//		fit in the viewport, then it tries, in order, the bottom-right corner, the top left corner,
+	//		and the top-right corner.
+	// onCancel: Function
+	//		callback when user has canceled the popup by
+	//			1. hitting ESC or
+	//			2. by using the popup widget's proprietary cancel mechanism (like a cancel button in a dialog);
+	//			   i.e. whenever popupWidget.onCancel() is called, args.onCancel is called
+	// onClose: Function
+	//		callback whenever this popup is closed
+	// onExecute: Function
+	//		callback when user "executed" on the popup/sub-popup by selecting a menu choice, etc. (top menu only)
+	// padding: dijit.__Position
+	//		adding a buffer around the opening position. This is only useful when around is not set.
+	this.popup = popup;
+	this.parent = parent;
+	this.around = around;
+	this.x = x;
+	this.y = y;
+	this.orient = orient;
+	this.onCancel = onCancel;
+	this.onClose = onClose;
+	this.onExecute = onExecute;
+	this.padding = padding;
+}
+=====*/
+	this.open = function(/*dijit.popup.__OpenArgs*/ args){
+		// summary:
+		//		Popup the widget at the specified position
+		//
+		// example:
+		//		opening at the mouse position
+		//		|		dijit.popup.open({popup: menuWidget, x: evt.pageX, y: evt.pageY});
+		//
+		// example:
+		//		opening the widget as a dropdown
+		//		|		dijit.popup.open({parent: this, popup: menuWidget, around: this.domNode, onClose: function(){...}  });
+		//
+		//		Note that whatever widget called dijit.popup.open() should also listen to its own _onBlur callback
+		//		(fired from _base/focus.js) to know that focus has moved somewhere else and thus the popup should be closed.
+
+		var widget = args.popup,
+			orient = args.orient || {'BL':'TL', 'TL':'BL'},
+			around = args.around,
+			id = (args.around && args.around.id) ? (args.around.id+"_dropdown") : ("popup_"+idGen++);
+
+		// make wrapper div to hold widget and possibly hold iframe behind it.
+		// we can't attach the iframe as a child of the widget.domNode because
+		// widget.domNode might be a <table>, <ul>, etc.
+		var wrapper = dojo.create("div",{
+			id: id, 
+			"class":"dijitPopup",
+			style:{
+				zIndex: beginZIndex + stack.length,
+				visibility:"hidden"
+			}
+		}, dojo.body());
+		dijit.setWaiRole(wrapper, "presentation");
+		
+		// prevent transient scrollbar causing misalign (#5776)
+		wrapper.style.left = wrapper.style.top = "0px";		
+
+		if(args.parent){
+			wrapper.dijitPopupParent=args.parent.id;
+		}
+
+		var s = widget.domNode.style;
+		s.display = "";
+		s.visibility = "";
+		s.position = "";
+		s.top = "0px";
+		wrapper.appendChild(widget.domNode);
+
+		var iframe = new dijit.BackgroundIframe(wrapper);
+
+		// position the wrapper node
+		var best = around ?
+			dijit.placeOnScreenAroundElement(wrapper, around, orient, widget.orient ? dojo.hitch(widget, "orient") : null) :
+			dijit.placeOnScreen(wrapper, args, orient == 'R' ? ['TR','BR','TL','BL'] : ['TL','BL','TR','BR'], args.padding);
+
+		wrapper.style.visibility = "visible";
+		// TODO: use effects to fade in wrapper
+
+		var handlers = [];
+
+		// Compute the closest ancestor popup that's *not* a child of another popup.
+		// Ex: For a TooltipDialog with a button that spawns a tree of menus, find the popup of the button.
+		var getTopPopup = function(){
+			for(var pi=stack.length-1; pi > 0 && stack[pi].parent === stack[pi-1].widget; pi--){
+				/* do nothing, just trying to get right value for pi */
+			}
+			return stack[pi];
+		}
+
+		// provide default escape and tab key handling
+		// (this will work for any widget, not just menu)
+		handlers.push(dojo.connect(wrapper, "onkeypress", this, function(evt){
+			if(evt.charOrCode == dojo.keys.ESCAPE && args.onCancel){
+				dojo.stopEvent(evt);
+				args.onCancel();
+			}else if(evt.charOrCode === dojo.keys.TAB){
+				dojo.stopEvent(evt);
+				var topPopup = getTopPopup();
+				if(topPopup && topPopup.onCancel){
+					topPopup.onCancel();
+				}
+			}
+		}));
+
+		// watch for cancel/execute events on the popup and notify the caller
+		// (for a menu, "execute" means clicking an item)
+		if(widget.onCancel){
+			handlers.push(dojo.connect(widget, "onCancel", null, args.onCancel));
+		}
+
+		handlers.push(dojo.connect(widget, widget.onExecute ? "onExecute" : "onChange", null, function(){
+			var topPopup = getTopPopup();
+			if(topPopup && topPopup.onExecute){
+				topPopup.onExecute();
+			}
+		}));
+
+		stack.push({
+			wrapper: wrapper,
+			iframe: iframe,
+			widget: widget,
+			parent: args.parent,
+			onExecute: args.onExecute,
+			onCancel: args.onCancel,
+ 			onClose: args.onClose,
+			handlers: handlers
+		});
+
+		if(widget.onOpen){
+			widget.onOpen(best);
+		}
+
+		return best;
+	};
+
+	this.close = function(/*Widget*/ popup){
+		// summary:
+		//		Close specified popup and any popups that it parented
+		while(dojo.some(stack, function(elem){return elem.widget == popup;})){
+			var top = stack.pop(),
+				wrapper = top.wrapper,
+				iframe = top.iframe,
+				widget = top.widget,
+				onClose = top.onClose;
+	
+			if(widget.onClose){
+				widget.onClose();
+			}
+			dojo.forEach(top.handlers, dojo.disconnect);
+	
+			// #2685: check if the widget still has a domNode so ContentPane can change its URL without getting an error
+			if(!widget||!widget.domNode){ return; }
+			
+			this.prepare(widget.domNode);
+
+			iframe.destroy();
+			dojo.destroy(wrapper);
+	
+			if(onClose){
+				onClose();
+			}
+		}
+	};
+}();
+
+dijit._frames = new function(){
+	// summary: cache of iframes
+	var queue = [];
+
+	this.pop = function(){
+		var iframe;
+		if(queue.length){
+			iframe = queue.pop();
+			iframe.style.display="";
+		}else{
+			if(dojo.isIE){
+				var burl = dojo.config["dojoBlankHtmlUrl"] || (dojo.moduleUrl("dojo", "resources/blank.html")+"") || "javascript:\"\"";
+				var html="<iframe src='" + burl + "'"
+					+ " style='position: absolute; left: 0px; top: 0px;"
+					+ "z-index: -1; filter:Alpha(Opacity=\"0\");'>";
+				iframe = dojo.doc.createElement(html);
+			}else{
+			 	iframe = dojo.create("iframe");
+				iframe.src = 'javascript:""';
+				iframe.className = "dijitBackgroundIframe";
+			}
+			iframe.tabIndex = -1; // Magic to prevent iframe from getting focus on tab keypress - as style didnt work.
+			dojo.body().appendChild(iframe);
+		}
+		return iframe;
+	};
+
+	this.push = function(iframe){
+		iframe.style.display="none";
+		if(dojo.isIE){
+			iframe.style.removeExpression("width");
+			iframe.style.removeExpression("height");
+		}
+		queue.push(iframe);
+	}
+}();
+
+
+dijit.BackgroundIframe = function(/* DomNode */node){
+	// summary:
+	//		For IE z-index schenanigans. id attribute is required.
+	//
+	// description:
+	//		new dijit.BackgroundIframe(node)
+	//			Makes a background iframe as a child of node, that fills
+	//			area (and position) of node
+
+	if(!node.id){ throw new Error("no id"); }
+	if(dojo.isIE < 7 || (dojo.isFF < 3 && dojo.hasClass(dojo.body(), "dijit_a11y"))){
+		var iframe = dijit._frames.pop();
+		node.appendChild(iframe);
+		if(dojo.isIE){
+			iframe.style.setExpression("width", dojo._scopeName + ".doc.getElementById('" + node.id + "').offsetWidth");
+			iframe.style.setExpression("height", dojo._scopeName + ".doc.getElementById('" + node.id + "').offsetHeight");
+		}
+		this.iframe = iframe;
+	}
+};
+
+dojo.extend(dijit.BackgroundIframe, {
+	destroy: function(){
+		//	summary: destroy the iframe
+		if(this.iframe){
+			dijit._frames.push(this.iframe);
+			delete this.iframe;
+		}
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit._base.scroll"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.scroll"] = true;
+dojo.provide("dijit._base.scroll");
+
+dijit.scrollIntoView = function(/* DomNode */node){
+	// summary:
+	//		Scroll the passed node into view, if it is not.
+
+	// don't rely on that node.scrollIntoView works just because the function is there
+	// it doesnt work in Konqueror or Opera even though the function is there and probably
+	//	not safari either
+	// native scrollIntoView() causes FF3's whole window to scroll if there is no scroll bar 
+	//	on the immediate parent
+	// dont like browser sniffs implementations but sometimes you have to use it
+	// It's not enough just to scroll the menu node into view if
+	// node.scrollIntoView hides part of the parent's scrollbar,
+	// so just manage the parent scrollbar ourselves
+
+	//var testdir="H"; //debug
+	try{ // catch unexpected/unrecreatable errors (#7808) since we can recover using a semi-acceptable native method
+	node = dojo.byId(node);
+	var doc = dojo.doc;
+	var body = dojo.body();
+	var html = body.parentNode;
+	// if FF2 (which is perfect) or an untested browser, then use the native method
+
+	if((!(dojo.isFF >= 3 || dojo.isIE || dojo.isWebKit) || node == body || node == html) && (typeof node.scrollIntoView == "function")){ // FF2 is perfect, too bad FF3 is not
+		node.scrollIntoView(false); // short-circuit to native if possible
+		return;
+	}
+	var ltr = dojo._isBodyLtr();
+	var isIE8strict = dojo.isIE >= 8 && !compatMode;
+	var rtl = !ltr && !isIE8strict; // IE8 flips scrolling so pretend it's ltr
+	// body and html elements are all messed up due to browser bugs and inconsistencies related to doctype
+	// normalize the values before proceeding (FF2 is not listed since its native behavior is perfect)
+	// for computation simplification, client and offset width and height are the same for body and html
+	// strict:       html:       |      body:       | compatMode:
+	//           width   height  |  width   height  |------------
+	//    ie*:  clientW  clientH | scrollW  clientH | CSS1Compat
+	//    ff3:  clientW  clientH |HscrollW  clientH | CSS1Compat
+	//    sf3:  clientW  clientH | clientW HclientH | CSS1Compat
+	//    op9:  clientW  clientH |HscrollW  clientH | CSS1Compat
+	// ---------------------------------------------|-----------
+	//   none:        html:      |      body:       |
+	//           width    height |  width   height  |
+	//    ie*: BclientW BclientH | clientW  clientH | BackCompat
+	//    ff3: BclientW BclientH | clientW  clientH | BackCompat
+	//    sf3:  clientW  clientH | clientW HclientH | CSS1Compat
+	//    op9: BclientW BclientH | clientW  clientH | BackCompat
+	// ---------------------------------------------|-----------
+	//  loose:        html:      |      body:       |
+	//           width    height |  width   height  |
+	//    ie*:  clientW  clientH | scrollW  clientH | CSS1Compat
+	//    ff3: BclientW BclientH | clientW  clientH | BackCompat
+	//    sf3:  clientW  clientH | clientW HclientH | CSS1Compat
+	//    op9:  clientW  clientH |HscrollW  clientH | CSS1Compat
+	var scrollRoot = body;
+	var compatMode = doc.compatMode == 'BackCompat';
+	if(compatMode){ // BODY is scrollable, HTML has same client size
+		// body client values already OK
+		html._offsetWidth = html._clientWidth = body._offsetWidth = body.clientWidth;
+		html._offsetHeight = html._clientHeight = body._offsetHeight = body.clientHeight;
+	}else{
+		if(dojo.isWebKit){
+			body._offsetWidth = body._clientWidth  = html.clientWidth;
+			body._offsetHeight = body._clientHeight = html.clientHeight;
+		}else{
+			scrollRoot = html;
+		}
+		html._offsetHeight = html.clientHeight;
+		html._offsetWidth  = html.clientWidth;
+	}
+
+	function isFixedPosition(element){
+		var ie = dojo.isIE;
+		return ((ie <= 6 || (ie >= 7 && compatMode))? false : (dojo.style(element, 'position').toLowerCase() == "fixed"));
+	}
+
+	function addPseudoAttrs(element){
+		var parent = element.parentNode;
+		var offsetParent = element.offsetParent;
+		if(offsetParent == null || isFixedPosition(element)){ // position:fixed has no real offsetParent
+			offsetParent = html; // prevents exeptions
+			parent = (element == body)? html : null;
+		}
+		// all the V/H object members below are to reuse code for both directions
+		element._offsetParent = offsetParent;
+		element._parent = parent;
+		//
+		//
+		var bp = dojo._getBorderExtents(element);
+		element._borderStart = { H:(isIE8strict && !ltr)? (bp.w-bp.l):bp.l, V:bp.t };
+		element._borderSize = { H:bp.w, V:bp.h };
+		element._scrolledAmount = { H:element.scrollLeft, V:element.scrollTop };
+		element._offsetSize = { H: element._offsetWidth||element.offsetWidth, V: element._offsetHeight||element.offsetHeight };
+		//
+		// IE8 flips everything in rtl mode except offsetLeft and borderLeft - so manually change offsetLeft to offsetRight here 
+		element._offsetStart = { H:(isIE8strict && !ltr)? offsetParent.clientWidth-element.offsetLeft-element._offsetSize.H:element.offsetLeft, V:element.offsetTop };
+		//
+		element._clientSize = { H:element._clientWidth||element.clientWidth, V:element._clientHeight||element.clientHeight };
+		if(element != body && element != html && element != node){
+			for(var dir in element._offsetSize){ // for both x and y directions
+				var scrollBarSize = element._offsetSize[dir] - element._clientSize[dir] - element._borderSize[dir];
+				//if(dir==testdir)
+				var hasScrollBar = element._clientSize[dir] > 0 && scrollBarSize > 0; // can't check for a specific scrollbar size since it changes dramatically as you zoom
+				//if(dir==testdir)
+				if(hasScrollBar){
+					element._offsetSize[dir] -= scrollBarSize;
+					if(dojo.isIE && rtl && dir=="H"){ element._offsetStart[dir] += scrollBarSize; }
+				}
+			}
+		}
+	}
+
+	var element = node;
+	while(element != null){
+		if(isFixedPosition(element)){ node.scrollIntoView(false); return; } //TODO: handle without native call
+		addPseudoAttrs(element);
+		element = element._parent;
+	}
+	if(dojo.isIE && node._parent){ // if no parent, then offsetParent._borderStart may not tbe set
+		var offsetParent = node._offsetParent;
+		//
+		node._offsetStart.H += offsetParent._borderStart.H;
+		node._offsetStart.V += offsetParent._borderStart.V;
+	}
+	if(dojo.isIE >= 7 && scrollRoot == html && rtl && body._offsetStart && body._offsetStart.H == 0){ // IE7 bug
+		var scroll = html.scrollWidth - html._offsetSize.H;
+		if(scroll > 0){
+			//
+			body._offsetStart.H = -scroll;
+		}
+	}
+	if(dojo.isIE <= 6 && !compatMode){
+		html._offsetSize.H += html._borderSize.H;
+		html._offsetSize.V += html._borderSize.V;
+	}
+	// eliminate offsetLeft/Top oddities by tweaking scroll for ease of computation
+	if(rtl && body._offsetStart && scrollRoot == html && html._scrolledAmount){
+		var ofs = body._offsetStart.H;
+		if(ofs < 0){
+			html._scrolledAmount.H += ofs;
+			body._offsetStart.H = 0;
+		}
+	}
+	element = node;
+	while(element){
+		var parent = element._parent;
+		if(!parent){ break; }
+			//
+			if(parent.tagName == "TD"){
+				var table = parent._parent._parent._parent; // point to TABLE
+				if(parent != element._offsetParent && parent._offsetParent != element._offsetParent){
+					parent = table; // child of TD has the same offsetParent as TABLE, so skip TD, TR, and TBODY (ie. verticalslider)
+				}
+			}
+			// check if this node and its parent share the same offsetParent
+			var relative = element._offsetParent == parent;
+			//
+			for(var dir in element._offsetStart){ // for both x and y directions
+				var otherDir = dir=="H"? "V" : "H";
+				if(rtl && dir=="H" && (parent != html) && (parent != body) && (dojo.isIE || dojo.isWebKit) && parent._clientSize.H > 0 && parent.scrollWidth > parent._clientSize.H){ // scroll starts on the right
+					var delta = parent.scrollWidth - parent._clientSize.H;
+					//
+					if(delta > 0){
+						parent._scrolledAmount.H -= delta;
+					} // match FF3 which has cool negative scrollLeft values
+				}
+				if(parent._offsetParent.tagName == "TABLE"){ // make it consistent
+					if(dojo.isIE){ // make it consistent with Safari and FF3 and exclude the starting TABLE border of TABLE children
+						parent._offsetStart[dir] -= parent._offsetParent._borderStart[dir];
+						parent._borderStart[dir] = parent._borderSize[dir] = 0;
+					}
+					else{
+						parent._offsetStart[dir] += parent._offsetParent._borderStart[dir];
+					}
+				}
+				//if(dir==testdir)
+				if(dojo.isIE){
+					//if(dir==testdir)
+					parent._offsetStart[dir] += parent._offsetParent._borderStart[dir];
+				}
+				//if(dir==testdir)
+				// underflow = visible gap between parent and this node taking scrolling into account
+				// if negative, part of the node is obscured by the parent's beginning and should be scrolled to become visible
+				var underflow = element._offsetStart[dir] - parent._scrolledAmount[dir] - (relative? 0 : parent._offsetStart[dir]) - parent._borderStart[dir];
+				// if overflow is positive, number of pixels obscured by the parent's end
+				var overflow = underflow + element._offsetSize[dir] - parent._offsetSize[dir] + parent._borderSize[dir];
+				//if(dir==testdir)
+				var scrollAttr = (dir=="H")? "scrollLeft" : "scrollTop";
+				// see if we should scroll forward or backward
+				var reverse = dir=="H" && rtl; // flip everything
+				var underflowScroll = reverse? -overflow : underflow;
+				var overflowScroll = reverse? -underflow : overflow;
+				// don't scroll if the over/underflow signs are opposite since that means that
+				// the node extends beyond parent's boundary in both/neither directions
+				var scrollAmount = (underflowScroll*overflowScroll <= 0)? 0 : Math[(underflowScroll < 0)? "max" : "min"](underflowScroll, overflowScroll);
+				//if(dir==testdir)
+				if(scrollAmount != 0){
+					var oldScroll = parent[scrollAttr];
+					parent[scrollAttr] += (reverse)? -scrollAmount : scrollAmount; // actually perform the scroll
+					var scrolledAmount = parent[scrollAttr] - oldScroll; // in case the scroll failed
+					//if(dir==testdir)
+				}
+				if(relative){
+					element._offsetStart[dir] += parent._offsetStart[dir];
+				}
+				element._offsetStart[dir] -= parent[scrollAttr];
+			}
+			element._parent = parent._parent;
+			element._offsetParent = parent._offsetParent;
+	}
+	parent = node;
+	var next;
+	while(parent && parent.removeAttribute){
+		next = parent.parentNode;
+		parent.removeAttribute('_offsetParent');
+		parent.removeAttribute('_parent');
+		parent = next;
+	}
+	}catch(error){
+		console.error('scrollIntoView: ' + error);
+		node.scrollIntoView(false);
+	}
+};
+
+}
+
+if(!dojo._hasResource["dijit._base.sniff"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.sniff"] = true;
+// summary:
+//		Applies pre-set CSS classes to the top-level HTML node, based on:
+// 			- browser (ex: dj_ie)
+//			- browser version (ex: dj_ie6)
+//			- box model (ex: dj_contentBox)
+//			- text direction (ex: dijitRtl)
+//
+//		In addition, browser, browser version, and box model are
+//		combined with an RTL flag when browser text is RTL.  ex: dj_ie-rtl.
+//
+//		Simply doing a require on this module will
+//		establish this CSS.  Modified version of Morris' CSS hack.
+
+dojo.provide("dijit._base.sniff");
+
+(function(){
+	
+	var d = dojo,
+		html = d.doc.documentElement,
+		ie = d.isIE,
+		opera = d.isOpera,
+		maj = Math.floor,
+		ff = d.isFF,
+		boxModel = d.boxModel.replace(/-/,''),
+		classes = {
+			dj_ie: ie,
+//			dj_ie55: ie == 5.5,
+			dj_ie6: maj(ie) == 6,
+			dj_ie7: maj(ie) == 7,
+			dj_iequirks: ie && d.isQuirks,
+			// NOTE: Opera not supported by dijit
+			dj_opera: opera,
+			dj_opera8: maj(opera) == 8,
+			dj_opera9: maj(opera) == 9,
+			dj_khtml: d.isKhtml,
+			dj_webkit: d.isWebKit,
+			dj_safari: d.isSafari,
+			dj_gecko: d.isMozilla,
+			dj_ff2: maj(ff) == 2,
+			dj_ff3: maj(ff) == 3
+		}; // no dojo unsupported browsers
+		
+	classes["dj_" + boxModel] = true;
+	
+	// apply browser, browser version, and box model class names
+	for(var p in classes){
+		if(classes[p]){
+			if(html.className){
+				html.className += " " + p;
+			}else{
+				html.className = p;
+			}
+		}
+	}
+
+	// If RTL mode then add dijitRtl flag plus repeat existing classes
+	// with -rtl extension
+	// (unshift is to make this code run after <body> node is loaded but before parser runs)
+	dojo._loaders.unshift(function(){
+		if(!dojo._isBodyLtr()){
+			html.className += " dijitRtl";
+			for(var p in classes){
+				if(classes[p]){
+					html.className += " " + p + "-rtl";
+				}
+			}
+		}
+	});
+	
+})();
+
+}
+
+if(!dojo._hasResource["dijit._base.typematic"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.typematic"] = true;
+dojo.provide("dijit._base.typematic");
+
+dijit.typematic = {
+	// summary:
+	//		These functions are used to repetitively call a user specified callback
+	//		method when a specific key or mouse click over a specific DOM node is
+	//		held down for a specific amount of time.
+	//		Only 1 such event is allowed to occur on the browser page at 1 time.
+
+	_fireEventAndReload: function(){
+		this._timer = null;
+		this._callback(++this._count, this._node, this._evt);
+		this._currentTimeout = (this._currentTimeout < 0) ? this._initialDelay : ((this._subsequentDelay > 1) ? this._subsequentDelay : Math.round(this._currentTimeout * this._subsequentDelay));
+		this._timer = setTimeout(dojo.hitch(this, "_fireEventAndReload"), this._currentTimeout);
+	},
+
+	trigger: function(/*Event*/ evt, /* Object */ _this, /*DOMNode*/ node, /* Function */ callback, /* Object */ obj, /* Number */ subsequentDelay, /* Number */ initialDelay){
+		// summary:
+		//	    Start a timed, repeating callback sequence.
+		//	    If already started, the function call is ignored.
+		//	    This method is not normally called by the user but can be
+		//	    when the normal listener code is insufficient.
+		// evt:
+		//		key or mouse event object to pass to the user callback
+		// _this:
+		//		pointer to the user's widget space.
+		// node:
+		//		the DOM node object to pass the the callback function
+		// callback:
+		//		function to call until the sequence is stopped called with 3 parameters:
+		// count:
+		//		integer representing number of repeated calls (0..n) with -1 indicating the iteration has stopped
+		// node:
+		//		the DOM node object passed in
+		// evt:
+		//		key or mouse event object
+		// obj:
+		//		user space object used to uniquely identify each typematic sequence
+		// subsequentDelay:
+		//		if > 1, the number of milliseconds until the 3->n events occur
+		//		or else the fractional time multiplier for the next event's delay, default=0.9
+		// initialDelay:
+		//		the number of milliseconds until the 2nd event occurs, default=500ms
+		if(obj != this._obj){
+			this.stop();
+			this._initialDelay = initialDelay || 500;
+			this._subsequentDelay = subsequentDelay || 0.90;
+			this._obj = obj;
+			this._evt = evt;
+			this._node = node;
+			this._currentTimeout = -1;
+			this._count = -1;
+			this._callback = dojo.hitch(_this, callback);
+			this._fireEventAndReload();
+		}
+	},
+
+	stop: function(){
+		// summary:
+		//	  Stop an ongoing timed, repeating callback sequence.
+		if(this._timer){
+			clearTimeout(this._timer);
+			this._timer = null;
+		}
+		if(this._obj){
+			this._callback(-1, this._node, this._evt);
+			this._obj = null;
+		}
+	},
+
+	addKeyListener: function(/*DOMNode*/ node, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay){
+		// summary:
+		//		Start listening for a specific typematic key.
+		//		See also the trigger method for other parameters.
+		// keyObject:
+		//		an object defining the key to listen for.
+		// charOrCode:
+		//		the printable character (string) or keyCode (number) to listen for.
+		// keyCode:
+		//		(deprecated - use charOrCode) the keyCode (number) to listen for (implies charCode = 0).
+		// charCode:
+		//		(deprecated - use charOrCode) the charCode (number) to listen for.
+		// ctrlKey:
+		//		desired ctrl key state to initiate the calback sequence:
+		//			- pressed (true)
+		//			- released (false)
+		//			- either (unspecified)
+		// altKey:
+		//		same as ctrlKey but for the alt key
+		// shiftKey:
+		//		same as ctrlKey but for the shift key
+		// returns:
+		//		an array of dojo.connect handles
+		if(keyObject.keyCode){
+			keyObject.charOrCode = keyObject.keyCode;
+			dojo.deprecated("keyCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.", "", "2.0");
+		}else if(keyObject.charCode){
+			keyObject.charOrCode = String.fromCharCode(keyObject.charCode);
+			dojo.deprecated("charCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.", "", "2.0");
+		}
+		return [
+			dojo.connect(node, "onkeypress", this, function(evt){
+				if(evt.charOrCode == keyObject.charOrCode &&
+				(keyObject.ctrlKey === undefined || keyObject.ctrlKey == evt.ctrlKey) &&
+				(keyObject.altKey === undefined || keyObject.altKey == evt.ctrlKey) &&
+				(keyObject.shiftKey === undefined || keyObject.shiftKey == evt.ctrlKey)){
+					dojo.stopEvent(evt);
+					dijit.typematic.trigger(keyObject, _this, node, callback, keyObject, subsequentDelay, initialDelay);
+				}else if(dijit.typematic._obj == keyObject){
+					dijit.typematic.stop();
+				}
+			}),
+			dojo.connect(node, "onkeyup", this, function(evt){
+				if(dijit.typematic._obj == keyObject){
+					dijit.typematic.stop();
+				}
+			})
+		];
+	},
+
+	addMouseListener: function(/*DOMNode*/ node, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay){
+		// summary:
+		//		Start listening for a typematic mouse click.
+		//		See the trigger method for other parameters.
+		// returns:
+		//		an array of dojo.connect handles
+		var dc = dojo.connect;
+		return [
+			dc(node, "mousedown", this, function(evt){
+				dojo.stopEvent(evt);
+				dijit.typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay);
+			}),
+			dc(node, "mouseup", this, function(evt){
+				dojo.stopEvent(evt);
+				dijit.typematic.stop();
+			}),
+			dc(node, "mouseout", this, function(evt){
+				dojo.stopEvent(evt);
+				dijit.typematic.stop();
+			}),
+			dc(node, "mousemove", this, function(evt){
+				dojo.stopEvent(evt);
+			}),
+			dc(node, "dblclick", this, function(evt){
+				dojo.stopEvent(evt);
+				if(dojo.isIE){
+					dijit.typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay);
+					setTimeout(dojo.hitch(this, dijit.typematic.stop), 50);
+				}
+			})
+		];
+	},
+
+	addListener: function(/*Node*/ mouseNode, /*Node*/ keyNode, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay){
+		// summary:
+		//		Start listening for a specific typematic key and mouseclick.
+		//		This is a thin wrapper to addKeyListener and addMouseListener.
+		//		See the addMouseListener and addKeyListener methods for other parameters.
+		// mouseNode:
+		//		the DOM node object to listen on for mouse events.
+		// keyNode:
+		//		the DOM node object to listen on for key events.
+		// returns:
+		//		an array of dojo.connect handles
+		return this.addKeyListener(keyNode, keyObject, _this, callback, subsequentDelay, initialDelay).concat(
+			this.addMouseListener(mouseNode, _this, callback, subsequentDelay, initialDelay));
+	}
+};
+
+}
+
+if(!dojo._hasResource["dijit._base.wai"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.wai"] = true;
+dojo.provide("dijit._base.wai");
+
+dijit.wai = {
+	onload: function(){
+		// summary:
+		//		Detects if we are in high-contrast mode or not
+
+		// This must be a named function and not an anonymous
+		// function, so that the widget parsing code can make sure it
+		// registers its onload function after this function.
+		// DO NOT USE "this" within this function.
+
+		// create div for testing if high contrast mode is on or images are turned off
+		var div = dojo.create("div",{
+			id: "a11yTestNode",
+			style:{
+				cssText:'border: 1px solid;'
+					+ 'border-color:red green;'
+					+ 'position: absolute;'
+					+ 'height: 5px;'
+					+ 'top: -999px;'
+					+ 'background-image: url("' + (dojo.config.blankGif || dojo.moduleUrl("dojo", "resources/blank.gif")) + '");'
+			}
+		}, dojo.body());
+
+		// test it
+		var cs = dojo.getComputedStyle(div);
+		if(cs){
+			var bkImg = cs.backgroundImage;
+			var needsA11y = (cs.borderTopColor==cs.borderRightColor) || (bkImg != null && (bkImg == "none" || bkImg == "url(invalid-url:)" ));
+			dojo[needsA11y ? "addClass" : "removeClass"](dojo.body(), "dijit_a11y");
+			if(dojo.isIE){
+				div.outerHTML = "";		// prevent mixed-content warning, see http://support.microsoft.com/kb/925014
+			}else{
+				dojo.body().removeChild(div);
+			}
+		}
+	}
+};
+
+// Test if computer is in high contrast mode.
+// Make sure the a11y test runs first, before widgets are instantiated.
+if(dojo.isIE || dojo.isMoz){	// NOTE: checking in Safari messes things up
+	dojo._loaders.unshift(dijit.wai.onload);
+}
+
+dojo.mixin(dijit,
+{
+	_XhtmlRoles: /banner|contentinfo|definition|main|navigation|search|note|secondary|seealso/,
+
+	hasWaiRole: function(/*Element*/ elem, /*String*/ role){
+		// summary:
+		//		Determines if an element has a particular non-XHTML role.
+		// returns:
+		//		True if elem has the specific non-XHTML role attribute and false if not.
+		// 		For backwards compatibility if role parameter not provided, 
+		// 		returns true if has non XHTML role 
+		var waiRole = this.getWaiRole(elem);		
+		return role ? (waiRole.indexOf(role) > -1) : (waiRole.length > 0);
+	},
+
+	getWaiRole: function(/*Element*/ elem){
+		// summary:
+		//		Gets the non-XHTML role for an element (which should be a wai role).
+		// returns:
+		//		The non-XHTML role of elem or an empty string if elem
+		//		does not have a role.
+		 return dojo.trim((dojo.attr(elem, "role") || "").replace(this._XhtmlRoles,"").replace("wairole:",""));
+	},
+
+	setWaiRole: function(/*Element*/ elem, /*String*/ role){
+		// summary:
+		//		Sets the role on an element.
+		// description:
+		//		In other than FF2 replace existing role attribute with new role.
+		//		FF3 supports XHTML and ARIA roles so    
+		//		if elem already has an XHTML role, append this role to XHTML role 
+		//		and remove other ARIA roles.
+		//		On Firefox 2 and below, "wairole:" is
+		//		prepended to the provided role value.
+
+		var curRole = dojo.attr(elem, "role") || "";
+		if(dojo.isFF < 3 || !this._XhtmlRoles.test(curRole)){
+			dojo.attr(elem, "role", dojo.isFF < 3 ? "wairole:" + role : role);
+		}else{
+			if((" "+ curRole +" ").indexOf(" " + role + " ") < 0){
+				var clearXhtml = dojo.trim(curRole.replace(this._XhtmlRoles, ""));
+				var cleanRole = dojo.trim(curRole.replace(clearXhtml, ""));	 
+         		dojo.attr(elem, "role", cleanRole + (cleanRole ? ' ' : '') + role);
+			}
+		}
+	},
+
+	removeWaiRole: function(/*Element*/ elem, /*String*/ role){
+		// summary:
+		//		Removes the specified non-XHTML role from an element.
+		// 		Removes role attribute if no specific role provided (for backwards compat.)
+
+		var roleValue = dojo.attr(elem, "role"); 
+		if(!roleValue){ return; }
+		if(role){
+			var searchRole = dojo.isFF < 3 ? "wairole:" + role : role;
+			var t = dojo.trim((" " + roleValue + " ").replace(" " + searchRole + " ", " "));
+			dojo.attr(elem, "role", t);
+		}else{
+			elem.removeAttribute("role");	
+		}
+	},
+
+	hasWaiState: function(/*Element*/ elem, /*String*/ state){
+		// summary:
+		//		Determines if an element has a given state.
+		// description:
+		//		On Firefox 2 and below, we check for an attribute in namespace
+		//		"http://www.w3.org/2005/07/aaa" with a name of the given state.
+		//		On all other browsers, we check for an attribute
+		//		called "aria-"+state.
+		// returns:
+		//		true if elem has a value for the given state and
+		//		false if it does not.
+		if(dojo.isFF < 3){
+			return elem.hasAttributeNS("http://www.w3.org/2005/07/aaa", state);
+		}
+		return elem.hasAttribute ? elem.hasAttribute("aria-"+state) : !!elem.getAttribute("aria-"+state);
+	},
+
+	getWaiState: function(/*Element*/ elem, /*String*/ state){
+		// summary:
+		//		Gets the value of a state on an element.
+		// description:
+		//		On Firefox 2 and below, we check for an attribute in namespace
+		//		"http://www.w3.org/2005/07/aaa" with a name of the given state.
+		//		On all other browsers, we check for an attribute called
+		//		"aria-"+state.
+		// returns:
+		//		The value of the requested state on elem
+		//		or an empty string if elem has no value for state.
+		if(dojo.isFF < 3){
+			return elem.getAttributeNS("http://www.w3.org/2005/07/aaa", state);
+		}
+		return elem.getAttribute("aria-"+state) || "";
+	},
+
+	setWaiState: function(/*Element*/ elem, /*String*/ state, /*String*/ value){
+		// summary:
+		//		Sets a state on an element.
+		// description:
+		//		On Firefox 2 and below, we set an attribute in namespace
+		//		"http://www.w3.org/2005/07/aaa" with a name of the given state.
+		//		On all other browsers, we set an attribute called
+		//		"aria-"+state.
+		if(dojo.isFF < 3){
+			elem.setAttributeNS("http://www.w3.org/2005/07/aaa",
+				"aaa:"+state, value);
+		}else{
+			elem.setAttribute("aria-"+state, value);
+		}
+	},
+
+	removeWaiState: function(/*Element*/ elem, /*String*/ state){
+		// summary:
+		//		Removes a state from an element.
+		// description:
+		//		On Firefox 2 and below, we remove the attribute in namespace
+		//		"http://www.w3.org/2005/07/aaa" with a name of the given state.
+		//		On all other browsers, we remove the attribute called
+		//		"aria-"+state.
+		if(dojo.isFF < 3){
+			elem.removeAttributeNS("http://www.w3.org/2005/07/aaa", state);
+		}else{
+			elem.removeAttribute("aria-"+state);
+		}
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base"] = true;
+dojo.provide("dijit._base");
+
+
+
+
+
+
+
+
+
+
+
+}
+
+if(!dojo._hasResource["dojo.date.stamp"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.date.stamp"] = true;
+dojo.provide("dojo.date.stamp");
+
+// Methods to convert dates to or from a wire (string) format using well-known conventions
+
+dojo.date.stamp.fromISOString = function(/*String*/formattedString, /*Number?*/defaultTime){
+	//	summary:
+	//		Returns a Date object given a string formatted according to a subset of the ISO-8601 standard.
+	//
+	//	description:
+	//		Accepts a string formatted according to a profile of ISO8601 as defined by
+	//		[RFC3339](http://www.ietf.org/rfc/rfc3339.txt), except that partial input is allowed.
+	//		Can also process dates as specified [by the W3C](http://www.w3.org/TR/NOTE-datetime)
+	//		The following combinations are valid:
+	//
+	//			* dates only
+	//			|	* yyyy
+	//			|	* yyyy-MM
+	//			|	* yyyy-MM-dd
+	// 			* times only, with an optional time zone appended
+	//			|	* THH:mm
+	//			|	* THH:mm:ss
+	//			|	* THH:mm:ss.SSS
+	// 			* and "datetimes" which could be any combination of the above
+	//
+	//		timezones may be specified as Z (for UTC) or +/- followed by a time expression HH:mm
+	//		Assumes the local time zone if not specified.  Does not validate.  Improperly formatted
+	//		input may return null.  Arguments which are out of bounds will be handled
+	// 		by the Date constructor (e.g. January 32nd typically gets resolved to February 1st)
+	//		Only years between 100 and 9999 are supported.
+	//
+  	//	formattedString:
+	//		A string such as 2005-06-30T08:05:00-07:00 or 2005-06-30 or T08:05:00
+	//
+	//	defaultTime:
+	//		Used for defaults for fields omitted in the formattedString.
+	//		Uses 1970-01-01T00:00:00.0Z by default.
+
+	if(!dojo.date.stamp._isoRegExp){
+		dojo.date.stamp._isoRegExp =
+//TODO: could be more restrictive and check for 00-59, etc.
+			/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(.\d+)?)?((?:[+-](\d{2}):(\d{2}))|Z)?)?$/;
+	}
+
+	var match = dojo.date.stamp._isoRegExp.exec(formattedString);
+	var result = null;
+
+	if(match){
+		match.shift();
+		if(match[1]){match[1]--;} // Javascript Date months are 0-based
+		if(match[6]){match[6] *= 1000;} // Javascript Date expects fractional seconds as milliseconds
+
+		if(defaultTime){
+			// mix in defaultTime.  Relatively expensive, so use || operators for the fast path of defaultTime === 0
+			defaultTime = new Date(defaultTime);
+			dojo.map(["FullYear", "Month", "Date", "Hours", "Minutes", "Seconds", "Milliseconds"], function(prop){
+				return defaultTime["get" + prop]();
+			}).forEach(function(value, index){
+				if(match[index] === undefined){
+					match[index] = value;
+				}
+			});
+		}
+		result = new Date(match[0]||1970, match[1]||0, match[2]||1, match[3]||0, match[4]||0, match[5]||0, match[6]||0);
+//		result.setFullYear(match[0]||1970); // for year < 100
+
+		var offset = 0;
+		var zoneSign = match[7] && match[7].charAt(0);
+		if(zoneSign != 'Z'){
+			offset = ((match[8] || 0) * 60) + (Number(match[9]) || 0);
+			if(zoneSign != '-'){ offset *= -1; }
+		}
+		if(zoneSign){
+			offset -= result.getTimezoneOffset();
+		}
+		if(offset){
+			result.setTime(result.getTime() + offset * 60000);
+		}
+	}
+
+	return result; // Date or null
+}
+
+/*=====
+	dojo.date.stamp.__Options = function(){
+		//	selector: String
+		//		"date" or "time" for partial formatting of the Date object.
+		//		Both date and time will be formatted by default.
+		//	zulu: Boolean
+		//		if true, UTC/GMT is used for a timezone
+		//	milliseconds: Boolean
+		//		if true, output milliseconds
+		this.selector = selector;
+		this.zulu = zulu;
+		this.milliseconds = milliseconds;
+	}
+=====*/
+
+dojo.date.stamp.toISOString = function(/*Date*/dateObject, /*dojo.date.stamp.__Options?*/options){
+	//	summary:
+	//		Format a Date object as a string according a subset of the ISO-8601 standard
+	//
+	//	description:
+	//		When options.selector is omitted, output follows [RFC3339](http://www.ietf.org/rfc/rfc3339.txt)
+	//		The local time zone is included as an offset from GMT, except when selector=='time' (time without a date)
+	//		Does not check bounds.  Only years between 100 and 9999 are supported.
+	//
+	//	dateObject:
+	//		A Date object
+
+	var _ = function(n){ return (n < 10) ? "0" + n : n; };
+	options = options || {};
+	var formattedDate = [];
+	var getter = options.zulu ? "getUTC" : "get";
+	var date = "";
+	if(options.selector != "time"){
+		var year = dateObject[getter+"FullYear"]();
+		date = ["0000".substr((year+"").length)+year, _(dateObject[getter+"Month"]()+1), _(dateObject[getter+"Date"]())].join('-');
+	}
+	formattedDate.push(date);
+	if(options.selector != "date"){
+		var time = [_(dateObject[getter+"Hours"]()), _(dateObject[getter+"Minutes"]()), _(dateObject[getter+"Seconds"]())].join(':');
+		var millis = dateObject[getter+"Milliseconds"]();
+		if(options.milliseconds){
+			time += "."+ (millis < 100 ? "0" : "") + _(millis);
+		}
+		if(options.zulu){
+			time += "Z";
+		}else if(options.selector != "time"){
+			var timezoneOffset = dateObject.getTimezoneOffset();
+			var absOffset = Math.abs(timezoneOffset);
+			time += (timezoneOffset > 0 ? "-" : "+") + 
+				_(Math.floor(absOffset/60)) + ":" + _(absOffset%60);
+		}
+		formattedDate.push(time);
+	}
+	return formattedDate.join('T'); // String
+}
+
+}
+
+if(!dojo._hasResource["dojo.parser"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.parser"] = true;
+dojo.provide("dojo.parser");
+
+
+dojo.parser = new function(){
+	// summary: The Dom/Widget parsing package
+
+	var d = dojo;
+	var dtName = d._scopeName + "Type";
+	var qry = "[" + dtName + "]";
+
+	var _anonCtr = 0, _anon = {};
+	var nameAnonFunc = function(/*Function*/anonFuncPtr, /*Object*/thisObj){
+		// summary:
+		//		Creates a reference to anonFuncPtr in thisObj with a completely
+		//		unique name. The new name is returned as a String. 
+		var nso = thisObj || _anon;
+		if(dojo.isIE){
+			var cn = anonFuncPtr["__dojoNameCache"];
+			if(cn && nso[cn] === anonFuncPtr){
+				return cn;
+			}
+		}
+		var name;
+		do{
+			name = "__" + _anonCtr++;
+		}while(name in nso)
+		nso[name] = anonFuncPtr;
+		return name; // String
+	}
+
+	function val2type(/*Object*/ value){
+		// summary:
+		//		Returns name of type of given value.
+
+		if(d.isString(value)){ return "string"; }
+		if(typeof value == "number"){ return "number"; }
+		if(typeof value == "boolean"){ return "boolean"; }
+		if(d.isFunction(value)){ return "function"; }
+		if(d.isArray(value)){ return "array"; } // typeof [] == "object"
+		if(value instanceof Date) { return "date"; } // assume timestamp
+		if(value instanceof d._Url){ return "url"; }
+		return "object";
+	}
+
+	function str2obj(/*String*/ value, /*String*/ type){
+		// summary:
+		//		Convert given string value to given type
+		switch(type){
+			case "string":
+				return value;
+			case "number":
+				return value.length ? Number(value) : NaN;
+			case "boolean":
+				// for checked/disabled value might be "" or "checked".  interpret as true.
+				return typeof value == "boolean" ? value : !(value.toLowerCase()=="false");
+			case "function":
+				if(d.isFunction(value)){
+					// IE gives us a function, even when we say something like onClick="foo"
+					// (in which case it gives us an invalid function "function(){ foo }"). 
+					//  Therefore, convert to string
+					value=value.toString();
+					value=d.trim(value.substring(value.indexOf('{')+1, value.length-1));
+				}
+				try{
+					if(value.search(/[^\w\.]+/i) != -1){
+						// TODO: "this" here won't work
+						value = nameAnonFunc(new Function(value), this);
+					}
+					return d.getObject(value, false);
+				}catch(e){ return new Function(); }
+			case "array":
+				return value ? value.split(/\s*,\s*/) : [];
+			case "date":
+				switch(value){
+					case "": return new Date("");	// the NaN of dates
+					case "now": return new Date();	// current date
+					default: return d.date.stamp.fromISOString(value);
+				}
+			case "url":
+				return d.baseUrl + value;
+			default:
+				return d.fromJson(value);
+		}
+	}
+
+	var instanceClasses = {
+		// map from fully qualified name (like "dijit.Button") to structure like
+		// { cls: dijit.Button, params: {label: "string", disabled: "boolean"} }
+	};
+	
+	function getClassInfo(/*String*/ className){
+		// className:
+		//		fully qualified name (like "dijit.form.Button")
+		// returns:
+		//		structure like
+		//			{ 
+		//				cls: dijit.Button, 
+		//				params: { label: "string", disabled: "boolean"}
+		//			}
+
+		if(!instanceClasses[className]){
+			// get pointer to widget class
+			var cls = d.getObject(className);
+			if(!d.isFunction(cls)){
+				throw new Error("Could not load class '" + className +
+					"'. Did you spell the name correctly and use a full path, like 'dijit.form.Button'?");
+			}
+			var proto = cls.prototype;
+	
+			// get table of parameter names & types
+			var params = {}, dummyClass = {};
+			for(var name in proto){
+				if(name.charAt(0)=="_"){ continue; } 	// skip internal properties
+				if(name in dummyClass){ continue; }		// skip "constructor" and "toString"
+				var defVal = proto[name];
+				params[name]=val2type(defVal);
+			}
+
+			instanceClasses[className] = { cls: cls, params: params };
+		}
+		return instanceClasses[className];
+	}
+
+	this._functionFromScript = function(script){
+		var preamble = "";
+		var suffix = "";
+		var argsStr = script.getAttribute("args");
+		if(argsStr){
+			d.forEach(argsStr.split(/\s*,\s*/), function(part, idx){
+				preamble += "var "+part+" = arguments["+idx+"]; ";
+			});
+		}
+		var withStr = script.getAttribute("with");
+		if(withStr && withStr.length){
+			d.forEach(withStr.split(/\s*,\s*/), function(part){
+				preamble += "with("+part+"){";
+				suffix += "}";
+			});
+		}
+		return new Function(preamble+script.innerHTML+suffix);
+	}
+
+	this.instantiate = function(/* Array */nodes, /* Object? */mixin){
+		// summary:
+		//		Takes array of nodes, and turns them into class instances and
+		//		potentially calls a layout method to allow them to connect with
+		//		any children		
+		// mixin: Object
+		//		An object that will be mixed in with each node in the array.
+		//		Values in the mixin will override values in the node, if they
+		//		exist.
+		var thelist = [];
+		mixin = mixin||{};
+		d.forEach(nodes, function(node){
+			if(!node){ return; }
+			var type = dtName in mixin?mixin[dtName]:node.getAttribute(dtName);
+			if(!type || !type.length){ return; }
+			var clsInfo = getClassInfo(type),
+				clazz = clsInfo.cls,
+				ps = clazz._noScript || clazz.prototype._noScript;
+
+			// read parameters (ie, attributes).
+			// clsInfo.params lists expected params like {"checked": "boolean", "n": "number"}
+			var params = {},
+				attributes = node.attributes;
+			for(var name in clsInfo.params){
+				var item = name in mixin?{value:mixin[name],specified:true}:attributes.getNamedItem(name);
+				if(!item || (!item.specified && (!dojo.isIE || name.toLowerCase()!="value"))){ continue; }
+				var value = item.value;
+				// Deal with IE quirks for 'class' and 'style'
+				switch(name){
+				case "class":
+					value = "className" in mixin?mixin.className:node.className;
+					break;
+				case "style":
+					value = "style" in mixin?mixin.style:(node.style && node.style.cssText); // FIXME: Opera?
+				}
+				var _type = clsInfo.params[name];
+				if(typeof value == "string"){
+					params[name] = str2obj(value, _type);
+				}else{
+					params[name] = value;
+				}
+			}
+
+			// Process <script type="dojo/*"> script tags
+			// <script type="dojo/method" event="foo"> tags are added to params, and passed to
+			// the widget on instantiation.
+			// <script type="dojo/method"> tags (with no event) are executed after instantiation
+			// <script type="dojo/connect" event="foo"> tags are dojo.connected after instantiation
+			// note: dojo/* script tags cannot exist in self closing widgets, like <input />
+			if(!ps){
+				var connects = [],	// functions to connect after instantiation
+					calls = [];		// functions to call after instantiation
+
+				d.query("> script[type^='dojo/']", node).orphan().forEach(function(script){
+					var event = script.getAttribute("event"),
+						type = script.getAttribute("type"),
+						nf = d.parser._functionFromScript(script);
+					if(event){
+						if(type == "dojo/connect"){
+							connects.push({event: event, func: nf});
+						}else{
+							params[event] = nf;
+						}
+					}else{
+						calls.push(nf);
+					}
+				});
+			}
+
+			var markupFactory = clazz["markupFactory"];
+			if(!markupFactory && clazz["prototype"]){
+				markupFactory = clazz.prototype["markupFactory"];
+			}
+			// create the instance
+			var instance = markupFactory ? markupFactory(params, node, clazz) : new clazz(params, node);
+			thelist.push(instance);
+
+			// map it to the JS namespace if that makes sense
+			var jsname = node.getAttribute("jsId");
+			if(jsname){
+				d.setObject(jsname, instance);
+			}
+
+			// process connections and startup functions
+			if(!ps){
+				d.forEach(connects, function(connect){
+					d.connect(instance, connect.event, null, connect.func);
+				});
+				d.forEach(calls, function(func){
+					func.call(instance);
+				});
+			}
+		});
+
+		// Call startup on each top level instance if it makes sense (as for
+		// widgets).  Parent widgets will recursively call startup on their
+		// (non-top level) children
+		d.forEach(thelist, function(instance){
+			if(	instance  && 
+				instance.startup &&
+				!instance._started && 
+				(!instance.getParent || !instance.getParent())
+			){
+				instance.startup();
+			}
+		});
+		return thelist;
+	};
+
+	this.parse = function(/*DomNode?*/ rootNode){
+		// summary:
+		//		Search specified node (or root node) recursively for class instances,
+		//		and instantiate them Searches for
+		//		dojoType="qualified.class.name"
+		var list = d.query(qry, rootNode);
+		// go build the object instances
+		var instances = this.instantiate(list);
+		return instances;
+	};
+}();
+
+//Register the parser callback. It should be the first callback
+//after the a11y test.
+
+(function(){
+	var parseRunner = function(){ 
+		if(dojo.config["parseOnLoad"] == true){
+			dojo.parser.parse(); 
+		}
+	};
+
+	// FIXME: need to clobber cross-dependency!!
+	if(dojo.exists("dijit.wai.onload") && (dijit.wai.onload === dojo._loaders[0])){
+		dojo._loaders.splice(1, 0, parseRunner);
+	}else{
+		dojo._loaders.unshift(parseRunner);
+	}
+})();
+
+}
+
+if(!dojo._hasResource["dijit._Widget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._Widget"] = true;
+dojo.provide("dijit._Widget");
+
+dojo.require( "dijit._base" );
+
+dojo.connect(dojo, "connect", 
+	function(/*Widget*/ widget, /*String*/ event){
+		if(widget && dojo.isFunction(widget._onConnect)){
+			widget._onConnect(event);
+		}
+	});
+
+dijit._connectOnUseEventHandler = function(/*Event*/ event){};
+
+(function(){
+
+var _attrReg = {};
+var getAttrReg = function(dc){
+	if(!_attrReg[dc]){
+		var r = [];
+		var attrs;
+		var proto = dojo.getObject(dc).prototype;
+		for(var fxName in proto){
+			if(dojo.isFunction(proto[fxName]) && (attrs = fxName.match(/^_set([a-zA-Z]*)Attr$/)) && attrs[1]){
+				r.push(attrs[1].charAt(0).toLowerCase() + attrs[1].substr(1));
+			}
+		}
+		_attrReg[dc] = r;
+	}
+	return _attrReg[dc]||[];
+}
+
+dojo.declare("dijit._Widget", null, {
+	// summary:
+	//		Base class for all dijit widgets. 	
+
+	// id: [const] String
+	//		A unique, opaque ID string that can be assigned by users or by the
+	//		system. If the developer passes an ID which is known not to be
+	//		unique, the specified ID is ignored and the system-generated ID is
+	//		used instead.
+	id: "",
+
+	// lang: [const] String
+	//		Rarely used.  Overrides the default Dojo locale used to render this widget,
+	//		as defined by the [HTML LANG](http://www.w3.org/TR/html401/struct/dirlang.html#adef-lang) attribute.
+	//		Value must be among the list of locales specified during by the Dojo bootstrap,
+	//		formatted according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt) (like en-us).
+	lang: "",
+
+	// dir: [const] String
+	//		Unsupported by Dijit, but here for completeness.  Dijit only supports setting text direction on the
+	//		entire document.
+	//		Bi-directional support, as defined by the [HTML DIR](http://www.w3.org/TR/html401/struct/dirlang.html#adef-dir)
+	//		attribute. Either left-to-right "ltr" or right-to-left "rtl".
+	dir: "",
+
+	// class: String
+	//		HTML class attribute
+	"class": "",
+
+	// style: String||Object
+	//		HTML style attributes as cssText string or name/value hash
+	style: "",
+
+	// title: String
+	//		HTML title attribute, used to specify the title of tabs, accordion panes, etc.
+	title: "",
+
+	// srcNodeRef: [readonly] DomNode
+	//		pointer to original dom node
+	srcNodeRef: null,
+
+	// domNode: [readonly] DomNode
+	//		This is our visible representation of the widget! Other DOM
+	//		Nodes may by assigned to other properties, usually through the
+	//		template system's dojoAttachPoint syntax, but the domNode
+	//		property is the canonical "top level" node in widget UI.
+	domNode: null,
+
+	// containerNode: [readonly] DomNode
+	//		Designates where children of the source dom node will be placed.
+	//		"Children" in this case refers to both dom nodes and widgets.
+	//		For example, for myWidget:
+	//
+	//		|	<div dojoType=myWidget>
+	//		|		<b> here's a plain dom node
+	//		|		<span dojoType=subWidget>and a widget</span>
+	//		|		<i> and another plain dom node </i>
+	//		|	</div>
+	//
+	//		containerNode would point to:
+	//
+	//		|		<b> here's a plain dom node
+	//		|		<span dojoType=subWidget>and a widget</span>
+	//		|		<i> and another plain dom node </i>
+	//
+	//		In templated widgets, "containerNode" is set via a
+	//		dojoAttachPoint assignment.
+	//
+	//		containerNode must be defined for any widget that accepts innerHTML
+	//		(like ContentPane or BorderContainer or even Button), and conversely
+	//		is null for widgets that don't, like TextBox.
+	containerNode: null,
+
+	// attributeMap: [protected] Object
+	//		attributeMap sets up a "binding" between attributes (aka properties)
+	//		of the widget and the widget's DOM.
+	//		Changes to widget attributes listed in attributeMap will be 
+	//		reflected into the DOM.
+	//
+	//		For example, calling attr('title', 'hello')
+	//		on a TitlePane will automatically cause the TitlePane's DOM to update
+	//		with the new title.
+	//
+	//		attributeMap is a hash where the key is an attribute of the widget,
+	//		and the value reflects a binding to a:
+	//
+	//		- DOM node attribute
+	// |		focus: {node: "focusNode", type: "attribute"}
+	// 		Maps this.focus to this.focusNode.focus
+	//
+	//		- DOM node innerHTML
+	//	|		title: { node: "titleNode", type: "innerHTML" }
+	//		Maps this.title to this.titleNode.innerHTML
+	//
+	//		- DOM node CSS class
+	// |		myClass: { node: "domNode", type: "class" }
+	//		Maps this.myClass to this.domNode.className
+	//
+	//		If the value is an array, then each element in the array matches one of the
+	//		formats of the above list.
+	//
+	//		There are also some shorthands for backwards compatibility:
+	//		- string --> { node: string, type: "attribute" }, for example:
+	//	|	"focusNode" ---> { node: "focusNode", type: "attribute" }
+	//		- "" --> { node: "domNode", type: "attribute" }
+	attributeMap: {id:"", dir:"", lang:"", "class":"", style:"", title:""},
+
+	// _deferredConnects: [protected] Object
+	//		attributeMap addendum for event handlers that should be connected only on first use
+	_deferredConnects: {
+		onClick: "",
+		onDblClick: "",
+		onKeyDown: "",
+		onKeyPress: "",
+		onKeyUp: "",
+		onMouseMove: "",
+		onMouseDown: "",
+		onMouseOut: "",
+		onMouseOver: "",
+		onMouseLeave: "",
+		onMouseEnter: "",
+		onMouseUp: ""},
+
+	onClick: dijit._connectOnUseEventHandler,
+	/*=====
+	onClick: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of mouse click events.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onDblClick: dijit._connectOnUseEventHandler,
+	/*=====
+	onDblClick: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of mouse double click events.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onKeyDown: dijit._connectOnUseEventHandler,
+	/*=====
+	onKeyDown: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of keys being pressed down.
+		// event:
+		//		key Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onKeyPress: dijit._connectOnUseEventHandler,
+	/*=====
+	onKeyPress: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of printable keys being typed.
+		// event:
+		//		key Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onKeyUp: dijit._connectOnUseEventHandler,
+	/*=====
+	onKeyUp: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of keys being released.
+		// event:
+		//		key Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseDown: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseDown: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse button is pressed down.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseMove: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseMove: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse moves over nodes contained within this widget.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseOut: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseOut: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse moves off of nodes contained within this widget.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseOver: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseOver: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse moves onto nodes contained within this widget.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseLeave: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseLeave: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse moves off of this widget.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseEnter: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseEnter: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse moves onto this widget.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseUp: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseUp: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse button is released.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+
+	// Constants used in templates
+	
+	// _blankGif: [protected] URL
+	//		Used by <img> nodes in templates that really get there image via CSS background-image
+	_blankGif: (dojo.config.blankGif || dojo.moduleUrl("dojo", "resources/blank.gif")),
+
+	//////////// INITIALIZATION METHODS ///////////////////////////////////////
+
+	postscript: function(/*Object?*/params, /*DomNode|String*/srcNodeRef){
+		// summary:
+		//		Kicks off widget instantiation.  See create() for details.
+		// tags:
+		//		private
+		this.create(params, srcNodeRef);
+	},
+
+	create: function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){
+		// summary:
+		//		Kick off the life-cycle of a widget
+		// params:
+		//		Hash of initialization parameters for widget, including
+		//		scalar values (like title, duration etc.) and functions,
+		//		typically callbacks like onClick.
+		// srcNodeRef:
+		//		If a srcNodeRef (dom node) is specified:
+		//			- use srcNodeRef.innerHTML as my contents
+		//			- if this is a behavioral widget then apply behavior
+		//			  to that srcNodeRef 
+		//			- otherwise, replace srcNodeRef with my generated DOM
+		//			  tree
+		// description:
+		//		To understand the process by which widgets are instantiated, it
+		//		is critical to understand what other methods create calls and
+		//		which of them you'll want to override. Of course, adventurous
+		//		developers could override create entirely, but this should
+		//		only be done as a last resort.
+		//
+		//		Below is a list of the methods that are called, in the order
+		//		they are fired, along with notes about what they do and if/when
+		//		you should over-ride them in your widget:
+		//
+		// * postMixInProperties:
+		//	|	* a stub function that you can over-ride to modify
+		//		variables that may have been naively assigned by
+		//		mixInProperties
+		// * widget is added to manager object here
+		// * buildRendering:
+		//	|	* Subclasses use this method to handle all UI initialization
+		//		Sets this.domNode.  Templated widgets do this automatically
+		//		and otherwise it just uses the source dom node.
+		// * postCreate:
+		//	|	* a stub function that you can over-ride to modify take
+		//		actions once the widget has been placed in the UI
+		// tags:
+		//		private
+
+		// store pointer to original dom tree
+		this.srcNodeRef = dojo.byId(srcNodeRef);
+
+		// For garbage collection.  An array of handles returned by Widget.connect()
+		// Each handle returned from Widget.connect() is an array of handles from dojo.connect()
+		this._connects = [];
+
+		// To avoid double-connects, remove entries from _deferredConnects
+		// that have been setup manually by a subclass (ex, by dojoAttachEvent).
+		// If a subclass has redefined a callback (ex: onClick) then assume it's being
+		// connected to manually.
+		this._deferredConnects = dojo.clone(this._deferredConnects);
+		for(var attr in this.attributeMap){
+			delete this._deferredConnects[attr]; // can't be in both attributeMap and _deferredConnects
+		}
+		for(attr in this._deferredConnects){
+			if(this[attr] !== dijit._connectOnUseEventHandler){
+				delete this._deferredConnects[attr];	// redefined, probably dojoAttachEvent exists
+			}
+		}
+
+		//mixin our passed parameters
+		if(this.srcNodeRef && (typeof this.srcNodeRef.id == "string")){ this.id = this.srcNodeRef.id; }
+		if(params){
+			this.params = params;
+			dojo.mixin(this,params);
+		}
+		this.postMixInProperties();
+
+		// generate an id for the widget if one wasn't specified
+		// (be sure to do this before buildRendering() because that function might
+		// expect the id to be there.)
+		if(!this.id){
+			this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
+		}
+		dijit.registry.add(this);
+
+		this.buildRendering();
+
+		if(this.domNode){
+			// Copy attributes listed in attributeMap into the [newly created] DOM for the widget.
+			this._applyAttributes();
+
+			var source = this.srcNodeRef;
+			if(source && source.parentNode){
+				source.parentNode.replaceChild(this.domNode, source);
+			}
+
+			// If the developer has specified a handler as a widget parameter
+			// (ex: new Button({onClick: ...})
+			// then naturally need to connect from dom node to that handler immediately, 
+			for(attr in this.params){
+				this._onConnect(attr);
+			}
+		}
+		
+		if(this.domNode){
+			this.domNode.setAttribute("widgetId", this.id);
+		}
+		this.postCreate();
+
+		// If srcNodeRef has been processed and removed from the DOM (e.g. TemplatedWidget) then delete it to allow GC.
+		if(this.srcNodeRef && !this.srcNodeRef.parentNode){
+			delete this.srcNodeRef;
+		}	
+
+		this._created = true;
+	},
+
+	_applyAttributes: function(){
+		// summary:
+		//		Step during widget creation to copy all widget attributes to the
+		//		DOM as per attributeMap and _setXXXAttr functions.
+		// description:
+		//		Skips over blank/false attribute values, unless they were explicitly specified
+		//		as parameters to the widget, since those are the default anyway,
+		//		and setting tabIndex="" is different than not setting tabIndex at all.
+		//
+		//		It processes the attributes in the attribute map first, and then
+		//		it goes through and processes the attributes for the _setXXXAttr
+		//		functions that have been specified
+		// tags:
+		//		private
+		var condAttrApply = function(attr, scope){
+			if( (scope.params && attr in scope.params) || scope[attr]){
+				scope.attr(attr, scope[attr]);
+			}
+		};
+		for(var attr in this.attributeMap){
+			condAttrApply(attr, this);
+		}
+		dojo.forEach(getAttrReg(this.declaredClass), function(a){
+			if(!(a in this.attributeMap)){
+				condAttrApply(a, this);
+			}
+		}, this);
+	},
+
+	postMixInProperties: function(){
+		// summary:
+		//		Called after the parameters to the widget have been read-in,
+		//		but before the widget template is instantiated. Especially
+		//		useful to set properties that are referenced in the widget
+		//		template.
+		// tags:
+		//		protected
+	},
+
+	buildRendering: function(){
+		// summary:
+		//		Construct the UI for this widget, setting this.domNode.  Most
+		//		widgets will mixin `dijit._Templated`, which implements this
+		//		method.
+		// tags:
+		//		protected
+		this.domNode = this.srcNodeRef || dojo.create('div');
+	},
+
+	postCreate: function(){
+		// summary:
+		//		Called after a widget's dom has been setup
+		// tags:
+		//		protected
+	},
+
+	startup: function(){
+		// summary:
+		//		Called after a widget's children, and other widgets on the page, have been created.
+		//		Provides an opportunity to manipulate any children before they are displayed.
+		//		This is useful for composite widgets that need to control or layout sub-widgets.
+		//		Many layout widgets can use this as a wiring phase.
+		this._started = true;
+	},
+
+	//////////// DESTROY FUNCTIONS ////////////////////////////////
+
+	destroyRecursive: function(/*Boolean?*/ preserveDom){
+		// summary:
+		// 		Destroy this widget and it's descendants. This is the generic
+		// 		"destructor" function that all widget users should call to
+		// 		cleanly discard with a widget. Once a widget is destroyed, it's
+		// 		removed from the manager object.
+		// preserveDom:
+		//		If true, this method will leave the original Dom structure
+		//		alone of descendant Widgets. Note: This will NOT work with
+		//		dijit._Templated widgets.
+
+		this.destroyDescendants(preserveDom);
+		this.destroy(preserveDom);
+	},
+
+	destroy: function(/*Boolean*/ preserveDom){
+		// summary:
+		// 		Destroy this widget, but not its descendants.
+		//		Will, however, destroy internal widgets such as those used within a template.
+		// preserveDom: Boolean
+		//		If true, this method will leave the original Dom structure alone.
+		//		Note: This will not yet work with _Templated widgets
+
+		this.uninitialize();
+		dojo.forEach(this._connects, function(array){
+			dojo.forEach(array, dojo.disconnect);
+		});
+
+		// destroy widgets created as part of template, etc.
+		dojo.forEach(this._supportingWidgets||[], function(w){ 
+			if(w.destroy){
+				w.destroy();
+			}
+		});
+		
+		this.destroyRendering(preserveDom);
+		dijit.registry.remove(this.id);
+	},
+
+	destroyRendering: function(/*Boolean?*/ preserveDom){
+		// summary:
+		//		Destroys the DOM nodes associated with this widget
+		// preserveDom:
+		//		If true, this method will leave the original Dom structure alone
+		//		during tear-down. Note: this will not work with _Templated
+		//		widgets yet. 
+		// tags:
+		//		protected
+
+		if(this.bgIframe){
+			this.bgIframe.destroy(preserveDom);
+			delete this.bgIframe;
+		}
+
+		if(this.domNode){
+			if(preserveDom){
+				dojo.removeAttr(this.domNode, "widgetId");
+			}else{
+				dojo.destroy(this.domNode);
+			}
+			delete this.domNode;
+		}
+
+		if(this.srcNodeRef){
+			if(!preserveDom){
+				dojo.destroy(this.srcNodeRef);
+			}
+			delete this.srcNodeRef;
+		}
+	},
+
+	destroyDescendants: function(/*Boolean?*/ preserveDom){
+		// summary:
+		//		Recursively destroy the children of this widget and their
+		//		descendants.
+		// preserveDom:
+		//		If true, the preserveDom attribute is passed to all descendant
+		//		widget's .destroy() method. Not for use with _Templated
+		//		widgets.
+
+		// get all direct descendants and destroy them recursively
+		dojo.forEach(this.getChildren(), function(widget){ 
+			if(widget.destroyRecursive){
+				widget.destroyRecursive(preserveDom);
+			}
+		});
+	},
+
+
+	uninitialize: function(){
+		// summary:
+		//		Stub function. Override to implement custom widget tear-down
+		//		behavior.
+		// tags:
+		//		protected
+		return false;
+	},
+
+	////////////////// MISCELLANEOUS METHODS ///////////////////
+
+	onFocus: function(){
+		// summary:
+		//		Called when the widget becomes "active" because
+		//		it or a widget inside of it either has focus, or has recently
+		//		been clicked.
+		// tags:
+		//		callback
+	},
+
+	onBlur: function(){
+		// summary:
+		//		Called when the widget stops being "active" because
+		//		focus moved to something outside of it, or the user
+		//		clicked somewhere outside of it, or the widget was
+		//		hidden.
+		// tags:
+		//		callback
+	},
+
+	_onFocus: function(e){
+		// summary:
+		//		This is where widgets do processing for when they are active,
+		//		such as changing CSS classes.  See onFocus() for more details.
+		// tags:
+		//		protected
+		this.onFocus();
+	},
+
+	_onBlur: function(){
+		// summary:
+		//		This is where widgets do processing for when they stop being active,
+		//		such as changing CSS classes.  See onBlur() for more details.
+		// tags:
+		//		protected
+		this.onBlur();
+	},
+
+	_onConnect: function(/*String*/ event){
+		// summary:
+		//		Called when someone connects to one of my handlers.
+		//		"Turn on" that handler if it isn't active yet.
+		//
+		//		This is also called for every single initialization parameter
+		//		so need to do nothing for parameters like "id".
+		// tags:
+		//		private
+		if(event in this._deferredConnects){
+			var mapNode = this[this._deferredConnects[event]||'domNode'];
+			this.connect(mapNode, event.toLowerCase(), event);
+			delete this._deferredConnects[event];
+		}
+	},
+
+	_setClassAttr: function(/*String*/ value){
+		// summary:
+		//		Custom setter for the CSS "class" attribute
+		// tags:
+		//		protected
+		var mapNode = this[this.attributeMap["class"]||'domNode'];
+		dojo.removeClass(mapNode, this["class"])
+		this["class"] = value;
+		dojo.addClass(mapNode, value);
+	},
+
+	_setStyleAttr: function(/*String||Object*/ value){
+		// summary:
+		//		Sets the style attribut of the widget according to value,
+		//		which is either a hash like {height: "5px", width: "3px"}
+		//		or a plain string
+		// description:
+		//		Determines which node to set the style on based on style setting
+		//		in attributeMap.
+		// tags:
+		//		protected
+
+		var mapNode = this[this.attributeMap["style"]||'domNode'];
+		
+		// Note: technically we should revert any style setting made in a previous call
+		// to his method, but that's difficult to keep track of.
+
+		if(dojo.isObject(value)){
+			dojo.style(mapNode, value);
+		}else{
+			if(mapNode.style.cssText){
+				mapNode.style.cssText += "; " + value;
+			}else{
+				mapNode.style.cssText = value;
+			}
+		}
+
+		this["style"] = value;
+	},
+
+	setAttribute: function(/*String*/ attr, /*anything*/ value){
+		// summary:
+		//		Deprecated.  Use attr() instead.
+		// tags:
+		//		deprecated
+		dojo.deprecated(this.declaredClass+"::setAttribute() is deprecated. Use attr() instead.", "", "2.0");
+		this.attr(attr, value);
+	},
+	
+	_attrToDom: function(/*String*/ attr, /*String*/ value){
+		// summary:
+		//		Reflect a widget attribute (title, tabIndex, duration etc.) to
+		//		the widget DOM, as specified in attributeMap.
+		//
+		// description:
+		//		Also sets this["attr"] to the new value.
+		//		Note some attributes like "type"
+		//		cannot be processed this way as they are not mutable.
+		//
+		// tags:
+		//		private
+
+		var commands = this.attributeMap[attr];
+		dojo.forEach( dojo.isArray(commands) ? commands : [commands], function(command){
+
+			// Get target node and what we are doing to that node
+			var mapNode = this[command.node || command || "domNode"];	// DOM node
+			var type = command.type || "attribute";	// class, innerHTML, or attribute
+	
+			switch(type){
+				case "attribute":
+					if(dojo.isFunction(value)){ // functions execute in the context of the widget
+						value = dojo.hitch(this, value);
+					}
+					if(/^on[A-Z][a-zA-Z]*$/.test(attr)){ // eg. onSubmit needs to be onsubmit
+						attr = attr.toLowerCase();
+					}
+					dojo.attr(mapNode, attr, value);
+					break;
+				case "innerHTML":
+					mapNode.innerHTML = value;
+					break;
+				case "class":
+					dojo.removeClass(mapNode, this[attr]);
+					dojo.addClass(mapNode, value);
+					break;
+			}
+		}, this);
+		this[attr] = value;
+	},
+
+	attr: function(/*String|Object*/name, /*Object?*/value){
+		//	summary:
+		//		Set or get properties on a widget instance.
+		//	name:
+		//		The property to get or set. If an object is passed here and not
+		//		a string, its keys are used as names of attributes to be set
+		//		and the value of the object as values to set in the widget.
+		//	value:
+		//		Optional. If provided, attr() operates as a setter. If omitted,
+		//		the current value of the named property is returned.
+		//	description:
+		//		Get or set named properties on a widget. If no value is
+		//		provided, the current value of the attribute is returned,
+		//		potentially via a getter method. If a value is provided, then
+		//		the method acts as a setter, assigning the value to the name,
+		//		potentially calling any explicitly provided setters to handle
+		//		the operation. For instance, if the widget has properties "foo"
+		//		and "bar" and a method named "_setFooAttr", calling:
+		//	|	myWidget.attr("foo", "Howdy!");
+		//		would be equivalent to calling:
+		//	|	widget._setFooAttr("Howdy!");
+		//		while calling:
+		//	|	myWidget.attr("bar", "Howdy!");
+		//		would be the same as writing:
+		//	|	widget.bar = "Howdy!";
+		//		It also tries to copy the changes to the widget's DOM according
+		//		to settings in attributeMap (see description of `dijit._Widget.attributeMap`
+		//		for details)
+		//		For example, calling:
+		//	|	myTitlePane.attr("title", "Howdy!");
+		//		will do
+		//	|	myTitlePane.title = "Howdy!";
+		//	|	myTitlePane.title.innerHTML = "Howdy!";
+		//		It works for dom node attributes too.  Calling
+		//	|	widget.attr("disabled", true)
+		//		will set the disabled attribute on the widget's focusNode,
+		//		among other housekeeping for a change in disabled state.
+
+		//	open questions:
+		//		- how to handle build shortcut for attributes which want to map
+		//		into DOM attributes?
+		//		- what relationship should setAttribute()/attr() have to
+		//		layout() calls?
+		var args = arguments.length;
+		if(args == 1 && !dojo.isString(name)){
+			for(var x in name){ this.attr(x, name[x]); }
+			return this;
+		}
+		var names = this._getAttrNames(name);
+		if(args == 2){ // setter
+			if(this[names.s]){
+				// use the explicit setter
+				return this[names.s](value) || this;
+			}else{
+				// if param is specified as DOM node attribute, copy it
+				if(name in this.attributeMap){
+					this._attrToDom(name, value);
+				}
+
+				// FIXME: what about function assignments? Any way to connect() here?
+				this[name] = value;
+			}
+			return this;
+		}else{ // getter
+			if(this[names.g]){
+				return this[names.g]();
+			}else{
+				return this[name];
+			}
+		}
+	},
+
+	_attrPairNames: {},		// shared between all widgets
+	_getAttrNames: function(name){
+		// summary:
+		//		Helper function for Widget.attr().
+		//		Caches attribute name values so we don't do the string ops every time.
+		// tags:
+		//		private
+
+		var apn = this._attrPairNames;
+		if(apn[name]){ return apn[name]; }
+		var uc = name.charAt(0).toUpperCase() + name.substr(1);
+		return apn[name] = {
+			n: name+"Node",
+			s: "_set"+uc+"Attr",
+			g: "_get"+uc+"Attr"
+		};
+	},
+
+	toString: function(){
+		// summary:
+		//		Returns a string that represents the widget. When a widget is
+		//		cast to a string, this method will be used to generate the
+		//		output. Currently, it does not implement any sort of reversable
+		//		serialization.
+		return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String
+	},
+
+	getDescendants: function(){
+		// summary:
+		//		Returns all the widgets that contained by this, i.e., all widgets underneath this.containerNode.
+		//		This method should generally be avoided as it returns widgets declared in templates, which are
+		//		supposed to be internal/hidden, but it's left here for back-compat reasons.
+
+		if(this.containerNode){
+			var list = dojo.query('[widgetId]', this.containerNode);
+			return list.map(dijit.byNode);		// Array
+		}else{
+			return [];
+		}
+	},
+
+	getChildren: function(){
+		// summary:
+		//		Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
+		//		Does not return nested widgets, nor widgets that are part of this widget's template.
+		if(this.containerNode){
+			return dijit.findWidgets(this.containerNode);
+		}else{
+			return [];
+		}
+	},
+
+	// nodesWithKeyClick: [private] String[]
+	//		List of nodes that correctly handle click events via native browser support,
+	//		and don't need dijit's help
+	nodesWithKeyClick: ["input", "button"],
+
+	connect: function(
+			/*Object|null*/ obj,
+			/*String|Function*/ event,
+			/*String|Function*/ method){
+		// summary:
+		//		Connects specified obj/event to specified method of this object
+		//		and registers for disconnect() on widget destroy.
+		// description:
+		//		Provide widget-specific analog to dojo.connect, except with the
+		//		implicit use of this widget as the target object.
+		//		This version of connect also provides a special "ondijitclick"
+		//		event which triggers on a click or space-up, enter-down in IE
+		//		or enter press in FF (since often can't cancel enter onkeydown
+		//		in FF)
+		// example:
+		//	|	var btn = new dijit.form.Button();
+		//	|	// when foo.bar() is called, call the listener we're going to
+		//	|	// provide in the scope of btn
+		//	|	btn.connect(foo, "bar", function(){ 
+		//	|		
+		//	|	});
+		// tags:
+		//		protected
+
+		var d = dojo;
+		var dc = dojo.connect;
+		var handles =[];
+		if(event == "ondijitclick"){
+			// add key based click activation for unsupported nodes.
+			if(!this.nodesWithKeyClick[obj.nodeName]){
+				var m = d.hitch(this, method);
+				handles.push(
+					dc(obj, "onkeydown", this, function(e){
+						if(!d.isFF && e.keyCode == d.keys.ENTER &&
+							!e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){
+							return m(e);
+						}else if(e.keyCode == d.keys.SPACE){
+							// stop space down as it causes IE to scroll
+							// the browser window
+							d.stopEvent(e);
+						}
+			 		}),
+					dc(obj, "onkeyup", this, function(e){
+						if(e.keyCode == d.keys.SPACE && 
+							!e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){ return m(e); }
+					})
+				);
+			 	if(d.isFF){
+					handles.push(
+						dc(obj, "onkeypress", this, function(e){
+							if(e.keyCode == d.keys.ENTER &&
+								!e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){ return m(e); }
+						})
+					);
+			 	}
+			}
+			event = "onclick";
+		}
+		handles.push(dc(obj, event, this, method));
+
+		// return handles for FormElement and ComboBox
+		this._connects.push(handles);
+		return handles;
+	},
+
+	disconnect: function(/*Object*/ handles){
+		// summary:
+		//		Disconnects handle created by this.connect.
+		//		Also removes handle from this widget's list of connects
+		// tags:
+		//		protected
+		for(var i=0; i<this._connects.length; i++){
+			if(this._connects[i]==handles){
+				dojo.forEach(handles, dojo.disconnect);
+				this._connects.splice(i, 1);
+				return;
+			}
+		}
+	},
+
+	isLeftToRight: function(){
+		// summary:
+		//		Checks the page for text direction
+		// tags:
+		//		protected
+		return dojo._isBodyLtr(); //Boolean
+	},
+
+	isFocusable: function(){
+		// summary:
+		//		Return true if this widget can currently be focused
+		//		and false if not
+		return this.focus && (dojo.style(this.domNode, "display") != "none");
+	},
+	
+	placeAt: function(/* String|DomNode|_Widget */reference, /* String?|Int? */position){
+		// summary:
+		//		Place this widget's domNode reference somewhere in the DOM based
+		//		on standard dojo.place conventions, or passing a Widget reference that
+		//		contains and addChild member.
+		//
+		// description:
+		//		A convenience function provided in all _Widgets, providing a simple
+		//		shorthand mechanism to put an existing (or newly created) Widget
+		//		somewhere in the dom, and allow chaining.
+		//
+		// reference: 
+		//		The String id of a domNode, a domNode reference, or a reference to a Widget posessing 
+		//		an addChild method.
+		//
+		// position: 
+		//		If passed a string or domNode reference, the position argument
+		//		accepts a string just as dojo.place does, one of: "first", "last", 
+		//		"before", or "after". 
+		//
+		//		If passed a _Widget reference, and that widget reference has an ".addChild" method, 
+		//		it will be called passing this widget instance into that method, supplying the optional
+		//		position index passed.
+		//
+		// returns: dijit._Widget
+		//		Provides a useful return of the newly created dijit._Widget instance so you 
+		//		can "chain" this function by instantiating, placing, then saving the return value
+		//		to a variable. 
+		//
+		// example:
+		// | 	// create a Button with no srcNodeRef, and place it in the body:
+		// | 	var button = new dijit.form.Button({ label:"click" }).placeAt(dojo.body());
+		// | 	// now, 'button' is still the widget reference to the newly created button
+		// | 	dojo.connect(button, "onClick", function(e){  });
+		//
+		// example:
+		// |	// create a button out of a node with id="src" and append it to id="wrapper":
+		// | 	var button = new dijit.form.Button({},"src").placeAt("wrapper");
+		//
+		// example:
+		// |	// place a new button as the first element of some div
+		// |	var button = new dijit.form.Button({ label:"click" }).placeAt("wrapper","first");
+		//
+		// example: 
+		// |	// create a contentpane and add it to a TabContainer
+		// |	var tc = dijit.byId("myTabs");
+		// |	new dijit.layout.ContentPane({ href:"foo.html", title:"Wow!" }).placeAt(tc)
+
+		if(reference["declaredClass"] && reference["addChild"]){
+			reference.addChild(this, position);
+		}else{
+			dojo.place(this.domNode, reference, position);
+		}
+		return this;
+	}
+
+});
+
+})();
+
+}
+
+if(!dojo._hasResource["dojo.string"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.string"] = true;
+dojo.provide("dojo.string");
+
+/*=====
+dojo.string = { 
+	// summary: String utilities for Dojo
+};
+=====*/
+
+dojo.string.rep = function(/*String*/str, /*Integer*/num){
+	//	summary:
+	//		Efficiently replicate a string `n` times.
+	//	str:
+	//		the string to replicate
+	//	num:
+	//		number of times to replicate the string
+	
+	if(num <= 0 || !str){ return ""; }
+	
+	var buf = [];
+	for(;;){
+		if(num & 1){
+			buf.push(str);
+		}
+		if(!(num >>= 1)){ break; }
+		str += str;
+	}
+	return buf.join("");	// String
+};
+
+dojo.string.pad = function(/*String*/text, /*Integer*/size, /*String?*/ch, /*Boolean?*/end){
+	//	summary:
+	//		Pad a string to guarantee that it is at least `size` length by
+	//		filling with the character `ch` at either the start or end of the
+	//		string. Pads at the start, by default.
+	//	text:
+	//		the string to pad
+	//	size:
+	//		length to provide padding
+	//	ch:
+	//		character to pad, defaults to '0'
+	//	end:
+	//		adds padding at the end if true, otherwise pads at start
+	//	example:
+	//	|	// Fill the string to length 10 with "+" characters on the right.  Yields "Dojo++++++".
+	//	|	dojo.string.pad("Dojo", 10, "+", true);
+
+	if(!ch){
+		ch = '0';
+	}
+	var out = String(text),
+		pad = dojo.string.rep(ch, Math.ceil((size - out.length) / ch.length));
+	return end ? out + pad : pad + out;	// String
+};
+
+dojo.string.substitute = function(	/*String*/		template, 
+									/*Object|Array*/map, 
+									/*Function?*/	transform, 
+									/*Object?*/		thisObject){
+	//	summary:
+	//		Performs parameterized substitutions on a string. Throws an
+	//		exception if any parameter is unmatched.
+	//	template: 
+	//		a string with expressions in the form `${key}` to be replaced or
+	//		`${key:format}` which specifies a format function. keys are case-sensitive. 
+	//	map:
+	//		hash to search for substitutions
+	//	transform: 
+	//		a function to process all parameters before substitution takes
+	//		place, e.g. dojo.string.encodeXML
+	//	thisObject: 
+	//		where to look for optional format function; default to the global
+	//		namespace
+	//	example:
+	//	|	// returns "File 'foo.html' is not found in directory '/temp'."
+	//	|	dojo.string.substitute(
+	//	|		"File '${0}' is not found in directory '${1}'.",
+	//	|		["foo.html","/temp"]
+	//	|	);
+	//	|
+	//	|	// also returns "File 'foo.html' is not found in directory '/temp'."
+	//	|	dojo.string.substitute(
+	//	|		"File '${name}' is not found in directory '${info.dir}'.",
+	//	|		{ name: "foo.html", info: { dir: "/temp" } }
+	//	|	);
+	//	example:
+	//		use a transform function to modify the values:
+	//	|	// returns "file 'foo.html' is not found in directory '/temp'."
+	//	|	dojo.string.substitute(
+	//	|		"${0} is not found in ${1}.",
+	//	|		["foo.html","/temp"],
+	//	|		function(str){
+	//	|			// try to figure out the type
+	//	|			var prefix = (str.charAt(0) == "/") ? "directory": "file";
+	//	|			return prefix + " '" + str + "'";
+	//	|		}
+	//	|	);
+	//	example:
+	//		use a formatter
+	//	|	// returns "thinger -- howdy"
+	//	|	dojo.string.substitute(
+	//	|		"${0:postfix}", ["thinger"], null, {
+	//	|			postfix: function(value, key){
+	//	|				return value + " -- howdy";
+	//	|			}
+	//	|		}
+	//	|	);
+
+	thisObject = thisObject||dojo.global;
+	transform = (!transform) ? 
+					function(v){ return v; } : 
+					dojo.hitch(thisObject, transform);
+
+	return template.replace(/\$\{([^\s\:\}]+)(?:\:([^\s\:\}]+))?\}/g, function(match, key, format){
+		var value = dojo.getObject(key, false, map);
+		if(format){
+			value = dojo.getObject(format, false, thisObject).call(thisObject, value, key);
+		}
+		return transform(value, key).toString();
+	}); // string
+};
+
+/*=====
+dojo.string.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 taken from [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript).
+	//		The short yet performant version of this function is dojo.trim(),
+	//		which is part of Dojo base.  Uses String.prototype.trim instead, if available.
+	return "";	// String
+}
+=====*/
+
+dojo.string.trim = String.prototype.trim ?
+	dojo.trim : // aliasing to the native function
+	function(str){
+		str = str.replace(/^\s+/, '');
+		for(var i = str.length - 1; i >= 0; i--){
+			if(/\S/.test(str.charAt(i))){
+				str = str.substring(0, i + 1);
+				break;
+			}
+		}
+		return str;
+	};
+
+}
+
+if(!dojo._hasResource["dijit._Templated"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._Templated"] = true;
+dojo.provide("dijit._Templated");
+
+
+
+
+
+dojo.declare("dijit._Templated",
+	null,
+	{
+		//	summary:
+		//		Mixin for widgets that are instantiated from a template
+		// 
+
+		// templateString: [protected] String
+		//		A string that represents the widget template. Pre-empts the
+		//		templatePath. In builds that have their strings "interned", the
+		//		templatePath is converted to an inline templateString, thereby
+		//		preventing a synchronous network call.
+		templateString: null,
+
+		// templatePath: [protected] String
+		//		Path to template (HTML file) for this widget relative to dojo.baseUrl
+		templatePath: null,
+
+		// widgetsInTemplate: [protected] Boolean
+		//		Should we parse the template to find widgets that might be
+		//		declared in markup inside it?  False by default.
+		widgetsInTemplate: false,
+
+		// skipNodeCache: [protected] Boolean
+		//		If using a cached widget template node poses issues for a
+		//		particular widget class, it can set this property to ensure
+		//		that its template is always re-built from a string
+		_skipNodeCache: false,
+
+		_stringRepl: function(tmpl){
+			// summary:
+			//		Does substitution of ${foo} type properties in template string
+			// tags:
+			//		private
+			var className = this.declaredClass, _this = this;
+			// Cache contains a string because we need to do property replacement
+			// do the property replacement
+			return dojo.string.substitute(tmpl, this, function(value, key){
+				if(key.charAt(0) == '!'){ value = dojo.getObject(key.substr(1), false, _this); }
+				if(typeof value == "undefined"){ throw new Error(className+" template:"+key); } // a debugging aide
+				if(value == null){ return ""; }
+
+				// Substitution keys beginning with ! will skip the transform step,
+				// in case a user wishes to insert unescaped markup, e.g. ${!foo}
+				return key.charAt(0) == "!" ? value :
+					// Safer substitution, see heading "Attribute values" in
+					// http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2
+					value.toString().replace(/"/g,"""); //TODO: add &amp? use encodeXML method?
+			}, this);
+		},
+
+		// method over-ride
+		buildRendering: function(){
+			// summary:
+			//		Construct the UI for this widget from a template, setting this.domNode.
+			// tags:
+			//		protected
+
+			// Lookup cached version of template, and download to cache if it
+			// isn't there already.  Returns either a DomNode or a string, depending on
+			// whether or not the template contains ${foo} replacement parameters.
+			var cached = dijit._Templated.getCachedTemplate(this.templatePath, this.templateString, this._skipNodeCache);
+
+			var node;
+			if(dojo.isString(cached)){
+				node = dojo._toDom(this._stringRepl(cached));
+			}else{
+				// if it's a node, all we have to do is clone it
+				node = cached.cloneNode(true);
+			}
+
+			this.domNode = node;
+
+			// recurse through the node, looking for, and attaching to, our
+			// attachment points and events, which should be defined on the template node.
+			this._attachTemplateNodes(node);
+
+			if(this.widgetsInTemplate){
+				var cw = (this._supportingWidgets = dojo.parser.parse(node));
+				this._attachTemplateNodes(cw, function(n,p){
+					return n[p];
+				});
+			}
+
+			this._fillContent(this.srcNodeRef);
+		},
+
+		_fillContent: function(/*DomNode*/ source){
+			// summary:
+			//		Relocate source contents to templated container node.
+			//		this.containerNode must be able to receive children, or exceptions will be thrown.
+			// tags:
+			//		protected
+			var dest = this.containerNode;
+			if(source && dest){
+				while(source.hasChildNodes()){
+					dest.appendChild(source.firstChild);
+				}
+			}
+		},
+
+		_attachTemplateNodes: function(rootNode, getAttrFunc){
+			// summary:
+			//		Iterate through the template and attach functions and nodes accordingly.	
+			// description:		
+			//		Map widget properties and functions to the handlers specified in
+			//		the dom node and it's descendants. This function iterates over all
+			//		nodes and looks for these properties:
+			//			* dojoAttachPoint
+			//			* dojoAttachEvent	
+			//			* waiRole
+			//			* waiState
+			// rootNode: DomNode|Array[Widgets]
+			//		the node to search for properties. All children will be searched.
+			// getAttrFunc: Function?
+			//		a function which will be used to obtain property for a given
+			//		DomNode/Widget
+			// tags:
+			//		private
+
+			getAttrFunc = getAttrFunc || function(n,p){ return n.getAttribute(p); };
+
+			var nodes = dojo.isArray(rootNode) ? rootNode : (rootNode.all || rootNode.getElementsByTagName("*"));
+			var x = dojo.isArray(rootNode) ? 0 : -1;
+			for(; x<nodes.length; x++){
+				var baseNode = (x == -1) ? rootNode : nodes[x];
+				if(this.widgetsInTemplate && getAttrFunc(baseNode, "dojoType")){
+					continue;
+				}
+				// Process dojoAttachPoint
+				var attachPoint = getAttrFunc(baseNode, "dojoAttachPoint");
+				if(attachPoint){
+					var point, points = attachPoint.split(/\s*,\s*/);
+					while((point = points.shift())){
+						if(dojo.isArray(this[point])){
+							this[point].push(baseNode);
+						}else{
+							this[point]=baseNode;
+						}
+					}
+				}
+
+				// Process dojoAttachEvent
+				var attachEvent = getAttrFunc(baseNode, "dojoAttachEvent");
+				if(attachEvent){
+					// NOTE: we want to support attributes that have the form
+					// "domEvent: nativeEvent; ..."
+					var event, events = attachEvent.split(/\s*,\s*/);
+					var trim = dojo.trim;
+					while((event = events.shift())){
+						if(event){
+							var thisFunc = null;
+							if(event.indexOf(":") != -1){
+								// oh, if only JS had tuple assignment
+								var funcNameArr = event.split(":");
+								event = trim(funcNameArr[0]);
+								thisFunc = trim(funcNameArr[1]);
+							}else{
+								event = trim(event);
+							}
+							if(!thisFunc){
+								thisFunc = event;
+							}
+							this.connect(baseNode, event, thisFunc);
+						}
+					}
+				}
+
+				// waiRole, waiState
+				var role = getAttrFunc(baseNode, "waiRole");
+				if(role){
+					dijit.setWaiRole(baseNode, role);
+				}
+				var values = getAttrFunc(baseNode, "waiState");
+				if(values){
+					dojo.forEach(values.split(/\s*,\s*/), function(stateValue){
+						if(stateValue.indexOf('-') != -1){
+							var pair = stateValue.split('-');
+							dijit.setWaiState(baseNode, pair[0], pair[1]);
+						}
+					});
+				}
+			}
+		}
+	}
+);
+
+// key is either templatePath or templateString; object is either string or DOM tree
+dijit._Templated._templateCache = {};
+
+dijit._Templated.getCachedTemplate = function(templatePath, templateString, alwaysUseString){
+	// summary:
+	//		Static method to get a template based on the templatePath or
+	//		templateString key
+	// templatePath: String
+	//		The URL to get the template from. dojo.uri.Uri is often passed as well.
+	// templateString: String?
+	//		a string to use in lieu of fetching the template from a URL. Takes precedence
+	//		over templatePath
+	// returns: Mixed
+	//		Either string (if there are ${} variables that need to be replaced) or just
+	//		a DOM tree (if the node can be cloned directly)
+
+	// is it already cached?
+	var tmplts = dijit._Templated._templateCache;
+	var key = templateString || templatePath;
+	var cached = tmplts[key];
+	if(cached){
+		if(!cached.ownerDocument || cached.ownerDocument == dojo.doc){
+			// string or node of the same document
+			return cached;
+		}
+		// destroy the old cached node of a different document
+		dojo.destroy(cached);
+	}
+
+	// If necessary, load template string from template path
+	if(!templateString){
+		templateString = dijit._Templated._sanitizeTemplateString(dojo.trim(dojo._getText(templatePath)));
+	}
+
+	templateString = dojo.string.trim(templateString);
+
+	if(alwaysUseString || templateString.match(/\$\{([^\}]+)\}/g)){
+		// there are variables in the template so all we can do is cache the string
+		return (tmplts[key] = templateString); //String
+	}else{
+		// there are no variables in the template so we can cache the DOM tree
+		return (tmplts[key] = dojo._toDom(templateString)); //Node
+	}
+};
+
+dijit._Templated._sanitizeTemplateString = function(/*String*/tString){
+	// summary: 
+	//		Strips <?xml ...?> declarations so that external SVG and XML
+	// 		documents can be added to a document without worry. Also, if the string
+	//		is an HTML document, only the part inside the body tag is returned.
+	if(tString){
+		tString = tString.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, "");
+		var matches = tString.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
+		if(matches){
+			tString = matches[1];
+		}
+	}else{
+		tString = "";
+	}
+	return tString; //String
+};
+
+
+if(dojo.isIE){
+	dojo.addOnWindowUnload(function(){
+		var cache = dijit._Templated._templateCache;
+		for(var key in cache){
+			var value = cache[key];
+			if(!isNaN(value.nodeType)){ // isNode equivalent
+				dojo.destroy(value);
+			}
+			delete cache[key];
+		}
+	});
+}
+
+// These arguments can be specified for widgets which are used in templates.
+// Since any widget can be specified as sub widgets in template, mix it
+// into the base widget class.  (This is a hack, but it's effective.)
+dojo.extend(dijit._Widget,{
+	dojoAttachEvent: "",
+	dojoAttachPoint: "",
+	waiRole: "",
+	waiState:""
+});
+
+}
+
+if(!dojo._hasResource["dijit._Container"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._Container"] = true;
+dojo.provide("dijit._Container");
+
+dojo.declare("dijit._Container",
+	null,
+	{
+		// summary:
+		//		Mixin for widgets that contain a set of widget children.
+		// description:
+		//		Use this mixin for widgets that needs to know about and
+		//		keep track of their widget children. Suitable for widgets like BorderContainer
+		//		and TabContainer which contain (only) a set of child widgets.
+		//
+		//		It's not suitable for widgets like ContentPane
+		//		which contains mixed HTML (plain DOM nodes in addition to widgets),
+		//		and where contained widgets are not necessarily directly below
+		//		this.containerNode.   In that case calls like addChild(node, position)
+		//		wouldn't make sense.
+
+		// isContainer: [protected] Boolean
+		//		Just a flag indicating that this widget descends from dijit._Container
+		isContainer: true,
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			if(!this.containerNode){
+				// all widgets with descendants must set containerNode
+   				this.containerNode = this.domNode;
+			}
+		},
+
+		addChild: function(/*Widget*/ widget, /*int?*/ insertIndex){
+			// summary:
+			//		Makes the given widget a child of this widget.
+			// description:
+			//		Inserts specified child widget's dom node as a child of this widget's
+			//		container node, and possibly does other processing (such as layout).
+
+			var refNode = this.containerNode;
+			if(insertIndex && typeof insertIndex == "number"){
+				var children = this.getChildren();
+				if(children && children.length >= insertIndex){
+					refNode = children[insertIndex-1].domNode;
+					insertIndex = "after";
+				}
+			}
+			dojo.place(widget.domNode, refNode, insertIndex);
+
+			// If I've been started but the child widget hasn't been started,
+			// start it now.  Make sure to do this after widget has been
+			// inserted into the DOM tree, so it can see that it's being controlled by me,
+			// so it doesn't try to size itself.
+			if(this._started && !widget._started){
+				widget.startup();
+			}
+		},
+
+		removeChild: function(/*Widget or int*/ widget){
+			// summary:
+			//		Removes the passed widget instance from this widget but does
+			//		not destroy it.  You can also pass in an integer indicating
+			//		the index within the container to remove
+			if(typeof widget == "number" && widget > 0){
+				widget = this.getChildren()[widget];
+			}
+			// If we cannot find the widget, just return
+			if(!widget || !widget.domNode){ return; }
+			
+			var node = widget.domNode;
+			node.parentNode.removeChild(node);	// detach but don't destroy
+		},
+
+		_nextElement: function(node){
+			// summary:
+			//      Find the next (non-text, non-comment etc) node
+			// tags:
+			//      private
+			do{
+				node = node.nextSibling;
+			}while(node && node.nodeType != 1);
+			return node;
+		},
+
+		_firstElement: function(node){
+			// summary:
+			//      Find the first (non-text, non-comment etc) node
+			// tags:
+			//      private
+			node = node.firstChild;
+			if(node && node.nodeType != 1){
+				node = this._nextElement(node);
+			}
+			return node;
+		},
+
+		getChildren: function(){
+			// summary:
+			//		Returns array of children widgets.
+			// description:
+			//		Returns the widgets that are directly under this.containerNode.
+			return dojo.query("> [widgetId]", this.containerNode).map(dijit.byNode); // Widget[]
+		},
+
+		hasChildren: function(){
+			// summary:
+			//		Returns true if widget has children, i.e. if this.containerNode contains something.
+			return !!this._firstElement(this.containerNode); // Boolean
+		},
+
+		destroyDescendants: function(/*Boolean*/ preserveDom){
+			// summary:
+			//      Destroys all the widgets inside this.containerNode,
+			//      but not this widget itself
+			dojo.forEach(this.getChildren(), function(child){ child.destroyRecursive(preserveDom); });
+		},
+	
+		_getSiblingOfChild: function(/*Widget*/ child, /*int*/ dir){
+			// summary:
+			//		Get the next or previous widget sibling of child
+			// dir:
+			//		if 1, get the next sibling
+			//		if -1, get the previous sibling
+			// tags:
+			//      private
+			var node = child.domNode;
+			var which = (dir>0 ? "nextSibling" : "previousSibling");
+			do{
+				node = node[which];
+			}while(node && (node.nodeType != 1 || !dijit.byNode(node)));
+			return node ? dijit.byNode(node) : null;
+		},
+		
+		getIndexOfChild: function(/*Widget*/ child){
+			// summary:
+			//		Gets the index of the child in this container or -1 if not found
+			var children = this.getChildren();
+			for(var i=0, c; c=children[i]; i++){
+				if(c == child){ 
+					return i; // int
+				}
+			}
+			return -1; // int
+		}
+	}
+);
+
+}
+
+if(!dojo._hasResource["dijit._Contained"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._Contained"] = true;
+dojo.provide("dijit._Contained");
+
+dojo.declare("dijit._Contained",
+		null,
+		{
+			// summary
+			//		Mixin for widgets that are children of a container widget
+			//
+			// example:
+			// | 	// make a basic custom widget that knows about it's parents
+			// |	dojo.declare("my.customClass",[dijit._Widget,dijit._Contained],{});
+			// 
+			getParent: function(){
+				// summary:
+				//		Returns the parent widget of this widget, assuming the parent
+				//		implements dijit._Container
+				for(var p=this.domNode.parentNode; p; p=p.parentNode){
+					var id = p.getAttribute && p.getAttribute("widgetId");
+					if(id){
+						var parent = dijit.byId(id);
+						return parent.isContainer ? parent : null;
+					}
+				}
+				return null;
+			},
+
+			_getSibling: function(which){
+				// summary:
+				//      Returns next or previous sibling
+				// which:
+				//      Either "next" or "previous"
+				// tags:
+				//      private
+				var node = this.domNode;
+				do{
+					node = node[which+"Sibling"];
+				}while(node && node.nodeType != 1);
+				if(!node){ return null; } // null
+				var id = node.getAttribute("widgetId");
+				return dijit.byId(id);
+			},
+
+			getPreviousSibling: function(){
+				// summary:
+				//		Returns null if this is the first child of the parent,
+				//		otherwise returns the next element sibling to the "left".
+
+				return this._getSibling("previous"); // Mixed
+			},
+
+			getNextSibling: function(){
+				// summary:
+				//		Returns null if this is the last child of the parent,
+				//		otherwise returns the next element sibling to the "right".
+
+				return this._getSibling("next"); // Mixed
+			},
+			
+			getIndexInParent: function(){
+				// summary:
+				//		Returns the index of this widget within its container parent.
+				//		It returns -1 if the parent does not exist, or if the parent
+				//		is not a dijit._Container
+				
+				var p = this.getParent();
+				if(!p || !p.getIndexOfChild){
+					return -1; // int
+				}
+				return p.getIndexOfChild(this); // int
+			}
+		}
+	);
+
+
+}
+
+if(!dojo._hasResource["dijit.layout._LayoutWidget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.layout._LayoutWidget"] = true;
+dojo.provide("dijit.layout._LayoutWidget");
+
+
+
+
+
+dojo.declare("dijit.layout._LayoutWidget",
+	[dijit._Widget, dijit._Container, dijit._Contained],
+	{
+		// summary:
+		//		Base class for a _Container widget which is responsible for laying out its children.
+		//		Widgets which mixin this code must define layout() to lay out the children.
+
+		// baseClass: [protected extension] String
+		//		This class name is applied to the widget's domNode
+		//		and also may be used to generate names for sub nodes,
+		//		like for example dijitTabContainer-content.
+		baseClass: "dijitLayoutContainer",
+
+		// isLayoutContainer: [private deprecated] Boolean
+		//		TODO: this is unused, but maybe it *should* be used for a child to
+		//		detect whether the parent is going to call resize() on it or not
+		//		(see calls to getParent() and resize() in this file)
+		isLayoutContainer: true,
+
+		postCreate: function(){
+			dojo.addClass(this.domNode, "dijitContainer");
+			dojo.addClass(this.domNode, this.baseClass);
+			
+			// TODO: this.inherited()
+		},
+
+		startup: function(){
+			// summary:
+			//		Called after all the widgets have been instantiated and their
+			//		dom nodes have been inserted somewhere under dojo.doc.body.
+			//
+			//		Widgets should override this method to do any initialization
+			//		dependent on other widgets existing, and then call
+			//		this superclass method to finish things off.
+			//
+			//		startup() in subclasses shouldn't do anything
+			//		size related because the size of the widget hasn't been set yet.
+
+			if(this._started){ return; }
+
+			// TODO: seems like this code should be in _Container.startup().
+			// Then things that don't extend LayoutContainer (like GridContainer)
+			// would get the behavior for free.
+			dojo.forEach(this.getChildren(), function(child){ child.startup(); });
+
+			// If I am a top level widget
+			if(!this.getParent || !this.getParent()){
+				// Do recursive sizing and layout of all my descendants
+				// (passing in no argument to resize means that it has to glean the size itself)
+				this.resize();
+
+				// Since my parent isn't a layout container, and my style is width=height=100% (or something similar),
+				// then I need to watch when the window resizes, and size myself accordingly.
+				// (Passing in no arguments to resize means that it has to glean the size itself.)
+				// TODO: make one global listener to avoid getViewport() per widget.
+				this._viewport = dijit.getViewport();
+				this.connect(dojo.global, 'onresize', function(){
+					var newViewport = dijit.getViewport();
+					if(newViewport.w != this._viewport.w ||  newViewport.h != this._viewport.h){
+						this._viewport = newViewport;
+						this.resize();
+					}
+				});
+			}
+			
+			this.inherited(arguments);
+		},
+
+		resize: function(changeSize, resultSize){
+			// summary:
+			//		Call this to resize a widget, or after its size has changed.
+			// description:
+			//		Change size mode:
+			//			When changeSize is specified, changes the marginBox of this widget
+			//			 and forces it to relayout its contents accordingly.
+			//			changeSize may specify height, width, or both.
+			//
+			//			If resultSize is specified it indicates the size the widget will
+			//			become after changeSize has been applied.
+			//
+			//		Notification mode:
+			//			When changeSize is null, indicates that the caller has already changed
+			//			the size of the widget, or perhaps it changed because the browser
+			//			window was resized.  Tells widget to relayout it's contents accordingly.
+			//
+			//			If resultSize is also specified it indicates the size the widget has
+			//			become.
+			//
+			//		In either mode, this method also:
+			//			1. Sets this._borderBox and this._contentBox to the new size of
+			//				the widget.  Queries the current domNode size if necessary.
+			//			2. Calls layout() to resize contents (and maybe adjust child widgets).	
+			//
+			// changeSize: Object?
+			//		Sets the widget to this margin-box size and position.
+			//		May include any/all of the following properties:
+			//	|	{w: int, h: int, l: int, t: int}
+			//
+			// resultSize: Object?
+			//		The margin-box size of this widget after applying changeSize (if 
+			//		changeSize is specified).  If caller knows this size and
+			//		passes it in, we don't need to query the browser to get the size.
+			//	|	{w: int, h: int}
+
+			var node = this.domNode;
+
+			// set margin box size, unless it wasn't specified, in which case use current size
+			if(changeSize){
+				dojo.marginBox(node, changeSize);
+
+				// set offset of the node
+				if(changeSize.t){ node.style.top = changeSize.t + "px"; }
+				if(changeSize.l){ node.style.left = changeSize.l + "px"; }
+			}
+
+			// If either height or width wasn't specified by the user, then query node for it.
+			// But note that setting the margin box and then immediately querying dimensions may return
+			// inaccurate results, so try not to depend on it.
+			var mb = resultSize || {};
+			dojo.mixin(mb, changeSize || {});	// changeSize overrides resultSize
+			if ( !("h" in mb) || !("w" in mb) ){
+				mb = dojo.mixin(dojo.marginBox(node), mb);	// just use dojo.marginBox() to fill in missing values
+			}
+
+			// Compute and save the size of my border box and content box
+			// (w/out calling dojo.contentBox() since that may fail if size was recently set)
+			var cs = dojo.getComputedStyle(node);
+			var me = dojo._getMarginExtents(node, cs);
+			var be = dojo._getBorderExtents(node, cs);
+			var bb = (this._borderBox = {
+				w: mb.w - (me.w + be.w),
+				h: mb.h - (me.h + be.h)
+			});
+			var pe = dojo._getPadExtents(node, cs);
+			this._contentBox = {
+				l: dojo._toPixelValue(node, cs.paddingLeft),
+				t: dojo._toPixelValue(node, cs.paddingTop),
+				w: bb.w - pe.w,
+				h: bb.h - pe.h
+			};
+
+			// Callback for widget to adjust size of it's children
+			this.layout();
+		},
+
+		layout: function(){
+			// summary:
+			//		Widgets override this method to size and position their contents/children.
+			//		When this is called this._contentBox is guaranteed to be set (see resize()).
+			//
+			//		This is called after startup(), and also when the widget's size has been
+			//		changed.
+			// tags:
+			//		protected extension
+		},
+
+		_setupChild: function(/*Widget*/child){
+			// summary:
+			//		Common setup for initial children and children which are added after startup
+			// tags:
+			//		protected extension
+
+			dojo.addClass(child.domNode, this.baseClass+"-child");
+			if(child.baseClass){
+				dojo.addClass(child.domNode, this.baseClass+"-"+child.baseClass);
+			}
+		},
+
+		addChild: function(/*Widget*/ child, /*Integer?*/ insertIndex){
+			// Overrides _Container.addChild() to call _setupChild()
+			this.inherited(arguments);
+			if(this._started){
+				this._setupChild(child);
+			}
+		},
+
+		removeChild: function(/*Widget*/ child){
+			// Overrides _Container.removeChild() to remove class added by _setupChild()
+			dojo.removeClass(child.domNode, this.baseClass+"-child");
+			if(child.baseClass){
+				dojo.removeClass(child.domNode, this.baseClass+"-"+child.baseClass);
+			}
+			this.inherited(arguments);
+		}
+	}
+);
+
+dijit.layout.marginBox2contentBox = function(/*DomNode*/ node, /*Object*/ mb){
+	// summary:
+	//		Given the margin-box size of a node, return its content box size.
+	//		Functions like dojo.contentBox() but is more reliable since it doesn't have
+	//		to wait for the browser to compute sizes.
+	var cs = dojo.getComputedStyle(node);
+	var me = dojo._getMarginExtents(node, cs);
+	var pb = dojo._getPadBorderExtents(node, cs);
+	return {
+		l: dojo._toPixelValue(node, cs.paddingLeft),
+		t: dojo._toPixelValue(node, cs.paddingTop),
+		w: mb.w - (me.w + pb.w),
+		h: mb.h - (me.h + pb.h)
+	};
+};
+
+(function(){
+	var capitalize = function(word){
+		return word.substring(0,1).toUpperCase() + word.substring(1);
+	};
+
+	var size = function(widget, dim){
+		// size the child
+		widget.resize ? widget.resize(dim) : dojo.marginBox(widget.domNode, dim);
+
+		// record child's size, but favor our own numbers when we have them.
+		// the browser lies sometimes
+		dojo.mixin(widget, dojo.marginBox(widget.domNode));
+		dojo.mixin(widget, dim);
+	};
+
+	dijit.layout.layoutChildren = function(/*DomNode*/ container, /*Object*/ dim, /*Object[]*/ children){
+		// summary
+		//		Layout a bunch of child dom nodes within a parent dom node
+		// container:
+		//		parent node
+		// dim:
+		//		{l, t, w, h} object specifying dimensions of container into which to place children
+		// children:
+		//		an array like [ {domNode: foo, layoutAlign: "bottom" }, {domNode: bar, layoutAlign: "client"} ]
+
+		// copy dim because we are going to modify it
+		dim = dojo.mixin({}, dim);
+
+		dojo.addClass(container, "dijitLayoutContainer");
+
+		// Move "client" elements to the end of the array for layout.  a11y dictates that the author
+		// needs to be able to put them in the document in tab-order, but this algorithm requires that
+		// client be last.
+		children = dojo.filter(children, function(item){ return item.layoutAlign != "client"; })
+			.concat(dojo.filter(children, function(item){ return item.layoutAlign == "client"; }));
+
+		// set positions/sizes
+		dojo.forEach(children, function(child){
+			var elm = child.domNode,
+				pos = child.layoutAlign;
+
+			// set elem to upper left corner of unused space; may move it later
+			var elmStyle = elm.style;
+			elmStyle.left = dim.l+"px";
+			elmStyle.top = dim.t+"px";
+			elmStyle.bottom = elmStyle.right = "auto";
+
+			dojo.addClass(elm, "dijitAlign" + capitalize(pos));
+
+			// set size && adjust record of remaining space.
+			// note that setting the width of a <div> may affect it's height.
+			if(pos == "top" || pos == "bottom"){
+				size(child, { w: dim.w });
+				dim.h -= child.h;
+				if(pos=="top"){
+					dim.t += child.h;
+				}else{
+					elmStyle.top = dim.t + dim.h + "px";
+				}
+			}else if(pos == "left" || pos == "right"){
+				size(child, { h: dim.h });
+				dim.w -= child.w;
+				if(pos == "left"){
+					dim.l += child.w;
+				}else{
+					elmStyle.left = dim.l + dim.w + "px";
+				}
+			}else if(pos == "client"){
+				size(child, dim);
+			}
+		});
+	};
+
+})();
+
+}
+
+if(!dojo._hasResource["dijit.form._FormWidget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form._FormWidget"] = true;
+dojo.provide("dijit.form._FormWidget");
+
+
+
+
+dojo.declare("dijit.form._FormWidget", [dijit._Widget, dijit._Templated],
+	{
+	//
+	// summary:
+	//		Base class for widgets corresponding to native HTML elements such as <checkbox> or <button>,
+	//		which can be children of a <form> node or a `dijit.form.Form` widget.
+	//
+	// description:
+	//		Represents a single HTML element.
+	//		All these widgets should have these attributes just like native HTML input elements.
+	//		You can set them during widget construction or afterwards, via `dijit._Widget.attr`.
+	//
+	//	They also share some common methods.
+
+	// baseClass: [protected] String
+	//		Root CSS class of the widget (ex: dijitTextBox), used to add CSS classes of widget
+	//		(ex: "dijitTextBox dijitTextBoxInvalid dijitTextBoxFocused dijitTextBoxInvalidFocused")
+	//		See _setStateClass().
+	baseClass: "",
+
+	// name: String
+	//		Name used when submitting form; same as "name" attribute or plain HTML elements
+	name: "",
+
+	// alt: String
+	//		Corresponds to the native HTML <input> element's attribute.
+	alt: "",
+
+	// value: String
+	//		Corresponds to the native HTML <input> element's attribute.
+	value: "",
+
+	// type: String
+	//		Corresponds to the native HTML <input> element's attribute.
+	type: "text",
+
+	// tabIndex: Integer
+	//		Order fields are traversed when user hits the tab key
+	tabIndex: "0",
+
+	// disabled: Boolean
+	//		Should this widget respond to user input?
+	//		In markup, this is specified as "disabled='disabled'", or just "disabled".
+	disabled: false,
+
+	// readOnly: Boolean
+	//		Should this widget respond to user input?
+	//		In markup, this is specified as "readOnly".
+	//		Similar to disabled except readOnly form values are submitted.
+	readOnly: false,
+
+	// intermediateChanges: Boolean
+	//		Fires onChange for each value change or only on demand
+	intermediateChanges: false,
+
+	// scrollOnFocus: Boolean
+	//		On focus, should this widget scroll into view?
+	scrollOnFocus: true,
+
+	// These mixins assume that the focus node is an INPUT, as many but not all _FormWidgets are.
+	attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
+		value: "focusNode",
+		disabled: "focusNode",
+		readOnly: "focusNode",
+		id: "focusNode",
+		tabIndex: "focusNode",
+		alt: "focusNode"
+	}),
+
+	postMixInProperties: function(){
+		// Setup name=foo string to be referenced from the template (but only if a name has been specified)
+		// Unfortunately we can't use attributeMap to set the name due to IE limitations, see #8660
+		this.nameAttrSetting = this.name ? ("name='" + this.name + "'") : "";
+		this.inherited(arguments);
+	},
+
+	_setDisabledAttr: function(/*Boolean*/ value){
+		this.disabled = value;
+		dojo.attr(this.focusNode, 'disabled', value);
+		dijit.setWaiState(this.focusNode, "disabled", value);
+
+				if(value){
+					//reset those, because after the domNode is disabled, we can no longer receive
+					//mouse related events, see #4200
+					this._hovering = false;
+					this._active = false;
+					// remove the tabIndex, especially for FF
+					this.focusNode.removeAttribute('tabIndex');
+				}else{
+					this.focusNode.setAttribute('tabIndex', this.tabIndex);
+				}
+				this._setStateClass();
+	},
+
+	setDisabled: function(/*Boolean*/ disabled){
+		// summary:
+		//		Deprecated.   Use attr('disabled', ...) instead.
+		dojo.deprecated("setDisabled("+disabled+") is deprecated. Use attr('disabled',"+disabled+") instead.", "", "2.0");
+		this.attr('disabled', disabled);
+	},
+
+	_onFocus: function(e){
+		if(this.scrollOnFocus){
+			dijit.scrollIntoView(this.domNode);
+		}
+		this.inherited(arguments);
+	},
+
+	_onMouse : function(/*Event*/ event){
+		// summary:
+		//	Sets _hovering, _active, and stateModifier properties depending on mouse state,
+		//	then calls setStateClass() to set appropriate CSS classes for this.domNode.
+		//
+		//	To get a different CSS class for hover, send onmouseover and onmouseout events to this method.
+		//	To get a different CSS class while mouse button is depressed, send onmousedown to this method.
+
+		var mouseNode = event.currentTarget;
+		if(mouseNode && mouseNode.getAttribute){
+			this.stateModifier = mouseNode.getAttribute("stateModifier") || "";
+		}
+
+		if(!this.disabled){
+			switch(event.type){
+				case "mouseenter":
+				case "mouseover":
+					this._hovering = true;
+					this._active = this._mouseDown;
+					break;
+
+				case "mouseout":
+				case "mouseleave":
+					this._hovering = false;
+					this._active = false;
+					break;
+
+				case "mousedown" :
+					this._active = true;
+					this._mouseDown = true;
+					// set a global event to handle mouseup, so it fires properly
+					//	even if the cursor leaves the button
+					var mouseUpConnector = this.connect(dojo.body(), "onmouseup", function(){
+						//if user clicks on the button, even if the mouse is released outside of it,
+						//this button should get focus (which mimics native browser buttons)
+						if(this._mouseDown && this.isFocusable()){
+							this.focus();
+						}
+						this._active = false;
+						this._mouseDown = false;
+						this._setStateClass();
+						this.disconnect(mouseUpConnector);
+					});
+					break;
+			}
+			this._setStateClass();
+		}
+	},
+
+	isFocusable: function(){
+		// summary:
+		//		Tells if this widget is focusable or not.   Used internally by dijit.
+		// tags:
+		//		protected
+		return !this.disabled && !this.readOnly && this.focusNode && (dojo.style(this.domNode, "display") != "none");
+	},
+
+	focus: function(){
+		// summary:
+		//		Put focus on this widget
+		dijit.focus(this.focusNode);
+	},
+
+	_setStateClass: function(){
+		// summary:
+		//		Update the visual state of the widget by setting the css classes on this.domNode
+		//		(or this.stateNode if defined) by combining this.baseClass with
+		//		various suffixes that represent the current widget state(s).
+		//
+		// description:
+		//		In the case where a widget has multiple
+		//		states, it sets the class based on all possible
+		//	 	combinations.  For example, an invalid form widget that is being hovered
+		//		will be "dijitInput dijitInputInvalid dijitInputHover dijitInputInvalidHover".
+		//
+		//		For complex widgets with multiple regions, there can be various hover/active states,
+		//		such as "Hover" or "CloseButtonHover" (for tab buttons).
+		//		This is controlled by a stateModifier="CloseButton" attribute on the close button node.
+		//
+		//		The widget may have one or more of the following states, determined
+		//		by this.state, this.checked, this.valid, and this.selected:
+		//			- Error - ValidationTextBox sets this.state to "Error" if the current input value is invalid
+		//			- Checked - ex: a checkmark or a ToggleButton in a checked state, will have this.checked==true
+		//			- Selected - ex: currently selected tab will have this.selected==true
+		//
+		//		In addition, it may have one or more of the following states,
+		//		based on this.disabled and flags set in _onMouse (this._active, this._hovering, this._focused):
+		//			- Disabled	- if the widget is disabled
+		//			- Active		- if the mouse (or space/enter key?) is being pressed down
+		//			- Focused		- if the widget has focus
+		//			- Hover		- if the mouse is over the widget
+
+		// Compute new set of classes
+		var newStateClasses = this.baseClass.split(" ");
+
+		function multiply(modifier){
+			newStateClasses = newStateClasses.concat(dojo.map(newStateClasses, function(c){ return c+modifier; }), "dijit"+modifier);
+		}
+
+		if(this.checked){
+			multiply("Checked");
+		}
+		if(this.state){
+			multiply(this.state);
+		}
+		if(this.selected){
+			multiply("Selected");
+		}
+
+		if(this.disabled){
+			multiply("Disabled");
+		}else if(this.readOnly){
+			multiply("ReadOnly");
+		}else if(this._active){
+			multiply(this.stateModifier+"Active");
+		}else{
+			if(this._focused){
+				multiply("Focused");
+			}
+			if(this._hovering){
+				multiply(this.stateModifier+"Hover");
+			}
+		}
+
+		// Remove old state classes and add new ones.
+		// For performance concerns we only write into domNode.className once.
+		var tn = this.stateNode || this.domNode,
+			classHash = {};	// set of all classes (state and otherwise) for node
+
+		dojo.forEach(tn.className.split(" "), function(c){ classHash[c] = true; });
+
+		if("_stateClasses" in this){
+			dojo.forEach(this._stateClasses, function(c){ delete classHash[c]; });
+		}
+
+		dojo.forEach(newStateClasses, function(c){ classHash[c] = true; });
+
+		var newClasses = [];
+		for(var c in classHash){
+			newClasses.push(c);
+		}
+		tn.className = newClasses.join(" ");
+
+		this._stateClasses = newStateClasses;
+	},
+
+	compare: function(/*anything*/val1, /*anything*/val2){
+		// summary:
+		//		Compare 2 values (as returned by attr('value') for this widget).
+		// tags:
+		//		protected
+		if((typeof val1 == "number") && (typeof val2 == "number")){
+			return (isNaN(val1) && isNaN(val2))? 0 : (val1-val2);
+		}else if(val1 > val2){ return 1; }
+		else if(val1 < val2){ return -1; }
+		else { return 0; }
+	},
+
+	onChange: function(newValue){
+		// summary:
+		//		Callback when this widget's value is changed.
+		// tags:
+		//		callback
+	},
+
+	// _onChangeActive: [private] Boolean
+	//		Indicates that changes to the value should call onChange() callback.
+	//		This is false during widget initialization, to avoid calling onChange()
+	//		when the initial value is set.
+	_onChangeActive: false,
+
+	_handleOnChange: function(/*anything*/ newValue, /* Boolean? */ priorityChange){
+		// summary:
+		//		Called when the value of the widget is set.  Calls onChange() if appropriate
+		// newValue:
+		//		the new value
+		// priorityChange:
+		//		For a slider, for example, dragging the slider is priorityChange==false,
+		//		but on mouse up, it's priorityChange==true.  If intermediateChanges==true,
+		//		onChange is only called form priorityChange=true events.
+		// tags:
+		//		private
+		this._lastValue = newValue;
+		if(this._lastValueReported == undefined && (priorityChange === null || !this._onChangeActive)){
+			// this block executes not for a change, but during initialization,
+			// and is used to store away the original value (or for ToggleButton, the original checked state)
+			this._resetValue = this._lastValueReported = newValue;
+		}
+		if((this.intermediateChanges || priorityChange || priorityChange === undefined) &&
+			((typeof newValue != typeof this._lastValueReported) ||
+				this.compare(newValue, this._lastValueReported) != 0)){
+			this._lastValueReported = newValue;
+			if(this._onChangeActive){ this.onChange(newValue); }
+		}
+	},
+
+	create: function(){
+		// Overrides _Widget.create()
+		this.inherited(arguments);
+		this._onChangeActive = true;
+		this._setStateClass();
+	},
+
+	destroy: function(){
+		if(this._layoutHackHandle){
+			clearTimeout(this._layoutHackHandle);
+		}
+		this.inherited(arguments);
+	},
+
+	setValue: function(/*String*/ value){
+		// summary:
+		//		Deprecated.   Use attr('value', ...) instead.
+		dojo.deprecated("dijit.form._FormWidget:setValue("+value+") is deprecated.  Use attr('value',"+value+") instead.", "", "2.0");
+		this.attr('value', value);
+	},
+
+	getValue: function(){
+		// summary:
+		//		Deprecated.   Use attr('value') instead.
+		dojo.deprecated(this.declaredClass+"::getValue() is deprecated. Use attr('value') instead.", "", "2.0");
+		return this.attr('value');
+	},
+
+	_layoutHack: function(){
+		// summary:
+		//		Work around table sizing bugs on FF2 by forcing redraw
+
+		if(dojo.isFF == 2 && !this._layoutHackHandle){
+			var node=this.domNode;
+			var old = node.style.opacity;
+			node.style.opacity = "0.999";
+			this._layoutHackHandle = setTimeout(dojo.hitch(this, function(){
+				this._layoutHackHandle = null;
+				node.style.opacity = old;
+			}), 0);
+		}
+	}
+});
+
+dojo.declare("dijit.form._FormValueWidget", dijit.form._FormWidget,
+{
+	// summary:
+	//		Base class for widgets corresponding to native HTML elements such as <input> or <select> that have user changeable values.
+	// description:
+	//		Each _FormValueWidget represents a single input value, and has a (possibly hidden) <input> element,
+	//		to which it serializes it's input value, so that form submission (either normal submission or via FormBind?)
+	//		works as expected.
+
+	// Don't attempt to mixin the 'type', 'name' attributes here programatically -- they must be declared
+	// directly in the template as read by the parser in order to function. IE is known to specifically
+	// require the 'name' attribute at element creation time.   See #8484, #8660.
+	// TODO: unclear what that {value: ""} is for; FormWidget.attributeMap copies value to focusNode,
+	// so maybe {value: ""} is so the value *doesn't* get copied to focusNode?
+	// Seems like we really want value removed from attributeMap altogether
+	// (although there's no easy way to do that now)
+	attributeMap: dojo.delegate(dijit.form._FormWidget.prototype.attributeMap, { value: "" }),
+
+	postCreate: function(){
+		if(dojo.isIE || dojo.isWebKit){ // IE won't stop the event with keypress and Safari won't send an ESCAPE to keypress at all
+			this.connect(this.focusNode || this.domNode, "onkeydown", this._onKeyDown);
+		}
+		// Update our reset value if it hasn't yet been set (because this.attr
+		// is only called when there *is* a value
+		if(this._resetValue === undefined){
+			this._resetValue = this.value;
+		}
+	},
+
+	_setValueAttr: function(/*anything*/ newValue, /*Boolean, optional*/ priorityChange){
+		// summary:
+		//		Hook so attr('value', value) works.
+		// description:
+		//		Sets the value of the widget.
+		//		If the value has changed, then fire onChange event, unless priorityChange
+		//		is specified as null (or false?)
+		this.value = newValue;
+		this._handleOnChange(newValue, priorityChange);
+	},
+
+	_getValueAttr: function(/*String*/ value){
+		// summary:
+		//		Hook so attr('value') works.
+		return this._lastValue;
+	},
+
+	undo: function(){
+		// summary:
+		//		Restore the value to the last value passed to onChange
+		this._setValueAttr(this._lastValueReported, false);
+	},
+
+	reset: function(){
+		// summary:
+		//		Reset the widget's value to what it was at initialization time
+		this._hasBeenBlurred = false;
+		this._setValueAttr(this._resetValue, true);
+	},
+
+	_onKeyDown: function(e){
+		if(e.keyCode == dojo.keys.ESCAPE && !e.ctrlKey && !e.altKey){
+			var te;
+			if(dojo.isIE){ 
+				e.preventDefault(); // default behavior needs to be stopped here since keypress is too late
+				te = document.createEventObject();
+				te.keyCode = dojo.keys.ESCAPE;
+				te.shiftKey = e.shiftKey;
+				e.srcElement.fireEvent('onkeypress', te);
+			}else if(dojo.isWebKit){ // ESCAPE needs help making it into keypress
+				te = document.createEvent('Events');
+				te.initEvent('keypress', true, true);
+				te.keyCode = dojo.keys.ESCAPE;
+				te.shiftKey = e.shiftKey;
+				e.target.dispatchEvent(te);
+			}
+		}
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit.dijit"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.dijit"] = true;
+dojo.provide("dijit.dijit");
+
+/*=====
+dijit.dijit = {
+	// summary: A roll-up for common dijit methods
+	// description:
+	//	A rollup file for the build system including the core and common
+	//	dijit files.
+	//	
+	// example:
+	// | <script type="text/javascript" src="js/dojo/dijit/dijit.js"></script>
+	//
+};
+=====*/
+
+// All the stuff in _base (these are the function that are guaranteed available without an explicit dojo.require)
+
+
+// And some other stuff that we tend to pull in all the time anyway
+
+
+
+
+
+
+
+}
+
diff --git a/dijit/form/Button.js b/dijit/form/Button.js
new file mode 100644
index 0000000..db7cf9b
--- /dev/null
+++ b/dijit/form/Button.js
@@ -0,0 +1,232 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.Button"]){
+dojo._hasResource["dijit.form.Button"]=true;
+dojo.provide("dijit.form.Button");
+dojo.require("dijit.form._FormWidget");
+dojo.require("dijit._Container");
+dojo.declare("dijit.form.Button",dijit.form._FormWidget,{label:"",showLabel:true,iconClass:"",type:"button",baseClass:"dijitButton",templateString:"<span class=\"dijit dijitReset dijitLeft dijitInline\"\n\tdojoAttachEvent=\"ondijitclick:_onButtonClick,onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\"\n\t><span class=\"dijitReset dijitRight dijitInline\"\n\t\t><span class=\"dijitReset dijitInline dijitButtonNode\"\n\t\t\t><button class=\"dijitReset dijitStretch dijitButto [...]
+if(this.disabled||this.readOnly){
+return false;
+}
+this._clicked();
+return this.onClick(e);
+},_onButtonClick:function(e){
+if(e.type!="click"&&!(this.type=="submit"||this.type=="reset")){
+dojo.stopEvent(e);
+}
+if(this._onClick(e)===false){
+e.preventDefault();
+}else{
+if(this.type=="submit"&&!this.focusNode.form){
+for(var _3=this.domNode;_3.parentNode;_3=_3.parentNode){
+var _4=dijit.byNode(_3);
+if(_4&&typeof _4._onSubmit=="function"){
+_4._onSubmit(e);
+break;
+}
+}
+}
+}
+},_setValueAttr:function(_5){
+var _6=this.attributeMap.value||"";
+if(this[_6.node||_6||"domNode"].tagName=="BUTTON"){
+if(_5!=this.value){
+
+}
+}
+},_fillContent:function(_7){
+if(_7&&!("label" in this.params)){
+this.attr("label",_7.innerHTML);
+}
+},postCreate:function(){
+if(this.showLabel==false){
+dojo.addClass(this.containerNode,"dijitDisplayNone");
+}
+dojo.setSelectable(this.focusNode,false);
+this.inherited(arguments);
+},onClick:function(e){
+return true;
+},_clicked:function(e){
+},setLabel:function(_a){
+dojo.deprecated("dijit.form.Button.setLabel() is deprecated.  Use attr('label', ...) instead.","","2.0");
+this.attr("label",_a);
+},_setLabelAttr:function(_b){
+this.containerNode.innerHTML=this.label=_b;
+this._layoutHack();
+if(this.showLabel==false&&!this.params.title){
+this.titleNode.title=dojo.trim(this.containerNode.innerText||this.containerNode.textContent||"");
+}
+}});
+dojo.declare("dijit.form.DropDownButton",[dijit.form.Button,dijit._Container],{baseClass:"dijitDropDownButton",templateString:"<span class=\"dijit dijitReset dijitLeft dijitInline\"\n\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse,onclick:_onDropDownClick,onkeydown:_onDropDownKeydown,onblur:_onDropDownBlur,onkeypress:_onKey\"\n\t><span class='dijitReset dijitRight dijitInline'\n\t\t><span class='dijitReset dijitInline dijitButtonNode'\n\t\t\t><button  [...]
+if(this.srcNodeRef){
+var _c=dojo.query("*",this.srcNodeRef);
+dijit.form.DropDownButton.superclass._fillContent.call(this,_c[0]);
+this.dropDownContainer=this.srcNodeRef;
+}
+},startup:function(){
+if(this._started){
+return;
+}
+if(!this.dropDown){
+var _d=dojo.query("[widgetId]",this.dropDownContainer)[0];
+this.dropDown=dijit.byNode(_d);
+delete this.dropDownContainer;
+}
+dijit.popup.prepare(this.dropDown.domNode);
+this.inherited(arguments);
+},destroyDescendants:function(){
+if(this.dropDown){
+this.dropDown.destroyRecursive();
+delete this.dropDown;
+}
+this.inherited(arguments);
+},_onArrowClick:function(e){
+if(this.disabled||this.readOnly){
+return;
+}
+this._toggleDropDown();
+},_onDropDownClick:function(e){
+var _10=dojo.isFF&&dojo.isFF<3&&navigator.appVersion.indexOf("Macintosh")!=-1;
+if(!_10||e.detail!=0||this._seenKeydown){
+this._onArrowClick(e);
+}
+this._seenKeydown=false;
+},_onDropDownKeydown:function(e){
+this._seenKeydown=true;
+},_onDropDownBlur:function(e){
+this._seenKeydown=false;
+},_onKey:function(e){
+if(this.disabled||this.readOnly){
+return;
+}
+if(e.charOrCode==dojo.keys.DOWN_ARROW){
+if(!this.dropDown||this.dropDown.domNode.style.visibility=="hidden"){
+dojo.stopEvent(e);
+this._toggleDropDown();
+}
+}
+},_onBlur:function(){
+this._closeDropDown();
+this.inherited(arguments);
+},_toggleDropDown:function(){
+if(this.disabled||this.readOnly){
+return;
+}
+dijit.focus(this.popupStateNode);
+var _14=this.dropDown;
+if(!_14){
+return;
+}
+if(!this._opened){
+if(_14.href&&!_14.isLoaded){
+var _15=this;
+var _16=dojo.connect(_14,"onLoad",function(){
+dojo.disconnect(_16);
+_15._openDropDown();
+});
+_14.refresh();
+return;
+}else{
+this._openDropDown();
+}
+}else{
+this._closeDropDown();
+}
+},_openDropDown:function(){
+var _17=this.dropDown;
+var _18=_17.domNode.style.width;
+var _19=this;
+dijit.popup.open({parent:this,popup:_17,around:this.domNode,orient:this.isLeftToRight()?{"BL":"TL","BR":"TR","TL":"BL","TR":"BR"}:{"BR":"TR","BL":"TL","TR":"BR","TL":"BL"},onExecute:function(){
+_19._closeDropDown(true);
+},onCancel:function(){
+_19._closeDropDown(true);
+},onClose:function(){
+_17.domNode.style.width=_18;
+_19.popupStateNode.removeAttribute("popupActive");
+_19._opened=false;
+}});
+if(this.domNode.offsetWidth>_17.domNode.offsetWidth){
+var _1a=null;
+if(!this.isLeftToRight()){
+_1a=_17.domNode.parentNode;
+var _1b=_1a.offsetLeft+_1a.offsetWidth;
+}
+dojo.marginBox(_17.domNode,{w:this.domNode.offsetWidth});
+if(_1a){
+_1a.style.left=_1b-this.domNode.offsetWidth+"px";
+}
+}
+this.popupStateNode.setAttribute("popupActive","true");
+this._opened=true;
+if(_17.focus){
+_17.focus();
+}
+},_closeDropDown:function(_1c){
+if(this._opened){
+dijit.popup.close(this.dropDown);
+if(_1c){
+this.focus();
+}
+this._opened=false;
+}
+}});
+dojo.declare("dijit.form.ComboButton",dijit.form.DropDownButton,{templateString:"<table class='dijit dijitReset dijitInline dijitLeft'\n\tcellspacing='0' cellpadding='0' waiRole=\"presentation\"\n\t><tbody waiRole=\"presentation\"><tr waiRole=\"presentation\"\n\t\t><td class=\"dijitReset dijitStretch dijitButtonContents dijitButtonNode\"\n\t\t\tdojoAttachEvent=\"ondijitclick:_onButtonClick,onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\"  dojoAttachPoint=\"titleNode\"\n [...]
+this.inherited(arguments);
+this._focalNodes=[this.titleNode,this.popupStateNode];
+dojo.forEach(this._focalNodes,dojo.hitch(this,function(_1d){
+if(dojo.isIE){
+this.connect(_1d,"onactivate",this._onNodeFocus);
+this.connect(_1d,"ondeactivate",this._onNodeBlur);
+}else{
+this.connect(_1d,"onfocus",this._onNodeFocus);
+this.connect(_1d,"onblur",this._onNodeBlur);
+}
+}));
+},focusFocalNode:function(_1e){
+this._focusedNode=_1e;
+dijit.focus(_1e);
+},hasNextFocalNode:function(){
+return this._focusedNode!==this.getFocalNodes()[1];
+},focusNext:function(){
+this._focusedNode=this.getFocalNodes()[this._focusedNode?1:0];
+dijit.focus(this._focusedNode);
+},hasPrevFocalNode:function(){
+return this._focusedNode!==this.getFocalNodes()[0];
+},focusPrev:function(){
+this._focusedNode=this.getFocalNodes()[this._focusedNode?0:1];
+dijit.focus(this._focusedNode);
+},getFocalNodes:function(){
+return this._focalNodes;
+},_onNodeFocus:function(evt){
+this._focusedNode=evt.currentTarget;
+var fnc=this._focusedNode==this.focusNode?"dijitDownArrowButtonFocused":"dijitButtonContentsFocused";
+dojo.addClass(this._focusedNode,fnc);
+},_onNodeBlur:function(evt){
+var fnc=evt.currentTarget==this.focusNode?"dijitDownArrowButtonFocused":"dijitButtonContentsFocused";
+dojo.removeClass(evt.currentTarget,fnc);
+},_onBlur:function(){
+this.inherited(arguments);
+this._focusedNode=null;
+}});
+dojo.declare("dijit.form.ToggleButton",dijit.form.Button,{baseClass:"dijitToggleButton",checked:false,attributeMap:dojo.mixin(dojo.clone(dijit.form.Button.prototype.attributeMap),{checked:"focusNode"}),_clicked:function(evt){
+this.attr("checked",!this.checked);
+},_setCheckedAttr:function(_24){
+this.checked=_24;
+dojo.attr(this.focusNode||this.domNode,"checked",_24);
+dijit.setWaiState(this.focusNode||this.domNode,"pressed",_24);
+this._setStateClass();
+this._handleOnChange(_24,true);
+},setChecked:function(_25){
+dojo.deprecated("setChecked("+_25+") is deprecated. Use attr('checked',"+_25+") instead.","","2.0");
+this.attr("checked",_25);
+},reset:function(){
+this._hasBeenBlurred=false;
+this.attr("checked",this.params.checked||false);
+}});
+}
diff --git a/dijit/form/CheckBox.js b/dijit/form/CheckBox.js
new file mode 100644
index 0000000..7fa44dc
--- /dev/null
+++ b/dijit/form/CheckBox.js
@@ -0,0 +1,65 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.CheckBox"]){
+dojo._hasResource["dijit.form.CheckBox"]=true;
+dojo.provide("dijit.form.CheckBox");
+dojo.require("dijit.form.Button");
+dojo.declare("dijit.form.CheckBox",dijit.form.ToggleButton,{templateString:"<div class=\"dijitReset dijitInline\" waiRole=\"presentation\"\n\t><input\n\t \t${nameAttrSetting} type=\"${type}\" ${checkedAttrSetting}\n\t\tclass=\"dijitReset dijitCheckBoxInput\"\n\t\tdojoAttachPoint=\"focusNode\"\n\t \tdojoAttachEvent=\"onmouseover:_onMouse,onmouseout:_onMouse,onclick:_onClick\"\n/></div>\n",baseClass:"dijitCheckBox",type:"checkbox",value:"on",_setValueAttr:function(_1){
+if(typeof _1=="string"){
+this.value=_1;
+dojo.attr(this.focusNode,"value",_1);
+_1=true;
+}
+if(this._created){
+this.attr("checked",_1);
+}
+},_getValueAttr:function(){
+return (this.checked?this.value:false);
+},postMixInProperties:function(){
+if(this.value==""){
+this.value="on";
+}
+this.checkedAttrSetting=this.checked?"checked":"";
+this.inherited(arguments);
+},_fillContent:function(_2){
+},reset:function(){
+this._hasBeenBlurred=false;
+this.attr("checked",this.params.checked||false);
+this.value=this.params.value||"on";
+dojo.attr(this.focusNode,"value",this.value);
+},_onFocus:function(){
+if(this.id){
+dojo.query("label[for='"+this.id+"']").addClass("dijitFocusedLabel");
+}
+},_onBlur:function(){
+if(this.id){
+dojo.query("label[for='"+this.id+"']").removeClass("dijitFocusedLabel");
+}
+}});
+dojo.declare("dijit.form.RadioButton",dijit.form.CheckBox,{type:"radio",baseClass:"dijitRadio",_setCheckedAttr:function(_3){
+this.inherited(arguments);
+if(!this._created){
+return;
+}
+if(_3){
+var _4=this;
+dojo.query("INPUT[type=radio]",this.focusNode.form||dojo.doc).forEach(function(_5){
+if(_5.name==_4.name&&_5!=_4.focusNode&&_5.form==_4.focusNode.form){
+var _6=dijit.getEnclosingWidget(_5);
+if(_6&&_6.checked){
+_6.attr("checked",false);
+}
+}
+});
+}
+},_clicked:function(e){
+if(!this.checked){
+this.attr("checked",true);
+}
+}});
+}
diff --git a/dijit/form/ComboBox.js b/dijit/form/ComboBox.js
new file mode 100644
index 0000000..10e9396
--- /dev/null
+++ b/dijit/form/ComboBox.js
@@ -0,0 +1,601 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.ComboBox"]){
+dojo._hasResource["dijit.form.ComboBox"]=true;
+dojo.provide("dijit.form.ComboBox");
+dojo.require("dijit.form.ValidationTextBox");
+dojo.require("dojo.data.util.simpleFetch");
+dojo.require("dojo.data.util.filter");
+dojo.require("dojo.regexp");
+dojo.requireLocalization("dijit.form","ComboBox",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.declare("dijit.form.ComboBoxMixin",null,{item:null,pageSize:Infinity,store:null,fetchProperties:{},query:{},autoComplete:true,highlightMatch:"first",searchDelay:100,searchAttr:"name",labelAttr:"",labelType:"text",queryExpr:"${0}*",ignoreCase:true,hasDownArrow:true,templateString:"<div class=\"dijit dijitReset dijitInlineTable dijitLeft\"\n\tid=\"widget_${id}\"\n\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\" dojoAttachPoint=\"comboNode\" waiRol [...]
+var _2=0;
+if(typeof (_1.selectionStart)=="number"){
+_2=_1.selectionStart;
+}else{
+if(dojo.isIE){
+var tr=dojo.doc.selection.createRange().duplicate();
+var _4=_1.createTextRange();
+tr.move("character",0);
+_4.move("character",0);
+try{
+_4.setEndPoint("EndToEnd",tr);
+_2=String(_4.text).replace(/\r/g,"").length;
+}
+catch(e){
+}
+}
+}
+return _2;
+},_setCaretPos:function(_5,_6){
+_6=parseInt(_6);
+dijit.selectInputText(_5,_6,_6);
+},_setDisabledAttr:function(_7){
+this.inherited(arguments);
+dijit.setWaiState(this.comboNode,"disabled",_7);
+},_onKeyPress:function(_8){
+var _9=_8.charOrCode;
+if(_8.altKey||(_8.ctrlKey&&(_9!="x"&&_9!="v"))||_8.key==dojo.keys.SHIFT){
+return;
+}
+var _a=false;
+var pw=this._popupWidget;
+var dk=dojo.keys;
+var _d=null;
+if(this._isShowingNow){
+pw.handleKey(_9);
+_d=pw.getHighlightedOption();
+}
+switch(_9){
+case dk.PAGE_DOWN:
+case dk.DOWN_ARROW:
+if(!this._isShowingNow||this._prev_key_esc){
+this._arrowPressed();
+_a=true;
+}else{
+if(_d){
+this._announceOption(_d);
+}
+}
+dojo.stopEvent(_8);
+this._prev_key_backspace=false;
+this._prev_key_esc=false;
+break;
+case dk.PAGE_UP:
+case dk.UP_ARROW:
+if(this._isShowingNow){
+this._announceOption(_d);
+}
+dojo.stopEvent(_8);
+this._prev_key_backspace=false;
+this._prev_key_esc=false;
+break;
+case dk.ENTER:
+if(_d){
+if(_d==pw.nextButton){
+this._nextSearch(1);
+dojo.stopEvent(_8);
+break;
+}else{
+if(_d==pw.previousButton){
+this._nextSearch(-1);
+dojo.stopEvent(_8);
+break;
+}
+}
+}else{
+this._setDisplayedValueAttr(this.attr("displayedValue"),true);
+}
+_8.preventDefault();
+case dk.TAB:
+var _e=this.attr("displayedValue");
+if(pw&&(_e==pw._messages["previousMessage"]||_e==pw._messages["nextMessage"])){
+break;
+}
+if(this._isShowingNow){
+this._prev_key_backspace=false;
+this._prev_key_esc=false;
+if(_d){
+pw.attr("value",{target:_d});
+}
+this._lastQuery=null;
+this._hideResultList();
+}
+break;
+case " ":
+this._prev_key_backspace=false;
+this._prev_key_esc=false;
+if(_d){
+dojo.stopEvent(_8);
+this._selectOption();
+this._hideResultList();
+}else{
+_a=true;
+}
+break;
+case dk.ESCAPE:
+this._prev_key_backspace=false;
+this._prev_key_esc=true;
+if(this._isShowingNow){
+dojo.stopEvent(_8);
+this._hideResultList();
+}
+break;
+case dk.DELETE:
+case dk.BACKSPACE:
+this._prev_key_esc=false;
+this._prev_key_backspace=true;
+_a=true;
+break;
+case dk.RIGHT_ARROW:
+case dk.LEFT_ARROW:
+this._prev_key_backspace=false;
+this._prev_key_esc=false;
+break;
+default:
+this._prev_key_backspace=false;
+this._prev_key_esc=false;
+_a=typeof _9=="string";
+}
+if(this.searchTimer){
+clearTimeout(this.searchTimer);
+}
+if(_a){
+setTimeout(dojo.hitch(this,"_startSearchFromInput"),1);
+}
+},_autoCompleteText:function(_f){
+var fn=this.focusNode;
+dijit.selectInputText(fn,fn.value.length);
+var _11=this.ignoreCase?"toLowerCase":"substr";
+if(_f[_11](0).indexOf(this.focusNode.value[_11](0))==0){
+var _12=this._getCaretPos(fn);
+if((_12+1)>fn.value.length){
+fn.value=_f;
+dijit.selectInputText(fn,_12);
+}
+}else{
+fn.value=_f;
+dijit.selectInputText(fn);
+}
+},_openResultList:function(_13,_14){
+if(this.disabled||this.readOnly||(_14.query[this.searchAttr]!=this._lastQuery)){
+return;
+}
+this._popupWidget.clearResultList();
+if(!_13.length){
+this._hideResultList();
+return;
+}
+this.item=null;
+var _15=new String(this.store.getValue(_13[0],this.searchAttr));
+if(_15&&this.autoComplete&&!this._prev_key_backspace&&(_14.query[this.searchAttr]!="*")){
+this.item=_13[0];
+this._autoCompleteText(_15);
+}
+_14._maxOptions=this._maxOptions;
+this._popupWidget.createOptions(_13,_14,dojo.hitch(this,"_getMenuLabelFromItem"));
+this._showResultList();
+if(_14.direction){
+if(1==_14.direction){
+this._popupWidget.highlightFirstOption();
+}else{
+if(-1==_14.direction){
+this._popupWidget.highlightLastOption();
+}
+}
+this._announceOption(this._popupWidget.getHighlightedOption());
+}
+},_showResultList:function(){
+this._hideResultList();
+var _16=this._popupWidget.getItems(),_17=Math.min(_16.length,this.maxListLength);
+this._arrowPressed();
+this.displayMessage("");
+dojo.style(this._popupWidget.domNode,{width:"",height:""});
+var _18=this.open();
+var _19=dojo.marginBox(this._popupWidget.domNode);
+this._popupWidget.domNode.style.overflow=((_18.h==_19.h)&&(_18.w==_19.w))?"hidden":"auto";
+var _1a=_18.w;
+if(_18.h<this._popupWidget.domNode.scrollHeight){
+_1a+=16;
+}
+dojo.marginBox(this._popupWidget.domNode,{h:_18.h,w:Math.max(_1a,this.domNode.offsetWidth)});
+dijit.setWaiState(this.comboNode,"expanded","true");
+},_hideResultList:function(){
+if(this._isShowingNow){
+dijit.popup.close(this._popupWidget);
+this._arrowIdle();
+this._isShowingNow=false;
+dijit.setWaiState(this.comboNode,"expanded","false");
+dijit.removeWaiState(this.focusNode,"activedescendant");
+}
+},_setBlurValue:function(){
+var _1b=this.attr("displayedValue");
+var pw=this._popupWidget;
+if(pw&&(_1b==pw._messages["previousMessage"]||_1b==pw._messages["nextMessage"])){
+this._setValueAttr(this._lastValueReported,true);
+}else{
+this.attr("displayedValue",_1b);
+}
+},_onBlur:function(){
+this._hideResultList();
+this._arrowIdle();
+this.inherited(arguments);
+},_announceOption:function(_1d){
+if(_1d==null){
+return;
+}
+var _1e;
+if(_1d==this._popupWidget.nextButton||_1d==this._popupWidget.previousButton){
+_1e=_1d.innerHTML;
+}else{
+_1e=this.store.getValue(_1d.item,this.searchAttr);
+}
+this.focusNode.value=this.focusNode.value.substring(0,this._getCaretPos(this.focusNode));
+dijit.setWaiState(this.focusNode,"activedescendant",dojo.attr(_1d,"id"));
+this._autoCompleteText(_1e);
+},_selectOption:function(evt){
+var tgt=null;
+if(!evt){
+evt={target:this._popupWidget.getHighlightedOption()};
+}
+if(!evt.target){
+this.attr("displayedValue",this.attr("displayedValue"));
+return;
+}else{
+tgt=evt.target;
+}
+if(!evt.noHide){
+this._hideResultList();
+this._setCaretPos(this.focusNode,this.store.getValue(tgt.item,this.searchAttr).length);
+}
+this._doSelect(tgt);
+},_doSelect:function(tgt){
+this.item=tgt.item;
+this.attr("value",this.store.getValue(tgt.item,this.searchAttr));
+},_onArrowMouseDown:function(evt){
+if(this.disabled||this.readOnly){
+return;
+}
+dojo.stopEvent(evt);
+this.focus();
+if(this._isShowingNow){
+this._hideResultList();
+}else{
+this._startSearch("");
+}
+},_startSearchFromInput:function(){
+this._startSearch(this.focusNode.value.replace(/([\\\*\?])/g,"\\$1"));
+},_getQueryString:function(_23){
+return dojo.string.substitute(this.queryExpr,[_23]);
+},_startSearch:function(key){
+if(!this._popupWidget){
+var _25=this.id+"_popup";
+this._popupWidget=new dijit.form._ComboBoxMenu({onChange:dojo.hitch(this,this._selectOption),id:_25});
+dijit.removeWaiState(this.focusNode,"activedescendant");
+dijit.setWaiState(this.textbox,"owns",_25);
+}
+this.item=null;
+var _26=dojo.clone(this.query);
+this._lastInput=key;
+this._lastQuery=_26[this.searchAttr]=this._getQueryString(key);
+this.searchTimer=setTimeout(dojo.hitch(this,function(_27,_28){
+var _29={queryOptions:{ignoreCase:this.ignoreCase,deep:true},query:_27,onBegin:dojo.hitch(this,"_setMaxOptions"),onComplete:dojo.hitch(this,"_openResultList"),onError:function(_2a){
+console.error("dijit.form.ComboBox: "+_2a);
+dojo.hitch(_28,"_hideResultList")();
+},start:0,count:this.pageSize};
+dojo.mixin(_29,_28.fetchProperties);
+var _2b=_28.store.fetch(_29);
+var _2c=function(_2d,_2e){
+_2d.start+=_2d.count*_2e;
+_2d.direction=_2e;
+this.store.fetch(_2d);
+};
+this._nextSearch=this._popupWidget.onPage=dojo.hitch(this,_2c,_2b);
+},_26,this),this.searchDelay);
+},_setMaxOptions:function(_2f,_30){
+this._maxOptions=_2f;
+},_getValueField:function(){
+return this.searchAttr;
+},_arrowPressed:function(){
+if(!this.disabled&&!this.readOnly&&this.hasDownArrow){
+dojo.addClass(this.downArrowNode,"dijitArrowButtonActive");
+}
+},_arrowIdle:function(){
+if(!this.disabled&&!this.readOnly&&this.hasDownArrow){
+dojo.removeClass(this.downArrowNode,"dojoArrowButtonPushed");
+}
+},compositionend:function(evt){
+this._onKeyPress({charCode:-1});
+},constructor:function(){
+this.query={};
+this.fetchProperties={};
+},postMixInProperties:function(){
+if(!this.hasDownArrow){
+this.baseClass="dijitTextBox";
+}
+if(!this.store){
+var _32=this.srcNodeRef;
+this.store=new dijit.form._ComboBoxDataStore(_32);
+if(!this.value||((typeof _32.selectedIndex=="number")&&_32.selectedIndex.toString()===this.value)){
+var _33=this.store.fetchSelectedItem();
+if(_33){
+this.value=this.store.getValue(_33,this._getValueField());
+}
+}
+}
+this.inherited(arguments);
+},postCreate:function(){
+var _34=dojo.query("label[for=\""+this.id+"\"]");
+if(_34.length){
+_34[0].id=(this.id+"_label");
+var cn=this.comboNode;
+dijit.setWaiState(cn,"labelledby",_34[0].id);
+}
+this.inherited(arguments);
+},uninitialize:function(){
+if(this._popupWidget){
+this._hideResultList();
+this._popupWidget.destroy();
+}
+},_getMenuLabelFromItem:function(_36){
+var _37=this.store.getValue(_36,this.labelAttr||this.searchAttr);
+var _38=this.labelType;
+if(this.highlightMatch!="none"&&this.labelType=="text"&&this._lastInput){
+_37=this.doHighlight(_37,this._escapeHtml(this._lastInput));
+_38="html";
+}
+return {html:_38=="html",label:_37};
+},doHighlight:function(_39,_3a){
+var _3b="i"+(this.highlightMatch=="all"?"g":"");
+var _3c=this._escapeHtml(_39);
+_3a=dojo.regexp.escapeString(_3a);
+var ret=_3c.replace(new RegExp("(^|\\s)("+_3a+")",_3b),"$1<span class=\"dijitComboBoxHighlightMatch\">$2</span>");
+return ret;
+},_escapeHtml:function(str){
+str=String(str).replace(/&/gm,"&").replace(/</gm,"<").replace(/>/gm,">").replace(/"/gm,""");
+return str;
+},open:function(){
+this._isShowingNow=true;
+return dijit.popup.open({popup:this._popupWidget,around:this.domNode,parent:this});
+},reset:function(){
+this.item=null;
+this.inherited(arguments);
+}});
+dojo.declare("dijit.form._ComboBoxMenu",[dijit._Widget,dijit._Templated],{templateString:"<ul class='dijitReset dijitMenu' dojoAttachEvent='onmousedown:_onMouseDown,onmouseup:_onMouseUp,onmouseover:_onMouseOver,onmouseout:_onMouseOut' tabIndex='-1' style='overflow: \"auto\"; overflow-x: \"hidden\";'>"+"<li class='dijitMenuItem dijitMenuPreviousButton' dojoAttachPoint='previousButton' waiRole='option'></li>"+"<li class='dijitMenuItem dijitMenuNextButton' dojoAttachPoint='nextButton' waiRo [...]
+this._messages=dojo.i18n.getLocalization("dijit.form","ComboBox",this.lang);
+this.inherited(arguments);
+},_setValueAttr:function(_3f){
+this.value=_3f;
+this.onChange(_3f);
+},onChange:function(_40){
+},onPage:function(_41){
+},postCreate:function(){
+this.previousButton.innerHTML=this._messages["previousMessage"];
+this.nextButton.innerHTML=this._messages["nextMessage"];
+this.inherited(arguments);
+},onClose:function(){
+this._blurOptionNode();
+},_createOption:function(_42,_43){
+var _44=_43(_42);
+var _45=dojo.doc.createElement("li");
+dijit.setWaiRole(_45,"option");
+if(_44.html){
+_45.innerHTML=_44.label;
+}else{
+_45.appendChild(dojo.doc.createTextNode(_44.label));
+}
+if(_45.innerHTML==""){
+_45.innerHTML=" ";
+}
+_45.item=_42;
+return _45;
+},createOptions:function(_46,_47,_48){
+this.previousButton.style.display=(_47.start==0)?"none":"";
+dojo.attr(this.previousButton,"id",this.id+"_prev");
+dojo.forEach(_46,function(_49,i){
+var _4b=this._createOption(_49,_48);
+_4b.className="dijitReset dijitMenuItem";
+dojo.attr(_4b,"id",this.id+i);
+this.domNode.insertBefore(_4b,this.nextButton);
+},this);
+var _4c=false;
+if(_47._maxOptions&&_47._maxOptions!=-1){
+if((_47.start+_47.count)<_47._maxOptions){
+_4c=true;
+}else{
+if((_47.start+_47.count)>(_47._maxOptions-1)){
+if(_47.count==_46.length){
+_4c=true;
+}
+}
+}
+}else{
+if(_47.count==_46.length){
+_4c=true;
+}
+}
+this.nextButton.style.display=_4c?"":"none";
+dojo.attr(this.nextButton,"id",this.id+"_next");
+},clearResultList:function(){
+while(this.domNode.childNodes.length>2){
+this.domNode.removeChild(this.domNode.childNodes[this.domNode.childNodes.length-2]);
+}
+},getItems:function(){
+return this.domNode.childNodes;
+},getListLength:function(){
+return this.domNode.childNodes.length-2;
+},_onMouseDown:function(evt){
+dojo.stopEvent(evt);
+},_onMouseUp:function(evt){
+if(evt.target===this.domNode){
+return;
+}else{
+if(evt.target==this.previousButton){
+this.onPage(-1);
+}else{
+if(evt.target==this.nextButton){
+this.onPage(1);
+}else{
+var tgt=evt.target;
+while(!tgt.item){
+tgt=tgt.parentNode;
+}
+this._setValueAttr({target:tgt},true);
+}
+}
+}
+},_onMouseOver:function(evt){
+if(evt.target===this.domNode){
+return;
+}
+var tgt=evt.target;
+if(!(tgt==this.previousButton||tgt==this.nextButton)){
+while(!tgt.item){
+tgt=tgt.parentNode;
+}
+}
+this._focusOptionNode(tgt);
+},_onMouseOut:function(evt){
+if(evt.target===this.domNode){
+return;
+}
+this._blurOptionNode();
+},_focusOptionNode:function(_53){
+if(this._highlighted_option!=_53){
+this._blurOptionNode();
+this._highlighted_option=_53;
+dojo.addClass(this._highlighted_option,"dijitMenuItemSelected");
+}
+},_blurOptionNode:function(){
+if(this._highlighted_option){
+dojo.removeClass(this._highlighted_option,"dijitMenuItemSelected");
+this._highlighted_option=null;
+}
+},_highlightNextOption:function(){
+var fc=this.domNode.firstChild;
+if(!this.getHighlightedOption()){
+this._focusOptionNode(fc.style.display=="none"?fc.nextSibling:fc);
+}else{
+var ns=this._highlighted_option.nextSibling;
+if(ns&&ns.style.display!="none"){
+this._focusOptionNode(ns);
+}
+}
+dijit.scrollIntoView(this._highlighted_option);
+},highlightFirstOption:function(){
+this._focusOptionNode(this.domNode.firstChild.nextSibling);
+dijit.scrollIntoView(this._highlighted_option);
+},highlightLastOption:function(){
+this._focusOptionNode(this.domNode.lastChild.previousSibling);
+dijit.scrollIntoView(this._highlighted_option);
+},_highlightPrevOption:function(){
+var lc=this.domNode.lastChild;
+if(!this.getHighlightedOption()){
+this._focusOptionNode(lc.style.display=="none"?lc.previousSibling:lc);
+}else{
+var ps=this._highlighted_option.previousSibling;
+if(ps&&ps.style.display!="none"){
+this._focusOptionNode(ps);
+}
+}
+dijit.scrollIntoView(this._highlighted_option);
+},_page:function(up){
+var _59=0;
+var _5a=this.domNode.scrollTop;
+var _5b=dojo.style(this.domNode,"height");
+if(!this.getHighlightedOption()){
+this._highlightNextOption();
+}
+while(_59<_5b){
+if(up){
+if(!this.getHighlightedOption().previousSibling||this._highlighted_option.previousSibling.style.display=="none"){
+break;
+}
+this._highlightPrevOption();
+}else{
+if(!this.getHighlightedOption().nextSibling||this._highlighted_option.nextSibling.style.display=="none"){
+break;
+}
+this._highlightNextOption();
+}
+var _5c=this.domNode.scrollTop;
+_59+=(_5c-_5a)*(up?-1:1);
+_5a=_5c;
+}
+},pageUp:function(){
+this._page(true);
+},pageDown:function(){
+this._page(false);
+},getHighlightedOption:function(){
+var ho=this._highlighted_option;
+return (ho&&ho.parentNode)?ho:null;
+},handleKey:function(key){
+switch(key){
+case dojo.keys.DOWN_ARROW:
+this._highlightNextOption();
+break;
+case dojo.keys.PAGE_DOWN:
+this.pageDown();
+break;
+case dojo.keys.UP_ARROW:
+this._highlightPrevOption();
+break;
+case dojo.keys.PAGE_UP:
+this.pageUp();
+break;
+}
+}});
+dojo.declare("dijit.form.ComboBox",[dijit.form.ValidationTextBox,dijit.form.ComboBoxMixin],{_setValueAttr:function(_5f,_60){
+if(!_5f){
+_5f="";
+}
+dijit.form.ValidationTextBox.prototype._setValueAttr.call(this,_5f,_60);
+}});
+dojo.declare("dijit.form._ComboBoxDataStore",null,{constructor:function(_61){
+this.root=_61;
+dojo.query("> option",_61).forEach(function(_62){
+_62.innerHTML=dojo.trim(_62.innerHTML);
+});
+},getValue:function(_63,_64,_65){
+return (_64=="value")?_63.value:(_63.innerText||_63.textContent||"");
+},isItemLoaded:function(_66){
+return true;
+},getFeatures:function(){
+return {"dojo.data.api.Read":true,"dojo.data.api.Identity":true};
+},_fetchItems:function(_67,_68,_69){
+if(!_67.query){
+_67.query={};
+}
+if(!_67.query.name){
+_67.query.name="";
+}
+if(!_67.queryOptions){
+_67.queryOptions={};
+}
+var _6a=dojo.data.util.filter.patternToRegExp(_67.query.name,_67.queryOptions.ignoreCase),_6b=dojo.query("> option",this.root).filter(function(_6c){
+return (_6c.innerText||_6c.textContent||"").match(_6a);
+});
+if(_67.sort){
+_6b.sort(dojo.data.util.sorter.createSortFunction(_67.sort,this));
+}
+_68(_6b,_67);
+},close:function(_6d){
+return;
+},getLabel:function(_6e){
+return _6e.innerHTML;
+},getIdentity:function(_6f){
+return dojo.attr(_6f,"value");
+},fetchItemByIdentity:function(_70){
+var _71=dojo.query("option[value='"+_70.identity+"']",this.root)[0];
+_70.onItem(_71);
+},fetchSelectedItem:function(){
+var _72=this.root,si=_72.selectedIndex;
+return dojo.query("> option:nth-child("+(si!=-1?si+1:1)+")",_72)[0];
+}});
+dojo.extend(dijit.form._ComboBoxDataStore,dojo.data.util.simpleFetch);
+}
diff --git a/dijit/form/ComboButton.js b/dijit/form/ComboButton.js
new file mode 100644
index 0000000..c073e90
--- /dev/null
+++ b/dijit/form/ComboButton.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.ComboButton"]){
+dojo._hasResource["dijit.form.ComboButton"]=true;
+dojo.provide("dijit.form.ComboButton");
+dojo.require("dijit.form.Button");
+}
diff --git a/dijit/form/CurrencyTextBox.js b/dijit/form/CurrencyTextBox.js
new file mode 100644
index 0000000..0f9b140
--- /dev/null
+++ b/dijit/form/CurrencyTextBox.js
@@ -0,0 +1,17 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.CurrencyTextBox"]){
+dojo._hasResource["dijit.form.CurrencyTextBox"]=true;
+dojo.provide("dijit.form.CurrencyTextBox");
+dojo.require("dojo.currency");
+dojo.require("dijit.form.NumberTextBox");
+dojo.declare("dijit.form.CurrencyTextBox",dijit.form.NumberTextBox,{currency:"",regExpGen:dojo.currency.regexp,_formatter:dojo.currency.format,parse:dojo.currency.parse,postMixInProperties:function(){
+this.constraints.currency=this.currency;
+this.inherited(arguments);
+}});
+}
diff --git a/dijit/form/DateTextBox.js b/dijit/form/DateTextBox.js
new file mode 100644
index 0000000..5595f38
--- /dev/null
+++ b/dijit/form/DateTextBox.js
@@ -0,0 +1,14 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.DateTextBox"]){
+dojo._hasResource["dijit.form.DateTextBox"]=true;
+dojo.provide("dijit.form.DateTextBox");
+dojo.require("dijit._Calendar");
+dojo.require("dijit.form._DateTimeTextBox");
+dojo.declare("dijit.form.DateTextBox",dijit.form._DateTimeTextBox,{baseClass:"dijitTextBox dijitDateTextBox",popupClass:"dijit._Calendar",_selector:"date",value:new Date("")});
+}
diff --git a/dijit/form/DropDownButton.js b/dijit/form/DropDownButton.js
new file mode 100644
index 0000000..187c6b4
--- /dev/null
+++ b/dijit/form/DropDownButton.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.DropDownButton"]){
+dojo._hasResource["dijit.form.DropDownButton"]=true;
+dojo.provide("dijit.form.DropDownButton");
+dojo.require("dijit.form.Button");
+}
diff --git a/dijit/form/FilteringSelect.js b/dijit/form/FilteringSelect.js
new file mode 100644
index 0000000..b8a1e69
--- /dev/null
+++ b/dijit/form/FilteringSelect.js
@@ -0,0 +1,102 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.FilteringSelect"]){
+dojo._hasResource["dijit.form.FilteringSelect"]=true;
+dojo.provide("dijit.form.FilteringSelect");
+dojo.require("dijit.form.ComboBox");
+dojo.declare("dijit.form.FilteringSelect",[dijit.form.MappedTextBox,dijit.form.ComboBoxMixin],{_isvalid:true,required:true,_lastDisplayedValue:"",isValid:function(){
+return this._isvalid||(!this.required&&this.attr("displayedValue")=="");
+},_callbackSetLabel:function(_1,_2,_3){
+if((_2&&_2.query[this.searchAttr]!=this._lastQuery)||(!_2&&_1.length&&this.store.getIdentity(_1[0])!=this._lastQuery)){
+return;
+}
+if(!_1.length){
+this.valueNode.value="";
+dijit.form.TextBox.superclass._setValueAttr.call(this,"",_3||(_3===undefined&&!this._focused));
+this._isvalid=false;
+this.validate(this._focused);
+this.item=null;
+}else{
+this._setValueFromItem(_1[0],_3);
+}
+},_openResultList:function(_4,_5){
+if(_5.query[this.searchAttr]!=this._lastQuery){
+return;
+}
+this._isvalid=_4.length!=0;
+this.validate(true);
+dijit.form.ComboBoxMixin.prototype._openResultList.apply(this,arguments);
+},_getValueAttr:function(){
+return this.valueNode.value;
+},_getValueField:function(){
+return "value";
+},_setValue:function(_6,_7,_8){
+this.valueNode.value=_6;
+dijit.form.FilteringSelect.superclass._setValueAttr.call(this,_6,_8,_7);
+this._lastDisplayedValue=_7;
+},_setValueAttr:function(_9,_a){
+if(!this._onChangeActive){
+_a=null;
+}
+this._lastQuery=_9;
+if(_9===null||_9===""){
+this._setDisplayedValueAttr("",_a);
+return;
+}
+var _b=this;
+var _c=function(_d,_e){
+if(_d){
+if(_b.store.isItemLoaded(_d)){
+_b._callbackSetLabel([_d],undefined,_e);
+}else{
+_b.store.loadItem({item:_d,onItem:function(_f,_10){
+_b._callbackSetLabel(_f,_10,_e);
+}});
+}
+}else{
+_b._isvalid=false;
+_b.validate(false);
+}
+};
+this.store.fetchItemByIdentity({identity:_9,onItem:function(_11){
+_c(_11,_a);
+}});
+},_setValueFromItem:function(_12,_13){
+this._isvalid=true;
+this.item=_12;
+this._setValue(this.store.getIdentity(_12),this.labelFunc(_12,this.store),_13);
+},labelFunc:function(_14,_15){
+return _15.getValue(_14,this.searchAttr);
+},_doSelect:function(tgt){
+this._setValueFromItem(tgt.item,true);
+},_setDisplayedValueAttr:function(_17,_18){
+if(!this._created){
+_18=false;
+}
+if(this.store){
+var _19=dojo.clone(this.query);
+this._lastQuery=_19[this.searchAttr]=_17.replace(/([\\\*\?])/g,"\\$1");
+this.textbox.value=_17;
+this._lastDisplayedValue=_17;
+var _1a=this;
+var _1b={query:_19,queryOptions:{ignoreCase:this.ignoreCase,deep:true},onComplete:function(_1c,_1d){
+dojo.hitch(_1a,"_callbackSetLabel")(_1c,_1d,_18);
+},onError:function(_1e){
+console.error("dijit.form.FilteringSelect: "+_1e);
+dojo.hitch(_1a,"_setValue")("",_17,false);
+}};
+dojo.mixin(_1b,this.fetchProperties);
+this.store.fetch(_1b);
+}
+},postMixInProperties:function(){
+this.inherited(arguments);
+this._isvalid=!this.required;
+},undo:function(){
+this.attr("displayedValue",this._lastDisplayedValue);
+}});
+}
diff --git a/dijit/form/Form.js b/dijit/form/Form.js
new file mode 100644
index 0000000..6e44ac1
--- /dev/null
+++ b/dijit/form/Form.js
@@ -0,0 +1,62 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.Form"]){
+dojo._hasResource["dijit.form.Form"]=true;
+dojo.provide("dijit.form.Form");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dijit.form._FormMixin");
+dojo.declare("dijit.form.Form",[dijit._Widget,dijit._Templated,dijit.form._FormMixin],{name:"",action:"",method:"",encType:"","accept-charset":"",accept:"",target:"",templateString:"<form dojoAttachPoint='containerNode' dojoAttachEvent='onreset:_onReset,onsubmit:_onSubmit' ${nameAttrSetting}></form>",attributeMap:dojo.delegate(dijit._Widget.prototype.attributeMap,{action:"",method:"",encType:"","accept-charset":"",accept:"",target:""}),postMixInProperties:function(){
+this.nameAttrSetting=this.name?("name='"+this.name+"'"):"";
+this.inherited(arguments);
+},execute:function(_1){
+},onExecute:function(){
+},_setEncTypeAttr:function(_2){
+this.encType=_2;
+dojo.attr(this.domNode,"encType",_2);
+if(dojo.isIE){
+this.domNode.encoding=_2;
+}
+},postCreate:function(){
+if(dojo.isIE&&this.srcNodeRef&&this.srcNodeRef.attributes){
+var _3=this.srcNodeRef.attributes.getNamedItem("encType");
+if(_3&&!_3.specified&&(typeof _3.value=="string")){
+this.attr("encType",_3.value);
+}
+}
+this.inherited(arguments);
+},onReset:function(e){
+return true;
+},_onReset:function(e){
+var _6={returnValue:true,preventDefault:function(){
+this.returnValue=false;
+},stopPropagation:function(){
+},currentTarget:e.currentTarget,target:e.target};
+if(!(this.onReset(_6)===false)&&_6.returnValue){
+this.reset();
+}
+dojo.stopEvent(e);
+return false;
+},_onSubmit:function(e){
+var fp=dijit.form.Form.prototype;
+if(this.execute!=fp.execute||this.onExecute!=fp.onExecute){
+dojo.deprecated("dijit.form.Form:execute()/onExecute() are deprecated. Use onSubmit() instead.","","2.0");
+this.onExecute();
+this.execute(this.getValues());
+}
+if(this.onSubmit(e)===false){
+dojo.stopEvent(e);
+}
+},onSubmit:function(e){
+return this.isValid();
+},submit:function(){
+if(!(this.onSubmit()===false)){
+this.containerNode.submit();
+}
+}});
+}
diff --git a/dijit/form/HorizontalRule.js b/dijit/form/HorizontalRule.js
new file mode 100644
index 0000000..bf3ef27
--- /dev/null
+++ b/dijit/form/HorizontalRule.js
@@ -0,0 +1,38 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.HorizontalRule"]){
+dojo._hasResource["dijit.form.HorizontalRule"]=true;
+dojo.provide("dijit.form.HorizontalRule");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.declare("dijit.form.HorizontalRule",[dijit._Widget,dijit._Templated],{templateString:"<div class=\"dijitRuleContainer dijitRuleContainerH\"></div>",count:3,container:"containerNode",ruleStyle:"",_positionPrefix:"<div class=\"dijitRuleMark dijitRuleMarkH\" style=\"left:",_positionSuffix:"%;",_suffix:"\"></div>",_genHTML:function(_1,_2){
+return this._positionPrefix+_1+this._positionSuffix+this.ruleStyle+this._suffix;
+},_isHorizontal:true,postCreate:function(){
+var _3;
+if(this.count==1){
+_3=this._genHTML(50,0);
+}else{
+var i;
+var _5=100/(this.count-1);
+if(!this._isHorizontal||this.isLeftToRight()){
+_3=this._genHTML(0,0);
+for(i=1;i<this.count-1;i++){
+_3+=this._genHTML(_5*i,i);
+}
+_3+=this._genHTML(100,this.count-1);
+}else{
+_3=this._genHTML(100,0);
+for(i=1;i<this.count-1;i++){
+_3+=this._genHTML(100-_5*i,i);
+}
+_3+=this._genHTML(0,this.count-1);
+}
+}
+this.domNode.innerHTML=_3;
+}});
+}
diff --git a/dijit/form/HorizontalRuleLabels.js b/dijit/form/HorizontalRuleLabels.js
new file mode 100644
index 0000000..05c2bd7
--- /dev/null
+++ b/dijit/form/HorizontalRuleLabels.js
@@ -0,0 +1,38 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.HorizontalRuleLabels"]){
+dojo._hasResource["dijit.form.HorizontalRuleLabels"]=true;
+dojo.provide("dijit.form.HorizontalRuleLabels");
+dojo.require("dijit.form.HorizontalRule");
+dojo.declare("dijit.form.HorizontalRuleLabels",dijit.form.HorizontalRule,{templateString:"<div class=\"dijitRuleContainer dijitRuleContainerH dijitRuleLabelsContainer dijitRuleLabelsContainerH\"></div>",labelStyle:"",labels:[],numericMargin:0,minimum:0,maximum:1,constraints:{pattern:"#%"},_positionPrefix:"<div class=\"dijitRuleLabelContainer dijitRuleLabelContainerH\" style=\"left:",_labelPrefix:"\"><span class=\"dijitRuleLabel dijitRuleLabelH\">",_suffix:"</span></div>",_calcPosition:fu [...]
+return _1;
+},_genHTML:function(_2,_3){
+return this._positionPrefix+this._calcPosition(_2)+this._positionSuffix+this.labelStyle+this._labelPrefix+this.labels[_3]+this._suffix;
+},getLabels:function(){
+var _4=this.labels;
+if(!_4.length){
+_4=dojo.query("> li",this.srcNodeRef).map(function(_5){
+return String(_5.innerHTML);
+});
+}
+this.srcNodeRef.innerHTML="";
+if(!_4.length&&this.count>1){
+var _6=this.minimum;
+var _7=(this.maximum-_6)/(this.count-1);
+for(var i=0;i<this.count;i++){
+_4.push((i<this.numericMargin||i>=(this.count-this.numericMargin))?"":dojo.number.format(_6,this.constraints));
+_6+=_7;
+}
+}
+return _4;
+},postMixInProperties:function(){
+this.inherited(arguments);
+this.labels=this.getLabels();
+this.count=this.labels.length;
+}});
+}
diff --git a/dijit/form/HorizontalSlider.js b/dijit/form/HorizontalSlider.js
new file mode 100644
index 0000000..ef9bbb1
--- /dev/null
+++ b/dijit/form/HorizontalSlider.js
@@ -0,0 +1,202 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.HorizontalSlider"]){
+dojo._hasResource["dijit.form.HorizontalSlider"]=true;
+dojo.provide("dijit.form.HorizontalSlider");
+dojo.require("dijit.form._FormWidget");
+dojo.require("dijit._Container");
+dojo.require("dojo.dnd.move");
+dojo.require("dijit.form.Button");
+dojo.require("dojo.number");
+dojo.require("dojo._base.fx");
+dojo.declare("dijit.form.HorizontalSlider",[dijit.form._FormValueWidget,dijit._Container],{templateString:"<table class=\"dijit dijitReset dijitSlider\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" rules=\"none\" dojoAttachEvent=\"onkeypress:_onKeyPress\"\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset\" colspan=\"2\"></td\n\t\t><td dojoAttachPoint=\"containerNode,topDecoration\" class=\"dijitReset\" style=\"text-align:center;width:100%;\"></td\n\t\t><td class=\"dijitReset\ [...]
+if(this.disabled||this.readOnly||e.altKey||e.ctrlKey){
+return;
+}
+switch(e.charOrCode){
+case dojo.keys.HOME:
+this._setValueAttr(this.minimum,true);
+break;
+case dojo.keys.END:
+this._setValueAttr(this.maximum,true);
+break;
+case ((this._descending||this.isLeftToRight())?dojo.keys.RIGHT_ARROW:dojo.keys.LEFT_ARROW):
+case (this._descending===false?dojo.keys.DOWN_ARROW:dojo.keys.UP_ARROW):
+case (this._descending===false?dojo.keys.PAGE_DOWN:dojo.keys.PAGE_UP):
+this.increment(e);
+break;
+case ((this._descending||this.isLeftToRight())?dojo.keys.LEFT_ARROW:dojo.keys.RIGHT_ARROW):
+case (this._descending===false?dojo.keys.UP_ARROW:dojo.keys.DOWN_ARROW):
+case (this._descending===false?dojo.keys.PAGE_UP:dojo.keys.PAGE_DOWN):
+this.decrement(e);
+break;
+default:
+return;
+}
+dojo.stopEvent(e);
+},_onHandleClick:function(e){
+if(this.disabled||this.readOnly){
+return;
+}
+if(!dojo.isIE){
+dijit.focus(this.sliderHandle);
+}
+dojo.stopEvent(e);
+},_isReversed:function(){
+return !this.isLeftToRight();
+},_onBarClick:function(e){
+if(this.disabled||this.readOnly||!this.clickSelect){
+return;
+}
+dijit.focus(this.sliderHandle);
+dojo.stopEvent(e);
+var _4=dojo.coords(this.sliderBarContainer,true);
+var _5=e[this._mousePixelCoord]-_4[this._startingPixelCoord];
+this._setPixelValue(this._isReversed()?(_4[this._pixelCount]-_5):_5,_4[this._pixelCount],true);
+this._movable.onMouseDown(e);
+},_setPixelValue:function(_6,_7,_8){
+if(this.disabled||this.readOnly){
+return;
+}
+_6=_6<0?0:_7<_6?_7:_6;
+var _9=this.discreteValues;
+if(_9<=1||_9==Infinity){
+_9=_7;
+}
+_9--;
+var _a=_7/_9;
+var _b=Math.round(_6/_a);
+this._setValueAttr((this.maximum-this.minimum)*_b/_9+this.minimum,_8);
+},_setValueAttr:function(_c,_d){
+this.valueNode.value=this.value=_c;
+dijit.setWaiState(this.focusNode,"valuenow",_c);
+this.inherited(arguments);
+var _e=(_c-this.minimum)/(this.maximum-this.minimum);
+var _f=(this._descending===false)?this.remainingBar:this.progressBar;
+var _10=(this._descending===false)?this.progressBar:this.remainingBar;
+if(this._inProgressAnim&&this._inProgressAnim.status!="stopped"){
+this._inProgressAnim.stop(true);
+}
+if(_d&&this.slideDuration>0&&_f.style[this._progressPixelSize]){
+var _11=this;
+var _12={};
+var _13=parseFloat(_f.style[this._progressPixelSize]);
+var _14=this.slideDuration*(_e-_13/100);
+if(_14==0){
+return;
+}
+if(_14<0){
+_14=0-_14;
+}
+_12[this._progressPixelSize]={start:_13,end:_e*100,units:"%"};
+this._inProgressAnim=dojo.animateProperty({node:_f,duration:_14,onAnimate:function(v){
+_10.style[_11._progressPixelSize]=(100-parseFloat(v[_11._progressPixelSize]))+"%";
+},onEnd:function(){
+delete _11._inProgressAnim;
+},properties:_12});
+this._inProgressAnim.play();
+}else{
+_f.style[this._progressPixelSize]=(_e*100)+"%";
+_10.style[this._progressPixelSize]=((1-_e)*100)+"%";
+}
+},_bumpValue:function(_16){
+if(this.disabled||this.readOnly){
+return;
+}
+var s=dojo.getComputedStyle(this.sliderBarContainer);
+var c=dojo._getContentBox(this.sliderBarContainer,s);
+var _19=this.discreteValues;
+if(_19<=1||_19==Infinity){
+_19=c[this._pixelCount];
+}
+_19--;
+var _1a=(this.value-this.minimum)*_19/(this.maximum-this.minimum)+_16;
+if(_1a<0){
+_1a=0;
+}
+if(_1a>_19){
+_1a=_19;
+}
+_1a=_1a*(this.maximum-this.minimum)/_19+this.minimum;
+this._setValueAttr(_1a,true);
+},_onClkBumper:function(val){
+if(this.disabled||this.readOnly||!this.clickSelect){
+return;
+}
+this._setValueAttr(val,true);
+},_onClkIncBumper:function(){
+this._onClkBumper(this._descending===false?this.minimum:this.maximum);
+},_onClkDecBumper:function(){
+this._onClkBumper(this._descending===false?this.maximum:this.minimum);
+},decrement:function(e){
+this._bumpValue(e.charOrCode==dojo.keys.PAGE_DOWN?-this.pageIncrement:-1);
+},increment:function(e){
+this._bumpValue(e.charOrCode==dojo.keys.PAGE_UP?this.pageIncrement:1);
+},_mouseWheeled:function(evt){
+dojo.stopEvent(evt);
+var _1f=!dojo.isMozilla;
+var _20=evt[(_1f?"wheelDelta":"detail")]*(_1f?1:-1);
+this[(_20<0?"decrement":"increment")](evt);
+},startup:function(){
+dojo.forEach(this.getChildren(),function(_21){
+if(this[_21.container]!=this.containerNode){
+this[_21.container].appendChild(_21.domNode);
+}
+},this);
+},_typematicCallback:function(_22,_23,e){
+if(_22==-1){
+return;
+}
+this[(_23==(this._descending?this.incrementButton:this.decrementButton))?"decrement":"increment"](e);
+},postCreate:function(){
+if(this.showButtons){
+this.incrementButton.style.display="";
+this.decrementButton.style.display="";
+this._connects.push(dijit.typematic.addMouseListener(this.decrementButton,this,"_typematicCallback",25,500));
+this._connects.push(dijit.typematic.addMouseListener(this.incrementButton,this,"_typematicCallback",25,500));
+}
+this.connect(this.domNode,!dojo.isMozilla?"onmousewheel":"DOMMouseScroll","_mouseWheeled");
+var _25=this;
+var _26=function(){
+dijit.form._SliderMover.apply(this,arguments);
+this.widget=_25;
+};
+dojo.extend(_26,dijit.form._SliderMover.prototype);
+this._movable=new dojo.dnd.Moveable(this.sliderHandle,{mover:_26});
+var _27=dojo.query("label[for=\""+this.id+"\"]");
+if(_27.length){
+_27[0].id=(this.id+"_label");
+dijit.setWaiState(this.focusNode,"labelledby",_27[0].id);
+}
+dijit.setWaiState(this.focusNode,"valuemin",this.minimum);
+dijit.setWaiState(this.focusNode,"valuemax",this.maximum);
+this.inherited(arguments);
+},destroy:function(){
+this._movable.destroy();
+if(this._inProgressAnim&&this._inProgressAnim.status!="stopped"){
+this._inProgressAnim.stop(true);
+}
+this.inherited(arguments);
+}});
+dojo.declare("dijit.form._SliderMover",dojo.dnd.Mover,{onMouseMove:function(e){
+var _29=this.widget;
+var _2a=_29._abspos;
+if(!_2a){
+_2a=_29._abspos=dojo.coords(_29.sliderBarContainer,true);
+_29._setPixelValue_=dojo.hitch(_29,"_setPixelValue");
+_29._isReversed_=_29._isReversed();
+}
+var _2b=e[_29._mousePixelCoord]-_2a[_29._startingPixelCoord];
+_29._setPixelValue_(_29._isReversed_?(_2a[_29._pixelCount]-_2b):_2b,_2a[_29._pixelCount],false);
+},destroy:function(e){
+dojo.dnd.Mover.prototype.destroy.apply(this,arguments);
+var _2d=this.widget;
+_2d._abspos=null;
+_2d._setValueAttr(_2d.value,true);
+}});
+}
diff --git a/dijit/form/MappedTextBox.js b/dijit/form/MappedTextBox.js
new file mode 100644
index 0000000..3035ba4
--- /dev/null
+++ b/dijit/form/MappedTextBox.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.MappedTextBox"]){
+dojo._hasResource["dijit.form.MappedTextBox"]=true;
+dojo.provide("dijit.form.MappedTextBox");
+dojo.require("dijit.form.ValidationTextBox");
+}
diff --git a/dijit/form/MultiSelect.js b/dijit/form/MultiSelect.js
new file mode 100644
index 0000000..97ad7ba
--- /dev/null
+++ b/dijit/form/MultiSelect.js
@@ -0,0 +1,49 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.MultiSelect"]){
+dojo._hasResource["dijit.form.MultiSelect"]=true;
+dojo.provide("dijit.form.MultiSelect");
+dojo.require("dijit.form._FormWidget");
+dojo.declare("dijit.form.MultiSelect",dijit.form._FormWidget,{size:7,templateString:"<select multiple='true' ${nameAttrSetting} dojoAttachPoint='containerNode,focusNode' dojoAttachEvent='onchange: _onChange'></select>",attributeMap:dojo.delegate(dijit.form._FormWidget.prototype.attributeMap,{size:"focusNode"}),reset:function(){
+this._hasBeenBlurred=false;
+this._setValueAttr(this._resetValue,true);
+},addSelected:function(_1){
+_1.getSelected().forEach(function(n){
+this.containerNode.appendChild(n);
+this.domNode.scrollTop=this.domNode.offsetHeight;
+var _3=_1.domNode.scrollTop;
+_1.domNode.scrollTop=0;
+_1.domNode.scrollTop=_3;
+},this);
+},getSelected:function(){
+return dojo.query("option",this.containerNode).filter(function(n){
+return n.selected;
+});
+},_getValueAttr:function(){
+return this.getSelected().map(function(n){
+return n.value;
+});
+},_multiValue:true,_setValueAttr:function(_6){
+dojo.query("option",this.containerNode).forEach(function(n){
+n.selected=(dojo.indexOf(_6,n.value)!=-1);
+});
+},invertSelection:function(_8){
+dojo.query("option",this.containerNode).forEach(function(n){
+n.selected=!n.selected;
+});
+this._handleOnChange(this.attr("value"),_8==true);
+},_onChange:function(e){
+this._handleOnChange(this.attr("value"),true);
+},resize:function(_b){
+if(_b){
+dojo.marginBox(this.domNode,_b);
+}
+},postCreate:function(){
+this._onChange();
+}});
+}
diff --git a/dijit/form/NumberSpinner.js b/dijit/form/NumberSpinner.js
new file mode 100644
index 0000000..c9137e0
--- /dev/null
+++ b/dijit/form/NumberSpinner.js
@@ -0,0 +1,38 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.NumberSpinner"]){
+dojo._hasResource["dijit.form.NumberSpinner"]=true;
+dojo.provide("dijit.form.NumberSpinner");
+dojo.require("dijit.form._Spinner");
+dojo.require("dijit.form.NumberTextBox");
+dojo.declare("dijit.form.NumberSpinner",[dijit.form._Spinner,dijit.form.NumberTextBoxMixin],{required:true,adjust:function(_1,_2){
+var tc=this.constraints,v=isNaN(_1),_5=!isNaN(tc.max),_6=!isNaN(tc.min);
+if(v&&_2!=0){
+_1=(_2>0)?_6?tc.min:_5?tc.max:0:_5?this.constraints.max:_6?tc.min:0;
+}
+var _7=_1+_2;
+if(v||isNaN(_7)){
+return _1;
+}
+if(_5&&(_7>tc.max)){
+_7=tc.max;
+}
+if(_6&&(_7<tc.min)){
+_7=tc.min;
+}
+return _7;
+},_onKeyPress:function(e){
+if((e.charOrCode==dojo.keys.HOME||e.charOrCode==dojo.keys.END)&&!e.ctrlKey&&!e.altKey){
+var _9=this.constraints[(e.charOrCode==dojo.keys.HOME?"min":"max")];
+if(_9){
+this._setValueAttr(_9,true);
+}
+dojo.stopEvent(e);
+}
+}});
+}
diff --git a/dijit/form/NumberTextBox.js b/dijit/form/NumberTextBox.js
new file mode 100644
index 0000000..7efdc91
--- /dev/null
+++ b/dijit/form/NumberTextBox.js
@@ -0,0 +1,82 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.NumberTextBox"]){
+dojo._hasResource["dijit.form.NumberTextBox"]=true;
+dojo.provide("dijit.form.NumberTextBox");
+dojo.require("dijit.form.ValidationTextBox");
+dojo.require("dojo.number");
+dojo.declare("dijit.form.NumberTextBoxMixin",null,{regExpGen:dojo.number.regexp,value:NaN,editOptions:{pattern:"#.######"},_formatter:dojo.number.format,postMixInProperties:function(){
+if(typeof this.constraints.max!="number"){
+this.constraints.max=9000000000000000;
+}
+this.inherited(arguments);
+},_onFocus:function(){
+if(this.disabled){
+return;
+}
+var _1=this.attr("value");
+if(typeof _1=="number"&&!isNaN(_1)){
+var _2=this.format(_1,this.constraints);
+if(_2!==undefined){
+this.textbox.value=_2;
+}
+}
+this.inherited(arguments);
+},format:function(_3,_4){
+if(typeof _3!="number"){
+return String(_3);
+}
+if(isNaN(_3)){
+return "";
+}
+if(("rangeCheck" in this)&&!this.rangeCheck(_3,_4)){
+return String(_3);
+}
+if(this.editOptions&&this._focused){
+_4=dojo.mixin(dojo.mixin({},this.editOptions),_4);
+}
+return this._formatter(_3,_4);
+},parse:dojo.number.parse,_getDisplayedValueAttr:function(){
+var v=this.inherited(arguments);
+return isNaN(v)?this.textbox.value:v;
+},filter:function(_6){
+return (_6===null||_6===""||_6===undefined)?NaN:this.inherited(arguments);
+},serialize:function(_7,_8){
+return (typeof _7!="number"||isNaN(_7))?"":this.inherited(arguments);
+},_setValueAttr:function(_9,_a,_b){
+if(_9!==undefined&&_b===undefined){
+if(typeof _9=="number"){
+if(isNaN(_9)){
+_b="";
+}else{
+if(("rangeCheck" in this)&&!this.rangeCheck(_9,this.constraints)){
+_b=String(_9);
+}
+}
+}else{
+if(!_9){
+_b="";
+_9=NaN;
+}else{
+_b=String(_9);
+_9=undefined;
+}
+}
+}
+this.inherited(arguments,[_9,_a,_b]);
+},_getValueAttr:function(){
+var v=this.inherited(arguments);
+if(isNaN(v)&&this.textbox.value!==""){
+var n=Number(this.textbox.value);
+return (String(n)===this.textbox.value)?n:undefined;
+}else{
+return v;
+}
+}});
+dojo.declare("dijit.form.NumberTextBox",[dijit.form.RangeBoundTextBox,dijit.form.NumberTextBoxMixin],{});
+}
diff --git a/dijit/form/RadioButton.js b/dijit/form/RadioButton.js
new file mode 100644
index 0000000..f355fab
--- /dev/null
+++ b/dijit/form/RadioButton.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.RadioButton"]){
+dojo._hasResource["dijit.form.RadioButton"]=true;
+dojo.provide("dijit.form.RadioButton");
+dojo.require("dijit.form.CheckBox");
+}
diff --git a/dijit/form/RangeBoundTextBox.js b/dijit/form/RangeBoundTextBox.js
new file mode 100644
index 0000000..c0dd0d2
--- /dev/null
+++ b/dijit/form/RangeBoundTextBox.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.RangeBoundTextBox"]){
+dojo._hasResource["dijit.form.RangeBoundTextBox"]=true;
+dojo.provide("dijit.form.RangeBoundTextBox");
+dojo.require("dijit.form.ValidationTextBox");
+}
diff --git a/dijit/form/SimpleTextarea.js b/dijit/form/SimpleTextarea.js
new file mode 100644
index 0000000..dafff7b
--- /dev/null
+++ b/dijit/form/SimpleTextarea.js
@@ -0,0 +1,57 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.SimpleTextarea"]){
+dojo._hasResource["dijit.form.SimpleTextarea"]=true;
+dojo.provide("dijit.form.SimpleTextarea");
+dojo.require("dijit.form.TextBox");
+dojo.declare("dijit.form.SimpleTextarea",dijit.form.TextBox,{baseClass:"dijitTextArea",attributeMap:dojo.delegate(dijit.form._FormValueWidget.prototype.attributeMap,{rows:"textbox",cols:"textbox"}),rows:"3",cols:"20",templatePath:null,templateString:"<textarea ${nameAttrSetting} dojoAttachPoint='focusNode,containerNode,textbox' autocomplete='off'></textarea>",postMixInProperties:function(){
+if(!this.value&&this.srcNodeRef){
+this.value=this.srcNodeRef.value;
+}
+this.inherited(arguments);
+},filter:function(_1){
+if(_1){
+_1=_1.replace(/\r/g,"");
+}
+return this.inherited(arguments);
+},postCreate:function(){
+this.inherited(arguments);
+if(dojo.isIE&&this.cols){
+dojo.addClass(this.domNode,"dijitTextAreaCols");
+}
+},_previousValue:"",_onInput:function(e){
+if(this.maxLength){
+var _3=parseInt(this.maxLength);
+var _4=this.textbox.value.replace(/\r/g,"");
+var _5=_4.length-_3;
+if(_5>0){
+dojo.stopEvent(e);
+var _6=this.textbox;
+if(_6.selectionStart){
+var _7=_6.selectionStart;
+var cr=0;
+if(dojo.isOpera){
+cr=(this.textbox.value.substring(0,_7).match(/\r/g)||[]).length;
+}
+this.textbox.value=_4.substring(0,_7-_5-cr)+_4.substring(_7-cr);
+_6.setSelectionRange(_7-_5,_7-_5);
+}else{
+if(dojo.doc.selection){
+_6.focus();
+var _9=dojo.doc.selection.createRange();
+_9.moveStart("character",-_5);
+_9.text="";
+_9.select();
+}
+}
+}
+this._previousValue=this.textbox.value;
+}
+this.inherited(arguments);
+}});
+}
diff --git a/dijit/form/Slider.js b/dijit/form/Slider.js
new file mode 100644
index 0000000..a2b3376
--- /dev/null
+++ b/dijit/form/Slider.js
@@ -0,0 +1,18 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.Slider"]){
+dojo._hasResource["dijit.form.Slider"]=true;
+dojo.provide("dijit.form.Slider");
+dojo.deprecated("Call require() for HorizontalSlider / VerticalRule, explicitly rather than 'dijit.form.Slider' itself","","2.0");
+dojo.require("dijit.form.HorizontalSlider");
+dojo.require("dijit.form.VerticalSlider");
+dojo.require("dijit.form.HorizontalRule");
+dojo.require("dijit.form.VerticalRule");
+dojo.require("dijit.form.HorizontalRuleLabels");
+dojo.require("dijit.form.VerticalRuleLabels");
+}
diff --git a/dijit/form/TextBox.js b/dijit/form/TextBox.js
new file mode 100644
index 0000000..54012f1
--- /dev/null
+++ b/dijit/form/TextBox.js
@@ -0,0 +1,152 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.TextBox"]){
+dojo._hasResource["dijit.form.TextBox"]=true;
+dojo.provide("dijit.form.TextBox");
+dojo.require("dijit.form._FormWidget");
+dojo.declare("dijit.form.TextBox",dijit.form._FormValueWidget,{trim:false,uppercase:false,lowercase:false,propercase:false,maxLength:"",templateString:"<input class=\"dijit dijitReset dijitLeft\" dojoAttachPoint='textbox,focusNode'\n\tdojoAttachEvent='onmouseenter:_onMouse,onmouseleave:_onMouse'\n\tautocomplete=\"off\" type=\"${type}\" ${nameAttrSetting}\n\t/>\n",baseClass:"dijitTextBox",attributeMap:dojo.delegate(dijit.form._FormValueWidget.prototype.attributeMap,{maxLength:"focusNode"} [...]
+return this.parse(this.attr("displayedValue"),this.constraints);
+},_setValueAttr:function(_1,_2,_3){
+var _4;
+if(_1!==undefined){
+_4=this.filter(_1);
+if(typeof _3!="string"){
+if(_4!==null&&((typeof _4!="number")||!isNaN(_4))){
+_3=this.filter(this.format(_4,this.constraints));
+}else{
+_3="";
+}
+}
+}
+if(_3!=null&&_3!=undefined&&((typeof _3)!="number"||!isNaN(_3))&&this.textbox.value!=_3){
+this.textbox.value=_3;
+}
+this.inherited(arguments,[_4,_2]);
+},displayedValue:"",getDisplayedValue:function(){
+dojo.deprecated(this.declaredClass+"::getDisplayedValue() is deprecated. Use attr('displayedValue') instead.","","2.0");
+return this.attr("displayedValue");
+},_getDisplayedValueAttr:function(){
+return this.filter(this.textbox.value);
+},setDisplayedValue:function(_5){
+dojo.deprecated(this.declaredClass+"::setDisplayedValue() is deprecated. Use attr('displayedValue', ...) instead.","","2.0");
+this.attr("displayedValue",_5);
+},_setDisplayedValueAttr:function(_6){
+if(_6===null||_6===undefined){
+_6="";
+}else{
+if(typeof _6!="string"){
+_6=String(_6);
+}
+}
+this.textbox.value=_6;
+this._setValueAttr(this.attr("value"),undefined,_6);
+},format:function(_7,_8){
+return ((_7==null||_7==undefined)?"":(_7.toString?_7.toString():_7));
+},parse:function(_9,_a){
+return _9;
+},_refreshState:function(){
+},_onInput:function(e){
+if(e&&e.type&&/key/i.test(e.type)&&e.keyCode){
+switch(e.keyCode){
+case dojo.keys.SHIFT:
+case dojo.keys.ALT:
+case dojo.keys.CTRL:
+case dojo.keys.TAB:
+return;
+}
+}
+if(this.intermediateChanges){
+var _c=this;
+setTimeout(function(){
+_c._handleOnChange(_c.attr("value"),false);
+},0);
+}
+this._refreshState();
+},postCreate:function(){
+this.textbox.setAttribute("value",this.textbox.value);
+this.inherited(arguments);
+if(dojo.isMoz||dojo.isOpera){
+this.connect(this.textbox,"oninput",this._onInput);
+}else{
+this.connect(this.textbox,"onkeydown",this._onInput);
+this.connect(this.textbox,"onkeyup",this._onInput);
+this.connect(this.textbox,"onpaste",this._onInput);
+this.connect(this.textbox,"oncut",this._onInput);
+}
+this._layoutHack();
+},_blankValue:"",filter:function(_d){
+if(_d===null){
+return this._blankValue;
+}
+if(typeof _d!="string"){
+return _d;
+}
+if(this.trim){
+_d=dojo.trim(_d);
+}
+if(this.uppercase){
+_d=_d.toUpperCase();
+}
+if(this.lowercase){
+_d=_d.toLowerCase();
+}
+if(this.propercase){
+_d=_d.replace(/[^\s]+/g,function(_e){
+return _e.substring(0,1).toUpperCase()+_e.substring(1);
+});
+}
+return _d;
+},_setBlurValue:function(){
+this._setValueAttr(this.attr("value"),true);
+},_onBlur:function(e){
+if(this.disabled){
+return;
+}
+this._setBlurValue();
+this.inherited(arguments);
+},_onFocus:function(e){
+if(this.disabled){
+return;
+}
+this._refreshState();
+this.inherited(arguments);
+},reset:function(){
+this.textbox.value="";
+this.inherited(arguments);
+}});
+dijit.selectInputText=function(_11,_12,_13){
+var _14=dojo.global;
+var _15=dojo.doc;
+_11=dojo.byId(_11);
+if(isNaN(_12)){
+_12=0;
+}
+if(isNaN(_13)){
+_13=_11.value?_11.value.length:0;
+}
+_11.focus();
+if(_15["selection"]&&dojo.body()["createTextRange"]){
+if(_11.createTextRange){
+var _16=_11.createTextRange();
+with(_16){
+collapse(true);
+moveStart("character",_12);
+moveEnd("character",_13);
+select();
+}
+}
+}else{
+if(_14["getSelection"]){
+var _17=_14.getSelection();
+if(_11.setSelectionRange){
+_11.setSelectionRange(_12,_13);
+}
+}
+}
+};
+}
diff --git a/dijit/form/Textarea.js b/dijit/form/Textarea.js
new file mode 100644
index 0000000..453b524
--- /dev/null
+++ b/dijit/form/Textarea.js
@@ -0,0 +1,98 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.Textarea"]){
+dojo._hasResource["dijit.form.Textarea"]=true;
+dojo.provide("dijit.form.Textarea");
+dojo.require("dijit.form.SimpleTextarea");
+dojo.declare("dijit.form.Textarea",dijit.form.SimpleTextarea,{cols:"",_previousNewlines:0,_strictMode:(dojo.doc.compatMode!="BackCompat"),_getHeight:function(_1){
+var _2=_1.scrollHeight;
+if(dojo.isIE){
+_2+=_1.offsetHeight-_1.clientHeight-((dojo.isIE<8&&this._strictMode)?dojo._getPadBorderExtents(_1).h:0);
+}else{
+if(dojo.isMoz){
+_2+=_1.offsetHeight-_1.clientHeight;
+}else{
+if(dojo.isWebKit&&!(dojo.isSafari<4)){
+_2+=dojo._getBorderExtents(_1).h;
+}else{
+_2+=dojo._getPadBorderExtents(_1).h;
+}
+}
+}
+return _2;
+},_estimateHeight:function(_3){
+_3.style.maxHeight="";
+_3.style.height="auto";
+_3.rows=(_3.value.match(/\n/g)||[]).length+1;
+},_needsHelpShrinking:dojo.isMoz||dojo.isWebKit,_onInput:function(){
+this.inherited(arguments);
+if(this._busyResizing){
+return;
+}
+this._busyResizing=true;
+var _4=this.textbox;
+if(_4.scrollHeight){
+var _5=this._getHeight(_4)+"px";
+if(_4.style.height!=_5){
+_4.style.maxHeight=_4.style.height=_5;
+}
+if(this._needsHelpShrinking){
+if(this._setTimeoutHandle){
+clearTimeout(this._setTimeoutHandle);
+}
+this._setTimeoutHandle=setTimeout(dojo.hitch(this,"_shrink"),0);
+}
+}else{
+this._estimateHeight(_4);
+}
+this._busyResizing=false;
+},_busyResizing:false,_shrink:function(){
+this._setTimeoutHandle=null;
+if(this._needsHelpShrinking&&!this._busyResizing){
+this._busyResizing=true;
+var _6=this.textbox;
+var _7=false;
+if(_6.value==""){
+_6.value=" ";
+_7=true;
+}
+var _8=_6.scrollHeight;
+if(!_8){
+this._estimateHeight(_6);
+}else{
+var _9=_6.style.paddingBottom;
+var _a=dojo._getPadExtents(_6);
+_a=_a.h-_a.t;
+_6.style.paddingBottom=_a+1+"px";
+var _b=this._getHeight(_6)-1+"px";
+if(_6.style.maxHeight!=_b){
+_6.style.paddingBottom=_a+_8+"px";
+_6.scrollTop=0;
+_6.style.maxHeight=this._getHeight(_6)-_8+"px";
+}
+_6.style.paddingBottom=_9;
+}
+if(_7){
+_6.value="";
+}
+this._busyResizing=false;
+}
+},resize:function(){
+this._onInput();
+},_setValueAttr:function(){
+this.inherited(arguments);
+this.resize();
+},postCreate:function(){
+this.inherited(arguments);
+dojo.style(this.textbox,{overflowY:"hidden",overflowX:"auto",boxSizing:"border-box",MsBoxSizing:"border-box",WebkitBoxSizing:"border-box",MozBoxSizing:"border-box"});
+this.connect(this.textbox,"onscroll",this._onInput);
+this.connect(this.textbox,"onresize",this._onInput);
+this.connect(this.textbox,"onfocus",this._onInput);
+setTimeout(dojo.hitch(this,"resize"),0);
+}});
+}
diff --git a/dijit/form/TimeTextBox.js b/dijit/form/TimeTextBox.js
new file mode 100644
index 0000000..e9c46f9
--- /dev/null
+++ b/dijit/form/TimeTextBox.js
@@ -0,0 +1,14 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.TimeTextBox"]){
+dojo._hasResource["dijit.form.TimeTextBox"]=true;
+dojo.provide("dijit.form.TimeTextBox");
+dojo.require("dijit._TimePicker");
+dojo.require("dijit.form._DateTimeTextBox");
+dojo.declare("dijit.form.TimeTextBox",dijit.form._DateTimeTextBox,{baseClass:"dijitTextBox dijitTimeTextBox",popupClass:"dijit._TimePicker",_selector:"time",value:new Date("")});
+}
diff --git a/dijit/form/ToggleButton.js b/dijit/form/ToggleButton.js
new file mode 100644
index 0000000..f05d314
--- /dev/null
+++ b/dijit/form/ToggleButton.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.ToggleButton"]){
+dojo._hasResource["dijit.form.ToggleButton"]=true;
+dojo.provide("dijit.form.ToggleButton");
+dojo.require("dijit.form.Button");
+}
diff --git a/dijit/form/ValidationTextBox.js b/dijit/form/ValidationTextBox.js
new file mode 100644
index 0000000..f45493a
--- /dev/null
+++ b/dijit/form/ValidationTextBox.js
@@ -0,0 +1,207 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.ValidationTextBox"]){
+dojo._hasResource["dijit.form.ValidationTextBox"]=true;
+dojo.provide("dijit.form.ValidationTextBox");
+dojo.require("dojo.i18n");
+dojo.require("dijit.form.TextBox");
+dojo.require("dijit.Tooltip");
+dojo.requireLocalization("dijit.form","validate",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.declare("dijit.form.ValidationTextBox",dijit.form.TextBox,{templateString:"<div class=\"dijit dijitReset dijitInlineTable dijitLeft\"\n\tid=\"widget_${id}\"\n\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\" waiRole=\"presentation\"\n\t><div style=\"overflow:hidden;\"\n\t\t><div class=\"dijitReset dijitValidationIcon\"><br></div\n\t\t><div class=\"dijitReset dijitValidationIconText\">Χ</div\n\t\t><div class=\"dijitReset dijitInputField\"\n\t\ [...]
+return this.regExp;
+},state:"",tooltipPosition:[],_setValueAttr:function(){
+this.inherited(arguments);
+this.validate(this._focused);
+},validator:function(_2,_3){
+return (new RegExp("^(?:"+this.regExpGen(_3)+")"+(this.required?"":"?")+"$")).test(_2)&&(!this.required||!this._isEmpty(_2))&&(this._isEmpty(_2)||this.parse(_2,_3)!==undefined);
+},_isValidSubset:function(){
+return this.textbox.value.search(this._partialre)==0;
+},isValid:function(_4){
+return this.validator(this.textbox.value,this.constraints);
+},_isEmpty:function(_5){
+return /^\s*$/.test(_5);
+},getErrorMessage:function(_6){
+return this.invalidMessage;
+},getPromptMessage:function(_7){
+return this.promptMessage;
+},_maskValidSubsetError:true,validate:function(_8){
+var _9="";
+var _a=this.disabled||this.isValid(_8);
+if(_a){
+this._maskValidSubsetError=true;
+}
+var _b=!_a&&_8&&this._isValidSubset();
+var _c=this._isEmpty(this.textbox.value);
+this.state=(_a||(!this._hasBeenBlurred&&_c)||_b)?"":"Error";
+if(this.state=="Error"){
+this._maskValidSubsetError=false;
+}
+this._setStateClass();
+dijit.setWaiState(this.focusNode,"invalid",_a?"false":"true");
+if(_8){
+if(_c){
+_9=this.getPromptMessage(true);
+}
+if(!_9&&(this.state=="Error"||(_b&&!this._maskValidSubsetError))){
+_9=this.getErrorMessage(true);
+}
+}
+this.displayMessage(_9);
+return _a;
+},_message:"",displayMessage:function(_d){
+if(this._message==_d){
+return;
+}
+this._message=_d;
+dijit.hideTooltip(this.domNode);
+if(_d){
+dijit.showTooltip(_d,this.domNode,this.tooltipPosition);
+}
+},_refreshState:function(){
+this.validate(this._focused);
+this.inherited(arguments);
+},constructor:function(){
+this.constraints={};
+},postMixInProperties:function(){
+this.inherited(arguments);
+this.constraints.locale=this.lang;
+this.messages=dojo.i18n.getLocalization("dijit.form","validate",this.lang);
+if(this.invalidMessage=="$_unset_$"){
+this.invalidMessage=this.messages.invalidMessage;
+}
+var p=this.regExpGen(this.constraints);
+this.regExp=p;
+var _f="";
+if(p!=".*"){
+this.regExp.replace(/\\.|\[\]|\[.*?[^\\]{1}\]|\{.*?\}|\(\?[=:!]|./g,function(re){
+switch(re.charAt(0)){
+case "{":
+case "+":
+case "?":
+case "*":
+case "^":
+case "$":
+case "|":
+case "(":
+_f+=re;
+break;
+case ")":
+_f+="|$)";
+break;
+default:
+_f+="(?:"+re+"|$)";
+break;
+}
+});
+}
+try{
+"".search(_f);
+}
+catch(e){
+_f=this.regExp;
+console.warn("RegExp error in "+this.declaredClass+": "+this.regExp);
+}
+this._partialre="^(?:"+_f+")$";
+},_setDisabledAttr:function(_11){
+this.inherited(arguments);
+if(this.valueNode){
+this.valueNode.disabled=_11;
+}
+this._refreshState();
+},_setRequiredAttr:function(_12){
+this.required=_12;
+dijit.setWaiState(this.focusNode,"required",_12);
+this._refreshState();
+},postCreate:function(){
+if(dojo.isIE){
+var s=dojo.getComputedStyle(this.focusNode);
+if(s){
+var ff=s.fontFamily;
+if(ff){
+this.focusNode.style.fontFamily=ff;
+}
+}
+}
+this.inherited(arguments);
+},reset:function(){
+this._maskValidSubsetError=true;
+this.inherited(arguments);
+}});
+dojo.declare("dijit.form.MappedTextBox",dijit.form.ValidationTextBox,{postMixInProperties:function(){
+this.inherited(arguments);
+this.nameAttrSetting="";
+},serialize:function(val,_16){
+return val.toString?val.toString():"";
+},toString:function(){
+var val=this.filter(this.attr("value"));
+return val!=null?(typeof val=="string"?val:this.serialize(val,this.constraints)):"";
+},validate:function(){
+this.valueNode.value=this.toString();
+return this.inherited(arguments);
+},buildRendering:function(){
+this.inherited(arguments);
+this.valueNode=dojo.create("input",{style:{display:"none"},type:this.type,name:this.name},this.textbox,"after");
+},_setDisabledAttr:function(_18){
+this.inherited(arguments);
+dojo.attr(this.valueNode,"disabled",_18);
+},reset:function(){
+this.valueNode.value="";
+this.inherited(arguments);
+}});
+dojo.declare("dijit.form.RangeBoundTextBox",dijit.form.MappedTextBox,{rangeMessage:"",rangeCheck:function(_19,_1a){
+var _1b="min" in _1a;
+var _1c="max" in _1a;
+if(_1b||_1c){
+return (!_1b||this.compare(_19,_1a.min)>=0)&&(!_1c||this.compare(_19,_1a.max)<=0);
+}
+return true;
+},isInRange:function(_1d){
+return this.rangeCheck(this.attr("value"),this.constraints);
+},_isDefinitelyOutOfRange:function(){
+var val=this.attr("value");
+var _1f=false;
+var _20=false;
+if("min" in this.constraints){
+var min=this.constraints.min;
+val=this.compare(val,((typeof min=="number")&&min>=0&&val!=0)?0:min);
+_1f=(typeof val=="number")&&val<0;
+}
+if("max" in this.constraints){
+var max=this.constraints.max;
+val=this.compare(val,((typeof max!="number")||max>0)?max:0);
+_20=(typeof val=="number")&&val>0;
+}
+return _1f||_20;
+},_isValidSubset:function(){
+return this.inherited(arguments)&&!this._isDefinitelyOutOfRange();
+},isValid:function(_23){
+return this.inherited(arguments)&&((this._isEmpty(this.textbox.value)&&!this.required)||this.isInRange(_23));
+},getErrorMessage:function(_24){
+if(dijit.form.RangeBoundTextBox.superclass.isValid.call(this,false)&&!this.isInRange(_24)){
+return this.rangeMessage;
+}
+return this.inherited(arguments);
+},postMixInProperties:function(){
+this.inherited(arguments);
+if(!this.rangeMessage){
+this.messages=dojo.i18n.getLocalization("dijit.form","validate",this.lang);
+this.rangeMessage=this.messages.rangeMessage;
+}
+},postCreate:function(){
+this.inherited(arguments);
+if(this.constraints.min!==undefined){
+dijit.setWaiState(this.focusNode,"valuemin",this.constraints.min);
+}
+if(this.constraints.max!==undefined){
+dijit.setWaiState(this.focusNode,"valuemax",this.constraints.max);
+}
+},_setValueAttr:function(_25,_26){
+dijit.setWaiState(this.focusNode,"valuenow",_25);
+this.inherited(arguments);
+}});
+}
diff --git a/dijit/form/VerticalRule.js b/dijit/form/VerticalRule.js
new file mode 100644
index 0000000..b8b89e0
--- /dev/null
+++ b/dijit/form/VerticalRule.js
@@ -0,0 +1,13 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.VerticalRule"]){
+dojo._hasResource["dijit.form.VerticalRule"]=true;
+dojo.provide("dijit.form.VerticalRule");
+dojo.require("dijit.form.HorizontalRule");
+dojo.declare("dijit.form.VerticalRule",dijit.form.HorizontalRule,{templateString:"<div class=\"dijitRuleContainer dijitRuleContainerV\"></div>",_positionPrefix:"<div class=\"dijitRuleMark dijitRuleMarkV\" style=\"top:",_isHorizontal:false});
+}
diff --git a/dijit/form/VerticalRuleLabels.js b/dijit/form/VerticalRuleLabels.js
new file mode 100644
index 0000000..604e03f
--- /dev/null
+++ b/dijit/form/VerticalRuleLabels.js
@@ -0,0 +1,15 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.VerticalRuleLabels"]){
+dojo._hasResource["dijit.form.VerticalRuleLabels"]=true;
+dojo.provide("dijit.form.VerticalRuleLabels");
+dojo.require("dijit.form.HorizontalRuleLabels");
+dojo.declare("dijit.form.VerticalRuleLabels",dijit.form.HorizontalRuleLabels,{templateString:"<div class=\"dijitRuleContainer dijitRuleContainerV dijitRuleLabelsContainer dijitRuleLabelsContainerV\"></div>",_positionPrefix:"<div class=\"dijitRuleLabelContainer dijitRuleLabelContainerV\" style=\"top:",_labelPrefix:"\"><span class=\"dijitRuleLabel dijitRuleLabelV\">",_calcPosition:function(_1){
+return 100-_1;
+},_isHorizontal:false});
+}
diff --git a/dijit/form/VerticalSlider.js b/dijit/form/VerticalSlider.js
new file mode 100644
index 0000000..9df15b6
--- /dev/null
+++ b/dijit/form/VerticalSlider.js
@@ -0,0 +1,39 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form.VerticalSlider"]){
+dojo._hasResource["dijit.form.VerticalSlider"]=true;
+dojo.provide("dijit.form.VerticalSlider");
+dojo.require("dijit.form.HorizontalSlider");
+dojo.declare("dijit.form.VerticalSlider",dijit.form.HorizontalSlider,{templateString:"<table class=\"dijitReset dijitSlider\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" rules=\"none\" dojoAttachEvent=\"onkeypress:_onKeyPress\"\n><tbody class=\"dijitReset\"\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset\"></td\n\t\t><td class=\"dijitReset dijitSliderButtonContainer dijitSliderButtonContainerV\"\n\t\t\t><div class=\"dijitSliderIncrementIconV\" tabIndex=\"-1\" style=\"displ [...]
+if(this._started){
+return;
+}
+if(!this.isLeftToRight()&&dojo.isMoz){
+if(this.leftDecoration){
+this._rtlRectify(this.leftDecoration);
+}
+if(this.rightDecoration){
+this._rtlRectify(this.rightDecoration);
+}
+}
+this.inherited(arguments);
+},_isReversed:function(){
+return this._descending;
+},_rtlRectify:function(_1){
+var _2=[];
+while(_1.firstChild){
+_2.push(_1.firstChild);
+_1.removeChild(_1.firstChild);
+}
+for(var i=_2.length-1;i>=0;i--){
+if(_2[i]){
+_1.appendChild(_2[i]);
+}
+}
+}});
+}
diff --git a/dijit/form/_DateTimeTextBox.js b/dijit/form/_DateTimeTextBox.js
new file mode 100644
index 0000000..8b39b1e
--- /dev/null
+++ b/dijit/form/_DateTimeTextBox.js
@@ -0,0 +1,128 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form._DateTimeTextBox"]){
+dojo._hasResource["dijit.form._DateTimeTextBox"]=true;
+dojo.provide("dijit.form._DateTimeTextBox");
+dojo.require("dojo.date");
+dojo.require("dojo.date.locale");
+dojo.require("dojo.date.stamp");
+dojo.require("dijit.form.ValidationTextBox");
+dojo.declare("dijit.form._DateTimeTextBox",dijit.form.RangeBoundTextBox,{regExpGen:dojo.date.locale.regexp,compare:dojo.date.compare,format:function(_1,_2){
+if(!_1){
+return "";
+}
+return dojo.date.locale.format(_1,_2);
+},parse:function(_3,_4){
+return dojo.date.locale.parse(_3,_4)||(this._isEmpty(_3)?null:undefined);
+},serialize:dojo.date.stamp.toISOString,value:new Date(""),_blankValue:null,popupClass:"",_selector:"",postMixInProperties:function(){
+this.inherited(arguments);
+if(!this.value||this.value.toString()==dijit.form._DateTimeTextBox.prototype.value.toString()){
+this.value=null;
+}
+var _5=this.constraints;
+_5.selector=this._selector;
+_5.fullYear=true;
+var _6=dojo.date.stamp.fromISOString;
+if(typeof _5.min=="string"){
+_5.min=_6(_5.min);
+}
+if(typeof _5.max=="string"){
+_5.max=_6(_5.max);
+}
+},_onFocus:function(_7){
+this._open();
+},_setValueAttr:function(_8,_9,_a){
+this.inherited(arguments);
+if(this._picker){
+if(!_8){
+_8=new Date();
+}
+this._picker.attr("value",_8);
+}
+},_open:function(){
+if(this.disabled||this.readOnly||!this.popupClass){
+return;
+}
+var _b=this;
+if(!this._picker){
+var _c=dojo.getObject(this.popupClass,false);
+this._picker=new _c({onValueSelected:function(_d){
+if(_b._tabbingAway){
+delete _b._tabbingAway;
+}else{
+_b.focus();
+}
+setTimeout(dojo.hitch(_b,"_close"),1);
+dijit.form._DateTimeTextBox.superclass._setValueAttr.call(_b,_d,true);
+},lang:_b.lang,constraints:_b.constraints,isDisabledDate:function(_e){
+var _f=dojo.date.compare;
+var _10=_b.constraints;
+return _10&&(_10.min&&(_f(_10.min,_e,"date")>0)||(_10.max&&_f(_10.max,_e,"date")<0));
+}});
+this._picker.attr("value",this.attr("value")||new Date());
+}
+if(!this._opened){
+dijit.popup.open({parent:this,popup:this._picker,around:this.domNode,onCancel:dojo.hitch(this,this._close),onClose:function(){
+_b._opened=false;
+}});
+this._opened=true;
+}
+dojo.marginBox(this._picker.domNode,{w:this.domNode.offsetWidth});
+},_close:function(){
+if(this._opened){
+dijit.popup.close(this._picker);
+this._opened=false;
+}
+},_onBlur:function(){
+this._close();
+if(this._picker){
+this._picker.destroy();
+delete this._picker;
+}
+this.inherited(arguments);
+},_getDisplayedValueAttr:function(){
+return this.textbox.value;
+},_setDisplayedValueAttr:function(_11,_12){
+this._setValueAttr(this.parse(_11,this.constraints),_12,_11);
+},destroy:function(){
+if(this._picker){
+this._picker.destroy();
+delete this._picker;
+}
+this.inherited(arguments);
+},postCreate:function(){
+this.inherited(arguments);
+this.connect(this.focusNode,"onkeypress",this._onKeyPress);
+},_onKeyPress:function(e){
+var p=this._picker,dk=dojo.keys;
+if(p&&this._opened&&p.handleKey){
+if(p.handleKey(e)===false){
+return;
+}
+}
+if(this._opened&&e.charOrCode==dk.ESCAPE&&!e.shiftKey&&!e.ctrlKey&&!e.altKey){
+this._close();
+dojo.stopEvent(e);
+}else{
+if(!this._opened&&e.charOrCode==dk.DOWN_ARROW){
+this._open();
+dojo.stopEvent(e);
+}else{
+if(e.charOrCode===dk.TAB){
+this._tabbingAway=true;
+}else{
+if(this._opened&&(e.keyChar||e.charOrCode===dk.BACKSPACE||e.charOrCode==dk.DELETE)){
+setTimeout(dojo.hitch(this,function(){
+dijit.placeOnScreenAroundElement(p.domNode.parentNode,this.domNode,{"BL":"TL","TL":"BL"},p.orient?dojo.hitch(p,"orient"):null);
+}),1);
+}
+}
+}
+}
+}});
+}
diff --git a/dijit/form/_FormMixin.js b/dijit/form/_FormMixin.js
new file mode 100644
index 0000000..55b0153
--- /dev/null
+++ b/dijit/form/_FormMixin.js
@@ -0,0 +1,148 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form._FormMixin"]){
+dojo._hasResource["dijit.form._FormMixin"]=true;
+dojo.provide("dijit.form._FormMixin");
+dojo.declare("dijit.form._FormMixin",null,{reset:function(){
+dojo.forEach(this.getDescendants(),function(_1){
+if(_1.reset){
+_1.reset();
+}
+});
+},validate:function(){
+var _2=false;
+return dojo.every(dojo.map(this.getDescendants(),function(_3){
+_3._hasBeenBlurred=true;
+var _4=_3.disabled||!_3.validate||_3.validate();
+if(!_4&&!_2){
+dijit.scrollIntoView(_3.containerNode||_3.domNode);
+_3.focus();
+_2=true;
+}
+return _4;
+}),function(_5){
+return _5;
+});
+},setValues:function(_6){
+dojo.deprecated(this.declaredClass+"::setValues() is deprecated. Use attr('value', val) instead.","","2.0");
+return this.attr("value",_6);
+},_setValueAttr:function(_7){
+var _8={};
+dojo.forEach(this.getDescendants(),function(_9){
+if(!_9.name){
+return;
+}
+var _a=_8[_9.name]||(_8[_9.name]=[]);
+_a.push(_9);
+});
+for(var _b in _8){
+if(!_8.hasOwnProperty(_b)){
+continue;
+}
+var _c=_8[_b],_d=dojo.getObject(_b,false,_7);
+if(_d===undefined){
+continue;
+}
+if(!dojo.isArray(_d)){
+_d=[_d];
+}
+if(typeof _c[0].checked=="boolean"){
+dojo.forEach(_c,function(w,i){
+w.attr("value",dojo.indexOf(_d,w.value)!=-1);
+});
+}else{
+if(_c[0]._multiValue){
+_c[0].attr("value",_d);
+}else{
+dojo.forEach(_c,function(w,i){
+w.attr("value",_d[i]);
+});
+}
+}
+}
+},getValues:function(){
+dojo.deprecated(this.declaredClass+"::getValues() is deprecated. Use attr('value') instead.","","2.0");
+return this.attr("value");
+},_getValueAttr:function(){
+var obj={};
+dojo.forEach(this.getDescendants(),function(_13){
+var _14=_13.name;
+if(!_14||_13.disabled){
+return;
+}
+var _15=_13.attr("value");
+if(typeof _13.checked=="boolean"){
+if(/Radio/.test(_13.declaredClass)){
+if(_15!==false){
+dojo.setObject(_14,_15,obj);
+}else{
+_15=dojo.getObject(_14,false,obj);
+if(_15===undefined){
+dojo.setObject(_14,null,obj);
+}
+}
+}else{
+var ary=dojo.getObject(_14,false,obj);
+if(!ary){
+ary=[];
+dojo.setObject(_14,ary,obj);
+}
+if(_15!==false){
+ary.push(_15);
+}
+}
+}else{
+dojo.setObject(_14,_15,obj);
+}
+});
+return obj;
+},isValid:function(){
+this._invalidWidgets=dojo.filter(this.getDescendants(),function(_17){
+return !_17.disabled&&_17.isValid&&!_17.isValid();
+});
+return !this._invalidWidgets.length;
+},onValidStateChange:function(_18){
+},_widgetChange:function(_19){
+var _1a=this._lastValidState;
+if(!_19||this._lastValidState===undefined){
+_1a=this.isValid();
+if(this._lastValidState===undefined){
+this._lastValidState=_1a;
+}
+}else{
+if(_19.isValid){
+this._invalidWidgets=dojo.filter(this._invalidWidgets||[],function(w){
+return (w!=_19);
+},this);
+if(!_19.isValid()&&!_19.attr("disabled")){
+this._invalidWidgets.push(_19);
+}
+_1a=(this._invalidWidgets.length===0);
+}
+}
+if(_1a!==this._lastValidState){
+this._lastValidState=_1a;
+this.onValidStateChange(_1a);
+}
+},connectChildren:function(){
+dojo.forEach(this._changeConnections,dojo.hitch(this,"disconnect"));
+var _1c=this;
+var _1d=this._changeConnections=[];
+dojo.forEach(dojo.filter(this.getDescendants(),function(_1e){
+return _1e.validate;
+}),function(_1f){
+_1d.push(_1c.connect(_1f,"validate",dojo.hitch(_1c,"_widgetChange",_1f)));
+_1d.push(_1c.connect(_1f,"_setDisabledAttr",dojo.hitch(_1c,"_widgetChange",_1f)));
+});
+this._widgetChange(null);
+},startup:function(){
+this.inherited(arguments);
+this._changeConnections=[];
+this.connectChildren();
+}});
+}
diff --git a/dijit/form/_FormWidget.js b/dijit/form/_FormWidget.js
new file mode 100644
index 0000000..f56f7ce
--- /dev/null
+++ b/dijit/form/_FormWidget.js
@@ -0,0 +1,214 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form._FormWidget"]){
+dojo._hasResource["dijit.form._FormWidget"]=true;
+dojo.provide("dijit.form._FormWidget");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.declare("dijit.form._FormWidget",[dijit._Widget,dijit._Templated],{baseClass:"",name:"",alt:"",value:"",type:"text",tabIndex:"0",disabled:false,readOnly:false,intermediateChanges:false,scrollOnFocus:true,attributeMap:dojo.delegate(dijit._Widget.prototype.attributeMap,{value:"focusNode",disabled:"focusNode",readOnly:"focusNode",id:"focusNode",tabIndex:"focusNode",alt:"focusNode"}),postMixInProperties:function(){
+this.nameAttrSetting=this.name?("name='"+this.name+"'"):"";
+this.inherited(arguments);
+},_setDisabledAttr:function(_1){
+this.disabled=_1;
+dojo.attr(this.focusNode,"disabled",_1);
+dijit.setWaiState(this.focusNode,"disabled",_1);
+if(_1){
+this._hovering=false;
+this._active=false;
+this.focusNode.removeAttribute("tabIndex");
+}else{
+this.focusNode.setAttribute("tabIndex",this.tabIndex);
+}
+this._setStateClass();
+},setDisabled:function(_2){
+dojo.deprecated("setDisabled("+_2+") is deprecated. Use attr('disabled',"+_2+") instead.","","2.0");
+this.attr("disabled",_2);
+},_onFocus:function(e){
+if(this.scrollOnFocus){
+dijit.scrollIntoView(this.domNode);
+}
+this.inherited(arguments);
+},_onMouse:function(_4){
+var _5=_4.currentTarget;
+if(_5&&_5.getAttribute){
+this.stateModifier=_5.getAttribute("stateModifier")||"";
+}
+if(!this.disabled){
+switch(_4.type){
+case "mouseenter":
+case "mouseover":
+this._hovering=true;
+this._active=this._mouseDown;
+break;
+case "mouseout":
+case "mouseleave":
+this._hovering=false;
+this._active=false;
+break;
+case "mousedown":
+this._active=true;
+this._mouseDown=true;
+var _6=this.connect(dojo.body(),"onmouseup",function(){
+if(this._mouseDown&&this.isFocusable()){
+this.focus();
+}
+this._active=false;
+this._mouseDown=false;
+this._setStateClass();
+this.disconnect(_6);
+});
+break;
+}
+this._setStateClass();
+}
+},isFocusable:function(){
+return !this.disabled&&!this.readOnly&&this.focusNode&&(dojo.style(this.domNode,"display")!="none");
+},focus:function(){
+dijit.focus(this.focusNode);
+},_setStateClass:function(){
+var _7=this.baseClass.split(" ");
+function _8(_9){
+_7=_7.concat(dojo.map(_7,function(c){
+return c+_9;
+}),"dijit"+_9);
+};
+if(this.checked){
+_8("Checked");
+}
+if(this.state){
+_8(this.state);
+}
+if(this.selected){
+_8("Selected");
+}
+if(this.disabled){
+_8("Disabled");
+}else{
+if(this.readOnly){
+_8("ReadOnly");
+}else{
+if(this._active){
+_8(this.stateModifier+"Active");
+}else{
+if(this._focused){
+_8("Focused");
+}
+if(this._hovering){
+_8(this.stateModifier+"Hover");
+}
+}
+}
+}
+var tn=this.stateNode||this.domNode,_c={};
+dojo.forEach(tn.className.split(" "),function(c){
+_c[c]=true;
+});
+if("_stateClasses" in this){
+dojo.forEach(this._stateClasses,function(c){
+delete _c[c];
+});
+}
+dojo.forEach(_7,function(c){
+_c[c]=true;
+});
+var _10=[];
+for(var c in _c){
+_10.push(c);
+}
+tn.className=_10.join(" ");
+this._stateClasses=_7;
+},compare:function(_12,_13){
+if((typeof _12=="number")&&(typeof _13=="number")){
+return (isNaN(_12)&&isNaN(_13))?0:(_12-_13);
+}else{
+if(_12>_13){
+return 1;
+}else{
+if(_12<_13){
+return -1;
+}else{
+return 0;
+}
+}
+}
+},onChange:function(_14){
+},_onChangeActive:false,_handleOnChange:function(_15,_16){
+this._lastValue=_15;
+if(this._lastValueReported==undefined&&(_16===null||!this._onChangeActive)){
+this._resetValue=this._lastValueReported=_15;
+}
+if((this.intermediateChanges||_16||_16===undefined)&&((typeof _15!=typeof this._lastValueReported)||this.compare(_15,this._lastValueReported)!=0)){
+this._lastValueReported=_15;
+if(this._onChangeActive){
+this.onChange(_15);
+}
+}
+},create:function(){
+this.inherited(arguments);
+this._onChangeActive=true;
+this._setStateClass();
+},destroy:function(){
+if(this._layoutHackHandle){
+clearTimeout(this._layoutHackHandle);
+}
+this.inherited(arguments);
+},setValue:function(_17){
+dojo.deprecated("dijit.form._FormWidget:setValue("+_17+") is deprecated.  Use attr('value',"+_17+") instead.","","2.0");
+this.attr("value",_17);
+},getValue:function(){
+dojo.deprecated(this.declaredClass+"::getValue() is deprecated. Use attr('value') instead.","","2.0");
+return this.attr("value");
+},_layoutHack:function(){
+if(dojo.isFF==2&&!this._layoutHackHandle){
+var _18=this.domNode;
+var old=_18.style.opacity;
+_18.style.opacity="0.999";
+this._layoutHackHandle=setTimeout(dojo.hitch(this,function(){
+this._layoutHackHandle=null;
+_18.style.opacity=old;
+}),0);
+}
+}});
+dojo.declare("dijit.form._FormValueWidget",dijit.form._FormWidget,{attributeMap:dojo.delegate(dijit.form._FormWidget.prototype.attributeMap,{value:""}),postCreate:function(){
+if(dojo.isIE||dojo.isWebKit){
+this.connect(this.focusNode||this.domNode,"onkeydown",this._onKeyDown);
+}
+if(this._resetValue===undefined){
+this._resetValue=this.value;
+}
+},_setValueAttr:function(_1a,_1b){
+this.value=_1a;
+this._handleOnChange(_1a,_1b);
+},_getValueAttr:function(_1c){
+return this._lastValue;
+},undo:function(){
+this._setValueAttr(this._lastValueReported,false);
+},reset:function(){
+this._hasBeenBlurred=false;
+this._setValueAttr(this._resetValue,true);
+},_onKeyDown:function(e){
+if(e.keyCode==dojo.keys.ESCAPE&&!e.ctrlKey&&!e.altKey){
+var te;
+if(dojo.isIE){
+e.preventDefault();
+te=document.createEventObject();
+te.keyCode=dojo.keys.ESCAPE;
+te.shiftKey=e.shiftKey;
+e.srcElement.fireEvent("onkeypress",te);
+}else{
+if(dojo.isWebKit){
+te=document.createEvent("Events");
+te.initEvent("keypress",true,true);
+te.keyCode=dojo.keys.ESCAPE;
+te.shiftKey=e.shiftKey;
+e.target.dispatchEvent(te);
+}
+}
+}
+}});
+}
diff --git a/dijit/form/_Spinner.js b/dijit/form/_Spinner.js
new file mode 100644
index 0000000..a1c194e
--- /dev/null
+++ b/dijit/form/_Spinner.js
@@ -0,0 +1,77 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.form._Spinner"]){
+dojo._hasResource["dijit.form._Spinner"]=true;
+dojo.provide("dijit.form._Spinner");
+dojo.require("dijit.form.ValidationTextBox");
+dojo.declare("dijit.form._Spinner",dijit.form.RangeBoundTextBox,{defaultTimeout:500,timeoutChangeRate:0.9,smallDelta:1,largeDelta:10,templateString:"<div class=\"dijit dijitReset dijitInlineTable dijitLeft\"\n\tid=\"widget_${id}\"\n\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\" waiRole=\"presentation\"\n\t><div class=\"dijitInputLayoutContainer\"\n\t\t><div class=\"dijitReset dijitSpinnerButtonContainer\"\n\t\t\t> <div class=\"dijitReset dijit [...]
+return _1;
+},_arrowState:function(_3,_4){
+this._active=_4;
+this.stateModifier=_3.getAttribute("stateModifier")||"";
+this._setStateClass();
+},_arrowPressed:function(_5,_6,_7){
+if(this.disabled||this.readOnly){
+return;
+}
+this._arrowState(_5,true);
+this._setValueAttr(this.adjust(this.attr("value"),_6*_7),false);
+dijit.selectInputText(this.textbox,this.textbox.value.length);
+},_arrowReleased:function(_8){
+this._wheelTimer=null;
+if(this.disabled||this.readOnly){
+return;
+}
+this._arrowState(_8,false);
+},_typematicCallback:function(_9,_a,_b){
+var _c=this.smallDelta;
+if(_a==this.textbox){
+var k=dojo.keys;
+var _e=_b.charOrCode;
+_c=(_e==k.PAGE_UP||_e==k.PAGE_DOWN)?this.largeDelta:this.smallDelta;
+_a=(_e==k.UP_ARROW||_e==k.PAGE_UP)?this.upArrowNode:this.downArrowNode;
+}
+if(_9==-1){
+this._arrowReleased(_a);
+}else{
+this._arrowPressed(_a,(_a==this.upArrowNode)?1:-1,_c);
+}
+},_wheelTimer:null,_mouseWheeled:function(_f){
+dojo.stopEvent(_f);
+var _10=_f.detail?(_f.detail*-1):(_f.wheelDelta/120);
+if(_10!==0){
+var _11=this[(_10>0?"upArrowNode":"downArrowNode")];
+this._arrowPressed(_11,_10,this.smallDelta);
+if(!this._wheelTimer){
+clearTimeout(this._wheelTimer);
+}
+this._wheelTimer=setTimeout(dojo.hitch(this,"_arrowReleased",_11),50);
+}
+},postCreate:function(){
+this.inherited(arguments);
+this.connect(this.domNode,!dojo.isMozilla?"onmousewheel":"DOMMouseScroll","_mouseWheeled");
+this._connects.push(dijit.typematic.addListener(this.upArrowNode,this.textbox,{charOrCode:dojo.keys.UP_ARROW,ctrlKey:false,altKey:false,shiftKey:false},this,"_typematicCallback",this.timeoutChangeRate,this.defaultTimeout));
+this._connects.push(dijit.typematic.addListener(this.downArrowNode,this.textbox,{charOrCode:dojo.keys.DOWN_ARROW,ctrlKey:false,altKey:false,shiftKey:false},this,"_typematicCallback",this.timeoutChangeRate,this.defaultTimeout));
+this._connects.push(dijit.typematic.addListener(this.upArrowNode,this.textbox,{charOrCode:dojo.keys.PAGE_UP,ctrlKey:false,altKey:false,shiftKey:false},this,"_typematicCallback",this.timeoutChangeRate,this.defaultTimeout));
+this._connects.push(dijit.typematic.addListener(this.downArrowNode,this.textbox,{charOrCode:dojo.keys.PAGE_DOWN,ctrlKey:false,altKey:false,shiftKey:false},this,"_typematicCallback",this.timeoutChangeRate,this.defaultTimeout));
+if(dojo.isIE){
+var _12=this;
+this.connect(this.domNode,"onresize",function(){
+setTimeout(dojo.hitch(_12,function(){
+var sz=this.upArrowNode.parentNode.offsetHeight;
+if(sz){
+this.upArrowNode.style.height=sz>>1;
+this.downArrowNode.style.height=sz-(sz>>1);
+this.focusNode.parentNode.style.height=sz;
+}
+this._setStateClass();
+}),0);
+});
+}
+}});
+}
diff --git a/dijit/form/nls/ComboBox.js b/dijit/form/nls/ComboBox.js
new file mode 100644
index 0000000..49bba39
--- /dev/null
+++ b/dijit/form/nls/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Previous choices","nextMessage":"More choices"})
\ No newline at end of file
diff --git a/dijit/form/nls/Textarea.js b/dijit/form/nls/Textarea.js
new file mode 100644
index 0000000..4b0e996
--- /dev/null
+++ b/dijit/form/nls/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"edit area","iframeFocusTitle":"edit area frame"})
\ No newline at end of file
diff --git a/dijit/form/nls/ar/ComboBox.js b/dijit/form/nls/ar/ComboBox.js
new file mode 100644
index 0000000..6a84531
--- /dev/null
+++ b/dijit/form/nls/ar/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"الاختيارات السابقة","nextMessage":"مزيد من الاختيارات"})
\ No newline at end of file
diff --git a/dijit/form/nls/ar/Textarea.js b/dijit/form/nls/ar/Textarea.js
new file mode 100644
index 0000000..fe623c6
--- /dev/null
+++ b/dijit/form/nls/ar/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"مساحة التحرير","iframeFocusTitle":"اطار مساحة التحرير"})
\ No newline at end of file
diff --git a/dijit/form/nls/ar/validate.js b/dijit/form/nls/ar/validate.js
new file mode 100644
index 0000000..615e56b
--- /dev/null
+++ b/dijit/form/nls/ar/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"هذه القيمة ليس بالمدى الصحيح.","invalidMessage":"القيمة التي تم ادخالها غير صحيحة.","missingMessage":"يجب ادخال هذه القيمة."})
\ No newline at end of file
diff --git a/dijit/form/nls/ca/ComboBox.js b/dijit/form/nls/ca/ComboBox.js
new file mode 100644
index 0000000..1a37868
--- /dev/null
+++ b/dijit/form/nls/ca/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Opcions anteriors","nextMessage":"Més opcions"})
\ No newline at end of file
diff --git a/dijit/form/nls/ca/Textarea.js b/dijit/form/nls/ca/Textarea.js
new file mode 100644
index 0000000..357f923
--- /dev/null
+++ b/dijit/form/nls/ca/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"àrea d'edició","iframeFocusTitle":"Marc de l'àrea d'edició"})
\ No newline at end of file
diff --git a/dijit/form/nls/ca/validate.js b/dijit/form/nls/ca/validate.js
new file mode 100644
index 0000000..a0a592e
--- /dev/null
+++ b/dijit/form/nls/ca/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Aquest valor és fora de l'interval","invalidMessage":"El valor introduït no és vàlid","missingMessage":"Aquest valor és necessari"})
\ No newline at end of file
diff --git a/dijit/form/nls/cs/ComboBox.js b/dijit/form/nls/cs/ComboBox.js
new file mode 100644
index 0000000..84e0841
--- /dev/null
+++ b/dijit/form/nls/cs/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Předchozí volby","nextMessage":"Další volby"})
\ No newline at end of file
diff --git a/dijit/form/nls/cs/Textarea.js b/dijit/form/nls/cs/Textarea.js
new file mode 100644
index 0000000..8a75ddc
--- /dev/null
+++ b/dijit/form/nls/cs/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"oblast úprav","iframeFocusTitle":"rámec oblasti úprav"})
\ No newline at end of file
diff --git a/dijit/form/nls/cs/validate.js b/dijit/form/nls/cs/validate.js
new file mode 100644
index 0000000..7bb7b9e
--- /dev/null
+++ b/dijit/form/nls/cs/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Tato hodnota je mimo rozsah.","invalidMessage":"Zadaná hodnota není platná.","missingMessage":"Tato hodnota je vyžadována."})
\ No newline at end of file
diff --git a/dijit/form/nls/da/ComboBox.js b/dijit/form/nls/da/ComboBox.js
new file mode 100644
index 0000000..4ddc10d
--- /dev/null
+++ b/dijit/form/nls/da/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Forrige valg","nextMessage":"Flere valg"})
\ No newline at end of file
diff --git a/dijit/form/nls/da/Textarea.js b/dijit/form/nls/da/Textarea.js
new file mode 100644
index 0000000..244c210
--- /dev/null
+++ b/dijit/form/nls/da/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"redigeringsområde","iframeFocusTitle":"ramme om redigeringsområde"})
\ No newline at end of file
diff --git a/dijit/form/nls/da/validate.js b/dijit/form/nls/da/validate.js
new file mode 100644
index 0000000..2874dd8
--- /dev/null
+++ b/dijit/form/nls/da/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Værdien er uden for intervallet.","invalidMessage":"Den angivne værdi er ugyldig.","missingMessage":"Værdien er påkrævet."})
\ No newline at end of file
diff --git a/dijit/form/nls/de/ComboBox.js b/dijit/form/nls/de/ComboBox.js
new file mode 100644
index 0000000..6cce34b
--- /dev/null
+++ b/dijit/form/nls/de/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Vorherige Auswahl","nextMessage":"Weitere Auswahlmöglichkeiten"})
\ No newline at end of file
diff --git a/dijit/form/nls/de/Textarea.js b/dijit/form/nls/de/Textarea.js
new file mode 100644
index 0000000..2cf75db
--- /dev/null
+++ b/dijit/form/nls/de/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"Editierbereich","iframeFocusTitle":"Rahmen für Editierbereich"})
\ No newline at end of file
diff --git a/dijit/form/nls/de/validate.js b/dijit/form/nls/de/validate.js
new file mode 100644
index 0000000..597796d
--- /dev/null
+++ b/dijit/form/nls/de/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Dieser Wert liegt außerhalb des gültigen Bereichs. ","invalidMessage":"Der eingegebene Wert ist ungültig. ","missingMessage":"Dieser Wert ist erforderlich."})
\ No newline at end of file
diff --git a/dijit/form/nls/el/ComboBox.js b/dijit/form/nls/el/ComboBox.js
new file mode 100644
index 0000000..ec294d1
--- /dev/null
+++ b/dijit/form/nls/el/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Προηγούμενες επιλογές","nextMessage":"Περισσότερες επιλογές"})
\ No newline at end of file
diff --git a/dijit/form/nls/el/Textarea.js b/dijit/form/nls/el/Textarea.js
new file mode 100644
index 0000000..9ce37a9
--- /dev/null
+++ b/dijit/form/nls/el/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"περιοχή επεξεργασίας","iframeFocusTitle":"πλαίσιο περιοχής επεξεργασίας"})
\ No newline at end of file
diff --git a/dijit/form/nls/el/validate.js b/dijit/form/nls/el/validate.js
new file mode 100644
index 0000000..cc57d55
--- /dev/null
+++ b/dijit/form/nls/el/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Η τιμή αυτή δεν ανήκει στο εύρος έγκυρων τιμών.","invalidMessage":"Η τιμή που καταχωρήσατε δεν είναι έγκυρη.","missingMessage":"Η τιμή αυτή πρέπει απαραίτητα να καθοριστεί."})
\ No newline at end of file
diff --git a/dijit/form/nls/es/ComboBox.js b/dijit/form/nls/es/ComboBox.js
new file mode 100644
index 0000000..5bf69f9
--- /dev/null
+++ b/dijit/form/nls/es/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Opciones anteriores","nextMessage":"Más opciones"})
\ No newline at end of file
diff --git a/dijit/form/nls/es/Textarea.js b/dijit/form/nls/es/Textarea.js
new file mode 100644
index 0000000..f92a50f
--- /dev/null
+++ b/dijit/form/nls/es/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"área de edición","iframeFocusTitle":"marco del área de edición"})
\ No newline at end of file
diff --git a/dijit/form/nls/es/validate.js b/dijit/form/nls/es/validate.js
new file mode 100644
index 0000000..65e190e
--- /dev/null
+++ b/dijit/form/nls/es/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Este valor está fuera del intervalo.","invalidMessage":"El valor especificado no es válido.","missingMessage":"Este valor es necesario."})
\ No newline at end of file
diff --git a/dijit/form/nls/fi/ComboBox.js b/dijit/form/nls/fi/ComboBox.js
new file mode 100644
index 0000000..6d9b830
--- /dev/null
+++ b/dijit/form/nls/fi/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Edelliset valinnat","nextMessage":"Lisää valintoja"})
\ No newline at end of file
diff --git a/dijit/form/nls/fi/Textarea.js b/dijit/form/nls/fi/Textarea.js
new file mode 100644
index 0000000..5efaee9
--- /dev/null
+++ b/dijit/form/nls/fi/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"muokkausalue","iframeFocusTitle":"muokkausalueen kehys"})
\ No newline at end of file
diff --git a/dijit/form/nls/fi/validate.js b/dijit/form/nls/fi/validate.js
new file mode 100644
index 0000000..276efcd
--- /dev/null
+++ b/dijit/form/nls/fi/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Tämä arvo on sallitun alueen ulkopuolella.","invalidMessage":"Annettu arvo ei kelpaa.","missingMessage":"Tämä arvo on pakollinen."})
\ No newline at end of file
diff --git a/dijit/form/nls/fr/ComboBox.js b/dijit/form/nls/fr/ComboBox.js
new file mode 100644
index 0000000..14b3976
--- /dev/null
+++ b/dijit/form/nls/fr/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Choix précédents","nextMessage":"Plus de choix"})
\ No newline at end of file
diff --git a/dijit/form/nls/fr/Textarea.js b/dijit/form/nls/fr/Textarea.js
new file mode 100644
index 0000000..4abb6c3
--- /dev/null
+++ b/dijit/form/nls/fr/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"zone d'édition","iframeFocusTitle":"cadre de la zone d'édition"})
\ No newline at end of file
diff --git a/dijit/form/nls/fr/validate.js b/dijit/form/nls/fr/validate.js
new file mode 100644
index 0000000..95a0169
--- /dev/null
+++ b/dijit/form/nls/fr/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Cette valeur n'est pas comprise dans la plage autorisée.","invalidMessage":"La valeur indiquée n'est pas correcte.","missingMessage":"Cette valeur est requise."})
\ No newline at end of file
diff --git a/dijit/form/nls/he/ComboBox.js b/dijit/form/nls/he/ComboBox.js
new file mode 100644
index 0000000..169d0f5
--- /dev/null
+++ b/dijit/form/nls/he/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"האפשרויות הקודמות","nextMessage":"אפשרויות נוספות"})
\ No newline at end of file
diff --git a/dijit/form/nls/he/Textarea.js b/dijit/form/nls/he/Textarea.js
new file mode 100644
index 0000000..809eadf
--- /dev/null
+++ b/dijit/form/nls/he/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"אזור עריכה","iframeFocusTitle":"מסגרת אזור עריכה"})
\ No newline at end of file
diff --git a/dijit/form/nls/he/validate.js b/dijit/form/nls/he/validate.js
new file mode 100644
index 0000000..3d778e2
--- /dev/null
+++ b/dijit/form/nls/he/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"הערך מחוץ לטווח.","invalidMessage":"הערך שצוין אינו חוקי.","missingMessage":"זהו ערך דרוש."})
\ No newline at end of file
diff --git a/dijit/form/nls/hu/ComboBox.js b/dijit/form/nls/hu/ComboBox.js
new file mode 100644
index 0000000..4b6a620
--- /dev/null
+++ b/dijit/form/nls/hu/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Előző menüpontok","nextMessage":"További menüpontok"})
\ No newline at end of file
diff --git a/dijit/form/nls/hu/Textarea.js b/dijit/form/nls/hu/Textarea.js
new file mode 100644
index 0000000..9b4ca01
--- /dev/null
+++ b/dijit/form/nls/hu/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"szerkesztési terület","iframeFocusTitle":"szerkesztési terület keret"})
\ No newline at end of file
diff --git a/dijit/form/nls/hu/validate.js b/dijit/form/nls/hu/validate.js
new file mode 100644
index 0000000..b6d7996
--- /dev/null
+++ b/dijit/form/nls/hu/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Az érték kívül van a megengedett tartományon.","invalidMessage":"A megadott érték érvénytelen.","missingMessage":"Meg kell adni egy értéket."})
\ No newline at end of file
diff --git a/dijit/form/nls/it/ComboBox.js b/dijit/form/nls/it/ComboBox.js
new file mode 100644
index 0000000..9f67072
--- /dev/null
+++ b/dijit/form/nls/it/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Scelte precedenti","nextMessage":"Altre scelte"})
\ No newline at end of file
diff --git a/dijit/form/nls/it/Textarea.js b/dijit/form/nls/it/Textarea.js
new file mode 100644
index 0000000..1b14ecc
--- /dev/null
+++ b/dijit/form/nls/it/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"modifica area","iframeFocusTitle":"modifica frame area"})
\ No newline at end of file
diff --git a/dijit/form/nls/it/validate.js b/dijit/form/nls/it/validate.js
new file mode 100644
index 0000000..af7227f
--- /dev/null
+++ b/dijit/form/nls/it/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Questo valore non è compreso nell'intervallo.","invalidMessage":"Il valore immesso non è valido.","missingMessage":"Questo valore è obbligatorio."})
\ No newline at end of file
diff --git a/dijit/form/nls/ja/ComboBox.js b/dijit/form/nls/ja/ComboBox.js
new file mode 100644
index 0000000..6b34170
--- /dev/null
+++ b/dijit/form/nls/ja/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"以前の選択項目","nextMessage":"追加の選択項目"})
\ No newline at end of file
diff --git a/dijit/form/nls/ja/Textarea.js b/dijit/form/nls/ja/Textarea.js
new file mode 100644
index 0000000..8a52f4a
--- /dev/null
+++ b/dijit/form/nls/ja/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"編集域","iframeFocusTitle":"編集域フレーム"})
\ No newline at end of file
diff --git a/dijit/form/nls/ja/validate.js b/dijit/form/nls/ja/validate.js
new file mode 100644
index 0000000..450cd7e
--- /dev/null
+++ b/dijit/form/nls/ja/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"この値は範囲外です。","invalidMessage":"入力した値は無効です。","missingMessage":"この値は必須です。"})
\ No newline at end of file
diff --git a/dijit/form/nls/ko/ComboBox.js b/dijit/form/nls/ko/ComboBox.js
new file mode 100644
index 0000000..87d0f06
--- /dev/null
+++ b/dijit/form/nls/ko/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"이전 선택사항","nextMessage":"기타 선택사항"})
\ No newline at end of file
diff --git a/dijit/form/nls/ko/Textarea.js b/dijit/form/nls/ko/Textarea.js
new file mode 100644
index 0000000..5c4e916
--- /dev/null
+++ b/dijit/form/nls/ko/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"편집 영역","iframeFocusTitle":"편집 영역 프레임"})
\ No newline at end of file
diff --git a/dijit/form/nls/ko/validate.js b/dijit/form/nls/ko/validate.js
new file mode 100644
index 0000000..c76c676
--- /dev/null
+++ b/dijit/form/nls/ko/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"이 값은 범위를 벗어납니다.","invalidMessage":"입력된 값이 올바르지 않습니다.","missingMessage":"이 값은 필수입니다."})
\ No newline at end of file
diff --git a/dijit/form/nls/nb/ComboBox.js b/dijit/form/nls/nb/ComboBox.js
new file mode 100644
index 0000000..de14554
--- /dev/null
+++ b/dijit/form/nls/nb/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Tidligere valg","nextMessage":"Flere valg"})
\ No newline at end of file
diff --git a/dijit/form/nls/nb/Textarea.js b/dijit/form/nls/nb/Textarea.js
new file mode 100644
index 0000000..16fadf5
--- /dev/null
+++ b/dijit/form/nls/nb/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"redigeringsområde","iframeFocusTitle":"ramme for redigeringsområde"})
\ No newline at end of file
diff --git a/dijit/form/nls/nb/validate.js b/dijit/form/nls/nb/validate.js
new file mode 100644
index 0000000..2fe96f2
--- /dev/null
+++ b/dijit/form/nls/nb/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Denne verdien er utenfor gyldig område.","invalidMessage":"Den angitte verdien er ikke gyldig.","missingMessage":"Denne verdien er obligatorisk."})
\ No newline at end of file
diff --git a/dijit/form/nls/nl/ComboBox.js b/dijit/form/nls/nl/ComboBox.js
new file mode 100644
index 0000000..b5885d7
--- /dev/null
+++ b/dijit/form/nls/nl/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Eerdere opties","nextMessage":"Meer opties"})
\ No newline at end of file
diff --git a/dijit/form/nls/nl/Textarea.js b/dijit/form/nls/nl/Textarea.js
new file mode 100644
index 0000000..d13c3a6
--- /dev/null
+++ b/dijit/form/nls/nl/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"veld bewerken","iframeFocusTitle":"veldkader bewerken"})
\ No newline at end of file
diff --git a/dijit/form/nls/nl/validate.js b/dijit/form/nls/nl/validate.js
new file mode 100644
index 0000000..b3062c1
--- /dev/null
+++ b/dijit/form/nls/nl/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Deze waarde is niet toegestaan.","invalidMessage":"De opgegeven waarde is ongeldig.","missingMessage":"Deze waarde is verplicht."})
\ No newline at end of file
diff --git a/dijit/form/nls/pl/ComboBox.js b/dijit/form/nls/pl/ComboBox.js
new file mode 100644
index 0000000..f2b4b08
--- /dev/null
+++ b/dijit/form/nls/pl/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Poprzednie wybory","nextMessage":"Więcej wyborów"})
\ No newline at end of file
diff --git a/dijit/form/nls/pl/Textarea.js b/dijit/form/nls/pl/Textarea.js
new file mode 100644
index 0000000..d918f59
--- /dev/null
+++ b/dijit/form/nls/pl/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"Obszar edycji","iframeFocusTitle":"Ramka obszaru edycji"})
\ No newline at end of file
diff --git a/dijit/form/nls/pl/validate.js b/dijit/form/nls/pl/validate.js
new file mode 100644
index 0000000..cf05d2f
--- /dev/null
+++ b/dijit/form/nls/pl/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Ta wartość jest spoza zakresu.","invalidMessage":"Wprowadzona wartość jest niepoprawna.","missingMessage":"Ta wartość jest wymagana."})
\ No newline at end of file
diff --git a/dijit/form/nls/pt-pt/ComboBox.js b/dijit/form/nls/pt-pt/ComboBox.js
new file mode 100644
index 0000000..2540542
--- /dev/null
+++ b/dijit/form/nls/pt-pt/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Opções anteriores","nextMessage":"Mais opções"})
\ No newline at end of file
diff --git a/dijit/form/nls/pt-pt/Textarea.js b/dijit/form/nls/pt-pt/Textarea.js
new file mode 100644
index 0000000..bcd75e7
--- /dev/null
+++ b/dijit/form/nls/pt-pt/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"área de edição","iframeFocusTitle":"painel da área de edição"})
\ No newline at end of file
diff --git a/dijit/form/nls/pt-pt/validate.js b/dijit/form/nls/pt-pt/validate.js
new file mode 100644
index 0000000..3d92170
--- /dev/null
+++ b/dijit/form/nls/pt-pt/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Este valor encontra-se fora do intervalo.","invalidMessage":"O valor introduzido não é válido.","missingMessage":"Este valor é requerido."})
\ No newline at end of file
diff --git a/dijit/form/nls/pt/ComboBox.js b/dijit/form/nls/pt/ComboBox.js
new file mode 100644
index 0000000..2540542
--- /dev/null
+++ b/dijit/form/nls/pt/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Opções anteriores","nextMessage":"Mais opções"})
\ No newline at end of file
diff --git a/dijit/form/nls/pt/Textarea.js b/dijit/form/nls/pt/Textarea.js
new file mode 100644
index 0000000..b4a0b0f
--- /dev/null
+++ b/dijit/form/nls/pt/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"editar área","iframeFocusTitle":"editar quadro da área"})
\ No newline at end of file
diff --git a/dijit/form/nls/pt/validate.js b/dijit/form/nls/pt/validate.js
new file mode 100644
index 0000000..3b43579
--- /dev/null
+++ b/dijit/form/nls/pt/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Este valor está fora do intervalo. ","invalidMessage":"O valor inserido não é válido.","missingMessage":"Este valor é necessário."})
\ No newline at end of file
diff --git a/dijit/form/nls/ru/ComboBox.js b/dijit/form/nls/ru/ComboBox.js
new file mode 100644
index 0000000..193f4ee
--- /dev/null
+++ b/dijit/form/nls/ru/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Предыдущие варианты","nextMessage":"Следующие варианты"})
\ No newline at end of file
diff --git a/dijit/form/nls/ru/Textarea.js b/dijit/form/nls/ru/Textarea.js
new file mode 100644
index 0000000..ad7ad22
--- /dev/null
+++ b/dijit/form/nls/ru/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"область редактирования","iframeFocusTitle":"фрейм области редактирования"})
\ No newline at end of file
diff --git a/dijit/form/nls/ru/validate.js b/dijit/form/nls/ru/validate.js
new file mode 100644
index 0000000..35fb5ca
--- /dev/null
+++ b/dijit/form/nls/ru/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Это значение вне диапазона.","invalidMessage":"Указано недопустимое значение.","missingMessage":"Это обязательное значение."})
\ No newline at end of file
diff --git a/dijit/form/nls/sk/ComboBox.js b/dijit/form/nls/sk/ComboBox.js
new file mode 100644
index 0000000..a45c7f2
--- /dev/null
+++ b/dijit/form/nls/sk/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Predchádzajúce voľby","nextMessage":"Ďalšie voľby"})
\ No newline at end of file
diff --git a/dijit/form/nls/sk/Textarea.js b/dijit/form/nls/sk/Textarea.js
new file mode 100644
index 0000000..3ee98c3
--- /dev/null
+++ b/dijit/form/nls/sk/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"upraviť oblasť","iframeFocusTitle":"upraviť rám oblasti"})
\ No newline at end of file
diff --git a/dijit/form/nls/sk/validate.js b/dijit/form/nls/sk/validate.js
new file mode 100644
index 0000000..612dab5
--- /dev/null
+++ b/dijit/form/nls/sk/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Táto hodnota je mimo rozsah.","invalidMessage":"Zadaná hodnota nie je platná.","missingMessage":"Táto hodnota je vyžadovaná."})
\ No newline at end of file
diff --git a/dijit/form/nls/sl/ComboBox.js b/dijit/form/nls/sl/ComboBox.js
new file mode 100644
index 0000000..e955688
--- /dev/null
+++ b/dijit/form/nls/sl/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Prejšnje možnosti","nextMessage":"Dodatne možnosti"})
\ No newline at end of file
diff --git a/dijit/form/nls/sl/Textarea.js b/dijit/form/nls/sl/Textarea.js
new file mode 100644
index 0000000..00e9ee8
--- /dev/null
+++ b/dijit/form/nls/sl/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"uredi področje","iframeFocusTitle":"uredi področje okvirja"})
\ No newline at end of file
diff --git a/dijit/form/nls/sl/validate.js b/dijit/form/nls/sl/validate.js
new file mode 100644
index 0000000..7635724
--- /dev/null
+++ b/dijit/form/nls/sl/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Ta vrednost je zunaj obsega. ","invalidMessage":"Vnesena vrednost ni veljavna.","missingMessage":"Ta vrednost je zahtevana."})
\ No newline at end of file
diff --git a/dijit/form/nls/sv/ComboBox.js b/dijit/form/nls/sv/ComboBox.js
new file mode 100644
index 0000000..860bf75
--- /dev/null
+++ b/dijit/form/nls/sv/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Föregående alternativ","nextMessage":"Fler alternativ"})
\ No newline at end of file
diff --git a/dijit/form/nls/sv/Textarea.js b/dijit/form/nls/sv/Textarea.js
new file mode 100644
index 0000000..9e508ac
--- /dev/null
+++ b/dijit/form/nls/sv/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"redigeringsområde","iframeFocusTitle":"redigeringsområdesram"})
\ No newline at end of file
diff --git a/dijit/form/nls/sv/validate.js b/dijit/form/nls/sv/validate.js
new file mode 100644
index 0000000..8c1b537
--- /dev/null
+++ b/dijit/form/nls/sv/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Värdet är utanför intervallet.","invalidMessage":"Det angivna värdet är ogiltigt.","missingMessage":"Värdet är obligatoriskt."})
\ No newline at end of file
diff --git a/dijit/form/nls/th/ComboBox.js b/dijit/form/nls/th/ComboBox.js
new file mode 100644
index 0000000..ff32a4f
--- /dev/null
+++ b/dijit/form/nls/th/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"การเลือกก่อนหน้า","nextMessage":"การเลือกเพิ่มเติม"})
\ No newline at end of file
diff --git a/dijit/form/nls/th/Textarea.js b/dijit/form/nls/th/Textarea.js
new file mode 100644
index 0000000..4361183
--- /dev/null
+++ b/dijit/form/nls/th/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"แก้ไขพื้นที่","iframeFocusTitle":"แก้ไขกรอบพื้นที่"})
\ No newline at end of file
diff --git a/dijit/form/nls/th/validate.js b/dijit/form/nls/th/validate.js
new file mode 100644
index 0000000..86606b7
--- /dev/null
+++ b/dijit/form/nls/th/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"ค่านี้เกินช่วง","invalidMessage":"ค่าที่ป้อนไม่ถูกต้อง","missingMessage":"จำเป็นต้องมีค่านี้"})
\ No newline at end of file
diff --git a/dijit/form/nls/tr/ComboBox.js b/dijit/form/nls/tr/ComboBox.js
new file mode 100644
index 0000000..46f71dc
--- /dev/null
+++ b/dijit/form/nls/tr/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"Önceki seçenekler","nextMessage":"Diğer seçenekler"})
\ No newline at end of file
diff --git a/dijit/form/nls/tr/Textarea.js b/dijit/form/nls/tr/Textarea.js
new file mode 100644
index 0000000..3f2b5e7
--- /dev/null
+++ b/dijit/form/nls/tr/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"düzenleme alanı","iframeFocusTitle":"düzenleme alanı çerçevesi"})
\ No newline at end of file
diff --git a/dijit/form/nls/tr/validate.js b/dijit/form/nls/tr/validate.js
new file mode 100644
index 0000000..838dbda
--- /dev/null
+++ b/dijit/form/nls/tr/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"Bu değer aralık dışında.","invalidMessage":"Girilen değer geçersiz.","missingMessage":"Bu değer gerekli."})
\ No newline at end of file
diff --git a/dijit/form/nls/validate.js b/dijit/form/nls/validate.js
new file mode 100644
index 0000000..29a1a47
--- /dev/null
+++ b/dijit/form/nls/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"This value is out of range.","invalidMessage":"The value entered is not valid.","missingMessage":"This value is required."})
\ No newline at end of file
diff --git a/dijit/form/nls/zh-tw/ComboBox.js b/dijit/form/nls/zh-tw/ComboBox.js
new file mode 100644
index 0000000..ead5fa6
--- /dev/null
+++ b/dijit/form/nls/zh-tw/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"前一個選擇項","nextMessage":"其他選擇項"})
\ No newline at end of file
diff --git a/dijit/form/nls/zh-tw/Textarea.js b/dijit/form/nls/zh-tw/Textarea.js
new file mode 100644
index 0000000..cb7abda
--- /dev/null
+++ b/dijit/form/nls/zh-tw/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"編輯區","iframeFocusTitle":"編輯區框"})
\ No newline at end of file
diff --git a/dijit/form/nls/zh-tw/validate.js b/dijit/form/nls/zh-tw/validate.js
new file mode 100644
index 0000000..b398a31
--- /dev/null
+++ b/dijit/form/nls/zh-tw/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"此值超出範圍。","invalidMessage":"輸入的值無效。","missingMessage":"必須提供此值。"})
\ No newline at end of file
diff --git a/dijit/form/nls/zh/ComboBox.js b/dijit/form/nls/zh/ComboBox.js
new file mode 100644
index 0000000..7cc92cf
--- /dev/null
+++ b/dijit/form/nls/zh/ComboBox.js
@@ -0,0 +1 @@
+({"previousMessage":"先前选项","nextMessage":"更多选项"})
\ No newline at end of file
diff --git a/dijit/form/nls/zh/Textarea.js b/dijit/form/nls/zh/Textarea.js
new file mode 100644
index 0000000..e1cf172
--- /dev/null
+++ b/dijit/form/nls/zh/Textarea.js
@@ -0,0 +1 @@
+({"iframeEditTitle":"编辑区","iframeFocusTitle":"编辑区框架"})
\ No newline at end of file
diff --git a/dijit/form/nls/zh/validate.js b/dijit/form/nls/zh/validate.js
new file mode 100644
index 0000000..e2c01f5
--- /dev/null
+++ b/dijit/form/nls/zh/validate.js
@@ -0,0 +1 @@
+({"rangeMessage":"此值超出范围。","invalidMessage":"输入的值无效。","missingMessage":"此值是必需值。"})
\ No newline at end of file
diff --git a/dijit/layout/AccordionContainer.js b/dijit/layout/AccordionContainer.js
new file mode 100644
index 0000000..e1d635a
--- /dev/null
+++ b/dijit/layout/AccordionContainer.js
@@ -0,0 +1,158 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.layout.AccordionContainer"]){
+dojo._hasResource["dijit.layout.AccordionContainer"]=true;
+dojo.provide("dijit.layout.AccordionContainer");
+dojo.require("dojo.fx");
+dojo.require("dijit._Container");
+dojo.require("dijit._Templated");
+dojo.require("dijit.layout.StackContainer");
+dojo.require("dijit.layout.ContentPane");
+dojo.require("dijit.layout.AccordionPane");
+dojo.declare("dijit.layout.AccordionContainer",dijit.layout.StackContainer,{duration:dijit.defaultDuration,_verticalSpace:0,baseClass:"dijitAccordionContainer",postCreate:function(){
+this.domNode.style.overflow="hidden";
+this.inherited(arguments);
+dijit.setWaiRole(this.domNode,"tablist");
+},startup:function(){
+if(this._started){
+return;
+}
+this.inherited(arguments);
+if(this.selectedChildWidget){
+var _1=this.selectedChildWidget.containerNode.style;
+_1.display="";
+_1.overflow="auto";
+this.selectedChildWidget._buttonWidget._setSelectedState(true);
+}
+},_getTargetHeight:function(_2){
+var cs=dojo.getComputedStyle(_2);
+return Math.max(this._verticalSpace-dojo._getPadBorderExtents(_2,cs).h,0);
+},layout:function(){
+var _4=this.selectedChildWidget;
+var _5=0;
+dojo.forEach(this.getChildren(),function(_6){
+_5+=_6._buttonWidget.getTitleHeight();
+});
+var _7=this._contentBox;
+this._verticalSpace=_7.h-_5;
+this._containerContentBox={h:this._verticalSpace,w:_7.w};
+if(_4){
+_4.resize(this._containerContentBox);
+}
+},_setupChild:function(_8){
+_8._buttonWidget=new dijit.layout._AccordionButton({contentWidget:_8,title:_8.title,id:_8.id+"_button",parent:this});
+dojo.place(_8._buttonWidget.domNode,_8.domNode,"before");
+this.inherited(arguments);
+},removeChild:function(_9){
+_9._buttonWidget.destroy();
+this.inherited(arguments);
+},getChildren:function(){
+return dojo.filter(this.inherited(arguments),function(_a){
+return _a.declaredClass!="dijit.layout._AccordionButton";
+});
+},destroy:function(){
+dojo.forEach(this.getChildren(),function(_b){
+_b._buttonWidget.destroy();
+});
+this.inherited(arguments);
+},_transition:function(_c,_d){
+if(this._inTransition){
+return;
+}
+this._inTransition=true;
+var _e=[];
+var _f=this._verticalSpace;
+if(_c){
+_c._buttonWidget.setSelected(true);
+this._showChild(_c);
+if(this.doLayout&&_c.resize){
+_c.resize(this._containerContentBox);
+}
+var _10=_c.domNode;
+dojo.addClass(_10,"dijitVisible");
+dojo.removeClass(_10,"dijitHidden");
+var _11=_10.style.overflow;
+_10.style.overflow="hidden";
+_e.push(dojo.animateProperty({node:_10,duration:this.duration,properties:{height:{start:1,end:this._getTargetHeight(_10)}},onEnd:dojo.hitch(this,function(){
+_10.style.overflow=_11;
+delete this._inTransition;
+})}));
+}
+if(_d){
+_d._buttonWidget.setSelected(false);
+var _12=_d.domNode,_13=_12.style.overflow;
+_12.style.overflow="hidden";
+_e.push(dojo.animateProperty({node:_12,duration:this.duration,properties:{height:{start:this._getTargetHeight(_12),end:1}},onEnd:function(){
+dojo.addClass(_12,"dijitHidden");
+dojo.removeClass(_12,"dijitVisible");
+_12.style.overflow=_13;
+if(_d.onHide){
+_d.onHide();
+}
+}}));
+}
+dojo.fx.combine(_e).play();
+},_onKeyPress:function(e,_15){
+if(this._inTransition||this.disabled||e.altKey||!(_15||e.ctrlKey)){
+if(this._inTransition){
+dojo.stopEvent(e);
+}
+return;
+}
+var k=dojo.keys,c=e.charOrCode;
+if((_15&&(c==k.LEFT_ARROW||c==k.UP_ARROW))||(e.ctrlKey&&c==k.PAGE_UP)){
+this._adjacent(false)._buttonWidget._onTitleClick();
+dojo.stopEvent(e);
+}else{
+if((_15&&(c==k.RIGHT_ARROW||c==k.DOWN_ARROW))||(e.ctrlKey&&(c==k.PAGE_DOWN||c==k.TAB))){
+this._adjacent(true)._buttonWidget._onTitleClick();
+dojo.stopEvent(e);
+}
+}
+}});
+dojo.declare("dijit.layout._AccordionButton",[dijit._Widget,dijit._Templated],{templateString:"<div dojoAttachPoint='titleNode,focusNode' dojoAttachEvent='ondijitclick:_onTitleClick,onkeypress:_onTitleKeyPress,onfocus:_handleFocus,onblur:_handleFocus,onmouseenter:_onTitleEnter,onmouseleave:_onTitleLeave'\n\t\tclass='dijitAccordionTitle' wairole=\"tab\" waiState=\"expanded-false\"\n\t\t><span class='dijitInline dijitAccordionArrow' waiRole=\"presentation\"></span\n\t\t><span class='arrowT [...]
+return this.parent;
+},postCreate:function(){
+this.inherited(arguments);
+dojo.setSelectable(this.domNode,false);
+this.setSelected(this.selected);
+var _18=dojo.attr(this.domNode,"id").replace(" ","_");
+dojo.attr(this.titleTextNode,"id",_18+"_title");
+dijit.setWaiState(this.focusNode,"labelledby",dojo.attr(this.titleTextNode,"id"));
+},getTitleHeight:function(){
+return dojo.marginBox(this.titleNode).h;
+},_onTitleClick:function(){
+var _19=this.getParent();
+if(!_19._inTransition){
+_19.selectChild(this.contentWidget);
+dijit.focus(this.focusNode);
+}
+},_onTitleEnter:function(){
+dojo.addClass(this.focusNode,"dijitAccordionTitle-hover");
+},_onTitleLeave:function(){
+dojo.removeClass(this.focusNode,"dijitAccordionTitle-hover");
+},_onTitleKeyPress:function(evt){
+return this.getParent()._onKeyPress(evt,this.contentWidget);
+},_setSelectedState:function(_1b){
+this.selected=_1b;
+dojo[(_1b?"addClass":"removeClass")](this.titleNode,"dijitAccordionTitle-selected");
+dijit.setWaiState(this.focusNode,"expanded",_1b);
+dijit.setWaiState(this.focusNode,"selected",_1b);
+this.focusNode.setAttribute("tabIndex",_1b?"0":"-1");
+},_handleFocus:function(e){
+dojo[(e.type=="focus"?"addClass":"removeClass")](this.focusNode,"dijitAccordionFocused");
+},setSelected:function(_1d){
+this._setSelectedState(_1d);
+if(_1d){
+var cw=this.contentWidget;
+if(cw.onSelected){
+cw.onSelected();
+}
+}
+}});
+}
diff --git a/dijit/layout/AccordionPane.js b/dijit/layout/AccordionPane.js
new file mode 100644
index 0000000..4804c41
--- /dev/null
+++ b/dijit/layout/AccordionPane.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.layout.AccordionPane"]){
+dojo._hasResource["dijit.layout.AccordionPane"]=true;
+dojo.provide("dijit.layout.AccordionPane");
+dojo.require("dijit.layout.ContentPane");
+dojo.declare("dijit.layout.AccordionPane",dijit.layout.ContentPane,{constructor:function(){
+dojo.deprecated("dijit.layout.AccordionPane deprecated, use ContentPane instead","","2.0");
+},onSelected:function(){
+}});
+}
diff --git a/dijit/layout/BorderContainer.js b/dijit/layout/BorderContainer.js
new file mode 100644
index 0000000..cb1f690
--- /dev/null
+++ b/dijit/layout/BorderContainer.js
@@ -0,0 +1,346 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.layout.BorderContainer"]){
+dojo._hasResource["dijit.layout.BorderContainer"]=true;
+dojo.provide("dijit.layout.BorderContainer");
+dojo.require("dijit.layout._LayoutWidget");
+dojo.require("dojo.cookie");
+dojo.declare("dijit.layout.BorderContainer",dijit.layout._LayoutWidget,{design:"headline",gutters:true,liveSplitters:true,persist:false,baseClass:"dijitBorderContainer",_splitterClass:"dijit.layout._Splitter",postMixInProperties:function(){
+if(!this.gutters){
+this.baseClass+="NoGutter";
+}
+this.inherited(arguments);
+},postCreate:function(){
+this.inherited(arguments);
+this._splitters={};
+this._splitterThickness={};
+},startup:function(){
+if(this._started){
+return;
+}
+dojo.forEach(this.getChildren(),this._setupChild,this);
+this.inherited(arguments);
+},_setupChild:function(_1){
+var _2=_1.region;
+if(_2){
+this.inherited(arguments);
+dojo.addClass(_1.domNode,this.baseClass+"Pane");
+var _3=this.isLeftToRight();
+if(_2=="leading"){
+_2=_3?"left":"right";
+}
+if(_2=="trailing"){
+_2=_3?"right":"left";
+}
+this["_"+_2]=_1.domNode;
+this["_"+_2+"Widget"]=_1;
+if((_1.splitter||this.gutters)&&!this._splitters[_2]){
+var _4=dojo.getObject(_1.splitter?this._splitterClass:"dijit.layout._Gutter");
+var _5={left:"right",right:"left",top:"bottom",bottom:"top",leading:"trailing",trailing:"leading"};
+var _6=new _4({container:this,child:_1,region:_2,oppNode:this["_"+_5[_1.region]],live:this.liveSplitters});
+_6.isSplitter=true;
+this._splitters[_2]=_6.domNode;
+dojo.place(this._splitters[_2],_1.domNode,"after");
+_6.startup();
+}
+_1.region=_2;
+}
+},_computeSplitterThickness:function(_7){
+this._splitterThickness[_7]=this._splitterThickness[_7]||dojo.marginBox(this._splitters[_7])[(/top|bottom/.test(_7)?"h":"w")];
+},layout:function(){
+for(var _8 in this._splitters){
+this._computeSplitterThickness(_8);
+}
+this._layoutChildren();
+},addChild:function(_9,_a){
+this.inherited(arguments);
+if(this._started){
+this._layoutChildren();
+}
+},removeChild:function(_b){
+var _c=_b.region;
+var _d=this._splitters[_c];
+if(_d){
+dijit.byNode(_d).destroy();
+delete this._splitters[_c];
+delete this._splitterThickness[_c];
+}
+this.inherited(arguments);
+delete this["_"+_c];
+delete this["_"+_c+"Widget"];
+if(this._started){
+this._layoutChildren(_b.region);
+}
+dojo.removeClass(_b.domNode,this.baseClass+"Pane");
+},getChildren:function(){
+return dojo.filter(this.inherited(arguments),function(_e){
+return !_e.isSplitter;
+});
+},getSplitter:function(_f){
+var _10=this._splitters[_f];
+return _10?dijit.byNode(_10):null;
+},resize:function(_11,_12){
+if(!this.cs||!this.pe){
+var _13=this.domNode;
+this.cs=dojo.getComputedStyle(_13);
+this.pe=dojo._getPadExtents(_13,this.cs);
+this.pe.r=dojo._toPixelValue(_13,this.cs.paddingRight);
+this.pe.b=dojo._toPixelValue(_13,this.cs.paddingBottom);
+dojo.style(_13,"padding","0px");
+}
+this.inherited(arguments);
+},_layoutChildren:function(_14){
+if(!this._borderBox||!this._borderBox.h){
+return;
+}
+var _15=(this.design=="sidebar");
+var _16=0,_17=0,_18=0,_19=0;
+var _1a={},_1b={},_1c={},_1d={},_1e=(this._center&&this._center.style)||{};
+var _1f=/left|right/.test(_14);
+var _20=!_14||(!_1f&&!_15);
+var _21=!_14||(_1f&&_15);
+if(this._top){
+_1a=_21&&this._top.style;
+_16=dojo.marginBox(this._top).h;
+}
+if(this._left){
+_1b=_20&&this._left.style;
+_18=dojo.marginBox(this._left).w;
+}
+if(this._right){
+_1c=_20&&this._right.style;
+_19=dojo.marginBox(this._right).w;
+}
+if(this._bottom){
+_1d=_21&&this._bottom.style;
+_17=dojo.marginBox(this._bottom).h;
+}
+var _22=this._splitters;
+var _23=_22.top,_24=_22.bottom,_25=_22.left,_26=_22.right;
+var _27=this._splitterThickness;
+var _28=_27.top||0,_29=_27.left||0,_2a=_27.right||0,_2b=_27.bottom||0;
+if(_29>50||_2a>50){
+setTimeout(dojo.hitch(this,function(){
+this._splitterThickness={};
+for(var _2c in this._splitters){
+this._computeSplitterThickness(_2c);
+}
+this._layoutChildren();
+}),50);
+return false;
+}
+var pe=this.pe;
+var _2e={left:(_15?_18+_29:0)+pe.l+"px",right:(_15?_19+_2a:0)+pe.r+"px"};
+if(_23){
+dojo.mixin(_23.style,_2e);
+_23.style.top=_16+pe.t+"px";
+}
+if(_24){
+dojo.mixin(_24.style,_2e);
+_24.style.bottom=_17+pe.b+"px";
+}
+_2e={top:(_15?0:_16+_28)+pe.t+"px",bottom:(_15?0:_17+_2b)+pe.b+"px"};
+if(_25){
+dojo.mixin(_25.style,_2e);
+_25.style.left=_18+pe.l+"px";
+}
+if(_26){
+dojo.mixin(_26.style,_2e);
+_26.style.right=_19+pe.r+"px";
+}
+dojo.mixin(_1e,{top:pe.t+_16+_28+"px",left:pe.l+_18+_29+"px",right:pe.r+_19+_2a+"px",bottom:pe.b+_17+_2b+"px"});
+var _2f={top:_15?pe.t+"px":_1e.top,bottom:_15?pe.b+"px":_1e.bottom};
+dojo.mixin(_1b,_2f);
+dojo.mixin(_1c,_2f);
+_1b.left=pe.l+"px";
+_1c.right=pe.r+"px";
+_1a.top=pe.t+"px";
+_1d.bottom=pe.b+"px";
+if(_15){
+_1a.left=_1d.left=_18+_29+pe.l+"px";
+_1a.right=_1d.right=_19+_2a+pe.r+"px";
+}else{
+_1a.left=_1d.left=pe.l+"px";
+_1a.right=_1d.right=pe.r+"px";
+}
+var _30=this._borderBox.h-pe.t-pe.b,_31=_30-(_16+_28+_17+_2b),_32=_15?_30:_31;
+var _33=this._borderBox.w-pe.l-pe.r,_34=_33-(_18+_29+_19+_2a),_35=_15?_34:_33;
+var dim={top:{w:_35,h:_16},bottom:{w:_35,h:_17},left:{w:_18,h:_32},right:{w:_19,h:_32},center:{h:_31,w:_34}};
+var _37=dojo.isIE<8||(dojo.isIE&&dojo.isQuirks)||dojo.some(this.getChildren(),function(_38){
+return _38.domNode.tagName=="TEXTAREA"||_38.domNode.tagName=="INPUT";
+});
+if(_37){
+var _39=function(_3a,_3b,_3c){
+if(_3a){
+(_3a.resize?_3a.resize(_3b,_3c):dojo.marginBox(_3a.domNode,_3b));
+}
+};
+if(_25){
+_25.style.height=_32;
+}
+if(_26){
+_26.style.height=_32;
+}
+_39(this._leftWidget,{h:_32},dim.left);
+_39(this._rightWidget,{h:_32},dim.right);
+if(_23){
+_23.style.width=_35;
+}
+if(_24){
+_24.style.width=_35;
+}
+_39(this._topWidget,{w:_35},dim.top);
+_39(this._bottomWidget,{w:_35},dim.bottom);
+_39(this._centerWidget,dim.center);
+}else{
+var _3d={};
+if(_14){
+_3d[_14]=_3d.center=true;
+if(/top|bottom/.test(_14)&&this.design!="sidebar"){
+_3d.left=_3d.right=true;
+}else{
+if(/left|right/.test(_14)&&this.design=="sidebar"){
+_3d.top=_3d.bottom=true;
+}
+}
+}
+dojo.forEach(this.getChildren(),function(_3e){
+if(_3e.resize&&(!_14||_3e.region in _3d)){
+_3e.resize(null,dim[_3e.region]);
+}
+},this);
+}
+},destroy:function(){
+for(var _3f in this._splitters){
+var _40=this._splitters[_3f];
+dijit.byNode(_40).destroy();
+dojo.destroy(_40);
+}
+delete this._splitters;
+delete this._splitterThickness;
+this.inherited(arguments);
+}});
+dojo.extend(dijit._Widget,{region:"",splitter:false,minSize:0,maxSize:Infinity});
+dojo.require("dijit._Templated");
+dojo.declare("dijit.layout._Splitter",[dijit._Widget,dijit._Templated],{live:true,templateString:"<div class=\"dijitSplitter\" dojoAttachEvent=\"onkeypress:_onKeyPress,onmousedown:_startDrag\" tabIndex=\"0\" waiRole=\"separator\"><div class=\"dijitSplitterThumb\"></div></div>",postCreate:function(){
+this.inherited(arguments);
+this.horizontal=/top|bottom/.test(this.region);
+dojo.addClass(this.domNode,"dijitSplitter"+(this.horizontal?"H":"V"));
+this._factor=/top|left/.test(this.region)?1:-1;
+this._minSize=this.child.minSize;
+this.child.domNode._recalc=true;
+this.connect(this.container,"resize",function(){
+this.child.domNode._recalc=true;
+});
+this._cookieName=this.container.id+"_"+this.region;
+if(this.container.persist){
+var _41=dojo.cookie(this._cookieName);
+if(_41){
+this.child.domNode.style[this.horizontal?"height":"width"]=_41;
+}
+}
+},_computeMaxSize:function(){
+var dim=this.horizontal?"h":"w",_43=this.container._splitterThickness[this.region];
+var _44=dojo.contentBox(this.container.domNode)[dim]-(this.oppNode?dojo.marginBox(this.oppNode)[dim]:0)-20-_43*2;
+this._maxSize=Math.min(this.child.maxSize,_44);
+},_startDrag:function(e){
+if(this.child.domNode._recalc){
+this._computeMaxSize();
+this.child.domNode._recalc=false;
+}
+if(!this.cover){
+this.cover=dojo.doc.createElement("div");
+dojo.addClass(this.cover,"dijitSplitterCover");
+dojo.place(this.cover,this.child.domNode,"after");
+}
+dojo.addClass(this.cover,"dijitSplitterCoverActive");
+if(this.fake){
+dojo.destroy(this.fake);
+}
+if(!(this._resize=this.live)){
+(this.fake=this.domNode.cloneNode(true)).removeAttribute("id");
+dojo.addClass(this.domNode,"dijitSplitterShadow");
+dojo.place(this.fake,this.domNode,"after");
+}
+dojo.addClass(this.domNode,"dijitSplitterActive");
+var _46=this._factor,max=this._maxSize,min=this._minSize||20,_49=this.horizontal,_4a=_49?"pageY":"pageX",_4b=e[_4a],_4c=this.domNode.style,dim=_49?"h":"w",_4e=dojo.marginBox(this.child.domNode)[dim],_4f=this.region,_50=parseInt(this.domNode.style[_4f],10),_51=this._resize,mb={},_53=this.child.domNode,_54=dojo.hitch(this.container,this.container._layoutChildren),de=dojo.doc.body;
+this._handlers=(this._handlers||[]).concat([dojo.connect(de,"onmousemove",this._drag=function(e,_57){
+var _58=e[_4a]-_4b,_59=_46*_58+_4e,_5a=Math.max(Math.min(_59,max),min);
+if(_51||_57){
+mb[dim]=_5a;
+dojo.marginBox(_53,mb);
+_54(_4f);
+}
+_4c[_4f]=_46*_58+_50+(_5a-_59)+"px";
+}),dojo.connect(dojo.doc,"ondragstart",dojo.stopEvent),dojo.connect(dojo.body(),"onselectstart",dojo.stopEvent),dojo.connect(de,"onmouseup",this,"_stopDrag")]);
+dojo.stopEvent(e);
+},_stopDrag:function(e){
+try{
+if(this.cover){
+dojo.removeClass(this.cover,"dijitSplitterCoverActive");
+}
+if(this.fake){
+dojo.destroy(this.fake);
+}
+dojo.removeClass(this.domNode,"dijitSplitterActive");
+dojo.removeClass(this.domNode,"dijitSplitterShadow");
+this._drag(e);
+this._drag(e,true);
+}
+finally{
+this._cleanupHandlers();
+if(this.oppNode){
+this.oppNode._recalc=true;
+}
+delete this._drag;
+}
+if(this.container.persist){
+dojo.cookie(this._cookieName,this.child.domNode.style[this.horizontal?"height":"width"],{expires:365});
+}
+},_cleanupHandlers:function(){
+dojo.forEach(this._handlers,dojo.disconnect);
+delete this._handlers;
+},_onKeyPress:function(e){
+if(this.child.domNode._recalc){
+this._computeMaxSize();
+this.child.domNode._recalc=false;
+}
+this._resize=true;
+var _5d=this.horizontal;
+var _5e=1;
+var dk=dojo.keys;
+switch(e.charOrCode){
+case _5d?dk.UP_ARROW:dk.LEFT_ARROW:
+_5e*=-1;
+case _5d?dk.DOWN_ARROW:dk.RIGHT_ARROW:
+break;
+default:
+return;
+}
+var _60=dojo.marginBox(this.child.domNode)[_5d?"h":"w"]+this._factor*_5e;
+var mb={};
+mb[this.horizontal?"h":"w"]=Math.max(Math.min(_60,this._maxSize),this._minSize);
+dojo.marginBox(this.child.domNode,mb);
+if(this.oppNode){
+this.oppNode._recalc=true;
+}
+this.container._layoutChildren(this.region);
+dojo.stopEvent(e);
+},destroy:function(){
+this._cleanupHandlers();
+delete this.child;
+delete this.container;
+delete this.cover;
+delete this.fake;
+this.inherited(arguments);
+}});
+dojo.declare("dijit.layout._Gutter",[dijit._Widget,dijit._Templated],{templateString:"<div class=\"dijitGutter\" waiRole=\"presentation\"></div>",postCreate:function(){
+this.horizontal=/top|bottom/.test(this.region);
+dojo.addClass(this.domNode,"dijitGutter"+(this.horizontal?"H":"V"));
+}});
+}
diff --git a/dijit/layout/ContentPane.js b/dijit/layout/ContentPane.js
new file mode 100644
index 0000000..df61022
--- /dev/null
+++ b/dijit/layout/ContentPane.js
@@ -0,0 +1,256 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.layout.ContentPane"]){
+dojo._hasResource["dijit.layout.ContentPane"]=true;
+dojo.provide("dijit.layout.ContentPane");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Contained");
+dojo.require("dijit.layout._LayoutWidget");
+dojo.require("dojo.parser");
+dojo.require("dojo.string");
+dojo.require("dojo.html");
+dojo.requireLocalization("dijit","loading",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.declare("dijit.layout.ContentPane",dijit._Widget,{href:"",extractContent:false,parseOnLoad:true,preventCache:false,preload:false,refreshOnShow:false,loadingMessage:"<span class='dijitContentPaneLoading'>${loadingState}</span>",errorMessage:"<span class='dijitContentPaneError'>${errorState}</span>",isLoaded:false,baseClass:"dijitContentPane",doLayout:true,ioArgs:{},isContainer:true,postMixInProperties:function(){
+this.inherited(arguments);
+var _1=dojo.i18n.getLocalization("dijit","loading",this.lang);
+this.loadingMessage=dojo.string.substitute(this.loadingMessage,_1);
+this.errorMessage=dojo.string.substitute(this.errorMessage,_1);
+if(!this.href&&this.srcNodeRef&&this.srcNodeRef.innerHTML){
+this.isLoaded=true;
+}
+},buildRendering:function(){
+this.inherited(arguments);
+if(!this.containerNode){
+this.containerNode=this.domNode;
+}
+},postCreate:function(){
+this.domNode.title="";
+if(!dojo.attr(this.domNode,"role")){
+dijit.setWaiRole(this.domNode,"group");
+}
+dojo.addClass(this.domNode,this.baseClass);
+},startup:function(){
+if(this._started){
+return;
+}
+if(this.isLoaded){
+dojo.forEach(this.getChildren(),function(_2){
+_2.startup();
+});
+if(this.doLayout){
+this._checkIfSingleChild();
+}
+if(!this._singleChild||!dijit._Contained.prototype.getParent.call(this)){
+this._scheduleLayout();
+}
+}
+this._loadCheck();
+this.inherited(arguments);
+},_checkIfSingleChild:function(){
+var _3=dojo.query(">",this.containerNode),_4=_3.filter(function(_5){
+return dojo.hasAttr(_5,"dojoType")||dojo.hasAttr(_5,"widgetId");
+}),_6=dojo.filter(_4.map(dijit.byNode),function(_7){
+return _7&&_7.domNode&&_7.resize;
+});
+if(_3.length==_4.length&&_6.length==1){
+this._singleChild=_6[0];
+}else{
+delete this._singleChild;
+}
+},setHref:function(_8){
+dojo.deprecated("dijit.layout.ContentPane.setHref() is deprecated. Use attr('href', ...) instead.","","2.0");
+return this.attr("href",_8);
+},_setHrefAttr:function(_9){
+this.cancel();
+this.href=_9;
+if(this._created&&(this.preload||this._isShown())){
+return this.refresh();
+}else{
+this._hrefChanged=true;
+}
+},setContent:function(_a){
+dojo.deprecated("dijit.layout.ContentPane.setContent() is deprecated.  Use attr('content', ...) instead.","","2.0");
+this.attr("content",_a);
+},_setContentAttr:function(_b){
+this.href="";
+this.cancel();
+this._setContent(_b||"");
+this._isDownloaded=false;
+},_getContentAttr:function(){
+return this.containerNode.innerHTML;
+},cancel:function(){
+if(this._xhrDfd&&(this._xhrDfd.fired==-1)){
+this._xhrDfd.cancel();
+}
+delete this._xhrDfd;
+},uninitialize:function(){
+if(this._beingDestroyed){
+this.cancel();
+}
+},destroyRecursive:function(_c){
+if(this._beingDestroyed){
+return;
+}
+this._beingDestroyed=true;
+this.inherited(arguments);
+},resize:function(_d){
+dojo.marginBox(this.domNode,_d);
+var _e=this.containerNode,mb=dojo.mixin(dojo.marginBox(_e),_d||{});
+var cb=(this._contentBox=dijit.layout.marginBox2contentBox(_e,mb));
+if(this._singleChild&&this._singleChild.resize){
+this._singleChild.resize({w:cb.w,h:cb.h});
+}
+},_isShown:function(){
+if("open" in this){
+return this.open;
+}else{
+var _11=this.domNode;
+return (_11.style.display!="none")&&(_11.style.visibility!="hidden")&&!dojo.hasClass(_11,"dijitHidden");
+}
+},_onShow:function(){
+if(this._needLayout){
+this._layoutChildren();
+}
+this._loadCheck();
+if(this.onShow){
+this.onShow();
+}
+},_loadCheck:function(){
+if((this.href&&!this._xhrDfd)&&(!this.isLoaded||this._hrefChanged||this.refreshOnShow)&&(this.preload||this._isShown())){
+delete this._hrefChanged;
+this.refresh();
+}
+},refresh:function(){
+this.cancel();
+this._setContent(this.onDownloadStart(),true);
+var _12=this;
+var _13={preventCache:(this.preventCache||this.refreshOnShow),url:this.href,handleAs:"text"};
+if(dojo.isObject(this.ioArgs)){
+dojo.mixin(_13,this.ioArgs);
+}
+var _14=(this._xhrDfd=(this.ioMethod||dojo.xhrGet)(_13));
+_14.addCallback(function(_15){
+try{
+_12._isDownloaded=true;
+_12._setContent(_15,false);
+_12.onDownloadEnd();
+}
+catch(err){
+_12._onError("Content",err);
+}
+delete _12._xhrDfd;
+return _15;
+});
+_14.addErrback(function(err){
+if(!_14.canceled){
+_12._onError("Download",err);
+}
+delete _12._xhrDfd;
+return err;
+});
+},_onLoadHandler:function(_17){
+this.isLoaded=true;
+try{
+this.onLoad(_17);
+}
+catch(e){
+console.error("Error "+this.widgetId+" running custom onLoad code: "+e.message);
+}
+},_onUnloadHandler:function(){
+this.isLoaded=false;
+try{
+this.onUnload();
+}
+catch(e){
+console.error("Error "+this.widgetId+" running custom onUnload code: "+e.message);
+}
+},destroyDescendants:function(){
+if(this.isLoaded){
+this._onUnloadHandler();
+}
+var _18=this._contentSetter;
+dojo.forEach(this.getChildren(),function(_19){
+if(_19.destroyRecursive){
+_19.destroyRecursive();
+}
+});
+if(_18){
+dojo.forEach(_18.parseResults,function(_1a){
+if(_1a.destroyRecursive&&_1a.domNode&&_1a.domNode.parentNode==dojo.body()){
+_1a.destroyRecursive();
+}
+});
+delete _18.parseResults;
+}
+dojo.html._emptyNode(this.containerNode);
+},_setContent:function(_1b,_1c){
+this.destroyDescendants();
+delete this._singleChild;
+var _1d=this._contentSetter;
+if(!(_1d&&_1d instanceof dojo.html._ContentSetter)){
+_1d=this._contentSetter=new dojo.html._ContentSetter({node:this.containerNode,_onError:dojo.hitch(this,this._onError),onContentError:dojo.hitch(this,function(e){
+var _1f=this.onContentError(e);
+try{
+this.containerNode.innerHTML=_1f;
+}
+catch(e){
+console.error("Fatal "+this.id+" could not change content due to "+e.message,e);
+}
+})});
+}
+var _20=dojo.mixin({cleanContent:this.cleanContent,extractContent:this.extractContent,parseContent:this.parseOnLoad},this._contentSetterParams||{});
+dojo.mixin(_1d,_20);
+_1d.set((dojo.isObject(_1b)&&_1b.domNode)?_1b.domNode:_1b);
+delete this._contentSetterParams;
+if(!_1c){
+dojo.forEach(this.getChildren(),function(_21){
+_21.startup();
+});
+if(this.doLayout){
+this._checkIfSingleChild();
+}
+this._scheduleLayout();
+this._onLoadHandler(_1b);
+}
+},_onError:function(_22,err,_24){
+var _25=this["on"+_22+"Error"].call(this,err);
+if(_24){
+console.error(_24,err);
+}else{
+if(_25){
+this._setContent(_25,true);
+}
+}
+},_scheduleLayout:function(){
+if(this._isShown()){
+this._layoutChildren();
+}else{
+this._needLayout=true;
+}
+},_layoutChildren:function(){
+if(this._singleChild&&this._singleChild.resize){
+var cb=this._contentBox||dojo.contentBox(this.containerNode);
+this._singleChild.resize({w:cb.w,h:cb.h});
+}else{
+dojo.forEach(this.getChildren(),function(_27){
+if(_27.resize){
+_27.resize();
+}
+});
+}
+delete this._needLayout;
+},onLoad:function(_28){
+},onUnload:function(){
+},onDownloadStart:function(){
+return this.loadingMessage;
+},onContentError:function(_29){
+},onDownloadError:function(_2a){
+return this.errorMessage;
+},onDownloadEnd:function(){
+}});
+}
diff --git a/dijit/layout/LayoutContainer.js b/dijit/layout/LayoutContainer.js
new file mode 100644
index 0000000..d949a68
--- /dev/null
+++ b/dijit/layout/LayoutContainer.js
@@ -0,0 +1,28 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.layout.LayoutContainer"]){
+dojo._hasResource["dijit.layout.LayoutContainer"]=true;
+dojo.provide("dijit.layout.LayoutContainer");
+dojo.require("dijit.layout._LayoutWidget");
+dojo.declare("dijit.layout.LayoutContainer",dijit.layout._LayoutWidget,{baseClass:"dijitLayoutContainer",constructor:function(){
+dojo.deprecated("dijit.layout.LayoutContainer is deprecated","use BorderContainer instead",2);
+},layout:function(){
+dijit.layout.layoutChildren(this.domNode,this._contentBox,this.getChildren());
+},addChild:function(_1,_2){
+this.inherited(arguments);
+if(this._started){
+dijit.layout.layoutChildren(this.domNode,this._contentBox,this.getChildren());
+}
+},removeChild:function(_3){
+this.inherited(arguments);
+if(this._started){
+dijit.layout.layoutChildren(this.domNode,this._contentBox,this.getChildren());
+}
+}});
+dojo.extend(dijit._Widget,{layoutAlign:"none"});
+}
diff --git a/dijit/layout/LinkPane.js b/dijit/layout/LinkPane.js
new file mode 100644
index 0000000..855f283
--- /dev/null
+++ b/dijit/layout/LinkPane.js
@@ -0,0 +1,20 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.layout.LinkPane"]){
+dojo._hasResource["dijit.layout.LinkPane"]=true;
+dojo.provide("dijit.layout.LinkPane");
+dojo.require("dijit.layout.ContentPane");
+dojo.require("dijit._Templated");
+dojo.declare("dijit.layout.LinkPane",[dijit.layout.ContentPane,dijit._Templated],{templateString:"<div class=\"dijitLinkPane\" dojoAttachPoint=\"containerNode\"></div>",postMixInProperties:function(){
+if(this.srcNodeRef){
+this.title+=this.srcNodeRef.innerHTML;
+}
+this.inherited(arguments);
+},_fillContent:function(_1){
+}});
+}
diff --git a/dijit/layout/SplitContainer.js b/dijit/layout/SplitContainer.js
new file mode 100644
index 0000000..92b58d3
--- /dev/null
+++ b/dijit/layout/SplitContainer.js
@@ -0,0 +1,349 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.layout.SplitContainer"]){
+dojo._hasResource["dijit.layout.SplitContainer"]=true;
+dojo.provide("dijit.layout.SplitContainer");
+dojo.require("dojo.cookie");
+dojo.require("dijit.layout._LayoutWidget");
+dojo.declare("dijit.layout.SplitContainer",dijit.layout._LayoutWidget,{constructor:function(){
+dojo.deprecated("dijit.layout.SplitContainer is deprecated","use BorderContainer with splitter instead",2);
+},activeSizing:false,sizerWidth:7,orientation:"horizontal",persist:true,baseClass:"dijitSplitContainer",postMixInProperties:function(){
+this.inherited("postMixInProperties",arguments);
+this.isHorizontal=(this.orientation=="horizontal");
+},postCreate:function(){
+this.inherited(arguments);
+this.sizers=[];
+if(dojo.isMozilla){
+this.domNode.style.overflow="-moz-scrollbars-none";
+}
+if(typeof this.sizerWidth=="object"){
+try{
+this.sizerWidth=parseInt(this.sizerWidth.toString());
+}
+catch(e){
+this.sizerWidth=7;
+}
+}
+var _1=dojo.doc.createElement("div");
+this.virtualSizer=_1;
+_1.style.position="relative";
+_1.style.zIndex=10;
+_1.className=this.isHorizontal?"dijitSplitContainerVirtualSizerH":"dijitSplitContainerVirtualSizerV";
+this.domNode.appendChild(_1);
+dojo.setSelectable(_1,false);
+},destroy:function(){
+delete this.virtualSizer;
+dojo.forEach(this._ownconnects,dojo.disconnect);
+this.inherited(arguments);
+},startup:function(){
+if(this._started){
+return;
+}
+dojo.forEach(this.getChildren(),function(_2,i,_4){
+this._setupChild(_2);
+if(i<_4.length-1){
+this._addSizer();
+}
+},this);
+if(this.persist){
+this._restoreState();
+}
+this.inherited(arguments);
+},_setupChild:function(_5){
+this.inherited(arguments);
+_5.domNode.style.position="absolute";
+dojo.addClass(_5.domNode,"dijitSplitPane");
+},_onSizerMouseDown:function(e){
+if(e.target.id){
+for(var i=0;i<this.sizers.length;i++){
+if(this.sizers[i].id==e.target.id){
+break;
+}
+}
+if(i<this.sizers.length){
+this.beginSizing(e,i);
+}
+}
+},_addSizer:function(_8){
+_8=_8===undefined?this.sizers.length:_8;
+var _9=dojo.doc.createElement("div");
+_9.id=dijit.getUniqueId("dijit_layout_SplitterContainer_Splitter");
+this.sizers.splice(_8,0,_9);
+this.domNode.appendChild(_9);
+_9.className=this.isHorizontal?"dijitSplitContainerSizerH":"dijitSplitContainerSizerV";
+var _a=dojo.doc.createElement("div");
+_a.className="thumb";
+_a.id=_9.id;
+_9.appendChild(_a);
+this.connect(_9,"onmousedown","_onSizerMouseDown");
+dojo.setSelectable(_9,false);
+},removeChild:function(_b){
+if(this.sizers.length){
+var i=dojo.indexOf(this.getChildren(),_b);
+if(i!=-1){
+if(i==this.sizers.length){
+i--;
+}
+dojo.destroy(this.sizers[i]);
+this.sizers.splice(i,1);
+}
+}
+this.inherited(arguments);
+if(this._started){
+this.layout();
+}
+},addChild:function(_d,_e){
+this.inherited(arguments);
+if(this._started){
+var _f=this.getChildren();
+if(_f.length>1){
+this._addSizer(_e);
+}
+this.layout();
+}
+},layout:function(){
+this.paneWidth=this._contentBox.w;
+this.paneHeight=this._contentBox.h;
+var _10=this.getChildren();
+if(!_10.length){
+return;
+}
+var _11=this.isHorizontal?this.paneWidth:this.paneHeight;
+if(_10.length>1){
+_11-=this.sizerWidth*(_10.length-1);
+}
+var _12=0;
+dojo.forEach(_10,function(_13){
+_12+=_13.sizeShare;
+});
+var _14=_11/_12;
+var _15=0;
+dojo.forEach(_10.slice(0,_10.length-1),function(_16){
+var _17=Math.round(_14*_16.sizeShare);
+_16.sizeActual=_17;
+_15+=_17;
+});
+_10[_10.length-1].sizeActual=_11-_15;
+this._checkSizes();
+var pos=0;
+var _19=_10[0].sizeActual;
+this._movePanel(_10[0],pos,_19);
+_10[0].position=pos;
+pos+=_19;
+if(!this.sizers){
+return;
+}
+dojo.some(_10.slice(1),function(_1a,i){
+if(!this.sizers[i]){
+return true;
+}
+this._moveSlider(this.sizers[i],pos,this.sizerWidth);
+this.sizers[i].position=pos;
+pos+=this.sizerWidth;
+_19=_1a.sizeActual;
+this._movePanel(_1a,pos,_19);
+_1a.position=pos;
+pos+=_19;
+},this);
+},_movePanel:function(_1c,pos,_1e){
+if(this.isHorizontal){
+_1c.domNode.style.left=pos+"px";
+_1c.domNode.style.top=0;
+var box={w:_1e,h:this.paneHeight};
+if(_1c.resize){
+_1c.resize(box);
+}else{
+dojo.marginBox(_1c.domNode,box);
+}
+}else{
+_1c.domNode.style.left=0;
+_1c.domNode.style.top=pos+"px";
+var box={w:this.paneWidth,h:_1e};
+if(_1c.resize){
+_1c.resize(box);
+}else{
+dojo.marginBox(_1c.domNode,box);
+}
+}
+},_moveSlider:function(_20,pos,_22){
+if(this.isHorizontal){
+_20.style.left=pos+"px";
+_20.style.top=0;
+dojo.marginBox(_20,{w:_22,h:this.paneHeight});
+}else{
+_20.style.left=0;
+_20.style.top=pos+"px";
+dojo.marginBox(_20,{w:this.paneWidth,h:_22});
+}
+},_growPane:function(_23,_24){
+if(_23>0){
+if(_24.sizeActual>_24.sizeMin){
+if((_24.sizeActual-_24.sizeMin)>_23){
+_24.sizeActual=_24.sizeActual-_23;
+_23=0;
+}else{
+_23-=_24.sizeActual-_24.sizeMin;
+_24.sizeActual=_24.sizeMin;
+}
+}
+}
+return _23;
+},_checkSizes:function(){
+var _25=0;
+var _26=0;
+var _27=this.getChildren();
+dojo.forEach(_27,function(_28){
+_26+=_28.sizeActual;
+_25+=_28.sizeMin;
+});
+if(_25<=_26){
+var _29=0;
+dojo.forEach(_27,function(_2a){
+if(_2a.sizeActual<_2a.sizeMin){
+_29+=_2a.sizeMin-_2a.sizeActual;
+_2a.sizeActual=_2a.sizeMin;
+}
+});
+if(_29>0){
+var _2b=this.isDraggingLeft?_27.reverse():_27;
+dojo.forEach(_2b,function(_2c){
+_29=this._growPane(_29,_2c);
+},this);
+}
+}else{
+dojo.forEach(_27,function(_2d){
+_2d.sizeActual=Math.round(_26*(_2d.sizeMin/_25));
+});
+}
+},beginSizing:function(e,i){
+var _30=this.getChildren();
+this.paneBefore=_30[i];
+this.paneAfter=_30[i+1];
+this.isSizing=true;
+this.sizingSplitter=this.sizers[i];
+if(!this.cover){
+this.cover=dojo.create("div",{style:{position:"absolute",zIndex:5,top:0,left:0,width:"100%",height:"100%"}},this.domNode);
+}else{
+this.cover.style.zIndex=5;
+}
+this.sizingSplitter.style.zIndex=6;
+this.originPos=dojo.coords(_30[0].domNode,true);
+if(this.isHorizontal){
+var _31=e.layerX||e.offsetX||0;
+var _32=e.pageX;
+this.originPos=this.originPos.x;
+}else{
+var _31=e.layerY||e.offsetY||0;
+var _32=e.pageY;
+this.originPos=this.originPos.y;
+}
+this.startPoint=this.lastPoint=_32;
+this.screenToClientOffset=_32-_31;
+this.dragOffset=this.lastPoint-this.paneBefore.sizeActual-this.originPos-this.paneBefore.position;
+if(!this.activeSizing){
+this._showSizingLine();
+}
+this._ownconnects=[];
+this._ownconnects.push(dojo.connect(dojo.doc.documentElement,"onmousemove",this,"changeSizing"));
+this._ownconnects.push(dojo.connect(dojo.doc.documentElement,"onmouseup",this,"endSizing"));
+dojo.stopEvent(e);
+},changeSizing:function(e){
+if(!this.isSizing){
+return;
+}
+this.lastPoint=this.isHorizontal?e.pageX:e.pageY;
+this.movePoint();
+if(this.activeSizing){
+this._updateSize();
+}else{
+this._moveSizingLine();
+}
+dojo.stopEvent(e);
+},endSizing:function(e){
+if(!this.isSizing){
+return;
+}
+if(this.cover){
+this.cover.style.zIndex=-1;
+}
+if(!this.activeSizing){
+this._hideSizingLine();
+}
+this._updateSize();
+this.isSizing=false;
+if(this.persist){
+this._saveState(this);
+}
+dojo.forEach(this._ownconnects,dojo.disconnect);
+},movePoint:function(){
+var p=this.lastPoint-this.screenToClientOffset;
+var a=p-this.dragOffset;
+a=this.legaliseSplitPoint(a);
+p=a+this.dragOffset;
+this.lastPoint=p+this.screenToClientOffset;
+},legaliseSplitPoint:function(a){
+a+=this.sizingSplitter.position;
+this.isDraggingLeft=!!(a>0);
+if(!this.activeSizing){
+var min=this.paneBefore.position+this.paneBefore.sizeMin;
+if(a<min){
+a=min;
+}
+var max=this.paneAfter.position+(this.paneAfter.sizeActual-(this.sizerWidth+this.paneAfter.sizeMin));
+if(a>max){
+a=max;
+}
+}
+a-=this.sizingSplitter.position;
+this._checkSizes();
+return a;
+},_updateSize:function(){
+var pos=this.lastPoint-this.dragOffset-this.originPos;
+var _3b=this.paneBefore.position;
+var _3c=this.paneAfter.position+this.paneAfter.sizeActual;
+this.paneBefore.sizeActual=pos-_3b;
+this.paneAfter.position=pos+this.sizerWidth;
+this.paneAfter.sizeActual=_3c-this.paneAfter.position;
+dojo.forEach(this.getChildren(),function(_3d){
+_3d.sizeShare=_3d.sizeActual;
+});
+if(this._started){
+this.layout();
+}
+},_showSizingLine:function(){
+this._moveSizingLine();
+dojo.marginBox(this.virtualSizer,this.isHorizontal?{w:this.sizerWidth,h:this.paneHeight}:{w:this.paneWidth,h:this.sizerWidth});
+this.virtualSizer.style.display="block";
+},_hideSizingLine:function(){
+this.virtualSizer.style.display="none";
+},_moveSizingLine:function(){
+var pos=(this.lastPoint-this.startPoint)+this.sizingSplitter.position;
+dojo.style(this.virtualSizer,(this.isHorizontal?"left":"top"),pos+"px");
+},_getCookieName:function(i){
+return this.id+"_"+i;
+},_restoreState:function(){
+dojo.forEach(this.getChildren(),function(_40,i){
+var _42=this._getCookieName(i);
+var _43=dojo.cookie(_42);
+if(_43){
+var pos=parseInt(_43);
+if(typeof pos=="number"){
+_40.sizeShare=pos;
+}
+}
+},this);
+},_saveState:function(){
+if(!this.persist){
+return;
+}
+dojo.forEach(this.getChildren(),function(_45,i){
+dojo.cookie(this._getCookieName(i),_45.sizeShare,{expires:365});
+},this);
+}});
+dojo.extend(dijit._Widget,{sizeMin:10,sizeShare:10});
+}
diff --git a/dijit/layout/StackContainer.js b/dijit/layout/StackContainer.js
new file mode 100644
index 0000000..6cf1f1f
--- /dev/null
+++ b/dijit/layout/StackContainer.js
@@ -0,0 +1,147 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.layout.StackContainer"]){
+dojo._hasResource["dijit.layout.StackContainer"]=true;
+dojo.provide("dijit.layout.StackContainer");
+dojo.require("dijit._Templated");
+dojo.require("dijit.layout._LayoutWidget");
+dojo.requireLocalization("dijit","common",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.require("dojo.cookie");
+dojo.declare("dijit.layout.StackContainer",dijit.layout._LayoutWidget,{doLayout:true,persist:false,baseClass:"dijitStackContainer",_started:false,postCreate:function(){
+this.inherited(arguments);
+dojo.addClass(this.domNode,"dijitLayoutContainer");
+dijit.setWaiRole(this.containerNode,"tabpanel");
+this.connect(this.domNode,"onkeypress",this._onKeyPress);
+},startup:function(){
+if(this._started){
+return;
+}
+var _1=this.getChildren();
+dojo.forEach(_1,this._setupChild,this);
+if(this.persist){
+this.selectedChildWidget=dijit.byId(dojo.cookie(this.id+"_selectedChild"));
+}else{
+dojo.some(_1,function(_2){
+if(_2.selected){
+this.selectedChildWidget=_2;
+}
+return _2.selected;
+},this);
+}
+var _3=this.selectedChildWidget;
+if(!_3&&_1[0]){
+_3=this.selectedChildWidget=_1[0];
+_3.selected=true;
+}
+dojo.publish(this.id+"-startup",[{children:_1,selected:_3}]);
+if(_3){
+this._showChild(_3);
+}
+this.inherited(arguments);
+},_setupChild:function(_4){
+this.inherited(arguments);
+dojo.removeClass(_4.domNode,"dijitVisible");
+dojo.addClass(_4.domNode,"dijitHidden");
+_4.domNode.title="";
+return _4;
+},addChild:function(_5,_6){
+this.inherited(arguments);
+if(this._started){
+dojo.publish(this.id+"-addChild",[_5,_6]);
+this.layout();
+if(!this.selectedChildWidget){
+this.selectChild(_5);
+}
+}
+},removeChild:function(_7){
+this.inherited(arguments);
+if(this._beingDestroyed){
+return;
+}
+if(this._started){
+dojo.publish(this.id+"-removeChild",[_7]);
+this.layout();
+}
+if(this.selectedChildWidget===_7){
+this.selectedChildWidget=undefined;
+if(this._started){
+var _8=this.getChildren();
+if(_8.length){
+this.selectChild(_8[0]);
+}
+}
+}
+},selectChild:function(_9){
+_9=dijit.byId(_9);
+if(this.selectedChildWidget!=_9){
+this._transition(_9,this.selectedChildWidget);
+this.selectedChildWidget=_9;
+dojo.publish(this.id+"-selectChild",[_9]);
+if(this.persist){
+dojo.cookie(this.id+"_selectedChild",this.selectedChildWidget.id);
+}
+}
+},_transition:function(_a,_b){
+if(_b){
+this._hideChild(_b);
+}
+this._showChild(_a);
+if(this.doLayout&&_a.resize){
+_a.resize(this._containerContentBox||this._contentBox);
+}
+},_adjacent:function(_c){
+var _d=this.getChildren();
+var _e=dojo.indexOf(_d,this.selectedChildWidget);
+_e+=_c?1:_d.length-1;
+return _d[_e%_d.length];
+},forward:function(){
+this.selectChild(this._adjacent(true));
+},back:function(){
+this.selectChild(this._adjacent(false));
+},_onKeyPress:function(e){
+dojo.publish(this.id+"-containerKeyPress",[{e:e,page:this}]);
+},layout:function(){
+if(this.doLayout&&this.selectedChildWidget&&this.selectedChildWidget.resize){
+this.selectedChildWidget.resize(this._contentBox);
+}
+},_showChild:function(_10){
+var _11=this.getChildren();
+_10.isFirstChild=(_10==_11[0]);
+_10.isLastChild=(_10==_11[_11.length-1]);
+_10.selected=true;
+dojo.removeClass(_10.domNode,"dijitHidden");
+dojo.addClass(_10.domNode,"dijitVisible");
+if(_10._onShow){
+_10._onShow();
+}else{
+if(_10.onShow){
+_10.onShow();
+}
+}
+},_hideChild:function(_12){
+_12.selected=false;
+dojo.removeClass(_12.domNode,"dijitVisible");
+dojo.addClass(_12.domNode,"dijitHidden");
+if(_12.onHide){
+_12.onHide();
+}
+},closeChild:function(_13){
+var _14=_13.onClose(this,_13);
+if(_14){
+this.removeChild(_13);
+_13.destroyRecursive();
+}
+},destroy:function(){
+this._beingDestroyed=true;
+this.inherited(arguments);
+}});
+dojo.require("dijit.layout.StackController");
+dojo.extend(dijit._Widget,{title:"",selected:false,closable:false,onClose:function(){
+return true;
+}});
+}
diff --git a/dijit/layout/StackController.js b/dijit/layout/StackController.js
new file mode 100644
index 0000000..c9e8fe2
--- /dev/null
+++ b/dijit/layout/StackController.js
@@ -0,0 +1,176 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.layout.StackController"]){
+dojo._hasResource["dijit.layout.StackController"]=true;
+dojo.provide("dijit.layout.StackController");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dijit._Container");
+dojo.require("dijit.form.ToggleButton");
+dojo.require("dijit.Menu");
+dojo.requireLocalization("dijit","common",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.declare("dijit.layout.StackController",[dijit._Widget,dijit._Templated,dijit._Container],{templateString:"<span wairole='tablist' dojoAttachEvent='onkeypress' class='dijitStackController'></span>",containerId:"",buttonWidget:"dijit.layout._StackButton",postCreate:function(){
+dijit.setWaiRole(this.domNode,"tablist");
+this.pane2button={};
+this.pane2handles={};
+this.pane2menu={};
+this._subscriptions=[dojo.subscribe(this.containerId+"-startup",this,"onStartup"),dojo.subscribe(this.containerId+"-addChild",this,"onAddChild"),dojo.subscribe(this.containerId+"-removeChild",this,"onRemoveChild"),dojo.subscribe(this.containerId+"-selectChild",this,"onSelectChild"),dojo.subscribe(this.containerId+"-containerKeyPress",this,"onContainerKeyPress")];
+},onStartup:function(_1){
+dojo.forEach(_1.children,this.onAddChild,this);
+this.onSelectChild(_1.selected);
+},destroy:function(){
+for(var _2 in this.pane2button){
+this.onRemoveChild(_2);
+}
+dojo.forEach(this._subscriptions,dojo.unsubscribe);
+this.inherited(arguments);
+},onAddChild:function(_3,_4){
+var _5=dojo.doc.createElement("span");
+this.domNode.appendChild(_5);
+var _6=dojo.getObject(this.buttonWidget);
+var _7=new _6({label:_3.title,closeButton:_3.closable},_5);
+this.addChild(_7,_4);
+this.pane2button[_3]=_7;
+_3.controlButton=_7;
+var _8=[];
+_8.push(dojo.connect(_7,"onClick",dojo.hitch(this,"onButtonClick",_3)));
+if(_3.closable){
+_8.push(dojo.connect(_7,"onClickCloseButton",dojo.hitch(this,"onCloseButtonClick",_3)));
+var _9=dojo.i18n.getLocalization("dijit","common");
+var _a=new dijit.Menu({targetNodeIds:[_7.id],id:_7.id+"_Menu"});
+var _b=new dijit.MenuItem({label:_9.itemClose});
+_8.push(dojo.connect(_b,"onClick",dojo.hitch(this,"onCloseButtonClick",_3)));
+_a.addChild(_b);
+this.pane2menu[_3]=_a;
+}
+this.pane2handles[_3]=_8;
+if(!this._currentChild){
+_7.focusNode.setAttribute("tabIndex","0");
+this._currentChild=_3;
+}
+if(!this.isLeftToRight()&&dojo.isIE&&this._rectifyRtlTabList){
+this._rectifyRtlTabList();
+}
+},onRemoveChild:function(_c){
+if(this._currentChild===_c){
+this._currentChild=null;
+}
+dojo.forEach(this.pane2handles[_c],dojo.disconnect);
+delete this.pane2handles[_c];
+var _d=this.pane2menu[_c];
+if(_d){
+_d.destroyRecursive();
+delete this.pane2menu[_c];
+}
+var _e=this.pane2button[_c];
+if(_e){
+_e.destroy();
+delete this.pane2button[_c];
+}
+},onSelectChild:function(_f){
+if(!_f){
+return;
+}
+if(this._currentChild){
+var _10=this.pane2button[this._currentChild];
+_10.attr("checked",false);
+_10.focusNode.setAttribute("tabIndex","-1");
+}
+var _11=this.pane2button[_f];
+_11.attr("checked",true);
+this._currentChild=_f;
+_11.focusNode.setAttribute("tabIndex","0");
+var _12=dijit.byId(this.containerId);
+dijit.setWaiState(_12.containerNode,"labelledby",_11.id);
+},onButtonClick:function(_13){
+var _14=dijit.byId(this.containerId);
+_14.selectChild(_13);
+},onCloseButtonClick:function(_15){
+var _16=dijit.byId(this.containerId);
+_16.closeChild(_15);
+var b=this.pane2button[this._currentChild];
+if(b){
+dijit.focus(b.focusNode||b.domNode);
+}
+},adjacent:function(_18){
+if(!this.isLeftToRight()&&(!this.tabPosition||/top|bottom/.test(this.tabPosition))){
+_18=!_18;
+}
+var _19=this.getChildren();
+var _1a=dojo.indexOf(_19,this.pane2button[this._currentChild]);
+var _1b=_18?1:_19.length-1;
+return _19[(_1a+_1b)%_19.length];
+},onkeypress:function(e){
+if(this.disabled||e.altKey){
+return;
+}
+var _1d=null;
+if(e.ctrlKey||!e._djpage){
+var k=dojo.keys;
+switch(e.charOrCode){
+case k.LEFT_ARROW:
+case k.UP_ARROW:
+if(!e._djpage){
+_1d=false;
+}
+break;
+case k.PAGE_UP:
+if(e.ctrlKey){
+_1d=false;
+}
+break;
+case k.RIGHT_ARROW:
+case k.DOWN_ARROW:
+if(!e._djpage){
+_1d=true;
+}
+break;
+case k.PAGE_DOWN:
+if(e.ctrlKey){
+_1d=true;
+}
+break;
+case k.DELETE:
+if(this._currentChild.closable){
+this.onCloseButtonClick(this._currentChild);
+}
+dojo.stopEvent(e);
+break;
+default:
+if(e.ctrlKey){
+if(e.charOrCode===k.TAB){
+this.adjacent(!e.shiftKey).onClick();
+dojo.stopEvent(e);
+}else{
+if(e.charOrCode=="w"){
+if(this._currentChild.closable){
+this.onCloseButtonClick(this._currentChild);
+}
+dojo.stopEvent(e);
+}
+}
+}
+}
+if(_1d!==null){
+this.adjacent(_1d).onClick();
+dojo.stopEvent(e);
+}
+}
+},onContainerKeyPress:function(_1f){
+_1f.e._djpage=_1f.page;
+this.onkeypress(_1f.e);
+}});
+dojo.declare("dijit.layout._StackButton",dijit.form.ToggleButton,{tabIndex:"-1",postCreate:function(evt){
+dijit.setWaiRole((this.focusNode||this.domNode),"tab");
+this.inherited(arguments);
+},onClick:function(evt){
+dijit.focus(this.focusNode);
+},onClickCloseButton:function(evt){
+evt.stopPropagation();
+}});
+}
diff --git a/dijit/layout/TabContainer.js b/dijit/layout/TabContainer.js
new file mode 100644
index 0000000..7f7164c
--- /dev/null
+++ b/dijit/layout/TabContainer.js
@@ -0,0 +1,63 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.layout.TabContainer"]){
+dojo._hasResource["dijit.layout.TabContainer"]=true;
+dojo.provide("dijit.layout.TabContainer");
+dojo.require("dijit.layout.StackContainer");
+dojo.require("dijit._Templated");
+dojo.require("dijit.layout.TabController");
+dojo.declare("dijit.layout.TabContainer",[dijit.layout.StackContainer,dijit._Templated],{tabPosition:"top",baseClass:"dijitTabContainer",tabStrip:false,nested:false,templateString:null,templateString:"<div class=\"dijitTabContainer\">\n\t<div dojoAttachPoint=\"tablistNode\"></div>\n\t<div dojoAttachPoint=\"tablistSpacer\" class=\"dijitTabSpacer ${baseClass}-spacer\"></div>\n\t<div class=\"dijitTabPaneWrapper ${baseClass}-container\" dojoAttachPoint=\"containerNode\"></div>\n</div>\n",_co [...]
+this.baseClass+=this.tabPosition.charAt(0).toUpperCase()+this.tabPosition.substr(1).replace(/-.*/,"");
+this.inherited(arguments);
+},postCreate:function(){
+this.inherited(arguments);
+var _1=dojo.getObject(this._controllerWidget);
+this.tablist=new _1({id:this.id+"_tablist",tabPosition:this.tabPosition,doLayout:this.doLayout,containerId:this.id,"class":this.baseClass+"-tabs"+(this.doLayout?"":" dijitTabNoLayout")},this.tablistNode);
+if(this.tabStrip){
+dojo.addClass(this.tablist.domNode,this.baseClass+"Strip");
+}
+if(!this.doLayout){
+dojo.addClass(this.domNode,"dijitTabContainerNoLayout");
+}
+if(this.nested){
+dojo.addClass(this.domNode,"dijitTabContainerNested");
+dojo.addClass(this.tablist.domNode,"dijitTabContainerTabListNested");
+dojo.addClass(this.tablistSpacer,"dijitTabContainerSpacerNested");
+dojo.addClass(this.containerNode,"dijitTabPaneWrapperNested");
+}
+},_setupChild:function(_2){
+dojo.addClass(_2.domNode,"dijitTabPane");
+this.inherited(arguments);
+return _2;
+},startup:function(){
+if(this._started){
+return;
+}
+this.tablist.startup();
+this.inherited(arguments);
+},layout:function(){
+if(!this.doLayout){
+return;
+}
+var _3=this.tabPosition.replace(/-h/,"");
+var _4=[{domNode:this.tablist.domNode,layoutAlign:_3},{domNode:this.tablistSpacer,layoutAlign:_3},{domNode:this.containerNode,layoutAlign:"client"}];
+dijit.layout.layoutChildren(this.domNode,this._contentBox,_4);
+this._containerContentBox=dijit.layout.marginBox2contentBox(this.containerNode,_4[2]);
+if(this.selectedChildWidget){
+this._showChild(this.selectedChildWidget);
+if(this.doLayout&&this.selectedChildWidget.resize){
+this.selectedChildWidget.resize(this._containerContentBox);
+}
+}
+},destroy:function(){
+if(this.tablist){
+this.tablist.destroy();
+}
+this.inherited(arguments);
+}});
+}
diff --git a/dijit/layout/TabController.js b/dijit/layout/TabController.js
new file mode 100644
index 0000000..99ca9b6
--- /dev/null
+++ b/dijit/layout/TabController.js
@@ -0,0 +1,47 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.layout.TabController"]){
+dojo._hasResource["dijit.layout.TabController"]=true;
+dojo.provide("dijit.layout.TabController");
+dojo.require("dijit.layout.StackController");
+dojo.requireLocalization("dijit","common",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.declare("dijit.layout.TabController",dijit.layout.StackController,{templateString:"<div wairole='tablist' dojoAttachEvent='onkeypress:onkeypress'></div>",tabPosition:"top",doLayout:true,buttonWidget:"dijit.layout._TabButton",_rectifyRtlTabList:function(){
+if(0>=this.tabPosition.indexOf("-h")){
+return;
+}
+if(!this.pane2button){
+return;
+}
+var _1=0;
+for(var _2 in this.pane2button){
+var ow=this.pane2button[_2].innerDiv.scrollWidth;
+_1=Math.max(_1,ow);
+}
+for(_2 in this.pane2button){
+this.pane2button[_2].innerDiv.style.width=_1+"px";
+}
+}});
+dojo.declare("dijit.layout._TabButton",dijit.layout._StackButton,{baseClass:"dijitTab",templateString:"<div waiRole=\"presentation\" dojoAttachEvent='onclick:onClick,onmouseenter:_onMouse,onmouseleave:_onMouse'>\n    <div waiRole=\"presentation\" class='dijitTabInnerDiv' dojoAttachPoint='innerDiv'>\n        <div waiRole=\"presentation\" class='dijitTabContent' dojoAttachPoint='tabContent'>\n\t        <span dojoAttachPoint='containerNode,focusNode' class='tabLabel'>${!label}</span><img cl [...]
+if(this.closeButton){
+dojo.addClass(this.innerDiv,"dijitClosable");
+var _4=dojo.i18n.getLocalization("dijit","common");
+if(this.closeNode){
+dojo.attr(this.closeNode,"title",_4.itemClose);
+dojo.attr(this.closeIcon,"title",_4.itemClose);
+}
+}else{
+this.closeNode.style.display="none";
+}
+this.inherited(arguments);
+dojo.setSelectable(this.containerNode,false);
+},_onCloseButtonEnter:function(){
+dojo.addClass(this.closeNode,"closeButton-hover");
+},_onCloseButtonLeave:function(){
+dojo.removeClass(this.closeNode,"closeButton-hover");
+}});
+}
diff --git a/dijit/layout/_LayoutWidget.js b/dijit/layout/_LayoutWidget.js
new file mode 100644
index 0000000..6578ef0
--- /dev/null
+++ b/dijit/layout/_LayoutWidget.js
@@ -0,0 +1,133 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.layout._LayoutWidget"]){
+dojo._hasResource["dijit.layout._LayoutWidget"]=true;
+dojo.provide("dijit.layout._LayoutWidget");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Container");
+dojo.require("dijit._Contained");
+dojo.declare("dijit.layout._LayoutWidget",[dijit._Widget,dijit._Container,dijit._Contained],{baseClass:"dijitLayoutContainer",isLayoutContainer:true,postCreate:function(){
+dojo.addClass(this.domNode,"dijitContainer");
+dojo.addClass(this.domNode,this.baseClass);
+},startup:function(){
+if(this._started){
+return;
+}
+dojo.forEach(this.getChildren(),function(_1){
+_1.startup();
+});
+if(!this.getParent||!this.getParent()){
+this.resize();
+this._viewport=dijit.getViewport();
+this.connect(dojo.global,"onresize",function(){
+var _2=dijit.getViewport();
+if(_2.w!=this._viewport.w||_2.h!=this._viewport.h){
+this._viewport=_2;
+this.resize();
+}
+});
+}
+this.inherited(arguments);
+},resize:function(_3,_4){
+var _5=this.domNode;
+if(_3){
+dojo.marginBox(_5,_3);
+if(_3.t){
+_5.style.top=_3.t+"px";
+}
+if(_3.l){
+_5.style.left=_3.l+"px";
+}
+}
+var mb=_4||{};
+dojo.mixin(mb,_3||{});
+if(!("h" in mb)||!("w" in mb)){
+mb=dojo.mixin(dojo.marginBox(_5),mb);
+}
+var cs=dojo.getComputedStyle(_5);
+var me=dojo._getMarginExtents(_5,cs);
+var be=dojo._getBorderExtents(_5,cs);
+var bb=(this._borderBox={w:mb.w-(me.w+be.w),h:mb.h-(me.h+be.h)});
+var pe=dojo._getPadExtents(_5,cs);
+this._contentBox={l:dojo._toPixelValue(_5,cs.paddingLeft),t:dojo._toPixelValue(_5,cs.paddingTop),w:bb.w-pe.w,h:bb.h-pe.h};
+this.layout();
+},layout:function(){
+},_setupChild:function(_c){
+dojo.addClass(_c.domNode,this.baseClass+"-child");
+if(_c.baseClass){
+dojo.addClass(_c.domNode,this.baseClass+"-"+_c.baseClass);
+}
+},addChild:function(_d,_e){
+this.inherited(arguments);
+if(this._started){
+this._setupChild(_d);
+}
+},removeChild:function(_f){
+dojo.removeClass(_f.domNode,this.baseClass+"-child");
+if(_f.baseClass){
+dojo.removeClass(_f.domNode,this.baseClass+"-"+_f.baseClass);
+}
+this.inherited(arguments);
+}});
+dijit.layout.marginBox2contentBox=function(_10,mb){
+var cs=dojo.getComputedStyle(_10);
+var me=dojo._getMarginExtents(_10,cs);
+var pb=dojo._getPadBorderExtents(_10,cs);
+return {l:dojo._toPixelValue(_10,cs.paddingLeft),t:dojo._toPixelValue(_10,cs.paddingTop),w:mb.w-(me.w+pb.w),h:mb.h-(me.h+pb.h)};
+};
+(function(){
+var _15=function(_16){
+return _16.substring(0,1).toUpperCase()+_16.substring(1);
+};
+var _17=function(_18,dim){
+_18.resize?_18.resize(dim):dojo.marginBox(_18.domNode,dim);
+dojo.mixin(_18,dojo.marginBox(_18.domNode));
+dojo.mixin(_18,dim);
+};
+dijit.layout.layoutChildren=function(_1a,dim,_1c){
+dim=dojo.mixin({},dim);
+dojo.addClass(_1a,"dijitLayoutContainer");
+_1c=dojo.filter(_1c,function(_1d){
+return _1d.layoutAlign!="client";
+}).concat(dojo.filter(_1c,function(_1e){
+return _1e.layoutAlign=="client";
+}));
+dojo.forEach(_1c,function(_1f){
+var elm=_1f.domNode,pos=_1f.layoutAlign;
+var _22=elm.style;
+_22.left=dim.l+"px";
+_22.top=dim.t+"px";
+_22.bottom=_22.right="auto";
+dojo.addClass(elm,"dijitAlign"+_15(pos));
+if(pos=="top"||pos=="bottom"){
+_17(_1f,{w:dim.w});
+dim.h-=_1f.h;
+if(pos=="top"){
+dim.t+=_1f.h;
+}else{
+_22.top=dim.t+dim.h+"px";
+}
+}else{
+if(pos=="left"||pos=="right"){
+_17(_1f,{h:dim.h});
+dim.w-=_1f.w;
+if(pos=="left"){
+dim.l+=_1f.w;
+}else{
+_22.left=dim.l+dim.w+"px";
+}
+}else{
+if(pos=="client"){
+_17(_1f,dim);
+}
+}
+}
+});
+};
+})();
+}
diff --git a/dijit/nls/ar/common.js b/dijit/nls/ar/common.js
new file mode 100644
index 0000000..99af508
--- /dev/null
+++ b/dijit/nls/ar/common.js
@@ -0,0 +1 @@
+({"buttonOk":"حسنا","buttonCancel":"الغاء","buttonSave":"حفظ","itemClose":"اغلاق"})
\ No newline at end of file
diff --git a/dijit/nls/ar/loading.js b/dijit/nls/ar/loading.js
new file mode 100644
index 0000000..f8bb535
--- /dev/null
+++ b/dijit/nls/ar/loading.js
@@ -0,0 +1 @@
+({"loadingState":"جاري التحميل...","errorState":"عفوا، حدث خطأ"})
\ No newline at end of file
diff --git a/dijit/nls/ca/common.js b/dijit/nls/ca/common.js
new file mode 100644
index 0000000..b9cd065
--- /dev/null
+++ b/dijit/nls/ca/common.js
@@ -0,0 +1 @@
+({"buttonOk":"D'acord","buttonCancel":"Cancel·la","buttonSave":"Desa","itemClose":"Tanca"})
\ No newline at end of file
diff --git a/dijit/nls/ca/loading.js b/dijit/nls/ca/loading.js
new file mode 100644
index 0000000..cd368cc
--- /dev/null
+++ b/dijit/nls/ca/loading.js
@@ -0,0 +1 @@
+({"loadingState":"S'està carregant...","errorState":"Ens sap greu. S'ha produït un error."})
\ No newline at end of file
diff --git a/dijit/nls/common.js b/dijit/nls/common.js
new file mode 100644
index 0000000..6573dcd
--- /dev/null
+++ b/dijit/nls/common.js
@@ -0,0 +1 @@
+({"buttonOk":"OK","buttonCancel":"Cancel","buttonSave":"Save","itemClose":"Close"})
\ No newline at end of file
diff --git a/dijit/nls/cs/common.js b/dijit/nls/cs/common.js
new file mode 100644
index 0000000..83b3682
--- /dev/null
+++ b/dijit/nls/cs/common.js
@@ -0,0 +1 @@
+({"buttonOk":"OK","buttonCancel":"Storno","buttonSave":"Uložit","itemClose":"Zavřít"})
\ No newline at end of file
diff --git a/dijit/nls/cs/loading.js b/dijit/nls/cs/loading.js
new file mode 100644
index 0000000..c611926
--- /dev/null
+++ b/dijit/nls/cs/loading.js
@@ -0,0 +1 @@
+({"loadingState":"Probíhá načítání...","errorState":"Omlouváme se, došlo k chybě"})
\ No newline at end of file
diff --git a/dijit/nls/da/common.js b/dijit/nls/da/common.js
new file mode 100644
index 0000000..8c51ed8
--- /dev/null
+++ b/dijit/nls/da/common.js
@@ -0,0 +1 @@
+({"buttonOk":"OK","buttonCancel":"Annullér","buttonSave":"Gem","itemClose":"Luk"})
\ No newline at end of file
diff --git a/dijit/nls/da/loading.js b/dijit/nls/da/loading.js
new file mode 100644
index 0000000..5088eaf
--- /dev/null
+++ b/dijit/nls/da/loading.js
@@ -0,0 +1 @@
+({"loadingState":"Indlæser...","errorState":"Der er opstået en fejl"})
\ No newline at end of file
diff --git a/dijit/nls/de/common.js b/dijit/nls/de/common.js
new file mode 100644
index 0000000..cd60c45
--- /dev/null
+++ b/dijit/nls/de/common.js
@@ -0,0 +1 @@
+({"buttonOk":"OK","buttonCancel":"Abbrechen","buttonSave":"Speichern","itemClose":"Schließen"})
\ No newline at end of file
diff --git a/dijit/nls/de/loading.js b/dijit/nls/de/loading.js
new file mode 100644
index 0000000..4989983
--- /dev/null
+++ b/dijit/nls/de/loading.js
@@ -0,0 +1 @@
+({"loadingState":"Wird geladen...","errorState":"Es ist ein Fehler aufgetreten."})
\ No newline at end of file
diff --git a/dijit/nls/dijit-all_ROOT.js b/dijit/nls/dijit-all_ROOT.js
new file mode 100644
index 0000000..bcd917c
--- /dev/null
+++ b/dijit/nls/dijit-all_ROOT.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_ROOT");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.ROOT");dojo.nls.colors.ROOT={"lightsteelblue":"light steel blue","orangered":"orange red","midnightblue":"midnight blue","cadetblue":"cadet blue","seashell":"seashell","slategrey":"slate gray","coral":"coral","darkturquoise":"dark turquoise","antiquewhite":"antique white","mediumspringgreen":"medium spring green","salmon":"salmon","darkgrey":"dark gray","ivor [...]
diff --git a/dijit/nls/dijit-all_ar.js b/dijit/nls/dijit-all_ar.js
new file mode 100644
index 0000000..011eb18
--- /dev/null
+++ b/dijit/nls/dijit-all_ar.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_ar");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.ar");dojo.nls.colors.ar={"lightsteelblue":"أزرق معدني فاتح","orangered":"أحمر مائل للبرتقالي","midnightblue":"أزرق بحري","cadetblue":"أزرق ملون بالرمادي","seashell":"أبيض مائل للأصفر فاتح","slategrey":"رمادي اردوازي","coral":"مرجاني","darkturquoise":"تركواز داكن","antiquewhite":"أبيض عتيق","mediumspringgreen":"أخضر ربيعي متوسط","salmon":"برتقالي وردي شاحب","dar [...]
diff --git a/dijit/nls/dijit-all_ca.js b/dijit/nls/dijit-all_ca.js
new file mode 100644
index 0000000..f86c2ce
--- /dev/null
+++ b/dijit/nls/dijit-all_ca.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_ca");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.ca");dojo.nls.colors.ca={"lightsteelblue":"blau acer clar","orangered":"taronja vermellós","midnightblue":"blau mitjanit","cadetblue":"blau marí","seashell":"petxina marina","slategrey":"gris pissarra","coral":"corall","darkturquoise":"turquesa fosc","antiquewhite":"blanc antic","mediumspringgreen":"verd primavera mitjà","salmon":"salmó","darkgrey":"gris fosc", [...]
diff --git a/dijit/nls/dijit-all_cs.js b/dijit/nls/dijit-all_cs.js
new file mode 100644
index 0000000..99e49f2
--- /dev/null
+++ b/dijit/nls/dijit-all_cs.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_cs");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.cs");dojo.nls.colors.cs={"lightsteelblue":"světlá ocelová modrá","orangered":"oranžovočervená","midnightblue":"temně modrá","cadetblue":"šedomodrá","seashell":"lasturová","slategrey":"břidlicová šedá","coral":"korálová červená","darkturquoise":"tmavě tyrkysová","antiquewhite":"krémově bílá","mediumspringgreen":"střední jarní zelená","salmon":"lososová","darkgre [...]
diff --git a/dijit/nls/dijit-all_da.js b/dijit/nls/dijit-all_da.js
new file mode 100644
index 0000000..9060c8a
--- /dev/null
+++ b/dijit/nls/dijit-all_da.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_da");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.da");dojo.nls.colors.da={"lightsteelblue":"lys stålblå","orangered":"orangerød","midnightblue":"midnatsblå","cadetblue":"kadetblå","seashell":"muslingeskal","slategrey":"skifergrå","coral":"koralrød","darkturquoise":"mørk turkis","antiquewhite":"antikhvid","mediumspringgreen":"mellemforårsgrøn","salmon":"laksefarvet","darkgrey":"mørkegrå","ivory":"elfenben","gr [...]
diff --git a/dijit/nls/dijit-all_de-de.js b/dijit/nls/dijit-all_de-de.js
new file mode 100644
index 0000000..997f731
--- /dev/null
+++ b/dijit/nls/dijit-all_de-de.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_de-de");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.de_de");dojo.nls.colors.de_de={"lightsteelblue":"Helles Stahlblau","orangered":"Orangerot","midnightblue":"Mitternachtblau","cadetblue":"Kadettenblau","seashell":"Muschelweiß","slategrey":"Schiefergrau","coral":"Koralle","darkturquoise":"Dunkeltürkis","antiquewhite":"Antikweiß","mediumspringgreen":"Mittelfrühlingsgrün","salmon":"Lachs","darkgrey":"Dunkelgrau [...]
diff --git a/dijit/nls/dijit-all_de.js b/dijit/nls/dijit-all_de.js
new file mode 100644
index 0000000..02b6ac7
--- /dev/null
+++ b/dijit/nls/dijit-all_de.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_de");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.de");dojo.nls.colors.de={"lightsteelblue":"Helles Stahlblau","orangered":"Orangerot","midnightblue":"Mitternachtblau","cadetblue":"Kadettenblau","seashell":"Muschelweiß","slategrey":"Schiefergrau","coral":"Koralle","darkturquoise":"Dunkeltürkis","antiquewhite":"Antikweiß","mediumspringgreen":"Mittelfrühlingsgrün","salmon":"Lachs","darkgrey":"Dunkelgrau","ivory" [...]
diff --git a/dijit/nls/dijit-all_el.js b/dijit/nls/dijit-all_el.js
new file mode 100644
index 0000000..b302916
--- /dev/null
+++ b/dijit/nls/dijit-all_el.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_el");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.el");dojo.nls.colors.el={"lightsteelblue":"ανοιχτό μπλε ατσαλιού","orangered":"πορτοκαλοκόκκινο","midnightblue":"πολύ σκούρο μπλε","cadetblue":"μπλε του στρατού","seashell":"κοχύλι","slategrey":"μεταλλικό γκρι","coral":"κοραλί","darkturquoise":"σκούρο τυρκουάζ","antiquewhite":"ξεθωριασμένο λευκό","mediumspringgreen":"μεσαίο πράσινο της άνοιξης","salmon":"σομόν" [...]
diff --git a/dijit/nls/dijit-all_en-gb.js b/dijit/nls/dijit-all_en-gb.js
new file mode 100644
index 0000000..1a0f9d4
--- /dev/null
+++ b/dijit/nls/dijit-all_en-gb.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_en-gb");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.en_gb");dojo.nls.colors.en_gb={"lightsteelblue":"light steel blue","orangered":"orange red","midnightblue":"midnight blue","cadetblue":"cadet blue","seashell":"seashell","slategrey":"slate gray","coral":"coral","darkturquoise":"dark turquoise","antiquewhite":"antique white","mediumspringgreen":"medium spring green","salmon":"salmon","darkgrey":"dark gray","i [...]
diff --git a/dijit/nls/dijit-all_en-us.js b/dijit/nls/dijit-all_en-us.js
new file mode 100644
index 0000000..ed5ffc9
--- /dev/null
+++ b/dijit/nls/dijit-all_en-us.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_en-us");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.en_us");dojo.nls.colors.en_us={"lightsteelblue":"light steel blue","orangered":"orange red","midnightblue":"midnight blue","cadetblue":"cadet blue","seashell":"seashell","slategrey":"slate gray","coral":"coral","darkturquoise":"dark turquoise","antiquewhite":"antique white","mediumspringgreen":"medium spring green","salmon":"salmon","darkgrey":"dark gray","i [...]
diff --git a/dijit/nls/dijit-all_en.js b/dijit/nls/dijit-all_en.js
new file mode 100644
index 0000000..cc66d39
--- /dev/null
+++ b/dijit/nls/dijit-all_en.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_en");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.en");dojo.nls.colors.en={"lightsteelblue":"light steel blue","orangered":"orange red","midnightblue":"midnight blue","cadetblue":"cadet blue","seashell":"seashell","slategrey":"slate gray","coral":"coral","darkturquoise":"dark turquoise","antiquewhite":"antique white","mediumspringgreen":"medium spring green","salmon":"salmon","darkgrey":"dark gray","ivory":"iv [...]
diff --git a/dijit/nls/dijit-all_es-es.js b/dijit/nls/dijit-all_es-es.js
new file mode 100644
index 0000000..8a4bb80
--- /dev/null
+++ b/dijit/nls/dijit-all_es-es.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_es-es");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.es_es");dojo.nls.colors.es_es={"lightsteelblue":"azul acero claro","orangered":"rojo anaranjado","midnightblue":"azul medianoche","cadetblue":"azul cadete","seashell":"blanco marfil","slategrey":"gris pizarra","coral":"coral","darkturquoise":"turquesa oscuro","antiquewhite":"blanco antiguo","mediumspringgreen":"verde primavera medio","salmon":"salmón","darkg [...]
diff --git a/dijit/nls/dijit-all_es.js b/dijit/nls/dijit-all_es.js
new file mode 100644
index 0000000..53049f1
--- /dev/null
+++ b/dijit/nls/dijit-all_es.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_es");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.es");dojo.nls.colors.es={"lightsteelblue":"azul acero claro","orangered":"rojo anaranjado","midnightblue":"azul medianoche","cadetblue":"azul cadete","seashell":"blanco marfil","slategrey":"gris pizarra","coral":"coral","darkturquoise":"turquesa oscuro","antiquewhite":"blanco antiguo","mediumspringgreen":"verde primavera medio","salmon":"salmón","darkgrey":"gri [...]
diff --git a/dijit/nls/dijit-all_fi-fi.js b/dijit/nls/dijit-all_fi-fi.js
new file mode 100644
index 0000000..55e86a1
--- /dev/null
+++ b/dijit/nls/dijit-all_fi-fi.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_fi-fi");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.fi_fi");dojo.nls.colors.fi_fi={"lightsteelblue":"light steel blue","orangered":"orange red","midnightblue":"midnight blue","cadetblue":"cadet blue","seashell":"seashell","slategrey":"slate gray","coral":"coral","darkturquoise":"dark turquoise","antiquewhite":"antique white","mediumspringgreen":"medium spring green","salmon":"salmon","darkgrey":"dark gray","i [...]
diff --git a/dijit/nls/dijit-all_fi.js b/dijit/nls/dijit-all_fi.js
new file mode 100644
index 0000000..06c13c6
--- /dev/null
+++ b/dijit/nls/dijit-all_fi.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_fi");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.fi");dojo.nls.colors.fi={"lightsteelblue":"light steel blue","orangered":"orange red","midnightblue":"midnight blue","cadetblue":"cadet blue","seashell":"seashell","slategrey":"slate gray","coral":"coral","darkturquoise":"dark turquoise","antiquewhite":"antique white","mediumspringgreen":"medium spring green","salmon":"salmon","darkgrey":"dark gray","ivory":"iv [...]
diff --git a/dijit/nls/dijit-all_fr-fr.js b/dijit/nls/dijit-all_fr-fr.js
new file mode 100644
index 0000000..c268211
--- /dev/null
+++ b/dijit/nls/dijit-all_fr-fr.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_fr-fr");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.fr_fr");dojo.nls.colors.fr_fr={"lightsteelblue":"bleu acier clair","orangered":"rouge orangé","midnightblue":"bleu nuit","cadetblue":"bleu pétrole","seashell":"coquillage","slategrey":"gris ardoise","coral":"corail","darkturquoise":"turquoise foncé","antiquewhite":"blanc antique","mediumspringgreen":"vert printemps moyen","salmon":"saumon","darkgrey":"gris f [...]
diff --git a/dijit/nls/dijit-all_fr.js b/dijit/nls/dijit-all_fr.js
new file mode 100644
index 0000000..9eff710
--- /dev/null
+++ b/dijit/nls/dijit-all_fr.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_fr");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.fr");dojo.nls.colors.fr={"lightsteelblue":"bleu acier clair","orangered":"rouge orangé","midnightblue":"bleu nuit","cadetblue":"bleu pétrole","seashell":"coquillage","slategrey":"gris ardoise","coral":"corail","darkturquoise":"turquoise foncé","antiquewhite":"blanc antique","mediumspringgreen":"vert printemps moyen","salmon":"saumon","darkgrey":"gris foncé","iv [...]
diff --git a/dijit/nls/dijit-all_he-il.js b/dijit/nls/dijit-all_he-il.js
new file mode 100644
index 0000000..e23508c
--- /dev/null
+++ b/dijit/nls/dijit-all_he-il.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_he-il");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.he_il");dojo.nls.colors.he_il={"lightsteelblue":"כחול פלדה בהיר","orangered":"כתום אדום","midnightblue":"כחול כהה","cadetblue":"כחול ים","seashell":"צדף","slategrey":"אפור צפחה","coral":"אלמוג","darkturquoise":"טורקיז כהה","antiquewhite":"לבן עתיק","mediumspringgreen":"ירוק אביב בינוני","salmon":"סלמון","darkgrey":"אפור כהה","ivory":"שנהב","greenyellow":"ירו [...]
diff --git a/dijit/nls/dijit-all_he.js b/dijit/nls/dijit-all_he.js
new file mode 100644
index 0000000..6b7eeb4
--- /dev/null
+++ b/dijit/nls/dijit-all_he.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_he");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.he");dojo.nls.colors.he={"lightsteelblue":"כחול פלדה בהיר","orangered":"כתום אדום","midnightblue":"כחול כהה","cadetblue":"כחול ים","seashell":"צדף","slategrey":"אפור צפחה","coral":"אלמוג","darkturquoise":"טורקיז כהה","antiquewhite":"לבן עתיק","mediumspringgreen":"ירוק אביב בינוני","salmon":"סלמון","darkgrey":"אפור כהה","ivory":"שנהב","greenyellow":"ירוק-צהוב"," [...]
diff --git a/dijit/nls/dijit-all_hu.js b/dijit/nls/dijit-all_hu.js
new file mode 100644
index 0000000..7af646e
--- /dev/null
+++ b/dijit/nls/dijit-all_hu.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_hu");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.hu");dojo.nls.colors.hu={"lightsteelblue":"világos acélkék","orangered":"narancsvörös","midnightblue":"éjkék","cadetblue":"kadétkék","seashell":"kagyló","slategrey":"palaszürke","coral":"korall","darkturquoise":"sötét türkizkék","antiquewhite":"antik fehér","mediumspringgreen":"közepes tavaszzöld","salmon":"lazacszín","darkgrey":"sötétszürke","ivory":"elefántcs [...]
diff --git a/dijit/nls/dijit-all_it-it.js b/dijit/nls/dijit-all_it-it.js
new file mode 100644
index 0000000..f93c817
--- /dev/null
+++ b/dijit/nls/dijit-all_it-it.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_it-it");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.it_it");dojo.nls.colors.it_it={"lightsteelblue":"blu acciao chiaro","orangered":"vermiglio","midnightblue":"blu melanzana scuro","cadetblue":"verde acqua","seashell":"sabbia rosa","slategrey":"grigio ardesia","coral":"corallo","darkturquoise":"turchese scuro","antiquewhite":"bianco antico","mediumspringgreen":"verde primavera medio","salmon":"salmone","darkg [...]
diff --git a/dijit/nls/dijit-all_it.js b/dijit/nls/dijit-all_it.js
new file mode 100644
index 0000000..52dfe92
--- /dev/null
+++ b/dijit/nls/dijit-all_it.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_it");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.it");dojo.nls.colors.it={"lightsteelblue":"blu acciao chiaro","orangered":"vermiglio","midnightblue":"blu melanzana scuro","cadetblue":"verde acqua","seashell":"sabbia rosa","slategrey":"grigio ardesia","coral":"corallo","darkturquoise":"turchese scuro","antiquewhite":"bianco antico","mediumspringgreen":"verde primavera medio","salmon":"salmone","darkgrey":"gri [...]
diff --git a/dijit/nls/dijit-all_ja-jp.js b/dijit/nls/dijit-all_ja-jp.js
new file mode 100644
index 0000000..1d8e20b
--- /dev/null
+++ b/dijit/nls/dijit-all_ja-jp.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_ja-jp");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.ja_jp");dojo.nls.colors.ja_jp={"lightsteelblue":"ライト・スチール・ブルー","orangered":"オレンジ・レッド","midnightblue":"ミッドナイト・ブルー","cadetblue":"くすんだ青","seashell":"シーシェル","slategrey":"スレート・グレイ","coral":"珊瑚","darkturquoise":"ダーク・ターコイズ","antiquewhite":"アンティーク・ホワイト","mediumspringgreen":"ミディアム・スプリング・グリーン","salmon":"サーモン","darkgrey":"ダーク・グレイ","ivory":"アイボリー","greenyellow":"緑黄色","m [...]
diff --git a/dijit/nls/dijit-all_ja.js b/dijit/nls/dijit-all_ja.js
new file mode 100644
index 0000000..b488528
--- /dev/null
+++ b/dijit/nls/dijit-all_ja.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_ja");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.ja");dojo.nls.colors.ja={"lightsteelblue":"ライト・スチール・ブルー","orangered":"オレンジ・レッド","midnightblue":"ミッドナイト・ブルー","cadetblue":"くすんだ青","seashell":"シーシェル","slategrey":"スレート・グレイ","coral":"珊瑚","darkturquoise":"ダーク・ターコイズ","antiquewhite":"アンティーク・ホワイト","mediumspringgreen":"ミディアム・スプリング・グリーン","salmon":"サーモン","darkgrey":"ダーク・グレイ","ivory":"アイボリー","greenyellow":"緑黄色","mistyrose" [...]
diff --git a/dijit/nls/dijit-all_ko-kr.js b/dijit/nls/dijit-all_ko-kr.js
new file mode 100644
index 0000000..bb3ac7f
--- /dev/null
+++ b/dijit/nls/dijit-all_ko-kr.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_ko-kr");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.ko_kr");dojo.nls.colors.ko_kr={"lightsteelblue":"라이트 스틸 블루(light steel blue)","orangered":"오렌지 레드(orange red)","midnightblue":"미드나잇 블루(midnight blue)","cadetblue":"카뎃 블루(cadet blue)","seashell":"씨쉘(seashell)","slategrey":"슬레이트 그레이(slate gray)","coral":"코랄(coral)","darkturquoise":"다크 터콰즈(dark turquoise)","antiquewhite":"앤틱 화이트(antique white)","mediumspringgre [...]
diff --git a/dijit/nls/dijit-all_ko.js b/dijit/nls/dijit-all_ko.js
new file mode 100644
index 0000000..7a3a0d4
--- /dev/null
+++ b/dijit/nls/dijit-all_ko.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_ko");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.ko");dojo.nls.colors.ko={"lightsteelblue":"라이트 스틸 블루(light steel blue)","orangered":"오렌지 레드(orange red)","midnightblue":"미드나잇 블루(midnight blue)","cadetblue":"카뎃 블루(cadet blue)","seashell":"씨쉘(seashell)","slategrey":"슬레이트 그레이(slate gray)","coral":"코랄(coral)","darkturquoise":"다크 터콰즈(dark turquoise)","antiquewhite":"앤틱 화이트(antique white)","mediumspringgreen":"미디엄  [...]
diff --git a/dijit/nls/dijit-all_nl-nl.js b/dijit/nls/dijit-all_nl-nl.js
new file mode 100644
index 0000000..15b7518
--- /dev/null
+++ b/dijit/nls/dijit-all_nl-nl.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_nl-nl");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.nl_nl");dojo.nls.colors.nl_nl={"lightsteelblue":"lichtstaalblauw","orangered":"oranjerood","midnightblue":"nachtblauw","cadetblue":"donkerstaalblauw","seashell":"schelp","slategrey":"leigrijs","coral":"koraalrood","darkturquoise":"donkerturquoise","antiquewhite":"antiekwit","mediumspringgreen":"midlentegroen","salmon":"zalm","darkgrey":"donkergrijs","ivory": [...]
diff --git a/dijit/nls/dijit-all_nl.js b/dijit/nls/dijit-all_nl.js
new file mode 100644
index 0000000..abb7bed
--- /dev/null
+++ b/dijit/nls/dijit-all_nl.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_nl");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.nl");dojo.nls.colors.nl={"lightsteelblue":"lichtstaalblauw","orangered":"oranjerood","midnightblue":"nachtblauw","cadetblue":"donkerstaalblauw","seashell":"schelp","slategrey":"leigrijs","coral":"koraalrood","darkturquoise":"donkerturquoise","antiquewhite":"antiekwit","mediumspringgreen":"midlentegroen","salmon":"zalm","darkgrey":"donkergrijs","ivory":"ivoorwit [...]
diff --git a/dijit/nls/dijit-all_no.js b/dijit/nls/dijit-all_no.js
new file mode 100644
index 0000000..5dc6643
--- /dev/null
+++ b/dijit/nls/dijit-all_no.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_no");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.no");dojo.nls.colors.no={"lightsteelblue":"light steel blue","orangered":"orange red","midnightblue":"midnight blue","cadetblue":"cadet blue","seashell":"seashell","slategrey":"slate gray","coral":"coral","darkturquoise":"dark turquoise","antiquewhite":"antique white","mediumspringgreen":"medium spring green","salmon":"salmon","darkgrey":"dark gray","ivory":"iv [...]
diff --git a/dijit/nls/dijit-all_pl.js b/dijit/nls/dijit-all_pl.js
new file mode 100644
index 0000000..2a632fb
--- /dev/null
+++ b/dijit/nls/dijit-all_pl.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_pl");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.pl");dojo.nls.colors.pl={"lightsteelblue":"jasny stalowoniebieski","orangered":"pomarańczowoczerwony","midnightblue":"ciemnogranatowy","cadetblue":"niebieskoszary","seashell":"muszla","slategrey":"łupkowy szary","coral":"koralowy","darkturquoise":"ciemnoturkusowy","antiquewhite":"biel antyczna","mediumspringgreen":"średnia wiosenna zieleń","salmon":"łososiowy", [...]
diff --git a/dijit/nls/dijit-all_pt-br.js b/dijit/nls/dijit-all_pt-br.js
new file mode 100644
index 0000000..ae931a5
--- /dev/null
+++ b/dijit/nls/dijit-all_pt-br.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_pt-br");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.pt_br");dojo.nls.colors.pt_br={"lightsteelblue":"azul-aço claro","orangered":"vermelho alaranjado","midnightblue":"azul meia-noite","cadetblue":"azul cadet","seashell":"seashell","slategrey":"cinza-ardósia","coral":"coral","darkturquoise":"turquesa escuro","antiquewhite":"branco antigo","mediumspringgreen":"verde-primavera médio","salmon":"salmão","darkgrey" [...]
diff --git a/dijit/nls/dijit-all_pt-pt.js b/dijit/nls/dijit-all_pt-pt.js
new file mode 100644
index 0000000..33c98ed
--- /dev/null
+++ b/dijit/nls/dijit-all_pt-pt.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_pt-pt");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.pt_pt");dojo.nls.colors.pt_pt={"lightsteelblue":"azul-aço claro","orangered":"vermelho alaranjado","midnightblue":"azul meia-noite","cadetblue":"azul cadete","seashell":"concha","slategrey":"cinzento ardósia","coral":"coral","darkturquoise":"turquesa escuro","antiquewhite":"branco antigo","mediumspringgreen":"verde primavera médio","salmon":"salmão","darkgre [...]
diff --git a/dijit/nls/dijit-all_pt.js b/dijit/nls/dijit-all_pt.js
new file mode 100644
index 0000000..e93d064
--- /dev/null
+++ b/dijit/nls/dijit-all_pt.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_pt");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.pt");dojo.nls.colors.pt={"lightsteelblue":"azul-aço claro","orangered":"vermelho alaranjado","midnightblue":"azul meia-noite","cadetblue":"azul cadet","seashell":"seashell","slategrey":"cinza-ardósia","coral":"coral","darkturquoise":"turquesa escuro","antiquewhite":"branco antigo","mediumspringgreen":"verde-primavera médio","salmon":"salmão","darkgrey":"cinza e [...]
diff --git a/dijit/nls/dijit-all_ru.js b/dijit/nls/dijit-all_ru.js
new file mode 100644
index 0000000..1c7b65e
--- /dev/null
+++ b/dijit/nls/dijit-all_ru.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_ru");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.ru");dojo.nls.colors.ru={"lightsteelblue":"светлый стальной","orangered":"оранжево-красный","midnightblue":"полуночно-синий","cadetblue":"серо-синий","seashell":"морская раковина","slategrey":"грифельно-серый","coral":"коралловый","darkturquoise":"темный бирюзовый","antiquewhite":"белый антик","mediumspringgreen":"нейтральный весенне-зеленый","salmon":"лососевы [...]
diff --git a/dijit/nls/dijit-all_sk.js b/dijit/nls/dijit-all_sk.js
new file mode 100644
index 0000000..2c6cd42
--- /dev/null
+++ b/dijit/nls/dijit-all_sk.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_sk");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.sk");dojo.nls.colors.sk={"lightsteelblue":"oceľovo modrá svetlá","orangered":"oranžovo červená","midnightblue":"nočná modrá","cadetblue":"sivomodrá","seashell":"lastúrová","slategrey":"bridlicová sivá","coral":"koralová","darkturquoise":"tyrkysová tmavá","antiquewhite":"antická biela","mediumspringgreen":"jarná zelená stredná","salmon":"lososovo ružová","darkgr [...]
diff --git a/dijit/nls/dijit-all_sl.js b/dijit/nls/dijit-all_sl.js
new file mode 100644
index 0000000..8814742
--- /dev/null
+++ b/dijit/nls/dijit-all_sl.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_sl");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.sl");dojo.nls.colors.sl={"lightsteelblue":"svetlo jeklena modra","orangered":"oranžno-rdeča","midnightblue":"polnočno modra","cadetblue":"zelenkasto modra","seashell":"morska školjka","slategrey":"skrilasto siva","coral":"koralna","darkturquoise":"temno turkizna","antiquewhite":"antično bela","mediumspringgreen":"srednje pomladno zelena","salmon":"lososova","da [...]
diff --git a/dijit/nls/dijit-all_sv.js b/dijit/nls/dijit-all_sv.js
new file mode 100644
index 0000000..e058f37
--- /dev/null
+++ b/dijit/nls/dijit-all_sv.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_sv");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.sv");dojo.nls.colors.sv={"lightsteelblue":"ljust stålblått","orangered":"orangerött","midnightblue":"midnattsblått","cadetblue":"kadettblått","seashell":"snäckskal","slategrey":"skiffergrått","coral":"korall","darkturquoise":"mörkturkost","antiquewhite":"antikvitt","mediumspringgreen":"mellanvårgrönt","salmon":"laxfärgat","darkgrey":"mörkgrått","ivory":"elfenbe [...]
diff --git a/dijit/nls/dijit-all_th.js b/dijit/nls/dijit-all_th.js
new file mode 100644
index 0000000..d31e754
--- /dev/null
+++ b/dijit/nls/dijit-all_th.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_th");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.th");dojo.nls.colors.th={"lightsteelblue":"light steel blue","orangered":"ส้มแกมแดง","midnightblue":"midnight blue","cadetblue":"cadet blue","seashell":"seashell","slategrey":"slate gray","coral":"coral","darkturquoise":"dark turquoise","antiquewhite":"antique white","mediumspringgreen":"medium spring green","salmon":"salmon","darkgrey":"เทาเข้ม","ivory":"งาช้า [...]
diff --git a/dijit/nls/dijit-all_tr.js b/dijit/nls/dijit-all_tr.js
new file mode 100644
index 0000000..2b9594a
--- /dev/null
+++ b/dijit/nls/dijit-all_tr.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_tr");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.tr");dojo.nls.colors.tr={"lightsteelblue":"açık metalik mavi","orangered":"turuncu kırmızı","midnightblue":"gece mavisi","cadetblue":"denizci mavisi","seashell":"deniz kabuğu","slategrey":"arduvaz grisi","coral":"mercan","darkturquoise":"koyu turkuaz","antiquewhite":"antik beyaz","mediumspringgreen":"orta bahar yeşili","salmon":"somon","darkgrey":"koyu gri","iv [...]
diff --git a/dijit/nls/dijit-all_xx.js b/dijit/nls/dijit-all_xx.js
new file mode 100644
index 0000000..7b47094
--- /dev/null
+++ b/dijit/nls/dijit-all_xx.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_xx");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.xx");dojo.nls.colors.xx={"lightsteelblue":"light steel blue","orangered":"orange red","midnightblue":"midnight blue","cadetblue":"cadet blue","seashell":"seashell","slategrey":"slate gray","coral":"coral","darkturquoise":"dark turquoise","antiquewhite":"antique white","mediumspringgreen":"medium spring green","salmon":"salmon","darkgrey":"dark gray","ivory":"iv [...]
diff --git a/dijit/nls/dijit-all_zh-cn.js b/dijit/nls/dijit-all_zh-cn.js
new file mode 100644
index 0000000..a127715
--- /dev/null
+++ b/dijit/nls/dijit-all_zh-cn.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_zh-cn");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.zh_cn");dojo.nls.colors.zh_cn={"lightsteelblue":"浅钢蓝色","orangered":"橙红色","midnightblue":"深蓝色","cadetblue":"灰蓝色","seashell":"海贝色","slategrey":"灰石色","coral":"珊瑚色","darkturquoise":"深粉蓝","antiquewhite":"古董白","mediumspringgreen":"间春绿色","salmon":"橙红","darkgrey":"深灰色","ivory":"象牙色","greenyellow":"绿黄色","mistyrose":"浅玫瑰色","lightsalmon":"淡橙色","silver":"银白色","dimgrey": [...]
diff --git a/dijit/nls/dijit-all_zh-tw.js b/dijit/nls/dijit-all_zh-tw.js
new file mode 100644
index 0000000..4a7a978
--- /dev/null
+++ b/dijit/nls/dijit-all_zh-tw.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_zh-tw");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.zh_tw");dojo.nls.colors.zh_tw={"lightsteelblue":"淡鐵藍色","orangered":"橙紅色","midnightblue":"午夜藍","cadetblue":"軍服藍","seashell":"海貝色","slategrey":"岩灰色","coral":"珊瑚紅","darkturquoise":"暗松石綠","antiquewhite":"米白色","mediumspringgreen":"中春綠色","salmon":"鮭紅色","darkgrey":"暗灰色","ivory":"象牙色","greenyellow":"綠黃色","mistyrose":"霧玫瑰色","lightsalmon":"淡鮭紅","silver":"銀色","dimgrey" [...]
diff --git a/dijit/nls/dijit-all_zh.js b/dijit/nls/dijit-all_zh.js
new file mode 100644
index 0000000..86367af
--- /dev/null
+++ b/dijit/nls/dijit-all_zh.js
@@ -0,0 +1 @@
+dojo.provide("dijit.nls.dijit-all_zh");dojo.provide("dojo.nls.colors");dojo.nls.colors._built=true;dojo.provide("dojo.nls.colors.zh");dojo.nls.colors.zh={"lightsteelblue":"浅钢蓝色","orangered":"橙红色","midnightblue":"深蓝色","cadetblue":"灰蓝色","seashell":"海贝色","slategrey":"灰石色","coral":"珊瑚色","darkturquoise":"深粉蓝","antiquewhite":"古董白","mediumspringgreen":"间春绿色","salmon":"橙红","darkgrey":"深灰色","ivory":"象牙色","greenyellow":"绿黄色","mistyrose":"浅玫瑰色","lightsalmon":"淡橙色","silver":"银白色","dimgrey":"暗灰色","or [...]
diff --git a/dijit/nls/el/common.js b/dijit/nls/el/common.js
new file mode 100644
index 0000000..8e7a36a
--- /dev/null
+++ b/dijit/nls/el/common.js
@@ -0,0 +1 @@
+({"buttonOk":"ΟΚ","buttonCancel":"Ακύρωση","buttonSave":"Αποθήκευση","itemClose":"Κλείσιμο"})
\ No newline at end of file
diff --git a/dijit/nls/el/loading.js b/dijit/nls/el/loading.js
new file mode 100644
index 0000000..9567b3c
--- /dev/null
+++ b/dijit/nls/el/loading.js
@@ -0,0 +1 @@
+({"loadingState":"Φόρτωση...","errorState":"Σας ζητούμε συγνώμη, παρουσιάστηκε σφάλμα"})
\ No newline at end of file
diff --git a/dijit/nls/es/common.js b/dijit/nls/es/common.js
new file mode 100644
index 0000000..b4feef9
--- /dev/null
+++ b/dijit/nls/es/common.js
@@ -0,0 +1 @@
+({"buttonOk":"Aceptar","buttonCancel":"Cancelar","buttonSave":"Guardar","itemClose":"Cerrar"})
\ No newline at end of file
diff --git a/dijit/nls/es/loading.js b/dijit/nls/es/loading.js
new file mode 100644
index 0000000..dc969a3
--- /dev/null
+++ b/dijit/nls/es/loading.js
@@ -0,0 +1 @@
+({"loadingState":"Cargando...","errorState":"Lo siento, se ha producido un error"})
\ No newline at end of file
diff --git a/dijit/nls/fi/common.js b/dijit/nls/fi/common.js
new file mode 100644
index 0000000..8b2fc26
--- /dev/null
+++ b/dijit/nls/fi/common.js
@@ -0,0 +1 @@
+({"buttonOk":"OK","buttonCancel":"Peruuta","buttonSave":"Tallenna","itemClose":"Sulje"})
\ No newline at end of file
diff --git a/dijit/nls/fi/loading.js b/dijit/nls/fi/loading.js
new file mode 100644
index 0000000..73e10a1
--- /dev/null
+++ b/dijit/nls/fi/loading.js
@@ -0,0 +1 @@
+({"loadingState":"Lataus on meneillään...","errorState":"On ilmennyt virhe."})
\ No newline at end of file
diff --git a/dijit/nls/fr/common.js b/dijit/nls/fr/common.js
new file mode 100644
index 0000000..9f6aabe
--- /dev/null
+++ b/dijit/nls/fr/common.js
@@ -0,0 +1 @@
+({"buttonOk":"OK","buttonCancel":"Annuler","buttonSave":"Sauvegarder","itemClose":"Fermer"})
\ No newline at end of file
diff --git a/dijit/nls/fr/loading.js b/dijit/nls/fr/loading.js
new file mode 100644
index 0000000..ec7192b
--- /dev/null
+++ b/dijit/nls/fr/loading.js
@@ -0,0 +1 @@
+({"loadingState":"Chargement...","errorState":"Une erreur est survenue"})
\ No newline at end of file
diff --git a/dijit/nls/he/common.js b/dijit/nls/he/common.js
new file mode 100644
index 0000000..b04d1cc
--- /dev/null
+++ b/dijit/nls/he/common.js
@@ -0,0 +1 @@
+({"buttonOk":"אישור","buttonCancel":"ביטול","buttonSave":"שמירה","itemClose":"סגירה"})
\ No newline at end of file
diff --git a/dijit/nls/he/loading.js b/dijit/nls/he/loading.js
new file mode 100644
index 0000000..7b1d5f3
--- /dev/null
+++ b/dijit/nls/he/loading.js
@@ -0,0 +1 @@
+({"loadingState":"טעינה...‏","errorState":"אירעה שגיאה"})
\ No newline at end of file
diff --git a/dijit/nls/hu/common.js b/dijit/nls/hu/common.js
new file mode 100644
index 0000000..21a773f
--- /dev/null
+++ b/dijit/nls/hu/common.js
@@ -0,0 +1 @@
+({"buttonOk":"OK","buttonCancel":"Mégse","buttonSave":"Mentés","itemClose":"Bezárás"})
\ No newline at end of file
diff --git a/dijit/nls/hu/loading.js b/dijit/nls/hu/loading.js
new file mode 100644
index 0000000..d61e9a2
--- /dev/null
+++ b/dijit/nls/hu/loading.js
@@ -0,0 +1 @@
+({"loadingState":"Betöltés...","errorState":"Sajnálom, hiba történt"})
\ No newline at end of file
diff --git a/dijit/nls/it/common.js b/dijit/nls/it/common.js
new file mode 100644
index 0000000..6b3dc74
--- /dev/null
+++ b/dijit/nls/it/common.js
@@ -0,0 +1 @@
+({"buttonOk":"OK","buttonCancel":"Annulla","buttonSave":"Salva","itemClose":"Chiudi"})
\ No newline at end of file
diff --git a/dijit/nls/it/loading.js b/dijit/nls/it/loading.js
new file mode 100644
index 0000000..60d05e0
--- /dev/null
+++ b/dijit/nls/it/loading.js
@@ -0,0 +1 @@
+({"loadingState":"Caricamento in corso...","errorState":"Si è verificato un errore"})
\ No newline at end of file
diff --git a/dijit/nls/ja/common.js b/dijit/nls/ja/common.js
new file mode 100644
index 0000000..b0b48c6
--- /dev/null
+++ b/dijit/nls/ja/common.js
@@ -0,0 +1 @@
+({"buttonOk":"OK","buttonCancel":"キャンセル","buttonSave":"保存","itemClose":"閉じる"})
\ No newline at end of file
diff --git a/dijit/nls/ja/loading.js b/dijit/nls/ja/loading.js
new file mode 100644
index 0000000..fa67d67
--- /dev/null
+++ b/dijit/nls/ja/loading.js
@@ -0,0 +1 @@
+({"loadingState":"ロード中...","errorState":"エラーが発生しました。"})
\ No newline at end of file
diff --git a/dijit/nls/ko/common.js b/dijit/nls/ko/common.js
new file mode 100644
index 0000000..8e12bbf
--- /dev/null
+++ b/dijit/nls/ko/common.js
@@ -0,0 +1 @@
+({"buttonOk":"확인","buttonCancel":"취소","buttonSave":"저장","itemClose":"닫기"})
\ No newline at end of file
diff --git a/dijit/nls/ko/loading.js b/dijit/nls/ko/loading.js
new file mode 100644
index 0000000..5d1ca12
--- /dev/null
+++ b/dijit/nls/ko/loading.js
@@ -0,0 +1 @@
+({"loadingState":"로드 중...","errorState":"죄송합니다. 오류가 발생했습니다."})
\ No newline at end of file
diff --git a/dijit/nls/loading.js b/dijit/nls/loading.js
new file mode 100644
index 0000000..1d6fa9b
--- /dev/null
+++ b/dijit/nls/loading.js
@@ -0,0 +1 @@
+({"loadingState":"Loading...","errorState":"Sorry, an error occurred"})
\ No newline at end of file
diff --git a/dijit/nls/nb/common.js b/dijit/nls/nb/common.js
new file mode 100644
index 0000000..73e38c7
--- /dev/null
+++ b/dijit/nls/nb/common.js
@@ -0,0 +1 @@
+({"buttonOk":"OK","buttonCancel":"Avbryt","buttonSave":"Lagre","itemClose":"Lukk"})
\ No newline at end of file
diff --git a/dijit/nls/nb/loading.js b/dijit/nls/nb/loading.js
new file mode 100644
index 0000000..dbc314d
--- /dev/null
+++ b/dijit/nls/nb/loading.js
@@ -0,0 +1 @@
+({"loadingState":"Laster inn...","errorState":"Det oppsto en feil"})
\ No newline at end of file
diff --git a/dijit/nls/nl/common.js b/dijit/nls/nl/common.js
new file mode 100644
index 0000000..fa4c66e
--- /dev/null
+++ b/dijit/nls/nl/common.js
@@ -0,0 +1 @@
+({"buttonOk":"OK","buttonCancel":"Annuleren","buttonSave":"Opslaan","itemClose":"Sluiten"})
\ No newline at end of file
diff --git a/dijit/nls/nl/loading.js b/dijit/nls/nl/loading.js
new file mode 100644
index 0000000..c9870fd
--- /dev/null
+++ b/dijit/nls/nl/loading.js
@@ -0,0 +1 @@
+({"loadingState":"Bezig met laden...","errorState":"Er is een fout opgetreden"})
\ No newline at end of file
diff --git a/dijit/nls/pl/common.js b/dijit/nls/pl/common.js
new file mode 100644
index 0000000..c84e539
--- /dev/null
+++ b/dijit/nls/pl/common.js
@@ -0,0 +1 @@
+({"buttonOk":"OK","buttonCancel":"Anuluj","buttonSave":"Zapisz","itemClose":"Zamknij"})
\ No newline at end of file
diff --git a/dijit/nls/pl/loading.js b/dijit/nls/pl/loading.js
new file mode 100644
index 0000000..eed3c3e
--- /dev/null
+++ b/dijit/nls/pl/loading.js
@@ -0,0 +1 @@
+({"loadingState":"Ładowanie...","errorState":"Niestety, wystąpił błąd"})
\ No newline at end of file
diff --git a/dijit/nls/pt-pt/common.js b/dijit/nls/pt-pt/common.js
new file mode 100644
index 0000000..7992705
--- /dev/null
+++ b/dijit/nls/pt-pt/common.js
@@ -0,0 +1 @@
+({"buttonOk":"OK","buttonCancel":"Cancelar","buttonSave":"Guardar","itemClose":"Fechar"})
\ No newline at end of file
diff --git a/dijit/nls/pt-pt/loading.js b/dijit/nls/pt-pt/loading.js
new file mode 100644
index 0000000..80257d3
--- /dev/null
+++ b/dijit/nls/pt-pt/loading.js
@@ -0,0 +1 @@
+({"loadingState":"A carregar...","errorState":"Lamentamos, mas ocorreu um erro"})
\ No newline at end of file
diff --git a/dijit/nls/pt/common.js b/dijit/nls/pt/common.js
new file mode 100644
index 0000000..b94e6bc
--- /dev/null
+++ b/dijit/nls/pt/common.js
@@ -0,0 +1 @@
+({"buttonOk":"OK","buttonCancel":"Cancelar","buttonSave":"Salvar","itemClose":"Fechar"})
\ No newline at end of file
diff --git a/dijit/nls/pt/loading.js b/dijit/nls/pt/loading.js
new file mode 100644
index 0000000..88cda7a
--- /dev/null
+++ b/dijit/nls/pt/loading.js
@@ -0,0 +1 @@
+({"loadingState":"Carregando...","errorState":"Desculpe, ocorreu um erro"})
\ No newline at end of file
diff --git a/dijit/nls/ru/common.js b/dijit/nls/ru/common.js
new file mode 100644
index 0000000..9a76d09
--- /dev/null
+++ b/dijit/nls/ru/common.js
@@ -0,0 +1 @@
+({"buttonOk":"ОК","buttonCancel":"Отмена","buttonSave":"Сохранить","itemClose":"Закрыть"})
\ No newline at end of file
diff --git a/dijit/nls/ru/loading.js b/dijit/nls/ru/loading.js
new file mode 100644
index 0000000..55cd03b
--- /dev/null
+++ b/dijit/nls/ru/loading.js
@@ -0,0 +1 @@
+({"loadingState":"Загрузка...","errorState":"Извините, возникла ошибка"})
\ No newline at end of file
diff --git a/dijit/nls/sk/common.js b/dijit/nls/sk/common.js
new file mode 100644
index 0000000..59a12d1
--- /dev/null
+++ b/dijit/nls/sk/common.js
@@ -0,0 +1 @@
+({"buttonOk":"OK","buttonCancel":"Zrušiť","buttonSave":"Uložiť","itemClose":"Zatvoriť"})
\ No newline at end of file
diff --git a/dijit/nls/sk/loading.js b/dijit/nls/sk/loading.js
new file mode 100644
index 0000000..e805bd8
--- /dev/null
+++ b/dijit/nls/sk/loading.js
@@ -0,0 +1 @@
+({"loadingState":"Zavádzanie...","errorState":"Nastala chyba"})
\ No newline at end of file
diff --git a/dijit/nls/sl/common.js b/dijit/nls/sl/common.js
new file mode 100644
index 0000000..4704cc5
--- /dev/null
+++ b/dijit/nls/sl/common.js
@@ -0,0 +1 @@
+({"buttonOk":"V redu","buttonCancel":"Prekliči","buttonSave":"Shrani","itemClose":"Zapri"})
\ No newline at end of file
diff --git a/dijit/nls/sl/loading.js b/dijit/nls/sl/loading.js
new file mode 100644
index 0000000..4100866
--- /dev/null
+++ b/dijit/nls/sl/loading.js
@@ -0,0 +1 @@
+({"loadingState":"Nalaganje...","errorState":"Oprostite, prišlo je do napake."})
\ No newline at end of file
diff --git a/dijit/nls/sv/common.js b/dijit/nls/sv/common.js
new file mode 100644
index 0000000..cd3444f
--- /dev/null
+++ b/dijit/nls/sv/common.js
@@ -0,0 +1 @@
+({"buttonOk":"OK","buttonCancel":"Avbryt","buttonSave":"Spara","itemClose":"Stäng"})
\ No newline at end of file
diff --git a/dijit/nls/sv/loading.js b/dijit/nls/sv/loading.js
new file mode 100644
index 0000000..95b90d2
--- /dev/null
+++ b/dijit/nls/sv/loading.js
@@ -0,0 +1 @@
+({"loadingState":"Läser in...","errorState":"Det uppstod ett fel."})
\ No newline at end of file
diff --git a/dijit/nls/th/common.js b/dijit/nls/th/common.js
new file mode 100644
index 0000000..be06dd0
--- /dev/null
+++ b/dijit/nls/th/common.js
@@ -0,0 +1 @@
+({"buttonOk":"ตกลง","buttonCancel":"ยกเลิก","buttonSave":"บันทึก","itemClose":"ปิด"})
\ No newline at end of file
diff --git a/dijit/nls/th/loading.js b/dijit/nls/th/loading.js
new file mode 100644
index 0000000..bb6b75d
--- /dev/null
+++ b/dijit/nls/th/loading.js
@@ -0,0 +1 @@
+({"loadingState":"กำลังโหลด...","errorState":"ขออภัย เกิดข้อผิดพลาด"})
\ No newline at end of file
diff --git a/dijit/nls/tr/common.js b/dijit/nls/tr/common.js
new file mode 100644
index 0000000..e89e645
--- /dev/null
+++ b/dijit/nls/tr/common.js
@@ -0,0 +1 @@
+({"buttonOk":"Tamam","buttonCancel":"İptal","buttonSave":"Kaydet","itemClose":"Kapat"})
\ No newline at end of file
diff --git a/dijit/nls/tr/loading.js b/dijit/nls/tr/loading.js
new file mode 100644
index 0000000..b0ed738
--- /dev/null
+++ b/dijit/nls/tr/loading.js
@@ -0,0 +1 @@
+({"loadingState":"Yükleniyor...","errorState":"Üzgünüz, bir hata oluştu"})
\ No newline at end of file
diff --git a/dijit/nls/zh-tw/common.js b/dijit/nls/zh-tw/common.js
new file mode 100644
index 0000000..5d3fee0
--- /dev/null
+++ b/dijit/nls/zh-tw/common.js
@@ -0,0 +1 @@
+({"buttonOk":"確定","buttonCancel":"取消","buttonSave":"儲存","itemClose":"關閉"})
\ No newline at end of file
diff --git a/dijit/nls/zh-tw/loading.js b/dijit/nls/zh-tw/loading.js
new file mode 100644
index 0000000..0078541
--- /dev/null
+++ b/dijit/nls/zh-tw/loading.js
@@ -0,0 +1 @@
+({"loadingState":"載入中...","errorState":"抱歉,發生錯誤"})
\ No newline at end of file
diff --git a/dijit/nls/zh/common.js b/dijit/nls/zh/common.js
new file mode 100644
index 0000000..0bb6267
--- /dev/null
+++ b/dijit/nls/zh/common.js
@@ -0,0 +1 @@
+({"buttonOk":"确定","buttonCancel":"取消","buttonSave":"保存","itemClose":"关闭"})
\ No newline at end of file
diff --git a/dijit/nls/zh/loading.js b/dijit/nls/zh/loading.js
new file mode 100644
index 0000000..c4b6fd7
--- /dev/null
+++ b/dijit/nls/zh/loading.js
@@ -0,0 +1 @@
+({"loadingState":"正在加载...","errorState":"对不起,发生了错误"})
\ No newline at end of file
diff --git a/dijit/resources/_modules.js b/dijit/resources/_modules.js
new file mode 100644
index 0000000..0b276e5
--- /dev/null
+++ b/dijit/resources/_modules.js
@@ -0,0 +1,7 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
diff --git a/dijit/robot.js b/dijit/robot.js
new file mode 100644
index 0000000..bdcd59d
--- /dev/null
+++ b/dijit/robot.js
@@ -0,0 +1,19 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.robot"]){
+dojo._hasResource["dijit.robot"]=true;
+dojo.provide("dijit.robot");
+dojo.require("dojo.robot");
+dojo.require("dijit._base.scroll");
+dojo.mixin(doh.robot,{_scrollIntoView:function(_1){
+if(typeof _1=="function"){
+_1=_1();
+}
+dijit.scrollIntoView(_1);
+}});
+}
diff --git a/dijit/robotx.js b/dijit/robotx.js
new file mode 100644
index 0000000..5f86f8c
--- /dev/null
+++ b/dijit/robotx.js
@@ -0,0 +1,24 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.robotx"]){
+dojo._hasResource["dijit.robotx"]=true;
+dojo.provide("dijit.robotx");
+dojo.require("dijit.robot");
+dojo.require("dojo.robotx");
+dojo.experimental("dijit.robotx");
+(function(){
+var _1=doh.robot._updateDocument;
+dojo.mixin(doh.robot,{_updateDocument:function(){
+_1();
+var _2=dojo.global;
+if(_2["dijit"]){
+dijit.registry=_2.dijit.registry;
+}
+}});
+})();
+}
diff --git a/dijit/themes/a11y/README.txt b/dijit/themes/a11y/README.txt
new file mode 100644
index 0000000..a809354
--- /dev/null
+++ b/dijit/themes/a11y/README.txt
@@ -0,0 +1,3 @@
+This folder contains images used by all themes when in "high-contrast" mode.
+
+If you think you need to put something here, please talk to Becky or Bill first.
\ No newline at end of file
diff --git a/dijit/themes/a11y/colors3x4.png b/dijit/themes/a11y/colors3x4.png
new file mode 100644
index 0000000..e407881
Binary files /dev/null and b/dijit/themes/a11y/colors3x4.png differ
diff --git a/dijit/themes/a11y/colors7x10.png b/dijit/themes/a11y/colors7x10.png
new file mode 100644
index 0000000..77d22ce
Binary files /dev/null and b/dijit/themes/a11y/colors7x10.png differ
diff --git a/dijit/themes/a11y/indeterminate_progress.gif b/dijit/themes/a11y/indeterminate_progress.gif
new file mode 100644
index 0000000..66f535c
Binary files /dev/null and b/dijit/themes/a11y/indeterminate_progress.gif differ
diff --git a/dijit/themes/dijit.css b/dijit/themes/dijit.css
new file mode 100644
index 0000000..ad9a984
--- /dev/null
+++ b/dijit/themes/dijit.css
@@ -0,0 +1,1301 @@
+
+.dijitReset {
+	
+	margin:0;
+	border:0;
+	padding:0;
+	line-height:normal;
+	font: inherit;
+	color: inherit;
+}
+.dijitInline {
+	
+	display:-moz-inline-box;		
+	display:inline-block;			
+	#zoom: 1; 
+	#display:inline; 
+	border:0;
+	padding:0;
+	vertical-align:middle;
+	#vertical-align: auto;	
+}
+.dijitHidden {
+	
+	display: none !important;
+}
+.dijitVisible {
+	
+	display: block !important;	
+	position: relative;			
+}
+.dj_ie INPUT.dijitTextBox,
+.dj_ie .dijitInputField INPUT {
+	font-size: 100%;
+}
+.dj_ie .dijitInputField INPUT { 
+	margin: -1px 0 !important;
+}
+.dijitInlineTable {
+	
+	display: -moz-inline-stack;	
+	display:inline-table;
+	display:inline-block;		
+	#zoom: 1; 
+	#display:inline; 
+	box-sizing: content-box; -moz-box-sizing: content-box;
+	border:0;
+	padding:0;
+}
+.dijitTeeny {
+	font-size:1px;
+	line-height:1px;
+}
+.dijitPopup {
+	position: absolute;
+	background-color: transparent;
+	margin: 0;
+	border: 0;
+	padding: 0;
+}
+.dijit_a11y .dijitPopup,
+.dijit_ally .dijitPopup div,
+.dijit_a11y .dijitPopup table,
+.dijit_a11y .dijitTooltipContainer {
+	background-color: white !important;
+}
+.dijitInputField {
+	overflow:hidden;
+	#zoom:1;
+}
+.dijitPositionOnly {
+	
+	padding: 0 !important;
+	border: 0 !important;
+	background-color: transparent !important;
+	background-image: none !important;
+	height: auto !important;
+	width: auto !important;
+}
+.dijitNonPositionOnly {
+	
+	float: none !important;
+	position: static !important;
+	margin: 0 0 0 0 !important;
+	vertical-align: middle !important;
+}
+.dijitBackgroundIframe {
+	
+	position: absolute;
+	left: 0;
+	top: 0;
+	width: 100%;
+	height: 100%;
+	z-index: -1;
+	border: 0;
+	padding: 0;
+	margin: 0;
+}
+.dijitClickableRegion {
+	
+	background-color: #e2ebf2;
+	cursor: text;
+}
+.dijitDisplayNone {
+	
+	display:none !important;
+}
+.dijitContainer {
+	
+	overflow: hidden;	
+}
+.dijit_a11y * {
+	background-image:none !important;
+}
+.dijit_a11y .dijitCalendarIncrementControl {
+	display: none;	
+}
+.dijit_a11y .dijitA11ySideArrow {
+	display: inline !important; 
+	cursor: pointer;
+}
+.dijit_a11y .dijitCalendarSelectedDate {
+	text-decoration:overline !important;
+}
+.dijit_a11y .dijit * {
+	background:white !important;
+	color:black !important;
+}
+.dijit_a11y .dijitButtonNode {
+	border-color: black!important;
+	border-style: outset!important;
+	border-width: medium!important;
+}
+.dijit_a11y .dijitButtonDisabled .dijitButtonNode,
+.dijit_a11y .dijitDropDownButtonDisabled .dijitButtonNode,
+.dijit_a11y .dijitComboButtonDisabled .dijitButtonNode,
+.dijit_a11y .dijitComboBoxDisabled .dijitInputField,
+.dijit_a11y .dijitComboBoxDisabled .dijitButtonNode,
+.dijit_a11y .dijitSpinnerDisabled .dijitButtonNode,
+.dijit_a11y .dijitSpinnerDisabled .dijitInputField {
+	border-style: outset!important;
+	border-width: medium!important;
+	border-color: #999 !important;
+	color:#999 !important;
+}
+.dj_ff2 .dijit_a11y .dijitComboButton .dijitButtonContentsFocused,
+.dj_ff2 .dijit_a11y .dijitComboButton .dijitDownArrowButtonFocused {
+	border: 1px dotted black !important;
+}
+.dijitButtonNode * {
+	vertical-align: middle;
+}
+.dijit_a11y .dijitArrowButtonInner {
+	width: 1em;
+	display: none !important;
+}
+.dijitButtonNode .dijitArrowButtonInner {
+	background:no-repeat center;
+	width: 16px;
+}
+.dijitComboBox .dijitArrowButtonInner {
+	display: block;
+}
+.dijit_a11y .dijitToggleButtonChecked .dijitToggleButtonIconChar {
+	display: inline !important;
+}
+	
+.dijitLeft {
+	
+	background-position:left top;
+	background-repeat:no-repeat;
+}
+.dijitStretch {
+	
+	white-space:nowrap;			
+	background-repeat:repeat-x;
+}
+.dijitRight {
+	
+	#display:inline;				
+	background-position:right top;
+	background-repeat:no-repeat;
+}
+.dijitButton,
+.dijitDropDownButton,
+.dijitComboButton {
+	
+	margin: 0.2em;
+}
+.dijitToolbar .dijitButton,
+.dijitToolbar .dijitDropDownButton,
+.dijitToolbar .dijitComboButton {
+	margin: 0;
+}
+.dj_ie8 .dijitToolbar button,
+.dj_webkit .dijitToolbar button {
+	
+	padding: 1px 2px;
+}
+.dj_ie .dijitToolbar .dijitComboBox{
+	
+	vertical-align: middle;
+}
+.dj_ie .dijitComboButton {
+	
+	margin-bottom: -3px;
+}
+.dj_webkit .dijitToolbar .dijitDropDownButton {
+	padding-left: 0.3em;
+}
+.dj_gecko .dijitToolbar .dijitButtonNode::-moz-focus-inner {
+	padding:0;
+}
+.dijitButtonNode {
+	
+	border:1px solid gray;
+	margin:0;
+	line-height:normal;
+	vertical-align: middle;
+	#vertical-align: auto;
+	text-align:center;
+	white-space: nowrap;
+}
+.dijitButtonNode, .dijitButtonNode * {
+	cursor: pointer;
+} 
+.dijitReadOnly *,
+.dijitDisabled *,
+.dijitReadOnly,
+.dijitDisabled,
+.dijitDisabledClickableRegion {	
+	cursor: not-allowed !important;
+}
+.dj_ie .dijitButtonNode {
+	
+	zoom: 1;
+}
+.dj_ie .dijitButtonNode button { 
+	 
+	overflow: visible;
+} 
+.dijitArrowButton {
+	
+	
+	padding: 0 .4em;
+}
+DIV.dijitArrowButton {
+	float: right;
+}
+.dijitSpinner .dijitInputLayoutContainer .dijitArrowButton {
+	border-style: solid;
+	border-width: 0 0 0 1px !important;
+	padding: 0;
+	position: absolute;
+	right: 0;
+	float: none;
+}
+.dijitSpinner .dijitInputLayoutContainer .dijitArrowButton {
+	position: absolute;
+	height: 50%;
+}
+.dijitSpinner .dijitInputLayoutContainer .dijitDownArrowButton {
+	top: auto;
+	bottom: 0;
+	border-top-width: 1px !important;
+}
+.dijitSpinner .dijitInputLayoutContainer .dijitUpArrowButton {
+	top: 0;
+	bottom: auto;
+}
+TABLE.dijitComboButton {
+	
+	border-collapse: collapse;
+	border:0;
+	padding:0;
+	margin:0;
+}
+.dijitToolbar .dijitComboButton {
+	
+	border-collapse: separate;
+}
+.dj_ie BUTTON.dijitButtonNode {
+	overflow: visible; 
+}
+table .dijitButton .dijitButtonNode,
+table .dijitComboButton .dijitButtonNode {
+	#overflow:hidden; 
+}
+.dijitButtonNode IMG {
+	
+	vertical-align:middle;
+	
+}
+.dijitTextBox,
+.dijitComboBox,
+.dijitSpinner {
+	border: solid black 1px;
+	#overflow: hidden; 
+	width: 15em;	
+	vertical-align: middle;
+	#vertical-align: auto;	
+}
+.dijitTimeTextBox {
+	width: 8em;
+}
+.dijitTextBox input:focus,
+.dijitComboBox input:focus,
+.dijitSpinner input:focus {
+	outline: none;	
+}
+.dijitTextBoxFocused,
+.dijitComboBoxFocused,
+.dijitSpinnerFocused, .dijitSpinnerUpArrowActive, .dijitSpinnerDownArrowActive,
+.dijitTextAreaFocused {
+	
+	outline: auto 5px -webkit-focus-ring-color;
+}
+.dijitTextAreaFocused div {
+	
+	outline: none !important;
+}
+.dijitTextBox INPUT,
+.dijitComboBox INPUT,
+.dijitSpinner INPUT {
+	border-left: solid black 1px;	
+	display:inline;
+	position:static !important;
+	border:0 !important;	
+	margin:0 !important;
+	vertical-align:top !important;
+	background-color:transparent !important;
+	background-image:none !important;
+	width:100% !important;
+}
+.dijitValidationIcon {
+	visibility: hidden;
+	display: block;
+	padding: 0 2px;
+	float: right;
+	height: auto;
+}
+.dijitValidationIconText {
+	visibility: hidden;
+	display: none;
+	float:right;
+	font-family: sans-serif;
+	font-style:italic;
+	font-size: 0.75em;
+	padding-right: 0.15em;
+	line-height: 160%;
+}
+.dijit_a11y .dijitValidationIcon { display: none !important; }
+.dijit_a11y .dijitValidationIconText { display: block !important; }
+.dijitError .dijitValidationIcon,
+.dijitError .dijitValidationIconText {
+	visibility: visible;
+}
+.dijitTextBox .dijitArrowButton {
+	
+	display:none;
+}
+.dijitCheckBox,
+.dijitRadio,
+.dijitCheckBoxInput {
+	padding: 0;
+	border: 0;
+	width: 16px;
+	height: 16px;
+	background-position:center center;
+	background-repeat:no-repeat;
+	overflow: hidden;
+}
+.dijitCheckBox INPUT,
+.dijitRadio INPUT {
+	margin: 0;
+	padding: 0;
+	display: block;
+}
+.dijitCheckBoxInput {
+	
+	opacity: 0.01;
+}
+.dj_ie .dijitCheckBoxInput {
+	filter: alpha(opacity=0);
+}
+.dijit_a11y .dijitCheckBox,
+.dijit_a11y .dijitRadio {
+	width: auto;
+	height: auto;
+}
+.dijit_a11y .dijitCheckBoxInput {
+	opacity: 1;
+	filter: none;
+	width: auto;
+	height: auto;
+}
+.dijitProgressBarEmpty{
+	
+	position:relative;overflow:hidden;
+	border:1px solid black; 	
+	z-index:0;			
+}
+.dijitProgressBarFull {
+	
+	position:absolute;
+	overflow:hidden;
+	z-index:-1;
+	top:0;
+	width:100%;
+}
+.dj_ie6 .dijitProgressBarFull {
+	height:1.6em;
+}
+.dijitProgressBarTile {
+	
+	position:absolute;
+	overflow:hidden;
+	top:0;
+	left:0;
+	bottom:0;
+	right:0;
+	margin:0;
+	padding:0;
+	width:auto;
+	height:auto;
+	background-color:#aaa;
+	background-attachment: fixed;
+}
+.dijit_a11y .dijitProgressBarTile{
+	
+	border-width:4px;
+	border-style:solid;
+	background-color:transparent !important;
+}
+.dj_ie6 .dijitProgressBarTile {
+	
+	position:static;
+	
+	height:1.6em;
+}
+.dijitProgressBarIndeterminate .dijitProgressBarLabel {
+	visibility:hidden;
+}
+.dijitProgressBarIndeterminate .dijitProgressBarTile {
+	
+}
+.dijitProgressBarIndeterminateHighContrastImage {
+	display:none;
+}
+.dijit_a11y .dijitProgressBarIndeterminate .dijitProgressBarIndeterminateHighContrastImage {
+	display:block;
+	position:absolute;
+	top:0;
+	bottom:0;
+	margin:0;
+	padding:0;
+	width:100%;
+	height:auto;
+}
+.dijitProgressBarLabel {
+	display:block;
+	position:static;
+	width:100%;
+	text-align:center;
+	background-color:transparent !important;
+}
+.dijitTooltip {
+	position: absolute;
+	z-index: 2000;
+	display: block;
+	
+	left: 50%;
+	top: -10000px;
+	overflow: visible;
+}
+.dijitTooltipContainer {
+	border: solid black 2px;
+	background: #b8b5b5;
+	color: black;
+	font-size: small;
+}
+.dijitTooltipFocusNode {
+	padding: 2px 2px 2px 2px;
+}
+.dijitTooltipConnector {
+	position: absolute;
+}
+.dijitTooltipData {
+	display:none;
+}
+.dijitLayoutContainer{
+	position: relative;
+	display: block;
+	overflow: hidden;
+}
+body .dijitAlignTop,
+body .dijitAlignBottom,
+body .dijitAlignLeft,
+body .dijitAlignRight {
+	position: absolute;
+	overflow: hidden;
+}
+body .dijitAlignClient { position: absolute; }
+.dijitBorderContainer, .dijitBorderContainerNoGutter {
+	position:relative;
+	overflow: hidden;
+}
+.dijitBorderContainerPane,
+.dijitBorderContainerNoGutterPane {
+	position: absolute !important;	
+	z-index: 2;		
+}
+.dijitBorderContainer > .dijitTextArea {
+	
+	resize: none;
+}
+.dijitGutter {
+	
+	position: absolute;
+	font-size: 1px;		
+}
+.dijitSplitter {
+	position: absolute;
+	overflow: hidden;
+	z-index: 10;		
+	background-color: #fff;
+	border-color: gray;
+	border-style: solid;
+	border-width: 0;
+}
+.dj_ie .dijitSplitter {
+	z-index: 1;	
+}
+.dijitSplitterActive {
+	z-index: 11 !important;
+}
+.dijitSplitterCover{
+	position:absolute;
+	z-index:-1;
+	top:0;
+	left:0;
+	width:100%;
+	height:100%;
+}
+.dijitSplitterCoverActive{
+	z-index:3 !important;
+}
+.dj_ie .dijitSplitterCover{
+	background: white;
+	filter: alpha(opacity=0);
+}
+.dijitSplitterH {
+	height: 7px;
+	border-top:1px;
+	border-bottom:1px;
+	cursor: ns-resize;
+}
+.dijitSplitterV {
+	width: 7px;
+	border-left:1px;
+	border-right:1px;
+	cursor: ew-resize;
+}
+.dijitSplitContainer{
+	position: relative;
+	overflow: hidden;
+	display: block;
+}
+.dijitSplitPane{
+	position: absolute;
+}
+.dijitSplitContainerSizerH,
+.dijitSplitContainerSizerV {
+	position:absolute;
+	font-size: 1px;
+	cursor: move;
+	cursor: w-resize;
+	background-color: ThreeDFace;
+	border: 1px solid;
+	border-color: ThreeDHighlight ThreeDShadow ThreeDShadow ThreeDHighlight;
+	margin: 0;
+}
+.dijitSplitContainerSizerH .thumb, .dijitSplitterV .dijitSplitterThumb {
+	overflow:hidden;
+	position:absolute;
+	top:49%;
+}
+.dijitSplitContainerSizerV .thumb, .dijitSplitterH .dijitSplitterThumb {
+	position:absolute;
+	left:49%;
+}
+.dijitSplitterShadow,
+.dijitSplitContainerVirtualSizerH,
+.dijitSplitContainerVirtualSizerV {
+	font-size: 1px;
+	background-color: ThreeDShadow;
+	-moz-opacity: 0.5;
+	opacity: 0.5;
+	filter: Alpha(Opacity=50);
+	margin: 0;
+}
+.dj_ie .dijitSplitterV, .dijitSplitContainerVirtualSizerH {
+	cursor: w-resize;
+}
+.dj_ie .dijitSplitterH, .dijitSplitContainerSizerV, .dijitSplitContainerVirtualSizerV {
+	cursor: n-resize;
+}
+.dijit_a11y .dijitSplitterH {
+	border-top:1px solid #d3d3d3 !important;
+	border-bottom:1px solid #d3d3d3 !important;
+}
+.dijit_a11y .dijitSplitterV {
+	border-left:1px solid #d3d3d3 !important;
+	border-right:1px solid #d3d3d3 !important;
+}
+.dijitContentPane {
+	display: block;
+	overflow: auto;	
+}
+.dijitTitlePane {
+	display: block;
+	overflow: hidden;
+}
+.dijitColorPalette {
+	border:1px solid #999;
+	background:#fff;
+	-moz-border-radius:3pt;
+}
+img.dijitColorPaletteUnder {
+	border-style:none;
+	position:absolute;
+	left:0;
+	top:0;
+}
+.dijitColorPaletteInner {
+	position: relative;
+	overflow:hidden;
+	outline:0;
+}
+.dijitPaletteCell {
+	width: 20px;
+	height: 20px;
+	position: absolute;
+	overflow: hidden;
+	z-index: 10;
+	outline-width: 0;
+}
+.dijitPaletteImg {
+	width: 16px; 
+	height: 14px; 
+	position: absolute;
+	top: 1px;
+	left: 1px;
+	overflow: hidden;
+	cursor: default;
+	border:1px solid #999;
+	
+}
+.dijitPaletteCellHighlight img {
+	width: 14px; 
+	height: 12px; 
+	position: absolute;
+	top: 1px;
+	left: 1px;
+	overflow: hidden;
+	cursor: default;
+	border:2px solid #000;
+	outline:1px solid #dedede;
+		
+}
+.dijit_a11y .dijitPaletteCell {
+	background-color:transparent !important;
+}
+.dijit_a11y .dijitPaletteImg {
+	background-color:transparent !important;
+}
+.dijitAccordionContainer {
+	border:1px solid #b7b7b7;
+	border-top:0 !important;
+}
+.dijitAccordionTitle {
+	cursor: pointer;
+}
+.dijitAccordionTitle .arrowTextUp,
+.dijitAccordionTitle .arrowTextDown {
+	display: none;
+	font-size: 0.65em;
+	font-weight: normal !important;
+}
+.dijit_a11y .dijitAccordionTitle .arrowTextUp {
+	display: inline;
+}
+.dijit_a11y .dijitAccordionTitle-selected .arrowTextDown {
+	display: inline;
+}
+.dijit_a11y .dijitAccordionTitle-selected .arrowTextUp {
+	display: none;
+}
+.dijitCalendarContainer thead tr th, .dijitCalendarContainer thead tr td, .dijitCalendarContainer tbody tr td, .dijitCalendarContainer tfoot tr td {
+	padding: 0;
+}
+.dijitCalendarNextYear {
+	margin:0 0 0 0.55em;
+}
+.dijitCalendarPreviousYear {
+	margin:0 0.55em 0 0;
+}
+.dijitCalendarIncrementControl {
+	cursor:pointer;
+	vertical-align: middle;
+}
+.dijitCalendarDisabledDate {
+	color:gray !important;
+}
+.dijitCalendarBodyContainer tbody tr td {
+	cursor:pointer;
+}
+.dijitCalendarPreviousMonthDisabled,
+.dijitCalendarCurrentMonthDisabled,
+.dijitCalendarNextMonthDisabled {
+	cursor:default !important
+}
+.dijitCalendarDateTemplate,
+.dijitCalendarSelectedYear,
+.dijitCalendarNextYear,
+.dijitCalendarPreviousYear {
+	cursor:pointer;
+}
+.dijitCalendarMonthLabelSpacer {
+	
+  	position: relative;
+  	height: 1px;
+  	overflow: hidden;
+  	visibility: hidden;
+}
+.dijitMenu {
+	border:1px solid black;
+	background-color:white;
+}
+.dijitMenuTable {
+	margin:1px 0;
+	border-collapse:collapse;
+	border-width:0;
+	background-color:white;
+}
+.dj_webkit .dijitMenuTable td[colspan="2"]{
+	border-right:hidden;
+}
+.dijitMenuItem{
+	text-align: left;
+	white-space: nowrap;
+	padding:.1em .2em;
+	cursor:pointer;
+}
+.dijitMenuPassive .dijitMenuItemHover,
+.dijitMenuItemSelected {
+	
+	background-color:black;
+	color:white;
+}
+.dijitMenuItemIcon, .dijitMenuExpand {
+	background-repeat: no-repeat;
+}
+.dijitMenuItemDisabled * {
+	
+	opacity:0.3;
+	cursor:default;
+}
+.dj_ie .dijit_a11y .dijitMenuItemDisabled td,
+.dj_ie .dijitMenuItemDisabled *,
+.dj_ie .dijitMenuItemDisabled td {
+	color:gray !important;
+	filter: alpha(opacity=35);
+}
+.dijitMenuItemLabel {
+	position: relative;
+	vertical-align: middle;
+}
+.dijit_a11y .dijitMenuItemSelected .dijitMenuItemLabel {
+	border-width: 1px;
+	border-style: solid;
+}
+.dijit_a11y .dijitMenuItemSelected {
+	border: 1px #fff dotted !important;
+}
+.dijitMenuExpandA11y {
+	display: none;
+}
+.dijit_a11y .dijitMenuExpandA11y {
+	display: inline;
+}
+.dijitMenuSeparator td {
+	border: 0;
+	padding: 0;
+}
+.dijitMenuSeparatorTop {
+	height: 50%;
+	margin: 0;
+	margin-top:3px;
+	font-size: 1px;
+}
+.dijitMenuSeparatorBottom {
+	height: 50%;
+	margin: 0;
+	margin-bottom:3px;
+	font-size: 1px;
+}
+.dijitCheckedMenuItemIconChar {
+	vertical-align: middle;
+	visibility:hidden;
+}
+.dijitCheckedMenuItemChecked .dijitCheckedMenuItemIconChar {
+	visibility: visible;
+}
+.dijit_a11y .dijitCheckedMenuItemIconChar {
+	display:inline !important;
+}
+.dijit_a11y .dijitCheckedMenuItemIcon {
+	display: none;
+}
+.dijitStackController .dijitToggleButtonChecked * {
+	cursor: default;	
+}
+.dijitTabContainerBottom-tabs,
+.dijitTabContainerTop-tabs,
+.dijitTabContainerLeft-tabs,
+.dijitTabContainerRight-tabs {
+	z-index:10;
+	overflow: visible !important;  
+}
+.dijitTabContainerBottom-container,
+.dijitTabContainerTop-container,
+.dijitTabContainerLeft-container,
+.dijitTabContainerRight-container {
+	z-index:0;
+	overflow: hidden;
+	border: 1px solid black;
+}
+.dijitTabContainerTop-tabs {
+	border-bottom: 1px solid black;
+}
+.dijitTabContainerTop-container {
+	border-top: 0px;
+}
+.dijitTabContainerLeft-tabs {
+	border-right: 1px solid black;
+}
+.dijitTabContainerLeft-container {
+	border-left: 0px;
+}
+.dijitTabContainerBottom-tabs {
+	border-top: 1px solid black;
+}
+.dijitTabContainerBottom-container {
+	border-bottom: 0px;
+}
+.dijitTabContainerRight-tabs {
+	border-left: 1px solid black
+}
+.dijitTabContainerRight-container {
+	border-right: 0px;
+}
+.dijitTab {
+	position:relative;
+	cursor:pointer;
+	white-space:nowrap;
+	z-index:3;
+}
+.dijitTabChecked {
+	cursor: default;	
+}
+.dijitTabContainerTop-tabs .dijitTab {
+	top: 1px;	
+}
+.dijitTabContainerBottom-tabs .dijitTab {
+	top: -1px;	
+}
+.dijitTabContainerLeft-tabs .dijitTab {
+	left: 1px;	
+}
+.dijitTabContainerRight-tabs .dijitTab {
+	left: -1px;	
+}
+.dijitTabContainerTop-tabs .dijitTab,
+.dijitTabContainerBottom-tabs .dijitTab {
+	
+	display:-moz-inline-box;		
+	display:inline-block;			
+	#zoom: 1; 
+	#display:inline; 
+}
+.dijitTabInnerDiv {
+	position:relative;
+}
+.dijitTab .closeText {
+	display:none;
+}
+.dijit_a11y .closeText {
+	display:inline;
+	margin: 0px 6px;
+}
+.dijit_a11y .dijitTab .closeImage {
+	display:none;
+}
+.dijit_a11y .closeButton-hover .closeText {
+	border:thin solid;
+}
+.dijit_a11y .dijitTabChecked {
+	border-style:dashed !important;
+}
+.dijit_a11y .dijitTabInnerDiv {
+	border-left:none !important;
+ }
+.dijitTabPane,
+.dijitStackContainer-child,
+.dijitAccordionContainer-child {
+	
+    border: none !important;
+}
+.dijitInlineEditor {
+	
+	position:relative;
+	vertical-align:bottom;
+}
+.dj_ie .dijitInlineEditor {
+	vertical-align:middle;
+}
+.dijitInlineValue {
+	
+}
+.dijitInlineEditor .dijitButtonContainer {
+	
+	position:absolute;
+	right:0;
+	overflow:visible;
+}
+.dijitInlineEditor .saveButton,
+.dijitInlineEditor .cancelButton {
+}
+.dijitTreeRow, .dijitTreeContent {
+	white-space: nowrap;
+}
+.dijitTreeRow img {
+	
+	vertical-align: middle;
+}
+.dijitTreeContent {
+    cursor: default;
+}
+.dijitExpandoText {
+	display: none;
+}
+.dijit_a11y .dijitExpandoText {
+	display: inline;
+	padding-left: 10px;
+	padding-right: 10px;
+	font-family: monospace;
+	border-style: solid;
+	border-width: thin;
+	cursor: pointer;
+}
+.dijitTreeLabel {
+	margin: 0px 4px;
+}
+.dijitDialog {
+	position: absolute;
+	z-index: 999;
+	padding: 1px;
+     overflow: hidden;       
+}
+.dj_ff2 .dijitDialog {
+     overflow: auto;          
+}
+.dijitDialogFixed div.dijitDialogTitleBar {
+	cursor:default; 
+}
+.dijitDialogUnderlayWrapper {
+	position: absolute;
+	left: 0;
+	top: 0;
+	z-index: 998;
+	display: none;
+	background: transparent !important;
+}
+.dijitDialogUnderlay {
+	background: #eee;
+	opacity: 0.5;
+}
+.dj_ie .dijitDialogUnderlay {
+	filter: alpha(opacity=50);
+}
+.dijit_a11y .dijitInputLayoutContainer,
+.dijit_a11y .dijitDialog {
+	opacity: 1 !important;
+	background-color: white !important;
+}
+.dijitDialog .closeText {
+	display:none;
+	
+	position:absolute;
+}
+.dijit_a11y .dijitDialog .closeText {
+	display:inline;
+}
+.dijitSliderMoveable {
+	z-index:99;
+	position:absolute !important;
+	display:block;
+	vertical-align:middle;
+}
+.dijitSliderMoveableH {
+	right:0;
+}
+.dijit_a11y div.dijitSliderImageHandle,
+.dijitSliderImageHandle {
+	margin:0;
+	padding:0;
+	position:absolute !important;
+	border:8px solid gray;
+	width:0;
+	height:0;
+}
+.dijit_a11y .dijitSliderFocused .dijitSliderImageHandle {
+	border:4px solid #000;
+	height:8px;
+	width:8px;
+}
+.dijitSliderImageHandleV {
+	top:-8px;
+	left:-6px;
+}
+.dijitSliderImageHandleH {
+	left:-8px;
+	top:-5px;
+	vertical-align:top;
+}
+.dijitSliderBar {
+	border-style:solid;
+	border-color:black;
+}
+.dijitSliderBarContainerV {
+	position:relative;
+	height:100%;
+	z-index:1;
+}
+.dijitSliderBarContainerH {
+	position:relative;
+	z-index:1;
+}
+.dijitSliderBarH {
+	height:4px;
+	border-width:1px 0;
+}
+.dijitSliderBarV {
+	width:4px;
+	border-width:0 1px;
+}
+.dijitSliderProgressBar {
+	background-color:red;
+	z-index:1;
+}
+.dijitSliderProgressBarV {
+	position:static !important;
+	height:0%;
+	vertical-align:top;
+	text-align:left;
+}
+.dijitSliderProgressBarH {
+	position:absolute !important;
+	width:0%;
+	vertical-align:middle;
+	overflow:visible;
+}
+.dijitSliderRemainingBar {
+	overflow:hidden;
+	background-color:transparent;
+	z-index:1;
+}
+.dijitSliderRemainingBarV {
+	height:100%;
+	text-align:left;
+}
+.dijitSliderRemainingBarH {
+	width:100% !important;
+}
+.dijitSliderBumper {
+	overflow:hidden;
+	z-index:1;
+}
+.dijitSliderBumperV {
+	width:4px;
+	height:8px;
+	border-width:0 1px;
+}
+.dijitSliderBumperH {
+	width:8px;
+	height:4px;
+	border-width:1px 0;
+}
+.dijitSliderBottomBumper,
+.dijitSliderLeftBumper {
+	background-color:red;
+}
+.dijitSliderTopBumper,
+.dijitSliderRightBumper {
+	background-color:transparent;
+}
+.dijitSliderDecorationH {
+	text-align:center;
+}
+.dijitSlider .dijitSliderButton {
+	font-family:monospace;
+	margin:0;
+	padding:0;
+	display:block;
+}
+.dijit_a11y .dijitSliderButtonInner {
+	visibility:visible !important;
+}
+.dijitSliderButtonContainer {
+	text-align:center;
+	height:0;
+}
+.dijitSlider .dijitButtonNode {
+	padding:0;
+	display:block;
+}
+.dijitRuleContainer {
+	position:relative;
+	overflow:visible;
+}
+.dijitRuleContainerV {
+	height:100%;
+	line-height:0;
+	float:left;
+	text-align:left;
+}
+.dj_opera .dijitRuleContainerV {
+	line-height:2%;
+}
+.dj_ie .dijitRuleContainerV {
+	line-height:normal;
+}
+.dj_gecko .dijitRuleContainerV {
+	margin:0 0 1px 0; 
+}
+.dijitRuleMark {
+	position:absolute;
+	border:1px solid black;
+	line-height:0;
+	height:100%;
+}
+.dijitRuleMarkH {
+	width:0;
+	border-top-width:0 !important;
+	border-bottom-width:0 !important;
+	border-left-width:0 !important;
+}
+.dijitRuleLabelContainer {
+	position:absolute;
+}
+.dijitRuleLabelContainerH {
+	text-align:center;
+	display:inline-block;
+}
+.dijitRuleLabelH {
+	position:relative;
+	left:-50%;
+}
+.dijitRuleMarkV {
+	height:0;
+	border-right-width:0 !important;
+	border-bottom-width:0 !important;
+	border-left-width:0 !important;
+	width:100%;
+	left:0;
+}
+.dj_ie .dijitRuleLabelContainerV {
+	margin-top:-.55em;
+}
+.dijit_a11y .dijitButtonContents .dijitButtonText {
+	display: inline !important;
+}
+.dijitTextArea {
+	width:100%;
+	overflow-y: auto;	
+}
+.dijitTextArea[cols] {
+	width:auto; 
+}
+.dj_ie .dijitTextAreaCols {
+	width:auto;
+}
+.dijitTextArea > DIV {
+	text-decoration:none;
+	overflow:auto;
+	min-height: 1.40em;
+}
+.dj_ie .dijitTextArea p {
+	margin-top:0;
+	margin-bottom:0;
+	line-height: normal !important;
+}
+.dijitToolbarSeparator {
+	height: 18px;
+	width: 5px;
+	padding: 0 1px;
+	margin: 0;
+}
+.dijitIEFixedToolbar {
+	position:absolute;
+	
+	top: expression(eval((document.documentElement||document.body).scrollTop));
+}
+.RichTextEditable {
+	display: block;	
+}
+.dijitTimePickerItemInner {
+	text-align:center;
+	border:0;
+	padding:2px 8px 2px 8px;
+}
+.dijitTimePickerTick,
+.dijitTimePickerMarker {
+	border-bottom:1px solid gray;
+}
+.dijitTimePicker .dijitDownArrowButton {
+	border-top: none !important;
+}
+.dijitTimePickerTick {
+	color:#CCC;
+}
+.dijitTimePickerMarker {
+	color:black;
+	background-color:#CCC;
+}
+.dijitTimePickerItemSelected {
+	font-weight:bold;
+	color:#333;
+	background-color:#b7cdee;
+}
+.dijitTimePickerItemHover {
+	background-color:gray;
+	color:white;
+	cursor:pointer;
+}
+.dijit_a11y .dijitTimePickerItem {
+	border-bottom:1px solid #333;	
+}
+.dijitToggleButtonIconChar {
+	display:none !important;
+}
+.dijit_a11y .dijitToggleButtonIconChar {
+	display:inline !important;
+}
+.dijit_a11y .dijitToggleButtonIconChar {
+	visibility:hidden;
+}
+.dijit_a11y .dijitToggleButtonChecked .dijitToggleButtonIconChar {
+	visibility:visible !important;
+}
+.dijitArrowButtonChar {
+	display:none !important;
+}
+.dijit_a11y .dijitArrowButtonChar {
+	display:inline !important;
+}
+.dijitInputLayoutContainer {
+	position: relative;
+	overflow: hidden;
+}
+.dijitSpinnerButtonContainer {
+	float: right;
+	width: 18px;
+	position: relative;
+	overflow: hidden;
+}
+.dijitSpinner .dijitInputLayoutContainer .dijitArrowButton {
+	height: 50%;
+	width: 16px;
+	overflow: hidden;
+}
+.dijitSpinner .dijitInputLayoutContainer .dijitArrowButtonInner {
+	overflow: hidden;
+	line-height: 50%;
+}
+.dijit_a11y .dijitSpinner .dijitInputLayoutContainer .dijitArrowButton {
+	width: 100%;
+}
+.dijit_a11y .dijitSpinner .dijitArrowButton .dijitArrowButtonChar {
+	font-size: 0.4em;
+	vertical-align: top;
+}
+.dijit_a11y .dijitSpinnerButtonContainer {
+	width: 0.5em;
+	margin-left: 2px;
+	overflow: visible;
+}
+.dijit_a11y .dijitSpinnerButtonContainer .dijitButtonNode {
+	border-width: 1px 0px 0px 1px;
+	border-style: solid !important;
+}
diff --git a/dijit/themes/dijit_rtl.css b/dijit/themes/dijit_rtl.css
new file mode 100644
index 0000000..a125d1d
--- /dev/null
+++ b/dijit/themes/dijit_rtl.css
@@ -0,0 +1,76 @@
+.dj_gecko-rtl .dijitInputField {
+	direction: ltr; 
+}
+.dj_gecko-rtl .dijitInputField * {
+	direction: rtl; 
+}
+.dijitRtl .dijitMenuItem {
+	text-align: right;
+}
+.dijitRtl .dijitComboBox .dijitInputField {
+	border-right-width:1px !important;
+	border-left-width:0 !important;
+}
+.dijitRtl .dijitCalendarNextYear {
+	margin:0 0.55em 0 0;
+}
+.dijitRtl .dijitCalendarPreviousYear {
+	margin:0 0 0 0.55em;
+}
+.dijitRtl .dijitProgressBarFull .dijitProgressBarLabel {
+	right:0; 
+}
+.dijitRtl .dijitSliderImageHandleV {
+	left:auto;
+	right:-6px;
+}
+.dj_ie-rtl .dijitSliderImageHandleV {
+	right:-10px;
+}
+.dijitRtl .dijitSliderMoveableH {
+	right:auto;
+	left:0;
+}
+.dijitRtl .dijitRuleContainerV {
+	float:right;
+}
+.dj_gecko-rtl .dijitRuleContainerV {
+	float:left;
+}
+.dj_ie-rtl .dijitRuleContainerV {
+	text-align:right;
+}
+.dj_ie-rtl .dijitRuleLabelV {
+	text-align:left;
+}
+.dj_ie-rtl .dijitRuleLabelH {
+	zoom:1;
+}
+.dj_ie-rtl .dijitSliderProgressBarH {
+	right:0;
+	left:auto;
+}
+.dj_gecko-rtl .dijitSliderProgressBarH {
+	float:right;
+	right:0;
+	left:auto;
+}
+.dijitRtl .dijitSpinner .dijitInputLayoutContainer .dijitArrowButton {
+	right: auto;
+	left: 0;
+	border-width: 0 1px 0 0 !important;
+}
+.dijitRtl .dijitSpinnerButtonContainer {
+	float: left;
+}
+.dijitRtl .dijit_a11y .dijitSpinnerButtonContainer {
+	margin-left: none;
+	margin-right: 2px;
+}
+.dijitRtl DIV.dijitArrowButton, .dijitRtl .dijitValidationIcon, .dijitRtl .dijitValidationIconText {
+	float: left;
+}
+.dijitRtl .dijitContentPaneLoading, .dijitRtl .dijitContentPaneError {
+	background-position:right;
+	padding-right:25px;
+}
diff --git a/dijit/themes/nihilo/Calendar.css b/dijit/themes/nihilo/Calendar.css
new file mode 100644
index 0000000..6fd45e0
--- /dev/null
+++ b/dijit/themes/nihilo/Calendar.css
@@ -0,0 +1,131 @@
+
+	
+.nihilo .dijitCalendarIncrementControl {
+	
+	width:15px;
+	height:15px;
+	background-image: url("images/spriteRoundedIconsSmall.png");
+	background-repeat: no-repeat
+}
+.dj_ie6 .nihilo .dijitCalendarIncrementControl {
+	font-size:.1em;
+	background-image: url("images/spriteRoundedIconsSmall.gif");
+}
+.nihilo .dijitA11ySideArrow {
+	display: none;
+}
+.nihilo .dijitCalendarDecrease {
+	background-position: top left;
+}
+.nihilo .dijitCalendarIncrease {
+	background-position: -30px top;
+}
+.nihilo table.dijitCalendarContainer {
+	font-size: 100%;
+	border-spacing: 0;
+	border-collapse: separate;
+	border: 1px solid #ccc;
+	margin: 0;
+}
+.nihilo .dijitCalendarMonthContainer th {
+	
+	background:#d3d3d3 url("images/titleBar.png") repeat-x top;
+	padding-top:.3em;
+	padding-bottom:.2em;
+	text-align:center;
+}
+.dj_ie6 .nihilo .dijitCalendarMonthContainer th {
+	padding-top:.2em;
+	padding-bottom:.1em;
+	
+}
+.nihilo .dijitCalendarDayLabelTemplate {
+	
+	background:#fefefe;
+	font-weight:normal;
+	padding-top:.15em;
+	padding-bottom:.2em;
+	border-bottom: 1px solid #eeeeee;
+	color:#293a4b;
+	text-align:center;
+}
+.nihilo .dijitCalendarBodyContainer {
+	border-bottom: 1px solid #eeeeee;	
+}
+.nihilo .dijitCalendarMonthLabel {
+	color:#293a4b;
+	font-weight: bold;
+}
+.nihilo .dijitCalendarDateTemplate {
+	
+	font-size: 0.9em;
+	font-weight: bold;
+	text-align: center;
+	padding: 0.3em 0.3em 0.05em 0.3em;
+	letter-spacing: 1px;
+	background-color: #fdfdfd;
+	border:#fdfdfd solid 1px !important;
+}
+.dj_ie .nihilo .dijitCalendarDateTemplate {
+	padding: 0.1em .33em 0.02em .33em;
+}
+.nihilo .dijitCalendarPreviousMonth,
+.nihilo .dijitCalendarNextMonth 		{
+	
+	color:#999999;
+	background-color:#f5f5f5 !important;
+	border:#f5f5f5 solid 1px !important;
+}
+.nihilo .dijitCalendarPreviousMonthDisabled,
+.nihilo .dijitCalendarNextMonthDisabled	{
+	
+	background-color:#a4a5a6 !important;
+}
+.nihilo .dijitCalendarCurrentMonth {
+	
+}
+.nihilo .dijitCalendarCurrentMonthDisabled {
+		
+	background-color:#bbbbbc !important;
+}
+.nihilo .dijitCalendarDisabledDate {
+	
+	
+	text-decoration:line-through !important;
+	cursor:default !important;
+}
+.nihilo .dijitCalendarCurrentDate {
+	
+	text-decoration:underline;
+	font-weight:bold;
+}
+.nihilo .dijitCalendarSelectedDate {
+	
+	background-color:#ffe284 !important;
+	color:black !important;
+	border:#f7c95c solid 1px !important;
+}
+.nihilo .dijitCalendarYearContainer {
+	
+	background:white url("images/titleBar.png") repeat-x top;
+}
+.nihilo .dijitCalendarYearLabel {
+	
+	margin:0;
+	padding:0.4em 0 0.25em 0;
+	text-align:center;
+}
+.nihilo .dijitCalendarSelectedYear {
+	
+	color:black;
+	padding:0.2em;
+	padding-bottom:0.1em;
+	background-color:#ffe284 !important;
+	border:#f7c95c solid 1px !important;
+}
+.nihilo .dijitCalendarNextYear,
+.nihilo .dijitCalendarPreviousYear {
+	
+	color:black !important;
+	font-weight:normal;
+}
diff --git a/dijit/themes/nihilo/Calendar_rtl.css b/dijit/themes/nihilo/Calendar_rtl.css
new file mode 100644
index 0000000..245d93f
--- /dev/null
+++ b/dijit/themes/nihilo/Calendar_rtl.css
@@ -0,0 +1,7 @@
+
+.dijitRtl .nihilo .dijitCalendarDecrease {
+	background-position: -30px top;
+}
+.dijitRtl .nihilo .dijitCalendarIncrease {
+	background-position: 0px top;
+}
diff --git a/dijit/themes/nihilo/ColorPalette.css b/dijit/themes/nihilo/ColorPalette.css
new file mode 100644
index 0000000..328bc84
--- /dev/null
+++ b/dijit/themes/nihilo/ColorPalette.css
@@ -0,0 +1,5 @@
+.dijitColorPalette {
+	border:1px solid #d3d3d3;
+	background:#fff;
+	-moz-border-radius: 0px !important;
+}
diff --git a/dijit/themes/nihilo/Common.css b/dijit/themes/nihilo/Common.css
new file mode 100644
index 0000000..c894dea
--- /dev/null
+++ b/dijit/themes/nihilo/Common.css
@@ -0,0 +1,19 @@
+
+.nihilo .dojoDndItemBefore {
+	border-top: 2px solid #369;
+}
+.nihilo .dojoDndItemAfter {
+	border-bottom: 2px solid #369;
+}
+.nihilo .dojoDndItemOver {
+	cursor:pointer;
+}
+.nihilo table.dojoDndAvatar { -moz-border-radius: 0; border: 1px solid #ccc; border-collapse: collapse; background-color: #fff; font-size: 75%; color: black;}
+.nihilo .dojoDndAvatar td	{ border: none; }
+.nihilo .dojoDndAvatar tr	{ border: none; }
+.nihilo .dojoDndAvatarHeader td	{ height: 20px; padding: 0 0 0 21px; }
+.nihilo .dojoDndAvatarItem td { padding: 2px;}
+.nihilo.dojoDndMove .dojoDndAvatarHeader	{background-color: #f58383; background-image: url(images/dndNoMove.png); background-repeat: no-repeat; background-position: 2px center;}
+.nihilo.dojoDndCopy .dojoDndAvatarHeader	{background-color: #f58383; background-image: url(images/dndNoCopy.png); background-repeat: no-repeat; background-position: 2px center;}
+.nihilo.dojoDndMove .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{background-color: #97e68d; background-image: url(images/dndMove.png); background-repeat: no-repeat; background-position: 2px center;}
+.nihilo.dojoDndCopy .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{background-color: #97e68d; background-image: url(images/dndCopy.png); background-repeat: no-repeat; background-position: 2px center;}
diff --git a/dijit/themes/nihilo/Dialog.css b/dijit/themes/nihilo/Dialog.css
new file mode 100644
index 0000000..d40eba3
--- /dev/null
+++ b/dijit/themes/nihilo/Dialog.css
@@ -0,0 +1,131 @@
+
+.nihilo .dijitDialog {
+	background: #eee;
+	border: 1px solid #d3d3d3;
+	-webkit-box-shadow: 0px 5px 10px #adadad;
+	padding: 0px;
+}
+.nihilo .dijitDialog .dijitDialogTitle {
+	
+	font-size: 0.9em;
+	color: #3243C5F;
+	font-weight: bold;
+	padding: 0px 4px;
+}
+.nihilo .dijitDialog .dijitDialogPaneContent {
+	background: #ffffff;
+	border:none;
+	border-top: 1px solid #d3d3d3; 
+	padding:10px;
+}
+.nihilo .dijitDialogTitleBar {
+	
+	background: #fafafa url("images/titleBar.png") repeat-x top left;
+	padding: 5px 6px 3px 6px;
+	cursor: move;
+	outline:0; 
+}
+.nihilo .dijitDialogCloseIcon {
+	
+	background-image: url("images/spriteRoundedIconsSmall.png");
+	background-repeat: no-repeat;
+	background-position: -60px 0px;
+	position: absolute;
+	vertical-align: middle;
+	right: 6px;
+	top: 4px;
+	height: 15px;
+	width: 15px;
+	cursor: pointer;
+}
+.dj_ie6 .nihilo .dijitDialogCloseIcon {
+	background-image: url("images/spriteRoundedIconsSmall.gif");
+}
+.nihilo .dijitDialogCloseIcon-hover {
+	background-position: -60px -15px;
+}
+.nihilo .dijitTooltip,
+.nihilo .dijitTooltipDialog {
+	
+	background: transparent;	
+}
+.dijitTooltipBelow {
+	
+	padding-top: 10px;
+}
+.dijitTooltipAbove {
+	
+	padding-bottom: 10px;
+}
+.nihilo .dijitTooltipContainer {
+	
+	background-color: #fff;
+	border:1px solid #d3d3d3;
+	padding:0.45em;
+}
+.nihilo .dijitTooltipConnector {
+	
+	border:0px;
+	z-index: 2;
+}
+.nihilo .dijitTooltipABRight .dijitTooltipConnector {
+	
+	left: auto !important;
+	right: 6px;
+}
+.nihilo .dijitTooltipBelow .dijitTooltipConnector {
+	
+	top: 0px;
+	left: 6px;
+	background:url("images/tooltipConnectorUp.png") no-repeat top left;
+	width:17px;
+	height:11px;
+}
+.dj_ie6 .nihilo .dijitTooltipBelow .dijitTooltipConnector {
+	background-image: url("images/tooltipConnectorUp.gif");
+}
+.nihilo .dijitTooltipAbove .dijitTooltipConnector {
+	
+	bottom: 0px;
+	left: 6px;
+	background:url("images/tooltipConnectorDown.png") no-repeat top left;
+	width:17px;
+	height:11px;
+}
+.dj_ie6 .nihilo .dijitTooltipAbove .dijitTooltipConnector {
+	background-image: url("images/tooltipConnectorDown.gif");
+}
+.dj_ie6 .nihilo .dijitTooltipAbove .dijitTooltipConnector {
+	bottom: -5px;
+}
+.nihilo .dijitTooltipLeft {
+	padding-right: 10px;
+}
+.dj_ie6 .nihilo .dijitTooltipLeft {
+	padding-left: 11px;
+}
+.nihilo .dijitTooltipLeft .dijitTooltipConnector {
+	
+	right: 0px;
+	bottom: 3px;
+	background:url("images/tooltipConnectorRight.png") no-repeat top left;
+	width:11px;
+	height:17px;
+}
+.dj_ie6 .nihilo .dijitTooltipLeft .dijitTooltipConnector {
+	background-image: url("images/tooltipConnectorRight.gif");
+}
+.nihilo .dijitTooltipRight {
+	padding-left: 10px;
+}
+.nihilo .dijitTooltipRight .dijitTooltipConnector {
+	
+	left: 0px;
+	bottom: 3px;
+	background:url("images/tooltipConnectorLeft.png") no-repeat top left;
+	width:11px;
+	height:17px;
+}
+.dj_ie6 .nihilo .dijitTooltipRight .dijitTooltipConnector {
+	background-image: url("images/tooltipConnectorLeft.gif");
+}
diff --git a/dijit/themes/nihilo/Dialog_rtl.css b/dijit/themes/nihilo/Dialog_rtl.css
new file mode 100644
index 0000000..105d504
--- /dev/null
+++ b/dijit/themes/nihilo/Dialog_rtl.css
@@ -0,0 +1,5 @@
+
+.dijitRtl .nihilo .dijitDialogTitleBar .dijitDialogCloseIcon {
+	right: auto;
+	left: 5px;
+}
diff --git a/dijit/themes/nihilo/Editor.css b/dijit/themes/nihilo/Editor.css
new file mode 100644
index 0000000..6d618ea
--- /dev/null
+++ b/dijit/themes/nihilo/Editor.css
@@ -0,0 +1,61 @@
+.dijitIEFixedToolbar {
+	position:absolute;
+	
+	top: expression(eval((document.documentElement||document.body).scrollTop));
+}
+.nihilo .dijitToolbar .dijitToolbarSeparator {
+	background: url('images/editor.gif');
+}
+.nihilo .dijitEditorIcon {
+	background-image: url('images/editor.gif'); 
+	background-repeat: no-repeat;
+	width: 18px;
+	height: 18px;
+	text-align: center;
+}
+.nihilo .dijitDisabled .dijitEditorIcon {
+	background-image: url('images/editorDisabled.gif'); 
+}
+.nihilo .dijitEditorIconSep { background-position: 0px; }
+.nihilo .dijitEditorIconBackColor { background-position: -18px; }
+.nihilo .dijitEditorIconBold { background-position: -36px; }
+.nihilo .dijitEditorIconCancel { background-position: -54px; }
+.nihilo .dijitEditorIconCopy { background-position: -72px; }
+.nihilo .dijitEditorIconCreateLink { background-position: -90px; }
+.nihilo .dijitEditorIconCut { background-position: -108px; }
+.nihilo .dijitEditorIconDelete { background-position: -126px; }
+.nihilo .dijitEditorIconForeColor { background-position: -144px; }
+.nihilo .dijitEditorIconHiliteColor { background-position: -162px; }
+.nihilo .dijitEditorIconIndent { background-position: -180px; }
+.nihilo .dijitEditorIconInsertHorizontalRule { background-position: -198px; }
+.nihilo .dijitEditorIconInsertImage { background-position: -216px; }
+.nihilo .dijitEditorIconInsertOrderedList { background-position: -234px; }
+.nihilo .dijitEditorIconInsertTable { background-position: -252px; }
+.nihilo .dijitEditorIconInsertUnorderedList { background-position: -270px; }
+.nihilo .dijitEditorIconItalic { background-position: -288px; }
+.nihilo .dijitEditorIconJustifyCenter { background-position: -306px; }
+.nihilo .dijitEditorIconJustifyFull { background-position: -324px; }
+.nihilo .dijitEditorIconJustifyLeft { background-position: -342px; }
+.nihilo .dijitEditorIconJustifyRight { background-position: -360px; }
+.nihilo .dijitEditorIconLeftToRight { background-position: -378px; }
+.nihilo .dijitEditorIconListBulletIndent { background-position: -396px; }
+.nihilo .dijitEditorIconListBulletOutdent { background-position: -414px; }
+.nihilo .dijitEditorIconListNumIndent { background-position: -432px; }
+.nihilo .dijitEditorIconListNumOutdent { background-position: -450px; }
+.nihilo .dijitEditorIconOutdent { background-position: -468px; }
+.nihilo .dijitEditorIconPaste { background-position: -486px; }
+.nihilo .dijitEditorIconRedo { background-position: -504px; }
+.nihilo .dijitEditorIconRemoveFormat { background-position: -522px; }
+.nihilo .dijitEditorIconRightToLeft { background-position: -540px; }
+.nihilo .dijitEditorIconSave { background-position: -558px; }
+.nihilo .dijitEditorIconSpace { background-position: -576px; }
+.nihilo .dijitEditorIconStrikethrough { background-position: -594px; }
+.nihilo .dijitEditorIconSubscript { background-position: -612px; }
+.nihilo .dijitEditorIconSuperscript { background-position: -630px; }
+.nihilo .dijitEditorIconUnderline { background-position: -648px; }
+.nihilo .dijitEditorIconUndo { background-position: -666px; }
+.nihilo .dijitEditorIconWikiword { background-position: -684px; }
+.nihilo .dijitEditorIconToggleDir { background-position: -540px; }
+.nihilo .dijitEditorIconTabIndent { background-position: -702px; }
+.nihilo .dijitEditorIconSelectAll { background-position: -720px; }
+.nihilo .dijitEditorIconUnlink { background-position: -738px; }
diff --git a/dijit/themes/nihilo/Editor_rtl.css b/dijit/themes/nihilo/Editor_rtl.css
new file mode 100644
index 0000000..7d77754
--- /dev/null
+++ b/dijit/themes/nihilo/Editor_rtl.css
@@ -0,0 +1,10 @@
+
+.dijitRtl .nihilo .dijitEditorIcon {
+	background-image: url('images/editor_rtl.gif'); 
+}
+.dijitRtl .nihilo .dijitDisabled .dijitEditorIcon {
+	background-image: url('images/editorDisabled_rtl.gif'); 
+}
+.dijitRtl .nihilo .dijitToolbar .dijitToolbarSeparator {
+	background-image: url('images/editor_rtl.gif');
+}
diff --git a/dijit/themes/nihilo/Menu.css b/dijit/themes/nihilo/Menu.css
new file mode 100644
index 0000000..b530a90
--- /dev/null
+++ b/dijit/themes/nihilo/Menu.css
@@ -0,0 +1,62 @@
+
+.nihilo .dijitMenu,
+.nihilo .dijitMenuBar {
+	border: 1px solid #d3d3d3;
+	margin: 0px;
+	padding: 0px;
+	background-color: #fff;
+}
+.nihilo .dijitBorderContainer .dijitMenuBar {
+	border: 1px #ccc solid;
+}
+.nihilo .dijitMenuItem {
+	font-family: sans-serif;
+	margin: 0px;
+	color: #243C5F;
+}
+.nihilo .dijitMenuBar .dijitMenuItem {
+	padding: 4px 5px;
+}
+.nihilo .dijitMenuPreviousButton, .nihilo .dijitMenuNextButton {
+	font-style: italic;
+}
+.nihilo .dijitMenuItem TD {
+	padding:1px;
+}
+.nihilo .dijitMenuPassive .dijitMenuItemHover,
+.nihilo .dijitMenuItemSelected {
+	background-color: #ffe284; 
+	color: #243C5F;
+}
+.nihilo .dijitMenuItemIcon {
+	width: 15px;
+	height: 15px;
+}
+.nihilo .dijitMenuExpand {
+	width:15px;
+	height:15px;
+	background-image: url('images/spriteRoundedIconsSmall.png');
+	background-position: -30px top;
+}
+.dj_ie6 .nihilo .dijitMenuExpand {
+	background-image:url('images/spriteRoundedIconsSmall.gif');
+}
+.nihilo .dijitMenuSeparator {
+	height: 1px;
+}
+.nihilo .dijitMenuSeparatorTop {
+	border-bottom: 1px solid #fff; 
+}
+.nihilo .dijitMenuSeparatorBottom {
+	border-top: 1px solid #d3d3d3;
+}
+.nihilo .dijitCheckedMenuItemIconChar {
+	display: none;
+}
+.nihilo .dijitCheckedMenuItemIcon {
+	background-image: url('images/spriteCheckbox.gif');
+	background-position: -80px;
+}
+.nihilo .dijitCheckedMenuItemChecked .dijitCheckedMenuItemIcon {
+	background-position: -64px;
+}
diff --git a/dijit/themes/nihilo/Menu_rtl.css b/dijit/themes/nihilo/Menu_rtl.css
new file mode 100644
index 0000000..06fccbf
--- /dev/null
+++ b/dijit/themes/nihilo/Menu_rtl.css
@@ -0,0 +1,8 @@
+
+.dijitRtl .nihilo .dijitMenuItem .dijitMenuItemIcon {
+	padding-left: 3px;
+	padding-right: 0px;
+}
+.dijitRtl .nihilo .dijitMenuItem .dijitMenuExpand {
+	background-position: 0px top;
+}
diff --git a/dijit/themes/nihilo/ProgressBar.css b/dijit/themes/nihilo/ProgressBar.css
new file mode 100644
index 0000000..7713aeb
--- /dev/null
+++ b/dijit/themes/nihilo/ProgressBar.css
@@ -0,0 +1,24 @@
+
+.nihilo .dijitProgressBar {
+	margin:2px 0px 2px 0px;
+}
+.nihilo .dijitProgressBarEmpty{
+	
+	background:#fff url("images/progressBarEmpty.png") repeat-x center center;
+	border-color: #f8d582 #f8d582 #f8d582 #f8d582;
+}
+.nihilo .dijitProgressBarTile{
+	
+	background:#f0f0f0 url("images/progressBarFull.png") repeat-x center center;
+}
+.nihilo .dijitProgressBarFull {
+	border-right:1px solid #f8d582;
+}
+.nihilo .dijitProgressBarLabel {
+	
+	color:#293a4b;
+}
+.nihilo .dijitProgressBarIndeterminate .dijitProgressBarTile {
+	
+	background:#cad2de url("images/progressBarAnim.gif") repeat-x center center;
+}
diff --git a/dijit/themes/nihilo/TimePicker.css b/dijit/themes/nihilo/TimePicker.css
new file mode 100644
index 0000000..70ee3b5
--- /dev/null
+++ b/dijit/themes/nihilo/TimePicker.css
@@ -0,0 +1,50 @@
+
+.nihilo .dijitTimePickerTick,
+.nihilo .dijitTimePickerMarker {
+	border-color: #eeeeee;
+}
+.nihilo .dijitTimePickerTick {
+	color:white;
+}
+.nihilo .dijitTimePickerMarker {
+	background:#d3d3d3 url("images/titleBar.png") repeat-x top;
+	color:#293a4b;
+	font-weight: bold;
+}
+.nihilo .dijitTimePickerItemSelected {
+	color: black;
+	background: #ffe284 none;
+}
+.nihilo .dijitTimePickerItemHover {
+	background: #d6d6dd none;
+	color:black;
+}
+.nihilo .dijitTimePickerItemHover,
+.nihilo .dijitTimePickerItemSelected {
+	position: relative;
+	z-index: 10;
+}
+.nihilo .dijitTimePickerTick .dijitTimePickerItemInner {
+	font-size:0.4em;
+}
+.nihilo .dijitTimePickerItemHover .dijitTimePickerItemInner,
+.nihilo .dijitTimePickerItemSelected .dijitTimePickerItemInner {
+	font-size:1em;
+}
+.nihilo .dijitTimePickerMarkerHover {
+	border-top: 1px solid #eeeeee;
+}
+.nihilo .dijitTimePickerTickHover,
+.nihilo .dijitTimePickerTickSelected {
+	margin-top:-0.3em;
+	margin-bottom:-0.3em;
+	border-bottom: none;
+}
+.dijit_a11y .dijitTimePickerTickHover {
+	background-color: #CCC !important;
+	border-top: 1px solid #333 !important;
+	border-bottom: 1px solid #333 !important;
+}
+.dijit_a11y .dijitTimePickerMarkerHover {
+	border-bottom-width: 2px;
+}
diff --git a/dijit/themes/nihilo/TitlePane.css b/dijit/themes/nihilo/TitlePane.css
new file mode 100644
index 0000000..576897e
--- /dev/null
+++ b/dijit/themes/nihilo/TitlePane.css
@@ -0,0 +1,68 @@
+ 
+ 
+.nihilo .dijitTitlePaneTitle {
+	background: #cccccc;
+	background:#fff url("images/titleBar.png") repeat-x top left;
+	border:1px solid #bfbfbf;
+	padding:3px 4px;
+	cursor: pointer;
+	font-size: 0.9em;
+	font-weight: bold;
+	color: #6d6d6d;
+}
+.nihilo .dijitTitlePaneTitle-hover  {
+	background: #f9f9f9 url("images/accordionItemActive.png") top repeat-x;
+}
+.nihilo .dijitTitlePaneTitle * {
+	vertical-align: middle;
+}
+.nihilo .dijitTitlePane .dijitArrowNode {
+	width:15px;
+	height:15px;
+}
+.nihilo .dijitTitlePaneFocused .dijitTitlePaneTextNode {
+	color: #243C5F;
+}
+.nihilo .dijitOpen .dijitTitlePaneTextNode {
+	color: #243C5F;
+}
+.nihilo .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background: url('images/spriteRoundedIconsSmall.png') no-repeat -30px top;
+}
+.dj_ie6 .nihilo .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background:url('images/spriteRoundedIconsSmall.gif') no-repeat -30px top;
+}
+.nihilo .dijitTitlePane .dijitOpen .dijitArrowNode {
+	background:url('images/spriteRoundedIconsSmall.png') no-repeat -15px top;
+}
+.dj_ie6 .nihilo .dijitTitlePane .dijitOpen .dijitArrowNode {
+	background:url('images/spriteRoundedIconsSmall.gif') no-repeat -15px top;
+}
+.nihilo .dijitTitlePane .dijitArrowNodeInner {
+	display:none;
+}
+.dijit_a11y .dijitTitlePane .dijitArrowNodeInner {
+	display:inline !important;
+	font-family:monospace;
+	cursor: pointer;
+	padding-bottom:.2em;
+}
+.dijit_a11y .dijitTitlePane .dijitArrowNode {
+	display:none;
+}
+.nihilo .dijitTitlePaneContentOuter {
+	background: #ffffff;
+	border:1px solid #bfbfbf;
+	border-top: 0px solid #3d3d3d;	
+}
+.nihilo .dijitTitlePaneContentInner {
+	padding:10px;
+}
+.dj_ie6 .nihilo .dijitTitlePaneContentOuter,
+.dj_ie6 .nihilo .dijitTitlePane .dijitTitlePaneTitle {
+	zoom: 1;
+}
+.nihilo .dijitTitlePaneTextNode {
+	margin-left: 4px;
+	margin-right: 4px;
+}
diff --git a/dijit/themes/nihilo/TitlePane_rtl.css b/dijit/themes/nihilo/TitlePane_rtl.css
new file mode 100644
index 0000000..a8aef83
--- /dev/null
+++ b/dijit/themes/nihilo/TitlePane_rtl.css
@@ -0,0 +1,6 @@
+.dijitRtl .nihilo .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background-position: 0px top;
+}
+.dj_ie6-rtl .nihilo .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background-position: 0px top;
+}
diff --git a/dijit/themes/nihilo/Toolbar.css b/dijit/themes/nihilo/Toolbar.css
new file mode 100644
index 0000000..4013f1c
--- /dev/null
+++ b/dijit/themes/nihilo/Toolbar.css
@@ -0,0 +1,58 @@
+.nihilo .dijitToolbar {
+	border-bottom: 1px solid #ccc;
+	background:#eaeaea url("images/titleBar.png") repeat-x top left;
+}
+.dj_ie6 .nihilo .dijitToolbar {
+	height: 10px;
+}
+.nihilo .dijitToolbar .dijitButtonNode,
+.nihilo .dijitToolbar .dijitComboButton .dijitButtonContents,
+.nihilo .dijitToolbar .dijitComboButton .dijitDownArrowButton {
+	background: none;
+	margin: 0px;
+	padding: 0px;
+	border: none;
+	font-size: 12px;
+}
+.nihilo .dijitToolbar .dijitButton,
+.nihilo .dijitToolbar .dijitToggleButton,
+.nihilo .dijitToolbar .dijitDropDownButton,
+.nihilo .dijitToolbar .dijitComboButton .dijitButtonContents,
+.nihilo .dijitToolbar .dijitComboButton .dijitDownArrowButton {
+	background: none;	
+	padding: 1px;	
+}
+.nihilo .dijitToolbar .dijitButtonChecked,
+.nihilo .dijitToolbar .dijitToggleButtonChecked {
+	background-color:#ffeeb9;
+	border:1px solid #f7c95c;
+	padding: 0;
+}
+.nihilo .dijitToolbar .dijitButtonCheckedHover,
+.nihilo .dijitToolbar .dijitToggleButtonCheckedHover
+ {
+	background-color:#ffe284;
+	border:1px solid #f7c95c;
+	padding: 0;
+}
+.nihilo .dijitToolbar .dijitButtonHover,
+.nihilo .dijitToolbar .dijitToggleButtonHover,
+.nihilo .dijitToolbar .dijitDropDownButtonHover,
+.nihilo .dijitToolbar .dijitComboButtonHover .dijitButtonContents,
+.nihilo .dijitToolbar .dijitComboButtonDownArrowHover .dijitDownArrowButton {
+	
+	border: 1px solid #f7c95c;
+	padding: 0;
+	background-color:#ffe284;
+}
+.nihilo .dijitToolbar label {	
+	padding: 3px 3px 0 6px;
+}
+.dj_ie .nihilo .dijitToolbar .dijitComboButton .dijitButtonContentsFocused,
+.dj_ie .nihilo .dijitToolbar .dijitComboButton .dijitDownArrowButtonFocused,
+.dj_ff2 .nihilo.dijitToolbar .dijitComboButton .dijitButtonContentsFocused,
+.dj_ff2 .nihilo .dijitToolbar .dijitComboButton .dijitDownArrowButtonFocused {
+	
+	border: 1px #555 dotted !important;
+	padding: 0px;
+}
diff --git a/dijit/themes/nihilo/Tree.css b/dijit/themes/nihilo/Tree.css
new file mode 100644
index 0000000..668c9d4
--- /dev/null
+++ b/dijit/themes/nihilo/Tree.css
@@ -0,0 +1,87 @@
+
+.nihilo .dijitTreeNode {
+    background : url('images/treeI.gif') no-repeat;
+    background-position : top left;
+    background-repeat : repeat-y;
+    zoom: 1;	
+}
+.nihilo .dijitTreeIsLast {
+    background: url('images/treeI_half.gif') no-repeat;
+}
+.nihilo .dijitTreeNodeHover {
+	
+	background-image: url(images/treeHover.png);
+	background-repeat: repeat;
+	background-color: none !important;
+}
+.nihilo .dijitTreeLabel {
+	font-weight: normal;
+	margin-left: 3px;	
+}
+.nihilo .dijitTreeIsRoot {
+    margin-left: 0;
+    background-image: none;
+}
+.nihilo .dijitTreeExpando {
+    width: 18px;
+    height: 18px;
+}
+.nihilo .dijitTreeRow {
+	
+	padding-bottom: 2px;
+}
+.nihilo .dijitTreeContent {
+    min-height: 18px;
+    min-width: 18px;
+    padding-left:1px;
+}
+.nihilo .dijitTreeExpand {
+    width: 18px;
+    height: 18px;
+    background-repeat : no-repeat;
+}
+.nihilo .dijitTreeNodeEmphasized {
+    background-color: Highlight;
+    color: HighlightText;
+}
+.nihilo .dijitTreeLabelFocused {
+	outline: 1px invert dotted;
+}
+.nihilo .dijitTreeExpandoOpened {
+	background: url('images/spriteTree.gif') no-repeat -18px top;
+}
+.nihilo .dijitTreeExpandoClosed {
+	background-image: url('images/spriteTree.gif');
+}
+.nihilo .dijitTreeExpandoLeaf {
+	background: url('images/spriteTree.gif') no-repeat -36px top;
+}
+.nihilo .dijitTreeExpandoLoading {
+	background-image: url('images/treeExpand_loading.gif');
+}
+.nihilo .dijitTreeIcon {
+	width: 16px;
+	height: 16px;
+}
+.nihilo .dijitFolderOpened {
+	background: url('images/spriteDivIcons.gif') no-repeat -16px top;
+}
+.nihilo .dijitFolderClosed {
+	background: url('images/spriteDivIcons.gif') no-repeat top left;
+}
+.nihilo .dijitLeaf {
+	background: url('images/spriteDivIcons.gif') no-repeat -32px top;
+}
+.nihilo .dijitTreeNode .dojoDndItemBefore,
+.nihilo .dijitTreeNode .dojoDndItemAfter {
+	border-bottom: none;
+	border-top: none;
+}
+.nihilo .dijitTreeNode .dojoDndItemBefore .dijitTreeContent {
+	
+	border-top: 2px solid #369;
+}
+.nihilo .dijitTreeNode .dojoDndItemAfter .dijitTreeContent {
+	
+	border-bottom: 2px solid #369;
+}
diff --git a/dijit/themes/nihilo/Tree_rtl.css b/dijit/themes/nihilo/Tree_rtl.css
new file mode 100644
index 0000000..d9b2994
--- /dev/null
+++ b/dijit/themes/nihilo/Tree_rtl.css
@@ -0,0 +1,22 @@
+
+.dijitRtl .nihilo .dijitTreeContainer .dijitTreeNode {
+    background-image : none;
+}
+.dijitRtl .nihilo .dijitTreeContainer .dijitTreeIsRoot {
+}
+.dijitRtl .nihilo .dijitTreeContainer .dijitTreeIsLast {
+    background-image: url('images/treeI_half_rtl.gif');
+}
+.dijitRtl .nihilo .dijitTreeContainer .dijitTreeContent {
+    padding-left: auto;
+    padding-right: 1px;   
+}
+.dijitRtl .nihilo .dijitTreeContainer .dijitTreeExpandoOpened {
+	background: url('images/spriteTree_rtl.gif') no-repeat -18px top;
+}
+.dijitRtl .nihilo .dijitTreeContainer .dijitTreeExpandoClosed {
+	background-image: url('images/spriteTree_rtl.gif');
+}
+.dijitRtl .nihilo .dijitTreeContainer .dijitTreeExpandoLeaf {
+	background: none;
+}
diff --git a/dijit/themes/nihilo/form/Button.css b/dijit/themes/nihilo/form/Button.css
new file mode 100644
index 0000000..e996526
--- /dev/null
+++ b/dijit/themes/nihilo/form/Button.css
@@ -0,0 +1,86 @@
+
+.nihilo .dijitButtonNode {
+	
+	
+	border:1px solid #dedede;
+	border-bottom:1px solid #dedede;
+	padding: 0.1em 0.2em 0.2em 0.2em; 
+	background: #fff url("../images/buttonEnabled.png") repeat-x top left;
+}
+.nihilo .dijitButtonNode button { 
+	border: 0px; 
+	background-color: transparent; 
+} 
+ 
+.nihilo .dijitButtonText {
+	text-align: center; 
+	padding: 0 0.3em;
+}
+.nihilo .dijitComboBox .dijitButtonNode {
+	border-width: 0px 0px 0px 1px;
+}
+.nihilo .dijitArrowButton {
+	color: #111;
+}
+.nihilo .dijitComboButton .dijitDownArrowButton {
+	padding-right:4px;
+}
+.dj_ff2 .nihilo .dijitComboButton .dijitButtonContentsFocused,
+.dj_ff2 .nihilo .dijitComboButton .dijitDownArrowButtonFocused {
+	border: 1px black dotted !important;
+}
+.nihilo .dijitButtonDisabled .dijitButtonNode,
+.nihilo .dijitToggleButtonDisabled .dijitButtonNode,
+.nihilo .dijitDropDownButtonDisabled .dijitButtonNode,
+.nihilo .dijitComboButtonDisabled .dijitButtonNode,
+.nihilo .dijitComboBoxDisabled,
+.nihilo .dijitSpinnerDisabled,
+.nihilo .dijitSpinnerDisabled .dijitButtonNode {
+	
+	border-color: #dedede;
+	background:#fafafa url("../images/buttonDisabled.png") top repeat-x;
+	opacity: 0.60; 
+}
+.nihilo .dijitButtonHover .dijitButtonNode,
+.nihilo .dijitButtonNodeHover,
+.nihilo .dijitToggleButtonHover .dijitButtonNode,
+.nihilo .dijitDropDownButtonHover .dijitButtonNode,
+.nihilo .dijitComboButtonHover .dijitButtonContents,
+.nihilo .dijitComboButtonDownArrowHover .dijitDownArrowButton,
+.nihilo .dijitComboBoxHover .dijitDownArrowButton,
+.nihilo .dijitSpinnerUpArrowHover .dijitUpArrowButton,
+.nihilo .dijitSpinnerDownArrowHover .dijitDownArrowButton {
+	
+	
+	color:#243C5F;
+	background:#fcfcfc url("../images/buttonHover.png") repeat-x top left;
+}
+.nihilo .dijitSpinnerUpArrowActive .dijitUpArrowButton,
+.nihilo .dijitSpinnerDownArrowActive .dijitDownArrowButton,
+.nihilo .dijitButtonActive .dijitButtonNode,
+.nihilo .dijitToggleButtonActive .dijitButtonNode,
+.nihilo .dijitDropDownButtonActive .dijitButtonNode,
+.nihilo .dijitComboButtonActive .dijitButtonContents,
+.nihilo .dijitDownArrowActive .dijitDownArrowButton,
+.nihilo .dijitComboBoxActive .dijitDownArrowButton,
+.nihilo .dijitStackController .dijitToggleButtonChecked .dijitButtonNode {
+	
+	border-color:#dedede;
+	background: #f5f5f5 url("../images/buttonActive.png") top left repeat-x;
+}
+.nihilo .dijitArrowButtonInner {
+	background:url("../images/spriteArrows.png") no-repeat left top;
+	width: 11px;
+}
+.nihilo .dijitUpArrowButton .dijitArrowButtonInner { 
+	background:url("../images/spriteArrows.png") no-repeat -22px top; 
+	width: 11px;
+}
+.dj_ie6 .nihilo .dijitArrowButtonInner {
+	background:url("../images/spriteArrows.gif") no-repeat left top;
+	width: 11px;
+}
+.dj_ie6 .nihilo .dijitUpArrowButton .dijitArrowButtonInner {
+	background:url("../images/spriteArrows.gif") no-repeat -22px top;
+	width: 11px;
+}
diff --git a/dijit/themes/nihilo/form/Button_rtl.css b/dijit/themes/nihilo/form/Button_rtl.css
new file mode 100644
index 0000000..26fda32
--- /dev/null
+++ b/dijit/themes/nihilo/form/Button_rtl.css
@@ -0,0 +1,3 @@
+.dijitRtl .nihilo .dijitComboBox .dijitButtonNode {
+	border-width: 0px 0px 0px 1px;
+}
diff --git a/dijit/themes/nihilo/form/Checkbox.css b/dijit/themes/nihilo/form/Checkbox.css
new file mode 100644
index 0000000..ceee44f
--- /dev/null
+++ b/dijit/themes/nihilo/form/Checkbox.css
@@ -0,0 +1,40 @@
+
+.nihilo .dijitToggleButton .dijitCheckBox,
+.nihilo .dijitToggleButton .dijitCheckBoxIcon {
+	background-image: url('../images/spriteCheckbox.gif');
+}
+.nihilo .dijitCheckBox,
+.nihilo .dijitCheckBoxIcon {		
+	background-image: url('../images/spriteCheckbox.gif'); 
+	background-repeat: no-repeat;
+	width: 16px;
+	height: 16px;
+	margin: 0;
+	padding: 0;
+}
+.nihilo .dijitCheckBox,
+.nihilo .dijitToggleButton .dijitCheckBoxIcon {
+	
+	background-position: -16px;
+}
+.nihilo .dijitCheckBoxChecked,
+.nihilo .dijitToggleButtonChecked .dijitCheckBoxIcon {
+	
+	background-position: 0px;
+}
+.nihilo .dijitCheckBoxDisabled {
+	
+	background-position: -48px;
+}
+.nihilo .dijitCheckBoxCheckedDisabled {
+	
+	background-position: -32px;
+}
+.nihilo .dijitCheckBoxHover {
+	
+	background-position: -80px;
+}
+.nihilo .dijitCheckBoxCheckedHover {
+	
+	background-position: -64px;
+}
diff --git a/dijit/themes/nihilo/form/ComboBox.css b/dijit/themes/nihilo/form/ComboBox.css
new file mode 100644
index 0000000..fa7262e
--- /dev/null
+++ b/dijit/themes/nihilo/form/ComboBox.css
@@ -0,0 +1,10 @@
+.nihilo .dijitComboBox .dijitArrowButton .dijitArrowButtonInner {
+	background:url("../images/spriteArrows.png") no-repeat left center;
+	width: 11px;
+}
+.dj_ie6 .nihilo .dijitComboBox .dijitArrowButton .dijitArrowButtonInner {
+	background:url("../images/spriteArrows.gif") no-repeat left center;
+}
+.nihilo .dijitComboBoxHover .dijitArrowButtonInner {
+	
+}
diff --git a/dijit/themes/nihilo/form/Common.css b/dijit/themes/nihilo/form/Common.css
new file mode 100644
index 0000000..bbb2864
--- /dev/null
+++ b/dijit/themes/nihilo/form/Common.css
@@ -0,0 +1,88 @@
+
+.nihilo .dijitInputField INPUT,
+.nihilo .dijitTextBox,
+.nihilo .dijitComboBox,
+.nihilo .dijitSpinner {
+	margin: 0em 0.1em;
+}
+.nihilo .dijitTextBox,
+.nihilo .dijitComboBox,
+.nihilo .dijitSpinner,
+.nihilo .dijitInlineEditor input,
+.nihilo .dijitTextArea {
+	
+	background:#fff url("../images/validationInputBg.png") repeat-x top left;
+	border:1px solid #d3d3d3;
+	line-height: normal;
+}
+.dj_ie6 .nihilo .dijitTextBox,
+.dj_ie6 .nihilo .dijitComboBox,
+.dj_ie6 .nihilo .dijitSpinner,
+.dj_ie6 .nihilo .dijitInlineEditor input,
+.dj_ie6 .nihilo .dijitTextArea {
+	background:#fff url('../images/validationInputBg.gif') repeat-x top left;
+}
+.nihilo .dijitComboBox .dijitButtonNode {
+	padding: 0 0.2em;
+}
+.nihilo .dijitComboBox .dijitButtonNode,
+.nihilo .dijitSpinner .dijitButtonNode {
+	
+	border-color: #d3d3d3;
+	border-left: 1px solid #d3d3d3;
+}
+.nihilo .dijitTextBoxDisabled,
+.nihilo .dijitComboBoxDisabled,
+.nihilo .dijitSpinnerDisabled,
+.nihilo .dijitTextAreaDisabled {
+	color: gray;
+}
+.dj_webkit .nihilo .dijitTextBoxDisabled,
+.dj_webkit .nihilo .dijitComboBoxDisabled,
+.dj_webkit .nihilo .dijitSpinnerDisabled,
+.dj_webkit .nihilo .dijitTextareaDisabled {
+	color: #eee;
+}
+.nihilo .dijitTextBoxFocused,
+.nihilo .dijitComboBoxFocused,
+.nihilo .dijitSpinnerFocused, .nihilo .dijitSpinnerUpArrowActive, .nihilo .dijitSpinnerDownArrowActive,
+.nihilo .dijitTextAreaFocused {
+	
+	border-color:#b3b3b3;
+}
+.nihilo .dijitComboBoxFocused .dijitButtonNode,
+.nihilo .dijitSpinnerFocused .dijitButtonNode,
+.nihilo .dijitSpinnerUpArrowActive .dijitButtonNode,
+.nihilo .dijitSpinnerDownArrowActive .dijitButtonNode {
+	border-left-color:#d3d3d3;
+}
+.nihilo .dijitSpinnerFocused .dijitDownArrowButton,
+.nihilo .dijitSpinnerUpArrowActive .dijitDownArrowButton,
+.nihilo .dijitSpinnerDownArrowActive .dijitDownArrowButton {
+	border-top-color:#d3d3d3;
+}
+.nihilo .dijitError {
+	border-color:#b3b3b3;
+	background-color:#f9f7ba;
+	background-image:none;
+}
+.dj_ie6 .nihilo .dijitError INPUT {
+	
+	background-color:#f9f7ba !important;
+}
+.nihilo .dijitErrorFocused {
+	background-color:#ff6;
+	background-image:none;
+}
+.dj_ie6 .nihilo .dijitErrorFocused INPUT {
+	
+	background-color:#ff6 !important;
+}
+.nihilo .dijitValidationIcon {
+	
+	width: 16px;
+	background: transparent url('../images/warning.png') no-repeat center center;
+}
+.nihilo .dijitComboBoxHighlightMatch {
+	background-color:#d3d3d3;
+}
diff --git a/dijit/themes/nihilo/form/Common_rtl.css b/dijit/themes/nihilo/form/Common_rtl.css
new file mode 100644
index 0000000..d4e95c3
--- /dev/null
+++ b/dijit/themes/nihilo/form/Common_rtl.css
@@ -0,0 +1,7 @@
+.dijitRtl .nihilo .dijitComboBox .dijitButtonNode,
+.dijitRtl .nihilo .dijitSpinner .dijitButtonNode {
+	
+	border-color: #8ba0bd;
+	border-left: 0px solid #8ba0bd;
+	border-right: 1px solid #8ba0bd;
+}
diff --git a/dijit/themes/nihilo/form/RadioButton.css b/dijit/themes/nihilo/form/RadioButton.css
new file mode 100644
index 0000000..c876f59
--- /dev/null
+++ b/dijit/themes/nihilo/form/RadioButton.css
@@ -0,0 +1,40 @@
+
+.nihilo .dijitToggleButton .dijitRadio,
+.nihilo .dijitToggleButton .dijitRadioIcon {
+	background-image: url('../images/spriteRadio.gif');
+}
+.nihilo .dijitRadio,
+.nihilo .dijitRadioIcon	{		
+	background-image: url('../images/spriteRadio.gif'); 
+	background-repeat: no-repeat;
+	width: 16px;
+	height: 16px;
+	margin: 0;
+	padding: 0;
+}
+.nihilo .dijitRadio,
+.nihilo .dijitToggleButton .dijitRadioIcon {
+	
+	background-position: -16px;
+}
+.nihilo .dijitRadioChecked,
+.nihilo .dijitToggleButtonChecked .dijitRadioIcon {
+	
+	background-position: 0px;
+}
+.nihilo .dijitRadioDisabled {
+	
+	background-position: -48px;
+}
+.nihilo .dijitRadioCheckedDisabled {
+	
+	background-position: -32px;
+}
+.nihilo .dijitRadioHover {
+	
+	background-position: -80px;
+}
+.nihilo .dijitRadioCheckedHover {
+	
+	background-position: -64px;
+}
diff --git a/dijit/themes/nihilo/form/Slider.css b/dijit/themes/nihilo/form/Slider.css
new file mode 100644
index 0000000..d7e803b
--- /dev/null
+++ b/dijit/themes/nihilo/form/Slider.css
@@ -0,0 +1,115 @@
+
+.nihilo .dijitSliderProgressBarH {
+	border-color: #aab0bb;
+	background: #c0c2c5 url("../images/sliderFull.png") repeat-x top left;
+}
+.nihilo .dijitSliderProgressBarV {
+	border-color: #aab0bb;
+	background: #c0c2c5 url("../images/sliderFullVertical.png") repeat-y bottom left;
+}
+.nihilo .dijitSliderFocused .dijitSliderProgressBarH,
+.nihilo .dijitSliderFocused .dijitSliderLeftBumper {
+	background-image:url("../images/sliderFullFocus.png");
+}
+.nihilo .dijitSliderFocused .dijitSliderProgressBarV,
+.nihilo .dijitSliderFocused .dijitSliderBottomBumper {
+	background-image:url("../images/sliderFullVerticalFocus.png");
+}
+.nihilo .dijitSliderRemainingBarV {
+	border-color: #b4b4b4;
+	background: #dcdcdc url("../images/sliderEmptyVertical.png") repeat-y bottom left;
+}
+.nihilo .dijitSliderRemainingBarH {
+	border-color: #b4b4b4;
+	background: #dcdcdc url("../images/sliderEmpty.png") repeat-x top left;
+}
+.nihilo .dijitSliderBar {
+	border-style: solid;
+	outline:1px;
+	
+}
+.nihilo .dijitSliderFocused .dijitSliderBar {
+	border-color:#727272;	
+}
+.dijit_a11y .dijitSliderProgressBar {
+	background-color:#333 !important;
+}
+.nihilo .dijitSliderImageHandleH {
+	border:0px;
+	width:15px;
+	height:18px;
+	background:url("../images/preciseSliderThumb.png") no-repeat center top;
+	#background:url("../images/preciseSliderThumb.gif") no-repeat center top;
+	cursor:pointer;
+}
+.nihilo .dijitSliderFocused .dijitSliderImageHandleH {
+	background-image:url("../images/preciseSliderThumbFocus.png");
+	#background-image:url("../images/preciseSliderThumbFocus.gif");
+}
+.nihilo .dijitSliderLeftBumper {
+	border-left-width: 1px;
+	border-color: #aab0bb;
+	background: #c0c2c5 url("../images/sliderFull.png") repeat-x top left;
+}
+.nihilo .dijitSliderRightBumper {
+	background: #dcdcdc url("../images/sliderEmpty.png") repeat-x top left;
+	border-color: #b4b4b4;
+	border-right-width: 1px;
+}
+.nihilo .dijitSliderImageHandleV {
+	border:0px;
+	width:20px;
+	height:15px;
+	background:url("../images/sliderThumb.png") no-repeat center center;
+	#background:url("../images/sliderThumb.gif") no-repeat center center;
+	cursor:pointer;
+}
+.nihilo .dijitSliderFocused .dijitSliderImageHandleV {
+	background-image:url("../images/sliderThumbFocus.png");
+	#background-image:url("../images/sliderThumbFocus.gif");
+}
+.nihilo .dijitSliderBottomBumper {
+	border-bottom-width: 1px;
+	border-color: #aab0bb;
+	background: #c0c2c5 url("../images/sliderFullVertical.png") repeat-y bottom left;
+}
+.nihilo .dijitSliderTopBumper {
+	background: #dcdcdc url("../images/sliderEmptyVertical.png") repeat-y top left;
+	border-color: #b4b4b4;
+	border-top-width: 1px;
+}
+.nihilo .dijitSliderIncrementIconH,
+.nihilo .dijitSliderIncrementIconV {
+	background:url('../images/spriteRoundedIconsSmall.png') no-repeat -45px top;
+	#background:url('../images/spriteRoundedIconsSmall.gif') no-repeat -45px top;
+	width:15px; height:15px;
+	cursor:pointer;
+}
+.nihilo .dijitSliderIncrementIconH {
+	background:url('../images/spriteRoundedIconsSmall.png') no-repeat -30px top;
+	#background:url('../images/spriteRoundedIconsSmall.gif') no-repeat -30px top;
+}
+.nihilo .dijitSliderDecrementIconH,
+.nihilo .dijitSliderDecrementIconV {
+	width:15px;
+	height:15px;
+	cursor:pointer;
+	background:url('../images/spriteRoundedIconsSmall.png') no-repeat -15px top;
+	#background:url('../images/spriteRoundedIconsSmall.gif') no-repeat -15px top;
+}
+.nihilo .dijitSliderDecrementIconH { 
+	background:url('../images/spriteRoundedIconsSmall.png') no-repeat 0px top; 
+	#background:url('../images/spriteRoundedIconsSmall.gif') no-repeat 0px top; 
+}
+.nihilo .dijitSliderButtonInner {
+	visibility:hidden;
+}
+.nihilo .dijitSliderDisabled {
+	opacity:0.6 !important;
+}
+.dj_ie .nihilo .dijitSliderDisabled,
+.dj_ie .nihilo .dijitSliderDisabled .dijitRuleContainer,
+.dj_ie .nihilo .dijitSliderDisabled .dijitSliderRemainingBar,
+.dj_ie .nihilo .dijitSliderDisabled .dijitSliderProgressBar {
+	filter: gray() alpha(opacity=40);
+}
diff --git a/dijit/themes/nihilo/form/Slider_rtl.css b/dijit/themes/nihilo/form/Slider_rtl.css
new file mode 100644
index 0000000..fc40452
--- /dev/null
+++ b/dijit/themes/nihilo/form/Slider_rtl.css
@@ -0,0 +1,29 @@
+
+.dijitRtl .nihilo .dijitSliderProgressBarH,
+.dijitRtl .nihilo .dijitSliderRemainingBarH,
+.dijitRtl .nihilo .dijitSliderLeftBumper,
+.dijitRtl .nihilo .dijitSliderRightBumper,
+.dijitRtl .nihilo .dijitSliderTopBumper {
+	background-position: top right;
+}
+.dijitRtl .nihilo .dijitSliderProgressBarV,
+.dijitRtl .nihilo .dijitSliderRemainingBarV,
+.dijitRtl .nihilo .dijitSliderBottomBumper {
+	background-position: bottom right;
+}
+.dijitRtl .nihilo .dijitSliderLeftBumper {
+	border-left-width: 0px;
+	border-right-width: 1px;
+}
+.dijitRtl .nihilo .dijitSliderRightBumper {
+	border-left-width: 1px;
+	border-right-width: 0px;
+}
+.dijitRtl .nihilo .dijitSliderIncrementIconH {
+	background:url('../images/spriteRoundedIconsSmall.png') no-repeat left top;
+	#background:url('../images/spriteRoundedIconsSmall.gif') no-repeat left top;
+}
+.dijitRtl .nihilo .dijitSliderDecrementIconH {
+	background:url('../images/spriteRoundedIconsSmall.png') no-repeat -30px top;
+	#background:url('../images/spriteRoundedIconsSmall.gif') no-repeat -30px top;
+}
diff --git a/dijit/themes/nihilo/form/TimeTextBox.css b/dijit/themes/nihilo/form/TimeTextBox.css
new file mode 100644
index 0000000..d450925
--- /dev/null
+++ b/dijit/themes/nihilo/form/TimeTextBox.css
@@ -0,0 +1 @@
+ at CHARSET "UTF-8";
diff --git a/dijit/themes/nihilo/images/accordionItemActive.png b/dijit/themes/nihilo/images/accordionItemActive.png
new file mode 100644
index 0000000..58f3cf9
Binary files /dev/null and b/dijit/themes/nihilo/images/accordionItemActive.png differ
diff --git a/dijit/themes/nihilo/images/buttonActive.png b/dijit/themes/nihilo/images/buttonActive.png
new file mode 100644
index 0000000..e2f2fda
Binary files /dev/null and b/dijit/themes/nihilo/images/buttonActive.png differ
diff --git a/dijit/themes/nihilo/images/buttonDisabled.png b/dijit/themes/nihilo/images/buttonDisabled.png
new file mode 100644
index 0000000..b76af42
Binary files /dev/null and b/dijit/themes/nihilo/images/buttonDisabled.png differ
diff --git a/dijit/themes/nihilo/images/buttonEnabled.png b/dijit/themes/nihilo/images/buttonEnabled.png
new file mode 100644
index 0000000..d4fd306
Binary files /dev/null and b/dijit/themes/nihilo/images/buttonEnabled.png differ
diff --git a/dijit/themes/nihilo/images/buttonHover.png b/dijit/themes/nihilo/images/buttonHover.png
new file mode 100644
index 0000000..1af7e83
Binary files /dev/null and b/dijit/themes/nihilo/images/buttonHover.png differ
diff --git a/dijit/themes/nihilo/images/dndCopy.png b/dijit/themes/nihilo/images/dndCopy.png
new file mode 100644
index 0000000..baecd7c
Binary files /dev/null and b/dijit/themes/nihilo/images/dndCopy.png differ
diff --git a/dijit/themes/nihilo/images/dndMove.png b/dijit/themes/nihilo/images/dndMove.png
new file mode 100644
index 0000000..07f878c
Binary files /dev/null and b/dijit/themes/nihilo/images/dndMove.png differ
diff --git a/dijit/themes/nihilo/images/dndNoCopy.png b/dijit/themes/nihilo/images/dndNoCopy.png
new file mode 100644
index 0000000..9bf9c33
Binary files /dev/null and b/dijit/themes/nihilo/images/dndNoCopy.png differ
diff --git a/dijit/themes/nihilo/images/dndNoMove.png b/dijit/themes/nihilo/images/dndNoMove.png
new file mode 100644
index 0000000..cb8bd8b
Binary files /dev/null and b/dijit/themes/nihilo/images/dndNoMove.png differ
diff --git a/dijit/themes/nihilo/images/editor.gif b/dijit/themes/nihilo/images/editor.gif
new file mode 100644
index 0000000..127c9c4
Binary files /dev/null and b/dijit/themes/nihilo/images/editor.gif differ
diff --git a/dijit/themes/nihilo/images/editorDisabled.gif b/dijit/themes/nihilo/images/editorDisabled.gif
new file mode 100644
index 0000000..9dc5103
Binary files /dev/null and b/dijit/themes/nihilo/images/editorDisabled.gif differ
diff --git a/dijit/themes/nihilo/images/editorDisabled_rtl.gif b/dijit/themes/nihilo/images/editorDisabled_rtl.gif
new file mode 100644
index 0000000..74d407a
Binary files /dev/null and b/dijit/themes/nihilo/images/editorDisabled_rtl.gif differ
diff --git a/dijit/themes/nihilo/images/editor_rtl.gif b/dijit/themes/nihilo/images/editor_rtl.gif
new file mode 100644
index 0000000..b94d040
Binary files /dev/null and b/dijit/themes/nihilo/images/editor_rtl.gif differ
diff --git a/dijit/themes/nihilo/images/no.gif b/dijit/themes/nihilo/images/no.gif
new file mode 100644
index 0000000..9021a14
Binary files /dev/null and b/dijit/themes/nihilo/images/no.gif differ
diff --git a/dijit/themes/nihilo/images/preciseSliderThumb.gif b/dijit/themes/nihilo/images/preciseSliderThumb.gif
new file mode 100644
index 0000000..53b33e5
Binary files /dev/null and b/dijit/themes/nihilo/images/preciseSliderThumb.gif differ
diff --git a/dijit/themes/nihilo/images/preciseSliderThumb.png b/dijit/themes/nihilo/images/preciseSliderThumb.png
new file mode 100644
index 0000000..045bf35
Binary files /dev/null and b/dijit/themes/nihilo/images/preciseSliderThumb.png differ
diff --git a/dijit/themes/nihilo/images/preciseSliderThumbFocus.gif b/dijit/themes/nihilo/images/preciseSliderThumbFocus.gif
new file mode 100644
index 0000000..8c6f92e
Binary files /dev/null and b/dijit/themes/nihilo/images/preciseSliderThumbFocus.gif differ
diff --git a/dijit/themes/nihilo/images/preciseSliderThumbFocus.png b/dijit/themes/nihilo/images/preciseSliderThumbFocus.png
new file mode 100644
index 0000000..c235849
Binary files /dev/null and b/dijit/themes/nihilo/images/preciseSliderThumbFocus.png differ
diff --git a/dijit/themes/nihilo/images/progressBarAnim.gif b/dijit/themes/nihilo/images/progressBarAnim.gif
new file mode 100644
index 0000000..543d048
Binary files /dev/null and b/dijit/themes/nihilo/images/progressBarAnim.gif differ
diff --git a/dijit/themes/nihilo/images/progressBarEmpty.png b/dijit/themes/nihilo/images/progressBarEmpty.png
new file mode 100644
index 0000000..c2d3695
Binary files /dev/null and b/dijit/themes/nihilo/images/progressBarEmpty.png differ
diff --git a/dijit/themes/nihilo/images/progressBarFull.png b/dijit/themes/nihilo/images/progressBarFull.png
new file mode 100644
index 0000000..a8f3865
Binary files /dev/null and b/dijit/themes/nihilo/images/progressBarFull.png differ
diff --git a/dijit/themes/nihilo/images/sliderEmpty.png b/dijit/themes/nihilo/images/sliderEmpty.png
new file mode 100644
index 0000000..99fbd72
Binary files /dev/null and b/dijit/themes/nihilo/images/sliderEmpty.png differ
diff --git a/dijit/themes/nihilo/images/sliderEmptyVertical.png b/dijit/themes/nihilo/images/sliderEmptyVertical.png
new file mode 100644
index 0000000..2d497e3
Binary files /dev/null and b/dijit/themes/nihilo/images/sliderEmptyVertical.png differ
diff --git a/dijit/themes/nihilo/images/sliderFull.png b/dijit/themes/nihilo/images/sliderFull.png
new file mode 100644
index 0000000..9adb254
Binary files /dev/null and b/dijit/themes/nihilo/images/sliderFull.png differ
diff --git a/dijit/themes/nihilo/images/sliderFullFocus.png b/dijit/themes/nihilo/images/sliderFullFocus.png
new file mode 100644
index 0000000..3d75cae
Binary files /dev/null and b/dijit/themes/nihilo/images/sliderFullFocus.png differ
diff --git a/dijit/themes/nihilo/images/sliderFullVertical.png b/dijit/themes/nihilo/images/sliderFullVertical.png
new file mode 100644
index 0000000..27e9752
Binary files /dev/null and b/dijit/themes/nihilo/images/sliderFullVertical.png differ
diff --git a/dijit/themes/nihilo/images/sliderFullVerticalFocus.png b/dijit/themes/nihilo/images/sliderFullVerticalFocus.png
new file mode 100644
index 0000000..cca6184
Binary files /dev/null and b/dijit/themes/nihilo/images/sliderFullVerticalFocus.png differ
diff --git a/dijit/themes/nihilo/images/sliderThumb.gif b/dijit/themes/nihilo/images/sliderThumb.gif
new file mode 100644
index 0000000..29899a4
Binary files /dev/null and b/dijit/themes/nihilo/images/sliderThumb.gif differ
diff --git a/dijit/themes/nihilo/images/sliderThumb.png b/dijit/themes/nihilo/images/sliderThumb.png
new file mode 100644
index 0000000..b6abbd2
Binary files /dev/null and b/dijit/themes/nihilo/images/sliderThumb.png differ
diff --git a/dijit/themes/nihilo/images/sliderThumbFocus.gif b/dijit/themes/nihilo/images/sliderThumbFocus.gif
new file mode 100644
index 0000000..f8d306f
Binary files /dev/null and b/dijit/themes/nihilo/images/sliderThumbFocus.gif differ
diff --git a/dijit/themes/nihilo/images/sliderThumbFocus.png b/dijit/themes/nihilo/images/sliderThumbFocus.png
new file mode 100644
index 0000000..73ee705
Binary files /dev/null and b/dijit/themes/nihilo/images/sliderThumbFocus.png differ
diff --git a/dijit/themes/nihilo/images/splitContainerSizerH-thumb.png b/dijit/themes/nihilo/images/splitContainerSizerH-thumb.png
new file mode 100644
index 0000000..e7bc204
Binary files /dev/null and b/dijit/themes/nihilo/images/splitContainerSizerH-thumb.png differ
diff --git a/dijit/themes/nihilo/images/splitContainerSizerH.png b/dijit/themes/nihilo/images/splitContainerSizerH.png
new file mode 100644
index 0000000..5f5b0e9
Binary files /dev/null and b/dijit/themes/nihilo/images/splitContainerSizerH.png differ
diff --git a/dijit/themes/nihilo/images/splitContainerSizerV-thumb.png b/dijit/themes/nihilo/images/splitContainerSizerV-thumb.png
new file mode 100644
index 0000000..410a0a7
Binary files /dev/null and b/dijit/themes/nihilo/images/splitContainerSizerV-thumb.png differ
diff --git a/dijit/themes/nihilo/images/splitContainerSizerV.png b/dijit/themes/nihilo/images/splitContainerSizerV.png
new file mode 100644
index 0000000..064bc18
Binary files /dev/null and b/dijit/themes/nihilo/images/splitContainerSizerV.png differ
diff --git a/dijit/themes/nihilo/images/spriteArrows.gif b/dijit/themes/nihilo/images/spriteArrows.gif
new file mode 100644
index 0000000..fc81207
Binary files /dev/null and b/dijit/themes/nihilo/images/spriteArrows.gif differ
diff --git a/dijit/themes/nihilo/images/spriteArrows.png b/dijit/themes/nihilo/images/spriteArrows.png
new file mode 100644
index 0000000..73aa700
Binary files /dev/null and b/dijit/themes/nihilo/images/spriteArrows.png differ
diff --git a/dijit/themes/nihilo/images/spriteCheckbox.gif b/dijit/themes/nihilo/images/spriteCheckbox.gif
new file mode 100644
index 0000000..d2c4ebf
Binary files /dev/null and b/dijit/themes/nihilo/images/spriteCheckbox.gif differ
diff --git a/dijit/themes/nihilo/images/spriteCheckbox.png b/dijit/themes/nihilo/images/spriteCheckbox.png
new file mode 100644
index 0000000..e992330
Binary files /dev/null and b/dijit/themes/nihilo/images/spriteCheckbox.png differ
diff --git a/dijit/themes/nihilo/images/spriteDivIcons.gif b/dijit/themes/nihilo/images/spriteDivIcons.gif
new file mode 100644
index 0000000..00ad23a
Binary files /dev/null and b/dijit/themes/nihilo/images/spriteDivIcons.gif differ
diff --git a/dijit/themes/nihilo/images/spriteDivIcons.png b/dijit/themes/nihilo/images/spriteDivIcons.png
new file mode 100644
index 0000000..413098a
Binary files /dev/null and b/dijit/themes/nihilo/images/spriteDivIcons.png differ
diff --git a/dijit/themes/nihilo/images/spriteRadio.gif b/dijit/themes/nihilo/images/spriteRadio.gif
new file mode 100644
index 0000000..8dd6e57
Binary files /dev/null and b/dijit/themes/nihilo/images/spriteRadio.gif differ
diff --git a/dijit/themes/nihilo/images/spriteRadio.png b/dijit/themes/nihilo/images/spriteRadio.png
new file mode 100644
index 0000000..14c1080
Binary files /dev/null and b/dijit/themes/nihilo/images/spriteRadio.png differ
diff --git a/dijit/themes/nihilo/images/spriteRoundedIconsSmall.gif b/dijit/themes/nihilo/images/spriteRoundedIconsSmall.gif
new file mode 100644
index 0000000..251389a
Binary files /dev/null and b/dijit/themes/nihilo/images/spriteRoundedIconsSmall.gif differ
diff --git a/dijit/themes/nihilo/images/spriteRoundedIconsSmall.png b/dijit/themes/nihilo/images/spriteRoundedIconsSmall.png
new file mode 100644
index 0000000..e81ba07
Binary files /dev/null and b/dijit/themes/nihilo/images/spriteRoundedIconsSmall.png differ
diff --git a/dijit/themes/nihilo/images/spriteTree.gif b/dijit/themes/nihilo/images/spriteTree.gif
new file mode 100644
index 0000000..e546e28
Binary files /dev/null and b/dijit/themes/nihilo/images/spriteTree.gif differ
diff --git a/dijit/themes/nihilo/images/spriteTree.png b/dijit/themes/nihilo/images/spriteTree.png
new file mode 100644
index 0000000..33ae07b
Binary files /dev/null and b/dijit/themes/nihilo/images/spriteTree.png differ
diff --git a/dijit/themes/nihilo/images/spriteTree_rtl.gif b/dijit/themes/nihilo/images/spriteTree_rtl.gif
new file mode 100644
index 0000000..bbcc64b
Binary files /dev/null and b/dijit/themes/nihilo/images/spriteTree_rtl.gif differ
diff --git a/dijit/themes/nihilo/images/spriteTree_rtl.png b/dijit/themes/nihilo/images/spriteTree_rtl.png
new file mode 100644
index 0000000..b06afdb
Binary files /dev/null and b/dijit/themes/nihilo/images/spriteTree_rtl.png differ
diff --git a/dijit/themes/nihilo/images/tabBottomActiveC.gif b/dijit/themes/nihilo/images/tabBottomActiveC.gif
new file mode 100644
index 0000000..84bffde
Binary files /dev/null and b/dijit/themes/nihilo/images/tabBottomActiveC.gif differ
diff --git a/dijit/themes/nihilo/images/tabBottomActiveSpriteLR.gif b/dijit/themes/nihilo/images/tabBottomActiveSpriteLR.gif
new file mode 100644
index 0000000..6803db4
Binary files /dev/null and b/dijit/themes/nihilo/images/tabBottomActiveSpriteLR.gif differ
diff --git a/dijit/themes/nihilo/images/tabBottomEnabledC.gif b/dijit/themes/nihilo/images/tabBottomEnabledC.gif
new file mode 100644
index 0000000..9ef9ab0
Binary files /dev/null and b/dijit/themes/nihilo/images/tabBottomEnabledC.gif differ
diff --git a/dijit/themes/nihilo/images/tabBottomEnabledSpriteLR.gif b/dijit/themes/nihilo/images/tabBottomEnabledSpriteLR.gif
new file mode 100644
index 0000000..b6b08ce
Binary files /dev/null and b/dijit/themes/nihilo/images/tabBottomEnabledSpriteLR.gif differ
diff --git a/dijit/themes/nihilo/images/tabBottomHoverC.gif b/dijit/themes/nihilo/images/tabBottomHoverC.gif
new file mode 100644
index 0000000..0f533b5
Binary files /dev/null and b/dijit/themes/nihilo/images/tabBottomHoverC.gif differ
diff --git a/dijit/themes/nihilo/images/tabBottomHoverSpriteLR.gif b/dijit/themes/nihilo/images/tabBottomHoverSpriteLR.gif
new file mode 100644
index 0000000..010b08a
Binary files /dev/null and b/dijit/themes/nihilo/images/tabBottomHoverSpriteLR.gif differ
diff --git a/dijit/themes/nihilo/images/tabContainerSprite.gif b/dijit/themes/nihilo/images/tabContainerSprite.gif
new file mode 100644
index 0000000..92044a7
Binary files /dev/null and b/dijit/themes/nihilo/images/tabContainerSprite.gif differ
diff --git a/dijit/themes/nihilo/images/tabLeftChecked.gif b/dijit/themes/nihilo/images/tabLeftChecked.gif
new file mode 100644
index 0000000..d59fd4a
Binary files /dev/null and b/dijit/themes/nihilo/images/tabLeftChecked.gif differ
diff --git a/dijit/themes/nihilo/images/tabRightChecked.gif b/dijit/themes/nihilo/images/tabRightChecked.gif
new file mode 100644
index 0000000..d32f44e
Binary files /dev/null and b/dijit/themes/nihilo/images/tabRightChecked.gif differ
diff --git a/dijit/themes/nihilo/images/tabStripe.gif b/dijit/themes/nihilo/images/tabStripe.gif
new file mode 100644
index 0000000..a934675
Binary files /dev/null and b/dijit/themes/nihilo/images/tabStripe.gif differ
diff --git a/dijit/themes/nihilo/images/tabStripeBottom.gif b/dijit/themes/nihilo/images/tabStripeBottom.gif
new file mode 100644
index 0000000..64c3376
Binary files /dev/null and b/dijit/themes/nihilo/images/tabStripeBottom.gif differ
diff --git a/dijit/themes/nihilo/images/tabStripeLeft.gif b/dijit/themes/nihilo/images/tabStripeLeft.gif
new file mode 100644
index 0000000..d607a45
Binary files /dev/null and b/dijit/themes/nihilo/images/tabStripeLeft.gif differ
diff --git a/dijit/themes/nihilo/images/tabStripeRight.gif b/dijit/themes/nihilo/images/tabStripeRight.gif
new file mode 100644
index 0000000..9778ced
Binary files /dev/null and b/dijit/themes/nihilo/images/tabStripeRight.gif differ
diff --git a/dijit/themes/nihilo/images/titleBar.png b/dijit/themes/nihilo/images/titleBar.png
new file mode 100644
index 0000000..48f3a2f
Binary files /dev/null and b/dijit/themes/nihilo/images/titleBar.png differ
diff --git a/dijit/themes/nihilo/images/titleBarActive.png b/dijit/themes/nihilo/images/titleBarActive.png
new file mode 100644
index 0000000..58f3cf9
Binary files /dev/null and b/dijit/themes/nihilo/images/titleBarActive.png differ
diff --git a/dijit/themes/nihilo/images/tooltipConnectorDown.gif b/dijit/themes/nihilo/images/tooltipConnectorDown.gif
new file mode 100644
index 0000000..9c38495
Binary files /dev/null and b/dijit/themes/nihilo/images/tooltipConnectorDown.gif differ
diff --git a/dijit/themes/nihilo/images/tooltipConnectorDown.png b/dijit/themes/nihilo/images/tooltipConnectorDown.png
new file mode 100644
index 0000000..d75af71
Binary files /dev/null and b/dijit/themes/nihilo/images/tooltipConnectorDown.png differ
diff --git a/dijit/themes/nihilo/images/tooltipConnectorLeft.gif b/dijit/themes/nihilo/images/tooltipConnectorLeft.gif
new file mode 100644
index 0000000..fc947e0
Binary files /dev/null and b/dijit/themes/nihilo/images/tooltipConnectorLeft.gif differ
diff --git a/dijit/themes/nihilo/images/tooltipConnectorLeft.png b/dijit/themes/nihilo/images/tooltipConnectorLeft.png
new file mode 100644
index 0000000..f3de66a
Binary files /dev/null and b/dijit/themes/nihilo/images/tooltipConnectorLeft.png differ
diff --git a/dijit/themes/nihilo/images/tooltipConnectorRight.gif b/dijit/themes/nihilo/images/tooltipConnectorRight.gif
new file mode 100644
index 0000000..b0e8097
Binary files /dev/null and b/dijit/themes/nihilo/images/tooltipConnectorRight.gif differ
diff --git a/dijit/themes/nihilo/images/tooltipConnectorRight.png b/dijit/themes/nihilo/images/tooltipConnectorRight.png
new file mode 100644
index 0000000..ed6efc4
Binary files /dev/null and b/dijit/themes/nihilo/images/tooltipConnectorRight.png differ
diff --git a/dijit/themes/nihilo/images/tooltipConnectorUp.gif b/dijit/themes/nihilo/images/tooltipConnectorUp.gif
new file mode 100644
index 0000000..54bcf65
Binary files /dev/null and b/dijit/themes/nihilo/images/tooltipConnectorUp.gif differ
diff --git a/dijit/themes/nihilo/images/tooltipConnectorUp.png b/dijit/themes/nihilo/images/tooltipConnectorUp.png
new file mode 100644
index 0000000..7f7a5d8
Binary files /dev/null and b/dijit/themes/nihilo/images/tooltipConnectorUp.png differ
diff --git a/dijit/themes/nihilo/images/treeExpand_loading.gif b/dijit/themes/nihilo/images/treeExpand_loading.gif
new file mode 100644
index 0000000..db9ddd0
Binary files /dev/null and b/dijit/themes/nihilo/images/treeExpand_loading.gif differ
diff --git a/dijit/themes/nihilo/images/treeHover.png b/dijit/themes/nihilo/images/treeHover.png
new file mode 100644
index 0000000..ca80cd2
Binary files /dev/null and b/dijit/themes/nihilo/images/treeHover.png differ
diff --git a/dijit/themes/nihilo/images/treeI.gif b/dijit/themes/nihilo/images/treeI.gif
new file mode 100644
index 0000000..6f669e2
Binary files /dev/null and b/dijit/themes/nihilo/images/treeI.gif differ
diff --git a/dijit/themes/nihilo/images/treeI_half.gif b/dijit/themes/nihilo/images/treeI_half.gif
new file mode 100644
index 0000000..e5fd015
Binary files /dev/null and b/dijit/themes/nihilo/images/treeI_half.gif differ
diff --git a/dijit/themes/nihilo/images/treeI_half_rtl.gif b/dijit/themes/nihilo/images/treeI_half_rtl.gif
new file mode 100644
index 0000000..44ad021
Binary files /dev/null and b/dijit/themes/nihilo/images/treeI_half_rtl.gif differ
diff --git a/dijit/themes/nihilo/images/treeI_rtl.gif b/dijit/themes/nihilo/images/treeI_rtl.gif
new file mode 100644
index 0000000..0d32a2f
Binary files /dev/null and b/dijit/themes/nihilo/images/treeI_rtl.gif differ
diff --git a/dijit/themes/nihilo/images/validationInputBg.gif b/dijit/themes/nihilo/images/validationInputBg.gif
new file mode 100644
index 0000000..c28475c
Binary files /dev/null and b/dijit/themes/nihilo/images/validationInputBg.gif differ
diff --git a/dijit/themes/nihilo/images/validationInputBg.png b/dijit/themes/nihilo/images/validationInputBg.png
new file mode 100644
index 0000000..f3039f9
Binary files /dev/null and b/dijit/themes/nihilo/images/validationInputBg.png differ
diff --git a/dijit/themes/nihilo/images/warning.png b/dijit/themes/nihilo/images/warning.png
new file mode 100644
index 0000000..c52f83d
Binary files /dev/null and b/dijit/themes/nihilo/images/warning.png differ
diff --git a/dijit/themes/nihilo/layout/AccordionContainer.css b/dijit/themes/nihilo/layout/AccordionContainer.css
new file mode 100644
index 0000000..cb3613d
--- /dev/null
+++ b/dijit/themes/nihilo/layout/AccordionContainer.css
@@ -0,0 +1,37 @@
+
+.nihilo .dijitAccordionContainer {
+	border-color: #ccc;
+	background-color: #fff;
+}
+.nihilo .dijitAccordionTitle {
+	background:#fafafa url("../images/titleBar.png") repeat-x top left;
+	border-top: 1px solid #dedede;
+	padding: 5px 4px 6px 8px;
+	cursor:pointer;
+	font-size: 0.9em;
+	font-weight: bold;
+	color: #6d6d6d;
+}
+.nihilo .dijitAccordionTitle-selected  {
+	background: #f9f9f9 url("../images/accordionItemActive.png") top repeat-x;
+	font-weight: bold;
+	border-top: 1px solid #dedede;
+	border-bottom: 1px solid #dedede;
+	padding: 5px 4px 5px 8px;
+	cursor: default;	
+	color: #243C5F;
+}
+.nihilo .dijitAccordionArrow {
+	background:url("../images/spriteRoundedIconsSmall.gif") no-repeat -30px top;
+	width:15px;
+	height:15px;
+	margin-top:-1px;
+}
+.nihilo .dijitAccordionTitle-selected .dijitAccordionArrow {
+	background:url("../images/spriteRoundedIconsSmall.gif") no-repeat -15px top;
+	margin-top:-1px;
+}
+.nihilo .dijitAccordionText {
+	margin-left: 4px;
+	margin-right: 4px;
+}
diff --git a/dijit/themes/nihilo/layout/AccordionContainer_rtl.css b/dijit/themes/nihilo/layout/AccordionContainer_rtl.css
new file mode 100644
index 0000000..00d3292
--- /dev/null
+++ b/dijit/themes/nihilo/layout/AccordionContainer_rtl.css
@@ -0,0 +1,7 @@
+.dijitRtl .nihilo .dijitAccordionArrow {
+	background-position: 0px top;
+}
+.dijitRtl .nihilo .dijitAccordionTitle-selected .dijitAccordionArrow {
+	
+	background-position: -15px top;
+}
diff --git a/dijit/themes/nihilo/layout/BorderContainer.css b/dijit/themes/nihilo/layout/BorderContainer.css
new file mode 100644
index 0000000..598f092
--- /dev/null
+++ b/dijit/themes/nihilo/layout/BorderContainer.css
@@ -0,0 +1,59 @@
+ 
+.nihilo .dijitBorderContainer {
+	background-color: #fcfcfc;
+	padding: 5px;
+}
+.nihilo .dijitSplitContainer-child,
+.nihilo .dijitBorderContainer-child {
+	
+    border: 1px #ccc solid;
+}
+.nihilo .dijitBorderContainer-dijitTabContainerTop,
+.nihilo .dijitBorderContainer-dijitTabContainerBottom,
+.nihilo .dijitBorderContainer-dijitTabContainerLeft,
+.nihilo .dijitBorderContainer-dijitTabContainerRight {
+	
+	 border: none;
+}
+.nihilo .dijitBorderContainer-dijitBorderContainer {
+	
+	border: none;
+	padding: 0px;
+}
+.nihilo .dijitSplitterH,
+.nihilo .dijitGutterH {
+	background:#FCFCFC;
+	border:0;
+	border-left:0px solid #d3d3d3;
+	border-right:0px solid #d3d3d3;
+	height:5px;
+}
+.nihilo .dijitSplitterH .dijitSplitterThumb {
+	background:url("../images/splitContainerSizerH-thumb.png") no-repeat;
+	top:1px;
+	width:19px;
+	height:2px;
+}
+.nihilo .dijitSplitterV,
+.nihilo .dijitGutterV {
+	background:#FCFCFC;
+	border:0;
+	border-top:0px solid #d3d3d3;
+	border-bottom:0px solid #d3d3d3;
+	width:5px;
+}
+.nihilo .dijitSplitterV .dijitSplitterThumb {
+	background:url("../images/splitContainerSizerV-thumb.png") no-repeat;
+	left:1px;
+	height:19px;
+	width:5px;
+}
+.nihilo .dijitSplitterActive {
+	font-size: 1px;
+	background-image: none;
+	background-color: #aaa;
+	-moz-opacity: 0.6;
+	opacity: 0.6;
+	filter: Alpha(Opacity=60);
+	margin: 0;
+}
diff --git a/dijit/themes/nihilo/layout/ContentPane.css b/dijit/themes/nihilo/layout/ContentPane.css
new file mode 100644
index 0000000..2bd0a19
--- /dev/null
+++ b/dijit/themes/nihilo/layout/ContentPane.css
@@ -0,0 +1,17 @@
+
+.nihilo .dijitContentPane {
+    padding: 0px;
+}
+.nihilo .dijitTabContainerTop-dijitContentPane,
+.nihilo .dijitTabContainerLeft-dijitContentPane,
+.nihilo .dijitTabContainerRight-dijitContentPane,
+.nihilo .dijitTabContainerBottom-dijitContentPane,
+.nihilo .dijitAccordionContainer-dijitContentPane {
+    background-color: #fff;
+    padding: 5px;
+}
+.nihilo .dijitSplitContainer-dijitContentPane,
+.nihilo .dijitBorderContainer-dijitContentPane {
+    background-color: #fff;		
+    padding: 5px;
+}
diff --git a/dijit/themes/nihilo/layout/SplitContainer.css b/dijit/themes/nihilo/layout/SplitContainer.css
new file mode 100644
index 0000000..6d6d715
--- /dev/null
+++ b/dijit/themes/nihilo/layout/SplitContainer.css
@@ -0,0 +1,27 @@
+ 
+.nihilo .dijitSplitContainerSizerH {
+	background:url("../images/splitContainerSizerV.png") repeat-y #fff;
+	border:0;
+	border-left:0px solid #d3d3d3;
+	border-right:0px solid #d3d3d3;
+	width:5px;
+}
+.nihilo .dijitSplitContainerSizerH .thumb {
+	background:url("../images/splitContainerSizerV-thumb.png") no-repeat;
+	left:1px;
+	width:2px;
+	height:19px;
+}
+.nihilo .dijitSplitContainerSizerV {
+	background:url("../images/splitContainerSizerH.png") repeat-x #fff;
+	border:0;
+	border-top:0px solid #d3d3d3;
+	border-bottom:0px solid #d3d3d3;
+	height:2px;
+}
+.nihilo .dijitSplitContainerSizerV .thumb {
+	background:url("../images/splitContainerSizerH-thumb.png") no-repeat;
+	top:1px;
+	width:19px;
+	height:5px;
+}
diff --git a/dijit/themes/nihilo/layout/TabContainer.css b/dijit/themes/nihilo/layout/TabContainer.css
new file mode 100644
index 0000000..54f5ce4
--- /dev/null
+++ b/dijit/themes/nihilo/layout/TabContainer.css
@@ -0,0 +1,277 @@
+ 
+ 
+.nihilo .dijitTabPaneWrapper {
+	background:#fff;
+	border:1px solid #ccc;
+	margin: 0;
+	padding: 0;
+}
+.nihilo .dijitTabInnerDiv {
+	padding:0px 3px 0px 0px;
+	margin: 0 0 0 4px;
+	background: url("../images/tabContainerSprite.gif") no-repeat;
+	background-position: right -400px;
+}
+.nihilo .dijitTab {
+	line-height:normal;
+	margin:0 2px 0 0;	
+	padding:0px;
+	background: url("../images/tabContainerSprite.gif") no-repeat 0 -300px;
+	color: #6d6d6d;
+	border-bottom: 1px #ccc solid;
+}
+.nihilo .dijitTabInnerDiv .dijitTabContent {
+	padding:5px 3px 4px 4px;
+	background: url("../images/tabContainerSprite.gif") repeat-x 0 -350px;
+	position: relative;
+}
+.dijitTabSpacer {
+	font-size: 1px;
+}
+.nihilo .dijitTabHover {
+	color: #243C5F;
+	background: url("../images/tabContainerSprite.gif") no-repeat 0px -150px;
+}
+.nihilo .dijitTabHover .dijitTabInnerDiv {
+	background: url("../images/tabContainerSprite.gif") no-repeat right -250px;
+}
+.nihilo .dijitTabHover .dijitTabInnerDiv .dijitTabContent {
+	background: url("../images/tabContainerSprite.gif") repeat-x 0 -200px;
+}
+.nihilo .dijitTabChecked,
+.nihilo .dijitTabCloseButtonChecked
+{
+	
+	background: url("../images/tabContainerSprite.gif") no-repeat 0px -0px;
+}
+.nihilo .dijitTabChecked .dijitTabInnerDiv {
+	background: url("../images/tabContainerSprite.gif") no-repeat right -100px;
+}
+.nihilo .dijitTabChecked .dijitTabInnerDiv .dijitTabContent {
+	background: url("../images/tabContainerSprite.gif") repeat-x 0 -50px;
+	color: #243C5F !important;
+}
+.nihilo .dijitTabContainerTabListNested {
+	background: #FDFDFD;
+	border: none;
+	margin-bottom: 0px;		
+}
+.nihilo .dijitTabContainerTabListNested .dijitTab {
+	background: none;
+	border: none;
+	top: 0px;	
+}
+.nihilo .dijitTabContainerTabListNested .dijitTab .dijitTabInnerDiv,
+.nihilo .dijitTabContainerTabListNested .dijitTab .dijitTabContent {
+	background: none;
+}
+.nihilo .dijitTabContainerTabListNested .dijitTabHover .dijitTabContent .tabLabel {
+	text-decoration: underline;
+}
+.nihilo .dijitTabContainerTabListNested .dijitTabChecked .tabLabel {
+	text-decoration: underline;
+	font-weight: bold;
+}
+.nihilo .dijitTabContainerSpacerNested {
+	
+	height: 0px;
+	border-bottom: 0px;
+}
+.nihilo .dijitTabPaneWrapperNested {
+	border: none;	
+}
+.nihilo .dijitTab .closeImage {
+	background: url("../images/spriteRoundedIconsSmall.png") no-repeat -60px top;
+	width: 15px;
+	height: 15px;
+}
+.dj_ie6 .dijitTab .closeImage {
+	background: url("../images/spriteRoundedIconsSmall.gif") no-repeat -60px top;
+}
+.nihilo .dijitTab .closeButton-hover .closeImage {
+	background: url("../images/spriteRoundedIconsSmall.png") no-repeat -60px -15px;
+}
+.dj_ie6 .nihilo .dijitTab .closeButton-hover .closeImage {
+	background: url("../images/spriteRoundedIconsSmall.gif") no-repeat -60px -15px;
+}
+.nihilo .dijitTab .dijitTabButtonSpacer {
+	height: 15px;
+	width: 1px;
+}
+.nihilo .dijitTabContainerTop-tabs {
+	margin-bottom: -1px;
+	border-color: #ccc;
+	padding-left: 3px;
+}
+.nihilo .dijitTabContainerTop-container {
+	border-top: none;
+}
+.nihilo .dijitTabContainerTop-tabs .dijitTabChecked {
+	border-bottom-color: #f8f8f8;
+}
+.nihilo .dijitTabContainerTopStrip {
+	border: 1px solid #ccc;
+	padding-top: 2px;
+	padding-left: 3px;
+}
+.nihilo .dijitTabContainerTopStrip {
+	background: #f2f2f2;
+}
+.nihilo .dijitTabContainerBottom-tabs {
+	margin-top: -1px;
+	border-color: #ccc;
+	padding-left: 3px;
+}
+.nihilo .dijitTabContainerBottom-container {
+	border-bottom: none;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTab {
+	border-bottom: none;
+	border-top: 1px solid #ccc;
+	background: url("../images/tabBottomEnabledSpriteLR.gif") no-repeat bottom left;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTabChecked {
+	border-top-color:#f8f8f8;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTabInnerDiv .dijitTabContent {
+	padding-top: 4px;
+	padding-bottom: 5px;
+	background: url("../images/tabBottomEnabledC.gif") repeat-x bottom left;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTabInnerDiv {
+	background: url("../images/tabBottomEnabledSpriteLR.gif") no-repeat bottom right;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTabHover {
+	color: #243C5F;
+	background: url("../images/tabBottomHoverSpriteLR.gif") no-repeat bottom left;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTabHover .dijitTabInnerDiv {
+	background: url("../images/tabBottomHoverSpriteLR.gif") no-repeat bottom right;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTabHover .dijitTabInnerDiv .dijitTabContent {
+	background: url("../images/tabBottomHoverC.gif") repeat-x bottom left;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTabChecked,
+.nihilo .dijitTabContainerBottom-tabs .dijitTabCloseButtonChecked
+{
+	
+	background: url("../images/tabBottomActiveSpriteLR.gif") no-repeat bottom left;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabInnerDiv {
+	background: url("../images/tabBottomActiveSpriteLR.gif") no-repeat bottom right;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabInnerDiv .dijitTabContent {
+	background: url("../images/tabBottomActiveC.gif") repeat-x bottom left;
+}
+.nihilo .dijitTabContainerBottomStrip {
+	padding-bottom: 2px;
+	padding-left: 3px;	
+	border: 1px solid #ccc;
+}
+.nihilo .dijitTabContainerBottomStrip {
+	background: #f2f2f2;
+}
+.nihilo .dijitTabContainerBottom-spacer,
+.nihilo .dijitTabContainerTop-spacer {
+	height: 2px;
+	border: 1px solid #ccc;
+	background: #f8f8f8;
+}
+.nihilo .dijitTabContainerRight-tabs {
+	margin-left: -1px;
+	border-color: #ccc;
+	padding-top: 3px;
+}
+.nihilo .dijitTabContainerRight-container {
+	border-right: none;
+}
+.nihilo .dijitTabContainerRight-tabs .dijitTab {
+	border-bottom: none;
+	border-left: 1px solid #ccc;
+	border-bottom: 1px solid #dedede !important;
+}
+.dj_ie .nihilo .dijitTabContainerRight-tabs .dijitTabInnerDiv {
+	border-bottom: solid #fff 1px;
+}
+.nihilo .dijitTabContainerRight-tabs .dijitTabChecked {
+	border-left-color: #f8f8f8;
+}
+.nihilo .dijitTabContainerRight-tabs .dijitTabChecked {
+	background: url("../images/tabRightChecked.gif") no-repeat left top !important;
+}
+.dj_ie .nihilo .dijitTabContainerRight-tabs .dijitTabChecked .dijitTabInnerDiv,
+.dj_ie .nihilo .dijitTabContainerRight-tabs .dijitTabCheckedHover .dijitTabInnerDiv {
+	border-bottom: solid #efefef 1px;
+}
+.nihilo .dijitTabContainerRight-tabs .dijitTab {
+	background: url("../images/tabContainerSprite.gif") no-repeat left -350px;
+}
+.nihilo .dijitTabContainerRight-tabs .dijitTabHover .dijitTab {
+	background: url("../images/tabContainerSprite.gif") no-repeat left -200px;
+}
+.nihilo .dijitTabContainerRightStrip {
+	padding-right: 2px;
+	padding-top: 3px;	
+	border: 1px solid #ccc;
+}
+.nihilo .dijitTabContainerRightStrip {
+	background: #f2f2f2;
+}
+.nihilo .dijitTabContainerLeft-tabs {
+	margin-right: -1px;
+	border-color: #ccc;
+	padding-top: 3px;
+}
+.nihilo .dijitTabContainerLeft-container {
+	border-left: none;
+}
+.nihilo .dijitTabContainerLeft-tabs .dijitTab {
+	border-right: 1px solid #ccc;
+	border-bottom: 1px solid #dedede;
+}
+.nihilo .dijitTabContainerLeft-tabs .dijitTabChecked {
+	border-right: 1px solid #f8f8f8;
+}
+.nihilo .dijitTabContainerLeft-tabs .dijitTabInnerDiv {
+	background: url("../images/tabContainerSprite.gif") no-repeat right -350px;
+}
+.nihilo .dijitTabContainerLeft-tabs .dijitTabHover .dijitTabInnerDiv {
+	background: url("../images/tabContainerSprite.gif") no-repeat right -200px;
+}
+.nihilo .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabInnerDiv,
+.nihilo .dijitTabContainerLeft-tabs .dijitTabCheckedHover .dijitTabInnerDiv {
+	background: url("../images/tabLeftChecked.gif") no-repeat right top;
+}
+.dj_ie .nihilo .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabInnerDiv,
+.dj_ie .nihilo .dijitTabContainerLeft-tabs .dijitTabCheckedHover .dijitTabInnerDiv {
+	border-bottom: solid #efefef 1px;
+}
+.dj_ie .nihilo .dijitTabContainerLeft-tabs .dijitTabInnerDiv {
+border-bottom: solid #fff 1px;
+}
+.nihilo .dijitTabContainerLeftStrip {
+	padding-left: 2px;
+	padding-top: 3px;	
+	border: 1px solid #ccc;
+}
+.nihilo .dijitTabContainerLeftStrip {
+	background: #f2f2f2;
+}
+.nihilo .dijitTabContainerLeft-tabs .dijitTab,
+.nihilo .dijitTabContainerRight-tabs .dijitTab {
+	margin-right:auto;
+	margin-bottom:2px;	
+}
+.nihilo .dijitTabContainerLeft-spacer,
+.nihilo .dijitTabContainerRight-spacer {
+	width: 2px;
+	border: 1px solid #ccc;
+	background: #f8f8f8;
+}
+.nihilo .dijitTabContainerTop-dijitContentPane .dijitTabContainerTop-tabs {
+	border-left: 0px solid #ccc;
+	border-top: 0px solid #ccc;
+	border-right: 0px solid #ccc;
+	padding-top: 0px;
+	padding-left: 0px;	
+}
diff --git a/dijit/themes/nihilo/layout/TabContainer_rtl.css b/dijit/themes/nihilo/layout/TabContainer_rtl.css
new file mode 100644
index 0000000..65cab9b
--- /dev/null
+++ b/dijit/themes/nihilo/layout/TabContainer_rtl.css
@@ -0,0 +1,37 @@
+.dijitRtl .nihilo .dijitTab {
+	margin-right:0;
+	margin-left:2px;		
+}
+.dijitRtl .nihilo .dijitTabContainerTopStrip,
+.dijitRtl .nihilo .dijitTabContainerBottomStrip {
+	padding-right: 3px;
+	padding-left: 0px;
+}
+.dijitRtl .nihilo .dijitTabContainerTop-tabs {
+	padding-left: auto;
+	padding-right: 3px;
+}
+.dijitRtl .nihilo .dijitTabContainerBottom-tabs {
+	padding-left: auto;
+	padding-right: 3px;
+}
+.dijitRtl .nihilo .dijitTabInnerDiv {
+	padding-left: 3px;
+	padding-right: 4px;
+}
+.dijitRtl .nihilo .dijitTabPaneWrapper {
+	#zoom: 1;
+}
+.dj_ie-rtl .nihilo .dijitTabContainerLeft-tabs {
+	margin-left: 0px !important;
+}
+.dj_ie-rtl .nihilo .dijitTabContainerRight-tabs {
+	margin-right: 0px !important;
+}
+.dijitRtl .nihilo .dijitTabContainerLeft-tabs .dijitTab,
+.dijitRtl .nihilo .dijitTabContainerRight-tabs .dijitTab {
+	margin-left:0px;
+}
+.dj_ie-rtl .nihilo .dijitTab .dijitTabInnerDiv{
+	width : 1%;
+}
diff --git a/dijit/themes/nihilo/nihilo.css b/dijit/themes/nihilo/nihilo.css
new file mode 100644
index 0000000..2a6532a
--- /dev/null
+++ b/dijit/themes/nihilo/nihilo.css
@@ -0,0 +1,1480 @@
+
+ at import url("../dijit.css");
+.nihilo .dojoDndItemBefore {
+	border-top: 2px solid #369;
+}
+.nihilo .dojoDndItemAfter {
+	border-bottom: 2px solid #369;
+}
+.nihilo .dojoDndItemOver {
+	cursor:pointer;
+}
+.nihilo table.dojoDndAvatar { -moz-border-radius: 0; border: 1px solid #ccc; border-collapse: collapse; background-color: #fff; font-size: 75%; color: black;}
+.nihilo .dojoDndAvatar td	{ border: none; }
+.nihilo .dojoDndAvatar tr	{ border: none; }
+.nihilo .dojoDndAvatarHeader td	{ height: 20px; padding: 0 0 0 21px; }
+.nihilo .dojoDndAvatarItem td { padding: 2px;}
+.nihilo.dojoDndMove .dojoDndAvatarHeader	{background-color: #f58383; background-image: url(images/dndNoMove.png); background-repeat: no-repeat; background-position: 2px center;}
+.nihilo.dojoDndCopy .dojoDndAvatarHeader	{background-color: #f58383; background-image: url(images/dndNoCopy.png); background-repeat: no-repeat; background-position: 2px center;}
+.nihilo.dojoDndMove .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{background-color: #97e68d; background-image: url(images/dndMove.png); background-repeat: no-repeat; background-position: 2px center;}
+.nihilo.dojoDndCopy .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{background-color: #97e68d; background-image: url(images/dndCopy.png); background-repeat: no-repeat; background-position: 2px center;}
+.nihilo .dijitContentPane {
+    padding: 0px;
+}
+.nihilo .dijitTabContainerTop-dijitContentPane,
+.nihilo .dijitTabContainerLeft-dijitContentPane,
+.nihilo .dijitTabContainerRight-dijitContentPane,
+.nihilo .dijitTabContainerBottom-dijitContentPane,
+.nihilo .dijitAccordionContainer-dijitContentPane {
+    background-color: #fff;
+    padding: 5px;
+}
+.nihilo .dijitSplitContainer-dijitContentPane,
+.nihilo .dijitBorderContainer-dijitContentPane {
+    background-color: #fff;		
+    padding: 5px;
+}
+ 
+ 
+.nihilo .dijitTabPaneWrapper {
+	background:#fff;
+	border:1px solid #ccc;
+	margin: 0;
+	padding: 0;
+}
+.nihilo .dijitTabInnerDiv {
+	padding:0px 3px 0px 0px;
+	margin: 0 0 0 4px;
+	background: url(images/tabContainerSprite.gif) no-repeat;
+	background-position: right -400px;
+}
+.nihilo .dijitTab {
+	line-height:normal;
+	margin:0 2px 0 0;	
+	padding:0px;
+	background: url(images/tabContainerSprite.gif) no-repeat 0 -300px;
+	color: #6d6d6d;
+	border-bottom: 1px #ccc solid;
+}
+.nihilo .dijitTabInnerDiv .dijitTabContent {
+	padding:5px 3px 4px 4px;
+	background: url(images/tabContainerSprite.gif) repeat-x 0 -350px;
+	position: relative;
+}
+.dijitTabSpacer {
+	font-size: 1px;
+}
+.nihilo .dijitTabHover {
+	color: #243C5F;
+	background: url(images/tabContainerSprite.gif) no-repeat 0px -150px;
+}
+.nihilo .dijitTabHover .dijitTabInnerDiv {
+	background: url(images/tabContainerSprite.gif) no-repeat right -250px;
+}
+.nihilo .dijitTabHover .dijitTabInnerDiv .dijitTabContent {
+	background: url(images/tabContainerSprite.gif) repeat-x 0 -200px;
+}
+.nihilo .dijitTabChecked,
+.nihilo .dijitTabCloseButtonChecked
+{
+	
+	background: url(images/tabContainerSprite.gif) no-repeat 0px -0px;
+}
+.nihilo .dijitTabChecked .dijitTabInnerDiv {
+	background: url(images/tabContainerSprite.gif) no-repeat right -100px;
+}
+.nihilo .dijitTabChecked .dijitTabInnerDiv .dijitTabContent {
+	background: url(images/tabContainerSprite.gif) repeat-x 0 -50px;
+	color: #243C5F !important;
+}
+.nihilo .dijitTabContainerTabListNested {
+	background: #FDFDFD;
+	border: none;
+	margin-bottom: 0px;		
+}
+.nihilo .dijitTabContainerTabListNested .dijitTab {
+	background: none;
+	border: none;
+	top: 0px;	
+}
+.nihilo .dijitTabContainerTabListNested .dijitTab .dijitTabInnerDiv,
+.nihilo .dijitTabContainerTabListNested .dijitTab .dijitTabContent {
+	background: none;
+}
+.nihilo .dijitTabContainerTabListNested .dijitTabHover .dijitTabContent .tabLabel {
+	text-decoration: underline;
+}
+.nihilo .dijitTabContainerTabListNested .dijitTabChecked .tabLabel {
+	text-decoration: underline;
+	font-weight: bold;
+}
+.nihilo .dijitTabContainerSpacerNested {
+	
+	height: 0px;
+	border-bottom: 0px;
+}
+.nihilo .dijitTabPaneWrapperNested {
+	border: none;	
+}
+.nihilo .dijitTab .closeImage {
+	background: url(images/spriteRoundedIconsSmall.png) no-repeat -60px top;
+	width: 15px;
+	height: 15px;
+}
+.dj_ie6 .dijitTab .closeImage {
+	background: url(images/spriteRoundedIconsSmall.gif) no-repeat -60px top;
+}
+.nihilo .dijitTab .closeButton-hover .closeImage {
+	background: url(images/spriteRoundedIconsSmall.png) no-repeat -60px -15px;
+}
+.dj_ie6 .nihilo .dijitTab .closeButton-hover .closeImage {
+	background: url(images/spriteRoundedIconsSmall.gif) no-repeat -60px -15px;
+}
+.nihilo .dijitTab .dijitTabButtonSpacer {
+	height: 15px;
+	width: 1px;
+}
+.nihilo .dijitTabContainerTop-tabs {
+	margin-bottom: -1px;
+	border-color: #ccc;
+	padding-left: 3px;
+}
+.nihilo .dijitTabContainerTop-container {
+	border-top: none;
+}
+.nihilo .dijitTabContainerTop-tabs .dijitTabChecked {
+	border-bottom-color: #f8f8f8;
+}
+.nihilo .dijitTabContainerTopStrip {
+	border: 1px solid #ccc;
+	padding-top: 2px;
+	padding-left: 3px;
+}
+.nihilo .dijitTabContainerTopStrip {
+	background: #f2f2f2;
+}
+.nihilo .dijitTabContainerBottom-tabs {
+	margin-top: -1px;
+	border-color: #ccc;
+	padding-left: 3px;
+}
+.nihilo .dijitTabContainerBottom-container {
+	border-bottom: none;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTab {
+	border-bottom: none;
+	border-top: 1px solid #ccc;
+	background: url(images/tabBottomEnabledSpriteLR.gif) no-repeat bottom left;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTabChecked {
+	border-top-color:#f8f8f8;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTabInnerDiv .dijitTabContent {
+	padding-top: 4px;
+	padding-bottom: 5px;
+	background: url(images/tabBottomEnabledC.gif) repeat-x bottom left;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTabInnerDiv {
+	background: url(images/tabBottomEnabledSpriteLR.gif) no-repeat bottom right;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTabHover {
+	color: #243C5F;
+	background: url(images/tabBottomHoverSpriteLR.gif) no-repeat bottom left;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTabHover .dijitTabInnerDiv {
+	background: url(images/tabBottomHoverSpriteLR.gif) no-repeat bottom right;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTabHover .dijitTabInnerDiv .dijitTabContent {
+	background: url(images/tabBottomHoverC.gif) repeat-x bottom left;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTabChecked,
+.nihilo .dijitTabContainerBottom-tabs .dijitTabCloseButtonChecked
+{
+	
+	background: url(images/tabBottomActiveSpriteLR.gif) no-repeat bottom left;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabInnerDiv {
+	background: url(images/tabBottomActiveSpriteLR.gif) no-repeat bottom right;
+}
+.nihilo .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabInnerDiv .dijitTabContent {
+	background: url(images/tabBottomActiveC.gif) repeat-x bottom left;
+}
+.nihilo .dijitTabContainerBottomStrip {
+	padding-bottom: 2px;
+	padding-left: 3px;	
+	border: 1px solid #ccc;
+}
+.nihilo .dijitTabContainerBottomStrip {
+	background: #f2f2f2;
+}
+.nihilo .dijitTabContainerBottom-spacer,
+.nihilo .dijitTabContainerTop-spacer {
+	height: 2px;
+	border: 1px solid #ccc;
+	background: #f8f8f8;
+}
+.nihilo .dijitTabContainerRight-tabs {
+	margin-left: -1px;
+	border-color: #ccc;
+	padding-top: 3px;
+}
+.nihilo .dijitTabContainerRight-container {
+	border-right: none;
+}
+.nihilo .dijitTabContainerRight-tabs .dijitTab {
+	border-bottom: none;
+	border-left: 1px solid #ccc;
+	border-bottom: 1px solid #dedede !important;
+}
+.dj_ie .nihilo .dijitTabContainerRight-tabs .dijitTabInnerDiv {
+	border-bottom: solid #fff 1px;
+}
+.nihilo .dijitTabContainerRight-tabs .dijitTabChecked {
+	border-left-color: #f8f8f8;
+}
+.nihilo .dijitTabContainerRight-tabs .dijitTabChecked {
+	background: url(images/tabRightChecked.gif) no-repeat left top !important;
+}
+.dj_ie .nihilo .dijitTabContainerRight-tabs .dijitTabChecked .dijitTabInnerDiv,
+.dj_ie .nihilo .dijitTabContainerRight-tabs .dijitTabCheckedHover .dijitTabInnerDiv {
+	border-bottom: solid #efefef 1px;
+}
+.nihilo .dijitTabContainerRight-tabs .dijitTab {
+	background: url(images/tabContainerSprite.gif) no-repeat left -350px;
+}
+.nihilo .dijitTabContainerRight-tabs .dijitTabHover .dijitTab {
+	background: url(images/tabContainerSprite.gif) no-repeat left -200px;
+}
+.nihilo .dijitTabContainerRightStrip {
+	padding-right: 2px;
+	padding-top: 3px;	
+	border: 1px solid #ccc;
+}
+.nihilo .dijitTabContainerRightStrip {
+	background: #f2f2f2;
+}
+.nihilo .dijitTabContainerLeft-tabs {
+	margin-right: -1px;
+	border-color: #ccc;
+	padding-top: 3px;
+}
+.nihilo .dijitTabContainerLeft-container {
+	border-left: none;
+}
+.nihilo .dijitTabContainerLeft-tabs .dijitTab {
+	border-right: 1px solid #ccc;
+	border-bottom: 1px solid #dedede;
+}
+.nihilo .dijitTabContainerLeft-tabs .dijitTabChecked {
+	border-right: 1px solid #f8f8f8;
+}
+.nihilo .dijitTabContainerLeft-tabs .dijitTabInnerDiv {
+	background: url(images/tabContainerSprite.gif) no-repeat right -350px;
+}
+.nihilo .dijitTabContainerLeft-tabs .dijitTabHover .dijitTabInnerDiv {
+	background: url(images/tabContainerSprite.gif) no-repeat right -200px;
+}
+.nihilo .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabInnerDiv,
+.nihilo .dijitTabContainerLeft-tabs .dijitTabCheckedHover .dijitTabInnerDiv {
+	background: url(images/tabLeftChecked.gif) no-repeat right top;
+}
+.dj_ie .nihilo .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabInnerDiv,
+.dj_ie .nihilo .dijitTabContainerLeft-tabs .dijitTabCheckedHover .dijitTabInnerDiv {
+	border-bottom: solid #efefef 1px;
+}
+.dj_ie .nihilo .dijitTabContainerLeft-tabs .dijitTabInnerDiv {
+border-bottom: solid #fff 1px;
+}
+.nihilo .dijitTabContainerLeftStrip {
+	padding-left: 2px;
+	padding-top: 3px;	
+	border: 1px solid #ccc;
+}
+.nihilo .dijitTabContainerLeftStrip {
+	background: #f2f2f2;
+}
+.nihilo .dijitTabContainerLeft-tabs .dijitTab,
+.nihilo .dijitTabContainerRight-tabs .dijitTab {
+	margin-right:auto;
+	margin-bottom:2px;	
+}
+.nihilo .dijitTabContainerLeft-spacer,
+.nihilo .dijitTabContainerRight-spacer {
+	width: 2px;
+	border: 1px solid #ccc;
+	background: #f8f8f8;
+}
+.nihilo .dijitTabContainerTop-dijitContentPane .dijitTabContainerTop-tabs {
+	border-left: 0px solid #ccc;
+	border-top: 0px solid #ccc;
+	border-right: 0px solid #ccc;
+	padding-top: 0px;
+	padding-left: 0px;	
+}
+.nihilo .dijitAccordionContainer {
+	border-color: #ccc;
+	background-color: #fff;
+}
+.nihilo .dijitAccordionTitle {
+	background:#fafafa url(images/titleBar.png) repeat-x top left;
+	border-top: 1px solid #dedede;
+	padding: 5px 4px 6px 8px;
+	cursor:pointer;
+	font-size: 0.9em;
+	font-weight: bold;
+	color: #6d6d6d;
+}
+.nihilo .dijitAccordionTitle-selected  {
+	background: #f9f9f9 url(images/accordionItemActive.png) top repeat-x;
+	font-weight: bold;
+	border-top: 1px solid #dedede;
+	border-bottom: 1px solid #dedede;
+	padding: 5px 4px 5px 8px;
+	cursor: default;	
+	color: #243C5F;
+}
+.nihilo .dijitAccordionArrow {
+	background:url(images/spriteRoundedIconsSmall.gif) no-repeat -30px top;
+	width:15px;
+	height:15px;
+	margin-top:-1px;
+}
+.nihilo .dijitAccordionTitle-selected .dijitAccordionArrow {
+	background:url(images/spriteRoundedIconsSmall.gif) no-repeat -15px top;
+	margin-top:-1px;
+}
+.nihilo .dijitAccordionText {
+	margin-left: 4px;
+	margin-right: 4px;
+}
+ 
+.nihilo .dijitSplitContainerSizerH {
+	background:url(images/splitContainerSizerV.png) repeat-y #fff;
+	border:0;
+	border-left:0px solid #d3d3d3;
+	border-right:0px solid #d3d3d3;
+	width:5px;
+}
+.nihilo .dijitSplitContainerSizerH .thumb {
+	background:url(images/splitContainerSizerV-thumb.png) no-repeat;
+	left:1px;
+	width:2px;
+	height:19px;
+}
+.nihilo .dijitSplitContainerSizerV {
+	background:url(images/splitContainerSizerH.png) repeat-x #fff;
+	border:0;
+	border-top:0px solid #d3d3d3;
+	border-bottom:0px solid #d3d3d3;
+	height:2px;
+}
+.nihilo .dijitSplitContainerSizerV .thumb {
+	background:url(images/splitContainerSizerH-thumb.png) no-repeat;
+	top:1px;
+	width:19px;
+	height:5px;
+}
+ 
+.nihilo .dijitBorderContainer {
+	background-color: #fcfcfc;
+	padding: 5px;
+}
+.nihilo .dijitSplitContainer-child,
+.nihilo .dijitBorderContainer-child {
+	
+    border: 1px #ccc solid;
+}
+.nihilo .dijitBorderContainer-dijitTabContainerTop,
+.nihilo .dijitBorderContainer-dijitTabContainerBottom,
+.nihilo .dijitBorderContainer-dijitTabContainerLeft,
+.nihilo .dijitBorderContainer-dijitTabContainerRight {
+	
+	 border: none;
+}
+.nihilo .dijitBorderContainer-dijitBorderContainer {
+	
+	border: none;
+	padding: 0px;
+}
+.nihilo .dijitSplitterH,
+.nihilo .dijitGutterH {
+	background:#FCFCFC;
+	border:0;
+	border-left:0px solid #d3d3d3;
+	border-right:0px solid #d3d3d3;
+	height:5px;
+}
+.nihilo .dijitSplitterH .dijitSplitterThumb {
+	background:url(images/splitContainerSizerH-thumb.png) no-repeat;
+	top:1px;
+	width:19px;
+	height:2px;
+}
+.nihilo .dijitSplitterV,
+.nihilo .dijitGutterV {
+	background:#FCFCFC;
+	border:0;
+	border-top:0px solid #d3d3d3;
+	border-bottom:0px solid #d3d3d3;
+	width:5px;
+}
+.nihilo .dijitSplitterV .dijitSplitterThumb {
+	background:url(images/splitContainerSizerV-thumb.png) no-repeat;
+	left:1px;
+	height:19px;
+	width:5px;
+}
+.nihilo .dijitSplitterActive {
+	font-size: 1px;
+	background-image: none;
+	background-color: #aaa;
+	-moz-opacity: 0.6;
+	opacity: 0.6;
+	filter: Alpha(Opacity=60);
+	margin: 0;
+}
+.nihilo .dijitInputField INPUT,
+.nihilo .dijitTextBox,
+.nihilo .dijitComboBox,
+.nihilo .dijitSpinner {
+	margin: 0em 0.1em;
+}
+.nihilo .dijitTextBox,
+.nihilo .dijitComboBox,
+.nihilo .dijitSpinner,
+.nihilo .dijitInlineEditor input,
+.nihilo .dijitTextArea {
+	
+	background:#fff url(images/validationInputBg.png) repeat-x top left;
+	border:1px solid #d3d3d3;
+	line-height: normal;
+}
+.dj_ie6 .nihilo .dijitTextBox,
+.dj_ie6 .nihilo .dijitComboBox,
+.dj_ie6 .nihilo .dijitSpinner,
+.dj_ie6 .nihilo .dijitInlineEditor input,
+.dj_ie6 .nihilo .dijitTextArea {
+	background:#fff url(images/validationInputBg.gif) repeat-x top left;
+}
+.nihilo .dijitComboBox .dijitButtonNode {
+	padding: 0 0.2em;
+}
+.nihilo .dijitComboBox .dijitButtonNode,
+.nihilo .dijitSpinner .dijitButtonNode {
+	
+	border-color: #d3d3d3;
+	border-left: 1px solid #d3d3d3;
+}
+.nihilo .dijitTextBoxDisabled,
+.nihilo .dijitComboBoxDisabled,
+.nihilo .dijitSpinnerDisabled,
+.nihilo .dijitTextAreaDisabled {
+	color: gray;
+}
+.dj_webkit .nihilo .dijitTextBoxDisabled,
+.dj_webkit .nihilo .dijitComboBoxDisabled,
+.dj_webkit .nihilo .dijitSpinnerDisabled,
+.dj_webkit .nihilo .dijitTextareaDisabled {
+	color: #eee;
+}
+.nihilo .dijitTextBoxFocused,
+.nihilo .dijitComboBoxFocused,
+.nihilo .dijitSpinnerFocused, .nihilo .dijitSpinnerUpArrowActive, .nihilo .dijitSpinnerDownArrowActive,
+.nihilo .dijitTextAreaFocused {
+	
+	border-color:#b3b3b3;
+}
+.nihilo .dijitComboBoxFocused .dijitButtonNode,
+.nihilo .dijitSpinnerFocused .dijitButtonNode,
+.nihilo .dijitSpinnerUpArrowActive .dijitButtonNode,
+.nihilo .dijitSpinnerDownArrowActive .dijitButtonNode {
+	border-left-color:#d3d3d3;
+}
+.nihilo .dijitSpinnerFocused .dijitDownArrowButton,
+.nihilo .dijitSpinnerUpArrowActive .dijitDownArrowButton,
+.nihilo .dijitSpinnerDownArrowActive .dijitDownArrowButton {
+	border-top-color:#d3d3d3;
+}
+.nihilo .dijitError {
+	border-color:#b3b3b3;
+	background-color:#f9f7ba;
+	background-image:none;
+}
+.dj_ie6 .nihilo .dijitError INPUT {
+	
+	background-color:#f9f7ba !important;
+}
+.nihilo .dijitErrorFocused {
+	background-color:#ff6;
+	background-image:none;
+}
+.dj_ie6 .nihilo .dijitErrorFocused INPUT {
+	
+	background-color:#ff6 !important;
+}
+.nihilo .dijitValidationIcon {
+	
+	width: 16px;
+	background: transparent url(images/warning.png) no-repeat center center;
+}
+.nihilo .dijitComboBoxHighlightMatch {
+	background-color:#d3d3d3;
+}
+.nihilo .dijitButtonNode {
+	
+	
+	border:1px solid #dedede;
+	border-bottom:1px solid #dedede;
+	padding: 0.1em 0.2em 0.2em 0.2em; 
+	background: #fff url(images/buttonEnabled.png) repeat-x top left;
+}
+.nihilo .dijitButtonNode button { 
+	border: 0px; 
+	background-color: transparent; 
+} 
+ 
+.nihilo .dijitButtonText {
+	text-align: center; 
+	padding: 0 0.3em;
+}
+.nihilo .dijitComboBox .dijitButtonNode {
+	border-width: 0px 0px 0px 1px;
+}
+.nihilo .dijitArrowButton {
+	color: #111;
+}
+.nihilo .dijitComboButton .dijitDownArrowButton {
+	padding-right:4px;
+}
+.dj_ff2 .nihilo .dijitComboButton .dijitButtonContentsFocused,
+.dj_ff2 .nihilo .dijitComboButton .dijitDownArrowButtonFocused {
+	border: 1px black dotted !important;
+}
+.nihilo .dijitButtonDisabled .dijitButtonNode,
+.nihilo .dijitToggleButtonDisabled .dijitButtonNode,
+.nihilo .dijitDropDownButtonDisabled .dijitButtonNode,
+.nihilo .dijitComboButtonDisabled .dijitButtonNode,
+.nihilo .dijitComboBoxDisabled,
+.nihilo .dijitSpinnerDisabled,
+.nihilo .dijitSpinnerDisabled .dijitButtonNode {
+	
+	border-color: #dedede;
+	background:#fafafa url(images/buttonDisabled.png) top repeat-x;
+	opacity: 0.60; 
+}
+.nihilo .dijitButtonHover .dijitButtonNode,
+.nihilo .dijitButtonNodeHover,
+.nihilo .dijitToggleButtonHover .dijitButtonNode,
+.nihilo .dijitDropDownButtonHover .dijitButtonNode,
+.nihilo .dijitComboButtonHover .dijitButtonContents,
+.nihilo .dijitComboButtonDownArrowHover .dijitDownArrowButton,
+.nihilo .dijitComboBoxHover .dijitDownArrowButton,
+.nihilo .dijitSpinnerUpArrowHover .dijitUpArrowButton,
+.nihilo .dijitSpinnerDownArrowHover .dijitDownArrowButton {
+	
+	
+	color:#243C5F;
+	background:#fcfcfc url(images/buttonHover.png) repeat-x top left;
+}
+.nihilo .dijitSpinnerUpArrowActive .dijitUpArrowButton,
+.nihilo .dijitSpinnerDownArrowActive .dijitDownArrowButton,
+.nihilo .dijitButtonActive .dijitButtonNode,
+.nihilo .dijitToggleButtonActive .dijitButtonNode,
+.nihilo .dijitDropDownButtonActive .dijitButtonNode,
+.nihilo .dijitComboButtonActive .dijitButtonContents,
+.nihilo .dijitDownArrowActive .dijitDownArrowButton,
+.nihilo .dijitComboBoxActive .dijitDownArrowButton,
+.nihilo .dijitStackController .dijitToggleButtonChecked .dijitButtonNode {
+	
+	border-color:#dedede;
+	background: #f5f5f5 url(images/buttonActive.png) top left repeat-x;
+}
+.nihilo .dijitArrowButtonInner {
+	background:url(images/spriteArrows.png) no-repeat left top;
+	width: 11px;
+}
+.nihilo .dijitUpArrowButton .dijitArrowButtonInner { 
+	background:url(images/spriteArrows.png) no-repeat -22px top; 
+	width: 11px;
+}
+.dj_ie6 .nihilo .dijitArrowButtonInner {
+	background:url(images/spriteArrows.gif) no-repeat left top;
+	width: 11px;
+}
+.dj_ie6 .nihilo .dijitUpArrowButton .dijitArrowButtonInner {
+	background:url(images/spriteArrows.gif) no-repeat -22px top;
+	width: 11px;
+}
+.nihilo .dijitComboBox .dijitArrowButton .dijitArrowButtonInner {
+	background:url(images/spriteArrows.png) no-repeat left center;
+	width: 11px;
+}
+.dj_ie6 .nihilo .dijitComboBox .dijitArrowButton .dijitArrowButtonInner {
+	background:url(images/spriteArrows.gif) no-repeat left center;
+}
+.nihilo .dijitComboBoxHover .dijitArrowButtonInner {
+	
+}
+.nihilo .dijitToggleButton .dijitCheckBox,
+.nihilo .dijitToggleButton .dijitCheckBoxIcon {
+	background-image: url(images/spriteCheckbox.gif);
+}
+.nihilo .dijitCheckBox,
+.nihilo .dijitCheckBoxIcon {		
+	background-image: url(images/spriteCheckbox.gif); 
+	background-repeat: no-repeat;
+	width: 16px;
+	height: 16px;
+	margin: 0;
+	padding: 0;
+}
+.nihilo .dijitCheckBox,
+.nihilo .dijitToggleButton .dijitCheckBoxIcon {
+	
+	background-position: -16px;
+}
+.nihilo .dijitCheckBoxChecked,
+.nihilo .dijitToggleButtonChecked .dijitCheckBoxIcon {
+	
+	background-position: 0px;
+}
+.nihilo .dijitCheckBoxDisabled {
+	
+	background-position: -48px;
+}
+.nihilo .dijitCheckBoxCheckedDisabled {
+	
+	background-position: -32px;
+}
+.nihilo .dijitCheckBoxHover {
+	
+	background-position: -80px;
+}
+.nihilo .dijitCheckBoxCheckedHover {
+	
+	background-position: -64px;
+}
+.nihilo .dijitToggleButton .dijitRadio,
+.nihilo .dijitToggleButton .dijitRadioIcon {
+	background-image: url(images/spriteRadio.gif);
+}
+.nihilo .dijitRadio,
+.nihilo .dijitRadioIcon	{		
+	background-image: url(images/spriteRadio.gif); 
+	background-repeat: no-repeat;
+	width: 16px;
+	height: 16px;
+	margin: 0;
+	padding: 0;
+}
+.nihilo .dijitRadio,
+.nihilo .dijitToggleButton .dijitRadioIcon {
+	
+	background-position: -16px;
+}
+.nihilo .dijitRadioChecked,
+.nihilo .dijitToggleButtonChecked .dijitRadioIcon {
+	
+	background-position: 0px;
+}
+.nihilo .dijitRadioDisabled {
+	
+	background-position: -48px;
+}
+.nihilo .dijitRadioCheckedDisabled {
+	
+	background-position: -32px;
+}
+.nihilo .dijitRadioHover {
+	
+	background-position: -80px;
+}
+.nihilo .dijitRadioCheckedHover {
+	
+	background-position: -64px;
+}
+.nihilo .dijitSliderProgressBarH {
+	border-color: #aab0bb;
+	background: #c0c2c5 url(images/sliderFull.png) repeat-x top left;
+}
+.nihilo .dijitSliderProgressBarV {
+	border-color: #aab0bb;
+	background: #c0c2c5 url(images/sliderFullVertical.png) repeat-y bottom left;
+}
+.nihilo .dijitSliderFocused .dijitSliderProgressBarH,
+.nihilo .dijitSliderFocused .dijitSliderLeftBumper {
+	background-image:url(images/sliderFullFocus.png);
+}
+.nihilo .dijitSliderFocused .dijitSliderProgressBarV,
+.nihilo .dijitSliderFocused .dijitSliderBottomBumper {
+	background-image:url(images/sliderFullVerticalFocus.png);
+}
+.nihilo .dijitSliderRemainingBarV {
+	border-color: #b4b4b4;
+	background: #dcdcdc url(images/sliderEmptyVertical.png) repeat-y bottom left;
+}
+.nihilo .dijitSliderRemainingBarH {
+	border-color: #b4b4b4;
+	background: #dcdcdc url(images/sliderEmpty.png) repeat-x top left;
+}
+.nihilo .dijitSliderBar {
+	border-style: solid;
+	outline:1px;
+	
+}
+.nihilo .dijitSliderFocused .dijitSliderBar {
+	border-color:#727272;	
+}
+.dijit_a11y .dijitSliderProgressBar {
+	background-color:#333 !important;
+}
+.nihilo .dijitSliderImageHandleH {
+	border:0px;
+	width:15px;
+	height:18px;
+	background:url(images/preciseSliderThumb.png) no-repeat center top;
+	#background:url(images/preciseSliderThumb.gif) no-repeat center top;
+	cursor:pointer;
+}
+.nihilo .dijitSliderFocused .dijitSliderImageHandleH {
+	background-image:url(images/preciseSliderThumbFocus.png);
+	#background-image:url(images/preciseSliderThumbFocus.gif);
+}
+.nihilo .dijitSliderLeftBumper {
+	border-left-width: 1px;
+	border-color: #aab0bb;
+	background: #c0c2c5 url(images/sliderFull.png) repeat-x top left;
+}
+.nihilo .dijitSliderRightBumper {
+	background: #dcdcdc url(images/sliderEmpty.png) repeat-x top left;
+	border-color: #b4b4b4;
+	border-right-width: 1px;
+}
+.nihilo .dijitSliderImageHandleV {
+	border:0px;
+	width:20px;
+	height:15px;
+	background:url(images/sliderThumb.png) no-repeat center center;
+	#background:url(images/sliderThumb.gif) no-repeat center center;
+	cursor:pointer;
+}
+.nihilo .dijitSliderFocused .dijitSliderImageHandleV {
+	background-image:url(images/sliderThumbFocus.png);
+	#background-image:url(images/sliderThumbFocus.gif);
+}
+.nihilo .dijitSliderBottomBumper {
+	border-bottom-width: 1px;
+	border-color: #aab0bb;
+	background: #c0c2c5 url(images/sliderFullVertical.png) repeat-y bottom left;
+}
+.nihilo .dijitSliderTopBumper {
+	background: #dcdcdc url(images/sliderEmptyVertical.png) repeat-y top left;
+	border-color: #b4b4b4;
+	border-top-width: 1px;
+}
+.nihilo .dijitSliderIncrementIconH,
+.nihilo .dijitSliderIncrementIconV {
+	background:url(images/spriteRoundedIconsSmall.png) no-repeat -45px top;
+	#background:url(images/spriteRoundedIconsSmall.gif) no-repeat -45px top;
+	width:15px; height:15px;
+	cursor:pointer;
+}
+.nihilo .dijitSliderIncrementIconH {
+	background:url(images/spriteRoundedIconsSmall.png) no-repeat -30px top;
+	#background:url(images/spriteRoundedIconsSmall.gif) no-repeat -30px top;
+}
+.nihilo .dijitSliderDecrementIconH,
+.nihilo .dijitSliderDecrementIconV {
+	width:15px;
+	height:15px;
+	cursor:pointer;
+	background:url(images/spriteRoundedIconsSmall.png) no-repeat -15px top;
+	#background:url(images/spriteRoundedIconsSmall.gif) no-repeat -15px top;
+}
+.nihilo .dijitSliderDecrementIconH { 
+	background:url(images/spriteRoundedIconsSmall.png) no-repeat 0px top; 
+	#background:url(images/spriteRoundedIconsSmall.gif) no-repeat 0px top; 
+}
+.nihilo .dijitSliderButtonInner {
+	visibility:hidden;
+}
+.nihilo .dijitSliderDisabled {
+	opacity:0.6 !important;
+}
+.dj_ie .nihilo .dijitSliderDisabled,
+.dj_ie .nihilo .dijitSliderDisabled .dijitRuleContainer,
+.dj_ie .nihilo .dijitSliderDisabled .dijitSliderRemainingBar,
+.dj_ie .nihilo .dijitSliderDisabled .dijitSliderProgressBar {
+	filter: gray() alpha(opacity=40);
+}
+.nihilo .dijitTreeNode {
+    background : url(images/treeI.gif) no-repeat;
+    background-position : top left;
+    background-repeat : repeat-y;
+    zoom: 1;	
+}
+.nihilo .dijitTreeIsLast {
+    background: url(images/treeI_half.gif) no-repeat;
+}
+.nihilo .dijitTreeNodeHover {
+	
+	background-image: url(images/treeHover.png);
+	background-repeat: repeat;
+	background-color: none !important;
+}
+.nihilo .dijitTreeLabel {
+	font-weight: normal;
+	margin-left: 3px;	
+}
+.nihilo .dijitTreeIsRoot {
+    margin-left: 0;
+    background-image: none;
+}
+.nihilo .dijitTreeExpando {
+    width: 18px;
+    height: 18px;
+}
+.nihilo .dijitTreeRow {
+	
+	padding-bottom: 2px;
+}
+.nihilo .dijitTreeContent {
+    min-height: 18px;
+    min-width: 18px;
+    padding-left:1px;
+}
+.nihilo .dijitTreeExpand {
+    width: 18px;
+    height: 18px;
+    background-repeat : no-repeat;
+}
+.nihilo .dijitTreeNodeEmphasized {
+    background-color: Highlight;
+    color: HighlightText;
+}
+.nihilo .dijitTreeLabelFocused {
+	outline: 1px invert dotted;
+}
+.nihilo .dijitTreeExpandoOpened {
+	background: url(images/spriteTree.gif) no-repeat -18px top;
+}
+.nihilo .dijitTreeExpandoClosed {
+	background-image: url(images/spriteTree.gif);
+}
+.nihilo .dijitTreeExpandoLeaf {
+	background: url(images/spriteTree.gif) no-repeat -36px top;
+}
+.nihilo .dijitTreeExpandoLoading {
+	background-image: url(images/treeExpand_loading.gif);
+}
+.nihilo .dijitTreeIcon {
+	width: 16px;
+	height: 16px;
+}
+.nihilo .dijitFolderOpened {
+	background: url(images/spriteDivIcons.gif) no-repeat -16px top;
+}
+.nihilo .dijitFolderClosed {
+	background: url(images/spriteDivIcons.gif) no-repeat top left;
+}
+.nihilo .dijitLeaf {
+	background: url(images/spriteDivIcons.gif) no-repeat -32px top;
+}
+.nihilo .dijitTreeNode .dojoDndItemBefore,
+.nihilo .dijitTreeNode .dojoDndItemAfter {
+	border-bottom: none;
+	border-top: none;
+}
+.nihilo .dijitTreeNode .dojoDndItemBefore .dijitTreeContent {
+	
+	border-top: 2px solid #369;
+}
+.nihilo .dijitTreeNode .dojoDndItemAfter .dijitTreeContent {
+	
+	border-bottom: 2px solid #369;
+}
+.nihilo .dijitProgressBar {
+	margin:2px 0px 2px 0px;
+}
+.nihilo .dijitProgressBarEmpty{
+	
+	background:#fff url(images/progressBarEmpty.png) repeat-x center center;
+	border-color: #f8d582 #f8d582 #f8d582 #f8d582;
+}
+.nihilo .dijitProgressBarTile{
+	
+	background:#f0f0f0 url(images/progressBarFull.png) repeat-x center center;
+}
+.nihilo .dijitProgressBarFull {
+	border-right:1px solid #f8d582;
+}
+.nihilo .dijitProgressBarLabel {
+	
+	color:#293a4b;
+}
+.nihilo .dijitProgressBarIndeterminate .dijitProgressBarTile {
+	
+	background:#cad2de url(images/progressBarAnim.gif) repeat-x center center;
+}
+ 
+ 
+.nihilo .dijitTitlePaneTitle {
+	background: #cccccc;
+	background:#fff url(images/titleBar.png) repeat-x top left;
+	border:1px solid #bfbfbf;
+	padding:3px 4px;
+	cursor: pointer;
+	font-size: 0.9em;
+	font-weight: bold;
+	color: #6d6d6d;
+}
+.nihilo .dijitTitlePaneTitle-hover  {
+	background: #f9f9f9 url(images/accordionItemActive.png) top repeat-x;
+}
+.nihilo .dijitTitlePaneTitle * {
+	vertical-align: middle;
+}
+.nihilo .dijitTitlePane .dijitArrowNode {
+	width:15px;
+	height:15px;
+}
+.nihilo .dijitTitlePaneFocused .dijitTitlePaneTextNode {
+	color: #243C5F;
+}
+.nihilo .dijitOpen .dijitTitlePaneTextNode {
+	color: #243C5F;
+}
+.nihilo .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background: url(images/spriteRoundedIconsSmall.png) no-repeat -30px top;
+}
+.dj_ie6 .nihilo .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background:url(images/spriteRoundedIconsSmall.gif) no-repeat -30px top;
+}
+.nihilo .dijitTitlePane .dijitOpen .dijitArrowNode {
+	background:url(images/spriteRoundedIconsSmall.png) no-repeat -15px top;
+}
+.dj_ie6 .nihilo .dijitTitlePane .dijitOpen .dijitArrowNode {
+	background:url(images/spriteRoundedIconsSmall.gif) no-repeat -15px top;
+}
+.nihilo .dijitTitlePane .dijitArrowNodeInner {
+	display:none;
+}
+.dijit_a11y .dijitTitlePane .dijitArrowNodeInner {
+	display:inline !important;
+	font-family:monospace;
+	cursor: pointer;
+	padding-bottom:.2em;
+}
+.dijit_a11y .dijitTitlePane .dijitArrowNode {
+	display:none;
+}
+.nihilo .dijitTitlePaneContentOuter {
+	background: #ffffff;
+	border:1px solid #bfbfbf;
+	border-top: 0px solid #3d3d3d;	
+}
+.nihilo .dijitTitlePaneContentInner {
+	padding:10px;
+}
+.dj_ie6 .nihilo .dijitTitlePaneContentOuter,
+.dj_ie6 .nihilo .dijitTitlePane .dijitTitlePaneTitle {
+	zoom: 1;
+}
+.nihilo .dijitTitlePaneTextNode {
+	margin-left: 4px;
+	margin-right: 4px;
+}
+	
+.nihilo .dijitCalendarIncrementControl {
+	
+	width:15px;
+	height:15px;
+	background-image: url(images/spriteRoundedIconsSmall.png);
+	background-repeat: no-repeat
+}
+.dj_ie6 .nihilo .dijitCalendarIncrementControl {
+	font-size:.1em;
+	background-image: url(images/spriteRoundedIconsSmall.gif);
+}
+.nihilo .dijitA11ySideArrow {
+	display: none;
+}
+.nihilo .dijitCalendarDecrease {
+	background-position: top left;
+}
+.nihilo .dijitCalendarIncrease {
+	background-position: -30px top;
+}
+.nihilo table.dijitCalendarContainer {
+	font-size: 100%;
+	border-spacing: 0;
+	border-collapse: separate;
+	border: 1px solid #ccc;
+	margin: 0;
+}
+.nihilo .dijitCalendarMonthContainer th {
+	
+	background:#d3d3d3 url(images/titleBar.png) repeat-x top;
+	padding-top:.3em;
+	padding-bottom:.2em;
+	text-align:center;
+}
+.dj_ie6 .nihilo .dijitCalendarMonthContainer th {
+	padding-top:.2em;
+	padding-bottom:.1em;
+	
+}
+.nihilo .dijitCalendarDayLabelTemplate {
+	
+	background:#fefefe;
+	font-weight:normal;
+	padding-top:.15em;
+	padding-bottom:.2em;
+	border-bottom: 1px solid #eeeeee;
+	color:#293a4b;
+	text-align:center;
+}
+.nihilo .dijitCalendarBodyContainer {
+	border-bottom: 1px solid #eeeeee;	
+}
+.nihilo .dijitCalendarMonthLabel {
+	color:#293a4b;
+	font-weight: bold;
+}
+.nihilo .dijitCalendarDateTemplate {
+	
+	font-size: 0.9em;
+	font-weight: bold;
+	text-align: center;
+	padding: 0.3em 0.3em 0.05em 0.3em;
+	letter-spacing: 1px;
+	background-color: #fdfdfd;
+	border:#fdfdfd solid 1px !important;
+}
+.dj_ie .nihilo .dijitCalendarDateTemplate {
+	padding: 0.1em .33em 0.02em .33em;
+}
+.nihilo .dijitCalendarPreviousMonth,
+.nihilo .dijitCalendarNextMonth 		{
+	
+	color:#999999;
+	background-color:#f5f5f5 !important;
+	border:#f5f5f5 solid 1px !important;
+}
+.nihilo .dijitCalendarPreviousMonthDisabled,
+.nihilo .dijitCalendarNextMonthDisabled	{
+	
+	background-color:#a4a5a6 !important;
+}
+.nihilo .dijitCalendarCurrentMonth {
+	
+}
+.nihilo .dijitCalendarCurrentMonthDisabled {
+		
+	background-color:#bbbbbc !important;
+}
+.nihilo .dijitCalendarDisabledDate {
+	
+	
+	text-decoration:line-through !important;
+	cursor:default !important;
+}
+.nihilo .dijitCalendarCurrentDate {
+	
+	text-decoration:underline;
+	font-weight:bold;
+}
+.nihilo .dijitCalendarSelectedDate {
+	
+	background-color:#ffe284 !important;
+	color:black !important;
+	border:#f7c95c solid 1px !important;
+}
+.nihilo .dijitCalendarYearContainer {
+	
+	background:white url(images/titleBar.png) repeat-x top;
+}
+.nihilo .dijitCalendarYearLabel {
+	
+	margin:0;
+	padding:0.4em 0 0.25em 0;
+	text-align:center;
+}
+.nihilo .dijitCalendarSelectedYear {
+	
+	color:black;
+	padding:0.2em;
+	padding-bottom:0.1em;
+	background-color:#ffe284 !important;
+	border:#f7c95c solid 1px !important;
+}
+.nihilo .dijitCalendarNextYear,
+.nihilo .dijitCalendarPreviousYear {
+	
+	color:black !important;
+	font-weight:normal;
+}
+.nihilo .dijitTimePickerTick,
+.nihilo .dijitTimePickerMarker {
+	border-color: #eeeeee;
+}
+.nihilo .dijitTimePickerTick {
+	color:white;
+}
+.nihilo .dijitTimePickerMarker {
+	background:#d3d3d3 url(images/titleBar.png) repeat-x top;
+	color:#293a4b;
+	font-weight: bold;
+}
+.nihilo .dijitTimePickerItemSelected {
+	color: black;
+	background: #ffe284 none;
+}
+.nihilo .dijitTimePickerItemHover {
+	background: #d6d6dd none;
+	color:black;
+}
+.nihilo .dijitTimePickerItemHover,
+.nihilo .dijitTimePickerItemSelected {
+	position: relative;
+	z-index: 10;
+}
+.nihilo .dijitTimePickerTick .dijitTimePickerItemInner {
+	font-size:0.4em;
+}
+.nihilo .dijitTimePickerItemHover .dijitTimePickerItemInner,
+.nihilo .dijitTimePickerItemSelected .dijitTimePickerItemInner {
+	font-size:1em;
+}
+.nihilo .dijitTimePickerMarkerHover {
+	border-top: 1px solid #eeeeee;
+}
+.nihilo .dijitTimePickerTickHover,
+.nihilo .dijitTimePickerTickSelected {
+	margin-top:-0.3em;
+	margin-bottom:-0.3em;
+	border-bottom: none;
+}
+.dijit_a11y .dijitTimePickerTickHover {
+	background-color: #CCC !important;
+	border-top: 1px solid #333 !important;
+	border-bottom: 1px solid #333 !important;
+}
+.dijit_a11y .dijitTimePickerMarkerHover {
+	border-bottom-width: 2px;
+}
+.nihilo .dijitToolbar {
+	border-bottom: 1px solid #ccc;
+	background:#eaeaea url(images/titleBar.png) repeat-x top left;
+}
+.dj_ie6 .nihilo .dijitToolbar {
+	height: 10px;
+}
+.nihilo .dijitToolbar .dijitButtonNode,
+.nihilo .dijitToolbar .dijitComboButton .dijitButtonContents,
+.nihilo .dijitToolbar .dijitComboButton .dijitDownArrowButton {
+	background: none;
+	margin: 0px;
+	padding: 0px;
+	border: none;
+	font-size: 12px;
+}
+.nihilo .dijitToolbar .dijitButton,
+.nihilo .dijitToolbar .dijitToggleButton,
+.nihilo .dijitToolbar .dijitDropDownButton,
+.nihilo .dijitToolbar .dijitComboButton .dijitButtonContents,
+.nihilo .dijitToolbar .dijitComboButton .dijitDownArrowButton {
+	background: none;	
+	padding: 1px;	
+}
+.nihilo .dijitToolbar .dijitButtonChecked,
+.nihilo .dijitToolbar .dijitToggleButtonChecked {
+	background-color:#ffeeb9;
+	border:1px solid #f7c95c;
+	padding: 0;
+}
+.nihilo .dijitToolbar .dijitButtonCheckedHover,
+.nihilo .dijitToolbar .dijitToggleButtonCheckedHover
+ {
+	background-color:#ffe284;
+	border:1px solid #f7c95c;
+	padding: 0;
+}
+.nihilo .dijitToolbar .dijitButtonHover,
+.nihilo .dijitToolbar .dijitToggleButtonHover,
+.nihilo .dijitToolbar .dijitDropDownButtonHover,
+.nihilo .dijitToolbar .dijitComboButtonHover .dijitButtonContents,
+.nihilo .dijitToolbar .dijitComboButtonDownArrowHover .dijitDownArrowButton {
+	
+	border: 1px solid #f7c95c;
+	padding: 0;
+	background-color:#ffe284;
+}
+.nihilo .dijitToolbar label {	
+	padding: 3px 3px 0 6px;
+}
+.dj_ie .nihilo .dijitToolbar .dijitComboButton .dijitButtonContentsFocused,
+.dj_ie .nihilo .dijitToolbar .dijitComboButton .dijitDownArrowButtonFocused,
+.dj_ff2 .nihilo.dijitToolbar .dijitComboButton .dijitButtonContentsFocused,
+.dj_ff2 .nihilo .dijitToolbar .dijitComboButton .dijitDownArrowButtonFocused {
+	
+	border: 1px #555 dotted !important;
+	padding: 0px;
+}
+.nihilo .dijitDialog {
+	background: #eee;
+	border: 1px solid #d3d3d3;
+	-webkit-box-shadow: 0px 5px 10px #adadad;
+	padding: 0px;
+}
+.nihilo .dijitDialog .dijitDialogTitle {
+	
+	font-size: 0.9em;
+	color: #3243C5F;
+	font-weight: bold;
+	padding: 0px 4px;
+}
+.nihilo .dijitDialog .dijitDialogPaneContent {
+	background: #ffffff;
+	border:none;
+	border-top: 1px solid #d3d3d3; 
+	padding:10px;
+}
+.nihilo .dijitDialogTitleBar {
+	
+	background: #fafafa url(images/titleBar.png) repeat-x top left;
+	padding: 5px 6px 3px 6px;
+	cursor: move;
+	outline:0; 
+}
+.nihilo .dijitDialogCloseIcon {
+	
+	background-image: url(images/spriteRoundedIconsSmall.png);
+	background-repeat: no-repeat;
+	background-position: -60px 0px;
+	position: absolute;
+	vertical-align: middle;
+	right: 6px;
+	top: 4px;
+	height: 15px;
+	width: 15px;
+	cursor: pointer;
+}
+.dj_ie6 .nihilo .dijitDialogCloseIcon {
+	background-image: url(images/spriteRoundedIconsSmall.gif);
+}
+.nihilo .dijitDialogCloseIcon-hover {
+	background-position: -60px -15px;
+}
+.nihilo .dijitTooltip,
+.nihilo .dijitTooltipDialog {
+	
+	background: transparent;	
+}
+.dijitTooltipBelow {
+	
+	padding-top: 10px;
+}
+.dijitTooltipAbove {
+	
+	padding-bottom: 10px;
+}
+.nihilo .dijitTooltipContainer {
+	
+	background-color: #fff;
+	border:1px solid #d3d3d3;
+	padding:0.45em;
+}
+.nihilo .dijitTooltipConnector {
+	
+	border:0px;
+	z-index: 2;
+}
+.nihilo .dijitTooltipABRight .dijitTooltipConnector {
+	
+	left: auto !important;
+	right: 6px;
+}
+.nihilo .dijitTooltipBelow .dijitTooltipConnector {
+	
+	top: 0px;
+	left: 6px;
+	background:url(images/tooltipConnectorUp.png) no-repeat top left;
+	width:17px;
+	height:11px;
+}
+.dj_ie6 .nihilo .dijitTooltipBelow .dijitTooltipConnector {
+	background-image: url(images/tooltipConnectorUp.gif);
+}
+.nihilo .dijitTooltipAbove .dijitTooltipConnector {
+	
+	bottom: 0px;
+	left: 6px;
+	background:url(images/tooltipConnectorDown.png) no-repeat top left;
+	width:17px;
+	height:11px;
+}
+.dj_ie6 .nihilo .dijitTooltipAbove .dijitTooltipConnector {
+	background-image: url(images/tooltipConnectorDown.gif);
+}
+.dj_ie6 .nihilo .dijitTooltipAbove .dijitTooltipConnector {
+	bottom: -5px;
+}
+.nihilo .dijitTooltipLeft {
+	padding-right: 10px;
+}
+.dj_ie6 .nihilo .dijitTooltipLeft {
+	padding-left: 11px;
+}
+.nihilo .dijitTooltipLeft .dijitTooltipConnector {
+	
+	right: 0px;
+	bottom: 3px;
+	background:url(images/tooltipConnectorRight.png) no-repeat top left;
+	width:11px;
+	height:17px;
+}
+.dj_ie6 .nihilo .dijitTooltipLeft .dijitTooltipConnector {
+	background-image: url(images/tooltipConnectorRight.gif);
+}
+.nihilo .dijitTooltipRight {
+	padding-left: 10px;
+}
+.nihilo .dijitTooltipRight .dijitTooltipConnector {
+	
+	left: 0px;
+	bottom: 3px;
+	background:url(images/tooltipConnectorLeft.png) no-repeat top left;
+	width:11px;
+	height:17px;
+}
+.dj_ie6 .nihilo .dijitTooltipRight .dijitTooltipConnector {
+	background-image: url(images/tooltipConnectorLeft.gif);
+}
+.nihilo .dijitMenu,
+.nihilo .dijitMenuBar {
+	border: 1px solid #d3d3d3;
+	margin: 0px;
+	padding: 0px;
+	background-color: #fff;
+}
+.nihilo .dijitBorderContainer .dijitMenuBar {
+	border: 1px #ccc solid;
+}
+.nihilo .dijitMenuItem {
+	font-family: sans-serif;
+	margin: 0px;
+	color: #243C5F;
+}
+.nihilo .dijitMenuBar .dijitMenuItem {
+	padding: 4px 5px;
+}
+.nihilo .dijitMenuPreviousButton, .nihilo .dijitMenuNextButton {
+	font-style: italic;
+}
+.nihilo .dijitMenuItem TD {
+	padding:1px;
+}
+.nihilo .dijitMenuPassive .dijitMenuItemHover,
+.nihilo .dijitMenuItemSelected {
+	background-color: #ffe284; 
+	color: #243C5F;
+}
+.nihilo .dijitMenuItemIcon {
+	width: 15px;
+	height: 15px;
+}
+.nihilo .dijitMenuExpand {
+	width:15px;
+	height:15px;
+	background-image: url(images/spriteRoundedIconsSmall.png);
+	background-position: -30px top;
+}
+.dj_ie6 .nihilo .dijitMenuExpand {
+	background-image:url(images/spriteRoundedIconsSmall.gif);
+}
+.nihilo .dijitMenuSeparator {
+	height: 1px;
+}
+.nihilo .dijitMenuSeparatorTop {
+	border-bottom: 1px solid #fff; 
+}
+.nihilo .dijitMenuSeparatorBottom {
+	border-top: 1px solid #d3d3d3;
+}
+.nihilo .dijitCheckedMenuItemIconChar {
+	display: none;
+}
+.nihilo .dijitCheckedMenuItemIcon {
+	background-image: url(images/spriteCheckbox.gif);
+	background-position: -80px;
+}
+.nihilo .dijitCheckedMenuItemChecked .dijitCheckedMenuItemIcon {
+	background-position: -64px;
+}
+.dijitIEFixedToolbar {
+	position:absolute;
+	
+	top: expression(eval((document.documentElement||document.body).scrollTop));
+}
+.nihilo .dijitToolbar .dijitToolbarSeparator {
+	background: url(images/editor.gif);
+}
+.nihilo .dijitEditorIcon {
+	background-image: url(images/editor.gif); 
+	background-repeat: no-repeat;
+	width: 18px;
+	height: 18px;
+	text-align: center;
+}
+.nihilo .dijitDisabled .dijitEditorIcon {
+	background-image: url(images/editorDisabled.gif); 
+}
+.nihilo .dijitEditorIconSep { background-position: 0px; }
+.nihilo .dijitEditorIconBackColor { background-position: -18px; }
+.nihilo .dijitEditorIconBold { background-position: -36px; }
+.nihilo .dijitEditorIconCancel { background-position: -54px; }
+.nihilo .dijitEditorIconCopy { background-position: -72px; }
+.nihilo .dijitEditorIconCreateLink { background-position: -90px; }
+.nihilo .dijitEditorIconCut { background-position: -108px; }
+.nihilo .dijitEditorIconDelete { background-position: -126px; }
+.nihilo .dijitEditorIconForeColor { background-position: -144px; }
+.nihilo .dijitEditorIconHiliteColor { background-position: -162px; }
+.nihilo .dijitEditorIconIndent { background-position: -180px; }
+.nihilo .dijitEditorIconInsertHorizontalRule { background-position: -198px; }
+.nihilo .dijitEditorIconInsertImage { background-position: -216px; }
+.nihilo .dijitEditorIconInsertOrderedList { background-position: -234px; }
+.nihilo .dijitEditorIconInsertTable { background-position: -252px; }
+.nihilo .dijitEditorIconInsertUnorderedList { background-position: -270px; }
+.nihilo .dijitEditorIconItalic { background-position: -288px; }
+.nihilo .dijitEditorIconJustifyCenter { background-position: -306px; }
+.nihilo .dijitEditorIconJustifyFull { background-position: -324px; }
+.nihilo .dijitEditorIconJustifyLeft { background-position: -342px; }
+.nihilo .dijitEditorIconJustifyRight { background-position: -360px; }
+.nihilo .dijitEditorIconLeftToRight { background-position: -378px; }
+.nihilo .dijitEditorIconListBulletIndent { background-position: -396px; }
+.nihilo .dijitEditorIconListBulletOutdent { background-position: -414px; }
+.nihilo .dijitEditorIconListNumIndent { background-position: -432px; }
+.nihilo .dijitEditorIconListNumOutdent { background-position: -450px; }
+.nihilo .dijitEditorIconOutdent { background-position: -468px; }
+.nihilo .dijitEditorIconPaste { background-position: -486px; }
+.nihilo .dijitEditorIconRedo { background-position: -504px; }
+.nihilo .dijitEditorIconRemoveFormat { background-position: -522px; }
+.nihilo .dijitEditorIconRightToLeft { background-position: -540px; }
+.nihilo .dijitEditorIconSave { background-position: -558px; }
+.nihilo .dijitEditorIconSpace { background-position: -576px; }
+.nihilo .dijitEditorIconStrikethrough { background-position: -594px; }
+.nihilo .dijitEditorIconSubscript { background-position: -612px; }
+.nihilo .dijitEditorIconSuperscript { background-position: -630px; }
+.nihilo .dijitEditorIconUnderline { background-position: -648px; }
+.nihilo .dijitEditorIconUndo { background-position: -666px; }
+.nihilo .dijitEditorIconWikiword { background-position: -684px; }
+.nihilo .dijitEditorIconToggleDir { background-position: -540px; }
+.nihilo .dijitEditorIconTabIndent { background-position: -702px; }
+.nihilo .dijitEditorIconSelectAll { background-position: -720px; }
+.nihilo .dijitEditorIconUnlink { background-position: -738px; }
+.dijitColorPalette {
+	border:1px solid #d3d3d3;
+	background:#fff;
+	-moz-border-radius: 0px !important;
+}
diff --git a/dijit/themes/nihilo/nihilo_rtl.css b/dijit/themes/nihilo/nihilo_rtl.css
new file mode 100644
index 0000000..bb7a5eb
--- /dev/null
+++ b/dijit/themes/nihilo/nihilo_rtl.css
@@ -0,0 +1,212 @@
+
+.dj_gecko-rtl .dijitInputField {
+	direction: ltr; 
+}
+.dj_gecko-rtl .dijitInputField * {
+	direction: rtl; 
+}
+.dijitRtl .dijitMenuItem {
+	text-align: right;
+}
+.dijitRtl .dijitComboBox .dijitInputField {
+	border-right-width:1px !important;
+	border-left-width:0 !important;
+}
+.dijitRtl .dijitCalendarNextYear {
+	margin:0 0.55em 0 0;
+}
+.dijitRtl .dijitCalendarPreviousYear {
+	margin:0 0 0 0.55em;
+}
+.dijitRtl .dijitProgressBarFull .dijitProgressBarLabel {
+	right:0; 
+}
+.dijitRtl .dijitSliderImageHandleV {
+	left:auto;
+	right:-6px;
+}
+.dj_ie-rtl .dijitSliderImageHandleV {
+	right:-10px;
+}
+.dijitRtl .dijitSliderMoveableH {
+	right:auto;
+	left:0;
+}
+.dijitRtl .dijitRuleContainerV {
+	float:right;
+}
+.dj_gecko-rtl .dijitRuleContainerV {
+	float:left;
+}
+.dj_ie-rtl .dijitRuleContainerV {
+	text-align:right;
+}
+.dj_ie-rtl .dijitRuleLabelV {
+	text-align:left;
+}
+.dj_ie-rtl .dijitRuleLabelH {
+	zoom:1;
+}
+.dj_ie-rtl .dijitSliderProgressBarH {
+	right:0;
+	left:auto;
+}
+.dj_gecko-rtl .dijitSliderProgressBarH {
+	float:right;
+	right:0;
+	left:auto;
+}
+.dijitRtl .dijitSpinner .dijitInputLayoutContainer .dijitArrowButton {
+	right: auto;
+	left: 0;
+	border-width: 0 1px 0 0 !important;
+}
+.dijitRtl .dijitSpinnerButtonContainer {
+	float: left;
+}
+.dijitRtl .dijit_a11y .dijitSpinnerButtonContainer {
+	margin-left: none;
+	margin-right: 2px;
+}
+.dijitRtl DIV.dijitArrowButton, .dijitRtl .dijitValidationIcon, .dijitRtl .dijitValidationIconText {
+	float: left;
+}
+.dijitRtl .dijitContentPaneLoading, .dijitRtl .dijitContentPaneError {
+	background-position:right;
+	padding-right:25px;
+}
+.dijitRtl .nihilo .dijitTab {
+	margin-right:0;
+	margin-left:2px;		
+}
+.dijitRtl .nihilo .dijitTabContainerTopStrip,
+.dijitRtl .nihilo .dijitTabContainerBottomStrip {
+	padding-right: 3px;
+	padding-left: 0px;
+}
+.dijitRtl .nihilo .dijitTabContainerTop-tabs {
+	padding-left: auto;
+	padding-right: 3px;
+}
+.dijitRtl .nihilo .dijitTabContainerBottom-tabs {
+	padding-left: auto;
+	padding-right: 3px;
+}
+.dijitRtl .nihilo .dijitTabInnerDiv {
+	padding-left: 3px;
+	padding-right: 4px;
+}
+.dijitRtl .nihilo .dijitTabPaneWrapper {
+	#zoom: 1;
+}
+.dj_ie-rtl .nihilo .dijitTabContainerLeft-tabs {
+	margin-left: 0px !important;
+}
+.dj_ie-rtl .nihilo .dijitTabContainerRight-tabs {
+	margin-right: 0px !important;
+}
+.dijitRtl .nihilo .dijitTabContainerLeft-tabs .dijitTab,
+.dijitRtl .nihilo .dijitTabContainerRight-tabs .dijitTab {
+	margin-left:0px;
+}
+.dj_ie-rtl .nihilo .dijitTab .dijitTabInnerDiv{
+	width : 1%;
+}
+.dijitRtl .nihilo .dijitAccordionArrow {
+	background-position: 0px top;
+}
+.dijitRtl .nihilo .dijitAccordionTitle-selected .dijitAccordionArrow {
+	
+	background-position: -15px top;
+}
+.dijitRtl .nihilo .dijitSliderProgressBarH,
+.dijitRtl .nihilo .dijitSliderRemainingBarH,
+.dijitRtl .nihilo .dijitSliderLeftBumper,
+.dijitRtl .nihilo .dijitSliderRightBumper,
+.dijitRtl .nihilo .dijitSliderTopBumper {
+	background-position: top right;
+}
+.dijitRtl .nihilo .dijitSliderProgressBarV,
+.dijitRtl .nihilo .dijitSliderRemainingBarV,
+.dijitRtl .nihilo .dijitSliderBottomBumper {
+	background-position: bottom right;
+}
+.dijitRtl .nihilo .dijitSliderLeftBumper {
+	border-left-width: 0px;
+	border-right-width: 1px;
+}
+.dijitRtl .nihilo .dijitSliderRightBumper {
+	border-left-width: 1px;
+	border-right-width: 0px;
+}
+.dijitRtl .nihilo .dijitSliderIncrementIconH {
+	background:url(images/spriteRoundedIconsSmall.png) no-repeat left top;
+	#background:url(images/spriteRoundedIconsSmall.gif) no-repeat left top;
+}
+.dijitRtl .nihilo .dijitSliderDecrementIconH {
+	background:url(images/spriteRoundedIconsSmall.png) no-repeat -30px top;
+	#background:url(images/spriteRoundedIconsSmall.gif) no-repeat -30px top;
+}
+.dijitRtl .nihilo .dijitComboBox .dijitButtonNode {
+	border-width: 0px 0px 0px 1px;
+}
+.dijitRtl .nihilo .dijitComboBox .dijitButtonNode,
+.dijitRtl .nihilo .dijitSpinner .dijitButtonNode {
+	
+	border-color: #8ba0bd;
+	border-left: 0px solid #8ba0bd;
+	border-right: 1px solid #8ba0bd;
+}
+.dijitRtl .nihilo .dijitTreeContainer .dijitTreeNode {
+    background-image : none;
+}
+.dijitRtl .nihilo .dijitTreeContainer .dijitTreeIsRoot {
+}
+.dijitRtl .nihilo .dijitTreeContainer .dijitTreeIsLast {
+    background-image: url(images/treeI_half_rtl.gif);
+}
+.dijitRtl .nihilo .dijitTreeContainer .dijitTreeContent {
+    padding-left: auto;
+    padding-right: 1px;   
+}
+.dijitRtl .nihilo .dijitTreeContainer .dijitTreeExpandoOpened {
+	background: url(images/spriteTree_rtl.gif) no-repeat -18px top;
+}
+.dijitRtl .nihilo .dijitTreeContainer .dijitTreeExpandoClosed {
+	background-image: url(images/spriteTree_rtl.gif);
+}
+.dijitRtl .nihilo .dijitTreeContainer .dijitTreeExpandoLeaf {
+	background: none;
+}
+.dijitRtl .nihilo .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background-position: 0px top;
+}
+.dj_ie6-rtl .nihilo .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background-position: 0px top;
+}
+.dijitRtl .nihilo .dijitCalendarDecrease {
+	background-position: -30px top;
+}
+.dijitRtl .nihilo .dijitCalendarIncrease {
+	background-position: 0px top;
+}
+.dijitRtl .nihilo .dijitDialogTitleBar .dijitDialogCloseIcon {
+	right: auto;
+	left: 5px;
+}
+.dijitRtl .nihilo .dijitMenuItem .dijitMenuItemIcon {
+	padding-left: 3px;
+	padding-right: 0px;
+}
+.dijitRtl .nihilo .dijitMenuItem .dijitMenuExpand {
+	background-position: 0px top;
+}
+.dijitRtl .nihilo .dijitEditorIcon {
+	background-image: url(images/editor_rtl.gif); 
+}
+.dijitRtl .nihilo .dijitDisabled .dijitEditorIcon {
+	background-image: url(images/editorDisabled_rtl.gif); 
+}
+.dijitRtl .nihilo .dijitToolbar .dijitToolbarSeparator {
+	background-image: url(images/editor_rtl.gif);
+}
diff --git a/dijit/themes/soria/Calendar.css b/dijit/themes/soria/Calendar.css
new file mode 100644
index 0000000..f2d179f
--- /dev/null
+++ b/dijit/themes/soria/Calendar.css
@@ -0,0 +1,130 @@
+
+	
+.soria .dijitCalendarIncrementControl {
+	
+	width:15px;
+	height:15px;
+	background-image: url("images/spriteRoundedIconsSmall.png");
+	background-repeat: no-repeat;
+}
+.dj_ie6 .soria .dijitCalendarIncrementControl {
+	font-size:.1em;	
+	background-image: url("images/spriteRoundedIconsSmall.gif");
+}
+.soria .dijitA11ySideArrow {
+	display: none;
+}
+.soria .dijitCalendarDecrease {
+	background-position: top left;
+}
+.soria .dijitCalendarIncrease {
+	background-position: -30px top;
+}
+.soria table.dijitCalendarContainer {
+	font-size: 100%;
+	border-spacing: 0;
+	border-collapse: separate;
+	border: 1px solid #b1badf;
+	margin: 0;
+}
+.soria .dijitCalendarMonthContainer th {
+	
+	background:#bed7f0 url("images/titleBar.png") repeat-x top;
+	padding-top:.3em;
+	padding-bottom:.2em;
+	text-align:center;
+}
+.dj_ie6 .soria .dijitCalendarMonthContainer th {
+	padding-top:.2em;
+	padding-bottom:.1em;
+}
+.soria .dijitCalendarDayLabelTemplate {
+	
+	background:#bed7f0;
+	font-weight:normal;
+	padding-top:.15em;
+	padding-bottom:.2em;
+	border-bottom: 1px solid #b1badf;
+	color:#293a4b;
+	text-align:center;
+}
+.soria .dijitCalendarBodyContainer {
+	border-bottom: 1px solid #eeeeee;	
+}
+.soria .dijitCalendarMonthLabel {
+	color:#293a4b;
+	font-weight: bold;
+}
+.soria .dijitCalendarDateTemplate {
+	
+	font-size: 0.9em;
+	font-weight: bold;
+	text-align: center;
+	padding: 0.3em 0.3em 0.05em 0.3em;
+	letter-spacing: 1px;
+	background-color: #fff;
+	border:#fff solid 1px !important;
+}
+.dj_ie .soria .dijitCalendarDateTemplate {
+	padding: 0.1em .33em 0.02em .33em;
+}
+.soria .dijitCalendarPreviousMonth,
+.soria .dijitCalendarNextMonth 		{
+	
+	color:#999999;
+	background-color:#fdfdfd !important;
+	border:#fdfdfd solid 1px !important;
+}
+.soria .dijitCalendarPreviousMonthDisabled,
+.soria .dijitCalendarNextMonthDisabled	{
+	
+	background-color:#a4a5a6 !important;
+}
+.soria .dijitCalendarCurrentMonth {
+	
+}
+.soria .dijitCalendarCurrentMonthDisabled {
+		
+	background-color:#bbbbbc !important;
+}
+.soria .dijitCalendarDisabledDate {
+	
+	
+	text-decoration:line-through !important;
+	cursor:default !important;
+}
+.soria .dijitCalendarCurrentDate {
+	
+	text-decoration:underline;
+	font-weight:bold;
+}
+.soria .dijitCalendarSelectedDate {
+	
+	background-color:#b9cbf1 !important;
+	color:black !important;
+	border:#4b5aaa solid 1px !important;
+}
+.soria .dijitCalendarYearContainer {
+	
+	background:white url("images/titleBar.png") repeat-x top;
+}
+.soria .dijitCalendarYearLabel {
+	
+	margin:0;
+	padding:0.4em 0 0.25em 0;
+	text-align:center;
+}
+.soria .dijitCalendarSelectedYear {
+	
+	color:black;
+	padding:0.2em;
+	padding-bottom:0.1em;
+	background-color:#b9cbf1 !important;
+	border:#4b5aaa solid 1px !important;
+}
+.soria .dijitCalendarNextYear,
+.soria .dijitCalendarPreviousYear {
+	
+	color:black !important;
+	font-weight:normal;
+}
diff --git a/dijit/themes/soria/Calendar_rtl.css b/dijit/themes/soria/Calendar_rtl.css
new file mode 100644
index 0000000..bcfa495
--- /dev/null
+++ b/dijit/themes/soria/Calendar_rtl.css
@@ -0,0 +1,7 @@
+
+.dijitRtl .soria .dijitCalendarDecrease {
+	background-position: -30px top;
+}
+.dijitRtl .soria .dijitCalendarIncrease {
+	background-position: 0px top;
+}
diff --git a/dijit/themes/soria/ColorPalette.css b/dijit/themes/soria/ColorPalette.css
new file mode 100644
index 0000000..5a51275
--- /dev/null
+++ b/dijit/themes/soria/ColorPalette.css
@@ -0,0 +1,5 @@
+.dijitColorPalette {
+	border:1px solid #cbcbcb;
+	background:#fff;
+	-moz-border-radius: 0px !important;
+}
diff --git a/dijit/themes/soria/Common.css b/dijit/themes/soria/Common.css
new file mode 100644
index 0000000..362a867
--- /dev/null
+++ b/dijit/themes/soria/Common.css
@@ -0,0 +1,19 @@
+
+.soria .dojoDndItemBefore {
+	border-top: 2px solid #369;
+}
+.soria .dojoDndItemAfter {
+	border-bottom: 2px solid #369;
+}
+.soria .dojoDndItemOver {
+	cursor:pointer;
+}
+.soria table.dojoDndAvatar { -moz-border-radius: 0; border: 1px solid #ccc; border-collapse: collapse; background-color: #fff; font-size: 75%; color: black;}
+.soria .dojoDndAvatar td	{ border: none; }
+.soria .dojoDndAvatar tr	{ border: none; }
+.soria .dojoDndAvatarHeader td	{ height: 20px; padding: 0 0 0 21px; }
+.soria .dojoDndAvatarItem td { padding: 2px;}
+.soria.dojoDndMove .dojoDndAvatarHeader	{background-color: #f58383; background-image: url(images/dndNoMove.png); background-repeat: no-repeat; background-position: 2px center;}
+.soria.dojoDndCopy .dojoDndAvatarHeader	{background-color: #f58383; background-image: url(images/dndNoCopy.png); background-repeat: no-repeat; background-position: 2px center;}
+.soria.dojoDndMove .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{background-color: #97e68d; background-image: url(images/dndMove.png); background-repeat: no-repeat; background-position: 2px center;}
+.soria.dojoDndCopy .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{background-color: #97e68d; background-image: url(images/dndCopy.png); background-repeat: no-repeat; background-position: 2px center;}
diff --git a/dijit/themes/soria/Dialog.css b/dijit/themes/soria/Dialog.css
new file mode 100644
index 0000000..854d51d
--- /dev/null
+++ b/dijit/themes/soria/Dialog.css
@@ -0,0 +1,132 @@
+
+.soria .dijitDialog {
+	background: #eee;
+	border: 1px solid #cbcbcb;
+	-webkit-box-shadow: 0px 5px 10px #adadad;
+	padding: 0px;
+}
+.soria .dijitDialog .dijitDialogTitle {
+	
+	font-weight: bold;
+	padding: 0px 4px;
+	font-size: 0.9em;
+	color: #3243C5F;
+}
+.soria .dijitDialog .dijitDialogPaneContent {
+	background: #ffffff;
+	border:none;
+	border-top: 1px solid #b1badf; 
+	padding:10px;
+}
+.soria .dijitDialogTitleBar {
+	
+	background: #fafafa url("images/titleBar.png") repeat-x top left;
+	padding: 5px 6px 3px 6px;
+	cursor: move;
+	outline:0; 
+}
+.soria .dijitDialogCloseIcon {
+	
+	background-image: url("images/spriteRoundedIconsSmallBl.png");
+	background-repeat: no-repeat;
+	background-position: -60px 0px;
+	position: absolute;
+	vertical-align: middle;
+	right: 6px;
+	top: 4px;
+	height: 15px;
+	width: 15px;
+	cursor: pointer;
+}
+.dj_ie6 .soria .dijitDialogCloseIcon {
+	background-image: url("images/spriteRoundedIconsSmallBl.gif");
+}
+.soria .dijitDialogCloseIcon-hover {
+	background-position: -60px -15px;
+}
+.soria .dijitTooltip,
+.soria .dijitTooltipDialog {
+	
+	background: transparent;	
+}
+.dijitTooltipBelow {
+	
+	padding-top: 10px;
+}
+.dijitTooltipAbove {
+	
+	padding-bottom: 10px;
+}
+.soria .dijitTooltipContainer {
+	
+	background-color: #fff;
+	border:1px solid #cbcbcb;
+	padding:0.45em;
+}
+.soria .dijitTooltipConnector {
+	
+	border:0px;
+	z-index: 2;
+}
+.soria .dijitTooltipABRight .dijitTooltipConnector {
+	
+	left: auto !important;
+	right: 6px;
+}
+.soria .dijitTooltipBelow .dijitTooltipConnector {
+	
+	top: 0px;
+	left: 6px;
+	background:url("images/tooltipConnectorUp.png") no-repeat top left;
+	width:17px;
+	height:11px;
+}
+.dj_ie6 .soria .dijitTooltipBelow .dijitTooltipConnector {
+	background-image: url("images/tooltipConnectorUp.gif");
+}
+.soria .dijitTooltipAbove .dijitTooltipConnector {
+	
+	bottom: 0px;
+	left: 6px;
+	background:url("images/tooltipConnectorDown.png") no-repeat top left;
+	width:17px;
+	height:11px;
+}
+.dj_ie6 .soria .dijitTooltipAbove .dijitTooltipConnector {
+	background-image: url("images/tooltipConnectorDown.gif");
+}
+.dj_ie6 .soria .dijitTooltipAbove .dijitTooltipConnector {
+	background-image: url("images/tooltipConnectorDown.gif");
+	bottom: -5px;
+}
+.soria .dijitTooltipLeft {
+	padding-right: 10px;
+}
+.dj_ie6 .soria .dijitTooltipLeft {
+	padding-left: 11px;
+}
+.soria .dijitTooltipLeft .dijitTooltipConnector {
+	
+	right: 0px;
+	bottom: 3px;
+	background:url("images/tooltipConnectorRight.png") no-repeat top left;
+	width:11px;
+	height:17px;
+}
+.dj_ie6 .soria .dijitTooltipLeft .dijitTooltipConnector {
+	background-image: url("images/tooltipConnectorRight.gif");
+}
+.soria .dijitTooltipRight {
+	padding-left: 10px;
+}
+.soria .dijitTooltipRight .dijitTooltipConnector {
+	
+	left: 0px;
+	bottom: 3px;
+	background:url("images/tooltipConnectorLeft.png") no-repeat top left;
+	width:11px;
+	height:17px;
+}
+.dj_ie6 .soria .dijitTooltipRight .dijitTooltipConnector {
+	background-image: url("images/tooltipConnectorLeft.gif");
+}
diff --git a/dijit/themes/soria/Dialog_rtl.css b/dijit/themes/soria/Dialog_rtl.css
new file mode 100644
index 0000000..41db9ce
--- /dev/null
+++ b/dijit/themes/soria/Dialog_rtl.css
@@ -0,0 +1,5 @@
+
+.dijitRtl .soria .dijitDialogTitleBar .dijitDialogCloseIcon {
+	right: auto;
+	left: 5px;
+}
diff --git a/dijit/themes/soria/Editor.css b/dijit/themes/soria/Editor.css
new file mode 100644
index 0000000..54374df
--- /dev/null
+++ b/dijit/themes/soria/Editor.css
@@ -0,0 +1,61 @@
+.dijitIEFixedToolbar {
+	position:absolute;
+	
+	top: expression(eval((document.documentElement||document.body).scrollTop));
+}
+.soria .dijitToolbar .dijitToolbarSeparator {
+	background: url('images/editor.gif');
+}
+.soria .dijitEditorIcon {
+	background-image: url('images/editor.gif'); 
+	background-repeat: no-repeat;
+	width: 18px;
+	height: 18px;
+	text-align: center;
+}
+.soria .dijitDisabled .dijitEditorIcon {
+	background-image: url('images/editorDisabled.gif'); 
+}
+.soria .dijitEditorIconSep { background-position: 0px; }
+.soria .dijitEditorIconBackColor { background-position: -18px; }
+.soria .dijitEditorIconBold { background-position: -36px; }
+.soria .dijitEditorIconCancel { background-position: -54px; }
+.soria .dijitEditorIconCopy { background-position: -72px; }
+.soria .dijitEditorIconCreateLink { background-position: -90px; }
+.soria .dijitEditorIconCut { background-position: -108px; }
+.soria .dijitEditorIconDelete { background-position: -126px; }
+.soria .dijitEditorIconForeColor { background-position: -144px; }
+.soria .dijitEditorIconHiliteColor { background-position: -162px; }
+.soria .dijitEditorIconIndent { background-position: -180px; }
+.soria .dijitEditorIconInsertHorizontalRule { background-position: -198px; }
+.soria .dijitEditorIconInsertImage { background-position: -216px; }
+.soria .dijitEditorIconInsertOrderedList { background-position: -234px; }
+.soria .dijitEditorIconInsertTable { background-position: -252px; }
+.soria .dijitEditorIconInsertUnorderedList { background-position: -270px; }
+.soria .dijitEditorIconItalic { background-position: -288px; }
+.soria .dijitEditorIconJustifyCenter { background-position: -306px; }
+.soria .dijitEditorIconJustifyFull { background-position: -324px; }
+.soria .dijitEditorIconJustifyLeft { background-position: -342px; }
+.soria .dijitEditorIconJustifyRight { background-position: -360px; }
+.soria .dijitEditorIconLeftToRight { background-position: -378px; }
+.soria .dijitEditorIconListBulletIndent { background-position: -396px; }
+.soria .dijitEditorIconListBulletOutdent { background-position: -414px; }
+.soria .dijitEditorIconListNumIndent { background-position: -432px; }
+.soria .dijitEditorIconListNumOutdent { background-position: -450px; }
+.soria .dijitEditorIconOutdent { background-position: -468px; }
+.soria .dijitEditorIconPaste { background-position: -486px; }
+.soria .dijitEditorIconRedo { background-position: -504px; }
+.soria .dijitEditorIconRemoveFormat { background-position: -522px; }
+.soria .dijitEditorIconRightToLeft { background-position: -540px; }
+.soria .dijitEditorIconSave { background-position: -558px; }
+.soria .dijitEditorIconSpace { background-position: -576px; }
+.soria .dijitEditorIconStrikethrough { background-position: -594px; }
+.soria .dijitEditorIconSubscript { background-position: -612px; }
+.soria .dijitEditorIconSuperscript { background-position: -630px; }
+.soria .dijitEditorIconUnderline { background-position: -648px; }
+.soria .dijitEditorIconUndo { background-position: -666px; }
+.soria .dijitEditorIconWikiword { background-position: -684px; }
+.soria .dijitEditorIconToggleDir { background-position: -540px; }
+.soria .dijitEditorIconTabIndent { background-position: -702px; }
+.soria .dijitEditorIconSelectAll { background-position: -720px; }
+.soria .dijitEditorIconUnlink { background-position: -738px; }
diff --git a/dijit/themes/soria/Editor_rtl.css b/dijit/themes/soria/Editor_rtl.css
new file mode 100644
index 0000000..fd9658a
--- /dev/null
+++ b/dijit/themes/soria/Editor_rtl.css
@@ -0,0 +1,10 @@
+
+.dijitRtl .soria .dijitEditorIcon {
+	background-image: url('images/editor_rtl.gif'); 
+}
+.dijitRtl .soria .dijitDisabled .dijitEditorIcon {
+	background-image: url('images/editorDisabled_rtl.gif'); 
+}
+.dijitRtl .soria .dijitToolbar .dijitToolbarSeparator {
+	background-image: url('images/editor_rtl.gif');
+}
diff --git a/dijit/themes/soria/Menu.css b/dijit/themes/soria/Menu.css
new file mode 100644
index 0000000..9d6b97a
--- /dev/null
+++ b/dijit/themes/soria/Menu.css
@@ -0,0 +1,62 @@
+
+.soria .dijitMenu,
+.soria .dijitMenuBar {
+	border: 1px solid #cbcbcb;
+	margin: 0px;
+	padding: 0px;
+	background-color: #fff;
+}
+.soria .dijitBorderContainer .dijitMenuBar {
+	border:1px solid #B1BADF;
+}
+.soria .dijitMenuItem {
+	font-family: sans-serif;
+	margin: 0px;
+	color: #243C5F;
+}
+.soria .dijitMenuBar .dijitMenuItem {
+	padding: 4px 5px;
+}
+.soria .dijitMenuPreviousButton, .soria .dijitMenuNextButton {
+	font-style: italic;
+}
+.soria .dijitMenuItem TD {
+	padding:1px;
+}
+.soria .dijitMenuPassive .dijitMenuItemHover,
+.soria .dijitMenuItemSelected {
+	background-color: #d9e6f9; 
+	color: #243C5F;
+}
+.soria .dijitMenuItemIcon {
+	width: 15px;
+	height: 15px;
+}
+.soria .dijitMenuExpand {
+	width:15px;
+	height:15px;
+	background-image: url('images/spriteRoundedIconsSmall.png');
+	background-position: -30px top;
+}
+.dj_ie6 .soria .dijitMenuExpand {
+	background-image: url('images/spriteRoundedIconsSmall.gif');
+}
+.soria .dijitMenuSeparator {
+	height: 1px;
+}
+.soria .dijitMenuSeparatorTop {
+	border-bottom: 1px solid #fff; 
+}
+.soria .dijitMenuSeparatorBottom {
+	border-top: 1px solid #8ba0bd;
+}
+.soria .dijitCheckedMenuItemIconChar {
+	display: none;
+}
+.soria .dijitCheckedMenuItemIcon {
+	background-image: url('images/spriteCheckbox.gif');
+	background-position: -80px;
+}
+.soria .dijitCheckedMenuItemChecked .dijitCheckedMenuItemIcon {
+	background-position: -64px;
+}
diff --git a/dijit/themes/soria/Menu_rtl.css b/dijit/themes/soria/Menu_rtl.css
new file mode 100644
index 0000000..6fa9a6a
--- /dev/null
+++ b/dijit/themes/soria/Menu_rtl.css
@@ -0,0 +1,8 @@
+
+.dijitRtl .soria .dijitMenuItem .dijitMenuItemIcon {
+	padding-left: 3px;
+	padding-right: 0px;
+}
+.dijitRtl .soria .dijitMenuItem .dijitMenuExpand {
+	background-position: left top;
+}
diff --git a/dijit/themes/soria/ProgressBar.css b/dijit/themes/soria/ProgressBar.css
new file mode 100644
index 0000000..566d048
--- /dev/null
+++ b/dijit/themes/soria/ProgressBar.css
@@ -0,0 +1,24 @@
+
+.soria .dijitProgressBar {
+	margin:2px 0px 2px 0px;
+}
+.soria .dijitProgressBarEmpty{
+	
+	background:#fff url("images/progressBarEmpty.png") repeat-x center center;
+	border-color: #8ba0bd;
+}
+.soria .dijitProgressBarTile{
+	
+	background:#f0f0f0 url("images/progressBarFull.png") repeat-x center center;
+}
+.soria .dijitProgressBarFull {
+	border-right:1px solid #8ba0bd;
+}
+.soria .dijitProgressBarLabel {
+	
+	color:#293a4b;
+}
+.soria .dijitProgressBarIndeterminate .dijitProgressBarTile {
+	
+	background:#cad2de url("images/progressBarAnim.gif") repeat-x center center;
+}
diff --git a/dijit/themes/soria/TimePicker.css b/dijit/themes/soria/TimePicker.css
new file mode 100644
index 0000000..a9db415
--- /dev/null
+++ b/dijit/themes/soria/TimePicker.css
@@ -0,0 +1,50 @@
+
+.soria .dijitTimePickerTick,
+.soria .dijitTimePickerMarker {
+	border-color: #b1badf;
+}
+.soria .dijitTimePickerTick {
+	color:white;
+}
+.soria .dijitTimePickerMarker {
+	background:#bed7f0 url("images/titleBar.png") repeat-x top;
+	color:#293a4b;
+	font-weight: bold;
+}
+.soria .dijitTimePickerItemSelected {
+	color: black;
+	background: #b9cbf1 none;
+}
+.soria .dijitTimePickerItemHover {
+	background: #60a1ea none;
+	color:white;
+}
+.soria .dijitTimePickerItemHover,
+.soria .dijitTimePickerItemSelected {
+	position: relative;
+	z-index: 10;
+}
+.soria .dijitTimePickerTick .dijitTimePickerItemInner {
+	font-size:0.4em;
+}
+.soria .dijitTimePickerItemHover .dijitTimePickerItemInner,
+.soria .dijitTimePickerItemSelected .dijitTimePickerItemInner {
+	font-size:1em;
+}
+.soria .dijitTimePickerMarkerHover {
+	border-top: 1px solid #94b9ef;
+}
+.soria .dijitTimePickerTickHover,
+.soria .dijitTimePickerTickSelected {
+	margin-top:-0.3em;
+	margin-bottom:-0.3em;
+	border-bottom: none;
+}
+.dijit_a11y .dijitTimePickerTickHover {
+	background-color: #CCC !important;
+	border-top: 1px solid #333 !important;
+	border-bottom: 1px solid #333 !important;
+}
+.dijit_a11y .dijitTimePickerMarkerHover {
+	border-bottom-width: 2px;
+}
diff --git a/dijit/themes/soria/TitlePane.css b/dijit/themes/soria/TitlePane.css
new file mode 100644
index 0000000..cf2ee29
--- /dev/null
+++ b/dijit/themes/soria/TitlePane.css
@@ -0,0 +1,68 @@
+ 
+ 
+.soria .dijitTitlePaneTitle {
+	background: #cccccc;
+	background:#fff url("images/titleBar.png") repeat-x top left;
+	border:1px solid #bfbfbf;
+	padding:3px 4px;
+	cursor: pointer;
+	font-size: 0.9em;
+	font-weight: bold;
+	color: #6d6d6d;
+}
+.soria .dijitTitlePaneTitle-hover {
+	background: #f9f9f9 url("images/accordionItemActive.png") top repeat-x;
+}
+.soria .dijitTitlePaneTitle * {
+	vertical-align: middle;
+}
+.soria .dijitTitlePane .dijitArrowNode {
+	width:15px;
+	height:15px;
+}
+.soria .dijitTitlePaneFocused .dijitTitlePaneTextNode {
+	color: #243C5F;
+}
+.soria .dijitOpen .dijitTitlePaneTextNode {
+	color: #243C5F;
+}
+.soria .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background: url('images/spriteRoundedIconsSmall.png') no-repeat -30px top;
+}
+.dj_ie6 .soria .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background:url('images/spriteRoundedIconsSmall.gif') no-repeat -30px top;
+}
+.soria .dijitTitlePane .dijitOpen .dijitArrowNode {
+	background:url('images/spriteRoundedIconsSmall.png') no-repeat -15px top;
+}
+.dj_ie6 .soria .dijitTitlePane .dijitOpen .dijitArrowNode {
+	background:url('images/spriteRoundedIconsSmall.gif') no-repeat -15px top;
+}
+.soria .dijitTitlePane .dijitArrowNodeInner {
+	display:none;
+}
+.dijit_a11y .dijitTitlePane .dijitArrowNodeInner {
+	display:inline !important;
+	font-family:monospace;
+	cursor: pointer;
+	padding-bottom:.2em;
+}
+.dijit_a11y .dijitTitlePane .dijitArrowNode {
+	display:none;
+}
+.soria .dijitTitlePaneContentOuter {
+	background: #ffffff;
+	border:1px solid #bfbfbf;
+	border-top: 0px solid #3d3d3d;	
+}
+.soria .dijitTitlePaneContentInner {
+	padding:10px;
+}
+.dj_ie6 .soria .dijitTitlePaneContentOuter,
+.dj_ie6 .soria .dijitTitlePane .dijitTitlePaneTitle {
+	zoom: 1;
+}
+.soria .dijitTitlePaneTextNode {
+	margin-left: 4px;
+	margin-right: 4px;
+}
diff --git a/dijit/themes/soria/TitlePane_rtl.css b/dijit/themes/soria/TitlePane_rtl.css
new file mode 100644
index 0000000..1ac1245
--- /dev/null
+++ b/dijit/themes/soria/TitlePane_rtl.css
@@ -0,0 +1,6 @@
+.dijitRtl .soria .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background-position: 0px top;
+}
+.dj_ie6-rtl .soria .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background-position: 0px top;
+}
diff --git a/dijit/themes/soria/Toolbar.css b/dijit/themes/soria/Toolbar.css
new file mode 100644
index 0000000..fa4cbc3
--- /dev/null
+++ b/dijit/themes/soria/Toolbar.css
@@ -0,0 +1,58 @@
+.soria .dijitToolbar {
+	border-bottom: 1px solid #ccc;
+	background:#eaeaea url("images/titleBar.png") repeat-x top left;
+}
+.dj_ie6 .soria .dijitToolbar {
+	height: 10px;
+}
+.soria .dijitToolbar .dijitButtonNode,
+.soria .dijitToolbar .dijitComboButton .dijitButtonContents,
+.soria .dijitToolbar .dijitComboButton .dijitDownArrowButton {
+	background: none;
+	margin: 0px;
+	padding: 0px;
+	border: none;
+	font-size: 12px;
+}
+.soria .dijitToolbar .dijitButton,
+.soria .dijitToolbar .dijitToggleButton,
+.soria .dijitToolbar .dijitDropDownButton,
+.soria .dijitToolbar .dijitComboButton .dijitButtonContents,
+.soria .dijitToolbar .dijitComboButton .dijitDownArrowButton {
+	background: none;
+	padding: 1px;	
+}
+.soria .dijitToolbar .dijitButtonChecked,
+.soria .dijitToolbar .dijitToggleButtonChecked {
+	background-color:#d8e5f8;
+	border:1px solid #316ac5;
+	padding: 0px;
+}
+.soria .dijitToolbar .dijitButtonCheckedHover,
+.soria .dijitToolbar .dijitToggleButtonCheckedHover
+ {
+	background-color:#9abbea;
+	border:1px solid #316ac5;
+	padding: 0px;
+}
+.soria .dijitToolbar .dijitButtonHover,
+.soria .dijitToolbar .dijitToggleButtonHover,
+.soria .dijitToolbar .dijitDropDownButtonHover,
+.soria .dijitToolbar .dijitComboButtonHover .dijitButtonContents,
+.soria .dijitToolbar .dijitComboButtonDownArrowHover .dijitDownArrowButton {
+	
+	border: 1px solid #316ac5;
+	padding: 0px;
+	background-color:#9abbea;
+}
+.soria .dijitToolbar label {	
+	padding: 3px 3px 0 6px;
+}
+.dj_ie .soria .dijitToolbar .dijitComboButton .dijitButtonContentsFocused,
+.dj_ie .soria .dijitToolbar .dijitComboButton .dijitDownArrowButtonFocused,
+.dj_ff2 .soria.dijitToolbar .dijitComboButton .dijitButtonContentsFocused,
+.dj_ff2 .soria .dijitToolbar .dijitComboButton .dijitDownArrowButtonFocused {
+	
+	border: 1px #777 dotted !important;
+	padding: 0px;
+}
diff --git a/dijit/themes/soria/Tree.css b/dijit/themes/soria/Tree.css
new file mode 100644
index 0000000..3930d25
--- /dev/null
+++ b/dijit/themes/soria/Tree.css
@@ -0,0 +1,90 @@
+
+.soria .dijitTreeNode {
+    background : url('images/treeI.gif') no-repeat;
+    background-position : top left;
+    background-repeat : repeat-y;
+    zoom: 1;	
+}
+.soria .dijitTreeNodeHover {
+	
+	background-image: url(images/treeHover.png);
+	background-repeat: repeat;
+	background-color: none !important;
+}
+.soria .dijitTreeIsLast {
+    background: url('images/treeI_half.gif') no-repeat;
+}
+.soria .dijitTreeLabel {
+	font-weight: normal;
+	margin-left: 3px;
+}
+.soria .dijitTreeIsRoot {
+    margin-left: 0;
+    background-image: none;
+}
+.soria .dijitTreeExpando {
+    width: 18px;
+    height: 18px;
+}
+.soria .dijitTreeRow {
+	
+	padding-bottom: 2px;
+}
+.soria .dijitTreeContent {
+    min-height: 18px;
+    min-width: 18px;
+    padding-left:1px;
+}
+.soria .dijitTreeExpand {
+    width: 18px;
+    height: 18px;
+    background-repeat : no-repeat;
+}
+.soria .dijitTreeNodeEmphasized {
+    background-color: Highlight;
+    color: HighlightText;
+}
+.soria .dijitTreeLabelFocused {
+	outline: 1px invert dotted;
+}
+.soria .dijitTreeNodeSelected .dijitTreeLabel{
+	background:#b8cbec;
+}
+.soria .dijitTreeExpandoOpened {
+	background: url('images/spriteTree.gif') no-repeat -18px top;
+}
+.soria .dijitTreeExpandoClosed {
+	background-image: url('images/spriteTree.gif');
+}
+.soria .dijitTreeExpandoLeaf {
+	background: url('images/spriteTree.gif') no-repeat -36px top;
+}
+.soria .dijitTreeExpandoLoading {
+	background-image: url('images/treeExpand_loading.gif');
+}
+.soria .dijitTreeIcon {
+	width: 16px;
+	height: 16px;
+}
+.soria .dijitFolderOpened {
+	background: url('images/spriteDivIcons.gif') no-repeat -16px top;
+}
+.soria .dijitFolderClosed {
+	background: url('images/spriteDivIcons.gif') no-repeat top left;
+}
+.soria .dijitLeaf {
+	background: url('images/spriteDivIcons.gif') no-repeat -32px top;
+}
+.soria .dijitTreeNode .dojoDndItemBefore,
+.soria .dijitTreeNode .dojoDndItemAfter {
+	border-bottom: none;
+	border-top: none;
+}
+.soria .dijitTreeNode .dojoDndItemBefore .dijitTreeContent {
+	
+	border-top: 2px solid #369;
+}
+.soria .dijitTreeNode .dojoDndItemAfter .dijitTreeContent {
+	
+	border-bottom: 2px solid #369;
+}
diff --git a/dijit/themes/soria/Tree_rtl.css b/dijit/themes/soria/Tree_rtl.css
new file mode 100644
index 0000000..551c0d5
--- /dev/null
+++ b/dijit/themes/soria/Tree_rtl.css
@@ -0,0 +1,17 @@
+
+.dijitRtl .soria .dijitTreeContainer .dijitTreeNode {
+    background-image : none;
+}
+.dijitRtl .soria .dijitTreeContainer .dijitTreeContent {
+    padding-left: auto;
+    padding-right: 1px;   
+}
+.dijitRtl .soria .dijitTreeContainer .dijitTreeExpandoOpened {
+	background: url('images/spriteTree_rtl.gif') no-repeat -18px top;
+}
+.dijitRtl .soria .dijitTreeContainer .dijitTreeExpandoClosed {
+	background-image: url('images/spriteTree_rtl.gif');
+}
+.dijitRtl .soria .dijitTreeContainer .dijitTreeExpandoLeaf {
+	background: none;
+}
diff --git a/dijit/themes/soria/form/Button.css b/dijit/themes/soria/form/Button.css
new file mode 100644
index 0000000..086fb90
--- /dev/null
+++ b/dijit/themes/soria/form/Button.css
@@ -0,0 +1,88 @@
+
+.soria .dijitButtonNode {
+	
+	
+	border: 1px solid #8ba0bd;
+	border-bottom:1px solid #657c9c;
+	padding: 0.1em 0.2em 0.2em 0.2em; 
+	background: #bcd5f0 url("../images/buttonEnabled.png") repeat-x top left;
+}
+.soria .dijitButtonNode button { 
+	border: 0px; 
+	background-color: transparent; 
+} 
+ 
+.soria .dijitButtonText {
+	text-align: center; 
+	padding: 0 0.3em;
+}
+.soria .dijitComboBox .dijitButtonNode {
+	border-width: 0px 0px 0px 1px;
+}
+.soria .dijitArrowButton {
+	color: #111;
+}
+.soria .dijitComboButton .dijitDownArrowButton {
+	padding-right:4px;
+}
+.dj_ff2 .soria .dijitComboButton .dijitButtonContentsFocused,
+.dj_ff2 .soria .dijitComboButton .dijitDownArrowButtonFocused {
+	border: 1px black dotted !important;
+}
+.soria .dijitButtonDisabled .dijitButtonNode,
+.soria .dijitToggleButtonDisabled .dijitButtonNode,
+.soria .dijitDropDownButtonDisabled .dijitButtonNode,
+.soria .dijitComboButtonDisabled .dijitButtonNode,
+.soria .dijitComboBoxDisabled,
+.soria .dijitSpinnerDisabled,
+.soria .dijitSpinnerDisabled .dijitButtonNode {
+	
+	border-color: #b9bbdd #b9bbdd #b9bbdd #b9bbdd;
+	background:#c3d3e5 url("../images/buttonDisabled.png") top repeat-x;
+	opacity: 0.60; 
+}
+.soria .dijitButtonHover .dijitButtonNode,
+.soria .dijitButtonNodeHover,
+.soria .dijitToggleButtonHover .dijitButtonNode,
+.soria .dijitDropDownButtonHover .dijitButtonNode,
+.soria .dijitComboButtonHover .dijitButtonContents,
+.soria .dijitComboButtonDownArrowHover .dijitDownArrowButton,
+.soria .dijitComboBoxHover .dijitDownArrowButton,
+.soria .dijitSpinnerUpArrowHover .dijitUpArrowButton,
+.soria .dijitSpinnerDownArrowHover .dijitDownArrowButton {
+	
+	
+	color:#243C5F;
+	background:#acc5e2 url("../images/buttonHover.png") repeat-x top left;
+}
+.soria .dijitButtonActive .dijitButtonNode,
+.soria .dijitToggleButtonActive .dijitButtonNode,
+.soria .dijitDropDownButtonActive .dijitButtonNode,
+.soria .dijitComboButtonActive .dijitButtonContents,
+.soria .dijitStackController .dijitToggleButtonChecked .dijitButtonNode {
+	
+	border-color:#657c9c;
+	background: #91b4e5 url("../images/buttonActive.png") top left repeat-x;
+}
+.soria .dijitSpinnerUpArrowActive .dijitUpArrowButton,
+.soria .dijitSpinnerDownArrowActive .dijitDownArrowButton,
+.soria .dijitComboBoxActive .dijitDownArrowButton {
+	
+	background: #91b4e5 url("../images/buttonActive.png") top left repeat-x;
+}
+.soria .dijitArrowButtonInner {
+	background:url("../images/spriteArrows.png") no-repeat left top;
+	width: 11px;
+}
+.soria .dijitUpArrowButton .dijitArrowButtonInner { 
+	background:url("../images/spriteArrows.png") no-repeat -22px top; 
+	width: 11px;
+}
+.dj_ie6 .soria .dijitArrowButtonInner {
+	background:url("../images/spriteArrows.gif") no-repeat left top;
+	width: 11px;
+}
+.dj_ie6 .soria .dijitUpArrowButton .dijitArrowButtonInner {
+	background:url("../images/spriteArrows.gif") no-repeat -22px top;
+	width: 11px;
+}
diff --git a/dijit/themes/soria/form/Button_rtl.css b/dijit/themes/soria/form/Button_rtl.css
new file mode 100644
index 0000000..ee80da7
--- /dev/null
+++ b/dijit/themes/soria/form/Button_rtl.css
@@ -0,0 +1,3 @@
+.dijitRtl .soria .dijitComboBox .dijitButtonNode {
+	border-width: 0px 0px 0px 1px;
+}
diff --git a/dijit/themes/soria/form/Checkbox.css b/dijit/themes/soria/form/Checkbox.css
new file mode 100644
index 0000000..8227dcb
--- /dev/null
+++ b/dijit/themes/soria/form/Checkbox.css
@@ -0,0 +1,40 @@
+
+.soria .dijitToggleButton .dijitCheckBox,
+.soria .dijitToggleButton .dijitCheckBoxIcon {
+	background-image: url('../images/spriteCheckbox.gif');
+}
+.soria .dijitCheckBox,
+.soria .dijitCheckBoxIcon {		
+	background-image: url('../images/spriteCheckbox.gif'); 
+	background-repeat: no-repeat;
+	width: 16px;
+	height: 16px;
+	margin: 0;
+	padding: 0;
+}
+.soria .dijitCheckBox,
+.soria .dijitToggleButton .dijitCheckBoxIcon {
+	
+	background-position: -16px;
+}
+.soria .dijitCheckBoxChecked,
+.soria .dijitToggleButtonChecked .dijitCheckBoxIcon {
+	
+	background-position: 0px;
+}
+.soria .dijitCheckBoxDisabled {
+	
+	background-position: -48px;
+}
+.soria .dijitCheckBoxCheckedDisabled {
+	
+	background-position: -32px;
+}
+.soria .dijitCheckBoxHover {
+	
+	background-position: -80px;
+}
+.soria .dijitCheckBoxCheckedHover {
+	
+	background-position: -64px;
+}
diff --git a/dijit/themes/soria/form/ComboBox.css b/dijit/themes/soria/form/ComboBox.css
new file mode 100644
index 0000000..9167139
--- /dev/null
+++ b/dijit/themes/soria/form/ComboBox.css
@@ -0,0 +1,10 @@
+.soria .dijitComboBox .dijitArrowButton .dijitArrowButtonInner {
+	background:url("../images/spriteArrows.png") no-repeat left center;
+	width: 11px;
+}
+.dj_ie6 .soria .dijitComboBox .dijitArrowButton .dijitArrowButtonInner {
+	background:url("../images/spriteArrows.gif") no-repeat left center;
+}
+.soria .dijitComboBoxHover .dijitArrowButtonInner {
+	
+}
diff --git a/dijit/themes/soria/form/Common.css b/dijit/themes/soria/form/Common.css
new file mode 100644
index 0000000..f1e7f0e
--- /dev/null
+++ b/dijit/themes/soria/form/Common.css
@@ -0,0 +1,88 @@
+
+.soria .dijitInputField INPUT,
+.soria .dijitTextBox,
+.soria .dijitComboBox,
+.soria .dijitSpinner {
+	margin: 0em 0.1em;
+}
+.soria .dijitTextBox,
+.soria .dijitComboBox,
+.soria .dijitSpinner,
+.soria .dijitInlineEditor input,
+.soria .dijitTextArea {
+	
+	background:#fff url("../images/validationInputBg.png") repeat-x top left;
+	border:1px solid #8ba0bd;
+	line-height: normal;
+}
+.dj_ie6 .soria .dijitTextBox,
+.dj_ie6 .soria .dijitComboBox,
+.dj_ie6 .soria .dijitSpinner,
+.dj_ie6 .soria .dijitInlineEditor input,
+.dj_ie6 .soria .dijitTextArea {
+	background:#fff url('../images/validationInputBg.gif') repeat-x top left;
+}
+.soria .dijitTextBoxDisabled,
+.soria .dijitComboBoxDisabled,
+.soria .dijitSpinnerDisabled,
+.soria .dijitTextAreaDisabled {
+	color: gray;
+}
+.dj_webkit .soria .dijitTextBoxDisabled,
+.dj_webkit .soria .dijitComboBoxDisabled,
+.dj_webkit .soria .dijitSpinnerDisabled,
+.dj_webkit .soria .dijitTextareaDisabled {
+	color: #eee;
+}
+.soria .dijitComboBox .dijitButtonNode {
+	padding: 0 0.2em;
+}
+.soria .dijitComboBox .dijitButtonNode,
+.soria .dijitSpinner .dijitButtonNode {
+	
+	border-color: #8ba0bd;
+	border-left: 1px solid #8ba0bd;
+}
+.soria .dijitTextBoxFocused,
+.soria .dijitComboBoxFocused,
+.soria .dijitSpinnerFocused, .soria .dijitSpinnerUpArrowActive, .soria .dijitSpinnerDownArrowActive,
+.soria .dijitTextAreaFocused {
+	
+	border-color:#406b9b;
+}
+.soria .dijitComboBoxFocused .dijitButtonNode,
+.soria .dijitSpinnerFocused .dijitButtonNode,
+.soria .dijitSpinnerUpArrowActive .dijitButtonNode,
+.soria .dijitSpinnerDownArrowActive .dijitButtonNode {
+	border-left-color:#8ba0bd;
+}
+.soria .dijitSpinnerFocused .dijitDownArrowButton,
+.soria .dijitSpinnerUpArrowActive .dijitDownArrowButton,
+.soria .dijitSpinnerDownArrowActive .dijitDownArrowButton {
+	border-top-color:#8ba0bd;
+}
+.soria .dijitError {
+	border-color:#f3d118;
+	background-color:#f9f7ba;
+	background-image:none;
+}
+.dj_ie6 .soria .dijitError INPUT {
+	
+	background-color:#f9f7ba !important;
+}
+.soria .dijitErrorFocused {
+	background-color:#ff6;
+	background-image:none;
+}
+.dj_ie6 .soria .dijitErrorFocused INPUT {
+	
+	background-color:#ff6 !important;
+}
+.soria .dijitValidationIcon {
+	
+	width: 16px;
+	background: transparent url('../images/warning.png') no-repeat center center;
+}
+.soria .dijitComboBoxHighlightMatch {
+	background-color:#f9f7ba;
+}
diff --git a/dijit/themes/soria/form/Common_rtl.css b/dijit/themes/soria/form/Common_rtl.css
new file mode 100644
index 0000000..89f5ad7
--- /dev/null
+++ b/dijit/themes/soria/form/Common_rtl.css
@@ -0,0 +1,7 @@
+.dijitRtl .soria .dijitComboBox .dijitButtonNode,
+.dijitRtl .soria .dijitSpinner .dijitButtonNode {
+	
+	border-color: #8ba0bd;
+	border-left: 0px solid #8ba0bd;
+	border-right: 1px solid #8ba0bd;
+}
diff --git a/dijit/themes/soria/form/RadioButton.css b/dijit/themes/soria/form/RadioButton.css
new file mode 100644
index 0000000..543694e
--- /dev/null
+++ b/dijit/themes/soria/form/RadioButton.css
@@ -0,0 +1,40 @@
+
+.soria .dijitToggleButton .dijitRadio,
+.soria .dijitToggleButton .dijitRadioIcon {
+	background-image: url('../images/spriteRadio.gif');
+}
+.soria .dijitRadio,
+.soria .dijitRadioIcon	{		
+	background-image: url('../images/spriteRadio.gif'); 
+	background-repeat: no-repeat;
+	width: 16px;
+	height: 16px;
+	margin: 0;
+	padding: 0;
+}
+.soria .dijitRadio,
+.soria .dijitToggleButton .dijitRadioIcon {
+	
+	background-position: -16px;
+}
+.soria .dijitRadioChecked,
+.soria .dijitToggleButtonChecked .dijitRadioIcon {
+	
+	background-position: 0px;
+}
+.soria .dijitRadioDisabled {
+	
+	background-position: -48px;
+}
+.soria .dijitRadioCheckedDisabled {
+	
+	background-position: -32px;
+}
+.soria .dijitRadioHover {
+	
+	background-position: -80px;
+}
+.soria .dijitRadioCheckedHover {
+	
+	background-position: -64px;
+}
diff --git a/dijit/themes/soria/form/Slider.css b/dijit/themes/soria/form/Slider.css
new file mode 100644
index 0000000..4625bbf
--- /dev/null
+++ b/dijit/themes/soria/form/Slider.css
@@ -0,0 +1,117 @@
+
+.soria .dijitSliderProgressBarH {
+	border-color: #b1badf;
+	background: #c0c2c5 url("../images/sliderFull.png") repeat-x top left;
+}
+.soria .dijitSliderProgressBarV {
+	border-color: #b1badf;
+	background: #c0c2c5 url("../images/sliderFullVertical.png") repeat-y bottom left;
+}
+.soria .dijitSliderFocused .dijitSliderProgressBarH,
+.soria .dijitSliderFocused .dijitSliderLeftBumper {
+	background-image:url("../images/sliderFullFocus.png");
+}
+.soria .dijitSliderFocused .dijitSliderProgressBarV,
+.soria .dijitSliderFocused .dijitSliderBottomBumper {
+	background-image:url("../images/sliderFullVerticalFocus.png");
+}
+.soria .dijitSliderRemainingBarV {
+	border-color: #b4b4b4;
+	background: #dcdcdc url("../images/sliderEmptyVertical.png") repeat-y bottom left;
+}
+.soria .dijitSliderRemainingBarH {
+	border-color: #b4b4b4;
+	background: #dcdcdc url("../images/sliderEmpty.png") repeat-x top left;
+}
+.soria .dijitSliderBar {
+	border-style: solid;
+	outline:1px;
+	
+}
+.soria .dijitSliderFocused .dijitSliderBar {
+	border-color:#8ba0bd;	
+}
+.dijit_a11y .dijitSliderProgressBar {
+	background-color:#333 !important;
+}
+.soria .dijitSliderImageHandleH {
+	border:0px;
+	width:15px;
+	height:18px;
+	background:url("../images/preciseSliderThumb.png") no-repeat center top;
+	cursor:pointer;
+}
+.soria .dijitSliderFocused .dijitSliderImageHandleH {
+	background-image:url("../images/preciseSliderThumbFocus.png");
+	#background-image:url("../images/preciseSliderThumbFocus.gif");
+}
+.dj_ie6 .soria .dijitSliderImageHandleH {
+	background-image:url("../images/preciseSliderThumb.gif");
+}
+.soria .dijitSliderLeftBumper {
+	border-left-width: 1px;
+	border-color: #aab0bb;
+	background: #c0c2c5 url("../images/sliderFull.png") repeat-x top left;
+}
+.soria .dijitSliderRightBumper {
+	background: #dcdcdc url("../images/sliderEmpty.png") repeat-x top left;
+	border-color: #b4b4b4;
+	border-right-width: 1px;
+}
+.soria .dijitSliderImageHandleV {
+	border:0px;
+	width:20px;
+	height:15px;
+	background:url("../images/sliderThumb.png") no-repeat center center;
+	#background:url("../images/sliderThumb.gif") no-repeat center center;
+	cursor:pointer;
+}
+.soria .dijitSliderFocused .dijitSliderImageHandleV {
+	background-image:url("../images/sliderThumbFocus.png");
+	#background-image:url("../images/sliderThumbFocus.gif");
+}
+.soria .dijitSliderBottomBumper {
+	border-bottom-width: 1px;
+	border-color: #aab0bb;
+	background: #c0c2c5 url("../images/sliderFullVertical.png") repeat-y bottom left;
+}
+.soria .dijitSliderTopBumper {
+	background: #dcdcdc url("../images/sliderEmptyVertical.png") repeat-y top left;
+	border-color: #b4b4b4;
+	border-top-width: 1px;
+}
+.soria .dijitSliderIncrementIconH,
+.soria .dijitSliderIncrementIconV {
+	background:url('../images/spriteRoundedIconsSmall.png') no-repeat -45px top;
+	#background:url('../images/spriteRoundedIconsSmall.gif') no-repeat -45px top;
+	width:15px; height:15px;
+	cursor:pointer;
+}
+.soria .dijitSliderIncrementIconH {
+	background:url('../images/spriteRoundedIconsSmall.png') no-repeat -30px top;
+	#background:url('../images/spriteRoundedIconsSmall.gif') no-repeat -30px top;
+}
+.soria .dijitSliderDecrementIconH,
+.soria .dijitSliderDecrementIconV {
+	width:15px;
+	height:15px;
+	cursor:pointer;
+	background:url('../images/spriteRoundedIconsSmall.png') no-repeat -15px top;
+	#background:url('../images/spriteRoundedIconsSmall.gif') no-repeat -15px top;
+}
+.soria .dijitSliderDecrementIconH { 
+	background:url('../images/spriteRoundedIconsSmall.png') no-repeat 0px top;
+	#background:url('../images/spriteRoundedIconsSmall.gif') no-repeat 0px top;
+}
+.soria .dijitSliderButtonInner {
+	visibility:hidden;
+}
+.soria .dijitSliderDisabled {
+	opacity:0.6 !important;
+}
+.dj_ie .soria .dijitSliderDisabled,
+.dj_ie .soria .dijitSliderDisabled .dijitRuleContainer,
+.dj_ie .soria .dijitSliderDisabled .dijitSliderRemainingBar,
+.dj_ie .soria .dijitSliderDisabled .dijitSliderProgressBar {
+	filter: gray() alpha(opacity=40);
+}
diff --git a/dijit/themes/soria/form/Slider_rtl.css b/dijit/themes/soria/form/Slider_rtl.css
new file mode 100644
index 0000000..c1d8de3
--- /dev/null
+++ b/dijit/themes/soria/form/Slider_rtl.css
@@ -0,0 +1,29 @@
+
+.dijitRtl .soria .dijitSliderProgressBarH,
+.dijitRtl .soria .dijitSliderRemainingBarH,
+.dijitRtl .soria .dijitSliderLeftBumper,
+.dijitRtl .soria .dijitSliderRightBumper,
+.dijitRtl .soria .dijitSliderTopBumper {
+	background-position: top right;
+}
+.dijitRtl .soria .dijitSliderProgressBarV,
+.dijitRtl .soria .dijitSliderRemainingBarV,
+.dijitRtl .soria .dijitSliderBottomBumper {
+	background-position: bottom right;
+}
+.dijitRtl .soria .dijitSliderLeftBumper {
+	border-left-width: 0px;
+	border-right-width: 1px;
+}
+.dijitRtl .soria .dijitSliderRightBumper {
+	border-left-width: 1px;
+	border-right-width: 0px;
+}
+.dijitRtl .soria .dijitSliderIncrementIconH {
+	background:url('../images/spriteRoundedIconsSmall.png') no-repeat left top;
+	#background:url('../images/spriteRoundedIconsSmall.gif') no-repeat left top;
+}
+.dijitRtl .soria .dijitSliderDecrementIconH {
+	background:url('../images/spriteRoundedIconsSmall.png') no-repeat -30px top;
+	#background:url('../images/spriteRoundedIconsSmall.gif') no-repeat -30px top;
+}
diff --git a/dijit/themes/soria/form/TimeTextBox.css b/dijit/themes/soria/form/TimeTextBox.css
new file mode 100644
index 0000000..d450925
--- /dev/null
+++ b/dijit/themes/soria/form/TimeTextBox.css
@@ -0,0 +1 @@
+ at CHARSET "UTF-8";
diff --git a/dijit/themes/soria/images/accordionItemActive.gif b/dijit/themes/soria/images/accordionItemActive.gif
new file mode 100644
index 0000000..249a153
Binary files /dev/null and b/dijit/themes/soria/images/accordionItemActive.gif differ
diff --git a/dijit/themes/soria/images/accordionItemActive.png b/dijit/themes/soria/images/accordionItemActive.png
new file mode 100644
index 0000000..92c7431
Binary files /dev/null and b/dijit/themes/soria/images/accordionItemActive.png differ
diff --git a/dijit/themes/soria/images/buttonActive.png b/dijit/themes/soria/images/buttonActive.png
new file mode 100644
index 0000000..f815983
Binary files /dev/null and b/dijit/themes/soria/images/buttonActive.png differ
diff --git a/dijit/themes/soria/images/buttonDisabled.png b/dijit/themes/soria/images/buttonDisabled.png
new file mode 100644
index 0000000..f76e4ab
Binary files /dev/null and b/dijit/themes/soria/images/buttonDisabled.png differ
diff --git a/dijit/themes/soria/images/buttonEnabled.png b/dijit/themes/soria/images/buttonEnabled.png
new file mode 100644
index 0000000..3c55c83
Binary files /dev/null and b/dijit/themes/soria/images/buttonEnabled.png differ
diff --git a/dijit/themes/soria/images/buttonHover.png b/dijit/themes/soria/images/buttonHover.png
new file mode 100644
index 0000000..a22ebda
Binary files /dev/null and b/dijit/themes/soria/images/buttonHover.png differ
diff --git a/dijit/themes/soria/images/dndCopy.png b/dijit/themes/soria/images/dndCopy.png
new file mode 100644
index 0000000..baecd7c
Binary files /dev/null and b/dijit/themes/soria/images/dndCopy.png differ
diff --git a/dijit/themes/soria/images/dndMove.png b/dijit/themes/soria/images/dndMove.png
new file mode 100644
index 0000000..07f878c
Binary files /dev/null and b/dijit/themes/soria/images/dndMove.png differ
diff --git a/dijit/themes/soria/images/dndNoCopy.png b/dijit/themes/soria/images/dndNoCopy.png
new file mode 100644
index 0000000..9bf9c33
Binary files /dev/null and b/dijit/themes/soria/images/dndNoCopy.png differ
diff --git a/dijit/themes/soria/images/dndNoMove.png b/dijit/themes/soria/images/dndNoMove.png
new file mode 100644
index 0000000..cb8bd8b
Binary files /dev/null and b/dijit/themes/soria/images/dndNoMove.png differ
diff --git a/dijit/themes/soria/images/editor.gif b/dijit/themes/soria/images/editor.gif
new file mode 100644
index 0000000..127c9c4
Binary files /dev/null and b/dijit/themes/soria/images/editor.gif differ
diff --git a/dijit/themes/soria/images/editorDisabled.gif b/dijit/themes/soria/images/editorDisabled.gif
new file mode 100644
index 0000000..9dc5103
Binary files /dev/null and b/dijit/themes/soria/images/editorDisabled.gif differ
diff --git a/dijit/themes/soria/images/editorDisabled_rtl.gif b/dijit/themes/soria/images/editorDisabled_rtl.gif
new file mode 100644
index 0000000..74d407a
Binary files /dev/null and b/dijit/themes/soria/images/editorDisabled_rtl.gif differ
diff --git a/dijit/themes/soria/images/editor_rtl.gif b/dijit/themes/soria/images/editor_rtl.gif
new file mode 100644
index 0000000..b94d040
Binary files /dev/null and b/dijit/themes/soria/images/editor_rtl.gif differ
diff --git a/dijit/themes/soria/images/preciseSliderThumb.gif b/dijit/themes/soria/images/preciseSliderThumb.gif
new file mode 100644
index 0000000..53b33e5
Binary files /dev/null and b/dijit/themes/soria/images/preciseSliderThumb.gif differ
diff --git a/dijit/themes/soria/images/preciseSliderThumb.png b/dijit/themes/soria/images/preciseSliderThumb.png
new file mode 100644
index 0000000..045bf35
Binary files /dev/null and b/dijit/themes/soria/images/preciseSliderThumb.png differ
diff --git a/dijit/themes/soria/images/preciseSliderThumbFocus.gif b/dijit/themes/soria/images/preciseSliderThumbFocus.gif
new file mode 100644
index 0000000..8c6f92e
Binary files /dev/null and b/dijit/themes/soria/images/preciseSliderThumbFocus.gif differ
diff --git a/dijit/themes/soria/images/preciseSliderThumbFocus.png b/dijit/themes/soria/images/preciseSliderThumbFocus.png
new file mode 100644
index 0000000..c235849
Binary files /dev/null and b/dijit/themes/soria/images/preciseSliderThumbFocus.png differ
diff --git a/dijit/themes/soria/images/progressBarAnim.gif b/dijit/themes/soria/images/progressBarAnim.gif
new file mode 100644
index 0000000..73e25e1
Binary files /dev/null and b/dijit/themes/soria/images/progressBarAnim.gif differ
diff --git a/dijit/themes/soria/images/progressBarEmpty.png b/dijit/themes/soria/images/progressBarEmpty.png
new file mode 100644
index 0000000..04d81df
Binary files /dev/null and b/dijit/themes/soria/images/progressBarEmpty.png differ
diff --git a/dijit/themes/soria/images/progressBarFull.png b/dijit/themes/soria/images/progressBarFull.png
new file mode 100644
index 0000000..bed17b3
Binary files /dev/null and b/dijit/themes/soria/images/progressBarFull.png differ
diff --git a/dijit/themes/soria/images/sliderEmpty.png b/dijit/themes/soria/images/sliderEmpty.png
new file mode 100644
index 0000000..99fbd72
Binary files /dev/null and b/dijit/themes/soria/images/sliderEmpty.png differ
diff --git a/dijit/themes/soria/images/sliderEmptyVertical.png b/dijit/themes/soria/images/sliderEmptyVertical.png
new file mode 100644
index 0000000..2d497e3
Binary files /dev/null and b/dijit/themes/soria/images/sliderEmptyVertical.png differ
diff --git a/dijit/themes/soria/images/sliderFull.png b/dijit/themes/soria/images/sliderFull.png
new file mode 100644
index 0000000..171eb54
Binary files /dev/null and b/dijit/themes/soria/images/sliderFull.png differ
diff --git a/dijit/themes/soria/images/sliderFullFocus.png b/dijit/themes/soria/images/sliderFullFocus.png
new file mode 100644
index 0000000..0956a72
Binary files /dev/null and b/dijit/themes/soria/images/sliderFullFocus.png differ
diff --git a/dijit/themes/soria/images/sliderFullVertical.png b/dijit/themes/soria/images/sliderFullVertical.png
new file mode 100644
index 0000000..35845da
Binary files /dev/null and b/dijit/themes/soria/images/sliderFullVertical.png differ
diff --git a/dijit/themes/soria/images/sliderFullVerticalFocus.png b/dijit/themes/soria/images/sliderFullVerticalFocus.png
new file mode 100644
index 0000000..9b158bb
Binary files /dev/null and b/dijit/themes/soria/images/sliderFullVerticalFocus.png differ
diff --git a/dijit/themes/soria/images/sliderThumb.gif b/dijit/themes/soria/images/sliderThumb.gif
new file mode 100644
index 0000000..29899a4
Binary files /dev/null and b/dijit/themes/soria/images/sliderThumb.gif differ
diff --git a/dijit/themes/soria/images/sliderThumb.png b/dijit/themes/soria/images/sliderThumb.png
new file mode 100644
index 0000000..b6abbd2
Binary files /dev/null and b/dijit/themes/soria/images/sliderThumb.png differ
diff --git a/dijit/themes/soria/images/sliderThumbFocus.gif b/dijit/themes/soria/images/sliderThumbFocus.gif
new file mode 100644
index 0000000..f8d306f
Binary files /dev/null and b/dijit/themes/soria/images/sliderThumbFocus.gif differ
diff --git a/dijit/themes/soria/images/sliderThumbFocus.png b/dijit/themes/soria/images/sliderThumbFocus.png
new file mode 100644
index 0000000..73ee705
Binary files /dev/null and b/dijit/themes/soria/images/sliderThumbFocus.png differ
diff --git a/dijit/themes/soria/images/splitContainerSizerH-thumb.png b/dijit/themes/soria/images/splitContainerSizerH-thumb.png
new file mode 100644
index 0000000..0e8f397
Binary files /dev/null and b/dijit/themes/soria/images/splitContainerSizerH-thumb.png differ
diff --git a/dijit/themes/soria/images/splitContainerSizerH.png b/dijit/themes/soria/images/splitContainerSizerH.png
new file mode 100644
index 0000000..7cdf79a
Binary files /dev/null and b/dijit/themes/soria/images/splitContainerSizerH.png differ
diff --git a/dijit/themes/soria/images/splitContainerSizerV-thumb.png b/dijit/themes/soria/images/splitContainerSizerV-thumb.png
new file mode 100644
index 0000000..7f12fed
Binary files /dev/null and b/dijit/themes/soria/images/splitContainerSizerV-thumb.png differ
diff --git a/dijit/themes/soria/images/splitContainerSizerV.png b/dijit/themes/soria/images/splitContainerSizerV.png
new file mode 100644
index 0000000..9ff14d6
Binary files /dev/null and b/dijit/themes/soria/images/splitContainerSizerV.png differ
diff --git a/dijit/themes/soria/images/spriteArrows.gif b/dijit/themes/soria/images/spriteArrows.gif
new file mode 100644
index 0000000..fc81207
Binary files /dev/null and b/dijit/themes/soria/images/spriteArrows.gif differ
diff --git a/dijit/themes/soria/images/spriteArrows.png b/dijit/themes/soria/images/spriteArrows.png
new file mode 100644
index 0000000..73aa700
Binary files /dev/null and b/dijit/themes/soria/images/spriteArrows.png differ
diff --git a/dijit/themes/soria/images/spriteCheckbox.gif b/dijit/themes/soria/images/spriteCheckbox.gif
new file mode 100644
index 0000000..d2c4ebf
Binary files /dev/null and b/dijit/themes/soria/images/spriteCheckbox.gif differ
diff --git a/dijit/themes/soria/images/spriteCheckbox.png b/dijit/themes/soria/images/spriteCheckbox.png
new file mode 100644
index 0000000..e992330
Binary files /dev/null and b/dijit/themes/soria/images/spriteCheckbox.png differ
diff --git a/dijit/themes/soria/images/spriteDivIcons.gif b/dijit/themes/soria/images/spriteDivIcons.gif
new file mode 100644
index 0000000..f5c58e4
Binary files /dev/null and b/dijit/themes/soria/images/spriteDivIcons.gif differ
diff --git a/dijit/themes/soria/images/spriteDivIcons.png b/dijit/themes/soria/images/spriteDivIcons.png
new file mode 100644
index 0000000..d76325f
Binary files /dev/null and b/dijit/themes/soria/images/spriteDivIcons.png differ
diff --git a/dijit/themes/soria/images/spriteRadio.gif b/dijit/themes/soria/images/spriteRadio.gif
new file mode 100644
index 0000000..8dd6e57
Binary files /dev/null and b/dijit/themes/soria/images/spriteRadio.gif differ
diff --git a/dijit/themes/soria/images/spriteRadio.png b/dijit/themes/soria/images/spriteRadio.png
new file mode 100644
index 0000000..14c1080
Binary files /dev/null and b/dijit/themes/soria/images/spriteRadio.png differ
diff --git a/dijit/themes/soria/images/spriteRoundedIconsSmall.gif b/dijit/themes/soria/images/spriteRoundedIconsSmall.gif
new file mode 100644
index 0000000..795ea84
Binary files /dev/null and b/dijit/themes/soria/images/spriteRoundedIconsSmall.gif differ
diff --git a/dijit/themes/soria/images/spriteRoundedIconsSmall.png b/dijit/themes/soria/images/spriteRoundedIconsSmall.png
new file mode 100644
index 0000000..10c0d13
Binary files /dev/null and b/dijit/themes/soria/images/spriteRoundedIconsSmall.png differ
diff --git a/dijit/themes/soria/images/spriteRoundedIconsSmallBl.gif b/dijit/themes/soria/images/spriteRoundedIconsSmallBl.gif
new file mode 100644
index 0000000..6758181
Binary files /dev/null and b/dijit/themes/soria/images/spriteRoundedIconsSmallBl.gif differ
diff --git a/dijit/themes/soria/images/spriteRoundedIconsSmallBl.png b/dijit/themes/soria/images/spriteRoundedIconsSmallBl.png
new file mode 100644
index 0000000..2c9f51a
Binary files /dev/null and b/dijit/themes/soria/images/spriteRoundedIconsSmallBl.png differ
diff --git a/dijit/themes/soria/images/spriteTree.gif b/dijit/themes/soria/images/spriteTree.gif
new file mode 100644
index 0000000..e546e28
Binary files /dev/null and b/dijit/themes/soria/images/spriteTree.gif differ
diff --git a/dijit/themes/soria/images/spriteTree.png b/dijit/themes/soria/images/spriteTree.png
new file mode 100644
index 0000000..33ae07b
Binary files /dev/null and b/dijit/themes/soria/images/spriteTree.png differ
diff --git a/dijit/themes/soria/images/spriteTree_rtl.gif b/dijit/themes/soria/images/spriteTree_rtl.gif
new file mode 100644
index 0000000..bbcc64b
Binary files /dev/null and b/dijit/themes/soria/images/spriteTree_rtl.gif differ
diff --git a/dijit/themes/soria/images/spriteTree_rtl.png b/dijit/themes/soria/images/spriteTree_rtl.png
new file mode 100644
index 0000000..b06afdb
Binary files /dev/null and b/dijit/themes/soria/images/spriteTree_rtl.png differ
diff --git a/dijit/themes/soria/images/tabBottomActiveC.gif b/dijit/themes/soria/images/tabBottomActiveC.gif
new file mode 100644
index 0000000..fb61df9
Binary files /dev/null and b/dijit/themes/soria/images/tabBottomActiveC.gif differ
diff --git a/dijit/themes/soria/images/tabBottomActiveSpriteLR.gif b/dijit/themes/soria/images/tabBottomActiveSpriteLR.gif
new file mode 100644
index 0000000..7c2ed86
Binary files /dev/null and b/dijit/themes/soria/images/tabBottomActiveSpriteLR.gif differ
diff --git a/dijit/themes/soria/images/tabBottomEnabledC.gif b/dijit/themes/soria/images/tabBottomEnabledC.gif
new file mode 100644
index 0000000..0a5f0f8
Binary files /dev/null and b/dijit/themes/soria/images/tabBottomEnabledC.gif differ
diff --git a/dijit/themes/soria/images/tabBottomEnabledSpriteLR.gif b/dijit/themes/soria/images/tabBottomEnabledSpriteLR.gif
new file mode 100644
index 0000000..a77da39
Binary files /dev/null and b/dijit/themes/soria/images/tabBottomEnabledSpriteLR.gif differ
diff --git a/dijit/themes/soria/images/tabBottomHoverC.gif b/dijit/themes/soria/images/tabBottomHoverC.gif
new file mode 100644
index 0000000..47b9da2
Binary files /dev/null and b/dijit/themes/soria/images/tabBottomHoverC.gif differ
diff --git a/dijit/themes/soria/images/tabBottomHoverSpriteLR.gif b/dijit/themes/soria/images/tabBottomHoverSpriteLR.gif
new file mode 100644
index 0000000..59f3edd
Binary files /dev/null and b/dijit/themes/soria/images/tabBottomHoverSpriteLR.gif differ
diff --git a/dijit/themes/soria/images/tabContainerSprite.gif b/dijit/themes/soria/images/tabContainerSprite.gif
new file mode 100644
index 0000000..f0b3842
Binary files /dev/null and b/dijit/themes/soria/images/tabContainerSprite.gif differ
diff --git a/dijit/themes/soria/images/tabLeftChecked.gif b/dijit/themes/soria/images/tabLeftChecked.gif
new file mode 100644
index 0000000..3e7475a
Binary files /dev/null and b/dijit/themes/soria/images/tabLeftChecked.gif differ
diff --git a/dijit/themes/soria/images/tabRightChecked.gif b/dijit/themes/soria/images/tabRightChecked.gif
new file mode 100644
index 0000000..ec4b659
Binary files /dev/null and b/dijit/themes/soria/images/tabRightChecked.gif differ
diff --git a/dijit/themes/soria/images/tabStripe.gif b/dijit/themes/soria/images/tabStripe.gif
new file mode 100644
index 0000000..51a2d40
Binary files /dev/null and b/dijit/themes/soria/images/tabStripe.gif differ
diff --git a/dijit/themes/soria/images/tabStripeBottom.gif b/dijit/themes/soria/images/tabStripeBottom.gif
new file mode 100644
index 0000000..41b1ac0
Binary files /dev/null and b/dijit/themes/soria/images/tabStripeBottom.gif differ
diff --git a/dijit/themes/soria/images/tabStripeLeft.gif b/dijit/themes/soria/images/tabStripeLeft.gif
new file mode 100644
index 0000000..b2214fa
Binary files /dev/null and b/dijit/themes/soria/images/tabStripeLeft.gif differ
diff --git a/dijit/themes/soria/images/tabStripeRight.gif b/dijit/themes/soria/images/tabStripeRight.gif
new file mode 100644
index 0000000..bff3115
Binary files /dev/null and b/dijit/themes/soria/images/tabStripeRight.gif differ
diff --git a/dijit/themes/soria/images/titleBar.png b/dijit/themes/soria/images/titleBar.png
new file mode 100644
index 0000000..cbf98da
Binary files /dev/null and b/dijit/themes/soria/images/titleBar.png differ
diff --git a/dijit/themes/soria/images/titleBarActive.png b/dijit/themes/soria/images/titleBarActive.png
new file mode 100644
index 0000000..92c7431
Binary files /dev/null and b/dijit/themes/soria/images/titleBarActive.png differ
diff --git a/dijit/themes/soria/images/tooltipConnectorDown.gif b/dijit/themes/soria/images/tooltipConnectorDown.gif
new file mode 100644
index 0000000..9c38495
Binary files /dev/null and b/dijit/themes/soria/images/tooltipConnectorDown.gif differ
diff --git a/dijit/themes/soria/images/tooltipConnectorDown.png b/dijit/themes/soria/images/tooltipConnectorDown.png
new file mode 100644
index 0000000..d75af71
Binary files /dev/null and b/dijit/themes/soria/images/tooltipConnectorDown.png differ
diff --git a/dijit/themes/soria/images/tooltipConnectorLeft.gif b/dijit/themes/soria/images/tooltipConnectorLeft.gif
new file mode 100644
index 0000000..fc947e0
Binary files /dev/null and b/dijit/themes/soria/images/tooltipConnectorLeft.gif differ
diff --git a/dijit/themes/soria/images/tooltipConnectorLeft.png b/dijit/themes/soria/images/tooltipConnectorLeft.png
new file mode 100644
index 0000000..f3de66a
Binary files /dev/null and b/dijit/themes/soria/images/tooltipConnectorLeft.png differ
diff --git a/dijit/themes/soria/images/tooltipConnectorRight.gif b/dijit/themes/soria/images/tooltipConnectorRight.gif
new file mode 100644
index 0000000..b0e8097
Binary files /dev/null and b/dijit/themes/soria/images/tooltipConnectorRight.gif differ
diff --git a/dijit/themes/soria/images/tooltipConnectorRight.png b/dijit/themes/soria/images/tooltipConnectorRight.png
new file mode 100644
index 0000000..64190ee
Binary files /dev/null and b/dijit/themes/soria/images/tooltipConnectorRight.png differ
diff --git a/dijit/themes/soria/images/tooltipConnectorUp.gif b/dijit/themes/soria/images/tooltipConnectorUp.gif
new file mode 100644
index 0000000..54bcf65
Binary files /dev/null and b/dijit/themes/soria/images/tooltipConnectorUp.gif differ
diff --git a/dijit/themes/soria/images/tooltipConnectorUp.png b/dijit/themes/soria/images/tooltipConnectorUp.png
new file mode 100644
index 0000000..7f7a5d8
Binary files /dev/null and b/dijit/themes/soria/images/tooltipConnectorUp.png differ
diff --git a/dijit/themes/soria/images/treeExpand_loading.gif b/dijit/themes/soria/images/treeExpand_loading.gif
new file mode 100644
index 0000000..db9ddd0
Binary files /dev/null and b/dijit/themes/soria/images/treeExpand_loading.gif differ
diff --git a/dijit/themes/soria/images/treeHover.png b/dijit/themes/soria/images/treeHover.png
new file mode 100644
index 0000000..cd6d28b
Binary files /dev/null and b/dijit/themes/soria/images/treeHover.png differ
diff --git a/dijit/themes/soria/images/treeI.gif b/dijit/themes/soria/images/treeI.gif
new file mode 100644
index 0000000..6f669e2
Binary files /dev/null and b/dijit/themes/soria/images/treeI.gif differ
diff --git a/dijit/themes/soria/images/treeI_half.gif b/dijit/themes/soria/images/treeI_half.gif
new file mode 100644
index 0000000..e5fd015
Binary files /dev/null and b/dijit/themes/soria/images/treeI_half.gif differ
diff --git a/dijit/themes/soria/images/treeI_half_rtl.gif b/dijit/themes/soria/images/treeI_half_rtl.gif
new file mode 100644
index 0000000..44ad021
Binary files /dev/null and b/dijit/themes/soria/images/treeI_half_rtl.gif differ
diff --git a/dijit/themes/soria/images/treeI_rtl.gif b/dijit/themes/soria/images/treeI_rtl.gif
new file mode 100644
index 0000000..0d32a2f
Binary files /dev/null and b/dijit/themes/soria/images/treeI_rtl.gif differ
diff --git a/dijit/themes/soria/images/validationInputBg.gif b/dijit/themes/soria/images/validationInputBg.gif
new file mode 100644
index 0000000..c28475c
Binary files /dev/null and b/dijit/themes/soria/images/validationInputBg.gif differ
diff --git a/dijit/themes/soria/images/validationInputBg.png b/dijit/themes/soria/images/validationInputBg.png
new file mode 100644
index 0000000..f3039f9
Binary files /dev/null and b/dijit/themes/soria/images/validationInputBg.png differ
diff --git a/dijit/themes/soria/images/warning.png b/dijit/themes/soria/images/warning.png
new file mode 100644
index 0000000..c52f83d
Binary files /dev/null and b/dijit/themes/soria/images/warning.png differ
diff --git a/dijit/themes/soria/layout/AccordionContainer.css b/dijit/themes/soria/layout/AccordionContainer.css
new file mode 100644
index 0000000..24e653d
--- /dev/null
+++ b/dijit/themes/soria/layout/AccordionContainer.css
@@ -0,0 +1,38 @@
+ 
+ 
+.soria .dijitAccordionContainer {
+	border-color: #b1badf;
+	background-color: #fff;
+}
+.soria .dijitAccordionTitle {
+	background:#fafafa url("../images/titleBar.png") repeat-x top left;
+	border-top: 1px solid #b9bbdd;
+	padding: 5px 4px 6px 8px;
+	cursor:pointer;
+	font-size: 0.9em;
+	font-weight: bold;
+	color: #373941;
+}
+.soria .dijitAccordionTitle-selected  {
+	background: #f9f9f9 url("../images/accordionItemActive.png") top repeat-x;
+	font-weight: bold;
+	border-top: 1px solid #b9bbdd;
+	border-bottom: 1px solid #b9bbdd;
+	padding: 5px 4px 5px 8px;
+	cursor: default;	
+	color: #243C5F;
+}
+.soria .dijitAccordionArrow {
+	background:url("../images/spriteRoundedIconsSmallBl.gif") no-repeat -30px top;
+	width:15px;
+	height:15px;
+	margin-top:-1px;
+}
+.soria .dijitAccordionTitle-selected .dijitAccordionArrow {
+	background:url("../images/spriteRoundedIconsSmallBl.gif") no-repeat -15px top;
+	margin-top:-1px;
+}
+.soria .dijitAccordionText {
+	margin-left: 4px;
+	margin-right: 4px;
+}
diff --git a/dijit/themes/soria/layout/AccordionContainer_rtl.css b/dijit/themes/soria/layout/AccordionContainer_rtl.css
new file mode 100644
index 0000000..bc67630
--- /dev/null
+++ b/dijit/themes/soria/layout/AccordionContainer_rtl.css
@@ -0,0 +1,7 @@
+.dijitRtl .soria .dijitAccordionArrow {
+	background-position: 0px top;
+}
+.dijitRtl .soria .dijitAccordionTitle-selected .dijitAccordionArrow {
+	
+	background-position: -15px top;
+}
diff --git a/dijit/themes/soria/layout/BorderContainer.css b/dijit/themes/soria/layout/BorderContainer.css
new file mode 100644
index 0000000..4515041
--- /dev/null
+++ b/dijit/themes/soria/layout/BorderContainer.css
@@ -0,0 +1,59 @@
+
+.soria .dijitBorderContainer {
+	background-color: #e1ebfb;
+	padding: 5px;
+}
+.soria .dijitSplitContainer-child,
+.soria .dijitBorderContainer-child {
+	
+	border: 1px #b1badf solid;
+}
+.soria .dijitBorderContainer-dijitTabContainerTop,
+.soria .dijitBorderContainer-dijitTabContainerBottom,
+.soria .dijitBorderContainer-dijitTabContainerLeft,
+.soria .dijitBorderContainer-dijitTabContainerRight {
+	
+	 border: none;
+}
+.soria .dijitBorderContainer-dijitBorderContainer {
+	
+	border: none;
+	padding: 0px;
+}
+.soria .dijitSplitterH,
+.soria .dijitGutterH {
+	background: #E1EBFB;
+	border:0;
+	border-left:0px solid #d3d3d3;
+	border-right:0px solid #d3d3d3;
+	height:5px;
+}
+.soria .dijitSplitterH .dijitSplitterThumb {
+	background:url("../images/splitContainerSizerH-thumb.png") no-repeat;
+	top:1px;
+	width:19px;
+	height:2px;
+}
+.soria .dijitSplitterV,
+.soria .dijitGutterV {
+	background: #E1EBFB;
+	border:0;
+	border-top:0px solid #d3d3d3;
+	border-bottom:0px solid #d3d3d3;
+	width:5px;
+}
+.soria .dijitSplitterV .dijitSplitterThumb {
+	background:url("../images/splitContainerSizerV-thumb.png") no-repeat;
+	left:1px;
+	height:19px;
+	width:5px;
+}
+.soria .dijitSplitterActive {
+	font-size: 1px;
+	background-image: none;
+	background-color: #aaa;
+	-moz-opacity: 0.6;
+	opacity: 0.6;
+	filter: Alpha(Opacity=60);
+	margin: 0;
+}
diff --git a/dijit/themes/soria/layout/ContentPane.css b/dijit/themes/soria/layout/ContentPane.css
new file mode 100644
index 0000000..9308d50
--- /dev/null
+++ b/dijit/themes/soria/layout/ContentPane.css
@@ -0,0 +1,17 @@
+
+.soria .dijitContentPane {
+    padding: 0px;
+}
+.soria .dijitTabContainerTop-dijitContentPane,
+.soria .dijitTabContainerLeft-dijitContentPane,
+.soria .dijitTabContainerBottom-dijitContentPane,
+.soria .dijitTabContainerRight-dijitContentPane,
+.soria .dijitAccordionContainer-dijitContentPane {
+    background-color: #fff;
+    padding: 5px;
+}
+.soria .dijitSplitContainer-dijitContentPane,
+.soria .dijitBorderContainer-dijitContentPane {
+    background-color: #fff;		
+    padding: 5px;
+}
diff --git a/dijit/themes/soria/layout/SplitContainer.css b/dijit/themes/soria/layout/SplitContainer.css
new file mode 100644
index 0000000..88b0de2
--- /dev/null
+++ b/dijit/themes/soria/layout/SplitContainer.css
@@ -0,0 +1,27 @@
+ 
+.soria .dijitSplitContainerSizerH {
+	background:url("../images/splitContainerSizerV.png") repeat-y #cddef4;
+	border:0;
+	border-left:0px solid #436496;
+	border-right:0px solid #436496;
+	width:5px;
+}
+.soria .dijitSplitContainerSizerH .thumb {
+	background:url("../images/splitContainerSizerV-thumb.png") no-repeat #ccc;
+	left:1px;
+	width:2px;
+	height:19px;
+}
+.soria .dijitSplitContainerSizerV {
+	background:url("../images/splitContainerSizerH.png") repeat-x #cddef4;
+	border:0;
+	border-top:0px solid #436496;
+	border-bottom:0px solid #436496;
+	height:2px;
+}
+.soria .dijitSplitContainerSizerV .thumb {
+	background:url("../images/splitContainerSizerH-thumb.png") no-repeat #ccc;
+	top:1px;
+	width:19px;
+	height:5px;
+}
diff --git a/dijit/themes/soria/layout/TabContainer.css b/dijit/themes/soria/layout/TabContainer.css
new file mode 100644
index 0000000..c3479b2
--- /dev/null
+++ b/dijit/themes/soria/layout/TabContainer.css
@@ -0,0 +1,276 @@
+ 
+ 
+.soria .dijitTabPaneWrapper {
+	background:#fff;
+	border:1px solid #B1BADF;
+	margin: 0;
+	padding-left: 0px;
+}
+.soria .dijitTabInnerDiv {
+	padding:0px 3px 0px 0px;
+	margin: 0 0 0 4px;
+	background: url("../images/tabContainerSprite.gif") no-repeat;
+	background-position: right -400px;
+}
+.soria .dijitTab {
+	line-height:normal;
+	margin:0 2px 0 0;	
+	padding:0px;
+	background: url("../images/tabContainerSprite.gif") no-repeat 0 -300px;
+	color: #243C5F;
+	border-bottom: 1px #B1BADF solid;
+}	
+.soria .dijitTabInnerDiv .dijitTabContent {
+	padding:5px 3px 4px 4px;
+	background: url("../images/tabContainerSprite.gif") repeat-x 0 -350px;
+	position: relative;
+}
+.dijitTabSpacer {
+	font-size: 1px;
+}
+.soria .dijitTabHover {
+	color: #243C5F;
+	background: url("../images/tabContainerSprite.gif") no-repeat 0px -150px;
+}
+.soria .dijitTabHover .dijitTabInnerDiv {
+	background: url("../images/tabContainerSprite.gif") no-repeat right -250px;
+}
+.soria .dijitTabHover .dijitTabInnerDiv .dijitTabContent {
+	background: url("../images/tabContainerSprite.gif") repeat-x 0 -200px;
+}
+.soria .dijitTabChecked,
+.soria .dijitTabCloseButtonChecked
+{
+	
+	background: url("../images/tabContainerSprite.gif") no-repeat 0px -0px;
+}
+.soria .dijitTabChecked .dijitTabInnerDiv {
+	background: url("../images/tabContainerSprite.gif") no-repeat right -100px;
+}
+.soria .dijitTabChecked .dijitTabInnerDiv .dijitTabContent {
+	background: url("../images/tabContainerSprite.gif") repeat-x 0 -50px;
+	color: #243C5F !important;
+}
+.soria .dijitTabContainerTabListNested {
+	background: #F0F4FC;
+	background: #D9E9F9;
+	border: none;
+}
+.soria .dijitTabContainerTabListNested .dijitTab {
+	background: none;
+	border: none;
+	top: 0px;	
+}
+.soria .dijitTabContainerTabListNested .dijitTab .dijitTabInnerDiv,
+.soria .dijitTabContainerTabListNested .dijitTab .dijitTabContent {
+	background: none;
+}
+.soria .dijitTabContainerTabListNested .dijitTabHover .dijitTabContent .tabLabel {
+	text-decoration: underline;
+}
+.soria .dijitTabContainerTabListNested .dijitTabChecked .tabLabel {
+	text-decoration: underline;
+	font-weight: bold;
+}
+.soria .dijitTabContainerSpacerNested .dijitTabSpacer {
+	
+	height: 0px;
+}
+.soria .dijitTabPaneWrapperNested {
+	border: none;	
+}
+.soria .dijitTab .closeImage {
+	width: 15px;
+	height: 15px;
+	background: url("../images/spriteRoundedIconsSmall.png") no-repeat -60px top;
+}
+.dj_ie6 .dijitTab .dijitClosable .closeImage {
+	background: url("../images/spriteRoundedIconsSmall.gif") no-repeat -60px top;
+}
+.soria .dijitTab .closeButton-hover .closeImage {
+	background: url("../images/spriteRoundedIconsSmall.png") no-repeat -60px -15px;
+}
+.dj_ie6 .soria .dijitTab .closeButton-hover .closeImage {
+	background: url("../images/spriteRoundedIconsSmall.gif") no-repeat -60px -15px;
+}
+.soria .dijitTab .dijitTabButtonSpacer {
+	height: 15px;
+	width: 1px;
+}
+.soria .dijitTabContainerTop-tabs {
+	margin-bottom: -1px;
+	border-color: #ccc;
+	padding-left: 3px;
+}
+.soria .dijitTabContainerTop-container {
+	border-top: none;
+}
+.soria .dijitTabContainerTop-tabs .dijitTabChecked {
+	border-bottom-color: #94b4e6;
+}
+.soria .dijitTabContainerTopStrip {
+	border: 1px solid #B1BADF;
+	padding-top: 2px;
+	padding-left: 3px;
+}
+.soria .dijitTabContainerTopStrip {
+	background: #F0F4FC;
+}
+.soria .dijitTabContainerBottom-tabs {
+	margin-top: -1px;
+	border-color: #ccc;
+	padding-left: 3px;
+}
+.soria .dijitTabContainerBottom-container {
+	border-bottom: none;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTab {
+	border-bottom: none;
+	border-top: 1px solid #B1BADF;
+	background: url("../images/tabBottomEnabledSpriteLR.gif") no-repeat bottom left;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTabChecked {
+	border-top-color:#94b4e6;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTabInnerDiv .dijitTabContent {
+	padding-top: 4px;
+	padding-bottom: 5px;
+	background: url("../images/tabBottomEnabledC.gif") repeat-x bottom left;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTabInnerDiv {
+	background: url("../images/tabBottomEnabledSpriteLR.gif") no-repeat bottom right;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTabHover {
+	color: #243C5F;
+	background: url("../images/tabBottomHoverSpriteLR.gif") no-repeat bottom left;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTabHover .dijitTabInnerDiv {
+	background: url("../images/tabBottomHoverSpriteLR.gif") no-repeat bottom right;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTabHover .dijitTabInnerDiv .dijitTabContent {
+	background: url("../images/tabBottomHoverC.gif") repeat-x bottom left;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTabChecked,
+.soria .dijitTabContainerBottom-tabs .dijitTabCloseButtonChecked
+{
+	
+	background: url("../images/tabBottomActiveSpriteLR.gif") no-repeat bottom left;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabInnerDiv {
+	background: url("../images/tabBottomActiveSpriteLR.gif") no-repeat bottom right;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabInnerDiv .dijitTabContent {
+	background: url("../images/tabBottomActiveC.gif") repeat-x bottom left;
+}
+.soria .dijitTabContainerBottomStrip {
+	padding-bottom: 2px;
+	padding-left: 3px;	
+	border: 1px solid #B1BADF;
+}
+.soria .dijitTabContainerBottomStrip {
+	background: #F0F4FC;
+}
+.soria .dijitTabContainerBottom-spacer,
+.soria .dijitTabContainerTop-spacer {
+	height: 2px;
+	border: 1px solid #8ba0bd;
+	background: #94b4e6;
+}
+.soria .dijitTabContainerRight-tabs {
+	margin-left: -1px;
+	border-color: #ccc;
+	padding-top: 3px;
+}
+.soria .dijitTabContainerRight-container {
+	border-right: none;
+}
+.soria .dijitTabContainerRight-tabs .dijitTab {
+	border-bottom: none;
+	border-left: 1px solid #B1BADF;
+	border-bottom: 1px solid #B1BADF !important;
+}
+.dj_ie .soria .dijitTabContainerRight-tabs .dijitTabInnerDiv {
+	border-bottom: solid #fff 1px;
+}
+.soria .dijitTabContainerRight-tabs .dijitTabChecked {
+	border-left-color: #94b4e6;
+}
+.soria .dijitTabContainerRight-tabs .dijitTabChecked {
+	background: url("../images/tabRightChecked.gif") no-repeat left top !important;
+}
+.dj_ie .soria .dijitTabContainerRight-tabs .dijitTabChecked .dijitTabInnerDiv,
+.dj_ie .soria .dijitTabContainerRight-tabs .dijitTabCheckedHover .dijitTabInnerDiv {
+	border-bottom: solid #efefef 1px;
+}
+.soria .dijitTabContainerRight-tabs .dijitTab {
+	background: url("../images/tabContainerSprite.gif") no-repeat left -350px;
+}
+.soria .dijitTabContainerRight-tabs .dijitTabHover .dijitTab {
+	background: url("../images/tabContainerSprite.gif") no-repeat left -200px;
+}
+.soria .dijitTabContainerRightStrip {
+	padding-right: 2px;
+	padding-top: 3px;	
+	border: 1px solid #B1BADF;
+}
+.soria .dijitTabContainerRightStrip {
+	background: #F0F4FC;
+}
+.soria .dijitTabContainerLeft-tabs {
+	margin-right: -1px;
+	border-color: #ccc;
+	padding-top: 3px;
+}
+.soria .dijitTabContainerLeft-container {
+	border-left: none;
+}
+.soria .dijitTabContainerLeft-tabs .dijitTab {
+	border-right: 1px solid #B1BADF;
+	border-bottom: 1px solid #B1BADF;
+}
+.soria .dijitTabContainerLeft-tabs .dijitTabChecked {
+	border-right: 1px solid #94b4e6;
+}
+.soria .dijitTabContainerLeft-tabs .dijitTabInnerDiv {
+	background: url("../images/tabContainerSprite.gif") no-repeat right -350px;
+}
+.soria .dijitTabContainerLeft-tabs .dijitTabHover .dijitTabInnerDiv {
+	background: url("../images/tabContainerSprite.gif") no-repeat right -200px;
+}
+.soria .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabInnerDiv,
+.soria .dijitTabContainerLeft-tabs .dijitTabCheckedHover .dijitTabInnerDiv {
+	background: url("../images/tabLeftChecked.gif") no-repeat right top;
+}
+.dj_ie .soria .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabInnerDiv,
+.dj_ie .soria .dijitTabContainerLeft-tabs .dijitTabCheckedHover .dijitTabInnerDiv {
+	border-bottom: solid #efefef 1px;
+}
+.dj_ie .soria .dijitTabContainerLeft-tabs .dijitTabInnerDiv {
+	border-bottom: solid #fff 1px;
+}
+.soria .dijitTabContainerLeftStrip {
+	padding-left: 2px;
+	padding-top: 3px;	
+	border: 1px solid #B1BADF;
+}
+.soria .dijitTabContainerLeftStrip {
+	background: #F0F4FC;
+}
+.soria .dijitTabContainerLeft-tabs .dijitTab,
+.soria .dijitTabContainerRight-tabs .dijitTab {
+	margin-right:auto;
+	margin-bottom:2px;	
+}
+.soria .dijitTabContainerLeft-spacer,
+.soria .dijitTabContainerRight-spacer {
+	width: 2px;
+	border: 1px solid #8ba0bd;
+	background: #94b4e6;
+}
+.soria .dijitTabContainerTop-dijitContentPane .dijitTabContainerTop-tabs {
+	border-left: 0px solid #ccc;
+	border-top: 0px solid #ccc;
+	border-right: 0px solid #ccc;
+	padding-top: 0px;
+	padding-left: 0px;	
+}
diff --git a/dijit/themes/soria/layout/TabContainer_rtl.css b/dijit/themes/soria/layout/TabContainer_rtl.css
new file mode 100644
index 0000000..3097eab
--- /dev/null
+++ b/dijit/themes/soria/layout/TabContainer_rtl.css
@@ -0,0 +1,37 @@
+.dijitRtl .soria .dijitTab {
+	margin-right:0;
+	margin-left:2px;		
+}
+.dijitRtl .soria .dijitTabContainerTopStrip,
+.dijitRtl .soria .dijitTabContainerBottomStrip {
+	padding-right: 3px;
+	padding-left: 0px;
+}
+.dijitRtl .soria .dijitTabContainerTop-tabs {
+	padding-left: auto;
+	padding-right: 3px;
+}
+.dijitRtl .soria .dijitTabContainerBottom-tabs {
+	padding-left: auto;
+	padding-right: 3px;
+}
+.dijitRtl .soria .dijitTabInnerDiv {
+	padding-left: 3px;
+	padding-right: 4px;
+}
+.dijitRtl .soria .dijitTabPaneWrapper {
+	#zoom: 1;
+}
+.dj_ie-rtl .soria .dijitTabContainerLeft-tabs {
+	margin-left: 0px !important;
+}
+.dj_ie-rtl .soria .dijitTabContainerRight-tabs {
+	margin-right: 0px !important;
+}
+.dijitRtl .soria .dijitTabContainerLeft-tabs .dijitTab,
+.dijitRtl .soria .dijitTabContainerRight-tabs .dijitTab {
+	margin-left:0px;
+}
+.dj_ie-rtl .soria .dijitTab .dijitTabInnerDiv{
+	width : 1%;
+}
diff --git a/dijit/themes/soria/soria.css b/dijit/themes/soria/soria.css
new file mode 100644
index 0000000..771c3af
--- /dev/null
+++ b/dijit/themes/soria/soria.css
@@ -0,0 +1,1487 @@
+
+ at import url("../dijit.css");
+.soria .dojoDndItemBefore {
+	border-top: 2px solid #369;
+}
+.soria .dojoDndItemAfter {
+	border-bottom: 2px solid #369;
+}
+.soria .dojoDndItemOver {
+	cursor:pointer;
+}
+.soria table.dojoDndAvatar { -moz-border-radius: 0; border: 1px solid #ccc; border-collapse: collapse; background-color: #fff; font-size: 75%; color: black;}
+.soria .dojoDndAvatar td	{ border: none; }
+.soria .dojoDndAvatar tr	{ border: none; }
+.soria .dojoDndAvatarHeader td	{ height: 20px; padding: 0 0 0 21px; }
+.soria .dojoDndAvatarItem td { padding: 2px;}
+.soria.dojoDndMove .dojoDndAvatarHeader	{background-color: #f58383; background-image: url(images/dndNoMove.png); background-repeat: no-repeat; background-position: 2px center;}
+.soria.dojoDndCopy .dojoDndAvatarHeader	{background-color: #f58383; background-image: url(images/dndNoCopy.png); background-repeat: no-repeat; background-position: 2px center;}
+.soria.dojoDndMove .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{background-color: #97e68d; background-image: url(images/dndMove.png); background-repeat: no-repeat; background-position: 2px center;}
+.soria.dojoDndCopy .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{background-color: #97e68d; background-image: url(images/dndCopy.png); background-repeat: no-repeat; background-position: 2px center;}
+.soria .dijitContentPane {
+    padding: 0px;
+}
+.soria .dijitTabContainerTop-dijitContentPane,
+.soria .dijitTabContainerLeft-dijitContentPane,
+.soria .dijitTabContainerBottom-dijitContentPane,
+.soria .dijitTabContainerRight-dijitContentPane,
+.soria .dijitAccordionContainer-dijitContentPane {
+    background-color: #fff;
+    padding: 5px;
+}
+.soria .dijitSplitContainer-dijitContentPane,
+.soria .dijitBorderContainer-dijitContentPane {
+    background-color: #fff;		
+    padding: 5px;
+}
+ 
+ 
+.soria .dijitTabPaneWrapper {
+	background:#fff;
+	border:1px solid #B1BADF;
+	margin: 0;
+	padding-left: 0px;
+}
+.soria .dijitTabInnerDiv {
+	padding:0px 3px 0px 0px;
+	margin: 0 0 0 4px;
+	background: url(images/tabContainerSprite.gif) no-repeat;
+	background-position: right -400px;
+}
+.soria .dijitTab {
+	line-height:normal;
+	margin:0 2px 0 0;	
+	padding:0px;
+	background: url(images/tabContainerSprite.gif) no-repeat 0 -300px;
+	color: #243C5F;
+	border-bottom: 1px #B1BADF solid;
+}	
+.soria .dijitTabInnerDiv .dijitTabContent {
+	padding:5px 3px 4px 4px;
+	background: url(images/tabContainerSprite.gif) repeat-x 0 -350px;
+	position: relative;
+}
+.dijitTabSpacer {
+	font-size: 1px;
+}
+.soria .dijitTabHover {
+	color: #243C5F;
+	background: url(images/tabContainerSprite.gif) no-repeat 0px -150px;
+}
+.soria .dijitTabHover .dijitTabInnerDiv {
+	background: url(images/tabContainerSprite.gif) no-repeat right -250px;
+}
+.soria .dijitTabHover .dijitTabInnerDiv .dijitTabContent {
+	background: url(images/tabContainerSprite.gif) repeat-x 0 -200px;
+}
+.soria .dijitTabChecked,
+.soria .dijitTabCloseButtonChecked
+{
+	
+	background: url(images/tabContainerSprite.gif) no-repeat 0px -0px;
+}
+.soria .dijitTabChecked .dijitTabInnerDiv {
+	background: url(images/tabContainerSprite.gif) no-repeat right -100px;
+}
+.soria .dijitTabChecked .dijitTabInnerDiv .dijitTabContent {
+	background: url(images/tabContainerSprite.gif) repeat-x 0 -50px;
+	color: #243C5F !important;
+}
+.soria .dijitTabContainerTabListNested {
+	background: #F0F4FC;
+	background: #D9E9F9;
+	border: none;
+}
+.soria .dijitTabContainerTabListNested .dijitTab {
+	background: none;
+	border: none;
+	top: 0px;	
+}
+.soria .dijitTabContainerTabListNested .dijitTab .dijitTabInnerDiv,
+.soria .dijitTabContainerTabListNested .dijitTab .dijitTabContent {
+	background: none;
+}
+.soria .dijitTabContainerTabListNested .dijitTabHover .dijitTabContent .tabLabel {
+	text-decoration: underline;
+}
+.soria .dijitTabContainerTabListNested .dijitTabChecked .tabLabel {
+	text-decoration: underline;
+	font-weight: bold;
+}
+.soria .dijitTabContainerSpacerNested .dijitTabSpacer {
+	
+	height: 0px;
+}
+.soria .dijitTabPaneWrapperNested {
+	border: none;	
+}
+.soria .dijitTab .closeImage {
+	width: 15px;
+	height: 15px;
+	background: url(images/spriteRoundedIconsSmall.png) no-repeat -60px top;
+}
+.dj_ie6 .dijitTab .dijitClosable .closeImage {
+	background: url(images/spriteRoundedIconsSmall.gif) no-repeat -60px top;
+}
+.soria .dijitTab .closeButton-hover .closeImage {
+	background: url(images/spriteRoundedIconsSmall.png) no-repeat -60px -15px;
+}
+.dj_ie6 .soria .dijitTab .closeButton-hover .closeImage {
+	background: url(images/spriteRoundedIconsSmall.gif) no-repeat -60px -15px;
+}
+.soria .dijitTab .dijitTabButtonSpacer {
+	height: 15px;
+	width: 1px;
+}
+.soria .dijitTabContainerTop-tabs {
+	margin-bottom: -1px;
+	border-color: #ccc;
+	padding-left: 3px;
+}
+.soria .dijitTabContainerTop-container {
+	border-top: none;
+}
+.soria .dijitTabContainerTop-tabs .dijitTabChecked {
+	border-bottom-color: #94b4e6;
+}
+.soria .dijitTabContainerTopStrip {
+	border: 1px solid #B1BADF;
+	padding-top: 2px;
+	padding-left: 3px;
+}
+.soria .dijitTabContainerTopStrip {
+	background: #F0F4FC;
+}
+.soria .dijitTabContainerBottom-tabs {
+	margin-top: -1px;
+	border-color: #ccc;
+	padding-left: 3px;
+}
+.soria .dijitTabContainerBottom-container {
+	border-bottom: none;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTab {
+	border-bottom: none;
+	border-top: 1px solid #B1BADF;
+	background: url(images/tabBottomEnabledSpriteLR.gif) no-repeat bottom left;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTabChecked {
+	border-top-color:#94b4e6;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTabInnerDiv .dijitTabContent {
+	padding-top: 4px;
+	padding-bottom: 5px;
+	background: url(images/tabBottomEnabledC.gif) repeat-x bottom left;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTabInnerDiv {
+	background: url(images/tabBottomEnabledSpriteLR.gif) no-repeat bottom right;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTabHover {
+	color: #243C5F;
+	background: url(images/tabBottomHoverSpriteLR.gif) no-repeat bottom left;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTabHover .dijitTabInnerDiv {
+	background: url(images/tabBottomHoverSpriteLR.gif) no-repeat bottom right;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTabHover .dijitTabInnerDiv .dijitTabContent {
+	background: url(images/tabBottomHoverC.gif) repeat-x bottom left;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTabChecked,
+.soria .dijitTabContainerBottom-tabs .dijitTabCloseButtonChecked
+{
+	
+	background: url(images/tabBottomActiveSpriteLR.gif) no-repeat bottom left;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabInnerDiv {
+	background: url(images/tabBottomActiveSpriteLR.gif) no-repeat bottom right;
+}
+.soria .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabInnerDiv .dijitTabContent {
+	background: url(images/tabBottomActiveC.gif) repeat-x bottom left;
+}
+.soria .dijitTabContainerBottomStrip {
+	padding-bottom: 2px;
+	padding-left: 3px;	
+	border: 1px solid #B1BADF;
+}
+.soria .dijitTabContainerBottomStrip {
+	background: #F0F4FC;
+}
+.soria .dijitTabContainerBottom-spacer,
+.soria .dijitTabContainerTop-spacer {
+	height: 2px;
+	border: 1px solid #8ba0bd;
+	background: #94b4e6;
+}
+.soria .dijitTabContainerRight-tabs {
+	margin-left: -1px;
+	border-color: #ccc;
+	padding-top: 3px;
+}
+.soria .dijitTabContainerRight-container {
+	border-right: none;
+}
+.soria .dijitTabContainerRight-tabs .dijitTab {
+	border-bottom: none;
+	border-left: 1px solid #B1BADF;
+	border-bottom: 1px solid #B1BADF !important;
+}
+.dj_ie .soria .dijitTabContainerRight-tabs .dijitTabInnerDiv {
+	border-bottom: solid #fff 1px;
+}
+.soria .dijitTabContainerRight-tabs .dijitTabChecked {
+	border-left-color: #94b4e6;
+}
+.soria .dijitTabContainerRight-tabs .dijitTabChecked {
+	background: url(images/tabRightChecked.gif) no-repeat left top !important;
+}
+.dj_ie .soria .dijitTabContainerRight-tabs .dijitTabChecked .dijitTabInnerDiv,
+.dj_ie .soria .dijitTabContainerRight-tabs .dijitTabCheckedHover .dijitTabInnerDiv {
+	border-bottom: solid #efefef 1px;
+}
+.soria .dijitTabContainerRight-tabs .dijitTab {
+	background: url(images/tabContainerSprite.gif) no-repeat left -350px;
+}
+.soria .dijitTabContainerRight-tabs .dijitTabHover .dijitTab {
+	background: url(images/tabContainerSprite.gif) no-repeat left -200px;
+}
+.soria .dijitTabContainerRightStrip {
+	padding-right: 2px;
+	padding-top: 3px;	
+	border: 1px solid #B1BADF;
+}
+.soria .dijitTabContainerRightStrip {
+	background: #F0F4FC;
+}
+.soria .dijitTabContainerLeft-tabs {
+	margin-right: -1px;
+	border-color: #ccc;
+	padding-top: 3px;
+}
+.soria .dijitTabContainerLeft-container {
+	border-left: none;
+}
+.soria .dijitTabContainerLeft-tabs .dijitTab {
+	border-right: 1px solid #B1BADF;
+	border-bottom: 1px solid #B1BADF;
+}
+.soria .dijitTabContainerLeft-tabs .dijitTabChecked {
+	border-right: 1px solid #94b4e6;
+}
+.soria .dijitTabContainerLeft-tabs .dijitTabInnerDiv {
+	background: url(images/tabContainerSprite.gif) no-repeat right -350px;
+}
+.soria .dijitTabContainerLeft-tabs .dijitTabHover .dijitTabInnerDiv {
+	background: url(images/tabContainerSprite.gif) no-repeat right -200px;
+}
+.soria .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabInnerDiv,
+.soria .dijitTabContainerLeft-tabs .dijitTabCheckedHover .dijitTabInnerDiv {
+	background: url(images/tabLeftChecked.gif) no-repeat right top;
+}
+.dj_ie .soria .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabInnerDiv,
+.dj_ie .soria .dijitTabContainerLeft-tabs .dijitTabCheckedHover .dijitTabInnerDiv {
+	border-bottom: solid #efefef 1px;
+}
+.dj_ie .soria .dijitTabContainerLeft-tabs .dijitTabInnerDiv {
+	border-bottom: solid #fff 1px;
+}
+.soria .dijitTabContainerLeftStrip {
+	padding-left: 2px;
+	padding-top: 3px;	
+	border: 1px solid #B1BADF;
+}
+.soria .dijitTabContainerLeftStrip {
+	background: #F0F4FC;
+}
+.soria .dijitTabContainerLeft-tabs .dijitTab,
+.soria .dijitTabContainerRight-tabs .dijitTab {
+	margin-right:auto;
+	margin-bottom:2px;	
+}
+.soria .dijitTabContainerLeft-spacer,
+.soria .dijitTabContainerRight-spacer {
+	width: 2px;
+	border: 1px solid #8ba0bd;
+	background: #94b4e6;
+}
+.soria .dijitTabContainerTop-dijitContentPane .dijitTabContainerTop-tabs {
+	border-left: 0px solid #ccc;
+	border-top: 0px solid #ccc;
+	border-right: 0px solid #ccc;
+	padding-top: 0px;
+	padding-left: 0px;	
+}
+ 
+ 
+.soria .dijitAccordionContainer {
+	border-color: #b1badf;
+	background-color: #fff;
+}
+.soria .dijitAccordionTitle {
+	background:#fafafa url(images/titleBar.png) repeat-x top left;
+	border-top: 1px solid #b9bbdd;
+	padding: 5px 4px 6px 8px;
+	cursor:pointer;
+	font-size: 0.9em;
+	font-weight: bold;
+	color: #373941;
+}
+.soria .dijitAccordionTitle-selected  {
+	background: #f9f9f9 url(images/accordionItemActive.png) top repeat-x;
+	font-weight: bold;
+	border-top: 1px solid #b9bbdd;
+	border-bottom: 1px solid #b9bbdd;
+	padding: 5px 4px 5px 8px;
+	cursor: default;	
+	color: #243C5F;
+}
+.soria .dijitAccordionArrow {
+	background:url(images/spriteRoundedIconsSmallBl.gif) no-repeat -30px top;
+	width:15px;
+	height:15px;
+	margin-top:-1px;
+}
+.soria .dijitAccordionTitle-selected .dijitAccordionArrow {
+	background:url(images/spriteRoundedIconsSmallBl.gif) no-repeat -15px top;
+	margin-top:-1px;
+}
+.soria .dijitAccordionText {
+	margin-left: 4px;
+	margin-right: 4px;
+}
+ 
+.soria .dijitSplitContainerSizerH {
+	background:url(images/splitContainerSizerV.png) repeat-y #cddef4;
+	border:0;
+	border-left:0px solid #436496;
+	border-right:0px solid #436496;
+	width:5px;
+}
+.soria .dijitSplitContainerSizerH .thumb {
+	background:url(images/splitContainerSizerV-thumb.png) no-repeat #ccc;
+	left:1px;
+	width:2px;
+	height:19px;
+}
+.soria .dijitSplitContainerSizerV {
+	background:url(images/splitContainerSizerH.png) repeat-x #cddef4;
+	border:0;
+	border-top:0px solid #436496;
+	border-bottom:0px solid #436496;
+	height:2px;
+}
+.soria .dijitSplitContainerSizerV .thumb {
+	background:url(images/splitContainerSizerH-thumb.png) no-repeat #ccc;
+	top:1px;
+	width:19px;
+	height:5px;
+}
+.soria .dijitBorderContainer {
+	background-color: #e1ebfb;
+	padding: 5px;
+}
+.soria .dijitSplitContainer-child,
+.soria .dijitBorderContainer-child {
+	
+	border: 1px #b1badf solid;
+}
+.soria .dijitBorderContainer-dijitTabContainerTop,
+.soria .dijitBorderContainer-dijitTabContainerBottom,
+.soria .dijitBorderContainer-dijitTabContainerLeft,
+.soria .dijitBorderContainer-dijitTabContainerRight {
+	
+	 border: none;
+}
+.soria .dijitBorderContainer-dijitBorderContainer {
+	
+	border: none;
+	padding: 0px;
+}
+.soria .dijitSplitterH,
+.soria .dijitGutterH {
+	background: #E1EBFB;
+	border:0;
+	border-left:0px solid #d3d3d3;
+	border-right:0px solid #d3d3d3;
+	height:5px;
+}
+.soria .dijitSplitterH .dijitSplitterThumb {
+	background:url(images/splitContainerSizerH-thumb.png) no-repeat;
+	top:1px;
+	width:19px;
+	height:2px;
+}
+.soria .dijitSplitterV,
+.soria .dijitGutterV {
+	background: #E1EBFB;
+	border:0;
+	border-top:0px solid #d3d3d3;
+	border-bottom:0px solid #d3d3d3;
+	width:5px;
+}
+.soria .dijitSplitterV .dijitSplitterThumb {
+	background:url(images/splitContainerSizerV-thumb.png) no-repeat;
+	left:1px;
+	height:19px;
+	width:5px;
+}
+.soria .dijitSplitterActive {
+	font-size: 1px;
+	background-image: none;
+	background-color: #aaa;
+	-moz-opacity: 0.6;
+	opacity: 0.6;
+	filter: Alpha(Opacity=60);
+	margin: 0;
+}
+.soria .dijitInputField INPUT,
+.soria .dijitTextBox,
+.soria .dijitComboBox,
+.soria .dijitSpinner {
+	margin: 0em 0.1em;
+}
+.soria .dijitTextBox,
+.soria .dijitComboBox,
+.soria .dijitSpinner,
+.soria .dijitInlineEditor input,
+.soria .dijitTextArea {
+	
+	background:#fff url(images/validationInputBg.png) repeat-x top left;
+	border:1px solid #8ba0bd;
+	line-height: normal;
+}
+.dj_ie6 .soria .dijitTextBox,
+.dj_ie6 .soria .dijitComboBox,
+.dj_ie6 .soria .dijitSpinner,
+.dj_ie6 .soria .dijitInlineEditor input,
+.dj_ie6 .soria .dijitTextArea {
+	background:#fff url(images/validationInputBg.gif) repeat-x top left;
+}
+.soria .dijitTextBoxDisabled,
+.soria .dijitComboBoxDisabled,
+.soria .dijitSpinnerDisabled,
+.soria .dijitTextAreaDisabled {
+	color: gray;
+}
+.dj_webkit .soria .dijitTextBoxDisabled,
+.dj_webkit .soria .dijitComboBoxDisabled,
+.dj_webkit .soria .dijitSpinnerDisabled,
+.dj_webkit .soria .dijitTextareaDisabled {
+	color: #eee;
+}
+.soria .dijitComboBox .dijitButtonNode {
+	padding: 0 0.2em;
+}
+.soria .dijitComboBox .dijitButtonNode,
+.soria .dijitSpinner .dijitButtonNode {
+	
+	border-color: #8ba0bd;
+	border-left: 1px solid #8ba0bd;
+}
+.soria .dijitTextBoxFocused,
+.soria .dijitComboBoxFocused,
+.soria .dijitSpinnerFocused, .soria .dijitSpinnerUpArrowActive, .soria .dijitSpinnerDownArrowActive,
+.soria .dijitTextAreaFocused {
+	
+	border-color:#406b9b;
+}
+.soria .dijitComboBoxFocused .dijitButtonNode,
+.soria .dijitSpinnerFocused .dijitButtonNode,
+.soria .dijitSpinnerUpArrowActive .dijitButtonNode,
+.soria .dijitSpinnerDownArrowActive .dijitButtonNode {
+	border-left-color:#8ba0bd;
+}
+.soria .dijitSpinnerFocused .dijitDownArrowButton,
+.soria .dijitSpinnerUpArrowActive .dijitDownArrowButton,
+.soria .dijitSpinnerDownArrowActive .dijitDownArrowButton {
+	border-top-color:#8ba0bd;
+}
+.soria .dijitError {
+	border-color:#f3d118;
+	background-color:#f9f7ba;
+	background-image:none;
+}
+.dj_ie6 .soria .dijitError INPUT {
+	
+	background-color:#f9f7ba !important;
+}
+.soria .dijitErrorFocused {
+	background-color:#ff6;
+	background-image:none;
+}
+.dj_ie6 .soria .dijitErrorFocused INPUT {
+	
+	background-color:#ff6 !important;
+}
+.soria .dijitValidationIcon {
+	
+	width: 16px;
+	background: transparent url(images/warning.png) no-repeat center center;
+}
+.soria .dijitComboBoxHighlightMatch {
+	background-color:#f9f7ba;
+}
+.soria .dijitButtonNode {
+	
+	
+	border: 1px solid #8ba0bd;
+	border-bottom:1px solid #657c9c;
+	padding: 0.1em 0.2em 0.2em 0.2em; 
+	background: #bcd5f0 url(images/buttonEnabled.png) repeat-x top left;
+}
+.soria .dijitButtonNode button { 
+	border: 0px; 
+	background-color: transparent; 
+} 
+ 
+.soria .dijitButtonText {
+	text-align: center; 
+	padding: 0 0.3em;
+}
+.soria .dijitComboBox .dijitButtonNode {
+	border-width: 0px 0px 0px 1px;
+}
+.soria .dijitArrowButton {
+	color: #111;
+}
+.soria .dijitComboButton .dijitDownArrowButton {
+	padding-right:4px;
+}
+.dj_ff2 .soria .dijitComboButton .dijitButtonContentsFocused,
+.dj_ff2 .soria .dijitComboButton .dijitDownArrowButtonFocused {
+	border: 1px black dotted !important;
+}
+.soria .dijitButtonDisabled .dijitButtonNode,
+.soria .dijitToggleButtonDisabled .dijitButtonNode,
+.soria .dijitDropDownButtonDisabled .dijitButtonNode,
+.soria .dijitComboButtonDisabled .dijitButtonNode,
+.soria .dijitComboBoxDisabled,
+.soria .dijitSpinnerDisabled,
+.soria .dijitSpinnerDisabled .dijitButtonNode {
+	
+	border-color: #b9bbdd #b9bbdd #b9bbdd #b9bbdd;
+	background:#c3d3e5 url(images/buttonDisabled.png) top repeat-x;
+	opacity: 0.60; 
+}
+.soria .dijitButtonHover .dijitButtonNode,
+.soria .dijitButtonNodeHover,
+.soria .dijitToggleButtonHover .dijitButtonNode,
+.soria .dijitDropDownButtonHover .dijitButtonNode,
+.soria .dijitComboButtonHover .dijitButtonContents,
+.soria .dijitComboButtonDownArrowHover .dijitDownArrowButton,
+.soria .dijitComboBoxHover .dijitDownArrowButton,
+.soria .dijitSpinnerUpArrowHover .dijitUpArrowButton,
+.soria .dijitSpinnerDownArrowHover .dijitDownArrowButton {
+	
+	
+	color:#243C5F;
+	background:#acc5e2 url(images/buttonHover.png) repeat-x top left;
+}
+.soria .dijitButtonActive .dijitButtonNode,
+.soria .dijitToggleButtonActive .dijitButtonNode,
+.soria .dijitDropDownButtonActive .dijitButtonNode,
+.soria .dijitComboButtonActive .dijitButtonContents,
+.soria .dijitStackController .dijitToggleButtonChecked .dijitButtonNode {
+	
+	border-color:#657c9c;
+	background: #91b4e5 url(images/buttonActive.png) top left repeat-x;
+}
+.soria .dijitSpinnerUpArrowActive .dijitUpArrowButton,
+.soria .dijitSpinnerDownArrowActive .dijitDownArrowButton,
+.soria .dijitComboBoxActive .dijitDownArrowButton {
+	
+	background: #91b4e5 url(images/buttonActive.png) top left repeat-x;
+}
+.soria .dijitArrowButtonInner {
+	background:url(images/spriteArrows.png) no-repeat left top;
+	width: 11px;
+}
+.soria .dijitUpArrowButton .dijitArrowButtonInner { 
+	background:url(images/spriteArrows.png) no-repeat -22px top; 
+	width: 11px;
+}
+.dj_ie6 .soria .dijitArrowButtonInner {
+	background:url(images/spriteArrows.gif) no-repeat left top;
+	width: 11px;
+}
+.dj_ie6 .soria .dijitUpArrowButton .dijitArrowButtonInner {
+	background:url(images/spriteArrows.gif) no-repeat -22px top;
+	width: 11px;
+}
+.soria .dijitComboBox .dijitArrowButton .dijitArrowButtonInner {
+	background:url(images/spriteArrows.png) no-repeat left center;
+	width: 11px;
+}
+.dj_ie6 .soria .dijitComboBox .dijitArrowButton .dijitArrowButtonInner {
+	background:url(images/spriteArrows.gif) no-repeat left center;
+}
+.soria .dijitComboBoxHover .dijitArrowButtonInner {
+	
+}
+.soria .dijitToggleButton .dijitCheckBox,
+.soria .dijitToggleButton .dijitCheckBoxIcon {
+	background-image: url(images/spriteCheckbox.gif);
+}
+.soria .dijitCheckBox,
+.soria .dijitCheckBoxIcon {		
+	background-image: url(images/spriteCheckbox.gif); 
+	background-repeat: no-repeat;
+	width: 16px;
+	height: 16px;
+	margin: 0;
+	padding: 0;
+}
+.soria .dijitCheckBox,
+.soria .dijitToggleButton .dijitCheckBoxIcon {
+	
+	background-position: -16px;
+}
+.soria .dijitCheckBoxChecked,
+.soria .dijitToggleButtonChecked .dijitCheckBoxIcon {
+	
+	background-position: 0px;
+}
+.soria .dijitCheckBoxDisabled {
+	
+	background-position: -48px;
+}
+.soria .dijitCheckBoxCheckedDisabled {
+	
+	background-position: -32px;
+}
+.soria .dijitCheckBoxHover {
+	
+	background-position: -80px;
+}
+.soria .dijitCheckBoxCheckedHover {
+	
+	background-position: -64px;
+}
+.soria .dijitToggleButton .dijitRadio,
+.soria .dijitToggleButton .dijitRadioIcon {
+	background-image: url(images/spriteRadio.gif);
+}
+.soria .dijitRadio,
+.soria .dijitRadioIcon	{		
+	background-image: url(images/spriteRadio.gif); 
+	background-repeat: no-repeat;
+	width: 16px;
+	height: 16px;
+	margin: 0;
+	padding: 0;
+}
+.soria .dijitRadio,
+.soria .dijitToggleButton .dijitRadioIcon {
+	
+	background-position: -16px;
+}
+.soria .dijitRadioChecked,
+.soria .dijitToggleButtonChecked .dijitRadioIcon {
+	
+	background-position: 0px;
+}
+.soria .dijitRadioDisabled {
+	
+	background-position: -48px;
+}
+.soria .dijitRadioCheckedDisabled {
+	
+	background-position: -32px;
+}
+.soria .dijitRadioHover {
+	
+	background-position: -80px;
+}
+.soria .dijitRadioCheckedHover {
+	
+	background-position: -64px;
+}
+.soria .dijitSliderProgressBarH {
+	border-color: #b1badf;
+	background: #c0c2c5 url(images/sliderFull.png) repeat-x top left;
+}
+.soria .dijitSliderProgressBarV {
+	border-color: #b1badf;
+	background: #c0c2c5 url(images/sliderFullVertical.png) repeat-y bottom left;
+}
+.soria .dijitSliderFocused .dijitSliderProgressBarH,
+.soria .dijitSliderFocused .dijitSliderLeftBumper {
+	background-image:url(images/sliderFullFocus.png);
+}
+.soria .dijitSliderFocused .dijitSliderProgressBarV,
+.soria .dijitSliderFocused .dijitSliderBottomBumper {
+	background-image:url(images/sliderFullVerticalFocus.png);
+}
+.soria .dijitSliderRemainingBarV {
+	border-color: #b4b4b4;
+	background: #dcdcdc url(images/sliderEmptyVertical.png) repeat-y bottom left;
+}
+.soria .dijitSliderRemainingBarH {
+	border-color: #b4b4b4;
+	background: #dcdcdc url(images/sliderEmpty.png) repeat-x top left;
+}
+.soria .dijitSliderBar {
+	border-style: solid;
+	outline:1px;
+	
+}
+.soria .dijitSliderFocused .dijitSliderBar {
+	border-color:#8ba0bd;	
+}
+.dijit_a11y .dijitSliderProgressBar {
+	background-color:#333 !important;
+}
+.soria .dijitSliderImageHandleH {
+	border:0px;
+	width:15px;
+	height:18px;
+	background:url(images/preciseSliderThumb.png) no-repeat center top;
+	cursor:pointer;
+}
+.soria .dijitSliderFocused .dijitSliderImageHandleH {
+	background-image:url(images/preciseSliderThumbFocus.png);
+	#background-image:url(images/preciseSliderThumbFocus.gif);
+}
+.dj_ie6 .soria .dijitSliderImageHandleH {
+	background-image:url(images/preciseSliderThumb.gif);
+}
+.soria .dijitSliderLeftBumper {
+	border-left-width: 1px;
+	border-color: #aab0bb;
+	background: #c0c2c5 url(images/sliderFull.png) repeat-x top left;
+}
+.soria .dijitSliderRightBumper {
+	background: #dcdcdc url(images/sliderEmpty.png) repeat-x top left;
+	border-color: #b4b4b4;
+	border-right-width: 1px;
+}
+.soria .dijitSliderImageHandleV {
+	border:0px;
+	width:20px;
+	height:15px;
+	background:url(images/sliderThumb.png) no-repeat center center;
+	#background:url(images/sliderThumb.gif) no-repeat center center;
+	cursor:pointer;
+}
+.soria .dijitSliderFocused .dijitSliderImageHandleV {
+	background-image:url(images/sliderThumbFocus.png);
+	#background-image:url(images/sliderThumbFocus.gif);
+}
+.soria .dijitSliderBottomBumper {
+	border-bottom-width: 1px;
+	border-color: #aab0bb;
+	background: #c0c2c5 url(images/sliderFullVertical.png) repeat-y bottom left;
+}
+.soria .dijitSliderTopBumper {
+	background: #dcdcdc url(images/sliderEmptyVertical.png) repeat-y top left;
+	border-color: #b4b4b4;
+	border-top-width: 1px;
+}
+.soria .dijitSliderIncrementIconH,
+.soria .dijitSliderIncrementIconV {
+	background:url(images/spriteRoundedIconsSmall.png) no-repeat -45px top;
+	#background:url(images/spriteRoundedIconsSmall.gif) no-repeat -45px top;
+	width:15px; height:15px;
+	cursor:pointer;
+}
+.soria .dijitSliderIncrementIconH {
+	background:url(images/spriteRoundedIconsSmall.png) no-repeat -30px top;
+	#background:url(images/spriteRoundedIconsSmall.gif) no-repeat -30px top;
+}
+.soria .dijitSliderDecrementIconH,
+.soria .dijitSliderDecrementIconV {
+	width:15px;
+	height:15px;
+	cursor:pointer;
+	background:url(images/spriteRoundedIconsSmall.png) no-repeat -15px top;
+	#background:url(images/spriteRoundedIconsSmall.gif) no-repeat -15px top;
+}
+.soria .dijitSliderDecrementIconH { 
+	background:url(images/spriteRoundedIconsSmall.png) no-repeat 0px top;
+	#background:url(images/spriteRoundedIconsSmall.gif) no-repeat 0px top;
+}
+.soria .dijitSliderButtonInner {
+	visibility:hidden;
+}
+.soria .dijitSliderDisabled {
+	opacity:0.6 !important;
+}
+.dj_ie .soria .dijitSliderDisabled,
+.dj_ie .soria .dijitSliderDisabled .dijitRuleContainer,
+.dj_ie .soria .dijitSliderDisabled .dijitSliderRemainingBar,
+.dj_ie .soria .dijitSliderDisabled .dijitSliderProgressBar {
+	filter: gray() alpha(opacity=40);
+}
+.soria .dijitTreeNode {
+    background : url(images/treeI.gif) no-repeat;
+    background-position : top left;
+    background-repeat : repeat-y;
+    zoom: 1;	
+}
+.soria .dijitTreeNodeHover {
+	
+	background-image: url(images/treeHover.png);
+	background-repeat: repeat;
+	background-color: none !important;
+}
+.soria .dijitTreeIsLast {
+    background: url(images/treeI_half.gif) no-repeat;
+}
+.soria .dijitTreeLabel {
+	font-weight: normal;
+	margin-left: 3px;
+}
+.soria .dijitTreeIsRoot {
+    margin-left: 0;
+    background-image: none;
+}
+.soria .dijitTreeExpando {
+    width: 18px;
+    height: 18px;
+}
+.soria .dijitTreeRow {
+	
+	padding-bottom: 2px;
+}
+.soria .dijitTreeContent {
+    min-height: 18px;
+    min-width: 18px;
+    padding-left:1px;
+}
+.soria .dijitTreeExpand {
+    width: 18px;
+    height: 18px;
+    background-repeat : no-repeat;
+}
+.soria .dijitTreeNodeEmphasized {
+    background-color: Highlight;
+    color: HighlightText;
+}
+.soria .dijitTreeLabelFocused {
+	outline: 1px invert dotted;
+}
+.soria .dijitTreeNodeSelected .dijitTreeLabel{
+	background:#b8cbec;
+}
+.soria .dijitTreeExpandoOpened {
+	background: url(images/spriteTree.gif) no-repeat -18px top;
+}
+.soria .dijitTreeExpandoClosed {
+	background-image: url(images/spriteTree.gif);
+}
+.soria .dijitTreeExpandoLeaf {
+	background: url(images/spriteTree.gif) no-repeat -36px top;
+}
+.soria .dijitTreeExpandoLoading {
+	background-image: url(images/treeExpand_loading.gif);
+}
+.soria .dijitTreeIcon {
+	width: 16px;
+	height: 16px;
+}
+.soria .dijitFolderOpened {
+	background: url(images/spriteDivIcons.gif) no-repeat -16px top;
+}
+.soria .dijitFolderClosed {
+	background: url(images/spriteDivIcons.gif) no-repeat top left;
+}
+.soria .dijitLeaf {
+	background: url(images/spriteDivIcons.gif) no-repeat -32px top;
+}
+.soria .dijitTreeNode .dojoDndItemBefore,
+.soria .dijitTreeNode .dojoDndItemAfter {
+	border-bottom: none;
+	border-top: none;
+}
+.soria .dijitTreeNode .dojoDndItemBefore .dijitTreeContent {
+	
+	border-top: 2px solid #369;
+}
+.soria .dijitTreeNode .dojoDndItemAfter .dijitTreeContent {
+	
+	border-bottom: 2px solid #369;
+}
+.soria .dijitProgressBar {
+	margin:2px 0px 2px 0px;
+}
+.soria .dijitProgressBarEmpty{
+	
+	background:#fff url(images/progressBarEmpty.png) repeat-x center center;
+	border-color: #8ba0bd;
+}
+.soria .dijitProgressBarTile{
+	
+	background:#f0f0f0 url(images/progressBarFull.png) repeat-x center center;
+}
+.soria .dijitProgressBarFull {
+	border-right:1px solid #8ba0bd;
+}
+.soria .dijitProgressBarLabel {
+	
+	color:#293a4b;
+}
+.soria .dijitProgressBarIndeterminate .dijitProgressBarTile {
+	
+	background:#cad2de url(images/progressBarAnim.gif) repeat-x center center;
+}
+ 
+ 
+.soria .dijitTitlePaneTitle {
+	background: #cccccc;
+	background:#fff url(images/titleBar.png) repeat-x top left;
+	border:1px solid #bfbfbf;
+	padding:3px 4px;
+	cursor: pointer;
+	font-size: 0.9em;
+	font-weight: bold;
+	color: #6d6d6d;
+}
+.soria .dijitTitlePaneTitle-hover {
+	background: #f9f9f9 url(images/accordionItemActive.png) top repeat-x;
+}
+.soria .dijitTitlePaneTitle * {
+	vertical-align: middle;
+}
+.soria .dijitTitlePane .dijitArrowNode {
+	width:15px;
+	height:15px;
+}
+.soria .dijitTitlePaneFocused .dijitTitlePaneTextNode {
+	color: #243C5F;
+}
+.soria .dijitOpen .dijitTitlePaneTextNode {
+	color: #243C5F;
+}
+.soria .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background: url(images/spriteRoundedIconsSmall.png) no-repeat -30px top;
+}
+.dj_ie6 .soria .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background:url(images/spriteRoundedIconsSmall.gif) no-repeat -30px top;
+}
+.soria .dijitTitlePane .dijitOpen .dijitArrowNode {
+	background:url(images/spriteRoundedIconsSmall.png) no-repeat -15px top;
+}
+.dj_ie6 .soria .dijitTitlePane .dijitOpen .dijitArrowNode {
+	background:url(images/spriteRoundedIconsSmall.gif) no-repeat -15px top;
+}
+.soria .dijitTitlePane .dijitArrowNodeInner {
+	display:none;
+}
+.dijit_a11y .dijitTitlePane .dijitArrowNodeInner {
+	display:inline !important;
+	font-family:monospace;
+	cursor: pointer;
+	padding-bottom:.2em;
+}
+.dijit_a11y .dijitTitlePane .dijitArrowNode {
+	display:none;
+}
+.soria .dijitTitlePaneContentOuter {
+	background: #ffffff;
+	border:1px solid #bfbfbf;
+	border-top: 0px solid #3d3d3d;	
+}
+.soria .dijitTitlePaneContentInner {
+	padding:10px;
+}
+.dj_ie6 .soria .dijitTitlePaneContentOuter,
+.dj_ie6 .soria .dijitTitlePane .dijitTitlePaneTitle {
+	zoom: 1;
+}
+.soria .dijitTitlePaneTextNode {
+	margin-left: 4px;
+	margin-right: 4px;
+}
+	
+.soria .dijitCalendarIncrementControl {
+	
+	width:15px;
+	height:15px;
+	background-image: url(images/spriteRoundedIconsSmall.png);
+	background-repeat: no-repeat;
+}
+.dj_ie6 .soria .dijitCalendarIncrementControl {
+	font-size:.1em;	
+	background-image: url(images/spriteRoundedIconsSmall.gif);
+}
+.soria .dijitA11ySideArrow {
+	display: none;
+}
+.soria .dijitCalendarDecrease {
+	background-position: top left;
+}
+.soria .dijitCalendarIncrease {
+	background-position: -30px top;
+}
+.soria table.dijitCalendarContainer {
+	font-size: 100%;
+	border-spacing: 0;
+	border-collapse: separate;
+	border: 1px solid #b1badf;
+	margin: 0;
+}
+.soria .dijitCalendarMonthContainer th {
+	
+	background:#bed7f0 url(images/titleBar.png) repeat-x top;
+	padding-top:.3em;
+	padding-bottom:.2em;
+	text-align:center;
+}
+.dj_ie6 .soria .dijitCalendarMonthContainer th {
+	padding-top:.2em;
+	padding-bottom:.1em;
+}
+.soria .dijitCalendarDayLabelTemplate {
+	
+	background:#bed7f0;
+	font-weight:normal;
+	padding-top:.15em;
+	padding-bottom:.2em;
+	border-bottom: 1px solid #b1badf;
+	color:#293a4b;
+	text-align:center;
+}
+.soria .dijitCalendarBodyContainer {
+	border-bottom: 1px solid #eeeeee;	
+}
+.soria .dijitCalendarMonthLabel {
+	color:#293a4b;
+	font-weight: bold;
+}
+.soria .dijitCalendarDateTemplate {
+	
+	font-size: 0.9em;
+	font-weight: bold;
+	text-align: center;
+	padding: 0.3em 0.3em 0.05em 0.3em;
+	letter-spacing: 1px;
+	background-color: #fff;
+	border:#fff solid 1px !important;
+}
+.dj_ie .soria .dijitCalendarDateTemplate {
+	padding: 0.1em .33em 0.02em .33em;
+}
+.soria .dijitCalendarPreviousMonth,
+.soria .dijitCalendarNextMonth 		{
+	
+	color:#999999;
+	background-color:#fdfdfd !important;
+	border:#fdfdfd solid 1px !important;
+}
+.soria .dijitCalendarPreviousMonthDisabled,
+.soria .dijitCalendarNextMonthDisabled	{
+	
+	background-color:#a4a5a6 !important;
+}
+.soria .dijitCalendarCurrentMonth {
+	
+}
+.soria .dijitCalendarCurrentMonthDisabled {
+		
+	background-color:#bbbbbc !important;
+}
+.soria .dijitCalendarDisabledDate {
+	
+	
+	text-decoration:line-through !important;
+	cursor:default !important;
+}
+.soria .dijitCalendarCurrentDate {
+	
+	text-decoration:underline;
+	font-weight:bold;
+}
+.soria .dijitCalendarSelectedDate {
+	
+	background-color:#b9cbf1 !important;
+	color:black !important;
+	border:#4b5aaa solid 1px !important;
+}
+.soria .dijitCalendarYearContainer {
+	
+	background:white url(images/titleBar.png) repeat-x top;
+}
+.soria .dijitCalendarYearLabel {
+	
+	margin:0;
+	padding:0.4em 0 0.25em 0;
+	text-align:center;
+}
+.soria .dijitCalendarSelectedYear {
+	
+	color:black;
+	padding:0.2em;
+	padding-bottom:0.1em;
+	background-color:#b9cbf1 !important;
+	border:#4b5aaa solid 1px !important;
+}
+.soria .dijitCalendarNextYear,
+.soria .dijitCalendarPreviousYear {
+	
+	color:black !important;
+	font-weight:normal;
+}
+.soria .dijitTimePickerTick,
+.soria .dijitTimePickerMarker {
+	border-color: #b1badf;
+}
+.soria .dijitTimePickerTick {
+	color:white;
+}
+.soria .dijitTimePickerMarker {
+	background:#bed7f0 url(images/titleBar.png) repeat-x top;
+	color:#293a4b;
+	font-weight: bold;
+}
+.soria .dijitTimePickerItemSelected {
+	color: black;
+	background: #b9cbf1 none;
+}
+.soria .dijitTimePickerItemHover {
+	background: #60a1ea none;
+	color:white;
+}
+.soria .dijitTimePickerItemHover,
+.soria .dijitTimePickerItemSelected {
+	position: relative;
+	z-index: 10;
+}
+.soria .dijitTimePickerTick .dijitTimePickerItemInner {
+	font-size:0.4em;
+}
+.soria .dijitTimePickerItemHover .dijitTimePickerItemInner,
+.soria .dijitTimePickerItemSelected .dijitTimePickerItemInner {
+	font-size:1em;
+}
+.soria .dijitTimePickerMarkerHover {
+	border-top: 1px solid #94b9ef;
+}
+.soria .dijitTimePickerTickHover,
+.soria .dijitTimePickerTickSelected {
+	margin-top:-0.3em;
+	margin-bottom:-0.3em;
+	border-bottom: none;
+}
+.dijit_a11y .dijitTimePickerTickHover {
+	background-color: #CCC !important;
+	border-top: 1px solid #333 !important;
+	border-bottom: 1px solid #333 !important;
+}
+.dijit_a11y .dijitTimePickerMarkerHover {
+	border-bottom-width: 2px;
+}
+.soria .dijitToolbar {
+	border-bottom: 1px solid #ccc;
+	background:#eaeaea url(images/titleBar.png) repeat-x top left;
+}
+.dj_ie6 .soria .dijitToolbar {
+	height: 10px;
+}
+.soria .dijitToolbar .dijitButtonNode,
+.soria .dijitToolbar .dijitComboButton .dijitButtonContents,
+.soria .dijitToolbar .dijitComboButton .dijitDownArrowButton {
+	background: none;
+	margin: 0px;
+	padding: 0px;
+	border: none;
+	font-size: 12px;
+}
+.soria .dijitToolbar .dijitButton,
+.soria .dijitToolbar .dijitToggleButton,
+.soria .dijitToolbar .dijitDropDownButton,
+.soria .dijitToolbar .dijitComboButton .dijitButtonContents,
+.soria .dijitToolbar .dijitComboButton .dijitDownArrowButton {
+	background: none;
+	padding: 1px;	
+}
+.soria .dijitToolbar .dijitButtonChecked,
+.soria .dijitToolbar .dijitToggleButtonChecked {
+	background-color:#d8e5f8;
+	border:1px solid #316ac5;
+	padding: 0px;
+}
+.soria .dijitToolbar .dijitButtonCheckedHover,
+.soria .dijitToolbar .dijitToggleButtonCheckedHover
+ {
+	background-color:#9abbea;
+	border:1px solid #316ac5;
+	padding: 0px;
+}
+.soria .dijitToolbar .dijitButtonHover,
+.soria .dijitToolbar .dijitToggleButtonHover,
+.soria .dijitToolbar .dijitDropDownButtonHover,
+.soria .dijitToolbar .dijitComboButtonHover .dijitButtonContents,
+.soria .dijitToolbar .dijitComboButtonDownArrowHover .dijitDownArrowButton {
+	
+	border: 1px solid #316ac5;
+	padding: 0px;
+	background-color:#9abbea;
+}
+.soria .dijitToolbar label {	
+	padding: 3px 3px 0 6px;
+}
+.dj_ie .soria .dijitToolbar .dijitComboButton .dijitButtonContentsFocused,
+.dj_ie .soria .dijitToolbar .dijitComboButton .dijitDownArrowButtonFocused,
+.dj_ff2 .soria.dijitToolbar .dijitComboButton .dijitButtonContentsFocused,
+.dj_ff2 .soria .dijitToolbar .dijitComboButton .dijitDownArrowButtonFocused {
+	
+	border: 1px #777 dotted !important;
+	padding: 0px;
+}
+.soria .dijitDialog {
+	background: #eee;
+	border: 1px solid #cbcbcb;
+	-webkit-box-shadow: 0px 5px 10px #adadad;
+	padding: 0px;
+}
+.soria .dijitDialog .dijitDialogTitle {
+	
+	font-weight: bold;
+	padding: 0px 4px;
+	font-size: 0.9em;
+	color: #3243C5F;
+}
+.soria .dijitDialog .dijitDialogPaneContent {
+	background: #ffffff;
+	border:none;
+	border-top: 1px solid #b1badf; 
+	padding:10px;
+}
+.soria .dijitDialogTitleBar {
+	
+	background: #fafafa url(images/titleBar.png) repeat-x top left;
+	padding: 5px 6px 3px 6px;
+	cursor: move;
+	outline:0; 
+}
+.soria .dijitDialogCloseIcon {
+	
+	background-image: url(images/spriteRoundedIconsSmallBl.png);
+	background-repeat: no-repeat;
+	background-position: -60px 0px;
+	position: absolute;
+	vertical-align: middle;
+	right: 6px;
+	top: 4px;
+	height: 15px;
+	width: 15px;
+	cursor: pointer;
+}
+.dj_ie6 .soria .dijitDialogCloseIcon {
+	background-image: url(images/spriteRoundedIconsSmallBl.gif);
+}
+.soria .dijitDialogCloseIcon-hover {
+	background-position: -60px -15px;
+}
+.soria .dijitTooltip,
+.soria .dijitTooltipDialog {
+	
+	background: transparent;	
+}
+.dijitTooltipBelow {
+	
+	padding-top: 10px;
+}
+.dijitTooltipAbove {
+	
+	padding-bottom: 10px;
+}
+.soria .dijitTooltipContainer {
+	
+	background-color: #fff;
+	border:1px solid #cbcbcb;
+	padding:0.45em;
+}
+.soria .dijitTooltipConnector {
+	
+	border:0px;
+	z-index: 2;
+}
+.soria .dijitTooltipABRight .dijitTooltipConnector {
+	
+	left: auto !important;
+	right: 6px;
+}
+.soria .dijitTooltipBelow .dijitTooltipConnector {
+	
+	top: 0px;
+	left: 6px;
+	background:url(images/tooltipConnectorUp.png) no-repeat top left;
+	width:17px;
+	height:11px;
+}
+.dj_ie6 .soria .dijitTooltipBelow .dijitTooltipConnector {
+	background-image: url(images/tooltipConnectorUp.gif);
+}
+.soria .dijitTooltipAbove .dijitTooltipConnector {
+	
+	bottom: 0px;
+	left: 6px;
+	background:url(images/tooltipConnectorDown.png) no-repeat top left;
+	width:17px;
+	height:11px;
+}
+.dj_ie6 .soria .dijitTooltipAbove .dijitTooltipConnector {
+	background-image: url(images/tooltipConnectorDown.gif);
+}
+.dj_ie6 .soria .dijitTooltipAbove .dijitTooltipConnector {
+	background-image: url(images/tooltipConnectorDown.gif);
+	bottom: -5px;
+}
+.soria .dijitTooltipLeft {
+	padding-right: 10px;
+}
+.dj_ie6 .soria .dijitTooltipLeft {
+	padding-left: 11px;
+}
+.soria .dijitTooltipLeft .dijitTooltipConnector {
+	
+	right: 0px;
+	bottom: 3px;
+	background:url(images/tooltipConnectorRight.png) no-repeat top left;
+	width:11px;
+	height:17px;
+}
+.dj_ie6 .soria .dijitTooltipLeft .dijitTooltipConnector {
+	background-image: url(images/tooltipConnectorRight.gif);
+}
+.soria .dijitTooltipRight {
+	padding-left: 10px;
+}
+.soria .dijitTooltipRight .dijitTooltipConnector {
+	
+	left: 0px;
+	bottom: 3px;
+	background:url(images/tooltipConnectorLeft.png) no-repeat top left;
+	width:11px;
+	height:17px;
+}
+.dj_ie6 .soria .dijitTooltipRight .dijitTooltipConnector {
+	background-image: url(images/tooltipConnectorLeft.gif);
+}
+.soria .dijitMenu,
+.soria .dijitMenuBar {
+	border: 1px solid #cbcbcb;
+	margin: 0px;
+	padding: 0px;
+	background-color: #fff;
+}
+.soria .dijitBorderContainer .dijitMenuBar {
+	border:1px solid #B1BADF;
+}
+.soria .dijitMenuItem {
+	font-family: sans-serif;
+	margin: 0px;
+	color: #243C5F;
+}
+.soria .dijitMenuBar .dijitMenuItem {
+	padding: 4px 5px;
+}
+.soria .dijitMenuPreviousButton, .soria .dijitMenuNextButton {
+	font-style: italic;
+}
+.soria .dijitMenuItem TD {
+	padding:1px;
+}
+.soria .dijitMenuPassive .dijitMenuItemHover,
+.soria .dijitMenuItemSelected {
+	background-color: #d9e6f9; 
+	color: #243C5F;
+}
+.soria .dijitMenuItemIcon {
+	width: 15px;
+	height: 15px;
+}
+.soria .dijitMenuExpand {
+	width:15px;
+	height:15px;
+	background-image: url(images/spriteRoundedIconsSmall.png);
+	background-position: -30px top;
+}
+.dj_ie6 .soria .dijitMenuExpand {
+	background-image: url(images/spriteRoundedIconsSmall.gif);
+}
+.soria .dijitMenuSeparator {
+	height: 1px;
+}
+.soria .dijitMenuSeparatorTop {
+	border-bottom: 1px solid #fff; 
+}
+.soria .dijitMenuSeparatorBottom {
+	border-top: 1px solid #8ba0bd;
+}
+.soria .dijitCheckedMenuItemIconChar {
+	display: none;
+}
+.soria .dijitCheckedMenuItemIcon {
+	background-image: url(images/spriteCheckbox.gif);
+	background-position: -80px;
+}
+.soria .dijitCheckedMenuItemChecked .dijitCheckedMenuItemIcon {
+	background-position: -64px;
+}
+.dijitIEFixedToolbar {
+	position:absolute;
+	
+	top: expression(eval((document.documentElement||document.body).scrollTop));
+}
+.soria .dijitToolbar .dijitToolbarSeparator {
+	background: url(images/editor.gif);
+}
+.soria .dijitEditorIcon {
+	background-image: url(images/editor.gif); 
+	background-repeat: no-repeat;
+	width: 18px;
+	height: 18px;
+	text-align: center;
+}
+.soria .dijitDisabled .dijitEditorIcon {
+	background-image: url(images/editorDisabled.gif); 
+}
+.soria .dijitEditorIconSep { background-position: 0px; }
+.soria .dijitEditorIconBackColor { background-position: -18px; }
+.soria .dijitEditorIconBold { background-position: -36px; }
+.soria .dijitEditorIconCancel { background-position: -54px; }
+.soria .dijitEditorIconCopy { background-position: -72px; }
+.soria .dijitEditorIconCreateLink { background-position: -90px; }
+.soria .dijitEditorIconCut { background-position: -108px; }
+.soria .dijitEditorIconDelete { background-position: -126px; }
+.soria .dijitEditorIconForeColor { background-position: -144px; }
+.soria .dijitEditorIconHiliteColor { background-position: -162px; }
+.soria .dijitEditorIconIndent { background-position: -180px; }
+.soria .dijitEditorIconInsertHorizontalRule { background-position: -198px; }
+.soria .dijitEditorIconInsertImage { background-position: -216px; }
+.soria .dijitEditorIconInsertOrderedList { background-position: -234px; }
+.soria .dijitEditorIconInsertTable { background-position: -252px; }
+.soria .dijitEditorIconInsertUnorderedList { background-position: -270px; }
+.soria .dijitEditorIconItalic { background-position: -288px; }
+.soria .dijitEditorIconJustifyCenter { background-position: -306px; }
+.soria .dijitEditorIconJustifyFull { background-position: -324px; }
+.soria .dijitEditorIconJustifyLeft { background-position: -342px; }
+.soria .dijitEditorIconJustifyRight { background-position: -360px; }
+.soria .dijitEditorIconLeftToRight { background-position: -378px; }
+.soria .dijitEditorIconListBulletIndent { background-position: -396px; }
+.soria .dijitEditorIconListBulletOutdent { background-position: -414px; }
+.soria .dijitEditorIconListNumIndent { background-position: -432px; }
+.soria .dijitEditorIconListNumOutdent { background-position: -450px; }
+.soria .dijitEditorIconOutdent { background-position: -468px; }
+.soria .dijitEditorIconPaste { background-position: -486px; }
+.soria .dijitEditorIconRedo { background-position: -504px; }
+.soria .dijitEditorIconRemoveFormat { background-position: -522px; }
+.soria .dijitEditorIconRightToLeft { background-position: -540px; }
+.soria .dijitEditorIconSave { background-position: -558px; }
+.soria .dijitEditorIconSpace { background-position: -576px; }
+.soria .dijitEditorIconStrikethrough { background-position: -594px; }
+.soria .dijitEditorIconSubscript { background-position: -612px; }
+.soria .dijitEditorIconSuperscript { background-position: -630px; }
+.soria .dijitEditorIconUnderline { background-position: -648px; }
+.soria .dijitEditorIconUndo { background-position: -666px; }
+.soria .dijitEditorIconWikiword { background-position: -684px; }
+.soria .dijitEditorIconToggleDir { background-position: -540px; }
+.soria .dijitEditorIconTabIndent { background-position: -702px; }
+.soria .dijitEditorIconSelectAll { background-position: -720px; }
+.soria .dijitEditorIconUnlink { background-position: -738px; }
+.dijitColorPalette {
+	border:1px solid #cbcbcb;
+	background:#fff;
+	-moz-border-radius: 0px !important;
+}
diff --git a/dijit/themes/soria/soria_rtl.css b/dijit/themes/soria/soria_rtl.css
new file mode 100644
index 0000000..0189c42
--- /dev/null
+++ b/dijit/themes/soria/soria_rtl.css
@@ -0,0 +1,207 @@
+
+.dj_gecko-rtl .dijitInputField {
+	direction: ltr; 
+}
+.dj_gecko-rtl .dijitInputField * {
+	direction: rtl; 
+}
+.dijitRtl .dijitMenuItem {
+	text-align: right;
+}
+.dijitRtl .dijitComboBox .dijitInputField {
+	border-right-width:1px !important;
+	border-left-width:0 !important;
+}
+.dijitRtl .dijitCalendarNextYear {
+	margin:0 0.55em 0 0;
+}
+.dijitRtl .dijitCalendarPreviousYear {
+	margin:0 0 0 0.55em;
+}
+.dijitRtl .dijitProgressBarFull .dijitProgressBarLabel {
+	right:0; 
+}
+.dijitRtl .dijitSliderImageHandleV {
+	left:auto;
+	right:-6px;
+}
+.dj_ie-rtl .dijitSliderImageHandleV {
+	right:-10px;
+}
+.dijitRtl .dijitSliderMoveableH {
+	right:auto;
+	left:0;
+}
+.dijitRtl .dijitRuleContainerV {
+	float:right;
+}
+.dj_gecko-rtl .dijitRuleContainerV {
+	float:left;
+}
+.dj_ie-rtl .dijitRuleContainerV {
+	text-align:right;
+}
+.dj_ie-rtl .dijitRuleLabelV {
+	text-align:left;
+}
+.dj_ie-rtl .dijitRuleLabelH {
+	zoom:1;
+}
+.dj_ie-rtl .dijitSliderProgressBarH {
+	right:0;
+	left:auto;
+}
+.dj_gecko-rtl .dijitSliderProgressBarH {
+	float:right;
+	right:0;
+	left:auto;
+}
+.dijitRtl .dijitSpinner .dijitInputLayoutContainer .dijitArrowButton {
+	right: auto;
+	left: 0;
+	border-width: 0 1px 0 0 !important;
+}
+.dijitRtl .dijitSpinnerButtonContainer {
+	float: left;
+}
+.dijitRtl .dijit_a11y .dijitSpinnerButtonContainer {
+	margin-left: none;
+	margin-right: 2px;
+}
+.dijitRtl DIV.dijitArrowButton, .dijitRtl .dijitValidationIcon, .dijitRtl .dijitValidationIconText {
+	float: left;
+}
+.dijitRtl .dijitContentPaneLoading, .dijitRtl .dijitContentPaneError {
+	background-position:right;
+	padding-right:25px;
+}
+.dijitRtl .soria .dijitTab {
+	margin-right:0;
+	margin-left:2px;		
+}
+.dijitRtl .soria .dijitTabContainerTopStrip,
+.dijitRtl .soria .dijitTabContainerBottomStrip {
+	padding-right: 3px;
+	padding-left: 0px;
+}
+.dijitRtl .soria .dijitTabContainerTop-tabs {
+	padding-left: auto;
+	padding-right: 3px;
+}
+.dijitRtl .soria .dijitTabContainerBottom-tabs {
+	padding-left: auto;
+	padding-right: 3px;
+}
+.dijitRtl .soria .dijitTabInnerDiv {
+	padding-left: 3px;
+	padding-right: 4px;
+}
+.dijitRtl .soria .dijitTabPaneWrapper {
+	#zoom: 1;
+}
+.dj_ie-rtl .soria .dijitTabContainerLeft-tabs {
+	margin-left: 0px !important;
+}
+.dj_ie-rtl .soria .dijitTabContainerRight-tabs {
+	margin-right: 0px !important;
+}
+.dijitRtl .soria .dijitTabContainerLeft-tabs .dijitTab,
+.dijitRtl .soria .dijitTabContainerRight-tabs .dijitTab {
+	margin-left:0px;
+}
+.dj_ie-rtl .soria .dijitTab .dijitTabInnerDiv{
+	width : 1%;
+}
+.dijitRtl .soria .dijitAccordionArrow {
+	background-position: 0px top;
+}
+.dijitRtl .soria .dijitAccordionTitle-selected .dijitAccordionArrow {
+	
+	background-position: -15px top;
+}
+.dijitRtl .soria .dijitSliderProgressBarH,
+.dijitRtl .soria .dijitSliderRemainingBarH,
+.dijitRtl .soria .dijitSliderLeftBumper,
+.dijitRtl .soria .dijitSliderRightBumper,
+.dijitRtl .soria .dijitSliderTopBumper {
+	background-position: top right;
+}
+.dijitRtl .soria .dijitSliderProgressBarV,
+.dijitRtl .soria .dijitSliderRemainingBarV,
+.dijitRtl .soria .dijitSliderBottomBumper {
+	background-position: bottom right;
+}
+.dijitRtl .soria .dijitSliderLeftBumper {
+	border-left-width: 0px;
+	border-right-width: 1px;
+}
+.dijitRtl .soria .dijitSliderRightBumper {
+	border-left-width: 1px;
+	border-right-width: 0px;
+}
+.dijitRtl .soria .dijitSliderIncrementIconH {
+	background:url(images/spriteRoundedIconsSmall.png) no-repeat left top;
+	#background:url(images/spriteRoundedIconsSmall.gif) no-repeat left top;
+}
+.dijitRtl .soria .dijitSliderDecrementIconH {
+	background:url(images/spriteRoundedIconsSmall.png) no-repeat -30px top;
+	#background:url(images/spriteRoundedIconsSmall.gif) no-repeat -30px top;
+}
+.dijitRtl .soria .dijitComboBox .dijitButtonNode {
+	border-width: 0px 0px 0px 1px;
+}
+.dijitRtl .soria .dijitComboBox .dijitButtonNode,
+.dijitRtl .soria .dijitSpinner .dijitButtonNode {
+	
+	border-color: #8ba0bd;
+	border-left: 0px solid #8ba0bd;
+	border-right: 1px solid #8ba0bd;
+}
+.dijitRtl .soria .dijitTreeContainer .dijitTreeNode {
+    background-image : none;
+}
+.dijitRtl .soria .dijitTreeContainer .dijitTreeContent {
+    padding-left: auto;
+    padding-right: 1px;   
+}
+.dijitRtl .soria .dijitTreeContainer .dijitTreeExpandoOpened {
+	background: url(images/spriteTree_rtl.gif) no-repeat -18px top;
+}
+.dijitRtl .soria .dijitTreeContainer .dijitTreeExpandoClosed {
+	background-image: url(images/spriteTree_rtl.gif);
+}
+.dijitRtl .soria .dijitTreeContainer .dijitTreeExpandoLeaf {
+	background: none;
+}
+.dijitRtl .soria .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background-position: 0px top;
+}
+.dj_ie6-rtl .soria .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background-position: 0px top;
+}
+.dijitRtl .soria .dijitCalendarDecrease {
+	background-position: -30px top;
+}
+.dijitRtl .soria .dijitCalendarIncrease {
+	background-position: 0px top;
+}
+.dijitRtl .soria .dijitDialogTitleBar .dijitDialogCloseIcon {
+	right: auto;
+	left: 5px;
+}
+.dijitRtl .soria .dijitMenuItem .dijitMenuItemIcon {
+	padding-left: 3px;
+	padding-right: 0px;
+}
+.dijitRtl .soria .dijitMenuItem .dijitMenuExpand {
+	background-position: left top;
+}
+.dijitRtl .soria .dijitEditorIcon {
+	background-image: url(images/editor_rtl.gif); 
+}
+.dijitRtl .soria .dijitDisabled .dijitEditorIcon {
+	background-image: url(images/editorDisabled_rtl.gif); 
+}
+.dijitRtl .soria .dijitToolbar .dijitToolbarSeparator {
+	background-image: url(images/editor_rtl.gif);
+}
diff --git a/dijit/themes/tundra/Calendar.css b/dijit/themes/tundra/Calendar.css
new file mode 100644
index 0000000..443aa43
--- /dev/null
+++ b/dijit/themes/tundra/Calendar.css
@@ -0,0 +1,128 @@
+
+	
+.tundra .dijitCalendarIncrementControl {
+	
+	width:15px;
+	height:15px;
+	background-image: url("images/spriteRoundedIconsSmall.png");
+	background-repeat: no-repeat
+}
+.dj_ie6 .tundra .dijitCalendarIncrementControl {
+	font-size:.1em;
+	background-image: url("images/spriteRoundedIconsSmall.gif");
+}
+.tundra .dijitA11ySideArrow {
+	display: none;
+}
+.tundra .dijitCalendarDecrease {
+	background-position: top left;
+}
+.tundra .dijitCalendarIncrease {
+	background-position: -30px top;
+}
+.tundra table.dijitCalendarContainer {
+	font-size: 100%;
+	border-spacing: 0;
+	border-collapse: separate;
+	border: 1px solid #ccc;
+	margin: 0;
+}
+.tundra .dijitCalendarMonthContainer th {
+	
+	background:#d3d3d3 url("images/titleBar.png") repeat-x top;
+	padding-top:.3em;
+	padding-bottom:.2em;
+	text-align:center;
+}
+.dj_ie6 .tundra .dijitCalendarMonthContainer th {
+	padding-top:.2em;
+	padding-bottom:.1em;
+}
+.tundra .dijitCalendarDayLabelTemplate {
+	
+	background:white url("images/calendarDayLabel.png") repeat-x bottom;
+	font-weight:normal;
+	padding-top:.15em;
+	padding-bottom:0em;
+	border-top: 1px solid #eeeeee;
+	color:#293a4b;
+	text-align:center;
+}
+.tundra .dijitCalendarBodyContainer {
+	border-bottom: 1px solid #eeeeee;	
+}
+.tundra .dijitCalendarMonthLabel {
+	color:#293a4b;
+	font-weight: bold;
+}
+.tundra .dijitCalendarDateTemplate {
+	
+	font-size: 0.9em;
+	font-weight: bold;
+	text-align: center;
+	padding: 0.3em 0.3em 0.05em 0.3em;
+	letter-spacing: 1px;
+}
+.dj_ie .tundra .dijitCalendarDateTemplate {
+	padding: 0.1em .33em 0.02em .33em;
+}
+.tundra .dijitCalendarPreviousMonth,
+.tundra .dijitCalendarNextMonth 		{
+	
+	color:#999999;
+	background-color:#f8f8f8 !important;
+}
+.tundra .dijitCalendarPreviousMonthDisabled,
+.tundra .dijitCalendarNextMonthDisabled	{
+	
+	background-color:#a4a5a6 !important;
+}
+.tundra .dijitCalendarCurrentMonth {
+	
+	background-color:white !important;
+}
+.tundra .dijitCalendarCurrentMonthDisabled {
+		
+	background-color:#bbbbbc !important;
+}
+.tundra .dijitCalendarDisabledDate {
+	cursor:default !important;
+	text-decoration:line-through !important;
+}
+.tundra .dijitCalendarCurrentDate {
+	
+	text-decoration:underline;
+	font-weight:bold;
+}
+.tundra .dijitCalendarHoveredDate {
+	background-color: #e2ebf2 !important;
+}
+.tundra .dijitCalendarSelectedDate {
+	
+	background-color:#bbc4d0 !important;
+	color:black !important;
+}
+.tundra .dijitCalendarYearContainer {
+	
+	background:white url("images/calendarYearLabel.png") repeat-x bottom;
+	border-top:1px solid #ccc;
+}
+.tundra .dijitCalendarYearLabel {
+	
+	margin:0;
+	padding:0.4em 0 0.25em 0;
+	text-align:center;
+}
+.tundra .dijitCalendarSelectedYear {
+	
+	color:black;
+	padding:0.2em;
+	padding-bottom:0.1em;
+	background-color:#bbc4d0 !important;
+}
+.tundra .dijitCalendarNextYear,
+.tundra .dijitCalendarPreviousYear {
+	
+	color:black !important;
+	font-weight:normal;
+}
diff --git a/dijit/themes/tundra/Calendar_rtl.css b/dijit/themes/tundra/Calendar_rtl.css
new file mode 100644
index 0000000..4baf371
--- /dev/null
+++ b/dijit/themes/tundra/Calendar_rtl.css
@@ -0,0 +1,7 @@
+
+.dijitRtl .tundra .dijitCalendarDecrease {
+	background-position: -30px top;
+}
+.dijitRtl .tundra .dijitCalendarIncrease {
+	background-position: 0px top;
+}
diff --git a/dijit/themes/tundra/ColorPalette.css b/dijit/themes/tundra/ColorPalette.css
new file mode 100644
index 0000000..56fa558
--- /dev/null
+++ b/dijit/themes/tundra/ColorPalette.css
@@ -0,0 +1,5 @@
+.dijitColorPalette {
+	border:1px solid #7eabcd;
+	background:#fff;
+	-moz-border-radius: 0px !important;
+}
diff --git a/dijit/themes/tundra/Common.css b/dijit/themes/tundra/Common.css
new file mode 100644
index 0000000..b7f8ace
--- /dev/null
+++ b/dijit/themes/tundra/Common.css
@@ -0,0 +1,27 @@
+
+.tundra .dojoDndItemBefore {
+	border-top: 2px solid #369;
+}
+.tundra .dojoDndItemAfter {
+	border-bottom: 2px solid #369;
+}
+.tundra .dojoDndItemOver {
+	cursor:pointer;
+}
+.tundra table.dojoDndAvatar { -moz-border-radius: 0; border: 1px solid #ccc; border-collapse: collapse; background-color: #fff; font-size: 75%; color: black;}
+.tundra .dojoDndAvatar td	{ border: none; }
+.tundra .dojoDndAvatar tr	{ border: none; }
+.tundra .dojoDndAvatarHeader td	{ height: 20px; padding: 0 0 0 21px; }
+.tundra .dojoDndAvatarItem td { padding: 2px;}
+.tundra.dojoDndMove .dojoDndAvatarHeader	{background-color: #f58383; background-image: url(images/dndNoMove.png); background-repeat: no-repeat; background-position: 2px center;}
+.tundra.dojoDndCopy .dojoDndAvatarHeader	{background-color: #f58383; background-image: url(images/dndNoCopy.png); background-repeat: no-repeat; background-position: 2px center;}
+.tundra.dojoDndMove .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{background-color: #97e68d; background-image: url(images/dndMove.png); background-repeat: no-repeat; background-position: 2px center;}
+.tundra.dojoDndCopy .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{background-color: #97e68d; background-image: url(images/dndCopy.png); background-repeat: no-repeat; background-position: 2px center;}
+.tundra .dijitContentPaneLoading {
+	background:url('images/loading.gif') no-repeat left center;
+	padding-left:25px;
+}
+.tundra .dijitContentPaneError {
+	background:url('images/warning.png') no-repeat left center;
+	padding-left:25px;
+}
diff --git a/dijit/themes/tundra/Dialog.css b/dijit/themes/tundra/Dialog.css
new file mode 100644
index 0000000..f96dd28
--- /dev/null
+++ b/dijit/themes/tundra/Dialog.css
@@ -0,0 +1,143 @@
+
+.tundra .dijitDialog {
+	background: #fff;
+	border: 1px solid #7eabcd;
+	
+	padding: 0px;
+	-webkit-box-shadow: 0px 5px 10px #adadad;
+}
+.tundra .dijitDialog .dijitDialogPaneContent {
+	background: #fff;
+	border:none;
+	border-top: 1px solid #d3d3d3; 
+	padding:10px;
+}
+.tundra .dijitDialogTitleBar {
+	
+	background: #fafafa url("images/titleBar.png") repeat-x top left;
+	padding: 5px 6px 3px 6px;
+	cursor: move;
+	outline:0; 
+}
+.tundra .dijitDialogTitle {
+	
+	font-weight: bold;
+	padding: 0px 4px;
+}
+.tundra .dijitDialogCloseIcon {
+	
+	
+	background: url("images/tabClose.png") no-repeat right top;
+	position: absolute;
+	vertical-align: middle;
+	right: 6px;
+	top: 4px;
+	height: 15px;
+	width: 15px;
+	cursor: pointer;
+}
+.dj_ie6 .tundra .dijitDialogCloseIcon {
+	background : url("images/tabClose.gif") no-repeat right top;
+}
+.tundra .dijitDialogCloseIcon-hover {
+	background: url("images/tabCloseHover.png") no-repeat right top;
+}
+.dj_ie6 .tundra .dijitDialogCloseIcon-hover {
+	background : url("images/tabCloseHover.gif") no-repeat right top;
+}
+.tundra .dijitTooltip,
+.tundra .dijitTooltipDialog {
+	
+	background: transparent;	
+}
+.dijitTooltipBelow {
+	
+	padding-top: 13px;
+}
+.dijitTooltipAbove {
+	
+	padding-bottom: 13px;
+}
+.tundra .dijitTooltipContainer {
+	
+	background: #ffffff url("images/popupMenuBg.gif") repeat-x bottom left;
+	border: 1px solid #7eabcd;
+	padding: 0.45em;	
+	-webkit-border-radius: 3px;
+}
+.dj_ff3 .tundra .dijitTooltipContainer {
+	
+	-moz-border-radius: 3px;
+}	
+.tundra .dijitTooltipConnector {
+	
+	border:0px;
+	z-index: 2;
+}
+.tundra .dijitTooltipABRight .dijitTooltipConnector {
+	
+	left: auto !important;
+	right: 3px;
+}
+.tundra .dijitTooltipBelow .dijitTooltipConnector {
+	
+	top: 0px;
+	left: 3px;
+	background:url("images/tooltipConnectorUp.png") no-repeat top left;
+	width:16px;
+	height:14px;
+}
+.dj_ie6 .tundra .dijitTooltipBelow .dijitTooltipConnector {
+	
+	background-image: url("images/tooltipConnectorUp.gif");
+}
+.tundra .dijitTooltipAbove .dijitTooltipConnector {
+	
+	bottom: 0px;
+	left: 3px;
+	background:url("images/tooltipConnectorDown.png") no-repeat top left;
+	width:16px;
+	height:14px;
+}
+.dj_ie6 .tundra .dijitTooltipAbove .dijitTooltipConnector {
+	background-image: url("images/tooltipConnectorDown.gif");
+}
+.dj_ie6 .tundra .dijitTooltipAbove .dijitTooltipConnector {
+	bottom: -3px;
+}
+.tundra .dijitTooltipLeft {
+	padding-right: 14px;
+}
+.dj_ie6 .tundra .dijitTooltipLeft {
+	padding-left: 15px;
+}
+.tundra .dijitTooltipLeft .dijitTooltipConnector {
+	
+	right: 0px;
+	bottom: 3px;
+	background:url("images/tooltipConnectorRight.png") no-repeat top left;
+	width:16px;
+	height:14px;
+}
+.dj_ie6 .tundra .dijitTooltipLeft .dijitTooltipConnector {
+	background-image: url("images/tooltipConnectorRight.gif");
+}
+.tundra .dijitTooltipRight {
+	padding-left: 14px;
+}
+.tundra .dijitTooltipRight .dijitTooltipConnector {
+	
+	left: 0px;
+	bottom: 3px;
+	background:url("images/tooltipConnectorLeft.png") no-repeat top left;
+	width:16px;
+	height:14px;
+}
+.dj_ie6 .tundra .dijitTooltipRight .dijitTooltipConnector {
+	background-image: url("images/tooltipConnectorLeft.gif");
+}
+.dj_webkit .tundra .dijitPopup .dijitTooltipContainer,
+.dj_webkit .tundra .dijitPopup .dijitMenu {
+	
+	-webkit-box-shadow: 0px 5px 10px #adadad;
+}
diff --git a/dijit/themes/tundra/Dialog_rtl.css b/dijit/themes/tundra/Dialog_rtl.css
new file mode 100644
index 0000000..a7fd88b
--- /dev/null
+++ b/dijit/themes/tundra/Dialog_rtl.css
@@ -0,0 +1,5 @@
+
+.dijitRtl .tundra .dijitDialogTitleBar .dijitDialogCloseIcon {
+	right: auto;
+	left: 5px;
+}
diff --git a/dijit/themes/tundra/Editor.css b/dijit/themes/tundra/Editor.css
new file mode 100644
index 0000000..f929b97
--- /dev/null
+++ b/dijit/themes/tundra/Editor.css
@@ -0,0 +1,61 @@
+.dijitIEFixedToolbar {
+	position:absolute;
+	
+	top: expression(eval((document.documentElement||document.body).scrollTop));
+}
+.tundra .dijitToolbar .dijitToolbarSeparator {
+	background: url('images/editor.gif');
+}
+.tundra .dijitEditorIcon {
+	background-image: url('images/editor.gif'); 
+	background-repeat: no-repeat;
+	width: 18px;
+	height: 18px;
+	text-align: center;
+}
+.tundra .dijitDisabled .dijitEditorIcon {
+	background-image: url('images/editorDisabled.gif'); 
+}
+.tundra .dijitEditorIconSep { background-position: 0px; }
+.tundra .dijitEditorIconBackColor { background-position: -18px; }
+.tundra .dijitEditorIconBold { background-position: -36px; }
+.tundra .dijitEditorIconCancel { background-position: -54px; }
+.tundra .dijitEditorIconCopy { background-position: -72px; }
+.tundra .dijitEditorIconCreateLink { background-position: -90px; }
+.tundra .dijitEditorIconCut { background-position: -108px; }
+.tundra .dijitEditorIconDelete { background-position: -126px; }
+.tundra .dijitEditorIconForeColor { background-position: -144px; }
+.tundra .dijitEditorIconHiliteColor { background-position: -162px; }
+.tundra .dijitEditorIconIndent { background-position: -180px; }
+.tundra .dijitEditorIconInsertHorizontalRule { background-position: -198px; }
+.tundra .dijitEditorIconInsertImage { background-position: -216px; }
+.tundra .dijitEditorIconInsertOrderedList { background-position: -234px; }
+.tundra .dijitEditorIconInsertTable { background-position: -252px; }
+.tundra .dijitEditorIconInsertUnorderedList { background-position: -270px; }
+.tundra .dijitEditorIconItalic { background-position: -288px; }
+.tundra .dijitEditorIconJustifyCenter { background-position: -306px; }
+.tundra .dijitEditorIconJustifyFull { background-position: -324px; }
+.tundra .dijitEditorIconJustifyLeft { background-position: -342px; }
+.tundra .dijitEditorIconJustifyRight { background-position: -360px; }
+.tundra .dijitEditorIconLeftToRight { background-position: -378px; }
+.tundra .dijitEditorIconListBulletIndent { background-position: -396px; }
+.tundra .dijitEditorIconListBulletOutdent { background-position: -414px; }
+.tundra .dijitEditorIconListNumIndent { background-position: -432px; }
+.tundra .dijitEditorIconListNumOutdent { background-position: -450px; }
+.tundra .dijitEditorIconOutdent { background-position: -468px; }
+.tundra .dijitEditorIconPaste { background-position: -486px; }
+.tundra .dijitEditorIconRedo { background-position: -504px; }
+.tundra .dijitEditorIconRemoveFormat { background-position: -522px; }
+.tundra .dijitEditorIconRightToLeft { background-position: -540px; }
+.tundra .dijitEditorIconSave { background-position: -558px; }
+.tundra .dijitEditorIconSpace { background-position: -576px; }
+.tundra .dijitEditorIconStrikethrough { background-position: -594px; }
+.tundra .dijitEditorIconSubscript { background-position: -612px; }
+.tundra .dijitEditorIconSuperscript { background-position: -630px; }
+.tundra .dijitEditorIconUnderline { background-position: -648px; }
+.tundra .dijitEditorIconUndo { background-position: -666px; }
+.tundra .dijitEditorIconWikiword { background-position: -684px; }
+.tundra .dijitEditorIconToggleDir { background-position: -540px; }
+.tundra .dijitEditorIconTabIndent { background-position: -702px; }
+.tundra .dijitEditorIconSelectAll { background-position: -720px; }
+.tundra .dijitEditorIconUnlink { background-position: -738px; }
diff --git a/dijit/themes/tundra/Editor_rtl.css b/dijit/themes/tundra/Editor_rtl.css
new file mode 100644
index 0000000..0ac4885
--- /dev/null
+++ b/dijit/themes/tundra/Editor_rtl.css
@@ -0,0 +1,10 @@
+
+.dijitRtl .tundra .dijitEditorIcon {
+	background-image: url('images/editor_rtl.gif'); 
+}
+.dijitRtl .tundra .dijitDisabled .dijitEditorIcon {
+	background-image: url('images/editorDisabled_rtl.gif'); 
+}
+.dijitRtl .tundra .dijitToolbar .dijitToolbarSeparator {
+	background-image: url('images/editor_rtl.gif');
+}
diff --git a/dijit/themes/tundra/Menu.css b/dijit/themes/tundra/Menu.css
new file mode 100644
index 0000000..172b547
--- /dev/null
+++ b/dijit/themes/tundra/Menu.css
@@ -0,0 +1,61 @@
+.tundra .dijitMenu,
+.tundra .dijitMenuBar {
+	border: 1px solid #7eabcd;
+	margin: 0px;
+	padding: 0px;
+	background-color: #f7f7f7;
+	
+}
+.tundra .dijitBorderContainer .dijitMenuBar {
+	border:1px solid #ccc;
+}
+.tundra .dijitMenuItem {
+	font-family: sans-serif;
+	margin: 0;
+}
+.tundra .dijitMenuBar .dijitMenuItem {
+	padding: 4px 5px;
+}
+.tundra .dijitMenuPreviousButton, .tundra .dijitMenuNextButton {
+	font-style: italic;
+}
+.tundra .dijitMenuItem td {
+	padding: 2px;
+}
+.tundra .dijitMenuPassive .dijitMenuItemHover,
+.tundra .dijitMenuItemSelected {
+	background-color: #3559ac;
+	color:#fff;
+}
+.tundra .dijitMenuItemIcon {
+	width: 16px;
+	height: 16px;
+}
+.tundra .dijitMenuExpand {
+	width: 7px;
+	height: 7px;
+	background-image: url('images/spriteArrows.png');
+	background-position: -14px 0px;
+}
+.dj_ie6 .tundra .dijitMenuExpand {
+	background-image: url('images/spriteArrows.gif');
+}
+.tundra .dijitMenuSeparatorTop {
+	border-bottom: 1px solid #9b9b9b;
+}
+.tundra .dijitMenuSeparatorBottom {
+	border-top: 1px solid #e8e8e8;
+}
+.tundra .dijitCheckedMenuItemIconChar {
+	display: none;
+}
+.tundra .dijitCheckedMenuItemIcon {
+	background-image: url('images/checkmark.png');
+	background-position: -80px;
+}
+.dj_ie6 .tundra .dijitCheckedMenuItemIcon {
+	background-image: url('images/checkmark.gif');
+}
+.tundra .dijitCheckedMenuItemChecked .dijitCheckedMenuItemIcon {
+	background-position: -64px;
+}
diff --git a/dijit/themes/tundra/Menu_rtl.css b/dijit/themes/tundra/Menu_rtl.css
new file mode 100644
index 0000000..6d64c87
--- /dev/null
+++ b/dijit/themes/tundra/Menu_rtl.css
@@ -0,0 +1,7 @@
+.dijitRtl .tundra .dijitMenuItem .dijitMenuItemIcon {
+	padding-left: 3px;
+	padding-right: 0px;
+}
+.dijitRtl .tundra .dijitMenuItem .dijitMenuExpand {
+	background-position: -7px 0px;
+}
diff --git a/dijit/themes/tundra/ProgressBar.css b/dijit/themes/tundra/ProgressBar.css
new file mode 100644
index 0000000..3f555c42
--- /dev/null
+++ b/dijit/themes/tundra/ProgressBar.css
@@ -0,0 +1,23 @@
+.tundra .dijitProgressBar {
+	margin:2px 0px 2px 0px;
+}
+.tundra .dijitProgressBarEmpty {
+	
+	background:#fff url("images/progressBarEmpty.png") repeat-x center center;
+	border-color: #a2a2a2 #b8b8b8 #b8b8b8 #a2a2a2;
+}
+.tundra .dijitProgressBarTile {
+	
+	background:#f0f0f0 url("images/progressBarFull.png") repeat-x center center;
+}
+.tundra .dijitProgressBarFull {
+	border-right:1px solid #b8b8b8;
+}
+.tundra .dijitProgressBarLabel {
+	
+	color:#293a4b;
+}
+.tundra .dijitProgressBarIndeterminate .dijitProgressBarTile {
+	
+	background:#cad2de url("images/progressBarAnim.gif") repeat-x center center;
+}
diff --git a/dijit/themes/tundra/TimePicker.css b/dijit/themes/tundra/TimePicker.css
new file mode 100644
index 0000000..0129fa1
--- /dev/null
+++ b/dijit/themes/tundra/TimePicker.css
@@ -0,0 +1,50 @@
+
+.tundra .dijitTimePickerTick,
+.tundra .dijitTimePickerMarker {
+	border-color: #ccc;
+}
+.tundra .dijitTimePickerTick {
+	color:white;
+}
+.tundra .dijitTimePickerMarker {
+	background:#d3d3d3 url("images/titleBar.png") repeat-x top;
+	color:#293a4b;
+	font-weight: bold;
+}
+.tundra .dijitTimePickerItemSelected {
+	color: black;
+	background: #bbc4d0 none;
+}
+.tundra .dijitTimePickerItemHover {
+	background: #60a1ea none;
+	color:white;
+}
+.tundra .dijitTimePickerItemHover,
+.tundra .dijitTimePickerItemSelected {
+	position: relative;
+	z-index: 10;
+}
+.tundra .dijitTimePickerTick .dijitTimePickerItemInner {
+	font-size:0.4em;
+}
+.tundra .dijitTimePickerItemHover .dijitTimePickerItemInner,
+.tundra .dijitTimePickerItemSelected .dijitTimePickerItemInner {
+	font-size:1em;
+}
+.tundra .dijitTimePickerMarkerHover {
+	border-top: 1px solid #ccc;
+}
+.tundra .dijitTimePickerTickHover,
+.tundra .dijitTimePickerTickSelected {
+	margin-top:-0.3em;
+	margin-bottom:-0.3em;
+	border-bottom: none;
+}
+.dijit_a11y .dijitTimePickerTickHover {
+	background-color: #CCC !important;
+	border-top: 1px solid #333 !important;
+	border-bottom: 1px solid #333 !important;
+}
+.dijit_a11y .dijitTimePickerMarkerHover {
+	border-bottom-width: 2px;
+}
diff --git a/dijit/themes/tundra/TitlePane.css b/dijit/themes/tundra/TitlePane.css
new file mode 100644
index 0000000..f5d8de3
--- /dev/null
+++ b/dijit/themes/tundra/TitlePane.css
@@ -0,0 +1,60 @@
+.tundra .dijitTitlePaneTitle {
+	background: #cccccc;
+	background:#fff url("images/titleBar.png") repeat-x bottom left;
+	border:1px solid #bfbfbf;
+	padding:3px 4px;
+	cursor: pointer;
+}
+.tundra .dijitTitlePaneTitle-hover  {
+	background: #f8fafd url("images/accordionItemHover.gif") bottom repeat-x;
+}
+.tundra .dijitTitlePaneTitle * {
+	vertical-align: middle;
+}
+.tundra .dijitTitlePane .dijitArrowNode {
+	cursor: pointer;
+	background-image: url('images/spriteArrows.png');
+	background-repeat: no-repeat;
+	height: 7px;
+	width: 7px;
+}
+.dj_ie6 .tundra .dijitTitlePane .dijitArrowNode {
+	background-image: url('images/spriteArrows.gif');
+}
+.tundra .dijitTitlePane .dijitOpen .dijitArrowNode {
+	background-position: 0px 0px;
+}
+.tundra .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background-position: -14px 0px;
+}
+.tundra .dijitTitlePaneFocused .dijitTitlePaneTextNode {
+	text-decoration:underline;
+}
+.tundra .dijitTitlePane .dijitArrowNodeInner {
+	display:none;
+}
+.dijit_a11y .dijitTitlePane .dijitArrowNodeInner {
+	display:inline !important;
+	font-family:monospace;
+	cursor: pointer;
+	padding-bottom:.2em;
+}
+.dijit_a11y .dijitTitlePane .dijitArrowNode {
+	display:none;
+}
+.tundra .dijitTitlePaneContentOuter {
+	background: #ffffff;
+	border:1px solid #bfbfbf;
+	border-top: 1px solid #ccc;	
+}
+.tundra .dijitTitlePaneContentInner {
+	padding:10px;
+}
+.dj_ie6 .tundra .dijitTitlePaneContentOuter,
+.dj_ie6 .tundra .dijitTitlePane .dijitTitlePaneTitle {
+	zoom: 1;
+}
+.tundra .dijitTitlePaneTextNode {
+	margin-left: 4px;
+	margin-right: 4px;
+}
diff --git a/dijit/themes/tundra/TitlePane_rtl.css b/dijit/themes/tundra/TitlePane_rtl.css
new file mode 100644
index 0000000..a99135d
--- /dev/null
+++ b/dijit/themes/tundra/TitlePane_rtl.css
@@ -0,0 +1,3 @@
+.dijitRtl .tundra .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background-position: -7px 0px;
+}
diff --git a/dijit/themes/tundra/Toolbar.css b/dijit/themes/tundra/Toolbar.css
new file mode 100644
index 0000000..7033ddf
--- /dev/null
+++ b/dijit/themes/tundra/Toolbar.css
@@ -0,0 +1,58 @@
+.tundra .dijitToolbar {
+	border-bottom: 1px solid #ccc;
+	background:#eaeaea url("images/titleBar.png") repeat-x top left;
+}
+.dj_ie6 .tundra .dijitToolbar {
+	height: 10px;
+}
+.tundra .dijitToolbar .dijitButtonNode,
+.tundra .dijitToolbar .dijitComboButton .dijitButtonContents,
+.tundra .dijitToolbar .dijitComboButton .dijitDownArrowButton {
+	background: none;
+	margin: 0px;
+	padding: 0px;
+	border: none;
+	font-size: 12px;
+}
+.tundra .dijitToolbar .dijitButton,
+.tundra .dijitToolbar .dijitToggleButton,
+.tundra .dijitToolbar .dijitDropDownButton,
+.tundra .dijitToolbar .dijitComboButton .dijitButtonContents,
+.tundra .dijitToolbar .dijitComboButton .dijitDownArrowButton  {
+	background: none;
+	padding: 1px;
+}
+.tundra .dijitToolbar .dijitButtonChecked,
+.tundra .dijitToolbar .dijitToggleButtonChecked {
+	background-color:#d4dff2;
+	border:1px solid #316ac5;
+	padding: 0px;	
+}
+.tundra .dijitToolbar .dijitButtonCheckedHover,
+.tundra .dijitToolbar .dijitToggleButtonCheckedHover
+ {
+	background-color:#abc1e5;
+	border:1px solid #316ac5;
+	padding: 0px;	
+}
+.tundra .dijitToolbar .dijitButtonHover,
+.tundra .dijitToolbar .dijitToggleButtonHover,
+.tundra .dijitToolbar .dijitDropDownButtonHover,
+.tundra .dijitToolbar .dijitComboButtonHover .dijitButtonContents,
+.tundra .dijitToolbar .dijitComboButtonDownArrowHover .dijitDownArrowButton {
+	
+	border: 1px solid #869cbf;
+	padding: 0px;	
+	background-color:#e1e5f0;
+}
+.tundra .dijitToolbar label {	
+	padding: 3px 3px 0 6px;
+}
+.dj_ie .tundra .dijitToolbar .dijitComboButton .dijitButtonContentsFocused,
+.dj_ie .tundra .dijitToolbar .dijitComboButton .dijitDownArrowButtonFocused,
+.dj_ff2 .tundra .dijitToolbar .dijitComboButton .dijitButtonContentsFocused,
+.dj_ff2 .tundra .dijitToolbar .dijitComboButton .dijitDownArrowButtonFocused {
+	
+	border: 1px #555 dotted !important;
+	padding: 0px;	
+}
diff --git a/dijit/themes/tundra/Tree.css b/dijit/themes/tundra/Tree.css
new file mode 100644
index 0000000..d6dc5a5
--- /dev/null
+++ b/dijit/themes/tundra/Tree.css
@@ -0,0 +1,85 @@
+
+.tundra .dijitTreeNode {
+    background-image : url('images/i.gif');
+    background-repeat : repeat-y;
+    zoom: 1;	
+}
+.tundra .dijitTreeIsLast {
+    background: url('images/i_half.gif') no-repeat;
+}
+.tundra .dijitTreeIsRoot {
+    margin-left: 0;
+    background-image: none;
+}
+.tundra .dijitTreeExpando {
+    width: 18px;
+    height: 18px;
+}
+.tundra .dijitTreeRow {
+	
+	padding-bottom: 2px;
+}
+.tundra .dijitTreeContent {
+    min-height: 18px;
+    min-width: 18px;
+ }
+.tundra .dijitTreeExpand {
+    width: 18px;
+    height: 18px;
+    background-repeat : no-repeat;
+}
+.tundra .dijitTreeNodeEmphasized {
+    background-color: Highlight;
+    color: HighlightText;
+}
+.tundra .dijitTreeLabelFocused {
+	outline: 1px invert dotted;
+}
+.tundra .dijitTreeNodeSelected .dijitTreeLabel {
+	background:#e2ebfe;
+}
+.tundra .dijitTreeNodeHover {
+	
+	
+	background-image: url(images/treeHover.png);
+	background-repeat: repeat;
+	background-color: none !important;
+}
+.tundra .dijitTreeExpandoOpened {
+	background-image: url('images/treeExpand_minus.gif');
+}
+.tundra .dijitTreeExpandoClosed {
+	background-image: url('images/treeExpand_plus.gif');
+}
+.tundra .dijitTreeExpandoLeaf {
+	background-image: url('images/treeExpand_leaf.gif');
+}
+.tundra .dijitTreeExpandoLoading {
+	background-image: url('images/treeExpand_loading.gif');
+}
+.tundra .dijitTreeIcon {
+	width: 16px;
+	height: 16px;
+}
+.tundra .dijitFolderOpened {
+	background: url('images/folderOpened.gif') no-repeat;
+}
+.tundra .dijitFolderClosed {
+	background: url('images/folderClosed.gif') no-repeat;
+}
+.tundra .dijitLeaf {
+	background: url('images/leaf.gif') no-repeat;
+}
+.tundra .dijitTreeNode .dojoDndItemBefore,
+.tundra .dijitTreeNode .dojoDndItemAfter {
+	border-bottom: none;
+	border-top: none;
+}
+.tundra .dijitTreeNode .dojoDndItemBefore .dijitTreeContent {
+	
+	border-top: 2px solid #369;
+}
+.tundra .dijitTreeNode .dojoDndItemAfter .dijitTreeContent {
+	
+	border-bottom: 2px solid #369;
+}
diff --git a/dijit/themes/tundra/Tree_rtl.css b/dijit/themes/tundra/Tree_rtl.css
new file mode 100644
index 0000000..1a7c938
--- /dev/null
+++ b/dijit/themes/tundra/Tree_rtl.css
@@ -0,0 +1,13 @@
+
+.dijitRtl .tundra .dijitTreeContainer .dijitTreeNode {
+    background-image : none;
+}
+.dijitRtl .tundra .dijitTreeContainer .dijitTreeExpandoOpened {
+	background-image: url('images/treeExpand_minus_rtl.gif');
+}
+.dijitRtl .tundra .dijitTreeContainer .dijitTreeExpandoClosed {
+	background-image: url('images/treeExpand_plus_rtl.gif');
+}
+.dijitRtl .tundra .dijitTreeContainer .dijitTreeExpandoLeaf {
+	background-image: none;
+}
diff --git a/dijit/themes/tundra/form/Button.css b/dijit/themes/tundra/form/Button.css
new file mode 100644
index 0000000..f357f5b
--- /dev/null
+++ b/dijit/themes/tundra/form/Button.css
@@ -0,0 +1,116 @@
+
+.tundra .dijitButtonNode {
+	
+	border: 1px solid #c0c0c0; 
+	border-bottom: 1px solid #9b9b9b; 
+	padding: 0.1em 0.2em 0.2em 0.2em; 
+	background: #fff url("../images/buttonEnabled.png") repeat-x bottom left;
+}
+.tundra .dijitButtonNode button { 
+	border: 0px; 
+	background-color: transparent; 
+} 
+ 
+.tundra .dijitButtonText {
+	text-align: center; 
+	padding: 0 0.3em;
+}
+.tundra .dijitDisabled .dijitButtonText {
+	color: #7F7F7F;
+}
+.tundra .dijitArrowButton {
+	color: #111;
+}
+.tundra .dijitComboButton .dijitDownArrowButton {
+	padding-right:4px;
+}
+.dj_ff2 .tundra .dijitComboButton .dijitButtonContentsFocused,
+.dj_ff2 .tundra .dijitComboButton .dijitDownArrowButtonFocused {
+	border: 1px solid transparent; 
+}
+.tundra .dijitButtonDisabled .dijitButtonNode,
+.tundra .dijitToggleButtonDisabled .dijitButtonNode,
+.tundra .dijitDropDownButtonDisabled .dijitButtonNode,
+.tundra .dijitComboButtonDisabled .dijitButtonNode,
+.tundra .dijitComboBoxDisabled,
+.tundra .dijitSpinnerDisabled,
+.tundra .dijitSpinnerDisabled .dijitButtonNode {
+	
+	
+	border-color: #d5d5d5 #d5d5d5 #bdbdbd #d5d5d5; 
+	background:#e4e4e4 url("../images/buttonDisabled.png") top repeat-x;
+}
+.tundra .dijitButtonHover .dijitButtonNode,
+.tundra .dijitButtonNodeHover,
+.tundra .dijitToggleButtonHover .dijitButtonNode,
+.tundra .dijitDropDownButtonHover .dijitButtonNode,
+.tundra .dijitComboButtonHover .dijitButtonContents,
+.tundra .dijitComboButtonDownArrowHover .dijitDownArrowButton {
+	
+	
+	border-color:		#a5beda; 
+	border-bottom-color:#5c7590; 
+	color:#243C5F;
+	background:#fcfdff url("../images/buttonHover.png") repeat-x bottom;
+}
+.tundra .dijitComboBoxHover .dijitDownArrowButton,
+.tundra .dijitSpinnerUpArrowHover .dijitUpArrowButton,
+.tundra .dijitSpinnerDownArrowHover .dijitDownArrowButton {
+	
+	color:#243C5F;
+	background:#fcfdff url("../images/buttonHover.png") repeat-x bottom;
+}
+.tundra .dijitSpinnerUpArrowActive .dijitUpArrowButton,
+.tundra .dijitSpinnerDownArrowActive .dijitDownArrowButton,
+.tundra .dijitButtonActive .dijitButtonNode,
+.tundra .dijitToggleButtonActive .dijitButtonNode,
+.tundra .dijitDropDownButtonActive .dijitButtonNode,
+.tundra .dijitComboButtonActive .dijitButtonContents,
+.tundra .dijitDownArrowActive .dijitDownArrowButton,
+.tundra .dijitComboBoxActive .dijitDownArrowButton,
+.tundra .dijitStackController .dijitToggleButtonChecked .dijitButtonNode {
+	
+	border-color:#366dba;
+	background: #ededed url("../images/buttonActive.png") bottom repeat-x;
+}
+.tundra .dijitArrowButtonInner {
+	background-image:url("../images/spriteArrows.png");
+	background-position: left top;
+	width: 7px;
+	height: 7px;
+	font-size: 1px;
+	margin: 0px 4px 0px 5px;
+}
+.dj_ie6 .tundra .dijitArrowButtonInner {
+	background-image:url("../images/spriteArrows.gif");
+}
+.tundra .dijitDisabled .dijitArrowButtonInner {
+	background-position: -28px top;
+}
+.tundra .dijitUpArrowButton .dijitArrowButtonInner { 
+	background-position: -21px top; 
+}
+.tundra .dijitDisabled .dijitUpArrowButton .dijitArrowButtonInner { 
+	background-position: -49px top; 
+}
+.tundra .dijitComboBox .dijitArrowButton .dijitArrowButtonInner {
+	background-image: url("../images/comboArrowDown.gif");
+	background-repeat: no-repeat;
+	background-attachment: scroll;
+	background-position: center center;
+	height: auto;
+	font-size: 100%;
+	font-size: inherit;
+}
+.tundra .dijitComboBoxHover .dijitArrowButtonInner {
+	
+}
+.tundra .dijitSpinner .dijitArrowButtonInner {
+	display: block;  
+	position:absolute;
+	top: 50%; 
+	margin-top: -4px; 
+	left: 50%;
+	margin-left: -4px; 
+	line-height: 2px;
+}
diff --git a/dijit/themes/tundra/form/Checkbox.css b/dijit/themes/tundra/form/Checkbox.css
new file mode 100644
index 0000000..e7ff2f9
--- /dev/null
+++ b/dijit/themes/tundra/form/Checkbox.css
@@ -0,0 +1,45 @@
+.tundra .dijitToggleButton .dijitCheckBoxIcon {
+	background-image: url('../images/checkmarkNoBorder.png');
+}
+.dj_ie6 .tundra .dijitToggleButton .dijitCheckBoxIcon {
+	background-image: url('../images/checkmarkNoBorder.gif');
+}
+.tundra .dijitCheckBox,
+.tundra .dijitCheckBoxIcon			{
+	background-image: url('../images/checkmark.png'); 
+	background-repeat: no-repeat;
+	width: 16px;
+	height: 16px;
+	margin: 0 2px 0 0;
+	padding: 0;
+}
+.dj_ie6 .tundra .dijitCheckBox,
+.dj_ie6 .tundra .dijitCheckBoxIcon			{
+	background-image: url('../images/checkmark.gif'); 
+}
+.tundra .dijitCheckBox,
+.tundra .dijitToggleButton .dijitCheckBoxIcon {
+	
+	background-position: -16px;
+}
+.tundra .dijitCheckBoxChecked,
+.tundra .dijitToggleButtonChecked .dijitCheckBoxIcon {
+	
+	background-position: 0px;
+}
+.tundra .dijitCheckBoxDisabled {
+	
+	background-position: -48px;
+}
+.tundra .dijitCheckBoxCheckedDisabled {
+	
+	background-position: -32px;
+}
+.tundra .dijitCheckBoxHover {
+	
+	background-position: -80px;
+}
+.tundra .dijitCheckBoxCheckedHover {
+	
+	background-position: -64px;
+}
diff --git a/dijit/themes/tundra/form/Common.css b/dijit/themes/tundra/form/Common.css
new file mode 100644
index 0000000..a43f17f
--- /dev/null
+++ b/dijit/themes/tundra/form/Common.css
@@ -0,0 +1,119 @@
+
+.tundra .dijitInputField INPUT,
+.tundra .dijitTextBox,
+.tundra .dijitComboBox,
+.tundra .dijitSpinner {
+	margin: 0em 0.1em;
+}
+.tundra .dijitTextBox,
+.tundra .dijitComboBox,
+.tundra .dijitSpinner,
+.tundra .dijitTextArea {
+	font-family: sans-serif;
+	font-size: 100%;
+}
+.tundra .dijitTextArea {
+	padding: 3px;
+}
+.tundra .dijitTextBox,
+.tundra .dijitComboBox,
+.tundra .dijitSpinner,
+.tundra .dijitTextArea,
+.tundra .dijitInlineEditor input {
+	
+	background:#fff url("../images/validationInputBg.png") repeat-x top left;
+	#background:#fff url('../images/validationInputBg.gif') repeat-x top left;
+	border:1px solid #b3b3b3;
+	line-height: normal;
+}
+.tundra .dijitTextBoxDisabled,
+.tundra .dijitComboBoxDisabled,
+.tundra .dijitSpinnerDisabled,
+.tundra .dijitTextAreaDisabled {
+	color: gray;
+}
+.dj_webkit .tundra .dijitTextBoxDisabled,
+.dj_webkit .tundra .dijitComboBoxDisabled,
+.dj_webkit .tundra .dijitSpinnerDisabled,
+.dj_webkit .tundra .dijitTextAreaDisabled {
+	color: #eee;
+}
+.tundra .dijitComboBox .dijitInputField {
+	padding: 1px 0;
+}
+.tundra .dijitComboBox .dijitButtonNode {
+	padding: 1px 0.2em;
+}
+.tundra .dijitComboBox .dijitButtonNode,
+.tundra .dijitSpinner .dijitButtonNode {
+	
+	border-color: #9b9b9b;
+	border-width: 0px 0px 0px 1px;
+	border-style: solid;
+}
+.tundra .dijitTextBoxFocused,
+.tundra .dijitComboBoxFocused,
+.tundra .dijitSpinnerFocused, .tundra .dijitSpinnerUpArrowActive, .tundra .dijitSpinnerDownArrowActive,
+.tundra .dijitTextAreaFocused {
+	
+	border-color:#406b9b;
+}
+.tundra .dijitComboBoxFocused .dijitButtonNode,
+.tundra .dijitSpinnerFocused .dijitButtonNode,
+.tundra .dijitSpinnerUpArrowActive .dijitButtonNode,
+.tundra .dijitSpinnerDownArrowActive .dijitButtonNode {
+	border-left-color:#366dba;
+}
+.tundra .dijitSpinnerFocused .dijitDownArrowButton,
+.tundra .dijitSpinnerUpArrowActive .dijitDownArrowButton,
+.tundra .dijitSpinnerDownArrowActive .dijitDownArrowButton {
+	border-top-color:#366dba;
+}
+.tundra .dijitError {
+	background-color:#f9f7ba;
+	background-image:none;
+}
+.dj_ie6 .tundra .dijitError INPUT {
+	
+	background-color:#f9f7ba !important;
+}
+.tundra .dijitErrorFocused {
+	background-color:#f9f999;
+	background-image:none;
+}
+.dj_ie6 .tundra .dijitErrorFocused INPUT {
+	
+	background-color:#f9f999 !important;
+}
+.tundra .dijitValidationIcon {
+	
+	width: 16px;
+	background: transparent url('../images/warning.png') no-repeat center center;
+}
+.tundra .dijitInlineValue {
+	
+	padding:3px;
+	margin:4px;
+}
+.tundra .dijitInlineEditor {
+	
+	display: inline-block;
+	display: -moz-inline-stack;
+	#display:inline;
+	
+}
+.dijitInlineEditor .saveButton,
+.dijitInlineEditor .cancelButton {
+	margin:3px 3px 3px 0px;
+}
+.RichTextEditable {
+	border:1px solid #bfbfbf;
+	border-top:0;
+}
+.tundra .dijitComboBoxHighlightMatch {
+	background-color:#a5beda;
+}
+.tundra .dijitFocusedLabel {
+	
+	outline: 1px dotted #666666;
+}
diff --git a/dijit/themes/tundra/form/Common_rtl.css b/dijit/themes/tundra/form/Common_rtl.css
new file mode 100644
index 0000000..093415e
--- /dev/null
+++ b/dijit/themes/tundra/form/Common_rtl.css
@@ -0,0 +1,6 @@
+.dijitRtl .tundra .dijitComboBox .dijitButtonNode,
+.dijitRtl  .dijitSpinner .dijitButtonNode {
+	
+	border-color: #9b9b9b;
+	border-width: 0px 1px 0px 0px;
+}
diff --git a/dijit/themes/tundra/form/RadioButton.css b/dijit/themes/tundra/form/RadioButton.css
new file mode 100644
index 0000000..0d3b534
--- /dev/null
+++ b/dijit/themes/tundra/form/RadioButton.css
@@ -0,0 +1,44 @@
+.tundra .dijitToggleButton .dijitRadio,
+.tundra .dijitToggleButton .dijitRadioIcon {
+	background-image: url('../images/checkmarkNoBorder.png');
+}
+.dj_ie6 .tundra .dijitToggleButton .dijitRadio,
+.dj_ie6 .tundra .dijitToggleButton .dijitRadioIcon {
+	background-image: url('../images/checkmarkNoBorder.gif');
+}
+.tundra .dijitRadio,
+.tundra .dijitRadioIcon	{		
+	background-image: url('../images/checkmark.png'); 
+	background-repeat: no-repeat;
+	width: 16px;
+	height: 16px;
+	margin: 0;
+	padding: 0;
+}
+.dj_ie6 .tundra .dijitRadio,
+.dj_ie6 .tundra .dijitRadioIcon	{		
+	background-image: url('../images/checkmark.gif'); 
+}
+.tundra .dijitRadio,
+.tundra .dijitToggleButton .dijitRadioIcon {
+	
+	background-position: -112px;
+}
+.tundra .dijitRadioDisabled {
+	
+	background-position: -144px;
+}
+.tundra .dijitRadioHover {
+	
+	background-position: -176px;
+}
+.tundra .dijitRadioChecked,
+.tundra .dijitRadioCheckedHover,
+.tundra .dijitToggleButtonChecked .dijitRadioIcon {
+	
+	background-position: -96px;
+}
+.tundra .dijitRadioCheckedDisabled {
+	
+	background-position: -128px;
+}
diff --git a/dijit/themes/tundra/form/Slider.css b/dijit/themes/tundra/form/Slider.css
new file mode 100644
index 0000000..59c4685
--- /dev/null
+++ b/dijit/themes/tundra/form/Slider.css
@@ -0,0 +1,126 @@
+.tundra .dijitSliderProgressBarH {
+	border-color: #aab0bb;
+	background: #c0c2c5 url("../images/sliderFull.png") repeat-x top left;
+}
+.tundra .dijitSliderProgressBarV {
+	border-color: #aab0bb;
+	background: #c0c2c5 url("../images/sliderFullVertical.png") repeat-y bottom left;
+}
+.tundra .dijitSliderFocused .dijitSliderProgressBarH,
+.tundra .dijitSliderFocused .dijitSliderLeftBumper {
+	background-image:url("../images/sliderFullFocus.png");
+}
+.tundra .dijitSliderFocused .dijitSliderProgressBarV,
+.tundra .dijitSliderFocused .dijitSliderBottomBumper {
+	background-image:url("../images/sliderFullVerticalFocus.png");
+}
+.tundra .dijitSliderRemainingBarV {
+	border-color: #b4b4b4;
+	background: #dcdcdc url("../images/sliderEmptyVertical.png") repeat-y bottom left;
+}
+.tundra .dijitSliderRemainingBarH {
+	border-color: #b4b4b4;
+	background: #dcdcdc url("../images/sliderEmpty.png") repeat-x top left;
+}
+.tundra .dijitSliderBar {
+	border-style: solid;
+	outline:1px;
+}
+.tundra .dijitSliderFocused .dijitSliderBar {
+	border-color:#888;	
+}
+.dijit_a11y .dijitSliderProgressBar {
+	background-color:#888 !important;
+}
+.tundra .dijitSliderImageHandleH {
+	border:0px;
+	width:16px;
+	height:16px;
+	background:url("../images/preciseSliderThumb.png") no-repeat center top;
+	cursor:pointer;
+}
+.tundra .dijitSliderFocused .dijitSliderImageHandleH {
+	background-image:url("../images/preciseSliderThumbFocus.png");
+	#background-image:url("../images/preciseSliderThumbFocus.gif");
+}
+.dj_ie6 .tundra .dijitSliderImageHandleH {
+	background-image:url("../images/preciseSliderThumb.gif");
+}
+.tundra .dijitSliderLeftBumper {
+	border-left-width: 1px;
+	border-color: #aab0bb;
+	background: #c0c2c5 url("../images/sliderFull.png") repeat-x top left;
+}
+.tundra .dijitSliderRightBumper {
+	background: #dcdcdc url("../images/sliderEmpty.png") repeat-x top left;
+	border-color: #b4b4b4;
+	border-right-width: 1px;
+}
+.tundra .dijitSliderImageHandleV {
+	border:0px;
+	width:16px;
+	height:16px;
+	background:url("../images/sliderThumb.png") no-repeat center center;
+	cursor:pointer;
+}
+.tundra .dijitSliderFocused .dijitSliderImageHandleV {
+	background-image:url("../images/sliderThumbFocus.png");
+}
+.dj_ie6 .tundra .dijitSliderFocused .dijitSliderImageHandleV {
+	background-image:url("../images/sliderThumbFocus.gif");
+}
+.tundra .dijitSliderBottomBumper {
+	border-bottom-width: 1px;
+	border-color: #aab0bb;
+	background: #c0c2c5 url("../images/sliderFullVertical.png") repeat-y bottom left;
+}
+.tundra .dijitSliderTopBumper {
+	background: #dcdcdc url("../images/sliderEmptyVertical.png") repeat-y top left;
+	border-color: #b4b4b4;
+	border-top-width: 1px;
+}
+.tundra .dijitSliderDecrementIconH,
+.tundra .dijitSliderDecrementIconV,
+.tundra .dijitSliderIncrementIconH,
+.tundra .dijitSliderIncrementIconV {
+	cursor: pointer;
+	background-image: url('../images/spriteArrows.png');
+	background-repeat: no-repeat;
+	margin: 5px;
+	height: 7px;
+	width: 7px;
+	font-size: 1px;
+}
+.dj_ie6 .tundra .dijitSliderDecrementIconH,
+.dj_ie6 .tundra .dijitSliderDecrementIconV,
+.dj_ie6 .tundra .dijitSliderIncrementIconH,
+.dj_ie6 .tundra .dijitSliderIncrementIconV {
+	background-image: url('../images/spriteArrows.gif');
+}
+.tundra .dijitSliderDecrementIconH {
+	background-position: -7px 0px;
+}
+.tundra .dijitSliderIncrementIconH {
+	background-position: -14px 0px;
+}
+.tundra .dijitSliderDecrementIconV {
+	background-position: 0px 0px;
+}
+.tundra .dijitSliderIncrementIconV {
+	background-position: -21px 0px;
+}
+.tundra .dijitSliderButtonInner {
+	visibility:hidden;
+}
+.tundra .dijitSliderDisabled {
+	opacity:0.6 !important;
+}
+.dj_ie .tundra .dijitSliderDisabled,
+.dj_ie .tundra .dijitSliderDisabled .dijitRuleContainer,
+.dj_ie .tundra .dijitSliderDisabled .dijitSliderRemainingBar,
+.dj_ie .tundra .dijitSliderDisabled .dijitSliderProgressBar {
+	filter: gray() alpha(opacity=40);
+}
+.tundra .dijitSliderDisabled * {
+	cursor: not-allowed !important;
+}
diff --git a/dijit/themes/tundra/form/Slider_rtl.css b/dijit/themes/tundra/form/Slider_rtl.css
new file mode 100644
index 0000000..90d2b73
--- /dev/null
+++ b/dijit/themes/tundra/form/Slider_rtl.css
@@ -0,0 +1,26 @@
+.dijitRtl .tundra .dijitSliderProgressBarH,
+.dijitRtl .tundra .dijitSliderRemainingBarH,
+.dijitRtl .tundra .dijitSliderLeftBumper,
+.dijitRtl .tundra .dijitSliderRightBumper,
+.dijitRtl .tundra .dijitSliderTopBumper {
+	background-position: top right;
+}
+.dijitRtl .tundra .dijitSliderProgressBarV,
+.dijitRtl .tundra .dijitSliderRemainingBarV,
+.dijitRtl .tundra .dijitSliderBottomBumper {
+	background-position: bottom right;
+}
+.dijitRtl .tundra .dijitSliderLeftBumper {
+	border-left-width: 0px;
+	border-right-width: 1px;
+}
+.dijitRtl .tundra .dijitSliderRightBumper {
+	border-left-width: 1px;
+	border-right-width: 0px;
+}
+.dijitRtl .tundra .dijitSliderIncrementIconH {
+	background-position: -7px 0px;
+}
+.dijitRtl .tundra .dijitSliderDecrementIconH {
+	background-position: -14px 0px;
+}
diff --git a/dijit/themes/tundra/images/accordionItemActive.gif b/dijit/themes/tundra/images/accordionItemActive.gif
new file mode 100644
index 0000000..ccff383
Binary files /dev/null and b/dijit/themes/tundra/images/accordionItemActive.gif differ
diff --git a/dijit/themes/tundra/images/accordionItemHover.gif b/dijit/themes/tundra/images/accordionItemHover.gif
new file mode 100644
index 0000000..96bd3a4
Binary files /dev/null and b/dijit/themes/tundra/images/accordionItemHover.gif differ
diff --git a/dijit/themes/tundra/images/buttonActive.png b/dijit/themes/tundra/images/buttonActive.png
new file mode 100644
index 0000000..09417b1
Binary files /dev/null and b/dijit/themes/tundra/images/buttonActive.png differ
diff --git a/dijit/themes/tundra/images/buttonDisabled.png b/dijit/themes/tundra/images/buttonDisabled.png
new file mode 100644
index 0000000..70766f4
Binary files /dev/null and b/dijit/themes/tundra/images/buttonDisabled.png differ
diff --git a/dijit/themes/tundra/images/buttonEnabled.png b/dijit/themes/tundra/images/buttonEnabled.png
new file mode 100644
index 0000000..cf0eb20
Binary files /dev/null and b/dijit/themes/tundra/images/buttonEnabled.png differ
diff --git a/dijit/themes/tundra/images/buttonHover.png b/dijit/themes/tundra/images/buttonHover.png
new file mode 100644
index 0000000..b074e4e
Binary files /dev/null and b/dijit/themes/tundra/images/buttonHover.png differ
diff --git a/dijit/themes/tundra/images/calendarDayLabel.png b/dijit/themes/tundra/images/calendarDayLabel.png
new file mode 100644
index 0000000..c1a1553
Binary files /dev/null and b/dijit/themes/tundra/images/calendarDayLabel.png differ
diff --git a/dijit/themes/tundra/images/calendarMonthLabel.png b/dijit/themes/tundra/images/calendarMonthLabel.png
new file mode 100644
index 0000000..fd2cf0a
Binary files /dev/null and b/dijit/themes/tundra/images/calendarMonthLabel.png differ
diff --git a/dijit/themes/tundra/images/calendarYearLabel.png b/dijit/themes/tundra/images/calendarYearLabel.png
new file mode 100644
index 0000000..dd344f5
Binary files /dev/null and b/dijit/themes/tundra/images/calendarYearLabel.png differ
diff --git a/dijit/themes/tundra/images/checkmark.gif b/dijit/themes/tundra/images/checkmark.gif
new file mode 100644
index 0000000..ae6faa9
Binary files /dev/null and b/dijit/themes/tundra/images/checkmark.gif differ
diff --git a/dijit/themes/tundra/images/checkmark.png b/dijit/themes/tundra/images/checkmark.png
new file mode 100644
index 0000000..0307109
Binary files /dev/null and b/dijit/themes/tundra/images/checkmark.png differ
diff --git a/dijit/themes/tundra/images/checkmarkNoBorder.gif b/dijit/themes/tundra/images/checkmarkNoBorder.gif
new file mode 100644
index 0000000..324bfb3
Binary files /dev/null and b/dijit/themes/tundra/images/checkmarkNoBorder.gif differ
diff --git a/dijit/themes/tundra/images/checkmarkNoBorder.png b/dijit/themes/tundra/images/checkmarkNoBorder.png
new file mode 100644
index 0000000..9cec0c0
Binary files /dev/null and b/dijit/themes/tundra/images/checkmarkNoBorder.png differ
diff --git a/dijit/themes/tundra/images/circleIcon.gif b/dijit/themes/tundra/images/circleIcon.gif
new file mode 100644
index 0000000..d582290
Binary files /dev/null and b/dijit/themes/tundra/images/circleIcon.gif differ
diff --git a/dijit/themes/tundra/images/circleIcon.png b/dijit/themes/tundra/images/circleIcon.png
new file mode 100644
index 0000000..6f059e6
Binary files /dev/null and b/dijit/themes/tundra/images/circleIcon.png differ
diff --git a/dijit/themes/tundra/images/comboArrowDown.gif b/dijit/themes/tundra/images/comboArrowDown.gif
new file mode 100644
index 0000000..e00a87b
Binary files /dev/null and b/dijit/themes/tundra/images/comboArrowDown.gif differ
diff --git a/dijit/themes/tundra/images/dijitProgressBarAnim.gif b/dijit/themes/tundra/images/dijitProgressBarAnim.gif
new file mode 100644
index 0000000..167a3e0
Binary files /dev/null and b/dijit/themes/tundra/images/dijitProgressBarAnim.gif differ
diff --git a/dijit/themes/tundra/images/dijitProgressBarAnim.psd b/dijit/themes/tundra/images/dijitProgressBarAnim.psd
new file mode 100644
index 0000000..0a7bf23
Binary files /dev/null and b/dijit/themes/tundra/images/dijitProgressBarAnim.psd differ
diff --git a/dijit/themes/tundra/images/dndCopy.png b/dijit/themes/tundra/images/dndCopy.png
new file mode 100644
index 0000000..baecd7c
Binary files /dev/null and b/dijit/themes/tundra/images/dndCopy.png differ
diff --git a/dijit/themes/tundra/images/dndMove.png b/dijit/themes/tundra/images/dndMove.png
new file mode 100644
index 0000000..07f878c
Binary files /dev/null and b/dijit/themes/tundra/images/dndMove.png differ
diff --git a/dijit/themes/tundra/images/dndNoCopy.png b/dijit/themes/tundra/images/dndNoCopy.png
new file mode 100644
index 0000000..9bf9c33
Binary files /dev/null and b/dijit/themes/tundra/images/dndNoCopy.png differ
diff --git a/dijit/themes/tundra/images/dndNoMove.png b/dijit/themes/tundra/images/dndNoMove.png
new file mode 100644
index 0000000..cb8bd8b
Binary files /dev/null and b/dijit/themes/tundra/images/dndNoMove.png differ
diff --git a/dijit/themes/tundra/images/dojoTundraGradientBg.gif b/dijit/themes/tundra/images/dojoTundraGradientBg.gif
new file mode 100644
index 0000000..0da1239
Binary files /dev/null and b/dijit/themes/tundra/images/dojoTundraGradientBg.gif differ
diff --git a/dijit/themes/tundra/images/dojoTundraGradientBg.png b/dijit/themes/tundra/images/dojoTundraGradientBg.png
new file mode 100644
index 0000000..ac118dd
Binary files /dev/null and b/dijit/themes/tundra/images/dojoTundraGradientBg.png differ
diff --git a/dijit/themes/tundra/images/doubleArrowDown.png b/dijit/themes/tundra/images/doubleArrowDown.png
new file mode 100644
index 0000000..92678d2
Binary files /dev/null and b/dijit/themes/tundra/images/doubleArrowDown.png differ
diff --git a/dijit/themes/tundra/images/doubleArrowUp.png b/dijit/themes/tundra/images/doubleArrowUp.png
new file mode 100644
index 0000000..bba30fe
Binary files /dev/null and b/dijit/themes/tundra/images/doubleArrowUp.png differ
diff --git a/dijit/themes/tundra/images/editor.gif b/dijit/themes/tundra/images/editor.gif
new file mode 100644
index 0000000..127c9c4
Binary files /dev/null and b/dijit/themes/tundra/images/editor.gif differ
diff --git a/dijit/themes/tundra/images/editorDisabled.gif b/dijit/themes/tundra/images/editorDisabled.gif
new file mode 100644
index 0000000..9dc5103
Binary files /dev/null and b/dijit/themes/tundra/images/editorDisabled.gif differ
diff --git a/dijit/themes/tundra/images/editorDisabled_rtl.gif b/dijit/themes/tundra/images/editorDisabled_rtl.gif
new file mode 100644
index 0000000..74d407a
Binary files /dev/null and b/dijit/themes/tundra/images/editorDisabled_rtl.gif differ
diff --git a/dijit/themes/tundra/images/editor_rtl.gif b/dijit/themes/tundra/images/editor_rtl.gif
new file mode 100644
index 0000000..b94d040
Binary files /dev/null and b/dijit/themes/tundra/images/editor_rtl.gif differ
diff --git a/dijit/themes/tundra/images/folderClosed.gif b/dijit/themes/tundra/images/folderClosed.gif
new file mode 100644
index 0000000..9d5fcbc
Binary files /dev/null and b/dijit/themes/tundra/images/folderClosed.gif differ
diff --git a/dijit/themes/tundra/images/folderOpened.gif b/dijit/themes/tundra/images/folderOpened.gif
new file mode 100644
index 0000000..a514c7b
Binary files /dev/null and b/dijit/themes/tundra/images/folderOpened.gif differ
diff --git a/dijit/themes/tundra/images/i.gif b/dijit/themes/tundra/images/i.gif
new file mode 100644
index 0000000..ebd95a7
Binary files /dev/null and b/dijit/themes/tundra/images/i.gif differ
diff --git a/dijit/themes/tundra/images/i_half.gif b/dijit/themes/tundra/images/i_half.gif
new file mode 100644
index 0000000..2947c4f
Binary files /dev/null and b/dijit/themes/tundra/images/i_half.gif differ
diff --git a/dijit/themes/tundra/images/i_half_rtl.gif b/dijit/themes/tundra/images/i_half_rtl.gif
new file mode 100644
index 0000000..4f60ec4
Binary files /dev/null and b/dijit/themes/tundra/images/i_half_rtl.gif differ
diff --git a/dijit/themes/tundra/images/i_rtl.gif b/dijit/themes/tundra/images/i_rtl.gif
new file mode 100644
index 0000000..7dafaad
Binary files /dev/null and b/dijit/themes/tundra/images/i_rtl.gif differ
diff --git a/dijit/themes/tundra/images/leaf.gif b/dijit/themes/tundra/images/leaf.gif
new file mode 100644
index 0000000..85b0178
Binary files /dev/null and b/dijit/themes/tundra/images/leaf.gif differ
diff --git a/dijit/themes/tundra/images/loading.gif b/dijit/themes/tundra/images/loading.gif
new file mode 100644
index 0000000..6e7c8e5
Binary files /dev/null and b/dijit/themes/tundra/images/loading.gif differ
diff --git a/dijit/themes/tundra/images/menu.png b/dijit/themes/tundra/images/menu.png
new file mode 100644
index 0000000..f5b93d1
Binary files /dev/null and b/dijit/themes/tundra/images/menu.png differ
diff --git a/dijit/themes/tundra/images/minusButton.gif b/dijit/themes/tundra/images/minusButton.gif
new file mode 100644
index 0000000..48d5172
Binary files /dev/null and b/dijit/themes/tundra/images/minusButton.gif differ
diff --git a/dijit/themes/tundra/images/no.gif b/dijit/themes/tundra/images/no.gif
new file mode 100644
index 0000000..9021a14
Binary files /dev/null and b/dijit/themes/tundra/images/no.gif differ
diff --git a/dijit/themes/tundra/images/noX.gif b/dijit/themes/tundra/images/noX.gif
new file mode 100644
index 0000000..4a16dc7
Binary files /dev/null and b/dijit/themes/tundra/images/noX.gif differ
diff --git a/dijit/themes/tundra/images/plusButton.gif b/dijit/themes/tundra/images/plusButton.gif
new file mode 100644
index 0000000..103c021
Binary files /dev/null and b/dijit/themes/tundra/images/plusButton.gif differ
diff --git a/dijit/themes/tundra/images/popupMenuBg.gif b/dijit/themes/tundra/images/popupMenuBg.gif
new file mode 100644
index 0000000..15f4f1b
Binary files /dev/null and b/dijit/themes/tundra/images/popupMenuBg.gif differ
diff --git a/dijit/themes/tundra/images/preciseSliderThumb.gif b/dijit/themes/tundra/images/preciseSliderThumb.gif
new file mode 100644
index 0000000..15d4879
Binary files /dev/null and b/dijit/themes/tundra/images/preciseSliderThumb.gif differ
diff --git a/dijit/themes/tundra/images/preciseSliderThumb.png b/dijit/themes/tundra/images/preciseSliderThumb.png
new file mode 100644
index 0000000..f2fc338
Binary files /dev/null and b/dijit/themes/tundra/images/preciseSliderThumb.png differ
diff --git a/dijit/themes/tundra/images/preciseSliderThumbFocus.gif b/dijit/themes/tundra/images/preciseSliderThumbFocus.gif
new file mode 100644
index 0000000..b44611c
Binary files /dev/null and b/dijit/themes/tundra/images/preciseSliderThumbFocus.gif differ
diff --git a/dijit/themes/tundra/images/preciseSliderThumbFocus.png b/dijit/themes/tundra/images/preciseSliderThumbFocus.png
new file mode 100644
index 0000000..fb06323
Binary files /dev/null and b/dijit/themes/tundra/images/preciseSliderThumbFocus.png differ
diff --git a/dijit/themes/tundra/images/progressBarAnim-1.png b/dijit/themes/tundra/images/progressBarAnim-1.png
new file mode 100644
index 0000000..cfc3fd2
Binary files /dev/null and b/dijit/themes/tundra/images/progressBarAnim-1.png differ
diff --git a/dijit/themes/tundra/images/progressBarAnim-2.png b/dijit/themes/tundra/images/progressBarAnim-2.png
new file mode 100644
index 0000000..d27981d
Binary files /dev/null and b/dijit/themes/tundra/images/progressBarAnim-2.png differ
diff --git a/dijit/themes/tundra/images/progressBarAnim-3.png b/dijit/themes/tundra/images/progressBarAnim-3.png
new file mode 100644
index 0000000..3b92a7d
Binary files /dev/null and b/dijit/themes/tundra/images/progressBarAnim-3.png differ
diff --git a/dijit/themes/tundra/images/progressBarAnim-4.png b/dijit/themes/tundra/images/progressBarAnim-4.png
new file mode 100644
index 0000000..61e4276
Binary files /dev/null and b/dijit/themes/tundra/images/progressBarAnim-4.png differ
diff --git a/dijit/themes/tundra/images/progressBarAnim-5.png b/dijit/themes/tundra/images/progressBarAnim-5.png
new file mode 100644
index 0000000..48b189a
Binary files /dev/null and b/dijit/themes/tundra/images/progressBarAnim-5.png differ
diff --git a/dijit/themes/tundra/images/progressBarAnim-6.png b/dijit/themes/tundra/images/progressBarAnim-6.png
new file mode 100644
index 0000000..af50c4d
Binary files /dev/null and b/dijit/themes/tundra/images/progressBarAnim-6.png differ
diff --git a/dijit/themes/tundra/images/progressBarAnim-7.png b/dijit/themes/tundra/images/progressBarAnim-7.png
new file mode 100644
index 0000000..a4fffa3
Binary files /dev/null and b/dijit/themes/tundra/images/progressBarAnim-7.png differ
diff --git a/dijit/themes/tundra/images/progressBarAnim-8.png b/dijit/themes/tundra/images/progressBarAnim-8.png
new file mode 100644
index 0000000..b4c92f3
Binary files /dev/null and b/dijit/themes/tundra/images/progressBarAnim-8.png differ
diff --git a/dijit/themes/tundra/images/progressBarAnim-9.png b/dijit/themes/tundra/images/progressBarAnim-9.png
new file mode 100644
index 0000000..d8bff13
Binary files /dev/null and b/dijit/themes/tundra/images/progressBarAnim-9.png differ
diff --git a/dijit/themes/tundra/images/progressBarAnim.gif b/dijit/themes/tundra/images/progressBarAnim.gif
new file mode 100644
index 0000000..d3df139
Binary files /dev/null and b/dijit/themes/tundra/images/progressBarAnim.gif differ
diff --git a/dijit/themes/tundra/images/progressBarAnim.psd b/dijit/themes/tundra/images/progressBarAnim.psd
new file mode 100644
index 0000000..0a7bf23
Binary files /dev/null and b/dijit/themes/tundra/images/progressBarAnim.psd differ
diff --git a/dijit/themes/tundra/images/progressBarEmpty.png b/dijit/themes/tundra/images/progressBarEmpty.png
new file mode 100644
index 0000000..07f4c91
Binary files /dev/null and b/dijit/themes/tundra/images/progressBarEmpty.png differ
diff --git a/dijit/themes/tundra/images/progressBarFull.png b/dijit/themes/tundra/images/progressBarFull.png
new file mode 100644
index 0000000..0ce60f5
Binary files /dev/null and b/dijit/themes/tundra/images/progressBarFull.png differ
diff --git a/dijit/themes/tundra/images/radioButtonActive.png b/dijit/themes/tundra/images/radioButtonActive.png
new file mode 100644
index 0000000..60840c7
Binary files /dev/null and b/dijit/themes/tundra/images/radioButtonActive.png differ
diff --git a/dijit/themes/tundra/images/radioButtonActiveDisabled.png b/dijit/themes/tundra/images/radioButtonActiveDisabled.png
new file mode 100644
index 0000000..b49724e
Binary files /dev/null and b/dijit/themes/tundra/images/radioButtonActiveDisabled.png differ
diff --git a/dijit/themes/tundra/images/radioButtonActiveHover.png b/dijit/themes/tundra/images/radioButtonActiveHover.png
new file mode 100644
index 0000000..f21d4e5
Binary files /dev/null and b/dijit/themes/tundra/images/radioButtonActiveHover.png differ
diff --git a/dijit/themes/tundra/images/radioButtonDisabled.png b/dijit/themes/tundra/images/radioButtonDisabled.png
new file mode 100644
index 0000000..8da7e78
Binary files /dev/null and b/dijit/themes/tundra/images/radioButtonDisabled.png differ
diff --git a/dijit/themes/tundra/images/radioButtonEnabled.png b/dijit/themes/tundra/images/radioButtonEnabled.png
new file mode 100644
index 0000000..4342fea
Binary files /dev/null and b/dijit/themes/tundra/images/radioButtonEnabled.png differ
diff --git a/dijit/themes/tundra/images/radioButtonHover.png b/dijit/themes/tundra/images/radioButtonHover.png
new file mode 100644
index 0000000..fcb697f
Binary files /dev/null and b/dijit/themes/tundra/images/radioButtonHover.png differ
diff --git a/dijit/themes/tundra/images/sliderEmpty.png b/dijit/themes/tundra/images/sliderEmpty.png
new file mode 100644
index 0000000..070c12f
Binary files /dev/null and b/dijit/themes/tundra/images/sliderEmpty.png differ
diff --git a/dijit/themes/tundra/images/sliderEmptyVertical.png b/dijit/themes/tundra/images/sliderEmptyVertical.png
new file mode 100644
index 0000000..45aceb7
Binary files /dev/null and b/dijit/themes/tundra/images/sliderEmptyVertical.png differ
diff --git a/dijit/themes/tundra/images/sliderFull.png b/dijit/themes/tundra/images/sliderFull.png
new file mode 100644
index 0000000..4b3fcbb
Binary files /dev/null and b/dijit/themes/tundra/images/sliderFull.png differ
diff --git a/dijit/themes/tundra/images/sliderFullFocus.png b/dijit/themes/tundra/images/sliderFullFocus.png
new file mode 100644
index 0000000..ee19356
Binary files /dev/null and b/dijit/themes/tundra/images/sliderFullFocus.png differ
diff --git a/dijit/themes/tundra/images/sliderFullVertical.png b/dijit/themes/tundra/images/sliderFullVertical.png
new file mode 100644
index 0000000..e7618e8
Binary files /dev/null and b/dijit/themes/tundra/images/sliderFullVertical.png differ
diff --git a/dijit/themes/tundra/images/sliderFullVerticalFocus.png b/dijit/themes/tundra/images/sliderFullVerticalFocus.png
new file mode 100644
index 0000000..3ab37e6
Binary files /dev/null and b/dijit/themes/tundra/images/sliderFullVerticalFocus.png differ
diff --git a/dijit/themes/tundra/images/sliderThumb.png b/dijit/themes/tundra/images/sliderThumb.png
new file mode 100644
index 0000000..fe33583
Binary files /dev/null and b/dijit/themes/tundra/images/sliderThumb.png differ
diff --git a/dijit/themes/tundra/images/sliderThumbFocus.gif b/dijit/themes/tundra/images/sliderThumbFocus.gif
new file mode 100644
index 0000000..15dd3d9
Binary files /dev/null and b/dijit/themes/tundra/images/sliderThumbFocus.gif differ
diff --git a/dijit/themes/tundra/images/sliderThumbFocus.png b/dijit/themes/tundra/images/sliderThumbFocus.png
new file mode 100644
index 0000000..fe9763a
Binary files /dev/null and b/dijit/themes/tundra/images/sliderThumbFocus.png differ
diff --git a/dijit/themes/tundra/images/smallArrowDown.png b/dijit/themes/tundra/images/smallArrowDown.png
new file mode 100644
index 0000000..cabd01c
Binary files /dev/null and b/dijit/themes/tundra/images/smallArrowDown.png differ
diff --git a/dijit/themes/tundra/images/smallArrowUp.png b/dijit/themes/tundra/images/smallArrowUp.png
new file mode 100644
index 0000000..a4dd670
Binary files /dev/null and b/dijit/themes/tundra/images/smallArrowUp.png differ
diff --git a/dijit/themes/tundra/images/splitContainerSizerH-thumb.png b/dijit/themes/tundra/images/splitContainerSizerH-thumb.png
new file mode 100644
index 0000000..e7bc204
Binary files /dev/null and b/dijit/themes/tundra/images/splitContainerSizerH-thumb.png differ
diff --git a/dijit/themes/tundra/images/splitContainerSizerH.png b/dijit/themes/tundra/images/splitContainerSizerH.png
new file mode 100644
index 0000000..0e5e471
Binary files /dev/null and b/dijit/themes/tundra/images/splitContainerSizerH.png differ
diff --git a/dijit/themes/tundra/images/splitContainerSizerV-thumb.png b/dijit/themes/tundra/images/splitContainerSizerV-thumb.png
new file mode 100644
index 0000000..410a0a7
Binary files /dev/null and b/dijit/themes/tundra/images/splitContainerSizerV-thumb.png differ
diff --git a/dijit/themes/tundra/images/splitContainerSizerV.png b/dijit/themes/tundra/images/splitContainerSizerV.png
new file mode 100644
index 0000000..6781f0e
Binary files /dev/null and b/dijit/themes/tundra/images/splitContainerSizerV.png differ
diff --git a/dijit/themes/tundra/images/spriteArrows.gif b/dijit/themes/tundra/images/spriteArrows.gif
new file mode 100644
index 0000000..56a37f4
Binary files /dev/null and b/dijit/themes/tundra/images/spriteArrows.gif differ
diff --git a/dijit/themes/tundra/images/spriteArrows.png b/dijit/themes/tundra/images/spriteArrows.png
new file mode 100644
index 0000000..e0229c9
Binary files /dev/null and b/dijit/themes/tundra/images/spriteArrows.png differ
diff --git a/dijit/themes/tundra/images/spriteRoundedIconsSmall.gif b/dijit/themes/tundra/images/spriteRoundedIconsSmall.gif
new file mode 100644
index 0000000..251389a
Binary files /dev/null and b/dijit/themes/tundra/images/spriteRoundedIconsSmall.gif differ
diff --git a/dijit/themes/tundra/images/spriteRoundedIconsSmall.png b/dijit/themes/tundra/images/spriteRoundedIconsSmall.png
new file mode 100644
index 0000000..e81ba07
Binary files /dev/null and b/dijit/themes/tundra/images/spriteRoundedIconsSmall.png differ
diff --git a/dijit/themes/tundra/images/tabActive.png b/dijit/themes/tundra/images/tabActive.png
new file mode 100644
index 0000000..eaf1ed4
Binary files /dev/null and b/dijit/themes/tundra/images/tabActive.png differ
diff --git a/dijit/themes/tundra/images/tabClose.gif b/dijit/themes/tundra/images/tabClose.gif
new file mode 100644
index 0000000..2cb0ee1
Binary files /dev/null and b/dijit/themes/tundra/images/tabClose.gif differ
diff --git a/dijit/themes/tundra/images/tabClose.png b/dijit/themes/tundra/images/tabClose.png
new file mode 100644
index 0000000..136cd22
Binary files /dev/null and b/dijit/themes/tundra/images/tabClose.png differ
diff --git a/dijit/themes/tundra/images/tabCloseHover.gif b/dijit/themes/tundra/images/tabCloseHover.gif
new file mode 100644
index 0000000..f59471e
Binary files /dev/null and b/dijit/themes/tundra/images/tabCloseHover.gif differ
diff --git a/dijit/themes/tundra/images/tabCloseHover.png b/dijit/themes/tundra/images/tabCloseHover.png
new file mode 100644
index 0000000..290e77f
Binary files /dev/null and b/dijit/themes/tundra/images/tabCloseHover.png differ
diff --git a/dijit/themes/tundra/images/tabDisabled.png b/dijit/themes/tundra/images/tabDisabled.png
new file mode 100644
index 0000000..ea0f617
Binary files /dev/null and b/dijit/themes/tundra/images/tabDisabled.png differ
diff --git a/dijit/themes/tundra/images/tabEnabled.png b/dijit/themes/tundra/images/tabEnabled.png
new file mode 100644
index 0000000..d40cf45
Binary files /dev/null and b/dijit/themes/tundra/images/tabEnabled.png differ
diff --git a/dijit/themes/tundra/images/tabHover.gif b/dijit/themes/tundra/images/tabHover.gif
new file mode 100644
index 0000000..471e0ee
Binary files /dev/null and b/dijit/themes/tundra/images/tabHover.gif differ
diff --git a/dijit/themes/tundra/images/tabHover.png b/dijit/themes/tundra/images/tabHover.png
new file mode 100644
index 0000000..16487f1
Binary files /dev/null and b/dijit/themes/tundra/images/tabHover.png differ
diff --git a/dijit/themes/tundra/images/titleBar.png b/dijit/themes/tundra/images/titleBar.png
new file mode 100644
index 0000000..617d9d4
Binary files /dev/null and b/dijit/themes/tundra/images/titleBar.png differ
diff --git a/dijit/themes/tundra/images/titleBarBg.gif b/dijit/themes/tundra/images/titleBarBg.gif
new file mode 100644
index 0000000..1cd57cf
Binary files /dev/null and b/dijit/themes/tundra/images/titleBarBg.gif differ
diff --git a/dijit/themes/tundra/images/tooltipConnectorDown.gif b/dijit/themes/tundra/images/tooltipConnectorDown.gif
new file mode 100644
index 0000000..18b2795
Binary files /dev/null and b/dijit/themes/tundra/images/tooltipConnectorDown.gif differ
diff --git a/dijit/themes/tundra/images/tooltipConnectorDown.png b/dijit/themes/tundra/images/tooltipConnectorDown.png
new file mode 100644
index 0000000..1aff5a3
Binary files /dev/null and b/dijit/themes/tundra/images/tooltipConnectorDown.png differ
diff --git a/dijit/themes/tundra/images/tooltipConnectorLeft.gif b/dijit/themes/tundra/images/tooltipConnectorLeft.gif
new file mode 100644
index 0000000..3d9cbc5
Binary files /dev/null and b/dijit/themes/tundra/images/tooltipConnectorLeft.gif differ
diff --git a/dijit/themes/tundra/images/tooltipConnectorLeft.png b/dijit/themes/tundra/images/tooltipConnectorLeft.png
new file mode 100644
index 0000000..e68fec3
Binary files /dev/null and b/dijit/themes/tundra/images/tooltipConnectorLeft.png differ
diff --git a/dijit/themes/tundra/images/tooltipConnectorRight.gif b/dijit/themes/tundra/images/tooltipConnectorRight.gif
new file mode 100644
index 0000000..2b887f7
Binary files /dev/null and b/dijit/themes/tundra/images/tooltipConnectorRight.gif differ
diff --git a/dijit/themes/tundra/images/tooltipConnectorRight.png b/dijit/themes/tundra/images/tooltipConnectorRight.png
new file mode 100644
index 0000000..dc2434a
Binary files /dev/null and b/dijit/themes/tundra/images/tooltipConnectorRight.png differ
diff --git a/dijit/themes/tundra/images/tooltipConnectorUp.gif b/dijit/themes/tundra/images/tooltipConnectorUp.gif
new file mode 100644
index 0000000..d0cad8a
Binary files /dev/null and b/dijit/themes/tundra/images/tooltipConnectorUp.gif differ
diff --git a/dijit/themes/tundra/images/tooltipConnectorUp.png b/dijit/themes/tundra/images/tooltipConnectorUp.png
new file mode 100644
index 0000000..55a378b
Binary files /dev/null and b/dijit/themes/tundra/images/tooltipConnectorUp.png differ
diff --git a/dijit/themes/tundra/images/treeExpand_leaf.gif b/dijit/themes/tundra/images/treeExpand_leaf.gif
new file mode 100644
index 0000000..4b1c6c1
Binary files /dev/null and b/dijit/themes/tundra/images/treeExpand_leaf.gif differ
diff --git a/dijit/themes/tundra/images/treeExpand_leaf_rtl.gif b/dijit/themes/tundra/images/treeExpand_leaf_rtl.gif
new file mode 100644
index 0000000..b563d7c
Binary files /dev/null and b/dijit/themes/tundra/images/treeExpand_leaf_rtl.gif differ
diff --git a/dijit/themes/tundra/images/treeExpand_loading.gif b/dijit/themes/tundra/images/treeExpand_loading.gif
new file mode 100644
index 0000000..424d376
Binary files /dev/null and b/dijit/themes/tundra/images/treeExpand_loading.gif differ
diff --git a/dijit/themes/tundra/images/treeExpand_minus.gif b/dijit/themes/tundra/images/treeExpand_minus.gif
new file mode 100644
index 0000000..5977782
Binary files /dev/null and b/dijit/themes/tundra/images/treeExpand_minus.gif differ
diff --git a/dijit/themes/tundra/images/treeExpand_minus_rtl.gif b/dijit/themes/tundra/images/treeExpand_minus_rtl.gif
new file mode 100644
index 0000000..cf50054
Binary files /dev/null and b/dijit/themes/tundra/images/treeExpand_minus_rtl.gif differ
diff --git a/dijit/themes/tundra/images/treeExpand_mius.gif b/dijit/themes/tundra/images/treeExpand_mius.gif
new file mode 100644
index 0000000..5977782
Binary files /dev/null and b/dijit/themes/tundra/images/treeExpand_mius.gif differ
diff --git a/dijit/themes/tundra/images/treeExpand_plus.gif b/dijit/themes/tundra/images/treeExpand_plus.gif
new file mode 100644
index 0000000..2b96a55
Binary files /dev/null and b/dijit/themes/tundra/images/treeExpand_plus.gif differ
diff --git a/dijit/themes/tundra/images/treeExpand_plus_rtl.gif b/dijit/themes/tundra/images/treeExpand_plus_rtl.gif
new file mode 100644
index 0000000..11f9916
Binary files /dev/null and b/dijit/themes/tundra/images/treeExpand_plus_rtl.gif differ
diff --git a/dijit/themes/tundra/images/treeHover.png b/dijit/themes/tundra/images/treeHover.png
new file mode 100644
index 0000000..cd6d28b
Binary files /dev/null and b/dijit/themes/tundra/images/treeHover.png differ
diff --git a/dijit/themes/tundra/images/validationInputBg.gif b/dijit/themes/tundra/images/validationInputBg.gif
new file mode 100644
index 0000000..5a9916a
Binary files /dev/null and b/dijit/themes/tundra/images/validationInputBg.gif differ
diff --git a/dijit/themes/tundra/images/validationInputBg.png b/dijit/themes/tundra/images/validationInputBg.png
new file mode 100644
index 0000000..d222fb4
Binary files /dev/null and b/dijit/themes/tundra/images/validationInputBg.png differ
diff --git a/dijit/themes/tundra/images/warning.png b/dijit/themes/tundra/images/warning.png
new file mode 100644
index 0000000..c52f83d
Binary files /dev/null and b/dijit/themes/tundra/images/warning.png differ
diff --git a/dijit/themes/tundra/layout/AccordionContainer.css b/dijit/themes/tundra/layout/AccordionContainer.css
new file mode 100644
index 0000000..a96f49f
--- /dev/null
+++ b/dijit/themes/tundra/layout/AccordionContainer.css
@@ -0,0 +1,22 @@
+
+.tundra .dijitAccordionContainer {
+	border-color: #ccc;
+	background-color: #fff;
+}
+.tundra .dijitAccordionTitle {
+	background:#fafafa url("../images/titleBar.png") repeat-x bottom left;
+	border-top: 1px solid #bfbfbf;
+	padding: 4px 4px 4px 8px;
+	cursor:pointer;
+}
+.tundra .dijitAccordionTitle-hover  {
+	background: #f8fafd url("../images/accordionItemHover.gif") bottom repeat-x;
+}
+.tundra .dijitAccordionTitle-selected  {
+	background: #f9f9f9 url("../images/accordionItemActive.gif") bottom repeat-x;
+	font-weight: bold;
+	border-top: 1px solid #aaaaaa;
+	border-bottom: 1px solid #bfbfbf;
+	padding: 4px 4px 4px 8px;
+	cursor: default;
+}
diff --git a/dijit/themes/tundra/layout/BorderContainer.css b/dijit/themes/tundra/layout/BorderContainer.css
new file mode 100644
index 0000000..22ec672
--- /dev/null
+++ b/dijit/themes/tundra/layout/BorderContainer.css
@@ -0,0 +1,55 @@
+
+.tundra .dijitBorderContainer {
+	background-color: #fcfcfc;
+	padding: 5px;
+}
+.tundra .dijitSplitContainer-child,
+.tundra .dijitBorderContainer-child {
+	
+	border: 1px #ccc solid;
+}
+.tundra .dijitBorderContainer-dijitTabContainerTop,
+.tundra .dijitBorderContainer-dijitTabContainerBottom,
+.tundra .dijitBorderContainer-dijitTabContainerLeft,
+.tundra .dijitBorderContainer-dijitTabContainerRight {
+	
+	 border: none;
+}
+.tundra .dijitBorderContainer-dijitBorderContainer {
+	
+	border: none;
+	padding: 0px;
+}
+.tundra .dijitSplitterH,
+.tundra .dijitGutterH {
+	background:#fcfcfc;
+	border:0;
+	height:5px;
+}
+.tundra .dijitSplitterH .dijitSplitterThumb {
+	background:url("../images/splitContainerSizerH-thumb.png") no-repeat;
+	top:1px;
+	width:19px;
+	height:2px;
+}
+.tundra .dijitSplitterV,
+.tundra .dijitGutterV {
+	background:#fcfcfc;
+	border:0;
+	width:5px;
+}
+.tundra .dijitSplitterV .dijitSplitterThumb {
+	background:url("../images/splitContainerSizerV-thumb.png") no-repeat;
+	left:1px;
+	height:19px;
+	width:5px;
+}
+.tundra .dijitSplitterActive {
+	font-size: 1px;
+	background-image: none;
+	background-color: #aaa;
+	-moz-opacity: 0.6;
+	opacity: 0.6;
+	filter: Alpha(Opacity=60);
+	margin: 0;
+}
diff --git a/dijit/themes/tundra/layout/ContentPane.css b/dijit/themes/tundra/layout/ContentPane.css
new file mode 100644
index 0000000..8b470b9
--- /dev/null
+++ b/dijit/themes/tundra/layout/ContentPane.css
@@ -0,0 +1,17 @@
+
+.tundra .dijitContentPane {
+	padding: 0px;
+}
+.tundra .dijitTabContainerTop-dijitContentPane,
+.tundra .dijitTabContainerLeft-dijitContentPane,
+.tundra .dijitTabContainerBottom-dijitContentPane,
+.tundra .dijitTabContainerRight-dijitContentPane,
+.tundra .dijitAccordionContainer-dijitContentPane {
+	background-color: #fff;
+	padding: 5px;
+}
+.tundra .dijitSplitContainer-dijitContentPane,
+.tundra .dijitBorderContainer-dijitContentPane {
+	background-color: #fff;		
+	padding: 5px;
+}
diff --git a/dijit/themes/tundra/layout/SplitContainer.css b/dijit/themes/tundra/layout/SplitContainer.css
new file mode 100644
index 0000000..b9945d6
--- /dev/null
+++ b/dijit/themes/tundra/layout/SplitContainer.css
@@ -0,0 +1,31 @@
+.tundra .dijitSplitContainerSizerH {
+	background:url("../images/splitContainerSizerV.png") repeat-y #fff;
+	border:0;
+	border-left:1px solid #bfbfbf;
+	border-right:1px solid #bfbfbf;
+	width:7px;
+}
+.tundra .dijitSplitContainerSizerH .thumb {
+	background:url("../images/splitContainerSizerV-thumb.png") no-repeat #ccc;
+	left:1px;
+	width:3px;
+	height:19px;
+	overflow: hidden;
+}
+.tundra .dijitSplitContainerSizerV {
+	background:url("../images/splitContainerSizerH.png") repeat-x #fff;
+	border:0;
+	border-top:1px solid #bfbfbf;
+	border-bottom:1px solid #bfbfbf;
+	height:7px;
+}
+.tundra .dijitSplitContainerSizerV .thumb {
+	background:url("../images/splitContainerSizerH-thumb.png") no-repeat #ccc;
+	top:1px;
+	width:19px;
+	height:3px;
+	overflow: hidden;
+}
+.tundra .dijitSplitter {
+	border-color: #bfbfbf;
+}
diff --git a/dijit/themes/tundra/layout/TabContainer.css b/dijit/themes/tundra/layout/TabContainer.css
new file mode 100644
index 0000000..4307abb
--- /dev/null
+++ b/dijit/themes/tundra/layout/TabContainer.css
@@ -0,0 +1,174 @@
+
+.tundra .dijitTabPaneWrapper {
+	background:#fff;
+	border:1px solid #ccc;
+	margin: 0;
+	padding: 0;
+}
+.tundra .dijitTab {
+	line-height:normal;
+	margin-right:4px;	
+	padding:0px;
+	border:1px solid #ccc;
+	background:#e2e2e2 url("../images/tabEnabled.png") repeat-x;
+}
+.tundra .dijitTabInnerDiv {
+	padding:6px 8px 5px 9px;
+}
+.dijitTabSpacer {
+	font-size: 1px;
+}
+.tundra .dijitTabChecked {
+	
+	background-color:#fff;
+	border-color: #ccc;
+	background-image:none;
+}
+.tundra .dijitTabHover {
+	color: #243C5F;
+	border-top-color:#92a0b3;
+	border-left-color:#92a0b3;
+	border-right-color:#92a0b3;
+	background:#e2e2e2 url("../images/tabHover.gif") repeat-x;
+}
+.tundra .dijitTabCheckedHover {
+	color: inherit;
+	border:1px solid #ccc;
+	background:#fff;
+}
+.tundra .dijitTab .dijitClosable .closeImage {
+	background: url("../images/tabClose.png") no-repeat right top;
+	width: 12px;
+	height: 12px;
+}
+.tundra .dijitTab .dijitTabButtonSpacer {
+	
+	height: 12px;
+	width: 1px;
+}
+.tundra .dijitTabContainerTabListNested .dijitTab {
+	background: none;
+	border: none;
+	top: 0px;		 
+}
+.tundra .dijitTabContainerTabListNested .dijitTab .dijitTabContent {
+}
+.tundra .dijitTabContainerTabListNested .dijitTabHover .dijitTabContent .tabLabel {
+	text-decoration: underline;
+}
+.tundra .dijitTabContainerTabListNested .dijitTabChecked .dijitTabContent .tabLabel {
+	text-decoration: underline;
+	font-weight: bold;
+	
+}
+.tundra .dijitTabContainer .dijitTabPaneWrapperNested {
+	border: none;	
+}
+.tundra .dijitTab .closeImage {
+	background-image : url("../images/tabClose.png");
+}
+.dj_ie6 .tundra .dijitTab .closeImage {
+	background-image : url("../images/tabClose.gif");
+}
+.tundra .dijitTab .closeButton-hover .closeImage {
+	background-image : url("../images/tabCloseHover.png");
+}
+.dj_ie6 .tundra .dijitTab .closeButton-hover .closeImage {
+	background-image : url("../images/tabCloseHover.gif");
+}
+.tundra .dijitTabContainerTop-tabs {
+	margin-bottom: -1px;
+	border-color: #ccc;
+}
+.tundra .dijitTabContainerTop-container {
+	border-top: none;
+}
+.tundra .dijitTabContainerTop-tabs .dijitTabChecked {
+	border-bottom-color:white;
+}
+.tundra .dijitTabContainerTopStrip {
+	border: 1px solid #ccc;
+	padding-top: 2px;
+	padding-left: 3px;
+}
+.tundra .dijitTabContainerTopStrip {
+	background: #f2f2f2;
+}
+.tundra .dijitTabContainerBottom-tabs {
+	margin-top: -1px;
+	border-color: #ccc;
+}
+.tundra .dijitTabContainerBottom-container {
+	border-bottom: none;
+}
+.tundra .dijitTabContainerBottom-tabs .dijitTabChecked {
+	border-top-color:white;
+}
+.tundra .dijitTabContainerBottomStrip {
+	padding-bottom: 2px;
+	padding-left: 3px;	
+	border: 1px solid #ccc;
+}
+.tundra .dijitTabContainerBottomStrip {
+	background: #f2f2f2;
+}
+.tundra .dijitTabContainerBottom-spacer,
+.tundra .dijitTabContainerTop-spacer {
+	height: 0px;
+	border-top: 1px solid #ccc;
+	background: #fff;
+}
+.tundra .dijitTabContainerRight-tabs {
+	margin-left: -1px;
+	border-color: #ccc;
+}
+.tundra .dijitTabContainerRight-container {
+	border-right: none;
+}
+.tundra .dijitTabContainerRight-tabs .dijitTabChecked {
+	border-left-color:white;
+}
+.tundra .dijitTabContainerRightStrip {
+	padding-right: 2px;
+	padding-top: 3px;	
+	border: 1px solid #ccc;
+}
+.tundra .dijitTabContainerRightStrip {
+	background: #f2f2f2;
+}
+.tundra .dijitTabContainerLeft-tabs {
+	margin-right: -1px;
+	border-color: #ccc;
+}
+.tundra .dijitTabContainerLeft-container {
+	border-left: none;
+}
+.tundra .dijitTabContainerLeft-tabs .dijitTabChecked {
+	border-right-color:white;
+}
+.tundra .dijitTabContainerLeftStrip {
+	padding-left: 2px;
+	padding-top: 3px;	
+	border: 1px solid #ccc;
+}
+.tundra .dijitTabContainerLeftStrip {
+	background: #f2f2f2;
+}
+.tundra .dijitTabContainerLeft-tabs .dijitTab,
+.tundra .dijitTabContainerRight-tabs .dijitTab {
+	margin-right:0px;
+	margin-bottom:4px;	
+}
+.tundra .dijitTabContainerLeft-spacer,
+.tundra .dijitTabContainerRight-spacer {
+	width: 0px;
+	border-left: 1px solid #ccc;
+	background: #fff;
+}
+.tundra .dijitTabContainerTop-dijitContentPane .dijitTabContainerTop-tabs {
+	border-left: 0px solid #ccc;
+	border-top: 0px solid #ccc;
+	border-right: 0px solid #ccc;
+	padding-top: 0px;
+	padding-left: 0px;	
+}
diff --git a/dijit/themes/tundra/layout/TabContainer_rtl.css b/dijit/themes/tundra/layout/TabContainer_rtl.css
new file mode 100644
index 0000000..f0ba45d
--- /dev/null
+++ b/dijit/themes/tundra/layout/TabContainer_rtl.css
@@ -0,0 +1,30 @@
+.dijitRtl .tundra .dijitTab {
+	margin-right:auto;
+	margin-left:4px;		
+	-moz-box-orient:horizontal;
+	text-align: right;
+}
+.dijitRtl .tundra .dijitTabContainerTopStrip,
+.dijitRtl .tundra .dijitTabContainerBottomStrip {
+	padding-right: 3px;
+	padding-left: 0px;
+}
+.dijitRtl .tundra .dijitTabInnerDiv {
+	padding:6px 9px 5px 8px;
+}
+.dijitRtl .tundra .dijitTabPaneWrapper {
+	#zoom: 1;
+}
+.dj_ie-rtl .tundra .dijitTabContainerLeft-tabs {
+	margin-left: 1px !important;
+}
+.dj_ie-rtl .tundra .dijitTabContainerRight-tabs {
+	margin-right: 1px !important;
+}
+.dijitRtl .tundra .dijitTabContainerLeft-tabs .dijitTab,
+.dijitRtl .tundra .dijitTabContainerRight-tabs .dijitTab {
+	margin-left:0px;
+}
+.dj_ie-rtl .tundra .dijitTab .dijitTabInnerDiv {
+	width : 1% !important;
+}
diff --git a/dijit/themes/tundra/tundra.css b/dijit/themes/tundra/tundra.css
new file mode 100644
index 0000000..cc8d0d9
--- /dev/null
+++ b/dijit/themes/tundra/tundra.css
@@ -0,0 +1,1614 @@
+
+ at import url("../dijit.css");
+.tundra .dojoDndItemBefore {
+	border-top: 2px solid #369;
+}
+.tundra .dojoDndItemAfter {
+	border-bottom: 2px solid #369;
+}
+.tundra .dojoDndItemOver {
+	cursor:pointer;
+}
+.tundra table.dojoDndAvatar { -moz-border-radius: 0; border: 1px solid #ccc; border-collapse: collapse; background-color: #fff; font-size: 75%; color: black;}
+.tundra .dojoDndAvatar td	{ border: none; }
+.tundra .dojoDndAvatar tr	{ border: none; }
+.tundra .dojoDndAvatarHeader td	{ height: 20px; padding: 0 0 0 21px; }
+.tundra .dojoDndAvatarItem td { padding: 2px;}
+.tundra.dojoDndMove .dojoDndAvatarHeader	{background-color: #f58383; background-image: url(images/dndNoMove.png); background-repeat: no-repeat; background-position: 2px center;}
+.tundra.dojoDndCopy .dojoDndAvatarHeader	{background-color: #f58383; background-image: url(images/dndNoCopy.png); background-repeat: no-repeat; background-position: 2px center;}
+.tundra.dojoDndMove .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{background-color: #97e68d; background-image: url(images/dndMove.png); background-repeat: no-repeat; background-position: 2px center;}
+.tundra.dojoDndCopy .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{background-color: #97e68d; background-image: url(images/dndCopy.png); background-repeat: no-repeat; background-position: 2px center;}
+.tundra .dijitContentPaneLoading {
+	background:url(images/loading.gif) no-repeat left center;
+	padding-left:25px;
+}
+.tundra .dijitContentPaneError {
+	background:url(images/warning.png) no-repeat left center;
+	padding-left:25px;
+}
+.tundra .dijitContentPane {
+	padding: 0px;
+}
+.tundra .dijitTabContainerTop-dijitContentPane,
+.tundra .dijitTabContainerLeft-dijitContentPane,
+.tundra .dijitTabContainerBottom-dijitContentPane,
+.tundra .dijitTabContainerRight-dijitContentPane,
+.tundra .dijitAccordionContainer-dijitContentPane {
+	background-color: #fff;
+	padding: 5px;
+}
+.tundra .dijitSplitContainer-dijitContentPane,
+.tundra .dijitBorderContainer-dijitContentPane {
+	background-color: #fff;		
+	padding: 5px;
+}
+.tundra .dijitTabPaneWrapper {
+	background:#fff;
+	border:1px solid #ccc;
+	margin: 0;
+	padding: 0;
+}
+.tundra .dijitTab {
+	line-height:normal;
+	margin-right:4px;	
+	padding:0px;
+	border:1px solid #ccc;
+	background:#e2e2e2 url(images/tabEnabled.png) repeat-x;
+}
+.tundra .dijitTabInnerDiv {
+	padding:6px 8px 5px 9px;
+}
+.dijitTabSpacer {
+	font-size: 1px;
+}
+.tundra .dijitTabChecked {
+	
+	background-color:#fff;
+	border-color: #ccc;
+	background-image:none;
+}
+.tundra .dijitTabHover {
+	color: #243C5F;
+	border-top-color:#92a0b3;
+	border-left-color:#92a0b3;
+	border-right-color:#92a0b3;
+	background:#e2e2e2 url(images/tabHover.gif) repeat-x;
+}
+.tundra .dijitTabCheckedHover {
+	color: inherit;
+	border:1px solid #ccc;
+	background:#fff;
+}
+.tundra .dijitTab .dijitClosable .closeImage {
+	background: url(images/tabClose.png) no-repeat right top;
+	width: 12px;
+	height: 12px;
+}
+.tundra .dijitTab .dijitTabButtonSpacer {
+	
+	height: 12px;
+	width: 1px;
+}
+.tundra .dijitTabContainerTabListNested .dijitTab {
+	background: none;
+	border: none;
+	top: 0px;		 
+}
+.tundra .dijitTabContainerTabListNested .dijitTab .dijitTabContent {
+}
+.tundra .dijitTabContainerTabListNested .dijitTabHover .dijitTabContent .tabLabel {
+	text-decoration: underline;
+}
+.tundra .dijitTabContainerTabListNested .dijitTabChecked .dijitTabContent .tabLabel {
+	text-decoration: underline;
+	font-weight: bold;
+	
+}
+.tundra .dijitTabContainer .dijitTabPaneWrapperNested {
+	border: none;	
+}
+.tundra .dijitTab .closeImage {
+	background-image : url(images/tabClose.png);
+}
+.dj_ie6 .tundra .dijitTab .closeImage {
+	background-image : url(images/tabClose.gif);
+}
+.tundra .dijitTab .closeButton-hover .closeImage {
+	background-image : url(images/tabCloseHover.png);
+}
+.dj_ie6 .tundra .dijitTab .closeButton-hover .closeImage {
+	background-image : url(images/tabCloseHover.gif);
+}
+.tundra .dijitTabContainerTop-tabs {
+	margin-bottom: -1px;
+	border-color: #ccc;
+}
+.tundra .dijitTabContainerTop-container {
+	border-top: none;
+}
+.tundra .dijitTabContainerTop-tabs .dijitTabChecked {
+	border-bottom-color:white;
+}
+.tundra .dijitTabContainerTopStrip {
+	border: 1px solid #ccc;
+	padding-top: 2px;
+	padding-left: 3px;
+}
+.tundra .dijitTabContainerTopStrip {
+	background: #f2f2f2;
+}
+.tundra .dijitTabContainerBottom-tabs {
+	margin-top: -1px;
+	border-color: #ccc;
+}
+.tundra .dijitTabContainerBottom-container {
+	border-bottom: none;
+}
+.tundra .dijitTabContainerBottom-tabs .dijitTabChecked {
+	border-top-color:white;
+}
+.tundra .dijitTabContainerBottomStrip {
+	padding-bottom: 2px;
+	padding-left: 3px;	
+	border: 1px solid #ccc;
+}
+.tundra .dijitTabContainerBottomStrip {
+	background: #f2f2f2;
+}
+.tundra .dijitTabContainerBottom-spacer,
+.tundra .dijitTabContainerTop-spacer {
+	height: 0px;
+	border-top: 1px solid #ccc;
+	background: #fff;
+}
+.tundra .dijitTabContainerRight-tabs {
+	margin-left: -1px;
+	border-color: #ccc;
+}
+.tundra .dijitTabContainerRight-container {
+	border-right: none;
+}
+.tundra .dijitTabContainerRight-tabs .dijitTabChecked {
+	border-left-color:white;
+}
+.tundra .dijitTabContainerRightStrip {
+	padding-right: 2px;
+	padding-top: 3px;	
+	border: 1px solid #ccc;
+}
+.tundra .dijitTabContainerRightStrip {
+	background: #f2f2f2;
+}
+.tundra .dijitTabContainerLeft-tabs {
+	margin-right: -1px;
+	border-color: #ccc;
+}
+.tundra .dijitTabContainerLeft-container {
+	border-left: none;
+}
+.tundra .dijitTabContainerLeft-tabs .dijitTabChecked {
+	border-right-color:white;
+}
+.tundra .dijitTabContainerLeftStrip {
+	padding-left: 2px;
+	padding-top: 3px;	
+	border: 1px solid #ccc;
+}
+.tundra .dijitTabContainerLeftStrip {
+	background: #f2f2f2;
+}
+.tundra .dijitTabContainerLeft-tabs .dijitTab,
+.tundra .dijitTabContainerRight-tabs .dijitTab {
+	margin-right:0px;
+	margin-bottom:4px;	
+}
+.tundra .dijitTabContainerLeft-spacer,
+.tundra .dijitTabContainerRight-spacer {
+	width: 0px;
+	border-left: 1px solid #ccc;
+	background: #fff;
+}
+.tundra .dijitTabContainerTop-dijitContentPane .dijitTabContainerTop-tabs {
+	border-left: 0px solid #ccc;
+	border-top: 0px solid #ccc;
+	border-right: 0px solid #ccc;
+	padding-top: 0px;
+	padding-left: 0px;	
+}
+.tundra .dijitAccordionContainer {
+	border-color: #ccc;
+	background-color: #fff;
+}
+.tundra .dijitAccordionTitle {
+	background:#fafafa url(images/titleBar.png) repeat-x bottom left;
+	border-top: 1px solid #bfbfbf;
+	padding: 4px 4px 4px 8px;
+	cursor:pointer;
+}
+.tundra .dijitAccordionTitle-hover  {
+	background: #f8fafd url(images/accordionItemHover.gif) bottom repeat-x;
+}
+.tundra .dijitAccordionTitle-selected  {
+	background: #f9f9f9 url(images/accordionItemActive.gif) bottom repeat-x;
+	font-weight: bold;
+	border-top: 1px solid #aaaaaa;
+	border-bottom: 1px solid #bfbfbf;
+	padding: 4px 4px 4px 8px;
+	cursor: default;
+}
+.tundra .dijitSplitContainerSizerH {
+	background:url(images/splitContainerSizerV.png) repeat-y #fff;
+	border:0;
+	border-left:1px solid #bfbfbf;
+	border-right:1px solid #bfbfbf;
+	width:7px;
+}
+.tundra .dijitSplitContainerSizerH .thumb {
+	background:url(images/splitContainerSizerV-thumb.png) no-repeat #ccc;
+	left:1px;
+	width:3px;
+	height:19px;
+	overflow: hidden;
+}
+.tundra .dijitSplitContainerSizerV {
+	background:url(images/splitContainerSizerH.png) repeat-x #fff;
+	border:0;
+	border-top:1px solid #bfbfbf;
+	border-bottom:1px solid #bfbfbf;
+	height:7px;
+}
+.tundra .dijitSplitContainerSizerV .thumb {
+	background:url(images/splitContainerSizerH-thumb.png) no-repeat #ccc;
+	top:1px;
+	width:19px;
+	height:3px;
+	overflow: hidden;
+}
+.tundra .dijitSplitter {
+	border-color: #bfbfbf;
+}
+.tundra .dijitBorderContainer {
+	background-color: #fcfcfc;
+	padding: 5px;
+}
+.tundra .dijitSplitContainer-child,
+.tundra .dijitBorderContainer-child {
+	
+	border: 1px #ccc solid;
+}
+.tundra .dijitBorderContainer-dijitTabContainerTop,
+.tundra .dijitBorderContainer-dijitTabContainerBottom,
+.tundra .dijitBorderContainer-dijitTabContainerLeft,
+.tundra .dijitBorderContainer-dijitTabContainerRight {
+	
+	 border: none;
+}
+.tundra .dijitBorderContainer-dijitBorderContainer {
+	
+	border: none;
+	padding: 0px;
+}
+.tundra .dijitSplitterH,
+.tundra .dijitGutterH {
+	background:#fcfcfc;
+	border:0;
+	height:5px;
+}
+.tundra .dijitSplitterH .dijitSplitterThumb {
+	background:url(images/splitContainerSizerH-thumb.png) no-repeat;
+	top:1px;
+	width:19px;
+	height:2px;
+}
+.tundra .dijitSplitterV,
+.tundra .dijitGutterV {
+	background:#fcfcfc;
+	border:0;
+	width:5px;
+}
+.tundra .dijitSplitterV .dijitSplitterThumb {
+	background:url(images/splitContainerSizerV-thumb.png) no-repeat;
+	left:1px;
+	height:19px;
+	width:5px;
+}
+.tundra .dijitSplitterActive {
+	font-size: 1px;
+	background-image: none;
+	background-color: #aaa;
+	-moz-opacity: 0.6;
+	opacity: 0.6;
+	filter: Alpha(Opacity=60);
+	margin: 0;
+}
+.tundra .dijitInputField INPUT,
+.tundra .dijitTextBox,
+.tundra .dijitComboBox,
+.tundra .dijitSpinner {
+	margin: 0em 0.1em;
+}
+.tundra .dijitTextBox,
+.tundra .dijitComboBox,
+.tundra .dijitSpinner,
+.tundra .dijitTextArea {
+	font-family: sans-serif;
+	font-size: 100%;
+}
+.tundra .dijitTextArea {
+	padding: 3px;
+}
+.tundra .dijitTextBox,
+.tundra .dijitComboBox,
+.tundra .dijitSpinner,
+.tundra .dijitTextArea,
+.tundra .dijitInlineEditor input {
+	
+	background:#fff url(images/validationInputBg.png) repeat-x top left;
+	#background:#fff url(images/validationInputBg.gif) repeat-x top left;
+	border:1px solid #b3b3b3;
+	line-height: normal;
+}
+.tundra .dijitTextBoxDisabled,
+.tundra .dijitComboBoxDisabled,
+.tundra .dijitSpinnerDisabled,
+.tundra .dijitTextAreaDisabled {
+	color: gray;
+}
+.dj_webkit .tundra .dijitTextBoxDisabled,
+.dj_webkit .tundra .dijitComboBoxDisabled,
+.dj_webkit .tundra .dijitSpinnerDisabled,
+.dj_webkit .tundra .dijitTextAreaDisabled {
+	color: #eee;
+}
+.tundra .dijitComboBox .dijitInputField {
+	padding: 1px 0;
+}
+.tundra .dijitComboBox .dijitButtonNode {
+	padding: 1px 0.2em;
+}
+.tundra .dijitComboBox .dijitButtonNode,
+.tundra .dijitSpinner .dijitButtonNode {
+	
+	border-color: #9b9b9b;
+	border-width: 0px 0px 0px 1px;
+	border-style: solid;
+}
+.tundra .dijitTextBoxFocused,
+.tundra .dijitComboBoxFocused,
+.tundra .dijitSpinnerFocused, .tundra .dijitSpinnerUpArrowActive, .tundra .dijitSpinnerDownArrowActive,
+.tundra .dijitTextAreaFocused {
+	
+	border-color:#406b9b;
+}
+.tundra .dijitComboBoxFocused .dijitButtonNode,
+.tundra .dijitSpinnerFocused .dijitButtonNode,
+.tundra .dijitSpinnerUpArrowActive .dijitButtonNode,
+.tundra .dijitSpinnerDownArrowActive .dijitButtonNode {
+	border-left-color:#366dba;
+}
+.tundra .dijitSpinnerFocused .dijitDownArrowButton,
+.tundra .dijitSpinnerUpArrowActive .dijitDownArrowButton,
+.tundra .dijitSpinnerDownArrowActive .dijitDownArrowButton {
+	border-top-color:#366dba;
+}
+.tundra .dijitError {
+	background-color:#f9f7ba;
+	background-image:none;
+}
+.dj_ie6 .tundra .dijitError INPUT {
+	
+	background-color:#f9f7ba !important;
+}
+.tundra .dijitErrorFocused {
+	background-color:#f9f999;
+	background-image:none;
+}
+.dj_ie6 .tundra .dijitErrorFocused INPUT {
+	
+	background-color:#f9f999 !important;
+}
+.tundra .dijitValidationIcon {
+	
+	width: 16px;
+	background: transparent url(images/warning.png) no-repeat center center;
+}
+.tundra .dijitInlineValue {
+	
+	padding:3px;
+	margin:4px;
+}
+.tundra .dijitInlineEditor {
+	
+	display: inline-block;
+	display: -moz-inline-stack;
+	#display:inline;
+	
+}
+.dijitInlineEditor .saveButton,
+.dijitInlineEditor .cancelButton {
+	margin:3px 3px 3px 0px;
+}
+.RichTextEditable {
+	border:1px solid #bfbfbf;
+	border-top:0;
+}
+.tundra .dijitComboBoxHighlightMatch {
+	background-color:#a5beda;
+}
+.tundra .dijitFocusedLabel {
+	
+	outline: 1px dotted #666666;
+}
+.tundra .dijitButtonNode {
+	
+	border: 1px solid #c0c0c0; 
+	border-bottom: 1px solid #9b9b9b; 
+	padding: 0.1em 0.2em 0.2em 0.2em; 
+	background: #fff url(images/buttonEnabled.png) repeat-x bottom left;
+}
+.tundra .dijitButtonNode button { 
+	border: 0px; 
+	background-color: transparent; 
+} 
+ 
+.tundra .dijitButtonText {
+	text-align: center; 
+	padding: 0 0.3em;
+}
+.tundra .dijitDisabled .dijitButtonText {
+	color: #7F7F7F;
+}
+.tundra .dijitArrowButton {
+	color: #111;
+}
+.tundra .dijitComboButton .dijitDownArrowButton {
+	padding-right:4px;
+}
+.dj_ff2 .tundra .dijitComboButton .dijitButtonContentsFocused,
+.dj_ff2 .tundra .dijitComboButton .dijitDownArrowButtonFocused {
+	border: 1px solid transparent; 
+}
+.tundra .dijitButtonDisabled .dijitButtonNode,
+.tundra .dijitToggleButtonDisabled .dijitButtonNode,
+.tundra .dijitDropDownButtonDisabled .dijitButtonNode,
+.tundra .dijitComboButtonDisabled .dijitButtonNode,
+.tundra .dijitComboBoxDisabled,
+.tundra .dijitSpinnerDisabled,
+.tundra .dijitSpinnerDisabled .dijitButtonNode {
+	
+	
+	border-color: #d5d5d5 #d5d5d5 #bdbdbd #d5d5d5; 
+	background:#e4e4e4 url(images/buttonDisabled.png) top repeat-x;
+}
+.tundra .dijitButtonHover .dijitButtonNode,
+.tundra .dijitButtonNodeHover,
+.tundra .dijitToggleButtonHover .dijitButtonNode,
+.tundra .dijitDropDownButtonHover .dijitButtonNode,
+.tundra .dijitComboButtonHover .dijitButtonContents,
+.tundra .dijitComboButtonDownArrowHover .dijitDownArrowButton {
+	
+	
+	border-color:		#a5beda; 
+	border-bottom-color:#5c7590; 
+	color:#243C5F;
+	background:#fcfdff url(images/buttonHover.png) repeat-x bottom;
+}
+.tundra .dijitComboBoxHover .dijitDownArrowButton,
+.tundra .dijitSpinnerUpArrowHover .dijitUpArrowButton,
+.tundra .dijitSpinnerDownArrowHover .dijitDownArrowButton {
+	
+	color:#243C5F;
+	background:#fcfdff url(images/buttonHover.png) repeat-x bottom;
+}
+.tundra .dijitSpinnerUpArrowActive .dijitUpArrowButton,
+.tundra .dijitSpinnerDownArrowActive .dijitDownArrowButton,
+.tundra .dijitButtonActive .dijitButtonNode,
+.tundra .dijitToggleButtonActive .dijitButtonNode,
+.tundra .dijitDropDownButtonActive .dijitButtonNode,
+.tundra .dijitComboButtonActive .dijitButtonContents,
+.tundra .dijitDownArrowActive .dijitDownArrowButton,
+.tundra .dijitComboBoxActive .dijitDownArrowButton,
+.tundra .dijitStackController .dijitToggleButtonChecked .dijitButtonNode {
+	
+	border-color:#366dba;
+	background: #ededed url(images/buttonActive.png) bottom repeat-x;
+}
+.tundra .dijitArrowButtonInner {
+	background-image:url(images/spriteArrows.png);
+	background-position: left top;
+	width: 7px;
+	height: 7px;
+	font-size: 1px;
+	margin: 0px 4px 0px 5px;
+}
+.dj_ie6 .tundra .dijitArrowButtonInner {
+	background-image:url(images/spriteArrows.gif);
+}
+.tundra .dijitDisabled .dijitArrowButtonInner {
+	background-position: -28px top;
+}
+.tundra .dijitUpArrowButton .dijitArrowButtonInner { 
+	background-position: -21px top; 
+}
+.tundra .dijitDisabled .dijitUpArrowButton .dijitArrowButtonInner { 
+	background-position: -49px top; 
+}
+.tundra .dijitComboBox .dijitArrowButton .dijitArrowButtonInner {
+	background-image: url(images/comboArrowDown.gif);
+	background-repeat: no-repeat;
+	background-attachment: scroll;
+	background-position: center center;
+	height: auto;
+	font-size: 100%;
+	font-size: inherit;
+}
+.tundra .dijitComboBoxHover .dijitArrowButtonInner {
+	
+}
+.tundra .dijitSpinner .dijitArrowButtonInner {
+	display: block;  
+	position:absolute;
+	top: 50%; 
+	margin-top: -4px; 
+	left: 50%;
+	margin-left: -4px; 
+	line-height: 2px;
+}
+.tundra .dijitToggleButton .dijitCheckBoxIcon {
+	background-image: url(images/checkmarkNoBorder.png);
+}
+.dj_ie6 .tundra .dijitToggleButton .dijitCheckBoxIcon {
+	background-image: url(images/checkmarkNoBorder.gif);
+}
+.tundra .dijitCheckBox,
+.tundra .dijitCheckBoxIcon			{
+	background-image: url(images/checkmark.png); 
+	background-repeat: no-repeat;
+	width: 16px;
+	height: 16px;
+	margin: 0 2px 0 0;
+	padding: 0;
+}
+.dj_ie6 .tundra .dijitCheckBox,
+.dj_ie6 .tundra .dijitCheckBoxIcon			{
+	background-image: url(images/checkmark.gif); 
+}
+.tundra .dijitCheckBox,
+.tundra .dijitToggleButton .dijitCheckBoxIcon {
+	
+	background-position: -16px;
+}
+.tundra .dijitCheckBoxChecked,
+.tundra .dijitToggleButtonChecked .dijitCheckBoxIcon {
+	
+	background-position: 0px;
+}
+.tundra .dijitCheckBoxDisabled {
+	
+	background-position: -48px;
+}
+.tundra .dijitCheckBoxCheckedDisabled {
+	
+	background-position: -32px;
+}
+.tundra .dijitCheckBoxHover {
+	
+	background-position: -80px;
+}
+.tundra .dijitCheckBoxCheckedHover {
+	
+	background-position: -64px;
+}
+.tundra .dijitToggleButton .dijitRadio,
+.tundra .dijitToggleButton .dijitRadioIcon {
+	background-image: url(images/checkmarkNoBorder.png);
+}
+.dj_ie6 .tundra .dijitToggleButton .dijitRadio,
+.dj_ie6 .tundra .dijitToggleButton .dijitRadioIcon {
+	background-image: url(images/checkmarkNoBorder.gif);
+}
+.tundra .dijitRadio,
+.tundra .dijitRadioIcon	{		
+	background-image: url(images/checkmark.png); 
+	background-repeat: no-repeat;
+	width: 16px;
+	height: 16px;
+	margin: 0;
+	padding: 0;
+}
+.dj_ie6 .tundra .dijitRadio,
+.dj_ie6 .tundra .dijitRadioIcon	{		
+	background-image: url(images/checkmark.gif); 
+}
+.tundra .dijitRadio,
+.tundra .dijitToggleButton .dijitRadioIcon {
+	
+	background-position: -112px;
+}
+.tundra .dijitRadioDisabled {
+	
+	background-position: -144px;
+}
+.tundra .dijitRadioHover {
+	
+	background-position: -176px;
+}
+.tundra .dijitRadioChecked,
+.tundra .dijitRadioCheckedHover,
+.tundra .dijitToggleButtonChecked .dijitRadioIcon {
+	
+	background-position: -96px;
+}
+.tundra .dijitRadioCheckedDisabled {
+	
+	background-position: -128px;
+}
+.tundra .dijitSliderProgressBarH {
+	border-color: #aab0bb;
+	background: #c0c2c5 url(images/sliderFull.png) repeat-x top left;
+}
+.tundra .dijitSliderProgressBarV {
+	border-color: #aab0bb;
+	background: #c0c2c5 url(images/sliderFullVertical.png) repeat-y bottom left;
+}
+.tundra .dijitSliderFocused .dijitSliderProgressBarH,
+.tundra .dijitSliderFocused .dijitSliderLeftBumper {
+	background-image:url(images/sliderFullFocus.png);
+}
+.tundra .dijitSliderFocused .dijitSliderProgressBarV,
+.tundra .dijitSliderFocused .dijitSliderBottomBumper {
+	background-image:url(images/sliderFullVerticalFocus.png);
+}
+.tundra .dijitSliderRemainingBarV {
+	border-color: #b4b4b4;
+	background: #dcdcdc url(images/sliderEmptyVertical.png) repeat-y bottom left;
+}
+.tundra .dijitSliderRemainingBarH {
+	border-color: #b4b4b4;
+	background: #dcdcdc url(images/sliderEmpty.png) repeat-x top left;
+}
+.tundra .dijitSliderBar {
+	border-style: solid;
+	outline:1px;
+}
+.tundra .dijitSliderFocused .dijitSliderBar {
+	border-color:#888;	
+}
+.dijit_a11y .dijitSliderProgressBar {
+	background-color:#888 !important;
+}
+.tundra .dijitSliderImageHandleH {
+	border:0px;
+	width:16px;
+	height:16px;
+	background:url(images/preciseSliderThumb.png) no-repeat center top;
+	cursor:pointer;
+}
+.tundra .dijitSliderFocused .dijitSliderImageHandleH {
+	background-image:url(images/preciseSliderThumbFocus.png);
+	#background-image:url(images/preciseSliderThumbFocus.gif);
+}
+.dj_ie6 .tundra .dijitSliderImageHandleH {
+	background-image:url(images/preciseSliderThumb.gif);
+}
+.tundra .dijitSliderLeftBumper {
+	border-left-width: 1px;
+	border-color: #aab0bb;
+	background: #c0c2c5 url(images/sliderFull.png) repeat-x top left;
+}
+.tundra .dijitSliderRightBumper {
+	background: #dcdcdc url(images/sliderEmpty.png) repeat-x top left;
+	border-color: #b4b4b4;
+	border-right-width: 1px;
+}
+.tundra .dijitSliderImageHandleV {
+	border:0px;
+	width:16px;
+	height:16px;
+	background:url(images/sliderThumb.png) no-repeat center center;
+	cursor:pointer;
+}
+.tundra .dijitSliderFocused .dijitSliderImageHandleV {
+	background-image:url(images/sliderThumbFocus.png);
+}
+.dj_ie6 .tundra .dijitSliderFocused .dijitSliderImageHandleV {
+	background-image:url(images/sliderThumbFocus.gif);
+}
+.tundra .dijitSliderBottomBumper {
+	border-bottom-width: 1px;
+	border-color: #aab0bb;
+	background: #c0c2c5 url(images/sliderFullVertical.png) repeat-y bottom left;
+}
+.tundra .dijitSliderTopBumper {
+	background: #dcdcdc url(images/sliderEmptyVertical.png) repeat-y top left;
+	border-color: #b4b4b4;
+	border-top-width: 1px;
+}
+.tundra .dijitSliderDecrementIconH,
+.tundra .dijitSliderDecrementIconV,
+.tundra .dijitSliderIncrementIconH,
+.tundra .dijitSliderIncrementIconV {
+	cursor: pointer;
+	background-image: url(images/spriteArrows.png);
+	background-repeat: no-repeat;
+	margin: 5px;
+	height: 7px;
+	width: 7px;
+	font-size: 1px;
+}
+.dj_ie6 .tundra .dijitSliderDecrementIconH,
+.dj_ie6 .tundra .dijitSliderDecrementIconV,
+.dj_ie6 .tundra .dijitSliderIncrementIconH,
+.dj_ie6 .tundra .dijitSliderIncrementIconV {
+	background-image: url(images/spriteArrows.gif);
+}
+.tundra .dijitSliderDecrementIconH {
+	background-position: -7px 0px;
+}
+.tundra .dijitSliderIncrementIconH {
+	background-position: -14px 0px;
+}
+.tundra .dijitSliderDecrementIconV {
+	background-position: 0px 0px;
+}
+.tundra .dijitSliderIncrementIconV {
+	background-position: -21px 0px;
+}
+.tundra .dijitSliderButtonInner {
+	visibility:hidden;
+}
+.tundra .dijitSliderDisabled {
+	opacity:0.6 !important;
+}
+.dj_ie .tundra .dijitSliderDisabled,
+.dj_ie .tundra .dijitSliderDisabled .dijitRuleContainer,
+.dj_ie .tundra .dijitSliderDisabled .dijitSliderRemainingBar,
+.dj_ie .tundra .dijitSliderDisabled .dijitSliderProgressBar {
+	filter: gray() alpha(opacity=40);
+}
+.tundra .dijitSliderDisabled * {
+	cursor: not-allowed !important;
+}
+.tundra .dijitTreeNode {
+    background-image : url(images/i.gif);
+    background-repeat : repeat-y;
+    zoom: 1;	
+}
+.tundra .dijitTreeIsLast {
+    background: url(images/i_half.gif) no-repeat;
+}
+.tundra .dijitTreeIsRoot {
+    margin-left: 0;
+    background-image: none;
+}
+.tundra .dijitTreeExpando {
+    width: 18px;
+    height: 18px;
+}
+.tundra .dijitTreeRow {
+	
+	padding-bottom: 2px;
+}
+.tundra .dijitTreeContent {
+    min-height: 18px;
+    min-width: 18px;
+ }
+.tundra .dijitTreeExpand {
+    width: 18px;
+    height: 18px;
+    background-repeat : no-repeat;
+}
+.tundra .dijitTreeNodeEmphasized {
+    background-color: Highlight;
+    color: HighlightText;
+}
+.tundra .dijitTreeLabelFocused {
+	outline: 1px invert dotted;
+}
+.tundra .dijitTreeNodeSelected .dijitTreeLabel {
+	background:#e2ebfe;
+}
+.tundra .dijitTreeNodeHover {
+	
+	
+	background-image: url(images/treeHover.png);
+	background-repeat: repeat;
+	background-color: none !important;
+}
+.tundra .dijitTreeExpandoOpened {
+	background-image: url(images/treeExpand_minus.gif);
+}
+.tundra .dijitTreeExpandoClosed {
+	background-image: url(images/treeExpand_plus.gif);
+}
+.tundra .dijitTreeExpandoLeaf {
+	background-image: url(images/treeExpand_leaf.gif);
+}
+.tundra .dijitTreeExpandoLoading {
+	background-image: url(images/treeExpand_loading.gif);
+}
+.tundra .dijitTreeIcon {
+	width: 16px;
+	height: 16px;
+}
+.tundra .dijitFolderOpened {
+	background: url(images/folderOpened.gif) no-repeat;
+}
+.tundra .dijitFolderClosed {
+	background: url(images/folderClosed.gif) no-repeat;
+}
+.tundra .dijitLeaf {
+	background: url(images/leaf.gif) no-repeat;
+}
+.tundra .dijitTreeNode .dojoDndItemBefore,
+.tundra .dijitTreeNode .dojoDndItemAfter {
+	border-bottom: none;
+	border-top: none;
+}
+.tundra .dijitTreeNode .dojoDndItemBefore .dijitTreeContent {
+	
+	border-top: 2px solid #369;
+}
+.tundra .dijitTreeNode .dojoDndItemAfter .dijitTreeContent {
+	
+	border-bottom: 2px solid #369;
+}
+.tundra .dijitProgressBar {
+	margin:2px 0px 2px 0px;
+}
+.tundra .dijitProgressBarEmpty {
+	
+	background:#fff url(images/progressBarEmpty.png) repeat-x center center;
+	border-color: #a2a2a2 #b8b8b8 #b8b8b8 #a2a2a2;
+}
+.tundra .dijitProgressBarTile {
+	
+	background:#f0f0f0 url(images/progressBarFull.png) repeat-x center center;
+}
+.tundra .dijitProgressBarFull {
+	border-right:1px solid #b8b8b8;
+}
+.tundra .dijitProgressBarLabel {
+	
+	color:#293a4b;
+}
+.tundra .dijitProgressBarIndeterminate .dijitProgressBarTile {
+	
+	background:#cad2de url(images/progressBarAnim.gif) repeat-x center center;
+}
+.tundra .dijitTitlePaneTitle {
+	background: #cccccc;
+	background:#fff url(images/titleBar.png) repeat-x bottom left;
+	border:1px solid #bfbfbf;
+	padding:3px 4px;
+	cursor: pointer;
+}
+.tundra .dijitTitlePaneTitle-hover  {
+	background: #f8fafd url(images/accordionItemHover.gif) bottom repeat-x;
+}
+.tundra .dijitTitlePaneTitle * {
+	vertical-align: middle;
+}
+.tundra .dijitTitlePane .dijitArrowNode {
+	cursor: pointer;
+	background-image: url(images/spriteArrows.png);
+	background-repeat: no-repeat;
+	height: 7px;
+	width: 7px;
+}
+.dj_ie6 .tundra .dijitTitlePane .dijitArrowNode {
+	background-image: url(images/spriteArrows.gif);
+}
+.tundra .dijitTitlePane .dijitOpen .dijitArrowNode {
+	background-position: 0px 0px;
+}
+.tundra .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background-position: -14px 0px;
+}
+.tundra .dijitTitlePaneFocused .dijitTitlePaneTextNode {
+	text-decoration:underline;
+}
+.tundra .dijitTitlePane .dijitArrowNodeInner {
+	display:none;
+}
+.dijit_a11y .dijitTitlePane .dijitArrowNodeInner {
+	display:inline !important;
+	font-family:monospace;
+	cursor: pointer;
+	padding-bottom:.2em;
+}
+.dijit_a11y .dijitTitlePane .dijitArrowNode {
+	display:none;
+}
+.tundra .dijitTitlePaneContentOuter {
+	background: #ffffff;
+	border:1px solid #bfbfbf;
+	border-top: 1px solid #ccc;	
+}
+.tundra .dijitTitlePaneContentInner {
+	padding:10px;
+}
+.dj_ie6 .tundra .dijitTitlePaneContentOuter,
+.dj_ie6 .tundra .dijitTitlePane .dijitTitlePaneTitle {
+	zoom: 1;
+}
+.tundra .dijitTitlePaneTextNode {
+	margin-left: 4px;
+	margin-right: 4px;
+}
+	
+.tundra .dijitCalendarIncrementControl {
+	
+	width:15px;
+	height:15px;
+	background-image: url(images/spriteRoundedIconsSmall.png);
+	background-repeat: no-repeat
+}
+.dj_ie6 .tundra .dijitCalendarIncrementControl {
+	font-size:.1em;
+	background-image: url(images/spriteRoundedIconsSmall.gif);
+}
+.tundra .dijitA11ySideArrow {
+	display: none;
+}
+.tundra .dijitCalendarDecrease {
+	background-position: top left;
+}
+.tundra .dijitCalendarIncrease {
+	background-position: -30px top;
+}
+.tundra table.dijitCalendarContainer {
+	font-size: 100%;
+	border-spacing: 0;
+	border-collapse: separate;
+	border: 1px solid #ccc;
+	margin: 0;
+}
+.tundra .dijitCalendarMonthContainer th {
+	
+	background:#d3d3d3 url(images/titleBar.png) repeat-x top;
+	padding-top:.3em;
+	padding-bottom:.2em;
+	text-align:center;
+}
+.dj_ie6 .tundra .dijitCalendarMonthContainer th {
+	padding-top:.2em;
+	padding-bottom:.1em;
+}
+.tundra .dijitCalendarDayLabelTemplate {
+	
+	background:white url(images/calendarDayLabel.png) repeat-x bottom;
+	font-weight:normal;
+	padding-top:.15em;
+	padding-bottom:0em;
+	border-top: 1px solid #eeeeee;
+	color:#293a4b;
+	text-align:center;
+}
+.tundra .dijitCalendarBodyContainer {
+	border-bottom: 1px solid #eeeeee;	
+}
+.tundra .dijitCalendarMonthLabel {
+	color:#293a4b;
+	font-weight: bold;
+}
+.tundra .dijitCalendarDateTemplate {
+	
+	font-size: 0.9em;
+	font-weight: bold;
+	text-align: center;
+	padding: 0.3em 0.3em 0.05em 0.3em;
+	letter-spacing: 1px;
+}
+.dj_ie .tundra .dijitCalendarDateTemplate {
+	padding: 0.1em .33em 0.02em .33em;
+}
+.tundra .dijitCalendarPreviousMonth,
+.tundra .dijitCalendarNextMonth 		{
+	
+	color:#999999;
+	background-color:#f8f8f8 !important;
+}
+.tundra .dijitCalendarPreviousMonthDisabled,
+.tundra .dijitCalendarNextMonthDisabled	{
+	
+	background-color:#a4a5a6 !important;
+}
+.tundra .dijitCalendarCurrentMonth {
+	
+	background-color:white !important;
+}
+.tundra .dijitCalendarCurrentMonthDisabled {
+		
+	background-color:#bbbbbc !important;
+}
+.tundra .dijitCalendarDisabledDate {
+	cursor:default !important;
+	text-decoration:line-through !important;
+}
+.tundra .dijitCalendarCurrentDate {
+	
+	text-decoration:underline;
+	font-weight:bold;
+}
+.tundra .dijitCalendarHoveredDate {
+	background-color: #e2ebf2 !important;
+}
+.tundra .dijitCalendarSelectedDate {
+	
+	background-color:#bbc4d0 !important;
+	color:black !important;
+}
+.tundra .dijitCalendarYearContainer {
+	
+	background:white url(images/calendarYearLabel.png) repeat-x bottom;
+	border-top:1px solid #ccc;
+}
+.tundra .dijitCalendarYearLabel {
+	
+	margin:0;
+	padding:0.4em 0 0.25em 0;
+	text-align:center;
+}
+.tundra .dijitCalendarSelectedYear {
+	
+	color:black;
+	padding:0.2em;
+	padding-bottom:0.1em;
+	background-color:#bbc4d0 !important;
+}
+.tundra .dijitCalendarNextYear,
+.tundra .dijitCalendarPreviousYear {
+	
+	color:black !important;
+	font-weight:normal;
+}
+.tundra .dijitTimePickerTick,
+.tundra .dijitTimePickerMarker {
+	border-color: #ccc;
+}
+.tundra .dijitTimePickerTick {
+	color:white;
+}
+.tundra .dijitTimePickerMarker {
+	background:#d3d3d3 url(images/titleBar.png) repeat-x top;
+	color:#293a4b;
+	font-weight: bold;
+}
+.tundra .dijitTimePickerItemSelected {
+	color: black;
+	background: #bbc4d0 none;
+}
+.tundra .dijitTimePickerItemHover {
+	background: #60a1ea none;
+	color:white;
+}
+.tundra .dijitTimePickerItemHover,
+.tundra .dijitTimePickerItemSelected {
+	position: relative;
+	z-index: 10;
+}
+.tundra .dijitTimePickerTick .dijitTimePickerItemInner {
+	font-size:0.4em;
+}
+.tundra .dijitTimePickerItemHover .dijitTimePickerItemInner,
+.tundra .dijitTimePickerItemSelected .dijitTimePickerItemInner {
+	font-size:1em;
+}
+.tundra .dijitTimePickerMarkerHover {
+	border-top: 1px solid #ccc;
+}
+.tundra .dijitTimePickerTickHover,
+.tundra .dijitTimePickerTickSelected {
+	margin-top:-0.3em;
+	margin-bottom:-0.3em;
+	border-bottom: none;
+}
+.dijit_a11y .dijitTimePickerTickHover {
+	background-color: #CCC !important;
+	border-top: 1px solid #333 !important;
+	border-bottom: 1px solid #333 !important;
+}
+.dijit_a11y .dijitTimePickerMarkerHover {
+	border-bottom-width: 2px;
+}
+.tundra .dijitToolbar {
+	border-bottom: 1px solid #ccc;
+	background:#eaeaea url(images/titleBar.png) repeat-x top left;
+}
+.dj_ie6 .tundra .dijitToolbar {
+	height: 10px;
+}
+.tundra .dijitToolbar .dijitButtonNode,
+.tundra .dijitToolbar .dijitComboButton .dijitButtonContents,
+.tundra .dijitToolbar .dijitComboButton .dijitDownArrowButton {
+	background: none;
+	margin: 0px;
+	padding: 0px;
+	border: none;
+	font-size: 12px;
+}
+.tundra .dijitToolbar .dijitButton,
+.tundra .dijitToolbar .dijitToggleButton,
+.tundra .dijitToolbar .dijitDropDownButton,
+.tundra .dijitToolbar .dijitComboButton .dijitButtonContents,
+.tundra .dijitToolbar .dijitComboButton .dijitDownArrowButton  {
+	background: none;
+	padding: 1px;
+}
+.tundra .dijitToolbar .dijitButtonChecked,
+.tundra .dijitToolbar .dijitToggleButtonChecked {
+	background-color:#d4dff2;
+	border:1px solid #316ac5;
+	padding: 0px;	
+}
+.tundra .dijitToolbar .dijitButtonCheckedHover,
+.tundra .dijitToolbar .dijitToggleButtonCheckedHover
+ {
+	background-color:#abc1e5;
+	border:1px solid #316ac5;
+	padding: 0px;	
+}
+.tundra .dijitToolbar .dijitButtonHover,
+.tundra .dijitToolbar .dijitToggleButtonHover,
+.tundra .dijitToolbar .dijitDropDownButtonHover,
+.tundra .dijitToolbar .dijitComboButtonHover .dijitButtonContents,
+.tundra .dijitToolbar .dijitComboButtonDownArrowHover .dijitDownArrowButton {
+	
+	border: 1px solid #869cbf;
+	padding: 0px;	
+	background-color:#e1e5f0;
+}
+.tundra .dijitToolbar label {	
+	padding: 3px 3px 0 6px;
+}
+.dj_ie .tundra .dijitToolbar .dijitComboButton .dijitButtonContentsFocused,
+.dj_ie .tundra .dijitToolbar .dijitComboButton .dijitDownArrowButtonFocused,
+.dj_ff2 .tundra .dijitToolbar .dijitComboButton .dijitButtonContentsFocused,
+.dj_ff2 .tundra .dijitToolbar .dijitComboButton .dijitDownArrowButtonFocused {
+	
+	border: 1px #555 dotted !important;
+	padding: 0px;	
+}
+.tundra .dijitDialog {
+	background: #fff;
+	border: 1px solid #7eabcd;
+	
+	padding: 0px;
+	-webkit-box-shadow: 0px 5px 10px #adadad;
+}
+.tundra .dijitDialog .dijitDialogPaneContent {
+	background: #fff;
+	border:none;
+	border-top: 1px solid #d3d3d3; 
+	padding:10px;
+}
+.tundra .dijitDialogTitleBar {
+	
+	background: #fafafa url(images/titleBar.png) repeat-x top left;
+	padding: 5px 6px 3px 6px;
+	cursor: move;
+	outline:0; 
+}
+.tundra .dijitDialogTitle {
+	
+	font-weight: bold;
+	padding: 0px 4px;
+}
+.tundra .dijitDialogCloseIcon {
+	
+	
+	background: url(images/tabClose.png) no-repeat right top;
+	position: absolute;
+	vertical-align: middle;
+	right: 6px;
+	top: 4px;
+	height: 15px;
+	width: 15px;
+	cursor: pointer;
+}
+.dj_ie6 .tundra .dijitDialogCloseIcon {
+	background : url(images/tabClose.gif) no-repeat right top;
+}
+.tundra .dijitDialogCloseIcon-hover {
+	background: url(images/tabCloseHover.png) no-repeat right top;
+}
+.dj_ie6 .tundra .dijitDialogCloseIcon-hover {
+	background : url(images/tabCloseHover.gif) no-repeat right top;
+}
+.tundra .dijitTooltip,
+.tundra .dijitTooltipDialog {
+	
+	background: transparent;	
+}
+.dijitTooltipBelow {
+	
+	padding-top: 13px;
+}
+.dijitTooltipAbove {
+	
+	padding-bottom: 13px;
+}
+.tundra .dijitTooltipContainer {
+	
+	background: #ffffff url(images/popupMenuBg.gif) repeat-x bottom left;
+	border: 1px solid #7eabcd;
+	padding: 0.45em;	
+	-webkit-border-radius: 3px;
+}
+.dj_ff3 .tundra .dijitTooltipContainer {
+	
+	-moz-border-radius: 3px;
+}	
+.tundra .dijitTooltipConnector {
+	
+	border:0px;
+	z-index: 2;
+}
+.tundra .dijitTooltipABRight .dijitTooltipConnector {
+	
+	left: auto !important;
+	right: 3px;
+}
+.tundra .dijitTooltipBelow .dijitTooltipConnector {
+	
+	top: 0px;
+	left: 3px;
+	background:url(images/tooltipConnectorUp.png) no-repeat top left;
+	width:16px;
+	height:14px;
+}
+.dj_ie6 .tundra .dijitTooltipBelow .dijitTooltipConnector {
+	
+	background-image: url(images/tooltipConnectorUp.gif);
+}
+.tundra .dijitTooltipAbove .dijitTooltipConnector {
+	
+	bottom: 0px;
+	left: 3px;
+	background:url(images/tooltipConnectorDown.png) no-repeat top left;
+	width:16px;
+	height:14px;
+}
+.dj_ie6 .tundra .dijitTooltipAbove .dijitTooltipConnector {
+	background-image: url(images/tooltipConnectorDown.gif);
+}
+.dj_ie6 .tundra .dijitTooltipAbove .dijitTooltipConnector {
+	bottom: -3px;
+}
+.tundra .dijitTooltipLeft {
+	padding-right: 14px;
+}
+.dj_ie6 .tundra .dijitTooltipLeft {
+	padding-left: 15px;
+}
+.tundra .dijitTooltipLeft .dijitTooltipConnector {
+	
+	right: 0px;
+	bottom: 3px;
+	background:url(images/tooltipConnectorRight.png) no-repeat top left;
+	width:16px;
+	height:14px;
+}
+.dj_ie6 .tundra .dijitTooltipLeft .dijitTooltipConnector {
+	background-image: url(images/tooltipConnectorRight.gif);
+}
+.tundra .dijitTooltipRight {
+	padding-left: 14px;
+}
+.tundra .dijitTooltipRight .dijitTooltipConnector {
+	
+	left: 0px;
+	bottom: 3px;
+	background:url(images/tooltipConnectorLeft.png) no-repeat top left;
+	width:16px;
+	height:14px;
+}
+.dj_ie6 .tundra .dijitTooltipRight .dijitTooltipConnector {
+	background-image: url(images/tooltipConnectorLeft.gif);
+}
+.dj_webkit .tundra .dijitPopup .dijitTooltipContainer,
+.dj_webkit .tundra .dijitPopup .dijitMenu {
+	
+	-webkit-box-shadow: 0px 5px 10px #adadad;
+}
+.tundra .dijitMenu,
+.tundra .dijitMenuBar {
+	border: 1px solid #7eabcd;
+	margin: 0px;
+	padding: 0px;
+	background-color: #f7f7f7;
+	
+}
+.tundra .dijitBorderContainer .dijitMenuBar {
+	border:1px solid #ccc;
+}
+.tundra .dijitMenuItem {
+	font-family: sans-serif;
+	margin: 0;
+}
+.tundra .dijitMenuBar .dijitMenuItem {
+	padding: 4px 5px;
+}
+.tundra .dijitMenuPreviousButton, .tundra .dijitMenuNextButton {
+	font-style: italic;
+}
+.tundra .dijitMenuItem td {
+	padding: 2px;
+}
+.tundra .dijitMenuPassive .dijitMenuItemHover,
+.tundra .dijitMenuItemSelected {
+	background-color: #3559ac;
+	color:#fff;
+}
+.tundra .dijitMenuItemIcon {
+	width: 16px;
+	height: 16px;
+}
+.tundra .dijitMenuExpand {
+	width: 7px;
+	height: 7px;
+	background-image: url(images/spriteArrows.png);
+	background-position: -14px 0px;
+}
+.dj_ie6 .tundra .dijitMenuExpand {
+	background-image: url(images/spriteArrows.gif);
+}
+.tundra .dijitMenuSeparatorTop {
+	border-bottom: 1px solid #9b9b9b;
+}
+.tundra .dijitMenuSeparatorBottom {
+	border-top: 1px solid #e8e8e8;
+}
+.tundra .dijitCheckedMenuItemIconChar {
+	display: none;
+}
+.tundra .dijitCheckedMenuItemIcon {
+	background-image: url(images/checkmark.png);
+	background-position: -80px;
+}
+.dj_ie6 .tundra .dijitCheckedMenuItemIcon {
+	background-image: url(images/checkmark.gif);
+}
+.tundra .dijitCheckedMenuItemChecked .dijitCheckedMenuItemIcon {
+	background-position: -64px;
+}
+.dijitIEFixedToolbar {
+	position:absolute;
+	
+	top: expression(eval((document.documentElement||document.body).scrollTop));
+}
+.tundra .dijitToolbar .dijitToolbarSeparator {
+	background: url(images/editor.gif);
+}
+.tundra .dijitEditorIcon {
+	background-image: url(images/editor.gif); 
+	background-repeat: no-repeat;
+	width: 18px;
+	height: 18px;
+	text-align: center;
+}
+.tundra .dijitDisabled .dijitEditorIcon {
+	background-image: url(images/editorDisabled.gif); 
+}
+.tundra .dijitEditorIconSep { background-position: 0px; }
+.tundra .dijitEditorIconBackColor { background-position: -18px; }
+.tundra .dijitEditorIconBold { background-position: -36px; }
+.tundra .dijitEditorIconCancel { background-position: -54px; }
+.tundra .dijitEditorIconCopy { background-position: -72px; }
+.tundra .dijitEditorIconCreateLink { background-position: -90px; }
+.tundra .dijitEditorIconCut { background-position: -108px; }
+.tundra .dijitEditorIconDelete { background-position: -126px; }
+.tundra .dijitEditorIconForeColor { background-position: -144px; }
+.tundra .dijitEditorIconHiliteColor { background-position: -162px; }
+.tundra .dijitEditorIconIndent { background-position: -180px; }
+.tundra .dijitEditorIconInsertHorizontalRule { background-position: -198px; }
+.tundra .dijitEditorIconInsertImage { background-position: -216px; }
+.tundra .dijitEditorIconInsertOrderedList { background-position: -234px; }
+.tundra .dijitEditorIconInsertTable { background-position: -252px; }
+.tundra .dijitEditorIconInsertUnorderedList { background-position: -270px; }
+.tundra .dijitEditorIconItalic { background-position: -288px; }
+.tundra .dijitEditorIconJustifyCenter { background-position: -306px; }
+.tundra .dijitEditorIconJustifyFull { background-position: -324px; }
+.tundra .dijitEditorIconJustifyLeft { background-position: -342px; }
+.tundra .dijitEditorIconJustifyRight { background-position: -360px; }
+.tundra .dijitEditorIconLeftToRight { background-position: -378px; }
+.tundra .dijitEditorIconListBulletIndent { background-position: -396px; }
+.tundra .dijitEditorIconListBulletOutdent { background-position: -414px; }
+.tundra .dijitEditorIconListNumIndent { background-position: -432px; }
+.tundra .dijitEditorIconListNumOutdent { background-position: -450px; }
+.tundra .dijitEditorIconOutdent { background-position: -468px; }
+.tundra .dijitEditorIconPaste { background-position: -486px; }
+.tundra .dijitEditorIconRedo { background-position: -504px; }
+.tundra .dijitEditorIconRemoveFormat { background-position: -522px; }
+.tundra .dijitEditorIconRightToLeft { background-position: -540px; }
+.tundra .dijitEditorIconSave { background-position: -558px; }
+.tundra .dijitEditorIconSpace { background-position: -576px; }
+.tundra .dijitEditorIconStrikethrough { background-position: -594px; }
+.tundra .dijitEditorIconSubscript { background-position: -612px; }
+.tundra .dijitEditorIconSuperscript { background-position: -630px; }
+.tundra .dijitEditorIconUnderline { background-position: -648px; }
+.tundra .dijitEditorIconUndo { background-position: -666px; }
+.tundra .dijitEditorIconWikiword { background-position: -684px; }
+.tundra .dijitEditorIconToggleDir { background-position: -540px; }
+.tundra .dijitEditorIconTabIndent { background-position: -702px; }
+.tundra .dijitEditorIconSelectAll { background-position: -720px; }
+.tundra .dijitEditorIconUnlink { background-position: -738px; }
+.dijitColorPalette {
+	border:1px solid #7eabcd;
+	background:#fff;
+	-moz-border-radius: 0px !important;
+}
+.dj_gecko-rtl .dijitInputField {
+	direction: ltr; 
+}
+.dj_gecko-rtl .dijitInputField * {
+	direction: rtl; 
+}
+.dijitRtl .dijitMenuItem {
+	text-align: right;
+}
+.dijitRtl .dijitComboBox .dijitInputField {
+	border-right-width:1px !important;
+	border-left-width:0 !important;
+}
+.dijitRtl .dijitCalendarNextYear {
+	margin:0 0.55em 0 0;
+}
+.dijitRtl .dijitCalendarPreviousYear {
+	margin:0 0 0 0.55em;
+}
+.dijitRtl .dijitProgressBarFull .dijitProgressBarLabel {
+	right:0; 
+}
+.dijitRtl .dijitSliderImageHandleV {
+	left:auto;
+	right:-6px;
+}
+.dj_ie-rtl .dijitSliderImageHandleV {
+	right:-10px;
+}
+.dijitRtl .dijitSliderMoveableH {
+	right:auto;
+	left:0;
+}
+.dijitRtl .dijitRuleContainerV {
+	float:right;
+}
+.dj_gecko-rtl .dijitRuleContainerV {
+	float:left;
+}
+.dj_ie-rtl .dijitRuleContainerV {
+	text-align:right;
+}
+.dj_ie-rtl .dijitRuleLabelV {
+	text-align:left;
+}
+.dj_ie-rtl .dijitRuleLabelH {
+	zoom:1;
+}
+.dj_ie-rtl .dijitSliderProgressBarH {
+	right:0;
+	left:auto;
+}
+.dj_gecko-rtl .dijitSliderProgressBarH {
+	float:right;
+	right:0;
+	left:auto;
+}
+.dijitRtl .dijitSpinner .dijitInputLayoutContainer .dijitArrowButton {
+	right: auto;
+	left: 0;
+	border-width: 0 1px 0 0 !important;
+}
+.dijitRtl .dijitSpinnerButtonContainer {
+	float: left;
+}
+.dijitRtl .dijit_a11y .dijitSpinnerButtonContainer {
+	margin-left: none;
+	margin-right: 2px;
+}
+.dijitRtl DIV.dijitArrowButton, .dijitRtl .dijitValidationIcon, .dijitRtl .dijitValidationIconText {
+	float: left;
+}
+.dijitRtl .dijitContentPaneLoading, .dijitRtl .dijitContentPaneError {
+	background-position:right;
+	padding-right:25px;
+}
+.dijitRtl .tundra .dijitCalendarDecrease {
+	background-position: -30px top;
+}
+.dijitRtl .tundra .dijitCalendarIncrease {
+	background-position: 0px top;
+}
+.dijitRtl .tundra .dijitDialogTitleBar .dijitDialogCloseIcon {
+	right: auto;
+	left: 5px;
+}
+.dijitRtl .tundra .dijitEditorIcon {
+	background-image: url(images/editor_rtl.gif); 
+}
+.dijitRtl .tundra .dijitDisabled .dijitEditorIcon {
+	background-image: url(images/editorDisabled_rtl.gif); 
+}
+.dijitRtl .tundra .dijitToolbar .dijitToolbarSeparator {
+	background-image: url(images/editor_rtl.gif);
+}
+.dijitRtl .tundra .dijitMenuItem .dijitMenuItemIcon {
+	padding-left: 3px;
+	padding-right: 0px;
+}
+.dijitRtl .tundra .dijitMenuItem .dijitMenuExpand {
+	background-position: -7px 0px;
+}
+.dijitRtl .tundra .dijitTreeContainer .dijitTreeNode {
+    background-image : none;
+}
+.dijitRtl .tundra .dijitTreeContainer .dijitTreeExpandoOpened {
+	background-image: url(images/treeExpand_minus_rtl.gif);
+}
+.dijitRtl .tundra .dijitTreeContainer .dijitTreeExpandoClosed {
+	background-image: url(images/treeExpand_plus_rtl.gif);
+}
+.dijitRtl .tundra .dijitTreeContainer .dijitTreeExpandoLeaf {
+	background-image: none;
+}
+.dijitRtl .tundra .dijitTitlePane .dijitClosed .dijitArrowNode {
+	background-position: -7px 0px;
+}
+.dijitRtl .tundra .dijitTab {
+	margin-right:auto;
+	margin-left:4px;		
+	-moz-box-orient:horizontal;
+	text-align: right;
+}
+.dijitRtl .tundra .dijitTabContainerTopStrip,
+.dijitRtl .tundra .dijitTabContainerBottomStrip {
+	padding-right: 3px;
+	padding-left: 0px;
+}
+.dijitRtl .tundra .dijitTabInnerDiv {
+	padding:6px 9px 5px 8px;
+}
+.dijitRtl .tundra .dijitTabPaneWrapper {
+	#zoom: 1;
+}
+.dj_ie-rtl .tundra .dijitTabContainerLeft-tabs {
+	margin-left: 1px !important;
+}
+.dj_ie-rtl .tundra .dijitTabContainerRight-tabs {
+	margin-right: 1px !important;
+}
+.dijitRtl .tundra .dijitTabContainerLeft-tabs .dijitTab,
+.dijitRtl .tundra .dijitTabContainerRight-tabs .dijitTab {
+	margin-left:0px;
+}
+.dj_ie-rtl .tundra .dijitTab .dijitTabInnerDiv {
+	width : 1% !important;
+}
+.dijitRtl .tundra .dijitSliderProgressBarH,
+.dijitRtl .tundra .dijitSliderRemainingBarH,
+.dijitRtl .tundra .dijitSliderLeftBumper,
+.dijitRtl .tundra .dijitSliderRightBumper,
+.dijitRtl .tundra .dijitSliderTopBumper {
+	background-position: top right;
+}
+.dijitRtl .tundra .dijitSliderProgressBarV,
+.dijitRtl .tundra .dijitSliderRemainingBarV,
+.dijitRtl .tundra .dijitSliderBottomBumper {
+	background-position: bottom right;
+}
+.dijitRtl .tundra .dijitSliderLeftBumper {
+	border-left-width: 0px;
+	border-right-width: 1px;
+}
+.dijitRtl .tundra .dijitSliderRightBumper {
+	border-left-width: 1px;
+	border-right-width: 0px;
+}
+.dijitRtl .tundra .dijitSliderIncrementIconH {
+	background-position: -7px 0px;
+}
+.dijitRtl .tundra .dijitSliderDecrementIconH {
+	background-position: -14px 0px;
+}
diff --git a/dijit/tree/ForestStoreModel.js b/dijit/tree/ForestStoreModel.js
new file mode 100644
index 0000000..4e49ff3
--- /dev/null
+++ b/dijit/tree/ForestStoreModel.js
@@ -0,0 +1,74 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.tree.ForestStoreModel"]){
+dojo._hasResource["dijit.tree.ForestStoreModel"]=true;
+dojo.provide("dijit.tree.ForestStoreModel");
+dojo.require("dijit.tree.TreeStoreModel");
+dojo.declare("dijit.tree.ForestStoreModel",dijit.tree.TreeStoreModel,{rootId:"$root$",rootLabel:"ROOT",query:null,constructor:function(_1){
+this.root={store:this,root:true,id:_1.rootId,label:_1.rootLabel,children:_1.rootChildren};
+},mayHaveChildren:function(_2){
+return _2===this.root||this.inherited(arguments);
+},getChildren:function(_3,_4,_5){
+if(_3===this.root){
+if(this.root.children){
+_4(this.root.children);
+}else{
+this.store.fetch({query:this.query,onComplete:dojo.hitch(this,function(_6){
+this.root.children=_6;
+_4(_6);
+}),onError:_5});
+}
+}else{
+this.inherited(arguments);
+}
+},getIdentity:function(_7){
+return (_7===this.root)?this.root.id:this.inherited(arguments);
+},getLabel:function(_8){
+return (_8===this.root)?this.root.label:this.inherited(arguments);
+},newItem:function(_9,_a){
+if(_a===this.root){
+this.onNewRootItem(_9);
+return this.store.newItem(_9);
+}else{
+return this.inherited(arguments);
+}
+},onNewRootItem:function(_b){
+},pasteItem:function(_c,_d,_e,_f,_10){
+if(_d===this.root){
+if(!_f){
+this.onLeaveRoot(_c);
+}
+}
+dijit.tree.TreeStoreModel.prototype.pasteItem.call(this,_c,_d===this.root?null:_d,_e===this.root?null:_e,_f,_10);
+if(_e===this.root){
+this.onAddToRoot(_c);
+}
+},onAddToRoot:function(_11){
+
+},onLeaveRoot:function(_12){
+
+},_requeryTop:function(){
+var _13=this.root.children||[];
+this.store.fetch({query:this.query,onComplete:dojo.hitch(this,function(_14){
+this.root.children=_14;
+if(_13.length!=_14.length||dojo.some(_13,function(_15,idx){
+return _14[idx]!=_15;
+})){
+this.onChildrenChange(this.root,_14);
+}
+})});
+},_onNewItem:function(_17,_18){
+this._requeryTop();
+this.inherited(arguments);
+},_onDeleteItem:function(_19){
+if(dojo.indexOf(this.root.children,_19)!=-1){
+this._requeryTop();
+}
+this.inherited(arguments);
+}});
+}
diff --git a/dijit/tree/TreeStoreModel.js b/dijit/tree/TreeStoreModel.js
new file mode 100644
index 0000000..6ed087a
--- /dev/null
+++ b/dijit/tree/TreeStoreModel.js
@@ -0,0 +1,122 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dijit.tree.TreeStoreModel"]){
+dojo._hasResource["dijit.tree.TreeStoreModel"]=true;
+dojo.provide("dijit.tree.TreeStoreModel");
+dojo.declare("dijit.tree.TreeStoreModel",null,{store:null,childrenAttrs:["children"],labelAttr:"",root:null,query:null,constructor:function(_1){
+dojo.mixin(this,_1);
+this.connects=[];
+var _2=this.store;
+if(!_2.getFeatures()["dojo.data.api.Identity"]){
+throw new Error("dijit.Tree: store must support dojo.data.Identity");
+}
+if(_2.getFeatures()["dojo.data.api.Notification"]){
+this.connects=this.connects.concat([dojo.connect(_2,"onNew",this,"_onNewItem"),dojo.connect(_2,"onDelete",this,"_onDeleteItem"),dojo.connect(_2,"onSet",this,"_onSetItem")]);
+}
+},destroy:function(){
+dojo.forEach(this.connects,dojo.disconnect);
+},getRoot:function(_3,_4){
+if(this.root){
+_3(this.root);
+}else{
+this.store.fetch({query:this.query,onComplete:dojo.hitch(this,function(_5){
+if(_5.length!=1){
+throw new Error(this.declaredClass+": query "+dojo.toJson(this.query)+" returned "+_5.length+" items, but must return exactly one item");
+}
+this.root=_5[0];
+_3(this.root);
+}),onError:_4});
+}
+},mayHaveChildren:function(_6){
+return dojo.some(this.childrenAttrs,function(_7){
+return this.store.hasAttribute(_6,_7);
+},this);
+},getChildren:function(_8,_9,_a){
+var _b=this.store;
+var _c=[];
+for(var i=0;i<this.childrenAttrs.length;i++){
+var _e=_b.getValues(_8,this.childrenAttrs[i]);
+_c=_c.concat(_e);
+}
+var _f=0;
+dojo.forEach(_c,function(_10){
+if(!_b.isItemLoaded(_10)){
+_f++;
+}
+});
+if(_f==0){
+_9(_c);
+}else{
+var _11=function _11(_12){
+if(--_f==0){
+_9(_c);
+}
+};
+dojo.forEach(_c,function(_13){
+if(!_b.isItemLoaded(_13)){
+_b.loadItem({item:_13,onItem:_11,onError:_a});
+}
+});
+}
+},getIdentity:function(_14){
+return this.store.getIdentity(_14);
+},getLabel:function(_15){
+if(this.labelAttr){
+return this.store.getValue(_15,this.labelAttr);
+}else{
+return this.store.getLabel(_15);
+}
+},newItem:function(_16,_17){
+var _18={parent:_17,attribute:this.childrenAttrs[0]};
+return this.store.newItem(_16,_18);
+},pasteItem:function(_19,_1a,_1b,_1c,_1d){
+var _1e=this.store,_1f=this.childrenAttrs[0];
+if(_1a){
+dojo.forEach(this.childrenAttrs,function(_20){
+if(_1e.containsValue(_1a,_20,_19)){
+if(!_1c){
+var _21=dojo.filter(_1e.getValues(_1a,_20),function(x){
+return x!=_19;
+});
+_1e.setValues(_1a,_20,_21);
+}
+_1f=_20;
+}
+});
+}
+if(_1b){
+if(typeof _1d=="number"){
+var _23=_1e.getValues(_1b,_1f);
+_23.splice(_1d,0,_19);
+_1e.setValues(_1b,_1f,_23);
+}else{
+_1e.setValues(_1b,_1f,_1e.getValues(_1b,_1f).concat(_19));
+}
+}
+},onChange:function(_24){
+},onChildrenChange:function(_25,_26){
+},onDelete:function(_27,_28){
+},_onNewItem:function(_29,_2a){
+if(!_2a){
+return;
+}
+this.getChildren(_2a.item,dojo.hitch(this,function(_2b){
+this.onChildrenChange(_2a.item,_2b);
+}));
+},_onDeleteItem:function(_2c){
+this.onDelete(_2c);
+},_onSetItem:function(_2d,_2e,_2f,_30){
+if(dojo.indexOf(this.childrenAttrs,_2e)!=-1){
+this.getChildren(_2d,dojo.hitch(this,function(_31){
+this.onChildrenChange(_2d,_31);
+}));
+}else{
+this.onChange(_2d);
+}
+}});
+}
diff --git a/dijit/tree/model.js b/dijit/tree/model.js
new file mode 100644
index 0000000..a40ca0c
--- /dev/null
+++ b/dijit/tree/model.js
@@ -0,0 +1,18 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+dojo.declare("dijit.tree.model",null,{destroy:function(){
+},getRoot:function(_1){
+},mayHaveChildren:function(_2){
+},getChildren:function(_3,_4){
+},getIdentity:function(_5){
+},getLabel:function(_6){
+},newItem:function(_7,_8){
+},pasteItem:function(_9,_a,_b,_c){
+},onChange:function(_d){
+},onChildrenChange:function(_e,_f){
+}});
diff --git a/dojo/AdapterRegistry.js b/dojo/AdapterRegistry.js
new file mode 100644
index 0000000..353d416
--- /dev/null
+++ b/dojo/AdapterRegistry.js
@@ -0,0 +1,39 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.AdapterRegistry"]){
+dojo._hasResource["dojo.AdapterRegistry"]=true;
+dojo.provide("dojo.AdapterRegistry");
+dojo.AdapterRegistry=function(_1){
+this.pairs=[];
+this.returnWrappers=_1||false;
+};
+dojo.extend(dojo.AdapterRegistry,{register:function(_2,_3,_4,_5,_6){
+this.pairs[((_6)?"unshift":"push")]([_2,_3,_4,_5]);
+},match:function(){
+for(var i=0;i<this.pairs.length;i++){
+var _8=this.pairs[i];
+if(_8[1].apply(this,arguments)){
+if((_8[3])||(this.returnWrappers)){
+return _8[2];
+}else{
+return _8[2].apply(this,arguments);
+}
+}
+}
+throw new Error("No match found");
+},unregister:function(_9){
+for(var i=0;i<this.pairs.length;i++){
+var _b=this.pairs[i];
+if(_b[0]==_9){
+this.pairs.splice(i,1);
+return true;
+}
+}
+return false;
+}});
+}
diff --git a/dojo/DeferredList.js b/dojo/DeferredList.js
new file mode 100644
index 0000000..9f406a1
--- /dev/null
+++ b/dojo/DeferredList.js
@@ -0,0 +1,69 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.DeferredList"]){
+dojo._hasResource["dojo.DeferredList"]=true;
+dojo.provide("dojo.DeferredList");
+dojo.declare("dojo.DeferredList",dojo.Deferred,{constructor:function(_1,_2,_3,_4,_5){
+this.list=_1;
+this.resultList=new Array(this.list.length);
+this.chain=[];
+this.id=this._nextId();
+this.fired=-1;
+this.paused=0;
+this.results=[null,null];
+this.canceller=_5;
+this.silentlyCancelled=false;
+if(this.list.length===0&&!_2){
+this.callback(this.resultList);
+}
+this.finishedCount=0;
+this.fireOnOneCallback=_2;
+this.fireOnOneErrback=_3;
+this.consumeErrors=_4;
+dojo.forEach(this.list,function(d,_7){
+d.addCallback(this,function(r){
+this._cbDeferred(_7,true,r);
+return r;
+});
+d.addErrback(this,function(r){
+this._cbDeferred(_7,false,r);
+return r;
+});
+},this);
+},_cbDeferred:function(_a,_b,_c){
+this.resultList[_a]=[_b,_c];
+this.finishedCount+=1;
+if(this.fired!==0){
+if(_b&&this.fireOnOneCallback){
+this.callback([_a,_c]);
+}else{
+if(!_b&&this.fireOnOneErrback){
+this.errback(_c);
+}else{
+if(this.finishedCount==this.list.length){
+this.callback(this.resultList);
+}
+}
+}
+}
+if(!_b&&this.consumeErrors){
+_c=null;
+}
+return _c;
+},gatherResults:function(_d){
+var d=new dojo.DeferredList(_d,false,true,false);
+d.addCallback(function(_f){
+var ret=[];
+dojo.forEach(_f,function(_11){
+ret.push(_11[1]);
+});
+return ret;
+});
+return d;
+}});
+}
diff --git a/dojo/LICENSE b/dojo/LICENSE
new file mode 100644
index 0000000..ad1676a
--- /dev/null
+++ b/dojo/LICENSE
@@ -0,0 +1,195 @@
+Dojo is available under *either* the terms of the modified BSD license *or* the
+Academic Free License version 2.1. As a recipient of Dojo, you may choose which
+license to receive this code under (except as noted in per-module LICENSE
+files). Some modules may not be the copyright of the Dojo Foundation. These
+modules contain explicit declarations of copyright in both the LICENSE files in
+the directories in which they reside and in the code itself. No external
+contributions are allowed under licenses which are fundamentally incompatible
+with the AFL or BSD licenses that Dojo is distributed under.
+
+The text of the AFL and BSD licenses is reproduced below. 
+
+-------------------------------------------------------------------------------
+The "New" BSD License:
+**********************
+
+Copyright (c) 2005-2009, The Dojo Foundation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice, this
+    list of conditions and the following disclaimer.
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+  * Neither the name of the Dojo Foundation nor the names of its contributors
+    may be used to endorse or promote products derived from this software
+    without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+-------------------------------------------------------------------------------
+The Academic Free License, v. 2.1:
+**********************************
+
+This Academic Free License (the "License") applies to any original work of
+authorship (the "Original Work") whose owner (the "Licensor") has placed the
+following notice immediately following the copyright notice for the Original
+Work:
+
+Licensed under the Academic Free License version 2.1
+
+1) Grant of Copyright License. Licensor hereby grants You a world-wide,
+royalty-free, non-exclusive, perpetual, sublicenseable license to do the
+following:
+
+a) to reproduce the Original Work in copies;
+
+b) to prepare derivative works ("Derivative Works") based upon the Original
+Work;
+
+c) to distribute copies of the Original Work and Derivative Works to the
+public;
+
+d) to perform the Original Work publicly; and
+
+e) to display the Original Work publicly.
+
+2) Grant of Patent License. Licensor hereby grants You a world-wide,
+royalty-free, non-exclusive, perpetual, sublicenseable license, under patent
+claims owned or controlled by the Licensor that are embodied in the Original
+Work as furnished by the Licensor, to make, use, sell and offer for sale the
+Original Work and Derivative Works.
+
+3) Grant of Source Code License. The term "Source Code" means the preferred
+form of the Original Work for making modifications to it and all available
+documentation describing how to modify the Original Work. Licensor hereby
+agrees to provide a machine-readable copy of the Source Code of the Original
+Work along with each copy of the Original Work that Licensor distributes.
+Licensor reserves the right to satisfy this obligation by placing a
+machine-readable copy of the Source Code in an information repository
+reasonably calculated to permit inexpensive and convenient access by You for as
+long as Licensor continues to distribute the Original Work, and by publishing
+the address of that information repository in a notice immediately following
+the copyright notice that applies to the Original Work.
+
+4) Exclusions From License Grant. Neither the names of Licensor, nor the names
+of any contributors to the Original Work, nor any of their trademarks or
+service marks, may be used to endorse or promote products derived from this
+Original Work without express prior written permission of the Licensor. Nothing
+in this License shall be deemed to grant any rights to trademarks, copyrights,
+patents, trade secrets or any other intellectual property of Licensor except as
+expressly stated herein. No patent license is granted to make, use, sell or
+offer to sell embodiments of any patent claims other than the licensed claims
+defined in Section 2. No right is granted to the trademarks of Licensor even if
+such marks are included in the Original Work. Nothing in this License shall be
+interpreted to prohibit Licensor from licensing under different terms from this
+License any Original Work that Licensor otherwise would have a right to
+license.
+
+5) This section intentionally omitted.
+
+6) Attribution Rights. You must retain, in the Source Code of any Derivative
+Works that You create, all copyright, patent or trademark notices from the
+Source Code of the Original Work, as well as any notices of licensing and any
+descriptive text identified therein as an "Attribution Notice." You must cause
+the Source Code for any Derivative Works that You create to carry a prominent
+Attribution Notice reasonably calculated to inform recipients that You have
+modified the Original Work.
+
+7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that
+the copyright in and to the Original Work and the patent rights granted herein
+by Licensor are owned by the Licensor or are sublicensed to You under the terms
+of this License with the permission of the contributor(s) of those copyrights
+and patent rights. Except as expressly stated in the immediately proceeding
+sentence, the Original Work is provided under this License on an "AS IS" BASIS
+and WITHOUT WARRANTY, either express or implied, including, without limitation,
+the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU.
+This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No
+license to Original Work is granted hereunder except under this disclaimer.
+
+8) Limitation of Liability. Under no circumstances and under no legal theory,
+whether in tort (including negligence), contract, or otherwise, shall the
+Licensor be liable to any person for any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License
+or the use of the Original Work including, without limitation, damages for loss
+of goodwill, work stoppage, computer failure or malfunction, or any and all
+other commercial damages or losses. This limitation of liability shall not
+apply to liability for death or personal injury resulting from Licensor's
+negligence to the extent applicable law prohibits such limitation. Some
+jurisdictions do not allow the exclusion or limitation of incidental or
+consequential damages, so this exclusion and limitation may not apply to You.
+
+9) Acceptance and Termination. If You distribute copies of the Original Work or
+a Derivative Work, You must make a reasonable effort under the circumstances to
+obtain the express assent of recipients to the terms of this License. Nothing
+else but this License (or another written agreement between Licensor and You)
+grants You permission to create Derivative Works based upon the Original Work
+or to exercise any of the rights granted in Section 1 herein, and any attempt
+to do so except under the terms of this License (or another written agreement
+between Licensor and You) is expressly prohibited by U.S. copyright law, the
+equivalent laws of other countries, and by international treaty. Therefore, by
+exercising any of the rights granted to You in Section 1 herein, You indicate
+Your acceptance of this License and all of its terms and conditions.
+
+10) Termination for Patent Action. This License shall terminate automatically
+and You may no longer exercise any of the rights granted to You by this License
+as of the date You commence an action, including a cross-claim or counterclaim,
+against Licensor or any licensee alleging that the Original Work infringes a
+patent. This termination provision shall not apply for an action alleging
+patent infringement by combinations of the Original Work with other software or
+hardware.
+
+11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this
+License may be brought only in the courts of a jurisdiction wherein the
+Licensor resides or in which Licensor conducts its primary business, and under
+the laws of that jurisdiction excluding its conflict-of-law provisions. The
+application of the United Nations Convention on Contracts for the International
+Sale of Goods is expressly excluded. Any use of the Original Work outside the
+scope of this License or after its termination shall be subject to the
+requirements and penalties of the U.S. Copyright Act, 17 U.S.C. § 101 et
+seq., the equivalent laws of other countries, and international treaty. This
+section shall survive the termination of this License.
+
+12) Attorneys Fees. In any action to enforce the terms of this License or
+seeking damages relating thereto, the prevailing party shall be entitled to
+recover its costs and expenses, including, without limitation, reasonable
+attorneys' fees and costs incurred in connection with such action, including
+any appeal of such action. This section shall survive the termination of this
+License.
+
+13) Miscellaneous. This License represents the complete agreement concerning
+the subject matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent necessary to
+make it enforceable.
+
+14) Definition of "You" in This License. "You" throughout this License, whether
+in upper or lower case, means an individual or a legal entity exercising rights
+under, and complying with all of the terms of, this License. For legal
+entities, "You" includes any entity that controls, is controlled by, or is
+under common control with you. For purposes of this definition, "control" means
+(i) the power, direct or indirect, to cause the direction or management of such
+entity, whether by contract or otherwise, or (ii) ownership of fifty percent
+(50%) or more of the outstanding shares, or (iii) beneficial ownership of such
+entity.
+
+15) Right to Use. You may use the Original Work in all ways not otherwise
+restricted or conditioned by this License or by law, and Licensor promises not
+to interfere with or be responsible for such uses by You.
+
+This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved.
+Permission is hereby granted to copy and distribute this license without
+modification. This license may not be modified without the express written
+permission of its copyright owner.
diff --git a/dojo/NodeList-fx.js b/dojo/NodeList-fx.js
new file mode 100644
index 0000000..76a26fd
--- /dev/null
+++ b/dojo/NodeList-fx.js
@@ -0,0 +1,40 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.NodeList-fx"]){
+dojo._hasResource["dojo.NodeList-fx"]=true;
+dojo.provide("dojo.NodeList-fx");
+dojo.require("dojo.fx");
+dojo.extend(dojo.NodeList,{_anim:function(_1,_2,_3){
+_3=_3||{};
+return dojo.fx.combine(this.map(function(_4){
+var _5={node:_4};
+dojo.mixin(_5,_3);
+return _1[_2](_5);
+}));
+},wipeIn:function(_6){
+return this._anim(dojo.fx,"wipeIn",_6);
+},wipeOut:function(_7){
+return this._anim(dojo.fx,"wipeOut",_7);
+},slideTo:function(_8){
+return this._anim(dojo.fx,"slideTo",_8);
+},fadeIn:function(_9){
+return this._anim(dojo,"fadeIn",_9);
+},fadeOut:function(_a){
+return this._anim(dojo,"fadeOut",_a);
+},animateProperty:function(_b){
+return this._anim(dojo,"animateProperty",_b);
+},anim:function(_c,_d,_e,_f,_10){
+var _11=dojo.fx.combine(this.map(function(_12){
+return dojo.animateProperty({node:_12,properties:_c,duration:_d||350,easing:_e});
+}));
+if(_f){
+dojo.connect(_11,"onEnd",_f);
+}
+return _11.play(_10||0);
+}});
+}
diff --git a/dojo/NodeList-html.js b/dojo/NodeList-html.js
new file mode 100644
index 0000000..76281ee
--- /dev/null
+++ b/dojo/NodeList-html.js
@@ -0,0 +1,21 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.NodeList-html"]){
+dojo._hasResource["dojo.NodeList-html"]=true;
+dojo.provide("dojo.NodeList-html");
+dojo.require("dojo.html");
+dojo.extend(dojo.NodeList,{html:function(_1,_2){
+var _3=new dojo.html._ContentSetter(_2||{});
+this.forEach(function(_4){
+_3.node=_4;
+_3.set(_1);
+_3.tearDown();
+});
+return this;
+}});
+}
diff --git a/dojo/OpenAjax.js b/dojo/OpenAjax.js
new file mode 100644
index 0000000..5f7c344
--- /dev/null
+++ b/dojo/OpenAjax.js
@@ -0,0 +1,155 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!window["OpenAjax"]){
+OpenAjax=new function(){
+var t=true;
+var f=false;
+var g=window;
+var _4;
+var _5="org.openajax.hub.";
+var h={};
+this.hub=h;
+h.implementer="http://openajax.org";
+h.implVersion="0.6";
+h.specVersion="0.6";
+h.implExtraData={};
+var _4={};
+h.libraries=_4;
+h.registerLibrary=function(_7,_8,_9,_a){
+_4[_7]={prefix:_7,namespaceURI:_8,version:_9,extraData:_a};
+this.publish(_5+"registerLibrary",_4[_7]);
+};
+h.unregisterLibrary=function(_b){
+this.publish(_5+"unregisterLibrary",_4[_b]);
+delete _4[_b];
+};
+h._subscriptions={c:{},s:[]};
+h._cleanup=[];
+h._subIndex=0;
+h._pubDepth=0;
+h.subscribe=function(_c,_d,_e,_f,_10){
+if(!_e){
+_e=window;
+}
+var _11=_c+"."+this._subIndex;
+var sub={scope:_e,cb:_d,fcb:_10,data:_f,sid:this._subIndex++,hdl:_11};
+var _13=_c.split(".");
+this._subscribe(this._subscriptions,_13,0,sub);
+return _11;
+};
+h.publish=function(_14,_15){
+var _16=_14.split(".");
+this._pubDepth++;
+this._publish(this._subscriptions,_16,0,_14,_15);
+this._pubDepth--;
+if((this._cleanup.length>0)&&(this._pubDepth==0)){
+for(var i=0;i<this._cleanup.length;i++){
+this.unsubscribe(this._cleanup[i].hdl);
+}
+delete (this._cleanup);
+this._cleanup=[];
+}
+};
+h.unsubscribe=function(sub){
+var _19=sub.split(".");
+var sid=_19.pop();
+this._unsubscribe(this._subscriptions,_19,0,sid);
+};
+h._subscribe=function(_1b,_1c,_1d,sub){
+var _1f=_1c[_1d];
+if(_1d==_1c.length){
+_1b.s.push(sub);
+}else{
+if(typeof _1b.c=="undefined"){
+_1b.c={};
+}
+if(typeof _1b.c[_1f]=="undefined"){
+_1b.c[_1f]={c:{},s:[]};
+this._subscribe(_1b.c[_1f],_1c,_1d+1,sub);
+}else{
+this._subscribe(_1b.c[_1f],_1c,_1d+1,sub);
+}
+}
+};
+h._publish=function(_20,_21,_22,_23,msg){
+if(typeof _20!="undefined"){
+var _25;
+if(_22==_21.length){
+_25=_20;
+}else{
+this._publish(_20.c[_21[_22]],_21,_22+1,_23,msg);
+this._publish(_20.c["*"],_21,_22+1,_23,msg);
+_25=_20.c["**"];
+}
+if(typeof _25!="undefined"){
+var _26=_25.s;
+var max=_26.length;
+for(var i=0;i<max;i++){
+if(_26[i].cb){
+var sc=_26[i].scope;
+var cb=_26[i].cb;
+var fcb=_26[i].fcb;
+var d=_26[i].data;
+if(typeof cb=="string"){
+cb=sc[cb];
+}
+if(typeof fcb=="string"){
+fcb=sc[fcb];
+}
+if((!fcb)||(fcb.call(sc,_23,msg,d))){
+cb.call(sc,_23,msg,d);
+}
+}
+}
+}
+}
+};
+h._unsubscribe=function(_2d,_2e,_2f,sid){
+if(typeof _2d!="undefined"){
+if(_2f<_2e.length){
+var _31=_2d.c[_2e[_2f]];
+this._unsubscribe(_31,_2e,_2f+1,sid);
+if(_31.s.length==0){
+for(var x in _31.c){
+return;
+}
+delete _2d.c[_2e[_2f]];
+}
+return;
+}else{
+var _33=_2d.s;
+var max=_33.length;
+for(var i=0;i<max;i++){
+if(sid==_33[i].sid){
+if(this._pubDepth>0){
+_33[i].cb=null;
+this._cleanup.push(_33[i]);
+}else{
+_33.splice(i,1);
+}
+return;
+}
+}
+}
+}
+};
+h.reinit=function(){
+for(var lib in OpenAjax.hub.libraries){
+delete OpenAjax.hub.libraries[lib];
+}
+OpenAjax.hub.registerLibrary("OpenAjax","http://openajax.org/hub","0.6",{});
+delete OpenAjax._subscriptions;
+OpenAjax._subscriptions={c:{},s:[]};
+delete OpenAjax._cleanup;
+OpenAjax._cleanup=[];
+OpenAjax._subIndex=0;
+OpenAjax._pubDepth=0;
+};
+};
+OpenAjax.hub.registerLibrary("OpenAjax","http://openajax.org/hub","0.6",{});
+}
diff --git a/dojo/_base.js b/dojo/_base.js
new file mode 100644
index 0000000..9fff822
--- /dev/null
+++ b/dojo/_base.js
@@ -0,0 +1,19 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._base"]){
+dojo._hasResource["dojo._base"]=true;
+dojo.provide("dojo._base");
+dojo.require("dojo._base.lang");
+dojo.require("dojo._base.declare");
+dojo.require("dojo._base.connect");
+dojo.require("dojo._base.Deferred");
+dojo.require("dojo._base.json");
+dojo.require("dojo._base.array");
+dojo.require("dojo._base.Color");
+dojo.requireIf(dojo.isBrowser,"dojo._base.browser");
+}
diff --git a/dojo/_base/Color.js b/dojo/_base/Color.js
new file mode 100644
index 0000000..23d662a
--- /dev/null
+++ b/dojo/_base/Color.js
@@ -0,0 +1,102 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._base.Color"]){
+dojo._hasResource["dojo._base.Color"]=true;
+dojo.provide("dojo._base.Color");
+dojo.require("dojo._base.array");
+dojo.require("dojo._base.lang");
+(function(){
+var d=dojo;
+dojo.Color=function(_2){
+if(_2){
+this.setColor(_2);
+}
+};
+dojo.Color.named={black:[0,0,0],silver:[192,192,192],gray:[128,128,128],white:[255,255,255],maroon:[128,0,0],red:[255,0,0],purple:[128,0,128],fuchsia:[255,0,255],green:[0,128,0],lime:[0,255,0],olive:[128,128,0],yellow:[255,255,0],navy:[0,0,128],blue:[0,0,255],teal:[0,128,128],aqua:[0,255,255]};
+dojo.extend(dojo.Color,{r:255,g:255,b:255,a:1,_set:function(r,g,b,a){
+var t=this;
+t.r=r;
+t.g=g;
+t.b=b;
+t.a=a;
+},setColor:function(_8){
+if(d.isString(_8)){
+d.colorFromString(_8,this);
+}else{
+if(d.isArray(_8)){
+d.colorFromArray(_8,this);
+}else{
+this._set(_8.r,_8.g,_8.b,_8.a);
+if(!(_8 instanceof d.Color)){
+this.sanitize();
+}
+}
+}
+return this;
+},sanitize:function(){
+return this;
+},toRgb:function(){
+var t=this;
+return [t.r,t.g,t.b];
+},toRgba:function(){
+var t=this;
+return [t.r,t.g,t.b,t.a];
+},toHex:function(){
+var _b=d.map(["r","g","b"],function(x){
+var s=this[x].toString(16);
+return s.length<2?"0"+s:s;
+},this);
+return "#"+_b.join("");
+},toCss:function(_e){
+var t=this,rgb=t.r+", "+t.g+", "+t.b;
+return (_e?"rgba("+rgb+", "+t.a:"rgb("+rgb)+")";
+},toString:function(){
+return this.toCss(true);
+}});
+dojo.blendColors=function(_11,end,_13,obj){
+var t=obj||new d.Color();
+d.forEach(["r","g","b","a"],function(x){
+t[x]=_11[x]+(end[x]-_11[x])*_13;
+if(x!="a"){
+t[x]=Math.round(t[x]);
+}
+});
+return t.sanitize();
+};
+dojo.colorFromRgb=function(_17,obj){
+var m=_17.toLowerCase().match(/^rgba?\(([\s\.,0-9]+)\)/);
+return m&&dojo.colorFromArray(m[1].split(/\s*,\s*/),obj);
+};
+dojo.colorFromHex=function(_1a,obj){
+var t=obj||new d.Color(),_1d=(_1a.length==4)?4:8,_1e=(1<<_1d)-1;
+_1a=Number("0x"+_1a.substr(1));
+if(isNaN(_1a)){
+return null;
+}
+d.forEach(["b","g","r"],function(x){
+var c=_1a&_1e;
+_1a>>=_1d;
+t[x]=_1d==4?17*c:c;
+});
+t.a=1;
+return t;
+};
+dojo.colorFromArray=function(a,obj){
+var t=obj||new d.Color();
+t._set(Number(a[0]),Number(a[1]),Number(a[2]),Number(a[3]));
+if(isNaN(t.a)){
+t.a=1;
+}
+return t.sanitize();
+};
+dojo.colorFromString=function(str,obj){
+var a=d.Color.named[str];
+return a&&d.colorFromArray(a,obj)||d.colorFromRgb(str,obj)||d.colorFromHex(str,obj);
+};
+})();
+}
diff --git a/dojo/_base/Deferred.js b/dojo/_base/Deferred.js
new file mode 100644
index 0000000..9944304
--- /dev/null
+++ b/dojo/_base/Deferred.js
@@ -0,0 +1,132 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._base.Deferred"]){
+dojo._hasResource["dojo._base.Deferred"]=true;
+dojo.provide("dojo._base.Deferred");
+dojo.require("dojo._base.lang");
+dojo.Deferred=function(_1){
+this.chain=[];
+this.id=this._nextId();
+this.fired=-1;
+this.paused=0;
+this.results=[null,null];
+this.canceller=_1;
+this.silentlyCancelled=false;
+};
+dojo.extend(dojo.Deferred,{_nextId:(function(){
+var n=1;
+return function(){
+return n++;
+};
+})(),cancel:function(){
+var _3;
+if(this.fired==-1){
+if(this.canceller){
+_3=this.canceller(this);
+}else{
+this.silentlyCancelled=true;
+}
+if(this.fired==-1){
+if(!(_3 instanceof Error)){
+var _4=_3;
+var _5="Deferred Cancelled";
+if(_3&&_3.toString){
+_5+=": "+_3.toString();
+}
+_3=new Error(_5);
+_3.dojoType="cancel";
+_3.cancelResult=_4;
+}
+this.errback(_3);
+}
+}else{
+if((this.fired==0)&&(this.results[0] instanceof dojo.Deferred)){
+this.results[0].cancel();
+}
+}
+},_resback:function(_6){
+this.fired=((_6 instanceof Error)?1:0);
+this.results[this.fired]=_6;
+this._fire();
+},_check:function(){
+if(this.fired!=-1){
+if(!this.silentlyCancelled){
+throw new Error("already called!");
+}
+this.silentlyCancelled=false;
+return;
+}
+},callback:function(_7){
+this._check();
+this._resback(_7);
+},errback:function(_8){
+this._check();
+if(!(_8 instanceof Error)){
+_8=new Error(_8);
+}
+this._resback(_8);
+},addBoth:function(cb,_a){
+var _b=dojo.hitch.apply(dojo,arguments);
+return this.addCallbacks(_b,_b);
+},addCallback:function(cb,_d){
+return this.addCallbacks(dojo.hitch.apply(dojo,arguments));
+},addErrback:function(cb,_f){
+return this.addCallbacks(null,dojo.hitch.apply(dojo,arguments));
+},addCallbacks:function(cb,eb){
+this.chain.push([cb,eb]);
+if(this.fired>=0){
+this._fire();
+}
+return this;
+},_fire:function(){
+var _12=this.chain;
+var _13=this.fired;
+var res=this.results[_13];
+var _15=this;
+var cb=null;
+while((_12.length>0)&&(this.paused==0)){
+var f=_12.shift()[_13];
+if(!f){
+continue;
+}
+var _18=function(){
+var ret=f(res);
+if(typeof ret!="undefined"){
+res=ret;
+}
+_13=((res instanceof Error)?1:0);
+if(res instanceof dojo.Deferred){
+cb=function(res){
+_15._resback(res);
+_15.paused--;
+if((_15.paused==0)&&(_15.fired>=0)){
+_15._fire();
+}
+};
+this.paused++;
+}
+};
+if(dojo.config.debugAtAllCosts){
+_18.call(this);
+}else{
+try{
+_18.call(this);
+}
+catch(err){
+_13=1;
+res=err;
+}
+}
+}
+this.fired=_13;
+this.results[_13]=res;
+if((cb)&&(this.paused)){
+res.addBoth(cb);
+}
+}});
+}
diff --git a/dojo/_base/NodeList.js b/dojo/_base/NodeList.js
new file mode 100644
index 0000000..7074b1a
--- /dev/null
+++ b/dojo/_base/NodeList.js
@@ -0,0 +1,164 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._base.NodeList"]){
+dojo._hasResource["dojo._base.NodeList"]=true;
+dojo.provide("dojo._base.NodeList");
+dojo.require("dojo._base.lang");
+dojo.require("dojo._base.array");
+(function(){
+var d=dojo;
+var ap=Array.prototype,_3=ap.slice,_4=ap.concat;
+var _5=function(a){
+a.constructor=d.NodeList;
+dojo._mixin(a,d.NodeList.prototype);
+return a;
+};
+var _7=function(f,a,o){
+a=[0].concat(_3.call(a,0));
+if(!a.sort){
+a=_3.call(a,0);
+}
+o=o||d.global;
+return function(_b){
+a[0]=_b;
+return f.apply(o,a);
+};
+};
+var _c=function(f,o){
+return function(){
+this.forEach(_7(f,arguments,o));
+return this;
+};
+};
+var _f=function(f,o){
+return function(){
+return this.map(_7(f,arguments,o));
+};
+};
+var _12=function(f,o){
+return function(){
+return this.filter(_7(f,arguments,o));
+};
+};
+var _15=function(f,g,o){
+return function(){
+var a=arguments,_1a=_7(f,a,o);
+if(g.call(o||d.global,a)){
+return this.map(_1a);
+}
+this.forEach(_1a);
+return this;
+};
+};
+var _1b=function(a){
+return a.length==1&&d.isString(a[0]);
+};
+var _1d=function(_1e){
+var p=_1e.parentNode;
+if(p){
+p.removeChild(_1e);
+}
+};
+dojo.NodeList=function(){
+return _5(Array.apply(null,arguments));
+};
+var nl=d.NodeList,nlp=nl.prototype;
+nl._wrap=_5;
+nl._adaptAsMap=_f;
+nl._adaptAsForEach=_c;
+nl._adaptAsFilter=_12;
+nl._adaptWithCondition=_15;
+d.forEach(["slice","splice"],function(_22){
+var f=ap[_22];
+nlp[_22]=function(){
+return _5(f.apply(this,arguments));
+};
+});
+d.forEach(["indexOf","lastIndexOf","every","some"],function(_24){
+var f=d[_24];
+nlp[_24]=function(){
+return f.apply(d,[this].concat(_3.call(arguments,0)));
+};
+});
+d.forEach(["attr","style"],function(_26){
+nlp[_26]=_15(d[_26],_1b);
+});
+d.forEach(["connect","addClass","removeClass","toggleClass","empty"],function(_27){
+nlp[_27]=_c(d[_27]);
+});
+dojo.extend(dojo.NodeList,{concat:function(_28){
+var t=d.isArray(this)?this:_3.call(this,0),m=d.map(arguments,function(a){
+return a&&!d.isArray(a)&&(a.constructor===NodeList||a.constructor==nl)?_3.call(a,0):a;
+});
+return _5(_4.apply(t,m));
+},map:function(_2c,obj){
+return _5(d.map(this,_2c,obj));
+},forEach:function(_2e,_2f){
+d.forEach(this,_2e,_2f);
+return this;
+},coords:_f(d.coords),place:function(_30,_31){
+var _32=d.query(_30)[0];
+return this.forEach(function(_33){
+d.place(_33,_32,_31);
+});
+},orphan:function(_34){
+return (_34?d._filterQueryResult(this,_34):this).forEach(_1d);
+},adopt:function(_35,_36){
+return d.query(_35).place(this[0],_36);
+},query:function(_37){
+if(!_37){
+return this;
+}
+var ret=this.map(function(_39){
+return d.query(_37,_39).filter(function(_3a){
+return _3a!==undefined;
+});
+});
+return _5(_4.apply([],ret));
+},filter:function(_3b){
+var a=arguments,_3d=this,_3e=0;
+if(d.isString(_3b)){
+_3d=d._filterQueryResult(this,a[0]);
+if(a.length==1){
+return _3d;
+}
+_3e=1;
+}
+return _5(d.filter(_3d,a[_3e],a[_3e+1]));
+},addContent:function(_3f,_40){
+var c=d.isString(_3f)?d._toDom(_3f,this[0]&&this[0].ownerDocument):_3f,i,l=this.length-1;
+for(i=0;i<l;++i){
+d.place(c.cloneNode(true),this[i],_40);
+}
+if(l>=0){
+d.place(c,this[l],_40);
+}
+return this;
+},instantiate:function(_44,_45){
+var c=d.isFunction(_44)?_44:d.getObject(_44);
+_45=_45||{};
+return this.forEach(function(_47){
+new c(_45,_47);
+});
+},at:function(){
+var t=new dojo.NodeList();
+d.forEach(arguments,function(i){
+if(this[i]){
+t.push(this[i]);
+}
+},this);
+return t;
+}});
+d.forEach(["blur","focus","change","click","error","keydown","keypress","keyup","load","mousedown","mouseenter","mouseleave","mousemove","mouseout","mouseover","mouseup","submit"],function(evt){
+var _oe="on"+evt;
+nlp[_oe]=function(a,b){
+return this.connect(_oe,a,b);
+};
+});
+})();
+}
diff --git a/dojo/_base/_loader/bootstrap.js b/dojo/_base/_loader/bootstrap.js
new file mode 100644
index 0000000..7f21fcc
--- /dev/null
+++ b/dojo/_base/_loader/bootstrap.js
@@ -0,0 +1,108 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+(function(){
+if(typeof this["loadFirebugConsole"]=="function"){
+this["loadFirebugConsole"]();
+}else{
+this.console=this.console||{};
+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 _4=tn+"";
+console[_4]=("log" in console)?function(){
+var a=Array.apply({},arguments);
+a.unshift(_4+":");
+console["log"](a.join(" "));
+}:function(){
+};
+})();
+}
+}
+}
+if(typeof dojo=="undefined"){
+this.dojo={_scopeName:"dojo",_scopePrefix:"",_scopePrefixArgs:"",_scopeSuffix:"",_scopeMap:{},_scopeMapRev:{}};
+}
+var d=dojo;
+if(typeof dijit=="undefined"){
+this.dijit={_scopeName:"dijit"};
+}
+if(typeof dojox=="undefined"){
+this.dojox={_scopeName:"dojox"};
+}
+if(!d._scopeArgs){
+d._scopeArgs=[dojo,dijit,dojox];
+}
+d.global=this;
+d.config={isDebug:false,debugAtAllCosts:false};
+if(typeof djConfig!="undefined"){
+for(var _7 in djConfig){
+d.config[_7]=djConfig[_7];
+}
+}
+dojo.locale=d.config.locale;
+var _8="$Rev: 18832 $".match(/\d+/);
+dojo.version={major:1,minor:3,patch:2,flag:"",revision:_8?+_8[0]:NaN,toString:function(){
+with(d.version){
+return major+"."+minor+"."+patch+flag+" ("+revision+")";
+}
+}};
+if(typeof OpenAjax!="undefined"){
+OpenAjax.hub.registerLibrary(dojo._scopeName,"http://dojotoolkit.org",d.version.toString());
+}
+var _9={};
+dojo._mixin=function(_a,_b){
+for(var x in _b){
+if(_9[x]===undefined||_9[x]!=_b[x]){
+_a[x]=_b[x];
+}
+}
+if(d.isIE&&_b){
+var p=_b.toString;
+if(typeof p=="function"&&p!=_a.toString&&p!=_9.toString&&p!="\nfunction toString() {\n    [native code]\n}\n"){
+_a.toString=_b.toString;
+}
+}
+return _a;
+};
+dojo.mixin=function(_e,_f){
+if(!_e){
+_e={};
+}
+for(var i=1,l=arguments.length;i<l;i++){
+d._mixin(_e,arguments[i]);
+}
+return _e;
+};
+dojo._getProp=function(_12,_13,_14){
+var obj=_14||d.global;
+for(var i=0,p;obj&&(p=_12[i]);i++){
+if(i==0&&this._scopeMap[p]){
+p=this._scopeMap[p];
+}
+obj=(p in obj?obj[p]:(_13?obj[p]={}:undefined));
+}
+return obj;
+};
+dojo.setObject=function(_18,_19,_1a){
+var _1b=_18.split("."),p=_1b.pop(),obj=d._getProp(_1b,true,_1a);
+return obj&&p?(obj[p]=_19):undefined;
+};
+dojo.getObject=function(_1e,_1f,_20){
+return d._getProp(_1e.split("."),_1f,_20);
+};
+dojo.exists=function(_21,obj){
+return !!d.getObject(_21,false,obj);
+};
+dojo["eval"]=function(_23){
+return d.global.eval?d.global.eval(_23):eval(_23);
+};
+d.deprecated=d.experimental=function(){
+};
+})();
diff --git a/dojo/_base/_loader/hostenv_browser.js b/dojo/_base/_loader/hostenv_browser.js
new file mode 100644
index 0000000..8344294
--- /dev/null
+++ b/dojo/_base/_loader/hostenv_browser.js
@@ -0,0 +1,234 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(typeof window!="undefined"){
+dojo.isBrowser=true;
+dojo._name="browser";
+(function(){
+var d=dojo;
+if(document&&document.getElementsByTagName){
+var _2=document.getElementsByTagName("script");
+var _3=/dojo(\.xd)?\.js(\W|$)/i;
+for(var i=0;i<_2.length;i++){
+var _5=_2[i].getAttribute("src");
+if(!_5){
+continue;
+}
+var m=_5.match(_3);
+if(m){
+if(!d.config.baseUrl){
+d.config.baseUrl=_5.substring(0,m.index);
+}
+var _7=_2[i].getAttribute("djConfig");
+if(_7){
+var _8=eval("({ "+_7+" })");
+for(var x in _8){
+dojo.config[x]=_8[x];
+}
+}
+break;
+}
+}
+}
+d.baseUrl=d.config.baseUrl;
+var n=navigator;
+var _b=n.userAgent,_c=n.appVersion,tv=parseFloat(_c);
+if(_b.indexOf("Opera")>=0){
+d.isOpera=tv;
+}
+if(_b.indexOf("AdobeAIR")>=0){
+d.isAIR=1;
+}
+d.isKhtml=(_c.indexOf("Konqueror")>=0)?tv:0;
+d.isWebKit=parseFloat(_b.split("WebKit/")[1])||undefined;
+d.isChrome=parseFloat(_b.split("Chrome/")[1])||undefined;
+var _e=Math.max(_c.indexOf("WebKit"),_c.indexOf("Safari"),0);
+if(_e&&!dojo.isChrome){
+d.isSafari=parseFloat(_c.split("Version/")[1]);
+if(!d.isSafari||parseFloat(_c.substr(_e+7))<=419.3){
+d.isSafari=2;
+}
+}
+if(_b.indexOf("Gecko")>=0&&!d.isKhtml&&!d.isWebKit){
+d.isMozilla=d.isMoz=tv;
+}
+if(d.isMoz){
+d.isFF=parseFloat(_b.split("Firefox/")[1]||_b.split("Minefield/")[1]||_b.split("Shiretoko/")[1])||undefined;
+}
+if(document.all&&!d.isOpera){
+d.isIE=parseFloat(_c.split("MSIE ")[1])||undefined;
+if(d.isIE>=8&&document.documentMode!=5){
+d.isIE=document.documentMode;
+}
+}
+if(dojo.isIE&&window.location.protocol==="file:"){
+dojo.config.ieForceActiveXXhr=true;
+}
+var cm=document.compatMode;
+d.isQuirks=cm=="BackCompat"||cm=="QuirksMode"||d.isIE<6;
+d.locale=dojo.config.locale||(d.isIE?n.userLanguage:n.language).toLowerCase();
+d._XMLHTTP_PROGIDS=["Msxml2.XMLHTTP","Microsoft.XMLHTTP","Msxml2.XMLHTTP.4.0"];
+d._xhrObj=function(){
+var _10,_11;
+if(!dojo.isIE||!dojo.config.ieForceActiveXXhr){
+try{
+_10=new XMLHttpRequest();
+}
+catch(e){
+}
+}
+if(!_10){
+for(var i=0;i<3;++i){
+var _13=d._XMLHTTP_PROGIDS[i];
+try{
+_10=new ActiveXObject(_13);
+}
+catch(e){
+_11=e;
+}
+if(_10){
+d._XMLHTTP_PROGIDS=[_13];
+break;
+}
+}
+}
+if(!_10){
+throw new Error("XMLHTTP not available: "+_11);
+}
+return _10;
+};
+d._isDocumentOk=function(_14){
+var _15=_14.status||0;
+return (_15>=200&&_15<300)||_15==304||_15==1223||(!_15&&(location.protocol=="file:"||location.protocol=="chrome:"));
+};
+var _16=window.location+"";
+var _17=document.getElementsByTagName("base");
+var _18=(_17&&_17.length>0);
+d._getText=function(uri,_1a){
+var _1b=this._xhrObj();
+if(!_18&&dojo._Url){
+uri=(new dojo._Url(_16,uri)).toString();
+}
+if(d.config.cacheBust){
+uri+="";
+uri+=(uri.indexOf("?")==-1?"?":"&")+String(d.config.cacheBust).replace(/\W+/g,"");
+}
+_1b.open("GET",uri,false);
+try{
+_1b.send(null);
+if(!d._isDocumentOk(_1b)){
+var err=Error("Unable to load "+uri+" status:"+_1b.status);
+err.status=_1b.status;
+err.responseText=_1b.responseText;
+throw err;
+}
+}
+catch(e){
+if(_1a){
+return null;
+}
+throw e;
+}
+return _1b.responseText;
+};
+var _w=window;
+var _1e=function(_1f,fp){
+var _21=_w[_1f]||function(){
+};
+_w[_1f]=function(){
+fp.apply(_w,arguments);
+_21.apply(_w,arguments);
+};
+};
+d._windowUnloaders=[];
+d.windowUnloaded=function(){
+var mll=d._windowUnloaders;
+while(mll.length){
+(mll.pop())();
+}
+};
+var _23=0;
+d.addOnWindowUnload=function(obj,_25){
+d._onto(d._windowUnloaders,obj,_25);
+if(!_23){
+_23=1;
+_1e("onunload",d.windowUnloaded);
+}
+};
+var _26=0;
+d.addOnUnload=function(obj,_28){
+d._onto(d._unloaders,obj,_28);
+if(!_26){
+_26=1;
+_1e("onbeforeunload",dojo.unloaded);
+}
+};
+})();
+dojo._initFired=false;
+dojo._loadInit=function(e){
+dojo._initFired=true;
+var _2a=e&&e.type?e.type.toLowerCase():"load";
+if(arguments.callee.initialized||(_2a!="domcontentloaded"&&_2a!="load")){
+return;
+}
+arguments.callee.initialized=true;
+if("_khtmlTimer" in dojo){
+clearInterval(dojo._khtmlTimer);
+delete dojo._khtmlTimer;
+}
+if(dojo._inFlightCount==0){
+dojo._modulesLoaded();
+}
+};
+if(!dojo.config.afterOnLoad){
+if(document.addEventListener){
+if(dojo.isWebKit>525||dojo.isOpera||dojo.isFF>=3||(dojo.isMoz&&dojo.config.enableMozDomContentLoaded===true)){
+document.addEventListener("DOMContentLoaded",dojo._loadInit,null);
+}
+window.addEventListener("load",dojo._loadInit,null);
+}
+if(dojo.isAIR){
+window.addEventListener("load",dojo._loadInit,null);
+}else{
+if((dojo.isWebKit<525)||dojo.isKhtml){
+dojo._khtmlTimer=setInterval(function(){
+if(/loaded|complete/.test(document.readyState)){
+dojo._loadInit();
+}
+},10);
+}
+}
+}
+if(dojo.isIE){
+if(!dojo.config.afterOnLoad){
+document.write("<scr"+"ipt defer src=\"//:\" "+"onreadystatechange=\"if(this.readyState=='complete'){"+dojo._scopeName+"._loadInit();}\">"+"</scr"+"ipt>");
+}
+try{
+document.namespaces.add("v","urn:schemas-microsoft-com:vml");
+document.createStyleSheet().addRule("v\\:*","behavior:url(#default#VML);  display:inline-block");
+}
+catch(e){
+}
+}
+}
+(function(){
+var mp=dojo.config["modulePaths"];
+if(mp){
+for(var _2c in mp){
+dojo.registerModulePath(_2c,mp[_2c]);
+}
+}
+})();
+if(dojo.config.isDebug){
+dojo.require("dojo._firebug.firebug");
+}
+if(dojo.config.debugAtAllCosts){
+dojo.config.useXDomain=true;
+dojo.require("dojo._base._loader.loader_xd");
+dojo.require("dojo._base._loader.loader_debug");
+dojo.require("dojo.i18n");
+}
diff --git a/dojo/_base/_loader/hostenv_ff_ext.js b/dojo/_base/_loader/hostenv_ff_ext.js
new file mode 100644
index 0000000..3c17c94
--- /dev/null
+++ b/dojo/_base/_loader/hostenv_ff_ext.js
@@ -0,0 +1,177 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(typeof window!="undefined"){
+dojo.isBrowser=true;
+dojo._name="browser";
+(function(){
+var d=dojo;
+d.baseUrl=d.config.baseUrl;
+var n=navigator;
+var _3=n.userAgent;
+var _4=n.appVersion;
+var tv=parseFloat(_4);
+d.isMozilla=d.isMoz=tv;
+if(d.isMoz){
+d.isFF=parseFloat(_3.split("Firefox/")[1])||undefined;
+}
+var cm=document.compatMode;
+d.isQuirks=cm=="BackCompat"||cm=="QuirksMode";
+d.locale=dojo.config.locale||n.language.toLowerCase();
+d._xhrObj=function(){
+return new XMLHttpRequest();
+};
+var _7=d._loadUri;
+d._loadUri=function(_8,cb){
+var _a=["file:","chrome:","resource:"].some(function(_b){
+return String(_8).indexOf(_b)==0;
+});
+if(_a){
+var l=Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader);
+var _d=l.loadSubScript(_8,d.global);
+if(cb){
+cb(_d);
+}
+return true;
+}else{
+return _7.apply(d,arguments);
+}
+};
+d._isDocumentOk=function(_e){
+var _f=_e.status||0;
+return (_f>=200&&_f<300)||_f==304||_f==1223||(!_f&&(location.protocol=="file:"||location.protocol=="chrome:"));
+};
+var _10=false;
+d._getText=function(uri,_12){
+var _13=this._xhrObj();
+if(!_10&&dojo._Url){
+uri=(new dojo._Url(uri)).toString();
+}
+if(d.config.cacheBust){
+uri+="";
+uri+=(uri.indexOf("?")==-1?"?":"&")+String(d.config.cacheBust).replace(/\W+/g,"");
+}
+var _14=["file:","chrome:","resource:"].some(function(_15){
+return String(uri).indexOf(_15)==0;
+});
+if(_14){
+var _16=Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
+var _17=Components.classes["@mozilla.org/scriptableinputstream;1"].getService(Components.interfaces.nsIScriptableInputStream);
+var _18=_16.newChannel(uri,null,null);
+var _19=_18.open();
+_17.init(_19);
+var str=_17.read(_19.available());
+_17.close();
+_19.close();
+return str;
+}else{
+_13.open("GET",uri,false);
+try{
+_13.send(null);
+if(!d._isDocumentOk(_13)){
+var err=Error("Unable to load "+uri+" status:"+_13.status);
+err.status=_13.status;
+err.responseText=_13.responseText;
+throw err;
+}
+}
+catch(e){
+if(_12){
+return null;
+}
+throw e;
+}
+return _13.responseText;
+}
+};
+d._windowUnloaders=[];
+d.windowUnloaded=function(){
+var mll=this._windowUnloaders;
+while(mll.length){
+(mll.pop())();
+}
+};
+d.addOnWindowUnload=function(obj,_1e){
+d._onto(d._windowUnloaders,obj,_1e);
+};
+var _1f=[];
+var _20=null;
+dojo._defaultContext=[window,document];
+dojo.pushContext=function(g,d){
+var old=[dojo.global,dojo.doc];
+_1f.push(old);
+var n;
+if(!g&&!d){
+n=dojo._defaultContext;
+}else{
+n=[g,d];
+if(!d&&dojo.isString(g)){
+var t=document.getElementById(g);
+if(t.contentDocument){
+n=[t.contentWindow,t.contentDocument];
+}
+}
+}
+_20=n;
+dojo.setContext.apply(dojo,n);
+return old;
+};
+dojo.popContext=function(){
+var oc=_20;
+if(!_1f.length){
+return oc;
+}
+dojo.setContext.apply(dojo,_1f.pop());
+return oc;
+};
+dojo._inContext=function(g,d,f){
+var a=dojo._toArray(arguments);
+f=a.pop();
+if(a.length==1){
+d=null;
+}
+dojo.pushContext(g,d);
+var r=f();
+dojo.popContext();
+return r;
+};
+})();
+dojo._initFired=false;
+dojo._loadInit=function(e){
+dojo._initFired=true;
+var _2d=(e&&e.type)?e.type.toLowerCase():"load";
+if(arguments.callee.initialized||(_2d!="domcontentloaded"&&_2d!="load")){
+return;
+}
+arguments.callee.initialized=true;
+if(dojo._inFlightCount==0){
+dojo._modulesLoaded();
+}
+};
+if(!dojo.config.afterOnLoad){
+window.addEventListener("DOMContentLoaded",function(e){
+dojo._loadInit(e);
+},false);
+}
+}
+(function(){
+var mp=dojo.config["modulePaths"];
+if(mp){
+for(var _30 in mp){
+dojo.registerModulePath(_30,mp[_30]);
+}
+}
+})();
+if(dojo.config.isDebug){
+console.log=function(m){
+var s=Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
+s.logStringMessage(m);
+};
+console.debug=function(){
+
+};
+}
diff --git a/dojo/_base/_loader/hostenv_rhino.js b/dojo/_base/_loader/hostenv_rhino.js
new file mode 100644
index 0000000..f156098
--- /dev/null
+++ b/dojo/_base/_loader/hostenv_rhino.js
@@ -0,0 +1,163 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(dojo.config["baseUrl"]){
+dojo.baseUrl=dojo.config["baseUrl"];
+}else{
+dojo.baseUrl="./";
+}
+dojo.locale=dojo.locale||String(java.util.Locale.getDefault().toString().replace("_","-").toLowerCase());
+dojo._name="rhino";
+dojo.isRhino=true;
+if(typeof print=="function"){
+console.debug=print;
+}
+if(!("byId" in dojo)){
+dojo.byId=function(id,_2){
+if(id&&(typeof id=="string"||id instanceof String)){
+if(!_2){
+_2=document;
+}
+return _2.getElementById(id);
+}
+return id;
+};
+}
+dojo._loadUri=function(_3,cb){
+try{
+var _5=(new java.io.File(_3)).exists();
+if(!_5){
+try{
+var _6=(new java.net.URL(_3)).openStream();
+_6.close();
+}
+catch(e){
+return false;
+}
+}
+if(cb){
+var _7=(_5?readText:readUri)(_3,"UTF-8");
+if(!eval("'‏'").length){
+_7=String(_7).replace(/[\u200E\u200F\u202A-\u202E]/g,function(_8){
+return "\\u"+_8.charCodeAt(0).toString(16);
+});
+}
+cb(eval("("+_7+")"));
+}else{
+load(_3);
+}
+return true;
+}
+catch(e){
+
+return false;
+}
+};
+dojo.exit=function(_9){
+quit(_9);
+};
+dojo._rhinoCurrentScriptViaJava=function(_a){
+var _b=Packages.org.mozilla.javascript.Context.getCurrentContext().getOptimizationLevel();
+var _c=new java.io.CharArrayWriter();
+var pw=new java.io.PrintWriter(_c);
+var _e=new java.lang.Exception();
+var s=_c.toString();
+var _10=s.match(/[^\(]*\.js\)/gi);
+if(!_10){
+throw Error("cannot parse printStackTrace output: "+s);
+}
+var _11=((typeof _a!="undefined")&&(_a))?_10[_a+1]:_10[_10.length-1];
+_11=_10[3];
+if(!_11){
+_11=_10[1];
+}
+if(!_11){
+throw Error("could not find js file in printStackTrace output: "+s);
+}
+return _11;
+};
+function readText(_12,_13){
+_13=_13||"utf-8";
+var jf=new java.io.File(_12);
+var is=new java.io.FileInputStream(jf);
+return dj_readInputStream(is,_13);
+};
+function readUri(uri,_17){
+var _18=(new java.net.URL(uri)).openConnection();
+_17=_17||_18.getContentEncoding()||"utf-8";
+var is=_18.getInputStream();
+return dj_readInputStream(is,_17);
+};
+function dj_readInputStream(is,_1b){
+var _1c=new java.io.BufferedReader(new java.io.InputStreamReader(is,_1b));
+try{
+var sb=new java.lang.StringBuffer();
+var _1e="";
+while((_1e=_1c.readLine())!==null){
+sb.append(_1e);
+sb.append(java.lang.System.getProperty("line.separator"));
+}
+return sb.toString();
+}
+finally{
+_1c.close();
+}
+};
+if((!dojo.config.libraryScriptUri)||(!dojo.config.libraryScriptUri.length)){
+try{
+dojo.config.libraryScriptUri=dojo._rhinoCurrentScriptViaJava(1);
+}
+catch(e){
+if(dojo.config["isDebug"]){
+print("\n");
+print("we have no idea where Dojo is located.");
+print("Please try loading rhino in a non-interpreted mode or set a");
+print("\n\tdjConfig.libraryScriptUri\n");
+print("Setting the dojo path to './'");
+print("This is probably wrong!");
+print("\n");
+print("Dojo will try to load anyway");
+}
+dojo.config.libraryScriptUri="./";
+}
+}
+dojo.doc=typeof document!="undefined"?document:null;
+dojo.body=function(){
+return document.body;
+};
+if(typeof setTimeout=="undefined"||typeof clearTimeout=="undefined"){
+dojo._timeouts=[];
+function clearTimeout(idx){
+if(!dojo._timeouts[idx]){
+return;
+}
+dojo._timeouts[idx].stop();
+};
+function setTimeout(_20,_21){
+var def={sleepTime:_21,hasSlept:false,run:function(){
+if(!this.hasSlept){
+this.hasSlept=true;
+java.lang.Thread.currentThread().sleep(this.sleepTime);
+}
+try{
+_20();
+}
+catch(e){
+
+}
+}};
+var _23=new java.lang.Runnable(def);
+var _24=new java.lang.Thread(_23);
+_24.start();
+return dojo._timeouts.push(_24)-1;
+};
+}
+if(dojo.config["modulePaths"]){
+for(var param in dojo.config["modulePaths"]){
+dojo.registerModulePath(param,dojo.config["modulePaths"][param]);
+}
+}
diff --git a/dojo/_base/_loader/hostenv_spidermonkey.js b/dojo/_base/_loader/hostenv_spidermonkey.js
new file mode 100644
index 0000000..d35a6fa
--- /dev/null
+++ b/dojo/_base/_loader/hostenv_spidermonkey.js
@@ -0,0 +1,50 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(dojo.config["baseUrl"]){
+dojo.baseUrl=dojo.config["baseUrl"];
+}else{
+dojo.baseUrl="./";
+}
+dojo._name="spidermonkey";
+dojo.isSpidermonkey=true;
+dojo.exit=function(_1){
+quit(_1);
+};
+if(typeof print=="function"){
+console.debug=print;
+}
+if(typeof line2pc=="undefined"){
+throw new Error("attempt to use SpiderMonkey host environment when no 'line2pc' global");
+}
+dojo._spidermonkeyCurrentFile=function(_2){
+var s="";
+try{
+throw Error("whatever");
+}
+catch(e){
+s=e.stack;
+}
+var _4=s.match(/[^@]*\.js/gi);
+if(!_4){
+throw Error("could not parse stack string: '"+s+"'");
+}
+var _5=(typeof _2!="undefined"&&_2)?_4[_2+1]:_4[_4.length-1];
+if(!_5){
+throw Error("could not find file name in stack string '"+s+"'");
+}
+return _5;
+};
+dojo._loadUri=function(_6){
+var ok=load(_6);
+return 1;
+};
+if(dojo.config["modulePaths"]){
+for(var param in dojo.config["modulePaths"]){
+dojo.registerModulePath(param,dojo.config["modulePaths"][param]);
+}
+}
diff --git a/dojo/_base/_loader/loader.js b/dojo/_base/_loader/loader.js
new file mode 100644
index 0000000..b2613fa
--- /dev/null
+++ b/dojo/_base/_loader/loader.js
@@ -0,0 +1,301 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.foo"]){
+dojo._hasResource["dojo.foo"]=true;
+(function(){
+var d=dojo;
+d.mixin(d,{_loadedModules:{},_inFlightCount:0,_hasResource:{},_modulePrefixes:{dojo:{name:"dojo",value:"."},doh:{name:"doh",value:"../util/doh"},tests:{name:"tests",value:"tests"}},_moduleHasPrefix:function(_2){
+var mp=this._modulePrefixes;
+return !!(mp[_2]&&mp[_2].value);
+},_getModulePrefix:function(_4){
+var mp=this._modulePrefixes;
+if(this._moduleHasPrefix(_4)){
+return mp[_4].value;
+}
+return _4;
+},_loadedUrls:[],_postLoad:false,_loaders:[],_unloaders:[],_loadNotifying:false});
+dojo._loadPath=function(_6,_7,cb){
+var _9=((_6.charAt(0)=="/"||_6.match(/^\w+:/))?"":this.baseUrl)+_6;
+try{
+return !_7?this._loadUri(_9,cb):this._loadUriAndCheck(_9,_7,cb);
+}
+catch(e){
+console.error(e);
+return false;
+}
+};
+dojo._loadUri=function(_a,cb){
+if(this._loadedUrls[_a]){
+return true;
+}
+var _c=this._getText(_a,true);
+if(!_c){
+return false;
+}
+this._loadedUrls[_a]=true;
+this._loadedUrls.push(_a);
+if(cb){
+_c="("+_c+")";
+}else{
+_c=this._scopePrefix+_c+this._scopeSuffix;
+}
+if(d.isMoz){
+_c+="\r\n//@ sourceURL="+_a;
+}
+var _d=d["eval"](_c);
+if(cb){
+cb(_d);
+}
+return true;
+};
+dojo._loadUriAndCheck=function(_e,_f,cb){
+var ok=false;
+try{
+ok=this._loadUri(_e,cb);
+}
+catch(e){
+console.error("failed loading "+_e+" with error: "+e);
+}
+return !!(ok&&this._loadedModules[_f]);
+};
+dojo.loaded=function(){
+this._loadNotifying=true;
+this._postLoad=true;
+var mll=d._loaders;
+this._loaders=[];
+for(var x=0;x<mll.length;x++){
+mll[x]();
+}
+this._loadNotifying=false;
+if(d._postLoad&&d._inFlightCount==0&&mll.length){
+d._callLoaded();
+}
+};
+dojo.unloaded=function(){
+var mll=d._unloaders;
+while(mll.length){
+(mll.pop())();
+}
+};
+d._onto=function(arr,obj,fn){
+if(!fn){
+arr.push(obj);
+}else{
+if(fn){
+var _18=(typeof fn=="string")?obj[fn]:fn;
+arr.push(function(){
+_18.call(obj);
+});
+}
+}
+};
+dojo.addOnLoad=function(obj,_1a){
+d._onto(d._loaders,obj,_1a);
+if(d._postLoad&&d._inFlightCount==0&&!d._loadNotifying){
+d._callLoaded();
+}
+};
+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(){
+if(typeof setTimeout=="object"||(dojo.config.useXDomain&&d.isOpera)){
+if(dojo.isAIR){
+setTimeout(function(){
+dojo.loaded();
+},0);
+}else{
+setTimeout(dojo._scopeName+".loaded();",0);
+}
+}else{
+d.loaded();
+}
+};
+dojo._getModuleSymbols=function(_1c){
+var _1d=_1c.split(".");
+for(var i=_1d.length;i>0;i--){
+var _1f=_1d.slice(0,i).join(".");
+if((i==1)&&!this._moduleHasPrefix(_1f)){
+_1d[0]="../"+_1d[0];
+}else{
+var _20=this._getModulePrefix(_1f);
+if(_20!=_1f){
+_1d.splice(0,i,_20);
+break;
+}
+}
+}
+return _1d;
+};
+dojo._global_omit_module_check=false;
+dojo.loadInit=function(_21){
+_21();
+};
+dojo._loadModule=dojo.require=function(_22,_23){
+_23=this._global_omit_module_check||_23;
+var _24=this._loadedModules[_22];
+if(_24){
+return _24;
+}
+var _25=this._getModuleSymbols(_22).join("/")+".js";
+var _26=(!_23)?_22:null;
+var ok=this._loadPath(_25,_26);
+if(!ok&&!_23){
+throw new Error("Could not load '"+_22+"'; last tried '"+_25+"'");
+}
+if(!_23&&!this._isXDomain){
+_24=this._loadedModules[_22];
+if(!_24){
+throw new Error("symbol '"+_22+"' is not defined after loading '"+_25+"'");
+}
+}
+return _24;
+};
+dojo.provide=function(_28){
+_28=_28+"";
+return (d._loadedModules[_28]=d.getObject(_28,true));
+};
+dojo.platformRequire=function(_29){
+var _2a=_29.common||[];
+var _2b=_2a.concat(_29[d._name]||_29["default"]||[]);
+for(var x=0;x<_2b.length;x++){
+var _2d=_2b[x];
+if(_2d.constructor==Array){
+d._loadModule.apply(d,_2d);
+}else{
+d._loadModule(_2d);
+}
+}
+};
+dojo.requireIf=function(_2e,_2f){
+if(_2e===true){
+var _30=[];
+for(var i=1;i<arguments.length;i++){
+_30.push(arguments[i]);
+}
+d.require.apply(d,_30);
+}
+};
+dojo.requireAfterIf=d.requireIf;
+dojo.registerModulePath=function(_32,_33){
+d._modulePrefixes[_32]={name:_32,value:_33};
+};
+dojo.requireLocalization=function(_34,_35,_36,_37){
+d.require("dojo.i18n");
+d.i18n._requireLocalization.apply(d.hostenv,arguments);
+};
+var ore=new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$");
+var ire=new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$");
+dojo._Url=function(){
+var n=null;
+var _a=arguments;
+var uri=[_a[0]];
+for(var i=1;i<_a.length;i++){
+if(!_a[i]){
+continue;
+}
+var _3e=new d._Url(_a[i]+"");
+var _3f=new d._Url(uri[0]+"");
+if(_3e.path==""&&!_3e.scheme&&!_3e.authority&&!_3e.query){
+if(_3e.fragment!=n){
+_3f.fragment=_3e.fragment;
+}
+_3e=_3f;
+}else{
+if(!_3e.scheme){
+_3e.scheme=_3f.scheme;
+if(!_3e.authority){
+_3e.authority=_3f.authority;
+if(_3e.path.charAt(0)!="/"){
+var _40=_3f.path.substring(0,_3f.path.lastIndexOf("/")+1)+_3e.path;
+var _41=_40.split("/");
+for(var j=0;j<_41.length;j++){
+if(_41[j]=="."){
+if(j==_41.length-1){
+_41[j]="";
+}else{
+_41.splice(j,1);
+j--;
+}
+}else{
+if(j>0&&!(j==1&&_41[0]=="")&&_41[j]==".."&&_41[j-1]!=".."){
+if(j==(_41.length-1)){
+_41.splice(j,1);
+_41[j-1]="";
+}else{
+_41.splice(j-1,2);
+j-=2;
+}
+}
+}
+}
+_3e.path=_41.join("/");
+}
+}
+}
+}
+uri=[];
+if(_3e.scheme){
+uri.push(_3e.scheme,":");
+}
+if(_3e.authority){
+uri.push("//",_3e.authority);
+}
+uri.push(_3e.path);
+if(_3e.query){
+uri.push("?",_3e.query);
+}
+if(_3e.fragment){
+uri.push("#",_3e.fragment);
+}
+}
+this.uri=uri.join("");
+var r=this.uri.match(ore);
+this.scheme=r[2]||(r[1]?"":n);
+this.authority=r[4]||(r[3]?"":n);
+this.path=r[5];
+this.query=r[7]||(r[6]?"":n);
+this.fragment=r[9]||(r[8]?"":n);
+if(this.authority!=n){
+r=this.authority.match(ire);
+this.user=r[3]||n;
+this.password=r[4]||n;
+this.host=r[6]||r[7];
+this.port=r[9]||n;
+}
+};
+dojo._Url.prototype.toString=function(){
+return this.uri;
+};
+dojo.moduleUrl=function(_44,url){
+var loc=d._getModuleSymbols(_44).join("/");
+if(!loc){
+return null;
+}
+if(loc.lastIndexOf("/")!=loc.length-1){
+loc+="/";
+}
+var _47=loc.indexOf(":");
+if(loc.charAt(0)!="/"&&(_47==-1||_47>loc.indexOf("/"))){
+loc=d.baseUrl+loc;
+}
+return new d._Url(loc,url);
+};
+})();
+}
diff --git a/dojo/_base/_loader/loader_debug.js b/dojo/_base/_loader/loader_debug.js
new file mode 100644
index 0000000..cddb73a
--- /dev/null
+++ b/dojo/_base/_loader/loader_debug.js
@@ -0,0 +1,59 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._base._loader.loader_debug"]){
+dojo._hasResource["dojo._base._loader.loader_debug"]=true;
+dojo.provide("dojo._base._loader.loader_debug");
+dojo.nonDebugProvide=dojo.provide;
+dojo.provide=function(_1){
+var _2=dojo["_xdDebugQueue"];
+if(_2&&_2.length>0&&_1==_2["currentResourceName"]){
+if(dojo.isAIR){
+window.setTimeout(function(){
+dojo._xdDebugFileLoaded(_1);
+},1);
+}else{
+window.setTimeout(dojo._scopeName+"._xdDebugFileLoaded('"+_1+"')",1);
+}
+}
+return dojo.nonDebugProvide.apply(dojo,arguments);
+};
+dojo._xdDebugFileLoaded=function(_3){
+if(!this._xdDebugScopeChecked){
+if(dojo._scopeName!="dojo"){
+window.dojo=window[dojo.config.scopeMap[0][1]];
+window.dijit=window[dojo.config.scopeMap[1][1]];
+window.dojox=window[dojo.config.scopeMap[2][1]];
+}
+this._xdDebugScopeChecked=true;
+}
+var _4=this._xdDebugQueue;
+if(_3&&_3==_4.currentResourceName){
+_4.shift();
+}
+if(_4.length==0){
+dojo._xdWatchInFlight();
+}
+if(_4.length==0){
+_4.currentResourceName=null;
+for(var _5 in this._xdInFlight){
+if(this._xdInFlight[_5]===true){
+return;
+}
+}
+this._xdNotifyLoaded();
+}else{
+if(_3==_4.currentResourceName){
+_4.currentResourceName=_4[0].resourceName;
+var _6=document.createElement("script");
+_6.type="text/javascript";
+_6.src=_4[0].resourcePath;
+document.getElementsByTagName("head")[0].appendChild(_6);
+}
+}
+};
+}
diff --git a/dojo/_base/_loader/loader_xd.js b/dojo/_base/_loader/loader_xd.js
new file mode 100644
index 0000000..2649e30
--- /dev/null
+++ b/dojo/_base/_loader/loader_xd.js
@@ -0,0 +1,456 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._base._loader.loader_xd"]){
+dojo._hasResource["dojo._base._loader.loader_xd"]=true;
+dojo.provide("dojo._base._loader.loader_xd");
+dojo._xdReset=function(){
+this._isXDomain=dojo.config.useXDomain||false;
+this._xdTimer=0;
+this._xdInFlight={};
+this._xdOrderedReqs=[];
+this._xdDepMap={};
+this._xdContents=[];
+this._xdDefList=[];
+};
+dojo._xdReset();
+dojo._xdCreateResource=function(_1,_2,_3){
+var _4=_1.replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg,"");
+var _5=[];
+var _6=/dojo.(require|requireIf|provide|requireAfterIf|platformRequire|requireLocalization)\s*\(([\w\W]*?)\)/mg;
+var _7;
+while((_7=_6.exec(_4))!=null){
+if(_7[1]=="requireLocalization"){
+eval(_7[0]);
+}else{
+_5.push("\""+_7[1]+"\", "+_7[2]);
+}
+}
+var _8=[];
+_8.push(dojo._scopeName+"._xdResourceLoaded(function("+dojo._scopePrefixArgs+"){\n");
+var _9=dojo._xdExtractLoadInits(_1);
+if(_9){
+_1=_9[0];
+for(var i=1;i<_9.length;i++){
+_8.push(_9[i]+";\n");
+}
+}
+_8.push("return {");
+if(_5.length>0){
+_8.push("depends: [");
+for(i=0;i<_5.length;i++){
+if(i>0){
+_8.push(",\n");
+}
+_8.push("["+_5[i]+"]");
+}
+_8.push("],");
+}
+_8.push("\ndefineResource: function("+dojo._scopePrefixArgs+"){");
+if(!dojo.config["debugAtAllCosts"]||_2=="dojo._base._loader.loader_debug"){
+_8.push(_1);
+}
+_8.push("\n}, resourceName: '"+_2+"', resourcePath: '"+_3+"'};});");
+return _8.join("");
+};
+dojo._xdExtractLoadInits=function(_b){
+var _c=/dojo.loadInit\s*\(/g;
+_c.lastIndex=0;
+var _d=/[\(\)]/g;
+_d.lastIndex=0;
+var _e=[];
+var _f;
+while((_f=_c.exec(_b))){
+_d.lastIndex=_c.lastIndex;
+var _10=1;
+var _11;
+while((_11=_d.exec(_b))){
+if(_11[0]==")"){
+_10-=1;
+}else{
+_10+=1;
+}
+if(_10==0){
+break;
+}
+}
+if(_10!=0){
+throw "unmatched paren around character "+_d.lastIndex+" in: "+_b;
+}
+var _12=_c.lastIndex-_f[0].length;
+_e.push(_b.substring(_12,_d.lastIndex));
+var _13=_d.lastIndex-_12;
+_b=_b.substring(0,_12)+_b.substring(_d.lastIndex,_b.length);
+_c.lastIndex=_d.lastIndex-_13;
+_c.lastIndex=_d.lastIndex;
+}
+if(_e.length>0){
+_e.unshift(_b);
+}
+return (_e.length?_e:null);
+};
+dojo._xdIsXDomainPath=function(_14){
+var _15=_14.indexOf(":");
+var _16=_14.indexOf("/");
+if(_15>0&&_15<_16){
+return true;
+}else{
+var url=this.baseUrl;
+_15=url.indexOf(":");
+_16=url.indexOf("/");
+if(_15>0&&_15<_16&&(!location.host||url.indexOf("http://"+location.host)!=0)){
+return true;
+}
+}
+return false;
+};
+dojo._loadPath=function(_18,_19,cb){
+var _1b=this._xdIsXDomainPath(_18);
+this._isXDomain|=_1b;
+var uri=((_18.charAt(0)=="/"||_18.match(/^\w+:/))?"":this.baseUrl)+_18;
+try{
+return ((!_19||this._isXDomain)?this._loadUri(uri,cb,_1b,_19):this._loadUriAndCheck(uri,_19,cb));
+}
+catch(e){
+console.error(e);
+return false;
+}
+};
+dojo._loadUri=function(uri,cb,_1f,_20){
+if(this._loadedUrls[uri]){
+return 1;
+}
+if(this._isXDomain&&_20&&_20!="dojo.i18n"){
+this._xdOrderedReqs.push(_20);
+if(_1f||uri.indexOf("/nls/")==-1){
+this._xdInFlight[_20]=true;
+this._inFlightCount++;
+}
+if(!this._xdTimer){
+if(dojo.isAIR){
+this._xdTimer=setInterval(function(){
+dojo._xdWatchInFlight();
+},100);
+}else{
+this._xdTimer=setInterval(dojo._scopeName+"._xdWatchInFlight();",100);
+}
+}
+this._xdStartTime=(new Date()).getTime();
+}
+if(_1f){
+var _21=uri.lastIndexOf(".");
+if(_21<=0){
+_21=uri.length-1;
+}
+var _22=uri.substring(0,_21)+".xd";
+if(_21!=uri.length-1){
+_22+=uri.substring(_21,uri.length);
+}
+if(dojo.isAIR){
+_22=_22.replace("app:/","/");
+}
+var _23=document.createElement("script");
+_23.type="text/javascript";
+_23.src=_22;
+if(!this.headElement){
+this._headElement=document.getElementsByTagName("head")[0];
+if(!this._headElement){
+this._headElement=document.getElementsByTagName("html")[0];
+}
+}
+this._headElement.appendChild(_23);
+}else{
+var _24=this._getText(uri,null,true);
+if(_24==null){
+return 0;
+}
+if(this._isXDomain&&uri.indexOf("/nls/")==-1&&_20!="dojo.i18n"){
+var res=this._xdCreateResource(_24,_20,uri);
+dojo.eval(res);
+}else{
+if(cb){
+_24="("+_24+")";
+}else{
+_24=this._scopePrefix+_24+this._scopeSuffix;
+}
+var _26=dojo["eval"](_24+"\r\n//@ sourceURL="+uri);
+if(cb){
+cb(_26);
+}
+}
+}
+this._loadedUrls[uri]=true;
+this._loadedUrls.push(uri);
+return true;
+};
+dojo._xdResourceLoaded=function(res){
+res=res.apply(dojo.global,dojo._scopeArgs);
+var _28=res.depends;
+var _29=null;
+var _2a=null;
+var _2b=[];
+if(_28&&_28.length>0){
+var dep=null;
+var _2d=0;
+var _2e=false;
+for(var i=0;i<_28.length;i++){
+dep=_28[i];
+if(dep[0]=="provide"){
+_2b.push(dep[1]);
+}else{
+if(!_29){
+_29=[];
+}
+if(!_2a){
+_2a=[];
+}
+var _30=this._xdUnpackDependency(dep);
+if(_30.requires){
+_29=_29.concat(_30.requires);
+}
+if(_30.requiresAfter){
+_2a=_2a.concat(_30.requiresAfter);
+}
+}
+var _31=dep[0];
+var _32=_31.split(".");
+if(_32.length==2){
+dojo[_32[0]][_32[1]].apply(dojo[_32[0]],dep.slice(1));
+}else{
+dojo[_31].apply(dojo,dep.slice(1));
+}
+}
+if(_2b.length==1&&_2b[0]=="dojo._base._loader.loader_debug"){
+res.defineResource(dojo);
+}else{
+var _33=this._xdContents.push({content:res.defineResource,resourceName:res["resourceName"],resourcePath:res["resourcePath"],isDefined:false})-1;
+for(i=0;i<_2b.length;i++){
+this._xdDepMap[_2b[i]]={requires:_29,requiresAfter:_2a,contentIndex:_33};
+}
+}
+for(i=0;i<_2b.length;i++){
+this._xdInFlight[_2b[i]]=false;
+}
+}
+};
+dojo._xdLoadFlattenedBundle=function(_34,_35,_36,_37){
+_36=_36||"root";
+var _38=dojo.i18n.normalizeLocale(_36).replace("-","_");
+var _39=[_34,"nls",_35].join(".");
+var _3a=dojo["provide"](_39);
+_3a[_38]=_37;
+var _3b=[_34,_38,_35].join(".");
+var _3c=dojo._xdBundleMap[_3b];
+if(_3c){
+for(var _3d in _3c){
+_3a[_3d]=_37;
+}
+}
+};
+dojo._xdInitExtraLocales=function(){
+var _3e=dojo.config.extraLocale;
+if(_3e){
+if(!_3e instanceof Array){
+_3e=[_3e];
+}
+dojo._xdReqLoc=dojo.xdRequireLocalization;
+dojo.xdRequireLocalization=function(m,b,_41,_42){
+dojo._xdReqLoc(m,b,_41,_42);
+if(_41){
+return;
+}
+for(var i=0;i<_3e.length;i++){
+dojo._xdReqLoc(m,b,_3e[i],_42);
+}
+};
+}
+};
+dojo._xdBundleMap={};
+dojo.xdRequireLocalization=function(_44,_45,_46,_47){
+if(dojo._xdInitExtraLocales){
+dojo._xdInitExtraLocales();
+dojo._xdInitExtraLocales=null;
+dojo.xdRequireLocalization.apply(dojo,arguments);
+return;
+}
+var _48=_47.split(",");
+var _49=dojo.i18n.normalizeLocale(_46);
+var _4a="";
+for(var i=0;i<_48.length;i++){
+if(_49.indexOf(_48[i])==0){
+if(_48[i].length>_4a.length){
+_4a=_48[i];
+}
+}
+}
+var _4c=_4a.replace("-","_");
+var _4d=dojo.getObject([_44,"nls",_45].join("."));
+if(_4d&&_4d[_4c]){
+_4e[_49.replace("-","_")]=_4d[_4c];
+}else{
+var _4f=[_44,(_4c||"root"),_45].join(".");
+var _4e=dojo._xdBundleMap[_4f];
+if(!_4e){
+_4e=dojo._xdBundleMap[_4f]={};
+}
+_4e[_49.replace("-","_")]=true;
+dojo.require(_44+".nls"+(_4a?"."+_4a:"")+"."+_45);
+}
+};
+dojo._xdRealRequireLocalization=dojo.requireLocalization;
+dojo.requireLocalization=function(_50,_51,_52,_53){
+var _54=this.moduleUrl(_50).toString();
+if(this._xdIsXDomainPath(_54)){
+return dojo.xdRequireLocalization.apply(dojo,arguments);
+}else{
+return dojo._xdRealRequireLocalization.apply(dojo,arguments);
+}
+};
+dojo._xdUnpackDependency=function(dep){
+var _56=null;
+var _57=null;
+switch(dep[0]){
+case "requireIf":
+case "requireAfterIf":
+if(dep[1]===true){
+_56=[{name:dep[2],content:null}];
+}
+break;
+case "platformRequire":
+var _58=dep[1];
+var _59=_58["common"]||[];
+_56=(_58[dojo.hostenv.name_])?_59.concat(_58[dojo.hostenv.name_]||[]):_59.concat(_58["default"]||[]);
+if(_56){
+for(var i=0;i<_56.length;i++){
+if(_56[i] instanceof Array){
+_56[i]={name:_56[i][0],content:null};
+}else{
+_56[i]={name:_56[i],content:null};
+}
+}
+}
+break;
+case "require":
+_56=[{name:dep[1],content:null}];
+break;
+case "i18n._preloadLocalizations":
+dojo.i18n._preloadLocalizations.apply(dojo.i18n._preloadLocalizations,dep.slice(1));
+break;
+}
+if(dep[0]=="requireAfterIf"||dep[0]=="requireIf"){
+_57=_56;
+_56=null;
+}
+return {requires:_56,requiresAfter:_57};
+};
+dojo._xdWalkReqs=function(){
+var _5b=null;
+var req;
+for(var i=0;i<this._xdOrderedReqs.length;i++){
+req=this._xdOrderedReqs[i];
+if(this._xdDepMap[req]){
+_5b=[req];
+_5b[req]=true;
+this._xdEvalReqs(_5b);
+}
+}
+};
+dojo._xdEvalReqs=function(_5e){
+while(_5e.length>0){
+var req=_5e[_5e.length-1];
+var res=this._xdDepMap[req];
+var i,_62,_63;
+if(res){
+_62=res.requires;
+if(_62&&_62.length>0){
+for(i=0;i<_62.length;i++){
+_63=_62[i].name;
+if(_63&&!_5e[_63]){
+_5e.push(_63);
+_5e[_63]=true;
+this._xdEvalReqs(_5e);
+}
+}
+}
+var _64=this._xdContents[res.contentIndex];
+if(!_64.isDefined){
+var _65=_64.content;
+_65["resourceName"]=_64["resourceName"];
+_65["resourcePath"]=_64["resourcePath"];
+this._xdDefList.push(_65);
+_64.isDefined=true;
+}
+this._xdDepMap[req]=null;
+_62=res.requiresAfter;
+if(_62&&_62.length>0){
+for(i=0;i<_62.length;i++){
+_63=_62[i].name;
+if(_63&&!_5e[_63]){
+_5e.push(_63);
+_5e[_63]=true;
+this._xdEvalReqs(_5e);
+}
+}
+}
+}
+_5e.pop();
+}
+};
+dojo._xdClearInterval=function(){
+clearInterval(this._xdTimer);
+this._xdTimer=0;
+};
+dojo._xdWatchInFlight=function(){
+var _66="";
+var _67=(dojo.config.xdWaitSeconds||15)*1000;
+var _68=(this._xdStartTime+_67)<(new Date()).getTime();
+for(var _69 in this._xdInFlight){
+if(this._xdInFlight[_69]===true){
+if(_68){
+_66+=_69+" ";
+}else{
+return;
+}
+}
+}
+this._xdClearInterval();
+if(_68){
+throw "Could not load cross-domain resources: "+_66;
+}
+this._xdWalkReqs();
+var _6a=this._xdDefList.length;
+for(var i=0;i<_6a;i++){
+var _6c=dojo._xdDefList[i];
+if(dojo.config["debugAtAllCosts"]&&_6c["resourceName"]){
+if(!this["_xdDebugQueue"]){
+this._xdDebugQueue=[];
+}
+this._xdDebugQueue.push({resourceName:_6c.resourceName,resourcePath:_6c.resourcePath});
+}else{
+_6c.apply(dojo.global,dojo._scopeArgs);
+}
+}
+for(i=0;i<this._xdContents.length;i++){
+var _6d=this._xdContents[i];
+if(_6d.content&&!_6d.isDefined){
+_6d.content.apply(dojo.global,dojo._scopeArgs);
+}
+}
+this._xdReset();
+if(this["_xdDebugQueue"]&&this._xdDebugQueue.length>0){
+this._xdDebugFileLoaded();
+}else{
+this._xdNotifyLoaded();
+}
+};
+dojo._xdNotifyLoaded=function(){
+this._inFlightCount=0;
+if(this._initFired&&!this._loadNotifying){
+this._callLoaded();
+}
+};
+}
diff --git a/dojo/_base/array.js b/dojo/_base/array.js
new file mode 100644
index 0000000..88c435c
--- /dev/null
+++ b/dojo/_base/array.js
@@ -0,0 +1,78 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._base.array"]){
+dojo._hasResource["dojo._base.array"]=true;
+dojo.require("dojo._base.lang");
+dojo.provide("dojo._base.array");
+(function(){
+var _1=function(_2,_3,cb){
+return [dojo.isString(_2)?_2.split(""):_2,_3||dojo.global,dojo.isString(cb)?new Function("item","index","array",cb):cb];
+};
+dojo.mixin(dojo,{indexOf:function(_5,_6,_7,_8){
+var _9=1,_a=_5.length||0,i=0;
+if(_8){
+i=_a-1;
+_9=_a=-1;
+}
+if(_7!=undefined){
+i=_7;
+}
+if((_8&&i>_a)||i<_a){
+for(;i!=_a;i+=_9){
+if(_5[i]==_6){
+return i;
+}
+}
+}
+return -1;
+},lastIndexOf:function(_c,_d,_e){
+return dojo.indexOf(_c,_d,_e,true);
+},forEach:function(_f,_10,_11){
+if(!_f||!_f.length){
+return;
+}
+var _p=_1(_f,_11,_10);
+_f=_p[0];
+for(var i=0,l=_f.length;i<l;++i){
+_p[2].call(_p[1],_f[i],i,_f);
+}
+},_everyOrSome:function(_15,arr,_17,_18){
+var _p=_1(arr,_18,_17);
+arr=_p[0];
+for(var i=0,l=arr.length;i<l;++i){
+var _1c=!!_p[2].call(_p[1],arr[i],i,arr);
+if(_15^_1c){
+return _1c;
+}
+}
+return _15;
+},every:function(arr,_1e,_1f){
+return dojo._everyOrSome(true,arr,_1e,_1f);
+},some:function(arr,_21,_22){
+return dojo._everyOrSome(false,arr,_21,_22);
+},map:function(arr,_24,_25){
+var _p=_1(arr,_25,_24);
+arr=_p[0];
+var _27=(arguments[3]?(new arguments[3]()):[]);
+for(var i=0,l=arr.length;i<l;++i){
+_27.push(_p[2].call(_p[1],arr[i],i,arr));
+}
+return _27;
+},filter:function(arr,_2b,_2c){
+var _p=_1(arr,_2c,_2b);
+arr=_p[0];
+var _2e=[];
+for(var i=0,l=arr.length;i<l;++i){
+if(_p[2].call(_p[1],arr[i],i,arr)){
+_2e.push(arr[i]);
+}
+}
+return _2e;
+}});
+})();
+}
diff --git a/dojo/_base/browser.js b/dojo/_base/browser.js
new file mode 100644
index 0000000..e6222bf
--- /dev/null
+++ b/dojo/_base/browser.js
@@ -0,0 +1,22 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._base.browser"]){
+dojo._hasResource["dojo._base.browser"]=true;
+dojo.provide("dojo._base.browser");
+dojo.require("dojo._base.window");
+dojo.require("dojo._base.connect");
+dojo.require("dojo._base.event");
+dojo.require("dojo._base.html");
+dojo.require("dojo._base.NodeList");
+dojo.require("dojo._base.query");
+dojo.require("dojo._base.xhr");
+dojo.require("dojo._base.fx");
+dojo.forEach(dojo.config.require,function(i){
+dojo["require"](i);
+});
+}
diff --git a/dojo/_base/connect.js b/dojo/_base/connect.js
new file mode 100644
index 0000000..cf344f9
--- /dev/null
+++ b/dojo/_base/connect.js
@@ -0,0 +1,85 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._base.connect"]){
+dojo._hasResource["dojo._base.connect"]=true;
+dojo.provide("dojo._base.connect");
+dojo.require("dojo._base.lang");
+dojo._listener={getDispatcher:function(){
+return function(){
+var ap=Array.prototype,c=arguments.callee,ls=c._listeners,t=c.target;
+var r=t&&t.apply(this,arguments);
+var _6;
+_6=[].concat(ls);
+for(var i in _6){
+if(!(i in ap)){
+_6[i].apply(this,arguments);
+}
+}
+return r;
+};
+},add:function(_8,_9,_a){
+_8=_8||dojo.global;
+var f=_8[_9];
+if(!f||!f._listeners){
+var d=dojo._listener.getDispatcher();
+d.target=f;
+d._listeners=[];
+f=_8[_9]=d;
+}
+return f._listeners.push(_a);
+},remove:function(_d,_e,_f){
+var f=(_d||dojo.global)[_e];
+if(f&&f._listeners&&_f--){
+delete f._listeners[_f];
+}
+}};
+dojo.connect=function(obj,_12,_13,_14,_15){
+var a=arguments,_17=[],i=0;
+_17.push(dojo.isString(a[0])?null:a[i++],a[i++]);
+var a1=a[i+1];
+_17.push(dojo.isString(a1)||dojo.isFunction(a1)?a[i++]:null,a[i++]);
+for(var l=a.length;i<l;i++){
+_17.push(a[i]);
+}
+return dojo._connect.apply(this,_17);
+};
+dojo._connect=function(obj,_1c,_1d,_1e){
+var l=dojo._listener,h=l.add(obj,_1c,dojo.hitch(_1d,_1e));
+return [obj,_1c,h,l];
+};
+dojo.disconnect=function(_21){
+if(_21&&_21[0]!==undefined){
+dojo._disconnect.apply(this,_21);
+delete _21[0];
+}
+};
+dojo._disconnect=function(obj,_23,_24,_25){
+_25.remove(obj,_23,_24);
+};
+dojo._topics={};
+dojo.subscribe=function(_26,_27,_28){
+return [_26,dojo._listener.add(dojo._topics,_26,dojo.hitch(_27,_28))];
+};
+dojo.unsubscribe=function(_29){
+if(_29){
+dojo._listener.remove(dojo._topics,_29[0],_29[1]);
+}
+};
+dojo.publish=function(_2a,_2b){
+var f=dojo._topics[_2a];
+if(f){
+f.apply(this,_2b||[]);
+}
+};
+dojo.connectPublisher=function(_2d,obj,_2f){
+var pf=function(){
+dojo.publish(_2d,arguments);
+};
+return (_2f)?dojo.connect(obj,_2f,pf):dojo.connect(obj,pf);
+};
+}
diff --git a/dojo/_base/declare.js b/dojo/_base/declare.js
new file mode 100644
index 0000000..17753f5
--- /dev/null
+++ b/dojo/_base/declare.js
@@ -0,0 +1,128 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._base.declare"]){
+dojo._hasResource["dojo._base.declare"]=true;
+dojo.provide("dojo._base.declare");
+dojo.require("dojo._base.lang");
+dojo.declare=function(_1,_2,_3){
+var dd=arguments.callee,_5;
+if(dojo.isArray(_2)){
+_5=_2;
+_2=_5.shift();
+}
+if(_5){
+dojo.forEach(_5,function(m,i){
+if(!m){
+throw (_1+": mixin #"+i+" is null");
+}
+_2=dd._delegate(_2,m);
+});
+}
+var _8=dd._delegate(_2);
+_3=_3||{};
+_8.extend(_3);
+dojo.extend(_8,{declaredClass:_1,_constructor:_3.constructor});
+_8.prototype.constructor=_8;
+return dojo.setObject(_1,_8);
+};
+dojo.mixin(dojo.declare,{_delegate:function(_9,_a){
+var bp=(_9||0).prototype,mp=(_a||0).prototype,dd=dojo.declare;
+var _e=dd._makeCtor();
+dojo.mixin(_e,{superclass:bp,mixin:mp,extend:dd._extend});
+if(_9){
+_e.prototype=dojo._delegate(bp);
+}
+dojo.extend(_e,dd._core,mp||0,{_constructor:null,preamble:null});
+_e.prototype.constructor=_e;
+_e.prototype.declaredClass=(bp||0).declaredClass+"_"+(mp||0).declaredClass;
+return _e;
+},_extend:function(_f){
+var i,fn;
+for(i in _f){
+if(dojo.isFunction(fn=_f[i])&&!0[i]){
+fn.nom=i;
+fn.ctor=this;
+}
+}
+dojo.extend(this,_f);
+},_makeCtor:function(){
+return function(){
+this._construct(arguments);
+};
+},_core:{_construct:function(_12){
+var c=_12.callee,s=c.superclass,ct=s&&s.constructor,m=c.mixin,mct=m&&m.constructor,a=_12,ii,fn;
+if(a[0]){
+if(((fn=a[0].preamble))){
+a=fn.apply(this,a)||a;
+}
+}
+if((fn=c.prototype.preamble)){
+a=fn.apply(this,a)||a;
+}
+if(ct&&ct.apply){
+ct.apply(this,a);
+}
+if(mct&&mct.apply){
+mct.apply(this,a);
+}
+if((ii=c.prototype._constructor)){
+ii.apply(this,_12);
+}
+if(this.constructor.prototype==c.prototype&&(ct=this.postscript)){
+ct.apply(this,_12);
+}
+},_findMixin:function(_1b){
+var c=this.constructor,p,m;
+while(c){
+p=c.superclass;
+m=c.mixin;
+if(m==_1b||(m instanceof _1b.constructor)){
+return p;
+}
+if(m&&m._findMixin&&(m=m._findMixin(_1b))){
+return m;
+}
+c=p&&p.constructor;
+}
+},_findMethod:function(_1f,_20,_21,has){
+var p=_21,c,m,f;
+do{
+c=p.constructor;
+m=c.mixin;
+if(m&&(m=this._findMethod(_1f,_20,m,has))){
+return m;
+}
+if((f=p[_1f])&&(has==(f==_20))){
+return p;
+}
+p=c.superclass;
+}while(p);
+return !has&&(p=this._findMixin(_21))&&this._findMethod(_1f,_20,p,has);
+},inherited:function(_27,_28,_29){
+var a=arguments;
+if(!dojo.isString(a[0])){
+_29=_28;
+_28=_27;
+_27=_28.callee.nom;
+}
+a=_29||_28;
+var c=_28.callee,p=this.constructor.prototype,fn,mp;
+if(this[_27]!=c||p[_27]==c){
+mp=(c.ctor||0).superclass||this._findMethod(_27,c,p,true);
+if(!mp){
+throw (this.declaredClass+": inherited method \""+_27+"\" mismatch");
+}
+p=this._findMethod(_27,c,mp,false);
+}
+fn=p&&p[_27];
+if(!fn){
+throw (mp.declaredClass+": inherited method \""+_27+"\" not found");
+}
+return fn.apply(this,a);
+}}});
+}
diff --git a/dojo/_base/event.js b/dojo/_base/event.js
new file mode 100644
index 0000000..df1ec62
--- /dev/null
+++ b/dojo/_base/event.js
@@ -0,0 +1,342 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._base.event"]){
+dojo._hasResource["dojo._base.event"]=true;
+dojo.provide("dojo._base.event");
+dojo.require("dojo._base.connect");
+(function(){
+var _1=(dojo._event_listener={add:function(_2,_3,fp){
+if(!_2){
+return;
+}
+_3=_1._normalizeEventName(_3);
+fp=_1._fixCallback(_3,fp);
+var _5=_3;
+if(!dojo.isIE&&(_3=="mouseenter"||_3=="mouseleave")){
+var _6=fp;
+_3=(_3=="mouseenter")?"mouseover":"mouseout";
+fp=function(e){
+if(dojo.isFF<=2){
+try{
+e.relatedTarget.tagName;
+}
+catch(e2){
+return;
+}
+}
+if(!dojo.isDescendant(e.relatedTarget,_2)){
+return _6.call(this,e);
+}
+};
+}
+_2.addEventListener(_3,fp,false);
+return fp;
+},remove:function(_8,_9,_a){
+if(_8){
+_9=_1._normalizeEventName(_9);
+if(!dojo.isIE&&(_9=="mouseenter"||_9=="mouseleave")){
+_9=(_9=="mouseenter")?"mouseover":"mouseout";
+}
+_8.removeEventListener(_9,_a,false);
+}
+},_normalizeEventName:function(_b){
+return _b.slice(0,2)=="on"?_b.slice(2):_b;
+},_fixCallback:function(_c,fp){
+return _c!="keypress"?fp:function(e){
+return fp.call(this,_1._fixEvent(e,this));
+};
+},_fixEvent:function(_f,_10){
+switch(_f.type){
+case "keypress":
+_1._setKeyChar(_f);
+break;
+}
+return _f;
+},_setKeyChar:function(evt){
+evt.keyChar=evt.charCode?String.fromCharCode(evt.charCode):"";
+evt.charOrCode=evt.keyChar||evt.keyCode;
+},_punctMap:{106:42,111:47,186:59,187:43,188:44,189:45,190:46,191:47,192:96,219:91,220:92,221:93,222:39}});
+dojo.fixEvent=function(evt,_13){
+return _1._fixEvent(evt,_13);
+};
+dojo.stopEvent=function(evt){
+evt.preventDefault();
+evt.stopPropagation();
+};
+var _15=dojo._listener;
+dojo._connect=function(obj,_17,_18,_19,_1a){
+var _1b=obj&&(obj.nodeType||obj.attachEvent||obj.addEventListener);
+var lid=_1b?(_1a?2:1):0,l=[dojo._listener,_1,_15][lid];
+var h=l.add(obj,_17,dojo.hitch(_18,_19));
+return [obj,_17,h,lid];
+};
+dojo._disconnect=function(obj,_20,_21,_22){
+([dojo._listener,_1,_15][_22]).remove(obj,_20,_21);
+};
+dojo.keys={BACKSPACE:8,TAB:9,CLEAR:12,ENTER:13,SHIFT:16,CTRL:17,ALT:18,PAUSE:19,CAPS_LOCK:20,ESCAPE:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT_ARROW:37,UP_ARROW:38,RIGHT_ARROW:39,DOWN_ARROW:40,INSERT:45,DELETE:46,HELP:47,LEFT_WINDOW:91,RIGHT_WINDOW:92,SELECT:93,NUMPAD_0:96,NUMPAD_1:97,NUMPAD_2:98,NUMPAD_3:99,NUMPAD_4:100,NUMPAD_5:101,NUMPAD_6:102,NUMPAD_7:103,NUMPAD_8:104,NUMPAD_9:105,NUMPAD_MULTIPLY:106,NUMPAD_PLUS:107,NUMPAD_ENTER:108,NUMPAD_MINUS:109,NUMPAD_PERIOD:110,NUM [...]
+if(dojo.isIE){
+var _23=function(e,_25){
+try{
+return (e.keyCode=_25);
+}
+catch(e){
+return 0;
+}
+};
+var iel=dojo._listener;
+var _27=(dojo._ieListenersName="_"+dojo._scopeName+"_listeners");
+if(!dojo.config._allow_leaks){
+_15=iel=dojo._ie_listener={handlers:[],add:function(_28,_29,_2a){
+_28=_28||dojo.global;
+var f=_28[_29];
+if(!f||!f[_27]){
+var d=dojo._getIeDispatcher();
+d.target=f&&(ieh.push(f)-1);
+d[_27]=[];
+f=_28[_29]=d;
+}
+return f[_27].push(ieh.push(_2a)-1);
+},remove:function(_2e,_2f,_30){
+var f=(_2e||dojo.global)[_2f],l=f&&f[_27];
+if(f&&l&&_30--){
+delete ieh[l[_30]];
+delete l[_30];
+}
+}};
+var ieh=iel.handlers;
+}
+dojo.mixin(_1,{add:function(_33,_34,fp){
+if(!_33){
+return;
+}
+_34=_1._normalizeEventName(_34);
+if(_34=="onkeypress"){
+var kd=_33.onkeydown;
+if(!kd||!kd[_27]||!kd._stealthKeydownHandle){
+var h=_1.add(_33,"onkeydown",_1._stealthKeyDown);
+kd=_33.onkeydown;
+kd._stealthKeydownHandle=h;
+kd._stealthKeydownRefs=1;
+}else{
+kd._stealthKeydownRefs++;
+}
+}
+return iel.add(_33,_34,_1._fixCallback(fp));
+},remove:function(_38,_39,_3a){
+_39=_1._normalizeEventName(_39);
+iel.remove(_38,_39,_3a);
+if(_39=="onkeypress"){
+var kd=_38.onkeydown;
+if(--kd._stealthKeydownRefs<=0){
+iel.remove(_38,"onkeydown",kd._stealthKeydownHandle);
+delete kd._stealthKeydownHandle;
+}
+}
+},_normalizeEventName:function(_3c){
+return _3c.slice(0,2)!="on"?"on"+_3c:_3c;
+},_nop:function(){
+},_fixEvent:function(evt,_3e){
+if(!evt){
+var w=_3e&&(_3e.ownerDocument||_3e.document||_3e).parentWindow||window;
+evt=w.event;
+}
+if(!evt){
+return (evt);
+}
+evt.target=evt.srcElement;
+evt.currentTarget=(_3e||evt.srcElement);
+evt.layerX=evt.offsetX;
+evt.layerY=evt.offsetY;
+var se=evt.srcElement,doc=(se&&se.ownerDocument)||document;
+var _42=((dojo.isIE<6)||(doc["compatMode"]=="BackCompat"))?doc.body:doc.documentElement;
+var _43=dojo._getIeDocumentElementOffset();
+evt.pageX=evt.clientX+dojo._fixIeBiDiScrollLeft(_42.scrollLeft||0)-_43.x;
+evt.pageY=evt.clientY+(_42.scrollTop||0)-_43.y;
+if(evt.type=="mouseover"){
+evt.relatedTarget=evt.fromElement;
+}
+if(evt.type=="mouseout"){
+evt.relatedTarget=evt.toElement;
+}
+evt.stopPropagation=_1._stopPropagation;
+evt.preventDefault=_1._preventDefault;
+return _1._fixKeys(evt);
+},_fixKeys:function(evt){
+switch(evt.type){
+case "keypress":
+var c=("charCode" in evt?evt.charCode:evt.keyCode);
+if(c==10){
+c=0;
+evt.keyCode=13;
+}else{
+if(c==13||c==27){
+c=0;
+}else{
+if(c==3){
+c=99;
+}
+}
+}
+evt.charCode=c;
+_1._setKeyChar(evt);
+break;
+}
+return evt;
+},_stealthKeyDown:function(evt){
+var kp=evt.currentTarget.onkeypress;
+if(!kp||!kp[_27]){
+return;
+}
+var k=evt.keyCode;
+var _49=k!=13&&k!=32&&k!=27&&(k<48||k>90)&&(k<96||k>111)&&(k<186||k>192)&&(k<219||k>222);
+if(_49||evt.ctrlKey){
+var c=_49?0:k;
+if(evt.ctrlKey){
+if(k==3||k==13){
+return;
+}else{
+if(c>95&&c<106){
+c-=48;
+}else{
+if((!evt.shiftKey)&&(c>=65&&c<=90)){
+c+=32;
+}else{
+c=_1._punctMap[c]||c;
+}
+}
+}
+}
+var _4b=_1._synthesizeEvent(evt,{type:"keypress",faux:true,charCode:c});
+kp.call(evt.currentTarget,_4b);
+evt.cancelBubble=_4b.cancelBubble;
+evt.returnValue=_4b.returnValue;
+_23(evt,_4b.keyCode);
+}
+},_stopPropagation:function(){
+this.cancelBubble=true;
+},_preventDefault:function(){
+this.bubbledKeyCode=this.keyCode;
+if(this.ctrlKey){
+_23(this,0);
+}
+this.returnValue=false;
+}});
+dojo.stopEvent=function(evt){
+evt=evt||window.event;
+_1._stopPropagation.call(evt);
+_1._preventDefault.call(evt);
+};
+}
+_1._synthesizeEvent=function(evt,_4e){
+var _4f=dojo.mixin({},evt,_4e);
+_1._setKeyChar(_4f);
+_4f.preventDefault=function(){
+evt.preventDefault();
+};
+_4f.stopPropagation=function(){
+evt.stopPropagation();
+};
+return _4f;
+};
+if(dojo.isOpera){
+dojo.mixin(_1,{_fixEvent:function(evt,_51){
+switch(evt.type){
+case "keypress":
+var c=evt.which;
+if(c==3){
+c=99;
+}
+c=c<41&&!evt.shiftKey?0:c;
+if(evt.ctrlKey&&!evt.shiftKey&&c>=65&&c<=90){
+c+=32;
+}
+return _1._synthesizeEvent(evt,{charCode:c});
+}
+return evt;
+}});
+}
+if(dojo.isWebKit){
+_1._add=_1.add;
+_1._remove=_1.remove;
+dojo.mixin(_1,{add:function(_53,_54,fp){
+if(!_53){
+return;
+}
+var _56=_1._add(_53,_54,fp);
+if(_1._normalizeEventName(_54)=="keypress"){
+_56._stealthKeyDownHandle=_1._add(_53,"keydown",function(evt){
+var k=evt.keyCode;
+var _59=k!=13&&k!=32&&k!=27&&(k<48||k>90)&&(k<96||k>111)&&(k<186||k>192)&&(k<219||k>222);
+if(_59||evt.ctrlKey){
+var c=_59?0:k;
+if(evt.ctrlKey){
+if(k==3||k==13){
+return;
+}else{
+if(c>95&&c<106){
+c-=48;
+}else{
+if(!evt.shiftKey&&c>=65&&c<=90){
+c+=32;
+}else{
+c=_1._punctMap[c]||c;
+}
+}
+}
+}
+var _5b=_1._synthesizeEvent(evt,{type:"keypress",faux:true,charCode:c});
+fp.call(evt.currentTarget,_5b);
+}
+});
+}
+return _56;
+},remove:function(_5c,_5d,_5e){
+if(_5c){
+if(_5e._stealthKeyDownHandle){
+_1._remove(_5c,"keydown",_5e._stealthKeyDownHandle);
+}
+_1._remove(_5c,_5d,_5e);
+}
+},_fixEvent:function(evt,_60){
+switch(evt.type){
+case "keypress":
+if(evt.faux){
+return evt;
+}
+var c=evt.charCode;
+c=c>=32?c:0;
+return _1._synthesizeEvent(evt,{charCode:c,faux:true});
+}
+return evt;
+}});
+}
+})();
+if(dojo.isIE){
+dojo._ieDispatcher=function(_62,_63){
+var ap=Array.prototype,h=dojo._ie_listener.handlers,c=_62.callee,ls=c[dojo._ieListenersName],t=h[c.target];
+var r=t&&t.apply(_63,_62);
+var lls=[].concat(ls);
+for(var i in lls){
+var f=h[lls[i]];
+if(!(i in ap)&&f){
+f.apply(_63,_62);
+}
+}
+return r;
+};
+dojo._getIeDispatcher=function(){
+return new Function(dojo._scopeName+"._ieDispatcher(arguments, this)");
+};
+dojo._event_listener._fixCallback=function(fp){
+var f=dojo._event_listener._fixEvent;
+return function(e){
+return fp.call(this,f(e,this));
+};
+};
+}
+}
diff --git a/dojo/_base/fx.js b/dojo/_base/fx.js
new file mode 100644
index 0000000..dbf9126
--- /dev/null
+++ b/dojo/_base/fx.js
@@ -0,0 +1,296 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._base.fx"]){
+dojo._hasResource["dojo._base.fx"]=true;
+dojo.provide("dojo._base.fx");
+dojo.require("dojo._base.Color");
+dojo.require("dojo._base.connect");
+dojo.require("dojo._base.declare");
+dojo.require("dojo._base.lang");
+dojo.require("dojo._base.html");
+(function(){
+var d=dojo;
+var _2=d.mixin;
+dojo._Line=function(_3,_4){
+this.start=_3;
+this.end=_4;
+};
+dojo._Line.prototype.getValue=function(n){
+return ((this.end-this.start)*n)+this.start;
+};
+d.declare("dojo._Animation",null,{constructor:function(_6){
+_2(this,_6);
+if(d.isArray(this.curve)){
+this.curve=new d._Line(this.curve[0],this.curve[1]);
+}
+},duration:350,repeat:0,rate:10,_percent:0,_startRepeatCount:0,_fire:function(_7,_8){
+if(this[_7]){
+if(dojo.config.debugAtAllCosts){
+this[_7].apply(this,_8||[]);
+}else{
+try{
+this[_7].apply(this,_8||[]);
+}
+catch(e){
+console.error("exception in animation handler for:",_7);
+console.error(e);
+}
+}
+}
+return this;
+},play:function(_9,_a){
+var _t=this;
+if(_t._delayTimer){
+_t._clearTimer();
+}
+if(_a){
+_t._stopTimer();
+_t._active=_t._paused=false;
+_t._percent=0;
+}else{
+if(_t._active&&!_t._paused){
+return _t;
+}
+}
+_t._fire("beforeBegin");
+var de=_9||_t.delay,_p=dojo.hitch(_t,"_play",_a);
+if(de>0){
+_t._delayTimer=setTimeout(_p,de);
+return _t;
+}
+_p();
+return _t;
+},_play:function(_e){
+var _t=this;
+if(_t._delayTimer){
+_t._clearTimer();
+}
+_t._startTime=new Date().valueOf();
+if(_t._paused){
+_t._startTime-=_t.duration*_t._percent;
+}
+_t._endTime=_t._startTime+_t.duration;
+_t._active=true;
+_t._paused=false;
+var _10=_t.curve.getValue(_t._percent);
+if(!_t._percent){
+if(!_t._startRepeatCount){
+_t._startRepeatCount=_t.repeat;
+}
+_t._fire("onBegin",[_10]);
+}
+_t._fire("onPlay",[_10]);
+_t._cycle();
+return _t;
+},pause:function(){
+var _t=this;
+if(_t._delayTimer){
+_t._clearTimer();
+}
+_t._stopTimer();
+if(!_t._active){
+return _t;
+}
+_t._paused=true;
+_t._fire("onPause",[_t.curve.getValue(_t._percent)]);
+return _t;
+},gotoPercent:function(_12,_13){
+var _t=this;
+_t._stopTimer();
+_t._active=_t._paused=true;
+_t._percent=_12;
+if(_13){
+_t.play();
+}
+return _t;
+},stop:function(_15){
+var _t=this;
+if(_t._delayTimer){
+_t._clearTimer();
+}
+if(!_t._timer){
+return _t;
+}
+_t._stopTimer();
+if(_15){
+_t._percent=1;
+}
+_t._fire("onStop",[_t.curve.getValue(_t._percent)]);
+_t._active=_t._paused=false;
+return _t;
+},status:function(){
+if(this._active){
+return this._paused?"paused":"playing";
+}
+return "stopped";
+},_cycle:function(){
+var _t=this;
+if(_t._active){
+var _18=new Date().valueOf();
+var _19=(_18-_t._startTime)/(_t._endTime-_t._startTime);
+if(_19>=1){
+_19=1;
+}
+_t._percent=_19;
+if(_t.easing){
+_19=_t.easing(_19);
+}
+_t._fire("onAnimate",[_t.curve.getValue(_19)]);
+if(_t._percent<1){
+_t._startTimer();
+}else{
+_t._active=false;
+if(_t.repeat>0){
+_t.repeat--;
+_t.play(null,true);
+}else{
+if(_t.repeat==-1){
+_t.play(null,true);
+}else{
+if(_t._startRepeatCount){
+_t.repeat=_t._startRepeatCount;
+_t._startRepeatCount=0;
+}
+}
+}
+_t._percent=0;
+_t._fire("onEnd");
+_t._stopTimer();
+}
+}
+return _t;
+},_clearTimer:function(){
+clearTimeout(this._delayTimer);
+delete this._delayTimer;
+}});
+var ctr=0,_1b=[],_1c=null,_1d={run:function(){
+}};
+dojo._Animation.prototype._startTimer=function(){
+if(!this._timer){
+this._timer=d.connect(_1d,"run",this,"_cycle");
+ctr++;
+}
+if(!_1c){
+_1c=setInterval(d.hitch(_1d,"run"),this.rate);
+}
+};
+dojo._Animation.prototype._stopTimer=function(){
+if(this._timer){
+d.disconnect(this._timer);
+this._timer=null;
+ctr--;
+}
+if(ctr<=0){
+clearInterval(_1c);
+_1c=null;
+ctr=0;
+}
+};
+var _1e=d.isIE?function(_1f){
+var ns=_1f.style;
+if(!ns.width.length&&d.style(_1f,"width")=="auto"){
+ns.width="auto";
+}
+}:function(){
+};
+dojo._fade=function(_21){
+_21.node=d.byId(_21.node);
+var _22=_2({properties:{}},_21),_23=(_22.properties.opacity={});
+_23.start=!("start" in _22)?function(){
+return +d.style(_22.node,"opacity")||0;
+}:_22.start;
+_23.end=_22.end;
+var _24=d.animateProperty(_22);
+d.connect(_24,"beforeBegin",d.partial(_1e,_22.node));
+return _24;
+};
+dojo.fadeIn=function(_25){
+return d._fade(_2({end:1},_25));
+};
+dojo.fadeOut=function(_26){
+return d._fade(_2({end:0},_26));
+};
+dojo._defaultEasing=function(n){
+return 0.5+((Math.sin((n+1.5)*Math.PI))/2);
+};
+var _28=function(_29){
+this._properties=_29;
+for(var p in _29){
+var _2b=_29[p];
+if(_2b.start instanceof d.Color){
+_2b.tempColor=new d.Color();
+}
+}
+};
+_28.prototype.getValue=function(r){
+var ret={};
+for(var p in this._properties){
+var _2f=this._properties[p],_30=_2f.start;
+if(_30 instanceof d.Color){
+ret[p]=d.blendColors(_30,_2f.end,r,_2f.tempColor).toCss();
+}else{
+if(!d.isArray(_30)){
+ret[p]=((_2f.end-_30)*r)+_30+(p!="opacity"?_2f.units||"px":0);
+}
+}
+}
+return ret;
+};
+dojo.animateProperty=function(_31){
+_31.node=d.byId(_31.node);
+if(!_31.easing){
+_31.easing=d._defaultEasing;
+}
+var _32=new d._Animation(_31);
+d.connect(_32,"beforeBegin",_32,function(){
+var pm={};
+for(var p in this.properties){
+if(p=="width"||p=="height"){
+this.node.display="block";
+}
+var _35=this.properties[p];
+_35=pm[p]=_2({},(d.isObject(_35)?_35:{end:_35}));
+if(d.isFunction(_35.start)){
+_35.start=_35.start();
+}
+if(d.isFunction(_35.end)){
+_35.end=_35.end();
+}
+var _36=(p.toLowerCase().indexOf("color")>=0);
+function _37(_38,p){
+var v={height:_38.offsetHeight,width:_38.offsetWidth}[p];
+if(v!==undefined){
+return v;
+}
+v=d.style(_38,p);
+return (p=="opacity")?+v:(_36?v:parseFloat(v));
+};
+if(!("end" in _35)){
+_35.end=_37(this.node,p);
+}else{
+if(!("start" in _35)){
+_35.start=_37(this.node,p);
+}
+}
+if(_36){
+_35.start=new d.Color(_35.start);
+_35.end=new d.Color(_35.end);
+}else{
+_35.start=(p=="opacity")?+_35.start:parseFloat(_35.start);
+}
+}
+this.curve=new _28(pm);
+});
+d.connect(_32,"onAnimate",d.hitch(d,"style",_32.node));
+return _32;
+};
+dojo.anim=function(_3b,_3c,_3d,_3e,_3f,_40){
+return d.animateProperty({node:_3b,duration:_3d||d._Animation.prototype.duration,properties:_3c,easing:_3e,onEnd:_3f}).play(_40||0);
+};
+})();
+}
diff --git a/dojo/_base/html.js b/dojo/_base/html.js
new file mode 100644
index 0000000..9e1109e
--- /dev/null
+++ b/dojo/_base/html.js
@@ -0,0 +1,715 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._base.html"]){
+dojo._hasResource["dojo._base.html"]=true;
+dojo.require("dojo._base.lang");
+dojo.provide("dojo._base.html");
+try{
+document.execCommand("BackgroundImageCache",false,true);
+}
+catch(e){
+}
+if(dojo.isIE||dojo.isOpera){
+dojo.byId=function(id,_2){
+if(dojo.isString(id)){
+var _d=_2||dojo.doc;
+var te=_d.getElementById(id);
+if(te&&(te.attributes.id.value==id||te.id==id)){
+return te;
+}else{
+var _5=_d.all[id];
+if(!_5||_5.nodeName){
+_5=[_5];
+}
+var i=0;
+while((te=_5[i++])){
+if((te.attributes&&te.attributes.id&&te.attributes.id.value==id)||te.id==id){
+return te;
+}
+}
+}
+}else{
+return id;
+}
+};
+}else{
+dojo.byId=function(id,_8){
+return dojo.isString(id)?(_8||dojo.doc).getElementById(id):id;
+};
+}
+(function(){
+var d=dojo;
+var _a=null;
+d.addOnWindowUnload(function(){
+_a=null;
+});
+dojo._destroyElement=dojo.destroy=function(_b){
+_b=d.byId(_b);
+try{
+if(!_a||_a.ownerDocument!=_b.ownerDocument){
+_a=_b.ownerDocument.createElement("div");
+}
+_a.appendChild(_b.parentNode?_b.parentNode.removeChild(_b):_b);
+_a.innerHTML="";
+}
+catch(e){
+}
+};
+dojo.isDescendant=function(_c,_d){
+try{
+_c=d.byId(_c);
+_d=d.byId(_d);
+while(_c){
+if(_c===_d){
+return true;
+}
+_c=_c.parentNode;
+}
+}
+catch(e){
+}
+return false;
+};
+dojo.setSelectable=function(_e,_f){
+_e=d.byId(_e);
+if(d.isMozilla){
+_e.style.MozUserSelect=_f?"":"none";
+}else{
+if(d.isKhtml||d.isWebKit){
+_e.style.KhtmlUserSelect=_f?"auto":"none";
+}else{
+if(d.isIE){
+var v=(_e.unselectable=_f?"":"on");
+d.query("*",_e).forEach("item.unselectable = '"+v+"'");
+}
+}
+}
+};
+var _11=function(_12,ref){
+var _14=ref.parentNode;
+if(_14){
+_14.insertBefore(_12,ref);
+}
+};
+var _15=function(_16,ref){
+var _18=ref.parentNode;
+if(_18){
+if(_18.lastChild==ref){
+_18.appendChild(_16);
+}else{
+_18.insertBefore(_16,ref.nextSibling);
+}
+}
+};
+dojo.place=function(_19,_1a,_1b){
+_1a=d.byId(_1a);
+if(d.isString(_19)){
+_19=_19.charAt(0)=="<"?d._toDom(_19,_1a.ownerDocument):d.byId(_19);
+}
+if(typeof _1b=="number"){
+var cn=_1a.childNodes;
+if(!cn.length||cn.length<=_1b){
+_1a.appendChild(_19);
+}else{
+_11(_19,cn[_1b<0?0:_1b]);
+}
+}else{
+switch(_1b){
+case "before":
+_11(_19,_1a);
+break;
+case "after":
+_15(_19,_1a);
+break;
+case "replace":
+_1a.parentNode.replaceChild(_19,_1a);
+break;
+case "only":
+d.empty(_1a);
+_1a.appendChild(_19);
+break;
+case "first":
+if(_1a.firstChild){
+_11(_19,_1a.firstChild);
+break;
+}
+default:
+_1a.appendChild(_19);
+}
+}
+return _19;
+};
+dojo.boxModel="content-box";
+if(d.isIE){
+var _1d=document.compatMode;
+d.boxModel=_1d=="BackCompat"||_1d=="QuirksMode"||d.isIE<6?"border-box":"content-box";
+}
+var gcs;
+if(d.isWebKit){
+gcs=function(_1f){
+var s;
+if(_1f.nodeType==1){
+var dv=_1f.ownerDocument.defaultView;
+s=dv.getComputedStyle(_1f,null);
+if(!s&&_1f.style){
+_1f.style.display="";
+s=dv.getComputedStyle(_1f,null);
+}
+}
+return s||{};
+};
+}else{
+if(d.isIE){
+gcs=function(_22){
+return _22.nodeType==1?_22.currentStyle:{};
+};
+}else{
+gcs=function(_23){
+return _23.nodeType==1?_23.ownerDocument.defaultView.getComputedStyle(_23,null):{};
+};
+}
+}
+dojo.getComputedStyle=gcs;
+if(!d.isIE){
+d._toPixelValue=function(_24,_25){
+return parseFloat(_25)||0;
+};
+}else{
+d._toPixelValue=function(_26,_27){
+if(!_27){
+return 0;
+}
+if(_27=="medium"){
+return 4;
+}
+if(_27.slice&&_27.slice(-2)=="px"){
+return parseFloat(_27);
+}
+with(_26){
+var _28=style.left;
+var _29=runtimeStyle.left;
+runtimeStyle.left=currentStyle.left;
+try{
+style.left=_27;
+_27=style.pixelLeft;
+}
+catch(e){
+_27=0;
+}
+style.left=_28;
+runtimeStyle.left=_29;
+}
+return _27;
+};
+}
+var px=d._toPixelValue;
+var _2b="DXImageTransform.Microsoft.Alpha";
+var af=function(n,f){
+try{
+return n.filters.item(_2b);
+}
+catch(e){
+return f?{}:null;
+}
+};
+dojo._getOpacity=d.isIE?function(_2f){
+try{
+return af(_2f).Opacity/100;
+}
+catch(e){
+return 1;
+}
+}:function(_30){
+return gcs(_30).opacity;
+};
+dojo._setOpacity=d.isIE?function(_31,_32){
+var ov=_32*100;
+_31.style.zoom=1;
+af(_31,1).Enabled=!(_32==1);
+if(!af(_31)){
+_31.style.filter+=" progid:"+_2b+"(Opacity="+ov+")";
+}else{
+af(_31,1).Opacity=ov;
+}
+if(_31.nodeName.toLowerCase()=="tr"){
+d.query("> td",_31).forEach(function(i){
+d._setOpacity(i,_32);
+});
+}
+return _32;
+}:function(_35,_36){
+return _35.style.opacity=_36;
+};
+var _37={left:true,top:true};
+var _38=/margin|padding|width|height|max|min|offset/;
+var _39=function(_3a,_3b,_3c){
+_3b=_3b.toLowerCase();
+if(d.isIE){
+if(_3c=="auto"){
+if(_3b=="height"){
+return _3a.offsetHeight;
+}
+if(_3b=="width"){
+return _3a.offsetWidth;
+}
+}
+if(_3b=="fontweight"){
+switch(_3c){
+case 700:
+return "bold";
+case 400:
+default:
+return "normal";
+}
+}
+}
+if(!(_3b in _37)){
+_37[_3b]=_38.test(_3b);
+}
+return _37[_3b]?px(_3a,_3c):_3c;
+};
+var _3d=d.isIE?"styleFloat":"cssFloat",_3e={"cssFloat":_3d,"styleFloat":_3d,"float":_3d};
+dojo.style=function(_3f,_40,_41){
+var n=d.byId(_3f),_43=arguments.length,op=(_40=="opacity");
+_40=_3e[_40]||_40;
+if(_43==3){
+return op?d._setOpacity(n,_41):n.style[_40]=_41;
+}
+if(_43==2&&op){
+return d._getOpacity(n);
+}
+var s=gcs(n);
+if(_43==2&&!d.isString(_40)){
+for(var x in _40){
+d.style(_3f,x,_40[x]);
+}
+return s;
+}
+return (_43==1)?s:_39(n,_40,s[_40]||n.style[_40]);
+};
+dojo._getPadExtents=function(n,_48){
+var s=_48||gcs(n),l=px(n,s.paddingLeft),t=px(n,s.paddingTop);
+return {l:l,t:t,w:l+px(n,s.paddingRight),h:t+px(n,s.paddingBottom)};
+};
+dojo._getBorderExtents=function(n,_4d){
+var ne="none",s=_4d||gcs(n),bl=(s.borderLeftStyle!=ne?px(n,s.borderLeftWidth):0),bt=(s.borderTopStyle!=ne?px(n,s.borderTopWidth):0);
+return {l:bl,t:bt,w:bl+(s.borderRightStyle!=ne?px(n,s.borderRightWidth):0),h:bt+(s.borderBottomStyle!=ne?px(n,s.borderBottomWidth):0)};
+};
+dojo._getPadBorderExtents=function(n,_53){
+var s=_53||gcs(n),p=d._getPadExtents(n,s),b=d._getBorderExtents(n,s);
+return {l:p.l+b.l,t:p.t+b.t,w:p.w+b.w,h:p.h+b.h};
+};
+dojo._getMarginExtents=function(n,_58){
+var s=_58||gcs(n),l=px(n,s.marginLeft),t=px(n,s.marginTop),r=px(n,s.marginRight),b=px(n,s.marginBottom);
+if(d.isWebKit&&(s.position!="absolute")){
+r=l;
+}
+return {l:l,t:t,w:l+r,h:t+b};
+};
+dojo._getMarginBox=function(_5e,_5f){
+var s=_5f||gcs(_5e),me=d._getMarginExtents(_5e,s);
+var l=_5e.offsetLeft-me.l,t=_5e.offsetTop-me.t,p=_5e.parentNode;
+if(d.isMoz){
+var sl=parseFloat(s.left),st=parseFloat(s.top);
+if(!isNaN(sl)&&!isNaN(st)){
+l=sl,t=st;
+}else{
+if(p&&p.style){
+var pcs=gcs(p);
+if(pcs.overflow!="visible"){
+var be=d._getBorderExtents(p,pcs);
+l+=be.l,t+=be.t;
+}
+}
+}
+}else{
+if(d.isOpera||(d.isIE>7&&!d.isQuirks)){
+if(p){
+be=d._getBorderExtents(p);
+l-=be.l;
+t-=be.t;
+}
+}
+}
+return {l:l,t:t,w:_5e.offsetWidth+me.w,h:_5e.offsetHeight+me.h};
+};
+dojo._getContentBox=function(_69,_6a){
+var s=_6a||gcs(_69),pe=d._getPadExtents(_69,s),be=d._getBorderExtents(_69,s),w=_69.clientWidth,h;
+if(!w){
+w=_69.offsetWidth,h=_69.offsetHeight;
+}else{
+h=_69.clientHeight,be.w=be.h=0;
+}
+if(d.isOpera){
+pe.l+=be.l;
+pe.t+=be.t;
+}
+return {l:pe.l,t:pe.t,w:w-pe.w-be.w,h:h-pe.h-be.h};
+};
+dojo._getBorderBox=function(_70,_71){
+var s=_71||gcs(_70),pe=d._getPadExtents(_70,s),cb=d._getContentBox(_70,s);
+return {l:cb.l-pe.l,t:cb.t-pe.t,w:cb.w+pe.w,h:cb.h+pe.h};
+};
+dojo._setBox=function(_75,l,t,w,h,u){
+u=u||"px";
+var s=_75.style;
+if(!isNaN(l)){
+s.left=l+u;
+}
+if(!isNaN(t)){
+s.top=t+u;
+}
+if(w>=0){
+s.width=w+u;
+}
+if(h>=0){
+s.height=h+u;
+}
+};
+dojo._isButtonTag=function(_7c){
+return _7c.tagName=="BUTTON"||_7c.tagName=="INPUT"&&_7c.getAttribute("type").toUpperCase()=="BUTTON";
+};
+dojo._usesBorderBox=function(_7d){
+var n=_7d.tagName;
+return d.boxModel=="border-box"||n=="TABLE"||d._isButtonTag(_7d);
+};
+dojo._setContentSize=function(_7f,_80,_81,_82){
+if(d._usesBorderBox(_7f)){
+var pb=d._getPadBorderExtents(_7f,_82);
+if(_80>=0){
+_80+=pb.w;
+}
+if(_81>=0){
+_81+=pb.h;
+}
+}
+d._setBox(_7f,NaN,NaN,_80,_81);
+};
+dojo._setMarginBox=function(_84,_85,_86,_87,_88,_89){
+var s=_89||gcs(_84),bb=d._usesBorderBox(_84),pb=bb?_8d:d._getPadBorderExtents(_84,s);
+if(d.isWebKit){
+if(d._isButtonTag(_84)){
+var ns=_84.style;
+if(_87>=0&&!ns.width){
+ns.width="4px";
+}
+if(_88>=0&&!ns.height){
+ns.height="4px";
+}
+}
+}
+var mb=d._getMarginExtents(_84,s);
+if(_87>=0){
+_87=Math.max(_87-pb.w-mb.w,0);
+}
+if(_88>=0){
+_88=Math.max(_88-pb.h-mb.h,0);
+}
+d._setBox(_84,_85,_86,_87,_88);
+};
+var _8d={l:0,t:0,w:0,h:0};
+dojo.marginBox=function(_90,box){
+var n=d.byId(_90),s=gcs(n),b=box;
+return !b?d._getMarginBox(n,s):d._setMarginBox(n,b.l,b.t,b.w,b.h,s);
+};
+dojo.contentBox=function(_95,box){
+var n=d.byId(_95),s=gcs(n),b=box;
+return !b?d._getContentBox(n,s):d._setContentSize(n,b.w,b.h,s);
+};
+var _9a=function(_9b,_9c){
+if(!(_9b=(_9b||0).parentNode)){
+return 0;
+}
+var val,_9e=0,_b=d.body();
+while(_9b&&_9b.style){
+if(gcs(_9b).position=="fixed"){
+return 0;
+}
+val=_9b[_9c];
+if(val){
+_9e+=val-0;
+if(_9b==_b){
+break;
+}
+}
+_9b=_9b.parentNode;
+}
+return _9e;
+};
+dojo._docScroll=function(){
+var _b=d.body(),_w=d.global,de=d.doc.documentElement;
+return {y:(_w.pageYOffset||de.scrollTop||_b.scrollTop||0),x:(_w.pageXOffset||d._fixIeBiDiScrollLeft(de.scrollLeft)||_b.scrollLeft||0)};
+};
+dojo._isBodyLtr=function(){
+return ("_bodyLtr" in d)?d._bodyLtr:d._bodyLtr=gcs(d.body()).direction=="ltr";
+};
+dojo._getIeDocumentElementOffset=function(){
+var de=d.doc.documentElement;
+if(d.isIE<7){
+return {x:d._isBodyLtr()||window.parent==window?de.clientLeft:de.offsetWidth-de.clientWidth-de.clientLeft,y:de.clientTop};
+}else{
+if(d.isIE<8){
+return {x:de.getBoundingClientRect().left,y:de.getBoundingClientRect().top};
+}else{
+return {x:0,y:0};
+}
+}
+};
+dojo._fixIeBiDiScrollLeft=function(_a4){
+var dd=d.doc;
+if(d.isIE<8&&!d._isBodyLtr()){
+var de=dd.compatMode=="BackCompat"?dd.body:dd.documentElement;
+return _a4+de.clientWidth-de.scrollWidth;
+}
+return _a4;
+};
+dojo._abs=function(_a7,_a8){
+var db=d.body(),dh=d.body().parentNode,ret;
+if(_a7["getBoundingClientRect"]){
+var _ac=_a7.getBoundingClientRect();
+ret={x:_ac.left,y:_ac.top};
+if(d.isFF>=3){
+var cs=gcs(dh);
+ret.x-=px(dh,cs.marginLeft)+px(dh,cs.borderLeftWidth);
+ret.y-=px(dh,cs.marginTop)+px(dh,cs.borderTopWidth);
+}
+if(d.isIE){
+var _ae=d._getIeDocumentElementOffset();
+ret.x-=_ae.x+(d.isQuirks?db.clientLeft:0);
+ret.y-=_ae.y+(d.isQuirks?db.clientTop:0);
+}
+}else{
+ret={x:0,y:0};
+if(_a7["offsetParent"]){
+ret.x-=_9a(_a7,"scrollLeft");
+ret.y-=_9a(_a7,"scrollTop");
+var _af=_a7;
+do{
+var n=_af.offsetLeft,t=_af.offsetTop;
+ret.x+=isNaN(n)?0:n;
+ret.y+=isNaN(t)?0:t;
+cs=gcs(_af);
+if(_af!=_a7){
+if(d.isFF){
+ret.x+=2*px(_af,cs.borderLeftWidth);
+ret.y+=2*px(_af,cs.borderTopWidth);
+}else{
+ret.x+=px(_af,cs.borderLeftWidth);
+ret.y+=px(_af,cs.borderTopWidth);
+}
+}
+if(d.isFF&&cs.position=="static"){
+var _b2=_af.parentNode;
+while(_b2!=_af.offsetParent){
+var pcs=gcs(_b2);
+if(pcs.position=="static"){
+ret.x+=px(_af,pcs.borderLeftWidth);
+ret.y+=px(_af,pcs.borderTopWidth);
+}
+_b2=_b2.parentNode;
+}
+}
+_af=_af.offsetParent;
+}while((_af!=dh)&&_af);
+}else{
+if(_a7.x&&_a7.y){
+ret.x+=isNaN(_a7.x)?0:_a7.x;
+ret.y+=isNaN(_a7.y)?0:_a7.y;
+}
+}
+}
+if(_a8){
+var _b4=d._docScroll();
+ret.x+=_b4.x;
+ret.y+=_b4.y;
+}
+return ret;
+};
+dojo.coords=function(_b5,_b6){
+var n=d.byId(_b5),s=gcs(n),mb=d._getMarginBox(n,s);
+var abs=d._abs(n,_b6);
+mb.x=abs.x;
+mb.y=abs.y;
+return mb;
+};
+var _bb=d.isIE<8;
+var _bc=function(_bd){
+switch(_bd.toLowerCase()){
+case "tabindex":
+return _bb?"tabIndex":"tabindex";
+case "readonly":
+return "readOnly";
+case "class":
+return "className";
+case "for":
+case "htmlfor":
+return _bb?"htmlFor":"for";
+default:
+return _bd;
+}
+};
+var _be={colspan:"colSpan",enctype:"enctype",frameborder:"frameborder",method:"method",rowspan:"rowSpan",scrolling:"scrolling",shape:"shape",span:"span",type:"type",valuetype:"valueType",classname:"className",innerhtml:"innerHTML"};
+dojo.hasAttr=function(_bf,_c0){
+_bf=d.byId(_bf);
+var _c1=_bc(_c0);
+_c1=_c1=="htmlFor"?"for":_c1;
+var _c2=_bf.getAttributeNode&&_bf.getAttributeNode(_c1);
+return _c2?_c2.specified:false;
+};
+var _c3={},_c4=0,_c5=dojo._scopeName+"attrid",_c6={col:1,colgroup:1,table:1,tbody:1,tfoot:1,thead:1,tr:1,title:1};
+dojo.attr=function(_c7,_c8,_c9){
+_c7=d.byId(_c7);
+var _ca=arguments.length;
+if(_ca==2&&!d.isString(_c8)){
+for(var x in _c8){
+d.attr(_c7,x,_c8[x]);
+}
+return;
+}
+_c8=_bc(_c8);
+if(_ca==3){
+if(d.isFunction(_c9)){
+var _cc=d.attr(_c7,_c5);
+if(!_cc){
+_cc=_c4++;
+d.attr(_c7,_c5,_cc);
+}
+if(!_c3[_cc]){
+_c3[_cc]={};
+}
+var h=_c3[_cc][_c8];
+if(h){
+d.disconnect(h);
+}else{
+try{
+delete _c7[_c8];
+}
+catch(e){
+}
+}
+_c3[_cc][_c8]=d.connect(_c7,_c8,_c9);
+}else{
+if(typeof _c9=="boolean"){
+_c7[_c8]=_c9;
+}else{
+if(_c8==="style"&&!d.isString(_c9)){
+d.style(_c7,_c9);
+}else{
+if(_c8=="className"){
+_c7.className=_c9;
+}else{
+if(_c8==="innerHTML"){
+if(d.isIE&&_c7.tagName.toLowerCase() in _c6){
+d.empty(_c7);
+_c7.appendChild(d._toDom(_c9,_c7.ownerDocument));
+}else{
+_c7[_c8]=_c9;
+}
+}else{
+_c7.setAttribute(_c8,_c9);
+}
+}
+}
+}
+}
+}else{
+var _ce=_be[_c8.toLowerCase()];
+if(_ce){
+return _c7[_ce];
+}
+var _cf=_c7[_c8];
+return (typeof _cf=="boolean"||typeof _cf=="function")?_cf:(d.hasAttr(_c7,_c8)?_c7.getAttribute(_c8):null);
+}
+};
+dojo.removeAttr=function(_d0,_d1){
+d.byId(_d0).removeAttribute(_bc(_d1));
+};
+dojo.create=function(tag,_d3,_d4,pos){
+var doc=d.doc;
+if(_d4){
+_d4=d.byId(_d4);
+doc=_d4.ownerDocument;
+}
+if(d.isString(tag)){
+tag=doc.createElement(tag);
+}
+if(_d3){
+d.attr(tag,_d3);
+}
+if(_d4){
+d.place(tag,_d4,pos);
+}
+return tag;
+};
+d.empty=d.isIE?function(_d7){
+_d7=d.byId(_d7);
+for(var c;c=_d7.lastChild;){
+d.destroy(c);
+}
+}:function(_d9){
+d.byId(_d9).innerHTML="";
+};
+var _da={option:["select"],tbody:["table"],thead:["table"],tfoot:["table"],tr:["table","tbody"],td:["table","tbody","tr"],th:["table","thead","tr"],legend:["fieldset"],caption:["table"],colgroup:["table"],col:["table","colgroup"],li:["ul"]},_db=/<\s*([\w\:]+)/,_dc={},_dd=0,_de="__"+d._scopeName+"ToDomId";
+for(var _df in _da){
+var tw=_da[_df];
+tw.pre=_df=="option"?"<select multiple=\"multiple\">":"<"+tw.join("><")+">";
+tw.post="</"+tw.reverse().join("></")+">";
+}
+d._toDom=function(_e1,doc){
+doc=doc||d.doc;
+var _e3=doc[_de];
+if(!_e3){
+doc[_de]=_e3=++_dd+"";
+_dc[_e3]=doc.createElement("div");
+}
+_e1+="";
+var _e4=_e1.match(_db),tag=_e4?_e4[1].toLowerCase():"",_e6=_dc[_e3],_e7,i,fc,df;
+if(_e4&&_da[tag]){
+_e7=_da[tag];
+_e6.innerHTML=_e7.pre+_e1+_e7.post;
+for(i=_e7.length;i;--i){
+_e6=_e6.firstChild;
+}
+}else{
+_e6.innerHTML=_e1;
+}
+if(_e6.childNodes.length==1){
+return _e6.removeChild(_e6.firstChild);
+}
+df=doc.createDocumentFragment();
+while(fc=_e6.firstChild){
+df.appendChild(fc);
+}
+return df;
+};
+var _eb="className";
+dojo.hasClass=function(_ec,_ed){
+return ((" "+d.byId(_ec)[_eb]+" ").indexOf(" "+_ed+" ")>=0);
+};
+dojo.addClass=function(_ee,_ef){
+_ee=d.byId(_ee);
+var cls=_ee[_eb];
+if((" "+cls+" ").indexOf(" "+_ef+" ")<0){
+_ee[_eb]=cls+(cls?" ":"")+_ef;
+}
+};
+dojo.removeClass=function(_f1,_f2){
+_f1=d.byId(_f1);
+var t=d.trim((" "+_f1[_eb]+" ").replace(" "+_f2+" "," "));
+if(_f1[_eb]!=t){
+_f1[_eb]=t;
+}
+};
+dojo.toggleClass=function(_f4,_f5,_f6){
+if(_f6===undefined){
+_f6=!d.hasClass(_f4,_f5);
+}
+d[_f6?"addClass":"removeClass"](_f4,_f5);
+};
+})();
+}
diff --git a/dojo/_base/json.js b/dojo/_base/json.js
new file mode 100644
index 0000000..835114a
--- /dev/null
+++ b/dojo/_base/json.js
@@ -0,0 +1,81 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._base.json"]){
+dojo._hasResource["dojo._base.json"]=true;
+dojo.provide("dojo._base.json");
+dojo.fromJson=function(_1){
+return eval("("+_1+")");
+};
+dojo._escapeString=function(_2){
+return ("\""+_2.replace(/(["\\])/g,"\\$1")+"\"").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r");
+};
+dojo.toJsonIndentStr="\t";
+dojo.toJson=function(it,_4,_5){
+if(it===undefined){
+return "undefined";
+}
+var _6=typeof it;
+if(_6=="number"||_6=="boolean"){
+return it+"";
+}
+if(it===null){
+return "null";
+}
+if(dojo.isString(it)){
+return dojo._escapeString(it);
+}
+var _7=arguments.callee;
+var _8;
+_5=_5||"";
+var _9=_4?_5+dojo.toJsonIndentStr:"";
+var tf=it.__json__||it.json;
+if(dojo.isFunction(tf)){
+_8=tf.call(it);
+if(it!==_8){
+return _7(_8,_4,_9);
+}
+}
+if(it.nodeType&&it.cloneNode){
+throw new Error("Can't serialize DOM nodes");
+}
+var _b=_4?" ":"";
+var _c=_4?"\n":"";
+if(dojo.isArray(it)){
+var _d=dojo.map(it,function(_e){
+var _f=_7(_e,_4,_9);
+if(typeof _f!="string"){
+_f="undefined";
+}
+return _c+_9+_f;
+});
+return "["+_d.join(","+_b)+_c+_5+"]";
+}
+if(_6=="function"){
+return null;
+}
+var _10=[],key;
+for(key in it){
+var _12,val;
+if(typeof key=="number"){
+_12="\""+key+"\"";
+}else{
+if(typeof key=="string"){
+_12=dojo._escapeString(key);
+}else{
+continue;
+}
+}
+val=_7(it[key],_4,_9);
+if(typeof val!="string"){
+continue;
+}
+_10.push(_c+_9+_12+":"+_b+val);
+}
+return "{"+_10.join(","+_b)+_c+_5+"}";
+};
+}
diff --git a/dojo/_base/lang.js b/dojo/_base/lang.js
new file mode 100644
index 0000000..3f71cf6
--- /dev/null
+++ b/dojo/_base/lang.js
@@ -0,0 +1,139 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._base.lang"]){
+dojo._hasResource["dojo._base.lang"]=true;
+dojo.provide("dojo._base.lang");
+dojo.isString=function(it){
+return !!arguments.length&&it!=null&&(typeof it=="string"||it instanceof String);
+};
+dojo.isArray=function(it){
+return it&&(it instanceof Array||typeof it=="array");
+};
+dojo.isFunction=(function(){
+var _3=function(it){
+var t=typeof it;
+return it&&(t=="function"||it instanceof Function);
+};
+return dojo.isSafari?function(it){
+if(typeof it=="function"&&it=="[object NodeList]"){
+return false;
+}
+return _3(it);
+}:_3;
+})();
+dojo.isObject=function(it){
+return it!==undefined&&(it===null||typeof it=="object"||dojo.isArray(it)||dojo.isFunction(it));
+};
+dojo.isArrayLike=function(it){
+var d=dojo;
+return it&&it!==undefined&&!d.isString(it)&&!d.isFunction(it)&&!(it.tagName&&it.tagName.toLowerCase()=="form")&&(d.isArray(it)||isFinite(it.length));
+};
+dojo.isAlien=function(it){
+return it&&!dojo.isFunction(it)&&/\{\s*\[native code\]\s*\}/.test(String(it));
+};
+dojo.extend=function(_b,_c){
+for(var i=1,l=arguments.length;i<l;i++){
+dojo._mixin(_b.prototype,arguments[i]);
+}
+return _b;
+};
+dojo._hitchArgs=function(_f,_10){
+var pre=dojo._toArray(arguments,2);
+var _12=dojo.isString(_10);
+return function(){
+var _13=dojo._toArray(arguments);
+var f=_12?(_f||dojo.global)[_10]:_10;
+return f&&f.apply(_f||this,pre.concat(_13));
+};
+};
+dojo.hitch=function(_15,_16){
+if(arguments.length>2){
+return dojo._hitchArgs.apply(dojo,arguments);
+}
+if(!_16){
+_16=_15;
+_15=null;
+}
+if(dojo.isString(_16)){
+_15=_15||dojo.global;
+if(!_15[_16]){
+throw (["dojo.hitch: scope[\"",_16,"\"] is null (scope=\"",_15,"\")"].join(""));
+}
+return function(){
+return _15[_16].apply(_15,arguments||[]);
+};
+}
+return !_15?_16:function(){
+return _16.apply(_15,arguments||[]);
+};
+};
+dojo.delegate=dojo._delegate=(function(){
+function TMP(){
+};
+return function(obj,_19){
+TMP.prototype=obj;
+var tmp=new TMP();
+if(_19){
+dojo._mixin(tmp,_19);
+}
+return tmp;
+};
+})();
+(function(){
+var _1b=function(obj,_1d,_1e){
+return (_1e||[]).concat(Array.prototype.slice.call(obj,_1d||0));
+};
+var _1f=function(obj,_21,_22){
+var arr=_22||[];
+for(var x=_21||0;x<obj.length;x++){
+arr.push(obj[x]);
+}
+return arr;
+};
+dojo._toArray=dojo.isIE?function(obj){
+return ((obj.item)?_1f:_1b).apply(this,arguments);
+}:_1b;
+})();
+dojo.partial=function(_26){
+var arr=[null];
+return dojo.hitch.apply(dojo,arr.concat(dojo._toArray(arguments)));
+};
+dojo.clone=function(o){
+if(!o){
+return o;
+}
+if(dojo.isArray(o)){
+var r=[];
+for(var i=0;i<o.length;++i){
+r.push(dojo.clone(o[i]));
+}
+return r;
+}
+if(!dojo.isObject(o)){
+return o;
+}
+if(o.nodeType&&o.cloneNode){
+return o.cloneNode(true);
+}
+if(o instanceof Date){
+return new Date(o.getTime());
+}
+r=new o.constructor();
+for(i in o){
+if(!(i in r)||r[i]!=o[i]){
+r[i]=dojo.clone(o[i]);
+}
+}
+return r;
+};
+dojo.trim=String.prototype.trim?function(str){
+return str.trim();
+}:function(str){
+return str.replace(/^\s\s*/,"").replace(/\s\s*$/,"");
+};
+}
diff --git a/dojo/_base/query-sizzle.js b/dojo/_base/query-sizzle.js
new file mode 100644
index 0000000..05b1237
--- /dev/null
+++ b/dojo/_base/query-sizzle.js
@@ -0,0 +1,628 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._base.query"]){
+dojo._hasResource["dojo._base.query"]=true;
+if(typeof dojo!="undefined"){
+dojo.provide("dojo._base.query");
+dojo.require("dojo._base.NodeList");
+dojo.query=function(_1,_2,_3){
+_3=_3||dojo.NodeList;
+if(!_1){
+return new _3();
+}
+if(_1.constructor==_3){
+return _1;
+}
+if(!dojo.isString(_1)){
+return new _3(_1);
+}
+if(dojo.isString(_2)){
+_2=dojo.byId(_2);
+if(!_2){
+return new _3();
+}
+}
+return dojo.Sizzle(_1,_2,new _3());
+};
+dojo._filterQueryResult=function(_4,_5){
+return dojo.Sizzle.filter(_5,_4);
+};
+}
+(function(ns){
+var _7=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|[^[\]]+)+\]|\\.|[^ >+~,(\[]+)+|[>+~])(\s*,\s*)?/g,_8=0,_9=Object.prototype.toString;
+var _a=function(_b,_c,_d,_e){
+_d=_d||[];
+_c=_c||document;
+if(_c.nodeType!==1&&_c.nodeType!==9){
+return [];
+}
+if(!_b||typeof _b!=="string"){
+return _d;
+}
+var _f=[],m,set,_12,_13,_14,_15,_16=true;
+_7.lastIndex=0;
+while((m=_7.exec(_b))!==null){
+_f.push(m[1]);
+if(m[2]){
+_15=RegExp.rightContext;
+break;
+}
+}
+if(_f.length>1&&_17.match.POS.exec(_b)){
+if(_f.length===2&&_17.relative[_f[0]]){
+var _18="",_19;
+while((_19=_17.match.POS.exec(_b))){
+_18+=_19[0];
+_b=_b.replace(_17.match.POS,"");
+}
+set=_a.filter(_18,_a(_b,_c));
+}else{
+set=_17.relative[_f[0]]?[_c]:_a(_f.shift(),_c);
+while(_f.length){
+var _1a=[];
+_b=_f.shift();
+if(_17.relative[_b]){
+_b+=_f.shift();
+}
+for(var i=0,l=set.length;i<l;i++){
+_a(_b,set[i],_1a);
+}
+set=_1a;
+}
+}
+}else{
+var ret=_e?{expr:_f.pop(),set:_1e(_e)}:_a.find(_f.pop(),_f.length===1&&_c.parentNode?_c.parentNode:_c);
+set=_a.filter(ret.expr,ret.set);
+if(_f.length>0){
+_12=_1e(set);
+}else{
+_16=false;
+}
+while(_f.length){
+var cur=_f.pop(),pop=cur;
+if(!_17.relative[cur]){
+cur="";
+}else{
+pop=_f.pop();
+}
+if(pop==null){
+pop=_c;
+}
+_17.relative[cur](_12,pop);
+}
+}
+if(!_12){
+_12=set;
+}
+if(!_12){
+throw "Syntax error, unrecognized expression: "+(cur||_b);
+}
+if(_9.call(_12)==="[object Array]"){
+if(!_16){
+_d.push.apply(_d,_12);
+}else{
+if(_c.nodeType===1){
+for(var i=0;_12[i]!=null;i++){
+if(_12[i]&&(_12[i]===true||_12[i].nodeType===1&&_21(_c,_12[i]))){
+_d.push(set[i]);
+}
+}
+}else{
+for(var i=0;_12[i]!=null;i++){
+if(_12[i]&&_12[i].nodeType===1){
+_d.push(set[i]);
+}
+}
+}
+}
+}else{
+_1e(_12,_d);
+}
+if(_15){
+_a(_15,_c,_d,_e);
+}
+return _d;
+};
+_a.matches=function(_22,set){
+return _a(_22,null,null,set);
+};
+_a.find=function(_24,_25){
+var set,_27;
+if(!_24){
+return [];
+}
+for(var i=0,l=_17.order.length;i<l;i++){
+var _2a=_17.order[i],_27;
+if((_27=_17.match[_2a].exec(_24))){
+var _2b=RegExp.leftContext;
+if(_2b.substr(_2b.length-1)!=="\\"){
+_27[1]=(_27[1]||"").replace(/\\/g,"");
+set=_17.find[_2a](_27,_25);
+if(set!=null){
+_24=_24.replace(_17.match[_2a],"");
+break;
+}
+}
+}
+}
+if(!set){
+set=_25.getElementsByTagName("*");
+}
+return {set:set,expr:_24};
+};
+_a.filter=function(_2c,set,_2e,not){
+var old=_2c,_31=[],_32=set,_33,_34;
+while(_2c&&set.length){
+for(var _35 in _17.filter){
+if((_33=_17.match[_35].exec(_2c))!=null){
+var _36=_17.filter[_35],_37=null,_38=0,_39,_3a;
+_34=false;
+if(_32==_31){
+_31=[];
+}
+if(_17.preFilter[_35]){
+_33=_17.preFilter[_35](_33,_32,_2e,_31,not);
+if(!_33){
+_34=_39=true;
+}else{
+if(_33[0]===true){
+_37=[];
+var _3b=null,_3c;
+for(var i=0;(_3c=_32[i])!==undefined;i++){
+if(_3c&&_3b!==_3c){
+_37.push(_3c);
+_3b=_3c;
+}
+}
+}
+}
+}
+if(_33){
+for(var i=0;(_3a=_32[i])!==undefined;i++){
+if(_3a){
+if(_37&&_3a!=_37[_38]){
+_38++;
+}
+_39=_36(_3a,_33,_38,_37);
+var _3e=not^!!_39;
+if(_2e&&_39!=null){
+if(_3e){
+_34=true;
+}else{
+_32[i]=false;
+}
+}else{
+if(_3e){
+_31.push(_3a);
+_34=true;
+}
+}
+}
+}
+}
+if(_39!==undefined){
+if(!_2e){
+_32=_31;
+}
+_2c=_2c.replace(_17.match[_35],"");
+if(!_34){
+return [];
+}
+break;
+}
+}
+}
+_2c=_2c.replace(/\s*,\s*/,"");
+if(_2c==old){
+if(_34==null){
+throw "Syntax error, unrecognized expression: "+_2c;
+}else{
+break;
+}
+}
+old=_2c;
+}
+return _32;
+};
+var _17=_a.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u0128-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u0128-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u0128-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[((?:[\w\u0128-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\]/,TAG:/^((?:[\w\u0128-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child\(?(even|odd|[\dn+-]*)\)?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)\(?(\d*)\)?(?:[^-]|$)/,PSEUDO:/:((?:[\w\u0128-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\ [...]
+for(var i=0,l=_3f.length;i<l;i++){
+var _43=_3f[i];
+if(_43){
+var cur=_43.previousSibling;
+while(cur&&cur.nodeType!==1){
+cur=cur.previousSibling;
+}
+_3f[i]=typeof _40==="string"?cur||false:cur===_40;
+}
+}
+if(typeof _40==="string"){
+_a.filter(_40,_3f,true);
+}
+},">":function(_45,_46){
+if(typeof _46==="string"&&!/\W/.test(_46)){
+_46=_46.toUpperCase();
+for(var i=0,l=_45.length;i<l;i++){
+var _49=_45[i];
+if(_49){
+var _4a=_49.parentNode;
+_45[i]=_4a.nodeName===_46?_4a:false;
+}
+}
+}else{
+for(var i=0,l=_45.length;i<l;i++){
+var _49=_45[i];
+if(_49){
+_45[i]=typeof _46==="string"?_49.parentNode:_49.parentNode===_46;
+}
+}
+if(typeof _46==="string"){
+_a.filter(_46,_45,true);
+}
+}
+},"":function(_4b,_4c){
+var _4d="done"+(_8++),_4e=_4f;
+if(!_4c.match(/\W/)){
+var _50=_4c=_4c.toUpperCase();
+_4e=_51;
+}
+_4e("parentNode",_4c,_4d,_4b,_50);
+},"~":function(_52,_53){
+var _54="done"+(_8++),_55=_4f;
+if(typeof _53==="string"&&!_53.match(/\W/)){
+var _56=_53=_53.toUpperCase();
+_55=_51;
+}
+_55("previousSibling",_53,_54,_52,_56);
+}},find:{ID:function(_57,_58){
+if(_58.getElementById){
+var m=_58.getElementById(_57[1]);
+return m?[m]:[];
+}
+},NAME:function(_5a,_5b){
+return _5b.getElementsByName?_5b.getElementsByName(_5a[1]):null;
+},TAG:function(_5c,_5d){
+return _5d.getElementsByTagName(_5c[1]);
+}},preFilter:{CLASS:function(_5e,_5f,_60,_61,not){
+_5e=" "+_5e[1].replace(/\\/g,"")+" ";
+for(var i=0;_5f[i];i++){
+if(not^(" "+_5f[i].className+" ").indexOf(_5e)>=0){
+if(!_60){
+_61.push(_5f[i]);
+}
+}else{
+if(_60){
+_5f[i]=false;
+}
+}
+}
+return false;
+},ID:function(_64){
+return _64[1];
+},TAG:function(_65){
+return _65[1].toUpperCase();
+},CHILD:function(_66){
+if(_66[1]=="nth"){
+var _67=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(_66[2]=="even"&&"2n"||_66[2]=="odd"&&"2n+1"||!/\D/.test(_66[2])&&"0n+"+_66[2]||_66[2]);
+_66[2]=(_67[1]+(_67[2]||1))-0;
+_66[3]=_67[3]-0;
+}
+_66[0]="done"+(_8++);
+return _66;
+},ATTR:function(_68){
+var _69=_68[1];
+if(_17.attrMap[_69]){
+_68[1]=_17.attrMap[_69];
+}
+if(_68[2]==="~="){
+_68[4]=" "+_68[4]+" ";
+}
+return _68;
+},PSEUDO:function(_6a,_6b,_6c,_6d,not){
+if(_6a[1]==="not"){
+if(_6a[3].match(_7).length>1){
+_6a[3]=_a(_6a[3],null,null,_6b);
+}else{
+var ret=_a.filter(_6a[3],_6b,_6c,true^not);
+if(!_6c){
+_6d.push.apply(_6d,ret);
+}
+return false;
+}
+}
+return _6a;
+},POS:function(_70){
+_70.unshift(true);
+return _70;
+}},filters:{enabled:function(_71){
+return _71.disabled===false&&_71.type!=="hidden";
+},disabled:function(_72){
+return _72.disabled===true;
+},checked:function(_73){
+return _73.checked===true;
+},selected:function(_74){
+_74.parentNode.selectedIndex;
+return _74.selected===true;
+},parent:function(_75){
+return !!_75.firstChild;
+},empty:function(_76){
+return !_76.firstChild;
+},has:function(_77,i,_79){
+return !!_a(_79[3],_77).length;
+},header:function(_7a){
+return /h\d/i.test(_7a.nodeName);
+},text:function(_7b){
+return "text"===_7b.type;
+},radio:function(_7c){
+return "radio"===_7c.type;
+},checkbox:function(_7d){
+return "checkbox"===_7d.type;
+},file:function(_7e){
+return "file"===_7e.type;
+},password:function(_7f){
+return "password"===_7f.type;
+},submit:function(_80){
+return "submit"===_80.type;
+},image:function(_81){
+return "image"===_81.type;
+},reset:function(_82){
+return "reset"===_82.type;
+},button:function(_83){
+return "button"===_83.type||_83.nodeName.toUpperCase()==="BUTTON";
+},input:function(_84){
+return /input|select|textarea|button/i.test(_84.nodeName);
+}},setFilters:{first:function(_85,i){
+return i===0;
+},last:function(_87,i,_89,_8a){
+return i===_8a.length-1;
+},even:function(_8b,i){
+return i%2===0;
+},odd:function(_8d,i){
+return i%2===1;
+},lt:function(_8f,i,_91){
+return i<_91[3]-0;
+},gt:function(_92,i,_94){
+return i>_94[3]-0;
+},nth:function(_95,i,_97){
+return _97[3]-0==i;
+},eq:function(_98,i,_9a){
+return _9a[3]-0==i;
+}},filter:{CHILD:function(_9b,_9c){
+var _9d=_9c[1],_9e=_9b.parentNode;
+var _9f=_9c[0];
+if(_9e&&!_9e[_9f]){
+var _a0=1;
+for(var _a1=_9e.firstChild;_a1;_a1=_a1.nextSibling){
+if(_a1.nodeType==1){
+_a1.nodeIndex=_a0++;
+}
+}
+_9e[_9f]=_a0-1;
+}
+if(_9d=="first"){
+return _9b.nodeIndex==1;
+}else{
+if(_9d=="last"){
+return _9b.nodeIndex==_9e[_9f];
+}else{
+if(_9d=="only"){
+return _9e[_9f]==1;
+}else{
+if(_9d=="nth"){
+var add=false,_a3=_9c[2],_a4=_9c[3];
+if(_a3==1&&_a4==0){
+return true;
+}
+if(_a3==0){
+if(_9b.nodeIndex==_a4){
+add=true;
+}
+}else{
+if((_9b.nodeIndex-_a4)%_a3==0&&(_9b.nodeIndex-_a4)/_a3>=0){
+add=true;
+}
+}
+return add;
+}
+}
+}
+}
+},PSEUDO:function(_a5,_a6,i,_a8){
+var _a9=_a6[1],_aa=_17.filters[_a9];
+if(_aa){
+return _aa(_a5,i,_a6,_a8);
+}else{
+if(_a9==="contains"){
+return (_a5.textContent||_a5.innerText||"").indexOf(_a6[3])>=0;
+}else{
+if(_a9==="not"){
+var not=_a6[3];
+for(var i=0,l=not.length;i<l;i++){
+if(not[i]===_a5){
+return false;
+}
+}
+return true;
+}
+}
+}
+},ID:function(_ad,_ae){
+return _ad.nodeType===1&&_ad.getAttribute("id")===_ae;
+},TAG:function(_af,_b0){
+return (_b0==="*"&&_af.nodeType===1)||_af.nodeName===_b0;
+},CLASS:function(_b1,_b2){
+return _b2.test(_b1.className);
+},ATTR:function(_b3,_b4){
+var _b5=_b3[_b4[1]]||_b3.getAttribute(_b4[1]),_b6=_b5+"",_b7=_b4[2],_b8=_b4[4];
+return _b5==null?false:_b7==="="?_b6===_b8:_b7==="*="?_b6.indexOf(_b8)>=0:_b7==="~="?(" "+_b6+" ").indexOf(_b8)>=0:!_b4[4]?_b5:_b7==="!="?_b6!=_b8:_b7==="^="?_b6.indexOf(_b8)===0:_b7==="$="?_b6.substr(_b6.length-_b8.length)===_b8:_b7==="|="?_b6===_b8||_b6.substr(0,_b8.length+1)===_b8+"-":false;
+},POS:function(_b9,_ba,i,_bc){
+var _bd=_ba[2],_be=_17.setFilters[_bd];
+if(_be){
+return _be(_b9,i,_ba,_bc);
+}
+}}};
+for(var _bf in _17.match){
+_17.match[_bf]=RegExp(_17.match[_bf].source+/(?![^\[]*\])(?![^\(]*\))/.source);
+}
+var _1e=function(_c0,_c1){
+_c0=Array.prototype.slice.call(_c0);
+if(_c1){
+_c1.push.apply(_c1,_c0);
+return _c1;
+}
+return _c0;
+};
+try{
+Array.prototype.slice.call(document.documentElement.childNodes);
+}
+catch(e){
+_1e=function(_c2,_c3){
+var ret=_c3||[];
+if(_9.call(_c2)==="[object Array]"){
+Array.prototype.push.apply(ret,_c2);
+}else{
+if(typeof _c2.length==="number"){
+for(var i=0,l=_c2.length;i<l;i++){
+ret.push(_c2[i]);
+}
+}else{
+for(var i=0;_c2[i];i++){
+ret.push(_c2[i]);
+}
+}
+}
+return ret;
+};
+}
+(function(){
+var _c7=document.createElement("form"),id="script"+(new Date).getTime();
+_c7.innerHTML="<input name='"+id+"'/>";
+var _c9=document.documentElement;
+_c9.insertBefore(_c7,_c9.firstChild);
+if(!!document.getElementById(id)){
+_17.find.ID=function(_ca,_cb){
+if(_cb.getElementById){
+var m=_cb.getElementById(_ca[1]);
+return m?m.id===_ca[1]||m.getAttributeNode&&m.getAttributeNode("id").nodeValue===_ca[1]?[m]:undefined:[];
+}
+};
+_17.filter.ID=function(_cd,_ce){
+var _cf=_cd.getAttributeNode&&_cd.getAttributeNode("id");
+return _cd.nodeType===1&&_cf&&_cf.nodeValue===_ce;
+};
+}
+_c9.removeChild(_c7);
+})();
+(function(){
+var div=document.createElement("div");
+div.appendChild(document.createComment(""));
+if(div.getElementsByTagName("*").length>0){
+_17.find.TAG=function(_d1,_d2){
+var _d3=_d2.getElementsByTagName(_d1[1]);
+if(_d1[1]==="*"){
+var tmp=[];
+for(var i=0;_d3[i];i++){
+if(_d3[i].nodeType===1){
+tmp.push(_d3[i]);
+}
+}
+_d3=tmp;
+}
+return _d3;
+};
+}
+})();
+if(document.querySelectorAll){
+(function(){
+var _d6=_a;
+_a=function(_d7,_d8,_d9,_da){
+_d8=_d8||document;
+if(!_da&&_d8.nodeType===9){
+try{
+return _1e(_d8.querySelectorAll(_d7),_d9);
+}
+catch(e){
+}
+}
+return _d6(_d7,_d8,_d9,_da);
+};
+_a.find=_d6.find;
+_a.filter=_d6.filter;
+_a.selectors=_d6.selectors;
+_a.matches=_d6.matches;
+})();
+}
+if(document.documentElement.getElementsByClassName){
+_17.order.splice(1,0,"CLASS");
+_17.find.CLASS=function(_db,_dc){
+return _dc.getElementsByClassName(_db[1]);
+};
+}
+function _51(dir,cur,_df,_e0,_e1){
+for(var i=0,l=_e0.length;i<l;i++){
+var _e4=_e0[i];
+if(_e4){
+_e4=_e4[dir];
+var _e5=false;
+while(_e4&&_e4.nodeType){
+var _e6=_e4[_df];
+if(_e6){
+_e5=_e0[_e6];
+break;
+}
+if(_e4.nodeType===1){
+_e4[_df]=i;
+}
+if(_e4.nodeName===cur){
+_e5=_e4;
+break;
+}
+_e4=_e4[dir];
+}
+_e0[i]=_e5;
+}
+}
+};
+function _4f(dir,cur,_e9,_ea,_eb){
+for(var i=0,l=_ea.length;i<l;i++){
+var _ee=_ea[i];
+if(_ee){
+_ee=_ee[dir];
+var _ef=false;
+while(_ee&&_ee.nodeType){
+if(_ee[_e9]){
+_ef=_ea[_ee[_e9]];
+break;
+}
+if(_ee.nodeType===1){
+_ee[_e9]=i;
+if(typeof cur!=="string"){
+if(_ee===cur){
+_ef=true;
+break;
+}
+}else{
+if(_a.filter(cur,[_ee]).length>0){
+_ef=_ee;
+break;
+}
+}
+}
+_ee=_ee[dir];
+}
+_ea[i]=_ef;
+}
+}
+};
+var _21=document.compareDocumentPosition?function(a,b){
+return a.compareDocumentPosition(b)&16;
+}:function(a,b){
+return a!==b&&(a.contains?a.contains(b):true);
+};
+(ns||window).Sizzle=_a;
+})(typeof dojo=="undefined"?null:dojo);
+}
diff --git a/dojo/_base/query.js b/dojo/_base/query.js
new file mode 100644
index 0000000..c6333a9
--- /dev/null
+++ b/dojo/_base/query.js
@@ -0,0 +1,793 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._base.query"]){
+dojo._hasResource["dojo._base.query"]=true;
+if(typeof dojo!="undefined"){
+dojo.provide("dojo._base.query");
+dojo.require("dojo._base.NodeList");
+dojo.require("dojo._base.lang");
+}
+(function(d){
+var _2=d.trim;
+var _3=d.forEach;
+var _4=d._queryListCtor=d.NodeList;
+var _5=d.isString;
+var _6=function(){
+return d.doc;
+};
+var _7=((d.isWebKit||d.isMozilla)&&((_6().compatMode)=="BackCompat"));
+var _8=!!_6().firstChild["children"]?"children":"childNodes";
+var _9=">~+";
+var _a=false;
+var _b=function(){
+return true;
+};
+var _c=function(_d){
+if(_9.indexOf(_d.slice(-1))>=0){
+_d+=" * ";
+}else{
+_d+=" ";
+}
+var ts=function(s,e){
+return _2(_d.slice(s,e));
+};
+var _11=[];
+var _12=-1,_13=-1,_14=-1,_15=-1,_16=-1,_17=-1,_18=-1,lc="",cc="",_1b;
+var x=0,ql=_d.length,_1e=null,_cp=null;
+var _20=function(){
+if(_18>=0){
+var tv=(_18==x)?null:ts(_18,x);
+_1e[(_9.indexOf(tv)<0)?"tag":"oper"]=tv;
+_18=-1;
+}
+};
+var _22=function(){
+if(_17>=0){
+_1e.id=ts(_17,x).replace(/\\/g,"");
+_17=-1;
+}
+};
+var _23=function(){
+if(_16>=0){
+_1e.classes.push(ts(_16+1,x).replace(/\\/g,""));
+_16=-1;
+}
+};
+var _24=function(){
+_22();
+_20();
+_23();
+};
+var _25=function(){
+_24();
+if(_15>=0){
+_1e.pseudos.push({name:ts(_15+1,x)});
+}
+_1e.loops=(_1e.pseudos.length||_1e.attrs.length||_1e.classes.length);
+_1e.oquery=_1e.query=ts(_1b,x);
+_1e.otag=_1e.tag=(_1e["oper"])?null:(_1e.tag||"*");
+if(_1e.tag){
+_1e.tag=_1e.tag.toUpperCase();
+}
+if(_11.length&&(_11[_11.length-1].oper)){
+_1e.infixOper=_11.pop();
+_1e.query=_1e.infixOper.query+" "+_1e.query;
+}
+_11.push(_1e);
+_1e=null;
+};
+for(;lc=cc,cc=_d.charAt(x),x<ql;x++){
+if(lc=="\\"){
+continue;
+}
+if(!_1e){
+_1b=x;
+_1e={query:null,pseudos:[],attrs:[],classes:[],tag:null,oper:null,id:null,getTag:function(){
+return (_a)?this.otag:this.tag;
+}};
+_18=x;
+}
+if(_12>=0){
+if(cc=="]"){
+if(!_cp.attr){
+_cp.attr=ts(_12+1,x);
+}else{
+_cp.matchFor=ts((_14||_12+1),x);
+}
+var cmf=_cp.matchFor;
+if(cmf){
+if((cmf.charAt(0)=="\"")||(cmf.charAt(0)=="'")){
+_cp.matchFor=cmf.slice(1,-1);
+}
+}
+_1e.attrs.push(_cp);
+_cp=null;
+_12=_14=-1;
+}else{
+if(cc=="="){
+var _27=("|~^$*".indexOf(lc)>=0)?lc:"";
+_cp.type=_27+cc;
+_cp.attr=ts(_12+1,x-_27.length);
+_14=x+1;
+}
+}
+}else{
+if(_13>=0){
+if(cc==")"){
+if(_15>=0){
+_cp.value=ts(_13+1,x);
+}
+_15=_13=-1;
+}
+}else{
+if(cc=="#"){
+_24();
+_17=x+1;
+}else{
+if(cc=="."){
+_24();
+_16=x;
+}else{
+if(cc==":"){
+_24();
+_15=x;
+}else{
+if(cc=="["){
+_24();
+_12=x;
+_cp={};
+}else{
+if(cc=="("){
+if(_15>=0){
+_cp={name:ts(_15+1,x),value:null};
+_1e.pseudos.push(_cp);
+}
+_13=x;
+}else{
+if((cc==" ")&&(lc!=cc)){
+_25();
+}
+}
+}
+}
+}
+}
+}
+}
+}
+return _11;
+};
+var _28=function(_29,_2a){
+if(!_29){
+return _2a;
+}
+if(!_2a){
+return _29;
+}
+return function(){
+return _29.apply(window,arguments)&&_2a.apply(window,arguments);
+};
+};
+var _2b=function(i,arr){
+var r=arr||[];
+if(i){
+r.push(i);
+}
+return r;
+};
+var _2f=function(n){
+return (1==n.nodeType);
+};
+var _31="";
+var _32=function(_33,_34){
+if(!_33){
+return _31;
+}
+if(_34=="class"){
+return _33.className||_31;
+}
+if(_34=="for"){
+return _33.htmlFor||_31;
+}
+if(_34=="style"){
+return _33.style.cssText||_31;
+}
+return (_a?_33.getAttribute(_34):_33.getAttribute(_34,2))||_31;
+};
+var _35={"*=":function(_36,_37){
+return function(_38){
+return (_32(_38,_36).indexOf(_37)>=0);
+};
+},"^=":function(_39,_3a){
+return function(_3b){
+return (_32(_3b,_39).indexOf(_3a)==0);
+};
+},"$=":function(_3c,_3d){
+var _3e=" "+_3d;
+return function(_3f){
+var ea=" "+_32(_3f,_3c);
+return (ea.lastIndexOf(_3d)==(ea.length-_3d.length));
+};
+},"~=":function(_41,_42){
+var _43=" "+_42+" ";
+return function(_44){
+var ea=" "+_32(_44,_41)+" ";
+return (ea.indexOf(_43)>=0);
+};
+},"|=":function(_46,_47){
+var _48=" "+_47+"-";
+return function(_49){
+var ea=" "+_32(_49,_46);
+return ((ea==_47)||(ea.indexOf(_48)==0));
+};
+},"=":function(_4b,_4c){
+return function(_4d){
+return (_32(_4d,_4b)==_4c);
+};
+}};
+var _4e=(typeof _6().firstChild.nextElementSibling=="undefined");
+var _ns=!_4e?"nextElementSibling":"nextSibling";
+var _ps=!_4e?"previousElementSibling":"previousSibling";
+var _51=(_4e?_2f:_b);
+var _52=function(_53){
+while(_53=_53[_ps]){
+if(_51(_53)){
+return false;
+}
+}
+return true;
+};
+var _54=function(_55){
+while(_55=_55[_ns]){
+if(_51(_55)){
+return false;
+}
+}
+return true;
+};
+var _56=function(_57){
+var _58=_57.parentNode;
+var i=0,_5a=_58[_8],ci=(_57["_i"]||-1),cl=(_58["_l"]||-1);
+if(!_5a){
+return -1;
+}
+var l=_5a.length;
+if(cl==l&&ci>=0&&cl>=0){
+return ci;
+}
+_58["_l"]=l;
+ci=-1;
+for(var te=_58["firstElementChild"]||_58["firstChild"];te;te=te[_ns]){
+if(_51(te)){
+te["_i"]=++i;
+if(_57===te){
+ci=i;
+}
+}
+}
+return ci;
+};
+var _5f=function(_60){
+return !((_56(_60))%2);
+};
+var _61=function(_62){
+return ((_56(_62))%2);
+};
+var _63={"checked":function(_64,_65){
+return function(_66){
+return !!d.attr(_66,"checked");
+};
+},"first-child":function(){
+return _52;
+},"last-child":function(){
+return _54;
+},"only-child":function(_67,_68){
+return function(_69){
+if(!_52(_69)){
+return false;
+}
+if(!_54(_69)){
+return false;
+}
+return true;
+};
+},"empty":function(_6a,_6b){
+return function(_6c){
+var cn=_6c.childNodes;
+var cnl=_6c.childNodes.length;
+for(var x=cnl-1;x>=0;x--){
+var nt=cn[x].nodeType;
+if((nt===1)||(nt==3)){
+return false;
+}
+}
+return true;
+};
+},"contains":function(_71,_72){
+var cz=_72.charAt(0);
+if(cz=="\""||cz=="'"){
+_72=_72.slice(1,-1);
+}
+return function(_74){
+return (_74.innerHTML.indexOf(_72)>=0);
+};
+},"not":function(_75,_76){
+var p=_c(_76)[0];
+var _78={el:1};
+if(p.tag!="*"){
+_78.tag=1;
+}
+if(!p.classes.length){
+_78.classes=1;
+}
+var ntf=_7a(p,_78);
+return function(_7b){
+return (!ntf(_7b));
+};
+},"nth-child":function(_7c,_7d){
+var pi=parseInt;
+if(_7d=="odd"){
+return _61;
+}else{
+if(_7d=="even"){
+return _5f;
+}
+}
+if(_7d.indexOf("n")!=-1){
+var _7f=_7d.split("n",2);
+var _80=_7f[0]?((_7f[0]=="-")?-1:pi(_7f[0])):1;
+var idx=_7f[1]?pi(_7f[1]):0;
+var lb=0,ub=-1;
+if(_80>0){
+if(idx<0){
+idx=(idx%_80)&&(_80+(idx%_80));
+}else{
+if(idx>0){
+if(idx>=_80){
+lb=idx-idx%_80;
+}
+idx=idx%_80;
+}
+}
+}else{
+if(_80<0){
+_80*=-1;
+if(idx>0){
+ub=idx;
+idx=idx%_80;
+}
+}
+}
+if(_80>0){
+return function(_84){
+var i=_56(_84);
+return (i>=lb)&&(ub<0||i<=ub)&&((i%_80)==idx);
+};
+}else{
+_7d=idx;
+}
+}
+var _86=pi(_7d);
+return function(_87){
+return (_56(_87)==_86);
+};
+}};
+var _88=(d.isIE)?function(_89){
+var clc=_89.toLowerCase();
+if(clc=="class"){
+_89="className";
+}
+return function(_8b){
+return (_a?_8b.getAttribute(_89):_8b[_89]||_8b[clc]);
+};
+}:function(_8c){
+return function(_8d){
+return (_8d&&_8d.getAttribute&&_8d.hasAttribute(_8c));
+};
+};
+var _7a=function(_8e,_8f){
+if(!_8e){
+return _b;
+}
+_8f=_8f||{};
+var ff=null;
+if(!("el" in _8f)){
+ff=_28(ff,_2f);
+}
+if(!("tag" in _8f)){
+if(_8e.tag!="*"){
+ff=_28(ff,function(_91){
+return (_91&&(_91.tagName==_8e.getTag()));
+});
+}
+}
+if(!("classes" in _8f)){
+_3(_8e.classes,function(_92,idx,arr){
+var re=new RegExp("(?:^|\\s)"+_92+"(?:\\s|$)");
+ff=_28(ff,function(_96){
+return re.test(_96.className);
+});
+ff.count=idx;
+});
+}
+if(!("pseudos" in _8f)){
+_3(_8e.pseudos,function(_97){
+var pn=_97.name;
+if(_63[pn]){
+ff=_28(ff,_63[pn](pn,_97.value));
+}
+});
+}
+if(!("attrs" in _8f)){
+_3(_8e.attrs,function(_99){
+var _9a;
+var a=_99.attr;
+if(_99.type&&_35[_99.type]){
+_9a=_35[_99.type](a,_99.matchFor);
+}else{
+if(a.length){
+_9a=_88(a);
+}
+}
+if(_9a){
+ff=_28(ff,_9a);
+}
+});
+}
+if(!("id" in _8f)){
+if(_8e.id){
+ff=_28(ff,function(_9c){
+return (!!_9c&&(_9c.id==_8e.id));
+});
+}
+}
+if(!ff){
+if(!("default" in _8f)){
+ff=_b;
+}
+}
+return ff;
+};
+var _9d=function(_9e){
+return function(_9f,ret,bag){
+while(_9f=_9f[_ns]){
+if(_4e&&(!_2f(_9f))){
+continue;
+}
+if((!bag||_a2(_9f,bag))&&_9e(_9f)){
+ret.push(_9f);
+}
+break;
+}
+return ret;
+};
+};
+var _a3=function(_a4){
+return function(_a5,ret,bag){
+var te=_a5[_ns];
+while(te){
+if(_51(te)){
+if(bag&&!_a2(te,bag)){
+break;
+}
+if(_a4(te)){
+ret.push(te);
+}
+}
+te=te[_ns];
+}
+return ret;
+};
+};
+var _a9=function(_aa){
+_aa=_aa||_b;
+return function(_ab,ret,bag){
+var te,x=0,_b0=_ab[_8];
+while(te=_b0[x++]){
+if(_51(te)&&(!bag||_a2(te,bag))&&(_aa(te,x))){
+ret.push(te);
+}
+}
+return ret;
+};
+};
+var _b1=function(_b2,_b3){
+var pn=_b2.parentNode;
+while(pn){
+if(pn==_b3){
+break;
+}
+pn=pn.parentNode;
+}
+return !!pn;
+};
+var _b5={};
+var _b6=function(_b7){
+var _b8=_b5[_b7.query];
+if(_b8){
+return _b8;
+}
+var io=_b7.infixOper;
+var _ba=(io?io.oper:"");
+var _bb=_7a(_b7,{el:1});
+var qt=_b7.tag;
+var _bd=("*"==qt);
+var ecs=_6()["getElementsByClassName"];
+if(!_ba){
+if(_b7.id){
+_bb=(!_b7.loops&&_bd)?_b:_7a(_b7,{el:1,id:1});
+_b8=function(_bf,arr){
+var te=d.byId(_b7.id,(_bf.ownerDocument||_bf));
+if(!te||!_bb(te)){
+return;
+}
+if(9==_bf.nodeType){
+return _2b(te,arr);
+}else{
+if(_b1(te,_bf)){
+return _2b(te,arr);
+}
+}
+};
+}else{
+if(ecs&&/\{\s*\[native code\]\s*\}/.test(String(ecs))&&_b7.classes.length&&!_7){
+_bb=_7a(_b7,{el:1,classes:1,id:1});
+var _c2=_b7.classes.join(" ");
+_b8=function(_c3,arr,bag){
+var ret=_2b(0,arr),te,x=0;
+var _c9=_c3.getElementsByClassName(_c2);
+while((te=_c9[x++])){
+if(_bb(te,_c3)&&_a2(te,bag)){
+ret.push(te);
+}
+}
+return ret;
+};
+}else{
+if(!_bd&&!_b7.loops){
+_b8=function(_ca,arr,bag){
+var ret=_2b(0,arr),te,x=0;
+var _d0=_ca.getElementsByTagName(_b7.getTag());
+while((te=_d0[x++])){
+if(_a2(te,bag)){
+ret.push(te);
+}
+}
+return ret;
+};
+}else{
+_bb=_7a(_b7,{el:1,tag:1,id:1});
+_b8=function(_d1,arr,bag){
+var ret=_2b(0,arr),te,x=0;
+var _d7=_d1.getElementsByTagName(_b7.getTag());
+while((te=_d7[x++])){
+if(_bb(te,_d1)&&_a2(te,bag)){
+ret.push(te);
+}
+}
+return ret;
+};
+}
+}
+}
+}else{
+var _d8={el:1};
+if(_bd){
+_d8.tag=1;
+}
+_bb=_7a(_b7,_d8);
+if("+"==_ba){
+_b8=_9d(_bb);
+}else{
+if("~"==_ba){
+_b8=_a3(_bb);
+}else{
+if(">"==_ba){
+_b8=_a9(_bb);
+}
+}
+}
+}
+return _b5[_b7.query]=_b8;
+};
+var _d9=function(_da,_db){
+var _dc=_2b(_da),qp,x,te,qpl=_db.length,bag,ret;
+for(var i=0;i<qpl;i++){
+ret=[];
+qp=_db[i];
+x=_dc.length-1;
+if(x>0){
+bag={};
+ret.nozip=true;
+}
+var gef=_b6(qp);
+while(te=_dc[x--]){
+gef(te,ret,bag);
+}
+if(!ret.length){
+break;
+}
+_dc=ret;
+}
+return ret;
+};
+var _e5={},_e6={};
+var _e7=function(_e8){
+var _e9=_c(_2(_e8));
+if(_e9.length==1){
+var tef=_b6(_e9[0]);
+return function(_eb){
+var r=tef(_eb,new _4());
+if(r){
+r.nozip=true;
+}
+return r;
+};
+}
+return function(_ed){
+return _d9(_ed,_e9);
+};
+};
+var nua=navigator.userAgent;
+var wk="WebKit/";
+var _f0=(d.isWebKit&&(nua.indexOf(wk)>0)&&(parseFloat(nua.split(wk)[1])>528));
+var _f1=d.isIE?"commentStrip":"nozip";
+var qsa="querySelectorAll";
+var _f3=(!!_6()[qsa]&&(!d.isSafari||(d.isSafari>3.1)||_f0));
+var _f4=function(_f5,_f6){
+if(_f3){
+var _f7=_e6[_f5];
+if(_f7&&!_f6){
+return _f7;
+}
+}
+var _f8=_e5[_f5];
+if(_f8){
+return _f8;
+}
+var qcz=_f5.charAt(0);
+var _fa=(-1==_f5.indexOf(" "));
+if((_f5.indexOf("#")>=0)&&(_fa)){
+_f6=true;
+}
+var _fb=(_f3&&(!_f6)&&(_9.indexOf(qcz)==-1)&&(!d.isIE||(_f5.indexOf(":")==-1))&&(!(_7&&(_f5.indexOf(".")>=0)))&&(_f5.indexOf(":contains")==-1)&&(_f5.indexOf("|=")==-1));
+if(_fb){
+var tq=(_9.indexOf(_f5.charAt(_f5.length-1))>=0)?(_f5+" *"):_f5;
+return _e6[_f5]=function(_fd){
+try{
+if(!((9==_fd.nodeType)||_fa)){
+throw "";
+}
+var r=_fd[qsa](tq);
+r[_f1]=true;
+return r;
+}
+catch(e){
+return _f4(_f5,true)(_fd);
+}
+};
+}else{
+var _ff=_f5.split(/\s*,\s*/);
+return _e5[_f5]=((_ff.length<2)?_e7(_f5):function(root){
+var _101=0,ret=[],tp;
+while((tp=_ff[_101++])){
+ret=ret.concat(_e7(tp)(root));
+}
+return ret;
+});
+}
+};
+var _104=0;
+var _105=d.isIE?function(node){
+if(_a){
+return (node.getAttribute("_uid")||node.setAttribute("_uid",++_104)||_104);
+}else{
+return node.uniqueID;
+}
+}:function(node){
+return (node._uid||(node._uid=++_104));
+};
+var _a2=function(node,bag){
+if(!bag){
+return 1;
+}
+var id=_105(node);
+if(!bag[id]){
+return bag[id]=1;
+}
+return 0;
+};
+var _10b="_zipIdx";
+var _zip=function(arr){
+if(arr&&arr.nozip){
+return (_4._wrap)?_4._wrap(arr):arr;
+}
+var ret=new _4();
+if(!arr||!arr.length){
+return ret;
+}
+if(arr[0]){
+ret.push(arr[0]);
+}
+if(arr.length<2){
+return ret;
+}
+_104++;
+if(d.isIE&&_a){
+var _10f=_104+"";
+arr[0].setAttribute(_10b,_10f);
+for(var x=1,te;te=arr[x];x++){
+if(arr[x].getAttribute(_10b)!=_10f){
+ret.push(te);
+}
+te.setAttribute(_10b,_10f);
+}
+}else{
+if(d.isIE&&arr.commentStrip){
+try{
+for(var x=1,te;te=arr[x];x++){
+if(_2f(te)){
+ret.push(te);
+}
+}
+}
+catch(e){
+}
+}else{
+if(arr[0]){
+arr[0][_10b]=_104;
+}
+for(var x=1,te;te=arr[x];x++){
+if(arr[x][_10b]!=_104){
+ret.push(te);
+}
+te[_10b]=_104;
+}
+}
+}
+return ret;
+};
+d.query=function(_112,root){
+_4=d._queryListCtor;
+if(!_112){
+return new _4();
+}
+if(_112.constructor==_4){
+return _112;
+}
+if(!_5(_112)){
+return new _4(_112);
+}
+if(_5(root)){
+root=d.byId(root);
+if(!root){
+return new _4();
+}
+}
+root=root||_6();
+var od=root.ownerDocument||root.documentElement;
+_a=(root.contentType&&root.contentType=="application/xml")||(d.isOpera&&(root.doctype||od.toString()=="[object XMLDocument]"))||(!!od)&&(d.isIE?od.xml:(root.xmlVersion||od.xmlVersion));
+var r=_f4(_112)(root);
+if(r&&r.nozip&&!_4._wrap){
+return r;
+}
+return _zip(r);
+};
+d.query.pseudos=_63;
+d._filterQueryResult=function(_116,_117){
+var _118=new d._queryListCtor();
+var _119=_7a(_c(_117)[0]);
+for(var x=0,te;te=_116[x];x++){
+if(_119(te)){
+_118.push(te);
+}
+}
+return _118;
+};
+})(this["queryPortability"]||this["acme"]||dojo);
+}
diff --git a/dojo/_base/window.js b/dojo/_base/window.js
new file mode 100644
index 0000000..a27d958
--- /dev/null
+++ b/dojo/_base/window.js
@@ -0,0 +1,46 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._base.window"]){
+dojo._hasResource["dojo._base.window"]=true;
+dojo.provide("dojo._base.window");
+dojo.doc=window["document"]||null;
+dojo.body=function(){
+return dojo.doc.body||dojo.doc.getElementsByTagName("body")[0];
+};
+dojo.setContext=function(_1,_2){
+dojo.global=_1;
+dojo.doc=_2;
+};
+dojo.withGlobal=function(_3,_4,_5,_6){
+var _7=dojo.global;
+try{
+dojo.global=_3;
+return dojo.withDoc.call(null,_3.document,_4,_5,_6);
+}
+finally{
+dojo.global=_7;
+}
+};
+dojo.withDoc=function(_8,_9,_a,_b){
+var _c=dojo.doc,_d=dojo._bodyLtr;
+try{
+dojo.doc=_8;
+delete dojo._bodyLtr;
+if(_a&&dojo.isString(_9)){
+_9=_a[_9];
+}
+return _9.apply(_a,_b||[]);
+}
+finally{
+dojo.doc=_c;
+if(_d!==undefined){
+dojo._bodyLtr=_d;
+}
+}
+};
+}
diff --git a/dojo/_base/xhr.js b/dojo/_base/xhr.js
new file mode 100644
index 0000000..8f739a7
--- /dev/null
+++ b/dojo/_base/xhr.js
@@ -0,0 +1,377 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._base.xhr"]){
+dojo._hasResource["dojo._base.xhr"]=true;
+dojo.provide("dojo._base.xhr");
+dojo.require("dojo._base.Deferred");
+dojo.require("dojo._base.json");
+dojo.require("dojo._base.lang");
+dojo.require("dojo._base.query");
+(function(){
+var _d=dojo;
+function _2(_3,_4,_5){
+var _6=_3[_4];
+if(_d.isString(_6)){
+_3[_4]=[_6,_5];
+}else{
+if(_d.isArray(_6)){
+_6.push(_5);
+}else{
+_3[_4]=_5;
+}
+}
+};
+dojo.formToObject=function(_7){
+var _8={};
+var _9="file|submit|image|reset|button|";
+_d.forEach(dojo.byId(_7).elements,function(_a){
+var _b=_a.name;
+var _c=(_a.type||"").toLowerCase();
+if(_b&&_c&&_9.indexOf(_c)==-1&&!_a.disabled){
+if(_c=="radio"||_c=="checkbox"){
+if(_a.checked){
+_2(_8,_b,_a.value);
+}
+}else{
+if(_a.multiple){
+_8[_b]=[];
+_d.query("option",_a).forEach(function(_d){
+if(_d.selected){
+_2(_8,_b,_d.value);
+}
+});
+}else{
+_2(_8,_b,_a.value);
+if(_c=="image"){
+_8[_b+".x"]=_8[_b+".y"]=_8[_b].x=_8[_b].y=0;
+}
+}
+}
+}
+});
+return _8;
+};
+dojo.objectToQuery=function(_e){
+var _f=encodeURIComponent;
+var _10=[];
+var _11={};
+for(var _12 in _e){
+var _13=_e[_12];
+if(_13!=_11[_12]){
+var _14=_f(_12)+"=";
+if(_d.isArray(_13)){
+for(var i=0;i<_13.length;i++){
+_10.push(_14+_f(_13[i]));
+}
+}else{
+_10.push(_14+_f(_13));
+}
+}
+}
+return _10.join("&");
+};
+dojo.formToQuery=function(_16){
+return _d.objectToQuery(_d.formToObject(_16));
+};
+dojo.formToJson=function(_17,_18){
+return _d.toJson(_d.formToObject(_17),_18);
+};
+dojo.queryToObject=function(str){
+var ret={};
+var qp=str.split("&");
+var dec=decodeURIComponent;
+_d.forEach(qp,function(_1d){
+if(_1d.length){
+var _1e=_1d.split("=");
+var _1f=dec(_1e.shift());
+var val=dec(_1e.join("="));
+if(_d.isString(ret[_1f])){
+ret[_1f]=[ret[_1f]];
+}
+if(_d.isArray(ret[_1f])){
+ret[_1f].push(val);
+}else{
+ret[_1f]=val;
+}
+}
+});
+return ret;
+};
+dojo._blockAsync=false;
+dojo._contentHandlers={text:function(xhr){
+return xhr.responseText;
+},json:function(xhr){
+return _d.fromJson(xhr.responseText||null);
+},"json-comment-filtered":function(xhr){
+if(!dojo.config.useCommentedJson){
+console.warn("Consider using the standard mimetype:application/json."+" json-commenting can introduce security issues. To"+" decrease the chances of hijacking, use the standard the 'json' handler and"+" prefix your json with: {}&&\n"+"Use djConfig.useCommentedJson=true to turn off this message.");
+}
+var _24=xhr.responseText;
+var _25=_24.indexOf("/*");
+var _26=_24.lastIndexOf("*/");
+if(_25==-1||_26==-1){
+throw new Error("JSON was not comment filtered");
+}
+return _d.fromJson(_24.substring(_25+2,_26));
+},javascript:function(xhr){
+return _d.eval(xhr.responseText);
+},xml:function(xhr){
+var _29=xhr.responseXML;
+if(_d.isIE&&(!_29||!_29.documentElement)){
+var ms=function(n){
+return "MSXML"+n+".DOMDocument";
+};
+var dp=["Microsoft.XMLDOM",ms(6),ms(4),ms(3),ms(2)];
+_d.some(dp,function(p){
+try{
+var dom=new ActiveXObject(p);
+dom.async=false;
+dom.loadXML(xhr.responseText);
+_29=dom;
+}
+catch(e){
+return false;
+}
+return true;
+});
+}
+return _29;
+}};
+dojo._contentHandlers["json-comment-optional"]=function(xhr){
+var _30=_d._contentHandlers;
+if(xhr.responseText&&xhr.responseText.indexOf("/*")!=-1){
+return _30["json-comment-filtered"](xhr);
+}else{
+return _30["json"](xhr);
+}
+};
+dojo._ioSetArgs=function(_31,_32,_33,_34){
+var _35={args:_31,url:_31.url};
+var _36=null;
+if(_31.form){
+var _37=_d.byId(_31.form);
+var _38=_37.getAttributeNode("action");
+_35.url=_35.url||(_38?_38.value:null);
+_36=_d.formToObject(_37);
+}
+var _39=[{}];
+if(_36){
+_39.push(_36);
+}
+if(_31.content){
+_39.push(_31.content);
+}
+if(_31.preventCache){
+_39.push({"dojo.preventCache":new Date().valueOf()});
+}
+_35.query=_d.objectToQuery(_d.mixin.apply(null,_39));
+_35.handleAs=_31.handleAs||"text";
+var d=new _d.Deferred(_32);
+d.addCallbacks(_33,function(_3b){
+return _34(_3b,d);
+});
+var ld=_31.load;
+if(ld&&_d.isFunction(ld)){
+d.addCallback(function(_3d){
+return ld.call(_31,_3d,_35);
+});
+}
+var err=_31.error;
+if(err&&_d.isFunction(err)){
+d.addErrback(function(_3f){
+return err.call(_31,_3f,_35);
+});
+}
+var _40=_31.handle;
+if(_40&&_d.isFunction(_40)){
+d.addBoth(function(_41){
+return _40.call(_31,_41,_35);
+});
+}
+d.ioArgs=_35;
+return d;
+};
+var _42=function(dfd){
+dfd.canceled=true;
+var xhr=dfd.ioArgs.xhr;
+var _at=typeof xhr.abort;
+if(_at=="function"||_at=="object"||_at=="unknown"){
+xhr.abort();
+}
+var err=dfd.ioArgs.error;
+if(!err){
+err=new Error("xhr cancelled");
+err.dojoType="cancel";
+}
+return err;
+};
+var _47=function(dfd){
+var ret=_d._contentHandlers[dfd.ioArgs.handleAs](dfd.ioArgs.xhr);
+return ret===undefined?null:ret;
+};
+var _4a=function(_4b,dfd){
+console.error(_4b);
+return _4b;
+};
+var _4d=null;
+var _4e=[];
+var _4f=function(){
+var now=(new Date()).getTime();
+if(!_d._blockAsync){
+for(var i=0,tif;i<_4e.length&&(tif=_4e[i]);i++){
+var dfd=tif.dfd;
+var _54=function(){
+if(!dfd||dfd.canceled||!tif.validCheck(dfd)){
+_4e.splice(i--,1);
+}else{
+if(tif.ioCheck(dfd)){
+_4e.splice(i--,1);
+tif.resHandle(dfd);
+}else{
+if(dfd.startTime){
+if(dfd.startTime+(dfd.ioArgs.args.timeout||0)<now){
+_4e.splice(i--,1);
+var err=new Error("timeout exceeded");
+err.dojoType="timeout";
+dfd.errback(err);
+dfd.cancel();
+}
+}
+}
+}
+};
+if(dojo.config.debugAtAllCosts){
+_54.call(this);
+}else{
+try{
+_54.call(this);
+}
+catch(e){
+dfd.errback(e);
+}
+}
+}
+}
+if(!_4e.length){
+clearInterval(_4d);
+_4d=null;
+return;
+}
+};
+dojo._ioCancelAll=function(){
+try{
+_d.forEach(_4e,function(i){
+try{
+i.dfd.cancel();
+}
+catch(e){
+}
+});
+}
+catch(e){
+}
+};
+if(_d.isIE){
+_d.addOnWindowUnload(_d._ioCancelAll);
+}
+_d._ioWatch=function(dfd,_58,_59,_5a){
+var _5b=dfd.ioArgs.args;
+if(_5b.timeout){
+dfd.startTime=(new Date()).getTime();
+}
+_4e.push({dfd:dfd,validCheck:_58,ioCheck:_59,resHandle:_5a});
+if(!_4d){
+_4d=setInterval(_4f,50);
+}
+if(_5b.sync){
+_4f();
+}
+};
+var _5c="application/x-www-form-urlencoded";
+var _5d=function(dfd){
+return dfd.ioArgs.xhr.readyState;
+};
+var _5f=function(dfd){
+return 4==dfd.ioArgs.xhr.readyState;
+};
+var _61=function(dfd){
+var xhr=dfd.ioArgs.xhr;
+if(_d._isDocumentOk(xhr)){
+dfd.callback(dfd);
+}else{
+var err=new Error("Unable to load "+dfd.ioArgs.url+" status:"+xhr.status);
+err.status=xhr.status;
+err.responseText=xhr.responseText;
+dfd.errback(err);
+}
+};
+dojo._ioAddQueryToUrl=function(_65){
+if(_65.query.length){
+_65.url+=(_65.url.indexOf("?")==-1?"?":"&")+_65.query;
+_65.query=null;
+}
+};
+dojo.xhr=function(_66,_67,_68){
+var dfd=_d._ioSetArgs(_67,_42,_47,_4a);
+dfd.ioArgs.xhr=_d._xhrObj(dfd.ioArgs.args);
+if(_68){
+if("postData" in _67){
+dfd.ioArgs.query=_67.postData;
+}else{
+if("putData" in _67){
+dfd.ioArgs.query=_67.putData;
+}
+}
+}else{
+_d._ioAddQueryToUrl(dfd.ioArgs);
+}
+var _6a=dfd.ioArgs;
+var xhr=_6a.xhr;
+xhr.open(_66,_6a.url,_67.sync!==true,_67.user||undefined,_67.password||undefined);
+if(_67.headers){
+for(var hdr in _67.headers){
+if(hdr.toLowerCase()==="content-type"&&!_67.contentType){
+_67.contentType=_67.headers[hdr];
+}else{
+xhr.setRequestHeader(hdr,_67.headers[hdr]);
+}
+}
+}
+xhr.setRequestHeader("Content-Type",_67.contentType||_5c);
+if(!_67.headers||!_67.headers["X-Requested-With"]){
+xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");
+}
+if(dojo.config.debugAtAllCosts){
+xhr.send(_6a.query);
+}else{
+try{
+xhr.send(_6a.query);
+}
+catch(e){
+dfd.ioArgs.error=e;
+dfd.cancel();
+}
+}
+_d._ioWatch(dfd,_5d,_5f,_61);
+xhr=null;
+return dfd;
+};
+dojo.xhrGet=function(_6d){
+return _d.xhr("GET",_6d);
+};
+dojo.rawXhrPost=dojo.xhrPost=function(_6e){
+return _d.xhr("POST",_6e,true);
+};
+dojo.rawXhrPut=dojo.xhrPut=function(_6f){
+return _d.xhr("PUT",_6f,true);
+};
+dojo.xhrDelete=function(_70){
+return _d.xhr("DELETE",_70);
+};
+})();
+}
diff --git a/dojo/_firebug/LICENSE b/dojo/_firebug/LICENSE
new file mode 100644
index 0000000..8c777a2
--- /dev/null
+++ b/dojo/_firebug/LICENSE
@@ -0,0 +1,37 @@
+License Disclaimer:
+
+All contents of this directory are Copyright (c) the Dojo Foundation, with the
+following exceptions:
+-------------------------------------------------------------------------------
+
+firebug.html, firebug.js, errIcon.png, infoIcon.png, warningIcon.png:
+	* Copyright (c) 2006-2007, Joe Hewitt, All rights reserved.
+	  Distributed under the terms of the BSD License (see below)
+
+-------------------------------------------------------------------------------
+
+Copyright (c) 2006-2007, Joe Hewitt
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice, this
+	list of conditions and the following disclaimer.
+  * Redistributions in binary form must reproduce the above copyright notice,
+	this list of conditions and the following disclaimer in the documentation
+	and/or other materials provided with the distribution.
+  * Neither the name of the Dojo Foundation nor the names of its contributors
+	may be used to endorse or promote products derived from this software
+	without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/dojo/_firebug/errorIcon.png b/dojo/_firebug/errorIcon.png
new file mode 100644
index 0000000..2d75261
Binary files /dev/null and b/dojo/_firebug/errorIcon.png differ
diff --git a/dojo/_firebug/firebug.css b/dojo/_firebug/firebug.css
new file mode 100644
index 0000000..3b6f4f9
--- /dev/null
+++ b/dojo/_firebug/firebug.css
@@ -0,0 +1,208 @@
+.firebug {
+	margin: 0;
+	background:#fff;
+	font-family: Lucida Grande, Tahoma, sans-serif;
+	font-size: 11px;
+	overflow: hidden;
+	border: 1px solid black;
+	position: relative;
+}
+.firebug a {
+	text-decoration: none;
+}
+.firebug a:hover {
+	text-decoration: underline;
+}
+.firebug a:visited{
+	color:#0000FF;
+}
+.firebug #firebugToolbar {
+	height: 18px;
+	line-height:18px;
+	border-top: 1px solid ThreeDHighlight;
+	border-bottom: 1px solid ThreeDShadow;
+	padding: 2px 6px;
+	
+	background:#f0f0f0;
+}
+.firebug #firebugLog, .firebug #objectLog {
+	overflow: auto;
+	position: absolute;
+	left: 0;
+	width: 100%;
+}
+#objectLog{
+	overflow:scroll;
+	height:258px;
+}
+.firebug #firebugCommandLine {
+	position: absolute;
+	bottom: 0;
+	left: 0;
+	width: 100%;
+	height: 18px;
+	border: none;
+	border-top: 1px solid ThreeDShadow;
+}
+.firebug .logRow {
+	position: relative;
+	border-bottom: 1px solid #D7D7D7;
+	padding: 2px 4px 1px 6px;
+	background-color: #FFFFFF;
+}
+.firebug .logRow-command {
+	font-family: Monaco, monospace;
+	color: blue;
+}
+.firebug .objectBox-null {
+	padding: 0 2px;
+	border: 1px solid #666666;
+	background-color: #888888;
+	color: #FFFFFF;
+}
+.firebug .objectBox-string {
+	font-family: Monaco, monospace;
+	color: red;
+	white-space: pre;
+}
+.firebug .objectBox-number {
+	color: #000088;
+}
+.firebug .objectBox-function {
+	font-family: Monaco, monospace;
+	color: DarkGreen;
+}
+.firebug .objectBox-object {
+	color: DarkGreen;
+	font-weight: bold;
+}
+.firebug .logRow-info,
+.firebug .logRow-error,
+.firebug .logRow-warning
+ {
+	background: #00FFFF no-repeat 2px 2px;
+	padding-left: 20px;
+	padding-bottom: 3px;
+}
+.firebug .logRow-info {
+	background: #FFF url(infoIcon.png) no-repeat 2px 2px;
+	padding-left: 20px;
+	padding-bottom: 3px;
+}
+.firebug .logRow-warning {
+	
+	background: #00FFFF url(warningIcon.png) no-repeat 2px 2px;
+	padding-left: 20px;
+	padding-bottom: 3px;
+}
+.firebug .logRow-error {
+	background: LightYellow url(errorIcon.png) no-repeat 2px 2px;
+	padding-left: 20px;
+	padding-bottom: 3px;
+}
+.firebug .errorMessage {
+	vertical-align: top;
+	color: #FF0000;
+}
+.firebug .objectBox-sourceLink {
+	position: absolute;
+	right: 4px;
+	top: 2px;
+	padding-left: 8px;
+	font-family: Lucida Grande, sans-serif;
+	font-weight: bold;
+	color: #0000FF;
+}
+.firebug .logRow-group {
+	background: #EEEEEE;
+	border-bottom: none;
+}
+.firebug .logGroup {
+	background: #EEEEEE;
+}
+.firebug .logGroupBox {
+	margin-left: 24px;
+	border-top: 1px solid #D7D7D7;
+	border-left: 1px solid #D7D7D7;
+}
+.firebug .selectorTag,
+.firebug .selectorId,
+.firebug .selectorClass {
+	font-family: Monaco, monospace;
+	font-weight: normal;
+}
+.firebug .selectorTag {
+	color: #0000FF;
+}
+.firebug .selectorId {
+	color: DarkBlue;
+}
+.firebug .selectorClass {
+	color: red;
+}
+.firebug .objectBox-element {
+	font-family: Monaco, monospace;
+	color: #000088;
+}
+.firebug .nodeChildren {
+	margin-left: 16px;
+}
+.firebug .nodeTag {
+	color: blue;
+}
+.firebug .nodeValue {
+	color: #FF0000;
+	font-weight: normal;
+}
+.firebug .nodeText,
+.firebug .nodeComment {
+	margin: 0 2px;
+	vertical-align: top;
+}
+.firebug .nodeText {
+	color: #333333;
+}
+.firebug .nodeComment {
+	color: DarkGreen;
+}
+.firebug .propertyNameCell {
+	vertical-align: top;
+}
+.firebug .propertyName {
+	font-weight: bold;
+}
+#firebugToolbar ul.tabs{
+	margin:0 !important;
+	padding:0;
+}
+#firebugToolbar ul.tabs li{
+	list-style:none;
+	background:transparent url(tab_lft_norm.png) no-repeat left;
+	line-height:18px;
+	float:left;
+	margin-left:5px;
+}
+#firebugToolbar ul.tabs li.right{
+	float:right;
+	margin-right:5px;
+	margin-left:0;
+}
+#firebugToolbar ul.tabs li.gap{
+	margin-left:20px;
+}
+#firebugToolbar .tabs a{
+	text-decoration:none;
+	background:transparent url(tab_rgt_norm.png) no-repeat right;
+	line-height:18px;
+	padding:3px 9px 4px 0px;
+	margin-left:9px;
+	color:#333333;
+}
+#firebugToolbar .tabs li:hover{
+	background:transparent url(tab_lft_over.png) no-repeat left;
+}
+#firebugToolbar .tabs a:hover{
+	text-decoration:none;
+	background:transparent url(tab_rgt_over.png) no-repeat right;
+	color:#FFFFFF;
+}
diff --git a/dojo/_firebug/firebug.js b/dojo/_firebug/firebug.js
new file mode 100644
index 0000000..0700287
--- /dev/null
+++ b/dojo/_firebug/firebug.js
@@ -0,0 +1,894 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo._firebug.firebug"]){
+dojo._hasResource["dojo._firebug.firebug"]=true;
+dojo.provide("dojo._firebug.firebug");
+dojo.deprecated=function(_1,_2,_3){
+var _4="DEPRECATED: "+_1;
+if(_2){
+_4+=" "+_2;
+}
+if(_3){
+_4+=" -- will be removed in version: "+_3;
+}
+console.warn(_4);
+};
+dojo.experimental=function(_5,_6){
+var _7="EXPERIMENTAL: "+_5+" -- APIs subject to change without notice.";
+if(_6){
+_7+=" "+_6;
+}
+console.warn(_7);
+};
+if(!window.firebug&&!dojo.config.useCustomLogger&&!dojo.isAIR&&(!dojo.isMoz||(dojo.isMoz&&!("console" in window))||(dojo.isMoz&&!(window.loadFirebugConsole||console.firebug)))){
+(function(){
+try{
+if(window!=window.parent){
+if(window.parent["console"]){
+window.console=window.parent.console;
+}
+return;
+}
+}
+catch(e){
+}
+var _8=document;
+var _9=window;
+var _a=0;
+var _b=null;
+var _c=null;
+var _d=null;
+var _e=null;
+var _f=null;
+var _10=null;
+var _11=false;
+var _12=[];
+var _13=[];
+var _14={};
+var _15={};
+var _16=null;
+var _17;
+var _18;
+var _19=false;
+var _1a=null;
+var _1b=document.createElement("div");
+var _1c;
+var _1d;
+window.console={_connects:[],log:function(){
+_1e(arguments,"");
+},debug:function(){
+_1e(arguments,"debug");
+},info:function(){
+_1e(arguments,"info");
+},warn:function(){
+_1e(arguments,"warning");
+},error:function(){
+_1e(arguments,"error");
+},assert:function(_1f,_20){
+if(!_1f){
+var _21=[];
+for(var i=1;i<arguments.length;++i){
+_21.push(arguments[i]);
+}
+_1e(_21.length?_21:["Assertion Failure"],"error");
+throw _20?_20:"Assertion Failure";
+}
+},dir:function(obj){
+var str=_25(obj);
+str=str.replace(/\n/g,"<br />");
+str=str.replace(/\t/g,"    ");
+_26([str],"dir");
+},dirxml:function(_27){
+var _28=[];
+_29(_27,_28);
+_26(_28,"dirxml");
+},group:function(){
+_26(arguments,"group",_2a);
+},groupEnd:function(){
+_26(arguments,"",_2b);
+},time:function(_2c){
+_14[_2c]=new Date().getTime();
+},timeEnd:function(_2d){
+if(_2d in _14){
+var _2e=(new Date()).getTime()-_14[_2d];
+_1e([_2d+":",_2e+"ms"]);
+delete _14[_2d];
+}
+},count:function(_2f){
+if(!_15[_2f]){
+_15[_2f]=0;
+}
+_15[_2f]++;
+_1e([_2f+": "+_15[_2f]]);
+},trace:function(_30){
+var _31=_30||3;
+var f=console.trace.caller;
+
+for(var i=0;i<_31;i++){
+var _34=f.toString();
+var _35=[];
+for(var a=0;a<f.arguments.length;a++){
+_35.push(f.arguments[a]);
+}
+if(f.arguments.length){
+
+}else{
+
+}
+f=f.caller;
+}
+},profile:function(){
+this.warn(["profile() not supported."]);
+},profileEnd:function(){
+},clear:function(){
+if(_c){
+while(_c.childNodes.length){
+dojo.destroy(_c.firstChild);
+}
+}
+dojo.forEach(this._connects,dojo.disconnect);
+},open:function(){
+_37(true);
+},close:function(){
+if(_11){
+_37();
+}
+},_restoreBorder:function(){
+if(_1c){
+_1c.style.border=_1d;
+}
+},openDomInspector:function(){
+_19=true;
+_c.style.display="none";
+_16.style.display="block";
+_d.style.display="none";
+document.body.style.cursor="pointer";
+_17=dojo.connect(document,"mousemove",function(evt){
+if(!_19){
+return;
+}
+if(!_1a){
+_1a=setTimeout(function(){
+_1a=null;
+},50);
+}else{
+return;
+}
+var _39=evt.target;
+if(_39&&(_1c!==_39)){
+var _3a=true;
+console._restoreBorder();
+var _3b=[];
+_29(_39,_3b);
+_16.innerHTML=_3b.join("");
+_1c=_39;
+_1d=_1c.style.border;
+_1c.style.border="#0000FF 1px solid";
+}
+});
+setTimeout(function(){
+_18=dojo.connect(document,"click",function(evt){
+document.body.style.cursor="";
+_19=!_19;
+dojo.disconnect(_18);
+});
+},30);
+},_closeDomInspector:function(){
+document.body.style.cursor="";
+dojo.disconnect(_17);
+dojo.disconnect(_18);
+_19=false;
+console._restoreBorder();
+},openConsole:function(){
+_c.style.display="block";
+_16.style.display="none";
+_d.style.display="none";
+console._closeDomInspector();
+},openObjectInspector:function(){
+_c.style.display="none";
+_16.style.display="none";
+_d.style.display="block";
+console._closeDomInspector();
+},recss:function(){
+var i,a,s;
+a=document.getElementsByTagName("link");
+for(i=0;i<a.length;i++){
+s=a[i];
+if(s.rel.toLowerCase().indexOf("stylesheet")>=0&&s.href){
+var h=s.href.replace(/(&|%5C?)forceReload=\d+/,"");
+s.href=h+(h.indexOf("?")>=0?"&":"?")+"forceReload="+new Date().valueOf();
+}
+}
+}};
+function _37(_41){
+_11=_41||!_11;
+if(_b){
+_b.style.display=_11?"block":"none";
+}
+};
+function _42(){
+_37(true);
+if(_f){
+_f.focus();
+}
+};
+function _43(x,y,w,h){
+var win=window.open("","_firebug","status=0,menubar=0,resizable=1,top="+y+",left="+x+",width="+w+",height="+h+",scrollbars=1,addressbar=0");
+if(!win){
+var msg="Firebug Lite could not open a pop-up window, most likely because of a blocker.\n"+"Either enable pop-ups for this domain, or change the djConfig to popup=false.";
+alert(msg);
+}
+_4a(win);
+var _4b=win.document;
+var _4c="<html style=\"height:100%;\"><head><title>Firebug Lite</title></head>\n"+"<body bgColor=\"#ccc\" style=\"height:97%;\" onresize=\"opener.onFirebugResize()\">\n"+"<div id=\"fb\"></div>"+"</body></html>";
+_4b.write(_4c);
+_4b.close();
+return win;
+};
+function _4a(wn){
+var d=new Date();
+d.setTime(d.getTime()+(60*24*60*60*1000));
+d=d.toUTCString();
+var dc=wn.document,_50;
+if(wn.innerWidth){
+_50=function(){
+return {w:wn.innerWidth,h:wn.innerHeight};
+};
+}else{
+if(dc.documentElement&&dc.documentElement.clientWidth){
+_50=function(){
+return {w:dc.documentElement.clientWidth,h:dc.documentElement.clientHeight};
+};
+}else{
+if(dc.body){
+_50=function(){
+return {w:dc.body.clientWidth,h:dc.body.clientHeight};
+};
+}
+}
+}
+window.onFirebugResize=function(){
+layout(_50().h);
+clearInterval(wn._firebugWin_resize);
+wn._firebugWin_resize=setTimeout(function(){
+var x=wn.screenLeft,y=wn.screenTop,w=wn.outerWidth||wn.document.body.offsetWidth,h=wn.outerHeight||wn.document.body.offsetHeight;
+document.cookie="_firebugPosition="+[x,y,w,h].join(",")+"; expires="+d+"; path=/";
+},5000);
+};
+};
+function _55(){
+if(_b){
+return;
+}
+if(dojo.config.popup){
+var _56="100%";
+var _57=document.cookie.match(/(?:^|; )_firebugPosition=([^;]*)/);
+var p=_57?_57[1].split(","):[2,2,320,480];
+_9=_43(p[0],p[1],p[2],p[3]);
+_8=_9.document;
+dojo.config.debugContainerId="fb";
+_9.console=window.console;
+_9.dojo=window.dojo;
+}else{
+_8=document;
+_56=(dojo.config.debugHeight||300)+"px";
+}
+var _59=_8.createElement("link");
+_59.href=dojo.moduleUrl("dojo._firebug","firebug.css");
+_59.rel="stylesheet";
+_59.type="text/css";
+var _5a=_8.getElementsByTagName("head");
+if(_5a){
+_5a=_5a[0];
+}
+if(!_5a){
+_5a=_8.getElementsByTagName("html")[0];
+}
+if(dojo.isIE){
+window.setTimeout(function(){
+_5a.appendChild(_59);
+},0);
+}else{
+_5a.appendChild(_59);
+}
+if(dojo.config.debugContainerId){
+_b=_8.getElementById(dojo.config.debugContainerId);
+}
+if(!_b){
+_b=_8.createElement("div");
+_8.body.appendChild(_b);
+}
+_b.className+=" firebug";
+_b.style.height=_56;
+_b.style.display=(_11?"block":"none");
+var _5b=function(_5c,_5d,_5e,_5f){
+return "<li class=\""+_5f+"\"><a href=\"javascript:void(0);\" onclick=\"console."+_5e+"(); return false;\" title=\""+_5d+"\">"+_5c+"</a></li>";
+};
+_b.innerHTML="<div id=\"firebugToolbar\">"+"  <ul id=\"fireBugTabs\" class=\"tabs\">"+_5b("Clear","Remove All Console Logs","clear","")+_5b("ReCSS","Refresh CSS without reloading page","recss","")+_5b("Console","Show Console Logs","openConsole","gap")+_5b("DOM","Show DOM Inspector","openDomInspector","")+_5b("Object","Show Object Inspector","openObjectInspector","")+((dojo.config.popup)?"":_5b("Close","Close the console","close","gap"))+"\t</ul>"+"</div>"+"<input type=\"text\" id=\"fireb [...]
+_10=_8.getElementById("firebugToolbar");
+_f=_8.getElementById("firebugCommandLine");
+_60(_f,"keydown",_61);
+_60(_8,dojo.isIE||dojo.isSafari?"keydown":"keypress",_62);
+_c=_8.getElementById("firebugLog");
+_d=_8.getElementById("objectLog");
+_16=_8.getElementById("domInspect");
+_e=_8.getElementById("fireBugTabs");
+_63();
+_64();
+};
+dojo.addOnLoad(_55);
+function _65(){
+_8=null;
+if(_9.console){
+_9.console.clear();
+}
+_9=null;
+_b=null;
+_c=null;
+_d=null;
+_16=null;
+_f=null;
+_12=[];
+_13=[];
+_14={};
+};
+function _66(){
+var _67=_f.value;
+_f.value="";
+_26([">  ",_67],"command");
+var _68;
+try{
+_68=eval(_67);
+}
+catch(e){
+
+}
+
+};
+function _63(h){
+var _6a=25;
+var _6b=h?h-(_6a+_f.offsetHeight+25+(h*0.01))+"px":(_b.offsetHeight-_6a-_f.offsetHeight)+"px";
+_c.style.top=_6a+"px";
+_c.style.height=_6b;
+_d.style.height=_6b;
+_d.style.top=_6a+"px";
+_16.style.height=_6b;
+_16.style.top=_6a+"px";
+_f.style.bottom=0;
+dojo.connect(window,"onunload",_65);
+};
+function _26(_6c,_6d,_6e){
+if(_c){
+_6f(_6c,_6d,_6e);
+}else{
+_12.push([_6c,_6d,_6e]);
+}
+};
+function _64(){
+var _70=_12;
+_12=[];
+for(var i=0;i<_70.length;++i){
+_6f(_70[i][0],_70[i][1],_70[i][2]);
+}
+};
+function _6f(_72,_73,_74){
+var _75=_c.scrollTop+_c.offsetHeight>=_c.scrollHeight;
+_74=_74||_76;
+_74(_72,_73);
+if(_75){
+_c.scrollTop=_c.scrollHeight-_c.offsetHeight;
+}
+};
+function _77(row){
+var _79=_13.length?_13[_13.length-1]:_c;
+_79.appendChild(row);
+};
+function _76(_7a,_7b){
+var row=_c.ownerDocument.createElement("div");
+row.className="logRow"+(_7b?" logRow-"+_7b:"");
+row.innerHTML=_7a.join("");
+_77(row);
+};
+function _2a(_7d,_7e){
+_1e(_7d,_7e);
+var _7f=_c.ownerDocument.createElement("div");
+_7f.className="logGroupBox";
+_77(_7f);
+_13.push(_7f);
+};
+function _2b(){
+_13.pop();
+};
+function _1e(_80,_81){
+var _82=[];
+var _83=_80[0];
+var _84=0;
+if(typeof (_83)!="string"){
+_83="";
+_84=-1;
+}
+var _85=_86(_83);
+for(var i=0;i<_85.length;++i){
+var _88=_85[i];
+if(_88&&typeof _88=="object"){
+_88.appender(_80[++_84],_82);
+}else{
+_89(_88,_82);
+}
+}
+var ids=[];
+var obs=[];
+for(i=_84+1;i<_80.length;++i){
+_89(" ",_82);
+var _8c=_80[i];
+if(_8c===undefined||_8c===null){
+_8d(_8c,_82);
+}else{
+if(typeof (_8c)=="string"){
+_89(_8c,_82);
+}else{
+if(_8c instanceof Date){
+_89(_8c.toString(),_82);
+}else{
+if(_8c.nodeType==9){
+_89("[ XmlDoc ]",_82);
+}else{
+var id="_a"+_a++;
+ids.push(id);
+obs.push(_8c);
+var str="<a id=\""+id+"\" href=\"javascript:void(0);\">"+_90(_8c)+"</a>";
+_91(str,_82);
+}
+}
+}
+}
+}
+_26(_82,_81);
+for(i=0;i<ids.length;i++){
+var btn=_8.getElementById(ids[i]);
+if(!btn){
+continue;
+}
+btn.obj=obs[i];
+_9.console._connects.push(dojo.connect(btn,"onclick",function(){
+console.openObjectInspector();
+try{
+_25(this.obj);
+}
+catch(e){
+this.obj=e;
+}
+_d.innerHTML="<pre>"+_25(this.obj)+"</pre>";
+}));
+}
+};
+function _86(_93){
+var _94=[];
+var reg=/((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
+var _96={s:_89,d:_97,i:_97,f:_98};
+for(var m=reg.exec(_93);m;m=reg.exec(_93)){
+var _9a=m[8]?m[8]:m[5];
+var _9b=_9a in _96?_96[_9a]:_9c;
+var _9d=m[3]?parseInt(m[3]):(m[4]=="."?-1:0);
+_94.push(_93.substr(0,m[0][0]=="%"?m.index:m.index+1));
+_94.push({appender:_9b,precision:_9d});
+_93=_93.substr(m.index+m[0].length);
+}
+_94.push(_93);
+return _94;
+};
+function _9e(_9f){
+function _a0(ch){
+switch(ch){
+case "<":
+return "<";
+case ">":
+return ">";
+case "&":
+return "&";
+case "'":
+return "'";
+case "\"":
+return """;
+}
+return "?";
+};
+return String(_9f).replace(/[<>&"']/g,_a0);
+};
+function _a2(_a3){
+try{
+return _a3+"";
+}
+catch(e){
+return null;
+}
+};
+function _91(_a4,_a5){
+_a5.push(_a2(_a4));
+};
+function _89(_a6,_a7){
+_a7.push(_9e(_a2(_a6)));
+};
+function _8d(_a8,_a9){
+_a9.push("<span class=\"objectBox-null\">",_9e(_a2(_a8)),"</span>");
+};
+function _aa(_ab,_ac){
+_ac.push("<span class=\"objectBox-string\">"",_9e(_a2(_ab)),""</span>");
+};
+function _97(_ad,_ae){
+_ae.push("<span class=\"objectBox-number\">",_9e(_a2(_ad)),"</span>");
+};
+function _98(_af,_b0){
+_b0.push("<span class=\"objectBox-number\">",_9e(_a2(_af)),"</span>");
+};
+function _b1(_b2,_b3){
+_b3.push("<span class=\"objectBox-function\">",_90(_b2),"</span>");
+};
+function _9c(_b4,_b5){
+try{
+if(_b4===undefined){
+_8d("undefined",_b5);
+}else{
+if(_b4===null){
+_8d("null",_b5);
+}else{
+if(typeof _b4=="string"){
+_aa(_b4,_b5);
+}else{
+if(typeof _b4=="number"){
+_97(_b4,_b5);
+}else{
+if(typeof _b4=="function"){
+_b1(_b4,_b5);
+}else{
+if(_b4.nodeType==1){
+_b6(_b4,_b5);
+}else{
+if(typeof _b4=="object"){
+_b7(_b4,_b5);
+}else{
+_89(_b4,_b5);
+}
+}
+}
+}
+}
+}
+}
+}
+catch(e){
+}
+};
+function _b7(_b8,_b9){
+var _ba=_a2(_b8);
+var _bb=/\[object (.*?)\]/;
+var m=_bb.exec(_ba);
+_b9.push("<span class=\"objectBox-object\">",m?m[1]:_ba,"</span>");
+};
+function _b6(_bd,_be){
+_be.push("<span class=\"objectBox-selector\">");
+_be.push("<span class=\"selectorTag\">",_9e(_bd.nodeName.toLowerCase()),"</span>");
+if(_bd.id){
+_be.push("<span class=\"selectorId\">#",_9e(_bd.id),"</span>");
+}
+if(_bd.className){
+_be.push("<span class=\"selectorClass\">.",_9e(_bd.className),"</span>");
+}
+_be.push("</span>");
+};
+function _29(_bf,_c0){
+if(_bf.nodeType==1){
+_c0.push("<div class=\"objectBox-element\">","<<span class=\"nodeTag\">",_bf.nodeName.toLowerCase(),"</span>");
+for(var i=0;i<_bf.attributes.length;++i){
+var _c2=_bf.attributes[i];
+if(!_c2.specified){
+continue;
+}
+_c0.push(" <span class=\"nodeName\">",_c2.nodeName.toLowerCase(),"</span>="<span class=\"nodeValue\">",_9e(_c2.nodeValue),"</span>"");
+}
+if(_bf.firstChild){
+_c0.push("></div><div class=\"nodeChildren\">");
+for(var _c3=_bf.firstChild;_c3;_c3=_c3.nextSibling){
+_29(_c3,_c0);
+}
+_c0.push("</div><div class=\"objectBox-element\"></<span class=\"nodeTag\">",_bf.nodeName.toLowerCase(),"></span></div>");
+}else{
+_c0.push("/></div>");
+}
+}else{
+if(_bf.nodeType==3){
+_c0.push("<div class=\"nodeText\">",_9e(_bf.nodeValue),"</div>");
+}
+}
+};
+function _60(_c4,_c5,_c6){
+if(document.all){
+_c4.attachEvent("on"+_c5,_c6);
+}else{
+_c4.addEventListener(_c5,_c6,false);
+}
+};
+function _c7(_c8,_c9,_ca){
+if(document.all){
+_c8.detachEvent("on"+_c9,_ca);
+}else{
+_c8.removeEventListener(_c9,_ca,false);
+}
+};
+function _cb(_cc){
+if(document.all){
+_cc.cancelBubble=true;
+}else{
+_cc.stopPropagation();
+}
+};
+function _cd(msg,_cf,_d0){
+var _d1=_cf.lastIndexOf("/");
+var _d2=_d1==-1?_cf:_cf.substr(_d1+1);
+var _d3=["<span class=\"errorMessage\">",msg,"</span>","<div class=\"objectBox-sourceLink\">",_d2," (line ",_d0,")</div>"];
+_26(_d3,"error");
+};
+var _d4=new Date().getTime();
+function _62(_d5){
+var _d6=(new Date()).getTime();
+if(_d6>_d4+200){
+_d5=dojo.fixEvent(_d5);
+var _d7=dojo.keys;
+var ekc=_d5.keyCode;
+_d4=_d6;
+if(ekc==_d7.F12){
+_37();
+}else{
+if((ekc==_d7.NUMPAD_ENTER||ekc==76)&&_d5.shiftKey&&(_d5.metaKey||_d5.ctrlKey)){
+_42();
+}else{
+return;
+}
+}
+_cb(_d5);
+}
+};
+function _61(e){
+var dk=dojo.keys;
+if(e.keyCode==13&&_f.value){
+_db(_f.value);
+_66();
+}else{
+if(e.keyCode==27){
+_f.value="";
+}else{
+if(e.keyCode==dk.UP_ARROW||e.charCode==dk.UP_ARROW){
+_dc("older");
+}else{
+if(e.keyCode==dk.DOWN_ARROW||e.charCode==dk.DOWN_ARROW){
+_dc("newer");
+}else{
+if(e.keyCode==dk.HOME||e.charCode==dk.HOME){
+_dd=1;
+_dc("older");
+}else{
+if(e.keyCode==dk.END||e.charCode==dk.END){
+_dd=999999;
+_dc("newer");
+}
+}
+}
+}
+}
+}
+};
+var _dd=-1;
+var _de=null;
+function _db(_df){
+var _e0=_e1("firebug_history");
+_e0=(_e0)?dojo.fromJson(_e0):[];
+var pos=dojo.indexOf(_e0,_df);
+if(pos!=-1){
+_e0.splice(pos,1);
+}
+_e0.push(_df);
+_e1("firebug_history",dojo.toJson(_e0),30);
+while(_e0.length&&!_e1("firebug_history")){
+_e0.shift();
+_e1("firebug_history",dojo.toJson(_e0),30);
+}
+_de=null;
+_dd=-1;
+};
+function _dc(_e3){
+var _e4=_e1("firebug_history");
+_e4=(_e4)?dojo.fromJson(_e4):[];
+if(!_e4.length){
+return;
+}
+if(_de===null){
+_de=_f.value;
+}
+if(_dd==-1){
+_dd=_e4.length;
+}
+if(_e3=="older"){
+--_dd;
+if(_dd<0){
+_dd=0;
+}
+}else{
+if(_e3=="newer"){
+++_dd;
+if(_dd>_e4.length){
+_dd=_e4.length;
+}
+}
+}
+if(_dd==_e4.length){
+_f.value=_de;
+_de=null;
+}else{
+_f.value=_e4[_dd];
+}
+};
+function _e1(_e5,_e6){
+var c=document.cookie;
+if(arguments.length==1){
+var _e8=c.match(new RegExp("(?:^|; )"+_e5+"=([^;]*)"));
+return _e8?decodeURIComponent(_e8[1]):undefined;
+}else{
+var d=new Date();
+d.setMonth(d.getMonth()+1);
+document.cookie=_e5+"="+encodeURIComponent(_e6)+((d.toUtcString)?"; expires="+d.toUTCString():"");
+}
+};
+function _ea(it){
+return it&&it instanceof Array||typeof it=="array";
+};
+function _ec(o){
+var cnt=0;
+for(var nm in o){
+cnt++;
+}
+return cnt;
+};
+function _25(o,i,txt,_f3){
+var ind=" \t";
+txt=txt||"";
+i=i||ind;
+_f3=_f3||[];
+var _f5;
+if(o&&o.nodeType==1){
+var _f6=[];
+_29(o,_f6);
+return _f6.join("");
+}
+var br=",\n",cnt=0,_f9=_ec(o);
+if(o instanceof Date){
+return i+o.toString()+br;
+}
+looking:
+for(var nm in o){
+cnt++;
+if(cnt==_f9){
+br="\n";
+}
+if(o[nm]===window||o[nm]===document){
+continue;
+}else{
+if(o[nm]===null){
+txt+=i+nm+" : NULL"+br;
+}else{
+if(o[nm]&&o[nm].nodeType){
+if(o[nm].nodeType==1){
+}else{
+if(o[nm].nodeType==3){
+txt+=i+nm+" : [ TextNode "+o[nm].data+" ]"+br;
+}
+}
+}else{
+if(typeof o[nm]=="object"&&(o[nm] instanceof String||o[nm] instanceof Number||o[nm] instanceof Boolean)){
+txt+=i+nm+" : "+o[nm]+","+br;
+}else{
+if(o[nm] instanceof Date){
+txt+=i+nm+" : "+o[nm].toString()+br;
+}else{
+if(typeof (o[nm])=="object"&&o[nm]){
+for(var j=0,_fc;_fc=_f3[j];j++){
+if(o[nm]===_fc){
+txt+=i+nm+" : RECURSION"+br;
+continue looking;
+}
+}
+_f3.push(o[nm]);
+_f5=(_ea(o[nm]))?["[","]"]:["{","}"];
+txt+=i+nm+" : "+_f5[0]+"\n";
+txt+=_25(o[nm],i+ind,"",_f3);
+txt+=i+_f5[1]+br;
+}else{
+if(typeof o[nm]=="undefined"){
+txt+=i+nm+" : undefined"+br;
+}else{
+if(nm=="toString"&&typeof o[nm]=="function"){
+var _fd=o[nm]();
+if(typeof _fd=="string"&&_fd.match(/function ?(.*?)\(/)){
+_fd=_9e(_90(o[nm]));
+}
+txt+=i+nm+" : "+_fd+br;
+}else{
+txt+=i+nm+" : "+_9e(_90(o[nm]))+br;
+}
+}
+}
+}
+}
+}
+}
+}
+}
+return txt;
+};
+function _90(obj){
+var _ff=(obj instanceof Error);
+if(obj.nodeType==1){
+return _9e("< "+obj.tagName.toLowerCase()+" id=\""+obj.id+"\" />");
+}
+if(obj.nodeType==3){
+return _9e("[TextNode: \""+obj.nodeValue+"\"]");
+}
+var nm=(obj&&(obj.id||obj.name||obj.ObjectID||obj.widgetId));
+if(!_ff&&nm){
+return "{"+nm+"}";
+}
+var _101=2;
+var _102=4;
+var cnt=0;
+if(_ff){
+nm="[ Error: "+(obj.message||obj.description||obj)+" ]";
+}else{
+if(_ea(obj)){
+nm="["+obj.slice(0,_102).join(",");
+if(obj.length>_102){
+nm+=" ... ("+obj.length+" items)";
+}
+nm+="]";
+}else{
+if(typeof obj=="function"){
+nm=obj+"";
+var reg=/function\s*([^\(]*)(\([^\)]*\))[^\{]*\{/;
+var m=reg.exec(nm);
+if(m){
+if(!m[1]){
+m[1]="function";
+}
+nm=m[1]+m[2];
+}else{
+nm="function()";
+}
+}else{
+if(typeof obj!="object"||typeof obj=="string"){
+nm=obj+"";
+}else{
+nm="{";
+for(var i in obj){
+cnt++;
+if(cnt>_101){
+break;
+}
+nm+=i+":"+_9e(obj[i])+"  ";
+}
+nm+="}";
+}
+}
+}
+}
+return nm;
+};
+_60(document,dojo.isIE||dojo.isSafari?"keydown":"keypress",_62);
+if((document.documentElement.getAttribute("debug")=="true")||(dojo.config.isDebug)){
+_37(true);
+}
+})();
+}
+}
diff --git a/dojo/_firebug/infoIcon.png b/dojo/_firebug/infoIcon.png
new file mode 100644
index 0000000..da1e533
Binary files /dev/null and b/dojo/_firebug/infoIcon.png differ
diff --git a/dojo/_firebug/tab_lft_norm.png b/dojo/_firebug/tab_lft_norm.png
new file mode 100644
index 0000000..f0479a2
Binary files /dev/null and b/dojo/_firebug/tab_lft_norm.png differ
diff --git a/dojo/_firebug/tab_lft_over.png b/dojo/_firebug/tab_lft_over.png
new file mode 100644
index 0000000..2f36cca
Binary files /dev/null and b/dojo/_firebug/tab_lft_over.png differ
diff --git a/dojo/_firebug/tab_rgt_norm.png b/dojo/_firebug/tab_rgt_norm.png
new file mode 100644
index 0000000..464af3e
Binary files /dev/null and b/dojo/_firebug/tab_rgt_norm.png differ
diff --git a/dojo/_firebug/tab_rgt_over.png b/dojo/_firebug/tab_rgt_over.png
new file mode 100644
index 0000000..2bc2cd0
Binary files /dev/null and b/dojo/_firebug/tab_rgt_over.png differ
diff --git a/dojo/_firebug/warningIcon.png b/dojo/_firebug/warningIcon.png
new file mode 100644
index 0000000..de51084
Binary files /dev/null and b/dojo/_firebug/warningIcon.png differ
diff --git a/dojo/back.js b/dojo/back.js
new file mode 100644
index 0000000..51eb86d
--- /dev/null
+++ b/dojo/back.js
@@ -0,0 +1,254 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.back"]){
+dojo._hasResource["dojo.back"]=true;
+dojo.provide("dojo.back");
+(function(){
+var _1=dojo.back;
+function _2(){
+var h=window.location.hash;
+if(h.charAt(0)=="#"){
+h=h.substring(1);
+}
+return dojo.isMozilla?h:decodeURIComponent(h);
+};
+function _4(h){
+if(!h){
+h="";
+}
+window.location.hash=encodeURIComponent(h);
+_6=history.length;
+};
+if(dojo.exists("tests.back-hash")){
+_1.getHash=_2;
+_1.setHash=_4;
+}
+var _7=(typeof (window)!=="undefined")?window.location.href:"";
+var _8=(typeof (window)!=="undefined")?_2():"";
+var _9=null;
+var _a=null;
+var _b=null;
+var _c=null;
+var _d=[];
+var _e=[];
+var _f=false;
+var _10=false;
+var _6;
+function _11(){
+var _12=_e.pop();
+if(!_12){
+return;
+}
+var _13=_e[_e.length-1];
+if(!_13&&_e.length==0){
+_13=_9;
+}
+if(_13){
+if(_13.kwArgs["back"]){
+_13.kwArgs["back"]();
+}else{
+if(_13.kwArgs["backButton"]){
+_13.kwArgs["backButton"]();
+}else{
+if(_13.kwArgs["handle"]){
+_13.kwArgs.handle("back");
+}
+}
+}
+}
+_d.push(_12);
+};
+_1.goBack=_11;
+function _14(){
+var _15=_d.pop();
+if(!_15){
+return;
+}
+if(_15.kwArgs["forward"]){
+_15.kwArgs.forward();
+}else{
+if(_15.kwArgs["forwardButton"]){
+_15.kwArgs.forwardButton();
+}else{
+if(_15.kwArgs["handle"]){
+_15.kwArgs.handle("forward");
+}
+}
+}
+_e.push(_15);
+};
+_1.goForward=_14;
+function _16(url,_18,_19){
+return {"url":url,"kwArgs":_18,"urlHash":_19};
+};
+function _1a(url){
+var _1c=url.split("?");
+if(_1c.length<2){
+return null;
+}else{
+return _1c[1];
+}
+};
+function _1d(){
+var url=(dojo.config["dojoIframeHistoryUrl"]||dojo.moduleUrl("dojo","resources/iframe_history.html"))+"?"+(new Date()).getTime();
+_f=true;
+if(_c){
+dojo.isWebKit?_c.location=url:window.frames[_c.name].location=url;
+}else{
+}
+return url;
+};
+function _1f(){
+if(!_10){
+var hsl=_e.length;
+var _21=_2();
+if((_21===_8||window.location.href==_7)&&(hsl==1)){
+_11();
+return;
+}
+if(_d.length>0){
+if(_d[_d.length-1].urlHash===_21){
+_14();
+return;
+}
+}
+if((hsl>=2)&&(_e[hsl-2])){
+if(_e[hsl-2].urlHash===_21){
+_11();
+return;
+}
+}
+if(dojo.isSafari&&dojo.isSafari<3){
+var _22=history.length;
+if(_22>_6){
+_14();
+}else{
+if(_22<_6){
+_11();
+}
+}
+_6=_22;
+}
+}
+};
+_1.init=function(){
+if(dojo.byId("dj_history")){
+return;
+}
+var src=dojo.config["dojoIframeHistoryUrl"]||dojo.moduleUrl("dojo","resources/iframe_history.html");
+document.write("<iframe style=\"border:0;width:1px;height:1px;position:absolute;visibility:hidden;bottom:0;right:0;\" name=\"dj_history\" id=\"dj_history\" src=\""+src+"\"></iframe>");
+};
+_1.setInitialState=function(_24){
+_9=_16(_7,_24,_8);
+};
+_1.addToHistory=function(_25){
+_d=[];
+var _26=null;
+var url=null;
+if(!_c){
+if(dojo.config["useXDomain"]&&!dojo.config["dojoIframeHistoryUrl"]){
+console.warn("dojo.back: When using cross-domain Dojo builds,"+" please save iframe_history.html to your domain and set djConfig.dojoIframeHistoryUrl"+" to the path on your domain to iframe_history.html");
+}
+_c=window.frames["dj_history"];
+}
+if(!_b){
+_b=dojo.create("a",{style:{display:"none"}},dojo.body());
+}
+if(_25["changeUrl"]){
+_26=""+((_25["changeUrl"]!==true)?_25["changeUrl"]:(new Date()).getTime());
+if(_e.length==0&&_9.urlHash==_26){
+_9=_16(url,_25,_26);
+return;
+}else{
+if(_e.length>0&&_e[_e.length-1].urlHash==_26){
+_e[_e.length-1]=_16(url,_25,_26);
+return;
+}
+}
+_10=true;
+setTimeout(function(){
+_4(_26);
+_10=false;
+},1);
+_b.href=_26;
+if(dojo.isIE){
+url=_1d();
+var _28=_25["back"]||_25["backButton"]||_25["handle"];
+var tcb=function(_2a){
+if(_2()!=""){
+setTimeout(function(){
+_4(_26);
+},1);
+}
+_28.apply(this,[_2a]);
+};
+if(_25["back"]){
+_25.back=tcb;
+}else{
+if(_25["backButton"]){
+_25.backButton=tcb;
+}else{
+if(_25["handle"]){
+_25.handle=tcb;
+}
+}
+}
+var _2b=_25["forward"]||_25["forwardButton"]||_25["handle"];
+var tfw=function(_2d){
+if(_2()!=""){
+_4(_26);
+}
+if(_2b){
+_2b.apply(this,[_2d]);
+}
+};
+if(_25["forward"]){
+_25.forward=tfw;
+}else{
+if(_25["forwardButton"]){
+_25.forwardButton=tfw;
+}else{
+if(_25["handle"]){
+_25.handle=tfw;
+}
+}
+}
+}else{
+if(!dojo.isIE){
+if(!_a){
+_a=setInterval(_1f,200);
+}
+}
+}
+}else{
+url=_1d();
+}
+_e.push(_16(url,_25,_26));
+};
+_1._iframeLoaded=function(evt,_2f){
+var _30=_1a(_2f.href);
+if(_30==null){
+if(_e.length==1){
+_11();
+}
+return;
+}
+if(_f){
+_f=false;
+return;
+}
+if(_e.length>=2&&_30==_1a(_e[_e.length-2].url)){
+_11();
+}else{
+if(_d.length>0&&_30==_1a(_d[_d.length-1].url)){
+_14();
+}
+}
+};
+})();
+}
diff --git a/dojo/behavior.js b/dojo/behavior.js
new file mode 100644
index 0000000..6c6df5e
--- /dev/null
+++ b/dojo/behavior.js
@@ -0,0 +1,94 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.behavior"]){
+dojo._hasResource["dojo.behavior"]=true;
+dojo.provide("dojo.behavior");
+dojo.behavior=new function(){
+function _1(_2,_3){
+if(!_2[_3]){
+_2[_3]=[];
+}
+return _2[_3];
+};
+var _4=0;
+function _5(_6,_7,_8){
+var _9={};
+for(var x in _6){
+if(typeof _9[x]=="undefined"){
+if(!_8){
+_7(_6[x],x);
+}else{
+_8.call(_7,_6[x],x);
+}
+}
+}
+};
+this._behaviors={};
+this.add=function(_b){
+var _c={};
+_5(_b,this,function(_d,_e){
+var _f=_1(this._behaviors,_e);
+if(typeof _f["id"]!="number"){
+_f.id=_4++;
+}
+var _10=[];
+_f.push(_10);
+if((dojo.isString(_d))||(dojo.isFunction(_d))){
+_d={found:_d};
+}
+_5(_d,function(_11,_12){
+_1(_10,_12).push(_11);
+});
+});
+};
+var _13=function(_14,_15,_16){
+if(dojo.isString(_15)){
+if(_16=="found"){
+dojo.publish(_15,[_14]);
+}else{
+dojo.connect(_14,_16,function(){
+dojo.publish(_15,arguments);
+});
+}
+}else{
+if(dojo.isFunction(_15)){
+if(_16=="found"){
+_15(_14);
+}else{
+dojo.connect(_14,_16,_15);
+}
+}
+}
+};
+this.apply=function(){
+_5(this._behaviors,function(_17,id){
+dojo.query(id).forEach(function(_19){
+var _1a=0;
+var bid="_dj_behavior_"+_17.id;
+if(typeof _19[bid]=="number"){
+_1a=_19[bid];
+if(_1a==(_17.length)){
+return;
+}
+}
+for(var x=_1a,_1d;_1d=_17[x];x++){
+_5(_1d,function(_1e,_1f){
+if(dojo.isArray(_1e)){
+dojo.forEach(_1e,function(_20){
+_13(_19,_20,_1f);
+});
+}
+});
+}
+_19[bid]=_17.length;
+});
+});
+};
+};
+dojo.addOnLoad(dojo.behavior,"apply");
+}
diff --git a/dojo/build.txt b/dojo/build.txt
new file mode 100644
index 0000000..b8110cd
--- /dev/null
+++ b/dojo/build.txt
@@ -0,0 +1,317 @@
+Files baked into this build:
+
+dojo.js:
+./jslib/dojoGuardStart.jsfrag
+./../../dojo/_base/_loader/bootstrap.js
+./../../dojo/_base/_loader/loader.js
+./../../dojo/_base/_loader/hostenv_browser.js
+./../../release/dojo-release-1.3.2/dojo/_base/lang.js
+./../../release/dojo-release-1.3.2/dojo/_base/declare.js
+./../../release/dojo-release-1.3.2/dojo/_base/connect.js
+./../../release/dojo-release-1.3.2/dojo/_base/Deferred.js
+./../../release/dojo-release-1.3.2/dojo/_base/json.js
+./../../release/dojo-release-1.3.2/dojo/_base/array.js
+./../../release/dojo-release-1.3.2/dojo/_base/Color.js
+./../../release/dojo-release-1.3.2/dojo/_base.js
+./../../release/dojo-release-1.3.2/dojo/_base/window.js
+./../../release/dojo-release-1.3.2/dojo/_base/event.js
+./../../release/dojo-release-1.3.2/dojo/_base/html.js
+./../../release/dojo-release-1.3.2/dojo/_base/NodeList.js
+./../../release/dojo-release-1.3.2/dojo/_base/query.js
+./../../release/dojo-release-1.3.2/dojo/_base/xhr.js
+./../../release/dojo-release-1.3.2/dojo/_base/fx.js
+./../../release/dojo-release-1.3.2/dojo/_base/browser.js
+./jslib/dojoGuardEnd.jsfrag
+
+../dijit/dijit.js:
+./../../release/dojo-release-1.3.2/dijit/_base/focus.js
+./../../release/dojo-release-1.3.2/dijit/_base/manager.js
+./../../release/dojo-release-1.3.2/dojo/AdapterRegistry.js
+./../../release/dojo-release-1.3.2/dijit/_base/place.js
+./../../release/dojo-release-1.3.2/dijit/_base/window.js
+./../../release/dojo-release-1.3.2/dijit/_base/popup.js
+./../../release/dojo-release-1.3.2/dijit/_base/scroll.js
+./../../release/dojo-release-1.3.2/dijit/_base/sniff.js
+./../../release/dojo-release-1.3.2/dijit/_base/typematic.js
+./../../release/dojo-release-1.3.2/dijit/_base/wai.js
+./../../release/dojo-release-1.3.2/dijit/_base.js
+./../../release/dojo-release-1.3.2/dojo/date/stamp.js
+./../../release/dojo-release-1.3.2/dojo/parser.js
+./../../release/dojo-release-1.3.2/dijit/_Widget.js
+./../../release/dojo-release-1.3.2/dojo/string.js
+./../../release/dojo-release-1.3.2/dijit/_Templated.js
+./../../release/dojo-release-1.3.2/dijit/_Container.js
+./../../release/dojo-release-1.3.2/dijit/_Contained.js
+./../../release/dojo-release-1.3.2/dijit/layout/_LayoutWidget.js
+./../../release/dojo-release-1.3.2/dijit/form/_FormWidget.js
+./../../release/dojo-release-1.3.2/dijit/dijit.js
+
+../dijit/dijit-all.js:
+./../../release/dojo-release-1.3.2/dojo/colors.js
+./../../release/dojo-release-1.3.2/dojo/i18n.js
+./../../release/dojo-release-1.3.2/dijit/ColorPalette.js
+./../../release/dojo-release-1.3.2/dijit/Declaration.js
+./../../release/dojo-release-1.3.2/dojo/dnd/common.js
+./../../release/dojo-release-1.3.2/dojo/dnd/autoscroll.js
+./../../release/dojo-release-1.3.2/dojo/dnd/Mover.js
+./../../release/dojo-release-1.3.2/dojo/dnd/Moveable.js
+./../../release/dojo-release-1.3.2/dojo/dnd/move.js
+./../../release/dojo-release-1.3.2/dojo/dnd/TimedMoveable.js
+./../../release/dojo-release-1.3.2/dojo/fx/Toggler.js
+./../../release/dojo-release-1.3.2/dojo/fx.js
+./../../release/dojo-release-1.3.2/dijit/form/_FormMixin.js
+./../../release/dojo-release-1.3.2/dijit/_DialogMixin.js
+./../../release/dojo-release-1.3.2/dijit/DialogUnderlay.js
+./../../release/dojo-release-1.3.2/dojo/html.js
+./../../release/dojo-release-1.3.2/dijit/layout/ContentPane.js
+./../../release/dojo-release-1.3.2/dijit/TooltipDialog.js
+./../../release/dojo-release-1.3.2/dijit/Dialog.js
+./../../release/dojo-release-1.3.2/dijit/_editor/selection.js
+./../../release/dojo-release-1.3.2/dijit/_editor/range.js
+./../../release/dojo-release-1.3.2/dijit/_editor/html.js
+./../../release/dojo-release-1.3.2/dijit/_editor/RichText.js
+./../../release/dojo-release-1.3.2/dijit/_KeyNavContainer.js
+./../../release/dojo-release-1.3.2/dijit/ToolbarSeparator.js
+./../../release/dojo-release-1.3.2/dijit/Toolbar.js
+./../../release/dojo-release-1.3.2/dijit/form/Button.js
+./../../release/dojo-release-1.3.2/dijit/_editor/_Plugin.js
+./../../release/dojo-release-1.3.2/dijit/_editor/plugins/EnterKeyHandling.js
+./../../release/dojo-release-1.3.2/dijit/Editor.js
+./../../release/dojo-release-1.3.2/dijit/MenuItem.js
+./../../release/dojo-release-1.3.2/dijit/PopupMenuItem.js
+./../../release/dojo-release-1.3.2/dijit/CheckedMenuItem.js
+./../../release/dojo-release-1.3.2/dijit/MenuSeparator.js
+./../../release/dojo-release-1.3.2/dijit/Menu.js
+./../../release/dojo-release-1.3.2/dijit/MenuBar.js
+./../../release/dojo-release-1.3.2/dijit/MenuBarItem.js
+./../../release/dojo-release-1.3.2/dijit/PopupMenuBarItem.js
+./../../release/dojo-release-1.3.2/dojo/regexp.js
+./../../release/dojo-release-1.3.2/dojo/number.js
+./../../release/dojo-release-1.3.2/dijit/ProgressBar.js
+./../../release/dojo-release-1.3.2/dijit/TitlePane.js
+./../../release/dojo-release-1.3.2/dijit/Tooltip.js
+./../../release/dojo-release-1.3.2/dojo/cookie.js
+./../../release/dojo-release-1.3.2/dijit/tree/TreeStoreModel.js
+./../../release/dojo-release-1.3.2/dijit/tree/ForestStoreModel.js
+./../../release/dojo-release-1.3.2/dijit/Tree.js
+./../../release/dojo-release-1.3.2/dijit/form/TextBox.js
+./../../release/dojo-release-1.3.2/dijit/InlineEditBox.js
+./../../release/dojo-release-1.3.2/dijit/form/CheckBox.js
+./../../release/dojo-release-1.3.2/dijit/form/ValidationTextBox.js
+./../../release/dojo-release-1.3.2/dojo/data/util/sorter.js
+./../../release/dojo-release-1.3.2/dojo/data/util/simpleFetch.js
+./../../release/dojo-release-1.3.2/dojo/data/util/filter.js
+./../../release/dojo-release-1.3.2/dijit/form/ComboBox.js
+./../../release/dojo-release-1.3.2/dojo/cldr/monetary.js
+./../../release/dojo-release-1.3.2/dojo/currency.js
+./../../release/dojo-release-1.3.2/dijit/form/NumberTextBox.js
+./../../release/dojo-release-1.3.2/dijit/form/CurrencyTextBox.js
+./../../release/dojo-release-1.3.2/dojo/cldr/supplemental.js
+./../../release/dojo-release-1.3.2/dojo/date.js
+./../../release/dojo-release-1.3.2/dojo/date/locale.js
+./../../release/dojo-release-1.3.2/dijit/_Calendar.js
+./../../release/dojo-release-1.3.2/dijit/form/_DateTimeTextBox.js
+./../../release/dojo-release-1.3.2/dijit/form/DateTextBox.js
+./../../release/dojo-release-1.3.2/dijit/form/FilteringSelect.js
+./../../release/dojo-release-1.3.2/dijit/form/_Spinner.js
+./../../release/dojo-release-1.3.2/dijit/form/NumberSpinner.js
+./../../release/dojo-release-1.3.2/dijit/form/HorizontalSlider.js
+./../../release/dojo-release-1.3.2/dijit/form/VerticalSlider.js
+./../../release/dojo-release-1.3.2/dijit/form/HorizontalRule.js
+./../../release/dojo-release-1.3.2/dijit/form/VerticalRule.js
+./../../release/dojo-release-1.3.2/dijit/form/HorizontalRuleLabels.js
+./../../release/dojo-release-1.3.2/dijit/form/VerticalRuleLabels.js
+./../../release/dojo-release-1.3.2/dijit/form/SimpleTextarea.js
+./../../release/dojo-release-1.3.2/dijit/form/Textarea.js
+./../../release/dojo-release-1.3.2/dijit/form/ToggleButton.js
+./../../release/dojo-release-1.3.2/dijit/layout/StackController.js
+./../../release/dojo-release-1.3.2/dijit/layout/StackContainer.js
+./../../release/dojo-release-1.3.2/dijit/layout/AccordionPane.js
+./../../release/dojo-release-1.3.2/dijit/layout/AccordionContainer.js
+./../../release/dojo-release-1.3.2/dijit/layout/BorderContainer.js
+./../../release/dojo-release-1.3.2/dijit/layout/LayoutContainer.js
+./../../release/dojo-release-1.3.2/dijit/layout/LinkPane.js
+./../../release/dojo-release-1.3.2/dijit/layout/SplitContainer.js
+./../../release/dojo-release-1.3.2/dijit/layout/TabController.js
+./../../release/dojo-release-1.3.2/dijit/layout/TabContainer.js
+./../../release/dojo-release-1.3.2/dijit/dijit-all.js
+
+../dojox/off/offline.js:
+./../../release/dojo-release-1.3.2/dojox/storage/Provider.js
+./../../release/dojo-release-1.3.2/dojox/storage/manager.js
+./../../release/dojo-release-1.3.2/dojo/gears.js
+./../../release/dojo-release-1.3.2/dojox/sql/_crypto.js
+./../../release/dojo-release-1.3.2/dojox/sql/_base.js
+./../../release/dojo-release-1.3.2/dojox/sql.js
+./../../release/dojo-release-1.3.2/dojox/storage/GearsStorageProvider.js
+./../../release/dojo-release-1.3.2/dojox/storage/WhatWGStorageProvider.js
+./../../release/dojo-release-1.3.2/dojo/AdapterRegistry.js
+./../../release/dojo-release-1.3.2/dijit/_base/place.js
+./../../release/dojo-release-1.3.2/dojox/flash/_base.js
+./../../release/dojo-release-1.3.2/dojox/flash.js
+./../../release/dojo-release-1.3.2/dojox/storage/FlashStorageProvider.js
+./../../release/dojo-release-1.3.2/dojox/storage/_common.js
+./../../release/dojo-release-1.3.2/dojox/storage.js
+./../../release/dojo-release-1.3.2/dojox/off/files.js
+./../../release/dojo-release-1.3.2/dojox/off/sync.js
+./../../release/dojo-release-1.3.2/dojox/off/_common.js
+./../../release/dojo-release-1.3.2/dojox/off.js
+./../../release/dojo-release-1.3.2/dojox/off/ui.js
+./../../release/dojo-release-1.3.2/dojox/off/offline.js
+
+../dojox/grid/DataGrid.js:
+./../../release/dojo-release-1.3.2/dijit/_base/focus.js
+./../../release/dojo-release-1.3.2/dijit/_base/manager.js
+./../../release/dojo-release-1.3.2/dojo/AdapterRegistry.js
+./../../release/dojo-release-1.3.2/dijit/_base/place.js
+./../../release/dojo-release-1.3.2/dijit/_base/window.js
+./../../release/dojo-release-1.3.2/dijit/_base/popup.js
+./../../release/dojo-release-1.3.2/dijit/_base/scroll.js
+./../../release/dojo-release-1.3.2/dijit/_base/sniff.js
+./../../release/dojo-release-1.3.2/dijit/_base/typematic.js
+./../../release/dojo-release-1.3.2/dijit/_base/wai.js
+./../../release/dojo-release-1.3.2/dijit/_base.js
+./../../release/dojo-release-1.3.2/dojo/date/stamp.js
+./../../release/dojo-release-1.3.2/dojo/parser.js
+./../../release/dojo-release-1.3.2/dijit/_Widget.js
+./../../release/dojo-release-1.3.2/dojo/string.js
+./../../release/dojo-release-1.3.2/dijit/_Templated.js
+./../../release/dojo-release-1.3.2/dijit/_Container.js
+./../../release/dojo-release-1.3.2/dijit/_Contained.js
+./../../release/dojo-release-1.3.2/dijit/layout/_LayoutWidget.js
+./../../release/dojo-release-1.3.2/dijit/form/_FormWidget.js
+./../../release/dojo-release-1.3.2/dijit/dijit.js
+./../../release/dojo-release-1.3.2/dijit/_KeyNavContainer.js
+./../../release/dojo-release-1.3.2/dijit/MenuItem.js
+./../../release/dojo-release-1.3.2/dijit/PopupMenuItem.js
+./../../release/dojo-release-1.3.2/dijit/CheckedMenuItem.js
+./../../release/dojo-release-1.3.2/dijit/MenuSeparator.js
+./../../release/dojo-release-1.3.2/dijit/Menu.js
+./../../release/dojo-release-1.3.2/dojox/html/metrics.js
+./../../release/dojo-release-1.3.2/dojox/grid/util.js
+./../../release/dojo-release-1.3.2/dojox/grid/_Scroller.js
+./../../release/dojo-release-1.3.2/dojox/grid/cells/_base.js
+./../../release/dojo-release-1.3.2/dojox/grid/cells.js
+./../../release/dojo-release-1.3.2/dojo/dnd/common.js
+./../../release/dojo-release-1.3.2/dojo/dnd/autoscroll.js
+./../../release/dojo-release-1.3.2/dojo/dnd/Mover.js
+./../../release/dojo-release-1.3.2/dojo/dnd/Moveable.js
+./../../release/dojo-release-1.3.2/dojox/grid/_Builder.js
+./../../release/dojo-release-1.3.2/dojo/dnd/Container.js
+./../../release/dojo-release-1.3.2/dojo/dnd/Selector.js
+./../../release/dojo-release-1.3.2/dojo/dnd/Avatar.js
+./../../release/dojo-release-1.3.2/dojo/dnd/Manager.js
+./../../release/dojo-release-1.3.2/dojo/dnd/Source.js
+./../../release/dojo-release-1.3.2/dojox/grid/_View.js
+./../../release/dojo-release-1.3.2/dojox/grid/_RowSelector.js
+./../../release/dojo-release-1.3.2/dojox/grid/_Layout.js
+./../../release/dojo-release-1.3.2/dojox/grid/_ViewManager.js
+./../../release/dojo-release-1.3.2/dojox/grid/_RowManager.js
+./../../release/dojo-release-1.3.2/dojox/grid/_FocusManager.js
+./../../release/dojo-release-1.3.2/dojox/grid/_EditManager.js
+./../../release/dojo-release-1.3.2/dojox/grid/Selection.js
+./../../release/dojo-release-1.3.2/dojox/grid/_Events.js
+./../../release/dojo-release-1.3.2/dojo/i18n.js
+./../../release/dojo-release-1.3.2/dojox/grid/_Grid.js
+./../../release/dojo-release-1.3.2/dojox/grid/DataSelection.js
+./../../release/dojo-release-1.3.2/dojox/grid/DataGrid.js
+
+../dojox/gfx.js:
+./../../release/dojo-release-1.3.2/dojox/gfx/matrix.js
+./../../release/dojo-release-1.3.2/dojox/gfx/_base.js
+./../../release/dojo-release-1.3.2/dojox/gfx.js
+
+../dojox/charting/widget/Chart2D.js:
+./../../release/dojo-release-1.3.2/dijit/_base/focus.js
+./../../release/dojo-release-1.3.2/dijit/_base/manager.js
+./../../release/dojo-release-1.3.2/dojo/AdapterRegistry.js
+./../../release/dojo-release-1.3.2/dijit/_base/place.js
+./../../release/dojo-release-1.3.2/dijit/_base/window.js
+./../../release/dojo-release-1.3.2/dijit/_base/popup.js
+./../../release/dojo-release-1.3.2/dijit/_base/scroll.js
+./../../release/dojo-release-1.3.2/dijit/_base/sniff.js
+./../../release/dojo-release-1.3.2/dijit/_base/typematic.js
+./../../release/dojo-release-1.3.2/dijit/_base/wai.js
+./../../release/dojo-release-1.3.2/dijit/_base.js
+./../../release/dojo-release-1.3.2/dijit/_Widget.js
+./../../release/dojo-release-1.3.2/dojox/gfx/matrix.js
+./../../release/dojo-release-1.3.2/dojox/gfx/_base.js
+./../../release/dojo-release-1.3.2/dojox/gfx.js
+./../../release/dojo-release-1.3.2/dojox/lang/functional/lambda.js
+./../../release/dojo-release-1.3.2/dojox/lang/functional/array.js
+./../../release/dojo-release-1.3.2/dojox/lang/functional/object.js
+./../../release/dojo-release-1.3.2/dojox/lang/functional.js
+./../../release/dojo-release-1.3.2/dojox/lang/functional/fold.js
+./../../release/dojo-release-1.3.2/dojox/lang/functional/reversed.js
+./../../release/dojo-release-1.3.2/dojo/colors.js
+./../../release/dojo-release-1.3.2/dojox/color/_base.js
+./../../release/dojo-release-1.3.2/dojox/color.js
+./../../release/dojo-release-1.3.2/dojox/color/Palette.js
+./../../release/dojo-release-1.3.2/dojox/charting/Theme.js
+./../../release/dojo-release-1.3.2/dojox/charting/Element.js
+./../../release/dojo-release-1.3.2/dojox/charting/Series.js
+./../../release/dojo-release-1.3.2/dojox/charting/scaler/common.js
+./../../release/dojo-release-1.3.2/dojox/charting/scaler/linear.js
+./../../release/dojo-release-1.3.2/dojox/charting/axis2d/common.js
+./../../release/dojo-release-1.3.2/dojox/charting/axis2d/Base.js
+./../../release/dojo-release-1.3.2/dojo/string.js
+./../../release/dojo-release-1.3.2/dojox/lang/utils.js
+./../../release/dojo-release-1.3.2/dojox/charting/axis2d/Default.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/common.js
+./../../release/dojo-release-1.3.2/dojox/charting/scaler/primitive.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/Base.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/Default.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/Lines.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/Areas.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/Markers.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/MarkersOnly.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/Scatter.js
+./../../release/dojo-release-1.3.2/dojox/lang/functional/sequence.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/Stacked.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/StackedLines.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/StackedAreas.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/Columns.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/StackedColumns.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/ClusteredColumns.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/Bars.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/StackedBars.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/ClusteredBars.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/Grid.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/Pie.js
+./../../release/dojo-release-1.3.2/dojox/charting/plot2d/Bubble.js
+./../../release/dojo-release-1.3.2/dojox/charting/Chart2D.js
+./../../release/dojo-release-1.3.2/dojo/fx/easing.js
+./../../release/dojo-release-1.3.2/dojox/gfx/fx.js
+./../../release/dojo-release-1.3.2/dojox/charting/action2d/Base.js
+./../../release/dojo-release-1.3.2/dojox/charting/action2d/Highlight.js
+./../../release/dojo-release-1.3.2/dojo/fx/Toggler.js
+./../../release/dojo-release-1.3.2/dojo/fx.js
+./../../release/dojo-release-1.3.2/dojox/charting/action2d/Magnify.js
+./../../release/dojo-release-1.3.2/dojox/lang/functional/scan.js
+./../../release/dojo-release-1.3.2/dojox/charting/action2d/MoveSlice.js
+./../../release/dojo-release-1.3.2/dojox/charting/action2d/Shake.js
+./../../release/dojo-release-1.3.2/dojo/date/stamp.js
+./../../release/dojo-release-1.3.2/dojo/parser.js
+./../../release/dojo-release-1.3.2/dijit/_Templated.js
+./../../release/dojo-release-1.3.2/dijit/Tooltip.js
+./../../release/dojo-release-1.3.2/dojox/charting/action2d/Tooltip.js
+./../../release/dojo-release-1.3.2/dojox/charting/widget/Chart2D.js
+./../../release/dojo-release-1.3.2/dojox/charting/themes/ET/greys.js
+./../../release/dojo-release-1.3.2/dojox/charting/widget/Sparkline.js
+./../../release/dojo-release-1.3.2/dojox/charting/widget/Legend.js
+
+../dojox/dtl.js:
+./../../release/dojo-release-1.3.2/dojox/string/Builder.js
+./../../release/dojo-release-1.3.2/dojox/string/tokenize.js
+./../../release/dojo-release-1.3.2/dojox/dtl/_base.js
+./../../release/dojo-release-1.3.2/dojox/dtl.js
+./../../release/dojo-release-1.3.2/dojox/dtl/Context.js
+./../../release/dojo-release-1.3.2/dojox/dtl/tag/logic.js
+./../../release/dojo-release-1.3.2/dojox/dtl/tag/loop.js
+./../../release/dojo-release-1.3.2/dojo/date.js
+./../../release/dojo-release-1.3.2/dojox/date/php.js
+./../../release/dojo-release-1.3.2/dojox/dtl/utils/date.js
+./../../release/dojo-release-1.3.2/dojox/dtl/tag/date.js
+./../../release/dojo-release-1.3.2/dojox/dtl/tag/loader.js
+./../../release/dojo-release-1.3.2/dojox/dtl/tag/misc.js
+./../../release/dojo-release-1.3.2/dojox/dtl/ext-dojo/NodeList.js
diff --git a/dojo/cldr/LICENSE b/dojo/cldr/LICENSE
new file mode 100644
index 0000000..7aeb1dd
--- /dev/null
+++ b/dojo/cldr/LICENSE
@@ -0,0 +1,29 @@
+UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
+
+Unicode Data Files include all data files under the directories http://www.unicode.org/Public/, http://www.unicode.org/reports/, 
+and http://www.unicode.org/cldr/data/ . Unicode Software includes any source code published in the Unicode Standard or under
+the directories http://www.unicode.org/Public/, http://www.unicode.org/reports/, and http://www.unicode.org/cldr/data/.
+NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR 
+OTHERWISE USING UNICODE INC.'S DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU
+UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS
+AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
+
+COPYRIGHT AND PERMISSION NOTICE
+Copyright � 1991-2007 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in http://www.unicode.org/copyright.html.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Unicode data files and any associated
+documentation (the "Data Files") or Unicode software and any associated documentation (the "Software") to deal in the Data 
+Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell 
+copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided
+that (a) the above copyright notice(s) and this permission notice appear with all copies of the Data Files or Software, (b) both the
+above copyright notice(s) and this permission notice appear in associated documentation, and (c) there is clear notice in each modified Data File 
+or in the Software as well as in the documentation associated with the Data File(s) or Software that the data or software has been modified.
+THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE 
+AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
+INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, 
+OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF 
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THE DATA FILES OR SOFTWARE.
+Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other 
+dealings in these Data Files or Software without prior written authorization of the copyright holder.
\ No newline at end of file
diff --git a/dojo/cldr/README b/dojo/cldr/README
new file mode 100644
index 0000000..3687676
--- /dev/null
+++ b/dojo/cldr/README
@@ -0,0 +1,18 @@
+All files within this directory were derived from the Common Locale
+Data Repository (see http://unicode.org/cldr)  The CLDR project is
+responsible for the accuracy and maintenance of this data.  A copy
+of this data is checked into the Dojo util project as a zip file.
+The XML data is transformed to the JSON-style Javascript you see
+under the nls/ directory.  These Javascript files include data
+necessary to do things like format and parse dates, numbers, and
+currencies in different locales to consider cultural differences.
+They are used by other modules in core Dojo such as dojo.date,
+dojo.number and dojo.currency.  It usually is not necessary to use
+dojo.cldr directly.
+
+An arbitrary subset of locales have been checked in to dojo/cldr
+under svn.  To support other locales, the full set may be generated
+by using xslt scripts in the util/buildscripts/cldr/ ant script.
+Hundreds of locales are supported by the CLDR project.
+
+See terms of use: http://www.unicode.org/copyright.html#Exhibit1
diff --git a/dojo/cldr/monetary.js b/dojo/cldr/monetary.js
new file mode 100644
index 0000000..be83bb0
--- /dev/null
+++ b/dojo/cldr/monetary.js
@@ -0,0 +1,23 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.cldr.monetary"]){
+dojo._hasResource["dojo.cldr.monetary"]=true;
+dojo.provide("dojo.cldr.monetary");
+dojo.cldr.monetary.getData=function(_1){
+var _2={ADP:0,BHD:3,BIF:0,BYR:0,CLF:0,CLP:0,DJF:0,ESP:0,GNF:0,IQD:3,ITL:0,JOD:3,JPY:0,KMF:0,KRW:0,KWD:3,LUF:0,LYD:3,MGA:0,MGF:0,OMR:3,PYG:0,RWF:0,TND:3,TRL:0,VUV:0,XAF:0,XOF:0,XPF:0};
+var _3={CHF:5};
+var _4=_2[_1],_5=_3[_1];
+if(typeof _4=="undefined"){
+_4=2;
+}
+if(typeof _5=="undefined"){
+_5=0;
+}
+return {places:_4,round:_5};
+};
+}
diff --git a/dojo/cldr/nls/ar/currency.js b/dojo/cldr/nls/ar/currency.js
new file mode 100644
index 0000000..097e496
--- /dev/null
+++ b/dojo/cldr/nls/ar/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"دولار هونج كونج","CHF_displayName":"فرنك سويسرى","CAD_displayName":"دولار كندى","CNY_displayName":"يوان صيني","AUD_displayName":"دولار أسترالى","JPY_displayName":"ين ياباني","USD_displayName":"دولار أمريكي","GBP_displayName":"جنيه سترليني","EUR_displayName":"يورو","USD_symbol":"US$","GBP_symbol":"UK£","JPY_symbol":"JP¥","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/ar/gregorian.js b/dojo/cldr/nls/ar/gregorian.js
new file mode 100644
index 0000000..6dcbf22
--- /dev/null
+++ b/dojo/cldr/nls/ar/gregorian.js
@@ -0,0 +1 @@
+({"dateFormatItem-yM":"M/yyyy","field-dayperiod":"ص/م","dateFormatItem-yQ":"yyyy Q","field-minute":"الدقائق","eraNames":["قبل الميلاد","ميلادي"],"dateFormatItem-MMMEd":"E d MMM","field-weekday":"اليوم","dateFormatItem-yQQQ":"yyyy QQQ","dateFormatItem-MMdd":"dd‏/MM","days-standAlone-wide":["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],"dateFormatItem-MMM":"LLL","patternChars":"GanjkHmsSEDFwWxhKzAeugXZvcL","months-standAlone-narrow":["ي","ف","م","أ","و","ن","ل","غ","س" [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/ar/islamic-civil.js b/dojo/cldr/nls/ar/islamic-civil.js
new file mode 100644
index 0000000..aad7fd9
--- /dev/null
+++ b/dojo/cldr/nls/ar/islamic-civil.js
@@ -0,0 +1 @@
+({"eraAbbr":["ه"],"patternChars":"GanjkHmsSEDFwWxhKzAeugXZvcL","months-format-wide":["محرم","صفر","ربيع الأول","ربيع الآخر","جمادى الأولى","جمادى الآخرة","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة"],"months at localeAlias1":{"bundle":"islamic","target":"months"},"era at localeAlias2":{"bundle":"islamic","target":"era"},"months-format-narrow":["1","2","3","4","5","6","7","8","9","10","11","12"],"quarters-standAlone-narrow":["1","2","3","4"],"dateFormatItem-yQQQ":"yyyy QQQ","dateFormatIt [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/ar/islamic.js b/dojo/cldr/nls/ar/islamic.js
new file mode 100644
index 0000000..67ac743
--- /dev/null
+++ b/dojo/cldr/nls/ar/islamic.js
@@ -0,0 +1 @@
+({"eraAbbr":["ه"],"patternChars":"GanjkHmsSEDFwWxhKzAeugXZvcL","months-format-wide":["محرم","صفر","ربيع الأول","ربيع الآخر","جمادى الأولى","جمادى الآخرة","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة"],"am":"ص","pm":"م","months-format-narrow":["1","2","3","4","5","6","7","8","9","10","11","12"],"quarters-standAlone-narrow":["1","2","3","4"],"dateFormatItem-yQQQ":"yyyy QQQ","dateFormatItem-yMEd":"EEE, yyyy-M-d","dateFormatItem-MMMEd":"E MMM d","eraNarrow":["AH"],"dateTimeFormats-appe [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/ar/number.js b/dojo/cldr/nls/ar/number.js
new file mode 100644
index 0000000..9e5f250
--- /dev/null
+++ b/dojo/cldr/nls/ar/number.js
@@ -0,0 +1 @@
+({"group":"٬","percentSign":"٪","exponential":"اس","list":"؛","decimal":"٫","nan":"ليس رقم","nativeZeroDigit":"٠","decimalFormat":"#,##0.###;#,##0.###-","currencyFormat":"¤ #,##0.00;¤ #,##0.00-","scientificFormat":"#E0","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","infinity":"∞","minusSign":"-","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","plusSign":"+","currencySpacing-afterCurrency-surroundingMatch":"[:dig [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/ca/currency.js b/dojo/cldr/nls/ca/currency.js
new file mode 100644
index 0000000..44fdb19
--- /dev/null
+++ b/dojo/cldr/nls/ca/currency.js
@@ -0,0 +1 @@
+({"EUR_displayName":"Euro","CHF_displayName":"Franc suís","GBP_displayName":"Lliura esterlina britànica","JPY_displayName":"Ien japonès","CNY_displayName":"Iuan renmimbi xinès","USD_displayName":"Dòlar EUA","USD_symbol":"US$","GBP_symbol":"UK£","JPY_symbol":"JP¥","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/ca/gregorian.js b/dojo/cldr/nls/ca/gregorian.js
new file mode 100644
index 0000000..078925b
--- /dev/null
+++ b/dojo/cldr/nls/ca/gregorian.js
@@ -0,0 +1 @@
+({"dateFormatItem-yM":"M/yyyy","field-dayperiod":"AM/PM","dateFormatItem-yQ":"Q yyyy","field-minute":"minut","eraNames":["aC","dC"],"dateFormatItem-MMMEd":"E MMM d","field-weekday":"dia de la setmana","dateFormatItem-yQQQ":"QQQ yyyy","days-standAlone-wide":["diumenge","dilluns","dimarts","dimecres","dijous","divendres","dissabte"],"dateFormatItem-MMM":"LLL","patternChars":"GuMtkHmsSEDFwWahKzUeygAZvcL","months-standAlone-narrow":["g","f","m","a","m","j","j","a","s","o","n","d"],"field-era [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/ca/number.js b/dojo/cldr/nls/ca/number.js
new file mode 100644
index 0000000..da4300c
--- /dev/null
+++ b/dojo/cldr/nls/ca/number.js
@@ -0,0 +1 @@
+({"group":".","percentSign":"%","exponential":"E","percentFormat":"#,##0%","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":",","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","currencyFormat":"#,##0.00 ¤","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpacing-afterCu [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/cs/currency.js b/dojo/cldr/nls/cs/currency.js
new file mode 100644
index 0000000..1f0c2ff
--- /dev/null
+++ b/dojo/cldr/nls/cs/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"Dolar hongkongský","CHF_displayName":"Frank švýcarský","CHF_symbol":"SwF","HKD_symbol":"HK$","CAD_displayName":"Dolar kanadský","CNY_displayName":"Juan renminbi","AUD_displayName":"Dolar australský","JPY_displayName":"Jen","CAD_symbol":"Can$","USD_displayName":"Dolar americký","CNY_symbol":"Y","GBP_displayName":"Libra šterlinků","AUD_symbol":"$A","EUR_displayName":"Euro","USD_symbol":"US$","GBP_symbol":"UK£","JPY_symbol":"JP¥","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/cs/gregorian.js b/dojo/cldr/nls/cs/gregorian.js
new file mode 100644
index 0000000..4a01c78
--- /dev/null
+++ b/dojo/cldr/nls/cs/gregorian.js
@@ -0,0 +1 @@
+({"quarters-standAlone-wide":["1. čtvrtletí","2. čtvrtletí","3. čtvrtletí","4. čtvrtletí"],"quarters-format-abbr":["1. čtvrtletí","2. čtvrtletí","3. čtvrtletí","4. čtvrtletí"],"dateFormat-medium":"d.M.yyyy","quarters-standAlone-abbr":["1. čtvrtletí","2. čtvrtletí","3. čtvrtletí","4. čtvrtletí"],"eraNarrow":["př.Kr.","po Kr."],"months-format-narrow":["l","ú","b","d","k","č","č","s","z","ř","l","p"],"pm":"odp.","months-standAlone-narrow":["l","ú","b","d","k","č","č","s","z","ř","l","p"],"m [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/cs/number.js b/dojo/cldr/nls/cs/number.js
new file mode 100644
index 0000000..ad7c869
--- /dev/null
+++ b/dojo/cldr/nls/cs/number.js
@@ -0,0 +1 @@
+({"group":" ","percentSign":"%","exponential":"E","percentFormat":"#,##0%","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":",","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","currencyFormat":"#,##0.00 ¤","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpacing-afterCu [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/currency.js b/dojo/cldr/nls/currency.js
new file mode 100644
index 0000000..742b390
--- /dev/null
+++ b/dojo/cldr/nls/currency.js
@@ -0,0 +1 @@
+({"USD_symbol":"US$","EUR_displayName":"EUR","GBP_displayName":"GBP","JPY_displayName":"JPY","GBP_symbol":"UK£","JPY_symbol":"JP¥","EUR_symbol":"€","USD_displayName":"USD"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/da/currency.js b/dojo/cldr/nls/da/currency.js
new file mode 100644
index 0000000..7bed5de
--- /dev/null
+++ b/dojo/cldr/nls/da/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"Hongkong dollar","CHF_displayName":"Schweizisk franc","CHF_symbol":"SwF","HKD_symbol":"HK$","CAD_displayName":"Canadisk dollar","CNY_displayName":"Kinesisk yuan renminbi","USD_symbol":"$","AUD_displayName":"Australsk dollar","JPY_displayName":"Japansk yen","CAD_symbol":"Can$","USD_displayName":"Amerikansk dollar","CNY_symbol":"Y","GBP_displayName":"Britisk pund","GBP_symbol":"£","AUD_symbol":"$A","EUR_displayName":"Euro","JPY_symbol":"JP¥","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/da/gregorian.js b/dojo/cldr/nls/da/gregorian.js
new file mode 100644
index 0000000..76f2933
--- /dev/null
+++ b/dojo/cldr/nls/da/gregorian.js
@@ -0,0 +1 @@
+({"months-format-narrow":["J","F","M","A","M","J","J","A","S","O","N","D"],"quarters-standAlone-narrow":["1","2","3","4"],"field-weekday":"ugedag","dateFormatItem-yQQQ":"QQQ yyyy","dateFormatItem-yMEd":"EEE. d-M-yyyy","dateFormatItem-MMMEd":"E d MMM","eraNarrow":["f.Kr.","e.Kr."],"dateFormat-long":"d. MMM yyyy","months-format-wide":["januar","februar","marts","april","maj","juni","juli","august","september","oktober","november","december"],"dateFormat-full":"EEEE 'den' d. MMMM yyyy","dat [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/da/number.js b/dojo/cldr/nls/da/number.js
new file mode 100644
index 0000000..2f5fc8e
--- /dev/null
+++ b/dojo/cldr/nls/da/number.js
@@ -0,0 +1 @@
+({"group":".","percentSign":"%","exponential":"E","percentFormat":"#,##0 %","scientificFormat":"#E0","list":",","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":",","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","currencyFormat":"#,##0.00 ¤","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpacing-afterC [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/de-de/number.js b/dojo/cldr/nls/de-de/number.js
new file mode 100644
index 0000000..e600506
--- /dev/null
+++ b/dojo/cldr/nls/de-de/number.js
@@ -0,0 +1 @@
+({"currencyFormat":"#,##0.00 ¤","group":".","percentSign":"%","exponential":"E","percentFormat":"#,##0 %","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":",","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpacing-afterC [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/de/currency.js b/dojo/cldr/nls/de/currency.js
new file mode 100644
index 0000000..56d66a6
--- /dev/null
+++ b/dojo/cldr/nls/de/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"Hongkong-Dollar","CHF_displayName":"Schweizer Franken","CHF_symbol":"SFr.","JPY_symbol":"¥","CAD_displayName":"Kanadischer Dollar","CNY_displayName":"Renminbi Yuan","USD_symbol":"$","AUD_displayName":"Australischer Dollar","JPY_displayName":"Yen","CAD_symbol":"Can$","USD_displayName":"US-Dollar","CNY_symbol":"Y","GBP_displayName":"Pfund Sterling","GBP_symbol":"£","AUD_symbol":"$A","EUR_displayName":"Euro","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/de/gregorian.js b/dojo/cldr/nls/de/gregorian.js
new file mode 100644
index 0000000..f0d7994
--- /dev/null
+++ b/dojo/cldr/nls/de/gregorian.js
@@ -0,0 +1 @@
+({"months-format-narrow":["J","F","M","A","M","J","J","A","S","O","N","D"],"quarters-standAlone-narrow":["1","2","3","4"],"field-weekday":"Wochentag","dateFormatItem-yyQQQQ":"QQQQ yy","dateFormatItem-yQQQ":"QQQ yyyy","dateFormatItem-yMEd":"EEE, yyyy-M-d","dateFormatItem-MMMEd":"E d. MMM","eraNarrow":["v. Chr.","n. Chr."],"dateFormat-long":"d. MMMM yyyy","months-format-wide":["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],"dateF [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/de/number.js b/dojo/cldr/nls/de/number.js
new file mode 100644
index 0000000..90861a0
--- /dev/null
+++ b/dojo/cldr/nls/de/number.js
@@ -0,0 +1 @@
+({"group":".","percentSign":"%","exponential":"E","percentFormat":"#,##0 %","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":",","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","currencyFormat":"#,##0.00 ¤","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpacing-afterC [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/el/currency.js b/dojo/cldr/nls/el/currency.js
new file mode 100644
index 0000000..9338e30
--- /dev/null
+++ b/dojo/cldr/nls/el/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"Δολάριο Χονγκ Κονγκ","CHF_displayName":"Φράγκο Ελβετίας","CHF_symbol":"SwF","HKD_symbol":"HK$","CAD_displayName":"Δολάριο Καναδά","CNY_displayName":"Γιουάν Ρενμίμπι Κίνας","AUD_displayName":"Δολάριο Αυστραλίας","JPY_displayName":"Γιεν Ιαπωνίας","CAD_symbol":"Can$","USD_displayName":"Δολάριο ΗΠΑ","CNY_symbol":"Y","GBP_displayName":"Λίρα Στερλίνα Βρετανίας","GBP_symbol":"GBP","AUD_symbol":"$A","EUR_displayName":"Ευρώ","USD_symbol":"US$","JPY_symbol":"JP¥","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/el/gregorian.js b/dojo/cldr/nls/el/gregorian.js
new file mode 100644
index 0000000..c7ebd97
--- /dev/null
+++ b/dojo/cldr/nls/el/gregorian.js
@@ -0,0 +1 @@
+({"field-dayperiod":"ΠΜ/ΜΜ","field-minute":"Λεπτό","eraNames":["π.Χ.","μ.Χ."],"dateFormatItem-MMMEd":"E d MMM","field-weekday":"Ημέρα Εβδομάδας","dateFormatItem-MMdd":"dd/MM","days-standAlone-wide":["Κυριακή","Δευτέρα","Τρίτη","Τετάρτη","Πέμπτη","Παρασκευή","Σάββατο"],"patternChars":"GanjkHmsSEDFwWxhKzAeugXZvcL","months-standAlone-narrow":["Ι","Φ","Μ","Α","Μ","Ι","Ι","Α","Σ","Ο","Ν","Δ"],"field-era":"Περίοδος","field-hour":"Ώρα","quarters-standAlone-abbr":["Τ1","Τ2","Τ3","Τ4"],"timeForma [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/el/number.js b/dojo/cldr/nls/el/number.js
new file mode 100644
index 0000000..5b8929f
--- /dev/null
+++ b/dojo/cldr/nls/el/number.js
@@ -0,0 +1 @@
+({"currencyFormat":"#,##0.00 ¤;-#,##0.00 ¤","group":".","decimal":",","scientificFormat":"#E0","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","infinity":"∞","list":";","percentSign":"%","minusSign":"-","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","nan":"NaN","nativeZeroDigit":"0","plusSign":"+","currencySpacing-afterCurrency-surroundingMatch":"[:digit:]","currencySpacing-beforeCurrency-currencyMatch":"[:letter [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-au/currency.js b/dojo/cldr/nls/en-au/currency.js
new file mode 100644
index 0000000..c9caa43
--- /dev/null
+++ b/dojo/cldr/nls/en-au/currency.js
@@ -0,0 +1 @@
+({"AUD_symbol":"$","USD_symbol":"US$","HKD_displayName":"Hong Kong Dollar","CHF_displayName":"Swiss Franc","CHF_symbol":"Fr.","JPY_symbol":"¥","HKD_symbol":"HK$","CAD_displayName":"Canadian Dollar","CNY_displayName":"Chinese Yuan Renminbi","AUD_displayName":"Australian Dollar","JPY_displayName":"Japanese Yen","CAD_symbol":"CA$","USD_displayName":"US Dollar","CNY_symbol":"RMB","GBP_displayName":"British Pound Sterling","GBP_symbol":"£","EUR_displayName":"Euro","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-au/gregorian.js b/dojo/cldr/nls/en-au/gregorian.js
new file mode 100644
index 0000000..e98939a
--- /dev/null
+++ b/dojo/cldr/nls/en-au/gregorian.js
@@ -0,0 +1 @@
+({"dateFormat-short":"d/MM/yy","dateFormatItem-MMdd":"dd/MM","dateFormat-medium":"dd/MM/yyyy","dateFormat-long":"d MMMM yyyy","dateFormatItem-MMMMd":"d MMMM","dateFormat-full":"EEEE, d MMMM yyyy","dateFormatItem-yyyyMM":"MM/yyyy","dateFormatItem-yyyyMMMM":"MMMM yyyy","dateFormatItem-yM":"M/yyyy","field-dayperiod":"AM/PM","dateFormatItem-yQ":"Q yyyy","field-minute":"Minute","eraNames":["Before Christ","Anno Domini"],"dateFormatItem-MMMEd":"E, MMM d","field-weekday":"Day of the Week","date [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-au/number.js b/dojo/cldr/nls/en-au/number.js
new file mode 100644
index 0000000..748ea80
--- /dev/null
+++ b/dojo/cldr/nls/en-au/number.js
@@ -0,0 +1 @@
+({"currencyFormat":"¤#,##0.00","group":",","percentSign":"%","exponential":"E","percentFormat":"#,##0%","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":".","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpacing-afterCur [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-ca/currency.js b/dojo/cldr/nls/en-ca/currency.js
new file mode 100644
index 0000000..516b0e1
--- /dev/null
+++ b/dojo/cldr/nls/en-ca/currency.js
@@ -0,0 +1 @@
+({"CAD_symbol":"$","USD_symbol":"US$","HKD_displayName":"Hong Kong Dollar","CHF_displayName":"Swiss Franc","CHF_symbol":"Fr.","JPY_symbol":"¥","HKD_symbol":"HK$","CAD_displayName":"Canadian Dollar","CNY_displayName":"Chinese Yuan Renminbi","AUD_displayName":"Australian Dollar","JPY_displayName":"Japanese Yen","USD_displayName":"US Dollar","CNY_symbol":"RMB","GBP_displayName":"British Pound Sterling","GBP_symbol":"£","AUD_symbol":"A$","EUR_displayName":"Euro","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-ca/gregorian.js b/dojo/cldr/nls/en-ca/gregorian.js
new file mode 100644
index 0000000..6dcb8ba
--- /dev/null
+++ b/dojo/cldr/nls/en-ca/gregorian.js
@@ -0,0 +1 @@
+({"dateFormat-short":"yy-MM-dd","dateFormatItem-MMdd":"MM-dd","dateFormat-medium":"yyyy-MM-dd","dateFormatItem-yyMMM":"MMM-yy","dateFormatItem-yM":"M/yyyy","field-dayperiod":"AM/PM","dateFormatItem-yQ":"Q yyyy","field-minute":"Minute","eraNames":["Before Christ","Anno Domini"],"dateFormatItem-MMMEd":"E, MMM d","field-weekday":"Day of the Week","dateFormatItem-yQQQ":"QQQ yyyy","days-standAlone-wide":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"dateFormatItem-M [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-gb/gregorian.js b/dojo/cldr/nls/en-gb/gregorian.js
new file mode 100644
index 0000000..c463e9e
--- /dev/null
+++ b/dojo/cldr/nls/en-gb/gregorian.js
@@ -0,0 +1 @@
+({"dateFormatItem-yyMMM":"MMM yy","dateFormatItem-Md":"d/M","dateFormatItem-yMEd":"EEE, d/M/yyyy","dateFormatItem-yyyyMMMM":"MMMM yyyy","timeFormat-full":"HH:mm:ss v","timeFormat-medium":"HH:mm:ss","dateFormatItem-MEd":"E, d/M","dateFormat-medium":"d MMM yyyy","dateFormatItem-MMdd":"dd/MM","dateFormatItem-yyyyMM":"MM/yyyy","dateFormat-full":"EEEE, d MMMM yyyy","timeFormat-long":"HH:mm:ss z","timeFormat-short":"HH:mm","dateFormat-short":"dd/MM/yyyy","dateFormatItem-MMMMd":"d MMMM","dateFo [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-gb/number.js b/dojo/cldr/nls/en-gb/number.js
new file mode 100644
index 0000000..748ea80
--- /dev/null
+++ b/dojo/cldr/nls/en-gb/number.js
@@ -0,0 +1 @@
+({"currencyFormat":"¤#,##0.00","group":",","percentSign":"%","exponential":"E","percentFormat":"#,##0%","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":".","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpacing-afterCur [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-us/currency.js b/dojo/cldr/nls/en-us/currency.js
new file mode 100644
index 0000000..ee32ca2
--- /dev/null
+++ b/dojo/cldr/nls/en-us/currency.js
@@ -0,0 +1 @@
+({"USD_symbol":"$","HKD_displayName":"Hong Kong Dollar","CHF_displayName":"Swiss Franc","CHF_symbol":"Fr.","JPY_symbol":"¥","HKD_symbol":"HK$","CAD_displayName":"Canadian Dollar","CNY_displayName":"Chinese Yuan Renminbi","AUD_displayName":"Australian Dollar","JPY_displayName":"Japanese Yen","CAD_symbol":"CA$","USD_displayName":"US Dollar","CNY_symbol":"RMB","GBP_displayName":"British Pound Sterling","GBP_symbol":"£","AUD_symbol":"A$","EUR_displayName":"Euro","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-us/number.js b/dojo/cldr/nls/en-us/number.js
new file mode 100644
index 0000000..6052262
--- /dev/null
+++ b/dojo/cldr/nls/en-us/number.js
@@ -0,0 +1 @@
+({"currencyFormat":"¤#,##0.00;(¤#,##0.00)","group":",","percentSign":"%","exponential":"E","percentFormat":"#,##0%","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":".","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpac [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/en/currency.js b/dojo/cldr/nls/en/currency.js
new file mode 100644
index 0000000..1be18a5
--- /dev/null
+++ b/dojo/cldr/nls/en/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"Hong Kong Dollar","CHF_displayName":"Swiss Franc","CHF_symbol":"Fr.","JPY_symbol":"¥","HKD_symbol":"HK$","CAD_displayName":"Canadian Dollar","CNY_displayName":"Chinese Yuan Renminbi","USD_symbol":"$","AUD_displayName":"Australian Dollar","JPY_displayName":"Japanese Yen","CAD_symbol":"CA$","USD_displayName":"US Dollar","CNY_symbol":"RMB","GBP_displayName":"British Pound Sterling","GBP_symbol":"£","AUD_symbol":"A$","EUR_displayName":"Euro","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/en/gregorian.js b/dojo/cldr/nls/en/gregorian.js
new file mode 100644
index 0000000..b8be379
--- /dev/null
+++ b/dojo/cldr/nls/en/gregorian.js
@@ -0,0 +1 @@
+({"dateFormatItem-yM":"M/yyyy","field-dayperiod":"AM/PM","dateFormatItem-yQ":"Q yyyy","field-minute":"Minute","eraNames":["Before Christ","Anno Domini"],"dateFormatItem-MMMEd":"E, MMM d","field-weekday":"Day of the Week","dateFormatItem-yQQQ":"QQQ yyyy","days-standAlone-wide":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"dateFormatItem-MMM":"LLL","months-standAlone-narrow":["J","F","M","A","M","J","J","A","S","O","N","D"],"field-era":"Era","field-hour":"Hour", [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/en/number.js b/dojo/cldr/nls/en/number.js
new file mode 100644
index 0000000..92b2e32
--- /dev/null
+++ b/dojo/cldr/nls/en/number.js
@@ -0,0 +1 @@
+({"group":",","percentSign":"%","exponential":"E","percentFormat":"#,##0%","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":".","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","currencyFormat":"¤#,##0.00;(¤#,##0.00)","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpac [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/es-es/gregorian.js b/dojo/cldr/nls/es-es/gregorian.js
new file mode 100644
index 0000000..0b251df
--- /dev/null
+++ b/dojo/cldr/nls/es-es/gregorian.js
@@ -0,0 +1 @@
+({"timeFormat-medium":"H:mm:ss","timeFormat-full":"HH'H'mm''ss\" v","timeFormat-short":"H:mm","months-format-narrow":["E","F","M","A","M","J","J","A","S","O","N","D"],"quarters-standAlone-narrow":["1","2","3","4"],"field-weekday":"día de la semana","dateFormatItem-yyQQQQ":"QQQQ 'de' yy","dateFormatItem-yQQQ":"QQQ yyyy","dateFormatItem-yMEd":"EEE d/M/yyyy","dateFormatItem-MMMEd":"E d MMM","eraNarrow":["a.C.","d.C."],"dateFormatItem-MMMdd":"dd-MMM","dateFormat-long":"d 'de' MMMM 'de' yyyy" [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/es-es/number.js b/dojo/cldr/nls/es-es/number.js
new file mode 100644
index 0000000..70e001f
--- /dev/null
+++ b/dojo/cldr/nls/es-es/number.js
@@ -0,0 +1 @@
+({"currencyFormat":"#,##0.00 ¤","decimalFormat":"#,##0.###","group":".","scientificFormat":"#E0","percentFormat":"#,##0%","decimal":",","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","infinity":"∞","list":";","percentSign":"%","minusSign":"-","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","nan":"NaN","nativeZeroDigit":"0","plusSign":"+","currencySpacing-afterCurrency-surroundingMatch":"[:digit:]","currencySpacin [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/es/currency.js b/dojo/cldr/nls/es/currency.js
new file mode 100644
index 0000000..40b4661
--- /dev/null
+++ b/dojo/cldr/nls/es/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"dólar de Hong Kong","CHF_displayName":"franco suizo","CHF_symbol":"SwF","HKD_symbol":"HK$","CAD_displayName":"dólar canadiense","CNY_displayName":"yuan renminbi chino","AUD_displayName":"dólar australiano","JPY_displayName":"yen japonés","CAD_symbol":"Can$","USD_displayName":"dólar estadounidense","CNY_symbol":"Y","GBP_displayName":"libra esterlina británica","AUD_symbol":"$A","EUR_displayName":"euro","USD_symbol":"US$","GBP_symbol":"UK£","JPY_symbol":"JP¥","EUR_symb [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/es/gregorian.js b/dojo/cldr/nls/es/gregorian.js
new file mode 100644
index 0000000..94de3ee
--- /dev/null
+++ b/dojo/cldr/nls/es/gregorian.js
@@ -0,0 +1 @@
+({"months-format-narrow":["E","F","M","A","M","J","J","A","S","O","N","D"],"quarters-standAlone-narrow":["1","2","3","4"],"field-weekday":"día de la semana","dateFormatItem-yyQQQQ":"QQQQ 'de' yy","dateFormatItem-yQQQ":"QQQ yyyy","dateFormatItem-yMEd":"EEE d/M/yyyy","dateFormatItem-MMMEd":"E d MMM","eraNarrow":["a.C.","d.C."],"dateFormatItem-MMMdd":"dd-MMM","dateFormat-long":"d 'de' MMMM 'de' yyyy","months-format-wide":["enero","febrero","marzo","abril","mayo","junio","julio","agosto","se [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/es/number.js b/dojo/cldr/nls/es/number.js
new file mode 100644
index 0000000..d878fb3
--- /dev/null
+++ b/dojo/cldr/nls/es/number.js
@@ -0,0 +1 @@
+({"decimalFormat":"#,##0.###","group":".","scientificFormat":"#E0","percentFormat":"#,##0%","currencyFormat":"¤ #,##0.00","decimal":",","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","infinity":"∞","list":";","percentSign":"%","minusSign":"-","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","nan":"NaN","nativeZeroDigit":"0","plusSign":"+","currencySpacing-afterCurrency-surroundingMatch":"[:digit:]","currencySpacin [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/fi/currency.js b/dojo/cldr/nls/fi/currency.js
new file mode 100644
index 0000000..635098a
--- /dev/null
+++ b/dojo/cldr/nls/fi/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"Hongkongin dollari","CHF_displayName":"Sveitsin frangi","JPY_symbol":"¥","CAD_displayName":"Kanadan dollari","CNY_displayName":"Kiinan yuan","USD_symbol":"$","AUD_displayName":"Australian dollari","JPY_displayName":"Japanin jeni","USD_displayName":"Yhdysvaltain dollari","GBP_displayName":"Englannin punta","GBP_symbol":"£","EUR_displayName":"euro","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/fi/gregorian.js b/dojo/cldr/nls/fi/gregorian.js
new file mode 100644
index 0000000..41a404e
--- /dev/null
+++ b/dojo/cldr/nls/fi/gregorian.js
@@ -0,0 +1 @@
+({"months-format-narrow":["T","H","M","H","T","K","H","E","S","L","M","J"],"quarters-standAlone-narrow":["1","2","3","4"],"field-weekday":"viikonpäivä","dateFormatItem-yQQQ":"QQQ yyyy","dateFormatItem-yMEd":"EEE d.M.yyyy","dateFormatItem-MMMEd":"E d. MMM","eraNarrow":["eKr.","jKr."],"dateFormat-long":"d. MMMM yyyy","months-format-wide":["tammikuuta","helmikuuta","maaliskuuta","huhtikuuta","toukokuuta","kesäkuuta","heinäkuuta","elokuuta","syyskuuta","lokakuuta","marraskuuta","joulukuuta"] [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/fi/number.js b/dojo/cldr/nls/fi/number.js
new file mode 100644
index 0000000..aa0fee6
--- /dev/null
+++ b/dojo/cldr/nls/fi/number.js
@@ -0,0 +1 @@
+({"group":" ","percentSign":"%","exponential":"E","percentFormat":"#,##0 %","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":",","nan":"epäluku","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","currencyFormat":"#,##0.00 ¤","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpacing-af [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr/currency.js b/dojo/cldr/nls/fr/currency.js
new file mode 100644
index 0000000..cb3b689
--- /dev/null
+++ b/dojo/cldr/nls/fr/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"dollar de Hong Kong","CHF_displayName":"franc suisse","CHF_symbol":"sFr.","JPY_symbol":"¥JP","HKD_symbol":"$HK","CAD_displayName":"dollar canadien","CNY_displayName":"yuan renminbi chinois","USD_symbol":"$US","AUD_displayName":"dollar australien","JPY_displayName":"yen japonais","CAD_symbol":"$Ca","USD_displayName":"dollar des États-Unis","CNY_symbol":"Ұ","GBP_displayName":"livre sterling","GBP_symbol":"£UK","AUD_symbol":"$A","EUR_displayName":"euro","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr/gregorian.js b/dojo/cldr/nls/fr/gregorian.js
new file mode 100644
index 0000000..2f9fcd3
--- /dev/null
+++ b/dojo/cldr/nls/fr/gregorian.js
@@ -0,0 +1 @@
+({"months-format-narrow":["J","F","M","A","M","J","J","A","S","O","N","D"],"quarters-standAlone-narrow":["1","2","3","4"],"field-weekday":"jour de la semaine","dateFormatItem-yyQQQQ":"QQQQ yy","dateFormatItem-yQQQ":"QQQ yyyy","dateFormatItem-yMEd":"EEE d/M/yyyy","dateFormatItem-MMMEd":"E d MMM","eraNarrow":["av. J.-C.","ap. J.-C."],"dateFormatItem-MMMdd":"dd MMM","dateFormat-long":"d MMMM yyyy","months-format-wide":["janvier","février","mars","avril","mai","juin","juillet","août","septem [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr/number.js b/dojo/cldr/nls/fr/number.js
new file mode 100644
index 0000000..f9a71ab
--- /dev/null
+++ b/dojo/cldr/nls/fr/number.js
@@ -0,0 +1 @@
+({"group":" ","percentSign":"%","exponential":"E","percentFormat":"#,##0 %","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":",","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","currencyFormat":"#,##0.00 ¤","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpacing-afterC [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/gregorian.js b/dojo/cldr/nls/gregorian.js
new file mode 100644
index 0000000..fa60244
--- /dev/null
+++ b/dojo/cldr/nls/gregorian.js
@@ -0,0 +1 @@
+({"months-format-narrow":["1","2","3","4","5","6","7","8","9","10","11","12"],"quarters-standAlone-narrow":["1","2","3","4"],"field-weekday":"Day of the Week","dateFormatItem-yQQQ":"yyyy QQQ","dateFormatItem-yMEd":"EEE, yyyy-M-d","dateFormatItem-MMMEd":"E MMM d","eraNarrow":["BCE","CE"],"dateTimeFormats-appendItem-Day-Of-Week":"{0} {1}","dateFormat-long":"yyyy MMMM d","months-format-wide":["1","2","3","4","5","6","7","8","9","10","11","12"],"dateFormat-full":"EEEE, yyyy MMMM dd","dateFor [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/he/currency.js b/dojo/cldr/nls/he/currency.js
new file mode 100644
index 0000000..93a19fa
--- /dev/null
+++ b/dojo/cldr/nls/he/currency.js
@@ -0,0 +1 @@
+({"EUR_displayName":"אירו","CHF_displayName":"פרנק שוויצרי","HKD_displayName":"דולר הונג קונגי","CAD_displayName":"דולר קנדי","GBP_displayName":"לירה שטרלינג","JPY_displayName":"ין יפני","AUD_displayName":"דולר אוסטרלי","USD_displayName":"דולר אמריקאי","USD_symbol":"US$","GBP_symbol":"UK£","JPY_symbol":"JP¥","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/he/gregorian.js b/dojo/cldr/nls/he/gregorian.js
new file mode 100644
index 0000000..ccd13f1
--- /dev/null
+++ b/dojo/cldr/nls/he/gregorian.js
@@ -0,0 +1 @@
+({"quarters-standAlone-narrow":["1","2","3","4"],"field-weekday":"יום בשבוע","dateFormatItem-yQQQ":"yyyy QQQ","dateFormatItem-yMEd":"EEE, yyyy-M-d","dateFormatItem-MMMEd":"E d MMM","eraNarrow":["לפנה״ס","לסה״נ"],"dateFormat-long":"d MMMM yyyy","months-format-wide":["ינואר","פברואר","מרץ","אפריל","מאי","יוני","יולי","אוגוסט","ספטמבר","אוקטובר","נובמבר","דצמבר"],"dateFormat-full":"EEEE d MMMM yyyy","dateFormatItem-Md":"d/M","field-era":"תקופה","dateFormatItem-yM":"yyyy-M","months-standAlon [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/he/hebrew.js b/dojo/cldr/nls/he/hebrew.js
new file mode 100644
index 0000000..158669a
--- /dev/null
+++ b/dojo/cldr/nls/he/hebrew.js
@@ -0,0 +1 @@
+({"eraAbbr":["לבה\"ע"],"patternChars":"GanjkHmsSEDFwWxhKzAeugXZvcL","months-format-wide":["תשרי","חשון","כסלו","טבת","שבט","אדר ראשון","אדר שני","ניסן","אייר","סיון","תמוז","אב","אלול"],"am":"לפנה\"צ","pm":"אחה\"צ","months-standAlone-abbr at localeAlias106":{"bundle":"hebrew","target":"months-format-wide"},"months-format-abbr at localeAlias103":{"bundle":"hebrew","target":"months-format-wide"},"months-format-narrow":["1","2","3","4","5","6","7","8","9","10","11","12","13"],"quarters-standAlone [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/he/number.js b/dojo/cldr/nls/he/number.js
new file mode 100644
index 0000000..23e6fa4
--- /dev/null
+++ b/dojo/cldr/nls/he/number.js
@@ -0,0 +1 @@
+({"group":",","percentSign":"%","exponential":"E","percentFormat":"#,##0%","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":".","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","currencyFormat":"#,##0.00 ¤","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpacing-afterCu [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/hebrew.js b/dojo/cldr/nls/hebrew.js
new file mode 100644
index 0000000..da9132c
--- /dev/null
+++ b/dojo/cldr/nls/hebrew.js
@@ -0,0 +1 @@
+({"months-standAlone-abbr at localeAlias106":{"bundle":"hebrew","target":"months-format-wide"},"months-format-abbr at localeAlias103":{"bundle":"hebrew","target":"months-format-wide"},"months-format-narrow":["1","2","3","4","5","6","7","8","9","10","11","12","13"],"quarters-standAlone-narrow":["1","2","3","4"],"dateFormatItem-yQQQ":"yyyy QQQ","quarters at localeAlias114":{"bundle":"gregorian","target":"quarters"},"dateFormatItem-yMEd":"EEE, yyyy-M-d","dateFormatItem-MMMEd":"E MMM d","eraNarrow":[ [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/hu/currency.js b/dojo/cldr/nls/hu/currency.js
new file mode 100644
index 0000000..e979d4b
--- /dev/null
+++ b/dojo/cldr/nls/hu/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"Hongkongi dollár","CHF_displayName":"Svájci frank","CHF_symbol":"SwF","HKD_symbol":"HK$","CAD_displayName":"Kanadai dollár","CNY_displayName":"Kínai jüan renminbi","USD_symbol":"USD","AUD_displayName":"Ausztrál dollár","JPY_displayName":"Japán jen","CAD_symbol":"Can$","USD_displayName":"USA dollár","CNY_symbol":"Y","GBP_displayName":"Brit font sterling","AUD_symbol":"$A","EUR_displayName":"Euro","GBP_symbol":"UK£","JPY_symbol":"JP¥","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/hu/gregorian.js b/dojo/cldr/nls/hu/gregorian.js
new file mode 100644
index 0000000..0897bb8
--- /dev/null
+++ b/dojo/cldr/nls/hu/gregorian.js
@@ -0,0 +1 @@
+({"field-dayperiod":"napszak","field-minute":"perc","eraNames":["időszámításunk előtt","időszámításunk szerint"],"field-weekday":"hét napja","dateFormatItem-MMdd":"MM.dd.","days-standAlone-wide":["vasárnap","hétfő","kedd","szerda","csütörtök","péntek","szombat"],"dateFormatItem-MMM":"LLL","patternChars":"GanjkHmsSEDFwWxhKzAeugXZvcL","months-standAlone-narrow":["J","F","M","Á","M","J","J","A","S","O","N","D"],"field-era":"éra","field-hour":"óra","quarters-standAlone-abbr":["N1","N2","N3", [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/hu/number.js b/dojo/cldr/nls/hu/number.js
new file mode 100644
index 0000000..472a2c8
--- /dev/null
+++ b/dojo/cldr/nls/hu/number.js
@@ -0,0 +1 @@
+({"group":" ","percentSign":"%","exponential":"E","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":",","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","currencyFormat":"#,##0.00 ¤","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpacing-afterCurrency-surroundingMatch": [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/islamic-civil.js b/dojo/cldr/nls/islamic-civil.js
new file mode 100644
index 0000000..e0373ec
--- /dev/null
+++ b/dojo/cldr/nls/islamic-civil.js
@@ -0,0 +1 @@
+({"months-format-narrow":["1","2","3","4","5","6","7","8","9","10","11","12"],"quarters-standAlone-narrow":["1","2","3","4"],"dateFormatItem-yQQQ":"yyyy QQQ","dateFormatItem-yMEd":"EEE, yyyy-M-d","dateFormatItem-MMMEd":"E MMM d","eraNarrow":["AH"],"dateTimeFormats-appendItem-Day-Of-Week":"{0} {1}","months-standAlone-abbr at localeAlias172":{"bundle":"islamic","target":"months-format-abbr"},"months-standAlone-abbr at localeAlias173":{"bundle":"islamic","target":"months-format-wide"},"dateFormat [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/islamic.js b/dojo/cldr/nls/islamic.js
new file mode 100644
index 0000000..b350e09
--- /dev/null
+++ b/dojo/cldr/nls/islamic.js
@@ -0,0 +1 @@
+({"months-format-narrow":["1","2","3","4","5","6","7","8","9","10","11","12"],"quarters-standAlone-narrow":["1","2","3","4"],"dateFormatItem-yQQQ":"yyyy QQQ","dateFormatItem-yMEd":"EEE, yyyy-M-d","dateFormatItem-MMMEd":"E MMM d","eraNarrow":["AH"],"dateTimeFormats-appendItem-Day-Of-Week":"{0} {1}","dateFormat-long":"yyyy MMMM d","months-format-wide":["Muharram","Safar","Rabiʻ I","Rabiʻ II","Jumada I","Jumada II","Rajab","Shaʻban","Ramadan","Shawwal","Dhuʻl-Qiʻdah","Dhuʻl-Hijjah"],"days-s [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/it-it/gregorian.js b/dojo/cldr/nls/it-it/gregorian.js
new file mode 100644
index 0000000..6666338
--- /dev/null
+++ b/dojo/cldr/nls/it-it/gregorian.js
@@ -0,0 +1 @@
+({"timeFormat-long":"H:mm:ss z","dateFormatItem-yM":"M/yyyy","field-dayperiod":"periodo del giorno","dateFormatItem-yQ":"Q-yyyy","field-minute":"minuto","eraNames":["a.C.","d.C"],"dateFormatItem-MMMEd":"EEE d MMM","field-weekday":"giorno della settimana","dateFormatItem-yQQQ":"QQQ yyyy","dateFormatItem-MMdd":"dd/MM","days-standAlone-wide":["Domenica","Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato"],"dateFormatItem-MMM":"LLL","months-standAlone-narrow":["G","F","M","A","M","G" [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/it/currency.js b/dojo/cldr/nls/it/currency.js
new file mode 100644
index 0000000..375ec67
--- /dev/null
+++ b/dojo/cldr/nls/it/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"Dollaro di Hong Kong","CHF_displayName":"Franco Svizzero","CHF_symbol":"SFr.","CAD_displayName":"Dollaro Canadese","CNY_displayName":"Renmimbi Cinese","AUD_displayName":"Dollaro Australiano","JPY_displayName":"Yen Giapponese","USD_displayName":"Dollaro Statunitense","GBP_displayName":"Sterlina Inglese","EUR_displayName":"Euro","USD_symbol":"US$","GBP_symbol":"UK£","JPY_symbol":"JP¥","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/it/gregorian.js b/dojo/cldr/nls/it/gregorian.js
new file mode 100644
index 0000000..8a6289e
--- /dev/null
+++ b/dojo/cldr/nls/it/gregorian.js
@@ -0,0 +1 @@
+({"dateFormatItem-yM":"M/yyyy","field-dayperiod":"periodo del giorno","dateFormatItem-yQ":"Q-yyyy","field-minute":"minuto","eraNames":["a.C.","d.C"],"dateFormatItem-MMMEd":"EEE d MMM","field-weekday":"giorno della settimana","dateFormatItem-yQQQ":"QQQ yyyy","dateFormatItem-MMdd":"dd/MM","days-standAlone-wide":["Domenica","Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato"],"dateFormatItem-MMM":"LLL","months-standAlone-narrow":["G","F","M","A","M","G","L","A","S","O","N","D"],"fie [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/it/number.js b/dojo/cldr/nls/it/number.js
new file mode 100644
index 0000000..d878fb3
--- /dev/null
+++ b/dojo/cldr/nls/it/number.js
@@ -0,0 +1 @@
+({"decimalFormat":"#,##0.###","group":".","scientificFormat":"#E0","percentFormat":"#,##0%","currencyFormat":"¤ #,##0.00","decimal":",","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","infinity":"∞","list":";","percentSign":"%","minusSign":"-","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","nan":"NaN","nativeZeroDigit":"0","plusSign":"+","currencySpacing-afterCurrency-surroundingMatch":"[:digit:]","currencySpacin [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja-jp/number.js b/dojo/cldr/nls/ja-jp/number.js
new file mode 100644
index 0000000..4329dc1
--- /dev/null
+++ b/dojo/cldr/nls/ja-jp/number.js
@@ -0,0 +1 @@
+({"currencyFormat":"¤#,##0.00","decimalFormat":"#,##0.###","group":",","scientificFormat":"#E0","percentFormat":"#,##0%","decimal":".","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","infinity":"∞","list":";","percentSign":"%","minusSign":"-","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","nan":"NaN","nativeZeroDigit":"0","plusSign":"+","currencySpacing-afterCurrency-surroundingMatch":"[:digit:]","currencySpacing [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja/currency.js b/dojo/cldr/nls/ja/currency.js
new file mode 100644
index 0000000..76cd3d9
--- /dev/null
+++ b/dojo/cldr/nls/ja/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"香港ドル","CHF_displayName":"スイス フラン","JPY_symbol":"¥","CAD_displayName":"カナダ ドル","CNY_displayName":"中国人民元","AUD_displayName":"オーストラリア ドル","JPY_displayName":"日本円","USD_displayName":"米ドル","CNY_symbol":"元","GBP_displayName":"英国ポンド","EUR_displayName":"ユーロ","USD_symbol":"US$","GBP_symbol":"UK£","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja/gregorian.js b/dojo/cldr/nls/ja/gregorian.js
new file mode 100644
index 0000000..1322b2b
--- /dev/null
+++ b/dojo/cldr/nls/ja/gregorian.js
@@ -0,0 +1 @@
+({"dateFormatItem-yM":"y/M","field-dayperiod":"午前/午後","dateFormatItem-yQ":"y/Q","dateFormatItem-GGGGyMd":"GGGGy年M月d日","field-minute":"分","eraNames":["紀元前","西暦"],"dateFormatItem-MMMEd":"M月d日(E)","field-weekday":"曜日","dateFormatItem-yQQQ":"yyyyQQQ","dateFormatItem-MMdd":"MM/dd","days-standAlone-wide":["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],"dateFormatItem-MMM":"LLL","patternChars":"GanjkHmsSEDFwWxhKzAeugXZvcL","months-standAlone-narrow":["1","2","3","4","5","6","7","8","9","10","11","1 [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja/number.js b/dojo/cldr/nls/ja/number.js
new file mode 100644
index 0000000..90d87b9
--- /dev/null
+++ b/dojo/cldr/nls/ja/number.js
@@ -0,0 +1 @@
+({"decimalFormat":"#,##0.###","group":",","scientificFormat":"#E0","percentFormat":"#,##0%","currencyFormat":"¤#,##0.00","decimal":".","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","infinity":"∞","list":";","percentSign":"%","minusSign":"-","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","nan":"NaN","nativeZeroDigit":"0","plusSign":"+","currencySpacing-afterCurrency-surroundingMatch":"[:digit:]","currencySpacing [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/ko-kr/gregorian.js b/dojo/cldr/nls/ko-kr/gregorian.js
new file mode 100644
index 0000000..9a375b3
--- /dev/null
+++ b/dojo/cldr/nls/ko-kr/gregorian.js
@@ -0,0 +1 @@
+({"timeFormat-medium":"a h:mm:ss","timeFormat-short":"a h:mm","months-format-narrow":["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],"quarters-standAlone-narrow":["1","2","3","4"],"field-weekday":"요일","dateFormatItem-yQQQ":"yyyy년 QQQ","dateFormatItem-yMEd":"yyyy. M. d. EEE","dateFormatItem-MMMEd":"MMM d일 (E)","eraNarrow":["기원전","서기"],"dateFormat-long":"yyyy년 M월 d일","months-format-wide":["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],"dateFormat-full":"yy [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/ko-kr/number.js b/dojo/cldr/nls/ko-kr/number.js
new file mode 100644
index 0000000..748ea80
--- /dev/null
+++ b/dojo/cldr/nls/ko-kr/number.js
@@ -0,0 +1 @@
+({"currencyFormat":"¤#,##0.00","group":",","percentSign":"%","exponential":"E","percentFormat":"#,##0%","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":".","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpacing-afterCur [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/ko/currency.js b/dojo/cldr/nls/ko/currency.js
new file mode 100644
index 0000000..bea8d9d
--- /dev/null
+++ b/dojo/cldr/nls/ko/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"홍콩 달러","CHF_displayName":"스위스 프랑","JPY_symbol":"¥","HKD_symbol":"HK$","CAD_displayName":"캐나다 달러","CNY_displayName":"중국 위안 인민폐","AUD_displayName":"호주 달러","JPY_displayName":"일본 엔","CAD_symbol":"Can$","USD_displayName":"미국 달러","CNY_symbol":"¥","GBP_displayName":"영국령 파운드 스털링","AUD_symbol":"A$","EUR_displayName":"유로화","USD_symbol":"US$","GBP_symbol":"UK£","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/ko/gregorian.js b/dojo/cldr/nls/ko/gregorian.js
new file mode 100644
index 0000000..bb049e6
--- /dev/null
+++ b/dojo/cldr/nls/ko/gregorian.js
@@ -0,0 +1 @@
+({"months-format-narrow":["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],"quarters-standAlone-narrow":["1","2","3","4"],"field-weekday":"요일","dateFormatItem-yQQQ":"yyyy년 QQQ","dateFormatItem-yMEd":"yyyy. M. d. EEE","dateFormatItem-MMMEd":"MMM d일 (E)","eraNarrow":["기원전","서기"],"dateFormat-long":"yyyy년 M월 d일","months-format-wide":["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],"dateFormat-full":"yyyy년 M월 d일 EEEE","dateFormatItem-Md":"M. d.","field-era":"연호" [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/ko/number.js b/dojo/cldr/nls/ko/number.js
new file mode 100644
index 0000000..b155b91
--- /dev/null
+++ b/dojo/cldr/nls/ko/number.js
@@ -0,0 +1 @@
+({"group":",","percentSign":"%","exponential":"E","percentFormat":"#,##0%","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":".","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","currencyFormat":"¤#,##0.00","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpacing-afterCur [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/nb/currency.js b/dojo/cldr/nls/nb/currency.js
new file mode 100644
index 0000000..0be3327
--- /dev/null
+++ b/dojo/cldr/nls/nb/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"Hongkong-dollar","CHF_displayName":"sveitsiske franc","JPY_symbol":"JPY","CAD_displayName":"kanadiske dollar","CNY_displayName":"kinesiske yuan renminbi","USD_symbol":"USD","AUD_displayName":"australske dollar","JPY_displayName":"japanske yen","USD_displayName":"amerikanske dollar","EUR_symbol":"EUR","GBP_displayName":"britiske pund sterling","GBP_symbol":"GBP","EUR_displayName":"euro"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/nb/gregorian.js b/dojo/cldr/nls/nb/gregorian.js
new file mode 100644
index 0000000..3cec677
--- /dev/null
+++ b/dojo/cldr/nls/nb/gregorian.js
@@ -0,0 +1 @@
+({"dateFormatItem-yM":"M yyyy","field-dayperiod":"AM/PM","dateFormatItem-yQ":"Q yyyy","field-minute":"minutt","eraNames":["f.Kr.","e.Kr."],"dateFormatItem-MMMEd":"E d. MMM","field-weekday":"ukedag","dateFormatItem-yQQQ":"QQQ yyyy","dateFormatItem-MMdd":"dd.MM","days-standAlone-wide":["søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag"],"dateFormatItem-MMM":"LLL","months-standAlone-narrow":["J","F","M","A","M","J","J","A","S","O","N","D"],"field-era":"tidsalder","field-hour": [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/nb/number.js b/dojo/cldr/nls/nb/number.js
new file mode 100644
index 0000000..2904b4b
--- /dev/null
+++ b/dojo/cldr/nls/nb/number.js
@@ -0,0 +1 @@
+({"group":" ","percentSign":"%","exponential":"E","percentFormat":"#,##0 %","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":",","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","currencyFormat":"¤ #,##0.00","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpacing-afterC [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/nl/currency.js b/dojo/cldr/nls/nl/currency.js
new file mode 100644
index 0000000..940d0a2
--- /dev/null
+++ b/dojo/cldr/nls/nl/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"Hongkongse dollar","CHF_displayName":"Zwitserse franc","CHF_symbol":"SwF","HKD_symbol":"HK$","CAD_displayName":"Canadese dollar","CNY_displayName":"Chinese yuan renminbi","USD_symbol":"USD","AUD_displayName":"Australische dollar","JPY_displayName":"Japanse yen","CAD_symbol":"Can$","USD_displayName":"Amerikaanse dollar","CNY_symbol":"Y","GBP_displayName":"Brits pond sterling","GBP_symbol":"GBP","AUD_symbol":"$A","EUR_displayName":"euro","JPY_symbol":"JP¥","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/nl/gregorian.js b/dojo/cldr/nls/nl/gregorian.js
new file mode 100644
index 0000000..29ffd04
--- /dev/null
+++ b/dojo/cldr/nls/nl/gregorian.js
@@ -0,0 +1 @@
+({"dateFormatItem-yM":"M-yyyy","field-dayperiod":"AM/PM","dateFormatItem-yQ":"Q yyyy","field-minute":"Minuut","eraNames":["Voor Christus","Anno Domini"],"dateFormatItem-MMMEd":"E d MMM","field-weekday":"Dag van de week","dateFormatItem-yQQQ":"QQQ yyyy","dateFormatItem-MMdd":"dd-MM","days-standAlone-wide":["zondag","maandag","dinsdag","woensdag","donderdag","vrijdag","zaterdag"],"dateFormatItem-MMM":"LLL","months-standAlone-narrow":["J","F","M","A","M","J","J","A","S","O","N","D"],"field- [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/nl/number.js b/dojo/cldr/nls/nl/number.js
new file mode 100644
index 0000000..6e47a0a
--- /dev/null
+++ b/dojo/cldr/nls/nl/number.js
@@ -0,0 +1 @@
+({"group":".","percentSign":"%","exponential":"E","percentFormat":"#,##0%","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":",","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","currencyFormat":"¤ #,##0.00;¤ #,##0.00-","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpa [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/number.js b/dojo/cldr/nls/number.js
new file mode 100644
index 0000000..8f76216
--- /dev/null
+++ b/dojo/cldr/nls/number.js
@@ -0,0 +1 @@
+({"scientificFormat":"#E0","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","infinity":"∞","list":";","percentSign":"%","minusSign":"-","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","nan":"NaN","nativeZeroDigit":"0","plusSign":"+","currencySpacing-afterCurrency-surroundingMatch":"[:digit:]","currencyFormat":"¤ #,##0.00","currencySpacing-beforeCurrency-currencyMatch":"[:letter:]","perMille":"‰","group":",","percen [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/pl/currency.js b/dojo/cldr/nls/pl/currency.js
new file mode 100644
index 0000000..f7356a7
--- /dev/null
+++ b/dojo/cldr/nls/pl/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"dolar hongkoński","CHF_displayName":"frank szwajcarski","CHF_symbol":"SwF","JPY_symbol":"¥","HKD_symbol":"HK$","CAD_displayName":"dolar kanadyjski","CNY_displayName":"juan renminbi","USD_symbol":"$","AUD_displayName":"dolar australijski","JPY_displayName":"jen japoński","CAD_symbol":"Can$","USD_displayName":"dolar amerykański ","CNY_symbol":"Y","GBP_displayName":"funt szterling","GBP_symbol":"£","AUD_symbol":"$A","EUR_displayName":"euro","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/pl/gregorian.js b/dojo/cldr/nls/pl/gregorian.js
new file mode 100644
index 0000000..9cfd94c
--- /dev/null
+++ b/dojo/cldr/nls/pl/gregorian.js
@@ -0,0 +1 @@
+({"dateFormatItem-yM":"yyyy-M","field-dayperiod":"Dayperiod","dateFormatItem-yQ":"yyyy Q","field-minute":"Minuta","eraNames":["p.n.e.","n.e."],"dateFormatItem-MMMEd":"d MMM E","field-weekday":"Dzień tygodnia","dateFormatItem-yQQQ":"yyyy QQQ","dateFormatItem-MMdd":"MM-dd","days-standAlone-wide":["niedziela","poniedziałek","wtorek","środa","czwartek","piątek","sobota"],"dateFormatItem-MMM":"LLL","months-standAlone-narrow":["s","l","m","k","m","c","l","s","w","p","l","g"],"field-era":"Era", [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/pl/number.js b/dojo/cldr/nls/pl/number.js
new file mode 100644
index 0000000..ad7c869
--- /dev/null
+++ b/dojo/cldr/nls/pl/number.js
@@ -0,0 +1 @@
+({"group":" ","percentSign":"%","exponential":"E","percentFormat":"#,##0%","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":",","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","currencyFormat":"#,##0.00 ¤","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpacing-afterCu [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt-br/gregorian.js b/dojo/cldr/nls/pt-br/gregorian.js
new file mode 100644
index 0000000..88b8cb0
--- /dev/null
+++ b/dojo/cldr/nls/pt-br/gregorian.js
@@ -0,0 +1 @@
+({"field-hour":"Hora","field-dayperiod":"Período do dia","field-minute":"Minuto","timeFormat-full":"HH'h'mm'min'ss's' z","field-week":"Semana","field-weekday":"Dia da semana","field-second":"Segundo","dateFormat-medium":"dd/MM/yyyy","field-day":"Dia","timeFormat-long":"H'h'm'min's's' z","field-month":"Mês","field-year":"Ano","dateFormat-short":"dd/MM/yy","field-zone":"Fuso","months-format-narrow":["J","F","M","A","M","J","J","A","S","O","N","D"],"quarters-standAlone-narrow":["1","2","3", [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt-pt/gregorian.js b/dojo/cldr/nls/pt-pt/gregorian.js
new file mode 100644
index 0000000..f308b11
--- /dev/null
+++ b/dojo/cldr/nls/pt-pt/gregorian.js
@@ -0,0 +1 @@
+({"quarters-standAlone-wide":["1.º trimestre","2.º trimestre","3.º trimestre","4.º trimestre"],"quarters-format-abbr":["1.º trimestre","2.º trimestre","3.º trimestre","4.º trimestre"],"dateFormat-medium":"yyyy/MM/dd","dateFormatItem-MMMEd":"E d MMM","quarters-standAlone-abbr":["1.º trimestre","2.º trimestre","3.º trimestre","4.º trimestre"],"pm":"Depois do meio-dia","timeFormat-full":"HH'H'mm'm'ss's' v","dateFormatItem-Md":"d-M","months-standAlone-wide":["Janeiro","Fevereiro","Março","Ab [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt-pt/number.js b/dojo/cldr/nls/pt-pt/number.js
new file mode 100644
index 0000000..e06fd94
--- /dev/null
+++ b/dojo/cldr/nls/pt-pt/number.js
@@ -0,0 +1 @@
+({"currencyFormat":"#,##0.00 ¤","group":" ","percentSign":"%","exponential":"E","percentFormat":"#,##0%","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":",","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpacing-afterCu [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt/currency.js b/dojo/cldr/nls/pt/currency.js
new file mode 100644
index 0000000..7643be6
--- /dev/null
+++ b/dojo/cldr/nls/pt/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"Dólar de Hong Kong","CHF_displayName":"Franco suíço","CHF_symbol":"SwF","JPY_symbol":"¥","HKD_symbol":"HK$","CAD_displayName":"Dólar canadense","CNY_displayName":"Yuan Renminbi chinês","AUD_displayName":"Dólar australiano","JPY_displayName":"Iene japonês","CAD_symbol":"Can$","USD_displayName":"Dólar norte-americano","CNY_symbol":"Y","GBP_displayName":"Libra esterlina britânica","GBP_symbol":"£","AUD_symbol":"$A","EUR_displayName":"Euro","USD_symbol":"US$","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt/gregorian.js b/dojo/cldr/nls/pt/gregorian.js
new file mode 100644
index 0000000..14276f1
--- /dev/null
+++ b/dojo/cldr/nls/pt/gregorian.js
@@ -0,0 +1 @@
+({"months-format-narrow":["J","F","M","A","M","J","J","A","S","O","N","D"],"quarters-standAlone-narrow":["1","2","3","4"],"field-weekday":"Dia da semana","dateFormatItem-yQQQ":"yyyy QQQ","dateFormatItem-yMEd":"EEE, dd/MM/yyyy","dateFormatItem-MMMEd":"EEE, d MMM","eraNarrow":["a.C.","d.C."],"dateFormat-long":"d 'de' MMMM 'de' yyyy","months-format-wide":["janeiro","fevereiro","março","abril","maio","junho","julho","agosto","setembro","outubro","novembro","dezembro"],"dateFormat-full":"EEEE [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt/number.js b/dojo/cldr/nls/pt/number.js
new file mode 100644
index 0000000..f10fcfa
--- /dev/null
+++ b/dojo/cldr/nls/pt/number.js
@@ -0,0 +1 @@
+({"group":".","percentSign":"%","exponential":"E","percentFormat":"#,##0%","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":",","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","currencyFormat":"¤#,##0.00;(¤#,##0.00)","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpac [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/ru/currency.js b/dojo/cldr/nls/ru/currency.js
new file mode 100644
index 0000000..890bb19
--- /dev/null
+++ b/dojo/cldr/nls/ru/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"Гонконгский доллар","CHF_displayName":"Швейцарский франк","CHF_symbol":"SwF","JPY_symbol":"¥","HKD_symbol":"HK$","CAD_displayName":"Канадский доллар","CNY_displayName":"Юань Ренминби","USD_symbol":"$","AUD_displayName":"Австралийский доллар","JPY_displayName":"Японская иена","CAD_symbol":"Can$","USD_displayName":"Доллар США","CNY_symbol":"Y","GBP_displayName":"Английский фунт стерлингов","GBP_symbol":"£","AUD_symbol":"$A","EUR_displayName":"Евро","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/ru/gregorian.js b/dojo/cldr/nls/ru/gregorian.js
new file mode 100644
index 0000000..3725286
--- /dev/null
+++ b/dojo/cldr/nls/ru/gregorian.js
@@ -0,0 +1 @@
+({"months-format-narrow":["Я","Ф","М","А","М","И","И","А","С","О","Н","Д"],"quarters-standAlone-narrow":["1","2","3","4"],"field-weekday":"День недели","dateFormatItem-yQQQ":"yyyy QQQ","dateFormatItem-yMEd":"EEE, yyyy-M-d","dateFormatItem-yyyyLLLL":"LLLL yyyy","dateFormatItem-MMMEd":"E MMM d","eraNarrow":["до н.э.","н.э."],"dateFormat-long":"d MMMM yyyy 'г'.","months-format-wide":["января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"]," [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/ru/number.js b/dojo/cldr/nls/ru/number.js
new file mode 100644
index 0000000..55fbdf8
--- /dev/null
+++ b/dojo/cldr/nls/ru/number.js
@@ -0,0 +1 @@
+({"group":" ","percentSign":"%","exponential":"E","percentFormat":"#,##0 %","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":",","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","currencyFormat":"#,##0.00 ¤","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","nan":"NaN","currencySpacing-afterC [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/sk/currency.js b/dojo/cldr/nls/sk/currency.js
new file mode 100644
index 0000000..c7583ac
--- /dev/null
+++ b/dojo/cldr/nls/sk/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"Hong Kongský dolár","CHF_displayName":"Švajčiarský frank","CHF_symbol":"SwF","HKD_symbol":"HK$","CAD_displayName":"Kanadský dolár","CNY_displayName":"Čínsky Yuan Renminbi","AUD_displayName":"Austrálsky dolár","JPY_displayName":"Japonský yen","CAD_symbol":"Can$","USD_displayName":"US dolár","CNY_symbol":"Y","GBP_displayName":"Britská libra","AUD_symbol":"$A","EUR_displayName":"Euro","USD_symbol":"US$","GBP_symbol":"UK£","JPY_symbol":"JP¥","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/sk/gregorian.js b/dojo/cldr/nls/sk/gregorian.js
new file mode 100644
index 0000000..701ab3d
--- /dev/null
+++ b/dojo/cldr/nls/sk/gregorian.js
@@ -0,0 +1 @@
+({"field-minute":"minúta","eraNames":["pred n.l.","n.l."],"field-weekday":"deň v týždni","days-standAlone-wide":["Nedeľa","Pondelok","Utorok","Streda","Štvrtok","Piatok","Sobota"],"patternChars":"GanjkHmsSEDFwWxhKzAeugXZvcL","months-standAlone-narrow":["j","f","m","a","m","j","j","a","s","o","n","d"],"field-era":"éra","field-hour":"hodina","quarters-standAlone-abbr":["1. štvrťrok","2. štvrťrok","3. štvrťrok","4. štvrťrok"],"timeFormat-full":"H:mm:ss v","months-standAlone-abbr":["jan","fe [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/sk/number.js b/dojo/cldr/nls/sk/number.js
new file mode 100644
index 0000000..f4095fd
--- /dev/null
+++ b/dojo/cldr/nls/sk/number.js
@@ -0,0 +1 @@
+({"currencyFormat":"#,##0.00 ¤","group":" ","decimal":",","scientificFormat":"#E0","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","infinity":"∞","list":";","percentSign":"%","minusSign":"-","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","nan":"NaN","nativeZeroDigit":"0","plusSign":"+","currencySpacing-afterCurrency-surroundingMatch":"[:digit:]","currencySpacing-beforeCurrency-currencyMatch":"[:letter:]","perMill [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/sl/currency.js b/dojo/cldr/nls/sl/currency.js
new file mode 100644
index 0000000..429c01a
--- /dev/null
+++ b/dojo/cldr/nls/sl/currency.js
@@ -0,0 +1 @@
+({"EUR_displayName":"Evro","GBP_displayName":"Britanski Funt Sterling","JPY_displayName":"Japonski Jen","CNY_displayName":"Kitajski Yuan Renminbi","USD_displayName":"Ameriški Dolar","USD_symbol":"US$","GBP_symbol":"UK£","JPY_symbol":"JP¥","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/sl/gregorian.js b/dojo/cldr/nls/sl/gregorian.js
new file mode 100644
index 0000000..2c034ab
--- /dev/null
+++ b/dojo/cldr/nls/sl/gregorian.js
@@ -0,0 +1 @@
+({"dateFormat-medium":"d.M.yyyy","eraNarrow":["pr.n.š.","po Kr."],"months-format-narrow":["j","f","m","a","m","j","j","a","s","o","n","d"],"timeFormat-full":"H:mm:ss v","months-standAlone-narrow":["j","f","m","a","m","j","j","a","s","o","n","d"],"months-standAlone-wide":["januar","februar","marec","april","maj","junij","julij","avgust","september","oktober","november","december"],"eraNames":["pr.n.š.","po Kr."],"days-standAlone-narrow":["n","p","t","s","č","p","s"],"dateFormatItem-MMMMd" [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/sl/number.js b/dojo/cldr/nls/sl/number.js
new file mode 100644
index 0000000..4179e25
--- /dev/null
+++ b/dojo/cldr/nls/sl/number.js
@@ -0,0 +1 @@
+({"group":".","percentSign":"%","exponential":"E","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":",","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","plusSign":"+","scientificFormat":"#E0","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpacing-afterCurrency-surroundingMatch":"[:digit:]","currencyFormat":"¤ #,##0.00","currencySpacing [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/sv/currency.js b/dojo/cldr/nls/sv/currency.js
new file mode 100644
index 0000000..0c00416
--- /dev/null
+++ b/dojo/cldr/nls/sv/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"Hongkong-dollar","CHF_displayName":"schweizisk franc","CHF_symbol":"SwF","HKD_symbol":"HK$","CAD_displayName":"kanadensisk dollar","CNY_displayName":"kinesisk yuan renminbi","AUD_displayName":"australisk dollar","JPY_displayName":"japansk yen","CAD_symbol":"Can$","USD_displayName":"US-dollar","CNY_symbol":"Y","GBP_displayName":"brittiskt pund sterling","AUD_symbol":"$A","EUR_displayName":"euro","USD_symbol":"US$","GBP_symbol":"UK£","JPY_symbol":"JP¥","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/sv/gregorian.js b/dojo/cldr/nls/sv/gregorian.js
new file mode 100644
index 0000000..e218186
--- /dev/null
+++ b/dojo/cldr/nls/sv/gregorian.js
@@ -0,0 +1 @@
+({"months-format-narrow":["J","F","M","A","M","J","J","A","S","O","N","D"],"quarters-standAlone-narrow":["1","2","3","4"],"field-weekday":"veckodag","dateFormatItem-yQQQ":"yyyy QQQ","dateFormatItem-yMEd":"EEE, yyyy-MM-dd","dateFormatItem-MMMEd":"E d MMM","eraNarrow":["f.Kr.","e.Kr."],"dateFormat-long":"d MMMM yyyy","months-format-wide":["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december"],"dateFormat-full":"EEEE 'den' d MMMM yyyy" [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/sv/number.js b/dojo/cldr/nls/sv/number.js
new file mode 100644
index 0000000..fa12589
--- /dev/null
+++ b/dojo/cldr/nls/sv/number.js
@@ -0,0 +1 @@
+({"group":" ","percentSign":"%","exponential":"×10^","percentFormat":"#,##0 %","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"−","decimal":",","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","currencyFormat":"#,##0.00 ¤","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","nan":"NaN","currencySpacing-aft [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/currency.js b/dojo/cldr/nls/th/currency.js
new file mode 100644
index 0000000..909e26f
--- /dev/null
+++ b/dojo/cldr/nls/th/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"เหรียญฮ่องกง","CHF_displayName":"ฟรังก์สวิส","JPY_symbol":"¥","HKD_symbol":"HK$","CAD_displayName":"ดอลลาร์แคนาดา","CNY_displayName":"หยวนเหรินเหมินบี้","USD_symbol":"US$","AUD_displayName":"ดอลลาร์ออสเตรเลีย","JPY_displayName":"เยน","CAD_symbol":"Can$","USD_displayName":"ดอลลาร์สหรัฐ","EUR_symbol":"€","CNY_symbol":"¥","GBP_displayName":"ปอนด์สเตอร์ลิงอังกฤษ","GBP_symbol":"£","AUD_symbol":"$A","EUR_displayName":"ยูโร"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/gregorian.js b/dojo/cldr/nls/th/gregorian.js
new file mode 100644
index 0000000..c0a0dc0
--- /dev/null
+++ b/dojo/cldr/nls/th/gregorian.js
@@ -0,0 +1 @@
+({"dateFormatItem-yM":"M/yyyy","field-dayperiod":"ช่วงวัน","dateFormatItem-yQ":"Q yyyy","field-minute":"นาที","eraNames":["ปีก่อนคริสต์ศักราชที่","คริสต์ศักราช"],"dateFormatItem-MMMEd":"E d MMM","field-weekday":"วันในสัปดาห์","dateFormatItem-yQQQ":"QQQ yyyy","days-standAlone-wide":["วันอาทิตย์","วันจันทร์","วันอังคาร","วันพุธ","วันพฤหัสบดี","วันศุกร์","วันเสาร์"],"dateFormatItem-MMM":"LLL","patternChars":"GanjkHmsSEDFwWxhKzAeugXZvcL","months-standAlone-narrow":["ม.ค.","ก.พ.","มี.ค.","เม. [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/number.js b/dojo/cldr/nls/th/number.js
new file mode 100644
index 0000000..9d4a250
--- /dev/null
+++ b/dojo/cldr/nls/th/number.js
@@ -0,0 +1 @@
+({"group":",","percentSign":"%","exponential":"E","percentFormat":"#,##0%","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":".","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","currencyFormat":"¤#,##0.00;¤-#,##0.00","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpaci [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/tr/currency.js b/dojo/cldr/nls/tr/currency.js
new file mode 100644
index 0000000..29318a3
--- /dev/null
+++ b/dojo/cldr/nls/tr/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"Hong Kong Doları","CHF_displayName":"İsviçre Frangı","CHF_symbol":"SwF","JPY_symbol":"¥","HKD_symbol":"HK$","CAD_displayName":"Kanada Doları","CNY_displayName":"Çin Yuanı Renminbi","USD_symbol":"$","AUD_displayName":"Avustralya Doları","JPY_displayName":"Japon Yeni","CAD_symbol":"Can$","USD_displayName":"ABD Doları","CNY_symbol":"Y","GBP_displayName":"İngiliz Sterlini","GBP_symbol":"£","AUD_symbol":"$A","EUR_displayName":"Euro","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/tr/gregorian.js b/dojo/cldr/nls/tr/gregorian.js
new file mode 100644
index 0000000..fcd3355
--- /dev/null
+++ b/dojo/cldr/nls/tr/gregorian.js
@@ -0,0 +1 @@
+({"dateFormatItem-yM":"M/yyyy","field-dayperiod":"AM/PM","dateFormatItem-yQ":"Q yyyy","field-minute":"Dakika","eraNames":["Milattan Önce","Milattan Sonra"],"dateFormatItem-MMMEd":"d MMM E","field-weekday":"Haftanın Günü","dateFormatItem-yQQQ":"QQQ yyyy","days-standAlone-wide":["Pazar","Pazartesi","Salı","Çarşamba","Perşembe","Cuma","Cumartesi"],"dateFormatItem-MMM":"LLL","patternChars":"GanjkHmsSEDFwWxhKzAeugXZvcL","months-standAlone-narrow":["O","Ş","M","N","M","H","T","A","E","E","K"," [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/tr/number.js b/dojo/cldr/nls/tr/number.js
new file mode 100644
index 0000000..0be4606
--- /dev/null
+++ b/dojo/cldr/nls/tr/number.js
@@ -0,0 +1 @@
+({"group":".","percentSign":"%","exponential":"E","percentFormat":"% #,##0","scientificFormat":"#E0","list":";","infinity":"∞","patternDigit":"#","minusSign":"-","decimal":",","nan":"NaN","nativeZeroDigit":"0","perMille":"‰","decimalFormat":"#,##0.###","currencyFormat":"#,##0.00 ¤","plusSign":"+","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","currencySpacing-afterC [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-cn/gregorian.js b/dojo/cldr/nls/zh-cn/gregorian.js
new file mode 100644
index 0000000..e3e560f
--- /dev/null
+++ b/dojo/cldr/nls/zh-cn/gregorian.js
@@ -0,0 +1 @@
+({"dateFormat-short":"yy-M-d","timeFormat-long":"ahh'时'mm'分'ss'秒'","dateFormat-medium":"yyyy-M-d","dateFormat-long":"yyyy'年'M'月'd'日'","timeFormat-medium":"ahh:mm:ss","timeFormat-short":"ah:mm","timeFormat-full":"ahh'时'mm'分'ss'秒' z","dateFormat-full":"yyyy'年'M'月'd'日'EEEE","months-format-narrow":["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],"quarters-standAlone-narrow":["1","2","3","4"],"field-weekday":"周天","dateFormatItem-yQQQ":"y年QQQ","dateFormatItem-yMEd":"yyyy年M月d日,E [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-cn/number.js b/dojo/cldr/nls/zh-cn/number.js
new file mode 100644
index 0000000..4329dc1
--- /dev/null
+++ b/dojo/cldr/nls/zh-cn/number.js
@@ -0,0 +1 @@
+({"currencyFormat":"¤#,##0.00","decimalFormat":"#,##0.###","group":",","scientificFormat":"#E0","percentFormat":"#,##0%","decimal":".","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","infinity":"∞","list":";","percentSign":"%","minusSign":"-","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","nan":"NaN","nativeZeroDigit":"0","plusSign":"+","currencySpacing-afterCurrency-surroundingMatch":"[:digit:]","currencySpacing [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-tw/currency.js b/dojo/cldr/nls/zh-tw/currency.js
new file mode 100644
index 0000000..4dc7389
--- /dev/null
+++ b/dojo/cldr/nls/zh-tw/currency.js
@@ -0,0 +1 @@
+({"BRE_displayName":"巴西克魯賽羅 (1990-1993)","DEM_displayName":"德國馬克","KGS_symbol":"som","CUP_displayName":"古巴披索","HUF_symbol":"Ft","BDT_symbol":"Tk","LSL_symbol":"M","VEF_symbol":"BsF","MDL_displayName":"摩杜雲列伊","DOP_displayName":"多明尼加披索","MTL_symbol":"Lm","NGN_displayName":"奈及利亞奈拉","KZT_displayName":"卡扎克斯坦坦吉","BGL_symbol":"lev","LTT_displayName":"立陶宛特羅","LAK_displayName":"寮國基普","LKR_displayName":"斯里蘭卡盧布","AOR_displayName":"安哥拉新寬扎 Reajustado (1995-1999)","XEU_displayName":"歐洲貨幣單位 XEU","SYP_s [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-tw/gregorian.js b/dojo/cldr/nls/zh-tw/gregorian.js
new file mode 100644
index 0000000..9889901
--- /dev/null
+++ b/dojo/cldr/nls/zh-tw/gregorian.js
@@ -0,0 +1 @@
+({"quarters-standAlone-wide":["第1季","第2季","第3季","第4季"],"quarters-format-abbr":["第1季","第2季","第3季","第4季"],"dateFormat-medium":"yyyy/M/d","field-second":"秒","quarters-standAlone-abbr":["第1季","第2季","第3季","第4季"],"dateFormatItem-MMdd":"MM/dd","dateFormatItem-MEd":"M-d(E)","dateFormatItem-yMEd":"yyyy/M/d(EEE)","field-week":"週","months-format-narrow":["1","2","3","4","5","6","7","8","9","10","11","12"],"timeFormat-full":"ahh時mm分ss秒v","dateFormatItem-HHmmss":"H:mm:ss","dateTimeAvailableFormats":[ [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-tw/number.js b/dojo/cldr/nls/zh-tw/number.js
new file mode 100644
index 0000000..dc51043
--- /dev/null
+++ b/dojo/cldr/nls/zh-tw/number.js
@@ -0,0 +1 @@
+({"currencyFormat":"¤#,##0.00","group":",","list":";","decimalFormat":"#,##0.###","scientificFormat":"#E0","percentFormat":"#,##0%","decimal":".","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","infinity":"∞","percentSign":"%","minusSign":"-","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","nan":"NaN","nativeZeroDigit":"0","plusSign":"+","currencySpacing-afterCurrency-surroundingMatch":"[:digit:]","currencySpacing [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh/currency.js b/dojo/cldr/nls/zh/currency.js
new file mode 100644
index 0000000..50efc23
--- /dev/null
+++ b/dojo/cldr/nls/zh/currency.js
@@ -0,0 +1 @@
+({"HKD_displayName":"港元","CHF_displayName":"瑞士法郎","HKD_symbol":"HK$","CAD_displayName":"加拿大元","CNY_displayName":"人民币","AUD_displayName":"澳大利亚元","JPY_displayName":"日元","USD_displayName":"美元","CNY_symbol":"¥","GBP_displayName":"英镑","EUR_displayName":"欧元","USD_symbol":"US$","GBP_symbol":"UK£","JPY_symbol":"JP¥","EUR_symbol":"€"})
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh/gregorian.js b/dojo/cldr/nls/zh/gregorian.js
new file mode 100644
index 0000000..8126676
--- /dev/null
+++ b/dojo/cldr/nls/zh/gregorian.js
@@ -0,0 +1 @@
+({"months-format-narrow":["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],"quarters-standAlone-narrow":["1","2","3","4"],"field-weekday":"周天","dateFormatItem-yQQQ":"y年QQQ","dateFormatItem-yMEd":"yyyy年M月d日,E","dateFormatItem-MMMEd":"MMMd日E","eraNarrow":["公元前","公元"],"dateFormat-long":"yyyy年M月d日","months-format-wide":["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],"dateFormat-full":"yyyy年M月d日EEEE","dateFormatItem-Md":"M-d","field-era":"时期","dateFormatItem-yM [...]
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh/number.js b/dojo/cldr/nls/zh/number.js
new file mode 100644
index 0000000..90d87b9
--- /dev/null
+++ b/dojo/cldr/nls/zh/number.js
@@ -0,0 +1 @@
+({"decimalFormat":"#,##0.###","group":",","scientificFormat":"#E0","percentFormat":"#,##0%","currencyFormat":"¤#,##0.00","decimal":".","currencySpacing-afterCurrency-currencyMatch":"[:letter:]","infinity":"∞","list":";","percentSign":"%","minusSign":"-","currencySpacing-beforeCurrency-surroundingMatch":"[:digit:]","currencySpacing-afterCurrency-insertBetween":" ","nan":"NaN","nativeZeroDigit":"0","plusSign":"+","currencySpacing-afterCurrency-surroundingMatch":"[:digit:]","currencySpacing [...]
\ No newline at end of file
diff --git a/dojo/cldr/supplemental.js b/dojo/cldr/supplemental.js
new file mode 100644
index 0000000..28ca582
--- /dev/null
+++ b/dojo/cldr/supplemental.js
@@ -0,0 +1,45 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.cldr.supplemental"]){
+dojo._hasResource["dojo.cldr.supplemental"]=true;
+dojo.provide("dojo.cldr.supplemental");
+dojo.require("dojo.i18n");
+dojo.cldr.supplemental.getFirstDayOfWeek=function(_1){
+var _2={mv:5,ae:6,af:6,bh:6,dj:6,dz:6,eg:6,er:6,et:6,iq:6,ir:6,jo:6,ke:6,kw:6,lb:6,ly:6,ma:6,om:6,qa:6,sa:6,sd:6,so:6,tn:6,ye:6,as:0,au:0,az:0,bw:0,ca:0,cn:0,fo:0,ge:0,gl:0,gu:0,hk:0,ie:0,il:0,is:0,jm:0,jp:0,kg:0,kr:0,la:0,mh:0,mo:0,mp:0,mt:0,nz:0,ph:0,pk:0,sg:0,th:0,tt:0,tw:0,um:0,us:0,uz:0,vi:0,za:0,zw:0,et:0,mw:0,ng:0,tj:0,sy:4};
+var _3=dojo.cldr.supplemental._region(_1);
+var _4=_2[_3];
+return (_4===undefined)?1:_4;
+};
+dojo.cldr.supplemental._region=function(_5){
+_5=dojo.i18n.normalizeLocale(_5);
+var _6=_5.split("-");
+var _7=_6[1];
+if(!_7){
+_7={de:"de",en:"us",es:"es",fi:"fi",fr:"fr",he:"il",hu:"hu",it:"it",ja:"jp",ko:"kr",nl:"nl",pt:"br",sv:"se",zh:"cn"}[_6[0]];
+}else{
+if(_7.length==4){
+_7=_6[2];
+}
+}
+return _7;
+};
+dojo.cldr.supplemental.getWeekend=function(_8){
+var _9={eg:5,il:5,sy:5,"in":0,ae:4,bh:4,dz:4,iq:4,jo:4,kw:4,lb:4,ly:4,ma:4,om:4,qa:4,sa:4,sd:4,tn:4,ye:4};
+var _a={ae:5,bh:5,dz:5,iq:5,jo:5,kw:5,lb:5,ly:5,ma:5,om:5,qa:5,sa:5,sd:5,tn:5,ye:5,af:5,ir:5,eg:6,il:6,sy:6};
+var _b=dojo.cldr.supplemental._region(_8);
+var _c=_9[_b];
+var _d=_a[_b];
+if(_c===undefined){
+_c=6;
+}
+if(_d===undefined){
+_d=0;
+}
+return {start:_c,end:_d};
+};
+}
diff --git a/dojo/colors.js b/dojo/colors.js
new file mode 100644
index 0000000..d373112
--- /dev/null
+++ b/dojo/colors.js
@@ -0,0 +1,76 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.colors"]){
+dojo._hasResource["dojo.colors"]=true;
+dojo.provide("dojo.colors");
+(function(){
+var _1=function(m1,m2,h){
+if(h<0){
+++h;
+}
+if(h>1){
+--h;
+}
+var h6=6*h;
+if(h6<1){
+return m1+(m2-m1)*h6;
+}
+if(2*h<1){
+return m2;
+}
+if(3*h<2){
+return m1+(m2-m1)*(2/3-h)*6;
+}
+return m1;
+};
+dojo.colorFromRgb=function(_6,_7){
+var m=_6.toLowerCase().match(/^(rgba?|hsla?)\(([\s\.\-,%0-9]+)\)/);
+if(m){
+var c=m[2].split(/\s*,\s*/),l=c.length,t=m[1],a;
+if((t=="rgb"&&l==3)||(t=="rgba"&&l==4)){
+var r=c[0];
+if(r.charAt(r.length-1)=="%"){
+a=dojo.map(c,function(x){
+return parseFloat(x)*2.56;
+});
+if(l==4){
+a[3]=c[3];
+}
+return dojo.colorFromArray(a,_7);
+}
+return dojo.colorFromArray(c,_7);
+}
+if((t=="hsl"&&l==3)||(t=="hsla"&&l==4)){
+var H=((parseFloat(c[0])%360)+360)%360/360,S=parseFloat(c[1])/100,L=parseFloat(c[2])/100,m2=L<=0.5?L*(S+1):L+S-L*S,m1=2*L-m2;
+a=[_1(m1,m2,H+1/3)*256,_1(m1,m2,H)*256,_1(m1,m2,H-1/3)*256,1];
+if(l==4){
+a[3]=c[3];
+}
+return dojo.colorFromArray(a,_7);
+}
+}
+return null;
+};
+var _14=function(c,low,_17){
+c=Number(c);
+return isNaN(c)?_17:c<low?low:c>_17?_17:c;
+};
+dojo.Color.prototype.sanitize=function(){
+var t=this;
+t.r=Math.round(_14(t.r,0,255));
+t.g=Math.round(_14(t.g,0,255));
+t.b=Math.round(_14(t.b,0,255));
+t.a=_14(t.a,0,1);
+return this;
+};
+})();
+dojo.colors.makeGrey=function(g,a){
+return dojo.colorFromArray([g,g,g,a]);
+};
+dojo.mixin(dojo.Color.named,{aliceblue:[240,248,255],antiquewhite:[250,235,215],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],blanchedalmond:[255,235,205],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod: [...]
+}
diff --git a/dojo/cookie.js b/dojo/cookie.js
new file mode 100644
index 0000000..b80b672
--- /dev/null
+++ b/dojo/cookie.js
@@ -0,0 +1,50 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.cookie"]){
+dojo._hasResource["dojo.cookie"]=true;
+dojo.provide("dojo.cookie");
+dojo.require("dojo.regexp");
+dojo.cookie=function(_1,_2,_3){
+var c=document.cookie;
+if(arguments.length==1){
+var _5=c.match(new RegExp("(?:^|; )"+dojo.regexp.escapeString(_1)+"=([^;]*)"));
+return _5?decodeURIComponent(_5[1]):undefined;
+}else{
+_3=_3||{};
+var _6=_3.expires;
+if(typeof _6=="number"){
+var d=new Date();
+d.setTime(d.getTime()+_6*24*60*60*1000);
+_6=_3.expires=d;
+}
+if(_6&&_6.toUTCString){
+_3.expires=_6.toUTCString();
+}
+_2=encodeURIComponent(_2);
+var _8=_1+"="+_2,_9;
+for(_9 in _3){
+_8+="; "+_9;
+var _a=_3[_9];
+if(_a!==true){
+_8+="="+_a;
+}
+}
+document.cookie=_8;
+}
+};
+dojo.cookie.isSupported=function(){
+if(!("cookieEnabled" in navigator)){
+this("__djCookieTest__","CookiesAllowed");
+navigator.cookieEnabled=this("__djCookieTest__")=="CookiesAllowed";
+if(navigator.cookieEnabled){
+this("__djCookieTest__","",{expires:-1});
+}
+}
+return navigator.cookieEnabled;
+};
+}
diff --git a/dojo/currency.js b/dojo/currency.js
new file mode 100644
index 0000000..eb8e87f
--- /dev/null
+++ b/dojo/currency.js
@@ -0,0 +1,36 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.currency"]){
+dojo._hasResource["dojo.currency"]=true;
+dojo.provide("dojo.currency");
+dojo.require("dojo.number");
+dojo.require("dojo.i18n");
+dojo.requireLocalization("dojo.cldr","currency",null,"ROOT,ar,ca,cs,da,de,el,en,en-au,en-ca,en-us,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.require("dojo.cldr.monetary");
+dojo.currency._mixInDefaults=function(_1){
+_1=_1||{};
+_1.type="currency";
+var _2=dojo.i18n.getLocalization("dojo.cldr","currency",_1.locale)||{};
+var _3=_1.currency;
+var _4=dojo.cldr.monetary.getData(_3);
+dojo.forEach(["displayName","symbol","group","decimal"],function(_5){
+_4[_5]=_2[_3+"_"+_5];
+});
+_4.fractional=[true,false];
+return dojo.mixin(_4,_1);
+};
+dojo.currency.format=function(_6,_7){
+return dojo.number.format(_6,dojo.currency._mixInDefaults(_7));
+};
+dojo.currency.regexp=function(_8){
+return dojo.number.regexp(dojo.currency._mixInDefaults(_8));
+};
+dojo.currency.parse=function(_9,_a){
+return dojo.number.parse(_9,dojo.currency._mixInDefaults(_a));
+};
+}
diff --git a/dojo/data/ItemFileReadStore.js b/dojo/data/ItemFileReadStore.js
new file mode 100644
index 0000000..c6b1c4b
--- /dev/null
+++ b/dojo/data/ItemFileReadStore.js
@@ -0,0 +1,514 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.data.ItemFileReadStore"]){
+dojo._hasResource["dojo.data.ItemFileReadStore"]=true;
+dojo.provide("dojo.data.ItemFileReadStore");
+dojo.require("dojo.data.util.filter");
+dojo.require("dojo.data.util.simpleFetch");
+dojo.require("dojo.date.stamp");
+dojo.declare("dojo.data.ItemFileReadStore",null,{constructor:function(_1){
+this._arrayOfAllItems=[];
+this._arrayOfTopLevelItems=[];
+this._loadFinished=false;
+this._jsonFileUrl=_1.url;
+this._jsonData=_1.data;
+this._datatypeMap=_1.typeMap||{};
+if(!this._datatypeMap["Date"]){
+this._datatypeMap["Date"]={type:Date,deserialize:function(_2){
+return dojo.date.stamp.fromISOString(_2);
+}};
+}
+this._features={"dojo.data.api.Read":true,"dojo.data.api.Identity":true};
+this._itemsByIdentity=null;
+this._storeRefPropName="_S";
+this._itemNumPropName="_0";
+this._rootItemPropName="_RI";
+this._reverseRefMap="_RRM";
+this._loadInProgress=false;
+this._queuedFetches=[];
+if(_1.urlPreventCache!==undefined){
+this.urlPreventCache=_1.urlPreventCache?true:false;
+}
+if(_1.clearOnClose){
+this.clearOnClose=true;
+}
+},url:"",data:null,typeMap:null,clearOnClose:false,urlPreventCache:false,_assertIsItem:function(_3){
+if(!this.isItem(_3)){
+throw new Error("dojo.data.ItemFileReadStore: Invalid item argument.");
+}
+},_assertIsAttribute:function(_4){
+if(typeof _4!=="string"){
+throw new Error("dojo.data.ItemFileReadStore: Invalid attribute argument.");
+}
+},getValue:function(_5,_6,_7){
+var _8=this.getValues(_5,_6);
+return (_8.length>0)?_8[0]:_7;
+},getValues:function(_9,_a){
+this._assertIsItem(_9);
+this._assertIsAttribute(_a);
+return _9[_a]||[];
+},getAttributes:function(_b){
+this._assertIsItem(_b);
+var _c=[];
+for(var _d in _b){
+if((_d!==this._storeRefPropName)&&(_d!==this._itemNumPropName)&&(_d!==this._rootItemPropName)&&(_d!==this._reverseRefMap)){
+_c.push(_d);
+}
+}
+return _c;
+},hasAttribute:function(_e,_f){
+return this.getValues(_e,_f).length>0;
+},containsValue:function(_10,_11,_12){
+var _13=undefined;
+if(typeof _12==="string"){
+_13=dojo.data.util.filter.patternToRegExp(_12,false);
+}
+return this._containsValue(_10,_11,_12,_13);
+},_containsValue:function(_14,_15,_16,_17){
+return dojo.some(this.getValues(_14,_15),function(_18){
+if(_18!==null&&!dojo.isObject(_18)&&_17){
+if(_18.toString().match(_17)){
+return true;
+}
+}else{
+if(_16===_18){
+return true;
+}
+}
+});
+},isItem:function(_19){
+if(_19&&_19[this._storeRefPropName]===this){
+if(this._arrayOfAllItems[_19[this._itemNumPropName]]===_19){
+return true;
+}
+}
+return false;
+},isItemLoaded:function(_1a){
+return this.isItem(_1a);
+},loadItem:function(_1b){
+this._assertIsItem(_1b.item);
+},getFeatures:function(){
+return this._features;
+},getLabel:function(_1c){
+if(this._labelAttr&&this.isItem(_1c)){
+return this.getValue(_1c,this._labelAttr);
+}
+return undefined;
+},getLabelAttributes:function(_1d){
+if(this._labelAttr){
+return [this._labelAttr];
+}
+return null;
+},_fetchItems:function(_1e,_1f,_20){
+var _21=this;
+var _22=function(_23,_24){
+var _25=[];
+var i,key;
+if(_23.query){
+var _28;
+var _29=_23.queryOptions?_23.queryOptions.ignoreCase:false;
+var _2a={};
+for(key in _23.query){
+_28=_23.query[key];
+if(typeof _28==="string"){
+_2a[key]=dojo.data.util.filter.patternToRegExp(_28,_29);
+}
+}
+for(i=0;i<_24.length;++i){
+var _2b=true;
+var _2c=_24[i];
+if(_2c===null){
+_2b=false;
+}else{
+for(key in _23.query){
+_28=_23.query[key];
+if(!_21._containsValue(_2c,key,_28,_2a[key])){
+_2b=false;
+}
+}
+}
+if(_2b){
+_25.push(_2c);
+}
+}
+_1f(_25,_23);
+}else{
+for(i=0;i<_24.length;++i){
+var _2d=_24[i];
+if(_2d!==null){
+_25.push(_2d);
+}
+}
+_1f(_25,_23);
+}
+};
+if(this._loadFinished){
+_22(_1e,this._getItemsArray(_1e.queryOptions));
+}else{
+if(this._jsonFileUrl){
+if(this._loadInProgress){
+this._queuedFetches.push({args:_1e,filter:_22});
+}else{
+this._loadInProgress=true;
+var _2e={url:_21._jsonFileUrl,handleAs:"json-comment-optional",preventCache:this.urlPreventCache};
+var _2f=dojo.xhrGet(_2e);
+_2f.addCallback(function(_30){
+try{
+_21._getItemsFromLoadedData(_30);
+_21._loadFinished=true;
+_21._loadInProgress=false;
+_22(_1e,_21._getItemsArray(_1e.queryOptions));
+_21._handleQueuedFetches();
+}
+catch(e){
+_21._loadFinished=true;
+_21._loadInProgress=false;
+_20(e,_1e);
+}
+});
+_2f.addErrback(function(_31){
+_21._loadInProgress=false;
+_20(_31,_1e);
+});
+var _32=null;
+if(_1e.abort){
+_32=_1e.abort;
+}
+_1e.abort=function(){
+var df=_2f;
+if(df&&df.fired===-1){
+df.cancel();
+df=null;
+}
+if(_32){
+_32.call(_1e);
+}
+};
+}
+}else{
+if(this._jsonData){
+try{
+this._loadFinished=true;
+this._getItemsFromLoadedData(this._jsonData);
+this._jsonData=null;
+_22(_1e,this._getItemsArray(_1e.queryOptions));
+}
+catch(e){
+_20(e,_1e);
+}
+}else{
+_20(new Error("dojo.data.ItemFileReadStore: No JSON source data was provided as either URL or a nested Javascript object."),_1e);
+}
+}
+}
+},_handleQueuedFetches:function(){
+if(this._queuedFetches.length>0){
+for(var i=0;i<this._queuedFetches.length;i++){
+var _35=this._queuedFetches[i];
+var _36=_35.args;
+var _37=_35.filter;
+if(_37){
+_37(_36,this._getItemsArray(_36.queryOptions));
+}else{
+this.fetchItemByIdentity(_36);
+}
+}
+this._queuedFetches=[];
+}
+},_getItemsArray:function(_38){
+if(_38&&_38.deep){
+return this._arrayOfAllItems;
+}
+return this._arrayOfTopLevelItems;
+},close:function(_39){
+if(this.clearOnClose&&(this._jsonFileUrl!=="")){
+this._arrayOfAllItems=[];
+this._arrayOfTopLevelItems=[];
+this._loadFinished=false;
+this._itemsByIdentity=null;
+this._loadInProgress=false;
+this._queuedFetches=[];
+}
+},_getItemsFromLoadedData:function(_3a){
+var _3b=false;
+function _3c(_3d){
+var _3e=((_3d!==null)&&(typeof _3d==="object")&&(!dojo.isArray(_3d)||_3b)&&(!dojo.isFunction(_3d))&&(_3d.constructor==Object||dojo.isArray(_3d))&&(typeof _3d._reference==="undefined")&&(typeof _3d._type==="undefined")&&(typeof _3d._value==="undefined"));
+return _3e;
+};
+var _3f=this;
+function _40(_41){
+_3f._arrayOfAllItems.push(_41);
+for(var _42 in _41){
+var _43=_41[_42];
+if(_43){
+if(dojo.isArray(_43)){
+var _44=_43;
+for(var k=0;k<_44.length;++k){
+var _46=_44[k];
+if(_3c(_46)){
+_40(_46);
+}
+}
+}else{
+if(_3c(_43)){
+_40(_43);
+}
+}
+}
+}
+};
+this._labelAttr=_3a.label;
+var i;
+var _48;
+this._arrayOfAllItems=[];
+this._arrayOfTopLevelItems=_3a.items;
+for(i=0;i<this._arrayOfTopLevelItems.length;++i){
+_48=this._arrayOfTopLevelItems[i];
+if(dojo.isArray(_48)){
+_3b=true;
+}
+_40(_48);
+_48[this._rootItemPropName]=true;
+}
+var _49={};
+var key;
+for(i=0;i<this._arrayOfAllItems.length;++i){
+_48=this._arrayOfAllItems[i];
+for(key in _48){
+if(key!==this._rootItemPropName){
+var _4b=_48[key];
+if(_4b!==null){
+if(!dojo.isArray(_4b)){
+_48[key]=[_4b];
+}
+}else{
+_48[key]=[null];
+}
+}
+_49[key]=key;
+}
+}
+while(_49[this._storeRefPropName]){
+this._storeRefPropName+="_";
+}
+while(_49[this._itemNumPropName]){
+this._itemNumPropName+="_";
+}
+while(_49[this._reverseRefMap]){
+this._reverseRefMap+="_";
+}
+var _4c;
+var _4d=_3a.identifier;
+if(_4d){
+this._itemsByIdentity={};
+this._features["dojo.data.api.Identity"]=_4d;
+for(i=0;i<this._arrayOfAllItems.length;++i){
+_48=this._arrayOfAllItems[i];
+_4c=_48[_4d];
+var _4e=_4c[0];
+if(!this._itemsByIdentity[_4e]){
+this._itemsByIdentity[_4e]=_48;
+}else{
+if(this._jsonFileUrl){
+throw new Error("dojo.data.ItemFileReadStore:  The json data as specified by: ["+this._jsonFileUrl+"] is malformed.  Items within the list have identifier: ["+_4d+"].  Value collided: ["+_4e+"]");
+}else{
+if(this._jsonData){
+throw new Error("dojo.data.ItemFileReadStore:  The json data provided by the creation arguments is malformed.  Items within the list have identifier: ["+_4d+"].  Value collided: ["+_4e+"]");
+}
+}
+}
+}
+}else{
+this._features["dojo.data.api.Identity"]=Number;
+}
+for(i=0;i<this._arrayOfAllItems.length;++i){
+_48=this._arrayOfAllItems[i];
+_48[this._storeRefPropName]=this;
+_48[this._itemNumPropName]=i;
+}
+for(i=0;i<this._arrayOfAllItems.length;++i){
+_48=this._arrayOfAllItems[i];
+for(key in _48){
+_4c=_48[key];
+for(var j=0;j<_4c.length;++j){
+_4b=_4c[j];
+if(_4b!==null&&typeof _4b=="object"){
+if(_4b._type&&_4b._value){
+var _50=_4b._type;
+var _51=this._datatypeMap[_50];
+if(!_51){
+throw new Error("dojo.data.ItemFileReadStore: in the typeMap constructor arg, no object class was specified for the datatype '"+_50+"'");
+}else{
+if(dojo.isFunction(_51)){
+_4c[j]=new _51(_4b._value);
+}else{
+if(dojo.isFunction(_51.deserialize)){
+_4c[j]=_51.deserialize(_4b._value);
+}else{
+throw new Error("dojo.data.ItemFileReadStore: Value provided in typeMap was neither a constructor, nor a an object with a deserialize function");
+}
+}
+}
+}
+if(_4b._reference){
+var _52=_4b._reference;
+if(!dojo.isObject(_52)){
+_4c[j]=this._itemsByIdentity[_52];
+}else{
+for(var k=0;k<this._arrayOfAllItems.length;++k){
+var _54=this._arrayOfAllItems[k];
+var _55=true;
+for(var _56 in _52){
+if(_54[_56]!=_52[_56]){
+_55=false;
+}
+}
+if(_55){
+_4c[j]=_54;
+}
+}
+}
+if(this.referenceIntegrity){
+var _57=_4c[j];
+if(this.isItem(_57)){
+this._addReferenceToMap(_57,_48,key);
+}
+}
+}else{
+if(this.isItem(_4b)){
+if(this.referenceIntegrity){
+this._addReferenceToMap(_4b,_48,key);
+}
+}
+}
+}
+}
+}
+}
+},_addReferenceToMap:function(_58,_59,_5a){
+},getIdentity:function(_5b){
+var _5c=this._features["dojo.data.api.Identity"];
+if(_5c===Number){
+return _5b[this._itemNumPropName];
+}else{
+var _5d=_5b[_5c];
+if(_5d){
+return _5d[0];
+}
+}
+return null;
+},fetchItemByIdentity:function(_5e){
+var _5f;
+var _60;
+if(!this._loadFinished){
+var _61=this;
+if(this._jsonFileUrl){
+if(this._loadInProgress){
+this._queuedFetches.push({args:_5e});
+}else{
+this._loadInProgress=true;
+var _62={url:_61._jsonFileUrl,handleAs:"json-comment-optional",preventCache:this.urlPreventCache};
+var _63=dojo.xhrGet(_62);
+_63.addCallback(function(_64){
+var _65=_5e.scope?_5e.scope:dojo.global;
+try{
+_61._getItemsFromLoadedData(_64);
+_61._loadFinished=true;
+_61._loadInProgress=false;
+_5f=_61._getItemByIdentity(_5e.identity);
+if(_5e.onItem){
+_5e.onItem.call(_65,_5f);
+}
+_61._handleQueuedFetches();
+}
+catch(error){
+_61._loadInProgress=false;
+if(_5e.onError){
+_5e.onError.call(_65,error);
+}
+}
+});
+_63.addErrback(function(_66){
+_61._loadInProgress=false;
+if(_5e.onError){
+var _67=_5e.scope?_5e.scope:dojo.global;
+_5e.onError.call(_67,_66);
+}
+});
+}
+}else{
+if(this._jsonData){
+_61._getItemsFromLoadedData(_61._jsonData);
+_61._jsonData=null;
+_61._loadFinished=true;
+_5f=_61._getItemByIdentity(_5e.identity);
+if(_5e.onItem){
+_60=_5e.scope?_5e.scope:dojo.global;
+_5e.onItem.call(_60,_5f);
+}
+}
+}
+}else{
+_5f=this._getItemByIdentity(_5e.identity);
+if(_5e.onItem){
+_60=_5e.scope?_5e.scope:dojo.global;
+_5e.onItem.call(_60,_5f);
+}
+}
+},_getItemByIdentity:function(_68){
+var _69=null;
+if(this._itemsByIdentity){
+_69=this._itemsByIdentity[_68];
+}else{
+_69=this._arrayOfAllItems[_68];
+}
+if(_69===undefined){
+_69=null;
+}
+return _69;
+},getIdentityAttributes:function(_6a){
+var _6b=this._features["dojo.data.api.Identity"];
+if(_6b===Number){
+return null;
+}else{
+return [_6b];
+}
+},_forceLoad:function(){
+var _6c=this;
+if(this._jsonFileUrl){
+var _6d={url:_6c._jsonFileUrl,handleAs:"json-comment-optional",preventCache:this.urlPreventCache,sync:true};
+var _6e=dojo.xhrGet(_6d);
+_6e.addCallback(function(_6f){
+try{
+if(_6c._loadInProgress!==true&&!_6c._loadFinished){
+_6c._getItemsFromLoadedData(_6f);
+_6c._loadFinished=true;
+}else{
+if(_6c._loadInProgress){
+throw new Error("dojo.data.ItemFileReadStore:  Unable to perform a synchronous load, an async load is in progress.");
+}
+}
+}
+catch(e){
+
+throw e;
+}
+});
+_6e.addErrback(function(_70){
+throw _70;
+});
+}else{
+if(this._jsonData){
+_6c._getItemsFromLoadedData(_6c._jsonData);
+_6c._jsonData=null;
+_6c._loadFinished=true;
+}
+}
+}});
+dojo.extend(dojo.data.ItemFileReadStore,dojo.data.util.simpleFetch);
+}
diff --git a/dojo/data/ItemFileWriteStore.js b/dojo/data/ItemFileWriteStore.js
new file mode 100644
index 0000000..c9071d7
--- /dev/null
+++ b/dojo/data/ItemFileWriteStore.js
@@ -0,0 +1,526 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.data.ItemFileWriteStore"]){
+dojo._hasResource["dojo.data.ItemFileWriteStore"]=true;
+dojo.provide("dojo.data.ItemFileWriteStore");
+dojo.require("dojo.data.ItemFileReadStore");
+dojo.declare("dojo.data.ItemFileWriteStore",dojo.data.ItemFileReadStore,{constructor:function(_1){
+this._features["dojo.data.api.Write"]=true;
+this._features["dojo.data.api.Notification"]=true;
+this._pending={_newItems:{},_modifiedItems:{},_deletedItems:{}};
+if(!this._datatypeMap["Date"].serialize){
+this._datatypeMap["Date"].serialize=function(_2){
+return dojo.date.stamp.toISOString(_2,{zulu:true});
+};
+}
+if(_1&&(_1.referenceIntegrity===false)){
+this.referenceIntegrity=false;
+}
+this._saveInProgress=false;
+},referenceIntegrity:true,_assert:function(_3){
+if(!_3){
+throw new Error("assertion failed in ItemFileWriteStore");
+}
+},_getIdentifierAttribute:function(){
+var _4=this.getFeatures()["dojo.data.api.Identity"];
+return _4;
+},newItem:function(_5,_6){
+this._assert(!this._saveInProgress);
+if(!this._loadFinished){
+this._forceLoad();
+}
+if(typeof _5!="object"&&typeof _5!="undefined"){
+throw new Error("newItem() was passed something other than an object");
+}
+var _7=null;
+var _8=this._getIdentifierAttribute();
+if(_8===Number){
+_7=this._arrayOfAllItems.length;
+}else{
+_7=_5[_8];
+if(typeof _7==="undefined"){
+throw new Error("newItem() was not passed an identity for the new item");
+}
+if(dojo.isArray(_7)){
+throw new Error("newItem() was not passed an single-valued identity");
+}
+}
+if(this._itemsByIdentity){
+this._assert(typeof this._itemsByIdentity[_7]==="undefined");
+}
+this._assert(typeof this._pending._newItems[_7]==="undefined");
+this._assert(typeof this._pending._deletedItems[_7]==="undefined");
+var _9={};
+_9[this._storeRefPropName]=this;
+_9[this._itemNumPropName]=this._arrayOfAllItems.length;
+if(this._itemsByIdentity){
+this._itemsByIdentity[_7]=_9;
+_9[_8]=[_7];
+}
+this._arrayOfAllItems.push(_9);
+var _a=null;
+if(_6&&_6.parent&&_6.attribute){
+_a={item:_6.parent,attribute:_6.attribute,oldValue:undefined};
+var _b=this.getValues(_6.parent,_6.attribute);
+if(_b&&_b.length>0){
+var _c=_b.slice(0,_b.length);
+if(_b.length===1){
+_a.oldValue=_b[0];
+}else{
+_a.oldValue=_b.slice(0,_b.length);
+}
+_c.push(_9);
+this._setValueOrValues(_6.parent,_6.attribute,_c,false);
+_a.newValue=this.getValues(_6.parent,_6.attribute);
+}else{
+this._setValueOrValues(_6.parent,_6.attribute,_9,false);
+_a.newValue=_9;
+}
+}else{
+_9[this._rootItemPropName]=true;
+this._arrayOfTopLevelItems.push(_9);
+}
+this._pending._newItems[_7]=_9;
+for(var _d in _5){
+if(_d===this._storeRefPropName||_d===this._itemNumPropName){
+throw new Error("encountered bug in ItemFileWriteStore.newItem");
+}
+var _e=_5[_d];
+if(!dojo.isArray(_e)){
+_e=[_e];
+}
+_9[_d]=_e;
+if(this.referenceIntegrity){
+for(var i=0;i<_e.length;i++){
+var val=_e[i];
+if(this.isItem(val)){
+this._addReferenceToMap(val,_9,_d);
+}
+}
+}
+}
+this.onNew(_9,_a);
+return _9;
+},_removeArrayElement:function(_11,_12){
+var _13=dojo.indexOf(_11,_12);
+if(_13!=-1){
+_11.splice(_13,1);
+return true;
+}
+return false;
+},deleteItem:function(_14){
+this._assert(!this._saveInProgress);
+this._assertIsItem(_14);
+var _15=_14[this._itemNumPropName];
+var _16=this.getIdentity(_14);
+if(this.referenceIntegrity){
+var _17=this.getAttributes(_14);
+if(_14[this._reverseRefMap]){
+_14["backup_"+this._reverseRefMap]=dojo.clone(_14[this._reverseRefMap]);
+}
+dojo.forEach(_17,function(_18){
+dojo.forEach(this.getValues(_14,_18),function(_19){
+if(this.isItem(_19)){
+if(!_14["backupRefs_"+this._reverseRefMap]){
+_14["backupRefs_"+this._reverseRefMap]=[];
+}
+_14["backupRefs_"+this._reverseRefMap].push({id:this.getIdentity(_19),attr:_18});
+this._removeReferenceFromMap(_19,_14,_18);
+}
+},this);
+},this);
+var _1a=_14[this._reverseRefMap];
+if(_1a){
+for(var _1b in _1a){
+var _1c=null;
+if(this._itemsByIdentity){
+_1c=this._itemsByIdentity[_1b];
+}else{
+_1c=this._arrayOfAllItems[_1b];
+}
+if(_1c){
+for(var _1d in _1a[_1b]){
+var _1e=this.getValues(_1c,_1d)||[];
+var _1f=dojo.filter(_1e,function(_20){
+return !(this.isItem(_20)&&this.getIdentity(_20)==_16);
+},this);
+this._removeReferenceFromMap(_14,_1c,_1d);
+if(_1f.length<_1e.length){
+this._setValueOrValues(_1c,_1d,_1f,true);
+}
+}
+}
+}
+}
+}
+this._arrayOfAllItems[_15]=null;
+_14[this._storeRefPropName]=null;
+if(this._itemsByIdentity){
+delete this._itemsByIdentity[_16];
+}
+this._pending._deletedItems[_16]=_14;
+if(_14[this._rootItemPropName]){
+this._removeArrayElement(this._arrayOfTopLevelItems,_14);
+}
+this.onDelete(_14);
+return true;
+},setValue:function(_21,_22,_23){
+return this._setValueOrValues(_21,_22,_23,true);
+},setValues:function(_24,_25,_26){
+return this._setValueOrValues(_24,_25,_26,true);
+},unsetAttribute:function(_27,_28){
+return this._setValueOrValues(_27,_28,[],true);
+},_setValueOrValues:function(_29,_2a,_2b,_2c){
+this._assert(!this._saveInProgress);
+this._assertIsItem(_29);
+this._assert(dojo.isString(_2a));
+this._assert(typeof _2b!=="undefined");
+var _2d=this._getIdentifierAttribute();
+if(_2a==_2d){
+throw new Error("ItemFileWriteStore does not have support for changing the value of an item's identifier.");
+}
+var _2e=this._getValueOrValues(_29,_2a);
+var _2f=this.getIdentity(_29);
+if(!this._pending._modifiedItems[_2f]){
+var _30={};
+for(var key in _29){
+if((key===this._storeRefPropName)||(key===this._itemNumPropName)||(key===this._rootItemPropName)){
+_30[key]=_29[key];
+}else{
+if(key===this._reverseRefMap){
+_30[key]=dojo.clone(_29[key]);
+}else{
+_30[key]=_29[key].slice(0,_29[key].length);
+}
+}
+}
+this._pending._modifiedItems[_2f]=_30;
+}
+var _32=false;
+if(dojo.isArray(_2b)&&_2b.length===0){
+_32=delete _29[_2a];
+_2b=undefined;
+if(this.referenceIntegrity&&_2e){
+var _33=_2e;
+if(!dojo.isArray(_33)){
+_33=[_33];
+}
+for(var i=0;i<_33.length;i++){
+var _35=_33[i];
+if(this.isItem(_35)){
+this._removeReferenceFromMap(_35,_29,_2a);
+}
+}
+}
+}else{
+var _36;
+if(dojo.isArray(_2b)){
+var _37=_2b;
+_36=_2b.slice(0,_2b.length);
+}else{
+_36=[_2b];
+}
+if(this.referenceIntegrity){
+if(_2e){
+var _33=_2e;
+if(!dojo.isArray(_33)){
+_33=[_33];
+}
+var map={};
+dojo.forEach(_33,function(_39){
+if(this.isItem(_39)){
+var id=this.getIdentity(_39);
+map[id.toString()]=true;
+}
+},this);
+dojo.forEach(_36,function(_3b){
+if(this.isItem(_3b)){
+var id=this.getIdentity(_3b);
+if(map[id.toString()]){
+delete map[id.toString()];
+}else{
+this._addReferenceToMap(_3b,_29,_2a);
+}
+}
+},this);
+for(var rId in map){
+var _3e;
+if(this._itemsByIdentity){
+_3e=this._itemsByIdentity[rId];
+}else{
+_3e=this._arrayOfAllItems[rId];
+}
+this._removeReferenceFromMap(_3e,_29,_2a);
+}
+}else{
+for(var i=0;i<_36.length;i++){
+var _35=_36[i];
+if(this.isItem(_35)){
+this._addReferenceToMap(_35,_29,_2a);
+}
+}
+}
+}
+_29[_2a]=_36;
+_32=true;
+}
+if(_2c){
+this.onSet(_29,_2a,_2e,_2b);
+}
+return _32;
+},_addReferenceToMap:function(_3f,_40,_41){
+var _42=this.getIdentity(_40);
+var _43=_3f[this._reverseRefMap];
+if(!_43){
+_43=_3f[this._reverseRefMap]={};
+}
+var _44=_43[_42];
+if(!_44){
+_44=_43[_42]={};
+}
+_44[_41]=true;
+},_removeReferenceFromMap:function(_45,_46,_47){
+var _48=this.getIdentity(_46);
+var _49=_45[this._reverseRefMap];
+var _4a;
+if(_49){
+for(_4a in _49){
+if(_4a==_48){
+delete _49[_4a][_47];
+if(this._isEmpty(_49[_4a])){
+delete _49[_4a];
+}
+}
+}
+if(this._isEmpty(_49)){
+delete _45[this._reverseRefMap];
+}
+}
+},_dumpReferenceMap:function(){
+var i;
+for(i=0;i<this._arrayOfAllItems.length;i++){
+var _4c=this._arrayOfAllItems[i];
+if(_4c&&_4c[this._reverseRefMap]){
+
+}
+}
+},_getValueOrValues:function(_4d,_4e){
+var _4f=undefined;
+if(this.hasAttribute(_4d,_4e)){
+var _50=this.getValues(_4d,_4e);
+if(_50.length==1){
+_4f=_50[0];
+}else{
+_4f=_50;
+}
+}
+return _4f;
+},_flatten:function(_51){
+if(this.isItem(_51)){
+var _52=_51;
+var _53=this.getIdentity(_52);
+var _54={_reference:_53};
+return _54;
+}else{
+if(typeof _51==="object"){
+for(var _55 in this._datatypeMap){
+var _56=this._datatypeMap[_55];
+if(dojo.isObject(_56)&&!dojo.isFunction(_56)){
+if(_51 instanceof _56.type){
+if(!_56.serialize){
+throw new Error("ItemFileWriteStore:  No serializer defined for type mapping: ["+_55+"]");
+}
+return {_type:_55,_value:_56.serialize(_51)};
+}
+}else{
+if(_51 instanceof _56){
+return {_type:_55,_value:_51.toString()};
+}
+}
+}
+}
+return _51;
+}
+},_getNewFileContentString:function(){
+var _57={};
+var _58=this._getIdentifierAttribute();
+if(_58!==Number){
+_57.identifier=_58;
+}
+if(this._labelAttr){
+_57.label=this._labelAttr;
+}
+_57.items=[];
+for(var i=0;i<this._arrayOfAllItems.length;++i){
+var _5a=this._arrayOfAllItems[i];
+if(_5a!==null){
+var _5b={};
+for(var key in _5a){
+if(key!==this._storeRefPropName&&key!==this._itemNumPropName&&key!==this._reverseRefMap&&key!==this._rootItemPropName){
+var _5d=key;
+var _5e=this.getValues(_5a,_5d);
+if(_5e.length==1){
+_5b[_5d]=this._flatten(_5e[0]);
+}else{
+var _5f=[];
+for(var j=0;j<_5e.length;++j){
+_5f.push(this._flatten(_5e[j]));
+_5b[_5d]=_5f;
+}
+}
+}
+}
+_57.items.push(_5b);
+}
+}
+var _61=true;
+return dojo.toJson(_57,_61);
+},_isEmpty:function(_62){
+var _63=true;
+if(dojo.isObject(_62)){
+var i;
+for(i in _62){
+_63=false;
+break;
+}
+}else{
+if(dojo.isArray(_62)){
+if(_62.length>0){
+_63=false;
+}
+}
+}
+return _63;
+},save:function(_65){
+this._assert(!this._saveInProgress);
+this._saveInProgress=true;
+var _66=this;
+var _67=function(){
+_66._pending={_newItems:{},_modifiedItems:{},_deletedItems:{}};
+_66._saveInProgress=false;
+if(_65&&_65.onComplete){
+var _68=_65.scope||dojo.global;
+_65.onComplete.call(_68);
+}
+};
+var _69=function(err){
+_66._saveInProgress=false;
+if(_65&&_65.onError){
+var _6b=_65.scope||dojo.global;
+_65.onError.call(_6b,err);
+}
+};
+if(this._saveEverything){
+var _6c=this._getNewFileContentString();
+this._saveEverything(_67,_69,_6c);
+}
+if(this._saveCustom){
+this._saveCustom(_67,_69);
+}
+if(!this._saveEverything&&!this._saveCustom){
+_67();
+}
+},revert:function(){
+this._assert(!this._saveInProgress);
+var _6d;
+for(_6d in this._pending._modifiedItems){
+var _6e=this._pending._modifiedItems[_6d];
+var _6f=null;
+if(this._itemsByIdentity){
+_6f=this._itemsByIdentity[_6d];
+}else{
+_6f=this._arrayOfAllItems[_6d];
+}
+_6e[this._storeRefPropName]=this;
+_6f[this._storeRefPropName]=null;
+var _70=_6f[this._itemNumPropName];
+this._arrayOfAllItems[_70]=_6e;
+if(_6f[this._rootItemPropName]){
+var i;
+for(i=0;i<this._arrayOfTopLevelItems.length;i++){
+var _72=this._arrayOfTopLevelItems[i];
+if(this.getIdentity(_72)==_6d){
+this._arrayOfTopLevelItems[i]=_6e;
+break;
+}
+}
+}
+if(this._itemsByIdentity){
+this._itemsByIdentity[_6d]=_6e;
+}
+}
+var _73;
+for(_6d in this._pending._deletedItems){
+_73=this._pending._deletedItems[_6d];
+_73[this._storeRefPropName]=this;
+var _74=_73[this._itemNumPropName];
+if(_73["backup_"+this._reverseRefMap]){
+_73[this._reverseRefMap]=_73["backup_"+this._reverseRefMap];
+delete _73["backup_"+this._reverseRefMap];
+}
+this._arrayOfAllItems[_74]=_73;
+if(this._itemsByIdentity){
+this._itemsByIdentity[_6d]=_73;
+}
+if(_73[this._rootItemPropName]){
+this._arrayOfTopLevelItems.push(_73);
+}
+}
+for(_6d in this._pending._deletedItems){
+_73=this._pending._deletedItems[_6d];
+if(_73["backupRefs_"+this._reverseRefMap]){
+dojo.forEach(_73["backupRefs_"+this._reverseRefMap],function(_75){
+var _76;
+if(this._itemsByIdentity){
+_76=this._itemsByIdentity[_75.id];
+}else{
+_76=this._arrayOfAllItems[_75.id];
+}
+this._addReferenceToMap(_76,_73,_75.attr);
+},this);
+delete _73["backupRefs_"+this._reverseRefMap];
+}
+}
+for(_6d in this._pending._newItems){
+var _77=this._pending._newItems[_6d];
+_77[this._storeRefPropName]=null;
+this._arrayOfAllItems[_77[this._itemNumPropName]]=null;
+if(_77[this._rootItemPropName]){
+this._removeArrayElement(this._arrayOfTopLevelItems,_77);
+}
+if(this._itemsByIdentity){
+delete this._itemsByIdentity[_6d];
+}
+}
+this._pending={_newItems:{},_modifiedItems:{},_deletedItems:{}};
+return true;
+},isDirty:function(_78){
+if(_78){
+var _79=this.getIdentity(_78);
+return new Boolean(this._pending._newItems[_79]||this._pending._modifiedItems[_79]||this._pending._deletedItems[_79]).valueOf();
+}else{
+if(!this._isEmpty(this._pending._newItems)||!this._isEmpty(this._pending._modifiedItems)||!this._isEmpty(this._pending._deletedItems)){
+return true;
+}
+return false;
+}
+},onSet:function(_7a,_7b,_7c,_7d){
+},onNew:function(_7e,_7f){
+},onDelete:function(_80){
+},close:function(_81){
+if(this.clearOnClose){
+if(!this.isDirty()){
+this.inherited(arguments);
+}else{
+if(this._jsonFileUrl!==""){
+throw new Error("dojo.data.ItemFileWriteStore: There are unsaved changes present in the store.  Please save or revert the changes before invoking close.");
+}
+}
+}
+}});
+}
diff --git a/dojo/data/api/Identity.js b/dojo/data/api/Identity.js
new file mode 100644
index 0000000..2a1baf6
--- /dev/null
+++ b/dojo/data/api/Identity.js
@@ -0,0 +1,26 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.data.api.Identity"]){
+dojo._hasResource["dojo.data.api.Identity"]=true;
+dojo.provide("dojo.data.api.Identity");
+dojo.require("dojo.data.api.Read");
+dojo.declare("dojo.data.api.Identity",dojo.data.api.Read,{getFeatures:function(){
+return {"dojo.data.api.Read":true,"dojo.data.api.Identity":true};
+},getIdentity:function(_1){
+throw new Error("Unimplemented API: dojo.data.api.Identity.getIdentity");
+var _2=null;
+return _2;
+},getIdentityAttributes:function(_3){
+throw new Error("Unimplemented API: dojo.data.api.Identity.getIdentityAttributes");
+return null;
+},fetchItemByIdentity:function(_4){
+if(!this.isItemLoaded(_4.item)){
+throw new Error("Unimplemented API: dojo.data.api.Identity.fetchItemByIdentity");
+}
+}});
+}
diff --git a/dojo/data/api/Notification.js b/dojo/data/api/Notification.js
new file mode 100644
index 0000000..e063d48
--- /dev/null
+++ b/dojo/data/api/Notification.js
@@ -0,0 +1,21 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.data.api.Notification"]){
+dojo._hasResource["dojo.data.api.Notification"]=true;
+dojo.provide("dojo.data.api.Notification");
+dojo.require("dojo.data.api.Read");
+dojo.declare("dojo.data.api.Notification",dojo.data.api.Read,{getFeatures:function(){
+return {"dojo.data.api.Read":true,"dojo.data.api.Notification":true};
+},onSet:function(_1,_2,_3,_4){
+throw new Error("Unimplemented API: dojo.data.api.Notification.onSet");
+},onNew:function(_5,_6){
+throw new Error("Unimplemented API: dojo.data.api.Notification.onNew");
+},onDelete:function(_7){
+throw new Error("Unimplemented API: dojo.data.api.Notification.onDelete");
+}});
+}
diff --git a/dojo/data/api/Read.js b/dojo/data/api/Read.js
new file mode 100644
index 0000000..38594d2
--- /dev/null
+++ b/dojo/data/api/Read.js
@@ -0,0 +1,55 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.data.api.Read"]){
+dojo._hasResource["dojo.data.api.Read"]=true;
+dojo.provide("dojo.data.api.Read");
+dojo.require("dojo.data.api.Request");
+dojo.declare("dojo.data.api.Read",null,{getValue:function(_1,_2,_3){
+var _4=null;
+throw new Error("Unimplemented API: dojo.data.api.Read.getValue");
+return _4;
+},getValues:function(_5,_6){
+var _7=[];
+throw new Error("Unimplemented API: dojo.data.api.Read.getValues");
+return _7;
+},getAttributes:function(_8){
+var _9=[];
+throw new Error("Unimplemented API: dojo.data.api.Read.getAttributes");
+return _9;
+},hasAttribute:function(_a,_b){
+throw new Error("Unimplemented API: dojo.data.api.Read.hasAttribute");
+return false;
+},containsValue:function(_c,_d,_e){
+throw new Error("Unimplemented API: dojo.data.api.Read.containsValue");
+return false;
+},isItem:function(_f){
+throw new Error("Unimplemented API: dojo.data.api.Read.isItem");
+return false;
+},isItemLoaded:function(_10){
+throw new Error("Unimplemented API: dojo.data.api.Read.isItemLoaded");
+return false;
+},loadItem:function(_11){
+if(!this.isItemLoaded(_11.item)){
+throw new Error("Unimplemented API: dojo.data.api.Read.loadItem");
+}
+},fetch:function(_12){
+var _13=null;
+throw new Error("Unimplemented API: dojo.data.api.Read.fetch");
+return _13;
+},getFeatures:function(){
+return {"dojo.data.api.Read":true};
+},close:function(_14){
+throw new Error("Unimplemented API: dojo.data.api.Read.close");
+},getLabel:function(_15){
+throw new Error("Unimplemented API: dojo.data.api.Read.getLabel");
+return undefined;
+},getLabelAttributes:function(_16){
+throw new Error("Unimplemented API: dojo.data.api.Read.getLabelAttributes");
+return null;
+}});
+}
diff --git a/dojo/data/api/Request.js b/dojo/data/api/Request.js
new file mode 100644
index 0000000..72e1989
--- /dev/null
+++ b/dojo/data/api/Request.js
@@ -0,0 +1,14 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.data.api.Request"]){
+dojo._hasResource["dojo.data.api.Request"]=true;
+dojo.provide("dojo.data.api.Request");
+dojo.declare("dojo.data.api.Request",null,{abort:function(){
+throw new Error("Unimplemented API: dojo.data.api.Request.abort");
+}});
+}
diff --git a/dojo/data/api/Write.js b/dojo/data/api/Write.js
new file mode 100644
index 0000000..d04d7d7
--- /dev/null
+++ b/dojo/data/api/Write.js
@@ -0,0 +1,39 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.data.api.Write"]){
+dojo._hasResource["dojo.data.api.Write"]=true;
+dojo.provide("dojo.data.api.Write");
+dojo.require("dojo.data.api.Read");
+dojo.declare("dojo.data.api.Write",dojo.data.api.Read,{getFeatures:function(){
+return {"dojo.data.api.Read":true,"dojo.data.api.Write":true};
+},newItem:function(_1,_2){
+var _3;
+throw new Error("Unimplemented API: dojo.data.api.Write.newItem");
+return _3;
+},deleteItem:function(_4){
+throw new Error("Unimplemented API: dojo.data.api.Write.deleteItem");
+return false;
+},setValue:function(_5,_6,_7){
+throw new Error("Unimplemented API: dojo.data.api.Write.setValue");
+return false;
+},setValues:function(_8,_9,_a){
+throw new Error("Unimplemented API: dojo.data.api.Write.setValues");
+return false;
+},unsetAttribute:function(_b,_c){
+throw new Error("Unimplemented API: dojo.data.api.Write.clear");
+return false;
+},save:function(_d){
+throw new Error("Unimplemented API: dojo.data.api.Write.save");
+},revert:function(){
+throw new Error("Unimplemented API: dojo.data.api.Write.revert");
+return false;
+},isDirty:function(_e){
+throw new Error("Unimplemented API: dojo.data.api.Write.isDirty");
+return false;
+}});
+}
diff --git a/dojo/data/util/filter.js b/dojo/data/util/filter.js
new file mode 100644
index 0000000..0f6fa8a
--- /dev/null
+++ b/dojo/data/util/filter.js
@@ -0,0 +1,52 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.data.util.filter"]){
+dojo._hasResource["dojo.data.util.filter"]=true;
+dojo.provide("dojo.data.util.filter");
+dojo.data.util.filter.patternToRegExp=function(_1,_2){
+var _3="^";
+var c=null;
+for(var i=0;i<_1.length;i++){
+c=_1.charAt(i);
+switch(c){
+case "\\":
+_3+=c;
+i++;
+_3+=_1.charAt(i);
+break;
+case "*":
+_3+=".*";
+break;
+case "?":
+_3+=".";
+break;
+case "$":
+case "^":
+case "/":
+case "+":
+case ".":
+case "|":
+case "(":
+case ")":
+case "{":
+case "}":
+case "[":
+case "]":
+_3+="\\";
+default:
+_3+=c;
+}
+}
+_3+="$";
+if(_2){
+return new RegExp(_3,"mi");
+}else{
+return new RegExp(_3,"m");
+}
+};
+}
diff --git a/dojo/data/util/simpleFetch.js b/dojo/data/util/simpleFetch.js
new file mode 100644
index 0000000..69fa0f6
--- /dev/null
+++ b/dojo/data/util/simpleFetch.js
@@ -0,0 +1,64 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.data.util.simpleFetch"]){
+dojo._hasResource["dojo.data.util.simpleFetch"]=true;
+dojo.provide("dojo.data.util.simpleFetch");
+dojo.require("dojo.data.util.sorter");
+dojo.data.util.simpleFetch.fetch=function(_1){
+_1=_1||{};
+if(!_1.store){
+_1.store=this;
+}
+var _2=this;
+var _3=function(_4,_5){
+if(_5.onError){
+var _6=_5.scope||dojo.global;
+_5.onError.call(_6,_4,_5);
+}
+};
+var _7=function(_8,_9){
+var _a=_9.abort||null;
+var _b=false;
+var _c=_9.start?_9.start:0;
+var _d=(_9.count&&(_9.count!==Infinity))?(_c+_9.count):_8.length;
+_9.abort=function(){
+_b=true;
+if(_a){
+_a.call(_9);
+}
+};
+var _e=_9.scope||dojo.global;
+if(!_9.store){
+_9.store=_2;
+}
+if(_9.onBegin){
+_9.onBegin.call(_e,_8.length,_9);
+}
+if(_9.sort){
+_8.sort(dojo.data.util.sorter.createSortFunction(_9.sort,_2));
+}
+if(_9.onItem){
+for(var i=_c;(i<_8.length)&&(i<_d);++i){
+var _10=_8[i];
+if(!_b){
+_9.onItem.call(_e,_10,_9);
+}
+}
+}
+if(_9.onComplete&&!_b){
+var _11=null;
+if(!_9.onItem){
+_11=_8.slice(_c,_d);
+}
+_9.onComplete.call(_e,_11,_9);
+}
+};
+this._fetchItems(_1,_7,_3);
+return _1;
+};
+}
diff --git a/dojo/data/util/sorter.js b/dojo/data/util/sorter.js
new file mode 100644
index 0000000..a8699e5
--- /dev/null
+++ b/dojo/data/util/sorter.js
@@ -0,0 +1,64 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.data.util.sorter"]){
+dojo._hasResource["dojo.data.util.sorter"]=true;
+dojo.provide("dojo.data.util.sorter");
+dojo.data.util.sorter.basicComparator=function(a,b){
+var r=-1;
+if(a===null){
+a=undefined;
+}
+if(b===null){
+b=undefined;
+}
+if(a==b){
+r=0;
+}else{
+if(a>b||a==null){
+r=1;
+}
+}
+return r;
+};
+dojo.data.util.sorter.createSortFunction=function(_4,_5){
+var _6=[];
+function _7(_8,_9){
+return function(_a,_b){
+var a=_5.getValue(_a,_8);
+var b=_5.getValue(_b,_8);
+var _e=null;
+if(_5.comparatorMap){
+if(typeof _8!=="string"){
+_8=_5.getIdentity(_8);
+}
+_e=_5.comparatorMap[_8]||dojo.data.util.sorter.basicComparator;
+}
+_e=_e||dojo.data.util.sorter.basicComparator;
+return _9*_e(a,b);
+};
+};
+var _f;
+for(var i=0;i<_4.length;i++){
+_f=_4[i];
+if(_f.attribute){
+var _11=(_f.descending)?-1:1;
+_6.push(_7(_f.attribute,_11));
+}
+}
+return function(_12,_13){
+var i=0;
+while(i<_6.length){
+var ret=_6[i++](_12,_13);
+if(ret!==0){
+return ret;
+}
+}
+return 0;
+};
+};
+}
diff --git a/dojo/date.js b/dojo/date.js
new file mode 100644
index 0000000..25e3ed5
--- /dev/null
+++ b/dojo/date.js
@@ -0,0 +1,218 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.date"]){
+dojo._hasResource["dojo.date"]=true;
+dojo.provide("dojo.date");
+dojo.date.getDaysInMonth=function(_1){
+var _2=_1.getMonth();
+var _3=[31,28,31,30,31,30,31,31,30,31,30,31];
+if(_2==1&&dojo.date.isLeapYear(_1)){
+return 29;
+}
+return _3[_2];
+};
+dojo.date.isLeapYear=function(_4){
+var _5=_4.getFullYear();
+return !(_5%400)||(!(_5%4)&&!!(_5%100));
+};
+dojo.date.getTimezoneName=function(_6){
+var _7=_6.toString();
+var tz="";
+var _9;
+var _a=_7.indexOf("(");
+if(_a>-1){
+tz=_7.substring(++_a,_7.indexOf(")"));
+}else{
+var _b=/([A-Z\/]+) \d{4}$/;
+if((_9=_7.match(_b))){
+tz=_9[1];
+}else{
+_7=_6.toLocaleString();
+_b=/ ([A-Z\/]+)$/;
+if((_9=_7.match(_b))){
+tz=_9[1];
+}
+}
+}
+return (tz=="AM"||tz=="PM")?"":tz;
+};
+dojo.date.compare=function(_c,_d,_e){
+_c=new Date(Number(_c));
+_d=new Date(Number(_d||new Date()));
+if(_e!=="undefined"){
+if(_e=="date"){
+_c.setHours(0,0,0,0);
+_d.setHours(0,0,0,0);
+}else{
+if(_e=="time"){
+_c.setFullYear(0,0,0);
+_d.setFullYear(0,0,0);
+}
+}
+}
+if(_c>_d){
+return 1;
+}
+if(_c<_d){
+return -1;
+}
+return 0;
+};
+dojo.date.add=function(_f,_10,_11){
+var sum=new Date(Number(_f));
+var _13=false;
+var _14="Date";
+switch(_10){
+case "day":
+break;
+case "weekday":
+var _15,_16;
+var mod=_11%5;
+if(!mod){
+_15=(_11>0)?5:-5;
+_16=(_11>0)?((_11-5)/5):((_11+5)/5);
+}else{
+_15=mod;
+_16=parseInt(_11/5);
+}
+var _18=_f.getDay();
+var adj=0;
+if(_18==6&&_11>0){
+adj=1;
+}else{
+if(_18==0&&_11<0){
+adj=-1;
+}
+}
+var _1a=_18+_15;
+if(_1a==0||_1a==6){
+adj=(_11>0)?2:-2;
+}
+_11=(7*_16)+_15+adj;
+break;
+case "year":
+_14="FullYear";
+_13=true;
+break;
+case "week":
+_11*=7;
+break;
+case "quarter":
+_11*=3;
+case "month":
+_13=true;
+_14="Month";
+break;
+case "hour":
+case "minute":
+case "second":
+case "millisecond":
+_14="UTC"+_10.charAt(0).toUpperCase()+_10.substring(1)+"s";
+}
+if(_14){
+sum["set"+_14](sum["get"+_14]()+_11);
+}
+if(_13&&(sum.getDate()<_f.getDate())){
+sum.setDate(0);
+}
+return sum;
+};
+dojo.date.difference=function(_1b,_1c,_1d){
+_1c=_1c||new Date();
+_1d=_1d||"day";
+var _1e=_1c.getFullYear()-_1b.getFullYear();
+var _1f=1;
+switch(_1d){
+case "quarter":
+var m1=_1b.getMonth();
+var m2=_1c.getMonth();
+var q1=Math.floor(m1/3)+1;
+var q2=Math.floor(m2/3)+1;
+q2+=(_1e*4);
+_1f=q2-q1;
+break;
+case "weekday":
+var _24=Math.round(dojo.date.difference(_1b,_1c,"day"));
+var _25=parseInt(dojo.date.difference(_1b,_1c,"week"));
+var mod=_24%7;
+if(mod==0){
+_24=_25*5;
+}else{
+var adj=0;
+var _28=_1b.getDay();
+var _29=_1c.getDay();
+_25=parseInt(_24/7);
+mod=_24%7;
+var _2a=new Date(_1b);
+_2a.setDate(_2a.getDate()+(_25*7));
+var _2b=_2a.getDay();
+if(_24>0){
+switch(true){
+case _28==6:
+adj=-1;
+break;
+case _28==0:
+adj=0;
+break;
+case _29==6:
+adj=-1;
+break;
+case _29==0:
+adj=-2;
+break;
+case (_2b+mod)>5:
+adj=-2;
+}
+}else{
+if(_24<0){
+switch(true){
+case _28==6:
+adj=0;
+break;
+case _28==0:
+adj=1;
+break;
+case _29==6:
+adj=2;
+break;
+case _29==0:
+adj=1;
+break;
+case (_2b+mod)<0:
+adj=2;
+}
+}
+}
+_24+=adj;
+_24-=(_25*2);
+}
+_1f=_24;
+break;
+case "year":
+_1f=_1e;
+break;
+case "month":
+_1f=(_1c.getMonth()-_1b.getMonth())+(_1e*12);
+break;
+case "week":
+_1f=parseInt(dojo.date.difference(_1b,_1c,"day")/7);
+break;
+case "day":
+_1f/=24;
+case "hour":
+_1f/=60;
+case "minute":
+_1f/=60;
+case "second":
+_1f/=1000;
+case "millisecond":
+_1f*=_1c.getTime()-_1b.getTime();
+}
+return Math.round(_1f);
+};
+}
diff --git a/dojo/date/locale.js b/dojo/date/locale.js
new file mode 100644
index 0000000..1e3646f
--- /dev/null
+++ b/dojo/date/locale.js
@@ -0,0 +1,490 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.date.locale"]){
+dojo._hasResource["dojo.date.locale"]=true;
+dojo.provide("dojo.date.locale");
+dojo.require("dojo.date");
+dojo.require("dojo.cldr.supplemental");
+dojo.require("dojo.regexp");
+dojo.require("dojo.string");
+dojo.require("dojo.i18n");
+dojo.requireLocalization("dojo.cldr","gregorian",null,"ROOT,ar,ca,cs,da,de,el,en,en-au,en-ca,en-gb,es,es-es,fi,fr,he,hu,it,it-it,ja,ko,ko-kr,nb,nl,pl,pt,pt-br,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-cn,zh-tw");
+(function(){
+function _1(_2,_3,_4,_5){
+return _5.replace(/([a-z])\1*/ig,function(_6){
+var s,_8;
+var c=_6.charAt(0);
+var l=_6.length;
+var _b=["abbr","wide","narrow"];
+switch(c){
+case "G":
+s=_3[(l<4)?"eraAbbr":"eraNames"][_2.getFullYear()<0?0:1];
+break;
+case "y":
+s=_2.getFullYear();
+switch(l){
+case 1:
+break;
+case 2:
+if(!_4){
+s=String(s);
+s=s.substr(s.length-2);
+break;
+}
+default:
+_8=true;
+}
+break;
+case "Q":
+case "q":
+s=Math.ceil((_2.getMonth()+1)/3);
+_8=true;
+break;
+case "M":
+var m=_2.getMonth();
+if(l<3){
+s=m+1;
+_8=true;
+}else{
+var _d=["months","format",_b[l-3]].join("-");
+s=_3[_d][m];
+}
+break;
+case "w":
+var _e=0;
+s=dojo.date.locale._getWeekOfYear(_2,_e);
+_8=true;
+break;
+case "d":
+s=_2.getDate();
+_8=true;
+break;
+case "D":
+s=dojo.date.locale._getDayOfYear(_2);
+_8=true;
+break;
+case "E":
+var d=_2.getDay();
+if(l<3){
+s=d+1;
+_8=true;
+}else{
+var _10=["days","format",_b[l-3]].join("-");
+s=_3[_10][d];
+}
+break;
+case "a":
+var _11=(_2.getHours()<12)?"am":"pm";
+s=_3[_11];
+break;
+case "h":
+case "H":
+case "K":
+case "k":
+var h=_2.getHours();
+switch(c){
+case "h":
+s=(h%12)||12;
+break;
+case "H":
+s=h;
+break;
+case "K":
+s=(h%12);
+break;
+case "k":
+s=h||24;
+break;
+}
+_8=true;
+break;
+case "m":
+s=_2.getMinutes();
+_8=true;
+break;
+case "s":
+s=_2.getSeconds();
+_8=true;
+break;
+case "S":
+s=Math.round(_2.getMilliseconds()*Math.pow(10,l-3));
+_8=true;
+break;
+case "v":
+case "z":
+s=dojo.date.getTimezoneName(_2);
+if(s){
+break;
+}
+l=4;
+case "Z":
+var _13=_2.getTimezoneOffset();
+var tz=[(_13<=0?"+":"-"),dojo.string.pad(Math.floor(Math.abs(_13)/60),2),dojo.string.pad(Math.abs(_13)%60,2)];
+if(l==4){
+tz.splice(0,0,"GMT");
+tz.splice(3,0,":");
+}
+s=tz.join("");
+break;
+default:
+throw new Error("dojo.date.locale.format: invalid pattern char: "+_5);
+}
+if(_8){
+s=dojo.string.pad(s,l);
+}
+return s;
+});
+};
+dojo.date.locale.format=function(_15,_16){
+_16=_16||{};
+var _17=dojo.i18n.normalizeLocale(_16.locale);
+var _18=_16.formatLength||"short";
+var _19=dojo.date.locale._getGregorianBundle(_17);
+var str=[];
+var _1b=dojo.hitch(this,_1,_15,_19,_16.fullYear);
+if(_16.selector=="year"){
+var _1c=_15.getFullYear();
+if(_17.match(/^zh|^ja/)){
+_1c+="年";
+}
+return _1c;
+}
+if(_16.selector!="time"){
+var _1d=_16.datePattern||_19["dateFormat-"+_18];
+if(_1d){
+str.push(_1e(_1d,_1b));
+}
+}
+if(_16.selector!="date"){
+var _1f=_16.timePattern||_19["timeFormat-"+_18];
+if(_1f){
+str.push(_1e(_1f,_1b));
+}
+}
+var _20=str.join(" ");
+return _20;
+};
+dojo.date.locale.regexp=function(_21){
+return dojo.date.locale._parseInfo(_21).regexp;
+};
+dojo.date.locale._parseInfo=function(_22){
+_22=_22||{};
+var _23=dojo.i18n.normalizeLocale(_22.locale);
+var _24=dojo.date.locale._getGregorianBundle(_23);
+var _25=_22.formatLength||"short";
+var _26=_22.datePattern||_24["dateFormat-"+_25];
+var _27=_22.timePattern||_24["timeFormat-"+_25];
+var _28;
+if(_22.selector=="date"){
+_28=_26;
+}else{
+if(_22.selector=="time"){
+_28=_27;
+}else{
+_28=_26+" "+_27;
+}
+}
+var _29=[];
+var re=_1e(_28,dojo.hitch(this,_2b,_29,_24,_22));
+return {regexp:re,tokens:_29,bundle:_24};
+};
+dojo.date.locale.parse=function(_2c,_2d){
+var _2e=dojo.date.locale._parseInfo(_2d);
+var _2f=_2e.tokens,_30=_2e.bundle;
+var re=new RegExp("^"+_2e.regexp+"$",_2e.strict?"":"i");
+var _32=re.exec(_2c);
+if(!_32){
+return null;
+}
+var _33=["abbr","wide","narrow"];
+var _34=[1970,0,1,0,0,0,0];
+var _35="";
+var _36=dojo.every(_32,function(v,i){
+if(!i){
+return true;
+}
+var _39=_2f[i-1];
+var l=_39.length;
+switch(_39.charAt(0)){
+case "y":
+if(l!=2&&_2d.strict){
+_34[0]=v;
+}else{
+if(v<100){
+v=Number(v);
+var _3b=""+new Date().getFullYear();
+var _3c=_3b.substring(0,2)*100;
+var _3d=Math.min(Number(_3b.substring(2,4))+20,99);
+var num=(v<_3d)?_3c+v:_3c-100+v;
+_34[0]=num;
+}else{
+if(_2d.strict){
+return false;
+}
+_34[0]=v;
+}
+}
+break;
+case "M":
+if(l>2){
+var _3f=_30["months-format-"+_33[l-3]].concat();
+if(!_2d.strict){
+v=v.replace(".","").toLowerCase();
+_3f=dojo.map(_3f,function(s){
+return s.replace(".","").toLowerCase();
+});
+}
+v=dojo.indexOf(_3f,v);
+if(v==-1){
+return false;
+}
+}else{
+v--;
+}
+_34[1]=v;
+break;
+case "E":
+case "e":
+var _41=_30["days-format-"+_33[l-3]].concat();
+if(!_2d.strict){
+v=v.toLowerCase();
+_41=dojo.map(_41,function(d){
+return d.toLowerCase();
+});
+}
+v=dojo.indexOf(_41,v);
+if(v==-1){
+return false;
+}
+break;
+case "D":
+_34[1]=0;
+case "d":
+_34[2]=v;
+break;
+case "a":
+var am=_2d.am||_30.am;
+var pm=_2d.pm||_30.pm;
+if(!_2d.strict){
+var _45=/\./g;
+v=v.replace(_45,"").toLowerCase();
+am=am.replace(_45,"").toLowerCase();
+pm=pm.replace(_45,"").toLowerCase();
+}
+if(_2d.strict&&v!=am&&v!=pm){
+return false;
+}
+_35=(v==pm)?"p":(v==am)?"a":"";
+break;
+case "K":
+if(v==24){
+v=0;
+}
+case "h":
+case "H":
+case "k":
+if(v>23){
+return false;
+}
+_34[3]=v;
+break;
+case "m":
+_34[4]=v;
+break;
+case "s":
+_34[5]=v;
+break;
+case "S":
+_34[6]=v;
+}
+return true;
+});
+var _46=+_34[3];
+if(_35==="p"&&_46<12){
+_34[3]=_46+12;
+}else{
+if(_35==="a"&&_46==12){
+_34[3]=0;
+}
+}
+var _47=new Date(_34[0],_34[1],_34[2],_34[3],_34[4],_34[5],_34[6]);
+if(_2d.strict){
+_47.setFullYear(_34[0]);
+}
+var _48=_2f.join(""),_49=_48.indexOf("d")!=-1,_4a=_48.indexOf("M")!=-1;
+if(!_36||(_4a&&_47.getMonth()>_34[1])||(_49&&_47.getDate()>_34[2])){
+return null;
+}
+if((_4a&&_47.getMonth()<_34[1])||(_49&&_47.getDate()<_34[2])){
+_47=dojo.date.add(_47,"hour",1);
+}
+return _47;
+};
+function _1e(_4b,_4c,_4d,_4e){
+var _4f=function(x){
+return x;
+};
+_4c=_4c||_4f;
+_4d=_4d||_4f;
+_4e=_4e||_4f;
+var _51=_4b.match(/(''|[^'])+/g);
+var _52=_4b.charAt(0)=="'";
+dojo.forEach(_51,function(_53,i){
+if(!_53){
+_51[i]="";
+}else{
+_51[i]=(_52?_4d:_4c)(_53);
+_52=!_52;
+}
+});
+return _4e(_51.join(""));
+};
+function _2b(_55,_56,_57,_58){
+_58=dojo.regexp.escapeString(_58);
+if(!_57.strict){
+_58=_58.replace(" a"," ?a");
+}
+return _58.replace(/([a-z])\1*/ig,function(_59){
+var s;
+var c=_59.charAt(0);
+var l=_59.length;
+var p2="",p3="";
+if(_57.strict){
+if(l>1){
+p2="0"+"{"+(l-1)+"}";
+}
+if(l>2){
+p3="0"+"{"+(l-2)+"}";
+}
+}else{
+p2="0?";
+p3="0{0,2}";
+}
+switch(c){
+case "y":
+s="\\d{2,4}";
+break;
+case "M":
+s=(l>2)?"\\S+?":p2+"[1-9]|1[0-2]";
+break;
+case "D":
+s=p2+"[1-9]|"+p3+"[1-9][0-9]|[12][0-9][0-9]|3[0-5][0-9]|36[0-6]";
+break;
+case "d":
+s="[12]\\d|"+p2+"[1-9]|3[01]";
+break;
+case "w":
+s=p2+"[1-9]|[1-4][0-9]|5[0-3]";
+break;
+case "E":
+s="\\S+";
+break;
+case "h":
+s=p2+"[1-9]|1[0-2]";
+break;
+case "k":
+s=p2+"\\d|1[01]";
+break;
+case "H":
+s=p2+"\\d|1\\d|2[0-3]";
+break;
+case "K":
+s=p2+"[1-9]|1\\d|2[0-4]";
+break;
+case "m":
+case "s":
+s="[0-5]\\d";
+break;
+case "S":
+s="\\d{"+l+"}";
+break;
+case "a":
+var am=_57.am||_56.am||"AM";
+var pm=_57.pm||_56.pm||"PM";
+if(_57.strict){
+s=am+"|"+pm;
+}else{
+s=am+"|"+pm;
+if(am!=am.toLowerCase()){
+s+="|"+am.toLowerCase();
+}
+if(pm!=pm.toLowerCase()){
+s+="|"+pm.toLowerCase();
+}
+if(s.indexOf(".")!=-1){
+s+="|"+s.replace(/\./g,"");
+}
+}
+s=s.replace(/\./g,"\\.");
+break;
+default:
+s=".*";
+}
+if(_55){
+_55.push(_59);
+}
+return "("+s+")";
+}).replace(/[\xa0 ]/g,"[\\s\\xa0]");
+};
+})();
+(function(){
+var _61=[];
+dojo.date.locale.addCustomFormats=function(_62,_63){
+_61.push({pkg:_62,name:_63});
+};
+dojo.date.locale._getGregorianBundle=function(_64){
+var _65={};
+dojo.forEach(_61,function(_66){
+var _67=dojo.i18n.getLocalization(_66.pkg,_66.name,_64);
+_65=dojo.mixin(_65,_67);
+},this);
+return _65;
+};
+})();
+dojo.date.locale.addCustomFormats("dojo.cldr","gregorian");
+dojo.date.locale.getNames=function(_68,_69,_6a,_6b){
+var _6c;
+var _6d=dojo.date.locale._getGregorianBundle(_6b);
+var _6e=[_68,_6a,_69];
+if(_6a=="standAlone"){
+var key=_6e.join("-");
+_6c=_6d[key];
+if(_6c[0]==1){
+_6c=undefined;
+}
+}
+_6e[1]="format";
+return (_6c||_6d[_6e.join("-")]).concat();
+};
+dojo.date.locale.isWeekend=function(_70,_71){
+var _72=dojo.cldr.supplemental.getWeekend(_71);
+var day=(_70||new Date()).getDay();
+if(_72.end<_72.start){
+_72.end+=7;
+if(day<_72.start){
+day+=7;
+}
+}
+return day>=_72.start&&day<=_72.end;
+};
+dojo.date.locale._getDayOfYear=function(_74){
+return dojo.date.difference(new Date(_74.getFullYear(),0,1,_74.getHours()),_74)+1;
+};
+dojo.date.locale._getWeekOfYear=function(_75,_76){
+if(arguments.length==1){
+_76=0;
+}
+var _77=new Date(_75.getFullYear(),0,1).getDay();
+var adj=(_77-_76+7)%7;
+var _79=Math.floor((dojo.date.locale._getDayOfYear(_75)+adj-1)/7);
+if(_77==_76){
+_79++;
+}
+return _79;
+};
+}
diff --git a/dojo/date/stamp.js b/dojo/date/stamp.js
new file mode 100644
index 0000000..7f39a67
--- /dev/null
+++ b/dojo/date/stamp.js
@@ -0,0 +1,85 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.date.stamp"]){
+dojo._hasResource["dojo.date.stamp"]=true;
+dojo.provide("dojo.date.stamp");
+dojo.date.stamp.fromISOString=function(_1,_2){
+if(!dojo.date.stamp._isoRegExp){
+dojo.date.stamp._isoRegExp=/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(.\d+)?)?((?:[+-](\d{2}):(\d{2}))|Z)?)?$/;
+}
+var _3=dojo.date.stamp._isoRegExp.exec(_1);
+var _4=null;
+if(_3){
+_3.shift();
+if(_3[1]){
+_3[1]--;
+}
+if(_3[6]){
+_3[6]*=1000;
+}
+if(_2){
+_2=new Date(_2);
+dojo.map(["FullYear","Month","Date","Hours","Minutes","Seconds","Milliseconds"],function(_5){
+return _2["get"+_5]();
+}).forEach(function(_6,_7){
+if(_3[_7]===undefined){
+_3[_7]=_6;
+}
+});
+}
+_4=new Date(_3[0]||1970,_3[1]||0,_3[2]||1,_3[3]||0,_3[4]||0,_3[5]||0,_3[6]||0);
+var _8=0;
+var _9=_3[7]&&_3[7].charAt(0);
+if(_9!="Z"){
+_8=((_3[8]||0)*60)+(Number(_3[9])||0);
+if(_9!="-"){
+_8*=-1;
+}
+}
+if(_9){
+_8-=_4.getTimezoneOffset();
+}
+if(_8){
+_4.setTime(_4.getTime()+_8*60000);
+}
+}
+return _4;
+};
+dojo.date.stamp.toISOString=function(_a,_b){
+var _=function(n){
+return (n<10)?"0"+n:n;
+};
+_b=_b||{};
+var _e=[];
+var _f=_b.zulu?"getUTC":"get";
+var _10="";
+if(_b.selector!="time"){
+var _11=_a[_f+"FullYear"]();
+_10=["0000".substr((_11+"").length)+_11,_(_a[_f+"Month"]()+1),_(_a[_f+"Date"]())].join("-");
+}
+_e.push(_10);
+if(_b.selector!="date"){
+var _12=[_(_a[_f+"Hours"]()),_(_a[_f+"Minutes"]()),_(_a[_f+"Seconds"]())].join(":");
+var _13=_a[_f+"Milliseconds"]();
+if(_b.milliseconds){
+_12+="."+(_13<100?"0":"")+_(_13);
+}
+if(_b.zulu){
+_12+="Z";
+}else{
+if(_b.selector!="time"){
+var _14=_a.getTimezoneOffset();
+var _15=Math.abs(_14);
+_12+=(_14>0?"-":"+")+_(Math.floor(_15/60))+":"+_(_15%60);
+}
+}
+_e.push(_12);
+}
+return _e.join("T");
+};
+}
diff --git a/dojo/dnd/Avatar.js b/dojo/dnd/Avatar.js
new file mode 100644
index 0000000..a2ae36d
--- /dev/null
+++ b/dojo/dnd/Avatar.js
@@ -0,0 +1,47 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.dnd.Avatar"]){
+dojo._hasResource["dojo.dnd.Avatar"]=true;
+dojo.provide("dojo.dnd.Avatar");
+dojo.require("dojo.dnd.common");
+dojo.declare("dojo.dnd.Avatar",null,{constructor:function(_1){
+this.manager=_1;
+this.construct();
+},construct:function(){
+var a=dojo.create("table",{"class":"dojoDndAvatar",style:{position:"absolute",zIndex:"1999",margin:"0px"}}),b=dojo.create("tbody",null,a),tr=dojo.create("tr",null,b),td=dojo.create("td",{innerHTML:this._generateText()},tr),k=Math.min(5,this.manager.nodes.length),i=0,_8=this.manager.source,_9;
+dojo.attr(tr,{"class":"dojoDndAvatarHeader",style:{opacity:0.9}});
+for(;i<k;++i){
+if(_8.creator){
+_9=_8._normalizedCreator(_8.getItem(this.manager.nodes[i].id).data,"avatar").node;
+}else{
+_9=this.manager.nodes[i].cloneNode(true);
+if(_9.tagName.toLowerCase()=="tr"){
+var _a=dojo.create("table"),_b=dojo.create("tbody",null,_a);
+_b.appendChild(_9);
+_9=_a;
+}
+}
+_9.id="";
+tr=dojo.create("tr",null,b);
+td=dojo.create("td",null,tr);
+td.appendChild(_9);
+dojo.attr(tr,{"class":"dojoDndAvatarItem",style:{opacity:(9-i)/10}});
+}
+this.node=a;
+},destroy:function(){
+dojo.destroy(this.node);
+this.node=false;
+},update:function(){
+dojo[(this.manager.canDropFlag?"add":"remove")+"Class"](this.node,"dojoDndAvatarCanDrop");
+dojo.query("tr.dojoDndAvatarHeader td",this.node).forEach(function(_c){
+_c.innerHTML=this._generateText();
+},this);
+},_generateText:function(){
+return this.manager.nodes.length.toString();
+}});
+}
diff --git a/dojo/dnd/Container.js b/dojo/dnd/Container.js
new file mode 100644
index 0000000..c2cf260
--- /dev/null
+++ b/dojo/dnd/Container.js
@@ -0,0 +1,233 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.dnd.Container"]){
+dojo._hasResource["dojo.dnd.Container"]=true;
+dojo.provide("dojo.dnd.Container");
+dojo.require("dojo.dnd.common");
+dojo.require("dojo.parser");
+dojo.declare("dojo.dnd.Container",null,{skipForm:false,constructor:function(_1,_2){
+this.node=dojo.byId(_1);
+if(!_2){
+_2={};
+}
+this.creator=_2.creator||null;
+this.skipForm=_2.skipForm;
+this.parent=_2.dropParent&&dojo.byId(_2.dropParent);
+this.map={};
+this.current=null;
+this.containerState="";
+dojo.addClass(this.node,"dojoDndContainer");
+if(!(_2&&_2._skipStartup)){
+this.startup();
+}
+this.events=[dojo.connect(this.node,"onmouseover",this,"onMouseOver"),dojo.connect(this.node,"onmouseout",this,"onMouseOut"),dojo.connect(this.node,"ondragstart",this,"onSelectStart"),dojo.connect(this.node,"onselectstart",this,"onSelectStart")];
+},creator:function(){
+},getItem:function(_3){
+return this.map[_3];
+},setItem:function(_4,_5){
+this.map[_4]=_5;
+},delItem:function(_6){
+delete this.map[_6];
+},forInItems:function(f,o){
+o=o||dojo.global;
+var m=this.map,e=dojo.dnd._empty;
+for(var i in m){
+if(i in e){
+continue;
+}
+f.call(o,m[i],i,this);
+}
+return o;
+},clearItems:function(){
+this.map={};
+},getAllNodes:function(){
+return dojo.query("> .dojoDndItem",this.parent);
+},sync:function(){
+var _c={};
+this.getAllNodes().forEach(function(_d){
+if(_d.id){
+var _e=this.getItem(_d.id);
+if(_e){
+_c[_d.id]=_e;
+return;
+}
+}else{
+_d.id=dojo.dnd.getUniqueId();
+}
+var _f=_d.getAttribute("dndType"),_10=_d.getAttribute("dndData");
+_c[_d.id]={data:_10||_d.innerHTML,type:_f?_f.split(/\s*,\s*/):["text"]};
+},this);
+this.map=_c;
+return this;
+},insertNodes:function(_11,_12,_13){
+if(!this.parent.firstChild){
+_13=null;
+}else{
+if(_12){
+if(!_13){
+_13=this.parent.firstChild;
+}
+}else{
+if(_13){
+_13=_13.nextSibling;
+}
+}
+}
+if(_13){
+for(var i=0;i<_11.length;++i){
+var t=this._normalizedCreator(_11[i]);
+this.setItem(t.node.id,{data:t.data,type:t.type});
+this.parent.insertBefore(t.node,_13);
+}
+}else{
+for(var i=0;i<_11.length;++i){
+var t=this._normalizedCreator(_11[i]);
+this.setItem(t.node.id,{data:t.data,type:t.type});
+this.parent.appendChild(t.node);
+}
+}
+return this;
+},destroy:function(){
+dojo.forEach(this.events,dojo.disconnect);
+this.clearItems();
+this.node=this.parent=this.current=null;
+},markupFactory:function(_16,_17){
+_16._skipStartup=true;
+return new dojo.dnd.Container(_17,_16);
+},startup:function(){
+if(!this.parent){
+this.parent=this.node;
+if(this.parent.tagName.toLowerCase()=="table"){
+var c=this.parent.getElementsByTagName("tbody");
+if(c&&c.length){
+this.parent=c[0];
+}
+}
+}
+this.defaultCreator=dojo.dnd._defaultCreator(this.parent);
+this.sync();
+},onMouseOver:function(e){
+var n=e.relatedTarget;
+while(n){
+if(n==this.node){
+break;
+}
+try{
+n=n.parentNode;
+}
+catch(x){
+n=null;
+}
+}
+if(!n){
+this._changeState("Container","Over");
+this.onOverEvent();
+}
+n=this._getChildByEvent(e);
+if(this.current==n){
+return;
+}
+if(this.current){
+this._removeItemClass(this.current,"Over");
+}
+if(n){
+this._addItemClass(n,"Over");
+}
+this.current=n;
+},onMouseOut:function(e){
+for(var n=e.relatedTarget;n;){
+if(n==this.node){
+return;
+}
+try{
+n=n.parentNode;
+}
+catch(x){
+n=null;
+}
+}
+if(this.current){
+this._removeItemClass(this.current,"Over");
+this.current=null;
+}
+this._changeState("Container","");
+this.onOutEvent();
+},onSelectStart:function(e){
+if(!this.skipForm||!dojo.dnd.isFormElement(e)){
+dojo.stopEvent(e);
+}
+},onOverEvent:function(){
+},onOutEvent:function(){
+},_changeState:function(_1e,_1f){
+var _20="dojoDnd"+_1e;
+var _21=_1e.toLowerCase()+"State";
+dojo.removeClass(this.node,_20+this[_21]);
+dojo.addClass(this.node,_20+_1f);
+this[_21]=_1f;
+},_addItemClass:function(_22,_23){
+dojo.addClass(_22,"dojoDndItem"+_23);
+},_removeItemClass:function(_24,_25){
+dojo.removeClass(_24,"dojoDndItem"+_25);
+},_getChildByEvent:function(e){
+var _27=e.target;
+if(_27){
+for(var _28=_27.parentNode;_28;_27=_28,_28=_27.parentNode){
+if(_28==this.parent&&dojo.hasClass(_27,"dojoDndItem")){
+return _27;
+}
+}
+}
+return null;
+},_normalizedCreator:function(_29,_2a){
+var t=(this.creator||this.defaultCreator).call(this,_29,_2a);
+if(!dojo.isArray(t.type)){
+t.type=["text"];
+}
+if(!t.node.id){
+t.node.id=dojo.dnd.getUniqueId();
+}
+dojo.addClass(t.node,"dojoDndItem");
+return t;
+}});
+dojo.dnd._createNode=function(tag){
+if(!tag){
+return dojo.dnd._createSpan;
+}
+return function(_2d){
+return dojo.create(tag,{innerHTML:_2d});
+};
+};
+dojo.dnd._createTrTd=function(_2e){
+var tr=dojo.create("tr");
+dojo.create("td",{innerHTML:_2e},tr);
+return tr;
+};
+dojo.dnd._createSpan=function(_30){
+return dojo.create("span",{innerHTML:_30});
+};
+dojo.dnd._defaultCreatorNodes={ul:"li",ol:"li",div:"div",p:"div"};
+dojo.dnd._defaultCreator=function(_31){
+var tag=_31.tagName.toLowerCase();
+var c=tag=="tbody"||tag=="thead"?dojo.dnd._createTrTd:dojo.dnd._createNode(dojo.dnd._defaultCreatorNodes[tag]);
+return function(_34,_35){
+var _36=_34&&dojo.isObject(_34),_37,_38,n;
+if(_36&&_34.tagName&&_34.nodeType&&_34.getAttribute){
+_37=_34.getAttribute("dndData")||_34.innerHTML;
+_38=_34.getAttribute("dndType");
+_38=_38?_38.split(/\s*,\s*/):["text"];
+n=_34;
+}else{
+_37=(_36&&_34.data)?_34.data:_34;
+_38=(_36&&_34.type)?_34.type:["text"];
+n=(_35=="avatar"?dojo.dnd._createSpan:c)(String(_37));
+}
+n.id=dojo.dnd.getUniqueId();
+return {node:n,data:_37,type:_38};
+};
+};
+}
diff --git a/dojo/dnd/Manager.js b/dojo/dnd/Manager.js
new file mode 100644
index 0000000..eff1bcf
--- /dev/null
+++ b/dojo/dnd/Manager.js
@@ -0,0 +1,128 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.dnd.Manager"]){
+dojo._hasResource["dojo.dnd.Manager"]=true;
+dojo.provide("dojo.dnd.Manager");
+dojo.require("dojo.dnd.common");
+dojo.require("dojo.dnd.autoscroll");
+dojo.require("dojo.dnd.Avatar");
+dojo.declare("dojo.dnd.Manager",null,{constructor:function(){
+this.avatar=null;
+this.source=null;
+this.nodes=[];
+this.copy=true;
+this.target=null;
+this.canDropFlag=false;
+this.events=[];
+},OFFSET_X:16,OFFSET_Y:16,overSource:function(_1){
+if(this.avatar){
+this.target=(_1&&_1.targetState!="Disabled")?_1:null;
+this.canDropFlag=Boolean(this.target);
+this.avatar.update();
+}
+dojo.publish("/dnd/source/over",[_1]);
+},outSource:function(_2){
+if(this.avatar){
+if(this.target==_2){
+this.target=null;
+this.canDropFlag=false;
+this.avatar.update();
+dojo.publish("/dnd/source/over",[null]);
+}
+}else{
+dojo.publish("/dnd/source/over",[null]);
+}
+},startDrag:function(_3,_4,_5){
+this.source=_3;
+this.nodes=_4;
+this.copy=Boolean(_5);
+this.avatar=this.makeAvatar();
+dojo.body().appendChild(this.avatar.node);
+dojo.publish("/dnd/start",[_3,_4,this.copy]);
+this.events=[dojo.connect(dojo.doc,"onmousemove",this,"onMouseMove"),dojo.connect(dojo.doc,"onmouseup",this,"onMouseUp"),dojo.connect(dojo.doc,"onkeydown",this,"onKeyDown"),dojo.connect(dojo.doc,"onkeyup",this,"onKeyUp"),dojo.connect(dojo.doc,"ondragstart",dojo.stopEvent),dojo.connect(dojo.body(),"onselectstart",dojo.stopEvent)];
+var c="dojoDnd"+(_5?"Copy":"Move");
+dojo.addClass(dojo.body(),c);
+},canDrop:function(_7){
+var _8=Boolean(this.target&&_7);
+if(this.canDropFlag!=_8){
+this.canDropFlag=_8;
+this.avatar.update();
+}
+},stopDrag:function(){
+dojo.removeClass(dojo.body(),"dojoDndCopy");
+dojo.removeClass(dojo.body(),"dojoDndMove");
+dojo.forEach(this.events,dojo.disconnect);
+this.events=[];
+this.avatar.destroy();
+this.avatar=null;
+this.source=this.target=null;
+this.nodes=[];
+},makeAvatar:function(){
+return new dojo.dnd.Avatar(this);
+},updateAvatar:function(){
+this.avatar.update();
+},onMouseMove:function(e){
+var a=this.avatar;
+if(a){
+dojo.dnd.autoScrollNodes(e);
+var s=a.node.style;
+s.left=(e.pageX+this.OFFSET_X)+"px";
+s.top=(e.pageY+this.OFFSET_Y)+"px";
+var _c=Boolean(this.source.copyState(dojo.dnd.getCopyKeyState(e)));
+if(this.copy!=_c){
+this._setCopyStatus(_c);
+}
+}
+},onMouseUp:function(e){
+if(this.avatar){
+if(this.target&&this.canDropFlag){
+var _e=Boolean(this.source.copyState(dojo.dnd.getCopyKeyState(e))),_f=[this.source,this.nodes,_e,this.target];
+dojo.publish("/dnd/drop/before",_f);
+dojo.publish("/dnd/drop",_f);
+}else{
+dojo.publish("/dnd/cancel");
+}
+this.stopDrag();
+}
+},onKeyDown:function(e){
+if(this.avatar){
+switch(e.keyCode){
+case dojo.keys.CTRL:
+var _11=Boolean(this.source.copyState(true));
+if(this.copy!=_11){
+this._setCopyStatus(_11);
+}
+break;
+case dojo.keys.ESCAPE:
+dojo.publish("/dnd/cancel");
+this.stopDrag();
+break;
+}
+}
+},onKeyUp:function(e){
+if(this.avatar&&e.keyCode==dojo.keys.CTRL){
+var _13=Boolean(this.source.copyState(false));
+if(this.copy!=_13){
+this._setCopyStatus(_13);
+}
+}
+},_setCopyStatus:function(_14){
+this.copy=_14;
+this.source._markDndStatus(this.copy);
+this.updateAvatar();
+dojo.removeClass(dojo.body(),"dojoDnd"+(this.copy?"Move":"Copy"));
+dojo.addClass(dojo.body(),"dojoDnd"+(this.copy?"Copy":"Move"));
+}});
+dojo.dnd._manager=null;
+dojo.dnd.manager=function(){
+if(!dojo.dnd._manager){
+dojo.dnd._manager=new dojo.dnd.Manager();
+}
+return dojo.dnd._manager;
+};
+}
diff --git a/dojo/dnd/Moveable.js b/dojo/dnd/Moveable.js
new file mode 100644
index 0000000..f40872d
--- /dev/null
+++ b/dojo/dnd/Moveable.js
@@ -0,0 +1,77 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.dnd.Moveable"]){
+dojo._hasResource["dojo.dnd.Moveable"]=true;
+dojo.provide("dojo.dnd.Moveable");
+dojo.require("dojo.dnd.Mover");
+dojo.declare("dojo.dnd.Moveable",null,{handle:"",delay:0,skip:false,constructor:function(_1,_2){
+this.node=dojo.byId(_1);
+if(!_2){
+_2={};
+}
+this.handle=_2.handle?dojo.byId(_2.handle):null;
+if(!this.handle){
+this.handle=this.node;
+}
+this.delay=_2.delay>0?_2.delay:0;
+this.skip=_2.skip;
+this.mover=_2.mover?_2.mover:dojo.dnd.Mover;
+this.events=[dojo.connect(this.handle,"onmousedown",this,"onMouseDown"),dojo.connect(this.handle,"ondragstart",this,"onSelectStart"),dojo.connect(this.handle,"onselectstart",this,"onSelectStart")];
+},markupFactory:function(_3,_4){
+return new dojo.dnd.Moveable(_4,_3);
+},destroy:function(){
+dojo.forEach(this.events,dojo.disconnect);
+this.events=this.node=this.handle=null;
+},onMouseDown:function(e){
+if(this.skip&&dojo.dnd.isFormElement(e)){
+return;
+}
+if(this.delay){
+this.events.push(dojo.connect(this.handle,"onmousemove",this,"onMouseMove"),dojo.connect(this.handle,"onmouseup",this,"onMouseUp"));
+this._lastX=e.pageX;
+this._lastY=e.pageY;
+}else{
+this.onDragDetected(e);
+}
+dojo.stopEvent(e);
+},onMouseMove:function(e){
+if(Math.abs(e.pageX-this._lastX)>this.delay||Math.abs(e.pageY-this._lastY)>this.delay){
+this.onMouseUp(e);
+this.onDragDetected(e);
+}
+dojo.stopEvent(e);
+},onMouseUp:function(e){
+for(var i=0;i<2;++i){
+dojo.disconnect(this.events.pop());
+}
+dojo.stopEvent(e);
+},onSelectStart:function(e){
+if(!this.skip||!dojo.dnd.isFormElement(e)){
+dojo.stopEvent(e);
+}
+},onDragDetected:function(e){
+new this.mover(this.node,e,this);
+},onMoveStart:function(_b){
+dojo.publish("/dnd/move/start",[_b]);
+dojo.addClass(dojo.body(),"dojoMove");
+dojo.addClass(this.node,"dojoMoveItem");
+},onMoveStop:function(_c){
+dojo.publish("/dnd/move/stop",[_c]);
+dojo.removeClass(dojo.body(),"dojoMove");
+dojo.removeClass(this.node,"dojoMoveItem");
+},onFirstMove:function(_d){
+},onMove:function(_e,_f){
+this.onMoving(_e,_f);
+var s=_e.node.style;
+s.left=_f.l+"px";
+s.top=_f.t+"px";
+this.onMoved(_e,_f);
+},onMoving:function(_11,_12){
+},onMoved:function(_13,_14){
+}});
+}
diff --git a/dojo/dnd/Mover.js b/dojo/dnd/Mover.js
new file mode 100644
index 0000000..aca35aa
--- /dev/null
+++ b/dojo/dnd/Mover.js
@@ -0,0 +1,65 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.dnd.Mover"]){
+dojo._hasResource["dojo.dnd.Mover"]=true;
+dojo.provide("dojo.dnd.Mover");
+dojo.require("dojo.dnd.common");
+dojo.require("dojo.dnd.autoscroll");
+dojo.declare("dojo.dnd.Mover",null,{constructor:function(_1,e,_3){
+this.node=dojo.byId(_1);
+this.marginBox={l:e.pageX,t:e.pageY};
+this.mouseButton=e.button;
+var h=this.host=_3,d=_1.ownerDocument,_6=dojo.connect(d,"onmousemove",this,"onFirstMove");
+this.events=[dojo.connect(d,"onmousemove",this,"onMouseMove"),dojo.connect(d,"onmouseup",this,"onMouseUp"),dojo.connect(d,"ondragstart",dojo.stopEvent),dojo.connect(d.body,"onselectstart",dojo.stopEvent),_6];
+if(h&&h.onMoveStart){
+h.onMoveStart(this);
+}
+},onMouseMove:function(e){
+dojo.dnd.autoScroll(e);
+var m=this.marginBox;
+this.host.onMove(this,{l:m.l+e.pageX,t:m.t+e.pageY});
+dojo.stopEvent(e);
+},onMouseUp:function(e){
+if(dojo.isWebKit&&dojo.dnd._isMac&&this.mouseButton==2?e.button==0:this.mouseButton==e.button){
+this.destroy();
+}
+dojo.stopEvent(e);
+},onFirstMove:function(){
+var s=this.node.style,l,t,h=this.host;
+switch(s.position){
+case "relative":
+case "absolute":
+l=Math.round(parseFloat(s.left));
+t=Math.round(parseFloat(s.top));
+break;
+default:
+s.position="absolute";
+var m=dojo.marginBox(this.node);
+var b=dojo.doc.body;
+var bs=dojo.getComputedStyle(b);
+var bm=dojo._getMarginBox(b,bs);
+var bc=dojo._getContentBox(b,bs);
+l=m.l-(bc.l-bm.l);
+t=m.t-(bc.t-bm.t);
+break;
+}
+this.marginBox.l=l-this.marginBox.l;
+this.marginBox.t=t-this.marginBox.t;
+if(h&&h.onFirstMove){
+h.onFirstMove(this);
+}
+dojo.disconnect(this.events.pop());
+},destroy:function(){
+dojo.forEach(this.events,dojo.disconnect);
+var h=this.host;
+if(h&&h.onMoveStop){
+h.onMoveStop(this);
+}
+this.events=this.node=this.host=null;
+}});
+}
diff --git a/dojo/dnd/Selector.js b/dojo/dnd/Selector.js
new file mode 100644
index 0000000..c0b5c1f
--- /dev/null
+++ b/dojo/dnd/Selector.js
@@ -0,0 +1,239 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.dnd.Selector"]){
+dojo._hasResource["dojo.dnd.Selector"]=true;
+dojo.provide("dojo.dnd.Selector");
+dojo.require("dojo.dnd.common");
+dojo.require("dojo.dnd.Container");
+dojo.declare("dojo.dnd.Selector",dojo.dnd.Container,{constructor:function(_1,_2){
+if(!_2){
+_2={};
+}
+this.singular=_2.singular;
+this.autoSync=_2.autoSync;
+this.selection={};
+this.anchor=null;
+this.simpleSelection=false;
+this.events.push(dojo.connect(this.node,"onmousedown",this,"onMouseDown"),dojo.connect(this.node,"onmouseup",this,"onMouseUp"));
+},singular:false,getSelectedNodes:function(){
+var t=new dojo.NodeList();
+var e=dojo.dnd._empty;
+for(var i in this.selection){
+if(i in e){
+continue;
+}
+t.push(dojo.byId(i));
+}
+return t;
+},selectNone:function(){
+return this._removeSelection()._removeAnchor();
+},selectAll:function(){
+this.forInItems(function(_6,id){
+this._addItemClass(dojo.byId(id),"Selected");
+this.selection[id]=1;
+},this);
+return this._removeAnchor();
+},deleteSelectedNodes:function(){
+var e=dojo.dnd._empty;
+for(var i in this.selection){
+if(i in e){
+continue;
+}
+var n=dojo.byId(i);
+this.delItem(i);
+dojo.destroy(n);
+}
+this.anchor=null;
+this.selection={};
+return this;
+},forInSelectedItems:function(f,o){
+o=o||dojo.global;
+var s=this.selection,e=dojo.dnd._empty;
+for(var i in s){
+if(i in e){
+continue;
+}
+f.call(o,this.getItem(i),i,this);
+}
+},sync:function(){
+dojo.dnd.Selector.superclass.sync.call(this);
+if(this.anchor){
+if(!this.getItem(this.anchor.id)){
+this.anchor=null;
+}
+}
+var t=[],e=dojo.dnd._empty;
+for(var i in this.selection){
+if(i in e){
+continue;
+}
+if(!this.getItem(i)){
+t.push(i);
+}
+}
+dojo.forEach(t,function(i){
+delete this.selection[i];
+},this);
+return this;
+},insertNodes:function(_14,_15,_16,_17){
+var _18=this._normalizedCreator;
+this._normalizedCreator=function(_19,_1a){
+var t=_18.call(this,_19,_1a);
+if(_14){
+if(!this.anchor){
+this.anchor=t.node;
+this._removeItemClass(t.node,"Selected");
+this._addItemClass(this.anchor,"Anchor");
+}else{
+if(this.anchor!=t.node){
+this._removeItemClass(t.node,"Anchor");
+this._addItemClass(t.node,"Selected");
+}
+}
+this.selection[t.node.id]=1;
+}else{
+this._removeItemClass(t.node,"Selected");
+this._removeItemClass(t.node,"Anchor");
+}
+return t;
+};
+dojo.dnd.Selector.superclass.insertNodes.call(this,_15,_16,_17);
+this._normalizedCreator=_18;
+return this;
+},destroy:function(){
+dojo.dnd.Selector.superclass.destroy.call(this);
+this.selection=this.anchor=null;
+},markupFactory:function(_1c,_1d){
+_1c._skipStartup=true;
+return new dojo.dnd.Selector(_1d,_1c);
+},onMouseDown:function(e){
+if(this.autoSync){
+this.sync();
+}
+if(!this.current){
+return;
+}
+if(!this.singular&&!dojo.dnd.getCopyKeyState(e)&&!e.shiftKey&&(this.current.id in this.selection)){
+this.simpleSelection=true;
+if(e.button===dojo.dnd._lmb){
+dojo.stopEvent(e);
+}
+return;
+}
+if(!this.singular&&e.shiftKey){
+if(!dojo.dnd.getCopyKeyState(e)){
+this._removeSelection();
+}
+var c=this.getAllNodes();
+if(c.length){
+if(!this.anchor){
+this.anchor=c[0];
+this._addItemClass(this.anchor,"Anchor");
+}
+this.selection[this.anchor.id]=1;
+if(this.anchor!=this.current){
+var i=0;
+for(;i<c.length;++i){
+var _21=c[i];
+if(_21==this.anchor||_21==this.current){
+break;
+}
+}
+for(++i;i<c.length;++i){
+var _21=c[i];
+if(_21==this.anchor||_21==this.current){
+break;
+}
+this._addItemClass(_21,"Selected");
+this.selection[_21.id]=1;
+}
+this._addItemClass(this.current,"Selected");
+this.selection[this.current.id]=1;
+}
+}
+}else{
+if(this.singular){
+if(this.anchor==this.current){
+if(dojo.dnd.getCopyKeyState(e)){
+this.selectNone();
+}
+}else{
+this.selectNone();
+this.anchor=this.current;
+this._addItemClass(this.anchor,"Anchor");
+this.selection[this.current.id]=1;
+}
+}else{
+if(dojo.dnd.getCopyKeyState(e)){
+if(this.anchor==this.current){
+delete this.selection[this.anchor.id];
+this._removeAnchor();
+}else{
+if(this.current.id in this.selection){
+this._removeItemClass(this.current,"Selected");
+delete this.selection[this.current.id];
+}else{
+if(this.anchor){
+this._removeItemClass(this.anchor,"Anchor");
+this._addItemClass(this.anchor,"Selected");
+}
+this.anchor=this.current;
+this._addItemClass(this.current,"Anchor");
+this.selection[this.current.id]=1;
+}
+}
+}else{
+if(!(this.current.id in this.selection)){
+this.selectNone();
+this.anchor=this.current;
+this._addItemClass(this.current,"Anchor");
+this.selection[this.current.id]=1;
+}
+}
+}
+}
+dojo.stopEvent(e);
+},onMouseUp:function(e){
+if(!this.simpleSelection){
+return;
+}
+this.simpleSelection=false;
+this.selectNone();
+if(this.current){
+this.anchor=this.current;
+this._addItemClass(this.anchor,"Anchor");
+this.selection[this.current.id]=1;
+}
+},onMouseMove:function(e){
+this.simpleSelection=false;
+},onOverEvent:function(){
+this.onmousemoveEvent=dojo.connect(this.node,"onmousemove",this,"onMouseMove");
+},onOutEvent:function(){
+dojo.disconnect(this.onmousemoveEvent);
+delete this.onmousemoveEvent;
+},_removeSelection:function(){
+var e=dojo.dnd._empty;
+for(var i in this.selection){
+if(i in e){
+continue;
+}
+var _26=dojo.byId(i);
+if(_26){
+this._removeItemClass(_26,"Selected");
+}
+}
+this.selection={};
+return this;
+},_removeAnchor:function(){
+if(this.anchor){
+this._removeItemClass(this.anchor,"Anchor");
+this.anchor=null;
+}
+return this;
+}});
+}
diff --git a/dojo/dnd/Source.js b/dojo/dnd/Source.js
new file mode 100644
index 0000000..0078417
--- /dev/null
+++ b/dojo/dnd/Source.js
@@ -0,0 +1,297 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.dnd.Source"]){
+dojo._hasResource["dojo.dnd.Source"]=true;
+dojo.provide("dojo.dnd.Source");
+dojo.require("dojo.dnd.Selector");
+dojo.require("dojo.dnd.Manager");
+dojo.declare("dojo.dnd.Source",dojo.dnd.Selector,{isSource:true,horizontal:false,copyOnly:false,selfCopy:false,selfAccept:true,skipForm:false,withHandles:false,autoSync:false,delay:0,accept:["text"],constructor:function(_1,_2){
+dojo.mixin(this,dojo.mixin({},_2));
+var _3=this.accept;
+if(_3.length){
+this.accept={};
+for(var i=0;i<_3.length;++i){
+this.accept[_3[i]]=1;
+}
+}
+this.isDragging=false;
+this.mouseDown=false;
+this.targetAnchor=null;
+this.targetBox=null;
+this.before=true;
+this._lastX=0;
+this._lastY=0;
+this.sourceState="";
+if(this.isSource){
+dojo.addClass(this.node,"dojoDndSource");
+}
+this.targetState="";
+if(this.accept){
+dojo.addClass(this.node,"dojoDndTarget");
+}
+if(this.horizontal){
+dojo.addClass(this.node,"dojoDndHorizontal");
+}
+this.topics=[dojo.subscribe("/dnd/source/over",this,"onDndSourceOver"),dojo.subscribe("/dnd/start",this,"onDndStart"),dojo.subscribe("/dnd/drop",this,"onDndDrop"),dojo.subscribe("/dnd/cancel",this,"onDndCancel")];
+},checkAcceptance:function(_5,_6){
+if(this==_5){
+return !this.copyOnly||this.selfAccept;
+}
+for(var i=0;i<_6.length;++i){
+var _8=_5.getItem(_6[i].id).type;
+var _9=false;
+for(var j=0;j<_8.length;++j){
+if(_8[j] in this.accept){
+_9=true;
+break;
+}
+}
+if(!_9){
+return false;
+}
+}
+return true;
+},copyState:function(_b,_c){
+if(_b){
+return true;
+}
+if(arguments.length<2){
+_c=this==dojo.dnd.manager().target;
+}
+if(_c){
+if(this.copyOnly){
+return this.selfCopy;
+}
+}else{
+return this.copyOnly;
+}
+return false;
+},destroy:function(){
+dojo.dnd.Source.superclass.destroy.call(this);
+dojo.forEach(this.topics,dojo.unsubscribe);
+this.targetAnchor=null;
+},markupFactory:function(_d,_e){
+_d._skipStartup=true;
+return new dojo.dnd.Source(_e,_d);
+},onMouseMove:function(e){
+if(this.isDragging&&this.targetState=="Disabled"){
+return;
+}
+dojo.dnd.Source.superclass.onMouseMove.call(this,e);
+var m=dojo.dnd.manager();
+if(this.isDragging){
+var _11=false;
+if(this.current){
+if(!this.targetBox||this.targetAnchor!=this.current){
+this.targetBox={xy:dojo.coords(this.current,true),w:this.current.offsetWidth,h:this.current.offsetHeight};
+}
+if(this.horizontal){
+_11=(e.pageX-this.targetBox.xy.x)<(this.targetBox.w/2);
+}else{
+_11=(e.pageY-this.targetBox.xy.y)<(this.targetBox.h/2);
+}
+}
+if(this.current!=this.targetAnchor||_11!=this.before){
+this._markTargetAnchor(_11);
+m.canDrop(!this.current||m.source!=this||!(this.current.id in this.selection));
+}
+}else{
+if(this.mouseDown&&this.isSource&&(Math.abs(e.pageX-this._lastX)>this.delay||Math.abs(e.pageY-this._lastY)>this.delay)){
+var _12=this.getSelectedNodes();
+if(_12.length){
+m.startDrag(this,_12,this.copyState(dojo.dnd.getCopyKeyState(e),true));
+}
+}
+}
+},onMouseDown:function(e){
+if(!this.mouseDown&&this._legalMouseDown(e)&&(!this.skipForm||!dojo.dnd.isFormElement(e))){
+this.mouseDown=true;
+this._lastX=e.pageX;
+this._lastY=e.pageY;
+dojo.dnd.Source.superclass.onMouseDown.call(this,e);
+}
+},onMouseUp:function(e){
+if(this.mouseDown){
+this.mouseDown=false;
+dojo.dnd.Source.superclass.onMouseUp.call(this,e);
+}
+},onDndSourceOver:function(_15){
+if(this!=_15){
+this.mouseDown=false;
+if(this.targetAnchor){
+this._unmarkTargetAnchor();
+}
+}else{
+if(this.isDragging){
+var m=dojo.dnd.manager();
+m.canDrop(this.targetState!="Disabled"&&(!this.current||m.source!=this||!(this.current.id in this.selection)));
+}
+}
+},onDndStart:function(_17,_18,_19){
+if(this.autoSync){
+this.sync();
+}
+if(this.isSource){
+this._changeState("Source",this==_17?(_19?"Copied":"Moved"):"");
+}
+var _1a=this.accept&&this.checkAcceptance(_17,_18);
+this._changeState("Target",_1a?"":"Disabled");
+if(this==_17){
+dojo.dnd.manager().overSource(this);
+}
+this.isDragging=true;
+},onDndDrop:function(_1b,_1c,_1d,_1e){
+if(this==_1e){
+this.onDrop(_1b,_1c,_1d);
+}
+this.onDndCancel();
+},onDndCancel:function(){
+if(this.targetAnchor){
+this._unmarkTargetAnchor();
+this.targetAnchor=null;
+}
+this.before=true;
+this.isDragging=false;
+this.mouseDown=false;
+this._changeState("Source","");
+this._changeState("Target","");
+},onDrop:function(_1f,_20,_21){
+if(this!=_1f){
+this.onDropExternal(_1f,_20,_21);
+}else{
+this.onDropInternal(_20,_21);
+}
+},onDropExternal:function(_22,_23,_24){
+var _25=this._normalizedCreator;
+if(this.creator){
+this._normalizedCreator=function(_26,_27){
+return _25.call(this,_22.getItem(_26.id).data,_27);
+};
+}else{
+if(_24){
+this._normalizedCreator=function(_28,_29){
+var t=_22.getItem(_28.id);
+var n=_28.cloneNode(true);
+n.id=dojo.dnd.getUniqueId();
+return {node:n,data:t.data,type:t.type};
+};
+}else{
+this._normalizedCreator=function(_2c,_2d){
+var t=_22.getItem(_2c.id);
+_22.delItem(_2c.id);
+return {node:_2c,data:t.data,type:t.type};
+};
+}
+}
+this.selectNone();
+if(!_24&&!this.creator){
+_22.selectNone();
+}
+this.insertNodes(true,_23,this.before,this.current);
+if(!_24&&this.creator){
+_22.deleteSelectedNodes();
+}
+this._normalizedCreator=_25;
+},onDropInternal:function(_2f,_30){
+var _31=this._normalizedCreator;
+if(this.current&&this.current.id in this.selection){
+return;
+}
+if(_30){
+if(this.creator){
+this._normalizedCreator=function(_32,_33){
+return _31.call(this,this.getItem(_32.id).data,_33);
+};
+}else{
+this._normalizedCreator=function(_34,_35){
+var t=this.getItem(_34.id);
+var n=_34.cloneNode(true);
+n.id=dojo.dnd.getUniqueId();
+return {node:n,data:t.data,type:t.type};
+};
+}
+}else{
+if(!this.current){
+return;
+}
+this._normalizedCreator=function(_38,_39){
+var t=this.getItem(_38.id);
+return {node:_38,data:t.data,type:t.type};
+};
+}
+this._removeSelection();
+this.insertNodes(true,_2f,this.before,this.current);
+this._normalizedCreator=_31;
+},onDraggingOver:function(){
+},onDraggingOut:function(){
+},onOverEvent:function(){
+dojo.dnd.Source.superclass.onOverEvent.call(this);
+dojo.dnd.manager().overSource(this);
+if(this.isDragging&&this.targetState!="Disabled"){
+this.onDraggingOver();
+}
+},onOutEvent:function(){
+dojo.dnd.Source.superclass.onOutEvent.call(this);
+dojo.dnd.manager().outSource(this);
+if(this.isDragging&&this.targetState!="Disabled"){
+this.onDraggingOut();
+}
+},_markTargetAnchor:function(_3b){
+if(this.current==this.targetAnchor&&this.before==_3b){
+return;
+}
+if(this.targetAnchor){
+this._removeItemClass(this.targetAnchor,this.before?"Before":"After");
+}
+this.targetAnchor=this.current;
+this.targetBox=null;
+this.before=_3b;
+if(this.targetAnchor){
+this._addItemClass(this.targetAnchor,this.before?"Before":"After");
+}
+},_unmarkTargetAnchor:function(){
+if(!this.targetAnchor){
+return;
+}
+this._removeItemClass(this.targetAnchor,this.before?"Before":"After");
+this.targetAnchor=null;
+this.targetBox=null;
+this.before=true;
+},_markDndStatus:function(_3c){
+this._changeState("Source",_3c?"Copied":"Moved");
+},_legalMouseDown:function(e){
+if(!dojo.dnd._isLmbPressed(e)){
+return false;
+}
+if(!this.withHandles){
+return true;
+}
+for(var _3e=e.target;_3e&&_3e!==this.node;_3e=_3e.parentNode){
+if(dojo.hasClass(_3e,"dojoDndHandle")){
+return true;
+}
+if(dojo.hasClass(_3e,"dojoDndItem")){
+break;
+}
+}
+return false;
+}});
+dojo.declare("dojo.dnd.Target",dojo.dnd.Source,{constructor:function(_3f,_40){
+this.isSource=false;
+dojo.removeClass(this.node,"dojoDndSource");
+},markupFactory:function(_41,_42){
+_41._skipStartup=true;
+return new dojo.dnd.Target(_42,_41);
+}});
+dojo.declare("dojo.dnd.AutoSource",dojo.dnd.Source,{constructor:function(_43,_44){
+this.autoSync=true;
+},markupFactory:function(_45,_46){
+_45._skipStartup=true;
+return new dojo.dnd.AutoSource(_46,_45);
+}});
+}
diff --git a/dojo/dnd/TimedMoveable.js b/dojo/dnd/TimedMoveable.js
new file mode 100644
index 0000000..669dd25
--- /dev/null
+++ b/dojo/dnd/TimedMoveable.js
@@ -0,0 +1,40 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.dnd.TimedMoveable"]){
+dojo._hasResource["dojo.dnd.TimedMoveable"]=true;
+dojo.provide("dojo.dnd.TimedMoveable");
+dojo.require("dojo.dnd.Moveable");
+(function(){
+var _1=dojo.dnd.Moveable.prototype.onMove;
+dojo.declare("dojo.dnd.TimedMoveable",dojo.dnd.Moveable,{timeout:40,constructor:function(_2,_3){
+if(!_3){
+_3={};
+}
+if(_3.timeout&&typeof _3.timeout=="number"&&_3.timeout>=0){
+this.timeout=_3.timeout;
+}
+},markupFactory:function(_4,_5){
+return new dojo.dnd.TimedMoveable(_5,_4);
+},onMoveStop:function(_6){
+if(_6._timer){
+clearTimeout(_6._timer);
+_1.call(this,_6,_6._leftTop);
+}
+dojo.dnd.Moveable.prototype.onMoveStop.apply(this,arguments);
+},onMove:function(_7,_8){
+_7._leftTop=_8;
+if(!_7._timer){
+var _t=this;
+_7._timer=setTimeout(function(){
+_7._timer=null;
+_1.call(_t,_7,_7._leftTop);
+},this.timeout);
+}
+}});
+})();
+}
diff --git a/dojo/dnd/autoscroll.js b/dojo/dnd/autoscroll.js
new file mode 100644
index 0000000..63a4a03
--- /dev/null
+++ b/dojo/dnd/autoscroll.js
@@ -0,0 +1,99 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.dnd.autoscroll"]){
+dojo._hasResource["dojo.dnd.autoscroll"]=true;
+dojo.provide("dojo.dnd.autoscroll");
+dojo.dnd.getViewport=function(){
+var d=dojo.doc,dd=d.documentElement,w=window,b=dojo.body();
+if(dojo.isMozilla){
+return {w:dd.clientWidth,h:w.innerHeight};
+}else{
+if(!dojo.isOpera&&w.innerWidth){
+return {w:w.innerWidth,h:w.innerHeight};
+}else{
+if(!dojo.isOpera&&dd&&dd.clientWidth){
+return {w:dd.clientWidth,h:dd.clientHeight};
+}else{
+if(b.clientWidth){
+return {w:b.clientWidth,h:b.clientHeight};
+}
+}
+}
+}
+return null;
+};
+dojo.dnd.V_TRIGGER_AUTOSCROLL=32;
+dojo.dnd.H_TRIGGER_AUTOSCROLL=32;
+dojo.dnd.V_AUTOSCROLL_VALUE=16;
+dojo.dnd.H_AUTOSCROLL_VALUE=16;
+dojo.dnd.autoScroll=function(e){
+var v=dojo.dnd.getViewport(),dx=0,dy=0;
+if(e.clientX<dojo.dnd.H_TRIGGER_AUTOSCROLL){
+dx=-dojo.dnd.H_AUTOSCROLL_VALUE;
+}else{
+if(e.clientX>v.w-dojo.dnd.H_TRIGGER_AUTOSCROLL){
+dx=dojo.dnd.H_AUTOSCROLL_VALUE;
+}
+}
+if(e.clientY<dojo.dnd.V_TRIGGER_AUTOSCROLL){
+dy=-dojo.dnd.V_AUTOSCROLL_VALUE;
+}else{
+if(e.clientY>v.h-dojo.dnd.V_TRIGGER_AUTOSCROLL){
+dy=dojo.dnd.V_AUTOSCROLL_VALUE;
+}
+}
+window.scrollBy(dx,dy);
+};
+dojo.dnd._validNodes={"div":1,"p":1,"td":1};
+dojo.dnd._validOverflow={"auto":1,"scroll":1};
+dojo.dnd.autoScrollNodes=function(e){
+for(var n=e.target;n;){
+if(n.nodeType==1&&(n.tagName.toLowerCase() in dojo.dnd._validNodes)){
+var s=dojo.getComputedStyle(n);
+if(s.overflow.toLowerCase() in dojo.dnd._validOverflow){
+var b=dojo._getContentBox(n,s),t=dojo._abs(n,true);
+var w=Math.min(dojo.dnd.H_TRIGGER_AUTOSCROLL,b.w/2),h=Math.min(dojo.dnd.V_TRIGGER_AUTOSCROLL,b.h/2),rx=e.pageX-t.x,ry=e.pageY-t.y,dx=0,dy=0;
+if(dojo.isWebKit||dojo.isOpera){
+rx+=dojo.body().scrollLeft,ry+=dojo.body().scrollTop;
+}
+if(rx>0&&rx<b.w){
+if(rx<w){
+dx=-w;
+}else{
+if(rx>b.w-w){
+dx=w;
+}
+}
+}
+if(ry>0&&ry<b.h){
+if(ry<h){
+dy=-h;
+}else{
+if(ry>b.h-h){
+dy=h;
+}
+}
+}
+var _14=n.scrollLeft,_15=n.scrollTop;
+n.scrollLeft=n.scrollLeft+dx;
+n.scrollTop=n.scrollTop+dy;
+if(_14!=n.scrollLeft||_15!=n.scrollTop){
+return;
+}
+}
+}
+try{
+n=n.parentNode;
+}
+catch(x){
+n=null;
+}
+}
+dojo.dnd.autoScroll(e);
+};
+}
diff --git a/dojo/dnd/common.js b/dojo/dnd/common.js
new file mode 100644
index 0000000..3a0b444
--- /dev/null
+++ b/dojo/dnd/common.js
@@ -0,0 +1,38 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.dnd.common"]){
+dojo._hasResource["dojo.dnd.common"]=true;
+dojo.provide("dojo.dnd.common");
+dojo.dnd._isMac=navigator.appVersion.indexOf("Macintosh")>=0;
+dojo.dnd._copyKey=dojo.dnd._isMac?"metaKey":"ctrlKey";
+dojo.dnd.getCopyKeyState=function(e){
+return e[dojo.dnd._copyKey];
+};
+dojo.dnd._uniqueId=0;
+dojo.dnd.getUniqueId=function(){
+var id;
+do{
+id=dojo._scopeName+"Unique"+(++dojo.dnd._uniqueId);
+}while(dojo.byId(id));
+return id;
+};
+dojo.dnd._empty={};
+dojo.dnd.isFormElement=function(e){
+var t=e.target;
+if(t.nodeType==3){
+t=t.parentNode;
+}
+return " button textarea input select option ".indexOf(" "+t.tagName.toLowerCase()+" ")>=0;
+};
+dojo.dnd._lmb=dojo.isIE?1:0;
+dojo.dnd._isLmbPressed=dojo.isIE?function(e){
+return e.button&1;
+}:function(e){
+return e.button===0;
+};
+}
diff --git a/dojo/dnd/move.js b/dojo/dnd/move.js
new file mode 100644
index 0000000..54070f6
--- /dev/null
+++ b/dojo/dnd/move.js
@@ -0,0 +1,125 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.dnd.move"]){
+dojo._hasResource["dojo.dnd.move"]=true;
+dojo.provide("dojo.dnd.move");
+dojo.require("dojo.dnd.Mover");
+dojo.require("dojo.dnd.Moveable");
+dojo.declare("dojo.dnd.move.constrainedMoveable",dojo.dnd.Moveable,{constraints:function(){
+},within:false,markupFactory:function(_1,_2){
+return new dojo.dnd.move.constrainedMoveable(_2,_1);
+},constructor:function(_3,_4){
+if(!_4){
+_4={};
+}
+this.constraints=_4.constraints;
+this.within=_4.within;
+},onFirstMove:function(_5){
+var c=this.constraintBox=this.constraints.call(this,_5);
+c.r=c.l+c.w;
+c.b=c.t+c.h;
+if(this.within){
+var mb=dojo.marginBox(_5.node);
+c.r-=mb.w;
+c.b-=mb.h;
+}
+},onMove:function(_8,_9){
+var c=this.constraintBox,s=_8.node.style;
+s.left=(_9.l<c.l?c.l:c.r<_9.l?c.r:_9.l)+"px";
+s.top=(_9.t<c.t?c.t:c.b<_9.t?c.b:_9.t)+"px";
+}});
+dojo.declare("dojo.dnd.move.boxConstrainedMoveable",dojo.dnd.move.constrainedMoveable,{box:{},markupFactory:function(_c,_d){
+return new dojo.dnd.move.boxConstrainedMoveable(_d,_c);
+},constructor:function(_e,_f){
+var box=_f&&_f.box;
+this.constraints=function(){
+return box;
+};
+}});
+dojo.declare("dojo.dnd.move.parentConstrainedMoveable",dojo.dnd.move.constrainedMoveable,{area:"content",markupFactory:function(_11,_12){
+return new dojo.dnd.move.parentConstrainedMoveable(_12,_11);
+},constructor:function(_13,_14){
+var _15=_14&&_14.area;
+this.constraints=function(){
+var n=this.node.parentNode,s=dojo.getComputedStyle(n),mb=dojo._getMarginBox(n,s);
+if(_15=="margin"){
+return mb;
+}
+var t=dojo._getMarginExtents(n,s);
+mb.l+=t.l,mb.t+=t.t,mb.w-=t.w,mb.h-=t.h;
+if(_15=="border"){
+return mb;
+}
+t=dojo._getBorderExtents(n,s);
+mb.l+=t.l,mb.t+=t.t,mb.w-=t.w,mb.h-=t.h;
+if(_15=="padding"){
+return mb;
+}
+t=dojo._getPadExtents(n,s);
+mb.l+=t.l,mb.t+=t.t,mb.w-=t.w,mb.h-=t.h;
+return mb;
+};
+}});
+dojo.dnd.move.constrainedMover=function(fun,_1b){
+dojo.deprecated("dojo.dnd.move.constrainedMover, use dojo.dnd.move.constrainedMoveable instead");
+var _1c=function(_1d,e,_1f){
+dojo.dnd.Mover.call(this,_1d,e,_1f);
+};
+dojo.extend(_1c,dojo.dnd.Mover.prototype);
+dojo.extend(_1c,{onMouseMove:function(e){
+dojo.dnd.autoScroll(e);
+var m=this.marginBox,c=this.constraintBox,l=m.l+e.pageX,t=m.t+e.pageY;
+l=l<c.l?c.l:c.r<l?c.r:l;
+t=t<c.t?c.t:c.b<t?c.b:t;
+this.host.onMove(this,{l:l,t:t});
+},onFirstMove:function(){
+dojo.dnd.Mover.prototype.onFirstMove.call(this);
+var c=this.constraintBox=fun.call(this);
+c.r=c.l+c.w;
+c.b=c.t+c.h;
+if(_1b){
+var mb=dojo.marginBox(this.node);
+c.r-=mb.w;
+c.b-=mb.h;
+}
+}});
+return _1c;
+};
+dojo.dnd.move.boxConstrainedMover=function(box,_28){
+dojo.deprecated("dojo.dnd.move.boxConstrainedMover, use dojo.dnd.move.boxConstrainedMoveable instead");
+return dojo.dnd.move.constrainedMover(function(){
+return box;
+},_28);
+};
+dojo.dnd.move.parentConstrainedMover=function(_29,_2a){
+dojo.deprecated("dojo.dnd.move.parentConstrainedMover, use dojo.dnd.move.parentConstrainedMoveable instead");
+var fun=function(){
+var n=this.node.parentNode,s=dojo.getComputedStyle(n),mb=dojo._getMarginBox(n,s);
+if(_29=="margin"){
+return mb;
+}
+var t=dojo._getMarginExtents(n,s);
+mb.l+=t.l,mb.t+=t.t,mb.w-=t.w,mb.h-=t.h;
+if(_29=="border"){
+return mb;
+}
+t=dojo._getBorderExtents(n,s);
+mb.l+=t.l,mb.t+=t.t,mb.w-=t.w,mb.h-=t.h;
+if(_29=="padding"){
+return mb;
+}
+t=dojo._getPadExtents(n,s);
+mb.l+=t.l,mb.t+=t.t,mb.w-=t.w,mb.h-=t.h;
+return mb;
+};
+return dojo.dnd.move.constrainedMover(fun,_2a);
+};
+dojo.dnd.constrainedMover=dojo.dnd.move.constrainedMover;
+dojo.dnd.boxConstrainedMover=dojo.dnd.move.boxConstrainedMover;
+dojo.dnd.parentConstrainedMover=dojo.dnd.move.parentConstrainedMover;
+}
diff --git a/dojo/dojo.js b/dojo/dojo.js
new file mode 100644
index 0000000..d69fc40
--- /dev/null
+++ b/dojo/dojo.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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 a compiled version of Dojo, built for deployment and not for
+	development. To get an editable version, please visit:
+
+		http://dojotoolkit.org
+
+	for documentation and information on getting the source.
+*/
+
+(function(){var _1=null;if((_1||(typeof djConfig!="undefined"&&djConfig.scopeMap))&&(typeof window!="undefined")){var _2="",_3="",_4="",_5={},_6={};_1=_1||djConfig.scopeMap;for(var i=0;i<_1.length;i++){var _8=_1[i];_2+="var "+_8[0]+" = {}; "+_8[1]+" = "+_8[0]+";"+_8[1]+"._scopeName = '"+_8[1]+"';";_3+=(i==0?"":",")+_8[0];_4+=(i==0?"":",")+_8[1];_5[_8[0]]=_8[1];_6[_8[1]]=_8[0];}eval(_2+"dojo._scopeArgs = ["+_4+"];");dojo._scopePrefixArgs=_3;dojo._scopePrefix="(function("+_3+"){";dojo._sco [...]
diff --git a/dojo/dojo.js.uncompressed.js b/dojo/dojo.js.uncompressed.js
new file mode 100644
index 0000000..9cb49a8
--- /dev/null
+++ b/dojo/dojo.js.uncompressed.js
@@ -0,0 +1,9439 @@
+/*
+	Copyright (c) 2004-2009, 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 a compiled version of Dojo, built for deployment and not for
+	development. To get an editable version, please visit:
+
+		http://dojotoolkit.org
+
+	for documentation and information on getting the source.
+*/
+
+;(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.
+	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
+}
+=====*/
+
+(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(){}
+				})();
+			}
+		}
+	}
+
+	//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"){
+		this.dojo = {
+			_scopeName: "dojo",
+			_scopePrefix: "",
+			_scopePrefixArgs: "",
+			_scopeSuffix: "",
+			_scopeMap: {},
+			_scopeMapRev: {}
+		};
+	}
+
+	var d = dojo;
+
+	//Need placeholders for dijit and dojox for scoping code.
+	if(typeof dijit == "undefined"){
+		this.dijit = {_scopeName: "dijit"};
+	}
+	if(typeof dojox == "undefined"){
+		this.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
+	};
+
+	if(typeof djConfig != "undefined"){
+		for(var opt in djConfig){
+			d.config[opt] = djConfig[opt];
+		}
+	}
+
+/*=====
+	// Override locale setting, if specified
+	dojo.locale = {
+		// summary: the locale as defined by Dojo (read-only)
+	};
+=====*/
+	dojo.locale = d.config.locale;
+
+	var rev = "$Rev: 18832 $".match(/\d+/); 
+
+	dojo.version = {
+		// summary: 
+		//		version number of dojo
+		//	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
+		major: 1, minor: 3, patch: 2, 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 tobj = {};
+	dojo._mixin = function(/*Object*/ obj, /*Object*/ props){
+		// summary:
+		//		Adds all properties and methods of props to obj. This addition
+		//		is "prototype extension safe", so that instances of objects
+		//		will not pass along prototype defaults.
+		for(var x in props){
+			// the "tobj" condition avoid copying properties in "props"
+			// inherited from Object.prototype.  For example, if obj has a custom
+			// toString() method, don't overwrite it with the toString() method
+			// that props inherited from Object.prototype
+			if(tobj[x] === undefined || tobj[x] != props[x]){
+				obj[x] = props[x];
+			}
+		}
+				// IE doesn't recognize custom toStrings in for..in
+		if(d.isIE && props){
+			var p = props.toString;
+			if(typeof p == "function" && p != obj.toString && p != tobj.toString &&
+				p != "\nfunction toString() {\n    [native code]\n}\n"){
+					obj.toString = props.toString;
+			}
+		}
+				return obj; // 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
+		//		destionation 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);
+		//	|	
+		//	|			
+		//	|			//  ...
+		//	|		},
+		//	|		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"
+		//	|	
+		//	|	// will print "true"
+		//	|	
+		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 && this._scopeMap[p]){
+				p = this._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
+		//	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); // Boolean
+	}
+
+
+	dojo["eval"] = function(/*String*/ scriptFragment){
+		//	summary: 
+		//		Perform an evaluation in the global scope. Use this rather than
+		//		calling 'eval()' directly.
+		//	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`
+
+
+		// note:
+		//	 - JSC eval() takes an optional second argument which can be 'unsafe'.
+		//	 - Mozilla/SpiderMonkey eval() takes an optional second argument which is the
+		//  	 scope object for new symbols.
+
+		// FIXME: investigate Joseph Smarr's technique for IE:
+		//		http://josephsmarr.com/2007/01/31/fixing-eval-to-use-global-scope-in-ie/
+		//	see also:
+		// 		http://trac.dojotoolkit.org/ticket/744
+		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;
+
+	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 = this._modulePrefixes;
+			return !!(mp[module] && mp[module].value); // Boolean
+		},
+
+		_getModulePrefix: function(/*String*/module){
+			// summary: gets the prefix associated with module
+			var mp = this._modulePrefixes;
+			if(this._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+:/)) ? "" : this.baseUrl) + relpath;
+		try{
+			return !module ? this._loadUri(uri, cb) : this._loadUriAndCheck(uri, module, cb); // Boolean
+		}catch(e){
+			console.error(e);
+			return false; // Boolean
+		}
+	}
+
+	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(this._loadedUrls[uri]){
+			return true; // Boolean
+		}
+		var contents = this._getText(uri, true);
+		if(!contents){ return false; } // Boolean
+		this._loadedUrls[uri] = true;
+		this._loadedUrls.push(uri);
+		if(cb){
+			contents = '('+contents+')';
+		}else{
+			//Only do the scoping if no callback. If a callback is specified,
+			//it is most likely the i18n bundle stuff.
+			contents = this._scopePrefix + contents + this._scopeSuffix;
+		}
+		if(d.isMoz){ contents += "\r\n//@ sourceURL=" + uri; } // debugging assist for Firebug
+		var value = d["eval"](contents);
+		if(cb){ cb(value); }
+		return true; // Boolean
+	}
+	
+	// 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 = this._loadUri(uri, cb);
+		}catch(e){
+			console.error("failed loading " + uri + " with error: " + e);
+		}
+		return !!(ok && this._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.
+		this._loadNotifying = true;
+		this._postLoad = true;
+		var mll = d._loaders;
+
+		//Clear listeners so new ones can be added
+		//For other xdomain package loads after the initial load.
+		this._loaders = [];
+
+		for(var x = 0; x < mll.length; x++){
+			mll[x]();
+		}
+
+		this._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.addOnLoad = function(/*Object?*/obj, /*String|Function*/functionName){
+		// summary:
+		//		Registers a function to be triggered after the DOM has finished
+		//		loading and widgets declared in markup have been instantiated.
+		//		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.)
+		// example:
+		//	|	dojo.addOnLoad(functionPointer);
+		//	|	dojo.addOnLoad(object, "functionName");
+		//	|	dojo.addOnLoad(object, function(){ /* ... */});
+
+		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" || (dojo.config.useXDomain && d.isOpera)){
+			if(dojo.isAIR){
+				setTimeout(function(){dojo.loaded();}, 0);
+			}else{
+				setTimeout(dojo._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) && !this._moduleHasPrefix(parentModule)){		
+				// Support default module directory (sibling of dojo) for top-level modules 
+				syms[0] = "../" + syms[0];
+			}else{
+				var parentModulePath = this._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:
+		//		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:
+		//		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:
+		//		`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 excpetion 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`.
+		//	
+		//		`dojo.require()` does nothing about importing symbols into
+		//		the current namespace.  It is presumed that the caller will
+		//		take care of that. 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 = this._global_omit_module_check || omitModuleCheck;
+
+		//Check if it is already loaded.
+		var module = this._loadedModules[moduleName];
+		if(module){
+			return module;
+		}
+
+		// convert periods to slashes
+		var relpath = this._getModuleSymbols(moduleName).join("/") + '.js';
+
+		var modArg = (!omitModuleCheck) ? moduleName : null;
+		var ok = this._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 && !this._isXDomain){
+			// pass in false so we can give better error
+			module = this._loadedModules[moduleName];
+			if(!module){
+				throw new Error("symbol '" + moduleName + "' is not defined after loading '" + relpath + "'"); 
+			}
+		}
+
+		return module;
+	}
+
+	dojo.provide = function(/*String*/ resourceName){
+		//	summary:
+		//		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.
+		//	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.
+		//	
+		//		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.
+
+		//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
+		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
+		//
+		// 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("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$");
+	var 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;
+
+		var _a = arguments;
+		var 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]+"");
+			var 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");
+		//	|	 // 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); // String
+	}
+})();
+
+/*=====
+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
+}
+=====*/
+
+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");
+					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;
+
+		// 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] || dua.split("Shiretoko/")[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, for a previous
+			//version. Make sure isIE reflects the desired version.
+			//document.documentMode of 5 means quirks mode.
+			if(d.isIE >= 8 && document.documentMode != 5){
+				d.isIE = document.documentMode;
+			}
+		}
+
+		//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;
+		}
+		
+		var cm = document.compatMode;
+		d.isQuirks = cm == "BackCompat" || cm == "QuirksMode" || d.isIE < 6;
+
+		// 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;
+			return (stat >= 200 && stat < 300) || 	// Boolean
+				stat == 304 || 						// allow any 2XX response code
+				stat == 1223 || 						// get it out of the cache
+				(!stat && (location.protocol=="file:" || location.protocol=="chrome:") ); // Internet Explorer mangled the status code
+		}
+
+		//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 = this._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 oldHandler = _w[evtName] || function(){};
+			_w[evtName] = function(){
+				fp.apply(_w, arguments);
+				oldHandler.apply(_w, arguments);
+			};
+		};
+
+
+		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())();
+			}
+		};
+
+		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);
+			}
+		};
+
+	})();
+
+	dojo._initFired = false;
+	//	BEGIN DOMContentLoaded, from Dean Edwards (http://dean.edwards.name/weblog/2006/06/again/)
+	dojo._loadInit = function(e){
+		dojo._initFired = true;
+		// allow multiple calls, only first one will take effect
+		// A bug in khtml calls events callbacks for document for event which isnt supported
+		// for example a created contextmenu event calls DOMContentLoaded, workaround
+		var type = e && e.type ? e.type.toLowerCase() : "load";
+		if(arguments.callee.initialized || (type != "domcontentloaded" && type != "load")){ return; }
+		arguments.callee.initialized = true;
+		if("_khtmlTimer" in dojo){
+			clearInterval(dojo._khtmlTimer);
+			delete dojo._khtmlTimer;
+		}
+
+		if(dojo._inFlightCount == 0){
+			dojo._modulesLoaded();
+		}
+	}
+
+	if(!dojo.config.afterOnLoad){
+		//	START DOMContentLoaded
+		// Mozilla and Opera 9 expose the event we could use
+				if(document.addEventListener){
+			// NOTE: 
+			//		due to a threading issue in Firefox 2.0, we can't enable
+			//		DOMContentLoaded on that platform. For more information, see:
+			//		http://trac.dojotoolkit.org/ticket/1704
+			if(dojo.isWebKit > 525 || dojo.isOpera || dojo.isFF >= 3 || (dojo.isMoz && dojo.config.enableMozDomContentLoaded === true)){
+						document.addEventListener("DOMContentLoaded", dojo._loadInit, null);
+					}
+	
+			//	mainly for Opera 8.5, won't be fired if DOMContentLoaded fired already.
+			//  also used for Mozilla because of trac #1640
+			window.addEventListener("load", dojo._loadInit, null);
+		}
+			
+				if(dojo.isAIR){
+			window.addEventListener("load", dojo._loadInit, null);
+		}else if((dojo.isWebKit < 525) || dojo.isKhtml){
+			dojo._khtmlTimer = setInterval(function(){
+				if(/loaded|complete/.test(document.readyState)){
+					dojo._loadInit(); // call the onload handler
+				}
+			}, 10);
+		}
+				//	END DOMContentLoaded
+	}
+
+		if(dojo.isIE){
+		// 	for Internet Explorer. readyState will not be achieved on init
+		// 	call, but dojo doesn't need it however, we'll include it
+		// 	because we don't know if there are other functions added that
+		// 	might.  Note that this has changed because the build process
+		// 	strips all comments -- including conditional ones.
+		if(!dojo.config.afterOnLoad){
+			document.write('<scr'+'ipt defer src="//:" '
+				+ 'onreadystatechange="if(this.readyState==\'complete\'){' + dojo._scopeName + '._loadInit();}">'
+				+ '</scr'+'ipt>'
+			);
+		}
+
+		try{
+			document.namespaces.add("v","urn:schemas-microsoft-com:vml");
+			document.createStyleSheet().addRule("v\\:*", "behavior:url(#default#VML);  display:inline-block");
+		}catch(e){}
+	}
+	
+
+	/*
+	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){
+	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");
+
+// Crockford (ish) functions
+
+dojo.isString = function(/*anything*/ it){
+	//	summary:
+	//		Return true if it is a String
+	return !!arguments.length && it != null && (typeof it == "string" || it instanceof String); // Boolean
+}
+
+dojo.isArray = function(/*anything*/ it){
+	//	summary:
+	//		Return true if it is an Array
+	return it && (it instanceof Array || typeof it == "array"); // Boolean
+}
+
+/*=====
+dojo.isFunction = function(it){
+	// summary: Return true if it is a Function
+	// it: anything
+	return; // Boolean
+}
+=====*/
+
+dojo.isFunction = (function(){
+	var _isFunction = function(/*anything*/ it){
+		var t = typeof it; // must evaluate separately due to bizarre Opera bug. See #8937 
+		return it && (t == "function" || it instanceof Function); // Boolean
+	};
+
+	return dojo.isSafari ?
+		// only slow this down w/ gratuitious casting in Safari (not WebKit)
+		function(/*anything*/ it){
+			if(typeof it == "function" && it == "[object NodeList]"){ return false; }
+			return _isFunction(it); // Boolean
+		} : _isFunction;
+})();
+
+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" || dojo.isArray(it) || dojo.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`
+	var d = dojo;
+	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 && !dojo.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++){
+		dojo._mixin(constructor.prototype, arguments[i]);
+	}
+	return constructor; // Object
+}
+
+dojo._hitchArgs = function(scope, method /*,...*/){
+	var pre = dojo._toArray(arguments, 2);
+	var named = dojo.isString(method);
+	return function(){
+		// arrayify arguments
+		var args = dojo._toArray(arguments);
+		// locate our method
+		var f = named ? (scope||dojo.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
+	if(arguments.length > 2){
+		return dojo._hitchArgs.apply(dojo, arguments); // Function
+	}
+	if(!method){
+		method = scope;
+		scope = null;
+	}
+	if(dojo.isString(method)){
+		scope = scope || dojo.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();
+		if(props){
+			dojo._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.
+}
+=====*/
+
+(function(){
+	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 = 
+				dojo.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 dojo.hitch.apply(dojo, arr.concat(dojo._toArray(arguments))); // Function
+}
+
+dojo.clone = function(/*anything*/ o){
+	// summary:
+	//		Clones objects (including DOM nodes) and all children.
+	//		Warning: do not clone cyclic structures.
+	if(!o){ return o; }
+	if(dojo.isArray(o)){
+		var r = [];
+		for(var i = 0; i < o.length; ++i){
+			r.push(dojo.clone(o[i]));
+		}
+		return r; // Array
+	}
+	if(!dojo.isObject(o)){
+		return o;	/*anything*/
+	}
+	if(o.nodeType && o.cloneNode){ // isNode
+		return o.cloneNode(true); // Node
+	}
+	if(o instanceof Date){
+		return new Date(o.getTime());	// Date
+	}
+	// Generic objects
+	r = new o.constructor(); // specific to dojo.declare()'d classes!
+	for(i in o){
+		if(!(i in r) || r[i] != o[i]){
+			r[i] = dojo.clone(o[i]);
+		}
+	}
+	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*$/, ''); };
+
+}
+
+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");
+
+
+// this file courtesy of the TurboAjax Group, licensed under a Dojo CLA
+
+dojo.declare = function(/*String*/ className, /*Function|Function[]*/ superclass, /*Object*/ props){
+	//	summary: 
+	//		Create a feature-rich constructor from compact notation
+	//	className:
+	//		The name of the constructor (loosely, a "class")
+	//		stored in the "declaredClass" property in the created prototype
+	//	superclass:
+	//		May be null, a Function, or an Array of Functions. If an array, 
+	//		the first element is used as the prototypical ancestor and
+	//		any following Functions become mixin ancestors.
+	//	props:
+	//		An object whose properties are copied to the
+	//		created prototype.
+	//		Add an instance-initialization function by making it a property 
+	//		named "constructor".
+	//	description:
+	//		Create a constructor using a compact notation for inheritance and
+	//		prototype extension. 
+	//
+	//		All superclasses (including mixins) must be Functions (not simple Objects).
+	//
+	//		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.
+	//
+	//		"className" is cached in "declaredClass" property of the new class.
+	//
+	//	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(); 
+	//	|		}
+	//	|	);
+
+	// process superclass argument
+	var dd = arguments.callee, mixins;
+	if(dojo.isArray(superclass)){
+		mixins = superclass;
+		superclass = mixins.shift();
+	}
+	// construct intermediate classes for mixins
+	if(mixins){
+		dojo.forEach(mixins, function(m, i){
+			if(!m){ throw(className + ": mixin #" + i + " is null"); } // It's likely a required module is not loaded
+			superclass = dd._delegate(superclass, m);
+		});
+	}
+	// create constructor
+	var ctor = dd._delegate(superclass);
+	// extend with "props"
+	props = props || {};
+	ctor.extend(props);
+	// more prototype decoration
+	dojo.extend(ctor, {declaredClass: className, _constructor: props.constructor/*, preamble: null*/});
+	// special help for IE
+	ctor.prototype.constructor = ctor;
+	// create named reference
+	return dojo.setObject(className, ctor); // Function
+};
+
+dojo.mixin(dojo.declare, {
+	_delegate: function(base, mixin){
+		var bp = (base||0).prototype, mp = (mixin||0).prototype, dd=dojo.declare;
+		// fresh constructor, fresh prototype
+		var ctor = dd._makeCtor();
+		// cache ancestry
+		dojo.mixin(ctor, {superclass: bp, mixin: mp, extend: dd._extend});
+		// chain prototypes
+		if(base){ctor.prototype = dojo._delegate(bp);}
+		// add mixin and core
+		dojo.extend(ctor, dd._core, mp||0, {_constructor: null, preamble: null});
+		// special help for IE
+		ctor.prototype.constructor = ctor;
+		// name this class for debugging
+		ctor.prototype.declaredClass = (bp||0).declaredClass + '_' + (mp||0).declaredClass;
+		return ctor;
+	},
+	_extend: function(props){
+		var i, fn;
+		for(i in props){ if(dojo.isFunction(fn=props[i]) && !0[i]){fn.nom=i;fn.ctor=this;} }
+		dojo.extend(this, props);
+	},
+	_makeCtor: function(){
+		// we have to make a function, but don't want to close over anything
+		return function(){ this._construct(arguments); };
+	},
+	_core: { 
+		_construct: function(args){
+			var c=args.callee, s=c.superclass, ct=s&&s.constructor, m=c.mixin, mct=m&&m.constructor, a=args, ii, fn;
+			// side-effect of = used on purpose here, lint may complain, don't try this at home
+			if(a[0]){ 
+				// FIXME: preambles for each mixin should be allowed
+				// FIXME: 
+				//		should we allow the preamble here NOT to modify the
+				//		default args, but instead to act on each mixin
+				//		independently of the class instance being constructed
+				//		(for impedence matching)?
+
+				// allow any first argument w/ a "preamble" property to act as a
+				// class preamble (not exclusive of the prototype preamble)
+				if(/*dojo.isFunction*/((fn = a[0].preamble))){ 
+					a = fn.apply(this, a) || a; 
+				}
+			} 
+			// prototype preamble
+			if((fn = c.prototype.preamble)){a = fn.apply(this, a) || a;}
+			// FIXME: 
+			//		need to provide an optional prototype-settable
+			//		"_explicitSuper" property which disables this
+			// initialize superclass
+			if(ct&&ct.apply){ct.apply(this, a);}
+			// initialize mixin
+			if(mct&&mct.apply){mct.apply(this, a);}
+			// initialize self
+			if((ii=c.prototype._constructor)){ii.apply(this, args);}
+			// post construction
+			if(this.constructor.prototype==c.prototype && (ct=this.postscript)){ ct.apply(this, args); }
+		},
+		_findMixin: function(mixin){
+			var c = this.constructor, p, m;
+			while(c){
+				p = c.superclass;
+				m = c.mixin;
+				if(m==mixin || (m instanceof mixin.constructor)){return p;}
+				if(m && m._findMixin && (m=m._findMixin(mixin))){return m;}
+				c = p && p.constructor;
+			}
+		},
+		_findMethod: function(name, method, ptype, has){
+			// consciously trading readability for bytes and speed in this low-level method
+			var p=ptype, c, m, f;
+			do{
+				c = p.constructor;
+				m = c.mixin;
+				// find method by name in our mixin ancestor
+				if(m && (m=this._findMethod(name, method, m, has))){return m;}
+				// if we found a named method that either exactly-is or exactly-is-not 'method'
+				if((f=p[name])&&(has==(f==method))){return p;}
+				// ascend chain
+				p = c.superclass;
+			}while(p);
+			// if we couldn't find an ancestor in our primary chain, try a mixin chain
+			return !has && (p=this._findMixin(ptype)) && this._findMethod(name, method, p, has);
+		},
+		inherited: function(name, args, newArgs){
+			// optionalize name argument
+			var a = arguments;
+			if(!dojo.isString(a[0])){newArgs=args; args=name; name=args.callee.nom;}
+			a = newArgs||args;
+			var c = args.callee, p = this.constructor.prototype, fn, mp;
+			// if not an instance override
+			if(this[name] != c || p[name] == c){
+				// start from memoized prototype, or
+				// find a prototype that has property 'name' == 'c'
+				mp = (c.ctor||0).superclass || this._findMethod(name, c, p, true);
+				if(!mp){throw(this.declaredClass + ': inherited method "' + name + '" mismatch');}
+				// find a prototype that has property 'name' != 'c'
+				p = this._findMethod(name, c, mp, false);
+			}
+			// we expect 'name' to be in prototype 'p'
+			fn = p && p[name];
+			if(!fn){throw(mp.declaredClass + ': inherited method "' + name + '" not found');}
+			// if the function exists, invoke it in our scope
+			return fn.apply(this, a);
+		}
+	}
+});
+
+}
+
+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
+			var r = t && t.apply(this, arguments);
+			// make local copy of listener array so it is immutable during processing
+			var lls;
+											lls = [].concat(ls);
+							
+			// invoke listeners after target function
+			for(var 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:
+	//		Create a link that calls one function when another executes. 
+	//
+	// description:
+	//		Connects method to event, so that after event fires, method
+	//		does too. All connected functions are passed the same arguments as
+	//		the event function was initially called with. You may connect as
+	//		many methods to event as needed.
+	//
+	//		event must be a string. If obj is null, dojo.global is used.
+	//
+	//		null arguments may simply be omitted.
+	//
+	//		obj[event] can resolve to a function or undefined (null). 
+	//		If obj[event] is null, it is assigned a function.
+	//
+	//		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 ommited
+	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 everytime 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");
+
+
+dojo.Deferred = function(/*Function?*/ canceller){
+	// summary:
+	//		Encapsulates a sequence of callbacks in response to a value that
+	//		may not yet be available.  This is modeled after the Deferred class
+	//		from Twisted <http://twistedmatrix.com>.
+	// description:
+	//		JavaScript has no threads, and even if it did, threads are hard.
+	//		Deferreds are a way of abstracting non-blocking events, such as the
+	//		final response to an XMLHttpRequest. Deferreds create a promise to
+	//		return a response a some point in the future and an easy way to
+	//		register your interest in receiving that response.
+	//
+	//		The most important methods for Deffered users are:
+	//
+	//			* addCallback(handler)
+	//			* addErrback(handler)
+	//			* callback(result)
+	//			* errback(result)
+	//
+	//		In general, when a function returns a Deferred, users then "fill
+	//		in" the second half of the contract by registering callbacks and
+	//		error handlers. You may register as many callback and errback
+	//		handlers as you like and they will be executed in the order
+	//		registered when a result is provided. Usually this result is
+	//		provided as the result of an asynchronous operation. The code
+	//		"managing" the Deferred (the code that made the promise to provide
+	//		an answer later) will use the callback() and errback() methods to
+	//		communicate with registered listeners about the result of the
+	//		operation. At this time, all registered result handlers are called
+	//		*with the most recent result value*.
+	//
+	//		Deferred callback handlers are treated as a chain, and each item in
+	//		the chain is required to return a value that will be fed into
+	//		successive handlers. The most minimal callback may be registered
+	//		like this:
+	//
+	//		|	var d = new dojo.Deferred();
+	//		|	d.addCallback(function(result){ return result; });
+	//
+	//		Perhaps the most common mistake when first using Deferreds is to
+	//		forget to return a value (in most cases, the value you were
+	//		passed).
+	//
+	//		The sequence of callbacks is internally represented as a list of
+	//		2-tuples containing the callback/errback pair.  For example, the
+	//		following call sequence:
+	//		
+	//		|	var d = new dojo.Deferred();
+	//		|	d.addCallback(myCallback);
+	//		|	d.addErrback(myErrback);
+	//		|	d.addBoth(myBoth);
+	//		|	d.addCallbacks(myCallback, myErrback);
+	//
+	//		is translated into a Deferred with the following internal
+	//		representation:
+	//
+	//		|	[
+	//		|		[myCallback, null],
+	//		|		[null, myErrback],
+	//		|		[myBoth, myBoth],
+	//		|		[myCallback, myErrback]
+	//		|	]
+	//
+	//		The Deferred also keeps track of its current status (fired).  Its
+	//		status may be one of three things:
+	//
+	//			* -1: no value yet (initial condition)
+	//			* 0: success
+	//			* 1: error
+	//	
+	//		A Deferred will be in the error state if one of the following three
+	//		conditions are met:
+	//
+	//			1. The result given to callback or errback is "instanceof" Error
+	//			2. The previous callback or errback raised an exception while
+	//			   executing
+	//			3. The previous callback or errback returned a value
+	//			   "instanceof" Error
+	//
+	//		Otherwise, the Deferred will be in the success state. The state of
+	//		the Deferred determines the next element in the callback sequence
+	//		to run.
+	//
+	//		When a callback or errback occurs with the example deferred chain,
+	//		something equivalent to the following will happen (imagine
+	//		that exceptions are caught and returned):
+	//
+	//		|	// d.callback(result) or d.errback(result)
+	//		|	if(!(result instanceof Error)){
+	//		|		result = myCallback(result);
+	//		|	}
+	//		|	if(result instanceof Error){
+	//		|		result = myErrback(result);
+	//		|	}
+	//		|	result = myBoth(result);
+	//		|	if(result instanceof Error){
+	//		|		result = myErrback(result);
+	//		|	}else{
+	//		|		result = myCallback(result);
+	//		|	}
+	//
+	//		The result is then stored away in case another step is added to the
+	//		callback sequence.	Since the Deferred already has a value
+	//		available, any new callbacks added will be called immediately.
+	//
+	//		There are two other "advanced" details about this implementation
+	//		that are useful:
+	//
+	//		Callbacks are allowed to return Deferred instances 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).addErrback(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 syncrhonous 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).addErrback(function(){
+	//		|		promptUserToRecover();
+	//		|	});
+	//
+	//		Note that the caller doesn't have to change his code at all to
+	//		handle the asynchronous case.
+
+	this.chain = [];
+	this.id = this._nextId();
+	this.fired = -1;
+	this.paused = 0;
+	this.results = [null, null];
+	this.canceller = canceller;
+	this.silentlyCancelled = false;
+};
+
+dojo.extend(dojo.Deferred, {
+	/*
+	makeCalled: function(){
+		// summary:
+		//		returns a new, empty deferred, which is already in the called
+		//		state. Calling callback() or errback() on this deferred will
+		//		yeild an error and adding new handlers to it will result in
+		//		them being called immediately.
+		var deferred = new dojo.Deferred();
+		deferred.callback();
+		return deferred;
+	},
+
+	toString: function(){
+		var state;
+		if(this.fired == -1){
+			state = 'unfired';
+		}else{
+			state = this.fired ? 'success' : 'error';
+		}
+		return 'Deferred(' + this.id + ', ' + state + ')';
+	},
+	*/
+
+	_nextId: (function(){
+		var n = 1;
+		return function(){ return n++; };
+	})(),
+
+	cancel: function(){
+		// summary:	
+		//		Cancels a Deferred that has not yet received a value, or is
+		//		waiting on another Deferred as its value.
+		// description:
+		//		If a canceller is defined, the canceller is called. If the
+		//		canceller did not return an error, or there was no canceller,
+		//		then the errback chain is started.
+		var err;
+		if(this.fired == -1){
+			if(this.canceller){
+				err = this.canceller(this);
+			}else{
+				this.silentlyCancelled = true;
+			}
+			if(this.fired == -1){
+				if(!(err instanceof Error)){
+					var res = err;
+					var msg = "Deferred Cancelled";
+					if(err && err.toString){
+						msg += ": " + err.toString();
+					}
+					err = new Error(msg);
+					err.dojoType = "cancel";
+					err.cancelResult = res;
+				}
+				this.errback(err);
+			}
+		}else if(	(this.fired == 0) &&
+					(this.results[0] instanceof dojo.Deferred)
+		){
+			this.results[0].cancel();
+		}
+	},
+			
+
+	_resback: function(res){
+		// summary:
+		//		The private primitive that means either callback or errback
+		this.fired = ((res instanceof Error) ? 1 : 0);
+		this.results[this.fired] = res;
+		this._fire();
+	},
+
+	_check: function(){
+		if(this.fired != -1){
+			if(!this.silentlyCancelled){
+				throw new Error("already called!");
+			}
+			this.silentlyCancelled = false;
+			return;
+		}
+	},
+
+	callback: function(res){
+		//	summary:	
+		//		Begin the callback sequence with a non-error value.
+		
+		/*
+		callback or errback should only be called once on a given
+		Deferred.
+		*/
+		this._check();
+		this._resback(res);
+	},
+
+	errback: function(/*Error*/res){
+		//	summary: 
+		//		Begin the callback sequence with an error result.
+		this._check();
+		if(!(res instanceof Error)){
+			res = new Error(res);
+		}
+		this._resback(res);
+	},
+
+	addBoth: function(/*Function|Object*/cb, /*String?*/cbfn){
+		//	summary:
+		//		Add the same function as both a callback and an errback as the
+		//		next element on the callback sequence.This is useful for code
+		//		that you want to guarantee to run, e.g. a finalizer.
+		var enclosed = dojo.hitch.apply(dojo, arguments);
+		return this.addCallbacks(enclosed, enclosed); // dojo.Deferred
+	},
+
+	addCallback: function(/*Function|Object*/cb, /*String?*/cbfn /*...*/){
+		//	summary: 
+		//		Add a single callback to the end of the callback sequence.
+		return this.addCallbacks(dojo.hitch.apply(dojo, arguments)); // dojo.Deferred
+	},
+
+	addErrback: function(cb, cbfn){
+		//	summary: 
+		//		Add a single callback to the end of the callback sequence.
+		return this.addCallbacks(null, dojo.hitch.apply(dojo, arguments)); // dojo.Deferred
+	},
+
+	addCallbacks: function(cb, eb){
+		// summary: 
+		//		Add separate callback and errback to the end of the callback
+		//		sequence.
+		this.chain.push([cb, eb])
+		if(this.fired >= 0){
+			this._fire();
+		}
+		return this; // dojo.Deferred
+	},
+
+	_fire: function(){
+		// summary: 
+		//		Used internally to exhaust the callback sequence when a result
+		//		is available.
+		var chain = this.chain;
+		var fired = this.fired;
+		var res = this.results[fired];
+		var self = this;
+		var cb = null;
+		while(
+			(chain.length > 0) &&
+			(this.paused == 0)
+		){
+			// Array
+			var f = chain.shift()[fired];
+			if(!f){ continue; }
+			var func = function(){
+				var ret = f(res);
+				//If no response, then use previous response.
+				if(typeof ret != "undefined"){
+					res = ret;
+				}
+				fired = ((res instanceof Error) ? 1 : 0);
+				if(res instanceof dojo.Deferred){
+					cb = function(res){
+						self._resback(res);
+						// inlined from _pause()
+						self.paused--;
+						if(
+							(self.paused == 0) && 
+							(self.fired >= 0)
+						){
+							self._fire();
+						}
+					}
+					// inlined from _unpause
+					this.paused++;
+				}
+			};
+			if(dojo.config.debugAtAllCosts){
+				func.call(this);
+			}else{
+				try{
+					func.call(this);
+				}catch(err){
+					fired = 1;
+					res = err;
+				}
+			}
+		}
+		this.fired = fired;
+		this.results[fired] = res;
+		if((cb)&&(this.paused)){
+			// this is for "tail recursion" in case the dependent
+			// deferred is already fired
+			res.addBoth(cb);
+		}
+	}
+});
+
+}
+
+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.  Throws for invalid JSON strings.
+	// 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 before calling dojo.toJson().
+	//
+	// _indentStr:
+	//		private variable for recursive calls when pretty printing, do not use.
+
+	if(it === undefined){
+		return "undefined";
+	}
+	var objtype = typeof it;
+	if(objtype == "number" || objtype == "boolean"){
+		return it + "";
+	}
+	if(it === null){
+		return "null";
+	}
+	if(dojo.isString(it)){ 
+		return dojo._escapeString(it); 
+	}
+	// recurse
+	var recurse = arguments.callee;
+	// short-circuit for objects that support "json" serialization
+	// if they return "self" then just pass-through...
+	var newObj;
+	_indentStr = _indentStr || "";
+	var nextIndent = prettyPrint ? _indentStr + dojo.toJsonIndentStr : "";
+	var tf = it.__json__||it.json;
+	if(dojo.isFunction(tf)){
+		newObj = tf.call(it);
+		if(it !== newObj){
+			return recurse(newObj, prettyPrint, nextIndent);
+		}
+	}
+	if(it.nodeType && it.cloneNode){ // isNode
+		// we can't seriailize DOM nodes as regular objects because they have cycles
+		// DOM nodes could be serialized with something like outerHTML, but
+		// that can be provided by users in the form of .json or .__json__ function.
+		throw new Error("Can't serialize DOM nodes");
+	}
+
+	var sep = prettyPrint ? " " : "";
+	var newLine = prettyPrint ? "\n" : "";
+
+	// array
+	if(dojo.isArray(it)){
+		var res = dojo.map(it, function(obj){
+			var val = recurse(obj, prettyPrint, nextIndent);
+			if(typeof val != "string"){
+				val = "undefined";
+			}
+			return newLine + nextIndent + val;
+		});
+		return "[" + res.join("," + sep) + newLine + _indentStr + "]";
+	}
+	/*
+	// look in the registry
+	try {
+		window.o = it;
+		newObj = dojo.json.jsonRegistry.match(it);
+		return recurse(newObj, prettyPrint, nextIndent);
+	}catch(e){
+		// 
+	}
+	// it's a function with no adapter, skip it
+	*/
+	if(objtype == "function"){
+		return null; // null
+	}
+	// generic object code path
+	var output = [], key;
+	for(key in it){
+		var keyStr, val;
+		if(typeof key == "number"){
+			keyStr = '"' + key + '"';
+		}else if(typeof key == "string"){
+			keyStr = dojo._escapeString(key);
+		}else{
+			// skip non-string or number keys
+			continue;
+		}
+		val = recurse(it[key], prettyPrint, nextIndent);
+		if(typeof val != "string"){
+			// skip non-serializable values
+			continue;
+		}
+		// FIXME: use += on Moz!!
+		//	 MOW NOTE: using += is a pain because you have to account for the dangling comma...
+		output.push(newLine + nextIndent + keyStr + ":" + sep + val);
+	}
+	return "{" + output.join("," + sep) + newLine + _indentStr + "}"; // String
+}
+
+}
+
+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 [ 
+			dojo.isString(arr) ? arr.split("") : arr, 
+			obj || dojo.global,
+			// FIXME: cache the anonymous functions we create here?
+			dojo.isString(cb) ? new Function("item", "index", "array", cb) : cb
+		];
+	};
+
+	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:
+			//		For details on this method, see:
+			// 			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_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:
+			//		For details on this method, see:
+			// 			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_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.
+			//	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. For more details, see:
+			//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:forEach
+			//	example:
+			//	|	// log out all members of the array:
+			//	|	dojo.forEach(
+			//	|		[ "thinger", "blah", "howdy", 10 ],
+			//	|		function(item){
+			//	|			
+			//	|		}
+			//	|	);
+			//	example:
+			//	|	// log out the members and their indexes
+			//	|	dojo.forEach(
+			//	|		[ "thinger", "blah", "howdy", 10 ],
+			//	|		function(item, idx, arr){
+			//	|			
+			//	|		}
+			//	|	);
+			//	example:
+			//	|	// use a scoped object member as the callback
+			//	|	
+			//	|	var obj = {
+			//	|		prefix: "logged via obj.callback:", 
+			//	|		callback: function(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);
+			}
+		},
+
+		_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
+		},
+
+		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. For more details, see:
+			//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_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 dojo._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. For more details, see:
+			//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_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 dojo._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. For more details, see:
+			//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_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. For more details, see:
+			//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_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.Color"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.Color"] = true;
+dojo.provide("dojo._base.Color");
+
+
+
+(function(){
+	
+	var d = dojo;
+		
+	dojo.Color = function(/*Array|String|Object*/ color){
+		// summary:
+		//		Takes a named string, hex string, array of rgb or rgba values,
+		//		an object with r, g, b, and a properties, or another `dojo.Color` object
+		//		and creates a new Color instance to work from.
+		//
+		// example:
+		// 	Work with a Color instance:
+		//	| var c = new dojo.Color(); 
+		//	| c.setColor([0,0,0]); // black
+		//	| var hex = c.toHex(); // #000000
+		//
+		// example:
+		//	Work with a node's color:
+		//	| var color = dojo.style("someNode", "backgroundColor");
+		//	| var n = new dojo.Color(color);
+		//	| // adjust the color some
+		//	| n.r *= .5; 
+		//  |  // rgb(128, 255, 255);
+		if(color){ this.setColor(color); }
+	};
+
+	// FIXME: there's got to be a more space-efficient way to encode or discover these!!  Use hex?
+	dojo.Color.named = {
+		black:      [0,0,0],
+		silver:     [192,192,192],
+		gray:       [128,128,128],
+		white:      [255,255,255],
+		maroon:		[128,0,0],
+		red:        [255,0,0],
+		purple:		[128,0,128],
+		fuchsia:	[255,0,255],
+		green:	    [0,128,0],
+		lime:	    [0,255,0],
+		olive:		[128,128,0],
+		yellow:		[255,255,0],
+		navy:       [0,0,128],
+		blue:       [0,0,255],
+		teal:		[0,128,128],
+		aqua:		[0,255,255]
+	};
+
+	dojo.extend(dojo.Color, {
+		r: 255, g: 255, b: 255, a: 1,
+		_set: function(r, g, b, a){
+			var t = this; t.r = r; t.g = g; t.b = b; t.a = a;
+		},
+		setColor: function(/*Array|String|Object*/ color){
+			// summary:
+			//		Takes a named string, hex string, array of rgb or rgba values,
+			//		an object with r, g, b, and a properties, or another `dojo.Color` object
+			//		and sets this color instance to that value. 
+			// 
+			// example:
+			//	|	var c = new dojo.Color(); // no color
+			//	|	c.setColor("#ededed"); // greyish
+			if(d.isString(color)){
+				d.colorFromString(color, this);
+			}else if(d.isArray(color)){
+				d.colorFromArray(color, this);
+			}else{
+				this._set(color.r, color.g, color.b, color.a);
+				if(!(color instanceof d.Color)){ this.sanitize(); }
+			}
+			return this;	// dojo.Color
+		},
+		sanitize: function(){
+			// summary:
+			//		makes sure that the object has correct attributes
+			// description: 
+			//		the default implementation does nothing, include dojo.colors to
+			//		augment it to real checks
+			return this;	// dojo.Color
+		},
+		toRgb: function(){
+			// summary: Returns 3 component array of rgb values
+			//
+			// example:
+			//	| var c = new dojo.Color("#000000"); 
+			//	|  // [0,0,0] 
+			var t = this;
+			return [t.r, t.g, t.b];	// Array
+		},
+		toRgba: function(){
+			// summary: Returns a 4 component array of rgba values
+			var t = this;
+			return [t.r, t.g, t.b, t.a];	// Array
+		},
+		toHex: function(){
+			// summary: Returns a css color string in hexadecimal representation
+			//
+			// example: 
+			// | 	 // #000000
+			var arr = d.map(["r", "g", "b"], function(x){
+				var s = this[x].toString(16);
+				return s.length < 2 ? "0" + s : s;
+			}, this);
+			return "#" + arr.join("");	// String
+		},
+		toCss: function(/*Boolean?*/ includeAlpha){
+			// summary: Returns a css color string in rgb(a) representation
+			//
+			// example:
+			// |	var c = new dojo.Color("#FFF").toCss();
+			// |	 // rgb('255','255','255')
+			var t = this, rgb = t.r + ", " + t.g + ", " + t.b;
+			return (includeAlpha ? "rgba(" + rgb + ", " + t.a : "rgb(" + rgb) + ")";	// String
+		},
+		toString: function(){
+			// summary: Returns a visual representation of the color
+			return this.toCss(true); // String
+		}
+	});
+
+	dojo.blendColors = function(
+		/*dojo.Color*/ start, 
+		/*dojo.Color*/ end, 
+		/*Number*/ weight,
+		/*dojo.Color?*/ obj
+	){
+		// summary: 
+		//		Blend colors end and start with weight from 0 to 1, 0.5 being a 50/50 blend,
+		//		can reuse a previously allocated dojo.Color object for the result
+		var t = obj || new d.Color();
+		d.forEach(["r", "g", "b", "a"], function(x){
+			t[x] = start[x] + (end[x] - start[x]) * weight;
+			if(x != "a"){ t[x] = Math.round(t[x]); }
+		});
+		return t.sanitize();	// dojo.Color
+	};
+
+	dojo.colorFromRgb = function(/*String*/ color, /*dojo.Color?*/ obj){
+		// summary: get rgb(a) array from css-style color declarations
+		var m = color.toLowerCase().match(/^rgba?\(([\s\.,0-9]+)\)/);
+		return m && dojo.colorFromArray(m[1].split(/\s*,\s*/), obj);	// dojo.Color
+	};
+
+	dojo.colorFromHex = function(/*String*/ color, /*dojo.Color?*/ obj){
+		// summary: converts a hex string with a '#' prefix to a color object.
+		//	Supports 12-bit #rgb shorthand.
+		//
+		// example:
+		//	| var thing = dojo.colorFromHex("#ededed"); // grey, longhand
+		//
+		// example:
+		//	| var thing = dojo.colorFromHex("#000"); // black, shorthand
+		var t = obj || new d.Color(),
+			bits = (color.length == 4) ? 4 : 8,
+			mask = (1 << bits) - 1;
+		color = Number("0x" + color.substr(1));
+		if(isNaN(color)){
+			return null; // dojo.Color
+		}
+		d.forEach(["b", "g", "r"], function(x){
+			var c = color & mask;
+			color >>= bits;
+			t[x] = bits == 4 ? 17 * c : c;
+		});
+		t.a = 1;
+		return t;	// dojo.Color
+	};
+
+	dojo.colorFromArray = function(/*Array*/ a, /*dojo.Color?*/ obj){
+		// summary: builds a color from 1, 2, 3, or 4 element array
+		var t = obj || new d.Color();
+		t._set(Number(a[0]), Number(a[1]), Number(a[2]), Number(a[3]));
+		if(isNaN(t.a)){ t.a = 1; }
+		return t.sanitize();	// dojo.Color
+	};
+
+	dojo.colorFromString = function(/*String*/ str, /*dojo.Color?*/ obj){
+		//	summary:
+		//		parses str for a color value.
+		//	description:
+		//		Acceptable input values for str may include arrays of any form
+		//		accepted by dojo.colorFromArray, hex strings such as "#aaaaaa", or
+		//		rgb or rgba strings such as "rgb(133, 200, 16)" or "rgba(10, 10,
+		//		10, 50)"
+		//	returns:
+		//		a dojo.Color object. If obj is passed, it will be the return value.
+		var a = d.Color.named[str];
+		return a && d.colorFromArray(a, obj) || d.colorFromRgb(str, obj) || d.colorFromHex(str, obj);
+	};
+
+})();
+
+}
+
+if(!dojo._hasResource["dojo._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base"] = true;
+dojo.provide("dojo._base");
+
+
+
+
+
+
+
+
+
+}
+
+if(!dojo._hasResource["dojo._base.window"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.window"] = true;
+dojo.provide("dojo._base.window");
+
+/*=====
+dojo.doc = {
+	// summary:
+	//		Alias for the current document. 'dojo.doc' can be modified
+	//		for temporary context shifting. Also see dojo.withDoc().
+	// description:
+	//    Refer to dojo.doc rather
+	//    than referring to 'window.document' to ensure your code runs
+	//    correctly in managed contexts.
+	// example:
+	// 	|	n.appendChild(dojo.doc.createElement('div'));
+}
+=====*/
+dojo.doc = window["document"] || null;
+
+dojo.body = function(){
+	// summary:
+	//		Return the body element of the document
+	//		return the body object associated with dojo.doc
+	// example:
+	// 	|	dojo.body().appendChild(dojo.doc.createElement('div'));
+
+	// Note: document.body is not defined for a strict xhtml document
+	// Would like to memoize this, but dojo.doc can change vi dojo.withDoc().
+	return dojo.doc.body || dojo.doc.getElementsByTagName("body")[0]; // Node
+}
+
+dojo.setContext = function(/*Object*/globalObject, /*DocumentElement*/globalDocument){
+	// summary:
+	//		changes the behavior of many core Dojo functions that deal with
+	//		namespace and DOM lookup, changing them to work in a new global
+	//		context (e.g., an iframe). The varibles dojo.global and dojo.doc
+	//		are modified as a result of calling this function and the result of
+	//		`dojo.body()` likewise differs.
+	dojo.global = globalObject;
+	dojo.doc = globalDocument;
+};
+
+dojo.withGlobal = function(	/*Object*/globalObject, 
+							/*Function*/callback, 
+							/*Object?*/thisObject, 
+							/*Array?*/cbArguments){
+	// summary:
+	//		Invoke callback with globalObject as dojo.global and
+	//		globalObject.document as dojo.doc.
+	// description:
+	//		Invoke callback with globalObject as dojo.global and
+	//		globalObject.document as dojo.doc. If provided, globalObject
+	//		will be executed in the context of object thisObject
+	//		When callback() returns or throws an error, the dojo.global
+	//		and dojo.doc will be restored to its previous state.
+
+	var oldGlob = dojo.global;
+	try{
+		dojo.global = globalObject;
+		return dojo.withDoc.call(null, globalObject.document, callback, thisObject, cbArguments);
+	}finally{
+		dojo.global = oldGlob;
+	}
+}
+
+dojo.withDoc = function(	/*DocumentElement*/documentObject, 
+							/*Function*/callback, 
+							/*Object?*/thisObject, 
+							/*Array?*/cbArguments){
+	// summary:
+	//		Invoke callback with documentObject as dojo.doc.
+	// description:
+	//		Invoke callback with documentObject as dojo.doc. If provided,
+	//		callback will be executed in the context of object thisObject
+	//		When callback() returns or throws an error, the dojo.doc will
+	//		be restored to its previous state.
+
+	var oldDoc = dojo.doc,
+		oldLtr = dojo._bodyLtr;
+
+	try{
+		dojo.doc = documentObject;
+		delete dojo._bodyLtr; // uncache
+
+		if(thisObject && dojo.isString(callback)){
+			callback = thisObject[callback];
+		}
+
+		return callback.apply(thisObject, cbArguments || []);
+	}finally{
+		dojo.doc = oldDoc;
+		if(oldLtr !== undefined){ dojo._bodyLtr = oldLtr; }
+	}
+};
+	
+
+}
+
+if(!dojo._hasResource["dojo._base.event"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.event"] = true;
+dojo.provide("dojo._base.event");
+
+
+// this file courtesy of the TurboAjax Group, licensed under a Dojo CLA
+
+(function(){
+	// DOM event listener machinery
+	var del = (dojo._event_listener = {
+		add: function(/*DOMNode*/node, /*String*/name, /*Function*/fp){
+			if(!node){return;} 
+			name = del._normalizeEventName(name);
+			fp = del._fixCallback(name, fp);
+			var oname = name;
+			if(
+								!dojo.isIE && 
+								(name == "mouseenter" || name == "mouseleave")
+			){
+				var ofp = fp;
+				//oname = name;
+				name = (name == "mouseenter") ? "mouseover" : "mouseout";
+				fp = function(e){		
+					if(dojo.isFF <= 2) {
+						// check tagName to fix a FF2 bug with invalid nodes (hidden child DIV of INPUT)
+						// which causes isDescendant to return false which causes
+						// spurious, and more importantly, incorrect mouse events to fire.
+						// TODO: remove tagName check when Firefox 2 is no longer supported
+						try{ e.relatedTarget.tagName; }catch(e2){ return; }
+					}
+					if(!dojo.isDescendant(e.relatedTarget, node)){
+						// e.type = oname; // FIXME: doesn't take? SJM: event.type is generally immutable.
+						return ofp.call(this, e); 
+					}
+				}
+			}
+			node.addEventListener(name, fp, false);
+			return fp; /*Handle*/
+		},
+		remove: function(/*DOMNode*/node, /*String*/event, /*Handle*/handle){
+			// summary:
+			//		clobbers the listener from the node
+			// node:
+			//		DOM node to attach the event to
+			// event:
+			//		the name of the handler to remove the function from
+			// handle:
+			//		the handle returned from add
+			if(node){
+				event = del._normalizeEventName(event);
+				if(!dojo.isIE && (event == "mouseenter" || event == "mouseleave")){
+					event = (event == "mouseenter") ? "mouseover" : "mouseout";
+				}
+
+				node.removeEventListener(event, handle, false);
+			}
+		},
+		_normalizeEventName: function(/*String*/name){
+			// Generally, name should be lower case, unless it is special
+			// somehow (e.g. a Mozilla DOM event).
+			// Remove 'on'.
+			return name.slice(0,2) =="on" ? name.slice(2) : name;
+		},
+		_fixCallback: function(/*String*/name, fp){
+			// By default, we only invoke _fixEvent for 'keypress'
+			// If code is added to _fixEvent for other events, we have
+			// to revisit this optimization.
+			// This also applies to _fixEvent overrides for Safari and Opera
+			// below.
+			return name != "keypress" ? fp : function(e){ return fp.call(this, del._fixEvent(e, this)); };
+		},
+		_fixEvent: function(evt, sender){
+			// _fixCallback only attaches us to keypress.
+			// Switch on evt.type anyway because we might 
+			// be called directly from dojo.fixEvent.
+			switch(evt.type){
+				case "keypress":
+					del._setKeyChar(evt);
+					break;
+			}
+			return evt;
+		},
+		_setKeyChar: function(evt){
+			evt.keyChar = evt.charCode ? String.fromCharCode(evt.charCode) : '';
+			evt.charOrCode = evt.keyChar || evt.keyCode;
+		},
+		// For IE and Safari: some ctrl-key combinations (mostly w/punctuation) do not emit a char code in IE
+		// we map those virtual key codes to ascii here
+		// not valid for all (non-US) keyboards, so maybe we shouldn't bother
+		_punctMap: { 
+			106:42, 
+			111:47, 
+			186:59, 
+			187:43, 
+			188:44, 
+			189:45, 
+			190:46, 
+			191:47, 
+			192:96, 
+			219:91, 
+			220:92, 
+			221:93, 
+			222:39 
+		}
+	});
+
+	// DOM events
+	
+	dojo.fixEvent = function(/*Event*/evt, /*DOMNode*/sender){
+		// summary:
+		//		normalizes properties on the event object including event
+		//		bubbling methods, keystroke normalization, and x/y positions
+		// evt: Event
+		//		native event object
+		// sender: DOMNode
+		//		node to treat as "currentTarget"
+		return del._fixEvent(evt, sender);
+	}
+
+	dojo.stopEvent = function(/*Event*/evt){
+		// summary:
+		//		prevents propagation and clobbers the default action of the
+		//		passed event
+		// evt: Event
+		//		The event object. If omitted, window.event is used on IE.
+		evt.preventDefault();
+		evt.stopPropagation();
+		// NOTE: below, this method is overridden for IE
+	}
+
+	// the default listener to use on dontFix nodes, overriden for IE
+	var node_listener = dojo._listener;
+	
+	// Unify connect and event listeners
+	dojo._connect = function(obj, event, context, method, dontFix){
+		// FIXME: need a more strict test
+		var isNode = obj && (obj.nodeType||obj.attachEvent||obj.addEventListener);
+		// choose one of three listener options: raw (connect.js), DOM event on a Node, custom event on a Node
+		// we need the third option to provide leak prevention on broken browsers (IE)
+		var lid = isNode ? (dontFix ? 2 : 1) : 0, l = [dojo._listener, del, node_listener][lid];
+		// create a listener
+		var h = l.add(obj, event, dojo.hitch(context, method));
+		// formerly, the disconnect package contained "l" directly, but if client code
+		// leaks the disconnect package (by connecting it to a node), referencing "l" 
+		// compounds the problem.
+		// instead we return a listener id, which requires custom _disconnect below.
+		// return disconnect package
+		return [ obj, event, h, lid ];
+	}
+
+	dojo._disconnect = function(obj, event, handle, listener){
+		([dojo._listener, del, node_listener][listener]).remove(obj, event, handle);
+	}
+
+	// Constants
+
+	// Public: client code should test
+	// keyCode against these named constants, as the
+	// actual codes can vary by browser.
+	dojo.keys = {
+		// summary: definitions for common key values
+		BACKSPACE: 8,
+		TAB: 9,
+		CLEAR: 12,
+		ENTER: 13,
+		SHIFT: 16,
+		CTRL: 17,
+		ALT: 18,
+		PAUSE: 19,
+		CAPS_LOCK: 20,
+		ESCAPE: 27,
+		SPACE: 32,
+		PAGE_UP: 33,
+		PAGE_DOWN: 34,
+		END: 35,
+		HOME: 36,
+		LEFT_ARROW: 37,
+		UP_ARROW: 38,
+		RIGHT_ARROW: 39,
+		DOWN_ARROW: 40,
+		INSERT: 45,
+		DELETE: 46,
+		HELP: 47,
+		LEFT_WINDOW: 91,
+		RIGHT_WINDOW: 92,
+		SELECT: 93,
+		NUMPAD_0: 96,
+		NUMPAD_1: 97,
+		NUMPAD_2: 98,
+		NUMPAD_3: 99,
+		NUMPAD_4: 100,
+		NUMPAD_5: 101,
+		NUMPAD_6: 102,
+		NUMPAD_7: 103,
+		NUMPAD_8: 104,
+		NUMPAD_9: 105,
+		NUMPAD_MULTIPLY: 106,
+		NUMPAD_PLUS: 107,
+		NUMPAD_ENTER: 108,
+		NUMPAD_MINUS: 109,
+		NUMPAD_PERIOD: 110,
+		NUMPAD_DIVIDE: 111,
+		F1: 112,
+		F2: 113,
+		F3: 114,
+		F4: 115,
+		F5: 116,
+		F6: 117,
+		F7: 118,
+		F8: 119,
+		F9: 120,
+		F10: 121,
+		F11: 122,
+		F12: 123,
+		F13: 124,
+		F14: 125,
+		F15: 126,
+		NUM_LOCK: 144,
+		SCROLL_LOCK: 145
+	};
+	
+		// IE event normalization
+	if(dojo.isIE){ 
+		var _trySetKeyCode = function(e, code){
+			try{
+				// squelch errors when keyCode is read-only
+				// (e.g. if keyCode is ctrl or shift)
+				return (e.keyCode = code);
+			}catch(e){
+				return 0;
+			}
+		}
+
+		// by default, use the standard listener
+		var iel = dojo._listener;
+		var listenersName = (dojo._ieListenersName = "_" + dojo._scopeName + "_listeners");
+		// dispatcher tracking property
+		if(!dojo.config._allow_leaks){
+			// custom listener that handles leak protection for DOM events
+			node_listener = iel = dojo._ie_listener = {
+				// support handler indirection: event handler functions are 
+				// referenced here. Event dispatchers hold only indices.
+				handlers: [],
+				// add a listener to an object
+				add: function(/*Object*/ source, /*String*/ method, /*Function*/ listener){
+					source = source || dojo.global;
+					var f = source[method];
+					if(!f||!f[listenersName]){
+						var d = dojo._getIeDispatcher();
+						// original target function is special
+						d.target = f && (ieh.push(f) - 1);
+						// dispatcher holds a list of indices into handlers table
+						d[listenersName] = [];
+						// redirect source to dispatcher
+						f = source[method] = d;
+					}
+					return f[listenersName].push(ieh.push(listener) - 1) ; /*Handle*/
+				},
+				// remove a listener from an object
+				remove: function(/*Object*/ source, /*String*/ method, /*Handle*/ handle){
+					var f = (source||dojo.global)[method], l = f && f[listenersName];
+					if(f && l && handle--){
+						delete ieh[l[handle]];
+						delete l[handle];
+					}
+				}
+			};
+			// alias used above
+			var ieh = iel.handlers;
+		}
+
+		dojo.mixin(del, {
+			add: function(/*DOMNode*/node, /*String*/event, /*Function*/fp){
+				if(!node){return;} // undefined
+				event = del._normalizeEventName(event);
+				if(event=="onkeypress"){
+					// we need to listen to onkeydown to synthesize
+					// keypress events that otherwise won't fire
+					// on IE
+					var kd = node.onkeydown;
+					if(!kd || !kd[listenersName] || !kd._stealthKeydownHandle){
+						var h = del.add(node, "onkeydown", del._stealthKeyDown);
+						kd = node.onkeydown;
+						kd._stealthKeydownHandle = h;
+						kd._stealthKeydownRefs = 1;
+					}else{
+						kd._stealthKeydownRefs++;
+					}
+				}
+				return iel.add(node, event, del._fixCallback(fp));
+			},
+			remove: function(/*DOMNode*/node, /*String*/event, /*Handle*/handle){
+				event = del._normalizeEventName(event);
+				iel.remove(node, event, handle); 
+				if(event=="onkeypress"){
+					var kd = node.onkeydown;
+					if(--kd._stealthKeydownRefs <= 0){
+						iel.remove(node, "onkeydown", kd._stealthKeydownHandle);
+						delete kd._stealthKeydownHandle;
+					}
+				}
+			},
+			_normalizeEventName: function(/*String*/eventName){
+				// Generally, eventName should be lower case, unless it is
+				// special somehow (e.g. a Mozilla event)
+				// ensure 'on'
+				return eventName.slice(0,2) != "on" ? "on" + eventName : eventName;
+			},
+			_nop: function(){},
+			_fixEvent: function(/*Event*/evt, /*DOMNode*/sender){
+				// summary:
+				//		normalizes properties on the event object including event
+				//		bubbling methods, keystroke normalization, and x/y positions
+				// evt: native event object
+				// sender: node to treat as "currentTarget"
+				if(!evt){
+					var w = sender && (sender.ownerDocument || sender.document || sender).parentWindow || window;
+					evt = w.event; 
+				}
+				if(!evt){return(evt);}
+				evt.target = evt.srcElement; 
+				evt.currentTarget = (sender || evt.srcElement); 
+				evt.layerX = evt.offsetX;
+				evt.layerY = evt.offsetY;
+				// FIXME: scroll position query is duped from dojo.html to
+				// avoid dependency on that entire module. Now that HTML is in
+				// Base, we should convert back to something similar there.
+				var se = evt.srcElement, doc = (se && se.ownerDocument) || document;
+				// DO NOT replace the following to use dojo.body(), in IE, document.documentElement should be used
+				// here rather than document.body
+				var docBody = ((dojo.isIE < 6) || (doc["compatMode"] == "BackCompat")) ? doc.body : doc.documentElement;
+				var offset = dojo._getIeDocumentElementOffset();
+				evt.pageX = evt.clientX + dojo._fixIeBiDiScrollLeft(docBody.scrollLeft || 0) - offset.x;
+				evt.pageY = evt.clientY + (docBody.scrollTop || 0) - offset.y;
+				if(evt.type == "mouseover"){ 
+					evt.relatedTarget = evt.fromElement;
+				}
+				if(evt.type == "mouseout"){ 
+					evt.relatedTarget = evt.toElement;
+				}
+				evt.stopPropagation = del._stopPropagation;
+				evt.preventDefault = del._preventDefault;
+				return del._fixKeys(evt);
+			},
+			_fixKeys: function(evt){
+				switch(evt.type){
+					case "keypress":
+						var c = ("charCode" in evt ? evt.charCode : evt.keyCode);
+						if (c==10){
+							// CTRL-ENTER is CTRL-ASCII(10) on IE, but CTRL-ENTER on Mozilla
+							c=0;
+							evt.keyCode = 13;
+						}else if(c==13||c==27){
+							c=0; // Mozilla considers ENTER and ESC non-printable
+						}else if(c==3){
+							c=99; // Mozilla maps CTRL-BREAK to CTRL-c
+						}
+						// Mozilla sets keyCode to 0 when there is a charCode
+						// but that stops the event on IE.
+						evt.charCode = c;
+						del._setKeyChar(evt);
+						break;
+				}
+				return evt;
+			},
+			_stealthKeyDown: function(evt){
+				// IE doesn't fire keypress for most non-printable characters.
+				// other browsers do, we simulate it here.
+				var kp = evt.currentTarget.onkeypress;
+				// only works if kp exists and is a dispatcher
+				if(!kp || !kp[listenersName]){ return; }
+				// munge key/charCode
+				var k=evt.keyCode;
+				// These are Windows Virtual Key Codes
+				// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/UserInput/VirtualKeyCodes.asp
+				var unprintable = k!=13 && k!=32 && k!=27 && (k<48||k>90) && (k<96||k>111) && (k<186||k>192) && (k<219||k>222);
+				// synthesize keypress for most unprintables and CTRL-keys
+				if(unprintable||evt.ctrlKey){
+					var c = unprintable ? 0 : k;
+					if(evt.ctrlKey){
+						if(k==3 || k==13){
+							return; // IE will post CTRL-BREAK, CTRL-ENTER as keypress natively 
+						}else if(c>95 && c<106){ 
+							c -= 48; // map CTRL-[numpad 0-9] to ASCII
+						}else if((!evt.shiftKey)&&(c>=65&&c<=90)){ 
+							c += 32; // map CTRL-[A-Z] to lowercase
+						}else{ 
+							c = del._punctMap[c] || c; // map other problematic CTRL combinations to ASCII
+						}
+					}
+					// simulate a keypress event
+					var faux = del._synthesizeEvent(evt, {type: 'keypress', faux: true, charCode: c});
+					kp.call(evt.currentTarget, faux);
+					evt.cancelBubble = faux.cancelBubble;
+					evt.returnValue = faux.returnValue;
+					_trySetKeyCode(evt, faux.keyCode);
+				}
+			},
+			// Called in Event scope
+			_stopPropagation: function(){
+				this.cancelBubble = true; 
+			},
+			_preventDefault: function(){
+				// Setting keyCode to 0 is the only way to prevent certain keypresses (namely
+				// ctrl-combinations that correspond to menu accelerator keys).
+				// Otoh, it prevents upstream listeners from getting this information
+				// Try to split the difference here by clobbering keyCode only for ctrl 
+				// combinations. If you still need to access the key upstream, bubbledKeyCode is
+				// provided as a workaround.
+				this.bubbledKeyCode = this.keyCode;
+				if(this.ctrlKey){_trySetKeyCode(this, 0);}
+				this.returnValue = false;
+			}
+		});
+				
+		// override stopEvent for IE
+		dojo.stopEvent = function(evt){
+			evt = evt || window.event;
+			del._stopPropagation.call(evt);
+			del._preventDefault.call(evt);
+		}
+	}
+	
+	del._synthesizeEvent = function(evt, props){
+			var faux = dojo.mixin({}, evt, props);
+			del._setKeyChar(faux);
+			// FIXME: would prefer to use dojo.hitch: dojo.hitch(evt, evt.preventDefault); 
+			// but it throws an error when preventDefault is invoked on Safari
+			// does Event.preventDefault not support "apply" on Safari?
+			faux.preventDefault = function(){ evt.preventDefault(); }; 
+			faux.stopPropagation = function(){ evt.stopPropagation(); }; 
+			return faux;
+	}
+	
+		// Opera event normalization
+	if(dojo.isOpera){
+		dojo.mixin(del, {
+			_fixEvent: function(evt, sender){
+				switch(evt.type){
+					case "keypress":
+						var c = evt.which;
+						if(c==3){
+							c=99; // Mozilla maps CTRL-BREAK to CTRL-c
+						}
+						// can't trap some keys at all, like INSERT and DELETE
+						// there is no differentiating info between DELETE and ".", or INSERT and "-"
+						c = c<41 && !evt.shiftKey ? 0 : c;
+						if(evt.ctrlKey && !evt.shiftKey && c>=65 && c<=90){
+							// lowercase CTRL-[A-Z] keys
+							c += 32;
+						}
+						return del._synthesizeEvent(evt, { charCode: c });
+				}
+				return evt;
+			}
+		});
+	}
+	
+		// Webkit event normalization
+	if(dojo.isWebKit){
+				del._add = del.add;
+		del._remove = del.remove;
+
+		dojo.mixin(del, {
+			add: function(/*DOMNode*/node, /*String*/event, /*Function*/fp){
+				if(!node){return;} // undefined
+				var handle = del._add(node, event, fp);
+				if(del._normalizeEventName(event) == "keypress"){
+					// we need to listen to onkeydown to synthesize
+					// keypress events that otherwise won't fire
+					// in Safari 3.1+: https://lists.webkit.org/pipermail/webkit-dev/2007-December/002992.html
+					handle._stealthKeyDownHandle = del._add(node, "keydown", function(evt){
+						//A variation on the IE _stealthKeydown function
+						//Synthesize an onkeypress event, but only for unprintable characters.
+						var k=evt.keyCode;
+						// These are Windows Virtual Key Codes
+						// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/UserInput/VirtualKeyCodes.asp
+						var unprintable = k!=13 && k!=32 && k!=27 && (k<48 || k>90) && (k<96 || k>111) && (k<186 || k>192) && (k<219 || k>222);
+						// synthesize keypress for most unprintables and CTRL-keys
+						if(unprintable || evt.ctrlKey){
+							var c = unprintable ? 0 : k;
+							if(evt.ctrlKey){
+								if(k==3 || k==13){
+									return; // IE will post CTRL-BREAK, CTRL-ENTER as keypress natively 
+								}else if(c>95 && c<106){ 
+									c -= 48; // map CTRL-[numpad 0-9] to ASCII
+								}else if(!evt.shiftKey && c>=65 && c<=90){ 
+									c += 32; // map CTRL-[A-Z] to lowercase
+								}else{ 
+									c = del._punctMap[c] || c; // map other problematic CTRL combinations to ASCII
+								}
+							}
+							// simulate a keypress event
+							var faux = del._synthesizeEvent(evt, {type: 'keypress', faux: true, charCode: c});
+							fp.call(evt.currentTarget, faux);
+						}
+					});
+				}
+				return handle; /*Handle*/
+			},
+
+			remove: function(/*DOMNode*/node, /*String*/event, /*Handle*/handle){
+				if(node){
+					if(handle._stealthKeyDownHandle){
+						del._remove(node, "keydown", handle._stealthKeyDownHandle);
+					}
+					del._remove(node, event, handle);
+				}
+			},
+			_fixEvent: function(evt, sender){
+				switch(evt.type){
+					case "keypress":
+						if(evt.faux){ return evt; }
+						var c = evt.charCode;
+						c = c>=32 ? c : 0;
+						return del._synthesizeEvent(evt, {charCode: c, faux: true});
+				}
+				return evt;
+			}
+		});
+		}
+	})();
+
+if(dojo.isIE){
+	// keep this out of the closure
+	// closing over 'iel' or 'ieh' b0rks leak prevention
+	// ls[i] is an index into the master handler array
+	dojo._ieDispatcher = function(args, sender){
+		var ap=Array.prototype, h=dojo._ie_listener.handlers, c=args.callee, ls=c[dojo._ieListenersName], t=h[c.target];
+		// return value comes from original target function
+		var r = t && t.apply(sender, args);
+		// make local copy of listener array so it's immutable during processing
+		var lls = [].concat(ls);
+		// invoke listeners after target function
+		for(var i in lls){
+			var f = h[lls[i]];
+			if(!(i in ap) && f){
+				f.apply(sender, args);
+			}
+		}
+		return r;
+	}
+	dojo._getIeDispatcher = function(){
+		// ensure the returned function closes over nothing ("new Function" apparently doesn't close)
+		return new Function(dojo._scopeName + "._ieDispatcher(arguments, this)"); // function
+	}
+	// keep this out of the closure to reduce RAM allocation
+	dojo._event_listener._fixCallback = function(fp){
+		var f = dojo._event_listener._fixEvent;
+		return function(e){ return fp.call(this, f(e, this)); };
+	}
+}
+
+}
+
+if(!dojo._hasResource["dojo._base.html"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.html"] = true;
+
+dojo.provide("dojo._base.html");
+
+// FIXME: need to add unit tests for all the semi-public methods
+
+try{
+	document.execCommand("BackgroundImageCache", false, true);
+}catch(e){
+	// sane browsers don't have cache "issues"
+}
+
+// =============================
+// DOM Functions
+// =============================
+
+/*=====
+dojo.byId = function(id, doc){
+	//	summary:
+	//		Returns DOM node with matching `id` attribute or `null` 
+	//		if not found, similar to "$" function in another library.
+	//		If `id` is a DomNode, this function is a no-op.
+	//
+	//	id: String|DOMNode
+	//	 	A string to match an HTML id attribute or a reference to a DOM Node
+	//
+	//	doc: Document?
+	//		Document to work in. Defaults to the current value of
+	//		dojo.doc.  Can be used to retrieve
+	//		node references from other documents.
+	// 
+	//	example:
+	//	Look up a node by ID:
+	//	| var n = dojo.byId("foo");
+	//
+	//	example:
+	//	Check if a node exists.
+	//	|	if(dojo.byId("bar")){ ... }
+	//
+	//	example:
+	//	Allow string or DomNode references to be passed to a custom function:
+	//	| var foo = function(nodeOrId){ 
+	//	|	nodeOrId = dojo.byId(nodeOrId); 
+	//	|	// ... more stuff
+	//	| }
+=====*/
+
+if(dojo.isIE || dojo.isOpera){
+	dojo.byId = function(id, doc){
+		if(dojo.isString(id)){
+			var _d = doc || dojo.doc;
+			var te = _d.getElementById(id);
+			// attributes.id.value is better than just id in case the 
+			// user has a name=id inside a form
+			if(te && (te.attributes.id.value == id || te.id == id)){
+				return te;
+			}else{
+				var eles = _d.all[id];
+				if(!eles || eles.nodeName){
+					eles = [eles];
+				}
+				// if more than 1, choose first with the correct id
+				var i=0;
+				while((te=eles[i++])){
+					if((te.attributes && te.attributes.id && te.attributes.id.value == id)
+						|| te.id == id){
+						return te;
+					}
+				}
+			}
+		}else{
+			return id; // DomNode
+		}
+	};
+}else{
+	dojo.byId = function(id, doc){
+		return dojo.isString(id) ? (doc || dojo.doc).getElementById(id) : id; // DomNode
+	};
+}
+/*=====
+}
+=====*/
+
+(function(){
+	var d = dojo;
+
+	var _destroyContainer = null;
+		d.addOnWindowUnload(function(){
+		_destroyContainer = null; //prevent IE leak
+	});
+	
+/*=====
+	dojo._destroyElement = function(node){
+		// summary: Existing alias for `dojo.destroy`. Deprecated, will be removed in 2.0
+	}
+=====*/
+	dojo._destroyElement = dojo.destroy = function(/*String|DomNode*/node){
+		//	summary:
+		//		Removes a node from its parent, clobbering it and all of its
+		//		children.
+		//
+		//	description:
+		//		Removes a node from its parent, clobbering it and all of its
+		//		children. Function only works with DomNodes, and returns nothing.
+		//		
+		//	node:
+		//		A String ID or DomNode reference of the element to be destroyed
+		//
+		//	example:
+		//	Destroy a node byId:
+		//	| dojo.destroy("someId");
+		//
+		//	example:
+		//	Destroy all nodes in a list by reference:
+		//	| dojo.query(".someNode").forEach(dojo.destroy);
+		
+		node = d.byId(node);
+		try{
+			if(!_destroyContainer || _destroyContainer.ownerDocument != node.ownerDocument){
+				_destroyContainer = node.ownerDocument.createElement("div");
+			}
+			_destroyContainer.appendChild(node.parentNode ? node.parentNode.removeChild(node) : node);
+			// NOTE: see http://trac.dojotoolkit.org/ticket/2931. This may be a bug and not a feature
+			_destroyContainer.innerHTML = ""; 
+		}catch(e){
+			/* squelch */
+		}
+	};
+
+	dojo.isDescendant = function(/*DomNode|String*/node, /*DomNode|String*/ancestor){
+		//	summary:
+		//		Returns true if node is a descendant of ancestor
+		//	node: string id or node reference to test
+		//	ancestor: string id or node reference of potential parent to test against
+		try{
+			node = d.byId(node);
+			ancestor = d.byId(ancestor);
+			while(node){
+				if(node === ancestor){
+					return true; // Boolean
+				}
+				node = node.parentNode;
+			}
+		}catch(e){ /* squelch, return false */ }
+		return false; // Boolean
+	};
+
+	dojo.setSelectable = function(/*DomNode|String*/node, /*Boolean*/selectable){
+		//	summary: enable or disable selection on a node
+		//	node:
+		//		id or reference to node
+		//	selectable:
+		//		state to put the node in. false indicates unselectable, true 
+		//		allows selection.
+		node = d.byId(node);
+				if(d.isMozilla){
+			node.style.MozUserSelect = selectable ? "" : "none";
+		}else if(d.isKhtml || d.isWebKit){
+					node.style.KhtmlUserSelect = selectable ? "auto" : "none";
+				}else if(d.isIE){
+			var v = (node.unselectable = selectable ? "" : "on");
+			d.query("*", node).forEach("item.unselectable = '"+v+"'");
+		}
+				//FIXME: else?  Opera?
+	};
+
+	var _insertBefore = function(/*DomNode*/node, /*DomNode*/ref){
+		var parent = ref.parentNode;
+		if(parent){
+			parent.insertBefore(node, ref);
+		}
+	}
+
+	var _insertAfter = function(/*DomNode*/node, /*DomNode*/ref){
+		//	summary:
+		//		Try to insert node after ref
+		var parent = ref.parentNode;
+		if(parent){
+			if(parent.lastChild == ref){
+				parent.appendChild(node);
+			}else{
+				parent.insertBefore(node, ref.nextSibling);
+			}
+		}
+	}
+
+	dojo.place = function(node, refNode, position){
+		//	summary:
+		//		Attempt to insert node into the DOM, choosing from various positioning options.
+		//		Returns true if successful, false otherwise.
+		//
+		//	node: String|DomNode
+		//		id or node reference, or HTML fragment starting with "<" to place relative to refNode
+		//
+		//	refNode: String|DomNode
+		//		id or node reference to use as basis for placement
+		//
+		//	position: String|Number?
+		//		string noting the position of node relative to refNode or a
+		//		number indicating the location in the childNodes collection of refNode. 
+		//		Accepted string values are:
+		//	|	* before
+		//	|	* after
+		//	|	* replace
+		//	|	* only
+		//	|	* first
+		//	|	* last
+		//		"first" and "last" indicate positions as children of refNode, "replace" replaces refNode,
+		//		"only" replaces all children.  position defaults to "last" if not specified
+		//
+		//	returns: DomNode
+		//		Returned values is the first argument resolved to a DOM node.
+		//
+		//		.place() is also a method of `dojo.NodeList`, allowing `dojo.query` node lookups.
+		// 
+		// example:
+		// Place a node by string id as the last child of another node by string id:
+		// | 	dojo.place("someNode", "anotherNode");
+		//
+		// example:
+		// Place a node by string id before another node by string id
+		// | 	dojo.place("someNode", "anotherNode", "before");
+		//
+		// example:
+		// Create a Node, and place it in the body element (last child):
+		// | 	dojo.place(dojo.create('div'), dojo.body());
+		//
+		// example:
+		// Put a new LI as the first child of a list by id:
+		// | 	dojo.place(dojo.create('li'), "someUl", "first");
+
+		refNode = d.byId(refNode);
+		if(d.isString(node)){
+			node = node.charAt(0) == "<" ? d._toDom(node, refNode.ownerDocument) : d.byId(node);
+		}
+		if(typeof position == "number"){
+			var cn = refNode.childNodes;
+			if(!cn.length || cn.length <= position){
+				refNode.appendChild(node);
+			}else{
+				_insertBefore(node, cn[position < 0 ? 0 : position]);
+			}
+		}else{
+			switch(position){
+				case "before":
+					_insertBefore(node, refNode);
+					break;
+				case "after":
+					_insertAfter(node, refNode);
+					break;
+				case "replace":
+					refNode.parentNode.replaceChild(node, refNode);
+					break; 
+				case "only":
+					d.empty(refNode);
+					refNode.appendChild(node);
+					break;
+				case "first":
+					if(refNode.firstChild){
+						_insertBefore(node, refNode.firstChild);
+						break;
+					}
+					// else fallthrough...
+				default: // aka: last
+					refNode.appendChild(node);
+			}
+		}
+		return node; // DomNode
+	}
+
+	// Box functions will assume this model.
+	// On IE/Opera, BORDER_BOX will be set if the primary document is in quirks mode.
+	// Can be set to change behavior of box setters.
+	
+	// can be either:
+	//	"border-box"
+	//	"content-box" (default)
+	dojo.boxModel = "content-box";
+	
+	// We punt per-node box mode testing completely.
+	// If anybody cares, we can provide an additional (optional) unit 
+	// that overrides existing code to include per-node box sensitivity.
+
+	// Opera documentation claims that Opera 9 uses border-box in BackCompat mode.
+	// but experiments (Opera 9.10.8679 on Windows Vista) indicate that it actually continues to use content-box.
+	// IIRC, earlier versions of Opera did in fact use border-box.
+	// Opera guys, this is really confusing. Opera being broken in quirks mode is not our fault.
+
+		if(d.isIE /*|| dojo.isOpera*/){
+		var _dcm = document.compatMode;
+		// client code may have to adjust if compatMode varies across iframes
+		d.boxModel = _dcm == "BackCompat" || _dcm == "QuirksMode" || d.isIE < 6 ? "border-box" : "content-box"; // FIXME: remove IE < 6 support?
+	}
+	
+	// =============================
+	// Style Functions
+	// =============================
+	
+	// getComputedStyle drives most of the style code.
+	// Wherever possible, reuse the returned object.
+	//
+	// API functions below that need to access computed styles accept an 
+	// optional computedStyle parameter.
+	// If this parameter is omitted, the functions will call getComputedStyle themselves.
+	// This way, calling code can access computedStyle once, and then pass the reference to 
+	// multiple API functions. 
+
+/*=====
+	dojo.getComputedStyle = function(node){
+		//	summary:
+		//		Returns a "computed style" object.
+		//
+		//	description:
+		//		Gets a "computed style" object which can be used to gather
+		//		information about the current state of the rendered node. 
+		//
+		//		Note that this may behave differently on different browsers.
+		//		Values may have different formats and value encodings across
+		//		browsers.
+		//
+		//		Note also that this method is expensive.  Wherever possible,
+		//		reuse the returned object.
+		//
+		//		Use the dojo.style() method for more consistent (pixelized)
+		//		return values.
+		//
+		//	node: DOMNode
+		//		A reference to a DOM node. Does NOT support taking an
+		//		ID string for speed reasons.
+		//	example:
+		//	|	dojo.getComputedStyle(dojo.byId('foo')).borderWidth;
+		//
+		//	example:
+		//	Reusing the returned object, avoiding multiple lookups:
+		//	|	var cs = dojo.getComputedStyle(dojo.byId("someNode"));
+		//	|	var w = cs.width, h = cs.height;
+		return; // CSS2Properties
+	}
+=====*/
+
+	// Although we normally eschew argument validation at this
+	// level, here we test argument 'node' for (duck)type,
+	// by testing nodeType, ecause 'document' is the 'parentNode' of 'body'
+	// it is frequently sent to this function even 
+	// though it is not Element.
+	var gcs;
+		if(d.isWebKit){
+			gcs = function(/*DomNode*/node){
+			var s;
+			if(node.nodeType == 1){
+				var dv = node.ownerDocument.defaultView;
+				s = dv.getComputedStyle(node, null);
+				if(!s && node.style){ 
+					node.style.display = ""; 
+					s = dv.getComputedStyle(node, null);
+				}
+			}
+			return s || {};
+		}; 
+		}else if(d.isIE){
+		gcs = function(node){
+			// IE (as of 7) doesn't expose Element like sane browsers
+			return node.nodeType == 1 /* ELEMENT_NODE*/ ? node.currentStyle : {};
+		};
+	}else{
+		gcs = function(node){
+			return node.nodeType == 1 ? 
+				node.ownerDocument.defaultView.getComputedStyle(node, null) : {};
+		};
+	}
+		dojo.getComputedStyle = gcs;
+
+		if(!d.isIE){
+			d._toPixelValue = function(element, value){
+			// style values can be floats, client code may want
+			// to round for integer pixels.
+			return parseFloat(value) || 0; 
+		};
+		}else{
+		d._toPixelValue = function(element, avalue){
+			if(!avalue){ return 0; }
+			// on IE7, medium is usually 4 pixels
+			if(avalue == "medium"){ return 4; }
+			// style values can be floats, client code may
+			// want to round this value for integer pixels.
+			if(avalue.slice && avalue.slice(-2) == 'px'){ return parseFloat(avalue); }
+			with(element){
+				var sLeft = style.left;
+				var rsLeft = runtimeStyle.left;
+				runtimeStyle.left = currentStyle.left;
+				try{
+					// 'avalue' may be incompatible with style.left, which can cause IE to throw
+					// this has been observed for border widths using "thin", "medium", "thick" constants
+					// those particular constants could be trapped by a lookup
+					// but perhaps there are more
+					style.left = avalue;
+					avalue = style.pixelLeft;
+				}catch(e){
+					avalue = 0;
+				}
+				style.left = sLeft;
+				runtimeStyle.left = rsLeft;
+			}
+			return avalue;
+		}
+	}
+		var px = d._toPixelValue;
+
+	// FIXME: there opacity quirks on FF that we haven't ported over. Hrm.
+	/*=====
+	dojo._getOpacity = function(node){
+			//	summary:
+			//		Returns the current opacity of the passed node as a
+			//		floating-point value between 0 and 1.
+			//	node: DomNode
+			//		a reference to a DOM node. Does NOT support taking an
+			//		ID string for speed reasons.
+			//	returns: Number between 0 and 1
+			return; // Number
+	}
+	=====*/
+
+		var astr = "DXImageTransform.Microsoft.Alpha";
+	var af = function(n, f){ 
+		try{
+			return n.filters.item(astr);
+		}catch(e){
+			return f ? {} : null;
+		}
+	}
+
+		dojo._getOpacity = 
+			d.isIE ? function(node){
+			try{
+				return af(node).Opacity / 100; // Number
+			}catch(e){
+				return 1; // Number
+			}
+		} : 
+			function(node){
+			return gcs(node).opacity;
+		};
+
+	/*=====
+	dojo._setOpacity = function(node, opacity){
+			//	summary:
+			//		set the opacity of the passed node portably. Returns the
+			//		new opacity of the node.
+			//	node: DOMNode
+			//		a reference to a DOM node. Does NOT support taking an
+			//		ID string for performance reasons.
+			//	opacity: Number
+			//		A Number between 0 and 1. 0 specifies transparent.
+			//	returns: Number between 0 and 1
+			return; // Number
+	}
+	=====*/
+
+	dojo._setOpacity = 
+				d.isIE ? function(/*DomNode*/node, /*Number*/opacity){
+			var ov = opacity * 100;
+			node.style.zoom = 1.0;
+
+			// on IE7 Alpha(Filter opacity=100) makes text look fuzzy so disable it altogether (bug #2661),
+			//but still update the opacity value so we can get a correct reading if it is read later.
+			af(node, 1).Enabled = !(opacity == 1);
+
+			if(!af(node)){
+				node.style.filter += " progid:" + astr + "(Opacity=" + ov + ")";
+			}else{
+				af(node, 1).Opacity = ov;
+			}
+
+			if(node.nodeName.toLowerCase() == "tr"){
+				d.query("> td", node).forEach(function(i){
+					d._setOpacity(i, opacity);
+				});
+			}
+			return opacity;
+		} : 
+				function(node, opacity){
+			return node.style.opacity = opacity;
+		};
+
+	var _pixelNamesCache = {
+		left: true, top: true
+	};
+	var _pixelRegExp = /margin|padding|width|height|max|min|offset/;  // |border
+	var _toStyleValue = function(node, type, value){
+		type = type.toLowerCase(); // FIXME: should we really be doing string case conversion here? Should we cache it? Need to profile!
+				if(d.isIE){
+			if(value == "auto"){
+				if(type == "height"){ return node.offsetHeight; }
+				if(type == "width"){ return node.offsetWidth; }
+			}
+			if(type == "fontweight"){
+				switch(value){
+					case 700: return "bold";
+					case 400:
+					default: return "normal";
+				}
+			}
+		}
+				if(!(type in _pixelNamesCache)){
+			_pixelNamesCache[type] = _pixelRegExp.test(type);
+		}
+		return _pixelNamesCache[type] ? px(node, value) : value;
+	}
+
+	var _floatStyle = d.isIE ? "styleFloat" : "cssFloat",
+		_floatAliases = { "cssFloat": _floatStyle, "styleFloat": _floatStyle, "float": _floatStyle }
+	;
+	
+	// public API
+	
+	dojo.style = function(	/*DomNode|String*/ node, 
+							/*String?|Object?*/ style, 
+							/*String?*/ value){
+		//	summary:
+		//		Accesses styles on a node. If 2 arguments are
+		//		passed, acts as a getter. If 3 arguments are passed, acts
+		//		as a setter.
+		//	description:
+		//		Getting the style value uses the computed style for the node, so the value
+		//		will be a calculated value, not just the immediate node.style value.
+		//		Also when getting values, use specific style names,
+		//		like "borderBottomWidth" instead of "border" since compound values like
+		//		"border" are not necessarily reflected as expected.
+		//		If you want to get node dimensions, use dojo.marginBox() or
+		//		dojo.contentBox(). 
+		//	node:
+		//		id or reference to node to get/set style for
+		//	style:
+		//		the style property to set in DOM-accessor format
+		//		("borderWidth", not "border-width") or an object with key/value
+		//		pairs suitable for setting each property.
+		//	value:
+		//		If passed, sets value on the node for style, handling
+		//		cross-browser concerns.  When setting a pixel value,
+		//		be sure to include "px" in the value. For instance, top: "200px".
+		//		Otherwise, in some cases, some browsers will not apply the style.
+		//	example:
+		//		Passing only an ID or node returns the computed style object of
+		//		the node:
+		//	|	dojo.style("thinger");
+		//	example:
+		//		Passing a node and a style property returns the current
+		//		normalized, computed value for that property:
+		//	|	dojo.style("thinger", "opacity"); // 1 by default
+		//
+		//	example:
+		//		Passing a node, a style property, and a value changes the
+		//		current display of the node and returns the new computed value
+		//	|	dojo.style("thinger", "opacity", 0.5); // == 0.5
+		//
+		//	example:
+		//		Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node:
+		//	|	dojo.style("thinger", {
+		//	|		"opacity": 0.5,
+		//	|		"border": "3px solid black",
+		//	|		"height": "300px"
+		//	|	});
+		//
+		// 	example:
+		//		When the CSS style property is hyphenated, the JavaScript property is camelCased.
+		//		font-size becomes fontSize, and so on.
+		//	|	dojo.style("thinger",{
+		//	|		fontSize:"14pt",
+		//	|		letterSpacing:"1.2em"
+		//	|	});
+		//
+		//	example:
+		//		dojo.NodeList implements .style() using the same syntax, omitting the "node" parameter, calling
+		//		dojo.style() on every element of the list. See: dojo.query and dojo.NodeList
+		//	|	dojo.query(".someClassName").style("visibility","hidden");
+		//	|	// or
+		//	|	dojo.query("#baz > div").style({
+		//	|		opacity:0.75,
+		//	|		fontSize:"13pt"
+		//	|	});
+
+		var n = d.byId(node), args = arguments.length, op = (style == "opacity");
+		style = _floatAliases[style] || style;
+		if(args == 3){
+			return op ? d._setOpacity(n, value) : n.style[style] = value; /*Number*/
+		}
+		if(args == 2 && op){
+			return d._getOpacity(n);
+		}
+		var s = gcs(n);
+		if(args == 2 && !d.isString(style)){
+			for(var x in style){
+				d.style(node, x, style[x]);
+			}
+			return s;
+		}
+		return (args == 1) ? s : _toStyleValue(n, style, s[style] || n.style[style]); /* CSS2Properties||String||Number */
+	}
+
+	// =============================
+	// Box Functions
+	// =============================
+
+	dojo._getPadExtents = function(/*DomNode*/n, /*Object*/computedStyle){
+		//	summary:
+		// 		Returns object with special values specifically useful for node
+		// 		fitting.
+		//
+		// 		* l/t = left/top padding (respectively)
+		// 		* w = the total of the left and right padding 
+		// 		* h = the total of the top and bottom padding
+		//
+		//		If 'node' has position, l/t forms the origin for child nodes. 
+		//		The w/h are used for calculating boxes.
+		//		Normally application code will not need to invoke this
+		//		directly, and will use the ...box... functions instead.
+		var 
+			s = computedStyle||gcs(n), 
+			l = px(n, s.paddingLeft), 
+			t = px(n, s.paddingTop);
+		return { 
+			l: l,
+			t: t,
+			w: l+px(n, s.paddingRight),
+			h: t+px(n, s.paddingBottom)
+		};
+	}
+
+	dojo._getBorderExtents = function(/*DomNode*/n, /*Object*/computedStyle){
+		//	summary:
+		//		returns an object with properties useful for noting the border
+		//		dimensions.
+		//
+		// 		* l/t = the sum of left/top border (respectively)
+		//		* w = the sum of the left and right border
+		//		* h = the sum of the top and bottom border
+		//
+		//		The w/h are used for calculating boxes.
+		//		Normally application code will not need to invoke this
+		//		directly, and will use the ...box... functions instead.
+		var 
+			ne = "none",
+			s = computedStyle||gcs(n), 
+			bl = (s.borderLeftStyle != ne ? px(n, s.borderLeftWidth) : 0),
+			bt = (s.borderTopStyle != ne ? px(n, s.borderTopWidth) : 0);
+		return { 
+			l: bl,
+			t: bt,
+			w: bl + (s.borderRightStyle!=ne ? px(n, s.borderRightWidth) : 0),
+			h: bt + (s.borderBottomStyle!=ne ? px(n, s.borderBottomWidth) : 0)
+		};
+	}
+
+	dojo._getPadBorderExtents = function(/*DomNode*/n, /*Object*/computedStyle){
+		//	summary:
+		//		Returns object with properties useful for box fitting with
+		//		regards to padding.
+		//
+		//		* l/t = the sum of left/top padding and left/top border (respectively)
+		//		* w = the sum of the left and right padding and border
+		//		* h = the sum of the top and bottom padding and border
+		//
+		//		The w/h are used for calculating boxes.
+		//		Normally application code will not need to invoke this
+		//		directly, and will use the ...box... functions instead.
+		var 
+			s = computedStyle||gcs(n), 
+			p = d._getPadExtents(n, s),
+			b = d._getBorderExtents(n, s);
+		return { 
+			l: p.l + b.l,
+			t: p.t + b.t,
+			w: p.w + b.w,
+			h: p.h + b.h
+		};
+	}
+
+	dojo._getMarginExtents = function(n, computedStyle){
+		//	summary:
+		//		returns object with properties useful for box fitting with
+		//		regards to box margins (i.e., the outer-box).
+		//
+		//		* l/t = marginLeft, marginTop, respectively
+		//		* w = total width, margin inclusive
+		//		* h = total height, margin inclusive
+		//
+		//		The w/h are used for calculating boxes.
+		//		Normally application code will not need to invoke this
+		//		directly, and will use the ...box... functions instead.
+		var 
+			s = computedStyle||gcs(n), 
+			l = px(n, s.marginLeft),
+			t = px(n, s.marginTop),
+			r = px(n, s.marginRight),
+			b = px(n, s.marginBottom);
+		if(d.isWebKit && (s.position != "absolute")){
+			// FIXME: Safari's version of the computed right margin
+			// is the space between our right edge and the right edge 
+			// of our offsetParent. 
+			// What we are looking for is the actual margin value as 
+			// determined by CSS.
+			// Hack solution is to assume left/right margins are the same.
+			r = l;
+		}
+		return { 
+			l: l,
+			t: t,
+			w: l+r,
+			h: t+b
+		};
+	}
+
+	// Box getters work in any box context because offsetWidth/clientWidth
+	// are invariant wrt box context
+	//
+	// They do *not* work for display: inline objects that have padding styles
+	// because the user agent ignores padding (it's bogus styling in any case)
+	//
+	// Be careful with IMGs because they are inline or block depending on 
+	// browser and browser mode.
+
+	// Although it would be easier to read, there are not separate versions of 
+	// _getMarginBox for each browser because:
+	// 1. the branching is not expensive
+	// 2. factoring the shared code wastes cycles (function call overhead)
+	// 3. duplicating the shared code wastes bytes
+	
+	dojo._getMarginBox = function(/*DomNode*/node, /*Object*/computedStyle){
+		// summary:
+		//		returns an object that encodes the width, height, left and top
+		//		positions of the node's margin box.
+		var s = computedStyle || gcs(node), me = d._getMarginExtents(node, s);
+		var l = node.offsetLeft - me.l, t = node.offsetTop - me.t, p = node.parentNode;
+				if(d.isMoz){
+			// Mozilla:
+			// If offsetParent has a computed overflow != visible, the offsetLeft is decreased
+			// by the parent's border.
+			// We don't want to compute the parent's style, so instead we examine node's
+			// computed left/top which is more stable.
+			var sl = parseFloat(s.left), st = parseFloat(s.top);
+			if(!isNaN(sl) && !isNaN(st)){
+				l = sl, t = st;
+			}else{
+				// If child's computed left/top are not parseable as a number (e.g. "auto"), we
+				// have no choice but to examine the parent's computed style.
+				if(p && p.style){
+					var pcs = gcs(p);
+					if(pcs.overflow != "visible"){
+						var be = d._getBorderExtents(p, pcs);
+						l += be.l, t += be.t;
+					}
+				}
+			}
+		}else if(d.isOpera || (d.isIE > 7 && !d.isQuirks)){
+			// On Opera and IE 8, offsetLeft/Top includes the parent's border
+			if(p){
+				be = d._getBorderExtents(p);
+				l -= be.l;
+				t -= be.t;
+			}
+		}
+				return { 
+			l: l, 
+			t: t, 
+			w: node.offsetWidth + me.w, 
+			h: node.offsetHeight + me.h 
+		};
+	}
+	
+	dojo._getContentBox = function(node, computedStyle){
+		// summary:
+		//		Returns an object that encodes the width, height, left and top
+		//		positions of the node's content box, irrespective of the
+		//		current box model.
+
+		// clientWidth/Height are important since the automatically account for scrollbars
+		// fallback to offsetWidth/Height for special cases (see #3378)
+		var s = computedStyle || gcs(node),
+			pe = d._getPadExtents(node, s),
+			be = d._getBorderExtents(node, s),
+			w = node.clientWidth, 
+			h
+		;
+		if(!w){
+			w = node.offsetWidth, h = node.offsetHeight;
+		}else{
+			h = node.clientHeight, be.w = be.h = 0; 
+		}
+		// On Opera, offsetLeft includes the parent's border
+				if(d.isOpera){ pe.l += be.l; pe.t += be.t; };
+				return { 
+			l: pe.l, 
+			t: pe.t, 
+			w: w - pe.w - be.w, 
+			h: h - pe.h - be.h
+		};
+	}
+
+	dojo._getBorderBox = function(node, computedStyle){
+		var s = computedStyle || gcs(node), 
+			pe = d._getPadExtents(node, s),
+			cb = d._getContentBox(node, s)
+		;
+		return { 
+			l: cb.l - pe.l, 
+			t: cb.t - pe.t, 
+			w: cb.w + pe.w, 
+			h: cb.h + pe.h
+		};
+	}
+
+	// Box setters depend on box context because interpretation of width/height styles
+	// vary wrt box context.
+	//
+	// The value of dojo.boxModel is used to determine box context.
+	// dojo.boxModel can be set directly to change behavior.
+	//
+	// Beware of display: inline objects that have padding styles
+	// because the user agent ignores padding (it's a bogus setup anyway)
+	//
+	// Be careful with IMGs because they are inline or block depending on 
+	// browser and browser mode.
+	// 
+	// Elements other than DIV may have special quirks, like built-in
+	// margins or padding, or values not detectable via computedStyle.
+	// In particular, margins on TABLE do not seems to appear 
+	// at all in computedStyle on Mozilla.
+	
+	dojo._setBox = function(/*DomNode*/node, /*Number?*/l, /*Number?*/t, /*Number?*/w, /*Number?*/h, /*String?*/u){
+		//	summary:
+		//		sets width/height/left/top in the current (native) box-model
+		//		dimentions. Uses the unit passed in u.
+		//	node: DOM Node reference. Id string not supported for performance reasons.
+		//	l: optional. left offset from parent.
+		//	t: optional. top offset from parent.
+		//	w: optional. width in current box model.
+		//	h: optional. width in current box model.
+		//	u: optional. unit measure to use for other measures. Defaults to "px".
+		u = u || "px";
+		var s = node.style;
+		if(!isNaN(l)){ s.left = l + u; }
+		if(!isNaN(t)){ s.top = t + u; }
+		if(w >= 0){ s.width = w + u; }
+		if(h >= 0){ s.height = h + u; }
+	}
+
+	dojo._isButtonTag = function(/*DomNode*/node) {
+		// summary:
+		//		True if the node is BUTTON or INPUT.type="button".
+		return node.tagName == "BUTTON" 
+			|| node.tagName=="INPUT" && node.getAttribute("type").toUpperCase() == "BUTTON"; // boolean
+	}
+	
+	dojo._usesBorderBox = function(/*DomNode*/node){
+		//	summary: 
+		//		True if the node uses border-box layout.
+
+		// We could test the computed style of node to see if a particular box
+		// has been specified, but there are details and we choose not to bother.
+		
+		// TABLE and BUTTON (and INPUT type=button) are always border-box by default.
+		// If you have assigned a different box to either one via CSS then
+		// box functions will break.
+		
+		var n = node.tagName;
+		return d.boxModel=="border-box" || n=="TABLE" || d._isButtonTag(node); // boolean
+	}
+
+	dojo._setContentSize = function(/*DomNode*/node, /*Number*/widthPx, /*Number*/heightPx, /*Object*/computedStyle){
+		//	summary:
+		//		Sets the size of the node's contents, irrespective of margins,
+		//		padding, or borders.
+		if(d._usesBorderBox(node)){
+			var pb = d._getPadBorderExtents(node, computedStyle);
+			if(widthPx >= 0){ widthPx += pb.w; }
+			if(heightPx >= 0){ heightPx += pb.h; }
+		}
+		d._setBox(node, NaN, NaN, widthPx, heightPx);
+	}
+
+	dojo._setMarginBox = function(/*DomNode*/node, 	/*Number?*/leftPx, /*Number?*/topPx, 
+													/*Number?*/widthPx, /*Number?*/heightPx, 
+													/*Object*/computedStyle){
+		//	summary:
+		//		sets the size of the node's margin box and placement
+		//		(left/top), irrespective of box model. Think of it as a
+		//		passthrough to dojo._setBox that handles box-model vagaries for
+		//		you.
+
+		var s = computedStyle || gcs(node),
+		// Some elements have special padding, margin, and box-model settings. 
+		// To use box functions you may need to set padding, margin explicitly.
+		// Controlling box-model is harder, in a pinch you might set dojo.boxModel.
+			bb = d._usesBorderBox(node),
+			pb = bb ? _nilExtents : d._getPadBorderExtents(node, s)
+		;
+		if(d.isWebKit){
+			// on Safari (3.1.2), button nodes with no explicit size have a default margin
+			// setting an explicit size eliminates the margin.
+			// We have to swizzle the width to get correct margin reading.
+			if(d._isButtonTag(node)){
+				var ns = node.style;
+				if(widthPx >= 0 && !ns.width) { ns.width = "4px"; }
+				if(heightPx >= 0 && !ns.height) { ns.height = "4px"; }
+			}
+		}
+		var mb = d._getMarginExtents(node, s);
+		if(widthPx >= 0){ widthPx = Math.max(widthPx - pb.w - mb.w, 0); }
+		if(heightPx >= 0){ heightPx = Math.max(heightPx - pb.h - mb.h, 0); }
+		d._setBox(node, leftPx, topPx, widthPx, heightPx);
+	}
+	
+	var _nilExtents = { l:0, t:0, w:0, h:0 };
+
+	// public API
+	
+	dojo.marginBox = function(/*DomNode|String*/node, /*Object?*/box){
+		//	summary:
+		//		Getter/setter for the margin-box of node.
+		//	description: 
+		//		Returns an object in the expected format of box (regardless
+		//		if box is passed). The object might look like:
+		//			`{ l: 50, t: 200, w: 300: h: 150 }`
+		//		for a node offset from its parent 50px to the left, 200px from
+		//		the top with a margin width of 300px and a margin-height of
+		//		150px.
+		//	node:
+		//		id or reference to DOM Node to get/set box for
+		//	box:
+		//		If passed, denotes that dojo.marginBox() should
+		//		update/set the margin box for node. Box is an object in the
+		//		above format. All properties are optional if passed.
+		var n = d.byId(node), s = gcs(n), b = box;
+		return !b ? d._getMarginBox(n, s) : d._setMarginBox(n, b.l, b.t, b.w, b.h, s); // Object
+	}
+
+	dojo.contentBox = function(/*DomNode|String*/node, /*Object?*/box){
+		//	summary:
+		//		Getter/setter for the content-box of node.
+		//	description:
+		//		Returns an object in the expected format of box (regardless if box is passed).
+		//		The object might look like:
+		//			`{ l: 50, t: 200, w: 300: h: 150 }`
+		//		for a node offset from its parent 50px to the left, 200px from
+		//		the top with a content width of 300px and a content-height of
+		//		150px. Note that the content box may have a much larger border
+		//		or margin box, depending on the box model currently in use and
+		//		CSS values set/inherited for node.
+		//	node:
+		//		id or reference to DOM Node to get/set box for
+		//	box:
+		//		If passed, denotes that dojo.contentBox() should
+		//		update/set the content box for node. Box is an object in the
+		//		above format. All properties are optional if passed.
+		var n = d.byId(node), s = gcs(n), b = box;
+		return !b ? d._getContentBox(n, s) : d._setContentSize(n, b.w, b.h, s); // Object
+	}
+	
+	// =============================
+	// Positioning 
+	// =============================
+	
+	var _sumAncestorProperties = function(node, prop){
+		if(!(node = (node||0).parentNode)){return 0}
+		var val, retVal = 0, _b = d.body();
+		while(node && node.style){
+			if(gcs(node).position == "fixed"){
+				return 0;
+			}
+			val = node[prop];
+			if(val){
+				retVal += val - 0;
+				// opera and khtml #body & #html has the same values, we only
+				// need one value
+				if(node == _b){ break; }
+			}
+			node = node.parentNode;
+		}
+		return retVal;	//	integer
+	}
+
+	dojo._docScroll = function(){
+		var 
+			_b = d.body(),
+			_w = d.global,
+			de = d.doc.documentElement;
+		return {
+			y: (_w.pageYOffset || de.scrollTop || _b.scrollTop || 0),
+			x: (_w.pageXOffset || d._fixIeBiDiScrollLeft(de.scrollLeft) || _b.scrollLeft || 0)
+		};
+	};
+	
+	dojo._isBodyLtr = function(){
+		//FIXME: could check html and body tags directly instead of computed style?  need to ignore case, accept empty values
+		return ("_bodyLtr" in d) ? d._bodyLtr :
+			d._bodyLtr = gcs(d.body()).direction == "ltr"; // Boolean 
+	}
+	
+		dojo._getIeDocumentElementOffset = function(){
+		// summary
+		// The following values in IE contain an offset:
+		//     event.clientX
+		//     event.clientY
+		//     node.getBoundingClientRect().left
+		//     node.getBoundingClientRect().top
+		// But other position related values do not contain this offset, such as
+		// node.offsetLeft, node.offsetTop, node.style.left and node.style.top.
+		// The offset is always (2, 2) in LTR direction. When the body is in RTL
+		// direction, the offset counts the width of left scroll bar's width.
+		// This function computes the actual offset.
+
+		//NOTE: assumes we're being called in an IE browser
+
+		var de = d.doc.documentElement;
+		//FIXME: use this instead?			var de = d.compatMode == "BackCompat" ? d.body : d.documentElement;
+
+		if(d.isIE < 7){
+			return { x: d._isBodyLtr() || window.parent == window ?
+				de.clientLeft : de.offsetWidth - de.clientWidth - de.clientLeft, 
+				y: de.clientTop }; // Object
+		}else if(d.isIE < 8){
+			return {x: de.getBoundingClientRect().left, y: de.getBoundingClientRect().top};
+		}else{
+			return {
+				x: 0,
+				y: 0
+			};
+		}
+
+	};
+		
+	dojo._fixIeBiDiScrollLeft = function(/*Integer*/ scrollLeft){
+		// In RTL direction, scrollLeft should be a negative value, but IE < 8
+		// returns a positive one. All codes using documentElement.scrollLeft
+		// must call this function to fix this error, otherwise the position
+		// will offset to right when there is a horizontal scrollbar.
+
+				var dd = d.doc;
+		if(d.isIE < 8 && !d._isBodyLtr()){
+			var de = dd.compatMode == "BackCompat" ? dd.body : dd.documentElement;
+			return scrollLeft + de.clientWidth - de.scrollWidth; // Integer
+		}
+				return scrollLeft; // Integer
+	}
+
+	dojo._abs = function(/*DomNode*/node, /*Boolean?*/includeScroll){
+		//	summary:
+		//		Gets the position of the passed element relative to
+		//		the viewport (if includeScroll==false), or relative to the
+		//		document root (if includeScroll==true).
+		//
+		//		Returns an object of the form:
+		//			{ x: 100, y: 300 }
+		//		if includeScroll is passed, the x and y values will include any
+		//		document offsets that may affect the position relative to the
+		//		viewport.
+
+		// FIXME: need to decide in the brave-new-world if we're going to be
+		// margin-box or border-box.
+		
+		// targetBoxType == "border-box"
+		var db = d.body(), dh = d.body().parentNode, ret;
+		if(node["getBoundingClientRect"]){
+			// IE6+, FF3+, super-modern WebKit, and Opera 9.6+ all take this branch
+			var client = node.getBoundingClientRect();
+			ret = { x: client.left, y: client.top };
+					if(d.isFF >= 3){
+				// in FF3 you have to subtract the document element margins
+				var cs = gcs(dh);
+				ret.x -= px(dh, cs.marginLeft) + px(dh, cs.borderLeftWidth);
+				ret.y -= px(dh, cs.marginTop) + px(dh, cs.borderTopWidth);
+			}
+			if(d.isIE){
+				// On IE there's a 2px offset that we need to adjust for, see _getIeDocumentElementOffset()
+				var offset = d._getIeDocumentElementOffset();
+
+				// fixes the position in IE, quirks mode
+				ret.x -= offset.x + (d.isQuirks ? db.clientLeft : 0);
+				ret.y -= offset.y + (d.isQuirks ? db.clientTop : 0);
+			}
+				}else{
+			// FF2 and Safari
+			ret = {
+				x: 0,
+				y: 0
+			};
+			if(node["offsetParent"]){
+				ret.x -= _sumAncestorProperties(node, "scrollLeft");
+				ret.y -= _sumAncestorProperties(node, "scrollTop");
+				
+				var curnode = node;
+				do{
+					var n = curnode.offsetLeft,
+						t = curnode.offsetTop;
+					ret.x += isNaN(n) ? 0 : n;
+					ret.y += isNaN(t) ? 0 : t;
+
+					cs = gcs(curnode);
+					if(curnode != node){
+								if(d.isFF){
+							// tried left+right with differently sized left/right borders
+							// it really is 2xleft border in FF, not left+right, even in RTL!
+							ret.x += 2 * px(curnode,cs.borderLeftWidth);
+							ret.y += 2 * px(curnode,cs.borderTopWidth);
+						}else{
+									ret.x += px(curnode, cs.borderLeftWidth);
+							ret.y += px(curnode, cs.borderTopWidth);
+								}
+							}
+					// static children in a static div in FF2 are affected by the div's border as well
+					// but offsetParent will skip this div!
+							if(d.isFF && cs.position=="static"){
+						var parent=curnode.parentNode;
+						while(parent!=curnode.offsetParent){
+							var pcs=gcs(parent);
+							if(pcs.position=="static"){
+								ret.x += px(curnode,pcs.borderLeftWidth);
+								ret.y += px(curnode,pcs.borderTopWidth);
+							}
+							parent=parent.parentNode;
+						}
+					}
+							curnode = curnode.offsetParent;
+				}while((curnode != dh) && curnode);
+			}else if(node.x && node.y){
+				ret.x += isNaN(node.x) ? 0 : node.x;
+				ret.y += isNaN(node.y) ? 0 : node.y;
+			}
+		}
+		// account for document scrolling
+		// if offsetParent is used, ret value already includes scroll position
+		// so we may have to actually remove that value if !includeScroll
+		if(includeScroll){
+			var scroll = d._docScroll();
+			ret.x += scroll.x;
+			ret.y += scroll.y;
+		}
+
+		return ret; // Object
+	}
+
+	// FIXME: need a setter for coords or a moveTo!!
+	dojo.coords = function(/*DomNode|String*/node, /*Boolean?*/includeScroll){
+		//	summary:
+		//		Returns an object that measures margin box width/height and
+		//		absolute positioning data from dojo._abs().
+		//
+		//	description:
+		//		Returns an object that measures margin box width/height and
+		//		absolute positioning data from dojo._abs().
+		//		Return value will be in the form:
+		//			`{ l: 50, t: 200, w: 300: h: 150, x: 100, y: 300 }`
+		//		Does not act as a setter. If includeScroll is passed, the x and
+		//		y params are affected as one would expect in dojo._abs().
+		var n = d.byId(node), s = gcs(n), mb = d._getMarginBox(n, s);
+		var abs = d._abs(n, includeScroll);
+		mb.x = abs.x;
+		mb.y = abs.y;
+		return mb;
+	}
+
+	// =============================
+	// Element attribute Functions
+	// =============================
+
+		var ieLT8 = d.isIE < 8;
+	
+	var _fixAttrName = function(/*String*/name){
+		switch(name.toLowerCase()){
+			// Internet Explorer will only set or remove tabindex/readonly
+			// if it is spelled "tabIndex"/"readOnly"
+						case "tabindex":
+				return ieLT8 ? "tabIndex" : "tabindex";
+						case "readonly":
+				return "readOnly";
+			case "class":
+				return "className";
+						case "for": case "htmlfor":
+				// to pick up for attrib set in markup via getAttribute() IE<8 uses "htmlFor" and others use "for"
+				// get/setAttribute works in all as long use same value for both get/set
+				return ieLT8 ? "htmlFor" : "for";
+						default:
+				return name;
+		}
+	}
+
+	// non-deprecated HTML4 attributes with default values
+	// http://www.w3.org/TR/html401/index/attributes.html
+	// FF and Safari will return the default values if you
+	// access the attributes via a property but not
+	// via getAttribute()
+	var _attrProps = {
+		colspan: "colSpan",
+		enctype: "enctype",
+		frameborder: "frameborder",
+		method: "method",
+		rowspan: "rowSpan",
+		scrolling: "scrolling",
+		shape: "shape",
+		span: "span",
+		type: "type",
+		valuetype: "valueType",
+		// the following attributes don't have the default but should be treated like properties
+		classname: "className",
+		innerhtml: "innerHTML"
+	}
+
+	dojo.hasAttr = function(/*DomNode|String*/node, /*String*/name){
+		//	summary:
+		//		Returns true if the requested attribute is specified on the
+		//		given element, and false otherwise.
+		//	node:
+		//		id or reference to the element to check
+		//	name:
+		//		the name of the attribute
+		//	returns:
+		//		true if the requested attribute is specified on the
+		//		given element, and false otherwise
+		node = d.byId(node);
+		var fixName = _fixAttrName(name);
+		fixName = fixName == "htmlFor" ? "for" : fixName; //IE<8 uses htmlFor except in this case
+		var attr = node.getAttributeNode && node.getAttributeNode(fixName);
+		return attr ? attr.specified : false; // Boolean
+	}
+
+	var _evtHdlrMap = {}, _ctr = 0,
+		_attrId = dojo._scopeName + "attrid",
+		// the next dictionary lists elements with read-only innerHTML on IE
+		_roInnerHtml = {col: 1, colgroup: 1,
+			// frameset: 1, head: 1, html: 1, style: 1,
+			table: 1, tbody: 1, tfoot: 1, thead: 1, tr: 1, title: 1};
+
+	dojo.attr = function(/*DomNode|String*/node, /*String|Object*/name, /*String?*/value){
+		//	summary:
+		//		Gets or sets an attribute on an HTML element.
+		//	description:
+		//		Handles normalized getting and setting of attributes on DOM
+		//		Nodes. If 2 arguments are passed, and a the second argumnt is a
+		//		string, acts as a getter.
+		//	
+		//		If a third argument is passed, or if the second argumnt is a
+		//		map of attributes, acts as a setter.
+		//
+		//		When passing functions as values, note that they will not be
+		//		directly assigned to slots on the node, but rather the default
+		//		behavior will be removed and the new behavior will be added
+		//		using `dojo.connect()`, meaning that event handler properties
+		//		will be normalized and that some caveats with regards to
+		//		non-standard behaviors for onsubmit apply. Namely that you
+		//		should cancel form submission using `dojo.stopEvent()` on the
+		//		passed event object instead of returning a boolean value from
+		//		the handler itself.
+		//	node:
+		//		id or reference to the element to get or set the attribute on
+		//	name:
+		//		the name of the attribute to get or set.
+		//	value:
+		//		The value to set for the attribute
+		//	returns:
+		//		when used as a getter, the value of the requested attribute
+		//		or null if that attribute does not have a specified or
+		//		default value;
+		//
+		//		when used as a setter, undefined
+		//
+		//	example:
+		//	|	// get the current value of the "foo" attribute on a node
+		//	|	dojo.attr(dojo.byId("nodeId"), "foo");
+		//	|	// or we can just pass the id:
+		//	|	dojo.attr("nodeId", "foo");
+		//
+		//	example:
+		//	|	// use attr() to set the tab index
+		//	|	dojo.attr("nodeId", "tabindex", 3);
+		//	|
+		//
+		//	example:
+		//	Set multiple values at once, including event handlers:
+		//	|	dojo.attr("formId", {
+		//	|		"foo": "bar",
+		//	|		"tabindex": -1,
+		//	|		"method": "POST",
+		//	|		"onsubmit": function(e){
+		//	|			// stop submitting the form. Note that the IE behavior
+		//	|			// of returning true or false will have no effect here
+		//	|			// since our handler is connect()ed to the built-in
+		//	|			// onsubmit behavior and so we need to use
+		//	|			// dojo.stopEvent() to ensure that the submission
+		//	|			// doesn't proceed.
+		//	|			dojo.stopEvent(e);
+		//	|
+		//	|			// submit the form with Ajax
+		//	|			dojo.xhrPost({ form: "formId" });
+		//	|		}
+		//	|	});
+		//
+		//	example:
+		//	Style is s special case: Only set with an object hash of styles
+		//	|	dojo.attr("someNode",{
+		//	|		id:"bar",
+		//	|		style:{
+		//	|			width:"200px", height:"100px", color:"#000"
+		//	|		}
+		//	|	});
+		//
+		//	example:
+		//	Again, only set style as an object hash of styles:
+		//	|	var obj = { color:"#fff", backgroundColor:"#000" };
+		//	|	dojo.attr("someNode", "style", obj);
+		//	|
+		//	|	// though shorter to use `dojo.style` in this case:
+		//	|	dojo.style("someNode", obj);
+		
+		node = d.byId(node);
+		var args = arguments.length;
+		if(args == 2 && !d.isString(name)){
+			// the object form of setter: the 2nd argument is a dictionary
+			for(var x in name){ d.attr(node, x, name[x]); }
+			// FIXME: return the node in this case? could be useful.
+			return;
+		}
+		name = _fixAttrName(name);
+		if(args == 3){ // setter
+			if(d.isFunction(value)){
+				// clobber if we can
+				var attrId = d.attr(node, _attrId);
+				if(!attrId){
+					attrId = _ctr++;
+					d.attr(node, _attrId, attrId);
+				}
+				if(!_evtHdlrMap[attrId]){
+					_evtHdlrMap[attrId] = {};
+				}
+				var h = _evtHdlrMap[attrId][name];
+				if(h){
+					d.disconnect(h);
+				}else{
+					try{
+						delete node[name];
+					}catch(e){}
+				}
+
+				// ensure that event objects are normalized, etc.
+				_evtHdlrMap[attrId][name] = d.connect(node, name, value);
+
+			}else if(typeof value == "boolean"){ // e.g. onsubmit, disabled
+				node[name] = value;
+			}else if(name === "style" && !d.isString(value)){
+				// when the name is "style" and value is an object, pass along
+				d.style(node, value);
+			}else if(name == "className"){
+				node.className = value;
+			}else if(name === "innerHTML"){
+								if(d.isIE && node.tagName.toLowerCase() in _roInnerHtml){
+					d.empty(node);
+					node.appendChild(d._toDom(value, node.ownerDocument));
+				}else{
+									node[name] = value;
+								}
+							}else{
+				node.setAttribute(name, value);
+			}
+		}else{
+			// getter
+			// should we access this attribute via a property or
+			// via getAttribute()?
+			var prop = _attrProps[name.toLowerCase()];
+			if(prop){
+				return node[prop];
+			}
+			var attrValue = node[name];
+			return (typeof attrValue == 'boolean' || typeof attrValue == 'function') ? attrValue
+				: (d.hasAttr(node, name) ? node.getAttribute(name) : null);
+		}
+	}
+
+	dojo.removeAttr = function(/*DomNode|String*/node, /*String*/name){
+		//	summary:
+		//		Removes an attribute from an HTML element.
+		//	node:
+		//		id or reference to the element to remove the attribute from
+		//	name:
+		//		the name of the attribute to remove
+		d.byId(node).removeAttribute(_fixAttrName(name));
+	}
+	
+	dojo.create = function(tag, attrs, refNode, pos){
+		// summary: Create an element, allowing for optional attribute decoration
+		//		and placement. 
+		//
+		// description:
+		//		A DOM Element creation function. A shorthand method for creating a node or
+		//		a fragment, and allowing for a convenient optional attribute setting step, 
+		//		as well as an optional DOM placement reference.
+		//|
+		//		Attributes are set by passing the optional object through `dojo.attr`.
+		//		See `dojo.attr` for noted caveats and nuances, and API if applicable. 
+		//|
+		//		Placement is done via `dojo.place`, assuming the new node to be the action 
+		//		node, passing along the optional reference node and position. 
+		//
+		// tag: String|DomNode
+		//		A string of the element to create (eg: "div", "a", "p", "li", "script", "br"),
+		//		or an existing DOM node to process.
+		//
+		// attrs: Object
+		//		An object-hash of attributes to set on the newly created node.
+		//		Can be null, if you don't want to set any attributes/styles.
+		//		See: `dojo.attr` for a description of available attributes.
+		//
+		// refNode: String?|DomNode?
+		//		Optional reference node. Used by `dojo.place` to place the newly created
+		//		node somewhere in the dom relative to refNode. Can be a DomNode reference
+		//		or String ID of a node.
+		//	
+		// pos: String?
+		//		Optional positional reference. Defaults to "last" by way of `dojo.place`,
+		//		though can be set to "first","after","before","last", "replace" or "only"
+		//		to further control the placement of the new node relative to the refNode.
+		//		'refNode' is required if a 'pos' is specified.
+		//
+		// returns: DomNode
+		//
+		// example:
+		//	Create a DIV:
+		//	| var n = dojo.create("div");
+		//
+		// example:
+		//	Create a DIV with content:
+		//	| var n = dojo.create("div", { innerHTML:"<p>hi</p>" });
+		//
+		// example:
+		//	Place a new DIV in the BODY, with no attributes set
+		//	| var n = dojo.create("div", null, dojo.body());
+		//
+		// example:
+		//	Create an UL, and populate it with LI's. Place the list as the first-child of a 
+		//	node with id="someId":
+		//	| var ul = dojo.create("ul", null, "someId", "first"); 
+		//	| var items = ["one", "two", "three", "four"];
+		//	| dojo.forEach(items, function(data){
+		//	|	dojo.create("li", { innerHTML: data }, ul);
+		//	| });
+		//
+		// example:
+		//	Create an anchor, with an href. Place in BODY:
+		//	| dojo.create("a", { href:"foo.html", title:"Goto FOO!" }, dojo.body());
+		//
+		// example:
+		//	Create a `dojo.NodeList` from a new element (for syntatic sugar):
+		//	|	dojo.query(dojo.create('div'))
+		//	|		.addClass("newDiv")
+		//	|		.onclick(function(e){  })
+		//	|		.place("#someNode"); // redundant, but cleaner.
+
+		var doc = d.doc;
+		if(refNode){		
+			refNode = d.byId(refNode);
+			doc = refNode.ownerDocument;
+		}
+		if(d.isString(tag)){
+			tag = doc.createElement(tag);
+		}
+		if(attrs){ d.attr(tag, attrs); }
+		if(refNode){ d.place(tag, refNode, pos); }
+		return tag; // DomNode
+	}
+	
+	/*=====
+	dojo.empty = function(node){
+			//	summary:
+			//		safely removes all children of the node.
+			//	node: DOMNode|String
+			//		a reference to a DOM node or an id.
+			//	example:
+			//	Destroy node's children byId:
+			//	| dojo.empty("someId");
+			//
+			//	example:
+			//	Destroy all nodes' children in a list by reference:
+			//	| dojo.query(".someNode").forEach(dojo.empty);
+	}
+	=====*/
+
+	d.empty = 
+				d.isIE ?  function(node){
+			node = d.byId(node);
+			for(var c; c = node.lastChild;){ // intentional assignment
+				d.destroy(c);
+			}
+		} :
+				function(node){
+			d.byId(node).innerHTML = "";
+		};
+
+	/*=====
+	dojo._toDom = function(frag, doc){
+			//	summary:
+			//		instantiates an HTML fragment returning the corresponding DOM.
+			//	frag: String
+			//		the HTML fragment
+			//	doc: DocumentNode?
+			//		optional document to use when creating DOM nodes, defaults to
+			//		dojo.doc if not specified.
+			//	returns: DocumentFragment
+			//
+			//	example:
+			//	Create a table row:
+			//	| var tr = dojo._toDom("<tr><td>First!</td></tr>");
+	}
+	=====*/
+
+	// support stuff for dojo._toDom
+	var tagWrap = {
+			option: ["select"],
+			tbody: ["table"],
+			thead: ["table"],
+			tfoot: ["table"],
+			tr: ["table", "tbody"],
+			td: ["table", "tbody", "tr"],
+			th: ["table", "thead", "tr"],
+			legend: ["fieldset"],
+			caption: ["table"],
+			colgroup: ["table"],
+			col: ["table", "colgroup"],
+			li: ["ul"]
+		},
+		reTag = /<\s*([\w\:]+)/,
+		masterNode = {}, masterNum = 0,
+		masterName = "__" + d._scopeName + "ToDomId";
+
+	// generate start/end tag strings to use
+	// for the injection for each special tag wrap case.
+	for(var param in tagWrap){
+		var tw = tagWrap[param];
+		tw.pre  = param == "option" ? '<select multiple="multiple">' : "<" + tw.join("><") + ">";
+		tw.post = "</" + tw.reverse().join("></") + ">";
+		// the last line is destructive: it reverses the array,
+		// but we don't care at this point
+	}
+
+	d._toDom = function(frag, doc){
+		// summary converts HTML string into DOM nodes.
+
+		doc = doc || d.doc;
+		var masterId = doc[masterName];
+		if(!masterId){
+			doc[masterName] = masterId = ++masterNum + "";
+			masterNode[masterId] = doc.createElement("div");
+		}
+
+		// make sure the frag is a string.
+		frag += "";
+
+		// find the starting tag, and get node wrapper
+		var match = frag.match(reTag),
+			tag = match ? match[1].toLowerCase() : "",
+			master = masterNode[masterId],
+			wrap, i, fc, df;
+		if(match && tagWrap[tag]){
+			wrap = tagWrap[tag];
+			master.innerHTML = wrap.pre + frag + wrap.post;
+			for(i = wrap.length; i; --i){
+				master = master.firstChild;
+			}
+		}else{
+			master.innerHTML = frag;
+		}
+
+		// one node shortcut => return the node itself
+		if(master.childNodes.length == 1){
+			return master.removeChild(master.firstChild); // DOMNode
+		}
+		
+		// return multiple nodes as a document fragment
+		df = doc.createDocumentFragment();
+		while(fc = master.firstChild){ // intentional assignment
+			df.appendChild(fc);
+		}
+		return df; // DOMNode
+	}
+
+	// =============================
+	// (CSS) Class Functions
+	// =============================
+	var _className = "className";
+
+	dojo.hasClass = function(/*DomNode|String*/node, /*String*/classStr){
+		//	summary:
+		//		Returns whether or not the specified classes are a portion of the
+		//		class list currently applied to the node. 
+		//
+		//	node: 
+		//		String ID or DomNode reference to check the class for.
+		//
+		//	classStr:
+		//		A string class name to look for.
+		// 
+		//	example:
+		//	| if(dojo.hasClass("someNode","aSillyClassName")){ ... }
+		
+		return ((" "+ d.byId(node)[_className] +" ").indexOf(" "+ classStr +" ") >= 0);  // Boolean
+	};
+
+	dojo.addClass = function(/*DomNode|String*/node, /*String*/classStr){
+		//	summary:
+		//		Adds the specified classes to the end of the class list on the
+		//		passed node. Will not re-apply duplicate classes, except in edge
+		//		cases when adding multiple classes at once.
+		//
+		//	node: String ID or DomNode reference to add a class string too
+		//	classStr: A String class name to add
+		//
+		// example:
+		//	Add A class to some node:
+		//	|	dojo.addClass("someNode", "anewClass");
+		//
+		// example:
+		//	Add two classes at once (could potentially add duplicate):
+		//	| 	dojo.addClass("someNode", "firstClass secondClass");
+		//
+		// example:
+		//	Available in `dojo.NodeList` for multiple additions
+		//	| dojo.query("ul > li").addClass("firstLevel");
+		
+		node = d.byId(node);
+		var cls = node[_className];
+		if((" "+ cls +" ").indexOf(" " + classStr + " ") < 0){
+			node[_className] = cls + (cls ? ' ' : '') + classStr;
+		}
+	};
+
+	dojo.removeClass = function(/*DomNode|String*/node, /*String*/classStr){
+		// summary: Removes the specified classes from node. No `dojo.hasClass` 
+		//		check is required. 
+		//
+		// node: String ID or DomNode reference to remove the class from.
+		//
+		// classString: String class name to remove
+		//
+		// example:
+		// 	| dojo.removeClass("someNode", "firstClass");
+		//
+		// example:
+		//	Available in `dojo.NodeList` for multiple removal
+		//	| dojo.query(".foo").removeClass("foo");
+		
+		node = d.byId(node);
+		var t = d.trim((" " + node[_className] + " ").replace(" " + classStr + " ", " "));
+		if(node[_className] != t){ node[_className] = t; }
+	};
+
+	dojo.toggleClass = function(/*DomNode|String*/node, /*String*/classStr, /*Boolean?*/condition){
+		//	summary:
+		//		Adds a class to node if not present, or removes if present.
+		//		Pass a boolean condition if you want to explicitly add or remove.
+		//	condition:
+		//		If passed, true means to add the class, false means to remove.
+		//
+		// example:
+		//	| dojo.toggleClass("someNode", "hovered");
+		//
+		// example:
+		// 	Forcefully add a class
+		//	| dojo.toggleClass("someNode", "hovered", true);
+		//
+		// example:
+		//	Available in `dojo.NodeList` for multiple toggles
+		//	| dojo.query(".toggleMe").toggleClass("toggleMe");
+		
+		if(condition === undefined){
+			condition = !d.hasClass(node, classStr);
+		}
+		d[condition ? "addClass" : "removeClass"](node, classStr);
+	};
+
+})();
+
+}
+
+if(!dojo._hasResource["dojo._base.NodeList"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.NodeList"] = true;
+dojo.provide("dojo._base.NodeList");
+
+
+
+(function(){
+
+	var d = dojo;
+
+	var ap = Array.prototype, aps = ap.slice, apc = ap.concat;
+	
+	var tnl = function(a){
+		// decorate an array to make it look like a NodeList
+		a.constructor = d.NodeList;
+		dojo._mixin(a, d.NodeList.prototype);
+		return a;
+	};
+
+	var loopBody = function(f, a, o){
+		a = [0].concat(aps.call(a, 0));
+		if(!a.sort){
+			// make sure it's a real array before we pass it on to be wrapped
+			a = aps.call(a, 0);
+		}
+		o = o || d.global;
+		return function(node){
+			a[0] = node;
+			return f.apply(o, a);
+		};
+	};
+	
+	// adapters
+
+	var adaptAsForEach = function(f, o){
+		//	summary:
+		//		adapts a single node function to be used in the forEach-type
+		//		actions. The initial object is returned from the specialized
+		//		function.
+		//	f: Function
+		//		a function to adapt
+		//	o: Object?
+		//		an optional context for f
+		return function(){
+			this.forEach(loopBody(f, arguments, o));
+			return this;	// Object
+		};
+	};
+
+	var adaptAsMap = function(f, o){
+		//	summary:
+		//		adapts a single node function to be used in the map-type
+		//		actions. The return is a new array of values, as via `dojo.map`
+		//	f: Function
+		//		a function to adapt
+		//	o: Object?
+		//		an optional context for f
+		return function(){
+			return this.map(loopBody(f, arguments, o));
+		};
+	};
+	
+	var adaptAsFilter = function(f, o){
+		//	summary:
+		//		adapts a single node function to be used in the filter-type actions
+		//	f: Function
+		//		a function to adapt
+		//	o: Object?
+		//		an optional context for f
+		return function(){
+			return this.filter(loopBody(f, arguments, o));
+		};
+	};
+	
+	var adaptWithCondition = function(f, g, o){
+		//	summary: 
+		//		adapts a single node function to be used in the map-type
+		//		actions, behaves like forEach() or map() depending on arguments
+		//	f: Function
+		//		a function to adapt
+		//	g: Function
+		//		a condition function, if true runs as map(), otherwise runs as forEach()
+		//	o: Object?
+		//		an optional context for f and g
+		return function(){
+			var a = arguments, body = loopBody(f, a, o);
+			if(g.call(o || d.global, a)){
+				return this.map(body);	// self
+			}
+			this.forEach(body);
+			return this;	// self
+		};
+	};
+	
+	var magicGuard = function(a){
+		//	summary:
+		//		the guard function for dojo.attr() and dojo.style()
+		return a.length == 1 && d.isString(a[0])
+	};
+	
+	var orphan = function(node){
+		//	summary:
+		//		function to orphan nodes
+		var p = node.parentNode;
+		if(p){
+			p.removeChild(node);
+		}
+	};
+	// FIXME: should we move orphan() to dojo.html?
+
+	dojo.NodeList = function(){
+		//	summary:
+		//		dojo.NodeList is an of Array subclass which adds syntactic
+		//		sugar for chaining, common iteration operations, animation, and
+		//		node manipulation. NodeLists are most often returned as the
+		//		result of dojo.query() calls.
+		//	description:
+		//		dojo.NodeList instances provide many utilities that reflect
+		//		core Dojo APIs for Array iteration and manipulation, DOM
+		//		manipulation, and event handling. Instead of needing to dig up
+		//		functions in the dojo.* namespace, NodeLists generally make the
+		//		full power of Dojo available for DOM manipulation tasks in a
+		//		simple, chainable way.
+		//	example:
+		//		create a node list from a node
+		//		|	new dojo.NodeList(dojo.byId("foo"));
+		//	example:
+		//		get a NodeList from a CSS query and iterate on it
+		//		|	var l = dojo.query(".thinger");
+		//		|	l.forEach(function(node, index, nodeList){
+		//		|		
+		//		|	});
+		//	example:
+		//		use native and Dojo-provided array methods to manipulate a
+		//		NodeList without needing to use dojo.* functions explicitly:
+		//		|	var l = dojo.query(".thinger");
+		//		|	// since NodeLists are real arrays, they have a length
+		//		|	// property that is both readable and writable and
+		//		|	// push/pop/shift/unshift methods
+		//		|	
+		//		|	l.push(dojo.create("<span>howdy!</span>"));
+		//		|
+		//		|	// dojo's normalized array methods work too:
+		//		|	
+		//		|	// ...including the special "function as string" shorthand
+		//		|	
+		//		|
+		//		|	// NodeLists can be [..] indexed, or you can use the at()
+		//		|	// function to get specific items wrapped in a new NodeList:
+		//		|	var node = l[3]; // the 4th element
+		//		|	var newList = l.at(1, 3); // the 2nd and 4th elements
+		//	example:
+		//		the style functions you expect are all there too:
+		//		|	// style() as a getter...
+		//		|	var borders = dojo.query(".thinger").style("border");
+		//		|	// ...and as a setter:
+		//		|	dojo.query(".thinger").style("border", "1px solid black");
+		//		|	// class manipulation
+		//		|	dojo.query("li:nth-child(even)").addClass("even");
+		//		|	// even getting the coordinates of all the items
+		//		|	var coords = dojo.query(".thinger").coords();
+		//	example:
+		//		DOM manipulation functions from the dojo.* namespace area also
+		//		available:
+		//		|	// remove all of the elements in the list from their
+		//		|	// parents (akin to "deleting" them from the document)
+		//		|	dojo.query(".thinger").orphan();
+		//		|	// place all elements in the list at the front of #foo
+		//		|	dojo.query(".thinger").place("foo", "first");
+		//	example:
+		//		Event handling couldn't be easier. `dojo.connect` is mapped in,
+		//		and shortcut handlers are provided for most DOM events:
+		//		|	// like dojo.connect(), but with implicit scope
+		//		|	dojo.query("li").connect("onclick", console, "log");
+		//		|
+		//		|	// many common event handlers are already available directly:
+		//		|	dojo.query("li").onclick(console, "log");
+		//		|	var toggleHovered = dojo.hitch(dojo, "toggleClass", "hovered");
+		//		|	dojo.query("p")
+		//		|		.onmouseenter(toggleHovered)
+		//		|		.onmouseleave(toggleHovered);
+		//	example:
+		//		chainability is a key advantage of NodeLists:
+		//		|	dojo.query(".thinger")
+		//		|		.onclick(function(e){ /* ... */ })
+		//		|		.at(1, 3, 8) // get a subset
+		//		|			.style("padding", "5px")
+		//		|			.forEach(console.log);
+
+		return tnl(Array.apply(null, arguments));
+	};
+
+	var nl = d.NodeList, nlp = nl.prototype;
+	
+	// expose adapters and the wrapper as private functions
+	
+	nl._wrap = tnl;
+	nl._adaptAsMap = adaptAsMap;
+	nl._adaptAsForEach = adaptAsForEach;
+	nl._adaptAsFilter  = adaptAsFilter;
+	nl._adaptWithCondition = adaptWithCondition;
+	
+	// mass assignment
+	
+	// add array redirectors
+	d.forEach(["slice", "splice"], function(name){
+		var f = ap[name];
+		nlp[name] = function(){ return tnl(f.apply(this, arguments)); };
+	});
+	// concat should be here but some browsers with native NodeList have problems with it
+	
+	// add array.js redirectors
+	d.forEach(["indexOf", "lastIndexOf", "every", "some"], function(name){
+		var f = d[name];
+		nlp[name] = function(){ return f.apply(d, [this].concat(aps.call(arguments, 0))); };
+	});
+	
+	// add conditional methods
+	d.forEach(["attr", "style"], function(name){
+		nlp[name] = adaptWithCondition(d[name], magicGuard);
+	});
+	
+	// add forEach actions
+	d.forEach(["connect", "addClass", "removeClass", "toggleClass", "empty"], function(name){
+		nlp[name] = adaptAsForEach(d[name]);
+	});
+
+	dojo.extend(dojo.NodeList, {
+		// http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array#Methods
+
+		// FIXME: handle return values for #3244
+		//		http://trac.dojotoolkit.org/ticket/3244
+		
+		// FIXME:
+		//		need to wrap or implement:
+		//			join (perhaps w/ innerHTML/outerHTML overload for toString() of items?)
+		//			reduce
+		//			reduceRight
+
+		/*=====
+		slice: function(begin, end){
+			// summary:
+			//		Returns a new NodeList, maintaining this one in place
+			// description:
+			//		This method behaves exactly like the Array.slice method
+			//		with the caveat that it returns a dojo.NodeList and not a
+			//		raw Array. For more details, see Mozilla's (slice
+			//		documentation)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:slice]
+			// begin: Integer
+			//		Can be a positive or negative integer, with positive
+			//		integers noting the offset to begin at, and negative
+			//		integers denoting an offset from the end (i.e., to the left
+			//		of the end)
+			// end: Integer?
+			//		Optional parameter to describe what position relative to
+			//		the NodeList's zero index to end the slice at. Like begin,
+			//		can be positive or negative.
+			return tnl(a.slice.apply(this, arguments));
+		},
+
+		splice: function(index, howmany, item){
+			// summary:
+			//		Returns a new NodeList, manipulating this NodeList based on
+			//		the arguments passed, potentially splicing in new elements
+			//		at an offset, optionally deleting elements
+			// description:
+			//		This method behaves exactly like the Array.splice method
+			//		with the caveat that it returns a dojo.NodeList and not a
+			//		raw Array. For more details, see Mozilla's (splice
+			//		documentation)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:splice]
+			// index: Integer
+			//		begin can be a positive or negative integer, with positive
+			//		integers noting the offset to begin at, and negative
+			//		integers denoting an offset from the end (i.e., to the left
+			//		of the end)
+			// howmany: Integer?
+			//		Optional parameter to describe what position relative to
+			//		the NodeList's zero index to end the slice at. Like begin,
+			//		can be positive or negative.
+			// item: Object...?
+			//		Any number of optional parameters may be passed in to be
+			//		spliced into the NodeList
+			// returns:
+			//		dojo.NodeList
+			return tnl(a.splice.apply(this, arguments));
+		},
+
+		indexOf: function(value, fromIndex){
+			//	summary:
+			//		see dojo.indexOf(). The primary difference is that the acted-on 
+			//		array is implicitly this NodeList
+			// value: Object:
+			//		The value to search for.
+			// fromIndex: Integer?:
+			//		The loction to start searching from. Optional. Defaults to 0.
+			//	description:
+			//		For more details on the behavior of indexOf, see Mozilla's
+			//		(indexOf
+			//		docs)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf]
+			//	returns:
+			//		Positive Integer or 0 for a match, -1 of not found.
+			return d.indexOf(this, value, fromIndex); // Integer
+		},
+
+		lastIndexOf: function(value, fromIndex){
+			// summary:
+			//		see dojo.lastIndexOf(). The primary difference is that the
+			//		acted-on array is implicitly this NodeList
+			//	description:
+			//		For more details on the behavior of lastIndexOf, see
+			//		Mozilla's (lastIndexOf
+			//		docs)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf]
+			// value: Object
+			//		The value to search for.
+			// fromIndex: Integer?
+			//		The loction to start searching from. Optional. Defaults to 0.
+			// returns:
+			//		Positive Integer or 0 for a match, -1 of not found.
+			return d.lastIndexOf(this, value, fromIndex); // Integer
+		},
+
+		every: function(callback, thisObject){
+			//	summary:
+			//		see `dojo.every()` and the (Array.every
+			//		docs)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:every].
+			//		Takes the same structure of arguments and returns as
+			//		dojo.every() with the caveat that the passed array is
+			//		implicitly this NodeList
+			// callback: Function: the callback
+			// thisObject: Object?: the context
+			return d.every(this, callback, thisObject); // Boolean
+		},
+
+		some: function(callback, thisObject){
+			//	summary:
+			//		Takes the same structure of arguments and returns as
+			//		`dojo.some()` with the caveat that the passed array is
+			//		implicitly this NodeList.  See `dojo.some()` and Mozilla's
+			//		(Array.some
+			//		documentation)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:some].
+			// callback: Function: the callback
+			// thisObject: Object?: the context
+			return d.some(this, callback, thisObject); // Boolean
+		},
+		=====*/
+
+		concat: function(item){
+			// summary:
+			//		Returns a new NodeList comprised of items in this NodeList
+			//		as well as items passed in as parameters
+			// description:
+			//		This method behaves exactly like the Array.concat method
+			//		with the caveat that it returns a `dojo.NodeList` and not a
+			//		raw Array. For more details, see the (Array.concat
+			//		docs)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:concat]
+			// item: Object?
+			//		Any number of optional parameters may be passed in to be
+			//		spliced into the NodeList
+			// returns:
+			//		dojo.NodeList
+			
+			//return tnl(apc.apply(this, arguments));
+			// the line above won't work for the native NodeList :-(
+			
+			// implementation notes:
+			// 1) Native NodeList is not an array, and cannot be used directly
+			// in concat() --- the latter doesn't recognize it as an array, and
+			// does not inline it, but append as a single entity.
+			// 2) On some browsers (e.g., Safari) the "constructor" property is
+			// read-only and cannot be changed. So we have to test for both
+			// native NodeList and dojo.NodeList in this property to recognize
+			// the node list.
+			
+			var t = d.isArray(this) ? this : aps.call(this, 0),
+				m = d.map(arguments, function(a){
+					return a && !d.isArray(a) &&
+						(a.constructor === NodeList || a.constructor == nl) ?
+							aps.call(a, 0) : a;
+				});
+			return tnl(apc.apply(t, m));	// dojo.NodeList
+		},
+
+		map: function(/*Function*/ func, /*Function?*/ obj){
+			//	summary:
+			//		see dojo.map(). The primary difference is that the acted-on
+			//		array is implicitly this NodeList and the return is a
+			//		dojo.NodeList (a subclass of Array)
+			///return d.map(this, func, obj, d.NodeList); // dojo.NodeList
+			return tnl(d.map(this, func, obj)); // dojo.NodeList
+		},
+
+		forEach: function(callback, thisObj){
+			//	summary:
+			//		see `dojo.forEach()`. The primary difference is that the acted-on 
+			//		array is implicitly this NodeList
+			d.forEach(this, callback, thisObj);
+			// non-standard return to allow easier chaining
+			return this; // dojo.NodeList 
+		},
+
+
+		/*=====
+		coords: function(){
+			//	summary:
+			// 		Returns the box objects all elements in a node list as
+			// 		an Array (*not* a NodeList)
+			
+			return d.map(this, d.coords); // Array
+		},
+
+		attr: function(property, value){
+			//	summary:
+			//		gets or sets the DOM attribute for every element in the
+			//		NodeList
+			//	property: String
+			//		the attribute to get/set
+			//	value: String?
+			//		optional. The value to set the property to
+			//	returns:
+			//		if no value is passed, the result is an array of attribute values
+			//		If a value is passed, the return is this NodeList
+			return; // dojo.NodeList
+			return; // Array
+		},
+
+		style: function(property, value){
+			//	summary:
+			//		gets or sets the CSS property for every element in the NodeList
+			//	property: String
+			//		the CSS property to get/set, in JavaScript notation
+			//		("lineHieght" instead of "line-height") 
+			//	value: String?
+			//		optional. The value to set the property to
+			//	returns:
+			//		if no value is passed, the result is an array of strings.
+			//		If a value is passed, the return is this NodeList
+			return; // dojo.NodeList
+			return; // Array
+		},
+
+		addClass: function(className){
+			//	summary:
+			//		adds the specified class to every node in the list
+			//	className: String
+			//		the CSS class to add
+			return; // dojo.NodeList
+		},
+
+		removeClass: function(className){
+			//	summary:
+			//		removes the specified class from every node in the list
+			//	className: String
+			//		the CSS class to add
+			//	returns:
+			//		dojo.NodeList, this list
+			return; // dojo.NodeList
+		},
+
+		toggleClass: function(className, condition){
+			//	summary:
+			//		Adds a class to node if not present, or removes if present.
+			//		Pass a boolean condition if you want to explicitly add or remove.
+			//	condition: Boolean?
+			//		If passed, true means to add the class, false means to remove.
+			//	className: String
+			//		the CSS class to add
+			return; // dojo.NodeList
+		},
+
+		connect: function(methodName, objOrFunc, funcName){
+			//	summary:
+			//		attach event handlers to every item of the NodeList. Uses dojo.connect()
+			//		so event properties are normalized
+			//	methodName: String
+			//		the name of the method to attach to. For DOM events, this should be
+			//		the lower-case name of the event
+			//	objOrFunc: Object|Function|String
+			//		if 2 arguments are passed (methodName, objOrFunc), objOrFunc should
+			//		reference a function or be the name of the function in the global
+			//		namespace to attach. If 3 arguments are provided
+			//		(methodName, objOrFunc, funcName), objOrFunc must be the scope to 
+			//		locate the bound function in
+			//	funcName: String?
+			//		optional. A string naming the function in objOrFunc to bind to the
+			//		event. May also be a function reference.
+			//	example:
+			//		add an onclick handler to every button on the page
+			//		|	dojo.query("div:nth-child(odd)").connect("onclick", function(e){
+			//		|		
+			//		|	});
+			// example:
+			//		attach foo.bar() to every odd div's onmouseover
+			//		|	dojo.query("div:nth-child(odd)").connect("onmouseover", foo, "bar");
+		},
+
+		empty: function(){
+			//	summary:
+			//		clears all content from each node in the list. Effectively
+			//		equivalent to removing all child nodes from every item in
+			//		the list.
+			return this.forEach("item.innerHTML='';"); // dojo.NodeList
+			// FIXME: should we be checking for and/or disposing of widgets below these nodes?
+		},
+		=====*/
+		
+		// useful html methods
+		coords:	adaptAsMap(d.coords),
+
+		// FIXME: connectPublisher()? connectRunOnce()?
+
+		/*
+		destroy: function(){
+			//	summary:
+			//		destroys every item in 	the list.
+			this.forEach(d.destroy);
+			// FIXME: should we be checking for and/or disposing of widgets below these nodes?
+		},
+		*/
+
+		place: function(/*String||Node*/ queryOrNode, /*String*/ position){
+			//	summary:
+			//		places elements of this node list relative to the first element matched
+			//		by queryOrNode. Returns the original NodeList. See: `dojo.place`
+			//	queryOrNode:
+			//		may be a string representing any valid CSS3 selector or a DOM node.
+			//		In the selector case, only the first matching element will be used 
+			//		for relative positioning.
+			//	position:
+			//		can be one of:
+			//		|	"last" (default)
+			//		|	"first"
+			//		|	"before"
+			//		|	"after"
+			//		|	"only"
+			//		|	"replace"
+			// 		or an offset in the childNodes property
+			var item = d.query(queryOrNode)[0];
+			return this.forEach(function(node){ d.place(node, item, position); }); // dojo.NodeList
+		},
+
+		orphan: function(/*String?*/ simpleFilter){
+			//	summary:
+			//		removes elements in this list that match the simple filter
+			//		from their parents and returns them as a new NodeList.
+			//	simpleFilter:
+			//		single-expression CSS rule. For example, ".thinger" or
+			//		"#someId[attrName='value']" but not "div > span". In short,
+			//		anything which does not invoke a descent to evaluate but
+			//		can instead be used to test a single node is acceptable.
+			//	returns:
+			//		`dojo.NodeList` containing the orpahned elements 
+			return (simpleFilter ? d._filterQueryResult(this, simpleFilter) : this).forEach(orphan); // dojo.NodeList
+		},
+
+		adopt: function(/*String||Array||DomNode*/ queryOrListOrNode, /*String?*/ position){
+			//	summary:
+			//		places any/all elements in queryOrListOrNode at a
+			//		position relative to the first element in this list.
+			//		Returns a dojo.NodeList of the adopted elements.
+			//	queryOrListOrNode:
+			//		a DOM node or a query string or a query result.
+			//		Represents the nodes to be adopted relative to the
+			//		first element of this NodeList.
+			//	position:
+			//		can be one of:
+			//		|	"last" (default)
+			//		|	"first"
+			//		|	"before"
+			//		|	"after"
+			//		|	"only"
+			//		|	"replace"
+			// 		or an offset in the childNodes property
+			return d.query(queryOrListOrNode).place(this[0], position);	// dojo.NodeList
+		},
+
+		// FIXME: do we need this?
+		query: function(/*String*/ queryStr){
+			//	summary:
+			//		Returns a new list whose memebers match the passed query,
+			//		assuming elements of the current NodeList as the root for
+			//		each search.
+			//	example:
+			//		assume a DOM created by this markup:
+			//	|	<div id="foo">
+			//	|		<p>
+			//	|			bacon is tasty, <span>dontcha think?</span>
+			//	|		</p>
+			//	|	</div>
+			//	|	<div id="bar">
+			//	|		<p>great commedians may not be funny <span>in person</span></p>
+			//	|	</div>
+			//		If we are presented with the following defintion for a NodeList:
+			//	|	var l = new dojo.NodeList(dojo.byId("foo"), dojo.byId("bar"));
+			//		it's possible to find all span elements under paragraphs
+			//		contained by these elements with this sub-query:
+			//	| 	var spans = l.query("p span");
+
+			// FIXME: probably slow
+			if(!queryStr){ return this; }
+			var ret = this.map(function(node){
+				// FIXME: why would we ever get undefined here?
+				return d.query(queryStr, node).filter(function(subNode){ return subNode !== undefined; });
+			});
+			return tnl(apc.apply([], ret));	// dojo.NodeList
+		},
+
+		filter: function(/*String|Function*/ simpleFilter){
+			//	summary:
+			// 		"masks" the built-in javascript filter() method (supported
+			// 		in Dojo via `dojo.filter`) to support passing a simple
+			// 		string filter in addition to supporting filtering function
+			// 		objects.
+			//	simpleFilter:
+			//		If a string, a single-expression CSS rule. For example,
+			//		".thinger" or "#someId[attrName='value']" but not "div >
+			//		span". In short, anything which does not invoke a descent
+			//		to evaluate but can instead be used to test a single node
+			//		is acceptable.
+			//	example:
+			//		"regular" JS filter syntax as exposed in dojo.filter:
+			//		|	dojo.query("*").filter(function(item){
+			//		|		// highlight every paragraph
+			//		|		return (item.nodeName == "p");
+			//		|	}).style("backgroundColor", "yellow");
+			// example:
+			//		the same filtering using a CSS selector
+			//		|	dojo.query("*").filter("p").styles("backgroundColor", "yellow");
+
+			var a = arguments, items = this, start = 0;
+			if(d.isString(simpleFilter)){
+				items = d._filterQueryResult(this, a[0]);
+				if(a.length == 1){
+					// if we only got a string query, pass back the filtered results
+					return items; // dojo.NodeList
+				}
+				// if we got a callback, run it over the filtered items
+				start = 1;
+			}
+			return tnl(d.filter(items, a[start], a[start + 1]));	// dojo.NodeList
+		},
+		
+		/*
+		// FIXME: should this be "copyTo" and include parenting info?
+		clone: function(){
+			// summary:
+			//		creates node clones of each element of this list
+			//		and returns a new list containing the clones
+		},
+		*/
+
+		addContent: function(/*String|DomNode*/ content, /*String||Integer?*/ position){
+			//	summary:
+			//		add a node or some HTML as a string to every item in the
+			//		list.  Returns the original list.
+			//	description:
+			//		a copy of the HTML content is added to each item in the
+			//		list, with an optional position argument. If no position
+			//		argument is provided, the content is appended to the end of
+			//		each item.
+			//	content:
+			//		DOM node or HTML in string format to add at position to
+			//		every item
+			//	position:
+			//		can be one of:
+			//		|	"last"||"end" (default)
+			//		|	"first||"start"
+			//		|	"before"
+			//		|	"after"
+			// 		or an offset in the childNodes property
+			//	example:
+			//		appends content to the end if the position is ommitted
+			//	|	dojo.query("h3 > p").addContent("hey there!");
+			//	example:
+			//		add something to the front of each element that has a
+			//		"thinger" property:
+			//	|	dojo.query("[thinger]").addContent("...", "first");
+			//	example:
+			//		adds a header before each element of the list
+			//	|	dojo.query(".note").addContent("<h4>NOTE:</h4>", "before");
+			//	example:
+			//		add a clone of a DOM node to the end of every element in
+			//		the list, removing it from its existing parent.
+			//	|	dojo.query(".note").addContent(dojo.byId("foo"));
+			var c = d.isString(content) ? 
+						d._toDom(content, this[0] && this[0].ownerDocument) : 
+						content, 
+					i, 
+					l = this.length - 1;
+			for(i = 0; i < l; ++i){
+				d.place(c.cloneNode(true), this[i], position);
+			}
+			if(l >= 0){
+				d.place(c, this[l], position);
+			}
+			return this;	// dojo.NodeList
+		},
+
+		instantiate: function(/*String|Object*/ declaredClass, /*Object?*/ properties){
+			//	summary:
+			//		Create a new instance of a specified class, using the
+			//		specified properties and each node in the nodeList as a
+			//		srcNodeRef
+			var c = d.isFunction(declaredClass) ? declaredClass : d.getObject(declaredClass);
+			properties = properties || {};
+			return this.forEach(function(node){ new c(properties, node); });	// dojo.NodeList
+		},
+
+		at: function(/*===== index =====*/){
+			//	summary:
+			//		Returns a new NodeList comprised of items in this NodeList
+			//		at the given index or indices.
+			//	index: Integer...
+			//		One or more 0-based indices of items in the current
+			//		NodeList.
+			//	returns:
+			//		dojo.NodeList
+			var t = new dojo.NodeList();
+			d.forEach(arguments, function(i){ if(this[i]){ t.push(this[i]); }}, this);
+			return t; // dojo.NodeList
+		}
+
+	});
+
+	// syntactic sugar for DOM events
+	d.forEach([
+		"blur", "focus", "change", "click", "error", "keydown", "keypress",
+		"keyup", "load", "mousedown", "mouseenter", "mouseleave", "mousemove",
+		"mouseout", "mouseover", "mouseup", "submit" 
+		], function(evt){
+			var _oe = "on"+evt;
+			nlp[_oe] = function(a, b){
+				return this.connect(_oe, a, b);
+			}
+				// FIXME: should these events trigger publishes?
+				/*
+				return (a ? this.connect(_oe, a, b) : 
+							this.forEach(function(n){  
+								// FIXME:
+								//		listeners get buried by
+								//		addEventListener and can't be dug back
+								//		out to be triggered externally.
+								// see:
+								//		http://developer.mozilla.org/en/docs/DOM:element
+
+								
+
+								// FIXME: need synthetic event support!
+								var _e = { target: n, faux: true, type: evt };
+								// dojo._event_listener._synthesizeEvent({}, { target: n, faux: true, type: evt });
+								try{ n[evt](_e); }catch(e){  }
+								try{ n[_oe](_e); }catch(e){  }
+							})
+				);
+			}
+			*/
+		}
+	);
+
+})();
+
+}
+
+if(!dojo._hasResource["dojo._base.query"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.query"] = true;
+if(typeof dojo != "undefined"){
+	dojo.provide("dojo._base.query");
+	
+	
+
+}
+
+/*
+	dojo.query() architectural overview:
+
+		dojo.query is a relatively full-featured CSS3 query library. It is
+		designed to take any valid CSS3 selector and return the nodes matching
+		the selector. To do this quickly, it processes queries in several
+		steps, applying caching where profitable.
+		
+		The steps (roughly in reverse order of the way they appear in the code):
+			1.) check to see if we already have a "query dispatcher"
+				- if so, use that with the given parameterization. Skip to step 4.
+			2.) attempt to determine which branch to dispatch the query to:
+				- JS (optimized DOM iteration)
+				- native (FF3.1+, Safari 3.1+, IE 8+)
+			3.) tokenize and convert to executable "query dispatcher"
+				- this is where the lion's share of the complexity in the
+				  system lies. In the DOM version, the query dispatcher is
+				  assembled as a chain of "yes/no" test functions pertaining to
+				  a section of a simple query statement (".blah:nth-child(odd)"
+				  but not "div div", which is 2 simple statements). Individual
+				  statement dispatchers are cached (to prevent re-definition)
+				  as are entire dispatch chains (to make re-execution of the
+				  same query fast)
+			4.) the resulting query dispatcher is called in the passed scope
+			    (by default the top-level document)
+				- for DOM queries, this results in a recursive, top-down
+				  evaluation of nodes based on each simple query section
+				- for native implementations, this may mean working around spec
+				  bugs. So be it.
+			5.) matched nodes are pruned to ensure they are unique (if necessary)
+*/
+
+;(function(d){
+	// define everything in a closure for compressability reasons. "d" is an
+	// alias to "dojo" (or the toolkit alias object, e.g., "acme").
+
+	////////////////////////////////////////////////////////////////////////
+	// Toolkit aliases
+	////////////////////////////////////////////////////////////////////////
+
+	// if you are extracing dojo.query for use in your own system, you will
+	// need to provide these methods and properties. No other porting should be
+	// necessary, save for configuring the system to use a class other than
+	// dojo.NodeList as the return instance instantiator
+	var trim = 			d.trim;
+	var each = 			d.forEach;
+	// 					d.isIE; // float
+	// 					d.isSafari; // float
+	// 					d.isOpera; // float
+	// 					d.isWebKit; // float
+	// 					d.doc ; // document element
+	var qlc = d._queryListCtor = 		d.NodeList;
+	var isString = 		d.isString;
+
+	var getDoc = function(){ return d.doc; };
+	// NOTE(alex): the spec is idiotic. CSS queries should ALWAYS be case-sensitive, but nooooooo
+	var cssCaseBug = ((d.isWebKit||d.isMozilla) && ((getDoc().compatMode) == "BackCompat"));
+
+	////////////////////////////////////////////////////////////////////////
+	// Global utilities
+	////////////////////////////////////////////////////////////////////////
+
+
+	// on browsers that support the "children" collection we can avoid a lot of
+	// iteration on chaff (non-element) nodes.
+	// why.
+	var childNodesName = !!getDoc().firstChild["children"] ? "children" : "childNodes";
+
+	var specials = ">~+";
+
+	// global thunk to determine whether we should treat the current query as
+	// case sensitive or not. This switch is flipped by the query evaluator
+	// based on the document passed as the context to search.
+	var caseSensitive = false;
+
+	// how high?
+	var yesman = function(){ return true; };
+
+	////////////////////////////////////////////////////////////////////////
+	// Tokenizer
+	////////////////////////////////////////////////////////////////////////
+
+	var getQueryParts = function(query){
+		//	summary: 
+		//		state machine for query tokenization
+		//	description:
+		//		instead of using a brittle and slow regex-based CSS parser,
+		//		dojo.query implements an AST-style query representation. This
+		//		representation is only generated once per query. For example,
+		//		the same query run multiple times or under different root nodes
+		//		does not re-parse the selector expression but instead uses the
+		//		cached data structure. The state machine implemented here
+		//		terminates on the last " " (space) charachter and returns an
+		//		ordered array of query component structures (or "parts"). Each
+		//		part represents an operator or a simple CSS filtering
+		//		expression. The structure for parts is documented in the code
+		//		below.
+
+
+		// NOTE: 
+		//		this code is designed to run fast and compress well. Sacrifices
+		//		to readibility and maintainability have been made.  Your best
+		//		bet when hacking the tokenizer is to put The Donnas on *really*
+		//		loud (may we recommend their "Spend The Night" release?) and
+		//		just assume you're gonna make mistakes. Keep the unit tests
+		//		open and run them frequently. Knowing is half the battle ;-)
+		if(specials.indexOf(query.slice(-1)) >= 0){
+			// if we end with a ">", "+", or "~", that means we're implicitly
+			// searching all children, so make it explicit
+			query += " * "
+		}else{
+			// if you have not provided a terminator, one will be provided for
+			// you...
+			query += " ";
+		}
+
+		var ts = function(/*Integer*/ s, /*Integer*/ e){
+			// trim and slice. 
+
+			// take an index to start a string slice from and an end position
+			// and return a trimmed copy of that sub-string
+			return trim(query.slice(s, e));
+		}
+
+		// the overall data graph of the full query, as represented by queryPart objects
+		var queryParts = []; 
+
+
+		// state keeping vars
+		var inBrackets = -1, inParens = -1, inMatchFor = -1, 
+			inPseudo = -1, inClass = -1, inId = -1, inTag = -1, 
+			lc = "", cc = "", pStart;
+
+		// iteration vars
+		var x = 0, // index in the query
+			ql = query.length,
+			currentPart = null, // data structure representing the entire clause
+			_cp = null; // the current pseudo or attr matcher
+
+		// several temporary variables are assigned to this structure durring a
+		// potential sub-expression match:
+		//		attr:
+		//			a string representing the current full attribute match in a
+		//			bracket expression
+		//		type:
+		//			if there's an operator in a bracket expression, this is
+		//			used to keep track of it
+		//		value:
+		//			the internals of parenthetical expression for a pseudo. for
+		//			:nth-child(2n+1), value might be "2n+1"
+
+		var endTag = function(){
+			// called when the tokenizer hits the end of a particular tag name.
+			// Re-sets state variables for tag matching and sets up the matcher
+			// to handle the next type of token (tag or operator).
+			if(inTag >= 0){
+				var tv = (inTag == x) ? null : ts(inTag, x); // .toLowerCase();
+				currentPart[ (specials.indexOf(tv) < 0) ? "tag" : "oper" ] = tv;
+				inTag = -1;
+			}
+		}
+
+		var endId = function(){
+			// called when the tokenizer might be at the end of an ID portion of a match
+			if(inId >= 0){
+				currentPart.id = ts(inId, x).replace(/\\/g, "");
+				inId = -1;
+			}
+		}
+
+		var endClass = function(){
+			// called when the tokenizer might be at the end of a class name
+			// match. CSS allows for multiple classes, so we augment the
+			// current item with another class in its list
+			if(inClass >= 0){
+				currentPart.classes.push(ts(inClass+1, x).replace(/\\/g, ""));
+				inClass = -1;
+			}
+		}
+
+		var endAll = function(){
+			// at the end of a simple fragment, so wall off the matches
+			endId(); endTag(); endClass();
+		}
+
+		var endPart = function(){
+			endAll();
+			if(inPseudo >= 0){
+				currentPart.pseudos.push({ name: ts(inPseudo+1, x) });
+			}
+			// hint to the selector engine to tell it whether or not it
+			// needs to do any iteration. Many simple selectors don't, and
+			// we can avoid significant construction-time work by advising
+			// the system to skip them
+			currentPart.loops = (	
+					currentPart.pseudos.length || 
+					currentPart.attrs.length || 
+					currentPart.classes.length	);
+
+			currentPart.oquery = currentPart.query = ts(pStart, x); // save the full expression as a string
+
+
+			// otag/tag are hints to suggest to the system whether or not
+			// it's an operator or a tag. We save a copy of otag since the
+			// tag name is cast to upper-case in regular HTML matches. The
+			// system has a global switch to figure out if the current
+			// expression needs to be case sensitive or not and it will use
+			// otag or tag accordingly
+			currentPart.otag = currentPart.tag = (currentPart["oper"]) ? null : (currentPart.tag || "*");
+
+			if(currentPart.tag){
+				// if we're in a case-insensitive HTML doc, we likely want
+				// the toUpperCase when matching on element.tagName. If we
+				// do it here, we can skip the string op per node
+				// comparison
+				currentPart.tag = currentPart.tag.toUpperCase();
+			}
+
+			// add the part to the list
+			if(queryParts.length && (queryParts[queryParts.length-1].oper)){
+				// operators are always infix, so we remove them from the
+				// list and attach them to the next match. The evaluator is
+				// responsible for sorting out how to handle them.
+				currentPart.infixOper = queryParts.pop();
+				currentPart.query = currentPart.infixOper.query + " " + currentPart.query;
+				/*
+				
+				*/
+			}
+			queryParts.push(currentPart);
+
+			currentPart = null;
+		}
+
+		// iterate over the query, charachter by charachter, building up a 
+		// list of query part objects
+		for(; lc=cc, cc=query.charAt(x), x < ql; x++){
+			//		cc: the current character in the match
+			//		lc: the last charachter (if any)
+
+			// someone is trying to escape something, so don't try to match any
+			// fragments. We assume we're inside a literal.
+			if(lc == "\\"){ continue; } 
+			if(!currentPart){ // a part was just ended or none has yet been created
+				// NOTE: I hate all this alloc, but it's shorter than writing tons of if's
+				pStart = x;
+				//	rules describe full CSS sub-expressions, like:
+				//		#someId
+				//		.className:first-child
+				//	but not:
+				//		thinger > div.howdy[type=thinger]
+				//	the indidual components of the previous query would be
+				//	split into 3 parts that would be represented a structure
+				//	like:
+				//		[
+				//			{
+				//				query: "thinger",
+				//				tag: "thinger",
+				//			},
+				//			{
+				//				query: "div.howdy[type=thinger]",
+				//				classes: ["howdy"],
+				//				infixOper: {
+				//					query: ">",
+				//					oper: ">",
+				//				}
+				//			},
+				//		]
+				currentPart = {
+					query: null, // the full text of the part's rule
+					pseudos: [], // CSS supports multiple pseud-class matches in a single rule
+					attrs: [], 	// CSS supports multi-attribute match, so we need an array
+					classes: [], // class matches may be additive, e.g.: .thinger.blah.howdy
+					tag: null, 	// only one tag...
+					oper: null, // ...or operator per component. Note that these wind up being exclusive.
+					id: null, 	// the id component of a rule
+					getTag: function(){
+						return (caseSensitive) ? this.otag : this.tag;
+					}
+				};
+
+				// if we don't have a part, we assume we're going to start at
+				// the beginning of a match, which should be a tag name. This
+				// might fault a little later on, but we detect that and this
+				// iteration will still be fine.
+				inTag = x; 
+			}
+
+			if(inBrackets >= 0){
+				// look for a the close first
+				if(cc == "]"){ // if we're in a [...] clause and we end, do assignment
+					if(!_cp.attr){
+						// no attribute match was previously begun, so we
+						// assume this is an attribute existance match in the
+						// form of [someAttributeName]
+						_cp.attr = ts(inBrackets+1, x);
+					}else{
+						// we had an attribute already, so we know that we're
+						// matching some sort of value, as in [attrName=howdy]
+						_cp.matchFor = ts((inMatchFor||inBrackets+1), x);
+					}
+					var cmf = _cp.matchFor;
+					if(cmf){
+						// try to strip quotes from the matchFor value. We want
+						// [attrName=howdy] to match the same 
+						//	as [attrName = 'howdy' ]
+						if(	(cmf.charAt(0) == '"') || (cmf.charAt(0)  == "'") ){
+							_cp.matchFor = cmf.slice(1, -1);
+						}
+					}
+					// end the attribute by adding it to the list of attributes. 
+					currentPart.attrs.push(_cp);
+					_cp = null; // necessary?
+					inBrackets = inMatchFor = -1;
+				}else if(cc == "="){
+					// if the last char was an operator prefix, make sure we
+					// record it along with the "=" operator. 
+					var addToCc = ("|~^$*".indexOf(lc) >=0 ) ? lc : "";
+					_cp.type = addToCc+cc;
+					_cp.attr = ts(inBrackets+1, x-addToCc.length);
+					inMatchFor = x+1;
+				}
+				// now look for other clause parts
+			}else if(inParens >= 0){
+				// if we're in a parenthetical expression, we need to figure
+				// out if it's attached to a pseduo-selector rule like
+				// :nth-child(1)
+				if(cc == ")"){
+					if(inPseudo >= 0){
+						_cp.value = ts(inParens+1, x);
+					}
+					inPseudo = inParens = -1;
+				}
+			}else if(cc == "#"){
+				// start of an ID match
+				endAll();
+				inId = x+1;
+			}else if(cc == "."){
+				// start of a class match
+				endAll();
+				inClass = x;
+			}else if(cc == ":"){
+				// start of a pseudo-selector match
+				endAll();
+				inPseudo = x;
+			}else if(cc == "["){
+				// start of an attribute match. 
+				endAll();
+				inBrackets = x;
+				// provide a new structure for the attribute match to fill-in
+				_cp = {
+					/*=====
+					attr: null, type: null, matchFor: null
+					=====*/
+				};
+			}else if(cc == "("){
+				// we really only care if we've entered a parenthetical
+				// expression if we're already inside a pseudo-selector match
+				if(inPseudo >= 0){
+					// provide a new structure for the pseudo match to fill-in
+					_cp = { 
+						name: ts(inPseudo+1, x), 
+						value: null
+					}
+					currentPart.pseudos.push(_cp);
+				}
+				inParens = x;
+			}else if(
+				(cc == " ") && 
+				// if it's a space char and the last char is too, consume the
+				// current one without doing more work
+				(lc != cc)
+			){
+				endPart();
+			}
+		}
+		return queryParts;
+	};
+	
+
+	////////////////////////////////////////////////////////////////////////
+	// DOM query infrastructure
+	////////////////////////////////////////////////////////////////////////
+
+	var agree = function(first, second){
+		// the basic building block of the yes/no chaining system. agree(f1,
+		// f2) generates a new function which returns the boolean results of
+		// both of the passed functions to a single logical-anded result. If
+		// either are not possed, the other is used exclusively.
+		if(!first){ return second; }
+		if(!second){ return first; }
+
+		return function(){
+			return first.apply(window, arguments) && second.apply(window, arguments);
+		}
+	};
+
+	var getArr = function(i, arr){
+		// helps us avoid array alloc when we don't need it
+		var r = arr||[]; // FIXME: should this be 'new d._queryListCtor()' ?
+		if(i){ r.push(i); }
+		return r;
+	};
+
+	var _isElement = function(n){ return (1 == n.nodeType); };
+
+	// FIXME: need to coalesce _getAttr with defaultGetter
+	var blank = "";
+	var _getAttr = function(elem, attr){
+		if(!elem){ return blank; }
+		if(attr == "class"){
+			return elem.className || blank;
+		}
+		if(attr == "for"){
+			return elem.htmlFor || blank;
+		}
+		if(attr == "style"){
+			return elem.style.cssText || blank;
+		}
+		return (caseSensitive ? elem.getAttribute(attr) : elem.getAttribute(attr, 2)) || blank;
+	};
+
+	var attrs = {
+		"*=": function(attr, value){
+			return function(elem){
+				// E[foo*="bar"]
+				//		an E element whose "foo" attribute value contains
+				//		the substring "bar"
+				return (_getAttr(elem, attr).indexOf(value)>=0);
+			}
+		},
+		"^=": function(attr, value){
+			// E[foo^="bar"]
+			//		an E element whose "foo" attribute value begins exactly
+			//		with the string "bar"
+			return function(elem){
+				return (_getAttr(elem, attr).indexOf(value)==0);
+			}
+		},
+		"$=": function(attr, value){
+			// E[foo$="bar"]	
+			//		an E element whose "foo" attribute value ends exactly
+			//		with the string "bar"
+			var tval = " "+value;
+			return function(elem){
+				var ea = " "+_getAttr(elem, attr);
+				return (ea.lastIndexOf(value)==(ea.length-value.length));
+			}
+		},
+		"~=": function(attr, value){
+			// E[foo~="bar"]	
+			//		an E element whose "foo" attribute value is a list of
+			//		space-separated values, one of which is exactly equal
+			//		to "bar"
+
+			// return "[contains(concat(' ',@"+attr+",' '), ' "+ value +" ')]";
+			var tval = " "+value+" ";
+			return function(elem){
+				var ea = " "+_getAttr(elem, attr)+" ";
+				return (ea.indexOf(tval)>=0);
+			}
+		},
+		"|=": function(attr, value){
+			// E[hreflang|="en"]
+			//		an E element whose "hreflang" attribute has a
+			//		hyphen-separated list of values beginning (from the
+			//		left) with "en"
+			var valueDash = " "+value+"-";
+			return function(elem){
+				var ea = " "+_getAttr(elem, attr);
+				return (
+					(ea == value) ||
+					(ea.indexOf(valueDash)==0)
+				);
+			}
+		},
+		"=": function(attr, value){
+			return function(elem){
+				return (_getAttr(elem, attr) == value);
+			}
+		}
+	};
+
+	// avoid testing for node type if we can. Defining this in the negative
+	// here to avoid negation in the fast path.
+	var _noNES = (typeof getDoc().firstChild.nextElementSibling == "undefined");
+	var _ns = !_noNES ? "nextElementSibling" : "nextSibling";
+	var _ps = !_noNES ? "previousElementSibling" : "previousSibling";
+	var _simpleNodeTest = (_noNES ? _isElement : yesman);
+
+	var _lookLeft = function(node){
+		// look left
+		while(node = node[_ps]){
+			if(_simpleNodeTest(node)){ return false; }
+		}
+		return true;
+	};
+
+	var _lookRight = function(node){
+		// look right
+		while(node = node[_ns]){
+			if(_simpleNodeTest(node)){ return false; }
+		}
+		return true;
+	};
+
+	var getNodeIndex = function(node){
+		var root = node.parentNode;
+		var i = 0,
+			tret = root[childNodesName],
+			ci = (node["_i"]||-1),
+			cl = (root["_l"]||-1);
+
+		if(!tret){ return -1; }
+		var l = tret.length;
+
+		// we calcuate the parent length as a cheap way to invalidate the
+		// cache. It's not 100% accurate, but it's much more honest than what
+		// other libraries do
+		if( cl == l && ci >= 0 && cl >= 0 ){
+			// if it's legit, tag and release
+			return ci;
+		}
+
+		// else re-key things
+		root["_l"] = l;
+		ci = -1;
+		for(var te = root["firstElementChild"]||root["firstChild"]; te; te = te[_ns]){
+			if(_simpleNodeTest(te)){ 
+				te["_i"] = ++i;
+				if(node === te){ 
+					// NOTE:
+					// 	shortcuting the return at this step in indexing works
+					// 	very well for benchmarking but we avoid it here since
+					// 	it leads to potential O(n^2) behavior in sequential
+					// 	getNodexIndex operations on a previously un-indexed
+					// 	parent. We may revisit this at a later time, but for
+					// 	now we just want to get the right answer more often
+					// 	than not.
+					ci = i;
+				}
+			}
+		}
+		return ci;
+	};
+
+	var isEven = function(elem){
+		return !((getNodeIndex(elem)) % 2);
+	};
+
+	var isOdd = function(elem){
+		return ((getNodeIndex(elem)) % 2);
+	};
+
+	var pseudos = {
+		"checked": function(name, condition){
+			return function(elem){
+				// FIXME: make this more portable!!
+				return !!d.attr(elem, "checked");
+			}
+		},
+		"first-child": function(){ return _lookLeft; },
+		"last-child": function(){ return _lookRight; },
+		"only-child": function(name, condition){
+			return function(node){ 
+				if(!_lookLeft(node)){ return false; }
+				if(!_lookRight(node)){ return false; }
+				return true;
+			};
+		},
+		"empty": function(name, condition){
+			return function(elem){
+				// DomQuery and jQuery get this wrong, oddly enough.
+				// The CSS 3 selectors spec is pretty explicit about it, too.
+				var cn = elem.childNodes;
+				var cnl = elem.childNodes.length;
+				// if(!cnl){ return true; }
+				for(var x=cnl-1; x >= 0; x--){
+					var nt = cn[x].nodeType;
+					if((nt === 1)||(nt == 3)){ return false; }
+				}
+				return true;
+			}
+		},
+		"contains": function(name, condition){
+			var cz = condition.charAt(0);
+			if( cz == '"' || cz == "'" ){ //remove quote
+				condition = condition.slice(1, -1);
+			}
+			return function(elem){
+				return (elem.innerHTML.indexOf(condition) >= 0);
+			}
+		},
+		"not": function(name, condition){
+			var p = getQueryParts(condition)[0];
+			var ignores = { el: 1 }; 
+			if(p.tag != "*"){
+				ignores.tag = 1;
+			}
+			if(!p.classes.length){
+				ignores.classes = 1;
+			}
+			var ntf = getSimpleFilterFunc(p, ignores);
+			return function(elem){
+				return (!ntf(elem));
+			}
+		},
+		"nth-child": function(name, condition){
+			var pi = parseInt;
+			// avoid re-defining function objects if we can
+			if(condition == "odd"){
+				return isOdd;
+			}else if(condition == "even"){
+				return isEven;
+			}
+			// FIXME: can we shorten this?
+			if(condition.indexOf("n") != -1){
+				var tparts = condition.split("n", 2);
+				var pred = tparts[0] ? ((tparts[0] == '-') ? -1 : pi(tparts[0])) : 1;
+				var idx = tparts[1] ? pi(tparts[1]) : 0;
+				var lb = 0, ub = -1;
+				if(pred > 0){
+					if(idx < 0){
+						idx = (idx % pred) && (pred + (idx % pred));
+					}else if(idx>0){
+						if(idx >= pred){
+							lb = idx - idx % pred;
+						}
+						idx = idx % pred;
+					}
+				}else if(pred<0){
+					pred *= -1;
+					// idx has to be greater than 0 when pred is negative;
+					// shall we throw an error here?
+					if(idx > 0){
+						ub = idx;
+						idx = idx % pred;
+					}
+				}
+				if(pred > 0){
+					return function(elem){
+						var i = getNodeIndex(elem);
+						return (i>=lb) && (ub<0 || i<=ub) && ((i % pred) == idx);
+					}
+				}else{
+					condition = idx;
+				}
+			}
+			var ncount = pi(condition);
+			return function(elem){
+				return (getNodeIndex(elem) == ncount);
+			}
+		}
+	};
+
+	var defaultGetter = (d.isIE) ? function(cond){
+		var clc = cond.toLowerCase();
+		if(clc == "class"){ cond = "className"; }
+		return function(elem){
+			return (caseSensitive ? elem.getAttribute(cond) : elem[cond]||elem[clc]);
+		}
+	} : function(cond){
+		return function(elem){
+			return (elem && elem.getAttribute && elem.hasAttribute(cond));
+		}
+	};
+
+	var getSimpleFilterFunc = function(query, ignores){
+		// generates a node tester function based on the passed query part. The
+		// query part is one of the structures generatd by the query parser
+		// when it creates the query AST. The "ignores" object specifies which
+		// (if any) tests to skip, allowing the system to avoid duplicating
+		// work where it may have already been taken into account by other
+		// factors such as how the nodes to test were fetched in the first
+		// place
+		if(!query){ return yesman; }
+		ignores = ignores||{};
+
+		var ff = null;
+
+		if(!("el" in ignores)){
+			ff = agree(ff, _isElement);
+		}
+
+		if(!("tag" in ignores)){
+			if(query.tag != "*"){
+				ff = agree(ff, function(elem){
+					return (elem && (elem.tagName == query.getTag()));
+				});
+			}
+		}
+
+		if(!("classes" in ignores)){
+			each(query.classes, function(cname, idx, arr){
+				// get the class name
+				/*
+				var isWildcard = cname.charAt(cname.length-1) == "*";
+				if(isWildcard){
+					cname = cname.substr(0, cname.length-1);
+				}
+				// I dislike the regex thing, even if memozied in a cache, but it's VERY short
+				var re = new RegExp("(?:^|\\s)" + cname + (isWildcard ? ".*" : "") + "(?:\\s|$)");
+				*/
+				var re = new RegExp("(?:^|\\s)" + cname + "(?:\\s|$)");
+				ff = agree(ff, function(elem){
+					return re.test(elem.className);
+				});
+				ff.count = idx;
+			});
+		}
+
+		if(!("pseudos" in ignores)){
+			each(query.pseudos, function(pseudo){
+				var pn = pseudo.name;
+				if(pseudos[pn]){
+					ff = agree(ff, pseudos[pn](pn, pseudo.value));
+				}
+			});
+		}
+
+		if(!("attrs" in ignores)){
+			each(query.attrs, function(attr){
+				var matcher;
+				var a = attr.attr;
+				// type, attr, matchFor
+				if(attr.type && attrs[attr.type]){
+					matcher = attrs[attr.type](a, attr.matchFor);
+				}else if(a.length){
+					matcher = defaultGetter(a);
+				}
+				if(matcher){
+					ff = agree(ff, matcher);
+				}
+			});
+		}
+
+		if(!("id" in ignores)){
+			if(query.id){
+				ff = agree(ff, function(elem){ 
+					return (!!elem && (elem.id == query.id));
+				});
+			}
+		}
+
+		if(!ff){
+			if(!("default" in ignores)){
+				ff = yesman; 
+			}
+		}
+		return ff;
+	};
+
+	var _nextSibling = function(filterFunc){
+		return function(node, ret, bag){
+			while(node = node[_ns]){
+				if(_noNES && (!_isElement(node))){ continue; }
+				if(
+					(!bag || _isUnique(node, bag)) &&
+					filterFunc(node)
+				){
+					ret.push(node);
+				}
+				break;
+			}
+			return ret;
+		}
+	};
+
+	var _nextSiblings = function(filterFunc){
+		return function(root, ret, bag){
+			var te = root[_ns];
+			while(te){
+				if(_simpleNodeTest(te)){
+					if(bag && !_isUnique(te, bag)){
+						break;
+					}
+					if(filterFunc(te)){
+						ret.push(te);
+					}
+				}
+				te = te[_ns];
+			}
+			return ret;
+		}
+	};
+
+	// get an array of child *elements*, skipping text and comment nodes
+	var _childElements = function(filterFunc){
+		filterFunc = filterFunc||yesman;
+		return function(root, ret, bag){
+			// get an array of child elements, skipping text and comment nodes
+			var te, x = 0, tret = root[childNodesName];
+			while(te = tret[x++]){
+				if(
+					_simpleNodeTest(te) &&
+					(!bag || _isUnique(te, bag)) &&
+					(filterFunc(te, x))
+				){ 
+					ret.push(te);
+				}
+			}
+			return ret;
+		};
+	};
+	
+	/*
+	// thanks, Dean!
+	var itemIsAfterRoot = d.isIE ? function(item, root){
+		return (item.sourceIndex > root.sourceIndex);
+	} : function(item, root){
+		return (item.compareDocumentPosition(root) == 2);
+	};
+	*/
+
+	// test to see if node is below root
+	var _isDescendant = function(node, root){
+		var pn = node.parentNode;
+		while(pn){
+			if(pn == root){
+				break;
+			}
+			pn = pn.parentNode;
+		}
+		return !!pn;
+	};
+
+	var _getElementsFuncCache = {};
+
+	var getElementsFunc = function(query){
+		var retFunc = _getElementsFuncCache[query.query];
+		// if we've got a cached dispatcher, just use that
+		if(retFunc){ return retFunc; }
+		// else, generate a new on
+
+		// NOTE:
+		//		this function returns a function that searches for nodes and
+		//		filters them.  The search may be specialized by infix operators
+		//		(">", "~", or "+") else it will default to searching all
+		//		descendants (the " " selector). Once a group of children is
+		//		founde, a test function is applied to weed out the ones we
+		//		don't want. Many common cases can be fast-pathed. We spend a
+		//		lot of cycles to create a dispatcher that doesn't do more work
+		//		than necessary at any point since, unlike this function, the
+		//		dispatchers will be called every time. The logic of generating
+		//		efficient dispatchers looks like this in pseudo code:
+		//
+		//		# if it's a purely descendant query (no ">", "+", or "~" modifiers)
+		//		if infixOperator == " ":
+		//			if only(id):
+		//				return def(root):
+		//					return d.byId(id, root);
+		//
+		//			elif id:
+		//				return def(root):
+		//					return filter(d.byId(id, root));
+		//
+		//			elif cssClass && getElementsByClassName:
+		//				return def(root):
+		//					return filter(root.getElementsByClassName(cssClass));
+		//
+		//			elif only(tag):
+		//				return def(root):
+		//					return root.getElementsByTagName(tagName);
+		//
+		//			else:
+		//				# search by tag name, then filter
+		//				return def(root):
+		//					return filter(root.getElementsByTagName(tagName||"*"));
+		//
+		//		elif infixOperator == ">":
+		//			# search direct children
+		//			return def(root):
+		//				return filter(root.children);
+		//
+		//		elif infixOperator == "+":
+		//			# search next sibling
+		//			return def(root):
+		//				return filter(root.nextElementSibling);
+		//
+		//		elif infixOperator == "~":
+		//			# search rightward siblings
+		//			return def(root):
+		//				return filter(nextSiblings(root));
+
+		var io = query.infixOper;
+		var oper = (io ? io.oper : "");
+		// the default filter func which tests for all conditions in the query
+		// part. This is potentially inefficient, so some optimized paths may
+		// re-define it to test fewer things.
+		var filterFunc = getSimpleFilterFunc(query, { el: 1 });
+		var qt = query.tag;
+		var wildcardTag = ("*" == qt);
+		var ecs = getDoc()["getElementsByClassName"]; 
+
+		if(!oper){
+			// if there's no infix operator, then it's a descendant query. ID
+			// and "elements by class name" variants can be accelerated so we
+			// call them out explicitly:
+			if(query.id){
+				// testing shows that the overhead of yesman() is acceptable
+				// and can save us some bytes vs. re-defining the function
+				// everywhere.
+				filterFunc = (!query.loops && wildcardTag) ? 
+					yesman : 
+					getSimpleFilterFunc(query, { el: 1, id: 1 });
+
+				retFunc = function(root, arr){
+					var te = d.byId(query.id, (root.ownerDocument||root));
+					if(!te || !filterFunc(te)){ return; }
+					if(9 == root.nodeType){ // if root's a doc, we just return directly
+						return getArr(te, arr);
+					}else{ // otherwise check ancestry
+						if(_isDescendant(te, root)){
+							return getArr(te, arr);
+						}
+					}
+				}
+			}else if(
+				ecs && 
+				// isAlien check. Workaround for Prototype.js being totally evil/dumb.
+				/\{\s*\[native code\]\s*\}/.test(String(ecs)) && 
+				query.classes.length &&
+				!cssCaseBug
+			){
+				// it's a class-based query and we've got a fast way to run it.
+
+				// ignore class and ID filters since we will have handled both
+				filterFunc = getSimpleFilterFunc(query, { el: 1, classes: 1, id: 1 });
+				var classesString = query.classes.join(" ");
+				retFunc = function(root, arr, bag){
+					var ret = getArr(0, arr), te, x=0;
+					var tret = root.getElementsByClassName(classesString);
+					while((te = tret[x++])){
+						if(filterFunc(te, root) && _isUnique(te, bag)){
+							ret.push(te);
+						}
+					}
+					return ret;
+				};
+
+			}else if(!wildcardTag && !query.loops){
+				// it's tag only. Fast-path it.
+				retFunc = function(root, arr, bag){
+					var ret = getArr(0, arr), te, x=0;
+					var tret = root.getElementsByTagName(query.getTag());
+					while((te = tret[x++])){
+						if(_isUnique(te, bag)){
+							ret.push(te);
+						}
+					}
+					return ret;
+				};
+			}else{
+				// the common case:
+				//		a descendant selector without a fast path. By now it's got
+				//		to have a tag selector, even if it's just "*" so we query
+				//		by that and filter
+				filterFunc = getSimpleFilterFunc(query, { el: 1, tag: 1, id: 1 });
+				retFunc = function(root, arr, bag){
+					var ret = getArr(0, arr), te, x=0;
+					// we use getTag() to avoid case sensitivity issues
+					var tret = root.getElementsByTagName(query.getTag());
+					while((te = tret[x++])){
+						if(filterFunc(te, root) && _isUnique(te, bag)){
+							ret.push(te);
+						}
+					}
+					return ret;
+				};
+			}
+		}else{
+			// the query is scoped in some way. Instead of querying by tag we
+			// use some other collection to find candidate nodes
+			var skipFilters = { el: 1 };
+			if(wildcardTag){
+				skipFilters.tag = 1;
+			}
+			filterFunc = getSimpleFilterFunc(query, skipFilters);
+			if("+" == oper){
+				retFunc = _nextSibling(filterFunc);
+			}else if("~" == oper){
+				retFunc = _nextSiblings(filterFunc);
+			}else if(">" == oper){
+				retFunc = _childElements(filterFunc);
+			}
+		}
+		// cache it and return
+		return _getElementsFuncCache[query.query] = retFunc;
+	};
+
+	var filterDown = function(root, queryParts){
+		// NOTE:
+		//		this is the guts of the DOM query system. It takes a list of
+		//		parsed query parts and a root and finds children which match
+		//		the selector represented by the parts
+		var candidates = getArr(root), qp, x, te, qpl = queryParts.length, bag, ret;
+
+		for(var i = 0; i < qpl; i++){
+			ret = [];
+			qp = queryParts[i];
+			x = candidates.length - 1;
+			if(x > 0){
+				// if we have more than one root at this level, provide a new
+				// hash to use for checking group membership but tell the
+				// system not to post-filter us since we will already have been
+				// gauranteed to be unique
+				bag = {};
+				ret.nozip = true;
+			}
+			var gef = getElementsFunc(qp);
+			while(te = candidates[x--]){
+				// for every root, get the elements that match the descendant
+				// selector, adding them to the "ret" array and filtering them
+				// via membership in this level's bag. If there are more query
+				// parts, then this level's return will be used as the next
+				// level's candidates
+				gef(te, ret, bag);
+			}
+			if(!ret.length){ break; }
+			candidates = ret;
+		}
+		return ret;
+	};
+
+	////////////////////////////////////////////////////////////////////////
+	// the query runner
+	////////////////////////////////////////////////////////////////////////
+
+	// these are the primary caches for full-query results. The query
+	// dispatcher functions are generated then stored here for hash lookup in
+	// the future
+	var _queryFuncCacheDOM = {},
+		_queryFuncCacheQSA = {};
+
+	// this is the second level of spliting, from full-length queries (e.g.,
+	// "div.foo .bar") into simple query expressions (e.g., ["div.foo",
+	// ".bar"])
+	var getStepQueryFunc = function(query){
+		var qparts = getQueryParts(trim(query));
+
+		// if it's trivial, avoid iteration and zipping costs
+		if(qparts.length == 1){
+			// we optimize this case here to prevent dispatch further down the
+			// chain, potentially slowing things down. We could more elegantly
+			// handle this in filterDown(), but it's slower for simple things
+			// that need to be fast (e.g., "#someId").
+			var tef = getElementsFunc(qparts[0]);
+			return function(root){
+				var r = tef(root, new qlc());
+				if(r){ r.nozip = true; }
+				return r;
+			}
+		}
+
+		// otherwise, break it up and return a runner that iterates over the parts recursively
+		return function(root){
+			return filterDown(root, qparts);
+		}
+	};
+
+	// NOTES:
+	//	* we can't trust QSA for anything but document-rooted queries, so
+	//	  caching is split into DOM query evaluators and QSA query evaluators
+	//	* caching query results is dirty and leak-prone (or, at a minimum,
+	//	  prone to unbounded growth). Other toolkits may go this route, but
+	//	  they totally destroy their own ability to manage their memory
+	//	  footprint. If we implement it, it should only ever be with a fixed
+	//	  total element reference # limit and an LRU-style algorithm since JS
+	//	  has no weakref support. Caching compiled query evaluators is also
+	//	  potentially problematic, but even on large documents the size of the
+	//	  query evaluators is often < 100 function objects per evaluator (and
+	//	  LRU can be applied if it's ever shown to be an issue).
+	//	* since IE's QSA support is currently only for HTML documents and even
+	//	  then only in IE 8's "standards mode", we have to detect our dispatch
+	//	  route at query time and keep 2 separate caches. Ugg.
+
+	// we need to determine if we think we can run a given query via
+	// querySelectorAll or if we'll need to fall back on DOM queries to get
+	// there. We need a lot of information about the environment and the query
+	// to make the determiniation (e.g. does it support QSA, does the query in
+	// question work in the native QSA impl, etc.).
+	var nua = navigator.userAgent;
+	// some versions of Safari provided QSA, but it was buggy and crash-prone.
+	// We need te detect the right "internal" webkit version to make this work.
+	var wk = "WebKit/";
+	var is525 = (
+		d.isWebKit && 
+		(nua.indexOf(wk) > 0) && 
+		(parseFloat(nua.split(wk)[1]) > 528)
+	);
+
+	// IE QSA queries may incorrectly include comment nodes, so we throw the
+	// zipping function into "remove" comments mode instead of the normal "skip
+	// it" which every other QSA-clued browser enjoys
+	var noZip = d.isIE ? "commentStrip" : "nozip";
+
+	var qsa = "querySelectorAll";
+	var qsaAvail = (
+		!!getDoc()[qsa] && 
+		// see #5832
+		(!d.isSafari || (d.isSafari > 3.1) || is525 )
+	); 
+	var getQueryFunc = function(query, forceDOM){
+
+		if(qsaAvail){
+			// if we've got a cached variant and we think we can do it, run it!
+			var qsaCached = _queryFuncCacheQSA[query];
+			if(qsaCached && !forceDOM){ return qsaCached; }
+		}
+
+		// else if we've got a DOM cached variant, assume that we already know
+		// all we need to and use it
+		var domCached = _queryFuncCacheDOM[query];
+		if(domCached){ return domCached; }
+
+		// TODO: 
+		//		today we're caching DOM and QSA branches separately so we
+		//		recalc useQSA every time. If we had a way to tag root+query
+		//		efficiently, we'd be in good shape to do a global cache.
+
+		var qcz = query.charAt(0);
+		var nospace = (-1 == query.indexOf(" "));
+
+		// byId searches are wicked fast compared to QSA, even when filtering
+		// is required
+		if( (query.indexOf("#") >= 0) && (nospace) ){
+			forceDOM = true;
+		}
+
+		var useQSA = ( 
+			qsaAvail && (!forceDOM) &&
+			// as per CSS 3, we can't currently start w/ combinator:
+			//		http://www.w3.org/TR/css3-selectors/#w3cselgrammar
+			(specials.indexOf(qcz) == -1) && 
+			// IE's QSA impl sucks on pseudos
+			(!d.isIE || (query.indexOf(":") == -1)) &&
+
+			(!(cssCaseBug && (query.indexOf(".") >= 0))) &&
+
+			// FIXME:
+			//		need to tighten up browser rules on ":contains" and "|=" to
+			//		figure out which aren't good
+			(query.indexOf(":contains") == -1) &&
+			(query.indexOf("|=") == -1) // some browsers don't grok it
+		);
+
+		// TODO: 
+		//		if we've got a descendant query (e.g., "> .thinger" instead of
+		//		just ".thinger") in a QSA-able doc, but are passed a child as a
+		//		root, it should be possible to give the item a synthetic ID and
+		//		trivially rewrite the query to the form "#synid > .thinger" to
+		//		use the QSA branch
+
+
+		if(useQSA){
+			var tq = (specials.indexOf(query.charAt(query.length-1)) >= 0) ? 
+						(query + " *") : query;
+			return _queryFuncCacheQSA[query] = function(root){
+				try{
+					// the QSA system contains an egregious spec bug which
+					// limits us, effectively, to only running QSA queries over
+					// entire documents.  See:
+					//		http://ejohn.org/blog/thoughts-on-queryselectorall/
+					//	despite this, we can also handle QSA runs on simple
+					//	selectors, but we don't want detection to be expensive
+					//	so we're just checking for the presence of a space char
+					//	right now. Not elegant, but it's cheaper than running
+					//	the query parser when we might not need to
+					if(!((9 == root.nodeType) || nospace)){ throw ""; }
+					var r = root[qsa](tq);
+					// skip expensive duplication checks and just wrap in a NodeList
+					r[noZip] = true;
+					return r;
+				}catch(e){
+					// else run the DOM branch on this query, ensuring that we
+					// default that way in the future
+					return getQueryFunc(query, true)(root);
+				}
+			}
+		}else{
+			// DOM branch
+			var parts = query.split(/\s*,\s*/);
+			return _queryFuncCacheDOM[query] = ((parts.length < 2) ? 
+				// if not a compound query (e.g., ".foo, .bar"), cache and return a dispatcher
+				getStepQueryFunc(query) : 
+				// if it *is* a complex query, break it up into its
+				// constituent parts and return a dispatcher that will
+				// merge the parts when run
+				function(root){
+					var pindex = 0, // avoid array alloc for every invocation
+						ret = [],
+						tp;
+					while((tp = parts[pindex++])){
+						ret = ret.concat(getStepQueryFunc(tp)(root));
+					}
+					return ret;
+				}
+			);
+		}
+	};
+
+	var _zipIdx = 0;
+
+	// NOTE:
+	//		this function is Moo inspired, but our own impl to deal correctly
+	//		with XML in IE
+	var _nodeUID = d.isIE ? function(node){
+		if(caseSensitive){
+			// XML docs don't have uniqueID on their nodes
+			return (node.getAttribute("_uid") || node.setAttribute("_uid", ++_zipIdx) || _zipIdx);
+
+		}else{
+			return node.uniqueID;
+		}
+	} : 
+	function(node){
+		return (node._uid || (node._uid = ++_zipIdx));
+	};
+
+	// determine if a node in is unique in a "bag". In this case we don't want
+	// to flatten a list of unique items, but rather just tell if the item in
+	// question is already in the bag. Normally we'd just use hash lookup to do
+	// this for us but IE's DOM is busted so we can't really count on that. On
+	// the upside, it gives us a built in unique ID function. 
+	var _isUnique = function(node, bag){
+		if(!bag){ return 1; }
+		var id = _nodeUID(node);
+		if(!bag[id]){ return bag[id] = 1; }
+		return 0;
+	};
+
+	// attempt to efficiently determine if an item in a list is a dupe,
+	// returning a list of "uniques", hopefully in doucment order
+	var _zipIdxName = "_zipIdx";
+	var _zip = function(arr){
+		if(arr && arr.nozip){ 
+			return (qlc._wrap) ? qlc._wrap(arr) : arr;
+		}
+		// var ret = new d._queryListCtor();
+		var ret = new qlc();
+		if(!arr || !arr.length){ return ret; }
+		if(arr[0]){
+			ret.push(arr[0]);
+		}
+		if(arr.length < 2){ return ret; }
+
+		_zipIdx++;
+		
+		// we have to fork here for IE and XML docs because we can't set
+		// expandos on their nodes (apparently). *sigh*
+		if(d.isIE && caseSensitive){
+			var szidx = _zipIdx+"";
+			arr[0].setAttribute(_zipIdxName, szidx);
+			for(var x = 1, te; te = arr[x]; x++){
+				if(arr[x].getAttribute(_zipIdxName) != szidx){ 
+					ret.push(te);
+				}
+				te.setAttribute(_zipIdxName, szidx);
+			}
+		}else if(d.isIE && arr.commentStrip){
+			try{
+				for(var x = 1, te; te = arr[x]; x++){
+					if(_isElement(te)){ 
+						ret.push(te);
+					}
+				}
+			}catch(e){ /* squelch */ }
+		}else{
+			if(arr[0]){ arr[0][_zipIdxName] = _zipIdx; }
+			for(var x = 1, te; te = arr[x]; x++){
+				if(arr[x][_zipIdxName] != _zipIdx){ 
+					ret.push(te);
+				}
+				te[_zipIdxName] = _zipIdx;
+			}
+		}
+		return ret;
+	};
+
+	// the main executor
+	d.query = function(/*String*/ query, /*String|DOMNode?*/ root){
+		//	summary:
+		//		Returns nodes which match the given CSS3 selector, searching the
+		//		entire document by default but optionally taking a node to scope
+		//		the search by. Returns an instance of dojo.NodeList.
+		//	description:
+		//		dojo.query() is the swiss army knife of DOM node manipulation in
+		//		Dojo. Much like Prototype's "$$" (bling-bling) function or JQuery's
+		//		"$" function, dojo.query provides robust, high-performance
+		//		CSS-based node selector support with the option of scoping searches
+		//		to a particular sub-tree of a document.
+		//
+		//		Supported Selectors:
+		//		--------------------
+		//
+		//		dojo.query() supports a rich set of CSS3 selectors, including:
+		//
+		//			* class selectors (e.g., `.foo`)
+		//			* node type selectors like `span`
+		//			* ` ` descendant selectors
+		//			* `>` child element selectors 
+		//			* `#foo` style ID selectors
+		//			* `*` universal selector
+		//			* `~`, the immediately preceeded-by sibling selector
+		//			* `+`, the preceeded-by sibling selector
+		//			* attribute queries:
+		//			|	* `[foo]` attribute presence selector
+		//			|	* `[foo='bar']` attribute value exact match
+		//			|	* `[foo~='bar']` attribute value list item match
+		//			|	* `[foo^='bar']` attribute start match
+		//			|	* `[foo$='bar']` attribute end match
+		//			|	* `[foo*='bar']` attribute substring match
+		//			* `:first-child`, `:last-child`, and `:only-child` positional selectors
+		//			* `:empty` content emtpy selector
+		//			* `:checked` pseudo selector
+		//			* `:nth-child(n)`, `:nth-child(2n+1)` style positional calculations
+		//			* `:nth-child(even)`, `:nth-child(odd)` positional selectors
+		//			* `:not(...)` negation pseudo selectors
+		//
+		//		Any legal combination of these selectors will work with
+		//		`dojo.query()`, including compound selectors ("," delimited).
+		//		Very complex and useful searches can be constructed with this
+		//		palette of selectors and when combined with functions for
+		//		manipulation presented by dojo.NodeList, many types of DOM
+		//		manipulation operations become very straightforward.
+		//		
+		//		Unsupported Selectors:
+		//		----------------------
+		//
+		//		While dojo.query handles many CSS3 selectors, some fall outside of
+		//		what's resaonable for a programmatic node querying engine to
+		//		handle. Currently unsupported selectors include:
+		//		
+		//			* namespace-differentiated selectors of any form
+		//			* all `::` pseduo-element selectors
+		//			* certain pseduo-selectors which don't get a lot of day-to-day use:
+		//			|	* `:root`, `:lang()`, `:target`, `:focus`
+		//			* all visual and state selectors:
+		//			|	* `:root`, `:active`, `:hover`, `:visisted`, `:link`,
+		//				  `:enabled`, `:disabled`
+		//			* `:*-of-type` pseudo selectors
+		//		
+		//		dojo.query and XML Documents:
+		//		-----------------------------
+		//		
+		//		`dojo.query` (as of dojo 1.2) supports searching XML documents
+		//		in a case-sensitive manner. If an HTML document is served with
+		//		a doctype that forces case-sensitivity (e.g., XHTML 1.1
+		//		Strict), dojo.query() will detect this and "do the right
+		//		thing". Case sensitivity is dependent upon the document being
+		//		searched and not the query used. It is therefore possible to
+		//		use case-sensitive queries on strict sub-documents (iframes,
+		//		etc.) or XML documents while still assuming case-insensitivity
+		//		for a host/root document.
+		//
+		//		Non-selector Queries:
+		//		---------------------
+		//
+		//		If something other than a String is passed for the query,
+		//		`dojo.query` will return a new `dojo.NodeList` instance
+		//		constructed from that parameter alone and all further
+		//		processing will stop. This means that if you have a reference
+		//		to a node or NodeList, you can quickly construct a new NodeList
+		//		from the original by calling `dojo.query(node)` or
+		//		`dojo.query(list)`.
+		//
+		//	query:
+		//		The CSS3 expression to match against. For details on the syntax of
+		//		CSS3 selectors, see <http://www.w3.org/TR/css3-selectors/#selectors>
+		//	root:
+		//		A DOMNode (or node id) to scope the search from. Optional.
+		//	returns: dojo.NodeList
+		//		An instance of `dojo.NodeList`. Many methods are available on
+		//		NodeLists for searching, iterating, manipulating, and handling
+		//		events on the matched nodes in the returned list.
+		//	example:
+		//		search the entire document for elements with the class "foo":
+		//	|	dojo.query(".foo");
+		//		these elements will match:
+		//	|	<span class="foo"></span>
+		//	|	<span class="foo bar"></span>
+		//	|	<p class="thud foo"></p>
+		//	example:
+		//		search the entire document for elements with the classes "foo" *and* "bar":
+		//	|	dojo.query(".foo.bar");
+		//		these elements will match:
+		//	|	<span class="foo bar"></span>
+		//		while these will not:
+		//	|	<span class="foo"></span>
+		//	|	<p class="thud foo"></p>
+		//	example:
+		//		find `<span>` elements which are descendants of paragraphs and
+		//		which have a "highlighted" class:
+		//	|	dojo.query("p span.highlighted");
+		//		the innermost span in this fragment matches:
+		//	|	<p class="foo">
+		//	|		<span>...
+		//	|			<span class="highlighted foo bar">...</span>
+		//	|		</span>
+		//	|	</p>
+		//	example:
+		//		set an "odd" class on all odd table rows inside of the table
+		//		`#tabular_data`, using the `>` (direct child) selector to avoid
+		//		affecting any nested tables:
+		//	|	dojo.query("#tabular_data > tbody > tr:nth-child(odd)").addClass("odd");
+		//	example:
+		//		remove all elements with the class "error" from the document
+		//		and store them in a list:
+		//	|	var errors = dojo.query(".error").orphan();
+		//	example:
+		//		add an onclick handler to every submit button in the document
+		//		which causes the form to be sent via Ajax instead:
+		//	|	dojo.query("input[type='submit']").onclick(function(e){
+		//	|		dojo.stopEvent(e); // prevent sending the form
+		//	|		var btn = e.target;
+		//	|		dojo.xhrPost({
+		//	|			form: btn.form,
+		//	|			load: function(data){
+		//	|				// replace the form with the response
+		//	|				var div = dojo.doc.createElement("div");
+		//	|				dojo.place(div, btn.form, "after");
+		//	|				div.innerHTML = data;
+		//	|				dojo.style(btn.form, "display", "none");
+		//	|			}
+		//	|		});
+		//	|	});
+
+		//Set list constructor to desired value. This can change
+		//between calls, so always re-assign here.
+		qlc = d._queryListCtor;
+
+		if(!query){
+			return new qlc();
+		}
+
+		if(query.constructor == qlc){
+			return query;
+		}
+		if(!isString(query)){
+			return new qlc(query); // dojo.NodeList
+		}
+		if(isString(root)){
+			root = d.byId(root);
+			if(!root){ return new qlc(); }
+		}
+
+		root = root||getDoc();
+		var od = root.ownerDocument||root.documentElement;
+
+		// throw the big case sensitivity switch
+
+		// NOTE:
+		// 		Opera in XHTML mode doesn't detect case-sensitivity correctly
+		// 		and it's not clear that there's any way to test for it
+		caseSensitive = (root.contentType && root.contentType=="application/xml") || 
+						(d.isOpera && (root.doctype || od.toString() == "[object XMLDocument]")) ||
+						(!!od) && 
+						(d.isIE ? od.xml : (root.xmlVersion||od.xmlVersion));
+
+		// NOTE: 
+		//		adding "true" as the 2nd argument to getQueryFunc is useful for
+		//		testing the DOM branch without worrying about the
+		//		behavior/performance of the QSA branch.
+		var r = getQueryFunc(query)(root);
+
+		// FIXME:
+		//		need to investigate this branch WRT #8074 and #8075
+		if(r && r.nozip && !qlc._wrap){
+			return r;
+		}
+		return _zip(r); // dojo.NodeList
+	}
+
+	// FIXME: need to add infrastructure for post-filtering pseudos, ala :last
+	d.query.pseudos = pseudos;
+
+	// one-off function for filtering a NodeList based on a simple selector
+	d._filterQueryResult = function(nodeList, simpleFilter){
+		var tmpNodeList = new d._queryListCtor();
+		var filterFunc = getSimpleFilterFunc(getQueryParts(simpleFilter)[0]);
+		for(var x = 0, te; te = nodeList[x]; x++){
+			if(filterFunc(te)){ tmpNodeList.push(te); }
+		}
+		return tmpNodeList;
+	}
+})(this["queryPortability"]||this["acme"]||dojo);
+
+/*
+*/
+
+}
+
+if(!dojo._hasResource["dojo._base.xhr"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.xhr"] = true;
+dojo.provide("dojo._base.xhr");
+
+
+
+
+
+(function(){
+	var _d = dojo;
+	function setValue(/*Object*/obj, /*String*/name, /*String*/value){
+		//summary:
+		//		For the named property in object, set the value. If a value
+		//		already exists and it is a string, convert the value to be an
+		//		array of values.
+		var val = obj[name];
+		if(_d.isString(val)){
+			obj[name] = [val, value];
+		}else if(_d.isArray(val)){
+			val.push(value);
+		}else{
+			obj[name] = value;
+		}
+	}
+
+	dojo.formToObject = function(/*DOMNode||String*/ formNode){
+		// summary:
+		//		dojo.formToObject returns the values encoded in an HTML form as
+		//		string properties in an object which it then returns. Disabled form
+		//		elements, buttons, and other non-value form elements are skipped.
+		//		Multi-select elements are returned as an array of string values.
+		// description:
+		//		This form:
+		//
+		//		|	<form id="test_form">
+		//		|		<input type="text" name="blah" value="blah">
+		//		|		<input type="text" name="no_value" value="blah" disabled>
+		//		|		<input type="button" name="no_value2" value="blah">
+		//		|		<select type="select" multiple name="multi" size="5">
+		//		|			<option value="blah">blah</option>
+		//		|			<option value="thud" selected>thud</option>
+		//		|			<option value="thonk" selected>thonk</option>
+		//		|		</select>
+		//		|	</form>
+		//
+		//		yields this object structure as the result of a call to
+		//		formToObject():
+		//
+		//		|	{ 
+		//		|		blah: "blah",
+		//		|		multi: [
+		//		|			"thud",
+		//		|			"thonk"
+		//		|		]
+		//		|	};
+
+		var ret = {};
+		var exclude = "file|submit|image|reset|button|";
+		_d.forEach(dojo.byId(formNode).elements, function(item){
+			var _in = item.name;
+			var type = (item.type||"").toLowerCase();
+			if(_in && type && exclude.indexOf(type) == -1 && !item.disabled){
+				if(type == "radio" || type == "checkbox"){
+					if(item.checked){ setValue(ret, _in, item.value); }
+				}else if(item.multiple){
+					ret[_in] = [];
+					_d.query("option", item).forEach(function(opt){
+						if(opt.selected){
+							setValue(ret, _in, opt.value);
+						}
+					});
+				}else{ 
+					setValue(ret, _in, item.value);
+					if(type == "image"){
+						ret[_in+".x"] = ret[_in+".y"] = ret[_in].x = ret[_in].y = 0;
+					}
+				}
+			}
+		});
+		return ret; // Object
+	}
+
+	dojo.objectToQuery = function(/*Object*/ map){
+		//	summary:
+		//		takes a name/value mapping object and returns a string representing
+		//		a URL-encoded version of that object.
+		//	example:
+		//		this object:
+		//
+		//		|	{ 
+		//		|		blah: "blah",
+		//		|		multi: [
+		//		|			"thud",
+		//		|			"thonk"
+		//		|		]
+		//		|	};
+		//
+		//	yields the following query string:
+		//	
+		//	|	"blah=blah&multi=thud&multi=thonk"
+
+		// FIXME: need to implement encodeAscii!!
+		var enc = encodeURIComponent;
+		var pairs = [];
+		var backstop = {};
+		for(var name in map){
+			var value = map[name];
+			if(value != backstop[name]){
+				var assign = enc(name) + "=";
+				if(_d.isArray(value)){
+					for(var i=0; i < value.length; i++){
+						pairs.push(assign + enc(value[i]));
+					}
+				}else{
+					pairs.push(assign + enc(value));
+				}
+			}
+		}
+		return pairs.join("&"); // String
+	}
+
+	dojo.formToQuery = function(/*DOMNode||String*/ formNode){
+		// summary:
+		//		Returns a URL-encoded string representing the form passed as either a
+		//		node or string ID identifying the form to serialize
+		return _d.objectToQuery(_d.formToObject(formNode)); // String
+	}
+
+	dojo.formToJson = function(/*DOMNode||String*/ formNode, /*Boolean?*/prettyPrint){
+		// summary:
+		//		return a serialized JSON string from a form node or string
+		//		ID identifying the form to serialize
+		return _d.toJson(_d.formToObject(formNode), prettyPrint); // String
+	}
+
+	dojo.queryToObject = function(/*String*/ str){
+		// summary:
+		//		returns an object representing a de-serialized query section of a
+		//		URL. Query keys with multiple values are returned in an array.
+		// description:
+		//		This string:
+		//
+		//	|		"foo=bar&foo=baz&thinger=%20spaces%20=blah&zonk=blarg&"
+		//		
+		//		results in this object structure:
+		//
+		//	|		{
+		//	|			foo: [ "bar", "baz" ],
+		//	|			thinger: " spaces =blah",
+		//	|			zonk: "blarg"
+		//	|		}
+		//	
+		//		Note that spaces and other urlencoded entities are correctly
+		//		handled.
+
+		// FIXME: should we grab the URL string if we're not passed one?
+		var ret = {};
+		var qp = str.split("&");
+		var dec = decodeURIComponent;
+		_d.forEach(qp, function(item){
+			if(item.length){
+				var parts = item.split("=");
+				var name = dec(parts.shift());
+				var val = dec(parts.join("="));
+				if(_d.isString(ret[name])){
+					ret[name] = [ret[name]];
+				}
+				if(_d.isArray(ret[name])){
+					ret[name].push(val);
+				}else{
+					ret[name] = val;
+				}
+			}
+		});
+		return ret; // Object
+	}
+
+	/*
+		from refactor.txt:
+
+		all bind() replacement APIs take the following argument structure:
+
+			{
+				url: "blah.html",
+
+				// all below are optional, but must be supported in some form by
+				// every IO API
+				timeout: 1000, // milliseconds
+				handleAs: "text", // replaces the always-wrong "mimetype"
+				content: { 
+					key: "value"
+				},
+
+				// browser-specific, MAY be unsupported
+				sync: true, // defaults to false
+				form: dojo.byId("someForm") 
+			}
+	*/
+
+	// need to block async callbacks from snatching this thread as the result
+	// of an async callback might call another sync XHR, this hangs khtml forever
+	// must checked by watchInFlight()
+
+	dojo._blockAsync = false;
+
+	dojo._contentHandlers = {
+		text: function(xhr){ return xhr.responseText; },
+		json: function(xhr){
+			return _d.fromJson(xhr.responseText || null);
+		},
+		"json-comment-filtered": function(xhr){ 
+			// NOTE: the json-comment-filtered option was implemented to prevent
+			// "JavaScript Hijacking", but it is less secure than standard JSON. Use
+			// standard JSON instead. JSON prefixing can be used to subvert hijacking.
+			if(!dojo.config.useCommentedJson){
+				console.warn("Consider using the standard mimetype:application/json."
+					+ " json-commenting can introduce security issues. To"
+					+ " decrease the chances of hijacking, use the standard the 'json' handler and"
+					+ " prefix your json with: {}&&\n"
+					+ "Use djConfig.useCommentedJson=true to turn off this message.");
+			}
+
+			var value = xhr.responseText;
+			var cStartIdx = value.indexOf("\/*");
+			var cEndIdx = value.lastIndexOf("*\/");
+			if(cStartIdx == -1 || cEndIdx == -1){
+				throw new Error("JSON was not comment filtered");
+			}
+			return _d.fromJson(value.substring(cStartIdx+2, cEndIdx));
+		},
+		javascript: function(xhr){ 
+			// FIXME: try Moz and IE specific eval variants?
+			return _d.eval(xhr.responseText);
+		},
+		xml: function(xhr){
+			var result = xhr.responseXML;
+						if(_d.isIE && (!result || !result.documentElement)){
+				var ms = function(n){ return "MSXML" + n + ".DOMDocument"; }
+				var dp = ["Microsoft.XMLDOM", ms(6), ms(4), ms(3), ms(2)];
+				_d.some(dp, function(p){
+					try{
+						var dom = new ActiveXObject(p);
+						dom.async = false;
+						dom.loadXML(xhr.responseText);
+						result = dom;
+					}catch(e){ return false; }
+					return true;
+				});
+			}
+						return result; // DOMDocument
+		}
+	};
+
+	dojo._contentHandlers["json-comment-optional"] = function(xhr){
+		var handlers = _d._contentHandlers;
+		if(xhr.responseText && xhr.responseText.indexOf("\/*") != -1){
+			return handlers["json-comment-filtered"](xhr);
+		}else{
+			return handlers["json"](xhr);
+		}
+	};
+
+	/*=====
+	dojo.__IoArgs = function(){
+		//	url: String
+		//		URL to server endpoint.
+		//	content: Object?
+		//		Contains properties with string values. These
+		//		properties will be serialized as name1=value2 and
+		//		passed in the request.
+		//	timeout: Integer?
+		//		Milliseconds to wait for the response. If this time
+		//		passes, the then error callbacks are called.
+		//	form: DOMNode?
+		//		DOM node for a form. Used to extract the form values
+		//		and send to the server.
+		//	preventCache: Boolean?
+		//		Default is false. If true, then a
+		//		"dojo.preventCache" parameter is sent in the request
+		//		with a value that changes with each request
+		//		(timestamp). Useful only with GET-type requests.
+		//	handleAs: String?
+		//		Acceptable values depend on the type of IO
+		//		transport (see specific IO calls for more information).
+		//	load: Function?
+		//		function(response, ioArgs){} response is of type Object, ioArgs
+		//		is of type dojo.__IoCallbackArgs.  This function will be
+		//		called on a successful HTTP response code.
+		//	error: Function?
+		//		function(response, ioArgs){} response is of type Object, ioArgs
+		//		is of type dojo.__IoCallbackArgs. This function will
+		//		be called when the request fails due to a network or server error, the url
+		//		is invalid, etc. It will also be called if the load or handle callback throws an
+		//		exception, unless djConfig.debugAtAllCosts is true.  This allows deployed applications
+		//		to continue to run even when a logic error happens in the callback, while making
+		//		it easier to troubleshoot while in debug mode.
+		//	handle: Function?
+		//		function(response, ioArgs){} response is of type Object, ioArgs
+		//		is of type dojo.__IoCallbackArgs.  This function will
+		//		be called at the end of every request, whether or not an error occurs.
+		this.url = url;
+		this.content = content;
+		this.timeout = timeout;
+		this.form = form;
+		this.preventCache = preventCache;
+		this.handleAs = handleAs;
+		this.load = load;
+		this.error = error;
+		this.handle = handle;
+	}
+	=====*/
+
+	/*=====
+	dojo.__IoCallbackArgs = function(args, xhr, url, query, handleAs, id, canDelete, json){
+		//	args: Object
+		//		the original object argument to the IO call.
+		//	xhr: XMLHttpRequest
+		//		For XMLHttpRequest calls only, the
+		//		XMLHttpRequest object that was used for the
+		//		request.
+		//	url: String
+		//		The final URL used for the call. Many times it
+		//		will be different than the original args.url
+		//		value.
+		//	query: String
+		//		For non-GET requests, the
+		//		name1=value1&name2=value2 parameters sent up in
+		//		the request.
+		//	handleAs: String
+		//		The final indicator on how the response will be
+		//		handled.
+		//	id: String
+		//		For dojo.io.script calls only, the internal
+		//		script ID used for the request.
+		//	canDelete: Boolean
+		//		For dojo.io.script calls only, indicates
+		//		whether the script tag that represents the
+		//		request can be deleted after callbacks have
+		//		been called. Used internally to know when
+		//		cleanup can happen on JSONP-type requests.
+		//	json: Object
+		//		For dojo.io.script calls only: holds the JSON
+		//		response for JSONP-type requests. Used
+		//		internally to hold on to the JSON responses.
+		//		You should not need to access it directly --
+		//		the same object should be passed to the success
+		//		callbacks directly.
+		this.args = args;
+		this.xhr = xhr;
+		this.url = url;
+		this.query = query;
+		this.handleAs = handleAs;
+		this.id = id;
+		this.canDelete = canDelete;
+		this.json = json;
+	}
+	=====*/
+
+
+
+	dojo._ioSetArgs = function(/*dojo.__IoArgs*/args,
+			/*Function*/canceller,
+			/*Function*/okHandler,
+			/*Function*/errHandler){
+		//	summary: 
+		//		sets up the Deferred and ioArgs property on the Deferred so it
+		//		can be used in an io call.
+		//	args:
+		//		The args object passed into the public io call. Recognized properties on
+		//		the args object are:
+		//	canceller:
+		//		The canceller function used for the Deferred object. The function
+		//		will receive one argument, the Deferred object that is related to the
+		//		canceller.
+		//	okHandler:
+		//		The first OK callback to be registered with Deferred. It has the opportunity
+		//		to transform the OK response. It will receive one argument -- the Deferred
+		//		object returned from this function.
+		//	errHandler:
+		//		The first error callback to be registered with Deferred. It has the opportunity
+		//		to do cleanup on an error. It will receive two arguments: error (the 
+		//		Error object) and dfd, the Deferred object returned from this function.
+
+		var ioArgs = {args: args, url: args.url};
+
+		//Get values from form if requestd.
+		var formObject = null;
+		if(args.form){ 
+			var form = _d.byId(args.form);
+			//IE requires going through getAttributeNode instead of just getAttribute in some form cases, 
+			//so use it for all.  See #2844
+			var actnNode = form.getAttributeNode("action");
+			ioArgs.url = ioArgs.url || (actnNode ? actnNode.value : null); 
+			formObject = _d.formToObject(form);
+		}
+
+		// set up the query params
+		var miArgs = [{}];
+	
+		if(formObject){
+			// potentially over-ride url-provided params w/ form values
+			miArgs.push(formObject);
+		}
+		if(args.content){
+			// stuff in content over-rides what's set by form
+			miArgs.push(args.content);
+		}
+		if(args.preventCache){
+			miArgs.push({"dojo.preventCache": new Date().valueOf()});
+		}
+		ioArgs.query = _d.objectToQuery(_d.mixin.apply(null, miArgs));
+	
+		// .. and the real work of getting the deferred in order, etc.
+		ioArgs.handleAs = args.handleAs || "text";
+		var d = new _d.Deferred(canceller);
+		d.addCallbacks(okHandler, function(error){
+			return errHandler(error, d);
+		});
+
+		//Support specifying load, error and handle callback functions from the args.
+		//For those callbacks, the "this" object will be the args object.
+		//The callbacks will get the deferred result value as the
+		//first argument and the ioArgs object as the second argument.
+		var ld = args.load;
+		if(ld && _d.isFunction(ld)){
+			d.addCallback(function(value){
+				return ld.call(args, value, ioArgs);
+			});
+		}
+		var err = args.error;
+		if(err && _d.isFunction(err)){
+			d.addErrback(function(value){
+				return err.call(args, value, ioArgs);
+			});
+		}
+		var handle = args.handle;
+		if(handle && _d.isFunction(handle)){
+			d.addBoth(function(value){
+				return handle.call(args, value, ioArgs);
+			});
+		}
+		
+		d.ioArgs = ioArgs;
+	
+		// FIXME: need to wire up the xhr object's abort method to something
+		// analagous in the Deferred
+		return d;
+	}
+
+	var _deferredCancel = function(/*Deferred*/dfd){
+		//summary: canceller function for dojo._ioSetArgs call.
+		
+		dfd.canceled = true;
+		var xhr = dfd.ioArgs.xhr;
+		var _at = typeof xhr.abort;
+		if(_at == "function" || _at == "object" || _at == "unknown"){
+			xhr.abort();
+		}
+		var err = dfd.ioArgs.error;
+		if(!err){
+			err = new Error("xhr cancelled");
+			err.dojoType="cancel";
+		}
+		return err;
+	}
+	var _deferredOk = function(/*Deferred*/dfd){
+		//summary: okHandler function for dojo._ioSetArgs call.
+
+		var ret = _d._contentHandlers[dfd.ioArgs.handleAs](dfd.ioArgs.xhr);
+		return ret === undefined ? null : ret;
+	}
+	var _deferError = function(/*Error*/error, /*Deferred*/dfd){
+		//summary: errHandler function for dojo._ioSetArgs call.
+
+		console.error(error);
+		return error;
+	}
+
+	// avoid setting a timer per request. It degrades performance on IE
+	// something fierece if we don't use unified loops.
+	var _inFlightIntvl = null;
+	var _inFlight = [];
+	var _watchInFlight = function(){
+		//summary: 
+		//		internal method that checks each inflight XMLHttpRequest to see
+		//		if it has completed or if the timeout situation applies.
+		
+		var now = (new Date()).getTime();
+		// make sure sync calls stay thread safe, if this callback is called
+		// during a sync call and this results in another sync call before the
+		// first sync call ends the browser hangs
+		if(!_d._blockAsync){
+			// we need manual loop because we often modify _inFlight (and therefore 'i') while iterating
+			// note: the second clause is an assigment on purpose, lint may complain
+			for(var i = 0, tif; i < _inFlight.length && (tif = _inFlight[i]); i++){
+				var dfd = tif.dfd;
+				var func = function(){
+					if(!dfd || dfd.canceled || !tif.validCheck(dfd)){
+						_inFlight.splice(i--, 1); 
+					}else if(tif.ioCheck(dfd)){
+						_inFlight.splice(i--, 1);
+						tif.resHandle(dfd);
+					}else if(dfd.startTime){
+						//did we timeout?
+						if(dfd.startTime + (dfd.ioArgs.args.timeout || 0) < now){
+							_inFlight.splice(i--, 1);
+							var err = new Error("timeout exceeded");
+							err.dojoType = "timeout";
+							dfd.errback(err);
+							//Cancel the request so the io module can do appropriate cleanup.
+							dfd.cancel();
+						}
+					}
+				};
+				if(dojo.config.debugAtAllCosts){
+					func.call(this);
+				}else{
+					try{
+						func.call(this);
+					}catch(e){
+						dfd.errback(e);
+					}
+				}
+			}
+		}
+
+		if(!_inFlight.length){
+			clearInterval(_inFlightIntvl);
+			_inFlightIntvl = null;
+			return;
+		}
+
+	}
+
+	dojo._ioCancelAll = function(){
+		//summary: Cancels all pending IO requests, regardless of IO type
+		//(xhr, script, iframe).
+		try{
+			_d.forEach(_inFlight, function(i){
+				try{
+					i.dfd.cancel();
+				}catch(e){/*squelch*/}
+			});
+		}catch(e){/*squelch*/}
+	}
+
+	//Automatically call cancel all io calls on unload
+	//in IE for trac issue #2357.
+		if(_d.isIE){
+		_d.addOnWindowUnload(_d._ioCancelAll);
+	}
+	
+	_d._ioWatch = function(/*Deferred*/dfd,
+		/*Function*/validCheck,
+		/*Function*/ioCheck,
+		/*Function*/resHandle){
+		//summary: watches the io request represented by dfd to see if it completes.
+		//dfd:
+		//		The Deferred object to watch.
+		//validCheck:
+		//		Function used to check if the IO request is still valid. Gets the dfd
+		//		object as its only argument.
+		//ioCheck:
+		//		Function used to check if basic IO call worked. Gets the dfd
+		//		object as its only argument.
+		//resHandle:
+		//		Function used to process response. Gets the dfd
+		//		object as its only argument.
+		var args = dfd.ioArgs.args;
+		if(args.timeout){
+			dfd.startTime = (new Date()).getTime();
+		}
+		_inFlight.push({dfd: dfd, validCheck: validCheck, ioCheck: ioCheck, resHandle: resHandle});
+		if(!_inFlightIntvl){
+			_inFlightIntvl = setInterval(_watchInFlight, 50);
+		}
+		// handle sync requests
+		//A weakness: async calls in flight
+		//could have their handlers called as part of the
+		//_watchInFlight call, before the sync's callbacks
+		// are called.
+		if(args.sync){
+			_watchInFlight();
+		}
+	}
+
+	var _defaultContentType = "application/x-www-form-urlencoded";
+
+	var _validCheck = function(/*Deferred*/dfd){
+		return dfd.ioArgs.xhr.readyState; //boolean
+	}
+	var _ioCheck = function(/*Deferred*/dfd){
+		return 4 == dfd.ioArgs.xhr.readyState; //boolean
+	}
+	var _resHandle = function(/*Deferred*/dfd){
+		var xhr = dfd.ioArgs.xhr;
+		if(_d._isDocumentOk(xhr)){
+			dfd.callback(dfd);
+		}else{
+			var err = new Error("Unable to load " + dfd.ioArgs.url + " status:" + xhr.status);
+			err.status = xhr.status;
+			err.responseText = xhr.responseText;
+			dfd.errback(err);
+		}
+	}
+
+	dojo._ioAddQueryToUrl = function(/*dojo.__IoCallbackArgs*/ioArgs){
+		//summary: Adds query params discovered by the io deferred construction to the URL.
+		//Only use this for operations which are fundamentally GET-type operations.
+		if(ioArgs.query.length){
+			ioArgs.url += (ioArgs.url.indexOf("?") == -1 ? "?" : "&") + ioArgs.query;
+			ioArgs.query = null;
+		}		
+	}
+
+	/*=====
+	dojo.declare("dojo.__XhrArgs", dojo.__IoArgs, {
+		constructor: function(){
+			//	summary:
+			//		In addition to the properties listed for the dojo._IoArgs type,
+			//		the following properties are allowed for dojo.xhr* methods.
+			//	handleAs: String?
+			//		Acceptable values are: text (default), json, json-comment-optional,
+			//		json-comment-filtered, javascript, xml
+			//	sync: Boolean?
+			//		false is default. Indicates whether the request should
+			//		be a synchronous (blocking) request.
+			//	headers: Object?
+			//		Additional HTTP headers to send in the request.
+			this.handleAs = handleAs;
+			this.sync = sync;
+			this.headers = headers;
+		}
+	});
+	=====*/
+
+	dojo.xhr = function(/*String*/ method, /*dojo.__XhrArgs*/ args, /*Boolean?*/ hasBody){
+		//	summary:
+		//		Sends an HTTP request with the given method.
+		//	description:
+		//		Sends an HTTP request with the given method.
+		//		See also dojo.xhrGet(), xhrPost(), xhrPut() and dojo.xhrDelete() for shortcuts
+		//		for those HTTP methods. There are also methods for "raw" PUT and POST methods
+		//		via dojo.rawXhrPut() and dojo.rawXhrPost() respectively.
+		//	method:
+		//		HTTP method to be used, such as GET, POST, PUT, DELETE.  Should be uppercase.
+		//	hasBody:
+		//		If the request has an HTTP body, then pass true for hasBody.
+
+		//Make the Deferred object for this xhr request.
+		var dfd = _d._ioSetArgs(args, _deferredCancel, _deferredOk, _deferError);
+
+		//Pass the args to _xhrObj, to allow xhr iframe proxy interceptions.
+		dfd.ioArgs.xhr = _d._xhrObj(dfd.ioArgs.args);
+
+		if(hasBody){
+			if("postData" in args){
+				dfd.ioArgs.query = args.postData;
+			}else if("putData" in args){
+				dfd.ioArgs.query = args.putData;
+			}
+		}else{
+			_d._ioAddQueryToUrl(dfd.ioArgs);
+		}
+
+		// IE 6 is a steaming pile. It won't let you call apply() on the native function (xhr.open).
+		// workaround for IE6's apply() "issues"
+		var ioArgs = dfd.ioArgs;
+		var xhr = ioArgs.xhr;
+		xhr.open(method, ioArgs.url, args.sync !== true, args.user || undefined, args.password || undefined);
+		if(args.headers){
+			for(var hdr in args.headers){
+				if(hdr.toLowerCase() === "content-type" && !args.contentType){
+					args.contentType = args.headers[hdr];
+				}else{
+					xhr.setRequestHeader(hdr, args.headers[hdr]);
+				}
+			}
+		}
+		// FIXME: is this appropriate for all content types?
+		xhr.setRequestHeader("Content-Type", args.contentType || _defaultContentType);
+		if(!args.headers || !args.headers["X-Requested-With"]){
+			xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+		}
+		// FIXME: set other headers here!
+		if(dojo.config.debugAtAllCosts){
+			xhr.send(ioArgs.query);
+		}else{
+			try{
+				xhr.send(ioArgs.query);
+			}catch(e){
+				dfd.ioArgs.error = e;
+				dfd.cancel();
+			}
+		}
+		_d._ioWatch(dfd, _validCheck, _ioCheck, _resHandle);
+		xhr = null;
+		return dfd; // dojo.Deferred
+	}
+
+	dojo.xhrGet = function(/*dojo.__XhrArgs*/ args){
+		//	summary: 
+		//		Sends an HTTP GET request to the server.
+		return _d.xhr("GET", args); // dojo.Deferred
+	}
+
+	dojo.rawXhrPost = dojo.xhrPost = function(/*dojo.__XhrArgs*/ args){
+		//	summary:
+		//		Sends an HTTP POST request to the server. In addtion to the properties
+		//		listed for the dojo.__XhrArgs type, the following property is allowed:
+		//	postData:
+		//		String. Send raw data in the body of the POST request.
+		return _d.xhr("POST", args, true); // dojo.Deferred
+	}
+
+	dojo.rawXhrPut = dojo.xhrPut = function(/*dojo.__XhrArgs*/ args){
+		//	summary:
+		//		Sends an HTTP PUT request to the server. In addtion to the properties
+		//		listed for the dojo.__XhrArgs type, the following property is allowed:
+		//	putData:
+		//		String. Send raw data in the body of the PUT request.
+		return _d.xhr("PUT", args, true); // dojo.Deferred
+	}
+
+	dojo.xhrDelete = function(/*dojo.__XhrArgs*/ args){
+		//	summary:
+		//		Sends an HTTP DELETE request to the server.
+		return _d.xhr("DELETE", args); //dojo.Deferred
+	}
+
+	/*
+	dojo.wrapForm = function(formNode){
+		//summary:
+		//		A replacement for FormBind, but not implemented yet.
+
+		// FIXME: need to think harder about what extensions to this we might
+		// want. What should we allow folks to do w/ this? What events to
+		// set/send?
+		throw new Error("dojo.wrapForm not yet implemented");
+	}
+	*/
+})();
+
+}
+
+if(!dojo._hasResource["dojo._base.fx"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.fx"] = true;
+dojo.provide("dojo._base.fx");
+
+
+
+
+
+
+/*
+	Animation losely package based on Dan Pupius' work, contributed under CLA: 
+		http://pupius.co.uk/js/Toolkit.Drawing.js
+*/
+(function(){ 
+
+	var d = dojo;
+	var _mixin = d.mixin;
+	
+	dojo._Line = function(/*int*/ start, /*int*/ end){
+		//	summary:
+		//		dojo._Line is the object used to generate values from a start value
+		//		to an end value
+		//	start: int
+		//		Beginning value for range
+		//	end: int
+		//		Ending value for range
+		this.start = start;
+		this.end = end;
+	}
+	dojo._Line.prototype.getValue = function(/*float*/ n){
+		//	summary: Returns the point on the line
+		//	n: a floating point number greater than 0 and less than 1
+		return ((this.end - this.start) * n) + this.start; // Decimal
+	}
+	
+	d.declare("dojo._Animation", null, {
+		//	summary
+		//		A generic animation class that fires callbacks into its handlers
+		//		object at various states. Nearly all dojo animation functions
+		//		return an instance of this method, usually without calling the
+		//		.play() method beforehand. Therefore, you will likely need to
+		//		call .play() on instances of dojo._Animation when one is
+		//		returned.
+		constructor: function(/*Object*/ args){
+			_mixin(this, args);
+			if(d.isArray(this.curve)){
+				/* curve: Array
+					pId: a */
+				this.curve = new d._Line(this.curve[0], this.curve[1]);
+			}
+		},
+		
+		// duration: Integer
+		//	The time in milliseonds the animation will take to run
+		duration: 350,
+	
+	/*=====
+		// curve: dojo._Line||Array
+		//	A two element array of start and end values, or a dojo._Line instance to be
+		//	used in the Animation. 
+		curve: null,
+	
+		// easing: Function
+		//	A Function to adjust the acceleration (or deceleration) of the progress 
+		//	across a dojo._Line
+		easing: null,
+	=====*/
+	
+		// repeat: Integer
+		//	The number of times to loop the animation
+		repeat: 0,
+	
+		// rate: Integer
+		//	the time in milliseconds to wait before advancing to next frame 
+		//	(used as a fps timer: rate/1000 = fps)
+		rate: 10 /* 100 fps */,
+	
+	/*===== 
+		// delay: Integer
+		// 	The time in milliseconds to wait before starting animation after it has been .play()'ed
+		delay: null,
+	
+		// events
+		//
+		// beforeBegin: Event
+		//	Synthetic event fired before a dojo._Animation begins playing (synchronous)
+		beforeBegin: null,
+	
+		// onBegin: Event
+		//	Synthetic event fired as a dojo._Animation begins playing (useful?)
+		onBegin: null,
+	
+		// onAnimate: Event
+		//	Synthetic event fired at each interval of a dojo._Animation
+		onAnimate: null,
+	
+		// onEnd: Event
+		//	Synthetic event fired after the final frame of a dojo._Animation
+		onEnd: null,
+	
+		// onPlay: Event
+		//	Synthetic event fired any time a dojo._Animation is play()'ed
+		onPlay: null,
+	
+		// onPause: Event
+		//	Synthetic event fired when a dojo._Animation is paused
+		onPause: null,
+	
+		// onStop: Event
+		//	Synthetic event fires when a dojo._Animation is stopped
+		onStop: null,
+	
+	=====*/
+	
+		_percent: 0,
+		_startRepeatCount: 0,
+	
+		_fire: function(/*Event*/ evt, /*Array?*/ args){
+			//	summary:
+			//		Convenience function.  Fire event "evt" and pass it the
+			//		arguments specified in "args".
+			//	evt:
+			//		The event to fire.
+			//	args:
+			//		The arguments to pass to the event.
+			if(this[evt]){
+				if(dojo.config.debugAtAllCosts){
+					this[evt].apply(this, args||[]);
+				}else{
+					try{
+						this[evt].apply(this, args||[]);
+					}catch(e){
+						// squelch and log because we shouldn't allow exceptions in
+						// synthetic event handlers to cause the internal timer to run
+						// amuck, potentially pegging the CPU. I'm not a fan of this
+						// squelch, but hopefully logging will make it clear what's
+						// going on
+						console.error("exception in animation handler for:", evt);
+						console.error(e);
+					}
+				}
+			}
+			return this; // dojo._Animation
+		},
+
+		play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
+			// summary:
+			//		Start the animation.
+			// delay:
+			//		How many milliseconds to delay before starting.
+			// gotoStart:
+			//		If true, starts the animation from the beginning; otherwise,
+			//		starts it from its current position.
+			var _t = this;
+			if(_t._delayTimer){ _t._clearTimer(); }
+			if(gotoStart){
+				_t._stopTimer();
+				_t._active = _t._paused = false;
+				_t._percent = 0;
+			}else if(_t._active && !_t._paused){
+				return _t; // dojo._Animation
+			}
+	
+			_t._fire("beforeBegin");
+	
+			var de = delay || _t.delay,
+				_p = dojo.hitch(_t, "_play", gotoStart);
+				
+			if(de > 0){
+				_t._delayTimer = setTimeout(_p, de);
+				return _t; // dojo._Animation
+			}
+			_p();
+			return _t;
+		},
+	
+		_play: function(gotoStart){
+			var _t = this;
+			if(_t._delayTimer){ _t._clearTimer(); }
+			_t._startTime = new Date().valueOf();
+			if(_t._paused){
+				_t._startTime -= _t.duration * _t._percent;
+			}
+			_t._endTime = _t._startTime + _t.duration;
+	
+			_t._active = true;
+			_t._paused = false;
+	
+			var value = _t.curve.getValue(_t._percent);
+			if(!_t._percent){
+				if(!_t._startRepeatCount){
+					_t._startRepeatCount = _t.repeat;
+				}
+				_t._fire("onBegin", [value]);
+			}
+	
+			_t._fire("onPlay", [value]);
+	
+			_t._cycle();
+			return _t; // dojo._Animation
+		},
+	
+		pause: function(){
+			// summary: Pauses a running animation.
+			var _t = this;
+			if(_t._delayTimer){ _t._clearTimer(); }
+			_t._stopTimer();
+			if(!_t._active){ return _t; /*dojo._Animation*/ }
+			_t._paused = true;
+			_t._fire("onPause", [_t.curve.getValue(_t._percent)]);
+			return _t; // dojo._Animation
+		},
+	
+		gotoPercent: function(/*Decimal*/ percent, /*Boolean?*/ andPlay){
+			//	summary:
+			//		Sets the progress of the animation.
+			//	percent:
+			//		A percentage in decimal notation (between and including 0.0 and 1.0).
+			//	andPlay:
+			//		If true, play the animation after setting the progress.
+			var _t = this;
+			_t._stopTimer();
+			_t._active = _t._paused = true;
+			_t._percent = percent;
+			if(andPlay){ _t.play(); }
+			return _t; // dojo._Animation
+		},
+	
+		stop: function(/*boolean?*/ gotoEnd){
+			// summary: Stops a running animation.
+			// gotoEnd: If true, the animation will end.
+			var _t = this;
+			if(_t._delayTimer){ _t._clearTimer(); }
+			if(!_t._timer){ return _t; /* dojo._Animation */ }
+			_t._stopTimer();
+			if(gotoEnd){
+				_t._percent = 1;
+			}
+			_t._fire("onStop", [_t.curve.getValue(_t._percent)]);
+			_t._active = _t._paused = false;
+			return _t; // dojo._Animation
+		},
+	
+		status: function(){
+			// summary: Returns a string token representation of the status of
+			//			the animation, one of: "paused", "playing", "stopped"
+			if(this._active){
+				return this._paused ? "paused" : "playing"; // String
+			}
+			return "stopped"; // String
+		},
+	
+		_cycle: function(){
+			var _t = this;
+			if(_t._active){
+				var curr = new Date().valueOf();
+				var step = (curr - _t._startTime) / (_t._endTime - _t._startTime);
+	
+				if(step >= 1){
+					step = 1;
+				}
+				_t._percent = step;
+	
+				// Perform easing
+				if(_t.easing){
+					step = _t.easing(step);
+				}
+	
+				_t._fire("onAnimate", [_t.curve.getValue(step)]);
+	
+				if(_t._percent < 1){
+					_t._startTimer();
+				}else{
+					_t._active = false;
+	
+					if(_t.repeat > 0){
+						_t.repeat--;
+						_t.play(null, true);
+					}else if(_t.repeat == -1){
+						_t.play(null, true);
+					}else{
+						if(_t._startRepeatCount){
+							_t.repeat = _t._startRepeatCount;
+							_t._startRepeatCount = 0;
+						}
+					}
+					_t._percent = 0;
+					_t._fire("onEnd");
+					_t._stopTimer();
+				}
+			}
+			return _t; // dojo._Animation
+		},
+		
+		_clearTimer: function(){
+			// summary: Clear the play delay timer
+			clearTimeout(this._delayTimer);
+			delete this._delayTimer;
+		}
+		
+	});
+
+	var ctr = 0,
+		_globalTimerList = [],
+		timer = null,
+		runner = {
+			run: function(){ }
+		};
+
+	dojo._Animation.prototype._startTimer = function(){
+		// this._timer = setTimeout(dojo.hitch(this, "_cycle"), this.rate);
+		if(!this._timer){
+			this._timer = d.connect(runner, "run", this, "_cycle");
+			ctr++;
+		}
+		if(!timer){
+			timer = setInterval(d.hitch(runner, "run"), this.rate);
+		}
+	};
+
+	dojo._Animation.prototype._stopTimer = function(){
+		if(this._timer){
+			d.disconnect(this._timer);
+			this._timer = null;
+			ctr--;
+		}
+		if(ctr <= 0){
+			clearInterval(timer);
+			timer = null;
+			ctr = 0;
+		}
+	};
+
+	var _makeFadeable = 
+				d.isIE ? function(node){
+			// only set the zoom if the "tickle" value would be the same as the
+			// default
+			var ns = node.style;
+			// don't set the width to auto if it didn't already cascade that way.
+			// We don't want to f anyones designs
+			if(!ns.width.length && d.style(node, "width") == "auto"){
+				ns.width = "auto";
+			}
+		} : 
+				function(){};
+
+	dojo._fade = function(/*Object*/ args){
+		//	summary: 
+		//		Returns an animation that will fade the node defined by
+		//		args.node from the start to end values passed (args.start
+		//		args.end) (end is mandatory, start is optional)
+
+		args.node = d.byId(args.node);
+		var fArgs = _mixin({ properties: {} }, args),
+		 	props = (fArgs.properties.opacity = {});
+		
+		props.start = !("start" in fArgs) ?
+			function(){ 
+				return +d.style(fArgs.node, "opacity")||0; 
+			} : fArgs.start;
+		props.end = fArgs.end;
+
+		var anim = d.animateProperty(fArgs);
+		d.connect(anim, "beforeBegin", d.partial(_makeFadeable, fArgs.node));
+
+		return anim; // dojo._Animation
+	}
+
+	/*=====
+	dojo.__FadeArgs = function(node, duration, easing){
+		// 	node: DOMNode|String
+		//		The node referenced in the animation
+		//	duration: Integer?
+		//		Duration of the animation in milliseconds.
+		//	easing: Function?
+		//		An easing function.
+		this.node = node;
+		this.duration = duration;
+		this.easing = easing;
+	}
+	=====*/
+
+	dojo.fadeIn = function(/*dojo.__FadeArgs*/ args){
+		// summary: 
+		//		Returns an animation that will fade node defined in 'args' from
+		//		its current opacity to fully opaque.
+		return d._fade(_mixin({ end: 1 }, args)); // dojo._Animation
+	}
+
+	dojo.fadeOut = function(/*dojo.__FadeArgs*/  args){
+		// summary: 
+		//		Returns an animation that will fade node defined in 'args'
+		//		from its current opacity to fully transparent.
+		return d._fade(_mixin({ end: 0 }, args)); // dojo._Animation
+	}
+
+	dojo._defaultEasing = function(/*Decimal?*/ n){
+		// summary: The default easing function for dojo._Animation(s)
+		return 0.5 + ((Math.sin((n + 1.5) * Math.PI))/2);
+	}
+
+	var PropLine = function(properties){
+		// PropLine is an internal class which is used to model the values of
+		// an a group of CSS properties across an animation lifecycle. In
+		// particular, the "getValue" function handles getting interpolated
+		// values between start and end for a particular CSS value.
+		this._properties = properties;
+		for(var p in properties){
+			var prop = properties[p];
+			if(prop.start instanceof d.Color){
+				// create a reusable temp color object to keep intermediate results
+				prop.tempColor = new d.Color();
+			}
+		}
+	}
+
+	PropLine.prototype.getValue = function(r){
+		var ret = {};
+		for(var p in this._properties){
+			var prop = this._properties[p],
+				start = prop.start;
+			if(start instanceof d.Color){
+				ret[p] = d.blendColors(start, prop.end, r, prop.tempColor).toCss();
+			}else if(!d.isArray(start)){
+				ret[p] = ((prop.end - start) * r) + start + (p != "opacity" ? prop.units || "px" : 0);
+			}
+		}
+		return ret;
+	}
+
+	/*=====
+	dojo.declare("dojo.__AnimArgs", [dojo.__FadeArgs], {
+		// Properties: Object?
+		//	A hash map of style properties to Objects describing the transition,
+		//	such as the properties of dojo._Line with an additional 'unit' property
+		properties: {}
+		
+		//TODOC: add event callbacks
+	});
+	=====*/
+
+	dojo.animateProperty = function(/*dojo.__AnimArgs*/ args){
+		//	summary: 
+		//		Returns an animation that will transition the properties of
+		//		node defined in 'args' depending how they are defined in
+		//		'args.properties'
+		//
+		// description:
+		//		dojo.animateProperty is the foundation of most dojo.fx
+		//		animations. It takes an object of "properties" corresponding to
+		//		style properties, and animates them in parallel over a set
+		//		duration.
+		//	
+		// 	example:
+		//		A simple animation that changes the width of the specified node.
+		//	|	dojo.animateProperty({ 
+		//	|		node: "nodeId",
+		//	|		properties: { width: 400 },
+		//	|	}).play();
+		//		Dojo figures out the start value for the width and converts the
+		//		integer specified for the width to the more expressive but
+		//		verbose form `{ width: { end: '400', units: 'px' } }` which you
+		//		can also specify directly
+		//
+		// 	example:
+		//		Animate width, height, and padding over 2 seconds... the
+		//		pedantic way:
+		//	|	dojo.animateProperty({ node: node, duration:2000,
+		//	|		properties: {
+		//	|			width: { start: '200', end: '400', unit:"px" },
+		//	|			height: { start:'200', end: '400', unit:"px" },
+		//	|			paddingTop: { start:'5', end:'50', unit:"px" } 
+		//	|		}
+		//	|	}).play();
+		//		Note 'paddingTop' is used over 'padding-top'. Multi-name CSS properties
+		//		are written using "mixed case", as the hyphen is illegal as an object key.
+		//		
+		// 	example:
+		//		Plug in a different easing function and register a callback for
+		//		when the animation ends. Easing functions accept values between
+		//		zero and one and return a value on that basis. In this case, an
+		//		exponential-in curve.
+		//	|	dojo.animateProperty({ 
+		//	|		node: "nodeId",
+		//	|		// dojo figures out the start value
+		//	|		properties: { width: { end: 400 } },
+		//	|		easing: function(n){
+		//	|			return (n==0) ? 0 : Math.pow(2, 10 * (n - 1));
+		//	|		},
+		//	|		onEnd: function(){
+		//	|			// called when the animation finishes
+		//	|		}
+		//	|	}).play(500); // delay playing half a second
+		//
+		//	example:
+		//		Like all `dojo._Animation`s, animateProperty returns a handle to the
+		//		Animation instance, which fires the events common to Dojo FX. Use `dojo.connect`
+		//		to access these events outside of the Animation definiton:
+		//	|	var anim = dojo.animateProperty({
+		//	|		node:"someId",
+		//	|		properties:{
+		//	|			width:400, height:500
+		//	|		}
+		//	|	});
+		//	|	dojo.connect(anim,"onEnd", function(){
+		//	|		
+		//	|	});
+		//	|	// play the animation now:
+		//	|	anim.play();
+		
+		args.node = d.byId(args.node);
+		if(!args.easing){ args.easing = d._defaultEasing; }
+
+		var anim = new d._Animation(args);
+		d.connect(anim, "beforeBegin", anim, function(){
+			var pm = {};
+			for(var p in this.properties){
+				// Make shallow copy of properties into pm because we overwrite
+				// some values below. In particular if start/end are functions
+				// we don't want to overwrite them or the functions won't be
+				// called if the animation is reused.
+				if(p == "width" || p == "height"){
+					this.node.display = "block";
+				}
+				var prop = this.properties[p];
+				prop = pm[p] = _mixin({}, (d.isObject(prop) ? prop: { end: prop }));
+
+				if(d.isFunction(prop.start)){
+					prop.start = prop.start();
+				}
+				if(d.isFunction(prop.end)){
+					prop.end = prop.end();
+				}
+				var isColor = (p.toLowerCase().indexOf("color") >= 0);
+				function getStyle(node, p){
+					// dojo.style(node, "height") can return "auto" or "" on IE; this is more reliable:
+					var v = {height: node.offsetHeight, width: node.offsetWidth}[p];
+					if(v !== undefined){ return v; }
+					v = d.style(node, p);
+					return (p == "opacity") ? +v : (isColor ? v : parseFloat(v));
+				}
+				if(!("end" in prop)){
+					prop.end = getStyle(this.node, p);
+				}else if(!("start" in prop)){
+					prop.start = getStyle(this.node, p);
+				}
+
+				if(isColor){
+					prop.start = new d.Color(prop.start);
+					prop.end = new d.Color(prop.end);
+				}else{
+					prop.start = (p == "opacity") ? +prop.start : parseFloat(prop.start);
+				}
+			}
+			this.curve = new PropLine(pm);
+		});
+		d.connect(anim, "onAnimate", d.hitch(d, "style", anim.node));
+		return anim; // dojo._Animation
+	}
+
+	dojo.anim = function(	/*DOMNode|String*/ 	node, 
+							/*Object*/ 			properties, 
+							/*Integer?*/		duration, 
+							/*Function?*/		easing, 
+							/*Function?*/		onEnd,
+							/*Integer?*/		delay){
+		//	summary:
+		//		A simpler interface to `dojo.animateProperty()`, also returns
+		//		an instance of `dojo._Animation` but begins the animation
+		//		immediately, unlike nearly every other Dojo animation API.
+		//	description:
+		//		`dojo.anim` is a simpler (but somewhat less powerful) version
+		//		of `dojo.animateProperty`.  It uses defaults for many basic properties
+		//		and allows for positional parameters to be used in place of the
+		//		packed "property bag" which is used for other Dojo animation
+		//		methods.
+		//
+		//		The `dojo._Animation` object returned from `dojo.anim` will be
+		//		already playing when it is returned from this function, so
+		//		calling play() on it again is (usually) a no-op.
+		//	node:
+		//		a DOM node or the id of a node to animate CSS properties on
+		//	duration:
+		//		The number of milliseconds over which the animation
+		//		should run. Defaults to the global animation default duration
+		//		(350ms).
+		//	easing:
+		//		An easing function over which to calculate acceleration
+		//		and deceleration of the animation through its duration.
+		//		A default easing algorithm is provided, but you may
+		//		plug in any you wish. A large selection of easing algorithms
+		//		are available in `dojo.fx.easing`.
+		//	onEnd:
+		//		A function to be called when the animation finishes
+		//		running.
+		//	delay:
+		//		The number of milliseconds to delay beginning the
+		//		animation by. The default is 0.
+		//	example:
+		//		Fade out a node
+		//	|	dojo.anim("id", { opacity: 0 });
+		//	example:
+		//		Fade out a node over a full second
+		//	|	dojo.anim("id", { opacity: 0 }, 1000);
+		return d.animateProperty({ 
+			node: node,
+			duration: duration||d._Animation.prototype.duration,
+			properties: properties,
+			easing: easing,
+			onEnd: onEnd 
+		}).play(delay||0);
+	}
+})();
+
+}
+
+if(!dojo._hasResource["dojo._base.browser"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.browser"] = true;
+dojo.provide("dojo._base.browser");
+
+
+
+
+
+
+
+
+
+
+//Need this to be the last code segment in base, so do not place any
+//dojo.requireIf calls in this file. Otherwise, due to how the build system
+//puts all requireIf dependencies after the current file, the require calls
+//could be called before all of base is defined.
+dojo.forEach(dojo.config.require, function(i){
+	dojo["require"](i);
+});
+
+}
+
+	//INSERT dojo.i18n._preloadLocalizations HERE
+
+	if(dojo.config.afterOnLoad && dojo.isBrowser){
+		//Dojo is being added to the page after page load, so just trigger
+		//the init sequence after a timeout. Using a timeout so the rest of this
+		//script gets evaluated properly. This work needs to happen after the
+		//dojo.config.require work done in dojo._base.
+		window.setTimeout(dojo._loadInit, 1000);
+	}
+
+})();
+
diff --git a/dojo/fx.js b/dojo/fx.js
new file mode 100644
index 0000000..d94211f
--- /dev/null
+++ b/dojo/fx.js
@@ -0,0 +1,253 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.fx"]){
+dojo._hasResource["dojo.fx"]=true;
+dojo.provide("dojo.fx");
+dojo.require("dojo.fx.Toggler");
+(function(){
+var d=dojo,_2={_fire:function(_3,_4){
+if(this[_3]){
+this[_3].apply(this,_4||[]);
+}
+return this;
+}};
+var _5=function(_6){
+this._index=-1;
+this._animations=_6||[];
+this._current=this._onAnimateCtx=this._onEndCtx=null;
+this.duration=0;
+d.forEach(this._animations,function(a){
+this.duration+=a.duration;
+if(a.delay){
+this.duration+=a.delay;
+}
+},this);
+};
+d.extend(_5,{_onAnimate:function(){
+this._fire("onAnimate",arguments);
+},_onEnd:function(){
+d.disconnect(this._onAnimateCtx);
+d.disconnect(this._onEndCtx);
+this._onAnimateCtx=this._onEndCtx=null;
+if(this._index+1==this._animations.length){
+this._fire("onEnd");
+}else{
+this._current=this._animations[++this._index];
+this._onAnimateCtx=d.connect(this._current,"onAnimate",this,"_onAnimate");
+this._onEndCtx=d.connect(this._current,"onEnd",this,"_onEnd");
+this._current.play(0,true);
+}
+},play:function(_8,_9){
+if(!this._current){
+this._current=this._animations[this._index=0];
+}
+if(!_9&&this._current.status()=="playing"){
+return this;
+}
+var _a=d.connect(this._current,"beforeBegin",this,function(){
+this._fire("beforeBegin");
+}),_b=d.connect(this._current,"onBegin",this,function(_c){
+this._fire("onBegin",arguments);
+}),_d=d.connect(this._current,"onPlay",this,function(_e){
+this._fire("onPlay",arguments);
+d.disconnect(_a);
+d.disconnect(_b);
+d.disconnect(_d);
+});
+if(this._onAnimateCtx){
+d.disconnect(this._onAnimateCtx);
+}
+this._onAnimateCtx=d.connect(this._current,"onAnimate",this,"_onAnimate");
+if(this._onEndCtx){
+d.disconnect(this._onEndCtx);
+}
+this._onEndCtx=d.connect(this._current,"onEnd",this,"_onEnd");
+this._current.play.apply(this._current,arguments);
+return this;
+},pause:function(){
+if(this._current){
+var e=d.connect(this._current,"onPause",this,function(arg){
+this._fire("onPause",arguments);
+d.disconnect(e);
+});
+this._current.pause();
+}
+return this;
+},gotoPercent:function(_11,_12){
+this.pause();
+var _13=this.duration*_11;
+this._current=null;
+d.some(this._animations,function(a){
+if(a.duration<=_13){
+this._current=a;
+return true;
+}
+_13-=a.duration;
+return false;
+});
+if(this._current){
+this._current.gotoPercent(_13/this._current.duration,_12);
+}
+return this;
+},stop:function(_15){
+if(this._current){
+if(_15){
+for(;this._index+1<this._animations.length;++this._index){
+this._animations[this._index].stop(true);
+}
+this._current=this._animations[this._index];
+}
+var e=d.connect(this._current,"onStop",this,function(arg){
+this._fire("onStop",arguments);
+d.disconnect(e);
+});
+this._current.stop();
+}
+return this;
+},status:function(){
+return this._current?this._current.status():"stopped";
+},destroy:function(){
+if(this._onAnimateCtx){
+d.disconnect(this._onAnimateCtx);
+}
+if(this._onEndCtx){
+d.disconnect(this._onEndCtx);
+}
+}});
+d.extend(_5,_2);
+dojo.fx.chain=function(_18){
+return new _5(_18);
+};
+var _19=function(_1a){
+this._animations=_1a||[];
+this._connects=[];
+this._finished=0;
+this.duration=0;
+d.forEach(_1a,function(a){
+var _1c=a.duration;
+if(a.delay){
+_1c+=a.delay;
+}
+if(this.duration<_1c){
+this.duration=_1c;
+}
+this._connects.push(d.connect(a,"onEnd",this,"_onEnd"));
+},this);
+this._pseudoAnimation=new d._Animation({curve:[0,1],duration:this.duration});
+var _1d=this;
+d.forEach(["beforeBegin","onBegin","onPlay","onAnimate","onPause","onStop"],function(evt){
+_1d._connects.push(d.connect(_1d._pseudoAnimation,evt,function(){
+_1d._fire(evt,arguments);
+}));
+});
+};
+d.extend(_19,{_doAction:function(_1f,_20){
+d.forEach(this._animations,function(a){
+a[_1f].apply(a,_20);
+});
+return this;
+},_onEnd:function(){
+if(++this._finished==this._animations.length){
+this._fire("onEnd");
+}
+},_call:function(_22,_23){
+var t=this._pseudoAnimation;
+t[_22].apply(t,_23);
+},play:function(_25,_26){
+this._finished=0;
+this._doAction("play",arguments);
+this._call("play",arguments);
+return this;
+},pause:function(){
+this._doAction("pause",arguments);
+this._call("pause",arguments);
+return this;
+},gotoPercent:function(_27,_28){
+var ms=this.duration*_27;
+d.forEach(this._animations,function(a){
+a.gotoPercent(a.duration<ms?1:(ms/a.duration),_28);
+});
+this._call("gotoPercent",arguments);
+return this;
+},stop:function(_2b){
+this._doAction("stop",arguments);
+this._call("stop",arguments);
+return this;
+},status:function(){
+return this._pseudoAnimation.status();
+},destroy:function(){
+d.forEach(this._connects,dojo.disconnect);
+}});
+d.extend(_19,_2);
+dojo.fx.combine=function(_2c){
+return new _19(_2c);
+};
+dojo.fx.wipeIn=function(_2d){
+_2d.node=d.byId(_2d.node);
+var _2e=_2d.node,s=_2e.style,o;
+var _31=d.animateProperty(d.mixin({properties:{height:{start:function(){
+o=s.overflow;
+s.overflow="hidden";
+if(s.visibility=="hidden"||s.display=="none"){
+s.height="1px";
+s.display="";
+s.visibility="";
+return 1;
+}else{
+var _32=d.style(_2e,"height");
+return Math.max(_32,1);
+}
+},end:function(){
+return _2e.scrollHeight;
+}}}},_2d));
+d.connect(_31,"onEnd",function(){
+s.height="auto";
+s.overflow=o;
+});
+return _31;
+};
+dojo.fx.wipeOut=function(_33){
+var _34=_33.node=d.byId(_33.node),s=_34.style,o;
+var _37=d.animateProperty(d.mixin({properties:{height:{end:1}}},_33));
+d.connect(_37,"beforeBegin",function(){
+o=s.overflow;
+s.overflow="hidden";
+s.display="";
+});
+d.connect(_37,"onEnd",function(){
+s.overflow=o;
+s.height="auto";
+s.display="none";
+});
+return _37;
+};
+dojo.fx.slideTo=function(_38){
+var _39=_38.node=d.byId(_38.node),top=null,_3b=null;
+var _3c=(function(n){
+return function(){
+var cs=d.getComputedStyle(n);
+var pos=cs.position;
+top=(pos=="absolute"?n.offsetTop:parseInt(cs.top)||0);
+_3b=(pos=="absolute"?n.offsetLeft:parseInt(cs.left)||0);
+if(pos!="absolute"&&pos!="relative"){
+var ret=d.coords(n,true);
+top=ret.y;
+_3b=ret.x;
+n.style.position="absolute";
+n.style.top=top+"px";
+n.style.left=_3b+"px";
+}
+};
+})(_39);
+_3c();
+var _41=d.animateProperty(d.mixin({properties:{top:_38.top||0,left:_38.left||0}},_38));
+d.connect(_41,"beforeBegin",_41,_3c);
+return _41;
+};
+})();
+}
diff --git a/dojo/fx/Toggler.js b/dojo/fx/Toggler.js
new file mode 100644
index 0000000..210cf3e
--- /dev/null
+++ b/dojo/fx/Toggler.js
@@ -0,0 +1,30 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.fx.Toggler"]){
+dojo._hasResource["dojo.fx.Toggler"]=true;
+dojo.provide("dojo.fx.Toggler");
+dojo.declare("dojo.fx.Toggler",null,{constructor:function(_1){
+var _t=this;
+dojo.mixin(_t,_1);
+_t.node=_1.node;
+_t._showArgs=dojo.mixin({},_1);
+_t._showArgs.node=_t.node;
+_t._showArgs.duration=_t.showDuration;
+_t.showAnim=_t.showFunc(_t._showArgs);
+_t._hideArgs=dojo.mixin({},_1);
+_t._hideArgs.node=_t.node;
+_t._hideArgs.duration=_t.hideDuration;
+_t.hideAnim=_t.hideFunc(_t._hideArgs);
+dojo.connect(_t.showAnim,"beforeBegin",dojo.hitch(_t.hideAnim,"stop",true));
+dojo.connect(_t.hideAnim,"beforeBegin",dojo.hitch(_t.showAnim,"stop",true));
+},node:null,showFunc:dojo.fadeIn,hideFunc:dojo.fadeOut,showDuration:200,hideDuration:200,show:function(_3){
+return this.showAnim.play(_3||0);
+},hide:function(_4){
+return this.hideAnim.play(_4||0);
+}});
+}
diff --git a/dojo/fx/easing.js b/dojo/fx/easing.js
new file mode 100644
index 0000000..632d9eb
--- /dev/null
+++ b/dojo/fx/easing.js
@@ -0,0 +1,166 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.fx.easing"]){
+dojo._hasResource["dojo.fx.easing"]=true;
+dojo.provide("dojo.fx.easing");
+dojo.fx.easing={linear:function(n){
+return n;
+},quadIn:function(n){
+return Math.pow(n,2);
+},quadOut:function(n){
+return n*(n-2)*-1;
+},quadInOut:function(n){
+n=n*2;
+if(n<1){
+return Math.pow(n,2)/2;
+}
+return -1*((--n)*(n-2)-1)/2;
+},cubicIn:function(n){
+return Math.pow(n,3);
+},cubicOut:function(n){
+return Math.pow(n-1,3)+1;
+},cubicInOut:function(n){
+n=n*2;
+if(n<1){
+return Math.pow(n,3)/2;
+}
+n-=2;
+return (Math.pow(n,3)+2)/2;
+},quartIn:function(n){
+return Math.pow(n,4);
+},quartOut:function(n){
+return -1*(Math.pow(n-1,4)-1);
+},quartInOut:function(n){
+n=n*2;
+if(n<1){
+return Math.pow(n,4)/2;
+}
+n-=2;
+return -1/2*(Math.pow(n,4)-2);
+},quintIn:function(n){
+return Math.pow(n,5);
+},quintOut:function(n){
+return Math.pow(n-1,5)+1;
+},quintInOut:function(n){
+n=n*2;
+if(n<1){
+return Math.pow(n,5)/2;
+}
+n-=2;
+return (Math.pow(n,5)+2)/2;
+},sineIn:function(n){
+return -1*Math.cos(n*(Math.PI/2))+1;
+},sineOut:function(n){
+return Math.sin(n*(Math.PI/2));
+},sineInOut:function(n){
+return -1*(Math.cos(Math.PI*n)-1)/2;
+},expoIn:function(n){
+return (n==0)?0:Math.pow(2,10*(n-1));
+},expoOut:function(n){
+return (n==1)?1:(-1*Math.pow(2,-10*n)+1);
+},expoInOut:function(n){
+if(n==0){
+return 0;
+}
+if(n==1){
+return 1;
+}
+n=n*2;
+if(n<1){
+return Math.pow(2,10*(n-1))/2;
+}
+--n;
+return (-1*Math.pow(2,-10*n)+2)/2;
+},circIn:function(n){
+return -1*(Math.sqrt(1-Math.pow(n,2))-1);
+},circOut:function(n){
+n=n-1;
+return Math.sqrt(1-Math.pow(n,2));
+},circInOut:function(n){
+n=n*2;
+if(n<1){
+return -1/2*(Math.sqrt(1-Math.pow(n,2))-1);
+}
+n-=2;
+return 1/2*(Math.sqrt(1-Math.pow(n,2))+1);
+},backIn:function(n){
+var s=1.70158;
+return Math.pow(n,2)*((s+1)*n-s);
+},backOut:function(n){
+n=n-1;
+var s=1.70158;
+return Math.pow(n,2)*((s+1)*n+s)+1;
+},backInOut:function(n){
+var s=1.70158*1.525;
+n=n*2;
+if(n<1){
+return (Math.pow(n,2)*((s+1)*n-s))/2;
+}
+n-=2;
+return (Math.pow(n,2)*((s+1)*n+s)+2)/2;
+},elasticIn:function(n){
+if(n==0||n==1){
+return n;
+}
+var p=0.3;
+var s=p/4;
+n=n-1;
+return -1*Math.pow(2,10*n)*Math.sin((n-s)*(2*Math.PI)/p);
+},elasticOut:function(n){
+if(n==0||n==1){
+return n;
+}
+var p=0.3;
+var s=p/4;
+return Math.pow(2,-10*n)*Math.sin((n-s)*(2*Math.PI)/p)+1;
+},elasticInOut:function(n){
+if(n==0){
+return 0;
+}
+n=n*2;
+if(n==2){
+return 1;
+}
+var p=0.3*1.5;
+var s=p/4;
+if(n<1){
+n-=1;
+return -0.5*(Math.pow(2,10*n)*Math.sin((n-s)*(2*Math.PI)/p));
+}
+n-=1;
+return 0.5*(Math.pow(2,-10*n)*Math.sin((n-s)*(2*Math.PI)/p))+1;
+},bounceIn:function(n){
+return (1-dojo.fx.easing.bounceOut(1-n));
+},bounceOut:function(n){
+var s=7.5625;
+var p=2.75;
+var l;
+if(n<(1/p)){
+l=s*Math.pow(n,2);
+}else{
+if(n<(2/p)){
+n-=(1.5/p);
+l=s*Math.pow(n,2)+0.75;
+}else{
+if(n<(2.5/p)){
+n-=(2.25/p);
+l=s*Math.pow(n,2)+0.9375;
+}else{
+n-=(2.625/p);
+l=s*Math.pow(n,2)+0.984375;
+}
+}
+}
+return l;
+},bounceInOut:function(n){
+if(n<0.5){
+return dojo.fx.easing.bounceIn(n*2)/2;
+}
+return (dojo.fx.easing.bounceOut(n*2-1)/2)+0.5;
+}};
+}
diff --git a/dojo/gears.js b/dojo/gears.js
new file mode 100644
index 0000000..e8edb13
--- /dev/null
+++ b/dojo/gears.js
@@ -0,0 +1,45 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.gears"]){
+dojo._hasResource["dojo.gears"]=true;
+dojo.provide("dojo.gears");
+dojo.gears._gearsObject=function(){
+var _1;
+var _2;
+var _3=dojo.getObject("google.gears");
+if(_3){
+return _3;
+}
+if(typeof GearsFactory!="undefined"){
+_1=new GearsFactory();
+}else{
+if(dojo.isIE){
+try{
+_1=new ActiveXObject("Gears.Factory");
+}
+catch(e){
+}
+}else{
+if(navigator.mimeTypes["application/x-googlegears"]){
+_1=document.createElement("object");
+_1.setAttribute("type","application/x-googlegears");
+_1.setAttribute("width",0);
+_1.setAttribute("height",0);
+_1.style.display="none";
+document.documentElement.appendChild(_1);
+}
+}
+}
+if(!_1){
+return null;
+}
+dojo.setObject("google.gears.factory",_1);
+return dojo.getObject("google.gears");
+};
+dojo.gears.available=(!!dojo.gears._gearsObject())||0;
+}
diff --git a/dojo/html.js b/dojo/html.js
new file mode 100644
index 0000000..a697000
--- /dev/null
+++ b/dojo/html.js
@@ -0,0 +1,177 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.html"]){
+dojo._hasResource["dojo.html"]=true;
+dojo.provide("dojo.html");
+dojo.require("dojo.parser");
+(function(){
+var _1=0;
+dojo.html._secureForInnerHtml=function(_2){
+return _2.replace(/(?:\s*<!DOCTYPE\s[^>]+>|<title[^>]*>[\s\S]*?<\/title>)/ig,"");
+};
+dojo.html._emptyNode=dojo.empty;
+dojo.html._setNodeContent=function(_3,_4,_5){
+if(_5){
+dojo.html._emptyNode(_3);
+}
+if(typeof _4=="string"){
+var _6="",_7="",_8=0,_9=_3.nodeName.toLowerCase();
+switch(_9){
+case "tr":
+_6="<tr>";
+_7="</tr>";
+_8+=1;
+case "tbody":
+case "thead":
+_6="<tbody>"+_6;
+_7+="</tbody>";
+_8+=1;
+case "table":
+_6="<table>"+_6;
+_7+="</table>";
+_8+=1;
+break;
+}
+if(_8){
+var n=_3.ownerDocument.createElement("div");
+n.innerHTML=_6+_4+_7;
+do{
+n=n.firstChild;
+}while(--_8);
+dojo.forEach(n.childNodes,function(n){
+_3.appendChild(n.cloneNode(true));
+});
+}else{
+_3.innerHTML=_4;
+}
+}else{
+if(_4.nodeType){
+_3.appendChild(_4);
+}else{
+dojo.forEach(_4,function(n){
+_3.appendChild(n.cloneNode(true));
+});
+}
+}
+return _3;
+};
+dojo.declare("dojo.html._ContentSetter",null,{node:"",content:"",id:"",cleanContent:false,extractContent:false,parseContent:false,constructor:function(_d,_e){
+dojo.mixin(this,_d||{});
+_e=this.node=dojo.byId(this.node||_e);
+if(!this.id){
+this.id=["Setter",(_e)?_e.id||_e.tagName:"",_1++].join("_");
+}
+if(!(this.node||_e)){
+new Error(this.declaredClass+": no node provided to "+this.id);
+}
+},set:function(_f,_10){
+if(undefined!==_f){
+this.content=_f;
+}
+if(_10){
+this._mixin(_10);
+}
+this.onBegin();
+this.setContent();
+this.onEnd();
+return this.node;
+},setContent:function(){
+var _11=this.node;
+if(!_11){
+console.error("setContent given no node");
+}
+try{
+_11=dojo.html._setNodeContent(_11,this.content);
+}
+catch(e){
+var _12=this.onContentError(e);
+try{
+_11.innerHTML=_12;
+}
+catch(e){
+console.error("Fatal "+this.declaredClass+".setContent could not change content due to "+e.message,e);
+}
+}
+this.node=_11;
+},empty:function(){
+if(this.parseResults&&this.parseResults.length){
+dojo.forEach(this.parseResults,function(w){
+if(w.destroy){
+w.destroy();
+}
+});
+delete this.parseResults;
+}
+dojo.html._emptyNode(this.node);
+},onBegin:function(){
+var _14=this.content;
+if(dojo.isString(_14)){
+if(this.cleanContent){
+_14=dojo.html._secureForInnerHtml(_14);
+}
+if(this.extractContent){
+var _15=_14.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
+if(_15){
+_14=_15[1];
+}
+}
+}
+this.empty();
+this.content=_14;
+return this.node;
+},onEnd:function(){
+if(this.parseContent){
+this._parse();
+}
+return this.node;
+},tearDown:function(){
+delete this.parseResults;
+delete this.node;
+delete this.content;
+},onContentError:function(err){
+return "Error occured setting content: "+err;
+},_mixin:function(_17){
+var _18={},key;
+for(key in _17){
+if(key in _18){
+continue;
+}
+this[key]=_17[key];
+}
+},_parse:function(){
+var _1a=this.node;
+try{
+this.parseResults=dojo.parser.parse(_1a,true);
+}
+catch(e){
+this._onError("Content",e,"Error parsing in _ContentSetter#"+this.id);
+}
+},_onError:function(_1b,err,_1d){
+var _1e=this["on"+_1b+"Error"].call(this,err);
+if(_1d){
+console.error(_1d,err);
+}else{
+if(_1e){
+dojo.html._setNodeContent(this.node,_1e,true);
+}
+}
+}});
+dojo.html.set=function(_1f,_20,_21){
+if(undefined==_20){
+console.warn("dojo.html.set: no cont argument provided, using empty string");
+_20="";
+}
+if(!_21){
+return dojo.html._setNodeContent(_1f,_20,true);
+}else{
+var op=new dojo.html._ContentSetter(dojo.mixin(_21,{content:_20,node:_1f}));
+return op.set();
+}
+};
+})();
+}
diff --git a/dojo/i18n.js b/dojo/i18n.js
new file mode 100644
index 0000000..fd1ac48
--- /dev/null
+++ b/dojo/i18n.js
@@ -0,0 +1,171 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.i18n"]){
+dojo._hasResource["dojo.i18n"]=true;
+dojo.provide("dojo.i18n");
+dojo.i18n.getLocalization=function(_1,_2,_3){
+_3=dojo.i18n.normalizeLocale(_3);
+var _4=_3.split("-");
+var _5=[_1,"nls",_2].join(".");
+var _6=dojo._loadedModules[_5];
+if(_6){
+var _7;
+for(var i=_4.length;i>0;i--){
+var _9=_4.slice(0,i).join("_");
+if(_6[_9]){
+_7=_6[_9];
+break;
+}
+}
+if(!_7){
+_7=_6.ROOT;
+}
+if(_7){
+var _a=function(){
+};
+_a.prototype=_7;
+return new _a();
+}
+}
+throw new Error("Bundle not found: "+_2+" in "+_1+" , locale="+_3);
+};
+dojo.i18n.normalizeLocale=function(_b){
+var _c=_b?_b.toLowerCase():dojo.locale;
+if(_c=="root"){
+_c="ROOT";
+}
+return _c;
+};
+dojo.i18n._requireLocalization=function(_d,_e,_f,_10){
+var _11=dojo.i18n.normalizeLocale(_f);
+var _12=[_d,"nls",_e].join(".");
+var _13="";
+if(_10){
+var _14=_10.split(",");
+for(var i=0;i<_14.length;i++){
+if(_11["indexOf"](_14[i])==0){
+if(_14[i].length>_13.length){
+_13=_14[i];
+}
+}
+}
+if(!_13){
+_13="ROOT";
+}
+}
+var _16=_10?_13:_11;
+var _17=dojo._loadedModules[_12];
+var _18=null;
+if(_17){
+if(dojo.config.localizationComplete&&_17._built){
+return;
+}
+var _19=_16.replace(/-/g,"_");
+var _1a=_12+"."+_19;
+_18=dojo._loadedModules[_1a];
+}
+if(!_18){
+_17=dojo["provide"](_12);
+var _1b=dojo._getModuleSymbols(_d);
+var _1c=_1b.concat("nls").join("/");
+var _1d;
+dojo.i18n._searchLocalePath(_16,_10,function(loc){
+var _1f=loc.replace(/-/g,"_");
+var _20=_12+"."+_1f;
+var _21=false;
+if(!dojo._loadedModules[_20]){
+dojo["provide"](_20);
+var _22=[_1c];
+if(loc!="ROOT"){
+_22.push(loc);
+}
+_22.push(_e);
+var _23=_22.join("/")+".js";
+_21=dojo._loadPath(_23,null,function(_24){
+var _25=function(){
+};
+_25.prototype=_1d;
+_17[_1f]=new _25();
+for(var j in _24){
+_17[_1f][j]=_24[j];
+}
+});
+}else{
+_21=true;
+}
+if(_21&&_17[_1f]){
+_1d=_17[_1f];
+}else{
+_17[_1f]=_1d;
+}
+if(_10){
+return true;
+}
+});
+}
+if(_10&&_11!=_13){
+_17[_11.replace(/-/g,"_")]=_17[_13.replace(/-/g,"_")];
+}
+};
+(function(){
+var _27=dojo.config.extraLocale;
+if(_27){
+if(!_27 instanceof Array){
+_27=[_27];
+}
+var req=dojo.i18n._requireLocalization;
+dojo.i18n._requireLocalization=function(m,b,_2b,_2c){
+req(m,b,_2b,_2c);
+if(_2b){
+return;
+}
+for(var i=0;i<_27.length;i++){
+req(m,b,_27[i],_2c);
+}
+};
+}
+})();
+dojo.i18n._searchLocalePath=function(_2e,_2f,_30){
+_2e=dojo.i18n.normalizeLocale(_2e);
+var _31=_2e.split("-");
+var _32=[];
+for(var i=_31.length;i>0;i--){
+_32.push(_31.slice(0,i).join("-"));
+}
+_32.push(false);
+if(_2f){
+_32.reverse();
+}
+for(var j=_32.length-1;j>=0;j--){
+var loc=_32[j]||"ROOT";
+var _36=_30(loc);
+if(_36){
+break;
+}
+}
+};
+dojo.i18n._preloadLocalizations=function(_37,_38){
+function _39(_3a){
+_3a=dojo.i18n.normalizeLocale(_3a);
+dojo.i18n._searchLocalePath(_3a,true,function(loc){
+for(var i=0;i<_38.length;i++){
+if(_38[i]==loc){
+dojo["require"](_37+"_"+loc);
+return true;
+}
+}
+return false;
+});
+};
+_39();
+var _3d=dojo.config.extraLocale||[];
+for(var i=0;i<_3d.length;i++){
+_39(_3d[i]);
+}
+};
+}
diff --git a/dojo/io/iframe.js b/dojo/io/iframe.js
new file mode 100644
index 0000000..dcd0b30
--- /dev/null
+++ b/dojo/io/iframe.js
@@ -0,0 +1,258 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.io.iframe"]){
+dojo._hasResource["dojo.io.iframe"]=true;
+dojo.provide("dojo.io.iframe");
+dojo.io.iframe={create:function(_1,_2,_3){
+if(window[_1]){
+return window[_1];
+}
+if(window.frames[_1]){
+return window.frames[_1];
+}
+var _4=null;
+var _5=_3;
+if(!_5){
+if(dojo.config["useXDomain"]&&!dojo.config["dojoBlankHtmlUrl"]){
+console.warn("dojo.io.iframe.create: When using cross-domain Dojo builds,"+" please save dojo/resources/blank.html to your domain and set djConfig.dojoBlankHtmlUrl"+" to the path on your domain to blank.html");
+}
+_5=(dojo.config["dojoBlankHtmlUrl"]||dojo.moduleUrl("dojo","resources/blank.html"));
+}
+var _6=dojo.isIE?"<iframe name=\""+_1+"\" src=\""+_5+"\" onload=\""+_2+"\">":"iframe";
+_4=dojo.doc.createElement(_6);
+with(_4){
+name=_1;
+setAttribute("name",_1);
+id=_1;
+}
+dojo.body().appendChild(_4);
+window[_1]=_4;
+with(_4.style){
+if(!(dojo.isSafari<3)){
+position="absolute";
+}
+left=top="1px";
+height=width="1px";
+visibility="hidden";
+}
+if(!dojo.isIE){
+this.setSrc(_4,_5,true);
+_4.onload=new Function(_2);
+}
+return _4;
+},setSrc:function(_7,_8,_9){
+try{
+if(!_9){
+if(dojo.isWebKit){
+_7.location=_8;
+}else{
+frames[_7.name].location=_8;
+}
+}else{
+var _a;
+if(dojo.isIE||dojo.isWebKit>521){
+_a=_7.contentWindow.document;
+}else{
+if(dojo.isSafari){
+_a=_7.document;
+}else{
+_a=_7.contentWindow;
+}
+}
+if(!_a){
+_7.location=_8;
+return;
+}else{
+_a.location.replace(_8);
+}
+}
+}
+catch(e){
+
+}
+},doc:function(_b){
+var _c=_b.contentDocument||(((_b.name)&&(_b.document)&&(document.getElementsByTagName("iframe")[_b.name].contentWindow)&&(document.getElementsByTagName("iframe")[_b.name].contentWindow.document)))||((_b.name)&&(document.frames[_b.name])&&(document.frames[_b.name].document))||null;
+return _c;
+},send:function(_d){
+if(!this["_frame"]){
+this._frame=this.create(this._iframeName,dojo._scopeName+".io.iframe._iframeOnload();");
+}
+var _e=dojo._ioSetArgs(_d,function(_f){
+_f.canceled=true;
+_f.ioArgs._callNext();
+},function(dfd){
+var _11=null;
+try{
+var _12=dfd.ioArgs;
+var dii=dojo.io.iframe;
+var ifd=dii.doc(dii._frame);
+var _15=_12.handleAs;
+_11=ifd;
+if(_15!="html"){
+if(_15=="xml"){
+if(dojo.isIE){
+dojo.query("a",dii._frame.contentWindow.document.documentElement).orphan();
+var _16=(dii._frame.contentWindow.document).documentElement.innerText;
+_16=_16.replace(/>\s+</g,"><");
+_16=dojo.trim(_16);
+var _17={responseText:_16};
+_11=dojo._contentHandlers["xml"](_17);
+}
+}else{
+_11=ifd.getElementsByTagName("textarea")[0].value;
+if(_15=="json"){
+_11=dojo.fromJson(_11);
+}else{
+if(_15=="javascript"){
+_11=dojo.eval(_11);
+}
+}
+}
+}
+}
+catch(e){
+_11=e;
+}
+finally{
+_12._callNext();
+}
+return _11;
+},function(_18,dfd){
+dfd.ioArgs._hasError=true;
+dfd.ioArgs._callNext();
+return _18;
+});
+_e.ioArgs._callNext=function(){
+if(!this["_calledNext"]){
+this._calledNext=true;
+dojo.io.iframe._currentDfd=null;
+dojo.io.iframe._fireNextRequest();
+}
+};
+this._dfdQueue.push(_e);
+this._fireNextRequest();
+dojo._ioWatch(_e,function(dfd){
+return !dfd.ioArgs["_hasError"];
+},function(dfd){
+return (!!dfd.ioArgs["_finished"]);
+},function(dfd){
+if(dfd.ioArgs._finished){
+dfd.callback(dfd);
+}else{
+dfd.errback(new Error("Invalid dojo.io.iframe request state"));
+}
+});
+return _e;
+},_currentDfd:null,_dfdQueue:[],_iframeName:dojo._scopeName+"IoIframe",_fireNextRequest:function(){
+try{
+if((this._currentDfd)||(this._dfdQueue.length==0)){
+return;
+}
+var dfd=this._currentDfd=this._dfdQueue.shift();
+var _1e=dfd.ioArgs;
+var _1f=_1e.args;
+_1e._contentToClean=[];
+var fn=dojo.byId(_1f["form"]);
+var _21=_1f["content"]||{};
+if(fn){
+if(_21){
+var _22=function(_23,_24){
+var tn;
+if(dojo.isIE){
+tn=dojo.doc.createElement("<input type='hidden' name='"+_23+"'>");
+}else{
+tn=dojo.doc.createElement("input");
+tn.type="hidden";
+tn.name=_23;
+}
+tn.value=_24;
+fn.appendChild(tn);
+_1e._contentToClean.push(_23);
+};
+for(var x in _21){
+var val=_21[x];
+if(dojo.isArray(val)&&val.length>1){
+var i;
+for(i=0;i<val.length;i++){
+_22(x,val[i]);
+}
+}else{
+if(!fn[x]){
+_22(x,val);
+}else{
+fn[x].value=val;
+}
+}
+}
+}
+var _29=fn.getAttributeNode("action");
+var _2a=fn.getAttributeNode("method");
+var _2b=fn.getAttributeNode("target");
+if(_1f["url"]){
+_1e._originalAction=_29?_29.value:null;
+if(_29){
+_29.value=_1f.url;
+}else{
+fn.setAttribute("action",_1f.url);
+}
+}
+if(!_2a||!_2a.value){
+if(_2a){
+_2a.value=(_1f["method"])?_1f["method"]:"post";
+}else{
+fn.setAttribute("method",(_1f["method"])?_1f["method"]:"post");
+}
+}
+_1e._originalTarget=_2b?_2b.value:null;
+if(_2b){
+_2b.value=this._iframeName;
+}else{
+fn.setAttribute("target",this._iframeName);
+}
+fn.target=this._iframeName;
+fn.submit();
+}else{
+var _2c=_1f.url+(_1f.url.indexOf("?")>-1?"&":"?")+_1e.query;
+this.setSrc(this._frame,_2c,true);
+}
+}
+catch(e){
+dfd.errback(e);
+}
+},_iframeOnload:function(){
+var dfd=this._currentDfd;
+if(!dfd){
+this._fireNextRequest();
+return;
+}
+var _2e=dfd.ioArgs;
+var _2f=_2e.args;
+var _30=dojo.byId(_2f.form);
+if(_30){
+var _31=_2e._contentToClean;
+for(var i=0;i<_31.length;i++){
+var key=_31[i];
+for(var j=0;j<_30.childNodes.length;j++){
+var _35=_30.childNodes[j];
+if(_35.name==key){
+dojo.destroy(_35);
+break;
+}
+}
+}
+if(_2e["_originalAction"]){
+_30.setAttribute("action",_2e._originalAction);
+}
+if(_2e["_originalTarget"]){
+_30.setAttribute("target",_2e._originalTarget);
+_30.target=_2e._originalTarget;
+}
+}
+_2e._finished=true;
+}};
+}
diff --git a/dojo/io/script.js b/dojo/io/script.js
new file mode 100644
index 0000000..585cf44
--- /dev/null
+++ b/dojo/io/script.js
@@ -0,0 +1,108 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.io.script"]){
+dojo._hasResource["dojo.io.script"]=true;
+dojo.provide("dojo.io.script");
+dojo.io.script={get:function(_1){
+var _2=this._makeScriptDeferred(_1);
+var _3=_2.ioArgs;
+dojo._ioAddQueryToUrl(_3);
+if(this._canAttach(_3)){
+this.attach(_3.id,_3.url,_1.frameDoc);
+}
+dojo._ioWatch(_2,this._validCheck,this._ioCheck,this._resHandle);
+return _2;
+},attach:function(id,_5,_6){
+var _7=(_6||dojo.doc);
+var _8=_7.createElement("script");
+_8.type="text/javascript";
+_8.src=_5;
+_8.id=id;
+_8.charset="utf-8";
+_7.getElementsByTagName("head")[0].appendChild(_8);
+},remove:function(id,_a){
+dojo.destroy(dojo.byId(id,_a));
+if(this["jsonp_"+id]){
+delete this["jsonp_"+id];
+}
+},_makeScriptDeferred:function(_b){
+var _c=dojo._ioSetArgs(_b,this._deferredCancel,this._deferredOk,this._deferredError);
+var _d=_c.ioArgs;
+_d.id=dojo._scopeName+"IoScript"+(this._counter++);
+_d.canDelete=false;
+if(_b.callbackParamName){
+_d.query=_d.query||"";
+if(_d.query.length>0){
+_d.query+="&";
+}
+_d.query+=_b.callbackParamName+"="+(_b.frameDoc?"parent.":"")+dojo._scopeName+".io.script.jsonp_"+_d.id+"._jsonpCallback";
+_d.frameDoc=_b.frameDoc;
+_d.canDelete=true;
+_c._jsonpCallback=this._jsonpCallback;
+this["jsonp_"+_d.id]=_c;
+}
+return _c;
+},_deferredCancel:function(_e){
+_e.canceled=true;
+if(_e.ioArgs.canDelete){
+dojo.io.script._addDeadScript(_e.ioArgs);
+}
+},_deferredOk:function(_f){
+if(_f.ioArgs.canDelete){
+dojo.io.script._addDeadScript(_f.ioArgs);
+}
+if(_f.ioArgs.json){
+return _f.ioArgs.json;
+}else{
+return _f.ioArgs;
+}
+},_deferredError:function(_10,dfd){
+if(dfd.ioArgs.canDelete){
+if(_10.dojoType=="timeout"){
+dojo.io.script.remove(dfd.ioArgs.id,dfd.ioArgs.frameDoc);
+}else{
+dojo.io.script._addDeadScript(dfd.ioArgs);
+}
+}
+
+return _10;
+},_deadScripts:[],_counter:1,_addDeadScript:function(_12){
+dojo.io.script._deadScripts.push({id:_12.id,frameDoc:_12.frameDoc});
+_12.frameDoc=null;
+},_validCheck:function(dfd){
+var _14=dojo.io.script;
+var _15=_14._deadScripts;
+if(_15&&_15.length>0){
+for(var i=0;i<_15.length;i++){
+_14.remove(_15[i].id,_15[i].frameDoc);
+_15[i].frameDoc=null;
+}
+dojo.io.script._deadScripts=[];
+}
+return true;
+},_ioCheck:function(dfd){
+if(dfd.ioArgs.json){
+return true;
+}
+var _18=dfd.ioArgs.args.checkString;
+if(_18&&eval("typeof("+_18+") != 'undefined'")){
+return true;
+}
+return false;
+},_resHandle:function(dfd){
+if(dojo.io.script._ioCheck(dfd)){
+dfd.callback(dfd);
+}else{
+dfd.errback(new Error("inconceivable dojo.io.script._resHandle error"));
+}
+},_canAttach:function(_1a){
+return true;
+},_jsonpCallback:function(_1b){
+this.ioArgs.json=_1b;
+}};
+}
diff --git a/dojo/jaxer.js b/dojo/jaxer.js
new file mode 100644
index 0000000..43d8fce
--- /dev/null
+++ b/dojo/jaxer.js
@@ -0,0 +1,19 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.jaxer"]){
+dojo._hasResource["dojo.jaxer"]=true;
+dojo.provide("dojo.jaxer");
+if(typeof print=="function"){
+console.debug=Jaxer.Log.debug;
+console.warn=Jaxer.Log.warn;
+console.error=Jaxer.Log.error;
+console.info=Jaxer.Log.info;
+console.log=Jaxer.Log.warn;
+}
+onserverload=dojo._loadInit;
+}
diff --git a/dojo/nls/ar/colors.js b/dojo/nls/ar/colors.js
new file mode 100644
index 0000000..50e4a12
--- /dev/null
+++ b/dojo/nls/ar/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"أزرق معدني فاتح","orangered":"أحمر مائل للبرتقالي","midnightblue":"أزرق بحري","cadetblue":"أزرق ملون بالرمادي","seashell":"أبيض مائل للأصفر فاتح","slategrey":"رمادي اردوازي","coral":"مرجاني","darkturquoise":"تركواز داكن","antiquewhite":"أبيض عتيق","mediumspringgreen":"أخضر ربيعي متوسط","salmon":"برتقالي وردي شاحب","darkgrey":"رمادي داكن","ivory":"عاجي","greenyellow":"أخضر مائل للأصفر","mistyrose":"وردي","lightsalmon":"فضي فاتح","silver":"فضي","dimgrey":"رمادي شاحب","o [...]
\ No newline at end of file
diff --git a/dojo/nls/ca/colors.js b/dojo/nls/ca/colors.js
new file mode 100644
index 0000000..0f1461a
--- /dev/null
+++ b/dojo/nls/ca/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"blau acer clar","orangered":"taronja vermellós","midnightblue":"blau mitjanit","cadetblue":"blau marí","seashell":"petxina marina","slategrey":"gris pissarra","coral":"corall","darkturquoise":"turquesa fosc","antiquewhite":"blanc antic","mediumspringgreen":"verd primavera mitjà","salmon":"salmó","darkgrey":"gris fosc","ivory":"marbre","greenyellow":"verd grogós","mistyrose":"rosa dens","lightsalmon":"salmó clar","silver":"argent","dimgrey":"gris fosc","orange":"taronj [...]
\ No newline at end of file
diff --git a/dojo/nls/colors.js b/dojo/nls/colors.js
new file mode 100644
index 0000000..454e644
--- /dev/null
+++ b/dojo/nls/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"light steel blue","orangered":"orange red","midnightblue":"midnight blue","cadetblue":"cadet blue","seashell":"seashell","slategrey":"slate gray","coral":"coral","darkturquoise":"dark turquoise","antiquewhite":"antique white","mediumspringgreen":"medium spring green","salmon":"salmon","darkgrey":"dark gray","ivory":"ivory","greenyellow":"green-yellow","mistyrose":"misty rose","lightsalmon":"light salmon","silver":"silver","dimgrey":"dim gray","orange":"orange","white" [...]
\ No newline at end of file
diff --git a/dojo/nls/cs/colors.js b/dojo/nls/cs/colors.js
new file mode 100644
index 0000000..7ae5d30
--- /dev/null
+++ b/dojo/nls/cs/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"světlá ocelová modrá","orangered":"oranžovočervená","midnightblue":"temně modrá","cadetblue":"šedomodrá","seashell":"lasturová","slategrey":"břidlicová šedá","coral":"korálová červená","darkturquoise":"tmavě tyrkysová","antiquewhite":"krémově bílá","mediumspringgreen":"střední jarní zelená","salmon":"lososová","darkgrey":"tmavě šedá","ivory":"slonovinová","greenyellow":"zelenožlutá","mistyrose":"růžovobílá","lightsalmon":"světle lososová","silver":"stříbrná","dimgrey" [...]
\ No newline at end of file
diff --git a/dojo/nls/da/colors.js b/dojo/nls/da/colors.js
new file mode 100644
index 0000000..322154f
--- /dev/null
+++ b/dojo/nls/da/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"lys stålblå","orangered":"orangerød","midnightblue":"midnatsblå","cadetblue":"kadetblå","seashell":"muslingeskal","slategrey":"skifergrå","coral":"koralrød","darkturquoise":"mørk turkis","antiquewhite":"antikhvid","mediumspringgreen":"mellemforårsgrøn","salmon":"laksefarvet","darkgrey":"mørkegrå","ivory":"elfenben","greenyellow":"grøngul","mistyrose":"blegrosa","lightsalmon":"lys laksefarvet","silver":"sølv","dimgrey":"svag grå","orange":"orange","white":"hvid","navaj [...]
\ No newline at end of file
diff --git a/dojo/nls/de/colors.js b/dojo/nls/de/colors.js
new file mode 100644
index 0000000..7ae21bf
--- /dev/null
+++ b/dojo/nls/de/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"Helles Stahlblau","orangered":"Orangerot","midnightblue":"Mitternachtblau","cadetblue":"Kadettenblau","seashell":"Muschelweiß","slategrey":"Schiefergrau","coral":"Koralle","darkturquoise":"Dunkeltürkis","antiquewhite":"Antikweiß","mediumspringgreen":"Mittelfrühlingsgrün","salmon":"Lachs","darkgrey":"Dunkelgrau","ivory":"Elfenbein","greenyellow":"Grüngelb","mistyrose":"Blassrose","lightsalmon":"Helllachs","silver":"Silbergrau","dimgrey":"Blassgrau","orange":"Orange","w [...]
\ No newline at end of file
diff --git a/dojo/nls/el/colors.js b/dojo/nls/el/colors.js
new file mode 100644
index 0000000..a80df97
--- /dev/null
+++ b/dojo/nls/el/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"ανοιχτό μπλε ατσαλιού","orangered":"πορτοκαλοκόκκινο","midnightblue":"πολύ σκούρο μπλε","cadetblue":"μπλε του στρατού","seashell":"κοχύλι","slategrey":"μεταλλικό γκρι","coral":"κοραλί","darkturquoise":"σκούρο τυρκουάζ","antiquewhite":"ξεθωριασμένο λευκό","mediumspringgreen":"μεσαίο πράσινο της άνοιξης","salmon":"σομόν","darkgrey":"σκούρο γκρι","ivory":"ιβουάρ","greenyellow":"πρασινοκίτρινο","mistyrose":"τριανταφυλλί","lightsalmon":"ανοιχτό σομόν","silver":"ασημί","dim [...]
\ No newline at end of file
diff --git a/dojo/nls/es/colors.js b/dojo/nls/es/colors.js
new file mode 100644
index 0000000..95bb23e
--- /dev/null
+++ b/dojo/nls/es/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"azul acero claro","orangered":"rojo anaranjado","midnightblue":"azul medianoche","cadetblue":"azul cadete","seashell":"blanco marfil","slategrey":"gris pizarra","coral":"coral","darkturquoise":"turquesa oscuro","antiquewhite":"blanco antiguo","mediumspringgreen":"verde primavera medio","salmon":"salmón","darkgrey":"gris oscuro","ivory":"marfil","greenyellow":"amarillo verdoso","mistyrose":"rosa difuminado","lightsalmon":"salmón claro","silver":"plateado","dimgrey":"gr [...]
\ No newline at end of file
diff --git a/dojo/nls/fi/colors.js b/dojo/nls/fi/colors.js
new file mode 100644
index 0000000..454e644
--- /dev/null
+++ b/dojo/nls/fi/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"light steel blue","orangered":"orange red","midnightblue":"midnight blue","cadetblue":"cadet blue","seashell":"seashell","slategrey":"slate gray","coral":"coral","darkturquoise":"dark turquoise","antiquewhite":"antique white","mediumspringgreen":"medium spring green","salmon":"salmon","darkgrey":"dark gray","ivory":"ivory","greenyellow":"green-yellow","mistyrose":"misty rose","lightsalmon":"light salmon","silver":"silver","dimgrey":"dim gray","orange":"orange","white" [...]
\ No newline at end of file
diff --git a/dojo/nls/fr/colors.js b/dojo/nls/fr/colors.js
new file mode 100644
index 0000000..cf1e7e9
--- /dev/null
+++ b/dojo/nls/fr/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"bleu acier clair","orangered":"rouge orangé","midnightblue":"bleu nuit","cadetblue":"bleu pétrole","seashell":"coquillage","slategrey":"gris ardoise","coral":"corail","darkturquoise":"turquoise foncé","antiquewhite":"blanc antique","mediumspringgreen":"vert printemps moyen","salmon":"saumon","darkgrey":"gris foncé","ivory":"ivoire","greenyellow":"vert-jaune","mistyrose":"rose pâle","lightsalmon":"saumon clair","silver":"argent","dimgrey":"gris soutenu","orange":"orang [...]
\ No newline at end of file
diff --git a/dojo/nls/he/colors.js b/dojo/nls/he/colors.js
new file mode 100644
index 0000000..a689ec6
--- /dev/null
+++ b/dojo/nls/he/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"כחול פלדה בהיר","orangered":"כתום אדום","midnightblue":"כחול כהה","cadetblue":"כחול ים","seashell":"צדף","slategrey":"אפור צפחה","coral":"אלמוג","darkturquoise":"טורקיז כהה","antiquewhite":"לבן עתיק","mediumspringgreen":"ירוק אביב בינוני","salmon":"סלמון","darkgrey":"אפור כהה","ivory":"שנהב","greenyellow":"ירוק-צהוב","mistyrose":"ורוד מעורפל","lightsalmon":"סלמון בהיר","silver":"כסף","dimgrey":"אפור עמום","orange":"כתום","white":"לבן","navajowhite":"לבן נוואחו","royal [...]
\ No newline at end of file
diff --git a/dojo/nls/hu/colors.js b/dojo/nls/hu/colors.js
new file mode 100644
index 0000000..c0bce74
--- /dev/null
+++ b/dojo/nls/hu/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"világos acélkék","orangered":"narancsvörös","midnightblue":"éjkék","cadetblue":"kadétkék","seashell":"kagyló","slategrey":"palaszürke","coral":"korall","darkturquoise":"sötét türkizkék","antiquewhite":"antik fehér","mediumspringgreen":"közepes tavaszzöld","salmon":"lazacszín","darkgrey":"sötétszürke","ivory":"elefántcsont","greenyellow":"zöldessárga","mistyrose":"halvány rózsaszín","lightsalmon":"világos lazacszín","silver":"ezüst","dimgrey":"halványszürke","orange":" [...]
\ No newline at end of file
diff --git a/dojo/nls/it/colors.js b/dojo/nls/it/colors.js
new file mode 100644
index 0000000..8a53007
--- /dev/null
+++ b/dojo/nls/it/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"blu acciao chiaro","orangered":"vermiglio","midnightblue":"blu melanzana scuro","cadetblue":"verde acqua","seashell":"sabbia rosa","slategrey":"grigio ardesia","coral":"corallo","darkturquoise":"turchese scuro","antiquewhite":"bianco antico","mediumspringgreen":"verde primavera medio","salmon":"salmone","darkgrey":"grigio scuro","ivory":"avorio","greenyellow":"giallo verde","mistyrose":"rosa pallido","lightsalmon":"salmone chiaro","silver":"grigio 25%","dimgrey":"grig [...]
\ No newline at end of file
diff --git a/dojo/nls/ja/colors.js b/dojo/nls/ja/colors.js
new file mode 100644
index 0000000..46aa1f2
--- /dev/null
+++ b/dojo/nls/ja/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"ライト・スチール・ブルー","orangered":"オレンジ・レッド","midnightblue":"ミッドナイト・ブルー","cadetblue":"くすんだ青","seashell":"シーシェル","slategrey":"スレート・グレイ","coral":"珊瑚","darkturquoise":"ダーク・ターコイズ","antiquewhite":"アンティーク・ホワイト","mediumspringgreen":"ミディアム・スプリング・グリーン","salmon":"サーモン","darkgrey":"ダーク・グレイ","ivory":"アイボリー","greenyellow":"緑黄色","mistyrose":"ミスティ・ローズ","lightsalmon":"ライト・サーモン","silver":"銀","dimgrey":"くすんだグレイ","orange":"オレンジ","white":"白","navajowhite":"ナバホ・ホワイト","royalblue":"藤色","deeppink":" [...]
\ No newline at end of file
diff --git a/dojo/nls/ko/colors.js b/dojo/nls/ko/colors.js
new file mode 100644
index 0000000..0c6576b
--- /dev/null
+++ b/dojo/nls/ko/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"라이트 스틸 블루(light steel blue)","orangered":"오렌지 레드(orange red)","midnightblue":"미드나잇 블루(midnight blue)","cadetblue":"카뎃 블루(cadet blue)","seashell":"씨쉘(seashell)","slategrey":"슬레이트 그레이(slate gray)","coral":"코랄(coral)","darkturquoise":"다크 터콰즈(dark turquoise)","antiquewhite":"앤틱 화이트(antique white)","mediumspringgreen":"미디엄 스프링 그린(medium spring green)","salmon":"샐몬(salmon)","darkgrey":"다크 그레이(dark gray)","ivory":"아이보리(ivory)","greenyellow":"그린 옐로우(green-yellow)","mistyrose" [...]
\ No newline at end of file
diff --git a/dojo/nls/nb/colors.js b/dojo/nls/nb/colors.js
new file mode 100644
index 0000000..15770a4
--- /dev/null
+++ b/dojo/nls/nb/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"lys stålblå","orangered":"rødoransje","midnightblue":"midnattsblå","cadetblue":"mørk grønnblå","seashell":"skjellhvit","slategrey":"skifergrå","coral":"korall","darkturquoise":"mørk turkis","antiquewhite":"antikk hvit","mediumspringgreen":"middels vårgrønn","salmon":"lakserosa","darkgrey":"mørk grå","ivory":"elfenbenshvit","greenyellow":"gulgrønn","mistyrose":"lys rosenrød","lightsalmon":"lys lakserosa","silver":"sølvfarget","dimgrey":"mørk mørkegrå","orange":"oransje [...]
\ No newline at end of file
diff --git a/dojo/nls/nl/colors.js b/dojo/nls/nl/colors.js
new file mode 100644
index 0000000..ae0ccbf
--- /dev/null
+++ b/dojo/nls/nl/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"lichtstaalblauw","orangered":"oranjerood","midnightblue":"nachtblauw","cadetblue":"donkerstaalblauw","seashell":"schelp","slategrey":"leigrijs","coral":"koraalrood","darkturquoise":"donkerturquoise","antiquewhite":"antiekwit","mediumspringgreen":"midlentegroen","salmon":"zalm","darkgrey":"donkergrijs","ivory":"ivoorwit","greenyellow":"groengeel","mistyrose":"matroze","lightsalmon":"lichtzalm","silver":"zilvergrijs","dimgrey":"dofgrijs","orange":"oranje","white":"wit", [...]
\ No newline at end of file
diff --git a/dojo/nls/pl/colors.js b/dojo/nls/pl/colors.js
new file mode 100644
index 0000000..852268c
--- /dev/null
+++ b/dojo/nls/pl/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"jasny stalowoniebieski","orangered":"pomarańczowoczerwony","midnightblue":"ciemnogranatowy","cadetblue":"niebieskoszary","seashell":"muszla","slategrey":"łupkowy szary","coral":"koralowy","darkturquoise":"ciemnoturkusowy","antiquewhite":"biel antyczna","mediumspringgreen":"średnia wiosenna zieleń","salmon":"łososiowy","darkgrey":"ciemnoszary","ivory":"kość słoniowa","greenyellow":"zielonożółty","mistyrose":"bladoróżany","lightsalmon":"jasnołososiowy","silver":"srebrny [...]
\ No newline at end of file
diff --git a/dojo/nls/pt-pt/colors.js b/dojo/nls/pt-pt/colors.js
new file mode 100644
index 0000000..e01afd2
--- /dev/null
+++ b/dojo/nls/pt-pt/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"azul-aço claro","orangered":"vermelho alaranjado","midnightblue":"azul meia-noite","cadetblue":"azul cadete","seashell":"concha","slategrey":"cinzento ardósia","coral":"coral","darkturquoise":"turquesa escuro","antiquewhite":"branco antigo","mediumspringgreen":"verde primavera médio","salmon":"salmão","darkgrey":"cinzento escuro","ivory":"marfim","greenyellow":"amarelo esverdeado","mistyrose":"rosa pálido","lightsalmon":"salmão claro","silver":"prateado","dimgrey":"ci [...]
\ No newline at end of file
diff --git a/dojo/nls/pt/colors.js b/dojo/nls/pt/colors.js
new file mode 100644
index 0000000..897efc3
--- /dev/null
+++ b/dojo/nls/pt/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"azul-aço claro","orangered":"vermelho alaranjado","midnightblue":"azul meia-noite","cadetblue":"azul cadet","seashell":"seashell","slategrey":"cinza-ardósia","coral":"coral","darkturquoise":"turquesa escuro","antiquewhite":"branco antigo","mediumspringgreen":"verde-primavera médio","salmon":"salmão","darkgrey":"cinza escuro","ivory":"marfim","greenyellow":"amarelo esverdeado","mistyrose":"rosa enevoado","lightsalmon":"salmão claro","silver":"prateado","dimgrey":"cinza [...]
\ No newline at end of file
diff --git a/dojo/nls/ru/colors.js b/dojo/nls/ru/colors.js
new file mode 100644
index 0000000..4b67053
--- /dev/null
+++ b/dojo/nls/ru/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"светлый стальной","orangered":"оранжево-красный","midnightblue":"полуночно-синий","cadetblue":"серо-синий","seashell":"морская раковина","slategrey":"грифельно-серый","coral":"коралловый","darkturquoise":"темный бирюзовый","antiquewhite":"белый антик","mediumspringgreen":"нейтральный весенне-зеленый","salmon":"лососевый","darkgrey":"темно-серый","ivory":"слоновой кости","greenyellow":"зелено-желтый","mistyrose":"блекло-розовый","lightsalmon":"светло-лососевый","silver [...]
\ No newline at end of file
diff --git a/dojo/nls/sk/colors.js b/dojo/nls/sk/colors.js
new file mode 100644
index 0000000..9dbd8e6
--- /dev/null
+++ b/dojo/nls/sk/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"oceľovo modrá svetlá","orangered":"oranžovo červená","midnightblue":"nočná modrá","cadetblue":"sivomodrá","seashell":"lastúrová","slategrey":"bridlicová sivá","coral":"koralová","darkturquoise":"tyrkysová tmavá","antiquewhite":"antická biela","mediumspringgreen":"jarná zelená stredná","salmon":"lososovo ružová","darkgrey":"tmavosivá","ivory":"slonovinová","greenyellow":"žltozelená","mistyrose":"zahmlená ruža","lightsalmon":"lososovo ružová svetlá","silver":"strieborná [...]
\ No newline at end of file
diff --git a/dojo/nls/sl/colors.js b/dojo/nls/sl/colors.js
new file mode 100644
index 0000000..e009ce9
--- /dev/null
+++ b/dojo/nls/sl/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"svetlo jeklena modra","orangered":"oranžno-rdeča","midnightblue":"polnočno modra","cadetblue":"zelenkasto modra","seashell":"morska školjka","slategrey":"skrilasto siva","coral":"koralna","darkturquoise":"temno turkizna","antiquewhite":"antično bela","mediumspringgreen":"srednje pomladno zelena","salmon":"lososova","darkgrey":"temno siva","ivory":"slonokoščena","greenyellow":"zeleno-rumena","mistyrose":"megleno rožnata","lightsalmon":"svetlo lososova","silver":"srebrn [...]
\ No newline at end of file
diff --git a/dojo/nls/sv/colors.js b/dojo/nls/sv/colors.js
new file mode 100644
index 0000000..269e85c
--- /dev/null
+++ b/dojo/nls/sv/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"ljust stålblått","orangered":"orangerött","midnightblue":"midnattsblått","cadetblue":"kadettblått","seashell":"snäckskal","slategrey":"skiffergrått","coral":"korall","darkturquoise":"mörkturkost","antiquewhite":"antikvitt","mediumspringgreen":"mellanvårgrönt","salmon":"laxfärgat","darkgrey":"mörkgrått","ivory":"elfenbensvitt","greenyellow":"gröngult","mistyrose":"dunkelrosa","lightsalmon":"ljust laxfärgat","silver":"silver","dimgrey":"smutsgrått","orange":"orange","wh [...]
\ No newline at end of file
diff --git a/dojo/nls/th/colors.js b/dojo/nls/th/colors.js
new file mode 100644
index 0000000..706ed8a
--- /dev/null
+++ b/dojo/nls/th/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"light steel blue","orangered":"ส้มแกมแดง","midnightblue":"midnight blue","cadetblue":"cadet blue","seashell":"seashell","slategrey":"slate gray","coral":"coral","darkturquoise":"dark turquoise","antiquewhite":"antique white","mediumspringgreen":"medium spring green","salmon":"salmon","darkgrey":"เทาเข้ม","ivory":"งาช้าง","greenyellow":"เขียวแกมเหลือง","mistyrose":"misty rose","lightsalmon":"light salmon","silver":"เงิน","dimgrey":"dim gray","orange":"ส้ม","white":"ขาว [...]
\ No newline at end of file
diff --git a/dojo/nls/tr/colors.js b/dojo/nls/tr/colors.js
new file mode 100644
index 0000000..a75f12f
--- /dev/null
+++ b/dojo/nls/tr/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"açık metalik mavi","orangered":"turuncu kırmızı","midnightblue":"gece mavisi","cadetblue":"denizci mavisi","seashell":"deniz kabuğu","slategrey":"arduvaz grisi","coral":"mercan","darkturquoise":"koyu turkuaz","antiquewhite":"antik beyaz","mediumspringgreen":"orta bahar yeşili","salmon":"somon","darkgrey":"koyu gri","ivory":"fildişi","greenyellow":"yeşil-sarı","mistyrose":"gülkurusu","lightsalmon":"açık somon","silver":"gümüş","dimgrey":"soluk gri","orange":"turuncu"," [...]
\ No newline at end of file
diff --git a/dojo/nls/zh-tw/colors.js b/dojo/nls/zh-tw/colors.js
new file mode 100644
index 0000000..6ee6c5e
--- /dev/null
+++ b/dojo/nls/zh-tw/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"淡鐵藍色","orangered":"橙紅色","midnightblue":"午夜藍","cadetblue":"軍服藍","seashell":"海貝色","slategrey":"岩灰色","coral":"珊瑚紅","darkturquoise":"暗松石綠","antiquewhite":"米白色","mediumspringgreen":"中春綠色","salmon":"鮭紅色","darkgrey":"暗灰色","ivory":"象牙色","greenyellow":"綠黃色","mistyrose":"霧玫瑰色","lightsalmon":"淡鮭紅","silver":"銀色","dimgrey":"昏灰色","orange":"橙色","white":"白色","navajowhite":"印地安黃色","royalblue":"品藍色","deeppink":"深粉紅色","lime":"檸檬色","oldlace":"舊蕾絲色","chartreuse":"淡黃綠色","darkcyan":"暗青色","y [...]
\ No newline at end of file
diff --git a/dojo/nls/zh/colors.js b/dojo/nls/zh/colors.js
new file mode 100644
index 0000000..35368f3
--- /dev/null
+++ b/dojo/nls/zh/colors.js
@@ -0,0 +1 @@
+({"lightsteelblue":"浅钢蓝色","orangered":"橙红色","midnightblue":"深蓝色","cadetblue":"灰蓝色","seashell":"海贝色","slategrey":"灰石色","coral":"珊瑚色","darkturquoise":"深粉蓝","antiquewhite":"古董白","mediumspringgreen":"间春绿色","salmon":"橙红","darkgrey":"深灰色","ivory":"象牙色","greenyellow":"绿黄色","mistyrose":"浅玫瑰色","lightsalmon":"淡橙色","silver":"银白色","dimgrey":"暗灰色","orange":"橙色","white":"白色","navajowhite":"纳瓦白","royalblue":"品蓝","deeppink":"深粉红色","lime":"淡黄绿色","oldlace":"老白色","chartreuse":"黄绿色","darkcyan":"深青绿","yellow [...]
\ No newline at end of file
diff --git a/dojo/number.js b/dojo/number.js
new file mode 100644
index 0000000..d748d72
--- /dev/null
+++ b/dojo/number.js
@@ -0,0 +1,324 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.number"]){
+dojo._hasResource["dojo.number"]=true;
+dojo.provide("dojo.number");
+dojo.require("dojo.i18n");
+dojo.requireLocalization("dojo.cldr","number",null,"ROOT,ar,ca,cs,da,de,de-de,el,en,en-au,en-gb,en-us,es,es-es,fi,fr,he,hu,it,ja,ja-jp,ko,ko-kr,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-cn,zh-tw");
+dojo.require("dojo.string");
+dojo.require("dojo.regexp");
+dojo.number.format=function(_1,_2){
+_2=dojo.mixin({},_2||{});
+var _3=dojo.i18n.normalizeLocale(_2.locale);
+var _4=dojo.i18n.getLocalization("dojo.cldr","number",_3);
+_2.customs=_4;
+var _5=_2.pattern||_4[(_2.type||"decimal")+"Format"];
+if(isNaN(_1)||Math.abs(_1)==Infinity){
+return null;
+}
+return dojo.number._applyPattern(_1,_5,_2);
+};
+dojo.number._numberPatternRE=/[#0,]*[#0](?:\.0*#*)?/;
+dojo.number._applyPattern=function(_6,_7,_8){
+_8=_8||{};
+var _9=_8.customs.group;
+var _a=_8.customs.decimal;
+var _b=_7.split(";");
+var _c=_b[0];
+_7=_b[(_6<0)?1:0]||("-"+_c);
+if(_7.indexOf("%")!=-1){
+_6*=100;
+}else{
+if(_7.indexOf("‰")!=-1){
+_6*=1000;
+}else{
+if(_7.indexOf("¤")!=-1){
+_9=_8.customs.currencyGroup||_9;
+_a=_8.customs.currencyDecimal||_a;
+_7=_7.replace(/\u00a4{1,3}/,function(_d){
+var _e=["symbol","currency","displayName"][_d.length-1];
+return _8[_e]||_8.currency||"";
+});
+}else{
+if(_7.indexOf("E")!=-1){
+throw new Error("exponential notation not supported");
+}
+}
+}
+}
+var _f=dojo.number._numberPatternRE;
+var _10=_c.match(_f);
+if(!_10){
+throw new Error("unable to find a number expression in pattern: "+_7);
+}
+if(_8.fractional===false){
+_8.places=0;
+}
+return _7.replace(_f,dojo.number._formatAbsolute(_6,_10[0],{decimal:_a,group:_9,places:_8.places,round:_8.round}));
+};
+dojo.number.round=function(_11,_12,_13){
+var _14=10/(_13||10);
+return (_14*+_11).toFixed(_12)/_14;
+};
+if((0.9).toFixed()==0){
+(function(){
+var _15=dojo.number.round;
+dojo.number.round=function(v,p,m){
+var d=Math.pow(10,-p||0),a=Math.abs(v);
+if(!v||a>=d||a*Math.pow(10,p+1)<5){
+d=0;
+}
+return _15(v,p,m)+(v>0?d:-d);
+};
+})();
+}
+dojo.number._formatAbsolute=function(_1b,_1c,_1d){
+_1d=_1d||{};
+if(_1d.places===true){
+_1d.places=0;
+}
+if(_1d.places===Infinity){
+_1d.places=6;
+}
+var _1e=_1c.split(".");
+var _1f=(_1d.places>=0)?_1d.places:(_1e[1]&&_1e[1].length)||0;
+if(!(_1d.round<0)){
+_1b=dojo.number.round(_1b,_1f,_1d.round);
+}
+var _20=String(Math.abs(_1b)).split(".");
+var _21=_20[1]||"";
+if(_1d.places){
+var _22=dojo.isString(_1d.places)&&_1d.places.indexOf(",");
+if(_22){
+_1d.places=_1d.places.substring(_22+1);
+}
+_20[1]=dojo.string.pad(_21.substr(0,_1d.places),_1d.places,"0",true);
+}else{
+if(_1e[1]&&_1d.places!==0){
+var pad=_1e[1].lastIndexOf("0")+1;
+if(pad>_21.length){
+_20[1]=dojo.string.pad(_21,pad,"0",true);
+}
+var _24=_1e[1].length;
+if(_24<_21.length){
+_20[1]=_21.substr(0,_24);
+}
+}else{
+if(_20[1]){
+_20.pop();
+}
+}
+}
+var _25=_1e[0].replace(",","");
+pad=_25.indexOf("0");
+if(pad!=-1){
+pad=_25.length-pad;
+if(pad>_20[0].length){
+_20[0]=dojo.string.pad(_20[0],pad);
+}
+if(_25.indexOf("#")==-1){
+_20[0]=_20[0].substr(_20[0].length-pad);
+}
+}
+var _26=_1e[0].lastIndexOf(",");
+var _27,_28;
+if(_26!=-1){
+_27=_1e[0].length-_26-1;
+var _29=_1e[0].substr(0,_26);
+_26=_29.lastIndexOf(",");
+if(_26!=-1){
+_28=_29.length-_26-1;
+}
+}
+var _2a=[];
+for(var _2b=_20[0];_2b;){
+var off=_2b.length-_27;
+_2a.push((off>0)?_2b.substr(off):_2b);
+_2b=(off>0)?_2b.slice(0,off):"";
+if(_28){
+_27=_28;
+delete _28;
+}
+}
+_20[0]=_2a.reverse().join(_1d.group||",");
+return _20.join(_1d.decimal||".");
+};
+dojo.number.regexp=function(_2d){
+return dojo.number._parseInfo(_2d).regexp;
+};
+dojo.number._parseInfo=function(_2e){
+_2e=_2e||{};
+var _2f=dojo.i18n.normalizeLocale(_2e.locale);
+var _30=dojo.i18n.getLocalization("dojo.cldr","number",_2f);
+var _31=_2e.pattern||_30[(_2e.type||"decimal")+"Format"];
+var _32=_30.group;
+var _33=_30.decimal;
+var _34=1;
+if(_31.indexOf("%")!=-1){
+_34/=100;
+}else{
+if(_31.indexOf("‰")!=-1){
+_34/=1000;
+}else{
+var _35=_31.indexOf("¤")!=-1;
+if(_35){
+_32=_30.currencyGroup||_32;
+_33=_30.currencyDecimal||_33;
+}
+}
+}
+var _36=_31.split(";");
+if(_36.length==1){
+_36.push("-"+_36[0]);
+}
+var re=dojo.regexp.buildGroupRE(_36,function(_38){
+_38="(?:"+dojo.regexp.escapeString(_38,".")+")";
+return _38.replace(dojo.number._numberPatternRE,function(_39){
+var _3a={signed:false,separator:_2e.strict?_32:[_32,""],fractional:_2e.fractional,decimal:_33,exponent:false};
+var _3b=_39.split(".");
+var _3c=_2e.places;
+if(_3b.length==1||_3c===0){
+_3a.fractional=false;
+}else{
+if(_3c===undefined){
+_3c=_2e.pattern?_3b[1].lastIndexOf("0")+1:Infinity;
+}
+if(_3c&&_2e.fractional==undefined){
+_3a.fractional=true;
+}
+if(!_2e.places&&(_3c<_3b[1].length)){
+_3c+=","+_3b[1].length;
+}
+_3a.places=_3c;
+}
+var _3d=_3b[0].split(",");
+if(_3d.length>1){
+_3a.groupSize=_3d.pop().length;
+if(_3d.length>1){
+_3a.groupSize2=_3d.pop().length;
+}
+}
+return "("+dojo.number._realNumberRegexp(_3a)+")";
+});
+},true);
+if(_35){
+re=re.replace(/([\s\xa0]*)(\u00a4{1,3})([\s\xa0]*)/g,function(_3e,_3f,_40,_41){
+var _42=["symbol","currency","displayName"][_40.length-1];
+var _43=dojo.regexp.escapeString(_2e[_42]||_2e.currency||"");
+_3f=_3f?"[\\s\\xa0]":"";
+_41=_41?"[\\s\\xa0]":"";
+if(!_2e.strict){
+if(_3f){
+_3f+="*";
+}
+if(_41){
+_41+="*";
+}
+return "(?:"+_3f+_43+_41+")?";
+}
+return _3f+_43+_41;
+});
+}
+return {regexp:re.replace(/[\xa0 ]/g,"[\\s\\xa0]"),group:_32,decimal:_33,factor:_34};
+};
+dojo.number.parse=function(_44,_45){
+var _46=dojo.number._parseInfo(_45);
+var _47=(new RegExp("^"+_46.regexp+"$")).exec(_44);
+if(!_47){
+return NaN;
+}
+var _48=_47[1];
+if(!_47[1]){
+if(!_47[2]){
+return NaN;
+}
+_48=_47[2];
+_46.factor*=-1;
+}
+_48=_48.replace(new RegExp("["+_46.group+"\\s\\xa0"+"]","g"),"").replace(_46.decimal,".");
+return _48*_46.factor;
+};
+dojo.number._realNumberRegexp=function(_49){
+_49=_49||{};
+if(!("places" in _49)){
+_49.places=Infinity;
+}
+if(typeof _49.decimal!="string"){
+_49.decimal=".";
+}
+if(!("fractional" in _49)||/^0/.test(_49.places)){
+_49.fractional=[true,false];
+}
+if(!("exponent" in _49)){
+_49.exponent=[true,false];
+}
+if(!("eSigned" in _49)){
+_49.eSigned=[true,false];
+}
+var _4a=dojo.number._integerRegexp(_49);
+var _4b=dojo.regexp.buildGroupRE(_49.fractional,function(q){
+var re="";
+if(q&&(_49.places!==0)){
+re="\\"+_49.decimal;
+if(_49.places==Infinity){
+re="(?:"+re+"\\d+)?";
+}else{
+re+="\\d{"+_49.places+"}";
+}
+}
+return re;
+},true);
+var _4e=dojo.regexp.buildGroupRE(_49.exponent,function(q){
+if(q){
+return "([eE]"+dojo.number._integerRegexp({signed:_49.eSigned})+")";
+}
+return "";
+});
+var _50=_4a+_4b;
+if(_4b){
+_50="(?:(?:"+_50+")|(?:"+_4b+"))";
+}
+return _50+_4e;
+};
+dojo.number._integerRegexp=function(_51){
+_51=_51||{};
+if(!("signed" in _51)){
+_51.signed=[true,false];
+}
+if(!("separator" in _51)){
+_51.separator="";
+}else{
+if(!("groupSize" in _51)){
+_51.groupSize=3;
+}
+}
+var _52=dojo.regexp.buildGroupRE(_51.signed,function(q){
+return q?"[-+]":"";
+},true);
+var _54=dojo.regexp.buildGroupRE(_51.separator,function(sep){
+if(!sep){
+return "(?:\\d+)";
+}
+sep=dojo.regexp.escapeString(sep);
+if(sep==" "){
+sep="\\s";
+}else{
+if(sep==" "){
+sep="\\s\\xa0";
+}
+}
+var grp=_51.groupSize,_57=_51.groupSize2;
+if(_57){
+var _58="(?:0|[1-9]\\d{0,"+(_57-1)+"}(?:["+sep+"]\\d{"+_57+"})*["+sep+"]\\d{"+grp+"})";
+return ((grp-_57)>0)?"(?:"+_58+"|(?:0|[1-9]\\d{0,"+(grp-1)+"}))":_58;
+}
+return "(?:0|[1-9]\\d{0,"+(grp-1)+"}(?:["+sep+"]\\d{"+grp+"})*)";
+},true);
+return _52+_54;
+};
+}
diff --git a/dojo/parser.js b/dojo/parser.js
new file mode 100644
index 0000000..0302637
--- /dev/null
+++ b/dojo/parser.js
@@ -0,0 +1,228 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.parser"]){
+dojo._hasResource["dojo.parser"]=true;
+dojo.provide("dojo.parser");
+dojo.require("dojo.date.stamp");
+dojo.parser=new function(){
+var d=dojo;
+var _2=d._scopeName+"Type";
+var _3="["+_2+"]";
+var _4=0,_5={};
+var _6=function(_7,_8){
+var _9=_8||_5;
+if(dojo.isIE){
+var cn=_7["__dojoNameCache"];
+if(cn&&_9[cn]===_7){
+return cn;
+}
+}
+var _b;
+do{
+_b="__"+_4++;
+}while(_b in _9);
+_9[_b]=_7;
+return _b;
+};
+function _c(_d){
+if(d.isString(_d)){
+return "string";
+}
+if(typeof _d=="number"){
+return "number";
+}
+if(typeof _d=="boolean"){
+return "boolean";
+}
+if(d.isFunction(_d)){
+return "function";
+}
+if(d.isArray(_d)){
+return "array";
+}
+if(_d instanceof Date){
+return "date";
+}
+if(_d instanceof d._Url){
+return "url";
+}
+return "object";
+};
+function _e(_f,_10){
+switch(_10){
+case "string":
+return _f;
+case "number":
+return _f.length?Number(_f):NaN;
+case "boolean":
+return typeof _f=="boolean"?_f:!(_f.toLowerCase()=="false");
+case "function":
+if(d.isFunction(_f)){
+_f=_f.toString();
+_f=d.trim(_f.substring(_f.indexOf("{")+1,_f.length-1));
+}
+try{
+if(_f.search(/[^\w\.]+/i)!=-1){
+_f=_6(new Function(_f),this);
+}
+return d.getObject(_f,false);
+}
+catch(e){
+return new Function();
+}
+case "array":
+return _f?_f.split(/\s*,\s*/):[];
+case "date":
+switch(_f){
+case "":
+return new Date("");
+case "now":
+return new Date();
+default:
+return d.date.stamp.fromISOString(_f);
+}
+case "url":
+return d.baseUrl+_f;
+default:
+return d.fromJson(_f);
+}
+};
+var _11={};
+function _12(_13){
+if(!_11[_13]){
+var cls=d.getObject(_13);
+if(!d.isFunction(cls)){
+throw new Error("Could not load class '"+_13+"'. Did you spell the name correctly and use a full path, like 'dijit.form.Button'?");
+}
+var _15=cls.prototype;
+var _16={},_17={};
+for(var _18 in _15){
+if(_18.charAt(0)=="_"){
+continue;
+}
+if(_18 in _17){
+continue;
+}
+var _19=_15[_18];
+_16[_18]=_c(_19);
+}
+_11[_13]={cls:cls,params:_16};
+}
+return _11[_13];
+};
+this._functionFromScript=function(_1a){
+var _1b="";
+var _1c="";
+var _1d=_1a.getAttribute("args");
+if(_1d){
+d.forEach(_1d.split(/\s*,\s*/),function(_1e,idx){
+_1b+="var "+_1e+" = arguments["+idx+"]; ";
+});
+}
+var _20=_1a.getAttribute("with");
+if(_20&&_20.length){
+d.forEach(_20.split(/\s*,\s*/),function(_21){
+_1b+="with("+_21+"){";
+_1c+="}";
+});
+}
+return new Function(_1b+_1a.innerHTML+_1c);
+};
+this.instantiate=function(_22,_23){
+var _24=[];
+_23=_23||{};
+d.forEach(_22,function(_25){
+if(!_25){
+return;
+}
+var _26=_2 in _23?_23[_2]:_25.getAttribute(_2);
+if(!_26||!_26.length){
+return;
+}
+var _27=_12(_26),_28=_27.cls,ps=_28._noScript||_28.prototype._noScript;
+var _2a={},_2b=_25.attributes;
+for(var _2c in _27.params){
+var _2d=_2c in _23?{value:_23[_2c],specified:true}:_2b.getNamedItem(_2c);
+if(!_2d||(!_2d.specified&&(!dojo.isIE||_2c.toLowerCase()!="value"))){
+continue;
+}
+var _2e=_2d.value;
+switch(_2c){
+case "class":
+_2e="className" in _23?_23.className:_25.className;
+break;
+case "style":
+_2e="style" in _23?_23.style:(_25.style&&_25.style.cssText);
+}
+var _2f=_27.params[_2c];
+if(typeof _2e=="string"){
+_2a[_2c]=_e(_2e,_2f);
+}else{
+_2a[_2c]=_2e;
+}
+}
+if(!ps){
+var _30=[],_31=[];
+d.query("> script[type^='dojo/']",_25).orphan().forEach(function(_32){
+var _33=_32.getAttribute("event"),_26=_32.getAttribute("type"),nf=d.parser._functionFromScript(_32);
+if(_33){
+if(_26=="dojo/connect"){
+_30.push({event:_33,func:nf});
+}else{
+_2a[_33]=nf;
+}
+}else{
+_31.push(nf);
+}
+});
+}
+var _35=_28["markupFactory"];
+if(!_35&&_28["prototype"]){
+_35=_28.prototype["markupFactory"];
+}
+var _36=_35?_35(_2a,_25,_28):new _28(_2a,_25);
+_24.push(_36);
+var _37=_25.getAttribute("jsId");
+if(_37){
+d.setObject(_37,_36);
+}
+if(!ps){
+d.forEach(_30,function(_38){
+d.connect(_36,_38.event,null,_38.func);
+});
+d.forEach(_31,function(_39){
+_39.call(_36);
+});
+}
+});
+d.forEach(_24,function(_3a){
+if(_3a&&_3a.startup&&!_3a._started&&(!_3a.getParent||!_3a.getParent())){
+_3a.startup();
+}
+});
+return _24;
+};
+this.parse=function(_3b){
+var _3c=d.query(_3,_3b);
+var _3d=this.instantiate(_3c);
+return _3d;
+};
+}();
+(function(){
+var _3e=function(){
+if(dojo.config["parseOnLoad"]==true){
+dojo.parser.parse();
+}
+};
+if(dojo.exists("dijit.wai.onload")&&(dijit.wai.onload===dojo._loaders[0])){
+dojo._loaders.splice(1,0,_3e);
+}else{
+dojo._loaders.unshift(_3e);
+}
+})();
+}
diff --git a/dojo/regexp.js b/dojo/regexp.js
new file mode 100644
index 0000000..7018bad
--- /dev/null
+++ b/dojo/regexp.js
@@ -0,0 +1,32 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.regexp"]){
+dojo._hasResource["dojo.regexp"]=true;
+dojo.provide("dojo.regexp");
+dojo.regexp.escapeString=function(_1,_2){
+return _1.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g,function(ch){
+if(_2&&_2.indexOf(ch)!=-1){
+return ch;
+}
+return "\\"+ch;
+});
+};
+dojo.regexp.buildGroupRE=function(_4,re,_6){
+if(!(_4 instanceof Array)){
+return re(_4);
+}
+var b=[];
+for(var i=0;i<_4.length;i++){
+b.push(re(_4[i]));
+}
+return dojo.regexp.group(b.join("|"),_6);
+};
+dojo.regexp.group=function(_9,_a){
+return "("+(_a?"?:":"")+_9+")";
+};
+}
diff --git a/dojo/resources/LICENSE b/dojo/resources/LICENSE
new file mode 100644
index 0000000..eb28b7e
--- /dev/null
+++ b/dojo/resources/LICENSE
@@ -0,0 +1,30 @@
+License Disclaimer:
+
+All contents of this directory are Copyright (c) the Dojo Foundation, with the
+following exceptions:
+-------------------------------------------------------------------------------
+
+dojo.css:
+	* parts Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+	  Distributed under the terms of the BSD License
+
+The Program includes all or portions of the following software which was obtained under the terms and conditions of the BSD License.
+
+http://developer.yahoo.com/yui/license.html
+
+Copyright (c) 2007, Yahoo! Inc.
+ All rights reserved.
+ Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the 
+documentation and/or other materials provided with the distribution.
+ * Neither the name of Yahoo! Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without 
+specific prior written permission of Yahoo! Inc. 
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 
+OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
diff --git a/dojo/resources/_modules.js b/dojo/resources/_modules.js
new file mode 100644
index 0000000..0b276e5
--- /dev/null
+++ b/dojo/resources/_modules.js
@@ -0,0 +1,7 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
diff --git a/dojo/resources/blank.gif b/dojo/resources/blank.gif
new file mode 100644
index 0000000..e565824
Binary files /dev/null and b/dojo/resources/blank.gif differ
diff --git a/dojo/resources/blank.html b/dojo/resources/blank.html
new file mode 100644
index 0000000..40fe770
--- /dev/null
+++ b/dojo/resources/blank.html
@@ -0,0 +1 @@
+<html><head><script>isLoaded = true;</script></head><body></body></html>
diff --git a/dojo/resources/dnd.css b/dojo/resources/dnd.css
new file mode 100644
index 0000000..8bf39e7
--- /dev/null
+++ b/dojo/resources/dnd.css
@@ -0,0 +1,9 @@
+
+.dojoDndAvatar			{font-size: 75%; color: black;}
+.dojoDndAvatarHeader td	{padding-left: 20px; padding-right: 4px;}
+.dojoDndAvatarHeader	{background: #ccc;}
+.dojoDndAvatarItem		{background: #eee;}
+.dojoDndMove .dojoDndAvatarHeader	{background-image: url(images/dndNoMove.png); background-repeat: no-repeat;}
+.dojoDndCopy .dojoDndAvatarHeader	{background-image: url(images/dndNoCopy.png); background-repeat: no-repeat;}
+.dojoDndMove .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{background-image: url(images/dndMove.png); background-repeat: no-repeat;}
+.dojoDndCopy .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{background-image: url(images/dndCopy.png); background-repeat: no-repeat;}
diff --git a/dojo/resources/dojo.css b/dojo/resources/dojo.css
new file mode 100644
index 0000000..16e0950
--- /dev/null
+++ b/dojo/resources/dojo.css
@@ -0,0 +1,99 @@
+
+body, div, dl, dt, dd, li, h1, h2, h3, h4, h5, h6, pre, form, fieldset, input, textarea, p, blockquote, th, td {
+	margin: 0;
+	padding: 0;
+}
+fieldset, img {
+	border: 0 none;
+}
+address, caption, cite, code, dfn, th, var {
+	font-style: normal; 
+	font-weight: normal;
+}
+caption, th {
+	text-align: left;
+}
+q:before, q:after {
+	content:"";
+}
+abbr, acronym {
+	border:0;
+}
+body { 
+	font: 12px Myriad,Helvetica,Tahoma,Arial,clean,sans-serif; 
+	*font-size: 75%;
+}
+h1 {
+	font-size: 1.5em; 
+	font-weight: normal;
+	line-height: 1em; 
+	margin-top: 1em;
+	margin-bottom:0;
+}
+h2 { 
+	font-size: 1.1667em; 
+	font-weight: bold; 
+	line-height: 1.286em; 
+	margin-top: 1.929em; 
+	margin-bottom:0.643em;
+}
+h3, h4, h5, h6 {
+	font-size: 1em; 
+	font-weight: bold; 
+	line-height: 1.5em; 
+	margin-top: 1.5em; 
+	margin-bottom: 0;
+}
+p { 
+	font-size: 1em; 
+	margin-top: 1.5em; 
+	margin-bottom: 1.5em; 
+	line-height: 1.5em;
+}
+blockquote { 
+	font-size: 0.916em; 
+	margin-top: 3.272em; 
+	margin-bottom: 3.272em; 
+	line-height: 1.636em; 
+	padding: 1.636em; 
+	border-top: 1px solid #ccc; 
+	border-bottom: 1px solid #ccc;
+}
+ol li, ul li { 
+	font-size: 1em; 
+	line-height: 1.5em; 
+	margin: 0;
+}
+pre, code { 
+	font-size:115%;
+	*font-size:100%;
+	font-family: Courier, "Courier New"; 
+	background-color: #efefef; 
+	border: 1px solid #ccc;
+}
+pre { 
+	border-width: 1px 0; 
+	padding: 1.5em;
+}
+table {  font-size:100%; }
+table.dojoTabular { 
+	border-collapse: collapse; 
+	border-spacing: 0; 
+	border: 1px solid #ccc; 
+	margin: 0 1.5em;
+}
+.dojoTabular th { 
+	text-align: center; 
+	font-weight: bold;
+}
+table.dojoTabular thead, table.dojoTabular tfoot { 
+	background-color: #efefef; 
+	border: 1px solid #ccc; 
+	border-width: 1px 0; 
+}
+table.dojoTabular thead tr th,
+table.dojoTabular thead tr td,
+table.dojoTabular tbody tr td,
+table.dojoTabular tfoot tr td { 
+	padding: 0.25em 0.5em;
+}
diff --git a/dojo/resources/iframe_history.html b/dojo/resources/iframe_history.html
new file mode 100644
index 0000000..aee368f
--- /dev/null
+++ b/dojo/resources/iframe_history.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+	<title></title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<script type="text/javascript">
+	// <!--
+	var noInit = false;
+	
+	function defineParams(sparams){
+		if(sparams){
+			var ss = (sparams.indexOf("&") >= 0) ? "&" : "&";
+			sparams = sparams.split(ss);
+			for(var x=0; x<sparams.length; x++){
+				var tp = sparams[x].split("=");
+				if(typeof window[tp[0]] != "undefined"){
+					window[tp[0]] = ((tp[1]=="true")||(tp[1]=="false")) ? eval(tp[1]) : tp[1];
+				}
+			}
+		}
+	}
+	
+	function init(){
+		// parse the query string if there is one to try to get params that
+		// we can act on. Also allow params to be in a fragment identifier.
+		var query = null;
+		var frag = null;
+		var url = document.location.href;
+		var hashIndex = url.indexOf("#");
+		
+		//Extract fragment identifier
+		if(hashIndex != -1){
+			frag = url.substring(hashIndex + 1, url.length);
+			url = url.substring(0, hashIndex);
+		}
+
+		//Extract querystring
+		var parts = url.split("?");
+		if(parts.length == 2){
+			query = parts[1];
+		}
+
+		defineParams(query);
+		defineParams(frag);
+
+		if(noInit){ return; }
+		var hasParentDojo = false;
+		try{
+			hasParentDojo = window.parent != window && window.parent["dojo"];
+		}catch(e){
+			alert("Initializing iframe_history.html failed. If you are using a cross-domain Dojo build,"
+				+ " please save iframe_history.html to your domain and set djConfig.dojoIframeHistoryUrl"
+				+ " to the path on your domain to iframe_history.html");
+			throw e;
+		}
+
+		if(hasParentDojo){
+			//Set the page title so IE history shows up with a somewhat correct name.
+			document.title = window.parent.document.title;
+			
+			//Notify parent that we are loaded.
+			var pdj = window.parent.dojo;
+			if(pdj["back"]){
+				pdj.back._iframeLoaded(null, window.location);
+			}
+		}
+
+	}
+	// -->
+	</script>
+</head>
+<body onload="try{ init(); }catch(e){ alert(e); }">
+	<h4>The Dojo Toolkit -- iframe_history.html</h4>
+
+	<p>This file is used in Dojo's back/fwd button management.</p>
+</body>
+</html>
diff --git a/dojo/resources/images/dndCopy.png b/dojo/resources/images/dndCopy.png
new file mode 100644
index 0000000..660ca4f
Binary files /dev/null and b/dojo/resources/images/dndCopy.png differ
diff --git a/dojo/resources/images/dndMove.png b/dojo/resources/images/dndMove.png
new file mode 100644
index 0000000..74af29c
Binary files /dev/null and b/dojo/resources/images/dndMove.png differ
diff --git a/dojo/resources/images/dndNoCopy.png b/dojo/resources/images/dndNoCopy.png
new file mode 100644
index 0000000..87f3aa0
Binary files /dev/null and b/dojo/resources/images/dndNoCopy.png differ
diff --git a/dojo/resources/images/dndNoMove.png b/dojo/resources/images/dndNoMove.png
new file mode 100644
index 0000000..d75ed86
Binary files /dev/null and b/dojo/resources/images/dndNoMove.png differ
diff --git a/dojo/robot.js b/dojo/robot.js
new file mode 100644
index 0000000..2703058
--- /dev/null
+++ b/dojo/robot.js
@@ -0,0 +1,49 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.robot"]){
+dojo._hasResource["dojo.robot"]=true;
+dojo.provide("dojo.robot");
+dojo.experimental("dojo.robot");
+dojo.require("doh.robot");
+(function(){
+dojo.mixin(doh.robot,{_scrollIntoView:function(_1){
+if(typeof _1=="function"){
+_1=_1();
+}
+_1.scrollIntoView(false);
+},scrollIntoView:function(_2,_3){
+doh.robot.sequence(function(){
+doh.robot._scrollIntoView(_2);
+},_3);
+},mouseMoveAt:function(_4,_5,_6,_7,_8){
+doh.robot._assertRobot();
+_6=_6||100;
+this.sequence(function(){
+if(typeof _4=="function"){
+_4=_4();
+}
+if(!_4){
+return;
+}
+_4=dojo.byId(_4);
+if(_8===undefined){
+var _9=dojo.contentBox(_4);
+_7=_9.w/2;
+_8=_9.h/2;
+}
+var x=_7;
+var y=_8;
+doh.robot._scrollIntoView(_4);
+var c=dojo.coords(_4);
+x+=c.x;
+y+=c.y;
+doh.robot._mouseMove(x,y,false,_6);
+},_5,_6);
+}});
+})();
+}
diff --git a/dojo/robotx.js b/dojo/robotx.js
new file mode 100644
index 0000000..9f68845
--- /dev/null
+++ b/dojo/robotx.js
@@ -0,0 +1,80 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.robotx"]){
+dojo._hasResource["dojo.robotx"]=true;
+dojo.provide("dojo.robotx");
+dojo.require("dojo.robot");
+dojo.experimental("dojo.robotx");
+(function(){
+doh.robot._runsemaphore.lock.push("dojo.robotx.lock");
+var _1=document.getElementById("robotapplication");
+var _2=dojo.connect(doh,"_groupStarted",function(){
+dojo.disconnect(_2);
+_1.style.visibility="visible";
+});
+var _3=function(){
+doh.robot._updateDocument();
+_3=null;
+var _4=(document.compatMode=="BackCompat")?document.body:document.documentElement;
+var _5=document.getElementById("robotconsole").offsetHeight;
+if(_5){
+_1.style.height=(_4.clientHeight-_5)+"px";
+}
+doh.run();
+};
+var _6=function(){
+if(_3){
+_3();
+}
+var _7=dojo.connect(dojo.body(),"onunload",function(){
+dojo.global=window;
+dojo.doc=document;
+dojo.disconnect(_7);
+});
+};
+dojo.config.debugContainerId="robotconsole";
+dojo.config.debugHeight=dojo.config.debugHeight||200;
+document.write("<div id=\"robotconsole\" style=\"position:absolute;left:0px;bottom:0px;width:100%;\"></div>");
+_1=document.createElement("iframe");
+_1.setAttribute("ALLOWTRANSPARENCY","true");
+_1.scrolling=dojo.isIE?"yes":"auto";
+dojo.style(_1,{visibility:"hidden",border:"0px none",padding:"0px",margin:"0px",position:"absolute",left:"0px",top:"0px",width:"100%",height:"100%"});
+if(_1["attachEvent"]!==undefined){
+_1.attachEvent("onload",_6);
+}else{
+dojo.connect(_1,"onload",_6);
+}
+dojo.mixin(doh.robot,{_updateDocument:function(){
+dojo.setContext(_1.contentWindow,_1.contentWindow.document);
+var _8=dojo.global;
+if(_8["dojo"]){
+dojo._topics=_8.dojo._topics;
+}
+},initRobot:function(_9){
+_1.src=_9;
+dojo.addOnLoad(function(){
+var _a={overflow:dojo.isWebKit?"hidden":"visible",margin:"0px",borderWidth:"0px",height:"100%",width:"100%"};
+dojo.style(document.documentElement,_a);
+dojo.style(document.body,_a);
+document.body.appendChild(_1);
+var _b=document.createElement("base");
+_b.href=_9;
+document.getElementsByTagName("head")[0].appendChild(_b);
+});
+},waitForPageToLoad:function(_c){
+var d=new doh.Deferred();
+_3=function(){
+_3=null;
+doh.robot._updateDocument();
+d.callback(true);
+};
+_c();
+return d;
+}});
+})();
+}
diff --git a/dojo/rpc/JsonService.js b/dojo/rpc/JsonService.js
new file mode 100644
index 0000000..989c931
--- /dev/null
+++ b/dojo/rpc/JsonService.js
@@ -0,0 +1,37 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.rpc.JsonService"]){
+dojo._hasResource["dojo.rpc.JsonService"]=true;
+dojo.provide("dojo.rpc.JsonService");
+dojo.require("dojo.rpc.RpcService");
+dojo.declare("dojo.rpc.JsonService",dojo.rpc.RpcService,{bustCache:false,contentType:"application/json-rpc",lastSubmissionId:0,callRemote:function(_1,_2){
+var _3=new dojo.Deferred();
+this.bind(_1,_2,_3);
+return _3;
+},bind:function(_4,_5,_6,_7){
+var _8=dojo.rawXhrPost({url:_7||this.serviceUrl,postData:this.createRequest(_4,_5),contentType:this.contentType,timeout:this.timeout,handleAs:"json-comment-optional"});
+_8.addCallbacks(this.resultCallback(_6),this.errorCallback(_6));
+},createRequest:function(_9,_a){
+var _b={"params":_a,"method":_9,"id":++this.lastSubmissionId};
+var _c=dojo.toJson(_b);
+return _c;
+},parseResults:function(_d){
+if(dojo.isObject(_d)){
+if("result" in _d){
+return _d.result;
+}
+if("Result" in _d){
+return _d.Result;
+}
+if("ResultSet" in _d){
+return _d.ResultSet;
+}
+}
+return _d;
+}});
+}
diff --git a/dojo/rpc/JsonpService.js b/dojo/rpc/JsonpService.js
new file mode 100644
index 0000000..1704364
--- /dev/null
+++ b/dojo/rpc/JsonpService.js
@@ -0,0 +1,32 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.rpc.JsonpService"]){
+dojo._hasResource["dojo.rpc.JsonpService"]=true;
+dojo.provide("dojo.rpc.JsonpService");
+dojo.require("dojo.rpc.RpcService");
+dojo.require("dojo.io.script");
+dojo.declare("dojo.rpc.JsonpService",dojo.rpc.RpcService,{constructor:function(_1,_2){
+if(this.required){
+if(_2){
+dojo.mixin(this.required,_2);
+}
+dojo.forEach(this.required,function(_3){
+if(_3==""||_3==undefined){
+throw new Error("Required Service Argument not found: "+_3);
+}
+});
+}
+},strictArgChecks:false,bind:function(_4,_5,_6,_7){
+var _8=dojo.io.script.get({url:_7||this.serviceUrl,callbackParamName:this.callbackParamName||"callback",content:this.createRequest(_5),timeout:this.timeout,handleAs:"json",preventCache:true});
+_8.addCallbacks(this.resultCallback(_6),this.errorCallback(_6));
+},createRequest:function(_9){
+var _a=(dojo.isArrayLike(_9)&&_9.length==1)?_9[0]:{};
+dojo.mixin(_a,this.required);
+return _a;
+}});
+}
diff --git a/dojo/rpc/RpcService.js b/dojo/rpc/RpcService.js
new file mode 100644
index 0000000..1eb10bb
--- /dev/null
+++ b/dojo/rpc/RpcService.js
@@ -0,0 +1,89 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.rpc.RpcService"]){
+dojo._hasResource["dojo.rpc.RpcService"]=true;
+dojo.provide("dojo.rpc.RpcService");
+dojo.declare("dojo.rpc.RpcService",null,{constructor:function(_1){
+if(_1){
+if((dojo.isString(_1))||(_1 instanceof dojo._Url)){
+if(_1 instanceof dojo._Url){
+var _2=_1+"";
+}else{
+_2=_1;
+}
+var _3=dojo.xhrGet({url:_2,handleAs:"json-comment-optional",sync:true});
+_3.addCallback(this,"processSmd");
+_3.addErrback(function(){
+throw new Error("Unable to load SMD from "+_1);
+});
+}else{
+if(_1.smdStr){
+this.processSmd(dojo.eval("("+_1.smdStr+")"));
+}else{
+if(_1.serviceUrl){
+this.serviceUrl=_1.serviceUrl;
+}
+this.timeout=_1.timeout||3000;
+if("strictArgChecks" in _1){
+this.strictArgChecks=_1.strictArgChecks;
+}
+this.processSmd(_1);
+}
+}
+}
+},strictArgChecks:true,serviceUrl:"",parseResults:function(_4){
+return _4;
+},errorCallback:function(_5){
+return function(_6){
+_5.errback(_6.message);
+};
+},resultCallback:function(_7){
+var tf=dojo.hitch(this,function(_9){
+if(_9.error!=null){
+var _a;
+if(typeof _9.error=="object"){
+_a=new Error(_9.error.message);
+_a.code=_9.error.code;
+_a.error=_9.error.error;
+}else{
+_a=new Error(_9.error);
+}
+_a.id=_9.id;
+_a.errorObject=_9;
+_7.errback(_a);
+}else{
+_7.callback(this.parseResults(_9));
+}
+});
+return tf;
+},generateMethod:function(_b,_c,_d){
+return dojo.hitch(this,function(){
+var _e=new dojo.Deferred();
+if((this.strictArgChecks)&&(_c!=null)&&(arguments.length!=_c.length)){
+throw new Error("Invalid number of parameters for remote method.");
+}else{
+this.bind(_b,dojo._toArray(arguments),_e,_d);
+}
+return _e;
+});
+},processSmd:function(_f){
+if(_f.methods){
+dojo.forEach(_f.methods,function(m){
+if(m&&m.name){
+this[m.name]=this.generateMethod(m.name,m.parameters,m.url||m.serviceUrl||m.serviceURL);
+if(!dojo.isFunction(this[m.name])){
+throw new Error("RpcService: Failed to create"+m.name+"()");
+}
+}
+},this);
+}
+this.serviceUrl=_f.serviceUrl||_f.serviceURL;
+this.required=_f.required;
+this.smd=_f;
+}});
+}
diff --git a/dojo/string.js b/dojo/string.js
new file mode 100644
index 0000000..eef037a
--- /dev/null
+++ b/dojo/string.js
@@ -0,0 +1,57 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojo.string"]){
+dojo._hasResource["dojo.string"]=true;
+dojo.provide("dojo.string");
+dojo.string.rep=function(_1,_2){
+if(_2<=0||!_1){
+return "";
+}
+var _3=[];
+for(;;){
+if(_2&1){
+_3.push(_1);
+}
+if(!(_2>>=1)){
+break;
+}
+_1+=_1;
+}
+return _3.join("");
+};
+dojo.string.pad=function(_4,_5,ch,_7){
+if(!ch){
+ch="0";
+}
+var _8=String(_4),_9=dojo.string.rep(ch,Math.ceil((_5-_8.length)/ch.length));
+return _7?_8+_9:_9+_8;
+};
+dojo.string.substitute=function(_a,_b,_c,_d){
+_d=_d||dojo.global;
+_c=(!_c)?function(v){
+return v;
+}:dojo.hitch(_d,_c);
+return _a.replace(/\$\{([^\s\:\}]+)(?:\:([^\s\:\}]+))?\}/g,function(_f,key,_11){
+var _12=dojo.getObject(key,false,_b);
+if(_11){
+_12=dojo.getObject(_11,false,_d).call(_d,_12,key);
+}
+return _c(_12,key).toString();
+});
+};
+dojo.string.trim=String.prototype.trim?dojo.trim:function(str){
+str=str.replace(/^\s+/,"");
+for(var i=str.length-1;i>=0;i--){
+if(/\S/.test(str.charAt(i))){
+str=str.substring(0,i+1);
+break;
+}
+}
+return str;
+};
+}
diff --git a/dojox/LICENSE b/dojox/LICENSE
new file mode 100644
index 0000000..ad1676a
--- /dev/null
+++ b/dojox/LICENSE
@@ -0,0 +1,195 @@
+Dojo is available under *either* the terms of the modified BSD license *or* the
+Academic Free License version 2.1. As a recipient of Dojo, you may choose which
+license to receive this code under (except as noted in per-module LICENSE
+files). Some modules may not be the copyright of the Dojo Foundation. These
+modules contain explicit declarations of copyright in both the LICENSE files in
+the directories in which they reside and in the code itself. No external
+contributions are allowed under licenses which are fundamentally incompatible
+with the AFL or BSD licenses that Dojo is distributed under.
+
+The text of the AFL and BSD licenses is reproduced below. 
+
+-------------------------------------------------------------------------------
+The "New" BSD License:
+**********************
+
+Copyright (c) 2005-2009, The Dojo Foundation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice, this
+    list of conditions and the following disclaimer.
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+  * Neither the name of the Dojo Foundation nor the names of its contributors
+    may be used to endorse or promote products derived from this software
+    without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+-------------------------------------------------------------------------------
+The Academic Free License, v. 2.1:
+**********************************
+
+This Academic Free License (the "License") applies to any original work of
+authorship (the "Original Work") whose owner (the "Licensor") has placed the
+following notice immediately following the copyright notice for the Original
+Work:
+
+Licensed under the Academic Free License version 2.1
+
+1) Grant of Copyright License. Licensor hereby grants You a world-wide,
+royalty-free, non-exclusive, perpetual, sublicenseable license to do the
+following:
+
+a) to reproduce the Original Work in copies;
+
+b) to prepare derivative works ("Derivative Works") based upon the Original
+Work;
+
+c) to distribute copies of the Original Work and Derivative Works to the
+public;
+
+d) to perform the Original Work publicly; and
+
+e) to display the Original Work publicly.
+
+2) Grant of Patent License. Licensor hereby grants You a world-wide,
+royalty-free, non-exclusive, perpetual, sublicenseable license, under patent
+claims owned or controlled by the Licensor that are embodied in the Original
+Work as furnished by the Licensor, to make, use, sell and offer for sale the
+Original Work and Derivative Works.
+
+3) Grant of Source Code License. The term "Source Code" means the preferred
+form of the Original Work for making modifications to it and all available
+documentation describing how to modify the Original Work. Licensor hereby
+agrees to provide a machine-readable copy of the Source Code of the Original
+Work along with each copy of the Original Work that Licensor distributes.
+Licensor reserves the right to satisfy this obligation by placing a
+machine-readable copy of the Source Code in an information repository
+reasonably calculated to permit inexpensive and convenient access by You for as
+long as Licensor continues to distribute the Original Work, and by publishing
+the address of that information repository in a notice immediately following
+the copyright notice that applies to the Original Work.
+
+4) Exclusions From License Grant. Neither the names of Licensor, nor the names
+of any contributors to the Original Work, nor any of their trademarks or
+service marks, may be used to endorse or promote products derived from this
+Original Work without express prior written permission of the Licensor. Nothing
+in this License shall be deemed to grant any rights to trademarks, copyrights,
+patents, trade secrets or any other intellectual property of Licensor except as
+expressly stated herein. No patent license is granted to make, use, sell or
+offer to sell embodiments of any patent claims other than the licensed claims
+defined in Section 2. No right is granted to the trademarks of Licensor even if
+such marks are included in the Original Work. Nothing in this License shall be
+interpreted to prohibit Licensor from licensing under different terms from this
+License any Original Work that Licensor otherwise would have a right to
+license.
+
+5) This section intentionally omitted.
+
+6) Attribution Rights. You must retain, in the Source Code of any Derivative
+Works that You create, all copyright, patent or trademark notices from the
+Source Code of the Original Work, as well as any notices of licensing and any
+descriptive text identified therein as an "Attribution Notice." You must cause
+the Source Code for any Derivative Works that You create to carry a prominent
+Attribution Notice reasonably calculated to inform recipients that You have
+modified the Original Work.
+
+7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that
+the copyright in and to the Original Work and the patent rights granted herein
+by Licensor are owned by the Licensor or are sublicensed to You under the terms
+of this License with the permission of the contributor(s) of those copyrights
+and patent rights. Except as expressly stated in the immediately proceeding
+sentence, the Original Work is provided under this License on an "AS IS" BASIS
+and WITHOUT WARRANTY, either express or implied, including, without limitation,
+the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU.
+This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No
+license to Original Work is granted hereunder except under this disclaimer.
+
+8) Limitation of Liability. Under no circumstances and under no legal theory,
+whether in tort (including negligence), contract, or otherwise, shall the
+Licensor be liable to any person for any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License
+or the use of the Original Work including, without limitation, damages for loss
+of goodwill, work stoppage, computer failure or malfunction, or any and all
+other commercial damages or losses. This limitation of liability shall not
+apply to liability for death or personal injury resulting from Licensor's
+negligence to the extent applicable law prohibits such limitation. Some
+jurisdictions do not allow the exclusion or limitation of incidental or
+consequential damages, so this exclusion and limitation may not apply to You.
+
+9) Acceptance and Termination. If You distribute copies of the Original Work or
+a Derivative Work, You must make a reasonable effort under the circumstances to
+obtain the express assent of recipients to the terms of this License. Nothing
+else but this License (or another written agreement between Licensor and You)
+grants You permission to create Derivative Works based upon the Original Work
+or to exercise any of the rights granted in Section 1 herein, and any attempt
+to do so except under the terms of this License (or another written agreement
+between Licensor and You) is expressly prohibited by U.S. copyright law, the
+equivalent laws of other countries, and by international treaty. Therefore, by
+exercising any of the rights granted to You in Section 1 herein, You indicate
+Your acceptance of this License and all of its terms and conditions.
+
+10) Termination for Patent Action. This License shall terminate automatically
+and You may no longer exercise any of the rights granted to You by this License
+as of the date You commence an action, including a cross-claim or counterclaim,
+against Licensor or any licensee alleging that the Original Work infringes a
+patent. This termination provision shall not apply for an action alleging
+patent infringement by combinations of the Original Work with other software or
+hardware.
+
+11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this
+License may be brought only in the courts of a jurisdiction wherein the
+Licensor resides or in which Licensor conducts its primary business, and under
+the laws of that jurisdiction excluding its conflict-of-law provisions. The
+application of the United Nations Convention on Contracts for the International
+Sale of Goods is expressly excluded. Any use of the Original Work outside the
+scope of this License or after its termination shall be subject to the
+requirements and penalties of the U.S. Copyright Act, 17 U.S.C. § 101 et
+seq., the equivalent laws of other countries, and international treaty. This
+section shall survive the termination of this License.
+
+12) Attorneys Fees. In any action to enforce the terms of this License or
+seeking damages relating thereto, the prevailing party shall be entitled to
+recover its costs and expenses, including, without limitation, reasonable
+attorneys' fees and costs incurred in connection with such action, including
+any appeal of such action. This section shall survive the termination of this
+License.
+
+13) Miscellaneous. This License represents the complete agreement concerning
+the subject matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent necessary to
+make it enforceable.
+
+14) Definition of "You" in This License. "You" throughout this License, whether
+in upper or lower case, means an individual or a legal entity exercising rights
+under, and complying with all of the terms of, this License. For legal
+entities, "You" includes any entity that controls, is controlled by, or is
+under common control with you. For purposes of this definition, "control" means
+(i) the power, direct or indirect, to cause the direction or management of such
+entity, whether by contract or otherwise, or (ii) ownership of fifty percent
+(50%) or more of the outstanding shares, or (iii) beneficial ownership of such
+entity.
+
+15) Right to Use. You may use the Original Work in all ways not otherwise
+restricted or conditioned by this License or by law, and Licensor promises not
+to interfere with or be responsible for such uses by You.
+
+This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved.
+Permission is hereby granted to copy and distribute this license without
+modification. This license may not be modified without the express written
+permission of its copyright owner.
diff --git a/dojox/analytics.js b/dojox/analytics.js
new file mode 100644
index 0000000..e07a131
--- /dev/null
+++ b/dojox/analytics.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.analytics"]){
+dojo._hasResource["dojox.analytics"]=true;
+dojo.provide("dojox.analytics");
+dojo.require("dojox.analytics._base");
+}
diff --git a/dojox/analytics/README b/dojox/analytics/README
new file mode 100644
index 0000000..6304903
--- /dev/null
+++ b/dojox/analytics/README
@@ -0,0 +1,139 @@
+-------------------------------------------------------------------------------
+dojox.analytics
+-------------------------------------------------------------------------------
+Version 1.0
+Release date: 12/17/2007
+-------------------------------------------------------------------------------
+Project state: 
+[base]: alpha
+[Urchin]: alpha
+-------------------------------------------------------------------------------
+Project authors
+	Dustin Machi  (dmachi)
+	Peter Higgins (dante)
+-------------------------------------------------------------------------------
+Project description
+	analytics and client monitoring system.  Including the base analytics
+system and any number of plugins enables logging of different system data
+back to the server.  Plugins included at this time:
+
+	dojo - reports dojo startup  collected information
+	window - reports available window information to the server
+	mouseOver - allows periodic sampling of mouseOver 
+	mouseClick - reports any mouse clicks to the server
+	idle - reports idle/activity 
+	consoleMessages - reports console.* messages to the server	
+
+	Additionally, a Google Ananlytics (Urchin tracker) helper is included
+	in this project, though is unrelated to the Core dojox.analytics 
+	project code. 
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo Core (package loader).
+-------------------------------------------------------------------------------
+Documentation
+
+Usage:
+
+The primary intended usage will be to create a custom build layer that includes 
+the particular plugins you need for your project.   However in practice you
+can use the system as such:
+
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+                djConfig="parseOnLoad: true, isDebug: false, usePlainJson: true, sendMethod: 'script', sendInterval: 5000"></script>
+
+        <script language="JavaScript" type="text/javascript">
+                // include the analytics system
+                dojo.require("dojox.analytics");
+
+                //tracks mouse clicks on the page
+                dojo.require("dojox.analytics.plugins.mouseClick");
+
+                // this plugin returns the informatin dojo collects when it launches
+                dojo.require("dojox.analytics.plugins.dojo");
+
+                // this plugin return the information the window has when it launches
+                // and it also ties to a few events such as window.option
+                dojo.require("dojox.analytics.plugins.window");
+
+                // this plugin tracks console. message, It logs console.error, warn, and
+                // info messages to the tracker.  It also defines console.rlog() which
+                // can be used to log only to the server.  Note that if isDebug() is disabled
+                // you will still see the console messages on the sever, but not in the actual
+                // browser console.
+                dojo.require("dojox.analytics.plugins.consoleMessages");
+
+                // tracks where a mouse is on a page an what it is over, periodically sampling
+                // and storing this data
+                dojo.require("dojox.analytics.plugins.mouseOver");
+
+                //tracks when the user has gone idle
+                dojo.require("dojox.analytics.plugins.idle");
+
+	</script> 
+
+When done using a build, none of the dojo.require() statement will be requires 
+would already be in the build. 
+
+Most of the plugins and the base itself have a number of configurable params
+that are passed in via the djConfig variable set.  This approach is taken so that
+the parameters can be easily provided in the case of a build or for a custom
+dojo.js build with analytics built in. Examples for different build profiles 
+are in the profiles directory.
+
+Available Configuration Parameters:
+
+	Base Configs
+	sendInterval - Normal send interval. Default 5000 
+	sendMethod - "script" || "xhrPost"
+	inTransitRetry - Delay before retrying an a send if it was in transit
+			or if there is still data to be sent after a post.
+			Default 1000
+	analyticsUrl - url to send logging data to. defaults to the test php 
+			file for now
+	maxRequestSize - Maximum size of GET style requests. Capped at 2000 for 
+			IE, and 4000 otherwise	
+
+	consoleMessages Config:
+
+	consoleLogFuncs - functions from the console object that you will log to 
+			the server. If the console object doesn't exist
+			or a particuarl method doesn't exist it will be
+			created as a remote logging only method. This provides
+			a quick and convient way to automatically define
+			a remote logging funciton that includes the functions
+			name in the log.  The 'rlog' in the default paramerters
+			is an example of this.  Defaults to ["error", "warn", "info", "rlog"]	
+
+	idle Config:
+	
+		idleTime - Number of ms to be idle before being reported to the server as idle
+
+	mouseOver config:
+		targetProps - the properties whose values will be reported for each target from
+				a mouse over sample.  defaults to ["id","className","localName","href", "spellcheck", "lang", "textContent", "value" ]
+
+		sampleDelay - the delay in ms between mouseover samples. Defaults to 2500
+
+	window config:
+		windowConnects - methods on the window objec that will be attached to 
+				have its data passed to the server when called.
+
+	
+Note that the basic usage of this system simply serializes json with toJson() when passed
+to the analytics addData() method.  If data is passed that has circular references
+it will die.  Take care not to do that or be surprised when it doens't work
+in those cases.
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/analytics
+
+Install into the following directory structure:
+/dojox/analytics/
+
+...which should be at the same level as your Dojo checkout.
diff --git a/dojox/analytics/Urchin.js b/dojox/analytics/Urchin.js
new file mode 100644
index 0000000..f45fb9e
--- /dev/null
+++ b/dojox/analytics/Urchin.js
@@ -0,0 +1,34 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.analytics.Urchin"]){
+dojo._hasResource["dojox.analytics.Urchin"]=true;
+dojo.provide("dojox.analytics.Urchin");
+dojo.declare("dojox.analytics.Urchin",null,{acct:dojo.config.urchin,loadInterval:42,decay:0.5,timeout:4200,constructor:function(_1){
+this.tracker=null;
+dojo.mixin(this,_1);
+this._loadGA();
+},_loadGA:function(){
+var _2=("https:"==document.location.protocol)?"https://ssl.":"http://www.";
+dojo.create("script",{src:_2+"google-analytics.com/ga.js"},dojo.doc.getElementsByTagName("head")[0]);
+setTimeout(dojo.hitch(this,"_checkGA"),this.loadInterval);
+},_checkGA:function(){
+if(this.loadInterval>this.timeout){
+return;
+}
+setTimeout(dojo.hitch(this,!window["_gat"]?"_checkGA":"_gotGA"),this.loadInterval);
+this.loadInterval*=(this.decay+1);
+},_gotGA:function(){
+this.tracker=_gat._getTracker(this.acct);
+this.tracker._initData();
+this.GAonLoad.apply(this,arguments);
+},GAonLoad:function(){
+this.trackPageView();
+},trackPageView:function(_3){
+this.tracker._trackPageview.apply(this,arguments);
+}});
+}
diff --git a/dojox/analytics/_base.js b/dojox/analytics/_base.js
new file mode 100644
index 0000000..4602d42
--- /dev/null
+++ b/dojox/analytics/_base.js
@@ -0,0 +1,82 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.analytics._base"]){
+dojo._hasResource["dojox.analytics._base"]=true;
+dojo.provide("dojox.analytics._base");
+dojox.analytics=function(){
+this._data=[];
+this._id=1;
+this.sendInterval=dojo.config["sendInterval"]||5000;
+this.inTransitRetry=dojo.config["inTransitRetry"]||200;
+this.dataUrl=dojo.config["analyticsUrl"]||dojo.moduleUrl("dojox.analytics.logger","dojoxAnalytics.php");
+this.sendMethod=dojo.config["sendMethod"]||"xhrPost";
+this.maxRequestSize=dojo.isIE?2000:dojo.config["maxRequestSize"]||4000;
+dojo.addOnLoad(this,"schedulePusher");
+dojo.addOnUnload(this,"pushData",true);
+};
+dojo.extend(dojox.analytics,{schedulePusher:function(_1){
+setTimeout(dojo.hitch(this,"checkData"),_1||this.sendInterval);
+},addData:function(_2,_3){
+if(arguments.length>2){
+var c=[];
+for(var i=1;i<arguments.length;i++){
+c.push(arguments[i]);
+}
+_3=c;
+}
+this._data.push({plugin:_2,data:_3});
+},checkData:function(){
+if(this._inTransit){
+this.schedulePusher(this.inTransitRetry);
+return;
+}
+if(this.pushData()){
+return;
+}
+this.schedulePusher();
+},pushData:function(){
+if(this._data.length){
+this._inTransit=this._data;
+this._data=[];
+var _6;
+switch(this.sendMethod){
+case "script":
+_6=dojo.io.script.get({url:this.getQueryPacket(),preventCache:1,callbackParamName:"callback"});
+break;
+case "xhrPost":
+default:
+_6=dojo.xhrPost({url:this.dataUrl,content:{id:this._id++,data:dojo.toJson(this._inTransit)}});
+break;
+}
+_6.addCallback(this,"onPushComplete");
+return _6;
+}
+return false;
+},getQueryPacket:function(){
+while(true){
+var _7={id:this._id++,data:dojo.toJson(this._inTransit)};
+var _8=this.dataUrl+"?"+dojo.objectToQuery(_7);
+if(_8.length>this.maxRequestSize){
+this._data.unshift(this._inTransit.pop());
+this._split=1;
+}else{
+return _8;
+}
+}
+},onPushComplete:function(_9){
+if(this._inTransit){
+delete this._inTransit;
+}
+if(this._data.length>0){
+this.schedulePusher(this.inTransitRetry);
+}else{
+this.schedulePusher();
+}
+}});
+dojox.analytics=new dojox.analytics();
+}
diff --git a/dojox/analytics/logger/JSON.php b/dojox/analytics/logger/JSON.php
new file mode 100644
index 0000000..e87e4d0
--- /dev/null
+++ b/dojox/analytics/logger/JSON.php
@@ -0,0 +1,724 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/** 
+ * Converts to and from JSON format.
+ * 
+ * JSON (JavaScript Object Notation) is a lightweight data-interchange
+ * format. It is easy for humans to read and write. It is easy for machines
+ * to parse and generate. It is based on a subset of the JavaScript
+ * Programming Language, Standard ECMA-262 3rd Edition - December 1999.
+ * This feature can also be found in  Python. JSON is a text format that is
+ * completely language independent but uses conventions that are familiar
+ * to programmers of the C-family of languages, including C, C++, C#, Java,
+ * JavaScript, Perl, TCL, and many others. These properties make JSON an
+ * ideal data-interchange language.
+ * 
+ * This package provides a simple encoder and decoder for JSON notation. It
+ * is intended for use with client-side Javascript applications that make
+ * use of HTTPRequest to perform server communication functions - data can
+ * be encoded into JSON notation for use in a client-side javascript, or
+ * decoded from incoming Javascript requests. JSON format is native to
+ * Javascript, and can be directly eval()'ed with no further parsing
+ * overhead
+ *
+ * All strings should be in ASCII or UTF-8 format!
+ *
+ * LICENSE: Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met: Redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following
+ * disclaimer. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * 
+ * @category   
+ * @package     Services_JSON
+ * @author      Michal Migurski <mike-json at teczno.com>
+ * @author      Matt Knapp <mdknapp[at]gmail[dot]com>
+ * @author      Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
+ * @copyright   2005 Michal Migurski
+ * @license     http://www.opensource.org/licenses/bsd-license.php
+ * @link        http://pear.php.net/pepr/pepr-proposal-show.php?id=198
+ */
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_SLICE',   1);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_STR',  2);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_ARR',  4);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_OBJ',  8);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_CMT', 16);
+
+/**
+ * Behavior switch for Services_JSON::decode()
+ */
+define('SERVICES_JSON_LOOSE_TYPE', 10);
+
+/**
+ * Behavior switch for Services_JSON::decode()
+ */
+define('SERVICES_JSON_STRICT_TYPE', 11);
+
+/** 
+ * Converts to and from JSON format.
+ *
+ * Brief example of use:
+ *
+ * <code>
+ * // create a new instance of Services_JSON
+ * $json = new Services_JSON();
+ * 
+ * // convert a complexe value to JSON notation, and send it to the browser
+ * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
+ * $output = $json->encode($value);
+ *
+ * print($output);
+ * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
+ * 
+ * // accept incoming POST data, assumed to be in JSON notation
+ * $input = file_get_contents('php://input', 1000000);
+ * $value = $json->decode($input);
+ * </code>
+ */
+class Services_JSON
+{
+   /**
+    * constructs a new JSON instance
+    *
+    * @param    int     $use    object behavior: when encoding or decoding,
+    *                           be loose or strict about object/array usage
+    *
+    *                           possible values:
+    *                           - SERVICES_JSON_STRICT_TYPE: strict typing, default.
+    *                                                        "{...}" syntax creates objects in decode().
+    *                           - SERVICES_JSON_LOOSE_TYPE:  loose typing.
+    *                                                        "{...}" syntax creates associative arrays in decode().
+    */
+    function Services_JSON($use = SERVICES_JSON_STRICT_TYPE)
+    {
+        $this->use = $use;
+    }
+
+   /**
+    * convert a string from one UTF-16 char to one UTF-8 char
+    *
+    * Normally should be handled by mb_convert_encoding, but
+    * provides a slower PHP-only method for installations
+    * that lack the multibye string extension.
+    *
+    * @param    string  $utf16  UTF-16 character
+    * @return   string  UTF-8 character
+    * @access   private
+    */
+    function utf162utf8($utf16)
+    {
+        // oh please oh please oh please oh please oh please
+        if(function_exists('mb_convert_encoding'))
+            return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
+        
+        $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
+
+        switch(true) {
+            case ((0x7F & $bytes) == $bytes):
+                // this case should never be reached, because we are in ASCII range
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0x7F & $bytes);
+
+            case (0x07FF & $bytes) == $bytes:
+                // return a 2-byte UTF-8 character
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0xC0 | (($bytes >> 6) & 0x1F))
+                     . chr(0x80 | ($bytes & 0x3F));
+
+            case (0xFFFF & $bytes) == $bytes:
+                // return a 3-byte UTF-8 character
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0xE0 | (($bytes >> 12) & 0x0F))
+                     . chr(0x80 | (($bytes >> 6) & 0x3F))
+                     . chr(0x80 | ($bytes & 0x3F));
+        }
+
+        // ignoring UTF-32 for now, sorry
+        return '';
+    }        
+
+   /**
+    * convert a string from one UTF-8 char to one UTF-16 char
+    *
+    * Normally should be handled by mb_convert_encoding, but
+    * provides a slower PHP-only method for installations
+    * that lack the multibye string extension.
+    *
+    * @param    string  $utf8   UTF-8 character
+    * @return   string  UTF-16 character
+    * @access   private
+    */
+    function utf82utf16($utf8)
+    {
+        // oh please oh please oh please oh please oh please
+        if(function_exists('mb_convert_encoding'))
+            return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
+        
+        switch(strlen($utf8)) {
+            case 1:
+                // this case should never be reached, because we are in ASCII range
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return $utf8;
+
+            case 2:
+                // return a UTF-16 character from a 2-byte UTF-8 char
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0x07 & (ord($utf8{0}) >> 2))
+                     . chr((0xC0 & (ord($utf8{0}) << 6))
+                         | (0x3F & ord($utf8{1})));
+                
+            case 3:
+                // return a UTF-16 character from a 3-byte UTF-8 char
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr((0xF0 & (ord($utf8{0}) << 4))
+                         | (0x0F & (ord($utf8{1}) >> 2)))
+                     . chr((0xC0 & (ord($utf8{1}) << 6))
+                         | (0x7F & ord($utf8{2})));
+        }
+
+        // ignoring UTF-32 for now, sorry
+        return '';
+    }        
+
+   /**
+    * encodes an arbitrary variable into JSON format
+    *
+    * @param    mixed   $var    any number, boolean, string, array, or object to be encoded.
+    *                           see argument 1 to Services_JSON() above for array-parsing behavior.
+    *                           if var is a strng, note that encode() always expects it
+    *                           to be in ASCII or UTF-8 format!
+    *
+    * @return   string  JSON string representation of input var
+    * @access   public
+    */
+    function encode($var)
+    {
+        switch (gettype($var)) {
+            case 'boolean':
+                return $var ? 'true' : 'false';
+            
+            case 'NULL':
+                return 'null';
+            
+            case 'integer':
+                return (int) $var;
+                
+            case 'double':
+            case 'float':
+                return (float) $var;
+                
+            case 'string':
+                // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
+                $ascii = '';
+                $strlen_var = strlen($var);
+
+               /*
+                * Iterate over every character in the string,
+                * escaping with a slash or encoding to UTF-8 where necessary
+                */
+                for ($c = 0; $c < $strlen_var; ++$c) {
+                    
+                    $ord_var_c = ord($var{$c});
+                    
+                    switch (true) {
+                        case $ord_var_c == 0x08:
+                            $ascii .= '\b';
+                            break;
+                        case $ord_var_c == 0x09:
+                            $ascii .= '\t';
+                            break;
+                        case $ord_var_c == 0x0A:
+                            $ascii .= '\n';
+                            break;
+                        case $ord_var_c == 0x0C:
+                            $ascii .= '\f';
+                            break;
+                        case $ord_var_c == 0x0D:
+                            $ascii .= '\r';
+                            break;
+
+                        case $ord_var_c == 0x22:
+                        case $ord_var_c == 0x2F:
+                        case $ord_var_c == 0x5C:
+                            // double quote, slash, slosh
+                            $ascii .= '\\'.$var{$c};
+                            break;
+                            
+                        case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
+                            // characters U-00000000 - U-0000007F (same as ASCII)
+                            $ascii .= $var{$c};
+                            break;
+                        
+                        case (($ord_var_c & 0xE0) == 0xC0):
+                            // characters U-00000080 - U-000007FF, mask 110XXXXX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
+                            $c += 1;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+    
+                        case (($ord_var_c & 0xF0) == 0xE0):
+                            // characters U-00000800 - U-0000FFFF, mask 1110XXXX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}));
+                            $c += 2;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+    
+                        case (($ord_var_c & 0xF8) == 0xF0):
+                            // characters U-00010000 - U-001FFFFF, mask 11110XXX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}),
+                                         ord($var{$c + 3}));
+                            $c += 3;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+    
+                        case (($ord_var_c & 0xFC) == 0xF8):
+                            // characters U-00200000 - U-03FFFFFF, mask 111110XX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}),
+                                         ord($var{$c + 3}),
+                                         ord($var{$c + 4}));
+                            $c += 4;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+    
+                        case (($ord_var_c & 0xFE) == 0xFC):
+                            // characters U-04000000 - U-7FFFFFFF, mask 1111110X
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}),
+                                         ord($var{$c + 3}),
+                                         ord($var{$c + 4}),
+                                         ord($var{$c + 5}));
+                            $c += 5;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+                    }
+                }
+                
+                return '"'.$ascii.'"';
+                
+            case 'array':
+               /*
+                * As per JSON spec if any array key is not an integer
+                * we must treat the the whole array as an object. We
+                * also try to catch a sparsely populated associative
+                * array with numeric keys here because some JS engines
+                * will create an array with empty indexes up to
+                * max_index which can cause memory issues and because
+                * the keys, which may be relevant, will be remapped
+                * otherwise.
+                * 
+                * As per the ECMA and JSON specification an object may
+                * have any string as a property. Unfortunately due to
+                * a hole in the ECMA specification if the key is a
+                * ECMA reserved word or starts with a digit the
+                * parameter is only accessible using ECMAScript's
+                * bracket notation.
+                */
+                
+                // treat as a JSON object  
+                if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
+                    return '{' .
+                           join(',', array_map(array($this, 'name_value'),
+                                               array_keys($var),
+                                               array_values($var)))
+                           . '}';
+                }
+
+                // treat it like a regular array
+                return '[' . join(',', array_map(array($this, 'encode'), $var)) . ']';
+                
+            case 'object':
+                $vars = get_object_vars($var);
+                return '{' .
+                       join(',', array_map(array($this, 'name_value'),
+                                           array_keys($vars),
+                                           array_values($vars)))
+                       . '}';
+
+            default:
+                return '';
+        }
+    }
+    
+   /**
+    * array-walking function for use in generating JSON-formatted name-value pairs
+    *
+    * @param    string  $name   name of key to use
+    * @param    mixed   $value  reference to an array element to be encoded
+    *
+    * @return   string  JSON-formatted name-value pair, like '"name":value'
+    * @access   private
+    */
+    function name_value($name, $value)
+    {
+        return $this->encode(strval($name)) . ':' . $this->encode($value);
+    }        
+
+   /**
+    * reduce a string by removing leading and trailing comments and whitespace
+    *
+    * @param    $str    string      string value to strip of comments and whitespace
+    *
+    * @return   string  string value stripped of comments and whitespace
+    * @access   private
+    */
+    function reduce_string($str)
+    {
+        $str = preg_replace(array(
+        
+                // eliminate single line comments in '// ...' form
+                '#^\s*//(.+)$#m',
+    
+                // eliminate multi-line comments in '/* ... */' form, at start of string
+                '#^\s*/\*(.+)\*/#Us',
+    
+                // eliminate multi-line comments in '/* ... */' form, at end of string
+                '#/\*(.+)\*/\s*$#Us'
+    
+            ), '', $str);
+        
+        // eliminate extraneous space
+        return trim($str);
+    }
+
+   /**
+    * decodes a JSON string into appropriate variable
+    *
+    * @param    string  $str    JSON-formatted string
+    *
+    * @return   mixed   number, boolean, string, array, or object
+    *                   corresponding to given JSON input string.
+    *                   See argument 1 to Services_JSON() above for object-output behavior.
+    *                   Note that decode() always returns strings
+    *                   in ASCII or UTF-8 format!
+    * @access   public
+    */
+    function decode($str)
+    {
+        $str = $this->reduce_string($str);
+    
+        switch (strtolower($str)) {
+            case 'true':
+                return true;
+
+            case 'false':
+                return false;
+            
+            case 'null':
+                return null;
+            
+            default:
+                if (is_numeric($str)) {
+                    // Lookie-loo, it's a number
+
+                    // This would work on its own, but I'm trying to be
+                    // good about returning integers where appropriate:
+                    // return (float)$str;
+
+                    // Return float or int, as appropriate
+                    return ((float)$str == (integer)$str)
+                        ? (integer)$str
+                        : (float)$str;
+                    
+                } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
+                    // STRINGS RETURNED IN UTF-8 FORMAT
+                    $delim = substr($str, 0, 1);
+                    $chrs = substr($str, 1, -1);
+                    $utf8 = '';
+                    $strlen_chrs = strlen($chrs);
+                    
+                    for ($c = 0; $c < $strlen_chrs; ++$c) {
+                    
+                        $substr_chrs_c_2 = substr($chrs, $c, 2);
+                        $ord_chrs_c = ord($chrs{$c});
+                        
+                        switch (true) {
+                            case $substr_chrs_c_2 == '\b':
+                                $utf8 .= chr(0x08);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\t':
+                                $utf8 .= chr(0x09);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\n':
+                                $utf8 .= chr(0x0A);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\f':
+                                $utf8 .= chr(0x0C);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\r':
+                                $utf8 .= chr(0x0D);
+                                ++$c;
+                                break;
+
+                            case $substr_chrs_c_2 == '\\"':
+                            case $substr_chrs_c_2 == '\\\'':
+                            case $substr_chrs_c_2 == '\\\\':
+                            case $substr_chrs_c_2 == '\\/':
+                                if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
+                                   ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
+                                    $utf8 .= $chrs{++$c};
+                                }
+                                break;
+                                
+                            case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
+                                // single, escaped unicode character
+                                $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
+                                       . chr(hexdec(substr($chrs, ($c + 4), 2)));
+                                $utf8 .= $this->utf162utf8($utf16);
+                                $c += 5;
+                                break;
+        
+                            case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
+                                $utf8 .= $chrs{$c};
+                                break;
+        
+                            case ($ord_chrs_c & 0xE0) == 0xC0:
+                                // characters U-00000080 - U-000007FF, mask 110XXXXX
+                                //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 2);
+                                ++$c;
+                                break;
+    
+                            case ($ord_chrs_c & 0xF0) == 0xE0:
+                                // characters U-00000800 - U-0000FFFF, mask 1110XXXX
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 3);
+                                $c += 2;
+                                break;
+    
+                            case ($ord_chrs_c & 0xF8) == 0xF0:
+                                // characters U-00010000 - U-001FFFFF, mask 11110XXX
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 4);
+                                $c += 3;
+                                break;
+    
+                            case ($ord_chrs_c & 0xFC) == 0xF8:
+                                // characters U-00200000 - U-03FFFFFF, mask 111110XX
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 5);
+                                $c += 4;
+                                break;
+    
+                            case ($ord_chrs_c & 0xFE) == 0xFC:
+                                // characters U-04000000 - U-7FFFFFFF, mask 1111110X
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 6);
+                                $c += 5;
+                                break;
+
+                        }
+
+                    }
+                    
+                    return $utf8;
+                
+                } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
+                    // array, or object notation
+
+                    if ($str{0} == '[') {
+                        $stk = array(SERVICES_JSON_IN_ARR);
+                        $arr = array();
+                    } else {
+                        if ($this->use == SERVICES_JSON_LOOSE_TYPE) {
+                            $stk = array(SERVICES_JSON_IN_OBJ);
+                            $obj = array();
+                        } else {
+                            $stk = array(SERVICES_JSON_IN_OBJ);
+                            $obj = new stdClass();
+                        }
+                    }
+                    
+                    array_push($stk, array('what'  => SERVICES_JSON_SLICE,
+                                           'where' => 0,
+                                           'delim' => false));
+
+                    $chrs = substr($str, 1, -1);
+                    $chrs = $this->reduce_string($chrs);
+                    
+                    if ($chrs == '') {
+                        if (reset($stk) == SERVICES_JSON_IN_ARR) {
+                            return $arr;
+
+                        } else {
+                            return $obj;
+
+                        }
+                    }
+
+                    //print("\nparsing {$chrs}\n");
+                    
+                    $strlen_chrs = strlen($chrs);
+                    
+                    for ($c = 0; $c <= $strlen_chrs; ++$c) {
+                    
+                        $top = end($stk);
+                        $substr_chrs_c_2 = substr($chrs, $c, 2);
+                    
+                        if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
+                            // found a comma that is not inside a string, array, etc.,
+                            // OR we've reached the end of the character list
+                            $slice = substr($chrs, $top['where'], ($c - $top['where']));
+                            array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
+                            //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                            if (reset($stk) == SERVICES_JSON_IN_ARR) {
+                                // we are in an array, so just push an element onto the stack
+                                array_push($arr, $this->decode($slice));
+
+                            } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
+                                // we are in an object, so figure
+                                // out the property name and set an
+                                // element in an associative array,
+                                // for now
+                                if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+                                    // "name":value pair
+                                    $key = $this->decode($parts[1]);
+                                    $val = $this->decode($parts[2]);
+
+                                    if ($this->use == SERVICES_JSON_LOOSE_TYPE) {
+                                        $obj[$key] = $val;
+                                    } else {
+                                        $obj->$key = $val;
+                                    }
+                                } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+                                    // name:value pair, where name is unquoted
+                                    $key = $parts[1];
+                                    $val = $this->decode($parts[2]);
+
+                                    if ($this->use == SERVICES_JSON_LOOSE_TYPE) {
+                                        $obj[$key] = $val;
+                                    } else {
+                                        $obj->$key = $val;
+                                    }
+                                }
+
+                            }
+
+                        } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
+                            // found a quote, and we are not inside a string
+                            array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
+                            //print("Found start of string at {$c}\n");
+
+                        } elseif (($chrs{$c} == $top['delim']) &&
+                                 ($top['what'] == SERVICES_JSON_IN_STR) &&
+                                 (($chrs{$c - 1} != '\\') ||
+                                 ($chrs{$c - 1} == '\\' && $chrs{$c - 2} == '\\'))) {
+                            // found a quote, we're in a string, and it's not escaped
+                            array_pop($stk);
+                            //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
+
+                        } elseif (($chrs{$c} == '[') &&
+                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+                            // found a left-bracket, and we are in an array, object, or slice
+                            array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
+                            //print("Found start of array at {$c}\n");
+
+                        } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
+                            // found a right-bracket, and we're in an array
+                            array_pop($stk);
+                            //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                        } elseif (($chrs{$c} == '{') &&
+                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+                            // found a left-brace, and we are in an array, object, or slice
+                            array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
+                            //print("Found start of object at {$c}\n");
+
+                        } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
+                            // found a right-brace, and we're in an object
+                            array_pop($stk);
+                            //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                        } elseif (($substr_chrs_c_2 == '/*') &&
+                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+                            // found a comment start, and we are in an array, object, or slice
+                            array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
+                            $c++;
+                            //print("Found start of comment at {$c}\n");
+
+                        } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
+                            // found a comment end, and we're in one now
+                            array_pop($stk);
+                            $c++;
+                            
+                            for ($i = $top['where']; $i <= $c; ++$i)
+                                $chrs = substr_replace($chrs, ' ', $i, 1);
+                            
+                            //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                        }
+                    
+                    }
+                    
+                    if (reset($stk) == SERVICES_JSON_IN_ARR) {
+                        return $arr;
+
+                    } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
+                        return $obj;
+
+                    }
+                
+                }
+        }
+    }
+    
+}
+    
+?>
\ No newline at end of file
diff --git a/dojox/analytics/logger/dojoxAnalytics.php b/dojox/analytics/logger/dojoxAnalytics.php
new file mode 100644
index 0000000..0f7f849
--- /dev/null
+++ b/dojox/analytics/logger/dojoxAnalytics.php
@@ -0,0 +1,31 @@
+<?php
+	require_once("./JSON.php");
+
+	$filename = "./logs/analytics.log";
+	$json = new Services_JSON;
+
+	$id = $_REQUEST["id"];
+	$items = $json->decode($_REQUEST["data"]);
+
+	if (!$handle = fopen($filename, 'a+')) {
+		print '{error: "server error"}';
+		exit;
+	}
+
+	foreach($items as $i=>$item){
+		$item->_analyticsId = $id;
+		$item->_analyticsTimeStamp = time();
+		$log = $json->encode($item) . "\n";
+		fwrite($handle, $log);
+	}
+	
+	fclose($handle);
+
+	$response = "{'eventsRecieved': '" . sizeof($items) . "', 'id': '" . $id . "'}";
+	if ($_REQUEST["callback"]){
+		print $_REQUEST["callback"] . "(" . $response . ");";
+	}else{
+		print $response;
+	}
+	
+?>
diff --git a/dojox/analytics/plugins/consoleMessages.js b/dojox/analytics/plugins/consoleMessages.js
new file mode 100644
index 0000000..17b4866
--- /dev/null
+++ b/dojox/analytics/plugins/consoleMessages.js
@@ -0,0 +1,25 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.analytics.plugins.consoleMessages"]){
+dojo._hasResource["dojox.analytics.plugins.consoleMessages"]=true;
+dojo.provide("dojox.analytics.plugins.consoleMessages");
+dojox.analytics.plugins.consoleMessages=new (function(){
+this.addData=dojo.hitch(dojox.analytics,"addData","consoleMessages");
+var _1=dojo.config["consoleLogFuncs"]||["error","warn","info","rlog"];
+if(!console){
+console={};
+}
+for(var i=0;i<_1.length;i++){
+if(console[_1[i]]){
+dojo.connect(console,_1[i],dojo.hitch(this,"addData",_1[i]));
+}else{
+console[_1[i]]=dojo.hitch(this,"addData",_1[i]);
+}
+}
+})();
+}
diff --git a/dojox/analytics/plugins/dojo.js b/dojox/analytics/plugins/dojo.js
new file mode 100644
index 0000000..5ecd2ba
--- /dev/null
+++ b/dojox/analytics/plugins/dojo.js
@@ -0,0 +1,22 @@
+if(!dojo._hasResource["dojox.analytics.plugins.dojo"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.analytics.plugins.dojo"] = true;
+dojo.provide("dojox.analytics.plugins.dojo");
+
+dojox.analytics.plugins.dojo = new (function(){
+	// summary:
+	//	plugin to have analyitcs return the base info dojo collects
+	this.addData = dojo.hitch(dojox.analytics, "addData", "dojo");
+	dojo.addOnLoad(dojo.hitch(this, function(){
+		var data = {};
+		for(var i in dojo){
+			if ((i=="version") || ((!dojo.isObject(dojo[i]))&&(i[0]!="_"))){
+				data[i]=dojo[i];
+			}
+		}
+
+		if (dojo.config){data.djConfig=dojo.config}
+		this.addData(data);
+	}));
+})();
+
+}
diff --git a/dojox/analytics/plugins/idle.js b/dojox/analytics/plugins/idle.js
new file mode 100644
index 0000000..86b82be
--- /dev/null
+++ b/dojox/analytics/plugins/idle.js
@@ -0,0 +1,35 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.analytics.plugins.idle"]){
+dojo._hasResource["dojox.analytics.plugins.idle"]=true;
+dojo.provide("dojox.analytics.plugins.idle");
+dojox.analytics.plugins.idle=new (function(){
+this.addData=dojo.hitch(dojox.analytics,"addData","idle");
+this.idleTime=dojo.config["idleTime"]||60000;
+this.idle=true;
+this.setIdle=function(){
+this.addData("isIdle");
+this.idle=true;
+};
+dojo.addOnLoad(dojo.hitch(this,function(){
+var _1=["onmousemove","onkeydown","onclick","onscroll"];
+for(var i=0;i<_1.length;i++){
+dojo.connect(dojo.doc,_1[i],this,function(e){
+if(this.idle){
+this.idle=false;
+this.addData("isActive");
+this.idleTimer=setTimeout(dojo.hitch(this,"setIdle"),this.idleTime);
+}else{
+clearTimeout(this.idleTimer);
+this.idleTimer=setTimeout(dojo.hitch(this,"setIdle"),this.idleTime);
+}
+});
+}
+}));
+})();
+}
diff --git a/dojox/analytics/plugins/mouseClick.js b/dojox/analytics/plugins/mouseClick.js
new file mode 100644
index 0000000..0c58c3c
--- /dev/null
+++ b/dojox/analytics/plugins/mouseClick.js
@@ -0,0 +1,51 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.analytics.plugins.mouseClick"]){
+dojo._hasResource["dojox.analytics.plugins.mouseClick"]=true;
+dojo.provide("dojox.analytics.plugins.mouseClick");
+dojox.analytics.plugins.mouseClick=new (function(){
+this.addData=dojo.hitch(dojox.analytics,"addData","mouseClick");
+this.onClick=function(e){
+this.addData(this.trimEvent(e));
+};
+dojo.connect(dojo.doc,"onclick",this,"onClick");
+this.trimEvent=function(e){
+var t={};
+for(var i in e){
+switch(i){
+case "target":
+case "originalTarget":
+case "explicitOriginalTarget":
+var _5=["id","className","nodeName","localName","href","spellcheck","lang"];
+t[i]={};
+for(var j=0;j<_5.length;j++){
+if(e[i][_5[j]]){
+if(_5[j]=="text"||_5[j]=="textContent"){
+if((e[i]["localName"]!="HTML")&&(e[i]["localName"]!="BODY")){
+t[i][_5[j]]=e[i][_5[j]].substr(0,50);
+}
+}else{
+t[i][_5[j]]=e[i][_5[j]];
+}
+}
+}
+break;
+case "clientX":
+case "clientY":
+case "pageX":
+case "pageY":
+case "screenX":
+case "screenY":
+t[i]=e[i];
+break;
+}
+}
+return t;
+};
+})();
+}
diff --git a/dojox/analytics/plugins/mouseOver.js b/dojox/analytics/plugins/mouseOver.js
new file mode 100644
index 0000000..4705880
--- /dev/null
+++ b/dojox/analytics/plugins/mouseOver.js
@@ -0,0 +1,76 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.analytics.plugins.mouseOver"]){
+dojo._hasResource["dojox.analytics.plugins.mouseOver"]=true;
+dojo.provide("dojox.analytics.plugins.mouseOver");
+dojox.analytics.plugins.mouseOver=new (function(){
+this.watchMouse=dojo.config["watchMouseOver"]||true;
+this.mouseSampleDelay=dojo.config["sampleDelay"]||2500;
+this.addData=dojo.hitch(dojox.analytics,"addData","mouseOver");
+this.targetProps=dojo.config["targetProps"]||["id","className","localName","href","spellcheck","lang","textContent","value"];
+this.toggleWatchMouse=function(){
+if(this._watchingMouse){
+dojo.disconnect(this._watchingMouse);
+delete this._watchingMouse;
+return;
+}
+dojo.connect(dojo.doc,"onmousemove",this,"sampleMouse");
+};
+if(this.watchMouse){
+dojo.connect(dojo.doc,"onmouseover",this,"toggleWatchMouse");
+dojo.connect(dojo.doc,"onmouseout",this,"toggleWatchMouse");
+}
+this.sampleMouse=function(e){
+if(!this._rateLimited){
+this.addData("sample",this.trimMouseEvent(e));
+this._rateLimited=true;
+setTimeout(dojo.hitch(this,function(){
+if(this._rateLimited){
+this.trimMouseEvent(this._lastMouseEvent);
+delete this._lastMouseEvent;
+delete this._rateLimited;
+}
+}),this.mouseSampleDelay);
+}
+this._lastMouseEvent=e;
+return e;
+};
+this.trimMouseEvent=function(e){
+var t={};
+for(var i in e){
+switch(i){
+case "target":
+var _5=this.targetProps;
+t[i]={};
+for(var j=0;j<_5.length;j++){
+if(dojo.isObject(e[i])&&_5[j] in e[i]){
+if(_5[j]=="text"||_5[j]=="textContent"){
+if(e[i]["localName"]&&(e[i]["localName"]!="HTML")&&(e[i]["localName"]!="BODY")){
+t[i][_5[j]]=e[i][_5[j]].substr(0,50);
+}
+}else{
+t[i][_5[j]]=e[i][_5[j]];
+}
+}
+}
+break;
+case "x":
+case "y":
+if(e[i]){
+var _7=e[i];
+t[i]=_7+"";
+}
+break;
+default:
+break;
+}
+}
+return t;
+};
+})();
+}
diff --git a/dojox/analytics/plugins/window.js b/dojox/analytics/plugins/window.js
new file mode 100644
index 0000000..47ac2f3
--- /dev/null
+++ b/dojox/analytics/plugins/window.js
@@ -0,0 +1,36 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.analytics.plugins.window"]){
+dojo._hasResource["dojox.analytics.plugins.window"]=true;
+dojo.provide("dojox.analytics.plugins.window");
+dojox.analytics.plugins.window=new (function(){
+this.addData=dojo.hitch(dojox.analytics,"addData","window");
+this.windowConnects=dojo.config["windowConnects"]||["open","onerror"];
+for(var i=0;i<this.windowConnects.length;i++){
+dojo.connect(window,this.windowConnects[i],dojo.hitch(this,"addData",this.windowConnects[i]));
+}
+dojo.addOnLoad(dojo.hitch(this,function(){
+var _2={};
+for(var i in window){
+if(dojo.isObject(window[i])){
+switch(i){
+case "location":
+case "console":
+_2[i]=window[i];
+break;
+default:
+break;
+}
+}else{
+_2[i]=window[i];
+}
+}
+this.addData(_2);
+}));
+})();
+}
diff --git a/dojox/analytics/profiles/analytics.profile.js b/dojox/analytics/profiles/analytics.profile.js
new file mode 100644
index 0000000..95e99be
--- /dev/null
+++ b/dojox/analytics/profiles/analytics.profile.js
@@ -0,0 +1,8 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+dependencies={layers:[{name:"../dojox/analytics.js",dependencies:["dojox.analytics","dojox.analytics.plugins.dojo","dojox.analytics.plugins.window","dojox.analytics.plugins.consoleMessages","dojox.analytics.plugins.mouseOver","dojox.analytics.plugins.mouseClick","dojox.analytics.plugins.idle"]}],prefixes:[["dojox","../dojox"],["dijit","../dijit"]]};
diff --git a/dojox/analytics/profiles/analyticsInBase.profile.js b/dojox/analytics/profiles/analyticsInBase.profile.js
new file mode 100644
index 0000000..83ead70
--- /dev/null
+++ b/dojox/analytics/profiles/analyticsInBase.profile.js
@@ -0,0 +1,8 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+dependencies={layers:[{name:"dojo.js",dependencies:["dojox.analytics","dojox.analytics.plugins.dojo","dojox.analytics.plugins.window","dojox.analytics.plugins.consoleMessages","dojox.analytics.plugins.mouseOver","dojox.analytics.plugins.mouseClick","dojox.analytics.plugins.idle"]}],prefixes:[["dojox","../dojox"],["dijit","../dijit"]]};
diff --git a/dojox/atom/README b/dojox/atom/README
new file mode 100644
index 0000000..2e4936a
--- /dev/null
+++ b/dojox/atom/README
@@ -0,0 +1,53 @@
+-------------------------------------------------------------------------------
+DojoX Data
+-------------------------------------------------------------------------------
+Version 1.0
+Release date: 11/18/2008
+-------------------------------------------------------------------------------
+Project state: experimental
+-------------------------------------------------------------------------------
+Project authors
+	Jared Jurkiewicz (jared.jurkiewicz at gmail.com) 
+	Benjamin Schell (Corporate CLA)
+
+-------------------------------------------------------------------------------
+Project description
+
+The DojoX Atom project is an implementation of the ATOM document format in a 
+JavaScript model and a full Atom Publishing Protocol (APP) io library for working
+with ATOM feeds
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+DojoX Atom has dependencies on core dojo (dojo.data) and the D.O.H. unit test 
+framework.
+-------------------------------------------------------------------------------
+Documentation:
+
+See the Dojo API tool (http://dojotoolkit.org/api)
+as well as dojocampus (http://docs.dojocampus.org/dojox/atom)
+-------------------------------------------------------------------------------
+Contributions:
+
+Constributions of documentation, examples, and fixes are always welcome.
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/src/dojo/dojox/trunk/atom/*
+
+Install into the following directory structure:
+/dojox/atom/
+
+...which should be at the same level as your Dojo checkout.
+
+/dojox/atom/*
+
+Require in the sections you wish to use (the model, IO library, etc)
+-------------------------------------------------------------------------------
+Additional Notes: 
+	This library is still undergoing some work and as such the API may change
+	hence the marking of 'experimental'.
+
diff --git a/dojox/atom/io/Connection.js b/dojox/atom/io/Connection.js
new file mode 100644
index 0000000..7211358
--- /dev/null
+++ b/dojox/atom/io/Connection.js
@@ -0,0 +1,267 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.atom.io.Connection"]){
+dojo._hasResource["dojox.atom.io.Connection"]=true;
+dojo.provide("dojox.atom.io.Connection");
+dojo.require("dojox.atom.io.model");
+dojo.declare("dojox.atom.io.Connection",null,{constructor:function(_1,_2){
+this.sync=_1;
+this.preventCache=_2;
+},preventCache:false,alertsEnabled:false,getFeed:function(_3,_4,_5,_6){
+this._getXmlDoc(_3,"feed",new dojox.atom.io.model.Feed(),dojox.atom.io.model._Constants.ATOM_NS,_4,_5,_6);
+},getService:function(_7,_8,_9,_a){
+this._getXmlDoc(_7,"service",new dojox.atom.io.model.Service(_7),dojox.atom.io.model._Constants.APP_NS,_8,_9,_a);
+},getEntry:function(_b,_c,_d,_e){
+this._getXmlDoc(_b,"entry",new dojox.atom.io.model.Entry(),dojox.atom.io.model._Constants.ATOM_NS,_c,_d,_e);
+},_getXmlDoc:function(_f,_10,_11,_12,_13,_14,_15){
+if(!_15){
+_15=dojo.global;
+}
+var ae=this.alertsEnabled;
+var _17={url:_f,handleAs:"xml",sync:this.sync,preventCache:this.preventCache,load:function(_18,_19){
+var _1a=null;
+var _1b=_18;
+var _1c;
+if(_1b){
+if(typeof (_1b.getElementsByTagNameNS)!="undefined"){
+_1c=_1b.getElementsByTagNameNS(_12,_10);
+if(_1c&&_1c.length>0){
+_1a=_1c.item(0);
+}else{
+if(_1b.lastChild){
+_1a=_1b.lastChild;
+}
+}
+}else{
+if(typeof (_1b.getElementsByTagName)!="undefined"){
+_1c=_1b.getElementsByTagName(_10);
+if(_1c&&_1c.length>0){
+for(var i=0;i<_1c.length;i++){
+if(_1c[i].namespaceURI==_12){
+_1a=_1c[i];
+break;
+}
+}
+}else{
+if(_1b.lastChild){
+_1a=_1b.lastChild;
+}
+}
+}else{
+if(_1b.lastChild){
+_1a=_1b.lastChild;
+}else{
+_13.call(_15,null,null,_19);
+return;
+}
+}
+}
+_11.buildFromDom(_1a);
+if(_13){
+_13.call(_15,_11,_1b,_19);
+}else{
+if(ae){
+var _1e=dojo.i18n.getLocalization("dojox.atom.io","messages");
+throw new Error(_1e.noCallback);
+}
+}
+}else{
+_13.call(_15,null,null,_19);
+}
+}};
+if(this.user&&this.user!==null){
+_17.user=this.user;
+}
+if(this.password&&this.password!==null){
+_17.password=this.password;
+}
+if(_14){
+_17.error=function(_1f,_20){
+_14.call(_15,_1f,_20);
+};
+}else{
+_17.error=function(){
+var _21=dojo.i18n.getLocalization("dojox.atom.io","messages");
+throw new Error(_21.failedXhr);
+};
+}
+dojo.xhrGet(_17);
+},updateEntry:function(_22,_23,_24,_25,_26,_27){
+if(!_27){
+_27=dojo.global;
+}
+_22.updated=new Date();
+var url=_22.getEditHref();
+if(!url){
+var _29=dojo.i18n.getLocalization("dojox.atom.io","messages");
+throw new Error(_29.missingEditUrl);
+}
+var _2a=this;
+var ae=this.alertsEnabled;
+var _2c={url:url,handleAs:"text",contentType:"text/xml",sync:this.sync,preventCache:this.preventCache,load:function(_2d,_2e){
+var _2f=null;
+if(_25){
+_2f=_2e.xhr.getResponseHeader("Location");
+if(!_2f){
+_2f=url;
+}
+var _30=function(_31,dom,_33){
+if(_23){
+_23.call(_27,_31,_2f,_33);
+}else{
+if(ae){
+var _34=dojo.i18n.getLocalization("dojox.atom.io","messages");
+throw new Error(_34.noCallback);
+}
+}
+};
+_2a.getEntry(_2f,_30);
+}else{
+if(_23){
+_23.call(_27,_22,_2e.xhr.getResponseHeader("Location"),_2e);
+}else{
+if(ae){
+var _35=dojo.i18n.getLocalization("dojox.atom.io","messages");
+throw new Error(_35.noCallback);
+}
+}
+}
+return _2d;
+}};
+if(this.user&&this.user!==null){
+_2c.user=this.user;
+}
+if(this.password&&this.password!==null){
+_2c.password=this.password;
+}
+if(_24){
+_2c.error=function(_36,_37){
+_24.call(_27,_36,_37);
+};
+}else{
+_2c.error=function(){
+var _38=dojo.i18n.getLocalization("dojox.atom.io","messages");
+throw new Error(_38.failedXhr);
+};
+}
+if(_26){
+_2c.postData=_22.toString(true);
+_2c.headers={"X-Method-Override":"PUT"};
+dojo.rawXhrPost(_2c);
+}else{
+_2c.putData=_22.toString(true);
+var xhr=dojo.rawXhrPut(_2c);
+}
+},addEntry:function(_3a,url,_3c,_3d,_3e,_3f){
+if(!_3f){
+_3f=dojo.global;
+}
+_3a.published=new Date();
+_3a.updated=new Date();
+var _40=_3a.feedUrl;
+var ae=this.alertsEnabled;
+if(!url&&_40){
+url=_40;
+}
+if(!url){
+if(ae){
+var _42=dojo.i18n.getLocalization("dojox.atom.io","messages");
+throw new Error(_42.missingUrl);
+}
+return;
+}
+var _43=this;
+var _44={url:url,handleAs:"text",contentType:"text/xml",sync:this.sync,preventCache:this.preventCache,postData:_3a.toString(true),load:function(_45,_46){
+var _47=_46.xhr.getResponseHeader("Location");
+if(!_47){
+_47=url;
+}
+if(!_46.retrieveEntry){
+if(_3c){
+_3c.call(_3f,_3a,_47,_46);
+}else{
+if(ae){
+var _48=dojo.i18n.getLocalization("dojox.atom.io","messages");
+throw new Error(_48.noCallback);
+}
+}
+}else{
+var _49=function(_4a,dom,_4c){
+if(_3c){
+_3c.call(_3f,_4a,_47,_4c);
+}else{
+if(ae){
+var _4d=dojo.i18n.getLocalization("dojox.atom.io","messages");
+throw new Error(_4d.noCallback);
+}
+}
+};
+_43.getEntry(_47,_49);
+}
+return _45;
+}};
+if(this.user&&this.user!==null){
+_44.user=this.user;
+}
+if(this.password&&this.password!==null){
+_44.password=this.password;
+}
+if(_3d){
+_44.error=function(_4e,_4f){
+_3d.call(_3f,_4e,_4f);
+};
+}else{
+_44.error=function(){
+var _50=dojo.i18n.getLocalization("dojox.atom.io","messages");
+throw new Error(_50.failedXhr);
+};
+}
+dojo.rawXhrPost(_44);
+},deleteEntry:function(_51,_52,_53,_54,_55){
+if(!_55){
+_55=dojo.global;
+}
+var url=null;
+if(typeof (_51)=="string"){
+url=_51;
+}else{
+url=_51.getEditHref();
+}
+if(!url){
+var _57=dojo.i18n.getLocalization("dojox.atom.io","messages");
+_52.call(_55,false,null);
+throw new Error(_57.missingUrl);
+}
+var _58={url:url,handleAs:"text",sync:this.sync,preventCache:this.preventCache,load:function(_59,_5a){
+_52.call(_55,_5a);
+return _59;
+}};
+if(this.user&&this.user!==null){
+_58.user=this.user;
+}
+if(this.password&&this.password!==null){
+_58.password=this.password;
+}
+if(_53){
+_58.error=function(_5b,_5c){
+_53.call(_55,_5b,_5c);
+};
+}else{
+_58.error=function(){
+var _5d=dojo.i18n.getLocalization("dojox.atom.io","messages");
+throw new Error(_5d.failedXhr);
+};
+}
+if(_54){
+_58.headers={"X-Method-Override":"DELETE"};
+dojo.xhrPost(_58);
+}else{
+dojo.xhrDelete(_58);
+}
+}});
+}
diff --git a/dojox/atom/io/model.js b/dojox/atom/io/model.js
new file mode 100644
index 0000000..e18e10f
--- /dev/null
+++ b/dojox/atom/io/model.js
@@ -0,0 +1,938 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.atom.io.model"]){
+dojo._hasResource["dojox.atom.io.model"]=true;
+dojo.provide("dojox.atom.io.model");
+dojo.require("dojox.xml.parser");
+dojo.require("dojo.string");
+dojo.require("dojo.date.stamp");
+dojo.requireLocalization("dojox.atom.io","messages",null,"");
+dojox.atom.io.model._Constants={"ATOM_URI":"http://www.w3.org/2005/Atom","ATOM_NS":"http://www.w3.org/2005/Atom","PURL_NS":"http://purl.org/atom/app#","APP_NS":"http://www.w3.org/2007/app"};
+dojox.atom.io.model._actions={"link":function(_1,_2){
+if(_1.links===null){
+_1.links=[];
+}
+var _3=new dojox.atom.io.model.Link();
+_3.buildFromDom(_2);
+_1.links.push(_3);
+},"author":function(_4,_5){
+if(_4.authors===null){
+_4.authors=[];
+}
+var _6=new dojox.atom.io.model.Person("author");
+_6.buildFromDom(_5);
+_4.authors.push(_6);
+},"contributor":function(_7,_8){
+if(_7.contributors===null){
+_7.contributors=[];
+}
+var _9=new dojox.atom.io.model.Person("contributor");
+_9.buildFromDom(_8);
+_7.contributors.push(_9);
+},"category":function(_a,_b){
+if(_a.categories===null){
+_a.categories=[];
+}
+var _c=new dojox.atom.io.model.Category();
+_c.buildFromDom(_b);
+_a.categories.push(_c);
+},"icon":function(_d,_e){
+_d.icon=dojox.xml.parser.textContent(_e);
+},"id":function(_f,_10){
+_f.id=dojox.xml.parser.textContent(_10);
+},"rights":function(obj,_12){
+obj.rights=dojox.xml.parser.textContent(_12);
+},"subtitle":function(obj,_14){
+var cnt=new dojox.atom.io.model.Content("subtitle");
+cnt.buildFromDom(_14);
+obj.subtitle=cnt;
+},"title":function(obj,_17){
+var cnt=new dojox.atom.io.model.Content("title");
+cnt.buildFromDom(_17);
+obj.title=cnt;
+},"updated":function(obj,_1a){
+obj.updated=dojox.atom.io.model.util.createDate(_1a);
+},"issued":function(obj,_1c){
+obj.issued=dojox.atom.io.model.util.createDate(_1c);
+},"modified":function(obj,_1e){
+obj.modified=dojox.atom.io.model.util.createDate(_1e);
+},"published":function(obj,_20){
+obj.published=dojox.atom.io.model.util.createDate(_20);
+},"entry":function(obj,_22){
+if(obj.entries===null){
+obj.entries=[];
+}
+var _23=obj.createEntry?obj.createEntry():new dojox.atom.io.model.Entry();
+_23.buildFromDom(_22);
+obj.entries.push(_23);
+},"content":function(obj,_25){
+var cnt=new dojox.atom.io.model.Content("content");
+cnt.buildFromDom(_25);
+obj.content=cnt;
+},"summary":function(obj,_28){
+var _29=new dojox.atom.io.model.Content("summary");
+_29.buildFromDom(_28);
+obj.summary=_29;
+},"name":function(obj,_2b){
+obj.name=dojox.xml.parser.textContent(_2b);
+},"email":function(obj,_2d){
+obj.email=dojox.xml.parser.textContent(_2d);
+},"uri":function(obj,_2f){
+obj.uri=dojox.xml.parser.textContent(_2f);
+},"generator":function(obj,_31){
+obj.generator=new dojox.atom.io.model.Generator();
+obj.generator.buildFromDom(_31);
+}};
+dojox.atom.io.model.util={createDate:function(_32){
+var _33=dojox.xml.parser.textContent(_32);
+if(_33){
+return dojo.date.stamp.fromISOString(dojo.trim(_33));
+}
+return null;
+},escapeHtml:function(str){
+str=str.replace(/&/gm,"&").replace(/</gm,"<").replace(/>/gm,">").replace(/"/gm,""");
+str=str.replace(/'/gm,"'");
+return str;
+},unEscapeHtml:function(str){
+str=str.replace(/&/gm,"&").replace(/</gm,"<").replace(/>/gm,">").replace(/"/gm,"\"");
+str=str.replace(/'/gm,"'");
+return str;
+},getNodename:function(_36){
+var _37=null;
+if(_36!==null){
+_37=_36.localName?_36.localName:_36.nodeName;
+if(_37!==null){
+var _38=_37.indexOf(":");
+if(_38!==-1){
+_37=_37.substring((_38+1),_37.length);
+}
+}
+}
+return _37;
+}};
+dojo.declare("dojox.atom.io.model.Node",null,{constructor:function(_39,_3a,_3b,_3c,_3d){
+this.name_space=_39;
+this.name=_3a;
+this.attributes=[];
+if(_3b){
+this.attributes=_3b;
+}
+this.content=[];
+this.rawNodes=[];
+this.textContent=null;
+if(_3c){
+this.content.push(_3c);
+}
+this.shortNs=_3d;
+this._objName="Node";
+},buildFromDom:function(_3e){
+this._saveAttributes(_3e);
+this.name_space=_3e.namespaceURI;
+this.shortNs=_3e.prefix;
+this.name=dojox.atom.io.model.util.getNodename(_3e);
+for(var x=0;x<_3e.childNodes.length;x++){
+var c=_3e.childNodes[x];
+if(dojox.atom.io.model.util.getNodename(c)!="#text"){
+this.rawNodes.push(c);
+var n=new dojox.atom.io.model.Node();
+n.buildFromDom(c,true);
+this.content.push(n);
+}else{
+this.content.push(c.nodeValue);
+}
+}
+this.textContent=dojox.xml.parser.textContent(_3e);
+},_saveAttributes:function(_42){
+if(!this.attributes){
+this.attributes=[];
+}
+var _43=function(_44){
+var _45=_44.attributes;
+if(_45===null){
+return false;
+}
+return (_45.length!==0);
+};
+if(_43(_42)&&this._getAttributeNames){
+var _46=this._getAttributeNames(_42);
+if(_46&&_46.length>0){
+for(var x in _46){
+var _48=_42.getAttribute(_46[x]);
+if(_48){
+this.attributes[_46[x]]=_48;
+}
+}
+}
+}
+},addAttribute:function(_49,_4a){
+this.attributes[_49]=_4a;
+},getAttribute:function(_4b){
+return this.attributes[_4b];
+},_getAttributeNames:function(_4c){
+var _4d=[];
+for(var i=0;i<_4c.attributes.length;i++){
+_4d.push(_4c.attributes[i].nodeName);
+}
+return _4d;
+},toString:function(){
+var xml=[];
+var x;
+var _51=(this.shortNs?this.shortNs+":":"")+this.name;
+var _52=(this.name=="#cdata-section");
+if(_52){
+xml.push("<![CDATA[");
+xml.push(this.textContent);
+xml.push("]]>");
+}else{
+xml.push("<");
+xml.push(_51);
+if(this.name_space){
+xml.push(" xmlns='"+this.name_space+"'");
+}
+if(this.attributes){
+for(x in this.attributes){
+xml.push(" "+x+"='"+this.attributes[x]+"'");
+}
+}
+if(this.content){
+xml.push(">");
+for(x in this.content){
+xml.push(this.content[x]);
+}
+xml.push("</"+_51+">\n");
+}else{
+xml.push("/>\n");
+}
+}
+return xml.join("");
+},addContent:function(_53){
+this.content.push(_53);
+}});
+dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{constructor:function(_54){
+this.ATOM_URI=dojox.atom.io.model._Constants.ATOM_URI;
+this.links=null;
+this.authors=null;
+this.categories=null;
+this.contributors=null;
+this.icon=this.id=this.logo=this.xmlBase=this.rights=null;
+this.subtitle=this.title=null;
+this.updated=this.published=null;
+this.issued=this.modified=null;
+this.content=null;
+this.extensions=null;
+this.entries=null;
+this.name_spaces={};
+this._objName="AtomItem";
+},_getAttributeNames:function(){
+return null;
+},_accepts:{},accept:function(tag){
+return Boolean(this._accepts[tag]);
+},_postBuild:function(){
+},buildFromDom:function(_56){
+var i,c,n;
+for(i=0;i<_56.attributes.length;i++){
+c=_56.attributes.item(i);
+n=dojox.atom.io.model.util.getNodename(c);
+if(c.prefix=="xmlns"&&c.prefix!=n){
+this.addNamespace(c.nodeValue,n);
+}
+}
+c=_56.childNodes;
+for(i=0;i<c.length;i++){
+if(c[i].nodeType==1){
+var _5a=dojox.atom.io.model.util.getNodename(c[i]);
+if(!_5a){
+continue;
+}
+if(c[i].namespaceURI!=dojox.atom.io.model._Constants.ATOM_NS&&_5a!="#text"){
+if(!this.extensions){
+this.extensions=[];
+}
+var _5b=new dojox.atom.io.model.Node();
+_5b.buildFromDom(c[i]);
+this.extensions.push(_5b);
+}
+if(!this.accept(_5a.toLowerCase())){
+continue;
+}
+var fn=dojox.atom.io.model._actions[_5a];
+if(fn){
+fn(this,c[i]);
+}
+}
+}
+this._saveAttributes(_56);
+if(this._postBuild){
+this._postBuild();
+}
+},addNamespace:function(_5d,_5e){
+if(_5d&&_5e){
+this.name_spaces[_5e]=_5d;
+}
+},addAuthor:function(_5f,_60,uri){
+if(!this.authors){
+this.authors=[];
+}
+this.authors.push(new dojox.atom.io.model.Person("author",_5f,_60,uri));
+},addContributor:function(_62,_63,uri){
+if(!this.contributors){
+this.contributors=[];
+}
+this.contributors.push(new dojox.atom.io.model.Person("contributor",_62,_63,uri));
+},addLink:function(_65,rel,_67,_68,_69){
+if(!this.links){
+this.links=[];
+}
+this.links.push(new dojox.atom.io.model.Link(_65,rel,_67,_68,_69));
+},removeLink:function(_6a,rel){
+if(!this.links||!dojo.isArray(this.links)){
+return;
+}
+var _6c=0;
+for(var i=0;i<this.links.length;i++){
+if((!_6a||this.links[i].href===_6a)&&(!rel||this.links[i].rel===rel)){
+this.links.splice(i,1);
+_6c++;
+}
+}
+return _6c;
+},removeBasicLinks:function(){
+if(!this.links){
+return;
+}
+var _6e=0;
+for(var i=0;i<this.links.length;i++){
+if(!this.links[i].rel){
+this.links.splice(i,1);
+_6e++;
+i--;
+}
+}
+return _6e;
+},addCategory:function(_70,_71,_72){
+if(!this.categories){
+this.categories=[];
+}
+this.categories.push(new dojox.atom.io.model.Category(_70,_71,_72));
+},getCategories:function(_73){
+if(!_73){
+return this.categories;
+}
+var arr=[];
+for(var x in this.categories){
+if(this.categories[x].scheme===_73){
+arr.push(this.categories[x]);
+}
+}
+return arr;
+},removeCategories:function(_76,_77){
+if(!this.categories){
+return;
+}
+var _78=0;
+for(var i=0;i<this.categories.length;i++){
+if((!_76||this.categories[i].scheme===_76)&&(!_77||this.categories[i].term===_77)){
+this.categories.splice(i,1);
+_78++;
+i--;
+}
+}
+return _78;
+},setTitle:function(str,_7b){
+if(!str){
+return;
+}
+this.title=new dojox.atom.io.model.Content("title");
+this.title.value=str;
+if(_7b){
+this.title.type=_7b;
+}
+},addExtension:function(_7c,_7d,_7e,_7f,_80){
+if(!this.extensions){
+this.extensions=[];
+}
+this.extensions.push(new dojox.atom.io.model.Node(_7c,_7d,_7e,_7f,_80||"ns"+this.extensions.length));
+},getExtensions:function(_81,_82){
+var arr=[];
+if(!this.extensions){
+return arr;
+}
+for(var x in this.extensions){
+if((this.extensions[x].name_space===_81||this.extensions[x].shortNs===_81)&&(!_82||this.extensions[x].name===_82)){
+arr.push(this.extensions[x]);
+}
+}
+return arr;
+},removeExtensions:function(_85,_86){
+if(!this.extensions){
+return;
+}
+for(var i=0;i<this.extensions.length;i++){
+if((this.extensions[i].name_space==_85||this.extensions[i].shortNs===_85)&&this.extensions[i].name===_86){
+this.extensions.splice(i,1);
+i--;
+}
+}
+},destroy:function(){
+this.links=null;
+this.authors=null;
+this.categories=null;
+this.contributors=null;
+this.icon=this.id=this.logo=this.xmlBase=this.rights=null;
+this.subtitle=this.title=null;
+this.updated=this.published=null;
+this.issued=this.modified=null;
+this.content=null;
+this.extensions=null;
+this.entries=null;
+}});
+dojo.declare("dojox.atom.io.model.Category",dojox.atom.io.model.Node,{constructor:function(_88,_89,_8a){
+this.scheme=_88;
+this.term=_89;
+this.label=_8a;
+this._objName="Category";
+},_postBuild:function(){
+},_getAttributeNames:function(){
+return ["label","scheme","term"];
+},toString:function(){
+var s=[];
+s.push("<category ");
+if(this.label){
+s.push(" label=\""+this.label+"\" ");
+}
+if(this.scheme){
+s.push(" scheme=\""+this.scheme+"\" ");
+}
+if(this.term){
+s.push(" term=\""+this.term+"\" ");
+}
+s.push("/>\n");
+return s.join("");
+},buildFromDom:function(_8c){
+this._saveAttributes(_8c);
+this.label=this.attributes.label;
+this.scheme=this.attributes.scheme;
+this.term=this.attributes.term;
+if(this._postBuild){
+this._postBuild();
+}
+}});
+dojo.declare("dojox.atom.io.model.Content",dojox.atom.io.model.Node,{constructor:function(_8d,_8e,src,_90,_91){
+this.tagName=_8d;
+this.value=_8e;
+this.src=src;
+this.type=_90;
+this.xmlLang=_91;
+this.HTML="html";
+this.TEXT="text";
+this.XHTML="xhtml";
+this.XML="xml";
+this._useTextContent="true";
+},_getAttributeNames:function(){
+return ["type","src"];
+},_postBuild:function(){
+},buildFromDom:function(_92){
+if(_92.innerHTML){
+this.value=_92.innerHTML;
+}else{
+this.value=dojox.xml.parser.textContent(_92);
+}
+this._saveAttributes(_92);
+if(this.attributes){
+this.type=this.attributes.type;
+this.scheme=this.attributes.scheme;
+this.term=this.attributes.term;
+}
+if(!this.type){
+this.type="text";
+}
+var _93=this.type.toLowerCase();
+if(_93==="html"||_93==="text/html"||_93==="xhtml"||_93==="text/xhtml"){
+this.value=dojox.atom.io.model.util.unEscapeHtml(this.value);
+}
+if(this._postBuild){
+this._postBuild();
+}
+},toString:function(){
+var s=[];
+s.push("<"+this.tagName+" ");
+if(!this.type){
+this.type="text";
+}
+if(this.type){
+s.push(" type=\""+this.type+"\" ");
+}
+if(this.xmlLang){
+s.push(" xml:lang=\""+this.xmlLang+"\" ");
+}
+if(this.xmlBase){
+s.push(" xml:base=\""+this.xmlBase+"\" ");
+}
+if(this.type.toLowerCase()==this.HTML){
+s.push(">"+dojox.atom.io.model.util.escapeHtml(this.value)+"</"+this.tagName+">\n");
+}else{
+s.push(">"+this.value+"</"+this.tagName+">\n");
+}
+var ret=s.join("");
+return ret;
+}});
+dojo.declare("dojox.atom.io.model.Link",dojox.atom.io.model.Node,{constructor:function(_96,rel,_98,_99,_9a){
+this.href=_96;
+this.hrefLang=_98;
+this.rel=rel;
+this.title=_99;
+this.type=_9a;
+},_getAttributeNames:function(){
+return ["href","jrefLang","rel","title","type"];
+},_postBuild:function(){
+},buildFromDom:function(_9b){
+this._saveAttributes(_9b);
+this.href=this.attributes.href;
+this.hrefLang=this.attributes.hreflang;
+this.rel=this.attributes.rel;
+this.title=this.attributes.title;
+this.type=this.attributes.type;
+if(this._postBuild){
+this._postBuild();
+}
+},toString:function(){
+var s=[];
+s.push("<link ");
+if(this.href){
+s.push(" href=\""+this.href+"\" ");
+}
+if(this.hrefLang){
+s.push(" hrefLang=\""+this.hrefLang+"\" ");
+}
+if(this.rel){
+s.push(" rel=\""+this.rel+"\" ");
+}
+if(this.title){
+s.push(" title=\""+this.title+"\" ");
+}
+if(this.type){
+s.push(" type = \""+this.type+"\" ");
+}
+s.push("/>\n");
+return s.join("");
+}});
+dojo.declare("dojox.atom.io.model.Person",dojox.atom.io.model.Node,{constructor:function(_9d,_9e,_9f,uri){
+this.author="author";
+this.contributor="contributor";
+if(!_9d){
+_9d=this.author;
+}
+this.personType=_9d;
+this.name=_9e||"";
+this.email=_9f||"";
+this.uri=uri||"";
+this._objName="Person";
+},_getAttributeNames:function(){
+return null;
+},_postBuild:function(){
+},accept:function(tag){
+return Boolean(this._accepts[tag]);
+},buildFromDom:function(_a2){
+var c=_a2.childNodes;
+for(var i=0;i<c.length;i++){
+var _a5=dojox.atom.io.model.util.getNodename(c[i]);
+if(!_a5){
+continue;
+}
+if(c[i].namespaceURI!=dojox.atom.io.model._Constants.ATOM_NS&&_a5!="#text"){
+if(!this.extensions){
+this.extensions=[];
+}
+var _a6=new dojox.atom.io.model.Node();
+_a6.buildFromDom(c[i]);
+this.extensions.push(_a6);
+}
+if(!this.accept(_a5.toLowerCase())){
+continue;
+}
+var fn=dojox.atom.io.model._actions[_a5];
+if(fn){
+fn(this,c[i]);
+}
+}
+this._saveAttributes(_a2);
+if(this._postBuild){
+this._postBuild();
+}
+},_accepts:{"name":true,"uri":true,"email":true},toString:function(){
+var s=[];
+s.push("<"+this.personType+">\n");
+if(this.name){
+s.push("\t<name>"+this.name+"</name>\n");
+}
+if(this.email){
+s.push("\t<email>"+this.email+"</email>\n");
+}
+if(this.uri){
+s.push("\t<uri>"+this.uri+"</uri>\n");
+}
+s.push("</"+this.personType+">\n");
+return s.join("");
+}});
+dojo.declare("dojox.atom.io.model.Generator",dojox.atom.io.model.Node,{constructor:function(uri,_aa,_ab){
+this.uri=uri;
+this.version=_aa;
+this.value=_ab;
+},_postBuild:function(){
+},buildFromDom:function(_ac){
+this.value=dojox.xml.parser.textContent(_ac);
+this._saveAttributes(_ac);
+this.uri=this.attributes.uri;
+this.version=this.attributes.version;
+if(this._postBuild){
+this._postBuild();
+}
+},toString:function(){
+var s=[];
+s.push("<generator ");
+if(this.uri){
+s.push(" uri=\""+this.uri+"\" ");
+}
+if(this.version){
+s.push(" version=\""+this.version+"\" ");
+}
+s.push(">"+this.value+"</generator>\n");
+var ret=s.join("");
+return ret;
+}});
+dojo.declare("dojox.atom.io.model.Entry",dojox.atom.io.model.AtomItem,{constructor:function(id){
+this.id=id;
+this._objName="Entry";
+this.feedUrl=null;
+},_getAttributeNames:function(){
+return null;
+},_accepts:{"author":true,"content":true,"category":true,"contributor":true,"created":true,"id":true,"link":true,"published":true,"rights":true,"summary":true,"title":true,"updated":true,"xmlbase":true,"issued":true,"modified":true},toString:function(_b0){
+var s=[];
+var i;
+if(_b0){
+s.push("<?xml version='1.0' encoding='UTF-8'?>");
+s.push("<entry xmlns='"+dojox.atom.io.model._Constants.ATOM_URI+"'");
+}else{
+s.push("<entry");
+}
+if(this.xmlBase){
+s.push(" xml:base=\""+this.xmlBase+"\" ");
+}
+for(i in this.name_spaces){
+s.push(" xmlns:"+i+"=\""+this.name_spaces[i]+"\"");
+}
+s.push(">\n");
+s.push("<id>"+(this.id?this.id:"")+"</id>\n");
+if(this.issued&&!this.published){
+this.published=this.issued;
+}
+if(this.published){
+s.push("<published>"+dojo.date.stamp.toISOString(this.published)+"</published>\n");
+}
+if(this.created){
+s.push("<created>"+dojo.date.stamp.toISOString(this.created)+"</created>\n");
+}
+if(this.issued){
+s.push("<issued>"+dojo.date.stamp.toISOString(this.issued)+"</issued>\n");
+}
+if(this.modified){
+s.push("<modified>"+dojo.date.stamp.toISOString(this.modified)+"</modified>\n");
+}
+if(this.modified&&!this.updated){
+this.updated=this.modified;
+}
+if(this.updated){
+s.push("<updated>"+dojo.date.stamp.toISOString(this.updated)+"</updated>\n");
+}
+if(this.rights){
+s.push("<rights>"+this.rights+"</rights>\n");
+}
+if(this.title){
+s.push(this.title.toString());
+}
+if(this.summary){
+s.push(this.summary.toString());
+}
+var _b3=[this.authors,this.categories,this.links,this.contributors,this.extensions];
+for(var x in _b3){
+if(_b3[x]){
+for(var y in _b3[x]){
+s.push(_b3[x][y]);
+}
+}
+}
+if(this.content){
+s.push(this.content.toString());
+}
+s.push("</entry>\n");
+return s.join("");
+},getEditHref:function(){
+if(this.links===null||this.links.length===0){
+return null;
+}
+for(var x in this.links){
+if(this.links[x].rel&&this.links[x].rel=="edit"){
+return this.links[x].href;
+}
+}
+return null;
+},setEditHref:function(url){
+if(this.links===null){
+this.links=[];
+}
+for(var x in this.links){
+if(this.links[x].rel&&this.links[x].rel=="edit"){
+this.links[x].href=url;
+return;
+}
+}
+this.addLink(url,"edit");
+}});
+dojo.declare("dojox.atom.io.model.Feed",dojox.atom.io.model.AtomItem,{_accepts:{"author":true,"content":true,"category":true,"contributor":true,"created":true,"id":true,"link":true,"published":true,"rights":true,"summary":true,"title":true,"updated":true,"xmlbase":true,"entry":true,"logo":true,"issued":true,"modified":true,"icon":true,"subtitle":true},addEntry:function(_b9){
+if(!_b9.id){
+var _ba=dojo.i18n.getLocalization("dojox.atom.io","messages");
+throw new Error(_ba.noId);
+}
+if(!this.entries){
+this.entries=[];
+}
+_b9.feedUrl=this.getSelfHref();
+this.entries.push(_b9);
+},getFirstEntry:function(){
+if(!this.entries||this.entries.length===0){
+return null;
+}
+return this.entries[0];
+},getEntry:function(_bb){
+if(!this.entries){
+return null;
+}
+for(var x in this.entries){
+if(this.entries[x].id==_bb){
+return this.entries[x];
+}
+}
+return null;
+},removeEntry:function(_bd){
+if(!this.entries){
+return;
+}
+var _be=0;
+for(var i=0;i<this.entries.length;i++){
+if(this.entries[i]===_bd){
+this.entries.splice(i,1);
+_be++;
+}
+}
+return _be;
+},setEntries:function(_c0){
+for(var x in _c0){
+this.addEntry(_c0[x]);
+}
+},toString:function(){
+var s=[];
+var i;
+s.push("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
+s.push("<feed xmlns=\""+dojox.atom.io.model._Constants.ATOM_URI+"\"");
+if(this.xmlBase){
+s.push(" xml:base=\""+this.xmlBase+"\"");
+}
+for(i in this.name_spaces){
+s.push(" xmlns:"+i+"=\""+this.name_spaces[i]+"\"");
+}
+s.push(">\n");
+s.push("<id>"+(this.id?this.id:"")+"</id>\n");
+if(this.title){
+s.push(this.title);
+}
+if(this.copyright&&!this.rights){
+this.rights=this.copyright;
+}
+if(this.rights){
+s.push("<rights>"+this.rights+"</rights>\n");
+}
+if(this.issued){
+s.push("<issued>"+dojo.date.stamp.toISOString(this.issued)+"</issued>\n");
+}
+if(this.modified){
+s.push("<modified>"+dojo.date.stamp.toISOString(this.modified)+"</modified>\n");
+}
+if(this.modified&&!this.updated){
+this.updated=this.modified;
+}
+if(this.updated){
+s.push("<updated>"+dojo.date.stamp.toISOString(this.updated)+"</updated>\n");
+}
+if(this.published){
+s.push("<published>"+dojo.date.stamp.toISOString(this.published)+"</published>\n");
+}
+if(this.icon){
+s.push("<icon>"+this.icon+"</icon>\n");
+}
+if(this.language){
+s.push("<language>"+this.language+"</language>\n");
+}
+if(this.logo){
+s.push("<logo>"+this.logo+"</logo>\n");
+}
+if(this.subtitle){
+s.push(this.subtitle.toString());
+}
+if(this.tagline){
+s.push(this.tagline.toString());
+}
+var _c4=[this.alternateLinks,this.authors,this.categories,this.contributors,this.otherLinks,this.extensions,this.entries];
+for(i in _c4){
+if(_c4[i]){
+for(var x in _c4[i]){
+s.push(_c4[i][x]);
+}
+}
+}
+s.push("</feed>");
+return s.join("");
+},createEntry:function(){
+var _c6=new dojox.atom.io.model.Entry();
+_c6.feedUrl=this.getSelfHref();
+return _c6;
+},getSelfHref:function(){
+if(this.links===null||this.links.length===0){
+return null;
+}
+for(var x in this.links){
+if(this.links[x].rel&&this.links[x].rel=="self"){
+return this.links[x].href;
+}
+}
+return null;
+}});
+dojo.declare("dojox.atom.io.model.Service",dojox.atom.io.model.AtomItem,{constructor:function(_c8){
+this.href=_c8;
+},buildFromDom:function(_c9){
+var _ca;
+var i;
+var len=_c9.childNodes?_c9.childNodes.length:0;
+this.workspaces=[];
+if(_c9.tagName!="service"){
+return;
+}
+if(_c9.namespaceURI!=dojox.atom.io.model._Constants.PURL_NS&&_c9.namespaceURI!=dojox.atom.io.model._Constants.APP_NS){
+return;
+}
+var ns=_c9.namespaceURI;
+this.name_space=_c9.namespaceURI;
+var _ce;
+if(typeof (_c9.getElementsByTagNameNS)!="undefined"){
+_ce=_c9.getElementsByTagNameNS(ns,"workspace");
+}else{
+_ce=[];
+var _cf=_c9.getElementsByTagName("workspace");
+for(i=0;i<_cf.length;i++){
+if(_cf[i].namespaceURI==ns){
+_ce.push(_cf[i]);
+}
+}
+}
+if(_ce&&_ce.length>0){
+var _d0=0;
+var _d1;
+for(i=0;i<_ce.length;i++){
+_d1=(typeof (_ce.item)==="undefined"?_ce[i]:_ce.item(i));
+var _d2=new dojox.atom.io.model.Workspace();
+_d2.buildFromDom(_d1);
+this.workspaces[_d0++]=_d2;
+}
+}
+},getCollection:function(url){
+for(var i=0;i<this.workspaces.length;i++){
+var _d5=this.workspaces[i].collections;
+for(var j=0;j<_d5.length;j++){
+if(_d5[j].href==url){
+return _d5;
+}
+}
+}
+return null;
+}});
+dojo.declare("dojox.atom.io.model.Workspace",dojox.atom.io.model.AtomItem,{constructor:function(_d7){
+this.title=_d7;
+this.collections=[];
+},buildFromDom:function(_d8){
+var _d9=dojox.atom.io.model.util.getNodename(_d8);
+if(_d9!="workspace"){
+return;
+}
+var c=_d8.childNodes;
+var len=0;
+for(var i=0;i<c.length;i++){
+var _dd=c[i];
+if(_dd.nodeType===1){
+_d9=dojox.atom.io.model.util.getNodename(_dd);
+if(_dd.namespaceURI==dojox.atom.io.model._Constants.PURL_NS||_dd.namespaceURI==dojox.atom.io.model._Constants.APP_NS){
+if(_d9==="collection"){
+var _de=new dojox.atom.io.model.Collection();
+_de.buildFromDom(_dd);
+this.collections[len++]=_de;
+}
+}else{
+if(_dd.namespaceURI===dojox.atom.io.model._Constants.ATOM_NS){
+if(_d9==="title"){
+this.title=dojox.xml.parser.textContent(_dd);
+}
+}else{
+var _df=dojo.i18n.getLocalization("dojox.atom.io","messages");
+throw new Error(_df.badNS);
+}
+}
+}
+}
+}});
+dojo.declare("dojox.atom.io.model.Collection",dojox.atom.io.model.AtomItem,{constructor:function(_e0,_e1){
+this.href=_e0;
+this.title=_e1;
+this.attributes=[];
+this.features=[];
+this.children=[];
+this.memberType=null;
+this.id=null;
+},buildFromDom:function(_e2){
+this.href=_e2.getAttribute("href");
+var c=_e2.childNodes;
+for(var i=0;i<c.length;i++){
+var _e5=c[i];
+if(_e5.nodeType===1){
+var _e6=dojox.atom.io.model.util.getNodename(_e5);
+if(_e5.namespaceURI==dojox.atom.io.model._Constants.PURL_NS||_e5.namespaceURI==dojox.atom.io.model._Constants.APP_NS){
+if(_e6==="member-type"){
+this.memberType=dojox.xml.parser.textContent(_e5);
+}else{
+if(_e6=="feature"){
+if(_e5.getAttribute("id")){
+this.features.push(_e5.getAttribute("id"));
+}
+}else{
+var _e7=new dojox.atom.io.model.Node();
+_e7.buildFromDom(_e5);
+this.children.push(_e7);
+}
+}
+}else{
+if(_e5.namespaceURI===dojox.atom.io.model._Constants.ATOM_NS){
+if(_e6==="id"){
+this.id=dojox.xml.parser.textContent(_e5);
+}else{
+if(_e6==="title"){
+this.title=dojox.xml.parser.textContent(_e5);
+}
+}
+}
+}
+}
+}
+}});
+}
diff --git a/dojox/atom/widget/FeedEntryEditor.js b/dojox/atom/widget/FeedEntryEditor.js
new file mode 100644
index 0000000..26d4a5b
--- /dev/null
+++ b/dojox/atom/widget/FeedEntryEditor.js
@@ -0,0 +1,735 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.atom.widget.FeedEntryEditor"]){
+dojo._hasResource["dojox.atom.widget.FeedEntryEditor"]=true;
+dojo.provide("dojox.atom.widget.FeedEntryEditor");
+dojo.require("dojox.atom.widget.FeedEntryViewer");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dijit._Container");
+dojo.require("dijit.Editor");
+dojo.require("dijit.form.TextBox");
+dojo.require("dijit.form.SimpleTextarea");
+dojo.requireLocalization("dojox.atom.widget","FeedEntryEditor",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.requireLocalization("dojox.atom.widget","PeopleEditor",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.experimental("dojox.atom.widget.FeedEntryEditor");
+dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryViewer,{_contentEditor:null,_oldContent:null,_setObject:null,enableEdit:false,_contentEditorCreator:null,_editors:{},entryNewButton:null,_editable:false,templateString:"<div class=\"feedEntryViewer\">\n    <table border=\"0\" width=\"100%\" class=\"feedEntryViewerMenuTable\" dojoAttachPoint=\"feedEntryViewerMenu\" style=\"display: none;\">\n        <tr width=\"100%\"  dojoAttachPoint=\"entryCheckBoxDisplayOptions [...]
+if(this.entrySelectionTopic!==""){
+this._subscriptions=[dojo.subscribe(this.entrySelectionTopic,this,"_handleEvent")];
+}
+var _1=dojo.i18n.getLocalization("dojox.atom.widget","FeedEntryViewer");
+this.displayOptions.innerHTML=_1.displayOptions;
+this.feedEntryCheckBoxLabelTitle.innerHTML=_1.title;
+this.feedEntryCheckBoxLabelAuthors.innerHTML=_1.authors;
+this.feedEntryCheckBoxLabelContributors.innerHTML=_1.contributors;
+this.feedEntryCheckBoxLabelId.innerHTML=_1.id;
+this.close.innerHTML=_1.close;
+this.feedEntryCheckBoxLabelUpdated.innerHTML=_1.updated;
+this.feedEntryCheckBoxLabelSummary.innerHTML=_1.summary;
+this.feedEntryCheckBoxLabelContent.innerHTML=_1.content;
+_1=dojo.i18n.getLocalization("dojox.atom.widget","FeedEntryEditor");
+this.doNew.innerHTML=_1.doNew;
+this.edit.innerHTML=_1.edit;
+this.save.innerHTML=_1.save;
+this.cancel.innerHTML=_1.cancel;
+},setEntry:function(_2,_3,_4){
+if(this._entry!==_2){
+this._editMode=false;
+_4=false;
+}else{
+_4=true;
+}
+dojox.atom.widget.FeedEntryEditor.superclass.setEntry.call(this,_2,_3);
+this._editable=this._isEditable(_2);
+if(!_4&&!this._editable){
+dojo.style(this.entryEditButton,"display","none");
+dojo.style(this.entrySaveCancelButtons,"display","none");
+}
+if(this._editable&&this.enableEdit){
+if(!_4){
+dojo.style(this.entryEditButton,"display","");
+if(this.enableMenuFade&&this.entrySaveCancelButton){
+dojo.fadeOut({node:this.entrySaveCancelButton,duration:250}).play();
+}
+}
+}
+},_toggleEdit:function(){
+if(this._editable&&this.enableEdit){
+dojo.style(this.entryEditButton,"display","none");
+dojo.style(this.entrySaveCancelButtons,"display","");
+this._editMode=true;
+this.setEntry(this._entry,this._feed,true);
+}
+},_handleEvent:function(_5){
+if(_5.source!=this&&_5.action=="delete"&&_5.entry&&_5.entry==this._entry){
+dojo.style(this.entryEditButton,"display","none");
+}
+dojox.atom.widget.FeedEntryEditor.superclass._handleEvent.call(this,_5);
+},_isEditable:function(_6){
+var _7=false;
+if(_6&&_6!==null&&_6.links&&_6.links!==null){
+for(var x in _6.links){
+if(_6.links[x].rel&&_6.links[x].rel=="edit"){
+_7=true;
+break;
+}
+}
+}
+return _7;
+},setTitle:function(_9,_a,_b){
+if(!_a){
+dojox.atom.widget.FeedEntryEditor.superclass.setTitle.call(this,_9,_a,_b);
+if(_b.title&&_b.title.value&&_b.title.value!==null){
+this.setFieldValidity("title",true);
+}
+}else{
+if(_b.title&&_b.title.value&&_b.title.value!==null){
+if(!this._toLoad){
+this._toLoad=[];
+}
+this.entryTitleSelect.value=_b.title.type;
+var _c=this._createEditor(_9,_b.title,true,_b.title.type==="html"||_b.title.type==="xhtml");
+_c.name="title";
+this._toLoad.push(_c);
+this.setFieldValidity("titleedit",true);
+this.setFieldValidity("title",true);
+}
+}
+},setAuthors:function(_d,_e,_f){
+if(!_e){
+dojox.atom.widget.FeedEntryEditor.superclass.setAuthors.call(this,_d,_e,_f);
+if(_f.authors&&_f.authors.length>0){
+this.setFieldValidity("authors",true);
+}
+}else{
+if(_f.authors&&_f.authors.length>0){
+this._editors.authors=this._createPeopleEditor(this.entryAuthorNode,{data:_f.authors,name:"Author"});
+this.setFieldValidity("authors",true);
+}
+}
+},setContributors:function(_10,_11,_12){
+if(!_11){
+dojox.atom.widget.FeedEntryEditor.superclass.setContributors.call(this,_10,_11,_12);
+if(_12.contributors&&_12.contributors.length>0){
+this.setFieldValidity("contributors",true);
+}
+}else{
+if(_12.contributors&&_12.contributors.length>0){
+this._editors.contributors=this._createPeopleEditor(this.entryContributorNode,{data:_12.contributors,name:"Contributor"});
+this.setFieldValidity("contributors",true);
+}
+}
+},setId:function(_13,_14,_15){
+if(!_14){
+dojox.atom.widget.FeedEntryEditor.superclass.setId.call(this,_13,_14,_15);
+if(_15.id&&_15.id!==null){
+this.setFieldValidity("id",true);
+}
+}else{
+if(_15.id&&_15.id!==null){
+this._editors.id=this._createEditor(_13,_15.id);
+this.setFieldValidity("id",true);
+}
+}
+},setUpdated:function(_16,_17,_18){
+if(!_17){
+dojox.atom.widget.FeedEntryEditor.superclass.setUpdated.call(this,_16,_17,_18);
+if(_18.updated&&_18.updated!==null){
+this.setFieldValidity("updated",true);
+}
+}else{
+if(_18.updated&&_18.updated!==null){
+this._editors.updated=this._createEditor(_16,_18.updated);
+this.setFieldValidity("updated",true);
+}
+}
+},setSummary:function(_19,_1a,_1b){
+if(!_1a){
+dojox.atom.widget.FeedEntryEditor.superclass.setSummary.call(this,_19,_1a,_1b);
+if(_1b.summary&&_1b.summary.value&&_1b.summary.value!==null){
+this.setFieldValidity("summary",true);
+}
+}else{
+if(_1b.summary&&_1b.summary.value&&_1b.summary.value!==null){
+if(!this._toLoad){
+this._toLoad=[];
+}
+this.entrySummarySelect.value=_1b.summary.type;
+var _1c=this._createEditor(_19,_1b.summary,true,_1b.summary.type==="html"||_1b.summary.type==="xhtml");
+_1c.name="summary";
+this._toLoad.push(_1c);
+this.setFieldValidity("summaryedit",true);
+this.setFieldValidity("summary",true);
+}
+}
+},setContent:function(_1d,_1e,_1f){
+if(!_1e){
+dojox.atom.widget.FeedEntryEditor.superclass.setContent.call(this,_1d,_1e,_1f);
+if(_1f.content&&_1f.content.value&&_1f.content.value!==null){
+this.setFieldValidity("content",true);
+}
+}else{
+if(_1f.content&&_1f.content.value&&_1f.content.value!==null){
+if(!this._toLoad){
+this._toLoad=[];
+}
+this.entryContentSelect.value=_1f.content.type;
+var _20=this._createEditor(_1d,_1f.content,true,_1f.content.type==="html"||_1f.content.type==="xhtml");
+_20.name="content";
+this._toLoad.push(_20);
+this.setFieldValidity("contentedit",true);
+this.setFieldValidity("content",true);
+}
+}
+},_createEditor:function(_21,_22,_23,rte){
+var _25;
+var box;
+if(!_22){
+if(rte){
+return {anchorNode:_21,entryValue:"",editor:null,generateEditor:function(){
+var _27=document.createElement("div");
+_27.innerHTML=this.entryValue;
+this.anchorNode.appendChild(_27);
+var _28=new dijit.Editor({},_27);
+this.editor=_28;
+return _28;
+}};
+}
+if(_23){
+_25=document.createElement("textarea");
+_21.appendChild(_25);
+dojo.style(_25,"width","90%");
+box=new dijit.form.SimpleTextarea({},_25);
+}else{
+_25=document.createElement("input");
+_21.appendChild(_25);
+dojo.style(_25,"width","95%");
+box=new dijit.form.TextBox({},_25);
+}
+box.attr("value","");
+return box;
+}
+var _29;
+if(_22.value!==undefined){
+_29=_22.value;
+}else{
+if(_22.attr){
+_29=_22.attr("value");
+}else{
+_29=_22;
+}
+}
+if(rte){
+if(_29.indexOf("<")!=-1){
+_29=_29.replace(/</g,"<");
+}
+return {anchorNode:_21,entryValue:_29,editor:null,generateEditor:function(){
+var _2a=document.createElement("div");
+_2a.innerHTML=this.entryValue;
+this.anchorNode.appendChild(_2a);
+var _2b=new dijit.Editor({},_2a);
+this.editor=_2b;
+return _2b;
+}};
+}
+if(_23){
+_25=document.createElement("textarea");
+_21.appendChild(_25);
+dojo.style(_25,"width","90%");
+box=new dijit.form.SimpleTextarea({},_25);
+}else{
+_25=document.createElement("input");
+_21.appendChild(_25);
+dojo.style(_25,"width","95%");
+box=new dijit.form.TextBox({},_25);
+}
+box.attr("value",_29);
+return box;
+},_switchEditor:function(_2c){
+var _2d=null;
+var _2e=null;
+var _2f=null;
+if(dojo.isIE){
+_2e=_2c.srcElement;
+}else{
+_2e=_2c.target;
+}
+if(_2e===this.entryTitleSelect){
+_2f=this.entryTitleNode;
+_2d="title";
+}else{
+if(_2e===this.entrySummarySelect){
+_2f=this.entrySummaryNode;
+_2d="summary";
+}else{
+_2f=this.entryContentNode;
+_2d="content";
+}
+}
+var _30=this._editors[_2d];
+var _31;
+var _32;
+if(_2e.value==="text"){
+if(_30.declaredClass==="dijit.Editor"){
+_32=_30.attr("value",false);
+_30.close(false,true);
+_30.destroy();
+while(_2f.firstChild){
+dojo.destroy(_2f.firstChild);
+}
+_31=this._createEditor(_2f,{value:_32},true,false);
+this._editors[_2d]=_31;
+}
+}else{
+if(_30.declaredClass!="dijit.Editor"){
+_32=_30.attr("value");
+_30.destroy();
+while(_2f.firstChild){
+dojo.destroy(_2f.firstChild);
+}
+_31=this._createEditor(_2f,{value:_32},true,true);
+_31=dojo.hitch(_31,_31.generateEditor)();
+this._editors[_2d]=_31;
+}
+}
+},_createPeopleEditor:function(_33,_34){
+var _35=document.createElement("div");
+_33.appendChild(_35);
+return new dojox.atom.widget.PeopleEditor(_34,_35);
+},saveEdits:function(){
+dojo.style(this.entrySaveCancelButtons,"display","none");
+dojo.style(this.entryEditButton,"display","");
+dojo.style(this.entryNewButton,"display","");
+var _36=false;
+var _37;
+var i;
+var _39;
+var _3a;
+var _3b;
+var _3c;
+if(!this._new){
+_3a=this.getEntry();
+if(this._editors.title&&(this._editors.title.attr("value")!=_3a.title.value||this.entryTitleSelect.value!=_3a.title.type)){
+_37=this._editors.title.attr("value");
+if(this.entryTitleSelect.value==="xhtml"){
+_37=this._enforceXhtml(_37);
+if(_37.indexOf("<div xmlns=\"http://www.w3.org/1999/xhtml\">")!==0){
+_37="<div xmlns=\"http://www.w3.org/1999/xhtml\">"+_37+"</div>";
+}
+}
+_3a.title=new dojox.atom.io.model.Content("title",_37,null,this.entryTitleSelect.value);
+_36=true;
+}
+if(this._editors.id.attr("value")!=_3a.id){
+_3a.id=this._editors.id.attr("value");
+_36=true;
+}
+if(this._editors.summary&&(this._editors.summary.attr("value")!=_3a.summary.value||this.entrySummarySelect.value!=_3a.summary.type)){
+_37=this._editors.summary.attr("value");
+if(this.entrySummarySelect.value==="xhtml"){
+_37=this._enforceXhtml(_37);
+if(_37.indexOf("<div xmlns=\"http://www.w3.org/1999/xhtml\">")!==0){
+_37="<div xmlns=\"http://www.w3.org/1999/xhtml\">"+_37+"</div>";
+}
+}
+_3a.summary=new dojox.atom.io.model.Content("summary",_37,null,this.entrySummarySelect.value);
+_36=true;
+}
+if(this._editors.content&&(this._editors.content.attr("value")!=_3a.content.value||this.entryContentSelect.value!=_3a.content.type)){
+_37=this._editors.content.attr("value");
+if(this.entryContentSelect.value==="xhtml"){
+_37=this._enforceXhtml(_37);
+if(_37.indexOf("<div xmlns=\"http://www.w3.org/1999/xhtml\">")!==0){
+_37="<div xmlns=\"http://www.w3.org/1999/xhtml\">"+_37+"</div>";
+}
+}
+_3a.content=new dojox.atom.io.model.Content("content",_37,null,this.entryContentSelect.value);
+_36=true;
+}
+if(this._editors.authors){
+if(_36){
+_3a.authors=[];
+_3b=this._editors.authors.getValues();
+for(i in _3b){
+if(_3b[i].name||_3b[i].email||_3b[i].uri){
+_3a.addAuthor(_3b[i].name,_3b[i].email,_3b[i].uri);
+}
+}
+}else{
+var _3d=_3a.authors;
+var _3e=function(_3f,_40,uri){
+for(i in _3d){
+if(_3d[i].name===_3f&&_3d[i].email===_40&&_3d[i].uri===uri){
+return true;
+}
+}
+return false;
+};
+_3b=this._editors.authors.getValues();
+_39=false;
+for(i in _3b){
+if(!_3e(_3b[i].name,_3b[i].email,_3b[i].uri)){
+_39=true;
+break;
+}
+}
+if(_39){
+_3a.authors=[];
+for(i in _3b){
+if(_3b[i].name||_3b[i].email||_3b[i].uri){
+_3a.addAuthor(_3b[i].name,_3b[i].email,_3b[i].uri);
+}
+}
+_36=true;
+}
+}
+}
+if(this._editors.contributors){
+if(_36){
+_3a.contributors=[];
+_3c=this._editors.contributors.getValues();
+for(i in _3c){
+if(_3c[i].name||_3c[i].email||_3c[i].uri){
+_3a.addAuthor(_3c[i].name,_3c[i].email,_3c[i].uri);
+}
+}
+}else{
+var _42=_3a.contributors;
+var _43=function(_44,_45,uri){
+for(i in _42){
+if(_42[i].name===_44&&_42[i].email===_45&&_42[i].uri===uri){
+return true;
+}
+}
+return false;
+};
+_3c=this._editors.contributors.getValues();
+_39=false;
+for(i in _3c){
+if(_43(_3c[i].name,_3c[i].email,_3c[i].uri)){
+_39=true;
+break;
+}
+}
+if(_39){
+_3a.contributors=[];
+for(i in _3c){
+if(_3c[i].name||_3c[i].email||_3c[i].uri){
+_3a.addContributor(_3c[i].name,_3c[i].email,_3c[i].uri);
+}
+}
+_36=true;
+}
+}
+}
+if(_36){
+dojo.publish(this.entrySelectionTopic,[{action:"update",source:this,entry:_3a,callback:this._handleSave}]);
+}
+}else{
+this._new=false;
+_3a=new dojox.atom.io.model.Entry();
+_37=this._editors.title.attr("value");
+if(this.entryTitleSelect.value==="xhtml"){
+_37=this._enforceXhtml(_37);
+_37="<div xmlns=\"http://www.w3.org/1999/xhtml\">"+_37+"</div>";
+}
+_3a.setTitle(_37,this.entryTitleSelect.value);
+_3a.id=this._editors.id.attr("value");
+_3b=this._editors.authors.getValues();
+for(i in _3b){
+if(_3b[i].name||_3b[i].email||_3b[i].uri){
+_3a.addAuthor(_3b[i].name,_3b[i].email,_3b[i].uri);
+}
+}
+_3c=this._editors.contributors.getValues();
+for(i in _3c){
+if(_3c[i].name||_3c[i].email||_3c[i].uri){
+_3a.addContributor(_3c[i].name,_3c[i].email,_3c[i].uri);
+}
+}
+_37=this._editors.summary.attr("value");
+if(this.entrySummarySelect.value==="xhtml"){
+_37=this._enforceXhtml(_37);
+_37="<div xmlns=\"http://www.w3.org/1999/xhtml\">"+_37+"</div>";
+}
+_3a.summary=new dojox.atom.io.model.Content("summary",_37,null,this.entrySummarySelect.value);
+_37=this._editors.content.attr("value");
+if(this.entryContentSelect.value==="xhtml"){
+_37=this._enforceXhtml(_37);
+_37="<div xmlns=\"http://www.w3.org/1999/xhtml\">"+_37+"</div>";
+}
+_3a.content=new dojox.atom.io.model.Content("content",_37,null,this.entryContentSelect.value);
+dojo.style(this.entryNewButton,"display","");
+dojo.publish(this.entrySelectionTopic,[{action:"post",source:this,entry:_3a}]);
+}
+this._editMode=false;
+this.setEntry(_3a,this._feed,true);
+},_handleSave:function(_47,_48){
+this._editMode=false;
+this.clear();
+this.setEntry(_47,this.getFeed(),true);
+},cancelEdits:function(){
+this._new=false;
+dojo.style(this.entrySaveCancelButtons,"display","none");
+if(this._editable){
+dojo.style(this.entryEditButton,"display","");
+}
+dojo.style(this.entryNewButton,"display","");
+this._editMode=false;
+this.clearEditors();
+this.setEntry(this.getEntry(),this.getFeed(),true);
+},clear:function(){
+this._editable=false;
+this.clearEditors();
+dojox.atom.widget.FeedEntryEditor.superclass.clear.apply(this);
+if(this._contentEditor){
+this._contentEditor=this._setObject=this._oldContent=this._contentEditorCreator=null;
+this._editors={};
+}
+},clearEditors:function(){
+for(var key in this._editors){
+if(this._editors[key].declaredClass==="dijit.Editor"){
+this._editors[key].close(false,true);
+}
+this._editors[key].destroy();
+}
+this._editors={};
+},_enforceXhtml:function(_4a){
+var _4b=null;
+if(_4a){
+var _4c=/<br>/g;
+_4b=_4a.replace(_4c,"<br/>");
+_4b=this._closeTag(_4b,"hr");
+_4b=this._closeTag(_4b,"img");
+}
+return _4b;
+},_closeTag:function(_4d,tag){
+var _4f="<"+tag;
+var _50=_4d.indexOf(_4f);
+if(_50!==-1){
+while(_50!==-1){
+var _51="";
+var _52=false;
+for(var i=0;i<_4d.length;i++){
+var c=_4d.charAt(i);
+if(i<=_50||_52){
+_51+=c;
+}else{
+if(c===">"){
+_51+="/";
+_52=true;
+}
+_51+=c;
+}
+}
+_4d=_51;
+_50=_4d.indexOf(_4f,_50+1);
+}
+}
+return _4d;
+},_toggleNew:function(){
+dojo.style(this.entryNewButton,"display","none");
+dojo.style(this.entryEditButton,"display","none");
+dojo.style(this.entrySaveCancelButtons,"display","");
+this.entrySummarySelect.value="text";
+this.entryContentSelect.value="text";
+this.entryTitleSelect.value="text";
+this.clearNodes();
+this._new=true;
+var _55=dojo.i18n.getLocalization("dojox.atom.widget","FeedEntryViewer");
+var _56=new dojox.atom.widget.EntryHeader({title:_55.title});
+this.entryTitleHeader.appendChild(_56.domNode);
+this._editors.title=this._createEditor(this.entryTitleNode,null);
+this.setFieldValidity("title",true);
+var _57=new dojox.atom.widget.EntryHeader({title:_55.authors});
+this.entryAuthorHeader.appendChild(_57.domNode);
+this._editors.authors=this._createPeopleEditor(this.entryAuthorNode,{name:"Author"});
+this.setFieldValidity("authors",true);
+var _58=new dojox.atom.widget.EntryHeader({title:_55.contributors});
+this.entryContributorHeader.appendChild(_58.domNode);
+this._editors.contributors=this._createPeopleEditor(this.entryContributorNode,{name:"Contributor"});
+this.setFieldValidity("contributors",true);
+var _59=new dojox.atom.widget.EntryHeader({title:_55.id});
+this.entryIdHeader.appendChild(_59.domNode);
+this._editors.id=this._createEditor(this.entryIdNode,null);
+this.setFieldValidity("id",true);
+var _5a=new dojox.atom.widget.EntryHeader({title:_55.updated});
+this.entryUpdatedHeader.appendChild(_5a.domNode);
+this._editors.updated=this._createEditor(this.entryUpdatedNode,null);
+this.setFieldValidity("updated",true);
+var _5b=new dojox.atom.widget.EntryHeader({title:_55.summary});
+this.entrySummaryHeader.appendChild(_5b.domNode);
+this._editors.summary=this._createEditor(this.entrySummaryNode,null,true);
+this.setFieldValidity("summaryedit",true);
+this.setFieldValidity("summary",true);
+var _5c=new dojox.atom.widget.EntryHeader({title:_55.content});
+this.entryContentHeader.appendChild(_5c.domNode);
+this._editors.content=this._createEditor(this.entryContentNode,null,true);
+this.setFieldValidity("contentedit",true);
+this.setFieldValidity("content",true);
+this._displaySections();
+},_displaySections:function(){
+dojo.style(this.entrySummarySelect,"display","none");
+dojo.style(this.entryContentSelect,"display","none");
+dojo.style(this.entryTitleSelect,"display","none");
+if(this.isFieldValid("contentedit")){
+dojo.style(this.entryContentSelect,"display","");
+}
+if(this.isFieldValid("summaryedit")){
+dojo.style(this.entrySummarySelect,"display","");
+}
+if(this.isFieldValid("titleedit")){
+dojo.style(this.entryTitleSelect,"display","");
+}
+dojox.atom.widget.FeedEntryEditor.superclass._displaySections.apply(this);
+if(this._toLoad){
+for(var i in this._toLoad){
+var _5e;
+if(this._toLoad[i].generateEditor){
+_5e=dojo.hitch(this._toLoad[i],this._toLoad[i].generateEditor)();
+}else{
+_5e=this._toLoad[i];
+}
+this._editors[this._toLoad[i].name]=_5e;
+this._toLoad[i]=null;
+}
+this._toLoad=null;
+}
+}});
+dojo.declare("dojox.atom.widget.PeopleEditor",[dijit._Widget,dijit._Templated,dijit._Container],{templateString:"<div class=\"peopleEditor\">\n\t<table style=\"width: 100%\">\n\t\t<tbody dojoAttachPoint=\"peopleEditorEditors\"></tbody>\n\t</table>\n\t<span class=\"peopleEditorButton\" dojoAttachPoint=\"peopleEditorButton\" dojoAttachEvent=\"onclick:_add\"></span>\n</div>\n",_rows:[],_editors:[],_index:0,_numRows:0,postCreate:function(){
+var _5f=dojo.i18n.getLocalization("dojox.atom.widget","PeopleEditor");
+if(this.name){
+if(this.name=="Author"){
+this.peopleEditorButton.appendChild(document.createTextNode("["+_5f.addAuthor+"]"));
+}else{
+if(this.name=="Contributor"){
+this.peopleEditorButton.appendChild(document.createTextNode("["+_5f.addContributor+"]"));
+}
+}
+}else{
+this.peopleEditorButton.appendChild(document.createTextNode("["+_5f.add+"]"));
+}
+this._editors=[];
+if(!this.data||this.data.length===0){
+this._createEditors(null,null,null,0,this.name);
+this._index=1;
+}else{
+for(var i in this.data){
+this._createEditors(this.data[i].name,this.data[i].email,this.data[i].uri,i);
+this._index++;
+this._numRows++;
+}
+}
+},destroy:function(){
+for(var key in this._editors){
+for(var _62 in this._editors[key]){
+this._editors[key][_62].destroy();
+}
+}
+this._editors=[];
+},_createEditors:function(_63,_64,uri,_66,_67){
+var row=document.createElement("tr");
+this.peopleEditorEditors.appendChild(row);
+row.id="removeRow"+_66;
+var _69=document.createElement("td");
+_69.setAttribute("align","right");
+row.appendChild(_69);
+_69.colSpan=2;
+if(this._numRows>0){
+var hr=document.createElement("hr");
+_69.appendChild(hr);
+hr.id="hr"+_66;
+}
+row=document.createElement("span");
+_69.appendChild(row);
+row.className="peopleEditorButton";
+dojo.style(row,"font-size","x-small");
+dojo.connect(row,"onclick",this,"_removeEditor");
+row.id="remove"+_66;
+_69=document.createTextNode("[X]");
+row.appendChild(_69);
+row=document.createElement("tr");
+this.peopleEditorEditors.appendChild(row);
+row.id="editorsRow"+_66;
+var _6b=document.createElement("td");
+row.appendChild(_6b);
+dojo.style(_6b,"width","20%");
+_69=document.createElement("td");
+row.appendChild(_69);
+row=document.createElement("table");
+_6b.appendChild(row);
+dojo.style(row,"width","100%");
+_6b=document.createElement("tbody");
+row.appendChild(_6b);
+row=document.createElement("table");
+_69.appendChild(row);
+dojo.style(row,"width","100%");
+_69=document.createElement("tbody");
+row.appendChild(_69);
+this._editors[_66]=[];
+this._editors[_66].push(this._createEditor(_63,_67+"name"+_66,"Name:",_6b,_69));
+this._editors[_66].push(this._createEditor(_64,_67+"email"+_66,"Email:",_6b,_69));
+this._editors[_66].push(this._createEditor(uri,_67+"uri"+_66,"URI:",_6b,_69));
+},_createEditor:function(_6c,id,_6e,_6f,_70){
+var row=document.createElement("tr");
+_6f.appendChild(row);
+var _72=document.createElement("label");
+_72.setAttribute("for",id);
+_72.appendChild(document.createTextNode(_6e));
+_6f=document.createElement("td");
+_6f.appendChild(_72);
+row.appendChild(_6f);
+row=document.createElement("tr");
+_70.appendChild(row);
+_70=document.createElement("td");
+row.appendChild(_70);
+var _73=document.createElement("input");
+_73.setAttribute("id",id);
+_70.appendChild(_73);
+dojo.style(_73,"width","95%");
+var box=new dijit.form.TextBox({},_73);
+box.attr("value",_6c);
+return box;
+},_removeEditor:function(_75){
+var _76=null;
+if(dojo.isIE){
+_76=_75.srcElement;
+}else{
+_76=_75.target;
+}
+var id=_76.id;
+id=id.substring(6);
+for(var key in this._editors[id]){
+this._editors[id][key].destroy();
+}
+var _79=dojo.byId("editorsRow"+id);
+var _7a=_79.parentNode;
+_7a.removeChild(_79);
+_79=dojo.byId("removeRow"+id);
+_7a=_79.parentNode;
+_7a.removeChild(_79);
+this._numRows--;
+if(this._numRows===1&&_7a.firstChild.firstChild.firstChild.tagName.toLowerCase()==="hr"){
+_79=_7a.firstChild.firstChild;
+_79.removeChild(_79.firstChild);
+}
+this._editors[id]=null;
+},_add:function(){
+this._createEditors(null,null,null,this._index);
+this._index++;
+this._numRows++;
+},getValues:function(){
+var _7b=[];
+for(var i in this._editors){
+if(this._editors[i]){
+_7b.push({name:this._editors[i][0].attr("value"),email:this._editors[i][1].attr("value"),uri:this._editors[i][2].attr("value")});
+}
+}
+return _7b;
+}});
+}
diff --git a/dojox/atom/widget/FeedEntryViewer.js b/dojox/atom/widget/FeedEntryViewer.js
new file mode 100644
index 0000000..d6d58c0
--- /dev/null
+++ b/dojox/atom/widget/FeedEntryViewer.js
@@ -0,0 +1,395 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.atom.widget.FeedEntryViewer"]){
+dojo._hasResource["dojox.atom.widget.FeedEntryViewer"]=true;
+dojo.provide("dojox.atom.widget.FeedEntryViewer");
+dojo.require("dojo.fx");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dijit._Container");
+dojo.require("dijit.layout.ContentPane");
+dojo.require("dojox.atom.io.Connection");
+dojo.requireLocalization("dojox.atom.widget","FeedEntryViewer",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.experimental("dojox.atom.widget.FeedEntryViewer");
+dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget,dijit._Templated,dijit._Container],{entrySelectionTopic:"",_validEntryFields:{},displayEntrySections:"",_displayEntrySections:null,enableMenu:false,enableMenuFade:false,_optionButtonDisplayed:true,templateString:"<div class=\"feedEntryViewer\">\n    <table border=\"0\" width=\"100%\" class=\"feedEntryViewerMenuTable\" dojoAttachPoint=\"feedEntryViewerMenu\" style=\"display: none;\">\n        <tr width=\"100%\"  dojoAttachPoi [...]
+if(this.entrySelectionTopic!==""){
+this._subscriptions=[dojo.subscribe(this.entrySelectionTopic,this,"_handleEvent")];
+}
+var _1=dojo.i18n.getLocalization("dojox.atom.widget","FeedEntryViewer");
+this.displayOptions.innerHTML=_1.displayOptions;
+this.feedEntryCheckBoxLabelTitle.innerHTML=_1.title;
+this.feedEntryCheckBoxLabelAuthors.innerHTML=_1.authors;
+this.feedEntryCheckBoxLabelContributors.innerHTML=_1.contributors;
+this.feedEntryCheckBoxLabelId.innerHTML=_1.id;
+this.close.innerHTML=_1.close;
+this.feedEntryCheckBoxLabelUpdated.innerHTML=_1.updated;
+this.feedEntryCheckBoxLabelSummary.innerHTML=_1.summary;
+this.feedEntryCheckBoxLabelContent.innerHTML=_1.content;
+},startup:function(){
+if(this.displayEntrySections===""){
+this._displayEntrySections=["title","authors","contributors","summary","content","id","updated"];
+}else{
+this._displayEntrySections=this.displayEntrySections.split(",");
+}
+this._setDisplaySectionsCheckboxes();
+if(this.enableMenu){
+dojo.style(this.feedEntryViewerMenu,"display","");
+if(this.entryCheckBoxRow&&this.entryCheckBoxRow2){
+if(this.enableMenuFade){
+dojo.fadeOut({node:this.entryCheckBoxRow,duration:250}).play();
+dojo.fadeOut({node:this.entryCheckBoxRow2,duration:250}).play();
+}
+}
+}
+},clear:function(){
+this.destroyDescendants();
+this._entry=null;
+this._feed=null;
+this.clearNodes();
+},clearNodes:function(){
+dojo.forEach(["entryTitleRow","entryAuthorRow","entryContributorRow","entrySummaryRow","entryContentRow","entryIdRow","entryUpdatedRow"],function(_2){
+dojo.style(this[_2],"display","none");
+},this);
+dojo.forEach(["entryTitleNode","entryTitleHeader","entryAuthorHeader","entryContributorHeader","entryContributorNode","entrySummaryHeader","entrySummaryNode","entryContentHeader","entryContentNode","entryIdNode","entryIdHeader","entryUpdatedHeader","entryUpdatedNode"],function(_3){
+while(this[_3].firstChild){
+dojo.destroy(this[_3].firstChild);
+}
+},this);
+},setEntry:function(_4,_5,_6){
+this.clear();
+this._validEntryFields={};
+this._entry=_4;
+this._feed=_5;
+if(_4!==null){
+if(this.entryTitleHeader){
+this.setTitleHeader(this.entryTitleHeader,_4);
+}
+if(this.entryTitleNode){
+this.setTitle(this.entryTitleNode,this._editMode,_4);
+}
+if(this.entryAuthorHeader){
+this.setAuthorsHeader(this.entryAuthorHeader,_4);
+}
+if(this.entryAuthorNode){
+this.setAuthors(this.entryAuthorNode,this._editMode,_4);
+}
+if(this.entryContributorHeader){
+this.setContributorsHeader(this.entryContributorHeader,_4);
+}
+if(this.entryContributorNode){
+this.setContributors(this.entryContributorNode,this._editMode,_4);
+}
+if(this.entryIdHeader){
+this.setIdHeader(this.entryIdHeader,_4);
+}
+if(this.entryIdNode){
+this.setId(this.entryIdNode,this._editMode,_4);
+}
+if(this.entryUpdatedHeader){
+this.setUpdatedHeader(this.entryUpdatedHeader,_4);
+}
+if(this.entryUpdatedNode){
+this.setUpdated(this.entryUpdatedNode,this._editMode,_4);
+}
+if(this.entrySummaryHeader){
+this.setSummaryHeader(this.entrySummaryHeader,_4);
+}
+if(this.entrySummaryNode){
+this.setSummary(this.entrySummaryNode,this._editMode,_4);
+}
+if(this.entryContentHeader){
+this.setContentHeader(this.entryContentHeader,_4);
+}
+if(this.entryContentNode){
+this.setContent(this.entryContentNode,this._editMode,_4);
+}
+}
+this._displaySections();
+},setTitleHeader:function(_7,_8){
+if(_8.title&&_8.title.value&&_8.title.value!==null){
+var _9=dojo.i18n.getLocalization("dojox.atom.widget","FeedEntryViewer");
+var _a=new dojox.atom.widget.EntryHeader({title:_9.title});
+_7.appendChild(_a.domNode);
+}
+},setTitle:function(_b,_c,_d){
+if(_d.title&&_d.title.value&&_d.title.value!==null){
+if(_d.title.type=="text"){
+var _e=document.createTextNode(_d.title.value);
+_b.appendChild(_e);
+}else{
+var _f=document.createElement("span");
+var _10=new dijit.layout.ContentPane({refreshOnShow:true,executeScripts:false},_f);
+_10.attr("content",_d.title.value);
+_b.appendChild(_10.domNode);
+}
+this.setFieldValidity("title",true);
+}
+},setAuthorsHeader:function(_11,_12){
+if(_12.authors&&_12.authors.length>0){
+var _13=dojo.i18n.getLocalization("dojox.atom.widget","FeedEntryViewer");
+var _14=new dojox.atom.widget.EntryHeader({title:_13.authors});
+_11.appendChild(_14.domNode);
+}
+},setAuthors:function(_15,_16,_17){
+if(_17.authors&&_17.authors.length>0){
+for(var i in _17.authors){
+if(_17.authors[i].name){
+var _19=_15;
+if(_17.authors[i].uri){
+var _1a=document.createElement("a");
+_19.appendChild(_1a);
+_1a.href=_17.authors[i].uri;
+_19=_1a;
+}
+var _1b=_17.authors[i].name;
+if(_17.authors[i].email){
+_1b=_1b+" ("+_17.authors[i].email+")";
+}
+var _1c=document.createTextNode(_1b);
+_19.appendChild(_1c);
+var _1d=document.createElement("br");
+_15.appendChild(_1d);
+this.setFieldValidity("authors",true);
+}
+}
+}
+},setContributorsHeader:function(_1e,_1f){
+if(_1f.contributors&&_1f.contributors.length>0){
+var _20=dojo.i18n.getLocalization("dojox.atom.widget","FeedEntryViewer");
+var _21=new dojox.atom.widget.EntryHeader({title:_20.contributors});
+_1e.appendChild(_21.domNode);
+}
+},setContributors:function(_22,_23,_24){
+if(_24.contributors&&_24.contributors.length>0){
+for(var i in _24.contributors){
+var _26=document.createTextNode(_24.contributors[i].name);
+_22.appendChild(_26);
+var _27=document.createElement("br");
+_22.appendChild(_27);
+this.setFieldValidity("contributors",true);
+}
+}
+},setIdHeader:function(_28,_29){
+if(_29.id&&_29.id!==null){
+var _2a=dojo.i18n.getLocalization("dojox.atom.widget","FeedEntryViewer");
+var _2b=new dojox.atom.widget.EntryHeader({title:_2a.id});
+_28.appendChild(_2b.domNode);
+}
+},setId:function(_2c,_2d,_2e){
+if(_2e.id&&_2e.id!==null){
+var _2f=document.createTextNode(_2e.id);
+_2c.appendChild(_2f);
+this.setFieldValidity("id",true);
+}
+},setUpdatedHeader:function(_30,_31){
+if(_31.updated&&_31.updated!==null){
+var _32=dojo.i18n.getLocalization("dojox.atom.widget","FeedEntryViewer");
+var _33=new dojox.atom.widget.EntryHeader({title:_32.updated});
+_30.appendChild(_33.domNode);
+}
+},setUpdated:function(_34,_35,_36){
+if(_36.updated&&_36.updated!==null){
+var _37=document.createTextNode(_36.updated);
+_34.appendChild(_37);
+this.setFieldValidity("updated",true);
+}
+},setSummaryHeader:function(_38,_39){
+if(_39.summary&&_39.summary.value&&_39.summary.value!==null){
+var _3a=dojo.i18n.getLocalization("dojox.atom.widget","FeedEntryViewer");
+var _3b=new dojox.atom.widget.EntryHeader({title:_3a.summary});
+_38.appendChild(_3b.domNode);
+}
+},setSummary:function(_3c,_3d,_3e){
+if(_3e.summary&&_3e.summary.value&&_3e.summary.value!==null){
+var _3f=document.createElement("span");
+var _40=new dijit.layout.ContentPane({refreshOnShow:true,executeScripts:false},_3f);
+_40.attr("content",_3e.summary.value);
+_3c.appendChild(_40.domNode);
+this.setFieldValidity("summary",true);
+}
+},setContentHeader:function(_41,_42){
+if(_42.content&&_42.content.value&&_42.content.value!==null){
+var _43=dojo.i18n.getLocalization("dojox.atom.widget","FeedEntryViewer");
+var _44=new dojox.atom.widget.EntryHeader({title:_43.content});
+_41.appendChild(_44.domNode);
+}
+},setContent:function(_45,_46,_47){
+if(_47.content&&_47.content.value&&_47.content.value!==null){
+var _48=document.createElement("span");
+var _49=new dijit.layout.ContentPane({refreshOnShow:true,executeScripts:false},_48);
+_49.attr("content",_47.content.value);
+_45.appendChild(_49.domNode);
+this.setFieldValidity("content",true);
+}
+},_displaySections:function(){
+dojo.style(this.entryTitleRow,"display","none");
+dojo.style(this.entryAuthorRow,"display","none");
+dojo.style(this.entryContributorRow,"display","none");
+dojo.style(this.entrySummaryRow,"display","none");
+dojo.style(this.entryContentRow,"display","none");
+dojo.style(this.entryIdRow,"display","none");
+dojo.style(this.entryUpdatedRow,"display","none");
+for(var i in this._displayEntrySections){
+var _4b=this._displayEntrySections[i].toLowerCase();
+if(_4b==="title"&&this.isFieldValid("title")){
+dojo.style(this.entryTitleRow,"display","");
+}
+if(_4b==="authors"&&this.isFieldValid("authors")){
+dojo.style(this.entryAuthorRow,"display","");
+}
+if(_4b==="contributors"&&this.isFieldValid("contributors")){
+dojo.style(this.entryContributorRow,"display","");
+}
+if(_4b==="summary"&&this.isFieldValid("summary")){
+dojo.style(this.entrySummaryRow,"display","");
+}
+if(_4b==="content"&&this.isFieldValid("content")){
+dojo.style(this.entryContentRow,"display","");
+}
+if(_4b==="id"&&this.isFieldValid("id")){
+dojo.style(this.entryIdRow,"display","");
+}
+if(_4b==="updated"&&this.isFieldValid("updated")){
+dojo.style(this.entryUpdatedRow,"display","");
+}
+}
+},setDisplaySections:function(_4c){
+if(_4c!==null){
+this._displayEntrySections=_4c;
+this._displaySections();
+}else{
+this._displayEntrySections=["title","authors","contributors","summary","content","id","updated"];
+}
+},_setDisplaySectionsCheckboxes:function(){
+var _4d=["title","authors","contributors","summary","content","id","updated"];
+for(var i in _4d){
+if(dojo.indexOf(this._displayEntrySections,_4d[i])==-1){
+dojo.style(this["feedEntryCell"+_4d[i]],"display","none");
+}else{
+this["feedEntryCheckBox"+_4d[i].substring(0,1).toUpperCase()+_4d[i].substring(1)].checked=true;
+}
+}
+},_readDisplaySections:function(){
+var _4f=[];
+if(this.feedEntryCheckBoxTitle.checked){
+_4f.push("title");
+}
+if(this.feedEntryCheckBoxAuthors.checked){
+_4f.push("authors");
+}
+if(this.feedEntryCheckBoxContributors.checked){
+_4f.push("contributors");
+}
+if(this.feedEntryCheckBoxSummary.checked){
+_4f.push("summary");
+}
+if(this.feedEntryCheckBoxContent.checked){
+_4f.push("content");
+}
+if(this.feedEntryCheckBoxId.checked){
+_4f.push("id");
+}
+if(this.feedEntryCheckBoxUpdated.checked){
+_4f.push("updated");
+}
+this._displayEntrySections=_4f;
+},_toggleCheckbox:function(_50){
+if(_50.checked){
+_50.checked=false;
+}else{
+_50.checked=true;
+}
+this._readDisplaySections();
+this._displaySections();
+},_toggleOptions:function(_51){
+if(this.enableMenu){
+var _52=null;
+var _53;
+var _54;
+if(this._optionButtonDisplayed){
+if(this.enableMenuFade){
+_53=dojo.fadeOut({node:this.entryCheckBoxDisplayOptions,duration:250});
+dojo.connect(_53,"onEnd",this,function(){
+dojo.style(this.entryCheckBoxDisplayOptions,"display","none");
+dojo.style(this.entryCheckBoxRow,"display","");
+dojo.style(this.entryCheckBoxRow2,"display","");
+dojo.fadeIn({node:this.entryCheckBoxRow,duration:250}).play();
+dojo.fadeIn({node:this.entryCheckBoxRow2,duration:250}).play();
+});
+_53.play();
+}else{
+dojo.style(this.entryCheckBoxDisplayOptions,"display","none");
+dojo.style(this.entryCheckBoxRow,"display","");
+dojo.style(this.entryCheckBoxRow2,"display","");
+}
+this._optionButtonDisplayed=false;
+}else{
+if(this.enableMenuFade){
+_53=dojo.fadeOut({node:this.entryCheckBoxRow,duration:250});
+_54=dojo.fadeOut({node:this.entryCheckBoxRow2,duration:250});
+dojo.connect(_53,"onEnd",this,function(){
+dojo.style(this.entryCheckBoxRow,"display","none");
+dojo.style(this.entryCheckBoxRow2,"display","none");
+dojo.style(this.entryCheckBoxDisplayOptions,"display","");
+dojo.fadeIn({node:this.entryCheckBoxDisplayOptions,duration:250}).play();
+});
+_53.play();
+_54.play();
+}else{
+dojo.style(this.entryCheckBoxRow,"display","none");
+dojo.style(this.entryCheckBoxRow2,"display","none");
+dojo.style(this.entryCheckBoxDisplayOptions,"display","");
+}
+this._optionButtonDisplayed=true;
+}
+}
+},_handleEvent:function(_55){
+if(_55.source!=this){
+if(_55.action=="set"&&_55.entry){
+this.setEntry(_55.entry,_55.feed);
+}else{
+if(_55.action=="delete"&&_55.entry&&_55.entry==this._entry){
+this.clear();
+}
+}
+}
+},setFieldValidity:function(_56,_57){
+if(_56){
+var _58=_56.toLowerCase();
+this._validEntryFields[_56]=_57;
+}
+},isFieldValid:function(_59){
+return this._validEntryFields[_59.toLowerCase()];
+},getEntry:function(){
+return this._entry;
+},getFeed:function(){
+return this._feed;
+},destroy:function(){
+this.clear();
+dojo.forEach(this._subscriptions,dojo.unsubscribe);
+}});
+dojo.declare("dojox.atom.widget.EntryHeader",[dijit._Widget,dijit._Templated,dijit._Container],{title:"",templateString:"<span dojoAttachPoint=\"entryHeaderNode\" class=\"entryHeaderNode\"></span>\n",postCreate:function(){
+this.setListHeader();
+},setListHeader:function(_5a){
+this.clear();
+if(_5a){
+this.title=_5a;
+}
+var _5b=document.createTextNode(this.title);
+this.entryHeaderNode.appendChild(_5b);
+},clear:function(){
+this.destroyDescendants();
+if(this.entryHeaderNode){
+for(var i=0;i<this.entryHeaderNode.childNodes.length;i++){
+this.entryHeaderNode.removeChild(this.entryHeaderNode.childNodes[i]);
+}
+}
+},destroy:function(){
+this.clear();
+}});
+}
diff --git a/dojox/atom/widget/FeedViewer.js b/dojox/atom/widget/FeedViewer.js
new file mode 100644
index 0000000..707df1b
--- /dev/null
+++ b/dojox/atom/widget/FeedViewer.js
@@ -0,0 +1,410 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.atom.widget.FeedViewer"]){
+dojo._hasResource["dojox.atom.widget.FeedViewer"]=true;
+dojo.provide("dojox.atom.widget.FeedViewer");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dijit._Container");
+dojo.require("dojox.atom.io.Connection");
+dojo.requireLocalization("dojox.atom.widget","FeedViewerEntry",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.experimental("dojox.atom.widget.FeedViewer");
+dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget,dijit._Templated,dijit._Container],{feedViewerTableBody:null,feedViewerTable:null,entrySelectionTopic:"",url:"",xmethod:false,localSaveOnly:false,templateString:"<div class=\"feedViewerContainer\" dojoAttachPoint=\"feedViewerContainerNode\">\n\t<table cellspacing=\"0\" cellpadding=\"0\" class=\"feedViewerTable\">\n\t\t<tbody dojoAttachPoint=\"feedViewerTableBody\" class=\"feedViewerTableBody\">\n\t\t</tbody>\n\t</table>\n</div>\n [...]
+this._includeFilters=[];
+if(this.entrySelectionTopic!==""){
+this._subscriptions=[dojo.subscribe(this.entrySelectionTopic,this,"_handleEvent")];
+}
+this.atomIO=new dojox.atom.io.Connection();
+this.childWidgets=[];
+},startup:function(){
+this.containerNode=this.feedViewerTableBody;
+var _1=this.getDescendants();
+for(var i in _1){
+var _3=_1[i];
+if(_3&&_3.isFilter){
+this._includeFilters.push(new dojox.atom.widget.FeedViewer.CategoryIncludeFilter(_3.scheme,_3.term,_3.label));
+_3.destroy();
+}
+}
+if(this.url!==""){
+this.setFeedFromUrl(this.url);
+}
+},clear:function(){
+this.destroyDescendants();
+},setFeedFromUrl:function(_4){
+if(_4!==""){
+if(this._isRelativeURL(_4)){
+var _5="";
+if(_4.charAt(0)!=="/"){
+_5=this._calculateBaseURL(window.location.href,true);
+}else{
+_5=this._calculateBaseURL(window.location.href,false);
+}
+this.url=_5+_4;
+}
+this.atomIO.getFeed(_4,dojo.hitch(this,this.setFeed));
+}
+},setFeed:function(_6){
+this._feed=_6;
+this.clear();
+var _7=function(a,b){
+var _a=this._displayDateForEntry(a);
+var _b=this._displayDateForEntry(b);
+if(_a>_b){
+return -1;
+}
+if(_a<_b){
+return 1;
+}
+return 0;
+};
+var _c=function(_d){
+var _e=_d.split(",");
+_e.pop();
+return _e.join(",");
+};
+var _f=_6.entries.sort(dojo.hitch(this,_7));
+if(_6){
+var _10=null;
+for(var i=0;i<_f.length;i++){
+var _12=_f[i];
+if(this._isFilterAccepted(_12)){
+var _13=this._displayDateForEntry(_12);
+var _14="";
+if(_13!==null){
+_14=_c(_13.toLocaleString());
+if(_14===""){
+_14=""+(_13.getMonth()+1)+"/"+_13.getDate()+"/"+_13.getFullYear();
+}
+}
+if((_10===null)||(_10!=_14)){
+this.appendGrouping(_14);
+_10=_14;
+}
+this.appendEntry(_12);
+}
+}
+}
+},_displayDateForEntry:function(_15){
+if(_15.updated){
+return _15.updated;
+}
+if(_15.modified){
+return _15.modified;
+}
+if(_15.issued){
+return _15.issued;
+}
+return new Date();
+},appendGrouping:function(_16){
+var _17=new dojox.atom.widget.FeedViewerGrouping({});
+_17.setText(_16);
+this.addChild(_17);
+this.childWidgets.push(_17);
+},appendEntry:function(_18){
+var _19=new dojox.atom.widget.FeedViewerEntry({"xmethod":this.xmethod});
+_19.setTitle(_18.title.value);
+_19.setTime(this._displayDateForEntry(_18).toLocaleTimeString());
+_19.entrySelectionTopic=this.entrySelectionTopic;
+_19.feed=this;
+this.addChild(_19);
+this.childWidgets.push(_19);
+this.connect(_19,"onClick","_rowSelected");
+_18.domNode=_19.entryNode;
+_18._entryWidget=_19;
+_19.entry=_18;
+},deleteEntry:function(_1a){
+if(!this.localSaveOnly){
+this.atomIO.deleteEntry(_1a.entry,dojo.hitch(this,this._removeEntry,_1a),null,this.xmethod);
+}else{
+this._removeEntry(_1a,true);
+}
+dojo.publish(this.entrySelectionTopic,[{action:"delete",source:this,entry:_1a.entry}]);
+},_removeEntry:function(_1b,_1c){
+if(_1c){
+var idx=dojo.indexOf(this.childWidgets,_1b);
+var _1e=this.childWidgets[idx-1];
+var _1f=this.childWidgets[idx+1];
+if(_1e.declaredClass==="dojox.atom.widget.FeedViewerGrouping"&&(_1f===undefined||_1f.declaredClass==="dojox.atom.widget.FeedViewerGrouping")){
+_1e.destroy();
+}
+_1b.destroy();
+}else{
+}
+},_rowSelected:function(evt){
+var _21=evt.target;
+while(_21){
+if(_21.attributes){
+var _22=_21.attributes.getNamedItem("widgetid");
+if(_22&&_22.value.indexOf("FeedViewerEntry")!=-1){
+break;
+}
+}
+_21=_21.parentNode;
+}
+for(var i=0;i<this._feed.entries.length;i++){
+var _24=this._feed.entries[i];
+if((_21===_24.domNode)&&(this._currentSelection!==_24)){
+dojo.addClass(_24.domNode,"feedViewerEntrySelected");
+dojo.removeClass(_24._entryWidget.timeNode,"feedViewerEntryUpdated");
+dojo.addClass(_24._entryWidget.timeNode,"feedViewerEntryUpdatedSelected");
+this.onEntrySelected(_24);
+if(this.entrySelectionTopic!==""){
+dojo.publish(this.entrySelectionTopic,[{action:"set",source:this,feed:this._feed,entry:_24}]);
+}
+if(this._isEditable(_24)){
+_24._entryWidget.enableDelete();
+}
+this._deselectCurrentSelection();
+this._currentSelection=_24;
+break;
+}else{
+if((_21===_24.domNode)&&(this._currentSelection===_24)){
+dojo.publish(this.entrySelectionTopic,[{action:"delete",source:this,entry:_24}]);
+this._deselectCurrentSelection();
+break;
+}
+}
+}
+},_deselectCurrentSelection:function(){
+if(this._currentSelection){
+dojo.addClass(this._currentSelection._entryWidget.timeNode,"feedViewerEntryUpdated");
+dojo.removeClass(this._currentSelection.domNode,"feedViewerEntrySelected");
+dojo.removeClass(this._currentSelection._entryWidget.timeNode,"feedViewerEntryUpdatedSelected");
+this._currentSelection._entryWidget.disableDelete();
+this._currentSelection=null;
+}
+},_isEditable:function(_25){
+var _26=false;
+if(_25&&_25!==null&&_25.links&&_25.links!==null){
+for(var x in _25.links){
+if(_25.links[x].rel&&_25.links[x].rel=="edit"){
+_26=true;
+break;
+}
+}
+}
+return _26;
+},onEntrySelected:function(_28){
+},_isRelativeURL:function(url){
+function _2a(url){
+var _2c=false;
+if(url.indexOf("file://")===0){
+_2c=true;
+}
+return _2c;
+};
+function _2d(url){
+var _2f=false;
+if(url.indexOf("http://")===0){
+_2f=true;
+}
+return _2f;
+};
+var _30=false;
+if(url!==null){
+if(!_2a(url)&&!_2d(url)){
+_30=true;
+}
+}
+return _30;
+},_calculateBaseURL:function(_31,_32){
+var _33=null;
+if(_31!==null){
+var _34=_31.indexOf("?");
+if(_34!=-1){
+_31=_31.substring(0,_34);
+}
+if(_32){
+_34=_31.lastIndexOf("/");
+if((_34>0)&&(_34<_31.length)&&(_34!==(_31.length-1))){
+_33=_31.substring(0,(_34+1));
+}else{
+_33=_31;
+}
+}else{
+_34=_31.indexOf("://");
+if(_34>0){
+_34=_34+3;
+var _35=_31.substring(0,_34);
+var _36=_31.substring(_34,_31.length);
+_34=_36.indexOf("/");
+if((_34<_36.length)&&(_34>0)){
+_33=_35+_36.substring(0,_34);
+}else{
+_33=_35+_36;
+}
+}
+}
+}
+return _33;
+},_isFilterAccepted:function(_37){
+var _38=false;
+if(this._includeFilters&&(this._includeFilters.length>0)){
+for(var i=0;i<this._includeFilters.length;i++){
+var _3a=this._includeFilters[i];
+if(_3a.match(_37)){
+_38=true;
+break;
+}
+}
+}else{
+_38=true;
+}
+return _38;
+},addCategoryIncludeFilter:function(_3b){
+if(_3b){
+var _3c=_3b.scheme;
+var _3d=_3b.term;
+var _3e=_3b.label;
+var _3f=true;
+if(!_3c){
+_3c=null;
+}
+if(!_3d){
+_3c=null;
+}
+if(!_3e){
+_3c=null;
+}
+if(this._includeFilters&&this._includeFilters.length>0){
+for(var i=0;i<this._includeFilters.length;i++){
+var _41=this._includeFilters[i];
+if((_41.term===_3d)&&(_41.scheme===_3c)&&(_41.label===_3e)){
+_3f=false;
+break;
+}
+}
+}
+if(_3f){
+this._includeFilters.push(dojox.atom.widget.FeedViewer.CategoryIncludeFilter(_3c,_3d,_3e));
+}
+}
+},removeCategoryIncludeFilter:function(_42){
+if(_42){
+var _43=_42.scheme;
+var _44=_42.term;
+var _45=_42.label;
+if(!_43){
+_43=null;
+}
+if(!_44){
+_43=null;
+}
+if(!_45){
+_43=null;
+}
+var _46=[];
+if(this._includeFilters&&this._includeFilters.length>0){
+for(var i=0;i<this._includeFilters.length;i++){
+var _48=this._includeFilters[i];
+if(!((_48.term===_44)&&(_48.scheme===_43)&&(_48.label===_45))){
+_46.push(_48);
+}
+}
+this._includeFilters=_46;
+}
+}
+},_handleEvent:function(_49){
+if(_49.source!=this){
+if(_49.action=="update"&&_49.entry){
+var evt=_49;
+if(!this.localSaveOnly){
+this.atomIO.updateEntry(evt.entry,dojo.hitch(evt.source,evt.callback),null,true);
+}
+this._currentSelection._entryWidget.setTime(this._displayDateForEntry(evt.entry).toLocaleTimeString());
+this._currentSelection._entryWidget.setTitle(evt.entry.title.value);
+}else{
+if(_49.action=="post"&&_49.entry){
+if(!this.localSaveOnly){
+this.atomIO.addEntry(_49.entry,this.url,dojo.hitch(this,this._addEntry));
+}else{
+this._addEntry(_49.entry);
+}
+}
+}
+}
+},_addEntry:function(_4b){
+this._feed.addEntry(_4b);
+this.setFeed(this._feed);
+dojo.publish(this.entrySelectionTopic,[{action:"set",source:this,feed:this._feed,entry:_4b}]);
+},destroy:function(){
+this.clear();
+dojo.forEach(this._subscriptions,dojo.unsubscribe);
+}});
+dojo.declare("dojox.atom.widget.FeedViewerEntry",[dijit._Widget,dijit._Templated],{templateString:"<tr class=\"feedViewerEntry\" dojoAttachPoint=\"entryNode\" dojoAttachEvent=\"onclick:onClick\">\n    <td class=\"feedViewerEntryUpdated\" dojoAttachPoint=\"timeNode\">\n    </td>\n    <td>\n        <table border=\"0\" width=\"100%\" dojoAttachPoint=\"titleRow\">\n            <tr padding=\"0\" border=\"0\">\n                <td class=\"feedViewerEntryTitle\" dojoAttachPoint=\"titleNode\">\n [...]
+var _4c=dojo.i18n.getLocalization("dojox.atom.widget","FeedViewerEntry");
+this.deleteButton.innerHTML=_4c.deleteButton;
+},setTitle:function(_4d){
+if(this.titleNode.lastChild){
+this.titleNode.removeChild(this.titleNode.lastChild);
+}
+var _4e=document.createElement("div");
+_4e.innerHTML=_4d;
+this.titleNode.appendChild(_4e);
+},setTime:function(_4f){
+if(this.timeNode.lastChild){
+this.timeNode.removeChild(this.timeNode.lastChild);
+}
+var _50=document.createTextNode(_4f);
+this.timeNode.appendChild(_50);
+},enableDelete:function(){
+if(this.deleteButton!==null){
+this.deleteButton.style.display="inline";
+}
+},disableDelete:function(){
+if(this.deleteButton!==null){
+this.deleteButton.style.display="none";
+}
+},deleteEntry:function(_51){
+_51.preventDefault();
+_51.stopPropagation();
+this.feed.deleteEntry(this);
+},onClick:function(e){
+}});
+dojo.declare("dojox.atom.widget.FeedViewerGrouping",[dijit._Widget,dijit._Templated],{templateString:"<tr dojoAttachPoint=\"groupingNode\" class=\"feedViewerGrouping\">\n\t<td colspan=\"2\" dojoAttachPoint=\"titleNode\" class=\"feedViewerGroupingTitle\">\n\t</td>\n</tr>\n",groupingNode:null,titleNode:null,setText:function(_53){
+if(this.titleNode.lastChild){
+this.titleNode.removeChild(this.titleNode.lastChild);
+}
+var _54=document.createTextNode(_53);
+this.titleNode.appendChild(_54);
+}});
+dojo.declare("dojox.atom.widget.AtomEntryCategoryFilter",[dijit._Widget,dijit._Templated],{scheme:"",term:"",label:"",isFilter:true});
+dojo.declare("dojox.atom.widget.FeedViewer.CategoryIncludeFilter",null,{constructor:function(_55,_56,_57){
+this.scheme=_55;
+this.term=_56;
+this.label=_57;
+},match:function(_58){
+var _59=false;
+if(_58!==null){
+var _5a=_58.categories;
+if(_5a!==null){
+for(var i=0;i<_5a.length;i++){
+var _5c=_5a[i];
+if(this.scheme!==""){
+if(this.scheme!==_5c.scheme){
+break;
+}
+}
+if(this.term!==""){
+if(this.term!==_5c.term){
+break;
+}
+}
+if(this.label!==""){
+if(this.label!==_5c.label){
+break;
+}
+}
+_59=true;
+}
+}
+}
+return _59;
+}});
+}
diff --git a/dojox/atom/widget/nls/FeedEntryEditor.js b/dojox/atom/widget/nls/FeedEntryEditor.js
new file mode 100644
index 0000000..f7f1558
--- /dev/null
+++ b/dojox/atom/widget/nls/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[edit]","save":"[save]","cancel":"[cancel]","doNew":"[new]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/FeedEntryViewer.js b/dojox/atom/widget/nls/FeedEntryViewer.js
new file mode 100644
index 0000000..b294695
--- /dev/null
+++ b/dojox/atom/widget/nls/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[close]","title":"Title","authors":"Authors","summary":"Summary","content":"Content","contributors":"Contributors","updated":"Updated","displayOptions":"[display options]","id":"ID"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/FeedViewerEntry.js b/dojox/atom/widget/nls/FeedViewerEntry.js
new file mode 100644
index 0000000..6c686ff
--- /dev/null
+++ b/dojox/atom/widget/nls/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Delete]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/PeopleEditor.js b/dojox/atom/widget/nls/PeopleEditor.js
new file mode 100644
index 0000000..0f56092
--- /dev/null
+++ b/dojox/atom/widget/nls/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Add","addAuthor":"Add Author","addContributor":"Add Contributor"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ar/FeedEntryEditor.js b/dojox/atom/widget/nls/ar/FeedEntryEditor.js
new file mode 100644
index 0000000..e6c013f
--- /dev/null
+++ b/dojox/atom/widget/nls/ar/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[تحرير]","save":"[حفظ]","cancel":"[الغاء]","doNew":"[جديد]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ar/FeedEntryViewer.js b/dojox/atom/widget/nls/ar/FeedEntryViewer.js
new file mode 100644
index 0000000..fdaea31
--- /dev/null
+++ b/dojox/atom/widget/nls/ar/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[اغلاق]","title":"العنوان","authors":"المؤلفين","summary":"الملخص","content":"محتويات","contributors":"المساهمين","updated":"تعديل في","displayOptions":"[اختيارات العرض]","id":"الكود"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ar/FeedViewerEntry.js b/dojox/atom/widget/nls/ar/FeedViewerEntry.js
new file mode 100644
index 0000000..3f7a4bd
--- /dev/null
+++ b/dojox/atom/widget/nls/ar/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[حذف]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ar/PeopleEditor.js b/dojox/atom/widget/nls/ar/PeopleEditor.js
new file mode 100644
index 0000000..dd79bf3
--- /dev/null
+++ b/dojox/atom/widget/nls/ar/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"اضافة","addAuthor":"اضافة مؤلف","addContributor":"اضافة مشارك "})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ca/FeedEntryEditor.js b/dojox/atom/widget/nls/ca/FeedEntryEditor.js
new file mode 100644
index 0000000..961d3bc
--- /dev/null
+++ b/dojox/atom/widget/nls/ca/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[edita]","save":"[desa]","cancel":"[cancel·la]","doNew":"[nou]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ca/FeedEntryViewer.js b/dojox/atom/widget/nls/ca/FeedEntryViewer.js
new file mode 100644
index 0000000..7f546a9
--- /dev/null
+++ b/dojox/atom/widget/nls/ca/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[tanca]","title":"Títol","authors":"Autors","summary":"Resum","content":"Contingut","contributors":"Col·laboradors","updated":"Actualitzat","displayOptions":"[opcions de visualització]","id":"ID"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ca/FeedViewerEntry.js b/dojox/atom/widget/nls/ca/FeedViewerEntry.js
new file mode 100644
index 0000000..169d596
--- /dev/null
+++ b/dojox/atom/widget/nls/ca/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Suprimeix]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ca/PeopleEditor.js b/dojox/atom/widget/nls/ca/PeopleEditor.js
new file mode 100644
index 0000000..ca16393
--- /dev/null
+++ b/dojox/atom/widget/nls/ca/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Afegeix","addAuthor":"Afegeix un autor","addContributor":"Afegeix un col·laborador"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/cs/FeedEntryEditor.js b/dojox/atom/widget/nls/cs/FeedEntryEditor.js
new file mode 100644
index 0000000..45f2997
--- /dev/null
+++ b/dojox/atom/widget/nls/cs/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[upravit]","save":"[uložit]","cancel":"[storno]","doNew":"[nové]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/cs/FeedEntryViewer.js b/dojox/atom/widget/nls/cs/FeedEntryViewer.js
new file mode 100644
index 0000000..98e8851
--- /dev/null
+++ b/dojox/atom/widget/nls/cs/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[zavřít]","title":"Název","authors":"Autoři","summary":"Souhrn","content":"Obsah","contributors":"Přispěvatelé","updated":"Aktualizováno","displayOptions":"[volby zobrazení]","id":"ID"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/cs/FeedViewerEntry.js b/dojox/atom/widget/nls/cs/FeedViewerEntry.js
new file mode 100644
index 0000000..af02c93
--- /dev/null
+++ b/dojox/atom/widget/nls/cs/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Odstranit]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/cs/PeopleEditor.js b/dojox/atom/widget/nls/cs/PeopleEditor.js
new file mode 100644
index 0000000..d437043
--- /dev/null
+++ b/dojox/atom/widget/nls/cs/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Přidat","addAuthor":"Přidat autora","addContributor":"Přidat přispěvatele"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/da/FeedEntryEditor.js b/dojox/atom/widget/nls/da/FeedEntryEditor.js
new file mode 100644
index 0000000..0acccc0
--- /dev/null
+++ b/dojox/atom/widget/nls/da/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[redigér]","save":"[gem]","cancel":"[annullér]","doNew":"[ny]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/da/FeedEntryViewer.js b/dojox/atom/widget/nls/da/FeedEntryViewer.js
new file mode 100644
index 0000000..932e79b
--- /dev/null
+++ b/dojox/atom/widget/nls/da/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[luk]","title":"Titel","authors":"Forfattere","summary":"Summary","content":"Indhold","contributors":"Bidragydere","updated":"Opdateret","displayOptions":"[fremvisningsvalg]","id":"Id"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/da/FeedViewerEntry.js b/dojox/atom/widget/nls/da/FeedViewerEntry.js
new file mode 100644
index 0000000..8a161c2
--- /dev/null
+++ b/dojox/atom/widget/nls/da/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Slet]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/da/PeopleEditor.js b/dojox/atom/widget/nls/da/PeopleEditor.js
new file mode 100644
index 0000000..43aaa23
--- /dev/null
+++ b/dojox/atom/widget/nls/da/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Tilføj","addAuthor":"Tilføj forfatter","addContributor":"Tilføj bidragyder"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/de/FeedEntryEditor.js b/dojox/atom/widget/nls/de/FeedEntryEditor.js
new file mode 100644
index 0000000..c5a85ae
--- /dev/null
+++ b/dojox/atom/widget/nls/de/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[Bearbeiten]","save":"[Speichern]","cancel":"[Abbrechen]","doNew":"[Neu]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/de/FeedEntryViewer.js b/dojox/atom/widget/nls/de/FeedEntryViewer.js
new file mode 100644
index 0000000..68976fb
--- /dev/null
+++ b/dojox/atom/widget/nls/de/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[Schließen]","title":"Titel","authors":"Autoren","summary":"Zusammenfassung","content":"Inhalt","contributors":"Mitwirkende","updated":"Aktualisiert","displayOptions":"[Anzeigeoptionen]","id":"ID"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/de/FeedViewerEntry.js b/dojox/atom/widget/nls/de/FeedViewerEntry.js
new file mode 100644
index 0000000..4bc5c03
--- /dev/null
+++ b/dojox/atom/widget/nls/de/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Löschen]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/de/PeopleEditor.js b/dojox/atom/widget/nls/de/PeopleEditor.js
new file mode 100644
index 0000000..fdaff2f
--- /dev/null
+++ b/dojox/atom/widget/nls/de/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Hinzufügen","addAuthor":"Autor hinzufügen","addContributor":"Mitwirkenden hinzufügen"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/el/FeedEntryEditor.js b/dojox/atom/widget/nls/el/FeedEntryEditor.js
new file mode 100644
index 0000000..3cf776b
--- /dev/null
+++ b/dojox/atom/widget/nls/el/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[τροποποίηση]","save":"[αποθήκευση]","cancel":"[ακύρωση]","doNew":"[δημιουργία]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/el/FeedEntryViewer.js b/dojox/atom/widget/nls/el/FeedEntryViewer.js
new file mode 100644
index 0000000..45d95c6
--- /dev/null
+++ b/dojox/atom/widget/nls/el/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[κλείσιμο]","title":"Τίτλος","authors":"Συντάκτες","summary":"Περίληψη","content":"Περιεχόμενο","contributors":"Συνεισφέροντες","updated":"Ενημερώθηκε","displayOptions":"[επιλογές παρουσίασης]","id":"Ταυτότητα"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/el/FeedViewerEntry.js b/dojox/atom/widget/nls/el/FeedViewerEntry.js
new file mode 100644
index 0000000..db087e4
--- /dev/null
+++ b/dojox/atom/widget/nls/el/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Διαγραφή]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/el/PeopleEditor.js b/dojox/atom/widget/nls/el/PeopleEditor.js
new file mode 100644
index 0000000..74604b0
--- /dev/null
+++ b/dojox/atom/widget/nls/el/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Προσθήκη","addAuthor":"Προσθήκη συντάκτη","addContributor":"Προσθήκη συνεισφέροντα"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/es/FeedEntryEditor.js b/dojox/atom/widget/nls/es/FeedEntryEditor.js
new file mode 100644
index 0000000..426e7ad
--- /dev/null
+++ b/dojox/atom/widget/nls/es/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[editar]","save":"[guardar]","cancel":"[cancelar]","doNew":"[nuevo]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/es/FeedEntryViewer.js b/dojox/atom/widget/nls/es/FeedEntryViewer.js
new file mode 100644
index 0000000..d0d7a9a
--- /dev/null
+++ b/dojox/atom/widget/nls/es/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[cerrar]","title":"Título","authors":"Autores","summary":"Resumen","content":"Contenido","contributors":"Colaboradores","updated":"Actualizado","displayOptions":"[opciones de visualización]","id":"ID"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/es/FeedViewerEntry.js b/dojox/atom/widget/nls/es/FeedViewerEntry.js
new file mode 100644
index 0000000..c33cee5
--- /dev/null
+++ b/dojox/atom/widget/nls/es/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Suprimir]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/es/PeopleEditor.js b/dojox/atom/widget/nls/es/PeopleEditor.js
new file mode 100644
index 0000000..6ed1de3
--- /dev/null
+++ b/dojox/atom/widget/nls/es/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Añadir","addAuthor":"Añadir autor","addContributor":"Añadir colaborador"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/fi/FeedEntryEditor.js b/dojox/atom/widget/nls/fi/FeedEntryEditor.js
new file mode 100644
index 0000000..0bc76af
--- /dev/null
+++ b/dojox/atom/widget/nls/fi/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[muokkaa]","save":"[tallenna]","cancel":"[peruuta]","doNew":"[uusi]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/fi/FeedEntryViewer.js b/dojox/atom/widget/nls/fi/FeedEntryViewer.js
new file mode 100644
index 0000000..7e08399
--- /dev/null
+++ b/dojox/atom/widget/nls/fi/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[sulje]","title":"Otsikko","authors":"Tekijät","summary":"Yhteenveto","content":"Sisältö","contributors":"Osallistujat","updated":"Päivitetty","displayOptions":"[näyttöasetukset]","id":"Tunnus"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/fi/FeedViewerEntry.js b/dojox/atom/widget/nls/fi/FeedViewerEntry.js
new file mode 100644
index 0000000..832e2c4
--- /dev/null
+++ b/dojox/atom/widget/nls/fi/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Poista]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/fi/PeopleEditor.js b/dojox/atom/widget/nls/fi/PeopleEditor.js
new file mode 100644
index 0000000..a436742
--- /dev/null
+++ b/dojox/atom/widget/nls/fi/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Lisää","addAuthor":"Lisää tekijä","addContributor":"Lisää osallistuja"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/fr/FeedEntryEditor.js b/dojox/atom/widget/nls/fr/FeedEntryEditor.js
new file mode 100644
index 0000000..ff19654
--- /dev/null
+++ b/dojox/atom/widget/nls/fr/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[éditer]","save":"[sauvegarder]","cancel":"[annuler]","doNew":"[nouveau]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/fr/FeedEntryViewer.js b/dojox/atom/widget/nls/fr/FeedEntryViewer.js
new file mode 100644
index 0000000..93c0cbc
--- /dev/null
+++ b/dojox/atom/widget/nls/fr/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[fermer]","title":"Titre","authors":"Auteurs","summary":"Récapitulatif","content":"Contenu","contributors":"Collaborateurs","updated":"Mis à jour","displayOptions":"[options d'affichage]","id":"ID"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/fr/FeedViewerEntry.js b/dojox/atom/widget/nls/fr/FeedViewerEntry.js
new file mode 100644
index 0000000..8003cbb
--- /dev/null
+++ b/dojox/atom/widget/nls/fr/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Supprimer]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/fr/PeopleEditor.js b/dojox/atom/widget/nls/fr/PeopleEditor.js
new file mode 100644
index 0000000..5b7d866
--- /dev/null
+++ b/dojox/atom/widget/nls/fr/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Ajouter","addAuthor":"Ajouter un auteur","addContributor":"Ajouter un collaborateur"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/he/FeedEntryEditor.js b/dojox/atom/widget/nls/he/FeedEntryEditor.js
new file mode 100644
index 0000000..569ea3b
--- /dev/null
+++ b/dojox/atom/widget/nls/he/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[עריכה]","save":"[שמירה]","cancel":"[ביטול]","doNew":"[חדש]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/he/FeedEntryViewer.js b/dojox/atom/widget/nls/he/FeedEntryViewer.js
new file mode 100644
index 0000000..3c60372
--- /dev/null
+++ b/dojox/atom/widget/nls/he/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[סגירה]","title":"כותרת","authors":"מחברים","summary":"סיכום","content":"תוכן","contributors":"תורמים","updated":"עודכן","displayOptions":"[הצגת אפשרויות]","id":"זיהוי"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/he/FeedViewerEntry.js b/dojox/atom/widget/nls/he/FeedViewerEntry.js
new file mode 100644
index 0000000..4bb6ba0
--- /dev/null
+++ b/dojox/atom/widget/nls/he/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[מחיקה]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/he/PeopleEditor.js b/dojox/atom/widget/nls/he/PeopleEditor.js
new file mode 100644
index 0000000..00120d8
--- /dev/null
+++ b/dojox/atom/widget/nls/he/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"הוספה","addAuthor":"הוספת מחבר","addContributor":"הוספת תורם"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/hu/FeedEntryEditor.js b/dojox/atom/widget/nls/hu/FeedEntryEditor.js
new file mode 100644
index 0000000..9686e11
--- /dev/null
+++ b/dojox/atom/widget/nls/hu/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[szerkesztés]","save":"[mentés]","cancel":"[mégse]","doNew":"[új]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/hu/FeedEntryViewer.js b/dojox/atom/widget/nls/hu/FeedEntryViewer.js
new file mode 100644
index 0000000..c0f4853
--- /dev/null
+++ b/dojox/atom/widget/nls/hu/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[bezárás]","title":"Cím","authors":"Szerzők","summary":"Összegzés","content":"Tartalom","contributors":"Közreműködők","updated":"Frissítve","displayOptions":"[megjelenítési beállítások]","id":"Azonosító"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/hu/FeedViewerEntry.js b/dojox/atom/widget/nls/hu/FeedViewerEntry.js
new file mode 100644
index 0000000..a826114
--- /dev/null
+++ b/dojox/atom/widget/nls/hu/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Törlés]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/hu/PeopleEditor.js b/dojox/atom/widget/nls/hu/PeopleEditor.js
new file mode 100644
index 0000000..6ffe97c
--- /dev/null
+++ b/dojox/atom/widget/nls/hu/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Hozzáadás","addAuthor":"Szerző hozzáadása","addContributor":"Közreműködő hozzáadása"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/it/FeedEntryEditor.js b/dojox/atom/widget/nls/it/FeedEntryEditor.js
new file mode 100644
index 0000000..408de78
--- /dev/null
+++ b/dojox/atom/widget/nls/it/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[modifica]","save":"[salva]","cancel":"[annulla]","doNew":"[nuovo]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/it/FeedEntryViewer.js b/dojox/atom/widget/nls/it/FeedEntryViewer.js
new file mode 100644
index 0000000..3cc33ac
--- /dev/null
+++ b/dojox/atom/widget/nls/it/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[chiudi]","title":"Titolo","authors":"Autori","summary":"Riepilogo","content":"Indice","contributors":"Collaboratori","updated":"Aggiornato","displayOptions":"[visualizza opzioni]","id":"ID"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/it/FeedViewerEntry.js b/dojox/atom/widget/nls/it/FeedViewerEntry.js
new file mode 100644
index 0000000..3a0fa24
--- /dev/null
+++ b/dojox/atom/widget/nls/it/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Cancella]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/it/PeopleEditor.js b/dojox/atom/widget/nls/it/PeopleEditor.js
new file mode 100644
index 0000000..82b4f5b
--- /dev/null
+++ b/dojox/atom/widget/nls/it/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Aggiungi","addAuthor":"Aggiungi autore","addContributor":"Aggiungi collaboratori"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ja/FeedEntryEditor.js b/dojox/atom/widget/nls/ja/FeedEntryEditor.js
new file mode 100644
index 0000000..ca8986a
--- /dev/null
+++ b/dojox/atom/widget/nls/ja/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[編集]","save":"[保存]","cancel":"[キャンセル]","doNew":"[新規]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ja/FeedEntryViewer.js b/dojox/atom/widget/nls/ja/FeedEntryViewer.js
new file mode 100644
index 0000000..b935c62
--- /dev/null
+++ b/dojox/atom/widget/nls/ja/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[閉じる]","title":"タイトル","authors":"作成者","summary":"要約","content":"内容","contributors":"貢献者","updated":"更新","displayOptions":"[表示オプション]","id":"ID"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ja/FeedViewerEntry.js b/dojox/atom/widget/nls/ja/FeedViewerEntry.js
new file mode 100644
index 0000000..6dcdea0
--- /dev/null
+++ b/dojox/atom/widget/nls/ja/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[削除]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ja/PeopleEditor.js b/dojox/atom/widget/nls/ja/PeopleEditor.js
new file mode 100644
index 0000000..203fc3f
--- /dev/null
+++ b/dojox/atom/widget/nls/ja/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"追加","addAuthor":"作成者の追加","addContributor":"貢献者の追加"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ko/FeedEntryEditor.js b/dojox/atom/widget/nls/ko/FeedEntryEditor.js
new file mode 100644
index 0000000..227d37f
--- /dev/null
+++ b/dojox/atom/widget/nls/ko/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[편집]","save":"[저장]","cancel":"[취소]","doNew":"[새로 작성]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ko/FeedEntryViewer.js b/dojox/atom/widget/nls/ko/FeedEntryViewer.js
new file mode 100644
index 0000000..39caa6d
--- /dev/null
+++ b/dojox/atom/widget/nls/ko/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[닫기]","title":"제목","authors":"작성자","summary":"요약","content":"컨텐츠","contributors":"속성","updated":"갱신","displayOptions":"[옵션 표시]","id":"ID"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ko/FeedViewerEntry.js b/dojox/atom/widget/nls/ko/FeedViewerEntry.js
new file mode 100644
index 0000000..98b1b3f
--- /dev/null
+++ b/dojox/atom/widget/nls/ko/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[삭제]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ko/PeopleEditor.js b/dojox/atom/widget/nls/ko/PeopleEditor.js
new file mode 100644
index 0000000..ac52411
--- /dev/null
+++ b/dojox/atom/widget/nls/ko/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"추가","addAuthor":"작성자 추가","addContributor":"제공자 추가"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/nb/FeedEntryEditor.js b/dojox/atom/widget/nls/nb/FeedEntryEditor.js
new file mode 100644
index 0000000..3b482ed
--- /dev/null
+++ b/dojox/atom/widget/nls/nb/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[rediger]","save":"[lagre]","cancel":"[avbryt]","doNew":"[ny(tt)]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/nb/FeedEntryViewer.js b/dojox/atom/widget/nls/nb/FeedEntryViewer.js
new file mode 100644
index 0000000..f888d28
--- /dev/null
+++ b/dojox/atom/widget/nls/nb/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[lukk]","title":"Tittel","authors":"Forfattere","summary":"Sammendrag","content":"Innhold","contributors":"Bidragsytere","updated":"Oppdatert","displayOptions":"[visningsalternativer]","id":"ID"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/nb/FeedViewerEntry.js b/dojox/atom/widget/nls/nb/FeedViewerEntry.js
new file mode 100644
index 0000000..8e38e59
--- /dev/null
+++ b/dojox/atom/widget/nls/nb/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Slett]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/nb/PeopleEditor.js b/dojox/atom/widget/nls/nb/PeopleEditor.js
new file mode 100644
index 0000000..05ac102
--- /dev/null
+++ b/dojox/atom/widget/nls/nb/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Legg til","addAuthor":"Legg til forfatter","addContributor":"Legg til bidragsyter"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/nl/FeedEntryEditor.js b/dojox/atom/widget/nls/nl/FeedEntryEditor.js
new file mode 100644
index 0000000..0714571
--- /dev/null
+++ b/dojox/atom/widget/nls/nl/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[bewerken]","save":"[opslaan]","cancel":"[annuleren]","doNew":"[nieuw]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/nl/FeedEntryViewer.js b/dojox/atom/widget/nls/nl/FeedEntryViewer.js
new file mode 100644
index 0000000..294f590
--- /dev/null
+++ b/dojox/atom/widget/nls/nl/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[sluiten]","title":"Titel","authors":"Auteurs","summary":"Overzicht","content":"Content","contributors":"Deelnemers","updated":"Bijgewerkt","displayOptions":"[weergaveopties]","id":"ID"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/nl/FeedViewerEntry.js b/dojox/atom/widget/nls/nl/FeedViewerEntry.js
new file mode 100644
index 0000000..31a12d7
--- /dev/null
+++ b/dojox/atom/widget/nls/nl/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Wissen]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/nl/PeopleEditor.js b/dojox/atom/widget/nls/nl/PeopleEditor.js
new file mode 100644
index 0000000..e8dd783
--- /dev/null
+++ b/dojox/atom/widget/nls/nl/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Toevoegen","addAuthor":"Auteur toevoegen","addContributor":"Deelnemer toevoegen"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/pl/FeedEntryEditor.js b/dojox/atom/widget/nls/pl/FeedEntryEditor.js
new file mode 100644
index 0000000..2fc51b5
--- /dev/null
+++ b/dojox/atom/widget/nls/pl/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[Edytuj]","save":"[Zapisz]","cancel":"[Anuluj]","doNew":"[Nowy]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/pl/FeedEntryViewer.js b/dojox/atom/widget/nls/pl/FeedEntryViewer.js
new file mode 100644
index 0000000..9b52a9c
--- /dev/null
+++ b/dojox/atom/widget/nls/pl/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[Zamknij]","title":"Tytuł","authors":"Autorzy","summary":"Podsumowanie","content":"Treść","contributors":"Kontrybutorzy","updated":"Zaktualizowano","displayOptions":"[Opcje wyświetlania]","id":"Identyfikator"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/pl/FeedViewerEntry.js b/dojox/atom/widget/nls/pl/FeedViewerEntry.js
new file mode 100644
index 0000000..b6a347e
--- /dev/null
+++ b/dojox/atom/widget/nls/pl/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Usuń]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/pl/PeopleEditor.js b/dojox/atom/widget/nls/pl/PeopleEditor.js
new file mode 100644
index 0000000..baa45b1
--- /dev/null
+++ b/dojox/atom/widget/nls/pl/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Dodaj","addAuthor":"Dodaj autora","addContributor":"Dodaj kontrybutora"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/pt-pt/FeedEntryEditor.js b/dojox/atom/widget/nls/pt-pt/FeedEntryEditor.js
new file mode 100644
index 0000000..c87f234
--- /dev/null
+++ b/dojox/atom/widget/nls/pt-pt/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[editar]","save":"[guardar]","cancel":"[cancelar]","doNew":"[novo]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/pt-pt/FeedEntryViewer.js b/dojox/atom/widget/nls/pt-pt/FeedEntryViewer.js
new file mode 100644
index 0000000..40b3f60
--- /dev/null
+++ b/dojox/atom/widget/nls/pt-pt/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[fechar]","title":"Título","authors":"Autores","summary":"Resumo","content":"Conteúdo","contributors":"Contribuintes","updated":"Actualizado","displayOptions":"[opções de visualização]","id":"ID"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/pt-pt/FeedViewerEntry.js b/dojox/atom/widget/nls/pt-pt/FeedViewerEntry.js
new file mode 100644
index 0000000..de9f60e
--- /dev/null
+++ b/dojox/atom/widget/nls/pt-pt/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Eliminar]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/pt-pt/PeopleEditor.js b/dojox/atom/widget/nls/pt-pt/PeopleEditor.js
new file mode 100644
index 0000000..e89d433
--- /dev/null
+++ b/dojox/atom/widget/nls/pt-pt/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Adicionar","addAuthor":"Adicionar autor","addContributor":"Adicionar contribuinte"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/pt/FeedEntryEditor.js b/dojox/atom/widget/nls/pt/FeedEntryEditor.js
new file mode 100644
index 0000000..ab9981a
--- /dev/null
+++ b/dojox/atom/widget/nls/pt/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[editar]","save":"[salvar]","cancel":"[cancelar]","doNew":"[novo]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/pt/FeedEntryViewer.js b/dojox/atom/widget/nls/pt/FeedEntryViewer.js
new file mode 100644
index 0000000..bc12eea
--- /dev/null
+++ b/dojox/atom/widget/nls/pt/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[fechar]","title":"Título","authors":"Autores","summary":"Resumo","content":"Conteúdo","contributors":"Contribuidores","updated":"Atualizado","displayOptions":"[exibir opções]","id":"ID"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/pt/FeedViewerEntry.js b/dojox/atom/widget/nls/pt/FeedViewerEntry.js
new file mode 100644
index 0000000..74e0657
--- /dev/null
+++ b/dojox/atom/widget/nls/pt/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Excluir]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/pt/PeopleEditor.js b/dojox/atom/widget/nls/pt/PeopleEditor.js
new file mode 100644
index 0000000..76752ef
--- /dev/null
+++ b/dojox/atom/widget/nls/pt/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Adicionar","addAuthor":"Adicionar Autor","addContributor":"Adicionar Contribuidor"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ru/FeedEntryEditor.js b/dojox/atom/widget/nls/ru/FeedEntryEditor.js
new file mode 100644
index 0000000..c3a9380
--- /dev/null
+++ b/dojox/atom/widget/nls/ru/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[изменить]","save":"[сохранить]","cancel":"[отмена]","doNew":"[создать]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ru/FeedEntryViewer.js b/dojox/atom/widget/nls/ru/FeedEntryViewer.js
new file mode 100644
index 0000000..80bf42f
--- /dev/null
+++ b/dojox/atom/widget/nls/ru/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[закрыть]","title":"Название","authors":"Авторы","summary":"Сводка","content":"Информационное наполнение","contributors":"Участники","updated":"Обновлено","displayOptions":"[показать опции]","id":"ИД"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ru/FeedViewerEntry.js b/dojox/atom/widget/nls/ru/FeedViewerEntry.js
new file mode 100644
index 0000000..39247e2
--- /dev/null
+++ b/dojox/atom/widget/nls/ru/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Удалить]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/ru/PeopleEditor.js b/dojox/atom/widget/nls/ru/PeopleEditor.js
new file mode 100644
index 0000000..1b8f136
--- /dev/null
+++ b/dojox/atom/widget/nls/ru/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Добавить","addAuthor":"Добавить автора","addContributor":"Добавить участника"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/sk/FeedEntryEditor.js b/dojox/atom/widget/nls/sk/FeedEntryEditor.js
new file mode 100644
index 0000000..abc3a1b
--- /dev/null
+++ b/dojox/atom/widget/nls/sk/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[upraviť]","save":"[uložiť]","cancel":"[zrušiť]","doNew":"[nový]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/sk/FeedEntryViewer.js b/dojox/atom/widget/nls/sk/FeedEntryViewer.js
new file mode 100644
index 0000000..fbaea41
--- /dev/null
+++ b/dojox/atom/widget/nls/sk/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[zatvoriť]","title":"Nadpis","authors":"Autori","summary":"Súhrn","content":"Obsah","contributors":"Prispievatelia","updated":"Aktualizovaný","displayOptions":"[zobraziť voľby]","id":"ID"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/sk/FeedViewerEntry.js b/dojox/atom/widget/nls/sk/FeedViewerEntry.js
new file mode 100644
index 0000000..ff7123d
--- /dev/null
+++ b/dojox/atom/widget/nls/sk/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Vymazať]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/sk/PeopleEditor.js b/dojox/atom/widget/nls/sk/PeopleEditor.js
new file mode 100644
index 0000000..5a727c1
--- /dev/null
+++ b/dojox/atom/widget/nls/sk/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Pridať","addAuthor":"Pridať autora","addContributor":"Pridať prispievateľa"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/sl/FeedEntryEditor.js b/dojox/atom/widget/nls/sl/FeedEntryEditor.js
new file mode 100644
index 0000000..63c1380
--- /dev/null
+++ b/dojox/atom/widget/nls/sl/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[uredi]","save":"[shrani]","cancel":"[prekliči]","doNew":"[novo]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/sl/FeedEntryViewer.js b/dojox/atom/widget/nls/sl/FeedEntryViewer.js
new file mode 100644
index 0000000..943aeff
--- /dev/null
+++ b/dojox/atom/widget/nls/sl/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[zapri]","title":"Naslov","authors":"Avtorji","summary":"Povzetek","content":"Vsebina","contributors":"Kontributorji","updated":"Posodobljeno","displayOptions":"[možnosti prikaza]","id":"ID"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/sl/FeedViewerEntry.js b/dojox/atom/widget/nls/sl/FeedViewerEntry.js
new file mode 100644
index 0000000..020d9bd
--- /dev/null
+++ b/dojox/atom/widget/nls/sl/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Izbriši]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/sl/PeopleEditor.js b/dojox/atom/widget/nls/sl/PeopleEditor.js
new file mode 100644
index 0000000..0609ea8
--- /dev/null
+++ b/dojox/atom/widget/nls/sl/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Dodaj","addAuthor":"Dodaj avtorja","addContributor":"Dodaj kontributorja,"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/sv/FeedEntryEditor.js b/dojox/atom/widget/nls/sv/FeedEntryEditor.js
new file mode 100644
index 0000000..e880f80
--- /dev/null
+++ b/dojox/atom/widget/nls/sv/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[Redigera]","save":"[Spara]","cancel":"[Avbryt]","doNew":"[Nytt]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/sv/FeedEntryViewer.js b/dojox/atom/widget/nls/sv/FeedEntryViewer.js
new file mode 100644
index 0000000..3b58866
--- /dev/null
+++ b/dojox/atom/widget/nls/sv/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[Stäng]","title":"Rubrik","authors":"Författare","summary":"Sammanfattning","content":"Innehåll","contributors":"Medverkande","updated":"Uppdaterat","displayOptions":"[Visningsalternativ]","id":"ID"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/sv/FeedViewerEntry.js b/dojox/atom/widget/nls/sv/FeedViewerEntry.js
new file mode 100644
index 0000000..41de9cb
--- /dev/null
+++ b/dojox/atom/widget/nls/sv/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Ta bort]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/sv/PeopleEditor.js b/dojox/atom/widget/nls/sv/PeopleEditor.js
new file mode 100644
index 0000000..875908f
--- /dev/null
+++ b/dojox/atom/widget/nls/sv/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Lägg til ","addAuthor":"Lägg till författare","addContributor":"Lägg till medverkande"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/th/FeedEntryEditor.js b/dojox/atom/widget/nls/th/FeedEntryEditor.js
new file mode 100644
index 0000000..586f01b
--- /dev/null
+++ b/dojox/atom/widget/nls/th/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[แก้ไข]","save":"[บันทึก]","cancel":"[ยกเลิก]","doNew":"[สร้าง]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/th/FeedEntryViewer.js b/dojox/atom/widget/nls/th/FeedEntryViewer.js
new file mode 100644
index 0000000..eda9eb7
--- /dev/null
+++ b/dojox/atom/widget/nls/th/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[ปิด]","title":"ชื่อเรื่อง","authors":"ผู้เขียน","summary":"สรุป","content":"เนื้อหา","contributors":"ผู้อนุเคราะห์","updated":"อัพเดต","displayOptions":"[อ็อพชันการแสดงผล]","id":"ID"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/th/FeedViewerEntry.js b/dojox/atom/widget/nls/th/FeedViewerEntry.js
new file mode 100644
index 0000000..ce0cb07
--- /dev/null
+++ b/dojox/atom/widget/nls/th/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[ลบ]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/th/PeopleEditor.js b/dojox/atom/widget/nls/th/PeopleEditor.js
new file mode 100644
index 0000000..aaac340
--- /dev/null
+++ b/dojox/atom/widget/nls/th/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"เพิ่ม","addAuthor":"เพิ่มผู้เขียน","addContributor":"เพิ่มผู้อนุเคราะห์"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/tr/FeedEntryEditor.js b/dojox/atom/widget/nls/tr/FeedEntryEditor.js
new file mode 100644
index 0000000..fbe9891
--- /dev/null
+++ b/dojox/atom/widget/nls/tr/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[düzenle]","save":"[kaydet]","cancel":"[iptal]","doNew":"[yeni]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/tr/FeedEntryViewer.js b/dojox/atom/widget/nls/tr/FeedEntryViewer.js
new file mode 100644
index 0000000..03a11d3
--- /dev/null
+++ b/dojox/atom/widget/nls/tr/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[kapat]","title":"Başlık","authors":"Yazarlar","summary":"Özet","content":"İçerik","contributors":"Katkıda Bulunanlar","updated":"Güncelleştirildi","displayOptions":"[görüntüleme seçenekleri]","id":"Kimlik"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/tr/FeedViewerEntry.js b/dojox/atom/widget/nls/tr/FeedViewerEntry.js
new file mode 100644
index 0000000..ce6c932
--- /dev/null
+++ b/dojox/atom/widget/nls/tr/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[Sil]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/tr/PeopleEditor.js b/dojox/atom/widget/nls/tr/PeopleEditor.js
new file mode 100644
index 0000000..26bade5
--- /dev/null
+++ b/dojox/atom/widget/nls/tr/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"Ekle","addAuthor":"Yazar Ekle","addContributor":"Katkıda Bulunan Ekle"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/zh-tw/FeedEntryEditor.js b/dojox/atom/widget/nls/zh-tw/FeedEntryEditor.js
new file mode 100644
index 0000000..64e5ba5
--- /dev/null
+++ b/dojox/atom/widget/nls/zh-tw/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[編輯]","save":"[儲存]","cancel":"[取消]","doNew":"[新建]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/zh-tw/FeedEntryViewer.js b/dojox/atom/widget/nls/zh-tw/FeedEntryViewer.js
new file mode 100644
index 0000000..67f9fed
--- /dev/null
+++ b/dojox/atom/widget/nls/zh-tw/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[關閉]","title":"標題","authors":"作者","summary":"摘要","content":"內容","contributors":"提出者","updated":"已更新","displayOptions":"[顯示選項]","id":"ID"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/zh-tw/FeedViewerEntry.js b/dojox/atom/widget/nls/zh-tw/FeedViewerEntry.js
new file mode 100644
index 0000000..9a535ed
--- /dev/null
+++ b/dojox/atom/widget/nls/zh-tw/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[刪除]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/zh-tw/PeopleEditor.js b/dojox/atom/widget/nls/zh-tw/PeopleEditor.js
new file mode 100644
index 0000000..bd39377
--- /dev/null
+++ b/dojox/atom/widget/nls/zh-tw/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"新增","addAuthor":"新增作者","addContributor":"新增提出者"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/zh/FeedEntryEditor.js b/dojox/atom/widget/nls/zh/FeedEntryEditor.js
new file mode 100644
index 0000000..4d3c31d
--- /dev/null
+++ b/dojox/atom/widget/nls/zh/FeedEntryEditor.js
@@ -0,0 +1 @@
+({"edit":"[编辑]","save":"[保存]","cancel":"[取消]","doNew":"[新建]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/zh/FeedEntryViewer.js b/dojox/atom/widget/nls/zh/FeedEntryViewer.js
new file mode 100644
index 0000000..fe64bb3
--- /dev/null
+++ b/dojox/atom/widget/nls/zh/FeedEntryViewer.js
@@ -0,0 +1 @@
+({"close":"[关闭]","title":"标题","authors":"作者","summary":"摘要","content":"内容","contributors":"内容添加者","updated":"更新时间","displayOptions":"[显示选项]","id":"标识"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/zh/FeedViewerEntry.js b/dojox/atom/widget/nls/zh/FeedViewerEntry.js
new file mode 100644
index 0000000..b7ceb52
--- /dev/null
+++ b/dojox/atom/widget/nls/zh/FeedViewerEntry.js
@@ -0,0 +1 @@
+({"deleteButton":"[删除]"})
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/zh/PeopleEditor.js b/dojox/atom/widget/nls/zh/PeopleEditor.js
new file mode 100644
index 0000000..fd7eef6
--- /dev/null
+++ b/dojox/atom/widget/nls/zh/PeopleEditor.js
@@ -0,0 +1 @@
+({"add":"添加","addAuthor":"添加作者","addContributor":"添加内容添加者"})
\ No newline at end of file
diff --git a/dojox/atom/widget/templates/EntryHeader.html b/dojox/atom/widget/templates/EntryHeader.html
new file mode 100644
index 0000000..67d1e81
--- /dev/null
+++ b/dojox/atom/widget/templates/EntryHeader.html
@@ -0,0 +1 @@
+<span dojoAttachPoint="entryHeaderNode" class="entryHeaderNode"></span>
diff --git a/dojox/atom/widget/templates/FeedEntryEditor.html b/dojox/atom/widget/templates/FeedEntryEditor.html
new file mode 100644
index 0000000..6a7f445
--- /dev/null
+++ b/dojox/atom/widget/templates/FeedEntryEditor.html
@@ -0,0 +1,195 @@
+<div class="feedEntryViewer">
+    <table border="0" width="100%" class="feedEntryViewerMenuTable" dojoAttachPoint="feedEntryViewerMenu" style="display: none;">
+        <tr width="100%"  dojoAttachPoint="entryCheckBoxDisplayOptions">
+        	<td align="left" dojoAttachPoint="entryNewButton">
+                <span class="feedEntryViewerMenu" dojoAttachPoint="doNew" dojoAttachEvent="onclick:_toggleNew"></span>
+        	</td>
+            <td align="left" dojoAttachPoint="entryEditButton" style="display: none;">
+                <span class="feedEntryViewerMenu" dojoAttachPoint="edit" dojoAttachEvent="onclick:_toggleEdit"></span>
+            </td>
+            <td align="left" dojoAttachPoint="entrySaveCancelButtons" style="display: none;">
+                <span class="feedEntryViewerMenu" dojoAttachPoint="save" dojoAttachEvent="onclick:saveEdits"></span>
+                <span class="feedEntryViewerMenu" dojoAttachPoint="cancel" dojoAttachEvent="onclick:cancelEdits"></span>
+            </td>
+            <td align="right">
+                <span class="feedEntryViewerMenu" dojoAttachPoint="displayOptions" dojoAttachEvent="onclick:_toggleOptions"></span>
+            </td>
+        </tr>
+        <tr class="feedEntryViewerDisplayCheckbox" dojoAttachPoint="entryCheckBoxRow" width="100%" style="display: none;">
+            <td dojoAttachPoint="feedEntryCelltitle">
+                <input type="checkbox" name="title" value="Title" dojoAttachPoint="feedEntryCheckBoxTitle" dojoAttachEvent="onclick:_toggleCheckbox"/>
+				<label for="title" dojoAttachPoint="feedEntryCheckBoxLabelTitle"></label>
+            </td>
+            <td dojoAttachPoint="feedEntryCellauthors">
+                <input type="checkbox" name="authors" value="Authors" dojoAttachPoint="feedEntryCheckBoxAuthors" dojoAttachEvent="onclick:_toggleCheckbox"/>
+				<label for="title" dojoAttachPoint="feedEntryCheckBoxLabelAuthors"></label>
+            </td>
+            <td dojoAttachPoint="feedEntryCellcontributors">
+                <input type="checkbox" name="contributors" value="Contributors" dojoAttachPoint="feedEntryCheckBoxContributors" dojoAttachEvent="onclick:_toggleCheckbox"/>
+				<label for="title" dojoAttachPoint="feedEntryCheckBoxLabelContributors"></label>
+            </td>
+            <td dojoAttachPoint="feedEntryCellid">
+                <input type="checkbox" name="id" value="Id" dojoAttachPoint="feedEntryCheckBoxId" dojoAttachEvent="onclick:_toggleCheckbox"/>
+				<label for="title" dojoAttachPoint="feedEntryCheckBoxLabelId"></label>
+            </td>
+            <td rowspan="2" align="right">
+                <span class="feedEntryViewerMenu" dojoAttachPoint="close" dojoAttachEvent="onclick:_toggleOptions"></span>
+            </td>
+		</tr>
+		<tr class="feedEntryViewerDisplayCheckbox" dojoAttachPoint="entryCheckBoxRow2" width="100%" style="display: none;">
+            <td dojoAttachPoint="feedEntryCellupdated">
+                <input type="checkbox" name="updated" value="Updated" dojoAttachPoint="feedEntryCheckBoxUpdated" dojoAttachEvent="onclick:_toggleCheckbox"/>
+				<label for="title" dojoAttachPoint="feedEntryCheckBoxLabelUpdated"></label>
+            </td>
+            <td dojoAttachPoint="feedEntryCellsummary">
+                <input type="checkbox" name="summary" value="Summary" dojoAttachPoint="feedEntryCheckBoxSummary" dojoAttachEvent="onclick:_toggleCheckbox"/>
+				<label for="title" dojoAttachPoint="feedEntryCheckBoxLabelSummary"></label>
+            </td>
+            <td dojoAttachPoint="feedEntryCellcontent">
+                <input type="checkbox" name="content" value="Content" dojoAttachPoint="feedEntryCheckBoxContent" dojoAttachEvent="onclick:_toggleCheckbox"/>
+				<label for="title" dojoAttachPoint="feedEntryCheckBoxLabelContent"></label>
+            </td>
+        </tr>
+    </table>
+    
+    <table class="feedEntryViewerContainer" border="0" width="100%">
+        <tr class="feedEntryViewerTitle" dojoAttachPoint="entryTitleRow" style="display: none;">
+            <td>
+                <table width="100%" cellpadding="0" cellspacing="0" border="0">
+                    <tr class="graphic-tab-lgray">
+						<td class="lp2">
+							<span class="lp" dojoAttachPoint="entryTitleHeader"></span>
+						</td>
+                    </tr>
+                    <tr>
+                        <td>
+                        	<select dojoAttachPoint="entryTitleSelect" dojoAttachEvent="onchange:_switchEditor" style="display: none">
+                        		<option value="text">Text</option>
+								<option value="html">HTML</option>
+								<option value="xhtml">XHTML</option>
+                        	</select>
+                        </td>
+                    </tr>
+                    <tr>
+                        <td colspan="2" dojoAttachPoint="entryTitleNode">
+                        </td>
+                    </tr>
+                </table>
+            </td>
+        </tr>
+
+        <tr class="feedEntryViewerAuthor" dojoAttachPoint="entryAuthorRow" style="display: none;">
+            <td>
+                <table width="100%" cellpadding="0" cellspacing="0" border="0">
+                    <tr class="graphic-tab-lgray">
+						<td class="lp2">
+							<span class="lp" dojoAttachPoint="entryAuthorHeader"></span>
+						</td>
+                    </tr>
+                    <tr>
+                        <td dojoAttachPoint="entryAuthorNode">
+                        </td>
+                    </tr>
+                </table>
+            </td>
+        </tr>
+
+        <tr class="feedEntryViewerContributor" dojoAttachPoint="entryContributorRow" style="display: none;">
+            <td>
+                <table width="100%" cellpadding="0" cellspacing="0" border="0">
+                    <tr class="graphic-tab-lgray">
+						<td class="lp2">
+							<span class="lp" dojoAttachPoint="entryContributorHeader"></span>
+						</td>
+                    </tr>
+                    <tr>
+                        <td dojoAttachPoint="entryContributorNode" class="feedEntryViewerContributorNames">
+                        </td>
+                    </tr>
+                </table>
+            </td>
+        </tr>
+        
+        <tr class="feedEntryViewerId" dojoAttachPoint="entryIdRow" style="display: none;">
+            <td>
+                <table width="100%" cellpadding="0" cellspacing="0" border="0">
+                    <tr class="graphic-tab-lgray">
+						<td class="lp2">
+							<span class="lp" dojoAttachPoint="entryIdHeader"></span>
+						</td>
+                    </tr>
+                    <tr>
+                        <td dojoAttachPoint="entryIdNode" class="feedEntryViewerIdText">
+                        </td>
+                    </tr>
+                </table>
+            </td>
+        </tr>
+    
+        <tr class="feedEntryViewerUpdated" dojoAttachPoint="entryUpdatedRow" style="display: none;">
+            <td>
+                <table width="100%" cellpadding="0" cellspacing="0" border="0">
+                    <tr class="graphic-tab-lgray">
+						<td class="lp2">
+							<span class="lp" dojoAttachPoint="entryUpdatedHeader"></span>
+						</td>
+                    </tr>
+                    <tr>
+                        <td dojoAttachPoint="entryUpdatedNode" class="feedEntryViewerUpdatedText">
+                        </td>
+                    </tr>
+                </table>
+            </td>
+        </tr>
+    
+        <tr class="feedEntryViewerSummary" dojoAttachPoint="entrySummaryRow" style="display: none;">
+            <td>
+                <table width="100%" cellpadding="0" cellspacing="0" border="0">
+                    <tr class="graphic-tab-lgray">
+						<td class="lp2" colspan="2">
+							<span class="lp" dojoAttachPoint="entrySummaryHeader"></span>
+						</td>
+                    </tr>
+                    <tr>
+                        <td>
+                        	<select dojoAttachPoint="entrySummarySelect" dojoAttachEvent="onchange:_switchEditor" style="display: none">
+                        		<option value="text">Text</option>
+								<option value="html">HTML</option>
+								<option value="xhtml">XHTML</option>
+                        	</select>
+                        </td>
+                    </tr>
+                    <tr>
+                        <td dojoAttachPoint="entrySummaryNode">
+                        </td>
+                    </tr>
+                </table>
+            </td>
+        </tr>
+    
+        <tr class="feedEntryViewerContent" dojoAttachPoint="entryContentRow" style="display: none;">
+            <td>
+                <table width="100%" cellpadding="0" cellspacing="0" border="0">
+                    <tr class="graphic-tab-lgray">
+						<td class="lp2">
+							<span class="lp" dojoAttachPoint="entryContentHeader"></span>
+						</td>
+                    </tr>
+                    <tr>
+                        <td>
+                        	<select dojoAttachPoint="entryContentSelect" dojoAttachEvent="onchange:_switchEditor" style="display: none">
+                        		<option value="text">Text</option>
+								<option value="html">HTML</option>
+								<option value="xhtml">XHTML</option>
+                        	</select>
+                        </td>
+                    </tr>
+                    <tr>
+                        <td dojoAttachPoint="entryContentNode">
+                        </td>
+                    </tr>
+                </table>
+            </td>
+        </tr>
+    </table>
+</div>
diff --git a/dojox/atom/widget/templates/FeedEntryViewer.html b/dojox/atom/widget/templates/FeedEntryViewer.html
new file mode 100644
index 0000000..408c071
--- /dev/null
+++ b/dojox/atom/widget/templates/FeedEntryViewer.html
@@ -0,0 +1,158 @@
+<div class="feedEntryViewer">
+    <table border="0" width="100%" class="feedEntryViewerMenuTable" dojoAttachPoint="feedEntryViewerMenu" style="display: none;">
+        <tr width="100%"  dojoAttachPoint="entryCheckBoxDisplayOptions">
+            <td align="right">
+                <span class="feedEntryViewerMenu" dojoAttachPoint="displayOptions" dojoAttachEvent="onclick:_toggleOptions"></span>
+            </td>
+        </tr>
+        <tr class="feedEntryViewerDisplayCheckbox" dojoAttachPoint="entryCheckBoxRow" width="100%" style="display: none;">
+            <td dojoAttachPoint="feedEntryCelltitle">
+                <input type="checkbox" name="title" value="Title" dojoAttachPoint="feedEntryCheckBoxTitle" dojoAttachEvent="onclick:_toggleCheckbox"/>
+				<label for="title" dojoAttachPoint="feedEntryCheckBoxLabelTitle"></label>
+            </td>
+            <td dojoAttachPoint="feedEntryCellauthors">
+                <input type="checkbox" name="authors" value="Authors" dojoAttachPoint="feedEntryCheckBoxAuthors" dojoAttachEvent="onclick:_toggleCheckbox"/>
+				<label for="title" dojoAttachPoint="feedEntryCheckBoxLabelAuthors"></label>
+            </td>
+            <td dojoAttachPoint="feedEntryCellcontributors">
+                <input type="checkbox" name="contributors" value="Contributors" dojoAttachPoint="feedEntryCheckBoxContributors" dojoAttachEvent="onclick:_toggleCheckbox"/>
+				<label for="title" dojoAttachPoint="feedEntryCheckBoxLabelContributors"></label>
+            </td>
+            <td dojoAttachPoint="feedEntryCellid">
+                <input type="checkbox" name="id" value="Id" dojoAttachPoint="feedEntryCheckBoxId" dojoAttachEvent="onclick:_toggleCheckbox"/>
+				<label for="title" dojoAttachPoint="feedEntryCheckBoxLabelId"></label>
+            </td>
+            <td rowspan="2" align="right">
+                <span class="feedEntryViewerMenu" dojoAttachPoint="close" dojoAttachEvent="onclick:_toggleOptions"></span>
+            </td>
+		</tr>
+		<tr class="feedEntryViewerDisplayCheckbox" dojoAttachPoint="entryCheckBoxRow2" width="100%" style="display: none;">
+            <td dojoAttachPoint="feedEntryCellupdated">
+                <input type="checkbox" name="updated" value="Updated" dojoAttachPoint="feedEntryCheckBoxUpdated" dojoAttachEvent="onclick:_toggleCheckbox"/>
+				<label for="title" dojoAttachPoint="feedEntryCheckBoxLabelUpdated"></label>
+            </td>
+            <td dojoAttachPoint="feedEntryCellsummary">
+                <input type="checkbox" name="summary" value="Summary" dojoAttachPoint="feedEntryCheckBoxSummary" dojoAttachEvent="onclick:_toggleCheckbox"/>
+				<label for="title" dojoAttachPoint="feedEntryCheckBoxLabelSummary"></label>
+            </td>
+            <td dojoAttachPoint="feedEntryCellcontent">
+                <input type="checkbox" name="content" value="Content" dojoAttachPoint="feedEntryCheckBoxContent" dojoAttachEvent="onclick:_toggleCheckbox"/>
+				<label for="title" dojoAttachPoint="feedEntryCheckBoxLabelContent"></label>
+            </td>
+        </tr>
+    </table>
+    
+    <table class="feedEntryViewerContainer" border="0" width="100%">
+        <tr class="feedEntryViewerTitle" dojoAttachPoint="entryTitleRow" style="display: none;">
+            <td>
+                <table width="100%" cellpadding="0" cellspacing="0" border="0">
+                    <tr class="graphic-tab-lgray">
+						<td class="lp2">
+							<span class="lp" dojoAttachPoint="entryTitleHeader"></span>
+						</td>
+                    </tr>
+                    <tr>
+                        <td dojoAttachPoint="entryTitleNode">
+                        </td>
+                    </tr>
+                </table>
+            </td>
+        </tr>
+
+        <tr class="feedEntryViewerAuthor" dojoAttachPoint="entryAuthorRow" style="display: none;">
+            <td>
+                <table width="100%" cellpadding="0" cellspacing="0" border="0">
+                    <tr class="graphic-tab-lgray">
+						<td class="lp2">
+							<span class="lp" dojoAttachPoint="entryAuthorHeader"></span>
+						</td>
+                    </tr>
+                    <tr>
+                        <td dojoAttachPoint="entryAuthorNode">
+                        </td>
+                    </tr>
+                </table>
+            </td>
+        </tr>
+
+        <tr class="feedEntryViewerContributor" dojoAttachPoint="entryContributorRow" style="display: none;">
+            <td>
+                <table width="100%" cellpadding="0" cellspacing="0" border="0">
+                    <tr class="graphic-tab-lgray">
+						<td class="lp2">
+							<span class="lp" dojoAttachPoint="entryContributorHeader"></span>
+						</td>
+                    </tr>
+                    <tr>
+                        <td dojoAttachPoint="entryContributorNode" class="feedEntryViewerContributorNames">
+                        </td>
+                    </tr>
+                </table>
+            </td>
+        </tr>
+        
+        <tr class="feedEntryViewerId" dojoAttachPoint="entryIdRow" style="display: none;">
+            <td>
+                <table width="100%" cellpadding="0" cellspacing="0" border="0">
+                    <tr class="graphic-tab-lgray">
+						<td class="lp2">
+							<span class="lp" dojoAttachPoint="entryIdHeader"></span>
+						</td>
+                    </tr>
+                    <tr>
+                        <td dojoAttachPoint="entryIdNode" class="feedEntryViewerIdText">
+                        </td>
+                    </tr>
+                </table>
+            </td>
+        </tr>
+    
+        <tr class="feedEntryViewerUpdated" dojoAttachPoint="entryUpdatedRow" style="display: none;">
+            <td>
+                <table width="100%" cellpadding="0" cellspacing="0" border="0">
+                    <tr class="graphic-tab-lgray">
+						<td class="lp2">
+							<span class="lp" dojoAttachPoint="entryUpdatedHeader"></span>
+						</td>
+                    </tr>
+                    <tr>
+                        <td dojoAttachPoint="entryUpdatedNode" class="feedEntryViewerUpdatedText">
+                        </td>
+                    </tr>
+                </table>
+            </td>
+        </tr>
+    
+        <tr class="feedEntryViewerSummary" dojoAttachPoint="entrySummaryRow" style="display: none;">
+            <td>
+                <table width="100%" cellpadding="0" cellspacing="0" border="0">
+                    <tr class="graphic-tab-lgray">
+						<td class="lp2">
+							<span class="lp" dojoAttachPoint="entrySummaryHeader"></span>
+						</td>
+                    </tr>
+                    <tr>
+                        <td dojoAttachPoint="entrySummaryNode">
+                        </td>
+                    </tr>
+                </table>
+            </td>
+        </tr>
+    
+        <tr class="feedEntryViewerContent" dojoAttachPoint="entryContentRow" style="display: none;">
+            <td>
+                <table width="100%" cellpadding="0" cellspacing="0" border="0">
+                    <tr class="graphic-tab-lgray">
+						<td class="lp2">
+							<span class="lp" dojoAttachPoint="entryContentHeader"></span>
+						</td>
+                    </tr>
+                    <tr>
+                        <td dojoAttachPoint="entryContentNode">
+                        </td>
+                    </tr>
+                </table>
+            </td>
+        </tr>
+    </table>
+</div>
diff --git a/dojox/atom/widget/templates/FeedViewer.html b/dojox/atom/widget/templates/FeedViewer.html
new file mode 100644
index 0000000..f3d2108
--- /dev/null
+++ b/dojox/atom/widget/templates/FeedViewer.html
@@ -0,0 +1,6 @@
+<div class="feedViewerContainer" dojoAttachPoint="feedViewerContainerNode">
+	<table cellspacing="0" cellpadding="0" class="feedViewerTable">
+		<tbody dojoAttachPoint="feedViewerTableBody" class="feedViewerTableBody">
+		</tbody>
+	</table>
+</div>
diff --git a/dojox/atom/widget/templates/FeedViewerEntry.html b/dojox/atom/widget/templates/FeedViewerEntry.html
new file mode 100644
index 0000000..201f884
--- /dev/null
+++ b/dojox/atom/widget/templates/FeedViewerEntry.html
@@ -0,0 +1,15 @@
+<tr class="feedViewerEntry" dojoAttachPoint="entryNode" dojoAttachEvent="onclick:onClick">
+    <td class="feedViewerEntryUpdated" dojoAttachPoint="timeNode">
+    </td>
+    <td>
+        <table border="0" width="100%" dojoAttachPoint="titleRow">
+            <tr padding="0" border="0">
+                <td class="feedViewerEntryTitle" dojoAttachPoint="titleNode">
+                </td>
+                <td class="feedViewerEntryDelete" align="right">
+                    <span dojoAttachPoint="deleteButton" dojoAttachEvent="onclick:deleteEntry" class="feedViewerDeleteButton" style="display:none;">[delete]</span>
+                </td>
+            <tr>
+        </table>
+    </td>
+</tr>
\ No newline at end of file
diff --git a/dojox/atom/widget/templates/FeedViewerGrouping.html b/dojox/atom/widget/templates/FeedViewerGrouping.html
new file mode 100644
index 0000000..467e428
--- /dev/null
+++ b/dojox/atom/widget/templates/FeedViewerGrouping.html
@@ -0,0 +1,4 @@
+<tr dojoAttachPoint="groupingNode" class="feedViewerGrouping">
+	<td colspan="2" dojoAttachPoint="titleNode" class="feedViewerGroupingTitle">
+	</td>
+</tr>
\ No newline at end of file
diff --git a/dojox/atom/widget/templates/PeopleEditor.html b/dojox/atom/widget/templates/PeopleEditor.html
new file mode 100644
index 0000000..a034c76
--- /dev/null
+++ b/dojox/atom/widget/templates/PeopleEditor.html
@@ -0,0 +1,6 @@
+<div class="peopleEditor">
+	<table style="width: 100%">
+		<tbody dojoAttachPoint="peopleEditorEditors"></tbody>
+	</table>
+	<span class="peopleEditorButton" dojoAttachPoint="peopleEditorButton" dojoAttachEvent="onclick:_add"></span>
+</div>
\ No newline at end of file
diff --git a/dojox/atom/widget/templates/css/EntryHeader.css b/dojox/atom/widget/templates/css/EntryHeader.css
new file mode 100644
index 0000000..5375fef
--- /dev/null
+++ b/dojox/atom/widget/templates/css/EntryHeader.css
@@ -0,0 +1,27 @@
+
+.containerNode {
+        visibility : visible;
+}
+.graphic-tab-lgray {
+		margin-bottom: 10px;
+}
+.newgraphic-tab-lgray {
+        border-bottom: #d9d9d9 solid 7px;
+}
+td.lp { 
+        padding: 0px 13px 0px 10px;
+        font-weight: bold;
+        background: #d9d9d9;
+        border-bottom: #d9d9d9 solid 7px;
+}
+td.lp2 { 
+        background: #FFFFFF;
+        border-bottom: #d9d9d9 solid 7px;
+}
+span.lp {
+        padding: 0px 13px 0px 10px;
+        font-weight: bold;
+        background: #d9d9d9;
+        border-bottom: #d9d9d9 solid 7px;
+		width: auto;
+}
diff --git a/dojox/atom/widget/templates/css/HtmlFeedEntryEditor.css b/dojox/atom/widget/templates/css/HtmlFeedEntryEditor.css
new file mode 100644
index 0000000..f31be85
--- /dev/null
+++ b/dojox/atom/widget/templates/css/HtmlFeedEntryEditor.css
@@ -0,0 +1,84 @@
+.feedEntryEditor {
+        color:#000000;
+        background: #FFFFFF;
+}
+.feedEntryEditorMenuTable {
+        background: #C0C0C0;      
+        border:2px solid;
+        border-top-color: lightgrey;
+        border-left-color: lightgrey;
+        border-right-color: darkgray;
+        border-bottom-color: darkgray;
+}
+.feedEntryEditorMenu {
+        cursor: pointer;
+        color:#0000FF;
+        text-align: left;
+        font-size:  small;
+}
+.feedEntryEditorDisplayCheckbox {
+        font-size:  small;
+        text-align: left;
+}
+.feedEntryEditorMenu:hover {
+        text-decoration: underline;
+}
+.feedEntryEditorTitle {
+        color:#000000;
+        background: #FFFFFF;
+        text-align: left;
+        #padding-left: 10px;
+        font-size:  125%;
+        font-weight: bold; 
+}
+.feedEntryEditorAuthor {
+        color:#000000;
+        background: #FFFFFF;
+}
+.feedEntryEditorAuthorNames {
+        color:#000000;
+        background: #FFFFFF;
+        text-align: left;
+        #padding-left: 10px;
+        font-size:  110%;
+        font-style: italic;
+        font-weight: normal;
+}
+.feedEntryEditorSummary {
+        color:#000000;
+        background: #FFFFFF;
+}
+.feedEntryEditorUpdated {
+        color:#000000;
+        background: #FFFFFF;
+}
+.feedEntryEditorUpdatedText {
+        color:#000000;
+        background: #FFFFFF;
+        font-size:  110%;
+        font-style: italic;
+        font-weight: normal;
+}
+.feedEntryEditorId {
+        color:#000000;
+        background: #FFFFFF;
+}
+.feedEntryEditorIdText {
+        color:#000000;
+        background: #FFFFFF;
+        font-style: italic;
+        font-size:  110%;
+        font-weight: normal;
+}
+.feedEntryEditorContent {
+        color:#000000;
+        background: #FFFFFF;
+}
+.feedEntryEditorContributorNames {
+        color:#000000;
+        text-align: left;
+        #padding-left: 10px;
+        font-size:  125%;
+        font-style: italic;
+        font-weight: normal;
+}
diff --git a/dojox/atom/widget/templates/css/HtmlFeedEntryViewer.css b/dojox/atom/widget/templates/css/HtmlFeedEntryViewer.css
new file mode 100644
index 0000000..7ab9cbb
--- /dev/null
+++ b/dojox/atom/widget/templates/css/HtmlFeedEntryViewer.css
@@ -0,0 +1,90 @@
+.feedEntryViewer {
+        color:#000000;
+        background: #FFFFFF;
+}
+.feedEntryViewerMenuTable {
+        background: #C0C0C0;      
+        border:2px solid;
+        border-top-color: lightgrey;
+        border-left-color: lightgrey;
+        border-right-color: darkgray;
+        border-bottom-color: darkgray;
+		margin: 0;
+}
+.feedEntryViewerMenu, .peopleEditorButton {
+        cursor: pointer;
+        color:#0000FF;
+        text-align: left;
+        font-size:  small;
+}
+.feedEntryViewerDisplayCheckbox {
+        font-size:  small;
+        text-align: left;
+}
+.feedEntryViewerMenu:hover, .peopleEditorButton:hover {
+        text-decoration: underline;
+}
+.feedEntryViewerContainer, .feedEntryViewerContainer table {
+		border-width: 0;
+		margin: 0;
+}
+.feedEntryViewerTitle {
+        color:#000000;
+        background: #FFFFFF;
+        text-align: left;
+        
+        font-size:  125%;
+        font-weight: bold; 
+}
+.feedEntryViewerAuthor {
+        color:#000000;
+        background: #FFFFFF;
+}
+.feedEntryViewerAuthorNames {
+        color:#000000;
+        background: #FFFFFF;
+        text-align: left;
+        
+        font-size:  110%;
+        font-style: italic;
+        font-weight: normal;
+}
+.feedEntryViewerSummary {
+        color:#000000;
+        background: #FFFFFF;
+}
+.feedEntryViewerUpdated {
+        color:#000000;
+        background: #FFFFFF;
+}
+.feedEntryViewerUpdatedText {
+        color:#000000;
+        background: #FFFFFF;
+        font-size:  110%;
+        font-style: italic;
+        font-weight: normal;
+}
+.feedEntryViewerId {
+        color:#000000;
+        background: #FFFFFF;
+}
+.feedEntryViewerIdText {
+        color:#000000;
+        background: #FFFFFF;
+        font-style: italic;
+        font-size:  110%;
+        font-weight: normal;
+}
+.feedEntryViewerContent {
+        color:#000000;
+        background: #FFFFFF;
+}
+.feedEntryViewerContributorNames {
+        color:#000000;
+        text-align: left;
+        
+        font-size:  125%;
+        font-weight: normal;
+}
+.feedEntryViewer table {
+}
diff --git a/dojox/atom/widget/templates/css/HtmlFeedViewer.css b/dojox/atom/widget/templates/css/HtmlFeedViewer.css
new file mode 100644
index 0000000..70d3a57
--- /dev/null
+++ b/dojox/atom/widget/templates/css/HtmlFeedViewer.css
@@ -0,0 +1,14 @@
+.feedViewerTable {
+	font-size: small;
+	width:100%;
+	cursor:default;
+	padding:2px;
+}
+.feedViewerTable, .feedViewerTable table {
+	border-width: 0;
+	margin: 0;
+}
+.feedViewerTableBody {
+	overflow-x: auto;
+	overflow-y: auto;
+}
diff --git a/dojox/atom/widget/templates/css/HtmlFeedViewerEntry.css b/dojox/atom/widget/templates/css/HtmlFeedViewerEntry.css
new file mode 100644
index 0000000..8318b31
--- /dev/null
+++ b/dojox/atom/widget/templates/css/HtmlFeedViewerEntry.css
@@ -0,0 +1,60 @@
+.feedViewerEntry {
+        background: #F0F0F0;
+        padding: 2px;
+        overflow-x: auto;
+        overflow-y: auto;
+        cursor: pointer;   
+}
+.feedViewerEntry:hover {
+        background: #a6c2e7;
+        padding: 2px;
+}
+.feedViewerEntrySelected {
+        color: #000000;
+        background: #C0C0C0;
+        text-align: left;
+        vertical-align: top;
+        padding-bottom: 2px;
+        padding: 2px;
+}
+.feedViewerEntrySelected:hover {
+        background: #a6c2e7;
+        padding: 2px;
+}
+.feedViewerEntryUpdated {
+        text-align: left;
+        vertical-align: top;
+        color: #909090;
+        padding-bottom: 2px;
+        padding: 2px;
+}
+.feedViewerEntryUpdatedSelected {
+        text-align: left;
+        vertical-align: top;
+        color: #000000;
+        padding-bottom: 2px;
+        padding: 2px;
+}
+.feedViewerEntryTitle {
+        color:#000000;
+        text-align: left;
+        text-decoration:none;
+        padding-left: 4px;
+        padding-bottom: 2px;
+}
+.feedViewerEntryTitle:hover {
+        color:#000000;
+        text-align: left;
+        text-decoration:underline;
+        padding-left: 4px;
+        padding-bottom: 2px;
+}
+.feedViewerDeleteButton {
+        cursor: pointer;
+        color:#0000FF;
+        text-align: left;
+        font-size:  small;
+}
+.feedViewerDeleteButton:hover {
+        text-decoration: underline;
+}
diff --git a/dojox/atom/widget/templates/css/HtmlFeedViewerGrouping.css b/dojox/atom/widget/templates/css/HtmlFeedViewerGrouping.css
new file mode 100644
index 0000000..326781e
--- /dev/null
+++ b/dojox/atom/widget/templates/css/HtmlFeedViewerGrouping.css
@@ -0,0 +1,8 @@
+.feedViewerGrouping {
+}
+.feedViewerGroupingTitle {
+	font-weight: bold;
+	color:#606060;
+	border-bottom:1px solid #909090;
+	padding-top: 4px;
+}
diff --git a/dojox/charting/Chart2D.js b/dojox/charting/Chart2D.js
new file mode 100644
index 0000000..bf0cf7a
--- /dev/null
+++ b/dojox/charting/Chart2D.js
@@ -0,0 +1,373 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.Chart2D"]){
+dojo._hasResource["dojox.charting.Chart2D"]=true;
+dojo.provide("dojox.charting.Chart2D");
+dojo.require("dojox.gfx");
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.functional.fold");
+dojo.require("dojox.lang.functional.reversed");
+dojo.require("dojox.charting.Theme");
+dojo.require("dojox.charting.Series");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Default");
+dojo.require("dojox.charting.plot2d.Lines");
+dojo.require("dojox.charting.plot2d.Areas");
+dojo.require("dojox.charting.plot2d.Markers");
+dojo.require("dojox.charting.plot2d.MarkersOnly");
+dojo.require("dojox.charting.plot2d.Scatter");
+dojo.require("dojox.charting.plot2d.Stacked");
+dojo.require("dojox.charting.plot2d.StackedLines");
+dojo.require("dojox.charting.plot2d.StackedAreas");
+dojo.require("dojox.charting.plot2d.Columns");
+dojo.require("dojox.charting.plot2d.StackedColumns");
+dojo.require("dojox.charting.plot2d.ClusteredColumns");
+dojo.require("dojox.charting.plot2d.Bars");
+dojo.require("dojox.charting.plot2d.StackedBars");
+dojo.require("dojox.charting.plot2d.ClusteredBars");
+dojo.require("dojox.charting.plot2d.Grid");
+dojo.require("dojox.charting.plot2d.Pie");
+dojo.require("dojox.charting.plot2d.Bubble");
+(function(){
+var df=dojox.lang.functional,dc=dojox.charting,_3=df.lambda("item.clear()"),_4=df.lambda("item.purgeGroup()"),_5=df.lambda("item.destroy()"),_6=df.lambda("item.dirty = false"),_7=df.lambda("item.dirty = true");
+dojo.declare("dojox.charting.Chart2D",null,{constructor:function(_8,_9){
+if(!_9){
+_9={};
+}
+this.margins=_9.margins?_9.margins:{l:10,t:10,r:10,b:10};
+this.stroke=_9.stroke;
+this.fill=_9.fill;
+this.theme=null;
+this.axes={};
+this.stack=[];
+this.plots={};
+this.series=[];
+this.runs={};
+this.dirty=true;
+this.coords=null;
+this.node=dojo.byId(_8);
+var _a=dojo.marginBox(_8);
+this.surface=dojox.gfx.createSurface(this.node,_a.w,_a.h);
+},destroy:function(){
+dojo.forEach(this.series,_5);
+dojo.forEach(this.stack,_5);
+df.forIn(this.axes,_5);
+this.surface.destroy();
+},getCoords:function(){
+if(!this.coords){
+this.coords=dojo.coords(this.node,true);
+}
+return this.coords;
+},setTheme:function(_b){
+this.theme=_b._clone();
+this.dirty=true;
+return this;
+},addAxis:function(_c,_d){
+var _e;
+if(!_d||!("type" in _d)){
+_e=new dc.axis2d.Default(this,_d);
+}else{
+_e=typeof _d.type=="string"?new dc.axis2d[_d.type](this,_d):new _d.type(this,_d);
+}
+_e.name=_c;
+_e.dirty=true;
+if(_c in this.axes){
+this.axes[_c].destroy();
+}
+this.axes[_c]=_e;
+this.dirty=true;
+return this;
+},getAxis:function(_f){
+return this.axes[_f];
+},removeAxis:function(_10){
+if(_10 in this.axes){
+this.axes[_10].destroy();
+delete this.axes[_10];
+this.dirty=true;
+}
+return this;
+},addPlot:function(_11,_12){
+var _13;
+if(!_12||!("type" in _12)){
+_13=new dc.plot2d.Default(this,_12);
+}else{
+_13=typeof _12.type=="string"?new dc.plot2d[_12.type](this,_12):new _12.type(this,_12);
+}
+_13.name=_11;
+_13.dirty=true;
+if(_11 in this.plots){
+this.stack[this.plots[_11]].destroy();
+this.stack[this.plots[_11]]=_13;
+}else{
+this.plots[_11]=this.stack.length;
+this.stack.push(_13);
+}
+this.dirty=true;
+return this;
+},removePlot:function(_14){
+if(_14 in this.plots){
+var _15=this.plots[_14];
+delete this.plots[_14];
+this.stack[_15].destroy();
+this.stack.splice(_15,1);
+df.forIn(this.plots,function(idx,_17,_18){
+if(idx>_15){
+_18[_17]=idx-1;
+}
+});
+this.dirty=true;
+}
+return this;
+},addSeries:function(_19,_1a,_1b){
+var run=new dc.Series(this,_1a,_1b);
+if(_19 in this.runs){
+this.series[this.runs[_19]].destroy();
+this.series[this.runs[_19]]=run;
+}else{
+this.runs[_19]=this.series.length;
+this.series.push(run);
+}
+run.name=_19;
+this.dirty=true;
+if(!("ymin" in run)&&"min" in run){
+run.ymin=run.min;
+}
+if(!("ymax" in run)&&"max" in run){
+run.ymax=run.max;
+}
+return this;
+},removeSeries:function(_1d){
+if(_1d in this.runs){
+var _1e=this.runs[_1d],_1f=this.series[_1e].plot;
+delete this.runs[_1d];
+this.series[_1e].destroy();
+this.series.splice(_1e,1);
+df.forIn(this.runs,function(idx,_21,_22){
+if(idx>_1e){
+_22[_21]=idx-1;
+}
+});
+this.dirty=true;
+}
+return this;
+},updateSeries:function(_23,_24){
+if(_23 in this.runs){
+var run=this.series[this.runs[_23]];
+run.data=_24;
+run.dirty=true;
+this._invalidateDependentPlots(run.plot,false);
+this._invalidateDependentPlots(run.plot,true);
+}
+return this;
+},resize:function(_26,_27){
+var box;
+switch(arguments.length){
+case 0:
+box=dojo.marginBox(this.node);
+break;
+case 1:
+box=_26;
+break;
+default:
+box={w:_26,h:_27};
+break;
+}
+dojo.marginBox(this.node,box);
+this.surface.setDimensions(box.w,box.h);
+this.dirty=true;
+this.coords=null;
+return this.render();
+},getGeometry:function(){
+var ret={};
+df.forIn(this.axes,function(_2a){
+if(_2a.initialized()){
+ret[_2a.name]={name:_2a.name,vertical:_2a.vertical,scaler:_2a.scaler,ticks:_2a.ticks};
+}
+});
+return ret;
+},setAxisWindow:function(_2b,_2c,_2d){
+var _2e=this.axes[_2b];
+if(_2e){
+_2e.setWindow(_2c,_2d);
+}
+return this;
+},setWindow:function(sx,sy,dx,dy){
+if(!("plotArea" in this)){
+this.calculateGeometry();
+}
+df.forIn(this.axes,function(_33){
+var _34,_35,_36=_33.getScaler().bounds,s=_36.span/(_36.upper-_36.lower);
+if(_33.vertical){
+_34=sy;
+_35=dy/s/_34;
+}else{
+_34=sx;
+_35=dx/s/_34;
+}
+_33.setWindow(_34,_35);
+});
+return this;
+},calculateGeometry:function(){
+if(this.dirty){
+return this.fullGeometry();
+}
+dojo.forEach(this.stack,function(_38){
+if(_38.dirty||(_38.hAxis&&this.axes[_38.hAxis].dirty)||(_38.vAxis&&this.axes[_38.vAxis].dirty)){
+_38.calculateAxes(this.plotArea);
+}
+},this);
+return this;
+},fullGeometry:function(){
+this._makeDirty();
+dojo.forEach(this.stack,_3);
+if(!this.theme){
+this.setTheme(new dojox.charting.Theme(dojox.charting._def));
+}
+dojo.forEach(this.series,function(run){
+if(!(run.plot in this.plots)){
+var _3a=new dc.plot2d.Default(this,{});
+_3a.name=run.plot;
+this.plots[run.plot]=this.stack.length;
+this.stack.push(_3a);
+}
+this.stack[this.plots[run.plot]].addSeries(run);
+},this);
+dojo.forEach(this.stack,function(_3b){
+if(_3b.hAxis){
+_3b.setAxis(this.axes[_3b.hAxis]);
+}
+if(_3b.vAxis){
+_3b.setAxis(this.axes[_3b.vAxis]);
+}
+},this);
+var dim=this.dim=this.surface.getDimensions();
+dim.width=dojox.gfx.normalizedLength(dim.width);
+dim.height=dojox.gfx.normalizedLength(dim.height);
+df.forIn(this.axes,_3);
+dojo.forEach(this.stack,function(_3d){
+_3d.calculateAxes(dim);
+});
+var _3e=this.offsets={l:0,r:0,t:0,b:0};
+df.forIn(this.axes,function(_3f){
+df.forIn(_3f.getOffsets(),function(o,i){
+_3e[i]+=o;
+});
+});
+df.forIn(this.margins,function(o,i){
+_3e[i]+=o;
+});
+this.plotArea={width:dim.width-_3e.l-_3e.r,height:dim.height-_3e.t-_3e.b};
+df.forIn(this.axes,_3);
+dojo.forEach(this.stack,function(_44){
+_44.calculateAxes(this.plotArea);
+},this);
+return this;
+},render:function(){
+if(this.theme){
+this.theme.clear();
+}
+if(this.dirty){
+return this.fullRender();
+}
+this.calculateGeometry();
+df.forEachRev(this.stack,function(_45){
+_45.render(this.dim,this.offsets);
+},this);
+df.forIn(this.axes,function(_46){
+_46.render(this.dim,this.offsets);
+},this);
+this._makeClean();
+if(this.surface.render){
+this.surface.render();
+}
+return this;
+},fullRender:function(){
+this.fullGeometry();
+var _47=this.offsets,dim=this.dim;
+var _49=df.foldl(this.stack,"z + plot.getRequiredColors()",0);
+this.theme.defineColors({num:_49,cache:false});
+dojo.forEach(this.series,_4);
+df.forIn(this.axes,_4);
+dojo.forEach(this.stack,_4);
+this.surface.clear();
+var t=this.theme,_4b=t.plotarea&&t.plotarea.fill,_4c=t.plotarea&&t.plotarea.stroke;
+if(_4b){
+this.surface.createRect({x:_47.l,y:_47.t,width:dim.width-_47.l-_47.r,height:dim.height-_47.t-_47.b}).setFill(_4b);
+}
+if(_4c){
+this.surface.createRect({x:_47.l,y:_47.t,width:dim.width-_47.l-_47.r-1,height:dim.height-_47.t-_47.b-1}).setStroke(_4c);
+}
+df.foldr(this.stack,function(z,_4e){
+return _4e.render(dim,_47),0;
+},0);
+_4b=this.fill?this.fill:(t.chart&&t.chart.fill);
+_4c=this.stroke?this.stroke:(t.chart&&t.chart.stroke);
+if(_4b=="inherit"){
+var _4f=this.node,_4b=new dojo.Color(dojo.style(_4f,"backgroundColor"));
+while(_4b.a==0&&_4f!=document.documentElement){
+_4b=new dojo.Color(dojo.style(_4f,"backgroundColor"));
+_4f=_4f.parentNode;
+}
+}
+if(_4b){
+if(_47.l){
+this.surface.createRect({width:_47.l,height:dim.height+1}).setFill(_4b);
+}
+if(_47.r){
+this.surface.createRect({x:dim.width-_47.r,width:_47.r+1,height:dim.height+1}).setFill(_4b);
+}
+if(_47.t){
+this.surface.createRect({width:dim.width+1,height:_47.t}).setFill(_4b);
+}
+if(_47.b){
+this.surface.createRect({y:dim.height-_47.b,width:dim.width+1,height:_47.b+2}).setFill(_4b);
+}
+}
+if(_4c){
+this.surface.createRect({width:dim.width-1,height:dim.height-1}).setStroke(_4c);
+}
+df.forIn(this.axes,function(_50){
+_50.render(dim,_47);
+});
+this._makeClean();
+if(this.surface.render){
+this.surface.render();
+}
+return this;
+},connectToPlot:function(_51,_52,_53){
+return _51 in this.plots?this.stack[this.plots[_51]].connect(_52,_53):null;
+},_makeClean:function(){
+dojo.forEach(this.axes,_6);
+dojo.forEach(this.stack,_6);
+dojo.forEach(this.series,_6);
+this.dirty=false;
+},_makeDirty:function(){
+dojo.forEach(this.axes,_7);
+dojo.forEach(this.stack,_7);
+dojo.forEach(this.series,_7);
+this.dirty=true;
+},_invalidateDependentPlots:function(_54,_55){
+if(_54 in this.plots){
+var _56=this.stack[this.plots[_54]],_57,_58=_55?"vAxis":"hAxis";
+if(_56[_58]){
+_57=this.axes[_56[_58]];
+if(_57.dependOnData()){
+_57.dirty=true;
+dojo.forEach(this.stack,function(p){
+if(p[_58]&&p[_58]==_56[_58]){
+p.dirty=true;
+}
+});
+}
+}else{
+_56.dirty=true;
+}
+}
+}});
+})();
+}
diff --git a/dojox/charting/Chart3D.js b/dojox/charting/Chart3D.js
new file mode 100644
index 0000000..9452f82
--- /dev/null
+++ b/dojox/charting/Chart3D.js
@@ -0,0 +1,73 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.Chart3D"]){
+dojo._hasResource["dojox.charting.Chart3D"]=true;
+dojo.provide("dojox.charting.Chart3D");
+dojo.require("dojox.gfx3d");
+(function(){
+var _1={x:0,y:0,z:1},v=dojox.gfx3d.vector,n=dojox.gfx.normalizedLength;
+dojo.declare("dojox.charting.Chart3D",null,{constructor:function(_4,_5,_6,_7){
+this.node=dojo.byId(_4);
+this.surface=dojox.gfx.createSurface(this.node,n(this.node.style.width),n(this.node.style.height));
+this.view=this.surface.createViewport();
+this.view.setLights(_5.lights,_5.ambient,_5.specular);
+this.view.setCameraTransform(_6);
+this.theme=_7;
+this.walls=[];
+this.plots=[];
+},generate:function(){
+return this._generateWalls()._generatePlots();
+},invalidate:function(){
+this.view.invalidate();
+return this;
+},render:function(){
+this.view.render();
+return this;
+},addPlot:function(_8){
+return this._add(this.plots,_8);
+},removePlot:function(_9){
+return this._remove(this.plots,_9);
+},addWall:function(_a){
+return this._add(this.walls,_a);
+},removeWall:function(_b){
+return this._remove(this.walls,_b);
+},_add:function(_c,_d){
+if(!dojo.some(_c,function(i){
+return i==_d;
+})){
+_c.push(_d);
+this.view.invalidate();
+}
+return this;
+},_remove:function(_f,_10){
+var a=dojo.filter(_f,function(i){
+return i!=_10;
+});
+return a.length<_f.length?(_f=a,this.invalidate()):this;
+},_generateWalls:function(){
+for(var i=0;i<this.walls.length;++i){
+if(v.dotProduct(_1,this.walls[i].normal)>0){
+this.walls[i].generate(this);
+}
+}
+return this;
+},_generatePlots:function(){
+var _14=0,m=dojox.gfx3d.matrix,i=0;
+for(;i<this.plots.length;++i){
+_14+=this.plots[i].getDepth();
+}
+for(--i;i>=0;--i){
+var _17=this.view.createScene();
+_17.setTransform(m.translate(0,0,-_14));
+this.plots[i].generate(this,_17);
+_14-=this.plots[i].getDepth();
+}
+return this;
+}});
+})();
+}
diff --git a/dojox/charting/DataChart.js b/dojox/charting/DataChart.js
new file mode 100644
index 0000000..7bc0218
--- /dev/null
+++ b/dojox/charting/DataChart.js
@@ -0,0 +1,220 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.DataChart"]){
+dojo._hasResource["dojox.charting.DataChart"]=true;
+dojo.provide("dojox.charting.DataChart");
+dojo.require("dojox.charting.Chart2D");
+dojo.require("dojox.charting.themes.PlotKit.blue");
+dojo.experimental("dojox.charting.DataChart");
+(function(){
+var _1={vertical:true,min:0,max:10,majorTickStep:5,minorTickStep:1,natural:false,stroke:"black",majorTick:{stroke:"black",length:8},minorTick:{stroke:"gray",length:2},majorLabels:true};
+var _2={natural:true,majorLabels:true,includeZero:false,majorTickStep:1,majorTick:{stroke:"black",length:8},fixUpper:"major",stroke:"black",htmlLabels:true,from:1};
+var _3={markers:true,tension:2,gap:2};
+dojo.declare("dojox.charting.DataChart",[dojox.charting.Chart2D],{scroll:true,comparative:false,query:"*",queryOptions:"",fieldName:"value",chartTheme:dojox.charting.themes.PlotKit.blue,displayRange:0,stretchToFit:true,minWidth:200,minHeight:100,showing:true,label:"name",constructor:function(_4,_5){
+this.domNode=dojo.byId(_4);
+dojo.mixin(this,_5);
+this.xaxis=dojo.mixin(dojo.mixin({},_2),_5.xaxis);
+if(this.xaxis.labelFunc=="seriesLabels"){
+this.xaxis.labelFunc=dojo.hitch(this,"seriesLabels");
+}
+this.yaxis=dojo.mixin(dojo.mixin({},_1),_5.yaxis);
+if(this.yaxis.labelFunc=="seriesLabels"){
+this.yaxis.labelFunc=dojo.hitch(this,"seriesLabels");
+}
+this.convertLabels(this.yaxis);
+this.convertLabels(this.xaxis);
+this.onSetItems={};
+this.onSetInterval=0;
+this.dataLength=0;
+this.seriesData={};
+this.seriesDataBk={};
+this.firstRun=true;
+this.dataOffset=0;
+this.chartTheme.plotarea.stroke={color:"gray",width:3};
+this.setTheme(this.chartTheme);
+if(this.displayRange){
+this.stretchToFit=false;
+}
+if(!this.stretchToFit){
+this.xaxis.to=this.displayRange;
+}
+this.addAxis("x",this.xaxis);
+this.addAxis("y",this.yaxis);
+_3.type=_5.type||"Markers";
+this.addPlot("default",dojo.mixin(_3,_5.chartPlot));
+this.addPlot("grid",dojo.mixin(_5.grid||{},{type:"Grid",hMinorLines:true}));
+if(this.showing){
+this.render();
+}
+if(_5.store){
+this.setStore(_5.store,_5.query,_5.fieldName,_5.queryOptions);
+}
+},setStore:function(_6,_7,_8,_9){
+this.firstRun=true;
+this.store=_6||this.store;
+this.query=_7||this.query;
+this.fieldName=_8||this.fieldName;
+this.label=this.store.getLabelAttributes();
+this.queryOptions=_9||_9;
+this.fetch();
+dojo.connect(this.store,"onSet",this,"onSet");
+dojo.connect(this.store,"onError",this,"onError");
+},show:function(){
+if(!this.showing){
+dojo.style(this.domNode,"display","");
+this.showing=true;
+this.render();
+}
+},hide:function(){
+if(this.showing){
+dojo.style(this.domNode,"display","none");
+this.showing=false;
+}
+},onSet:function(_a){
+var nm=this.getProperty(_a,this.label);
+if(nm in this.runs||this.comparative){
+clearTimeout(this.onSetInterval);
+if(!this.onSetItems[nm]){
+this.onSetItems[nm]=_a;
+}
+this.onSetInterval=setTimeout(dojo.hitch(this,function(){
+clearTimeout(this.onSetInterval);
+var _c=[];
+for(var nm in this.onSetItems){
+_c.push(this.onSetItems[nm]);
+}
+this.onData(_c);
+this.onSetItems={};
+}),200);
+}
+},onError:function(_e){
+console.error(_e);
+},onDataReceived:function(_f){
+},getProperty:function(_10,_11){
+if(_11==this.label){
+return this.store.getLabel(_10);
+}
+if(_11=="id"){
+return this.store.getIdentity(_10);
+}
+var _12=this.store.getValues(_10,_11);
+if(_12.length<2){
+_12=this.store.getValue(_10,_11);
+}
+return _12;
+},onData:function(_13){
+if(!_13.length){
+return;
+}
+if(this.items&&this.items.length!=_13.length){
+dojo.forEach(_13,function(m){
+var id=this.getProperty(m,"id");
+dojo.forEach(this.items,function(m2,i){
+if(this.getProperty(m2,"id")==id){
+this.items[i]=m2;
+}
+},this);
+},this);
+_13=this.items;
+}
+if(this.stretchToFit){
+this.displayRange=_13.length;
+}
+this.onDataReceived(_13);
+this.items=_13;
+if(this.comparative){
+var nm="default";
+this.seriesData[nm]=[];
+this.seriesDataBk[nm]=[];
+dojo.forEach(_13,function(m,i){
+var _1b=this.getProperty(m,this.fieldName);
+this.seriesData[nm].push(_1b);
+},this);
+}else{
+dojo.forEach(_13,function(m,i){
+var nm=this.store.getLabel(m);
+if(!this.seriesData[nm]){
+this.seriesData[nm]=[];
+this.seriesDataBk[nm]=[];
+}
+var _1f=this.getProperty(m,this.fieldName);
+if(dojo.isArray(_1f)){
+this.seriesData[nm]=_1f;
+}else{
+if(!this.scroll){
+var ar=dojo.map(new Array(i+1),function(){
+return 0;
+});
+ar.push(Number(_1f));
+this.seriesData[nm]=ar;
+}else{
+if(this.seriesDataBk[nm].length>this.seriesData[nm].length){
+this.seriesData[nm]=this.seriesDataBk[nm];
+}
+this.seriesData[nm].push(Number(_1f));
+}
+this.seriesDataBk[nm].push(Number(_1f));
+}
+},this);
+}
+var _21;
+if(this.firstRun){
+this.firstRun=false;
+for(nm in this.seriesData){
+this.addSeries(nm,this.seriesData[nm]);
+_21=this.seriesData[nm];
+}
+}else{
+for(nm in this.seriesData){
+_21=this.seriesData[nm];
+if(this.scroll&&_21.length>this.displayRange){
+this.dataOffset=_21.length-this.displayRange-1;
+_21=_21.slice(_21.length-this.displayRange,_21.length);
+}
+this.updateSeries(nm,_21);
+}
+}
+this.dataLength=_21.length;
+if(this.showing){
+this.render();
+}
+},fetch:function(){
+if(!this.store){
+return;
+}
+this.store.fetch({query:this.query,queryOptions:this.queryOptions,start:this.start,count:this.count,sort:this.sort,onComplete:dojo.hitch(this,"onData"),onError:dojo.hitch(this,"onError")});
+},convertLabels:function(_22){
+if(!_22.labels||dojo.isObject(_22.labels[0])){
+return null;
+}
+_22.labels=dojo.map(_22.labels,function(ele,i){
+return {value:i,text:ele};
+});
+return null;
+},seriesLabels:function(val){
+val--;
+if(this.series.length<1||(!this.comparative&&val>this.series.length)){
+return "-";
+}
+if(this.comparative){
+return this.store.getLabel(this.items[val]);
+}else{
+for(var i=0;i<this.series.length;i++){
+if(this.series[i].data[val]>0){
+return this.series[i].name;
+}
+}
+}
+return "-";
+},resizeChart:function(dim){
+var w=Math.max(dim.w,this.minWidth);
+var h=Math.max(dim.h,this.minHeight);
+this.resize(w,h);
+}});
+})();
+}
diff --git a/dojox/charting/Element.js b/dojox/charting/Element.js
new file mode 100644
index 0000000..70268f3
--- /dev/null
+++ b/dojox/charting/Element.js
@@ -0,0 +1,53 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.Element"]){
+dojo._hasResource["dojox.charting.Element"]=true;
+dojo.provide("dojox.charting.Element");
+dojo.declare("dojox.charting.Element",null,{constructor:function(_1){
+this.chart=_1;
+this.group=null;
+this.htmlElements=[];
+this.dirty=true;
+},createGroup:function(_2){
+if(!_2){
+_2=this.chart.surface;
+}
+if(!this.group){
+this.group=_2.createGroup();
+}
+return this;
+},purgeGroup:function(){
+this.destroyHtmlElements();
+if(this.group){
+this.group.clear();
+this.group.removeShape();
+this.group=null;
+}
+this.dirty=true;
+return this;
+},cleanGroup:function(_3){
+this.destroyHtmlElements();
+if(!_3){
+_3=this.chart.surface;
+}
+if(this.group){
+this.group.clear();
+}else{
+this.group=_3.createGroup();
+}
+this.dirty=true;
+return this;
+},destroyHtmlElements:function(){
+if(this.htmlElements.length){
+dojo.forEach(this.htmlElements,dojo.destroy);
+this.htmlElements=[];
+}
+},destroy:function(){
+this.purgeGroup();
+}});
+}
diff --git a/dojox/charting/README b/dojox/charting/README
new file mode 100644
index 0000000..0858f3a
--- /dev/null
+++ b/dojox/charting/README
@@ -0,0 +1,31 @@
+-------------------------------------------------------------------------------
+dojox.charting
+-------------------------------------------------------------------------------
+Version 0.800
+Release date: 10/31/2007
+-------------------------------------------------------------------------------
+Project state:
+beta
+-------------------------------------------------------------------------------
+Credits
+	Tom Trenka (ttrenka at gmail.com)
+	Eugene Lazutkin (eugene.lazutkin at gmail.com)
+-------------------------------------------------------------------------------
+Project description
+
+Implementation of simple charting library based on dojox.gfx/dojox.gfx3d.
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo Core, dojox.gfx, dojox.gfx3d, dojox.lang.
+-------------------------------------------------------------------------------
+Documentation
+
+Not ready yet.
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/
+-------------------------------------------------------------------------------
diff --git a/dojox/charting/Series.js b/dojox/charting/Series.js
new file mode 100644
index 0000000..19b2038
--- /dev/null
+++ b/dojox/charting/Series.js
@@ -0,0 +1,23 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.Series"]){
+dojo._hasResource["dojox.charting.Series"]=true;
+dojo.provide("dojox.charting.Series");
+dojo.require("dojox.charting.Element");
+dojo.declare("dojox.charting.Series",dojox.charting.Element,{constructor:function(_1,_2,_3){
+dojo.mixin(this,_3);
+if(typeof this.plot!="string"){
+this.plot="default";
+}
+this.data=_2;
+this.dirty=true;
+this.clear();
+},clear:function(){
+this.dyn={};
+}});
+}
diff --git a/dojox/charting/Theme.js b/dojox/charting/Theme.js
new file mode 100644
index 0000000..075a367
--- /dev/null
+++ b/dojox/charting/Theme.js
@@ -0,0 +1,82 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.Theme"]){
+dojo._hasResource["dojox.charting.Theme"]=true;
+dojo.provide("dojox.charting.Theme");
+dojo.require("dojox.color");
+dojo.require("dojox.color.Palette");
+(function(){
+var _1=dojox.charting;
+_1.Theme=function(_2){
+_2=_2||{};
+var _3=_1.Theme._def;
+dojo.forEach(["chart","plotarea","axis","series","marker"],function(n){
+this[n]=dojo.delegate(_3[n],_2[n]||{});
+},this);
+this.markers=dojo.delegate(_1.Theme.Markers,_2.markers||{});
+this.colors=[];
+this.antiAlias=("antiAlias" in _2)?_2.antiAlias:true;
+this.assignColors=("assignColors" in _2)?_2.assignColors:true;
+this.assignMarkers=("assignMarkers" in _2)?_2.assignMarkers:true;
+_2.colors=_2.colors||_3.colors;
+dojo.forEach(_2.colors,function(_5){
+this.colors.push(_5);
+},this);
+this._current={color:0,marker:0};
+this._markers=[];
+this._buildMarkerArray();
+};
+_1.Theme.Markers={CIRCLE:"m-3,0 c0,-4 6,-4 6,0 m-6,0 c0,4 6,4 6,0",SQUARE:"m-3,-3 l0,6 6,0 0,-6 z",DIAMOND:"m0,-3 l3,3 -3,3 -3,-3 z",CROSS:"m0,-3 l0,6 m-3,-3 l6,0",X:"m-3,-3 l6,6 m0,-6 l-6,6",TRIANGLE:"m-3,3 l3,-6 3,6 z",TRIANGLE_INVERTED:"m-3,-3 l3,6 3,-6 z"};
+_1.Theme._def={chart:{stroke:null,fill:"white"},plotarea:{stroke:null,fill:"white"},axis:{stroke:{color:"#333",width:1},majorTick:{color:"#666",width:1,length:6,position:"center"},minorTick:{color:"#666",width:0.8,length:3,position:"center"},font:"normal normal normal 7pt Tahoma",fontColor:"#333"},series:{outline:{width:0.1,color:"#ccc"},stroke:{width:1.5,color:"#333"},fill:"#ccc",font:"normal normal normal 7pt Tahoma",fontColor:"#000"},marker:{stroke:{width:1},fill:"#333",font:"normal n [...]
+dojo.extend(_1.Theme,{defineColors:function(_6){
+var _7=_6||{};
+var c=[],n=_7.num||5;
+if(_7.colors){
+var l=_7.colors.length;
+for(var i=0;i<n;i++){
+c.push(_7.colors[i%l]);
+}
+this.colors=c;
+}else{
+if(_7.hue){
+var s=_7.saturation||100;
+var st=_7.low||30;
+var _e=_7.high||90;
+var l=(_e+st)/2;
+this.colors=dojox.color.Palette.generate(dojox.color.fromHsv(_7.hue,s,l),"monochromatic").colors;
+}else{
+if(_7.generator){
+this.colors=dojox.color.Palette.generate(_7.base,_7.generator).colors;
+}
+}
+}
+},_buildMarkerArray:function(){
+this._markers=[];
+for(var p in this.markers){
+this._markers.push(this.markers[p]);
+}
+this._current.marker=0;
+},_clone:function(){
+return new _1.Theme({chart:this.chart,plotarea:this.plotarea,axis:this.axis,series:this.series,marker:this.marker,antiAlias:this.antiAlias,assignColors:this.assignColors,assignMarkers:this.assigneMarkers,colors:dojo.delegate(this.colors)});
+},addMarker:function(_10,_11){
+this.markers[_10]=_11;
+this._buildMarkerArray();
+},setMarkers:function(obj){
+this.markers=obj;
+this._buildMarkerArray();
+},next:function(_13){
+if(_13=="marker"){
+return this._markers[this._current.marker++%this._markers.length];
+}else{
+return this.colors[this._current.color++%this.colors.length];
+}
+},clear:function(){
+this._current={color:0,marker:0};
+}});
+})();
+}
diff --git a/dojox/charting/action2d/Base.js b/dojox/charting/action2d/Base.js
new file mode 100644
index 0000000..222d75e
--- /dev/null
+++ b/dojox/charting/action2d/Base.js
@@ -0,0 +1,45 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.action2d.Base"]){
+dojo._hasResource["dojox.charting.action2d.Base"]=true;
+dojo.provide("dojox.charting.action2d.Base");
+dojo.require("dojo.fx.easing");
+dojo.require("dojox.lang.functional.object");
+dojo.require("dojox.gfx.fx");
+(function(){
+var _1=400,_2=dojo.fx.easing.backOut,df=dojox.lang.functional;
+dojo.declare("dojox.charting.action2d.Base",null,{overOutEvents:{onmouseover:1,onmouseout:1},constructor:function(_4,_5,_6){
+this.chart=_4;
+this.plot=_5?_5:"default";
+this.anim={};
+if(!_6){
+_6={};
+}
+this.duration=_6.duration?_6.duration:_1;
+this.easing=_6.easing?_6.easing:_2;
+},connect:function(){
+this.handle=this.chart.connectToPlot(this.plot,this,"process");
+},disconnect:function(){
+if(this.handle){
+dojo.disconnect(this.handle);
+this.handle=null;
+}
+},reset:function(){
+},destroy:function(){
+if(this.handle){
+this.disconnect();
+}
+df.forIn(this.anim,function(o){
+df.forIn(o,function(_8){
+_8.action.stop(true);
+});
+});
+this.anim={};
+}});
+})();
+}
diff --git a/dojox/charting/action2d/Highlight.js b/dojox/charting/action2d/Highlight.js
new file mode 100644
index 0000000..d602ae7
--- /dev/null
+++ b/dojox/charting/action2d/Highlight.js
@@ -0,0 +1,76 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.action2d.Highlight"]){
+dojo._hasResource["dojox.charting.action2d.Highlight"]=true;
+dojo.provide("dojox.charting.action2d.Highlight");
+dojo.require("dojox.charting.action2d.Base");
+dojo.require("dojox.color");
+(function(){
+var _1=100,_2=75,_3=50,c=dojox.color,cc=function(_6){
+return function(){
+return _6;
+};
+},hl=function(_8){
+var a=new c.Color(_8),x=a.toHsl();
+if(x.s==0){
+x.l=x.l<50?100:0;
+}else{
+x.s=_1;
+if(x.l<_3){
+x.l=_2;
+}else{
+if(x.l>_2){
+x.l=_3;
+}else{
+x.l=x.l-_3>_2-x.l?_3:_2;
+}
+}
+}
+return c.fromHsl(x);
+};
+dojo.declare("dojox.charting.action2d.Highlight",dojox.charting.action2d.Base,{defaultParams:{duration:400,easing:dojo.fx.easing.backOut},optionalParams:{highlight:"red"},constructor:function(_b,_c,_d){
+var a=_d&&_d.highlight;
+this.colorFun=a?(dojo.isFunction(a)?a:cc(a)):hl;
+this.connect();
+},process:function(o){
+if(!o.shape||!(o.type in this.overOutEvents)){
+return;
+}
+var _10=o.run.name,_11=o.index,_12,_13,_14;
+if(_10 in this.anim){
+_12=this.anim[_10][_11];
+}else{
+this.anim[_10]={};
+}
+if(_12){
+_12.action.stop(true);
+}else{
+var _15=o.shape.getFill();
+if(!_15||!(_15 instanceof dojo.Color)){
+return;
+}
+this.anim[_10][_11]=_12={start:_15,end:this.colorFun(_15)};
+}
+var _16=_12.start,end=_12.end;
+if(o.type=="onmouseout"){
+var t=_16;
+_16=end;
+end=t;
+}
+_12.action=dojox.gfx.fx.animateFill({shape:o.shape,duration:this.duration,easing:this.easing,color:{start:_16,end:end}});
+if(o.type=="onmouseout"){
+dojo.connect(_12.action,"onEnd",this,function(){
+if(this.anim[_10]){
+delete this.anim[_10][_11];
+}
+});
+}
+_12.action.play();
+}});
+})();
+}
diff --git a/dojox/charting/action2d/Magnify.js b/dojox/charting/action2d/Magnify.js
new file mode 100644
index 0000000..f3f42b7
--- /dev/null
+++ b/dojox/charting/action2d/Magnify.js
@@ -0,0 +1,68 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.action2d.Magnify"]){
+dojo._hasResource["dojox.charting.action2d.Magnify"]=true;
+dojo.provide("dojox.charting.action2d.Magnify");
+dojo.require("dojox.charting.action2d.Base");
+dojo.require("dojox.gfx.matrix");
+dojo.require("dojo.fx");
+(function(){
+var _1=2,m=dojox.gfx.matrix,gf=dojox.gfx.fx;
+dojo.declare("dojox.charting.action2d.Magnify",dojox.charting.action2d.Base,{defaultParams:{duration:400,easing:dojo.fx.easing.backOut,scale:_1},optionalParams:{},constructor:function(_4,_5,_6){
+this.scale=_6&&typeof _6.scale=="number"?_6.scale:_1;
+this.connect();
+},process:function(o){
+if(!o.shape||!(o.type in this.overOutEvents)||!("cx" in o)||!("cy" in o)){
+return;
+}
+var _8=o.run.name,_9=o.index,_a=[],_b,_c,_d;
+if(_8 in this.anim){
+_b=this.anim[_8][_9];
+}else{
+this.anim[_8]={};
+}
+if(_b){
+_b.action.stop(true);
+}else{
+this.anim[_8][_9]=_b={};
+}
+if(o.type=="onmouseover"){
+_c=m.identity;
+_d=this.scale;
+}else{
+_c=m.scaleAt(this.scale,o.cx,o.cy);
+_d=1/this.scale;
+}
+var _e={shape:o.shape,duration:this.duration,easing:this.easing,transform:[{name:"scaleAt",start:[1,o.cx,o.cy],end:[_d,o.cx,o.cy]},_c]};
+if(o.shape){
+_a.push(gf.animateTransform(_e));
+}
+if(o.oultine){
+_e.shape=o.outline;
+_a.push(gf.animateTransform(_e));
+}
+if(o.shadow){
+_e.shape=o.shadow;
+_a.push(gf.animateTransform(_e));
+}
+if(!_a.length){
+delete this.anim[_8][_9];
+return;
+}
+_b.action=dojo.fx.combine(_a);
+if(o.type=="onmouseout"){
+dojo.connect(_b.action,"onEnd",this,function(){
+if(this.anim[_8]){
+delete this.anim[_8][_9];
+}
+});
+}
+_b.action.play();
+}});
+})();
+}
diff --git a/dojox/charting/action2d/MoveSlice.js b/dojox/charting/action2d/MoveSlice.js
new file mode 100644
index 0000000..bdcf8c7
--- /dev/null
+++ b/dojox/charting/action2d/MoveSlice.js
@@ -0,0 +1,63 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.action2d.MoveSlice"]){
+dojo._hasResource["dojox.charting.action2d.MoveSlice"]=true;
+dojo.provide("dojox.charting.action2d.MoveSlice");
+dojo.require("dojox.charting.action2d.Base");
+dojo.require("dojox.gfx.matrix");
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.functional.scan");
+dojo.require("dojox.lang.functional.fold");
+(function(){
+var _1=1.05,_2=7,m=dojox.gfx.matrix,gf=dojox.gfx.fx,df=dojox.lang.functional;
+dojo.declare("dojox.charting.action2d.MoveSlice",dojox.charting.action2d.Base,{defaultParams:{duration:400,easing:dojo.fx.easing.backOut,scale:_1,shift:_2},optionalParams:{},constructor:function(_6,_7,_8){
+if(!_8){
+_8={};
+}
+this.scale=typeof _8.scale=="number"?_8.scale:_1;
+this.shift=typeof _8.shift=="number"?_8.shift:_2;
+this.connect();
+},process:function(o){
+if(!o.shape||o.element!="slice"||!(o.type in this.overOutEvents)){
+return;
+}
+if(!this.angles){
+if(typeof o.run.data[0]=="number"){
+this.angles=df.map(df.scanl(o.run.data,"+",0),"* 2 * Math.PI / this",df.foldl(o.run.data,"+",0));
+}else{
+this.angles=df.map(df.scanl(o.run.data,"a + b.y",0),"* 2 * Math.PI / this",df.foldl(o.run.data,"a + b.y",0));
+}
+}
+var _a=o.index,_b,_c,_d,_e,_f=(this.angles[_a]+this.angles[_a+1])/2,_10=m.rotateAt(-_f,o.cx,o.cy),_11=m.rotateAt(_f,o.cx,o.cy);
+_b=this.anim[_a];
+if(_b){
+_b.action.stop(true);
+}else{
+this.anim[_a]=_b={};
+}
+if(o.type=="onmouseover"){
+_d=0;
+_e=this.shift;
+_c=this.scale;
+}else{
+_d=this.shift;
+_e=0;
+_c=1/this.scale;
+}
+_b.action=dojox.gfx.fx.animateTransform({shape:o.shape,duration:this.duration,easing:this.easing,transform:[_11,{name:"translate",start:[_d,0],end:[_e,0]},{name:"scaleAt",start:[1,o.cx,o.cy],end:[_c,o.cx,o.cy]},_10]});
+if(o.type=="onmouseout"){
+dojo.connect(_b.action,"onEnd",this,function(){
+delete this.anim[_a];
+});
+}
+_b.action.play();
+},reset:function(){
+delete this.angles;
+}});
+})();
+}
diff --git a/dojox/charting/action2d/Shake.js b/dojox/charting/action2d/Shake.js
new file mode 100644
index 0000000..45cc082
--- /dev/null
+++ b/dojox/charting/action2d/Shake.js
@@ -0,0 +1,65 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.action2d.Shake"]){
+dojo._hasResource["dojox.charting.action2d.Shake"]=true;
+dojo.provide("dojox.charting.action2d.Shake");
+dojo.require("dojox.charting.action2d.Base");
+dojo.require("dojox.gfx.matrix");
+dojo.require("dojo.fx");
+(function(){
+var _1=3,m=dojox.gfx.matrix,gf=dojox.gfx.fx;
+dojo.declare("dojox.charting.action2d.Shake",dojox.charting.action2d.Base,{defaultParams:{duration:400,easing:dojo.fx.easing.backOut,shiftX:_1,shiftY:_1},optionalParams:{},constructor:function(_4,_5,_6){
+if(!_6){
+_6={};
+}
+this.shiftX=typeof _6.shiftX=="number"?_6.shiftX:_1;
+this.shiftY=typeof _6.shiftY=="number"?_6.shiftY:_1;
+this.connect();
+},process:function(o){
+if(!o.shape||!(o.type in this.overOutEvents)){
+return;
+}
+var _8=o.run.name,_9=o.index,_a=[],_b,_c=o.type=="onmouseover"?this.shiftX:-this.shiftX,_d=o.type=="onmouseover"?this.shiftY:-this.shiftY;
+if(_8 in this.anim){
+_b=this.anim[_8][_9];
+}else{
+this.anim[_8]={};
+}
+if(_b){
+_b.action.stop(true);
+}else{
+this.anim[_8][_9]=_b={};
+}
+var _e={shape:o.shape,duration:this.duration,easing:this.easing,transform:[{name:"translate",start:[this.shiftX,this.shiftY],end:[0,0]},m.identity]};
+if(o.shape){
+_a.push(gf.animateTransform(_e));
+}
+if(o.oultine){
+_e.shape=o.outline;
+_a.push(gf.animateTransform(_e));
+}
+if(o.shadow){
+_e.shape=o.shadow;
+_a.push(gf.animateTransform(_e));
+}
+if(!_a.length){
+delete this.anim[_8][_9];
+return;
+}
+_b.action=dojo.fx.combine(_a);
+if(o.type=="onmouseout"){
+dojo.connect(_b.action,"onEnd",this,function(){
+if(this.anim[_8]){
+delete this.anim[_8][_9];
+}
+});
+}
+_b.action.play();
+}});
+})();
+}
diff --git a/dojox/charting/action2d/Tooltip.js b/dojox/charting/action2d/Tooltip.js
new file mode 100644
index 0000000..a57958a
--- /dev/null
+++ b/dojox/charting/action2d/Tooltip.js
@@ -0,0 +1,93 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.action2d.Tooltip"]){
+dojo._hasResource["dojox.charting.action2d.Tooltip"]=true;
+dojo.provide("dojox.charting.action2d.Tooltip");
+dojo.require("dojox.charting.action2d.Base");
+dojo.require("dijit.Tooltip");
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.functional.scan");
+dojo.require("dojox.lang.functional.fold");
+(function(){
+var _1=function(o){
+var t=o.run&&o.run.data&&o.run.data[o.index];
+if(t&&typeof t=="object"&&t.tooltip){
+return t.tooltip;
+}
+return o.element=="bar"?o.x:o.y;
+};
+var df=dojox.lang.functional,_5=Math.PI/4,_6=Math.PI/2;
+dojo.declare("dojox.charting.action2d.Tooltip",dojox.charting.action2d.Base,{defaultParams:{text:_1},optionalParams:{},constructor:function(_7,_8,_9){
+this.text=_9&&_9.text?_9.text:_1;
+this.connect();
+},process:function(o){
+if(o.type==="onplotreset"||o.type==="onmouseout"){
+dijit.hideTooltip(this.aroundRect);
+this.aroundRect=null;
+return;
+}
+if(!o.shape||o.type!=="onmouseover"){
+return;
+}
+var _b={type:"rect"},_c=["after","before"];
+switch(o.element){
+case "marker":
+_b.x=o.cx;
+_b.y=o.cy;
+_b.width=_b.height=1;
+break;
+case "circle":
+_b.x=o.cx-o.cr;
+_b.y=o.cy-o.cr;
+_b.width=_b.height=2*o.cr;
+break;
+case "column":
+_c=["above","below"];
+case "bar":
+_b=dojo.clone(o.shape.getShape());
+break;
+default:
+if(!this.angles){
+if(typeof o.run.data[0]=="number"){
+this.angles=df.map(df.scanl(o.run.data,"+",0),"* 2 * Math.PI / this",df.foldl(o.run.data,"+",0));
+}else{
+this.angles=df.map(df.scanl(o.run.data,"a + b.y",0),"* 2 * Math.PI / this",df.foldl(o.run.data,"a + b.y",0));
+}
+}
+var _d=(this.angles[o.index]+this.angles[o.index+1])/2;
+_b.x=o.cx+o.cr*Math.cos(_d);
+_b.y=o.cy+o.cr*Math.sin(_d);
+_b.width=_b.height=1;
+if(_d<_5){
+}else{
+if(_d<_6+_5){
+_c=["below","above"];
+}else{
+if(_d<Math.PI+_5){
+_c=["before","after"];
+}else{
+if(_d<2*Math.PI-_5){
+_c=["above","below"];
+}
+}
+}
+}
+break;
+}
+var lt=dojo.coords(this.chart.node,true);
+_b.x+=lt.x;
+_b.y+=lt.y;
+_b.x=Math.round(_b.x);
+_b.y=Math.round(_b.y);
+_b.width=Math.ceil(_b.width);
+_b.height=Math.ceil(_b.height);
+this.aroundRect=_b;
+dijit.showTooltip(this.text(o),this.aroundRect,_c);
+}});
+})();
+}
diff --git a/dojox/charting/axis2d/Base.js b/dojox/charting/axis2d/Base.js
new file mode 100644
index 0000000..f03e903
--- /dev/null
+++ b/dojox/charting/axis2d/Base.js
@@ -0,0 +1,29 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.axis2d.Base"]){
+dojo._hasResource["dojox.charting.axis2d.Base"]=true;
+dojo.provide("dojox.charting.axis2d.Base");
+dojo.require("dojox.charting.Element");
+dojo.declare("dojox.charting.axis2d.Base",dojox.charting.Element,{constructor:function(_1,_2){
+this.vertical=_2&&_2.vertical;
+},clear:function(){
+return this;
+},initialized:function(){
+return false;
+},calculate:function(_3,_4,_5){
+return this;
+},getScaler:function(){
+return null;
+},getTicks:function(){
+return null;
+},getOffsets:function(){
+return {l:0,r:0,t:0,b:0};
+},render:function(_6,_7){
+return this;
+}});
+}
diff --git a/dojox/charting/axis2d/Default.js b/dojox/charting/axis2d/Default.js
new file mode 100644
index 0000000..62c0bac
--- /dev/null
+++ b/dojox/charting/axis2d/Default.js
@@ -0,0 +1,242 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.axis2d.Default"]){
+dojo._hasResource["dojox.charting.axis2d.Default"]=true;
+dojo.provide("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.scaler.linear");
+dojo.require("dojox.charting.axis2d.common");
+dojo.require("dojox.charting.axis2d.Base");
+dojo.require("dojo.colors");
+dojo.require("dojo.string");
+dojo.require("dojox.gfx");
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.utils");
+(function(){
+var dc=dojox.charting,df=dojox.lang.functional,du=dojox.lang.utils,g=dojox.gfx,_5=dc.scaler.linear,_6=4;
+dojo.declare("dojox.charting.axis2d.Default",dojox.charting.axis2d.Base,{defaultParams:{vertical:false,fixUpper:"none",fixLower:"none",natural:false,leftBottom:true,includeZero:false,fixed:true,majorLabels:true,minorTicks:true,minorLabels:true,microTicks:false,htmlLabels:true},optionalParams:{min:0,max:1,from:0,to:1,majorTickStep:4,minorTickStep:2,microTickStep:1,labels:[],labelFunc:null,maxLabelSize:0,stroke:{},majorTick:{},minorTick:{},microTick:{},font:"",fontColor:""},constructor:fun [...]
+this.opt=dojo.delegate(this.defaultParams,_8);
+du.updateWithPattern(this.opt,_8,this.optionalParams);
+},dependOnData:function(){
+return !("min" in this.opt)||!("max" in this.opt);
+},clear:function(){
+delete this.scaler;
+delete this.ticks;
+this.dirty=true;
+return this;
+},initialized:function(){
+return "scaler" in this&&!(this.dirty&&this.dependOnData());
+},setWindow:function(_9,_a){
+this.scale=_9;
+this.offset=_a;
+return this.clear();
+},getWindowScale:function(){
+return "scale" in this?this.scale:1;
+},getWindowOffset:function(){
+return "offset" in this?this.offset:0;
+},calculate:function(_b,_c,_d,_e){
+if(this.initialized()){
+return this;
+}
+this.labels="labels" in this.opt?this.opt.labels:_e;
+this.scaler=_5.buildScaler(_b,_c,_d,this.opt);
+if("scale" in this){
+this.opt.from=this.scaler.bounds.lower+this.offset;
+this.opt.to=(this.scaler.bounds.upper-this.scaler.bounds.lower)/this.scale+this.opt.from;
+if(!isFinite(this.opt.from)||isNaN(this.opt.from)||!isFinite(this.opt.to)||isNaN(this.opt.to)||this.opt.to-this.opt.from>=this.scaler.bounds.upper-this.scaler.bounds.lower){
+delete this.opt.from;
+delete this.opt.to;
+delete this.scale;
+delete this.offset;
+}else{
+if(this.opt.from<this.scaler.bounds.lower){
+this.opt.to+=this.scaler.bounds.lower-this.opt.from;
+this.opt.from=this.scaler.bounds.lower;
+}else{
+if(this.opt.to>this.scaler.bounds.upper){
+this.opt.from+=this.scaler.bounds.upper-this.opt.to;
+this.opt.to=this.scaler.bounds.upper;
+}
+}
+this.offset=this.opt.from-this.scaler.bounds.lower;
+}
+this.scaler=_5.buildScaler(_b,_c,_d,this.opt);
+if(this.scale==1&&this.offset==0){
+delete this.scale;
+delete this.offset;
+}
+}
+var _f=0,ta=this.chart.theme.axis,_11="font" in this.opt?this.opt.font:ta.font,_12=_11?g.normalizedLength(g.splitFontString(_11).size):0;
+if(this.vertical){
+if(_12){
+_f=_12+_6;
+}
+}else{
+if(_12){
+var _13,i;
+if(this.opt.labelFunc&&this.opt.maxLabelSize){
+_13=this.opt.maxLabelSize;
+}else{
+if(this.labels){
+_13=df.foldl(df.map(this.labels,function(_15){
+return dojox.gfx._base._getTextBox(_15.text,{font:_11}).w;
+}),"Math.max(a, b)",0);
+}else{
+var _16=Math.ceil(Math.log(Math.max(Math.abs(this.scaler.bounds.from),Math.abs(this.scaler.bounds.to)))/Math.LN10),t=[];
+if(this.scaler.bounds.from<0||this.scaler.bounds.to<0){
+t.push("-");
+}
+t.push(dojo.string.rep("9",_16));
+var _18=Math.floor(Math.log(this.scaler.bounds.to-this.scaler.bounds.from)/Math.LN10);
+if(_18>0){
+t.push(".");
+for(i=0;i<_18;++i){
+t.push("9");
+}
+}
+_13=dojox.gfx._base._getTextBox(t.join(""),{font:_11}).w;
+}
+}
+_f=_13+_6;
+}
+}
+this.scaler.minMinorStep=_f;
+this.ticks=_5.buildTicks(this.scaler,this.opt);
+return this;
+},getScaler:function(){
+return this.scaler;
+},getTicks:function(){
+return this.ticks;
+},getOffsets:function(){
+var _19={l:0,r:0,t:0,b:0},_1a,a,b,c,d,gtb=dojox.gfx._base._getTextBox,gl=dc.scaler.common.getNumericLabel,_21=0,ta=this.chart.theme.axis,_23="font" in this.opt?this.opt.font:ta.font,_24="majorTick" in this.opt?this.opt.majorTick:ta.majorTick,_25="minorTick" in this.opt?this.opt.minorTick:ta.minorTick,_26=_23?g.normalizedLength(g.splitFontString(_23).size):0,s=this.scaler;
+if(!s){
+return _19;
+}
+if(this.vertical){
+if(_26){
+if(this.opt.labelFunc&&this.opt.maxLabelSize){
+_1a=this.opt.maxLabelSize;
+}else{
+if(this.labels){
+_1a=df.foldl(df.map(this.labels,function(_28){
+return dojox.gfx._base._getTextBox(_28.text,{font:_23}).w;
+}),"Math.max(a, b)",0);
+}else{
+a=gtb(gl(s.major.start,s.major.prec,this.opt),{font:_23}).w;
+b=gtb(gl(s.major.start+s.major.count*s.major.tick,s.major.prec,this.opt),{font:_23}).w;
+c=gtb(gl(s.minor.start,s.minor.prec,this.opt),{font:_23}).w;
+d=gtb(gl(s.minor.start+s.minor.count*s.minor.tick,s.minor.prec,this.opt),{font:_23}).w;
+_1a=Math.max(a,b,c,d);
+}
+}
+_21=_1a+_6;
+}
+_21+=_6+Math.max(_24.length,_25.length);
+_19[this.opt.leftBottom?"l":"r"]=_21;
+_19.t=_19.b=_26/2;
+}else{
+if(_26){
+_21=_26+_6;
+}
+_21+=_6+Math.max(_24.length,_25.length);
+_19[this.opt.leftBottom?"b":"t"]=_21;
+if(_26){
+if(this.opt.labelFunc&&this.opt.maxLabelSize){
+_1a=this.opt.maxLabelSize;
+}else{
+if(this.labels){
+_1a=df.foldl(df.map(this.labels,function(_29){
+return dojox.gfx._base._getTextBox(_29.text,{font:_23}).w;
+}),"Math.max(a, b)",0);
+}else{
+a=gtb(gl(s.major.start,s.major.prec,this.opt),{font:_23}).w;
+b=gtb(gl(s.major.start+s.major.count*s.major.tick,s.major.prec,this.opt),{font:_23}).w;
+c=gtb(gl(s.minor.start,s.minor.prec,this.opt),{font:_23}).w;
+d=gtb(gl(s.minor.start+s.minor.count*s.minor.tick,s.minor.prec,this.opt),{font:_23}).w;
+_1a=Math.max(a,b,c,d);
+}
+}
+_19.l=_19.r=_1a/2;
+}
+}
+return _19;
+},render:function(dim,_2b){
+if(!this.dirty){
+return this;
+}
+var _2c,_2d,_2e,_2f,_30,_31,ta=this.chart.theme.axis,_33="stroke" in this.opt?this.opt.stroke:ta.stroke,_34="majorTick" in this.opt?this.opt.majorTick:ta.majorTick,_35="minorTick" in this.opt?this.opt.minorTick:ta.minorTick,_36="microTick" in this.opt?this.opt.microTick:ta.minorTick,_37="font" in this.opt?this.opt.font:ta.font,_38="fontColor" in this.opt?this.opt.fontColor:ta.fontColor,_39=Math.max(_34.length,_35.length),_3a=_37?g.normalizedLength(g.splitFontString(_37).size):0;
+if(this.vertical){
+_2c={y:dim.height-_2b.b};
+_2d={y:_2b.t};
+_2e={x:0,y:-1};
+if(this.opt.leftBottom){
+_2c.x=_2d.x=_2b.l;
+_2f={x:-1,y:0};
+_31="end";
+}else{
+_2c.x=_2d.x=dim.width-_2b.r;
+_2f={x:1,y:0};
+_31="start";
+}
+_30={x:_2f.x*(_39+_6),y:_3a*0.4};
+}else{
+_2c={x:_2b.l};
+_2d={x:dim.width-_2b.r};
+_2e={x:1,y:0};
+_31="middle";
+if(this.opt.leftBottom){
+_2c.y=_2d.y=dim.height-_2b.b;
+_2f={x:0,y:1};
+_30={y:_39+_6+_3a};
+}else{
+_2c.y=_2d.y=_2b.t;
+_2f={x:0,y:-1};
+_30={y:-_39-_6};
+}
+_30.x=0;
+}
+this.cleanGroup();
+try{
+var s=this.group,c=this.scaler,t=this.ticks,_3e,f=_5.getTransformerFromModel(this.scaler),_40=dojox.gfx.renderer=="canvas",_41=_40||this.opt.htmlLabels&&!dojo.isIE&&!dojo.isOpera?"html":"gfx",dx=_2f.x*_34.length,dy=_2f.y*_34.length;
+s.createLine({x1:_2c.x,y1:_2c.y,x2:_2d.x,y2:_2d.y}).setStroke(_33);
+dojo.forEach(t.major,function(_44){
+var _45=f(_44.value),_46,x=_2c.x+_2e.x*_45,y=_2c.y+_2e.y*_45;
+s.createLine({x1:x,y1:y,x2:x+dx,y2:y+dy}).setStroke(_34);
+if(_44.label){
+_46=dc.axis2d.common.createText[_41](this.chart,s,x+_30.x,y+_30.y,_31,_44.label,_37,_38);
+if(_41=="html"){
+this.htmlElements.push(_46);
+}
+}
+},this);
+dx=_2f.x*_35.length;
+dy=_2f.y*_35.length;
+_3e=c.minMinorStep<=c.minor.tick*c.bounds.scale;
+dojo.forEach(t.minor,function(_49){
+var _4a=f(_49.value),_4b,x=_2c.x+_2e.x*_4a,y=_2c.y+_2e.y*_4a;
+s.createLine({x1:x,y1:y,x2:x+dx,y2:y+dy}).setStroke(_35);
+if(_3e&&_49.label){
+_4b=dc.axis2d.common.createText[_41](this.chart,s,x+_30.x,y+_30.y,_31,_49.label,_37,_38);
+if(_41=="html"){
+this.htmlElements.push(_4b);
+}
+}
+},this);
+dx=_2f.x*_36.length;
+dy=_2f.y*_36.length;
+dojo.forEach(t.micro,function(_4e){
+var _4f=f(_4e.value),_50,x=_2c.x+_2e.x*_4f,y=_2c.y+_2e.y*_4f;
+s.createLine({x1:x,y1:y,x2:x+dx,y2:y+dy}).setStroke(_36);
+},this);
+}
+catch(e){
+}
+this.dirty=false;
+return this;
+}});
+})();
+}
diff --git a/dojox/charting/axis2d/common.js b/dojox/charting/axis2d/common.js
new file mode 100644
index 0000000..f0b5f90
--- /dev/null
+++ b/dojox/charting/axis2d/common.js
@@ -0,0 +1,63 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.axis2d.common"]){
+dojo._hasResource["dojox.charting.axis2d.common"]=true;
+dojo.provide("dojox.charting.axis2d.common");
+dojo.require("dojox.gfx");
+(function(){
+var g=dojox.gfx;
+function _2(s){
+s.marginLeft="0px";
+s.marginTop="0px";
+s.marginRight="0px";
+s.marginBottom="0px";
+s.paddingLeft="0px";
+s.paddingTop="0px";
+s.paddingRight="0px";
+s.paddingBottom="0px";
+s.borderLeftWidth="0px";
+s.borderTopWidth="0px";
+s.borderRightWidth="0px";
+s.borderBottomWidth="0px";
+};
+dojo.mixin(dojox.charting.axis2d.common,{createText:{gfx:function(_4,_5,x,y,_8,_9,_a,_b){
+return _5.createText({x:x,y:y,text:_9,align:_8}).setFont(_a).setFill(_b);
+},html:function(_c,_d,x,y,_10,_11,_12,_13){
+var p=dojo.doc.createElement("div"),s=p.style;
+_2(s);
+s.font=_12;
+p.innerHTML=String(_11).replace(/\s/g," ");
+s.color=_13;
+s.position="absolute";
+s.left="-10000px";
+dojo.body().appendChild(p);
+var _16=g.normalizedLength(g.splitFontString(_12).size),box=dojo.marginBox(p);
+dojo.body().removeChild(p);
+s.position="relative";
+switch(_10){
+case "middle":
+s.left=Math.floor(x-box.w/2)+"px";
+break;
+case "end":
+s.left=Math.floor(x-box.w)+"px";
+break;
+default:
+s.left=Math.floor(x)+"px";
+break;
+}
+s.top=Math.floor(y-_16)+"px";
+var _18=dojo.doc.createElement("div"),w=_18.style;
+_2(w);
+w.width="0px";
+w.height="0px";
+_18.appendChild(p);
+_c.node.insertBefore(_18,_c.node.firstChild);
+return _18;
+}}});
+})();
+}
diff --git a/dojox/charting/plot2d/Areas.js b/dojox/charting/plot2d/Areas.js
new file mode 100644
index 0000000..231ec8a
--- /dev/null
+++ b/dojox/charting/plot2d/Areas.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.Areas"]){
+dojo._hasResource["dojox.charting.plot2d.Areas"]=true;
+dojo.provide("dojox.charting.plot2d.Areas");
+dojo.require("dojox.charting.plot2d.Default");
+dojo.declare("dojox.charting.plot2d.Areas",dojox.charting.plot2d.Default,{constructor:function(){
+this.opt.lines=true;
+this.opt.areas=true;
+}});
+}
diff --git a/dojox/charting/plot2d/Bars.js b/dojox/charting/plot2d/Bars.js
new file mode 100644
index 0000000..a2dca87
--- /dev/null
+++ b/dojox/charting/plot2d/Bars.js
@@ -0,0 +1,78 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.Bars"]){
+dojo._hasResource["dojox.charting.plot2d.Bars"]=true;
+dojo.provide("dojox.charting.plot2d.Bars");
+dojo.require("dojox.charting.plot2d.common");
+dojo.require("dojox.charting.plot2d.Base");
+dojo.require("dojox.lang.utils");
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.functional.reversed");
+(function(){
+var df=dojox.lang.functional,du=dojox.lang.utils,dc=dojox.charting.plot2d.common,_4=df.lambda("item.purgeGroup()");
+dojo.declare("dojox.charting.plot2d.Bars",dojox.charting.plot2d.Base,{defaultParams:{hAxis:"x",vAxis:"y",gap:0,shadows:null},optionalParams:{minBarSize:1,maxBarSize:1},constructor:function(_5,_6){
+this.opt=dojo.clone(this.defaultParams);
+du.updateWithObject(this.opt,_6);
+du.updateWithPattern(this.opt,_6,this.optionalParams);
+this.series=[];
+this.hAxis=this.opt.hAxis;
+this.vAxis=this.opt.vAxis;
+},calculateAxes:function(_7){
+var _8=dc.collectSimpleStats(this.series),t;
+_8.hmin-=0.5;
+_8.hmax+=0.5;
+t=_8.hmin,_8.hmin=_8.vmin,_8.vmin=t;
+t=_8.hmax,_8.hmax=_8.vmax,_8.vmax=t;
+this._calc(_7,_8);
+return this;
+},render:function(_a,_b){
+this.dirty=this.isDirty();
+if(this.dirty){
+dojo.forEach(this.series,_4);
+this.cleanGroup();
+var s=this.group;
+df.forEachRev(this.series,function(_d){
+_d.cleanGroup(s);
+});
+}
+var t=this.chart.theme,_f,_10,_11,f,gap,_14,ht=this._hScaler.scaler.getTransformerFromModel(this._hScaler),vt=this._vScaler.scaler.getTransformerFromModel(this._vScaler),_17=Math.max(0,this._hScaler.bounds.lower),_18=ht(_17),_19=this.events();
+f=dc.calculateBarSize(this._vScaler.bounds.scale,this.opt);
+gap=f.gap;
+_14=f.size;
+this.resetEvents();
+for(var i=this.series.length-1;i>=0;--i){
+var run=this.series[i];
+if(!this.dirty&&!run.dirty){
+continue;
+}
+run.cleanGroup();
+var s=run.group;
+if(!run.fill||!run.stroke){
+_f=run.dyn.color=new dojo.Color(t.next("color"));
+}
+_10=run.stroke?run.stroke:dc.augmentStroke(t.series.stroke,_f);
+_11=run.fill?run.fill:dc.augmentFill(t.series.fill,_f);
+for(var j=0;j<run.data.length;++j){
+var v=run.data[j],hv=ht(v),_1f=hv-_18,w=Math.abs(_1f);
+if(w>=1&&_14>=1){
+var _21=s.createRect({x:_b.l+(v<_17?hv:_18),y:_a.height-_b.b-vt(j+1.5)+gap,width:w,height:_14}).setFill(_11).setStroke(_10);
+run.dyn.fill=_21.getFill();
+run.dyn.stroke=_21.getStroke();
+if(_19){
+var o={element:"bar",index:j,run:run,plot:this,hAxis:this.hAxis||null,vAxis:this.vAxis||null,shape:_21,x:v,y:j+1.5};
+this._connectEvents(_21,o);
+}
+}
+}
+run.dirty=false;
+}
+this.dirty=false;
+return this;
+}});
+})();
+}
diff --git a/dojox/charting/plot2d/Base.js b/dojox/charting/plot2d/Base.js
new file mode 100644
index 0000000..c753966
--- /dev/null
+++ b/dojox/charting/plot2d/Base.js
@@ -0,0 +1,90 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.Base"]){
+dojo._hasResource["dojox.charting.plot2d.Base"]=true;
+dojo.provide("dojox.charting.plot2d.Base");
+dojo.require("dojox.charting.scaler.primitive");
+dojo.require("dojox.charting.Element");
+dojo.require("dojox.charting.plot2d.common");
+dojo.declare("dojox.charting.plot2d.Base",dojox.charting.Element,{destroy:function(){
+this.resetEvents();
+this.inherited(arguments);
+},clear:function(){
+this.series=[];
+this._hAxis=null;
+this._vAxis=null;
+this.dirty=true;
+return this;
+},setAxis:function(_1){
+if(_1){
+this[_1.vertical?"_vAxis":"_hAxis"]=_1;
+}
+return this;
+},addSeries:function(_2){
+this.series.push(_2);
+return this;
+},calculateAxes:function(_3){
+return this;
+},isDirty:function(){
+return this.dirty||this._hAxis&&this._hAxis.dirty||this._vAxis&&this._vAxis.dirty;
+},render:function(_4,_5){
+return this;
+},getRequiredColors:function(){
+return this.series.length;
+},plotEvent:function(o){
+},connect:function(_7,_8){
+this.dirty=true;
+return dojo.connect(this,"plotEvent",_7,_8);
+},events:function(){
+var ls=this.plotEvent._listeners;
+if(!ls||!ls.length){
+return false;
+}
+for(var i in ls){
+if(!(i in Array.prototype)){
+return true;
+}
+}
+return false;
+},resetEvents:function(){
+this.plotEvent({type:"onplotreset",plot:this});
+},_calc:function(_b,_c){
+if(this._hAxis){
+if(!this._hAxis.initialized()){
+this._hAxis.calculate(_c.hmin,_c.hmax,_b.width);
+}
+this._hScaler=this._hAxis.getScaler();
+}else{
+this._hScaler=dojox.charting.scaler.primitive.buildScaler(_c.hmin,_c.hmax,_b.width);
+}
+if(this._vAxis){
+if(!this._vAxis.initialized()){
+this._vAxis.calculate(_c.vmin,_c.vmax,_b.height);
+}
+this._vScaler=this._vAxis.getScaler();
+}else{
+this._vScaler=dojox.charting.scaler.primitive.buildScaler(_c.vmin,_c.vmax,_b.height);
+}
+},_connectEvents:function(_d,o){
+_d.connect("onmouseover",this,function(e){
+o.type="onmouseover";
+o.event=e;
+this.plotEvent(o);
+});
+_d.connect("onmouseout",this,function(e){
+o.type="onmouseout";
+o.event=e;
+this.plotEvent(o);
+});
+_d.connect("onclick",this,function(e){
+o.type="onclick";
+o.event=e;
+this.plotEvent(o);
+});
+}});
+}
diff --git a/dojox/charting/plot2d/Bubble.js b/dojox/charting/plot2d/Bubble.js
new file mode 100644
index 0000000..5bebb7b
--- /dev/null
+++ b/dojox/charting/plot2d/Bubble.js
@@ -0,0 +1,98 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.Bubble"]){
+dojo._hasResource["dojox.charting.plot2d.Bubble"]=true;
+dojo.provide("dojox.charting.plot2d.Bubble");
+dojo.require("dojox.charting.plot2d.Base");
+dojo.require("dojox.lang.functional");
+(function(){
+var df=dojox.lang.functional,du=dojox.lang.utils,dc=dojox.charting.plot2d.common,_4=df.lambda("item.purgeGroup()");
+dojo.declare("dojox.charting.plot2d.Bubble",dojox.charting.plot2d.Base,{defaultParams:{hAxis:"x",vAxis:"y"},optionalParams:{},constructor:function(_5,_6){
+this.opt=dojo.clone(this.defaultParams);
+du.updateWithObject(this.opt,_6);
+this.series=[];
+this.hAxis=this.opt.hAxis;
+this.vAxis=this.opt.vAxis;
+},calculateAxes:function(_7){
+this._calc(_7,dc.collectSimpleStats(this.series));
+return this;
+},render:function(_8,_9){
+this.dirty=this.isDirty();
+if(this.dirty){
+dojo.forEach(this.series,_4);
+this.cleanGroup();
+var s=this.group;
+df.forEachRev(this.series,function(_b){
+_b.cleanGroup(s);
+});
+}
+var t=this.chart.theme,_d,_e,_f,_10,_11,ht=this._hScaler.scaler.getTransformerFromModel(this._hScaler),vt=this._vScaler.scaler.getTransformerFromModel(this._vScaler),_14=this.events();
+this.resetEvents();
+for(var i=this.series.length-1;i>=0;--i){
+var run=this.series[i];
+if(!this.dirty&&!run.dirty){
+continue;
+}
+run.cleanGroup();
+if(!run.data.length){
+run.dirty=false;
+continue;
+}
+if(typeof run.data[0]=="number"){
+console.warn("dojox.charting.plot2d.Bubble: the data in the following series cannot be rendered as a bubble chart; ",run);
+continue;
+}
+var s=run.group,_17=dojo.map(run.data,function(v,i){
+return {x:ht(v.x)+_9.l,y:_8.height-_9.b-vt(v.y),radius:this._vScaler.bounds.scale*(v.size/2)};
+},this);
+if(run.fill){
+_f=run.fill;
+}else{
+if(run.stroke){
+_f=run.stroke;
+}else{
+_f=run.dyn.color=new dojo.Color(t.next("color"));
+}
+}
+run.dyn.fill=_f;
+_d=run.dyn.stroke=run.stroke?dc.makeStroke(run.stroke):dc.augmentStroke(t.series.stroke,_f);
+var _1a=null,_1b=null,_1c=null;
+if(this.opt.shadows&&_d){
+var sh=this.opt.shadows,_11=new dojo.Color([0,0,0,0.2]),_10=dojo.clone(_e?_e:_d);
+_10.color=_11;
+_10.width+=sh.dw?sh.dw:0;
+run.dyn.shadow=_10;
+var _1e=dojo.map(_17,function(_1f){
+var sh=this.opt.shadows;
+return s.createCircle({cx:_1f.x+sh.dx,cy:_1f.y+sh.dy,r:_1f.radius}).setStroke(_10).setFill(_11);
+},this);
+}
+if(run.outline||t.series.outline){
+_e=dc.makeStroke(run.outline?run.outline:t.series.outline);
+_e.width=2*_e.width+_d.width;
+run.dyn.outline=_e;
+_1b=dojo.map(_17,function(_21){
+s.createCircle({cx:_21.x,cy:_21.y,r:_21.radius}).setStroke(_e);
+},this);
+}
+_1a=dojo.map(_17,function(_22){
+return s.createCircle({cx:_22.x,cy:_22.y,r:_22.radius}).setStroke(_d).setFill(_f);
+},this);
+if(_14){
+dojo.forEach(_1a,function(s,i){
+var o={element:"circle",index:i,run:run,plot:this,hAxis:this.hAxis||null,vAxis:this.vAxis||null,shape:s,outline:_1b&&_1b[i]||null,shadow:_1c&&_1c[i]||null,x:run.data[i].x,y:run.data[i].y,r:run.data[i].size/2,cx:_17[i].x,cy:_17[i].y,cr:_17[i].radius};
+this._connectEvents(s,o);
+},this);
+}
+run.dirty=false;
+}
+this.dirty=false;
+return this;
+}});
+})();
+}
diff --git a/dojox/charting/plot2d/ClusteredBars.js b/dojox/charting/plot2d/ClusteredBars.js
new file mode 100644
index 0000000..434b4d0
--- /dev/null
+++ b/dojox/charting/plot2d/ClusteredBars.js
@@ -0,0 +1,62 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.ClusteredBars"]){
+dojo._hasResource["dojox.charting.plot2d.ClusteredBars"]=true;
+dojo.provide("dojox.charting.plot2d.ClusteredBars");
+dojo.require("dojox.charting.plot2d.common");
+dojo.require("dojox.charting.plot2d.Bars");
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.functional.reversed");
+(function(){
+var df=dojox.lang.functional,dc=dojox.charting.plot2d.common,_3=df.lambda("item.purgeGroup()");
+dojo.declare("dojox.charting.plot2d.ClusteredBars",dojox.charting.plot2d.Bars,{render:function(_4,_5){
+this.dirty=this.isDirty();
+if(this.dirty){
+dojo.forEach(this.series,_3);
+this.cleanGroup();
+var s=this.group;
+df.forEachRev(this.series,function(_7){
+_7.cleanGroup(s);
+});
+}
+var t=this.chart.theme,_9,_a,_b,f,_d,_e,_f,ht=this._hScaler.scaler.getTransformerFromModel(this._hScaler),vt=this._vScaler.scaler.getTransformerFromModel(this._vScaler),_12=Math.max(0,this._hScaler.bounds.lower),_13=ht(_12),_14=this.events();
+f=dc.calculateBarSize(this._vScaler.bounds.scale,this.opt,this.series.length);
+_d=f.gap;
+_e=_f=f.size;
+this.resetEvents();
+for(var i=this.series.length-1;i>=0;--i){
+var run=this.series[i],_17=_f*(this.series.length-i-1);
+if(!this.dirty&&!run.dirty){
+continue;
+}
+run.cleanGroup();
+var s=run.group;
+if(!run.fill||!run.stroke){
+_9=run.dyn.color=new dojo.Color(t.next("color"));
+}
+_a=run.stroke?run.stroke:dc.augmentStroke(t.series.stroke,_9);
+_b=run.fill?run.fill:dc.augmentFill(t.series.fill,_9);
+for(var j=0;j<run.data.length;++j){
+var v=run.data[j],hv=ht(v),_1b=hv-_13,w=Math.abs(_1b);
+if(w>=1&&_e>=1){
+var _1d=s.createRect({x:_5.l+(v<_12?hv:_13),y:_4.height-_5.b-vt(j+1.5)+_d+_17,width:w,height:_e}).setFill(_b).setStroke(_a);
+run.dyn.fill=_1d.getFill();
+run.dyn.stroke=_1d.getStroke();
+if(_14){
+var o={element:"bar",index:j,run:run,plot:this,hAxis:this.hAxis||null,vAxis:this.vAxis||null,shape:_1d,x:v,y:j+1.5};
+this._connectEvents(_1d,o);
+}
+}
+}
+run.dirty=false;
+}
+this.dirty=false;
+return this;
+}});
+})();
+}
diff --git a/dojox/charting/plot2d/ClusteredColumns.js b/dojox/charting/plot2d/ClusteredColumns.js
new file mode 100644
index 0000000..8899aed
--- /dev/null
+++ b/dojox/charting/plot2d/ClusteredColumns.js
@@ -0,0 +1,62 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.ClusteredColumns"]){
+dojo._hasResource["dojox.charting.plot2d.ClusteredColumns"]=true;
+dojo.provide("dojox.charting.plot2d.ClusteredColumns");
+dojo.require("dojox.charting.plot2d.common");
+dojo.require("dojox.charting.plot2d.Columns");
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.functional.reversed");
+(function(){
+var df=dojox.lang.functional,dc=dojox.charting.plot2d.common,_3=df.lambda("item.purgeGroup()");
+dojo.declare("dojox.charting.plot2d.ClusteredColumns",dojox.charting.plot2d.Columns,{render:function(_4,_5){
+this.dirty=this.isDirty();
+if(this.dirty){
+dojo.forEach(this.series,_3);
+this.cleanGroup();
+var s=this.group;
+df.forEachRev(this.series,function(_7){
+_7.cleanGroup(s);
+});
+}
+var t=this.chart.theme,_9,_a,_b,f,_d,_e,_f,ht=this._hScaler.scaler.getTransformerFromModel(this._hScaler),vt=this._vScaler.scaler.getTransformerFromModel(this._vScaler),_12=Math.max(0,this._vScaler.bounds.lower),_13=vt(_12),_14=this.events();
+f=dc.calculateBarSize(this._hScaler.bounds.scale,this.opt,this.series.length);
+_d=f.gap;
+_e=_f=f.size;
+this.resetEvents();
+for(var i=0;i<this.series.length;++i){
+var run=this.series[i],_17=_f*i;
+if(!this.dirty&&!run.dirty){
+continue;
+}
+run.cleanGroup();
+var s=run.group;
+if(!run.fill||!run.stroke){
+_9=run.dyn.color=new dojo.Color(t.next("color"));
+}
+_a=run.stroke?run.stroke:dc.augmentStroke(t.series.stroke,_9);
+_b=run.fill?run.fill:dc.augmentFill(t.series.fill,_9);
+for(var j=0;j<run.data.length;++j){
+var v=run.data[j],vv=vt(v),_1b=vv-_13,h=Math.abs(_1b);
+if(_e>=1&&h>=1){
+var _1d=s.createRect({x:_5.l+ht(j+0.5)+_d+_17,y:_4.height-_5.b-(v>_12?vv:_13),width:_e,height:h}).setFill(_b).setStroke(_a);
+run.dyn.fill=_1d.getFill();
+run.dyn.stroke=_1d.getStroke();
+if(_14){
+var o={element:"column",index:j,run:run,plot:this,hAxis:this.hAxis||null,vAxis:this.vAxis||null,shape:_1d,x:j+0.5,y:v};
+this._connectEvents(_1d,o);
+}
+}
+}
+run.dirty=false;
+}
+this.dirty=false;
+return this;
+}});
+})();
+}
diff --git a/dojox/charting/plot2d/Columns.js b/dojox/charting/plot2d/Columns.js
new file mode 100644
index 0000000..4374a8b
--- /dev/null
+++ b/dojox/charting/plot2d/Columns.js
@@ -0,0 +1,76 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.Columns"]){
+dojo._hasResource["dojox.charting.plot2d.Columns"]=true;
+dojo.provide("dojox.charting.plot2d.Columns");
+dojo.require("dojox.charting.plot2d.common");
+dojo.require("dojox.charting.plot2d.Base");
+dojo.require("dojox.lang.utils");
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.functional.reversed");
+(function(){
+var df=dojox.lang.functional,du=dojox.lang.utils,dc=dojox.charting.plot2d.common,_4=df.lambda("item.purgeGroup()");
+dojo.declare("dojox.charting.plot2d.Columns",dojox.charting.plot2d.Base,{defaultParams:{hAxis:"x",vAxis:"y",gap:0,shadows:null},optionalParams:{minBarSize:1,maxBarSize:1},constructor:function(_5,_6){
+this.opt=dojo.clone(this.defaultParams);
+du.updateWithObject(this.opt,_6);
+du.updateWithPattern(this.opt,_6,this.optionalParams);
+this.series=[];
+this.hAxis=this.opt.hAxis;
+this.vAxis=this.opt.vAxis;
+},calculateAxes:function(_7){
+var _8=dc.collectSimpleStats(this.series);
+_8.hmin-=0.5;
+_8.hmax+=0.5;
+this._calc(_7,_8);
+return this;
+},render:function(_9,_a){
+this.dirty=this.isDirty();
+if(this.dirty){
+dojo.forEach(this.series,_4);
+this.cleanGroup();
+var s=this.group;
+df.forEachRev(this.series,function(_c){
+_c.cleanGroup(s);
+});
+}
+var t=this.chart.theme,_e,_f,_10,f,gap,_13,ht=this._hScaler.scaler.getTransformerFromModel(this._hScaler),vt=this._vScaler.scaler.getTransformerFromModel(this._vScaler),_16=Math.max(0,this._vScaler.bounds.lower),_17=vt(_16),_18=this.events();
+f=dc.calculateBarSize(this._hScaler.bounds.scale,this.opt);
+gap=f.gap;
+_13=f.size;
+this.resetEvents();
+for(var i=this.series.length-1;i>=0;--i){
+var run=this.series[i];
+if(!this.dirty&&!run.dirty){
+continue;
+}
+run.cleanGroup();
+var s=run.group;
+if(!run.fill||!run.stroke){
+_e=run.dyn.color=new dojo.Color(t.next("color"));
+}
+_f=run.stroke?run.stroke:dc.augmentStroke(t.series.stroke,_e);
+_10=run.fill?run.fill:dc.augmentFill(t.series.fill,_e);
+for(var j=0;j<run.data.length;++j){
+var v=run.data[j],vv=vt(v),_1e=vv-_17,h=Math.abs(_1e);
+if(_13>=1&&h>=1){
+var _20={x:_a.l+ht(j+0.5)+gap,y:_9.height-_a.b-(v>_16?vv:_17),width:_13,height:h},_21=s.createRect(_20).setFill(_10).setStroke(_f);
+run.dyn.fill=_21.getFill();
+run.dyn.stroke=_21.getStroke();
+if(_18){
+var o={element:"column",index:j,run:run,plot:this,hAxis:this.hAxis||null,vAxis:this.vAxis||null,shape:_21,x:j+0.5,y:v};
+this._connectEvents(_21,o);
+}
+}
+}
+run.dirty=false;
+}
+this.dirty=false;
+return this;
+}});
+})();
+}
diff --git a/dojox/charting/plot2d/Default.js b/dojox/charting/plot2d/Default.js
new file mode 100644
index 0000000..a8ed52f
--- /dev/null
+++ b/dojox/charting/plot2d/Default.js
@@ -0,0 +1,150 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.Default"]){
+dojo._hasResource["dojox.charting.plot2d.Default"]=true;
+dojo.provide("dojox.charting.plot2d.Default");
+dojo.require("dojox.charting.plot2d.common");
+dojo.require("dojox.charting.plot2d.Base");
+dojo.require("dojox.lang.utils");
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.functional.reversed");
+(function(){
+var df=dojox.lang.functional,du=dojox.lang.utils,dc=dojox.charting.plot2d.common,_4=df.lambda("item.purgeGroup()");
+dojo.declare("dojox.charting.plot2d.Default",dojox.charting.plot2d.Base,{defaultParams:{hAxis:"x",vAxis:"y",lines:true,areas:false,markers:false,shadows:0,tension:0},optionalParams:{},constructor:function(_5,_6){
+this.opt=dojo.clone(this.defaultParams);
+du.updateWithObject(this.opt,_6);
+this.series=[];
+this.hAxis=this.opt.hAxis;
+this.vAxis=this.opt.vAxis;
+},calculateAxes:function(_7){
+this._calc(_7,dc.collectSimpleStats(this.series));
+return this;
+},render:function(_8,_9){
+this.dirty=this.isDirty();
+if(this.dirty){
+dojo.forEach(this.series,_4);
+this.cleanGroup();
+var s=this.group;
+df.forEachRev(this.series,function(_b){
+_b.cleanGroup(s);
+});
+}
+var t=this.chart.theme,_d,_e,_f,_10,_11=this.events();
+this.resetEvents();
+for(var i=this.series.length-1;i>=0;--i){
+var run=this.series[i];
+if(!this.dirty&&!run.dirty){
+continue;
+}
+run.cleanGroup();
+if(!run.data.length){
+run.dirty=false;
+continue;
+}
+var s=run.group,_14,ht=this._hScaler.scaler.getTransformerFromModel(this._hScaler),vt=this._vScaler.scaler.getTransformerFromModel(this._vScaler);
+if(typeof run.data[0]=="number"){
+_14=dojo.map(run.data,function(v,i){
+return {x:ht(i+1)+_9.l,y:_8.height-_9.b-vt(v)};
+},this);
+}else{
+_14=dojo.map(run.data,function(v,i){
+return {x:ht(v.x)+_9.l,y:_8.height-_9.b-vt(v.y)};
+},this);
+}
+if(!run.fill||!run.stroke){
+_f=run.dyn.color=new dojo.Color(t.next("color"));
+}
+var _1b=this.opt.tension?dc.curve(_14,this.opt.tension):"";
+if(this.opt.areas){
+var _1c=run.fill?run.fill:dc.augmentFill(t.series.fill,_f);
+var _1d=dojo.clone(_14);
+if(this.opt.tension){
+var _1e="L"+_1d[_1d.length-1].x+","+(_8.height-_9.b)+" L"+_1d[0].x+","+(_8.height-_9.b)+" L"+_1d[0].x+","+_1d[0].y;
+run.dyn.fill=s.createPath(_1b+" "+_1e).setFill(_1c).getFill();
+}else{
+_1d.push({x:_14[_14.length-1].x,y:_8.height-_9.b});
+_1d.push({x:_14[0].x,y:_8.height-_9.b});
+_1d.push(_14[0]);
+run.dyn.fill=s.createPolyline(_1d).setFill(_1c).getFill();
+}
+}
+if(this.opt.lines||this.opt.markers){
+_d=run.stroke?dc.makeStroke(run.stroke):dc.augmentStroke(t.series.stroke,_f);
+if(run.outline||t.series.outline){
+_e=dc.makeStroke(run.outline?run.outline:t.series.outline);
+_e.width=2*_e.width+_d.width;
+}
+}
+if(this.opt.markers){
+_10=run.dyn.marker=run.marker?run.marker:t.next("marker");
+}
+var _1f=null,_20=null,_21=null;
+if(this.opt.shadows&&_d){
+var sh=this.opt.shadows,_23=new dojo.Color([0,0,0,0.3]),_24=dojo.map(_14,function(c){
+return {x:c.x+sh.dx,y:c.y+sh.dy};
+}),_26=dojo.clone(_e?_e:_d);
+_26.color=_23;
+_26.width+=sh.dw?sh.dw:0;
+if(this.opt.lines){
+if(this.opt.tension){
+run.dyn.shadow=s.createPath(dc.curve(_24,this.opt.tension)).setStroke(_26).getStroke();
+}else{
+run.dyn.shadow=s.createPolyline(_24).setStroke(_26).getStroke();
+}
+}
+if(this.opt.markers){
+_21=dojo.map(_24,function(c){
+return s.createPath("M"+c.x+" "+c.y+" "+_10).setStroke(_26).setFill(_23);
+},this);
+}
+}
+if(this.opt.lines){
+if(_e){
+if(this.opt.tension){
+run.dyn.outline=s.createPath(_1b).setStroke(_e).getStroke();
+}else{
+run.dyn.outline=s.createPolyline(_14).setStroke(_e).getStroke();
+}
+}
+if(this.opt.tension){
+run.dyn.stroke=s.createPath(_1b).setStroke(_d).getStroke();
+}else{
+run.dyn.stroke=s.createPolyline(_14).setStroke(_d).getStroke();
+}
+}
+if(this.opt.markers){
+_1f=new Array(_14.length);
+_20=new Array(_14.length);
+dojo.forEach(_14,function(c,i){
+var _2a="M"+c.x+" "+c.y+" "+_10;
+if(_e){
+_20[i]=s.createPath(_2a).setStroke(_e);
+}
+_1f[i]=s.createPath(_2a).setStroke(_d).setFill(_d.color);
+},this);
+if(_11){
+dojo.forEach(_1f,function(s,i){
+var o={element:"marker",index:i,run:run,plot:this,hAxis:this.hAxis||null,vAxis:this.vAxis||null,shape:s,outline:_20[i]||null,shadow:_21&&_21[i]||null,cx:_14[i].x,cy:_14[i].y};
+if(typeof run.data[0]=="number"){
+o.x=i+1;
+o.y=run.data[i];
+}else{
+o.x=run.data[i].x;
+o.y=run.data[i].y;
+}
+this._connectEvents(s,o);
+},this);
+}
+}
+run.dirty=false;
+}
+this.dirty=false;
+return this;
+}});
+})();
+}
diff --git a/dojox/charting/plot2d/Grid.js b/dojox/charting/plot2d/Grid.js
new file mode 100644
index 0000000..767ccfc
--- /dev/null
+++ b/dojox/charting/plot2d/Grid.js
@@ -0,0 +1,85 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.Grid"]){
+dojo._hasResource["dojox.charting.plot2d.Grid"]=true;
+dojo.provide("dojox.charting.plot2d.Grid");
+dojo.require("dojox.charting.Element");
+dojo.require("dojox.charting.plot2d.common");
+dojo.require("dojox.lang.functional");
+(function(){
+var du=dojox.lang.utils;
+dojo.declare("dojox.charting.plot2d.Grid",dojox.charting.Element,{defaultParams:{hAxis:"x",vAxis:"y",hMajorLines:true,hMinorLines:false,vMajorLines:true,vMinorLines:false,hStripes:"none",vStripes:"none"},optionalParams:{},constructor:function(_2,_3){
+this.opt=dojo.clone(this.defaultParams);
+du.updateWithObject(this.opt,_3);
+this.hAxis=this.opt.hAxis;
+this.vAxis=this.opt.vAxis;
+this.dirty=true;
+},clear:function(){
+this._hAxis=null;
+this._vAxis=null;
+this.dirty=true;
+return this;
+},setAxis:function(_4){
+if(_4){
+this[_4.vertical?"_vAxis":"_hAxis"]=_4;
+}
+return this;
+},addSeries:function(_5){
+return this;
+},calculateAxes:function(_6){
+return this;
+},isDirty:function(){
+return this.dirty||this._hAxis&&this._hAxis.dirty||this._vAxis&&this._vAxis.dirty;
+},getRequiredColors:function(){
+return 0;
+},render:function(_7,_8){
+this.dirty=this.isDirty();
+if(!this.dirty){
+return this;
+}
+this.cleanGroup();
+var s=this.group,ta=this.chart.theme.axis;
+try{
+var _b=this._vAxis.getScaler(),vt=_b.scaler.getTransformerFromModel(_b),_d=this._vAxis.getTicks();
+if(this.opt.hMinorLines){
+dojo.forEach(_d.minor,function(_e){
+var y=_7.height-_8.b-vt(_e.value);
+s.createLine({x1:_8.l,y1:y,x2:_7.width-_8.r,y2:y}).setStroke(ta.minorTick);
+});
+}
+if(this.opt.hMajorLines){
+dojo.forEach(_d.major,function(_10){
+var y=_7.height-_8.b-vt(_10.value);
+s.createLine({x1:_8.l,y1:y,x2:_7.width-_8.r,y2:y}).setStroke(ta.majorTick);
+});
+}
+}
+catch(e){
+}
+try{
+var _12=this._hAxis.getScaler(),ht=_12.scaler.getTransformerFromModel(_12),_d=this._hAxis.getTicks();
+if(_d&&this.opt.vMinorLines){
+dojo.forEach(_d.minor,function(_14){
+var x=_8.l+ht(_14.value);
+s.createLine({x1:x,y1:_8.t,x2:x,y2:_7.height-_8.b}).setStroke(ta.minorTick);
+});
+}
+if(_d&&this.opt.vMajorLines){
+dojo.forEach(_d.major,function(_16){
+var x=_8.l+ht(_16.value);
+s.createLine({x1:x,y1:_8.t,x2:x,y2:_7.height-_8.b}).setStroke(ta.majorTick);
+});
+}
+}
+catch(e){
+}
+this.dirty=false;
+return this;
+}});
+})();
+}
diff --git a/dojox/charting/plot2d/Lines.js b/dojox/charting/plot2d/Lines.js
new file mode 100644
index 0000000..0026744
--- /dev/null
+++ b/dojox/charting/plot2d/Lines.js
@@ -0,0 +1,15 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.Lines"]){
+dojo._hasResource["dojox.charting.plot2d.Lines"]=true;
+dojo.provide("dojox.charting.plot2d.Lines");
+dojo.require("dojox.charting.plot2d.Default");
+dojo.declare("dojox.charting.plot2d.Lines",dojox.charting.plot2d.Default,{constructor:function(){
+this.opt.lines=true;
+}});
+}
diff --git a/dojox/charting/plot2d/Markers.js b/dojox/charting/plot2d/Markers.js
new file mode 100644
index 0000000..bee2125
--- /dev/null
+++ b/dojox/charting/plot2d/Markers.js
@@ -0,0 +1,15 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.Markers"]){
+dojo._hasResource["dojox.charting.plot2d.Markers"]=true;
+dojo.provide("dojox.charting.plot2d.Markers");
+dojo.require("dojox.charting.plot2d.Default");
+dojo.declare("dojox.charting.plot2d.Markers",dojox.charting.plot2d.Default,{constructor:function(){
+this.opt.markers=true;
+}});
+}
diff --git a/dojox/charting/plot2d/MarkersOnly.js b/dojox/charting/plot2d/MarkersOnly.js
new file mode 100644
index 0000000..cdb0985
--- /dev/null
+++ b/dojox/charting/plot2d/MarkersOnly.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.MarkersOnly"]){
+dojo._hasResource["dojox.charting.plot2d.MarkersOnly"]=true;
+dojo.provide("dojox.charting.plot2d.MarkersOnly");
+dojo.require("dojox.charting.plot2d.Default");
+dojo.declare("dojox.charting.plot2d.MarkersOnly",dojox.charting.plot2d.Default,{constructor:function(){
+this.opt.lines=false;
+this.opt.markers=true;
+}});
+}
diff --git a/dojox/charting/plot2d/Pie.js b/dojox/charting/plot2d/Pie.js
new file mode 100644
index 0000000..a77f516
--- /dev/null
+++ b/dojox/charting/plot2d/Pie.js
@@ -0,0 +1,207 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.Pie"]){
+dojo._hasResource["dojox.charting.plot2d.Pie"]=true;
+dojo.provide("dojox.charting.plot2d.Pie");
+dojo.require("dojox.charting.Element");
+dojo.require("dojox.charting.axis2d.common");
+dojo.require("dojox.charting.plot2d.common");
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.gfx");
+(function(){
+var df=dojox.lang.functional,du=dojox.lang.utils,dc=dojox.charting.plot2d.common,da=dojox.charting.axis2d.common,g=dojox.gfx;
+dojo.declare("dojox.charting.plot2d.Pie",dojox.charting.Element,{defaultParams:{labels:true,ticks:false,fixed:true,precision:1,labelOffset:20,labelStyle:"default",htmlLabels:true},optionalParams:{font:"",fontColor:"",radius:0},constructor:function(_6,_7){
+this.opt=dojo.clone(this.defaultParams);
+du.updateWithObject(this.opt,_7);
+du.updateWithPattern(this.opt,_7,this.optionalParams);
+this.run=null;
+this.dyn=[];
+},destroy:function(){
+this.resetEvents();
+this.inherited(arguments);
+},clear:function(){
+this.dirty=true;
+this.dyn=[];
+this.run=null;
+return this;
+},setAxis:function(_8){
+return this;
+},addSeries:function(_9){
+this.run=_9;
+return this;
+},calculateAxes:function(_a){
+return this;
+},getRequiredColors:function(){
+return this.run?this.run.data.length:0;
+},plotEvent:function(o){
+},connect:function(_c,_d){
+this.dirty=true;
+return dojo.connect(this,"plotEvent",_c,_d);
+},events:function(){
+var ls=this.plotEvent._listeners;
+if(!ls||!ls.length){
+return false;
+}
+for(var i in ls){
+if(!(i in Array.prototype)){
+return true;
+}
+}
+return false;
+},resetEvents:function(){
+this.plotEvent({type:"onplotreset",plot:this});
+},_connectEvents:function(_10,o){
+_10.connect("onmouseover",this,function(e){
+o.type="onmouseover";
+o.event=e;
+this.plotEvent(o);
+});
+_10.connect("onmouseout",this,function(e){
+o.type="onmouseout";
+o.event=e;
+this.plotEvent(o);
+});
+_10.connect("onclick",this,function(e){
+o.type="onclick";
+o.event=e;
+this.plotEvent(o);
+});
+},render:function(dim,_16){
+if(!this.dirty){
+return this;
+}
+this.dirty=false;
+this.cleanGroup();
+var s=this.group,_18,t=this.chart.theme;
+this.resetEvents();
+if(!this.run||!this.run.data.length){
+return this;
+}
+var rx=(dim.width-_16.l-_16.r)/2,ry=(dim.height-_16.t-_16.b)/2,r=Math.min(rx,ry),_1d="font" in this.opt?this.opt.font:t.axis.font,_1e=_1d?g.normalizedLength(g.splitFontString(_1d).size):0,_1f="fontColor" in this.opt?this.opt.fontColor:t.axis.fontColor,_20=0,_21,_22,_23,_24,_25,_26,run=this.run.data,_28=this.events();
+if(typeof run[0]=="number"){
+_22=df.map(run,"Math.max(x, 0)");
+if(df.every(_22,"<= 0")){
+return this;
+}
+_23=df.map(_22,"/this",df.foldl(_22,"+",0));
+if(this.opt.labels){
+_24=dojo.map(_23,function(x){
+return x>0?this._getLabel(x*100)+"%":"";
+},this);
+}
+}else{
+_22=df.map(run,"Math.max(x.y, 0)");
+if(df.every(_22,"<= 0")){
+return this;
+}
+_23=df.map(_22,"/this",df.foldl(_22,"+",0));
+if(this.opt.labels){
+_24=dojo.map(_23,function(x,i){
+if(x<=0){
+return "";
+}
+var v=run[i];
+return "text" in v?v.text:this._getLabel(x*100)+"%";
+},this);
+}
+}
+if(this.opt.labels){
+_25=df.foldl1(df.map(_24,function(_2d){
+return dojox.gfx._base._getTextBox(_2d,{font:_1d}).w;
+},this),"Math.max(a, b)")/2;
+if(this.opt.labelOffset<0){
+r=Math.min(rx-2*_25,ry-_1e)+this.opt.labelOffset;
+}
+_26=r-this.opt.labelOffset;
+}
+if("radius" in this.opt){
+r=this.opt.radius;
+_26=r-this.opt.labelOffset;
+}
+var _2e={cx:_16.l+rx,cy:_16.t+ry,r:r};
+this.dyn=[];
+dojo.some(_23,function(_2f,i){
+if(_2f<=0){
+return false;
+}
+var v=run[i];
+if(_2f>=1){
+var _32,_33,_34;
+if(typeof v=="object"){
+_32="color" in v?v.color:new dojo.Color(t.next("color"));
+_33="fill" in v?v.fill:dc.augmentFill(t.series.fill,_32);
+_34="stroke" in v?v.stroke:dc.augmentStroke(t.series.stroke,_32);
+}else{
+_32=new dojo.Color(t.next("color"));
+_33=dc.augmentFill(t.series.fill,_32);
+_34=dc.augmentStroke(t.series.stroke,_32);
+}
+var _35=s.createCircle(_2e).setFill(_33).setStroke(_34);
+this.dyn.push({color:_32,fill:_33,stroke:_34});
+if(_28){
+var o={element:"slice",index:i,run:this.run,plot:this,shape:_35,x:i,y:typeof v=="number"?v:v.y,cx:_2e.cx,cy:_2e.cy,cr:r};
+this._connectEvents(_35,o);
+}
+return true;
+}
+var end=_20+_2f*2*Math.PI;
+if(i+1==_23.length){
+end=2*Math.PI;
+}
+var _38=end-_20,x1=_2e.cx+r*Math.cos(_20),y1=_2e.cy+r*Math.sin(_20),x2=_2e.cx+r*Math.cos(end),y2=_2e.cy+r*Math.sin(end);
+var _32,_33,_34;
+if(typeof v=="object"){
+_32="color" in v?v.color:new dojo.Color(t.next("color"));
+_33="fill" in v?v.fill:dc.augmentFill(t.series.fill,_32);
+_34="stroke" in v?v.stroke:dc.augmentStroke(t.series.stroke,_32);
+}else{
+_32=new dojo.Color(t.next("color"));
+_33=dc.augmentFill(t.series.fill,_32);
+_34=dc.augmentStroke(t.series.stroke,_32);
+}
+var _35=s.createPath({}).moveTo(_2e.cx,_2e.cy).lineTo(x1,y1).arcTo(r,r,0,_38>Math.PI,true,x2,y2).lineTo(_2e.cx,_2e.cy).closePath().setFill(_33).setStroke(_34);
+this.dyn.push({color:_32,fill:_33,stroke:_34});
+if(_28){
+var o={element:"slice",index:i,run:this.run,plot:this,shape:_35,x:i,y:typeof v=="number"?v:v.y,cx:_2e.cx,cy:_2e.cy,cr:r};
+this._connectEvents(_35,o);
+}
+_20=end;
+return false;
+},this);
+if(this.opt.labels){
+_20=0;
+dojo.some(_23,function(_3d,i){
+if(_3d<=0){
+return false;
+}
+if(_3d>=1){
+var v=run[i],_40=da.createText[this.opt.htmlLabels&&dojox.gfx.renderer!="vml"?"html":"gfx"](this.chart,s,_2e.cx,_2e.cy+_1e/2,"middle",_24[i],_1d,(typeof v=="object"&&"fontColor" in v)?v.fontColor:_1f);
+if(this.opt.htmlLabels){
+this.htmlElements.push(_40);
+}
+return true;
+}
+var end=_20+_3d*2*Math.PI,v=run[i];
+if(i+1==_23.length){
+end=2*Math.PI;
+}
+var _42=(_20+end)/2,x=_2e.cx+_26*Math.cos(_42),y=_2e.cy+_26*Math.sin(_42)+_1e/2;
+var _40=da.createText[this.opt.htmlLabels&&dojox.gfx.renderer!="vml"?"html":"gfx"](this.chart,s,x,y,"middle",_24[i],_1d,(typeof v=="object"&&"fontColor" in v)?v.fontColor:_1f);
+if(this.opt.htmlLabels){
+this.htmlElements.push(_40);
+}
+_20=end;
+return false;
+},this);
+}
+return this;
+},_getLabel:function(_45){
+return this.opt.fixed?_45.toFixed(this.opt.precision):_45.toString();
+}});
+})();
+}
diff --git a/dojox/charting/plot2d/Scatter.js b/dojox/charting/plot2d/Scatter.js
new file mode 100644
index 0000000..d4caae2
--- /dev/null
+++ b/dojox/charting/plot2d/Scatter.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.Scatter"]){
+dojo._hasResource["dojox.charting.plot2d.Scatter"]=true;
+dojo.provide("dojox.charting.plot2d.Scatter");
+dojo.require("dojox.charting.plot2d.Default");
+dojo.declare("dojox.charting.plot2d.Scatter",dojox.charting.plot2d.Default,{constructor:function(){
+this.opt.lines=false;
+this.opt.markers=true;
+}});
+}
diff --git a/dojox/charting/plot2d/Stacked.js b/dojox/charting/plot2d/Stacked.js
new file mode 100644
index 0000000..c4e8f71
--- /dev/null
+++ b/dojox/charting/plot2d/Stacked.js
@@ -0,0 +1,150 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.Stacked"]){
+dojo._hasResource["dojox.charting.plot2d.Stacked"]=true;
+dojo.provide("dojox.charting.plot2d.Stacked");
+dojo.require("dojox.charting.plot2d.common");
+dojo.require("dojox.charting.plot2d.Default");
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.functional.sequence");
+dojo.require("dojox.lang.functional.reversed");
+(function(){
+var df=dojox.lang.functional,dc=dojox.charting.plot2d.common,_3=df.lambda("item.purgeGroup()");
+dojo.declare("dojox.charting.plot2d.Stacked",dojox.charting.plot2d.Default,{calculateAxes:function(_4){
+var _5=dc.collectStackedStats(this.series);
+this._maxRunLength=_5.hmax;
+this._calc(_4,_5);
+return this;
+},render:function(_6,_7){
+if(this._maxRunLength<=0){
+return this;
+}
+var _8=df.repeat(this._maxRunLength,"-> 0",0);
+for(var i=0;i<this.series.length;++i){
+var _a=this.series[i];
+for(var j=0;j<_a.data.length;++j){
+var v=_a.data[j];
+if(isNaN(v)){
+v=0;
+}
+_8[j]+=v;
+}
+}
+this.dirty=this.isDirty();
+if(this.dirty){
+dojo.forEach(this.series,_3);
+this.cleanGroup();
+var s=this.group;
+df.forEachRev(this.series,function(_e){
+_e.cleanGroup(s);
+});
+}
+var t=this.chart.theme,_10,_11,_12,_13,_14=this.events(),ht=this._hScaler.scaler.getTransformerFromModel(this._hScaler),vt=this._vScaler.scaler.getTransformerFromModel(this._vScaler);
+this.resetEvents();
+for(var i=this.series.length-1;i>=0;--i){
+var _a=this.series[i];
+if(!this.dirty&&!_a.dirty){
+continue;
+}
+_a.cleanGroup();
+var s=_a.group,_17=dojo.map(_8,function(v,i){
+return {x:ht(i+1)+_7.l,y:_6.height-_7.b-vt(v)};
+},this);
+if(!_a.fill||!_a.stroke){
+_12=new dojo.Color(t.next("color"));
+}
+var _1a=this.opt.tension?dc.curve(_17,this.opt.tension):"";
+if(this.opt.areas){
+var _1b=dojo.clone(_17);
+var _1c=_a.fill?_a.fill:dc.augmentFill(t.series.fill,_12);
+if(this.opt.tension){
+var p=dc.curve(_1b,this.opt.tension);
+p+=" L"+_17[_17.length-1].x+","+(_6.height-_7.b)+" L"+_17[0].x+","+(_6.height-_7.b)+" L"+_17[0].x+","+_17[0].y;
+_a.dyn.fill=s.createPath(p).setFill(_1c).getFill();
+}else{
+_1b.push({x:_17[_17.length-1].x,y:_6.height-_7.b});
+_1b.push({x:_17[0].x,y:_6.height-_7.b});
+_1b.push(_17[0]);
+_a.dyn.fill=s.createPolyline(_1b).setFill(_1c).getFill();
+}
+}
+if(this.opt.lines||this.opt.markers){
+_10=_a.stroke?dc.makeStroke(_a.stroke):dc.augmentStroke(t.series.stroke,_12);
+if(_a.outline||t.series.outline){
+_11=dc.makeStroke(_a.outline?_a.outline:t.series.outline);
+_11.width=2*_11.width+_10.width;
+}
+}
+if(this.opt.markers){
+_13=_a.dyn.marker=_a.marker?_a.marker:t.next("marker");
+}
+var _1e,_1f,_20;
+if(this.opt.shadows&&_10){
+var sh=this.opt.shadows,_22=new dojo.Color([0,0,0,0.3]),_23=dojo.map(_17,function(c){
+return {x:c.x+sh.dx,y:c.y+sh.dy};
+}),_25=dojo.clone(_11?_11:_10);
+_25.color=_22;
+_25.width+=sh.dw?sh.dw:0;
+if(this.opt.lines){
+if(this.opt.tension){
+_a.dyn.shadow=s.createPath(dc.curve(_23,this.opt.tension)).setStroke(_25).getStroke();
+}else{
+_a.dyn.shadow=s.createPolyline(_23).setStroke(_25).getStroke();
+}
+}
+if(this.opt.markers){
+_20=dojo.map(_23,function(c){
+return s.createPath("M"+c.x+" "+c.y+" "+_13).setStroke(_25).setFill(_22);
+},this);
+}
+}
+if(this.opt.lines){
+if(_11){
+if(this.opt.tension){
+_a.dyn.outline=s.createPath(_1a).setStroke(_11).getStroke();
+}else{
+_a.dyn.outline=s.createPolyline(_17).setStroke(_11).getStroke();
+}
+}
+if(this.opt.tension){
+_a.dyn.stroke=s.createPath(_1a).setStroke(_10).getStroke();
+}else{
+_a.dyn.stroke=s.createPolyline(_17).setStroke(_10).getStroke();
+}
+}
+if(this.opt.markers){
+_1e=new Array(_17.length);
+_1f=new Array(_17.length);
+dojo.forEach(_17,function(c,i){
+var _29="M"+c.x+" "+c.y+" "+_13;
+if(_11){
+_1f[i]=s.createPath(_29).setStroke(_11);
+}
+_1e[i]=s.createPath(_29).setStroke(_10).setFill(_10.color);
+},this);
+if(_14){
+dojo.forEach(_1e,function(s,i){
+var o={element:"marker",index:i,run:_a,plot:this,hAxis:this.hAxis||null,vAxis:this.vAxis||null,shape:s,outline:_1f[i]||null,shadow:_20&&_20[i]||null,cx:_17[i].x,cy:_17[i].y,x:i+1,y:_a.data[i]};
+this._connectEvents(s,o);
+},this);
+}
+}
+_a.dirty=false;
+for(var j=0;j<_a.data.length;++j){
+var v=_a.data[j];
+if(isNaN(v)){
+v=0;
+}
+_8[j]-=v;
+}
+}
+this.dirty=false;
+return this;
+}});
+})();
+}
diff --git a/dojox/charting/plot2d/StackedAreas.js b/dojox/charting/plot2d/StackedAreas.js
new file mode 100644
index 0000000..85ecfa9
--- /dev/null
+++ b/dojox/charting/plot2d/StackedAreas.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.StackedAreas"]){
+dojo._hasResource["dojox.charting.plot2d.StackedAreas"]=true;
+dojo.provide("dojox.charting.plot2d.StackedAreas");
+dojo.require("dojox.charting.plot2d.Stacked");
+dojo.declare("dojox.charting.plot2d.StackedAreas",dojox.charting.plot2d.Stacked,{constructor:function(){
+this.opt.lines=true;
+this.opt.areas=true;
+}});
+}
diff --git a/dojox/charting/plot2d/StackedBars.js b/dojox/charting/plot2d/StackedBars.js
new file mode 100644
index 0000000..0cb7f9b
--- /dev/null
+++ b/dojox/charting/plot2d/StackedBars.js
@@ -0,0 +1,92 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.StackedBars"]){
+dojo._hasResource["dojox.charting.plot2d.StackedBars"]=true;
+dojo.provide("dojox.charting.plot2d.StackedBars");
+dojo.require("dojox.charting.plot2d.common");
+dojo.require("dojox.charting.plot2d.Bars");
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.functional.reversed");
+(function(){
+var df=dojox.lang.functional,dc=dojox.charting.plot2d.common,_3=df.lambda("item.purgeGroup()");
+dojo.declare("dojox.charting.plot2d.StackedBars",dojox.charting.plot2d.Bars,{calculateAxes:function(_4){
+var _5=dc.collectStackedStats(this.series),t;
+this._maxRunLength=_5.hmax;
+_5.hmin-=0.5;
+_5.hmax+=0.5;
+t=_5.hmin,_5.hmin=_5.vmin,_5.vmin=t;
+t=_5.hmax,_5.hmax=_5.vmax,_5.vmax=t;
+this._calc(_4,_5);
+return this;
+},render:function(_7,_8){
+if(this._maxRunLength<=0){
+return this;
+}
+var _9=df.repeat(this._maxRunLength,"-> 0",0);
+for(var i=0;i<this.series.length;++i){
+var _b=this.series[i];
+for(var j=0;j<_b.data.length;++j){
+var v=_b.data[j];
+if(isNaN(v)){
+v=0;
+}
+_9[j]+=v;
+}
+}
+this.dirty=this.isDirty();
+if(this.dirty){
+dojo.forEach(this.series,_3);
+this.cleanGroup();
+var s=this.group;
+df.forEachRev(this.series,function(_f){
+_f.cleanGroup(s);
+});
+}
+var t=this.chart.theme,_11,_12,_13,f,gap,_16,ht=this._hScaler.scaler.getTransformerFromModel(this._hScaler),vt=this._vScaler.scaler.getTransformerFromModel(this._vScaler),_19=this.events();
+f=dc.calculateBarSize(this._vScaler.bounds.scale,this.opt);
+gap=f.gap;
+_16=f.size;
+this.resetEvents();
+for(var i=this.series.length-1;i>=0;--i){
+var _b=this.series[i];
+if(!this.dirty&&!_b.dirty){
+continue;
+}
+_b.cleanGroup();
+var s=_b.group;
+if(!_b.fill||!_b.stroke){
+_11=_b.dyn.color=new dojo.Color(t.next("color"));
+}
+_12=_b.stroke?_b.stroke:dc.augmentStroke(t.series.stroke,_11);
+_13=_b.fill?_b.fill:dc.augmentFill(t.series.fill,_11);
+for(var j=0;j<_9.length;++j){
+var v=_9[j],_1a=ht(v);
+if(_1a>=1&&_16>=1){
+var _1b=s.createRect({x:_8.l,y:_7.height-_8.b-vt(j+1.5)+gap,width:_1a,height:_16}).setFill(_13).setStroke(_12);
+_b.dyn.fill=_1b.getFill();
+_b.dyn.stroke=_1b.getStroke();
+if(_19){
+var o={element:"bar",index:j,run:_b,plot:this,hAxis:this.hAxis||null,vAxis:this.vAxis||null,shape:_1b,x:v,y:j+1.5};
+this._connectEvents(_1b,o);
+}
+}
+}
+_b.dirty=false;
+for(var j=0;j<_b.data.length;++j){
+var v=_b.data[j];
+if(isNaN(v)){
+v=0;
+}
+_9[j]-=v;
+}
+}
+this.dirty=false;
+return this;
+}});
+})();
+}
diff --git a/dojox/charting/plot2d/StackedColumns.js b/dojox/charting/plot2d/StackedColumns.js
new file mode 100644
index 0000000..bad43b0
--- /dev/null
+++ b/dojox/charting/plot2d/StackedColumns.js
@@ -0,0 +1,90 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.StackedColumns"]){
+dojo._hasResource["dojox.charting.plot2d.StackedColumns"]=true;
+dojo.provide("dojox.charting.plot2d.StackedColumns");
+dojo.require("dojox.charting.plot2d.common");
+dojo.require("dojox.charting.plot2d.Columns");
+dojo.require("dojox.lang.functional");
+dojo.require("dojox.lang.functional.reversed");
+(function(){
+var df=dojox.lang.functional,dc=dojox.charting.plot2d.common,_3=df.lambda("item.purgeGroup()");
+dojo.declare("dojox.charting.plot2d.StackedColumns",dojox.charting.plot2d.Columns,{calculateAxes:function(_4){
+var _5=dc.collectStackedStats(this.series);
+this._maxRunLength=_5.hmax;
+_5.hmin-=0.5;
+_5.hmax+=0.5;
+this._calc(_4,_5);
+return this;
+},render:function(_6,_7){
+if(this._maxRunLength<=0){
+return this;
+}
+var _8=df.repeat(this._maxRunLength,"-> 0",0);
+for(var i=0;i<this.series.length;++i){
+var _a=this.series[i];
+for(var j=0;j<_a.data.length;++j){
+var v=_a.data[j];
+if(isNaN(v)){
+v=0;
+}
+_8[j]+=v;
+}
+}
+this.dirty=this.isDirty();
+if(this.dirty){
+dojo.forEach(this.series,_3);
+this.cleanGroup();
+var s=this.group;
+df.forEachRev(this.series,function(_e){
+_e.cleanGroup(s);
+});
+}
+var t=this.chart.theme,_10,_11,_12,f,gap,_15,ht=this._hScaler.scaler.getTransformerFromModel(this._hScaler),vt=this._vScaler.scaler.getTransformerFromModel(this._vScaler),_18=this.events();
+f=dc.calculateBarSize(this._hScaler.bounds.scale,this.opt);
+gap=f.gap;
+_15=f.size;
+this.resetEvents();
+for(var i=this.series.length-1;i>=0;--i){
+var _a=this.series[i];
+if(!this.dirty&&!_a.dirty){
+continue;
+}
+_a.cleanGroup();
+var s=_a.group;
+if(!_a.fill||!_a.stroke){
+_10=_a.dyn.color=new dojo.Color(t.next("color"));
+}
+_11=_a.stroke?_a.stroke:dc.augmentStroke(t.series.stroke,_10);
+_12=_a.fill?_a.fill:dc.augmentFill(t.series.fill,_10);
+for(var j=0;j<_8.length;++j){
+var v=_8[j],_19=vt(v);
+if(_15>=1&&_19>=1){
+var _1a=s.createRect({x:_7.l+ht(j+0.5)+gap,y:_6.height-_7.b-vt(v),width:_15,height:_19}).setFill(_12).setStroke(_11);
+_a.dyn.fill=_1a.getFill();
+_a.dyn.stroke=_1a.getStroke();
+if(_18){
+var o={element:"column",index:j,run:_a,plot:this,hAxis:this.hAxis||null,vAxis:this.vAxis||null,shape:_1a,x:j+0.5,y:v};
+this._connectEvents(_1a,o);
+}
+}
+}
+_a.dirty=false;
+for(var j=0;j<_a.data.length;++j){
+var v=_a.data[j];
+if(isNaN(v)){
+v=0;
+}
+_8[j]-=v;
+}
+}
+this.dirty=false;
+return this;
+}});
+})();
+}
diff --git a/dojox/charting/plot2d/StackedLines.js b/dojox/charting/plot2d/StackedLines.js
new file mode 100644
index 0000000..8396132
--- /dev/null
+++ b/dojox/charting/plot2d/StackedLines.js
@@ -0,0 +1,15 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.StackedLines"]){
+dojo._hasResource["dojox.charting.plot2d.StackedLines"]=true;
+dojo.provide("dojox.charting.plot2d.StackedLines");
+dojo.require("dojox.charting.plot2d.Stacked");
+dojo.declare("dojox.charting.plot2d.StackedLines",dojox.charting.plot2d.Stacked,{constructor:function(){
+this.opt.lines=true;
+}});
+}
diff --git a/dojox/charting/plot2d/common.js b/dojox/charting/plot2d/common.js
new file mode 100644
index 0000000..a15dd5b
--- /dev/null
+++ b/dojox/charting/plot2d/common.js
@@ -0,0 +1,210 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot2d.common"]){
+dojo._hasResource["dojox.charting.plot2d.common"]=true;
+dojo.provide("dojox.charting.plot2d.common");
+dojo.require("dojo.colors");
+dojo.require("dojox.gfx");
+dojo.require("dojox.lang.functional");
+(function(){
+var df=dojox.lang.functional,dc=dojox.charting.plot2d.common;
+dojo.mixin(dojox.charting.plot2d.common,{makeStroke:function(_3){
+if(!_3){
+return _3;
+}
+if(typeof _3=="string"||_3 instanceof dojo.Color){
+_3={color:_3};
+}
+return dojox.gfx.makeParameters(dojox.gfx.defaultStroke,_3);
+},augmentColor:function(_4,_5){
+var t=new dojo.Color(_4),c=new dojo.Color(_5);
+c.a=t.a;
+return c;
+},augmentStroke:function(_8,_9){
+var s=dc.makeStroke(_8);
+if(s){
+s.color=dc.augmentColor(s.color,_9);
+}
+return s;
+},augmentFill:function(_b,_c){
+var fc,c=new dojo.Color(_c);
+if(typeof _b=="string"||_b instanceof dojo.Color){
+return dc.augmentColor(_b,_c);
+}
+return _b;
+},defaultStats:{hmin:Number.POSITIVE_INFINITY,hmax:Number.NEGATIVE_INFINITY,vmin:Number.POSITIVE_INFINITY,vmax:Number.NEGATIVE_INFINITY},collectSimpleStats:function(_f){
+var _10=dojo.clone(dc.defaultStats);
+for(var i=0;i<_f.length;++i){
+var run=_f[i];
+if(!run.data.length){
+continue;
+}
+if(typeof run.data[0]=="number"){
+var _13=_10.vmin,_14=_10.vmax;
+if(!("ymin" in run)||!("ymax" in run)){
+dojo.forEach(run.data,function(val,i){
+var x=i+1,y=val;
+if(isNaN(y)){
+y=0;
+}
+_10.hmin=Math.min(_10.hmin,x);
+_10.hmax=Math.max(_10.hmax,x);
+_10.vmin=Math.min(_10.vmin,y);
+_10.vmax=Math.max(_10.vmax,y);
+});
+}
+if("ymin" in run){
+_10.vmin=Math.min(_13,run.ymin);
+}
+if("ymax" in run){
+_10.vmax=Math.max(_14,run.ymax);
+}
+}else{
+var _19=_10.hmin,_1a=_10.hmax,_13=_10.vmin,_14=_10.vmax;
+if(!("xmin" in run)||!("xmax" in run)||!("ymin" in run)||!("ymax" in run)){
+dojo.forEach(run.data,function(val,i){
+var x=val.x,y=val.y;
+if(isNaN(x)){
+x=0;
+}
+if(isNaN(y)){
+y=0;
+}
+_10.hmin=Math.min(_10.hmin,x);
+_10.hmax=Math.max(_10.hmax,x);
+_10.vmin=Math.min(_10.vmin,y);
+_10.vmax=Math.max(_10.vmax,y);
+});
+}
+if("xmin" in run){
+_10.hmin=Math.min(_19,run.xmin);
+}
+if("xmax" in run){
+_10.hmax=Math.max(_1a,run.xmax);
+}
+if("ymin" in run){
+_10.vmin=Math.min(_13,run.ymin);
+}
+if("ymax" in run){
+_10.vmax=Math.max(_14,run.ymax);
+}
+}
+}
+return _10;
+},calculateBarSize:function(_1f,opt,_21){
+if(!_21){
+_21=1;
+}
+var gap=opt.gap,_23=(_1f-2*gap)/_21;
+if("minBarSize" in opt){
+_23=Math.max(_23,opt.minBarSize);
+}
+if("maxBarSize" in opt){
+_23=Math.min(_23,opt.maxBarSize);
+}
+_23=Math.max(_23,1);
+gap=(_1f-_23*_21)/2;
+return {size:_23,gap:gap};
+},collectStackedStats:function(_24){
+var _25=dojo.clone(dc.defaultStats);
+if(_24.length){
+_25.hmin=Math.min(_25.hmin,1);
+_25.hmax=df.foldl(_24,"seed, run -> Math.max(seed, run.data.length)",_25.hmax);
+for(var i=0;i<_25.hmax;++i){
+var v=_24[0].data[i];
+if(isNaN(v)){
+v=0;
+}
+_25.vmin=Math.min(_25.vmin,v);
+for(var j=1;j<_24.length;++j){
+var t=_24[j].data[i];
+if(isNaN(t)){
+t=0;
+}
+v+=t;
+}
+_25.vmax=Math.max(_25.vmax,v);
+}
+}
+return _25;
+},curve:function(a,_2b){
+var arr=a.slice(0);
+if(_2b=="x"){
+arr[arr.length]=arr[0];
+}
+var p=dojo.map(arr,function(_2e,i){
+if(i==0){
+return "M"+_2e.x+","+_2e.y;
+}
+if(!isNaN(_2b)){
+var dx=_2e.x-arr[i-1].x,dy=arr[i-1].y;
+return "C"+(_2e.x-(_2b-1)*(dx/_2b))+","+dy+" "+(_2e.x-(dx/_2b))+","+_2e.y+" "+_2e.x+","+_2e.y;
+}else{
+if(_2b=="X"||_2b=="x"||_2b=="S"){
+var p0,p1=arr[i-1],p2=arr[i],p3;
+var _36,_37,_38,_39;
+var f=1/6;
+if(i==1){
+if(_2b=="x"){
+p0=arr[arr.length-2];
+}else{
+p0=p1;
+}
+f=1/3;
+}else{
+p0=arr[i-2];
+}
+if(i==(arr.length-1)){
+if(_2b=="x"){
+p3=arr[1];
+}else{
+p3=p2;
+}
+f=1/3;
+}else{
+p3=arr[i+1];
+}
+var _3b=Math.sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));
+var _3c=Math.sqrt((p2.x-p0.x)*(p2.x-p0.x)+(p2.y-p0.y)*(p2.y-p0.y));
+var _3d=Math.sqrt((p3.x-p1.x)*(p3.x-p1.x)+(p3.y-p1.y)*(p3.y-p1.y));
+var _3e=_3c*f;
+var _3f=_3d*f;
+if(_3e>_3b/2&&_3f>_3b/2){
+_3e=_3b/2;
+_3f=_3b/2;
+}else{
+if(_3e>_3b/2){
+_3e=_3b/2;
+_3f=_3b/2*_3d/_3c;
+}else{
+if(_3f>_3b/2){
+_3f=_3b/2;
+_3e=_3b/2*_3c/_3d;
+}
+}
+}
+if(_2b=="S"){
+if(p0==p1){
+_3e=0;
+}
+if(p2==p3){
+_3f=0;
+}
+}
+_36=p1.x+_3e*(p2.x-p0.x)/_3c;
+_37=p1.y+_3e*(p2.y-p0.y)/_3c;
+_38=p2.x-_3f*(p3.x-p1.x)/_3d;
+_39=p2.y-_3f*(p3.y-p1.y)/_3d;
+}
+}
+return "C"+(_36+","+_37+" "+_38+","+_39+" "+p2.x+","+p2.y);
+});
+return p.join(" ");
+}});
+})();
+}
diff --git a/dojox/charting/plot3d/Bars.js b/dojox/charting/plot3d/Bars.js
new file mode 100644
index 0000000..82a371a
--- /dev/null
+++ b/dojox/charting/plot3d/Bars.js
@@ -0,0 +1,64 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot3d.Bars"]){
+dojo._hasResource["dojox.charting.plot3d.Bars"]=true;
+dojo.provide("dojox.charting.plot3d.Bars");
+dojo.require("dojox.charting.plot3d.Base");
+(function(){
+var _1=function(a,f,o){
+a=typeof a=="string"?a.split(""):a;
+o=o||dojo.global;
+var z=a[0];
+for(var i=1;i<a.length;z=f.call(o,z,a[i++])){
+}
+return z;
+};
+dojo.declare("dojox.charting.plot3d.Bars",dojox.charting.plot3d.Base,{constructor:function(_7,_8,_9){
+this.depth="auto";
+this.gap=0;
+this.data=[];
+this.material={type:"plastic",finish:"dull",color:"lime"};
+if(_9){
+if("depth" in _9){
+this.depth=_9.depth;
+}
+if("gap" in _9){
+this.gap=_9.gap;
+}
+if("material" in _9){
+var m=_9.material;
+if(typeof m=="string"||m instanceof dojo.Color){
+this.material.color=m;
+}else{
+this.material=m;
+}
+}
+}
+},getDepth:function(){
+if(this.depth=="auto"){
+var w=this.width;
+if(this.data&&this.data.length){
+w=w/this.data.length;
+}
+return w-2*this.gap;
+}
+return this.depth;
+},generate:function(_c,_d){
+if(!this.data){
+return this;
+}
+var _e=this.width/this.data.length,_f=0,_10=this.depth=="auto"?_e-2*this.gap:this.depth,_11=this.height/_1(this.data,Math.max);
+if(!_d){
+_d=_c.view;
+}
+for(var i=0;i<this.data.length;++i,_f+=_e){
+_d.createCube({bottom:{x:_f+this.gap,y:0,z:0},top:{x:_f+_e-this.gap,y:this.data[i]*_11,z:_10}}).setFill(this.material);
+}
+}});
+})();
+}
diff --git a/dojox/charting/plot3d/Base.js b/dojox/charting/plot3d/Base.js
new file mode 100644
index 0000000..452e0b0
--- /dev/null
+++ b/dojox/charting/plot3d/Base.js
@@ -0,0 +1,22 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot3d.Base"]){
+dojo._hasResource["dojox.charting.plot3d.Base"]=true;
+dojo.provide("dojox.charting.plot3d.Base");
+dojo.require("dojox.charting.Chart3D");
+dojo.declare("dojox.charting.plot3d.Base",null,{constructor:function(_1,_2,_3){
+this.width=_1;
+this.height=_2;
+},setData:function(_4){
+this.data=_4?_4:[];
+return this;
+},getDepth:function(){
+return this.depth;
+},generate:function(_5,_6){
+}});
+}
diff --git a/dojox/charting/plot3d/Cylinders.js b/dojox/charting/plot3d/Cylinders.js
new file mode 100644
index 0000000..5344570
--- /dev/null
+++ b/dojox/charting/plot3d/Cylinders.js
@@ -0,0 +1,68 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.plot3d.Cylinders"]){
+dojo._hasResource["dojox.charting.plot3d.Cylinders"]=true;
+dojo.provide("dojox.charting.plot3d.Cylinders");
+dojo.require("dojox.charting.plot3d.Base");
+(function(){
+var _1=function(a,f,o){
+a=typeof a=="string"?a.split(""):a;
+o=o||dojo.global;
+var z=a[0];
+for(var i=1;i<a.length;z=f.call(o,z,a[i++])){
+}
+return z;
+};
+dojo.declare("dojox.charting.plot3d.Cylinders",dojox.charting.plot3d.Base,{constructor:function(_7,_8,_9){
+this.depth="auto";
+this.gap=0;
+this.data=[];
+this.material={type:"plastic",finish:"shiny",color:"lime"};
+this.outline=null;
+if(_9){
+if("depth" in _9){
+this.depth=_9.depth;
+}
+if("gap" in _9){
+this.gap=_9.gap;
+}
+if("material" in _9){
+var m=_9.material;
+if(typeof m=="string"||m instanceof dojo.Color){
+this.material.color=m;
+}else{
+this.material=m;
+}
+}
+if("outline" in _9){
+this.outline=_9.outline;
+}
+}
+},getDepth:function(){
+if(this.depth=="auto"){
+var w=this.width;
+if(this.data&&this.data.length){
+w=w/this.data.length;
+}
+return w-2*this.gap;
+}
+return this.depth;
+},generate:function(_c,_d){
+if(!this.data){
+return this;
+}
+var _e=this.width/this.data.length,_f=0,_10=this.height/_1(this.data,Math.max);
+if(!_d){
+_d=_c.view;
+}
+for(var i=0;i<this.data.length;++i,_f+=_e){
+_d.createCylinder({center:{x:_f+_e/2,y:0,z:0},radius:_e/2-this.gap,height:this.data[i]*_10}).setTransform(dojox.gfx3d.matrix.rotateXg(-90)).setFill(this.material).setStroke(this.outline);
+}
+}});
+})();
+}
diff --git a/dojox/charting/scaler/common.js b/dojox/charting/scaler/common.js
new file mode 100644
index 0000000..1fd86bb
--- /dev/null
+++ b/dojox/charting/scaler/common.js
@@ -0,0 +1,56 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.scaler.common"]){
+dojo._hasResource["dojox.charting.scaler.common"]=true;
+dojo.provide("dojox.charting.scaler.common");
+(function(){
+var eq=function(a,b){
+return Math.abs(a-b)<=0.000001*(Math.abs(a)+Math.abs(b));
+};
+dojo.mixin(dojox.charting.scaler.common,{findString:function(_4,_5){
+_4=_4.toLowerCase();
+for(var i=0;i<_5.length;++i){
+if(_4==_5[i]){
+return true;
+}
+}
+return false;
+},getNumericLabel:function(_7,_8,_9){
+var _a=_9.fixed?_7.toFixed(_8<0?-_8:0):_7.toString();
+if(_9.labelFunc){
+var r=_9.labelFunc(_a,_7,_8);
+if(r){
+return r;
+}
+}
+if(_9.labels){
+var l=_9.labels,lo=0,hi=l.length;
+while(lo<hi){
+var _f=Math.floor((lo+hi)/2),val=l[_f].value;
+if(val<_7){
+lo=_f+1;
+}else{
+hi=_f;
+}
+}
+if(lo<l.length&&eq(l[lo].value,_7)){
+return l[lo].text;
+}
+--lo;
+if(lo>=0&&lo<l.length&&eq(l[lo].value,_7)){
+return l[lo].text;
+}
+lo+=2;
+if(lo<l.length&&eq(l[lo].value,_7)){
+return l[lo].text;
+}
+}
+return _a;
+}});
+})();
+}
diff --git a/dojox/charting/scaler/linear.js b/dojox/charting/scaler/linear.js
new file mode 100644
index 0000000..8a614f1
--- /dev/null
+++ b/dojox/charting/scaler/linear.js
@@ -0,0 +1,217 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.scaler.linear"]){
+dojo._hasResource["dojox.charting.scaler.linear"]=true;
+dojo.provide("dojox.charting.scaler.linear");
+dojo.require("dojox.charting.scaler.common");
+(function(){
+var _1=3,dc=dojox.charting,_3=dc.scaler,_4=_3.common,_5=_4.findString,_6=_4.getNumericLabel;
+var _7=function(_8,_9,_a,_b,_c,_d,_e){
+_a=dojo.delegate(_a);
+if(!_b){
+if(_a.fixUpper=="major"){
+_a.fixUpper="minor";
+}
+if(_a.fixLower=="major"){
+_a.fixLower="minor";
+}
+}
+if(!_c){
+if(_a.fixUpper=="minor"){
+_a.fixUpper="micro";
+}
+if(_a.fixLower=="minor"){
+_a.fixLower="micro";
+}
+}
+if(!_d){
+if(_a.fixUpper=="micro"){
+_a.fixUpper="none";
+}
+if(_a.fixLower=="micro"){
+_a.fixLower="none";
+}
+}
+var _f=_5(_a.fixLower,["major"])?Math.floor(_a.min/_b)*_b:_5(_a.fixLower,["minor"])?Math.floor(_a.min/_c)*_c:_5(_a.fixLower,["micro"])?Math.floor(_a.min/_d)*_d:_a.min,_10=_5(_a.fixUpper,["major"])?Math.ceil(_a.max/_b)*_b:_5(_a.fixUpper,["minor"])?Math.ceil(_a.max/_c)*_c:_5(_a.fixUpper,["micro"])?Math.ceil(_a.max/_d)*_d:_a.max;
+if(_a.useMin){
+_8=_f;
+}
+if(_a.useMax){
+_9=_10;
+}
+var _11=(!_b||_a.useMin&&_5(_a.fixLower,["major"]))?_8:Math.ceil(_8/_b)*_b,_12=(!_c||_a.useMin&&_5(_a.fixLower,["major","minor"]))?_8:Math.ceil(_8/_c)*_c,_13=(!_d||_a.useMin&&_5(_a.fixLower,["major","minor","micro"]))?_8:Math.ceil(_8/_d)*_d,_14=!_b?0:(_a.useMax&&_5(_a.fixUpper,["major"])?Math.round((_9-_11)/_b):Math.floor((_9-_11)/_b))+1,_15=!_c?0:(_a.useMax&&_5(_a.fixUpper,["major","minor"])?Math.round((_9-_12)/_c):Math.floor((_9-_12)/_c))+1,_16=!_d?0:(_a.useMax&&_5(_a.fixUpper,["major" [...]
+if(!isFinite(_1b)){
+_1b=1;
+}
+return {bounds:{lower:_f,upper:_10,from:_8,to:_9,scale:_1b,span:_e},major:{tick:_b,start:_11,count:_14,prec:_19},minor:{tick:_c,start:_12,count:_15,prec:_1a},micro:{tick:_d,start:_13,count:_16,prec:0},minorPerMajor:_17,microPerMinor:_18,scaler:_3.linear};
+};
+dojo.mixin(dojox.charting.scaler.linear,{buildScaler:function(min,max,_1e,_1f){
+var h={fixUpper:"none",fixLower:"none",natural:false};
+if(_1f){
+if("fixUpper" in _1f){
+h.fixUpper=String(_1f.fixUpper);
+}
+if("fixLower" in _1f){
+h.fixLower=String(_1f.fixLower);
+}
+if("natural" in _1f){
+h.natural=Boolean(_1f.natural);
+}
+}
+if("min" in _1f){
+min=_1f.min;
+}
+if("max" in _1f){
+max=_1f.max;
+}
+if(_1f.includeZero){
+if(min>0){
+min=0;
+}
+if(max<0){
+max=0;
+}
+}
+h.min=min;
+h.useMin=true;
+h.max=max;
+h.useMax=true;
+if("from" in _1f){
+min=_1f.from;
+h.useMin=false;
+}
+if("to" in _1f){
+max=_1f.to;
+h.useMax=false;
+}
+if(max<=min){
+return _7(min,max,h,0,0,0,_1e);
+}
+var mag=Math.floor(Math.log(max-min)/Math.LN10),_22=_1f&&("majorTickStep" in _1f)?_1f.majorTickStep:Math.pow(10,mag),_23=0,_24=0,_25;
+if(_1f&&("minorTickStep" in _1f)){
+_23=_1f.minorTickStep;
+}else{
+do{
+_23=_22/10;
+if(!h.natural||_23>0.9){
+_25=_7(min,max,h,_22,_23,0,_1e);
+if(_25.bounds.scale*_25.minor.tick>_1){
+break;
+}
+}
+_23=_22/5;
+if(!h.natural||_23>0.9){
+_25=_7(min,max,h,_22,_23,0,_1e);
+if(_25.bounds.scale*_25.minor.tick>_1){
+break;
+}
+}
+_23=_22/2;
+if(!h.natural||_23>0.9){
+_25=_7(min,max,h,_22,_23,0,_1e);
+if(_25.bounds.scale*_25.minor.tick>_1){
+break;
+}
+}
+return _7(min,max,h,_22,0,0,_1e);
+}while(false);
+}
+if(_1f&&("microTickStep" in _1f)){
+_24=_1f.microTickStep;
+_25=_7(min,max,h,_22,_23,_24,_1e);
+}else{
+do{
+_24=_23/10;
+if(!h.natural||_24>0.9){
+_25=_7(min,max,h,_22,_23,_24,_1e);
+if(_25.bounds.scale*_25.micro.tick>_1){
+break;
+}
+}
+_24=_23/5;
+if(!h.natural||_24>0.9){
+_25=_7(min,max,h,_22,_23,_24,_1e);
+if(_25.bounds.scale*_25.micro.tick>_1){
+break;
+}
+}
+_24=_23/2;
+if(!h.natural||_24>0.9){
+_25=_7(min,max,h,_22,_23,_24,_1e);
+if(_25.bounds.scale*_25.micro.tick>_1){
+break;
+}
+}
+_24=0;
+}while(false);
+}
+return _24?_25:_7(min,max,h,_22,_23,0,_1e);
+},buildTicks:function(_26,_27){
+var _28,_29,_2a,_2b=_26.major.start,_2c=_26.minor.start,_2d=_26.micro.start;
+if(_27.microTicks&&_26.micro.tick){
+_28=_26.micro.tick,_29=_2d;
+}else{
+if(_27.minorTicks&&_26.minor.tick){
+_28=_26.minor.tick,_29=_2c;
+}else{
+if(_26.major.tick){
+_28=_26.major.tick,_29=_2b;
+}else{
+return null;
+}
+}
+}
+var _2e=1/_26.bounds.scale;
+if(_26.bounds.to<=_26.bounds.from||isNaN(_2e)||!isFinite(_2e)||_28<=0||isNaN(_28)||!isFinite(_28)){
+return null;
+}
+var _2f=[],_30=[],_31=[];
+while(_29<=_26.bounds.to+_2e){
+if(Math.abs(_2b-_29)<_28/2){
+_2a={value:_2b};
+if(_27.majorLabels){
+_2a.label=_6(_2b,_26.major.prec,_27);
+}
+_2f.push(_2a);
+_2b+=_26.major.tick;
+_2c+=_26.minor.tick;
+_2d+=_26.micro.tick;
+}else{
+if(Math.abs(_2c-_29)<_28/2){
+if(_27.minorTicks){
+_2a={value:_2c};
+if(_27.minorLabels&&(_26.minMinorStep<=_26.minor.tick*_26.bounds.scale)){
+_2a.label=_6(_2c,_26.minor.prec,_27);
+}
+_30.push(_2a);
+}
+_2c+=_26.minor.tick;
+_2d+=_26.micro.tick;
+}else{
+if(_27.microTicks){
+_31.push({value:_2d});
+}
+_2d+=_26.micro.tick;
+}
+}
+_29+=_28;
+}
+return {major:_2f,minor:_30,micro:_31};
+},getTransformerFromModel:function(_32){
+var _33=_32.bounds.from,_34=_32.bounds.scale;
+return function(x){
+return (x-_33)*_34;
+};
+},getTransformerFromPlot:function(_36){
+var _37=_36.bounds.from,_38=_36.bounds.scale;
+return function(x){
+return x/_38+_37;
+};
+}});
+})();
+}
diff --git a/dojox/charting/scaler/primitive.js b/dojox/charting/scaler/primitive.js
new file mode 100644
index 0000000..63efb7e
--- /dev/null
+++ b/dojox/charting/scaler/primitive.js
@@ -0,0 +1,26 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.scaler.primitive"]){
+dojo._hasResource["dojox.charting.scaler.primitive"]=true;
+dojo.provide("dojox.charting.scaler.primitive");
+dojox.charting.scaler.primitive={buildScaler:function(_1,_2,_3,_4){
+return {bounds:{lower:_1,upper:_2,from:_1,to:_2,scale:_3/(_2-_1),span:_3},scaler:dojox.charting.scaler.primitive};
+},buildTicks:function(_5,_6){
+return {major:[],minor:[],micro:[]};
+},getTransformerFromModel:function(_7){
+var _8=_7.bounds.from,_9=_7.bounds.scale;
+return function(x){
+return (x-_8)*_9;
+};
+},getTransformerFromPlot:function(_b){
+var _c=_b.bounds.from,_d=_b.bounds.scale;
+return function(x){
+return x/_d+_c;
+};
+}};
+}
diff --git a/dojox/charting/themes/Adobebricks.js b/dojox/charting/themes/Adobebricks.js
new file mode 100644
index 0000000..010b4ec
--- /dev/null
+++ b/dojox/charting/themes/Adobebricks.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.Adobebricks"]){
+dojo._hasResource["dojox.charting.themes.Adobebricks"]=true;
+dojo.provide("dojox.charting.themes.Adobebricks");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.Adobebricks=new _1.Theme({colors:["#7f2518","#3e170c","#cc3927","#651f0e","#8c271c"]});
+})();
+}
diff --git a/dojox/charting/themes/Algae.js b/dojox/charting/themes/Algae.js
new file mode 100644
index 0000000..2ff4db2
--- /dev/null
+++ b/dojox/charting/themes/Algae.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.Algae"]){
+dojo._hasResource["dojox.charting.themes.Algae"]=true;
+dojo.provide("dojox.charting.themes.Algae");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.Algae=new _1.Theme({colors:["#57808f","#506885","#4f7878","#558f7f","#508567"]});
+})();
+}
diff --git a/dojox/charting/themes/Bahamation.js b/dojox/charting/themes/Bahamation.js
new file mode 100644
index 0000000..9e5e497
--- /dev/null
+++ b/dojox/charting/themes/Bahamation.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.Bahamation"]){
+dojo._hasResource["dojox.charting.themes.Bahamation"]=true;
+dojo.provide("dojox.charting.themes.Bahamation");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.Bahamation=new _1.Theme({colors:["#3f9998","#3fc0c3","#70c058","#ef446f","#c663a6"]});
+})();
+}
diff --git a/dojox/charting/themes/BlueDusk.js b/dojox/charting/themes/BlueDusk.js
new file mode 100644
index 0000000..86bf3aa
--- /dev/null
+++ b/dojox/charting/themes/BlueDusk.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.BlueDusk"]){
+dojo._hasResource["dojox.charting.themes.BlueDusk"]=true;
+dojo.provide("dojox.charting.themes.BlueDusk");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.BlueDusk=new _1.Theme({colors:["#292e76","#3e56a6","#10143f","#33449c","#798dcd"]});
+})();
+}
diff --git a/dojox/charting/themes/CubanShirts.js b/dojox/charting/themes/CubanShirts.js
new file mode 100644
index 0000000..b849905
--- /dev/null
+++ b/dojox/charting/themes/CubanShirts.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.CubanShirts"]){
+dojo._hasResource["dojox.charting.themes.CubanShirts"]=true;
+dojo.provide("dojox.charting.themes.CubanShirts");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.CubanShirts=new _1.Theme({colors:["#d42d2a","#004f80","#989736","#2085c7","#7f7f33"]});
+})();
+}
diff --git a/dojox/charting/themes/Desert.js b/dojox/charting/themes/Desert.js
new file mode 100644
index 0000000..c731b74
--- /dev/null
+++ b/dojox/charting/themes/Desert.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.Desert"]){
+dojo._hasResource["dojox.charting.themes.Desert"]=true;
+dojo.provide("dojox.charting.themes.Desert");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.Desert=new _1.Theme({colors:["#ffebd5","#806544","#fdc888","#80766b","#cda26e"]});
+})();
+}
diff --git a/dojox/charting/themes/Dollar.js b/dojox/charting/themes/Dollar.js
new file mode 100644
index 0000000..2342282
--- /dev/null
+++ b/dojox/charting/themes/Dollar.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.Dollar"]){
+dojo._hasResource["dojox.charting.themes.Dollar"]=true;
+dojo.provide("dojox.charting.themes.Dollar");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.Dollar=new _1.Theme({colors:["#A4CE67","#739363","#6B824A","#343434","#636563"]});
+})();
+}
diff --git a/dojox/charting/themes/ET/greys.js b/dojox/charting/themes/ET/greys.js
new file mode 100644
index 0000000..fb54b5e
--- /dev/null
+++ b/dojox/charting/themes/ET/greys.js
@@ -0,0 +1,17 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.ET.greys"]){
+dojo._hasResource["dojox.charting.themes.ET.greys"]=true;
+dojo.provide("dojox.charting.themes.ET.greys");
+dojo.require("dojox.charting.Theme");
+dojo.deprecated("dojox.charting.themes.ET.greys","1.3");
+(function(){
+var _1=dojox.charting;
+_1.themes.ET.greys=new _1.Theme({antiAlias:false,chart:{stroke:null,fill:"inherit"},plotarea:{stroke:null,fill:"transparent"},axis:{stroke:{width:0},line:{width:0},majorTick:{color:"#666666",width:1,length:5},minorTick:{color:"black",width:0.5,length:2},font:"normal normal normal 8pt Tahoma",fontColor:"#999999"},series:{outline:{width:0,color:"black"},stroke:{width:1,color:"black"},fill:dojo.colorFromHex("#3b444b"),font:"normal normal normal 7pt Tahoma",fontColor:"#717171"},marker:{strok [...]
+})();
+}
diff --git a/dojox/charting/themes/Grasshopper.js b/dojox/charting/themes/Grasshopper.js
new file mode 100644
index 0000000..85f3484
--- /dev/null
+++ b/dojox/charting/themes/Grasshopper.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.Grasshopper"]){
+dojo._hasResource["dojox.charting.themes.Grasshopper"]=true;
+dojo.provide("dojox.charting.themes.Grasshopper");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.Grasshopper=new _1.Theme({colors:["#208040","#40b657","#78c25e","#14401f","#64bd5f"]});
+})();
+}
diff --git a/dojox/charting/themes/Grasslands.js b/dojox/charting/themes/Grasslands.js
new file mode 100644
index 0000000..611bc98
--- /dev/null
+++ b/dojox/charting/themes/Grasslands.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.Grasslands"]){
+dojo._hasResource["dojox.charting.themes.Grasslands"]=true;
+dojo.provide("dojox.charting.themes.Grasslands");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.Grasslands=new _1.Theme({colors:["#70803a","#dde574","#788062","#b1cc5d","#eff2c2"]});
+})();
+}
diff --git a/dojox/charting/themes/GreySkies.js b/dojox/charting/themes/GreySkies.js
new file mode 100644
index 0000000..eb3cba5
--- /dev/null
+++ b/dojox/charting/themes/GreySkies.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.GreySkies"]){
+dojo._hasResource["dojox.charting.themes.GreySkies"]=true;
+dojo.provide("dojox.charting.themes.GreySkies");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.GreySkies=new _1.Theme(_1.Theme._def);
+})();
+}
diff --git a/dojox/charting/themes/IndigoNation.js b/dojox/charting/themes/IndigoNation.js
new file mode 100644
index 0000000..706d637
--- /dev/null
+++ b/dojox/charting/themes/IndigoNation.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.IndigoNation"]){
+dojo._hasResource["dojox.charting.themes.IndigoNation"]=true;
+dojo.provide("dojox.charting.themes.IndigoNation");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.IndigoNation=new _1.Theme({colors:["#93a4d0","#3b4152","#687291","#9faed9","#8290b8"]});
+})();
+}
diff --git a/dojox/charting/themes/Ireland.js b/dojox/charting/themes/Ireland.js
new file mode 100644
index 0000000..bec47ad
--- /dev/null
+++ b/dojox/charting/themes/Ireland.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.Ireland"]){
+dojo._hasResource["dojox.charting.themes.Ireland"]=true;
+dojo.provide("dojox.charting.themes.Ireland");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.Ireland=new _1.Theme({colors:["#abdbcb","#435a51","#70998b","#78q596","#5f8074"]});
+})();
+}
diff --git a/dojox/charting/themes/MiamiNice.js b/dojox/charting/themes/MiamiNice.js
new file mode 100644
index 0000000..1a1714a
--- /dev/null
+++ b/dojox/charting/themes/MiamiNice.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.MiamiNice"]){
+dojo._hasResource["dojox.charting.themes.MiamiNice"]=true;
+dojo.provide("dojox.charting.themes.MiamiNice");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.MiamiNice=new _1.Theme({colors:["#7f9599","#45b8cc","#8ecfb0","#f8acac","#cc4482"]});
+})();
+}
diff --git a/dojox/charting/themes/Midwest.js b/dojox/charting/themes/Midwest.js
new file mode 100644
index 0000000..f1d48b7
--- /dev/null
+++ b/dojox/charting/themes/Midwest.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.Midwest"]){
+dojo._hasResource["dojox.charting.themes.Midwest"]=true;
+dojo.provide("dojox.charting.themes.Midwest");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.Midwest=new _1.Theme({colors:["#927b51","#a89166","#80c31c","#bcdd5a","#aebc21"]});
+})();
+}
diff --git a/dojox/charting/themes/Minty.js b/dojox/charting/themes/Minty.js
new file mode 100644
index 0000000..5a290ce
--- /dev/null
+++ b/dojox/charting/themes/Minty.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.Minty"]){
+dojo._hasResource["dojox.charting.themes.Minty"]=true;
+dojo.provide("dojox.charting.themes.Minty");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.Minty=new _1.Theme({colors:["#80ccbb","#539e8b","#335f54","#8dd1c2","#68c5ad"]});
+})();
+}
diff --git a/dojox/charting/themes/PlotKit/README b/dojox/charting/themes/PlotKit/README
new file mode 100644
index 0000000..dbf4c81
--- /dev/null
+++ b/dojox/charting/themes/PlotKit/README
@@ -0,0 +1,11 @@
+This directory contains a set of themes for the DojoX Charting 
+engine that are based on the visual stylings of the PlotKit
+chart kit, created by Alastair Tse:
+
+http://www.liquidx.net/plotkit/
+
+...whose work we admire.  Consider these themes to not be a 
+ripoff of his fine work, but instead a true homage: his charts
+are beautiful, and we stand in awe.
+
+--trt, 2007-06-08
diff --git a/dojox/charting/themes/PlotKit/blue.js b/dojox/charting/themes/PlotKit/blue.js
new file mode 100644
index 0000000..733b23b
--- /dev/null
+++ b/dojox/charting/themes/PlotKit/blue.js
@@ -0,0 +1,17 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.PlotKit.blue"]){
+dojo._hasResource["dojox.charting.themes.PlotKit.blue"]=true;
+dojo.provide("dojox.charting.themes.PlotKit.blue");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.PlotKit.blue=new _1.Theme({chart:{stroke:null,fill:"white"},plotarea:{stroke:null,fill:"#e7eef6"},axis:{stroke:{color:"#fff",width:2},line:{color:"#fff",width:1},majorTick:{color:"#fff",width:2,length:12},minorTick:{color:"#fff",width:1,length:8},font:"normal normal normal 8pt Tahoma",fontColor:"#999"},series:{outline:{width:0.1,color:"#fff"},stroke:{width:1.5,color:"#666"},fill:new dojo.Color([102,102,102,0.8]),font:"normal normal normal 7pt Tahoma",fontColor:"#000"},marker:{s [...]
+_1.themes.PlotKit.blue.defineColors({hue:217,saturation:60,low:40,high:88});
+})();
+}
diff --git a/dojox/charting/themes/PlotKit/cyan.js b/dojox/charting/themes/PlotKit/cyan.js
new file mode 100644
index 0000000..c97d371
--- /dev/null
+++ b/dojox/charting/themes/PlotKit/cyan.js
@@ -0,0 +1,17 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.PlotKit.cyan"]){
+dojo._hasResource["dojox.charting.themes.PlotKit.cyan"]=true;
+dojo.provide("dojox.charting.themes.PlotKit.cyan");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.PlotKit.cyan=new _1.Theme({chart:{stroke:null,fill:"white"},plotarea:{stroke:null,fill:"#e6f1f5"},axis:{stroke:{color:"#fff",width:2},line:{color:"#fff",width:1},majorTick:{color:"#fff",width:2,length:12},minorTick:{color:"#fff",width:1,length:8},font:"normal normal normal 8pt Tahoma",fontColor:"#999"},series:{outline:{width:1,color:"#fff"},stroke:{width:2,color:"#666"},fill:new dojo.Color([102,102,102,0.8]),font:"normal normal normal 7pt Tahoma",fontColor:"#000"},marker:{strok [...]
+_1.themes.PlotKit.cyan.defineColors({hue:194,saturation:60,low:40,high:88});
+})();
+}
diff --git a/dojox/charting/themes/PlotKit/green.js b/dojox/charting/themes/PlotKit/green.js
new file mode 100644
index 0000000..1955efd
--- /dev/null
+++ b/dojox/charting/themes/PlotKit/green.js
@@ -0,0 +1,17 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.PlotKit.green"]){
+dojo._hasResource["dojox.charting.themes.PlotKit.green"]=true;
+dojo.provide("dojox.charting.themes.PlotKit.green");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.PlotKit.green=new _1.Theme({chart:{stroke:null,fill:"white"},plotarea:{stroke:null,fill:"#eff5e6"},axis:{stroke:{color:"#fff",width:2},line:{color:"#fff",width:1},majorTick:{color:"#fff",width:2,length:12},minorTick:{color:"#fff",width:1,length:8},font:"normal normal normal 8pt Tahoma",fontColor:"#999"},series:{outline:{width:1,color:"#fff"},stroke:{width:2,color:"#666"},fill:new dojo.Color([102,102,102,0.8]),font:"normal normal normal 7pt Tahoma",fontColor:"#000"},marker:{stro [...]
+_1.themes.PlotKit.green.defineColors({hue:82,saturation:60,low:40,high:88});
+})();
+}
diff --git a/dojox/charting/themes/PlotKit/orange.js b/dojox/charting/themes/PlotKit/orange.js
new file mode 100644
index 0000000..3f45bf6
--- /dev/null
+++ b/dojox/charting/themes/PlotKit/orange.js
@@ -0,0 +1,17 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.PlotKit.orange"]){
+dojo._hasResource["dojox.charting.themes.PlotKit.orange"]=true;
+dojo.provide("dojox.charting.themes.PlotKit.orange");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.PlotKit.orange=new _1.Theme({chart:{stroke:null,fill:"white"},plotarea:{stroke:null,fill:"#f5eee6"},axis:{stroke:{color:"#fff",width:2},line:{color:"#fff",width:1},majorTick:{color:"#fff",width:2,length:12},minorTick:{color:"#fff",width:1,length:8},font:"normal normal normal 8pt Tahoma",fontColor:"#999"},series:{outline:{width:0.15,color:"#fff"},stroke:{width:1.5,color:"#666"},fill:new dojo.Color([102,102,102,0.8]),font:"normal normal normal 7pt Tahoma",fontColor:"#000"},marker [...]
+_1.themes.PlotKit.orange.defineColors({hue:31,saturation:60,low:40,high:88});
+})();
+}
diff --git a/dojox/charting/themes/PlotKit/purple.js b/dojox/charting/themes/PlotKit/purple.js
new file mode 100644
index 0000000..2ca8a18
--- /dev/null
+++ b/dojox/charting/themes/PlotKit/purple.js
@@ -0,0 +1,17 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.PlotKit.purple"]){
+dojo._hasResource["dojox.charting.themes.PlotKit.purple"]=true;
+dojo.provide("dojox.charting.themes.PlotKit.purple");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.PlotKit.purple=new _1.Theme({chart:{stroke:null,fill:"white"},plotarea:{stroke:null,fill:"#eee6f5"},axis:{stroke:{color:"#fff",width:2},line:{color:"#fff",width:1},majorTick:{color:"#fff",width:2,length:12},minorTick:{color:"#fff",width:1,length:8},font:"normal normal normal 8pt Tahoma",fontColor:"#999"},series:{outline:{width:1,color:"#fff"},stroke:{width:2,color:"#666"},fill:new dojo.Color([102,102,102,0.8]),font:"normal normal normal 7pt Tahoma",fontColor:"#000"},marker:{str [...]
+_1.themes.PlotKit.purple.defineColors({hue:271,saturation:60,low:40,high:88});
+})();
+}
diff --git a/dojox/charting/themes/PlotKit/red.js b/dojox/charting/themes/PlotKit/red.js
new file mode 100644
index 0000000..b47a330
--- /dev/null
+++ b/dojox/charting/themes/PlotKit/red.js
@@ -0,0 +1,17 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.PlotKit.red"]){
+dojo._hasResource["dojox.charting.themes.PlotKit.red"]=true;
+dojo.provide("dojox.charting.themes.PlotKit.red");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.PlotKit.red=new _1.Theme({chart:{stroke:null,fill:"white"},plotarea:{stroke:null,fill:"#f5e6e6"},axis:{stroke:{color:"#fff",width:2},line:{color:"#fff",width:1},majorTick:{color:"#fff",width:2,length:12},minorTick:{color:"#fff",width:1,length:8},font:"normal normal normal 8pt Tahoma",fontColor:"#999"},series:{outline:{width:1,color:"#fff"},stroke:{width:2,color:"#666"},fill:new dojo.Color([102,102,102,0.8]),font:"normal normal normal 7pt Tahoma",fontColor:"#000"},marker:{stroke [...]
+_1.themes.PlotKit.red.defineColors({hue:1,saturation:60,low:40,high:88});
+})();
+}
diff --git a/dojox/charting/themes/PurpleRain.js b/dojox/charting/themes/PurpleRain.js
new file mode 100644
index 0000000..d755fcf
--- /dev/null
+++ b/dojox/charting/themes/PurpleRain.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.PurpleRain"]){
+dojo._hasResource["dojox.charting.themes.PurpleRain"]=true;
+dojo.provide("dojox.charting.themes.PurpleRain");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.PurpleRain=new _1.Theme({colors:["#4879bc","#ef446f","#3f58a7","#8254a2","#4956a6"]});
+})();
+}
diff --git a/dojox/charting/themes/README b/dojox/charting/themes/README
new file mode 100644
index 0000000..9a3725d
--- /dev/null
+++ b/dojox/charting/themes/README
@@ -0,0 +1,5 @@
+Theme authors:
+
+GreySkies, Shrooms, PlotKit (all): Tom Trenka (ttrenka AT gmail.com)
+ET (all): Alex Russell (alex AT dojotoolkit.org)
+Ireland, SageToLime, Minty: Damon Dimmick (SitePen, Inc.)
diff --git a/dojox/charting/themes/RoyalPurples.js b/dojox/charting/themes/RoyalPurples.js
new file mode 100644
index 0000000..a44ae8b
--- /dev/null
+++ b/dojox/charting/themes/RoyalPurples.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.RoyalPurples"]){
+dojo._hasResource["dojox.charting.themes.RoyalPurples"]=true;
+dojo.provide("dojox.charting.themes.RoyalPurples");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.RoyalPurples=new _1.Theme({colors:["#473980","#685aa7","#7970b3","#231c3f","#7267ae"]});
+})();
+}
diff --git a/dojox/charting/themes/SageToLime.js b/dojox/charting/themes/SageToLime.js
new file mode 100644
index 0000000..38db603
--- /dev/null
+++ b/dojox/charting/themes/SageToLime.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.SageToLime"]){
+dojo._hasResource["dojox.charting.themes.SageToLime"]=true;
+dojo.provide("dojox.charting.themes.SageToLime");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.SageToLime=new _1.Theme({colors:["#abdbcb","#435a51","#70998b","#5f8074","#80ccbb","#539e8b","#78a596","#335f54","#8dd1c2","#68c5ad"]});
+})();
+}
diff --git a/dojox/charting/themes/Shrooms.js b/dojox/charting/themes/Shrooms.js
new file mode 100644
index 0000000..8524b61
--- /dev/null
+++ b/dojox/charting/themes/Shrooms.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.Shrooms"]){
+dojo._hasResource["dojox.charting.themes.Shrooms"]=true;
+dojo.provide("dojox.charting.themes.Shrooms");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.Shrooms=new _1.Theme({colors:["#bf1313","#69bf13","#13bfbf","#6913bf","#bf6913","#13bf13","#1369bf","#bf13bf","#bfbf13","#13bf69","#1313bf","#bf1369"]});
+})();
+}
diff --git a/dojox/charting/themes/Tufte.js b/dojox/charting/themes/Tufte.js
new file mode 100644
index 0000000..5677bc2
--- /dev/null
+++ b/dojox/charting/themes/Tufte.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.Tufte"]){
+dojo._hasResource["dojox.charting.themes.Tufte"]=true;
+dojo.provide("dojox.charting.themes.Tufte");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.Tufte=new _1.Theme({antiAlias:false,chart:{stroke:null,fill:"inherit"},plotarea:{stroke:null,fill:"transparent"},axis:{stroke:{width:0},line:{width:0},majorTick:{color:"#666666",width:1,length:5},minorTick:{color:"black",width:1,length:2},font:"normal normal normal 8pt Tahoma",fontColor:"#999999"},series:{outline:{width:0,color:"black"},stroke:{width:1,color:"black"},fill:new dojo.Color([59,68,75,0.85]),font:"normal normal normal 7pt Tahoma",fontColor:"#717171"},marker:{stroke: [...]
+})();
+}
diff --git a/dojox/charting/themes/WatersEdge.js b/dojox/charting/themes/WatersEdge.js
new file mode 100644
index 0000000..3c1469e
--- /dev/null
+++ b/dojox/charting/themes/WatersEdge.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.WatersEdge"]){
+dojo._hasResource["dojox.charting.themes.WatersEdge"]=true;
+dojo.provide("dojox.charting.themes.WatersEdge");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.WatersEdge=new _1.Theme({colors:["#437cc0","#6256a5","#4552a3","#43c4f2","#4b66b0"]});
+})();
+}
diff --git a/dojox/charting/themes/Wetland.js b/dojox/charting/themes/Wetland.js
new file mode 100644
index 0000000..a3ff02c
--- /dev/null
+++ b/dojox/charting/themes/Wetland.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.themes.Wetland"]){
+dojo._hasResource["dojox.charting.themes.Wetland"]=true;
+dojo.provide("dojox.charting.themes.Wetland");
+dojo.require("dojox.charting.Theme");
+(function(){
+var _1=dojox.charting;
+_1.themes.Wetland=new _1.Theme({colors:["#bfbc64","#737130","#73373b","#7dafca","#8d3c42"]});
+})();
+}
diff --git a/dojox/charting/widget/Chart2D.js b/dojox/charting/widget/Chart2D.js
new file mode 100644
index 0000000..1e1eef0
--- /dev/null
+++ b/dojox/charting/widget/Chart2D.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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 a compiled version of Dojo, built for deployment and not for
+	development. To get an editable version, please visit:
+
+		http://dojotoolkit.org
+
+	for documentation and information on getting the source.
+*/
+
+if(!dojo._hasResource["dijit._base.focus"]){dojo._hasResource["dijit._base.focus"]=true;dojo.provide("dijit._base.focus");dojo.mixin(dijit,{_curFocus:null,_prevFocus:null,isCollapsed:function(){var _1=dojo.doc;if(_1.selection){var s=_1.selection;if(s.type=="Text"){return !s.createRange().htmlText.length;}else{return !s.createRange().length;}}else{var _3=dojo.global;var _4=_3.getSelection();if(dojo.isString(_4)){return !_4;}else{return !_4||_4.isCollapsed||!_4.toString();}}},getBookmark:f [...]
diff --git a/dojox/charting/widget/Chart2D.js.uncompressed.js b/dojox/charting/widget/Chart2D.js.uncompressed.js
new file mode 100644
index 0000000..3010d7c
--- /dev/null
+++ b/dojox/charting/widget/Chart2D.js.uncompressed.js
@@ -0,0 +1,12543 @@
+/*
+	Copyright (c) 2004-2009, 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 a compiled version of Dojo, built for deployment and not for
+	development. To get an editable version, please visit:
+
+		http://dojotoolkit.org
+
+	for documentation and information on getting the source.
+*/
+
+if(!dojo._hasResource["dijit._base.focus"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.focus"] = true;
+dojo.provide("dijit._base.focus");
+
+// summary:
+//		These functions are used to query or set the focus and selection.
+//
+//		Also, they trace when widgets become actived/deactivated,
+//		so that the widget can fire _onFocus/_onBlur events.
+//		"Active" here means something similar to "focused", but
+//		"focus" isn't quite the right word because we keep track of
+//		a whole stack of "active" widgets.  Example:  Combobutton --> Menu -->
+//		MenuItem.   The onBlur event for Combobutton doesn't fire due to focusing
+//		on the Menu or a MenuItem, since they are considered part of the
+//		Combobutton widget.  It only happens when focus is shifted
+//		somewhere completely different.
+
+dojo.mixin(dijit,
+{
+	// _curFocus: DomNode
+	//		Currently focused item on screen
+	_curFocus: null,
+
+	// _prevFocus: DomNode
+	//		Previously focused item on screen
+	_prevFocus: null,
+
+	isCollapsed: function(){
+		// summary:
+		//		Returns true if there is no text selected
+		var _document = dojo.doc;
+		if(_document.selection){ // IE
+			var s=_document.selection;
+			if(s.type=='Text'){
+				return !s.createRange().htmlText.length; // Boolean
+			}else{ //Control range
+				return !s.createRange().length; // Boolean
+			}
+		}else{
+			var _window = dojo.global;
+			var selection = _window.getSelection();
+			
+			if(dojo.isString(selection)){ // Safari
+				// TODO: this is dead code; safari is taking the else branch.  remove after 1.3.
+				return !selection; // Boolean
+			}else{ // Mozilla/W3
+				return !selection || selection.isCollapsed || !selection.toString(); // Boolean
+			}
+		}
+	},
+
+	getBookmark: function(){
+		// summary:
+		//		Retrieves a bookmark that can be used with moveToBookmark to return to the same range
+		var bookmark, selection = dojo.doc.selection;
+		if(selection){ // IE
+			var range = selection.createRange();
+			if(selection.type.toUpperCase()=='CONTROL'){
+				if(range.length){
+					bookmark=[];
+					var i=0,len=range.length;
+					while(i<len){
+						bookmark.push(range.item(i++));
+					}
+				}else{
+					bookmark=null;
+				}
+			}else{
+				bookmark = range.getBookmark();
+			}
+		}else{
+			if(window.getSelection){
+				selection = dojo.global.getSelection();
+				if(selection){
+					range = selection.getRangeAt(0);
+					bookmark = range.cloneRange();
+				}
+			}else{
+				console.warn("No idea how to store the current selection for this browser!");
+			}
+		}
+		return bookmark; // Array
+	},
+
+	moveToBookmark: function(/*Object*/bookmark){
+		// summary:
+		//		Moves current selection to a bookmark
+		// bookmark:
+		//		This should be a returned object from dojo.html.selection.getBookmark()
+		var _document = dojo.doc;
+		if(_document.selection){ // IE
+			var range;
+			if(dojo.isArray(bookmark)){
+				range = _document.body.createControlRange();
+				//range.addElement does not have call/apply method, so can not call it directly
+				//range is not available in "range.addElement(item)", so can't use that either
+				dojo.forEach(bookmark, function(n){
+					range.addElement(n);
+				});
+			}else{
+				range = _document.selection.createRange();
+				range.moveToBookmark(bookmark);
+			}
+			range.select();
+		}else{ //Moz/W3C
+			var selection = dojo.global.getSelection && dojo.global.getSelection();
+			if(selection && selection.removeAllRanges){
+				selection.removeAllRanges();
+				selection.addRange(bookmark);
+			}else{
+				console.warn("No idea how to restore selection for this browser!");
+			}
+		}
+	},
+
+	getFocus: function(/*Widget?*/menu, /*Window?*/openedForWindow){
+		// summary:
+		//		Returns the current focus and selection.
+		//		Called when a popup appears (either a top level menu or a dialog),
+		//		or when a toolbar/menubar receives focus
+		//
+		// menu:
+		//		The menu that's being opened
+		//
+		// openedForWindow:
+		//		iframe in which menu was opened
+		//
+		// returns:
+		//		A handle to restore focus/selection
+
+		return {
+			// Node to return focus to
+			node: menu && dojo.isDescendant(dijit._curFocus, menu.domNode) ? dijit._prevFocus : dijit._curFocus,
+
+			// Previously selected text
+			bookmark:
+				!dojo.withGlobal(openedForWindow||dojo.global, dijit.isCollapsed) ?
+				dojo.withGlobal(openedForWindow||dojo.global, dijit.getBookmark) :
+				null,
+
+			openedForWindow: openedForWindow
+		}; // Object
+	},
+
+	focus: function(/*Object || DomNode */ handle){
+		// summary:
+		//		Sets the focused node and the selection according to argument.
+		//		To set focus to an iframe's content, pass in the iframe itself.
+		// handle:
+		//		object returned by get(), or a DomNode
+
+		if(!handle){ return; }
+
+		var node = "node" in handle ? handle.node : handle,		// because handle is either DomNode or a composite object
+			bookmark = handle.bookmark,
+			openedForWindow = handle.openedForWindow;
+
+		// Set the focus
+		// Note that for iframe's we need to use the <iframe> to follow the parentNode chain,
+		// but we need to set focus to iframe.contentWindow
+		if(node){
+			var focusNode = (node.tagName.toLowerCase()=="iframe") ? node.contentWindow : node;
+			if(focusNode && focusNode.focus){
+				try{
+					// Gecko throws sometimes if setting focus is impossible,
+					// node not displayed or something like that
+					focusNode.focus();
+				}catch(e){/*quiet*/}
+			}			
+			dijit._onFocusNode(node);
+		}
+
+		// set the selection
+		// do not need to restore if current selection is not empty
+		// (use keyboard to select a menu item)
+		if(bookmark && dojo.withGlobal(openedForWindow||dojo.global, dijit.isCollapsed)){
+			if(openedForWindow){
+				openedForWindow.focus();
+			}
+			try{
+				dojo.withGlobal(openedForWindow||dojo.global, dijit.moveToBookmark, null, [bookmark]);
+			}catch(e){
+				/*squelch IE internal error, see http://trac.dojotoolkit.org/ticket/1984 */
+			}
+		}
+	},
+
+	// _activeStack: Array
+	//		List of currently active widgets (focused widget and it's ancestors)
+	_activeStack: [],
+
+	registerIframe: function(/*DomNode*/ iframe){
+		// summary:
+		//		Registers listeners on the specified iframe so that any click
+		//		or focus event on that iframe (or anything in it) is reported
+		//		as a focus/click event on the <iframe> itself.
+		// description:
+		//		Currently only used by editor.
+		dijit.registerWin(iframe.contentWindow, iframe);
+	},
+		
+
+	registerWin: function(/*Window?*/targetWindow, /*DomNode?*/ effectiveNode){
+		// summary:
+		//		Registers listeners on the specified window (either the main
+		//		window or an iframe's window) to detect when the user has clicked somewhere
+		//		or focused somewhere.
+		// description:
+		//		Users should call registerIframe() instead of this method.
+		// targetWindow:
+		//		If specified this is the window associated with the iframe,
+		//		i.e. iframe.contentWindow.
+		// effectiveNode:
+		//		If specified, report any focus events inside targetWindow as
+		//		an event on effectiveNode, rather than on evt.target.
+
+		// TODO: make this function private in 2.0; Editor/users should call registerIframe(),
+		// or if Editor stops using <iframe> altogether than we can probably just drop
+		// the whole public API.
+
+		dojo.connect(targetWindow.document, "onmousedown", function(evt){
+			dijit._justMouseDowned = true;
+			setTimeout(function(){ dijit._justMouseDowned = false; }, 0);
+			dijit._onTouchNode(effectiveNode||evt.target||evt.srcElement);
+		});
+		//dojo.connect(targetWindow, "onscroll", ???);
+
+		// Listen for blur and focus events on targetWindow's document.
+		// IIRC, I'm using attachEvent() rather than dojo.connect() because focus/blur events don't bubble
+		// through dojo.connect(), and also maybe to catch the focus events early, before onfocus handlers
+		// fire.
+		var doc = targetWindow.document;
+		if(doc){
+			if(dojo.isIE){
+				doc.attachEvent('onactivate', function(evt){
+					if(evt.srcElement.tagName.toLowerCase() != "#document"){
+						dijit._onFocusNode(effectiveNode||evt.srcElement);
+					}
+				});
+				doc.attachEvent('ondeactivate', function(evt){
+					dijit._onBlurNode(effectiveNode||evt.srcElement);
+				});
+			}else{
+				doc.addEventListener('focus', function(evt){
+					dijit._onFocusNode(effectiveNode||evt.target);
+				}, true);
+				doc.addEventListener('blur', function(evt){
+					dijit._onBlurNode(effectiveNode||evt.target);
+				}, true);
+			}
+		}
+		doc = null;	// prevent memory leak (apparent circular reference via closure)
+	},
+
+	_onBlurNode: function(/*DomNode*/ node){
+		// summary:
+		// 		Called when focus leaves a node.
+		//		Usually ignored, _unless_ it *isn't* follwed by touching another node,
+		//		which indicates that we tabbed off the last field on the page,
+		//		in which case every widget is marked inactive
+		dijit._prevFocus = dijit._curFocus;
+		dijit._curFocus = null;
+
+		if(dijit._justMouseDowned){
+			// the mouse down caused a new widget to be marked as active; this blur event
+			// is coming late, so ignore it.
+			return;
+		}
+
+		// if the blur event isn't followed by a focus event then mark all widgets as inactive.
+		if(dijit._clearActiveWidgetsTimer){
+			clearTimeout(dijit._clearActiveWidgetsTimer);
+		}
+		dijit._clearActiveWidgetsTimer = setTimeout(function(){
+			delete dijit._clearActiveWidgetsTimer;
+			dijit._setStack([]);
+			dijit._prevFocus = null;
+		}, 100);
+	},
+
+	_onTouchNode: function(/*DomNode*/ node){
+		// summary:
+		//		Callback when node is focused or mouse-downed
+
+		// ignore the recent blurNode event
+		if(dijit._clearActiveWidgetsTimer){
+			clearTimeout(dijit._clearActiveWidgetsTimer);
+			delete dijit._clearActiveWidgetsTimer;
+		}
+
+		// compute stack of active widgets (ex: ComboButton --> Menu --> MenuItem)
+		var newStack=[];
+		try{
+			while(node){
+				if(node.dijitPopupParent){
+					node=dijit.byId(node.dijitPopupParent).domNode;
+				}else if(node.tagName && node.tagName.toLowerCase()=="body"){
+					// is this the root of the document or just the root of an iframe?
+					if(node===dojo.body()){
+						// node is the root of the main document
+						break;
+					}
+					// otherwise, find the iframe this node refers to (can't access it via parentNode,
+					// need to do this trick instead). window.frameElement is supported in IE/FF/Webkit
+					node=dijit.getDocumentWindow(node.ownerDocument).frameElement;
+				}else{
+					var id = node.getAttribute && node.getAttribute("widgetId");
+					if(id){
+						newStack.unshift(id);
+					}
+					node=node.parentNode;
+				}
+			}
+		}catch(e){ /* squelch */ }
+
+		dijit._setStack(newStack);
+	},
+
+	_onFocusNode: function(/*DomNode*/ node){
+		// summary:
+		//		Callback when node is focused
+
+		if(!node){
+			return;
+		}
+
+		if(node.nodeType == 9){
+			// Ignore focus events on the document itself.  This is here so that
+			// (for example) clicking the up/down arrows of a spinner
+			// (which don't get focus) won't cause that widget to blur. (FF issue)
+			return;
+		}
+
+		dijit._onTouchNode(node);
+
+		if(node==dijit._curFocus){ return; }
+		if(dijit._curFocus){
+			dijit._prevFocus = dijit._curFocus;
+		}
+		dijit._curFocus = node;
+		dojo.publish("focusNode", [node]);
+	},
+
+	_setStack: function(newStack){
+		// summary:
+		//		The stack of active widgets has changed.  Send out appropriate events and records new stack.
+
+		var oldStack = dijit._activeStack;
+		dijit._activeStack = newStack;
+
+		// compare old stack to new stack to see how many elements they have in common
+		for(var nCommon=0; nCommon<Math.min(oldStack.length, newStack.length); nCommon++){
+			if(oldStack[nCommon] != newStack[nCommon]){
+				break;
+			}
+		}
+
+		// for all elements that have gone out of focus, send blur event
+		for(var i=oldStack.length-1; i>=nCommon; i--){
+			var widget = dijit.byId(oldStack[i]);
+			if(widget){
+				widget._focused = false;
+				widget._hasBeenBlurred = true;
+				if(widget._onBlur){
+					widget._onBlur();
+				}
+				if (widget._setStateClass){
+					widget._setStateClass();
+				}
+				dojo.publish("widgetBlur", [widget]);
+			}
+		}
+
+		// for all element that have come into focus, send focus event
+		for(i=nCommon; i<newStack.length; i++){
+			widget = dijit.byId(newStack[i]);
+			if(widget){
+				widget._focused = true;
+				if(widget._onFocus){
+					widget._onFocus();
+				}
+				if (widget._setStateClass){
+					widget._setStateClass();
+				}
+				dojo.publish("widgetFocus", [widget]);
+			}
+		}
+	}
+});
+
+// register top window and all the iframes it contains
+dojo.addOnLoad(function(){dijit.registerWin(window); });
+
+}
+
+if(!dojo._hasResource["dijit._base.manager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.manager"] = true;
+dojo.provide("dijit._base.manager");
+
+dojo.declare("dijit.WidgetSet", null, {
+	// summary:
+	//		A set of widgets indexed by id. A default instance of this class is 
+	//		available as `dijit.registry`
+	//
+	// example:
+	//		Create a small list of widgets:
+	//		|	var ws = new dijit.WidgetSet();
+	//		|	ws.add(dijit.byId("one"));
+	//		| 	ws.add(dijit.byId("two"));
+	//		|	// destroy both:
+	//		|	ws.forEach(function(w){ w.destroy(); });
+	//
+	// example:
+	//		Using dijit.registry:
+	//		|	dijit.registry.forEach(function(w){ /* do something */ });
+	
+	constructor: function(){
+		this._hash = {};
+	},
+
+	add: function(/*Widget*/ widget){
+		// summary:
+		//		Add a widget to this list. If a duplicate ID is detected, a error is thrown.
+		//
+		// widget: dijit._Widget
+		//		Any dijit._Widget subclass.
+		if(this._hash[widget.id]){
+			throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered");
+		}
+		this._hash[widget.id]=widget;
+	},
+
+	remove: function(/*String*/ id){
+		// summary:
+		//		Remove a widget from this WidgetSet. Does not destroy the widget; simply
+		//		removes the reference.
+		delete this._hash[id];
+	},
+
+	forEach: function(/*Function*/ func){
+		// summary:
+		//		Call specified function for each widget in this set.
+		//
+		// func:
+		//		A callback function to run for each item. Is passed a the widget.
+		//
+		// example:
+		//		Using the default `dijit.registry` instance:
+		//		|	dijit.registry.forEach(function(widget){
+		//		|			
+		//		|	});
+		for(var id in this._hash){
+			func(this._hash[id]);
+		}
+	},
+
+	filter: function(/*Function*/ filter){
+		// summary:
+		//		Filter down this WidgetSet to a smaller new WidgetSet
+		//		Works the same as `dojo.filter` and `dojo.NodeList.filter`
+		//		
+		// filter:
+		//		Callback function to test truthiness.
+		//
+		// example:
+		//		Arbitrary: select the odd widgets in this list
+		//		|	var i = 0;
+		//		|	dijit.registry.filter(function(w){
+		//		|		return ++i % 2 == 0;
+		//		|	}).forEach(function(w){ /* odd ones */ });
+
+		var res = new dijit.WidgetSet();
+		this.forEach(function(widget){
+			if(filter(widget)){ res.add(widget); }
+		});
+		return res; // dijit.WidgetSet
+	},
+
+	byId: function(/*String*/ id){
+		// summary:
+		//		Find a widget in this list by it's id. 
+		// example:
+		//		Test if an id is in a particular WidgetSet
+		//		| var ws = new dijit.WidgetSet();
+		//		| ws.add(dijit.byId("bar"));
+		//		| var t = ws.byId("bar") // returns a widget
+		//		| var x = ws.byId("foo"); // returns undefined
+		
+		return this._hash[id];	// dijit._Widget
+	},
+
+	byClass: function(/*String*/ cls){
+		// summary:
+		//		Reduce this widgetset to a new WidgetSet of a particular declaredClass
+		// 
+		// example:
+		//		Find all titlePane's in a page:
+		//		|	dijit.registry.byClass("dijit.TitlePane").forEach(function(tp){ tp.close(); });
+		
+		return this.filter(function(widget){ return widget.declaredClass==cls; });	// dijit.WidgetSet
+	}
+	
+});
+
+/*=====
+dijit.registry = {
+	// summary: A list of widgets on a page.
+	// description: Is an instance of `dijit.WidgetSet`
+};
+=====*/
+dijit.registry = new dijit.WidgetSet();
+
+dijit._widgetTypeCtr = {};
+
+dijit.getUniqueId = function(/*String*/widgetType){
+	// summary: Generates a unique id for a given widgetType
+
+	var id;
+	do{
+		id = widgetType + "_" +
+			(widgetType in dijit._widgetTypeCtr ?
+				++dijit._widgetTypeCtr[widgetType] : dijit._widgetTypeCtr[widgetType] = 0);
+	}while(dijit.byId(id));
+	return id; // String
+};
+
+dijit.findWidgets = function(/*DomNode*/ root){
+	// summary:
+	//		Search subtree under root, putting found widgets in outAry.
+	//		Doesn't search for nested widgets (ie, widgets inside other widgets)
+	
+	var outAry = [];
+
+	function getChildrenHelper(root){
+		var list = dojo.isIE ? root.children : root.childNodes, i = 0, node;
+		while(node = list[i++]){
+			if(node.nodeType != 1){ continue; }
+			var widgetId = node.getAttribute("widgetId");
+			if(widgetId){
+				var widget = dijit.byId(widgetId);
+				outAry.push(widget);
+			}else{
+				getChildrenHelper(node);
+			}
+		}
+	}
+
+	getChildrenHelper(root);
+	return outAry;
+};
+
+if(dojo.isIE){
+	// Only run this for IE because we think it's only necessary in that case,
+	// and because it causes problems on FF.  See bug #3531 for details.
+	dojo.addOnWindowUnload(function(){
+		dojo.forEach(dijit.findWidgets(dojo.body()), function(widget){
+			if(widget.destroyRecursive){
+				widget.destroyRecursive();
+			}else if(widget.destroy){
+				widget.destroy();
+			}
+		});
+	});
+}
+
+dijit.byId = function(/*String|Widget*/id){
+	// summary:
+	//		Returns a widget by it's id, or if passed a widget, no-op (like dojo.byId())
+	return (dojo.isString(id)) ? dijit.registry.byId(id) : id; // Widget
+};
+
+dijit.byNode = function(/* DOMNode */ node){
+	// summary:
+	//		Returns the widget corresponding to the given DOMNode
+	return dijit.registry.byId(node.getAttribute("widgetId")); // Widget
+};
+
+dijit.getEnclosingWidget = function(/* DOMNode */ node){
+	// summary:
+	//		Returns the widget whose DOM tree contains the specified DOMNode, or null if
+	//		the node is not contained within the DOM tree of any widget
+	while(node){
+		if(node.getAttribute && node.getAttribute("widgetId")){
+			return dijit.registry.byId(node.getAttribute("widgetId"));
+		}
+		node = node.parentNode;
+	}
+	return null;
+};
+
+// elements that are tab-navigable if they have no tabindex value set
+// (except for "a", which must have an href attribute)
+dijit._tabElements = {
+	area: true,
+	button: true,
+	input: true,
+	object: true,
+	select: true,
+	textarea: true
+};
+
+dijit._isElementShown = function(/*Element*/elem){
+	var style = dojo.style(elem);
+	return (style.visibility != "hidden")
+		&& (style.visibility != "collapsed")
+		&& (style.display != "none")
+		&& (dojo.attr(elem, "type") != "hidden");
+}
+
+dijit.isTabNavigable = function(/*Element*/elem){
+	// summary:
+	//		Tests if an element is tab-navigable
+	if(dojo.hasAttr(elem, "disabled")){ return false; }
+	var hasTabindex = dojo.hasAttr(elem, "tabindex");
+	var tabindex = dojo.attr(elem, "tabindex");
+	if(hasTabindex && tabindex >= 0) {
+		return true; // boolean
+	}
+	var name = elem.nodeName.toLowerCase();
+	if(((name == "a" && dojo.hasAttr(elem, "href"))
+			|| dijit._tabElements[name])
+		&& (!hasTabindex || tabindex >= 0)){
+		return true; // boolean
+	}
+	return false; // boolean
+};
+
+dijit._getTabNavigable = function(/*DOMNode*/root){
+	// summary:
+	//		Finds descendants of the specified root node.
+	//
+	// description:
+	//		Finds the following descendants of the specified root node:
+	//		* the first tab-navigable element in document order
+	//		  without a tabindex or with tabindex="0"
+	//		* the last tab-navigable element in document order
+	//		  without a tabindex or with tabindex="0"
+	//		* the first element in document order with the lowest
+	//		  positive tabindex value
+	//		* the last element in document order with the highest
+	//		  positive tabindex value
+	var first, last, lowest, lowestTabindex, highest, highestTabindex;
+	var walkTree = function(/*DOMNode*/parent){
+		dojo.query("> *", parent).forEach(function(child){
+			var isShown = dijit._isElementShown(child);
+			if(isShown && dijit.isTabNavigable(child)){
+				var tabindex = dojo.attr(child, "tabindex");
+				if(!dojo.hasAttr(child, "tabindex") || tabindex == 0){
+					if(!first){ first = child; }
+					last = child;
+				}else if(tabindex > 0){
+					if(!lowest || tabindex < lowestTabindex){
+						lowestTabindex = tabindex;
+						lowest = child;
+					}
+					if(!highest || tabindex >= highestTabindex){
+						highestTabindex = tabindex;
+						highest = child;
+					}
+				}
+			}
+			if(isShown && child.nodeName.toUpperCase() != 'SELECT'){ walkTree(child) }
+		});
+	};
+	if(dijit._isElementShown(root)){ walkTree(root) }
+	return { first: first, last: last, lowest: lowest, highest: highest };
+}
+dijit.getFirstInTabbingOrder = function(/*String|DOMNode*/root){
+	// summary:
+	//		Finds the descendant of the specified root node
+	//		that is first in the tabbing order
+	var elems = dijit._getTabNavigable(dojo.byId(root));
+	return elems.lowest ? elems.lowest : elems.first; // DomNode
+};
+
+dijit.getLastInTabbingOrder = function(/*String|DOMNode*/root){
+	// summary:
+	//		Finds the descendant of the specified root node
+	//		that is last in the tabbing order
+	var elems = dijit._getTabNavigable(dojo.byId(root));
+	return elems.last ? elems.last : elems.highest; // DomNode
+};
+
+/*=====
+dojo.mixin(dijit, {
+	// defaultDuration: Integer
+	//		The default animation speed (in ms) to use for all Dijit
+	//		transitional animations, unless otherwise specified 
+	//		on a per-instance basis. Defaults to 200, overrided by 
+	//		`djConfig.defaultDuration`
+	defaultDuration: 300
+});
+=====*/
+
+dijit.defaultDuration = dojo.config["defaultDuration"] || 200;
+
+}
+
+if(!dojo._hasResource["dojo.AdapterRegistry"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.AdapterRegistry"] = true;
+dojo.provide("dojo.AdapterRegistry");
+
+dojo.AdapterRegistry = function(/*Boolean?*/ returnWrappers){
+	//	summary:
+	//		A registry to make contextual calling/searching easier.
+	//	description:
+	//		Objects of this class keep list of arrays in the form [name, check,
+	//		wrap, directReturn] that are used to determine what the contextual
+	//		result of a set of checked arguments is. All check/wrap functions
+	//		in this registry should be of the same arity.
+	//	example:
+	//	|	// create a new registry
+	//	|	var reg = new dojo.AdapterRegistry();
+	//	|	reg.register("handleString",
+	//	|		dojo.isString,
+	//	|		function(str){
+	//	|			// do something with the string here
+	//	|		}
+	//	|	);
+	//	|	reg.register("handleArr",
+	//	|		dojo.isArray,
+	//	|		function(arr){
+	//	|			// do something with the array here
+	//	|		}
+	//	|	);
+	//	|
+	//	|	// now we can pass reg.match() *either* an array or a string and
+	//	|	// the value we pass will get handled by the right function
+	//	|	reg.match("someValue"); // will call the first function
+	//	|	reg.match(["someValue"]); // will call the second
+
+	this.pairs = [];
+	this.returnWrappers = returnWrappers || false; // Boolean
+}
+
+dojo.extend(dojo.AdapterRegistry, {
+	register: function(/*String*/ name, /*Function*/ check, /*Function*/ wrap, /*Boolean?*/ directReturn, /*Boolean?*/ override){
+		//	summary: 
+		//		register a check function to determine if the wrap function or
+		//		object gets selected
+		//	name:
+		//		a way to identify this matcher.
+		//	check:
+		//		a function that arguments are passed to from the adapter's
+		//		match() function.  The check function should return true if the
+		//		given arguments are appropriate for the wrap function.
+		//	directReturn:
+		//		If directReturn is true, the value passed in for wrap will be
+		//		returned instead of being called. Alternately, the
+		//		AdapterRegistry can be set globally to "return not call" using
+		//		the returnWrappers property. Either way, this behavior allows
+		//		the registry to act as a "search" function instead of a
+		//		function interception library.
+		//	override:
+		//		If override is given and true, the check function will be given
+		//		highest priority. Otherwise, it will be the lowest priority
+		//		adapter.
+		this.pairs[((override) ? "unshift" : "push")]([name, check, wrap, directReturn]);
+	},
+
+	match: function(/* ... */){
+		// summary:
+		//		Find an adapter for the given arguments. If no suitable adapter
+		//		is found, throws an exception. match() accepts any number of
+		//		arguments, all of which are passed to all matching functions
+		//		from the registered pairs.
+		for(var i = 0; i < this.pairs.length; i++){
+			var pair = this.pairs[i];
+			if(pair[1].apply(this, arguments)){
+				if((pair[3])||(this.returnWrappers)){
+					return pair[2];
+				}else{
+					return pair[2].apply(this, arguments);
+				}
+			}
+		}
+		throw new Error("No match found");
+	},
+
+	unregister: function(name){
+		// summary: Remove a named adapter from the registry
+
+		// FIXME: this is kind of a dumb way to handle this. On a large
+		// registry this will be slow-ish and we can use the name as a lookup
+		// should we choose to trade memory for speed.
+		for(var i = 0; i < this.pairs.length; i++){
+			var pair = this.pairs[i];
+			if(pair[0] == name){
+				this.pairs.splice(i, 1);
+				return true;
+			}
+		}
+		return false;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit._base.place"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.place"] = true;
+dojo.provide("dijit._base.place");
+
+
+
+// ported from dojo.html.util
+
+dijit.getViewport = function(){
+	// summary:
+	//		Returns the dimensions and scroll position of the viewable area of a browser window
+
+	var scrollRoot = (dojo.doc.compatMode == 'BackCompat')? dojo.body() : dojo.doc.documentElement;
+
+	// get scroll position
+	var scroll = dojo._docScroll(); // scrollRoot.scrollTop/Left should work
+	return { w: scrollRoot.clientWidth, h: scrollRoot.clientHeight, l: scroll.x, t: scroll.y };
+};
+
+/*=====
+dijit.__Position = function(){
+	// x: Integer
+	//		horizontal coordinate in pixels, relative to document body
+	// y: Integer
+	//		vertical coordinate in pixels, relative to document body
+
+	thix.x = x;
+	this.y = y;
+}
+=====*/
+
+
+dijit.placeOnScreen = function(
+	/* DomNode */			node,
+	/* dijit.__Position */	pos,
+	/* String[] */			corners,
+	/* dijit.__Position? */	padding){
+	//	summary:
+	//		Positions one of the node's corners at specified position
+	//		such that node is fully visible in viewport.
+	//	description:
+	//		NOTE: node is assumed to be absolutely or relatively positioned.
+	//	pos:
+	//		Object like {x: 10, y: 20}
+	//	corners:
+	//		Array of Strings representing order to try corners in, like ["TR", "BL"].
+	//		Possible values are:
+	//			* "BL" - bottom left
+	//			* "BR" - bottom right
+	//			* "TL" - top left
+	//			* "TR" - top right
+	//	padding:
+	//		set padding to put some buffer around the element you want to position.
+	//	example:	
+	//		Try to place node's top right corner at (10,20).
+	//		If that makes node go (partially) off screen, then try placing
+	//		bottom left corner at (10,20).
+	//	|	placeOnScreen(node, {x: 10, y: 20}, ["TR", "BL"])
+
+	var choices = dojo.map(corners, function(corner){
+		var c = { corner: corner, pos: {x:pos.x,y:pos.y} };
+		if(padding){
+			c.pos.x += corner.charAt(1) == 'L' ? padding.x : -padding.x;
+			c.pos.y += corner.charAt(0) == 'T' ? padding.y : -padding.y;
+		}
+		return c; 
+	});
+
+	return dijit._place(node, choices);
+}
+
+dijit._place = function(/*DomNode*/ node, /* Array */ choices, /* Function */ layoutNode){
+	// summary:
+	//		Given a list of spots to put node, put it at the first spot where it fits,
+	//		of if it doesn't fit anywhere then the place with the least overflow
+	// choices: Array
+	//		Array of elements like: {corner: 'TL', pos: {x: 10, y: 20} }
+	//		Above example says to put the top-left corner of the node at (10,20)
+	// layoutNode: Function(node, aroundNodeCorner, nodeCorner)
+	//		for things like tooltip, they are displayed differently (and have different dimensions)
+	//		based on their orientation relative to the parent.   This adjusts the popup based on orientation.
+
+	// get {x: 10, y: 10, w: 100, h:100} type obj representing position of
+	// viewport over document
+	var view = dijit.getViewport();
+
+	// This won't work if the node is inside a <div style="position: relative">,
+	// so reattach it to dojo.doc.body.   (Otherwise, the positioning will be wrong
+	// and also it might get cutoff)
+	if(!node.parentNode || String(node.parentNode.tagName).toLowerCase() != "body"){
+		dojo.body().appendChild(node);
+	}
+
+	var best = null;
+	dojo.some(choices, function(choice){
+		var corner = choice.corner;
+		var pos = choice.pos;
+
+		// configure node to be displayed in given position relative to button
+		// (need to do this in order to get an accurate size for the node, because
+		// a tooltips size changes based on position, due to triangle)
+		if(layoutNode){
+			layoutNode(node, choice.aroundCorner, corner);
+		}
+
+		// get node's size
+		var style = node.style;
+		var oldDisplay = style.display;
+		var oldVis = style.visibility;
+		style.visibility = "hidden";
+		style.display = "";
+		var mb = dojo.marginBox(node);
+		style.display = oldDisplay;
+		style.visibility = oldVis;
+
+		// coordinates and size of node with specified corner placed at pos,
+		// and clipped by viewport
+		var startX = (corner.charAt(1) == 'L' ? pos.x : Math.max(view.l, pos.x - mb.w)),
+			startY = (corner.charAt(0) == 'T' ? pos.y : Math.max(view.t, pos.y -  mb.h)),
+			endX = (corner.charAt(1) == 'L' ? Math.min(view.l + view.w, startX + mb.w) : pos.x),
+			endY = (corner.charAt(0) == 'T' ? Math.min(view.t + view.h, startY + mb.h) : pos.y),
+			width = endX - startX,
+			height = endY - startY,
+			overflow = (mb.w - width) + (mb.h - height);
+
+		if(best == null || overflow < best.overflow){
+			best = {
+				corner: corner,
+				aroundCorner: choice.aroundCorner,
+				x: startX,
+				y: startY,
+				w: width,
+				h: height,
+				overflow: overflow
+			};
+		}
+		return !overflow;
+	});
+
+	node.style.left = best.x + "px";
+	node.style.top = best.y + "px";
+	if(best.overflow && layoutNode){
+		layoutNode(node, best.aroundCorner, best.corner);
+	}
+	return best;
+}
+
+dijit.placeOnScreenAroundNode = function(
+	/* DomNode */		node,
+	/* DomNode */		aroundNode,
+	/* Object */		aroundCorners,
+	/* Function? */		layoutNode){
+
+	// summary:
+	//		Position node adjacent or kitty-corner to aroundNode
+	//		such that it's fully visible in viewport.
+	//
+	// description:
+	//		Place node such that corner of node touches a corner of
+	//		aroundNode, and that node is fully visible.
+	//
+	// aroundCorners:
+	//		Ordered list of pairs of corners to try matching up.
+	//		Each pair of corners is represented as a key/value in the hash,
+	//		where the key corresponds to the aroundNode's corner, and
+	//		the value corresponds to the node's corner:
+	//
+	//	|	{ aroundNodeCorner1: nodeCorner1, aroundNodeCorner2: nodeCorner2,  ...}
+	//
+	//		The following strings are used to represent the four corners:
+	//			* "BL" - bottom left
+	//			* "BR" - bottom right
+	//			* "TL" - top left
+	//			* "TR" - top right
+	//
+	// layoutNode: Function(node, aroundNodeCorner, nodeCorner)
+	//		For things like tooltip, they are displayed differently (and have different dimensions)
+	//		based on their orientation relative to the parent.   This adjusts the popup based on orientation.
+	//
+	// example:
+	//	|	dijit.placeOnScreenAroundNode(node, aroundNode, {'BL':'TL', 'TR':'BR'}); 
+	//		This will try to position node such that node's top-left corner is at the same position
+	//		as the bottom left corner of the aroundNode (ie, put node below
+	//		aroundNode, with left edges aligned).  If that fails it will try to put
+	// 		the bottom-right corner of node where the top right corner of aroundNode is
+	//		(ie, put node above aroundNode, with right edges aligned)
+	//
+
+	// get coordinates of aroundNode
+	aroundNode = dojo.byId(aroundNode);
+	var oldDisplay = aroundNode.style.display;
+	aroundNode.style.display="";
+	// #3172: use the slightly tighter border box instead of marginBox
+	var aroundNodeW = aroundNode.offsetWidth; //mb.w; 
+	var aroundNodeH = aroundNode.offsetHeight; //mb.h;
+	var aroundNodePos = dojo.coords(aroundNode, true);
+	aroundNode.style.display=oldDisplay;
+
+	// place the node around the calculated rectangle
+	return dijit._placeOnScreenAroundRect(node, 
+		aroundNodePos.x, aroundNodePos.y, aroundNodeW, aroundNodeH,	// rectangle
+		aroundCorners, layoutNode);
+};
+
+/*=====
+dijit.__Rectangle = function(){
+	// x: Integer
+	//		horizontal offset in pixels, relative to document body
+	// y: Integer
+	//		vertical offset in pixels, relative to document body
+	// width: Integer
+	//		width in pixels
+	// height: Integer
+	//		height in pixels
+
+	thix.x = x;
+	this.y = y;
+	thix.width = width;
+	this.height = height;
+}
+=====*/
+
+
+dijit.placeOnScreenAroundRectangle = function(
+	/* DomNode */			node,
+	/* dijit.__Rectangle */	aroundRect,
+	/* Object */			aroundCorners,
+	/* Function */			layoutNode){
+
+	// summary:
+	//		Like dijit.placeOnScreenAroundNode(), except that the "around"
+	//		parameter is an arbitrary rectangle on the screen (x, y, width, height)
+	//		instead of a dom node.
+
+	return dijit._placeOnScreenAroundRect(node, 
+		aroundRect.x, aroundRect.y, aroundRect.width, aroundRect.height,	// rectangle
+		aroundCorners, layoutNode);
+};
+
+dijit._placeOnScreenAroundRect = function(
+	/* DomNode */		node,
+	/* Number */		x,
+	/* Number */		y,
+	/* Number */		width,
+	/* Number */		height,
+	/* Object */		aroundCorners,
+	/* Function */		layoutNode){
+
+	// summary:
+	//		Like dijit.placeOnScreenAroundNode(), except it accepts coordinates
+	//		of a rectangle to place node adjacent to.
+
+	// TODO: combine with placeOnScreenAroundRectangle()
+
+	// Generate list of possible positions for node
+	var choices = [];
+	for(var nodeCorner in aroundCorners){
+		choices.push( {
+			aroundCorner: nodeCorner,
+			corner: aroundCorners[nodeCorner],
+			pos: {
+				x: x + (nodeCorner.charAt(1) == 'L' ? 0 : width),
+				y: y + (nodeCorner.charAt(0) == 'T' ? 0 : height)
+			}
+		});
+	}
+
+	return dijit._place(node, choices, layoutNode);
+};
+
+dijit.placementRegistry = new dojo.AdapterRegistry();
+dijit.placementRegistry.register("node",
+	function(n, x){
+		return typeof x == "object" &&
+			typeof x.offsetWidth != "undefined" && typeof x.offsetHeight != "undefined";
+	},
+	dijit.placeOnScreenAroundNode);
+dijit.placementRegistry.register("rect",
+	function(n, x){
+		return typeof x == "object" &&
+			"x" in x && "y" in x && "width" in x && "height" in x;
+	},
+	dijit.placeOnScreenAroundRectangle);
+
+dijit.placeOnScreenAroundElement = function(
+	/* DomNode */		node,
+	/* Object */		aroundElement,
+	/* Object */		aroundCorners,
+	/* Function */		layoutNode){
+
+	// summary:
+	//		Like dijit.placeOnScreenAroundNode(), except it accepts an arbitrary object
+	//		for the "around" argument and finds a proper processor to place a node.
+
+	return dijit.placementRegistry.match.apply(dijit.placementRegistry, arguments);
+};
+
+}
+
+if(!dojo._hasResource["dijit._base.window"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.window"] = true;
+dojo.provide("dijit._base.window");
+
+// TODO: remove this in 2.0, it's not used anymore, or at least not internally
+
+dijit.getDocumentWindow = function(doc){
+	// summary:
+	// 		Get window object associated with document doc
+
+	// In some IE versions (at least 6.0), document.parentWindow does not return a
+	// reference to the real window object (maybe a copy), so we must fix it as well
+	// We use IE specific execScript to attach the real window reference to
+	// document._parentWindow for later use
+	if(dojo.isIE && window !== document.parentWindow && !doc._parentWindow){
+		/*
+		In IE 6, only the variable "window" can be used to connect events (others
+		may be only copies).
+		*/
+		doc.parentWindow.execScript("document._parentWindow = window;", "Javascript");
+		//to prevent memory leak, unset it after use
+		//another possibility is to add an onUnload handler which seems overkill to me (liucougar)
+		var win = doc._parentWindow;
+		doc._parentWindow = null;
+		return win;	//	Window
+	}
+
+	return doc._parentWindow || doc.parentWindow || doc.defaultView;	//	Window
+}
+
+}
+
+if(!dojo._hasResource["dijit._base.popup"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.popup"] = true;
+dojo.provide("dijit._base.popup");
+
+
+
+
+
+dijit.popup = new function(){
+	// summary:
+	//		This class is used to show/hide widgets as popups.
+
+	var stack = [],
+		beginZIndex=1000,
+		idGen = 1;
+
+	this.prepare = function(/*DomNode*/ node){
+		// summary:
+		//		Prepares a node to be used as a popup
+		//
+		// description:
+		//		Attaches node to dojo.doc.body, and
+		//		positions it off screen, but not display:none, so that
+		//		the widget doesn't appear in the page flow and/or cause a blank
+		//		area at the bottom of the viewport (making scrollbar longer), but
+		//		initialization of contained widgets works correctly
+
+		var s = node.style;
+		s.visibility = "hidden";	// so TAB key doesn't navigate to hidden popup
+		s.position = "absolute";
+		s.top = "-9999px";
+		if(s.display == "none"){
+			s.display="";
+		}
+		dojo.body().appendChild(node);
+	};
+
+/*=====
+dijit.popup.__OpenArgs = function(){
+	// popup: Widget
+	//		widget to display
+	// parent: Widget
+	//		the button etc. that is displaying this popup
+	// around: DomNode
+	//		DOM node (typically a button); place popup relative to this node.  (Specify this *or* "x" and "y" parameters.)
+	// x: Integer
+	//		Absolute horizontal position (in pixels) to place node at.  (Specify this *or* "around" parameter.)
+	// y: Integer
+	//		Absolute vertical position (in pixels) to place node at.  (Specity this *or* "around" parameter.)
+	// orient: Object || String
+	//		When the around parameter is specified, orient should be an 
+	//		ordered list of tuples of the form (around-node-corner, popup-node-corner).
+	//		dijit.popup.open() tries to position the popup according to each tuple in the list, in order,
+	//		until the popup appears fully within the viewport.
+	//
+	//		The default value is {BL:'TL', TL:'BL'}, which represents a list of two tuples:
+	//			1. (BL, TL)
+	//			2. (TL, BL)
+	//		where BL means "bottom left" and "TL" means "top left".
+	//		So by default, it first tries putting the popup below the around node, left-aligning them,
+	//		and then tries to put it above the around node, still left-aligning them.   Note that the
+	//		default is horizontally reversed when in RTL mode.
+	//
+	//		When an (x,y) position is specified rather than an around node, orient is either
+	//		"R" or "L".  R (for right) means that it tries to put the popup to the right of the mouse,
+	//		specifically positioning the popup's top-right corner at the mouse position, and if that doesn't
+	//		fit in the viewport, then it tries, in order, the bottom-right corner, the top left corner,
+	//		and the top-right corner.
+	// onCancel: Function
+	//		callback when user has canceled the popup by
+	//			1. hitting ESC or
+	//			2. by using the popup widget's proprietary cancel mechanism (like a cancel button in a dialog);
+	//			   i.e. whenever popupWidget.onCancel() is called, args.onCancel is called
+	// onClose: Function
+	//		callback whenever this popup is closed
+	// onExecute: Function
+	//		callback when user "executed" on the popup/sub-popup by selecting a menu choice, etc. (top menu only)
+	// padding: dijit.__Position
+	//		adding a buffer around the opening position. This is only useful when around is not set.
+	this.popup = popup;
+	this.parent = parent;
+	this.around = around;
+	this.x = x;
+	this.y = y;
+	this.orient = orient;
+	this.onCancel = onCancel;
+	this.onClose = onClose;
+	this.onExecute = onExecute;
+	this.padding = padding;
+}
+=====*/
+	this.open = function(/*dijit.popup.__OpenArgs*/ args){
+		// summary:
+		//		Popup the widget at the specified position
+		//
+		// example:
+		//		opening at the mouse position
+		//		|		dijit.popup.open({popup: menuWidget, x: evt.pageX, y: evt.pageY});
+		//
+		// example:
+		//		opening the widget as a dropdown
+		//		|		dijit.popup.open({parent: this, popup: menuWidget, around: this.domNode, onClose: function(){...}  });
+		//
+		//		Note that whatever widget called dijit.popup.open() should also listen to its own _onBlur callback
+		//		(fired from _base/focus.js) to know that focus has moved somewhere else and thus the popup should be closed.
+
+		var widget = args.popup,
+			orient = args.orient || {'BL':'TL', 'TL':'BL'},
+			around = args.around,
+			id = (args.around && args.around.id) ? (args.around.id+"_dropdown") : ("popup_"+idGen++);
+
+		// make wrapper div to hold widget and possibly hold iframe behind it.
+		// we can't attach the iframe as a child of the widget.domNode because
+		// widget.domNode might be a <table>, <ul>, etc.
+		var wrapper = dojo.create("div",{
+			id: id, 
+			"class":"dijitPopup",
+			style:{
+				zIndex: beginZIndex + stack.length,
+				visibility:"hidden"
+			}
+		}, dojo.body());
+		dijit.setWaiRole(wrapper, "presentation");
+		
+		// prevent transient scrollbar causing misalign (#5776)
+		wrapper.style.left = wrapper.style.top = "0px";		
+
+		if(args.parent){
+			wrapper.dijitPopupParent=args.parent.id;
+		}
+
+		var s = widget.domNode.style;
+		s.display = "";
+		s.visibility = "";
+		s.position = "";
+		s.top = "0px";
+		wrapper.appendChild(widget.domNode);
+
+		var iframe = new dijit.BackgroundIframe(wrapper);
+
+		// position the wrapper node
+		var best = around ?
+			dijit.placeOnScreenAroundElement(wrapper, around, orient, widget.orient ? dojo.hitch(widget, "orient") : null) :
+			dijit.placeOnScreen(wrapper, args, orient == 'R' ? ['TR','BR','TL','BL'] : ['TL','BL','TR','BR'], args.padding);
+
+		wrapper.style.visibility = "visible";
+		// TODO: use effects to fade in wrapper
+
+		var handlers = [];
+
+		// Compute the closest ancestor popup that's *not* a child of another popup.
+		// Ex: For a TooltipDialog with a button that spawns a tree of menus, find the popup of the button.
+		var getTopPopup = function(){
+			for(var pi=stack.length-1; pi > 0 && stack[pi].parent === stack[pi-1].widget; pi--){
+				/* do nothing, just trying to get right value for pi */
+			}
+			return stack[pi];
+		}
+
+		// provide default escape and tab key handling
+		// (this will work for any widget, not just menu)
+		handlers.push(dojo.connect(wrapper, "onkeypress", this, function(evt){
+			if(evt.charOrCode == dojo.keys.ESCAPE && args.onCancel){
+				dojo.stopEvent(evt);
+				args.onCancel();
+			}else if(evt.charOrCode === dojo.keys.TAB){
+				dojo.stopEvent(evt);
+				var topPopup = getTopPopup();
+				if(topPopup && topPopup.onCancel){
+					topPopup.onCancel();
+				}
+			}
+		}));
+
+		// watch for cancel/execute events on the popup and notify the caller
+		// (for a menu, "execute" means clicking an item)
+		if(widget.onCancel){
+			handlers.push(dojo.connect(widget, "onCancel", null, args.onCancel));
+		}
+
+		handlers.push(dojo.connect(widget, widget.onExecute ? "onExecute" : "onChange", null, function(){
+			var topPopup = getTopPopup();
+			if(topPopup && topPopup.onExecute){
+				topPopup.onExecute();
+			}
+		}));
+
+		stack.push({
+			wrapper: wrapper,
+			iframe: iframe,
+			widget: widget,
+			parent: args.parent,
+			onExecute: args.onExecute,
+			onCancel: args.onCancel,
+ 			onClose: args.onClose,
+			handlers: handlers
+		});
+
+		if(widget.onOpen){
+			widget.onOpen(best);
+		}
+
+		return best;
+	};
+
+	this.close = function(/*Widget*/ popup){
+		// summary:
+		//		Close specified popup and any popups that it parented
+		while(dojo.some(stack, function(elem){return elem.widget == popup;})){
+			var top = stack.pop(),
+				wrapper = top.wrapper,
+				iframe = top.iframe,
+				widget = top.widget,
+				onClose = top.onClose;
+	
+			if(widget.onClose){
+				widget.onClose();
+			}
+			dojo.forEach(top.handlers, dojo.disconnect);
+	
+			// #2685: check if the widget still has a domNode so ContentPane can change its URL without getting an error
+			if(!widget||!widget.domNode){ return; }
+			
+			this.prepare(widget.domNode);
+
+			iframe.destroy();
+			dojo.destroy(wrapper);
+	
+			if(onClose){
+				onClose();
+			}
+		}
+	};
+}();
+
+dijit._frames = new function(){
+	// summary: cache of iframes
+	var queue = [];
+
+	this.pop = function(){
+		var iframe;
+		if(queue.length){
+			iframe = queue.pop();
+			iframe.style.display="";
+		}else{
+			if(dojo.isIE){
+				var burl = dojo.config["dojoBlankHtmlUrl"] || (dojo.moduleUrl("dojo", "resources/blank.html")+"") || "javascript:\"\"";
+				var html="<iframe src='" + burl + "'"
+					+ " style='position: absolute; left: 0px; top: 0px;"
+					+ "z-index: -1; filter:Alpha(Opacity=\"0\");'>";
+				iframe = dojo.doc.createElement(html);
+			}else{
+			 	iframe = dojo.create("iframe");
+				iframe.src = 'javascript:""';
+				iframe.className = "dijitBackgroundIframe";
+			}
+			iframe.tabIndex = -1; // Magic to prevent iframe from getting focus on tab keypress - as style didnt work.
+			dojo.body().appendChild(iframe);
+		}
+		return iframe;
+	};
+
+	this.push = function(iframe){
+		iframe.style.display="none";
+		if(dojo.isIE){
+			iframe.style.removeExpression("width");
+			iframe.style.removeExpression("height");
+		}
+		queue.push(iframe);
+	}
+}();
+
+
+dijit.BackgroundIframe = function(/* DomNode */node){
+	// summary:
+	//		For IE z-index schenanigans. id attribute is required.
+	//
+	// description:
+	//		new dijit.BackgroundIframe(node)
+	//			Makes a background iframe as a child of node, that fills
+	//			area (and position) of node
+
+	if(!node.id){ throw new Error("no id"); }
+	if(dojo.isIE < 7 || (dojo.isFF < 3 && dojo.hasClass(dojo.body(), "dijit_a11y"))){
+		var iframe = dijit._frames.pop();
+		node.appendChild(iframe);
+		if(dojo.isIE){
+			iframe.style.setExpression("width", dojo._scopeName + ".doc.getElementById('" + node.id + "').offsetWidth");
+			iframe.style.setExpression("height", dojo._scopeName + ".doc.getElementById('" + node.id + "').offsetHeight");
+		}
+		this.iframe = iframe;
+	}
+};
+
+dojo.extend(dijit.BackgroundIframe, {
+	destroy: function(){
+		//	summary: destroy the iframe
+		if(this.iframe){
+			dijit._frames.push(this.iframe);
+			delete this.iframe;
+		}
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit._base.scroll"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.scroll"] = true;
+dojo.provide("dijit._base.scroll");
+
+dijit.scrollIntoView = function(/* DomNode */node){
+	// summary:
+	//		Scroll the passed node into view, if it is not.
+
+	// don't rely on that node.scrollIntoView works just because the function is there
+	// it doesnt work in Konqueror or Opera even though the function is there and probably
+	//	not safari either
+	// native scrollIntoView() causes FF3's whole window to scroll if there is no scroll bar 
+	//	on the immediate parent
+	// dont like browser sniffs implementations but sometimes you have to use it
+	// It's not enough just to scroll the menu node into view if
+	// node.scrollIntoView hides part of the parent's scrollbar,
+	// so just manage the parent scrollbar ourselves
+
+	//var testdir="H"; //debug
+	try{ // catch unexpected/unrecreatable errors (#7808) since we can recover using a semi-acceptable native method
+	node = dojo.byId(node);
+	var doc = dojo.doc;
+	var body = dojo.body();
+	var html = body.parentNode;
+	// if FF2 (which is perfect) or an untested browser, then use the native method
+
+	if((!(dojo.isFF >= 3 || dojo.isIE || dojo.isWebKit) || node == body || node == html) && (typeof node.scrollIntoView == "function")){ // FF2 is perfect, too bad FF3 is not
+		node.scrollIntoView(false); // short-circuit to native if possible
+		return;
+	}
+	var ltr = dojo._isBodyLtr();
+	var isIE8strict = dojo.isIE >= 8 && !compatMode;
+	var rtl = !ltr && !isIE8strict; // IE8 flips scrolling so pretend it's ltr
+	// body and html elements are all messed up due to browser bugs and inconsistencies related to doctype
+	// normalize the values before proceeding (FF2 is not listed since its native behavior is perfect)
+	// for computation simplification, client and offset width and height are the same for body and html
+	// strict:       html:       |      body:       | compatMode:
+	//           width   height  |  width   height  |------------
+	//    ie*:  clientW  clientH | scrollW  clientH | CSS1Compat
+	//    ff3:  clientW  clientH |HscrollW  clientH | CSS1Compat
+	//    sf3:  clientW  clientH | clientW HclientH | CSS1Compat
+	//    op9:  clientW  clientH |HscrollW  clientH | CSS1Compat
+	// ---------------------------------------------|-----------
+	//   none:        html:      |      body:       |
+	//           width    height |  width   height  |
+	//    ie*: BclientW BclientH | clientW  clientH | BackCompat
+	//    ff3: BclientW BclientH | clientW  clientH | BackCompat
+	//    sf3:  clientW  clientH | clientW HclientH | CSS1Compat
+	//    op9: BclientW BclientH | clientW  clientH | BackCompat
+	// ---------------------------------------------|-----------
+	//  loose:        html:      |      body:       |
+	//           width    height |  width   height  |
+	//    ie*:  clientW  clientH | scrollW  clientH | CSS1Compat
+	//    ff3: BclientW BclientH | clientW  clientH | BackCompat
+	//    sf3:  clientW  clientH | clientW HclientH | CSS1Compat
+	//    op9:  clientW  clientH |HscrollW  clientH | CSS1Compat
+	var scrollRoot = body;
+	var compatMode = doc.compatMode == 'BackCompat';
+	if(compatMode){ // BODY is scrollable, HTML has same client size
+		// body client values already OK
+		html._offsetWidth = html._clientWidth = body._offsetWidth = body.clientWidth;
+		html._offsetHeight = html._clientHeight = body._offsetHeight = body.clientHeight;
+	}else{
+		if(dojo.isWebKit){
+			body._offsetWidth = body._clientWidth  = html.clientWidth;
+			body._offsetHeight = body._clientHeight = html.clientHeight;
+		}else{
+			scrollRoot = html;
+		}
+		html._offsetHeight = html.clientHeight;
+		html._offsetWidth  = html.clientWidth;
+	}
+
+	function isFixedPosition(element){
+		var ie = dojo.isIE;
+		return ((ie <= 6 || (ie >= 7 && compatMode))? false : (dojo.style(element, 'position').toLowerCase() == "fixed"));
+	}
+
+	function addPseudoAttrs(element){
+		var parent = element.parentNode;
+		var offsetParent = element.offsetParent;
+		if(offsetParent == null || isFixedPosition(element)){ // position:fixed has no real offsetParent
+			offsetParent = html; // prevents exeptions
+			parent = (element == body)? html : null;
+		}
+		// all the V/H object members below are to reuse code for both directions
+		element._offsetParent = offsetParent;
+		element._parent = parent;
+		//
+		//
+		var bp = dojo._getBorderExtents(element);
+		element._borderStart = { H:(isIE8strict && !ltr)? (bp.w-bp.l):bp.l, V:bp.t };
+		element._borderSize = { H:bp.w, V:bp.h };
+		element._scrolledAmount = { H:element.scrollLeft, V:element.scrollTop };
+		element._offsetSize = { H: element._offsetWidth||element.offsetWidth, V: element._offsetHeight||element.offsetHeight };
+		//
+		// IE8 flips everything in rtl mode except offsetLeft and borderLeft - so manually change offsetLeft to offsetRight here 
+		element._offsetStart = { H:(isIE8strict && !ltr)? offsetParent.clientWidth-element.offsetLeft-element._offsetSize.H:element.offsetLeft, V:element.offsetTop };
+		//
+		element._clientSize = { H:element._clientWidth||element.clientWidth, V:element._clientHeight||element.clientHeight };
+		if(element != body && element != html && element != node){
+			for(var dir in element._offsetSize){ // for both x and y directions
+				var scrollBarSize = element._offsetSize[dir] - element._clientSize[dir] - element._borderSize[dir];
+				//if(dir==testdir)
+				var hasScrollBar = element._clientSize[dir] > 0 && scrollBarSize > 0; // can't check for a specific scrollbar size since it changes dramatically as you zoom
+				//if(dir==testdir)
+				if(hasScrollBar){
+					element._offsetSize[dir] -= scrollBarSize;
+					if(dojo.isIE && rtl && dir=="H"){ element._offsetStart[dir] += scrollBarSize; }
+				}
+			}
+		}
+	}
+
+	var element = node;
+	while(element != null){
+		if(isFixedPosition(element)){ node.scrollIntoView(false); return; } //TODO: handle without native call
+		addPseudoAttrs(element);
+		element = element._parent;
+	}
+	if(dojo.isIE && node._parent){ // if no parent, then offsetParent._borderStart may not tbe set
+		var offsetParent = node._offsetParent;
+		//
+		node._offsetStart.H += offsetParent._borderStart.H;
+		node._offsetStart.V += offsetParent._borderStart.V;
+	}
+	if(dojo.isIE >= 7 && scrollRoot == html && rtl && body._offsetStart && body._offsetStart.H == 0){ // IE7 bug
+		var scroll = html.scrollWidth - html._offsetSize.H;
+		if(scroll > 0){
+			//
+			body._offsetStart.H = -scroll;
+		}
+	}
+	if(dojo.isIE <= 6 && !compatMode){
+		html._offsetSize.H += html._borderSize.H;
+		html._offsetSize.V += html._borderSize.V;
+	}
+	// eliminate offsetLeft/Top oddities by tweaking scroll for ease of computation
+	if(rtl && body._offsetStart && scrollRoot == html && html._scrolledAmount){
+		var ofs = body._offsetStart.H;
+		if(ofs < 0){
+			html._scrolledAmount.H += ofs;
+			body._offsetStart.H = 0;
+		}
+	}
+	element = node;
+	while(element){
+		var parent = element._parent;
+		if(!parent){ break; }
+			//
+			if(parent.tagName == "TD"){
+				var table = parent._parent._parent._parent; // point to TABLE
+				if(parent != element._offsetParent && parent._offsetParent != element._offsetParent){
+					parent = table; // child of TD has the same offsetParent as TABLE, so skip TD, TR, and TBODY (ie. verticalslider)
+				}
+			}
+			// check if this node and its parent share the same offsetParent
+			var relative = element._offsetParent == parent;
+			//
+			for(var dir in element._offsetStart){ // for both x and y directions
+				var otherDir = dir=="H"? "V" : "H";
+				if(rtl && dir=="H" && (parent != html) && (parent != body) && (dojo.isIE || dojo.isWebKit) && parent._clientSize.H > 0 && parent.scrollWidth > parent._clientSize.H){ // scroll starts on the right
+					var delta = parent.scrollWidth - parent._clientSize.H;
+					//
+					if(delta > 0){
+						parent._scrolledAmount.H -= delta;
+					} // match FF3 which has cool negative scrollLeft values
+				}
+				if(parent._offsetParent.tagName == "TABLE"){ // make it consistent
+					if(dojo.isIE){ // make it consistent with Safari and FF3 and exclude the starting TABLE border of TABLE children
+						parent._offsetStart[dir] -= parent._offsetParent._borderStart[dir];
+						parent._borderStart[dir] = parent._borderSize[dir] = 0;
+					}
+					else{
+						parent._offsetStart[dir] += parent._offsetParent._borderStart[dir];
+					}
+				}
+				//if(dir==testdir)
+				if(dojo.isIE){
+					//if(dir==testdir)
+					parent._offsetStart[dir] += parent._offsetParent._borderStart[dir];
+				}
+				//if(dir==testdir)
+				// underflow = visible gap between parent and this node taking scrolling into account
+				// if negative, part of the node is obscured by the parent's beginning and should be scrolled to become visible
+				var underflow = element._offsetStart[dir] - parent._scrolledAmount[dir] - (relative? 0 : parent._offsetStart[dir]) - parent._borderStart[dir];
+				// if overflow is positive, number of pixels obscured by the parent's end
+				var overflow = underflow + element._offsetSize[dir] - parent._offsetSize[dir] + parent._borderSize[dir];
+				//if(dir==testdir)
+				var scrollAttr = (dir=="H")? "scrollLeft" : "scrollTop";
+				// see if we should scroll forward or backward
+				var reverse = dir=="H" && rtl; // flip everything
+				var underflowScroll = reverse? -overflow : underflow;
+				var overflowScroll = reverse? -underflow : overflow;
+				// don't scroll if the over/underflow signs are opposite since that means that
+				// the node extends beyond parent's boundary in both/neither directions
+				var scrollAmount = (underflowScroll*overflowScroll <= 0)? 0 : Math[(underflowScroll < 0)? "max" : "min"](underflowScroll, overflowScroll);
+				//if(dir==testdir)
+				if(scrollAmount != 0){
+					var oldScroll = parent[scrollAttr];
+					parent[scrollAttr] += (reverse)? -scrollAmount : scrollAmount; // actually perform the scroll
+					var scrolledAmount = parent[scrollAttr] - oldScroll; // in case the scroll failed
+					//if(dir==testdir)
+				}
+				if(relative){
+					element._offsetStart[dir] += parent._offsetStart[dir];
+				}
+				element._offsetStart[dir] -= parent[scrollAttr];
+			}
+			element._parent = parent._parent;
+			element._offsetParent = parent._offsetParent;
+	}
+	parent = node;
+	var next;
+	while(parent && parent.removeAttribute){
+		next = parent.parentNode;
+		parent.removeAttribute('_offsetParent');
+		parent.removeAttribute('_parent');
+		parent = next;
+	}
+	}catch(error){
+		console.error('scrollIntoView: ' + error);
+		node.scrollIntoView(false);
+	}
+};
+
+}
+
+if(!dojo._hasResource["dijit._base.sniff"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.sniff"] = true;
+// summary:
+//		Applies pre-set CSS classes to the top-level HTML node, based on:
+// 			- browser (ex: dj_ie)
+//			- browser version (ex: dj_ie6)
+//			- box model (ex: dj_contentBox)
+//			- text direction (ex: dijitRtl)
+//
+//		In addition, browser, browser version, and box model are
+//		combined with an RTL flag when browser text is RTL.  ex: dj_ie-rtl.
+//
+//		Simply doing a require on this module will
+//		establish this CSS.  Modified version of Morris' CSS hack.
+
+dojo.provide("dijit._base.sniff");
+
+(function(){
+	
+	var d = dojo,
+		html = d.doc.documentElement,
+		ie = d.isIE,
+		opera = d.isOpera,
+		maj = Math.floor,
+		ff = d.isFF,
+		boxModel = d.boxModel.replace(/-/,''),
+		classes = {
+			dj_ie: ie,
+//			dj_ie55: ie == 5.5,
+			dj_ie6: maj(ie) == 6,
+			dj_ie7: maj(ie) == 7,
+			dj_iequirks: ie && d.isQuirks,
+			// NOTE: Opera not supported by dijit
+			dj_opera: opera,
+			dj_opera8: maj(opera) == 8,
+			dj_opera9: maj(opera) == 9,
+			dj_khtml: d.isKhtml,
+			dj_webkit: d.isWebKit,
+			dj_safari: d.isSafari,
+			dj_gecko: d.isMozilla,
+			dj_ff2: maj(ff) == 2,
+			dj_ff3: maj(ff) == 3
+		}; // no dojo unsupported browsers
+		
+	classes["dj_" + boxModel] = true;
+	
+	// apply browser, browser version, and box model class names
+	for(var p in classes){
+		if(classes[p]){
+			if(html.className){
+				html.className += " " + p;
+			}else{
+				html.className = p;
+			}
+		}
+	}
+
+	// If RTL mode then add dijitRtl flag plus repeat existing classes
+	// with -rtl extension
+	// (unshift is to make this code run after <body> node is loaded but before parser runs)
+	dojo._loaders.unshift(function(){
+		if(!dojo._isBodyLtr()){
+			html.className += " dijitRtl";
+			for(var p in classes){
+				if(classes[p]){
+					html.className += " " + p + "-rtl";
+				}
+			}
+		}
+	});
+	
+})();
+
+}
+
+if(!dojo._hasResource["dijit._base.typematic"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.typematic"] = true;
+dojo.provide("dijit._base.typematic");
+
+dijit.typematic = {
+	// summary:
+	//		These functions are used to repetitively call a user specified callback
+	//		method when a specific key or mouse click over a specific DOM node is
+	//		held down for a specific amount of time.
+	//		Only 1 such event is allowed to occur on the browser page at 1 time.
+
+	_fireEventAndReload: function(){
+		this._timer = null;
+		this._callback(++this._count, this._node, this._evt);
+		this._currentTimeout = (this._currentTimeout < 0) ? this._initialDelay : ((this._subsequentDelay > 1) ? this._subsequentDelay : Math.round(this._currentTimeout * this._subsequentDelay));
+		this._timer = setTimeout(dojo.hitch(this, "_fireEventAndReload"), this._currentTimeout);
+	},
+
+	trigger: function(/*Event*/ evt, /* Object */ _this, /*DOMNode*/ node, /* Function */ callback, /* Object */ obj, /* Number */ subsequentDelay, /* Number */ initialDelay){
+		// summary:
+		//	    Start a timed, repeating callback sequence.
+		//	    If already started, the function call is ignored.
+		//	    This method is not normally called by the user but can be
+		//	    when the normal listener code is insufficient.
+		// evt:
+		//		key or mouse event object to pass to the user callback
+		// _this:
+		//		pointer to the user's widget space.
+		// node:
+		//		the DOM node object to pass the the callback function
+		// callback:
+		//		function to call until the sequence is stopped called with 3 parameters:
+		// count:
+		//		integer representing number of repeated calls (0..n) with -1 indicating the iteration has stopped
+		// node:
+		//		the DOM node object passed in
+		// evt:
+		//		key or mouse event object
+		// obj:
+		//		user space object used to uniquely identify each typematic sequence
+		// subsequentDelay:
+		//		if > 1, the number of milliseconds until the 3->n events occur
+		//		or else the fractional time multiplier for the next event's delay, default=0.9
+		// initialDelay:
+		//		the number of milliseconds until the 2nd event occurs, default=500ms
+		if(obj != this._obj){
+			this.stop();
+			this._initialDelay = initialDelay || 500;
+			this._subsequentDelay = subsequentDelay || 0.90;
+			this._obj = obj;
+			this._evt = evt;
+			this._node = node;
+			this._currentTimeout = -1;
+			this._count = -1;
+			this._callback = dojo.hitch(_this, callback);
+			this._fireEventAndReload();
+		}
+	},
+
+	stop: function(){
+		// summary:
+		//	  Stop an ongoing timed, repeating callback sequence.
+		if(this._timer){
+			clearTimeout(this._timer);
+			this._timer = null;
+		}
+		if(this._obj){
+			this._callback(-1, this._node, this._evt);
+			this._obj = null;
+		}
+	},
+
+	addKeyListener: function(/*DOMNode*/ node, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay){
+		// summary:
+		//		Start listening for a specific typematic key.
+		//		See also the trigger method for other parameters.
+		// keyObject:
+		//		an object defining the key to listen for.
+		// charOrCode:
+		//		the printable character (string) or keyCode (number) to listen for.
+		// keyCode:
+		//		(deprecated - use charOrCode) the keyCode (number) to listen for (implies charCode = 0).
+		// charCode:
+		//		(deprecated - use charOrCode) the charCode (number) to listen for.
+		// ctrlKey:
+		//		desired ctrl key state to initiate the calback sequence:
+		//			- pressed (true)
+		//			- released (false)
+		//			- either (unspecified)
+		// altKey:
+		//		same as ctrlKey but for the alt key
+		// shiftKey:
+		//		same as ctrlKey but for the shift key
+		// returns:
+		//		an array of dojo.connect handles
+		if(keyObject.keyCode){
+			keyObject.charOrCode = keyObject.keyCode;
+			dojo.deprecated("keyCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.", "", "2.0");
+		}else if(keyObject.charCode){
+			keyObject.charOrCode = String.fromCharCode(keyObject.charCode);
+			dojo.deprecated("charCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.", "", "2.0");
+		}
+		return [
+			dojo.connect(node, "onkeypress", this, function(evt){
+				if(evt.charOrCode == keyObject.charOrCode &&
+				(keyObject.ctrlKey === undefined || keyObject.ctrlKey == evt.ctrlKey) &&
+				(keyObject.altKey === undefined || keyObject.altKey == evt.ctrlKey) &&
+				(keyObject.shiftKey === undefined || keyObject.shiftKey == evt.ctrlKey)){
+					dojo.stopEvent(evt);
+					dijit.typematic.trigger(keyObject, _this, node, callback, keyObject, subsequentDelay, initialDelay);
+				}else if(dijit.typematic._obj == keyObject){
+					dijit.typematic.stop();
+				}
+			}),
+			dojo.connect(node, "onkeyup", this, function(evt){
+				if(dijit.typematic._obj == keyObject){
+					dijit.typematic.stop();
+				}
+			})
+		];
+	},
+
+	addMouseListener: function(/*DOMNode*/ node, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay){
+		// summary:
+		//		Start listening for a typematic mouse click.
+		//		See the trigger method for other parameters.
+		// returns:
+		//		an array of dojo.connect handles
+		var dc = dojo.connect;
+		return [
+			dc(node, "mousedown", this, function(evt){
+				dojo.stopEvent(evt);
+				dijit.typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay);
+			}),
+			dc(node, "mouseup", this, function(evt){
+				dojo.stopEvent(evt);
+				dijit.typematic.stop();
+			}),
+			dc(node, "mouseout", this, function(evt){
+				dojo.stopEvent(evt);
+				dijit.typematic.stop();
+			}),
+			dc(node, "mousemove", this, function(evt){
+				dojo.stopEvent(evt);
+			}),
+			dc(node, "dblclick", this, function(evt){
+				dojo.stopEvent(evt);
+				if(dojo.isIE){
+					dijit.typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay);
+					setTimeout(dojo.hitch(this, dijit.typematic.stop), 50);
+				}
+			})
+		];
+	},
+
+	addListener: function(/*Node*/ mouseNode, /*Node*/ keyNode, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay){
+		// summary:
+		//		Start listening for a specific typematic key and mouseclick.
+		//		This is a thin wrapper to addKeyListener and addMouseListener.
+		//		See the addMouseListener and addKeyListener methods for other parameters.
+		// mouseNode:
+		//		the DOM node object to listen on for mouse events.
+		// keyNode:
+		//		the DOM node object to listen on for key events.
+		// returns:
+		//		an array of dojo.connect handles
+		return this.addKeyListener(keyNode, keyObject, _this, callback, subsequentDelay, initialDelay).concat(
+			this.addMouseListener(mouseNode, _this, callback, subsequentDelay, initialDelay));
+	}
+};
+
+}
+
+if(!dojo._hasResource["dijit._base.wai"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.wai"] = true;
+dojo.provide("dijit._base.wai");
+
+dijit.wai = {
+	onload: function(){
+		// summary:
+		//		Detects if we are in high-contrast mode or not
+
+		// This must be a named function and not an anonymous
+		// function, so that the widget parsing code can make sure it
+		// registers its onload function after this function.
+		// DO NOT USE "this" within this function.
+
+		// create div for testing if high contrast mode is on or images are turned off
+		var div = dojo.create("div",{
+			id: "a11yTestNode",
+			style:{
+				cssText:'border: 1px solid;'
+					+ 'border-color:red green;'
+					+ 'position: absolute;'
+					+ 'height: 5px;'
+					+ 'top: -999px;'
+					+ 'background-image: url("' + (dojo.config.blankGif || dojo.moduleUrl("dojo", "resources/blank.gif")) + '");'
+			}
+		}, dojo.body());
+
+		// test it
+		var cs = dojo.getComputedStyle(div);
+		if(cs){
+			var bkImg = cs.backgroundImage;
+			var needsA11y = (cs.borderTopColor==cs.borderRightColor) || (bkImg != null && (bkImg == "none" || bkImg == "url(invalid-url:)" ));
+			dojo[needsA11y ? "addClass" : "removeClass"](dojo.body(), "dijit_a11y");
+			if(dojo.isIE){
+				div.outerHTML = "";		// prevent mixed-content warning, see http://support.microsoft.com/kb/925014
+			}else{
+				dojo.body().removeChild(div);
+			}
+		}
+	}
+};
+
+// Test if computer is in high contrast mode.
+// Make sure the a11y test runs first, before widgets are instantiated.
+if(dojo.isIE || dojo.isMoz){	// NOTE: checking in Safari messes things up
+	dojo._loaders.unshift(dijit.wai.onload);
+}
+
+dojo.mixin(dijit,
+{
+	_XhtmlRoles: /banner|contentinfo|definition|main|navigation|search|note|secondary|seealso/,
+
+	hasWaiRole: function(/*Element*/ elem, /*String*/ role){
+		// summary:
+		//		Determines if an element has a particular non-XHTML role.
+		// returns:
+		//		True if elem has the specific non-XHTML role attribute and false if not.
+		// 		For backwards compatibility if role parameter not provided, 
+		// 		returns true if has non XHTML role 
+		var waiRole = this.getWaiRole(elem);		
+		return role ? (waiRole.indexOf(role) > -1) : (waiRole.length > 0);
+	},
+
+	getWaiRole: function(/*Element*/ elem){
+		// summary:
+		//		Gets the non-XHTML role for an element (which should be a wai role).
+		// returns:
+		//		The non-XHTML role of elem or an empty string if elem
+		//		does not have a role.
+		 return dojo.trim((dojo.attr(elem, "role") || "").replace(this._XhtmlRoles,"").replace("wairole:",""));
+	},
+
+	setWaiRole: function(/*Element*/ elem, /*String*/ role){
+		// summary:
+		//		Sets the role on an element.
+		// description:
+		//		In other than FF2 replace existing role attribute with new role.
+		//		FF3 supports XHTML and ARIA roles so    
+		//		if elem already has an XHTML role, append this role to XHTML role 
+		//		and remove other ARIA roles.
+		//		On Firefox 2 and below, "wairole:" is
+		//		prepended to the provided role value.
+
+		var curRole = dojo.attr(elem, "role") || "";
+		if(dojo.isFF < 3 || !this._XhtmlRoles.test(curRole)){
+			dojo.attr(elem, "role", dojo.isFF < 3 ? "wairole:" + role : role);
+		}else{
+			if((" "+ curRole +" ").indexOf(" " + role + " ") < 0){
+				var clearXhtml = dojo.trim(curRole.replace(this._XhtmlRoles, ""));
+				var cleanRole = dojo.trim(curRole.replace(clearXhtml, ""));	 
+         		dojo.attr(elem, "role", cleanRole + (cleanRole ? ' ' : '') + role);
+			}
+		}
+	},
+
+	removeWaiRole: function(/*Element*/ elem, /*String*/ role){
+		// summary:
+		//		Removes the specified non-XHTML role from an element.
+		// 		Removes role attribute if no specific role provided (for backwards compat.)
+
+		var roleValue = dojo.attr(elem, "role"); 
+		if(!roleValue){ return; }
+		if(role){
+			var searchRole = dojo.isFF < 3 ? "wairole:" + role : role;
+			var t = dojo.trim((" " + roleValue + " ").replace(" " + searchRole + " ", " "));
+			dojo.attr(elem, "role", t);
+		}else{
+			elem.removeAttribute("role");	
+		}
+	},
+
+	hasWaiState: function(/*Element*/ elem, /*String*/ state){
+		// summary:
+		//		Determines if an element has a given state.
+		// description:
+		//		On Firefox 2 and below, we check for an attribute in namespace
+		//		"http://www.w3.org/2005/07/aaa" with a name of the given state.
+		//		On all other browsers, we check for an attribute
+		//		called "aria-"+state.
+		// returns:
+		//		true if elem has a value for the given state and
+		//		false if it does not.
+		if(dojo.isFF < 3){
+			return elem.hasAttributeNS("http://www.w3.org/2005/07/aaa", state);
+		}
+		return elem.hasAttribute ? elem.hasAttribute("aria-"+state) : !!elem.getAttribute("aria-"+state);
+	},
+
+	getWaiState: function(/*Element*/ elem, /*String*/ state){
+		// summary:
+		//		Gets the value of a state on an element.
+		// description:
+		//		On Firefox 2 and below, we check for an attribute in namespace
+		//		"http://www.w3.org/2005/07/aaa" with a name of the given state.
+		//		On all other browsers, we check for an attribute called
+		//		"aria-"+state.
+		// returns:
+		//		The value of the requested state on elem
+		//		or an empty string if elem has no value for state.
+		if(dojo.isFF < 3){
+			return elem.getAttributeNS("http://www.w3.org/2005/07/aaa", state);
+		}
+		return elem.getAttribute("aria-"+state) || "";
+	},
+
+	setWaiState: function(/*Element*/ elem, /*String*/ state, /*String*/ value){
+		// summary:
+		//		Sets a state on an element.
+		// description:
+		//		On Firefox 2 and below, we set an attribute in namespace
+		//		"http://www.w3.org/2005/07/aaa" with a name of the given state.
+		//		On all other browsers, we set an attribute called
+		//		"aria-"+state.
+		if(dojo.isFF < 3){
+			elem.setAttributeNS("http://www.w3.org/2005/07/aaa",
+				"aaa:"+state, value);
+		}else{
+			elem.setAttribute("aria-"+state, value);
+		}
+	},
+
+	removeWaiState: function(/*Element*/ elem, /*String*/ state){
+		// summary:
+		//		Removes a state from an element.
+		// description:
+		//		On Firefox 2 and below, we remove the attribute in namespace
+		//		"http://www.w3.org/2005/07/aaa" with a name of the given state.
+		//		On all other browsers, we remove the attribute called
+		//		"aria-"+state.
+		if(dojo.isFF < 3){
+			elem.removeAttributeNS("http://www.w3.org/2005/07/aaa", state);
+		}else{
+			elem.removeAttribute("aria-"+state);
+		}
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base"] = true;
+dojo.provide("dijit._base");
+
+
+
+
+
+
+
+
+
+
+
+}
+
+if(!dojo._hasResource["dijit._Widget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._Widget"] = true;
+dojo.provide("dijit._Widget");
+
+dojo.require( "dijit._base" );
+
+dojo.connect(dojo, "connect", 
+	function(/*Widget*/ widget, /*String*/ event){
+		if(widget && dojo.isFunction(widget._onConnect)){
+			widget._onConnect(event);
+		}
+	});
+
+dijit._connectOnUseEventHandler = function(/*Event*/ event){};
+
+(function(){
+
+var _attrReg = {};
+var getAttrReg = function(dc){
+	if(!_attrReg[dc]){
+		var r = [];
+		var attrs;
+		var proto = dojo.getObject(dc).prototype;
+		for(var fxName in proto){
+			if(dojo.isFunction(proto[fxName]) && (attrs = fxName.match(/^_set([a-zA-Z]*)Attr$/)) && attrs[1]){
+				r.push(attrs[1].charAt(0).toLowerCase() + attrs[1].substr(1));
+			}
+		}
+		_attrReg[dc] = r;
+	}
+	return _attrReg[dc]||[];
+}
+
+dojo.declare("dijit._Widget", null, {
+	// summary:
+	//		Base class for all dijit widgets. 	
+
+	// id: [const] String
+	//		A unique, opaque ID string that can be assigned by users or by the
+	//		system. If the developer passes an ID which is known not to be
+	//		unique, the specified ID is ignored and the system-generated ID is
+	//		used instead.
+	id: "",
+
+	// lang: [const] String
+	//		Rarely used.  Overrides the default Dojo locale used to render this widget,
+	//		as defined by the [HTML LANG](http://www.w3.org/TR/html401/struct/dirlang.html#adef-lang) attribute.
+	//		Value must be among the list of locales specified during by the Dojo bootstrap,
+	//		formatted according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt) (like en-us).
+	lang: "",
+
+	// dir: [const] String
+	//		Unsupported by Dijit, but here for completeness.  Dijit only supports setting text direction on the
+	//		entire document.
+	//		Bi-directional support, as defined by the [HTML DIR](http://www.w3.org/TR/html401/struct/dirlang.html#adef-dir)
+	//		attribute. Either left-to-right "ltr" or right-to-left "rtl".
+	dir: "",
+
+	// class: String
+	//		HTML class attribute
+	"class": "",
+
+	// style: String||Object
+	//		HTML style attributes as cssText string or name/value hash
+	style: "",
+
+	// title: String
+	//		HTML title attribute, used to specify the title of tabs, accordion panes, etc.
+	title: "",
+
+	// srcNodeRef: [readonly] DomNode
+	//		pointer to original dom node
+	srcNodeRef: null,
+
+	// domNode: [readonly] DomNode
+	//		This is our visible representation of the widget! Other DOM
+	//		Nodes may by assigned to other properties, usually through the
+	//		template system's dojoAttachPoint syntax, but the domNode
+	//		property is the canonical "top level" node in widget UI.
+	domNode: null,
+
+	// containerNode: [readonly] DomNode
+	//		Designates where children of the source dom node will be placed.
+	//		"Children" in this case refers to both dom nodes and widgets.
+	//		For example, for myWidget:
+	//
+	//		|	<div dojoType=myWidget>
+	//		|		<b> here's a plain dom node
+	//		|		<span dojoType=subWidget>and a widget</span>
+	//		|		<i> and another plain dom node </i>
+	//		|	</div>
+	//
+	//		containerNode would point to:
+	//
+	//		|		<b> here's a plain dom node
+	//		|		<span dojoType=subWidget>and a widget</span>
+	//		|		<i> and another plain dom node </i>
+	//
+	//		In templated widgets, "containerNode" is set via a
+	//		dojoAttachPoint assignment.
+	//
+	//		containerNode must be defined for any widget that accepts innerHTML
+	//		(like ContentPane or BorderContainer or even Button), and conversely
+	//		is null for widgets that don't, like TextBox.
+	containerNode: null,
+
+	// attributeMap: [protected] Object
+	//		attributeMap sets up a "binding" between attributes (aka properties)
+	//		of the widget and the widget's DOM.
+	//		Changes to widget attributes listed in attributeMap will be 
+	//		reflected into the DOM.
+	//
+	//		For example, calling attr('title', 'hello')
+	//		on a TitlePane will automatically cause the TitlePane's DOM to update
+	//		with the new title.
+	//
+	//		attributeMap is a hash where the key is an attribute of the widget,
+	//		and the value reflects a binding to a:
+	//
+	//		- DOM node attribute
+	// |		focus: {node: "focusNode", type: "attribute"}
+	// 		Maps this.focus to this.focusNode.focus
+	//
+	//		- DOM node innerHTML
+	//	|		title: { node: "titleNode", type: "innerHTML" }
+	//		Maps this.title to this.titleNode.innerHTML
+	//
+	//		- DOM node CSS class
+	// |		myClass: { node: "domNode", type: "class" }
+	//		Maps this.myClass to this.domNode.className
+	//
+	//		If the value is an array, then each element in the array matches one of the
+	//		formats of the above list.
+	//
+	//		There are also some shorthands for backwards compatibility:
+	//		- string --> { node: string, type: "attribute" }, for example:
+	//	|	"focusNode" ---> { node: "focusNode", type: "attribute" }
+	//		- "" --> { node: "domNode", type: "attribute" }
+	attributeMap: {id:"", dir:"", lang:"", "class":"", style:"", title:""},
+
+	// _deferredConnects: [protected] Object
+	//		attributeMap addendum for event handlers that should be connected only on first use
+	_deferredConnects: {
+		onClick: "",
+		onDblClick: "",
+		onKeyDown: "",
+		onKeyPress: "",
+		onKeyUp: "",
+		onMouseMove: "",
+		onMouseDown: "",
+		onMouseOut: "",
+		onMouseOver: "",
+		onMouseLeave: "",
+		onMouseEnter: "",
+		onMouseUp: ""},
+
+	onClick: dijit._connectOnUseEventHandler,
+	/*=====
+	onClick: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of mouse click events.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onDblClick: dijit._connectOnUseEventHandler,
+	/*=====
+	onDblClick: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of mouse double click events.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onKeyDown: dijit._connectOnUseEventHandler,
+	/*=====
+	onKeyDown: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of keys being pressed down.
+		// event:
+		//		key Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onKeyPress: dijit._connectOnUseEventHandler,
+	/*=====
+	onKeyPress: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of printable keys being typed.
+		// event:
+		//		key Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onKeyUp: dijit._connectOnUseEventHandler,
+	/*=====
+	onKeyUp: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of keys being released.
+		// event:
+		//		key Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseDown: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseDown: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse button is pressed down.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseMove: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseMove: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse moves over nodes contained within this widget.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseOut: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseOut: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse moves off of nodes contained within this widget.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseOver: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseOver: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse moves onto nodes contained within this widget.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseLeave: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseLeave: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse moves off of this widget.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseEnter: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseEnter: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse moves onto this widget.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseUp: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseUp: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse button is released.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+
+	// Constants used in templates
+	
+	// _blankGif: [protected] URL
+	//		Used by <img> nodes in templates that really get there image via CSS background-image
+	_blankGif: (dojo.config.blankGif || dojo.moduleUrl("dojo", "resources/blank.gif")),
+
+	//////////// INITIALIZATION METHODS ///////////////////////////////////////
+
+	postscript: function(/*Object?*/params, /*DomNode|String*/srcNodeRef){
+		// summary:
+		//		Kicks off widget instantiation.  See create() for details.
+		// tags:
+		//		private
+		this.create(params, srcNodeRef);
+	},
+
+	create: function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){
+		// summary:
+		//		Kick off the life-cycle of a widget
+		// params:
+		//		Hash of initialization parameters for widget, including
+		//		scalar values (like title, duration etc.) and functions,
+		//		typically callbacks like onClick.
+		// srcNodeRef:
+		//		If a srcNodeRef (dom node) is specified:
+		//			- use srcNodeRef.innerHTML as my contents
+		//			- if this is a behavioral widget then apply behavior
+		//			  to that srcNodeRef 
+		//			- otherwise, replace srcNodeRef with my generated DOM
+		//			  tree
+		// description:
+		//		To understand the process by which widgets are instantiated, it
+		//		is critical to understand what other methods create calls and
+		//		which of them you'll want to override. Of course, adventurous
+		//		developers could override create entirely, but this should
+		//		only be done as a last resort.
+		//
+		//		Below is a list of the methods that are called, in the order
+		//		they are fired, along with notes about what they do and if/when
+		//		you should over-ride them in your widget:
+		//
+		// * postMixInProperties:
+		//	|	* a stub function that you can over-ride to modify
+		//		variables that may have been naively assigned by
+		//		mixInProperties
+		// * widget is added to manager object here
+		// * buildRendering:
+		//	|	* Subclasses use this method to handle all UI initialization
+		//		Sets this.domNode.  Templated widgets do this automatically
+		//		and otherwise it just uses the source dom node.
+		// * postCreate:
+		//	|	* a stub function that you can over-ride to modify take
+		//		actions once the widget has been placed in the UI
+		// tags:
+		//		private
+
+		// store pointer to original dom tree
+		this.srcNodeRef = dojo.byId(srcNodeRef);
+
+		// For garbage collection.  An array of handles returned by Widget.connect()
+		// Each handle returned from Widget.connect() is an array of handles from dojo.connect()
+		this._connects = [];
+
+		// To avoid double-connects, remove entries from _deferredConnects
+		// that have been setup manually by a subclass (ex, by dojoAttachEvent).
+		// If a subclass has redefined a callback (ex: onClick) then assume it's being
+		// connected to manually.
+		this._deferredConnects = dojo.clone(this._deferredConnects);
+		for(var attr in this.attributeMap){
+			delete this._deferredConnects[attr]; // can't be in both attributeMap and _deferredConnects
+		}
+		for(attr in this._deferredConnects){
+			if(this[attr] !== dijit._connectOnUseEventHandler){
+				delete this._deferredConnects[attr];	// redefined, probably dojoAttachEvent exists
+			}
+		}
+
+		//mixin our passed parameters
+		if(this.srcNodeRef && (typeof this.srcNodeRef.id == "string")){ this.id = this.srcNodeRef.id; }
+		if(params){
+			this.params = params;
+			dojo.mixin(this,params);
+		}
+		this.postMixInProperties();
+
+		// generate an id for the widget if one wasn't specified
+		// (be sure to do this before buildRendering() because that function might
+		// expect the id to be there.)
+		if(!this.id){
+			this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
+		}
+		dijit.registry.add(this);
+
+		this.buildRendering();
+
+		if(this.domNode){
+			// Copy attributes listed in attributeMap into the [newly created] DOM for the widget.
+			this._applyAttributes();
+
+			var source = this.srcNodeRef;
+			if(source && source.parentNode){
+				source.parentNode.replaceChild(this.domNode, source);
+			}
+
+			// If the developer has specified a handler as a widget parameter
+			// (ex: new Button({onClick: ...})
+			// then naturally need to connect from dom node to that handler immediately, 
+			for(attr in this.params){
+				this._onConnect(attr);
+			}
+		}
+		
+		if(this.domNode){
+			this.domNode.setAttribute("widgetId", this.id);
+		}
+		this.postCreate();
+
+		// If srcNodeRef has been processed and removed from the DOM (e.g. TemplatedWidget) then delete it to allow GC.
+		if(this.srcNodeRef && !this.srcNodeRef.parentNode){
+			delete this.srcNodeRef;
+		}	
+
+		this._created = true;
+	},
+
+	_applyAttributes: function(){
+		// summary:
+		//		Step during widget creation to copy all widget attributes to the
+		//		DOM as per attributeMap and _setXXXAttr functions.
+		// description:
+		//		Skips over blank/false attribute values, unless they were explicitly specified
+		//		as parameters to the widget, since those are the default anyway,
+		//		and setting tabIndex="" is different than not setting tabIndex at all.
+		//
+		//		It processes the attributes in the attribute map first, and then
+		//		it goes through and processes the attributes for the _setXXXAttr
+		//		functions that have been specified
+		// tags:
+		//		private
+		var condAttrApply = function(attr, scope){
+			if( (scope.params && attr in scope.params) || scope[attr]){
+				scope.attr(attr, scope[attr]);
+			}
+		};
+		for(var attr in this.attributeMap){
+			condAttrApply(attr, this);
+		}
+		dojo.forEach(getAttrReg(this.declaredClass), function(a){
+			if(!(a in this.attributeMap)){
+				condAttrApply(a, this);
+			}
+		}, this);
+	},
+
+	postMixInProperties: function(){
+		// summary:
+		//		Called after the parameters to the widget have been read-in,
+		//		but before the widget template is instantiated. Especially
+		//		useful to set properties that are referenced in the widget
+		//		template.
+		// tags:
+		//		protected
+	},
+
+	buildRendering: function(){
+		// summary:
+		//		Construct the UI for this widget, setting this.domNode.  Most
+		//		widgets will mixin `dijit._Templated`, which implements this
+		//		method.
+		// tags:
+		//		protected
+		this.domNode = this.srcNodeRef || dojo.create('div');
+	},
+
+	postCreate: function(){
+		// summary:
+		//		Called after a widget's dom has been setup
+		// tags:
+		//		protected
+	},
+
+	startup: function(){
+		// summary:
+		//		Called after a widget's children, and other widgets on the page, have been created.
+		//		Provides an opportunity to manipulate any children before they are displayed.
+		//		This is useful for composite widgets that need to control or layout sub-widgets.
+		//		Many layout widgets can use this as a wiring phase.
+		this._started = true;
+	},
+
+	//////////// DESTROY FUNCTIONS ////////////////////////////////
+
+	destroyRecursive: function(/*Boolean?*/ preserveDom){
+		// summary:
+		// 		Destroy this widget and it's descendants. This is the generic
+		// 		"destructor" function that all widget users should call to
+		// 		cleanly discard with a widget. Once a widget is destroyed, it's
+		// 		removed from the manager object.
+		// preserveDom:
+		//		If true, this method will leave the original Dom structure
+		//		alone of descendant Widgets. Note: This will NOT work with
+		//		dijit._Templated widgets.
+
+		this.destroyDescendants(preserveDom);
+		this.destroy(preserveDom);
+	},
+
+	destroy: function(/*Boolean*/ preserveDom){
+		// summary:
+		// 		Destroy this widget, but not its descendants.
+		//		Will, however, destroy internal widgets such as those used within a template.
+		// preserveDom: Boolean
+		//		If true, this method will leave the original Dom structure alone.
+		//		Note: This will not yet work with _Templated widgets
+
+		this.uninitialize();
+		dojo.forEach(this._connects, function(array){
+			dojo.forEach(array, dojo.disconnect);
+		});
+
+		// destroy widgets created as part of template, etc.
+		dojo.forEach(this._supportingWidgets||[], function(w){ 
+			if(w.destroy){
+				w.destroy();
+			}
+		});
+		
+		this.destroyRendering(preserveDom);
+		dijit.registry.remove(this.id);
+	},
+
+	destroyRendering: function(/*Boolean?*/ preserveDom){
+		// summary:
+		//		Destroys the DOM nodes associated with this widget
+		// preserveDom:
+		//		If true, this method will leave the original Dom structure alone
+		//		during tear-down. Note: this will not work with _Templated
+		//		widgets yet. 
+		// tags:
+		//		protected
+
+		if(this.bgIframe){
+			this.bgIframe.destroy(preserveDom);
+			delete this.bgIframe;
+		}
+
+		if(this.domNode){
+			if(preserveDom){
+				dojo.removeAttr(this.domNode, "widgetId");
+			}else{
+				dojo.destroy(this.domNode);
+			}
+			delete this.domNode;
+		}
+
+		if(this.srcNodeRef){
+			if(!preserveDom){
+				dojo.destroy(this.srcNodeRef);
+			}
+			delete this.srcNodeRef;
+		}
+	},
+
+	destroyDescendants: function(/*Boolean?*/ preserveDom){
+		// summary:
+		//		Recursively destroy the children of this widget and their
+		//		descendants.
+		// preserveDom:
+		//		If true, the preserveDom attribute is passed to all descendant
+		//		widget's .destroy() method. Not for use with _Templated
+		//		widgets.
+
+		// get all direct descendants and destroy them recursively
+		dojo.forEach(this.getChildren(), function(widget){ 
+			if(widget.destroyRecursive){
+				widget.destroyRecursive(preserveDom);
+			}
+		});
+	},
+
+
+	uninitialize: function(){
+		// summary:
+		//		Stub function. Override to implement custom widget tear-down
+		//		behavior.
+		// tags:
+		//		protected
+		return false;
+	},
+
+	////////////////// MISCELLANEOUS METHODS ///////////////////
+
+	onFocus: function(){
+		// summary:
+		//		Called when the widget becomes "active" because
+		//		it or a widget inside of it either has focus, or has recently
+		//		been clicked.
+		// tags:
+		//		callback
+	},
+
+	onBlur: function(){
+		// summary:
+		//		Called when the widget stops being "active" because
+		//		focus moved to something outside of it, or the user
+		//		clicked somewhere outside of it, or the widget was
+		//		hidden.
+		// tags:
+		//		callback
+	},
+
+	_onFocus: function(e){
+		// summary:
+		//		This is where widgets do processing for when they are active,
+		//		such as changing CSS classes.  See onFocus() for more details.
+		// tags:
+		//		protected
+		this.onFocus();
+	},
+
+	_onBlur: function(){
+		// summary:
+		//		This is where widgets do processing for when they stop being active,
+		//		such as changing CSS classes.  See onBlur() for more details.
+		// tags:
+		//		protected
+		this.onBlur();
+	},
+
+	_onConnect: function(/*String*/ event){
+		// summary:
+		//		Called when someone connects to one of my handlers.
+		//		"Turn on" that handler if it isn't active yet.
+		//
+		//		This is also called for every single initialization parameter
+		//		so need to do nothing for parameters like "id".
+		// tags:
+		//		private
+		if(event in this._deferredConnects){
+			var mapNode = this[this._deferredConnects[event]||'domNode'];
+			this.connect(mapNode, event.toLowerCase(), event);
+			delete this._deferredConnects[event];
+		}
+	},
+
+	_setClassAttr: function(/*String*/ value){
+		// summary:
+		//		Custom setter for the CSS "class" attribute
+		// tags:
+		//		protected
+		var mapNode = this[this.attributeMap["class"]||'domNode'];
+		dojo.removeClass(mapNode, this["class"])
+		this["class"] = value;
+		dojo.addClass(mapNode, value);
+	},
+
+	_setStyleAttr: function(/*String||Object*/ value){
+		// summary:
+		//		Sets the style attribut of the widget according to value,
+		//		which is either a hash like {height: "5px", width: "3px"}
+		//		or a plain string
+		// description:
+		//		Determines which node to set the style on based on style setting
+		//		in attributeMap.
+		// tags:
+		//		protected
+
+		var mapNode = this[this.attributeMap["style"]||'domNode'];
+		
+		// Note: technically we should revert any style setting made in a previous call
+		// to his method, but that's difficult to keep track of.
+
+		if(dojo.isObject(value)){
+			dojo.style(mapNode, value);
+		}else{
+			if(mapNode.style.cssText){
+				mapNode.style.cssText += "; " + value;
+			}else{
+				mapNode.style.cssText = value;
+			}
+		}
+
+		this["style"] = value;
+	},
+
+	setAttribute: function(/*String*/ attr, /*anything*/ value){
+		// summary:
+		//		Deprecated.  Use attr() instead.
+		// tags:
+		//		deprecated
+		dojo.deprecated(this.declaredClass+"::setAttribute() is deprecated. Use attr() instead.", "", "2.0");
+		this.attr(attr, value);
+	},
+	
+	_attrToDom: function(/*String*/ attr, /*String*/ value){
+		// summary:
+		//		Reflect a widget attribute (title, tabIndex, duration etc.) to
+		//		the widget DOM, as specified in attributeMap.
+		//
+		// description:
+		//		Also sets this["attr"] to the new value.
+		//		Note some attributes like "type"
+		//		cannot be processed this way as they are not mutable.
+		//
+		// tags:
+		//		private
+
+		var commands = this.attributeMap[attr];
+		dojo.forEach( dojo.isArray(commands) ? commands : [commands], function(command){
+
+			// Get target node and what we are doing to that node
+			var mapNode = this[command.node || command || "domNode"];	// DOM node
+			var type = command.type || "attribute";	// class, innerHTML, or attribute
+	
+			switch(type){
+				case "attribute":
+					if(dojo.isFunction(value)){ // functions execute in the context of the widget
+						value = dojo.hitch(this, value);
+					}
+					if(/^on[A-Z][a-zA-Z]*$/.test(attr)){ // eg. onSubmit needs to be onsubmit
+						attr = attr.toLowerCase();
+					}
+					dojo.attr(mapNode, attr, value);
+					break;
+				case "innerHTML":
+					mapNode.innerHTML = value;
+					break;
+				case "class":
+					dojo.removeClass(mapNode, this[attr]);
+					dojo.addClass(mapNode, value);
+					break;
+			}
+		}, this);
+		this[attr] = value;
+	},
+
+	attr: function(/*String|Object*/name, /*Object?*/value){
+		//	summary:
+		//		Set or get properties on a widget instance.
+		//	name:
+		//		The property to get or set. If an object is passed here and not
+		//		a string, its keys are used as names of attributes to be set
+		//		and the value of the object as values to set in the widget.
+		//	value:
+		//		Optional. If provided, attr() operates as a setter. If omitted,
+		//		the current value of the named property is returned.
+		//	description:
+		//		Get or set named properties on a widget. If no value is
+		//		provided, the current value of the attribute is returned,
+		//		potentially via a getter method. If a value is provided, then
+		//		the method acts as a setter, assigning the value to the name,
+		//		potentially calling any explicitly provided setters to handle
+		//		the operation. For instance, if the widget has properties "foo"
+		//		and "bar" and a method named "_setFooAttr", calling:
+		//	|	myWidget.attr("foo", "Howdy!");
+		//		would be equivalent to calling:
+		//	|	widget._setFooAttr("Howdy!");
+		//		while calling:
+		//	|	myWidget.attr("bar", "Howdy!");
+		//		would be the same as writing:
+		//	|	widget.bar = "Howdy!";
+		//		It also tries to copy the changes to the widget's DOM according
+		//		to settings in attributeMap (see description of `dijit._Widget.attributeMap`
+		//		for details)
+		//		For example, calling:
+		//	|	myTitlePane.attr("title", "Howdy!");
+		//		will do
+		//	|	myTitlePane.title = "Howdy!";
+		//	|	myTitlePane.title.innerHTML = "Howdy!";
+		//		It works for dom node attributes too.  Calling
+		//	|	widget.attr("disabled", true)
+		//		will set the disabled attribute on the widget's focusNode,
+		//		among other housekeeping for a change in disabled state.
+
+		//	open questions:
+		//		- how to handle build shortcut for attributes which want to map
+		//		into DOM attributes?
+		//		- what relationship should setAttribute()/attr() have to
+		//		layout() calls?
+		var args = arguments.length;
+		if(args == 1 && !dojo.isString(name)){
+			for(var x in name){ this.attr(x, name[x]); }
+			return this;
+		}
+		var names = this._getAttrNames(name);
+		if(args == 2){ // setter
+			if(this[names.s]){
+				// use the explicit setter
+				return this[names.s](value) || this;
+			}else{
+				// if param is specified as DOM node attribute, copy it
+				if(name in this.attributeMap){
+					this._attrToDom(name, value);
+				}
+
+				// FIXME: what about function assignments? Any way to connect() here?
+				this[name] = value;
+			}
+			return this;
+		}else{ // getter
+			if(this[names.g]){
+				return this[names.g]();
+			}else{
+				return this[name];
+			}
+		}
+	},
+
+	_attrPairNames: {},		// shared between all widgets
+	_getAttrNames: function(name){
+		// summary:
+		//		Helper function for Widget.attr().
+		//		Caches attribute name values so we don't do the string ops every time.
+		// tags:
+		//		private
+
+		var apn = this._attrPairNames;
+		if(apn[name]){ return apn[name]; }
+		var uc = name.charAt(0).toUpperCase() + name.substr(1);
+		return apn[name] = {
+			n: name+"Node",
+			s: "_set"+uc+"Attr",
+			g: "_get"+uc+"Attr"
+		};
+	},
+
+	toString: function(){
+		// summary:
+		//		Returns a string that represents the widget. When a widget is
+		//		cast to a string, this method will be used to generate the
+		//		output. Currently, it does not implement any sort of reversable
+		//		serialization.
+		return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String
+	},
+
+	getDescendants: function(){
+		// summary:
+		//		Returns all the widgets that contained by this, i.e., all widgets underneath this.containerNode.
+		//		This method should generally be avoided as it returns widgets declared in templates, which are
+		//		supposed to be internal/hidden, but it's left here for back-compat reasons.
+
+		if(this.containerNode){
+			var list = dojo.query('[widgetId]', this.containerNode);
+			return list.map(dijit.byNode);		// Array
+		}else{
+			return [];
+		}
+	},
+
+	getChildren: function(){
+		// summary:
+		//		Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
+		//		Does not return nested widgets, nor widgets that are part of this widget's template.
+		if(this.containerNode){
+			return dijit.findWidgets(this.containerNode);
+		}else{
+			return [];
+		}
+	},
+
+	// nodesWithKeyClick: [private] String[]
+	//		List of nodes that correctly handle click events via native browser support,
+	//		and don't need dijit's help
+	nodesWithKeyClick: ["input", "button"],
+
+	connect: function(
+			/*Object|null*/ obj,
+			/*String|Function*/ event,
+			/*String|Function*/ method){
+		// summary:
+		//		Connects specified obj/event to specified method of this object
+		//		and registers for disconnect() on widget destroy.
+		// description:
+		//		Provide widget-specific analog to dojo.connect, except with the
+		//		implicit use of this widget as the target object.
+		//		This version of connect also provides a special "ondijitclick"
+		//		event which triggers on a click or space-up, enter-down in IE
+		//		or enter press in FF (since often can't cancel enter onkeydown
+		//		in FF)
+		// example:
+		//	|	var btn = new dijit.form.Button();
+		//	|	// when foo.bar() is called, call the listener we're going to
+		//	|	// provide in the scope of btn
+		//	|	btn.connect(foo, "bar", function(){ 
+		//	|		
+		//	|	});
+		// tags:
+		//		protected
+
+		var d = dojo;
+		var dc = dojo.connect;
+		var handles =[];
+		if(event == "ondijitclick"){
+			// add key based click activation for unsupported nodes.
+			if(!this.nodesWithKeyClick[obj.nodeName]){
+				var m = d.hitch(this, method);
+				handles.push(
+					dc(obj, "onkeydown", this, function(e){
+						if(!d.isFF && e.keyCode == d.keys.ENTER &&
+							!e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){
+							return m(e);
+						}else if(e.keyCode == d.keys.SPACE){
+							// stop space down as it causes IE to scroll
+							// the browser window
+							d.stopEvent(e);
+						}
+			 		}),
+					dc(obj, "onkeyup", this, function(e){
+						if(e.keyCode == d.keys.SPACE && 
+							!e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){ return m(e); }
+					})
+				);
+			 	if(d.isFF){
+					handles.push(
+						dc(obj, "onkeypress", this, function(e){
+							if(e.keyCode == d.keys.ENTER &&
+								!e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){ return m(e); }
+						})
+					);
+			 	}
+			}
+			event = "onclick";
+		}
+		handles.push(dc(obj, event, this, method));
+
+		// return handles for FormElement and ComboBox
+		this._connects.push(handles);
+		return handles;
+	},
+
+	disconnect: function(/*Object*/ handles){
+		// summary:
+		//		Disconnects handle created by this.connect.
+		//		Also removes handle from this widget's list of connects
+		// tags:
+		//		protected
+		for(var i=0; i<this._connects.length; i++){
+			if(this._connects[i]==handles){
+				dojo.forEach(handles, dojo.disconnect);
+				this._connects.splice(i, 1);
+				return;
+			}
+		}
+	},
+
+	isLeftToRight: function(){
+		// summary:
+		//		Checks the page for text direction
+		// tags:
+		//		protected
+		return dojo._isBodyLtr(); //Boolean
+	},
+
+	isFocusable: function(){
+		// summary:
+		//		Return true if this widget can currently be focused
+		//		and false if not
+		return this.focus && (dojo.style(this.domNode, "display") != "none");
+	},
+	
+	placeAt: function(/* String|DomNode|_Widget */reference, /* String?|Int? */position){
+		// summary:
+		//		Place this widget's domNode reference somewhere in the DOM based
+		//		on standard dojo.place conventions, or passing a Widget reference that
+		//		contains and addChild member.
+		//
+		// description:
+		//		A convenience function provided in all _Widgets, providing a simple
+		//		shorthand mechanism to put an existing (or newly created) Widget
+		//		somewhere in the dom, and allow chaining.
+		//
+		// reference: 
+		//		The String id of a domNode, a domNode reference, or a reference to a Widget posessing 
+		//		an addChild method.
+		//
+		// position: 
+		//		If passed a string or domNode reference, the position argument
+		//		accepts a string just as dojo.place does, one of: "first", "last", 
+		//		"before", or "after". 
+		//
+		//		If passed a _Widget reference, and that widget reference has an ".addChild" method, 
+		//		it will be called passing this widget instance into that method, supplying the optional
+		//		position index passed.
+		//
+		// returns: dijit._Widget
+		//		Provides a useful return of the newly created dijit._Widget instance so you 
+		//		can "chain" this function by instantiating, placing, then saving the return value
+		//		to a variable. 
+		//
+		// example:
+		// | 	// create a Button with no srcNodeRef, and place it in the body:
+		// | 	var button = new dijit.form.Button({ label:"click" }).placeAt(dojo.body());
+		// | 	// now, 'button' is still the widget reference to the newly created button
+		// | 	dojo.connect(button, "onClick", function(e){  });
+		//
+		// example:
+		// |	// create a button out of a node with id="src" and append it to id="wrapper":
+		// | 	var button = new dijit.form.Button({},"src").placeAt("wrapper");
+		//
+		// example:
+		// |	// place a new button as the first element of some div
+		// |	var button = new dijit.form.Button({ label:"click" }).placeAt("wrapper","first");
+		//
+		// example: 
+		// |	// create a contentpane and add it to a TabContainer
+		// |	var tc = dijit.byId("myTabs");
+		// |	new dijit.layout.ContentPane({ href:"foo.html", title:"Wow!" }).placeAt(tc)
+
+		if(reference["declaredClass"] && reference["addChild"]){
+			reference.addChild(this, position);
+		}else{
+			dojo.place(this.domNode, reference, position);
+		}
+		return this;
+	}
+
+});
+
+})();
+
+}
+
+if(!dojo._hasResource["dojox.gfx.matrix"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.matrix"] = true;
+dojo.provide("dojox.gfx.matrix");
+
+(function(){
+	var m = dojox.gfx.matrix;
+
+	// candidates for dojox.math:
+	var _degToRadCache = {};
+	m._degToRad = function(degree){
+		return _degToRadCache[degree] || (_degToRadCache[degree] = (Math.PI * degree / 180));
+	};
+	m._radToDeg = function(radian){ return radian / Math.PI * 180; };
+
+	m.Matrix2D = function(arg){
+		// summary: a 2D matrix object
+		// description: Normalizes a 2D matrix-like object. If arrays is passed,
+		//		all objects of the array are normalized and multiplied sequentially.
+		// arg: Object
+		//		a 2D matrix-like object, a number, or an array of such objects
+		if(arg){
+			if(typeof arg == "number"){
+				this.xx = this.yy = arg;
+			}else if(arg instanceof Array){
+				if(arg.length > 0){
+					var matrix = m.normalize(arg[0]);
+					// combine matrices
+					for(var i = 1; i < arg.length; ++i){
+						var l = matrix, r = dojox.gfx.matrix.normalize(arg[i]);
+						matrix = new m.Matrix2D();
+						matrix.xx = l.xx * r.xx + l.xy * r.yx;
+						matrix.xy = l.xx * r.xy + l.xy * r.yy;
+						matrix.yx = l.yx * r.xx + l.yy * r.yx;
+						matrix.yy = l.yx * r.xy + l.yy * r.yy;
+						matrix.dx = l.xx * r.dx + l.xy * r.dy + l.dx;
+						matrix.dy = l.yx * r.dx + l.yy * r.dy + l.dy;
+					}
+					dojo.mixin(this, matrix);
+				}
+			}else{
+				dojo.mixin(this, arg);
+			}
+		}
+	};
+
+	// the default (identity) matrix, which is used to fill in missing values
+	dojo.extend(m.Matrix2D, {xx: 1, xy: 0, yx: 0, yy: 1, dx: 0, dy: 0});
+
+	dojo.mixin(m, {
+		// summary: class constants, and methods of dojox.gfx.matrix
+
+		// matrix constants
+
+		// identity: dojox.gfx.matrix.Matrix2D
+		//		an identity matrix constant: identity * (x, y) == (x, y)
+		identity: new m.Matrix2D(),
+
+		// flipX: dojox.gfx.matrix.Matrix2D
+		//		a matrix, which reflects points at x = 0 line: flipX * (x, y) == (-x, y)
+		flipX:    new m.Matrix2D({xx: -1}),
+
+		// flipY: dojox.gfx.matrix.Matrix2D
+		//		a matrix, which reflects points at y = 0 line: flipY * (x, y) == (x, -y)
+		flipY:    new m.Matrix2D({yy: -1}),
+
+		// flipXY: dojox.gfx.matrix.Matrix2D
+		//		a matrix, which reflects points at the origin of coordinates: flipXY * (x, y) == (-x, -y)
+		flipXY:   new m.Matrix2D({xx: -1, yy: -1}),
+
+		// matrix creators
+
+		translate: function(a, b){
+			// summary: forms a translation matrix
+			// description: The resulting matrix is used to translate (move) points by specified offsets.
+			// a: Number: an x coordinate value
+			// b: Number: a y coordinate value
+			if(arguments.length > 1){
+				return new m.Matrix2D({dx: a, dy: b}); // dojox.gfx.matrix.Matrix2D
+			}
+			// branch
+			// a: dojox.gfx.Point: a point-like object, which specifies offsets for both dimensions
+			// b: null
+			return new m.Matrix2D({dx: a.x, dy: a.y}); // dojox.gfx.matrix.Matrix2D
+		},
+		scale: function(a, b){
+			// summary: forms a scaling matrix
+			// description: The resulting matrix is used to scale (magnify) points by specified offsets.
+			// a: Number: a scaling factor used for the x coordinate
+			// b: Number: a scaling factor used for the y coordinate
+			if(arguments.length > 1){
+				return new m.Matrix2D({xx: a, yy: b}); // dojox.gfx.matrix.Matrix2D
+			}
+			if(typeof a == "number"){
+				// branch
+				// a: Number: a uniform scaling factor used for the both coordinates
+				// b: null
+				return new m.Matrix2D({xx: a, yy: a}); // dojox.gfx.matrix.Matrix2D
+			}
+			// branch
+			// a: dojox.gfx.Point: a point-like object, which specifies scale factors for both dimensions
+			// b: null
+			return new m.Matrix2D({xx: a.x, yy: a.y}); // dojox.gfx.matrix.Matrix2D
+		},
+		rotate: function(angle){
+			// summary: forms a rotating matrix
+			// description: The resulting matrix is used to rotate points
+			//		around the origin of coordinates (0, 0) by specified angle.
+			// angle: Number: an angle of rotation in radians (>0 for CW)
+			var c = Math.cos(angle);
+			var s = Math.sin(angle);
+			return new m.Matrix2D({xx: c, xy: -s, yx: s, yy: c}); // dojox.gfx.matrix.Matrix2D
+		},
+		rotateg: function(degree){
+			// summary: forms a rotating matrix
+			// description: The resulting matrix is used to rotate points
+			//		around the origin of coordinates (0, 0) by specified degree.
+			//		See dojox.gfx.matrix.rotate() for comparison.
+			// degree: Number: an angle of rotation in degrees (>0 for CW)
+			return m.rotate(m._degToRad(degree)); // dojox.gfx.matrix.Matrix2D
+		},
+		skewX: function(angle) {
+			// summary: forms an x skewing matrix
+			// description: The resulting matrix is used to skew points in the x dimension
+			//		around the origin of coordinates (0, 0) by specified angle.
+			// angle: Number: an skewing angle in radians
+			return new m.Matrix2D({xy: Math.tan(angle)}); // dojox.gfx.matrix.Matrix2D
+		},
+		skewXg: function(degree){
+			// summary: forms an x skewing matrix
+			// description: The resulting matrix is used to skew points in the x dimension
+			//		around the origin of coordinates (0, 0) by specified degree.
+			//		See dojox.gfx.matrix.skewX() for comparison.
+			// degree: Number: an skewing angle in degrees
+			return m.skewX(m._degToRad(degree)); // dojox.gfx.matrix.Matrix2D
+		},
+		skewY: function(angle){
+			// summary: forms a y skewing matrix
+			// description: The resulting matrix is used to skew points in the y dimension
+			//		around the origin of coordinates (0, 0) by specified angle.
+			// angle: Number: an skewing angle in radians
+			return new m.Matrix2D({yx: Math.tan(angle)}); // dojox.gfx.matrix.Matrix2D
+		},
+		skewYg: function(degree){
+			// summary: forms a y skewing matrix
+			// description: The resulting matrix is used to skew points in the y dimension
+			//		around the origin of coordinates (0, 0) by specified degree.
+			//		See dojox.gfx.matrix.skewY() for comparison.
+			// degree: Number: an skewing angle in degrees
+			return m.skewY(m._degToRad(degree)); // dojox.gfx.matrix.Matrix2D
+		},
+		reflect: function(a, b){
+			// summary: forms a reflection matrix
+			// description: The resulting matrix is used to reflect points around a vector,
+			//		which goes through the origin.
+			// a: dojox.gfx.Point: a point-like object, which specifies a vector of reflection
+			// b: null
+			if(arguments.length == 1){
+				b = a.y;
+				a = a.x;
+			}
+			// branch
+			// a: Number: an x coordinate value
+			// b: Number: a y coordinate value
+
+			// make a unit vector
+			var a2 = a * a, b2 = b * b, n2 = a2 + b2, xy = 2 * a * b / n2;
+			return new m.Matrix2D({xx: 2 * a2 / n2 - 1, xy: xy, yx: xy, yy: 2 * b2 / n2 - 1}); // dojox.gfx.matrix.Matrix2D
+		},
+		project: function(a, b){
+			// summary: forms an orthogonal projection matrix
+			// description: The resulting matrix is used to project points orthogonally on a vector,
+			//		which goes through the origin.
+			// a: dojox.gfx.Point: a point-like object, which specifies a vector of projection
+			// b: null
+			if(arguments.length == 1){
+				b = a.y;
+				a = a.x;
+			}
+			// branch
+			// a: Number: an x coordinate value
+			// b: Number: a y coordinate value
+
+			// make a unit vector
+			var a2 = a * a, b2 = b * b, n2 = a2 + b2, xy = a * b / n2;
+			return new m.Matrix2D({xx: a2 / n2, xy: xy, yx: xy, yy: b2 / n2}); // dojox.gfx.matrix.Matrix2D
+		},
+
+		// ensure matrix 2D conformance
+		normalize: function(matrix){
+			// summary: converts an object to a matrix, if necessary
+			// description: Converts any 2D matrix-like object or an array of
+			//		such objects to a valid dojox.gfx.matrix.Matrix2D object.
+			// matrix: Object: an object, which is converted to a matrix, if necessary
+			return (matrix instanceof m.Matrix2D) ? matrix : new m.Matrix2D(matrix); // dojox.gfx.matrix.Matrix2D
+		},
+
+		// common operations
+
+		clone: function(matrix){
+			// summary: creates a copy of a 2D matrix
+			// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object to be cloned
+			var obj = new m.Matrix2D();
+			for(var i in matrix){
+				if(typeof(matrix[i]) == "number" && typeof(obj[i]) == "number" && obj[i] != matrix[i]) obj[i] = matrix[i];
+			}
+			return obj; // dojox.gfx.matrix.Matrix2D
+		},
+		invert: function(matrix){
+			// summary: inverts a 2D matrix
+			// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object to be inverted
+			var M = m.normalize(matrix),
+				D = M.xx * M.yy - M.xy * M.yx,
+				M = new m.Matrix2D({
+					xx: M.yy/D, xy: -M.xy/D,
+					yx: -M.yx/D, yy: M.xx/D,
+					dx: (M.xy * M.dy - M.yy * M.dx) / D,
+					dy: (M.yx * M.dx - M.xx * M.dy) / D
+				});
+			return M; // dojox.gfx.matrix.Matrix2D
+		},
+		_multiplyPoint: function(matrix, x, y){
+			// summary: applies a matrix to a point
+			// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix object to be applied
+			// x: Number: an x coordinate of a point
+			// y: Number: a y coordinate of a point
+			return {x: matrix.xx * x + matrix.xy * y + matrix.dx, y: matrix.yx * x + matrix.yy * y + matrix.dy}; // dojox.gfx.Point
+		},
+		multiplyPoint: function(matrix, /* Number||Point */ a, /* Number, optional */ b){
+			// summary: applies a matrix to a point
+			// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix object to be applied
+			// a: Number: an x coordinate of a point
+			// b: Number: a y coordinate of a point
+			var M = m.normalize(matrix);
+			if(typeof a == "number" && typeof b == "number"){
+				return m._multiplyPoint(M, a, b); // dojox.gfx.Point
+			}
+			// branch
+			// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix object to be applied
+			// a: dojox.gfx.Point: a point
+			// b: null
+			return m._multiplyPoint(M, a.x, a.y); // dojox.gfx.Point
+		},
+		multiply: function(matrix){
+			// summary: combines matrices by multiplying them sequentially in the given order
+			// matrix: dojox.gfx.matrix.Matrix2D...: a 2D matrix-like object,
+			//		all subsequent arguments are matrix-like objects too
+			var M = m.normalize(matrix);
+			// combine matrices
+			for(var i = 1; i < arguments.length; ++i){
+				var l = M, r = m.normalize(arguments[i]);
+				M = new m.Matrix2D();
+				M.xx = l.xx * r.xx + l.xy * r.yx;
+				M.xy = l.xx * r.xy + l.xy * r.yy;
+				M.yx = l.yx * r.xx + l.yy * r.yx;
+				M.yy = l.yx * r.xy + l.yy * r.yy;
+				M.dx = l.xx * r.dx + l.xy * r.dy + l.dx;
+				M.dy = l.yx * r.dx + l.yy * r.dy + l.dy;
+			}
+			return M; // dojox.gfx.matrix.Matrix2D
+		},
+
+		// high level operations
+
+		_sandwich: function(matrix, x, y){
+			// summary: applies a matrix at a centrtal point
+			// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object, which is applied at a central point
+			// x: Number: an x component of the central point
+			// y: Number: a y component of the central point
+			return m.multiply(m.translate(x, y), matrix, m.translate(-x, -y)); // dojox.gfx.matrix.Matrix2D
+		},
+		scaleAt: function(a, b, c, d){
+			// summary: scales a picture using a specified point as a center of scaling
+			// description: Compare with dojox.gfx.matrix.scale().
+			// a: Number: a scaling factor used for the x coordinate
+			// b: Number: a scaling factor used for the y coordinate
+			// c: Number: an x component of a central point
+			// d: Number: a y component of a central point
+
+			// accepts several signatures:
+			//	1) uniform scale factor, Point
+			//	2) uniform scale factor, x, y
+			//	3) x scale, y scale, Point
+			//	4) x scale, y scale, x, y
+
+			switch(arguments.length){
+				case 4:
+					// a and b are scale factor components, c and d are components of a point
+					return m._sandwich(m.scale(a, b), c, d); // dojox.gfx.matrix.Matrix2D
+				case 3:
+					if(typeof c == "number"){
+						// branch
+						// a: Number: a uniform scaling factor used for both coordinates
+						// b: Number: an x component of a central point
+						// c: Number: a y component of a central point
+						// d: null
+						return m._sandwich(m.scale(a), b, c); // dojox.gfx.matrix.Matrix2D
+					}
+					// branch
+					// a: Number: a scaling factor used for the x coordinate
+					// b: Number: a scaling factor used for the y coordinate
+					// c: dojox.gfx.Point: a central point
+					// d: null
+					return m._sandwich(m.scale(a, b), c.x, c.y); // dojox.gfx.matrix.Matrix2D
+			}
+			// branch
+			// a: Number: a uniform scaling factor used for both coordinates
+			// b: dojox.gfx.Point: a central point
+			// c: null
+			// d: null
+			return m._sandwich(m.scale(a), b.x, b.y); // dojox.gfx.matrix.Matrix2D
+		},
+		rotateAt: function(angle, a, b){
+			// summary: rotates a picture using a specified point as a center of rotation
+			// description: Compare with dojox.gfx.matrix.rotate().
+			// angle: Number: an angle of rotation in radians (>0 for CW)
+			// a: Number: an x component of a central point
+			// b: Number: a y component of a central point
+
+			// accepts several signatures:
+			//	1) rotation angle in radians, Point
+			//	2) rotation angle in radians, x, y
+
+			if(arguments.length > 2){
+				return m._sandwich(m.rotate(angle), a, b); // dojox.gfx.matrix.Matrix2D
+			}
+
+			// branch
+			// angle: Number: an angle of rotation in radians (>0 for CCW)
+			// a: dojox.gfx.Point: a central point
+			// b: null
+			return m._sandwich(m.rotate(angle), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+		},
+		rotategAt: function(degree, a, b){
+			// summary: rotates a picture using a specified point as a center of rotation
+			// description: Compare with dojox.gfx.matrix.rotateg().
+			// degree: Number: an angle of rotation in degrees (>0 for CW)
+			// a: Number: an x component of a central point
+			// b: Number: a y component of a central point
+
+			// accepts several signatures:
+			//	1) rotation angle in degrees, Point
+			//	2) rotation angle in degrees, x, y
+
+			if(arguments.length > 2){
+				return m._sandwich(m.rotateg(degree), a, b); // dojox.gfx.matrix.Matrix2D
+			}
+
+			// branch
+			// degree: Number: an angle of rotation in degrees (>0 for CCW)
+			// a: dojox.gfx.Point: a central point
+			// b: null
+			return m._sandwich(m.rotateg(degree), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+		},
+		skewXAt: function(angle, a, b){
+			// summary: skews a picture along the x axis using a specified point as a center of skewing
+			// description: Compare with dojox.gfx.matrix.skewX().
+			// angle: Number: an skewing angle in radians
+			// a: Number: an x component of a central point
+			// b: Number: a y component of a central point
+
+			// accepts several signatures:
+			//	1) skew angle in radians, Point
+			//	2) skew angle in radians, x, y
+
+			if(arguments.length > 2){
+				return m._sandwich(m.skewX(angle), a, b); // dojox.gfx.matrix.Matrix2D
+			}
+
+			// branch
+			// angle: Number: an skewing angle in radians
+			// a: dojox.gfx.Point: a central point
+			// b: null
+			return m._sandwich(m.skewX(angle), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+		},
+		skewXgAt: function(degree, a, b){
+			// summary: skews a picture along the x axis using a specified point as a center of skewing
+			// description: Compare with dojox.gfx.matrix.skewXg().
+			// degree: Number: an skewing angle in degrees
+			// a: Number: an x component of a central point
+			// b: Number: a y component of a central point
+
+			// accepts several signatures:
+			//	1) skew angle in degrees, Point
+			//	2) skew angle in degrees, x, y
+
+			if(arguments.length > 2){
+				return m._sandwich(m.skewXg(degree), a, b); // dojox.gfx.matrix.Matrix2D
+			}
+
+			// branch
+			// degree: Number: an skewing angle in degrees
+			// a: dojox.gfx.Point: a central point
+			// b: null
+			return m._sandwich(m.skewXg(degree), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+		},
+		skewYAt: function(angle, a, b){
+			// summary: skews a picture along the y axis using a specified point as a center of skewing
+			// description: Compare with dojox.gfx.matrix.skewY().
+			// angle: Number: an skewing angle in radians
+			// a: Number: an x component of a central point
+			// b: Number: a y component of a central point
+
+			// accepts several signatures:
+			//	1) skew angle in radians, Point
+			//	2) skew angle in radians, x, y
+
+			if(arguments.length > 2){
+				return m._sandwich(m.skewY(angle), a, b); // dojox.gfx.matrix.Matrix2D
+			}
+
+			// branch
+			// angle: Number: an skewing angle in radians
+			// a: dojox.gfx.Point: a central point
+			// b: null
+			return m._sandwich(m.skewY(angle), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+		},
+		skewYgAt: function(/* Number */ degree, /* Number||Point */ a, /* Number, optional */ b){
+			// summary: skews a picture along the y axis using a specified point as a center of skewing
+			// description: Compare with dojox.gfx.matrix.skewYg().
+			// degree: Number: an skewing angle in degrees
+			// a: Number: an x component of a central point
+			// b: Number: a y component of a central point
+
+			// accepts several signatures:
+			//	1) skew angle in degrees, Point
+			//	2) skew angle in degrees, x, y
+
+			if(arguments.length > 2){
+				return m._sandwich(m.skewYg(degree), a, b); // dojox.gfx.matrix.Matrix2D
+			}
+
+			// branch
+			// degree: Number: an skewing angle in degrees
+			// a: dojox.gfx.Point: a central point
+			// b: null
+			return m._sandwich(m.skewYg(degree), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+		}
+
+		//TODO: rect-to-rect mapping, scale-to-fit (isotropic and anisotropic versions)
+
+	});
+})();
+
+// propagate Matrix2D up
+dojox.gfx.Matrix2D = dojox.gfx.matrix.Matrix2D;
+
+}
+
+if(!dojo._hasResource["dojox.gfx._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx._base"] = true;
+dojo.provide("dojox.gfx._base");
+
+(function(){
+	var g = dojox.gfx, b = g._base;
+
+	// candidates for dojox.style (work on VML and SVG nodes)
+	g._hasClass = function(/*DomNode*/node, /*String*/classStr){
+		//	summary:
+		//		Returns whether or not the specified classes are a portion of the
+		//		class list currently applied to the node.
+		// return (new RegExp('(^|\\s+)'+classStr+'(\\s+|$)')).test(node.className)	// Boolean
+		var cls = node.getAttribute("className");
+		return cls && (" " + cls + " ").indexOf(" " + classStr + " ") >= 0;  // Boolean
+	}
+	g._addClass = function(/*DomNode*/node, /*String*/classStr){
+		//	summary:
+		//		Adds the specified classes to the end of the class list on the
+		//		passed node.
+		var cls = node.getAttribute("className") || "";
+		if(!cls || (" " + cls + " ").indexOf(" " + classStr + " ") < 0){
+			node.setAttribute("className", cls + (cls ? " " : "") + classStr);
+		}
+	}
+	g._removeClass = function(/*DomNode*/node, /*String*/classStr){
+		//	summary: Removes classes from node.
+		var cls = node.getAttribute("className");
+		if(cls){
+			node.setAttribute(
+				"className", 
+				cls.replace(new RegExp('(^|\\s+)' + classStr + '(\\s+|$)'), "$1$2")
+			);
+		}
+	}
+
+	// candidate for dojox.html.metrics (dynamic font resize handler is not implemented here)
+
+	//	derived from Morris John's emResized measurer
+	b._getFontMeasurements = function(){
+		//	summary:
+		//		Returns an object that has pixel equivilents of standard font
+		//		size values.
+		var heights = {
+			'1em': 0, '1ex': 0, '100%': 0, '12pt': 0, '16px': 0, 'xx-small': 0,
+			'x-small': 0, 'small': 0, 'medium': 0, 'large': 0, 'x-large': 0,
+			'xx-large': 0
+		};
+
+		if(dojo.isIE){
+			//	we do a font-size fix if and only if one isn't applied already.
+			//	NOTE: If someone set the fontSize on the HTML Element, this will kill it.
+			dojo.doc.documentElement.style.fontSize="100%";
+		}
+
+		//	set up the measuring node.
+		var div = dojo.doc.createElement("div");
+		var s = div.style;
+		s.position = "absolute";
+		s.left = "-100px";
+		s.top = "0px";
+		s.width = "30px";
+		s.height = "1000em";
+		s.border = "0px";
+		s.margin = "0px";
+		s.padding = "0px";
+		s.outline = "none";
+		s.lineHeight = "1";
+		s.overflow = "hidden";
+		dojo.body().appendChild(div);
+
+		//	do the measurements.
+		for(var p in heights){
+			div.style.fontSize = p;
+			heights[p] = Math.round(div.offsetHeight * 12/16) * 16/12 / 1000;
+		}
+
+		dojo.body().removeChild(div);
+		div = null;
+		return heights; 	//	object
+	};
+
+	var fontMeasurements = null;
+
+	b._getCachedFontMeasurements = function(recalculate){
+		if(recalculate || !fontMeasurements){
+			fontMeasurements = b._getFontMeasurements();
+		}
+		return fontMeasurements;
+	};
+
+	// candidate for dojox.html.metrics
+
+	var measuringNode = null, empty = {};
+	b._getTextBox = function(/* String */ text, /* Object */ style, /* String? */ className){
+		var m, s;
+		if(!measuringNode){
+			m = measuringNode = dojo.doc.createElement("div");
+			s = m.style;
+			s.position = "absolute";
+			s.left = "-10000px";
+			s.top = "0";
+			dojo.body().appendChild(m);
+		}else{
+			m = measuringNode;
+			s = m.style;
+		}
+		// reset styles
+		m.className = "";
+		s.border = "0";
+		s.margin = "0";
+		s.padding = "0";
+		s.outline = "0";
+		// set new style
+		if(arguments.length > 1 && style){
+			for(var i in style){
+				if(i in empty){ continue; }
+				s[i] = style[i];
+			}
+		}
+		// set classes
+		if(arguments.length > 2 && className){
+			m.className = className;
+		}
+		// take a measure
+		m.innerHTML = text;
+		return dojo.marginBox(m);
+	};
+
+	// candidate for dojo.dom
+
+	var uniqueId = 0;
+	b._getUniqueId = function(){
+		// summary: returns a unique string for use with any DOM element
+		var id;
+		do{
+			id = dojo._scopeName + "Unique" + (++uniqueId);
+		}while(dojo.byId(id));
+		return id;
+	};
+})();
+
+dojo.mixin(dojox.gfx, {
+	//	summary:
+	// 		defines constants, prototypes, and utility functions
+
+	// default shapes, which are used to fill in missing parameters
+	defaultPath: {
+		type: "path", path: ""
+	},
+	defaultPolyline: {
+		type: "polyline", points: []
+	},
+	defaultRect: {
+		type: "rect", x: 0, y: 0, width: 100, height: 100, r: 0
+	},
+	defaultEllipse: {
+		type: "ellipse", cx: 0, cy: 0, rx: 200, ry: 100
+	},
+	defaultCircle: {
+		type: "circle", cx: 0, cy: 0, r: 100
+	},
+	defaultLine: {
+		type: "line", x1: 0, y1: 0, x2: 100, y2: 100
+	},
+	defaultImage: {
+		type: "image", x: 0, y: 0, width: 0, height: 0, src: ""
+	},
+	defaultText: {
+		type: "text", x: 0, y: 0, text: "", align: "start",
+		decoration: "none", rotated: false, kerning: true
+	},
+	defaultTextPath: {
+		type: "textpath", text: "", align: "start",
+		decoration: "none", rotated: false, kerning: true
+	},
+
+	// default geometric attributes
+	defaultStroke: {
+		type: "stroke", color: "black", style: "solid", width: 1, 
+		cap: "butt", join: 4
+	},
+	defaultLinearGradient: {
+		type: "linear", x1: 0, y1: 0, x2: 100, y2: 100,
+		colors: [
+			{ offset: 0, color: "black" }, { offset: 1, color: "white" }
+		]
+	},
+	defaultRadialGradient: {
+		type: "radial", cx: 0, cy: 0, r: 100,
+		colors: [
+			{ offset: 0, color: "black" }, { offset: 1, color: "white" }
+		]
+	},
+	defaultPattern: {
+		type: "pattern", x: 0, y: 0, width: 0, height: 0, src: ""
+	},
+	defaultFont: {
+		type: "font", style: "normal", variant: "normal", 
+		weight: "normal", size: "10pt", family: "serif"
+	},
+
+	getDefault: (function(){
+		var typeCtorCache = {};
+		// a memoized delegate()
+		return function(/*String*/ type){
+			var t = typeCtorCache[type];
+			if(t){
+				return new t();
+			}
+			t = typeCtorCache[type] = function(){};
+			t.prototype = dojox.gfx[ "default" + type ];
+			return new t();
+		}
+	})(),
+
+	normalizeColor: function(/*Color*/ color){
+		//	summary:
+		// 		converts any legal color representation to normalized
+		// 		dojo.Color object
+		return (color instanceof dojo.Color) ? color : new dojo.Color(color); // dojo.Color
+	},
+	normalizeParameters: function(existed, update){
+		//	summary:
+		// 		updates an existing object with properties from an "update"
+		// 		object
+		//	existed: Object
+		//		the "target" object to be updated
+		//	update:  Object
+		//		the "update" object, whose properties will be used to update
+		//		the existed object
+		if(update){
+			var empty = {};
+			for(var x in existed){
+				if(x in update && !(x in empty)){
+					existed[x] = update[x];
+				}
+			}
+		}
+		return existed;	// Object
+	},
+	makeParameters: function(defaults, update){
+		//	summary:
+		// 		copies the original object, and all copied properties from the
+		// 		"update" object
+		//	defaults: Object
+		//		the object to be cloned before updating
+		//	update:   Object
+		//		the object, which properties are to be cloned during updating
+		if(!update){
+			// return dojo.clone(defaults);
+			return dojo.delegate(defaults);
+		}
+		var result = {};
+		for(var i in defaults){
+			if(!(i in result)){
+				result[i] = dojo.clone((i in update) ? update[i] : defaults[i]);
+			}
+		}
+		return result; // Object
+	},
+	formatNumber: function(x, addSpace){
+		// summary: converts a number to a string using a fixed notation
+		// x:			Number:		number to be converted
+		// addSpace:	Boolean?:	if it is true, add a space before a positive number
+		var val = x.toString();
+		if(val.indexOf("e") >= 0){
+			val = x.toFixed(4);
+		}else{
+			var point = val.indexOf(".");
+			if(point >= 0 && val.length - point > 5){
+				val = x.toFixed(4);
+			}
+		}
+		if(x < 0){
+			return val; // String
+		}
+		return addSpace ? " " + val : val; // String
+	},
+	// font operations
+	makeFontString: function(font){
+		// summary: converts a font object to a CSS font string
+		// font:	Object:	font object (see dojox.gfx.defaultFont)
+		return font.style + " " + font.variant + " " + font.weight + " " + font.size + " " + font.family; // Object
+	},
+	splitFontString: function(str){
+		// summary: converts a CSS font string to a font object
+		// str:		String:	a CSS font string
+		var font = dojox.gfx.getDefault("Font");
+		var t = str.split(/\s+/);
+		do{
+			if(t.length < 5){ break; }
+			font.style  = t[0];
+			font.varian = t[1];
+			font.weight = t[2];
+			var i = t[3].indexOf("/");
+			font.size = i < 0 ? t[3] : t[3].substring(0, i);
+			var j = 4;
+			if(i < 0){
+				if(t[4] == "/"){
+					j = 6;
+					break;
+				}
+				if(t[4].substr(0, 1) == "/"){
+					j = 5;
+					break;
+				}
+			}
+			if(j + 3 > t.length){ break; }
+			font.size = t[j];
+			font.family = t[j + 1];
+		}while(false);
+		return font;	// Object
+	},
+	// length operations
+	cm_in_pt: 72 / 2.54,	// Number: points per centimeter
+	mm_in_pt: 7.2 / 2.54,	// Number: points per millimeter
+	px_in_pt: function(){
+		// summary: returns a number of pixels per point
+		return dojox.gfx._base._getCachedFontMeasurements()["12pt"] / 12;	// Number
+	},
+	pt2px: function(len){
+		// summary: converts points to pixels
+		// len: Number: a value in points
+		return len * dojox.gfx.px_in_pt();	// Number
+	},
+	px2pt: function(len){
+		// summary: converts pixels to points
+		// len: Number: a value in pixels
+		return len / dojox.gfx.px_in_pt();	// Number
+	},
+	normalizedLength: function(len) {
+		// summary: converts any length value to pixels
+		// len: String: a length, e.g., "12pc"
+		if(len.length == 0) return 0;
+		if(len.length > 2){
+			var px_in_pt = dojox.gfx.px_in_pt();
+			var val = parseFloat(len);
+			switch(len.slice(-2)){
+				case "px": return val;
+				case "pt": return val * px_in_pt;
+				case "in": return val * 72 * px_in_pt;
+				case "pc": return val * 12 * px_in_pt;
+				case "mm": return val * dojox.gfx.mm_in_pt * px_in_pt;
+				case "cm": return val * dojox.gfx.cm_in_pt * px_in_pt;
+			}
+		}
+		return parseFloat(len);	// Number
+	},
+
+	// a constant used to split a SVG/VML path into primitive components
+	pathVmlRegExp: /([A-Za-z]+)|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g,
+	pathSvgRegExp: /([A-Za-z])|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g,
+
+	equalSources: function(a, b){
+		// summary: compares event sources, returns true if they are equal
+		return a && b && a == b;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.gfx"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx"] = true;
+dojo.provide("dojox.gfx");
+
+
+
+
+dojo.loadInit(function(){
+	//Since loaderInit can be fired before any dojo.provide/require calls,
+	//make sure the dojox.gfx object exists and only run this logic if dojox.gfx.renderer
+	//has not been defined yet.
+	var gfx = dojo.getObject("dojox.gfx", true), sl, flag, match;
+	if(!gfx.renderer){
+		var renderers = (typeof dojo.config.gfxRenderer == "string" ?
+			dojo.config.gfxRenderer : "svg,vml,silverlight,canvas").split(",");
+
+		// mobile platform detection
+		// TODO: move to the base?
+
+		var ua = navigator.userAgent, iPhoneOsBuild = 0, androidVersion = 0;
+		if(dojo.isSafari >= 3){
+			// detect mobile version of WebKit starting with "version 3"
+
+			//	comprehensive iPhone test.  Have to figure out whether it's SVG or Canvas based on the build.
+			//	iPhone OS build numbers from en.wikipedia.org.
+			if(ua.indexOf("iPhone") >= 0 || ua.indexOf("iPod") >= 0){
+				//	grab the build out of this.  Expression is a little nasty because we want
+				//		to be sure we have the whole version string.
+				match = ua.match(/Version\/(\d(\.\d)?(\.\d)?)\sMobile\/([^\s]*)\s?/);
+				if(match){
+					//	grab the build out of the match.  Only use the first three because of specific builds.
+					iPhoneOsBuild = parseInt(match[4].substr(0,3), 16);
+				}
+			}
+		}
+		if(dojo.isWebKit){
+			// Android detection
+			if(!iPhoneOsBuild){
+				match = ua.match(/Android\s+(\d+\.\d+)/);
+				if(match){
+					androidVersion = parseFloat(match[1]);
+					// Android 1.0-1.1 doesn't support SVG but supports Canvas
+				}
+			}
+		}
+
+		for(var i = 0; i < renderers.length; ++i){
+			switch(renderers[i]){
+				case "svg":
+					//	iPhone OS builds greater than 5F1 should have SVG.
+					if(!dojo.isIE && (!iPhoneOsBuild || iPhoneOsBuild >= 0x5f1) && !androidVersion && !dojo.isAIR){
+						dojox.gfx.renderer = "svg";
+					}
+					break;
+				case "vml":
+					if(dojo.isIE){
+						dojox.gfx.renderer = "vml";
+					}
+					break;
+				case "silverlight":
+					try{
+						if(dojo.isIE){
+							sl = new ActiveXObject("AgControl.AgControl");
+							if(sl && sl.IsVersionSupported("1.0")){
+								flag = true;
+							}
+						}else{
+							if(navigator.plugins["Silverlight Plug-In"]){
+								flag = true;
+							}
+						}
+					}catch(e){
+						flag = false;
+					}finally{
+						sl = null;
+					}
+					if(flag){ dojox.gfx.renderer = "silverlight"; }
+					break;
+				case "canvas":
+					//TODO: need more comprehensive test for Canvas
+					if(!dojo.isIE){
+						dojox.gfx.renderer = "canvas";
+					}
+					break;
+			}
+			if(dojox.gfx.renderer){ break; }
+		}
+		if(dojo.config.isDebug){
+			
+		}
+	}
+});
+
+// include a renderer conditionally
+dojo.requireIf(dojox.gfx.renderer == "svg", "dojox.gfx.svg");
+dojo.requireIf(dojox.gfx.renderer == "vml", "dojox.gfx.vml");
+dojo.requireIf(dojox.gfx.renderer == "silverlight", "dojox.gfx.silverlight");
+dojo.requireIf(dojox.gfx.renderer == "canvas", "dojox.gfx.canvas");
+
+}
+
+if(!dojo._hasResource["dojox.lang.functional.lambda"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.lang.functional.lambda"] = true;
+dojo.provide("dojox.lang.functional.lambda");
+
+// This module adds high-level functions and related constructs:
+//	- anonymous functions built from the string
+
+// Acknoledgements:
+//	- lambda() is based on work by Oliver Steele 
+//		(http://osteele.com/sources/javascript/functional/functional.js)
+//		which was published under MIT License
+
+// Notes:
+//	- lambda() produces functions, which after the compilation step are 
+//		as fast as regular JS functions (at least theoretically).
+
+// Lambda input values:
+//	- returns functions unchanged
+//	- converts strings to functions
+//	- converts arrays to a functional composition
+
+(function(){
+	var df = dojox.lang.functional, lcache = {};
+
+	// split() is augmented on IE6 to ensure the uniform behavior
+	var split = "ab".split(/a*/).length > 1 ? String.prototype.split :
+			function(sep){
+				 var r = this.split.call(this, sep),
+					 m = sep.exec(this);
+				 if(m && m.index == 0){ r.unshift(""); }
+				 return r;
+			};
+			
+	var lambda = function(/*String*/ s){
+		var args = [], sects = split.call(s, /\s*->\s*/m);
+		if(sects.length > 1){
+			while(sects.length){
+				s = sects.pop();
+				args = sects.pop().split(/\s*,\s*|\s+/m);
+				if(sects.length){ sects.push("(function(" + args + "){return (" + s + ")})"); }
+			}
+		}else if(s.match(/\b_\b/)){
+			args = ["_"];
+		}else{
+			var l = s.match(/^\s*(?:[+*\/%&|\^\.=<>]|!=)/m),
+				r = s.match(/[+\-*\/%&|\^\.=<>!]\s*$/m);
+			if(l || r){
+				if(l){
+					args.push("$1");
+					s = "$1" + s;
+				}
+				if(r){
+					args.push("$2");
+					s = s + "$2";
+				}
+			}else{
+				// the point of the long regex below is to exclude all well-known 
+				// lower-case words from the list of potential arguments
+				var vars = s.
+					replace(/(?:\b[A-Z]|\.[a-zA-Z_$])[a-zA-Z_$\d]*|[a-zA-Z_$][a-zA-Z_$\d]*:|this|true|false|null|undefined|typeof|instanceof|in|delete|new|void|arguments|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|escape|eval|isFinite|isNaN|parseFloat|parseInt|unescape|dojo|dijit|dojox|window|document|'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"/g, "").
+					match(/([a-z_$][a-z_$\d]*)/gi) || [], t = {};
+				dojo.forEach(vars, function(v){
+					if(!(v in t)){
+						args.push(v);
+						t[v] = 1;
+					}
+				});
+			}
+		}
+		return {args: args, body: s};	// Object
+	};
+
+	var compose = function(/*Array*/ a){
+		return a.length ? 
+					function(){
+						var i = a.length - 1, x = df.lambda(a[i]).apply(this, arguments);
+						for(--i; i >= 0; --i){ x = df.lambda(a[i]).call(this, x); }
+						return x;
+					}
+				: 
+					// identity
+					function(x){ return x; };
+	};
+
+	dojo.mixin(df, {
+		// lambda
+		rawLambda: function(/*String*/ s){
+			// summary:
+			//		builds a function from a snippet, or array (composing),
+			//		returns an object describing the function; functions are
+			//		passed through unmodified.
+			// description:
+			//		This method is to normalize a functional representation (a
+			//		text snippet) to an object that contains an array of
+			//		arguments, and a body , which is used to calculate the
+			//		returning value.
+			return lambda(s);	// Object
+		},
+		buildLambda: function(/*String*/ s){
+			// summary:
+			//		builds a function from a snippet, returns a string, which
+			//		represents the function.
+			// description:
+			//		This method returns a textual representation of a function
+			//		built from the snippet. It is meant to be evaled in the
+			//		proper context, so local variables can be pulled from the
+			//		environment.
+			s = lambda(s);
+			return "function(" + s.args.join(",") + "){return (" + s.body + ");}";	// String
+		},
+		lambda: function(/*Function|String|Array*/ s){
+			// summary:
+			//		builds a function from a snippet, or array (composing),
+			//		returns a function object; functions are passed through
+			//		unmodified.
+			// description:
+			//		This method is used to normalize a functional
+			//		representation (a text snippet, an array, or a function) to
+			//		a function object.
+			if(typeof s == "function"){ return s; }
+			if(s instanceof Array){ return compose(s); }
+			if(s in lcache){ return lcache[s]; }
+			s = lambda(s);
+			return lcache[s] = new Function(s.args, "return (" + s.body + ");");	// Function
+		},
+		clearLambdaCache: function(){
+			// summary:
+			//		clears internal cache of lambdas
+			lcache = {};
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.lang.functional.array"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.lang.functional.array"] = true;
+dojo.provide("dojox.lang.functional.array");
+
+
+
+// This module adds high-level functions and related constructs:
+//	- array-processing functions similar to standard JS functions
+
+// Notes:
+//	- this module provides JS standard methods similar to high-level functions in dojo/_base/array.js: 
+//		forEach, map, filter, every, some
+
+// Defined methods:
+//	- take any valid lambda argument as the functional argument
+//	- operate on dense arrays
+//	- take a string as the array argument
+//	- take an iterator objects as the array argument
+
+(function(){
+	var d = dojo, df = dojox.lang.functional, empty = {};
+
+	d.mixin(df, {
+		// JS 1.6 standard array functions, which can take a lambda as a parameter.
+		// Consider using dojo._base.array functions, if you don't need the lambda support.
+		filter: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
+			// summary: creates a new array with all elements that pass the test 
+			//	implemented by the provided function.
+			if(typeof a == "string"){ a = a.split(""); }
+			o = o || d.global; f = df.lambda(f);
+			var t = [], v, i, n;
+			if(d.isArray(a)){
+				// array
+				for(i = 0, n = a.length; i < n; ++i){
+					v = a[i];
+					if(f.call(o, v, i, a)){ t.push(v); }
+				}
+			}else if(typeof a.hasNext == "function" && typeof a.next == "function"){
+				// iterator
+				for(i = 0; a.hasNext();){
+					v = a.next();
+					if(f.call(o, v, i++, a)){ t.push(v); }
+				}
+			}else{
+				// object/dictionary
+				for(i in a){
+					if(!(i in empty)){
+						v = a[i];
+						if(f.call(o, v, i, a)){ t.push(v); }
+					}
+				}
+			}
+			return t;	// Array
+		},
+		forEach: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
+			// summary: executes a provided function once per array element.
+			if(typeof a == "string"){ a = a.split(""); }
+			o = o || d.global; f = df.lambda(f);
+			var i, n;
+			if(d.isArray(a)){
+				// array
+				for(i = 0, n = a.length; i < n; f.call(o, a[i], i, a), ++i);
+			}else if(typeof a.hasNext == "function" && typeof a.next == "function"){
+				// iterator
+				for(i = 0; a.hasNext(); f.call(o, a.next(), i++, a));
+			}else{
+				// object/dictionary
+				for(i in a){
+					if(!(i in empty)){
+						f.call(o, a[i], i, a);
+					}
+				}
+			}
+			return o;	// Object
+		},
+		map: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
+			// summary: creates a new array with the results of calling 
+			//	a provided function on every element in this array.
+			if(typeof a == "string"){ a = a.split(""); }
+			o = o || d.global; f = df.lambda(f);
+			var t, n, i;
+			if(d.isArray(a)){
+				// array
+				t = new Array(n = a.length);
+				for(i = 0; i < n; t[i] = f.call(o, a[i], i, a), ++i);
+			}else if(typeof a.hasNext == "function" && typeof a.next == "function"){
+				// iterator
+				t = [];
+				for(i = 0; a.hasNext(); t.push(f.call(o, a.next(), i++, a)));
+			}else{
+				// object/dictionary
+				t = [];
+				for(i in a){
+					if(!(i in empty)){
+						t.push(f.call(o, a[i], i, a));
+					}
+				}
+			}
+			return t;	// Array
+		},
+		every: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
+			// summary: tests whether all elements in the array pass the test 
+			//	implemented by the provided function.
+			if(typeof a == "string"){ a = a.split(""); }
+			o = o || d.global; f = df.lambda(f);
+			var i, n;
+			if(d.isArray(a)){
+				// array
+				for(i = 0, n = a.length; i < n; ++i){
+					if(!f.call(o, a[i], i, a)){
+						return false;	// Boolean
+					}
+				}
+			}else if(typeof a.hasNext == "function" && typeof a.next == "function"){
+				// iterator
+				for(i = 0; a.hasNext();){
+					if(!f.call(o, a.next(), i++, a)){
+						return false;	// Boolean
+					}
+				}
+			}else{
+				// object/dictionary
+				for(i in a){
+					if(!(i in empty)){
+						if(!f.call(o, a[i], i, a)){
+							return false;	// Boolean
+						}
+					}
+				}
+			}
+			return true;	// Boolean
+		},
+		some: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
+			// summary: tests whether some element in the array passes the test 
+			//	implemented by the provided function.
+			if(typeof a == "string"){ a = a.split(""); }
+			o = o || d.global; f = df.lambda(f);
+			var i, n;
+			if(d.isArray(a)){
+				// array
+				for(i = 0, n = a.length; i < n; ++i){
+					if(f.call(o, a[i], i, a)){
+						return true;	// Boolean
+					}
+				}
+			}else if(typeof a.hasNext == "function" && typeof a.next == "function"){
+				// iterator
+				for(i = 0; a.hasNext();){
+					if(f.call(o, a.next(), i++, a)){
+						return true;	// Boolean
+					}
+				}
+			}else{
+				// object/dictionary
+				for(i in a){
+					if(!(i in empty)){
+						if(f.call(o, a[i], i, a)){
+							return true;	// Boolean
+						}
+					}
+				}
+			}
+			return false;	// Boolean
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.lang.functional.object"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.lang.functional.object"] = true;
+dojo.provide("dojox.lang.functional.object");
+
+
+
+// This module adds high-level functions and related constructs:
+//	- object/dictionary helpers
+
+// Defined methods:
+//	- take any valid lambda argument as the functional argument
+//	- skip all attributes that are present in the empty object 
+//		(IE and/or 3rd-party libraries).
+
+(function(){
+	var d = dojo, df = dojox.lang.functional, empty = {};
+
+	d.mixin(df, {
+		// object helpers
+		keys: function(/*Object*/ obj){
+			// summary: returns an array of all keys in the object
+			var t = [];
+			for(var i in obj){
+				if(!(i in empty)){
+					t.push(i);
+				}
+			}
+			return	t; // Array
+		},
+		values: function(/*Object*/ obj){
+			// summary: returns an array of all values in the object
+			var t = [];
+			for(var i in obj){
+				if(!(i in empty)){
+					t.push(obj[i]);
+				}
+			}
+			return	t; // Array
+		},
+		filterIn: function(/*Object*/ obj, /*Function|String|Array*/ f, /*Object?*/ o){
+			// summary: creates new object with all attributes that pass the test 
+			//	implemented by the provided function.
+			o = o || d.global; f = df.lambda(f);
+			var t = {}, v, i;
+			for(i in obj){
+				if(!(i in empty)){
+					v = obj[i];
+					if(f.call(o, v, i, obj)){ t[i] = v; }
+				}
+			}
+			return t;	// Object
+		},
+		forIn: function(/*Object*/ obj, /*Function|String|Array*/ f, /*Object?*/ o){
+			// summary: iterates over all object attributes.
+			o = o || d.global; f = df.lambda(f);
+			for(var i in obj){
+				if(!(i in empty)){
+					f.call(o, obj[i], i, obj);
+				}
+			}
+			return o;	// Object
+		},
+		mapIn: function(/*Object*/ obj, /*Function|String|Array*/ f, /*Object?*/ o){
+			// summary: creates new object with the results of calling 
+			//	a provided function on every attribute in this object.
+			o = o || d.global; f = df.lambda(f);
+			var t = {}, i;
+			for(i in obj){
+				if(!(i in empty)){
+					t[i] = f.call(o, obj[i], i, obj);
+				}
+			}
+			return t;	// Object
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.lang.functional"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.lang.functional"] = true;
+dojo.provide("dojox.lang.functional");
+
+
+
+
+
+}
+
+if(!dojo._hasResource["dojox.lang.functional.fold"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.lang.functional.fold"] = true;
+dojo.provide("dojox.lang.functional.fold");
+
+
+
+// This module adds high-level functions and related constructs:
+//	- "fold" family of functions
+
+// Notes:
+//	- missing high-level functions are provided with the compatible API: 
+//		foldl, foldl1, foldr, foldr1
+//	- missing JS standard functions are provided with the compatible API: 
+//		reduce, reduceRight
+//	- the fold's counterpart: unfold
+
+// Defined methods:
+//	- take any valid lambda argument as the functional argument
+//	- operate on dense arrays
+//	- take a string as the array argument
+//	- take an iterator objects as the array argument (only foldl, foldl1, and reduce)
+
+(function(){
+	var d = dojo, df = dojox.lang.functional, empty = {};
+
+	d.mixin(df, {
+		// classic reduce-class functions
+		foldl: function(/*Array|String|Object*/ a, /*Function*/ f, /*Object*/ z, /*Object?*/ o){
+			// summary: repeatedly applies a binary function to an array from left
+			//	to right using a seed value as a starting point; returns the final
+			//	value.
+			if(typeof a == "string"){ a = a.split(""); }
+			o = o || d.global; f = df.lambda(f);
+			var i, n;
+			if(d.isArray(a)){
+				// array
+				for(i = 0, n = a.length; i < n; z = f.call(o, z, a[i], i, a), ++i);
+			}else if(typeof a.hasNext == "function" && typeof a.next == "function"){
+				// iterator
+				for(i = 0; a.hasNext(); z = f.call(o, z, a.next(), i++, a));
+			}else{
+				// object/dictionary
+				for(i in a){
+					if(!(i in empty)){
+						z = f.call(o, z, a[i], i, a);
+					}
+				}
+			}
+			return z;	// Object
+		},
+		foldl1: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
+			// summary: repeatedly applies a binary function to an array from left
+			//	to right; returns the final value.
+			if(typeof a == "string"){ a = a.split(""); }
+			o = o || d.global; f = df.lambda(f);
+			var z, i, n;
+			if(d.isArray(a)){
+				// array
+				z = a[0];
+				for(i = 1, n = a.length; i < n; z = f.call(o, z, a[i], i, a), ++i);
+			}else if(typeof a.hasNext == "function" && typeof a.next == "function"){
+				// iterator
+				if(a.hasNext()){
+					z = a.next();
+					for(i = 1; a.hasNext(); z = f.call(o, z, a.next(), i++, a));
+				}
+			}else{
+				// object/dictionary
+				var first = true;
+				for(i in a){
+					if(!(i in empty)){
+						if(first){
+							z = a[i];
+							first = false;
+						}else{
+							z = f.call(o, z, a[i], i, a);
+						}
+					}
+				}
+			}
+			return z;	// Object
+		},
+		foldr: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object*/ z, /*Object?*/ o){
+			// summary: repeatedly applies a binary function to an array from right
+			//	to left using a seed value as a starting point; returns the final 
+			//	value.
+			if(typeof a == "string"){ a = a.split(""); }
+			o = o || d.global; f = df.lambda(f);
+			for(var i = a.length; i > 0; --i, z = f.call(o, z, a[i], i, a));
+			return z;	// Object
+		},
+		foldr1: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
+			// summary: repeatedly applies a binary function to an array from right
+			//	to left; returns the final value.
+			if(typeof a == "string"){ a = a.split(""); }
+			o = o || d.global; f = df.lambda(f);
+			var n = a.length, z = a[n - 1], i = n - 1;
+			for(; i > 0; --i, z = f.call(o, z, a[i], i, a));
+			return z;	// Object
+		},
+		// JS 1.8 standard array functions, which can take a lambda as a parameter.
+		reduce: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ z){
+			// summary: apply a function simultaneously against two values of the array
+			//	(from left-to-right) as to reduce it to a single value.
+			return arguments.length < 3 ? df.foldl1(a, f) : df.foldl(a, f, z);	// Object
+		},
+		reduceRight: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ z){
+			// summary: apply a function simultaneously against two values of the array
+			//	(from right-to-left) as to reduce it to a single value.
+			return arguments.length < 3 ? df.foldr1(a, f) : df.foldr(a, f, z);	// Object
+		},
+		// the fold's counterpart: unfold
+		unfold: function(/*Function|String|Array*/ pr, /*Function|String|Array*/ f,
+						/*Function|String|Array*/ g, /*Object*/ z, /*Object?*/ o){
+			// summary: builds an array by unfolding a value
+			o = o || d.global; f = df.lambda(f); g = df.lambda(g); pr = df.lambda(pr);
+			var t = [];
+			for(; !pr.call(o, z); t.push(f.call(o, z)), z = g.call(o, z));
+			return t;	// Array
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.lang.functional.reversed"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.lang.functional.reversed"] = true;
+dojo.provide("dojox.lang.functional.reversed");
+
+
+
+// This module adds high-level functions and related constructs:
+//	- reversed versions of array-processing functions similar to standard JS functions
+
+// Notes:
+//	- this module provides reversed versions of standard array-processing functions: 
+//		forEachRev, mapRev, filterRev
+
+// Defined methods:
+//	- take any valid lambda argument as the functional argument
+//	- operate on dense arrays
+//	- take a string as the array argument
+
+(function(){
+	var d = dojo, df = dojox.lang.functional;
+
+	d.mixin(df, {
+		// JS 1.6 standard array functions, which can take a lambda as a parameter.
+		// Consider using dojo._base.array functions, if you don't need the lambda support.
+		filterRev: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
+			// summary: creates a new array with all elements that pass the test 
+			//	implemented by the provided function.
+			if(typeof a == "string"){ a = a.split(""); }
+			o = o || d.global; f = df.lambda(f);
+			var t = [], v, i = a.length - 1;
+			for(; i >= 0; --i){
+				v = a[i];
+				if(f.call(o, v, i, a)){ t.push(v); }
+			}
+			return t;	// Array
+		},
+		forEachRev: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
+			// summary: executes a provided function once per array element.
+			if(typeof a == "string"){ a = a.split(""); }
+			o = o || d.global; f = df.lambda(f);
+			for(var i = a.length - 1; i >= 0; f.call(o, a[i], i, a), --i);
+		},
+		mapRev: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
+			// summary: creates a new array with the results of calling 
+			//	a provided function on every element in this array.
+			if(typeof a == "string"){ a = a.split(""); }
+			o = o || d.global; f = df.lambda(f);
+			var n = a.length, t = new Array(n), i = n - 1, j = 0;
+			for(; i >= 0; t[j++] = f.call(o, a[i], i, a), --i);
+			return t;	// Array
+		},
+		everyRev: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
+			// summary: tests whether all elements in the array pass the test 
+			//	implemented by the provided function.
+			if(typeof a == "string"){ a = a.split(""); }
+			o = o || d.global; f = df.lambda(f);
+			for(var i = a.length - 1; i >= 0; --i){
+				if(!f.call(o, a[i], i, a)){
+					return false;	// Boolean
+				}
+			}
+			return true;	// Boolean
+		},
+		someRev: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
+			// summary: tests whether some element in the array passes the test 
+			//	implemented by the provided function.
+			if(typeof a == "string"){ a = a.split(""); }
+			o = o || d.global; f = df.lambda(f);
+			for(var i = a.length - 1; i >= 0; --i){
+				if(f.call(o, a[i], i, a)){
+					return true;	// Boolean
+				}
+			}
+			return false;	// Boolean
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojo.colors"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.colors"] = true;
+dojo.provide("dojo.colors");
+
+//TODO: this module appears to break naming conventions
+
+/*=====
+dojo.colors = {
+	// summary: Color utilities
+}
+=====*/
+
+(function(){
+	// this is a standard conversion prescribed by the CSS3 Color Module
+	var hue2rgb = function(m1, m2, h){
+		if(h < 0){ ++h; }
+		if(h > 1){ --h; }
+		var h6 = 6 * h;
+		if(h6 < 1){ return m1 + (m2 - m1) * h6; }
+		if(2 * h < 1){ return m2; }
+		if(3 * h < 2){ return m1 + (m2 - m1) * (2 / 3 - h) * 6; }
+		return m1;
+	};
+	
+	dojo.colorFromRgb = function(/*String*/ color, /*dojo.Color?*/ obj){
+		// summary:
+		//		get rgb(a) array from css-style color declarations
+		// description:
+		//		this function can handle all 4 CSS3 Color Module formats: rgb,
+		//		rgba, hsl, hsla, including rgb(a) with percentage values.
+		var m = color.toLowerCase().match(/^(rgba?|hsla?)\(([\s\.\-,%0-9]+)\)/);
+		if(m){
+			var c = m[2].split(/\s*,\s*/), l = c.length, t = m[1], a;
+			if((t == "rgb" && l == 3) || (t == "rgba" && l == 4)){
+				var r = c[0];
+				if(r.charAt(r.length - 1) == "%"){
+					// 3 rgb percentage values
+					a = dojo.map(c, function(x){
+						return parseFloat(x) * 2.56;
+					});
+					if(l == 4){ a[3] = c[3]; }
+					return dojo.colorFromArray(a, obj);	// dojo.Color
+				}
+				return dojo.colorFromArray(c, obj);	// dojo.Color
+			}
+			if((t == "hsl" && l == 3) || (t == "hsla" && l == 4)){
+				// normalize hsl values
+				var H = ((parseFloat(c[0]) % 360) + 360) % 360 / 360,
+					S = parseFloat(c[1]) / 100,
+					L = parseFloat(c[2]) / 100,
+					// calculate rgb according to the algorithm 
+					// recommended by the CSS3 Color Module 
+					m2 = L <= 0.5 ? L * (S + 1) : L + S - L * S, 
+					m1 = 2 * L - m2;
+				a = [
+					hue2rgb(m1, m2, H + 1 / 3) * 256,
+					hue2rgb(m1, m2, H) * 256,
+					hue2rgb(m1, m2, H - 1 / 3) * 256,
+					1
+				];
+				if(l == 4){ a[3] = c[3]; }
+				return dojo.colorFromArray(a, obj);	// dojo.Color
+			}
+		}
+		return null;	// dojo.Color
+	};
+	
+	var confine = function(c, low, high){
+		// summary:
+		//		sanitize a color component by making sure it is a number,
+		//		and clamping it to valid values
+		c = Number(c);
+		return isNaN(c) ? high : c < low ? low : c > high ? high : c;	// Number
+	};
+	
+	dojo.Color.prototype.sanitize = function(){
+		// summary: makes sure that the object has correct attributes
+		var t = this;
+		t.r = Math.round(confine(t.r, 0, 255));
+		t.g = Math.round(confine(t.g, 0, 255));
+		t.b = Math.round(confine(t.b, 0, 255));
+		t.a = confine(t.a, 0, 1);
+		return this;	// dojo.Color
+	};
+})();
+
+
+dojo.colors.makeGrey = function(/*Number*/ g, /*Number?*/ a){
+	// summary: creates a greyscale color with an optional alpha
+	return dojo.colorFromArray([g, g, g, a]);
+};
+
+// mixin all CSS3 named colors not already in _base, along with SVG 1.0 variant spellings
+dojo.mixin(dojo.Color.named, {
+	aliceblue:	[240,248,255],
+	antiquewhite:	[250,235,215],
+	aquamarine:	[127,255,212],
+	azure:	[240,255,255],
+	beige:	[245,245,220],
+	bisque:	[255,228,196],
+	blanchedalmond:	[255,235,205],
+	blueviolet:	[138,43,226],
+	brown:	[165,42,42],
+	burlywood:	[222,184,135],
+	cadetblue:	[95,158,160],
+	chartreuse:	[127,255,0],
+	chocolate:	[210,105,30],
+	coral:	[255,127,80],
+	cornflowerblue:	[100,149,237],
+	cornsilk:	[255,248,220],
+	crimson:	[220,20,60],
+	cyan:	[0,255,255],
+	darkblue:	[0,0,139],
+	darkcyan:	[0,139,139],
+	darkgoldenrod:	[184,134,11],
+	darkgray:	[169,169,169],
+	darkgreen:	[0,100,0],
+	darkgrey:	[169,169,169],
+	darkkhaki:	[189,183,107],
+	darkmagenta:	[139,0,139],
+	darkolivegreen:	[85,107,47],
+	darkorange:	[255,140,0],
+	darkorchid:	[153,50,204],
+	darkred:	[139,0,0],
+	darksalmon:	[233,150,122],
+	darkseagreen:	[143,188,143],
+	darkslateblue:	[72,61,139],
+	darkslategray:	[47,79,79],
+	darkslategrey:	[47,79,79],
+	darkturquoise:	[0,206,209],
+	darkviolet:	[148,0,211],
+	deeppink:	[255,20,147],
+	deepskyblue:	[0,191,255],
+	dimgray:	[105,105,105],
+	dimgrey:	[105,105,105],
+	dodgerblue:	[30,144,255],
+	firebrick:	[178,34,34],
+	floralwhite:	[255,250,240],
+	forestgreen:	[34,139,34],
+	gainsboro:	[220,220,220],
+	ghostwhite:	[248,248,255],
+	gold:	[255,215,0],
+	goldenrod:	[218,165,32],
+	greenyellow:	[173,255,47],
+	grey:	[128,128,128],
+	honeydew:	[240,255,240],
+	hotpink:	[255,105,180],
+	indianred:	[205,92,92],
+	indigo:	[75,0,130],
+	ivory:	[255,255,240],
+	khaki:	[240,230,140],
+	lavender:	[230,230,250],
+	lavenderblush:	[255,240,245],
+	lawngreen:	[124,252,0],
+	lemonchiffon:	[255,250,205],
+	lightblue:	[173,216,230],
+	lightcoral:	[240,128,128],
+	lightcyan:	[224,255,255],
+	lightgoldenrodyellow:	[250,250,210],
+	lightgray:	[211,211,211],
+	lightgreen:	[144,238,144],
+	lightgrey:	[211,211,211],
+	lightpink:	[255,182,193],
+	lightsalmon:	[255,160,122],
+	lightseagreen:	[32,178,170],
+	lightskyblue:	[135,206,250],
+	lightslategray:	[119,136,153],
+	lightslategrey:	[119,136,153],
+	lightsteelblue:	[176,196,222],
+	lightyellow:	[255,255,224],
+	limegreen:	[50,205,50],
+	linen:	[250,240,230],
+	magenta:	[255,0,255],
+	mediumaquamarine:	[102,205,170],
+	mediumblue:	[0,0,205],
+	mediumorchid:	[186,85,211],
+	mediumpurple:	[147,112,219],
+	mediumseagreen:	[60,179,113],
+	mediumslateblue:	[123,104,238],
+	mediumspringgreen:	[0,250,154],
+	mediumturquoise:	[72,209,204],
+	mediumvioletred:	[199,21,133],
+	midnightblue:	[25,25,112],
+	mintcream:	[245,255,250],
+	mistyrose:	[255,228,225],
+	moccasin:	[255,228,181],
+	navajowhite:	[255,222,173],
+	oldlace:	[253,245,230],
+	olivedrab:	[107,142,35],
+	orange:	[255,165,0],
+	orangered:	[255,69,0],
+	orchid:	[218,112,214],
+	palegoldenrod:	[238,232,170],
+	palegreen:	[152,251,152],
+	paleturquoise:	[175,238,238],
+	palevioletred:	[219,112,147],
+	papayawhip:	[255,239,213],
+	peachpuff:	[255,218,185],
+	peru:	[205,133,63],
+	pink:	[255,192,203],
+	plum:	[221,160,221],
+	powderblue:	[176,224,230],
+	rosybrown:	[188,143,143],
+	royalblue:	[65,105,225],
+	saddlebrown:	[139,69,19],
+	salmon:	[250,128,114],
+	sandybrown:	[244,164,96],
+	seagreen:	[46,139,87],
+	seashell:	[255,245,238],
+	sienna:	[160,82,45],
+	skyblue:	[135,206,235],
+	slateblue:	[106,90,205],
+	slategray:	[112,128,144],
+	slategrey:	[112,128,144],
+	snow:	[255,250,250],
+	springgreen:	[0,255,127],
+	steelblue:	[70,130,180],
+	tan:	[210,180,140],
+	thistle:	[216,191,216],
+	tomato:	[255,99,71],
+	transparent: [0, 0, 0, 0],
+	turquoise:	[64,224,208],
+	violet:	[238,130,238],
+	wheat:	[245,222,179],
+	whitesmoke:	[245,245,245],
+	yellowgreen:	[154,205,50]
+});
+
+}
+
+if(!dojo._hasResource["dojox.color._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.color._base"] = true;
+dojo.provide("dojox.color._base");
+
+
+//	alias all the dojo.Color mechanisms
+dojox.color.Color=dojo.Color;
+dojox.color.blend=dojo.blendColors;
+dojox.color.fromRgb=dojo.colorFromRgb;
+dojox.color.fromHex=dojo.colorFromHex;
+dojox.color.fromArray=dojo.colorFromArray;
+dojox.color.fromString=dojo.colorFromString;
+
+//	alias the dojo.colors mechanisms
+dojox.color.greyscale=dojo.colors.makeGrey;
+
+//	static methods
+dojo.mixin(dojox.color, {
+	fromCmy: function(/* Object|Array|int */cyan, /*int*/magenta, /*int*/yellow){
+		//	summary
+		//	Create a dojox.color.Color from a CMY defined color.
+		//	All colors should be expressed as 0-100 (percentage)
+
+		if(dojo.isArray(cyan)){
+			magenta=cyan[1], yellow=cyan[2], cyan=cyan[0];
+		} else if(dojo.isObject(cyan)){
+			magenta=cyan.m, yellow=cyan.y, cyan=cyan.c;
+		}
+		cyan/=100, magenta/=100, yellow/=100;
+
+		var r=1-cyan, g=1-magenta, b=1-yellow;
+		return new dojox.color.Color({ r:Math.round(r*255), g:Math.round(g*255), b:Math.round(b*255) });	//	dojox.color.Color
+	},
+
+	fromCmyk: function(/* Object|Array|int */cyan, /*int*/magenta, /*int*/yellow, /*int*/black){
+		//	summary
+		//	Create a dojox.color.Color from a CMYK defined color.
+		//	All colors should be expressed as 0-100 (percentage)
+
+		if(dojo.isArray(cyan)){
+			magenta=cyan[1], yellow=cyan[2], black=cyan[3], cyan=cyan[0];
+		} else if(dojo.isObject(cyan)){
+			magenta=cyan.m, yellow=cyan.y, black=cyan.b, cyan=cyan.c;
+		}
+		cyan/=100, magenta/=100, yellow/=100, black/=100;
+		var r,g,b;
+		r = 1-Math.min(1, cyan*(1-black)+black);
+		g = 1-Math.min(1, magenta*(1-black)+black);
+		b = 1-Math.min(1, yellow*(1-black)+black);
+		return new dojox.color.Color({ r:Math.round(r*255), g:Math.round(g*255), b:Math.round(b*255) });	//	dojox.color.Color
+	},
+	
+	fromHsl: function(/* Object|Array|int */hue, /* int */saturation, /* int */luminosity){
+		//	summary
+		//	Create a dojox.color.Color from an HSL defined color.
+		//	hue from 0-359 (degrees), saturation and luminosity 0-100.
+
+		if(dojo.isArray(hue)){
+			saturation=hue[1], luminosity=hue[2], hue=hue[0];
+		} else if(dojo.isObject(hue)){
+			saturation=hue.s, luminosity=hue.l, hue=hue.h;
+		}
+		saturation/=100;
+		luminosity/=100;
+
+		while(hue<0){ hue+=360; }
+		while(hue>=360){ hue-=360; }
+		
+		var r, g, b;
+		if(hue<120){
+			r=(120-hue)/60, g=hue/60, b=0;
+		} else if (hue<240){
+			r=0, g=(240-hue)/60, b=(hue-120)/60;
+		} else {
+			r=(hue-240)/60, g=0, b=(360-hue)/60;
+		}
+		
+		r=2*saturation*Math.min(r, 1)+(1-saturation);
+		g=2*saturation*Math.min(g, 1)+(1-saturation);
+		b=2*saturation*Math.min(b, 1)+(1-saturation);
+		if(luminosity<0.5){
+			r*=luminosity, g*=luminosity, b*=luminosity;
+		}else{
+			r=(1-luminosity)*r+2*luminosity-1;
+			g=(1-luminosity)*g+2*luminosity-1;
+			b=(1-luminosity)*b+2*luminosity-1;
+		}
+		return new dojox.color.Color({ r:Math.round(r*255), g:Math.round(g*255), b:Math.round(b*255) });	//	dojox.color.Color
+	},
+	
+	fromHsv: function(/* Object|Array|int */hue, /* int */saturation, /* int */value){
+		//	summary
+		//	Create a dojox.color.Color from an HSV defined color.
+		//	hue from 0-359 (degrees), saturation and value 0-100.
+
+		if(dojo.isArray(hue)){
+			saturation=hue[1], value=hue[2], hue=hue[0];
+		} else if (dojo.isObject(hue)){
+			saturation=hue.s, value=hue.v, hue=hue.h;
+		}
+		
+		if(hue==360){ hue=0; }
+		saturation/=100;
+		value/=100;
+		
+		var r, g, b;
+		if(saturation==0){
+			r=value, b=value, g=value;
+		}else{
+			var hTemp=hue/60, i=Math.floor(hTemp), f=hTemp-i;
+			var p=value*(1-saturation);
+			var q=value*(1-(saturation*f));
+			var t=value*(1-(saturation*(1-f)));
+			switch(i){
+				case 0:{ r=value, g=t, b=p; break; }
+				case 1:{ r=q, g=value, b=p; break; }
+				case 2:{ r=p, g=value, b=t; break; }
+				case 3:{ r=p, g=q, b=value; break; }
+				case 4:{ r=t, g=p, b=value; break; }
+				case 5:{ r=value, g=p, b=q; break; }
+			}
+		}
+		return new dojox.color.Color({ r:Math.round(r*255), g:Math.round(g*255), b:Math.round(b*255) });	//	dojox.color.Color
+	}
+});
+
+//	Conversions directly on dojox.color.Color
+dojo.extend(dojox.color.Color, {
+	toCmy: function(){
+		//	summary
+		//	Convert this Color to a CMY definition.
+		var cyan=1-(this.r/255), magenta=1-(this.g/255), yellow=1-(this.b/255);
+		return { c:Math.round(cyan*100), m:Math.round(magenta*100), y:Math.round(yellow*100) };		//	Object
+	},
+	
+	toCmyk: function(){
+		//	summary
+		//	Convert this Color to a CMYK definition.
+		var cyan, magenta, yellow, black;
+		var r=this.r/255, g=this.g/255, b=this.b/255;
+		black = Math.min(1-r, 1-g, 1-b);
+		cyan = (1-r-black)/(1-black);
+		magenta = (1-g-black)/(1-black);
+		yellow = (1-b-black)/(1-black);
+		return { c:Math.round(cyan*100), m:Math.round(magenta*100), y:Math.round(yellow*100), b:Math.round(black*100) };	//	Object
+	},
+	
+	toHsl: function(){
+		//	summary
+		//	Convert this Color to an HSL definition.
+		var r=this.r/255, g=this.g/255, b=this.b/255;
+		var min = Math.min(r, b, g), max = Math.max(r, g, b);
+		var delta = max-min;
+		var h=0, s=0, l=(min+max)/2;
+		if(l>0 && l<1){
+			s = delta/((l<0.5)?(2*l):(2-2*l));
+		}
+		if(delta>0){
+			if(max==r && max!=g){
+				h+=(g-b)/delta;
+			}
+			if(max==g && max!=b){
+				h+=(2+(b-r)/delta);
+			}
+			if(max==b && max!=r){
+				h+=(4+(r-g)/delta);
+			}
+			h*=60;
+		}
+		return { h:h, s:Math.round(s*100), l:Math.round(l*100) };	//	Object
+	},
+
+	toHsv: function(){
+		//	summary
+		//	Convert this Color to an HSV definition.
+		var r=this.r/255, g=this.g/255, b=this.b/255;
+		var min = Math.min(r, b, g), max = Math.max(r, g, b);
+		var delta = max-min;
+		var h = null, s = (max==0)?0:(delta/max);
+		if(s==0){
+			h = 0;
+		}else{
+			if(r==max){
+				h = 60*(g-b)/delta;
+			}else if(g==max){
+				h = 120 + 60*(b-r)/delta;
+			}else{
+				h = 240 + 60*(r-g)/delta;
+			}
+
+			if(h<0){ h+=360; }
+		}
+		return { h:h, s:Math.round(s*100), v:Math.round(max*100) };	//	Object
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.color"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.color"] = true;
+dojo.provide("dojox.color");
+
+
+}
+
+if(!dojo._hasResource["dojox.color.Palette"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.color.Palette"] = true;
+dojo.provide("dojox.color.Palette");
+
+
+(function(){
+	var dxc = dojox.color;
+	/***************************************************************
+	*	dojox.color.Palette
+	*
+	*	The Palette object is loosely based on the color palettes
+	*	at Kuler (http://kuler.adobe.com).  They are 5 color palettes
+	*	with the base color considered to be the third color in the
+	*	palette (for generation purposes).
+	*
+	*	Palettes can be generated from well-known algorithms or they
+	* 	can be manually created by passing an array to the constructor.
+	*
+	*	Palettes can be transformed, using a set of specific params
+	*	similar to the way shapes can be transformed with dojox.gfx.
+	*	However, unlike with transformations in dojox.gfx, transforming
+	* 	a palette will return you a new Palette object, in effect
+	* 	a clone of the original.
+	***************************************************************/
+
+	//	ctor ----------------------------------------------------------------------------
+	dxc.Palette = function(/* String|Array|dojox.color.Color|dojox.color.Palette */base){
+		//	summary
+		//		An object that represents a palette of colors.
+		//	description
+		//		A Palette is a representation of a set of colors.  While the standard
+		//		number of colors contained in a palette is 5, it can really handle any
+		//		number of colors.
+		//
+		//		A palette is useful for the ability to transform all the colors in it
+		//		using a simple object-based approach.  In addition, you can generate
+		//		palettes using dojox.color.Palette.generate; these generated palettes
+		//		are based on the palette generators at http://kuler.adobe.com.
+		//
+		//	colors: dojox.color.Color[]
+		//		The actual color references in this palette.
+		this.colors = [];
+		if(base instanceof dojox.color.Palette){
+			this.colors = base.colors.slice(0);
+		}
+		else if(base instanceof dojox.color.Color){
+			this.colors = [ null, null, base, null, null ];
+		}
+		else if(dojo.isArray(base)){
+			this.colors = dojo.map(base.slice(0), function(item){
+				if(dojo.isString(item)){ return new dojox.color.Color(item); }
+				return item;
+			});
+		}
+		else if (dojo.isString(base)){
+			this.colors = [ null, null, new dojox.color.Color(base), null, null ];
+		}
+	}
+
+	//	private functions ---------------------------------------------------------------
+
+	//	transformations
+	function tRGBA(p, param, val){
+		var ret = new dojox.color.Palette();
+		ret.colors = [];
+		dojo.forEach(p.colors, function(item){
+			var r=(param=="dr")?item.r+val:item.r,
+				g=(param=="dg")?item.g+val:item.g,
+				b=(param=="db")?item.b+val:item.b,
+				a=(param=="da")?item.a+val:item.a
+			ret.colors.push(new dojox.color.Color({
+				r: Math.min(255, Math.max(0, r)),
+				g: Math.min(255, Math.max(0, g)),
+				b: Math.min(255, Math.max(0, b)),
+				a: Math.min(1, Math.max(0, a))
+			}));
+		});
+		
+		return ret;
+	}
+
+	function tCMY(p, param, val){
+		var ret = new dojox.color.Palette();
+		ret.colors = [];
+		dojo.forEach(p.colors, function(item){
+			var o=item.toCmy(), 
+				c=(param=="dc")?o.c+val:o.c,
+				m=(param=="dm")?o.m+val:o.m,
+				y=(param=="dy")?o.y+val:o.y;
+			ret.colors.push(dojox.color.fromCmy(
+				Math.min(100, Math.max(0, c)),
+				Math.min(100, Math.max(0, m)),
+				Math.min(100, Math.max(0, y))
+			));
+		});
+		return ret;
+	}
+
+	function tCMYK(p, param, val){
+		var ret = new dojox.color.Palette();
+		ret.colors = [];
+		dojo.forEach(p.colors, function(item){
+			var o=item.toCmyk(), 
+				c=(param=="dc")?o.c+val:o.c,
+				m=(param=="dm")?o.m+val:o.m,
+				y=(param=="dy")?o.y+val:o.y,
+				k=(param=="dk")?o.b+val:o.b;
+			ret.colors.push(dojox.color.fromCmyk(
+				Math.min(100, Math.max(0, c)),
+				Math.min(100, Math.max(0, m)),
+				Math.min(100, Math.max(0, y)),
+				Math.min(100, Math.max(0, k))
+			));
+		});
+		return ret;
+	}
+
+	function tHSL(p, param, val){
+		var ret = new dojox.color.Palette();
+		ret.colors = [];
+		dojo.forEach(p.colors, function(item){
+			var o=item.toHsl(), 
+				h=(param=="dh")?o.h+val:o.h,
+				s=(param=="ds")?o.s+val:o.s,
+				l=(param=="dl")?o.l+val:o.l;
+			ret.colors.push(dojox.color.fromHsl(h%360, Math.min(100, Math.max(0, s)), Math.min(100, Math.max(0, l))));
+		});
+		return ret;
+	}
+
+	function tHSV(p, param, val){
+		var ret = new dojox.color.Palette();
+		ret.colors = [];
+		dojo.forEach(p.colors, function(item){
+			var o=item.toHsv(), 
+				h=(param=="dh")?o.h+val:o.h,
+				s=(param=="ds")?o.s+val:o.s,
+				v=(param=="dv")?o.v+val:o.v;
+			ret.colors.push(dojox.color.fromHsv(h%360, Math.min(100, Math.max(0, s)), Math.min(100, Math.max(0, v))));
+		});
+		return ret;
+	}
+
+	//	helper functions
+	function rangeDiff(val, low, high){
+		//	given the value in a range from 0 to high, find the equiv
+		//		using the range low to high.
+		return high-((high-val)*((high-low)/high));
+	}
+
+	//	object methods ---------------------------------------------------------------
+	dojo.extend(dxc.Palette, {
+		transform: function(/* Object */kwArgs){
+			//	summary
+			//		Transform the palette using a specific transformation function
+			//		and a set of transformation parameters.
+			//	description
+			//		{palette}.transform is a simple way to uniformly transform
+			//		all of the colors in a palette using any of 5 formulae:
+			//		RGBA, HSL, HSV, CMYK or CMY.
+			//
+			//		Once the forumula to be used is determined, you can pass any
+			//		number of parameters based on the formula "d"[param]; for instance,
+			//		{ use: "rgba", dr: 20, dg: -50 } will take all of the colors in
+			//		palette, add 20 to the R value and subtract 50 from the G value.
+			//
+			//		Unlike other types of transformations, transform does *not* alter
+			//		the original palette but will instead return a new one.
+			var fn=tRGBA;	//	the default transform function.
+			if(kwArgs.use){
+				//	we are being specific about the algo we want to use.
+				var use=kwArgs.use.toLowerCase();
+				if(use.indexOf("hs")==0){
+					if(use.charAt(2)=="l"){ fn=tHSL; }
+					else { fn=tHSV; }
+				}
+				else if(use.indexOf("cmy")==0){
+					if(use.charAt(3)=="k"){ fn=tCMYK; }
+					else { fn=tCMY; }
+				}
+			}
+			//	try to guess the best choice.
+			else if("dc" in kwArgs || "dm" in kwArgs || "dy" in kwArgs){
+				if("dk" in kwArgs){ fn = tCMYK; }
+				else { fn = tCMY; }
+			}
+			else if("dh" in kwArgs || "ds" in kwArgs){
+				if("dv" in kwArgs){ fn = tHSV; }
+				else { fn = tHSL; }
+			}
+
+			var palette = this;
+			for(var p in kwArgs){
+				//	ignore use
+				if(p=="use"){ continue; }
+				palette = fn(palette, p, kwArgs[p]);
+			}
+			return palette;		//	dojox.color.Palette
+		},
+		clone: function(){
+			//	summary
+			//		Clones the current palette.
+			return new dxc.Palette(this);	//	dojox.color.Palette
+		}
+	});
+
+	//	static methods ---------------------------------------------------------------
+	dojo.mixin(dxc.Palette, {
+		generators: {
+			analogous:function(/* Object */args){
+				var high=args.high||60, 	//	delta between base hue and highest hue (subtracted from base)
+					low=args.low||18,		//	delta between base hue and lowest hue (added to base)
+					base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
+					hsv=base.toHsv();
+
+				//	generate our hue angle differences
+				var h=[
+					(hsv.h+low+360)%360,
+					(hsv.h+Math.round(low/2)+360)%360,
+					hsv.h,
+					(hsv.h-Math.round(high/2)+360)%360,
+					(hsv.h-high+360)%360
+				];
+
+				var s1=Math.max(10, (hsv.s<=95)?hsv.s+5:(100-(hsv.s-95))),
+					s2=(hsv.s>1)?hsv.s-1:21-hsv.s,
+					v1=(hsv.v>=92)?hsv.v-9:Math.max(hsv.v+9, 20),
+					v2=(hsv.v<=90)?Math.max(hsv.v+5, 20):(95+Math.ceil((hsv.v-90)/2)),
+					s=[ s1, s2, hsv.s, s1, s1 ],
+					v=[ v1, v2, hsv.v, v1, v2 ]
+
+				return new dxc.Palette(dojo.map(h, function(hue, i){
+					return dojox.color.fromHsv(hue, s[i], v[i]);
+				}));		//	dojox.color.Palette
+			},
+
+			monochromatic: function(/* Object */args){
+				var base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
+					hsv = base.toHsv();
+				
+				//	figure out the saturation and value
+				var s1 = (hsv.s-30>9)?hsv.s-30:hsv.s+30,
+					s2 = hsv.s,
+					v1 = rangeDiff(hsv.v, 20, 100),
+					v2 = (hsv.v-20>20)?hsv.v-20:hsv.v+60,
+					v3 = (hsv.v-50>20)?hsv.v-50:hsv.v+30;
+
+				return new dxc.Palette([
+					dojox.color.fromHsv(hsv.h, s1, v1),
+					dojox.color.fromHsv(hsv.h, s2, v3),
+					base,
+					dojox.color.fromHsv(hsv.h, s1, v3),
+					dojox.color.fromHsv(hsv.h, s2, v2)
+				]);		//	dojox.color.Palette
+			},
+
+			triadic: function(/* Object */args){
+				var base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
+					hsv = base.toHsv();
+
+				var h1 = (hsv.h+57+360)%360,
+					h2 = (hsv.h-157+360)%360,
+					s1 = (hsv.s>20)?hsv.s-10:hsv.s+10,
+					s2 = (hsv.s>90)?hsv.s-10:hsv.s+10,
+					s3 = (hsv.s>95)?hsv.s-5:hsv.s+5,
+					v1 = (hsv.v-20>20)?hsv.v-20:hsv.v+20,
+					v2 = (hsv.v-30>20)?hsv.v-30:hsv.v+30,
+					v3 = (hsv.v-30>70)?hsv.v-30:hsv.v+30;
+
+				return new dxc.Palette([
+					dojox.color.fromHsv(h1, s1, hsv.v),
+					dojox.color.fromHsv(hsv.h, s2, v2),
+					base,
+					dojox.color.fromHsv(h2, s2, v1),
+					dojox.color.fromHsv(h2, s3, v3)
+				]);		//	dojox.color.Palette
+			},
+
+			complementary: function(/* Object */args){
+				var base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
+					hsv = base.toHsv();
+
+				var h1 = ((hsv.h*2)+137<360)?(hsv.h*2)+137:Math.floor(hsv.h/2)-137,
+					s1 = Math.max(hsv.s-10, 0),
+					s2 = rangeDiff(hsv.s, 10, 100),
+					s3 = Math.min(100, hsv.s+20),
+					v1 = Math.min(100, hsv.v+30),
+					v2 = (hsv.v>20)?hsv.v-30:hsv.v+30;
+
+				return new dxc.Palette([
+					dojox.color.fromHsv(hsv.h, s1, v1),
+					dojox.color.fromHsv(hsv.h, s2, v2),
+					base,
+					dojox.color.fromHsv(h1, s3, v2),
+					dojox.color.fromHsv(h1, hsv.s, hsv.v)
+				]);		//	dojox.color.Palette
+			},
+
+			splitComplementary: function(/* Object */args){
+				var base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
+					dangle = args.da || 30,
+					hsv = base.toHsv();
+
+				var baseh = ((hsv.h*2)+137<360)?(hsv.h*2)+137:Math.floor(hsv.h/2)-137,
+					h1 = (baseh-dangle+360)%360,
+					h2 = (baseh+dangle)%360,
+					s1 = Math.max(hsv.s-10, 0),
+					s2 = rangeDiff(hsv.s, 10, 100),
+					s3 = Math.min(100, hsv.s+20),
+					v1 = Math.min(100, hsv.v+30),
+					v2 = (hsv.v>20)?hsv.v-30:hsv.v+30;
+
+				return new dxc.Palette([
+					dojox.color.fromHsv(h1, s1, v1),
+					dojox.color.fromHsv(h1, s2, v2),
+					base,
+					dojox.color.fromHsv(h2, s3, v2),
+					dojox.color.fromHsv(h2, hsv.s, hsv.v)
+				]);		//	dojox.color.Palette
+			},
+
+			compound: function(/* Object */args){
+				var base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
+					hsv = base.toHsv();
+
+				var h1 = ((hsv.h*2)+18<360)?(hsv.h*2)+18:Math.floor(hsv.h/2)-18,
+					h2 = ((hsv.h*2)+120<360)?(hsv.h*2)+120:Math.floor(hsv.h/2)-120,
+					h3 = ((hsv.h*2)+99<360)?(hsv.h*2)+99:Math.floor(hsv.h/2)-99,
+					s1 = (hsv.s-40>10)?hsv.s-40:hsv.s+40,
+					s2 = (hsv.s-10>80)?hsv.s-10:hsv.s+10,
+					s3 = (hsv.s-25>10)?hsv.s-25:hsv.s+25,
+					v1 = (hsv.v-40>10)?hsv.v-40:hsv.v+40,
+					v2 = (hsv.v-20>80)?hsv.v-20:hsv.v+20,
+					v3 = Math.max(hsv.v, 20);
+
+				return new dxc.Palette([
+					dojox.color.fromHsv(h1, s1, v1),
+					dojox.color.fromHsv(h1, s2, v2),
+					base,
+					dojox.color.fromHsv(h2, s3, v3),
+					dojox.color.fromHsv(h3, s2, v2)
+				]);		//	dojox.color.Palette
+			},
+
+			shades: function(/* Object */args){
+				var base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
+					hsv = base.toHsv();
+
+				var s  = (hsv.s==100 && hsv.v==0)?0:hsv.s,
+					v1 = (hsv.v-50>20)?hsv.v-50:hsv.v+30,
+					v2 = (hsv.v-25>=20)?hsv.v-25:hsv.v+55,
+					v3 = (hsv.v-75>=20)?hsv.v-75:hsv.v+5,
+					v4 = Math.max(hsv.v-10, 20);
+
+				return new dxc.Palette([
+					new dojox.color.fromHsv(hsv.h, s, v1),
+					new dojox.color.fromHsv(hsv.h, s, v2),
+					base,
+					new dojox.color.fromHsv(hsv.h, s, v3),
+					new dojox.color.fromHsv(hsv.h, s, v4)
+				]);		//	dojox.color.Palette
+			}
+		},
+		generate: function(/* String|dojox.color.Color */base, /* Function|String */type){
+			//	summary
+			//		Generate a new Palette using any of the named functions in
+			//		dojox.color.Palette.generators or an optional function definition.
+			if(dojo.isFunction(type)){
+				return type({ base: base });	//	dojox.color.Palette
+			}
+			else if(dxc.Palette.generators[type]){
+				return dxc.Palette.generators[type]({ base: base });	//	dojox.color.Palette
+			}
+			throw new Error("dojox.color.Palette.generate: the specified generator ('" + type + "') does not exist.");
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.Theme"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.Theme"] = true;
+dojo.provide("dojox.charting.Theme");
+
+
+
+(function(){
+	var dxc=dojox.charting;
+	//	TODO: Legend information
+
+	dxc.Theme = function(/*Object?*/ kwArgs){
+		kwArgs=kwArgs||{};
+		var def = dxc.Theme._def;
+		dojo.forEach(["chart", "plotarea", "axis", "series", "marker"], function(n){
+			this[n] = dojo.delegate(def[n], kwArgs[n]||{});
+		}, this);
+		this.markers = dojo.delegate(dxc.Theme.Markers, kwArgs.markers||{});
+		this.colors = [];
+		this.antiAlias = ("antiAlias" in kwArgs)?kwArgs.antiAlias:true;
+		this.assignColors = ("assignColors" in kwArgs)?kwArgs.assignColors:true;
+		this.assignMarkers = ("assignMarkers" in kwArgs)?kwArgs.assignMarkers:true;
+
+		//	push the colors, use _def colors if none passed.
+		kwArgs.colors = kwArgs.colors||def.colors;
+		dojo.forEach(kwArgs.colors, function(item){ 
+			this.colors.push(item); 
+		}, this);
+
+		//	private variables for color and marker indexing
+		this._current = { color:0, marker: 0 };
+		this._markers = [];
+		this._buildMarkerArray();
+	};
+
+	//	"static" fields
+	//	default markers.
+	//	A marker is defined by an SVG path segment; it should be defined as
+	//		relative motion, and with the assumption that the path segment
+	//		will be moved to the value point (i.e prepend Mx,y)
+	dxc.Theme.Markers={
+		CIRCLE:		"m-3,0 c0,-4 6,-4 6,0 m-6,0 c0,4 6,4 6,0", 
+		SQUARE:		"m-3,-3 l0,6 6,0 0,-6 z", 
+		DIAMOND:	"m0,-3 l3,3 -3,3 -3,-3 z", 
+		CROSS:		"m0,-3 l0,6 m-3,-3 l6,0", 
+		X:			"m-3,-3 l6,6 m0,-6 l-6,6", 
+		TRIANGLE:	"m-3,3 l3,-6 3,6 z", 
+		TRIANGLE_INVERTED:"m-3,-3 l3,6 3,-6 z"
+	};
+	dxc.Theme._def={
+		//	all objects are structs used directly in dojox.gfx
+		chart:{ 
+			stroke:null,
+			fill: "white"
+		},
+		plotarea:{ 
+			stroke:null,
+			fill: "white"
+		},
+		//	TODO: label rotation on axis
+		axis:{
+			stroke:	{ //	the axis itself
+				color:"#333",
+				width:1
+			},
+			/*
+			line:	{ //	in the future can be used for gridlines
+				color:"#ccc",
+				width:1,
+				style:"Dot",
+				cap:"round"
+			},
+			*/
+			majorTick:	{ //	major ticks on axis, and used for major gridlines
+				color:"#666",
+				width:1, 
+				length:6, 
+				position:"center"
+			},
+			minorTick:	{ //	minor ticks on axis, and used for minor gridlines
+				color:"#666", 
+				width:0.8, 
+				length:3, 
+				position:"center"
+			},	
+			font: "normal normal normal 7pt Tahoma", //	labels on axis
+			fontColor:"#333"						//	color of labels
+		},
+		series:{
+			outline: {width: 0.1, color: "#ccc"},							//	line or outline
+			stroke: {width: 1.5, color: "#333"},							//	line or outline
+			fill: "#ccc",												//	fill, if appropriate
+			font: "normal normal normal 7pt Tahoma",					//	if there's a label
+			fontColor: "#000"											// 	color of labels
+		},
+		marker:{	//	any markers on a series.
+			stroke: {width:1},											//	stroke or outline
+			fill: "#333",												//	fill if needed
+			font: "normal normal normal 7pt Tahoma",					//	label
+			fontColor: "#000"
+		},
+		colors:[ "#54544c","#858e94","#6e767a","#948585","#474747" ]
+	};
+	
+	//	prototype methods
+	dojo.extend(dxc.Theme, {
+		defineColors: function(obj){
+			//	summary:
+			//		Generate a set of colors for the theme based on keyword
+			//		arguments
+			var kwArgs=obj||{};
+
+			//	note that we've changed the default number from 32 to 4 colors
+			//	are cycled anyways.
+			var c=[], n=kwArgs.num||5;	//	the number of colors to generate
+			if(kwArgs.colors){
+				//	we have an array of colors predefined, so fix for the number of series.
+				var l=kwArgs.colors.length;
+				for(var i=0; i<n; i++){
+					c.push(kwArgs.colors[i%l]);
+				}
+				this.colors=c;
+			}else if(kwArgs.hue){
+				//	single hue, generate a set based on brightness
+				var s=kwArgs.saturation||100;	//	saturation
+				var st=kwArgs.low||30;
+				var end=kwArgs.high||90;
+				//	we'd like it to be a little on the darker side.
+				var l=(end+st)/2;
+
+				//	alternately, use "shades"
+				this.colors = dojox.color.Palette.generate(
+					dojox.color.fromHsv(kwArgs.hue, s, l), "monochromatic"
+				).colors;
+			}else if(kwArgs.generator){
+				//	pass a base color and the name of a generator
+				this.colors=dojox.color.Palette.generate(kwArgs.base, kwArgs.generator).colors;
+			}
+		},
+	
+		_buildMarkerArray: function(){
+			this._markers = [];
+			for(var p in this.markers){ this._markers.push(this.markers[p]); }
+			//	reset the position
+			this._current.marker=0;
+		},
+
+		_clone: function(){
+			//	summary:
+			//		Return a clone of this theme, with the position vars reset to 0.
+			return new dxc.Theme({
+				chart: this.chart,
+				plotarea: this.plotarea,
+				axis: this.axis,
+				series: this.series,
+				marker: this.marker,
+				antiAlias: this.antiAlias,
+				assignColors: this.assignColors,
+				assignMarkers: this.assigneMarkers,
+				colors: dojo.delegate(this.colors)
+			});
+		},
+
+		addMarker:function(/*String*/ name, /*String*/ segment){
+			//	summary:
+			//		Add a custom marker to this theme.
+			//	example:
+			//	|	myTheme.addMarker("Ellipse", foo);
+			this.markers[name]=segment;
+			this._buildMarkerArray();
+		},
+		setMarkers:function(/*Object*/ obj){
+			//	summary:
+			//		Set all the markers of this theme at once.  obj should be a
+			//		dictionary of keys and path segments.
+			//
+			//	example:
+			//	|	myTheme.setMarkers({ "CIRCLE": foo });
+			this.markers=obj;
+			this._buildMarkerArray();
+		},
+
+		next: function(/*String?*/ type){
+			//	summary:
+			//		get either the next color or the next marker, depending on
+			//		what was passed. If type is not passed, it assumes color.
+			//	type:
+			//		Optional. One of either "color" or "marker". Defaults to
+			//		"color".
+			//	example:
+			//	|	var color = myTheme.next();
+			//	|	var color = myTheme.next("color");
+			//	|	var marker = myTheme.next("marker");
+			if(type == "marker"){
+				return this._markers[ this._current.marker++ % this._markers.length ];
+			}else{
+				return this.colors[ this._current.color++ % this.colors.length ];
+			}
+		},
+		clear: function(){
+			// summary:
+			//		resets both marker and color counters back to the start.
+			//		Subsequent calls to `next` will retrievie the first value
+			//		of each depending on the passed type.
+			this._current = {color: 0, marker: 0};
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.Element"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.Element"] = true;
+dojo.provide("dojox.charting.Element");
+
+dojo.declare("dojox.charting.Element", null, {
+	constructor: function(chart){
+		this.chart = chart;
+		this.group = null;
+		this.htmlElements = [];
+		this.dirty = true;
+	},
+	createGroup: function(creator){
+		if(!creator){ creator = this.chart.surface; }
+		if(!this.group){
+			this.group = creator.createGroup();
+		}
+		return this;
+	},
+	purgeGroup: function(){
+		this.destroyHtmlElements();
+		if(this.group){
+			this.group.clear();
+			this.group.removeShape();
+			this.group = null;
+		}
+		this.dirty = true;
+		return this;
+	},
+	cleanGroup: function(creator){
+		this.destroyHtmlElements();
+		if(!creator){ creator = this.chart.surface; }
+		if(this.group){
+			this.group.clear();
+		}else{
+			this.group = creator.createGroup();
+		}
+		this.dirty = true;
+		return this;
+	},
+	destroyHtmlElements: function(){
+		if(this.htmlElements.length){
+			dojo.forEach(this.htmlElements, dojo.destroy);
+			this.htmlElements = [];
+		}
+	},
+	destroy: function(){
+		this.purgeGroup();
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.charting.Series"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.Series"] = true;
+dojo.provide("dojox.charting.Series");
+
+
+
+dojo.declare("dojox.charting.Series", dojox.charting.Element, {
+	constructor: function(chart, data, kwArgs){
+		dojo.mixin(this, kwArgs);
+		if(typeof this.plot != "string"){ this.plot = "default"; }
+		this.data = data;
+		this.dirty = true;
+		this.clear();
+	},
+	clear: function(){
+		this.dyn = {};
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.charting.scaler.common"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.scaler.common"] = true;
+dojo.provide("dojox.charting.scaler.common");
+
+(function(){
+	var eq = function(/*Number*/ a, /*Number*/ b){
+		// summary: compare two FP numbers for equality
+		return Math.abs(a - b) <= 1e-6 * (Math.abs(a) + Math.abs(b));	// Boolean
+	};
+	
+	dojo.mixin(dojox.charting.scaler.common, {
+		findString: function(/*String*/ val, /*Array*/ text){
+			val = val.toLowerCase();
+			for(var i = 0; i < text.length; ++i){
+				if(val == text[i]){ return true; }
+			}
+			return false;
+		},
+		getNumericLabel: function(/*Number*/ number, /*Number*/ precision, /*Object*/ kwArgs){
+			var def = kwArgs.fixed ? 
+						number.toFixed(precision < 0 ? -precision : 0) : 
+						number.toString();
+			if(kwArgs.labelFunc){
+				var r = kwArgs.labelFunc(def, number, precision);
+				if(r){ return r; }
+				// else fall through to the regular labels search
+			}
+			if(kwArgs.labels){
+				// classic binary search
+				var l = kwArgs.labels, lo = 0, hi = l.length;
+				while(lo < hi){
+					var mid = Math.floor((lo + hi) / 2), val = l[mid].value;
+					if(val < number){
+						lo = mid + 1;
+					}else{
+						hi = mid;
+					}
+				}
+				// lets take into account FP errors
+				if(lo < l.length && eq(l[lo].value, number)){
+					return l[lo].text;
+				}
+				--lo;
+				if(lo >= 0 && lo < l.length && eq(l[lo].value, number)){
+					return l[lo].text;
+				}
+				lo += 2;
+				if(lo < l.length && eq(l[lo].value, number)){
+					return l[lo].text;
+				}
+				// otherwise we will produce a number
+			}
+			return def;
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.scaler.linear"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.scaler.linear"] = true;
+dojo.provide("dojox.charting.scaler.linear");
+
+
+(function(){
+	var deltaLimit = 3,	// pixels
+		dc = dojox.charting, dcs = dc.scaler, dcsc = dcs.common,
+		findString = dcsc.findString,
+		getLabel = dcsc.getNumericLabel;
+	
+	var calcTicks = function(min, max, kwArgs, majorTick, minorTick, microTick, span){
+		kwArgs = dojo.delegate(kwArgs);
+		if(!majorTick){
+			if(kwArgs.fixUpper == "major"){ kwArgs.fixUpper = "minor"; }
+			if(kwArgs.fixLower == "major"){ kwArgs.fixLower = "minor"; }
+		}
+		if(!minorTick){
+			if(kwArgs.fixUpper == "minor"){ kwArgs.fixUpper = "micro"; }
+			if(kwArgs.fixLower == "minor"){ kwArgs.fixLower = "micro"; }
+		}
+		if(!microTick){
+			if(kwArgs.fixUpper == "micro"){ kwArgs.fixUpper = "none"; }
+			if(kwArgs.fixLower == "micro"){ kwArgs.fixLower = "none"; }
+		}
+		var lowerBound = findString(kwArgs.fixLower, ["major"]) ?
+				Math.floor(kwArgs.min / majorTick) * majorTick :
+					findString(kwArgs.fixLower, ["minor"]) ?
+						Math.floor(kwArgs.min / minorTick) * minorTick :
+							findString(kwArgs.fixLower, ["micro"]) ?
+								Math.floor(kwArgs.min / microTick) * microTick : kwArgs.min,
+			upperBound = findString(kwArgs.fixUpper, ["major"]) ?
+				Math.ceil(kwArgs.max / majorTick) * majorTick :
+					findString(kwArgs.fixUpper, ["minor"]) ?
+						Math.ceil(kwArgs.max / minorTick) * minorTick :
+							findString(kwArgs.fixUpper, ["micro"]) ?
+								Math.ceil(kwArgs.max / microTick) * microTick : kwArgs.max;
+								
+		if(kwArgs.useMin){ min = lowerBound; }
+		if(kwArgs.useMax){ max = upperBound; }
+		
+		var majorStart = (!majorTick || kwArgs.useMin && findString(kwArgs.fixLower, ["major"])) ?
+				min : Math.ceil(min / majorTick) * majorTick,
+			minorStart = (!minorTick || kwArgs.useMin && findString(kwArgs.fixLower, ["major", "minor"])) ?
+				min : Math.ceil(min / minorTick) * minorTick,
+			microStart = (! microTick || kwArgs.useMin && findString(kwArgs.fixLower, ["major", "minor", "micro"])) ?
+				min : Math.ceil(min / microTick) * microTick,
+			majorCount = !majorTick ? 0 : (kwArgs.useMax && findString(kwArgs.fixUpper, ["major"]) ?
+				Math.round((max - majorStart) / majorTick) :
+				Math.floor((max - majorStart) / majorTick)) + 1,
+			minorCount = !minorTick ? 0 : (kwArgs.useMax && findString(kwArgs.fixUpper, ["major", "minor"]) ?
+				Math.round((max - minorStart) / minorTick) :
+				Math.floor((max - minorStart) / minorTick)) + 1,
+			microCount = !microTick ? 0 : (kwArgs.useMax && findString(kwArgs.fixUpper, ["major", "minor", "micro"]) ?
+				Math.round((max - microStart) / microTick) :
+				Math.floor((max - microStart) / microTick)) + 1,
+			minorPerMajor  = minorTick ? Math.round(majorTick / minorTick) : 0,
+			microPerMinor  = microTick ? Math.round(minorTick / microTick) : 0,
+			majorPrecision = majorTick ? Math.floor(Math.log(majorTick) / Math.LN10) : 0,
+			minorPrecision = minorTick ? Math.floor(Math.log(minorTick) / Math.LN10) : 0,
+			scale = span / (max - min);	
+		if(!isFinite(scale)){ scale = 1; }
+		
+		return {
+			bounds: {
+				lower:	lowerBound,
+				upper:	upperBound,
+				from:	min,
+				to:		max,
+				scale:	scale,
+				span:	span
+			},
+			major: {
+				tick:	majorTick,
+				start:	majorStart,
+				count:	majorCount,
+				prec:	majorPrecision
+			},
+			minor: {
+				tick:	minorTick,
+				start:	minorStart,
+				count:	minorCount,
+				prec:	minorPrecision
+			},
+			micro: {
+				tick:	microTick,
+				start:	microStart,
+				count:	microCount,
+				prec:	0
+			},
+			minorPerMajor:	minorPerMajor,
+			microPerMinor:	microPerMinor,
+			scaler:			dcs.linear
+		};
+	};
+	
+	dojo.mixin(dojox.charting.scaler.linear, {
+		buildScaler: function(/*Number*/ min, /*Number*/ max, /*Number*/ span, /*Object*/ kwArgs){
+			var h = {fixUpper: "none", fixLower: "none", natural: false};
+			if(kwArgs){
+				if("fixUpper" in kwArgs){ h.fixUpper = String(kwArgs.fixUpper); }
+				if("fixLower" in kwArgs){ h.fixLower = String(kwArgs.fixLower); }
+				if("natural"  in kwArgs){ h.natural  = Boolean(kwArgs.natural); }
+			}
+			
+			// update bounds
+			if("min" in kwArgs){ min = kwArgs.min; }
+			if("max" in kwArgs){ max = kwArgs.max; }
+			if(kwArgs.includeZero){
+				if(min > 0){ min = 0; }
+				if(max < 0){ max = 0; }
+			}
+			h.min = min;
+			h.useMin = true;
+			h.max = max;
+			h.useMax = true;
+			
+			if("from" in kwArgs){
+				min = kwArgs.from;
+				h.useMin = false;
+			}
+			if("to" in kwArgs){
+				max = kwArgs.to;
+				h.useMax = false;
+			}
+			
+			// check for erroneous condition
+			if(max <= min){
+				return calcTicks(min, max, h, 0, 0, 0, span);	// Object
+			}
+			
+			var mag = Math.floor(Math.log(max - min) / Math.LN10),
+				major = kwArgs && ("majorTickStep" in kwArgs) ? kwArgs.majorTickStep : Math.pow(10, mag), 
+				minor = 0, micro = 0, ticks;
+				
+			// calculate minor ticks
+			if(kwArgs && ("minorTickStep" in kwArgs)){
+				minor = kwArgs.minorTickStep;
+			}else{
+				do{
+					minor = major / 10;
+					if(!h.natural || minor > 0.9){
+						ticks = calcTicks(min, max, h, major, minor, 0, span);
+						if(ticks.bounds.scale * ticks.minor.tick > deltaLimit){ break; }
+					}
+					minor = major / 5;
+					if(!h.natural || minor > 0.9){
+						ticks = calcTicks(min, max, h, major, minor, 0, span);
+						if(ticks.bounds.scale * ticks.minor.tick > deltaLimit){ break; }
+					}
+					minor = major / 2;
+					if(!h.natural || minor > 0.9){
+						ticks = calcTicks(min, max, h, major, minor, 0, span);
+						if(ticks.bounds.scale * ticks.minor.tick > deltaLimit){ break; }
+					}
+					return calcTicks(min, max, h, major, 0, 0, span);	// Object
+				}while(false);
+			}
+	
+			// calculate micro ticks
+			if(kwArgs && ("microTickStep" in kwArgs)){
+				micro = kwArgs.microTickStep;
+				ticks = calcTicks(min, max, h, major, minor, micro, span);
+			}else{
+				do{
+					micro = minor / 10;
+					if(!h.natural || micro > 0.9){
+						ticks = calcTicks(min, max, h, major, minor, micro, span);
+						if(ticks.bounds.scale * ticks.micro.tick > deltaLimit){ break; }
+					}
+					micro = minor / 5;
+					if(!h.natural || micro > 0.9){
+						ticks = calcTicks(min, max, h, major, minor, micro, span);
+						if(ticks.bounds.scale * ticks.micro.tick > deltaLimit){ break; }
+					}
+					micro = minor / 2;
+					if(!h.natural || micro > 0.9){
+						ticks = calcTicks(min, max, h, major, minor, micro, span);
+						if(ticks.bounds.scale * ticks.micro.tick > deltaLimit){ break; }
+					}
+					micro = 0;
+				}while(false);
+			}
+	
+			return micro ? ticks : calcTicks(min, max, h, major, minor, 0, span);	// Object
+		},
+		buildTicks: function(/*Object*/ scaler, /*Object*/ kwArgs){
+			var step, next, tick,
+				nextMajor = scaler.major.start, 
+				nextMinor = scaler.minor.start, 
+				nextMicro = scaler.micro.start;
+			if(kwArgs.microTicks && scaler.micro.tick){
+				step = scaler.micro.tick, next = nextMicro;
+			}else if(kwArgs.minorTicks && scaler.minor.tick){
+				step = scaler.minor.tick, next = nextMinor;
+			}else if(scaler.major.tick){
+				step = scaler.major.tick, next = nextMajor;
+			}else{
+				// no ticks
+				return null;
+			}
+			// make sure that we have finite bounds
+			var revScale = 1 / scaler.bounds.scale;
+			if(scaler.bounds.to <= scaler.bounds.from || isNaN(revScale) || !isFinite(revScale) ||
+					step <= 0 || isNaN(step) || !isFinite(step)){
+				// no ticks
+				return null;
+			}
+			// loop over all ticks
+			var majorTicks = [], minorTicks = [], microTicks = [];
+			while(next <= scaler.bounds.to + revScale){
+				if(Math.abs(nextMajor - next) < step / 2){
+					// major tick
+					tick = {value: nextMajor};
+					if(kwArgs.majorLabels){
+						tick.label = getLabel(nextMajor, scaler.major.prec, kwArgs);
+					}
+					majorTicks.push(tick);
+					nextMajor += scaler.major.tick;
+					nextMinor += scaler.minor.tick;
+					nextMicro += scaler.micro.tick;
+				}else if(Math.abs(nextMinor - next) < step / 2){
+					// minor tick
+					if(kwArgs.minorTicks){
+						tick = {value: nextMinor};
+						if(kwArgs.minorLabels && (scaler.minMinorStep <= scaler.minor.tick * scaler.bounds.scale)){
+							tick.label = getLabel(nextMinor, scaler.minor.prec, kwArgs);
+						}
+						minorTicks.push(tick);
+					}
+					nextMinor += scaler.minor.tick;
+					nextMicro += scaler.micro.tick;
+				}else{
+					// micro tick
+					if(kwArgs.microTicks){
+						microTicks.push({value: nextMicro});
+					}
+					nextMicro += scaler.micro.tick;
+				}
+				next += step;
+			}
+			return {major: majorTicks, minor: minorTicks, micro: microTicks};	// Object
+		},
+		getTransformerFromModel: function(/*Object*/ scaler){
+			var offset = scaler.bounds.from, scale = scaler.bounds.scale;
+			return function(x){ return (x - offset) * scale; };	// Function
+		},
+		getTransformerFromPlot: function(/*Object*/ scaler){
+			var offset = scaler.bounds.from, scale = scaler.bounds.scale;
+			return function(x){ return x / scale + offset; };	// Function
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.axis2d.common"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.axis2d.common"] = true;
+dojo.provide("dojox.charting.axis2d.common");
+
+
+
+(function(){
+	var g = dojox.gfx;
+	
+	function clearNode(s){
+		s.marginLeft   = "0px";
+		s.marginTop    = "0px";
+		s.marginRight  = "0px";
+		s.marginBottom = "0px";
+		s.paddingLeft   = "0px";
+		s.paddingTop    = "0px";
+		s.paddingRight  = "0px";
+		s.paddingBottom = "0px";
+		s.borderLeftWidth   = "0px";
+		s.borderTopWidth    = "0px";
+		s.borderRightWidth  = "0px";
+		s.borderBottomWidth = "0px";
+	}
+	
+	dojo.mixin(dojox.charting.axis2d.common, {
+		createText: {
+			gfx: function(chart, creator, x, y, align, text, font, fontColor){
+				return creator.createText({
+					x: x, y: y, text: text, align: align
+				}).setFont(font).setFill(fontColor);
+			},
+			html: function(chart, creator, x, y, align, text, font, fontColor){
+				// setup the text node
+				var p = dojo.doc.createElement("div"), s = p.style;
+				clearNode(s);
+				s.font = font;
+				p.innerHTML = String(text).replace(/\s/g, " ");
+				s.color = fontColor;
+				// measure the size
+				s.position = "absolute";
+				s.left = "-10000px";
+				dojo.body().appendChild(p);
+				var size = g.normalizedLength(g.splitFontString(font).size),
+					box = dojo.marginBox(p);
+				// new settings for the text node
+				dojo.body().removeChild(p);
+				s.position = "relative";
+				switch(align){
+					case "middle":
+						s.left = Math.floor(x - box.w / 2) + "px";
+						break;
+					case "end":
+						s.left = Math.floor(x - box.w) + "px";
+						break;
+					//case "start":
+					default:
+						s.left = Math.floor(x) + "px";
+						break;
+				}
+				s.top = Math.floor(y - size) + "px";
+				// setup the wrapper node
+				var wrap = dojo.doc.createElement("div"), w = wrap.style;
+				clearNode(w);
+				w.width = "0px";
+				w.height = "0px";
+				// insert nodes
+				wrap.appendChild(p)
+				chart.node.insertBefore(wrap, chart.node.firstChild);
+				return wrap;
+			}
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.axis2d.Base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.axis2d.Base"] = true;
+dojo.provide("dojox.charting.axis2d.Base");
+
+
+
+dojo.declare("dojox.charting.axis2d.Base", dojox.charting.Element, {
+	constructor: function(chart, kwArgs){
+		this.vertical = kwArgs && kwArgs.vertical;
+	},
+	clear: function(){
+		return this;
+	},
+	initialized: function(){
+		return false;
+	},
+	calculate: function(min, max, span){
+		return this;
+	},
+	getScaler: function(){
+		return null;
+	},
+	getTicks: function(){
+		return null;
+	},
+	getOffsets: function(){
+		return {l: 0, r: 0, t: 0, b: 0};
+	},
+	render: function(dim, offsets){
+		return this;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojo.string"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.string"] = true;
+dojo.provide("dojo.string");
+
+/*=====
+dojo.string = { 
+	// summary: String utilities for Dojo
+};
+=====*/
+
+dojo.string.rep = function(/*String*/str, /*Integer*/num){
+	//	summary:
+	//		Efficiently replicate a string `n` times.
+	//	str:
+	//		the string to replicate
+	//	num:
+	//		number of times to replicate the string
+	
+	if(num <= 0 || !str){ return ""; }
+	
+	var buf = [];
+	for(;;){
+		if(num & 1){
+			buf.push(str);
+		}
+		if(!(num >>= 1)){ break; }
+		str += str;
+	}
+	return buf.join("");	// String
+};
+
+dojo.string.pad = function(/*String*/text, /*Integer*/size, /*String?*/ch, /*Boolean?*/end){
+	//	summary:
+	//		Pad a string to guarantee that it is at least `size` length by
+	//		filling with the character `ch` at either the start or end of the
+	//		string. Pads at the start, by default.
+	//	text:
+	//		the string to pad
+	//	size:
+	//		length to provide padding
+	//	ch:
+	//		character to pad, defaults to '0'
+	//	end:
+	//		adds padding at the end if true, otherwise pads at start
+	//	example:
+	//	|	// Fill the string to length 10 with "+" characters on the right.  Yields "Dojo++++++".
+	//	|	dojo.string.pad("Dojo", 10, "+", true);
+
+	if(!ch){
+		ch = '0';
+	}
+	var out = String(text),
+		pad = dojo.string.rep(ch, Math.ceil((size - out.length) / ch.length));
+	return end ? out + pad : pad + out;	// String
+};
+
+dojo.string.substitute = function(	/*String*/		template, 
+									/*Object|Array*/map, 
+									/*Function?*/	transform, 
+									/*Object?*/		thisObject){
+	//	summary:
+	//		Performs parameterized substitutions on a string. Throws an
+	//		exception if any parameter is unmatched.
+	//	template: 
+	//		a string with expressions in the form `${key}` to be replaced or
+	//		`${key:format}` which specifies a format function. keys are case-sensitive. 
+	//	map:
+	//		hash to search for substitutions
+	//	transform: 
+	//		a function to process all parameters before substitution takes
+	//		place, e.g. dojo.string.encodeXML
+	//	thisObject: 
+	//		where to look for optional format function; default to the global
+	//		namespace
+	//	example:
+	//	|	// returns "File 'foo.html' is not found in directory '/temp'."
+	//	|	dojo.string.substitute(
+	//	|		"File '${0}' is not found in directory '${1}'.",
+	//	|		["foo.html","/temp"]
+	//	|	);
+	//	|
+	//	|	// also returns "File 'foo.html' is not found in directory '/temp'."
+	//	|	dojo.string.substitute(
+	//	|		"File '${name}' is not found in directory '${info.dir}'.",
+	//	|		{ name: "foo.html", info: { dir: "/temp" } }
+	//	|	);
+	//	example:
+	//		use a transform function to modify the values:
+	//	|	// returns "file 'foo.html' is not found in directory '/temp'."
+	//	|	dojo.string.substitute(
+	//	|		"${0} is not found in ${1}.",
+	//	|		["foo.html","/temp"],
+	//	|		function(str){
+	//	|			// try to figure out the type
+	//	|			var prefix = (str.charAt(0) == "/") ? "directory": "file";
+	//	|			return prefix + " '" + str + "'";
+	//	|		}
+	//	|	);
+	//	example:
+	//		use a formatter
+	//	|	// returns "thinger -- howdy"
+	//	|	dojo.string.substitute(
+	//	|		"${0:postfix}", ["thinger"], null, {
+	//	|			postfix: function(value, key){
+	//	|				return value + " -- howdy";
+	//	|			}
+	//	|		}
+	//	|	);
+
+	thisObject = thisObject||dojo.global;
+	transform = (!transform) ? 
+					function(v){ return v; } : 
+					dojo.hitch(thisObject, transform);
+
+	return template.replace(/\$\{([^\s\:\}]+)(?:\:([^\s\:\}]+))?\}/g, function(match, key, format){
+		var value = dojo.getObject(key, false, map);
+		if(format){
+			value = dojo.getObject(format, false, thisObject).call(thisObject, value, key);
+		}
+		return transform(value, key).toString();
+	}); // string
+};
+
+/*=====
+dojo.string.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 taken from [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript).
+	//		The short yet performant version of this function is dojo.trim(),
+	//		which is part of Dojo base.  Uses String.prototype.trim instead, if available.
+	return "";	// String
+}
+=====*/
+
+dojo.string.trim = String.prototype.trim ?
+	dojo.trim : // aliasing to the native function
+	function(str){
+		str = str.replace(/^\s+/, '');
+		for(var i = str.length - 1; i >= 0; i--){
+			if(/\S/.test(str.charAt(i))){
+				str = str.substring(0, i + 1);
+				break;
+			}
+		}
+		return str;
+	};
+
+}
+
+if(!dojo._hasResource["dojox.lang.utils"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.lang.utils"] = true;
+dojo.provide("dojox.lang.utils");
+
+(function(){
+	var empty = {}, du = dojox.lang.utils;
+
+	var clone = function(o){
+		if(dojo.isArray(o)){
+			return dojo._toArray(o);
+		}
+		if(!dojo.isObject(o) || dojo.isFunction(o)){
+			return o;
+		}
+		return dojo.delegate(o);
+	}
+	
+	dojo.mixin(du, {
+		coerceType: function(target, source){
+			switch(typeof target){
+				case "number":	return Number(eval("(" + source + ")"));
+				case "string":	return String(source);
+				case "boolean":	return Boolean(eval("(" + source + ")"));
+			}
+			return eval("(" + source + ")");
+		},
+		
+		updateWithObject: function(target, source, conv){
+			// summary: updates an existing object in place with properties from an "source" object.
+			// target: Object: the "target" object to be updated
+			// source: Object: the "source" object, whose properties will be used to source the existed object.
+			// conv: Boolean?: force conversion to the original type
+			if(!source){ return target; }
+			for(var x in target){
+				if(x in source && !(x in empty)){
+					var t = target[x];
+					if(t && typeof t == "object"){
+						du.updateWithObject(t, source[x], conv);
+					}else{
+						target[x] = conv ? du.coerceType(t, source[x]) : clone(source[x]);
+					}
+				}
+			}
+			return target;	// Object
+		},
+	
+		updateWithPattern: function(target, source, pattern, conv){
+			// summary: updates an existing object in place with properties from an "source" object.
+			// target: Object: the "target" object to be updated
+			// source: Object: the "source" object, whose properties will be used to source the existed object.
+			// pattern: Array: an array of properties to be copied
+			// conv: Boolean?: force conversion to the original type
+			if(!source || !pattern){ return target; }
+			for(var x in pattern){
+				if(x in source && !(x in empty)){
+					target[x] = conv ? du.coerceType(pattern[x], source[x]) : clone(source[x]);
+				}
+			}
+			return target;	// Object
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.axis2d.Default"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.axis2d.Default"] = true;
+dojo.provide("dojox.charting.axis2d.Default");
+
+
+
+
+
+
+
+
+
+
+
+(function(){
+	var dc = dojox.charting,
+		df = dojox.lang.functional,
+		du = dojox.lang.utils,
+		g = dojox.gfx,
+		lin = dc.scaler.linear,
+		labelGap = 4;	// in pixels
+
+	dojo.declare("dojox.charting.axis2d.Default", dojox.charting.axis2d.Base, {
+		 defaultParams: {
+			vertical:    false,		// true for vertical axis
+			fixUpper:    "none",	// align the upper on ticks: "major", "minor", "micro", "none"
+			fixLower:    "none",	// align the lower on ticks: "major", "minor", "micro", "none"
+			natural:     false,		// all tick marks should be made on natural numbers
+			leftBottom:  true,		// position of the axis, used with "vertical"
+			includeZero: false,		// 0 should be included
+			fixed:       true,		// all labels are fixed numbers
+			majorLabels: true,		// draw major labels
+			minorTicks:  true,		// draw minor ticks
+			minorLabels: true,		// draw minor labels
+			microTicks:  false,		// draw micro ticks
+			htmlLabels:  true		// use HTML to draw labels
+		},
+		optionalParams: {
+			min:			0,	// minimal value on this axis
+			max:			1,	// maximal value on this axis
+			from:			0,	// visible from this value
+			to:				1,	// visible to this value
+			majorTickStep:	4,	// major tick step
+			minorTickStep:	2,	// minor tick step
+			microTickStep:	1,	// micro tick step
+			labels:			[],	// array of labels for major ticks
+								// with corresponding numeric values
+								// ordered by values
+			labelFunc:		null, // function to compute label values
+			maxLabelSize:	0,	// size in px. For use with labelFunc
+
+			// TODO: add support for minRange!
+			// minRange:		1,	// smallest distance from min allowed on the axis
+
+			// theme components
+			stroke:			{},	// stroke for an axis
+			majorTick:		{},	// stroke + length for a tick
+			minorTick:		{},	// stroke + length for a tick
+			microTick:		{},	// stroke + length for a tick
+			font:			"",	// font for labels
+			fontColor:		""	// color for labels as a string
+		},
+
+		constructor: function(chart, kwArgs){
+			this.opt = dojo.delegate(this.defaultParams, kwArgs);
+			// du.updateWithObject(this.opt, kwArgs);
+			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
+		},
+		dependOnData: function(){
+			return !("min" in this.opt) || !("max" in this.opt);
+		},
+		clear: function(){
+			delete this.scaler;
+			delete this.ticks;
+			this.dirty = true;
+			return this;
+		},
+		initialized: function(){
+			return "scaler" in this && !(this.dirty && this.dependOnData());
+		},
+		setWindow: function(scale, offset){
+			this.scale  = scale;
+			this.offset = offset;
+			return this.clear();
+		},
+		getWindowScale: function(){
+			return "scale" in this ? this.scale : 1;
+		},
+		getWindowOffset: function(){
+			return "offset" in this ? this.offset : 0;
+		},
+		calculate: function(min, max, span, labels){
+			if(this.initialized()){ return this; }
+			this.labels = "labels" in this.opt ? this.opt.labels : labels;
+			this.scaler = lin.buildScaler(min, max, span, this.opt);
+			if("scale" in this){
+				// calculate new range
+				this.opt.from = this.scaler.bounds.lower + this.offset;
+				this.opt.to   = (this.scaler.bounds.upper - this.scaler.bounds.lower) / this.scale + this.opt.from;
+				// make sure that bounds are correct
+				if(!isFinite(this.opt.from) || isNaN(this.opt.from) || !isFinite(this.opt.to) || isNaN(this.opt.to) ||
+						this.opt.to - this.opt.from >= this.scaler.bounds.upper - this.scaler.bounds.lower){
+					// any error --- remove from/to bounds
+					delete this.opt.from;
+					delete this.opt.to;
+					delete this.scale;
+					delete this.offset;
+				}else{
+					// shift the window, if we are out of bounds
+					if(this.opt.from < this.scaler.bounds.lower){
+						this.opt.to   += this.scaler.bounds.lower - this.opt.from;
+						this.opt.from  = this.scaler.bounds.lower;
+					}else if(this.opt.to > this.scaler.bounds.upper){
+						this.opt.from += this.scaler.bounds.upper - this.opt.to;
+						this.opt.to    = this.scaler.bounds.upper;
+					}
+					// update the offset
+					this.offset = this.opt.from - this.scaler.bounds.lower;
+				}
+				// re-calculate the scaler
+				this.scaler = lin.buildScaler(min, max, span, this.opt);
+				// cleanup
+				if(this.scale == 1 && this.offset == 0){
+					delete this.scale;
+					delete this.offset;
+				}
+			}
+			var minMinorStep = 0, ta = this.chart.theme.axis,
+				taFont = "font" in this.opt ? this.opt.font : ta.font,
+				size = taFont ? g.normalizedLength(g.splitFontString(taFont).size) : 0;
+			if(this.vertical){
+				if(size){
+					minMinorStep = size + labelGap;
+				}
+			}else{
+				if(size){
+					var labelWidth, i;
+					if(this.opt.labelFunc && this.opt.maxLabelSize){
+						labelWidth = this.opt.maxLabelSize;
+					}else if(this.labels){
+						labelWidth = df.foldl(df.map(this.labels, function(label){
+							return dojox.gfx._base._getTextBox(label.text, {font: taFont}).w;
+						}), "Math.max(a, b)", 0);
+					}else{
+						var labelLength = Math.ceil(Math.log(Math.max(Math.abs(this.scaler.bounds.from),
+								Math.abs(this.scaler.bounds.to))) / Math.LN10),
+							t = [];
+						if(this.scaler.bounds.from < 0 || this.scaler.bounds.to < 0){ t.push("-"); }
+						t.push(dojo.string.rep("9", labelLength));
+						var precision = Math.floor(Math.log(this.scaler.bounds.to - this.scaler.bounds.from) / Math.LN10);
+						if(precision > 0){
+							t.push(".");
+							for(i = 0; i < precision; ++i){ t.push("9"); }
+						}
+						labelWidth = dojox.gfx._base._getTextBox(t.join(""), {font: taFont}).w;
+					}
+					minMinorStep = labelWidth + labelGap;
+				}
+			}
+			this.scaler.minMinorStep = minMinorStep;
+			this.ticks = lin.buildTicks(this.scaler, this.opt);
+			return this;
+		},
+		getScaler: function(){
+			return this.scaler;
+		},
+		getTicks: function(){
+			return this.ticks;
+		},
+		getOffsets: function(){
+			var offsets = {l: 0, r: 0, t: 0, b: 0}, labelWidth, a, b, c, d,
+				gtb = dojox.gfx._base._getTextBox, gl = dc.scaler.common.getNumericLabel,
+				offset = 0, ta = this.chart.theme.axis,
+				taFont = "font" in this.opt ? this.opt.font : ta.font,
+				taMajorTick = "majorTick" in this.opt ? this.opt.majorTick : ta.majorTick,
+				taMinorTick = "minorTick" in this.opt ? this.opt.minorTick : ta.minorTick,
+				size = taFont ? g.normalizedLength(g.splitFontString(taFont).size) : 0,
+				s = this.scaler;
+			if(!s){
+				return offsets;
+			}
+			if(this.vertical){
+				if(size){
+					if(this.opt.labelFunc && this.opt.maxLabelSize){
+						labelWidth = this.opt.maxLabelSize;
+					}else if(this.labels){
+						labelWidth = df.foldl(df.map(this.labels, function(label){
+							return dojox.gfx._base._getTextBox(label.text, {font: taFont}).w;
+						}), "Math.max(a, b)", 0);
+					}else{
+						a = gtb(gl(s.major.start, s.major.prec, this.opt), {font: taFont}).w;
+						b = gtb(gl(s.major.start + s.major.count * s.major.tick, s.major.prec, this.opt), {font: taFont}).w;
+						c = gtb(gl(s.minor.start, s.minor.prec, this.opt), {font: taFont}).w;
+						d = gtb(gl(s.minor.start + s.minor.count * s.minor.tick, s.minor.prec, this.opt), {font: taFont}).w;
+						labelWidth = Math.max(a, b, c, d);
+					}
+					offset = labelWidth + labelGap;
+				}
+				offset += labelGap + Math.max(taMajorTick.length, taMinorTick.length);
+				offsets[this.opt.leftBottom ? "l" : "r"] = offset;
+				offsets.t = offsets.b = size / 2;
+			}else{
+				if(size){
+					offset = size + labelGap;
+				}
+				offset += labelGap + Math.max(taMajorTick.length, taMinorTick.length);
+				offsets[this.opt.leftBottom ? "b" : "t"] = offset;
+				if(size){
+					if(this.opt.labelFunc && this.opt.maxLabelSize){
+						labelWidth = this.opt.maxLabelSize;
+					}else if(this.labels){
+						labelWidth = df.foldl(df.map(this.labels, function(label){
+							return dojox.gfx._base._getTextBox(label.text, {font: taFont}).w;
+						}), "Math.max(a, b)", 0);
+					}else{
+						a = gtb(gl(s.major.start, s.major.prec, this.opt), {font: taFont}).w;
+						b = gtb(gl(s.major.start + s.major.count * s.major.tick, s.major.prec, this.opt), {font: taFont}).w;
+						c = gtb(gl(s.minor.start, s.minor.prec, this.opt), {font: taFont}).w;
+						d = gtb(gl(s.minor.start + s.minor.count * s.minor.tick, s.minor.prec, this.opt), {font: taFont}).w;
+						labelWidth = Math.max(a, b, c, d);
+					}
+					offsets.l = offsets.r = labelWidth / 2;
+				}
+			}
+			return offsets;
+		},
+		render: function(dim, offsets){
+			if(!this.dirty){ return this; }
+			// prepare variable
+			var start, stop, axisVector, tickVector, labelOffset, labelAlign,
+				ta = this.chart.theme.axis,
+				taStroke = "stroke" in this.opt ? this.opt.stroke : ta.stroke,
+				taMajorTick = "majorTick" in this.opt ? this.opt.majorTick : ta.majorTick,
+				taMinorTick = "minorTick" in this.opt ? this.opt.minorTick : ta.minorTick,
+				taMicroTick = "microTick" in this.opt ? this.opt.microTick : ta.minorTick,
+				taFont = "font" in this.opt ? this.opt.font : ta.font,
+				taFontColor = "fontColor" in this.opt ? this.opt.fontColor : ta.fontColor,
+				tickSize = Math.max(taMajorTick.length, taMinorTick.length),
+				size = taFont ? g.normalizedLength(g.splitFontString(taFont).size) : 0;
+			if(this.vertical){
+				start = {y: dim.height - offsets.b};
+				stop  = {y: offsets.t};
+				axisVector = {x: 0, y: -1};
+				if(this.opt.leftBottom){
+					start.x = stop.x = offsets.l;
+					tickVector = {x: -1, y: 0};
+					labelAlign = "end";
+				}else{
+					start.x = stop.x = dim.width - offsets.r;
+					tickVector = {x: 1, y: 0};
+					labelAlign = "start";
+				}
+				labelOffset = {x: tickVector.x * (tickSize + labelGap), y: size * 0.4};
+			}else{
+				start = {x: offsets.l};
+				stop  = {x: dim.width - offsets.r};
+				axisVector = {x: 1, y: 0};
+				labelAlign = "middle";
+				if(this.opt.leftBottom){
+					start.y = stop.y = dim.height - offsets.b;
+					tickVector = {x: 0, y: 1};
+					labelOffset = {y: tickSize + labelGap + size};
+				}else{
+					start.y = stop.y = offsets.t;
+					tickVector = {x: 0, y: -1};
+					labelOffset = {y: -tickSize - labelGap};
+				}
+				labelOffset.x = 0;
+			}
+
+			// render shapes
+
+			this.cleanGroup();
+
+			try{
+				var s = this.group, c = this.scaler, t = this.ticks, canLabel,
+					f = lin.getTransformerFromModel(this.scaler),
+					forceHtmlLabels = dojox.gfx.renderer == "canvas",
+					labelType = forceHtmlLabels || this.opt.htmlLabels && !dojo.isIE && !dojo.isOpera ? "html" : "gfx",
+					dx = tickVector.x * taMajorTick.length,
+					dy = tickVector.y * taMajorTick.length;
+
+				s.createLine({x1: start.x, y1: start.y, x2: stop.x, y2: stop.y}).setStroke(taStroke);
+
+				dojo.forEach(t.major, function(tick){
+					var offset = f(tick.value), elem,
+						x = start.x + axisVector.x * offset,
+						y = start.y + axisVector.y * offset;
+						s.createLine({
+							x1: x, y1: y,
+							x2: x + dx,
+							y2: y + dy
+						}).setStroke(taMajorTick);
+						if(tick.label){
+							elem = dc.axis2d.common.createText[labelType]
+											(this.chart, s, x + labelOffset.x, y + labelOffset.y, labelAlign,
+												tick.label, taFont, taFontColor);
+							if(labelType == "html"){ this.htmlElements.push(elem); }
+						}
+				}, this);
+
+				dx = tickVector.x * taMinorTick.length;
+				dy = tickVector.y * taMinorTick.length;
+				canLabel = c.minMinorStep <= c.minor.tick * c.bounds.scale;
+				dojo.forEach(t.minor, function(tick){
+					var offset = f(tick.value), elem,
+						x = start.x + axisVector.x * offset,
+						y = start.y + axisVector.y * offset;
+						s.createLine({
+							x1: x, y1: y,
+							x2: x + dx,
+							y2: y + dy
+						}).setStroke(taMinorTick);
+						if(canLabel && tick.label){
+							elem = dc.axis2d.common.createText[labelType]
+											(this.chart, s, x + labelOffset.x, y + labelOffset.y, labelAlign,
+												tick.label, taFont, taFontColor);
+							if(labelType == "html"){ this.htmlElements.push(elem); }
+						}
+				}, this);
+
+				dx = tickVector.x * taMicroTick.length;
+				dy = tickVector.y * taMicroTick.length;
+				dojo.forEach(t.micro, function(tick){
+					var offset = f(tick.value), elem,
+						x = start.x + axisVector.x * offset,
+						y = start.y + axisVector.y * offset;
+						s.createLine({
+							x1: x, y1: y,
+							x2: x + dx,
+							y2: y + dy
+						}).setStroke(taMicroTick);
+				}, this);
+			}catch(e){
+				// squelch
+			}
+
+			this.dirty = false;
+			return this;
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.common"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.common"] = true;
+dojo.provide("dojox.charting.plot2d.common");
+
+
+
+
+
+(function(){
+	var df = dojox.lang.functional, dc = dojox.charting.plot2d.common;
+
+	dojo.mixin(dojox.charting.plot2d.common, {
+		makeStroke: function(stroke){
+			if(!stroke){ return stroke; }
+			if(typeof stroke == "string" || stroke instanceof dojo.Color){
+				stroke = {color: stroke};
+			}
+			return dojox.gfx.makeParameters(dojox.gfx.defaultStroke, stroke);
+		},
+		augmentColor: function(target, color){
+			var t = new dojo.Color(target),
+				c = new dojo.Color(color);
+			c.a = t.a;
+			return c;
+		},
+		augmentStroke: function(stroke, color){
+			var s = dc.makeStroke(stroke);
+			if(s){
+				s.color = dc.augmentColor(s.color, color);
+			}
+			return s;
+		},
+		augmentFill: function(fill, color){
+			var fc, c = new dojo.Color(color);
+			if(typeof fill == "string" || fill instanceof dojo.Color){
+				return dc.augmentColor(fill, color);
+			}
+			return fill;
+		},
+
+		defaultStats: {hmin: Number.POSITIVE_INFINITY, hmax: Number.NEGATIVE_INFINITY,
+			vmin: Number.POSITIVE_INFINITY, vmax: Number.NEGATIVE_INFINITY},
+
+		collectSimpleStats: function(series){
+			var stats = dojo.clone(dc.defaultStats);
+			for(var i = 0; i < series.length; ++i){
+				var run = series[i];
+				if(!run.data.length){ continue; }
+				if(typeof run.data[0] == "number"){
+					// 1D case
+					var old_vmin = stats.vmin, old_vmax = stats.vmax;
+					if(!("ymin" in run) || !("ymax" in run)){
+						dojo.forEach(run.data, function(val, i){
+							var x = i + 1, y = val;
+							if(isNaN(y)){ y = 0; }
+							stats.hmin = Math.min(stats.hmin, x);
+							stats.hmax = Math.max(stats.hmax, x);
+							stats.vmin = Math.min(stats.vmin, y);
+							stats.vmax = Math.max(stats.vmax, y);
+						});
+					}
+					if("ymin" in run){ stats.vmin = Math.min(old_vmin, run.ymin); }
+					if("ymax" in run){ stats.vmax = Math.max(old_vmax, run.ymax); }
+				}else{
+					// 2D case
+					var old_hmin = stats.hmin, old_hmax = stats.hmax,
+						old_vmin = stats.vmin, old_vmax = stats.vmax;
+					if(!("xmin" in run) || !("xmax" in run) || !("ymin" in run) || !("ymax" in run)){
+						dojo.forEach(run.data, function(val, i){
+							var x = val.x, y = val.y;
+							if(isNaN(x)){ x = 0; }
+							if(isNaN(y)){ y = 0; }
+							stats.hmin = Math.min(stats.hmin, x);
+							stats.hmax = Math.max(stats.hmax, x);
+							stats.vmin = Math.min(stats.vmin, y);
+							stats.vmax = Math.max(stats.vmax, y);
+						});
+					}
+					if("xmin" in run){ stats.hmin = Math.min(old_hmin, run.xmin); }
+					if("xmax" in run){ stats.hmax = Math.max(old_hmax, run.xmax); }
+					if("ymin" in run){ stats.vmin = Math.min(old_vmin, run.ymin); }
+					if("ymax" in run){ stats.vmax = Math.max(old_vmax, run.ymax); }
+				}
+			}
+			return stats;
+		},
+
+		calculateBarSize: function(/* Number */ availableSize, /* Object */ opt, /* Number? */ clusterSize){
+			if(!clusterSize){
+				clusterSize = 1;
+			}
+			var gap = opt.gap, size = (availableSize - 2 * gap) / clusterSize;
+			if("minBarSize" in opt){
+				size = Math.max(size, opt.minBarSize);
+			}
+			if("maxBarSize" in opt){
+				size = Math.min(size, opt.maxBarSize);
+			}
+			size = Math.max(size, 1);
+			gap = (availableSize - size * clusterSize) / 2;
+			return {size: size, gap: gap};	// Object
+		},
+
+		collectStackedStats: function(series){
+			// collect statistics
+			var stats = dojo.clone(dc.defaultStats);
+			if(series.length){
+				// 1st pass: find the maximal length of runs
+				stats.hmin = Math.min(stats.hmin, 1);
+				stats.hmax = df.foldl(series, "seed, run -> Math.max(seed, run.data.length)", stats.hmax);
+				// 2nd pass: stack values
+				for(var i = 0; i < stats.hmax; ++i){
+					var v = series[0].data[i];
+					if(isNaN(v)){ v = 0; }
+					stats.vmin = Math.min(stats.vmin, v);
+					for(var j = 1; j < series.length; ++j){
+						var t = series[j].data[i];
+						if(isNaN(t)){ t = 0; }
+						v += t;
+					}
+					stats.vmax = Math.max(stats.vmax, v);
+				}
+			}
+			return stats;
+		},
+
+		curve: function(/* Number[] */a, /* Number|String */tension){
+			//	FIX for #7235, submitted by Enzo Michelangeli.
+			//	Emulates the smoothing algorithms used in a famous, unnamed spreadsheet
+			//		program ;)
+			var arr = a.slice(0);
+			if(tension == "x") {
+				arr[arr.length] = arr[0];   // add a last element equal to the first, closing the loop
+			}
+			var p=dojo.map(arr, function(item, i){
+				if(i==0){ return "M" + item.x + "," + item.y; }
+				if(!isNaN(tension)) { // use standard Dojo smoothing in tension is numeric
+					var dx=item.x-arr[i-1].x, dy=arr[i-1].y;
+					return "C"+(item.x-(tension-1)*(dx/tension))+","+dy+" "+(item.x-(dx/tension))+","+item.y+" "+item.x+","+item.y;
+				} else if(tension == "X" || tension == "x" || tension == "S") {
+					// use Excel "line smoothing" algorithm (http://xlrotor.com/resources/files.shtml)
+					var p0, p1 = arr[i-1], p2 = arr[i], p3;
+					var bz1x, bz1y, bz2x, bz2y;
+					var f = 1/6;
+					if(i==1) {
+						if(tension == "x") {
+							p0 = arr[arr.length-2];
+						} else { // "tension == X || tension == "S"
+							p0 = p1;
+						}
+						f = 1/3;
+					} else {
+						p0 = arr[i-2];
+					}
+					if(i==(arr.length-1)) {
+						if(tension == "x") {
+							p3 = arr[1];
+						} else { // "tension == X || tension == "S"
+							p3 = p2;
+						}
+						f = 1/3;
+					} else {
+						p3 = arr[i+1];
+					}
+					var p1p2 = Math.sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));
+					var p0p2 = Math.sqrt((p2.x-p0.x)*(p2.x-p0.x)+(p2.y-p0.y)*(p2.y-p0.y));
+					var p1p3 = Math.sqrt((p3.x-p1.x)*(p3.x-p1.x)+(p3.y-p1.y)*(p3.y-p1.y));
+
+					var p0p2f = p0p2 * f;
+					var p1p3f = p1p3 * f;
+
+					if(p0p2f > p1p2/2 && p1p3f > p1p2/2) {
+						p0p2f = p1p2/2;
+						p1p3f = p1p2/2;
+					} else if(p0p2f > p1p2/2) {
+						p0p2f = p1p2/2;
+						p1p3f = p1p2/2 * p1p3/p0p2;
+					} else if(p1p3f > p1p2/2) {
+						p1p3f = p1p2/2;
+						p0p2f = p1p2/2 * p0p2/p1p3;
+					}
+
+					if(tension == "S") {
+						if(p0 == p1) { p0p2f = 0; }
+						if(p2 == p3) { p1p3f = 0; }
+					}
+
+					bz1x = p1.x + p0p2f*(p2.x - p0.x)/p0p2;
+					bz1y = p1.y + p0p2f*(p2.y - p0.y)/p0p2;
+					bz2x = p2.x - p1p3f*(p3.x - p1.x)/p1p3;
+					bz2y = p2.y - p1p3f*(p3.y - p1.y)/p1p3;
+				}
+				return "C"+(bz1x+","+bz1y+" "+bz2x+","+bz2y+" "+p2.x+","+p2.y);
+			});
+			return p.join(" ");
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.scaler.primitive"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.scaler.primitive"] = true;
+dojo.provide("dojox.charting.scaler.primitive");
+
+dojox.charting.scaler.primitive = {
+	buildScaler: function(/*Number*/ min, /*Number*/ max, /*Number*/ span, /*Object*/ kwArgs){
+		return {
+			bounds: {
+				lower: min,
+				upper: max,
+				from:  min,
+				to:    max,
+				scale: span / (max - min),
+				span:  span
+			},
+			scaler: dojox.charting.scaler.primitive
+		};
+	},
+	buildTicks: function(/*Object*/ scaler, /*Object*/ kwArgs){
+		return {major: [], minor: [], micro: []};	// Object
+	},
+	getTransformerFromModel: function(/*Object*/ scaler){
+		var offset = scaler.bounds.from, scale = scaler.bounds.scale;
+		return function(x){ return (x - offset) * scale; };	// Function
+	},
+	getTransformerFromPlot: function(/*Object*/ scaler){
+		var offset = scaler.bounds.from, scale = scaler.bounds.scale;
+		return function(x){ return x / scale + offset; };	// Function
+	}
+};
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.Base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Base"] = true;
+dojo.provide("dojox.charting.plot2d.Base");
+
+
+
+
+
+dojo.declare("dojox.charting.plot2d.Base", dojox.charting.Element, {
+	destroy: function(){
+		this.resetEvents();
+		this.inherited(arguments);
+	},
+	clear: function(){
+		this.series = [];
+		this._hAxis = null;
+		this._vAxis = null;
+		this.dirty = true;
+		return this;
+	},
+	setAxis: function(axis){
+		if(axis){
+			this[axis.vertical ? "_vAxis" : "_hAxis"] = axis;
+		}
+		return this;
+	},
+	addSeries: function(run){
+		this.series.push(run);
+		return this;
+	},
+	calculateAxes: function(dim){
+		return this;
+	},
+	isDirty: function(){
+		return this.dirty || this._hAxis && this._hAxis.dirty || this._vAxis && this._vAxis.dirty;
+	},
+	render: function(dim, offsets){
+		return this;
+	},
+	getRequiredColors: function(){
+		return this.series.length;
+	},
+
+	// events
+	plotEvent: function(o){
+		// intentionally empty --- used for events
+	},
+	connect: function(object, method){
+		this.dirty = true;
+		return dojo.connect(this, "plotEvent", object, method);
+	},
+	events: function(){
+		var ls = this.plotEvent._listeners;
+		if(!ls || !ls.length){ return false; }
+		for(var i in ls){
+			if(!(i in Array.prototype)){
+				return true;
+			}
+		}
+		return false;
+	},
+	resetEvents: function(){
+		this.plotEvent({type: "onplotreset", plot: this});
+	},
+
+	// utilities
+	_calc: function(dim, stats){
+		// calculate scaler
+		if(this._hAxis){
+			if(!this._hAxis.initialized()){
+				this._hAxis.calculate(stats.hmin, stats.hmax, dim.width);
+			}
+			this._hScaler = this._hAxis.getScaler();
+		}else{
+			this._hScaler = dojox.charting.scaler.primitive.buildScaler(stats.hmin, stats.hmax, dim.width);
+		}
+		if(this._vAxis){
+			if(!this._vAxis.initialized()){
+				this._vAxis.calculate(stats.vmin, stats.vmax, dim.height);
+			}
+			this._vScaler = this._vAxis.getScaler();
+		}else{
+			this._vScaler = dojox.charting.scaler.primitive.buildScaler(stats.vmin, stats.vmax, dim.height);
+		}
+	},
+
+	_connectEvents: function(shape, o){
+		shape.connect("onmouseover", this, function(e){
+			o.type  = "onmouseover";
+			o.event = e;
+			this.plotEvent(o);
+		});
+		shape.connect("onmouseout", this, function(e){
+			o.type  = "onmouseout";
+			o.event = e;
+			this.plotEvent(o);
+		});
+		shape.connect("onclick", this, function(e){
+			o.type  = "onclick";
+			o.event = e;
+			this.plotEvent(o);
+		});
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.Default"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Default"] = true;
+dojo.provide("dojox.charting.plot2d.Default");
+
+
+
+
+
+
+
+
+(function(){
+	var df = dojox.lang.functional, du = dojox.lang.utils,
+		dc = dojox.charting.plot2d.common,
+		purgeGroup = df.lambda("item.purgeGroup()");
+
+	dojo.declare("dojox.charting.plot2d.Default", dojox.charting.plot2d.Base, {
+		defaultParams: {
+			hAxis: "x",		// use a horizontal axis named "x"
+			vAxis: "y",		// use a vertical axis named "y"
+			lines:   true,	// draw lines
+			areas:   false,	// draw areas
+			markers: false,	// draw markers
+			shadows: 0,		// draw shadows
+			tension: 0		// draw curved lines (tension>0)
+		},
+		optionalParams: {},	// no optional parameters
+		
+		constructor: function(chart, kwArgs){
+			this.opt = dojo.clone(this.defaultParams);
+			du.updateWithObject(this.opt, kwArgs);
+			this.series = [];
+			this.hAxis = this.opt.hAxis;
+			this.vAxis = this.opt.vAxis;
+		},
+		
+		calculateAxes: function(dim){
+			this._calc(dim, dc.collectSimpleStats(this.series));
+			return this;
+		},
+		render: function(dim, offsets){
+			this.dirty = this.isDirty();
+			if(this.dirty){
+				dojo.forEach(this.series, purgeGroup);
+				this.cleanGroup();
+				var s = this.group;
+				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
+			}
+			var t = this.chart.theme, stroke, outline, color, marker, events = this.events();
+			this.resetEvents();
+			for(var i = this.series.length - 1; i >= 0; --i){
+				var run = this.series[i];
+				if(!this.dirty && !run.dirty){ continue; }
+				run.cleanGroup();
+				if(!run.data.length){
+					run.dirty = false;
+					continue;
+				}
+
+				var s = run.group, lpoly, 
+					ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
+					vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler);
+				if(typeof run.data[0] == "number"){
+					lpoly = dojo.map(run.data, function(v, i){
+						return {
+							x: ht(i + 1) + offsets.l,
+							y: dim.height - offsets.b - vt(v)
+						};
+					}, this);
+				}else{
+					lpoly = dojo.map(run.data, function(v, i){
+						return {
+							x: ht(v.x) + offsets.l,
+							y: dim.height - offsets.b - vt(v.y)
+						};
+					}, this);
+				}
+				if(!run.fill || !run.stroke){
+					// need autogenerated color
+					color = run.dyn.color = new dojo.Color(t.next("color"));
+				}
+
+				var lpath = this.opt.tension ? dc.curve(lpoly, this.opt.tension) : "";
+
+				if(this.opt.areas){
+					var fill = run.fill ? run.fill : dc.augmentFill(t.series.fill, color);
+					var apoly = dojo.clone(lpoly);
+					if(this.opt.tension){
+						var apath = "L" + apoly[apoly.length-1].x + "," + (dim.height - offsets.b) +
+							" L" + apoly[0].x + "," + (dim.height - offsets.b) +
+							" L" + apoly[0].x + "," + apoly[0].y;
+						run.dyn.fill = s.createPath(lpath + " " + apath).setFill(fill).getFill();
+					} else {
+						apoly.push({x: lpoly[lpoly.length - 1].x, y: dim.height - offsets.b});
+						apoly.push({x: lpoly[0].x, y: dim.height - offsets.b});
+						apoly.push(lpoly[0]);
+						run.dyn.fill = s.createPolyline(apoly).setFill(fill).getFill();
+					}
+				}
+				if(this.opt.lines || this.opt.markers){
+					// need a stroke
+					stroke = run.stroke ? dc.makeStroke(run.stroke) : dc.augmentStroke(t.series.stroke, color);
+					if(run.outline || t.series.outline){
+						outline = dc.makeStroke(run.outline ? run.outline : t.series.outline);
+						outline.width = 2 * outline.width + stroke.width;
+					}
+				}
+				if(this.opt.markers){
+					// need a marker
+					marker = run.dyn.marker = run.marker ? run.marker : t.next("marker");
+				}
+				var frontMarkers = null, outlineMarkers = null, shadowMarkers = null;
+				if(this.opt.shadows && stroke){
+					var sh = this.opt.shadows, shadowColor = new dojo.Color([0, 0, 0, 0.3]),
+						spoly = dojo.map(lpoly, function(c){
+							return {x: c.x + sh.dx, y: c.y + sh.dy};
+						}),
+						shadowStroke = dojo.clone(outline ? outline : stroke);
+					shadowStroke.color = shadowColor;
+					shadowStroke.width += sh.dw ? sh.dw : 0;
+					if(this.opt.lines){
+						if(this.opt.tension){
+							run.dyn.shadow = s.createPath(dc.curve(spoly, this.opt.tension)).setStroke(shadowStroke).getStroke();
+						} else {
+							run.dyn.shadow = s.createPolyline(spoly).setStroke(shadowStroke).getStroke();
+						}
+					}
+					if(this.opt.markers){
+						shadowMarkers = dojo.map(spoly, function(c){
+							return s.createPath("M" + c.x + " " + c.y + " " + marker).
+								setStroke(shadowStroke).setFill(shadowColor);
+						}, this);
+					}
+				}
+				if(this.opt.lines){
+					if(outline){
+						if(this.opt.tension){
+							run.dyn.outline = s.createPath(lpath).setStroke(outline).getStroke();
+						} else {
+							run.dyn.outline = s.createPolyline(lpoly).setStroke(outline).getStroke();
+						}
+					}
+					if(this.opt.tension){
+						run.dyn.stroke = s.createPath(lpath).setStroke(stroke).getStroke();
+					} else {
+						run.dyn.stroke = s.createPolyline(lpoly).setStroke(stroke).getStroke();
+					}
+				}
+				if(this.opt.markers){
+					frontMarkers = new Array(lpoly.length);
+					outlineMarkers = new Array(lpoly.length);
+					dojo.forEach(lpoly, function(c, i){
+						var path = "M" + c.x + " " + c.y + " " + marker;
+						if(outline){
+							outlineMarkers[i] = s.createPath(path).setStroke(outline);
+						}
+						frontMarkers[i] = s.createPath(path).setStroke(stroke).setFill(stroke.color);
+					}, this);
+					if(events){
+						dojo.forEach(frontMarkers, function(s, i){
+							var o = {
+								element: "marker",
+								index:   i,
+								run:     run,
+								plot:    this,
+								hAxis:   this.hAxis || null,
+								vAxis:   this.vAxis || null,
+								shape:   s,
+								outline: outlineMarkers[i] || null,
+								shadow:  shadowMarkers && shadowMarkers[i] || null,
+								cx:      lpoly[i].x,
+								cy:      lpoly[i].y
+							};
+							if(typeof run.data[0] == "number"){
+								o.x = i + 1;
+								o.y = run.data[i];
+							}else{
+								o.x = run.data[i].x;
+								o.y = run.data[i].y;
+							}
+							this._connectEvents(s, o);
+						}, this);
+					}
+				}
+				run.dirty = false;
+			}
+			this.dirty = false;
+			return this;
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.Lines"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Lines"] = true;
+dojo.provide("dojox.charting.plot2d.Lines");
+
+
+
+dojo.declare("dojox.charting.plot2d.Lines", dojox.charting.plot2d.Default, {
+	constructor: function(){
+		this.opt.lines = true;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.Areas"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Areas"] = true;
+dojo.provide("dojox.charting.plot2d.Areas");
+
+
+
+dojo.declare("dojox.charting.plot2d.Areas", dojox.charting.plot2d.Default, {
+	constructor: function(){
+		this.opt.lines = true;
+		this.opt.areas = true;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.Markers"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Markers"] = true;
+dojo.provide("dojox.charting.plot2d.Markers");
+
+
+
+dojo.declare("dojox.charting.plot2d.Markers", dojox.charting.plot2d.Default, {
+	constructor: function(){
+		this.opt.markers = true;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.MarkersOnly"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.MarkersOnly"] = true;
+dojo.provide("dojox.charting.plot2d.MarkersOnly");
+
+
+
+dojo.declare("dojox.charting.plot2d.MarkersOnly", dojox.charting.plot2d.Default, {
+	constructor: function(){
+		this.opt.lines   = false;
+		this.opt.markers = true;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.Scatter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Scatter"] = true;
+dojo.provide("dojox.charting.plot2d.Scatter");
+
+
+
+dojo.declare("dojox.charting.plot2d.Scatter", dojox.charting.plot2d.Default, {
+	constructor: function(){
+		this.opt.lines   = false;
+		this.opt.markers = true;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.lang.functional.sequence"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.lang.functional.sequence"] = true;
+dojo.provide("dojox.lang.functional.sequence");
+
+
+
+// This module adds high-level functions and related constructs:
+//	- sequence generators
+
+// If you want more general sequence builders check out listcomp.js and
+// unfold() (in fold.js).
+
+// Defined methods:
+//	- take any valid lambda argument as the functional argument
+
+(function(){
+	var d = dojo, df = dojox.lang.functional;
+
+	d.mixin(df, {
+		// sequence generators
+		repeat: function(/*Number*/ n, /*Function|String|Array*/ f, /*Object*/ z, /*Object?*/ o){
+			// summary: builds an array by repeatedly applying a unary function N times
+			//	with a seed value Z. N should be greater than 0.
+			o = o || d.global; f = df.lambda(f);
+			var t = new Array(n), i = 1;
+			t[0] = z;
+			for(; i < n; t[i] = z = f.call(o, z), ++i);
+			return t;	// Array
+		},
+		until: function(/*Function|String|Array*/ pr, /*Function|String|Array*/ f, /*Object*/ z, /*Object?*/ o){
+			// summary: builds an array by repeatedly applying a unary function with
+			//	a seed value Z until the predicate is satisfied.
+			o = o || d.global; f = df.lambda(f); pr = df.lambda(pr);
+			var t = [];
+			for(; !pr.call(o, z); t.push(z), z = f.call(o, z));
+			return t;	// Array
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.Stacked"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Stacked"] = true;
+dojo.provide("dojox.charting.plot2d.Stacked");
+
+
+
+
+
+
+
+
+(function(){
+	var df = dojox.lang.functional, dc = dojox.charting.plot2d.common,
+		purgeGroup = df.lambda("item.purgeGroup()");
+
+	dojo.declare("dojox.charting.plot2d.Stacked", dojox.charting.plot2d.Default, {
+		calculateAxes: function(dim){
+			var stats = dc.collectStackedStats(this.series);
+			this._maxRunLength = stats.hmax;
+			this._calc(dim, stats);
+			return this;
+		},
+		render: function(dim, offsets){
+			if(this._maxRunLength <= 0){
+				return this;
+			}
+
+			// stack all values
+			var acc = df.repeat(this._maxRunLength, "-> 0", 0);
+			for(var i = 0; i < this.series.length; ++i){
+				var run = this.series[i];
+				for(var j = 0; j < run.data.length; ++j){
+					var v = run.data[j];
+					if(isNaN(v)){ v = 0; }
+					acc[j] += v;
+				}
+			}
+			// draw runs in backwards
+			this.dirty = this.isDirty();
+			if(this.dirty){
+				dojo.forEach(this.series, purgeGroup);
+				this.cleanGroup();
+				var s = this.group;
+				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
+			}
+
+			var t = this.chart.theme, stroke, outline, color, marker, events = this.events(),
+				ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
+				vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler);
+			this.resetEvents();
+
+			for(var i = this.series.length - 1; i >= 0; --i){
+				var run = this.series[i];
+				if(!this.dirty && !run.dirty){ continue; }
+				run.cleanGroup();
+				var s = run.group,
+					lpoly = dojo.map(acc, function(v, i){
+						return {
+							x: ht(i + 1) + offsets.l,
+							y: dim.height - offsets.b - vt(v)
+						};
+					}, this);
+				if(!run.fill || !run.stroke){
+					// need autogenerated color
+					color = new dojo.Color(t.next("color"));
+				}
+
+				var lpath = this.opt.tension ? dc.curve(lpoly, this.opt.tension) : "";
+				
+				if(this.opt.areas){
+					var apoly = dojo.clone(lpoly);
+					var fill = run.fill ? run.fill : dc.augmentFill(t.series.fill, color);
+					if(this.opt.tension){
+						var p=dc.curve(apoly, this.opt.tension);
+						p += " L" + lpoly[lpoly.length - 1].x + "," + (dim.height - offsets.b) +
+							" L" + lpoly[0].x + "," + (dim.height - offsets.b) +
+							" L" + lpoly[0].x + "," + lpoly[0].y;
+						run.dyn.fill = s.createPath(p).setFill(fill).getFill();
+					} else {
+						apoly.push({x: lpoly[lpoly.length - 1].x, y: dim.height - offsets.b});
+						apoly.push({x: lpoly[0].x, y: dim.height - offsets.b});
+						apoly.push(lpoly[0]);
+						run.dyn.fill = s.createPolyline(apoly).setFill(fill).getFill();
+					}
+				}
+				if(this.opt.lines || this.opt.markers){
+					// need a stroke
+					stroke = run.stroke ? dc.makeStroke(run.stroke) : dc.augmentStroke(t.series.stroke, color);
+					if(run.outline || t.series.outline){
+						outline = dc.makeStroke(run.outline ? run.outline : t.series.outline);
+						outline.width = 2 * outline.width + stroke.width;
+					}
+				}
+				if(this.opt.markers){
+					// need a marker
+					marker = run.dyn.marker = run.marker ? run.marker : t.next("marker");
+				}
+				var frontMarkers, outlineMarkers, shadowMarkers;
+				if(this.opt.shadows && stroke){
+					var sh = this.opt.shadows, shadowColor = new dojo.Color([0, 0, 0, 0.3]),
+						spoly = dojo.map(lpoly, function(c){
+							return {x: c.x + sh.dx, y: c.y + sh.dy};
+						}),
+						shadowStroke = dojo.clone(outline ? outline : stroke);
+					shadowStroke.color = shadowColor;
+					shadowStroke.width += sh.dw ? sh.dw : 0;
+					if(this.opt.lines){
+						if(this.opt.tension){
+							run.dyn.shadow = s.createPath(dc.curve(spoly, this.opt.tension)).setStroke(shadowStroke).getStroke();
+						} else {
+							run.dyn.shadow = s.createPolyline(spoly).setStroke(shadowStroke).getStroke();
+						}
+					}
+					if(this.opt.markers){
+						shadowMarkers = dojo.map(spoly, function(c){
+							return s.createPath("M" + c.x + " " + c.y + " " + marker).
+								setStroke(shadowStroke).setFill(shadowColor);
+						}, this);
+					}
+				}
+				if(this.opt.lines){
+					if(outline){
+						if(this.opt.tension){
+							run.dyn.outline = s.createPath(lpath).setStroke(outline).getStroke();
+						} else {
+							run.dyn.outline = s.createPolyline(lpoly).setStroke(outline).getStroke();
+						}
+					}
+					if(this.opt.tension){
+						run.dyn.stroke = s.createPath(lpath).setStroke(stroke).getStroke();
+					} else {
+						run.dyn.stroke = s.createPolyline(lpoly).setStroke(stroke).getStroke();
+					}
+				}
+				if(this.opt.markers){
+					frontMarkers = new Array(lpoly.length);
+					outlineMarkers = new Array(lpoly.length);
+					dojo.forEach(lpoly, function(c, i){
+						var path = "M" + c.x + " " + c.y + " " + marker;
+						if(outline){
+							outlineMarkers[i] = s.createPath(path).setStroke(outline);
+						}
+						frontMarkers[i] = s.createPath(path).setStroke(stroke).setFill(stroke.color);
+					}, this);
+					if(events){
+						dojo.forEach(frontMarkers, function(s, i){
+							var o = {
+								element: "marker",
+								index:   i,
+								run:     run,
+								plot:    this,
+								hAxis:   this.hAxis || null,
+								vAxis:   this.vAxis || null,
+								shape:   s,
+								outline: outlineMarkers[i] || null,
+								shadow:  shadowMarkers && shadowMarkers[i] || null,
+								cx:      lpoly[i].x,
+								cy:      lpoly[i].y,
+								x:       i + 1,
+								y:       run.data[i]
+							};
+							this._connectEvents(s, o);
+						}, this);
+					}
+				}
+				run.dirty = false;
+				// update the accumulator
+				for(var j = 0; j < run.data.length; ++j){
+					var v = run.data[j];
+					if(isNaN(v)){ v = 0; }
+					acc[j] -= v;
+				}
+			}
+			this.dirty = false;
+			return this;
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.StackedLines"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.StackedLines"] = true;
+dojo.provide("dojox.charting.plot2d.StackedLines");
+
+
+
+dojo.declare("dojox.charting.plot2d.StackedLines", dojox.charting.plot2d.Stacked, {
+	constructor: function(){
+		this.opt.lines = true;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.StackedAreas"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.StackedAreas"] = true;
+dojo.provide("dojox.charting.plot2d.StackedAreas");
+
+
+
+dojo.declare("dojox.charting.plot2d.StackedAreas", dojox.charting.plot2d.Stacked, {
+	constructor: function(){
+		this.opt.lines = true;
+		this.opt.areas = true;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.Columns"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Columns"] = true;
+dojo.provide("dojox.charting.plot2d.Columns");
+
+
+
+
+
+
+
+
+(function(){
+	var df = dojox.lang.functional, du = dojox.lang.utils,
+		dc = dojox.charting.plot2d.common,
+		purgeGroup = df.lambda("item.purgeGroup()");
+
+	dojo.declare("dojox.charting.plot2d.Columns", dojox.charting.plot2d.Base, {
+		defaultParams: {
+			hAxis: "x",		// use a horizontal axis named "x"
+			vAxis: "y",		// use a vertical axis named "y"
+			gap:	0,		// gap between columns in pixels
+			shadows: null	// draw shadows
+		},
+		optionalParams: {
+			minBarSize: 1,	// minimal bar size in pixels
+			maxBarSize: 1	// maximal bar size in pixels
+		},
+
+		constructor: function(chart, kwArgs){
+			this.opt = dojo.clone(this.defaultParams);
+			du.updateWithObject(this.opt, kwArgs);
+			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
+			this.series = [];
+			this.hAxis = this.opt.hAxis;
+			this.vAxis = this.opt.vAxis;
+		},
+
+		calculateAxes: function(dim){
+			var stats = dc.collectSimpleStats(this.series);
+			stats.hmin -= 0.5;
+			stats.hmax += 0.5;
+			this._calc(dim, stats);
+			return this;
+		},
+		render: function(dim, offsets){
+			this.dirty = this.isDirty();
+			if(this.dirty){
+				dojo.forEach(this.series, purgeGroup);
+				this.cleanGroup();
+				var s = this.group;
+				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
+			}
+			var t = this.chart.theme, color, stroke, fill, f, gap, width,
+				ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
+				vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
+				baseline = Math.max(0, this._vScaler.bounds.lower),
+				baselineHeight = vt(baseline),
+				events = this.events();
+			f = dc.calculateBarSize(this._hScaler.bounds.scale, this.opt);
+			gap = f.gap;
+			width = f.size;
+			this.resetEvents();
+			for(var i = this.series.length - 1; i >= 0; --i){
+				var run = this.series[i];
+				if(!this.dirty && !run.dirty){ continue; }
+				run.cleanGroup();
+				var s = run.group;
+				if(!run.fill || !run.stroke){
+					// need autogenerated color
+					color = run.dyn.color = new dojo.Color(t.next("color"));
+				}
+				stroke = run.stroke ? run.stroke : dc.augmentStroke(t.series.stroke, color);
+				fill = run.fill ? run.fill : dc.augmentFill(t.series.fill, color);
+				for(var j = 0; j < run.data.length; ++j){
+					var v = run.data[j],
+						vv = vt(v),
+						height = vv - baselineHeight,
+						h = Math.abs(height);
+					if(width >= 1 && h >= 1){
+						var rect = {
+								x: offsets.l + ht(j + 0.5) + gap,
+								y: dim.height - offsets.b - (v > baseline ? vv : baselineHeight),
+								width: width, height: h
+							},
+							shape = s.createRect(rect).setFill(fill).setStroke(stroke);
+						run.dyn.fill   = shape.getFill();
+						run.dyn.stroke = shape.getStroke();
+						if(events){
+							var o = {
+								element: "column",
+								index:   j,
+								run:     run,
+								plot:    this,
+								hAxis:   this.hAxis || null,
+								vAxis:   this.vAxis || null,
+								shape:   shape,
+								x:       j + 0.5,
+								y:       v
+							};
+							this._connectEvents(shape, o);
+						}
+					}
+				}
+				run.dirty = false;
+			}
+			this.dirty = false;
+			return this;
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.StackedColumns"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.StackedColumns"] = true;
+dojo.provide("dojox.charting.plot2d.StackedColumns");
+
+
+
+
+
+
+
+(function(){
+	var df = dojox.lang.functional, dc = dojox.charting.plot2d.common,
+		purgeGroup = df.lambda("item.purgeGroup()");
+
+	dojo.declare("dojox.charting.plot2d.StackedColumns", dojox.charting.plot2d.Columns, {
+		calculateAxes: function(dim){
+			var stats = dc.collectStackedStats(this.series);
+			this._maxRunLength = stats.hmax;
+			stats.hmin -= 0.5;
+			stats.hmax += 0.5;
+			this._calc(dim, stats);
+			return this;
+		},
+		render: function(dim, offsets){
+			if(this._maxRunLength <= 0){
+				return this;
+			}
+
+			// stack all values
+			var acc = df.repeat(this._maxRunLength, "-> 0", 0);
+			for(var i = 0; i < this.series.length; ++i){
+				var run = this.series[i];
+				for(var j = 0; j < run.data.length; ++j){
+					var v = run.data[j];
+					if(isNaN(v)){ v = 0; }
+					acc[j] += v;
+				}
+			}
+			// draw runs in backwards
+			this.dirty = this.isDirty();
+			if(this.dirty){
+				dojo.forEach(this.series, purgeGroup);
+				this.cleanGroup();
+				var s = this.group;
+				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
+			}
+			var t = this.chart.theme, color, stroke, fill, f, gap, width,
+				ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
+				vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
+				events = this.events();
+			f = dc.calculateBarSize(this._hScaler.bounds.scale, this.opt);
+			gap = f.gap;
+			width = f.size;
+			this.resetEvents();
+			for(var i = this.series.length - 1; i >= 0; --i){
+				var run = this.series[i];
+				if(!this.dirty && !run.dirty){ continue; }
+				run.cleanGroup();
+				var s = run.group;
+				if(!run.fill || !run.stroke){
+					// need autogenerated color
+					color = run.dyn.color = new dojo.Color(t.next("color"));
+				}
+				stroke = run.stroke ? run.stroke : dc.augmentStroke(t.series.stroke, color);
+				fill = run.fill ? run.fill : dc.augmentFill(t.series.fill, color);
+				for(var j = 0; j < acc.length; ++j){
+					var v = acc[j],
+						height = vt(v);
+					if(width >= 1 && height >= 1){
+						var shape = s.createRect({
+							x: offsets.l + ht(j + 0.5) + gap,
+							y: dim.height - offsets.b - vt(v),
+							width: width, height: height
+						}).setFill(fill).setStroke(stroke);
+						run.dyn.fill   = shape.getFill();
+						run.dyn.stroke = shape.getStroke();
+						if(events){
+							var o = {
+								element: "column",
+								index:   j,
+								run:     run,
+								plot:    this,
+								hAxis:   this.hAxis || null,
+								vAxis:   this.vAxis || null,
+								shape:   shape,
+								x:       j + 0.5,
+								y:       v
+							};
+							this._connectEvents(shape, o);
+						}
+					}
+				}
+				run.dirty = false;
+				// update the accumulator
+				for(var j = 0; j < run.data.length; ++j){
+					var v = run.data[j];
+					if(isNaN(v)){ v = 0; }
+					acc[j] -= v;
+				}
+			}
+			this.dirty = false;
+			return this;
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.ClusteredColumns"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.ClusteredColumns"] = true;
+dojo.provide("dojox.charting.plot2d.ClusteredColumns");
+
+
+
+
+
+
+
+(function(){
+	var df = dojox.lang.functional, dc = dojox.charting.plot2d.common,
+		purgeGroup = df.lambda("item.purgeGroup()");
+
+	dojo.declare("dojox.charting.plot2d.ClusteredColumns", dojox.charting.plot2d.Columns, {
+		render: function(dim, offsets){
+			this.dirty = this.isDirty();
+			if(this.dirty){
+				dojo.forEach(this.series, purgeGroup);
+				this.cleanGroup();
+				var s = this.group;
+				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
+			}
+			var t = this.chart.theme, color, stroke, fill, f, gap, width, thickness,
+				ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
+				vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
+				baseline = Math.max(0, this._vScaler.bounds.lower),
+				baselineHeight = vt(baseline),
+				events = this.events();
+			f = dc.calculateBarSize(this._hScaler.bounds.scale, this.opt, this.series.length);
+			gap = f.gap;
+			width = thickness = f.size;
+			this.resetEvents();
+			for(var i = 0; i < this.series.length; ++i){
+				var run = this.series[i], shift = thickness * i;
+				if(!this.dirty && !run.dirty){ continue; }
+				run.cleanGroup();
+				var s = run.group;
+				if(!run.fill || !run.stroke){
+					// need autogenerated color
+					color = run.dyn.color = new dojo.Color(t.next("color"));
+				}
+				stroke = run.stroke ? run.stroke : dc.augmentStroke(t.series.stroke, color);
+				fill = run.fill ? run.fill : dc.augmentFill(t.series.fill, color);
+				for(var j = 0; j < run.data.length; ++j){
+					var v = run.data[j],
+						vv = vt(v),
+						height = vv - baselineHeight,
+						h = Math.abs(height);
+					if(width >= 1 && h >= 1){
+						var shape = s.createRect({
+							x: offsets.l + ht(j + 0.5) + gap + shift,
+							y: dim.height - offsets.b - (v > baseline ? vv : baselineHeight),
+							width: width, height: h
+						}).setFill(fill).setStroke(stroke);
+						run.dyn.fill   = shape.getFill();
+						run.dyn.stroke = shape.getStroke();
+						if(events){
+							var o = {
+								element: "column",
+								index:   j,
+								run:     run,
+								plot:    this,
+								hAxis:   this.hAxis || null,
+								vAxis:   this.vAxis || null,
+								shape:   shape,
+								x:       j + 0.5,
+								y:       v
+							};
+							this._connectEvents(shape, o);
+						}
+					}
+				}
+				run.dirty = false;
+			}
+			this.dirty = false;
+			return this;
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.Bars"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Bars"] = true;
+dojo.provide("dojox.charting.plot2d.Bars");
+
+
+
+
+
+
+
+
+(function(){
+	var df = dojox.lang.functional, du = dojox.lang.utils,
+		dc = dojox.charting.plot2d.common,
+		purgeGroup = df.lambda("item.purgeGroup()");
+
+	dojo.declare("dojox.charting.plot2d.Bars", dojox.charting.plot2d.Base, {
+		defaultParams: {
+			hAxis: "x",		// use a horizontal axis named "x"
+			vAxis: "y",		// use a vertical axis named "y"
+			gap:	0,		// gap between columns in pixels
+			shadows: null	// draw shadows
+		},
+		optionalParams: {
+			minBarSize: 1,	// minimal bar size in pixels
+			maxBarSize: 1	// maximal bar size in pixels
+		},
+
+		constructor: function(chart, kwArgs){
+			this.opt = dojo.clone(this.defaultParams);
+			du.updateWithObject(this.opt, kwArgs);
+			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
+			this.series = [];
+			this.hAxis = this.opt.hAxis;
+			this.vAxis = this.opt.vAxis;
+		},
+
+		calculateAxes: function(dim){
+			var stats = dc.collectSimpleStats(this.series), t;
+			stats.hmin -= 0.5;
+			stats.hmax += 0.5;
+			t = stats.hmin, stats.hmin = stats.vmin, stats.vmin = t;
+			t = stats.hmax, stats.hmax = stats.vmax, stats.vmax = t;
+			this._calc(dim, stats);
+			return this;
+		},
+		render: function(dim, offsets){
+			this.dirty = this.isDirty();
+			if(this.dirty){
+				dojo.forEach(this.series, purgeGroup);
+				this.cleanGroup();
+				var s = this.group;
+				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
+			}
+			var t = this.chart.theme, color, stroke, fill, f, gap, height,
+				ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
+				vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
+				baseline = Math.max(0, this._hScaler.bounds.lower),
+				baselineWidth = ht(baseline),
+				events = this.events();
+			f = dc.calculateBarSize(this._vScaler.bounds.scale, this.opt);
+			gap = f.gap;
+			height = f.size;
+			this.resetEvents();
+			for(var i = this.series.length - 1; i >= 0; --i){
+				var run = this.series[i];
+				if(!this.dirty && !run.dirty){ continue; }
+				run.cleanGroup();
+				var s = run.group;
+				if(!run.fill || !run.stroke){
+					// need autogenerated color
+					color = run.dyn.color = new dojo.Color(t.next("color"));
+				}
+				stroke = run.stroke ? run.stroke : dc.augmentStroke(t.series.stroke, color);
+				fill = run.fill ? run.fill : dc.augmentFill(t.series.fill, color);
+				for(var j = 0; j < run.data.length; ++j){
+					var v = run.data[j],
+						hv = ht(v),
+						width = hv - baselineWidth,
+						w = Math.abs(width);
+					if(w >= 1 && height >= 1){
+						var shape = s.createRect({
+							x: offsets.l + (v < baseline ? hv : baselineWidth),
+							y: dim.height - offsets.b - vt(j + 1.5) + gap,
+							width: w, height: height
+						}).setFill(fill).setStroke(stroke);
+						run.dyn.fill   = shape.getFill();
+						run.dyn.stroke = shape.getStroke();
+						if(events){
+							var o = {
+								element: "bar",
+								index:   j,
+								run:     run,
+								plot:    this,
+								hAxis:   this.hAxis || null,
+								vAxis:   this.vAxis || null,
+								shape:   shape,
+								x:       v,
+								y:       j + 1.5
+							};
+							this._connectEvents(shape, o);
+						}
+					}
+				}
+				run.dirty = false;
+			}
+			this.dirty = false;
+			return this;
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.StackedBars"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.StackedBars"] = true;
+dojo.provide("dojox.charting.plot2d.StackedBars");
+
+
+
+
+
+
+
+(function(){
+	var df = dojox.lang.functional, dc = dojox.charting.plot2d.common,
+		purgeGroup = df.lambda("item.purgeGroup()");
+
+	dojo.declare("dojox.charting.plot2d.StackedBars", dojox.charting.plot2d.Bars, {
+		calculateAxes: function(dim){
+			var stats = dc.collectStackedStats(this.series), t;
+			this._maxRunLength = stats.hmax;
+			stats.hmin -= 0.5;
+			stats.hmax += 0.5;
+			t = stats.hmin, stats.hmin = stats.vmin, stats.vmin = t;
+			t = stats.hmax, stats.hmax = stats.vmax, stats.vmax = t;
+			this._calc(dim, stats);
+			return this;
+		},
+		render: function(dim, offsets){
+			if(this._maxRunLength <= 0){
+				return this;
+			}
+
+			// stack all values
+			var acc = df.repeat(this._maxRunLength, "-> 0", 0);
+			for(var i = 0; i < this.series.length; ++i){
+				var run = this.series[i];
+				for(var j = 0; j < run.data.length; ++j){
+					var v = run.data[j];
+					if(isNaN(v)){ v = 0; }
+					acc[j] += v;
+				}
+			}
+			// draw runs in backwards
+			this.dirty = this.isDirty();
+			if(this.dirty){
+				dojo.forEach(this.series, purgeGroup);
+				this.cleanGroup();
+				var s = this.group;
+				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
+			}
+			var t = this.chart.theme, color, stroke, fill, f, gap, height,
+				ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
+				vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
+				events = this.events();
+			f = dc.calculateBarSize(this._vScaler.bounds.scale, this.opt);
+			gap = f.gap;
+			height = f.size;
+			this.resetEvents();
+			for(var i = this.series.length - 1; i >= 0; --i){
+				var run = this.series[i];
+				if(!this.dirty && !run.dirty){ continue; }
+				run.cleanGroup();
+				var s = run.group;
+				if(!run.fill || !run.stroke){
+					// need autogenerated color
+					color = run.dyn.color = new dojo.Color(t.next("color"));
+				}
+				stroke = run.stroke ? run.stroke : dc.augmentStroke(t.series.stroke, color);
+				fill = run.fill ? run.fill : dc.augmentFill(t.series.fill, color);
+				for(var j = 0; j < acc.length; ++j){
+					var v = acc[j],
+						width  = ht(v);
+					if(width >= 1 && height >= 1){
+						var shape = s.createRect({
+							x: offsets.l,
+							y: dim.height - offsets.b - vt(j + 1.5) + gap,
+							width: width, height: height
+						}).setFill(fill).setStroke(stroke);
+						run.dyn.fill   = shape.getFill();
+						run.dyn.stroke = shape.getStroke();
+						if(events){
+							var o = {
+								element: "bar",
+								index:   j,
+								run:     run,
+								plot:    this,
+								hAxis:   this.hAxis || null,
+								vAxis:   this.vAxis || null,
+								shape:   shape,
+								x:       v,
+								y:       j + 1.5
+							};
+							this._connectEvents(shape, o);
+						}
+					}
+				}
+				run.dirty = false;
+				// update the accumulator
+				for(var j = 0; j < run.data.length; ++j){
+					var v = run.data[j];
+					if(isNaN(v)){ v = 0; }
+					acc[j] -= v;
+				}
+			}
+			this.dirty = false;
+			return this;
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.ClusteredBars"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.ClusteredBars"] = true;
+dojo.provide("dojox.charting.plot2d.ClusteredBars");
+
+
+
+
+
+
+
+(function(){
+	var df = dojox.lang.functional, dc = dojox.charting.plot2d.common,
+		purgeGroup = df.lambda("item.purgeGroup()");
+
+	dojo.declare("dojox.charting.plot2d.ClusteredBars", dojox.charting.plot2d.Bars, {
+		render: function(dim, offsets){
+			this.dirty = this.isDirty();
+			if(this.dirty){
+				dojo.forEach(this.series, purgeGroup);
+				this.cleanGroup();
+				var s = this.group;
+				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
+			}
+			var t = this.chart.theme, color, stroke, fill, f, gap, height, thickness,
+				ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
+				vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
+				baseline = Math.max(0, this._hScaler.bounds.lower),
+				baselineWidth = ht(baseline),
+				events = this.events();
+			f = dc.calculateBarSize(this._vScaler.bounds.scale, this.opt, this.series.length);
+			gap = f.gap;
+			height = thickness = f.size;
+			this.resetEvents();
+			for(var i = this.series.length - 1; i >= 0; --i){
+				var run = this.series[i], shift = thickness * (this.series.length - i - 1);
+				if(!this.dirty && !run.dirty){ continue; }
+				run.cleanGroup();
+				var s = run.group;
+				if(!run.fill || !run.stroke){
+					// need autogenerated color
+					color = run.dyn.color = new dojo.Color(t.next("color"));
+				}
+				stroke = run.stroke ? run.stroke : dc.augmentStroke(t.series.stroke, color);
+				fill = run.fill ? run.fill : dc.augmentFill(t.series.fill, color);
+				for(var j = 0; j < run.data.length; ++j){
+					var v = run.data[j],
+						hv = ht(v),
+						width = hv - baselineWidth,
+						w = Math.abs(width);
+					if(w >= 1 && height >= 1){
+						var shape = s.createRect({
+							x: offsets.l + (v < baseline ? hv : baselineWidth),
+							y: dim.height - offsets.b - vt(j + 1.5) + gap + shift,
+							width: w, height: height
+						}).setFill(fill).setStroke(stroke);
+						run.dyn.fill   = shape.getFill();
+						run.dyn.stroke = shape.getStroke();
+						if(events){
+							var o = {
+								element: "bar",
+								index:   j,
+								run:     run,
+								plot:    this,
+								hAxis:   this.hAxis || null,
+								vAxis:   this.vAxis || null,
+								shape:   shape,
+								x:       v,
+								y:       j + 1.5
+							};
+							this._connectEvents(shape, o);
+						}
+					}
+				}
+				run.dirty = false;
+			}
+			this.dirty = false;
+			return this;
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.Grid"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Grid"] = true;
+dojo.provide("dojox.charting.plot2d.Grid");
+
+
+
+
+
+(function(){
+	var du = dojox.lang.utils;
+
+	dojo.declare("dojox.charting.plot2d.Grid", dojox.charting.Element, {
+		defaultParams: {
+			hAxis: "x",			// use a horizontal axis named "x"
+			vAxis: "y",			// use a vertical axis named "y"
+			hMajorLines: true,	// draw horizontal major lines
+			hMinorLines: false,	// draw horizontal minor lines
+			vMajorLines: true,	// draw vertical major lines
+			vMinorLines: false,	// draw vertical minor lines
+			hStripes: "none",	// TBD
+			vStripes: "none"	// TBD
+		},
+		optionalParams: {},	// no optional parameters
+
+		constructor: function(chart, kwArgs){
+			this.opt = dojo.clone(this.defaultParams);
+			du.updateWithObject(this.opt, kwArgs);
+			this.hAxis = this.opt.hAxis;
+			this.vAxis = this.opt.vAxis;
+			this.dirty = true;
+		},
+		clear: function(){
+			this._hAxis = null;
+			this._vAxis = null;
+			this.dirty = true;
+			return this;
+		},
+		setAxis: function(axis){
+			if(axis){
+				this[axis.vertical ? "_vAxis" : "_hAxis"] = axis;
+			}
+			return this;
+		},
+		addSeries: function(run){
+			// nothing
+			return this;
+		},
+		calculateAxes: function(dim){
+			// nothing
+			return this;
+		},
+		isDirty: function(){
+			return this.dirty || this._hAxis && this._hAxis.dirty || this._vAxis && this._vAxis.dirty;
+		},
+		getRequiredColors: function(){
+			return 0;
+		},
+		render: function(dim, offsets){
+			this.dirty = this.isDirty();
+			if(!this.dirty){ return this; }
+			this.cleanGroup();
+			var s = this.group, ta = this.chart.theme.axis;
+			// draw horizontal stripes and lines
+			try{
+				var vScaler = this._vAxis.getScaler(),
+					vt = vScaler.scaler.getTransformerFromModel(vScaler),
+					ticks = this._vAxis.getTicks();
+				if(this.opt.hMinorLines){
+					dojo.forEach(ticks.minor, function(tick){
+						var y = dim.height - offsets.b - vt(tick.value);
+						s.createLine({
+							x1: offsets.l,
+							y1: y,
+							x2: dim.width - offsets.r,
+							y2: y
+						}).setStroke(ta.minorTick);
+					});
+				}
+				if(this.opt.hMajorLines){
+					dojo.forEach(ticks.major, function(tick){
+						var y = dim.height - offsets.b - vt(tick.value);
+						s.createLine({
+							x1: offsets.l,
+							y1: y,
+							x2: dim.width - offsets.r,
+							y2: y
+						}).setStroke(ta.majorTick);
+					});
+				}
+			}catch(e){
+				// squelch
+			}
+			// draw vertical stripes and lines
+			try{
+				var hScaler = this._hAxis.getScaler(),
+					ht = hScaler.scaler.getTransformerFromModel(hScaler),
+					ticks = this._hAxis.getTicks();
+				if(ticks && this.opt.vMinorLines){
+					dojo.forEach(ticks.minor, function(tick){
+						var x = offsets.l + ht(tick.value);
+						s.createLine({
+							x1: x,
+							y1: offsets.t,
+							x2: x,
+							y2: dim.height - offsets.b
+						}).setStroke(ta.minorTick);
+					});
+				}
+				if(ticks && this.opt.vMajorLines){
+					dojo.forEach(ticks.major, function(tick){
+						var x = offsets.l + ht(tick.value);
+						s.createLine({
+							x1: x,
+							y1: offsets.t,
+							x2: x,
+							y2: dim.height - offsets.b
+						}).setStroke(ta.majorTick);
+					});
+				}
+			}catch(e){
+				// squelch
+			}
+			this.dirty = false;
+			return this;
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.Pie"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Pie"] = true;
+dojo.provide("dojox.charting.plot2d.Pie");
+
+
+
+
+
+
+
+
+(function(){
+	var df = dojox.lang.functional, du = dojox.lang.utils,
+		dc = dojox.charting.plot2d.common,
+		da = dojox.charting.axis2d.common,
+		g = dojox.gfx;
+
+	dojo.declare("dojox.charting.plot2d.Pie", dojox.charting.Element, {
+		defaultParams: {
+			labels:			true,
+			ticks:			false,
+			fixed:			true,
+			precision:		1,
+			labelOffset:	20,
+			labelStyle:		"default",	// default/rows/auto
+			htmlLabels:		true		// use HTML to draw labels
+		},
+		optionalParams: {
+			font:		"",
+			fontColor:	"",
+			radius:		0
+		},
+
+		constructor: function(chart, kwArgs){
+			this.opt = dojo.clone(this.defaultParams);
+			du.updateWithObject(this.opt, kwArgs);
+			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
+			this.run = null;
+			this.dyn = [];
+		},
+		destroy: function(){
+			this.resetEvents();
+			this.inherited(arguments);
+		},
+		clear: function(){
+			this.dirty = true;
+			this.dyn = [];
+			this.run = null;
+			return this;
+		},
+		setAxis: function(axis){
+			// nothing
+			return this;
+		},
+		addSeries: function(run){
+			this.run = run;
+			return this;
+		},
+		calculateAxes: function(dim){
+			// nothing
+			return this;
+		},
+		getRequiredColors: function(){
+			return this.run ? this.run.data.length : 0;
+		},
+
+		// events
+		plotEvent: function(o){
+			// intentionally empty --- used for events
+		},
+		connect: function(object, method){
+			this.dirty = true;
+			return dojo.connect(this, "plotEvent", object, method);
+		},
+		events: function(){
+			var ls = this.plotEvent._listeners;
+			if(!ls || !ls.length){ return false; }
+			for(var i in ls){
+				if(!(i in Array.prototype)){
+					return true;
+				}
+			}
+			return false;
+		},
+		resetEvents: function(){
+			this.plotEvent({type: "onplotreset", plot: this});
+		},
+		_connectEvents: function(shape, o){
+			shape.connect("onmouseover", this, function(e){
+				o.type  = "onmouseover";
+				o.event = e;
+				this.plotEvent(o);
+			});
+			shape.connect("onmouseout", this, function(e){
+				o.type  = "onmouseout";
+				o.event = e;
+				this.plotEvent(o);
+			});
+			shape.connect("onclick", this, function(e){
+				o.type  = "onclick";
+				o.event = e;
+				this.plotEvent(o);
+			});
+		},
+
+		render: function(dim, offsets){
+			if(!this.dirty){ return this; }
+			this.dirty = false;
+			this.cleanGroup();
+			var s = this.group, color, t = this.chart.theme;
+			this.resetEvents();
+
+			if(!this.run || !this.run.data.length){
+				return this;
+			}
+
+			// calculate the geometry
+			var rx = (dim.width  - offsets.l - offsets.r) / 2,
+				ry = (dim.height - offsets.t - offsets.b) / 2,
+				r  = Math.min(rx, ry),
+				taFont = "font" in this.opt ? this.opt.font : t.axis.font,
+				size = taFont ? g.normalizedLength(g.splitFontString(taFont).size) : 0,
+				taFontColor = "fontColor" in this.opt ? this.opt.fontColor : t.axis.fontColor,
+				start = 0, step, filteredRun, slices, labels, shift, labelR,
+				run = this.run.data,
+				events = this.events();
+			if(typeof run[0] == "number"){
+				filteredRun = df.map(run, "Math.max(x, 0)");
+				if(df.every(filteredRun, "<= 0")){
+					return this;
+				}
+				slices = df.map(filteredRun, "/this", df.foldl(filteredRun, "+", 0));
+				if(this.opt.labels){
+					labels = dojo.map(slices, function(x){
+						return x > 0 ? this._getLabel(x * 100) + "%" : "";
+					}, this);
+				}
+			}else{
+				filteredRun = df.map(run, "Math.max(x.y, 0)");
+				if(df.every(filteredRun, "<= 0")){
+					return this;
+				}
+				slices = df.map(filteredRun, "/this", df.foldl(filteredRun, "+", 0));
+				if(this.opt.labels){
+					labels = dojo.map(slices, function(x, i){
+						if(x <= 0){ return ""; }
+						var v = run[i];
+						return "text" in v ? v.text : this._getLabel(x * 100) + "%";
+					}, this);
+				}
+			}
+			if(this.opt.labels){
+				shift = df.foldl1(df.map(labels, function(label){
+					return dojox.gfx._base._getTextBox(label, {font: taFont}).w;
+				}, this), "Math.max(a, b)") / 2;
+				if(this.opt.labelOffset < 0){
+					r = Math.min(rx - 2 * shift, ry - size) + this.opt.labelOffset;
+				}
+				labelR = r - this.opt.labelOffset;
+			}
+			if("radius" in this.opt){
+				r = this.opt.radius;
+				labelR = r - this.opt.labelOffset;
+			}
+			var	circle = {
+					cx: offsets.l + rx,
+					cy: offsets.t + ry,
+					r:  r
+				};
+
+			this.dyn = [];
+			// draw slices
+			dojo.some(slices, function(slice, i){
+				if(slice <= 0){
+					// degenerated slice
+					return false;	// continue
+				}
+				var v = run[i];
+				if(slice >= 1){
+					// whole pie
+					var color, fill, stroke;
+					if(typeof v == "object"){
+						color  = "color"  in v ? v.color  : new dojo.Color(t.next("color"));
+						fill   = "fill"   in v ? v.fill   : dc.augmentFill(t.series.fill, color);
+						stroke = "stroke" in v ? v.stroke : dc.augmentStroke(t.series.stroke, color);
+					}else{
+						color  = new dojo.Color(t.next("color"));
+						fill   = dc.augmentFill(t.series.fill, color);
+						stroke = dc.augmentStroke(t.series.stroke, color);
+					}
+					var shape = s.createCircle(circle).setFill(fill).setStroke(stroke);
+					this.dyn.push({color: color, fill: fill, stroke: stroke});
+
+					if(events){
+						var o = {
+							element: "slice",
+							index:   i,
+							run:     this.run,
+							plot:    this,
+							shape:   shape,
+							x:       i,
+							y:       typeof v == "number" ? v : v.y,
+							cx:      circle.cx,
+							cy:      circle.cy,
+							cr:      r
+						};
+						this._connectEvents(shape, o);
+					}
+
+					return true;	// stop iteration
+				}
+				// calculate the geometry of the slice
+				var end = start + slice * 2 * Math.PI;
+				if(i + 1 == slices.length){
+					end = 2 * Math.PI;
+				}
+				var	step = end - start,
+					x1 = circle.cx + r * Math.cos(start),
+					y1 = circle.cy + r * Math.sin(start),
+					x2 = circle.cx + r * Math.cos(end),
+					y2 = circle.cy + r * Math.sin(end);
+				// draw the slice
+				var color, fill, stroke;
+				if(typeof v == "object"){
+					color  = "color"  in v ? v.color  : new dojo.Color(t.next("color"));
+					fill   = "fill"   in v ? v.fill   : dc.augmentFill(t.series.fill, color);
+					stroke = "stroke" in v ? v.stroke : dc.augmentStroke(t.series.stroke, color);
+				}else{
+					color  = new dojo.Color(t.next("color"));
+					fill   = dc.augmentFill(t.series.fill, color);
+					stroke = dc.augmentStroke(t.series.stroke, color);
+				}
+				var shape = s.createPath({}).
+						moveTo(circle.cx, circle.cy).
+						lineTo(x1, y1).
+						arcTo(r, r, 0, step > Math.PI, true, x2, y2).
+						lineTo(circle.cx, circle.cy).
+						closePath().
+						setFill(fill).
+						setStroke(stroke);
+				this.dyn.push({color: color, fill: fill, stroke: stroke});
+
+				if(events){
+					var o = {
+						element: "slice",
+						index:   i,
+						run:     this.run,
+						plot:    this,
+						shape:   shape,
+						x:       i,
+						y:       typeof v == "number" ? v : v.y,
+						cx:      circle.cx,
+						cy:      circle.cy,
+						cr:      r
+					};
+					this._connectEvents(shape, o);
+				}
+
+				start = end;
+
+				return false;	// continue
+			}, this);
+			// draw labels
+			if(this.opt.labels){
+				start = 0;
+				dojo.some(slices, function(slice, i){
+					if(slice <= 0){
+						// degenerated slice
+						return false;	// continue
+					}
+					if(slice >= 1){
+						// whole pie
+						var v = run[i], elem = da.createText[this.opt.htmlLabels && dojox.gfx.renderer != "vml" ? "html" : "gfx"]
+									(this.chart, s, circle.cx, circle.cy + size / 2, "middle",
+										labels[i], taFont, (typeof v == "object" && "fontColor" in v) ? v.fontColor : taFontColor);
+						if(this.opt.htmlLabels){ this.htmlElements.push(elem); }
+						return true;	// stop iteration
+					}
+					// calculate the geometry of the slice
+					var end = start + slice * 2 * Math.PI, v = run[i];
+					if(i + 1 == slices.length){
+						end = 2 * Math.PI;
+					}
+					var	labelAngle = (start + end) / 2,
+						x = circle.cx + labelR * Math.cos(labelAngle),
+						y = circle.cy + labelR * Math.sin(labelAngle) + size / 2;
+					// draw the label
+					var elem = da.createText[this.opt.htmlLabels && dojox.gfx.renderer != "vml" ? "html" : "gfx"]
+									(this.chart, s, x, y, "middle",
+										labels[i], taFont,
+										(typeof v == "object" && "fontColor" in v)
+											? v.fontColor : taFontColor);
+					if(this.opt.htmlLabels){ this.htmlElements.push(elem); }
+					start = end;
+					return false;	// continue
+				}, this);
+			}
+			return this;
+		},
+
+		// utilities
+		_getLabel: function(number){
+			return this.opt.fixed ? number.toFixed(this.opt.precision) : number.toString();
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.plot2d.Bubble"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.plot2d.Bubble"] = true;
+dojo.provide("dojox.charting.plot2d.Bubble");
+
+
+
+
+(function(){
+	var df = dojox.lang.functional, du = dojox.lang.utils,
+		dc = dojox.charting.plot2d.common,
+		purgeGroup = df.lambda("item.purgeGroup()");
+
+	dojo.declare("dojox.charting.plot2d.Bubble", dojox.charting.plot2d.Base, {
+		defaultParams: {
+			hAxis: "x",		// use a horizontal axis named "x"
+			vAxis: "y"		// use a vertical axis named "y"
+		},
+		optionalParams: {},	// no optional parameters
+
+		constructor: function(chart, kwArgs){
+			this.opt = dojo.clone(this.defaultParams);
+			du.updateWithObject(this.opt, kwArgs);
+			this.series = [];
+			this.hAxis = this.opt.hAxis;
+			this.vAxis = this.opt.vAxis;
+		},
+		
+		calculateAxes: function(dim){
+			this._calc(dim, dc.collectSimpleStats(this.series));
+			return this;
+		},
+
+		//	override the render so that we are plotting only circles.
+		render: function(dim, offsets){
+			this.dirty = this.isDirty();
+			if(this.dirty){
+				dojo.forEach(this.series, purgeGroup);
+				this.cleanGroup();
+				var s = this.group;
+				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
+			}
+		
+			var t = this.chart.theme, stroke, outline, color, shadowStroke, shadowColor,
+				ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
+				vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
+				events = this.events();
+
+			this.resetEvents();
+
+			for(var i = this.series.length - 1; i >= 0; --i){
+				var run = this.series[i];
+				if(!this.dirty && !run.dirty){ continue; }
+				run.cleanGroup();
+				if(!run.data.length){
+					run.dirty = false;
+					continue;
+				}
+
+				if(typeof run.data[0] == "number"){
+					console.warn("dojox.charting.plot2d.Bubble: the data in the following series cannot be rendered as a bubble chart; ", run);
+					continue;
+				}
+				
+				var s = run.group,
+					points = dojo.map(run.data, function(v, i){
+						return {
+							x: ht(v.x) + offsets.l,
+							y: dim.height - offsets.b - vt(v.y),
+							radius: this._vScaler.bounds.scale * (v.size / 2)
+						};
+					}, this);
+
+				if(run.fill){
+					color = run.fill;
+				}else if(run.stroke){
+					color = run.stroke;
+				}else{
+					color = run.dyn.color = new dojo.Color(t.next("color"));
+				}
+				run.dyn.fill = color;
+
+				stroke = run.dyn.stroke = run.stroke ? dc.makeStroke(run.stroke) : dc.augmentStroke(t.series.stroke, color);
+
+				var frontCircles = null, outlineCircles = null, shadowCircles = null;
+
+				// make shadows if needed
+				if(this.opt.shadows && stroke){
+					var sh = this.opt.shadows, shadowColor = new dojo.Color([0, 0, 0, 0.2]),
+						shadowStroke = dojo.clone(outline ? outline : stroke);
+					shadowStroke.color = shadowColor;
+					shadowStroke.width += sh.dw ? sh.dw : 0;
+					run.dyn.shadow = shadowStroke;
+					var shadowMarkers = dojo.map(points, function(item){
+						var sh = this.opt.shadows;
+						return s.createCircle({
+							cx: item.x + sh.dx, cy: item.y + sh.dy, r: item.radius
+						}).setStroke(shadowStroke).setFill(shadowColor);
+					}, this);
+				}
+
+				// make outlines if needed
+				if(run.outline || t.series.outline){
+					outline = dc.makeStroke(run.outline ? run.outline : t.series.outline);
+					outline.width = 2 * outline.width + stroke.width;
+					run.dyn.outline = outline;
+					outlineCircles = dojo.map(points, function(item){
+						s.createCircle({ cx: item.x, cy: item.y, r: item.radius }).setStroke(outline);
+					}, this);
+				}
+
+				//	run through the data and add the circles.
+				frontCircles = dojo.map(points, function(item){
+					return s.createCircle({ cx: item.x, cy: item.y, r: item.radius }).setStroke(stroke).setFill(color);
+				}, this);
+				
+				if(events){
+					dojo.forEach(frontCircles, function(s, i){
+						var o = {
+							element: "circle",
+							index:   i,
+							run:     run,
+							plot:    this,
+							hAxis:   this.hAxis || null,
+							vAxis:   this.vAxis || null,
+							shape:   s,
+							outline: outlineCircles && outlineCircles[i] || null,
+							shadow:  shadowCircles && shadowCircles[i] || null,
+							x:       run.data[i].x,
+							y:       run.data[i].y,
+							r:       run.data[i].size / 2,
+							cx:      points[i].x,
+							cy:      points[i].y,
+							cr:      points[i].radius
+						};
+						this._connectEvents(s, o);
+					}, this);
+				}
+				
+				run.dirty = false;
+			}
+			this.dirty = false;
+			return this;
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.Chart2D"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.Chart2D"] = true;
+dojo.provide("dojox.charting.Chart2D");
+
+
+
+
+
+
+
+
+
+// require all axes to support references by name
+
+
+// require all plots to support references by name
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+(function(){
+	var df = dojox.lang.functional, dc = dojox.charting,
+		clear = df.lambda("item.clear()"),
+		purge = df.lambda("item.purgeGroup()"),
+		destroy = df.lambda("item.destroy()"),
+		makeClean = df.lambda("item.dirty = false"),
+		makeDirty = df.lambda("item.dirty = true");
+
+	dojo.declare("dojox.charting.Chart2D", null, {
+		constructor: function(node, kwArgs){
+			// initialize parameters
+			if(!kwArgs){ kwArgs = {}; }
+			this.margins = kwArgs.margins ? kwArgs.margins : {l: 10, t: 10, r: 10, b: 10};
+			this.stroke  = kwArgs.stroke;
+			this.fill    = kwArgs.fill;
+
+			// default initialization
+			this.theme = null;
+			this.axes = {};		// map of axes
+			this.stack = [];	// stack of plotters
+			this.plots = {};	// map of plotter indices
+			this.series = [];	// stack of data runs
+			this.runs = {};		// map of data run indices
+			this.dirty = true;
+			this.coords = null;
+
+			// create a surface
+			this.node = dojo.byId(node);
+			var box = dojo.marginBox(node);
+			this.surface = dojox.gfx.createSurface(this.node, box.w, box.h);
+		},
+		destroy: function(){
+			dojo.forEach(this.series, destroy);
+			dojo.forEach(this.stack,  destroy);
+			df.forIn(this.axes, destroy);
+			this.surface.destroy();
+		},
+		getCoords: function(){
+			if(!this.coords){
+				this.coords = dojo.coords(this.node, true);
+			}
+			return this.coords;
+		},
+		setTheme: function(theme){
+			this.theme = theme._clone();
+			this.dirty = true;
+			return this;
+		},
+		addAxis: function(name, kwArgs){
+			var axis;
+			if(!kwArgs || !("type" in kwArgs)){
+				axis = new dc.axis2d.Default(this, kwArgs);
+			}else{
+				axis = typeof kwArgs.type == "string" ?
+					new dc.axis2d[kwArgs.type](this, kwArgs) :
+					new kwArgs.type(this, kwArgs);
+			}
+			axis.name = name;
+			axis.dirty = true;
+			if(name in this.axes){
+				this.axes[name].destroy();
+			}
+			this.axes[name] = axis;
+			this.dirty = true;
+			return this;
+		},
+		getAxis: function(name){
+			return this.axes[name];
+		},
+		removeAxis: function(name){
+			if(name in this.axes){
+				// destroy the axis
+				this.axes[name].destroy();
+				delete this.axes[name];
+				// mark the chart as dirty
+				this.dirty = true;
+			}
+			return this;	// self
+		},
+		addPlot: function(name, kwArgs){
+			var plot;
+			if(!kwArgs || !("type" in kwArgs)){
+				plot = new dc.plot2d.Default(this, kwArgs);
+			}else{
+				plot = typeof kwArgs.type == "string" ?
+					new dc.plot2d[kwArgs.type](this, kwArgs) :
+					new kwArgs.type(this, kwArgs);
+			}
+			plot.name = name;
+			plot.dirty = true;
+			if(name in this.plots){
+				this.stack[this.plots[name]].destroy();
+				this.stack[this.plots[name]] = plot;
+			}else{
+				this.plots[name] = this.stack.length;
+				this.stack.push(plot);
+			}
+			this.dirty = true;
+			return this;
+		},
+		removePlot: function(name){
+			if(name in this.plots){
+				// get the index and remove the name
+				var index = this.plots[name];
+				delete this.plots[name];
+				// destroy the plot
+				this.stack[index].destroy();
+				// remove the plot from the stack
+				this.stack.splice(index, 1);
+				// update indices to reflect the shift
+				df.forIn(this.plots, function(idx, name, plots){
+					if(idx > index){
+						plots[name] = idx - 1;
+					}
+				});
+				// mark the chart as dirty
+				this.dirty = true;
+			}
+			return this;	// self
+		},
+		addSeries: function(name, data, kwArgs){
+			var run = new dc.Series(this, data, kwArgs);
+			if(name in this.runs){
+				this.series[this.runs[name]].destroy();
+				this.series[this.runs[name]] = run;
+			}else{
+				this.runs[name] = this.series.length;
+				this.series.push(run);
+			}
+			run.name = name;
+			this.dirty = true;
+			// fix min/max
+			if(!("ymin" in run) && "min" in run){ run.ymin = run.min; }
+			if(!("ymax" in run) && "max" in run){ run.ymax = run.max; }
+			return this;
+		},
+		removeSeries: function(name){
+			if(name in this.runs){
+				// get the index and remove the name
+				var index = this.runs[name],
+					plotName = this.series[index].plot;
+				delete this.runs[name];
+				// destroy the run
+				this.series[index].destroy();
+				// remove the run from the stack of series
+				this.series.splice(index, 1);
+				// update indices to reflect the shift
+				df.forIn(this.runs, function(idx, name, runs){
+					if(idx > index){
+						runs[name] = idx - 1;
+					}
+				});
+				this.dirty = true;
+			}
+			return this;	// self
+		},
+		updateSeries: function(name, data){
+			if(name in this.runs){
+				var run = this.series[this.runs[name]];
+				run.data = data;
+				run.dirty = true;
+				this._invalidateDependentPlots(run.plot, false);
+				this._invalidateDependentPlots(run.plot, true);
+			}
+			return this;
+		},
+		resize: function(width, height){
+			var box;
+			switch(arguments.length){
+				case 0:
+					box = dojo.marginBox(this.node);
+					break;
+				case 1:
+					box = width;
+					break;
+				default:
+					box = {w: width, h: height};
+					break;
+			}
+			dojo.marginBox(this.node, box);
+			this.surface.setDimensions(box.w, box.h);
+			this.dirty = true;
+			this.coords = null;
+			return this.render();
+		},
+		getGeometry: function(){
+			var ret = {};
+			df.forIn(this.axes, function(axis){
+				if(axis.initialized()){
+					ret[axis.name] = {
+						name:		axis.name,
+						vertical:	axis.vertical,
+						scaler:		axis.scaler,
+						ticks:		axis.ticks
+					};
+				}
+			});
+			return ret;
+		},
+		setAxisWindow: function(name, scale, offset){
+			var axis = this.axes[name];
+			if(axis){
+				axis.setWindow(scale, offset);
+			}
+			return this;
+		},
+		setWindow: function(sx, sy, dx, dy){
+			if(!("plotArea" in this)){
+				this.calculateGeometry();
+			}
+			df.forIn(this.axes, function(axis){
+				var scale, offset, bounds = axis.getScaler().bounds,
+					s = bounds.span / (bounds.upper - bounds.lower);
+				if(axis.vertical){
+					scale  = sy;
+					offset = dy / s / scale;
+				}else{
+					scale  = sx;
+					offset = dx / s / scale;
+				}
+				axis.setWindow(scale, offset);
+			});
+			return this;
+		},
+		calculateGeometry: function(){
+			if(this.dirty){
+				return this.fullGeometry();
+			}
+
+			// calculate geometry
+			dojo.forEach(this.stack, function(plot){
+				if(plot.dirty || (plot.hAxis && this.axes[plot.hAxis].dirty) ||
+						(plot.vAxis && this.axes[plot.vAxis].dirty)){
+					plot.calculateAxes(this.plotArea);
+				}
+			}, this);
+
+			return this;
+		},
+		fullGeometry: function(){
+			this._makeDirty();
+
+			// clear old values
+			dojo.forEach(this.stack, clear);
+
+			// rebuild new connections, and add defaults
+
+			// set up a theme
+			if(!this.theme){
+				this.setTheme(new dojox.charting.Theme(dojox.charting._def));
+			}
+
+			// assign series
+			dojo.forEach(this.series, function(run){
+				if(!(run.plot in this.plots)){
+					var plot = new dc.plot2d.Default(this, {});
+					plot.name = run.plot;
+					this.plots[run.plot] = this.stack.length;
+					this.stack.push(plot);
+				}
+				this.stack[this.plots[run.plot]].addSeries(run);
+			}, this);
+			// assign axes
+			dojo.forEach(this.stack, function(plot){
+				if(plot.hAxis){
+					plot.setAxis(this.axes[plot.hAxis]);
+				}
+				if(plot.vAxis){
+					plot.setAxis(this.axes[plot.vAxis]);
+				}
+			}, this);
+
+			// calculate geometry
+
+			// 1st pass
+			var dim = this.dim = this.surface.getDimensions();
+			dim.width  = dojox.gfx.normalizedLength(dim.width);
+			dim.height = dojox.gfx.normalizedLength(dim.height);
+			df.forIn(this.axes, clear);
+			dojo.forEach(this.stack, function(plot){ plot.calculateAxes(dim); });
+
+			// assumption: we don't have stacked axes yet
+			var offsets = this.offsets = {l: 0, r: 0, t: 0, b: 0};
+			df.forIn(this.axes, function(axis){
+				df.forIn(axis.getOffsets(), function(o, i){ offsets[i] += o; });
+			});
+			// add margins
+			df.forIn(this.margins, function(o, i){ offsets[i] += o; });
+
+			// 2nd pass with realistic dimensions
+			this.plotArea = {width: dim.width - offsets.l - offsets.r, height: dim.height - offsets.t - offsets.b};
+			df.forIn(this.axes, clear);
+			dojo.forEach(this.stack, function(plot){ plot.calculateAxes(this.plotArea); }, this);
+
+			return this;
+		},
+		render: function(){
+			if(this.theme){
+				this.theme.clear();
+			}
+
+			if(this.dirty){
+				return this.fullRender();
+			}
+
+			this.calculateGeometry();
+
+			// go over the stack backwards
+			df.forEachRev(this.stack, function(plot){ plot.render(this.dim, this.offsets); }, this);
+
+			// go over axes
+			df.forIn(this.axes, function(axis){ axis.render(this.dim, this.offsets); }, this);
+
+			this._makeClean();
+
+			// BEGIN FOR HTML CANVAS
+			if(this.surface.render){ this.surface.render(); };
+			// END FOR HTML CANVAS
+
+			return this;
+		},
+		fullRender: function(){
+			// calculate geometry
+			this.fullGeometry();
+			var offsets = this.offsets, dim = this.dim;
+
+			// get required colors
+			var requiredColors = df.foldl(this.stack, "z + plot.getRequiredColors()", 0);
+			this.theme.defineColors({num: requiredColors, cache: false});
+
+			// clear old shapes
+			dojo.forEach(this.series, purge);
+			df.forIn(this.axes, purge);
+			dojo.forEach(this.stack,  purge);
+			this.surface.clear();
+
+			// generate shapes
+
+			// draw a plot background
+			var t = this.theme,
+				fill   = t.plotarea && t.plotarea.fill,
+				stroke = t.plotarea && t.plotarea.stroke;
+			if(fill){
+				this.surface.createRect({
+					x: offsets.l, y: offsets.t,
+					width:  dim.width  - offsets.l - offsets.r,
+					height: dim.height - offsets.t - offsets.b
+				}).setFill(fill);
+			}
+			if(stroke){
+				this.surface.createRect({
+					x: offsets.l, y: offsets.t,
+					width:  dim.width  - offsets.l - offsets.r - 1,
+					height: dim.height - offsets.t - offsets.b - 1
+				}).setStroke(stroke);
+			}
+
+			// go over the stack backwards
+			df.foldr(this.stack, function(z, plot){ return plot.render(dim, offsets), 0; }, 0);
+
+			// pseudo-clipping: matting
+			fill   = this.fill   ? this.fill   : (t.chart && t.chart.fill);
+			stroke = this.stroke ? this.stroke : (t.chart && t.chart.stroke);
+
+			//	TRT: support for "inherit" as a named value in a theme.
+			if(fill == "inherit"){
+				//	find the background color of the nearest ancestor node, and use that explicitly.
+				var node = this.node, fill = new dojo.Color(dojo.style(node, "backgroundColor"));
+				while(fill.a==0 && node!=document.documentElement){
+					fill = new dojo.Color(dojo.style(node, "backgroundColor"));
+					node = node.parentNode;
+				}
+			}
+
+			if(fill){
+				if(offsets.l){	// left
+					this.surface.createRect({
+						width:  offsets.l,
+						height: dim.height + 1
+					}).setFill(fill);
+				}
+				if(offsets.r){	// right
+					this.surface.createRect({
+						x: dim.width - offsets.r,
+						width:  offsets.r + 1,
+						height: dim.height + 1
+					}).setFill(fill);
+				}
+				if(offsets.t){	// top
+					this.surface.createRect({
+						width:  dim.width + 1,
+						height: offsets.t
+					}).setFill(fill);
+				}
+				if(offsets.b){	// bottom
+					this.surface.createRect({
+						y: dim.height - offsets.b,
+						width:  dim.width + 1,
+						height: offsets.b + 2
+					}).setFill(fill);
+				}
+			}
+			if(stroke){
+				this.surface.createRect({
+					width:  dim.width - 1,
+					height: dim.height - 1
+				}).setStroke(stroke);
+			}
+
+			// go over axes
+			df.forIn(this.axes, function(axis){ axis.render(dim, offsets); });
+
+			this._makeClean();
+
+			// BEGIN FOR HTML CANVAS
+			if(this.surface.render){ this.surface.render(); };
+			// END FOR HTML CANVAS
+
+			return this;
+		},
+		connectToPlot: function(name, object, method){
+			return name in this.plots ? this.stack[this.plots[name]].connect(object, method) : null;
+		},
+		_makeClean: function(){
+			// reset dirty flags
+			dojo.forEach(this.axes,   makeClean);
+			dojo.forEach(this.stack,  makeClean);
+			dojo.forEach(this.series, makeClean);
+			this.dirty = false;
+		},
+		_makeDirty: function(){
+			// reset dirty flags
+			dojo.forEach(this.axes,   makeDirty);
+			dojo.forEach(this.stack,  makeDirty);
+			dojo.forEach(this.series, makeDirty);
+			this.dirty = true;
+		},
+		_invalidateDependentPlots: function(plotName, /* Boolean */ verticalAxis){
+			if(plotName in this.plots){
+				var plot = this.stack[this.plots[plotName]], axis,
+					axisName = verticalAxis ? "vAxis" : "hAxis";
+				if(plot[axisName]){
+					axis = this.axes[plot[axisName]];
+					if(axis.dependOnData()){
+						axis.dirty = true;
+						// find all plots and mark them dirty
+						dojo.forEach(this.stack, function(p){
+							if(p[axisName] && p[axisName] == plot[axisName]){
+								p.dirty = true;
+							}
+						});
+					}
+				}else{
+					plot.dirty = true;
+				}
+			}
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojo.fx.easing"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.fx.easing"] = true;
+dojo.provide("dojo.fx.easing");
+
+dojo.fx.easing = {
+	// summary: Collection of easing functions to use beyond the default dojo._defaultEasing
+	// 
+	// description:
+	//	Easing functions are used to manipulate the iteration through
+	//	an _Animation's _Line. _Line being the properties of an Animation,
+	//	and the easing function progresses through that Line determing
+	//	how quickly (or slowly) it should go. Or more accurately: modify
+	//	the value of the _Line based on the percentage of animation completed.
+	//	
+	//	All functions follow a simple naming convention of "ease type" + "when".
+	//	If the name of the function ends in Out, the easing described appears
+	//	towards the end of the animation. "In" means during the beginning,
+	//	and InOut means both ranges of the Animation will applied, both beginning
+	//	and end. 
+	//
+	//	example:
+	//	|	
+	//	|	var anim = dojo.fadeOut({
+	//	|		node: 'node',	
+	//	|		duration: 2000,
+	//	|		easing: dojo.fx.easing.quadIn
+	//	|	}).play();
+	//
+	
+	linear: function(/* Decimal? */n){
+		// summary: A linear easing function
+		return n;
+	},
+
+	quadIn: function(/* Decimal? */n){
+		return Math.pow(n, 2);
+	},
+
+	quadOut: function(/* Decimal? */n){
+		return n * (n - 2) * -1;
+	},
+
+	quadInOut: function(/* Decimal? */n){
+		n = n * 2;
+		if(n < 1){ return Math.pow(n, 2) / 2; }
+		return -1 * ((--n) * (n - 2) - 1) / 2;
+	},
+
+	cubicIn: function(/* Decimal? */n){
+		return Math.pow(n, 3);
+	},
+
+	cubicOut: function(/* Decimal? */n){
+		return Math.pow(n - 1, 3) + 1;
+	},
+
+	cubicInOut: function(/* Decimal? */n){
+		n = n * 2;
+		if(n < 1){ return Math.pow(n, 3) / 2; }
+		n -= 2;
+		return (Math.pow(n, 3) + 2) / 2;
+	},
+
+	quartIn: function(/* Decimal? */n){
+		return Math.pow(n, 4);
+	},
+
+	quartOut: function(/* Decimal? */n){
+		return -1 * (Math.pow(n - 1, 4) - 1);
+	},
+
+	quartInOut: function(/* Decimal? */n){
+		n = n * 2;
+		if(n < 1){ return Math.pow(n, 4) / 2; }
+		n -= 2;
+		return -1 / 2 * (Math.pow(n, 4) - 2);
+	},
+
+	quintIn: function(/* Decimal? */n){
+		return Math.pow(n, 5);
+	},
+
+	quintOut: function(/* Decimal? */n){
+		return Math.pow(n - 1, 5) + 1;
+	},
+
+	quintInOut: function(/* Decimal? */n){
+		n = n * 2;
+		if(n < 1){ return Math.pow(n, 5) / 2; };
+		n -= 2;
+		return (Math.pow(n, 5) + 2) / 2;
+	},
+
+	sineIn: function(/* Decimal? */n){
+		return -1 * Math.cos(n * (Math.PI / 2)) + 1;
+	},
+
+	sineOut: function(/* Decimal? */n){
+		return Math.sin(n * (Math.PI / 2));
+	},
+
+	sineInOut: function(/* Decimal? */n){
+		return -1 * (Math.cos(Math.PI * n) - 1) / 2;
+	},
+
+	expoIn: function(/* Decimal? */n){
+		return (n == 0) ? 0 : Math.pow(2, 10 * (n - 1));
+	},
+
+	expoOut: function(/* Decimal? */n){
+		return (n == 1) ? 1 : (-1 * Math.pow(2, -10 * n) + 1);
+	},
+
+	expoInOut: function(/* Decimal? */n){
+		if(n == 0){ return 0; }
+		if(n == 1){ return 1; }
+		n = n * 2;
+		if(n < 1){ return Math.pow(2, 10 * (n - 1)) / 2; }
+		--n;
+		return (-1 * Math.pow(2, -10 * n) + 2) / 2;
+	},
+
+	circIn: function(/* Decimal? */n){
+		return -1 * (Math.sqrt(1 - Math.pow(n, 2)) - 1);
+	},
+
+	circOut: function(/* Decimal? */n){
+		n = n - 1;
+		return Math.sqrt(1 - Math.pow(n, 2));
+	},
+
+	circInOut: function(/* Decimal? */n){
+		n = n * 2;
+		if(n < 1){ return -1 / 2 * (Math.sqrt(1 - Math.pow(n, 2)) - 1); }
+		n -= 2;
+		return 1 / 2 * (Math.sqrt(1 - Math.pow(n, 2)) + 1);
+	},
+
+	backIn: function(/* Decimal? */n){
+		// summary: An easing function that starts away from the target, and 
+		//		quickly accelerates towards the end value
+		var s = 1.70158;
+		return Math.pow(n, 2) * ((s + 1) * n - s);
+	},
+
+	backOut: function(/* Decimal? */n){
+		// summary: An easing function that pops past the range briefly, and 
+		// 	slowly comes back. 
+		n = n - 1;
+		var s = 1.70158;
+		return Math.pow(n, 2) * ((s + 1) * n + s) + 1;
+	},
+
+	backInOut: function(/* Decimal? */n){
+		// summary: An easing function combining the effects of backIn and backOut
+		var s = 1.70158 * 1.525;
+		n = n * 2;
+		if(n < 1){ return (Math.pow(n, 2) * ((s + 1) * n - s)) / 2; }
+		n-=2;
+		return (Math.pow(n, 2) * ((s + 1) * n + s) + 2) / 2;
+	},
+
+	elasticIn: function(/* Decimal? */n){
+		// summary: An easing function the elastically snaps from the start value
+		if(n == 0 || n == 1){ return n; }
+		var p = .3;
+		var s = p / 4;
+		n = n - 1;
+		return -1 * Math.pow(2, 10 * n) * Math.sin((n - s) * (2 * Math.PI) / p);
+	},
+
+	elasticOut: function(/* Decimal? */n){
+		// summary: An easing function that elasticly snaps around the target value, near the end of the Animation
+		if(n==0 || n == 1){ return n; }
+		var p = .3;
+		var s = p / 4;
+		return Math.pow(2, -10 * n) * Math.sin((n - s) * (2 * Math.PI) / p) + 1;
+	},
+
+	elasticInOut: function(/* Decimal? */n){
+		// summary: An easing function that elasticly snaps around the value, near the beginning and end of the Animation		
+		if(n == 0) return 0;
+		n = n * 2;
+		if(n == 2) return 1;
+		var p = .3 * 1.5;
+		var s = p / 4;
+		if(n < 1){
+			n -= 1;
+			return -.5 * (Math.pow(2, 10 * n) * Math.sin((n - s) * (2 * Math.PI) / p));
+		}
+		n -= 1;
+		return .5 * (Math.pow(2, -10 * n) * Math.sin((n - s) * (2 * Math.PI) / p)) + 1;
+	},
+
+	bounceIn: function(/* Decimal? */n){
+		// summary: An easing function that "bounces" near the beginning of an Animation
+		return (1 - dojo.fx.easing.bounceOut(1 - n)); // Decimal
+	},
+
+	bounceOut: function(/* Decimal? */n){
+		// summary: An easing function that "bounces" near the end of an Animation
+		var s = 7.5625;
+		var p = 2.75;
+		var l; 
+		if(n < (1 / p)){
+			l = s * Math.pow(n, 2);
+		}else if(n < (2 / p)){
+			n -= (1.5 / p);
+			l = s * Math.pow(n, 2) + .75;
+		}else if(n < (2.5 / p)){
+			n -= (2.25 / p);
+			l = s * Math.pow(n, 2) + .9375;
+		}else{
+			n -= (2.625 / p);
+			l = s * Math.pow(n, 2) + .984375;
+		}
+		return l;
+	},
+
+	bounceInOut: function(/* Decimal? */n){
+		// summary: An easing function that "bounces" at the beginning and end of the Animation
+		if(n < 0.5){ return dojo.fx.easing.bounceIn(n * 2) / 2; }
+		return (dojo.fx.easing.bounceOut(n * 2 - 1) / 2) + 0.5; // Decimal
+	}
+};
+
+}
+
+if(!dojo._hasResource["dojox.gfx.fx"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.fx"] = true;
+dojo.provide("dojox.gfx.fx");
+
+
+
+(function(){
+	var d = dojo, g = dojox.gfx, m = g.matrix;
+
+	// Generic interpolators. Should they be moved to dojox.fx?
+
+	var InterpolNumber = function(start, end){
+		this.start = start, this.end = end;
+	};
+	d.extend(InterpolNumber, {
+		getValue: function(r){
+			return (this.end - this.start) * r + this.start;
+		}
+	});
+
+	var InterpolUnit = function(start, end, unit){
+		this.start = start, this.end = end;
+		this.unit = unit;
+	};
+	d.extend(InterpolUnit, {
+		getValue: function(r){
+			return (this.end - this.start) * r + this.start + this.unit;
+		}
+	});
+
+	var InterpolColor = function(start, end){
+		this.start = start, this.end = end;
+		this.temp = new dojo.Color();
+	};
+	d.extend(InterpolColor, {
+		getValue: function(r){
+			return d.blendColors(this.start, this.end, r, this.temp);
+		}
+	});
+
+	var InterpolValues = function(values){
+		this.values = values;
+		this.length = values.length;
+	};
+	d.extend(InterpolValues, {
+		getValue: function(r){
+			return this.values[Math.min(Math.floor(r * this.length), this.length - 1)];
+		}
+	});
+
+	var InterpolObject = function(values, def){
+		this.values = values;
+		this.def = def ? def : {};
+	};
+	d.extend(InterpolObject, {
+		getValue: function(r){
+			var ret = dojo.clone(this.def);
+			for(var i in this.values){
+				ret[i] = this.values[i].getValue(r);
+			}
+			return ret;
+		}
+	});
+
+	var InterpolTransform = function(stack, original){
+		this.stack = stack;
+		this.original = original;
+	};
+	d.extend(InterpolTransform, {
+		getValue: function(r){
+			var ret = [];
+			dojo.forEach(this.stack, function(t){
+				if(t instanceof m.Matrix2D){
+					ret.push(t);
+					return;
+				}
+				if(t.name == "original" && this.original){
+					ret.push(this.original);
+					return;
+				}
+				if(!(t.name in m)){ return; }
+				var f = m[t.name];
+				if(typeof f != "function"){
+					// constant
+					ret.push(f);
+					return;
+				}
+				var val = dojo.map(t.start, function(v, i){
+								return (t.end[i] - v) * r + v;
+							}),
+					matrix = f.apply(m, val);
+				if(matrix instanceof m.Matrix2D){
+					ret.push(matrix);
+				}
+			}, this);
+			return ret;
+		}
+	});
+
+	var transparent = new d.Color(0, 0, 0, 0);
+
+	var getColorInterpol = function(prop, obj, name, def){
+		if(prop.values){
+			return new InterpolValues(prop.values);
+		}
+		var value, start, end;
+		if(prop.start){
+			start = g.normalizeColor(prop.start);
+		}else{
+			start = value = obj ? (name ? obj[name] : obj) : def;
+		}
+		if(prop.end){
+			end = g.normalizeColor(prop.end);
+		}else{
+			if(!value){
+				value = obj ? (name ? obj[name] : obj) : def;
+			}
+			end = value;
+		}
+		return new InterpolColor(start, end);
+	};
+
+	var getNumberInterpol = function(prop, obj, name, def){
+		if(prop.values){
+			return new InterpolValues(prop.values);
+		}
+		var value, start, end;
+		if(prop.start){
+			start = prop.start;
+		}else{
+			start = value = obj ? obj[name] : def;
+		}
+		if(prop.end){
+			end = prop.end;
+		}else{
+			if(typeof value != "number"){
+				value = obj ? obj[name] : def;
+			}
+			end = value;
+		}
+		return new InterpolNumber(start, end);
+	};
+
+	g.fx.animateStroke = function(/*Object*/ args){
+		// summary:
+		//	Returns an animation which will change stroke properties over time
+		// example:
+		//	|	dojox.gfx.fx.animateStroke{{
+		//	|		shape: shape,
+		//	|		duration: 500,
+		//	|		color: {start: "red", end: "green"},
+		//	|		width: {end: 15},
+		//	|		join:  {values: ["miter", "bevel", "round"]}
+		//	|	}).play();
+		if(!args.easing){ args.easing = d._defaultEasing; }
+		var anim = new d._Animation(args), shape = args.shape, stroke;
+		d.connect(anim, "beforeBegin", anim, function(){
+			stroke = shape.getStroke();
+			var prop = args.color, values = {}, value, start, end;
+			if(prop){
+				values.color = getColorInterpol(prop, stroke, "color", transparent);
+			}
+			prop = args.style;
+			if(prop && prop.values){
+				values.style = new InterpolValues(prop.values);
+			}
+			prop = args.width;
+			if(prop){
+				values.width = getNumberInterpol(prop, stroke, "width", 1);
+			}
+			prop = args.cap;
+			if(prop && prop.values){
+				values.cap = new InterpolValues(prop.values);
+			}
+			prop = args.join;
+			if(prop){
+				if(prop.values){
+					values.join = new InterpolValues(prop.values);
+				}else{
+					start = prop.start ? prop.start : (stroke && stroke.join || 0);
+					end = prop.end ? prop.end : (stroke && stroke.join || 0);
+					if(typeof start == "number" && typeof end == "number"){
+						values.join = new InterpolNumber(start, end);
+					}
+				}
+			}
+			this.curve = new InterpolObject(values, stroke);
+		});
+		d.connect(anim, "onAnimate", shape, "setStroke");
+		return anim; // dojo._Animation
+	};
+
+	g.fx.animateFill = function(/*Object*/ args){
+		// summary:
+		//	Returns an animation which will change fill color over time.
+		//	Only solid fill color is supported at the moment
+		// example:
+		//	|	dojox.gfx.fx.animateFill{{
+		//	|		shape: shape,
+		//	|		duration: 500,
+		//	|		color: {start: "red", end: "green"}
+		//	|	}).play();
+		if(!args.easing){ args.easing = d._defaultEasing; }
+		var anim = new d._Animation(args), shape = args.shape, fill;
+		d.connect(anim, "beforeBegin", anim, function(){
+			fill = shape.getFill();
+			var prop = args.color, values = {};
+			if(prop){
+				this.curve = getColorInterpol(prop, fill, "", transparent);
+			}
+		});
+		d.connect(anim, "onAnimate", shape, "setFill");
+		return anim; // dojo._Animation
+	};
+
+	g.fx.animateFont = function(/*Object*/ args){
+		// summary:
+		//	Returns an animation which will change font properties over time
+		// example:
+		//	|	dojox.gfx.fx.animateFont{{
+		//	|		shape: shape,
+		//	|		duration: 500,
+		//	|		variant: {values: ["normal", "small-caps"]},
+		//	|		size:  {end: 10, unit: "pt"}
+		//	|	}).play();
+		if(!args.easing){ args.easing = d._defaultEasing; }
+		var anim = new d._Animation(args), shape = args.shape, font;
+		d.connect(anim, "beforeBegin", anim, function(){
+			font = shape.getFont();
+			var prop = args.style, values = {}, value, start, end;
+			if(prop && prop.values){
+				values.style = new InterpolValues(prop.values);
+			}
+			prop = args.variant;
+			if(prop && prop.values){
+				values.variant = new InterpolValues(prop.values);
+			}
+			prop = args.weight;
+			if(prop && prop.values){
+				values.weight = new InterpolValues(prop.values);
+			}
+			prop = args.family;
+			if(prop && prop.values){
+				values.family = new InterpolValues(prop.values);
+			}
+			prop = args.size;
+			if(prop && prop.unit){
+				start = parseFloat(prop.start ? prop.start : (shape.font && shape.font.size || "0"));
+				end = parseFloat(prop.end ? prop.end : (shape.font && shape.font.size || "0"));
+				values.size = new InterpolUnit(start, end, prop.unit);
+			}
+			this.curve = new InterpolObject(values, font);
+		});
+		d.connect(anim, "onAnimate", shape, "setFont");
+		return anim; // dojo._Animation
+	};
+
+	g.fx.animateTransform = function(/*Object*/ args){
+		// summary:
+		//	Returns an animation which will change transformation over time
+		// example:
+		//	|	dojox.gfx.fx.animateTransform{{
+		//	|		shape: shape,
+		//	|		duration: 500,
+		//	|		transform: [
+		//	|			{name: "translate", start: [0, 0], end: [200, 200]},
+		//	|			{name: "original"}
+		//	|		]
+		//	|	}).play();
+		if(!args.easing){ args.easing = d._defaultEasing; }
+		var anim = new d._Animation(args), shape = args.shape, original;
+		d.connect(anim, "beforeBegin", anim, function(){
+			original = shape.getTransform();
+			this.curve = new InterpolTransform(args.transform, original);
+		});
+		d.connect(anim, "onAnimate", shape, "setTransform");
+		return anim; // dojo._Animation
+	};
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.action2d.Base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.action2d.Base"] = true;
+dojo.provide("dojox.charting.action2d.Base");
+
+
+
+
+
+(function(){
+	var DEFAULT_DURATION = 400,	// ms
+		DEFAULT_EASING   = dojo.fx.easing.backOut,
+		df = dojox.lang.functional;
+
+	dojo.declare("dojox.charting.action2d.Base", null, {
+
+		overOutEvents: {onmouseover: 1, onmouseout: 1},
+
+		constructor: function(chart, plot, kwargs){
+			this.chart = chart;
+			this.plot = plot ? plot : "default";
+			this.anim = {};
+
+			// process common optional named parameters
+			if(!kwargs){ kwargs = {}; }
+			this.duration = kwargs.duration ? kwargs.duration : DEFAULT_DURATION;
+			this.easing   = kwargs.easing   ? kwargs.easing   : DEFAULT_EASING;
+		},
+
+		connect: function(){
+			this.handle = this.chart.connectToPlot(this.plot, this, "process");
+		},
+
+		disconnect: function(){
+			if(this.handle){
+				dojo.disconnect(this.handle);
+				this.handle = null;
+			}
+		},
+
+		reset: function(){
+			// nothing by default
+		},
+
+		destroy: function(){
+			if(this.handle){
+				this.disconnect();
+			}
+			df.forIn(this.anim, function(o){
+				df.forIn(o, function(anim){
+					anim.action.stop(true);
+				});
+			});
+			this.anim = {};
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.action2d.Highlight"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.action2d.Highlight"] = true;
+dojo.provide("dojox.charting.action2d.Highlight");
+
+
+
+
+(function(){
+	var DEFAULT_SATURATION  = 100,	// %
+		DEFAULT_LUMINOSITY1 = 75,	// %
+		DEFAULT_LUMINOSITY2 = 50,	// %
+
+		c = dojox.color,
+		
+		cc = function(color){
+			return function(){ return color; };
+		},
+		
+		hl = function(color){
+			var a = new c.Color(color),
+				x = a.toHsl();
+			if(x.s == 0){
+				x.l = x.l < 50 ? 100 : 0;
+			}else{
+				x.s = DEFAULT_SATURATION;
+				if(x.l < DEFAULT_LUMINOSITY2){
+					x.l = DEFAULT_LUMINOSITY1;
+				}else if(x.l > DEFAULT_LUMINOSITY1){
+					x.l = DEFAULT_LUMINOSITY2;
+				}else{
+					x.l = x.l - DEFAULT_LUMINOSITY2 > DEFAULT_LUMINOSITY1 - x.l ?
+						DEFAULT_LUMINOSITY2 : DEFAULT_LUMINOSITY1;
+				}
+			}
+			return c.fromHsl(x);
+		};
+	
+	dojo.declare("dojox.charting.action2d.Highlight", dojox.charting.action2d.Base, {
+		// the data description block for the widget parser
+		defaultParams: {
+			duration: 400,	// duration of the action in ms
+			easing:   dojo.fx.easing.backOut	// easing for the action
+		},
+		optionalParams: {
+			highlight: "red"	// name for the highlight color
+								// programmatic instantiation can use functions and color objects
+		},
+		
+		constructor: function(chart, plot, kwArgs){
+			// process optional named parameters
+			var a = kwArgs && kwArgs.highlight;
+			this.colorFun = a ? (dojo.isFunction(a) ? a : cc(a)) : hl;
+			
+			this.connect();
+		},
+		
+		process: function(o){
+			if(!o.shape || !(o.type in this.overOutEvents)){ return; }
+			
+			var runName = o.run.name, index = o.index, anim, startFill, endFill;
+	
+			if(runName in this.anim){
+				anim = this.anim[runName][index];
+			}else{
+				this.anim[runName] = {};
+			}
+			
+			if(anim){
+				anim.action.stop(true);
+			}else{
+				var color = o.shape.getFill();
+				if(!color || !(color instanceof dojo.Color)){
+					return;
+				}
+				this.anim[runName][index] = anim = {
+					start: color,
+					end:   this.colorFun(color)
+				};
+			}
+			
+			var start = anim.start, end = anim.end;
+			if(o.type == "onmouseout"){
+				// swap colors
+				var t = start;
+				start = end;
+				end = t;
+			}
+			
+			anim.action = dojox.gfx.fx.animateFill({
+				shape:    o.shape,
+				duration: this.duration,
+				easing:   this.easing,
+				color:    {start: start, end: end}
+			});
+			if(o.type == "onmouseout"){
+				dojo.connect(anim.action, "onEnd", this, function(){
+					if(this.anim[runName]){
+						delete this.anim[runName][index];
+					}
+				});
+			}
+			anim.action.play();
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojo.fx.Toggler"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.fx.Toggler"] = true;
+dojo.provide("dojo.fx.Toggler");
+
+dojo.declare("dojo.fx.Toggler", null, {
+	// summary:
+	//		class constructor for an animation toggler. It accepts a packed
+	//		set of arguments about what type of animation to use in each
+	//		direction, duration, etc.
+	//
+	// example:
+	//	|	var t = new dojo.fx.Toggler({
+	//	|		node: "nodeId",
+	//	|		showDuration: 500,
+	//	|		// hideDuration will default to "200"
+	//	|		showFunc: dojo.wipeIn, 
+	//	|		// hideFunc will default to "fadeOut"
+	//	|	});
+	//	|	t.show(100); // delay showing for 100ms
+	//	|	// ...time passes...
+	//	|	t.hide();
+
+	// FIXME: need a policy for where the toggler should "be" the next
+	// time show/hide are called if we're stopped somewhere in the
+	// middle.
+
+	constructor: function(args){
+		var _t = this;
+
+		dojo.mixin(_t, args);
+		_t.node = args.node;
+		_t._showArgs = dojo.mixin({}, args);
+		_t._showArgs.node = _t.node;
+		_t._showArgs.duration = _t.showDuration;
+		_t.showAnim = _t.showFunc(_t._showArgs);
+
+		_t._hideArgs = dojo.mixin({}, args);
+		_t._hideArgs.node = _t.node;
+		_t._hideArgs.duration = _t.hideDuration;
+		_t.hideAnim = _t.hideFunc(_t._hideArgs);
+
+		dojo.connect(_t.showAnim, "beforeBegin", dojo.hitch(_t.hideAnim, "stop", true));
+		dojo.connect(_t.hideAnim, "beforeBegin", dojo.hitch(_t.showAnim, "stop", true));
+	},
+
+	// node: DomNode
+	//	the node to toggle
+	node: null,
+
+	// showFunc: Function
+	//	The function that returns the dojo._Animation to show the node
+	showFunc: dojo.fadeIn,
+
+	// hideFunc: Function	
+	//	The function that returns the dojo._Animation to hide the node
+	hideFunc: dojo.fadeOut,
+
+	// showDuration:
+	//	Time in milliseconds to run the show Animation
+	showDuration: 200,
+
+	// hideDuration:
+	//	Time in milliseconds to run the hide Animation
+	hideDuration: 200,
+
+	/*=====
+	_showArgs: null,
+	_showAnim: null,
+
+	_hideArgs: null,
+	_hideAnim: null,
+
+	_isShowing: false,
+	_isHiding: false,
+	=====*/
+
+	show: function(delay){
+		// summary: Toggle the node to showing
+		return this.showAnim.play(delay || 0);
+	},
+
+	hide: function(delay){
+		// summary: Toggle the node to hidden
+		return this.hideAnim.play(delay || 0);
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojo.fx"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.fx"] = true;
+dojo.provide("dojo.fx");
+
+/*=====
+dojo.fx = {
+	// summary: Effects library on top of Base animations
+};
+=====*/
+(function(){
+	
+	var d = dojo, 
+		_baseObj = {
+			_fire: function(evt, args){
+				if(this[evt]){
+					this[evt].apply(this, args||[]);
+				}
+				return this;
+			}
+		};
+
+	var _chain = function(animations){
+		this._index = -1;
+		this._animations = animations||[];
+		this._current = this._onAnimateCtx = this._onEndCtx = null;
+
+		this.duration = 0;
+		d.forEach(this._animations, function(a){
+			this.duration += a.duration;
+			if(a.delay){ this.duration += a.delay; }
+		}, this);
+	};
+	d.extend(_chain, {
+		_onAnimate: function(){
+			this._fire("onAnimate", arguments);
+		},
+		_onEnd: function(){
+			d.disconnect(this._onAnimateCtx);
+			d.disconnect(this._onEndCtx);
+			this._onAnimateCtx = this._onEndCtx = null;
+			if(this._index + 1 == this._animations.length){
+				this._fire("onEnd");
+			}else{
+				// switch animations
+				this._current = this._animations[++this._index];
+				this._onAnimateCtx = d.connect(this._current, "onAnimate", this, "_onAnimate");
+				this._onEndCtx = d.connect(this._current, "onEnd", this, "_onEnd");
+				this._current.play(0, true);
+			}
+		},
+		play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
+			if(!this._current){ this._current = this._animations[this._index = 0]; }
+			if(!gotoStart && this._current.status() == "playing"){ return this; }
+			var beforeBegin = d.connect(this._current, "beforeBegin", this, function(){
+					this._fire("beforeBegin");
+				}),
+				onBegin = d.connect(this._current, "onBegin", this, function(arg){
+					this._fire("onBegin", arguments);
+				}),
+				onPlay = d.connect(this._current, "onPlay", this, function(arg){
+					this._fire("onPlay", arguments);
+					d.disconnect(beforeBegin);
+					d.disconnect(onBegin);
+					d.disconnect(onPlay);
+				});
+			if(this._onAnimateCtx){
+				d.disconnect(this._onAnimateCtx);
+			}
+			this._onAnimateCtx = d.connect(this._current, "onAnimate", this, "_onAnimate");
+			if(this._onEndCtx){
+				d.disconnect(this._onEndCtx);
+			}
+			this._onEndCtx = d.connect(this._current, "onEnd", this, "_onEnd");
+			this._current.play.apply(this._current, arguments);
+			return this;
+		},
+		pause: function(){
+			if(this._current){
+				var e = d.connect(this._current, "onPause", this, function(arg){
+						this._fire("onPause", arguments);
+						d.disconnect(e);
+					});
+				this._current.pause();
+			}
+			return this;
+		},
+		gotoPercent: function(/*Decimal*/percent, /*Boolean?*/ andPlay){
+			this.pause();
+			var offset = this.duration * percent;
+			this._current = null;
+			d.some(this._animations, function(a){
+				if(a.duration <= offset){
+					this._current = a;
+					return true;
+				}
+				offset -= a.duration;
+				return false;
+			});
+			if(this._current){
+				this._current.gotoPercent(offset / this._current.duration, andPlay);
+			}
+			return this;
+		},
+		stop: function(/*boolean?*/ gotoEnd){
+			if(this._current){
+				if(gotoEnd){
+					for(; this._index + 1 < this._animations.length; ++this._index){
+						this._animations[this._index].stop(true);
+					}
+					this._current = this._animations[this._index];
+				}
+				var e = d.connect(this._current, "onStop", this, function(arg){
+						this._fire("onStop", arguments);
+						d.disconnect(e);
+					});
+				this._current.stop();
+			}
+			return this;
+		},
+		status: function(){
+			return this._current ? this._current.status() : "stopped";
+		},
+		destroy: function(){
+			if(this._onAnimateCtx){ d.disconnect(this._onAnimateCtx); }
+			if(this._onEndCtx){ d.disconnect(this._onEndCtx); }
+		}
+	});
+	d.extend(_chain, _baseObj);
+
+	dojo.fx.chain = function(/*dojo._Animation[]*/ animations){
+		// summary: Chain a list of dojo._Animation s to run in sequence
+		// example:
+		//	|	dojo.fx.chain([
+		//	|		dojo.fadeIn({ node:node }),
+		//	|		dojo.fadeOut({ node:otherNode })
+		//	|	]).play();
+		//
+		return new _chain(animations) // dojo._Animation
+	};
+
+	var _combine = function(animations){
+		this._animations = animations||[];
+		this._connects = [];
+		this._finished = 0;
+
+		this.duration = 0;
+		d.forEach(animations, function(a){
+			var duration = a.duration;
+			if(a.delay){ duration += a.delay; }
+			if(this.duration < duration){ this.duration = duration; }
+			this._connects.push(d.connect(a, "onEnd", this, "_onEnd"));
+		}, this);
+		
+		this._pseudoAnimation = new d._Animation({curve: [0, 1], duration: this.duration});
+		var self = this;
+		d.forEach(["beforeBegin", "onBegin", "onPlay", "onAnimate", "onPause", "onStop"], 
+			function(evt){
+				self._connects.push(d.connect(self._pseudoAnimation, evt,
+					function(){ self._fire(evt, arguments); }
+				));
+			}
+		);
+	};
+	d.extend(_combine, {
+		_doAction: function(action, args){
+			d.forEach(this._animations, function(a){
+				a[action].apply(a, args);
+			});
+			return this;
+		},
+		_onEnd: function(){
+			if(++this._finished == this._animations.length){
+				this._fire("onEnd");
+			}
+		},
+		_call: function(action, args){
+			var t = this._pseudoAnimation;
+			t[action].apply(t, args);
+		},
+		play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
+			this._finished = 0;
+			this._doAction("play", arguments);
+			this._call("play", arguments);
+			return this;
+		},
+		pause: function(){
+			this._doAction("pause", arguments);
+			this._call("pause", arguments);
+			return this;
+		},
+		gotoPercent: function(/*Decimal*/percent, /*Boolean?*/ andPlay){
+			var ms = this.duration * percent;
+			d.forEach(this._animations, function(a){
+				a.gotoPercent(a.duration < ms ? 1 : (ms / a.duration), andPlay);
+			});
+			this._call("gotoPercent", arguments);
+			return this;
+		},
+		stop: function(/*boolean?*/ gotoEnd){
+			this._doAction("stop", arguments);
+			this._call("stop", arguments);
+			return this;
+		},
+		status: function(){
+			return this._pseudoAnimation.status();
+		},
+		destroy: function(){
+			d.forEach(this._connects, dojo.disconnect);
+		}
+	});
+	d.extend(_combine, _baseObj);
+
+	dojo.fx.combine = function(/*dojo._Animation[]*/ animations){
+		// summary: Combine an array of `dojo._Animation`s to run in parallel
+		//
+		// description:
+		//		Combine an array of `dojo._Animation`s to run in parallel, 
+		//		providing a new `dojo._Animation` instance encompasing each
+		//		animation, firing standard animation events.
+		//
+		// example:
+		//	|	dojo.fx.combine([
+		//	|		dojo.fadeIn({ node:node }),
+		//	|		dojo.fadeOut({ node:otherNode })
+		//	|	]).play();
+		//
+		// example:
+		//	When the longest animation ends, execute a function:
+		//	| 	var anim = dojo.fx.combine([
+		//	|		dojo.fadeIn({ node: n, duration:700 }),
+		//	|		dojo.fadeOut({ node: otherNode, duration: 300 })
+		//	|	]);
+		//	|	dojo.connect(anim, "onEnd", function(){
+		//	|		// overall animation is done.
+		//	|	});
+		//	|	anim.play(); // play the animation
+		//
+		return new _combine(animations); // dojo._Animation
+	};
+
+	dojo.fx.wipeIn = function(/*Object*/ args){
+		// summary:
+		//		Returns an animation that will expand the
+		//		node defined in 'args' object from it's current height to
+		//		it's natural height (with no scrollbar).
+		//		Node must have no margin/border/padding.
+		args.node = d.byId(args.node);
+		var node = args.node, s = node.style, o;
+
+		var anim = d.animateProperty(d.mixin({
+			properties: {
+				height: {
+					// wrapped in functions so we wait till the last second to query (in case value has changed)
+					start: function(){
+						// start at current [computed] height, but use 1px rather than 0
+						// because 0 causes IE to display the whole panel
+						o = s.overflow;
+						s.overflow="hidden";
+						if(s.visibility=="hidden"||s.display=="none"){
+							s.height="1px";
+							s.display="";
+							s.visibility="";
+							return 1;
+						}else{
+							var height = d.style(node, "height");
+							return Math.max(height, 1);
+						}
+					},
+					end: function(){
+						return node.scrollHeight;
+					}
+				}
+			}
+		}, args));
+
+		d.connect(anim, "onEnd", function(){ 
+			s.height = "auto";
+			s.overflow = o;
+		});
+
+		return anim; // dojo._Animation
+	}
+
+	dojo.fx.wipeOut = function(/*Object*/ args){
+		// summary:
+		//		Returns an animation that will shrink node defined in "args"
+		//		from it's current height to 1px, and then hide it.
+		var node = args.node = d.byId(args.node), s = node.style, o;
+		
+		var anim = d.animateProperty(d.mixin({
+			properties: {
+				height: {
+					end: 1 // 0 causes IE to display the whole panel
+				}
+			}
+		}, args));
+
+		d.connect(anim, "beforeBegin", function(){
+			o = s.overflow;
+			s.overflow = "hidden";
+			s.display = "";
+		});
+		d.connect(anim, "onEnd", function(){
+			s.overflow = o;
+			s.height = "auto";
+			s.display = "none";
+		});
+
+		return anim; // dojo._Animation
+	}
+
+	dojo.fx.slideTo = function(/*Object?*/ args){
+		// summary:
+		//		Returns an animation that will slide "node" 
+		//		defined in args Object from its current position to
+		//		the position defined by (args.left, args.top).
+		// example:
+		//	|	dojo.fx.slideTo({ node: node, left:"40", top:"50", unit:"px" }).play()
+
+		var node = args.node = d.byId(args.node), 
+			top = null, left = null;
+
+		var init = (function(n){
+			return function(){
+				var cs = d.getComputedStyle(n);
+				var pos = cs.position;
+				top = (pos == 'absolute' ? n.offsetTop : parseInt(cs.top) || 0);
+				left = (pos == 'absolute' ? n.offsetLeft : parseInt(cs.left) || 0);
+				if(pos != 'absolute' && pos != 'relative'){
+					var ret = d.coords(n, true);
+					top = ret.y;
+					left = ret.x;
+					n.style.position="absolute";
+					n.style.top=top+"px";
+					n.style.left=left+"px";
+				}
+			};
+		})(node);
+		init();
+
+		var anim = d.animateProperty(d.mixin({
+			properties: {
+				top: args.top || 0,
+				left: args.left || 0
+			}
+		}, args));
+		d.connect(anim, "beforeBegin", anim, init);
+
+		return anim; // dojo._Animation
+	}
+
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.action2d.Magnify"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.action2d.Magnify"] = true;
+dojo.provide("dojox.charting.action2d.Magnify");
+
+
+
+
+
+(function(){
+	var DEFAULT_SCALE = 2,
+		m = dojox.gfx.matrix,
+		gf = dojox.gfx.fx;
+	
+	dojo.declare("dojox.charting.action2d.Magnify", dojox.charting.action2d.Base, {
+		// the data description block for the widget parser
+		defaultParams: {
+			duration: 400,	// duration of the action in ms
+			easing:   dojo.fx.easing.backOut,	// easing for the action
+			scale:    DEFAULT_SCALE	// scale of magnification
+		},
+		optionalParams: {},	// no optional parameters
+		
+		constructor: function(chart, plot, kwArgs){
+			// process optional named parameters
+			this.scale = kwArgs && typeof kwArgs.scale == "number" ? kwArgs.scale : DEFAULT_SCALE;
+			
+			this.connect();
+		},
+		
+		process: function(o){
+			if(!o.shape || !(o.type in this.overOutEvents) || 
+				!("cx" in o) || !("cy" in o)){ return; }
+			
+			var runName = o.run.name, index = o.index, vector = [], anim, init, scale;
+	
+			if(runName in this.anim){
+				anim = this.anim[runName][index];
+			}else{
+				this.anim[runName] = {};
+			}
+			
+			if(anim){
+				anim.action.stop(true);
+			}else{
+				this.anim[runName][index] = anim = {};
+			}
+			
+			if(o.type == "onmouseover"){
+				init  = m.identity;
+				scale = this.scale;
+			}else{
+				init  = m.scaleAt(this.scale, o.cx, o.cy);
+				scale = 1 / this.scale;
+			}
+			
+			var kwArgs = {
+				shape:    o.shape,
+				duration: this.duration,
+				easing:   this.easing,
+				transform: [
+					{name: "scaleAt", start: [1, o.cx, o.cy], end: [scale, o.cx, o.cy]},
+					init
+				]
+			};
+			if(o.shape){
+				vector.push(gf.animateTransform(kwArgs));
+			}
+			if(o.oultine){
+				kwArgs.shape = o.outline;
+				vector.push(gf.animateTransform(kwArgs));
+			}
+			if(o.shadow){
+				kwArgs.shape = o.shadow;
+				vector.push(gf.animateTransform(kwArgs));
+			}
+			
+			if(!vector.length){
+				delete this.anim[runName][index];
+				return;
+			}
+			
+			anim.action = dojo.fx.combine(vector);
+			if(o.type == "onmouseout"){
+				dojo.connect(anim.action, "onEnd", this, function(){
+					if(this.anim[runName]){
+						delete this.anim[runName][index];
+					}
+				});
+			}
+			anim.action.play();
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.lang.functional.scan"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.lang.functional.scan"] = true;
+dojo.provide("dojox.lang.functional.scan");
+
+
+
+// This module adds high-level functions and related constructs:
+//	- "scan" family of functions
+
+// Notes:
+//	- missing high-level functions are provided with the compatible API: 
+//		scanl, scanl1, scanr, scanr1
+
+// Defined methods:
+//	- take any valid lambda argument as the functional argument
+//	- operate on dense arrays
+//	- take a string as the array argument
+//	- take an iterator objects as the array argument (only scanl, and scanl1)
+
+(function(){
+	var d = dojo, df = dojox.lang.functional, empty = {};
+
+	d.mixin(df, {
+		// classic reduce-class functions
+		scanl: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object*/ z, /*Object?*/ o){
+			// summary: repeatedly applies a binary function to an array from left 
+			//	to right using a seed value as a starting point; returns an array
+			//	of values produced by foldl() at that point.
+			if(typeof a == "string"){ a = a.split(""); }
+			o = o || d.global; f = df.lambda(f);
+			var t, n, i;
+			if(d.isArray(a)){
+				// array
+				t = new Array((n = a.length) + 1);
+				t[0] = z;
+				for(i = 0; i < n; z = f.call(o, z, a[i], i, a), t[++i] = z);
+			}else if(typeof a.hasNext == "function" && typeof a.next == "function"){
+				// iterator
+				t = [z];
+				for(i = 0; a.hasNext(); t.push(z = f.call(o, z, a.next(), i++, a)));
+			}else{
+				// object/dictionary
+				t = [z];
+				for(i in a){
+					if(!(i in empty)){
+						t.push(z = f.call(o, z, a[i], i, a));
+					}
+				}
+			}
+			return t;	// Array
+		},
+		scanl1: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
+			// summary: repeatedly applies a binary function to an array from left 
+			//	to right; returns an array of values produced by foldl1() at that 
+			//	point.
+			if(typeof a == "string"){ a = a.split(""); }
+			o = o || d.global; f = df.lambda(f);
+			var t, n, z, first = true;
+			if(d.isArray(a)){
+				// array
+				t = new Array(n = a.length);
+				t[0] = z = a[0];
+				for(var i = 1; i < n; t[i] = z = f.call(o, z, a[i], i, a), ++i);
+			}else if(typeof a.hasNext == "function" && typeof a.next == "function"){
+				// iterator
+				if(a.hasNext()){
+					t = [z = a.next()];
+					for(var i = 1; a.hasNext(); t.push(z = f.call(o, z, a.next(), i++, a)));
+				}
+			}else{
+				// object/dictionary
+				for(var i in a){
+					if(!(i in empty)){
+						if(first){
+							t = [z = a[i]];
+							first = false;
+						}else{
+							t.push(z = f.call(o, z, a[i], i, a));
+						}
+					}
+				}
+			}
+			return t;	// Array
+		},
+		scanr: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object*/ z, /*Object?*/ o){
+			// summary: repeatedly applies a binary function to an array from right
+			//	to left using a seed value as a starting point; returns an array
+			//	of values produced by foldr() at that point.
+			if(typeof a == "string"){ a = a.split(""); }
+			o = o || d.global; f = df.lambda(f);
+			var n = a.length, t = new Array(n + 1), i = n;
+			t[n] = z;
+			for(; i > 0; --i, z = f.call(o, z, a[i], i, a), t[i] = z);
+			return t;	// Array
+		},
+		scanr1: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
+			// summary: repeatedly applies a binary function to an array from right
+			//	to left; returns an array of values produced by foldr1() at that 
+			//	point.
+			if(typeof a == "string"){ a = a.split(""); }
+			o = o || d.global; f = df.lambda(f);
+			var n = a.length, t = new Array(n), z = a[n - 1], i = n - 1;
+			t[i] = z;
+			for(; i > 0; --i, z = f.call(o, z, a[i], i, a), t[i] = z);
+			return t;	// Array
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.action2d.MoveSlice"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.action2d.MoveSlice"] = true;
+dojo.provide("dojox.charting.action2d.MoveSlice");
+
+
+
+
+
+
+
+
+(function(){
+	var DEFAULT_SCALE = 1.05,
+		DEFAULT_SHIFT = 7,	// px
+		m = dojox.gfx.matrix,
+		gf = dojox.gfx.fx,
+		df = dojox.lang.functional;
+	
+	dojo.declare("dojox.charting.action2d.MoveSlice", dojox.charting.action2d.Base, {
+		// the data description block for the widget parser
+		defaultParams: {
+			duration: 400,	// duration of the action in ms
+			easing:   dojo.fx.easing.backOut,	// easing for the action
+			scale:    DEFAULT_SCALE,	// scale of magnification
+			shift:    DEFAULT_SHIFT		// shift of the slice
+		},
+		optionalParams: {},	// no optional parameters
+
+		constructor: function(chart, plot, kwArgs){
+			// process optional named parameters
+			if(!kwArgs){ kwArgs = {}; }
+			this.scale = typeof kwArgs.scale == "number" ? kwArgs.scale : DEFAULT_SCALE;
+			this.shift = typeof kwArgs.shift == "number" ? kwArgs.shift : DEFAULT_SHIFT;
+			
+			this.connect();
+		},
+		
+		process: function(o){
+			if(!o.shape || o.element != "slice" || !(o.type in this.overOutEvents)){ return; }
+			
+			if(!this.angles){
+				// calculate the running total of slice angles
+				if(typeof o.run.data[0] == "number"){
+					this.angles = df.map(df.scanl(o.run.data, "+", 0),
+						"* 2 * Math.PI / this", df.foldl(o.run.data, "+", 0));
+				}else{
+					this.angles = df.map(df.scanl(o.run.data, "a + b.y", 0),
+						"* 2 * Math.PI / this", df.foldl(o.run.data, "a + b.y", 0));
+				}
+			}
+
+			var index = o.index, anim, endScale, startOffset, endOffset,
+				angle = (this.angles[index] + this.angles[index + 1]) / 2,
+				rotateTo0  = m.rotateAt(-angle, o.cx, o.cy),
+				rotateBack = m.rotateAt( angle, o.cx, o.cy);
+	
+			anim = this.anim[index];
+			
+			if(anim){
+				anim.action.stop(true);
+			}else{
+				this.anim[index] = anim = {};
+			}
+			
+			if(o.type == "onmouseover"){
+				startOffset = 0;
+				endOffset   = this.shift;
+				endScale    = this.scale;
+			}else{
+				startOffset = this.shift;
+				endOffset   = 0;
+				endScale    = 1 / this.scale;
+			}
+			
+			anim.action = dojox.gfx.fx.animateTransform({
+				shape:    o.shape,
+				duration: this.duration,
+				easing:   this.easing,
+				transform: [
+					rotateBack,
+					{name: "translate", start: [startOffset, 0], end: [endOffset, 0]},
+					{name: "scaleAt",   start: [1, o.cx, o.cy],  end: [endScale, o.cx, o.cy]},
+					rotateTo0
+				]
+			});
+
+			if(o.type == "onmouseout"){
+				dojo.connect(anim.action, "onEnd", this, function(){
+					delete this.anim[index];
+				});
+			}
+			anim.action.play();
+		},
+		
+		reset: function(){
+			delete this.angles;
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.action2d.Shake"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.action2d.Shake"] = true;
+dojo.provide("dojox.charting.action2d.Shake");
+
+
+
+
+
+(function(){
+	var DEFAULT_SHIFT = 3,
+		m = dojox.gfx.matrix,
+		gf = dojox.gfx.fx;
+	
+	dojo.declare("dojox.charting.action2d.Shake", dojox.charting.action2d.Base, {
+		// the data description block for the widget parser
+		defaultParams: {
+			duration: 400,	// duration of the action in ms
+			easing:   dojo.fx.easing.backOut,	// easing for the action
+			shiftX:   DEFAULT_SHIFT,	// shift of the element along the X axis
+			shiftY:   DEFAULT_SHIFT		// shift of the element along the Y axis
+		},
+		optionalParams: {},	// no optional parameters
+
+		constructor: function(chart, plot, kwArgs){
+			// process optional named parameters
+			if(!kwArgs){ kwArgs = {}; }
+			this.shiftX = typeof kwArgs.shiftX == "number" ? kwArgs.shiftX : DEFAULT_SHIFT;
+			this.shiftY = typeof kwArgs.shiftY == "number" ? kwArgs.shiftY : DEFAULT_SHIFT;
+			
+			this.connect();
+		},
+		
+		process: function(o){
+			if(!o.shape || !(o.type in this.overOutEvents)){ return; }
+			
+			var runName = o.run.name, index = o.index, vector = [], anim, 
+				shiftX = o.type == "onmouseover" ? this.shiftX : -this.shiftX,
+				shiftY = o.type == "onmouseover" ? this.shiftY : -this.shiftY;
+	
+			if(runName in this.anim){
+				anim = this.anim[runName][index];
+			}else{
+				this.anim[runName] = {};
+			}
+			
+			if(anim){
+				anim.action.stop(true);
+			}else{
+				this.anim[runName][index] = anim = {};
+			}
+			
+			var kwArgs = {
+				shape:     o.shape,
+				duration:  this.duration,
+				easing:    this.easing,
+				transform: [
+					{name: "translate", start: [this.shiftX, this.shiftY], end: [0, 0]},
+					m.identity
+				]
+			};
+			if(o.shape){
+				vector.push(gf.animateTransform(kwArgs));
+			}
+			if(o.oultine){
+				kwArgs.shape = o.outline;
+				vector.push(gf.animateTransform(kwArgs));
+			}
+			if(o.shadow){
+				kwArgs.shape = o.shadow;
+				vector.push(gf.animateTransform(kwArgs));
+			}
+			
+			if(!vector.length){
+				delete this.anim[runName][index];
+				return;
+			}
+			
+			anim.action = dojo.fx.combine(vector);
+			if(o.type == "onmouseout"){
+				dojo.connect(anim.action, "onEnd", this, function(){
+					if(this.anim[runName]){
+						delete this.anim[runName][index];
+					}
+				});
+			}
+			anim.action.play();
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojo.date.stamp"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.date.stamp"] = true;
+dojo.provide("dojo.date.stamp");
+
+// Methods to convert dates to or from a wire (string) format using well-known conventions
+
+dojo.date.stamp.fromISOString = function(/*String*/formattedString, /*Number?*/defaultTime){
+	//	summary:
+	//		Returns a Date object given a string formatted according to a subset of the ISO-8601 standard.
+	//
+	//	description:
+	//		Accepts a string formatted according to a profile of ISO8601 as defined by
+	//		[RFC3339](http://www.ietf.org/rfc/rfc3339.txt), except that partial input is allowed.
+	//		Can also process dates as specified [by the W3C](http://www.w3.org/TR/NOTE-datetime)
+	//		The following combinations are valid:
+	//
+	//			* dates only
+	//			|	* yyyy
+	//			|	* yyyy-MM
+	//			|	* yyyy-MM-dd
+	// 			* times only, with an optional time zone appended
+	//			|	* THH:mm
+	//			|	* THH:mm:ss
+	//			|	* THH:mm:ss.SSS
+	// 			* and "datetimes" which could be any combination of the above
+	//
+	//		timezones may be specified as Z (for UTC) or +/- followed by a time expression HH:mm
+	//		Assumes the local time zone if not specified.  Does not validate.  Improperly formatted
+	//		input may return null.  Arguments which are out of bounds will be handled
+	// 		by the Date constructor (e.g. January 32nd typically gets resolved to February 1st)
+	//		Only years between 100 and 9999 are supported.
+	//
+  	//	formattedString:
+	//		A string such as 2005-06-30T08:05:00-07:00 or 2005-06-30 or T08:05:00
+	//
+	//	defaultTime:
+	//		Used for defaults for fields omitted in the formattedString.
+	//		Uses 1970-01-01T00:00:00.0Z by default.
+
+	if(!dojo.date.stamp._isoRegExp){
+		dojo.date.stamp._isoRegExp =
+//TODO: could be more restrictive and check for 00-59, etc.
+			/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(.\d+)?)?((?:[+-](\d{2}):(\d{2}))|Z)?)?$/;
+	}
+
+	var match = dojo.date.stamp._isoRegExp.exec(formattedString);
+	var result = null;
+
+	if(match){
+		match.shift();
+		if(match[1]){match[1]--;} // Javascript Date months are 0-based
+		if(match[6]){match[6] *= 1000;} // Javascript Date expects fractional seconds as milliseconds
+
+		if(defaultTime){
+			// mix in defaultTime.  Relatively expensive, so use || operators for the fast path of defaultTime === 0
+			defaultTime = new Date(defaultTime);
+			dojo.map(["FullYear", "Month", "Date", "Hours", "Minutes", "Seconds", "Milliseconds"], function(prop){
+				return defaultTime["get" + prop]();
+			}).forEach(function(value, index){
+				if(match[index] === undefined){
+					match[index] = value;
+				}
+			});
+		}
+		result = new Date(match[0]||1970, match[1]||0, match[2]||1, match[3]||0, match[4]||0, match[5]||0, match[6]||0);
+//		result.setFullYear(match[0]||1970); // for year < 100
+
+		var offset = 0;
+		var zoneSign = match[7] && match[7].charAt(0);
+		if(zoneSign != 'Z'){
+			offset = ((match[8] || 0) * 60) + (Number(match[9]) || 0);
+			if(zoneSign != '-'){ offset *= -1; }
+		}
+		if(zoneSign){
+			offset -= result.getTimezoneOffset();
+		}
+		if(offset){
+			result.setTime(result.getTime() + offset * 60000);
+		}
+	}
+
+	return result; // Date or null
+}
+
+/*=====
+	dojo.date.stamp.__Options = function(){
+		//	selector: String
+		//		"date" or "time" for partial formatting of the Date object.
+		//		Both date and time will be formatted by default.
+		//	zulu: Boolean
+		//		if true, UTC/GMT is used for a timezone
+		//	milliseconds: Boolean
+		//		if true, output milliseconds
+		this.selector = selector;
+		this.zulu = zulu;
+		this.milliseconds = milliseconds;
+	}
+=====*/
+
+dojo.date.stamp.toISOString = function(/*Date*/dateObject, /*dojo.date.stamp.__Options?*/options){
+	//	summary:
+	//		Format a Date object as a string according a subset of the ISO-8601 standard
+	//
+	//	description:
+	//		When options.selector is omitted, output follows [RFC3339](http://www.ietf.org/rfc/rfc3339.txt)
+	//		The local time zone is included as an offset from GMT, except when selector=='time' (time without a date)
+	//		Does not check bounds.  Only years between 100 and 9999 are supported.
+	//
+	//	dateObject:
+	//		A Date object
+
+	var _ = function(n){ return (n < 10) ? "0" + n : n; };
+	options = options || {};
+	var formattedDate = [];
+	var getter = options.zulu ? "getUTC" : "get";
+	var date = "";
+	if(options.selector != "time"){
+		var year = dateObject[getter+"FullYear"]();
+		date = ["0000".substr((year+"").length)+year, _(dateObject[getter+"Month"]()+1), _(dateObject[getter+"Date"]())].join('-');
+	}
+	formattedDate.push(date);
+	if(options.selector != "date"){
+		var time = [_(dateObject[getter+"Hours"]()), _(dateObject[getter+"Minutes"]()), _(dateObject[getter+"Seconds"]())].join(':');
+		var millis = dateObject[getter+"Milliseconds"]();
+		if(options.milliseconds){
+			time += "."+ (millis < 100 ? "0" : "") + _(millis);
+		}
+		if(options.zulu){
+			time += "Z";
+		}else if(options.selector != "time"){
+			var timezoneOffset = dateObject.getTimezoneOffset();
+			var absOffset = Math.abs(timezoneOffset);
+			time += (timezoneOffset > 0 ? "-" : "+") + 
+				_(Math.floor(absOffset/60)) + ":" + _(absOffset%60);
+		}
+		formattedDate.push(time);
+	}
+	return formattedDate.join('T'); // String
+}
+
+}
+
+if(!dojo._hasResource["dojo.parser"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.parser"] = true;
+dojo.provide("dojo.parser");
+
+
+dojo.parser = new function(){
+	// summary: The Dom/Widget parsing package
+
+	var d = dojo;
+	var dtName = d._scopeName + "Type";
+	var qry = "[" + dtName + "]";
+
+	var _anonCtr = 0, _anon = {};
+	var nameAnonFunc = function(/*Function*/anonFuncPtr, /*Object*/thisObj){
+		// summary:
+		//		Creates a reference to anonFuncPtr in thisObj with a completely
+		//		unique name. The new name is returned as a String. 
+		var nso = thisObj || _anon;
+		if(dojo.isIE){
+			var cn = anonFuncPtr["__dojoNameCache"];
+			if(cn && nso[cn] === anonFuncPtr){
+				return cn;
+			}
+		}
+		var name;
+		do{
+			name = "__" + _anonCtr++;
+		}while(name in nso)
+		nso[name] = anonFuncPtr;
+		return name; // String
+	}
+
+	function val2type(/*Object*/ value){
+		// summary:
+		//		Returns name of type of given value.
+
+		if(d.isString(value)){ return "string"; }
+		if(typeof value == "number"){ return "number"; }
+		if(typeof value == "boolean"){ return "boolean"; }
+		if(d.isFunction(value)){ return "function"; }
+		if(d.isArray(value)){ return "array"; } // typeof [] == "object"
+		if(value instanceof Date) { return "date"; } // assume timestamp
+		if(value instanceof d._Url){ return "url"; }
+		return "object";
+	}
+
+	function str2obj(/*String*/ value, /*String*/ type){
+		// summary:
+		//		Convert given string value to given type
+		switch(type){
+			case "string":
+				return value;
+			case "number":
+				return value.length ? Number(value) : NaN;
+			case "boolean":
+				// for checked/disabled value might be "" or "checked".  interpret as true.
+				return typeof value == "boolean" ? value : !(value.toLowerCase()=="false");
+			case "function":
+				if(d.isFunction(value)){
+					// IE gives us a function, even when we say something like onClick="foo"
+					// (in which case it gives us an invalid function "function(){ foo }"). 
+					//  Therefore, convert to string
+					value=value.toString();
+					value=d.trim(value.substring(value.indexOf('{')+1, value.length-1));
+				}
+				try{
+					if(value.search(/[^\w\.]+/i) != -1){
+						// TODO: "this" here won't work
+						value = nameAnonFunc(new Function(value), this);
+					}
+					return d.getObject(value, false);
+				}catch(e){ return new Function(); }
+			case "array":
+				return value ? value.split(/\s*,\s*/) : [];
+			case "date":
+				switch(value){
+					case "": return new Date("");	// the NaN of dates
+					case "now": return new Date();	// current date
+					default: return d.date.stamp.fromISOString(value);
+				}
+			case "url":
+				return d.baseUrl + value;
+			default:
+				return d.fromJson(value);
+		}
+	}
+
+	var instanceClasses = {
+		// map from fully qualified name (like "dijit.Button") to structure like
+		// { cls: dijit.Button, params: {label: "string", disabled: "boolean"} }
+	};
+	
+	function getClassInfo(/*String*/ className){
+		// className:
+		//		fully qualified name (like "dijit.form.Button")
+		// returns:
+		//		structure like
+		//			{ 
+		//				cls: dijit.Button, 
+		//				params: { label: "string", disabled: "boolean"}
+		//			}
+
+		if(!instanceClasses[className]){
+			// get pointer to widget class
+			var cls = d.getObject(className);
+			if(!d.isFunction(cls)){
+				throw new Error("Could not load class '" + className +
+					"'. Did you spell the name correctly and use a full path, like 'dijit.form.Button'?");
+			}
+			var proto = cls.prototype;
+	
+			// get table of parameter names & types
+			var params = {}, dummyClass = {};
+			for(var name in proto){
+				if(name.charAt(0)=="_"){ continue; } 	// skip internal properties
+				if(name in dummyClass){ continue; }		// skip "constructor" and "toString"
+				var defVal = proto[name];
+				params[name]=val2type(defVal);
+			}
+
+			instanceClasses[className] = { cls: cls, params: params };
+		}
+		return instanceClasses[className];
+	}
+
+	this._functionFromScript = function(script){
+		var preamble = "";
+		var suffix = "";
+		var argsStr = script.getAttribute("args");
+		if(argsStr){
+			d.forEach(argsStr.split(/\s*,\s*/), function(part, idx){
+				preamble += "var "+part+" = arguments["+idx+"]; ";
+			});
+		}
+		var withStr = script.getAttribute("with");
+		if(withStr && withStr.length){
+			d.forEach(withStr.split(/\s*,\s*/), function(part){
+				preamble += "with("+part+"){";
+				suffix += "}";
+			});
+		}
+		return new Function(preamble+script.innerHTML+suffix);
+	}
+
+	this.instantiate = function(/* Array */nodes, /* Object? */mixin){
+		// summary:
+		//		Takes array of nodes, and turns them into class instances and
+		//		potentially calls a layout method to allow them to connect with
+		//		any children		
+		// mixin: Object
+		//		An object that will be mixed in with each node in the array.
+		//		Values in the mixin will override values in the node, if they
+		//		exist.
+		var thelist = [];
+		mixin = mixin||{};
+		d.forEach(nodes, function(node){
+			if(!node){ return; }
+			var type = dtName in mixin?mixin[dtName]:node.getAttribute(dtName);
+			if(!type || !type.length){ return; }
+			var clsInfo = getClassInfo(type),
+				clazz = clsInfo.cls,
+				ps = clazz._noScript || clazz.prototype._noScript;
+
+			// read parameters (ie, attributes).
+			// clsInfo.params lists expected params like {"checked": "boolean", "n": "number"}
+			var params = {},
+				attributes = node.attributes;
+			for(var name in clsInfo.params){
+				var item = name in mixin?{value:mixin[name],specified:true}:attributes.getNamedItem(name);
+				if(!item || (!item.specified && (!dojo.isIE || name.toLowerCase()!="value"))){ continue; }
+				var value = item.value;
+				// Deal with IE quirks for 'class' and 'style'
+				switch(name){
+				case "class":
+					value = "className" in mixin?mixin.className:node.className;
+					break;
+				case "style":
+					value = "style" in mixin?mixin.style:(node.style && node.style.cssText); // FIXME: Opera?
+				}
+				var _type = clsInfo.params[name];
+				if(typeof value == "string"){
+					params[name] = str2obj(value, _type);
+				}else{
+					params[name] = value;
+				}
+			}
+
+			// Process <script type="dojo/*"> script tags
+			// <script type="dojo/method" event="foo"> tags are added to params, and passed to
+			// the widget on instantiation.
+			// <script type="dojo/method"> tags (with no event) are executed after instantiation
+			// <script type="dojo/connect" event="foo"> tags are dojo.connected after instantiation
+			// note: dojo/* script tags cannot exist in self closing widgets, like <input />
+			if(!ps){
+				var connects = [],	// functions to connect after instantiation
+					calls = [];		// functions to call after instantiation
+
+				d.query("> script[type^='dojo/']", node).orphan().forEach(function(script){
+					var event = script.getAttribute("event"),
+						type = script.getAttribute("type"),
+						nf = d.parser._functionFromScript(script);
+					if(event){
+						if(type == "dojo/connect"){
+							connects.push({event: event, func: nf});
+						}else{
+							params[event] = nf;
+						}
+					}else{
+						calls.push(nf);
+					}
+				});
+			}
+
+			var markupFactory = clazz["markupFactory"];
+			if(!markupFactory && clazz["prototype"]){
+				markupFactory = clazz.prototype["markupFactory"];
+			}
+			// create the instance
+			var instance = markupFactory ? markupFactory(params, node, clazz) : new clazz(params, node);
+			thelist.push(instance);
+
+			// map it to the JS namespace if that makes sense
+			var jsname = node.getAttribute("jsId");
+			if(jsname){
+				d.setObject(jsname, instance);
+			}
+
+			// process connections and startup functions
+			if(!ps){
+				d.forEach(connects, function(connect){
+					d.connect(instance, connect.event, null, connect.func);
+				});
+				d.forEach(calls, function(func){
+					func.call(instance);
+				});
+			}
+		});
+
+		// Call startup on each top level instance if it makes sense (as for
+		// widgets).  Parent widgets will recursively call startup on their
+		// (non-top level) children
+		d.forEach(thelist, function(instance){
+			if(	instance  && 
+				instance.startup &&
+				!instance._started && 
+				(!instance.getParent || !instance.getParent())
+			){
+				instance.startup();
+			}
+		});
+		return thelist;
+	};
+
+	this.parse = function(/*DomNode?*/ rootNode){
+		// summary:
+		//		Search specified node (or root node) recursively for class instances,
+		//		and instantiate them Searches for
+		//		dojoType="qualified.class.name"
+		var list = d.query(qry, rootNode);
+		// go build the object instances
+		var instances = this.instantiate(list);
+		return instances;
+	};
+}();
+
+//Register the parser callback. It should be the first callback
+//after the a11y test.
+
+(function(){
+	var parseRunner = function(){ 
+		if(dojo.config["parseOnLoad"] == true){
+			dojo.parser.parse(); 
+		}
+	};
+
+	// FIXME: need to clobber cross-dependency!!
+	if(dojo.exists("dijit.wai.onload") && (dijit.wai.onload === dojo._loaders[0])){
+		dojo._loaders.splice(1, 0, parseRunner);
+	}else{
+		dojo._loaders.unshift(parseRunner);
+	}
+})();
+
+}
+
+if(!dojo._hasResource["dijit._Templated"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._Templated"] = true;
+dojo.provide("dijit._Templated");
+
+
+
+
+
+dojo.declare("dijit._Templated",
+	null,
+	{
+		//	summary:
+		//		Mixin for widgets that are instantiated from a template
+		// 
+
+		// templateString: [protected] String
+		//		A string that represents the widget template. Pre-empts the
+		//		templatePath. In builds that have their strings "interned", the
+		//		templatePath is converted to an inline templateString, thereby
+		//		preventing a synchronous network call.
+		templateString: null,
+
+		// templatePath: [protected] String
+		//		Path to template (HTML file) for this widget relative to dojo.baseUrl
+		templatePath: null,
+
+		// widgetsInTemplate: [protected] Boolean
+		//		Should we parse the template to find widgets that might be
+		//		declared in markup inside it?  False by default.
+		widgetsInTemplate: false,
+
+		// skipNodeCache: [protected] Boolean
+		//		If using a cached widget template node poses issues for a
+		//		particular widget class, it can set this property to ensure
+		//		that its template is always re-built from a string
+		_skipNodeCache: false,
+
+		_stringRepl: function(tmpl){
+			// summary:
+			//		Does substitution of ${foo} type properties in template string
+			// tags:
+			//		private
+			var className = this.declaredClass, _this = this;
+			// Cache contains a string because we need to do property replacement
+			// do the property replacement
+			return dojo.string.substitute(tmpl, this, function(value, key){
+				if(key.charAt(0) == '!'){ value = dojo.getObject(key.substr(1), false, _this); }
+				if(typeof value == "undefined"){ throw new Error(className+" template:"+key); } // a debugging aide
+				if(value == null){ return ""; }
+
+				// Substitution keys beginning with ! will skip the transform step,
+				// in case a user wishes to insert unescaped markup, e.g. ${!foo}
+				return key.charAt(0) == "!" ? value :
+					// Safer substitution, see heading "Attribute values" in
+					// http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2
+					value.toString().replace(/"/g,"""); //TODO: add &amp? use encodeXML method?
+			}, this);
+		},
+
+		// method over-ride
+		buildRendering: function(){
+			// summary:
+			//		Construct the UI for this widget from a template, setting this.domNode.
+			// tags:
+			//		protected
+
+			// Lookup cached version of template, and download to cache if it
+			// isn't there already.  Returns either a DomNode or a string, depending on
+			// whether or not the template contains ${foo} replacement parameters.
+			var cached = dijit._Templated.getCachedTemplate(this.templatePath, this.templateString, this._skipNodeCache);
+
+			var node;
+			if(dojo.isString(cached)){
+				node = dojo._toDom(this._stringRepl(cached));
+			}else{
+				// if it's a node, all we have to do is clone it
+				node = cached.cloneNode(true);
+			}
+
+			this.domNode = node;
+
+			// recurse through the node, looking for, and attaching to, our
+			// attachment points and events, which should be defined on the template node.
+			this._attachTemplateNodes(node);
+
+			if(this.widgetsInTemplate){
+				var cw = (this._supportingWidgets = dojo.parser.parse(node));
+				this._attachTemplateNodes(cw, function(n,p){
+					return n[p];
+				});
+			}
+
+			this._fillContent(this.srcNodeRef);
+		},
+
+		_fillContent: function(/*DomNode*/ source){
+			// summary:
+			//		Relocate source contents to templated container node.
+			//		this.containerNode must be able to receive children, or exceptions will be thrown.
+			// tags:
+			//		protected
+			var dest = this.containerNode;
+			if(source && dest){
+				while(source.hasChildNodes()){
+					dest.appendChild(source.firstChild);
+				}
+			}
+		},
+
+		_attachTemplateNodes: function(rootNode, getAttrFunc){
+			// summary:
+			//		Iterate through the template and attach functions and nodes accordingly.	
+			// description:		
+			//		Map widget properties and functions to the handlers specified in
+			//		the dom node and it's descendants. This function iterates over all
+			//		nodes and looks for these properties:
+			//			* dojoAttachPoint
+			//			* dojoAttachEvent	
+			//			* waiRole
+			//			* waiState
+			// rootNode: DomNode|Array[Widgets]
+			//		the node to search for properties. All children will be searched.
+			// getAttrFunc: Function?
+			//		a function which will be used to obtain property for a given
+			//		DomNode/Widget
+			// tags:
+			//		private
+
+			getAttrFunc = getAttrFunc || function(n,p){ return n.getAttribute(p); };
+
+			var nodes = dojo.isArray(rootNode) ? rootNode : (rootNode.all || rootNode.getElementsByTagName("*"));
+			var x = dojo.isArray(rootNode) ? 0 : -1;
+			for(; x<nodes.length; x++){
+				var baseNode = (x == -1) ? rootNode : nodes[x];
+				if(this.widgetsInTemplate && getAttrFunc(baseNode, "dojoType")){
+					continue;
+				}
+				// Process dojoAttachPoint
+				var attachPoint = getAttrFunc(baseNode, "dojoAttachPoint");
+				if(attachPoint){
+					var point, points = attachPoint.split(/\s*,\s*/);
+					while((point = points.shift())){
+						if(dojo.isArray(this[point])){
+							this[point].push(baseNode);
+						}else{
+							this[point]=baseNode;
+						}
+					}
+				}
+
+				// Process dojoAttachEvent
+				var attachEvent = getAttrFunc(baseNode, "dojoAttachEvent");
+				if(attachEvent){
+					// NOTE: we want to support attributes that have the form
+					// "domEvent: nativeEvent; ..."
+					var event, events = attachEvent.split(/\s*,\s*/);
+					var trim = dojo.trim;
+					while((event = events.shift())){
+						if(event){
+							var thisFunc = null;
+							if(event.indexOf(":") != -1){
+								// oh, if only JS had tuple assignment
+								var funcNameArr = event.split(":");
+								event = trim(funcNameArr[0]);
+								thisFunc = trim(funcNameArr[1]);
+							}else{
+								event = trim(event);
+							}
+							if(!thisFunc){
+								thisFunc = event;
+							}
+							this.connect(baseNode, event, thisFunc);
+						}
+					}
+				}
+
+				// waiRole, waiState
+				var role = getAttrFunc(baseNode, "waiRole");
+				if(role){
+					dijit.setWaiRole(baseNode, role);
+				}
+				var values = getAttrFunc(baseNode, "waiState");
+				if(values){
+					dojo.forEach(values.split(/\s*,\s*/), function(stateValue){
+						if(stateValue.indexOf('-') != -1){
+							var pair = stateValue.split('-');
+							dijit.setWaiState(baseNode, pair[0], pair[1]);
+						}
+					});
+				}
+			}
+		}
+	}
+);
+
+// key is either templatePath or templateString; object is either string or DOM tree
+dijit._Templated._templateCache = {};
+
+dijit._Templated.getCachedTemplate = function(templatePath, templateString, alwaysUseString){
+	// summary:
+	//		Static method to get a template based on the templatePath or
+	//		templateString key
+	// templatePath: String
+	//		The URL to get the template from. dojo.uri.Uri is often passed as well.
+	// templateString: String?
+	//		a string to use in lieu of fetching the template from a URL. Takes precedence
+	//		over templatePath
+	// returns: Mixed
+	//		Either string (if there are ${} variables that need to be replaced) or just
+	//		a DOM tree (if the node can be cloned directly)
+
+	// is it already cached?
+	var tmplts = dijit._Templated._templateCache;
+	var key = templateString || templatePath;
+	var cached = tmplts[key];
+	if(cached){
+		if(!cached.ownerDocument || cached.ownerDocument == dojo.doc){
+			// string or node of the same document
+			return cached;
+		}
+		// destroy the old cached node of a different document
+		dojo.destroy(cached);
+	}
+
+	// If necessary, load template string from template path
+	if(!templateString){
+		templateString = dijit._Templated._sanitizeTemplateString(dojo.trim(dojo._getText(templatePath)));
+	}
+
+	templateString = dojo.string.trim(templateString);
+
+	if(alwaysUseString || templateString.match(/\$\{([^\}]+)\}/g)){
+		// there are variables in the template so all we can do is cache the string
+		return (tmplts[key] = templateString); //String
+	}else{
+		// there are no variables in the template so we can cache the DOM tree
+		return (tmplts[key] = dojo._toDom(templateString)); //Node
+	}
+};
+
+dijit._Templated._sanitizeTemplateString = function(/*String*/tString){
+	// summary: 
+	//		Strips <?xml ...?> declarations so that external SVG and XML
+	// 		documents can be added to a document without worry. Also, if the string
+	//		is an HTML document, only the part inside the body tag is returned.
+	if(tString){
+		tString = tString.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, "");
+		var matches = tString.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
+		if(matches){
+			tString = matches[1];
+		}
+	}else{
+		tString = "";
+	}
+	return tString; //String
+};
+
+
+if(dojo.isIE){
+	dojo.addOnWindowUnload(function(){
+		var cache = dijit._Templated._templateCache;
+		for(var key in cache){
+			var value = cache[key];
+			if(!isNaN(value.nodeType)){ // isNode equivalent
+				dojo.destroy(value);
+			}
+			delete cache[key];
+		}
+	});
+}
+
+// These arguments can be specified for widgets which are used in templates.
+// Since any widget can be specified as sub widgets in template, mix it
+// into the base widget class.  (This is a hack, but it's effective.)
+dojo.extend(dijit._Widget,{
+	dojoAttachEvent: "",
+	dojoAttachPoint: "",
+	waiRole: "",
+	waiState:""
+});
+
+}
+
+if(!dojo._hasResource["dijit.Tooltip"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.Tooltip"] = true;
+dojo.provide("dijit.Tooltip");
+
+
+
+
+dojo.declare(
+	"dijit._MasterTooltip",
+	[dijit._Widget, dijit._Templated],
+	{
+		// summary:
+		//		Internal widget that holds the actual tooltip markup,
+		//		which occurs once per page.
+		//		Called by Tooltip widgets which are just containers to hold
+		//		the markup
+		// tags:
+		//		protected
+
+		// duration: Integer
+		//		Milliseconds to fade in/fade out
+		duration: dijit.defaultDuration,
+
+		templateString:"<div class=\"dijitTooltip dijitTooltipLeft\" id=\"dojoTooltip\">\n\t<div class=\"dijitTooltipContainer dijitTooltipContents\" dojoAttachPoint=\"containerNode\" waiRole='alert'></div>\n\t<div class=\"dijitTooltipConnector\"></div>\n</div>\n",
+
+		postCreate: function(){
+			dojo.body().appendChild(this.domNode);
+
+			this.bgIframe = new dijit.BackgroundIframe(this.domNode);
+
+			// Setup fade-in and fade-out functions.
+			this.fadeIn = dojo.fadeIn({ node: this.domNode, duration: this.duration, onEnd: dojo.hitch(this, "_onShow") });
+			this.fadeOut = dojo.fadeOut({ node: this.domNode, duration: this.duration, onEnd: dojo.hitch(this, "_onHide") });
+
+		},
+
+		show: function(/*String*/ innerHTML, /*DomNode*/ aroundNode, /*String[]?*/ position){
+			// summary:
+			//		Display tooltip w/specified contents to right of specified node
+			//		(To left if there's no space on the right, or if LTR==right)
+
+			if(this.aroundNode && this.aroundNode === aroundNode){
+				return;
+			}
+
+			if(this.fadeOut.status() == "playing"){
+				// previous tooltip is being hidden; wait until the hide completes then show new one
+				this._onDeck=arguments;
+				return;
+			}
+			this.containerNode.innerHTML=innerHTML;
+
+			// Firefox bug. when innerHTML changes to be shorter than previous
+			// one, the node size will not be updated until it moves.
+			this.domNode.style.top = (this.domNode.offsetTop + 1) + "px";
+
+			// position the element and change CSS according to position[] (a list of positions to try)
+			var align = {};
+			var ltr = this.isLeftToRight();
+			dojo.forEach( (position && position.length) ? position : dijit.Tooltip.defaultPosition, function(pos){
+				switch(pos){
+					case "after":				
+						align[ltr ? "BR" : "BL"] = ltr ? "BL" : "BR";
+						break;
+					case "before":
+						align[ltr ? "BL" : "BR"] = ltr ? "BR" : "BL";
+						break;
+					case "below":
+						// first try to align left borders, next try to align right borders (or reverse for RTL mode)
+						align[ltr ? "BL" : "BR"] = ltr ? "TL" : "TR";
+						align[ltr ? "BR" : "BL"] = ltr ? "TR" : "TL";
+						break;
+					case "above":
+					default:
+						// first try to align left borders, next try to align right borders (or reverse for RTL mode)
+						align[ltr ? "TL" : "TR"] = ltr ? "BL" : "BR";
+						align[ltr ? "TR" : "TL"] = ltr ? "BR" : "BL";
+						break;
+				}
+			});
+			var pos = dijit.placeOnScreenAroundElement(this.domNode, aroundNode, align, dojo.hitch(this, "orient"));
+
+			// show it
+			dojo.style(this.domNode, "opacity", 0);
+			this.fadeIn.play();
+			this.isShowingNow = true;
+			this.aroundNode = aroundNode;
+		},
+
+		orient: function(/* DomNode */ node, /* String */ aroundCorner, /* String */ tooltipCorner){
+			// summary:
+			//		Private function to set CSS for tooltip node based on which position it's in.
+			//		This is called by the dijit popup code.
+			// tags:
+			//		protected
+
+			node.className = "dijitTooltip " +
+				{
+					"BL-TL": "dijitTooltipBelow dijitTooltipABLeft",
+					"TL-BL": "dijitTooltipAbove dijitTooltipABLeft",
+					"BR-TR": "dijitTooltipBelow dijitTooltipABRight",
+					"TR-BR": "dijitTooltipAbove dijitTooltipABRight",
+					"BR-BL": "dijitTooltipRight",
+					"BL-BR": "dijitTooltipLeft"
+				}[aroundCorner + "-" + tooltipCorner];
+		},
+
+		_onShow: function(){
+			// summary:
+			//		Called at end of fade-in operation
+			// tags:
+			//		protected
+			if(dojo.isIE){
+				// the arrow won't show up on a node w/an opacity filter
+				this.domNode.style.filter="";
+			}
+		},
+
+		hide: function(aroundNode){
+			// summary:
+			//		Hide the tooltip
+			if(this._onDeck && this._onDeck[1] == aroundNode){
+				// this hide request is for a show() that hasn't even started yet;
+				// just cancel the pending show()
+				this._onDeck=null;
+			}else if(this.aroundNode === aroundNode){
+				// this hide request is for the currently displayed tooltip
+				this.fadeIn.stop();
+				this.isShowingNow = false;
+				this.aroundNode = null;
+				this.fadeOut.play();
+			}else{
+				// just ignore the call, it's for a tooltip that has already been erased
+			}
+		},
+
+		_onHide: function(){
+			// summary:
+			//		Called at end of fade-out operation
+			// tags:
+			//		protected
+
+			this.domNode.style.cssText="";	// to position offscreen again
+			if(this._onDeck){
+				// a show request has been queued up; do it now
+				this.show.apply(this, this._onDeck);
+				this._onDeck=null;
+			}
+		}
+
+	}
+);
+
+dijit.showTooltip = function(/*String*/ innerHTML, /*DomNode*/ aroundNode, /*String[]?*/ position){
+	// summary:
+	//		Display tooltip w/specified contents in specified position.
+	//		See description of dijit.Tooltip.defaultPosition for details on position parameter.
+	//		If position is not specified then dijit.Tooltip.defaultPosition is used.
+	if(!dijit._masterTT){ dijit._masterTT = new dijit._MasterTooltip(); }
+	return dijit._masterTT.show(innerHTML, aroundNode, position);
+};
+
+dijit.hideTooltip = function(aroundNode){
+	// summary:
+	//		Hide the tooltip
+	if(!dijit._masterTT){ dijit._masterTT = new dijit._MasterTooltip(); }
+	return dijit._masterTT.hide(aroundNode);
+};
+
+dojo.declare(
+	"dijit.Tooltip",
+	dijit._Widget,
+	{
+		// summary
+		//		Pops up a tooltip (a help message) when you hover over a node.
+
+		// label: String
+		//		Text to display in the tooltip.
+		//		Specified as innerHTML when creating the widget from markup.
+		label: "",
+
+		// showDelay: Integer
+		//		Number of milliseconds to wait after hovering over/focusing on the object, before
+		//		the tooltip is displayed.
+		showDelay: 400,
+
+		// connectId: [const] String[]
+		//		Id's of domNodes to attach the tooltip to.
+		//		When user hovers over any of the specified dom nodes, the tooltip will appear.
+		//
+		//		Note: Currently connectId can only be specified on initialization, it cannot
+		//		be changed via attr('connectId', ...)
+		//
+		//		Note: in 2.0 this will be renamed to connectIds for less confusion.
+		connectId: [],
+
+		// position: String[]
+		//		See description of `dijit.Tooltip.defaultPosition` for details on position parameter.
+		position: [],
+
+		_setConnectIdAttr: function(ids){
+			// TODO: erase old conections
+
+			this._connectNodes = [];
+
+			// TODO: rename connectId to connectIds for 2.0, and remove this code converting from string to array
+			this.connectId = dojo.isArrayLike(ids) ? ids : [ids];
+			
+			dojo.forEach(this.connectId, function(id) {
+				var node = dojo.byId(id);
+				if (node) {
+					this._connectNodes.push(node);
+					dojo.forEach(["onMouseEnter", "onMouseLeave", "onFocus", "onBlur"], function(event){
+						this.connect(node, event.toLowerCase(), "_"+event);
+					}, this);
+					if(dojo.isIE){
+						// BiDi workaround
+						node.style.zoom = 1;
+					}
+				}
+			}, this);
+		},
+
+		postCreate: function(){	
+			dojo.addClass(this.domNode,"dijitTooltipData");
+		},
+
+		_onMouseEnter: function(/*Event*/ e){
+			// summary:
+			//		Handler for mouseenter event on the target node
+			// tags:
+			//		private
+			this._onHover(e);
+		},
+
+		_onMouseLeave: function(/*Event*/ e){
+			// summary:
+			//		Handler for mouseleave event on the target node
+			// tags:
+			//		private
+			this._onUnHover(e);
+		},
+
+		_onFocus: function(/*Event*/ e){
+			// summary:
+			//		Handler for focus event on the target node
+			// tags:
+			//		private
+
+			// TODO: this is dangerously named, as the dijit focus manager calls
+			// _onFocus() on any widget that gets focus (whereas in this class we
+			// are connecting onfocus on the *target* DOM node to this method
+
+			this._focus = true;
+			this._onHover(e);
+			this.inherited(arguments);
+		},
+		
+		_onBlur: function(/*Event*/ e){
+			// summary:
+			//		Handler for blur event on the target node
+			// tags:
+			//		private
+
+			// TODO: rename; see above comment
+
+			this._focus = false;
+			this._onUnHover(e);
+			this.inherited(arguments);
+		},
+
+		_onHover: function(/*Event*/ e){
+			// summary:
+			//		Despite the name of this method, it actually handles both hover and focus
+			//		events on the target node, setting a timer to show the tooltip.
+			// tags:
+			//		private
+			if(!this._showTimer){
+				var target = e.target;
+				this._showTimer = setTimeout(dojo.hitch(this, function(){this.open(target)}), this.showDelay);
+			}
+		},
+
+		_onUnHover: function(/*Event*/ e){
+			// summary:
+			//		Despite the name of this method, it actually handles both mouseleave and blur
+			//		events on the target node, hiding the tooltip.
+			// tags:
+			//		private
+
+			// keep a tooltip open if the associated element still has focus (even though the
+			// mouse moved away)
+			if(this._focus){ return; }
+
+			if(this._showTimer){
+				clearTimeout(this._showTimer);
+				delete this._showTimer;
+			}
+			this.close();
+		},
+
+		open: function(/*DomNode*/ target){
+ 			// summary:
+			//		Display the tooltip; usually not called directly.
+			// tags:
+			//		private
+
+			target = target || this._connectNodes[0];
+			if(!target){ return; }
+
+			if(this._showTimer){
+				clearTimeout(this._showTimer);
+				delete this._showTimer;
+			}
+			dijit.showTooltip(this.label || this.domNode.innerHTML, target, this.position);
+			
+			this._connectNode = target;
+		},
+
+		close: function(){
+			// summary:
+			//		Hide the tooltip or cancel timer for show of tooltip
+			// tags:
+			//		private
+
+			if(this._connectNode){
+				// if tooltip is currently shown
+				dijit.hideTooltip(this._connectNode);
+				delete this._connectNode;
+			}
+			if(this._showTimer){
+				// if tooltip is scheduled to be shown (after a brief delay)
+				clearTimeout(this._showTimer);
+				delete this._showTimer;
+			}
+		},
+
+		uninitialize: function(){
+			this.close();
+		}
+	}
+);
+
+// dijit.Tooltip.defaultPosition: String[]
+//		This variable controls the position of tooltips, if the position is not specified to
+//		the Tooltip widget or *TextBox widget itself.  It's an array of strings with the following values:
+//
+//			* before: places tooltip to the left of the target node/widget, or to the right in
+//			  the case of RTL scripts like Hebrew and Arabic
+//			* after: places tooltip to the right of the target node/widget, or to the left in
+//			  the case of RTL scripts like Hebrew and Arabic
+//			* above: tooltip goes above target node
+//			* below: tooltip goes below target node
+//
+//		The list is positions is tried, in order, until a position is found where the tooltip fits
+//		within the viewport.
+//
+//		Be careful setting this parameter.  A value of "above" may work fine until the user scrolls
+//		the screen so that there's no room above the target node.   Nodes with drop downs, like
+//		DropDownButton or FilteringSelect, are especially problematic, in that you need to be sure
+//		that the drop down and tooltip don't overlap, even when the viewport is scrolled so that there
+//		is only room below (or above) the target node, but not both.
+dijit.Tooltip.defaultPosition = ["after", "before"];
+
+}
+
+if(!dojo._hasResource["dojox.charting.action2d.Tooltip"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.action2d.Tooltip"] = true;
+dojo.provide("dojox.charting.action2d.Tooltip");
+
+
+
+
+
+
+
+
+(function(){
+	var DEFAULT_TEXT = function(o){
+		var t = o.run && o.run.data && o.run.data[o.index];
+		if(t && typeof t == "object" && t.tooltip){
+			return t.tooltip;
+		}
+		return o.element == "bar" ? o.x : o.y;
+	};
+	
+	var df = dojox.lang.functional, pi4 = Math.PI / 4, pi2 = Math.PI / 2;
+	
+	dojo.declare("dojox.charting.action2d.Tooltip", dojox.charting.action2d.Base, {
+		// the data description block for the widget parser
+		defaultParams: {
+			text: DEFAULT_TEXT	// the function to produce a tooltip from the object
+		},
+		optionalParams: {},	// no optional parameters
+
+		constructor: function(chart, plot, kwArgs){
+			// process optional named parameters
+			this.text = kwArgs && kwArgs.text ? kwArgs.text : DEFAULT_TEXT;
+			
+			this.connect();
+		},
+		
+		process: function(o){
+			if(o.type === "onplotreset" || o.type === "onmouseout"){
+				dijit.hideTooltip(this.aroundRect);
+				this.aroundRect = null;
+				return;
+			}
+			
+			if(!o.shape || o.type !== "onmouseover"){ return; }
+			
+			// calculate relative coordinates and the position
+			var aroundRect = {type: "rect"}, position = ["after", "before"];
+			switch(o.element){
+				case "marker":
+					aroundRect.x = o.cx;
+					aroundRect.y = o.cy;
+					aroundRect.width = aroundRect.height = 1;
+					break;
+				case "circle":
+					aroundRect.x = o.cx - o.cr;
+					aroundRect.y = o.cy - o.cr;
+					aroundRect.width = aroundRect.height = 2 * o.cr;
+					break;
+				case "column":
+					position = ["above", "below"];
+				case "bar":
+					aroundRect = dojo.clone(o.shape.getShape());
+					break;
+				default:
+				//case "slice":
+					if(!this.angles){
+						// calculate the running total of slice angles
+						if(typeof o.run.data[0] == "number"){
+							this.angles = df.map(df.scanl(o.run.data, "+", 0),
+								"* 2 * Math.PI / this", df.foldl(o.run.data, "+", 0));
+						}else{
+							this.angles = df.map(df.scanl(o.run.data, "a + b.y", 0),
+								"* 2 * Math.PI / this", df.foldl(o.run.data, "a + b.y", 0));
+						}
+					}
+					var angle = (this.angles[o.index] + this.angles[o.index + 1]) / 2;
+					aroundRect.x = o.cx + o.cr * Math.cos(angle);
+					aroundRect.y = o.cy + o.cr * Math.sin(angle);
+					aroundRect.width = aroundRect.height = 1;
+					// calculate the position
+					if(angle < pi4){
+						// do nothing: the position is right
+					}else if(angle < pi2 + pi4){
+						position = ["below", "above"];
+					}else if(angle < Math.PI + pi4){
+						position = ["before", "after"];
+					}else if(angle < 2 * Math.PI - pi4){
+						position = ["above", "below"];
+					}
+					/*
+					else{
+						// do nothing: the position is right
+					}
+					 */
+					break;
+			}
+			
+			// adjust relative coordinates to absolute, and remove fractions
+			var lt = dojo.coords(this.chart.node, true);
+			aroundRect.x += lt.x;
+			aroundRect.y += lt.y;
+			aroundRect.x = Math.round(aroundRect.x);
+			aroundRect.y = Math.round(aroundRect.y);
+			aroundRect.width = Math.ceil(aroundRect.width);
+			aroundRect.height = Math.ceil(aroundRect.height);
+			this.aroundRect = aroundRect;
+			
+			dijit.showTooltip(this.text(o), this.aroundRect, position);
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.widget.Chart2D"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.widget.Chart2D"] = true;
+dojo.provide("dojox.charting.widget.Chart2D");
+
+
+
+
+
+// require all actions to support references by name
+
+
+
+
+
+
+(function(){
+	var collectParams, collectAxisParams, collectPlotParams,
+		collectActionParams, collectDataParams,
+		notNull = function(o){ return o; },
+		df = dojox.lang.functional,
+		du = dojox.lang.utils,
+		dc = dojox.charting,
+		d = dojo;
+	
+	dojo.declare("dojox.charting.widget.Chart2D", dijit._Widget, {
+		// parameters for the markup
+		
+		// theme for the chart
+		theme: null,
+		
+		// margins for the chart: {l: 10, r: 10, t: 10, b: 10}
+		margins: null,
+		
+		// chart area
+		stroke: null,
+		fill:   null,
+		
+		// methods
+		
+		buildRendering: function(){
+			var n = this.domNode = this.srcNodeRef;
+			
+			// collect chart parameters
+			var axes    = d.query("> .axis", n).map(collectAxisParams).filter(notNull),
+				plots   = d.query("> .plot", n).map(collectPlotParams).filter(notNull),
+				actions = d.query("> .action", n).map(collectActionParams).filter(notNull),
+				series  = d.query("> .series", n).map(collectDataParams).filter(notNull);
+			
+			// build the chart
+			n.innerHTML = "";
+			var c = this.chart = new dc.Chart2D(n, {
+				margins: this.margins, 
+				stroke:  this.stroke,
+				fill:    this.fill
+			});
+			
+			// add collected parameters
+			if(this.theme){
+				c.setTheme(this.theme);
+			}
+			axes.forEach(function(axis){
+				c.addAxis(axis.name, axis.kwArgs);
+			});
+			plots.forEach(function(plot){
+				c.addPlot(plot.name, plot.kwArgs);
+			});
+			
+			this.actions = actions.map(function(action){
+				return new action.action(c, action.plot, action.kwArgs)
+			});
+			
+			var render = df.foldl(series, function(render, series){
+				if(series.type == "data"){
+					c.addSeries(series.name, series.data, series.kwArgs);
+					render = true;
+				}else{
+					c.addSeries(series.name, [0], series.kwArgs);
+					var kw = {};
+					du.updateWithPattern(
+						kw, 
+						series.kwArgs, 
+						{
+							"query": "", 
+							"queryOptions": null, 
+							"start": 0, 
+							"count": 1 //, 
+							// "sort": []
+						}, 
+						true
+					);
+					if(series.kwArgs.sort){
+						// sort is a complex object type and doesn't survive coercian
+						kw.sort = dojo.clone(series.kwArgs.sort);
+					}
+					d.mixin(kw, {
+						onComplete: function(data){
+							var values;
+							if("valueFn" in series.kwArgs){
+								var fn = series.kwArgs.valueFn;
+								values = d.map(data, function(x){
+									return fn(series.data.getValue(x, series.field, 0));
+								});
+							}else{
+								values = d.map(data, function(x){
+									return series.data.getValue(x, series.field, 0);
+								});
+							}
+							c.addSeries(series.name, values, series.kwArgs).render();
+						}
+					});
+					series.data.fetch(kw);
+				}
+				return render;
+			}, false);
+			if(render){ c.render(); }
+		},
+		destroy: function(){
+			// summary: properly destroy the widget
+			this.chart.destroy();
+			this.inherited(arguments);
+		},
+		resize: function(box){
+			// summary: resize the widget
+			if(box.w > 0 && box.h > 0){
+				dojo.marginBox(this.domNode, box);
+				this.chart.resize();
+			}
+		}
+	});
+	
+	collectParams = function(node, type, kw){
+		var dp = eval("(" + type + ".prototype.defaultParams)");
+		var x, attr;
+		for(x in dp){
+			if(x in kw){ continue; }
+			attr = node.getAttribute(x);
+			kw[x] = du.coerceType(dp[x], attr == null || typeof attr == "undefined" ? dp[x] : attr);
+		}
+		var op = eval("(" + type + ".prototype.optionalParams)");
+		for(x in op){
+			if(x in kw){ continue; }
+			attr = node.getAttribute(x);
+			if(attr != null){
+				kw[x] = du.coerceType(op[x], attr);
+			}
+		}
+	};
+	
+	collectAxisParams = function(node){
+		var name = node.getAttribute("name"), type = node.getAttribute("type");
+		if(!name){ return null; }
+		var o = {name: name, kwArgs: {}}, kw = o.kwArgs;
+		if(type){
+			if(dc.axis2d[type]){
+				type = dojox._scopeName + ".charting.axis2d." + type;
+			}
+			var axis = eval("(" + type + ")");
+			if(axis){ kw.type = axis; } 
+		}else{
+			type = dojox._scopeName + ".charting.axis2d.Default";
+		}
+		collectParams(node, type, kw);
+		return o;
+	};
+	
+	collectPlotParams = function(node){
+		// var name = d.attr(node, "name"), type = d.attr(node, "type");
+		var name = node.getAttribute("name"), type = node.getAttribute("type");
+		if(!name){ return null; }
+		var o = {name: name, kwArgs: {}}, kw = o.kwArgs;
+		if(type){
+			if(dc.plot2d[type]){
+				type = dojox._scopeName + ".charting.plot2d." + type;
+			}
+			var plot = eval("(" + type + ")");
+			if(plot){ kw.type = plot; } 
+		}else{
+			type = dojox._scopeName + ".charting.plot2d.Default";
+		}
+		collectParams(node, type, kw);
+		return o;
+	};
+	
+	collectActionParams = function(node){
+		// var plot = d.attr(node, "plot"), type = d.attr(node, "type");
+		var plot = node.getAttribute("plot"), type = node.getAttribute("type");
+		if(!plot){ plot = "default"; }
+		var o = {plot: plot, kwArgs: {}}, kw = o.kwArgs;
+		if(type){
+			if(dc.action2d[type]){
+				type = dojox._scopeName + ".charting.action2d." + type;
+			}
+			var action = eval("(" + type + ")");
+			if(!action){ return null; }
+			o.action = action;
+		}else{
+			return null;
+		}
+		collectParams(node, type, kw);
+		return o;
+	};
+
+	collectDataParams = function(node){
+		var ga = d.partial(d.attr, node);
+		var name = ga("name");
+		if(!name){ return null; }
+		var o = { name: name, kwArgs: {} }, kw = o.kwArgs, t;
+		t = ga("plot");
+		if(t != null){ kw.plot = t; }
+		t = ga("marker");
+		if(t != null){ kw.marker = t; }
+		t = ga("stroke");
+		if(t != null){ kw.stroke = eval("(" + t + ")"); }
+		t = ga("fill");
+		if(t != null){ kw.fill = eval("(" + t + ")"); }
+		t = ga("legend");
+		if(t != null){ kw.legend = t; }
+		t = ga("data");
+		if(t != null){
+			o.type = "data";
+			o.data = dojo.map(String(t).split(','), Number);
+			return o;
+		}
+		t = ga("array");
+		if(t != null){
+			o.type = "data";
+			o.data = eval("(" + t + ")");
+			return o;
+		}
+		t = ga("store");
+		if(t != null){
+			o.type = "store";
+			o.data = eval("(" + t + ")");
+			t = ga("field");
+			o.field = t != null ? t : "value";
+			t = ga("query");
+			if(!!t){ kw.query = t; }
+			t = ga("queryOptions");
+			if(!!t){ kw.queryOptions = eval("(" + t + ")"); }
+			t = ga("start");
+			if(!!t){ kw.start = Number(t); }
+			t = ga("count");
+			if(!!t){ kw.count = Number(t); }
+			t = ga("sort");
+			if(!!t){ kw.sort = eval("("+t+")"); }
+			t = ga("valueFn");
+			if(!!t){ kw.valueFn = df.lambda(t); }
+			return o;
+		}
+		return null;
+	};
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.themes.ET.greys"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.themes.ET.greys"] = true;
+dojo.provide("dojox.charting.themes.ET.greys");
+
+dojo.deprecated("dojox.charting.themes.ET.greys", "1.3");
+
+(function(){
+	var dxc=dojox.charting;
+	dxc.themes.ET.greys = new dxc.Theme({
+		antiAlias: false,
+		chart: {
+			stroke: null,
+			fill: "inherit"
+		},
+		plotarea: {
+			// stroke: { width: 0.2, color: "#666666" },
+			stroke: null,
+			fill: "transparent"
+		},
+		axis:{
+			stroke:{ width:	0 },
+			line:{ width:	0 },
+			majorTick:{ 
+				color:	"#666666", 
+				width:	1,
+				length: 5
+			},
+			minorTick: { 
+				color:	"black", 
+				width:	0.5, 
+				length:	2
+			},
+			font:"normal normal normal 8pt Tahoma",
+			fontColor:"#999999"
+		},
+		series:{
+			outline:{ width: 0, color: "black" },
+			stroke:	{ width: 1, color: "black" },
+			fill:	dojo.colorFromHex("#3b444b"),
+			font: "normal normal normal 7pt Tahoma",	//	label
+			fontColor: "#717171"
+		},
+		marker:{	//	any markers on a series.
+			stroke:{ width:1 },
+			fill:"#333",
+			font:"normal normal normal 7pt Tahoma",	//	label
+			fontColor:"#000"
+		},
+		colors:[
+			dojo.colorFromHex("#8a8c8f"), 
+			dojo.colorFromHex("#4b4b4b"),
+			dojo.colorFromHex("#3b444b"), 
+			dojo.colorFromHex("#2e2d30"),
+			dojo.colorFromHex("#000000") 
+		]
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.widget.Sparkline"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.widget.Sparkline"] = true;
+dojo.provide("dojox.charting.widget.Sparkline");
+
+
+
+
+(function(){
+
+	var d = dojo;
+
+	dojo.declare("dojox.charting.widget.Sparkline",
+		dojox.charting.widget.Chart2D,
+		{
+			theme: dojox.charting.themes.ET.greys,
+			margins: { l: 0, r: 0, t: 0, b: 0 },
+			type: "Lines",
+			valueFn: "Number(x)",
+			store: "",
+			field: "",
+			query: "",
+			queryOptions: "",
+			start: "0",
+			count: "Infinity",
+			sort: "",
+			data: "",
+			name: "default",
+			buildRendering: function(){
+				var n = this.srcNodeRef;
+				if(	!n.childNodes.length || // shortcut the query
+					!d.query("> .axis, > .plot, > .action, > .series", n).length){
+					var plot = document.createElement("div");
+					d.attr(plot, {
+						"class": "plot",
+						"name": "default",
+						"type": this.type
+					});
+					n.appendChild(plot);
+
+					var series = document.createElement("div");
+					d.attr(series, {
+						"class": "series",
+						plot: "default",
+						name: this.name,
+						start: this.start,
+						count: this.count,
+						valueFn: this.valueFn
+					});
+					d.forEach(
+						["store", "field", "query", "queryOptions", "sort", "data"],
+						function(i){
+							if(this[i].length){
+								d.attr(series, i, this[i]);
+							}
+						},
+						this
+					);
+					n.appendChild(series);
+				}
+				this.inherited(arguments);
+			}
+		}
+	);
+
+})();
+
+}
+
+if(!dojo._hasResource["dojox.charting.widget.Legend"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.charting.widget.Legend"] = true;
+dojo.provide("dojox.charting.widget.Legend");
+
+
+
+
+
+
+
+dojo.declare("dojox.charting.widget.Legend", [dijit._Widget, dijit._Templated], {
+	// summary: A legend for a chart. A legend contains summary labels for 
+	// each series of data contained in the chart.
+	//
+	// Set the boolean horizontal attribute to false to layout legend labels vertically.
+	//
+	// (Line or Scatter charts (colored lines with shape symbols) )
+	// -o- Series1		-X- Series2		-v- Series3
+	//
+	// (Area/Bar/Pie charts (letters represent colors))
+	// [a] Series1		[b] Series2		[c] Series3
+	
+	chartRef:   "",
+	horizontal: true,
+	
+	templateString: "<table dojoAttachPoint='legendNode' class='dojoxLegendNode'><tbody dojoAttachPoint='legendBody'></tbody></table>",
+	
+	legendNode: null,
+	legendBody: null,
+	
+	postCreate: function(){
+		if(!this.chart){
+			if(!this.chartRef){ return; }
+			this.chart = dijit.byId(this.chartRef);
+			if(!this.chart){
+				var node = dojo.byId(this.chartRef);
+				if(node){
+					this.chart = dijit.byNode(node);
+				}else{
+					
+					return;
+				}
+			}
+			this.series = this.chart.chart.series;
+		}else{
+			this.series = this.chart.series;
+		}
+		
+		this.refresh();
+	},
+	refresh: function(){
+		// summary: regenerates the legend to reflect changes to the chart
+		
+		var df = dojox.lang.functional;
+
+		// cleanup
+		if(this._surfaces){
+			dojo.forEach(this._surfaces, function(surface){
+				surface.destroy();
+			});
+		}
+		this._surfaces = [];
+		while(this.legendBody.lastChild){
+			dojo.destroy(this.legendBody.lastChild);
+		}
+
+		if(this.horizontal){
+			dojo.addClass(this.legendNode, "dojoxLegendHorizontal");
+			// make a container <tr>
+			this._tr = dojo.doc.createElement("tr");
+			this.legendBody.appendChild(this._tr);
+		}
+		
+		var s = this.series;
+		if(s.length == 0){
+			return;
+		}
+		if(s[0].chart.stack[0].declaredClass == "dojox.charting.plot2d.Pie"){
+			var t = s[0].chart.stack[0];
+			if(typeof t.run.data[0] == "number"){
+				var filteredRun = df.map(t.run.data, "Math.max(x, 0)");
+				if(df.every(filteredRun, "<= 0")){
+					return;
+				}
+				var slices = df.map(filteredRun, "/this", df.foldl(filteredRun, "+", 0));
+				dojo.forEach(slices, function(x, i){
+					this._addLabel(t.dyn[i], t._getLabel(x * 100) + "%");
+				}, this);
+			}else{
+				dojo.forEach(t.run.data, function(x, i){
+					this._addLabel(t.dyn[i], x.legend || x.text || x.y);
+				}, this);
+			}
+		}else{
+			dojo.forEach(s, function(x){
+				this._addLabel(x.dyn, x.legend || x.name);
+			}, this);
+		}
+	},
+	_addLabel: function(dyn, label){
+		// create necessary elements
+		var icon = dojo.doc.createElement("td"),
+			text = dojo.doc.createElement("td"),
+			div  = dojo.doc.createElement("div");
+		dojo.addClass(icon, "dojoxLegendIcon");
+		dojo.addClass(text, "dojoxLegendText");
+		div.style.width  = "20px";
+		div.style.height = "20px";
+		icon.appendChild(div);
+		
+		// create a skeleton
+		if(this._tr){
+			// horizontal
+			this._tr.appendChild(icon);
+			this._tr.appendChild(text);
+		}else{
+			// vertical
+			var tr = dojo.doc.createElement("tr");
+			this.legendBody.appendChild(tr);
+			tr.appendChild(icon);
+			tr.appendChild(text);
+		}
+		
+		// populate the skeleton
+		this._makeIcon(div, dyn);
+		text.innerHTML = String(label);
+	},
+	_makeIcon: function(div, dyn){
+		var mb = {h: 14, w: 14};
+		var surface = dojox.gfx.createSurface(div, mb.w, mb.h);
+		this._surfaces.push(surface);
+		if(dyn.fill){
+			// regions
+			surface.createRect({x: 2, y: 2, width: mb.w - 4, height: mb.h - 4}).
+				setFill(dyn.fill).setStroke(dyn.stroke);
+		}else if(dyn.stroke || dyn.marker){
+			// draw line
+			var line = {x1: 0, y1: mb.h / 2, x2: mb.w, y2: mb.h / 2};
+			if(dyn.stroke){
+				surface.createLine(line).setStroke(dyn.stroke);
+			}
+			if(dyn.marker){
+				// draw marker on top
+				var c = {x: mb.w / 2, y: mb.h / 2};
+				if(dyn.stroke){
+					surface.createPath({path: "M" + c.x + " " + c.y + " " + dyn.marker}).
+						setFill(dyn.stroke.color).setStroke(dyn.stroke);
+				}else{
+					surface.createPath({path: "M" + c.x + " " + c.y + " " + dyn.marker}).
+						setFill(dyn.color).setStroke(dyn.color);
+				}
+			}
+		}else{
+			// nothing
+			surface.createRect({x: 2, y: 2, width: mb.w - 4, height: mb.h - 4}).
+				setStroke("black");
+			surface.createLine({x1: 2, y1: 2, x2: mb.w - 2, y2: mb.h - 2}).setStroke("black");
+			surface.createLine({x1: 2, y1: mb.h - 2, x2: mb.w - 2, y2: 2}).setStroke("black");
+		}
+	}
+});
+
+}
+
diff --git a/dojox/charting/widget/Legend.js b/dojox/charting/widget/Legend.js
new file mode 100644
index 0000000..c11ce45
--- /dev/null
+++ b/dojox/charting/widget/Legend.js
@@ -0,0 +1,121 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.widget.Legend"]){
+dojo._hasResource["dojox.charting.widget.Legend"]=true;
+dojo.provide("dojox.charting.widget.Legend");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dojox.lang.functional.array");
+dojo.require("dojox.lang.functional.fold");
+dojo.declare("dojox.charting.widget.Legend",[dijit._Widget,dijit._Templated],{chartRef:"",horizontal:true,templateString:"<table dojoAttachPoint='legendNode' class='dojoxLegendNode'><tbody dojoAttachPoint='legendBody'></tbody></table>",legendNode:null,legendBody:null,postCreate:function(){
+if(!this.chart){
+if(!this.chartRef){
+return;
+}
+this.chart=dijit.byId(this.chartRef);
+if(!this.chart){
+var _1=dojo.byId(this.chartRef);
+if(_1){
+this.chart=dijit.byNode(_1);
+}else{
+
+return;
+}
+}
+this.series=this.chart.chart.series;
+}else{
+this.series=this.chart.series;
+}
+this.refresh();
+},refresh:function(){
+var df=dojox.lang.functional;
+if(this._surfaces){
+dojo.forEach(this._surfaces,function(_3){
+_3.destroy();
+});
+}
+this._surfaces=[];
+while(this.legendBody.lastChild){
+dojo.destroy(this.legendBody.lastChild);
+}
+if(this.horizontal){
+dojo.addClass(this.legendNode,"dojoxLegendHorizontal");
+this._tr=dojo.doc.createElement("tr");
+this.legendBody.appendChild(this._tr);
+}
+var s=this.series;
+if(s.length==0){
+return;
+}
+if(s[0].chart.stack[0].declaredClass=="dojox.charting.plot2d.Pie"){
+var t=s[0].chart.stack[0];
+if(typeof t.run.data[0]=="number"){
+var _6=df.map(t.run.data,"Math.max(x, 0)");
+if(df.every(_6,"<= 0")){
+return;
+}
+var _7=df.map(_6,"/this",df.foldl(_6,"+",0));
+dojo.forEach(_7,function(x,i){
+this._addLabel(t.dyn[i],t._getLabel(x*100)+"%");
+},this);
+}else{
+dojo.forEach(t.run.data,function(x,i){
+this._addLabel(t.dyn[i],x.legend||x.text||x.y);
+},this);
+}
+}else{
+dojo.forEach(s,function(x){
+this._addLabel(x.dyn,x.legend||x.name);
+},this);
+}
+},_addLabel:function(_d,_e){
+var _f=dojo.doc.createElement("td"),_10=dojo.doc.createElement("td"),div=dojo.doc.createElement("div");
+dojo.addClass(_f,"dojoxLegendIcon");
+dojo.addClass(_10,"dojoxLegendText");
+div.style.width="20px";
+div.style.height="20px";
+_f.appendChild(div);
+if(this._tr){
+this._tr.appendChild(_f);
+this._tr.appendChild(_10);
+}else{
+var tr=dojo.doc.createElement("tr");
+this.legendBody.appendChild(tr);
+tr.appendChild(_f);
+tr.appendChild(_10);
+}
+this._makeIcon(div,_d);
+_10.innerHTML=String(_e);
+},_makeIcon:function(div,dyn){
+var mb={h:14,w:14};
+var _16=dojox.gfx.createSurface(div,mb.w,mb.h);
+this._surfaces.push(_16);
+if(dyn.fill){
+_16.createRect({x:2,y:2,width:mb.w-4,height:mb.h-4}).setFill(dyn.fill).setStroke(dyn.stroke);
+}else{
+if(dyn.stroke||dyn.marker){
+var _17={x1:0,y1:mb.h/2,x2:mb.w,y2:mb.h/2};
+if(dyn.stroke){
+_16.createLine(_17).setStroke(dyn.stroke);
+}
+if(dyn.marker){
+var c={x:mb.w/2,y:mb.h/2};
+if(dyn.stroke){
+_16.createPath({path:"M"+c.x+" "+c.y+" "+dyn.marker}).setFill(dyn.stroke.color).setStroke(dyn.stroke);
+}else{
+_16.createPath({path:"M"+c.x+" "+c.y+" "+dyn.marker}).setFill(dyn.color).setStroke(dyn.color);
+}
+}
+}else{
+_16.createRect({x:2,y:2,width:mb.w-4,height:mb.h-4}).setStroke("black");
+_16.createLine({x1:2,y1:2,x2:mb.w-2,y2:mb.h-2}).setStroke("black");
+_16.createLine({x1:2,y1:mb.h-2,x2:mb.w-2,y2:2}).setStroke("black");
+}
+}
+}});
+}
diff --git a/dojox/charting/widget/Sparkline.js b/dojox/charting/widget/Sparkline.js
new file mode 100644
index 0000000..f1c791f
--- /dev/null
+++ b/dojox/charting/widget/Sparkline.js
@@ -0,0 +1,33 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.charting.widget.Sparkline"]){
+dojo._hasResource["dojox.charting.widget.Sparkline"]=true;
+dojo.provide("dojox.charting.widget.Sparkline");
+dojo.require("dojox.charting.widget.Chart2D");
+dojo.require("dojox.charting.themes.ET.greys");
+(function(){
+var d=dojo;
+dojo.declare("dojox.charting.widget.Sparkline",dojox.charting.widget.Chart2D,{theme:dojox.charting.themes.ET.greys,margins:{l:0,r:0,t:0,b:0},type:"Lines",valueFn:"Number(x)",store:"",field:"",query:"",queryOptions:"",start:"0",count:"Infinity",sort:"",data:"",name:"default",buildRendering:function(){
+var n=this.srcNodeRef;
+if(!n.childNodes.length||!d.query("> .axis, > .plot, > .action, > .series",n).length){
+var _3=document.createElement("div");
+d.attr(_3,{"class":"plot","name":"default","type":this.type});
+n.appendChild(_3);
+var _4=document.createElement("div");
+d.attr(_4,{"class":"series",plot:"default",name:this.name,start:this.start,count:this.count,valueFn:this.valueFn});
+d.forEach(["store","field","query","queryOptions","sort","data"],function(i){
+if(this[i].length){
+d.attr(_4,i,this[i]);
+}
+},this);
+n.appendChild(_4);
+}
+this.inherited(arguments);
+}});
+})();
+}
diff --git a/dojox/collections.js b/dojox/collections.js
new file mode 100644
index 0000000..d0bb1d9
--- /dev/null
+++ b/dojox/collections.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.collections"]){
+dojo._hasResource["dojox.collections"]=true;
+dojo.provide("dojox.collections");
+dojo.require("dojox.collections._base");
+}
diff --git a/dojox/collections/ArrayList.js b/dojox/collections/ArrayList.js
new file mode 100644
index 0000000..924798c
--- /dev/null
+++ b/dojox/collections/ArrayList.js
@@ -0,0 +1,104 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.collections.ArrayList"]){
+dojo._hasResource["dojox.collections.ArrayList"]=true;
+dojo.provide("dojox.collections.ArrayList");
+dojo.require("dojox.collections._base");
+dojox.collections.ArrayList=function(_1){
+var _2=[];
+if(_1){
+_2=_2.concat(_1);
+}
+this.count=_2.length;
+this.add=function(_3){
+_2.push(_3);
+this.count=_2.length;
+};
+this.addRange=function(a){
+if(a.getIterator){
+var e=a.getIterator();
+while(!e.atEnd()){
+this.add(e.get());
+}
+this.count=_2.length;
+}else{
+for(var i=0;i<a.length;i++){
+_2.push(a[i]);
+}
+this.count=_2.length;
+}
+};
+this.clear=function(){
+_2.splice(0,_2.length);
+this.count=0;
+};
+this.clone=function(){
+return new dojox.collections.ArrayList(_2);
+};
+this.contains=function(_7){
+for(var i=0;i<_2.length;i++){
+if(_2[i]==_7){
+return true;
+}
+}
+return false;
+};
+this.forEach=function(fn,_a){
+dojo.forEach(_2,fn,_a);
+};
+this.getIterator=function(){
+return new dojox.collections.Iterator(_2);
+};
+this.indexOf=function(_b){
+for(var i=0;i<_2.length;i++){
+if(_2[i]==_b){
+return i;
+}
+}
+return -1;
+};
+this.insert=function(i,_e){
+_2.splice(i,0,_e);
+this.count=_2.length;
+};
+this.item=function(i){
+return _2[i];
+};
+this.remove=function(obj){
+var i=this.indexOf(obj);
+if(i>=0){
+_2.splice(i,1);
+}
+this.count=_2.length;
+};
+this.removeAt=function(i){
+_2.splice(i,1);
+this.count=_2.length;
+};
+this.reverse=function(){
+_2.reverse();
+};
+this.sort=function(fn){
+if(fn){
+_2.sort(fn);
+}else{
+_2.sort();
+}
+};
+this.setByIndex=function(i,obj){
+_2[i]=obj;
+this.count=_2.length;
+};
+this.toArray=function(){
+return [].concat(_2);
+};
+this.toString=function(_16){
+return _2.join((_16||","));
+};
+};
+}
diff --git a/dojox/collections/BinaryTree.js b/dojox/collections/BinaryTree.js
new file mode 100644
index 0000000..3b4a3d7
--- /dev/null
+++ b/dojox/collections/BinaryTree.js
@@ -0,0 +1,255 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.collections.BinaryTree"]){
+dojo._hasResource["dojox.collections.BinaryTree"]=true;
+dojo.provide("dojox.collections.BinaryTree");
+dojo.require("dojox.collections._base");
+dojox.collections.BinaryTree=function(_1){
+function _2(_3,_4,_5){
+this.value=_3||null;
+this.right=_4||null;
+this.left=_5||null;
+this.clone=function(){
+var c=new _2();
+if(this.value.value){
+c.value=this.value.clone();
+}else{
+c.value=this.value;
+}
+if(this.left!=null){
+c.left=this.left.clone();
+}
+if(this.right!=null){
+c.right=this.right.clone();
+}
+return c;
+};
+this.compare=function(n){
+if(this.value>n.value){
+return 1;
+}
+if(this.value<n.value){
+return -1;
+}
+return 0;
+};
+this.compareData=function(d){
+if(this.value>d){
+return 1;
+}
+if(this.value<d){
+return -1;
+}
+return 0;
+};
+};
+function _9(_a,a){
+if(_a){
+_9(_a.left,a);
+a.push(_a.value);
+_9(_a.right,a);
+}
+};
+function _c(_d,_e){
+var s="";
+if(_d){
+s=_d.value.toString()+_e;
+s+=_c(_d.left,_e);
+s+=_c(_d.right,_e);
+}
+return s;
+};
+function _10(_11,sep){
+var s="";
+if(_11){
+s=_10(_11.left,sep);
+s+=_11.value.toString()+sep;
+s+=_10(_11.right,sep);
+}
+return s;
+};
+function _14(_15,sep){
+var s="";
+if(_15){
+s=_14(_15.left,sep);
+s+=_14(_15.right,sep);
+s+=_15.value.toString()+sep;
+}
+return s;
+};
+function _18(_19,_1a){
+if(!_19){
+return null;
+}
+var i=_19.compareData(_1a);
+if(i==0){
+return _19;
+}
+if(i>0){
+return _18(_19.left,_1a);
+}else{
+return _18(_19.right,_1a);
+}
+};
+this.add=function(_1c){
+var n=new _2(_1c);
+var i;
+var _1f=_20;
+var _21=null;
+while(_1f){
+i=_1f.compare(n);
+if(i==0){
+return;
+}
+_21=_1f;
+if(i>0){
+_1f=_1f.left;
+}else{
+_1f=_1f.right;
+}
+}
+this.count++;
+if(!_21){
+_20=n;
+}else{
+i=_21.compare(n);
+if(i>0){
+_21.left=n;
+}else{
+_21.right=n;
+}
+}
+};
+this.clear=function(){
+_20=null;
+this.count=0;
+};
+this.clone=function(){
+var c=new dojox.collections.BinaryTree();
+var itr=this.getIterator();
+while(!itr.atEnd()){
+c.add(itr.get());
+}
+return c;
+};
+this.contains=function(_24){
+return this.search(_24)!=null;
+};
+this.deleteData=function(_25){
+var _26=_20;
+var _27=null;
+var i=_26.compareData(_25);
+while(i!=0&&_26!=null){
+if(i>0){
+_27=_26;
+_26=_26.left;
+}else{
+if(i<0){
+_27=_26;
+_26=_26.right;
+}
+}
+i=_26.compareData(_25);
+}
+if(!_26){
+return;
+}
+this.count--;
+if(!_26.right){
+if(!_27){
+_20=_26.left;
+}else{
+i=_27.compare(_26);
+if(i>0){
+_27.left=_26.left;
+}else{
+if(i<0){
+_27.right=_26.left;
+}
+}
+}
+}else{
+if(!_26.right.left){
+if(!_27){
+_20=_26.right;
+}else{
+i=_27.compare(_26);
+if(i>0){
+_27.left=_26.right;
+}else{
+if(i<0){
+_27.right=_26.right;
+}
+}
+}
+}else{
+var _29=_26.right.left;
+var _2a=_26.right;
+while(_29.left!=null){
+_2a=_29;
+_29=_29.left;
+}
+_2a.left=_29.right;
+_29.left=_26.left;
+_29.right=_26.right;
+if(!_27){
+_20=_29;
+}else{
+i=_27.compare(_26);
+if(i>0){
+_27.left=_29;
+}else{
+if(i<0){
+_27.right=_29;
+}
+}
+}
+}
+}
+};
+this.getIterator=function(){
+var a=[];
+_9(_20,a);
+return new dojox.collections.Iterator(a);
+};
+this.search=function(_2c){
+return _18(_20,_2c);
+};
+this.toString=function(_2d,sep){
+if(!_2d){
+_2d=dojox.collections.BinaryTree.TraversalMethods.Inorder;
+}
+if(!sep){
+sep=",";
+}
+var s="";
+switch(_2d){
+case dojox.collections.BinaryTree.TraversalMethods.Preorder:
+s=_c(_20,sep);
+break;
+case dojox.collections.BinaryTree.TraversalMethods.Inorder:
+s=_10(_20,sep);
+break;
+case dojox.collections.BinaryTree.TraversalMethods.Postorder:
+s=_14(_20,sep);
+break;
+}
+if(s.length==0){
+return "";
+}else{
+return s.substring(0,s.length-sep.length);
+}
+};
+this.count=0;
+var _20=this.root=null;
+if(_1){
+this.add(_1);
+}
+};
+dojox.collections.BinaryTree.TraversalMethods={Preorder:1,Inorder:2,Postorder:3};
+}
diff --git a/dojox/collections/Dictionary.js b/dojox/collections/Dictionary.js
new file mode 100644
index 0000000..ddcdb5a
--- /dev/null
+++ b/dojox/collections/Dictionary.js
@@ -0,0 +1,91 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.collections.Dictionary"]){
+dojo._hasResource["dojox.collections.Dictionary"]=true;
+dojo.provide("dojox.collections.Dictionary");
+dojo.require("dojox.collections._base");
+dojox.collections.Dictionary=function(_1){
+var _2={};
+this.count=0;
+var _3={};
+this.add=function(k,v){
+var b=(k in _2);
+_2[k]=new dojox.collections.DictionaryEntry(k,v);
+if(!b){
+this.count++;
+}
+};
+this.clear=function(){
+_2={};
+this.count=0;
+};
+this.clone=function(){
+return new dojox.collections.Dictionary(this);
+};
+this.contains=this.containsKey=function(k){
+if(_3[k]){
+return false;
+}
+return (_2[k]!=null);
+};
+this.containsValue=function(v){
+var e=this.getIterator();
+while(e.get()){
+if(e.element.value==v){
+return true;
+}
+}
+return false;
+};
+this.entry=function(k){
+return _2[k];
+};
+this.forEach=function(fn,_c){
+var a=[];
+for(var p in _2){
+if(!_3[p]){
+a.push(_2[p]);
+}
+}
+dojo.forEach(a,fn,_c);
+};
+this.getKeyList=function(){
+return (this.getIterator()).map(function(_f){
+return _f.key;
+});
+};
+this.getValueList=function(){
+return (this.getIterator()).map(function(_10){
+return _10.value;
+});
+};
+this.item=function(k){
+if(k in _2){
+return _2[k].valueOf();
+}
+return undefined;
+};
+this.getIterator=function(){
+return new dojox.collections.DictionaryIterator(_2);
+};
+this.remove=function(k){
+if(k in _2&&!_3[k]){
+delete _2[k];
+this.count--;
+return true;
+}
+return false;
+};
+if(_1){
+var e=_1.getIterator();
+while(e.get()){
+this.add(e.element.key,e.element.value);
+}
+}
+};
+}
diff --git a/dojox/collections/Queue.js b/dojox/collections/Queue.js
new file mode 100644
index 0000000..fde50aa
--- /dev/null
+++ b/dojox/collections/Queue.js
@@ -0,0 +1,57 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.collections.Queue"]){
+dojo._hasResource["dojox.collections.Queue"]=true;
+dojo.provide("dojox.collections.Queue");
+dojo.require("dojox.collections._base");
+dojox.collections.Queue=function(_1){
+var q=[];
+if(_1){
+q=q.concat(_1);
+}
+this.count=q.length;
+this.clear=function(){
+q=[];
+this.count=q.length;
+};
+this.clone=function(){
+return new dojox.collections.Queue(q);
+};
+this.contains=function(o){
+for(var i=0;i<q.length;i++){
+if(q[i]==o){
+return true;
+}
+}
+return false;
+};
+this.copyTo=function(_5,i){
+_5.splice(i,0,q);
+};
+this.dequeue=function(){
+var r=q.shift();
+this.count=q.length;
+return r;
+};
+this.enqueue=function(o){
+this.count=q.push(o);
+};
+this.forEach=function(fn,_a){
+dojo.forEach(q,fn,_a);
+};
+this.getIterator=function(){
+return new dojox.collections.Iterator(q);
+};
+this.peek=function(){
+return q[0];
+};
+this.toArray=function(){
+return [].concat(q);
+};
+};
+}
diff --git a/dojox/collections/README b/dojox/collections/README
new file mode 100644
index 0000000..4f68fe8
--- /dev/null
+++ b/dojox/collections/README
@@ -0,0 +1,39 @@
+-------------------------------------------------------------------------------
+DojoX Collections
+-------------------------------------------------------------------------------
+Version 0.9
+Release date: 05/27/2007
+-------------------------------------------------------------------------------
+Project state: production
+-------------------------------------------------------------------------------
+Project authors
+	Tom Trenka (ttrenka at gmail.com)
+-------------------------------------------------------------------------------
+Project description
+
+DojoX Collections is the port of the original Dojo 0.4.x collection classes.
+It is intended for use by people who are looking for a little bit more 
+functionality out of common collections, like ArrayLists or Dictionaries.
+
+Included are the Iterator and DictionaryIterator classes, both of which can
+operate on standard arrays and objects (respectively).
+-------------------------------------------------------------------------------
+Dependencies:
+
+DojoX Collections has no dependencies, outside of Dojo Core.
+-------------------------------------------------------------------------------
+Documentation
+
+See the API documentation for Dojo (http://dojotoolkit.org/api).
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/collections.js
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/collections/*
+
+Install into the following directory structure:
+/dojox/collections/
+
+...which should be at the same level as your Dojo checkout.
+-------------------------------------------------------------------------------
diff --git a/dojox/collections/Set.js b/dojox/collections/Set.js
new file mode 100644
index 0000000..47218bb
--- /dev/null
+++ b/dojox/collections/Set.js
@@ -0,0 +1,84 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.collections.Set"]){
+dojo._hasResource["dojox.collections.Set"]=true;
+dojo.provide("dojox.collections.Set");
+dojo.require("dojox.collections.ArrayList");
+(function(){
+var _1=dojox.collections;
+_1.Set=new (function(){
+function _2(_3){
+if(_3.constructor==Array){
+return new dojox.collections.ArrayList(_3);
+}
+return _3;
+};
+this.union=function(_4,_5){
+_4=_2(_4);
+_5=_2(_5);
+var _6=new dojox.collections.ArrayList(_4.toArray());
+var e=_5.getIterator();
+while(!e.atEnd()){
+var _8=e.get();
+if(!_6.contains(_8)){
+_6.add(_8);
+}
+}
+return _6;
+};
+this.intersection=function(_9,_a){
+_9=_2(_9);
+_a=_2(_a);
+var _b=new dojox.collections.ArrayList();
+var e=_a.getIterator();
+while(!e.atEnd()){
+var _d=e.get();
+if(_9.contains(_d)){
+_b.add(_d);
+}
+}
+return _b;
+};
+this.difference=function(_e,_f){
+_e=_2(_e);
+_f=_2(_f);
+var _10=new dojox.collections.ArrayList();
+var e=_e.getIterator();
+while(!e.atEnd()){
+var _12=e.get();
+if(!_f.contains(_12)){
+_10.add(_12);
+}
+}
+return _10;
+};
+this.isSubSet=function(_13,_14){
+_13=_2(_13);
+_14=_2(_14);
+var e=_13.getIterator();
+while(!e.atEnd()){
+if(!_14.contains(e.get())){
+return false;
+}
+}
+return true;
+};
+this.isSuperSet=function(_16,_17){
+_16=_2(_16);
+_17=_2(_17);
+var e=_17.getIterator();
+while(!e.atEnd()){
+if(!_16.contains(e.get())){
+return false;
+}
+}
+return true;
+};
+})();
+})();
+}
diff --git a/dojox/collections/SortedList.js b/dojox/collections/SortedList.js
new file mode 100644
index 0000000..6e2d831
--- /dev/null
+++ b/dojox/collections/SortedList.js
@@ -0,0 +1,161 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.collections.SortedList"]){
+dojo._hasResource["dojox.collections.SortedList"]=true;
+dojo.provide("dojox.collections.SortedList");
+dojo.require("dojox.collections._base");
+dojox.collections.SortedList=function(_1){
+var _2=this;
+var _3={};
+var q=[];
+var _5=function(a,b){
+if(a.key>b.key){
+return 1;
+}
+if(a.key<b.key){
+return -1;
+}
+return 0;
+};
+var _8=function(){
+q=[];
+var e=_2.getIterator();
+while(!e.atEnd()){
+q.push(e.get());
+}
+q.sort(_5);
+};
+var _a={};
+this.count=q.length;
+this.add=function(k,v){
+if(!_3[k]){
+_3[k]=new dojox.collections.DictionaryEntry(k,v);
+this.count=q.push(_3[k]);
+q.sort(_5);
+}
+};
+this.clear=function(){
+_3={};
+q=[];
+this.count=q.length;
+};
+this.clone=function(){
+return new dojox.collections.SortedList(this);
+};
+this.contains=this.containsKey=function(k){
+if(_a[k]){
+return false;
+}
+return (_3[k]!=null);
+};
+this.containsValue=function(o){
+var e=this.getIterator();
+while(!e.atEnd()){
+var _10=e.get();
+if(_10.value==o){
+return true;
+}
+}
+return false;
+};
+this.copyTo=function(arr,i){
+var e=this.getIterator();
+var idx=i;
+while(!e.atEnd()){
+arr.splice(idx,0,e.get());
+idx++;
+}
+};
+this.entry=function(k){
+return _3[k];
+};
+this.forEach=function(fn,_17){
+dojo.forEach(q,fn,_17);
+};
+this.getByIndex=function(i){
+return q[i].valueOf();
+};
+this.getIterator=function(){
+return new dojox.collections.DictionaryIterator(_3);
+};
+this.getKey=function(i){
+return q[i].key;
+};
+this.getKeyList=function(){
+var arr=[];
+var e=this.getIterator();
+while(!e.atEnd()){
+arr.push(e.get().key);
+}
+return arr;
+};
+this.getValueList=function(){
+var arr=[];
+var e=this.getIterator();
+while(!e.atEnd()){
+arr.push(e.get().value);
+}
+return arr;
+};
+this.indexOfKey=function(k){
+for(var i=0;i<q.length;i++){
+if(q[i].key==k){
+return i;
+}
+}
+return -1;
+};
+this.indexOfValue=function(o){
+for(var i=0;i<q.length;i++){
+if(q[i].value==o){
+return i;
+}
+}
+return -1;
+};
+this.item=function(k){
+if(k in _3&&!_a[k]){
+return _3[k].valueOf();
+}
+return undefined;
+};
+this.remove=function(k){
+delete _3[k];
+_8();
+this.count=q.length;
+};
+this.removeAt=function(i){
+delete _3[q[i].key];
+_8();
+this.count=q.length;
+};
+this.replace=function(k,v){
+if(!_3[k]){
+this.add(k,v);
+return false;
+}else{
+_3[k]=new dojox.collections.DictionaryEntry(k,v);
+_8();
+return true;
+}
+};
+this.setByIndex=function(i,o){
+_3[q[i].key].value=o;
+_8();
+this.count=q.length;
+};
+if(_1){
+var e=_1.getIterator();
+while(!e.atEnd()){
+var _2a=e.get();
+q[q.length]=_3[_2a.key]=new dojox.collections.DictionaryEntry(_2a.key,_2a.value);
+}
+q.sort(_5);
+}
+};
+}
diff --git a/dojox/collections/Stack.js b/dojox/collections/Stack.js
new file mode 100644
index 0000000..51c86ac
--- /dev/null
+++ b/dojox/collections/Stack.js
@@ -0,0 +1,57 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.collections.Stack"]){
+dojo._hasResource["dojox.collections.Stack"]=true;
+dojo.provide("dojox.collections.Stack");
+dojo.require("dojox.collections._base");
+dojox.collections.Stack=function(_1){
+var q=[];
+if(_1){
+q=q.concat(_1);
+}
+this.count=q.length;
+this.clear=function(){
+q=[];
+this.count=q.length;
+};
+this.clone=function(){
+return new dojox.collections.Stack(q);
+};
+this.contains=function(o){
+for(var i=0;i<q.length;i++){
+if(q[i]==o){
+return true;
+}
+}
+return false;
+};
+this.copyTo=function(_5,i){
+_5.splice(i,0,q);
+};
+this.forEach=function(fn,_8){
+dojo.forEach(q,fn,_8);
+};
+this.getIterator=function(){
+return new dojox.collections.Iterator(q);
+};
+this.peek=function(){
+return q[(q.length-1)];
+};
+this.pop=function(){
+var r=q.pop();
+this.count=q.length;
+return r;
+};
+this.push=function(o){
+this.count=q.push(o);
+};
+this.toArray=function(){
+return [].concat(q);
+};
+};
+}
diff --git a/dojox/collections/_base.js b/dojox/collections/_base.js
new file mode 100644
index 0000000..6c4860a
--- /dev/null
+++ b/dojox/collections/_base.js
@@ -0,0 +1,71 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.collections._base"]){
+dojo._hasResource["dojox.collections._base"]=true;
+dojo.provide("dojox.collections._base");
+dojox.collections.DictionaryEntry=function(k,v){
+this.key=k;
+this.value=v;
+this.valueOf=function(){
+return this.value;
+};
+this.toString=function(){
+return String(this.value);
+};
+};
+dojox.collections.Iterator=function(_3){
+var a=_3;
+var _5=0;
+this.element=a[_5]||null;
+this.atEnd=function(){
+return (_5>=a.length);
+};
+this.get=function(){
+if(this.atEnd()){
+return null;
+}
+this.element=a[_5++];
+return this.element;
+};
+this.map=function(fn,_7){
+return dojo.map(a,fn,_7);
+};
+this.reset=function(){
+_5=0;
+this.element=a[_5];
+};
+};
+dojox.collections.DictionaryIterator=function(_8){
+var a=[];
+var _a={};
+for(var p in _8){
+if(!_a[p]){
+a.push(_8[p]);
+}
+}
+var _c=0;
+this.element=a[_c]||null;
+this.atEnd=function(){
+return (_c>=a.length);
+};
+this.get=function(){
+if(this.atEnd()){
+return null;
+}
+this.element=a[_c++];
+return this.element;
+};
+this.map=function(fn,_e){
+return dojo.map(a,fn,_e);
+};
+this.reset=function(){
+_c=0;
+this.element=a[_c];
+};
+};
+}
diff --git a/dojox/color.js b/dojox/color.js
new file mode 100644
index 0000000..2af5f8c
--- /dev/null
+++ b/dojox/color.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.color"]){
+dojo._hasResource["dojox.color"]=true;
+dojo.provide("dojox.color");
+dojo.require("dojox.color._base");
+}
diff --git a/dojox/color/Colorspace.js b/dojox/color/Colorspace.js
new file mode 100644
index 0000000..08c6131
--- /dev/null
+++ b/dojox/color/Colorspace.js
@@ -0,0 +1,472 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.color.Colorspace"]){
+dojo._hasResource["dojox.color.Colorspace"]=true;
+dojo.provide("dojox.color.Colorspace");
+dojo.require("dojox.math.matrix");
+dojox.color.Colorspace=new (function(){
+var _1=dojox.color;
+var _2=dojox.math.matrix;
+var _3=this;
+var _4={"2":{"E":{x:1/3,y:1/3,t:5400},"D50":{x:0.34567,y:0.3585,t:5000},"D55":{x:0.33242,y:0.34743,t:5500},"D65":{x:0.31271,y:0.32902,t:6500},"D75":{x:0.29902,y:0.31485,t:7500},"A":{x:0.44757,y:0.40745,t:2856},"B":{x:0.34842,y:0.35161,t:4874},"C":{x:0.31006,y:0.31616,t:6774},"9300":{x:0.2848,y:0.2932,t:9300},"F2":{x:0.37207,y:0.37512,t:4200},"F7":{x:0.31285,y:0.32918,t:6500},"F11":{x:0.38054,y:0.37691,t:4000}},"10":{"E":{x:1/3,y:1/3,t:5400},"D50":{x:0.34773,y:0.35952,t:5000},"D55":{x:0.3 [...]
+var _5={"Adobe RGB 98":[2.2,"D65",0.64,0.33,0.297361,0.21,0.71,0.627355,0.15,0.06,0.075285],"Apple RGB":[1.8,"D65",0.625,0.34,0.244634,0.28,0.595,0.672034,0.155,0.07,0.083332],"Best RGB":[2.2,"D50",0.7347,0.2653,0.228457,0.215,0.775,0.737352,0.13,0.035,0.034191],"Beta RGB":[2.2,"D50",0.6888,0.3112,0.303273,0.1986,0.7551,0.663786,0.1265,0.0352,0.032941],"Bruce RGB":[2.2,"D65",0.64,0.33,0.240995,0.28,0.65,0.683554,0.15,0.06,0.075452],"CIE RGB":[2.2,"E",0.735,0.265,0.176204,0.274,0.717,0.81 [...]
+var _6={"XYZ scaling":{ma:[[1,0,0],[0,1,0],[0,0,1]],mai:[[1,0,0],[0,1,0],[0,0,1]]},"Bradford":{ma:[[0.8951,-0.7502,0.0389],[0.2664,1.7135,-0.0685],[-0.1614,0.0367,1.0296]],mai:[[0.986993,0.432305,-0.008529],[-0.147054,0.51836,0.040043],[0.159963,0.049291,0.968487]]},"Von Kries":{ma:[[0.40024,-0.2263,0],[0.7076,1.16532,0],[-0.08081,0.0457,0.91822]],mai:[[1.859936,0.361191,0],[-1.129382,0.638812,0],[0.219897,-0.000006,1.089064]]}};
+var _7={"XYZ":{"xyY":function(_8,_9){
+_9=dojo.mixin({whitepoint:"D65",observer:"10",useApproximation:true},_9||{});
+var wp=_3.whitepoint(_9.whitepoint,_9.observer);
+var _b=_8.X+_8.Y+_8.Z;
+if(_b==0){
+var x=wp.x,y=wp.y;
+}else{
+var x=_8.X/_b,y=_8.Y/_b;
+}
+return {x:x,y:y,Y:_8.Y};
+},"Lab":function(_e,_f){
+_f=dojo.mixin({whitepoint:"D65",observer:"10",useApproximation:true},_f||{});
+var _10=_3.kappa(_f.useApproximation),_11=_3.epsilon(_f.useApproximation);
+var wp=_3.whitepoint(_f.whitepoint,_f.observer);
+var xr=_e.X/wp.x,yr=_e.Y/wp.y,zr=_e.z/wp.z;
+var fx=(xr>_11)?Math.pow(xr,1/3):(_10*xr+16)/116;
+var fy=(yr>_11)?Math.pow(yr,1/3):(_10*yr+16)/116;
+var fz=(zr>_11)?Math.pow(zr,1/3):(_10*zr+16)/116;
+var L=116*fy-16,a=500*(fx-fy),b=200*(fy-fz);
+return {L:L,a:a,b:b};
+},"Luv":function(xyz,_1d){
+_1d=dojo.mixin({whitepoint:"D65",observer:"10",useApproximation:true},_1d||{});
+var _1e=_3.kappa(_1d.useApproximation),_1f=_3.epsilon(_1d.useApproximation);
+var wp=_3.whitepoint(_1d.whitepoint,_1d.observer);
+var ud=(4*xyz.X)/(xyz.X+15*xyz.Y+3*xyz.Z);
+var vd=(9*xyz.Y)/(xyz.X+15*xyz.Y+3*xyz.Z);
+var udr=(4*wp.x)/(wp.x+15*wp.y+3*wp.z);
+var vdr=(9*wp.y)/(wp.x+15*wp.y+3*wp.z);
+var yr=xyz.Y/wp.y;
+var L=(yr>_1f)?116*Math.pow(yr,1/3)-16:_1e*yr;
+var u=13*L*(ud-udr);
+var v=13*L*(vd-vdr);
+return {L:L,u:u,v:v};
+}},"xyY":{"XYZ":function(xyY){
+if(xyY.y==0){
+var X=0,Y=0,Z=0;
+}else{
+var X=(xyY.x*xyY.Y)/xyY.y;
+var Y=xyY.Y;
+var Z=((1-xyY.x-xyY.y)*xyY.Y)/xyY.y;
+}
+return {X:X,Y:Y,Z:Z};
+}},"Lab":{"XYZ":function(lab,_2e){
+_2e=dojo.mixin({whitepoint:"D65",observer:"10",useApproximation:true},_2e||{});
+var b=_2e.useApproximation,_30=_3.kappa(b),_31=_3.epsilon(b);
+var wp=_3.whitepoint(_2e.whitepoint,_2e.observer);
+var yr=(lab.L>(_30*_31))?Math.pow((lab.L+16)/116,3):lab.L/_30;
+var fy=(yr>_31)?(lab.L+16)/116:(_30*yr+16)/116;
+var fx=(lab.a/500)+fy;
+var fz=fy-(lab.b/200);
+var _37=Math.pow(fx,3),_38=Math.pow(fz,3);
+var xr=(_37>_31)?_37:(116*fx-16)/_30;
+var zr=(_38>_31)?_38:(116*fz-16)/_30;
+return {X:xr*wp.x,Y:yr*wp.y,Z:zr*wp.z};
+},"LCHab":function(lab){
+var L=lab.L,C=Math.pow(lab.a*lab.a+lab.b*lab.b,0.5),H=Math.atan(lab.b,lab.a)*(180/Math.PI);
+if(H<0){
+H+=360;
+}
+if(H<360){
+H-=360;
+}
+return {L:L,C:C,H:H};
+}},"LCHab":{"Lab":function(lch){
+var _40=lch.H*(Math.PI/180),L=lch.L,a=lch.C/Math.pow(Math.pow(Math.tan(_40),2)+1,0.5);
+if(90<lchH&&lch.H<270){
+a=-a;
+}
+var b=Math.pow(Math.pow(lch.C,2)-Math.pow(a,2),0.5);
+if(lch.H>180){
+b=-b;
+}
+return {L:L,a:a,b:b};
+}},"Luv":{"XYZ":function(Luv,_45){
+_45=dojo.mixin({whitepoint:"D65",observer:"10",useApproximation:true},_45||{});
+var b=_45.useApproximation,_47=_3.kappa(b),_48=_3.epsilon(b);
+var wp=_3.whitepoint(_45.whitepoint,_45.observer);
+var uz=(4*wp.x)/(wp.x+15*wp.y+3*wp.z);
+var vz=(9*wp.y)/(wp.x+15*wp.y+3*wp.z);
+var Y=(Luv.L>_47*_48)?Math.pow((Luv.L+16)/116,3):Luv.L/_47;
+var a=(1/3)*(((52*Luv.L)/(Luv.u+13*Luv.L*uz))-1);
+var b=-5*Y,c=-(1/3),d=Y*(((39*Luv.L)/(Luv.v+13*Luv.L*vz))-5);
+var X=(d-b)/(a-c),Z=X*a+b;
+return {X:X,Y:Y,Z:Z};
+},"LCHuv":function(Luv){
+var L=Luv.L,C=Math.pow(Luv.u*Luv.u+Luv.v*Luv*v,0.5),H=Math.atan(Luv.v,Luv.u)*(180/Math.PI);
+if(H<0){
+H+=360;
+}
+if(H>360){
+H-=360;
+}
+return {L:L,C:C,H:H};
+}},"LCHuv":{"Luv":function(LCH){
+var _57=LCH.H*(Math.PI/180);
+var L=LCH.L,u=LCH.C/Math.pow(Math.pow(Math.tan(_57),2)+1,0.5);
+var v=Math.pow(LCH.C*LCH.C-u*u,0.5);
+if(90<LCH.H&&LCH.H>270){
+u*=-1;
+}
+if(LCH.H>180){
+v*=-1;
+}
+return {L:L,u:u,v:v};
+}}};
+var _5b={"CMY":{"CMYK":function(obj,_5d){
+return _1.fromCmy(obj).toCmyk();
+},"HSL":function(obj,_5f){
+return _1.fromCmy(obj).toHsl();
+},"HSV":function(obj,_61){
+return _1.fromCmy(obj).toHsv();
+},"Lab":function(obj,_63){
+return _7["XYZ"]["Lab"](_1.fromCmy(obj).toXYZ(_63));
+},"LCHab":function(obj,_65){
+return _7["Lab"]["LCHab"](_5b["CMY"]["Lab"](obj));
+},"LCHuv":function(obj,_67){
+return _7["LCHuv"]["Luv"](_7["Luv"]["XYZ"](_1.fromCmy(obj).toXYZ(_67)));
+},"Luv":function(obj,_69){
+return _7["Luv"]["XYZ"](_1.fromCmy(obj).toXYZ(_69));
+},"RGB":function(obj,_6b){
+return _1.fromCmy(obj);
+},"XYZ":function(obj,_6d){
+return _1.fromCmy(obj).toXYZ(_6d);
+},"xyY":function(obj,_6f){
+return _7["XYZ"]["xyY"](_1.fromCmy(obj).toXYZ(_6f));
+}},"CMYK":{"CMY":function(obj,_71){
+return _1.fromCmyk(obj).toCmy();
+},"HSL":function(obj,_73){
+return _1.fromCmyk(obj).toHsl();
+},"HSV":function(obj,_75){
+return _1.fromCmyk(obj).toHsv();
+},"Lab":function(obj,_77){
+return _7["XYZ"]["Lab"](_1.fromCmyk(obj).toXYZ(_77));
+},"LCHab":function(obj,_79){
+return _7["Lab"]["LCHab"](_5b["CMYK"]["Lab"](obj));
+},"LCHuv":function(obj,_7b){
+return _7["LCHuv"]["Luv"](_7["Luv"]["XYZ"](_1.fromCmyk(obj).toXYZ(_7b)));
+},"Luv":function(obj,_7d){
+return _7["Luv"]["XYZ"](_1.fromCmyk(obj).toXYZ(_7d));
+},"RGB":function(obj,_7f){
+return _1.fromCmyk(obj);
+},"XYZ":function(obj,_81){
+return _1.fromCmyk(obj).toXYZ(_81);
+},"xyY":function(obj,_83){
+return _7["XYZ"]["xyY"](_1.fromCmyk(obj).toXYZ(_83));
+}},"HSL":{"CMY":function(obj,_85){
+return _1.fromHsl(obj).toCmy();
+},"CMYK":function(obj,_87){
+return _1.fromHsl(obj).toCmyk();
+},"HSV":function(obj,_89){
+return _1.fromHsl(obj).toHsv();
+},"Lab":function(obj,_8b){
+return _7["XYZ"]["Lab"](_1.fromHsl(obj).toXYZ(_8b));
+},"LCHab":function(obj,_8d){
+return _7["Lab"]["LCHab"](_5b["CMYK"]["Lab"](obj));
+},"LCHuv":function(obj,_8f){
+return _7["LCHuv"]["Luv"](_7["Luv"]["XYZ"](_1.fromHsl(obj).toXYZ(_8f)));
+},"Luv":function(obj,_91){
+return _7["Luv"]["XYZ"](_1.fromHsl(obj).toXYZ(_91));
+},"RGB":function(obj,_93){
+return _1.fromHsl(obj);
+},"XYZ":function(obj,_95){
+return _1.fromHsl(obj).toXYZ(_95);
+},"xyY":function(obj,_97){
+return _7["XYZ"]["xyY"](_1.fromHsl(obj).toXYZ(_97));
+}},"HSV":{"CMY":function(obj,_99){
+return _1.fromHsv(obj).toCmy();
+},"CMYK":function(obj,_9b){
+return _1.fromHsv(obj).toCmyk();
+},"HSL":function(obj,_9d){
+return _1.fromHsv(obj).toHsl();
+},"Lab":function(obj,_9f){
+return _7["XYZ"]["Lab"](_1.fromHsv(obj).toXYZ(_9f));
+},"LCHab":function(obj,_a1){
+return _7["Lab"]["LCHab"](_5b["CMYK"]["Lab"](obj));
+},"LCHuv":function(obj,_a3){
+return _7["LCHuv"]["Luv"](_7["Luv"]["XYZ"](_1.fromHsv(obj).toXYZ(_a3)));
+},"Luv":function(obj,_a5){
+return _7["Luv"]["XYZ"](_1.fromHsv(obj).toXYZ(_a5));
+},"RGB":function(obj,_a7){
+return _1.fromHsv(obj);
+},"XYZ":function(obj,_a9){
+return _1.fromHsv(obj).toXYZ(_a9);
+},"xyY":function(obj,_ab){
+return _7["XYZ"]["xyY"](_1.fromHsv(obj).toXYZ(_ab));
+}},"Lab":{"CMY":function(obj,_ad){
+return _1.fromXYZ(_7["Lab"]["XYZ"](obj,_ad)).toCmy();
+},"CMYK":function(obj,_af){
+return _1.fromXYZ(_7["Lab"]["XYZ"](obj,_af)).toCmyk();
+},"HSL":function(obj,_b1){
+return _1.fromXYZ(_7["Lab"]["XYZ"](obj,_b1)).toHsl();
+},"HSV":function(obj,_b3){
+return _1.fromXYZ(_7["Lab"]["XYZ"](obj,_b3)).toHsv();
+},"LCHab":function(obj,_b5){
+return _7["Lab"]["LCHab"](obj,_b5);
+},"LCHuv":function(obj,_b7){
+return _7["Luv"]["LCHuv"](_7["Lab"]["XYZ"](obj,_b7),_b7);
+},"Luv":function(obj,_b9){
+return _7["XYZ"]["Luv"](_7["Lab"]["XYZ"](obj,_b9),_b9);
+},"RGB":function(obj,_bb){
+return _1.fromXYZ(_7["Lab"]["XYZ"](obj,_bb));
+},"XYZ":function(obj,_bd){
+return _7["Lab"]["XYZ"](obj,_bd);
+},"xyY":function(obj,_bf){
+return _7["XYZ"]["xyY"](_7["Lab"]["XYZ"](obj,_bf),_bf);
+}},"LCHab":{"CMY":function(obj,_c1){
+return _1.fromXYZ(_7["Lab"]["XYZ"](_7["LCHab"]["Lab"](obj),_c1),_c1).toCmy();
+},"CMYK":function(obj,_c3){
+return _1.fromXYZ(_7["Lab"]["XYZ"](_7["LCHab"]["Lab"](obj),_c3),_c3).toCmyk();
+},"HSL":function(obj,_c5){
+return _1.fromXYZ(_7["Lab"]["XYZ"](_7["LCHab"]["Lab"](obj),_c5),_c5).toHsl();
+},"HSV":function(obj,_c7){
+return _1.fromXYZ(_7["Lab"]["XYZ"](_7["LCHab"]["Lab"](obj),_c7),_c7).toHsv();
+},"Lab":function(obj,_c9){
+return _7["Lab"]["LCHab"](obj,_c9);
+},"LCHuv":function(obj,_cb){
+return _7["Luv"]["LCHuv"](_7["XYZ"]["Luv"](_7["Lab"]["XYZ"](_7["LCHab"]["Lab"](obj),_cb),_cb),_cb);
+},"Luv":function(obj,_cd){
+return _7["XYZ"]["Luv"](_7["Lab"]["XYZ"](_7["LCHab"]["Lab"](obj),_cd),_cd);
+},"RGB":function(obj,_cf){
+return _1.fromXYZ(_7["Lab"]["XYZ"](_7["LCHab"]["Lab"](obj),_cf),_cf);
+},"XYZ":function(obj,_d1){
+return _7["Lab"]["XYZ"](_7["LCHab"]["Lab"](obj,_d1),_d1);
+},"xyY":function(obj,_d3){
+return _7["XYZ"]["xyY"](_7["Lab"]["XYZ"](_7["LCHab"]["Lab"](obj),_d3),_d3);
+}},"LCHuv":{"CMY":function(obj,_d5){
+return _1.fromXYZ(_7["Luv"]["XYZ"](_7["LCHuv"]["Luv"](obj),_d5),_d5).toCmy();
+},"CMYK":function(obj,_d7){
+return _1.fromXYZ(_7["Luv"]["XYZ"](_7["LCHuv"]["Luv"](obj),_d7),_d7).toCmyk();
+},"HSL":function(obj,_d9){
+return _1.fromXYZ(_7["Luv"]["XYZ"](_7["LCHuv"]["Luv"](obj),_d9),_d9).toHsl();
+},"HSV":function(obj,_db){
+return _1.fromXYZ(_7["Luv"]["XYZ"](_7["LCHuv"]["Luv"](obj),_db),_db).toHsv();
+},"Lab":function(obj,_dd){
+return _7["XYZ"]["Lab"](_7["Luv"]["XYZ"](_7["LCHuv"]["Luv"](obj),_dd),_dd);
+},"LCHab":function(obj,_df){
+return _7["Lab"]["LCHab"](_7["XYZ"]["Lab"](_7["Luv"]["XYZ"](_7["LCHuv"]["Luv"](obj),_df),_df),_df);
+},"Luv":function(obj,_e1){
+return _7["LCHuv"]["Luv"](obj,_e1);
+},"RGB":function(obj,_e3){
+return _1.fromXYZ(_7["Luv"]["XYZ"](_7["LCHuv"]["Luv"](obj),_e3),_e3);
+},"XYZ":function(obj,_e5){
+return _7["Luv"]["XYZ"](_7["LCHuv"]["Luv"](obj),_e5);
+},"xyY":function(obj,_e7){
+return _7["XYZ"]["xyY"](_7["Luv"]["XYZ"](_7["LCHuv"]["Luv"](obj),_e7),_e7);
+}},"Luv":{"CMY":function(obj,_e9){
+return _1.fromXYZ(_7["Luv"]["XYZ"](obj,_e9),_e9).toCmy();
+},"CMYK":function(obj,_eb){
+return _1.fromXYZ(_7["Luv"]["XYZ"](obj,_eb),_eb).toCmyk();
+},"HSL":function(obj,_ed){
+return _1.fromXYZ(_7["Luv"]["XYZ"](obj,_ed),_ed).toHsl();
+},"HSV":function(obj,_ef){
+return _1.fromXYZ(_7["Luv"]["XYZ"](obj,_ef),_ef).toHsv();
+},"Lab":function(obj,_f1){
+return _7["XYZ"]["Lab"](_7["Luv"]["XYZ"](obj,_f1),_f1);
+},"LCHab":function(obj,_f3){
+return _7["Lab"]["LCHab"](_7["XYZ"]["Lab"](_7["Luv"]["XYZ"](obj,_f3),_f3),_f3);
+},"LCHuv":function(obj,_f5){
+return _7["Luv"]["LCHuv"](obj,_f5);
+},"RGB":function(obj,_f7){
+return _1.fromXYZ(_7["Luv"]["XYZ"](obj,_f7),_f7);
+},"XYZ":function(obj,_f9){
+return _7["Luv"]["XYZ"](obj,_f9);
+},"xyY":function(obj,_fb){
+return _7["XYZ"]["xyY"](_7["Luv"]["XYZ"](obj,_fb),_fb);
+}},"RGB":{"CMY":function(obj,_fd){
+return obj.toCmy();
+},"CMYK":function(obj,_ff){
+return obj.toCmyk();
+},"HSL":function(obj,_101){
+return obj.toHsl();
+},"HSV":function(obj,_103){
+return obj.toHsv();
+},"Lab":function(obj,_105){
+return _7["XYZ"]["Lab"](obj.toXYZ(_105),_105);
+},"LCHab":function(obj,_107){
+return _7["LCHab"]["Lab"](_7["XYZ"]["Lab"](obj.toXYZ(_107),_107),_107);
+},"LCHuv":function(obj,_109){
+return _7["LCHuv"]["Luv"](_7["XYZ"]["Luv"](obj.toXYZ(_109),_109),_109);
+},"Luv":function(obj,_10b){
+return _7["XYZ"]["Luv"](obj.toXYZ(_10b),_10b);
+},"XYZ":function(obj,_10d){
+return obj.toXYZ(_10d);
+},"xyY":function(obj,_10f){
+return _7["XYZ"]["xyY"](obj.toXYZ(_10f),_10f);
+}},"XYZ":{"CMY":function(obj,_111){
+return _1.fromXYZ(obj,_111).toCmy();
+},"CMYK":function(obj,_113){
+return _1.fromXYZ(obj,_113).toCmyk();
+},"HSL":function(obj,_115){
+return _1.fromXYZ(obj,_115).toHsl();
+},"HSV":function(obj,_117){
+return _1.fromXYZ(obj,_117).toHsv();
+},"Lab":function(obj,_119){
+return _7["XYZ"]["Lab"](obj,_119);
+},"LCHab":function(obj,_11b){
+return _7["Lab"]["LCHab"](_7["XYZ"]["Lab"](obj,_11b),_11b);
+},"LCHuv":function(obj,_11d){
+return _7["Luv"]["LCHuv"](_7["XYZ"]["Luv"](obj,_11d),_11d);
+},"Luv":function(obj,_11f){
+return _7["XYZ"]["Luv"](obj,_11f);
+},"RGB":function(obj,_121){
+return _1.fromXYZ(obj,_121);
+},"xyY":function(obj,_123){
+return _7["XYZ"]["xyY"](_1.fromXYZ(obj,_123),_123);
+}},"xyY":{"CMY":function(obj,_125){
+return _1.fromXYZ(_7["xyY"]["XYZ"](obj,_125),_125).toCmy();
+},"CMYK":function(obj,_127){
+return _1.fromXYZ(_7["xyY"]["XYZ"](obj,_127),_127).toCmyk();
+},"HSL":function(obj,_129){
+return _1.fromXYZ(_7["xyY"]["XYZ"](obj,_129),_129).toHsl();
+},"HSV":function(obj,_12b){
+return _1.fromXYZ(_7["xyY"]["XYZ"](obj,_12b),_12b).toHsv();
+},"Lab":function(obj,_12d){
+return _7["Lab"]["XYZ"](_7["xyY"]["XYZ"](obj,_12d),_12d);
+},"LCHab":function(obj,_12f){
+return _7["LCHab"]["Lab"](_7["Lab"]["XYZ"](_7["xyY"]["XYZ"](obj,_12f),_12f),_12f);
+},"LCHuv":function(obj,_131){
+return _7["LCHuv"]["Luv"](_7["Luv"]["XYZ"](_7["xyY"]["XYZ"](obj,_131),_131),_131);
+},"Luv":function(obj,_133){
+return _7["Luv"]["XYZ"](_7["xyY"]["XYZ"](obj,_133),_133);
+},"RGB":function(obj,_135){
+return _1.fromXYZ(_7["xyY"]["XYZ"](obj,_135),_135);
+},"XYZ":function(obj,_137){
+return _7["xyY"]["XYZ"](obj,_137);
+}}};
+this.whitepoint=function(_138,_139){
+_139=_139||"10";
+var x=0,y=0,t=0;
+if(_4[_139]&&_4[_139][_138]){
+x=_4[_139][_138].x;
+y=_4[_139][_138].y;
+t=_4[_139][_138].t;
+}else{
+console.warn("dojox.color.Colorspace::whitepoint: either the observer or the whitepoint name was not found. ",_139,_138);
+}
+var wp={x:x,y:y,z:(1-x-y),t:t,Y:1};
+return this.convert(wp,"xyY","XYZ");
+};
+this.tempToWhitepoint=function(t){
+if(t<4000){
+console.warn("dojox.color.Colorspace::tempToWhitepoint: can't find a white point for temperatures less than 4000K. (Passed ",t,").");
+return {x:0,y:0};
+}
+if(t>25000){
+console.warn("dojox.color.Colorspace::tempToWhitepoint: can't find a white point for temperatures greater than 25000K. (Passed ",t,").");
+return {x:0,y:0};
+}
+var t1=t,t2=t*t,t3=t2*t;
+var ten9=Math.pow(10,9),ten6=Math.pow(10,6),ten3=Math.pow(10,3);
+if(t<=7000){
+var x=(-4.607*ten9/t3)+(2.9678*ten6/t2)+(0.09911*ten3/t)+0.2444063;
+}else{
+var x=(-2.0064*ten9/t3)+(1.9018*ten6/t2)+(0.24748*ten3/t)+0.23704;
+}
+var y=-3*x*x+2.87*x-0.275;
+return {x:x,y:y};
+};
+this.primaries=function(_147){
+_147=dojo.mixin({profile:"sRGB",whitepoint:"D65",observer:"10",adaptor:"Bradford"},_147||{});
+var m=[];
+if(_5[_147.profile]){
+m=_5[_147.profile].slice(0);
+}else{
+console.warn("dojox.color.Colorspace::primaries: the passed profile was not found.  ","Available profiles include: ",_5,".  The profile passed was ",_147.profile);
+}
+var _149={name:_147.profile,gamma:m[0],whitepoint:m[1],xr:m[2],yr:m[3],Yr:m[4],xg:m[5],yg:m[6],Yg:m[7],xb:m[8],yb:m[9],Yb:m[10]};
+if(_147.whitepoint!=_149.whitepoint){
+var r=this.convert(this.adapt({color:this.convert({x:xr,y:yr,Y:Yr},"xyY","XYZ"),adaptor:_147.adaptor,source:_149.whitepoint,destination:_147.whitepoint}),"XYZ","xyY");
+var g=this.convert(this.adapt({color:this.convert({x:xg,y:yg,Y:Yg},"xyY","XYZ"),adaptor:_147.adaptor,source:_149.whitepoint,destination:_147.whitepoint}),"XYZ","xyY");
+var b=this.convert(this.adapt({color:this.convert({x:xb,y:yb,Y:Yb},"xyY","XYZ"),adaptor:_147.adaptor,source:_149.whitepoint,destination:_147.whitepoint}),"XYZ","xyY");
+_149=dojo.mixin(_149,{xr:r.x,yr:r.y,Yr:r.Y,xg:g.x,yg:g.y,Yg:g.Y,xb:b.x,yb:b.y,Yb:b.Y,whitepoint:_147.whitepoint});
+}
+return dojo.mixin(_149,{zr:1-_149.xr-_149.yr,zg:1-_149.xg-_149.yg,zb:1-_149.xb-_149.yb});
+};
+this.adapt=function(_14d){
+if(!_14d.color||!_14d.source){
+console.error("dojox.color.Colorspace::adapt: color and source arguments are required. ",_14d);
+}
+_14d=dojo.mixin({adaptor:"Bradford",destination:"D65"},_14d);
+var swp=this.whitepoint(_14d.source);
+var dwp=this.whitepoint(_14d.destination);
+if(_6[_14d.adaptor]){
+var ma=_6[_14d.adaptor].ma;
+var mai=_6[_14d.adaptor].mai;
+}else{
+console.warn("dojox.color.Colorspace::adapt: the passed adaptor '",_14d.adaptor,"' was not found.");
+}
+var dSrc=_2.multiply([[swp.x,swp.y,swp.z]],ma);
+var _153=_2.multiply([[dwp.x,dwp.y,dwp.z]],ma);
+var _154=[[_153[0][0]/dSrc[0][0],0,0],[0,_153[0][1]/dSrc[0][1],0],[0,0,_153[0][2]/dSrc[0][2]]];
+var m=_2.multiply(_2.multiply(ma,_154),mai);
+var r=_2.multiply([[_14d.color.X,_14d.color.Y,_14d.color.Z]],m)[0];
+return {X:r[0],Y:r[1],Z:r[2]};
+};
+this.matrix=function(to,_158){
+var wp=this.whitepoint(_158.whitepoint);
+var Xr=p.xr/p.yr,Yr=1,Zr=(1-p.xr-p.yr)/p.yr;
+var Xg=p.xg/p.yg,Yg=1,Zg=(1-p.xg-p.yg)/p.yg;
+var Xb=p.xb/p.yb,Yb=1,Zr=(1-p.xb-p.yb)/p.yb;
+var m1=[[Xr,Yr,Zr],[Xg,Yg,Zg],[Xb,Yb,Zb]];
+var m2=[[wp.X,wp.Y,wp.Z]];
+var sm=dojox.math.matrix.multiply(m2,dojox.math.matrix.inverse(m1));
+var Sr=sm[0][0],Sg=sm[0][1],Sb=sm[0][2];
+var _168=[[Sr*Xr,Sr*Yr,Sr*Zr],[Sg*Xg,Sg*Yg,Sg*Zg],[Sb*Xb,Sb*Yb,Sb*Zb]];
+if(to=="RGB"){
+return dojox.math.inverse(_168);
+}
+return _168;
+};
+this.epsilon=function(_169){
+return (_169||typeof (_169)=="undefined")?0.008856:216/24289;
+};
+this.kappa=function(_16a){
+return (_16a||typeof (_16a)=="undefined")?903.3:24389/27;
+};
+this.convert=function(_16b,from,to,_16e){
+if(_5b[from]&&_5b[from][to]){
+return _5b[from][to](obj,_16e);
+}
+console.warn("dojox.color.Colorspace::convert: Can't convert ",_16b," from ",from," to ",to,".");
+};
+})();
+dojo.mixin(dojox.color,{fromXYZ:function(xyz,_170){
+_170=_170||{};
+var p=dojox.color.Colorspace.primaries(_170);
+var m=dojox.color.Colorspace.matrix("RGB",p);
+var rgb=dojox.math.matrix.mutliply([[xyz.X,xyz.Y,xyz.Z]],m);
+var r=rgb[0][0],g=rgb[0][1],b=rgb[0][2];
+if(p.profile=="sRGB"){
+var R=(r>0.0031308)?(1.055*Math.pow(r,1/2.4))-0.055:12.92*r;
+var G=(g>0.0031308)?(1.055*Math.pow(g,1/2.4))-0.055:12.92*g;
+var B=(b>0.0031308)?(1.055*Math.pow(b,1/2.4))-0.055:12.92*b;
+}else{
+var R=Math.pow(r,1/p.gamma),G=Math.pow(g,1/p.gamma),B=Math.pow(b,1/p.gamma);
+}
+return new dojox.color.Color({r:Math.floor(R*255),g:Math.floor(G*255),b:Math.floor(B*255)});
+}});
+dojo.extend(dojox.color.Color,{toXYZ:function(_17a){
+_17a=_17a||{};
+var p=dojox.color.Colorspace.primaries(_17a);
+var m=dojox.color.Colorspace.matrix("XYZ",p);
+var _r=this.r/255,_g=this.g/255,_b=this.b/255;
+if(p.profile=="sRGB"){
+var r=(_r>0.04045)?Math.pow(((_r+0.055)/1.055),2.4):_r/12.92;
+var g=(_g>0.04045)?Math.pow(((_g+0.055)/1.055),2.4):_g/12.92;
+var b=(_b>0.04045)?Math.pow(((_b+0.055)/1.055),2.4):_b/12.92;
+}else{
+var r=Math.pow(_r,p.gamma),g=Math.pow(_g,p.gamma),b=Math.pow(_b,p.gamma);
+}
+var xyz=dojox.math.matrix([[r,g,b]],m);
+return {X:xyz[0][0],Y:xyz[0][1],Z:xyz[0][2]};
+}});
+}
diff --git a/dojox/color/Palette.js b/dojox/color/Palette.js
new file mode 100644
index 0000000..76c739e
--- /dev/null
+++ b/dojox/color/Palette.js
@@ -0,0 +1,175 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.color.Palette"]){
+dojo._hasResource["dojox.color.Palette"]=true;
+dojo.provide("dojox.color.Palette");
+dojo.require("dojox.color");
+(function(){
+var _1=dojox.color;
+_1.Palette=function(_2){
+this.colors=[];
+if(_2 instanceof dojox.color.Palette){
+this.colors=_2.colors.slice(0);
+}else{
+if(_2 instanceof dojox.color.Color){
+this.colors=[null,null,_2,null,null];
+}else{
+if(dojo.isArray(_2)){
+this.colors=dojo.map(_2.slice(0),function(_3){
+if(dojo.isString(_3)){
+return new dojox.color.Color(_3);
+}
+return _3;
+});
+}else{
+if(dojo.isString(_2)){
+this.colors=[null,null,new dojox.color.Color(_2),null,null];
+}
+}
+}
+}
+};
+function _4(p,_6,_7){
+var _8=new dojox.color.Palette();
+_8.colors=[];
+dojo.forEach(p.colors,function(_9){
+var r=(_6=="dr")?_9.r+_7:_9.r,g=(_6=="dg")?_9.g+_7:_9.g,b=(_6=="db")?_9.b+_7:_9.b,a=(_6=="da")?_9.a+_7:_9.a;
+_8.colors.push(new dojox.color.Color({r:Math.min(255,Math.max(0,r)),g:Math.min(255,Math.max(0,g)),b:Math.min(255,Math.max(0,b)),a:Math.min(1,Math.max(0,a))}));
+});
+
+return _8;
+};
+function _e(p,_10,val){
+var ret=new dojox.color.Palette();
+ret.colors=[];
+dojo.forEach(p.colors,function(_13){
+var o=_13.toCmy(),c=(_10=="dc")?o.c+val:o.c,m=(_10=="dm")?o.m+val:o.m,y=(_10=="dy")?o.y+val:o.y;
+ret.colors.push(dojox.color.fromCmy(Math.min(100,Math.max(0,c)),Math.min(100,Math.max(0,m)),Math.min(100,Math.max(0,y))));
+});
+return ret;
+};
+function _18(p,_1a,val){
+var ret=new dojox.color.Palette();
+ret.colors=[];
+dojo.forEach(p.colors,function(_1d){
+var o=_1d.toCmyk(),c=(_1a=="dc")?o.c+val:o.c,m=(_1a=="dm")?o.m+val:o.m,y=(_1a=="dy")?o.y+val:o.y,k=(_1a=="dk")?o.b+val:o.b;
+ret.colors.push(dojox.color.fromCmyk(Math.min(100,Math.max(0,c)),Math.min(100,Math.max(0,m)),Math.min(100,Math.max(0,y)),Math.min(100,Math.max(0,k))));
+});
+return ret;
+};
+function _23(p,_25,val){
+var ret=new dojox.color.Palette();
+ret.colors=[];
+dojo.forEach(p.colors,function(_28){
+var o=_28.toHsl(),h=(_25=="dh")?o.h+val:o.h,s=(_25=="ds")?o.s+val:o.s,l=(_25=="dl")?o.l+val:o.l;
+ret.colors.push(dojox.color.fromHsl(h%360,Math.min(100,Math.max(0,s)),Math.min(100,Math.max(0,l))));
+});
+return ret;
+};
+function _2d(p,_2f,val){
+var ret=new dojox.color.Palette();
+ret.colors=[];
+dojo.forEach(p.colors,function(_32){
+var o=_32.toHsv(),h=(_2f=="dh")?o.h+val:o.h,s=(_2f=="ds")?o.s+val:o.s,v=(_2f=="dv")?o.v+val:o.v;
+ret.colors.push(dojox.color.fromHsv(h%360,Math.min(100,Math.max(0,s)),Math.min(100,Math.max(0,v))));
+});
+return ret;
+};
+function _37(val,low,_3a){
+return _3a-((_3a-val)*((_3a-low)/_3a));
+};
+dojo.extend(_1.Palette,{transform:function(_3b){
+var fn=_4;
+if(_3b.use){
+var use=_3b.use.toLowerCase();
+if(use.indexOf("hs")==0){
+if(use.charAt(2)=="l"){
+fn=_23;
+}else{
+fn=_2d;
+}
+}else{
+if(use.indexOf("cmy")==0){
+if(use.charAt(3)=="k"){
+fn=_18;
+}else{
+fn=_e;
+}
+}
+}
+}else{
+if("dc" in _3b||"dm" in _3b||"dy" in _3b){
+if("dk" in _3b){
+fn=_18;
+}else{
+fn=_e;
+}
+}else{
+if("dh" in _3b||"ds" in _3b){
+if("dv" in _3b){
+fn=_2d;
+}else{
+fn=_23;
+}
+}
+}
+}
+var _3e=this;
+for(var p in _3b){
+if(p=="use"){
+continue;
+}
+_3e=fn(_3e,p,_3b[p]);
+}
+return _3e;
+},clone:function(){
+return new _1.Palette(this);
+}});
+dojo.mixin(_1.Palette,{generators:{analogous:function(_40){
+var _41=_40.high||60,low=_40.low||18,_43=dojo.isString(_40.base)?new dojox.color.Color(_40.base):_40.base,hsv=_43.toHsv();
+var h=[(hsv.h+low+360)%360,(hsv.h+Math.round(low/2)+360)%360,hsv.h,(hsv.h-Math.round(_41/2)+360)%360,(hsv.h-_41+360)%360];
+var s1=Math.max(10,(hsv.s<=95)?hsv.s+5:(100-(hsv.s-95))),s2=(hsv.s>1)?hsv.s-1:21-hsv.s,v1=(hsv.v>=92)?hsv.v-9:Math.max(hsv.v+9,20),v2=(hsv.v<=90)?Math.max(hsv.v+5,20):(95+Math.ceil((hsv.v-90)/2)),s=[s1,s2,hsv.s,s1,s1],v=[v1,v2,hsv.v,v1,v2];
+return new _1.Palette(dojo.map(h,function(hue,i){
+return dojox.color.fromHsv(hue,s[i],v[i]);
+}));
+},monochromatic:function(_4e){
+var _4f=dojo.isString(_4e.base)?new dojox.color.Color(_4e.base):_4e.base,hsv=_4f.toHsv();
+var s1=(hsv.s-30>9)?hsv.s-30:hsv.s+30,s2=hsv.s,v1=_37(hsv.v,20,100),v2=(hsv.v-20>20)?hsv.v-20:hsv.v+60,v3=(hsv.v-50>20)?hsv.v-50:hsv.v+30;
+return new _1.Palette([dojox.color.fromHsv(hsv.h,s1,v1),dojox.color.fromHsv(hsv.h,s2,v3),_4f,dojox.color.fromHsv(hsv.h,s1,v3),dojox.color.fromHsv(hsv.h,s2,v2)]);
+},triadic:function(_56){
+var _57=dojo.isString(_56.base)?new dojox.color.Color(_56.base):_56.base,hsv=_57.toHsv();
+var h1=(hsv.h+57+360)%360,h2=(hsv.h-157+360)%360,s1=(hsv.s>20)?hsv.s-10:hsv.s+10,s2=(hsv.s>90)?hsv.s-10:hsv.s+10,s3=(hsv.s>95)?hsv.s-5:hsv.s+5,v1=(hsv.v-20>20)?hsv.v-20:hsv.v+20,v2=(hsv.v-30>20)?hsv.v-30:hsv.v+30,v3=(hsv.v-30>70)?hsv.v-30:hsv.v+30;
+return new _1.Palette([dojox.color.fromHsv(h1,s1,hsv.v),dojox.color.fromHsv(hsv.h,s2,v2),_57,dojox.color.fromHsv(h2,s2,v1),dojox.color.fromHsv(h2,s3,v3)]);
+},complementary:function(_61){
+var _62=dojo.isString(_61.base)?new dojox.color.Color(_61.base):_61.base,hsv=_62.toHsv();
+var h1=((hsv.h*2)+137<360)?(hsv.h*2)+137:Math.floor(hsv.h/2)-137,s1=Math.max(hsv.s-10,0),s2=_37(hsv.s,10,100),s3=Math.min(100,hsv.s+20),v1=Math.min(100,hsv.v+30),v2=(hsv.v>20)?hsv.v-30:hsv.v+30;
+return new _1.Palette([dojox.color.fromHsv(hsv.h,s1,v1),dojox.color.fromHsv(hsv.h,s2,v2),_62,dojox.color.fromHsv(h1,s3,v2),dojox.color.fromHsv(h1,hsv.s,hsv.v)]);
+},splitComplementary:function(_6a){
+var _6b=dojo.isString(_6a.base)?new dojox.color.Color(_6a.base):_6a.base,_6c=_6a.da||30,hsv=_6b.toHsv();
+var _6e=((hsv.h*2)+137<360)?(hsv.h*2)+137:Math.floor(hsv.h/2)-137,h1=(_6e-_6c+360)%360,h2=(_6e+_6c)%360,s1=Math.max(hsv.s-10,0),s2=_37(hsv.s,10,100),s3=Math.min(100,hsv.s+20),v1=Math.min(100,hsv.v+30),v2=(hsv.v>20)?hsv.v-30:hsv.v+30;
+return new _1.Palette([dojox.color.fromHsv(h1,s1,v1),dojox.color.fromHsv(h1,s2,v2),_6b,dojox.color.fromHsv(h2,s3,v2),dojox.color.fromHsv(h2,hsv.s,hsv.v)]);
+},compound:function(_76){
+var _77=dojo.isString(_76.base)?new dojox.color.Color(_76.base):_76.base,hsv=_77.toHsv();
+var h1=((hsv.h*2)+18<360)?(hsv.h*2)+18:Math.floor(hsv.h/2)-18,h2=((hsv.h*2)+120<360)?(hsv.h*2)+120:Math.floor(hsv.h/2)-120,h3=((hsv.h*2)+99<360)?(hsv.h*2)+99:Math.floor(hsv.h/2)-99,s1=(hsv.s-40>10)?hsv.s-40:hsv.s+40,s2=(hsv.s-10>80)?hsv.s-10:hsv.s+10,s3=(hsv.s-25>10)?hsv.s-25:hsv.s+25,v1=(hsv.v-40>10)?hsv.v-40:hsv.v+40,v2=(hsv.v-20>80)?hsv.v-20:hsv.v+20,v3=Math.max(hsv.v,20);
+return new _1.Palette([dojox.color.fromHsv(h1,s1,v1),dojox.color.fromHsv(h1,s2,v2),_77,dojox.color.fromHsv(h2,s3,v3),dojox.color.fromHsv(h3,s2,v2)]);
+},shades:function(_82){
+var _83=dojo.isString(_82.base)?new dojox.color.Color(_82.base):_82.base,hsv=_83.toHsv();
+var s=(hsv.s==100&&hsv.v==0)?0:hsv.s,v1=(hsv.v-50>20)?hsv.v-50:hsv.v+30,v2=(hsv.v-25>=20)?hsv.v-25:hsv.v+55,v3=(hsv.v-75>=20)?hsv.v-75:hsv.v+5,v4=Math.max(hsv.v-10,20);
+return new _1.Palette([new dojox.color.fromHsv(hsv.h,s,v1),new dojox.color.fromHsv(hsv.h,s,v2),_83,new dojox.color.fromHsv(hsv.h,s,v3),new dojox.color.fromHsv(hsv.h,s,v4)]);
+}},generate:function(_8a,_8b){
+if(dojo.isFunction(_8b)){
+return _8b({base:_8a});
+}else{
+if(_1.Palette.generators[_8b]){
+return _1.Palette.generators[_8b]({base:_8a});
+}
+}
+throw new Error("dojox.color.Palette.generate: the specified generator ('"+_8b+"') does not exist.");
+}});
+})();
+}
diff --git a/dojox/color/README b/dojox/color/README
new file mode 100644
index 0000000..a65e11a
--- /dev/null
+++ b/dojox/color/README
@@ -0,0 +1,41 @@
+-------------------------------------------------------------------------------
+DojoX Color
+-------------------------------------------------------------------------------
+Version 0.9
+Release date: 10/20/2007
+-------------------------------------------------------------------------------
+Project state:
+dojox.color._base: 			production
+dojox.color.Colorspace:		experimental
+dojox.color.Generator:		beta
+-------------------------------------------------------------------------------
+Credits
+	Cal Henderson
+	Tom Trenka (ttrenka AT gmail.com)
+-------------------------------------------------------------------------------
+Project description
+
+Both a port of the older dojo.gfx.color work (Cal Henderson) as well as some
+new additions (Generator, Tom Trenka).  Everything is applied to an alias of
+dojo.Color or dojo.color, so that you can just use dojox.color.Color instead
+with extended methods.
+-------------------------------------------------------------------------------
+Dependencies:
+
+Depends on the Dojo Core, v1.0
+-------------------------------------------------------------------------------
+Documentation
+
+See the API documentation.
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/color.js
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/color/*
+
+Install into the following directory structure:
+/dojox/color/
+
+...which should be at the same level as your Dojo checkout.
+-------------------------------------------------------------------------------
diff --git a/dojox/color/_base.js b/dojox/color/_base.js
new file mode 100644
index 0000000..0078645
--- /dev/null
+++ b/dojox/color/_base.js
@@ -0,0 +1,180 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.color._base"]){
+dojo._hasResource["dojox.color._base"]=true;
+dojo.provide("dojox.color._base");
+dojo.require("dojo.colors");
+dojox.color.Color=dojo.Color;
+dojox.color.blend=dojo.blendColors;
+dojox.color.fromRgb=dojo.colorFromRgb;
+dojox.color.fromHex=dojo.colorFromHex;
+dojox.color.fromArray=dojo.colorFromArray;
+dojox.color.fromString=dojo.colorFromString;
+dojox.color.greyscale=dojo.colors.makeGrey;
+dojo.mixin(dojox.color,{fromCmy:function(_1,_2,_3){
+if(dojo.isArray(_1)){
+_2=_1[1],_3=_1[2],_1=_1[0];
+}else{
+if(dojo.isObject(_1)){
+_2=_1.m,_3=_1.y,_1=_1.c;
+}
+}
+_1/=100,_2/=100,_3/=100;
+var r=1-_1,g=1-_2,b=1-_3;
+return new dojox.color.Color({r:Math.round(r*255),g:Math.round(g*255),b:Math.round(b*255)});
+},fromCmyk:function(_7,_8,_9,_a){
+if(dojo.isArray(_7)){
+_8=_7[1],_9=_7[2],_a=_7[3],_7=_7[0];
+}else{
+if(dojo.isObject(_7)){
+_8=_7.m,_9=_7.y,_a=_7.b,_7=_7.c;
+}
+}
+_7/=100,_8/=100,_9/=100,_a/=100;
+var r,g,b;
+r=1-Math.min(1,_7*(1-_a)+_a);
+g=1-Math.min(1,_8*(1-_a)+_a);
+b=1-Math.min(1,_9*(1-_a)+_a);
+return new dojox.color.Color({r:Math.round(r*255),g:Math.round(g*255),b:Math.round(b*255)});
+},fromHsl:function(_e,_f,_10){
+if(dojo.isArray(_e)){
+_f=_e[1],_10=_e[2],_e=_e[0];
+}else{
+if(dojo.isObject(_e)){
+_f=_e.s,_10=_e.l,_e=_e.h;
+}
+}
+_f/=100;
+_10/=100;
+while(_e<0){
+_e+=360;
+}
+while(_e>=360){
+_e-=360;
+}
+var r,g,b;
+if(_e<120){
+r=(120-_e)/60,g=_e/60,b=0;
+}else{
+if(_e<240){
+r=0,g=(240-_e)/60,b=(_e-120)/60;
+}else{
+r=(_e-240)/60,g=0,b=(360-_e)/60;
+}
+}
+r=2*_f*Math.min(r,1)+(1-_f);
+g=2*_f*Math.min(g,1)+(1-_f);
+b=2*_f*Math.min(b,1)+(1-_f);
+if(_10<0.5){
+r*=_10,g*=_10,b*=_10;
+}else{
+r=(1-_10)*r+2*_10-1;
+g=(1-_10)*g+2*_10-1;
+b=(1-_10)*b+2*_10-1;
+}
+return new dojox.color.Color({r:Math.round(r*255),g:Math.round(g*255),b:Math.round(b*255)});
+},fromHsv:function(hue,_15,_16){
+if(dojo.isArray(hue)){
+_15=hue[1],_16=hue[2],hue=hue[0];
+}else{
+if(dojo.isObject(hue)){
+_15=hue.s,_16=hue.v,hue=hue.h;
+}
+}
+if(hue==360){
+hue=0;
+}
+_15/=100;
+_16/=100;
+var r,g,b;
+if(_15==0){
+r=_16,b=_16,g=_16;
+}else{
+var _1a=hue/60,i=Math.floor(_1a),f=_1a-i;
+var p=_16*(1-_15);
+var q=_16*(1-(_15*f));
+var t=_16*(1-(_15*(1-f)));
+switch(i){
+case 0:
+r=_16,g=t,b=p;
+break;
+case 1:
+r=q,g=_16,b=p;
+break;
+case 2:
+r=p,g=_16,b=t;
+break;
+case 3:
+r=p,g=q,b=_16;
+break;
+case 4:
+r=t,g=p,b=_16;
+break;
+case 5:
+r=_16,g=p,b=q;
+break;
+}
+}
+return new dojox.color.Color({r:Math.round(r*255),g:Math.round(g*255),b:Math.round(b*255)});
+}});
+dojo.extend(dojox.color.Color,{toCmy:function(){
+var _20=1-(this.r/255),_21=1-(this.g/255),_22=1-(this.b/255);
+return {c:Math.round(_20*100),m:Math.round(_21*100),y:Math.round(_22*100)};
+},toCmyk:function(){
+var _23,_24,_25,_26;
+var r=this.r/255,g=this.g/255,b=this.b/255;
+_26=Math.min(1-r,1-g,1-b);
+_23=(1-r-_26)/(1-_26);
+_24=(1-g-_26)/(1-_26);
+_25=(1-b-_26)/(1-_26);
+return {c:Math.round(_23*100),m:Math.round(_24*100),y:Math.round(_25*100),b:Math.round(_26*100)};
+},toHsl:function(){
+var r=this.r/255,g=this.g/255,b=this.b/255;
+var min=Math.min(r,b,g),max=Math.max(r,g,b);
+var _2f=max-min;
+var h=0,s=0,l=(min+max)/2;
+if(l>0&&l<1){
+s=_2f/((l<0.5)?(2*l):(2-2*l));
+}
+if(_2f>0){
+if(max==r&&max!=g){
+h+=(g-b)/_2f;
+}
+if(max==g&&max!=b){
+h+=(2+(b-r)/_2f);
+}
+if(max==b&&max!=r){
+h+=(4+(r-g)/_2f);
+}
+h*=60;
+}
+return {h:h,s:Math.round(s*100),l:Math.round(l*100)};
+},toHsv:function(){
+var r=this.r/255,g=this.g/255,b=this.b/255;
+var min=Math.min(r,b,g),max=Math.max(r,g,b);
+var _38=max-min;
+var h=null,s=(max==0)?0:(_38/max);
+if(s==0){
+h=0;
+}else{
+if(r==max){
+h=60*(g-b)/_38;
+}else{
+if(g==max){
+h=120+60*(b-r)/_38;
+}else{
+h=240+60*(r-g)/_38;
+}
+}
+if(h<0){
+h+=360;
+}
+}
+return {h:h,s:Math.round(s*100),v:Math.round(max*100)};
+}});
+}
diff --git a/dojox/cometd.js b/dojox/cometd.js
new file mode 100644
index 0000000..6744f97
--- /dev/null
+++ b/dojox/cometd.js
@@ -0,0 +1,14 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.cometd"]){
+dojo._hasResource["dojox.cometd"]=true;
+dojo.provide("dojox.cometd");
+dojo.require("dojox.cometd._base");
+dojo.require("dojox.cometd.longPollTransport");
+dojo.require("dojox.cometd.callbackPollTransport");
+}
diff --git a/dojox/cometd/HttpChannels.js b/dojox/cometd/HttpChannels.js
new file mode 100644
index 0000000..f690c1c
--- /dev/null
+++ b/dojox/cometd/HttpChannels.js
@@ -0,0 +1,14 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.cometd.HttpChannels"]){
+dojo._hasResource["dojox.cometd.HttpChannels"]=true;
+dojo.provide("dojox.cometd.HttpChannels");
+dojo.require("dojox.io.httpParse");
+dojo.require("dojox.cometd.RestChannels");
+dojox.cometd.HttpChannels=dojox.cometd.RestChannels;
+}
diff --git a/dojox/cometd/README b/dojox/cometd/README
new file mode 100644
index 0000000..05a42a2
--- /dev/null
+++ b/dojox/cometd/README
@@ -0,0 +1,29 @@
+-------------------------------------------------------------------------------
+Cometd (client)
+-------------------------------------------------------------------------------
+Version 0.4
+Release date: May 29, 2007
+-------------------------------------------------------------------------------
+Project state: beta 
+-------------------------------------------------------------------------------
+Project authors
+	Alex Russell (alex at dojotoolkit.org)
+	Greg Wilkins
+-------------------------------------------------------------------------------
+Project description
+
+Low-latency data transfer from servers to clients. dojox.cometd implements a
+Bayeux protocol client for use with most Bayeux servers. See cometd.com for
+details on Cometd or on the Bayeux protocol.
+-------------------------------------------------------------------------------
+Dependencies:
+
+Needs a cooperating Bayeux server
+-------------------------------------------------------------------------------
+Documentation
+
+See http://cometd.com
+-------------------------------------------------------------------------------
+Installation instructions
+
+Use this library with (preferably through) an existing Cometd server.
diff --git a/dojox/cometd/RestChannels.js b/dojox/cometd/RestChannels.js
new file mode 100644
index 0000000..cfcdcf7
--- /dev/null
+++ b/dojox/cometd/RestChannels.js
@@ -0,0 +1,338 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.cometd.RestChannels"]){
+dojo._hasResource["dojox.cometd.RestChannels"]=true;
+dojo.provide("dojox.cometd.RestChannels");
+dojo.require("dojox.rpc.Client");
+dojo.requireIf(dojox.data&&!!dojox.data.JsonRestStore,"dojox.data.restListener");
+(function(){
+dojo.declare("dojox.cometd.RestChannels",null,{constructor:function(_1){
+dojo.mixin(this,_1);
+if(dojox.rpc.Rest&&this.autoSubscribeRoot){
+var _2=dojox.rpc.Rest._get;
+var _3=this;
+dojox.rpc.Rest._get=function(_4,id){
+var _6=dojo.xhrGet;
+dojo.xhrGet=function(r){
+var _8=_3.autoSubscribeRoot;
+return (_8&&r.url.substring(0,_8.length)==_8)?_3.get(r.url,r):_6(r);
+};
+var _9=_2.apply(this,arguments);
+dojo.xhrGet=_6;
+return _9;
+};
+}
+if(dojox.data&&dojox.data.restListener){
+this.receive=dojox.data.restListener;
+}
+},absoluteUrl:function(_a,_b){
+return new dojo._Url(_a,_b)+"";
+},acceptType:"application/rest+json,application/http;q=0.9,*/*;q=0.7",subscriptions:{},subCallbacks:{},autoReconnectTime:3000,reloadDataOnReconnect:true,sendAsJson:false,url:"/channels",autoSubscribeRoot:"/",open:function(){
+this.started=true;
+if(!this.connected){
+this.connectionId=dojox.rpc.Client.clientId;
+var _c=this.createdClientId?"Client-Id":"Create-Client-Id";
+this.createdClientId=true;
+var _d={Accept:this.acceptType};
+_d[_c]=this.connectionId;
+var _e=dojo.xhrPost({headers:_d,url:this.url,noStatus:true});
+var _f=this;
+this.lastIndex=0;
+var _10,_11=function(_12){
+if(typeof dojo=="undefined"){
+return null;
+}
+if(xhr&&xhr.status>400){
+return _10(true);
+}
+if(typeof _12=="string"){
+_12=_12.substring(_f.lastIndex);
+}
+var _14=xhr&&(xhr.contentType||xhr.getResponseHeader("Content-Type"))||(typeof _12!="string"&&"already json");
+var _15=_f.onprogress(xhr,_12,_14);
+if(_15){
+if(_10()){
+return new Error(_15);
+}
+}
+if(!xhr||xhr.readyState==4){
+xhr=null;
+if(_f.connected){
+_f.connected=false;
+_f.open();
+}
+}
+return _12;
+};
+_10=function(_16){
+if(xhr&&xhr.status==409){
+
+_f.disconnected();
+return null;
+}
+_f.createdClientId=false;
+_f.disconnected();
+return _16;
+};
+_e.addCallbacks(_11,_10);
+var xhr=_e.ioArgs.xhr;
+if(xhr){
+xhr.onreadystatechange=function(){
+var _17;
+try{
+if(xhr.readyState==3){
+_f.readyState=3;
+_17=xhr.responseText;
+}
+}
+catch(e){
+}
+if(typeof _17=="string"){
+_11(_17);
+}
+};
+}
+if(window.attachEvent){
+window.attachEvent("onunload",function(){
+_f.connected=false;
+if(xhr){
+xhr.abort();
+}
+});
+}
+this.connected=true;
+}
+},_send:function(_18,_19,_1a){
+if(this.sendAsJson){
+_19.postBody=dojo.toJson({target:_19.url,method:_18,content:_1a,params:_19.content,subscribe:_19.headers["Subscribe"]});
+_19.url=this.url;
+_18="POST";
+}else{
+_19.postData=dojo.toJson(_1a);
+}
+return dojo.xhr(_18,_19,_19.postBody);
+},subscribe:function(_1b,_1c){
+_1c=_1c||{};
+_1c.url=this.absoluteUrl(this.url,_1b);
+if(_1c.headers){
+delete _1c.headers.Range;
+}
+var _1d=this.subscriptions[_1b];
+var _1e=_1c.method||"HEAD";
+var _1f=_1c.since;
+var _20=_1c.callback;
+var _21=_1c.headers||(_1c.headers={});
+this.subscriptions[_1b]=_1f||_1d||0;
+var _22=this.subCallbacks[_1b];
+if(_20){
+this.subCallbacks[_1b]=_22?function(m){
+_22(m);
+_20(m);
+}:_20;
+}
+if(!this.connected){
+this.open();
+}
+if(_1d===undefined||_1d!=_1f){
+_21["Cache-Control"]="max-age=0";
+_1f=typeof _1f=="number"?new Date(_1f).toUTCString():_1f;
+if(_1f){
+_21["Subscribe-Since"]=_1f;
+}
+_21["Subscribe"]=_1c.unsubscribe?"none":"*";
+var dfd=this._send(_1e,_1c);
+var _25=this;
+dfd.addBoth(function(_26){
+var xhr=dfd.ioArgs.xhr;
+if(!(_26 instanceof Error)){
+if(_1c.confirmation){
+_1c.confirmation();
+}
+}
+if(xhr&&xhr.getResponseHeader("Subscribed")=="OK"){
+var _28=xhr.getResponseHeader("Last-Modified");
+if(xhr.responseText){
+_25.subscriptions[_1b]=_28||new Date().toUTCString();
+}else{
+return null;
+}
+}else{
+if(xhr&&!(_26 instanceof Error)){
+delete _25.subscriptions[_1b];
+}
+}
+if(!(_26 instanceof Error)){
+var _29={responseText:xhr&&xhr.responseText,channel:_1b,getResponseHeader:function(_2a){
+return xhr.getResponseHeader(_2a);
+},getAllResponseHeaders:function(){
+return xhr.getAllResponseHeaders();
+},result:_26};
+if(_25.subCallbacks[_1b]){
+_25.subCallbacks[_1b](_29);
+}
+}else{
+if(_25.subCallbacks[_1b]){
+_25.subCallbacks[_1b](xhr);
+}
+}
+return _26;
+});
+return dfd;
+}
+return null;
+},publish:function(_2b,_2c){
+return this._send("POST",{url:_2b,contentType:"application/json"},_2c);
+},_processMessage:function(_2d){
+_2d.event=_2d.event||_2d.getResponseHeader("Event");
+if(_2d.event=="connection-conflict"){
+return "conflict";
+}
+try{
+_2d.result=_2d.result||dojo.fromJson(_2d.responseText);
+}
+catch(e){
+}
+var _2e=this;
+var loc=_2d.channel=new dojo._Url(this.url,_2d.source||_2d.getResponseHeader("Content-Location"))+"";
+if(loc in this.subscriptions&&_2d.getResponseHeader){
+this.subscriptions[loc]=_2d.getResponseHeader("Last-Modified");
+}
+if(this.subCallbacks[loc]){
+setTimeout(function(){
+_2e.subCallbacks[loc](_2d);
+},0);
+}
+this.receive(_2d);
+return null;
+},onprogress:function(xhr,_31,_32){
+if(!_32||_32.match(/application\/rest\+json/)){
+var _33=_31.length;
+_31=_31.replace(/^\s*[,\[]?/,"[").replace(/[,\]]?\s*$/,"]");
+try{
+var _34=dojo.fromJson(_31);
+this.lastIndex+=_33;
+}
+catch(e){
+}
+}else{
+if(dojox.io&&dojox.io.httpParse&&_32.match(/application\/http/)){
+var _35="";
+if(xhr&&xhr.getAllResponseHeaders){
+_35=xhr.getAllResponseHeaders();
+}
+_34=dojox.io.httpParse(_31,_35,xhr.readyState!=4);
+}else{
+if(typeof _31=="object"){
+_34=_31;
+}
+}
+}
+if(_34){
+for(var i=0;i<_34.length;i++){
+if(this._processMessage(_34[i])){
+return "conflict";
+}
+}
+return null;
+}
+if(!xhr){
+return "error";
+}
+if(xhr.readyState!=4){
+return null;
+}
+if(xhr.__proto__){
+xhr={channel:"channel",__proto__:xhr};
+}
+return this._processMessage(xhr);
+},get:function(_37,_38){
+(_38=_38||{}).method="GET";
+return this.subscribe(_37,_38);
+},receive:function(_39){
+},disconnected:function(){
+var _3a=this;
+if(this.connected){
+this.connected=false;
+if(this.started){
+setTimeout(function(){
+var _3b=_3a.subscriptions;
+_3a.subscriptions={};
+for(var i in _3b){
+if(_3a.reloadDataOnReconnect&&dojox.rpc.JsonRest){
+delete dojox.rpc.Rest._index[i];
+dojox.rpc.JsonRest.fetch(i);
+}else{
+_3a.subscribe(i,{since:_3b[i]});
+}
+}
+_3a.open();
+},this.autoReconnectTime);
+}
+}
+},unsubscribe:function(_3d,_3e){
+_3e=_3e||{};
+_3e.unsubscribe=true;
+this.subscribe(_3d,_3e);
+},disconnect:function(){
+this.started=false;
+this.xhr.abort();
+}});
+var _3f=dojox.cometd.RestChannels.defaultInstance=new dojox.cometd.RestChannels();
+if(dojox.cometd.connectionTypes){
+_3f.startup=function(_40){
+_3f.open();
+this._cometd._deliver({channel:"/meta/connect",successful:true});
+};
+_3f.check=function(_41,_42,_43){
+for(var i=0;i<_41.length;i++){
+if(_41[i]=="rest-channels"){
+return !_43;
+}
+}
+return false;
+};
+_3f.deliver=function(_45){
+};
+dojo.connect(this,"receive",null,function(_46){
+_46.data=_46.result;
+this._cometd._deliver(_46);
+});
+_3f.sendMessages=function(_47){
+for(var i=0;i<_47.length;i++){
+var _49=_47[i];
+var _4a=_49.channel;
+var _4b=this._cometd;
+var _4c={confirmation:function(){
+_4b._deliver({channel:_4a,successful:true});
+}};
+if(_4a=="/meta/subscribe"){
+this.subscribe(_49.subscription,_4c);
+}else{
+if(_4a=="/meta/unsubscribe"){
+this.unsubscribe(_49.subscription,_4c);
+}else{
+if(_4a=="/meta/connect"){
+_4c.confirmation();
+}else{
+if(_4a=="/meta/disconnect"){
+_3f.disconnect();
+_4c.confirmation();
+}else{
+if(_4a.substring(0,6)!="/meta/"){
+this.publish(_4a,_49.data);
+}
+}
+}
+}
+}
+}
+};
+dojox.cometd.connectionTypes.register("rest-channels",_3f.check,_3f,false,true);
+}
+})();
+}
diff --git a/dojox/cometd/_base.js b/dojox/cometd/_base.js
new file mode 100644
index 0000000..4843e43
--- /dev/null
+++ b/dojox/cometd/_base.js
@@ -0,0 +1,404 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.cometd._base"]){
+dojo._hasResource["dojox.cometd._base"]=true;
+dojo.provide("dojox.cometd._base");
+dojo.require("dojo.AdapterRegistry");
+dojox.cometd={Connection:function(_1){
+dojo.mixin(this,{prefix:_1,_status:"unconnected",_handshook:false,_initialized:false,_polling:false,expectedNetworkDelay:10000,connectTimeout:0,version:"1.0",minimumVersion:"0.9",clientId:null,messageId:0,batch:0,_isXD:false,handshakeReturn:null,currentTransport:null,url:null,lastMessage:null,_messageQ:[],handleAs:"json",_advice:{},_backoffInterval:0,_backoffIncrement:1000,_backoffMax:60000,_deferredSubscribes:{},_deferredUnsubscribes:{},_subscriptions:[],_extendInList:[],_extendOutList:[]});
+this.state=function(){
+return this._status;
+};
+this.init=function(_2,_3,_4){
+_3=_3||{};
+_3.version=this.version;
+_3.minimumVersion=this.minimumVersion;
+_3.channel="/meta/handshake";
+_3.id=""+this.messageId++;
+this.url=_2||dojo.config["cometdRoot"];
+if(!this.url){
+throw "no cometd root";
+return null;
+}
+var _5="^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$";
+var _6=(""+window.location).match(new RegExp(_5));
+if(_6[4]){
+var _7=_6[4].split(":");
+var _8=_7[0];
+var _9=_7[1]||"80";
+_6=this.url.match(new RegExp(_5));
+if(_6[4]){
+_7=_6[4].split(":");
+var _a=_7[0];
+var _b=_7[1]||"80";
+this._isXD=((_a!=_8)||(_b!=_9));
+}
+}
+if(!this._isXD){
+_3.supportedConnectionTypes=dojo.map(dojox.cometd.connectionTypes.pairs,"return item[0]");
+}
+_3=this._extendOut(_3);
+var _c={url:this.url,handleAs:this.handleAs,content:{"message":dojo.toJson([_3])},load:dojo.hitch(this,function(_d){
+this._backon();
+this._finishInit(_d);
+}),error:dojo.hitch(this,function(e){
+this._backoff();
+this._finishInit(e);
+}),timeout:this.expectedNetworkDelay};
+if(_4){
+dojo.mixin(_c,_4);
+}
+this._props=_3;
+for(var _f in this._subscriptions){
+for(var sub in this._subscriptions[_f]){
+if(this._subscriptions[_f][sub].topic){
+dojo.unsubscribe(this._subscriptions[_f][sub].topic);
+}
+}
+}
+this._messageQ=[];
+this._subscriptions=[];
+this._initialized=true;
+this._status="handshaking";
+this.batch=0;
+this.startBatch();
+var r;
+if(this._isXD){
+_c.callbackParamName="jsonp";
+r=dojo.io.script.get(_c);
+}else{
+r=dojo.xhrPost(_c);
+}
+return r;
+};
+this.publish=function(_12,_13,_14){
+var _15={data:_13,channel:_12};
+if(_14){
+dojo.mixin(_15,_14);
+}
+this._sendMessage(_15);
+};
+this.subscribe=function(_16,_17,_18,_19){
+_19=_19||{};
+if(_17){
+var _1a=_1+_16;
+var _1b=this._subscriptions[_1a];
+if(!_1b||_1b.length==0){
+_1b=[];
+_19.channel="/meta/subscribe";
+_19.subscription=_16;
+this._sendMessage(_19);
+var _ds=this._deferredSubscribes;
+if(_ds[_16]){
+_ds[_16].cancel();
+delete _ds[_16];
+}
+_ds[_16]=new dojo.Deferred();
+}
+for(var i in _1b){
+if(_1b[i].objOrFunc===_17&&(!_1b[i].funcName&&!_18||_1b[i].funcName==_18)){
+return null;
+}
+}
+var _1e=dojo.subscribe(_1a,_17,_18);
+_1b.push({topic:_1e,objOrFunc:_17,funcName:_18});
+this._subscriptions[_1a]=_1b;
+}
+var ret=this._deferredSubscribes[_16]||{};
+ret.args=dojo._toArray(arguments);
+return ret;
+};
+this.unsubscribe=function(_20,_21,_22,_23){
+if((arguments.length==1)&&(!dojo.isString(_20))&&(_20.args)){
+return this.unsubscribe.apply(this,_20.args);
+}
+var _24=_1+_20;
+var _25=this._subscriptions[_24];
+if(!_25||_25.length==0){
+return null;
+}
+var s=0;
+for(var i in _25){
+var sb=_25[i];
+if((!_21)||(sb.objOrFunc===_21&&(!sb.funcName&&!_22||sb.funcName==_22))){
+dojo.unsubscribe(_25[i].topic);
+delete _25[i];
+}else{
+s++;
+}
+}
+if(s==0){
+_23=_23||{};
+_23.channel="/meta/unsubscribe";
+_23.subscription=_20;
+delete this._subscriptions[_24];
+this._sendMessage(_23);
+this._deferredUnsubscribes[_20]=new dojo.Deferred();
+if(this._deferredSubscribes[_20]){
+this._deferredSubscribes[_20].cancel();
+delete this._deferredSubscribes[_20];
+}
+}
+return this._deferredUnsubscribes[_20];
+};
+this.disconnect=function(){
+for(var _29 in this._subscriptions){
+for(var sub in this._subscriptions[_29]){
+if(this._subscriptions[_29][sub].topic){
+dojo.unsubscribe(this._subscriptions[_29][sub].topic);
+}
+}
+}
+this._subscriptions=[];
+this._messageQ=[];
+if(this._initialized&&this.currentTransport){
+this._initialized=false;
+this.currentTransport.disconnect();
+}
+if(!this._polling){
+this._publishMeta("connect",false);
+}
+this._initialized=false;
+this._handshook=false;
+this._status="disconnected";
+this._publishMeta("disconnect",true);
+};
+this.subscribed=function(_2b,_2c){
+};
+this.unsubscribed=function(_2d,_2e){
+};
+this.tunnelInit=function(_2f,_30){
+};
+this.tunnelCollapse=function(){
+};
+this._backoff=function(){
+if(!this._advice){
+this._advice={reconnect:"retry",interval:0};
+}else{
+if(!this._advice.interval){
+this._advice.interval=0;
+}
+}
+if(this._backoffInterval<this._backoffMax){
+this._backoffInterval+=this._backoffIncrement;
+}
+};
+this._backon=function(){
+this._backoffInterval=0;
+};
+this._interval=function(){
+var i=this._backoffInterval+(this._advice?(this._advice.interval?this._advice.interval:0):0);
+if(i>0){
+
+}
+return i;
+};
+this._publishMeta=function(_32,_33,_34){
+try{
+var _35={cometd:this,action:_32,successful:_33,state:this.state()};
+if(_34){
+dojo.mixin(_35,_34);
+}
+dojo.publish(this.prefix+"/meta",[_35]);
+}
+catch(e){
+
+}
+};
+this._finishInit=function(_36){
+if(this._status!="handshaking"){
+return;
+}
+var _37=this._handshook;
+var _38=false;
+var _39={};
+if(_36 instanceof Error){
+dojo.mixin(_39,{reestablish:false,failure:true,error:_36,advice:this._advice});
+}else{
+_36=_36[0];
+_36=this._extendIn(_36);
+this.handshakeReturn=_36;
+if(_36["advice"]){
+this._advice=_36.advice;
+}
+_38=_36.successful?_36.successful:false;
+if(_36.version<this.minimumVersion){
+if(console.log){
+
+}
+_38=false;
+this._advice.reconnect="none";
+}
+dojo.mixin(_39,{reestablish:_38&&_37,response:_36});
+}
+this._publishMeta("handshake",_38,_39);
+if(this._status!="handshaking"){
+return;
+}
+if(_38){
+this._status="connecting";
+this._handshook=true;
+this.currentTransport=dojox.cometd.connectionTypes.match(_36.supportedConnectionTypes,_36.version,this._isXD);
+var _3a=this.currentTransport;
+_3a._cometd=this;
+_3a.version=_36.version;
+this.clientId=_36.clientId;
+this.tunnelInit=_3a.tunnelInit&&dojo.hitch(_3a,"tunnelInit");
+this.tunnelCollapse=_3a.tunnelCollapse&&dojo.hitch(_3a,"tunnelCollapse");
+_3a.startup(_36);
+}else{
+if(!this._advice||this._advice["reconnect"]!="none"){
+setTimeout(dojo.hitch(this,"init",this.url,this._props),this._interval());
+}
+}
+};
+this._extendIn=function(_3b){
+dojo.forEach(dojox.cometd._extendInList,function(f){
+_3b=f(_3b)||_3b;
+});
+return _3b;
+};
+this._extendOut=function(_3d){
+dojo.forEach(dojox.cometd._extendOutList,function(f){
+_3d=f(_3d)||_3d;
+});
+return _3d;
+};
+this.deliver=function(_3f){
+dojo.forEach(_3f,this._deliver,this);
+return _3f;
+};
+this._deliver=function(_40){
+_40=this._extendIn(_40);
+if(!_40["channel"]){
+if(_40["success"]!==true){
+return;
+}
+}
+this.lastMessage=_40;
+if(_40.advice){
+this._advice=_40.advice;
+}
+var _41=null;
+if((_40["channel"])&&(_40.channel.length>5)&&(_40.channel.substr(0,5)=="/meta")){
+switch(_40.channel){
+case "/meta/connect":
+var _42={response:_40};
+if(_40.successful){
+if(this._status!="connected"){
+this._status="connected";
+this.endBatch();
+}
+}
+if(this._initialized){
+this._publishMeta("connect",_40.successful,_42);
+}
+break;
+case "/meta/subscribe":
+_41=this._deferredSubscribes[_40.subscription];
+try{
+if(!_40.successful){
+if(_41){
+_41.errback(new Error(_40.error));
+}
+this.currentTransport.cancelConnect();
+return;
+}
+if(_41){
+_41.callback(true);
+}
+this.subscribed(_40.subscription,_40);
+}
+catch(e){
+log.warn(e);
+}
+break;
+case "/meta/unsubscribe":
+_41=this._deferredUnsubscribes[_40.subscription];
+try{
+if(!_40.successful){
+if(_41){
+_41.errback(new Error(_40.error));
+}
+this.currentTransport.cancelConnect();
+return;
+}
+if(_41){
+_41.callback(true);
+}
+this.unsubscribed(_40.subscription,_40);
+}
+catch(e){
+log.warn(e);
+}
+break;
+default:
+if(_40.successful&&!_40.successful){
+this.currentTransport.cancelConnect();
+return;
+}
+}
+}
+this.currentTransport.deliver(_40);
+if(_40.data){
+try{
+var _43=[_40];
+var _44=_1+_40.channel;
+var _45=_40.channel.split("/");
+var _46=_1;
+for(var i=1;i<_45.length-1;i++){
+dojo.publish(_46+"/**",_43);
+_46+="/"+_45[i];
+}
+dojo.publish(_46+"/**",_43);
+dojo.publish(_46+"/*",_43);
+dojo.publish(_44,_43);
+}
+catch(e){
+
+}
+}
+};
+this._sendMessage=function(_48){
+if(this.currentTransport&&!this.batch){
+return this.currentTransport.sendMessages([_48]);
+}else{
+this._messageQ.push(_48);
+return null;
+}
+};
+this.startBatch=function(){
+this.batch++;
+};
+this.endBatch=function(){
+if(--this.batch<=0&&this.currentTransport&&this._status=="connected"){
+this.batch=0;
+var _49=this._messageQ;
+this._messageQ=[];
+if(_49.length>0){
+this.currentTransport.sendMessages(_49);
+}
+}
+};
+this._onUnload=function(){
+dojo.addOnUnload(dojox.cometd,"disconnect");
+};
+this._connectTimeout=function(){
+var _4a=0;
+if(this._advice&&this._advice.timeout&&this.expectedNetworkDelay>0){
+_4a=this._advice.timeout+this.expectedNetworkDelay;
+}
+if(this.connectTimeout>0&&this.connectTimeout<_4a){
+return this.connectTimeout;
+}
+return _4a;
+};
+},connectionTypes:new dojo.AdapterRegistry(true)};
+dojox.cometd.Connection.call(dojox.cometd,"/cometd");
+dojo.addOnUnload(dojox.cometd,"_onUnload");
+}
diff --git a/dojox/cometd/ack.js b/dojox/cometd/ack.js
new file mode 100644
index 0000000..461f9dd
--- /dev/null
+++ b/dojox/cometd/ack.js
@@ -0,0 +1,46 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.cometd.ack"]){
+dojo._hasResource["dojox.cometd.ack"]=true;
+dojo.provide("dojox.cometd.ack");
+dojo.require("dojox.cometd._base");
+dojox.cometd._ack=new function(){
+var _1=false;
+var _2=-1;
+this._in=function(_3){
+if(_3.channel=="/meta/handshake"){
+_1=_3.ext&&_3.ext.ack;
+}else{
+if(_1&&_3.channel=="/meta/connect"&&_3.ext&&_3.ext.ack&&_3.successful){
+var _4=parseInt(_3.ext.ack);
+_2=_4;
+}
+}
+return _3;
+};
+this._out=function(_5){
+if(_5.channel=="/meta/handshake"){
+if(!_5.ext){
+_5.ext={};
+}
+_5.ext.ack=dojox.cometd.ackEnabled;
+_2=-1;
+}
+if(_1&&_5.channel=="/meta/connect"){
+if(!_5.ext){
+_5.ext={};
+}
+_5.ext.ack=_2;
+}
+return _5;
+};
+};
+dojox.cometd._extendInList.push(dojo.hitch(dojox.cometd._ack,"_in"));
+dojox.cometd._extendOutList.push(dojo.hitch(dojox.cometd._ack,"_out"));
+dojox.cometd.ackEnabled=true;
+}
diff --git a/dojox/cometd/callbackPollTransport.js b/dojox/cometd/callbackPollTransport.js
new file mode 100644
index 0000000..d36e455
--- /dev/null
+++ b/dojox/cometd/callbackPollTransport.js
@@ -0,0 +1,74 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.cometd.callbackPollTransport"]){
+dojo._hasResource["dojox.cometd.callbackPollTransport"]=true;
+dojo.provide("dojox.cometd.callbackPollTransport");
+dojo.require("dojox.cometd._base");
+dojo.require("dojox.cometd.longPollTransport");
+dojo.require("dojo.io.script");
+dojox.cometd.callbackPollTransport=new function(){
+this._connectionType="callback-polling";
+this._cometd=null;
+this.check=function(_1,_2,_3){
+return (dojo.indexOf(_1,"callback-polling")>=0);
+};
+this.tunnelInit=function(){
+var _4={channel:"/meta/connect",clientId:this._cometd.clientId,connectionType:this._connectionType,id:""+this._cometd.messageId++};
+_4=this._cometd._extendOut(_4);
+this.openTunnelWith([_4]);
+};
+this.tunnelCollapse=dojox.cometd.longPollTransport.tunnelCollapse;
+this._connect=dojox.cometd.longPollTransport._connect;
+this.deliver=dojox.cometd.longPollTransport.deliver;
+this.openTunnelWith=function(_5,_6){
+this._cometd._polling=true;
+var _7={load:dojo.hitch(this,function(_8){
+this._cometd._polling=false;
+this._cometd.deliver(_8);
+this._cometd._backon();
+this.tunnelCollapse();
+}),error:dojo.hitch(this,function(_9){
+this._cometd._polling=false;
+this._cometd._publishMeta("connect",false);
+this._cometd._backoff();
+this.tunnelCollapse();
+}),url:(_6||this._cometd.url),content:{message:dojo.toJson(_5)},callbackParamName:"jsonp"};
+var _a=this._cometd._connectTimeout();
+if(_a>0){
+_7.timeout=_a;
+}
+dojo.io.script.get(_7);
+};
+this.sendMessages=function(_b){
+for(var i=0;i<_b.length;i++){
+_b[i].clientId=this._cometd.clientId;
+_b[i].id=""+this._cometd.messageId++;
+_b[i]=this._cometd._extendOut(_b[i]);
+}
+var _d={url:this._cometd.url||dojo.config["cometdRoot"],load:dojo.hitch(this._cometd,"deliver"),callbackParamName:"jsonp",content:{message:dojo.toJson(_b)},error:dojo.hitch(this,function(_e){
+this._cometd._publishMeta("publish",false,{messages:_b});
+}),timeout:this._cometd.expectedNetworkDelay};
+return dojo.io.script.get(_d);
+};
+this.startup=function(_f){
+if(this._cometd._connected){
+return;
+}
+this.tunnelInit();
+};
+this.disconnect=dojox.cometd.longPollTransport.disconnect;
+this.disconnect=function(){
+var _10={channel:"/meta/disconnect",clientId:this._cometd.clientId,id:""+this._cometd.messageId++};
+_10=this._cometd._extendOut(_10);
+dojo.io.script.get({url:this._cometd.url||dojo.config["cometdRoot"],callbackParamName:"jsonp",content:{message:dojo.toJson([_10])}});
+};
+this.cancelConnect=function(){
+};
+};
+dojox.cometd.connectionTypes.register("callback-polling",dojox.cometd.callbackPollTransport.check,dojox.cometd.callbackPollTransport);
+}
diff --git a/dojox/cometd/longPollTransport.js b/dojox/cometd/longPollTransport.js
new file mode 100644
index 0000000..84fae98
--- /dev/null
+++ b/dojox/cometd/longPollTransport.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.cometd.longPollTransport"]){
+dojo._hasResource["dojox.cometd.longPollTransport"]=true;
+dojo.provide("dojox.cometd.longPollTransport");
+dojo.require("dojox.cometd.longPollTransportJsonEncoded");
+}
diff --git a/dojox/cometd/longPollTransportFormEncoded.js b/dojox/cometd/longPollTransportFormEncoded.js
new file mode 100644
index 0000000..1c60e89
--- /dev/null
+++ b/dojox/cometd/longPollTransportFormEncoded.js
@@ -0,0 +1,118 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.cometd.longPollTransportFormEncoded"]){
+dojo._hasResource["dojox.cometd.longPollTransportFormEncoded"]=true;
+dojo.provide("dojox.cometd.longPollTransportFormEncoded");
+dojo.require("dojox.cometd._base");
+dojox.cometd.longPollTransportFormEncoded=new function(){
+this._connectionType="long-polling";
+this._cometd=null;
+this.check=function(_1,_2,_3){
+return ((!_3)&&(dojo.indexOf(_1,"long-polling")>=0));
+};
+this.tunnelInit=function(){
+var _4={channel:"/meta/connect",clientId:this._cometd.clientId,connectionType:this._connectionType,id:""+this._cometd.messageId++};
+_4=this._cometd._extendOut(_4);
+this.openTunnelWith({message:dojo.toJson([_4])});
+};
+this.tunnelCollapse=function(){
+if(!this._cometd._initialized){
+return;
+}
+if(this._cometd._advice&&this._cometd._advice["reconnect"]=="none"){
+return;
+}
+var _5=this._cometd._interval();
+if(this._cometd._status=="connected"){
+setTimeout(dojo.hitch(this,"_connect"),_5);
+}else{
+setTimeout(dojo.hitch(this._cometd,function(){
+this.init(this.url,this._props);
+}),_5);
+}
+};
+this._connect=function(){
+if(!this._cometd._initialized){
+return;
+}
+if(this._cometd._polling){
+return;
+}
+if((this._cometd._advice)&&(this._cometd._advice["reconnect"]=="handshake")){
+this._cometd._status="unconnected";
+this._initialized=false;
+this._cometd.init(this._cometd.url,this._cometd._props);
+}else{
+if(this._cometd._status=="connected"){
+var _6={channel:"/meta/connect",connectionType:this._connectionType,clientId:this._cometd.clientId,id:""+this._cometd.messageId++};
+if(this._cometd.connectTimeout>=this._cometd.expectedNetworkDelay){
+_6.advice={timeout:this._cometd.connectTimeout-this._cometd.expectedNetworkDelay};
+}
+_6=this._cometd._extendOut(_6);
+this.openTunnelWith({message:dojo.toJson([_6])});
+}
+}
+};
+this.deliver=function(_7){
+};
+this.openTunnelWith=function(_8,_9){
+this._cometd._polling=true;
+var _a={url:(_9||this._cometd.url),content:_8,handleAs:this._cometd.handleAs,load:dojo.hitch(this,function(_b){
+this._cometd._polling=false;
+this._cometd.deliver(_b);
+this._cometd._backon();
+this.tunnelCollapse();
+}),error:dojo.hitch(this,function(_c){
+var _d={failure:true,error:_c,advice:this._cometd._advice};
+this._cometd._polling=false;
+this._cometd._publishMeta("connect",false,_d);
+this._cometd._backoff();
+this.tunnelCollapse();
+})};
+var _e=this._cometd._connectTimeout();
+if(_e>0){
+_a.timeout=_e;
+}
+this._poll=dojo.xhrPost(_a);
+};
+this.sendMessages=function(_f){
+for(var i=0;i<_f.length;i++){
+_f[i].clientId=this._cometd.clientId;
+_f[i].id=""+this._cometd.messageId++;
+_f[i]=this._cometd._extendOut(_f[i]);
+}
+return dojo.xhrPost({url:this._cometd.url||dojo.config["cometdRoot"],handleAs:this._cometd.handleAs,load:dojo.hitch(this._cometd,"deliver"),content:{message:dojo.toJson(_f)},error:dojo.hitch(this,function(err){
+this._cometd._publishMeta("publish",false,{messages:_f});
+}),timeout:this._cometd.expectedNetworkDelay});
+};
+this.startup=function(_12){
+if(this._cometd._status=="connected"){
+return;
+}
+this.tunnelInit();
+};
+this.disconnect=function(){
+var _13={channel:"/meta/disconnect",clientId:this._cometd.clientId,id:""+this._cometd.messageId++};
+_13=this._cometd._extendOut(_13);
+dojo.xhrPost({url:this._cometd.url||dojo.config["cometdRoot"],handleAs:this._cometd.handleAs,content:{message:dojo.toJson([_13])}});
+};
+this.cancelConnect=function(){
+if(this._poll){
+this._poll.cancel();
+this._cometd._polling=false;
+this._cometd._publishMeta("connect",false,{cancel:true});
+this._cometd._backoff();
+this.disconnect();
+this.tunnelCollapse();
+}
+};
+};
+dojox.cometd.longPollTransport=dojox.cometd.longPollTransportFormEncoded;
+dojox.cometd.connectionTypes.register("long-polling",dojox.cometd.longPollTransport.check,dojox.cometd.longPollTransportFormEncoded);
+dojox.cometd.connectionTypes.register("long-polling-form-encoded",dojox.cometd.longPollTransport.check,dojox.cometd.longPollTransportFormEncoded);
+}
diff --git a/dojox/cometd/longPollTransportJsonEncoded.js b/dojox/cometd/longPollTransportJsonEncoded.js
new file mode 100644
index 0000000..8d0a07a
--- /dev/null
+++ b/dojox/cometd/longPollTransportJsonEncoded.js
@@ -0,0 +1,119 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.cometd.longPollTransportJsonEncoded"]){
+dojo._hasResource["dojox.cometd.longPollTransportJsonEncoded"]=true;
+dojo.provide("dojox.cometd.longPollTransportJsonEncoded");
+dojo.require("dojox.cometd._base");
+dojox.cometd.longPollTransportJsonEncoded=new function(){
+this._connectionType="long-polling";
+this._cometd=null;
+this.check=function(_1,_2,_3){
+return ((!_3)&&(dojo.indexOf(_1,"long-polling")>=0));
+};
+this.tunnelInit=function(){
+var _4={channel:"/meta/connect",clientId:this._cometd.clientId,connectionType:this._connectionType,id:""+this._cometd.messageId++};
+_4=this._cometd._extendOut(_4);
+this.openTunnelWith([_4]);
+};
+this.tunnelCollapse=function(){
+if(!this._cometd._initialized){
+return;
+}
+if(this._cometd._advice&&this._cometd._advice["reconnect"]=="none"){
+return;
+}
+if(this._cometd._status=="connected"){
+setTimeout(dojo.hitch(this,function(){
+this._connect();
+}),this._cometd._interval());
+}else{
+setTimeout(dojo.hitch(this._cometd,function(){
+this.init(this.url,this._props);
+}),this._cometd._interval());
+}
+};
+this._connect=function(){
+if(!this._cometd._initialized){
+return;
+}
+if(this._cometd._polling){
+return;
+}
+if((this._cometd._advice)&&(this._cometd._advice["reconnect"]=="handshake")){
+this._cometd._status="unconnected";
+this._initialized=false;
+this._cometd.init(this._cometd.url,this._cometd._props);
+}else{
+if(this._cometd._status=="connected"){
+var _5={channel:"/meta/connect",connectionType:this._connectionType,clientId:this._cometd.clientId,id:""+this._cometd.messageId++};
+if(this._cometd.connectTimeout>=this._cometd.expectedNetworkDelay){
+_5.advice={timeout:(this._cometd.connectTimeout-this._cometd.expectedNetworkDelay)};
+}
+_5=this._cometd._extendOut(_5);
+this.openTunnelWith([_5]);
+}
+}
+};
+this.deliver=function(_6){
+};
+this.openTunnelWith=function(_7,_8){
+this._cometd._polling=true;
+var _9={url:(_8||this._cometd.url),postData:dojo.toJson(_7),contentType:"text/json;charset=UTF-8",handleAs:this._cometd.handleAs,load:dojo.hitch(this,function(_a){
+this._cometd._polling=false;
+this._cometd.deliver(_a);
+this._cometd._backon();
+this.tunnelCollapse();
+}),error:dojo.hitch(this,function(_b){
+this._cometd._polling=false;
+var _c={failure:true,error:_b,advice:this._cometd._advice};
+this._cometd._publishMeta("connect",false,_c);
+this._cometd._backoff();
+this.tunnelCollapse();
+})};
+var _d=this._cometd._connectTimeout();
+if(_d>0){
+_9.timeout=_d;
+}
+this._poll=dojo.rawXhrPost(_9);
+};
+this.sendMessages=function(_e){
+for(var i=0;i<_e.length;i++){
+_e[i].clientId=this._cometd.clientId;
+_e[i].id=""+this._cometd.messageId++;
+_e[i]=this._cometd._extendOut(_e[i]);
+}
+return dojo.rawXhrPost({url:this._cometd.url||dojo.config["cometdRoot"],handleAs:this._cometd.handleAs,load:dojo.hitch(this._cometd,"deliver"),postData:dojo.toJson(_e),contentType:"text/json;charset=UTF-8",error:dojo.hitch(this,function(err){
+this._cometd._publishMeta("publish",false,{messages:_e});
+}),timeout:this._cometd.expectedNetworkDelay});
+};
+this.startup=function(_11){
+if(this._cometd._status=="connected"){
+return;
+}
+this.tunnelInit();
+};
+this.disconnect=function(){
+var _12={channel:"/meta/disconnect",clientId:this._cometd.clientId,id:""+this._cometd.messageId++};
+_12=this._cometd._extendOut(_12);
+dojo.rawXhrPost({url:this._cometd.url||dojo.config["cometdRoot"],handleAs:this._cometd.handleAs,postData:dojo.toJson([_12]),contentType:"text/json;charset=UTF-8"});
+};
+this.cancelConnect=function(){
+if(this._poll){
+this._poll.cancel();
+this._cometd._polling=false;
+this._cometd._publishMeta("connect",false,{cancel:true});
+this._cometd._backoff();
+this.disconnect();
+this.tunnelCollapse();
+}
+};
+};
+dojox.cometd.longPollTransport=dojox.cometd.longPollTransportJsonEncoded;
+dojox.cometd.connectionTypes.register("long-polling",dojox.cometd.longPollTransport.check,dojox.cometd.longPollTransportJsonEncoded);
+dojox.cometd.connectionTypes.register("long-polling-json-encoded",dojox.cometd.longPollTransport.check,dojox.cometd.longPollTransportJsonEncoded);
+}
diff --git a/dojox/cometd/timestamp.js b/dojox/cometd/timestamp.js
new file mode 100644
index 0000000..77b20c5
--- /dev/null
+++ b/dojox/cometd/timestamp.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.cometd.timestamp"]){
+dojo._hasResource["dojox.cometd.timestamp"]=true;
+dojo.provide("dojox.cometd.timestamp");
+dojo.require("dojox.cometd._base");
+dojox.cometd._extendOutList.push(function(_1){
+_1.timestamp=new Date().toUTCString();
+return _1;
+});
+}
diff --git a/dojox/cometd/timesync.js b/dojox/cometd/timesync.js
new file mode 100644
index 0000000..7df1eb5
--- /dev/null
+++ b/dojox/cometd/timesync.js
@@ -0,0 +1,75 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.cometd.timesync"]){
+dojo._hasResource["dojox.cometd.timesync"]=true;
+dojo.provide("dojox.cometd.timesync");
+dojo.require("dojox.cometd._base");
+dojox.cometd.timesync=new function(){
+this._window=10;
+this._lags=[];
+this._offsets=[];
+this.lag=0;
+this.offset=0;
+this.samples=0;
+this.getServerTime=function(){
+return new Date().getTime()+this.offset;
+};
+this.getServerDate=function(){
+return new Date(this.getServerTime());
+};
+this.setTimeout=function(_1,_2){
+var ts=(_2 instanceof Date)?_2.getTime():(0+_2);
+var tc=ts-this.offset;
+var _5=tc-new Date().getTime();
+if(_5<=0){
+_5=1;
+}
+return setTimeout(_1,_5);
+};
+this._in=function(_6){
+var _7=_6.channel;
+if(_7&&_7.indexOf("/meta/")==0){
+if(_6.ext&&_6.ext.timesync){
+var _8=_6.ext.timesync;
+var _9=new Date().getTime();
+var l=(_9-_8.tc-_8.p)/2-_8.a;
+var o=_8.ts-_8.tc-l;
+this._lags.push(l);
+this._offsets.push(o);
+if(this._offsets.length>this._window){
+this._offsets.shift();
+this._lags.shift();
+}
+this.samples++;
+l=0;
+o=0;
+for(var i in this._offsets){
+l+=this._lags[i];
+o+=this._offsets[i];
+}
+this.offset=parseInt((o/this._offsets.length).toFixed());
+this.lag=parseInt((l/this._lags.length).toFixed());
+}
+}
+return _6;
+};
+this._out=function(_d){
+var _e=_d.channel;
+if(_e&&_e.indexOf("/meta/")==0){
+var _f=new Date().getTime();
+if(!_d.ext){
+_d.ext={};
+}
+_d.ext.timesync={tc:_f,l:this.lag,o:this.offset};
+}
+return _d;
+};
+};
+dojox.cometd._extendInList.push(dojo.hitch(dojox.cometd.timesync,"_in"));
+dojox.cometd._extendOutList.push(dojo.hitch(dojox.cometd.timesync,"_out"));
+}
diff --git a/dojox/data/AndOrReadStore.js b/dojox/data/AndOrReadStore.js
new file mode 100644
index 0000000..b8a154b
--- /dev/null
+++ b/dojox/data/AndOrReadStore.js
@@ -0,0 +1,617 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.AndOrReadStore"]){
+dojo._hasResource["dojox.data.AndOrReadStore"]=true;
+dojo.provide("dojox.data.AndOrReadStore");
+dojo.require("dojo.data.util.filter");
+dojo.require("dojo.data.util.simpleFetch");
+dojo.require("dojo.date.stamp");
+dojo.declare("dojox.data.AndOrReadStore",null,{constructor:function(_1){
+this._arrayOfAllItems=[];
+this._arrayOfTopLevelItems=[];
+this._loadFinished=false;
+this._jsonFileUrl=_1.url;
+this._jsonData=_1.data;
+this._datatypeMap=_1.typeMap||{};
+if(!this._datatypeMap["Date"]){
+this._datatypeMap["Date"]={type:Date,deserialize:function(_2){
+return dojo.date.stamp.fromISOString(_2);
+}};
+}
+this._features={"dojo.data.api.Read":true,"dojo.data.api.Identity":true};
+this._itemsByIdentity=null;
+this._storeRefPropName="_S";
+this._itemNumPropName="_0";
+this._rootItemPropName="_RI";
+this._reverseRefMap="_RRM";
+this._loadInProgress=false;
+this._queuedFetches=[];
+if(_1.urlPreventCache!==undefined){
+this.urlPreventCache=_1.urlPreventCache?true:false;
+}
+if(_1.clearOnClose){
+this.clearOnClose=true;
+}
+},url:"",data:null,typeMap:null,clearOnClose:false,urlPreventCache:false,_assertIsItem:function(_3){
+if(!this.isItem(_3)){
+throw new Error("dojox.data.AndOrReadStore: Invalid item argument.");
+}
+},_assertIsAttribute:function(_4){
+if(typeof _4!=="string"){
+throw new Error("dojox.data.AndOrReadStore: Invalid attribute argument.");
+}
+},getValue:function(_5,_6,_7){
+var _8=this.getValues(_5,_6);
+return (_8.length>0)?_8[0]:_7;
+},getValues:function(_9,_a){
+this._assertIsItem(_9);
+this._assertIsAttribute(_a);
+return _9[_a]||[];
+},getAttributes:function(_b){
+this._assertIsItem(_b);
+var _c=[];
+for(var _d in _b){
+if((_d!==this._storeRefPropName)&&(_d!==this._itemNumPropName)&&(_d!==this._rootItemPropName)&&(_d!==this._reverseRefMap)){
+_c.push(_d);
+}
+}
+return _c;
+},hasAttribute:function(_e,_f){
+return this.getValues(_e,_f).length>0;
+},containsValue:function(_10,_11,_12){
+var _13=undefined;
+if(typeof _12==="string"){
+_13=dojo.data.util.filter.patternToRegExp(_12,false);
+}
+return this._containsValue(_10,_11,_12,_13);
+},_containsValue:function(_14,_15,_16,_17){
+return dojo.some(this.getValues(_14,_15),function(_18){
+if(_18!==null&&!dojo.isObject(_18)&&_17){
+if(_18.toString().match(_17)){
+return true;
+}
+}else{
+if(_16===_18){
+return true;
+}
+}
+});
+},isItem:function(_19){
+if(_19&&_19[this._storeRefPropName]===this){
+if(this._arrayOfAllItems[_19[this._itemNumPropName]]===_19){
+return true;
+}
+}
+return false;
+},isItemLoaded:function(_1a){
+return this.isItem(_1a);
+},loadItem:function(_1b){
+this._assertIsItem(_1b.item);
+},getFeatures:function(){
+return this._features;
+},getLabel:function(_1c){
+if(this._labelAttr&&this.isItem(_1c)){
+return this.getValue(_1c,this._labelAttr);
+}
+return undefined;
+},getLabelAttributes:function(_1d){
+if(this._labelAttr){
+return [this._labelAttr];
+}
+return null;
+},_fetchItems:function(_1e,_1f,_20){
+var _21=this;
+var _22=function(_23,_24){
+var _25=[];
+if(_23.query){
+var _26=dojo.fromJson(dojo.toJson(_23.query));
+if(typeof _26=="object"){
+var _27=0;
+var p;
+for(p in _26){
+_27++;
+}
+if(_27>1&&_26.complexQuery){
+var cq=_26.complexQuery;
+var _2a=false;
+for(p in _26){
+if(p!=="complexQuery"){
+if(!_2a){
+cq="( "+cq+" )";
+_2a=true;
+}
+cq+=" AND "+p+":"+_23.query[p];
+delete _26[p];
+}
+}
+_26.complexQuery=cq;
+}
+}
+var _2b=_23.queryOptions?_23.queryOptions.ignoreCase:false;
+if(typeof _26!="string"){
+_26=dojo.toJson(_26);
+_26=_26.replace(/\\\\/g,"\\");
+}
+_26=_26.replace(/\\"/g,"\"");
+var _2c=dojo.trim(_26.replace(/{|}/g,""));
+var _2d,i;
+if(_2c.match(/"? *complexQuery *"?:/)){
+_2c=dojo.trim(_2c.replace(/"?\s*complexQuery\s*"?:/,""));
+var _2f=["'","\""];
+var _30,_31;
+var _32=false;
+for(i=0;i<_2f.length;i++){
+_30=_2c.indexOf(_2f[i]);
+_2d=_2c.indexOf(_2f[i],1);
+_31=_2c.indexOf(":",1);
+if(_30===0&&_2d!=-1&&_31<_2d){
+_32=true;
+break;
+}
+}
+if(_32){
+_2c=_2c.replace(/^\"|^\'|\"$|\'$/g,"");
+}
+}
+var _33=_2c;
+var _34=/^,|^NOT |^AND |^OR |^\(|^\)|^!|^&&|^\|\|/i;
+var _35="";
+var op="";
+var val="";
+var pos=-1;
+var err=false;
+var key="";
+var _3b="";
+var tok="";
+_2d=-1;
+for(i=0;i<_24.length;++i){
+var _3d=true;
+var _3e=_24[i];
+if(_3e===null){
+_3d=false;
+}else{
+_2c=_33;
+_35="";
+while(_2c.length>0&&!err){
+op=_2c.match(_34);
+while(op&&!err){
+_2c=dojo.trim(_2c.replace(op[0],""));
+op=dojo.trim(op[0]).toUpperCase();
+op=op=="NOT"?"!":op=="AND"||op==","?"&&":op=="OR"?"||":op;
+op=" "+op+" ";
+_35+=op;
+op=_2c.match(_34);
+}
+if(_2c.length>0){
+pos=_2c.indexOf(":");
+if(pos==-1){
+err=true;
+break;
+}else{
+key=dojo.trim(_2c.substring(0,pos).replace(/\"|\'/g,""));
+_2c=dojo.trim(_2c.substring(pos+1));
+tok=_2c.match(/^\'|^\"/);
+if(tok){
+tok=tok[0];
+pos=_2c.indexOf(tok);
+_2d=_2c.indexOf(tok,pos+1);
+if(_2d==-1){
+err=true;
+break;
+}
+_3b=_2c.substring(pos+1,_2d);
+if(_2d==_2c.length-1){
+_2c="";
+}else{
+_2c=dojo.trim(_2c.substring(_2d+1));
+}
+_35+=_21._containsValue(_3e,key,_3b,dojo.data.util.filter.patternToRegExp(_3b,_2b));
+}else{
+tok=_2c.match(/\s|\)|,/);
+if(tok){
+var _3f=new Array(tok.length);
+for(var j=0;j<tok.length;j++){
+_3f[j]=_2c.indexOf(tok[j]);
+}
+pos=_3f[0];
+if(_3f.length>1){
+for(var j=1;j<_3f.length;j++){
+pos=Math.min(pos,_3f[j]);
+}
+}
+_3b=dojo.trim(_2c.substring(0,pos));
+_2c=dojo.trim(_2c.substring(pos));
+}else{
+_3b=dojo.trim(_2c);
+_2c="";
+}
+_35+=_21._containsValue(_3e,key,_3b,dojo.data.util.filter.patternToRegExp(_3b,_2b));
+}
+}
+}
+}
+_3d=eval(_35);
+}
+if(_3d){
+_25.push(_3e);
+}
+}
+if(err){
+_25=[];
+
+}
+_1f(_25,_23);
+}else{
+for(var i=0;i<_24.length;++i){
+var _41=_24[i];
+if(_41!==null){
+_25.push(_41);
+}
+}
+_1f(_25,_23);
+}
+};
+if(this._loadFinished){
+_22(_1e,this._getItemsArray(_1e.queryOptions));
+}else{
+if(this._jsonFileUrl){
+if(this._loadInProgress){
+this._queuedFetches.push({args:_1e,filter:_22});
+}else{
+this._loadInProgress=true;
+var _42={url:_21._jsonFileUrl,handleAs:"json-comment-optional",preventCache:this.urlPreventCache};
+var _43=dojo.xhrGet(_42);
+_43.addCallback(function(_44){
+try{
+_21._getItemsFromLoadedData(_44);
+_21._loadFinished=true;
+_21._loadInProgress=false;
+_22(_1e,_21._getItemsArray(_1e.queryOptions));
+_21._handleQueuedFetches();
+}
+catch(e){
+_21._loadFinished=true;
+_21._loadInProgress=false;
+_20(e,_1e);
+}
+});
+_43.addErrback(function(_45){
+_21._loadInProgress=false;
+_20(_45,_1e);
+});
+var _46=null;
+if(_1e.abort){
+_46=_1e.abort;
+}
+_1e.abort=function(){
+var df=_43;
+if(df&&df.fired===-1){
+df.cancel();
+df=null;
+}
+if(_46){
+_46.call(_1e);
+}
+};
+}
+}else{
+if(this._jsonData){
+try{
+this._loadFinished=true;
+this._getItemsFromLoadedData(this._jsonData);
+this._jsonData=null;
+_22(_1e,this._getItemsArray(_1e.queryOptions));
+}
+catch(e){
+_20(e,_1e);
+}
+}else{
+_20(new Error("dojox.data.AndOrReadStore: No JSON source data was provided as either URL or a nested Javascript object."),_1e);
+}
+}
+}
+},_handleQueuedFetches:function(){
+if(this._queuedFetches.length>0){
+for(var i=0;i<this._queuedFetches.length;i++){
+var _49=this._queuedFetches[i];
+var _4a=_49.args;
+var _4b=_49.filter;
+if(_4b){
+_4b(_4a,this._getItemsArray(_4a.queryOptions));
+}else{
+this.fetchItemByIdentity(_4a);
+}
+}
+this._queuedFetches=[];
+}
+},_getItemsArray:function(_4c){
+if(_4c&&_4c.deep){
+return this._arrayOfAllItems;
+}
+return this._arrayOfTopLevelItems;
+},close:function(_4d){
+if(this.clearOnClose&&(this._jsonFileUrl!=="")){
+this._arrayOfAllItems=[];
+this._arrayOfTopLevelItems=[];
+this._loadFinished=false;
+this._itemsByIdentity=null;
+this._loadInProgress=false;
+this._queuedFetches=[];
+}
+},_getItemsFromLoadedData:function(_4e){
+function _4f(_50){
+var _51=((_50!==null)&&(typeof _50==="object")&&(!dojo.isArray(_50))&&(!dojo.isFunction(_50))&&(_50.constructor==Object)&&(typeof _50._reference==="undefined")&&(typeof _50._type==="undefined")&&(typeof _50._value==="undefined"));
+return _51;
+};
+var _52=this;
+function _53(_54){
+_52._arrayOfAllItems.push(_54);
+for(var _55 in _54){
+var _56=_54[_55];
+if(_56){
+if(dojo.isArray(_56)){
+var _57=_56;
+for(var k=0;k<_57.length;++k){
+var _59=_57[k];
+if(_4f(_59)){
+_53(_59);
+}
+}
+}else{
+if(_4f(_56)){
+_53(_56);
+}
+}
+}
+}
+};
+this._labelAttr=_4e.label;
+var i;
+var _5b;
+this._arrayOfAllItems=[];
+this._arrayOfTopLevelItems=_4e.items;
+for(i=0;i<this._arrayOfTopLevelItems.length;++i){
+_5b=this._arrayOfTopLevelItems[i];
+_53(_5b);
+_5b[this._rootItemPropName]=true;
+}
+var _5c={};
+var key;
+for(i=0;i<this._arrayOfAllItems.length;++i){
+_5b=this._arrayOfAllItems[i];
+for(key in _5b){
+if(key!==this._rootItemPropName){
+var _5e=_5b[key];
+if(_5e!==null){
+if(!dojo.isArray(_5e)){
+_5b[key]=[_5e];
+}
+}else{
+_5b[key]=[null];
+}
+}
+_5c[key]=key;
+}
+}
+while(_5c[this._storeRefPropName]){
+this._storeRefPropName+="_";
+}
+while(_5c[this._itemNumPropName]){
+this._itemNumPropName+="_";
+}
+while(_5c[this._reverseRefMap]){
+this._reverseRefMap+="_";
+}
+var _5f;
+var _60=_4e.identifier;
+if(_60){
+this._itemsByIdentity={};
+this._features["dojo.data.api.Identity"]=_60;
+for(i=0;i<this._arrayOfAllItems.length;++i){
+_5b=this._arrayOfAllItems[i];
+_5f=_5b[_60];
+var _61=_5f[0];
+if(!this._itemsByIdentity[_61]){
+this._itemsByIdentity[_61]=_5b;
+}else{
+if(this._jsonFileUrl){
+throw new Error("dojox.data.AndOrReadStore:  The json data as specified by: ["+this._jsonFileUrl+"] is malformed.  Items within the list have identifier: ["+_60+"].  Value collided: ["+_61+"]");
+}else{
+if(this._jsonData){
+throw new Error("dojox.data.AndOrReadStore:  The json data provided by the creation arguments is malformed.  Items within the list have identifier: ["+_60+"].  Value collided: ["+_61+"]");
+}
+}
+}
+}
+}else{
+this._features["dojo.data.api.Identity"]=Number;
+}
+for(i=0;i<this._arrayOfAllItems.length;++i){
+_5b=this._arrayOfAllItems[i];
+_5b[this._storeRefPropName]=this;
+_5b[this._itemNumPropName]=i;
+}
+for(i=0;i<this._arrayOfAllItems.length;++i){
+_5b=this._arrayOfAllItems[i];
+for(key in _5b){
+_5f=_5b[key];
+for(var j=0;j<_5f.length;++j){
+_5e=_5f[j];
+if(_5e!==null&&typeof _5e=="object"){
+if(_5e._type&&_5e._value){
+var _63=_5e._type;
+var _64=this._datatypeMap[_63];
+if(!_64){
+throw new Error("dojox.data.AndOrReadStore: in the typeMap constructor arg, no object class was specified for the datatype '"+_63+"'");
+}else{
+if(dojo.isFunction(_64)){
+_5f[j]=new _64(_5e._value);
+}else{
+if(dojo.isFunction(_64.deserialize)){
+_5f[j]=_64.deserialize(_5e._value);
+}else{
+throw new Error("dojox.data.AndOrReadStore: Value provided in typeMap was neither a constructor, nor a an object with a deserialize function");
+}
+}
+}
+}
+if(_5e._reference){
+var _65=_5e._reference;
+if(!dojo.isObject(_65)){
+_5f[j]=this._itemsByIdentity[_65];
+}else{
+for(var k=0;k<this._arrayOfAllItems.length;++k){
+var _67=this._arrayOfAllItems[k];
+var _68=true;
+for(var _69 in _65){
+if(_67[_69]!=_65[_69]){
+_68=false;
+}
+}
+if(_68){
+_5f[j]=_67;
+}
+}
+}
+if(this.referenceIntegrity){
+var _6a=_5f[j];
+if(this.isItem(_6a)){
+this._addReferenceToMap(_6a,_5b,key);
+}
+}
+}else{
+if(this.isItem(_5e)){
+if(this.referenceIntegrity){
+this._addReferenceToMap(_5e,_5b,key);
+}
+}
+}
+}
+}
+}
+}
+},_addReferenceToMap:function(_6b,_6c,_6d){
+},getIdentity:function(_6e){
+var _6f=this._features["dojo.data.api.Identity"];
+if(_6f===Number){
+return _6e[this._itemNumPropName];
+}else{
+var _70=_6e[_6f];
+if(_70){
+return _70[0];
+}
+}
+return null;
+},fetchItemByIdentity:function(_71){
+if(!this._loadFinished){
+var _72=this;
+if(this._jsonFileUrl){
+if(this._loadInProgress){
+this._queuedFetches.push({args:_71});
+}else{
+this._loadInProgress=true;
+var _73={url:_72._jsonFileUrl,handleAs:"json-comment-optional",preventCache:this.urlPreventCache};
+var _74=dojo.xhrGet(_73);
+_74.addCallback(function(_75){
+var _76=_71.scope?_71.scope:dojo.global;
+try{
+_72._getItemsFromLoadedData(_75);
+_72._loadFinished=true;
+_72._loadInProgress=false;
+var _77=_72._getItemByIdentity(_71.identity);
+if(_71.onItem){
+_71.onItem.call(_76,_77);
+}
+_72._handleQueuedFetches();
+}
+catch(error){
+_72._loadInProgress=false;
+if(_71.onError){
+_71.onError.call(_76,error);
+}
+}
+});
+_74.addErrback(function(_78){
+_72._loadInProgress=false;
+if(_71.onError){
+var _79=_71.scope?_71.scope:dojo.global;
+_71.onError.call(_79,_78);
+}
+});
+}
+}else{
+if(this._jsonData){
+_72._getItemsFromLoadedData(_72._jsonData);
+_72._jsonData=null;
+_72._loadFinished=true;
+var _7a=_72._getItemByIdentity(_71.identity);
+if(_71.onItem){
+var _7b=_71.scope?_71.scope:dojo.global;
+_71.onItem.call(_7b,_7a);
+}
+}
+}
+}else{
+var _7a=this._getItemByIdentity(_71.identity);
+if(_71.onItem){
+var _7b=_71.scope?_71.scope:dojo.global;
+_71.onItem.call(_7b,_7a);
+}
+}
+},_getItemByIdentity:function(_7c){
+var _7d=null;
+if(this._itemsByIdentity){
+_7d=this._itemsByIdentity[_7c];
+}else{
+_7d=this._arrayOfAllItems[_7c];
+}
+if(_7d===undefined){
+_7d=null;
+}
+return _7d;
+},getIdentityAttributes:function(_7e){
+var _7f=this._features["dojo.data.api.Identity"];
+if(_7f===Number){
+return null;
+}else{
+return [_7f];
+}
+},_forceLoad:function(){
+var _80=this;
+if(this._jsonFileUrl){
+var _81={url:_80._jsonFileUrl,handleAs:"json-comment-optional",preventCache:this.urlPreventCache,sync:true};
+var _82=dojo.xhrGet(_81);
+_82.addCallback(function(_83){
+try{
+if(_80._loadInProgress!==true&&!_80._loadFinished){
+_80._getItemsFromLoadedData(_83);
+_80._loadFinished=true;
+}else{
+if(_80._loadInProgress){
+throw new Error("dojox.data.AndOrReadStore:  Unable to perform a synchronous load, an async load is in progress.");
+}
+}
+}
+catch(e){
+
+throw e;
+}
+});
+_82.addErrback(function(_84){
+throw _84;
+});
+}else{
+if(this._jsonData){
+_80._getItemsFromLoadedData(_80._jsonData);
+_80._jsonData=null;
+_80._loadFinished=true;
+}
+}
+}});
+dojo.extend(dojox.data.AndOrReadStore,dojo.data.util.simpleFetch);
+}
diff --git a/dojox/data/AndOrWriteStore.js b/dojox/data/AndOrWriteStore.js
new file mode 100644
index 0000000..0f5c046
--- /dev/null
+++ b/dojox/data/AndOrWriteStore.js
@@ -0,0 +1,526 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.AndOrWriteStore"]){
+dojo._hasResource["dojox.data.AndOrWriteStore"]=true;
+dojo.provide("dojox.data.AndOrWriteStore");
+dojo.require("dojox.data.AndOrReadStore");
+dojo.declare("dojox.data.AndOrWriteStore",dojox.data.AndOrReadStore,{constructor:function(_1){
+this._features["dojo.data.api.Write"]=true;
+this._features["dojo.data.api.Notification"]=true;
+this._pending={_newItems:{},_modifiedItems:{},_deletedItems:{}};
+if(!this._datatypeMap["Date"].serialize){
+this._datatypeMap["Date"].serialize=function(_2){
+return dojo.date.stamp.toISOString(_2,{zulu:true});
+};
+}
+if(_1&&(_1.referenceIntegrity===false)){
+this.referenceIntegrity=false;
+}
+this._saveInProgress=false;
+},referenceIntegrity:true,_assert:function(_3){
+if(!_3){
+throw new Error("assertion failed in ItemFileWriteStore");
+}
+},_getIdentifierAttribute:function(){
+var _4=this.getFeatures()["dojo.data.api.Identity"];
+return _4;
+},newItem:function(_5,_6){
+this._assert(!this._saveInProgress);
+if(!this._loadFinished){
+this._forceLoad();
+}
+if(typeof _5!="object"&&typeof _5!="undefined"){
+throw new Error("newItem() was passed something other than an object");
+}
+var _7=null;
+var _8=this._getIdentifierAttribute();
+if(_8===Number){
+_7=this._arrayOfAllItems.length;
+}else{
+_7=_5[_8];
+if(typeof _7==="undefined"){
+throw new Error("newItem() was not passed an identity for the new item");
+}
+if(dojo.isArray(_7)){
+throw new Error("newItem() was not passed an single-valued identity");
+}
+}
+if(this._itemsByIdentity){
+this._assert(typeof this._itemsByIdentity[_7]==="undefined");
+}
+this._assert(typeof this._pending._newItems[_7]==="undefined");
+this._assert(typeof this._pending._deletedItems[_7]==="undefined");
+var _9={};
+_9[this._storeRefPropName]=this;
+_9[this._itemNumPropName]=this._arrayOfAllItems.length;
+if(this._itemsByIdentity){
+this._itemsByIdentity[_7]=_9;
+_9[_8]=[_7];
+}
+this._arrayOfAllItems.push(_9);
+var _a=null;
+if(_6&&_6.parent&&_6.attribute){
+_a={item:_6.parent,attribute:_6.attribute,oldValue:undefined};
+var _b=this.getValues(_6.parent,_6.attribute);
+if(_b&&_b.length>0){
+var _c=_b.slice(0,_b.length);
+if(_b.length===1){
+_a.oldValue=_b[0];
+}else{
+_a.oldValue=_b.slice(0,_b.length);
+}
+_c.push(_9);
+this._setValueOrValues(_6.parent,_6.attribute,_c,false);
+_a.newValue=this.getValues(_6.parent,_6.attribute);
+}else{
+this._setValueOrValues(_6.parent,_6.attribute,_9,false);
+_a.newValue=_9;
+}
+}else{
+_9[this._rootItemPropName]=true;
+this._arrayOfTopLevelItems.push(_9);
+}
+this._pending._newItems[_7]=_9;
+for(var _d in _5){
+if(_d===this._storeRefPropName||_d===this._itemNumPropName){
+throw new Error("encountered bug in ItemFileWriteStore.newItem");
+}
+var _e=_5[_d];
+if(!dojo.isArray(_e)){
+_e=[_e];
+}
+_9[_d]=_e;
+if(this.referenceIntegrity){
+for(var i=0;i<_e.length;i++){
+var val=_e[i];
+if(this.isItem(val)){
+this._addReferenceToMap(val,_9,_d);
+}
+}
+}
+}
+this.onNew(_9,_a);
+return _9;
+},_removeArrayElement:function(_11,_12){
+var _13=dojo.indexOf(_11,_12);
+if(_13!=-1){
+_11.splice(_13,1);
+return true;
+}
+return false;
+},deleteItem:function(_14){
+this._assert(!this._saveInProgress);
+this._assertIsItem(_14);
+var _15=_14[this._itemNumPropName];
+var _16=this.getIdentity(_14);
+if(this.referenceIntegrity){
+var _17=this.getAttributes(_14);
+if(_14[this._reverseRefMap]){
+_14["backup_"+this._reverseRefMap]=dojo.clone(_14[this._reverseRefMap]);
+}
+dojo.forEach(_17,function(_18){
+dojo.forEach(this.getValues(_14,_18),function(_19){
+if(this.isItem(_19)){
+if(!_14["backupRefs_"+this._reverseRefMap]){
+_14["backupRefs_"+this._reverseRefMap]=[];
+}
+_14["backupRefs_"+this._reverseRefMap].push({id:this.getIdentity(_19),attr:_18});
+this._removeReferenceFromMap(_19,_14,_18);
+}
+},this);
+},this);
+var _1a=_14[this._reverseRefMap];
+if(_1a){
+for(var _1b in _1a){
+var _1c=null;
+if(this._itemsByIdentity){
+_1c=this._itemsByIdentity[_1b];
+}else{
+_1c=this._arrayOfAllItems[_1b];
+}
+if(_1c){
+for(var _1d in _1a[_1b]){
+var _1e=this.getValues(_1c,_1d)||[];
+var _1f=dojo.filter(_1e,function(_20){
+return !(this.isItem(_20)&&this.getIdentity(_20)==_16);
+},this);
+this._removeReferenceFromMap(_14,_1c,_1d);
+if(_1f.length<_1e.length){
+this._setValueOrValues(_1c,_1d,_1f);
+}
+}
+}
+}
+}
+}
+this._arrayOfAllItems[_15]=null;
+_14[this._storeRefPropName]=null;
+if(this._itemsByIdentity){
+delete this._itemsByIdentity[_16];
+}
+this._pending._deletedItems[_16]=_14;
+if(_14[this._rootItemPropName]){
+this._removeArrayElement(this._arrayOfTopLevelItems,_14);
+}
+this.onDelete(_14);
+return true;
+},setValue:function(_21,_22,_23){
+return this._setValueOrValues(_21,_22,_23,true);
+},setValues:function(_24,_25,_26){
+return this._setValueOrValues(_24,_25,_26,true);
+},unsetAttribute:function(_27,_28){
+return this._setValueOrValues(_27,_28,[],true);
+},_setValueOrValues:function(_29,_2a,_2b,_2c){
+this._assert(!this._saveInProgress);
+this._assertIsItem(_29);
+this._assert(dojo.isString(_2a));
+this._assert(typeof _2b!=="undefined");
+var _2d=this._getIdentifierAttribute();
+if(_2a==_2d){
+throw new Error("ItemFileWriteStore does not have support for changing the value of an item's identifier.");
+}
+var _2e=this._getValueOrValues(_29,_2a);
+var _2f=this.getIdentity(_29);
+if(!this._pending._modifiedItems[_2f]){
+var _30={};
+for(var key in _29){
+if((key===this._storeRefPropName)||(key===this._itemNumPropName)||(key===this._rootItemPropName)){
+_30[key]=_29[key];
+}else{
+if(key===this._reverseRefMap){
+_30[key]=dojo.clone(_29[key]);
+}else{
+_30[key]=_29[key].slice(0,_29[key].length);
+}
+}
+}
+this._pending._modifiedItems[_2f]=_30;
+}
+var _32=false;
+if(dojo.isArray(_2b)&&_2b.length===0){
+_32=delete _29[_2a];
+_2b=undefined;
+if(this.referenceIntegrity&&_2e){
+var _33=_2e;
+if(!dojo.isArray(_33)){
+_33=[_33];
+}
+for(var i=0;i<_33.length;i++){
+var _35=_33[i];
+if(this.isItem(_35)){
+this._removeReferenceFromMap(_35,_29,_2a);
+}
+}
+}
+}else{
+var _36;
+if(dojo.isArray(_2b)){
+var _37=_2b;
+_36=_2b.slice(0,_2b.length);
+}else{
+_36=[_2b];
+}
+if(this.referenceIntegrity){
+if(_2e){
+var _33=_2e;
+if(!dojo.isArray(_33)){
+_33=[_33];
+}
+var map={};
+dojo.forEach(_33,function(_39){
+if(this.isItem(_39)){
+var id=this.getIdentity(_39);
+map[id.toString()]=true;
+}
+},this);
+dojo.forEach(_36,function(_3b){
+if(this.isItem(_3b)){
+var id=this.getIdentity(_3b);
+if(map[id.toString()]){
+delete map[id.toString()];
+}else{
+this._addReferenceToMap(_3b,_29,_2a);
+}
+}
+},this);
+for(var rId in map){
+var _3e;
+if(this._itemsByIdentity){
+_3e=this._itemsByIdentity[rId];
+}else{
+_3e=this._arrayOfAllItems[rId];
+}
+this._removeReferenceFromMap(_3e,_29,_2a);
+}
+}else{
+for(var i=0;i<_36.length;i++){
+var _35=_36[i];
+if(this.isItem(_35)){
+this._addReferenceToMap(_35,_29,_2a);
+}
+}
+}
+}
+_29[_2a]=_36;
+_32=true;
+}
+if(_2c){
+this.onSet(_29,_2a,_2e,_2b);
+}
+return _32;
+},_addReferenceToMap:function(_3f,_40,_41){
+var _42=this.getIdentity(_40);
+var _43=_3f[this._reverseRefMap];
+if(!_43){
+_43=_3f[this._reverseRefMap]={};
+}
+var _44=_43[_42];
+if(!_44){
+_44=_43[_42]={};
+}
+_44[_41]=true;
+},_removeReferenceFromMap:function(_45,_46,_47){
+var _48=this.getIdentity(_46);
+var _49=_45[this._reverseRefMap];
+var _4a;
+if(_49){
+for(_4a in _49){
+if(_4a==_48){
+delete _49[_4a][_47];
+if(this._isEmpty(_49[_4a])){
+delete _49[_4a];
+}
+}
+}
+if(this._isEmpty(_49)){
+delete _45[this._reverseRefMap];
+}
+}
+},_dumpReferenceMap:function(){
+var i;
+for(i=0;i<this._arrayOfAllItems.length;i++){
+var _4c=this._arrayOfAllItems[i];
+if(_4c&&_4c[this._reverseRefMap]){
+
+}
+}
+},_getValueOrValues:function(_4d,_4e){
+var _4f=undefined;
+if(this.hasAttribute(_4d,_4e)){
+var _50=this.getValues(_4d,_4e);
+if(_50.length==1){
+_4f=_50[0];
+}else{
+_4f=_50;
+}
+}
+return _4f;
+},_flatten:function(_51){
+if(this.isItem(_51)){
+var _52=_51;
+var _53=this.getIdentity(_52);
+var _54={_reference:_53};
+return _54;
+}else{
+if(typeof _51==="object"){
+for(var _55 in this._datatypeMap){
+var _56=this._datatypeMap[_55];
+if(dojo.isObject(_56)&&!dojo.isFunction(_56)){
+if(_51 instanceof _56.type){
+if(!_56.serialize){
+throw new Error("ItemFileWriteStore:  No serializer defined for type mapping: ["+_55+"]");
+}
+return {_type:_55,_value:_56.serialize(_51)};
+}
+}else{
+if(_51 instanceof _56){
+return {_type:_55,_value:_51.toString()};
+}
+}
+}
+}
+return _51;
+}
+},_getNewFileContentString:function(){
+var _57={};
+var _58=this._getIdentifierAttribute();
+if(_58!==Number){
+_57.identifier=_58;
+}
+if(this._labelAttr){
+_57.label=this._labelAttr;
+}
+_57.items=[];
+for(var i=0;i<this._arrayOfAllItems.length;++i){
+var _5a=this._arrayOfAllItems[i];
+if(_5a!==null){
+var _5b={};
+for(var key in _5a){
+if(key!==this._storeRefPropName&&key!==this._itemNumPropName&&key!==this._reverseRefMap&&key!==this._rootItemPropName){
+var _5d=key;
+var _5e=this.getValues(_5a,_5d);
+if(_5e.length==1){
+_5b[_5d]=this._flatten(_5e[0]);
+}else{
+var _5f=[];
+for(var j=0;j<_5e.length;++j){
+_5f.push(this._flatten(_5e[j]));
+_5b[_5d]=_5f;
+}
+}
+}
+}
+_57.items.push(_5b);
+}
+}
+var _61=true;
+return dojo.toJson(_57,_61);
+},_isEmpty:function(_62){
+var _63=true;
+if(dojo.isObject(_62)){
+var i;
+for(i in _62){
+_63=false;
+break;
+}
+}else{
+if(dojo.isArray(_62)){
+if(_62.length>0){
+_63=false;
+}
+}
+}
+return _63;
+},save:function(_65){
+this._assert(!this._saveInProgress);
+this._saveInProgress=true;
+var _66=this;
+var _67=function(){
+_66._pending={_newItems:{},_modifiedItems:{},_deletedItems:{}};
+_66._saveInProgress=false;
+if(_65&&_65.onComplete){
+var _68=_65.scope||dojo.global;
+_65.onComplete.call(_68);
+}
+};
+var _69=function(){
+_66._saveInProgress=false;
+if(_65&&_65.onError){
+var _6a=_65.scope||dojo.global;
+_65.onError.call(_6a);
+}
+};
+if(this._saveEverything){
+var _6b=this._getNewFileContentString();
+this._saveEverything(_67,_69,_6b);
+}
+if(this._saveCustom){
+this._saveCustom(_67,_69);
+}
+if(!this._saveEverything&&!this._saveCustom){
+_67();
+}
+},revert:function(){
+this._assert(!this._saveInProgress);
+var _6c;
+for(_6c in this._pending._modifiedItems){
+var _6d=this._pending._modifiedItems[_6c];
+var _6e=null;
+if(this._itemsByIdentity){
+_6e=this._itemsByIdentity[_6c];
+}else{
+_6e=this._arrayOfAllItems[_6c];
+}
+_6d[this._storeRefPropName]=this;
+_6e[this._storeRefPropName]=null;
+var _6f=_6e[this._itemNumPropName];
+this._arrayOfAllItems[_6f]=_6d;
+if(_6e[this._rootItemPropName]){
+var i;
+for(i=0;i<this._arrayOfTopLevelItems.length;i++){
+var _71=this._arrayOfTopLevelItems[i];
+if(this.getIdentity(_71)==_6c){
+this._arrayOfTopLevelItems[i]=_6d;
+break;
+}
+}
+}
+if(this._itemsByIdentity){
+this._itemsByIdentity[_6c]=_6d;
+}
+}
+var _72;
+for(_6c in this._pending._deletedItems){
+_72=this._pending._deletedItems[_6c];
+_72[this._storeRefPropName]=this;
+var _73=_72[this._itemNumPropName];
+if(_72["backup_"+this._reverseRefMap]){
+_72[this._reverseRefMap]=_72["backup_"+this._reverseRefMap];
+delete _72["backup_"+this._reverseRefMap];
+}
+this._arrayOfAllItems[_73]=_72;
+if(this._itemsByIdentity){
+this._itemsByIdentity[_6c]=_72;
+}
+if(_72[this._rootItemPropName]){
+this._arrayOfTopLevelItems.push(_72);
+}
+}
+for(_6c in this._pending._deletedItems){
+_72=this._pending._deletedItems[_6c];
+if(_72["backupRefs_"+this._reverseRefMap]){
+dojo.forEach(_72["backupRefs_"+this._reverseRefMap],function(_74){
+var _75;
+if(this._itemsByIdentity){
+_75=this._itemsByIdentity[_74.id];
+}else{
+_75=this._arrayOfAllItems[_74.id];
+}
+this._addReferenceToMap(_75,_72,_74.attr);
+},this);
+delete _72["backupRefs_"+this._reverseRefMap];
+}
+}
+for(_6c in this._pending._newItems){
+var _76=this._pending._newItems[_6c];
+_76[this._storeRefPropName]=null;
+this._arrayOfAllItems[_76[this._itemNumPropName]]=null;
+if(_76[this._rootItemPropName]){
+this._removeArrayElement(this._arrayOfTopLevelItems,_76);
+}
+if(this._itemsByIdentity){
+delete this._itemsByIdentity[_6c];
+}
+}
+this._pending={_newItems:{},_modifiedItems:{},_deletedItems:{}};
+return true;
+},isDirty:function(_77){
+if(_77){
+var _78=this.getIdentity(_77);
+return new Boolean(this._pending._newItems[_78]||this._pending._modifiedItems[_78]||this._pending._deletedItems[_78]).valueOf();
+}else{
+if(!this._isEmpty(this._pending._newItems)||!this._isEmpty(this._pending._modifiedItems)||!this._isEmpty(this._pending._deletedItems)){
+return true;
+}
+return false;
+}
+},onSet:function(_79,_7a,_7b,_7c){
+},onNew:function(_7d,_7e){
+},onDelete:function(_7f){
+},close:function(_80){
+if(this.clearOnClose){
+if(!this.isDirty()){
+this.inherited(arguments);
+}else{
+if(this._jsonFileUrl!==""){
+throw new Error("dojox.data.AndOrWriteStore: There are unsaved changes present in the store.  Please save or revert the changes before invoking close.");
+}
+}
+}
+}});
+}
diff --git a/dojox/data/AppStore.js b/dojox/data/AppStore.js
new file mode 100644
index 0000000..6416d77
--- /dev/null
+++ b/dojox/data/AppStore.js
@@ -0,0 +1,550 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.AppStore"]){
+dojo._hasResource["dojox.data.AppStore"]=true;
+dojo.provide("dojox.data.AppStore");
+dojo.require("dojox.atom.io.Connection");
+dojo.require("dojo.data.util.simpleFetch");
+dojo.require("dojo.data.util.filter");
+dojo.experimental("dojox.data.AppStore");
+dojo.declare("dojox.data.AppStore",null,{url:"",urlPreventCache:false,xmethod:false,_atomIO:null,_feed:null,_requests:null,_processing:null,_updates:null,_adds:null,_deletes:null,constructor:function(_1){
+if(_1&&_1.url){
+this.url=_1.url;
+}
+if(_1&&_1.urlPreventCache){
+this.urlPreventCache=_1.urlPreventCache;
+}
+if(!this.url){
+throw new Error("A URL is required to instantiate an APP Store object");
+}
+},_setFeed:function(_2,_3){
+this._feed=_2;
+var i;
+for(i=0;i<this._feed.entries.length;i++){
+this._feed.entries[i].store=this;
+}
+if(this._requests){
+for(i=0;i<this._requests.length;i++){
+var _5=this._requests[i];
+if(_5.request&&_5.fh&&_5.eh){
+this._finishFetchItems(_5.request,_5.fh,_5.eh);
+}else{
+if(_5.clear){
+this._feed=null;
+}else{
+if(_5.add){
+this._feed.addEntry(_5.add);
+}else{
+if(_5.remove){
+this._feed.removeEntry(_5.remove);
+}
+}
+}
+}
+}
+}
+this._requests=null;
+},_getAllItems:function(){
+var _6=[];
+for(var i=0;i<this._feed.entries.length;i++){
+_6.push(this._feed.entries[i]);
+}
+return _6;
+},_assertIsItem:function(_8){
+if(!this.isItem(_8)){
+throw new Error("This error message is provided when a function is called in the following form: "+"getAttribute(argument, attributeName).  The argument variable represents the member "+"or owner of the object. The error is created when an item that does not belong "+"to this store is specified as an argument.");
+}
+},_assertIsAttribute:function(_9){
+if(typeof _9!=="string"){
+throw new Error("The attribute argument must be a string. The error is created "+"when a different type of variable is specified such as an array or object.");
+}
+for(var _a in dojox.atom.io.model._actions){
+if(_a==_9){
+return true;
+}
+}
+return false;
+},_addUpdate:function(_b){
+if(!this._updates){
+this._updates=[_b];
+}else{
+this._updates.push(_b);
+}
+},getValue:function(_c,_d,_e){
+var _f=this.getValues(_c,_d);
+return (_f.length>0)?_f[0]:_e;
+},getValues:function(_10,_11){
+this._assertIsItem(_10);
+var _12=this._assertIsAttribute(_11);
+if(_12){
+if((_11==="author"||_11==="contributor"||_11==="link")&&_10[_11+"s"]){
+return _10[_11+"s"];
+}
+if(_11==="category"&&_10.categories){
+return _10.categories;
+}
+if(_10[_11]){
+_10=_10[_11];
+if(_10.declaredClass=="dojox.atom.io.model.Content"){
+return [_10.value];
+}
+return [_10];
+}
+}
+return [];
+},getAttributes:function(_13){
+this._assertIsItem(_13);
+var _14=[];
+for(var key in dojox.atom.io.model._actions){
+if(this.hasAttribute(_13,key)){
+_14.push(key);
+}
+}
+return _14;
+},hasAttribute:function(_16,_17){
+return this.getValues(_16,_17).length>0;
+},containsValue:function(_18,_19,_1a){
+var _1b=undefined;
+if(typeof _1a==="string"){
+_1b=dojo.data.util.filter.patternToRegExp(_1a,false);
+}
+return this._containsValue(_18,_19,_1a,_1b);
+},_containsValue:function(_1c,_1d,_1e,_1f,_20){
+var _21=this.getValues(_1c,_1d);
+for(var i=0;i<_21.length;++i){
+var _23=_21[i];
+if(typeof _23==="string"&&_1f){
+if(_20){
+_23=_23.replace(new RegExp(/^\s+/),"");
+_23=_23.replace(new RegExp(/\s+$/),"");
+}
+_23=_23.replace(/\r|\n|\r\n/g,"");
+return (_23.match(_1f)!==null);
+}else{
+if(_1e===_23){
+return true;
+}
+}
+}
+return false;
+},isItem:function(_24){
+return _24&&_24.store&&_24.store===this;
+},isItemLoaded:function(_25){
+return this.isItem(_25);
+},loadItem:function(_26){
+this._assertIsItem(_26.item);
+},_fetchItems:function(_27,_28,_29){
+if(this._feed){
+this._finishFetchItems(_27,_28,_29);
+}else{
+var _2a=false;
+if(!this._requests){
+this._requests=[];
+_2a=true;
+}
+this._requests.push({request:_27,fh:_28,eh:_29});
+if(_2a){
+this._atomIO=new dojox.atom.io.Connection(false,this.urlPreventCache);
+this._atomIO.getFeed(this.url,this._setFeed,null,this);
+}
+}
+},_finishFetchItems:function(_2b,_2c,_2d){
+var _2e=null;
+var _2f=this._getAllItems();
+if(_2b.query){
+var _30=_2b.queryOptions?_2b.queryOptions.ignoreCase:false;
+_2e=[];
+var _31={};
+var key;
+var _33;
+for(key in _2b.query){
+_33=_2b.query[key]+"";
+if(typeof _33==="string"){
+_31[key]=dojo.data.util.filter.patternToRegExp(_33,_30);
+}
+}
+for(var i=0;i<_2f.length;++i){
+var _35=true;
+var _36=_2f[i];
+for(key in _2b.query){
+_33=_2b.query[key]+"";
+if(!this._containsValue(_36,key,_33,_31[key],_2b.trim)){
+_35=false;
+}
+}
+if(_35){
+_2e.push(_36);
+}
+}
+}else{
+if(_2f.length>0){
+_2e=_2f.slice(0,_2f.length);
+}
+}
+try{
+_2c(_2e,_2b);
+}
+catch(e){
+_2d(e,_2b);
+}
+},getFeatures:function(){
+return {"dojo.data.api.Read":true,"dojo.data.api.Write":true,"dojo.data.api.Identity":true};
+},close:function(_37){
+this._feed=null;
+},getLabel:function(_38){
+if(this.isItem(_38)){
+return this.getValue(_38,"title","No Title");
+}
+return undefined;
+},getLabelAttributes:function(_39){
+return ["title"];
+},getIdentity:function(_3a){
+this._assertIsItem(_3a);
+return this.getValue(_3a,"id");
+},getIdentityAttributes:function(_3b){
+return ["id"];
+},fetchItemByIdentity:function(_3c){
+this._fetchItems({query:{id:_3c.identity},onItem:_3c.onItem,scope:_3c.scope},function(_3d,_3e){
+var _3f=_3e.scope;
+if(!_3f){
+_3f=dojo.global;
+}
+if(_3d.length<1){
+_3e.onItem.call(_3f,null);
+}else{
+_3e.onItem.call(_3f,_3d[0]);
+}
+},_3c.onError);
+},newItem:function(_40){
+var _41=new dojox.atom.io.model.Entry();
+var _42=null;
+var _43=null;
+var i;
+for(var key in _40){
+if(this._assertIsAttribute(key)){
+_42=_40[key];
+switch(key){
+case "link":
+for(i in _42){
+_43=_42[i];
+_41.addLink(_43.href,_43.rel,_43.hrefLang,_43.title,_43.type);
+}
+break;
+case "author":
+for(i in _42){
+_43=_42[i];
+_41.addAuthor(_43.name,_43.email,_43.uri);
+}
+break;
+case "contributor":
+for(i in _42){
+_43=_42[i];
+_41.addContributor(_43.name,_43.email,_43.uri);
+}
+break;
+case "category":
+for(i in _42){
+_43=_42[i];
+_41.addCategory(_43.scheme,_43.term,_43.label);
+}
+break;
+case "icon":
+case "id":
+case "logo":
+case "xmlBase":
+case "rights":
+_41[key]=_42;
+break;
+case "updated":
+case "published":
+case "issued":
+case "modified":
+_41[key]=dojox.atom.io.model.util.createDate(_42);
+break;
+case "content":
+case "summary":
+case "title":
+case "subtitle":
+_41[key]=new dojox.atom.io.model.Content(key);
+_41[key].value=_42;
+break;
+default:
+_41[key]=_42;
+break;
+}
+}
+}
+_41.store=this;
+_41.isDirty=true;
+if(!this._adds){
+this._adds=[_41];
+}else{
+this._adds.push(_41);
+}
+if(this._feed){
+this._feed.addEntry(_41);
+}else{
+if(this._requests){
+this._requests.push({add:_41});
+}else{
+this._requests=[{add:_41}];
+this._atomIO=new dojox.atom.io.Connection(false,this.urlPreventCache);
+this._atomIO.getFeed(this.url,dojo.hitch(this,this._setFeed));
+}
+}
+return true;
+},deleteItem:function(_46){
+this._assertIsItem(_46);
+if(!this._deletes){
+this._deletes=[_46];
+}else{
+this._deletes.push(_46);
+}
+if(this._feed){
+this._feed.removeEntry(_46);
+}else{
+if(this._requests){
+this._requests.push({remove:_46});
+}else{
+this._requests=[{remove:_46}];
+this._atomIO=new dojox.atom.io.Connection(false,this.urlPreventCache);
+this._atomIO.getFeed(this.url,dojo.hitch(this,this._setFeed));
+}
+}
+_46=null;
+return true;
+},setValue:function(_47,_48,_49){
+this._assertIsItem(_47);
+var _4a={item:_47};
+if(this._assertIsAttribute(_48)){
+switch(_48){
+case "link":
+_4a.links=_47.links;
+this._addUpdate(_4a);
+_47.links=null;
+_47.addLink(_49.href,_49.rel,_49.hrefLang,_49.title,_49.type);
+_47.isDirty=true;
+return true;
+case "author":
+_4a.authors=_47.authors;
+this._addUpdate(_4a);
+_47.authors=null;
+_47.addAuthor(_49.name,_49.email,_49.uri);
+_47.isDirty=true;
+return true;
+case "contributor":
+_4a.contributors=_47.contributors;
+this._addUpdate(_4a);
+_47.contributors=null;
+_47.addContributor(_49.name,_49.email,_49.uri);
+_47.isDirty=true;
+return true;
+case "category":
+_4a.categories=_47.categories;
+this._addUpdate(_4a);
+_47.categories=null;
+_47.addCategory(_49.scheme,_49.term,_49.label);
+_47.isDirty=true;
+return true;
+case "icon":
+case "id":
+case "logo":
+case "xmlBase":
+case "rights":
+_4a[_48]=_47[_48];
+this._addUpdate(_4a);
+_47[_48]=_49;
+_47.isDirty=true;
+return true;
+case "updated":
+case "published":
+case "issued":
+case "modified":
+_4a[_48]=_47[_48];
+this._addUpdate(_4a);
+_47[_48]=dojox.atom.io.model.util.createDate(_49);
+_47.isDirty=true;
+return true;
+case "content":
+case "summary":
+case "title":
+case "subtitle":
+_4a[_48]=_47[_48];
+this._addUpdate(_4a);
+_47[_48]=new dojox.atom.io.model.Content(_48);
+_47[_48].value=_49;
+_47.isDirty=true;
+return true;
+default:
+_4a[_48]=_47[_48];
+this._addUpdate(_4a);
+_47[_48]=_49;
+_47.isDirty=true;
+return true;
+}
+}
+return false;
+},setValues:function(_4b,_4c,_4d){
+if(_4d.length===0){
+return this.unsetAttribute(_4b,_4c);
+}
+this._assertIsItem(_4b);
+var _4e={item:_4b};
+var _4f;
+var i;
+if(this._assertIsAttribute(_4c)){
+switch(_4c){
+case "link":
+_4e.links=_4b.links;
+_4b.links=null;
+for(i in _4d){
+_4f=_4d[i];
+_4b.addLink(_4f.href,_4f.rel,_4f.hrefLang,_4f.title,_4f.type);
+}
+_4b.isDirty=true;
+return true;
+case "author":
+_4e.authors=_4b.authors;
+_4b.authors=null;
+for(i in _4d){
+_4f=_4d[i];
+_4b.addAuthor(_4f.name,_4f.email,_4f.uri);
+}
+_4b.isDirty=true;
+return true;
+case "contributor":
+_4e.contributors=_4b.contributors;
+_4b.contributors=null;
+for(i in _4d){
+_4f=_4d[i];
+_4b.addContributor(_4f.name,_4f.email,_4f.uri);
+}
+_4b.isDirty=true;
+return true;
+case "categories":
+_4e.categories=_4b.categories;
+_4b.categories=null;
+for(i in _4d){
+_4f=_4d[i];
+_4b.addCategory(_4f.scheme,_4f.term,_4f.label);
+}
+_4b.isDirty=true;
+return true;
+case "icon":
+case "id":
+case "logo":
+case "xmlBase":
+case "rights":
+_4e[_4c]=_4b[_4c];
+_4b[_4c]=_4d[0];
+_4b.isDirty=true;
+return true;
+case "updated":
+case "published":
+case "issued":
+case "modified":
+_4e[_4c]=_4b[_4c];
+_4b[_4c]=dojox.atom.io.model.util.createDate(_4d[0]);
+_4b.isDirty=true;
+return true;
+case "content":
+case "summary":
+case "title":
+case "subtitle":
+_4e[_4c]=_4b[_4c];
+_4b[_4c]=new dojox.atom.io.model.Content(_4c);
+_4b[_4c].values[0]=_4d[0];
+_4b.isDirty=true;
+return true;
+default:
+_4e[_4c]=_4b[_4c];
+_4b[_4c]=_4d[0];
+_4b.isDirty=true;
+return true;
+}
+}
+this._addUpdate(_4e);
+return false;
+},unsetAttribute:function(_51,_52){
+this._assertIsItem(_51);
+if(this._assertIsAttribute(_52)){
+if(_51[_52]!==null){
+var _53={item:_51};
+switch(_52){
+case "author":
+case "contributor":
+case "link":
+_53[_52+"s"]=_51[_52+"s"];
+break;
+case "category":
+_53.categories=_51.categories;
+break;
+default:
+_53[_52]=_51[_52];
+break;
+}
+_51.isDirty=true;
+_51[_52]=null;
+this._addUpdate(_53);
+return true;
+}
+}
+return false;
+},save:function(_54){
+var i;
+for(i in this._adds){
+this._atomIO.addEntry(this._adds[i],null,function(){
+},_54.onError,false,_54.scope);
+}
+this._adds=null;
+for(i in this._updates){
+this._atomIO.updateEntry(this._updates[i].item,function(){
+},_54.onError,false,this.xmethod,_54.scope);
+}
+this._updates=null;
+for(i in this._deletes){
+this._atomIO.removeEntry(this._deletes[i],function(){
+},_54.onError,this.xmethod,_54.scope);
+}
+this._deletes=null;
+this._atomIO.getFeed(this.url,dojo.hitch(this,this._setFeed));
+if(_54.onComplete){
+var _56=_54.scope||dojo.global;
+_54.onComplete.call(_56);
+}
+},revert:function(){
+var i;
+for(i in this._adds){
+this._feed.removeEntry(this._adds[i]);
+}
+this._adds=null;
+var _58,_59,key;
+for(i in this._updates){
+_58=this._updates[i];
+_59=_58.item;
+for(key in _58){
+if(key!=="item"){
+_59[key]=_58[key];
+}
+}
+}
+this._updates=null;
+for(i in this._deletes){
+this._feed.addEntry(this._deletes[i]);
+}
+this._deletes=null;
+return true;
+},isDirty:function(_5b){
+if(_5b){
+this._assertIsItem(_5b);
+return _5b.isDirty?true:false;
+}
+return (this._adds!==null||this._updates!==null);
+}});
+dojo.extend(dojox.data.AppStore,dojo.data.util.simpleFetch);
+}
diff --git a/dojox/data/AtomReadStore.js b/dojox/data/AtomReadStore.js
new file mode 100644
index 0000000..1db2b95
--- /dev/null
+++ b/dojox/data/AtomReadStore.js
@@ -0,0 +1,339 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.AtomReadStore"]){
+dojo._hasResource["dojox.data.AtomReadStore"]=true;
+dojo.provide("dojox.data.AtomReadStore");
+dojo.require("dojo.data.util.simpleFetch");
+dojo.require("dojo.data.util.filter");
+dojo.require("dojo.date.stamp");
+dojo.experimental("dojox.data.AtomReadStore");
+dojo.declare("dojox.data.AtomReadStore",null,{constructor:function(_1){
+if(_1){
+this.url=_1.url;
+this.rewriteUrl=_1.rewriteUrl;
+this.label=_1.label||this.label;
+this.sendQuery=(_1.sendQuery||_1.sendquery||this.sendQuery);
+this.unescapeHTML=_1.unescapeHTML;
+}
+if(!this.url){
+throw new Error("AtomReadStore: a URL must be specified when creating the data store");
+}
+},url:"",label:"title",sendQuery:false,unescapeHTML:false,getValue:function(_2,_3,_4){
+this._assertIsItem(_2);
+this._assertIsAttribute(_3);
+this._initItem(_2);
+_3=_3.toLowerCase();
+if(!_2._attribs[_3]&&!_2._parsed){
+this._parseItem(_2);
+_2._parsed=true;
+}
+var _5=_2._attribs[_3];
+if(!_5&&_3=="summary"){
+var _6=this.getValue(_2,"content");
+var _7=new RegExp("/(<([^>]+)>)/g","i");
+var _8=_6.text.replace(_7,"");
+_5={text:_8.substring(0,Math.min(400,_8.length)),type:"text"};
+_2._attribs[_3]=_5;
+}
+if(_5&&this.unescapeHTML){
+if((_3=="content"||_3=="summary"||_3=="subtitle")&&!_2["_"+_3+"Escaped"]){
+_5.text=this._unescapeHTML(_5.text);
+_2["_"+_3+"Escaped"]=true;
+}
+}
+return _5?dojo.isArray(_5)?_5[0]:_5:_4;
+},getValues:function(_9,_a){
+this._assertIsItem(_9);
+this._assertIsAttribute(_a);
+this._initItem(_9);
+_a=_a.toLowerCase();
+if(!_9._attribs[_a]){
+this._parseItem(_9);
+}
+var _b=_9._attribs[_a];
+return _b?((_b.length!==undefined&&typeof (_b)!=="string")?_b:[_b]):undefined;
+},getAttributes:function(_c){
+this._assertIsItem(_c);
+if(!_c._attribs){
+this._initItem(_c);
+this._parseItem(_c);
+}
+var _d=[];
+for(var x in _c._attribs){
+_d.push(x);
+}
+return _d;
+},hasAttribute:function(_f,_10){
+return (this.getValue(_f,_10)!==undefined);
+},containsValue:function(_11,_12,_13){
+var _14=this.getValues(_11,_12);
+for(var i=0;i<_14.length;i++){
+if((typeof _13==="string")){
+if(_14[i].toString&&_14[i].toString()===_13){
+return true;
+}
+}else{
+if(_14[i]===_13){
+return true;
+}
+}
+}
+return false;
+},isItem:function(_16){
+if(_16&&_16.element&&_16.store&&_16.store===this){
+return true;
+}
+return false;
+},isItemLoaded:function(_17){
+return this.isItem(_17);
+},loadItem:function(_18){
+},getFeatures:function(){
+var _19={"dojo.data.api.Read":true};
+return _19;
+},getLabel:function(_1a){
+if((this.label!=="")&&this.isItem(_1a)){
+var _1b=this.getValue(_1a,this.label);
+if(_1b&&_1b.text){
+return _1b.text;
+}else{
+if(_1b){
+return _1b.toString();
+}else{
+return undefined;
+}
+}
+}
+return undefined;
+},getLabelAttributes:function(_1c){
+if(this.label!==""){
+return [this.label];
+}
+return null;
+},getFeedValue:function(_1d,_1e){
+var _1f=this.getFeedValues(_1d,_1e);
+if(dojo.isArray(_1f)){
+return _1f[0];
+}
+return _1f;
+},getFeedValues:function(_20,_21){
+if(!this.doc){
+return _21;
+}
+if(!this._feedMetaData){
+this._feedMetaData={element:this.doc.getElementsByTagName("feed")[0],store:this,_attribs:{}};
+this._parseItem(this._feedMetaData);
+}
+return this._feedMetaData._attribs[_20]||_21;
+},_initItem:function(_22){
+if(!_22._attribs){
+_22._attribs={};
+}
+},_fetchItems:function(_23,_24,_25){
+var url=this._getFetchUrl(_23);
+if(!url){
+_25(new Error("No URL specified."));
+return;
+}
+var _27=(!this.sendQuery?_23:null);
+var _28=this;
+var _29=function(_2a){
+_28.doc=_2a;
+var _2b=_28._getItems(_2a,_27);
+var _2c=_23.query;
+if(_2c){
+if(_2c.id){
+_2b=dojo.filter(_2b,function(_2d){
+return (_28.getValue(_2d,"id")==_2c.id);
+});
+}else{
+if(_2c.category){
+_2b=dojo.filter(_2b,function(_2e){
+var _2f=_28.getValues(_2e,"category");
+if(!_2f){
+return false;
+}
+return dojo.some(_2f,"return item.term=='"+_2c.category+"'");
+});
+}
+}
+}
+if(_2b&&_2b.length>0){
+_24(_2b,_23);
+}else{
+_24([],_23);
+}
+};
+if(this.doc){
+_29(this.doc);
+}else{
+var _30={url:url,handleAs:"xml"};
+var _31=dojo.xhrGet(_30);
+_31.addCallback(_29);
+_31.addErrback(function(_32){
+_25(_32,_23);
+});
+}
+},_getFetchUrl:function(_33){
+if(!this.sendQuery){
+return this.url;
+}
+var _34=_33.query;
+if(!_34){
+return this.url;
+}
+if(dojo.isString(_34)){
+return this.url+_34;
+}
+var _35="";
+for(var _36 in _34){
+var _37=_34[_36];
+if(_37){
+if(_35){
+_35+="&";
+}
+_35+=(_36+"="+_37);
+}
+}
+if(!_35){
+return this.url;
+}
+var _38=this.url;
+if(_38.indexOf("?")<0){
+_38+="?";
+}else{
+_38+="&";
+}
+return _38+_35;
+},_getItems:function(_39,_3a){
+if(this._items){
+return this._items;
+}
+var _3b=[];
+var _3c=[];
+if(_39.childNodes.length<1){
+this._items=_3b;
+
+return _3b;
+}
+var _3d=dojo.filter(_39.childNodes,"return item.tagName && item.tagName.toLowerCase() == 'feed'");
+var _3e=_3a.query;
+if(!_3d||_3d.length!=1){
+
+return _3b;
+}
+_3c=dojo.filter(_3d[0].childNodes,"return item.tagName && item.tagName.toLowerCase() == 'entry'");
+if(_3a.onBegin){
+_3a.onBegin(_3c.length,this.sendQuery?_3a:{});
+}
+for(var i=0;i<_3c.length;i++){
+var _40=_3c[i];
+if(_40.nodeType!=1){
+continue;
+}
+_3b.push(this._getItem(_40));
+}
+this._items=_3b;
+return _3b;
+},close:function(_41){
+},_getItem:function(_42){
+return {element:_42,store:this};
+},_parseItem:function(_43){
+var _44=_43._attribs;
+var _45=this;
+var _46,_47;
+function _48(_49){
+var txt=_49.textContent||_49.innerHTML||_49.innerXML;
+if(!txt&&_49.childNodes[0]){
+var _4b=_49.childNodes[0];
+if(_4b&&(_4b.nodeType==3||_4b.nodeType==4)){
+txt=_49.childNodes[0].nodeValue;
+}
+}
+return txt;
+};
+function _4c(_4d){
+return {text:_48(_4d),type:_4d.getAttribute("type")};
+};
+dojo.forEach(_43.element.childNodes,function(_4e){
+var _4f=_4e.tagName?_4e.tagName.toLowerCase():"";
+switch(_4f){
+case "title":
+_44[_4f]={text:_48(_4e),type:_4e.getAttribute("type")};
+break;
+case "subtitle":
+case "summary":
+case "content":
+_44[_4f]=_4c(_4e);
+break;
+case "author":
+var _50,_51;
+dojo.forEach(_4e.childNodes,function(_52){
+if(!_52.tagName){
+return;
+}
+switch(_52.tagName.toLowerCase()){
+case "name":
+_50=_52;
+break;
+case "uri":
+_51=_52;
+break;
+}
+});
+var _53={};
+if(_50&&_50.length==1){
+_53.name=_48(_50[0]);
+}
+if(_51&&_51.length==1){
+_53.uri=_48(_51[0]);
+}
+_44[_4f]=_53;
+break;
+case "id":
+_44[_4f]=_48(_4e);
+break;
+case "updated":
+_44[_4f]=dojo.date.stamp.fromISOString(_48(_4e));
+break;
+case "published":
+_44[_4f]=dojo.date.stamp.fromISOString(_48(_4e));
+break;
+case "category":
+if(!_44[_4f]){
+_44[_4f]=[];
+}
+_44[_4f].push({scheme:_4e.getAttribute("scheme"),term:_4e.getAttribute("term")});
+break;
+case "link":
+if(!_44[_4f]){
+_44[_4f]=[];
+}
+var _54={rel:_4e.getAttribute("rel"),href:_4e.getAttribute("href"),type:_4e.getAttribute("type")};
+_44[_4f].push(_54);
+if(_54.rel=="alternate"){
+_44["alternate"]=_54;
+}
+break;
+default:
+break;
+}
+});
+},_unescapeHTML:function(_55){
+_55=_55.replace(/’/m,"'").replace(/″/m,"\"").replace(/</m,">").replace(/>/m,"<").replace(/&/m,"&");
+return _55;
+},_assertIsItem:function(_56){
+if(!this.isItem(_56)){
+throw new Error("dojox.data.AtomReadStore: Invalid item argument.");
+}
+},_assertIsAttribute:function(_57){
+if(typeof _57!=="string"){
+throw new Error("dojox.data.AtomReadStore: Invalid attribute argument.");
+}
+}});
+dojo.extend(dojox.data.AtomReadStore,dojo.data.util.simpleFetch);
+}
diff --git a/dojox/data/ClientFilter.js b/dojox/data/ClientFilter.js
new file mode 100644
index 0000000..6de020b
--- /dev/null
+++ b/dojox/data/ClientFilter.js
@@ -0,0 +1,171 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.ClientFilter"]){
+dojo._hasResource["dojox.data.ClientFilter"]=true;
+dojo.provide("dojox.data.ClientFilter");
+dojo.require("dojo.data.util.filter");
+(function(){
+var cf;
+var _2=function(_3,_4,_5){
+return function(_6){
+_3._updates.push({create:_4&&_6,remove:_5&&_6});
+cf.onUpdate();
+};
+};
+cf=dojo.declare("dojox.data.ClientFilter",null,{constructor:function(){
+this.onSet=_2(this,true,true);
+this.onNew=_2(this,true,false);
+this.onDelete=_2(this,false,true);
+this._updates=[];
+this._fetchCache=[];
+},updateResultSet:function(_7,_8){
+if(this.isUpdateable(_8)){
+for(var i=_8._version||0;i<this._updates.length;i++){
+var _a=this._updates[i].create;
+var _b=this._updates[i].remove;
+if(_b){
+for(var j=0;j<_7.length;j++){
+if(_7[j]==_b){
+_7.splice(j--,1);
+var _d=true;
+}
+}
+}
+if(_a&&this.matchesQuery(_a,_8)&&dojo.indexOf(_7,_a)==-1){
+_7.push(_a);
+_d=true;
+}
+}
+if(_8.sort&&_d){
+_7.sort(this.makeComparator(_8.sort.concat()));
+}
+if(_8.count&&_d){
+_7.splice(_8.count,_7.length);
+}
+_8._version=this._updates.length;
+return _d?2:1;
+}
+return 0;
+},querySuperSet:function(_e,_f){
+if(_e.query==_f.query){
+return {};
+}
+if(!(_f.query instanceof Object&&(!_e.query||typeof _e.query=="object"))){
+return false;
+}
+var _10=dojo.mixin({},_f.query);
+for(var i in _e.query){
+if(_10[i]==_e.query[i]){
+delete _10[i];
+}else{
+if(!(typeof _e.query[i]=="string"&&dojo.data.util.filter.patternToRegExp(_e.query[i]).test(_10[i]))){
+return false;
+}
+}
+}
+return _10;
+},serverVersion:0,cachingFetch:function(_12){
+var _13=this;
+for(var i=0;i<this._fetchCache.length;i++){
+var _15=this._fetchCache[i];
+var _16=this.querySuperSet(_15,_12);
+if(_16!==false){
+var _17=_15._loading;
+if(!_17){
+_17=new dojo.Deferred();
+_17.callback(_15.cacheResults);
+}
+_17.addCallback(function(_18){
+_18=_13.clientSideFetch({query:_16,sort:_12.sort,start:_12.start,count:_12.count},_18);
+_17.fullLength=_18._fullLength;
+return _18;
+});
+}
+}
+if(!_17){
+var _19=dojo.mixin({},_12);
+var _1a=(_12.queryOptions||0).cache;
+if(_1a===undefined?this.cacheByDefault:_1a){
+if(_12.start||_12.count){
+delete _19.start;
+delete _19.count;
+_12.clientQuery=dojo.mixin(_12.clientQuery||{},{start:_12.start,count:_12.count});
+}
+_12=_19;
+this._fetchCache.push(_12);
+}
+_17=_12._loading=this._doQuery(_12);
+}
+var _1b=this.serverVersion;
+_17.addCallback(function(_1c){
+delete _12._loading;
+if(_1c){
+_12._version=_1b;
+_13.updateResultSet(_1c,_12);
+_12.cacheResults=_1c;
+}
+return _1c;
+});
+return _17;
+},isUpdateable:function(_1d){
+return typeof _1d.query=="object";
+},clientSideFetch:function(_1e,_1f){
+if(_1e.query){
+var _20=[];
+for(var i=0;i<_1f.length;i++){
+var _22=_1f[i];
+if(_22&&this.matchesQuery(_22,_1e)){
+_20.push(_1f[i]);
+}
+}
+}else{
+_20=_1e.sort?_1f.concat():_1f;
+}
+if(_1e.sort){
+_20.sort(this.makeComparator(_1e.sort.concat()));
+}
+return this.clientSidePaging(_1e,_20);
+},clientSidePaging:function(_23,_24){
+var _25=_23.start||0;
+var _26=(_25||_23.count)?_24.slice(_25,_25+(_23.count||_24.length)):_24;
+_26._fullLength=_24.length;
+return _26;
+},matchesQuery:function(_27,_28){
+var _29=_28.query;
+var _2a=_28.queryOptions&&_28.queryOptions.ignoreCase;
+for(var i in _29){
+var _2c=_29[i];
+var _2d=this.getValue(_27,i);
+if((typeof _2c=="string"&&(_2c.match(/[\*\.]/)||_2a))?!dojo.data.util.filter.patternToRegExp(_2c,_2a).test(_2d):_2d!=_2c){
+return false;
+}
+}
+return true;
+},makeComparator:function(_2e){
+var _2f=_2e.shift();
+if(!_2f){
+return function(){
+};
+}
+var _30=_2f.attribute;
+var _31=!!_2f.descending;
+var _32=this.makeComparator(_2e);
+var _33=this;
+return function(a,b){
+var av=_33.getValue(a,_30);
+var bv=_33.getValue(b,_30);
+if(av!=bv){
+return av<bv==_31?1:-1;
+}
+return _32(a,b);
+};
+}});
+cf.onUpdate=function(){
+};
+})();
+}
diff --git a/dojox/data/CouchDBRestStore.js b/dojox/data/CouchDBRestStore.js
new file mode 100644
index 0000000..24760cb
--- /dev/null
+++ b/dojox/data/CouchDBRestStore.js
@@ -0,0 +1,64 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.CouchDBRestStore"]){
+dojo._hasResource["dojox.data.CouchDBRestStore"]=true;
+dojo.provide("dojox.data.CouchDBRestStore");
+dojo.require("dojox.data.JsonRestStore");
+dojo.declare("dojox.data.CouchDBRestStore",dojox.data.JsonRestStore,{save:function(_1){
+var _2=this.inherited(arguments);
+var _3=this.service.servicePath;
+for(var i=0;i<_2.length;i++){
+(function(_5,_6){
+_6.addCallback(function(_7){
+if(_7){
+_5.__id=_3+_7.id;
+_5._rev=_7.rev;
+}
+return _7;
+});
+})(_2[i].content,_2[i].deferred);
+}
+},fetch:function(_8){
+_8.query=_8.query||"_all_docs?";
+if(_8.start){
+_8.query=(_8.query?(_8.query+"&"):"")+"startkey="+_8.start;
+delete _8.start;
+}
+if(_8.count){
+_8.query=(_8.query?(_8.query+"&"):"")+"count="+_8.count;
+delete _8.count;
+}
+return this.inherited(arguments);
+},_processResults:function(_9){
+var _a=_9.rows;
+if(_a){
+var _b=this.service.servicePath;
+var _c=this;
+for(var i=0;i<_a.length;i++){
+_a[i]={__id:_b+_a[i].id,_id:_a[i].id,_loadObject:function(_e){
+_c.fetchItemByIdentity({identity:this._id,onItem:_e});
+delete this._loadObject;
+}};
+}
+return {totalCount:_9.total_rows,items:_9.rows};
+}else{
+return {items:_9};
+}
+}});
+dojox.data.CouchDBRestStore.getStores=function(_f){
+var dfd=dojo.xhrGet({url:_f+"_all_dbs",handleAs:"json",sync:true});
+var _11={};
+dfd.addBoth(function(dbs){
+for(var i=0;i<dbs.length;i++){
+_11[dbs[i]]=new dojox.data.CouchDBRestStore({target:_f+dbs[i],idAttribute:"_id"});
+}
+return _11;
+});
+return _11;
+};
+}
diff --git a/dojox/data/CssClassStore.js b/dojox/data/CssClassStore.js
new file mode 100644
index 0000000..bd5c1cb
--- /dev/null
+++ b/dojox/data/CssClassStore.js
@@ -0,0 +1,104 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.CssClassStore"]){
+dojo._hasResource["dojox.data.CssClassStore"]=true;
+dojo.provide("dojox.data.CssClassStore");
+dojo.require("dojox.data.CssRuleStore");
+dojo.declare("dojox.data.CssClassStore",dojox.data.CssRuleStore,{_labelAttribute:"class",_idAttribute:"class",_cName:"dojox.data.CssClassStore",getFeatures:function(){
+return {"dojo.data.api.Read":true,"dojo.data.api.Identity":true};
+},getAttributes:function(_1){
+this._assertIsItem(_1);
+return ["class","classSans"];
+},getValue:function(_2,_3,_4){
+var _5=this.getValues(_2,_3);
+if(_5&&_5.length>0){
+return _5[0];
+}
+return _4;
+},getValues:function(_6,_7){
+this._assertIsItem(_6);
+this._assertIsAttribute(_7);
+var _8=[];
+if(_7==="class"){
+_8=[_6.className];
+}else{
+if(_7==="classSans"){
+_8=[_6.className.replace(/\./g,"")];
+}
+}
+return _8;
+},_handleRule:function(_9,_a,_b){
+var _c={};
+var s=_9["selectorText"].split(" ");
+for(var j=0;j<s.length;j++){
+var _f=s[j];
+var _10=_f.indexOf(".");
+if(_f&&_f.length>0&&_10!==-1){
+var _11=_f.indexOf(",")||_f.indexOf("[");
+_f=_f.substring(_10,((_11!==-1&&_11>_10)?_11:_f.length));
+_c[_f]=true;
+}
+}
+for(var key in _c){
+if(!this._allItems[key]){
+var _13={};
+_13.className=key;
+_13[this._storeRef]=this;
+this._allItems[key]=_13;
+}
+}
+},_handleReturn:function(){
+var _14=[];
+var _15={};
+for(var i in this._allItems){
+_15[i]=this._allItems[i];
+}
+var _17;
+while(this._pending.length){
+_17=this._pending.pop();
+_17.request._items=_15;
+_14.push(_17);
+}
+while(_14.length){
+_17=_14.pop();
+if(_17.fetch){
+this._handleFetchReturn(_17.request);
+}else{
+this._handleFetchByIdentityReturn(_17.request);
+}
+}
+},_handleFetchByIdentityReturn:function(_18){
+var _19=_18._items;
+var _1a=_19[(dojo.isWebKit?_18.identity.toLowerCase():_18.identity)];
+if(!this.isItem(_1a)){
+_1a=null;
+}
+if(_18.onItem){
+var _1b=_18.scope||dojo.global;
+_18.onItem.call(_1b,_1a);
+}
+},getIdentity:function(_1c){
+this._assertIsItem(_1c);
+return this.getValue(_1c,this._idAttribute);
+},getIdentityAttributes:function(_1d){
+this._assertIsItem(_1d);
+return [this._idAttribute];
+},fetchItemByIdentity:function(_1e){
+_1e=_1e||{};
+if(!_1e.store){
+_1e.store=this;
+}
+if(this._pending&&this._pending.length>0){
+this._pending.push({request:_1e});
+}else{
+this._pending=[{request:_1e}];
+this._fetch(_1e);
+}
+return _1e;
+}});
+}
diff --git a/dojox/data/CssRuleStore.js b/dojox/data/CssRuleStore.js
new file mode 100644
index 0000000..4daa93c
--- /dev/null
+++ b/dojox/data/CssRuleStore.js
@@ -0,0 +1,336 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.CssRuleStore"]){
+dojo._hasResource["dojox.data.CssRuleStore"]=true;
+dojo.provide("dojox.data.CssRuleStore");
+dojo.require("dojo.data.util.filter");
+dojo.require("dojo.data.util.sorter");
+dojo.require("dojox.data.css");
+dojo.declare("dojox.data.CssRuleStore",null,{_storeRef:"_S",_labelAttribute:"selector",_cache:null,_browserMap:null,_cName:"dojox.data.CssRuleStore",constructor:function(_1){
+if(_1){
+dojo.mixin(this,_1);
+}
+this._cache={};
+this._allItems=null;
+this._waiting=[];
+this.gatherHandle=null;
+var _2=this;
+function _3(){
+try{
+_2.context=dojox.data.css.determineContext(_2.context);
+if(_2.gatherHandle){
+clearInterval(_2.gatherHandle);
+_2.gatherHandle=null;
+}
+while(_2._waiting.length){
+var _4=_2._waiting.pop();
+dojox.data.css.rules.forEach(_4.forFunc,null,_2.context);
+_4.finishFunc();
+}
+}
+catch(e){
+}
+};
+this.gatherHandle=setInterval(_3,250);
+},setContext:function(_5){
+if(_5){
+this.close();
+this.context=dojox.data.css.determineContext(_5);
+}
+},getFeatures:function(){
+return {"dojo.data.api.Read":true};
+},isItem:function(_6){
+if(_6&&_6[this._storeRef]==this){
+return true;
+}
+return false;
+},hasAttribute:function(_7,_8){
+this._assertIsItem(_7);
+this._assertIsAttribute(_8);
+var _9=this.getAttributes(_7);
+if(dojo.indexOf(_9,_8)!=-1){
+return true;
+}
+return false;
+},getAttributes:function(_a){
+this._assertIsItem(_a);
+var _b=["selector","classes","rule","style","cssText","styleSheet","parentStyleSheet","parentStyleSheetHref"];
+var _c=_a.rule.style;
+if(_c){
+var _d;
+for(_d in _c){
+_b.push("style."+_d);
+}
+}
+return _b;
+},getValue:function(_e,_f,_10){
+var _11=this.getValues(_e,_f);
+var _12=_10;
+if(_11&&_11.length>0){
+return _11[0];
+}
+return _10;
+},getValues:function(_13,_14){
+this._assertIsItem(_13);
+this._assertIsAttribute(_14);
+var _15=null;
+if(_14==="selector"){
+_15=_13.rule["selectorText"];
+if(_15&&dojo.isString(_15)){
+_15=_15.split(",");
+}
+}else{
+if(_14==="classes"){
+_15=_13.classes;
+}else{
+if(_14==="rule"){
+_15=_13.rule.rule;
+}else{
+if(_14==="style"){
+_15=_13.rule.style;
+}else{
+if(_14==="cssText"){
+if(dojo.isIE){
+if(_13.rule.style){
+_15=_13.rule.style.cssText;
+if(_15){
+_15="{ "+_15.toLowerCase()+" }";
+}
+}
+}else{
+_15=_13.rule.cssText;
+if(_15){
+_15=_15.substring(_15.indexOf("{"),_15.length);
+}
+}
+}else{
+if(_14==="styleSheet"){
+_15=_13.rule.styleSheet;
+}else{
+if(_14==="parentStyleSheet"){
+_15=_13.rule.parentStyleSheet;
+}else{
+if(_14==="parentStyleSheetHref"){
+if(_13.href){
+_15=_13.href;
+}
+}else{
+if(_14.indexOf("style.")===0){
+var _16=_14.substring(_14.indexOf("."),_14.length);
+_15=_13.rule.style[_16];
+}else{
+_15=[];
+}
+}
+}
+}
+}
+}
+}
+}
+}
+if(_15!==undefined){
+if(!dojo.isArray(_15)){
+_15=[_15];
+}
+}
+return _15;
+},getLabel:function(_17){
+this._assertIsItem(_17);
+return this.getValue(_17,this._labelAttribute);
+},getLabelAttributes:function(_18){
+return [this._labelAttribute];
+},containsValue:function(_19,_1a,_1b){
+var _1c=undefined;
+if(typeof _1b==="string"){
+_1c=dojo.data.util.filter.patternToRegExp(_1b,false);
+}
+return this._containsValue(_19,_1a,_1b,_1c);
+},isItemLoaded:function(_1d){
+return this.isItem(_1d);
+},loadItem:function(_1e){
+this._assertIsItem(_1e.item);
+},fetch:function(_1f){
+_1f=_1f||{};
+if(!_1f.store){
+_1f.store=this;
+}
+var _20=_1f.scope||dojo.global;
+if(this._pending&&this._pending.length>0){
+this._pending.push({request:_1f,fetch:true});
+}else{
+this._pending=[{request:_1f,fetch:true}];
+this._fetch(_1f);
+}
+return _1f;
+},_fetch:function(_21){
+var _22=_21.scope||dojo.global;
+if(this._allItems===null){
+this._allItems={};
+try{
+if(this.gatherHandle){
+this._waiting.push({"forFunc":dojo.hitch(this,this._handleRule),"finishFunc":dojo.hitch(this,this._handleReturn)});
+}else{
+dojox.data.css.rules.forEach(dojo.hitch(this,this._handleRule),null,this.context);
+this._handleReturn();
+}
+}
+catch(e){
+if(_21.onError){
+_21.onError.call(_22,e,_21);
+}
+}
+}else{
+this._handleReturn();
+}
+},_handleRule:function(_23,_24,_25){
+var _26=_23["selectorText"];
+var s=_26.split(" ");
+var _28=[];
+for(var j=0;j<s.length;j++){
+var tmp=s[j];
+var _2b=tmp.indexOf(".");
+if(tmp&&tmp.length>0&&_2b!==-1){
+var _2c=tmp.indexOf(",")||tmp.indexOf("[");
+tmp=tmp.substring(_2b,((_2c!==-1&&_2c>_2b)?_2c:tmp.length));
+_28.push(tmp);
+}
+}
+var _2d={};
+_2d.rule=_23;
+_2d.styleSheet=_24;
+_2d.href=_25;
+_2d.classes=_28;
+_2d[this._storeRef]=this;
+if(!this._allItems[_26]){
+this._allItems[_26]=[];
+}
+this._allItems[_26].push(_2d);
+},_handleReturn:function(){
+var _2e=[];
+var _2f=[];
+var _30=null;
+for(var i in this._allItems){
+_30=this._allItems[i];
+for(var j in _30){
+_2f.push(_30[j]);
+}
+}
+var _33;
+while(this._pending.length){
+_33=this._pending.pop();
+_33.request._items=_2f;
+_2e.push(_33);
+}
+while(_2e.length){
+_33=_2e.pop();
+this._handleFetchReturn(_33.request);
+}
+},_handleFetchReturn:function(_34){
+var _35=_34.scope||dojo.global;
+var _36=[];
+var _37="all";
+var i;
+if(_34.query){
+_37=dojo.toJson(_34.query);
+}
+if(this._cache[_37]){
+_36=this._cache[_37];
+}else{
+if(_34.query){
+for(i in _34._items){
+var _39=_34._items[i];
+var _3a=dojo.isWebKit?true:(_34.queryOptions?_34.queryOptions.ignoreCase:false);
+var _3b={};
+var key;
+var _3d;
+for(key in _34.query){
+_3d=_34.query[key];
+if(typeof _3d==="string"){
+_3b[key]=dojo.data.util.filter.patternToRegExp(_3d,_3a);
+}
+}
+var _3e=true;
+for(key in _34.query){
+_3d=_34.query[key];
+if(!this._containsValue(_39,key,_3d,_3b[key])){
+_3e=false;
+}
+}
+if(_3e){
+_36.push(_39);
+}
+}
+this._cache[_37]=_36;
+}else{
+for(i in _34._items){
+_36.push(_34._items[i]);
+}
+}
+}
+var _3f=_36.length;
+if(_34.sort){
+_36.sort(dojo.data.util.sorter.createSortFunction(_34.sort,this));
+}
+var _40=0;
+var _41=_36.length;
+if(_34.start>0&&_34.start<_36.length){
+_40=_34.start;
+}
+if(_34.count&&_34.count){
+_41=_34.count;
+}
+var _42=_40+_41;
+if(_42>_36.length){
+_42=_36.length;
+}
+_36=_36.slice(_40,_42);
+if(_34.onBegin){
+_34.onBegin.call(_35,_3f,_34);
+}
+if(_34.onItem){
+if(dojo.isArray(_36)){
+for(i=0;i<_36.length;i++){
+_34.onItem.call(_35,_36[i],_34);
+}
+if(_34.onComplete){
+_34.onComplete.call(_35,null,_34);
+}
+}
+}else{
+if(_34.onComplete){
+_34.onComplete.call(_35,_36,_34);
+}
+}
+return _34;
+},close:function(){
+this._cache={};
+this._allItems=null;
+},_assertIsItem:function(_43){
+if(!this.isItem(_43)){
+throw new Error(this._cName+": Invalid item argument.");
+}
+},_assertIsAttribute:function(_44){
+if(typeof _44!=="string"){
+throw new Error(this._cName+": Invalid attribute argument.");
+}
+},_containsValue:function(_45,_46,_47,_48){
+return dojo.some(this.getValues(_45,_46),function(_49){
+if(_49!==null&&!dojo.isObject(_49)&&_48){
+if(_49.toString().match(_48)){
+return true;
+}
+}else{
+if(_47===_49){
+return true;
+}
+}
+return false;
+});
+}});
+}
diff --git a/dojox/data/CsvStore.js b/dojox/data/CsvStore.js
new file mode 100644
index 0000000..5e8456b
--- /dev/null
+++ b/dojox/data/CsvStore.js
@@ -0,0 +1,424 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.CsvStore"]){
+dojo._hasResource["dojox.data.CsvStore"]=true;
+dojo.provide("dojox.data.CsvStore");
+dojo.require("dojo.data.util.filter");
+dojo.require("dojo.data.util.simpleFetch");
+dojo.declare("dojox.data.CsvStore",null,{constructor:function(_1){
+this._attributes=[];
+this._attributeIndexes={};
+this._dataArray=[];
+this._arrayOfAllItems=[];
+this._loadFinished=false;
+if(_1.url){
+this.url=_1.url;
+}
+this._csvData=_1.data;
+if(_1.label){
+this.label=_1.label;
+}else{
+if(this.label===""){
+this.label=undefined;
+}
+}
+this._storeProp="_csvStore";
+this._idProp="_csvId";
+this._features={"dojo.data.api.Read":true,"dojo.data.api.Identity":true};
+this._loadInProgress=false;
+this._queuedFetches=[];
+this.identifier=_1.identifier;
+if(this.identifier===""){
+delete this.identifier;
+}else{
+this._idMap={};
+}
+},url:"",label:"",identifier:"",_assertIsItem:function(_2){
+if(!this.isItem(_2)){
+throw new Error(this.declaredClass+": a function was passed an item argument that was not an item");
+}
+},_assertIsAttribute:function(_3){
+if(!dojo.isString(_3)){
+throw new Error(this.declaredClass+": a function was passed an attribute argument that was not an attribute object nor an attribute name string");
+}
+},_getIndex:function(_4){
+var _5=this.getIdentity(_4);
+if(this.identifier){
+_5=this._idMap[_5];
+}
+return _5;
+},getValue:function(_6,_7,_8){
+this._assertIsItem(_6);
+this._assertIsAttribute(_7);
+var _9=_8;
+if(this.hasAttribute(_6,_7)){
+var _a=this._dataArray[this._getIndex(_6)];
+_9=_a[this._attributeIndexes[_7]];
+}
+return _9;
+},getValues:function(_b,_c){
+var _d=this.getValue(_b,_c);
+return (_d?[_d]:[]);
+},getAttributes:function(_e){
+this._assertIsItem(_e);
+var _f=[];
+var _10=this._dataArray[this._getIndex(_e)];
+for(var i=0;i<_10.length;i++){
+if(_10[i]!==""){
+_f.push(this._attributes[i]);
+}
+}
+return _f;
+},hasAttribute:function(_12,_13){
+this._assertIsItem(_12);
+this._assertIsAttribute(_13);
+var _14=this._attributeIndexes[_13];
+var _15=this._dataArray[this._getIndex(_12)];
+return (typeof _14!=="undefined"&&_14<_15.length&&_15[_14]!=="");
+},containsValue:function(_16,_17,_18){
+var _19=undefined;
+if(typeof _18==="string"){
+_19=dojo.data.util.filter.patternToRegExp(_18,false);
+}
+return this._containsValue(_16,_17,_18,_19);
+},_containsValue:function(_1a,_1b,_1c,_1d){
+var _1e=this.getValues(_1a,_1b);
+for(var i=0;i<_1e.length;++i){
+var _20=_1e[i];
+if(typeof _20==="string"&&_1d){
+return (_20.match(_1d)!==null);
+}else{
+if(_1c===_20){
+return true;
+}
+}
+}
+return false;
+},isItem:function(_21){
+if(_21&&_21[this._storeProp]===this){
+var _22=_21[this._idProp];
+if(this.identifier){
+var _23=this._dataArray[this._idMap[_22]];
+if(_23){
+return true;
+}
+}else{
+if(_22>=0&&_22<this._dataArray.length){
+return true;
+}
+}
+}
+return false;
+},isItemLoaded:function(_24){
+return this.isItem(_24);
+},loadItem:function(_25){
+},getFeatures:function(){
+return this._features;
+},getLabel:function(_26){
+if(this.label&&this.isItem(_26)){
+return this.getValue(_26,this.label);
+}
+return undefined;
+},getLabelAttributes:function(_27){
+if(this.label){
+return [this.label];
+}
+return null;
+},_fetchItems:function(_28,_29,_2a){
+var _2b=this;
+var _2c=function(_2d,_2e){
+var _2f=null;
+if(_2d.query){
+var key,_31;
+_2f=[];
+var _32=_2d.queryOptions?_2d.queryOptions.ignoreCase:false;
+var _33={};
+for(key in _2d.query){
+_31=_2d.query[key];
+if(typeof _31==="string"){
+_33[key]=dojo.data.util.filter.patternToRegExp(_31,_32);
+}
+}
+for(var i=0;i<_2e.length;++i){
+var _35=true;
+var _36=_2e[i];
+for(key in _2d.query){
+_31=_2d.query[key];
+if(!_2b._containsValue(_36,key,_31,_33[key])){
+_35=false;
+}
+}
+if(_35){
+_2f.push(_36);
+}
+}
+}else{
+if(_2e.length>0){
+_2f=_2e.slice(0,_2e.length);
+}
+}
+_29(_2f,_2d);
+};
+if(this._loadFinished){
+_2c(_28,this._arrayOfAllItems);
+}else{
+if(this.url!==""){
+if(this._loadInProgress){
+this._queuedFetches.push({args:_28,filter:_2c});
+}else{
+this._loadInProgress=true;
+var _37={url:_2b.url,handleAs:"text"};
+var _38=dojo.xhrGet(_37);
+_38.addCallback(function(_39){
+try{
+_2b._processData(_39);
+_2c(_28,_2b._arrayOfAllItems);
+_2b._handleQueuedFetches();
+}
+catch(e){
+_2a(e,_28);
+}
+});
+_38.addErrback(function(_3a){
+_2b._loadInProgress=false;
+if(_2a){
+_2a(_3a,_28);
+}else{
+throw _3a;
+}
+});
+}
+}else{
+if(this._csvData){
+try{
+this._processData(this._csvData);
+this._csvData=null;
+_2c(_28,this._arrayOfAllItems);
+}
+catch(e){
+_2a(e,_28);
+}
+}else{
+var _3b=new Error(this.declaredClass+": No CSV source data was provided as either URL or String data input.");
+if(_2a){
+_2a(_3b,_28);
+}else{
+throw _3b;
+}
+}
+}
+}
+},close:function(_3c){
+},_getArrayOfArraysFromCsvFileContents:function(_3d){
+if(dojo.isString(_3d)){
+var _3e=new RegExp("\r\n|\n|\r");
+var _3f=new RegExp("^\\s+","g");
+var _40=new RegExp("\\s+$","g");
+var _41=new RegExp("\"\"","g");
+var _42=[];
+var i;
+var _44=this._splitLines(_3d);
+for(i=0;i<_44.length;++i){
+var _45=_44[i];
+if(_45.length>0){
+var _46=_45.split(",");
+var j=0;
+while(j<_46.length){
+var _48=_46[j];
+var _49=_48.replace(_3f,"");
+var _4a=_49.replace(_40,"");
+var _4b=_4a.charAt(0);
+var _4c=_4a.charAt(_4a.length-1);
+var _4d=_4a.charAt(_4a.length-2);
+var _4e=_4a.charAt(_4a.length-3);
+if(_4a.length===2&&_4a=="\"\""){
+_46[j]="";
+}else{
+if((_4b=="\"")&&((_4c!="\"")||((_4c=="\"")&&(_4d=="\"")&&(_4e!="\"")))){
+if(j+1===_46.length){
+return null;
+}
+var _4f=_46[j+1];
+_46[j]=_49+","+_4f;
+_46.splice(j+1,1);
+}else{
+if((_4b=="\"")&&(_4c=="\"")){
+_4a=_4a.slice(1,(_4a.length-1));
+_4a=_4a.replace(_41,"\"");
+}
+_46[j]=_4a;
+j+=1;
+}
+}
+}
+_42.push(_46);
+}
+}
+this._attributes=_42.shift();
+for(i=0;i<this._attributes.length;i++){
+this._attributeIndexes[this._attributes[i]]=i;
+}
+this._dataArray=_42;
+}
+},_splitLines:function(_50){
+var _51=[];
+var i;
+var _53="";
+var _54=false;
+for(i=0;i<_50.length;i++){
+var c=_50.charAt(i);
+switch(c){
+case "\"":
+_54=!_54;
+_53+=c;
+break;
+case "\r":
+if(_54){
+_53+=c;
+}else{
+_51.push(_53);
+_53="";
+if(i<(_50.length-1)&&_50.charAt(i+1)=="\n"){
+i++;
+}
+}
+break;
+case "\n":
+if(_54){
+_53+=c;
+}else{
+_51.push(_53);
+_53="";
+}
+break;
+default:
+_53+=c;
+}
+}
+if(_53!==""){
+_51.push(_53);
+}
+return _51;
+},_processData:function(_56){
+this._getArrayOfArraysFromCsvFileContents(_56);
+this._arrayOfAllItems=[];
+if(this.identifier){
+if(this._attributeIndexes[this.identifier]===undefined){
+throw new Error(this.declaredClass+": Identity specified is not a column header in the data set.");
+}
+}
+for(var i=0;i<this._dataArray.length;i++){
+var id=i;
+if(this.identifier){
+var _59=this._dataArray[i];
+id=_59[this._attributeIndexes[this.identifier]];
+this._idMap[id]=i;
+}
+this._arrayOfAllItems.push(this._createItemFromIdentity(id));
+}
+this._loadFinished=true;
+this._loadInProgress=false;
+},_createItemFromIdentity:function(_5a){
+var _5b={};
+_5b[this._storeProp]=this;
+_5b[this._idProp]=_5a;
+return _5b;
+},getIdentity:function(_5c){
+if(this.isItem(_5c)){
+return _5c[this._idProp];
+}
+return null;
+},fetchItemByIdentity:function(_5d){
+var _5e;
+var _5f=_5d.scope?_5d.scope:dojo.global;
+if(!this._loadFinished){
+var _60=this;
+if(this.url!==""){
+if(this._loadInProgress){
+this._queuedFetches.push({args:_5d});
+}else{
+this._loadInProgress=true;
+var _61={url:_60.url,handleAs:"text"};
+var _62=dojo.xhrGet(_61);
+_62.addCallback(function(_63){
+try{
+_60._processData(_63);
+var _64=_60._createItemFromIdentity(_5d.identity);
+if(!_60.isItem(_64)){
+_64=null;
+}
+if(_5d.onItem){
+_5d.onItem.call(_5f,_64);
+}
+_60._handleQueuedFetches();
+}
+catch(error){
+if(_5d.onError){
+_5d.onError.call(_5f,error);
+}
+}
+});
+_62.addErrback(function(_65){
+this._loadInProgress=false;
+if(_5d.onError){
+_5d.onError.call(_5f,_65);
+}
+});
+}
+}else{
+if(this._csvData){
+try{
+_60._processData(_60._csvData);
+_60._csvData=null;
+_5e=_60._createItemFromIdentity(_5d.identity);
+if(!_60.isItem(_5e)){
+_5e=null;
+}
+if(_5d.onItem){
+_5d.onItem.call(_5f,_5e);
+}
+}
+catch(e){
+if(_5d.onError){
+_5d.onError.call(_5f,e);
+}
+}
+}
+}
+}else{
+_5e=this._createItemFromIdentity(_5d.identity);
+if(!this.isItem(_5e)){
+_5e=null;
+}
+if(_5d.onItem){
+_5d.onItem.call(_5f,_5e);
+}
+}
+},getIdentityAttributes:function(_66){
+if(this.identifier){
+return [this.identifier];
+}else{
+return null;
+}
+},_handleQueuedFetches:function(){
+if(this._queuedFetches.length>0){
+for(var i=0;i<this._queuedFetches.length;i++){
+var _68=this._queuedFetches[i];
+var _69=_68.filter;
+var _6a=_68.args;
+if(_69){
+_69(_6a,this._arrayOfAllItems);
+}else{
+this.fetchItemByIdentity(_68.args);
+}
+}
+this._queuedFetches=[];
+}
+}});
+dojo.extend(dojox.data.CsvStore,dojo.data.util.simpleFetch);
+}
diff --git a/dojox/data/FileStore.js b/dojox/data/FileStore.js
new file mode 100644
index 0000000..e2e1733
--- /dev/null
+++ b/dojox/data/FileStore.js
@@ -0,0 +1,239 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.FileStore"]){
+dojo._hasResource["dojox.data.FileStore"]=true;
+dojo.provide("dojox.data.FileStore");
+dojo.declare("dojox.data.FileStore",null,{constructor:function(_1){
+if(_1&&_1.label){
+this.label=_1.label;
+}
+if(_1&&_1.url){
+this.url=_1.url;
+}
+if(_1&&_1.options){
+if(dojo.isArray(_1.options)){
+this.options=_1.options;
+}else{
+if(dojo.isString(_1.options)){
+this.options=_1.options.split(",");
+}
+}
+}
+if(_1&&_1.pathAsQueryParam){
+this.pathAsQueryParam=true;
+}
+},url:"",_storeRef:"_S",label:"name",_identifier:"path",_attributes:["children","directory","name","path","modified","size","parentDir"],pathSeparator:"/",options:[],_assertIsItem:function(_2){
+if(!this.isItem(_2)){
+throw new Error("dojox.data.FileStore: a function was passed an item argument that was not an item");
+}
+},_assertIsAttribute:function(_3){
+if(typeof _3!=="string"){
+throw new Error("dojox.data.FileStore: a function was passed an attribute argument that was not an attribute name string");
+}
+},pathAsQueryParam:false,getFeatures:function(){
+return {"dojo.data.api.Read":true,"dojo.data.api.Identity":true};
+},getValue:function(_4,_5,_6){
+var _7=this.getValues(_4,_5);
+var _8=_6;
+if(_7&&_7.length>0){
+_8=_7[0];
+}
+return _8;
+},getAttributes:function(_9){
+return this._attributes;
+},hasAttribute:function(_a,_b){
+if(this.getValue(_a,_b)){
+return true;
+}
+return false;
+},getIdentity:function(_c){
+return this.getValue(_c,this._identifier);
+},getIdentityAttributes:function(_d){
+return [this._identifier];
+},isItemLoaded:function(_e){
+var _f=this.isItem(_e);
+if(_f&&typeof _e._loaded=="boolean"&&!_e._loaded){
+_f=false;
+}
+return _f;
+},loadItem:function(_10){
+var _11=_10.item;
+var _12=this;
+var _13=_10.scope||dojo.global;
+var _14={};
+if(this.options.length>0){
+_14.options=dojo.toJson(this.options);
+}
+if(this.pathAsQueryParam){
+_14.path=_11.parentPath+this.pathSeparator+_11.name;
+}
+var _15={url:this.pathAsQueryParam?this.url:this.url+"/"+_11.parentPath+"/"+_11.name,handleAs:"json-comment-optional",content:_14,preventCache:true};
+var _16=dojo.xhrGet(_15);
+_16.addErrback(function(_17){
+if(_10.onError){
+_10.onError.call(_13,_17);
+}
+});
+_16.addCallback(function(_18){
+delete _11.parentPath;
+delete _11._loaded;
+dojo.mixin(_11,_18);
+_12._processItem(_11);
+if(_10.onItem){
+_10.onItem.call(_13,_11);
+}
+});
+},getLabel:function(_19){
+return this.getValue(_19,this.label);
+},getLabelAttributes:function(_1a){
+return [this.label];
+},containsValue:function(_1b,_1c,_1d){
+var _1e=this.getValues(_1b,_1c);
+for(var i=0;i<_1e.length;i++){
+if(_1e[i]==_1d){
+return true;
+}
+}
+return false;
+},getValues:function(_20,_21){
+this._assertIsItem(_20);
+this._assertIsAttribute(_21);
+var _22=_20[_21];
+if(typeof _22!=="undefined"&&!dojo.isArray(_22)){
+_22=[_22];
+}else{
+if(typeof _22==="undefined"){
+_22=[];
+}
+}
+return _22;
+},isItem:function(_23){
+if(_23&&_23[this._storeRef]===this){
+return true;
+}
+return false;
+},close:function(_24){
+},fetch:function(_25){
+_25=_25||{};
+if(!_25.store){
+_25.store=this;
+}
+var _26=this;
+var _27=_25.scope||dojo.global;
+var _28={};
+if(_25.query){
+_28.query=dojo.toJson(_25.query);
+}
+if(_25.sort){
+_28.sort=dojo.toJson(_25.sort);
+}
+if(_25.queryOptions){
+_28.queryOptions=dojo.toJson(_25.queryOptions);
+}
+if(typeof _25.start=="number"){
+_28.start=""+_25.start;
+}
+if(typeof _25.count=="number"){
+_28.count=""+_25.count;
+}
+if(this.options.length>0){
+_28.options=dojo.toJson(this.options);
+}
+var _29={url:this.url,preventCache:true,handleAs:"json-comment-optional",content:_28};
+var _2a=dojo.xhrGet(_29);
+_2a.addCallback(function(_2b){
+_26._processResult(_2b,_25);
+});
+_2a.addErrback(function(_2c){
+if(_25.onError){
+_25.onError.call(_27,_2c,_25);
+}
+});
+},fetchItemByIdentity:function(_2d){
+var _2e=_2d.identity;
+var _2f=this;
+var _30=_2d.scope||dojo.global;
+var _31={};
+if(this.options.length>0){
+_31.options=dojo.toJson(this.options);
+}
+if(this.pathAsQueryParam){
+_31.path=_2e;
+}
+var _32={url:this.pathAsQueryParam?this.url:this.url+"/"+_2e,handleAs:"json-comment-optional",content:_31,preventCache:true};
+var _33=dojo.xhrGet(_32);
+_33.addErrback(function(_34){
+if(_2d.onError){
+_2d.onError.call(_30,_34);
+}
+});
+_33.addCallback(function(_35){
+var _36=_2f._processItem(_35);
+if(_2d.onItem){
+_2d.onItem.call(_30,_36);
+}
+});
+},_processResult:function(_37,_38){
+var _39=_38.scope||dojo.global;
+try{
+if(_37.pathSeparator){
+this.pathSeparator=_37.pathSeparator;
+}
+if(_38.onBegin){
+_38.onBegin.call(_39,_37.total,_38);
+}
+var _3a=this._processItemArray(_37.items);
+if(_38.onItem){
+var i;
+for(i=0;i<_3a.length;i++){
+_38.onItem.call(_39,_3a[i],_38);
+}
+_3a=null;
+}
+if(_38.onComplete){
+_38.onComplete.call(_39,_3a,_38);
+}
+}
+catch(e){
+if(_38.onError){
+_38.onError.call(_39,e,_38);
+}else{
+
+}
+}
+},_processItemArray:function(_3c){
+var i;
+for(i=0;i<_3c.length;i++){
+this._processItem(_3c[i]);
+}
+return _3c;
+},_processItem:function(_3e){
+if(!_3e){
+return null;
+}
+_3e[this._storeRef]=this;
+if(_3e.children&&_3e.directory){
+if(dojo.isArray(_3e.children)){
+var _3f=_3e.children;
+var i;
+for(i=0;i<_3f.length;i++){
+var _41=_3f[i];
+if(dojo.isObject(_41)){
+_3f[i]=this._processItem(_41);
+}else{
+_3f[i]={name:_41,_loaded:false,parentPath:_3e.path};
+_3f[i][this._storeRef]=this;
+}
+}
+}else{
+delete _3e.children;
+}
+}
+return _3e;
+}});
+}
diff --git a/dojox/data/FlickrRestStore.js b/dojox/data/FlickrRestStore.js
new file mode 100644
index 0000000..c63aaa5
--- /dev/null
+++ b/dojox/data/FlickrRestStore.js
@@ -0,0 +1,289 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.FlickrRestStore"]){
+dojo._hasResource["dojox.data.FlickrRestStore"]=true;
+dojo.provide("dojox.data.FlickrRestStore");
+dojo.require("dojox.data.FlickrStore");
+dojo.declare("dojox.data.FlickrRestStore",dojox.data.FlickrStore,{constructor:function(_1){
+if(_1){
+if(_1.label){
+this.label=_1.label;
+}
+if(_1.apikey){
+this._apikey=_1.apikey;
+}
+}
+this._cache=[];
+this._prevRequests={};
+this._handlers={};
+this._prevRequestRanges=[];
+this._maxPhotosPerUser={};
+this._id=dojox.data.FlickrRestStore.prototype._id++;
+},_id:0,_requestCount:0,_flickrRestUrl:"http://www.flickr.com/services/rest/",_apikey:null,_storeRef:"_S",_cache:null,_prevRequests:null,_handlers:null,_sortAttributes:{"date-posted":true,"date-taken":true,"interestingness":true},_fetchItems:function(_2,_3,_4){
+var _5={};
+if(!_2.query){
+_2.query=_5={};
+}else{
+dojo.mixin(_5,_2.query);
+}
+var _6=[];
+var _7=[];
+var _8={format:"json",method:"flickr.photos.search",api_key:this._apikey,extras:"owner_name,date_upload,date_taken"};
+var _9=false;
+if(_5.userid){
+_9=true;
+_8.user_id=_2.query.userid;
+_6.push("userid"+_2.query.userid);
+}
+if(_5.apikey){
+_9=true;
+_8.api_key=_2.query.apikey;
+_7.push("api"+_2.query.apikey);
+}else{
+if(_8.api_key){
+_9=true;
+_2.query.apikey=_8.api_key;
+_7.push("api"+_8.api_key);
+}else{
+throw Error("dojox.data.FlickrRestStore: An API key must be specified.");
+}
+}
+_2._curCount=_2.count;
+if(_5.page){
+_8.page=_2.query.page;
+_7.push("page"+_8.page);
+}else{
+if(typeof (_2.start)!="undefined"&&_2.start!=null){
+if(!_2.count){
+_2.count=20;
+}
+var _a=_2.start%_2.count;
+var _b=_2.start,_c=_2.count;
+if(_a!=0){
+if(_b<_c/2){
+_c=_b+_c;
+_b=0;
+}else{
+var _d=20,_e=2;
+for(var i=_d;i>0;i--){
+if(_b%i==0&&(_b/i)>=_c){
+_e=i;
+break;
+}
+}
+_c=_b/_e;
+}
+_2._realStart=_2.start;
+_2._realCount=_2.count;
+_2._curStart=_b;
+_2._curCount=_c;
+}else{
+_2._realStart=_2._realCount=null;
+_2._curStart=_2.start;
+_2._curCount=_2.count;
+}
+_8.page=(_b/_c)+1;
+_7.push("page"+_8.page);
+}
+}
+if(_2._curCount){
+_8.per_page=_2._curCount;
+_7.push("count"+_2._curCount);
+}
+if(_5.lang){
+_8.lang=_2.query.lang;
+_6.push("lang"+_2.lang);
+}
+var url=this._flickrRestUrl;
+if(_5.setid){
+_8.method="flickr.photosets.getPhotos";
+_8.photoset_id=_2.query.setid;
+_6.push("set"+_2.query.setid);
+}
+if(_5.tags){
+if(_5.tags instanceof Array){
+_8.tags=_5.tags.join(",");
+}else{
+_8.tags=_5.tags;
+}
+_6.push("tags"+_8.tags);
+if(_5["tag_mode"]&&(_5.tag_mode.toLowerCase()=="any"||_5.tag_mode.toLowerCase()=="all")){
+_8.tag_mode=_5.tag_mode;
+}
+}
+if(_5.text){
+_8.text=_5.text;
+_6.push("text:"+_5.text);
+}
+if(_5.sort&&_5.sort.length>0){
+if(!_5.sort[0].attribute){
+_5.sort[0].attribute="date-posted";
+}
+if(this._sortAttributes[_5.sort[0].attribute]){
+if(_5.sort[0].descending){
+_8.sort=_5.sort[0].attribute+"-desc";
+}else{
+_8.sort=_5.sort[0].attribute+"-asc";
+}
+}
+}else{
+_8.sort="date-posted-asc";
+}
+_6.push("sort:"+_8.sort);
+_6=_6.join(".");
+_7=_7.length>0?"."+_7.join("."):"";
+var _11=_6+_7;
+_2={query:_5,count:_2._curCount,start:_2._curStart,_realCount:_2._realCount,_realStart:_2._realStart,onBegin:_2.onBegin,onComplete:_2.onComplete,onItem:_2.onItem};
+var _12={request:_2,fetchHandler:_3,errorHandler:_4};
+if(this._handlers[_11]){
+this._handlers[_11].push(_12);
+return;
+}
+this._handlers[_11]=[_12];
+var _13=null;
+var _14={url:this._flickrRestUrl,preventCache:true,content:_8,callbackParamName:"jsoncallback"};
+var _15=dojo.hitch(this,function(_16,_17,_18){
+var _19=_18.request.onBegin;
+_18.request.onBegin=null;
+var _1a;
+var req=_18.request;
+if(typeof (req._realStart)!=undefined&&req._realStart!=null){
+req.start=req._realStart;
+req.count=req._realCount;
+req._realStart=req._realCount=null;
+}
+if(_19){
+var _1c=null;
+if(_17){
+_1c=(_17.photoset?_17.photoset:_17.photos);
+}
+if(_1c&&typeof (_1c.perpage)!="undefined"&&typeof (_1c.pages)!="undefined"){
+if(_1c.perpage*_1c.pages<=_18.request.start+_18.request.count){
+_1a=_18.request.start+_1c.photo.length;
+}else{
+_1a=_1c.perpage*_1c.pages;
+}
+this._maxPhotosPerUser[_6]=_1a;
+_19(_1a,_18.request);
+}else{
+if(this._maxPhotosPerUser[_6]){
+_19(this._maxPhotosPerUser[_6],_18.request);
+}
+}
+}
+_18.fetchHandler(_16,_18.request);
+if(_19){
+_18.request.onBegin=_19;
+}
+});
+var _1d=dojo.hitch(this,function(_1e){
+if(_1e.stat!="ok"){
+_4(null,_2);
+}else{
+var _1f=this._handlers[_11];
+if(!_1f){
+
+return;
+}
+this._handlers[_11]=null;
+this._prevRequests[_11]=_1e;
+var _20=this._processFlickrData(_1e,_2,_6);
+if(!this._prevRequestRanges[_6]){
+this._prevRequestRanges[_6]=[];
+}
+this._prevRequestRanges[_6].push({start:_2.start,end:_2.start+(_1e.photoset?_1e.photoset.photo.length:_1e.photos.photo.length)});
+dojo.forEach(_1f,function(i){
+_15(_20,_1e,i);
+});
+}
+});
+var _22=this._prevRequests[_11];
+if(_22){
+this._handlers[_11]=null;
+_15(this._cache[_6],_22,_12);
+return;
+}else{
+if(this._checkPrevRanges(_6,_2.start,_2.count)){
+this._handlers[_11]=null;
+_15(this._cache[_6],null,_12);
+return;
+}
+}
+var _23=dojo.io.script.get(_14);
+_23.addCallback(_1d);
+_23.addErrback(function(_24){
+dojo.disconnect(_13);
+_4(_24,_2);
+});
+},getAttributes:function(_25){
+return ["title","author","imageUrl","imageUrlSmall","imageUrlMedium","imageUrlThumb","link","dateTaken","datePublished"];
+},getValues:function(_26,_27){
+this._assertIsItem(_26);
+this._assertIsAttribute(_27);
+switch(_27){
+case "title":
+return [this._unescapeHtml(_26.title)];
+case "author":
+return [_26.ownername];
+case "imageUrlSmall":
+return [_26.media.s];
+case "imageUrl":
+return [_26.media.l];
+case "imageUrlMedium":
+return [_26.media.m];
+case "imageUrlThumb":
+return [_26.media.t];
+case "link":
+return ["http://www.flickr.com/photos/"+_26.owner+"/"+_26.id];
+case "dateTaken":
+return [_26.datetaken];
+case "datePublished":
+return [_26.datepublished];
+default:
+return undefined;
+}
+},_processFlickrData:function(_28,_29,_2a){
+if(_28.items){
+return dojox.data.FlickrStore.prototype._processFlickrData.apply(this,arguments);
+}
+var _2b=["http://farm",null,".static.flickr.com/",null,"/",null,"_",null];
+var _2c=[];
+var _2d=(_28.photoset?_28.photoset:_28.photos);
+if(_28.stat=="ok"&&_2d&&_2d.photo){
+_2c=_2d.photo;
+for(var i=0;i<_2c.length;i++){
+var _2f=_2c[i];
+_2f[this._storeRef]=this;
+_2b[1]=_2f.farm;
+_2b[3]=_2f.server;
+_2b[5]=_2f.id;
+_2b[7]=_2f.secret;
+var _30=_2b.join("");
+_2f.media={s:_30+"_s.jpg",m:_30+"_m.jpg",l:_30+".jpg",t:_30+"_t.jpg"};
+if(!_2f.owner&&_28.photoset){
+_2f.owner=_28.photoset.owner;
+}
+}
+}
+var _31=_29.start?_29.start:0;
+var arr=this._cache[_2a];
+if(!arr){
+this._cache[_2a]=arr=[];
+}
+dojo.forEach(_2c,function(i,idx){
+arr[idx+_31]=i;
+});
+return arr;
+},_checkPrevRanges:function(_35,_36,_37){
+var end=_36+_37;
+var arr=this._prevRequestRanges[_35];
+return (!!arr)&&dojo.some(arr,function(_3a){
+return ((_36>=_3a.start)&&(end<=_3a.end));
+});
+}});
+}
diff --git a/dojox/data/FlickrStore.js b/dojox/data/FlickrStore.js
new file mode 100644
index 0000000..1b12537
--- /dev/null
+++ b/dojox/data/FlickrStore.js
@@ -0,0 +1,147 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.FlickrStore"]){
+dojo._hasResource["dojox.data.FlickrStore"]=true;
+dojo.provide("dojox.data.FlickrStore");
+dojo.require("dojo.data.util.simpleFetch");
+dojo.require("dojo.io.script");
+dojo.require("dojo.date.stamp");
+dojo.require("dojo.AdapterRegistry");
+(function(){
+var d=dojo;
+dojo.declare("dojox.data.FlickrStore",null,{constructor:function(_2){
+if(_2&&_2.label){
+this.label=_2.label;
+}
+},_storeRef:"_S",label:"title",_assertIsItem:function(_3){
+if(!this.isItem(_3)){
+throw new Error("dojox.data.FlickrStore: a function was passed an item argument that was not an item");
+}
+},_assertIsAttribute:function(_4){
+if(typeof _4!=="string"){
+throw new Error("dojox.data.FlickrStore: a function was passed an attribute argument that was not an attribute name string");
+}
+},getFeatures:function(){
+return {"dojo.data.api.Read":true};
+},getValue:function(_5,_6,_7){
+var _8=this.getValues(_5,_6);
+if(_8&&_8.length>0){
+return _8[0];
+}
+return _7;
+},getAttributes:function(_9){
+return ["title","description","author","datePublished","dateTaken","imageUrl","imageUrlSmall","imageUrlMedium","tags","link"];
+},hasAttribute:function(_a,_b){
+if(this.getValue(_a,_b)){
+return true;
+}
+return false;
+},isItemLoaded:function(_c){
+return this.isItem(_c);
+},loadItem:function(_d){
+},getLabel:function(_e){
+return this.getValue(_e,this.label);
+},getLabelAttributes:function(_f){
+return [this.label];
+},containsValue:function(_10,_11,_12){
+var _13=this.getValues(_10,_11);
+for(var i=0;i<_13.length;i++){
+if(_13[i]===_12){
+return true;
+}
+}
+return false;
+},getValues:function(_15,_16){
+this._assertIsItem(_15);
+this._assertIsAttribute(_16);
+var u=d.hitch(this,"_unescapeHtml");
+var s=d.hitch(d.date.stamp,"fromISOString");
+switch(_16){
+case "title":
+return [u(_15.title)];
+case "author":
+return [u(_15.author)];
+case "datePublished":
+return [s(_15.published)];
+case "dateTaken":
+return [s(_15.date_taken)];
+case "imageUrlSmall":
+return [_15.media.m.replace(/_m\./,"_s.")];
+case "imageUrl":
+return [_15.media.m.replace(/_m\./,".")];
+case "imageUrlMedium":
+return [_15.media.m];
+case "link":
+return [_15.link];
+case "tags":
+return _15.tags.split(" ");
+case "description":
+return [u(_15.description)];
+default:
+return [];
+}
+},isItem:function(_19){
+if(_19&&_19[this._storeRef]===this){
+return true;
+}
+return false;
+},close:function(_1a){
+},_fetchItems:function(_1b,_1c,_1d){
+var rq=_1b.query=_1b.query||{};
+var _1f={format:"json",tagmode:"any"};
+d.forEach(["tags","tagmode","lang","id","ids"],function(i){
+if(rq[i]){
+_1f[i]=rq[i];
+}
+});
+_1f.id=rq.id||rq.userid||rq.groupid;
+if(rq.userids){
+_1f.ids=rq.userids;
+}
+var _21=null;
+var _22={url:dojox.data.FlickrStore.urlRegistry.match(_1b),preventCache:true,content:_1f};
+var _23=d.hitch(this,function(_24){
+if(!!_21){
+d.disconnect(_21);
+}
+_1c(this._processFlickrData(_24),_1b);
+});
+_21=d.connect("jsonFlickrFeed",_23);
+var _25=d.io.script.get(_22);
+_25.addErrback(function(_26){
+d.disconnect(_21);
+_1d(_26,_1b);
+});
+},_processFlickrData:function(_27){
+var _28=[];
+if(_27.items){
+_28=_27.items;
+for(var i=0;i<_27.items.length;i++){
+var _2a=_27.items[i];
+_2a[this._storeRef]=this;
+}
+}
+return _28;
+},_unescapeHtml:function(str){
+return str.replace(/&/gm,"&").replace(/</gm,"<").replace(/>/gm,">").replace(/"/gm,"\"").replace(/'/gm,"'");
+}});
+dojo.extend(dojox.data.FlickrStore,dojo.data.util.simpleFetch);
+var _2c="http://api.flickr.com/services/feeds/";
+var reg=dojox.data.FlickrStore.urlRegistry=new d.AdapterRegistry(true);
+reg.register("group pool",function(_2e){
+return !!_2e.query["groupid"];
+},_2c+"groups_pool.gne");
+reg.register("default",function(_2f){
+return true;
+},_2c+"photos_public.gne");
+})();
+if(!jsonFlickrFeed){
+var jsonFlickrFeed=function(_30){
+};
+}
+}
diff --git a/dojox/data/GoogleFeedStore.js b/dojox/data/GoogleFeedStore.js
new file mode 100644
index 0000000..38721d6
--- /dev/null
+++ b/dojox/data/GoogleFeedStore.js
@@ -0,0 +1,24 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.GoogleFeedStore"]){
+dojo._hasResource["dojox.data.GoogleFeedStore"]=true;
+dojo.provide("dojox.data.GoogleFeedStore");
+dojo.experimental("dojox.data.GoogleFeedStore");
+dojo.require("dojox.data.GoogleSearchStore");
+dojo.declare("dojox.data.GoogleFeedStore",dojox.data.GoogleSearchStore,{_type:"",_googleUrl:"http://ajax.googleapis.com/ajax/services/feed/load",_attributes:["title","link","author","published","content","summary","categories"],_queryAttr:"url",_processItem:function(_1,_2){
+this.inherited(arguments);
+_1["summary"]=_1["contentSnippet"];
+_1["published"]=_1["publishedDate"];
+},_getItems:function(_3){
+return _3["feed"]&&_3.feed[["entries"]]?_3.feed[["entries"]]:null;
+},_createContent:function(_4,_5,_6){
+var cb=this.inherited(arguments);
+cb.num=(_6.count||10)+(_6.start||0);
+return cb;
+}});
+}
diff --git a/dojox/data/GoogleSearchStore.js b/dojox/data/GoogleSearchStore.js
new file mode 100644
index 0000000..67fb5a2
--- /dev/null
+++ b/dojox/data/GoogleSearchStore.js
@@ -0,0 +1,239 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.GoogleSearchStore"]){
+dojo._hasResource["dojox.data.GoogleSearchStore"]=true;
+dojo.provide("dojox.data.GoogleSearchStore");
+dojo.provide("dojox.data.GoogleWebSearchStore");
+dojo.provide("dojox.data.GoogleBlogSearchStore");
+dojo.provide("dojox.data.GoogleLocalSearchStore");
+dojo.provide("dojox.data.GoogleVideoSearchStore");
+dojo.provide("dojox.data.GoogleNewsSearchStore");
+dojo.provide("dojox.data.GoogleBookSearchStore");
+dojo.provide("dojox.data.GoogleImageSearchStore");
+dojo.require("dojo.io.script");
+dojo.experimental("dojox.data.GoogleSearchStore");
+dojo.declare("dojox.data.GoogleSearchStore",null,{constructor:function(_1){
+if(_1){
+if(_1.label){
+this.label=_1.label;
+}
+if(_1.key){
+this._key=_1.key;
+}
+if(_1.lang){
+this._lang=_1.lang;
+}
+}
+this._id=dojox.data.GoogleSearchStore.prototype._id++;
+},_id:0,_requestCount:0,_googleUrl:"http://ajax.googleapis.com/ajax/services/search/",_storeRef:"_S",_attributes:["unescapedUrl","url","visibleUrl","cacheUrl","title","titleNoFormatting","content"],label:"titleNoFormatting",_type:"web",_queryAttr:"text",_assertIsItem:function(_2){
+if(!this.isItem(_2)){
+throw new Error("dojox.data.GoogleSearchStore: a function was passed an item argument that was not an item");
+}
+},_assertIsAttribute:function(_3){
+if(typeof _3!=="string"){
+throw new Error("dojox.data.GoogleSearchStore: a function was passed an attribute argument that was not an attribute name string");
+}
+},getFeatures:function(){
+return {"dojo.data.api.Read":true};
+},getValue:function(_4,_5,_6){
+var _7=this.getValues(_4,_5);
+if(_7&&_7.length>0){
+return _7[0];
+}
+return _6;
+},getAttributes:function(_8){
+return this._attributes;
+},hasAttribute:function(_9,_a){
+if(this.getValue(_9,_a)){
+return true;
+}
+return false;
+},isItemLoaded:function(_b){
+return this.isItem(_b);
+},loadItem:function(_c){
+},getLabel:function(_d){
+return this.getValue(_d,this.label);
+},getLabelAttributes:function(_e){
+return [this.label];
+},containsValue:function(_f,_10,_11){
+var _12=this.getValues(_f,_10);
+for(var i=0;i<_12.length;i++){
+if(_12[i]===_11){
+return true;
+}
+}
+return false;
+},getValues:function(_14,_15){
+this._assertIsItem(_14);
+this._assertIsAttribute(_15);
+var val=_14[_15];
+if(dojo.isArray(val)){
+return val;
+}else{
+if(val!==undefined){
+return [val];
+}else{
+return [];
+}
+}
+},isItem:function(_17){
+if(_17&&_17[this._storeRef]===this){
+return true;
+}
+return false;
+},close:function(_18){
+},_format:function(_19,_1a){
+return _19;
+},fetch:function(_1b){
+_1b=_1b||{};
+var _1c=_1b.scope||dojo.global;
+if(!_1b.query||!_1b.query[this._queryAttr]){
+if(_1b.onError){
+_1b.onError.call(_1c,new Error(this.declaredClass+": A query must be specified, with a '"+[this._queryAttr]+"' parameter."));
+return;
+}
+}
+var _1d=_1b.query[this._queryAttr];
+_1b={query:{},onComplete:_1b.onComplete,onError:_1b.onError,onItem:_1b.onItem,onBegin:_1b.onBegin,start:_1b.start,count:_1b.count};
+_1b.query[this._queryAttr]=_1d;
+var _1e=8;
+var _1f="GoogleSearchStoreCallback_"+this._id+"_"+(++this._requestCount);
+var _20=this._createContent(_1d,_1f,_1b);
+var _21;
+if(typeof (_1b.start)==="undefined"||_1b.start===null){
+_1b.start=0;
+}
+if(!_1b.count){
+_1b.count=_1e;
+}
+_21={start:_1b.start-_1b.start%_1e};
+var _22=this;
+var _23=null;
+var _24=this._googleUrl+this._type;
+var _25={url:_24,preventCache:true,content:_20};
+var _26=[];
+var _27=0;
+var _28=false;
+var _29=_1b.start-1;
+var _2a=0;
+function _2b(req){
+_2a++;
+_25.content.context=_25.content.start=req.start;
+var _2d=dojo.io.script.get(_25);
+_2d.addErrback(function(_2e){
+if(_1b.onError){
+_1b.onError.call(_1c,_2e,_1b);
+}
+});
+};
+var _2f=function(_30,_31){
+if(_28){
+return;
+}
+var _32=_22._getItems(_31);
+var _33=_31?_31["cursor"]:null;
+if(_32){
+for(var i=0;i<_32.length&&i+_30<_1b.count+_1b.start;i++){
+_22._processItem(_32[i],_31);
+_26[i+_30]=_32[i];
+}
+_27++;
+if(_27==1){
+var _35=_33?_33.pages:null;
+var _36=_35?Number(_35[_35.length-1].start):0;
+if(_1b.onBegin){
+var est=_33?_33.estimatedResultCount:_32.length;
+var _38=est?Math.min(est,_36+_32.length):_36+_32.length;
+_1b.onBegin.call(_1c,_38,_1b);
+}
+var _39=(_1b.start-_1b.start%_1e)+_1e;
+var _3a=1;
+while(_35){
+if(!_35[_3a]||Number(_35[_3a].start)>=_1b.start+_1b.count){
+break;
+}
+if(Number(_35[_3a].start)>=_39){
+_2b({start:_35[_3a].start});
+}
+_3a++;
+}
+}
+if(_1b.onItem&&_26[_29+1]){
+do{
+_29++;
+_1b.onItem.call(_1c,_26[_29],_1b);
+}while(_26[_29+1]&&_29<_1b.start+_1b.count);
+}
+if(_27==_2a){
+_28=true;
+dojo.global[_1f]=null;
+if(_1b.onItem){
+_1b.onComplete.call(_1c,null,_1b);
+}else{
+_26=_26.slice(_1b.start,_1b.start+_1b.count);
+_1b.onComplete.call(_1c,_26,_1b);
+}
+}
+}
+};
+var _3b=[];
+var _3c=_21.start-1;
+var _3d=function(a,b){
+if(a.start<b.start){
+return -1;
+}
+if(b.start<a.start){
+return 1;
+}
+return 0;
+};
+dojo.global[_1f]=function(_40,_41,_42,_43){
+try{
+if(_42!=200){
+if(_1b.onError){
+_1b.onError.call(_1c,new Error("Response from Google was: "+_42),_1b);
+}
+dojo.global[_1f]=function(){
+};
+return;
+}
+if(_40==_3c+1){
+_2f(Number(_40),_41);
+_3c+=_1e;
+if(_3b.length>0){
+_3b.sort(_3d);
+while(_3b.length>0&&_3b[0].start==_3c+1){
+_2f(Number(_3b[0].start),_3b[0].data);
+_3b.splice(0,1);
+_3c+=_1e;
+}
+}
+}else{
+_3b.push({start:_40,data:_41});
+}
+}
+catch(e){
+_1b.onError.call(_1c,e,_1b);
+}
+};
+_2b(_21);
+},_processItem:function(_44,_45){
+_44[this._storeRef]=this;
+},_getItems:function(_46){
+return _46["results"]||_46;
+},_createContent:function(_47,_48,_49){
+return {q:_47,v:"1.0",rsz:"large",callback:_48,key:this._key,hl:this._lang};
+}});
+dojo.declare("dojox.data.GoogleWebSearchStore",dojox.data.GoogleSearchStore,{});
+dojo.declare("dojox.data.GoogleBlogSearchStore",dojox.data.GoogleSearchStore,{_type:"blogs",_attributes:["blogUrl","postUrl","title","titleNoFormatting","content","author","publishedDate"]});
+dojo.declare("dojox.data.GoogleLocalSearchStore",dojox.data.GoogleSearchStore,{_type:"local",_attributes:["title","titleNoFormatting","url","lat","lng","streetAddress","city","region","country","phoneNumbers","ddUrl","ddUrlToHere","ddUrlFromHere","staticMapUrl"]});
+dojo.declare("dojox.data.GoogleVideoSearchStore",dojox.data.GoogleSearchStore,{_type:"video",_attributes:["title","titleNoFormatting","content","url","published","publisher","duration","tbWidth","tbHeight","tbUrl","playUrl"]});
+dojo.declare("dojox.data.GoogleNewsSearchStore",dojox.data.GoogleSearchStore,{_type:"news",_attributes:["title","titleNoFormatting","content","url","unescapedUrl","publisher","clusterUrl","location","publishedDate","relatedStories"]});
+dojo.declare("dojox.data.GoogleBookSearchStore",dojox.data.GoogleSearchStore,{_type:"books",_attributes:["title","titleNoFormatting","authors","url","unescapedUrl","bookId","pageCount","publishedYear"]});
+dojo.declare("dojox.data.GoogleImageSearchStore",dojox.data.GoogleSearchStore,{_type:"images",_attributes:["title","titleNoFormatting","visibleUrl","url","unescapedUrl","originalContextUrl","width","height","tbWidth","tbHeight","tbUrl","content","contentNoFormatting"]});
+}
diff --git a/dojox/data/HtmlStore.js b/dojox/data/HtmlStore.js
new file mode 100644
index 0000000..e2a1208
--- /dev/null
+++ b/dojox/data/HtmlStore.js
@@ -0,0 +1,313 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.HtmlStore"]){
+dojo._hasResource["dojox.data.HtmlStore"]=true;
+dojo.provide("dojox.data.HtmlStore");
+dojo.require("dojox.xml.parser");
+dojo.require("dojo.data.util.simpleFetch");
+dojo.require("dojo.data.util.filter");
+dojo.declare("dojox.data.HtmlStore",null,{constructor:function(_1){
+if(_1.url){
+if(!_1.dataId){
+throw new Error("dojo.data.HtmlStore: Cannot instantiate using url without an id!");
+}
+this.url=_1.url;
+this.dataId=_1.dataId;
+}else{
+if(_1.dataId){
+this._rootNode=dojo.byId(_1.dataId);
+this.dataId=this._rootNode.id;
+}else{
+this._rootNode=dojo.byId(this.dataId);
+}
+this._indexItems();
+}
+},url:"",dataId:"",_indexItems:function(){
+this._getHeadings();
+if(this._rootNode.rows){
+if(this._rootNode.tBodies&&this._rootNode.tBodies.length>0){
+this._rootNode=this._rootNode.tBodies[0];
+}
+var i;
+for(i=0;i<this._rootNode.rows.length;i++){
+this._rootNode.rows[i].store=this;
+this._rootNode.rows[i]._ident=i+1;
+}
+}else{
+var c=1;
+for(i=0;i<this._rootNode.childNodes.length;i++){
+if(this._rootNode.childNodes[i].nodeType===1){
+this._rootNode.childNodes[i].store=this;
+this._rootNode.childNodes[i]._ident=c;
+c++;
+}
+}
+}
+},_getHeadings:function(){
+this._headings=[];
+if(this._rootNode.tHead){
+dojo.forEach(this._rootNode.tHead.rows[0].cells,dojo.hitch(this,function(th){
+this._headings.push(dojox.xml.parser.textContent(th));
+}));
+}else{
+this._headings=["name"];
+}
+},_getAllItems:function(){
+var _5=[];
+var i;
+if(this._rootNode.rows){
+for(i=0;i<this._rootNode.rows.length;i++){
+_5.push(this._rootNode.rows[i]);
+}
+}else{
+for(i=0;i<this._rootNode.childNodes.length;i++){
+if(this._rootNode.childNodes[i].nodeType===1){
+_5.push(this._rootNode.childNodes[i]);
+}
+}
+}
+return _5;
+},_assertIsItem:function(_7){
+if(!this.isItem(_7)){
+throw new Error("dojo.data.HtmlStore: a function was passed an item argument that was not an item");
+}
+},_assertIsAttribute:function(_8){
+if(typeof _8!=="string"){
+throw new Error("dojo.data.HtmlStore: a function was passed an attribute argument that was not an attribute name string");
+return -1;
+}
+return dojo.indexOf(this._headings,_8);
+},getValue:function(_9,_a,_b){
+var _c=this.getValues(_9,_a);
+return (_c.length>0)?_c[0]:_b;
+},getValues:function(_d,_e){
+this._assertIsItem(_d);
+var _f=this._assertIsAttribute(_e);
+if(_f>-1){
+if(_d.cells){
+return [dojox.xml.parser.textContent(_d.cells[_f])];
+}else{
+return [dojox.xml.parser.textContent(_d)];
+}
+}
+return [];
+},getAttributes:function(_10){
+this._assertIsItem(_10);
+var _11=[];
+for(var i=0;i<this._headings.length;i++){
+if(this.hasAttribute(_10,this._headings[i])){
+_11.push(this._headings[i]);
+}
+}
+return _11;
+},hasAttribute:function(_13,_14){
+return this.getValues(_13,_14).length>0;
+},containsValue:function(_15,_16,_17){
+var _18=undefined;
+if(typeof _17==="string"){
+_18=dojo.data.util.filter.patternToRegExp(_17,false);
+}
+return this._containsValue(_15,_16,_17,_18);
+},_containsValue:function(_19,_1a,_1b,_1c){
+var _1d=this.getValues(_19,_1a);
+for(var i=0;i<_1d.length;++i){
+var _1f=_1d[i];
+if(typeof _1f==="string"&&_1c){
+return (_1f.match(_1c)!==null);
+}else{
+if(_1b===_1f){
+return true;
+}
+}
+}
+return false;
+},isItem:function(_20){
+if(_20&&_20.store&&_20.store===this){
+return true;
+}
+return false;
+},isItemLoaded:function(_21){
+return this.isItem(_21);
+},loadItem:function(_22){
+this._assertIsItem(_22.item);
+},_fetchItems:function(_23,_24,_25){
+if(this._rootNode){
+this._finishFetchItems(_23,_24,_25);
+}else{
+if(!this.url){
+this._rootNode=dojo.byId(this.dataId);
+}else{
+var _26={url:this.url,handleAs:"text"};
+var _27=this;
+var _28=dojo.xhrGet(_26);
+_28.addCallback(function(_29){
+var _2a=function(_2b,id){
+if(_2b.id==id){
+return _2b;
+}
+if(_2b.childNodes){
+for(var i=0;i<_2b.childNodes.length;i++){
+var _2e=_2a(_2b.childNodes[i],id);
+if(_2e){
+return _2e;
+}
+}
+}
+return null;
+};
+var d=document.createElement("div");
+d.innerHTML=_29;
+_27._rootNode=_2a(d,_27.dataId);
+_27._indexItems();
+_27._finishFetchItems(_23,_24,_25);
+});
+_28.addErrback(function(_30){
+_25(_30,_23);
+});
+}
+}
+},_finishFetchItems:function(_31,_32,_33){
+var _34=null;
+var _35=this._getAllItems();
+if(_31.query){
+var _36=_31.queryOptions?_31.queryOptions.ignoreCase:false;
+_34=[];
+var _37={};
+var key;
+var _39;
+for(key in _31.query){
+_39=_31.query[key]+"";
+if(typeof _39==="string"){
+_37[key]=dojo.data.util.filter.patternToRegExp(_39,_36);
+}
+}
+for(var i=0;i<_35.length;++i){
+var _3b=true;
+var _3c=_35[i];
+for(key in _31.query){
+_39=_31.query[key]+"";
+if(!this._containsValue(_3c,key,_39,_37[key])){
+_3b=false;
+}
+}
+if(_3b){
+_34.push(_3c);
+}
+}
+_32(_34,_31);
+}else{
+if(_35.length>0){
+_34=_35.slice(0,_35.length);
+}
+_32(_34,_31);
+}
+},getFeatures:function(){
+return {"dojo.data.api.Read":true,"dojo.data.api.Identity":true};
+},close:function(_3d){
+},getLabel:function(_3e){
+if(this.isItem(_3e)){
+if(_3e.cells){
+return "Item #"+this.getIdentity(_3e);
+}else{
+return this.getValue(_3e,"name");
+}
+}
+return undefined;
+},getLabelAttributes:function(_3f){
+if(_3f.cells){
+return null;
+}else{
+return ["name"];
+}
+},getIdentity:function(_40){
+this._assertIsItem(_40);
+if(this.hasAttribute(_40,"name")){
+return this.getValue(_40,"name");
+}else{
+return _40._ident;
+}
+},getIdentityAttributes:function(_41){
+return null;
+},fetchItemByIdentity:function(_42){
+var _43=_42.identity;
+var _44=this;
+var _45=null;
+var _46=null;
+if(!this._rootNode){
+if(!this.url){
+this._rootNode=dojo.byId(this.dataId);
+this._indexItems();
+if(_44._rootNode.rows){
+_45=this._rootNode.rows[_43+1];
+}else{
+for(var i=0;i<_44._rootNode.childNodes.length;i++){
+if(_44._rootNode.childNodes[i].nodeType===1&&_43===dojox.xml.parser.textContent(_44._rootNode.childNodes[i])){
+_45=_44._rootNode.childNodes[i];
+}
+}
+}
+if(_42.onItem){
+_46=_42.scope?_42.scope:dojo.global;
+_42.onItem.call(_46,_45);
+}
+}else{
+var _48={url:this.url,handleAs:"text"};
+var _49=dojo.xhrGet(_48);
+_49.addCallback(function(_4a){
+var _4b=function(_4c,id){
+if(_4c.id==id){
+return _4c;
+}
+if(_4c.childNodes){
+for(var i=0;i<_4c.childNodes.length;i++){
+var _4f=_4b(_4c.childNodes[i],id);
+if(_4f){
+return _4f;
+}
+}
+}
+return null;
+};
+var d=document.createElement("div");
+d.innerHTML=_4a;
+_44._rootNode=_4b(d,_44.dataId);
+_44._indexItems();
+if(_44._rootNode.rows&&_43<=_44._rootNode.rows.length){
+_45=_44._rootNode.rows[_43-1];
+}else{
+for(var i=0;i<_44._rootNode.childNodes.length;i++){
+if(_44._rootNode.childNodes[i].nodeType===1&&_43===dojox.xml.parser.textContent(_44._rootNode.childNodes[i])){
+_45=_44._rootNode.childNodes[i];
+break;
+}
+}
+}
+if(_42.onItem){
+_46=_42.scope?_42.scope:dojo.global;
+_42.onItem.call(_46,_45);
+}
+});
+_49.addErrback(function(_52){
+if(_42.onError){
+_46=_42.scope?_42.scope:dojo.global;
+_42.onError.call(_46,_52);
+}
+});
+}
+}else{
+if(this._rootNode.rows[_43+1]){
+_45=this._rootNode.rows[_43+1];
+if(_42.onItem){
+_46=_42.scope?_42.scope:dojo.global;
+_42.onItem.call(_46,_45);
+}
+}
+}
+}});
+dojo.extend(dojox.data.HtmlStore,dojo.data.util.simpleFetch);
+}
diff --git a/dojox/data/HtmlTableStore.js b/dojox/data/HtmlTableStore.js
new file mode 100644
index 0000000..a3a38c8
--- /dev/null
+++ b/dojox/data/HtmlTableStore.js
@@ -0,0 +1,267 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.HtmlTableStore"]){
+dojo._hasResource["dojox.data.HtmlTableStore"]=true;
+dojo.provide("dojox.data.HtmlTableStore");
+dojo.require("dojox.xml.parser");
+dojo.require("dojo.data.util.simpleFetch");
+dojo.require("dojo.data.util.filter");
+dojo.declare("dojox.data.HtmlTableStore",null,{constructor:function(_1){
+dojo.deprecated("dojox.data.HtmlTableStore","Please use dojox.data.HtmlStore");
+if(_1.url){
+if(!_1.tableId){
+throw new Error("dojo.data.HtmlTableStore: Cannot instantiate using url without an id!");
+}
+this.url=_1.url;
+this.tableId=_1.tableId;
+}else{
+if(_1.tableId){
+this._rootNode=dojo.byId(_1.tableId);
+this.tableId=this._rootNode.id;
+}else{
+this._rootNode=dojo.byId(this.tableId);
+}
+this._getHeadings();
+for(var i=0;i<this._rootNode.rows.length;i++){
+this._rootNode.rows[i].store=this;
+}
+}
+},url:"",tableId:"",_getHeadings:function(){
+this._headings=[];
+dojo.forEach(this._rootNode.tHead.rows[0].cells,dojo.hitch(this,function(th){
+this._headings.push(dojox.xml.parser.textContent(th));
+}));
+},_getAllItems:function(){
+var _4=[];
+for(var i=1;i<this._rootNode.rows.length;i++){
+_4.push(this._rootNode.rows[i]);
+}
+return _4;
+},_assertIsItem:function(_6){
+if(!this.isItem(_6)){
+throw new Error("dojo.data.HtmlTableStore: a function was passed an item argument that was not an item");
+}
+},_assertIsAttribute:function(_7){
+if(typeof _7!=="string"){
+throw new Error("dojo.data.HtmlTableStore: a function was passed an attribute argument that was not an attribute name string");
+return -1;
+}
+return dojo.indexOf(this._headings,_7);
+},getValue:function(_8,_9,_a){
+var _b=this.getValues(_8,_9);
+return (_b.length>0)?_b[0]:_a;
+},getValues:function(_c,_d){
+this._assertIsItem(_c);
+var _e=this._assertIsAttribute(_d);
+if(_e>-1){
+return [dojox.xml.parser.textContent(_c.cells[_e])];
+}
+return [];
+},getAttributes:function(_f){
+this._assertIsItem(_f);
+var _10=[];
+for(var i=0;i<this._headings.length;i++){
+if(this.hasAttribute(_f,this._headings[i])){
+_10.push(this._headings[i]);
+}
+}
+return _10;
+},hasAttribute:function(_12,_13){
+return this.getValues(_12,_13).length>0;
+},containsValue:function(_14,_15,_16){
+var _17=undefined;
+if(typeof _16==="string"){
+_17=dojo.data.util.filter.patternToRegExp(_16,false);
+}
+return this._containsValue(_14,_15,_16,_17);
+},_containsValue:function(_18,_19,_1a,_1b){
+var _1c=this.getValues(_18,_19);
+for(var i=0;i<_1c.length;++i){
+var _1e=_1c[i];
+if(typeof _1e==="string"&&_1b){
+return (_1e.match(_1b)!==null);
+}else{
+if(_1a===_1e){
+return true;
+}
+}
+}
+return false;
+},isItem:function(_1f){
+if(_1f&&_1f.store&&_1f.store===this){
+return true;
+}
+return false;
+},isItemLoaded:function(_20){
+return this.isItem(_20);
+},loadItem:function(_21){
+this._assertIsItem(_21.item);
+},_fetchItems:function(_22,_23,_24){
+if(this._rootNode){
+this._finishFetchItems(_22,_23,_24);
+}else{
+if(!this.url){
+this._rootNode=dojo.byId(this.tableId);
+this._getHeadings();
+for(var i=0;i<this._rootNode.rows.length;i++){
+this._rootNode.rows[i].store=this;
+}
+}else{
+var _26={url:this.url,handleAs:"text"};
+var _27=this;
+var _28=dojo.xhrGet(_26);
+_28.addCallback(function(_29){
+var _2a=function(_2b,id){
+if(_2b.id==id){
+return _2b;
+}
+if(_2b.childNodes){
+for(var i=0;i<_2b.childNodes.length;i++){
+var _2e=_2a(_2b.childNodes[i],id);
+if(_2e){
+return _2e;
+}
+}
+}
+return null;
+};
+var d=document.createElement("div");
+d.innerHTML=_29;
+_27._rootNode=_2a(d,_27.tableId);
+_27._getHeadings.call(_27);
+for(var i=0;i<_27._rootNode.rows.length;i++){
+_27._rootNode.rows[i].store=_27;
+}
+_27._finishFetchItems(_22,_23,_24);
+});
+_28.addErrback(function(_31){
+_24(_31,_22);
+});
+}
+}
+},_finishFetchItems:function(_32,_33,_34){
+var _35=null;
+var _36=this._getAllItems();
+if(_32.query){
+var _37=_32.queryOptions?_32.queryOptions.ignoreCase:false;
+_35=[];
+var _38={};
+var _39;
+var key;
+for(key in _32.query){
+_39=_32.query[key]+"";
+if(typeof _39==="string"){
+_38[key]=dojo.data.util.filter.patternToRegExp(_39,_37);
+}
+}
+for(var i=0;i<_36.length;++i){
+var _3c=true;
+var _3d=_36[i];
+for(key in _32.query){
+_39=_32.query[key]+"";
+if(!this._containsValue(_3d,key,_39,_38[key])){
+_3c=false;
+}
+}
+if(_3c){
+_35.push(_3d);
+}
+}
+_33(_35,_32);
+}else{
+if(_36.length>0){
+_35=_36.slice(0,_36.length);
+}
+_33(_35,_32);
+}
+},getFeatures:function(){
+return {"dojo.data.api.Read":true,"dojo.data.api.Identity":true};
+},close:function(_3e){
+},getLabel:function(_3f){
+if(this.isItem(_3f)){
+return "Table Row #"+this.getIdentity(_3f);
+}
+return undefined;
+},getLabelAttributes:function(_40){
+return null;
+},getIdentity:function(_41){
+this._assertIsItem(_41);
+if(!dojo.isOpera){
+return _41.sectionRowIndex;
+}else{
+return (dojo.indexOf(this._rootNode.rows,_41)-1);
+}
+},getIdentityAttributes:function(_42){
+return null;
+},fetchItemByIdentity:function(_43){
+var _44=_43.identity;
+var _45=this;
+var _46=null;
+var _47=null;
+if(!this._rootNode){
+if(!this.url){
+this._rootNode=dojo.byId(this.tableId);
+this._getHeadings();
+for(var i=0;i<this._rootNode.rows.length;i++){
+this._rootNode.rows[i].store=this;
+}
+_46=this._rootNode.rows[_44+1];
+if(_43.onItem){
+_47=_43.scope?_43.scope:dojo.global;
+_43.onItem.call(_47,_46);
+}
+}else{
+var _49={url:this.url,handleAs:"text"};
+var _4a=dojo.xhrGet(_49);
+_4a.addCallback(function(_4b){
+var _4c=function(_4d,id){
+if(_4d.id==id){
+return _4d;
+}
+if(_4d.childNodes){
+for(var i=0;i<_4d.childNodes.length;i++){
+var _50=_4c(_4d.childNodes[i],id);
+if(_50){
+return _50;
+}
+}
+}
+return null;
+};
+var d=document.createElement("div");
+d.innerHTML=_4b;
+_45._rootNode=_4c(d,_45.tableId);
+_45._getHeadings.call(_45);
+for(var i=0;i<_45._rootNode.rows.length;i++){
+_45._rootNode.rows[i].store=_45;
+}
+_46=_45._rootNode.rows[_44+1];
+if(_43.onItem){
+_47=_43.scope?_43.scope:dojo.global;
+_43.onItem.call(_47,_46);
+}
+});
+_4a.addErrback(function(_53){
+if(_43.onError){
+_47=_43.scope?_43.scope:dojo.global;
+_43.onError.call(_47,_53);
+}
+});
+}
+}else{
+if(this._rootNode.rows[_44+1]){
+_46=this._rootNode.rows[_44+1];
+if(_43.onItem){
+_47=_43.scope?_43.scope:dojo.global;
+_43.onItem.call(_47,_46);
+}
+}
+}
+}});
+dojo.extend(dojox.data.HtmlTableStore,dojo.data.util.simpleFetch);
+}
diff --git a/dojox/data/ItemExplorer.js b/dojox/data/ItemExplorer.js
new file mode 100644
index 0000000..1c90e32
--- /dev/null
+++ b/dojox/data/ItemExplorer.js
@@ -0,0 +1,461 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.ItemExplorer"]){
+dojo._hasResource["dojox.data.ItemExplorer"]=true;
+dojo.provide("dojox.data.ItemExplorer");
+dojo.require("dijit.Tree");
+dojo.require("dijit.Dialog");
+dojo.require("dijit.Menu");
+dojo.require("dijit.form.ValidationTextBox");
+dojo.require("dijit.form.Textarea");
+dojo.require("dijit.form.Button");
+dojo.require("dijit.form.CheckBox");
+dojo.require("dijit.form.FilteringSelect");
+(function(){
+var _1=function(_2,_3,_4){
+var _5=_2.getValues(_3,_4);
+if(_5.length<2){
+_5=_2.getValue(_3,_4);
+}
+return _5;
+};
+dojo.declare("dojox.data.ItemExplorer",dijit.Tree,{useSelect:false,refSelectSearchAttr:null,constructor:function(_6){
+dojo.mixin(this,_6);
+var _7=this;
+var _8={};
+var _9=this.rootModelNode={value:_8,id:"root"};
+this._modelNodeIdMap={};
+this._modelNodePropMap={};
+var _a=1;
+this.model={getRoot:function(_b){
+_b(_9);
+},mayHaveChildren:function(_c){
+return _c.value&&typeof _c.value=="object"&&!(_c.value instanceof Date);
+},getChildren:function(_d,_e,_f){
+var _10,_11,_12=_d.value;
+var _13=[];
+if(_12==_8){
+_e([]);
+return;
+}
+var _14=_7.store&&_7.store.isItem(_12,true);
+if(_14&&!_7.store.isItemLoaded(_12)){
+_7.store.loadItem({item:_12,onItem:function(_15){
+_12=_15;
+_16();
+}});
+}else{
+_16();
+}
+function _16(){
+if(_14){
+_10=_7.store.getAttributes(_12);
+_11=_12;
+}else{
+if(_12&&typeof _12=="object"){
+_11=_d.value;
+_10=[];
+for(var i in _12){
+if(_12.hasOwnProperty(i)&&i!="__id"&&i!="__clientId"){
+_10.push(i);
+}
+}
+}
+}
+if(_10){
+for(var key,k=0;key=_10[k++];){
+_13.push({property:key,value:_14?_1(_7.store,_12,key):_12[key],parent:_11});
+}
+_13.push({addNew:true,parent:_11,parentNode:_d});
+}
+_e(_13);
+};
+},getIdentity:function(_1a){
+if(!_1a.id){
+if(_1a.addNew){
+_1a.property="--addNew";
+}
+_1a.id=_a++;
+if(_7.store){
+if(_7.store.isItem(_1a.value)){
+var _1b=_7.store.getIdentity(_1a.value);
+(_7._modelNodeIdMap[_1b]=_7._modelNodeIdMap[_1b]||[]).push(_1a);
+}
+if(_1a.parent){
+_1b=_7.store.getIdentity(_1a.parent)+"."+_1a.property;
+(_7._modelNodePropMap[_1b]=_7._modelNodePropMap[_1b]||[]).push(_1a);
+}
+}
+}
+return _1a.id;
+},getLabel:function(_1c){
+return _1c===_9?"Object Properties":_1c.addNew?(_1c.parent instanceof Array?"Add new value":"Add new property"):_1c.property+": "+(_1c.value instanceof Array?"("+_1c.value.length+" elements)":_1c.value);
+},onChildrenChange:function(_1d){
+},onChange:function(_1e){
+}};
+},postCreate:function(){
+this.inherited(arguments);
+dojo.connect(this,"onClick",function(_1f,_20){
+this.lastFocused=_20;
+if(_1f.addNew){
+this._addProperty();
+}else{
+this._editProperty();
+}
+});
+var _21=new dijit.Menu({targetNodeIds:[this.rootNode.domNode],id:"contextMenu"});
+dojo.connect(_21,"_openMyself",this,function(e){
+var _23=dijit.getEnclosingWidget(e.target);
+if(_23){
+var _24=_23.item;
+if(this.store.isItem(_24.value,true)&&!_24.parent){
+_21.getChildren().forEach(function(_25){
+_25.attr("disabled",(_25.label!="Add"));
+});
+this.lastFocused=_23;
+}else{
+if(_24.value&&typeof _24.value=="object"&&!(_24.value instanceof Date)){
+_21.getChildren().forEach(function(_26){
+_26.attr("disabled",(_26.label!="Add")&&(_26.label!="Delete"));
+});
+this.lastFocused=_23;
+}else{
+if(_24.property&&dojo.indexOf(this.store.getIdentityAttributes(),_24.property)>=0){
+this.focusNode(_23);
+alert("Cannot modify an Identifier node.");
+}else{
+if(_24.addNew){
+this.focusNode(_23);
+}else{
+_21.getChildren().forEach(function(_27){
+_27.attr("disabled",(_27.label!="Edit")&&(_27.label!="Delete"));
+});
+this.lastFocused=_23;
+}
+}
+}
+}
+}
+});
+_21.addChild(new dijit.MenuItem({label:"Add",onClick:dojo.hitch(this,"_addProperty")}));
+_21.addChild(new dijit.MenuItem({label:"Edit",onClick:dojo.hitch(this,"_editProperty")}));
+_21.addChild(new dijit.MenuItem({label:"Delete",onClick:dojo.hitch(this,"_destroyProperty")}));
+_21.startup();
+},store:null,setStore:function(_28){
+this.store=_28;
+var _29=this;
+if(this._editDialog){
+this._editDialog.destroyRecursive();
+delete this._editDialog;
+}
+dojo.connect(_28,"onSet",function(_2a,_2b,_2c,_2d){
+var _2e,i,_30=_29.store.getIdentity(_2a);
+_2e=_29._modelNodeIdMap[_30];
+if(_2e&&(_2c===undefined||_2d===undefined||_2c instanceof Array||_2d instanceof Array||typeof _2c=="object"||typeof _2d=="object")){
+for(i=0;i<_2e.length;i++){
+(function(_31){
+_29.model.getChildren(_31,function(_32){
+_29.model.onChildrenChange(_31,_32);
+});
+})(_2e[i]);
+}
+}
+_2e=_29._modelNodePropMap[_30+"."+_2b];
+if(_2e){
+for(i=0;i<_2e.length;i++){
+_2e[i].value=_2d;
+_29.model.onChange(_2e[i]);
+}
+}
+});
+this.rootNode.setChildItems([]);
+},setItem:function(_33){
+(this._modelNodeIdMap={})[this.store.getIdentity(_33)]=[this.rootModelNode];
+this._modelNodePropMap={};
+this.rootModelNode.value=_33;
+var _34=this;
+this.model.getChildren(this.rootModelNode,function(_35){
+_34.rootNode.setChildItems(_35);
+});
+},refreshItem:function(){
+this.setItem(this.rootModelNode.value);
+},_createEditDialog:function(){
+this._editDialog=new dijit.Dialog({title:"Edit Property",execute:dojo.hitch(this,"_updateItem"),preload:true});
+this._editDialog.placeAt(dojo.body());
+this._editDialog.startup();
+var _36=dojo.doc.createElement("div");
+var _37=dojo.doc.createElement("label");
+dojo.attr(_37,"for","property");
+dojo.style(_37,"fontWeight","bold");
+dojo.attr(_37,"innerHTML","Property:");
+_36.appendChild(_37);
+var _38=new dijit.form.ValidationTextBox({name:"property",value:"",required:true,disabled:true}).placeAt(_36);
+_36.appendChild(dojo.doc.createElement("br"));
+_36.appendChild(dojo.doc.createElement("br"));
+var _39=new dijit.form.RadioButton({name:"itemType",value:"value",onClick:dojo.hitch(this,function(){
+this._enableFields("value");
+})}).placeAt(_36);
+var _3a=dojo.doc.createElement("label");
+dojo.attr(_3a,"for","value");
+dojo.attr(_3a,"innerHTML","Value (JSON):");
+_36.appendChild(_3a);
+var _3b=dojo.doc.createElement("div");
+dojo.addClass(_3b,"value");
+var _3c=new dijit.form.Textarea({name:"jsonVal"}).placeAt(_3b);
+_36.appendChild(_3b);
+var _3d=new dijit.form.RadioButton({name:"itemType",value:"reference",onClick:dojo.hitch(this,function(){
+this._enableFields("reference");
+})}).placeAt(_36);
+var _3e=dojo.doc.createElement("label");
+dojo.attr(_3e,"for","_reference");
+dojo.attr(_3e,"innerHTML","Reference (ID):");
+_36.appendChild(_3e);
+_36.appendChild(dojo.doc.createElement("br"));
+var _3f=dojo.doc.createElement("div");
+dojo.addClass(_3f,"reference");
+if(this.useSelect){
+var _40=new dijit.form.FilteringSelect({name:"_reference",store:this.store,searchAttr:this.refSelectSearchAttr||this.store.getIdentityAttributes()[0],required:false,value:null,pageSize:10}).placeAt(_3f);
+}else{
+var _41=new dijit.form.ValidationTextBox({name:"_reference",value:"",promptMessage:"Enter the ID of the item to reference",isValid:dojo.hitch(this,function(_42){
+return true;
+})}).placeAt(_3f);
+}
+_36.appendChild(_3f);
+_36.appendChild(dojo.doc.createElement("br"));
+_36.appendChild(dojo.doc.createElement("br"));
+var _43=document.createElement("div");
+_43.setAttribute("dir","rtl");
+var _44=new dijit.form.Button({type:"reset",label:"Cancel"}).placeAt(_43);
+_44.onClick=dojo.hitch(this._editDialog,"onCancel");
+var _45=new dijit.form.Button({type:"submit",label:"OK"}).placeAt(_43);
+_36.appendChild(_43);
+this._editDialog.attr("content",_36);
+},_enableFields:function(_46){
+switch(_46){
+case "reference":
+dojo.query(".value [widgetId]",this._editDialog.containerNode).forEach(function(_47){
+dijit.getEnclosingWidget(_47).attr("disabled",true);
+});
+dojo.query(".reference [widgetId]",this._editDialog.containerNode).forEach(function(_48){
+dijit.getEnclosingWidget(_48).attr("disabled",false);
+});
+break;
+case "value":
+dojo.query(".value [widgetId]",this._editDialog.containerNode).forEach(function(_49){
+dijit.getEnclosingWidget(_49).attr("disabled",false);
+});
+dojo.query(".reference [widgetId]",this._editDialog.containerNode).forEach(function(_4a){
+dijit.getEnclosingWidget(_4a).attr("disabled",true);
+});
+break;
+}
+},_updateItem:function(_4b){
+var _4c,_4d,val,_4f,_50=this._editDialog.attr("title")=="Edit Property";
+var _51=this._editDialog;
+var _52=this.store;
+function _53(){
+try{
+var _54,_55=[];
+var _56=_4b.property;
+if(_50){
+while(!_52.isItem(_4d.parent,true)){
+_4c=_4c.getParent();
+_55.push(_4d.property);
+_4d=_4c.item;
+}
+if(_55.length==0){
+_52.setValue(_4d.parent,_4d.property,val);
+}else{
+_4f=_1(_52,_4d.parent,_4d.property);
+if(_4f instanceof Array){
+_4f=_4f.concat();
+}
+_54=_4f;
+while(_55.length>1){
+_54=_54[_55.pop()];
+}
+_54[_55]=val;
+_52.setValue(_4d.parent,_4d.property,_4f);
+}
+}else{
+if(_52.isItem(_57,true)){
+if(!_52.isItemLoaded(_57)){
+_52.loadItem({item:_57,onItem:function(_58){
+if(_58 instanceof Array){
+_56=_58.length;
+}
+_52.setValue(_58,_56,val);
+}});
+}else{
+if(_57 instanceof Array){
+_56=_57.length;
+}
+_52.setValue(_57,_56,val);
+}
+}else{
+if(_4d.value instanceof Array){
+_55.push(_4d.value.length);
+}else{
+_55.push(_4b.property);
+}
+while(!_52.isItem(_4d.parent,true)){
+_4c=_4c.getParent();
+_55.push(_4d.property);
+_4d=_4c.item;
+}
+_4f=_1(_52,_4d.parent,_4d.property);
+_54=_4f;
+while(_55.length>1){
+_54=_54[_55.pop()];
+}
+_54[_55]=val;
+_52.setValue(_4d.parent,_4d.property,_4f);
+}
+}
+}
+catch(e){
+alert(e);
+}
+};
+if(_51.validate()){
+_4c=this.lastFocused;
+_4d=_4c.item;
+var _57=_4d.value;
+if(_4d.addNew){
+_57=_4c.item.parent;
+_4c=_4c.getParent();
+_4d=_4c.item;
+}
+val=null;
+switch(_4b.itemType){
+case "reference":
+this.store.fetchItemByIdentity({identity:_4b._reference,onItem:function(_59){
+val=_59;
+_53();
+},onError:function(){
+alert("The id could not be found");
+}});
+break;
+case "value":
+var _5a=_4b.jsonVal;
+val=dojo.fromJson(_5a);
+if(typeof val=="function"){
+val.toString=function(){
+return _5a;
+};
+}
+_53();
+break;
+}
+}else{
+_51.show();
+}
+},_editProperty:function(){
+var _5b=dojo.mixin({},this.lastFocused.item);
+if(!this._editDialog){
+this._createEditDialog();
+}else{
+this._editDialog.reset();
+}
+if(dojo.indexOf(this.store.getIdentityAttributes(),_5b.property)>=0){
+alert("Cannot Edit an Identifier!");
+}else{
+this._editDialog.attr("title","Edit Property");
+dijit.getEnclosingWidget(dojo.query("input",this._editDialog.containerNode)[0]).attr("disabled",true);
+if(this.store.isItem(_5b.value,true)){
+if(_5b.parent){
+_5b.itemType="reference";
+this._enableFields(_5b.itemType);
+_5b._reference=this.store.getIdentity(_5b.value);
+this._editDialog.attr("value",_5b);
+this._editDialog.show();
+}
+}else{
+if(_5b.value&&typeof _5b.value=="object"&&!(_5b.value instanceof Date)){
+}else{
+_5b.itemType="value";
+this._enableFields(_5b.itemType);
+_5b.jsonVal=typeof _5b.value=="function"?_5b.value.toString():_5b.value instanceof Date?"new Date(\""+_5b.value+"\")":dojo.toJson(_5b.value);
+this._editDialog.attr("value",_5b);
+this._editDialog.show();
+}
+}
+}
+},_destroyProperty:function(){
+var _5c=this.lastFocused;
+var _5d=_5c.item;
+var _5e=[];
+while(!this.store.isItem(_5d.parent,true)||_5d.parent instanceof Array){
+_5c=_5c.getParent();
+_5e.push(_5d.property);
+_5d=_5c.item;
+}
+if(dojo.indexOf(this.store.getIdentityAttributes(),_5d.property)>=0){
+alert("Cannot Delete an Identifier!");
+}else{
+try{
+if(_5e.length>0){
+var _5f,_60=_1(this.store,_5d.parent,_5d.property);
+_5f=_60;
+while(_5e.length>1){
+_5f=_5f[_5e.pop()];
+}
+if(dojo.isArray(_5f)){
+_5f.splice(_5e,1);
+}else{
+delete _5f[_5e];
+}
+this.store.setValue(_5d.parent,_5d.property,_60);
+}else{
+this.store.unsetAttribute(_5d.parent,_5d.property);
+}
+}
+catch(e){
+alert(e);
+}
+}
+},_addProperty:function(){
+var _61=this.lastFocused.item;
+var _62=_61.value;
+var _63=dojo.hitch(this,function(){
+var _64=null;
+if(!this._editDialog){
+this._createEditDialog();
+}else{
+this._editDialog.reset();
+}
+if(_62 instanceof Array){
+_64=_62.length;
+dijit.getEnclosingWidget(dojo.query("input",this._editDialog.containerNode)[0]).attr("disabled",true);
+}else{
+dijit.getEnclosingWidget(dojo.query("input",this._editDialog.containerNode)[0]).attr("disabled",false);
+}
+this._editDialog.attr("title","Add Property");
+this._enableFields("value");
+this._editDialog.attr("value",{itemType:"value",property:_64});
+this._editDialog.show();
+});
+if(_61.addNew){
+_61=this.lastFocused.getParent().item;
+_62=this.lastFocused.item.parent;
+}
+if(_61.property&&dojo.indexOf(this.store.getIdentityAttributes(),_61.property)>=0){
+alert("Cannot add properties to an ID node!");
+}else{
+if(this.store.isItem(_62,true)&&!this.store.isItemLoaded(_62)){
+this.store.loadItem({item:_62,onItem:function(_65){
+_62=_65;
+_63();
+}});
+}else{
+_63();
+}
+}
+}});
+})();
+}
diff --git a/dojox/data/JsonQueryRestStore.js b/dojox/data/JsonQueryRestStore.js
new file mode 100644
index 0000000..9a96ef1
--- /dev/null
+++ b/dojox/data/JsonQueryRestStore.js
@@ -0,0 +1,17 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.JsonQueryRestStore"]){
+dojo._hasResource["dojox.data.JsonQueryRestStore"]=true;
+dojo.provide("dojox.data.JsonQueryRestStore");
+dojo.require("dojox.data.JsonRestStore");
+dojo.require("dojox.data.util.JsonQuery");
+dojo.requireIf(!!dojox.data.ClientFilter,"dojox.json.query");
+dojo.declare("dojox.data.JsonQueryRestStore",[dojox.data.JsonRestStore,dojox.data.util.JsonQuery],{matchesQuery:function(_1,_2){
+return _1.__id&&(_1.__id.indexOf("#")==-1)&&this.inherited(arguments);
+}});
+}
diff --git a/dojox/data/JsonRestStore.js b/dojox/data/JsonRestStore.js
new file mode 100644
index 0000000..55929f1
--- /dev/null
+++ b/dojox/data/JsonRestStore.js
@@ -0,0 +1,195 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.JsonRestStore"]){
+dojo._hasResource["dojox.data.JsonRestStore"]=true;
+dojo.provide("dojox.data.JsonRestStore");
+dojo.require("dojox.data.ServiceStore");
+dojo.require("dojox.rpc.JsonRest");
+dojo.declare("dojox.data.JsonRestStore",dojox.data.ServiceStore,{constructor:function(_1){
+dojo.connect(dojox.rpc.Rest._index,"onUpdate",this,function(_2,_3,_4,_5){
+var _6=this.service.servicePath;
+if(!_2.__id){
+
+}else{
+if(_2.__id.substring(0,_6.length)==_6){
+this.onSet(_2,_3,_4,_5);
+}
+}
+});
+this.idAttribute=this.idAttribute||"id";
+if(typeof _1.target=="string"&&!this.service){
+this.service=dojox.rpc.Rest(this.target,true);
+}
+dojox.rpc.JsonRest.registerService(this.service,_1.target,this.schema);
+this.schema=this.service._schema=this.schema||this.service._schema||{};
+this.service._store=this;
+this.schema._idAttr=this.idAttribute;
+var _7=dojox.rpc.JsonRest.getConstructor(this.service);
+var _8=this;
+this._constructor=function(_9){
+_7.call(this,_9);
+_8.onNew(this);
+};
+this._constructor.prototype=_7.prototype;
+this._index=dojox.rpc.Rest._index;
+},referenceIntegrity:true,target:"",newItem:function(_a,_b){
+_a=new this._constructor(_a);
+if(_b){
+var _c=this.getValue(_b.parent,_b.attribute,[]);
+this.setValue(_b.parent,_b.attribute,_c.concat([_a]));
+}
+return _a;
+},deleteItem:function(_d){
+var _e=[];
+var _f=dojox.data._getStoreForItem(_d)||this;
+if(this.referenceIntegrity){
+dojox.rpc.JsonRest._saveNotNeeded=true;
+var _10=dojox.rpc.Rest._index;
+var _11=function(_12){
+var _13;
+_e.push(_12);
+_12.__checked=1;
+for(var i in _12){
+var _15=_12[i];
+if(_15==_d){
+if(_12!=_10){
+if(_12 instanceof Array){
+(_13=_13||[]).push(i);
+}else{
+(dojox.data._getStoreForItem(_12)||_f).unsetAttribute(_12,i);
+}
+}
+}else{
+if((typeof _15=="object")&&_15){
+if(!_15.__checked){
+_11(_15);
+}
+if(typeof _15.__checked=="object"&&_12!=_10){
+(dojox.data._getStoreForItem(_12)||_f).setValue(_12,i,_15.__checked);
+}
+}
+}
+}
+if(_13){
+i=_13.length;
+_12=_12.__checked=_12.concat();
+while(i--){
+_12.splice(_13[i],1);
+}
+return _12;
+}
+return null;
+};
+_11(_10);
+dojox.rpc.JsonRest._saveNotNeeded=false;
+var i=0;
+while(_e[i]){
+delete _e[i++].__checked;
+}
+}
+dojox.rpc.JsonRest.deleteObject(_d);
+_f.onDelete(_d);
+},changing:function(_17,_18){
+dojox.rpc.JsonRest.changing(_17,_18);
+},setValue:function(_19,_1a,_1b){
+var old=_19[_1a];
+var _1d=_19.__id?dojox.data._getStoreForItem(_19):this;
+if(dojox.json.schema&&_1d.schema&&_1d.schema.properties){
+dojox.json.schema.mustBeValid(dojox.json.schema.checkPropertyChange(_1b,_1d.schema.properties[_1a]));
+}
+if(_1a==_1d.idAttribute){
+throw new Error("Can not change the identity attribute for an item");
+}
+_1d.changing(_19);
+_19[_1a]=_1b;
+_1d.onSet(_19,_1a,old,_1b);
+},setValues:function(_1e,_1f,_20){
+if(!dojo.isArray(_20)){
+throw new Error("setValues expects to be passed an Array object as its value");
+}
+this.setValue(_1e,_1f,_20);
+},unsetAttribute:function(_21,_22){
+this.changing(_21);
+var old=_21[_22];
+delete _21[_22];
+this.onSet(_21,_22,old,undefined);
+},save:function(_24){
+if(!(_24&&_24.global)){
+(_24=_24||{}).service=this.service;
+}
+var _25=dojox.rpc.JsonRest.commit(_24);
+this.serverVersion=this._updates&&this._updates.length;
+return _25;
+},revert:function(_26){
+var _27=dojox.rpc.JsonRest.getDirtyObjects().concat([]);
+while(_27.length>0){
+var d=_27.pop();
+var _29=dojox.data._getStoreForItem(d.object||d.old);
+if(!d.object){
+_29.onNew(d.old);
+}else{
+if(!d.old){
+_29.onDelete(d.object);
+}else{
+for(var i in d.object){
+if(d.object[i]!=d.old[i]){
+_29.onSet(d.object,i,d.object[i],d.old[i]);
+}
+}
+}
+}
+}
+dojox.rpc.JsonRest.revert(_26&&_26.global&&this.service);
+},isDirty:function(_2b){
+return dojox.rpc.JsonRest.isDirty(_2b);
+},isItem:function(_2c,_2d){
+return _2c&&_2c.__id&&(_2d||this.service==dojox.rpc.JsonRest.getServiceAndId(_2c.__id).service);
+},_doQuery:function(_2e){
+var _2f=typeof _2e.queryStr=="string"?_2e.queryStr:_2e.query;
+return dojox.rpc.JsonRest.query(this.service,_2f,_2e);
+},_processResults:function(_30,_31){
+var _32=_30.length;
+return {totalCount:_31.fullLength||(_31.request.count==_32?(_31.request.start||0)+_32*2:_32),items:_30};
+},getConstructor:function(){
+return this._constructor;
+},getIdentity:function(_33){
+var id=_33.__clientId||_33.__id;
+if(!id){
+return id;
+}
+var _35=this.service.servicePath;
+return id.substring(0,_35.length)!=_35?id:id.substring(_35.length);
+},fetchItemByIdentity:function(_36){
+var id=_36.identity;
+var _38=this;
+if(id.toString().match(/^(\w*:)?\//)){
+var _39=dojox.rpc.JsonRest.getServiceAndId(id);
+_38=_39.service._store;
+_36.identity=_39.id;
+}
+_36._prefix=_38.service.servicePath;
+return _38.inherited(arguments);
+},onSet:function(){
+},onNew:function(){
+},onDelete:function(){
+},getFeatures:function(){
+var _3a=this.inherited(arguments);
+_3a["dojo.data.api.Write"]=true;
+_3a["dojo.data.api.Notification"]=true;
+return _3a;
+}});
+dojox.data._getStoreForItem=function(_3b){
+if(_3b.__id){
+var _3c=_3b.__id.toString().match(/.*\//)[0];
+var _3d=dojox.rpc.JsonRest.services[_3c];
+return _3d?_3d._store:new dojox.data.JsonRestStore({target:_3c});
+}
+return null;
+};
+dojox.json.ref._useRefs=true;
+}
diff --git a/dojox/data/KeyValueStore.js b/dojox/data/KeyValueStore.js
new file mode 100644
index 0000000..dec80ab
--- /dev/null
+++ b/dojox/data/KeyValueStore.js
@@ -0,0 +1,222 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.KeyValueStore"]){
+dojo._hasResource["dojox.data.KeyValueStore"]=true;
+dojo.provide("dojox.data.KeyValueStore");
+dojo.require("dojo.data.util.filter");
+dojo.require("dojo.data.util.simpleFetch");
+dojo.declare("dojox.data.KeyValueStore",null,{constructor:function(_1){
+if(_1.url){
+this.url=_1.url;
+}
+this._keyValueString=_1.data;
+this._keyValueVar=_1.dataVar;
+this._keyAttribute="key";
+this._valueAttribute="value";
+this._storeProp="_keyValueStore";
+this._features={"dojo.data.api.Read":true,"dojo.data.api.Identity":true};
+this._loadInProgress=false;
+this._queuedFetches=[];
+},url:"",data:"",_assertIsItem:function(_2){
+if(!this.isItem(_2)){
+throw new Error("dojox.data.KeyValueStore: a function was passed an item argument that was not an item");
+}
+},_assertIsAttribute:function(_3,_4){
+if(!dojo.isString(_4)){
+throw new Error("dojox.data.KeyValueStore: a function was passed an attribute argument that was not an attribute object nor an attribute name string");
+}
+},getValue:function(_5,_6,_7){
+this._assertIsItem(_5);
+this._assertIsAttribute(_5,_6);
+var _8;
+if(_6==this._keyAttribute){
+_8=_5[this._keyAttribute];
+}else{
+_8=_5[this._valueAttribute];
+}
+if(_8===undefined){
+_8=_7;
+}
+return _8;
+},getValues:function(_9,_a){
+var _b=this.getValue(_9,_a);
+return (_b?[_b]:[]);
+},getAttributes:function(_c){
+return [this._keyAttribute,this._valueAttribute,_c[this._keyAttribute]];
+},hasAttribute:function(_d,_e){
+this._assertIsItem(_d);
+this._assertIsAttribute(_d,_e);
+return (_e==this._keyAttribute||_e==this._valueAttribute||_e==_d[this._keyAttribute]);
+},containsValue:function(_f,_10,_11){
+var _12=undefined;
+if(typeof _11==="string"){
+_12=dojo.data.util.filter.patternToRegExp(_11,false);
+}
+return this._containsValue(_f,_10,_11,_12);
+},_containsValue:function(_13,_14,_15,_16){
+var _17=this.getValues(_13,_14);
+for(var i=0;i<_17.length;++i){
+var _19=_17[i];
+if(typeof _19==="string"&&_16){
+return (_19.match(_16)!==null);
+}else{
+if(_15===_19){
+return true;
+}
+}
+}
+return false;
+},isItem:function(_1a){
+if(_1a&&_1a[this._storeProp]===this){
+return true;
+}
+return false;
+},isItemLoaded:function(_1b){
+return this.isItem(_1b);
+},loadItem:function(_1c){
+},getFeatures:function(){
+return this._features;
+},close:function(_1d){
+},getLabel:function(_1e){
+return _1e[this._keyAttribute];
+},getLabelAttributes:function(_1f){
+return [this._keyAttribute];
+},_fetchItems:function(_20,_21,_22){
+var _23=this;
+var _24=function(_25,_26){
+var _27=null;
+if(_25.query){
+_27=[];
+var _28=_25.queryOptions?_25.queryOptions.ignoreCase:false;
+var _29={};
+for(var key in _25.query){
+var _2b=_25.query[key];
+if(typeof _2b==="string"){
+_29[key]=dojo.data.util.filter.patternToRegExp(_2b,_28);
+}
+}
+for(var i=0;i<_26.length;++i){
+var _2d=true;
+var _2e=_26[i];
+for(var key in _25.query){
+var _2b=_25.query[key];
+if(!_23._containsValue(_2e,key,_2b,_29[key])){
+_2d=false;
+}
+}
+if(_2d){
+_27.push(_2e);
+}
+}
+}else{
+if(_25.identity){
+_27=[];
+var _2f;
+for(var key in _26){
+_2f=_26[key];
+if(_2f[_23._keyAttribute]==_25.identity){
+_27.push(_2f);
+break;
+}
+}
+}else{
+if(_26.length>0){
+_27=_26.slice(0,_26.length);
+}
+}
+}
+_21(_27,_25);
+};
+if(this._loadFinished){
+_24(_20,this._arrayOfAllItems);
+}else{
+if(this.url!==""){
+if(this._loadInProgress){
+this._queuedFetches.push({args:_20,filter:_24});
+}else{
+this._loadInProgress=true;
+var _30={url:_23.url,handleAs:"json-comment-filtered"};
+var _31=dojo.xhrGet(_30);
+_31.addCallback(function(_32){
+_23._processData(_32);
+_24(_20,_23._arrayOfAllItems);
+_23._handleQueuedFetches();
+});
+_31.addErrback(function(_33){
+_23._loadInProgress=false;
+throw _33;
+});
+}
+}else{
+if(this._keyValueString){
+this._processData(eval(this._keyValueString));
+this._keyValueString=null;
+_24(_20,this._arrayOfAllItems);
+}else{
+if(this._keyValueVar){
+this._processData(this._keyValueVar);
+this._keyValueVar=null;
+_24(_20,this._arrayOfAllItems);
+}else{
+throw new Error("dojox.data.KeyValueStore: No source data was provided as either URL, String, or Javascript variable data input.");
+}
+}
+}
+}
+},_handleQueuedFetches:function(){
+if(this._queuedFetches.length>0){
+for(var i=0;i<this._queuedFetches.length;i++){
+var _35=this._queuedFetches[i];
+var _36=_35.filter;
+var _37=_35.args;
+if(_36){
+_36(_37,this._arrayOfAllItems);
+}else{
+this.fetchItemByIdentity(_35.args);
+}
+}
+this._queuedFetches=[];
+}
+},_processData:function(_38){
+this._arrayOfAllItems=[];
+for(var i=0;i<_38.length;i++){
+this._arrayOfAllItems.push(this._createItem(_38[i]));
+}
+this._loadFinished=true;
+this._loadInProgress=false;
+},_createItem:function(_3a){
+var _3b={};
+_3b[this._storeProp]=this;
+for(var i in _3a){
+_3b[this._keyAttribute]=i;
+_3b[this._valueAttribute]=_3a[i];
+break;
+}
+return _3b;
+},getIdentity:function(_3d){
+if(this.isItem(_3d)){
+return _3d[this._keyAttribute];
+}
+return null;
+},getIdentityAttributes:function(_3e){
+return [this._keyAttribute];
+},fetchItemByIdentity:function(_3f){
+_3f.oldOnItem=_3f.onItem;
+_3f.onItem=null;
+_3f.onComplete=this._finishFetchItemByIdentity;
+this.fetch(_3f);
+},_finishFetchItemByIdentity:function(_40,_41){
+var _42=_41.scope||dojo.global;
+if(_40.length){
+_41.oldOnItem.call(_42,_40[0]);
+}else{
+_41.oldOnItem.call(_42,null);
+}
+}});
+dojo.extend(dojox.data.KeyValueStore,dojo.data.util.simpleFetch);
+}
diff --git a/dojox/data/OpenSearchStore.js b/dojox/data/OpenSearchStore.js
new file mode 100644
index 0000000..1bec283
--- /dev/null
+++ b/dojox/data/OpenSearchStore.js
@@ -0,0 +1,216 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.OpenSearchStore"]){
+dojo._hasResource["dojox.data.OpenSearchStore"]=true;
+dojo.provide("dojox.data.OpenSearchStore");
+dojo.require("dojo.data.util.simpleFetch");
+dojo.require("dojox.xml.DomParser");
+dojo.require("dojox.xml.parser");
+dojo.experimental("dojox.data.OpenSearchStore");
+dojo.declare("dojox.data.OpenSearchStore",null,{constructor:function(_1){
+if(_1){
+this.label=_1.label;
+this.url=_1.url;
+this.itemPath=_1.itemPath;
+}
+var _2=dojo.xhrGet({url:this.url,handleAs:"xml",sync:true});
+_2.addCallback(this,"_processOsdd");
+_2.addErrback(function(){
+throw new Error("Unable to load OpenSearch Description document from ".args.url);
+});
+},url:"",itemPath:"",_storeRef:"_S",urlElement:null,iframeElement:null,ATOM_CONTENT_TYPE:3,ATOM_CONTENT_TYPE_STRING:"atom",RSS_CONTENT_TYPE:2,RSS_CONTENT_TYPE_STRING:"rss",XML_CONTENT_TYPE:1,XML_CONTENT_TYPE_STRING:"xml",_assertIsItem:function(_3){
+if(!this.isItem(_3)){
+throw new Error("dojox.data.OpenSearchStore: a function was passed an item argument that was not an item");
+}
+},_assertIsAttribute:function(_4){
+if(typeof _4!=="string"){
+throw new Error("dojox.data.OpenSearchStore: a function was passed an attribute argument that was not an attribute name string");
+}
+},getFeatures:function(){
+return {"dojo.data.api.Read":true};
+},getValue:function(_5,_6,_7){
+var _8=this.getValues(_5,_6);
+if(_8){
+return _8[0];
+}
+return _7;
+},getAttributes:function(_9){
+return ["content"];
+},hasAttribute:function(_a,_b){
+if(this.getValue(_a,_b)){
+return true;
+}
+return false;
+},isItemLoaded:function(_c){
+return this.isItem(_c);
+},loadItem:function(_d){
+},getLabel:function(_e){
+return undefined;
+},getLabelAttributes:function(_f){
+return null;
+},containsValue:function(_10,_11,_12){
+var _13=this.getValues(_10,_11);
+for(var i=0;i<_13.length;i++){
+if(_13[i]===_12){
+return true;
+}
+}
+return false;
+},getValues:function(_15,_16){
+this._assertIsItem(_15);
+this._assertIsAttribute(_16);
+var _17=this.processItem(_15,_16);
+if(_17){
+return [_17];
+}
+return undefined;
+},isItem:function(_18){
+if(_18&&_18[this._storeRef]===this){
+return true;
+}
+return false;
+},close:function(_19){
+},process:function(_1a){
+return this["_processOSD"+this.contentType](_1a);
+},processItem:function(_1b,_1c){
+return this["_processItem"+this.contentType](_1b.node,_1c);
+},_createSearchUrl:function(_1d){
+var _1e=this.urlElement.attributes.getNamedItem("template").nodeValue;
+var _1f=this.urlElement.attributes;
+var _20=_1e.indexOf("{searchTerms}");
+_1e=_1e.substring(0,_20)+_1d.query.searchTerms+_1e.substring(_20+13);
+dojo.forEach([{"name":"count","test":_1d.count,"def":"10"},{"name":"startIndex","test":_1d.start,"def":this.urlElement.attributes.getNamedItem("indexOffset")?this.urlElement.attributes.getNamedItem("indexOffset").nodeValue:0},{"name":"startPage","test":_1d.startPage,"def":this.urlElement.attributes.getNamedItem("pageOffset")?this.urlElement.attributes.getNamedItem("pageOffset").nodeValue:0},{"name":"language","test":_1d.language,"def":"*"},{"name":"inputEncoding","test":_1d.inputEncoding [...]
+_1e=_1e.replace("{"+_21.name+"}",_21.test||_21.def);
+_1e=_1e.replace("{"+_21.name+"?}",_21.test||_21.def);
+});
+return _1e;
+},_fetchItems:function(_22,_23,_24){
+if(!_22.query){
+_22.query={};
+}
+var _25=this;
+var url=this._createSearchUrl(_22);
+var _27={url:url,preventCache:true};
+var xhr=dojo.xhrGet(_27);
+xhr.addErrback(function(_29){
+_24(_29,_22);
+});
+xhr.addCallback(function(_2a){
+var _2b=[];
+if(_2a){
+_2b=_25.process(_2a);
+for(var i=0;i<_2b.length;i++){
+_2b[i]={node:_2b[i]};
+_2b[i][_25._storeRef]=_25;
+}
+}
+_23(_2b,_22);
+});
+},_processOSDxml:function(_2d){
+var div=dojo.doc.createElement("div");
+div.innerHTML=_2d;
+return dojo.query(this.itemPath,div);
+},_processItemxml:function(_2f,_30){
+if(_30==="content"){
+return _2f.innerHTML;
+}
+return undefined;
+},_processOSDatom:function(_31){
+return this._processOSDfeed(_31,"entry");
+},_processItematom:function(_32,_33){
+return this._processItemfeed(_32,_33,"content");
+},_processOSDrss:function(_34){
+return this._processOSDfeed(_34,"item");
+},_processItemrss:function(_35,_36){
+return this._processItemfeed(_35,_36,"description");
+},_processOSDfeed:function(_37,_38){
+_37=dojox.xml.parser.parse(_37);
+var _39=[];
+var _3a=_37.getElementsByTagName(_38);
+for(var i=0;i<_3a.length;i++){
+_39.push(_3a.item(i));
+}
+return _39;
+},_processItemfeed:function(_3c,_3d,_3e){
+if(_3d==="content"){
+var _3f=_3c.getElementsByTagName(_3e).item(0);
+return this._getNodeXml(_3f,true);
+}
+return undefined;
+},_getNodeXml:function(_40,_41){
+var i;
+switch(_40.nodeType){
+case 1:
+var xml=[];
+if(!_41){
+xml.push("<"+_40.tagName);
+var _44;
+for(i=0;i<_40.attributes.length;i++){
+_44=_40.attributes.item(i);
+xml.push(" "+_44.nodeName+"=\""+_44.nodeValue+"\"");
+}
+xml.push(">");
+}
+for(i=0;i<_40.childNodes.length;i++){
+xml.push(this._getNodeXml(_40.childNodes.item(i)));
+}
+if(!_41){
+xml.push("</"+_40.tagName+">\n");
+}
+return xml.join("");
+case 3:
+case 4:
+return _40.nodeValue;
+}
+return undefined;
+},_processOsdd:function(doc){
+var _46=doc.getElementsByTagName("Url");
+var _47=[];
+var _48;
+var i;
+for(i=0;i<_46.length;i++){
+_48=_46[i].attributes.getNamedItem("type").nodeValue;
+switch(_48){
+case "application/rss+xml":
+_47[i]=this.RSS_CONTENT_TYPE;
+break;
+case "application/atom+xml":
+_47[i]=this.ATOM_CONTENT_TYPE;
+break;
+default:
+_47[i]=this.XML_CONTENT_TYPE;
+break;
+}
+}
+var _4a=0;
+var _4b=_47[0];
+for(i=1;i<_46.length;i++){
+if(_47[i]>_4b){
+_4a=i;
+_4b=_47[i];
+}
+}
+var _4c=_46[_4a].nodeName.toLowerCase();
+if(_4c=="url"){
+var _4d=_46[_4a].attributes;
+this.urlElement=_46[_4a];
+switch(_47[_4a]){
+case this.ATOM_CONTENT_TYPE:
+this.contentType=this.ATOM_CONTENT_TYPE_STRING;
+break;
+case this.RSS_CONTENT_TYPE:
+this.contentType=this.RSS_CONTENT_TYPE_STRING;
+break;
+case this.XML_CONTENT_TYPE:
+this.contentType=this.XML_CONTENT_TYPE_STRING;
+break;
+}
+}
+}});
+dojo.extend(dojox.data.OpenSearchStore,dojo.data.util.simpleFetch);
+}
diff --git a/dojox/data/OpmlStore.js b/dojox/data/OpmlStore.js
new file mode 100644
index 0000000..2da8bd6
--- /dev/null
+++ b/dojox/data/OpmlStore.js
@@ -0,0 +1,326 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.OpmlStore"]){
+dojo._hasResource["dojox.data.OpmlStore"]=true;
+dojo.provide("dojox.data.OpmlStore");
+dojo.require("dojo.data.util.filter");
+dojo.require("dojo.data.util.simpleFetch");
+dojo.declare("dojox.data.OpmlStore",null,{constructor:function(_1){
+this._xmlData=null;
+this._arrayOfTopLevelItems=[];
+this._arrayOfAllItems=[];
+this._metadataNodes=null;
+this._loadFinished=false;
+this.url=_1.url;
+this._opmlData=_1.data;
+if(_1.label){
+this.label=_1.label;
+}
+this._loadInProgress=false;
+this._queuedFetches=[];
+this._identityMap={};
+this._identCount=0;
+this._idProp="_I";
+},label:"text",url:"",_assertIsItem:function(_2){
+if(!this.isItem(_2)){
+throw new Error("dojo.data.OpmlStore: a function was passed an item argument that was not an item");
+}
+},_assertIsAttribute:function(_3){
+if(!dojo.isString(_3)){
+throw new Error("dojox.data.OpmlStore: a function was passed an attribute argument that was not an attribute object nor an attribute name string");
+}
+},_removeChildNodesThatAreNotElementNodes:function(_4,_5){
+var _6=_4.childNodes;
+if(_6.length===0){
+return;
+}
+var _7=[];
+var i,_9;
+for(i=0;i<_6.length;++i){
+_9=_6[i];
+if(_9.nodeType!=1){
+_7.push(_9);
+}
+}
+for(i=0;i<_7.length;++i){
+_9=_7[i];
+_4.removeChild(_9);
+}
+if(_5){
+for(i=0;i<_6.length;++i){
+_9=_6[i];
+this._removeChildNodesThatAreNotElementNodes(_9,_5);
+}
+}
+},_processRawXmlTree:function(_a){
+this._loadFinished=true;
+this._xmlData=_a;
+var _b=_a.getElementsByTagName("head");
+var _c=_b[0];
+if(_c){
+this._removeChildNodesThatAreNotElementNodes(_c);
+this._metadataNodes=_c.childNodes;
+}
+var _d=_a.getElementsByTagName("body");
+var _e=_d[0];
+if(_e){
+this._removeChildNodesThatAreNotElementNodes(_e,true);
+var _f=_d[0].childNodes;
+for(var i=0;i<_f.length;++i){
+var _11=_f[i];
+if(_11.tagName=="outline"){
+this._identityMap[this._identCount]=_11;
+this._identCount++;
+this._arrayOfTopLevelItems.push(_11);
+this._arrayOfAllItems.push(_11);
+this._checkChildNodes(_11);
+}
+}
+}
+},_checkChildNodes:function(_12){
+if(_12.firstChild){
+for(var i=0;i<_12.childNodes.length;i++){
+var _14=_12.childNodes[i];
+if(_14.tagName=="outline"){
+this._identityMap[this._identCount]=_14;
+this._identCount++;
+this._arrayOfAllItems.push(_14);
+this._checkChildNodes(_14);
+}
+}
+}
+},_getItemsArray:function(_15){
+if(_15&&_15.deep){
+return this._arrayOfAllItems;
+}
+return this._arrayOfTopLevelItems;
+},getValue:function(_16,_17,_18){
+this._assertIsItem(_16);
+this._assertIsAttribute(_17);
+if(_17=="children"){
+return (_16.firstChild||_18);
+}else{
+var _19=_16.getAttribute(_17);
+return (_19!==undefined)?_19:_18;
+}
+},getValues:function(_1a,_1b){
+this._assertIsItem(_1a);
+this._assertIsAttribute(_1b);
+var _1c=[];
+if(_1b=="children"){
+for(var i=0;i<_1a.childNodes.length;++i){
+_1c.push(_1a.childNodes[i]);
+}
+}else{
+if(_1a.getAttribute(_1b)!==null){
+_1c.push(_1a.getAttribute(_1b));
+}
+}
+return _1c;
+},getAttributes:function(_1e){
+this._assertIsItem(_1e);
+var _1f=[];
+var _20=_1e;
+var _21=_20.attributes;
+for(var i=0;i<_21.length;++i){
+var _23=_21.item(i);
+_1f.push(_23.nodeName);
+}
+if(_20.childNodes.length>0){
+_1f.push("children");
+}
+return _1f;
+},hasAttribute:function(_24,_25){
+return (this.getValues(_24,_25).length>0);
+},containsValue:function(_26,_27,_28){
+var _29=undefined;
+if(typeof _28==="string"){
+_29=dojo.data.util.filter.patternToRegExp(_28,false);
+}
+return this._containsValue(_26,_27,_28,_29);
+},_containsValue:function(_2a,_2b,_2c,_2d){
+var _2e=this.getValues(_2a,_2b);
+for(var i=0;i<_2e.length;++i){
+var _30=_2e[i];
+if(typeof _30==="string"&&_2d){
+return (_30.match(_2d)!==null);
+}else{
+if(_2c===_30){
+return true;
+}
+}
+}
+return false;
+},isItem:function(_31){
+return (_31&&_31.nodeType==1&&_31.tagName=="outline"&&_31.ownerDocument===this._xmlData);
+},isItemLoaded:function(_32){
+return this.isItem(_32);
+},loadItem:function(_33){
+},getLabel:function(_34){
+if(this.isItem(_34)){
+return this.getValue(_34,this.label);
+}
+return undefined;
+},getLabelAttributes:function(_35){
+return [this.label];
+},_fetchItems:function(_36,_37,_38){
+var _39=this;
+var _3a=function(_3b,_3c){
+var _3d=null;
+if(_3b.query){
+_3d=[];
+var _3e=_3b.queryOptions?_3b.queryOptions.ignoreCase:false;
+var _3f={};
+for(var key in _3b.query){
+var _41=_3b.query[key];
+if(typeof _41==="string"){
+_3f[key]=dojo.data.util.filter.patternToRegExp(_41,_3e);
+}
+}
+for(var i=0;i<_3c.length;++i){
+var _43=true;
+var _44=_3c[i];
+for(var key in _3b.query){
+var _41=_3b.query[key];
+if(!_39._containsValue(_44,key,_41,_3f[key])){
+_43=false;
+}
+}
+if(_43){
+_3d.push(_44);
+}
+}
+}else{
+if(_3c.length>0){
+_3d=_3c.slice(0,_3c.length);
+}
+}
+_37(_3d,_3b);
+};
+if(this._loadFinished){
+_3a(_36,this._getItemsArray(_36.queryOptions));
+}else{
+if(this._loadInProgress){
+this._queuedFetches.push({args:_36,filter:_3a});
+}else{
+if(this.url!==""){
+this._loadInProgress=true;
+var _45={url:_39.url,handleAs:"xml"};
+var _46=dojo.xhrGet(_45);
+_46.addCallback(function(_47){
+_39._processRawXmlTree(_47);
+_3a(_36,_39._getItemsArray(_36.queryOptions));
+_39._handleQueuedFetches();
+});
+_46.addErrback(function(_48){
+throw _48;
+});
+}else{
+if(this._opmlData){
+this._processRawXmlTree(this._opmlData);
+this._opmlData=null;
+_3a(_36,this._getItemsArray(_36.queryOptions));
+}else{
+throw new Error("dojox.data.OpmlStore: No OPML source data was provided as either URL or XML data input.");
+}
+}
+}
+}
+},getFeatures:function(){
+var _49={"dojo.data.api.Read":true,"dojo.data.api.Identity":true};
+return _49;
+},getIdentity:function(_4a){
+if(this.isItem(_4a)){
+for(var i in this._identityMap){
+if(this._identityMap[i]===_4a){
+return i;
+}
+}
+}
+return null;
+},fetchItemByIdentity:function(_4c){
+if(!this._loadFinished){
+var _4d=this;
+if(this.url!==""){
+if(this._loadInProgress){
+this._queuedFetches.push({args:_4c});
+}else{
+this._loadInProgress=true;
+var _4e={url:_4d.url,handleAs:"xml"};
+var _4f=dojo.xhrGet(_4e);
+_4f.addCallback(function(_50){
+var _51=_4c.scope?_4c.scope:dojo.global;
+try{
+_4d._processRawXmlTree(_50);
+var _52=_4d._identityMap[_4c.identity];
+if(!_4d.isItem(_52)){
+_52=null;
+}
+if(_4c.onItem){
+_4c.onItem.call(_51,_52);
+}
+_4d._handleQueuedFetches();
+}
+catch(error){
+if(_4c.onError){
+_4c.onError.call(_51,error);
+}
+}
+});
+_4f.addErrback(function(_53){
+this._loadInProgress=false;
+if(_4c.onError){
+var _54=_4c.scope?_4c.scope:dojo.global;
+_4c.onError.call(_54,_53);
+}
+});
+}
+}else{
+if(this._opmlData){
+this._processRawXmlTree(this._opmlData);
+this._opmlData=null;
+var _55=this._identityMap[_4c.identity];
+if(!_4d.isItem(_55)){
+_55=null;
+}
+if(_4c.onItem){
+var _56=_4c.scope?_4c.scope:dojo.global;
+_4c.onItem.call(_56,_55);
+}
+}
+}
+}else{
+var _55=this._identityMap[_4c.identity];
+if(!this.isItem(_55)){
+_55=null;
+}
+if(_4c.onItem){
+var _56=_4c.scope?_4c.scope:dojo.global;
+_4c.onItem.call(_56,_55);
+}
+}
+},getIdentityAttributes:function(_57){
+return null;
+},_handleQueuedFetches:function(){
+if(this._queuedFetches.length>0){
+for(var i=0;i<this._queuedFetches.length;i++){
+var _59=this._queuedFetches[i];
+var _5a=_59.args;
+var _5b=_59.filter;
+if(_5b){
+_5b(_5a,this._getItemsArray(_5a.queryOptions));
+}else{
+this.fetchItemByIdentity(_5a);
+}
+}
+this._queuedFetches=[];
+}
+},close:function(_5c){
+}});
+dojo.extend(dojox.data.OpmlStore,dojo.data.util.simpleFetch);
+}
diff --git a/dojox/data/PersevereStore.js b/dojox/data/PersevereStore.js
new file mode 100644
index 0000000..b96e4f1
--- /dev/null
+++ b/dojox/data/PersevereStore.js
@@ -0,0 +1,78 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.PersevereStore"]){
+dojo._hasResource["dojox.data.PersevereStore"]=true;
+dojo.provide("dojox.data.PersevereStore");
+dojo.require("dojox.data.JsonQueryRestStore");
+dojo.require("dojox.rpc.Client");
+dojox.json.ref.serializeFunctions=true;
+dojo.declare("dojox.data.PersevereStore",dojox.data.JsonQueryRestStore,{useFullIdInQueries:true,jsonQueryPagination:false});
+dojox.data.PersevereStore.getStores=function(_1,_2){
+_1=(_1&&(_1.match(/\/$/)?_1:(_1+"/")))||"/";
+if(_1.match(/^\w*:\/\//)){
+dojo.require("dojox.io.xhrScriptPlugin");
+dojox.io.xhrScriptPlugin(_1,"callback",dojox.io.xhrPlugins.fullHttpAdapter);
+}
+var _3=dojo.xhr;
+dojo.xhr=function(_4,_5){
+(_5.headers=_5.headers||{})["Server-Methods"]=false;
+return _3.apply(dojo,arguments);
+};
+var _6=dojox.rpc.Rest(_1,true);
+dojox.rpc._sync=_2;
+var _7=_6("Class/");
+var _8;
+var _9={};
+var _a=0;
+_7.addCallback(function(_b){
+dojox.json.ref.resolveJson(_b,{index:dojox.rpc.Rest._index,idPrefix:"/Class/",assignAbsoluteIds:true});
+function _c(_d){
+if(_d["extends"]&&_d["extends"].prototype){
+if(!_d.prototype||!_d.prototype.isPrototypeOf(_d["extends"].prototype)){
+_c(_d["extends"]);
+dojox.rpc.Rest._index[_d.prototype.__id]=_d.prototype=dojo.mixin(dojo.delegate(_d["extends"].prototype),_d.prototype);
+}
+}
+};
+function _e(_f,_10){
+if(_f&&_10){
+for(var j in _f){
+var _12=_f[j];
+if(_12.runAt=="server"&&!_10[j]){
+_10[j]=(function(_13){
+return function(){
+var _14=dojo.rawXhrPost({url:this.__id,postData:dojo.toJson({method:_13,id:_a++,params:dojo._toArray(arguments)}),handleAs:"json"});
+_14.addCallback(function(_15){
+return _15.error?new Error(_15.error):_15.result;
+});
+return _14;
+};
+})(j);
+}
+}
+}
+};
+for(var i in _b){
+if(typeof _b[i]=="object"){
+var _17=_b[i];
+_c(_17);
+_e(_17.methods,_17.prototype=_17.prototype||{});
+_e(_17.staticMethods,_17);
+_9[_b[i].id]=new dojox.data.PersevereStore({target:new dojo._Url(_1,_b[i].id)+"",schema:_17});
+}
+}
+return (_8=_9);
+});
+dojo.xhr=_3;
+return _2?_8:_7;
+};
+dojox.data.PersevereStore.addProxy=function(){
+dojo.require("dojox.io.xhrPlugins");
+dojox.io.xhrPlugins.addProxy("/proxy/");
+};
+}
diff --git a/dojox/data/PicasaStore.js b/dojox/data/PicasaStore.js
new file mode 100644
index 0000000..e6c42c9
--- /dev/null
+++ b/dojox/data/PicasaStore.js
@@ -0,0 +1,161 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.PicasaStore"]){
+dojo._hasResource["dojox.data.PicasaStore"]=true;
+dojo.provide("dojox.data.PicasaStore");
+dojo.require("dojo.data.util.simpleFetch");
+dojo.require("dojo.io.script");
+dojo.require("dojo.date.stamp");
+dojo.declare("dojox.data.PicasaStore",null,{constructor:function(_1){
+if(_1&&_1.label){
+this.label=_1.label;
+}
+},_picasaUrl:"http://picasaweb.google.com/data/feed/api/all",_storeRef:"_S",label:"title",_assertIsItem:function(_2){
+if(!this.isItem(_2)){
+throw new Error("dojox.data.PicasaStore: a function was passed an item argument that was not an item");
+}
+},_assertIsAttribute:function(_3){
+if(typeof _3!=="string"){
+throw new Error("dojox.data.PicasaStore: a function was passed an attribute argument that was not an attribute name string");
+}
+},getFeatures:function(){
+return {"dojo.data.api.Read":true};
+},getValue:function(_4,_5,_6){
+var _7=this.getValues(_4,_5);
+if(_7&&_7.length>0){
+return _7[0];
+}
+return _6;
+},getAttributes:function(_8){
+return ["id","published","updated","category","title$type","title","summary$type","summary","rights$type","rights","link","author","gphoto$id","gphoto$name","location"];
+},hasAttribute:function(_9,_a){
+if(this.getValue(_9,_a)){
+return true;
+}
+return false;
+},isItemLoaded:function(_b){
+return this.isItem(_b);
+},loadItem:function(_c){
+},getLabel:function(_d){
+return this.getValue(_d,this.label);
+},getLabelAttributes:function(_e){
+return [this.label];
+},containsValue:function(_f,_10,_11){
+var _12=this.getValues(_f,_10);
+for(var i=0;i<_12.length;i++){
+if(_12[i]===_11){
+return true;
+}
+}
+return false;
+},getValues:function(_14,_15){
+this._assertIsItem(_14);
+this._assertIsAttribute(_15);
+if(_15==="title"){
+return [this._unescapeHtml(_14.title)];
+}else{
+if(_15==="author"){
+return [this._unescapeHtml(_14.author[0].name)];
+}else{
+if(_15==="datePublished"){
+return [dojo.date.stamp.fromISOString(_14.published)];
+}else{
+if(_15==="dateTaken"){
+return [dojo.date.stamp.fromISOString(_14.date_taken)];
+}else{
+if(_15==="imageUrlSmall"){
+return [_14.media.thumbnail[1].url];
+}else{
+if(_15==="imageUrl"){
+return [_14.content$src];
+}else{
+if(_15==="imageUrlMedium"){
+return [_14.media.thumbnail[2].url];
+}else{
+if(_15==="link"){
+return [_14.link[1]];
+}else{
+if(_15==="tags"){
+return _14.tags.split(" ");
+}else{
+if(_15==="description"){
+return [this._unescapeHtml(_14.summary)];
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+return [];
+},isItem:function(_16){
+if(_16&&_16[this._storeRef]===this){
+return true;
+}
+return false;
+},close:function(_17){
+},_fetchItems:function(_18,_19,_1a){
+if(!_18.query){
+_18.query={};
+}
+var _1b={alt:"jsonm",pp:"1",psc:"G"};
+_1b["start-index"]="1";
+if(_18.query.start){
+_1b["start-index"]=_18.query.start;
+}
+if(_18.query.tags){
+_1b.q=_18.query.tags;
+}
+if(_18.query.userid){
+_1b.uname=_18.query.userid;
+}
+if(_18.query.userids){
+_1b.ids=_18.query.userids;
+}
+if(_18.query.lang){
+_1b.hl=_18.query.lang;
+}
+if(_18.count){
+_1b["max-results"]=_18.count;
+}else{
+_1b["max-results"]="20";
+}
+var _1c=this;
+var _1d=null;
+var _1e=function(_1f){
+if(_1d!==null){
+dojo.disconnect(_1d);
+}
+_19(_1c._processPicasaData(_1f),_18);
+};
+var _20={url:this._picasaUrl,content:_1b,callbackParamName:"callback",handle:_1e};
+var _21=dojo.io.script.get(_20);
+_21.addErrback(function(_22){
+dojo.disconnect(_1d);
+_1a(_22,_18);
+});
+},_processPicasaData:function(_23){
+var _24=[];
+if(_23.feed){
+_24=_23.feed.entry;
+for(var i=0;i<_24.length;i++){
+var _26=_24[i];
+_26[this._storeRef]=this;
+}
+}
+return _24;
+},_unescapeHtml:function(str){
+str=str.replace(/&/gm,"&").replace(/</gm,"<").replace(/>/gm,">").replace(/"/gm,"\"");
+str=str.replace(/'/gm,"'");
+return str;
+}});
+dojo.extend(dojox.data.PicasaStore,dojo.data.util.simpleFetch);
+}
diff --git a/dojox/data/QueryReadStore.js b/dojox/data/QueryReadStore.js
new file mode 100644
index 0000000..427d6ab
--- /dev/null
+++ b/dojox/data/QueryReadStore.js
@@ -0,0 +1,255 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.QueryReadStore"]){
+dojo._hasResource["dojox.data.QueryReadStore"]=true;
+dojo.provide("dojox.data.QueryReadStore");
+dojo.require("dojo.string");
+dojo.require("dojo.data.util.sorter");
+dojo.declare("dojox.data.QueryReadStore",null,{url:"",requestMethod:"get",_className:"dojox.data.QueryReadStore",_items:[],_lastServerQuery:null,_numRows:-1,lastRequestHash:null,doClientPaging:false,doClientSorting:false,_itemsByIdentity:null,_identifier:null,_features:{"dojo.data.api.Read":true,"dojo.data.api.Identity":true},_labelAttr:"label",constructor:function(_1){
+dojo.mixin(this,_1);
+},getValue:function(_2,_3,_4){
+this._assertIsItem(_2);
+if(!dojo.isString(_3)){
+throw new Error(this._className+".getValue(): Invalid attribute, string expected!");
+}
+if(!this.hasAttribute(_2,_3)){
+if(_4){
+return _4;
+}
+
+}
+return _2.i[_3];
+},getValues:function(_5,_6){
+this._assertIsItem(_5);
+var _7=[];
+if(this.hasAttribute(_5,_6)){
+_7.push(_5.i[_6]);
+}
+return _7;
+},getAttributes:function(_8){
+this._assertIsItem(_8);
+var _9=[];
+for(var i in _8.i){
+_9.push(i);
+}
+return _9;
+},hasAttribute:function(_b,_c){
+return this.isItem(_b)&&typeof _b.i[_c]!="undefined";
+},containsValue:function(_d,_e,_f){
+var _10=this.getValues(_d,_e);
+var len=_10.length;
+for(var i=0;i<len;i++){
+if(_10[i]==_f){
+return true;
+}
+}
+return false;
+},isItem:function(_13){
+if(_13){
+return typeof _13.r!="undefined"&&_13.r==this;
+}
+return false;
+},isItemLoaded:function(_14){
+return this.isItem(_14);
+},loadItem:function(_15){
+if(this.isItemLoaded(_15.item)){
+return;
+}
+},fetch:function(_16){
+_16=_16||{};
+if(!_16.store){
+_16.store=this;
+}
+var _17=this;
+var _18=function(_19,_1a){
+if(_1a.onError){
+var _1b=_1a.scope||dojo.global;
+_1a.onError.call(_1b,_19,_1a);
+}
+};
+var _1c=function(_1d,_1e,_1f){
+var _20=_1e.abort||null;
+var _21=false;
+var _22=_1e.start?_1e.start:0;
+if(_17.doClientPaging==false){
+_22=0;
+}
+var _23=_1e.count?(_22+_1e.count):_1d.length;
+_1e.abort=function(){
+_21=true;
+if(_20){
+_20.call(_1e);
+}
+};
+var _24=_1e.scope||dojo.global;
+if(!_1e.store){
+_1e.store=_17;
+}
+if(_1e.onBegin){
+_1e.onBegin.call(_24,_1f,_1e);
+}
+if(_1e.sort&&_17.doClientSorting){
+_1d.sort(dojo.data.util.sorter.createSortFunction(_1e.sort,_17));
+}
+if(_1e.onItem){
+for(var i=_22;(i<_1d.length)&&(i<_23);++i){
+var _26=_1d[i];
+if(!_21){
+_1e.onItem.call(_24,_26,_1e);
+}
+}
+}
+if(_1e.onComplete&&!_21){
+var _27=null;
+if(!_1e.onItem){
+_27=_1d.slice(_22,_23);
+}
+_1e.onComplete.call(_24,_27,_1e);
+}
+};
+this._fetchItems(_16,_1c,_18);
+return _16;
+},getFeatures:function(){
+return this._features;
+},close:function(_28){
+},getLabel:function(_29){
+if(this._labelAttr&&this.isItem(_29)){
+return this.getValue(_29,this._labelAttr);
+}
+return undefined;
+},getLabelAttributes:function(_2a){
+if(this._labelAttr){
+return [this._labelAttr];
+}
+return null;
+},_xhrFetchHandler:function(_2b,_2c,_2d,_2e){
+_2b=this._filterResponse(_2b);
+if(_2b.label){
+this._labelAttr=_2b.label;
+}
+var _2f=_2b.numRows||-1;
+this._items=[];
+dojo.forEach(_2b.items,function(e){
+this._items.push({i:e,r:this});
+},this);
+var _31=_2b.identifier;
+this._itemsByIdentity={};
+if(_31){
+this._identifier=_31;
+var i;
+for(i=0;i<this._items.length;++i){
+var _33=this._items[i].i;
+var _34=_33[_31];
+if(!this._itemsByIdentity[_34]){
+this._itemsByIdentity[_34]=_33;
+}else{
+throw new Error(this._className+":  The json data as specified by: ["+this.url+"] is malformed.  Items within the list have identifier: ["+_31+"].  Value collided: ["+_34+"]");
+}
+}
+}else{
+this._identifier=Number;
+for(i=0;i<this._items.length;++i){
+this._items[i].n=i;
+}
+}
+_2f=this._numRows=(_2f===-1)?this._items.length:_2f;
+_2d(this._items,_2c,_2f);
+this._numRows=_2f;
+},_fetchItems:function(_35,_36,_37){
+var _38=_35.serverQuery||_35.query||{};
+if(!this.doClientPaging){
+_38.start=_35.start||0;
+if(_35.count){
+_38.count=_35.count;
+}
+}
+if(!this.doClientSorting){
+if(_35.sort){
+var _39=_35.sort[0];
+if(_39&&_39.attribute){
+var _3a=_39.attribute;
+if(_39.descending){
+_3a="-"+_3a;
+}
+_38.sort=_3a;
+}
+}
+}
+if(this.doClientPaging&&this._lastServerQuery!==null&&dojo.toJson(_38)==dojo.toJson(this._lastServerQuery)){
+this._numRows=(this._numRows===-1)?this._items.length:this._numRows;
+_36(this._items,_35,this._numRows);
+}else{
+var _3b=this.requestMethod.toLowerCase()=="post"?dojo.xhrPost:dojo.xhrGet;
+var _3c=_3b({url:this.url,handleAs:"json-comment-optional",content:_38});
+_3c.addCallback(dojo.hitch(this,function(_3d){
+this._xhrFetchHandler(_3d,_35,_36,_37);
+}));
+_3c.addErrback(function(_3e){
+_37(_3e,_35);
+});
+this.lastRequestHash=new Date().getTime()+"-"+String(Math.random()).substring(2);
+this._lastServerQuery=dojo.mixin({},_38);
+}
+},_filterResponse:function(_3f){
+return _3f;
+},_assertIsItem:function(_40){
+if(!this.isItem(_40)){
+throw new Error(this._className+": Invalid item argument.");
+}
+},_assertIsAttribute:function(_41){
+if(typeof _41!=="string"){
+throw new Error(this._className+": Invalid attribute argument ('"+_41+"').");
+}
+},fetchItemByIdentity:function(_42){
+if(this._itemsByIdentity){
+var _43=this._itemsByIdentity[_42.identity];
+if(!(_43===undefined)){
+if(_42.onItem){
+var _44=_42.scope?_42.scope:dojo.global;
+_42.onItem.call(_44,{i:_43,r:this});
+}
+return;
+}
+}
+var _45=function(_46,_47){
+var _48=_42.scope?_42.scope:dojo.global;
+if(_42.onError){
+_42.onError.call(_48,_46);
+}
+};
+var _49=function(_4a,_4b){
+var _4c=_42.scope?_42.scope:dojo.global;
+try{
+var _4d=null;
+if(_4a&&_4a.length==1){
+_4d=_4a[0];
+}
+if(_42.onItem){
+_42.onItem.call(_4c,_4d);
+}
+}
+catch(error){
+if(_42.onError){
+_42.onError.call(_4c,error);
+}
+}
+};
+var _4e={serverQuery:{id:_42.identity}};
+this._fetchItems(_4e,_49,_45);
+},getIdentity:function(_4f){
+var _50=null;
+if(this._identifier===Number){
+_50=_4f.n;
+}else{
+_50=_4f.i[this._identifier];
+}
+return _50;
+},getIdentityAttributes:function(_51){
+return [this._identifier];
+}});
+}
diff --git a/dojox/data/README b/dojox/data/README
new file mode 100644
index 0000000..4641983
--- /dev/null
+++ b/dojox/data/README
@@ -0,0 +1,127 @@
+-------------------------------------------------------------------------------
+DojoX Data
+-------------------------------------------------------------------------------
+Version 1.1
+Release date: 03/18/2008
+-------------------------------------------------------------------------------
+Project state: production
+-------------------------------------------------------------------------------
+Project authors
+	Jared Jurkiewicz (jared.jurkiewicz at gmail.com) (FileStore, HtmlStore, XmlStore, FlickrStore, CssRuleStore, CssClassStore, AppStore, others).
+	Shane O'Sullivan (shaneosullivan1 at gmail.com) (FlickrRestStore, AtomReadStore, GoogleSeachStore, GoogleFeedStore)
+	Wolfram Kriesing (wolfram at kriesing.de) (QueryReadStore)
+	Dustin Machi (dmachi at dojotolkit.org) (jsonPathStore);
+	Russell Jones (KeyValueStore) (CLA)
+	Benjamin Schell (KeyValueStore, CssRuleStore, CssClassStore, AppStore, OpenSearchStore) (Corporate CLA)
+	Kurt Stutsman (kurt at snaplogic.org) (SnapLogicStore)
+	Kris Zyp (kzyp at dojotoolkit.org) (JsonRestStore, PersevereStore, S3JsonRestStore, CouchDBRestStore)
+	Frank Fortson (frank.fortson at equorum.com) (AndOrReadStore, AndOrWriteStore)
+
+
+-------------------------------------------------------------------------------
+Project description
+
+The DojoX Data project is a container for extensions and extra example stores
+that implement the dojo.data APIs.  It may also contain utility functions for
+working with specific types of data.
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+DojoX Data has dependencies on core dojo (dojo.data), dojox.xml for XmlStore 
+and dojox.data.dom(deprecated) and the D.O.H. unit test framework
+-------------------------------------------------------------------------------
+Documentation:
+
+See the Dojo API tool (http://dojotoolkit.org/api)
+-------------------------------------------------------------------------------
+Contributions:
+
+For contributions to be committed into the dojox repository, the datastore 
+should have basic unit tests that exercise the API's that the store declares it
+implements.  Documentation and demos are a plus, but unit tests are required
+to be committed into this sub-package.  This is necessary to help keep the 
+provided datastores as stable as possible.
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/data/*
+
+Install into the following directory structure:
+/dojox/data/
+
+...which should be at the same level as your Dojo checkout.
+
+/dojox/data/*
+
+Require in the dojox.data stores you wish to use.
+-------------------------------------------------------------------------------
+Additional Notes: 
+	dojox.data.AtomReadStore - Reads Atom XML documents.
+
+	dojox.data.CvsStore - comma-separated (spreadsheet output)
+	datastore implementation 
+	
+	dojox.data.FlickrRestStore - advanced version of: dojox.data.FlickrStore 
+	(Caching + user key support) 
+	
+	dojox.data.FlickrStore - data store driven by Flickr.com public API. 
+	
+	dojox.data.HtmlTableStore - Implementation of an HTML Table reading 
+	datastore
+	
+	dojox.data.HtmlStore - Implementation of an HTML reading datastore.  Can 
+	handle tables, ordered and un-ordered lists, and lists of divs.
+	
+	dojox.data.OpmlStore - Store for reading OMPL formatted data
+	
+	dojox.data.XmlStore - datastore for XML based services or  
+	documents.
+
+	dojox.data.QueryReadStore - datastore to provide serverside URL query
+	matching.  Similar to the 0.4.X ComboBox dataUrl parameter.	         
+
+	dojox.data.jsonPathStore - datastore that takes an arbitrary js object
+	and uses it as the store. Pre-Alpha at the moment.
+
+	dojox.data.KeyValueStore - datastore that mimics a key/value property
+	file format.
+
+	dojox.data.SnapLogicStore - Store to interface to SnapLogic data services.
+
+	dojox.data.JsonRestStore - Store to interface with RESTful HTTP/JSON web services.
+	dojox.data.PersevereStore - Extension of JsonRestStore for Persevere
+	dojox.data.CouchDBRestStore - Extension of JsonRestStore for CouchDB
+	dojox.data.S3JsonRestStore - Extension of JsonRestStore for Amazon S3
+	dojox.data.GoogleSearchStore - Store to interface Google's AJAX search services.  
+		There are many subclasses of this store for particular types of searches:
+		dojox.data.GoogleWebSearchStore
+		dojox.data.GoogleBlogSearchStore
+		dojox.data.GoogleLocalSearchStore
+		dojox.data.GoogleVideoSearchStore
+		dojox.data.GoogleNewsSearchStore
+		dojox.data.GoogleBookSearchStore
+		dojox.data.GoogleImageSearchStore
+
+	dojox.data.AndOrReadStore - Demonstrating a more complex query format allowing AND/OR.  
+	Based directly on dojo.data.ItemFileReadStore.
+
+	dojox.data.AndOrWriteStore - Demonstrating a more complex query format allowing AND/OR.  
+	Based directly on dojo.data.ItemFileWriteStore.
+
+	dojox.data.FileStore - A lazy-loading store designed for searching filesystems with a provided
+	PHP back end.  Implements dojo.data.api.Read and dojo.data.api.Identity
+
+	dojox.data.CssRuleStore - A store that allows searching/querying over Css rules loaded in the page in
+	the browser.
+
+	dojox.data.CssClassStore - A store that allows searching/querying over what classes are defined in the page in
+	the browser.
+
+	dojox.data.AppStore - A store that implements full read, write, and identity APIs for working with ATOM documents.
+	The store uses the full APP protocol.
+        
+	dojox.data.OpenSearchStore - A store that implements OpenSearch provider search capability.
+
diff --git a/dojox/data/RailsStore.js b/dojox/data/RailsStore.js
new file mode 100644
index 0000000..b25e5a5
--- /dev/null
+++ b/dojox/data/RailsStore.js
@@ -0,0 +1,121 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.RailsStore"]){
+dojo._hasResource["dojox.data.RailsStore"]=true;
+dojo.provide("dojox.data.RailsStore");
+dojo.require("dojox.data.JsonRestStore");
+dojo.declare("dojox.data.RailsStore",dojox.data.JsonRestStore,{constructor:function(){
+},preamble:function(_1){
+if(typeof _1.target=="string"&&!_1.service){
+var _2=_1.target.replace(/\/$/g,"");
+var _3=function(id,_5){
+_5=_5||{};
+var _6=_2;
+var _7;
+var _8;
+if(dojo.isObject(id)){
+_8="";
+_7="?"+dojo.objectToQuery(id);
+}else{
+if(_5.queryStr&&_5.queryStr.indexOf("?")!=-1){
+_8=_5.queryStr.replace(/\?.*/,"");
+_7=_5.queryStr.replace(/[^?]*\?/g,"?");
+}else{
+if(dojo.isString(_5.query)&&_5.query.indexOf("?")!=-1){
+_8=_5.query.replace(/\?.*/,"");
+_7=_5.query.replace(/[^?]*\?/g,"?");
+}else{
+_8=id?id.toString():"";
+_7="";
+}
+}
+}
+if(_8.indexOf("=")!=-1){
+_7=_8;
+_8="";
+}
+if(_8){
+_6=_6+"/"+_8+".json"+_7;
+}else{
+_6=_6+".json"+_7;
+}
+var _9=dojox.rpc._sync;
+dojox.rpc._sync=false;
+return {url:_6,handleAs:"json",contentType:"application/json",sync:_9,headers:{Accept:"application/json,application/javascript",Range:_5&&(_5.start>=0||_5.count>=0)?"items="+(_5.start||"0")+"-"+((_5.count&&(_5.count+(_5.start||0)-1))||""):undefined}};
+};
+_1.service=dojox.rpc.Rest(this.target,true,null,_3);
+}
+},fetch:function(_a){
+_a=_a||{};
+function _b(_c){
+function _d(){
+if(_a.queryStr==null){
+_a.queryStr="";
+}
+if(dojo.isObject(_a.query)){
+_a.queryStr="?"+dojo.objectToQuery(_a.query);
+}else{
+if(dojo.isString(_a.query)){
+_a.queryStr=_a.query;
+}
+}
+};
+function _e(){
+if(_a.queryStr.indexOf("?")==-1){
+return "?";
+}else{
+return "&";
+}
+};
+if(_a.queryStr==null){
+_d();
+}
+_a.queryStr=_a.queryStr+_e()+dojo.objectToQuery(_c);
+};
+if(_a.start||_a.count){
+if((_a.start||0)%_a.count){
+throw new Error("The start parameter must be a multiple of the count parameter");
+}
+_b({page:((_a.start||0)/_a.count)+1,per_page:_a.count});
+}
+if(_a.sort){
+var _f={sortBy:[],sortDir:[]};
+dojo.forEach(_a.sort,function(_10){
+_f.sortBy.push(_10.attribute);
+_f.sortDir.push(!!_10.descending?"DESC":"ASC");
+});
+_b(_f);
+delete _a.sort;
+}
+return this.inherited(arguments);
+},_processResults:function(_11,_12){
+var _13;
+if((typeof this.rootAttribute=="undefined")&&_11[0]){
+if(_11[0][this.idAttribute]){
+this.rootAttribute=false;
+
+}else{
+for(var _14 in _11[0]){
+if(_11[0][_14][this.idAttribute]){
+this.rootAttribute=_14;
+
+}
+}
+}
+}
+if(this.rootAttribute){
+_13=dojo.map(_11,function(_15){
+return _15[this.rootAttribute];
+},this);
+}else{
+_13=_11;
+}
+var _16=_11.length;
+return {totalCount:_12.fullLength||(_12.request.count==_16?(_12.request.start||0)+_16*2:_16),items:_13};
+}});
+}
diff --git a/dojox/data/S3Store.js b/dojox/data/S3Store.js
new file mode 100644
index 0000000..663224b
--- /dev/null
+++ b/dojox/data/S3Store.js
@@ -0,0 +1,29 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.S3Store"]){
+dojo._hasResource["dojox.data.S3Store"]=true;
+dojo.provide("dojox.data.S3Store");
+dojo.require("dojox.rpc.ProxiedPath");
+dojo.require("dojox.data.JsonRestStore");
+dojo.declare("dojox.data.S3Store",dojox.data.JsonRestStore,{_processResults:function(_1){
+var _2=_1.getElementsByTagName("Key");
+var _3=[];
+var _4=this;
+for(var i=0;i<_2.length;i++){
+var _6=_2[i];
+var _7={_loadObject:(function(_8,_9){
+return function(_a){
+delete this._loadObject;
+_4.service(_8).addCallback(_a);
+};
+})(_6.firstChild.nodeValue,_7)};
+_3.push(_7);
+}
+return {totalCount:_3.length,items:_3};
+}});
+}
diff --git a/dojox/data/ServiceStore.js b/dojox/data/ServiceStore.js
new file mode 100644
index 0000000..6e24196
--- /dev/null
+++ b/dojox/data/ServiceStore.js
@@ -0,0 +1,145 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.ServiceStore"]){
+dojo._hasResource["dojox.data.ServiceStore"]=true;
+dojo.provide("dojox.data.ServiceStore");
+dojo.declare("dojox.data.ServiceStore",dojox.data.ClientFilter,{constructor:function(_1){
+this.byId=this.fetchItemByIdentity;
+this._index={};
+if(_1){
+dojo.mixin(this,_1);
+}
+this.idAttribute=(_1&&_1.idAttribute)||(this.schema&&this.schema._idAttr);
+this.labelAttribute=this.labelAttribute||"label";
+},schema:null,idAttribute:"id",syncMode:false,estimateCountFactor:1,getSchema:function(){
+return this.schema;
+},loadLazyValues:true,getValue:function(_2,_3,_4){
+var _5=_2[_3];
+return _5||(_3 in _2?_5:_2._loadObject?(dojox.rpc._sync=true)&&arguments.callee.call(this,dojox.data.ServiceStore.prototype.loadItem({item:_2})||{},_3,_4):_4);
+},getValues:function(_6,_7){
+var _8=this.getValue(_6,_7);
+return _8 instanceof Array?_8:_8===undefined?[]:[_8];
+},getAttributes:function(_9){
+var _a=[];
+for(var i in _9){
+if(_9.hasOwnProperty(i)&&!(i.charAt(0)=="_"&&i.charAt(1)=="_")){
+_a.push(i);
+}
+}
+return _a;
+},hasAttribute:function(_c,_d){
+return _d in _c;
+},containsValue:function(_e,_f,_10){
+return dojo.indexOf(this.getValues(_e,_f),_10)>-1;
+},isItem:function(_11){
+return (typeof _11=="object")&&_11&&!(_11 instanceof Date);
+},isItemLoaded:function(_12){
+return _12&&!_12._loadObject;
+},loadItem:function(_13){
+var _14;
+if(_13.item._loadObject){
+_13.item._loadObject(function(_15){
+_14=_15;
+delete _14._loadObject;
+var _16=_15 instanceof Error?_13.onError:_13.onItem;
+if(_16){
+_16.call(_13.scope,_15);
+}
+});
+}else{
+if(_13.onItem){
+_13.onItem.call(_13.scope,_13.item);
+}
+}
+return _14;
+},_currentId:0,_processResults:function(_17,_18){
+if(_17&&typeof _17=="object"){
+var id=_17.__id;
+if(!id){
+if(this.idAttribute){
+id=_17[this.idAttribute];
+}else{
+id=this._currentId++;
+}
+if(id!==undefined){
+var _1a=this._index[id];
+if(_1a){
+for(var j in _1a){
+delete _1a[j];
+}
+_17=dojo.mixin(_1a,_17);
+}
+_17.__id=id;
+this._index[id]=_17;
+}
+}
+for(var i in _17){
+_17[i]=this._processResults(_17[i],_18).items;
+}
+}
+var _1d=_17.length;
+return {totalCount:_18.request.count==_1d?(_18.request.start||0)+_1d*this.estimateCountFactor:_1d,items:_17};
+},close:function(_1e){
+return _1e&&_1e.abort&&_1e.abort();
+},fetch:function(_1f){
+_1f=_1f||{};
+if("syncMode" in _1f?_1f.syncMode:this.syncMode){
+dojox.rpc._sync=true;
+}
+var _20=this;
+var _21=_1f.scope||_20;
+var _22=this.cachingFetch?this.cachingFetch(_1f):this._doQuery(_1f);
+_22.request=_1f;
+_22.addCallback(function(_23){
+if(_1f.clientFetch){
+_23=_20.clientSideFetch({query:_1f.clientFetch,sort:_1f.sort,start:_1f.start,count:_1f.count},_23);
+}
+var _24=_20._processResults(_23,_22);
+_23=_1f.results=_24.items;
+if(_1f.onBegin){
+_1f.onBegin.call(_21,_24.totalCount,_1f);
+}
+if(_1f.onItem){
+for(var i=0;i<_23.length;i++){
+_1f.onItem.call(_21,_23[i],_1f);
+}
+}
+if(_1f.onComplete){
+_1f.onComplete.call(_21,_1f.onItem?null:_23,_1f);
+}
+return _23;
+});
+_22.addErrback(_1f.onError&&dojo.hitch(_21,_1f.onError));
+_1f.abort=function(){
+_22.ioArgs.xhr.abort();
+};
+_1f.store=this;
+return _1f;
+},_doQuery:function(_26){
+var _27=typeof _26.queryStr=="string"?_26.queryStr:_26.query;
+return this.service(_27);
+},getFeatures:function(){
+return {"dojo.data.api.Read":true,"dojo.data.api.Identity":true,"dojo.data.api.Schema":this.schema};
+},getLabel:function(_28){
+return this.getValue(_28,this.labelAttribute);
+},getLabelAttributes:function(_29){
+return [this.labelAttribute];
+},getIdentity:function(_2a){
+return _2a.__id;
+},getIdentityAttributes:function(_2b){
+return [this.idAttribute];
+},fetchItemByIdentity:function(_2c){
+var _2d=this._index[(_2c._prefix||"")+_2c.identity];
+if(_2d&&_2c.onItem){
+_2c.onItem.call(_2c.scope,_2d);
+}else{
+return this.fetch({query:_2c.identity,onComplete:_2c.onItem,onError:_2c.onError,scope:_2c.scope}).results;
+}
+return _2d;
+}});
+}
diff --git a/dojox/data/SnapLogicStore.js b/dojox/data/SnapLogicStore.js
new file mode 100644
index 0000000..0b26ed5
--- /dev/null
+++ b/dojox/data/SnapLogicStore.js
@@ -0,0 +1,183 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.SnapLogicStore"]){
+dojo._hasResource["dojox.data.SnapLogicStore"]=true;
+dojo.provide("dojox.data.SnapLogicStore");
+dojo.require("dojo.io.script");
+dojo.require("dojo.data.util.sorter");
+dojo.declare("dojox.data.SnapLogicStore",null,{Parts:{DATA:"data",COUNT:"count"},url:"",constructor:function(_1){
+if(_1.url){
+this.url=_1.url;
+}
+this._parameters=_1.parameters;
+},_assertIsItem:function(_2){
+if(!this.isItem(_2)){
+throw new Error("dojox.data.SnapLogicStore: a function was passed an item argument that was not an item");
+}
+},_assertIsAttribute:function(_3){
+if(typeof _3!=="string"){
+throw new Error("dojox.data.SnapLogicStore: a function was passed an attribute argument that was not an attribute name string");
+}
+},getFeatures:function(){
+return {"dojo.data.api.Read":true};
+},getValue:function(_4,_5,_6){
+this._assertIsItem(_4);
+this._assertIsAttribute(_5);
+var i=dojo.indexOf(_4.attributes,_5);
+if(i!==-1){
+return _4.values[i];
+}
+return _6;
+},getAttributes:function(_8){
+this._assertIsItem(_8);
+return _8.attributes;
+},hasAttribute:function(_9,_a){
+this._assertIsItem(_9);
+this._assertIsAttribute(_a);
+for(var i=0;i<_9.attributes.length;++i){
+if(_a==_9.attributes[i]){
+return true;
+}
+}
+return false;
+},isItemLoaded:function(_c){
+return this.isItem(_c);
+},loadItem:function(_d){
+},getLabel:function(_e){
+return undefined;
+},getLabelAttributes:function(_f){
+return null;
+},containsValue:function(_10,_11,_12){
+return this.getValue(_10,_11)===_12;
+},getValues:function(_13,_14){
+this._assertIsItem(_13);
+this._assertIsAttribute(_14);
+var i=dojo.indexOf(_13.attributes,_14);
+if(i!==-1){
+return [_13.values[i]];
+}
+return [];
+},isItem:function(_16){
+if(_16&&_16._store===this){
+return true;
+}
+return false;
+},close:function(_17){
+},_fetchHandler:function(_18){
+var _19=_18.scope||dojo.global;
+if(_18.onBegin){
+_18.onBegin.call(_19,_18._countResponse[0],_18);
+}
+if(_18.onItem||_18.onComplete){
+var _1a=_18._dataResponse;
+if(!_1a.length){
+_18.onError.call(_19,new Error("dojox.data.SnapLogicStore: invalid response of length 0"),_18);
+return;
+}else{
+if(_18.query!="record count"){
+var _1b=_1a.shift();
+var _1c=[];
+for(var i=0;i<_1a.length;++i){
+if(_18._aborted){
+break;
+}
+_1c.push({attributes:_1b,values:_1a[i],_store:this});
+}
+if(_18.sort&&!_18._aborted){
+_1c.sort(dojo.data.util.sorter.createSortFunction(_18.sort,self));
+}
+}else{
+_1c=[({attributes:["count"],values:_1a,_store:this})];
+}
+}
+if(_18.onItem){
+for(var i=0;i<_1c.length;++i){
+if(_18._aborted){
+break;
+}
+_18.onItem.call(_19,_1c[i],_18);
+}
+_1c=null;
+}
+if(_18.onComplete&&!_18._aborted){
+_18.onComplete.call(_19,_1c,_18);
+}
+}
+},_partHandler:function(_1e,_1f,_20){
+if(_20 instanceof Error){
+if(_1f==this.Parts.DATA){
+_1e._dataHandle=null;
+}else{
+_1e._countHandle=null;
+}
+_1e._aborted=true;
+if(_1e.onError){
+_1e.onError.call(_1e.scope,_20,_1e);
+}
+}else{
+if(_1e._aborted){
+return;
+}
+if(_1f==this.Parts.DATA){
+_1e._dataResponse=_20;
+}else{
+_1e._countResponse=_20;
+}
+if((!_1e._dataHandle||_1e._dataResponse!==null)&&(!_1e._countHandle||_1e._countResponse!==null)){
+this._fetchHandler(_1e);
+}
+}
+},fetch:function(_21){
+_21._countResponse=null;
+_21._dataResponse=null;
+_21._aborted=false;
+_21.abort=function(){
+if(!_21._aborted){
+_21._aborted=true;
+if(_21._dataHandle&&_21._dataHandle.cancel){
+_21._dataHandle.cancel();
+}
+if(_21._countHandle&&_21._countHandle.cancel){
+_21._countHandle.cancel();
+}
+}
+};
+if(_21.onItem||_21.onComplete){
+var _22=this._parameters||{};
+if(_21.start){
+if(_21.start<0){
+throw new Error("dojox.data.SnapLogicStore: request start value must be 0 or greater");
+}
+_22["sn.start"]=_21.start+1;
+}
+if(_21.count){
+if(_21.count<0){
+throw new Error("dojox.data.SnapLogicStore: request count value 0 or greater");
+}
+_22["sn.limit"]=_21.count;
+}
+_22["sn.content_type"]="application/javascript";
+var _23=this;
+var _24=function(_25,_26){
+if(_25 instanceof Error){
+_23._fetchHandler(_25,_21);
+}
+};
+var _27={url:this.url,content:_22,timeout:60000,callbackParamName:"sn.stream_header",handle:dojo.hitch(this,"_partHandler",_21,this.Parts.DATA)};
+_21._dataHandle=dojo.io.script.get(_27);
+}
+if(_21.onBegin){
+var _22={};
+_22["sn.count"]="records";
+_22["sn.content_type"]="application/javascript";
+var _27={url:this.url,content:_22,timeout:60000,callbackParamName:"sn.stream_header",handle:dojo.hitch(this,"_partHandler",_21,this.Parts.COUNT)};
+_21._countHandle=dojo.io.script.get(_27);
+}
+return _21;
+}});
+}
diff --git a/dojox/data/StoreExplorer.js b/dojox/data/StoreExplorer.js
new file mode 100644
index 0000000..87d221d
--- /dev/null
+++ b/dojox/data/StoreExplorer.js
@@ -0,0 +1,148 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.StoreExplorer"]){
+dojo._hasResource["dojox.data.StoreExplorer"]=true;
+dojo.provide("dojox.data.StoreExplorer");
+dojo.require("dojox.grid.DataGrid");
+dojo.require("dojox.data.ItemExplorer");
+dojo.require("dijit.layout.BorderContainer");
+dojo.require("dijit.layout.ContentPane");
+dojo.declare("dojox.data.StoreExplorer",dijit.layout.BorderContainer,{constructor:function(_1){
+dojo.mixin(this,_1);
+},store:null,stringQueries:false,postCreate:function(){
+var _2=this;
+this.inherited(arguments);
+var _3=new dijit.layout.ContentPane({region:"top"}).placeAt(this);
+function _4(_5,_6){
+var _7=new dijit.form.Button({label:_5});
+_3.containerNode.appendChild(_7.domNode);
+_7.onClick=_6;
+return _7;
+};
+var _8=_3.containerNode.appendChild(document.createElement("span"));
+_8.innerHTML="Enter query:  ";
+_8.id="queryText";
+var _9=_3.containerNode.appendChild(document.createElement("input"));
+_9.type="text";
+_9.id="queryTextBox";
+_4("Query",function(){
+var _a=_9.value;
+_2.setQuery(_2.stringQueries?_a:dojo.fromJson(_a));
+});
+_3.containerNode.appendChild(document.createElement("span")).innerHTML="   ";
+var _b=_4("Create New",dojo.hitch(this,"createNew"));
+var _c=_4("Delete",function(){
+var _d=_e.selection.getSelected();
+for(var i=0;i<_d.length;i++){
+_2.store.deleteItem(_d[i]);
+}
+});
+this.setItemName=function(_10){
+_b.attr("label","<img style='width:12px; height:12px' src='"+dojo.moduleUrl("dijit.themes.tundra.images","dndCopy.png")+"' /> Create New "+_10);
+_c.attr("label","Delete "+_10);
+};
+_4("Save",function(){
+_2.store.save();
+_2.tree.refreshItem();
+});
+_4("Revert",function(){
+_2.store.revert();
+});
+_4("Add Column",function(){
+var _11=prompt("Enter column name:","property");
+if(_11){
+_2.gridLayout.push({field:_11,name:_11,formatter:dojo.hitch(_2,"_formatCell"),editable:true});
+_2.grid.attr("structure",_2.gridLayout);
+}
+});
+var _12=new dijit.layout.ContentPane({region:"center"}).placeAt(this);
+var _e=this.grid=new dojox.grid.DataGrid({store:this.store});
+_12.attr("content",_e);
+_e.canEdit=function(_13,_14){
+var _15=this._copyAttr(_14,_13.field);
+return !(_15&&typeof _15=="object")||_15 instanceof Date;
+};
+var _16=new dijit.layout.ContentPane({region:"trailing",splitter:true,style:"width: 300px"}).placeAt(this);
+var _17=this.tree=new dojox.data.ItemExplorer({store:this.store});
+_16.attr("content",_17);
+dojo.connect(_e,"onCellClick",function(){
+var _18=_e.selection.getSelected()[0];
+_17.setItem(_18);
+});
+this.gridOnFetchComplete=_e._onFetchComplete;
+this.setStore(this.store);
+},setQuery:function(_19){
+this.grid.setQuery(_19);
+},_formatCell:function(_1a){
+if(this.store.isItem(_1a)){
+return this.store.getLabel(_1a)||this.store.getIdentity(_1a);
+}
+return _1a;
+},setStore:function(_1b){
+this.store=_1b;
+var _1c=this;
+var _1d=this.grid;
+_1d._pending_requests[0]=false;
+function _1e(_1f){
+return _1c._formatCell(_1f);
+};
+var _20=this.gridOnFetchComplete;
+_1d._onFetchComplete=function(_21,req){
+var _23=_1c.gridLayout=[];
+var _24,key,_26,i,j,k,_2a=_1b.getIdentityAttributes();
+for(i=0;i<_2a.length;i++){
+key=_2a[i];
+_23.push({field:key,name:key,_score:100,formatter:_1e,editable:false});
+}
+for(i=0;_26=_21[i++];){
+var _2b=_1b.getAttributes(_26);
+for(k=0;key=_2b[k++];){
+var _2c=false;
+for(j=0;_24=_23[j++];){
+if(_24.field==key){
+_24._score++;
+_2c=true;
+break;
+}
+}
+if(!_2c){
+_23.push({field:key,name:key,_score:1,formatter:_1e,styles:"white-space:nowrap; ",editable:true});
+}
+}
+}
+_23=_23.sort(function(a,b){
+return a._score>b._score?-1:1;
+});
+for(j=0;_24=_23[j];j++){
+if(_24._score<_21.length/40*j){
+_23.splice(j,_23.length-j);
+break;
+}
+}
+for(j=0;_24=_23[j++];){
+_24.width=Math.round(100/_23.length)+"%";
+}
+_1d._onFetchComplete=_20;
+_1d.attr("structure",_23);
+var _2f=_20.apply(this,arguments);
+};
+_1d.setStore(_1b);
+this.queryOptions={cache:true};
+this.tree.setStore(_1b);
+},createNew:function(){
+var _30=prompt("Enter any properties to put in the new item (in JSON literal form):","{ }");
+if(_30){
+try{
+this.store.newItem(dojo.fromJson(_30));
+}
+catch(e){
+alert(e);
+}
+}
+}});
+}
diff --git a/dojox/data/WikipediaStore.js b/dojox/data/WikipediaStore.js
new file mode 100644
index 0000000..ae2f795
--- /dev/null
+++ b/dojox/data/WikipediaStore.js
@@ -0,0 +1,63 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.WikipediaStore"]){
+dojo._hasResource["dojox.data.WikipediaStore"]=true;
+dojo.provide("dojox.data.WikipediaStore");
+dojo.require("dojo.io.script");
+dojo.require("dojox.rpc.Service");
+dojo.require("dojox.data.ServiceStore");
+dojo.experimental("dojox.data.WikipediaStore");
+dojo.declare("dojox.data.WikipediaStore",dojox.data.ServiceStore,{constructor:function(_1){
+if(_1&&_1.service){
+this.service=_1.service;
+}else{
+var _2=new dojox.rpc.Service(dojo.moduleUrl("dojox.rpc.SMDLibrary","wikipedia.smd"));
+this.service=_2.query;
+}
+this.idAttribute=this.labelAttribute="title";
+},fetch:function(_3){
+var rq=dojo.mixin({},_3.query);
+if(rq&&(!rq.action||rq.action==="parse")){
+rq.action="parse";
+rq.page=rq.title;
+delete rq.title;
+}else{
+if(rq.action==="query"){
+rq.list="search";
+rq.srwhat="text";
+rq.srsearch=rq.text;
+if(_3.start){
+rq.sroffset=_3.start-1;
+}
+if(_3.count){
+rq.srlimit=_3.count>=500?500:_3.count;
+}
+delete rq.text;
+}
+}
+_3.query=rq;
+return this.inherited(arguments);
+},_processResults:function(_5,_6){
+if(_5.parse){
+_5.parse.title=dojo.queryToObject(_6.ioArgs.url.split("?")[1]).page;
+_5=[_5.parse];
+}else{
+if(_5.query&&_5.query.search){
+_5=_5.query.search;
+var _7=this;
+for(var i in _5){
+_5[i]._loadObject=function(_9){
+_7.fetch({query:{action:"parse",title:this.title},onItem:_9});
+delete this._loadObject;
+};
+}
+}
+}
+return this.inherited(arguments);
+}});
+}
diff --git a/dojox/data/XmlStore.js b/dojox/data/XmlStore.js
new file mode 100644
index 0000000..7bdf7db
--- /dev/null
+++ b/dojox/data/XmlStore.js
@@ -0,0 +1,917 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.XmlStore"]){
+dojo._hasResource["dojox.data.XmlStore"]=true;
+dojo.provide("dojox.data.XmlStore");
+dojo.provide("dojox.data.XmlItem");
+dojo.require("dojo.data.util.simpleFetch");
+dojo.require("dojo.data.util.filter");
+dojo.require("dojox.xml.parser");
+dojo.declare("dojox.data.XmlStore",null,{constructor:function(_1){
+if(_1){
+this.url=_1.url;
+this.rootItem=(_1.rootItem||_1.rootitem||this.rootItem);
+this.keyAttribute=(_1.keyAttribute||_1.keyattribute||this.keyAttribute);
+this._attributeMap=(_1.attributeMap||_1.attributemap);
+this.label=_1.label||this.label;
+this.sendQuery=(_1.sendQuery||_1.sendquery||this.sendQuery);
+}
+this._newItems=[];
+this._deletedItems=[];
+this._modifiedItems=[];
+},url:"",rootItem:"",keyAttribute:"",label:"",sendQuery:false,attributeMap:null,getValue:function(_2,_3,_4){
+var _5=_2.element;
+var i;
+var _7;
+if(_3==="tagName"){
+return _5.nodeName;
+}else{
+if(_3==="childNodes"){
+for(i=0;i<_5.childNodes.length;i++){
+_7=_5.childNodes[i];
+if(_7.nodeType===1){
+return this._getItem(_7);
+}
+}
+return _4;
+}else{
+if(_3==="text()"){
+for(i=0;i<_5.childNodes.length;i++){
+_7=_5.childNodes[i];
+if(_7.nodeType===3||_7.nodeType===4){
+return _7.nodeValue;
+}
+}
+return _4;
+}else{
+_3=this._getAttribute(_5.nodeName,_3);
+if(_3.charAt(0)==="@"){
+var _8=_3.substring(1);
+var _9=_5.getAttribute(_8);
+return (_9!==undefined)?_9:_4;
+}else{
+for(i=0;i<_5.childNodes.length;i++){
+_7=_5.childNodes[i];
+if(_7.nodeType===1&&_7.nodeName===_3){
+return this._getItem(_7);
+}
+}
+return _4;
+}
+}
+}
+}
+},getValues:function(_a,_b){
+var _c=_a.element;
+var _d=[];
+var i;
+var _f;
+if(_b==="tagName"){
+return [_c.nodeName];
+}else{
+if(_b==="childNodes"){
+for(i=0;i<_c.childNodes.length;i++){
+_f=_c.childNodes[i];
+if(_f.nodeType===1){
+_d.push(this._getItem(_f));
+}
+}
+return _d;
+}else{
+if(_b==="text()"){
+var ec=_c.childNodes;
+for(i=0;i<ec.length;i++){
+_f=ec[i];
+if(_f.nodeType===3||_f.nodeType===4){
+_d.push(_f.nodeValue);
+}
+}
+return _d;
+}else{
+_b=this._getAttribute(_c.nodeName,_b);
+if(_b.charAt(0)==="@"){
+var _11=_b.substring(1);
+var _12=_c.getAttribute(_11);
+return (_12!==undefined)?[_12]:[];
+}else{
+for(i=0;i<_c.childNodes.length;i++){
+_f=_c.childNodes[i];
+if(_f.nodeType===1&&_f.nodeName===_b){
+_d.push(this._getItem(_f));
+}
+}
+return _d;
+}
+}
+}
+}
+},getAttributes:function(_13){
+var _14=_13.element;
+var _15=[];
+var i;
+_15.push("tagName");
+if(_14.childNodes.length>0){
+var _17={};
+var _18=true;
+var _19=false;
+for(i=0;i<_14.childNodes.length;i++){
+var _1a=_14.childNodes[i];
+if(_1a.nodeType===1){
+var _1b=_1a.nodeName;
+if(!_17[_1b]){
+_15.push(_1b);
+_17[_1b]=_1b;
+}
+_18=true;
+}else{
+if(_1a.nodeType===3){
+_19=true;
+}
+}
+}
+if(_18){
+_15.push("childNodes");
+}
+if(_19){
+_15.push("text()");
+}
+}
+for(i=0;i<_14.attributes.length;i++){
+_15.push("@"+_14.attributes[i].nodeName);
+}
+if(this._attributeMap){
+for(var key in this._attributeMap){
+i=key.indexOf(".");
+if(i>0){
+var _1d=key.substring(0,i);
+if(_1d===_14.nodeName){
+_15.push(key.substring(i+1));
+}
+}else{
+_15.push(key);
+}
+}
+}
+return _15;
+},hasAttribute:function(_1e,_1f){
+return (this.getValue(_1e,_1f)!==undefined);
+},containsValue:function(_20,_21,_22){
+var _23=this.getValues(_20,_21);
+for(var i=0;i<_23.length;i++){
+if((typeof _22==="string")){
+if(_23[i].toString&&_23[i].toString()===_22){
+return true;
+}
+}else{
+if(_23[i]===_22){
+return true;
+}
+}
+}
+return false;
+},isItem:function(_25){
+if(_25&&_25.element&&_25.store&&_25.store===this){
+return true;
+}
+return false;
+},isItemLoaded:function(_26){
+return this.isItem(_26);
+},loadItem:function(_27){
+},getFeatures:function(){
+var _28={"dojo.data.api.Read":true,"dojo.data.api.Write":true};
+if(!this.sendQuery||this.keyAttribute!==""){
+_28["dojo.data.api.Identity"]=true;
+}
+return _28;
+},getLabel:function(_29){
+if((this.label!=="")&&this.isItem(_29)){
+var _2a=this.getValue(_29,this.label);
+if(_2a){
+return _2a.toString();
+}
+}
+return undefined;
+},getLabelAttributes:function(_2b){
+if(this.label!==""){
+return [this.label];
+}
+return null;
+},_fetchItems:function(_2c,_2d,_2e){
+var url=this._getFetchUrl(_2c);
+
+if(!url){
+_2e(new Error("No URL specified."));
+return;
+}
+var _30=(!this.sendQuery?_2c:{});
+var _31=this;
+var _32={url:url,handleAs:"xml",preventCache:true};
+var _33=dojo.xhrGet(_32);
+_33.addCallback(function(_34){
+var _35=_31._getItems(_34,_30);
+
+if(_35&&_35.length>0){
+_2d(_35,_2c);
+}else{
+_2d([],_2c);
+}
+});
+_33.addErrback(function(_36){
+_2e(_36,_2c);
+});
+},_getFetchUrl:function(_37){
+if(!this.sendQuery){
+return this.url;
+}
+var _38=_37.query;
+if(!_38){
+return this.url;
+}
+if(dojo.isString(_38)){
+return this.url+_38;
+}
+var _39="";
+for(var _3a in _38){
+var _3b=_38[_3a];
+if(_3b){
+if(_39){
+_39+="&";
+}
+_39+=(_3a+"="+_3b);
+}
+}
+if(!_39){
+return this.url;
+}
+var _3c=this.url;
+if(_3c.indexOf("?")<0){
+_3c+="?";
+}else{
+_3c+="&";
+}
+return _3c+_39;
+},_getItems:function(_3d,_3e){
+var _3f=null;
+if(_3e){
+_3f=_3e.query;
+}
+var _40=[];
+var _41=null;
+if(this.rootItem!==""){
+_41=dojo.query(this.rootItem,_3d);
+}else{
+_41=_3d.documentElement.childNodes;
+}
+var _42=_3e.queryOptions?_3e.queryOptions.deep:false;
+if(_42){
+_41=this._flattenNodes(_41);
+}
+for(var i=0;i<_41.length;i++){
+var _44=_41[i];
+if(_44.nodeType!=1){
+continue;
+}
+var _45=this._getItem(_44);
+if(_3f){
+var _46=true;
+var _47=_3e.queryOptions?_3e.queryOptions.ignoreCase:false;
+var _48;
+var _49={};
+for(var key in _3f){
+_48=_3f[key];
+if(typeof _48==="string"){
+_49[key]=dojo.data.util.filter.patternToRegExp(_48,_47);
+}
+}
+for(var _4b in _3f){
+_48=this.getValue(_45,_4b);
+if(_48){
+var _4c=_3f[_4b];
+if((typeof _48)==="string"&&(_49[_4b])){
+if((_48.match(_49[_4b]))!==null){
+continue;
+}
+}else{
+if((typeof _48)==="object"){
+if(_48.toString&&(_49[_4b])){
+var _4d=_48.toString();
+if((_4d.match(_49[_4b]))!==null){
+continue;
+}
+}else{
+if(_4c==="*"||_4c===_48){
+continue;
+}
+}
+}
+}
+}
+_46=false;
+break;
+}
+if(!_46){
+continue;
+}
+}
+_40.push(_45);
+}
+dojo.forEach(_40,function(_4e){
+_4e.element.parentNode.removeChild(_4e.element);
+},this);
+return _40;
+},_flattenNodes:function(_4f){
+var _50=[];
+if(_4f){
+var i;
+for(i=0;i<_4f.length;i++){
+var _52=_4f[i];
+_50.push(_52);
+if(_52.childNodes&&_52.childNodes.length>0){
+_50=_50.concat(this._flattenNodes(_52.childNodes));
+}
+}
+}
+return _50;
+},close:function(_53){
+},newItem:function(_54,_55){
+
+_54=(_54||{});
+var _56=_54.tagName;
+if(!_56){
+_56=this.rootItem;
+if(_56===""){
+return null;
+}
+}
+var _57=this._getDocument();
+var _58=_57.createElement(_56);
+for(var _59 in _54){
+var _5a;
+if(_59==="tagName"){
+continue;
+}else{
+if(_59==="text()"){
+_5a=_57.createTextNode(_54[_59]);
+_58.appendChild(_5a);
+}else{
+_59=this._getAttribute(_56,_59);
+if(_59.charAt(0)==="@"){
+var _5b=_59.substring(1);
+_58.setAttribute(_5b,_54[_59]);
+}else{
+var _5c=_57.createElement(_59);
+_5a=_57.createTextNode(_54[_59]);
+_5c.appendChild(_5a);
+_58.appendChild(_5c);
+}
+}
+}
+}
+var _5d=this._getItem(_58);
+this._newItems.push(_5d);
+var _5e=null;
+if(_55&&_55.parent&&_55.attribute){
+_5e={item:_55.parent,attribute:_55.attribute,oldValue:undefined};
+var _5f=this.getValues(_55.parent,_55.attribute);
+if(_5f&&_5f.length>0){
+var _60=_5f.slice(0,_5f.length);
+if(_5f.length===1){
+_5e.oldValue=_5f[0];
+}else{
+_5e.oldValue=_5f.slice(0,_5f.length);
+}
+_60.push(_5d);
+this.setValues(_55.parent,_55.attribute,_60);
+_5e.newValue=this.getValues(_55.parent,_55.attribute);
+}else{
+this.setValues(_55.parent,_55.attribute,_5d);
+_5e.newValue=_5d;
+}
+}
+return _5d;
+},deleteItem:function(_61){
+
+var _62=_61.element;
+if(_62.parentNode){
+this._backupItem(_61);
+_62.parentNode.removeChild(_62);
+return true;
+}
+this._forgetItem(_61);
+this._deletedItems.push(_61);
+return true;
+},setValue:function(_63,_64,_65){
+if(_64==="tagName"){
+return false;
+}
+this._backupItem(_63);
+var _66=_63.element;
+var _67;
+var _68;
+if(_64==="childNodes"){
+_67=_65.element;
+_66.appendChild(_67);
+}else{
+if(_64==="text()"){
+while(_66.firstChild){
+_66.removeChild(_66.firstChild);
+}
+_68=this._getDocument(_66).createTextNode(_65);
+_66.appendChild(_68);
+}else{
+_64=this._getAttribute(_66.nodeName,_64);
+if(_64.charAt(0)==="@"){
+var _69=_64.substring(1);
+_66.setAttribute(_69,_65);
+}else{
+for(var i=0;i<_66.childNodes.length;i++){
+var _6b=_66.childNodes[i];
+if(_6b.nodeType===1&&_6b.nodeName===_64){
+_67=_6b;
+break;
+}
+}
+var _6c=this._getDocument(_66);
+if(_67){
+while(_67.firstChild){
+_67.removeChild(_67.firstChild);
+}
+}else{
+_67=_6c.createElement(_64);
+_66.appendChild(_67);
+}
+_68=_6c.createTextNode(_65);
+_67.appendChild(_68);
+}
+}
+}
+return true;
+},setValues:function(_6d,_6e,_6f){
+if(_6e==="tagName"){
+return false;
+}
+this._backupItem(_6d);
+var _70=_6d.element;
+var i;
+var _72;
+var _73;
+if(_6e==="childNodes"){
+while(_70.firstChild){
+_70.removeChild(_70.firstChild);
+}
+for(i=0;i<_6f.length;i++){
+_72=_6f[i].element;
+_70.appendChild(_72);
+}
+}else{
+if(_6e==="text()"){
+while(_70.firstChild){
+_70.removeChild(_70.firstChild);
+}
+var _74="";
+for(i=0;i<_6f.length;i++){
+_74+=_6f[i];
+}
+_73=this._getDocument(_70).createTextNode(_74);
+_70.appendChild(_73);
+}else{
+_6e=this._getAttribute(_70.nodeName,_6e);
+if(_6e.charAt(0)==="@"){
+var _75=_6e.substring(1);
+_70.setAttribute(_75,_6f[0]);
+}else{
+for(i=_70.childNodes.length-1;i>=0;i--){
+var _76=_70.childNodes[i];
+if(_76.nodeType===1&&_76.nodeName===_6e){
+_70.removeChild(_76);
+}
+}
+var _77=this._getDocument(_70);
+for(i=0;i<_6f.length;i++){
+_72=_77.createElement(_6e);
+_73=_77.createTextNode(_6f[i]);
+_72.appendChild(_73);
+_70.appendChild(_72);
+}
+}
+}
+}
+return true;
+},unsetAttribute:function(_78,_79){
+if(_79==="tagName"){
+return false;
+}
+this._backupItem(_78);
+var _7a=_78.element;
+if(_79==="childNodes"||_79==="text()"){
+while(_7a.firstChild){
+_7a.removeChild(_7a.firstChild);
+}
+}else{
+_79=this._getAttribute(_7a.nodeName,_79);
+if(_79.charAt(0)==="@"){
+var _7b=_79.substring(1);
+_7a.removeAttribute(_7b);
+}else{
+for(var i=_7a.childNodes.length-1;i>=0;i--){
+var _7d=_7a.childNodes[i];
+if(_7d.nodeType===1&&_7d.nodeName===_79){
+_7a.removeChild(_7d);
+}
+}
+}
+}
+return true;
+},save:function(_7e){
+if(!_7e){
+_7e={};
+}
+var i;
+for(i=0;i<this._modifiedItems.length;i++){
+this._saveItem(this._modifiedItems[i],_7e,"PUT");
+}
+for(i=0;i<this._newItems.length;i++){
+var _80=this._newItems[i];
+if(_80.element.parentNode){
+this._newItems.splice(i,1);
+i--;
+continue;
+}
+this._saveItem(this._newItems[i],_7e,"POST");
+}
+for(i=0;i<this._deletedItems.length;i++){
+this._saveItem(this._deletedItems[i],_7e,"DELETE");
+}
+},revert:function(){
+
+
+
+this._newItems=[];
+this._restoreItems(this._deletedItems);
+this._deletedItems=[];
+this._restoreItems(this._modifiedItems);
+this._modifiedItems=[];
+return true;
+},isDirty:function(_81){
+if(_81){
+var _82=this._getRootElement(_81.element);
+return (this._getItemIndex(this._newItems,_82)>=0||this._getItemIndex(this._deletedItems,_82)>=0||this._getItemIndex(this._modifiedItems,_82)>=0);
+}else{
+return (this._newItems.length>0||this._deletedItems.length>0||this._modifiedItems.length>0);
+}
+},_saveItem:function(_83,_84,_85){
+var url;
+var _87;
+if(_85==="PUT"){
+url=this._getPutUrl(_83);
+}else{
+if(_85==="DELETE"){
+url=this._getDeleteUrl(_83);
+}else{
+url=this._getPostUrl(_83);
+}
+}
+if(!url){
+if(_84.onError){
+_87=_84.scope||dojo.global;
+_84.onError.call(_87,new Error("No URL for saving content: "+this._getPostContent(_83)));
+}
+return;
+}
+var _88={url:url,method:(_85||"POST"),contentType:"text/xml",handleAs:"xml"};
+var _89;
+if(_85==="PUT"){
+_88.putData=this._getPutContent(_83);
+_89=dojo.rawXhrPut(_88);
+}else{
+if(_85==="DELETE"){
+_89=dojo.xhrDelete(_88);
+}else{
+_88.postData=this._getPostContent(_83);
+_89=dojo.rawXhrPost(_88);
+}
+}
+_87=(_84.scope||dojo.global);
+var _8a=this;
+_89.addCallback(function(_8b){
+_8a._forgetItem(_83);
+if(_84.onComplete){
+_84.onComplete.call(_87);
+}
+});
+_89.addErrback(function(_8c){
+if(_84.onError){
+_84.onError.call(_87,_8c);
+}
+});
+},_getPostUrl:function(_8d){
+return this.url;
+},_getPutUrl:function(_8e){
+return this.url;
+},_getDeleteUrl:function(_8f){
+var url=this.url;
+if(_8f&&this.keyAttribute!==""){
+var _91=this.getValue(_8f,this.keyAttribute);
+if(_91){
+var key=this.keyAttribute.charAt(0)==="@"?this.keyAttribute.substring(1):this.keyAttribute;
+url+=url.indexOf("?")<0?"?":"&";
+url+=key+"="+_91;
+}
+}
+return url;
+},_getPostContent:function(_93){
+var _94=_93.element;
+var _95="<?xml version=\"1.0\"?>";
+return _95+dojox.xml.parser.innerXML(_94);
+},_getPutContent:function(_96){
+var _97=_96.element;
+var _98="<?xml version=\"1.0\"?>";
+return _98+dojox.xml.parser.innerXML(_97);
+},_getAttribute:function(_99,_9a){
+if(this._attributeMap){
+var key=_99+"."+_9a;
+var _9c=this._attributeMap[key];
+if(_9c){
+_9a=_9c;
+}else{
+_9c=this._attributeMap[_9a];
+if(_9c){
+_9a=_9c;
+}
+}
+}
+return _9a;
+},_getItem:function(_9d){
+try{
+var q=null;
+if(this.keyAttribute===""){
+q=this._getXPath(_9d);
+}
+return new dojox.data.XmlItem(_9d,this,q);
+}
+catch(e){
+
+}
+return null;
+},_getItemIndex:function(_9f,_a0){
+for(var i=0;i<_9f.length;i++){
+if(_9f[i].element===_a0){
+return i;
+}
+}
+return -1;
+},_backupItem:function(_a2){
+var _a3=this._getRootElement(_a2.element);
+if(this._getItemIndex(this._newItems,_a3)>=0||this._getItemIndex(this._modifiedItems,_a3)>=0){
+return;
+}
+if(_a3!=_a2.element){
+_a2=this._getItem(_a3);
+}
+_a2._backup=_a3.cloneNode(true);
+this._modifiedItems.push(_a2);
+},_restoreItems:function(_a4){
+dojo.forEach(_a4,function(_a5){
+if(_a5._backup){
+_a5.element=_a5._backup;
+_a5._backup=null;
+}
+},this);
+},_forgetItem:function(_a6){
+var _a7=_a6.element;
+var _a8=this._getItemIndex(this._newItems,_a7);
+if(_a8>=0){
+this._newItems.splice(_a8,1);
+}
+_a8=this._getItemIndex(this._deletedItems,_a7);
+if(_a8>=0){
+this._deletedItems.splice(_a8,1);
+}
+_a8=this._getItemIndex(this._modifiedItems,_a7);
+if(_a8>=0){
+this._modifiedItems.splice(_a8,1);
+}
+},_getDocument:function(_a9){
+if(_a9){
+return _a9.ownerDocument;
+}else{
+if(!this._document){
+return dojox.xml.parser.parse();
+}
+}
+return null;
+},_getRootElement:function(_aa){
+while(_aa.parentNode){
+_aa=_aa.parentNode;
+}
+return _aa;
+},_getXPath:function(_ab){
+var _ac=null;
+if(!this.sendQuery){
+var _ad=_ab;
+_ac="";
+while(_ad&&_ad!=_ab.ownerDocument){
+var pos=0;
+var _af=_ad;
+var _b0=_ad.nodeName;
+while(_af){
+_af=_af.previousSibling;
+if(_af&&_af.nodeName===_b0){
+pos++;
+}
+}
+var _b1="/"+_b0+"["+pos+"]";
+if(_ac){
+_ac=_b1+_ac;
+}else{
+_ac=_b1;
+}
+_ad=_ad.parentNode;
+}
+}
+return _ac;
+},getIdentity:function(_b2){
+if(!this.isItem(_b2)){
+throw new Error("dojox.data.XmlStore: Object supplied to getIdentity is not an item");
+}else{
+var id=null;
+if(this.sendQuery&&this.keyAttribute!==""){
+id=this.getValue(_b2,this.keyAttribute).toString();
+}else{
+if(!this.serverQuery){
+if(this.keyAttribute!==""){
+id=this.getValue(_b2,this.keyAttribute).toString();
+}else{
+id=_b2.q;
+}
+}
+}
+return id;
+}
+},getIdentityAttributes:function(_b4){
+if(!this.isItem(_b4)){
+throw new Error("dojox.data.XmlStore: Object supplied to getIdentity is not an item");
+}else{
+if(this.keyAttribute!==""){
+return [this.keyAttribute];
+}else{
+return null;
+}
+}
+},fetchItemByIdentity:function(_b5){
+var _b6=null;
+var _b7=null;
+var _b8=this;
+var url=null;
+var _ba=null;
+var _bb=null;
+if(!_b8.sendQuery){
+_b6=function(_bc){
+if(_bc){
+if(_b8.keyAttribute!==""){
+var _bd={};
+_bd.query={};
+_bd.query[_b8.keyAttribute]=_b5.identity;
+var _be=_b8._getItems(_bc,_bd);
+_b7=_b5.scope||dojo.global;
+if(_be.length===1){
+if(_b5.onItem){
+_b5.onItem.call(_b7,_be[0]);
+}
+}else{
+if(_be.length===0){
+if(_b5.onItem){
+_b5.onItem.call(_b7,null);
+}
+}else{
+if(_b5.onError){
+_b5.onError.call(_b7,new Error("Items array size for identity lookup greater than 1, invalid keyAttribute."));
+}
+}
+}
+}else{
+var _bf=_b5.identity.split("/");
+var i;
+var _c1=_bc;
+for(i=0;i<_bf.length;i++){
+if(_bf[i]&&_bf[i]!==""){
+var _c2=_bf[i];
+_c2=_c2.substring(0,_c2.length-1);
+var _c3=_c2.split("[");
+var tag=_c3[0];
+var _c5=parseInt(_c3[1],10);
+var pos=0;
+if(_c1){
+var _c7=_c1.childNodes;
+if(_c7){
+var j;
+var _c9=null;
+for(j=0;j<_c7.length;j++){
+var _ca=_c7[j];
+if(_ca.nodeName===tag){
+if(pos<_c5){
+pos++;
+}else{
+_c9=_ca;
+break;
+}
+}
+}
+if(_c9){
+_c1=_c9;
+}else{
+_c1=null;
+}
+}else{
+_c1=null;
+}
+}else{
+break;
+}
+}
+}
+var _cb=null;
+if(_c1){
+_cb=_b8._getItem(_c1);
+_cb.element.parentNode.removeChild(_cb.element);
+}
+if(_b5.onItem){
+_b7=_b5.scope||dojo.global;
+_b5.onItem.call(_b7,_cb);
+}
+}
+}
+};
+url=this._getFetchUrl(null);
+_ba={url:url,handleAs:"xml",preventCache:true};
+_bb=dojo.xhrGet(_ba);
+_bb.addCallback(_b6);
+if(_b5.onError){
+_bb.addErrback(function(_cc){
+var s=_b5.scope||dojo.global;
+_b5.onError.call(s,_cc);
+});
+}
+}else{
+if(_b8.keyAttribute!==""){
+var _ce={query:{}};
+_ce.query[_b8.keyAttribute]=_b5.identity;
+url=this._getFetchUrl(_ce);
+_b6=function(_cf){
+var _d0=null;
+if(_cf){
+var _d1=_b8._getItems(_d1,{});
+if(_d1.length===1){
+_d0=_d1[0];
+}else{
+if(_b5.onError){
+var _d2=_b5.scope||dojo.global;
+_b5.onError.call(_d2,new Error("More than one item was returned from the server for the denoted identity"));
+}
+}
+}
+if(_b5.onItem){
+_d2=_b5.scope||dojo.global;
+_b5.onItem.call(_d2,_d0);
+}
+};
+_ba={url:url,handleAs:"xml",preventCache:true};
+_bb=dojo.xhrGet(_ba);
+_bb.addCallback(_b6);
+if(_b5.onError){
+_bb.addErrback(function(_d3){
+var s=_b5.scope||dojo.global;
+_b5.onError.call(s,_d3);
+});
+}
+}else{
+if(_b5.onError){
+var s=_b5.scope||dojo.global;
+_b5.onError.call(s,new Error("XmlStore is not told that the server to provides identity support.  No keyAttribute specified."));
+}
+}
+}
+}});
+dojo.declare("dojox.data.XmlItem",null,{constructor:function(_d6,_d7,_d8){
+this.element=_d6;
+this.store=_d7;
+this.q=_d8;
+},toString:function(){
+var str="";
+if(this.element){
+for(var i=0;i<this.element.childNodes.length;i++){
+var _db=this.element.childNodes[i];
+if(_db.nodeType===3||_db.nodeType===4){
+str+=_db.nodeValue;
+}
+}
+}
+return str;
+}});
+dojo.extend(dojox.data.XmlStore,dojo.data.util.simpleFetch);
+}
diff --git a/dojox/data/css.js b/dojox/data/css.js
new file mode 100644
index 0000000..40eb3d5
--- /dev/null
+++ b/dojox/data/css.js
@@ -0,0 +1,91 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.css"]){
+dojo._hasResource["dojox.data.css"]=true;
+dojo.provide("dojox.data.css");
+dojo.provide("dojox.data.css.rules");
+dojox.data.css.rules.forEach=function(fn,_2,_3){
+if(_3){
+var _4=function(_5){
+dojo.forEach(_5[_5.cssRules?"cssRules":"rules"],function(_6){
+if(!_6.type||_6.type!==3){
+var _7="";
+if(_5&&_5.href){
+_7=_5.href;
+}
+fn.call(_2?_2:this,_6,_5,_7);
+}
+});
+};
+dojo.forEach(_3,_4);
+}
+};
+dojox.data.css.findStyleSheets=function(_8){
+var _9=[];
+var _a=function(_b){
+var s=dojox.data.css.findStyleSheet(_b);
+if(s){
+dojo.forEach(s,function(_d){
+if(dojo.indexOf(_9,_d)===-1){
+_9.push(_d);
+}
+});
+}
+};
+dojo.forEach(_8,_a);
+return _9;
+};
+dojox.data.css.findStyleSheet=function(_e){
+var _f=[];
+if(_e.charAt(0)==="."){
+_e=_e.substring(1);
+}
+var _10=function(_11){
+if(_11.href&&_11.href.match(_e)){
+_f.push(_11);
+return true;
+}
+if(_11.imports){
+return dojo.some(_11.imports,function(_12){
+return _10(_12);
+});
+}
+return dojo.some(_11[_11.cssRules?"cssRules":"rules"],function(_13){
+if(_13.type&&_13.type===3&&_10(_13.styleSheet)){
+return true;
+}
+return false;
+});
+};
+dojo.some(document.styleSheets,_10);
+return _f;
+};
+dojox.data.css.determineContext=function(_14){
+var ret=[];
+if(_14&&_14.length>0){
+_14=dojox.data.css.findStyleSheets(_14);
+}else{
+_14=document.styleSheets;
+}
+var _16=function(_17){
+ret.push(_17);
+if(_17.imports){
+dojo.forEach(_17.imports,function(_18){
+_16(_18);
+});
+}
+dojo.forEach(_17[_17.cssRules?"cssRules":"rules"],function(_19){
+if(_19.type&&_19.type===3){
+_16(_19.styleSheet);
+}
+});
+};
+dojo.forEach(_14,_16);
+return ret;
+};
+}
diff --git a/dojox/data/dom.js b/dojox/data/dom.js
new file mode 100644
index 0000000..800a338
--- /dev/null
+++ b/dojox/data/dom.js
@@ -0,0 +1,42 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.dom"]){
+dojo._hasResource["dojox.data.dom"]=true;
+dojo.provide("dojox.data.dom");
+dojo.require("dojox.xml.parser");
+dojo.deprecated("dojox.data.dom","Use dojox.xml.parser instead.","2.0");
+dojox.data.dom.createDocument=function(_1,_2){
+dojo.deprecated("dojox.data.dom.createDocument()","Use dojox.xml.parser.parse() instead.","2.0");
+try{
+return dojox.xml.parser.parse(_1,_2);
+}
+catch(e){
+return null;
+}
+};
+dojox.data.dom.textContent=function(_3,_4){
+dojo.deprecated("dojox.data.dom.textContent()","Use dojox.xml.parser.textContent() instead.","2.0");
+if(arguments.length>1){
+return dojox.xml.parser.textContent(_3,_4);
+}else{
+return dojox.xml.parser.textContent(_3);
+}
+};
+dojox.data.dom.replaceChildren=function(_5,_6){
+dojo.deprecated("dojox.data.dom.replaceChildren()","Use dojox.xml.parser.replaceChildren() instead.","2.0");
+dojox.xml.parser.replaceChildren(_5,_6);
+};
+dojox.data.dom.removeChildren=function(_7){
+dojo.deprecated("dojox.data.dom.removeChildren()","Use dojox.xml.parser.removeChildren() instead.","2.0");
+return dojox.xml.parser.removeChildren(_7);
+};
+dojox.data.dom.innerXML=function(_8){
+dojo.deprecated("dojox.data.dom.innerXML()","Use dojox.xml.parser.innerXML() instead.","2.0");
+return dojox.xml.parser.innerXML(_8);
+};
+}
diff --git a/dojox/data/jsonPathStore.js b/dojox/data/jsonPathStore.js
new file mode 100644
index 0000000..c041c1d
--- /dev/null
+++ b/dojox/data/jsonPathStore.js
@@ -0,0 +1,670 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.jsonPathStore"]){
+dojo._hasResource["dojox.data.jsonPathStore"]=true;
+dojo.provide("dojox.data.jsonPathStore");
+dojo.require("dojox.jsonPath");
+dojo.require("dojo.date");
+dojo.require("dojo.date.locale");
+dojo.require("dojo.date.stamp");
+dojox.data.ASYNC_MODE=0;
+dojox.data.SYNC_MODE=1;
+dojo.declare("dojox.data.jsonPathStore",null,{mode:dojox.data.ASYNC_MODE,metaLabel:"_meta",hideMetaAttributes:false,autoIdPrefix:"_auto_",autoIdentity:true,idAttribute:"_id",indexOnLoad:true,labelAttribute:"",url:"",_replaceRegex:/\'\]/gi,noRevert:false,constructor:function(_1){
+this.byId=this.fetchItemByIdentity;
+if(_1){
+dojo.mixin(this,_1);
+}
+this._dirtyItems=[];
+this._autoId=0;
+this._referenceId=0;
+this._references={};
+this._fetchQueue=[];
+this.index={};
+var _2="("+this.metaLabel+"'])";
+this.metaRegex=new RegExp(_2);
+if(!this.data&&!this.url){
+this.setData({});
+}
+if(this.data&&!this.url){
+this.setData(this.data);
+delete this.data;
+}
+if(this.url){
+dojo.xhrGet({url:_1.url,handleAs:"json",load:dojo.hitch(this,"setData"),sync:this.mode});
+}
+},_loadData:function(_3){
+if(this._data){
+delete this._data;
+}
+if(dojo.isString(_3)){
+this._data=dojo.fromJson(_3);
+}else{
+this._data=_3;
+}
+if(this.indexOnLoad){
+this.buildIndex();
+}
+this._updateMeta(this._data,{path:"$"});
+this.onLoadData(this._data);
+},onLoadData:function(_4){
+while(this._fetchQueue.length>0){
+var _5=this._fetchQueue.shift();
+this.fetch(_5);
+}
+},setData:function(_6){
+this._loadData(_6);
+},buildIndex:function(_7,_8){
+if(!this.idAttribute){
+throw new Error("buildIndex requires idAttribute for the store");
+}
+_8=_8||this._data;
+var _9=_7;
+_7=_7||"$";
+_7+="[*]";
+var _a=this.fetch({query:_7,mode:dojox.data.SYNC_MODE});
+for(var i=0;i<_a.length;i++){
+var _c,_d;
+if(dojo.isObject(_a[i])){
+var _e=_a[i][this.metaLabel]["path"];
+if(_9){
+_c=_9.split("['");
+_d=_c[_c.length-1].replace(this._replaceRegex,"");
+if(!dojo.isArray(_a[i])){
+this._addReference(_a[i],{parent:_8,attribute:_d});
+this.buildIndex(_e,_a[i]);
+}else{
+this.buildIndex(_e,_8);
+}
+}else{
+_c=_e.split("['");
+_d=_c[_c.length-1].replace(this._replaceRegex,"");
+this._addReference(_a[i],{parent:this._data,attribute:_d});
+this.buildIndex(_e,_a[i]);
+}
+}
+}
+},_correctReference:function(_f){
+if(this.index[_f[this.idAttribute]]&&(this.index[_f[this.idAttribute]][this.metaLabel]===_f[this.metaLabel])){
+return this.index[_f[this.idAttribute]];
+}
+return _f;
+},getValue:function(_10,_11){
+_10=this._correctReference(_10);
+return _10[_11];
+},getValues:function(_12,_13){
+_12=this._correctReference(_12);
+return dojo.isArray(_12[_13])?_12[_13]:[_12[_13]];
+},getAttributes:function(_14){
+_14=this._correctReference(_14);
+var res=[];
+for(var i in _14){
+if(this.hideMetaAttributes&&(i==this.metaLabel)){
+continue;
+}
+res.push(i);
+}
+return res;
+},hasAttribute:function(_17,_18){
+_17=this._correctReference(_17);
+if(_18 in _17){
+return true;
+}
+return false;
+},containsValue:function(_19,_1a,_1b){
+_19=this._correctReference(_19);
+if(_19[_1a]&&_19[_1a]==_1b){
+return true;
+}
+if(dojo.isObject(_19[_1a])||dojo.isObject(_1b)){
+if(this._shallowCompare(_19[_1a],_1b)){
+return true;
+}
+}
+return false;
+},_shallowCompare:function(a,b){
+if((dojo.isObject(a)&&!dojo.isObject(b))||(dojo.isObject(b)&&!dojo.isObject(a))){
+return false;
+}
+if(a["getFullYear"]||b["getFullYear"]){
+if((a["getFullYear"]&&!b["getFullYear"])||(b["getFullYear"]&&!a["getFullYear"])){
+return false;
+}else{
+if(!dojo.date.compare(a,b)){
+return true;
+}
+return false;
+}
+}
+for(var i in b){
+if(dojo.isObject(b[i])){
+if(!a[i]||!dojo.isObject(a[i])){
+return false;
+}
+if(b[i]["getFullYear"]){
+if(!a[i]["getFullYear"]){
+return false;
+}
+if(dojo.date.compare(a,b)){
+return false;
+}
+}else{
+if(!this._shallowCompare(a[i],b[i])){
+return false;
+}
+}
+}else{
+if(!b[i]||(a[i]!=b[i])){
+return false;
+}
+}
+}
+for(i in a){
+if(!b[i]){
+return false;
+}
+}
+return true;
+},isItem:function(_1f){
+if(!dojo.isObject(_1f)||!_1f[this.metaLabel]){
+return false;
+}
+if(this.requireId&&this._hasId&&!_1f[this._id]){
+return false;
+}
+return true;
+},isItemLoaded:function(_20){
+_20=this._correctReference(_20);
+return this.isItem(_20);
+},loadItem:function(_21){
+return true;
+},_updateMeta:function(_22,_23){
+if(_22&&_22[this.metaLabel]){
+dojo.mixin(_22[this.metaLabel],_23);
+return;
+}
+_22[this.metaLabel]=_23;
+},cleanMeta:function(_24,_25){
+_24=_24||this._data;
+if(_24[this.metaLabel]){
+if(_24[this.metaLabel].autoId){
+delete _24[this.idAttribute];
+}
+delete _24[this.metaLabel];
+}
+if(dojo.isArray(_24)){
+for(var i=0;i<_24.length;i++){
+if(dojo.isObject(_24[i])||dojo.isArray(_24[i])){
+this.cleanMeta(_24[i]);
+}
+}
+}else{
+if(dojo.isObject(_24)){
+for(i in _24){
+if(dojo.isObject(_24[i])){
+this.cleanMeta(_24[i]);
+}
+}
+}
+}
+},fetch:function(_27){
+if(!this._data){
+this._fetchQueue.push(_27);
+return _27;
+}
+if(dojo.isString(_27)){
+_28=_27;
+_27={query:_28,mode:dojox.data.SYNC_MODE};
+}
+var _28;
+if(!_27||!_27.query){
+if(!_27){
+var _27={};
+}
+if(!_27.query){
+_27.query="$..*";
+_28=_27.query;
+}
+}
+if(dojo.isObject(_27.query)){
+if(_27.query.query){
+_28=_27.query.query;
+}else{
+_28=_27.query="$..*";
+}
+if(_27.query.queryOptions){
+_27.queryOptions=_27.query.queryOptions;
+}
+}else{
+_28=_27.query;
+}
+if(!_27.mode){
+_27.mode=this.mode;
+}
+if(!_27.queryOptions){
+_27.queryOptions={};
+}
+_27.queryOptions.resultType="BOTH";
+var _29=dojox.jsonPath.query(this._data,_28,_27.queryOptions);
+var tmp=[];
+var _2b=0;
+for(var i=0;i<_29.length;i++){
+if(_27.start&&i<_27.start){
+continue;
+}
+if(_27.count&&(_2b>=_27.count)){
+continue;
+}
+var _2d=_29[i]["value"];
+var _2e=_29[i]["path"];
+if(!dojo.isObject(_2d)){
+continue;
+}
+if(this.metaRegex.exec(_2e)){
+continue;
+}
+this._updateMeta(_2d,{path:_29[i].path});
+if(this.autoIdentity&&!_2d[this.idAttribute]){
+var _2f=this.autoIdPrefix+this._autoId++;
+_2d[this.idAttribute]=_2f;
+_2d[this.metaLabel].autoId=true;
+}
+if(_2d[this.idAttribute]){
+this.index[_2d[this.idAttribute]]=_2d;
+}
+_2b++;
+tmp.push(_2d);
+}
+_29=tmp;
+var _30=_27.scope||dojo.global;
+if("sort" in _27){
+
+}
+if(_27.mode==dojox.data.SYNC_MODE){
+return _29;
+}
+if(_27.onBegin){
+_27["onBegin"].call(_30,_29.length,_27);
+}
+if(_27.onItem){
+for(var i=0;i<_29.length;i++){
+_27["onItem"].call(_30,_29[i],_27);
+}
+}
+if(_27.onComplete){
+_27["onComplete"].call(_30,_29,_27);
+}
+return _27;
+},dump:function(_31){
+var _31=_31||{};
+var d=_31.data||this._data;
+if(!_31.suppressExportMeta&&_31.clone){
+_33=dojo.clone(d);
+if(_33[this.metaLabel]){
+_33[this.metaLabel]["clone"]=true;
+}
+}else{
+var _33=d;
+}
+if(!_31.suppressExportMeta&&_33[this.metaLabel]){
+_33[this.metaLabel]["last_export"]=new Date().toString();
+}
+if(_31.cleanMeta){
+this.cleanMeta(_33);
+}
+switch(_31.type){
+case "raw":
+return _33;
+case "json":
+default:
+return dojo.toJson(_33,_31.pretty||false);
+}
+},getFeatures:function(){
+return {"dojo.data.api.Read":true,"dojo.data.api.Identity":true,"dojo.data.api.Write":true,"dojo.data.api.Notification":true};
+},getLabel:function(_34){
+_34=this._correctReference(_34);
+var _35="";
+if(dojo.isFunction(this.createLabel)){
+return this.createLabel(_34);
+}
+if(this.labelAttribute){
+if(dojo.isArray(this.labelAttribute)){
+for(var i=0;i<this.labelAttribute.length;i++){
+if(i>0){
+_35+=" ";
+}
+_35+=_34[this.labelAttribute[i]];
+}
+return _35;
+}else{
+return _34[this.labelAttribute];
+}
+}
+return _34.toString();
+},getLabelAttributes:function(_37){
+_37=this._correctReference(_37);
+return dojo.isArray(this.labelAttribute)?this.labelAttribute:[this.labelAttribute];
+},sort:function(a,b){
+
+},getIdentity:function(_3a){
+if(this.isItem(_3a)){
+return _3a[this.idAttribute];
+}
+throw new Error("Id not found for item");
+},getIdentityAttributes:function(_3b){
+return [this.idAttribute];
+},fetchItemByIdentity:function(_3c){
+var id;
+if(dojo.isString(_3c)){
+id=_3c;
+_3c={identity:id,mode:dojox.data.SYNC_MODE};
+}else{
+if(_3c){
+id=_3c["identity"];
+}
+if(!_3c.mode){
+_3c.mode=this.mode;
+}
+}
+if(this.index&&(this.index[id]||this.index["identity"])){
+if(_3c.mode==dojox.data.SYNC_MODE){
+return this.index[id];
+}
+if(_3c.onItem){
+_3c["onItem"].call(_3c.scope||dojo.global,this.index[id],_3c);
+}
+return _3c;
+}else{
+if(_3c.mode==dojox.data.SYNC_MODE){
+return false;
+}
+}
+if(_3c.onError){
+_3c["onItem"].call(_3c.scope||dojo.global,new Error("Item Not Found: "+id),_3c);
+}
+return _3c;
+},_makeItAnItem:function(_3e,_3f){
+var _40={};
+if(this.idAttribute&&!_3e[this.idAttribute]){
+if(this.requireId){
+throw new Error("requireId is enabled, new items must have an id defined to be added");
+}
+if(this.autoIdentity){
+var _41=this.autoIdPrefix+this._autoId++;
+_3e[this.idAttribute]=_41;
+_40.autoId=true;
+}
+}
+if(!_3f&&!_3f.attribute&&!this.idAttribute&&!_3e[this.idAttribute]){
+throw new Error("Adding a new item requires, at a minimum, either the pInfo information, including the pInfo.attribute, or an id on the item in the field identified by idAttribute");
+}
+if(!_3f.attribute){
+_3f.attribute=_3e[this.idAttribute];
+}
+if(_3e[this.idAttribute]){
+this.index[_3e[this.idAttribute]]=_3e;
+}
+this._updateMeta(_3e,_40);
+this._addReference(_3e,{parent:_3f.item,attribute:_3f.attribute});
+this._setDirty(_3e);
+if(_3e[_3f.attribute]&&dojo.isArray(_3e[_3f.attribute])){
+for(var i=0;i<_3e[_3f.attribute].length;i++){
+this._makeItAnItem(_3e[_3f.attribute][i],{item:_3e,attribute:_3f.attribute});
+}
+}
+return _3e;
+},newItem:function(_43,_44){
+var _45={item:this._data};
+if(_44){
+if(_44.parent){
+_44.item=_44.parent;
+}
+dojo.mixin(_45,_44);
+}
+this._makeItAnItem(_43,_45);
+_45.oldValue=this._trimItem(_45.item[_45.attribute]);
+this._setDirty(_45.item);
+if(dojo.isArray(_45.item[_45.attribute])){
+_45.item[_45.attribute].push(_43);
+}else{
+_45.item[_45.attribute]=_43;
+}
+_45.newValue=_45.item[_45.attribute];
+this.onNew(_43,_45);
+if(_43[_45.attribute]&&dojo.isArray(_43[_45.attribute])){
+for(var i=0;i<_43[_45.attribute].length;i++){
+this.onNew(_43[_45.attribute][i],{item:_43,attribute:_45.attribute});
+}
+}
+return _43;
+},_addReference:function(_47,_48){
+var rid="_ref_"+this._referenceId++;
+if(!_47[this.metaLabel]["referenceIds"]){
+_47[this.metaLabel]["referenceIds"]=[];
+}
+_47[this.metaLabel]["referenceIds"].push(rid);
+this._references[rid]=_48;
+},deleteItem:function(_4a){
+_4a=this._correctReference(_4a);
+
+if(this.isItem(_4a)){
+while(_4a[this.metaLabel]["referenceIds"].length>0){
+
+
+var rid=_4a[this.metaLabel]["referenceIds"].pop();
+var _4c=this._references[rid];
+
+var _4d=_4c.parent;
+var _4e=_4c.attribute;
+if(_4d&&_4d[_4e]&&!dojo.isArray(_4d[_4e])){
+this._setDirty(_4d);
+this.unsetAttribute(_4d,_4e);
+delete _4d[_4e];
+}
+if(dojo.isArray(_4d[_4e])){
+
+var _4f=this._trimItem(_4d[_4e]);
+var _50=false;
+for(var i=0;i<_4d[_4e].length&&!_50;i++){
+if(_4d[_4e][i][this.metaLabel]===_4a[this.metaLabel]){
+_50=true;
+}
+}
+if(_50){
+this._setDirty(_4d);
+var del=_4d[_4e].splice(i-1,1);
+delete del;
+}
+var _53=this._trimItem(_4d[_4e]);
+this.onSet(_4d,_4e,_4f,_53);
+}
+delete this._references[rid];
+}
+this.onDelete(_4a);
+delete this.index[_4a[this.idAttribute]];
+}
+},_setDirty:function(_54){
+if(this.noRevert){
+return;
+}
+for(var i=0;i<this._dirtyItems.length;i++){
+if(_54[this.idAttribute]==this._dirtyItems[i][this.idAttribute]){
+return;
+}
+}
+this._dirtyItems.push({item:_54,old:this._trimItem(_54)});
+this._updateMeta(_54,{isDirty:true});
+},setValue:function(_56,_57,_58){
+_56=this._correctReference(_56);
+this._setDirty(_56);
+var old=_56[_57]|undefined;
+_56[_57]=_58;
+this.onSet(_56,_57,old,_58);
+},setValues:function(_5a,_5b,_5c){
+_5a=this._correctReference(_5a);
+if(!dojo.isArray(_5c)){
+throw new Error("setValues expects to be passed an Array object as its value");
+}
+this._setDirty(_5a);
+var old=_5a[_5b]||null;
+_5a[_5b]=_5c;
+this.onSet(_5a,_5b,old,_5c);
+},unsetAttribute:function(_5e,_5f){
+_5e=this._correctReference(_5e);
+this._setDirty(_5e);
+var old=_5e[_5f];
+delete _5e[_5f];
+this.onSet(_5e,_5f,old,null);
+},save:function(_61){
+var _62=[];
+if(!_61){
+_61={};
+}
+while(this._dirtyItems.length>0){
+var _63=this._dirtyItems.pop()["item"];
+var t=this._trimItem(_63);
+var d;
+switch(_61.format){
+case "json":
+d=dojo.toJson(t);
+break;
+case "raw":
+default:
+d=t;
+}
+_62.push(d);
+this._markClean(_63);
+}
+this.onSave(_62);
+},_markClean:function(_66){
+if(_66&&_66[this.metaLabel]&&_66[this.metaLabel]["isDirty"]){
+delete _66[this.metaLabel]["isDirty"];
+}
+},revert:function(){
+while(this._dirtyItems.length>0){
+var d=this._dirtyItems.pop();
+this._mixin(d.item,d.old);
+}
+this.onRevert();
+},_mixin:function(_68,_69){
+var mix;
+if(dojo.isObject(_69)){
+if(dojo.isArray(_69)){
+while(_68.length>0){
+_68.pop();
+}
+for(var i=0;i<_69.length;i++){
+if(dojo.isObject(_69[i])){
+if(dojo.isArray(_69[i])){
+mix=[];
+}else{
+mix={};
+if(_69[i][this.metaLabel]&&_69[i][this.metaLabel]["type"]&&_69[i][this.metaLabel]["type"]=="reference"){
+_68[i]=this.index[_69[i][this.idAttribute]];
+continue;
+}
+}
+this._mixin(mix,_69[i]);
+_68.push(mix);
+}else{
+_68.push(_69[i]);
+}
+}
+}else{
+for(var i in _68){
+if(i in _69){
+continue;
+}
+delete _68[i];
+}
+for(var i in _69){
+if(dojo.isObject(_69[i])){
+if(dojo.isArray(_69[i])){
+mix=[];
+}else{
+if(_69[i][this.metaLabel]&&_69[i][this.metaLabel]["type"]&&_69[i][this.metaLabel]["type"]=="reference"){
+_68[i]=this.index[_69[i][this.idAttribute]];
+continue;
+}
+mix={};
+}
+this._mixin(mix,_69[i]);
+_68[i]=mix;
+}else{
+_68[i]=_69[i];
+}
+}
+}
+}
+},isDirty:function(_6c){
+_6c=this._correctReference(_6c);
+return _6c&&_6c[this.metaLabel]&&_6c[this.metaLabel]["isDirty"];
+},_createReference:function(_6d){
+var obj={};
+obj[this.metaLabel]={type:"reference"};
+obj[this.idAttribute]=_6d[this.idAttribute];
+return obj;
+},_trimItem:function(_6f){
+var _70;
+if(dojo.isArray(_6f)){
+_70=[];
+for(var i=0;i<_6f.length;i++){
+if(dojo.isArray(_6f[i])){
+_70.push(this._trimItem(_6f[i]));
+}else{
+if(dojo.isObject(_6f[i])){
+if(_6f[i]["getFullYear"]){
+_70.push(dojo.date.stamp.toISOString(_6f[i]));
+}else{
+if(_6f[i][this.idAttribute]){
+_70.push(this._createReference(_6f[i]));
+}else{
+_70.push(this._trimItem(_6f[i]));
+}
+}
+}else{
+_70.push(_6f[i]);
+}
+}
+}
+return _70;
+}
+if(dojo.isObject(_6f)){
+_70={};
+for(var _72 in _6f){
+if(!_6f[_72]){
+_70[_72]=undefined;
+continue;
+}
+if(dojo.isArray(_6f[_72])){
+_70[_72]=this._trimItem(_6f[_72]);
+}else{
+if(dojo.isObject(_6f[_72])){
+if(_6f[_72]["getFullYear"]){
+_70[_72]=dojo.date.stamp.toISOString(_6f[_72]);
+}else{
+if(_6f[_72][this.idAttribute]){
+_70[_72]=this._createReference(_6f[_72]);
+}else{
+_70[_72]=this._trimItem(_6f[_72]);
+}
+}
+}else{
+_70[_72]=_6f[_72];
+}
+}
+}
+return _70;
+}
+},onSet:function(_73,_74,_75,_76){
+},onNew:function(_77,_78){
+},onDelete:function(_79){
+},onSave:function(_7a){
+},onRevert:function(){
+}});
+dojox.data.jsonPathStore.byId=dojox.data.jsonPathStore.fetchItemByIdentity;
+}
diff --git a/dojox/data/restListener.js b/dojox/data/restListener.js
new file mode 100644
index 0000000..619ecb7
--- /dev/null
+++ b/dojox/data/restListener.js
@@ -0,0 +1,36 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.restListener"]){
+dojo._hasResource["dojox.data.restListener"]=true;
+dojo.provide("dojox.data.restListener");
+dojox.data.restListener=function(_1){
+var _2=_1.channel;
+var jr=dojox.rpc.JsonRest;
+var _4=jr.getServiceAndId(_2).service;
+var _5=dojox.json.ref.resolveJson(_1.result,{defaultId:_1.event=="put"&&_2,index:dojox.rpc.Rest._index,idPrefix:_4.servicePath,idAttribute:jr.getIdAttribute(_4),schemas:jr.schemas,loader:jr._loader,assignAbsoluteIds:true});
+var _6=dojox.rpc.Rest._index&&dojox.rpc.Rest._index[_2];
+var _7="on"+_1.event.toLowerCase();
+var _8=_4&&_4._store;
+if(_6){
+if(_6[_7]){
+_6[_7](_5);
+return;
+}
+}
+if(_8){
+switch(_7){
+case "onpost":
+_8.onNew(_5);
+break;
+case "ondelete":
+_8.onDelete(_6);
+break;
+}
+}
+};
+}
diff --git a/dojox/data/s3/README b/dojox/data/s3/README
new file mode 100644
index 0000000..cfa2347
--- /dev/null
+++ b/dojox/data/s3/README
@@ -0,0 +1,41 @@
+Using Amazon S3 with Dojo has the following prerequisites:
+    * You must be signed up to use Amazon S3. You can sign up for Amazon S3 at http://aws.amazon.com/s3.
+    * Use the provided proxy (/dojox/rpc/s3/proxy.php) with PHP 5.
+    * proxy.php requires the following modules:
+          o Crypt_HMAC
+          o HTTP_Request
+
+
+To use S3 from Dojo, you need a proxy. You can use the provided proxy example file by renaming 
+proxy.example-php to proxy.php and then you must enter your Amazon access key and secret access key
+into the proxy.php file on line 3 and 4:
+
+$accessKey = "access key";
+$secretAccessKey = "secret access key";
+
+You then use the Dojo RPC service with the "PROXIED-PATH" envelope:
+
+dojo.require("dojox.rpc.Service");
+dojo.require("dojox.rpc.ProxiedPath");
+var s3Buckets = new dojox.rpc.Service({
+	target:"http://s3.amazonaws.com/",
+	proxyUrl:"../s3/proxy.php", // the path to the proxy
+	transport:"REST",
+	envelope:"PROXIED-PATH",
+	contentType:"application/json",
+	services:{
+		myBucket:{
+			target:"myBucket",
+			parameters:[{type:"string"}]
+		}
+	}
+});
+
+
+To use the S3 as a Dojo data store you can use the S3JsonRestStore module. First setup an RPC service 
+as shown above and then pass the RPC service to the S3JsonRestStore:
+
+dojo.require("dojox.data.S3JsonRestStore");
+s3Store = new dojox.data.S3JsonRestStore({service:s3Buckets.myBucket}); // and create a store for it
+
+You can then use the s3Store as a normal Read/Write Dojo Data store.
diff --git a/dojox/data/s3/proxy.example-php b/dojox/data/s3/proxy.example-php
new file mode 100644
index 0000000..f33a639
--- /dev/null
+++ b/dojox/data/s3/proxy.example-php
@@ -0,0 +1,74 @@
+<?php
+// enter your Amazon S3 secret key and access key here:
+$accessKey = "access key";
+$secretAccessKey = "secret access key";
+
+
+
+$TARGET_WS = "http://s3.amazonaws.com";
+
+ob_start();
+
+require_once 'Crypt/HMAC.php';
+require_once 'HTTP/Request.php';
+
+$method = $_SERVER["REQUEST_METHOD"];
+if ($method == "PUT") {
+	$contentType = $_SERVER['CONTENT_TYPE'];
+}
+else {
+	$contentType ='';
+}
+$resource = str_replace($TARGET_WS, '', $_REQUEST['url']);
+$queryIndex = strpos($resource,'?'); // remove the query string
+if ($queryIndex) {
+	$resource = substr($resource,0,$queryIndex);
+}
+
+if (substr($resource,strlen($resource)-1,strlen($resource)) == '/') {
+	// remove the last slash
+	$resource = substr($resource,0,strlen($resource)-1);
+}
+$content = file_get_contents('php://input');
+
+$httpDate = gmdate("D, d M Y H:i:s T");
+$acl = "private";
+$stringToSign = "$method\n\n$contentType\n$httpDate\nx-amz-acl:$acl\n$resource";
+$hashObj =& new Crypt_HMAC($secretAccessKey, "sha1");
+$signature = hexTob64($hashObj->hash($stringToSign));
+
+$req =& new HTTP_Request($TARGET_WS . $resource);
+$req->setMethod($method);
+$req->addHeader("content-type", $contentType);
+$req->addHeader("Date", $httpDate);
+$req->addHeader("x-amz-acl", $acl);
+$req->addHeader("Authorization", "AWS " . $accessKey . ":" . $signature);
+if ($content != "") {
+	$req->setBody($content);
+}
+
+$req->sendRequest();
+
+$contentType = $req->getResponseHeader("content-type");
+header("content-type: $contentType");
+header('HTTP/1.1 ' . $req->getResponseCode() . ' Ok');
+
+ob_end_flush();
+
+$content = $req->getResponseBody();
+if ($content) {
+	print($content);
+}
+else {
+	print("\"success\"");
+}
+
+function hexTob64($str) {
+    $raw = '';
+    for ($i=0; $i < strlen($str); $i+=2) {
+        $raw .= chr(hexdec(substr($str, $i, 2)));
+    }
+    return base64_encode($raw);
+}
+
+?>
\ No newline at end of file
diff --git a/dojox/data/util/JsonQuery.js b/dojox/data/util/JsonQuery.js
new file mode 100644
index 0000000..3616025
--- /dev/null
+++ b/dojox/data/util/JsonQuery.js
@@ -0,0 +1,88 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.data.util.JsonQuery"]){
+dojo._hasResource["dojox.data.util.JsonQuery"]=true;
+dojo.provide("dojox.data.util.JsonQuery");
+dojo.declare("dojox.data.util.JsonQuery",null,{useFullIdInQueries:false,_toJsonQuery:function(_1,_2){
+var _3=true;
+var _4=this;
+function _5(_6,_7){
+if(_7.__id){
+var _8={};
+_8[_4.idAttribute]=_4.useFullIdInQueries?_7.__id:_7[_4.idAttribute];
+_7=_8;
+}
+for(var i in _7){
+var _a=_7[i];
+var _b=_6+(/^[a-zA-Z_][\w_]*$/.test(i)?"."+i:"["+dojo._escapeString(i)+"]");
+if(_a&&typeof _a=="object"){
+_5(_b,_a);
+}else{
+if(_a!="*"){
+_c+=(_3?"":"&")+_b+((_1.queryOptions&&_1.queryOptions.ignoreCase)?"~":"=")+dojo.toJson(_a);
+_3=false;
+}
+}
+}
+};
+if(_1.query&&typeof _1.query=="object"){
+var _c="[?(";
+_5("@",_1.query);
+if(!_3){
+_c+=")]";
+}else{
+_c="";
+}
+_1.queryStr=_c.replace(/\\"|"/g,function(t){
+return t=="\""?"'":t;
+});
+}else{
+if(!_1.query||_1.query=="*"){
+_1.query="";
+}
+}
+var _e=_1.sort;
+if(_e){
+_1.queryStr=_1.queryStr||(typeof _1.query=="string"?_1.query:"");
+_3=true;
+for(i=0;i<_e.length;i++){
+_1.queryStr+=(_3?"[":",")+(_e[i].descending?"\\":"/")+"@["+dojo._escapeString(_e[i].attribute)+"]";
+_3=false;
+}
+if(!_3){
+_1.queryStr+="]";
+}
+}
+if(_2&&(_1.start||_1.count)){
+_1.queryStr=(_1.queryStr||(typeof _1.query=="string"?_1.query:""))+"["+(_1.start||"")+":"+(_1.count?(_1.start||0)+_1.count:"")+"]";
+}
+if(typeof _1.queryStr=="string"){
+_1.queryStr=_1.queryStr.replace(/\\"|"/g,function(t){
+return t=="\""?"'":t;
+});
+return _1.queryStr;
+}
+return _1.query;
+},jsonQueryPagination:true,fetch:function(_10){
+this._toJsonQuery(_10,this.jsonQueryPagination);
+return this.inherited(arguments);
+},isUpdateable:function(){
+return true;
+},matchesQuery:function(_11,_12){
+_12._jsonQuery=_12._jsonQuery||dojox.json.query(this._toJsonQuery(_12));
+return _12._jsonQuery([_11]).length;
+},clientSideFetch:function(_13,_14){
+_13._jsonQuery=_13._jsonQuery||dojox.json.query(this._toJsonQuery(_13));
+return this.clientSidePaging(_13,_13._jsonQuery(_14));
+},querySuperSet:function(_15,_16){
+if(!_15.query){
+return _16.query;
+}
+return this.inherited(arguments);
+}});
+}
diff --git a/dojox/date/HebrewDate.js b/dojox/date/HebrewDate.js
new file mode 100644
index 0000000..0916d3a
--- /dev/null
+++ b/dojox/date/HebrewDate.js
@@ -0,0 +1,641 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.date.HebrewDate"]){
+dojo._hasResource["dojox.date.HebrewDate"]=true;
+dojo.provide("dojox.date.HebrewDate");
+dojo.experimental("dojox.date.HebrewDate");
+dojo.declare("dojox.date.HebrewDate",null,{TISHRI:0,HESHVAN:1,KISLEV:2,TEVET:3,SHEVAT:4,ADAR_1:5,ADAR:6,NISAN:7,IYAR:8,SIVAN:9,TAMUZ:10,AV:11,ELUL:12,_HOUR_PARTS:1080,_DAY_PARTS:24*1080,_MONTH_DAYS:29,_MONTH_FRACT:12*1080+793,_MONTH_PARTS:29*24*1080+12*1080+793,BAHARAD:11*1080+204,JAN_1_1_JULIAN_DAY:1721426,_MONTH_LENGTH:[[30,30,30],[29,29,30],[29,30,30],[29,29,29],[30,30,30],[30,30,30],[29,29,29],[30,30,30],[29,29,29],[30,30,30],[29,29,29],[30,30,30],[29,29,29]],_MONTH_START:[[0,0,0],[3 [...]
+var _1=arguments.length;
+if(_1==0){
+var _2=new Date();
+var _3=this._computeHebrewFields(_2);
+this._date=_3[2];
+this._month=_3[1];
+this._year=_3[0];
+this._hours=_2.getHours();
+this._minutes=_2.getMinutes();
+this._seconds=_2.getSeconds();
+this._milliseconds=_2.getMilliseconds();
+this._day=_2.getDay();
+}else{
+if(_1==1){
+this._year=arguments[0].getFullYear();
+this._month=arguments[0].getMonth();
+this._date=arguments[0].getDate();
+this._hours=arguments[0].getHours();
+this._minutes=arguments[0].getMinutes();
+this._seconds=arguments[0].getSeconds();
+this._milliseconds=arguments[0].getMilliseconds();
+}else{
+if(_1>=3){
+this._year=parseInt(arguments[0]);
+this._month=parseInt(arguments[1]);
+this._date=parseInt(arguments[2]);
+if(!this.isLeapYear(this._year)&&this._month>=5){
+this._month++;
+}
+if(this._month>12||(!this.isLeapYear(this._year)&&this._month>11)){
+console.warn("the month is incorrect , set 0");
+this._month=0;
+}
+this._hours=(arguments[3]!=null)?parseInt(arguments[3]):0;
+this._minutes=(arguments[4]!=null)?parseInt(arguments[4]):0;
+this._seconds=(arguments[5]!=null)?parseInt(arguments[5]):0;
+this._milliseconds=(arguments[6]!=null)?parseInt(arguments[6]):0;
+}
+}
+}
+var _4=this._startOfYear(this._year);
+if(this._month!=0){
+if(this.isLeapYear(this._year)){
+_4+=this.LEAP_MONTH_START[this._month][this._yearType(this._year)];
+}else{
+_4+=this._MONTH_START[this._month][this._yearType(this._year)];
+}
+}
+_4+=(this._date-1);
+this._day=((_4+1)%7);
+},getDate:function(){
+return parseInt(this._date);
+},getMonth:function(){
+return parseInt(this._month);
+},getFullYear:function(){
+return parseInt(this._year);
+},getHours:function(){
+return this._hours;
+},getMinutes:function(){
+return this._minutes;
+},getSeconds:function(){
+return this._seconds;
+},getMilliseconds:function(){
+return this._milliseconds;
+},setDate:function(_5){
+_5=parseInt(_5);
+if(_5>0){
+for(var _6=this.getDaysInHebrewMonth(this._month,this._year);_5>_6;_5-=_6,_6=this.getDaysInHebrewMonth(this._month,this._year)){
+this._month++;
+if(!this.isLeapYear(this._year)&&(this._month==5)){
+this._month++;
+}
+if(this._month>=13){
+this._year++;
+this._month-=13;
+}
+}
+this._date=_5;
+}else{
+for(_6=this.getDaysInHebrewMonth((this._month-1)>=0?(this._month-1):12,((this._month-1)>=0)?this._year:this._year-1);_5<=0;_6=this.getDaysInHebrewMonth((this._month-1)>=0?(this._month-1):12,((this._month-1)>=0)?this._year:this._year-1)){
+this._month--;
+if(!this.isLeapYear(this._year)&&this._month==5){
+this._month--;
+}
+if(this._month<0){
+this._year--;
+this._month+=13;
+}
+_5+=_6;
+}
+this._date=_5;
+}
+var _7=this._startOfYear(this._year);
+if(this._month!=0){
+if(this.isLeapYear(this._year)){
+_7+=this.LEAP_MONTH_START[this._month][this._yearType(this._year)];
+}else{
+_7+=this._MONTH_START[this._month][this._yearType(this._year)];
+}
+}
+_7+=(this._date-1);
+this._day=((_7+1)%7);
+return this;
+},setYear:function(_8){
+this._year=parseInt(_8);
+if(!this.isLeapYear(this._year)&&this._month==6){
+this._month--;
+}
+var _9=this._startOfYear(this._year);
+if(this._month!=0){
+if(this.isLeapYear(this._year)){
+_9+=this.LEAP_MONTH_START[this._month][this._yearType(this._year)];
+}else{
+_9+=this._MONTH_START[this._month][this._yearType(this._year)];
+}
+}
+_9+=(this._date-1);
+this._day=((_9+1)%7);
+return this;
+},setMonth:function(_a){
+var _b=parseInt(_a);
+if(!this.isLeapYear(this._year)&&_b>5){
+_b++;
+}
+if(_b>=0){
+while(_b>12){
+this._year++;
+_b-=13;
+if(!this.isLeapYear(this._year)&&_b>5){
+_b++;
+}
+}
+}else{
+while(_b<0){
+this._year--;
+_b+=13;
+if(!this.isLeapYear(this._year)&&_b<=5){
+_b--;
+}
+}
+}
+this._month=_b;
+var _c=this.getDaysInHebrewMonth(this._month,this._year);
+if(_c<this._date){
+this._date=_c;
+}
+var _d=this._startOfYear(this._year);
+if(this._month!=0){
+if(this.isLeapYear(this._year)){
+_d+=this.LEAP_MONTH_START[this._month][this._yearType(this._year)];
+}else{
+_d+=this._MONTH_START[this._month][this._yearType(this._year)];
+}
+}
+_d+=(this._date-1);
+this._day=((_d+1)%7);
+return this;
+},setHours:function(){
+var _e=arguments.length;
+var _f=0;
+if(_e>=1){
+_f=parseInt(arguments[0]);
+}
+if(_e>=2){
+this._minutes=parseInt(arguments[1]);
+}
+if(_e>=3){
+this._seconds=parseInt(arguments[2]);
+}
+if(_e==4){
+this._milliseconds=parseInt(arguments[3]);
+}
+while(_f>=24){
+this._date++;
+var _10=this.getDaysInHebrewMonth(this._month,this._year);
+if(this._date>_10){
+this._month++;
+if(!this.isLeapYear(this._year)&&(this._month==5)){
+this._month++;
+}
+if(this._month>=13){
+this._year++;
+this._month-=13;
+}
+this._date-=_10;
+}
+_f-=24;
+}
+this._hours=_f;
+var day=this._startOfYear(this._year);
+if(this._month!=0){
+if(this.isLeapYear(this._year)){
+day+=this.LEAP_MONTH_START[this._month][this._yearType(this._year)];
+}else{
+day+=this._MONTH_START[this._month][this._yearType(this._year)];
+}
+}
+day+=(this._date-1);
+this._day=((day+1)%7);
+return this;
+},setMinutes:function(_12){
+while(_12>=60){
+this._hours++;
+if(this._hours>=24){
+this._date++;
+this._hours-=24;
+var _13=this.getDaysInHebrewMonth(this._month,this._year);
+if(this._date>_13){
+this._month++;
+if(!this.isLeapYear(this._year)&&(this._month==5)){
+this._month++;
+}
+if(this._month>=13){
+this._year++;
+this._month-=13;
+}
+this._date-=_13;
+}
+}
+_12-=60;
+}
+this._minutes=_12;
+var day=this._startOfYear(this._year);
+if(this._month!=0){
+if(this.isLeapYear(this._year)){
+day+=this.LEAP_MONTH_START[this._month][this._yearType(this._year)];
+}else{
+day+=this._MONTH_START[this._month][this._yearType(this._year)];
+}
+}
+day+=(this._date-1);
+this._day=((day+1)%7);
+return this;
+},setSeconds:function(_15){
+while(_15>=60){
+this._minutes++;
+if(this._minutes>=60){
+this._hours++;
+this._minutes-=60;
+if(this._hours>=24){
+this._date++;
+this._hours-=24;
+var _16=this.getDaysInHebrewMonth(this._month,this._year);
+if(this._date>_16){
+this._month++;
+if(!this.isLeapYear(this._year)&&(this._month==5)){
+this._month++;
+}
+if(this._month>=13){
+this._year++;
+this._month-=13;
+}
+this._date-=_16;
+}
+}
+}
+_15-=60;
+}
+this._seconds=_15;
+var day=this._startOfYear(this._year);
+if(this._month!=0){
+if(this.isLeapYear(this._year)){
+day+=this.LEAP_MONTH_START[this._month][this._yearType(this._year)];
+}else{
+day+=this._MONTH_START[this._month][this._yearType(this._year)];
+}
+}
+day+=(this._date-1);
+this._day=((day+1)%7);
+return this;
+},setMilliseconds:function(_18){
+while(_18>=1000){
+this.setSeconds++;
+if(this.setSeconds>=60){
+this._minutes++;
+this._seconds-=60;
+if(this._minutes>=60){
+this._hours++;
+this._minutes-=60;
+if(this._hours>=24){
+this._date++;
+this._hours-=24;
+var _19=this.getDaysInHebrewMonth(this._month,this._year);
+if(this._date>_19){
+this._month++;
+if(!this.isLeapYear(this._year)&&(this._month==5)){
+this._month++;
+}
+if(this._month>=13){
+this._year++;
+this._month-=13;
+}
+this._date-=_19;
+}
+}
+}
+}
+_18-=1000;
+}
+this._milliseconds=_18;
+var day=this._startOfYear(this._year);
+if(this._month!=0){
+if(this.isLeapYear(this._year)){
+day+=this.LEAP_MONTH_START[this._month][this._yearType(this._year)];
+}else{
+day+=this._MONTH_START[this._month][this._yearType(this._year)];
+}
+}
+day+=(this._date-1);
+this._day=((day+1)%7);
+return this;
+},toString:function(){
+return this._date+", "+((!this.isLeapYear(this._year)&&this._month>5)?this._month:(this._month+1))+", "+this._year+"  "+this._hours+":"+this._minutes+":"+this._seconds;
+},valueOf:function(){
+return this.toGregorian().valueOf();
+},getDaysInHebrewMonth:function(_1b,_1c){
+switch(_1b){
+case this.HESHVAN:
+case this.KISLEV:
+return this._MONTH_LENGTH[_1b][this._yearType(_1c)];
+default:
+return this._MONTH_LENGTH[_1b][0];
+}
+},_yearType:function(_1d){
+var _1e=this._handleGetYearLength(Number(_1d));
+if(_1e>380){
+_1e-=30;
+}
+switch(_1e){
+case 353:
+return 0;
+case 354:
+return 1;
+case 355:
+return 2;
+}
+throw new Error("Illegal year length "+_1e+" in year "+_1d);
+},_handleGetYearLength:function(_1f){
+return this._startOfYear(_1f+1)-this._startOfYear(_1f);
+},_startOfYear:function(_20){
+var _21=Math.floor((235*_20-234)/19);
+var _22=_21*this._MONTH_FRACT+this.BAHARAD;
+var day=_21*29+Math.floor(_22/this._DAY_PARTS);
+_22%=this._DAY_PARTS;
+var wd=day%7;
+if(wd==2||wd==4||wd==6){
+day+=1;
+wd=day%7;
+}
+if(wd==1&&_22>15*this._HOUR_PARTS+204&&!this.isLeapYear(_20)){
+day+=2;
+}else{
+if(wd==0&&_22>21*this._HOUR_PARTS+589&&this.isLeapYear(_20-1)){
+day+=1;
+}
+}
+return day;
+},isLeapYear:function(_25){
+var x=(_25*12+17)%19;
+return x>=((x<0)?-7:12);
+},fromGregorian:function(_27){
+var _28=this._computeHebrewFields(_27);
+this._year=_28[0];
+this._month=_28[1];
+this._date=_28[2];
+this._hours=_27.getHours();
+this._milliseconds=_27.getMilliseconds();
+this._minutes=_27.getMinutes();
+this._seconds=_27.getSeconds();
+return this;
+},_computeHebrewFields:function(_29){
+var _2a=this._getJulianDayFromGregorianDate(_29);
+var d=_2a-347997;
+var m=Math.floor((d*this._DAY_PARTS)/this._MONTH_PARTS);
+var _2d=Math.floor((19*m+234)/235)+1;
+var ys=this._startOfYear(_2d);
+var _2f=(d-ys);
+while(_2f<1){
+_2d--;
+ys=this._startOfYear(_2d);
+_2f=d-ys;
+}
+var _30=this._yearType(_2d);
+var _31=this.isLeapYear(_2d)?this.LEAP_MONTH_START:this._MONTH_START;
+var _32=0;
+while(_2f>_31[_32][_30]){
+_32++;
+}
+_32--;
+var _33=_2f-_31[_32][_30];
+return [_2d,_32,_33];
+},toGregorian:function(){
+var _34=this._year;
+var _35=this._month;
+var _36=this._date;
+var day=this._startOfYear(_34);
+if(_35!=0){
+if(this.isLeapYear(_34)){
+day+=this.LEAP_MONTH_START[_35][this._yearType(_34)];
+}else{
+day+=this._MONTH_START[_35][this._yearType(_34)];
+}
+}
+var _38=(_36+day+347997);
+var _39=_38-this.JAN_1_1_JULIAN_DAY;
+var rem=new Array(1);
+var _3b=this._floorDivide(_39,146097,rem);
+var _3c=this._floorDivide(rem[0],36524,rem);
+var n4=this._floorDivide(rem[0],1461,rem);
+var n1=this._floorDivide(rem[0],365,rem);
+var _3f=400*_3b+100*_3c+4*n4+n1;
+var _40=rem[0];
+if(_3c==4||n1==4){
+_40=365;
+}else{
+++_3f;
+}
+var _41=!(_3f%4)&&(_3f%100||!(_3f%400));
+var _42=0;
+var _43=_41?60:59;
+if(_40>=_43){
+_42=_41?1:2;
+}
+var _44=Math.floor((12*(_40+_42)+6)/367);
+var _45=_40-this.GREGORIAN_MONTH_COUNT[_44][_41?3:2]+1;
+return new Date(_3f,_44,_45,this._hours,this._minutes,this._seconds,this._milliseconds);
+},_floorDivide:function(_46,_47,_48){
+if(_46>=0){
+_48[0]=(_46%_47);
+return Math.floor(_46/_47);
+}
+var _49=Math.floor(_46/_47);
+_48[0]=_46-(_49*_47);
+return _49;
+},getDay:function(){
+var _4a=this._year;
+var _4b=this._month;
+var _4c=this._date;
+var day=this._startOfYear(_4a);
+if(_4b!=0){
+if(this.isLeapYear(_4a)){
+day+=this.LEAP_MONTH_START[_4b][this._yearType(_4a)];
+}else{
+day+=this._MONTH_START[_4b][this._yearType(_4a)];
+}
+}
+day+=_4c-1;
+return (day+1)%7;
+},_getJulianDayFromGregorianDate:function(_4e){
+var _4f=_4e.getFullYear();
+var _50=_4e.getMonth();
+var d=_4e.getDate();
+var _52=!(_4f%4)&&(_4f%100||!(_4f%400));
+var y=_4f-1;
+var _54=365*y+Math.floor(y/4)-Math.floor(y/100)+Math.floor(y/400)+this.JAN_1_1_JULIAN_DAY-1;
+if(_50!=0){
+_54+=this.GREGORIAN_MONTH_COUNT[_50][_52?3:2];
+}
+_54+=d;
+return _54;
+}});
+dojox.date.HebrewDate.fromGregorian=function(_55){
+var _56=new dojox.date.HebrewDate();
+return _56.fromGregorian(_55);
+};
+dojox.date.HebrewDate.add=function(_57,_58,_59){
+var _5a=new dojox.date.HebrewDate(_57);
+switch(_58){
+case "day":
+_5a.setDate(_57.getDate()+_59);
+break;
+case "weekday":
+var day=_57.getDay();
+if(((day+_59)<5)&&((day+_59)>0)){
+_5a.setDate(_57.getDate()+_59);
+}else{
+var _5c=0;
+var _5d=0;
+if(day==5){
+day=4;
+_5d=(_59>0)?-1:1;
+}else{
+if(day==6){
+day=4;
+_5d=(_59>0)?-2:2;
+}
+}
+var add=(_59>0)?(5-day-1):(0-day);
+var _5f=_59-add;
+var div=parseInt(_5f/5);
+if((_5f%5)!=0){
+_5c=(_59>0)?2:-2;
+}
+_5c=_5c+div*7+_5f%5+add;
+_5a.setDate(_57.getDate()+_5c+_5d);
+}
+break;
+case "year":
+_5a.setYear(_57.getFullYear()+_59);
+break;
+case "week":
+_59*=7;
+_5a.setDate(_57.getDate()+_59);
+break;
+case "month":
+var _61=_57.getMonth();
+if(!_57.isLeapYear(_57.getFullYear())&&_61>5){
+_61--;
+}
+_5a.setMonth(_61+_59);
+break;
+case "hour":
+_5a.setHours(_57.getHours()+_59);
+break;
+case "minute":
+_5a.setMinutes(_57.getMinutes()+_59);
+break;
+case "second":
+_5a.setSeconds(_57.getSeconds()+_59);
+break;
+case "millisecond":
+_5a.setMilliseconds(_57.getMilliseconds()+_59);
+break;
+}
+return _5a;
+};
+dojox.date.HebrewDate.difference=function(_62,_63,_64){
+_63=_63||new dojox.date.HebrewDate();
+_64=_64||"day";
+var _65=_62.getFullYear()-_63.getFullYear();
+var _66=1;
+switch(_64){
+case "weekday":
+var _67=Math.round(dojox.date.HebrewDate.difference(_62,_63,"day"));
+var _68=parseInt(dojox.date.HebrewDate.difference(_62,_63,"week"));
+var mod=_67%7;
+if(mod==0){
+_67=_68*5;
+}else{
+var adj=0;
+var _6b=_63.getDay();
+var _6c=_62.getDay();
+_68=parseInt(_67/7);
+mod=_67%7;
+var _6d=new dojox.date.HebrewDate(_63);
+_6d.setDate(_6d.getDate()+(_68*7));
+var _6e=_6d.getDay();
+if(_67>0){
+switch(true){
+case _6b==5:
+adj=-1;
+break;
+case _6b==6:
+adj=0;
+break;
+case _6c==5:
+adj=-1;
+break;
+case _6c==6:
+adj=-2;
+break;
+case (_6e+mod)>5:
+adj=-2;
+}
+}else{
+if(_67<0){
+switch(true){
+case _6b==5:
+adj=0;
+break;
+case _6b==6:
+adj=1;
+break;
+case _6c==5:
+adj=2;
+break;
+case _6c==6:
+adj=1;
+break;
+case (_6e+mod)<0:
+adj=2;
+}
+}
+}
+_67+=adj;
+_67-=(_68*2);
+}
+_66=_67;
+break;
+case "year":
+_66=_65;
+break;
+case "month":
+var _6f=(_62.toGregorian()>_63.toGregorian())?_62:_63;
+var _70=(_62.toGregorian()>_63.toGregorian())?_63:_62;
+var _71=_6f.getMonth();
+var _72=_70.getMonth();
+if(_65==0){
+_66=(!_62.isLeapYear(_62.getFullYear())&&_6f.getMonth()>5&&_70.getMonth()<=5)?(_6f.getMonth()-_70.getMonth()-1):(_6f.getMonth()-_70.getMonth());
+}else{
+_66=(!_70.isLeapYear(_70.getFullYear())&&_72<6)?(13-_72-1):(13-_72);
+_66+=(!_6f.isLeapYear(_6f.getFullYear())&&_71>5)?(_71-1):_71;
+var i=_70.getFullYear()+1;
+var e=_6f.getFullYear();
+for(i;i<e;i++){
+_66+=_70.isLeapYear(i)?13:12;
+}
+}
+if(_62.toGregorian()<_63.toGregorian()){
+_66=-_66;
+}
+break;
+case "week":
+_66=parseInt(dojox.date.HebrewDate.difference(_62,_63,"day")/7);
+break;
+case "day":
+_66/=24;
+case "hour":
+_66/=60;
+case "minute":
+_66/=60;
+case "second":
+_66/=1000;
+case "millisecond":
+_66*=_62.toGregorian().getTime()-_63.toGregorian().getTime();
+}
+return Math.round(_66);
+};
+}
diff --git a/dojox/date/HebrewLocale.js b/dojox/date/HebrewLocale.js
new file mode 100644
index 0000000..4743fef
--- /dev/null
+++ b/dojox/date/HebrewLocale.js
@@ -0,0 +1,411 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.date.HebrewLocale"]){
+dojo._hasResource["dojox.date.HebrewLocale"]=true;
+dojo.provide("dojox.date.HebrewLocale");
+dojo.experimental("dojox.date.HebrewLocale");
+dojo.require("dojox.date.HebrewDate");
+dojo.require("dojox.date.HebrewNumerals");
+dojo.require("dojo.regexp");
+dojo.require("dojo.string");
+dojo.require("dojo.i18n");
+dojo.requireLocalization("dojo.cldr","hebrew",null,"ROOT,he");
+(function(){
+function _1(_2,_3,_4,_5,_6){
+return _6.replace(/([a-z])\1*/ig,function(_7){
+var s,_9;
+var c=_7.charAt(0);
+var l=_7.length;
+var _c=["abbr","wide","narrow"];
+switch(c){
+case "y":
+if(_4=="he"){
+s=dojox.date.HebrewNumerals.getYearHebrewLetters(_2.getFullYear());
+}else{
+s=String(_2.getFullYear());
+}
+break;
+case "M":
+var m=_2.getMonth();
+if(l<3){
+if(!_2.isLeapYear(_2.getFullYear())&&m>5){
+m--;
+}
+if(_4=="he"){
+s=dojox.date.HebrewNumerals.getMonthHebrewLetters(m);
+}else{
+s=m+1;
+_9=true;
+}
+}else{
+if(!_2.isLeapYear(_2.getFullYear())&&m==6){
+m--;
+}
+var _e=["months","format",_c[l-3]].join("-");
+s=_3[_e][m];
+}
+break;
+case "d":
+if(_4=="he"){
+s=dojox.date.HebrewNumerals.getDayHebrewLetters(_2.getDate());
+}else{
+s=_2.getDate();
+_9=true;
+}
+break;
+case "E":
+var d=_2.getDay();
+if(l<3){
+s=d+1;
+_9=true;
+}else{
+var _10=["days","format",_c[l-3]].join("-");
+s=_3[_10][d];
+}
+break;
+case "a":
+var _11=(_2.getHours()<12)?"am":"pm";
+s=_3[_11];
+break;
+case "h":
+case "H":
+case "K":
+case "k":
+var h=_2.getHours();
+switch(c){
+case "h":
+s=(h%12)||12;
+break;
+case "H":
+s=h;
+break;
+case "K":
+s=(h%12);
+break;
+case "k":
+s=h||24;
+break;
+}
+_9=true;
+break;
+case "m":
+s=_2.getMinutes();
+_9=true;
+break;
+case "s":
+s=_2.getSeconds();
+_9=true;
+break;
+case "S":
+s=Math.round(_2.getMilliseconds()*Math.pow(10,l-3));
+_9=true;
+break;
+default:
+throw new Error("dojox.date.HebrewLocale.formatPattern: invalid pattern char: "+_6);
+}
+if(_9){
+s=dojo.string.pad(s,l);
+}
+return s;
+});
+};
+dojox.date.HebrewLocale.format=function(_13,_14){
+_14=_14||{};
+var _15=dojo.i18n.normalizeLocale(_14.locale);
+var _16=_14.formatLength||"short";
+var _17=dojox.date.HebrewLocale._getHebrewBundle(_15);
+var str=[];
+var _19=dojo.hitch(this,_1,_13,_17,_15,_14.fullYear);
+if(_14.selector!="time"){
+var _1a=_14.datePattern||_17["dateFormat-"+_16];
+if(_1a){
+str.push(_1b(_1a,_19));
+}
+}
+if(_14.selector!="date"){
+var _1c=_14.timePattern||_17["timeFormat-"+_16];
+if(_1c){
+str.push(_1b(_1c,_19));
+}
+}
+var _1d=str.join(" ");
+return _1d;
+};
+dojox.date.HebrewLocale.regexp=function(_1e){
+return dojox.date.HebrewLocale._parseInfo(_1e).regexp;
+};
+dojox.date.HebrewLocale._parseInfo=function(_1f){
+_1f=_1f||{};
+var _20=dojo.i18n.normalizeLocale(_1f.locale);
+var _21=dojox.date.HebrewLocale._getHebrewBundle(_20);
+var _22=_1f.formatLength||"short";
+var _23=_1f.datePattern||_21["dateFormat-"+_22];
+var _24=_1f.timePattern||_21["timeFormat-"+_22];
+var _25;
+if(_1f.selector=="date"){
+_25=_23;
+}else{
+if(_1f.selector=="time"){
+_25=_24;
+}else{
+_25=(typeof (_24)=="undefined")?_23:_23+" "+_24;
+}
+}
+var _26=[];
+var re=_1b(_25,dojo.hitch(this,_28,_26,_21,_1f));
+return {regexp:re,tokens:_26,bundle:_21};
+};
+dojox.date.HebrewLocale.parse=function(_29,_2a){
+if(!_2a){
+_2a={};
+}
+var _2b=dojox.date.HebrewLocale._parseInfo(_2a);
+var _2c=_2b.tokens,_2d=_2b.bundle;
+var re=new RegExp("^"+_2b.regexp+"$");
+var _2f=re.exec(_29);
+var _30=dojo.i18n.normalizeLocale(_2a.locale);
+if(!_2f){
+
+return null;
+}
+var _31,_32;
+var _33=[5730,3,23,0,0,0,0];
+var _34="";
+var _35=0;
+var _36=["abbr","wide","narrow"];
+var _37=dojo.every(_2f,function(v,i){
+if(!i){
+return true;
+}
+var _3a=_2c[i-1];
+var l=_3a.length;
+switch(_3a.charAt(0)){
+case "y":
+if(_30=="he"){
+_33[0]=dojox.date.HebrewNumerals.parseYearHebrewLetters(v);
+}else{
+_33[0]=Number(v);
+}
+break;
+case "M":
+if(l>2){
+var _3c=_2d["months-format-"+_36[l-3]].concat();
+if(!_2a.strict){
+v=v.replace(".","").toLowerCase();
+_3c=dojo.map(_3c,function(s){
+return s.replace(".","").toLowerCase();
+});
+}
+v=dojo.indexOf(_3c,v);
+if(v==-1){
+return false;
+}
+_35=l;
+}else{
+if(_30=="he"){
+v=dojox.date.HebrewNumerals.parseMonthHebrewLetters(v);
+}else{
+v--;
+}
+}
+_33[1]=Number(v);
+break;
+case "D":
+_33[1]=0;
+case "d":
+if(_30=="he"){
+_33[2]=dojox.date.HebrewNumerals.parseDayHebrewLetters(v);
+}else{
+_33[2]=Number(v);
+}
+break;
+case "a":
+var am=_2a.am||_2d.am;
+var pm=_2a.pm||_2d.pm;
+if(!_2a.strict){
+var _40=/\./g;
+v=v.replace(_40,"").toLowerCase();
+am=am.replace(_40,"").toLowerCase();
+pm=pm.replace(_40,"").toLowerCase();
+}
+if(_2a.strict&&v!=am&&v!=pm){
+return false;
+}
+_34=(v==pm)?"p":(v==am)?"a":"";
+break;
+case "K":
+if(v==24){
+v=0;
+}
+case "h":
+case "H":
+case "k":
+_33[3]=Number(v);
+break;
+case "m":
+_33[4]=Number(v);
+break;
+case "s":
+_33[5]=Number(v);
+break;
+case "S":
+_33[6]=Number(v);
+}
+return true;
+});
+var _41=+_33[3];
+if(_34==="p"&&_41<12){
+_33[3]=_41+12;
+}else{
+if(_34==="a"&&_41==12){
+_33[3]=0;
+}
+}
+var _42=new dojox.date.HebrewDate(_33[0],_33[1],_33[2],_33[3],_33[4],_33[5],_33[6]);
+if((_35>2)&&(_33[1]>5)&&!_42.isLeapYear(_42.getFullYear())){
+_42=new dojox.date.HebrewDate(_33[0],_33[1]-1,_33[2],_33[3],_33[4],_33[5],_33[6]);
+}
+return _42;
+};
+function _1b(_43,_44,_45,_46){
+var _47=function(x){
+return x;
+};
+_44=_44||_47;
+_45=_45||_47;
+_46=_46||_47;
+var _49=_43.match(/(''|[^'])+/g);
+var _4a=_43.charAt(0)=="'";
+dojo.forEach(_49,function(_4b,i){
+if(!_4b){
+_49[i]="";
+}else{
+_49[i]=(_4a?_45:_44)(_4b);
+_4a=!_4a;
+}
+});
+return _46(_49.join(""));
+};
+function _28(_4d,_4e,_4f,_50){
+_50=dojo.regexp.escapeString(_50);
+var _51=dojo.i18n.normalizeLocale(_4f.locale);
+return _50.replace(/([a-z])\1*/ig,function(_52){
+var s;
+var c=_52.charAt(0);
+var l=_52.length;
+var p2="",p3="";
+if(_4f.strict){
+if(l>1){
+p2="0"+"{"+(l-1)+"}";
+}
+if(l>2){
+p3="0"+"{"+(l-2)+"}";
+}
+}else{
+p2="0?";
+p3="0{0,2}";
+}
+switch(c){
+case "y":
+s="\\S+";
+break;
+case "M":
+if(_51=="he"){
+s=(l>2)?"\\S+ ?\\S+":"\\S{1,4}";
+}else{
+s=(l>2)?"\\S+ ?\\S+":p2+"[1-9]|1[0-2]";
+}
+break;
+case "d":
+if(_51=="he"){
+s="\\S['\"']{1,2}\\S?";
+}else{
+s="[12]\\d|"+p2+"[1-9]|30";
+}
+break;
+case "E":
+if(_51=="he"){
+s=(l>3)?"\\S+ ?\\S+":"\\S";
+}else{
+s="\\S+";
+}
+break;
+case "h":
+s=p2+"[1-9]|1[0-2]";
+break;
+case "k":
+s=p2+"\\d|1[01]";
+break;
+case "H":
+s=p2+"\\d|1\\d|2[0-3]";
+break;
+case "K":
+s=p2+"[1-9]|1\\d|2[0-4]";
+break;
+case "m":
+case "s":
+s=p2+"\\d|[0-5]\\d";
+break;
+case "S":
+s="\\d{"+l+"}";
+break;
+case "a":
+var am=_4f.am||_4e.am||"AM";
+var pm=_4f.pm||_4e.pm||"PM";
+if(_4f.strict){
+s=am+"|"+pm;
+}else{
+s=am+"|"+pm;
+if(am!=am.toLowerCase()){
+s+="|"+am.toLowerCase();
+}
+if(pm!=pm.toLowerCase()){
+s+="|"+pm.toLowerCase();
+}
+}
+break;
+default:
+s=".*";
+}
+if(_4d){
+_4d.push(_52);
+}
+return "("+s+")";
+}).replace(/[\xa0 ]/g,"[\\s\\xa0]");
+};
+})();
+(function(){
+var _5a=[];
+dojox.date.HebrewLocale.addCustomFormats=function(_5b,_5c){
+_5a.push({pkg:_5b,name:_5c});
+};
+dojox.date.HebrewLocale._getHebrewBundle=function(_5d){
+var _5e={};
+dojo.forEach(_5a,function(_5f){
+var _60=dojo.i18n.getLocalization(_5f.pkg,_5f.name,_5d);
+_5e=dojo.mixin(_5e,_60);
+},this);
+return _5e;
+};
+})();
+dojox.date.HebrewLocale.addCustomFormats("dojo.cldr","hebrew");
+dojox.date.HebrewLocale.getNames=function(_61,_62,_63,_64){
+var _65;
+var _66=dojox.date.HebrewLocale._getHebrewBundle;
+var _67=[_61,_63,_62];
+if(_63=="standAlone"){
+var key=_67.join("-");
+_65=_66(_64)[key];
+if(_65===_66("ROOT")[key]){
+_65=undefined;
+}
+}
+_67[1]="format";
+return (_65||_66(_64)[_67.join("-")]).concat();
+};
+}
diff --git a/dojox/date/HebrewNumerals.js b/dojox/date/HebrewNumerals.js
new file mode 100644
index 0000000..2f687ed
--- /dev/null
+++ b/dojox/date/HebrewNumerals.js
@@ -0,0 +1,158 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.date.HebrewNumerals"]){
+dojo._hasResource["dojox.date.HebrewNumerals"]=true;
+dojo.provide("dojox.date.HebrewNumerals");
+dojo.experimental("dojox.date.HebrewNumerals");
+(function(){
+var _1=["א","ב","ג","ד","ה","ו","ז","ח","ט"];
+var _2=["י","כ","ל","מ","נ","ס","ע","פ","צ"];
+var _3=["ק","ר","ש","ת"];
+var _4=["יה","יו","טו","טז"];
+var _5=["א'","ב'","ג'","ד'","ה'","ו'","ז'","ח'","ט'","י'","י\"א","י\"ב","י\"ג"];
+var _6=["'"];
+dojox.date.HebrewNumerals.getYearHebrewLetters=function(_7){
+var _8="",_9="";
+_7=_7%1000;
+var i=0,n=4,j=9;
+while(_7){
+if(_7>=n*100){
+_8=_8.concat(_3[n-1]);
+_7-=n*100;
+continue;
+}else{
+if(n>1){
+n--;
+continue;
+}else{
+if(_7>=j*10){
+_8=_8.concat(_2[j-1]);
+_7-=j*10;
+}else{
+if(j>1){
+j--;
+continue;
+}else{
+if(_7>0){
+_8=_8.concat(_1[_7-1]);
+_7=0;
+}
+}
+}
+}
+}
+}
+var _d="";
+var _e=_8.indexOf(_4[0]);
+if(_e>-1){
+_8=_d.concat(_8.substr(_8[0],_e),_4[2],_8.substr(_8[_e+2],_8.length-_e-2));
+}else{
+if((_e=_8.indexOf(_4[1]))>-1){
+_8=_d.concat(_8.substr(_8[0],_e),_4[3],_8.substr(_8[_e+2],_8.length-_e-2));
+}
+}
+if(_8.length>1){
+var _f=_8.charAt(_8.length-1);
+_8=_9.concat(_8.substr(0,_8.length-1),"\"",_f);
+}else{
+_8=_8.concat(_6[0]);
+}
+return _8;
+};
+dojox.date.HebrewNumerals.parseYearHebrewLetters=function(_10){
+var _11=0,i=0,j=0;
+for(j=0;j<_10.length;j++){
+for(i=1;i<=5;i++){
+if(_10.charAt(j)==_3[i-1]){
+_11+=100*i;
+continue;
+}
+}
+for(i=1;i<=9;i++){
+if(_10.charAt(j)==_2[i-1]){
+_11+=10*i;
+continue;
+}
+}
+for(i=1;i<=9;i++){
+if(_10.charAt(j)==_1[i-1]){
+_11+=i;
+}
+}
+}
+return _11+5000;
+};
+dojox.date.HebrewNumerals.getDayHebrewLetters=function(day,_15){
+var str="";
+var j=3;
+while(day){
+if(day>=j*10){
+str=str.concat(_2[j-1]);
+day-=j*10;
+}else{
+if(j>1){
+j--;
+continue;
+}else{
+if(day>0){
+str=str.concat(_1[day-1]);
+day=0;
+}
+}
+}
+}
+var _18="";
+var ind=str.indexOf(_4[0]);
+if(ind>-1){
+str=_18.concat(str.substr(str[0],ind),_4[2],str.substr(str[ind+2],str.length-ind-2));
+}else{
+if((ind=str.indexOf(_4[1]))>-1){
+str=_18.concat(str.substr(str[0],ind),_4[3],str.substr(str[ind+2],str.length-ind-2));
+}
+}
+if(!_15){
+var _1a="";
+if(str.length>1){
+var _1b=str.charAt(str.length-1);
+str=_1a.concat(str.substr(0,str.length-1),"\"",_1b);
+}else{
+str=str.concat(_6[0]);
+}
+}
+return str;
+};
+dojox.date.HebrewNumerals.parseDayHebrewLetters=function(day){
+var _1d=0,i=0;
+for(var j=0;j<day.length;j++){
+for(i=1;i<=9;i++){
+if(day.charAt(j)==_2[i-1]){
+_1d+=10*i;
+continue;
+}
+}
+for(i=1;i<=9;i++){
+if(day.charAt(j)==_1[i-1]){
+_1d+=i;
+}
+}
+}
+return _1d;
+};
+dojox.date.HebrewNumerals.getMonthHebrewLetters=function(_20,_21,_22){
+return _5[_20];
+};
+dojox.date.HebrewNumerals.parseMonthHebrewLetters=function(_23){
+var _24=dojox.date.HebrewNumerals.parseDayHebrewLetters(_23)-1;
+if(_24==-1){
+console.warn("The month name is incorrect , set 0");
+_24=0;
+}
+return _24;
+};
+})();
+}
diff --git a/dojox/date/IslamicDate.js b/dojox/date/IslamicDate.js
new file mode 100644
index 0000000..11fc03b
--- /dev/null
+++ b/dojox/date/IslamicDate.js
@@ -0,0 +1,314 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.date.IslamicDate"]){
+dojo._hasResource["dojox.date.IslamicDate"]=true;
+dojo.provide("dojox.date.IslamicDate");
+dojo.experimental("dojox.date.IslamicDate");
+dojo.require("dojo.date.locale");
+dojo.require("dojo.date");
+dojo.requireLocalization("dojo.cldr","islamic",null,"ROOT,ar");
+dojo.declare("dojox.date.IslamicDate",null,{_date:0,_month:0,_year:0,_hours:0,_minutes:0,_seconds:0,_milliseconds:0,_day:0,_GREGORIAN_EPOCH:1721425.5,_ISLAMIC_EPOCH:1948439.5,constructor:function(){
+var _1=arguments.length;
+if(_1==0){
+var d=new Date();
+this._day=d.getDay();
+this.fromGregorian(d);
+}else{
+if(_1==1){
+this.parse(arguments[0]);
+}else{
+if(_1>=3){
+this._year=arguments[0];
+this._month=arguments[1];
+this._date=arguments[2];
+this._hours=arguments[3]||0;
+this._minutes=arguments[4]||0;
+this._seconds=arguments[5]||0;
+this._milliseconds=arguments[6]||0;
+}
+}
+}
+},getDate:function(){
+return parseInt(this._date);
+},getMonth:function(){
+return parseInt(this._month);
+},getFullYear:function(){
+return parseInt(this._year);
+},getDay:function(){
+var gd=this.toGregorian();
+return gd.getDay();
+},getHours:function(){
+return this._hours;
+},getMinutes:function(){
+return this._minutes;
+},getSeconds:function(){
+return this._seconds;
+},getMilliseconds:function(){
+return this._milliseconds;
+},setDate:function(_4){
+_4=parseInt(_4);
+if(_4>0&&_4<=this.getDaysInIslamicMonth(this._month,this._year)){
+this._date=_4;
+}else{
+var _5;
+if(_4>0){
+for(_5=this.getDaysInIslamicMonth(this._month,this._year);_4>_5;_4-=_5,_5=this.getDaysInIslamicMonth(this._month,this._year)){
+this._month++;
+if(this._month>=12){
+this._year++;
+this._month-=12;
+}
+}
+this._date=_4;
+}else{
+for(_5=this.getDaysInIslamicMonth((this._month-1)>=0?(this._month-1):11,((this._month-1)>=0)?this._year:this._year-1);_4<=0;_5=this.getDaysInIslamicMonth((this._month-1)>=0?(this._month-1):11,((this._month-1)>=0)?this._year:this._year-1)){
+this._month--;
+if(this._month<0){
+this._year--;
+this._month+=12;
+}
+_4+=_5;
+}
+this._date=_4;
+}
+}
+return this;
+},setYear:function(_6){
+this._year=parseInt(_6);
+},setMonth:function(_7){
+this._year+=Math.floor(_7/12);
+this._month=Math.floor(_7%12);
+},setHours:function(){
+var _8=arguments.length;
+var _9=0;
+if(_8>=1){
+_9=parseInt(arguments[0]);
+}
+if(_8>=2){
+this._minutes=parseInt(arguments[1]);
+}
+if(_8>=3){
+this._seconds=parseInt(arguments[2]);
+}
+if(_8==4){
+this._milliseconds=parseInt(arguments[3]);
+}
+while(_9>=24){
+this._date++;
+var _a=this.getDaysInIslamicMonth(this._month,this._year);
+if(this._date>_a){
+this._month++;
+if(this._month>=12){
+this._year++;
+this._month-=12;
+}
+this._date-=_a;
+}
+_9-=24;
+}
+this._hours=_9;
+},setMinutes:function(_b){
+while(_b>=60){
+this._hours++;
+if(this._hours>=24){
+this._date++;
+this._hours-=24;
+var _c=this.getDaysInIslamicMonth(this._month,this._year);
+if(this._date>_c){
+this._month++;
+if(this._month>=12){
+this._year++;
+this._month-=12;
+}
+this._date-=_c;
+}
+}
+_b-=60;
+}
+this._minutes=_b;
+},setSeconds:function(_d){
+while(_d>=60){
+this._minutes++;
+if(this._minutes>=60){
+this._hours++;
+this._minutes-=60;
+if(this._hours>=24){
+this._date++;
+this._hours-=24;
+var _e=this.getDaysInIslamicMonth(this._month,this._year);
+if(this._date>_e){
+this._month++;
+if(this._month>=12){
+this._year++;
+this._month-=12;
+}
+this._date-=_e;
+}
+}
+}
+_d-=60;
+}
+this._seconds=_d;
+},setMilliseconds:function(_f){
+while(_f>=1000){
+this.setSeconds++;
+if(this.setSeconds>=60){
+this._minutes++;
+this.setSeconds-=60;
+if(this._minutes>=60){
+this._hours++;
+this._minutes-=60;
+if(this._hours>=24){
+this._date++;
+this._hours-=24;
+var _10=this.getDaysInIslamicMonth(this._month,this._year);
+if(this._date>_10){
+this._month++;
+if(this._month>=12){
+this._year++;
+this._month-=12;
+}
+this._date-=_10;
+}
+}
+}
+}
+_f-=1000;
+}
+this._milliseconds=_f;
+},toString:function(){
+var x=new Date();
+x.setHours(this._hours);
+x.setMinutes(this._minutes);
+x.setSeconds(this._seconds);
+x.setMilliseconds(this._milliseconds);
+var _12=x.toTimeString();
+return (dojox.date.IslamicDate.weekDays[this.getDay()]+" "+dojox.date.IslamicDate.months[this._month]+" "+this._date+" "+this._year+" "+_12);
+},toGregorian:function(){
+var _13=this._year;
+var _14=this._month;
+var _15=this._date;
+var _16=_15+Math.ceil(29.5*_14)+(_13-1)*354+Math.floor((3+(11*_13))/30)+this._ISLAMIC_EPOCH-1;
+var wjd=Math.floor(_16-0.5)+0.5,_18=wjd-this._GREGORIAN_EPOCH,_19=Math.floor(_18/146097),dqc=this._mod(_18,146097),_1b=Math.floor(dqc/36524),_1c=this._mod(dqc,36524),_1d=Math.floor(_1c/1461),_1e=this._mod(_1c,1461),_1f=Math.floor(_1e/365),_20=(_19*400)+(_1b*100)+(_1d*4)+_1f;
+if(!(_1b==4||_1f==4)){
+_20++;
+}
+var _21=this._GREGORIAN_EPOCH+(365*(_20-1))+Math.floor((_20-1)/4)-(Math.floor((_20-1)/100))+Math.floor((_20-1)/400);
+var _22=wjd-_21;
+var tjd=(this._GREGORIAN_EPOCH-1)+(365*(_20-1))+Math.floor((_20-1)/4)-(Math.floor((_20-1)/100))+Math.floor((_20-1)/400)+Math.floor((739/12)+((dojo.date.isLeapYear(new Date(_20,3,1))?-1:-2))+1);
+var _24=((wjd<tjd)?0:(dojo.date.isLeapYear(new Date(_20,3,1))?1:2));
+var _25=Math.floor((((_22+_24)*12)+373)/367);
+var _26=(this._GREGORIAN_EPOCH-1)+(365*(_20-1))+Math.floor((_20-1)/4)-(Math.floor((_20-1)/100))+Math.floor((_20-1)/400)+Math.floor((((367*_25)-362)/12)+((_25<=2)?0:(dojo.date.isLeapYear(new Date(_20,_25,1))?-1:-2))+1);
+var day=(wjd-_26);
+var _28=new Date(_20,_25-1,day);
+_28.setHours(this._hours);
+_28.setMilliseconds(this._milliseconds);
+_28.setMinutes(this._minutes);
+_28.setSeconds(this._seconds);
+return _28;
+},fromGregorian:function(_29){
+var _2a=new Date(_29);
+var _2b=_2a.getFullYear(),_2c=_2a.getMonth(),_2d=_2a.getDate();
+var _2e=(this._GREGORIAN_EPOCH-1)+(365*(_2b-1))+Math.floor((_2b-1)/4)+(-Math.floor((_2b-1)/100))+Math.floor((_2b-1)/400)+Math.floor((((367*(_2c+1))-362)/12)+(((_2c+1)<=2)?0:(dojo.date.isLeapYear(_2a)?-1:-2))+_2d)+(Math.floor(_2a.getSeconds()+60*(_2a.getMinutes()+60*_2a.getHours())+0.5)/86400);
+_2e=Math.floor(_2e)+0.5;
+var _2f=_2e-1948440;
+var _30=Math.floor((30*_2f+10646)/10631);
+var _31=Math.ceil((_2f-29-this._yearStart(_30))/29.5);
+_31=Math.min(_31,11);
+var _32=Math.ceil(_2f-this._monthStart(_30,_31))+1;
+this._date=_32;
+this._month=_31;
+this._year=_30;
+this._hours=_2a.getHours();
+this._minutes=_2a.getMinutes();
+this._seconds=_2a.getSeconds();
+this._milliseconds=_2a.getMilliseconds();
+this._day=_2a.getDay();
+return this;
+},parse:function(_33){
+var _34=_33.toString();
+var _35=/\d{1,2}\D\d{1,2}\D\d{4}/;
+var sD,jd,mD=_34.match(_35);
+if(mD){
+mD=mD.toString();
+sD=mD.split(/\D/);
+this._month=sD[0]-1;
+this._date=sD[1];
+this._year=sD[2];
+}else{
+mD=_34.match(/\D{4,}\s\d{1,2}\s\d{4}/);
+if(mD){
+mD=mD.toString();
+var _39=mD.match(/\d{1,2}\s\d{4}/);
+_39=_39.toString();
+var _3a=mD.replace(/\s\d{1,2}\s\d{4}/,"");
+_3a=_3a.toString();
+this._month=dojo.indexOf(this._months,_3a);
+sD=_39.split(/\s/);
+this._date=sD[0];
+this._year=sD[1];
+}
+}
+var _3b=_34.match(/\d{2}:/);
+if(_3b!=null){
+_3b=_3b.toString();
+var _3c=_3b.split(":");
+this._hours=_3c[0];
+_3b=_34.match(/\d{2}:\d{2}/);
+if(_3b){
+_3b=_3b.toString();
+_3c=_3b.split(":");
+}
+this._minutes=_3c[1]!=null?_3c[1]:0;
+_3b=_34.match(/\d{2}:\d{2}:\d{2}/);
+if(_3b){
+_3b=_3b.toString();
+_3c=_3b.split(":");
+}
+this._seconds=_3c[2]!=null?_3c[2]:0;
+}else{
+this._hours=0;
+this._minutes=0;
+this._seconds=0;
+}
+this._milliseconds=0;
+},valueOf:function(){
+var _3d=this.toGregorian();
+return _3d.valueOf();
+},_yearStart:function(_3e){
+return (_3e-1)*354+Math.floor((3+11*_3e)/30);
+},_monthStart:function(_3f,_40){
+return Math.ceil(29.5*_40)+(_3f-1)*354+Math.floor((3+11*_3f)/30);
+},_civilLeapYear:function(_41){
+return (14+11*_41)%30<11;
+},getDaysInIslamicMonth:function(_42,_43){
+var _44=0;
+_44=29+((_42+1)%2);
+if(_42==11&&this._civilLeapYear(_43)){
+_44++;
+}
+return _44;
+},_mod:function(a,b){
+return a-(b*Math.floor(a/b));
+}});
+dojox.date.IslamicDate.getDaysInIslamicMonth=function(_47){
+return new dojox.date.IslamicDate().getDaysInIslamicMonth(_47.getMonth(),_47.getFullYear());
+};
+dojox.date.IslamicDate._getNames=function(_48,_49,use,_4b){
+var _4c;
+var _4d=dojo.i18n.getLocalization("dojo.cldr","islamic",_4b);
+var _4e=[_48,use,_49];
+if(use=="standAlone"){
+_4c=_4d[_4e.join("-")];
+}
+_4e[1]="format";
+return (_4c||_4d[_4e.join("-")]).concat();
+};
+dojox.date.IslamicDate.weekDays=dojox.date.IslamicDate._getNames("days","wide","format");
+dojox.date.IslamicDate.months=dojox.date.IslamicDate._getNames("months","wide","format");
+}
diff --git a/dojox/date/README b/dojox/date/README
new file mode 100644
index 0000000..8395369
--- /dev/null
+++ b/dojox/date/README
@@ -0,0 +1,40 @@
+-------------------------------------------------------------------------------
+DojoX Date
+-------------------------------------------------------------------------------
+Version 0.9
+Release date: 5/17/2007
+-------------------------------------------------------------------------------
+Project state:
+experimental
+-------------------------------------------------------------------------------
+Credits
+	Paul Sowden (dojox.date.posix)
+	Neil Roberts (dojox.date.php)
+	Hossam Aldin Katory (dojox.date.IslamicCalendar, dojox.date.HebrewCalendar)
+-------------------------------------------------------------------------------
+Project description
+
+Placeholder for any kind of date operations, including formatters that are
+common to other languages (posix and php).
+-------------------------------------------------------------------------------
+Dependencies:
+
+Depends only on the Dojo Core.
+-------------------------------------------------------------------------------
+Documentation
+
+See the API documentation for details.
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/date/*
+
+Install into the following directory structure:
+/dojox/date/
+
+...which should be at the same level as your Dojo checkout.
+
+To use the non-Gregorian calendars, you must do a complete build of dojo.cldr.
+See util/buildscripts/cldr/README for details.
+-------------------------------------------------------------------------------
diff --git a/dojox/date/php.js b/dojox/date/php.js
new file mode 100644
index 0000000..867c445
--- /dev/null
+++ b/dojox/date/php.js
@@ -0,0 +1,185 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.date.php"]){
+dojo._hasResource["dojox.date.php"]=true;
+dojo.provide("dojox.date.php");
+dojo.require("dojo.date");
+dojo.require("dojox.string.tokenize");
+dojox.date.php.format=function(_1,_2){
+var df=new dojox.date.php.DateFormat(_2);
+return df.format(_1);
+};
+dojox.date.php.DateFormat=function(_4){
+if(!this.regex){
+var _5=[];
+for(var _6 in this.constructor.prototype){
+if(dojo.isString(_6)&&_6.length==1&&dojo.isFunction(this[_6])){
+_5.push(_6);
+}
+}
+this.constructor.prototype.regex=new RegExp("(?:(\\\\.)|(["+_5.join("")+"]))","g");
+}
+var _7=[];
+this.tokens=dojox.string.tokenize(_4,this.regex,function(_8,_9,i){
+if(_9){
+_7.push([i,_9]);
+return _9;
+}
+if(_8){
+return _8.charAt(1);
+}
+});
+this.replacements=_7;
+};
+dojo.extend(dojox.date.php.DateFormat,{weekdays:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],weekdays_3:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],months_3:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],monthdays:[31,28,31,30,31,30,31,31,30,31,30,31],format:function(_b){
+this.date=_b;
+for(var i=0,_d;_d=this.replacements[i];i++){
+this.tokens[_d[0]]=this[_d[1]]();
+}
+return this.tokens.join("");
+},d:function(){
+var j=this.j();
+return (j.length==1)?"0"+j:j;
+},D:function(){
+return this.weekdays_3[this.date.getDay()];
+},j:function(){
+return this.date.getDate()+"";
+},l:function(){
+return this.weekdays[this.date.getDay()];
+},N:function(){
+var w=this.w();
+return (!w)?7:w;
+},S:function(){
+switch(this.date.getDate()){
+case 11:
+case 12:
+case 13:
+return "th";
+case 1:
+case 21:
+case 31:
+return "st";
+case 2:
+case 22:
+return "nd";
+case 3:
+case 23:
+return "rd";
+default:
+return "th";
+}
+},w:function(){
+return this.date.getDay()+"";
+},z:function(){
+var _10=this.date.getTime()-new Date(this.date.getFullYear(),0,1).getTime();
+return Math.floor(_10/86400000)+"";
+},W:function(){
+var _11;
+var _12=new Date(this.date.getFullYear(),0,1).getDay()+1;
+var w=this.date.getDay()+1;
+var z=parseInt(this.z());
+if(z<=(8-_12)&&_12>4){
+var _15=new Date(this.date.getFullYear()-1,this.date.getMonth(),this.date.getDate());
+if(_12==5||(_12==6&&dojo.date.isLeapYear(_15))){
+_11=53;
+}else{
+_11=52;
+}
+}else{
+var i;
+if(Boolean(this.L())){
+i=366;
+}else{
+i=365;
+}
+if((i-z)<(4-w)){
+_11=1;
+}else{
+var j=z+(7-w)+(_12-1);
+_11=Math.ceil(j/7);
+if(_12>4){
+--_11;
+}
+}
+}
+return _11;
+},F:function(){
+return this.months[this.date.getMonth()];
+},m:function(){
+var n=this.n();
+return (n.length==1)?"0"+n:n;
+},M:function(){
+return this.months_3[this.date.getMonth()];
+},n:function(){
+return this.date.getMonth()+1+"";
+},t:function(){
+return (Boolean(this.L())&&this.date.getMonth()==1)?29:this.monthdays[this.getMonth()];
+},L:function(){
+return (dojo.date.isLeapYear(this.date))?"1":"0";
+},o:function(){
+},Y:function(){
+return this.date.getFullYear()+"";
+},y:function(){
+return this.Y().slice(-2);
+},a:function(){
+return this.date.getHours()>=12?"pm":"am";
+},b:function(){
+return this.a().toUpperCase();
+},B:function(){
+var off=this.date.getTimezoneOffset()+60;
+var _1a=(this.date.getHours()*3600)+(this.date.getMinutes()*60)+this.getSeconds()+(off*60);
+var _1b=Math.abs(Math.floor(_1a/86.4)%1000)+"";
+while(_1b.length<2){
+_1b="0"+_1b;
+}
+return _1b;
+},g:function(){
+return (this.date.getHours()>12)?this.date.getHours()-12+"":this.date.getHours()+"";
+},G:function(){
+return this.date.getHours()+"";
+},h:function(){
+var g=this.g();
+return (g.length==1)?"0"+g:g;
+},H:function(){
+var G=this.G();
+return (G.length==1)?"0"+G:G;
+},i:function(){
+var _1e=this.date.getMinutes()+"";
+return (_1e.length==1)?"0"+_1e:_1e;
+},s:function(){
+var _1f=this.date.getSeconds()+"";
+return (_1f.length==1)?"0"+_1f:_1f;
+},e:function(){
+return dojo.date.getTimezoneName(this.date);
+},I:function(){
+},O:function(){
+var off=Math.abs(this.date.getTimezoneOffset());
+var _21=Math.floor(off/60)+"";
+var _22=(off%60)+"";
+if(_21.length==1){
+_21="0"+_21;
+}
+if(_22.length==1){
+_21="0"+_22;
+}
+return ((this.date.getTimezoneOffset()<0)?"+":"-")+_21+_22;
+},P:function(){
+var O=this.O();
+return O.substring(0,2)+":"+O.substring(2,4);
+},T:function(){
+return this.e().substring(0,3);
+},Z:function(){
+return this.date.getTimezoneOffset()*-60;
+},c:function(){
+return this.Y()+"-"+this.m()+"-"+this.d()+"T"+this.h()+":"+this.i()+":"+this.s()+this.P();
+},r:function(){
+return this.D()+", "+this.d()+" "+this.M()+" "+this.Y()+" "+this.H()+":"+this.i()+":"+this.s()+" "+this.O();
+},U:function(){
+return Math.floor(this.date.getTime()/1000);
+}});
+}
diff --git a/dojox/date/posix.js b/dojox/date/posix.js
new file mode 100644
index 0000000..bcbbdab
--- /dev/null
+++ b/dojox/date/posix.js
@@ -0,0 +1,218 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.date.posix"]){
+dojo._hasResource["dojox.date.posix"]=true;
+dojo.provide("dojox.date.posix");
+dojo.require("dojo.date");
+dojo.require("dojo.date.locale");
+dojo.require("dojo.string");
+dojox.date.posix.strftime=function(_1,_2,_3){
+var _4=null;
+var _=function(s,n){
+return dojo.string.pad(s,n||2,_4||"0");
+};
+var _8=dojo.date.locale._getGregorianBundle(_3);
+var $=function(_a){
+switch(_a){
+case "a":
+return dojo.date.locale.getNames("days","abbr","format",_3)[_1.getDay()];
+case "A":
+return dojo.date.locale.getNames("days","wide","format",_3)[_1.getDay()];
+case "b":
+case "h":
+return dojo.date.locale.getNames("months","abbr","format",_3)[_1.getMonth()];
+case "B":
+return dojo.date.locale.getNames("months","wide","format",_3)[_1.getMonth()];
+case "c":
+return dojo.date.locale.format(_1,{formatLength:"full",locale:_3});
+case "C":
+return _(Math.floor(_1.getFullYear()/100));
+case "d":
+return _(_1.getDate());
+case "D":
+return $("m")+"/"+$("d")+"/"+$("y");
+case "e":
+if(_4==null){
+_4=" ";
+}
+return _(_1.getDate());
+case "f":
+if(_4==null){
+_4=" ";
+}
+return _(_1.getMonth()+1);
+case "g":
+break;
+case "G":
+dojo.unimplemented("unimplemented modifier 'G'");
+break;
+case "F":
+return $("Y")+"-"+$("m")+"-"+$("d");
+case "H":
+return _(_1.getHours());
+case "I":
+return _(_1.getHours()%12||12);
+case "j":
+return _(dojo.date.locale._getDayOfYear(_1),3);
+case "k":
+if(_4==null){
+_4=" ";
+}
+return _(_1.getHours());
+case "l":
+if(_4==null){
+_4=" ";
+}
+return _(_1.getHours()%12||12);
+case "m":
+return _(_1.getMonth()+1);
+case "M":
+return _(_1.getMinutes());
+case "n":
+return "\n";
+case "p":
+return _8[_1.getHours()<12?"am":"pm"];
+case "r":
+return $("I")+":"+$("M")+":"+$("S")+" "+$("p");
+case "R":
+return $("H")+":"+$("M");
+case "S":
+return _(_1.getSeconds());
+case "t":
+return "\t";
+case "T":
+return $("H")+":"+$("M")+":"+$("S");
+case "u":
+return String(_1.getDay()||7);
+case "U":
+return _(dojo.date.locale._getWeekOfYear(_1));
+case "V":
+return _(dojox.date.posix.getIsoWeekOfYear(_1));
+case "W":
+return _(dojo.date.locale._getWeekOfYear(_1,1));
+case "w":
+return String(_1.getDay());
+case "x":
+return dojo.date.locale.format(_1,{selector:"date",formatLength:"full",locale:_3});
+case "X":
+return dojo.date.locale.format(_1,{selector:"time",formatLength:"full",locale:_3});
+case "y":
+return _(_1.getFullYear()%100);
+case "Y":
+return String(_1.getFullYear());
+case "z":
+var _b=_1.getTimezoneOffset();
+return (_b>0?"-":"+")+_(Math.floor(Math.abs(_b)/60))+":"+_(Math.abs(_b)%60);
+case "Z":
+return dojo.date.getTimezoneName(_1);
+case "%":
+return "%";
+}
+};
+var _c="";
+var i=0;
+var _e=0;
+var _f=null;
+while((_e=_2.indexOf("%",i))!=-1){
+_c+=_2.substring(i,_e++);
+switch(_2.charAt(_e++)){
+case "_":
+_4=" ";
+break;
+case "-":
+_4="";
+break;
+case "0":
+_4="0";
+break;
+case "^":
+_f="upper";
+break;
+case "*":
+_f="lower";
+break;
+case "#":
+_f="swap";
+break;
+default:
+_4=null;
+_e--;
+break;
+}
+var _10=$(_2.charAt(_e++));
+switch(_f){
+case "upper":
+_10=_10.toUpperCase();
+break;
+case "lower":
+_10=_10.toLowerCase();
+break;
+case "swap":
+var _11=_10.toLowerCase();
+var _12="";
+var ch="";
+for(var j=0;j<_10.length;j++){
+ch=_10.charAt(j);
+_12+=(ch==_11.charAt(j))?ch.toUpperCase():ch.toLowerCase();
+}
+_10=_12;
+break;
+default:
+break;
+}
+_f=null;
+_c+=_10;
+i=_e;
+}
+_c+=_2.substring(i);
+return _c;
+};
+dojox.date.posix.getStartOfWeek=function(_15,_16){
+if(isNaN(_16)){
+_16=dojo.cldr.supplemental.getFirstDayOfWeek?dojo.cldr.supplemental.getFirstDayOfWeek():0;
+}
+var _17=_16;
+if(_15.getDay()>=_16){
+_17-=_15.getDay();
+}else{
+_17-=(7-_15.getDay());
+}
+var _18=new Date(_15);
+_18.setHours(0,0,0,0);
+return dojo.date.add(_18,"day",_17);
+};
+dojox.date.posix.setIsoWeekOfYear=function(_19,_1a){
+if(!_1a){
+return _19;
+}
+var _1b=dojox.date.posix.getIsoWeekOfYear(_19);
+var _1c=_1a-_1b;
+if(_1a<0){
+var _1d=dojox.date.posix.getIsoWeeksInYear(_19);
+_1c=(_1d+_1a+1)-_1b;
+}
+return dojo.date.add(_19,"week",_1c);
+};
+dojox.date.posix.getIsoWeekOfYear=function(_1e){
+var _1f=dojox.date.posix.getStartOfWeek(_1e,1);
+var _20=new Date(_1e.getFullYear(),0,4);
+_20=dojox.date.posix.getStartOfWeek(_20,1);
+var _21=_1f.getTime()-_20.getTime();
+if(_21<0){
+return dojox.date.posix.getIsoWeeksInYear(_1f);
+}
+return Math.ceil(_21/604800000)+1;
+};
+dojox.date.posix.getIsoWeeksInYear=function(_22){
+function p(y){
+return y+Math.floor(y/4)-Math.floor(y/100)+Math.floor(y/400);
+};
+var y=_22.getFullYear();
+return (p(y)%7==4||p(y-1)%7==3)?53:52;
+};
+}
diff --git a/dojox/dtl.js b/dojox/dtl.js
new file mode 100644
index 0000000..310df48
--- /dev/null
+++ b/dojox/dtl.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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 a compiled version of Dojo, built for deployment and not for
+	development. To get an editable version, please visit:
+
+		http://dojotoolkit.org
+
+	for documentation and information on getting the source.
+*/
+
+if(!dojo._hasResource["dojox.string.Builder"]){dojo._hasResource["dojox.string.Builder"]=true;dojo.provide("dojox.string.Builder");dojox.string.Builder=function(_1){var b="";this.length=0;this.append=function(s){if(arguments.length>1){var _4="",l=arguments.length;switch(l){case 9:_4=""+arguments[8]+_4;case 8:_4=""+arguments[7]+_4;case 7:_4=""+arguments[6]+_4;case 6:_4=""+arguments[5]+_4;case 5:_4=""+arguments[4]+_4;case 4:_4=""+arguments[3]+_4;case 3:_4=""+arguments[2]+_4;case 2:b+=""+ar [...]
diff --git a/dojox/dtl.js.uncompressed.js b/dojox/dtl.js.uncompressed.js
new file mode 100644
index 0000000..beb30a7
--- /dev/null
+++ b/dojox/dtl.js.uncompressed.js
@@ -0,0 +1,2856 @@
+/*
+	Copyright (c) 2004-2009, 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 a compiled version of Dojo, built for deployment and not for
+	development. To get an editable version, please visit:
+
+		http://dojotoolkit.org
+
+	for documentation and information on getting the source.
+*/
+
+if(!dojo._hasResource["dojox.string.Builder"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.string.Builder"] = true;
+dojo.provide("dojox.string.Builder");
+
+dojox.string.Builder = function(/*String?*/str){
+	//	summary:
+	//		A fast buffer for creating large strings.
+	//
+	//	length: Number
+	//		The current length of the internal string.
+
+	//	N.B. the public nature of the internal buffer is no longer
+	//	needed because the IE-specific fork is no longer needed--TRT.
+	var b = "";
+	this.length = 0;
+	
+	this.append = function(/* String... */s){ 
+		// summary: Append all arguments to the end of the buffer 
+		if(arguments.length>1){
+			/*  
+				This is a loop unroll was designed specifically for Firefox;
+				it would seem that static index access on an Arguments
+				object is a LOT faster than doing dynamic index access.
+				Therefore, we create a buffer string and take advantage
+				of JS's switch fallthrough.  The peformance of this method
+				comes very close to straight up string concatenation (+=).
+
+				If the arguments object length is greater than 9, we fall
+				back to standard dynamic access.
+
+				This optimization seems to have no real effect on either
+				Safari or Opera, so we just use it for all.
+
+				It turns out also that this loop unroll can increase performance
+				significantly with Internet Explorer, particularly when 
+				as many arguments are provided as possible.
+
+				Loop unroll per suggestion from Kris Zyp, implemented by 
+				Tom Trenka.
+
+				Note: added empty string to force a string cast if needed.
+			 */
+			var tmp="", l=arguments.length;
+			switch(l){
+				case 9: tmp=""+arguments[8]+tmp;
+				case 8: tmp=""+arguments[7]+tmp;
+				case 7: tmp=""+arguments[6]+tmp;
+				case 6: tmp=""+arguments[5]+tmp;
+				case 5: tmp=""+arguments[4]+tmp;
+				case 4: tmp=""+arguments[3]+tmp;
+				case 3: tmp=""+arguments[2]+tmp;
+				case 2: {
+					b+=""+arguments[0]+arguments[1]+tmp;
+					break;
+				}
+				default: {
+					var i=0;
+					while(i<arguments.length){
+						tmp += arguments[i++];
+					}
+					b += tmp;
+				}
+			}
+		} else {
+			b += s;
+		}
+		this.length = b.length;
+		return this;	//	dojox.string.Builder
+	};
+	
+	this.concat = function(/*String...*/s){
+		//	summary:
+		//		Alias for append.
+		return this.append.apply(this, arguments);	//	dojox.string.Builder
+	};
+	
+	this.appendArray = function(/*Array*/strings) {
+		//	summary:
+		//		Append an array of items to the internal buffer.
+
+		//	Changed from String.prototype.concat.apply because of IE.
+		return this.append.apply(this, strings);	//	dojox.string.Builder
+	};
+	
+	this.clear = function(){
+		//	summary: 
+		//		Remove all characters from the buffer.
+		b = "";
+		this.length = 0;
+		return this;	//	dojox.string.Builder
+	};
+	
+	this.replace = function(/* String */oldStr, /* String */ newStr){
+		// 	summary: 
+		//		Replace instances of one string with another in the buffer.
+		b = b.replace(oldStr,newStr);
+		this.length = b.length;
+		return this;	//	dojox.string.Builder
+	};
+	
+	this.remove = function(/* Number */start, /* Number? */len){
+		//	summary:
+		//		Remove len characters starting at index start.  If len
+		//		is not provided, the end of the string is assumed.
+		if(len===undefined){ len = b.length; }
+		if(len == 0){ return this; }
+		b = b.substr(0, start) + b.substr(start+len);
+		this.length = b.length;
+		return this;	//	dojox.string.Builder
+	};
+	
+	this.insert = function(/* Number */index, /* String */str){
+		//	summary: 
+		//		Insert string str starting at index.
+		if(index == 0){
+			b = str + b;
+		}else{
+			b = b.slice(0, index) + str + b.slice(index);
+		}
+		this.length = b.length;
+		return this;	//	dojox.string.Builder
+	};
+	
+	this.toString = function(){
+		//	summary:
+		//		Return the string representation of the internal buffer.
+		return b;	//	String
+	};
+
+	//	initialize the buffer.
+	if(str){ this.append(str); }
+};
+
+}
+
+if(!dojo._hasResource["dojox.string.tokenize"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.string.tokenize"] = true;
+dojo.provide("dojox.string.tokenize");
+
+dojox.string.tokenize = function(/*String*/ str, /*RegExp*/ re, /*Function?*/ parseDelim, /*Object?*/ instance){
+	// summary:
+	//		Split a string by a regular expression with the ability to capture the delimeters
+	// parseDelim:
+	//		Each group (excluding the 0 group) is passed as a parameter. If the function returns
+	//		a value, it's added to the list of tokens.
+	// instance:
+	//		Used as the "this" instance when calling parseDelim
+	var tokens = [];
+	var match, content, lastIndex = 0;
+	while(match = re.exec(str)){
+		content = str.slice(lastIndex, re.lastIndex - match[0].length);
+		if(content.length){
+			tokens.push(content);
+		}
+		if(parseDelim){
+			if(dojo.isOpera){
+				var copy = match.slice(0);
+				while(copy.length < match.length){
+					copy.push(null);
+				}
+				match = copy;
+			}
+			var parsed = parseDelim.apply(instance, match.slice(1).concat(tokens.length));
+			if(typeof parsed != "undefined"){
+				tokens.push(parsed);
+			}
+		}
+		lastIndex = re.lastIndex;
+	}
+	content = str.slice(lastIndex);
+	if(content.length){
+		tokens.push(content);
+	}
+	return tokens;
+}
+
+}
+
+if(!dojo._hasResource["dojox.dtl._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.dtl._base"] = true;
+dojo.provide("dojox.dtl._base");
+
+
+
+
+dojo.experimental("dojox.dtl");
+
+(function(){
+	var dd = dojox.dtl;
+
+	dd.TOKEN_BLOCK = -1;
+	dd.TOKEN_VAR = -2;
+	dd.TOKEN_COMMENT = -3;
+	dd.TOKEN_TEXT = 3;
+
+	dd._Context = dojo.extend(function(dict){
+		// summary: Pass one of these when rendering a template to tell the template what values to use.
+		dojo._mixin(this, dict || {});
+		this._dicts = [];
+	},
+	{
+		push: function(){
+			var last = this;
+			var context = dojo.delegate(this);
+			context.pop = function(){ return last; }
+			return context;
+		},
+		pop: function(){
+			throw new Error("pop() called on empty Context");
+		},
+		get: function(key, otherwise){
+			if(typeof this[key] != "undefined"){
+				return this._normalize(this[key]);
+			}
+
+			for(var i = 0, dict; dict = this._dicts[i]; i++){
+				if(typeof dict[key] != "undefined"){
+					return this._normalize(dict[key]);
+				}
+			}
+
+			return otherwise;
+		},
+		_normalize: function(value){
+			if(value instanceof Date){
+				value.year = value.getFullYear();
+				value.month = value.getMonth() + 1;
+				value.day = value.getDate();
+				value.date = value.year + "-" + ("0" + value.month).slice(-2) + "-" + ("0" + value.day).slice(-2);
+				value.hour = value.getHours();
+				value.minute = value.getMinutes();
+				value.second = value.getSeconds();
+				value.microsecond = value.getMilliseconds();
+			}
+			return value;
+		},
+		update: function(dict){
+			var context = this.push();
+			if(dict){
+				dojo._mixin(this, dict);
+			}
+			return context;
+		}
+	});
+
+	var smart_split_re = /("(?:[^"\\]*(?:\\.[^"\\]*)*)"|'(?:[^'\\]*(?:\\.[^'\\]*)*)'|[^\s]+)/g;           
+	var split_re = /\s+/g;
+	var split = function(/*String|RegExp?*/ splitter, /*Integer?*/ limit){
+		splitter = splitter || split_re;
+		if(!(splitter instanceof RegExp)){
+			splitter = new RegExp(splitter, "g");
+		}
+		if(!splitter.global){
+			throw new Error("You must use a globally flagged RegExp with split " + splitter);
+		}
+		splitter.exec(""); // Reset the global
+
+		var part, parts = [], lastIndex = 0, i = 0;
+		while(part = splitter.exec(this)){
+			parts.push(this.slice(lastIndex, splitter.lastIndex - part[0].length));
+			lastIndex = splitter.lastIndex;
+			if(limit && (++i > limit - 1)){
+				break;
+			}
+		}
+		parts.push(this.slice(lastIndex));
+		return parts;
+	}
+
+	dd.Token = function(token_type, contents){
+		this.token_type = token_type;
+		this.contents = new String(dojo.trim(contents));
+		this.contents.split = split;
+		this.split = function(){
+			return String.prototype.split.apply(this.contents, arguments);
+		}
+	}
+	dd.Token.prototype.split_contents = function(/*Integer?*/ limit){
+		var bit, bits = [], i = 0;
+		limit = limit || 999;
+		while(i++ < limit && (bit = smart_split_re.exec(this.contents))){
+			bit = bit[0];
+			if(bit.charAt(0) == '"' && bit.slice(-1) == '"'){
+				bits.push('"' + bit.slice(1, -1).replace('\\"', '"').replace('\\\\', '\\') + '"');
+			}else if(bit.charAt(0) == "'" && bit.slice(-1) == "'"){
+				bits.push("'" + bit.slice(1, -1).replace("\\'", "'").replace('\\\\', '\\') + "'");
+			}else{
+				bits.push(bit);
+			}
+		}
+		return bits;
+	}
+
+	var ddt = dd.text = {
+		_get: function(module, name, errorless){
+			// summary: Used to find both tags and filters
+			var params = dd.register.get(module, name.toLowerCase(), errorless);
+			if(!params){
+				if(!errorless){
+					throw new Error("No tag found for " + name);
+				}
+				return null;
+			}
+
+			var fn = params[1];
+			var require = params[2];
+
+			var parts;
+			if(fn.indexOf(":") != -1){
+				parts = fn.split(":");
+				fn = parts.pop();
+			}
+
+			dojo["require"](require);
+
+			var parent = dojo.getObject(require);
+
+			return parent[fn || name] || parent[name + "_"] || parent[fn + "_"];
+		},
+		getTag: function(name, errorless){
+			return ddt._get("tag", name, errorless);
+		},
+		getFilter: function(name, errorless){
+			return ddt._get("filter", name, errorless);
+		},
+		getTemplate: function(file){
+			return new dd.Template(ddt.getTemplateString(file));
+		},
+		getTemplateString: function(file){
+			return dojo._getText(file.toString()) || "";
+		},
+		_resolveLazy: function(location, sync, json){
+			if(sync){
+				if(json){
+					return dojo.fromJson(dojo._getText(location)) || {};
+				}else{
+					return dd.text.getTemplateString(location);
+				}
+			}else{
+				return dojo.xhrGet({
+					handleAs: (json) ? "json" : "text",
+					url: location
+				});
+			}
+		},
+		_resolveTemplateArg: function(arg, sync){
+			if(ddt._isTemplate(arg)){
+				if(!sync){
+					var d = new dojo.Deferred();
+					d.callback(arg);
+					return d;
+				}
+				return arg;
+			}
+			return ddt._resolveLazy(arg, sync);
+		},
+		_isTemplate: function(arg){
+			return (typeof arg == "undefined") || (typeof arg == "string" && (arg.match(/^\s*[<{]/) || arg.indexOf(" ") != -1));
+		},
+		_resolveContextArg: function(arg, sync){
+			if(arg.constructor == Object){
+				if(!sync){
+					var d = new dojo.Deferred;
+					d.callback(arg);
+					return d;
+				}
+				return arg;
+			}
+			return ddt._resolveLazy(arg, sync, true);
+		},
+		_re: /(?:\{\{\s*(.+?)\s*\}\}|\{%\s*(load\s*)?(.+?)\s*%\})/g,
+		tokenize: function(str){
+			return dojox.string.tokenize(str, ddt._re, ddt._parseDelims);
+		},
+		_parseDelims: function(varr, load, tag){
+			if(varr){
+				return [dd.TOKEN_VAR, varr];
+			}else if(load){
+				var parts = dojo.trim(tag).split(/\s+/g);
+				for(var i = 0, part; part = parts[i]; i++){
+					dojo["require"](part);
+				}
+			}else{
+				return [dd.TOKEN_BLOCK, tag];
+			}
+		}
+	}
+
+	dd.Template = dojo.extend(function(/*String|dojo._Url*/ template, /*Boolean*/ isString){
+		// template:
+		//		The string or location of the string to
+		//		use as a template
+		var str = isString ? template : ddt._resolveTemplateArg(template, true) || "";
+		var tokens = ddt.tokenize(str);
+		var parser = new dd._Parser(tokens);
+		this.nodelist = parser.parse();
+	},
+	{
+		update: function(node, context){
+			// node: DOMNode|String|dojo.NodeList
+			//		A node reference or set of nodes
+			// context: dojo._Url|String|Object
+			//		The context object or location
+			return ddt._resolveContextArg(context).addCallback(this, function(contextObject){
+				var content = this.render(new dd._Context(contextObject));
+				if(node.forEach){
+					node.forEach(function(item){
+						item.innerHTML = content;
+					});
+				}else{
+					dojo.byId(node).innerHTML = content;
+				}
+				return this;
+			});
+		},
+		render: function(context, /*concatenatable?*/ buffer){
+			buffer = buffer || this.getBuffer();
+			context = context || new dd._Context({});
+			return this.nodelist.render(context, buffer) + "";
+		},
+		getBuffer: function(){
+			
+			return new dojox.string.Builder();
+		}
+	});
+
+	var qfRe = /\{\{\s*(.+?)\s*\}\}/g;
+	dd.quickFilter = function(str){
+		if(!str){
+			return new dd._NodeList();
+		}
+
+		if(str.indexOf("{%") == -1){
+			return new dd._QuickNodeList(dojox.string.tokenize(str, qfRe, function(token){
+				return new dd._Filter(token);
+			}));
+		}
+	}
+
+	dd._QuickNodeList = dojo.extend(function(contents){
+		this.contents = contents;
+	},
+	{
+		render: function(context, buffer){
+			for(var i=0, l=this.contents.length; i<l; i++){
+				if(this.contents[i].resolve){
+					buffer = buffer.concat(this.contents[i].resolve(context));
+				}else{
+					buffer = buffer.concat(this.contents[i]);
+				}
+			}
+			return buffer;
+		},
+		dummyRender: function(context){ return this.render(context, dd.Template.prototype.getBuffer()).toString(); },
+		clone: function(buffer){ return this; }
+	});
+
+	dd._Filter = dojo.extend(function(token){
+		// summary: Uses a string to find (and manipulate) a variable
+		if(!token) throw new Error("Filter must be called with variable name");
+		this.contents = token;
+
+		var cache = this._cache[token];
+		if(cache){
+			this.key = cache[0];
+			this.filters = cache[1];
+		}else{
+			this.filters = [];
+			dojox.string.tokenize(token, this._re, this._tokenize, this);
+			this._cache[token] = [this.key, this.filters];
+		}
+	},
+	{
+		_cache: {},
+		_re: /(?:^_\("([^\\"]*(?:\\.[^\\"])*)"\)|^"([^\\"]*(?:\\.[^\\"]*)*)"|^([a-zA-Z0-9_.]+)|\|(\w+)(?::(?:_\("([^\\"]*(?:\\.[^\\"])*)"\)|"([^\\"]*(?:\\.[^\\"]*)*)"|([a-zA-Z0-9_.]+)|'([^\\']*(?:\\.[^\\']*)*)'))?|^'([^\\']*(?:\\.[^\\']*)*)')/g,
+		_values: {
+			0: '"', // _("text")
+			1: '"', // "text"
+			2: "", // variable
+			8: '"' // 'text'
+		},
+		_args: {
+			4: '"', // :_("text")
+			5: '"', // :"text"
+			6: "", // :variable
+			7: "'"// :'text'
+		},
+		_tokenize: function(){
+			var pos, arg;
+
+			for(var i = 0, has = []; i < arguments.length; i++){
+				has[i] = (typeof arguments[i] != "undefined" && typeof arguments[i] == "string" && arguments[i]);
+			}
+
+			if(!this.key){
+				for(pos in this._values){
+					if(has[pos]){
+						this.key = this._values[pos] + arguments[pos] + this._values[pos];
+						break;
+					}
+				}
+			}else{
+				for(pos in this._args){
+					if(has[pos]){
+						var value = arguments[pos];
+						if(this._args[pos] == "'"){
+							value = value.replace(/\\'/g, "'");
+						}else if(this._args[pos] == '"'){
+							value = value.replace(/\\"/g, '"');
+						}
+						arg = [!this._args[pos], value];
+						break;
+					}
+				}
+				// Get a named filter
+				var fn = ddt.getFilter(arguments[3]);
+				if(!dojo.isFunction(fn)) throw new Error(arguments[3] + " is not registered as a filter");
+				this.filters.push([fn, arg]);
+			}
+		},
+		getExpression: function(){
+			return this.contents;
+		},
+		resolve: function(context){
+			if(typeof this.key == "undefined"){
+				return "";
+			}
+
+			var str = this.resolvePath(this.key, context);
+
+			for(var i = 0, filter; filter = this.filters[i]; i++){
+				// Each filter has the function in [0], a boolean in [1][0] of whether it's a variable or a string
+				// and [1][1] is either the variable name of the string content.
+				if(filter[1]){
+					if(filter[1][0]){
+						str = filter[0](str, this.resolvePath(filter[1][1], context));
+					}else{
+						str = filter[0](str, filter[1][1]);
+					}
+				}else{
+					str = filter[0](str);
+				}
+			}
+
+			return str;
+		},
+		resolvePath: function(path, context){
+			var current, parts;
+			var first = path.charAt(0);
+			var last = path.slice(-1);
+			if(!isNaN(parseInt(first))){
+				current = (path.indexOf(".") == -1) ? parseInt(path) : parseFloat(path);
+			}else if(first == '"' && first == last){
+				current = path.slice(1, -1);
+			}else{
+				if(path == "true"){ return true; }
+				if(path == "false"){ return false; }
+				if(path == "null" || path == "None"){ return null; }
+				parts = path.split(".");
+				current = context.get(parts[0]);
+
+				if(dojo.isFunction(current)){
+					var self = context.getThis && context.getThis();
+					if(current.alters_data){
+						current = "";
+					}else if(self){
+						current = current.call(self);
+					}else{
+						current = "";
+					}
+				}
+
+				for(var i = 1; i < parts.length; i++){
+					var part = parts[i];
+					if(current){
+						var base = current;
+						if(dojo.isObject(current) && part == "items" && typeof current[part] == "undefined"){
+							var items = [];
+							for(var key in current){
+								items.push([key, current[key]]);
+							}
+							current = items;
+							continue;
+						}
+
+						if(current.get && dojo.isFunction(current.get) && current.get.safe){
+							current = current.get(part);
+						}else if(typeof current[part] == "undefined"){
+							current = current[part];
+							break;
+						}else{
+							current = current[part];
+						}
+
+						if(dojo.isFunction(current)){
+							if(current.alters_data){
+								current = "";
+							}else{
+								current = current.call(base);
+							}
+						}else if(current instanceof Date){
+							current = dd._Context.prototype._normalize(current);
+						}
+					}else{
+						return "";
+					}
+				}
+			}
+			return current;
+		}
+	});
+
+	dd._TextNode = dd._Node = dojo.extend(function(/*Object*/ obj){
+		// summary: Basic catch-all node
+		this.contents = obj;
+	},
+	{
+		set: function(data){
+			this.contents = data;
+			return this;
+		},
+		render: function(context, buffer){
+			// summary: Adds content onto the buffer
+			return buffer.concat(this.contents);
+		},
+		isEmpty: function(){
+			return !dojo.trim(this.contents);
+		},
+		clone: function(){ return this; }
+	});
+
+	dd._NodeList = dojo.extend(function(/*Node[]*/ nodes){
+		// summary: Allows us to render a group of nodes
+		this.contents = nodes || [];
+		this.last = "";
+	},
+	{
+		push: function(node){
+			// summary: Add a new node to the list
+			this.contents.push(node);
+			return this;
+		},
+		concat: function(nodes){
+			this.contents = this.contents.concat(nodes);
+			return this;
+		},
+		render: function(context, buffer){
+			// summary: Adds all content onto the buffer
+			for(var i = 0; i < this.contents.length; i++){
+				buffer = this.contents[i].render(context, buffer);
+				if(!buffer) throw new Error("Template must return buffer");
+			}
+			return buffer;
+		},
+		dummyRender: function(context){
+			return this.render(context, dd.Template.prototype.getBuffer()).toString();
+		},
+		unrender: function(){ return arguments[1]; },
+		clone: function(){ return this; },
+		rtrim: function(){
+			while(1){
+				i = this.contents.length - 1;
+				if(this.contents[i] instanceof dd._TextNode && this.contents[i].isEmpty()){
+					this.contents.pop();
+				}else{
+					break;
+				}
+			}
+
+			return this;
+		}
+	});
+
+	dd._VarNode = dojo.extend(function(str){
+		// summary: A node to be processed as a variable
+		this.contents = new dd._Filter(str);
+	},
+	{
+		render: function(context, buffer){
+			var str = this.contents.resolve(context);
+			if(!str.safe){
+				str = dd._base.escape("" + str);
+			}
+			return buffer.concat(str);
+		}
+	});
+
+	dd._noOpNode = new function(){
+		// summary: Adds a no-op node. Useful in custom tags
+		this.render = this.unrender = function(){ return arguments[1]; }
+		this.clone = function(){ return this; }
+	}
+
+	dd._Parser = dojo.extend(function(tokens){
+		// summary: Parser used during initialization and for tag groups.
+		this.contents = tokens;
+	},
+	{
+		i: 0,
+		parse: function(/*Array?*/ stop_at){
+			// summary: Turns tokens into nodes
+			// description: Steps into tags are they're found. Blocks use the parse object
+			//		to find their closing tag (the stop_at array). stop_at is inclusive, it
+			//		returns the node that matched.
+			var terminators = {};
+			stop_at = stop_at || [];
+			for(var i = 0; i < stop_at.length; i++){
+				terminators[stop_at[i]] = true;
+			}
+
+			var nodelist = new dd._NodeList();
+			while(this.i < this.contents.length){
+				token = this.contents[this.i++];
+				if(typeof token == "string"){
+					nodelist.push(new dd._TextNode(token));
+				}else{
+					var type = token[0];
+					var text = token[1];
+					if(type == dd.TOKEN_VAR){
+						nodelist.push(new dd._VarNode(text));
+					}else if(type == dd.TOKEN_BLOCK){
+						if(terminators[text]){
+							--this.i;
+							return nodelist;
+						}
+						var cmd = text.split(/\s+/g);
+						if(cmd.length){
+							cmd = cmd[0];
+							var fn = ddt.getTag(cmd);
+							if(fn){
+								nodelist.push(fn(this, new dd.Token(type, text)));
+							}
+						}
+					}
+				}
+			}
+
+			if(stop_at.length){
+				throw new Error("Could not find closing tag(s): " + stop_at.toString());
+			}
+
+			this.contents.length = 0;
+			return nodelist;
+		},
+		next_token: function(){
+			// summary: Returns the next token in the list.
+			var token = this.contents[this.i++];
+			return new dd.Token(token[0], token[1]);
+		},
+		delete_first_token: function(){
+			this.i++;
+		},
+		skip_past: function(endtag){
+			while(this.i < this.contents.length){
+				var token = this.contents[this.i++];
+				if(token[0] == dd.TOKEN_BLOCK && token[1] == endtag){
+					return;
+				}
+			}
+			throw new Error("Unclosed tag found when looking for " + endtag);
+		},
+		create_variable_node: function(expr){
+			return new dd._VarNode(expr);
+		},
+		create_text_node: function(expr){
+			return new dd._TextNode(expr || "");
+		},
+		getTemplate: function(file){
+			return new dd.Template(file);
+		}
+	});
+
+	dd.register = {
+		_registry: {
+			attributes: [],
+			tags: [],
+			filters: []
+		},
+		get: function(/*String*/ module, /*String*/ name){
+			var registry = dd.register._registry[module + "s"];
+			for(var i = 0, entry; entry = registry[i]; i++){
+				if(typeof entry[0] == "string"){
+					if(entry[0] == name){
+						return entry;
+					}
+				}else if(name.match(entry[0])){
+					return entry;
+				}
+			}
+		},
+		getAttributeTags: function(){
+			var tags = [];
+			var registry = dd.register._registry.attributes;
+			for(var i = 0, entry; entry = registry[i]; i++){
+				if(entry.length == 3){
+					tags.push(entry);
+				}else{
+					var fn = dojo.getObject(entry[1]);
+					if(fn && dojo.isFunction(fn)){
+						entry.push(fn);
+						tags.push(entry);
+					}
+				}
+			}
+			return tags;
+		},
+		_any: function(type, base, locations){
+			for(var path in locations){
+				for(var i = 0, fn; fn = locations[path][i]; i++){
+					var key = fn;
+					if(dojo.isArray(fn)){
+						key = fn[0];
+						fn = fn[1];
+					}
+					if(typeof key == "string"){
+						if(key.substr(0, 5) == "attr:"){
+							var attr = fn;
+							if(attr.substr(0, 5) == "attr:"){
+								attr = attr.slice(5);
+							}
+							dd.register._registry.attributes.push([attr.toLowerCase(), base + "." + path + "." + attr]);
+						}
+						key = key.toLowerCase();
+					}
+					dd.register._registry[type].push([
+						key,
+						fn,
+						base + "." + path
+					]);
+				}
+			}
+		},
+		tags: function(/*String*/ base, /*Object*/ locations){
+			dd.register._any("tags", base, locations);
+		},
+		filters: function(/*String*/ base, /*Object*/ locations){
+			dd.register._any("filters", base, locations);
+		}
+	}
+
+	var escapeamp = /&/g;
+	var escapelt = /</g;
+	var escapegt = />/g;
+	var escapeqt = /'/g;
+	var escapedblqt = /"/g;
+	dd._base.escape = function(value){
+		// summary: Escapes a string's HTML
+		return dd.mark_safe(value.replace(escapeamp, '&').replace(escapelt, '<').replace(escapegt, '>').replace(escapedblqt, '"').replace(escapeqt, '''));
+	}
+
+	dd._base.safe = function(value){
+		if(typeof value == "string"){
+			value = new String(value);
+		}
+		if(typeof value == "object"){
+			value.safe = true;
+		}
+		return value;
+	}
+	dd.mark_safe = dd._base.safe;
+
+	dd.register.tags("dojox.dtl.tag", {
+		"date": ["now"],
+		"logic": ["if", "for", "ifequal", "ifnotequal"],
+		"loader": ["extends", "block", "include", "load", "ssi"],
+		"misc": ["comment", "debug", "filter", "firstof", "spaceless", "templatetag", "widthratio", "with"],
+		"loop": ["cycle", "ifchanged", "regroup"]
+	});
+	dd.register.filters("dojox.dtl.filter", {
+		"dates": ["date", "time", "timesince", "timeuntil"],
+		"htmlstrings": ["linebreaks", "linebreaksbr", "removetags", "striptags"],
+		"integers": ["add", "get_digit"],
+		"lists": ["dictsort", "dictsortreversed", "first", "join", "length", "length_is", "random", "slice", "unordered_list"],
+		"logic": ["default", "default_if_none", "divisibleby", "yesno"],
+		"misc": ["filesizeformat", "pluralize", "phone2numeric", "pprint"],
+		"strings": ["addslashes", "capfirst", "center", "cut", "fix_ampersands", "floatformat", "iriencode", "linenumbers", "ljust", "lower", "make_list", "rjust", "slugify", "stringformat", "title", "truncatewords", "truncatewords_html", "upper", "urlencode", "urlize", "urlizetrunc", "wordcount", "wordwrap"]
+	});
+	dd.register.filters("dojox.dtl", {
+		"_base": ["escape", "safe"]
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.dtl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.dtl"] = true;
+dojo.provide("dojox.dtl");
+
+
+}
+
+if(!dojo._hasResource["dojox.dtl.Context"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.dtl.Context"] = true;
+dojo.provide("dojox.dtl.Context");
+
+
+dojox.dtl.Context = dojo.extend(function(dict){
+	this._this = {};
+	dojox.dtl._Context.call(this, dict);
+}, dojox.dtl._Context.prototype,
+{
+	getKeys: function(){
+		var keys = [];
+		for(var key in this){
+			if(this.hasOwnProperty(key) && key != "_dicts" && key != "_this"){
+				keys.push(key);
+			}
+		}
+		return keys;
+	},
+	extend: function(/*dojox.dtl.Context|Object*/ obj){
+		// summary: Returns a clone of this context object, with the items from the
+		//		passed objecct mixed in.
+		return  dojo.delegate(this, obj);
+	},
+	filter: function(/*dojox.dtl.Context|Object|String...*/ filter){
+		// summary: Returns a clone of this context, only containing the items
+		//		defined in the filter.
+		var context = new dojox.dtl.Context();
+		var keys = [];
+		var i, arg;
+		if(filter instanceof dojox.dtl.Context){
+			keys = filter.getKeys();
+		}else if(typeof filter == "object"){
+			for(var key in filter){
+				keys.push(key);
+			}
+		}else{
+			for(i = 0; arg = arguments[i]; i++){
+				if(typeof arg == "string"){
+					keys.push(arg);
+				}
+			}
+		}
+
+		for(i = 0, key; key = keys[i]; i++){
+			context[key] = this[key];
+		}
+
+		return context;
+	},
+	setThis: function(/*Object*/ _this){
+		this._this = _this;
+	},
+	getThis: function(){
+		return this._this;
+	},
+	hasKey: function(key){
+		if(typeof this[key] != "undefined"){
+			return true;
+		}
+
+		for(var i = 0, dict; dict = this._dicts[i]; i++){
+			if(typeof dict[key] != "undefined"){
+				return true;
+			}
+		}
+
+		return false;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.dtl.tag.logic"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.dtl.tag.logic"] = true;
+dojo.provide("dojox.dtl.tag.logic");
+
+
+
+(function(){
+	var dd = dojox.dtl;
+	var ddt = dd.text;
+	var ddtl = dd.tag.logic;
+
+	ddtl.IfNode = dojo.extend(function(bools, trues, falses, type){
+		this.bools = bools;
+		this.trues = trues;
+		this.falses = falses;
+		this.type = type;
+	},
+	{
+		render: function(context, buffer){
+			var i, bool, ifnot, filter, value;
+			if(this.type == "or"){
+				for(i = 0; bool = this.bools[i]; i++){
+					ifnot = bool[0];
+					filter = bool[1];
+					value = filter.resolve(context);
+					if((value && !ifnot) || (ifnot && !value)){
+						if(this.falses){
+							buffer = this.falses.unrender(context, buffer);
+						}
+						return (this.trues) ? this.trues.render(context, buffer, this) : buffer;
+					}
+				}
+				if(this.trues){
+					buffer = this.trues.unrender(context, buffer);
+				}
+				return (this.falses) ? this.falses.render(context, buffer, this) : buffer;
+			}else{
+				for(i = 0; bool = this.bools[i]; i++){
+					ifnot = bool[0];
+					filter = bool[1];
+					value = filter.resolve(context);
+					// If we ever encounter a false value
+					if(value == ifnot){
+						if(this.trues){
+							buffer = this.trues.unrender(context, buffer);
+						}
+						return (this.falses) ? this.falses.render(context, buffer, this) : buffer;
+					}
+				}
+				if(this.falses){
+					buffer = this.falses.unrender(context, buffer);
+				}
+				return (this.trues) ? this.trues.render(context, buffer, this) : buffer;
+			}
+			return buffer;
+		},
+		unrender: function(context, buffer){
+			buffer = (this.trues) ? this.trues.unrender(context, buffer) : buffer;
+			buffer = (this.falses) ? this.falses.unrender(context, buffer) : buffer;
+			return buffer;
+		},
+		clone: function(buffer){
+			var trues = (this.trues) ? this.trues.clone(buffer) : null;
+			var falses = (this.falses) ? this.falses.clone(buffer) : null;
+			return new this.constructor(this.bools, trues, falses, this.type);
+		}
+	});
+
+	ddtl.IfEqualNode = dojo.extend(function(var1, var2, trues, falses, negate){
+		this.var1 = new dd._Filter(var1);
+		this.var2 = new dd._Filter(var2);
+		this.trues = trues;
+		this.falses = falses;
+		this.negate = negate;
+	},
+	{
+		render: function(context, buffer){
+			var var1 = this.var1.resolve(context);
+			var var2 = this.var2.resolve(context);
+			var1 = (typeof var1 != "undefined") ? var1 : "";
+			var2 = (typeof var1 != "undefined") ? var2 : "";
+			if((this.negate && var1 != var2) || (!this.negate && var1 == var2)){
+				if(this.falses){
+					buffer = this.falses.unrender(context, buffer, this);
+				}
+				return (this.trues) ? this.trues.render(context, buffer, this) : buffer;
+			}
+			if(this.trues){
+				buffer = this.trues.unrender(context, buffer, this);
+			}
+			return (this.falses) ? this.falses.render(context, buffer, this) : buffer;
+		},
+		unrender: function(context, buffer){
+			return ddtl.IfNode.prototype.unrender.call(this, context, buffer);
+		},
+		clone: function(buffer){
+			var trues = this.trues ? this.trues.clone(buffer) : null;
+			var falses = this.falses ? this.falses.clone(buffer) : null;
+			return new this.constructor(this.var1.getExpression(), this.var2.getExpression(), trues, falses, this.negate);
+		}
+	});
+
+	ddtl.ForNode = dojo.extend(function(assign, loop, reversed, nodelist){
+		this.assign = assign;
+		this.loop = new dd._Filter(loop);
+		this.reversed = reversed;
+		this.nodelist = nodelist;
+		this.pool = [];
+	},
+	{
+		render: function(context, buffer){
+			var i, j, k;
+			var dirty = false;
+			var assign = this.assign;
+
+			for(k = 0; k < assign.length; k++){
+				if(typeof context[assign[k]] != "undefined"){
+					dirty = true;
+					context = context.push();
+					break;
+				}
+			}
+			if(!dirty && context.forloop){
+				dirty = true;
+				context = context.push();
+			}
+
+			var items = this.loop.resolve(context) || [];
+			for(i = items.length; i < this.pool.length; i++){
+				this.pool[i].unrender(context, buffer, this);
+			}
+			if(this.reversed){
+				items = items.slice(0).reverse();
+			}
+
+			var isObject = dojo.isObject(items) && !dojo.isArrayLike(items);
+			var arred = [];
+			if(isObject){
+				for(var key in items){
+					arred.push(items[key]);
+				}
+			}else{
+				arred = items;
+			}
+
+			var forloop = context.forloop = {
+				parentloop: context.get("forloop", {})
+			};
+			var j = 0;
+			for(i = 0; i < arred.length; i++){
+				var item = arred[i];
+
+				forloop.counter0 = j;
+				forloop.counter = j + 1;
+				forloop.revcounter0 = arred.length - j - 1;
+				forloop.revcounter = arred.length - j;
+				forloop.first = !j;
+				forloop.last = (j == arred.length - 1);
+
+				if(assign.length > 1 && dojo.isArrayLike(item)){
+					if(!dirty){
+						dirty = true;
+						context = context.push();
+					}
+					var zipped = {};
+					for(k = 0; k < item.length && k < assign.length; k++){
+						zipped[assign[k]] = item[k];
+					}
+					dojo.mixin(context, zipped);
+				}else{
+					context[assign[0]] = item;
+				}
+
+				if(j + 1 > this.pool.length){
+					this.pool.push(this.nodelist.clone(buffer));
+				}
+				buffer = this.pool[j++].render(context, buffer, this);
+			}
+
+			delete context.forloop;
+			if(dirty){
+				context = context.pop();
+			}else{
+				for(k = 0; k < assign.length; k++){
+					delete context[assign[k]];
+				}
+			}
+			return buffer;
+		},
+		unrender: function(context, buffer){
+			for(var i = 0, pool; pool = this.pool[i]; i++){
+				buffer = pool.unrender(context, buffer);
+			}
+			return buffer;
+		},
+		clone: function(buffer){
+			return new this.constructor(this.assign, this.loop.getExpression(), this.reversed, this.nodelist.clone(buffer));
+		}
+	});
+
+	dojo.mixin(ddtl, {
+		if_: function(parser, token){
+			var i, part, type, bools = [], parts = token.contents.split();
+			parts.shift();
+			token = parts.join(" ");
+			parts = token.split(" and ");
+			if(parts.length == 1){
+				type = "or";
+				parts = token.split(" or ");
+			}else{
+				type = "and";
+				for(i = 0; i < parts.length; i++){
+					if(parts[i].indexOf(" or ") != -1){
+						// Note, since we split by and, this is the only place we need to error check
+						throw new Error("'if' tags can't mix 'and' and 'or'");
+					}
+				}
+			}
+			for(i = 0; part = parts[i]; i++){
+				var not = false;
+				if(part.indexOf("not ") == 0){
+					part = part.slice(4);
+					not = true;
+				}
+				bools.push([not, new dd._Filter(part)]);
+			}
+			var trues = parser.parse(["else", "endif"]);
+			var falses = false;
+			var token = parser.next_token();
+			if(token.contents == "else"){
+				falses = parser.parse(["endif"]);
+				parser.next_token();
+			}
+			return new ddtl.IfNode(bools, trues, falses, type);
+		},
+		_ifequal: function(parser, token, negate){
+			var parts = token.split_contents();
+			if(parts.length != 3){
+				throw new Error(parts[0] + " takes two arguments");
+			}
+			var end = 'end' + parts[0];
+			var trues = parser.parse(["else", end]);
+			var falses = false;
+			var token = parser.next_token();
+			if(token.contents == "else"){
+				falses = parser.parse([end]);
+				parser.next_token();
+			}
+			return new ddtl.IfEqualNode(parts[1], parts[2], trues, falses, negate);
+		},
+		ifequal: function(parser, token){
+			return ddtl._ifequal(parser, token);
+		},
+		ifnotequal: function(parser, token){
+			return ddtl._ifequal(parser, token, true);
+		},
+		for_: function(parser, token){
+			var parts = token.contents.split();
+			if(parts.length < 4){
+				throw new Error("'for' statements should have at least four words: " + token.contents);
+			}
+			var reversed = parts[parts.length - 1] == "reversed";
+			var index = (reversed) ? -3 : -2;
+			if(parts[parts.length + index] != "in"){
+				throw new Error("'for' tag received an invalid argument: " + token.contents);
+			}
+			var loopvars = parts.slice(1, index).join(" ").split(/ *, */);
+			for(var i = 0; i < loopvars.length; i++){
+				if(!loopvars[i] || loopvars[i].indexOf(" ") != -1){
+					throw new Error("'for' tag received an invalid argument: " + token.contents);
+				}
+			}
+			var nodelist = parser.parse(["endfor"]);
+			parser.next_token();
+			return new ddtl.ForNode(loopvars, parts[parts.length + index + 1], reversed, nodelist);
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.dtl.tag.loop"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.dtl.tag.loop"] = true;
+dojo.provide("dojox.dtl.tag.loop");
+
+
+
+
+(function(){
+	var dd = dojox.dtl;
+	var ddtl = dd.tag.loop;
+
+	ddtl.CycleNode = dojo.extend(function(cyclevars, name, text, shared){
+		this.cyclevars = cyclevars;
+		this.name = name;
+		this.contents = text;
+		this.shared = shared || {counter: -1, map: {}};
+	},
+	{
+		render: function(context, buffer){
+			if(context.forloop && !context.forloop.counter0){
+				this.shared.counter = -1;
+			}
+
+			++this.shared.counter;
+			var value = this.cyclevars[this.shared.counter % this.cyclevars.length];
+
+			var map = this.shared.map;
+			if(!map[value]){
+				map[value] = new dd._Filter(value);
+			}
+			value = map[value].resolve(context, buffer);
+
+			if(this.name){
+				context[this.name] = value;
+			}
+			this.contents.set(value);
+			return this.contents.render(context, buffer);
+		},
+		unrender: function(context, buffer){
+			return this.contents.unrender(context, buffer);
+		},
+		clone: function(buffer){
+			return new this.constructor(this.cyclevars, this.name, this.contents.clone(buffer), this.shared);
+		}
+	});
+
+	ddtl.IfChangedNode = dojo.extend(function(nodes, vars, shared){
+		this.nodes = nodes;
+		this._vars = vars;
+		this.shared = shared || {last: null, counter: 0};
+		this.vars = dojo.map(vars, function(item){
+			return new dojox.dtl._Filter(item);
+		});
+	}, {
+		render: function(context, buffer){
+			if(context.forloop){
+				if(context.forloop.counter <= this.shared.counter){
+					this.shared.last = null;
+				}
+				this.shared.counter = context.forloop.counter;
+			}
+
+			var change;
+			if(this.vars.length){
+				change = dojo.toJson(dojo.map(this.vars, function(item){
+					return item.resolve(context);
+				}));
+			}else{
+				change = this.nodes.dummyRender(context, buffer);
+			}
+
+			if(change != this.shared.last){
+				var firstloop = (this.shared.last === null);
+				this.shared.last = change;
+				context = context.push();
+				context.ifchanged = {firstloop: firstloop};
+				buffer = this.nodes.render(context, buffer);
+				context = context.pop();
+			}else{
+				buffer = this.nodes.unrender(context, buffer);
+			}
+			return buffer;
+		},
+		unrender: function(context, buffer){
+			return this.nodes.unrender(context, buffer);
+		},
+		clone: function(buffer){
+			return new this.constructor(this.nodes.clone(buffer), this._vars, this.shared);
+		}
+	});
+
+	ddtl.RegroupNode = dojo.extend(function(expression, key, alias){
+		this._expression = expression;
+		this.expression = new dd._Filter(expression);
+		this.key = key;
+		this.alias = alias;
+	},
+	{
+		_push: function(container, grouper, stack){
+			if(stack.length){
+				container.push({ grouper: grouper, list: stack });
+			}
+		},
+		render: function(context, buffer){
+			context[this.alias] = [];
+			var list = this.expression.resolve(context);
+			if(list){
+				var last = null;
+				var stack = [];
+				for(var i = 0; i < list.length; i++){
+					var id = list[i][this.key];
+					if(last !== id){
+						this._push(context[this.alias], last, stack);
+						last = id;
+						stack = [list[i]];
+					}else{
+						stack.push(list[i]);
+					}
+				}
+				this._push(context[this.alias], last, stack);
+			}
+			return buffer;
+		},
+		unrender: function(context, buffer){
+			return buffer;
+		},
+		clone: function(context, buffer){
+			return this;
+		}
+	});
+
+	dojo.mixin(ddtl, {
+		cycle: function(parser, token){
+			// summary: Cycle among the given strings each time this tag is encountered
+			var args = token.split_contents();
+
+			if(args.length < 2){
+				throw new Error("'cycle' tag requires at least two arguments");
+			}
+
+			if(args[1].indexOf(",") != -1){
+				var vars = args[1].split(",");
+				args = [args[0]];
+				for(var i = 0; i < vars.length; i++){
+					args.push('"' + vars[i] + '"');
+				}
+			}
+
+			if(args.length == 2){
+				var name = args[args.length - 1];
+
+				if(!parser._namedCycleNodes){
+					throw new Error("No named cycles in template: '" + name + "' is not defined");
+				}
+				if(!parser._namedCycleNodes[name]){
+					throw new Error("Named cycle '" + name + "' does not exist");
+				}
+
+		        return parser._namedCycleNodes[name];
+			}
+
+			if(args.length > 4 && args[args.length - 2] == "as"){
+				var name = args[args.length - 1];
+
+				var node = new ddtl.CycleNode(args.slice(1, args.length - 2), name, parser.create_text_node());
+
+				if(!parser._namedCycleNodes){
+					parser._namedCycleNodes = {};
+				}
+				parser._namedCycleNodes[name] = node;
+			}else{
+				node = new ddtl.CycleNode(args.slice(1), null, parser.create_text_node());
+			}
+
+			return node;
+		},
+		ifchanged: function(parser, token){
+			var parts = token.contents.split();
+			var nodes = parser.parse(["endifchanged"]);
+			parser.delete_first_token();
+			return new ddtl.IfChangedNode(nodes, parts.slice(1));
+		},
+		regroup: function(parser, token){
+			var tokens = dojox.string.tokenize(token.contents, /(\s+)/g, function(spaces){
+				return spaces;
+			});
+			if(tokens.length < 11 || tokens[tokens.length - 3] != "as" || tokens[tokens.length - 7] != "by"){
+				throw new Error("Expected the format: regroup list by key as newList");
+			}
+			var expression = tokens.slice(2, -8).join("");
+			var key = tokens[tokens.length - 5];
+			var alias = tokens[tokens.length - 1];
+			return new ddtl.RegroupNode(expression, key, alias);
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojo.date"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.date"] = true;
+dojo.provide("dojo.date");
+
+/*=====
+dojo.date = {
+	// summary: Date manipulation utilities
+}
+=====*/
+
+dojo.date.getDaysInMonth = function(/*Date*/dateObject){
+	//	summary:
+	//		Returns the number of days in the month used by dateObject
+	var month = dateObject.getMonth();
+	var days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+	if(month == 1 && dojo.date.isLeapYear(dateObject)){ return 29; } // Number
+	return days[month]; // Number
+}
+
+dojo.date.isLeapYear = function(/*Date*/dateObject){
+	//	summary:
+	//		Determines if the year of the dateObject is a leap year
+	//	description:
+	//		Leap years are years with an additional day YYYY-02-29, where the
+	//		year number is a multiple of four with the following exception: If
+	//		a year is a multiple of 100, then it is only a leap year if it is
+	//		also a multiple of 400. For example, 1900 was not a leap year, but
+	//		2000 is one.
+
+	var year = dateObject.getFullYear();
+	return !(year%400) || (!(year%4) && !!(year%100)); // Boolean
+}
+
+// FIXME: This is not localized
+dojo.date.getTimezoneName = function(/*Date*/dateObject){
+	//	summary:
+	//		Get the user's time zone as provided by the browser
+	// dateObject:
+	//		Needed because the timezone may vary with time (daylight savings)
+	//	description:
+	//		Try to get time zone info from toString or toLocaleString method of
+	//		the Date object -- UTC offset is not a time zone.  See
+	//		http://www.twinsun.com/tz/tz-link.htm Note: results may be
+	//		inconsistent across browsers.
+
+	var str = dateObject.toString(); // Start looking in toString
+	var tz = ''; // The result -- return empty string if nothing found
+	var match;
+
+	// First look for something in parentheses -- fast lookup, no regex
+	var pos = str.indexOf('(');
+	if(pos > -1){
+		tz = str.substring(++pos, str.indexOf(')'));
+	}else{
+		// If at first you don't succeed ...
+		// If IE knows about the TZ, it appears before the year
+		// Capital letters or slash before a 4-digit year 
+		// at the end of string
+		var pat = /([A-Z\/]+) \d{4}$/;
+		if((match = str.match(pat))){
+			tz = match[1];
+		}else{
+		// Some browsers (e.g. Safari) glue the TZ on the end
+		// of toLocaleString instead of putting it in toString
+			str = dateObject.toLocaleString();
+			// Capital letters or slash -- end of string, 
+			// after space
+			pat = / ([A-Z\/]+)$/;
+			if((match = str.match(pat))){
+				tz = match[1];
+			}
+		}
+	}
+
+	// Make sure it doesn't somehow end up return AM or PM
+	return (tz == 'AM' || tz == 'PM') ? '' : tz; // String
+}
+
+// Utility methods to do arithmetic calculations with Dates
+
+dojo.date.compare = function(/*Date*/date1, /*Date?*/date2, /*String?*/portion){
+	//	summary:
+	//		Compare two date objects by date, time, or both.
+	//	description:
+	//  	Returns 0 if equal, positive if a > b, else negative.
+	//	date1:
+	//		Date object
+	//	date2:
+	//		Date object.  If not specified, the current Date is used.
+	//	portion:
+	//		A string indicating the "date" or "time" portion of a Date object.
+	//		Compares both "date" and "time" by default.  One of the following:
+	//		"date", "time", "datetime"
+
+	// Extra step required in copy for IE - see #3112
+	date1 = new Date(Number(date1));
+	date2 = new Date(Number(date2 || new Date()));
+
+	if(portion !== "undefined"){
+		if(portion == "date"){
+			// Ignore times and compare dates.
+			date1.setHours(0, 0, 0, 0);
+			date2.setHours(0, 0, 0, 0);
+		}else if(portion == "time"){
+			// Ignore dates and compare times.
+			date1.setFullYear(0, 0, 0);
+			date2.setFullYear(0, 0, 0);
+		}
+	}
+	
+	if(date1 > date2){ return 1; } // int
+	if(date1 < date2){ return -1; } // int
+	return 0; // int
+};
+
+dojo.date.add = function(/*Date*/date, /*String*/interval, /*int*/amount){
+	//	summary:
+	//		Add to a Date in intervals of different size, from milliseconds to years
+	//	date: Date
+	//		Date object to start with
+	//	interval:
+	//		A string representing the interval.  One of the following:
+	//			"year", "month", "day", "hour", "minute", "second",
+	//			"millisecond", "quarter", "week", "weekday"
+	//	amount:
+	//		How much to add to the date.
+
+	var sum = new Date(Number(date)); // convert to Number before copying to accomodate IE (#3112)
+	var fixOvershoot = false;
+	var property = "Date";
+
+	switch(interval){
+		case "day":
+			break;
+		case "weekday":
+			//i18n FIXME: assumes Saturday/Sunday weekend, but this is not always true.  see dojo.cldr.supplemental
+
+			// Divide the increment time span into weekspans plus leftover days
+			// e.g., 8 days is one 5-day weekspan / and two leftover days
+			// Can't have zero leftover days, so numbers divisible by 5 get
+			// a days value of 5, and the remaining days make up the number of weeks
+			var days, weeks;
+			var mod = amount % 5;
+			if(!mod){
+				days = (amount > 0) ? 5 : -5;
+				weeks = (amount > 0) ? ((amount-5)/5) : ((amount+5)/5);
+			}else{
+				days = mod;
+				weeks = parseInt(amount/5);
+			}
+			// Get weekday value for orig date param
+			var strt = date.getDay();
+			// Orig date is Sat / positive incrementer
+			// Jump over Sun
+			var adj = 0;
+			if(strt == 6 && amount > 0){
+				adj = 1;
+			}else if(strt == 0 && amount < 0){
+			// Orig date is Sun / negative incrementer
+			// Jump back over Sat
+				adj = -1;
+			}
+			// Get weekday val for the new date
+			var trgt = strt + days;
+			// New date is on Sat or Sun
+			if(trgt == 0 || trgt == 6){
+				adj = (amount > 0) ? 2 : -2;
+			}
+			// Increment by number of weeks plus leftover days plus
+			// weekend adjustments
+			amount = (7 * weeks) + days + adj;
+			break;
+		case "year":
+			property = "FullYear";
+			// Keep increment/decrement from 2/29 out of March
+			fixOvershoot = true;
+			break;
+		case "week":
+			amount *= 7;
+			break;
+		case "quarter":
+			// Naive quarter is just three months
+			amount *= 3;
+			// fallthrough...
+		case "month":
+			// Reset to last day of month if you overshoot
+			fixOvershoot = true;
+			property = "Month";
+			break;
+		case "hour":
+		case "minute":
+		case "second":
+		case "millisecond":
+			property = "UTC"+interval.charAt(0).toUpperCase() + interval.substring(1) + "s";
+	}
+
+	if(property){
+		sum["set"+property](sum["get"+property]()+amount);
+	}
+
+	if(fixOvershoot && (sum.getDate() < date.getDate())){
+		sum.setDate(0);
+	}
+
+	return sum; // Date
+};
+
+dojo.date.difference = function(/*Date*/date1, /*Date?*/date2, /*String?*/interval){
+	//	summary:
+	//		Get the difference in a specific unit of time (e.g., number of
+	//		months, weeks, days, etc.) between two dates, rounded to the
+	//		nearest integer.
+	//	date1:
+	//		Date object
+	//	date2:
+	//		Date object.  If not specified, the current Date is used.
+	//	interval:
+	//		A string representing the interval.  One of the following:
+	//			"year", "month", "day", "hour", "minute", "second",
+	//			"millisecond", "quarter", "week", "weekday"
+	//		Defaults to "day".
+
+	date2 = date2 || new Date();
+	interval = interval || "day";
+	var yearDiff = date2.getFullYear() - date1.getFullYear();
+	var delta = 1; // Integer return value
+
+	switch(interval){
+		case "quarter":
+			var m1 = date1.getMonth();
+			var m2 = date2.getMonth();
+			// Figure out which quarter the months are in
+			var q1 = Math.floor(m1/3) + 1;
+			var q2 = Math.floor(m2/3) + 1;
+			// Add quarters for any year difference between the dates
+			q2 += (yearDiff * 4);
+			delta = q2 - q1;
+			break;
+		case "weekday":
+			var days = Math.round(dojo.date.difference(date1, date2, "day"));
+			var weeks = parseInt(dojo.date.difference(date1, date2, "week"));
+			var mod = days % 7;
+
+			// Even number of weeks
+			if(mod == 0){
+				days = weeks*5;
+			}else{
+				// Weeks plus spare change (< 7 days)
+				var adj = 0;
+				var aDay = date1.getDay();
+				var bDay = date2.getDay();
+
+				weeks = parseInt(days/7);
+				mod = days % 7;
+				// Mark the date advanced by the number of
+				// round weeks (may be zero)
+				var dtMark = new Date(date1);
+				dtMark.setDate(dtMark.getDate()+(weeks*7));
+				var dayMark = dtMark.getDay();
+
+				// Spare change days -- 6 or less
+				if(days > 0){
+					switch(true){
+						// Range starts on Sat
+						case aDay == 6:
+							adj = -1;
+							break;
+						// Range starts on Sun
+						case aDay == 0:
+							adj = 0;
+							break;
+						// Range ends on Sat
+						case bDay == 6:
+							adj = -1;
+							break;
+						// Range ends on Sun
+						case bDay == 0:
+							adj = -2;
+							break;
+						// Range contains weekend
+						case (dayMark + mod) > 5:
+							adj = -2;
+					}
+				}else if(days < 0){
+					switch(true){
+						// Range starts on Sat
+						case aDay == 6:
+							adj = 0;
+							break;
+						// Range starts on Sun
+						case aDay == 0:
+							adj = 1;
+							break;
+						// Range ends on Sat
+						case bDay == 6:
+							adj = 2;
+							break;
+						// Range ends on Sun
+						case bDay == 0:
+							adj = 1;
+							break;
+						// Range contains weekend
+						case (dayMark + mod) < 0:
+							adj = 2;
+					}
+				}
+				days += adj;
+				days -= (weeks*2);
+			}
+			delta = days;
+			break;
+		case "year":
+			delta = yearDiff;
+			break;
+		case "month":
+			delta = (date2.getMonth() - date1.getMonth()) + (yearDiff * 12);
+			break;
+		case "week":
+			// Truncate instead of rounding
+			// Don't use Math.floor -- value may be negative
+			delta = parseInt(dojo.date.difference(date1, date2, "day")/7);
+			break;
+		case "day":
+			delta /= 24;
+			// fallthrough
+		case "hour":
+			delta /= 60;
+			// fallthrough
+		case "minute":
+			delta /= 60;
+			// fallthrough
+		case "second":
+			delta /= 1000;
+			// fallthrough
+		case "millisecond":
+			delta *= date2.getTime() - date1.getTime();
+	}
+
+	// Round for fractional values and DST leaps
+	return Math.round(delta); // Number (integer)
+};
+
+}
+
+if(!dojo._hasResource["dojox.date.php"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.date.php"] = true;
+dojo.provide("dojox.date.php");
+
+
+
+dojox.date.php.format = function(/*Date*/ date, /*String*/ format){
+	// summary: Get a formatted string for a given date object
+	var df = new dojox.date.php.DateFormat(format);
+	return df.format(date);	
+}
+
+dojox.date.php.DateFormat = function(/*String*/ format){
+	// summary: Format the internal date object
+	if(!this.regex){
+		var keys = [];
+		for(var key in this.constructor.prototype){
+			if(dojo.isString(key) && key.length == 1 && dojo.isFunction(this[key])){
+				keys.push(key);
+			}
+		}
+		this.constructor.prototype.regex = new RegExp("(?:(\\\\.)|([" + keys.join("") + "]))", "g");
+	}
+
+	var replacements = [];
+
+	this.tokens = dojox.string.tokenize(format, this.regex, function(escape, token, i){
+		if(token){
+			replacements.push([i, token]);
+			return token;
+		}
+		if(escape){
+			return escape.charAt(1);
+		}
+	});
+
+	this.replacements = replacements;
+}
+dojo.extend(dojox.date.php.DateFormat, {
+	weekdays: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
+	weekdays_3: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
+	months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
+	months_3: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
+	monthdays: [31,28,31,30,31,30,31,31,30,31,30,31],
+
+	format: function(/*Date*/ date){
+		this.date = date;
+		for(var i = 0, replacement; replacement = this.replacements[i]; i++){
+			this.tokens[replacement[0]] = this[replacement[1]]();
+		}
+		return this.tokens.join("");
+	},
+
+	// Day
+
+	d: function(){
+		// summary: Day of the month, 2 digits with leading zeros
+		var j = this.j();
+		return (j.length == 1) ? "0" + j : j;
+	},
+
+	D: function(){
+		// summary: A textual representation of a day, three letters
+		return this.weekdays_3[this.date.getDay()];
+	},
+
+	j: function(){
+		// summary: Day of the month without leading zeros
+		return this.date.getDate() + "";
+	},
+
+	l: function(){
+		// summary: A full textual representation of the day of the week
+		return this.weekdays[this.date.getDay()];
+	},
+	
+	N: function(){
+		// summary: ISO-8601 numeric representation of the day of the week (added in PHP 5.1.0)
+		var w = this.w();
+		return (!w) ? 7 : w;
+	},
+
+	S: function(){
+		// summary: English ordinal suffix for the day of the month, 2 characters
+		switch(this.date.getDate()){
+			case 11: case 12: case 13: return "th";
+			case 1: case 21: case 31: return "st";
+			case 2: case 22: return "nd";
+			case 3: case 23: return "rd";
+			default: return "th";
+		}
+	},
+
+	w: function(){
+		// summary: Numeric representation of the day of the week
+		return this.date.getDay() + "";
+	},
+
+	z: function(){
+		// summary: The day of the year (starting from 0)
+		var millis = this.date.getTime() - new Date(this.date.getFullYear(), 0, 1).getTime();
+		return Math.floor(millis/86400000) + "";
+	},
+
+	// Week
+
+	W: function(){
+		// summary: ISO-8601 week number of year, weeks starting on Monday (added in PHP 4.1.0)
+		var week;
+		var jan1_w = new Date(this.date.getFullYear(), 0, 1).getDay() + 1;
+		var w = this.date.getDay() + 1;
+		var z = parseInt(this.z());
+
+		if(z <= (8 - jan1_w) && jan1_w > 4){
+			var last_year = new Date(this.date.getFullYear() - 1, this.date.getMonth(), this.date.getDate());
+			if(jan1_w == 5 || (jan1_w == 6 && dojo.date.isLeapYear(last_year))){
+				week = 53;
+			}else{
+				week = 52;
+			}
+		}else{
+			var i;
+			if(Boolean(this.L())){
+				i = 366;
+			}else{
+				i = 365;
+			}
+			if((i - z) < (4 - w)){
+				week = 1;
+			}else{
+				var j = z + (7 - w) + (jan1_w - 1);
+				week = Math.ceil(j / 7);
+				if(jan1_w > 4){
+					--week;
+				}
+			}
+		}
+		
+		return week;
+	},
+
+	// Month
+
+	F: function(){
+		// summary: A full textual representation of a month, such as January or March
+		return this.months[this.date.getMonth()];
+	},
+
+	m: function(){
+		// summary: Numeric representation of a month, with leading zeros
+		var n = this.n();
+		return (n.length == 1) ? "0" + n : n;
+	},
+
+	M: function(){
+		// summary: A short textual representation of a month, three letters
+		return this.months_3[this.date.getMonth()];
+	},
+
+	n: function(){
+		// summary: Numeric representation of a month, without leading zeros
+		return this.date.getMonth() + 1 + "";
+	},
+
+	t: function(){
+		// summary: Number of days in the given month
+		return (Boolean(this.L()) && this.date.getMonth() == 1) ? 29 : this.monthdays[this.getMonth()];
+	},
+
+	// Year
+
+	L: function(){
+		// summary: Whether it's a leap year
+		return (dojo.date.isLeapYear(this.date)) ? "1" : "0";
+	},
+
+	o: function(){
+		// summary:
+		//		ISO-8601 year number. This has the same value as Y, except that if
+		//		the ISO week number (W) belongs to the previous or next year, that year is used instead. (added in PHP 5.1.0)
+		// TODO: Figure out what this means
+	},
+
+	Y: function(){
+		// summary: A full numeric representation of a year, 4 digits
+		return this.date.getFullYear() + "";
+	},
+
+	y: function(){
+		// summary: A two digit representation of a year
+		return this.Y().slice(-2);
+	},
+
+	// Time
+
+	a: function(){
+		// summary: Lowercase Ante meridiem and Post meridiem
+		return this.date.getHours() >= 12 ? "pm" : "am";
+	},
+
+	b: function(){
+		// summary: Uppercase Ante meridiem and Post meridiem
+		return this.a().toUpperCase();
+	},
+
+	B: function(){
+		// summary:
+		//	Swatch Internet time
+		//	A day is 1,000 beats. All time is measured from GMT + 1
+		var off = this.date.getTimezoneOffset() + 60;
+		var secs = (this.date.getHours() * 3600) + (this.date.getMinutes() * 60) + this.getSeconds() + (off * 60);
+		var beat = Math.abs(Math.floor(secs / 86.4) % 1000) + "";
+		while(beat.length <  2) beat = "0" + beat;
+		return beat;
+	},
+
+	g: function(){
+		// summary: 12-hour format of an hour without leading zeros
+		return (this.date.getHours() > 12) ? this.date.getHours() - 12 + "" : this.date.getHours() + "";
+	},
+
+	G: function(){
+		// summary: 24-hour format of an hour without leading zeros
+		return this.date.getHours() + "";
+	},
+
+	h: function(){
+		// summary: 12-hour format of an hour with leading zeros
+		var g = this.g();
+		return (g.length == 1) ? "0" + g : g;
+	},
+
+	H: function(){
+		// summary: 24-hour format of an hour with leading zeros
+		var G = this.G();
+		return (G.length == 1) ? "0" + G : G;
+	},
+
+	i: function(){
+		// summary: Minutes with leading zeros
+		var mins = this.date.getMinutes() + "";
+		return (mins.length == 1) ? "0" + mins : mins;
+	},
+
+	s: function(){
+		// summary: Seconds, with leading zeros
+		var secs = this.date.getSeconds() + "";
+		return (secs.length == 1) ? "0" + secs : secs;
+	},
+
+	// Timezone
+
+	e: function(){
+		// summary: Timezone identifier (added in PHP 5.1.0)
+		return dojo.date.getTimezoneName(this.date);
+	},
+
+	I: function(){
+		// summary: Whether or not the date is in daylight saving time
+		// TODO: Can dojo.date do this?
+	},
+
+	O: function(){
+		// summary: Difference to Greenwich time (GMT) in hours
+		var off = Math.abs(this.date.getTimezoneOffset());
+		var hours = Math.floor(off / 60) + "";
+		var mins = (off % 60) + "";
+		if(hours.length == 1) hours = "0" + hours;
+		if(mins.length == 1) hours = "0" + mins;
+		return ((this.date.getTimezoneOffset() < 0) ? "+" : "-") + hours + mins;
+	},
+
+	P: function(){
+		// summary: Difference to Greenwich time (GMT) with colon between hours and minutes (added in PHP 5.1.3)
+		var O = this.O();
+		return O.substring(0, 2) + ":" + O.substring(2, 4);
+	},
+
+	T: function(){
+		// summary: Timezone abbreviation
+
+		// Guess...
+		return this.e().substring(0, 3);
+	},
+
+	Z: function(){
+		// summary:
+		//		Timezone offset in seconds. The offset for timezones west of UTC is always negative,
+		//		and for those east of UTC is always positive.
+		return this.date.getTimezoneOffset() * -60;
+	},
+
+	// Full Date/Time
+
+	c: function(){
+		// summary: ISO 8601 date (added in PHP 5)
+		return this.Y() + "-" + this.m() + "-" + this.d() + "T" + this.h() + ":" + this.i() + ":" + this.s() + this.P();
+	},
+
+	r: function(){
+		// summary: RFC 2822 formatted date
+		return this.D() + ", " + this.d() + " " + this.M() + " " + this.Y() + " " + this.H() + ":" + this.i() + ":" + this.s() + " " + this.O();
+	},
+
+	U: function(){
+		// summary: Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
+		return Math.floor(this.date.getTime() / 1000);
+	}
+
+});
+
+}
+
+if(!dojo._hasResource["dojox.dtl.utils.date"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.dtl.utils.date"] = true;
+dojo.provide("dojox.dtl.utils.date");
+
+
+
+dojox.dtl.utils.date.DateFormat = function(/*String*/ format){
+	dojox.date.php.DateFormat.call(this, format);
+}
+dojo.extend(dojox.dtl.utils.date.DateFormat, dojox.date.php.DateFormat.prototype, {
+	f: function(){
+		// summary:
+		//		Time, in 12-hour hours and minutes, with minutes left off if they're zero.
+		// description: 
+		//		Examples: '1', '1:30', '2:05', '2'
+		//		Proprietary extension.
+		return (!this.date.getMinutes()) ? this.g() : this.g() + ":" + this.i();
+	},
+	N: function(){
+		// summary: Month abbreviation in Associated Press style. Proprietary extension.
+		return dojox.dtl.utils.date._months_ap[this.date.getMonth()];
+	},
+	P: function(){
+		// summary:
+		//		Time, in 12-hour hours, minutes and 'a.m.'/'p.m.', with minutes left off
+		//		if they're zero and the strings 'midnight' and 'noon' if appropriate.
+		// description:
+		//		Examples: '1 a.m.', '1:30 p.m.', 'midnight', 'noon', '12:30 p.m.'
+		//		Proprietary extension.
+		if(!this.date.getMinutes() && !this.date.getHours()){
+			return 'midnight';
+		}
+		if(!this.date.getMinutes() && this.date.getHours() == 12){
+			return 'noon';
+		}
+		return this.f() + " " + this.a();
+	}
+});
+
+dojo.mixin(dojox.dtl.utils.date, {
+	format: function(/*Date*/ date, /*String*/ format){
+		var df = new dojox.dtl.utils.date.DateFormat(format);
+		return df.format(date);
+	},
+	timesince: function(d, now){
+		// summary:
+		//		Takes two datetime objects and returns the time between then and now
+		//		as a nicely formatted string, e.g "10 minutes"
+		// description:
+		//		Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since
+		if(!(d instanceof Date)){
+			d = new Date(d.year, d.month, d.day);
+		}
+		if(!now){
+			now = new Date();
+		}
+
+		var delta = Math.abs(now.getTime() - d.getTime());
+		for(var i = 0, chunk; chunk = dojox.dtl.utils.date._chunks[i]; i++){
+			var count = Math.floor(delta / chunk[0]);
+			if(count) break;
+		}
+		return count + " " + chunk[1](count);
+	},
+	_chunks: [
+		[60 * 60 * 24 * 365 * 1000, function(n){ return (n == 1) ? 'year' : 'years'; }],
+		[60 * 60 * 24 * 30 * 1000, function(n){ return (n == 1) ? 'month' : 'months'; }],
+		[60 * 60 * 24 * 7 * 1000, function(n){ return (n == 1) ? 'week' : 'weeks'; }],
+		[60 * 60 * 24 * 1000, function(n){ return (n == 1) ? 'day' : 'days'; }],
+		[60 * 60 * 1000, function(n){ return (n == 1) ? 'hour' : 'hours'; }],
+		[60 * 1000, function(n){ return (n == 1) ? 'minute' : 'minutes'; }]
+	],
+	_months_ap: ["Jan.", "Feb.", "March", "April", "May", "June", "July", "Aug.", "Sept.", "Oct.", "Nov.", "Dec."]
+});
+
+}
+
+if(!dojo._hasResource["dojox.dtl.tag.date"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.dtl.tag.date"] = true;
+dojo.provide("dojox.dtl.tag.date");
+
+
+
+
+dojox.dtl.tag.date.NowNode = function(format, node){
+	this._format = format;
+	this.format = new dojox.dtl.utils.date.DateFormat(format);
+	this.contents = node;
+}
+dojo.extend(dojox.dtl.tag.date.NowNode, {
+	render: function(context, buffer){
+		this.contents.set(this.format.format(new Date()));
+		return this.contents.render(context, buffer);
+	},
+	unrender: function(context, buffer){
+		return this.contents.unrender(context, buffer);
+	},
+	clone: function(buffer){
+		return new this.constructor(this._format, this.contents.clone(buffer));
+	}
+});
+
+dojox.dtl.tag.date.now = function(parser, token){
+	// Split by either :" or :'
+	var parts = token.split_contents();
+	if(parts.length != 2){
+		throw new Error("'now' statement takes one argument");
+	}
+	return new dojox.dtl.tag.date.NowNode(parts[1].slice(1, -1), parser.create_text_node());
+}
+
+}
+
+if(!dojo._hasResource["dojox.dtl.tag.loader"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.dtl.tag.loader"] = true;
+dojo.provide("dojox.dtl.tag.loader");
+
+
+
+(function(){
+	var dd = dojox.dtl;
+	var ddtl = dd.tag.loader;
+
+	ddtl.BlockNode = dojo.extend(function(name, nodelist){
+		this.name = name;
+		this.nodelist = nodelist; // Can be overridden
+	},
+	{
+		"super": function(){
+			if(this.parent){
+				var html = this.parent.nodelist.dummyRender(this.context, null, true);
+				if(typeof html == "string"){
+					html = new String(html);
+				}
+				html.safe = true;
+				return html;
+			}
+			return '';
+		},
+		render: function(context, buffer){
+			var name = this.name;
+			var nodelist = this.nodelist;
+			var parent;
+			if(buffer.blocks){
+				var block = buffer.blocks[name];
+				if(block){
+					parent = block.parent;
+					nodelist = block.nodelist;
+					block.used = true;
+				}
+			}
+
+			this.rendered = nodelist;
+
+			context = context.push();
+			this.context = context;
+			this.parent = null;
+			if(nodelist != this.nodelist){
+				this.parent = this;
+			}
+			context.block = this;
+
+			if(buffer.getParent){
+				var bufferParent = buffer.getParent();
+				var setParent = dojo.connect(buffer, "onSetParent", function(node, up, root){
+					if(up && root){
+						buffer.setParent(bufferParent);
+					}
+				});
+			}
+			buffer = nodelist.render(context, buffer, this);
+			setParent && dojo.disconnect(setParent);
+			context = context.pop();
+			return buffer;
+		},
+		unrender: function(context, buffer){
+			return this.rendered.unrender(context, buffer);
+		},
+		clone: function(buffer){
+			return new this.constructor(this.name, this.nodelist.clone(buffer));
+		},
+		toString: function(){ return "dojox.dtl.tag.loader.BlockNode"; }
+	});
+
+	ddtl.ExtendsNode = dojo.extend(function(getTemplate, nodelist, shared, parent, key){
+		this.getTemplate = getTemplate;
+		this.nodelist = nodelist;
+		this.shared = shared;
+		this.parent = parent;
+		this.key = key;
+	},
+	{
+		parents: {},
+		getParent: function(context){
+			var parent = this.parent;
+			if(!parent){
+				var string;
+				parent = this.parent = context.get(this.key, false);
+				if(!parent){
+					throw new Error("extends tag used a variable that did not resolve");
+				}
+				if(typeof parent == "object"){
+					var url = parent.url || parent.templatePath;
+					if(parent.shared){
+						this.shared = true;
+					}
+					if(url){
+						parent = this.parent = url.toString();
+					}else if(parent.templateString){
+						// Allow the builder's string interning to work
+						string = parent.templateString;
+						parent = this.parent = " ";
+					}else{
+						parent = this.parent = this.parent.toString();
+					}
+				}
+				if(parent && parent.indexOf("shared:") === 0){
+					this.shared = true;
+					parent = this.parent = parent.substring(7, parent.length);
+				}
+			}
+			if(!parent){
+				throw new Error("Invalid template name in 'extends' tag.");
+			}
+			if(parent.render){
+				return parent;
+			}
+			if(this.parents[parent]){
+				return this.parents[parent];
+			}
+			this.parent = this.getTemplate(string || dojox.dtl.text.getTemplateString(parent));
+			if(this.shared){
+				this.parents[parent] = this.parent;
+			}
+			return this.parent;
+		},
+		render: function(context, buffer){
+			var parent = this.getParent(context);
+
+			parent.blocks = parent.blocks || {};
+			buffer.blocks = buffer.blocks || {};
+
+			for(var i = 0, node; node = this.nodelist.contents[i]; i++){
+				if(node instanceof dojox.dtl.tag.loader.BlockNode){
+					var old = parent.blocks[node.name];
+					if(old && old.nodelist != node.nodelist){
+						// In a shared template, the individual blocks might change
+						buffer = old.nodelist.unrender(context, buffer);
+					}
+					parent.blocks[node.name] = buffer.blocks[node.name] = {
+						shared: this.shared,
+						nodelist: node.nodelist,
+						used: false
+					}
+				}
+			}
+
+			this.rendered = parent;
+			return parent.nodelist.render(context, buffer, this);
+		},
+		unrender: function(context, buffer){
+			return this.rendered.unrender(context, buffer, this);
+		},
+		toString: function(){ return "dojox.dtl.block.ExtendsNode"; }
+	});
+
+	ddtl.IncludeNode = dojo.extend(function(path, constant, getTemplate, text, parsed){
+		this._path = path;
+		this.constant = constant;
+		this.path = (constant) ? path : new dd._Filter(path);
+		this.getTemplate = getTemplate;
+		this.text = text;
+		this.parsed = (arguments.length == 5) ? parsed : true;
+	},
+	{
+		_cache: [{}, {}],
+		render: function(context, buffer){
+			var location = ((this.constant) ? this.path : this.path.resolve(context)).toString();
+			var parsed = Number(this.parsed);
+			var dirty = false;
+			if(location != this.last){
+				dirty = true;
+				if(this.last){
+					buffer = this.unrender(context, buffer);
+				}
+				this.last = location;
+			}
+
+			var cache = this._cache[parsed];
+
+			if(parsed){
+				if(!cache[location]){
+					cache[location] = dd.text._resolveTemplateArg(location, true);
+				}
+				if(dirty){
+					var template = this.getTemplate(cache[location]);
+					this.rendered = template.nodelist;
+				}
+				return this.rendered.render(context, buffer, this);
+			}else{
+				if(this.text instanceof dd._TextNode){
+					if(dirty){
+						this.rendered = this.text;
+						this.rendered.set(dd.text._resolveTemplateArg(location, true));
+					}
+					return this.rendered.render(context, buffer);
+				}else{
+					if(!cache[location]){
+						var nodelist = [];
+						var div = document.createElement("div");
+						div.innerHTML = dd.text._resolveTemplateArg(location, true);
+						var children = div.childNodes;
+						while(children.length){
+							var removed = div.removeChild(children[0]);
+							nodelist.push(removed);
+						}
+						cache[location] = nodelist;
+					}
+					if(dirty){
+						this.nodelist = [];
+						var exists = true;
+						for(var i = 0, child; child = cache[location][i]; i++){
+							this.nodelist.push(child.cloneNode(true));
+						}
+					}
+					for(var i = 0, node; node = this.nodelist[i]; i++){
+						buffer = buffer.concat(node);
+					}
+				}
+			}
+			return buffer;
+		},
+		unrender: function(context, buffer){
+			if(this.rendered){
+				buffer = this.rendered.unrender(context, buffer);
+			}
+			if(this.nodelist){
+				for(var i = 0, node; node = this.nodelist[i]; i++){
+					buffer = buffer.remove(node);
+				}
+			}
+			return buffer;
+		},
+		clone: function(buffer){
+			return new this.constructor(this._path, this.constant, this.getTemplate, this.text.clone(buffer), this.parsed);
+		}
+	});
+
+	dojo.mixin(ddtl, {
+		block: function(parser, token){
+			var parts = token.contents.split();
+			var name = parts[1];
+
+			parser._blocks = parser._blocks || {};
+			parser._blocks[name] = parser._blocks[name] || [];
+			parser._blocks[name].push(name);
+
+			var nodelist = parser.parse(["endblock", "endblock " + name]).rtrim();
+			parser.next_token();
+			return new dojox.dtl.tag.loader.BlockNode(name, nodelist);
+		},
+		extends_: function(parser, token){
+			var parts = token.contents.split();
+			var shared = false;
+			var parent = null;
+			var key = null;
+			if(parts[1].charAt(0) == '"' || parts[1].charAt(0) == "'"){
+				parent = parts[1].substring(1, parts[1].length - 1);
+			}else{
+				key = parts[1];
+			}
+			if(parent && parent.indexOf("shared:") == 0){
+				shared = true;
+				parent = parent.substring(7, parent.length);
+			}
+			var nodelist = parser.parse();
+			return new dojox.dtl.tag.loader.ExtendsNode(parser.getTemplate, nodelist, shared, parent, key);
+		},
+		include: function(parser, token){
+			var parts = token.contents.split();
+			if(parts.length != 2){
+				throw new Error(parts[0] + " tag takes one argument: the name of the template to be included");
+			}
+			var path = parts[1];
+			var constant = false;
+			if((path.charAt(0) == '"' || path.slice(-1) == "'") && path.charAt(0) == path.slice(-1)){
+				path = path.slice(1, -1);
+				constant = true;
+			}
+			return new ddtl.IncludeNode(path, constant, parser.getTemplate, parser.create_text_node());
+		},
+		ssi: function(parser, token){
+			// We're going to treat things a little differently here.
+			// First of all, this tag is *not* portable, so I'm not
+			// concerned about it being a "drop in" replacement.
+
+			// Instead, we'll just replicate the include tag, but with that
+			// optional "parsed" parameter.
+			var parts = token.contents.split();
+			var parsed = false;
+			if(parts.length == 3){
+				parsed = (parts.pop() == "parsed");
+				if(!parsed){
+					throw new Error("Second (optional) argument to ssi tag must be 'parsed'");
+				}
+			}
+			var node = ddtl.include(parser, new dd.Token(token.token_type, parts.join(" ")));
+			node.parsed = parsed;
+			return node;
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.dtl.tag.misc"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.dtl.tag.misc"] = true;
+dojo.provide("dojox.dtl.tag.misc");
+
+
+(function(){
+	var dd = dojox.dtl;
+	var ddtm = dd.tag.misc;
+
+	ddtm.DebugNode = dojo.extend(function(text){
+		this.text = text;
+	},
+	{
+		render: function(context, buffer){
+			var keys = context.getKeys();
+			var debug = [];
+			var only = {};
+			for(var i = 0, key; key = keys[i]; i++){
+				only[key] = context[key];
+				debug += "[" + key + ": " + typeof context[key] + "]\n";
+			}
+			
+			return this.text.set(debug).render(context, buffer, this);
+		},
+		unrender: function(context, buffer){
+			return buffer;
+		},
+		clone: function(buffer){
+			return new this.constructor(this.text.clone(buffer));
+		},
+		toString: function(){ return "ddtm.DebugNode"; }
+	});
+
+	ddtm.FilterNode = dojo.extend(function(varnode, nodelist){
+		this._varnode = varnode;
+		this._nodelist = nodelist;
+	},
+	{
+		render: function(context, buffer){
+			// Doing this in HTML requires a different buffer with a fake root node
+			var output = this._nodelist.render(context, new dojox.string.Builder());
+			context = context.update({ "var": output.toString() });
+			var filtered = this._varnode.render(context, buffer);
+			context = context.pop();
+			return buffer;
+		},
+		unrender: function(context, buffer){
+			return buffer;
+		},
+		clone: function(buffer){
+			return new this.constructor(this._expression, this._nodelist.clone(buffer));
+		}
+	});
+
+	ddtm.FirstOfNode = dojo.extend(function(vars, text){
+		this._vars = vars;
+		this.vars = dojo.map(vars, function(item){
+			return new dojox.dtl._Filter(item);
+		});
+		this.contents = text;
+	},
+	{
+		render: function(context, buffer){
+			for(var i = 0, item; item = this.vars[i]; i++){
+				var resolved = item.resolve(context);
+				if(typeof resolved != "undefined"){
+					if(resolved === null){
+						resolved = "null";
+					}
+					this.contents.set(resolved);
+					return this.contents.render(context, buffer);
+				}
+			}
+			return this.contents.unrender(context, buffer);
+		},
+		unrender: function(context, buffer){
+			return this.contents.unrender(context, buffer);
+		},
+		clone: function(buffer){
+			return new this.constructor(this._vars, this.contents.clone(buffer));
+		}
+	});
+
+	ddtm.SpacelessNode = dojo.extend(function(nodelist, text){
+		this.nodelist = nodelist;
+		this.contents = text;
+	},
+	{
+		render: function(context, buffer){
+			if(buffer.getParent){
+				// Unfortunately, we have to branch here
+				var watch = [
+					dojo.connect(buffer, "onAddNodeComplete", this, "_watch"),
+					dojo.connect(buffer, "onSetParent", this, "_watchParent")
+				];
+				buffer = this.nodelist.render(context, buffer);
+				dojo.disconnect(watch[0]);
+				dojo.disconnect(watch[1]);
+			}else{
+				var value = this.nodelist.dummyRender(context);
+				this.contents.set(value.replace(/>\s+</g, '><'));
+				buffer = this.contents.render(context, buffer);
+			}
+			return buffer;
+		},
+		unrender: function(context, buffer){
+			return this.nodelist.unrender(context, buffer);
+		},
+		clone: function(buffer){
+			return new this.constructor(this.nodelist.clone(buffer), this.contents.clone(buffer));
+		},
+		_isEmpty: function(node){
+			return (node.nodeType == 3 && !node.data.match(/[^\s\n]/));
+		},
+		_watch: function(node){
+			if(this._isEmpty(node)){
+				var remove = false;
+				if(node.parentNode.firstChild == node){
+					node.parentNode.removeChild(node);
+				}
+			}else{
+				var children = node.parentNode.childNodes;
+				if(node.nodeType == 1 && children.length > 2){
+					for(var i = 2, child; child = children[i]; i++){
+						if(children[i - 2].nodeType == 1 && this._isEmpty(children[i - 1])){
+							node.parentNode.removeChild(children[i - 1]);
+							return;
+						}
+					}
+				}
+			}
+		},
+		_watchParent: function(node){
+			var children = node.childNodes;
+			if(children.length){
+				while(node.childNodes.length){
+					var last = node.childNodes[node.childNodes.length - 1];
+					if(!this._isEmpty(last)){
+						return;
+					}
+					node.removeChild(last);
+				}
+			}
+		}
+	});
+
+	ddtm.TemplateTagNode = dojo.extend(function(tag, text){
+		this.tag = tag;
+		this.contents = text;
+	},
+	{
+		mapping: {
+			openblock: "{%",
+			closeblock: "%}",
+			openvariable: "{{",
+			closevariable: "}}",
+			openbrace: "{",
+			closebrace: "}",
+			opencomment: "{#",
+			closecomment: "#}"
+		},
+		render: function(context, buffer){
+			this.contents.set(this.mapping[this.tag]);
+			return this.contents.render(context, buffer);
+		},
+		unrender: function(context, buffer){
+			return this.contents.unrender(context, buffer);
+		},
+		clone: function(buffer){
+			return new this.constructor(this.tag, this.contents.clone(buffer));
+		}
+	});
+
+	ddtm.WidthRatioNode = dojo.extend(function(current, max, width, text){
+		this.current = new dd._Filter(current);
+		this.max = new dd._Filter(max);
+		this.width = width;
+		this.contents = text;
+	},
+	{
+		render: function(context, buffer){
+			var current = +this.current.resolve(context);
+			var max = +this.max.resolve(context);
+			if(typeof current != "number" || typeof max != "number" || !max){
+				this.contents.set("");
+			}else{
+				this.contents.set("" + Math.round((current / max) * this.width));
+			}
+			return this.contents.render(context, buffer);
+		},
+		unrender: function(context, buffer){
+			return this.contents.unrender(context, buffer);
+		},
+		clone: function(buffer){
+			return new this.constructor(this.current.getExpression(), this.max.getExpression(), this.width, this.contents.clone(buffer));
+		}
+	});
+
+	ddtm.WithNode = dojo.extend(function(target, alias, nodelist){
+		this.target = new dd._Filter(target);
+		this.alias = alias;
+		this.nodelist = nodelist;
+	},
+	{
+		render: function(context, buffer){
+			var target = this.target.resolve(context);
+			context = context.push();
+			context[this.alias] = target;
+			buffer = this.nodelist.render(context, buffer);
+			context = context.pop();
+			return buffer;
+		},
+		unrender: function(context, buffer){
+			return buffer;
+		},
+		clone: function(buffer){
+			return new this.constructor(this.target.getExpression(), this.alias, this.nodelist.clone(buffer));
+		}
+	});
+
+	dojo.mixin(ddtm, {
+		comment: function(parser, token){
+			// summary: Ignore everything between {% comment %} and {% endcomment %}
+			parser.skip_past("endcomment");
+			return dd._noOpNode;
+		},
+		debug: function(parser, token){
+			// summary: Output the current context, maybe add more stuff later.
+			return new ddtm.DebugNode(parser.create_text_node());
+		},
+		filter: function(parser, token){
+			// summary: Filter the contents of the blog through variable filters.
+			var rest = token.contents.split(null, 1)[1];
+			var varnode = parser.create_variable_node("var|" + rest);
+			var nodelist = parser.parse(["endfilter"]);
+			parser.next_token();
+			return new ddtm.FilterNode(varnode, nodelist);
+		},
+		firstof: function(parser, token){
+			var parts = token.split_contents().slice(1);
+			if(!parts.length){
+				throw new Error("'firstof' statement requires at least one argument");
+			}
+			return new ddtm.FirstOfNode(parts, parser.create_text_node());
+		},
+		spaceless: function(parser, token){
+			var nodelist = parser.parse(["endspaceless"]);
+			parser.delete_first_token();
+			return new ddtm.SpacelessNode(nodelist, parser.create_text_node());
+		},
+		templatetag: function(parser, token){
+			var parts = token.contents.split();
+			if(parts.length != 2){
+				throw new Error("'templatetag' statement takes one argument");
+			}
+			var tag = parts[1];
+			var mapping = ddtm.TemplateTagNode.prototype.mapping;
+			if(!mapping[tag]){
+				var keys = [];
+				for(var key in mapping){
+					keys.push(key);
+				}
+				throw new Error("Invalid templatetag argument: '" + tag + "'. Must be one of: " + keys.join(", "));
+			}
+			return new ddtm.TemplateTagNode(tag, parser.create_text_node());
+		},
+		widthratio: function(parser, token){
+			var parts = token.contents.split();
+			if(parts.length != 4){
+				throw new Error("widthratio takes three arguments");
+			}
+			var width = +parts[3];
+			if(typeof width != "number"){
+				throw new Error("widthratio final argument must be an integer");
+			}
+			return new ddtm.WidthRatioNode(parts[1], parts[2], width, parser.create_text_node());
+		},
+		with_: function(parser, token){
+			var parts = token.split_contents();
+			if(parts.length != 4 || parts[2] != "as"){
+				throw new Error("do_width expected format as 'with value as name'");
+			}
+			var nodelist = parser.parse(["endwith"]);
+			parser.next_token();
+			return new ddtm.WithNode(parts[1], parts[3], nodelist);
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.dtl.ext-dojo.NodeList"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.dtl.ext-dojo.NodeList"] = true;
+dojo.provide("dojox.dtl.ext-dojo.NodeList");
+
+
+dojo.extend(dojo.NodeList, {
+	dtl: function(template, context){
+		// template: dojox.dtl.__StringArgs|String
+		//		The template string or location
+		// context: dojox.dtl.__ObjectArgs|Object
+		//		The context object or location
+		var d = dojox.dtl;
+
+		var self = this;
+		var render = function(template, context){
+			var content = template.render(new d._Context(context));
+			self.forEach(function(node){
+				node.innerHTML = content;
+			});
+		}
+
+		d.text._resolveTemplateArg(template).addCallback(function(templateString){
+			template = new d.Template(templateString);
+			d.text._resolveContextArg(context).addCallback(function(context){
+				render(template, context);
+			});
+		});
+
+		return this;
+	}
+});
+
+}
+
diff --git a/dojox/dtl/Context.js b/dojox/dtl/Context.js
new file mode 100644
index 0000000..7086f55
--- /dev/null
+++ b/dojox/dtl/Context.js
@@ -0,0 +1,63 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.Context"]){
+dojo._hasResource["dojox.dtl.Context"]=true;
+dojo.provide("dojox.dtl.Context");
+dojo.require("dojox.dtl._base");
+dojox.dtl.Context=dojo.extend(function(_1){
+this._this={};
+dojox.dtl._Context.call(this,_1);
+},dojox.dtl._Context.prototype,{getKeys:function(){
+var _2=[];
+for(var _3 in this){
+if(this.hasOwnProperty(_3)&&_3!="_dicts"&&_3!="_this"){
+_2.push(_3);
+}
+}
+return _2;
+},extend:function(_4){
+return dojo.delegate(this,_4);
+},filter:function(_5){
+var _6=new dojox.dtl.Context();
+var _7=[];
+var i,_9;
+if(_5 instanceof dojox.dtl.Context){
+_7=_5.getKeys();
+}else{
+if(typeof _5=="object"){
+for(var _a in _5){
+_7.push(_a);
+}
+}else{
+for(i=0;_9=arguments[i];i++){
+if(typeof _9=="string"){
+_7.push(_9);
+}
+}
+}
+}
+for(i=0,_a;_a=_7[i];i++){
+_6[_a]=this[_a];
+}
+return _6;
+},setThis:function(_b){
+this._this=_b;
+},getThis:function(){
+return this._this;
+},hasKey:function(_c){
+if(typeof this[_c]!="undefined"){
+return true;
+}
+for(var i=0,_e;_e=this._dicts[i];i++){
+if(typeof _e[_c]!="undefined"){
+return true;
+}
+}
+return false;
+}});
+}
diff --git a/dojox/dtl/DomInline.js b/dojox/dtl/DomInline.js
new file mode 100644
index 0000000..9765ac5
--- /dev/null
+++ b/dojox/dtl/DomInline.js
@@ -0,0 +1,35 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.DomInline"]){
+dojo._hasResource["dojox.dtl.DomInline"]=true;
+dojo.provide("dojox.dtl.DomInline");
+dojo.require("dojox.dtl.dom");
+dojo.require("dijit._Widget");
+dojox.dtl.DomInline=dojo.extend(function(_1,_2){
+this.create(_1,_2);
+},dijit._Widget.prototype,{context:null,render:function(_3){
+this.context=_3||this.context;
+this.postMixInProperties();
+var _4=this.template.render(this.context).getRootNode();
+if(_4!=this.containerNode){
+this.containerNode.parentNode.replaceChild(_4,this.containerNode);
+this.containerNode=_4;
+}
+},declaredClass:"dojox.dtl.Inline",buildRendering:function(){
+var _5=this.domNode=document.createElement("div");
+this.containerNode=_5.appendChild(document.createElement("div"));
+var _6=this.srcNodeRef;
+if(_6.parentNode){
+_6.parentNode.replaceChild(_5,_6);
+}
+this.template=new dojox.dtl.DomTemplate(dojo.trim(_6.text),true);
+this.render();
+},postMixInProperties:function(){
+this.context=(this.context.get===dojox.dtl._Context.prototype.get)?this.context:new dojox.dtl.Context(this.context);
+}});
+}
diff --git a/dojox/dtl/HtmlInline.js b/dojox/dtl/HtmlInline.js
new file mode 100644
index 0000000..106abbb
--- /dev/null
+++ b/dojox/dtl/HtmlInline.js
@@ -0,0 +1,15 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.HtmlInline"]){
+dojo._hasResource["dojox.dtl.HtmlInline"]=true;
+dojo.provide("dojox.dtl.HtmlInline");
+dojo.require("dojox.dtl.DomInline");
+dojo.deprecated("dojox.dtl.html","All packages and classes in dojox.dtl that start with Html or html have been renamed to Dom or dom");
+dojox.dtl.HtmlInline=dojox.dtl.DomInline;
+dojox.dtl.HtmlInline.prototype.declaredClass="dojox.dtl.HtmlInline";
+}
diff --git a/dojox/dtl/Inline.js b/dojox/dtl/Inline.js
new file mode 100644
index 0000000..1ad27c1
--- /dev/null
+++ b/dojox/dtl/Inline.js
@@ -0,0 +1,31 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.Inline"]){
+dojo._hasResource["dojox.dtl.Inline"]=true;
+dojo.provide("dojox.dtl.Inline");
+dojo.require("dojox.dtl._base");
+dojo.require("dijit._Widget");
+dojox.dtl.Inline=dojo.extend(function(_1,_2){
+this.create(_1,_2);
+},dijit._Widget.prototype,{context:null,render:function(_3){
+this.context=_3||this.context;
+this.postMixInProperties();
+dojo.query("*",this.domNode).orphan();
+this.domNode.innerHTML=this.template.render(this.context);
+},declaredClass:"dojox.dtl.Inline",buildRendering:function(){
+var _4=this.domNode=document.createElement("div");
+var _5=this.srcNodeRef;
+if(_5.parentNode){
+_5.parentNode.replaceChild(_4,_5);
+}
+this.template=new dojox.dtl.Template(dojo.trim(_5.text),true);
+this.render();
+},postMixInProperties:function(){
+this.context=(this.context.get===dojox.dtl._Context.prototype.get)?this.context:new dojox.dtl._Context(this.context);
+}});
+}
diff --git a/dojox/dtl/README b/dojox/dtl/README
new file mode 100644
index 0000000..54dd4f3
--- /dev/null
+++ b/dojox/dtl/README
@@ -0,0 +1,207 @@
+-------------------------------------------------------------------------------
+DojoX Django Template Language
+-------------------------------------------------------------------------------
+Version 0.0
+Release date: 09/20/2007
+-------------------------------------------------------------------------------
+Project state: experimental/feature incomplete
+-------------------------------------------------------------------------------
+Project authors
+	Neil Roberts (pottedmeat at dojotoolkit.org)
+-------------------------------------------------------------------------------
+Project description
+
+The Django Template language uses a system of templates that can be compiled
+once and rendered indefinitely afterwards. It uses a simple system of tags
+and filters.
+
+This is a 1:1 match with the Django Template Language as outlined in
+http://www.djangoproject.com/documentation/templates/. All applicable tags and
+filters have been implemented (see below), along with new filters and tags as
+necessary (see below).
+
+The Django Template Language is intended within Django to only handle text.
+Our implementation is able to handle HTML in addition to text. Actually, the
+text and HTML portions of dojox.dtl are two separate layers, the HTML layer
+sits on top of the text layer (base). It's also been implemented in such a way
+that you have little to fear when moving your code from Django to dojox.dtl.
+Your existing templates should work, and will benefit from the massive
+performance gain of being able to manipulate nodes, rather than having to do
+clunky innerHTML swaps you would have to do with a text-only system. It also
+allows for new HTML-centric abilities, outlined below.
+
+Despite having two levels of complexity, if you write your tags correctly, they
+will work in both environments.
+-------------------------------------------------------------------------------
+Dependencies
+
+Base:
+dojox.string.Builder
+
+Date filters and tags:
+dojox.date.php
+
+Widget:
+dijit._Widget
+dijit._Container
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/dtl.js
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/dtl/*
+
+Install into the following directory structure:
+/dojox/dtl/
+
+...which should be at the same level as your Dojo checkout.
+-------------------------------------------------------------------------------
+What's Been Done
+
+Note: HTML Unit Tests should only be around for the oddities of HTML, tag/filter
+code is the same for each environment with minor exceptions. Cloning of all tags
+should be tested inside a for loop.
+
+| Implemented |     Tag     | Text Unit Test | HTML Unit Test |
+|      X      | block       |       X        |                |
+|      X      | comment     |       X        |                |
+|      X      | cycle       |       X        |                |
+|      X      | debug       |       X        |                |
+|      X      | extends     |       X        |                |
+|      X      | filter      |       X        |                |
+|      X      | firstof     |       X        |                |
+|      X      | for         |       X        |                |
+|      X      | if          |       X        |                |
+|      X      | ifchanged   |       X        |       X        |
+|      X      | ifequal     |       X        |                |
+|      X      | ifnotequal  |       X        |                |
+|      X      | include     |       X        |       X        |
+|      X      | load        |       X        |                |
+|      X      | now         |       X        |                |
+|      X      | regroup     |       X        |                |
+|      X      | spaceless   |       X        |       X        |
+|      X      | ssi         |       X        |       X        |
+|      X      | templatetag |       X        |                |
+|     N/A     | url         |                |                |
+|      X      | widthratio  |       X        |                |
+|      X      | with        |       X        |                |
+
+| Implemented | Filter             | Text Unit Test | HTML Unit Test |
+|      X      | add                |       X        |                |
+|      X      | addslashes         |       X        |                |
+|      X      | capfirst           |       X        |                |
+|      X      | center             |       X        |                |
+|      X      | cut                |       X        |                |
+|      X      | date               |       X        |                |
+|      X      | default            |       X        |                |
+|      X      | default_if_none    |       X        |                |
+|      X      | dictsort           |       X        |                |
+|      X      | dictsort_reversed  |       X        |                |
+|      X      | divisibleby        |       X        |                |
+|      X      | escape             |       X        |                |
+|      X      | filesizeformat     |       X        |                |
+|      X      | first              |       X        |                |
+|      X      | fix_ampersands     |       X        |                |
+|      X      | floatformat        |       X        |                |
+|      X      | get_digit          |       X        |                |
+|      X      | iriencode          |       X        |                |
+|      X      | join               |       X        |                |
+|      X      | length             |       X        |                |
+|      X      | length_is          |       X        |                |
+|      X      | linebreaks         |       X        |                |
+|      X      | linebreaksbr       |       X        |                |
+|      X      | linenumbers        |       X        |                |
+|      X      | ljust              |       X        |                |
+|      X      | lower              |       X        |                |
+|      X      | make_list          |       X        |                |
+|      X      | phone2numeric      |       X        |                |
+|      X      | pluralize          |       X        |                |
+|      X      | pprint             |       X        |                |
+|      X      | random             |       X        |                |
+|      X      | removetags         |       X        |                |
+|      X      | rjust              |       X        |                |
+|      X      | slice              |       X        |                |
+|      X      | slugify            |       X        |                |
+|      X      | stringformat       |       X        |                |
+|      X      | striptags          |       X        |                |
+|      X      | time               |       X        |                |
+|      X      | timesince          |       X        |                |
+|      X      | timeuntil          |       X        |                |
+|      X      | title              |       X        |                |
+|      X      | truncatewords      |       X        |                |
+|      X      | truncatewords_html |       X        |                |
+|      X      | unordered_list     |       X        |                |
+|      X      | upper              |       X        |                |
+|      X      | urlencode          |       X        |                |
+|      X      | urlize             |       X        |                |
+|      X      | urlizetrunc        |       X        |                |
+|      X      | wordcount          |       X        |                |
+|      X      | wordwrap           |       X        |                |
+|      X      | yesno              |       X        |                |
+-------------------------------------------------------------------------------
+HTML-Specific Additions
+-------------------------------------------------------------------------------
+{%extends "shared:templates/template.html" %}
+
+When using the {% extends %} tag, we don't always want to replace the parent
+node in DOM. For example, if we have a list view and a detail view, but both
+share the same base template, we want it to share the parent template. This
+basically means that the same nodes will be used in the parent for both views.
+
+To use this, simply add "shared:" to the beginning of the specified template.
+-------------------------------------------------------------------------------
+<!--{% commented markup %}-->
+
+Some browsers treat comment nodes as full fledged nodes. If performance is
+important to you, you can wrap your markup in comments. The comments will be
+automatically stripped for browsers that cannot support this.
+-------------------------------------------------------------------------------
+Attribute Tags
+
+If a tag name begins with "attr:" then it will be able to inject an object
+into the parsed template. (See dojox.dtl.tag.event.EventNode)
+
+onclick/onmouseover/etc attributes work by attaching to the rendering object.
+
+tstyle attribute allows for styles to be changed dynamically. Use them just
+like a "style" attribute.
+
+attach attribute attaches the node to the rendering object.
+-------------------------------------------------------------------------------
+New Context Functions
+
+setThis() and getThis() returns the object "in charge" of the current rendering.
+This is used so that we can attach events.
+
+mixin() and filter() clone the current context, and either add to or reduce
+the keys in the context.
+-------------------------------------------------------------------------------
+Buffers
+
+Both the base and HTML versions of dojox.dtl use buffers. The base version uses
+dojox.string.Builder and the HTML version uses dojox.dtl.DomBuffer.
+
+The HTML buffer has several calls important to rendering:
+
+setParent/getParent/concat/remove:
+
+setParent and concat are used in order to render our HTML. As we move through
+the parsed template, different nodes change the parent or add on to the
+current parent. getParent is useful in things like the attribute tags, since
+they can use getParent to find the node that they're an attribute on. remove is
+used during unrendering.
+
+setAttribute:
+
+Sets an attribute on the current parent
+-------------------------------------------------------------------------------
+Tags Need clone/unrender Functions.
+
+One of the biggest challenges of getting dojox.dtl to work in an HTML
+environment was logic blocks. Nodes and objects inside a for loop need to be
+cloned, they can't simply be re-rendered, especially if they involve a Node.
+Also, in the case of an if/else block, we need to be able to not just render
+one of the blocks, but also unrender the second.
+
+This is really simple code, a good example is the dojox.dtl.DomNode
+object. Each function in this object is only one line long.
\ No newline at end of file
diff --git a/dojox/dtl/_DomTemplated.js b/dojox/dtl/_DomTemplated.js
new file mode 100644
index 0000000..58c6b95
--- /dev/null
+++ b/dojox/dtl/_DomTemplated.js
@@ -0,0 +1,61 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl._DomTemplated"]){
+dojo._hasResource["dojox.dtl._DomTemplated"]=true;
+dojo.provide("dojox.dtl._DomTemplated");
+dojo.require("dijit._Templated");
+dojo.require("dojox.dtl.dom");
+dojo.require("dojox.dtl.render.dom");
+dojo.require("dojox.dtl.contrib.dijit");
+dojox.dtl._DomTemplated={prototype:{_dijitTemplateCompat:false,buildRendering:function(){
+this.domNode=this.srcNodeRef;
+if(!this._render){
+var _1=dojox.dtl.contrib.dijit;
+var _2=_1.widgetsInTemplate;
+_1.widgetsInTemplate=this.widgetsInTemplate;
+this.template=this.template||this._getCachedTemplate(this.templatePath,this.templateString);
+this._render=new dojox.dtl.render.dom.Render(this.domNode,this.template);
+_1.widgetsInTemplate=_2;
+}
+this.render();
+this.domNode=this.template.getRootNode();
+if(this.srcNodeRef&&this.srcNodeRef.parentNode){
+dojo.destroy(this.srcNodeRef);
+delete this.srcNodeRef;
+}
+},setTemplate:function(_3,_4){
+if(dojox.dtl.text._isTemplate(_3)){
+this.template=this._getCachedTemplate(null,_3);
+}else{
+this.template=this._getCachedTemplate(_3);
+}
+this.render(_4);
+},render:function(_5,_6){
+if(_6){
+this.template=_6;
+}
+this._render.render(this._getContext(_5),this.template);
+},_getContext:function(_7){
+if(!(_7 instanceof dojox.dtl.Context)){
+_7=false;
+}
+_7=_7||new dojox.dtl.Context(this);
+_7.setThis(this);
+return _7;
+},_getCachedTemplate:function(_8,_9){
+if(!this._templates){
+this._templates={};
+}
+var _a=_9||_8.toString();
+var _b=this._templates;
+if(_b[_a]){
+return _b[_a];
+}
+return (_b[_a]=new dojox.dtl.DomTemplate(dijit._Templated.getCachedTemplate(_8,_9,true)));
+}}};
+}
diff --git a/dojox/dtl/_HtmlTemplated.js b/dojox/dtl/_HtmlTemplated.js
new file mode 100644
index 0000000..fc87194
--- /dev/null
+++ b/dojox/dtl/_HtmlTemplated.js
@@ -0,0 +1,15 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl._HtmlTemplated"]){
+dojo._hasResource["dojox.dtl._HtmlTemplated"]=true;
+dojo.provide("dojox.dtl._HtmlTemplated");
+dojo.require("dojox.dtl._DomTemplated");
+dojo.deprecated("dojox.dtl.html","All packages and classes in dojox.dtl that start with Html or html have been renamed to Dom or dom");
+dojox.dtl._HtmlTemplated=dojox.dtl._DomTemplated;
+dojox.dtl._HtmlTemplated.prototype.declaredClass="dojox.dtl._HtmlTemplated";
+}
diff --git a/dojox/dtl/_Templated.js b/dojox/dtl/_Templated.js
new file mode 100644
index 0000000..6e9d8bf
--- /dev/null
+++ b/dojox/dtl/_Templated.js
@@ -0,0 +1,71 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl._Templated"]){
+dojo._hasResource["dojox.dtl._Templated"]=true;
+dojo.provide("dojox.dtl._Templated");
+dojo.require("dijit._Templated");
+dojo.require("dojox.dtl._base");
+dojo.declare("dojox.dtl._Templated",dijit._Templated,{_dijitTemplateCompat:false,buildRendering:function(){
+var _1;
+if(this.domNode&&!this._template){
+return;
+}
+if(!this._template){
+var t=this.getCachedTemplate(this.templatePath,this.templateString,this._skipNodeCache);
+if(t instanceof dojox.dtl.Template){
+this._template=t;
+}else{
+_1=t;
+}
+}
+if(!_1){
+var _3=dojo._toDom(this._template.render(new dojox.dtl._Context(this)));
+if(_3.nodeType!==1&&_3.nodeType!==3){
+for(var i=0,l=_3.childNodes.length;i<l;++i){
+_1=_3.childNodes[i];
+if(_1.nodeType==1){
+break;
+}
+}
+}else{
+_1=_3;
+}
+}
+this._attachTemplateNodes(_1);
+if(this.widgetsInTemplate){
+var _6=dojo.parser.parse(_1);
+this._attachTemplateNodes(_6,function(n,p){
+return n[p];
+});
+}
+if(this.domNode){
+dojo.place(_1,this.domNode,"before");
+this.destroyDescendants();
+dojo.destroy(this.domNode);
+}
+this.domNode=_1;
+this._fillContent(this.srcNodeRef);
+},_templateCache:{},getCachedTemplate:function(_9,_a,_b){
+var _c=this._templateCache;
+var _d=_a||_9;
+if(_c[_d]){
+return _c[_d];
+}
+_a=dojo.string.trim(_a||dijit._Templated._sanitizeTemplateString(dojo._getText(_9)));
+if(this._dijitTemplateCompat&&(_b||_a.match(/\$\{([^\}]+)\}/g))){
+_a=this._stringRepl(_a);
+}
+if(_b||!_a.match(/\{[{%]([^\}]+)[%}]\}/g)){
+return _c[_d]=dojo._toDom(_a);
+}else{
+return _c[_d]=new dojox.dtl.Template(_a);
+}
+},render:function(){
+this.buildRendering();
+}});
+}
diff --git a/dojox/dtl/_base.js b/dojox/dtl/_base.js
new file mode 100644
index 0000000..c13be6c
--- /dev/null
+++ b/dojox/dtl/_base.js
@@ -0,0 +1,574 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl._base"]){
+dojo._hasResource["dojox.dtl._base"]=true;
+dojo.provide("dojox.dtl._base");
+dojo.require("dojox.string.Builder");
+dojo.require("dojox.string.tokenize");
+dojo.experimental("dojox.dtl");
+(function(){
+var dd=dojox.dtl;
+dd.TOKEN_BLOCK=-1;
+dd.TOKEN_VAR=-2;
+dd.TOKEN_COMMENT=-3;
+dd.TOKEN_TEXT=3;
+dd._Context=dojo.extend(function(_2){
+dojo._mixin(this,_2||{});
+this._dicts=[];
+},{push:function(){
+var _3=this;
+var _4=dojo.delegate(this);
+_4.pop=function(){
+return _3;
+};
+return _4;
+},pop:function(){
+throw new Error("pop() called on empty Context");
+},get:function(_5,_6){
+if(typeof this[_5]!="undefined"){
+return this._normalize(this[_5]);
+}
+for(var i=0,_8;_8=this._dicts[i];i++){
+if(typeof _8[_5]!="undefined"){
+return this._normalize(_8[_5]);
+}
+}
+return _6;
+},_normalize:function(_9){
+if(_9 instanceof Date){
+_9.year=_9.getFullYear();
+_9.month=_9.getMonth()+1;
+_9.day=_9.getDate();
+_9.date=_9.year+"-"+("0"+_9.month).slice(-2)+"-"+("0"+_9.day).slice(-2);
+_9.hour=_9.getHours();
+_9.minute=_9.getMinutes();
+_9.second=_9.getSeconds();
+_9.microsecond=_9.getMilliseconds();
+}
+return _9;
+},update:function(_a){
+var _b=this.push();
+if(_a){
+dojo._mixin(this,_a);
+}
+return _b;
+}});
+var _c=/("(?:[^"\\]*(?:\\.[^"\\]*)*)"|'(?:[^'\\]*(?:\\.[^'\\]*)*)'|[^\s]+)/g;
+var _d=/\s+/g;
+var _e=function(_f,_10){
+_f=_f||_d;
+if(!(_f instanceof RegExp)){
+_f=new RegExp(_f,"g");
+}
+if(!_f.global){
+throw new Error("You must use a globally flagged RegExp with split "+_f);
+}
+_f.exec("");
+var _11,_12=[],_13=0,i=0;
+while(_11=_f.exec(this)){
+_12.push(this.slice(_13,_f.lastIndex-_11[0].length));
+_13=_f.lastIndex;
+if(_10&&(++i>_10-1)){
+break;
+}
+}
+_12.push(this.slice(_13));
+return _12;
+};
+dd.Token=function(_15,_16){
+this.token_type=_15;
+this.contents=new String(dojo.trim(_16));
+this.contents.split=_e;
+this.split=function(){
+return String.prototype.split.apply(this.contents,arguments);
+};
+};
+dd.Token.prototype.split_contents=function(_17){
+var bit,_19=[],i=0;
+_17=_17||999;
+while(i++<_17&&(bit=_c.exec(this.contents))){
+bit=bit[0];
+if(bit.charAt(0)=="\""&&bit.slice(-1)=="\""){
+_19.push("\""+bit.slice(1,-1).replace("\\\"","\"").replace("\\\\","\\")+"\"");
+}else{
+if(bit.charAt(0)=="'"&&bit.slice(-1)=="'"){
+_19.push("'"+bit.slice(1,-1).replace("\\'","'").replace("\\\\","\\")+"'");
+}else{
+_19.push(bit);
+}
+}
+}
+return _19;
+};
+var ddt=dd.text={_get:function(_1c,_1d,_1e){
+var _1f=dd.register.get(_1c,_1d.toLowerCase(),_1e);
+if(!_1f){
+if(!_1e){
+throw new Error("No tag found for "+_1d);
+}
+return null;
+}
+var fn=_1f[1];
+var _21=_1f[2];
+var _22;
+if(fn.indexOf(":")!=-1){
+_22=fn.split(":");
+fn=_22.pop();
+}
+dojo["require"](_21);
+var _23=dojo.getObject(_21);
+return _23[fn||_1d]||_23[_1d+"_"]||_23[fn+"_"];
+},getTag:function(_24,_25){
+return ddt._get("tag",_24,_25);
+},getFilter:function(_26,_27){
+return ddt._get("filter",_26,_27);
+},getTemplate:function(_28){
+return new dd.Template(ddt.getTemplateString(_28));
+},getTemplateString:function(_29){
+return dojo._getText(_29.toString())||"";
+},_resolveLazy:function(_2a,_2b,_2c){
+if(_2b){
+if(_2c){
+return dojo.fromJson(dojo._getText(_2a))||{};
+}else{
+return dd.text.getTemplateString(_2a);
+}
+}else{
+return dojo.xhrGet({handleAs:(_2c)?"json":"text",url:_2a});
+}
+},_resolveTemplateArg:function(arg,_2e){
+if(ddt._isTemplate(arg)){
+if(!_2e){
+var d=new dojo.Deferred();
+d.callback(arg);
+return d;
+}
+return arg;
+}
+return ddt._resolveLazy(arg,_2e);
+},_isTemplate:function(arg){
+return (typeof arg=="undefined")||(typeof arg=="string"&&(arg.match(/^\s*[<{]/)||arg.indexOf(" ")!=-1));
+},_resolveContextArg:function(arg,_32){
+if(arg.constructor==Object){
+if(!_32){
+var d=new dojo.Deferred;
+d.callback(arg);
+return d;
+}
+return arg;
+}
+return ddt._resolveLazy(arg,_32,true);
+},_re:/(?:\{\{\s*(.+?)\s*\}\}|\{%\s*(load\s*)?(.+?)\s*%\})/g,tokenize:function(str){
+return dojox.string.tokenize(str,ddt._re,ddt._parseDelims);
+},_parseDelims:function(_35,_36,tag){
+if(_35){
+return [dd.TOKEN_VAR,_35];
+}else{
+if(_36){
+var _38=dojo.trim(tag).split(/\s+/g);
+for(var i=0,_3a;_3a=_38[i];i++){
+dojo["require"](_3a);
+}
+}else{
+return [dd.TOKEN_BLOCK,tag];
+}
+}
+}};
+dd.Template=dojo.extend(function(_3b,_3c){
+var str=_3c?_3b:ddt._resolveTemplateArg(_3b,true)||"";
+var _3e=ddt.tokenize(str);
+var _3f=new dd._Parser(_3e);
+this.nodelist=_3f.parse();
+},{update:function(_40,_41){
+return ddt._resolveContextArg(_41).addCallback(this,function(_42){
+var _43=this.render(new dd._Context(_42));
+if(_40.forEach){
+_40.forEach(function(_44){
+_44.innerHTML=_43;
+});
+}else{
+dojo.byId(_40).innerHTML=_43;
+}
+return this;
+});
+},render:function(_45,_46){
+_46=_46||this.getBuffer();
+_45=_45||new dd._Context({});
+return this.nodelist.render(_45,_46)+"";
+},getBuffer:function(){
+dojo.require("dojox.string.Builder");
+return new dojox.string.Builder();
+}});
+var _47=/\{\{\s*(.+?)\s*\}\}/g;
+dd.quickFilter=function(str){
+if(!str){
+return new dd._NodeList();
+}
+if(str.indexOf("{%")==-1){
+return new dd._QuickNodeList(dojox.string.tokenize(str,_47,function(_49){
+return new dd._Filter(_49);
+}));
+}
+};
+dd._QuickNodeList=dojo.extend(function(_4a){
+this.contents=_4a;
+},{render:function(_4b,_4c){
+for(var i=0,l=this.contents.length;i<l;i++){
+if(this.contents[i].resolve){
+_4c=_4c.concat(this.contents[i].resolve(_4b));
+}else{
+_4c=_4c.concat(this.contents[i]);
+}
+}
+return _4c;
+},dummyRender:function(_4f){
+return this.render(_4f,dd.Template.prototype.getBuffer()).toString();
+},clone:function(_50){
+return this;
+}});
+dd._Filter=dojo.extend(function(_51){
+if(!_51){
+throw new Error("Filter must be called with variable name");
+}
+this.contents=_51;
+var _52=this._cache[_51];
+if(_52){
+this.key=_52[0];
+this.filters=_52[1];
+}else{
+this.filters=[];
+dojox.string.tokenize(_51,this._re,this._tokenize,this);
+this._cache[_51]=[this.key,this.filters];
+}
+},{_cache:{},_re:/(?:^_\("([^\\"]*(?:\\.[^\\"])*)"\)|^"([^\\"]*(?:\\.[^\\"]*)*)"|^([a-zA-Z0-9_.]+)|\|(\w+)(?::(?:_\("([^\\"]*(?:\\.[^\\"])*)"\)|"([^\\"]*(?:\\.[^\\"]*)*)"|([a-zA-Z0-9_.]+)|'([^\\']*(?:\\.[^\\']*)*)'))?|^'([^\\']*(?:\\.[^\\']*)*)')/g,_values:{0:"\"",1:"\"",2:"",8:"\""},_args:{4:"\"",5:"\"",6:"",7:"'"},_tokenize:function(){
+var pos,arg;
+for(var i=0,has=[];i<arguments.length;i++){
+has[i]=(typeof arguments[i]!="undefined"&&typeof arguments[i]=="string"&&arguments[i]);
+}
+if(!this.key){
+for(pos in this._values){
+if(has[pos]){
+this.key=this._values[pos]+arguments[pos]+this._values[pos];
+break;
+}
+}
+}else{
+for(pos in this._args){
+if(has[pos]){
+var _57=arguments[pos];
+if(this._args[pos]=="'"){
+_57=_57.replace(/\\'/g,"'");
+}else{
+if(this._args[pos]=="\""){
+_57=_57.replace(/\\"/g,"\"");
+}
+}
+arg=[!this._args[pos],_57];
+break;
+}
+}
+var fn=ddt.getFilter(arguments[3]);
+if(!dojo.isFunction(fn)){
+throw new Error(arguments[3]+" is not registered as a filter");
+}
+this.filters.push([fn,arg]);
+}
+},getExpression:function(){
+return this.contents;
+},resolve:function(_59){
+if(typeof this.key=="undefined"){
+return "";
+}
+var str=this.resolvePath(this.key,_59);
+for(var i=0,_5c;_5c=this.filters[i];i++){
+if(_5c[1]){
+if(_5c[1][0]){
+str=_5c[0](str,this.resolvePath(_5c[1][1],_59));
+}else{
+str=_5c[0](str,_5c[1][1]);
+}
+}else{
+str=_5c[0](str);
+}
+}
+return str;
+},resolvePath:function(_5d,_5e){
+var _5f,_60;
+var _61=_5d.charAt(0);
+var _62=_5d.slice(-1);
+if(!isNaN(parseInt(_61))){
+_5f=(_5d.indexOf(".")==-1)?parseInt(_5d):parseFloat(_5d);
+}else{
+if(_61=="\""&&_61==_62){
+_5f=_5d.slice(1,-1);
+}else{
+if(_5d=="true"){
+return true;
+}
+if(_5d=="false"){
+return false;
+}
+if(_5d=="null"||_5d=="None"){
+return null;
+}
+_60=_5d.split(".");
+_5f=_5e.get(_60[0]);
+if(dojo.isFunction(_5f)){
+var _63=_5e.getThis&&_5e.getThis();
+if(_5f.alters_data){
+_5f="";
+}else{
+if(_63){
+_5f=_5f.call(_63);
+}else{
+_5f="";
+}
+}
+}
+for(var i=1;i<_60.length;i++){
+var _65=_60[i];
+if(_5f){
+var _66=_5f;
+if(dojo.isObject(_5f)&&_65=="items"&&typeof _5f[_65]=="undefined"){
+var _67=[];
+for(var key in _5f){
+_67.push([key,_5f[key]]);
+}
+_5f=_67;
+continue;
+}
+if(_5f.get&&dojo.isFunction(_5f.get)&&_5f.get.safe){
+_5f=_5f.get(_65);
+}else{
+if(typeof _5f[_65]=="undefined"){
+_5f=_5f[_65];
+break;
+}else{
+_5f=_5f[_65];
+}
+}
+if(dojo.isFunction(_5f)){
+if(_5f.alters_data){
+_5f="";
+}else{
+_5f=_5f.call(_66);
+}
+}else{
+if(_5f instanceof Date){
+_5f=dd._Context.prototype._normalize(_5f);
+}
+}
+}else{
+return "";
+}
+}
+}
+}
+return _5f;
+}});
+dd._TextNode=dd._Node=dojo.extend(function(obj){
+this.contents=obj;
+},{set:function(_6a){
+this.contents=_6a;
+return this;
+},render:function(_6b,_6c){
+return _6c.concat(this.contents);
+},isEmpty:function(){
+return !dojo.trim(this.contents);
+},clone:function(){
+return this;
+}});
+dd._NodeList=dojo.extend(function(_6d){
+this.contents=_6d||[];
+this.last="";
+},{push:function(_6e){
+this.contents.push(_6e);
+return this;
+},concat:function(_6f){
+this.contents=this.contents.concat(_6f);
+return this;
+},render:function(_70,_71){
+for(var i=0;i<this.contents.length;i++){
+_71=this.contents[i].render(_70,_71);
+if(!_71){
+throw new Error("Template must return buffer");
+}
+}
+return _71;
+},dummyRender:function(_73){
+return this.render(_73,dd.Template.prototype.getBuffer()).toString();
+},unrender:function(){
+return arguments[1];
+},clone:function(){
+return this;
+},rtrim:function(){
+while(1){
+i=this.contents.length-1;
+if(this.contents[i] instanceof dd._TextNode&&this.contents[i].isEmpty()){
+this.contents.pop();
+}else{
+break;
+}
+}
+return this;
+}});
+dd._VarNode=dojo.extend(function(str){
+this.contents=new dd._Filter(str);
+},{render:function(_75,_76){
+var str=this.contents.resolve(_75);
+if(!str.safe){
+str=dd._base.escape(""+str);
+}
+return _76.concat(str);
+}});
+dd._noOpNode=new function(){
+this.render=this.unrender=function(){
+return arguments[1];
+};
+this.clone=function(){
+return this;
+};
+};
+dd._Parser=dojo.extend(function(_78){
+this.contents=_78;
+},{i:0,parse:function(_79){
+var _7a={};
+_79=_79||[];
+for(var i=0;i<_79.length;i++){
+_7a[_79[i]]=true;
+}
+var _7c=new dd._NodeList();
+while(this.i<this.contents.length){
+token=this.contents[this.i++];
+if(typeof token=="string"){
+_7c.push(new dd._TextNode(token));
+}else{
+var _7d=token[0];
+var _7e=token[1];
+if(_7d==dd.TOKEN_VAR){
+_7c.push(new dd._VarNode(_7e));
+}else{
+if(_7d==dd.TOKEN_BLOCK){
+if(_7a[_7e]){
+--this.i;
+return _7c;
+}
+var cmd=_7e.split(/\s+/g);
+if(cmd.length){
+cmd=cmd[0];
+var fn=ddt.getTag(cmd);
+if(fn){
+_7c.push(fn(this,new dd.Token(_7d,_7e)));
+}
+}
+}
+}
+}
+}
+if(_79.length){
+throw new Error("Could not find closing tag(s): "+_79.toString());
+}
+this.contents.length=0;
+return _7c;
+},next_token:function(){
+var _81=this.contents[this.i++];
+return new dd.Token(_81[0],_81[1]);
+},delete_first_token:function(){
+this.i++;
+},skip_past:function(_82){
+while(this.i<this.contents.length){
+var _83=this.contents[this.i++];
+if(_83[0]==dd.TOKEN_BLOCK&&_83[1]==_82){
+return;
+}
+}
+throw new Error("Unclosed tag found when looking for "+_82);
+},create_variable_node:function(_84){
+return new dd._VarNode(_84);
+},create_text_node:function(_85){
+return new dd._TextNode(_85||"");
+},getTemplate:function(_86){
+return new dd.Template(_86);
+}});
+dd.register={_registry:{attributes:[],tags:[],filters:[]},get:function(_87,_88){
+var _89=dd.register._registry[_87+"s"];
+for(var i=0,_8b;_8b=_89[i];i++){
+if(typeof _8b[0]=="string"){
+if(_8b[0]==_88){
+return _8b;
+}
+}else{
+if(_88.match(_8b[0])){
+return _8b;
+}
+}
+}
+},getAttributeTags:function(){
+var _8c=[];
+var _8d=dd.register._registry.attributes;
+for(var i=0,_8f;_8f=_8d[i];i++){
+if(_8f.length==3){
+_8c.push(_8f);
+}else{
+var fn=dojo.getObject(_8f[1]);
+if(fn&&dojo.isFunction(fn)){
+_8f.push(fn);
+_8c.push(_8f);
+}
+}
+}
+return _8c;
+},_any:function(_91,_92,_93){
+for(var _94 in _93){
+for(var i=0,fn;fn=_93[_94][i];i++){
+var key=fn;
+if(dojo.isArray(fn)){
+key=fn[0];
+fn=fn[1];
+}
+if(typeof key=="string"){
+if(key.substr(0,5)=="attr:"){
+var _98=fn;
+if(_98.substr(0,5)=="attr:"){
+_98=_98.slice(5);
+}
+dd.register._registry.attributes.push([_98.toLowerCase(),_92+"."+_94+"."+_98]);
+}
+key=key.toLowerCase();
+}
+dd.register._registry[_91].push([key,fn,_92+"."+_94]);
+}
+}
+},tags:function(_99,_9a){
+dd.register._any("tags",_99,_9a);
+},filters:function(_9b,_9c){
+dd.register._any("filters",_9b,_9c);
+}};
+var _9d=/&/g;
+var _9e=/</g;
+var _9f=/>/g;
+var _a0=/'/g;
+var _a1=/"/g;
+dd._base.escape=function(_a2){
+return dd.mark_safe(_a2.replace(_9d,"&").replace(_9e,"<").replace(_9f,">").replace(_a1,""").replace(_a0,"'"));
+};
+dd._base.safe=function(_a3){
+if(typeof _a3=="string"){
+_a3=new String(_a3);
+}
+if(typeof _a3=="object"){
+_a3.safe=true;
+}
+return _a3;
+};
+dd.mark_safe=dd._base.safe;
+dd.register.tags("dojox.dtl.tag",{"date":["now"],"logic":["if","for","ifequal","ifnotequal"],"loader":["extends","block","include","load","ssi"],"misc":["comment","debug","filter","firstof","spaceless","templatetag","widthratio","with"],"loop":["cycle","ifchanged","regroup"]});
+dd.register.filters("dojox.dtl.filter",{"dates":["date","time","timesince","timeuntil"],"htmlstrings":["linebreaks","linebreaksbr","removetags","striptags"],"integers":["add","get_digit"],"lists":["dictsort","dictsortreversed","first","join","length","length_is","random","slice","unordered_list"],"logic":["default","default_if_none","divisibleby","yesno"],"misc":["filesizeformat","pluralize","phone2numeric","pprint"],"strings":["addslashes","capfirst","center","cut","fix_ampersands","flo [...]
+dd.register.filters("dojox.dtl",{"_base":["escape","safe"]});
+})();
+}
diff --git a/dojox/dtl/contrib/data.js b/dojox/dtl/contrib/data.js
new file mode 100644
index 0000000..7389265
--- /dev/null
+++ b/dojox/dtl/contrib/data.js
@@ -0,0 +1,121 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.contrib.data"]){
+dojo._hasResource["dojox.dtl.contrib.data"]=true;
+dojo.provide("dojox.dtl.contrib.data");
+dojo.require("dojox.dtl._base");
+(function(){
+var dd=dojox.dtl;
+var _2=dd.contrib.data;
+var _3=true;
+_2._BoundItem=dojo.extend(function(_4,_5){
+this.item=_4;
+this.store=_5;
+},{get:function(_6){
+var _7=this.store;
+var _8=this.item;
+if(_6=="getLabel"){
+return _7.getLabel(_8);
+}else{
+if(_6=="getAttributes"){
+return _7.getAttributes(_8);
+}else{
+if(_6=="getIdentity"){
+if(_7.getIdentity){
+return _7.getIdentity(_8);
+}
+return "Store has no identity API";
+}else{
+if(!_7.hasAttribute(_8,_6)){
+if(_6.slice(-1)=="s"){
+if(_3){
+_3=false;
+dojo.deprecated("You no longer need an extra s to call getValues, it can be figured out automatically");
+}
+_6=_6.slice(0,-1);
+}
+if(!_7.hasAttribute(_8,_6)){
+return;
+}
+}
+var _9=_7.getValues(_8,_6);
+if(!_9){
+return;
+}
+if(!dojo.isArray(_9)){
+return new _2._BoundItem(_9,_7);
+}
+_9=dojo.map(_9,function(_a){
+if(dojo.isObject(_a)&&_7.isItem(_a)){
+return new _2._BoundItem(_a,_7);
+}
+return _a;
+});
+_9.get=_2._get;
+return _9;
+}
+}
+}
+}});
+_2._BoundItem.prototype.get.safe=true;
+_2.BindDataNode=dojo.extend(function(_b,_c,_d,_e){
+this.items=_b&&new dd._Filter(_b);
+this.query=_c&&new dd._Filter(_c);
+this.store=new dd._Filter(_d);
+this.alias=_e;
+},{render:function(_f,_10){
+var _11=this.items&&this.items.resolve(_f);
+var _12=this.query&&this.query.resolve(_f);
+var _13=this.store.resolve(_f);
+if(!_13||!_13.getFeatures){
+throw new Error("data_bind didn't receive a store");
+}
+if(_12){
+var _14=false;
+_13.fetch({query:_12,sync:true,scope:this,onComplete:function(it){
+_14=true;
+_11=it;
+}});
+if(!_14){
+throw new Error("The bind_data tag only works with a query if the store executed synchronously");
+}
+}
+var _16=[];
+if(_11){
+for(var i=0,_18;_18=_11[i];i++){
+_16.push(new _2._BoundItem(_18,_13));
+}
+}
+_f[this.alias]=_16;
+return _10;
+},unrender:function(_19,_1a){
+return _1a;
+},clone:function(){
+return this;
+}});
+dojo.mixin(_2,{_get:function(key){
+if(this.length){
+return (this[0] instanceof _2._BoundItem)?this[0].get(key):this[0][key];
+}
+},bind_data:function(_1c,_1d){
+var _1e=_1d.contents.split();
+if(_1e[2]!="to"||_1e[4]!="as"||!_1e[5]){
+throw new Error("data_bind expects the format: 'data_bind items to store as varName'");
+}
+return new _2.BindDataNode(_1e[1],null,_1e[3],_1e[5]);
+},bind_query:function(_1f,_20){
+var _21=_20.contents.split();
+if(_21[2]!="to"||_21[4]!="as"||!_21[5]){
+throw new Error("data_bind expects the format: 'bind_query query to store as varName'");
+}
+return new _2.BindDataNode(null,_21[1],_21[3],_21[5]);
+}});
+_2._get.safe=true;
+dd.register.tags("dojox.dtl.contrib",{"data":["bind_data","bind_query"]});
+})();
+}
diff --git a/dojox/dtl/contrib/dijit.js b/dojox/dtl/contrib/dijit.js
new file mode 100644
index 0000000..e4c340b
--- /dev/null
+++ b/dojox/dtl/contrib/dijit.js
@@ -0,0 +1,184 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.contrib.dijit"]){
+dojo._hasResource["dojox.dtl.contrib.dijit"]=true;
+dojo.provide("dojox.dtl.contrib.dijit");
+dojo.require("dojox.dtl.dom");
+dojo.require("dojo.parser");
+(function(){
+var dd=dojox.dtl;
+var _2=dd.contrib.dijit;
+_2.AttachNode=dojo.extend(function(_3,_4){
+this._keys=_3;
+this._object=_4;
+},{render:function(_5,_6){
+if(!this._rendered){
+this._rendered=true;
+for(var i=0,_8;_8=this._keys[i];i++){
+_5.getThis()[_8]=this._object||_6.getParent();
+}
+}
+return _6;
+},unrender:function(_9,_a){
+if(this._rendered){
+this._rendered=false;
+for(var i=0,_c;_c=this._keys[i];i++){
+if(_9.getThis()[_c]===(this._object||_a.getParent())){
+delete _9.getThis()[_c];
+}
+}
+}
+return _a;
+},clone:function(_d){
+return new this.constructor(this._keys,this._object);
+}});
+_2.EventNode=dojo.extend(function(_e,_f){
+this._command=_e;
+var _10,_11=_e.split(/\s*,\s*/);
+var _12=dojo.trim;
+var _13=[];
+var fns=[];
+while(_10=_11.pop()){
+if(_10){
+var fn=null;
+if(_10.indexOf(":")!=-1){
+var _16=_10.split(":");
+_10=_12(_16[0]);
+fn=_12(_16.slice(1).join(":"));
+}else{
+_10=_12(_10);
+}
+if(!fn){
+fn=_10;
+}
+_13.push(_10);
+fns.push(fn);
+}
+}
+this._types=_13;
+this._fns=fns;
+this._object=_f;
+this._rendered=[];
+},{_clear:false,render:function(_17,_18){
+for(var i=0,_1a;_1a=this._types[i];i++){
+if(!this._clear&&!this._object){
+_18.getParent()[_1a]=null;
+}
+var fn=this._fns[i];
+var _1c;
+if(fn.indexOf(" ")!=-1){
+if(this._rendered[i]){
+dojo.disconnect(this._rendered[i]);
+this._rendered[i]=false;
+}
+_1c=dojo.map(fn.split(" ").slice(1),function(_1d){
+return new dd._Filter(_1d).resolve(_17);
+});
+fn=fn.split(" ",2)[0];
+}
+if(!this._rendered[i]){
+if(!this._object){
+this._rendered[i]=_18.addEvent(_17,_1a,fn,_1c);
+}else{
+this._rendered[i]=dojo.connect(this._object,_1a,_17.getThis(),fn);
+}
+}
+}
+this._clear=true;
+return _18;
+},unrender:function(_1e,_1f){
+while(this._rendered.length){
+dojo.disconnect(this._rendered.pop());
+}
+return _1f;
+},clone:function(){
+return new this.constructor(this._command,this._object);
+}});
+function _20(n1){
+var n2=n1.cloneNode(true);
+if(dojo.isIE){
+dojo.query("script",n2).forEach("item.text = this[index].text;",dojo.query("script",n1));
+}
+return n2;
+};
+_2.DojoTypeNode=dojo.extend(function(_23,_24){
+this._node=_23;
+this._parsed=_24;
+var _25=_23.getAttribute("dojoAttachEvent");
+if(_25){
+this._events=new _2.EventNode(dojo.trim(_25));
+}
+var _26=_23.getAttribute("dojoAttachPoint");
+if(_26){
+this._attach=new _2.AttachNode(dojo.trim(_26).split(/\s*,\s*/));
+}
+if(!_24){
+this._dijit=dojo.parser.instantiate([_20(_23)])[0];
+}else{
+_23=_20(_23);
+var old=_2.widgetsInTemplate;
+_2.widgetsInTemplate=false;
+this._template=new dd.DomTemplate(_23);
+_2.widgetsInTemplate=old;
+}
+},{render:function(_28,_29){
+if(this._parsed){
+var _2a=new dd.DomBuffer();
+this._template.render(_28,_2a);
+var _2b=_20(_2a.getRootNode());
+var div=document.createElement("div");
+div.appendChild(_2b);
+var _2d=div.innerHTML;
+div.removeChild(_2b);
+if(_2d!=this._rendered){
+this._rendered=_2d;
+if(this._dijit){
+this._dijit.destroyRecursive();
+}
+this._dijit=dojo.parser.instantiate([_2b])[0];
+}
+}
+var _2e=this._dijit.domNode;
+if(this._events){
+this._events._object=this._dijit;
+this._events.render(_28,_29);
+}
+if(this._attach){
+this._attach._object=this._dijit;
+this._attach.render(_28,_29);
+}
+return _29.concat(_2e);
+},unrender:function(_2f,_30){
+return _30.remove(this._dijit.domNode);
+},clone:function(){
+return new this.constructor(this._node,this._parsed);
+}});
+dojo.mixin(_2,{widgetsInTemplate:true,dojoAttachPoint:function(_31,_32){
+return new _2.AttachNode(_32.contents.slice(16).split(/\s*,\s*/));
+},dojoAttachEvent:function(_33,_34){
+return new _2.EventNode(_34.contents.slice(16));
+},dojoType:function(_35,_36){
+var _37=false;
+if(_36.contents.slice(-7)==" parsed"){
+_37=true;
+}
+var _38=_36.contents.slice(9);
+var _39=_37?_38.slice(0,-7):_38.toString();
+if(_2.widgetsInTemplate){
+var _3a=_35.swallowNode();
+_3a.setAttribute("dojoType",_39);
+return new _2.DojoTypeNode(_3a,_37);
+}
+return new dd.AttributeNode("dojoType",_39);
+},on:function(_3b,_3c){
+var _3d=_3c.contents.split();
+return new _2.EventNode(_3d[0]+":"+_3d.slice(1).join(" "));
+}});
+dd.register.tags("dojox.dtl.contrib",{"dijit":["attr:dojoType","attr:dojoAttachPoint",["attr:attach","dojoAttachPoint"],"attr:dojoAttachEvent",[/(attr:)?on(click|key(up))/i,"on"]]});
+})();
+}
diff --git a/dojox/dtl/contrib/dom.js b/dojox/dtl/contrib/dom.js
new file mode 100644
index 0000000..dd74cb7
--- /dev/null
+++ b/dojox/dtl/contrib/dom.js
@@ -0,0 +1,131 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.contrib.dom"]){
+dojo._hasResource["dojox.dtl.contrib.dom"]=true;
+dojo.provide("dojox.dtl.contrib.dom");
+dojo.require("dojox.dtl.dom");
+(function(){
+var dd=dojox.dtl;
+var _2=dd.contrib.dom;
+var _3={render:function(){
+return this.contents;
+}};
+_2.StyleNode=dojo.extend(function(_4){
+this.contents={};
+this._current={};
+this._styles=_4;
+for(var _5 in _4){
+if(_4[_5].indexOf("{{")!=-1){
+var _6=new dd.Template(_4[_5]);
+}else{
+var _6=dojo.delegate(_3);
+_6.contents=_4[_5];
+}
+this.contents[_5]=_6;
+}
+},{render:function(_7,_8){
+for(var _9 in this.contents){
+var _a=this.contents[_9].render(_7);
+if(this._current[_9]!=_a){
+dojo.style(_8.getParent(),_9,this._current[_9]=_a);
+}
+}
+return _8;
+},unrender:function(_b,_c){
+this._current={};
+return _c;
+},clone:function(_d){
+return new this.constructor(this._styles);
+}});
+_2.BufferNode=dojo.extend(function(_e,_f){
+this.nodelist=_e;
+this.options=_f;
+},{_swap:function(_10,_11){
+if(!this.swapped&&this.parent.parentNode){
+if(_10=="node"){
+if((_11.nodeType==3&&!this.options.text)||(_11.nodeType==1&&!this.options.node)){
+return;
+}
+}else{
+if(_10=="class"){
+if(_10!="class"){
+return;
+}
+}
+}
+this.onAddNode&&dojo.disconnect(this.onAddNode);
+this.onRemoveNode&&dojo.disconnect(this.onRemoveNode);
+this.onChangeAttribute&&dojo.disconnect(this.onChangeAttribute);
+this.onChangeData&&dojo.disconnect(this.onChangeData);
+this.swapped=this.parent.cloneNode(true);
+this.parent.parentNode.replaceChild(this.swapped,this.parent);
+}
+},render:function(_12,_13){
+this.parent=_13.getParent();
+if(this.options.node){
+this.onAddNode=dojo.connect(_13,"onAddNode",dojo.hitch(this,"_swap","node"));
+this.onRemoveNode=dojo.connect(_13,"onRemoveNode",dojo.hitch(this,"_swap","node"));
+}
+if(this.options.text){
+this.onChangeData=dojo.connect(_13,"onChangeData",dojo.hitch(this,"_swap","node"));
+}
+if(this.options["class"]){
+this.onChangeAttribute=dojo.connect(_13,"onChangeAttribute",dojo.hitch(this,"_swap","class"));
+}
+_13=this.nodelist.render(_12,_13);
+if(this.swapped){
+this.swapped.parentNode.replaceChild(this.parent,this.swapped);
+dojo.destroy(this.swapped);
+}else{
+this.onAddNode&&dojo.disconnect(this.onAddNode);
+this.onRemoveNode&&dojo.disconnect(this.onRemoveNode);
+this.onChangeAttribute&&dojo.disconnect(this.onChangeAttribute);
+this.onChangeData&&dojo.disconnect(this.onChangeData);
+}
+delete this.parent;
+delete this.swapped;
+return _13;
+},unrender:function(_14,_15){
+return this.nodelist.unrender(_14,_15);
+},clone:function(_16){
+return new this.constructor(this.nodelist.clone(_16),this.options);
+}});
+dojo.mixin(_2,{buffer:function(_17,_18){
+var _19=_18.contents.split().slice(1);
+var _1a={};
+var _1b=false;
+for(var i=_19.length;i--;){
+_1b=true;
+_1a[_19[i]]=true;
+}
+if(!_1b){
+_1a.node=true;
+}
+var _1d=_17.parse(["endbuffer"]);
+_17.next_token();
+return new _2.BufferNode(_1d,_1a);
+},html:function(_1e,_1f){
+dojo.deprecated("{% html someVariable %}","Use {{ someVariable|safe }} instead");
+return _1e.create_variable_node(_1f.contents.slice(5)+"|safe");
+},style_:function(_20,_21){
+var _22={};
+_21=_21.contents.replace(/^style\s+/,"");
+var _23=_21.split(/\s*;\s*/g);
+for(var i=0,_25;_25=_23[i];i++){
+var _26=_25.split(/\s*:\s*/g);
+var key=_26[0];
+var _28=dojo.trim(_26[1]);
+if(_28){
+_22[key]=_28;
+}
+}
+return new _2.StyleNode(_22);
+}});
+dd.register.tags("dojox.dtl.contrib",{"dom":["html","attr:style","buffer"]});
+})();
+}
diff --git a/dojox/dtl/contrib/html.js b/dojox/dtl/contrib/html.js
new file mode 100644
index 0000000..a8b7453
--- /dev/null
+++ b/dojox/dtl/contrib/html.js
@@ -0,0 +1,13 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.contrib.html"]){
+dojo._hasResource["dojox.dtl.contrib.html"]=true;
+dojo.provide("dojox.dtl.contrib.html");
+dojo.require("dojox.dtl.contrib.dom");
+dojo.deprecated("dojox.dtl.html","All packages and classes in dojox.dtl that start with Html or html have been renamed to Dom or dom");
+}
diff --git a/dojox/dtl/contrib/objects.js b/dojox/dtl/contrib/objects.js
new file mode 100644
index 0000000..59cce93
--- /dev/null
+++ b/dojox/dtl/contrib/objects.js
@@ -0,0 +1,15 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.contrib.objects"]){
+dojo._hasResource["dojox.dtl.contrib.objects"]=true;
+dojo.provide("dojox.dtl.contrib.objects");
+dojo.mixin(dojox.dtl.contrib.objects,{key:function(_1,_2){
+return _1[_2];
+}});
+dojox.dtl.register.filters("dojox.dtl.contrib",{"objects":["key"]});
+}
diff --git a/dojox/dtl/dom.js b/dojox/dtl/dom.js
new file mode 100644
index 0000000..7c62cbe
--- /dev/null
+++ b/dojox/dtl/dom.js
@@ -0,0 +1,864 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.dom"]){
+dojo._hasResource["dojox.dtl.dom"]=true;
+dojo.provide("dojox.dtl.dom");
+dojo.require("dojox.dtl._base");
+dojo.require("dojox.dtl.Context");
+(function(){
+var dd=dojox.dtl;
+dd.BOOLS={checked:1,disabled:1,readonly:1};
+dd.TOKEN_CHANGE=-11;
+dd.TOKEN_ATTR=-12;
+dd.TOKEN_CUSTOM=-13;
+dd.TOKEN_NODE=1;
+var _2=dd.text;
+var _3=dd.dom={_attributes:{},_uppers:{},_re4:/^function anonymous\(\)\s*{\s*(.*)\s*}$/,_reTrim:/(?:^[\n\s]*(\{%)?\s*|\s*(%\})?[\n\s]*$)/g,_reSplit:/\s*%\}[\n\s]*\{%\s*/g,getTemplate:function(_4){
+if(typeof this._commentable=="undefined"){
+this._commentable=false;
+var _5=document.createElement("div");
+_5.innerHTML="<!--Test comment handling, and long comments, using comments whenever possible.-->";
+if(_5.childNodes.length&&_5.childNodes[0].nodeType==8&&_5.childNodes[0].data=="comment"){
+this._commentable=true;
+}
+}
+if(!this._commentable){
+_4=_4.replace(/<!--({({|%).*?(%|})})-->/g,"$1");
+}
+if(dojo.isIE){
+_4=_4.replace(/\b(checked|disabled|readonly|style)="/g,"t$1=\"");
+}
+_4=_4.replace(/\bstyle="/g,"tstyle=\"");
+var _6;
+var _7=dojo.isWebKit;
+var _8=[[true,"select","option"],[_7,"tr","td|th"],[_7,"thead","tr","th"],[_7,"tbody","tr","td"],[_7,"table","tbody|thead|tr","tr","td"]];
+var _9=[];
+for(var i=0,_b;_b=_8[i];i++){
+if(!_b[0]){
+continue;
+}
+if(_4.indexOf("<"+_b[1])!=-1){
+var _c=new RegExp("<"+_b[1]+"(?:.|\n)*?>((?:.|\n)+?)</"+_b[1]+">","ig");
+tagLoop:
+while(_6=_c.exec(_4)){
+var _d=_b[2].split("|");
+var _e=[];
+for(var j=0,_10;_10=_d[j];j++){
+_e.push("<"+_10+"(?:.|\n)*?>(?:.|\n)*?</"+_10+">");
+}
+var _11=[];
+var _12=dojox.string.tokenize(_6[1],new RegExp("("+_e.join("|")+")","ig"),function(_13){
+var tag=/<(\w+)/.exec(_13)[1];
+if(!_11[tag]){
+_11[tag]=true;
+_11.push(tag);
+}
+return {data:_13};
+});
+if(_11.length){
+var tag=(_11.length==1)?_11[0]:_b[2].split("|")[0];
+var _16=[];
+for(var j=0,jl=_12.length;j<jl;j++){
+var _18=_12[j];
+if(dojo.isObject(_18)){
+_16.push(_18.data);
+}else{
+var _19=_18.replace(this._reTrim,"");
+if(!_19){
+continue;
+}
+_18=_19.split(this._reSplit);
+for(var k=0,kl=_18.length;k<kl;k++){
+var _1c="";
+for(var p=2,pl=_b.length;p<pl;p++){
+if(p==2){
+_1c+="<"+tag+" dtlinstruction=\"{% "+_18[k].replace("\"","\\\"")+" %}\">";
+}else{
+if(tag==_b[p]){
+continue;
+}else{
+_1c+="<"+_b[p]+">";
+}
+}
+}
+_1c+="DTL";
+for(var p=_b.length-1;p>1;p--){
+if(p==2){
+_1c+="</"+tag+">";
+}else{
+if(tag==_b[p]){
+continue;
+}else{
+_1c+="</"+_b[p]+">";
+}
+}
+}
+_16.push("ÿ"+_9.length);
+_9.push(_1c);
+}
+}
+}
+_4=_4.replace(_6[1],_16.join(""));
+}
+}
+}
+}
+for(var i=_9.length;i--;){
+_4=_4.replace("ÿ"+i,_9[i]);
+}
+var re=/\b([a-zA-Z_:][a-zA-Z0-9_\-\.:]*)=['"]/g;
+while(_6=re.exec(_4)){
+var _20=_6[1].toLowerCase();
+if(_20=="dtlinstruction"){
+continue;
+}
+if(_20!=_6[1]){
+this._uppers[_20]=_6[1];
+}
+this._attributes[_20]=true;
+}
+var _5=document.createElement("div");
+_5.innerHTML=_4;
+var _21={nodes:[]};
+while(_5.childNodes.length){
+_21.nodes.push(_5.removeChild(_5.childNodes[0]));
+}
+return _21;
+},tokenize:function(_22){
+var _23=[];
+for(var i=0,_25;_25=_22[i++];){
+if(_25.nodeType!=1){
+this.__tokenize(_25,_23);
+}else{
+this._tokenize(_25,_23);
+}
+}
+return _23;
+},_swallowed:[],_tokenize:function(_26,_27){
+var _28=false;
+var _29=this._swallowed;
+var i,j,tag,_2d;
+if(!_27.first){
+_28=_27.first=true;
+var _2e=dd.register.getAttributeTags();
+for(i=0;tag=_2e[i];i++){
+try{
+(tag[2])({swallowNode:function(){
+throw 1;
+}},new dd.Token(dd.TOKEN_ATTR,""));
+}
+catch(e){
+_29.push(tag);
+}
+}
+}
+for(i=0;tag=_29[i];i++){
+var _2f=_26.getAttribute(tag[0]);
+if(_2f){
+var _29=false;
+var _30=(tag[2])({swallowNode:function(){
+_29=true;
+return _26;
+}},new dd.Token(dd.TOKEN_ATTR,tag[0]+" "+_2f));
+if(_29){
+if(_26.parentNode&&_26.parentNode.removeChild){
+_26.parentNode.removeChild(_26);
+}
+_27.push([dd.TOKEN_CUSTOM,_30]);
+return;
+}
+}
+}
+var _31=[];
+if(dojo.isIE&&_26.tagName=="SCRIPT"){
+_31.push({nodeType:3,data:_26.text});
+_26.text="";
+}else{
+for(i=0;_2d=_26.childNodes[i];i++){
+_31.push(_2d);
+}
+}
+_27.push([dd.TOKEN_NODE,_26]);
+var _32=false;
+if(_31.length){
+_27.push([dd.TOKEN_CHANGE,_26]);
+_32=true;
+}
+for(var key in this._attributes){
+var _34=false;
+var _35="";
+if(key=="class"){
+_35=_26.className||_35;
+}else{
+if(key=="for"){
+_35=_26.htmlFor||_35;
+}else{
+if(key=="value"&&_26.value==_26.innerHTML){
+continue;
+}else{
+if(_26.getAttribute){
+_35=_26.getAttribute(key,2)||_35;
+if(key=="href"||key=="src"){
+if(dojo.isIE){
+var _36=location.href.lastIndexOf(location.hash);
+var _37=location.href.substring(0,_36).split("/");
+_37.pop();
+_37=_37.join("/")+"/";
+if(_35.indexOf(_37)==0){
+_35=_35.replace(_37,"");
+}
+_35=decodeURIComponent(_35);
+}
+}else{
+if(key=="tstyle"){
+_34=key;
+key="style";
+}else{
+if(dd.BOOLS[key.slice(1)]&&dojo.trim(_35)){
+key=key.slice(1);
+}else{
+if(this._uppers[key]&&dojo.trim(_35)){
+_34=this._uppers[key];
+}
+}
+}
+}
+}
+}
+}
+}
+if(_34){
+_26.setAttribute(_34,"");
+_26.removeAttribute(_34);
+}
+if(typeof _35=="function"){
+_35=_35.toString().replace(this._re4,"$1");
+}
+if(!_32){
+_27.push([dd.TOKEN_CHANGE,_26]);
+_32=true;
+}
+_27.push([dd.TOKEN_ATTR,_26,key,_35]);
+}
+for(i=0,_2d;_2d=_31[i];i++){
+if(_2d.nodeType==1){
+var _38=_2d.getAttribute("dtlinstruction");
+if(_38){
+_2d.parentNode.removeChild(_2d);
+_2d={nodeType:8,data:_38};
+}
+}
+this.__tokenize(_2d,_27);
+}
+if(!_28&&_26.parentNode&&_26.parentNode.tagName){
+if(_32){
+_27.push([dd.TOKEN_CHANGE,_26,true]);
+}
+_27.push([dd.TOKEN_CHANGE,_26.parentNode]);
+_26.parentNode.removeChild(_26);
+}else{
+_27.push([dd.TOKEN_CHANGE,_26,true,true]);
+}
+},__tokenize:function(_39,_3a){
+var _3b=_39.data;
+switch(_39.nodeType){
+case 1:
+this._tokenize(_39,_3a);
+return;
+case 3:
+if(_3b.match(/[^\s\n]/)&&(_3b.indexOf("{{")!=-1||_3b.indexOf("{%")!=-1)){
+var _3c=_2.tokenize(_3b);
+for(var j=0,_3e;_3e=_3c[j];j++){
+if(typeof _3e=="string"){
+_3a.push([dd.TOKEN_TEXT,_3e]);
+}else{
+_3a.push(_3e);
+}
+}
+}else{
+_3a.push([_39.nodeType,_39]);
+}
+if(_39.parentNode){
+_39.parentNode.removeChild(_39);
+}
+return;
+case 8:
+if(_3b.indexOf("{%")==0){
+var _3e=dojo.trim(_3b.slice(2,-2));
+if(_3e.substr(0,5)=="load "){
+var _3f=dojo.trim(_3e).split(/\s+/g);
+for(var i=1,_41;_41=_3f[i];i++){
+dojo["require"](_41);
+}
+}
+_3a.push([dd.TOKEN_BLOCK,_3e]);
+}
+if(_3b.indexOf("{{")==0){
+_3a.push([dd.TOKEN_VAR,dojo.trim(_3b.slice(2,-2))]);
+}
+if(_39.parentNode){
+_39.parentNode.removeChild(_39);
+}
+return;
+}
+}};
+dd.DomTemplate=dojo.extend(function(obj){
+if(!obj.nodes){
+var _43=dojo.byId(obj);
+if(_43&&_43.nodeType==1){
+dojo.forEach(["class","src","href","name","value"],function(_44){
+_3._attributes[_44]=true;
+});
+obj={nodes:[_43]};
+}else{
+if(typeof obj=="object"){
+obj=_2.getTemplateString(obj);
+}
+obj=_3.getTemplate(obj);
+}
+}
+var _45=_3.tokenize(obj.nodes);
+if(dd.tests){
+this.tokens=_45.slice(0);
+}
+var _46=new dd._DomParser(_45);
+this.nodelist=_46.parse();
+},{_count:0,_re:/\bdojo:([a-zA-Z0-9_]+)\b/g,setClass:function(str){
+this.getRootNode().className=str;
+},getRootNode:function(){
+return this.buffer.rootNode;
+},getBuffer:function(){
+return new dd.DomBuffer();
+},render:function(_48,_49){
+_49=this.buffer=_49||this.getBuffer();
+this.rootNode=null;
+var _4a=this.nodelist.render(_48||new dd.Context({}),_49);
+for(var i=0,_4c;_4c=_49._cache[i];i++){
+if(_4c._cache){
+_4c._cache.length=0;
+}
+}
+return _4a;
+},unrender:function(_4d,_4e){
+return this.nodelist.unrender(_4d,_4e);
+}});
+dd.DomBuffer=dojo.extend(function(_4f){
+this._parent=_4f;
+this._cache=[];
+},{concat:function(_50){
+var _51=this._parent;
+if(_51&&_50.parentNode&&_50.parentNode===_51&&!_51._dirty){
+return this;
+}
+if(_50.nodeType==1&&!this.rootNode){
+this.rootNode=_50||true;
+return this;
+}
+if(!_51){
+if(_50.nodeType==3&&dojo.trim(_50.data)){
+throw new Error("Text should not exist outside of the root node in template");
+}
+return this;
+}
+if(this._closed){
+if(_50.nodeType==3&&!dojo.trim(_50.data)){
+return this;
+}else{
+throw new Error("Content should not exist outside of the root node in template");
+}
+}
+if(_51._dirty){
+if(_50._drawn&&_50.parentNode==_51){
+var _52=_51._cache;
+if(_52){
+for(var i=0,_54;_54=_52[i];i++){
+this.onAddNode&&this.onAddNode(_54);
+_51.insertBefore(_54,_50);
+this.onAddNodeComplete&&this.onAddNodeComplete(_54);
+}
+_52.length=0;
+}
+}
+_51._dirty=false;
+}
+if(!_51._cache){
+_51._cache=[];
+this._cache.push(_51);
+}
+_51._dirty=true;
+_51._cache.push(_50);
+return this;
+},remove:function(obj){
+if(typeof obj=="string"){
+if(this._parent){
+this._parent.removeAttribute(obj);
+}
+}else{
+if(obj.nodeType==1&&!this.getRootNode()&&!this._removed){
+this._removed=true;
+return this;
+}
+if(obj.parentNode){
+this.onRemoveNode&&this.onRemoveNode(obj);
+if(obj.parentNode){
+obj.parentNode.removeChild(obj);
+}
+}
+}
+return this;
+},setAttribute:function(key,_57){
+var old=dojo.attr(this._parent,key);
+if(this.onChangeAttribute&&old!=_57){
+this.onChangeAttribute(this._parent,key,old,_57);
+}
+if(key=="style"){
+this._parent.style.cssText=_57;
+}else{
+dojo.attr(this._parent,key,_57);
+}
+return this;
+},addEvent:function(_59,_5a,fn,_5c){
+if(!_59.getThis()){
+throw new Error("You must use Context.setObject(instance)");
+}
+this.onAddEvent&&this.onAddEvent(this.getParent(),_5a,fn);
+var _5d=fn;
+if(dojo.isArray(_5c)){
+_5d=function(e){
+this[fn].apply(this,[e].concat(_5c));
+};
+}
+return dojo.connect(this.getParent(),_5a,_59.getThis(),_5d);
+},setParent:function(_5f,up,_61){
+if(!this._parent){
+this._parent=this._first=_5f;
+}
+if(up&&_61&&_5f===this._first){
+this._closed=true;
+}
+if(up){
+var _62=this._parent;
+var _63="";
+var ie=dojo.isIE&&_62.tagName=="SCRIPT";
+if(ie){
+_62.text="";
+}
+if(_62._dirty){
+var _65=_62._cache;
+var _66=(_62.tagName=="SELECT"&&!_62.options.length);
+for(var i=0,_68;_68=_65[i];i++){
+if(_68!==_62){
+this.onAddNode&&this.onAddNode(_68);
+if(ie){
+_63+=_68.data;
+}else{
+_62.appendChild(_68);
+if(_66&&_68.defaultSelected&&i){
+_66=i;
+}
+}
+this.onAddNodeComplete&&this.onAddNodeComplete(_68);
+}
+}
+if(_66){
+_62.options.selectedIndex=(typeof _66=="number")?_66:0;
+}
+_65.length=0;
+_62._dirty=false;
+}
+if(ie){
+_62.text=_63;
+}
+}
+this._parent=_5f;
+this.onSetParent&&this.onSetParent(_5f,up,_61);
+return this;
+},getParent:function(){
+return this._parent;
+},getRootNode:function(){
+return this.rootNode;
+}});
+dd._DomNode=dojo.extend(function(_69){
+this.contents=_69;
+},{render:function(_6a,_6b){
+this._rendered=true;
+return _6b.concat(this.contents);
+},unrender:function(_6c,_6d){
+if(!this._rendered){
+return _6d;
+}
+this._rendered=false;
+return _6d.remove(this.contents);
+},clone:function(_6e){
+return new this.constructor(this.contents);
+}});
+dd._DomNodeList=dojo.extend(function(_6f){
+this.contents=_6f||[];
+},{push:function(_70){
+this.contents.push(_70);
+},unshift:function(_71){
+this.contents.unshift(_71);
+},render:function(_72,_73,_74){
+_73=_73||dd.DomTemplate.prototype.getBuffer();
+if(_74){
+var _75=_73.getParent();
+}
+for(var i=0;i<this.contents.length;i++){
+_73=this.contents[i].render(_72,_73);
+if(!_73){
+throw new Error("Template node render functions must return their buffer");
+}
+}
+if(_75){
+_73.setParent(_75);
+}
+return _73;
+},dummyRender:function(_77,_78,_79){
+var div=document.createElement("div");
+var _7b=_78.getParent();
+var old=_7b._clone;
+_7b._clone=div;
+var _7d=this.clone(_78,div);
+if(old){
+_7b._clone=old;
+}else{
+_7b._clone=null;
+}
+_78=dd.DomTemplate.prototype.getBuffer();
+_7d.unshift(new dd.ChangeNode(div));
+_7d.unshift(new dd._DomNode(div));
+_7d.push(new dd.ChangeNode(div,true));
+_7d.render(_77,_78);
+if(_79){
+return _78.getRootNode();
+}
+var _7e=div.innerHTML;
+return (dojo.isIE)?_7e.replace(/\s*_(dirty|clone)="[^"]*"/g,""):_7e;
+},unrender:function(_7f,_80,_81){
+if(_81){
+var _82=_80.getParent();
+}
+for(var i=0;i<this.contents.length;i++){
+_80=this.contents[i].unrender(_7f,_80);
+if(!_80){
+throw new Error("Template node render functions must return their buffer");
+}
+}
+if(_82){
+_80.setParent(_82);
+}
+return _80;
+},clone:function(_84){
+var _85=_84.getParent();
+var _86=this.contents;
+var _87=new dd._DomNodeList();
+var _88=[];
+for(var i=0;i<_86.length;i++){
+var _8a=_86[i].clone(_84);
+if(_8a instanceof dd.ChangeNode||_8a instanceof dd._DomNode){
+var _8b=_8a.contents._clone;
+if(_8b){
+_8a.contents=_8b;
+}else{
+if(_85!=_8a.contents&&_8a instanceof dd._DomNode){
+var _8c=_8a.contents;
+_8a.contents=_8a.contents.cloneNode(false);
+_84.onClone&&_84.onClone(_8c,_8a.contents);
+_88.push(_8c);
+_8c._clone=_8a.contents;
+}
+}
+}
+_87.push(_8a);
+}
+for(var i=0,_8a;_8a=_88[i];i++){
+_8a._clone=null;
+}
+return _87;
+},rtrim:function(){
+while(1){
+var i=this.contents.length-1;
+if(this.contents[i] instanceof dd._DomTextNode&&this.contents[i].isEmpty()){
+this.contents.pop();
+}else{
+break;
+}
+}
+return this;
+}});
+dd._DomVarNode=dojo.extend(function(str){
+this.contents=new dd._Filter(str);
+},{render:function(_8f,_90){
+var str=this.contents.resolve(_8f);
+var _92="text";
+if(str){
+if(str.render&&str.getRootNode){
+_92="injection";
+}else{
+if(str.safe){
+if(str.nodeType){
+_92="node";
+}else{
+if(str.toString){
+str=str.toString();
+_92="html";
+}
+}
+}
+}
+}
+if(this._type&&_92!=this._type){
+this.unrender(_8f,_90);
+}
+this._type=_92;
+switch(_92){
+case "text":
+this._rendered=true;
+this._txt=this._txt||document.createTextNode(str);
+if(this._txt.data!=str){
+var old=this._txt.data;
+this._txt.data=str;
+_90.onChangeData&&_90.onChangeData(this._txt,old,this._txt.data);
+}
+return _90.concat(this._txt);
+case "injection":
+var _94=str.getRootNode();
+if(this._rendered&&_94!=this._root){
+_90=this.unrender(_8f,_90);
+}
+this._root=_94;
+var _95=this._injected=new dd._DomNodeList();
+_95.push(new dd.ChangeNode(_90.getParent()));
+_95.push(new dd._DomNode(_94));
+_95.push(str);
+_95.push(new dd.ChangeNode(_90.getParent()));
+this._rendered=true;
+return _95.render(_8f,_90);
+case "node":
+this._rendered=true;
+if(this._node&&this._node!=str&&this._node.parentNode&&this._node.parentNode===_90.getParent()){
+this._node.parentNode.removeChild(this._node);
+}
+this._node=str;
+return _90.concat(str);
+case "html":
+if(this._rendered&&this._src!=str){
+_90=this.unrender(_8f,_90);
+}
+this._src=str;
+if(!this._rendered){
+this._rendered=true;
+this._html=this._html||[];
+var div=(this._div=this._div||document.createElement("div"));
+div.innerHTML=str;
+var _97=div.childNodes;
+while(_97.length){
+var _98=div.removeChild(_97[0]);
+this._html.push(_98);
+_90=_90.concat(_98);
+}
+}
+return _90;
+default:
+return _90;
+}
+},unrender:function(_99,_9a){
+if(!this._rendered){
+return _9a;
+}
+this._rendered=false;
+switch(this._type){
+case "text":
+return _9a.remove(this._txt);
+case "injection":
+return this._injection.unrender(_99,_9a);
+case "node":
+if(this._node.parentNode===_9a.getParent()){
+return _9a.remove(this._node);
+}
+return _9a;
+case "html":
+for(var i=0,l=this._html.length;i<l;i++){
+_9a=_9a.remove(this._html[i]);
+}
+return _9a;
+default:
+return _9a;
+}
+},clone:function(){
+return new this.constructor(this.contents.getExpression());
+}});
+dd.ChangeNode=dojo.extend(function(_9d,up,_9f){
+this.contents=_9d;
+this.up=up;
+this.root=_9f;
+},{render:function(_a0,_a1){
+return _a1.setParent(this.contents,this.up,this.root);
+},unrender:function(_a2,_a3){
+if(!_a3.getParent()){
+return _a3;
+}
+return _a3.setParent(this.contents);
+},clone:function(){
+return new this.constructor(this.contents,this.up,this.root);
+}});
+dd.AttributeNode=dojo.extend(function(key,_a5){
+this.key=key;
+this.value=_a5;
+this.contents=_a5;
+if(this._pool[_a5]){
+this.nodelist=this._pool[_a5];
+}else{
+if(!(this.nodelist=dd.quickFilter(_a5))){
+this.nodelist=(new dd.Template(_a5,true)).nodelist;
+}
+this._pool[_a5]=this.nodelist;
+}
+this.contents="";
+},{_pool:{},render:function(_a6,_a7){
+var key=this.key;
+var _a9=this.nodelist.dummyRender(_a6);
+if(dd.BOOLS[key]){
+_a9=!(_a9=="false"||_a9=="undefined"||!_a9);
+}
+if(_a9!==this.contents){
+this.contents=_a9;
+return _a7.setAttribute(key,_a9);
+}
+return _a7;
+},unrender:function(_aa,_ab){
+this.contents="";
+return _ab.remove(this.key);
+},clone:function(_ac){
+return new this.constructor(this.key,this.value);
+}});
+dd._DomTextNode=dojo.extend(function(str){
+this.contents=document.createTextNode(str);
+this.upcoming=str;
+},{set:function(_ae){
+this.upcoming=_ae;
+return this;
+},render:function(_af,_b0){
+if(this.contents.data!=this.upcoming){
+var old=this.contents.data;
+this.contents.data=this.upcoming;
+_b0.onChangeData&&_b0.onChangeData(this.contents,old,this.upcoming);
+}
+return _b0.concat(this.contents);
+},unrender:function(_b2,_b3){
+return _b3.remove(this.contents);
+},isEmpty:function(){
+return !dojo.trim(this.contents.data);
+},clone:function(){
+return new this.constructor(this.contents.data);
+}});
+dd._DomParser=dojo.extend(function(_b4){
+this.contents=_b4;
+},{i:0,parse:function(_b5){
+var _b6={};
+var _b7=this.contents;
+if(!_b5){
+_b5=[];
+}
+for(var i=0;i<_b5.length;i++){
+_b6[_b5[i]]=true;
+}
+var _b9=new dd._DomNodeList();
+while(this.i<_b7.length){
+var _ba=_b7[this.i++];
+var _bb=_ba[0];
+var _bc=_ba[1];
+if(_bb==dd.TOKEN_CUSTOM){
+_b9.push(_bc);
+}else{
+if(_bb==dd.TOKEN_CHANGE){
+var _bd=new dd.ChangeNode(_bc,_ba[2],_ba[3]);
+_bc[_bd.attr]=_bd;
+_b9.push(_bd);
+}else{
+if(_bb==dd.TOKEN_ATTR){
+var fn=_2.getTag("attr:"+_ba[2],true);
+if(fn&&_ba[3]){
+if(_ba[3].indexOf("{%")!=-1||_ba[3].indexOf("{{")!=-1){
+_bc.setAttribute(_ba[2],"");
+}
+_b9.push(fn(null,new dd.Token(_bb,_ba[2]+" "+_ba[3])));
+}else{
+if(dojo.isString(_ba[3])){
+if(_ba[2]=="style"||_ba[3].indexOf("{%")!=-1||_ba[3].indexOf("{{")!=-1){
+_b9.push(new dd.AttributeNode(_ba[2],_ba[3]));
+}else{
+if(dojo.trim(_ba[3])){
+try{
+dojo.attr(_bc,_ba[2],_ba[3]);
+}
+catch(e){
+}
+}
+}
+}
+}
+}else{
+if(_bb==dd.TOKEN_NODE){
+var fn=_2.getTag("node:"+_bc.tagName.toLowerCase(),true);
+if(fn){
+_b9.push(fn(null,new dd.Token(_bb,_bc),_bc.tagName.toLowerCase()));
+}
+_b9.push(new dd._DomNode(_bc));
+}else{
+if(_bb==dd.TOKEN_VAR){
+_b9.push(new dd._DomVarNode(_bc));
+}else{
+if(_bb==dd.TOKEN_TEXT){
+_b9.push(new dd._DomTextNode(_bc.data||_bc));
+}else{
+if(_bb==dd.TOKEN_BLOCK){
+if(_b6[_bc]){
+--this.i;
+return _b9;
+}
+var cmd=_bc.split(/\s+/g);
+if(cmd.length){
+cmd=cmd[0];
+var fn=_2.getTag(cmd);
+if(typeof fn!="function"){
+throw new Error("Function not found for "+cmd);
+}
+var tpl=fn(this,new dd.Token(_bb,_bc));
+if(tpl){
+_b9.push(tpl);
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+if(_b5.length){
+throw new Error("Could not find closing tag(s): "+_b5.toString());
+}
+return _b9;
+},next_token:function(){
+var _c1=this.contents[this.i++];
+return new dd.Token(_c1[0],_c1[1]);
+},delete_first_token:function(){
+this.i++;
+},skip_past:function(_c2){
+return dd._Parser.prototype.skip_past.call(this,_c2);
+},create_variable_node:function(_c3){
+return new dd._DomVarNode(_c3);
+},create_text_node:function(_c4){
+return new dd._DomTextNode(_c4||"");
+},getTemplate:function(loc){
+return new dd.DomTemplate(_3.getTemplate(loc));
+}});
+})();
+}
diff --git a/dojox/dtl/ext-dojo/NodeList.js b/dojox/dtl/ext-dojo/NodeList.js
new file mode 100644
index 0000000..25edd02
--- /dev/null
+++ b/dojox/dtl/ext-dojo/NodeList.js
@@ -0,0 +1,29 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.ext-dojo.NodeList"]){
+dojo._hasResource["dojox.dtl.ext-dojo.NodeList"]=true;
+dojo.provide("dojox.dtl.ext-dojo.NodeList");
+dojo.require("dojox.dtl._base");
+dojo.extend(dojo.NodeList,{dtl:function(_1,_2){
+var d=dojox.dtl;
+var _4=this;
+var _5=function(_6,_7){
+var _8=_6.render(new d._Context(_7));
+_4.forEach(function(_9){
+_9.innerHTML=_8;
+});
+};
+d.text._resolveTemplateArg(_1).addCallback(function(_a){
+_1=new d.Template(_a);
+d.text._resolveContextArg(_2).addCallback(function(_b){
+_5(_1,_b);
+});
+});
+return this;
+}});
+}
diff --git a/dojox/dtl/filter/dates.js b/dojox/dtl/filter/dates.js
new file mode 100644
index 0000000..d155d26
--- /dev/null
+++ b/dojox/dtl/filter/dates.js
@@ -0,0 +1,59 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.filter.dates"]){
+dojo._hasResource["dojox.dtl.filter.dates"]=true;
+dojo.provide("dojox.dtl.filter.dates");
+dojo.require("dojox.dtl.utils.date");
+(function(){
+var _1=dojox.dtl.filter.dates;
+dojo.mixin(_1,{_toDate:function(_2){
+if(_2 instanceof Date){
+return _2;
+}
+_2=new Date(_2);
+if(_2.getTime()==new Date(0).getTime()){
+return "";
+}
+return _2;
+},date:function(_3,_4){
+_3=_1._toDate(_3);
+if(!_3){
+return "";
+}
+_4=_4||"N j, Y";
+return dojox.dtl.utils.date.format(_3,_4);
+},time:function(_5,_6){
+_5=_1._toDate(_5);
+if(!_5){
+return "";
+}
+_6=_6||"P";
+return dojox.dtl.utils.date.format(_5,_6);
+},timesince:function(_7,_8){
+_7=_1._toDate(_7);
+if(!_7){
+return "";
+}
+var _9=dojox.dtl.utils.date.timesince;
+if(_8){
+return _9(_8,_7);
+}
+return _9(_7);
+},timeuntil:function(_a,_b){
+_a=_1._toDate(_a);
+if(!_a){
+return "";
+}
+var _c=dojox.dtl.utils.date.timesince;
+if(_b){
+return _c(_b,_a);
+}
+return _c(new Date(),_a);
+}});
+})();
+}
diff --git a/dojox/dtl/filter/htmlstrings.js b/dojox/dtl/filter/htmlstrings.js
new file mode 100644
index 0000000..1eaf8c3
--- /dev/null
+++ b/dojox/dtl/filter/htmlstrings.js
@@ -0,0 +1,37 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.filter.htmlstrings"]){
+dojo._hasResource["dojox.dtl.filter.htmlstrings"]=true;
+dojo.provide("dojox.dtl.filter.htmlstrings");
+dojo.require("dojox.dtl._base");
+dojo.mixin(dojox.dtl.filter.htmlstrings,{_linebreaksrn:/(\r\n|\n\r)/g,_linebreaksn:/\n{2,}/g,_linebreakss:/(^\s+|\s+$)/g,_linebreaksbr:/\n/g,_removetagsfind:/[a-z0-9]+/g,_striptags:/<[^>]*?>/g,linebreaks:function(_1){
+var _2=[];
+var dh=dojox.dtl.filter.htmlstrings;
+_1=_1.replace(dh._linebreaksrn,"\n");
+var _4=_1.split(dh._linebreaksn);
+for(var i=0;i<_4.length;i++){
+var _6=_4[i].replace(dh._linebreakss,"").replace(dh._linebreaksbr,"<br />");
+_2.push("<p>"+_6+"</p>");
+}
+return _2.join("\n\n");
+},linebreaksbr:function(_7){
+var dh=dojox.dtl.filter.htmlstrings;
+return _7.replace(dh._linebreaksrn,"\n").replace(dh._linebreaksbr,"<br />");
+},removetags:function(_9,_a){
+var dh=dojox.dtl.filter.htmlstrings;
+var _c=[];
+var _d;
+while(_d=dh._removetagsfind.exec(_a)){
+_c.push(_d[0]);
+}
+_c="("+_c.join("|")+")";
+return _9.replace(new RegExp("</?s*"+_c+"s*[^>]*>","gi"),"");
+},striptags:function(_e){
+return _e.replace(dojox.dtl.filter.htmlstrings._striptags,"");
+}});
+}
diff --git a/dojox/dtl/filter/integers.js b/dojox/dtl/filter/integers.js
new file mode 100644
index 0000000..49e67a0
--- /dev/null
+++ b/dojox/dtl/filter/integers.js
@@ -0,0 +1,28 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.filter.integers"]){
+dojo._hasResource["dojox.dtl.filter.integers"]=true;
+dojo.provide("dojox.dtl.filter.integers");
+dojo.mixin(dojox.dtl.filter.integers,{add:function(_1,_2){
+_1=parseInt(_1,10);
+_2=parseInt(_2,10);
+return isNaN(_2)?_1:_1+_2;
+},get_digit:function(_3,_4){
+_3=parseInt(_3,10);
+_4=parseInt(_4,10)-1;
+if(_4>=0){
+_3+="";
+if(_4<_3.length){
+_3=parseInt(_3.charAt(_4),10);
+}else{
+_3=0;
+}
+}
+return (isNaN(_3)?0:_3);
+}});
+}
diff --git a/dojox/dtl/filter/lists.js b/dojox/dtl/filter/lists.js
new file mode 100644
index 0000000..f7b5b2e
--- /dev/null
+++ b/dojox/dtl/filter/lists.js
@@ -0,0 +1,95 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.filter.lists"]){
+dojo._hasResource["dojox.dtl.filter.lists"]=true;
+dojo.provide("dojox.dtl.filter.lists");
+dojo.require("dojox.dtl._base");
+dojo.mixin(dojox.dtl.filter.lists,{_dictsort:function(a,b){
+if(a[0]==b[0]){
+return 0;
+}
+return (a[0]<b[0])?-1:1;
+},dictsort:function(_3,_4){
+if(!_4){
+return _3;
+}
+var i,_6,_7=[];
+if(!dojo.isArray(_3)){
+var _8=_3,_3=[];
+for(var _9 in _8){
+_3.push(_8[_9]);
+}
+}
+for(i=0;i<_3.length;i++){
+_7.push([new dojox.dtl._Filter("var."+_4).resolve(new dojox.dtl._Context({"var":_3[i]})),_3[i]]);
+}
+_7.sort(dojox.dtl.filter.lists._dictsort);
+var _a=[];
+for(i=0;_6=_7[i];i++){
+_a.push(_6[1]);
+}
+return _a;
+},dictsortreversed:function(_b,_c){
+if(!_c){
+return _b;
+}
+var _d=dojox.dtl.filter.lists.dictsort(_b,_c);
+return _d.reverse();
+},first:function(_e){
+return (_e.length)?_e[0]:"";
+},join:function(_f,arg){
+return _f.join(arg||",");
+},length:function(_11){
+return (isNaN(_11.length))?(_11+"").length:_11.length;
+},length_is:function(_12,arg){
+return _12.length==parseInt(arg);
+},random:function(_14){
+return _14[Math.floor(Math.random()*_14.length)];
+},slice:function(_15,arg){
+arg=arg||"";
+var _17=arg.split(":");
+var _18=[];
+for(var i=0;i<_17.length;i++){
+if(!_17[i].length){
+_18.push(null);
+}else{
+_18.push(parseInt(_17[i]));
+}
+}
+if(_18[0]===null){
+_18[0]=0;
+}
+if(_18[0]<0){
+_18[0]=_15.length+_18[0];
+}
+if(_18.length<2||_18[1]===null){
+_18[1]=_15.length;
+}
+if(_18[1]<0){
+_18[1]=_15.length+_18[1];
+}
+return _15.slice(_18[0],_18[1]);
+},_unordered_list:function(_1a,_1b){
+var ddl=dojox.dtl.filter.lists;
+var i,_1e="";
+for(i=0;i<_1b;i++){
+_1e+="\t";
+}
+if(_1a[1]&&_1a[1].length){
+var _1f=[];
+for(i=0;i<_1a[1].length;i++){
+_1f.push(ddl._unordered_list(_1a[1][i],_1b+1));
+}
+return _1e+"<li>"+_1a[0]+"\n"+_1e+"<ul>\n"+_1f.join("\n")+"\n"+_1e+"</ul>\n"+_1e+"</li>";
+}else{
+return _1e+"<li>"+_1a[0]+"</li>";
+}
+},unordered_list:function(_20){
+return dojox.dtl.filter.lists._unordered_list(_20,1);
+}});
+}
diff --git a/dojox/dtl/filter/logic.js b/dojox/dtl/filter/logic.js
new file mode 100644
index 0000000..cdf47a6
--- /dev/null
+++ b/dojox/dtl/filter/logic.js
@@ -0,0 +1,33 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.filter.logic"]){
+dojo._hasResource["dojox.dtl.filter.logic"]=true;
+dojo.provide("dojox.dtl.filter.logic");
+dojo.mixin(dojox.dtl.filter.logic,{default_:function(_1,_2){
+return _1||_2||"";
+},default_if_none:function(_3,_4){
+return (_3===null)?_4||"":_3||"";
+},divisibleby:function(_5,_6){
+return (parseInt(_5,10)%parseInt(_6,10))===0;
+},_yesno:/\s*,\s*/g,yesno:function(_7,_8){
+if(!_8){
+_8="yes,no,maybe";
+}
+var _9=_8.split(dojox.dtl.filter.logic._yesno);
+if(_9.length<2){
+return _7;
+}
+if(_7){
+return _9[0];
+}
+if((!_7&&_7!==null)||_9.length<3){
+return _9[1];
+}
+return _9[2];
+}});
+}
diff --git a/dojox/dtl/filter/misc.js b/dojox/dtl/filter/misc.js
new file mode 100644
index 0000000..12dd936
--- /dev/null
+++ b/dojox/dtl/filter/misc.js
@@ -0,0 +1,52 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.filter.misc"]){
+dojo._hasResource["dojox.dtl.filter.misc"]=true;
+dojo.provide("dojox.dtl.filter.misc");
+dojo.mixin(dojox.dtl.filter.misc,{filesizeformat:function(_1){
+_1=parseFloat(_1);
+if(_1<1024){
+return (_1==1)?_1+" byte":_1+" bytes";
+}else{
+if(_1<1024*1024){
+return (_1/1024).toFixed(1)+" KB";
+}else{
+if(_1<1024*1024*1024){
+return (_1/1024/1024).toFixed(1)+" MB";
+}
+}
+}
+return (_1/1024/1024/1024).toFixed(1)+" GB";
+},pluralize:function(_2,_3){
+_3=_3||"s";
+if(_3.indexOf(",")==-1){
+_3=","+_3;
+}
+var _4=_3.split(",");
+if(_4.length>2){
+return "";
+}
+var _5=_4[0];
+var _6=_4[1];
+if(parseInt(_2,10)!=1){
+return _6;
+}
+return _5;
+},_phone2numeric:{a:2,b:2,c:2,d:3,e:3,f:3,g:4,h:4,i:4,j:5,k:5,l:5,m:6,n:6,o:6,p:7,r:7,s:7,t:8,u:8,v:8,w:9,x:9,y:9},phone2numeric:function(_7){
+var dm=dojox.dtl.filter.misc;
+_7=_7+"";
+var _9="";
+for(var i=0;i<_7.length;i++){
+var _b=_7.charAt(i).toLowerCase();
+(dm._phone2numeric[_b])?_9+=dm._phone2numeric[_b]:_9+=_7.charAt(i);
+}
+return _9;
+},pprint:function(_c){
+return dojo.toJson(_c);
+}});
+}
diff --git a/dojox/dtl/filter/strings.js b/dojox/dtl/filter/strings.js
new file mode 100644
index 0000000..efadb93
--- /dev/null
+++ b/dojox/dtl/filter/strings.js
@@ -0,0 +1,270 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.filter.strings"]){
+dojo._hasResource["dojox.dtl.filter.strings"]=true;
+dojo.provide("dojox.dtl.filter.strings");
+dojo.require("dojox.dtl.filter.htmlstrings");
+dojo.require("dojox.string.sprintf");
+dojo.require("dojox.string.tokenize");
+dojo.mixin(dojox.dtl.filter.strings,{_urlquote:function(_1,_2){
+if(!_2){
+_2="/";
+}
+return dojox.string.tokenize(_1,/([^\w-_.])/g,function(_3){
+if(_2.indexOf(_3)==-1){
+if(_3==" "){
+return "+";
+}else{
+return "%"+_3.charCodeAt(0).toString(16).toUpperCase();
+}
+}
+return _3;
+}).join("");
+},addslashes:function(_4){
+return _4.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/'/g,"\\'");
+},capfirst:function(_5){
+_5=""+_5;
+return _5.charAt(0).toUpperCase()+_5.substring(1);
+},center:function(_6,_7){
+_7=_7||_6.length;
+_6=_6+"";
+var _8=_7-_6.length;
+if(_8%2){
+_6=_6+" ";
+_8-=1;
+}
+for(var i=0;i<_8;i+=2){
+_6=" "+_6+" ";
+}
+return _6;
+},cut:function(_a,_b){
+_b=_b+""||"";
+_a=_a+"";
+return _a.replace(new RegExp(_b,"g"),"");
+},_fix_ampersands:/&(?!(\w+|#\d+);)/g,fix_ampersands:function(_c){
+return _c.replace(dojox.dtl.filter.strings._fix_ampersands,"&");
+},floatformat:function(_d,_e){
+_e=parseInt(_e||-1,10);
+_d=parseFloat(_d);
+var m=_d-_d.toFixed(0);
+if(!m&&_e<0){
+return _d.toFixed();
+}
+_d=_d.toFixed(Math.abs(_e));
+return (_e<0)?parseFloat(_d)+"":_d;
+},iriencode:function(_10){
+return dojox.dtl.filter.strings._urlquote(_10,"/#%[]=:;$&()+,!");
+},linenumbers:function(_11){
+var df=dojox.dtl.filter;
+var _13=_11.split("\n");
+var _14=[];
+var _15=(_13.length+"").length;
+for(var i=0,_17;i<_13.length;i++){
+_17=_13[i];
+_14.push(df.strings.ljust(i+1,_15)+". "+dojox.dtl._base.escape(_17));
+}
+return _14.join("\n");
+},ljust:function(_18,arg){
+_18=_18+"";
+arg=parseInt(arg,10);
+while(_18.length<arg){
+_18=_18+" ";
+}
+return _18;
+},lower:function(_1a){
+return (_1a+"").toLowerCase();
+},make_list:function(_1b){
+var _1c=[];
+if(typeof _1b=="number"){
+_1b=_1b+"";
+}
+if(_1b.charAt){
+for(var i=0;i<_1b.length;i++){
+_1c.push(_1b.charAt(i));
+}
+return _1c;
+}
+if(typeof _1b=="object"){
+for(var key in _1b){
+_1c.push(_1b[key]);
+}
+return _1c;
+}
+return [];
+},rjust:function(_1f,arg){
+_1f=_1f+"";
+arg=parseInt(arg,10);
+while(_1f.length<arg){
+_1f=" "+_1f;
+}
+return _1f;
+},slugify:function(_21){
+_21=_21.replace(/[^\w\s-]/g,"").toLowerCase();
+return _21.replace(/[\-\s]+/g,"-");
+},_strings:{},stringformat:function(_22,arg){
+arg=""+arg;
+var _24=dojox.dtl.filter.strings._strings;
+if(!_24[arg]){
+_24[arg]=new dojox.string.sprintf.Formatter("%"+arg);
+}
+return _24[arg].format(_22);
+},title:function(_25){
+var _26,_27="";
+for(var i=0,_29;i<_25.length;i++){
+_29=_25.charAt(i);
+if(_26==" "||_26=="\n"||_26=="\t"||!_26){
+_27+=_29.toUpperCase();
+}else{
+_27+=_29.toLowerCase();
+}
+_26=_29;
+}
+return _27;
+},_truncatewords:/[ \n\r\t]/,truncatewords:function(_2a,arg){
+arg=parseInt(arg,10);
+if(!arg){
+return _2a;
+}
+for(var i=0,j=_2a.length,_2e=0,_2f,_30;i<_2a.length;i++){
+_2f=_2a.charAt(i);
+if(dojox.dtl.filter.strings._truncatewords.test(_30)){
+if(!dojox.dtl.filter.strings._truncatewords.test(_2f)){
+++_2e;
+if(_2e==arg){
+return _2a.substring(0,j+1);
+}
+}
+}else{
+if(!dojox.dtl.filter.strings._truncatewords.test(_2f)){
+j=i;
+}
+}
+_30=_2f;
+}
+return _2a;
+},_truncate_words:/(&.*?;|<.*?>|(\w[\w\-]*))/g,_truncate_tag:/<(\/)?([^ ]+?)(?: (\/)| .*?)?>/,_truncate_singlets:{br:true,col:true,link:true,base:true,img:true,param:true,area:true,hr:true,input:true},truncatewords_html:function(_31,arg){
+arg=parseInt(arg,10);
+if(arg<=0){
+return "";
+}
+var _33=dojox.dtl.filter.strings;
+var _34=0;
+var _35=[];
+var _36=dojox.string.tokenize(_31,_33._truncate_words,function(all,_38){
+if(_38){
+++_34;
+if(_34<arg){
+return _38;
+}else{
+if(_34==arg){
+return _38+" ...";
+}
+}
+}
+var tag=all.match(_33._truncate_tag);
+if(!tag||_34>=arg){
+return;
+}
+var _3a=tag[1];
+var _3b=tag[2].toLowerCase();
+var _3c=tag[3];
+if(_3a||_33._truncate_singlets[_3b]){
+}else{
+if(_3a){
+var i=dojo.indexOf(_35,_3b);
+if(i!=-1){
+_35=_35.slice(i+1);
+}
+}else{
+_35.unshift(_3b);
+}
+}
+return all;
+}).join("");
+_36=_36.replace(/\s+$/g,"");
+for(var i=0,tag;tag=_35[i];i++){
+_36+="</"+tag+">";
+}
+return _36;
+},upper:function(_40){
+return _40.toUpperCase();
+},urlencode:function(_41){
+return dojox.dtl.filter.strings._urlquote(_41);
+},_urlize:/^((?:[(>]|<)*)(.*?)((?:[.,)>\n]|>)*)$/,_urlize2:/^\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+$/,urlize:function(_42){
+return dojox.dtl.filter.strings.urlizetrunc(_42);
+},urlizetrunc:function(_43,arg){
+arg=parseInt(arg);
+return dojox.string.tokenize(_43,/(\S+)/g,function(_45){
+var _46=dojox.dtl.filter.strings._urlize.exec(_45);
+if(!_46){
+return _45;
+}
+var _47=_46[1];
+var _48=_46[2];
+var _49=_46[3];
+var _4a=_48.indexOf("www.")==0;
+var _4b=_48.indexOf("@")!=-1;
+var _4c=_48.indexOf(":")!=-1;
+var _4d=_48.indexOf("http://")==0;
+var _4e=_48.indexOf("https://")==0;
+var _4f=/[a-zA-Z0-9]/.test(_48.charAt(0));
+var _50=_48.substring(_48.length-4);
+var _51=_48;
+if(arg>3){
+_51=_51.substring(0,arg-3)+"...";
+}
+if(_4a||(!_4b&&!_4d&&_48.length&&_4f&&(_50==".org"||_50==".net"||_50==".com"))){
+return "<a href=\"http://"+_48+"\" rel=\"nofollow\">"+_51+"</a>";
+}else{
+if(_4d||_4e){
+return "<a href=\""+_48+"\" rel=\"nofollow\">"+_51+"</a>";
+}else{
+if(_4b&&!_4a&&!_4c&&dojox.dtl.filter.strings._urlize2.test(_48)){
+return "<a href=\"mailto:"+_48+"\">"+_48+"</a>";
+}
+}
+}
+return _45;
+}).join("");
+},wordcount:function(_52){
+_52=dojo.trim(_52);
+if(!_52){
+return 0;
+}
+return _52.split(/\s+/g).length;
+},wordwrap:function(_53,arg){
+arg=parseInt(arg);
+var _55=[];
+var _56=_53.split(/\s+/g);
+if(_56.length){
+var _57=_56.shift();
+_55.push(_57);
+var pos=_57.length-_57.lastIndexOf("\n")-1;
+for(var i=0;i<_56.length;i++){
+_57=_56[i];
+if(_57.indexOf("\n")!=-1){
+var _5a=_57.split(/\n/g);
+}else{
+var _5a=[_57];
+}
+pos+=_5a[0].length+1;
+if(arg&&pos>arg){
+_55.push("\n");
+pos=_5a[_5a.length-1].length;
+}else{
+_55.push(" ");
+if(_5a.length>1){
+pos=_5a[_5a.length-1].length;
+}
+}
+_55.push(_57);
+}
+}
+return _55.join("");
+}});
+}
diff --git a/dojox/dtl/html.js b/dojox/dtl/html.js
new file mode 100644
index 0000000..c2aa37d
--- /dev/null
+++ b/dojox/dtl/html.js
@@ -0,0 +1,14 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.html"]){
+dojo._hasResource["dojox.dtl.html"]=true;
+dojo.provide("dojox.dtl.html");
+dojo.deprecated("dojox.dtl.html","All packages and classes in dojox.dtl that start with Html or html have been renamed to Dom or dom");
+dojo.require("dojox.dtl.dom");
+dojox.dtl.HtmlTemplate=dojox.dtl.DomTemplate;
+}
diff --git a/dojox/dtl/render/dom.js b/dojox/dtl/render/dom.js
new file mode 100644
index 0000000..0cdcf11
--- /dev/null
+++ b/dojox/dtl/render/dom.js
@@ -0,0 +1,35 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.render.dom"]){
+dojo._hasResource["dojox.dtl.render.dom"]=true;
+dojo.provide("dojox.dtl.render.dom");
+dojo.require("dojox.dtl.Context");
+dojo.require("dojox.dtl.dom");
+dojox.dtl.render.dom.Render=function(_1,_2){
+this._tpl=_2;
+this.domNode=dojo.byId(_1);
+};
+dojo.extend(dojox.dtl.render.dom.Render,{setAttachPoint:function(_3){
+this.domNode=_3;
+},render:function(_4,_5,_6){
+if(!this.domNode){
+throw new Error("You cannot use the Render object without specifying where you want to render it");
+}
+this._tpl=_5=_5||this._tpl;
+_6=_6||_5.getBuffer();
+_4=_4||new dojox.dtl.Context();
+var _7=_5.render(_4,_6).getParent();
+if(!_7){
+throw new Error("Rendered template does not have a root node");
+}
+if(this.domNode!==_7){
+this.domNode.parentNode.replaceChild(_7,this.domNode);
+this.domNode=_7;
+}
+}});
+}
diff --git a/dojox/dtl/render/html.js b/dojox/dtl/render/html.js
new file mode 100644
index 0000000..3079cbd
--- /dev/null
+++ b/dojox/dtl/render/html.js
@@ -0,0 +1,13 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.render.html"]){
+dojo._hasResource["dojox.dtl.render.html"]=true;
+dojo.provide("dojox.dtl.render.html");
+dojo.require("dojox.dtl.render.dom");
+dojox.dtl.render.html.Render=dojox.dtl.render.dom.Render;
+}
diff --git a/dojox/dtl/tag/date.js b/dojox/dtl/tag/date.js
new file mode 100644
index 0000000..6d6e6a7
--- /dev/null
+++ b/dojox/dtl/tag/date.js
@@ -0,0 +1,33 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.tag.date"]){
+dojo._hasResource["dojox.dtl.tag.date"]=true;
+dojo.provide("dojox.dtl.tag.date");
+dojo.require("dojox.dtl._base");
+dojo.require("dojox.dtl.utils.date");
+dojox.dtl.tag.date.NowNode=function(_1,_2){
+this._format=_1;
+this.format=new dojox.dtl.utils.date.DateFormat(_1);
+this.contents=_2;
+};
+dojo.extend(dojox.dtl.tag.date.NowNode,{render:function(_3,_4){
+this.contents.set(this.format.format(new Date()));
+return this.contents.render(_3,_4);
+},unrender:function(_5,_6){
+return this.contents.unrender(_5,_6);
+},clone:function(_7){
+return new this.constructor(this._format,this.contents.clone(_7));
+}});
+dojox.dtl.tag.date.now=function(_8,_9){
+var _a=_9.split_contents();
+if(_a.length!=2){
+throw new Error("'now' statement takes one argument");
+}
+return new dojox.dtl.tag.date.NowNode(_a[1].slice(1,-1),_8.create_text_node());
+};
+}
diff --git a/dojox/dtl/tag/loader.js b/dojox/dtl/tag/loader.js
new file mode 100644
index 0000000..3368f9e
--- /dev/null
+++ b/dojox/dtl/tag/loader.js
@@ -0,0 +1,260 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.tag.loader"]){
+dojo._hasResource["dojox.dtl.tag.loader"]=true;
+dojo.provide("dojox.dtl.tag.loader");
+dojo.require("dojox.dtl._base");
+(function(){
+var dd=dojox.dtl;
+var _2=dd.tag.loader;
+_2.BlockNode=dojo.extend(function(_3,_4){
+this.name=_3;
+this.nodelist=_4;
+},{"super":function(){
+if(this.parent){
+var _5=this.parent.nodelist.dummyRender(this.context,null,true);
+if(typeof _5=="string"){
+_5=new String(_5);
+}
+_5.safe=true;
+return _5;
+}
+return "";
+},render:function(_6,_7){
+var _8=this.name;
+var _9=this.nodelist;
+var _a;
+if(_7.blocks){
+var _b=_7.blocks[_8];
+if(_b){
+_a=_b.parent;
+_9=_b.nodelist;
+_b.used=true;
+}
+}
+this.rendered=_9;
+_6=_6.push();
+this.context=_6;
+this.parent=null;
+if(_9!=this.nodelist){
+this.parent=this;
+}
+_6.block=this;
+if(_7.getParent){
+var _c=_7.getParent();
+var _d=dojo.connect(_7,"onSetParent",function(_e,up,_10){
+if(up&&_10){
+_7.setParent(_c);
+}
+});
+}
+_7=_9.render(_6,_7,this);
+_d&&dojo.disconnect(_d);
+_6=_6.pop();
+return _7;
+},unrender:function(_11,_12){
+return this.rendered.unrender(_11,_12);
+},clone:function(_13){
+return new this.constructor(this.name,this.nodelist.clone(_13));
+},toString:function(){
+return "dojox.dtl.tag.loader.BlockNode";
+}});
+_2.ExtendsNode=dojo.extend(function(_14,_15,_16,_17,key){
+this.getTemplate=_14;
+this.nodelist=_15;
+this.shared=_16;
+this.parent=_17;
+this.key=key;
+},{parents:{},getParent:function(_19){
+var _1a=this.parent;
+if(!_1a){
+var _1b;
+_1a=this.parent=_19.get(this.key,false);
+if(!_1a){
+throw new Error("extends tag used a variable that did not resolve");
+}
+if(typeof _1a=="object"){
+var url=_1a.url||_1a.templatePath;
+if(_1a.shared){
+this.shared=true;
+}
+if(url){
+_1a=this.parent=url.toString();
+}else{
+if(_1a.templateString){
+_1b=_1a.templateString;
+_1a=this.parent=" ";
+}else{
+_1a=this.parent=this.parent.toString();
+}
+}
+}
+if(_1a&&_1a.indexOf("shared:")===0){
+this.shared=true;
+_1a=this.parent=_1a.substring(7,_1a.length);
+}
+}
+if(!_1a){
+throw new Error("Invalid template name in 'extends' tag.");
+}
+if(_1a.render){
+return _1a;
+}
+if(this.parents[_1a]){
+return this.parents[_1a];
+}
+this.parent=this.getTemplate(_1b||dojox.dtl.text.getTemplateString(_1a));
+if(this.shared){
+this.parents[_1a]=this.parent;
+}
+return this.parent;
+},render:function(_1d,_1e){
+var _1f=this.getParent(_1d);
+_1f.blocks=_1f.blocks||{};
+_1e.blocks=_1e.blocks||{};
+for(var i=0,_21;_21=this.nodelist.contents[i];i++){
+if(_21 instanceof dojox.dtl.tag.loader.BlockNode){
+var old=_1f.blocks[_21.name];
+if(old&&old.nodelist!=_21.nodelist){
+_1e=old.nodelist.unrender(_1d,_1e);
+}
+_1f.blocks[_21.name]=_1e.blocks[_21.name]={shared:this.shared,nodelist:_21.nodelist,used:false};
+}
+}
+this.rendered=_1f;
+return _1f.nodelist.render(_1d,_1e,this);
+},unrender:function(_23,_24){
+return this.rendered.unrender(_23,_24,this);
+},toString:function(){
+return "dojox.dtl.block.ExtendsNode";
+}});
+_2.IncludeNode=dojo.extend(function(_25,_26,_27,_28,_29){
+this._path=_25;
+this.constant=_26;
+this.path=(_26)?_25:new dd._Filter(_25);
+this.getTemplate=_27;
+this.text=_28;
+this.parsed=(arguments.length==5)?_29:true;
+},{_cache:[{},{}],render:function(_2a,_2b){
+var _2c=((this.constant)?this.path:this.path.resolve(_2a)).toString();
+var _2d=Number(this.parsed);
+var _2e=false;
+if(_2c!=this.last){
+_2e=true;
+if(this.last){
+_2b=this.unrender(_2a,_2b);
+}
+this.last=_2c;
+}
+var _2f=this._cache[_2d];
+if(_2d){
+if(!_2f[_2c]){
+_2f[_2c]=dd.text._resolveTemplateArg(_2c,true);
+}
+if(_2e){
+var _30=this.getTemplate(_2f[_2c]);
+this.rendered=_30.nodelist;
+}
+return this.rendered.render(_2a,_2b,this);
+}else{
+if(this.text instanceof dd._TextNode){
+if(_2e){
+this.rendered=this.text;
+this.rendered.set(dd.text._resolveTemplateArg(_2c,true));
+}
+return this.rendered.render(_2a,_2b);
+}else{
+if(!_2f[_2c]){
+var _31=[];
+var div=document.createElement("div");
+div.innerHTML=dd.text._resolveTemplateArg(_2c,true);
+var _33=div.childNodes;
+while(_33.length){
+var _34=div.removeChild(_33[0]);
+_31.push(_34);
+}
+_2f[_2c]=_31;
+}
+if(_2e){
+this.nodelist=[];
+var _35=true;
+for(var i=0,_37;_37=_2f[_2c][i];i++){
+this.nodelist.push(_37.cloneNode(true));
+}
+}
+for(var i=0,_38;_38=this.nodelist[i];i++){
+_2b=_2b.concat(_38);
+}
+}
+}
+return _2b;
+},unrender:function(_39,_3a){
+if(this.rendered){
+_3a=this.rendered.unrender(_39,_3a);
+}
+if(this.nodelist){
+for(var i=0,_3c;_3c=this.nodelist[i];i++){
+_3a=_3a.remove(_3c);
+}
+}
+return _3a;
+},clone:function(_3d){
+return new this.constructor(this._path,this.constant,this.getTemplate,this.text.clone(_3d),this.parsed);
+}});
+dojo.mixin(_2,{block:function(_3e,_3f){
+var _40=_3f.contents.split();
+var _41=_40[1];
+_3e._blocks=_3e._blocks||{};
+_3e._blocks[_41]=_3e._blocks[_41]||[];
+_3e._blocks[_41].push(_41);
+var _42=_3e.parse(["endblock","endblock "+_41]).rtrim();
+_3e.next_token();
+return new dojox.dtl.tag.loader.BlockNode(_41,_42);
+},extends_:function(_43,_44){
+var _45=_44.contents.split();
+var _46=false;
+var _47=null;
+var key=null;
+if(_45[1].charAt(0)=="\""||_45[1].charAt(0)=="'"){
+_47=_45[1].substring(1,_45[1].length-1);
+}else{
+key=_45[1];
+}
+if(_47&&_47.indexOf("shared:")==0){
+_46=true;
+_47=_47.substring(7,_47.length);
+}
+var _49=_43.parse();
+return new dojox.dtl.tag.loader.ExtendsNode(_43.getTemplate,_49,_46,_47,key);
+},include:function(_4a,_4b){
+var _4c=_4b.contents.split();
+if(_4c.length!=2){
+throw new Error(_4c[0]+" tag takes one argument: the name of the template to be included");
+}
+var _4d=_4c[1];
+var _4e=false;
+if((_4d.charAt(0)=="\""||_4d.slice(-1)=="'")&&_4d.charAt(0)==_4d.slice(-1)){
+_4d=_4d.slice(1,-1);
+_4e=true;
+}
+return new _2.IncludeNode(_4d,_4e,_4a.getTemplate,_4a.create_text_node());
+},ssi:function(_4f,_50){
+var _51=_50.contents.split();
+var _52=false;
+if(_51.length==3){
+_52=(_51.pop()=="parsed");
+if(!_52){
+throw new Error("Second (optional) argument to ssi tag must be 'parsed'");
+}
+}
+var _53=_2.include(_4f,new dd.Token(_50.token_type,_51.join(" ")));
+_53.parsed=_52;
+return _53;
+}});
+})();
+}
diff --git a/dojox/dtl/tag/logic.js b/dojox/dtl/tag/logic.js
new file mode 100644
index 0000000..1a1fbaa
--- /dev/null
+++ b/dojox/dtl/tag/logic.js
@@ -0,0 +1,247 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.tag.logic"]){
+dojo._hasResource["dojox.dtl.tag.logic"]=true;
+dojo.provide("dojox.dtl.tag.logic");
+dojo.require("dojox.dtl._base");
+(function(){
+var dd=dojox.dtl;
+var _2=dd.text;
+var _3=dd.tag.logic;
+_3.IfNode=dojo.extend(function(_4,_5,_6,_7){
+this.bools=_4;
+this.trues=_5;
+this.falses=_6;
+this.type=_7;
+},{render:function(_8,_9){
+var i,_b,_c,_d,_e;
+if(this.type=="or"){
+for(i=0;_b=this.bools[i];i++){
+_c=_b[0];
+_d=_b[1];
+_e=_d.resolve(_8);
+if((_e&&!_c)||(_c&&!_e)){
+if(this.falses){
+_9=this.falses.unrender(_8,_9);
+}
+return (this.trues)?this.trues.render(_8,_9,this):_9;
+}
+}
+if(this.trues){
+_9=this.trues.unrender(_8,_9);
+}
+return (this.falses)?this.falses.render(_8,_9,this):_9;
+}else{
+for(i=0;_b=this.bools[i];i++){
+_c=_b[0];
+_d=_b[1];
+_e=_d.resolve(_8);
+if(_e==_c){
+if(this.trues){
+_9=this.trues.unrender(_8,_9);
+}
+return (this.falses)?this.falses.render(_8,_9,this):_9;
+}
+}
+if(this.falses){
+_9=this.falses.unrender(_8,_9);
+}
+return (this.trues)?this.trues.render(_8,_9,this):_9;
+}
+return _9;
+},unrender:function(_f,_10){
+_10=(this.trues)?this.trues.unrender(_f,_10):_10;
+_10=(this.falses)?this.falses.unrender(_f,_10):_10;
+return _10;
+},clone:function(_11){
+var _12=(this.trues)?this.trues.clone(_11):null;
+var _13=(this.falses)?this.falses.clone(_11):null;
+return new this.constructor(this.bools,_12,_13,this.type);
+}});
+_3.IfEqualNode=dojo.extend(function(_14,_15,_16,_17,_18){
+this.var1=new dd._Filter(_14);
+this.var2=new dd._Filter(_15);
+this.trues=_16;
+this.falses=_17;
+this.negate=_18;
+},{render:function(_19,_1a){
+var _1b=this.var1.resolve(_19);
+var _1c=this.var2.resolve(_19);
+_1b=(typeof _1b!="undefined")?_1b:"";
+_1c=(typeof _1b!="undefined")?_1c:"";
+if((this.negate&&_1b!=_1c)||(!this.negate&&_1b==_1c)){
+if(this.falses){
+_1a=this.falses.unrender(_19,_1a,this);
+}
+return (this.trues)?this.trues.render(_19,_1a,this):_1a;
+}
+if(this.trues){
+_1a=this.trues.unrender(_19,_1a,this);
+}
+return (this.falses)?this.falses.render(_19,_1a,this):_1a;
+},unrender:function(_1d,_1e){
+return _3.IfNode.prototype.unrender.call(this,_1d,_1e);
+},clone:function(_1f){
+var _20=this.trues?this.trues.clone(_1f):null;
+var _21=this.falses?this.falses.clone(_1f):null;
+return new this.constructor(this.var1.getExpression(),this.var2.getExpression(),_20,_21,this.negate);
+}});
+_3.ForNode=dojo.extend(function(_22,_23,_24,_25){
+this.assign=_22;
+this.loop=new dd._Filter(_23);
+this.reversed=_24;
+this.nodelist=_25;
+this.pool=[];
+},{render:function(_26,_27){
+var i,j,k;
+var _2b=false;
+var _2c=this.assign;
+for(k=0;k<_2c.length;k++){
+if(typeof _26[_2c[k]]!="undefined"){
+_2b=true;
+_26=_26.push();
+break;
+}
+}
+if(!_2b&&_26.forloop){
+_2b=true;
+_26=_26.push();
+}
+var _2d=this.loop.resolve(_26)||[];
+for(i=_2d.length;i<this.pool.length;i++){
+this.pool[i].unrender(_26,_27,this);
+}
+if(this.reversed){
+_2d=_2d.slice(0).reverse();
+}
+var _2e=dojo.isObject(_2d)&&!dojo.isArrayLike(_2d);
+var _2f=[];
+if(_2e){
+for(var key in _2d){
+_2f.push(_2d[key]);
+}
+}else{
+_2f=_2d;
+}
+var _31=_26.forloop={parentloop:_26.get("forloop",{})};
+var j=0;
+for(i=0;i<_2f.length;i++){
+var _32=_2f[i];
+_31.counter0=j;
+_31.counter=j+1;
+_31.revcounter0=_2f.length-j-1;
+_31.revcounter=_2f.length-j;
+_31.first=!j;
+_31.last=(j==_2f.length-1);
+if(_2c.length>1&&dojo.isArrayLike(_32)){
+if(!_2b){
+_2b=true;
+_26=_26.push();
+}
+var _33={};
+for(k=0;k<_32.length&&k<_2c.length;k++){
+_33[_2c[k]]=_32[k];
+}
+dojo.mixin(_26,_33);
+}else{
+_26[_2c[0]]=_32;
+}
+if(j+1>this.pool.length){
+this.pool.push(this.nodelist.clone(_27));
+}
+_27=this.pool[j++].render(_26,_27,this);
+}
+delete _26.forloop;
+if(_2b){
+_26=_26.pop();
+}else{
+for(k=0;k<_2c.length;k++){
+delete _26[_2c[k]];
+}
+}
+return _27;
+},unrender:function(_34,_35){
+for(var i=0,_37;_37=this.pool[i];i++){
+_35=_37.unrender(_34,_35);
+}
+return _35;
+},clone:function(_38){
+return new this.constructor(this.assign,this.loop.getExpression(),this.reversed,this.nodelist.clone(_38));
+}});
+dojo.mixin(_3,{if_:function(_39,_3a){
+var i,_3c,_3d,_3e=[],_3f=_3a.contents.split();
+_3f.shift();
+_3a=_3f.join(" ");
+_3f=_3a.split(" and ");
+if(_3f.length==1){
+_3d="or";
+_3f=_3a.split(" or ");
+}else{
+_3d="and";
+for(i=0;i<_3f.length;i++){
+if(_3f[i].indexOf(" or ")!=-1){
+throw new Error("'if' tags can't mix 'and' and 'or'");
+}
+}
+}
+for(i=0;_3c=_3f[i];i++){
+var not=false;
+if(_3c.indexOf("not ")==0){
+_3c=_3c.slice(4);
+not=true;
+}
+_3e.push([not,new dd._Filter(_3c)]);
+}
+var _41=_39.parse(["else","endif"]);
+var _42=false;
+var _3a=_39.next_token();
+if(_3a.contents=="else"){
+_42=_39.parse(["endif"]);
+_39.next_token();
+}
+return new _3.IfNode(_3e,_41,_42,_3d);
+},_ifequal:function(_43,_44,_45){
+var _46=_44.split_contents();
+if(_46.length!=3){
+throw new Error(_46[0]+" takes two arguments");
+}
+var end="end"+_46[0];
+var _48=_43.parse(["else",end]);
+var _49=false;
+var _44=_43.next_token();
+if(_44.contents=="else"){
+_49=_43.parse([end]);
+_43.next_token();
+}
+return new _3.IfEqualNode(_46[1],_46[2],_48,_49,_45);
+},ifequal:function(_4a,_4b){
+return _3._ifequal(_4a,_4b);
+},ifnotequal:function(_4c,_4d){
+return _3._ifequal(_4c,_4d,true);
+},for_:function(_4e,_4f){
+var _50=_4f.contents.split();
+if(_50.length<4){
+throw new Error("'for' statements should have at least four words: "+_4f.contents);
+}
+var _51=_50[_50.length-1]=="reversed";
+var _52=(_51)?-3:-2;
+if(_50[_50.length+_52]!="in"){
+throw new Error("'for' tag received an invalid argument: "+_4f.contents);
+}
+var _53=_50.slice(1,_52).join(" ").split(/ *, */);
+for(var i=0;i<_53.length;i++){
+if(!_53[i]||_53[i].indexOf(" ")!=-1){
+throw new Error("'for' tag received an invalid argument: "+_4f.contents);
+}
+}
+var _55=_4e.parse(["endfor"]);
+_4e.next_token();
+return new _3.ForNode(_53,_50[_50.length+_52+1],_51,_55);
+}});
+})();
+}
diff --git a/dojox/dtl/tag/loop.js b/dojox/dtl/tag/loop.js
new file mode 100644
index 0000000..c0a52bc
--- /dev/null
+++ b/dojox/dtl/tag/loop.js
@@ -0,0 +1,164 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.tag.loop"]){
+dojo._hasResource["dojox.dtl.tag.loop"]=true;
+dojo.provide("dojox.dtl.tag.loop");
+dojo.require("dojox.dtl._base");
+dojo.require("dojox.string.tokenize");
+(function(){
+var dd=dojox.dtl;
+var _2=dd.tag.loop;
+_2.CycleNode=dojo.extend(function(_3,_4,_5,_6){
+this.cyclevars=_3;
+this.name=_4;
+this.contents=_5;
+this.shared=_6||{counter:-1,map:{}};
+},{render:function(_7,_8){
+if(_7.forloop&&!_7.forloop.counter0){
+this.shared.counter=-1;
+}
+++this.shared.counter;
+var _9=this.cyclevars[this.shared.counter%this.cyclevars.length];
+var _a=this.shared.map;
+if(!_a[_9]){
+_a[_9]=new dd._Filter(_9);
+}
+_9=_a[_9].resolve(_7,_8);
+if(this.name){
+_7[this.name]=_9;
+}
+this.contents.set(_9);
+return this.contents.render(_7,_8);
+},unrender:function(_b,_c){
+return this.contents.unrender(_b,_c);
+},clone:function(_d){
+return new this.constructor(this.cyclevars,this.name,this.contents.clone(_d),this.shared);
+}});
+_2.IfChangedNode=dojo.extend(function(_e,_f,_10){
+this.nodes=_e;
+this._vars=_f;
+this.shared=_10||{last:null,counter:0};
+this.vars=dojo.map(_f,function(_11){
+return new dojox.dtl._Filter(_11);
+});
+},{render:function(_12,_13){
+if(_12.forloop){
+if(_12.forloop.counter<=this.shared.counter){
+this.shared.last=null;
+}
+this.shared.counter=_12.forloop.counter;
+}
+var _14;
+if(this.vars.length){
+_14=dojo.toJson(dojo.map(this.vars,function(_15){
+return _15.resolve(_12);
+}));
+}else{
+_14=this.nodes.dummyRender(_12,_13);
+}
+if(_14!=this.shared.last){
+var _16=(this.shared.last===null);
+this.shared.last=_14;
+_12=_12.push();
+_12.ifchanged={firstloop:_16};
+_13=this.nodes.render(_12,_13);
+_12=_12.pop();
+}else{
+_13=this.nodes.unrender(_12,_13);
+}
+return _13;
+},unrender:function(_17,_18){
+return this.nodes.unrender(_17,_18);
+},clone:function(_19){
+return new this.constructor(this.nodes.clone(_19),this._vars,this.shared);
+}});
+_2.RegroupNode=dojo.extend(function(_1a,key,_1c){
+this._expression=_1a;
+this.expression=new dd._Filter(_1a);
+this.key=key;
+this.alias=_1c;
+},{_push:function(_1d,_1e,_1f){
+if(_1f.length){
+_1d.push({grouper:_1e,list:_1f});
+}
+},render:function(_20,_21){
+_20[this.alias]=[];
+var _22=this.expression.resolve(_20);
+if(_22){
+var _23=null;
+var _24=[];
+for(var i=0;i<_22.length;i++){
+var id=_22[i][this.key];
+if(_23!==id){
+this._push(_20[this.alias],_23,_24);
+_23=id;
+_24=[_22[i]];
+}else{
+_24.push(_22[i]);
+}
+}
+this._push(_20[this.alias],_23,_24);
+}
+return _21;
+},unrender:function(_27,_28){
+return _28;
+},clone:function(_29,_2a){
+return this;
+}});
+dojo.mixin(_2,{cycle:function(_2b,_2c){
+var _2d=_2c.split_contents();
+if(_2d.length<2){
+throw new Error("'cycle' tag requires at least two arguments");
+}
+if(_2d[1].indexOf(",")!=-1){
+var _2e=_2d[1].split(",");
+_2d=[_2d[0]];
+for(var i=0;i<_2e.length;i++){
+_2d.push("\""+_2e[i]+"\"");
+}
+}
+if(_2d.length==2){
+var _30=_2d[_2d.length-1];
+if(!_2b._namedCycleNodes){
+throw new Error("No named cycles in template: '"+_30+"' is not defined");
+}
+if(!_2b._namedCycleNodes[_30]){
+throw new Error("Named cycle '"+_30+"' does not exist");
+}
+return _2b._namedCycleNodes[_30];
+}
+if(_2d.length>4&&_2d[_2d.length-2]=="as"){
+var _30=_2d[_2d.length-1];
+var _31=new _2.CycleNode(_2d.slice(1,_2d.length-2),_30,_2b.create_text_node());
+if(!_2b._namedCycleNodes){
+_2b._namedCycleNodes={};
+}
+_2b._namedCycleNodes[_30]=_31;
+}else{
+_31=new _2.CycleNode(_2d.slice(1),null,_2b.create_text_node());
+}
+return _31;
+},ifchanged:function(_32,_33){
+var _34=_33.contents.split();
+var _35=_32.parse(["endifchanged"]);
+_32.delete_first_token();
+return new _2.IfChangedNode(_35,_34.slice(1));
+},regroup:function(_36,_37){
+var _38=dojox.string.tokenize(_37.contents,/(\s+)/g,function(_39){
+return _39;
+});
+if(_38.length<11||_38[_38.length-3]!="as"||_38[_38.length-7]!="by"){
+throw new Error("Expected the format: regroup list by key as newList");
+}
+var _3a=_38.slice(2,-8).join("");
+var key=_38[_38.length-5];
+var _3c=_38[_38.length-1];
+return new _2.RegroupNode(_3a,key,_3c);
+}});
+})();
+}
diff --git a/dojox/dtl/tag/misc.js b/dojox/dtl/tag/misc.js
new file mode 100644
index 0000000..ab90b1d
--- /dev/null
+++ b/dojox/dtl/tag/misc.js
@@ -0,0 +1,223 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.tag.misc"]){
+dojo._hasResource["dojox.dtl.tag.misc"]=true;
+dojo.provide("dojox.dtl.tag.misc");
+dojo.require("dojox.dtl._base");
+(function(){
+var dd=dojox.dtl;
+var _2=dd.tag.misc;
+_2.DebugNode=dojo.extend(function(_3){
+this.text=_3;
+},{render:function(_4,_5){
+var _6=_4.getKeys();
+var _7=[];
+var _8={};
+for(var i=0,_a;_a=_6[i];i++){
+_8[_a]=_4[_a];
+_7+="["+_a+": "+typeof _4[_a]+"]\n";
+}
+
+return this.text.set(_7).render(_4,_5,this);
+},unrender:function(_b,_c){
+return _c;
+},clone:function(_d){
+return new this.constructor(this.text.clone(_d));
+},toString:function(){
+return "ddtm.DebugNode";
+}});
+_2.FilterNode=dojo.extend(function(_e,_f){
+this._varnode=_e;
+this._nodelist=_f;
+},{render:function(_10,_11){
+var _12=this._nodelist.render(_10,new dojox.string.Builder());
+_10=_10.update({"var":_12.toString()});
+var _13=this._varnode.render(_10,_11);
+_10=_10.pop();
+return _11;
+},unrender:function(_14,_15){
+return _15;
+},clone:function(_16){
+return new this.constructor(this._expression,this._nodelist.clone(_16));
+}});
+_2.FirstOfNode=dojo.extend(function(_17,_18){
+this._vars=_17;
+this.vars=dojo.map(_17,function(_19){
+return new dojox.dtl._Filter(_19);
+});
+this.contents=_18;
+},{render:function(_1a,_1b){
+for(var i=0,_1d;_1d=this.vars[i];i++){
+var _1e=_1d.resolve(_1a);
+if(typeof _1e!="undefined"){
+if(_1e===null){
+_1e="null";
+}
+this.contents.set(_1e);
+return this.contents.render(_1a,_1b);
+}
+}
+return this.contents.unrender(_1a,_1b);
+},unrender:function(_1f,_20){
+return this.contents.unrender(_1f,_20);
+},clone:function(_21){
+return new this.constructor(this._vars,this.contents.clone(_21));
+}});
+_2.SpacelessNode=dojo.extend(function(_22,_23){
+this.nodelist=_22;
+this.contents=_23;
+},{render:function(_24,_25){
+if(_25.getParent){
+var _26=[dojo.connect(_25,"onAddNodeComplete",this,"_watch"),dojo.connect(_25,"onSetParent",this,"_watchParent")];
+_25=this.nodelist.render(_24,_25);
+dojo.disconnect(_26[0]);
+dojo.disconnect(_26[1]);
+}else{
+var _27=this.nodelist.dummyRender(_24);
+this.contents.set(_27.replace(/>\s+</g,"><"));
+_25=this.contents.render(_24,_25);
+}
+return _25;
+},unrender:function(_28,_29){
+return this.nodelist.unrender(_28,_29);
+},clone:function(_2a){
+return new this.constructor(this.nodelist.clone(_2a),this.contents.clone(_2a));
+},_isEmpty:function(_2b){
+return (_2b.nodeType==3&&!_2b.data.match(/[^\s\n]/));
+},_watch:function(_2c){
+if(this._isEmpty(_2c)){
+var _2d=false;
+if(_2c.parentNode.firstChild==_2c){
+_2c.parentNode.removeChild(_2c);
+}
+}else{
+var _2e=_2c.parentNode.childNodes;
+if(_2c.nodeType==1&&_2e.length>2){
+for(var i=2,_30;_30=_2e[i];i++){
+if(_2e[i-2].nodeType==1&&this._isEmpty(_2e[i-1])){
+_2c.parentNode.removeChild(_2e[i-1]);
+return;
+}
+}
+}
+}
+},_watchParent:function(_31){
+var _32=_31.childNodes;
+if(_32.length){
+while(_31.childNodes.length){
+var _33=_31.childNodes[_31.childNodes.length-1];
+if(!this._isEmpty(_33)){
+return;
+}
+_31.removeChild(_33);
+}
+}
+}});
+_2.TemplateTagNode=dojo.extend(function(tag,_35){
+this.tag=tag;
+this.contents=_35;
+},{mapping:{openblock:"{%",closeblock:"%}",openvariable:"{{",closevariable:"}}",openbrace:"{",closebrace:"}",opencomment:"{#",closecomment:"#}"},render:function(_36,_37){
+this.contents.set(this.mapping[this.tag]);
+return this.contents.render(_36,_37);
+},unrender:function(_38,_39){
+return this.contents.unrender(_38,_39);
+},clone:function(_3a){
+return new this.constructor(this.tag,this.contents.clone(_3a));
+}});
+_2.WidthRatioNode=dojo.extend(function(_3b,max,_3d,_3e){
+this.current=new dd._Filter(_3b);
+this.max=new dd._Filter(max);
+this.width=_3d;
+this.contents=_3e;
+},{render:function(_3f,_40){
+var _41=+this.current.resolve(_3f);
+var max=+this.max.resolve(_3f);
+if(typeof _41!="number"||typeof max!="number"||!max){
+this.contents.set("");
+}else{
+this.contents.set(""+Math.round((_41/max)*this.width));
+}
+return this.contents.render(_3f,_40);
+},unrender:function(_43,_44){
+return this.contents.unrender(_43,_44);
+},clone:function(_45){
+return new this.constructor(this.current.getExpression(),this.max.getExpression(),this.width,this.contents.clone(_45));
+}});
+_2.WithNode=dojo.extend(function(_46,_47,_48){
+this.target=new dd._Filter(_46);
+this.alias=_47;
+this.nodelist=_48;
+},{render:function(_49,_4a){
+var _4b=this.target.resolve(_49);
+_49=_49.push();
+_49[this.alias]=_4b;
+_4a=this.nodelist.render(_49,_4a);
+_49=_49.pop();
+return _4a;
+},unrender:function(_4c,_4d){
+return _4d;
+},clone:function(_4e){
+return new this.constructor(this.target.getExpression(),this.alias,this.nodelist.clone(_4e));
+}});
+dojo.mixin(_2,{comment:function(_4f,_50){
+_4f.skip_past("endcomment");
+return dd._noOpNode;
+},debug:function(_51,_52){
+return new _2.DebugNode(_51.create_text_node());
+},filter:function(_53,_54){
+var _55=_54.contents.split(null,1)[1];
+var _56=_53.create_variable_node("var|"+_55);
+var _57=_53.parse(["endfilter"]);
+_53.next_token();
+return new _2.FilterNode(_56,_57);
+},firstof:function(_58,_59){
+var _5a=_59.split_contents().slice(1);
+if(!_5a.length){
+throw new Error("'firstof' statement requires at least one argument");
+}
+return new _2.FirstOfNode(_5a,_58.create_text_node());
+},spaceless:function(_5b,_5c){
+var _5d=_5b.parse(["endspaceless"]);
+_5b.delete_first_token();
+return new _2.SpacelessNode(_5d,_5b.create_text_node());
+},templatetag:function(_5e,_5f){
+var _60=_5f.contents.split();
+if(_60.length!=2){
+throw new Error("'templatetag' statement takes one argument");
+}
+var tag=_60[1];
+var _62=_2.TemplateTagNode.prototype.mapping;
+if(!_62[tag]){
+var _63=[];
+for(var key in _62){
+_63.push(key);
+}
+throw new Error("Invalid templatetag argument: '"+tag+"'. Must be one of: "+_63.join(", "));
+}
+return new _2.TemplateTagNode(tag,_5e.create_text_node());
+},widthratio:function(_65,_66){
+var _67=_66.contents.split();
+if(_67.length!=4){
+throw new Error("widthratio takes three arguments");
+}
+var _68=+_67[3];
+if(typeof _68!="number"){
+throw new Error("widthratio final argument must be an integer");
+}
+return new _2.WidthRatioNode(_67[1],_67[2],_68,_65.create_text_node());
+},with_:function(_69,_6a){
+var _6b=_6a.split_contents();
+if(_6b.length!=4||_6b[2]!="as"){
+throw new Error("do_width expected format as 'with value as name'");
+}
+var _6c=_69.parse(["endwith"]);
+_69.next_token();
+return new _2.WithNode(_6b[1],_6b[3],_6c);
+}});
+})();
+}
diff --git a/dojox/dtl/utils/date.js b/dojox/dtl/utils/date.js
new file mode 100644
index 0000000..1df6d20
--- /dev/null
+++ b/dojox/dtl/utils/date.js
@@ -0,0 +1,59 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.dtl.utils.date"]){
+dojo._hasResource["dojox.dtl.utils.date"]=true;
+dojo.provide("dojox.dtl.utils.date");
+dojo.require("dojox.date.php");
+dojox.dtl.utils.date.DateFormat=function(_1){
+dojox.date.php.DateFormat.call(this,_1);
+};
+dojo.extend(dojox.dtl.utils.date.DateFormat,dojox.date.php.DateFormat.prototype,{f:function(){
+return (!this.date.getMinutes())?this.g():this.g()+":"+this.i();
+},N:function(){
+return dojox.dtl.utils.date._months_ap[this.date.getMonth()];
+},P:function(){
+if(!this.date.getMinutes()&&!this.date.getHours()){
+return "midnight";
+}
+if(!this.date.getMinutes()&&this.date.getHours()==12){
+return "noon";
+}
+return this.f()+" "+this.a();
+}});
+dojo.mixin(dojox.dtl.utils.date,{format:function(_2,_3){
+var df=new dojox.dtl.utils.date.DateFormat(_3);
+return df.format(_2);
+},timesince:function(d,_6){
+if(!(d instanceof Date)){
+d=new Date(d.year,d.month,d.day);
+}
+if(!_6){
+_6=new Date();
+}
+var _7=Math.abs(_6.getTime()-d.getTime());
+for(var i=0,_9;_9=dojox.dtl.utils.date._chunks[i];i++){
+var _a=Math.floor(_7/_9[0]);
+if(_a){
+break;
+}
+}
+return _a+" "+_9[1](_a);
+},_chunks:[[60*60*24*365*1000,function(n){
+return (n==1)?"year":"years";
+}],[60*60*24*30*1000,function(n){
+return (n==1)?"month":"months";
+}],[60*60*24*7*1000,function(n){
+return (n==1)?"week":"weeks";
+}],[60*60*24*1000,function(n){
+return (n==1)?"day":"days";
+}],[60*60*1000,function(n){
+return (n==1)?"hour":"hours";
+}],[60*1000,function(n){
+return (n==1)?"minute":"minutes";
+}]],_months_ap:["Jan.","Feb.","March","April","May","June","July","Aug.","Sept.","Oct.","Nov.","Dec."]});
+}
diff --git a/dojox/editor/README b/dojox/editor/README
new file mode 100644
index 0000000..550a085
--- /dev/null
+++ b/dojox/editor/README
@@ -0,0 +1,44 @@
+-------------------------------------------------------------------------------
+dojox.editor
+-------------------------------------------------------------------------------
+Version 0.5
+Release date: 7/10/2008
+-------------------------------------------------------------------------------
+Project state:
+experimental
+-------------------------------------------------------------------------------
+Credits
+	Mike Wilcox 	- Author
+    Dustin Machi 	- Technical Assistance
+-------------------------------------------------------------------------------
+Project description
+
+Space for extensions and additional plugins for dijit.Editor 
+-------------------------------------------------------------------------------
+Dependencies:
+
+dijit
+dojox.form
+
+-------------------------------------------------------------------------------
+Documentation
+
+The plugins directory contains extensions which work with dijit.Editor.
+
+-------------------------------------------------------------------------------
+Plugin Installation instructions
+
+Get dojo and dijit from svn. Include the Editor and plugins in your page:
+
+dojo.require("dijit.Editor");
+dojo.require("dojox.editor.plugins.TablePlugins");
+dojo.require("dojox.editor.plugins.UploadImage");
+
+And the style sheet:
+
+<link href="[path]dojox/editor/plugins/resources/editorPlugins.css" type="text/css" rel="stylesheet" />
+<link href="[path]dojox/form/resources/FileInput.css" type="text/css" rel="stylesheet" />
+
+See tests for examples:
+dojox/editor/plugins/tests/editorTablePlugs.html
+dojox/editor/plugins/tests/editorUploadPlug.html
diff --git a/dojox/editor/plugins/TablePlugins.js b/dojox/editor/plugins/TablePlugins.js
new file mode 100644
index 0000000..a7d8054
--- /dev/null
+++ b/dojox/editor/plugins/TablePlugins.js
@@ -0,0 +1,609 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.editor.plugins.TablePlugins"]){
+dojo._hasResource["dojox.editor.plugins.TablePlugins"]=true;
+dojo.provide("dojox.editor.plugins.TablePlugins");
+dojo.require("dijit._editor._Plugin");
+dojo.require("dijit._editor.selection");
+dojo.require("dijit.Menu");
+dojo.require("dojo.i18n");
+dojo.requireLocalization("dojox.editor.plugins","TableDialog",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.experimental("dojox.editor.plugins.TablePlugins");
+dojo.declare("dojox.editor.plugins.GlobalTableHandler",dijit._editor._Plugin,{tablesConnected:false,currentlyAvailable:false,alwaysAvailable:false,availableCurrentlySet:false,initialized:false,tableData:null,shiftKeyDown:false,editorDomNode:null,undoEnabled:dojo.isIE,doMixins:function(){
+dojo.mixin(this.editor,{getAncestorElement:function(_1){
+return dojo.withGlobal(this.window,"getAncestorElement",dijit._editor.selection,[_1]);
+},hasAncestorElement:function(_2){
+return true;
+return dojo.withGlobal(this.window,"hasAncestorElement",dijit._editor.selection,[_2]);
+},selectElement:function(_3){
+dojo.withGlobal(this.window,"selectElement",dijit._editor.selection,[_3]);
+},byId:function(id){
+return dojo.withGlobal(this.window,"byId",dojo,[id]);
+},query:function(_5,_6,_7){
+var ar=dojo.withGlobal(this.window,"query",dojo,[_5,_6]);
+return (_7)?ar[0]:ar;
+}});
+},initialize:function(_9){
+if(this.initialized){
+return;
+}
+this.initialized=true;
+this.editor=_9;
+this.editorDomNode=this.editor.editNode||this.editor.iframe.document.body.firstChild;
+dojo.connect(this.editorDomNode,"mouseup",this.editor,"onClick");
+dojo.connect(this.editor,"onDisplayChanged",this,"checkAvailable");
+this.doMixins();
+this.connectDraggable();
+},getTableInfo:function(_a){
+if(_a){
+this._tempStoreTableData(false);
+}
+if(this.tableData){
+
+return this.tableData;
+}
+var tr,_c,td,_e,_f,_10,_11,_12;
+td=this.editor.getAncestorElement("td");
+if(td){
+tr=td.parentNode;
+}
+_f=this.editor.getAncestorElement("table");
+_e=dojo.query("td",_f);
+_e.forEach(function(d,i){
+if(td==d){
+_11=i;
+}
+});
+_c=dojo.query("tr",_f);
+_c.forEach(function(r,i){
+if(tr==r){
+_12=i;
+}
+});
+_10=_e.length/_c.length;
+var o={tbl:_f,td:td,tr:tr,trs:_c,tds:_e,rows:_c.length,cols:_10,tdIndex:_11,trIndex:_12,colIndex:_11%_10};
+
+this.tableData=o;
+this._tempStoreTableData(500);
+return this.tableData;
+},connectDraggable:function(){
+if(!dojo.isIE){
+return;
+}
+this.editorDomNode.ondragstart=dojo.hitch(this,"onDragStart");
+this.editorDomNode.ondragend=dojo.hitch(this,"onDragEnd");
+},onDragStart:function(){
+var e=window.event;
+if(!e.srcElement.id){
+e.srcElement.id="tbl_"+(new Date().getTime());
+}
+},onDragEnd:function(){
+var e=window.event;
+var _1a=e.srcElement;
+var id=_1a.id;
+var win=this.editor.window;
+if(_1a.tagName.toLowerCase()=="table"){
+setTimeout(function(){
+var _1d=dojo.withGlobal(win,"byId",dojo,[id]);
+dojo.removeAttr(_1d,"align");
+},100);
+}
+},checkAvailable:function(){
+if(this.availableCurrentlySet){
+return this.currentlyAvailable;
+}
+if(!this.editor){
+return false;
+}
+if(this.alwaysAvailable){
+return true;
+}
+this.currentlyAvailable=this.editor.hasAncestorElement("table");
+if(this.currentlyAvailable){
+this.connectTableKeys();
+}else{
+this.disconnectTableKeys();
+}
+this._tempAvailability(500);
+dojo.publish("available",[this.currentlyAvailable]);
+return this.currentlyAvailable;
+},_prepareTable:function(tbl){
+var tds=this.editor.query("td",tbl);
+
+if(!tds[0].id){
+tds.forEach(function(td,i){
+if(!td.id){
+td.id="tdid"+i+this.getTimeStamp();
+}
+},this);
+}
+return tds;
+},getTimeStamp:function(){
+return Math.floor(new Date().getTime()*1e-8);
+},_tempStoreTableData:function(_22){
+if(_22===true){
+}else{
+if(_22===false){
+this.tableData=null;
+}else{
+if(_22===undefined){
+console.warn("_tempStoreTableData must be passed an argument");
+}else{
+setTimeout(dojo.hitch(this,function(){
+this.tableData=null;
+}),_22);
+}
+}
+}
+},_tempAvailability:function(_23){
+if(_23===true){
+this.availableCurrentlySet=true;
+}else{
+if(_23===false){
+this.availableCurrentlySet=false;
+}else{
+if(_23===undefined){
+console.warn("_tempAvailability must be passed an argument");
+}else{
+this.availableCurrentlySet=true;
+setTimeout(dojo.hitch(this,function(){
+this.availableCurrentlySet=false;
+}),_23);
+}
+}
+}
+},connectTableKeys:function(){
+if(this.tablesConnected){
+return;
+}
+this.tablesConnected=true;
+var _24=(this.editor.iframe)?this.editor.document:this.editor.editNode;
+this.cnKeyDn=dojo.connect(_24,"onkeydown",this,"onKeyDown");
+this.cnKeyUp=dojo.connect(_24,"onkeyup",this,"onKeyUp");
+dojo.connect(_24,"onkeypress",this,"onKeyUp");
+},disconnectTableKeys:function(){
+dojo.disconnect(this.cnKeyDn);
+dojo.disconnect(this.cnKeyUp);
+this.tablesConnected=false;
+},onKeyDown:function(evt){
+var key=evt.keyCode;
+if(key==16){
+this.shiftKeyDown=true;
+}
+if(key==9){
+
+var o=this.getTableInfo();
+o.tdIndex=(this.shiftKeyDown)?o.tdIndex-1:tabTo=o.tdIndex+1;
+if(o.tdIndex>=0&&o.tdIndex<o.tds.length){
+this.editor.selectElement(o.tds[o.tdIndex]);
+this.currentlyAvailable=true;
+this._tempAvailability(true);
+this._tempStoreTableData(true);
+this.stopEvent=true;
+}else{
+this.stopEvent=false;
+this.onDisplayChanged();
+}
+if(this.stopEvent){
+dojo.stopEvent(evt);
+}
+}
+},onKeyUp:function(evt){
+var key=evt.keyCode;
+if(key==16){
+this.shiftKeyDown=false;
+}
+if(key==37||key==38||key==39||key==40){
+this.onDisplayChanged();
+}
+if(key==9&&this.stopEvent){
+dojo.stopEvent(evt);
+}
+},onDisplayChanged:function(){
+this.currentlyAvailable=false;
+this._tempStoreTableData(false);
+this._tempAvailability(false);
+this.checkAvailable();
+}});
+tablePluginHandler=new dojox.editor.plugins.GlobalTableHandler();
+dojo.declare("dojox.editor.plugins.TablePlugins",dijit._editor._Plugin,{iconClassPrefix:"editorIcon",useDefaultCommand:false,buttonClass:dijit.form.Button,commandName:"",label:"",alwaysAvailable:false,undoEnabled:false,constructor:function(){
+switch(this.commandName){
+case "colorTableCell":
+this.buttonClass=dijit.form.DropDownButton;
+this.dropDown=new dijit.ColorPalette();
+this.connect(this.dropDown,"onChange",function(_2a){
+this.modTable(null,_2a);
+});
+break;
+case "modifyTable":
+this.buttonClass=dijit.form.DropDownButton;
+this.modTable=this.launchModifyDialog;
+break;
+case "insertTable":
+this.alwaysAvailable=true;
+this.buttonClass=dijit.form.DropDownButton;
+this.modTable=this.launchInsertDialog;
+break;
+case "tableContextMenu":
+this.connect(this,"setEditor",function(){
+this._createContextMenu();
+this.button.domNode.style.display="none";
+});
+break;
+}
+dojo.subscribe("available",this,"onDisplayChanged");
+},onDisplayChanged:function(_2b){
+if(!this.alwaysAvailable){
+this.available=_2b;
+this.button.attr("disabled",!this.available);
+}
+},setEditor:function(){
+this.inherited(arguments);
+this.onEditorLoaded();
+},onEditorLoaded:function(){
+tablePluginHandler.initialize(this.editor);
+},_createContextMenu:function(){
+var _2c=dojo.isFF?this.editor.editNode:this.editorDomNode;
+var _2d=new dijit.Menu({targetNodeIds:[_2c],id:"progMenu",contextMenuForWindow:dojo.isIE});
+var _M=dijit.MenuItem;
+var _2f=dojo.i18n.getLocalization("dojox.editor.plugins","TableDialog",this.lang);
+_2d.addChild(new _M({label:_2f.selectTableLabel,onClick:dojo.hitch(this,"selectTable")}));
+_2d.addChild(new dijit.MenuSeparator());
+_2d.addChild(new _M({label:_2f.insertTableRowBeforeLabel,onClick:dojo.hitch(this,"modTable","insertTableRowBefore")}));
+_2d.addChild(new _M({label:_2f.insertTableRowAfterLabel,onClick:dojo.hitch(this,"modTable","insertTableRowAfter")}));
+_2d.addChild(new _M({label:_2f.insertTableColumnBeforeLabel,onClick:dojo.hitch(this,"modTable","insertTableColumnBefore")}));
+_2d.addChild(new _M({label:_2f.insertTableColumnAfterLabel,onClick:dojo.hitch(this,"modTable","insertTableColumnAfter")}));
+_2d.addChild(new dijit.MenuSeparator());
+_2d.addChild(new _M({label:_2f.deleteTableRowLabel,onClick:dojo.hitch(this,"modTable","deleteTableRow")}));
+_2d.addChild(new _M({label:_2f.deleteTableColumnLabel,onClick:dojo.hitch(this,"modTable","deleteTableColumn")}));
+_2d._openMyself=function(e){
+if(!tablePluginHandler.checkAvailable()){
+return;
+}
+if(this.leftClickToOpen&&e.button>0){
+return;
+}
+dojo.stopEvent(e);
+var x,y;
+if(dojo.isIE){
+x=e.x;
+y=e.y;
+}else{
+x=e.screenX;
+y=e.screenY+25;
+}
+var _33=this;
+var _34=dijit.getFocus(this);
+function _35(){
+dijit.focus(_34);
+dijit.popup.close(_33);
+};
+var res=dijit.popup.open({popup:this,x:x,y:y,onExecute:_35,onCancel:_35,orient:this.isLeftToRight()?"L":"R"});
+var v=dijit.getViewport();
+if(res.y+res.h>v.h){
+if(e.screenY-res.h>=0){
+y=e.screenY-res.h;
+}else{
+y=0;
+}
+dijit.popup.close(this);
+res=dijit.popup.open({popup:this,x:x,y:y,onExecute:_35,onCancel:_35,orient:this.isLeftToRight()?"L":"R"});
+}
+
+this.focus();
+this._onBlur=function(){
+this.inherited("_onBlur",arguments);
+dijit.popup.close(this);
+};
+};
+this.menu=_2d;
+},selectTable:function(){
+var o=this.getTableInfo();
+dojo.withGlobal(this.editor.window,"selectElement",dijit._editor.selection,[o.tbl]);
+},launchInsertDialog:function(){
+var w=new dojox.editor.plugins.EditorTableDialog({});
+w.show();
+var c=dojo.connect(w,"onBuildTable",this,function(obj){
+dojo.disconnect(c);
+var res=this.editor.execCommand("inserthtml",obj.htmlText);
+});
+},launchModifyDialog:function(){
+var o=this.getTableInfo();
+
+var w=new dojox.editor.plugins.EditorModifyTableDialog({table:o.tbl});
+w.show();
+this.connect(w,"onSetTable",function(_3f){
+var o=this.getTableInfo();
+
+dojo.attr(o.td,"bgcolor",_3f);
+});
+},_initButton:function(){
+this.command=this.commandName;
+this.label=this.editor.commands[this.command]=this._makeTitle(this.command);
+this.inherited(arguments);
+delete this.command;
+if(this.commandName!="colorTableCell"){
+this.connect(this.button.domNode,"click","modTable");
+}
+if(this.commandName=="tableContextMenu"){
+this.button.domNode.display="none";
+}
+this.onDisplayChanged(false);
+},modTable:function(cmd,_42){
+this.begEdit();
+var o=this.getTableInfo();
+var sw=(dojo.isString(cmd))?cmd:this.commandName;
+var r,c,i;
+var _48=false;
+switch(sw){
+case "insertTableRowBefore":
+r=o.tbl.insertRow(o.trIndex);
+for(i=0;i<o.cols;i++){
+c=r.insertCell(-1);
+c.innerHTML=" ";
+}
+break;
+case "insertTableRowAfter":
+r=o.tbl.insertRow(o.trIndex+1);
+for(i=0;i<o.cols;i++){
+c=r.insertCell(-1);
+c.innerHTML=" ";
+}
+break;
+case "insertTableColumnBefore":
+o.trs.forEach(function(r){
+c=r.insertCell(o.colIndex);
+c.innerHTML=" ";
+});
+_48=true;
+break;
+case "insertTableColumnAfter":
+o.trs.forEach(function(r){
+c=r.insertCell(o.colIndex+1);
+c.innerHTML=" ";
+});
+_48=true;
+break;
+case "deleteTableRow":
+o.tbl.deleteRow(o.trIndex);
+
+break;
+case "deleteTableColumn":
+o.trs.forEach(function(tr){
+tr.deleteCell(o.colIndex);
+});
+_48=true;
+break;
+case "colorTableCell":
+var tds=this.getSelectedCells(o.tbl);
+dojo.forEach(tds,function(td){
+dojo.style(td,"backgroundColor",_42);
+});
+break;
+case "modifyTable":
+break;
+case "insertTable":
+break;
+}
+if(_48){
+this.makeColumnsEven();
+}
+this.endEdit();
+},begEdit:function(){
+if(tablePluginHandler.undoEnabled){
+
+if(this.editor.customUndo){
+this.editor.beginEditing();
+}else{
+this.valBeforeUndo=this.editor.getValue();
+
+}
+}
+},endEdit:function(){
+if(tablePluginHandler.undoEnabled){
+if(this.editor.customUndo){
+this.editor.endEditing();
+}else{
+var _4e=this.editor.getValue();
+this.editor.setValue(this.valBeforeUndo);
+this.editor.replaceValue(_4e);
+}
+this.editor.onDisplayChanged();
+}
+},makeColumnsEven:function(){
+setTimeout(dojo.hitch(this,function(){
+var o=this.getTableInfo(true);
+var w=Math.floor(100/o.cols);
+o.tds.forEach(function(d){
+dojo.attr(d,"width",w+"%");
+});
+}),10);
+},getTableInfo:function(_52){
+return tablePluginHandler.getTableInfo(_52);
+},_makeTitle:function(str){
+var s=str.split(""),ns=[];
+dojo.forEach(str,function(c,i){
+if(c.charCodeAt(0)<91&&i>0&&ns[i-1].charCodeAt(0)!=32){
+ns.push(" ");
+}
+if(i==0){
+c=c.toUpperCase();
+}
+ns.push(c);
+});
+return ns.join("");
+},getSelectedCells:function(){
+var _58=[];
+var tbl=this.getTableInfo().tbl;
+var tds=tablePluginHandler._prepareTable(tbl);
+var e=this.editor;
+var r;
+if(!dojo.isIE){
+r=dijit.range.getSelection(e.window);
+var _5d=false;
+var _5e=false;
+if(r.anchorNode&&r.anchorNode.tagName&&r.anchorNode.tagName.toLowerCase()=="tr"){
+var trs=dojo.query("tr",tbl);
+var _60=[];
+trs.forEach(function(tr,i){
+if(!_5d&&(tr==r.anchorNode||tr==r.focusNode)){
+_60.push(tr);
+_5d=true;
+if(r.anchorNode==r.focusNode){
+_5e=true;
+}
+}else{
+if(_5d&&!_5e){
+_60.push(tr);
+if(tr==r.anchorNode||tr==r.focusNode){
+_5e=true;
+}
+}
+}
+});
+dojo.forEach(_60,function(tr){
+_58=_58.concat(dojo.query("td",tr));
+},this);
+}else{
+tds.forEach(function(td,i){
+if(!_5d&&(td.id==r.anchorNode.parentNode.id||td.id==r.focusNode.parentNode.id)){
+_58.push(td);
+_5d=true;
+if(r.anchorNode.parentNode.id==r.focusNode.parentNode.id){
+_5e=true;
+}
+}else{
+if(_5d&&!_5e){
+_58.push(td);
+if(td.id==r.focusNode.parentNode.id||td.id==r.anchorNode.parentNode.id){
+_5e=true;
+}
+}
+}
+});
+
+}
+}
+if(dojo.isIE){
+r=document.selection.createRange();
+var str=r.htmlText.match(/id=\w*/g);
+dojo.forEach(str,function(a){
+var id=a.substring(3,a.length);
+_58.push(e.byId(id));
+},this);
+}
+return _58;
+}});
+dojo.provide("dojox.editor.plugins.EditorTableDialog");
+dojo.require("dijit.Dialog");
+dojo.require("dijit.form.TextBox");
+dojo.require("dijit.form.FilteringSelect");
+dojo.require("dijit.form.Button");
+dojo.declare("dojox.editor.plugins.EditorTableDialog",[dijit.Dialog],{baseClass:"EditorTableDialog",widgetsInTemplate:true,templateString:"<div class=\"dijitDialog\" tabindex=\"-1\" waiRole=\"dialog\" waiState=\"labelledby-${id}_title\">\n\t<div dojoAttachPoint=\"titleBar\" class=\"dijitDialogTitleBar\">\n\t<span dojoAttachPoint=\"titleNode\" class=\"dijitDialogTitle\" id=\"${id}_title\">${insertTableTitle}</span>\n\t<span dojoAttachPoint=\"closeButtonNode\" class=\"dijitDialogCloseIcon\ [...]
+var _69=dojo.i18n.getLocalization("dojox.editor.plugins","TableDialog",this.lang);
+dojo.mixin(this,_69);
+this.inherited(arguments);
+},postCreate:function(){
+dojo.addClass(this.domNode,this.baseClass);
+this.inherited(arguments);
+},onInsert:function(){
+
+var _6a=this.selectRow.attr("value")||1,_6b=this.selectCol.attr("value")||1,_6c=this.selectWidth.attr("value"),_6d=this.selectWidthType.attr("value"),_6e=this.selectBorder.attr("value"),pad=this.selectPad.attr("value"),_70=this.selectSpace.attr("value"),_id="tbl_"+(new Date().getTime()),t="<table id=\""+_id+"\"width=\""+_6c+((_6d=="percent")?"%":"")+"\" border=\""+_6e+"\" cellspacing=\""+_70+"\" cellpadding=\""+pad+"\">\n";
+for(var r=0;r<_6a;r++){
+t+="\t<tr>\n";
+for(var c=0;c<_6b;c++){
+t+="\t\t<td width=\""+(Math.floor(100/_6b))+"%\"> </td>\n";
+}
+t+="\t</tr>\n";
+}
+t+="</table>";
+this.onBuildTable({htmlText:t,id:_id});
+this.hide();
+},onBuildTable:function(_75){
+}});
+dojo.provide("dojox.editor.plugins.EditorModifyTableDialog");
+dojo.require("dijit.ColorPalette");
+dojo.declare("dojox.editor.plugins.EditorModifyTableDialog",[dijit.Dialog],{baseClass:"EditorTableDialog",widgetsInTemplate:true,table:null,tableAtts:{},templateString:"<div class=\"dijitDialog\" tabindex=\"-1\" waiRole=\"dialog\" waiState=\"labelledby-${id}_title\">\n\t<div dojoAttachPoint=\"titleBar\" class=\"dijitDialogTitleBar\">\n\t<span dojoAttachPoint=\"titleNode\" class=\"dijitDialogTitle\" id=\"${id}_title\">${modifyTableTitle}</span>\n\t<span dojoAttachPoint=\"closeButtonNode\" [...]
+var _76=dojo.i18n.getLocalization("dojox.editor.plugins","TableDialog",this.lang);
+dojo.mixin(this,_76);
+this.inherited(arguments);
+},postCreate:function(){
+dojo.addClass(this.domNode,this.baseClass);
+this.inherited(arguments);
+this.connect(this.borderCol,"click",function(){
+var div=document.createElement("div");
+var w=new dijit.ColorPalette({},div);
+dijit.popup.open({popup:w,around:this.borderCol});
+this.connect(w,"onChange",function(_79){
+dijit.popup.close(w);
+this.setBrdColor(_79);
+});
+});
+this.connect(this.backgroundCol,"click",function(){
+var div=document.createElement("div");
+var w=new dijit.ColorPalette({},div);
+dijit.popup.open({popup:w,around:this.backgroundCol});
+this.connect(w,"onChange",function(_7c){
+dijit.popup.close(w);
+this.setBkColor(_7c);
+});
+});
+this.setBrdColor(dojo.attr(this.table,"bordercolor"));
+this.setBkColor(dojo.attr(this.table,"bgcolor"));
+var w=dojo.attr(this.table,"width");
+var p="pixels";
+if(w.indexOf("%")>-1){
+p="percent";
+w=w.replace(/%/,"");
+}
+this.selectWidth.attr("value",w);
+this.selectWidthType.attr("value",p);
+this.selectBorder.attr("value",dojo.attr(this.table,"border"));
+this.selectPad.attr("value",dojo.attr(this.table,"cellpadding"));
+this.selectSpace.attr("value",dojo.attr(this.table,"cellspacing"));
+this.selectAlign.attr("value",dojo.attr(this.table,"align"));
+},setBrdColor:function(_7f){
+this.brdColor=_7f;
+dojo.style(this.borderCol,"backgroundColor",_7f);
+},setBkColor:function(_80){
+this.bkColor=_80;
+dojo.style(this.backgroundCol,"backgroundColor",_80);
+},onSet:function(){
+dojo.attr(this.table,"bordercolor",this.brdColor);
+dojo.attr(this.table,"bgcolor",this.bkColor);
+dojo.attr(this.table,"width",(this.selectWidth.attr("value")+((this.selectWidthType.attr("value")=="pixels")?"":"%")));
+dojo.attr(this.table,"border",this.selectBorder.attr("value"));
+dojo.attr(this.table,"cellpadding",this.selectPad.attr("value"));
+dojo.attr(this.table,"cellspacing",this.selectSpace.attr("value"));
+dojo.attr(this.table,"align",this.selectAlign.attr("value"));
+this.hide();
+},onSetTable:function(_81){
+}});
+dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
+if(o.plugin){
+return;
+}
+if(o.args&&o.args.command){
+var cmd=o.args.command.charAt(0).toLowerCase()+o.args.command.substring(1,o.args.command.length);
+switch(cmd){
+case "insertTableRowBefore":
+case "insertTableRowAfter":
+case "insertTableColumnBefore":
+case "insertTableColumnAfter":
+case "deleteTableRow":
+case "deleteTableColumn":
+case "colorTableCell":
+case "modifyTable":
+case "insertTable":
+case "tableContextMenu":
+o.plugin=new dojox.editor.plugins.TablePlugins({commandName:cmd});
+break;
+}
+}
+});
+}
diff --git a/dojox/editor/plugins/UploadImage.js b/dojox/editor/plugins/UploadImage.js
new file mode 100644
index 0000000..4de9649
--- /dev/null
+++ b/dojox/editor/plugins/UploadImage.js
@@ -0,0 +1,54 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.editor.plugins.UploadImage"]){
+dojo._hasResource["dojox.editor.plugins.UploadImage"]=true;
+dojo.provide("dojox.editor.plugins.UploadImage");
+dojo.require("dijit._editor._Plugin");
+dojo.require("dojox.form.FileUploader");
+dojo.experimental("dojox.editor.plugins.UploadImage");
+dojo.declare("dojox.editor.plugins.UploadImage",dijit._editor._Plugin,{tempImageUrl:"",iconClassPrefix:"editorIcon",useDefaultCommand:false,uploadUrl:"",fileInput:null,label:"Mike",_initButton:function(){
+this.command="uploadImage";
+this.editor.commands[this.command]="Upload Image";
+this.inherited("_initButton",arguments);
+delete this.command;
+setTimeout(dojo.hitch(this,"createFileInput"),200);
+},createFileInput:function(){
+var _1=[["Jpeg File","*.jpg;*.jpeg"],["GIF File","*.gif"],["PNG File","*.png"],["All Images","*.jpg;*.jpeg;*.gif;*.png"]];
+console.warn("downloadPath:",this.downloadPath);
+this.fileInput=new dojox.form.FileUploader({isDebug:true,button:this.button,uploadUrl:this.uploadUrl,uploadOnChange:true,selectMultipleFiles:false,fileMask:_1});
+dojo.connect(this.fileInput,"onChange",this,"insertTempImage");
+dojo.connect(this.fileInput,"onComplete",this,"onComplete");
+},onComplete:function(_2,_3,_4){
+_2=_2[0];
+var _5=dojo.withGlobal(this.editor.window,"byId",dojo,[this.currentImageId]);
+var _6;
+if(this.downloadPath){
+_6=this.downloadPath+_2.name;
+}else{
+_6=_2.file;
+}
+_5.src=_6;
+if(_2.width){
+_5.width=_2.width;
+_5.height=_2.height;
+}
+},insertTempImage:function(){
+this.currentImageId="img_"+(new Date().getTime());
+var _7="<img id=\""+this.currentImageId+"\" src=\""+this.tempImageUrl+"\" width=\"32\" height=\"32\"/>";
+this.editor.execCommand("inserthtml",_7);
+}});
+dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
+if(o.plugin){
+return;
+}
+switch(o.args.name){
+case "uploadImage":
+o.plugin=new dojox.editor.plugins.UploadImage({url:o.args.url});
+}
+});
+}
diff --git a/dojox/editor/plugins/nls/TableDialog.js b/dojox/editor/plugins/nls/TableDialog.js
new file mode 100644
index 0000000..3e2f71f
--- /dev/null
+++ b/dojox/editor/plugins/nls/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Set","insertTableTitle":"Insert Table","insertTableRowAfterLabel":"Add Row After","center":"center","deleteTableColumnLabel":"Delete Column","right":"right","insertTableColumnBeforeLabel":"Add Column Before","tableWidth":"Table Width:","buttonInsert":"Insert","default":"default","align":"Align:","insertTableRowBeforeLabel":"Add Row Before","cellSpacing":"Cell Spacing:","pixels":"pixels","selectTableLabel":"Select Table","rows":"Rows:","modifyTableTitle":"Modify Table","cel [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/ar/TableDialog.js b/dojox/editor/plugins/nls/ar/TableDialog.js
new file mode 100644
index 0000000..d350f48
--- /dev/null
+++ b/dojox/editor/plugins/nls/ar/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"تحديد","insertTableTitle":"‏ادراج جدول‏","insertTableRowAfterLabel":"اضافة صف بعد","center":"توسيط","deleteTableColumnLabel":"حذف عمود","right":"لليمين","insertTableColumnBeforeLabel":"اضافة عمود قبل","tableWidth":"عرض الجدول:","buttonInsert":"‏ادراج‏","default":"المفترض","align":"محاذاة:","insertTableRowBeforeLabel":"اضافة صف قبل","cellSpacing":"تباعد الخانة:","pixels":"عنصر صورة","selectTableLabel":"تحديد جدول","rows":"الصفوف:","modifyTableTitle":"تعديل جدول","cellPaddin [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/ca/TableDialog.js b/dojox/editor/plugins/nls/ca/TableDialog.js
new file mode 100644
index 0000000..5d38c64
--- /dev/null
+++ b/dojox/editor/plugins/nls/ca/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Defineix","insertTableTitle":"Insereix taula","insertTableRowAfterLabel":"Afegeix fila després","center":"centrat","deleteTableColumnLabel":"Suprimeix columna","right":"dreta","insertTableColumnBeforeLabel":"Afegeix columna abans","tableWidth":"Amplada de taula:","buttonInsert":"Insereix","default":"default","align":"Alinea:","insertTableRowBeforeLabel":"Afegeix fila abans","cellSpacing":"Espaiat de cel·la:","pixels":"píxels","selectTableLabel":"Selecciona taula","rows":"F [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/cs/TableDialog.js b/dojox/editor/plugins/nls/cs/TableDialog.js
new file mode 100644
index 0000000..3582263
--- /dev/null
+++ b/dojox/editor/plugins/nls/cs/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Nastavit","insertTableTitle":"Vložit tabulku","insertTableRowAfterLabel":"Přidat řádek za","center":"střed","deleteTableColumnLabel":"Odstranit sloupec","right":"vpravo","insertTableColumnBeforeLabel":"Přidat sloupec před","tableWidth":"Šířka tabulky:","buttonInsert":"Vložit","default":"výchozí","align":"Zarovnat:","insertTableRowBeforeLabel":"Přidat řádek před","cellSpacing":"Odstup buněk:","pixels":"pixelů","selectTableLabel":"Vybrat tabulku","rows":"Řádky:","modifyTable [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/da/TableDialog.js b/dojox/editor/plugins/nls/da/TableDialog.js
new file mode 100644
index 0000000..1e4b8db
--- /dev/null
+++ b/dojox/editor/plugins/nls/da/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Definér","insertTableTitle":"Indsæt tabel","insertTableRowAfterLabel":"Tilføj række efter","center":"centreret","deleteTableColumnLabel":"Slet kolonne","right":"højre","insertTableColumnBeforeLabel":"Tilføj kolonne før","tableWidth":"Tabelbredde:","buttonInsert":"Indsæt","default":"standard","align":"Justér:","insertTableRowBeforeLabel":"Tilføj række før","cellSpacing":"Celleafstand:","pixels":"pixel","selectTableLabel":"Markér tabel","rows":"Rækker:","modifyTableTitle":"R [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/de/TableDialog.js b/dojox/editor/plugins/nls/de/TableDialog.js
new file mode 100644
index 0000000..2ad099f
--- /dev/null
+++ b/dojox/editor/plugins/nls/de/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Festlegen","insertTableTitle":"Tabelle einfügen","insertTableRowAfterLabel":"Zeile danach einfügen","center":"Mitte","deleteTableColumnLabel":"Spalte löschen","right":"Rechts","insertTableColumnBeforeLabel":"Spalte davor einfügen","tableWidth":"Tabellenbreite:","buttonInsert":"Einfügen","default":"Standard","align":"Ausrichten:","insertTableRowBeforeLabel":"Zeile davor einfügen","cellSpacing":"Zellenabstand:","pixels":"Pixel","selectTableLabel":"Tabelle auswählen","rows":" [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/el/TableDialog.js b/dojox/editor/plugins/nls/el/TableDialog.js
new file mode 100644
index 0000000..7e5b038
--- /dev/null
+++ b/dojox/editor/plugins/nls/el/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Ορισμός","insertTableTitle":"Εισαγωγή πίνακα","insertTableRowAfterLabel":"Προσθήκη γραμμής μετά","center":"κέντρο","deleteTableColumnLabel":"Διαγραφή στήλης","right":"δεξιά","insertTableColumnBeforeLabel":"Προσθήκη στήλης πριν","tableWidth":"Πλάτος πίνακα:","buttonInsert":"Εισαγωγή","default":"προεπιλογή","align":"Στοίχιση:","insertTableRowBeforeLabel":"Προσθήκη γραμμής πριν","cellSpacing":"Απόσταση κελιών","pixels":"εικονοστοιχεία","selectTableLabel":"Επιλογή πίνακα","row [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/es/TableDialog.js b/dojox/editor/plugins/nls/es/TableDialog.js
new file mode 100644
index 0000000..a170cf2
--- /dev/null
+++ b/dojox/editor/plugins/nls/es/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Establecer","insertTableTitle":"Insertar tabla","insertTableRowAfterLabel":"Añadir tabla detrás","center":"centro","deleteTableColumnLabel":"Suprimir columna","right":"derecha","insertTableColumnBeforeLabel":"Añadir columna delante","tableWidth":"Ancho de tabla:","buttonInsert":"Insertar","default":"predeterminado","align":"Alinear:","insertTableRowBeforeLabel":"Añadir tabla delante","cellSpacing":"Espaciado de celda:","pixels":"píxeles","selectTableLabel":"Seleccionar tab [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/fi/TableDialog.js b/dojox/editor/plugins/nls/fi/TableDialog.js
new file mode 100644
index 0000000..07b5daa
--- /dev/null
+++ b/dojox/editor/plugins/nls/fi/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Aseta","insertTableTitle":"Lisää taulukko","insertTableRowAfterLabel":"Lisää rivi jälkeen","center":"keskitetty","deleteTableColumnLabel":"Poista sarake","right":"oikea","insertTableColumnBeforeLabel":"Lisää sarake ennen","tableWidth":"Taulukon leveys:","buttonInsert":"Lisää","default":"oletus","align":"Tasaus:","insertTableRowBeforeLabel":"Lisää rivi ennen","cellSpacing":"Solujen väli:","pixels":"kuvapistettä","selectTableLabel":"Valitse taulukko","rows":"Rivit:","modifyT [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/fr/TableDialog.js b/dojox/editor/plugins/nls/fr/TableDialog.js
new file mode 100644
index 0000000..f637e7e
--- /dev/null
+++ b/dojox/editor/plugins/nls/fr/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Définir","insertTableTitle":"Insérer un tableau","insertTableRowAfterLabel":"Ajouter une ligne après","center":"centré","deleteTableColumnLabel":"Supprimer la colonne","right":"aligné à droite","insertTableColumnBeforeLabel":"Ajouter une colonne avant","tableWidth":"Largeur de table :","buttonInsert":"Insérer","default":"par défaut","align":"Aligner :","insertTableRowBeforeLabel":"Ajouter une ligne avant","cellSpacing":"Espacement des cellules :","pixels":"pixels","selectT [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/he/TableDialog.js b/dojox/editor/plugins/nls/he/TableDialog.js
new file mode 100644
index 0000000..b2a2132
--- /dev/null
+++ b/dojox/editor/plugins/nls/he/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"הגדרה","insertTableTitle":"הוספת טבלה","insertTableRowAfterLabel":"הוספת שורה אחרי","center":"מרכז","deleteTableColumnLabel":"מחיקת עמודה","right":"שמאל","insertTableColumnBeforeLabel":"הוספת עמודה לפני","tableWidth":"רוחב טבלה:","buttonInsert":"הוספה","default":"ברירת מחדל","align":"יישור:","insertTableRowBeforeLabel":"הוספת שורה לפני","cellSpacing":"ריווח תאים:","pixels":"פיקסלים","selectTableLabel":"בחירת טבלה","rows":"שורות:","modifyTableTitle":"שינוי טבלה","cellPaddin [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/hu/TableDialog.js b/dojox/editor/plugins/nls/hu/TableDialog.js
new file mode 100644
index 0000000..cff14fb
--- /dev/null
+++ b/dojox/editor/plugins/nls/hu/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Beállítás","insertTableTitle":"Táblázat beszúrása","insertTableRowAfterLabel":"Sor hozzáadása utána","center":"középre","deleteTableColumnLabel":"Oszlop törlése","right":"jobbra","insertTableColumnBeforeLabel":"Oszlop hozzáadása elé","tableWidth":"Táblázat szélessége:","buttonInsert":"Beszúrás","default":"alapértelmezés","align":"Igazítás:","insertTableRowBeforeLabel":"Sor hozzáadása elé","cellSpacing":"Cellatávolság:","pixels":"pixel","selectTableLabel":"Táblázat kiválasz [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/it/TableDialog.js b/dojox/editor/plugins/nls/it/TableDialog.js
new file mode 100644
index 0000000..21b7548
--- /dev/null
+++ b/dojox/editor/plugins/nls/it/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Imposta","insertTableTitle":"Inserisci tabella","insertTableRowAfterLabel":"Aggiungi riga dopo","center":"centro","deleteTableColumnLabel":"Elimina colonna","right":"destra","insertTableColumnBeforeLabel":"Aggiungi colonna prima","tableWidth":"Larghezza tabelle:","buttonInsert":"Inserisci","default":"predefinito","align":"Allinea:","insertTableRowBeforeLabel":"Aggiungi riga prima","cellSpacing":"Spaziatura celle:","pixels":"pixel","selectTableLabel":"Seleziona tabella","ro [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/ja/TableDialog.js b/dojox/editor/plugins/nls/ja/TableDialog.js
new file mode 100644
index 0000000..cf1dcab
--- /dev/null
+++ b/dojox/editor/plugins/nls/ja/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"設定","insertTableTitle":"テーブルの挿入","insertTableRowAfterLabel":"後ろに行を追加","center":"中央","deleteTableColumnLabel":"列の削除","right":"右","insertTableColumnBeforeLabel":"前に列を追加","tableWidth":"テーブル幅:","buttonInsert":"挿入","default":"デフォルト","align":"桁揃え:","insertTableRowBeforeLabel":"前に行を追加","cellSpacing":"セル間隔:","pixels":"ピクセル","selectTableLabel":"テーブルの選択","rows":"行:","modifyTableTitle":"テーブルの変更","cellPadding":"セル余白:","deleteTableRowLabel":"行の削除","backgroundColor":"背景色:","insertTableC [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/ko/TableDialog.js b/dojox/editor/plugins/nls/ko/TableDialog.js
new file mode 100644
index 0000000..91679d9
--- /dev/null
+++ b/dojox/editor/plugins/nls/ko/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"설정","insertTableTitle":"테이블 삽입","insertTableRowAfterLabel":"뒤에 행 추가","center":"가운데","deleteTableColumnLabel":"열 삭제","right":"오른쪽","insertTableColumnBeforeLabel":"앞에 열 추가","tableWidth":"테이블 너비:","buttonInsert":"삽입","default":"기본값","align":"맞추기:","insertTableRowBeforeLabel":"앞에 행 추가","cellSpacing":"셀 간격:","pixels":"픽셀","selectTableLabel":"테이블 선택","rows":"행:","modifyTableTitle":"테이블 수정","cellPadding":"셀 채우기:","deleteTableRowLabel":"행 삭제","backgroundColor":"배경색:","insertTableC [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/nb/TableDialog.js b/dojox/editor/plugins/nls/nb/TableDialog.js
new file mode 100644
index 0000000..8d3ad55
--- /dev/null
+++ b/dojox/editor/plugins/nls/nb/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Definer","insertTableTitle":"Sett inn tabell","insertTableRowAfterLabel":"Legg til rad etter","center":"midtstill","deleteTableColumnLabel":"Slett kolonne","right":"høyre","insertTableColumnBeforeLabel":"Legg til kolonne foran","tableWidth":"Tabellbredde:","buttonInsert":"Sett inn","default":"standard","align":"Juster:","insertTableRowBeforeLabel":"Legg til rad foran","cellSpacing":"Celleavstand:","pixels":"piksler","selectTableLabel":"Velg tabell","rows":"Rader:","modifyT [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/nl/TableDialog.js b/dojox/editor/plugins/nls/nl/TableDialog.js
new file mode 100644
index 0000000..bdb4ce9
--- /dev/null
+++ b/dojox/editor/plugins/nls/nl/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Instellen","insertTableTitle":"Tabel invoegen","insertTableRowAfterLabel":"Rij onder toevoegen","center":"gecentreerd","deleteTableColumnLabel":"Kolom wissen","right":"rechts","insertTableColumnBeforeLabel":"Kolom voor toevoegen","tableWidth":"Tabelbreedte:","buttonInsert":"invoegen","default":"standaard","align":"Uitlijnen","insertTableRowBeforeLabel":"Rij boven toevoegen","cellSpacing":"Celspatiëring:","pixels":"pixels","selectTableLabel":"Tabel selecteren","rows":"Rijen [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/pl/TableDialog.js b/dojox/editor/plugins/nls/pl/TableDialog.js
new file mode 100644
index 0000000..4d2e3c4
--- /dev/null
+++ b/dojox/editor/plugins/nls/pl/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Ustaw","insertTableTitle":"Wstaw tabelę","insertTableRowAfterLabel":"Dodaj wiersz po","center":"wyśrodkuj","deleteTableColumnLabel":"Usuń kolumnę","right":"do prawej","insertTableColumnBeforeLabel":"Dodaj kolumnę przed","tableWidth":"Szerokość tabeli:","buttonInsert":"Wstaw","default":"wartość domyślna","align":"Wyrównaj:","insertTableRowBeforeLabel":"Dodaj wiersz przed","cellSpacing":"Odstępy między komórkami:","pixels":"piksle","selectTableLabel":"Wybieranie tabeli","row [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/pt-pt/TableDialog.js b/dojox/editor/plugins/nls/pt-pt/TableDialog.js
new file mode 100644
index 0000000..76394e4
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt-pt/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Definir","insertTableTitle":"Inserir tabela","insertTableRowAfterLabel":"Adicionar linha depois","center":"centro","deleteTableColumnLabel":"Eliminar coluna","right":"direita","insertTableColumnBeforeLabel":"Adicionar coluna antes","tableWidth":"Largura da tabela:","buttonInsert":"Inserir","default":"predefinição","align":"Alinhar:","insertTableRowBeforeLabel":"Adicionar linha antes","cellSpacing":"Espaçamento de células:","pixels":"píxeis","selectTableLabel":"Seleccionar  [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/pt/TableDialog.js b/dojox/editor/plugins/nls/pt/TableDialog.js
new file mode 100644
index 0000000..10f4772
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Definir","insertTableTitle":"Inserir Tabela","insertTableRowAfterLabel":"Adicionar Linha Depois","center":"centralizado","deleteTableColumnLabel":"Excluir Coluna","right":"direita","insertTableColumnBeforeLabel":"Adicionar Coluna Antes","tableWidth":"Largura da Tabela:","buttonInsert":"Inserir","default":"padrão","align":"Alinhar:","insertTableRowBeforeLabel":"Adicionar Linha Antes","cellSpacing":"Espaçamento de Célula:","pixels":"pixels","selectTableLabel":"Selecionar Tab [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/ru/TableDialog.js b/dojox/editor/plugins/nls/ru/TableDialog.js
new file mode 100644
index 0000000..2b9b1ae
--- /dev/null
+++ b/dojox/editor/plugins/nls/ru/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Задать","insertTableTitle":"Вставить таблицу","insertTableRowAfterLabel":"Добавить строку после","center":"по центру","deleteTableColumnLabel":"Удалить столбец","right":"справа","insertTableColumnBeforeLabel":"Добавить столбец до","tableWidth":"Ширина таблицы:","buttonInsert":"Вставить","default":"по умолчанию","align":"Выровнять:","insertTableRowBeforeLabel":"Добавить строку до","cellSpacing":"Отступ в ячейке:","pixels":"пикс.","selectTableLabel":"Выбрать таблицу","rows": [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/sk/TableDialog.js b/dojox/editor/plugins/nls/sk/TableDialog.js
new file mode 100644
index 0000000..b8882f9
--- /dev/null
+++ b/dojox/editor/plugins/nls/sk/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Nastaviť","insertTableTitle":"Vložiť tabuľku","insertTableRowAfterLabel":"Pridať riadok za","center":"v strede","deleteTableColumnLabel":"Vymazať stĺpec","right":"vpravo","insertTableColumnBeforeLabel":"Pridať stĺpec pred","tableWidth":"Šírka tabuľky:","buttonInsert":"Vložiť","default":"predvolená hodnota","align":"Zarovnať:","insertTableRowBeforeLabel":"Pridať riadok pred","cellSpacing":"Riadkovanie bunky:","pixels":"pixely","selectTableLabel":"Vybrať tabuľku","rows":"Ria [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/sl/TableDialog.js b/dojox/editor/plugins/nls/sl/TableDialog.js
new file mode 100644
index 0000000..974afd7
--- /dev/null
+++ b/dojox/editor/plugins/nls/sl/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Nastavi","insertTableTitle":"Vstavi tabelo","insertTableRowAfterLabel":"Dodaj vrstico za","center":"sredina","deleteTableColumnLabel":"Izbriši stolpec","right":"desno","insertTableColumnBeforeLabel":"Dodaj stolpec pred","tableWidth":"Širina tabele:","buttonInsert":"Vstavi","default":"privzeto","align":"Poravnaj:","insertTableRowBeforeLabel":"Dodaj vrstico pred","cellSpacing":"Razmik med celicami:","pixels":"piksli","selectTableLabel":"Izberi tabelo","rows":"Vrstice:","modi [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/sv/TableDialog.js b/dojox/editor/plugins/nls/sv/TableDialog.js
new file mode 100644
index 0000000..bf7db0e
--- /dev/null
+++ b/dojox/editor/plugins/nls/sv/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Ange","insertTableTitle":"Infoga tabell","insertTableRowAfterLabel":"Lägg till rad efter","center":"centrera","deleteTableColumnLabel":"Ta bort kolumn","right":"högerjustera","insertTableColumnBeforeLabel":"Lägg till kolumn före","tableWidth":"Tabellbredd:","buttonInsert":"Infoga","default":"standard","align":"Justera:","insertTableRowBeforeLabel":"Lägg till rad före","cellSpacing":"Cellavstånd:","pixels":"bildpunkter","selectTableLabel":"Välj tabell","rows":"Rader:","modi [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/th/TableDialog.js b/dojox/editor/plugins/nls/th/TableDialog.js
new file mode 100644
index 0000000..5baeba0
--- /dev/null
+++ b/dojox/editor/plugins/nls/th/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"ตั้งค่า","insertTableTitle":"แทรกตาราง","insertTableRowAfterLabel":"เพิ่มแถวหลัง","center":"กึ่งกลาง","deleteTableColumnLabel":"ลบคอลัมน์","right":"ขวา","insertTableColumnBeforeLabel":"เพิ่มคอลัมน์ก่อน","tableWidth":"ความกว้างของตาราง:","buttonInsert":"แทรก","default":"ดีฟอลต์","align":"จัดตำแหน่ง:","insertTableRowBeforeLabel":"เพิ่มแถวก่อน","cellSpacing":"ระยะห่างเซลล์:","pixels":"พิกเซล","selectTableLabel":"เลือกตาราง","rows":"แถว:","modifyTableTitle":"ปรับเปลี่ยนตาราง", [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/tr/TableDialog.js b/dojox/editor/plugins/nls/tr/TableDialog.js
new file mode 100644
index 0000000..0cfb948
--- /dev/null
+++ b/dojox/editor/plugins/nls/tr/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"Ayarla","insertTableTitle":"Tablo Ekle","insertTableRowAfterLabel":"Satırı Arkasına Ekle","center":"orta","deleteTableColumnLabel":"Sütunu Sil","right":"sağ","insertTableColumnBeforeLabel":"Sütunu Önüne Ekle","tableWidth":"Tablo Genişliği","buttonInsert":"Ekle","default":"varsayılan","align":"Hizala:","insertTableRowBeforeLabel":"Satırı Önüne Ekle","cellSpacing":"Hücre Aralığı:","pixels":"piksel","selectTableLabel":"Tablo Seç","rows":"Satırlar:","modifyTableTitle":"Tabloyu [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/zh-tw/TableDialog.js b/dojox/editor/plugins/nls/zh-tw/TableDialog.js
new file mode 100644
index 0000000..9dfe915
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh-tw/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"設定","insertTableTitle":"插入表格","insertTableRowAfterLabel":"在後面新增一列","center":"置中","deleteTableColumnLabel":"刪除直欄","right":"右","insertTableColumnBeforeLabel":"在前面新增一個直欄","tableWidth":"表格寬度:","buttonInsert":"插入","default":"預設","align":"對齊:","insertTableRowBeforeLabel":"在前面新增一列","cellSpacing":"資料格間距:","pixels":"像素","selectTableLabel":"選取表格","rows":"列","modifyTableTitle":"修改表格","cellPadding":"資料格行距:","deleteTableRowLabel":"刪除列","backgroundColor":"背景顏色:","insertTableColumnAfterL [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/zh/TableDialog.js b/dojox/editor/plugins/nls/zh/TableDialog.js
new file mode 100644
index 0000000..8cc7412
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh/TableDialog.js
@@ -0,0 +1 @@
+({"buttonSet":"设置","insertTableTitle":"插入表","insertTableRowAfterLabel":"在之后添加行","center":"居中","deleteTableColumnLabel":"删除列","right":"右","insertTableColumnBeforeLabel":"在之前添加列","tableWidth":"表宽度:","buttonInsert":"插入","default":"缺省值","align":"对齐:","insertTableRowBeforeLabel":"在之前添加行","cellSpacing":"单元格间距:","pixels":"像素","selectTableLabel":"选择表","rows":"行:","modifyTableTitle":"修改表","cellPadding":"单元格边距:","deleteTableRowLabel":"删除行","backgroundColor":"背景色:","insertTableColumnAfterLabel":"在之 [...]
\ No newline at end of file
diff --git a/dojox/editor/plugins/resources/editorPlugins.css b/dojox/editor/plugins/resources/editorPlugins.css
new file mode 100644
index 0000000..0e6b71d
--- /dev/null
+++ b/dojox/editor/plugins/resources/editorPlugins.css
@@ -0,0 +1,142 @@
+
+.EditorTableDialog{
+}
+.EditorTableDialog .etdTable{
+	width:350px;
+	border:none;
+	table-layout:fixed;
+	border-collapse:collapse;
+}
+.EditorTableDialog .etdTable td{
+	width:200px;
+	border:#CCCCCC 0px solid;
+	padding:5px;
+}
+.EditorTableDialog .etdTable td.left{
+	width:200px;
+}
+.EditorTableDialog .etdTable td.right{
+	width:150px;
+}
+.EditorTableDialog .dijitTextBox{
+	width:50px;
+	float:right;
+	padding-left:3px;
+}
+.EditorTableDialog .dijitComboBox{
+	width:85px;
+	padding-left:5px;
+}
+.EditorTableDialog .etdTable .floatDijit{
+	float:right;
+}
+.EditorTableDialog label{
+	float:right;
+	margin:0;
+	margin-right:5px;
+}
+.EditorTableDialog .cellpad{
+	background:url(images/cellpad.png) no-repeat 5px;
+}
+.EditorTableDialog .cellspace{
+	background:url(images/cellspace.png) no-repeat 5px;
+}
+.dialogButtonContainer{
+	text-align:right;
+	margin-top:10px;
+	cursor:pointer;
+}
+.colorSwatchBtn{
+	display:block;
+	border:#666666 2px solid;
+	background-color:#CCCCCC;
+	width:16px;
+	height:16px;
+	cursor:pointer;
+	float:right;
+}
+.colorSwatchBtn:hover{
+	border:#0099FF 2px solid;
+}
+.colorSwatchBtn div{
+	background-color:#CCCCCC;
+	width:16px;
+	height:16px;
+	cursor:pointer;
+}
+.editorIcon{
+	background-image:url(images/tableIcons.png);
+	background-repeat: no-repeat;
+	width: 16px;
+	height: 16px;
+	text-align: center;
+}
+.editorIconUploadImage{
+	background:url(images/uploadImageIcon.gif) no-repeat 0px 4px;
+}
+.editorIconInsertTable{				
+	background-position:0px 0px;	}
+.editorIconInsertTableRowBefore{ 	
+	background-position:-19px 0px;	}
+.dijitDisabled .editorIconInsertTableRowBefore{ 	
+	background-position:-120px 0px;	}
+	
+.editorIconInsertTableRowAfter{ 	
+	background-position:-35px 0px;	}
+.dijitDisabled .editorIconInsertTableRowAfter{ 	
+	background-position:-136px 0px;	}
+.editorIconInsertTableColumnBefore{ 	
+	background-position:-52px 0px;	}
+.dijitDisabled .editorIconInsertTableColumnBefore{ 	
+	background-position:-154px 0px;	}
+	
+.editorIconInsertTableColumnAfter{ 	
+	background-position:-69px 0px;	}
+.dijitDisabled .editorIconInsertTableColumnAfter{ 	
+	background-position:-171px 0px;	}
+	
+.editorIconDeleteTableRow{ 	
+	background-position:-86px 0px;	}
+.dijitDisabled .editorIconDeleteTableRow{ 	
+	background-position:-205px 0px;	}
+	
+.editorIconDeleteTableColumn{ 	
+	background-position:-103px 0px;	}
+.dijitDisabled .editorIconDeleteTableColumn{ 	
+	background-position:-188px 0px;	}
+	
+.editorIconColorTableCell{ 	
+	background-position:-222px 0px;	}
+.dijitDisabled .editorIconColorTableCell{ 	
+	background-position:-239px 0px;	}
+.editorIconModifyTable{ 	
+	background-position:-256px 0px;	}
+.dijitDisabled .editorIconModifyTable{ 	
+	background-position:-273px 0px;	}
+.RichTextEditable .dijitTextBox, 
+.RichTextEditable .dijitComboBox,
+.RichTextEditable  .dijitSpinner {
+	width: 5em;
+}
+.dojoxDropDownSelect {
+background:#FFFFFF url(images/dropBk.png) repeat-x scroll left top;
+border: 1px solid;
+border-top-color:#cccccc;
+border-right-color:#cccccc;
+border-left-color:#999999;
+border-bottom-color:#ffffff;
+}
+.dojoxDropDownSelect.dojoxDropDownSelectHover{
+background-image:url(images/dropBkOver.png);
+}
+.dojoxDropDownSelect button{
+line-height:16px;
+height:16px;
+width:100px;
+text-align:left;
+color:#8397b9;
+}
+.dijitButtonNode .dijitArrowButtonInner{
+background:url(../../../../dijit/themes/tundra/images/spriteArrows.png) no-repeat left top;
+width:7px;
+}
diff --git a/dojox/editor/plugins/resources/images/busy.gif b/dojox/editor/plugins/resources/images/busy.gif
new file mode 100644
index 0000000..7519974
Binary files /dev/null and b/dojox/editor/plugins/resources/images/busy.gif differ
diff --git a/dojox/editor/plugins/resources/images/cellpad.png b/dojox/editor/plugins/resources/images/cellpad.png
new file mode 100644
index 0000000..e8d1b9b
Binary files /dev/null and b/dojox/editor/plugins/resources/images/cellpad.png differ
diff --git a/dojox/editor/plugins/resources/images/cellspace.png b/dojox/editor/plugins/resources/images/cellspace.png
new file mode 100644
index 0000000..d080221
Binary files /dev/null and b/dojox/editor/plugins/resources/images/cellspace.png differ
diff --git a/dojox/editor/plugins/resources/images/tableIcons.png b/dojox/editor/plugins/resources/images/tableIcons.png
new file mode 100644
index 0000000..898ecd8
Binary files /dev/null and b/dojox/editor/plugins/resources/images/tableIcons.png differ
diff --git a/dojox/editor/plugins/resources/images/uploadImageIcon.gif b/dojox/editor/plugins/resources/images/uploadImageIcon.gif
new file mode 100644
index 0000000..83ed316
Binary files /dev/null and b/dojox/editor/plugins/resources/images/uploadImageIcon.gif differ
diff --git a/dojox/editor/plugins/resources/insertTable.html b/dojox/editor/plugins/resources/insertTable.html
new file mode 100644
index 0000000..5d4b6b9
--- /dev/null
+++ b/dojox/editor/plugins/resources/insertTable.html
@@ -0,0 +1,41 @@
+<div class="dijitDialog" tabindex="-1" waiRole="dialog" waiState="labelledby-${id}_title">
+	<div dojoAttachPoint="titleBar" class="dijitDialogTitleBar">
+	<span dojoAttachPoint="titleNode" class="dijitDialogTitle" id="${id}_title">${insertTableTitle}</span>
+	<span dojoAttachPoint="closeButtonNode" class="dijitDialogCloseIcon" dojoAttachEvent="onclick: onCancel" title="${buttonCancel}">
+		<span dojoAttachPoint="closeText" class="closeText" title="${buttonCancel}">x</span>
+	</span>
+	</div>
+    <div dojoAttachPoint="containerNode" class="dijitDialogPaneContent">
+        <table class="etdTable"><tr>
+            <td class="left">
+                <span dojoAttachPoint="selectRow" dojoType="dijit.form.TextBox" value="2"></span>
+                <label>${rows}</label>
+            </td><td class="right">
+                <span dojoAttachPoint="selectCol" dojoType="dijit.form.TextBox" value="2"></span>
+                <label>${columns}</label>
+            </td></tr><tr><td>
+                <span dojoAttachPoint="selectWidth" dojoType="dijit.form.TextBox" value="100"></span>
+                <label>${tableWidth}</label>
+            </td><td>
+                <select dojoAttachPoint="selectWidthType" hasDownArrow="true" dojoType="dijit.form.FilteringSelect">
+                  <option value="percent">${percent}</option>
+                  <option value="pixels">${pixels}</option>
+                </select></td></tr>
+          <tr><td>
+                <span dojoAttachPoint="selectBorder" dojoType="dijit.form.TextBox" value="1"></span>
+                <label>${borderThickness}</label></td>
+            <td>
+                ${pixels}
+            </td></tr><tr><td>
+                <span dojoAttachPoint="selectPad" dojoType="dijit.form.TextBox" value="0"></span>
+                <label>${cellPadding}</label></td>
+            <td class="cellpad"></td></tr><tr><td>
+                <span dojoAttachPoint="selectSpace" dojoType="dijit.form.TextBox" value="0"></span>
+                <label>${cellSpacing}</label>
+            </td><td class="cellspace"></td></tr></table>
+        <div class="dialogButtonContainer">
+            <div dojoType="dijit.form.Button" dojoAttachEvent="onClick: onInsert">${buttonInsert}</div>
+            <div dojoType="dijit.form.Button" dojoAttachEvent="onClick: onCancel">${buttonCancel}</div>
+        </div>
+	</div>
+</div>
diff --git a/dojox/editor/plugins/resources/modifyTable.html b/dojox/editor/plugins/resources/modifyTable.html
new file mode 100644
index 0000000..c1b00c6
--- /dev/null
+++ b/dojox/editor/plugins/resources/modifyTable.html
@@ -0,0 +1,50 @@
+<div class="dijitDialog" tabindex="-1" waiRole="dialog" waiState="labelledby-${id}_title">
+	<div dojoAttachPoint="titleBar" class="dijitDialogTitleBar">
+	<span dojoAttachPoint="titleNode" class="dijitDialogTitle" id="${id}_title">${modifyTableTitle}</span>
+	<span dojoAttachPoint="closeButtonNode" class="dijitDialogCloseIcon" dojoAttachEvent="onclick: onCancel" title="${buttonCancel}">
+		<span dojoAttachPoint="closeText" class="closeText" title="${buttonCancel}">x</span>
+	</span>
+	</div>
+    <div dojoAttachPoint="containerNode" class="dijitDialogPaneContent">
+        <table class="etdTable">
+          <tr><td class="left">
+                <span class="colorSwatchBtn" dojoAttachPoint="backgroundCol"></span>
+                <label>${backgroundColor}</label>
+            </td><td class="right">
+                <span class="colorSwatchBtn" dojoAttachPoint="borderCol"></span>
+                <label>${borderColor}</label>
+            </td></tr><tr><td>
+                <span dojoAttachPoint="selectBorder" dojoType="dijit.form.TextBox" value="1"></span>
+                <label>${borderThickness}</label>
+            </td><td>
+            ${pixels}
+            </td></tr><tr><td>
+                <select class="floatDijit" dojoAttachPoint="selectAlign" dojoType="dijit.form.FilteringSelect">
+                  <option value="default">${default}</option>
+                  <option value="left">${left}</option>
+                  <option value="center">${center}</option>
+                  <option value="right">${right}</option>
+                </select>
+                <label>${align}</label>
+            </td><td></td></tr><tr><td>
+                <span dojoAttachPoint="selectWidth" dojoType="dijit.form.TextBox" value="100"></span>
+                <label>${tableWidth}</label>
+            </td><td>
+                <select dojoAttachPoint="selectWidthType" hasDownArrow="true" dojoType="dijit.form.FilteringSelect">
+                  <option value="percent">${percent}</option>
+                  <option value="pixels">${pixels}</option>
+                </select>
+                </td></tr><tr><td>
+                <span dojoAttachPoint="selectPad" dojoType="dijit.form.TextBox" value="0"></span>
+                <label>${cellPadding}</label></td>
+            <td class="cellpad"></td></tr><tr><td>
+                <span dojoAttachPoint="selectSpace" dojoType="dijit.form.TextBox" value="0"></span>
+                <label>${cellSpacing}</label>
+            </td><td class="cellspace"></td></tr>
+        </table>
+        <div class="dialogButtonContainer">
+            <div dojoType="dijit.form.Button" dojoAttachEvent="onClick: onSet">${buttonSet}</div>
+            <div dojoType="dijit.form.Button" dojoAttachEvent="onClick: onCancel">${buttonCancel}</div>
+        </div>
+	</div>
+</div>
diff --git a/dojox/embed/Flash.js b/dojox/embed/Flash.js
new file mode 100644
index 0000000..7b31b58
--- /dev/null
+++ b/dojox/embed/Flash.js
@@ -0,0 +1,264 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.embed.Flash"]){
+dojo._hasResource["dojox.embed.Flash"]=true;
+dojo.provide("dojox.embed.Flash");
+(function(){
+var _1,_2;
+var _3=9;
+var _4="dojox-embed-flash-",_5=0;
+var _6={expressInstall:false,width:320,height:240,swLiveConnect:"true",allowScriptAccess:"sameDomain",allowNetworking:"all",style:null,redirect:null};
+function _7(_8){
+_8=dojo.delegate(_6,_8);
+if(!("path" in _8)){
+console.error("dojox.embed.Flash(ctor):: no path reference to a Flash movie was provided.");
+return null;
+}
+if(!("id" in _8)){
+_8.id=(_4+_5++);
+}
+return _8;
+};
+if(dojo.isIE){
+_1=function(_9){
+_9=_7(_9);
+if(!_9){
+return null;
+}
+var p;
+var _b=_9.path;
+if(_9.vars){
+var a=[];
+for(p in _9.vars){
+a.push(p+"="+_9.vars[p]);
+}
+_b+=((_b.indexOf("?")==-1)?"?":"&")+a.join("&");
+}
+var s="<object id=\""+_9.id+"\" "+"classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" "+"width=\""+_9.width+"\" "+"height=\""+_9.height+"\""+((_9.style)?" style=\""+_9.style+"\"":"")+">"+"<param name=\"movie\" value=\""+_b+"\" />";
+if(_9.params){
+for(p in _9.params){
+s+="<param name=\""+p+"\" value=\""+_9.params[p]+"\" />";
+}
+}
+s+="</object>";
+return {id:_9.id,markup:s};
+};
+_2=(function(){
+var _e=10,_f=null;
+while(!_f&&_e>7){
+try{
+_f=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+_e--);
+}
+catch(e){
+}
+}
+if(_f){
+var v=_f.GetVariable("$version").split(" ")[1].split(",");
+return {major:(v[0]!=null)?parseInt(v[0]):0,minor:(v[1]!=null)?parseInt(v[1]):0,rev:(v[2]!=null)?parseInt(v[2]):0};
+}
+return {major:0,minor:0,rev:0};
+})();
+dojo.addOnUnload(function(){
+var _12=function(){
+};
+var _13=dojo.query("object").reverse().style("display","none").forEach(function(i){
+for(var p in i){
+if((p!="FlashVars")&&dojo.isFunction(i[p])){
+try{
+i[p]=_12;
+}
+catch(e){
+}
+}
+}
+});
+});
+}else{
+_1=function(_16){
+_16=_7(_16);
+if(!_16){
+return null;
+}
+var p;
+var _18=_16.path;
+if(_16.vars){
+var a=[];
+for(p in _16.vars){
+a.push(p+"="+_16.vars[p]);
+}
+_18+=((_18.indexOf("?")==-1)?"?":"&")+a.join("&");
+}
+var s="<embed type=\"application/x-shockwave-flash\" "+"src=\""+_18+"\" "+"id=\""+_16.id+"\" "+"width=\""+_16.width+"\" "+"height=\""+_16.height+"\""+((_16.style)?" style=\""+_16.style+"\" ":"")+"swLiveConnect=\""+_16.swLiveConnect+"\" "+"allowScriptAccess=\""+_16.allowScriptAccess+"\" "+"allowNetworking=\""+_16.allowNetworking+"\" "+"pluginspage=\""+window.location.protocol+"//www.adobe.com/go/getflashplayer\" ";
+if(_16.params){
+for(p in _16.params){
+s+=" "+p+"=\""+_16.params[p]+"\"";
+}
+}
+s+=" />";
+return {id:_16.id,markup:s};
+};
+_2=(function(){
+var _1b=navigator.plugins["Shockwave Flash"];
+if(_1b&&_1b.description){
+var v=_1b.description.replace(/([a-zA-Z]|\s)+/,"").replace(/(\s+r|\s+b[0-9]+)/,".").split(".");
+return {major:(v[0]!=null)?parseInt(v[0]):0,minor:(v[1]!=null)?parseInt(v[1]):0,rev:(v[2]!=null)?parseInt(v[2]):0};
+}
+return {major:0,minor:0,rev:0};
+})();
+}
+dojox.embed.Flash=function(_1d,_1e){
+if(location.href.toLowerCase().indexOf("file://")>-1){
+throw new Error("dojox.embed.Flash can't be run directly from a file. To instatiate the required SWF correctly it must be run from a server, like localHost.");
+}
+this.available=dojox.embed.Flash.available;
+this.minimumVersion=_1d.minimumVersion||_3;
+this.id=null;
+this.movie=null;
+this.domNode=null;
+if(_1e){
+_1e=dojo.byId(_1e);
+}
+setTimeout(dojo.hitch(this,function(){
+if(this.available&&this.available>=this.minimumVersion){
+if(_1d&&_1e){
+this.init(_1d,_1e);
+}
+}else{
+if(!this.available){
+this.onError("Flash is not installed.");
+}else{
+this.onError("Flash version detected: "+this.available+" is out of date. Minimum required: "+this.minimumVersion);
+}
+}
+}),100);
+};
+dojo.extend(dojox.embed.Flash,{onReady:function(_1f){
+},onLoad:function(_20){
+},onError:function(msg){
+},_onload:function(){
+clearInterval(this._poller);
+delete this._poller;
+delete this._pollCount;
+delete this._pollMax;
+this.onLoad(this.movie);
+},init:function(_22,_23){
+this.destroy();
+_23=dojo.byId(_23||this.domNode);
+if(!_23){
+throw new Error("dojox.embed.Flash: no domNode reference has been passed.");
+}
+var p=0,_25=false;
+this._poller=null;
+this._pollCount=0;
+this._pollMax=5;
+this.pollTime=100;
+if(dojox.embed.Flash.initialized){
+this.id=dojox.embed.Flash.place(_22,_23);
+this.domNode=_23;
+setTimeout(dojo.hitch(this,function(){
+this.movie=this.byId(this.id,_22.doc);
+this.onReady(this.movie);
+this._poller=setInterval(dojo.hitch(this,function(){
+try{
+p=this.movie.PercentLoaded();
+}
+catch(e){
+console.warn("this.movie.PercentLoaded() failed");
+}
+if(p==100){
+this._onload();
+}else{
+if(p==0&&this._pollCount++>this._pollMax){
+clearInterval(this._poller);
+throw new Error("Building SWF failed.");
+}
+}
+}),this.pollTime);
+}),1);
+}
+},_destroy:function(){
+try{
+this.domNode.removeChild(this.movie);
+}
+catch(e){
+}
+this.id=this.movie=this.domNode=null;
+},destroy:function(){
+if(!this.movie){
+return;
+}
+var _26=dojo.delegate({id:true,movie:true,domNode:true,onReady:true,onLoad:true});
+for(var p in this){
+if(!_26[p]){
+delete this[p];
+}
+}
+if(this._poller){
+dojo.connect(this,"onLoad",this,"_destroy");
+}else{
+this._destroy();
+}
+},byId:function(_28,doc){
+doc=doc||document;
+if(doc.embeds[_28]){
+return doc.embeds[_28];
+}
+if(doc[_28]){
+return doc[_28];
+}
+if(window[_28]){
+return window[_28];
+}
+if(document[_28]){
+return document[_28];
+}
+return null;
+}});
+dojo.mixin(dojox.embed.Flash,{minSupported:8,available:_2.major,supported:(_2.major>=_2.required),minimumRequired:_2.required,version:_2,initialized:false,onInitialize:function(){
+dojox.embed.Flash.initialized=true;
+},__ie_markup__:function(_2a){
+return _1(_2a);
+},proxy:function(obj,_2c){
+dojo.forEach((dojo.isArray(_2c)?_2c:[_2c]),function(_2d){
+this[_2d]=dojo.hitch(this,function(){
+return (function(){
+return eval(this.movie.CallFunction("<invoke name=\""+_2d+"\" returntype=\"javascript\">"+"<arguments>"+dojo.map(arguments,function(_2e){
+return __flash__toXML(_2e);
+}).join("")+"</arguments>"+"</invoke>"));
+}).apply(this,arguments||[]);
+});
+},obj);
+}});
+if(dojo.isIE){
+if(dojo._initFired){
+var e=document.createElement("script");
+e.type="text/javascript";
+e.src=dojo.moduleUrl("dojox","embed/IE/flash.js");
+document.getElementsByTagName("head")[0].appendChild(e);
+}else{
+document.write("<scr"+"ipt type=\"text/javascript\" src=\""+dojo.moduleUrl("dojox","embed/IE/flash.js")+"\">"+"</scr"+"ipt>");
+}
+}else{
+dojox.embed.Flash.place=function(_2f,_30){
+var o=_1(_2f);
+_30=dojo.byId(_30);
+if(!_30){
+_30=dojo.doc.createElement("div");
+_30.id=o.id+"-container";
+dojo.body().appendChild(_30);
+}
+if(o){
+_30.innerHTML=o.markup;
+return o.id;
+}
+return null;
+};
+dojox.embed.Flash.onInitialize();
+}
+})();
+}
diff --git a/dojox/embed/IE/flash.js b/dojox/embed/IE/flash.js
new file mode 100644
index 0000000..fc8b0de
--- /dev/null
+++ b/dojox/embed/IE/flash.js
@@ -0,0 +1,22 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+dojox.embed.Flash.place=function(_1,_2){
+var o=dojox.embed.Flash.__ie_markup__(_1);
+_2=dojo.byId(_2);
+if(!_2){
+_2=dojo.doc.createElement("div");
+_2.id=o.id+"-container";
+dojo.body().appendChild(_2);
+}
+if(o){
+_2.innerHTML=o.markup;
+return o.id;
+}
+return null;
+};
+dojox.embed.Flash.onInitialize();
diff --git a/dojox/embed/Object.js b/dojox/embed/Object.js
new file mode 100644
index 0000000..48b0df0
--- /dev/null
+++ b/dojox/embed/Object.js
@@ -0,0 +1,39 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.embed.Object"]){
+dojo._hasResource["dojox.embed.Object"]=true;
+dojo.provide("dojox.embed.Object");
+dojo.experimental("dojox.embed.Object");
+dojo.require("dijit._Widget");
+dojo.require("dojox.embed.Flash");
+dojo.require("dojox.embed.Quicktime");
+dojo.declare("dojox.embed.Object",dijit._Widget,{width:0,height:0,src:"",movie:null,params:null,reFlash:/\.swf|\.flv/gi,reQtMovie:/\.3gp|\.avi|\.m4v|\.mov|\.mp4|\.mpg|\.mpeg|\.qt/gi,reQtAudio:/\.aiff|\.aif|\.m4a|\.m4b|\.m4p|\.midi|\.mid|\.mp3|\.mpa|\.wav/gi,postCreate:function(){
+if(!this.width||!this.height){
+var _1=dojo.marginBox(this.domNode);
+this.width=_1.w,this.height=_1.h;
+}
+var em=dojox.embed.Flash;
+if(this.src.match(this.reQtMovie)||this.src.match(this.reQtAudio)){
+em=dojox.embed.Quicktime;
+}
+if(!this.params){
+this.params={};
+if(this.domNode.hasAttributes()){
+var _3={dojoType:"",width:"",height:"","class":"",style:"",id:"",src:""};
+var _4=this.domNode.attributes;
+for(var i=0,l=_4.length;i<l;i++){
+if(!_3[_4[i].name]){
+this.params[_4[i].name]=_4[i].value;
+}
+}
+}
+}
+var _7={path:this.src,width:this.width,height:this.height,params:this.params};
+this.movie=new (em)(_7,this.domNode);
+}});
+}
diff --git a/dojox/embed/Quicktime.js b/dojox/embed/Quicktime.js
new file mode 100644
index 0000000..fc189aa
--- /dev/null
+++ b/dojox/embed/Quicktime.js
@@ -0,0 +1,139 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.embed.Quicktime"]){
+dojo._hasResource["dojox.embed.Quicktime"]=true;
+dojo.provide("dojox.embed.Quicktime");
+(function(d){
+var _2,_3={major:0,minor:0,rev:0},_4,_5={width:320,height:240,redirect:null},_6="dojox-embed-quicktime-",_7=0,_8="This content requires the <a href=\"http://www.apple.com/quicktime/download/\" title=\"Download and install QuickTime.\">QuickTime plugin</a>.";
+function _9(_a){
+_a=d.mixin(d.clone(_5),_a||{});
+if(!("path" in _a)&&!_a.testing){
+console.error("dojox.embed.Quicktime(ctor):: no path reference to a QuickTime movie was provided.");
+return null;
+}
+if(_a.testing){
+_a.path="";
+}
+if(!("id" in _a)){
+_a.id=_6+_7++;
+}
+return _a;
+};
+if(d.isIE){
+_4=(function(){
+try{
+var o=new ActiveXObject("QuickTimeCheckObject.QuickTimeCheck.1");
+if(o!==undefined){
+var v=o.QuickTimeVersion.toString(16);
+function p(i){
+return (v.substring(i,i+1)-0)||0;
+};
+_3={major:p(0),minor:p(1),rev:p(2)};
+return o.IsQuickTimeAvailable(0);
+}
+}
+catch(e){
+}
+return false;
+})();
+_2=function(_f){
+if(!_4){
+return {id:null,markup:_8};
+}
+_f=_9(_f);
+if(!_f){
+return null;
+}
+var s="<object classid=\"clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B\" "+"codebase=\"http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0\" "+"id=\""+_f.id+"\" "+"width=\""+_f.width+"\" "+"height=\""+_f.height+"\">"+"<param name=\"src\" value=\""+_f.path+"\"/>";
+for(var p in _f.params||{}){
+s+="<param name=\""+p+"\" value=\""+_f.params[p]+"\"/>";
+}
+s+="</object>";
+return {id:_f.id,markup:s};
+};
+}else{
+_4=(function(){
+for(var i=0,p=navigator.plugins,l=p.length;i<l;i++){
+if(p[i].name.indexOf("QuickTime")>-1){
+return true;
+}
+}
+return false;
+})();
+_2=function(_15){
+if(!_4){
+return {id:null,markup:_8};
+}
+_15=_9(_15);
+if(!_15){
+return null;
+}
+var s="<embed type=\"video/quicktime\" src=\""+_15.path+"\" "+"id=\""+_15.id+"\" "+"name=\""+_15.id+"\" "+"pluginspage=\"www.apple.com/quicktime/download\" "+"enablejavascript=\"true\" "+"width=\""+_15.width+"\" "+"height=\""+_15.height+"\"";
+for(var p in _15.params||{}){
+s+=" "+p+"=\""+_15.params[p]+"\"";
+}
+s+="></embed>";
+return {id:_15.id,markup:s};
+};
+}
+dojox.embed.Quicktime=function(_18,_19){
+return dojox.embed.Quicktime.place(_18,_19);
+};
+d.mixin(dojox.embed.Quicktime,{minSupported:6,available:_4,supported:_4,version:_3,initialized:false,onInitialize:function(){
+dojox.embed.Quicktime.initialized=true;
+},place:function(_1a,_1b){
+var o=_2(_1a);
+if(!(_1b=d.byId(_1b))){
+_1b=d.create("div",{id:o.id+"-container"},d.body());
+}
+if(o){
+_1b.innerHTML=o.markup;
+if(o.id){
+return d.isIE?d.byId(o.id):document[o.id];
+}
+}
+return null;
+}});
+if(!d.isIE){
+var id="-qt-version-test",o=_2({testing:true,width:4,height:4}),c=10,top="-1000px",_21="1px";
+function _22(){
+setTimeout(function(){
+var qt=document[o.id],n=d.byId(id);
+if(qt){
+try{
+var v=qt.GetQuickTimeVersion().split(".");
+dojox.embed.Quicktime.version={major:parseInt(v[0]||0),minor:parseInt(v[1]||0),rev:parseInt(v[2]||0)};
+if(dojox.embed.Quicktime.supported=v[0]){
+dojox.embed.Quicktime.onInitialize();
+}
+c=0;
+}
+catch(e){
+if(c--){
+_22();
+}
+}
+}
+if(!c&&n){
+d.destroy(n);
+}
+},20);
+};
+if(d._initFired){
+d.create("div",{innerHTML:o.markup,id:id,style:{top:top,left:0,width:_21,height:_21,overflow:"hidden",position:"absolute"}},d.body());
+}else{
+document.write("<div style=\"top:"+top+";left:0;width:"+_21+";height:"+_21+";overflow:hidden;position:absolute\" id=\""+id+"\">"+o.markup+"</div>");
+}
+_22();
+}else{
+if(d.isIE&&_4){
+dojox.embed.Quicktime.onInitialize();
+}
+}
+})(dojo);
+}
diff --git a/dojox/embed/README b/dojox/embed/README
new file mode 100644
index 0000000..1f5cb00
--- /dev/null
+++ b/dojox/embed/README
@@ -0,0 +1,44 @@
+-------------------------------------------------------------------------------
+dojox.embed
+-------------------------------------------------------------------------------
+Version 0.1
+Release date: 4/7/2008
+-------------------------------------------------------------------------------
+Project state:
+beta
+-------------------------------------------------------------------------------
+Credits
+	Tom Trenka (ttrenka AT gmail.com)
+-------------------------------------------------------------------------------
+Project description
+
+A move/port of what was in dojox.av._base; the nominal purpose is to provide
+easy ways of including external objects that would normally require the use
+of either an OBJECT or an EMBED tag.
+
+The following constructors are considered beta (working tests and docs) as of
+2008-06-04:
+
+dojox.embed.Flash
+dojox.embed.FlashProxy
+dojox.embed.Quicktime
+dojox.embed.Object (a Dijit that can load anything there is an embed for here)
+-------------------------------------------------------------------------------
+Dependencies:
+
+dojox.embed has no dependencies, other than the Dojo base.
+-------------------------------------------------------------------------------
+Documentation
+
+TBD
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/dojox/trunk/embed/*
+
+Install into the following directory structure:
+/dojox/embed/
+
+...which should be at the same level as your Dojo checkout.
+-------------------------------------------------------------------------------
diff --git a/dojox/embed/flashVars.js b/dojox/embed/flashVars.js
new file mode 100644
index 0000000..0e183fe
--- /dev/null
+++ b/dojox/embed/flashVars.js
@@ -0,0 +1,37 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.embed.flashVars"]){
+dojo._hasResource["dojox.embed.flashVars"]=true;
+dojo.provide("dojox.embed.flashVars");
+dojo.mixin(dojox.embed.flashVars,{serialize:function(n,o){
+var _3=function(_4){
+if(typeof _4=="string"){
+_4=_4.replace(/;/g,"_sc_");
+_4=_4.replace(/\./g,"_pr_");
+_4=_4.replace(/\:/g,"_cl_");
+}
+return _4;
+};
+var df=dojox.embed.flashVars.serialize;
+var _6="";
+if(dojo.isArray(o)){
+for(var i=0;i<o.length;i++){
+_6+=df(n+"."+i,_3(o[i]))+";";
+}
+return _6.replace(/;{2,}/g,";");
+}else{
+if(dojo.isObject(o)){
+for(var nm in o){
+_6+=df(n+"."+nm,_3(o[nm]))+";";
+}
+return _6.replace(/;{2,}/g,";");
+}
+}
+return n+":"+o;
+}});
+}
diff --git a/dojox/embed/resources/version.mov b/dojox/embed/resources/version.mov
new file mode 100644
index 0000000..4f2cb73
Binary files /dev/null and b/dojox/embed/resources/version.mov differ
diff --git a/dojox/encoding/LICENSE b/dojox/encoding/LICENSE
new file mode 100644
index 0000000..f0a4be5
--- /dev/null
+++ b/dojox/encoding/LICENSE
@@ -0,0 +1,14 @@
+License Disclaimer:
+
+All contents of this directory are Copyright (c) the Dojo Foundation, with the
+following exceptions:
+-------------------------------------------------------------------------------
+
+MD5.js, SHA1.js:
+	* Copyright 1998-2005, Paul Johnstone
+	  Distributed under the terms of the BSD License
+
+SimpleAES.js
+	* Original version by Chris Veness (CLA signed with permission
+	  given under the terms of the BSD license)
+	  http://www.movable-type.co.uk/scripts/aes.html
diff --git a/dojox/encoding/README b/dojox/encoding/README
new file mode 100644
index 0000000..8826008
--- /dev/null
+++ b/dojox/encoding/README
@@ -0,0 +1,35 @@
+-------------------------------------------------------------------------------
+DojoX Encoding
+-------------------------------------------------------------------------------
+Version 0.1.0
+Release date: 7/30/2007
+-------------------------------------------------------------------------------
+Project state:
+experimental
+-------------------------------------------------------------------------------
+Credits
+	Eugene Lazutkin
+	Tom Trenka
+-------------------------------------------------------------------------------
+Project description
+
+DojoX Encoding provides a set of routines for common encoding algorithms.
+-------------------------------------------------------------------------------
+Dependencies:
+
+Encoding only depends on the Dojo Core.
+-------------------------------------------------------------------------------
+Documentation
+
+See the API documentation for details.
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/encoding/*
+
+Install into the following directory structure:
+/dojox/encoding/
+
+...which should be at the same level as your Dojo checkout.
+-------------------------------------------------------------------------------
diff --git a/dojox/encoding/_base.js b/dojox/encoding/_base.js
new file mode 100644
index 0000000..8c60ddc
--- /dev/null
+++ b/dojox/encoding/_base.js
@@ -0,0 +1,11 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.encoding._base"]){
+dojo._hasResource["dojox.encoding._base"]=true;
+dojo.provide("dojox.encoding._base");
+}
diff --git a/dojox/encoding/ascii85.js b/dojox/encoding/ascii85.js
new file mode 100644
index 0000000..3e9acb0
--- /dev/null
+++ b/dojox/encoding/ascii85.js
@@ -0,0 +1,71 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.encoding.ascii85"]){
+dojo._hasResource["dojox.encoding.ascii85"]=true;
+dojo.provide("dojox.encoding.ascii85");
+(function(){
+var c=function(_2,_3,_4){
+var i,j,n,b=[0,0,0,0,0];
+for(i=0;i<_3;i+=4){
+n=((_2[i]*256+_2[i+1])*256+_2[i+2])*256+_2[i+3];
+if(!n){
+_4.push("z");
+}else{
+for(j=0;j<5;b[j++]=n%85+33,n=Math.floor(n/85)){
+}
+}
+_4.push(String.fromCharCode(b[4],b[3],b[2],b[1],b[0]));
+}
+};
+dojox.encoding.ascii85.encode=function(_9){
+var _a=[],_b=_9.length%4,_c=_9.length-_b;
+c(_9,_c,_a);
+if(_b){
+var t=_9.slice(_c);
+while(t.length<4){
+t.push(0);
+}
+c(t,4,_a);
+var x=_a.pop();
+if(x=="z"){
+x="!!!!!";
+}
+_a.push(x.substr(0,_b+1));
+}
+return _a.join("");
+};
+dojox.encoding.ascii85.decode=function(_f){
+var n=_f.length,r=[],b=[0,0,0,0,0],i,j,t,x,y,d;
+for(i=0;i<n;++i){
+if(_f.charAt(i)=="z"){
+r.push(0,0,0,0);
+continue;
+}
+for(j=0;j<5;++j){
+b[j]=_f.charCodeAt(i+j)-33;
+}
+d=n-i;
+if(d<5){
+for(j=d;j<4;b[++j]=0){
+}
+b[d]=85;
+}
+t=(((b[0]*85+b[1])*85+b[2])*85+b[3])*85+b[4];
+x=t&255;
+t>>>=8;
+y=t&255;
+t>>>=8;
+r.push(t>>>8,t&255,y,x);
+for(j=d;j<5;++j,r.pop()){
+}
+i+=4;
+}
+return r;
+};
+})();
+}
diff --git a/dojox/encoding/base64.js b/dojox/encoding/base64.js
new file mode 100644
index 0000000..3edb863
--- /dev/null
+++ b/dojox/encoding/base64.js
@@ -0,0 +1,70 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.encoding.base64"]){
+dojo._hasResource["dojox.encoding.base64"]=true;
+dojo.provide("dojox.encoding.base64");
+(function(){
+var p="=";
+var _2="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+var _3=dojox.encoding;
+_3.base64.encode=function(ba){
+var s=[],l=ba.length;
+var rm=l%3;
+var x=l-rm;
+for(var i=0;i<x;){
+var t=ba[i++]<<16|ba[i++]<<8|ba[i++];
+s.push(_2.charAt((t>>>18)&63));
+s.push(_2.charAt((t>>>12)&63));
+s.push(_2.charAt((t>>>6)&63));
+s.push(_2.charAt(t&63));
+}
+switch(rm){
+case 2:
+var t=ba[i++]<<16|ba[i++]<<8;
+s.push(_2.charAt((t>>>18)&63));
+s.push(_2.charAt((t>>>12)&63));
+s.push(_2.charAt((t>>>6)&63));
+s.push(p);
+break;
+case 1:
+var t=ba[i++]<<16;
+s.push(_2.charAt((t>>>18)&63));
+s.push(_2.charAt((t>>>12)&63));
+s.push(p);
+s.push(p);
+break;
+}
+return s.join("");
+};
+_3.base64.decode=function(_b){
+var s=_b.split(""),_d=[];
+var l=s.length;
+while(s[--l]==p){
+}
+for(var i=0;i<l;){
+var t=_2.indexOf(s[i++])<<18;
+if(i<=l){
+t|=_2.indexOf(s[i++])<<12;
+}
+if(i<=l){
+t|=_2.indexOf(s[i++])<<6;
+}
+if(i<=l){
+t|=_2.indexOf(s[i++]);
+}
+_d.push((t>>>16)&255);
+_d.push((t>>>8)&255);
+_d.push(t&255);
+}
+while(_d[_d.length-1]==0){
+_d.pop();
+}
+return _d;
+};
+})();
+}
diff --git a/dojox/encoding/bits.js b/dojox/encoding/bits.js
new file mode 100644
index 0000000..d385a16
--- /dev/null
+++ b/dojox/encoding/bits.js
@@ -0,0 +1,64 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.encoding.bits"]){
+dojo._hasResource["dojox.encoding.bits"]=true;
+dojo.provide("dojox.encoding.bits");
+dojox.encoding.bits.OutputStream=function(){
+this.reset();
+};
+dojo.extend(dojox.encoding.bits.OutputStream,{reset:function(){
+this.buffer=[];
+this.accumulator=0;
+this.available=8;
+},putBits:function(_1,_2){
+while(_2){
+var w=Math.min(_2,this.available);
+var v=(w<=_2?_1>>>(_2-w):_1)<<(this.available-w);
+this.accumulator|=v&(255>>>(8-this.available));
+this.available-=w;
+if(!this.available){
+this.buffer.push(this.accumulator);
+this.accumulator=0;
+this.available=8;
+}
+_2-=w;
+}
+},getWidth:function(){
+return this.buffer.length*8+(8-this.available);
+},getBuffer:function(){
+var b=this.buffer;
+if(this.available<8){
+b.push(this.accumulator&(255<<this.available));
+}
+this.reset();
+return b;
+}});
+dojox.encoding.bits.InputStream=function(_6,_7){
+this.buffer=_6;
+this.width=_7;
+this.bbyte=this.bit=0;
+};
+dojo.extend(dojox.encoding.bits.InputStream,{getBits:function(_8){
+var r=0;
+while(_8){
+var w=Math.min(_8,8-this.bit);
+var v=this.buffer[this.bbyte]>>>(8-this.bit-w);
+r<<=w;
+r|=v&~(~0<<w);
+this.bit+=w;
+if(this.bit==8){
+++this.bbyte;
+this.bit=0;
+}
+_8-=w;
+}
+return r;
+},getWidth:function(){
+return this.width-this.bbyte*8-this.bit;
+}});
+}
diff --git a/dojox/encoding/compression/lzw.js b/dojox/encoding/compression/lzw.js
new file mode 100644
index 0000000..8a5f9ce
--- /dev/null
+++ b/dojox/encoding/compression/lzw.js
@@ -0,0 +1,83 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.encoding.compression.lzw"]){
+dojo._hasResource["dojox.encoding.compression.lzw"]=true;
+dojo.provide("dojox.encoding.compression.lzw");
+dojo.require("dojox.encoding.bits");
+(function(){
+var _1=function(x){
+var w=1;
+for(var v=2;x>=v;v<<=1,++w){
+}
+return w;
+};
+dojox.encoding.compression.lzw.Encoder=function(n){
+this.size=n;
+this.init();
+};
+dojo.extend(dojox.encoding.compression.lzw.Encoder,{init:function(){
+this.dict={};
+for(var i=0;i<this.size;++i){
+this.dict[String.fromCharCode(i)]=i;
+}
+this.width=_1(this.code=this.size);
+this.p="";
+},encode:function(_7,_8){
+var c=String.fromCharCode(_7),p=this.p+c,r=0;
+if(p in this.dict){
+this.p=p;
+return r;
+}
+_8.putBits(this.dict[this.p],this.width);
+if((this.code&(this.code+1))==0){
+_8.putBits(this.code++,r=this.width++);
+}
+this.dict[p]=this.code++;
+this.p=c;
+return r+this.width;
+},flush:function(_c){
+if(this.p.length==0){
+return 0;
+}
+_c.putBits(this.dict[this.p],this.width);
+this.p="";
+return this.width;
+}});
+dojox.encoding.compression.lzw.Decoder=function(n){
+this.size=n;
+this.init();
+};
+dojo.extend(dojox.encoding.compression.lzw.Decoder,{init:function(){
+this.codes=new Array(this.size);
+for(var i=0;i<this.size;++i){
+this.codes[i]=String.fromCharCode(i);
+}
+this.width=_1(this.size);
+this.p=-1;
+},decode:function(_f){
+var c=_f.getBits(this.width),v;
+if(c<this.codes.length){
+v=this.codes[c];
+if(this.p>=0){
+this.codes.push(this.codes[this.p]+v.substr(0,1));
+}
+}else{
+if((c&(c+1))==0){
+this.codes.push("");
+++this.width;
+return "";
+}
+var x=this.codes[this.p];
+v=x+x.substr(0,1);
+this.codes.push(v);
+}
+this.p=c;
+return v;
+}});
+})();
+}
diff --git a/dojox/encoding/compression/splay.js b/dojox/encoding/compression/splay.js
new file mode 100644
index 0000000..2c00ff6
--- /dev/null
+++ b/dojox/encoding/compression/splay.js
@@ -0,0 +1,65 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.encoding.compression.splay"]){
+dojo._hasResource["dojox.encoding.compression.splay"]=true;
+dojo.provide("dojox.encoding.compression.splay");
+dojo.require("dojox.encoding.bits");
+dojox.encoding.compression.Splay=function(n){
+this.up=new Array(2*n+1);
+this.left=new Array(n);
+this.right=new Array(n);
+this.reset();
+};
+dojo.extend(dojox.encoding.compression.Splay,{reset:function(){
+for(var i=1;i<this.up.length;this.up[i]=Math.floor((i-1)/2),++i){
+}
+for(var i=0;i<this.left.length;this.left[i]=2*i+1,this.right[i]=2*i+2,++i){
+}
+},splay:function(i){
+var a=i+this.left.length;
+do{
+var c=this.up[a];
+if(c){
+var d=this.up[c];
+var b=this.left[d];
+if(c==b){
+b=this.right[d];
+this.right[d]=a;
+}else{
+this.left[d]=a;
+}
+this[a==this.left[c]?"left":"right"][c]=b;
+this.up[a]=d;
+this.up[b]=c;
+a=d;
+}else{
+a=c;
+}
+}while(a);
+},encode:function(_8,_9){
+var s=[],a=_8+this.left.length;
+do{
+s.push(this.right[this.up[a]]==a);
+a=this.up[a];
+}while(a);
+this.splay(_8);
+var l=s.length;
+while(s.length){
+_9.putBits(s.pop()?1:0,1);
+}
+return l;
+},decode:function(_d){
+var a=0;
+do{
+a=this[_d.getBits(1)?"right":"left"][a];
+}while(a<this.left.length);
+a-=this.left.length;
+this.splay(a);
+return a;
+}});
+}
diff --git a/dojox/encoding/crypto/Blowfish.js b/dojox/encoding/crypto/Blowfish.js
new file mode 100644
index 0000000..bdb55a1
--- /dev/null
+++ b/dojox/encoding/crypto/Blowfish.js
@@ -0,0 +1,275 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.encoding.crypto.Blowfish"]){
+dojo._hasResource["dojox.encoding.crypto.Blowfish"]=true;
+dojo.provide("dojox.encoding.crypto.Blowfish");
+dojo.require("dojox.encoding.base64");
+dojo.require("dojox.encoding.crypto._base");
+dojox.encoding.crypto.Blowfish=new function(){
+var _1=Math.pow(2,2);
+var _2=Math.pow(2,3);
+var _3=Math.pow(2,4);
+var _4=Math.pow(2,8);
+var _5=Math.pow(2,16);
+var _6=Math.pow(2,24);
+var iv=null;
+var _8={p:[608135816,2242054355,320440878,57701188,2752067618,698298832,137296536,3964562569,1160258022,953160567,3193202383,887688300,3232508343,3380367581,1065670069,3041331479,2450970073,2306472731],s0:[3509652390,2564797868,805139163,3491422135,3101798381,1780907670,3128725573,4046225305,614570311,3012652279,134345442,2240740374,1667834072,1901547113,2757295779,4103290238,227898511,1921955416,1904987480,2182433518,2069144605,3260701109,2620446009,720527379,3318853667,677414384,339328 [...]
+function _9(x,y){
+return (((x>>16)+(y>>16)+(((x&65535)+(y&65535))>>16))<<16)|(((x&65535)+(y&65535))&65535);
+};
+function _c(x,y){
+return (((x>>16)^(y>>16))<<16)|(((x&65535)^(y&65535))&65535);
+};
+function $(v,box){
+var d=box.s3[v&255];
+v>>=8;
+var c=box.s2[v&255];
+v>>=8;
+var b=box.s1[v&255];
+v>>=8;
+var a=box.s0[v&255];
+var r=(((a>>16)+(b>>16)+(((a&65535)+(b&65535))>>16))<<16)|(((a&65535)+(b&65535))&65535);
+r=(((r>>16)^(c>>16))<<16)|(((r&65535)^(c&65535))&65535);
+return (((r>>16)+(d>>16)+(((r&65535)+(d&65535))>>16))<<16)|(((r&65535)+(d&65535))&65535);
+};
+function eb(o,box){
+var l=o.left;
+var r=o.right;
+l=_c(l,box.p[0]);
+r=_c(r,_c($(l,box),box.p[1]));
+l=_c(l,_c($(r,box),box.p[2]));
+r=_c(r,_c($(l,box),box.p[3]));
+l=_c(l,_c($(r,box),box.p[4]));
+r=_c(r,_c($(l,box),box.p[5]));
+l=_c(l,_c($(r,box),box.p[6]));
+r=_c(r,_c($(l,box),box.p[7]));
+l=_c(l,_c($(r,box),box.p[8]));
+r=_c(r,_c($(l,box),box.p[9]));
+l=_c(l,_c($(r,box),box.p[10]));
+r=_c(r,_c($(l,box),box.p[11]));
+l=_c(l,_c($(r,box),box.p[12]));
+r=_c(r,_c($(l,box),box.p[13]));
+l=_c(l,_c($(r,box),box.p[14]));
+r=_c(r,_c($(l,box),box.p[15]));
+l=_c(l,_c($(r,box),box.p[16]));
+o.right=l;
+o.left=_c(r,box.p[17]);
+};
+function db(o,box){
+var l=o.left;
+var r=o.right;
+l=_c(l,box.p[17]);
+r=_c(r,_c($(l,box),box.p[16]));
+l=_c(l,_c($(r,box),box.p[15]));
+r=_c(r,_c($(l,box),box.p[14]));
+l=_c(l,_c($(r,box),box.p[13]));
+r=_c(r,_c($(l,box),box.p[12]));
+l=_c(l,_c($(r,box),box.p[11]));
+r=_c(r,_c($(l,box),box.p[10]));
+l=_c(l,_c($(r,box),box.p[9]));
+r=_c(r,_c($(l,box),box.p[8]));
+l=_c(l,_c($(r,box),box.p[7]));
+r=_c(r,_c($(l,box),box.p[6]));
+l=_c(l,_c($(r,box),box.p[5]));
+r=_c(r,_c($(l,box),box.p[4]));
+l=_c(l,_c($(r,box),box.p[3]));
+r=_c(r,_c($(l,box),box.p[2]));
+l=_c(l,_c($(r,box),box.p[1]));
+o.right=l;
+o.left=_c(r,box.p[0]);
+};
+function _21(key){
+var k=key;
+if(dojo.isString(k)){
+k=dojo.map(k.split(""),function(_24){
+return _24.charCodeAt(0)&255;
+});
+}
+var pos=0,_26=0,res={left:0,right:0},i,j,l;
+var box={p:dojo.map(_8.p.slice(0),function(_2c){
+var l=k.length,j;
+for(j=0;j<4;j++){
+_26=(_26*_4)|k[pos++%l];
+}
+return (((_2c>>16)^(_26>>16))<<16)|(((_2c&65535)^(_26&65535))&65535);
+}),s0:_8.s0.slice(0),s1:_8.s1.slice(0),s2:_8.s2.slice(0),s3:_8.s3.slice(0)};
+for(i=0,l=box.p.length;i<l;){
+eb(res,box);
+box.p[i++]=res.left,box.p[i++]=res.right;
+}
+for(i=0;i<4;i++){
+for(j=0,l=box["s"+i].length;j<l;){
+eb(res,box);
+box["s"+i][j++]=res.left,box["s"+i][j++]=res.right;
+}
+}
+return box;
+};
+this.getIV=function(_2e){
+var out=_2e||dojox.encoding.crypto.outputTypes.Base64;
+switch(out){
+case dojox.encoding.crypto.outputTypes.Hex:
+return dojo.map(iv,function(_30){
+return (_30<=15?"0":"")+_30.toString(16);
+}).join("");
+case dojox.encoding.crypto.outputTypes.String:
+return iv.join("");
+case dojox.encoding.crypto.outputTypes.Raw:
+return iv;
+default:
+return dojox.encoding.base64.encode(iv);
+}
+};
+this.setIV=function(_31,_32){
+var ip=_32||dojox.encoding.crypto.outputTypes.Base64;
+var ba=null;
+switch(ip){
+case dojox.encoding.crypto.outputTypes.String:
+ba=dojo.map(_31.split(""),function(_35){
+return _35.charCodeAt(0);
+});
+break;
+case dojox.encoding.crypto.outputTypes.Hex:
+ba=[];
+for(var i=0,l=_31.length-1;i<l;i+=2){
+ba.push(parseInt(_31.substr(i,2),16));
+}
+break;
+case dojox.encoding.crypto.outputTypes.Raw:
+ba=_31;
+break;
+default:
+ba=dojox.encoding.base64.decode(_31);
+break;
+}
+iv={};
+iv.left=ba[0]*_6|ba[1]*_5|ba[2]*_4|ba[3];
+iv.right=ba[4]*_6|ba[5]*_5|ba[6]*_4|ba[7];
+};
+this.encrypt=function(_38,key,ao){
+var out=dojox.encoding.crypto.outputTypes.Base64;
+var _3c=dojox.encoding.crypto.cipherModes.ECB;
+if(ao){
+if(ao.outputType){
+out=ao.outputType;
+}
+if(ao.cipherMode){
+_3c=ao.cipherMode;
+}
+}
+var bx=_21(key),_3e=8-(_38.length&7);
+for(var i=0;i<_3e;i++){
+_38+=String.fromCharCode(_3e);
+}
+var _40=[],_41=_38.length>>3,pos=0,o={},_44=(_3c==dojox.encoding.crypto.cipherModes.CBC);
+var _45={left:iv.left||null,right:iv.right||null};
+for(var i=0;i<_41;i++){
+o.left=_38.charCodeAt(pos)*_6|_38.charCodeAt(pos+1)*_5|_38.charCodeAt(pos+2)*_4|_38.charCodeAt(pos+3);
+o.right=_38.charCodeAt(pos+4)*_6|_38.charCodeAt(pos+5)*_5|_38.charCodeAt(pos+6)*_4|_38.charCodeAt(pos+7);
+if(_44){
+o.left=(((o.left>>16)^(_45.left>>16))<<16)|(((o.left&65535)^(_45.left&65535))&65535);
+o.right=(((o.right>>16)^(_45.right>>16))<<16)|(((o.right&65535)^(_45.right&65535))&65535);
+}
+eb(o,bx);
+if(_44){
+_45.left=o.left;
+_45.right=o.right;
+}
+_40.push((o.left>>24)&255);
+_40.push((o.left>>16)&255);
+_40.push((o.left>>8)&255);
+_40.push(o.left&255);
+_40.push((o.right>>24)&255);
+_40.push((o.right>>16)&255);
+_40.push((o.right>>8)&255);
+_40.push(o.right&255);
+pos+=8;
+}
+switch(out){
+case dojox.encoding.crypto.outputTypes.Hex:
+return dojo.map(_40,function(_46){
+return (_46<=15?"0":"")+_46.toString(16);
+}).join("");
+case dojox.encoding.crypto.outputTypes.String:
+return _40.join("");
+case dojox.encoding.crypto.outputTypes.Raw:
+return _40;
+default:
+return dojox.encoding.base64.encode(_40);
+}
+};
+this.decrypt=function(_47,key,ao){
+var ip=dojox.encoding.crypto.outputTypes.Base64;
+var _4b=dojox.encoding.crypto.cipherModes.ECB;
+if(ao){
+if(ao.outputType){
+ip=ao.outputType;
+}
+if(ao.cipherMode){
+_4b=ao.cipherMode;
+}
+}
+var bx=_21(key);
+var pt=[];
+var c=null;
+switch(ip){
+case dojox.encoding.crypto.outputTypes.Hex:
+c=[];
+for(var i=0,l=_47.length-1;i<l;i+=2){
+c.push(parseInt(_47.substr(i,2),16));
+}
+break;
+case dojox.encoding.crypto.outputTypes.String:
+c=dojo.map(_47.split(""),function(_51){
+return _51.charCodeAt(0);
+});
+break;
+case dojox.encoding.crypto.outputTypes.Raw:
+c=_47;
+break;
+default:
+c=dojox.encoding.base64.decode(_47);
+break;
+}
+var _52=c.length>>3,pos=0,o={},_55=(_4b==dojox.encoding.crypto.cipherModes.CBC);
+var _56={left:iv.left||null,right:iv.right||null};
+for(var i=0;i<_52;i++){
+o.left=c[pos]*_6|c[pos+1]*_5|c[pos+2]*_4|c[pos+3];
+o.right=c[pos+4]*_6|c[pos+5]*_5|c[pos+6]*_4|c[pos+7];
+if(_55){
+var _57=o.left;
+var _58=o.right;
+}
+db(o,bx);
+if(_55){
+o.left=(((o.left>>16)^(_56.left>>16))<<16)|(((o.left&65535)^(_56.left&65535))&65535);
+o.right=(((o.right>>16)^(_56.right>>16))<<16)|(((o.right&65535)^(_56.right&65535))&65535);
+_56.left=_57;
+_56.right=_58;
+}
+pt.push((o.left>>24)&255);
+pt.push((o.left>>16)&255);
+pt.push((o.left>>8)&255);
+pt.push(o.left&255);
+pt.push((o.right>>24)&255);
+pt.push((o.right>>16)&255);
+pt.push((o.right>>8)&255);
+pt.push(o.right&255);
+pos+=8;
+}
+if(pt[pt.length-1]==pt[pt.length-2]||pt[pt.length-1]==1){
+var n=pt[pt.length-1];
+pt.splice(pt.length-n,n);
+}
+return dojo.map(pt,function(_5a){
+return String.fromCharCode(_5a);
+}).join("");
+};
+this.setIV("0000000000000000",dojox.encoding.crypto.outputTypes.Hex);
+}();
+}
diff --git a/dojox/encoding/crypto/SimpleAES.js b/dojox/encoding/crypto/SimpleAES.js
new file mode 100644
index 0000000..42bd1af
--- /dev/null
+++ b/dojox/encoding/crypto/SimpleAES.js
@@ -0,0 +1,236 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.encoding.crypto.SimpleAES"]){
+dojo._hasResource["dojox.encoding.crypto.SimpleAES"]=true;
+dojo.provide("dojox.encoding.crypto.SimpleAES");
+dojo.require("dojox.encoding.base64");
+dojo.require("dojox.encoding.crypto._base");
+(function(){
+var _1=[99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253,147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,236,95,151,68,23, [...]
+var _2=[[0,0,0,0],[1,0,0,0],[2,0,0,0],[4,0,0,0],[8,0,0,0],[16,0,0,0],[32,0,0,0],[64,0,0,0],[128,0,0,0],[27,0,0,0],[54,0,0,0]];
+function _3(_4,w){
+var Nb=4;
+var Nr=w.length/Nb-1;
+var _8=[[],[],[],[]];
+for(var i=0;i<4*Nb;i++){
+_8[i%4][Math.floor(i/4)]=_4[i];
+}
+_8=_a(_8,w,0,Nb);
+for(var _b=1;_b<Nr;_b++){
+_8=_c(_8,Nb);
+_8=_d(_8,Nb);
+_8=_e(_8,Nb);
+_8=_a(_8,w,_b,Nb);
+}
+_8=_c(_8,Nb);
+_8=_d(_8,Nb);
+_8=_a(_8,w,Nr,Nb);
+var _f=new Array(4*Nb);
+for(var i=0;i<4*Nb;i++){
+_f[i]=_8[i%4][Math.floor(i/4)];
+}
+return _f;
+};
+function _c(s,Nb){
+for(var r=0;r<4;r++){
+for(var c=0;c<Nb;c++){
+s[r][c]=_1[s[r][c]];
+}
+}
+return s;
+};
+function _d(s,Nb){
+var t=new Array(4);
+for(var r=1;r<4;r++){
+for(var c=0;c<4;c++){
+t[c]=s[r][(c+r)%Nb];
+}
+for(var c=0;c<4;c++){
+s[r][c]=t[c];
+}
+}
+return s;
+};
+function _e(s,Nb){
+for(var c=0;c<4;c++){
+var a=new Array(4);
+var b=new Array(4);
+for(var i=0;i<4;i++){
+a[i]=s[i][c];
+b[i]=s[i][c]&128?s[i][c]<<1^283:s[i][c]<<1;
+}
+s[0][c]=b[0]^a[1]^b[1]^a[2]^a[3];
+s[1][c]=a[0]^b[1]^a[2]^b[2]^a[3];
+s[2][c]=a[0]^a[1]^b[2]^a[3]^b[3];
+s[3][c]=a[0]^b[0]^a[1]^a[2]^b[3];
+}
+return s;
+};
+function _a(_1f,w,rnd,Nb){
+for(var r=0;r<4;r++){
+for(var c=0;c<Nb;c++){
+_1f[r][c]^=w[rnd*4+c][r];
+}
+}
+return _1f;
+};
+function _25(key){
+var Nb=4;
+var Nk=key.length/4;
+var Nr=Nk+6;
+var w=new Array(Nb*(Nr+1));
+var _2b=new Array(4);
+for(var i=0;i<Nk;i++){
+var r=[key[4*i],key[4*i+1],key[4*i+2],key[4*i+3]];
+w[i]=r;
+}
+for(var i=Nk;i<(Nb*(Nr+1));i++){
+w[i]=new Array(4);
+for(var t=0;t<4;t++){
+_2b[t]=w[i-1][t];
+}
+if(i%Nk==0){
+_2b=_2f(_30(_2b));
+for(var t=0;t<4;t++){
+_2b[t]^=_2[i/Nk][t];
+}
+}else{
+if(Nk>6&&i%Nk==4){
+_2b=_2f(_2b);
+}
+}
+for(var t=0;t<4;t++){
+w[i][t]=w[i-Nk][t]^_2b[t];
+}
+}
+return w;
+};
+function _2f(w){
+for(var i=0;i<4;i++){
+w[i]=_1[w[i]];
+}
+return w;
+};
+function _30(w){
+w[4]=w[0];
+for(var i=0;i<4;i++){
+w[i]=w[i+1];
+}
+return w;
+};
+function _35(_36,_37,_38){
+if(!(_38==128||_38==192||_38==256)){
+return "";
+}
+var _39=_38/8;
+var _3a=new Array(_39);
+for(var i=0;i<_39;i++){
+_3a[i]=_37.charCodeAt(i)&255;
+}
+var key=_3(_3a,_25(_3a));
+key=key.concat(key.slice(0,_39-16));
+var _3d=16;
+var _3e=new Array(_3d);
+var _3f=(new Date()).getTime();
+for(var i=0;i<4;i++){
+_3e[i]=(_3f>>>i*8)&255;
+}
+for(var i=0;i<4;i++){
+_3e[i+4]=(_3f/4294967296>>>i*8)&255;
+}
+var _40=_25(key);
+var _41=Math.ceil(_36.length/_3d);
+var _42=new Array(_41);
+for(var b=0;b<_41;b++){
+for(var c=0;c<4;c++){
+_3e[15-c]=(b>>>c*8)&255;
+}
+for(var c=0;c<4;c++){
+_3e[15-c-4]=(b/4294967296>>>c*8);
+}
+var _45=_3(_3e,_40);
+var _46=b<_41-1?_3d:(_36.length-1)%_3d+1;
+var ct="";
+for(var i=0;i<_46;i++){
+var _48=_36.charCodeAt(b*_3d+i);
+var _49=_48^_45[i];
+ct+=((_49<16)?"0":"")+_49.toString(16);
+}
+_42[b]=ct;
+}
+var _4a="";
+for(var i=0;i<8;i++){
+_4a+=((_3e[i]<16)?"0":"")+_3e[i].toString(16);
+}
+return _4a+" "+_42.join(" ");
+};
+function _4b(s){
+var ret=[];
+s.replace(/(..)/g,function(str){
+ret.push(parseInt(str,16));
+});
+return ret;
+};
+function _4f(_50,_51,_52){
+if(!(_52==128||_52==192||_52==256)){
+return "";
+}
+var _53=_52/8;
+var _54=new Array(_53);
+for(var i=0;i<_53;i++){
+_54[i]=_51.charCodeAt(i)&255;
+}
+var _56=_25(_54);
+var key=_3(_54,_56);
+key=key.concat(key.slice(0,_53-16));
+var _58=_25(key);
+_50=_50.split(" ");
+var _59=16;
+var _5a=new Array(_59);
+var _5b=_50[0];
+_5a=_4b(_5b);
+var _5c=new Array(_50.length-1);
+for(var b=1;b<_50.length;b++){
+for(var c=0;c<4;c++){
+_5a[15-c]=((b-1)>>>c*8)&255;
+}
+for(var c=0;c<4;c++){
+_5a[15-c-4]=((b/4294967296-1)>>>c*8)&255;
+}
+var _5f=_3(_5a,_58);
+var pt="";
+var tmp=_4b(_50[b]);
+for(var i=0;i<tmp.length;i++){
+var _62=_50[b].charCodeAt(i);
+var _63=tmp[i]^_5f[i];
+pt+=String.fromCharCode(_63);
+}
+_5c[b-1]=pt;
+}
+return _5c.join("");
+};
+function _64(str){
+return str.replace(/[\0\t\n\v\f\r\xa0!-]/g,function(c){
+return "!"+c.charCodeAt(0)+"!";
+});
+};
+function _67(str){
+return str.replace(/!\d\d?\d?!/g,function(c){
+return String.fromCharCode(c.slice(1,-1));
+});
+};
+dojox.encoding.crypto.SimpleAES=new (function(){
+this.encrypt=function(_6a,key){
+return _35(_6a,key,256);
+};
+this.decrypt=function(_6c,key){
+return _4f(_6c,key,256);
+};
+})();
+})();
+}
diff --git a/dojox/encoding/crypto/_base.js b/dojox/encoding/crypto/_base.js
new file mode 100644
index 0000000..94f62c0
--- /dev/null
+++ b/dojox/encoding/crypto/_base.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.encoding.crypto._base"]){
+dojo._hasResource["dojox.encoding.crypto._base"]=true;
+dojo.provide("dojox.encoding.crypto._base");
+(function(){
+var c=dojox.encoding.crypto;
+c.cipherModes={ECB:0,CBC:1,PCBC:2,CFB:3,OFB:4,CTR:5};
+c.outputTypes={Base64:0,Hex:1,String:2,Raw:3};
+})();
+}
diff --git a/dojox/encoding/digests/MD5.js b/dojox/encoding/digests/MD5.js
new file mode 100644
index 0000000..274621a
--- /dev/null
+++ b/dojox/encoding/digests/MD5.js
@@ -0,0 +1,158 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.encoding.digests.MD5"]){
+dojo._hasResource["dojox.encoding.digests.MD5"]=true;
+dojo.provide("dojox.encoding.digests.MD5");
+dojo.require("dojox.encoding.digests._base");
+(function(){
+var _1=dojox.encoding.digests;
+var _2=8;
+function R(n,c){
+return (n<<c)|(n>>>(32-c));
+};
+function C(q,a,b,x,s,t){
+return _1.addWords(R(_1.addWords(_1.addWords(a,q),_1.addWords(x,t)),s),b);
+};
+function FF(a,b,c,d,x,s,t){
+return C((b&c)|((~b)&d),a,b,x,s,t);
+};
+function GG(a,b,c,d,x,s,t){
+return C((b&d)|(c&(~d)),a,b,x,s,t);
+};
+function HH(a,b,c,d,x,s,t){
+return C(b^c^d,a,b,x,s,t);
+};
+function II(a,b,c,d,x,s,t){
+return C(c^(b|(~d)),a,b,x,s,t);
+};
+function _2d(x,len){
+x[len>>5]|=128<<((len)%32);
+x[(((len+64)>>>9)<<4)+14]=len;
+var a=1732584193;
+var b=-271733879;
+var c=-1732584194;
+var d=271733878;
+for(var i=0;i<x.length;i+=16){
+var _35=a;
+var _36=b;
+var _37=c;
+var _38=d;
+a=FF(a,b,c,d,x[i+0],7,-680876936);
+d=FF(d,a,b,c,x[i+1],12,-389564586);
+c=FF(c,d,a,b,x[i+2],17,606105819);
+b=FF(b,c,d,a,x[i+3],22,-1044525330);
+a=FF(a,b,c,d,x[i+4],7,-176418897);
+d=FF(d,a,b,c,x[i+5],12,1200080426);
+c=FF(c,d,a,b,x[i+6],17,-1473231341);
+b=FF(b,c,d,a,x[i+7],22,-45705983);
+a=FF(a,b,c,d,x[i+8],7,1770035416);
+d=FF(d,a,b,c,x[i+9],12,-1958414417);
+c=FF(c,d,a,b,x[i+10],17,-42063);
+b=FF(b,c,d,a,x[i+11],22,-1990404162);
+a=FF(a,b,c,d,x[i+12],7,1804603682);
+d=FF(d,a,b,c,x[i+13],12,-40341101);
+c=FF(c,d,a,b,x[i+14],17,-1502002290);
+b=FF(b,c,d,a,x[i+15],22,1236535329);
+a=GG(a,b,c,d,x[i+1],5,-165796510);
+d=GG(d,a,b,c,x[i+6],9,-1069501632);
+c=GG(c,d,a,b,x[i+11],14,643717713);
+b=GG(b,c,d,a,x[i+0],20,-373897302);
+a=GG(a,b,c,d,x[i+5],5,-701558691);
+d=GG(d,a,b,c,x[i+10],9,38016083);
+c=GG(c,d,a,b,x[i+15],14,-660478335);
+b=GG(b,c,d,a,x[i+4],20,-405537848);
+a=GG(a,b,c,d,x[i+9],5,568446438);
+d=GG(d,a,b,c,x[i+14],9,-1019803690);
+c=GG(c,d,a,b,x[i+3],14,-187363961);
+b=GG(b,c,d,a,x[i+8],20,1163531501);
+a=GG(a,b,c,d,x[i+13],5,-1444681467);
+d=GG(d,a,b,c,x[i+2],9,-51403784);
+c=GG(c,d,a,b,x[i+7],14,1735328473);
+b=GG(b,c,d,a,x[i+12],20,-1926607734);
+a=HH(a,b,c,d,x[i+5],4,-378558);
+d=HH(d,a,b,c,x[i+8],11,-2022574463);
+c=HH(c,d,a,b,x[i+11],16,1839030562);
+b=HH(b,c,d,a,x[i+14],23,-35309556);
+a=HH(a,b,c,d,x[i+1],4,-1530992060);
+d=HH(d,a,b,c,x[i+4],11,1272893353);
+c=HH(c,d,a,b,x[i+7],16,-155497632);
+b=HH(b,c,d,a,x[i+10],23,-1094730640);
+a=HH(a,b,c,d,x[i+13],4,681279174);
+d=HH(d,a,b,c,x[i+0],11,-358537222);
+c=HH(c,d,a,b,x[i+3],16,-722521979);
+b=HH(b,c,d,a,x[i+6],23,76029189);
+a=HH(a,b,c,d,x[i+9],4,-640364487);
+d=HH(d,a,b,c,x[i+12],11,-421815835);
+c=HH(c,d,a,b,x[i+15],16,530742520);
+b=HH(b,c,d,a,x[i+2],23,-995338651);
+a=II(a,b,c,d,x[i+0],6,-198630844);
+d=II(d,a,b,c,x[i+7],10,1126891415);
+c=II(c,d,a,b,x[i+14],15,-1416354905);
+b=II(b,c,d,a,x[i+5],21,-57434055);
+a=II(a,b,c,d,x[i+12],6,1700485571);
+d=II(d,a,b,c,x[i+3],10,-1894986606);
+c=II(c,d,a,b,x[i+10],15,-1051523);
+b=II(b,c,d,a,x[i+1],21,-2054922799);
+a=II(a,b,c,d,x[i+8],6,1873313359);
+d=II(d,a,b,c,x[i+15],10,-30611744);
+c=II(c,d,a,b,x[i+6],15,-1560198380);
+b=II(b,c,d,a,x[i+13],21,1309151649);
+a=II(a,b,c,d,x[i+4],6,-145523070);
+d=II(d,a,b,c,x[i+11],10,-1120210379);
+c=II(c,d,a,b,x[i+2],15,718787259);
+b=II(b,c,d,a,x[i+9],21,-343485551);
+a=_1.addWords(a,_35);
+b=_1.addWords(b,_36);
+c=_1.addWords(c,_37);
+d=_1.addWords(d,_38);
+}
+return [a,b,c,d];
+};
+function _39(_3a,key){
+var wa=_1.stringToWord(key);
+if(wa.length>16){
+wa=_2d(wa,key.length*_2);
+}
+var l=[],r=[];
+for(var i=0;i<16;i++){
+l[i]=wa[i]^909522486;
+r[i]=wa[i]^1549556828;
+}
+var h=_2d(l.concat(_1.stringToWord(_3a)),512+_3a.length*_2);
+return _2d(r.concat(h),640);
+};
+_1.MD5=function(_41,_42){
+var out=_42||_1.outputTypes.Base64;
+var wa=_2d(_1.stringToWord(_41),_41.length*_2);
+switch(out){
+case _1.outputTypes.Raw:
+return wa;
+case _1.outputTypes.Hex:
+return _1.wordToHex(wa);
+case _1.outputTypes.String:
+return _1.wordToString(wa);
+default:
+return _1.wordToBase64(wa);
+}
+};
+_1.MD5._hmac=function(_45,key,_47){
+var out=_47||_1.outputTypes.Base64;
+var wa=_39(_45,key);
+switch(out){
+case _1.outputTypes.Raw:
+return wa;
+case _1.outputTypes.Hex:
+return _1.wordToHex(wa);
+case _1.outputTypes.String:
+return _1.wordToString(wa);
+default:
+return _1.wordToBase64(wa);
+}
+};
+})();
+}
diff --git a/dojox/encoding/digests/SHA1.js b/dojox/encoding/digests/SHA1.js
new file mode 100644
index 0000000..d7ba01f
--- /dev/null
+++ b/dojox/encoding/digests/SHA1.js
@@ -0,0 +1,137 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.encoding.digests.SHA1"]){
+dojo._hasResource["dojox.encoding.digests.SHA1"]=true;
+dojo.provide("dojox.encoding.digests.SHA1");
+dojo.require("dojox.encoding.digests._base");
+(function(){
+var _1=dojox.encoding.digests;
+var _2=8,_3=(1<<_2)-1;
+function R(n,c){
+return (n<<c)|(n>>>(32-c));
+};
+function FT(t,b,c,d){
+if(t<20){
+return (b&c)|((~b)&d);
+}
+if(t<40){
+return b^c^d;
+}
+if(t<60){
+return (b&c)|(b&d)|(c&d);
+}
+return b^c^d;
+};
+function KT(t){
+return (t<20)?1518500249:(t<40)?1859775393:(t<60)?-1894007588:-899497514;
+};
+function _e(x,len){
+x[len>>5]|=128<<(24-len%32);
+x[((len+64>>9)<<4)+15]=len;
+var w=new Array(80),a=1732584193,b=-271733879,c=-1732584194,d=271733878,e=-1009589776;
+for(var i=0;i<x.length;i+=16){
+var _18=a,_19=b,_1a=c,_1b=d,_1c=e;
+for(var j=0;j<80;j++){
+if(j<16){
+w[j]=x[i+j];
+}else{
+w[j]=R(w[j-3]^w[j-8]^w[j-14]^w[j-16],1);
+}
+var t=_1.addWords(_1.addWords(R(a,5),FT(j,b,c,d)),_1.addWords(_1.addWords(e,w[j]),KT(j)));
+e=d;
+d=c;
+c=R(b,30);
+b=a;
+a=t;
+}
+a=_1.addWords(a,_18);
+b=_1.addWords(b,_19);
+c=_1.addWords(c,_1a);
+d=_1.addWords(d,_1b);
+e=_1.addWords(e,_1c);
+}
+return [a,b,c,d,e];
+};
+function _1f(_20,key){
+var wa=_23(key);
+if(wa.length>16){
+wa=_e(wa,key.length*_2);
+}
+var _24=new Array(16),_25=new Array(16);
+for(var i=0;i<16;i++){
+_24[i]=wa[i]^909522486;
+_25[i]=wa[i]^1549556828;
+}
+var _27=_e(_24.concat(_23(_20)),512+_20.length*_2);
+return _e(_25.concat(_27),512+160);
+};
+function _23(s){
+var wa=[];
+for(var i=0,l=s.length*_2;i<l;i+=_2){
+wa[i>>5]|=(s.charCodeAt(i/_2)&_3)<<(32-_2-i%32);
+}
+return wa;
+};
+function _2c(wa){
+var h="0123456789abcdef",s=[];
+for(var i=0,l=wa.length*4;i<l;i++){
+s.push(h.charAt((wa[i>>2]>>((3-i%4)*8+4))&15),h.charAt((wa[i>>2]>>((3-i%4)*8))&15));
+}
+return s.join("");
+};
+function _32(wa){
+var s=[];
+for(var i=0,l=wa.length*32;i<l;i+=_2){
+s.push(String.fromCharCode((wa[i>>5]>>>(32-_2-i%32))&_3));
+}
+return s.join("");
+};
+function _37(wa){
+var p="=",tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=[];
+for(var i=0,l=wa.length*4;i<l;i+=3){
+var t=(((wa[i>>2]>>8*(3-i%4))&255)<<16)|(((wa[i+1>>2]>>8*(3-(i+1)%4))&255)<<8)|((wa[i+2>>2]>>8*(3-(i+2)%4))&255);
+for(var j=0;j<4;j++){
+if(i*8+j*6>wa.length*32){
+s.push(p);
+}else{
+s.push(tab.charAt((t>>6*(3-j))&63));
+}
+}
+}
+return s.join("");
+};
+_1.SHA1=function(_40,_41){
+var out=_41||_1.outputTypes.Base64;
+var wa=_e(_23(_40),_40.length*_2);
+switch(out){
+case _1.outputTypes.Raw:
+return wa;
+case _1.outputTypes.Hex:
+return _2c(wa);
+case _1.outputTypes.String:
+return _32(wa);
+default:
+return _37(wa);
+}
+};
+_1.SHA1._hmac=function(_44,key,_46){
+var out=_46||_1.outputTypes.Base64;
+var wa=_1f(_44,key);
+switch(out){
+case _1.outputTypes.Raw:
+return wa;
+case _1.outputTypes.Hex:
+return _2c(wa);
+case _1.outputTypes.String:
+return _32(wa);
+default:
+return _37(wa);
+}
+};
+})();
+}
diff --git a/dojox/encoding/digests/_base.js b/dojox/encoding/digests/_base.js
new file mode 100644
index 0000000..3552903
--- /dev/null
+++ b/dojox/encoding/digests/_base.js
@@ -0,0 +1,57 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.encoding.digests._base"]){
+dojo._hasResource["dojox.encoding.digests._base"]=true;
+dojo.provide("dojox.encoding.digests._base");
+(function(){
+var d=dojox.encoding.digests;
+d.outputTypes={Base64:0,Hex:1,String:2,Raw:3};
+d.addWords=function(a,b){
+var l=(a&65535)+(b&65535);
+var m=(a>>16)+(b>>16)+(l>>16);
+return (m<<16)|(l&65535);
+};
+var _6=8;
+var _7=(1<<_6)-1;
+d.stringToWord=function(s){
+var wa=[];
+for(var i=0,l=s.length*_6;i<l;i+=_6){
+wa[i>>5]|=(s.charCodeAt(i/_6)&_7)<<(i%32);
+}
+return wa;
+};
+d.wordToString=function(wa){
+var s=[];
+for(var i=0,l=wa.length*32;i<l;i+=_6){
+s.push(String.fromCharCode((wa[i>>5]>>>(i%32))&_7));
+}
+return s.join("");
+};
+d.wordToHex=function(wa){
+var h="0123456789abcdef",s=[];
+for(var i=0,l=wa.length*4;i<l;i++){
+s.push(h.charAt((wa[i>>2]>>((i%4)*8+4))&15)+h.charAt((wa[i>>2]>>((i%4)*8))&15));
+}
+return s.join("");
+};
+d.wordToBase64=function(wa){
+var p="=",tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=[];
+for(var i=0,l=wa.length*4;i<l;i+=3){
+var t=(((wa[i>>2]>>8*(i%4))&255)<<16)|(((wa[i+1>>2]>>8*((i+1)%4))&255)<<8)|((wa[i+2>>2]>>8*((i+2)%4))&255);
+for(var j=0;j<4;j++){
+if(i*8+j*6>wa.length*32){
+s.push(p);
+}else{
+s.push(tab.charAt((t>>6*(3-j))&63));
+}
+}
+}
+return s.join("");
+};
+})();
+}
diff --git a/dojox/encoding/easy64.js b/dojox/encoding/easy64.js
new file mode 100644
index 0000000..fd7dae6
--- /dev/null
+++ b/dojox/encoding/easy64.js
@@ -0,0 +1,47 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.encoding.easy64"]){
+dojo._hasResource["dojox.encoding.easy64"]=true;
+dojo.provide("dojox.encoding.easy64");
+(function(){
+var c=function(_2,_3,_4){
+for(var i=0;i<_3;i+=3){
+_4.push(String.fromCharCode((_2[i]>>>2)+33),String.fromCharCode(((_2[i]&3)<<4)+(_2[i+1]>>>4)+33),String.fromCharCode(((_2[i+1]&15)<<2)+(_2[i+2]>>>6)+33),String.fromCharCode((_2[i+2]&63)+33));
+}
+};
+dojox.encoding.easy64.encode=function(_6){
+var _7=[],_8=_6.length%3,_9=_6.length-_8;
+c(_6,_9,_7);
+if(_8){
+var t=_6.slice(_9);
+while(t.length<3){
+t.push(0);
+}
+c(t,3,_7);
+for(var i=3;i>_8;_7.pop(),--i){
+}
+}
+return _7.join("");
+};
+dojox.encoding.easy64.decode=function(_c){
+var n=_c.length,r=[],b=[0,0,0,0],i,j,d;
+for(i=0;i<n;i+=4){
+for(j=0;j<4;++j){
+b[j]=_c.charCodeAt(i+j)-33;
+}
+d=n-i;
+for(j=d;j<4;b[++j]=0){
+}
+r.push((b[0]<<2)+(b[1]>>>4),((b[1]&15)<<4)+(b[2]>>>2),((b[2]&3)<<6)+b[3]);
+for(j=d;j<4;++j,r.pop()){
+}
+}
+return r;
+};
+})();
+}
diff --git a/dojox/flash.js b/dojox/flash.js
new file mode 100644
index 0000000..147438c
--- /dev/null
+++ b/dojox/flash.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.flash"]){
+dojo._hasResource["dojox.flash"]=true;
+dojo.provide("dojox.flash");
+dojo.require("dojox.flash._base");
+}
diff --git a/dojox/flash/DojoExternalInterface.as b/dojox/flash/DojoExternalInterface.as
new file mode 100644
index 0000000..e2f71a6
--- /dev/null
+++ b/dojox/flash/DojoExternalInterface.as
@@ -0,0 +1,177 @@
+/**
+	A wrapper around Flash 8's ExternalInterface; this is needed
+	because ExternalInterface has a number of serialization bugs that we 
+	need to correct for.
+	
+	@author Brad Neuberg
+*/
+
+import flash.external.ExternalInterface;
+
+class DojoExternalInterface{
+	public static var available:Boolean;
+	public static var dojoPath = "";
+		
+	public static function initialize(){
+		//trace("DojoExternalInterface.initialize");
+		
+		// extract the dojo base path
+		DojoExternalInterface.dojoPath = DojoExternalInterface.getDojoPath();
+		
+		// see if we need to do an express install
+		var install:ExpressInstall = new ExpressInstall();
+		if(install.needsUpdate){
+			install.init();
+		}
+		
+		// set whether communication is available
+		DojoExternalInterface.available = ExternalInterface.available;
+		
+		// make sure we can play nice in XD settings
+		System.security.allowDomain(unescape(_root.xdomain));
+	}
+	
+	/** Called when we are finished adding methods through addCallback. */
+	public static function done(){
+		//trace("done");
+		DojoExternalInterface.call("dojox.flash.loaded");
+	}
+	
+	public static function addCallback(methodName:String, instance:Object, 
+									   method:Function):Boolean{
+		//trace("addCallback");
+		ExternalInterface.addCallback(methodName, instance, function(){
+			instance = (instance) ? instance : null;
+			var params = [];
+			if(arguments && arguments.length){
+				for(var i = 0; i < arguments.length; i++){
+					params[i] = DojoExternalInterface.decodeData(arguments[i]);
+				}
+			}
+			
+			var results = method.apply(instance, params);
+			results = DojoExternalInterface.encodeData(results);
+			
+			return results;
+		});
+		
+		// tell JavaScript about DojoExternalInterface new method so we can create a proxy
+		ExternalInterface.call("dojox.flash.comm._addExternalInterfaceCallback", 
+													 methodName);
+													 
+		return true;
+	}
+	
+	public static function call(methodName:String):Void{
+		// we might have any number of optional arguments, so we have to 
+		// pass them in dynamically; strip out the results callback
+		var parameters = new Array();
+		for(var i = 0; i < arguments.length; i++){
+			parameters.push(arguments[i]);
+		}
+		
+		// FIXME: Should we be encoding or decoding the data to get
+		// around Flash's serialization bugs?
+		
+		var results = ExternalInterface.call.apply(ExternalInterface, parameters);
+		
+		return results;
+	}
+	
+	/** 
+		Called by Flash to indicate to JavaScript that we are ready to have
+		our Flash functions called. Calling loaded()
+		will fire the dojox.flash.loaded() event, so that JavaScript can know that
+		Flash has finished loading and adding its callbacks, and can begin to
+		interact with the Flash file.
+	*/
+	public static function loaded(){
+		DojoExternalInterface.call("dojox.flash.loaded");
+	}
+	
+	/**
+		Utility trace implementation that prints out to console.debug.
+	*/
+	public static function trace(msg){
+		DojoExternalInterface.call("console.debug", "FLASH: " + msg);
+	}
+	
+	private static function decodeData(data):String{
+		if(!data || typeof data != "string"){
+			return data;
+		}
+		
+		//      JAC: Using unicode character 0001 to store instead of Unicode null 
+		//      which causes trouble 
+		data = replaceStr(data, "&custom_null;", "\u0001");
+		
+		// we have to use custom encodings for certain characters when passing
+		// them over; for example, passing a backslash over as //// from JavaScript
+		// to Flash doesn't work
+		data = replaceStr(data, "&custom_backslash;", "\\");
+		
+		return data;
+	}
+	
+	private static function encodeData(data):String{	
+		if(!data || typeof data != "string"){
+			return data;
+		}
+		
+		// double encode all entity values, or they will be mis-decoded 
+		// by Flash when returned 
+		data = replaceStr(data, "&", "&");
+		
+		// certain XMLish characters break Flash's wire serialization for
+		// ExternalInterface; encode these into a custom encoding, rather than
+		// the standard entity encoding, because otherwise we won't be able to
+		// differentiate between our own encoding and any entity characters
+		// that are being used in the string itself
+		data = replaceStr(data, '<', '&custom_lt;');
+		data = replaceStr(data, '>', '&custom_gt;');
+		
+		// needed for IE
+		data = replaceStr(data, '\\', '&custom_backslash;');
+		data = replaceStr(data, "\u0001", "&custom_null;");
+		
+		// encode control characters and JavaScript delimiters
+		data = replaceStr(data, "\n", "\\n");
+		data = replaceStr(data, "\r", "\\r");
+		data = replaceStr(data, "\f", "\\f");
+		data = replaceStr(data, "'", "\\'");
+		data = replaceStr(data, '"', '\"');
+		
+		return data;
+	}
+	
+	/** 
+			Flash ActionScript has no String.replace method or support for
+			Regular Expressions! We roll our own very simple one.
+	*/
+	public static function replaceStr(inputStr:String, replaceThis:String, 
+										withThis:String):String{
+		var splitStr = inputStr.split(replaceThis);
+		if(!splitStr){
+			return inputStr;
+		}
+		
+		inputStr = splitStr.join(withThis);
+		return inputStr;
+	}
+	
+	private static function getDojoPath(){
+		var url = _root._url;
+		var start = url.indexOf("baseUrl=") + "baseUrl=".length;
+		var path = url.substring(start);
+		var end = path.indexOf("&");
+		if(end != -1){
+			path = path.substring(0, end);
+		}
+		
+		// some browsers append a junk string at the end: '%20'%20quality=
+		if(path.indexOf("'%20'%20quality=") != -1){
+			path = path.substring(0, path.indexOf("'%20'%20quality="));
+		}
+		return unescape(path);
+	}
+}
diff --git a/dojox/flash/ExpressInstall.as b/dojox/flash/ExpressInstall.as
new file mode 100644
index 0000000..1801171
--- /dev/null
+++ b/dojox/flash/ExpressInstall.as
@@ -0,0 +1,71 @@
+/**
+ * Based on the expressinstall.as class created by Geoff Stearns as part
+ * of the FlashObject library.
+ *
+ * Use this file to invoke the Macromedia Flash Player Express Install functionality
+ * This file is intended for use with the FlashObject embed script. You can download FlashObject 
+ * and this file at the following URL: http://blog.deconcept.com/flashobject/
+ *
+ * Usage: 
+ *          var ExpressInstall = new ExpressInstall();
+ *          
+ *          // test to see if install is needed:
+ *          if (ExpressInstall.needsUpdate) { // returns true if update is needed
+ *              ExpressInstall.init(); // starts the update
+ *          }
+ *
+ *	NOTE: Your Flash movie must be at least 214px by 137px in order to use ExpressInstall.
+ *
+ */
+
+class ExpressInstall{
+	public var needsUpdate:Boolean;
+	private var updater:MovieClip;
+	private var hold:MovieClip;
+	
+	public function ExpressInstall(){
+		// does the user need to update?
+		this.needsUpdate = (_root.MMplayerType == undefined) ? false : true;	
+	}
+
+	public function init():Void{
+		this.loadUpdater();
+	}
+
+	public function loadUpdater():Void{
+		System.security.allowDomain("fpdownload.macromedia.com");
+
+		// hope that nothing is at a depth of 10000000, you can change this depth if needed, but you want
+		// it to be on top of your content if you have any stuff on the first frame
+		this.updater = _root.createEmptyMovieClip("expressInstallHolder", 10000000);
+
+		// register the callback so we know if they cancel or there is an error
+		var _self = this;
+		this.updater.installStatus = _self.onInstallStatus;
+		this.hold = this.updater.createEmptyMovieClip("hold", 1);
+
+		// can't use movieClipLoader because it has to work in 6.0.65
+		this.updater.onEnterFrame = function():Void {
+			if(typeof this.hold.startUpdate == 'function'){
+				_self.initUpdater();
+				this.onEnterFrame = null;
+			}
+		}
+
+		var cacheBuster:Number = Math.random();
+
+		this.hold.loadMovie("http://fpdownload.macromedia.com/pub/flashplayer/"
+												+"update/current/swf/autoUpdater.swf?"+ cacheBuster);
+	}
+
+	private function initUpdater():Void{
+		this.hold.redirectURL = _root.MMredirectURL;
+		this.hold.MMplayerType = _root.MMplayerType;
+		this.hold.MMdoctitle = _root.MMdoctitle;
+		this.hold.startUpdate();
+	}
+
+	public function onInstallStatus(msg):Void{
+		getURL("javascript:dojox.flash.install._onInstallStatus('"+msg+"')");
+	}
+}
diff --git a/dojox/flash/README b/dojox/flash/README
new file mode 100644
index 0000000..bf01cba
--- /dev/null
+++ b/dojox/flash/README
@@ -0,0 +1,31 @@
+-------------------------------------------------------------------------------
+dojox.flash
+-------------------------------------------------------------------------------
+Version 0.5
+Release date: 2008-03-10
+-------------------------------------------------------------------------------
+Project state: experimental
+-------------------------------------------------------------------------------
+Project authors
+	Brad Neuberg (BradNeuberg at dojotoolkit.org)
+	Alex Russell (alex at dojotoolkit.org, only handled minor porting issues)
+-------------------------------------------------------------------------------
+Project description
+
+Infrastructure for high-performance Flash/JS communication
+-------------------------------------------------------------------------------
+Dependencies:
+
+MTASC for creating builds
+-------------------------------------------------------------------------------
+Documentation
+
+TODOC
+-------------------------------------------------------------------------------
+Installation instructions
+
+Not intended as a stand-alone module.
+-------------------------------------------------------------------------------
+Additional Notes
+
+TODOC
diff --git a/dojox/flash/_base.js b/dojox/flash/_base.js
new file mode 100644
index 0000000..c38bcff
--- /dev/null
+++ b/dojox/flash/_base.js
@@ -0,0 +1,299 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.flash._base"]){
+dojo._hasResource["dojox.flash._base"]=true;
+dojo.provide("dojox.flash._base");
+dojo.experimental("dojox.flash");
+dojo.require("dijit._base.place");
+dojox.flash=function(){
+};
+dojox.flash={ready:false,url:null,_visible:true,_loadedListeners:[],_installingListeners:[],setSwf:function(_1,_2){
+this.url=_1;
+this._visible=true;
+if(_2!==null&&_2!==undefined){
+this._visible=_2;
+}
+this._initialize();
+},addLoadedListener:function(_3){
+this._loadedListeners.push(_3);
+},addInstallingListener:function(_4){
+this._installingListeners.push(_4);
+},loaded:function(){
+dojox.flash.ready=true;
+if(dojox.flash._loadedListeners.length){
+for(var i=0;i<dojox.flash._loadedListeners.length;i++){
+dojox.flash._loadedListeners[i].call(null);
+}
+}
+},installing:function(){
+if(dojox.flash._installingListeners.length){
+for(var i=0;i<dojox.flash._installingListeners.length;i++){
+dojox.flash._installingListeners[i].call(null);
+}
+}
+},_initialize:function(){
+var _7=new dojox.flash.Install();
+dojox.flash.installer=_7;
+if(_7.needed()){
+_7.install();
+}else{
+dojox.flash.obj=new dojox.flash.Embed(this._visible);
+dojox.flash.obj.write();
+dojox.flash.comm=new dojox.flash.Communicator();
+}
+}};
+dojox.flash.Info=function(){
+this._detectVersion();
+};
+dojox.flash.Info.prototype={version:-1,versionMajor:-1,versionMinor:-1,versionRevision:-1,capable:false,installing:false,isVersionOrAbove:function(_8,_9,_a){
+_a=parseFloat("."+_a);
+if(this.versionMajor>=_8&&this.versionMinor>=_9&&this.versionRevision>=_a){
+return true;
+}else{
+return false;
+}
+},_detectVersion:function(){
+var _b;
+for(var _c=25;_c>0;_c--){
+if(dojo.isIE){
+var _d;
+try{
+if(_c>6){
+_d=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+_c);
+}else{
+_d=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
+}
+if(typeof _d=="object"){
+if(_c==6){
+_d.AllowScriptAccess="always";
+}
+_b=_d.GetVariable("$version");
+}
+}
+catch(e){
+continue;
+}
+}else{
+_b=this._JSFlashInfo(_c);
+}
+if(_b==-1){
+this.capable=false;
+return;
+}else{
+if(_b!=0){
+var _e;
+if(dojo.isIE){
+var _f=_b.split(" ");
+var _10=_f[1];
+_e=_10.split(",");
+}else{
+_e=_b.split(".");
+}
+this.versionMajor=_e[0];
+this.versionMinor=_e[1];
+this.versionRevision=_e[2];
+var _11=this.versionMajor+"."+this.versionRevision;
+this.version=parseFloat(_11);
+this.capable=true;
+break;
+}
+}
+}
+},_JSFlashInfo:function(_12){
+if(navigator.plugins!=null&&navigator.plugins.length>0){
+if(navigator.plugins["Shockwave Flash 2.0"]||navigator.plugins["Shockwave Flash"]){
+var _13=navigator.plugins["Shockwave Flash 2.0"]?" 2.0":"";
+var _14=navigator.plugins["Shockwave Flash"+_13].description;
+var _15=_14.split(" ");
+var _16=_15[2].split(".");
+var _17=_16[0];
+var _18=_16[1];
+var _19=(_15[3]||_15[4]).split("r");
+var _1a=_19[1]>0?_19[1]:0;
+var _1b=_17+"."+_18+"."+_1a;
+return _1b;
+}
+}
+return -1;
+}};
+dojox.flash.Embed=function(_1c){
+this._visible=_1c;
+};
+dojox.flash.Embed.prototype={width:215,height:138,id:"flashObject",_visible:true,protocol:function(){
+switch(window.location.protocol){
+case "https:":
+return "https";
+break;
+default:
+return "http";
+break;
+}
+},write:function(_1d){
+var _1e;
+var _1f=dojox.flash.url;
+var _20=_1f;
+var _21=_1f;
+var _22=dojo.baseUrl;
+var _23=document.location.protocol+"//"+document.location.host;
+if(_1d){
+var _24=escape(window.location);
+document.title=document.title.slice(0,47)+" - Flash Player Installation";
+var _25=escape(document.title);
+_20+="?MMredirectURL="+_24+"&MMplayerType=ActiveX"+"&MMdoctitle="+_25+"&baseUrl="+escape(_22)+"&xdomain="+escape(_23);
+_21+="?MMredirectURL="+_24+"&MMplayerType=PlugIn"+"&baseUrl="+escape(_22)+"&xdomain="+escape(_23);
+}else{
+_20+="?cachebust="+new Date().getTime();
+_20+="&baseUrl="+escape(_22);
+_20+="&xdomain="+escape(_23);
+}
+if(_21.indexOf("?")==-1){
+_21+="?baseUrl="+escape(_22);
+}else{
+_21+="&baseUrl="+escape(_22);
+}
+_21+="&xdomain="+escape(_23);
+_1e="<object classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" "+"codebase=\""+this.protocol()+"://fpdownload.macromedia.com/pub/shockwave/cabs/flash/"+"swflash.cab#version=8,0,0,0\"\n "+"width=\""+this.width+"\"\n "+"height=\""+this.height+"\"\n "+"id=\""+this.id+"\"\n "+"name=\""+this.id+"\"\n "+"align=\"middle\">\n "+"<param name=\"allowScriptAccess\" value=\"always\"></param>\n "+"<param name=\"movie\" value=\""+_20+"\"></param>\n "+"<param name=\"quality\" value=\"high\"></para [...]
+dojo.connect(dojo,"loaded",dojo.hitch(this,function(){
+var _26=this.id+"Container";
+if(dojo.byId(_26)){
+return;
+}
+var div=document.createElement("div");
+div.id=this.id+"Container";
+div.style.width=this.width+"px";
+div.style.height=this.height+"px";
+if(!this._visible){
+div.style.position="absolute";
+div.style.zIndex="10000";
+div.style.top="-1000px";
+}
+div.innerHTML=_1e;
+var _28=document.getElementsByTagName("body");
+if(!_28||!_28.length){
+throw new Error("No body tag for this page");
+}
+_28=_28[0];
+_28.appendChild(div);
+}));
+},get:function(){
+if(dojo.isIE||dojo.isWebKit){
+return dojo.byId(this.id);
+}else{
+return document[this.id+"Embed"];
+}
+},setVisible:function(_29){
+var _2a=dojo.byId(this.id+"Container");
+if(_29){
+_2a.style.position="absolute";
+_2a.style.visibility="visible";
+}else{
+_2a.style.position="absolute";
+_2a.style.y="-1000px";
+_2a.style.visibility="hidden";
+}
+},center:function(){
+var _2b=this.width;
+var _2c=this.height;
+var _2d=dijit.getViewport();
+var x=_2d.l+(_2d.w-_2b)/2;
+var y=_2d.t+(_2d.h-_2c)/2;
+var _30=dojo.byId(this.id+"Container");
+_30.style.top=y+"px";
+_30.style.left=x+"px";
+}};
+dojox.flash.Communicator=function(){
+};
+dojox.flash.Communicator.prototype={_addExternalInterfaceCallback:function(_31){
+var _32=dojo.hitch(this,function(){
+var _33=new Array(arguments.length);
+for(var i=0;i<arguments.length;i++){
+_33[i]=this._encodeData(arguments[i]);
+}
+var _35=this._execFlash(_31,_33);
+_35=this._decodeData(_35);
+return _35;
+});
+this[_31]=_32;
+},_encodeData:function(_36){
+if(!_36||typeof _36!="string"){
+return _36;
+}
+_36=_36.replace("\\","&custom_backslash;");
+_36=_36.replace(/\0/g,"&custom_null;");
+return _36;
+},_decodeData:function(_37){
+if(_37&&_37.length&&typeof _37!="string"){
+_37=_37[0];
+}
+if(!_37||typeof _37!="string"){
+return _37;
+}
+_37=_37.replace(/\&custom_null\;/g,"\x00");
+_37=_37.replace(/\&custom_lt\;/g,"<").replace(/\&custom_gt\;/g,">").replace(/\&custom_backslash\;/g,"\\");
+return _37;
+},_execFlash:function(_38,_39){
+var _3a=dojox.flash.obj.get();
+_39=(_39)?_39:[];
+for(var i=0;i<_39;i++){
+if(typeof _39[i]=="string"){
+_39[i]=this._encodeData(_39[i]);
+}
+}
+var _3c=function(){
+return eval(_3a.CallFunction("<invoke name=\""+_38+"\" returntype=\"javascript\">"+__flash__argumentsToXML(_39,0)+"</invoke>"));
+};
+var _3d=_3c.call(_39);
+if(typeof _3d=="string"){
+_3d=this._decodeData(_3d);
+}
+return _3d;
+}};
+dojox.flash.Install=function(){
+};
+dojox.flash.Install.prototype={needed:function(){
+if(!dojox.flash.info.capable){
+return true;
+}
+if(!dojox.flash.info.isVersionOrAbove(8,0,0)){
+return true;
+}
+return false;
+},install:function(){
+var _3e;
+dojox.flash.info.installing=true;
+dojox.flash.installing();
+if(dojox.flash.info.capable==false){
+_3e=new dojox.flash.Embed(false);
+_3e.write();
+}else{
+if(dojox.flash.info.isVersionOrAbove(6,0,65)){
+_3e=new dojox.flash.Embed(false);
+_3e.write(true);
+_3e.setVisible(true);
+_3e.center();
+}else{
+alert("This content requires a more recent version of the Macromedia "+" Flash Player.");
+window.location.href=+dojox.flash.Embed.protocol()+"://www.macromedia.com/go/getflashplayer";
+}
+}
+},_onInstallStatus:function(msg){
+if(msg=="Download.Complete"){
+dojox.flash._initialize();
+}else{
+if(msg=="Download.Cancelled"){
+alert("This content requires a more recent version of the Macromedia "+" Flash Player.");
+window.location.href=dojox.flash.Embed.protocol()+"://www.macromedia.com/go/getflashplayer";
+}else{
+if(msg=="Download.Failed"){
+alert("There was an error downloading the Flash Player update. "+"Please try again later, or visit macromedia.com to download "+"the latest version of the Flash plugin.");
+}
+}
+}
+}};
+dojox.flash.info=new dojox.flash.Info();
+}
diff --git a/dojox/form/BusyButton.js b/dojox/form/BusyButton.js
new file mode 100644
index 0000000..da54e85
--- /dev/null
+++ b/dojox/form/BusyButton.js
@@ -0,0 +1,79 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.BusyButton"]){
+dojo._hasResource["dojox.form.BusyButton"]=true;
+dojo.provide("dojox.form.BusyButton");
+dojo.require("dijit.form.Button");
+dojo.requireLocalization("dijit","loading",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.declare("dojox.form._BusyButtonMixin",null,{isBusy:false,busyLabel:"",timeout:null,useIcon:true,postMixInProperties:function(){
+this.inherited(arguments);
+if(!this.busyLabel){
+this.busyLabel=dojo.i18n.getLocalization("dijit","loading",this.lang).loadingState;
+}
+},postCreate:function(){
+this._label=this.containerNode.innerHTML;
+this._initTimeout=this.timeout;
+if(this.isBusy){
+this.makeBusy();
+}
+},makeBusy:function(){
+this.isBusy=true;
+this.attr("disabled",true);
+this.setLabel(this.busyLabel,this.timeout);
+},cancel:function(){
+this.attr("disabled",false);
+this.isBusy=false;
+this.setLabel(this._label);
+if(this._timeout){
+clearTimeout(this._timeout);
+}
+this.timeout=this._initTimeout;
+},resetTimeout:function(_1){
+if(this._timeout){
+clearTimeout(this._timeout);
+}
+if(_1){
+this._timeout=setTimeout(dojo.hitch(this,function(){
+this.cancel();
+}),_1);
+}else{
+if(_1==undefined||_1===0){
+this.cancel();
+}
+}
+},setLabel:function(_2,_3){
+this.label=_2;
+while(this.containerNode.firstChild){
+this.containerNode.removeChild(this.containerNode.firstChild);
+}
+this.containerNode.innerHTML=this.label;
+this._layoutHack();
+if(this.showLabel==false&&!(dojo.attr(this.domNode,"title"))){
+this.titleNode.title=dojo.trim(this.containerNode.innerText||this.containerNode.textContent||"");
+}
+if(_3){
+this.resetTimeout(_3);
+}else{
+this.timeout=null;
+}
+if(this.useIcon&&this.isBusy){
+var _4=new Image();
+_4.src=this._blankGif;
+dojo.attr(_4,"id",this.id+"_icon");
+dojo.addClass(_4,"dojoxBusyButtonIcon");
+this.containerNode.appendChild(_4);
+}
+},_clicked:function(e){
+if(!this.isBusy){
+this.makeBusy();
+}
+}});
+dojo.declare("dojox.form.BusyButton",[dijit.form.Button,dojox.form._BusyButtonMixin],{});
+dojo.declare("dojox.form.BusyComboButton",[dijit.form.ComboButton,dojox.form._BusyButtonMixin],{});
+dojo.declare("dojox.form.BusyDropDownButton",[dijit.form.DropDownButton,dojox.form._BusyButtonMixin],{});
+}
diff --git a/dojox/form/CheckedMultiSelect.js b/dojox/form/CheckedMultiSelect.js
new file mode 100644
index 0000000..4a9d410
--- /dev/null
+++ b/dojox/form/CheckedMultiSelect.js
@@ -0,0 +1,99 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.CheckedMultiSelect"]){
+dojo._hasResource["dojox.form.CheckedMultiSelect"]=true;
+dojo.provide("dojox.form.CheckedMultiSelect");
+dojo.require("dijit.form.CheckBox");
+dojo.require("dojox.form._FormSelectWidget");
+dojo.declare("dojox.form._CheckedMultiSelectItem",[dijit._Widget,dijit._Templated],{widgetsInTemplate:true,templateString:"<div class=\"dijitReset ${baseClass}\"\n\t><input class=\"${baseClass}Box\" dojoType=\"dijit.form.CheckBox\" dojoAttachPoint=\"checkBox\" \n\t\tdojoAttachEvent=\"_onClick:_changeBox\" type=\"${_type.type}\" baseClass=\"${_type.baseClass}\"\n\t><div class=\"dijitInline ${baseClass}Label\" dojoAttachPoint=\"labelNode\" dojoAttachEvent=\"onmousedown:_onMouse,onmouseover [...]
+if(this.parent._multiValue){
+this._type={type:"checkbox",baseClass:"dijitCheckBox"};
+}else{
+this._type={type:"radio",baseClass:"dijitRadio"};
+}
+this.disabled=this.option.disabled=this.option.disabled||false;
+this.inherited(arguments);
+},postCreate:function(){
+this.inherited(arguments);
+this.labelNode.innerHTML=this.option.label;
+},_changeBox:function(){
+if(this.attr("disabled")||this.attr("readOnly")){
+return;
+}
+if(this.parent._multiValue){
+this.option.selected=this.checkBox.attr("value")&&true;
+}else{
+this.parent.attr("value",this.option.value);
+}
+this.parent._updateSelection();
+this.parent.focus();
+},_onMouse:function(e){
+if(this.attr("disabled")||this.attr("readOnly")){
+dojo.stopEvent(e);
+}else{
+this.checkBox._onMouse(e);
+}
+},_onClick:function(e){
+if(this.attr("disabled")||this.attr("readOnly")){
+dojo.stopEvent(e);
+}else{
+this.checkBox._onClick(e);
+}
+},_updateBox:function(){
+this.checkBox.attr("value",this.option.selected);
+},_setDisabledAttr:function(_3){
+this.disabled=_3||this.option.disabled;
+this.checkBox.attr("disabled",this.disabled);
+dojo.toggleClass(this.domNode,"dojoxMultiSelectDisabled",this.disabled);
+},_setReadOnlyAttr:function(_4){
+this.checkBox.attr("readOnly",_4);
+this.checkBox._setStateClass();
+this.readOnly=_4;
+}});
+dojo.declare("dojox.form.CheckedMultiSelect",dojox.form._FormSelectWidget,{templateString:"",templateString:"<div class=\"dijit dijitReset dijitInline\" dojoAttachEvent=\"onmousedown:_mouseDown,onclick:focus\"\n\t><select class=\"${baseClass}Select\" multiple=\"true\" dojoAttachPoint=\"containerNode,focusNode\"></select\n\t><div dojoAttachPoint=\"wrapperDiv\"></div\n></div>\n",baseClass:"dojoxMultiSelect",_mouseDown:function(e){
+dojo.stopEvent(e);
+},_addOptionItem:function(_6){
+this.wrapperDiv.appendChild(new dojox.form._CheckedMultiSelectItem({option:_6,parent:this}).domNode);
+},_updateSelection:function(){
+this.inherited(arguments);
+dojo.forEach(this._getChildren(),function(c){
+c._updateBox();
+});
+},_getChildren:function(){
+return dojo.map(this.wrapperDiv.childNodes,function(n){
+return dijit.byNode(n);
+});
+},invertSelection:function(_9){
+dojo.forEach(this.options,function(i){
+i.selected=!i.selected;
+});
+this._updateSelection();
+},_setDisabledAttr:function(_b){
+this.inherited(arguments);
+dojo.forEach(this._getChildren(),function(_c){
+if(_c&&_c.attr){
+_c.attr("disabled",_b);
+}
+});
+},_setReadOnlyAttr:function(_d){
+if("readOnly" in this.attributeMap){
+this._attrToDom("readOnly",_d);
+}
+this.readOnly=_d;
+dojo.forEach(this._getChildren(),function(_e){
+if(_e&&_e.attr){
+_e.attr("readOnly",_d);
+}
+});
+this._setStateClass();
+},uninitialize:function(){
+dojo.forEach(this._getChildren(),function(_f){
+_f.destroyRecursive();
+});
+}});
+}
diff --git a/dojox/form/DateTextBox.js b/dojox/form/DateTextBox.js
new file mode 100644
index 0000000..d99b16d
--- /dev/null
+++ b/dojox/form/DateTextBox.js
@@ -0,0 +1,58 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.DateTextBox"]){
+dojo._hasResource["dojox.form.DateTextBox"]=true;
+dojo.provide("dojox.form.DateTextBox");
+dojo.require("dojox.widget.Calendar");
+dojo.require("dojox.widget.CalendarViews");
+dojo.require("dijit.form._DateTimeTextBox");
+dojo.declare("dojox.form.DateTextBox",dijit.form._DateTimeTextBox,{popupClass:"dojox.widget.Calendar",_selector:"date",_open:function(){
+this.inherited(arguments);
+dojo.style(this._picker.domNode.parentNode,"position","absolute");
+}});
+dojo.declare("dojox.form.DayTextBox",dojox.form.DateTextBox,{popupClass:"dojox.widget.DailyCalendar",format:function(_1){
+return _1.getDate();
+},validator:function(_2){
+var _3=Number(_2);
+var _4=/(^-?\d\d*$)/.test(String(_2));
+return _2==""||_2==null||(_4&&_3>=1&&_3<=31);
+},_open:function(){
+this.inherited(arguments);
+this._picker.onValueSelected=dojo.hitch(this,function(_5){
+this.focus();
+setTimeout(dojo.hitch(this,"_close"),1);
+dijit.form.TextBox.prototype._setValueAttr.call(this,_5,true,String(_5.getDate()));
+});
+}});
+dojo.declare("dojox.form.MonthTextBox",dojox.form.DateTextBox,{popupClass:"dojox.widget.MonthlyCalendar",format:function(_6){
+return _6+1;
+},validator:function(_7){
+var _8=Number(_7);
+var _9=/(^-?\d\d*$)/.test(String(_7));
+return _7==""||_7==null||(_9&&_8>=1&&_8<=12);
+},_open:function(){
+this.inherited(arguments);
+this._picker.onValueSelected=dojo.hitch(this,function(_a){
+this.focus();
+setTimeout(dojo.hitch(this,"_close"),1);
+dijit.form.TextBox.prototype._setValueAttr.call(this,_a+1,true,_a+1);
+});
+}});
+dojo.declare("dojox.form.YearTextBox",dojox.form.DateTextBox,{popupClass:"dojox.widget.YearlyCalendar",format:function(_b){
+return _b;
+},validator:function(_c){
+return _c==""||_c==null||/(^-?\d\d*$)/.test(String(_c));
+},_open:function(){
+this.inherited(arguments);
+this._picker.onValueSelected=dojo.hitch(this,function(_d){
+this.focus();
+setTimeout(dojo.hitch(this,"_close"),1);
+dijit.form.TextBox.prototype._setValueAttr.call(this,_d,true,_d);
+});
+}});
+}
diff --git a/dojox/form/DropDownSelect.js b/dojox/form/DropDownSelect.js
new file mode 100644
index 0000000..3ec5270
--- /dev/null
+++ b/dojox/form/DropDownSelect.js
@@ -0,0 +1,133 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.DropDownSelect"]){
+dojo._hasResource["dojox.form.DropDownSelect"]=true;
+dojo.provide("dojox.form.DropDownSelect");
+dojo.require("dojox.form._FormSelectWidget");
+dojo.require("dojox.form._HasDropDown");
+dojo.require("dijit.Menu");
+dojo.requireLocalization("dijit.form","validate",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.declare("dojox.form.DropDownSelect",[dojox.form._FormSelectWidget,dojox.form._HasDropDown],{attributeMap:dojo.mixin(dojo.clone(dojox.form._FormSelectWidget.prototype.attributeMap),{value:"valueNode",name:"valueNode"}),baseClass:"dojoxDropDownSelect",templateString:"<table class='dijit dijitReset dijitInline dijitLeft'\n\tdojoAttachPoint=\"dropDownNode,tableNode\" cellspacing='0' cellpadding='0' waiRole=\"presentation\"\n\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse [...]
+this.inherited(arguments);
+if(this.options.length&&!this.value){
+var si=this.srcNodeRef.selectedIndex;
+this.value=this.options[si!=-1?si:0].value;
+}
+this.dropDown=new dijit.Menu();
+dojo.addClass(this.dropDown.domNode,this.baseClass+"Menu");
+},_getMenuItemForOption:function(_2){
+if(!_2.value){
+return new dijit.MenuSeparator();
+}else{
+var _3=dojo.hitch(this,"_setValueAttr",_2);
+return new dijit.MenuItem({option:_2,label:_2.label,onClick:_3,disabled:_2.disabled||false});
+}
+},_addOptionItem:function(_4){
+this.dropDown.addChild(this._getMenuItemForOption(_4));
+},_getChildren:function(){
+return this.dropDown.getChildren();
+},_loadChildren:function(){
+this.inherited(arguments);
+var _5=this.options.length;
+this._isLoaded=false;
+this._childrenLoaded=true;
+if(!this._iReadOnly){
+this.attr("readOnly",(_5===1));
+delete this._iReadOnly;
+}
+if(!this._iDisabled){
+this.attr("disabled",(_5===0));
+delete this._iDisabled;
+}
+this._setValueAttr(this.value);
+},_setValueAttr:function(_6){
+this.inherited(arguments);
+dojo.attr(this.valueNode,"value",this.attr("value"));
+},_setDisplay:function(_7){
+this.containerNode.innerHTML="<span class=\" "+this.baseClass+"Label\">"+(_7||this.emptyLabel||" ")+"</span>";
+this._layoutHack();
+},validate:function(_8){
+var _9=this.isValid(_8);
+this.state=_9?"":"Error";
+this._setStateClass();
+dijit.setWaiState(this.focusNode,"invalid",_9?"false":"true");
+var _a=_9?"":this._missingMsg;
+if(this._message!==_a){
+this._message=_a;
+dijit.hideTooltip(this.domNode);
+if(_a){
+dijit.showTooltip(_a,this.domNode,this.tooltipPosition);
+}
+}
+return _9;
+},isValid:function(_b){
+return (!this.required||!(/^\s*$/.test(this.value)));
+},reset:function(){
+this.inherited(arguments);
+dijit.hideTooltip(this.domNode);
+this.state="";
+this._setStateClass();
+delete this._message;
+},postMixInProperties:function(){
+this.inherited(arguments);
+this._missingMsg=dojo.i18n.getLocalization("dijit.form","validate",this.lang).missingMessage;
+},postCreate:function(){
+this.inherited(arguments);
+if(dojo.attr(this.srcNodeRef,"disabled")){
+this.attr("disabled",true);
+}
+if(this.tableNode.style.width){
+dojo.addClass(this.domNode,this.baseClass+"FixedWidth");
+}
+},startup:function(){
+if(this._started){
+return;
+}
+if(!this.dropDown){
+var _c=dojo.query("[widgetId]",this.dropDownContainer)[0];
+this.dropDown=dijit.byNode(_c);
+delete this.dropDownContainer;
+}
+this.inherited(arguments);
+},_onMenuMouseup:function(e){
+var _e=this.dropDown,t=e.target;
+if(_e.onItemClick){
+var _10;
+while(t&&!(_10=dijit.byNode(t))){
+t=t.parentNode;
+}
+if(_10&&_10.onClick&&_10.getParent){
+_10.getParent().onItemClick(_10,e);
+}
+}
+},isLoaded:function(){
+return this._isLoaded;
+},loadDropDown:function(_11){
+this._loadChildren();
+this._isLoaded=true;
+_11();
+},_setReadOnlyAttr:function(_12){
+this._iReadOnly=_12;
+if(!_12&&this._childrenLoaded&&this.options.length===1){
+return;
+}
+this.readOnly=_12;
+},_setDisabledAttr:function(_13){
+this._iDisabled=_13;
+if(!_13&&this._childrenLoaded&&this.options.length===0){
+return;
+}
+this.inherited(arguments);
+},uninitialize:function(_14){
+if(this.dropDown){
+this.dropDown.destroyRecursive(_14);
+delete this.dropDown;
+}
+this.inherited(arguments);
+}});
+}
diff --git a/dojox/form/DropDownStack.js b/dojox/form/DropDownStack.js
new file mode 100644
index 0000000..302c0e9
--- /dev/null
+++ b/dojox/form/DropDownStack.js
@@ -0,0 +1,14 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.DropDownStack"]){
+dojo._hasResource["dojox.form.DropDownStack"]=true;
+dojo.provide("dojox.form.DropDownStack");
+dojo.require("dojox.form.DropDownSelect");
+dojo.require("dojox.form._SelectStackMixin");
+dojo.declare("dojox.form.DropDownStack",[dojox.form.DropDownSelect,dojox.form._SelectStackMixin],{});
+}
diff --git a/dojox/form/FileInput.js b/dojox/form/FileInput.js
new file mode 100644
index 0000000..55c4350
--- /dev/null
+++ b/dojox/form/FileInput.js
@@ -0,0 +1,42 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.FileInput"]){
+dojo._hasResource["dojox.form.FileInput"]=true;
+dojo.provide("dojox.form.FileInput");
+dojo.experimental("dojox.form.FileInput");
+dojo.require("dijit.form._FormWidget");
+dojo.require("dijit._Templated");
+dojo.declare("dojox.form.FileInput",dijit.form._FormWidget,{label:"Browse ...",cancelText:"Cancel",name:"uploadFile",templateString:"<div class=\"dijitFileInput\">\n\t<input id=\"${id}\" class=\"dijitFileInputReal\" type=\"file\" dojoAttachPoint=\"fileInput\" name=\"${name}\" />\n\t<div class=\"dijitFakeInput\">\n\t\t<input class=\"dijitFileInputVisible\" type=\"text\" dojoAttachPoint=\"focusNode, inputNode\" />\n\t\t<div class=\"dijitInline dijitFileInputText\" dojoAttachPoint=\"titleNo [...]
+this._listener=this.connect(this.fileInput,"onchange","_matchValue");
+this._keyListener=this.connect(this.fileInput,"onkeyup","_matchValue");
+},_matchValue:function(){
+this.inputNode.value=this.fileInput.value;
+if(this.inputNode.value){
+this.cancelNode.style.visibility="visible";
+dojo.fadeIn({node:this.cancelNode,duration:275}).play();
+}
+},setLabel:function(_1,_2){
+this.titleNode.innerHTML=_1;
+},reset:function(e){
+this.disconnect(this._listener);
+this.disconnect(this._keyListener);
+if(this.fileInput){
+this.domNode.removeChild(this.fileInput);
+}
+dojo.fadeOut({node:this.cancelNode,duration:275}).play();
+this.fileInput=document.createElement("input");
+this.fileInput.setAttribute("type","file");
+this.fileInput.setAttribute("id",this.id);
+this.fileInput.setAttribute("name",this.name);
+dojo.addClass(this.fileInput,"dijitFileInputReal");
+this.domNode.appendChild(this.fileInput);
+this._keyListener=this.connect(this.fileInput,"onkeyup","_matchValue");
+this._listener=this.connect(this.fileInput,"onchange","_matchValue");
+this.inputNode.value="";
+}});
+}
diff --git a/dojox/form/FileInputAuto.js b/dojox/form/FileInputAuto.js
new file mode 100644
index 0000000..bcff9e4
--- /dev/null
+++ b/dojox/form/FileInputAuto.js
@@ -0,0 +1,95 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.FileInputAuto"]){
+dojo._hasResource["dojox.form.FileInputAuto"]=true;
+dojo.provide("dojox.form.FileInputAuto");
+dojo.require("dojox.form.FileInput");
+dojo.require("dojo.io.iframe");
+dojo.declare("dojox.form.FileInputAuto",dojox.form.FileInput,{url:"",blurDelay:2000,duration:500,uploadMessage:"Uploading ...",triggerEvent:"onblur",_sent:false,templateString:"<div class=\"dijitFileInput\">\n\t<input id=\"${id}\" name=\"${name}\" class=\"dijitFileInputReal\" type=\"file\" dojoAttachPoint=\"fileInput\" />\n\t<div class=\"dijitFakeInput\" dojoAttachPoint=\"fakeNodeHolder\">\n\t\t<input class=\"dijitFileInputVisible\" type=\"text\" dojoAttachPoint=\"focusNode, inputNode\"  [...]
+this._blurListener=this.connect(this.fileInput,this.triggerEvent,"_onBlur");
+this._focusListener=this.connect(this.fileInput,"onfocus","_onFocus");
+this.inherited(arguments);
+},_onFocus:function(){
+if(this._blurTimer){
+clearTimeout(this._blurTimer);
+}
+},_onBlur:function(){
+if(this._blurTimer){
+clearTimeout(this._blurTimer);
+}
+if(!this._sent){
+this._blurTimer=setTimeout(dojo.hitch(this,"_sendFile"),this.blurDelay);
+}
+},setMessage:function(_1){
+this.overlay.removeChild(this.overlay.firstChild);
+this.overlay.appendChild(document.createTextNode(_1));
+},_sendFile:function(e){
+if(this._sent||this._sending||!this.fileInput.value){
+return;
+}
+this._sending=true;
+dojo.style(this.fakeNodeHolder,"display","none");
+dojo.style(this.overlay,{opacity:0,display:"block"});
+this.setMessage(this.uploadMessage);
+dojo.fadeIn({node:this.overlay,duration:this.duration}).play();
+var _3;
+if(dojo.isIE){
+_3=document.createElement("<form enctype=\"multipart/form-data\" method=\"post\">");
+_3.encoding="multipart/form-data";
+}else{
+_3=document.createElement("form");
+_3.setAttribute("enctype","multipart/form-data");
+}
+_3.appendChild(this.fileInput);
+dojo.body().appendChild(_3);
+dojo.io.iframe.send({url:this.url,form:_3,handleAs:"json",handle:dojo.hitch(this,"_handleSend")});
+},_handleSend:function(_4,_5){
+this.overlay.removeChild(this.overlay.firstChild);
+this._sent=true;
+this._sending=false;
+dojo.style(this.overlay,{opacity:0,border:"none",background:"none"});
+this.overlay.style.backgroundImage="none";
+this.fileInput.style.display="none";
+this.fakeNodeHolder.style.display="none";
+dojo.fadeIn({node:this.overlay,duration:this.duration}).play(250);
+this.disconnect(this._blurListener);
+this.disconnect(this._focusListener);
+dojo.body().removeChild(_5.args.form);
+this.fileInput=null;
+this.onComplete(_4,_5,this);
+},reset:function(e){
+if(this._blurTimer){
+clearTimeout(this._blurTimer);
+}
+this.disconnect(this._blurListener);
+this.disconnect(this._focusListener);
+this.overlay.style.display="none";
+this.fakeNodeHolder.style.display="";
+this.inherited(arguments);
+this._sent=false;
+this._sending=false;
+this._blurListener=this.connect(this.fileInput,this.triggerEvent,"_onBlur");
+this._focusListener=this.connect(this.fileInput,"onfocus","_onFocus");
+},onComplete:function(_7,_8,_9){
+}});
+dojo.declare("dojox.form.FileInputBlind",dojox.form.FileInputAuto,{startup:function(){
+this.inherited(arguments);
+this._off=dojo.style(this.inputNode,"width");
+this.inputNode.style.display="none";
+this._fixPosition();
+},_fixPosition:function(){
+if(dojo.isIE){
+dojo.style(this.fileInput,"width","1px");
+}else{
+dojo.style(this.fileInput,"left","-"+(this._off)+"px");
+}
+},reset:function(e){
+this.inherited(arguments);
+this._fixPosition();
+}});
+}
diff --git a/dojox/form/FilePickerTextBox.js b/dojox/form/FilePickerTextBox.js
new file mode 100644
index 0000000..b85b047
--- /dev/null
+++ b/dojox/form/FilePickerTextBox.js
@@ -0,0 +1,264 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.FilePickerTextBox"]){
+dojo._hasResource["dojox.form.FilePickerTextBox"]=true;
+dojo.provide("dojox.form.FilePickerTextBox");
+dojo.require("dojox.widget.FilePicker");
+dojo.require("dijit.form.ValidationTextBox");
+dojo.require("dojox.form._HasDropDown");
+dojo.declare("dojox.form.FilePickerTextBox",[dijit.form.ValidationTextBox,dojox.form._HasDropDown],{baseClass:"dojoxFilePickerTextBox",templateString:"<div class=\"dijit dijitReset dijitInlineTable dijitLeft\"\n\tid=\"widget_${id}\"\n\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\" waiRole=\"combobox\" tabIndex=\"-1\"\n\t><div style=\"overflow:hidden;\"\n\t\t><div class='dijitReset dijitRight dijitButtonNode dijitArrowButton dijitDownArrowButton'\n\t [...]
+this.inherited(arguments);
+this.dropDown=new dojox.widget.FilePicker(this.constraints);
+},postCreate:function(){
+this.inherited(arguments);
+this.connect(this.dropDown,"onChange",this._onWidgetChange);
+this.connect(this.focusNode,"onblur","_focusBlur");
+this.connect(this.focusNode,"onfocus","_focusFocus");
+this.connect(this.focusNode,"ondblclick",function(){
+dijit.selectInputText(this.focusNode);
+});
+},_setValueAttr:function(_1,_2,_3){
+if(!this._searchInProgress){
+this.inherited(arguments);
+_1=_1||"";
+var _4=this.dropDown.attr("pathValue")||"";
+if(_1!==_4){
+this._skip=true;
+var fx=dojo.hitch(this,"_setBlurValue");
+this.dropDown._setPathValueAttr(_1,!_3,this._settingBlurValue?fx:null);
+}
+}
+},_onWidgetChange:function(_6){
+if(!_6&&this.focusNode.value){
+this._hasValidPath=false;
+this.focusNode.value="";
+}else{
+this.valueItem=_6;
+var _7=this.dropDown._getPathValueAttr(_6);
+if(_7){
+this._hasValidPath=true;
+}
+if(!this._skip){
+this._setValueAttr(_7,undefined,true);
+}
+delete this._skip;
+}
+this.validate();
+},startup:function(){
+if(!this.dropDown._started){
+this.dropDown.startup();
+}
+this.inherited(arguments);
+},openDropDown:function(){
+this.dropDown.domNode.style.width="0px";
+if(!("minPaneWidth" in (this.constraints||{}))){
+this.dropDown.attr("minPaneWidth",(this.domNode.offsetWidth/this.numPanes));
+}
+this.inherited(arguments);
+},toggleDropDown:function(){
+this.inherited(arguments);
+if(this._opened){
+this.dropDown.attr("pathValue",this.attr("value"));
+}
+},_focusBlur:function(e){
+if(e.explicitOriginalTarget==this.focusNode&&!this._allowBlur){
+window.setTimeout(dojo.hitch(this,function(){
+if(!this._allowBlur){
+this.focus();
+}
+}),1);
+}else{
+if(this._menuFocus){
+this.dropDown._updateClass(this._menuFocus,"Item",{"Hover":false});
+delete this._menuFocus;
+}
+}
+},_focusFocus:function(e){
+if(this._menuFocus){
+this.dropDown._updateClass(this._menuFocus,"Item",{"Hover":false});
+}
+delete this._menuFocus;
+var _a=dijit.getFocus(this);
+if(_a&&_a.node){
+_a=dijit.byNode(_a.node);
+if(_a){
+this._menuFocus=_a.domNode;
+}
+}
+if(this._menuFocus){
+this.dropDown._updateClass(this._menuFocus,"Item",{"Hover":true});
+}
+delete this._allowBlur;
+},_onBlur:function(){
+this._allowBlur=true;
+delete this.dropDown._savedFocus;
+this.inherited(arguments);
+},_setBlurValue:function(){
+if(this.dropDown&&!this._settingBlurValue){
+this._settingBlurValue=true;
+this.attr("value",this.focusNode.value);
+}else{
+delete this._settingBlurValue;
+this.inherited(arguments);
+}
+},parse:function(_b,_c){
+if(this._hasValidPath||this._hasSelection){
+return _b;
+}
+var dd=this.dropDown,_e=dd.topDir,_f=dd.pathSeparator;
+var _10=dd.attr("pathValue");
+var _11=function(v){
+if(_e.length&&v.indexOf(_e)===0){
+v=v.substring(_e.length);
+}
+if(_f&&v[v.length-1]==_f){
+v=v.substring(0,v.length-1);
+}
+return v;
+};
+_10=_11(_10);
+var val=_11(_b);
+if(val==_10){
+return _b;
+}
+return undefined;
+},_startSearchFromInput:function(){
+var dd=this.dropDown,fn=this.focusNode;
+var val=fn.value,_17=val,_18=dd.topDir;
+if(this._hasSelection){
+dijit.selectInputText(fn,_17.length);
+}
+this._hasSelection=false;
+if(_18.length&&val.indexOf(_18)===0){
+val=val.substring(_18.length);
+}
+var _19=val.split(dd.pathSeparator);
+var _1a=dojo.hitch(this,function(idx){
+var dir=_19[idx];
+var _1d=dd.getChildren()[idx];
+var _1e;
+this._searchInProgress=true;
+var _1f=dojo.hitch(this,function(){
+delete this._searchInProgress;
+});
+if((dir||_1d)&&!this._opened){
+this.toggleDropDown();
+}
+if(dir&&_1d){
+var fx=dojo.hitch(this,function(){
+if(_1e){
+this.disconnect(_1e);
+}
+delete _1e;
+var _21=_1d._menu.getChildren();
+var _22=dojo.filter(_21,function(i){
+return i.label==dir;
+})[0];
+var _24=dojo.filter(_21,function(i){
+return (i.label.indexOf(dir)===0);
+})[0];
+if(_22&&((_19.length>idx+1&&_22.children)||(!_22.children))){
+idx++;
+_1d._menu.onItemClick(_22,{type:"internal",stopPropagation:function(){
+},preventDefault:function(){
+}});
+if(_19[idx]){
+_1a(idx);
+}else{
+_1f();
+}
+}else{
+_1d._setSelected(null);
+if(_24&&_19.length===idx+1){
+dd._setInProgress=true;
+dd._removeAfter(_1d);
+delete dd._setInProgress;
+var _26=_24.label;
+if(_24.children){
+_26+=dd.pathSeparator;
+}
+_26=_26.substring(dir.length);
+window.setTimeout(function(){
+dijit.scrollIntoView(_24.domNode);
+},1);
+fn.value=_17+_26;
+dijit.selectInputText(fn,_17.length);
+this._hasSelection=true;
+try{
+_24.focusNode.focus();
+}
+catch(e){
+}
+}else{
+if(this._menuFocus){
+this.dropDown._updateClass(this._menuFocus,"Item",{"Hover":false,"Focus":false});
+}
+delete this._menuFocus;
+}
+_1f();
+}
+});
+if(!_1d.isLoaded){
+_1e=this.connect(_1d,"onLoad",fx);
+}else{
+fx();
+}
+}else{
+if(_1d){
+_1d._setSelected(null);
+dd._setInProgress=true;
+dd._removeAfter(_1d);
+delete dd._setInProgress;
+}
+_1f();
+}
+});
+_1a(0);
+},_onKey:function(e){
+if(this.disabled||this.readOnly){
+return;
+}
+var dk=dojo.keys;
+var c=e.charOrCode;
+if(c==dk.DOWN_ARROW){
+this._allowBlur=true;
+}
+if(c==dk.ENTER&&this._opened){
+this.dropDown.onExecute();
+dijit.selectInputText(this.focusNode,this.focusNode.value.length);
+this._hasSelection=false;
+dojo.stopEvent(e);
+return;
+}
+if((c==dk.RIGHT_ARROW||c==dk.LEFT_ARROW||c==dk.TAB)&&this._hasSelection){
+this._startSearchFromInput();
+dojo.stopEvent(e);
+return;
+}
+this.inherited(arguments);
+var _2a=false;
+if((c==dk.BACKSPACE||c==dk.DELETE)&&this._hasSelection){
+this._hasSelection=false;
+}else{
+if(c==dk.BACKSPACE||c==dk.DELETE||c==" "){
+_2a=true;
+}else{
+_2a=e.keyChar!=="";
+}
+}
+if(this._searchTimer){
+window.clearTimeout(this._searchTimer);
+}
+delete this._searchTimer;
+if(_2a){
+this._hasValidPath=false;
+this._hasSelection=false;
+this._searchTimer=window.setTimeout(dojo.hitch(this,"_startSearchFromInput"),this.searchDelay+1);
+}
+}});
+}
diff --git a/dojox/form/FileUploader.js b/dojox/form/FileUploader.js
new file mode 100644
index 0000000..b04a72f
--- /dev/null
+++ b/dojox/form/FileUploader.js
@@ -0,0 +1,681 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.FileUploader"]){
+dojo._hasResource["dojox.form.FileUploader"]=true;
+dojo.provide("dojox.form.FileUploader");
+dojo.require("dojox.embed.Flash");
+dojo.require("dojo.io.iframe");
+dojo.require("dojox.html.styles");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dojox.embed.flashVars");
+dojo.experimental("dojox.form.FileUploader");
+(function(){
+var _1=dojo.config.uploaderPath||dojo.moduleUrl("dojox.form","resources/uploader.swf");
+var _2=function(o1,o2){
+var o={},nm;
+for(nm in o1){
+if(dojo.isObject(o1[nm])){
+o[nm]=_2({},o1[nm]);
+}else{
+o[nm]=o1[nm];
+}
+}
+for(nm in o2){
+if(dojo.isObject(o2[nm])){
+if(dojo.isObject(o[nm])){
+_2(o[nm],o2[nm]);
+}else{
+_2({},o2[nm]);
+}
+}else{
+o[nm]=o2[nm];
+}
+}
+return o;
+};
+var _7=function(_8){
+if(!_8||_8=="none"){
+return false;
+}
+return _8.replace(/:/g,"||").replace(/\./g,"^^").replace("url(","").replace(")","").replace(/'/g,"").replace(/"/g,"");
+};
+var _9=function(_a){
+var tn=_a.tagName.toLowerCase();
+return tn=="button"||tn=="input";
+};
+var _c=function(_d){
+var o={};
+o.ff=dojo.style(_d,"fontFamily");
+o.ff=o.ff.replace(/\"|\'/g,"");
+o.fw=dojo.style(_d,"fontWeight");
+o.fi=dojo.style(_d,"fontStyle");
+o.fs=parseInt(dojo.style(_d,"fontSize"),10);
+o.fc=new dojo.Color(dojo.style(_d,"color")).toHex();
+o.fc=parseInt(o.fc.substring(1,Infinity),16);
+o.lh=dojo.style(_d,"lineHeight");
+o.ta=dojo.style(_d,"textAlign");
+o.ta=o.ta=="start"||!o.ta?"left":o.ta;
+o.va=_9(_d)?"middle":o.lh==o.h?"middle":dojo.style(_d,"verticalAlign");
+return o;
+};
+var _f=function(_10){
+var cn=dojo.trim(_10.innerHTML);
+if(cn.indexOf("<")>-1){
+cn=escape(cn);
+}
+return cn;
+};
+var _12=function(_13){
+var o={};
+var dim=dojo.contentBox(_13);
+var pad=dojo._getPadExtents(_13);
+o.p=[pad.t,pad.w-pad.l,pad.h-pad.t,pad.l];
+o.w=dim.w+pad.w;
+o.h=dim.h+pad.h;
+o.d=dojo.style(_13,"display");
+var clr=new dojo.Color(dojo.style(_13,"backgroundColor"));
+o.bc=clr.a==0?"#ffffff":clr.toHex();
+o.bc=parseInt(o.bc.substring(1,Infinity),16);
+var url=_7(dojo.style(_13,"backgroundImage"));
+if(url){
+o.bi={url:url,rp:dojo.style(_13,"backgroundRepeat"),pos:escape(dojo.style(_13,"backgroundPosition"))};
+if(!o.bi.pos){
+var rx=dojo.style(_13,"backgroundPositionX");
+var ry=dojo.style(_13,"backgroundPositionY");
+rx=(rx=="left")?"0%":(rx=="right")?"100%":rx;
+ry=(ry=="top")?"0%":(ry=="bottom")?"100%":ry;
+o.bi.pos=escape(rx+" "+ry);
+}
+}
+return _2(o,_c(_13));
+};
+var _1b=function(_1c,_1d,_1e){
+var _1f,_20;
+if(_1e){
+_1f=dojo.place("<"+_1c.tagName+"><span>"+_1c.innerHTML+" "+_1d+"</span></"+_1c.tagName+">",_1c.parentNode);
+var _21=_1f.firstChild;
+dojo.addClass(_21,_1c.className);
+dojo.addClass(_1f,_1d);
+_20=_12(_21);
+}else{
+_1f=dojo.place("<"+_1c.tagName+">"+_1c.innerHTML+"</"+_1c.tagName+">",_1c.parentNode);
+dojo.addClass(_1f,_1c.className);
+dojo.addClass(_1f,_1d);
+_1f.id=_1c.id;
+_20=_12(_1f);
+}
+dojo.destroy(_1f);
+return _20;
+};
+var _22=function(ltr){
+return ltr.charCodeAt(0)<91;
+};
+dojo.declare("dojox.form.FileUploader",[dijit._Widget,dijit._Templated],{uploadUrl:"",uploadOnChange:false,selectMultipleFiles:true,htmlFieldName:"uploadedfile",flashFieldName:"flashUploadFiles",fileMask:[],minFlashVersion:9,tabIndex:-1,showProgress:false,progressMessage:"Loading",progressBackgroundUrl:dojo.moduleUrl("dijit","themes/tundra/images/buttonActive.png"),progressBackgroundColor:"#ededed",progressWidgetId:"",templateString:"<div><div dojoAttachPoint=\"progNode\"><div dojoAttach [...]
+if(this.isDebug){
+console.log.apply(console,arguments);
+}
+},postMixInProperties:function(){
+this.fileList=[];
+this._subs=[];
+this._cons=[];
+this.fileInputs=[];
+this.fileCount=0;
+this.flashReady=false;
+this._disabled=false;
+this.uploaderType=((dojox.embed.Flash.available>=this.minFlashVersion||this.force=="flash")&&this.force!="html")?"flash":"html";
+if(!this.swfPath){
+this.swfPath=_1;
+}
+this.getButtonStyle();
+},postCreate:function(){
+this.setButtonStyle();
+if(this.uploaderType=="flash"){
+this.uploaderType="flash";
+this.createFlashUploader();
+}else{
+this.uploaderType="html";
+this.createHtmlUploader();
+}
+if(this.fileListId){
+dojo.connect(dojo.byId(this.fileListId),"click",this,function(evt){
+var p=evt.target.parentNode.parentNode.parentNode;
+if(p.id&&p.id.indexOf("file_")>-1){
+this.removeFile(p.id.split("file_")[1]);
+}
+});
+}
+},getButtonStyle:function(){
+if(!this.srcNodeRef&&this.button&&this.button.domNode){
+this.isDijitButton=true;
+var cls=this.button.domNode.className+" dijitButtonNode";
+var txt=_f(dojo.query(".dijitButtonText",this.button.domNode)[0]);
+var _28="<button id=\""+this.button.id+"\" class=\""+cls+"\">"+txt+"</button>";
+this.srcNodeRef=dojo.place(_28,this.button.domNode,"after");
+this.button.destroy();
+this.hoverClass="dijitButtonHover";
+this.pressClass="dijitButtonActive";
+this.disabledClass="dijitButtonDisabled";
+}
+this.norm=_12(this.srcNodeRef);
+this.width=this.norm.w;
+this.height=this.norm.h;
+if(this.uploaderType=="flash"){
+if(this.hoverClass){
+this.over=_1b(this.srcNodeRef,this.hoverClass,this.isDijitButton);
+}else{
+this.over=_2({},this.norm);
+}
+if(this.activeClass){
+this.down=_1b(this.srcNodeRef,this.activeClass,this.isDijitButton);
+}else{
+this.down=_2({},this.norm);
+}
+if(this.disabledClass){
+this.dsbl=_1b(this.srcNodeRef,this.disabledClass,this.isDijitButton);
+}else{
+this.dsbl=_2({},this.norm);
+}
+this.fhtml={cn:_f(this.srcNodeRef),nr:this.norm,ov:this.over,dn:this.down,ds:this.dsbl};
+}else{
+this.fhtml={cn:_f(this.srcNodeRef),nr:this.norm};
+}
+},setButtonStyle:function(){
+dojo.style(this.domNode,{width:this.fhtml.nr.w+"px",height:(this.fhtml.nr.h)+"px",padding:"0px",lineHeight:"normal",position:"relative"});
+if(this.showProgress){
+this.progTextNode.innerHTML=this.progressMessage;
+dojo.style(this.progTextNode,{width:this.fhtml.nr.w+"px",height:(this.fhtml.nr.h+0)+"px",padding:"0px",margin:"0px",left:"0px",lineHeight:(this.fhtml.nr.h+0)+"px",position:"absolute"});
+dojo.style(this.progNode,{width:this.fhtml.nr.w+"px",height:(this.fhtml.nr.h+0)+"px",padding:"0px",margin:"0px",left:"0px",position:"absolute",display:"none",backgroundImage:"url("+this.progressBackgroundUrl+")",backgroundPosition:"bottom",backgroundRepeat:"repeat-x",backgroundColor:this.progressBackgroundColor});
+}
+dojo.style(this.insideNode,{position:"absolute",top:"0px",left:"0px",display:""});
+dojo.addClass(this.domNode,this.srcNodeRef.className);
+if(this.fhtml.nr.d.indexOf("inline")>-1){
+dojo.addClass(this.domNode,"dijitInline");
+}
+try{
+this.insideNode.innerHTML=this.fhtml.cn;
+}
+catch(e){
+console.warn("IE inline node",this.domNode.outerHTML);
+if(this.uploaderType=="flash"){
+this.insideNode=this.insideNode.parentNode.removeChild(this.insideNode);
+dojo.body().appendChild(this.insideNode);
+this.insideNode.innerHTML=this.fhtml.cn;
+var c=dojo.connect(this,"onReady",this,function(){
+dojo.disconnect(c);
+this.insideNode=this.insideNode.parentNode.removeChild(this.insideNode);
+this.domNode.appendChild(this.insideNode);
+});
+}else{
+this.insideNode.appendChild(document.createTextNode(this.fhtml.cn));
+}
+}
+this.flashDiv=this.insideNode;
+},onChange:function(_2a){
+},onProgress:function(_2b){
+},onComplete:function(_2c){
+},onCancel:function(){
+this.log("Upload Canceled");
+},onError:function(_2d){
+var _2e=_2d.type?_2d.type.toUpperCase():"ERROR";
+var msg=_2d.msg?_2d.msg:_2d;
+console.error("FLASH/ERROR/"+_2e,msg);
+},onReady:function(){
+},submit:function(_30){
+var _31=_30?dojo.formToObject(_30):null;
+this.upload(_31);
+return false;
+},upload:function(_32){
+if(!this.fileList.length){
+return false;
+}
+if(!this.uploadUrl){
+console.warn("uploadUrl not provided. Aborting.");
+return false;
+}
+if(!this.showProgress){
+this.attr("disabled",true);
+}else{
+}
+if(this.progressWidgetId){
+var _33=dijit.byId(this.progressWidgetId).domNode;
+console.warn("PROGRESS BAR",_33,dojo.style(_33,"display"));
+if(dojo.style(_33,"display")=="none"){
+this.restoreProgDisplay="none";
+dojo.style(_33,"display","block");
+}
+if(dojo.style(_33,"visibility")=="hidden"){
+this.restoreProgDisplay="hidden";
+dojo.style(_33,"visibility","visible");
+}
+}
+if(_32){
+this.postData=_32;
+}
+this.log("upload type:",this.uploaderType," - postData:",this.postData);
+for(var i=0;i<this.fileList.length;i++){
+var f=this.fileList[i];
+f.bytesLoaded=0;
+f.bytesTotal=f.size||100000;
+f.percent=0;
+}
+if(this.uploaderType=="flash"){
+this.uploadFlash();
+}else{
+this.uploadHTML();
+}
+return false;
+},removeFile:function(_36,_37){
+var i;
+for(i=0;i<this.fileList.length;i++){
+if(this.fileList[i].name==_36){
+if(!_37){
+this.fileList.splice(i,1);
+}
+break;
+}
+}
+if(this.uploaderType=="flash"){
+this.flashMovie.removeFile(_36);
+}else{
+if(!_37){
+dojo.destroy(this.fileInputs[i]);
+this.fileInputs.splice(i,1);
+}
+}
+if(this.fileListId){
+dojo.destroy("file_"+_36);
+}
+},destroyAll:function(){
+console.warn("DEPRECATED for 1.5 - use destroy() instead");
+this.destroy();
+},destroy:function(){
+if(this.uploaderType=="flash"&&!this.flashMovie){
+this._cons.push(dojo.connect(this,"onLoad",this,"destroy"));
+return;
+}
+dojo.forEach(this._subs,function(s){
+dojo.unsubscribe(s);
+});
+dojo.forEach(this._cons,function(c){
+dojo.disconnect(c);
+});
+if(this.scrollConnect){
+dojo.disconnect(this.scrollConnect);
+}
+if(this.uploaderType=="flash"){
+this.flashObject.destroy();
+dojo.destroy(this.flashDiv);
+}
+this.inherited(arguments);
+},hide:function(){
+console.warn("DEPRECATED for 1.5 - use dojo.style(domNode, 'display', 'none' instead");
+dojo.style(this.domNode,"display","none");
+},show:function(){
+console.warn("DEPRECATED for 1.5 - use dojo.style(domNode, 'display', '') instead");
+dojo.style(this.domNode,"display","");
+},disable:function(_3b){
+console.warn("DEPRECATED: FileUploader.disable() - will be removed in 1.5. Use attr('disable', true) instead.");
+this.attr("disable",_3b);
+},_displayProgress:function(_3c){
+if(_3c===true){
+if(this.uploaderType=="flash"){
+dojo.style(this.insideNode,"left","-1000px");
+}else{
+dojo.style(this.insideNode,"display","none");
+}
+dojo.style(this.progNode,"display","");
+}else{
+if(_3c===false){
+dojo.style(this.insideNode,"display","");
+dojo.style(this.insideNode,"left","0px");
+dojo.style(this.progNode,"display","none");
+}else{
+var w=_3c*this.fhtml.nr.w;
+dojo.style(this.progNode,{width:w+"px"});
+}
+}
+},_animateProgress:function(){
+this._displayProgress(true);
+var _3e=false;
+var c=dojo.connect(this,"_complete",function(){
+dojo.disconnect(c);
+_3e=true;
+});
+var w=0;
+var _41=setInterval(dojo.hitch(this,function(){
+w+=5;
+if(w>this.fhtml.nr.w){
+w=0;
+_3e=true;
+}
+this._displayProgress(w/this.fhtml.nr.w);
+if(_3e){
+clearInterval(_41);
+setTimeout(dojo.hitch(this,function(){
+this._displayProgress(false);
+}),500);
+}
+}),50);
+},_error:function(evt){
+this.onError(evt);
+},_addToFileList:function(){
+if(this.fileListId){
+var str="";
+dojo.forEach(this.fileList,function(d){
+str+="<table id=\"file_"+d.name+"\" class=\"fileToUpload\"><tr><td class=\"fileToUploadClose\"></td><td class=\"fileToUploadName\">"+d.name+"</td><td class=\"fileToUploadSize\">"+Math.ceil(d.size*0.001)+"kb</td></tr></table>";
+},this);
+dojo.byId(this.fileListId).innerHTML=str;
+}
+},_change:function(_45){
+if(dojo.isIE){
+dojo.forEach(_45,function(f){
+f.name=f.name.split("\\")[f.name.split("\\").length-1];
+});
+}
+if(this.selectMultipleFiles){
+this.fileList=this.fileList.concat(_45);
+}else{
+if(this.fileList[0]){
+this.removeFile(this.fileList[0].name);
+}
+this.fileList=_45;
+}
+this._addToFileList();
+this.onChange(_45);
+if(this.uploadOnChange){
+this.upload();
+}else{
+if(this.uploaderType=="html"&&this.selectMultipleFiles){
+this._buildFileInput();
+this._connectInput();
+}
+}
+},_complete:function(_47){
+_47=dojo.isArray(_47)?_47:[_47];
+dojo.forEach(_47,function(f){
+if(f.ERROR){
+console.error(f.ERROR);
+this._error(new Error(f.ERROR));
+}
+},this);
+dojo.forEach(this.fileList,function(f){
+f.bytesLoaded=1;
+f.bytesTotal=1;
+f.percent=100;
+this._progress(f);
+},this);
+dojo.forEach(this.fileList,function(f){
+this.removeFile(f.name,true);
+},this);
+this.onComplete(_47);
+this.fileList=[];
+this._resetHTML();
+this.attr("disabled",false);
+if(this.restoreProgDisplay){
+setTimeout(dojo.hitch(this,function(){
+dojo.style(dijit.byId(this.progressWidgetId).domNode,this.restoreProgDisplay=="none"?"display":"visibility",this.restoreProgDisplay);
+}),700);
+}
+},_progress:function(_4b){
+var _4c=0;
+var _4d=0;
+for(var i=0;i<this.fileList.length;i++){
+var f=this.fileList[i];
+if(f.name==_4b.name){
+f.bytesLoaded=_4b.bytesLoaded;
+f.bytesTotal=_4b.bytesTotal;
+f.percent=Math.ceil(f.bytesLoaded/f.bytesTotal*100);
+
+}
+_4d+=Math.ceil(0.001*f.bytesLoaded);
+_4c+=Math.ceil(0.001*f.bytesTotal);
+}
+var _50=Math.ceil(_4d/_4c*100);
+if(this.progressWidgetId){
+dijit.byId(this.progressWidgetId).update({progress:_50+"%"});
+}
+if(this.showProgress){
+this._displayProgress(_50*0.01);
+}
+this.onProgress(this.fileList);
+},_getDisabledAttr:function(){
+return this._disabled;
+},_setDisabledAttr:function(_51){
+if(this._disabled==_51){
+return;
+}
+if(this.uploaderType=="flash"){
+if(!this.flashReady){
+var _fc=dojo.connect(this,"onReady",this,function(){
+dojo.disconnect(_fc);
+this._setDisabledAttr(_51);
+});
+return;
+}
+this._disabled=_51;
+this.flashMovie.doDisable(_51);
+if(_51){
+dojo.addClass(this.domNode,this.disabledClass);
+}else{
+dojo.removeClass(this.domNode,this.disabledClass);
+}
+}else{
+this._disabled=_51;
+if(_51){
+dojo.addClass(this.domNode,this.disabledClass);
+dojo.style(this._fileInput,"display","none");
+}else{
+dojo.removeClass(this.domNode,this.disabledClass);
+dojo.style(this._fileInput,"display","");
+}
+}
+},_onFlashBlur:function(){
+this.flashMovie.blur();
+if(!this.nextFocusObject&&this.tabIndex){
+var _53=dojo.query("[tabIndex]");
+for(var i=0;i<_53.length;i++){
+if(_53[i].tabIndex>=Number(this.tabIndex)+1){
+this.nextFocusObject=_53[i];
+break;
+}
+}
+}
+this.nextFocusObject.focus();
+},_disconnect:function(){
+dojo.forEach(this._cons,function(c){
+dojo.disconnect(c);
+});
+},uploadHTML:function(){
+dojo.destroy(this._fileInput);
+this._setHtmlPostData();
+if(this.showProgress){
+this._animateProgress();
+}
+dojo.io.iframe.send({url:this.uploadUrl,form:this._formNode,handleAs:"json",handle:dojo.hitch(this,function(_56,_57,_58){
+this._complete(_56);
+})});
+},createHtmlUploader:function(){
+this._buildForm();
+this._setFormStyle();
+this._buildFileInput();
+this._connectInput();
+this._styleContent();
+this.onReady();
+},_connectInput:function(){
+this._disconnect();
+this._cons.push(dojo.connect(this._fileInput,"mouseover",this,function(evt){
+dojo.addClass(this.domNode,this.hoverClass);
+this.onMouseOver(evt);
+}));
+this._cons.push(dojo.connect(this._fileInput,"mouseout",this,function(evt){
+dojo.removeClass(this.domNode,this.activeClass);
+dojo.removeClass(this.domNode,this.hoverClass);
+this.onMouseOut(evt);
+this._checkHtmlCancel("off");
+}));
+this._cons.push(dojo.connect(this._fileInput,"mousedown",this,function(evt){
+dojo.addClass(this.domNode,this.activeClass);
+dojo.removeClass(this.domNode,this.hoverClass);
+this.onMouseDown(evt);
+}));
+this._cons.push(dojo.connect(this._fileInput,"mouseup",this,function(evt){
+dojo.removeClass(this.domNode,this.activeClass);
+this.onMouseUp(evt);
+this.onClick(evt);
+this._checkHtmlCancel("up");
+}));
+this._cons.push(dojo.connect(this._fileInput,"change",this,function(){
+this.log("html change");
+this._checkHtmlCancel("change");
+this._change([{name:this._fileInput.value,type:"",size:0}]);
+}));
+if(this.tabIndex>=0){
+dojo.attr(this.domNode,"tabIndex",this.tabIndex);
+}
+},_checkHtmlCancel:function(_5d){
+if(_5d=="change"){
+this.dialogIsOpen=false;
+}
+if(_5d=="up"){
+this.dialogIsOpen=true;
+}
+if(_5d=="off"){
+if(this.dialogIsOpen){
+this.onCancel();
+}
+this.dialogIsOpen=false;
+}
+},_styleContent:function(){
+var o=this.fhtml.nr;
+dojo.style(this.insideNode,{width:o.w+"px",height:o.va=="middle"?o.h+"px":"auto",lineHeight:o.va=="middle"?o.h+"px":"auto",textAlign:o.ta,paddingTop:o.p[0]+"px",paddingRight:o.p[1]+"px",paddingBottom:o.p[2]+"px",paddingLeft:o.p[3]+"px"});
+},_resetHTML:function(){
+if(this.uploaderType=="html"&&this._formNode){
+dojo.query("*",this._formNode).forEach(function(n){
+dojo.destroy(n);
+});
+this.fileCount=0;
+this._buildFileInput();
+this._connectInput();
+}
+},_buildForm:function(){
+if(this._formNode){
+return;
+}
+if(dojo.isIE){
+this._formNode=document.createElement("<form enctype=\"multipart/form-data\" method=\"post\">");
+this._formNode.encoding="multipart/form-data";
+}else{
+this._formNode=document.createElement("form");
+this._formNode.setAttribute("enctype","multipart/form-data");
+}
+this._formNode.id=dijit.getUniqueId("FileUploaderForm");
+this.domNode.appendChild(this._formNode);
+},_buildFileInput:function(){
+if(this._fileInput){
+this._disconnect();
+this._fileInput.id=this._fileInput.id+this.fileCount;
+dojo.style(this._fileInput,"display","none");
+}
+this._fileInput=document.createElement("input");
+this.fileInputs.push(this._fileInput);
+var nm=this.htmlFieldName;
+var _id=this.id;
+if(this.selectMultipleFiles){
+nm+=this.fileCount;
+_id+=this.fileCount;
+this.fileCount++;
+}
+dojo.attr(this._fileInput,{id:this.id,name:nm,type:"file"});
+dojo.addClass(this._fileInput,"dijitFileInputReal");
+this._formNode.appendChild(this._fileInput);
+var _62=dojo.marginBox(this._fileInput);
+dojo.style(this._fileInput,{position:"relative",left:(this.fhtml.nr.w-_62.w)+"px",opacity:0});
+},_setFormStyle:function(){
+var _63=Math.max(2,Math.max(Math.ceil(this.fhtml.nr.w/60),Math.ceil(this.fhtml.nr.h/15)));
+dojox.html.insertCssRule("#"+this._formNode.id+" input","font-size:"+_63+"em");
+dojo.style(this.domNode,{overflow:"hidden",position:"relative"});
+dojo.style(this.insideNode,"position","absolute");
+},_setHtmlPostData:function(){
+if(this.postData){
+for(var nm in this.postData){
+var f=document.createElement("input");
+dojo.attr(f,"type","hidden");
+dojo.attr(f,"name",nm);
+dojo.attr(f,"value",this.postData[nm]);
+this._formNode.appendChild(f);
+}
+}
+},uploadFlash:function(){
+try{
+if(this.showProgress){
+this._displayProgress(true);
+var c=dojo.connect(this,"_complete",this,function(){
+dojo.disconnect(c);
+this._displayProgress(false);
+});
+}
+this.flashMovie.doUpload(this.postData);
+}
+catch(err){
+throw new Error("Sorry, the SWF failed to initialize."+err);
+}
+},createFlashUploader:function(){
+this.uploadUrl=this.uploadUrl.toString();
+if(this.uploadUrl){
+if(this.uploadUrl.toLowerCase().indexOf("http")<0&&this.uploadUrl.indexOf("/")!=0){
+var loc=window.location.href.split("/");
+loc.pop();
+loc=loc.join("/")+"/";
+this.uploadUrl=loc+this.uploadUrl;
+this.log("SWF Fixed - Relative loc:",loc," abs loc:",this.uploadUrl);
+}
+}else{
+}
+var w=this.fhtml.nr.w;
+var h=this.fhtml.nr.h;
+var _6a={expressInstall:true,path:this.swfPath.uri||this.swfPath,width:w,height:h,allowScriptAccess:"always",allowNetworking:"all",vars:{uploadDataFieldName:this.flashFieldName,uploadUrl:this.uploadUrl,uploadOnSelect:this.uploadOnChange,deferredUploading:this.deferredUploading,selectMultipleFiles:this.selectMultipleFiles,id:this.id,isDebug:this.isDebug,devMode:this.devMode,flashButton:dojox.embed.flashVars.serialize("fh",this.fhtml),fileMask:dojox.embed.flashVars.serialize("fm",this.file [...]
+this.flashObject=new dojox.embed.Flash(_6a,this.insideNode);
+
+this.flashObject.onError=function(msg){
+console.warn("Flash Error:",msg);
+};
+this.flashObject.onReady=dojo.hitch(this,function(){
+});
+this.flashObject.onLoad=dojo.hitch(this,function(mov){
+this.flashMovie=mov;
+this.flashReady=true;
+this.onReady();
+});
+this._connectFlash();
+},_connectFlash:function(){
+this._doSub("/filesSelected","_change");
+this._doSub("/filesUploaded","_complete");
+this._doSub("/filesProgress","_progress");
+this._doSub("/filesError","_error");
+this._doSub("/filesCanceled","onCancel");
+this._doSub("/stageBlur","_onFlashBlur");
+this._doSub("/up","onMouseUp");
+this._doSub("/down","onMouseDown");
+this._doSub("/over","onMouseOver");
+this._doSub("/out","onMouseOut");
+this.connect(this.domNode,"focus",function(){
+this.flashMovie.focus();
+this.flashMovie.doFocus();
+dojo.connect(document,"keydown",function(evt){
+
+});
+});
+if(this.tabIndex>=0){
+dojo.attr(this.domNode,"tabIndex",this.tabIndex);
+}
+},_doSub:function(_6e,_6f){
+this._subs.push(dojo.subscribe(this.id+_6e,this,_6f));
+}});
+})();
+}
diff --git a/dojox/form/Manager.js b/dojox/form/Manager.js
new file mode 100644
index 0000000..20298db
--- /dev/null
+++ b/dojox/form/Manager.js
@@ -0,0 +1,35 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.Manager"]){
+dojo._hasResource["dojox.form.Manager"]=true;
+dojo.provide("dojox.form.Manager");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dojox.form.manager._Mixin");
+dojo.require("dojox.form.manager._NodeMixin");
+dojo.require("dojox.form.manager._FormMixin");
+dojo.require("dojox.form.manager._ValueMixin");
+dojo.require("dojox.form.manager._EnableMixin");
+dojo.require("dojox.form.manager._DisplayMixin");
+dojo.require("dojox.form.manager._ClassMixin");
+dojo.declare("dojox.form.Manager",[dijit._Widget,dijit._Templated,dojox.form.manager._Mixin,dojox.form.manager._NodeMixin,dojox.form.manager._FormMixin,dojox.form.manager._ValueMixin,dojox.form.manager._EnableMixin,dojox.form.manager._DisplayMixin,dojox.form.manager._ClassMixin],{widgetsInTemplate:true,buildRendering:function(){
+var _1=this.domNode=this.srcNodeRef;
+if(!this.containerNode){
+this.containerNode=_1;
+}
+this._attachTemplateNodes(_1);
+},startup:function(){
+if(this._started){
+return;
+}
+this._attachTemplateNodes(this.getDescendants(),function(n,p){
+return n[p];
+});
+this.inherited(arguments);
+}});
+}
diff --git a/dojox/form/MultiComboBox.js b/dojox/form/MultiComboBox.js
new file mode 100644
index 0000000..32ea2a2
--- /dev/null
+++ b/dojox/form/MultiComboBox.js
@@ -0,0 +1,46 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.MultiComboBox"]){
+dojo._hasResource["dojox.form.MultiComboBox"]=true;
+dojo.provide("dojox.form.MultiComboBox");
+dojo.experimental("dojox.form.MultiComboBox");
+dojo.require("dijit.form.ComboBox");
+dojo.require("dijit.form.ValidationTextBox");
+dojo.declare("dojox.form.MultiComboBox",[dijit.form.ValidationTextBox,dijit.form.ComboBoxMixin],{delimiter:",",_previousMatches:false,_setValueAttr:function(_1){
+if(this.delimiter&&_1.length!=0){
+_1=_1+this.delimiter+" ";
+arguments[0]=this._addPreviousMatches(_1);
+}
+this.inherited(arguments);
+},_addPreviousMatches:function(_2){
+if(this._previousMatches){
+if(!_2.match(new RegExp("^"+this._previousMatches))){
+_2=this._previousMatches+_2;
+}
+_2=this._cleanupDelimiters(_2);
+}
+return _2;
+},_cleanupDelimiters:function(_3){
+if(this.delimiter){
+_3=_3.replace(new RegExp("  +")," ");
+_3=_3.replace(new RegExp("^ *"+this.delimiter+"* *"),"");
+_3=_3.replace(new RegExp(this.delimiter+" *"+this.delimiter),this.delimiter);
+}
+return _3;
+},_autoCompleteText:function(_4){
+arguments[0]=this._addPreviousMatches(_4);
+this.inherited(arguments);
+},_startSearch:function(_5){
+_5=this._cleanupDelimiters(_5);
+var re=new RegExp("^.*"+this.delimiter+" *");
+if((this._previousMatches=_5.match(re))){
+arguments[0]=_5.replace(re,"");
+}
+this.inherited(arguments);
+}});
+}
diff --git a/dojox/form/PasswordValidator.js b/dojox/form/PasswordValidator.js
new file mode 100644
index 0000000..4762633
--- /dev/null
+++ b/dojox/form/PasswordValidator.js
@@ -0,0 +1,153 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.PasswordValidator"]){
+dojo._hasResource["dojox.form.PasswordValidator"]=true;
+dojo.provide("dojox.form.PasswordValidator");
+dojo.require("dijit.form._FormWidget");
+dojo.require("dijit.form.ValidationTextBox");
+dojo.requireLocalization("dojox.form","PasswordValidator",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.declare("dojox.form._ChildTextBox",dijit.form.ValidationTextBox,{containerWidget:null,type:"password",reset:function(){
+dijit.form.ValidationTextBox.prototype._setValueAttr.call(this,"",true);
+this._hasBeenBlurred=false;
+},postCreate:function(){
+this.inherited(arguments);
+if(!this.name){
+dojo.removeAttr(this.focusNode,"name");
+}
+}});
+dojo.declare("dojox.form._OldPWBox",dojox.form._ChildTextBox,{_isPWValid:false,_setValueAttr:function(_1,_2){
+if(_1===""){
+_1=dojox.form._OldPWBox.superclass.attr.call(this,"value");
+}
+if(_2!==null){
+this._isPWValid=this.containerWidget.pwCheck(_1);
+}
+this.inherited(arguments);
+this.containerWidget._childValueAttr(this.containerWidget._inputWidgets[1].attr("value"));
+},isValid:function(_3){
+return this.inherited("isValid",arguments)&&this._isPWValid;
+},_update:function(e){
+if(this._hasBeenBlurred){
+this.validate(true);
+}
+this._onMouse(e);
+},_getValueAttr:function(){
+if(this.containerWidget._started&&this.containerWidget.isValid()){
+return this.inherited(arguments);
+}
+return "";
+},_setBlurValue:function(){
+var _5=dijit.form.ValidationTextBox.prototype._getValueAttr.call(this);
+this._setValueAttr(_5,(this.isValid?this.isValid():true));
+}});
+dojo.declare("dojox.form._NewPWBox",dojox.form._ChildTextBox,{required:true,onChange:function(){
+this.containerWidget._inputWidgets[2].validate(false);
+this.inherited(arguments);
+}});
+dojo.declare("dojox.form._VerifyPWBox",dojox.form._ChildTextBox,{isValid:function(_6){
+return this.inherited("isValid",arguments)&&(this.attr("value")==this.containerWidget._inputWidgets[1].attr("value"));
+}});
+dojo.declare("dojox.form.PasswordValidator",dijit.form._FormValueWidget,{required:true,_inputWidgets:null,oldName:"",templateString:"<div dojoAttachPoint=\"containerNode\">\n\t<input type=\"hidden\" name=\"${name}\" value=\"\" dojoAttachPoint=\"focusNode\" />\n</div>\n",_hasBeenBlurred:false,isValid:function(_7){
+return dojo.every(this._inputWidgets,function(i){
+if(i&&i._setStateClass){
+i._setStateClass();
+}
+return (!i||i.isValid());
+});
+},validate:function(_9){
+return dojo.every(dojo.map(this._inputWidgets,function(i){
+if(i&&i.validate){
+i._hasBeenBlurred=(i._hasBeenBlurred||this._hasBeenBlurred);
+return i.validate();
+}
+return true;
+},this),"return item;");
+},reset:function(){
+this._hasBeenBlurred=false;
+dojo.forEach(this._inputWidgets,function(i){
+if(i&&i.reset){
+i.reset();
+}
+},this);
+},_createSubWidgets:function(){
+var _c=this._inputWidgets,_d=dojo.i18n.getLocalization("dojox.form","PasswordValidator",this.lang);
+dojo.forEach(_c,function(i,_f){
+if(i){
+var p={containerWidget:this},c;
+if(_f===0){
+p.name=this.oldName;
+p.invalidMessage=_d.badPasswordMessage;
+c=dojox.form._OldPWBox;
+}else{
+if(_f===1){
+p.required=this.required;
+c=dojox.form._NewPWBox;
+}else{
+if(_f===2){
+p.invalidMessage=_d.nomatchMessage;
+c=dojox.form._VerifyPWBox;
+}
+}
+}
+_c[_f]=new c(p,i);
+}
+},this);
+},pwCheck:function(_12){
+return false;
+},postCreate:function(){
+this.inherited(arguments);
+var _13=this._inputWidgets=[];
+dojo.forEach(["old","new","verify"],function(i){
+_13.push(dojo.query("input[pwType="+i+"]",this.containerNode)[0]);
+},this);
+if(!_13[1]||!_13[2]){
+throw new Error("Need at least pwType=\"new\" and pwType=\"verify\"");
+}
+if(this.oldName&&!_13[0]){
+throw new Error("Need to specify pwType=\"old\" if using oldName");
+}
+this._createSubWidgets();
+this.connect(this._inputWidgets[1],"_setValueAttr","_childValueAttr");
+this.connect(this._inputWidgets[2],"_setValueAttr","_childValueAttr");
+},_childValueAttr:function(v){
+this.attr("value",this.isValid()?v:"");
+},_setDisabledAttr:function(_16){
+this.inherited(arguments);
+dojo.forEach(this._inputWidgets,function(i){
+if(i&&i.attr){
+i.attr("disabled",_16);
+}
+});
+},_setRequiredAttribute:function(_18){
+this.required=_18;
+dojo.attr(this.focusNode,"required",_18);
+dijit.setWaiState(this.focusNode,"required",_18);
+this._refreshState();
+dojo.forEach(this._inputWidgets,function(i){
+if(i&&i.attr){
+i.attr("required",_18);
+}
+});
+},_setValueAttr:function(v){
+this.inherited(arguments);
+dojo.attr(this.focusNode,"value",v);
+},_getValueAttr:function(){
+return this.inherited(arguments)||"";
+},focus:function(){
+var f=false;
+dojo.forEach(this._inputWidgets,function(i){
+if(i&&!i.isValid()&&!f){
+i.focus();
+f=true;
+}
+});
+if(!f){
+this._inputWidgets[1].focus();
+}
+}});
+}
diff --git a/dojox/form/README b/dojox/form/README
new file mode 100644
index 0000000..ef7a7b8
--- /dev/null
+++ b/dojox/form/README
@@ -0,0 +1,70 @@
+-------------------------------------------------------------------------------
+dojox.form Collection
+-------------------------------------------------------------------------------
+Version 1.0
+Release date: 02/26/2008
+-------------------------------------------------------------------------------
+Project state:
+experimental
+-------------------------------------------------------------------------------
+Credits
+	Nathan Toone (nathan)
+	Peter Higgins	(dante)
+    Wolfram Kriesing (http://wolfram.kriesing.de/blog/): Rating
+    Mike Wilcox
+-------------------------------------------------------------------------------
+Project description
+
+	This is a collection of additional widgets that can be used in forms.
+-------------------------------------------------------------------------------
+Dependencies:
+
+	Depends on dojo core and dijit
+	
+	dojo.form.FileUploader depends on dojox.embed, and uses Flash movies created
+	in the deft project using Flex OSS 3.  You do not need any of the deft code; 
+	compiled movies are included with dojox.form in the resources folder.  
+	If you want to modify the actual movies, you can look in the deft project 
+	(under the package deft.av).
+-------------------------------------------------------------------------------
+Documentation
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+	Install into /dojox/form
+-------------------------------------------------------------------------------
+Additional Notes (Brief widget list):
+
+	* CheckedMultiSelect - an extension to dijit.form.MultiSelect which
+						uses check boxes instead of ctrl-click
+
+ 	* DropDownSelect - an extension to dijit.form.DropDownButton which is
+ 						meant to mirror the html <select> drop down
+
+	* DropDownStack/RadioStack - a widget that can toggle parts of a form as
+						"on" or "off" - to allow for different options based on 
+						the value selected.
+
+	* FileInput - experimental dijit-like input type="file"
+
+	* FileInputAuto/Blind - extension to FileInput for 
+						added flair/automation
+						
+	* FilePickerTextBox - a validating text box that can browser server-side
+						files using a dojox.data.FileStore
+	* FileUploader - Convert (almost) any button into a file input. Multi-file
+						uploads supported. Uses a SWF file created with Deft.
+						Compatible with Flash Player versions 8-10.
+	
+    * MultiComboBox - an experimental ComboBox that allows
+						multiple entries bases on a separator character.
+
+	* PasswordValidator - a widget which simplifies the common "old/new/verify" 
+						mechanism of specifying passwords
+
+	* Rating - a star-based rating widget
+ 	
+    * TimeSpinner - a number spinner that revolves through
+						time constrainsts
+
diff --git a/dojox/form/RadioStack.js b/dojox/form/RadioStack.js
new file mode 100644
index 0000000..c9b89bd
--- /dev/null
+++ b/dojox/form/RadioStack.js
@@ -0,0 +1,14 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.RadioStack"]){
+dojo._hasResource["dojox.form.RadioStack"]=true;
+dojo.provide("dojox.form.RadioStack");
+dojo.require("dojox.form.CheckedMultiSelect");
+dojo.require("dojox.form._SelectStackMixin");
+dojo.declare("dojox.form.RadioStack",[dojox.form.CheckedMultiSelect,dojox.form._SelectStackMixin],{});
+}
diff --git a/dojox/form/RangeSlider.js b/dojox/form/RangeSlider.js
new file mode 100644
index 0000000..75a3657
--- /dev/null
+++ b/dojox/form/RangeSlider.js
@@ -0,0 +1,330 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.RangeSlider"]){
+dojo._hasResource["dojox.form.RangeSlider"]=true;
+dojo.provide("dojox.form.RangeSlider");
+dojo.require("dijit.form.HorizontalSlider");
+dojo.require("dijit.form.VerticalSlider");
+dojo.require("dojox.fx");
+dojo.declare("dojox.form._RangeSliderMixin",null,{value:[0,100],postCreate:function(){
+this.inherited(arguments);
+if(this._isReversed()){
+this.value.sort(function(a,b){
+return b-a;
+});
+}else{
+this.value.sort(function(a,b){
+return a-b;
+});
+}
+var _5=this;
+var _6=function(){
+dijit.form._SliderMoverMax.apply(this,arguments);
+this.widget=_5;
+};
+dojo.extend(_6,dijit.form._SliderMoverMax.prototype);
+this._movableMax=new dojo.dnd.Moveable(this.sliderHandleMax,{mover:_6});
+dijit.setWaiState(this.focusNodeMax,"valuemin",this.minimum);
+dijit.setWaiState(this.focusNodeMax,"valuemax",this.maximum);
+var _7=function(){
+dijit.form._SliderBarMover.apply(this,arguments);
+this.widget=_5;
+};
+dojo.extend(_7,dijit.form._SliderBarMover.prototype);
+this._movableBar=new dojo.dnd.Moveable(this.progressBar,{mover:_7});
+},destroy:function(){
+this.inherited(arguments);
+this._movableMax.destroy();
+this._movableBar.destroy();
+},_onKeyPress:function(e){
+if(this.disabled||this.readOnly||e.altKey||e.ctrlKey){
+return;
+}
+var _9=e.currentTarget;
+var _a=false;
+var _b=false;
+var _c;
+if(_9==this.sliderHandle){
+_a=true;
+}else{
+if(_9==this.progressBar){
+_b=true;
+_a=true;
+}else{
+if(_9==this.sliderHandleMax){
+_b=true;
+}
+}
+}
+switch(e.keyCode){
+case dojo.keys.HOME:
+this._setValueAttr(this.minimum,true,_b);
+break;
+case dojo.keys.END:
+this._setValueAttr(this.maximum,true,_b);
+break;
+case ((this._descending||this.isLeftToRight())?dojo.keys.RIGHT_ARROW:dojo.keys.LEFT_ARROW):
+case (this._descending===false?dojo.keys.DOWN_ARROW:dojo.keys.UP_ARROW):
+case (this._descending===false?dojo.keys.PAGE_DOWN:dojo.keys.PAGE_UP):
+if(_a&&_b){
+_c=Array();
+_c[0]={"change":e.keyCode==dojo.keys.PAGE_UP?this.pageIncrement:1,"useMaxValue":true};
+_c[1]={"change":e.keyCode==dojo.keys.PAGE_UP?this.pageIncrement:1,"useMaxValue":false};
+this._bumpValue(_c);
+}else{
+if(_a){
+this._bumpValue(e.keyCode==dojo.keys.PAGE_UP?this.pageIncrement:1,true);
+}else{
+if(_b){
+this._bumpValue(e.keyCode==dojo.keys.PAGE_UP?this.pageIncrement:1);
+}
+}
+}
+break;
+case ((this._descending||this.isLeftToRight())?dojo.keys.LEFT_ARROW:dojo.keys.RIGHT_ARROW):
+case (this._descending===false?dojo.keys.UP_ARROW:dojo.keys.DOWN_ARROW):
+case (this._descending===false?dojo.keys.PAGE_UP:dojo.keys.PAGE_DOWN):
+if(_a&&_b){
+_c=Array();
+_c[0]={"change":e.keyCode==dojo.keys.PAGE_DOWN?-this.pageIncrement:-1,"useMaxValue":false};
+_c[1]={"change":e.keyCode==dojo.keys.PAGE_DOWN?-this.pageIncrement:-1,"useMaxValue":true};
+this._bumpValue(_c);
+}else{
+if(_a){
+this._bumpValue(e.keyCode==dojo.keys.PAGE_DOWN?-this.pageIncrement:-1);
+}else{
+if(_b){
+this._bumpValue(e.keyCode==dojo.keys.PAGE_DOWN?-this.pageIncrement:-1,true);
+}
+}
+}
+break;
+default:
+dijit.form._FormValueWidget.prototype._onKeyPress.apply(this,arguments);
+this.inherited(arguments);
+return;
+}
+dojo.stopEvent(e);
+},_onHandleClickMax:function(e){
+if(this.disabled||this.readOnly){
+return;
+}
+if(!dojo.isIE){
+dijit.focus(this.sliderHandleMax);
+}
+dojo.stopEvent(e);
+},_onClkIncBumper:function(){
+this._setValueAttr(this._descending===false?this.minimum:this.maximum,true,true);
+},_bumpValue:function(_e,_f){
+var _10;
+if(!dojo.isArray(_e)){
+_10=this._getBumpValue(_e,_f);
+}else{
+_10=Array();
+_10[0]=this._getBumpValue(_e[0]["change"],_e[0]["useMaxValue"]);
+_10[1]=this._getBumpValue(_e[1]["change"],_e[1]["useMaxValue"]);
+}
+this._setValueAttr(_10,true,!dojo.isArray(_e)&&((_e>0&&!_f)||(_f&&_e<0)));
+},_getBumpValue:function(_11,_12){
+var s=dojo.getComputedStyle(this.sliderBarContainer);
+var c=dojo._getContentBox(this.sliderBarContainer,s);
+var _15=this.discreteValues;
+if(_15<=1||_15==Infinity){
+_15=c[this._pixelCount];
+}
+_15--;
+var _16=!_12?this.value[0]:this.value[1];
+if((this._isReversed()&&_11<0)||(_11>0&&!this._isReversed())){
+_16=!_12?this.value[1]:this.value[0];
+}
+var _17=(_16-this.minimum)*_15/(this.maximum-this.minimum)+_11;
+if(_17<0){
+_17=0;
+}
+if(_17>_15){
+_17=_15;
+}
+return _17*(this.maximum-this.minimum)/_15+this.minimum;
+},_onBarClick:function(e){
+if(this.disabled||this.readOnly){
+return;
+}
+if(!dojo.isIE){
+dijit.focus(this.progressBar);
+}
+dojo.stopEvent(e);
+},_onRemainingBarClick:function(e){
+if(this.disabled||this.readOnly){
+return;
+}
+if(!dojo.isIE){
+dijit.focus(this.progressBar);
+}
+var _1a=dojo.coords(this.sliderBarContainer,true);
+var bar=dojo.coords(this.progressBar,true);
+var _1c=e[this._mousePixelCoord]-_1a[this._startingPixelCoord];
+var _1d=bar[this._startingPixelCount];
+var _1e=bar[this._startingPixelCount]+bar[this._pixelCount];
+var _1f=this._isReversed()?_1c<=_1d:_1c>=_1e;
+this._setPixelValue(this._isReversed()?(_1a[this._pixelCount]-_1c):_1c,_1a[this._pixelCount],true,_1f);
+dojo.stopEvent(e);
+},_setPixelValue:function(_20,_21,_22,_23){
+if(this.disabled||this.readOnly){
+return;
+}
+var _24=this._getValueByPixelValue(_20,_21);
+this._setValueAttr(_24,_22,_23);
+},_getValueByPixelValue:function(_25,_26){
+_25=_25<0?0:_26<_25?_26:_25;
+var _27=this.discreteValues;
+if(_27<=1||_27==Infinity){
+_27=_26;
+}
+_27--;
+var _28=_26/_27;
+var _29=Math.round(_25/_28);
+return (this.maximum-this.minimum)*_29/_27+this.minimum;
+},_setValueAttr:function(_2a,_2b,_2c){
+var _2d=this.value;
+if(!dojo.isArray(_2a)){
+if(_2c){
+if(this._isReversed()){
+_2d[0]=_2a;
+}else{
+_2d[1]=_2a;
+}
+}else{
+if(this._isReversed()){
+_2d[1]=_2a;
+}else{
+_2d[0]=_2a;
+}
+}
+}else{
+_2d=_2a;
+}
+this._lastValueReported="";
+this.valueNode.value=this.value=_2a=_2d;
+dijit.setWaiState(this.focusNode,"valuenow",_2d[0]);
+dijit.setWaiState(this.focusNodeMax,"valuenow",_2d[1]);
+if(this._isReversed()){
+this.value.sort(function(a,b){
+return b-a;
+});
+}else{
+this.value.sort(function(a,b){
+return a-b;
+});
+}
+dijit.form._FormValueWidget.prototype._setValueAttr.apply(this,arguments);
+this._printSliderBar(_2b,_2c);
+},_printSliderBar:function(_32,_33){
+var _34=(this.value[0]-this.minimum)/(this.maximum-this.minimum);
+var _35=(this.value[1]-this.minimum)/(this.maximum-this.minimum);
+var _36=_34;
+if(_34>_35){
+_34=_35;
+_35=_36;
+}
+var _37=this._isReversed()?((1-_34)*100):(_34*100);
+var _38=this._isReversed()?((1-_35)*100):(_35*100);
+var _39=this._isReversed()?((1-_35)*100):(_34*100);
+if(_32&&this.slideDuration>0&&this.progressBar.style[this._progressPixelSize]){
+var _3a=_33?_35:_34;
+var _3b=this;
+var _3c={};
+var _3d=parseFloat(this.progressBar.style[this._handleOffsetCoord]);
+var _3e=this.slideDuration/10;
+if(_3e===0){
+return;
+}
+if(_3e<0){
+_3e=0-_3e;
+}
+var _3f={};
+var _40={};
+var _41={};
+_3f[this._handleOffsetCoord]={start:this.sliderHandle.style[this._handleOffsetCoord],end:_37,units:"%"};
+_40[this._handleOffsetCoord]={start:this.sliderHandleMax.style[this._handleOffsetCoord],end:_38,units:"%"};
+_41[this._handleOffsetCoord]={start:this.progressBar.style[this._handleOffsetCoord],end:_39,units:"%"};
+_41[this._progressPixelSize]={start:this.progressBar.style[this._progressPixelSize],end:(_35-_34)*100,units:"%"};
+var _42=dojo.animateProperty({node:this.sliderHandle,duration:_3e,properties:_3f});
+var _43=dojo.animateProperty({node:this.sliderHandleMax,duration:_3e,properties:_40});
+var _44=dojo.animateProperty({node:this.progressBar,duration:_3e,properties:_41});
+var _45=dojo.fx.combine([_42,_43,_44]);
+_45.play();
+}else{
+this.sliderHandle.style[this._handleOffsetCoord]=_37+"%";
+this.sliderHandleMax.style[this._handleOffsetCoord]=_38+"%";
+this.progressBar.style[this._handleOffsetCoord]=_39+"%";
+this.progressBar.style[this._progressPixelSize]=((_35-_34)*100)+"%";
+}
+}});
+dojo.declare("dijit.form._SliderMoverMax",dijit.form._SliderMover,{onMouseMove:function(e){
+var _47=this.widget;
+var _48=_47._abspos;
+if(!_48){
+_48=_47._abspos=dojo.coords(_47.sliderBarContainer,true);
+_47._setPixelValue_=dojo.hitch(_47,"_setPixelValue");
+_47._isReversed_=_47._isReversed();
+}
+var _49=e[_47._mousePixelCoord]-_48[_47._startingPixelCoord];
+_47._setPixelValue_(_47._isReversed_?(_48[_47._pixelCount]-_49):_49,_48[_47._pixelCount],false,true);
+},destroy:function(e){
+dojo.dnd.Mover.prototype.destroy.apply(this,arguments);
+var _4b=this.widget;
+_4b._abspos=null;
+_4b._setValueAttr(_4b.value,true);
+}});
+dojo.declare("dijit.form._SliderBarMover",dojo.dnd.Mover,{onMouseMove:function(e){
+var _4d=this.widget;
+if(_4d.disabled||_4d.readOnly){
+return;
+}
+var _4e=_4d._abspos;
+var bar=_4d._bar;
+var _50=_4d._mouseOffset;
+if(!_4e){
+_4e=_4d._abspos=dojo.coords(_4d.sliderBarContainer,true);
+_4d._setPixelValue_=dojo.hitch(_4d,"_setPixelValue");
+_4d._getValueByPixelValue_=dojo.hitch(_4d,"_getValueByPixelValue");
+_4d._isReversed_=_4d._isReversed();
+}
+if(!bar){
+bar=_4d._bar=dojo.coords(_4d.progressBar,true);
+}
+if(!_50){
+_50=_4d._mouseOffset=e[_4d._mousePixelCoord]-_4e[_4d._startingPixelCoord]-bar[_4d._startingPixelCount];
+}
+var _51=e[_4d._mousePixelCoord]-_4e[_4d._startingPixelCoord]-_50;
+var _52=e[_4d._mousePixelCoord]-_4e[_4d._startingPixelCoord]-_50+bar[_4d._pixelCount];
+var _53=[_51,_52];
+_53.sort(function(a,b){
+return a-b;
+});
+if(_53[0]<=0){
+_53[0]=0;
+_53[1]=bar[_4d._pixelCount];
+}
+if(_53[1]>=_4e[_4d._pixelCount]){
+_53[1]=_4e[_4d._pixelCount];
+_53[0]=_4e[_4d._pixelCount]-bar[_4d._pixelCount];
+}
+var _56=[_4d._getValueByPixelValue(_4d._isReversed_?(_4e[_4d._pixelCount]-_53[0]):_53[0],_4e[_4d._pixelCount]),_4d._getValueByPixelValue(_4d._isReversed_?(_4e[_4d._pixelCount]-_53[1]):_53[1],_4e[_4d._pixelCount])];
+_4d._setValueAttr(_56,false,false);
+},destroy:function(e){
+dojo.dnd.Mover.prototype.destroy.apply(this,arguments);
+var _58=this.widget;
+_58._abspos=null;
+_58._bar=null;
+_58._mouseOffset=null;
+_58._setValueAttr(_58.value,true);
+}});
+dojo.declare("dojox.form.HorizontalRangeSlider",[dijit.form.HorizontalSlider,dojox.form._RangeSliderMixin],{templateString:"<table class=\"dijit dijitReset dijitSlider dojoxRangeSlider\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" rules=\"none\"\n    ><tr class=\"dijitReset\"\n        ><td class=\"dijitReset\" colspan=\"2\"></td\n        ><td dojoAttachPoint=\"containerNode,topDecoration\" class=\"dijitReset\" style=\"text-align:center;width:100%;\"></td\n        ><td class=\"dijitR [...]
+dojo.declare("dojox.form.VerticalRangeSlider",[dijit.form.VerticalSlider,dojox.form._RangeSliderMixin],{templateString:"<table class=\"dijitReset dijitSlider dojoxRangeSlider\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" rules=\"none\"\n><tbody class=\"dijitReset\"\n    ><tr class=\"dijitReset\"\n        ><td class=\"dijitReset\"></td\n        ><td class=\"dijitReset dijitSliderButtonContainer dijitSliderButtonContainerV\"\n            ><div class=\"dijitSliderIncrementIconV\" tabIn [...]
+}
diff --git a/dojox/form/Rating.js b/dojox/form/Rating.js
new file mode 100644
index 0000000..e8b95a4
--- /dev/null
+++ b/dojox/form/Rating.js
@@ -0,0 +1,56 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.Rating"]){
+dojo._hasResource["dojox.form.Rating"]=true;
+dojo.provide("dojox.form.Rating");
+dojo.require("dijit.form._FormWidget");
+dojo.declare("dojox.form.Rating",dijit.form._FormWidget,{templateString:null,numStars:3,value:0,constructor:function(_1){
+dojo.mixin(this,_1);
+var _2="<div dojoAttachPoint=\"domNode\" class=\"dojoxRating dijitInline\">"+"<input type=\"hidden\" value=\"0\" dojoAttachPoint=\"focusNode\" /><ul>${stars}</ul>"+"</div>";
+var _3="<li class=\"dojoxRatingStar dijitInline\" dojoAttachEvent=\"onclick:onStarClick,onmouseover:_onMouse,onmouseout:_onMouse\" value=\"${value}\"></li>";
+var _4="";
+for(var i=0;i<this.numStars;i++){
+_4+=dojo.string.substitute(_3,{value:i+1});
+}
+this.templateString=dojo.string.substitute(_2,{stars:_4});
+},postCreate:function(){
+this.inherited(arguments);
+this._renderStars(this.value);
+},_onMouse:function(_6){
+this.inherited(arguments);
+if(this._hovering){
+var _7=+dojo.attr(_6.target,"value");
+this.onMouseOver(_6,_7);
+this._renderStars(_7,true);
+}else{
+this._renderStars(this.value);
+}
+},_renderStars:function(_8,_9){
+dojo.query(".dojoxRatingStar",this.domNode).forEach(function(_a,i){
+if(i+1>_8){
+dojo.removeClass(_a,"dojoxRatingStarHover");
+dojo.removeClass(_a,"dojoxRatingStarChecked");
+}else{
+dojo.removeClass(_a,"dojoxRatingStar"+(_9?"Checked":"Hover"));
+dojo.addClass(_a,"dojoxRatingStar"+(_9?"Hover":"Checked"));
+}
+});
+},onStarClick:function(_c){
+var _d=+dojo.attr(_c.target,"value");
+this.setAttribute("value",_d==this.value?0:_d);
+this._renderStars(this.value);
+this.onChange(this.value);
+},onMouseOver:function(){
+},setAttribute:function(_e,_f){
+this.inherited("setAttribute",arguments);
+if(_e=="value"){
+this._renderStars(this.value);
+this.onChange(this.value);
+}
+}});
+}
diff --git a/dojox/form/TimeSpinner.js b/dojox/form/TimeSpinner.js
new file mode 100644
index 0000000..3f149f2
--- /dev/null
+++ b/dojox/form/TimeSpinner.js
@@ -0,0 +1,28 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.TimeSpinner"]){
+dojo._hasResource["dojox.form.TimeSpinner"]=true;
+dojo.provide("dojox.form.TimeSpinner");
+dojo.require("dijit.form._Spinner");
+dojo.require("dijit.form.NumberTextBox");
+dojo.require("dojo.date");
+dojo.require("dojo.date.locale");
+dojo.require("dojo.date.stamp");
+dojo.declare("dojox.form.TimeSpinner",[dijit.form._Spinner],{required:false,adjust:function(_1,_2){
+return dojo.date.add(_1,"minute",_2);
+},isValid:function(){
+return true;
+},smallDelta:5,largeDelta:30,timeoutChangeRate:0.5,parse:function(_3,_4){
+return dojo.date.locale.parse(_3,{selector:"time",formatLength:"short"});
+},format:function(_5,_6){
+if(dojo.isString(_5)){
+return _5;
+}
+return dojo.date.locale.format(_5,{selector:"time",formatLength:"short"});
+},serialize:dojo.date.stamp.toISOString,value:"12:00 AM"});
+}
diff --git a/dojox/form/_FormSelectWidget.js b/dojox/form/_FormSelectWidget.js
new file mode 100644
index 0000000..327ac7f
--- /dev/null
+++ b/dojox/form/_FormSelectWidget.js
@@ -0,0 +1,211 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form._FormSelectWidget"]){
+dojo._hasResource["dojox.form._FormSelectWidget"]=true;
+dojo.provide("dojox.form._FormSelectWidget");
+dojo.require("dijit.form._FormWidget");
+dojo.declare("dojox.form._FormSelectWidget",dijit.form._FormValueWidget,{multiple:"",_multiValue:false,options:null,getOptions:function(_1){
+var _2=_1,_3=this.options||[],l=_3.length;
+if(_2===undefined){
+return _3;
+}
+if(dojo.isArray(_2)){
+return dojo.map(_2,"return this.getOptions(item);",this);
+}
+if(dojo.isObject(_1)){
+if(!dojo.some(this.options,function(o,_6){
+if(o===_2||(o.value&&o.value===_2.value)){
+_2=_6;
+return true;
+}
+return false;
+})){
+_2=-1;
+}
+}
+if(typeof _2=="string"){
+for(var i=0;i<l;i++){
+if(_3[i].value===_2){
+_2=i;
+break;
+}
+}
+}
+if(typeof _2=="number"&&_2>=0&&_2<l){
+return this.options[_2];
+}
+return null;
+},addOption:function(_8){
+if(!dojo.isArray(_8)){
+_8=[_8];
+}
+dojo.forEach(_8,function(i){
+if(i&&dojo.isObject(i)){
+this.options.push(i);
+}
+},this);
+this._loadChildren();
+},removeOption:function(_a){
+if(!dojo.isArray(_a)){
+_a=[_a];
+}
+var _b=this.getOptions(_a);
+dojo.forEach(_b,function(i){
+this.options=dojo.filter(this.options,function(_d,_e){
+return (_d.value!==i.value);
+});
+this._removeOptionItem(i);
+},this);
+this._loadChildren();
+},updateOption:function(_f){
+if(!dojo.isArray(_f)){
+_f=[_f];
+}
+dojo.forEach(_f,function(i){
+var _11=this.getOptions(i),k;
+if(_11){
+for(k in i){
+_11[k]=i[k];
+}
+}
+},this);
+this._loadChildren();
+},_setValueAttr:function(_13,_14){
+var _15=this.getOptions()||[];
+if(!dojo.isArray(_13)){
+_13=[_13];
+}
+dojo.forEach(_13,function(i,idx){
+if(!dojo.isObject(i)){
+i=i+"";
+}
+if(typeof i==="string"){
+_13[idx]=dojo.filter(_15,function(_18){
+return _18.value===i;
+})[0]||{value:"",label:""};
+}
+},this);
+_13=dojo.filter(_13,function(i){
+return i&&i.value;
+});
+if(!this._multiValue&&(!_13[0]||!_13[0].value)&&_15.length){
+_13[0]=_15[0];
+}
+dojo.forEach(_15,function(i){
+i.selected=dojo.some(_13,function(v){
+return v.value===i.value;
+});
+});
+var val=dojo.map(_13,function(i){
+return i.value;
+}),_1e=dojo.map(_13,function(i){
+return i.label;
+});
+this.value=this._multiValue?val:val[0];
+this._setDisplay(this._multiValue?_1e:_1e[0]);
+this._updateSelection();
+this._handleOnChange(this.value,_14);
+},_getDisplayedValueAttr:function(){
+var val=this.attr("value");
+if(!dojo.isArray(val)){
+val=[val];
+}
+var ret=dojo.map(this.getOptions(val),function(v){
+if(v&&"label" in v){
+return v.label;
+}else{
+if(v){
+return v.value;
+}
+}
+return null;
+},this);
+return this._multiValue?ret:ret[0];
+},_getValueDeprecated:false,getValue:function(){
+return this._lastValue;
+},undo:function(){
+this._setValueAttr(this._lastValueReported,false);
+},_loadChildren:function(){
+dojo.forEach(this._getChildren(),function(_23){
+_23.destroyRecursive();
+});
+dojo.forEach(this.options,this._addOptionItem,this);
+this._updateSelection();
+},_updateSelection:function(){
+this.value=this._getValueFromOpts();
+var val=this.value;
+if(!dojo.isArray(val)){
+val=[val];
+}
+if(val&&val[0]){
+dojo.forEach(this._getChildren(),function(_25){
+var _26=dojo.some(val,function(v){
+return _25.option&&(v===_25.option.value);
+});
+dojo.toggleClass(_25.domNode,this.baseClass+"SelectedOption",_26);
+dijit.setWaiState(_25.domNode,"selected",_26);
+},this);
+}
+this._handleOnChange(this.value);
+},_getValueFromOpts:function(){
+var _28=this.getOptions()||[];
+if(!this._multiValue&&_28.length){
+var opt=dojo.filter(_28,function(i){
+return i.selected;
+})[0];
+if(opt&&opt.value){
+return opt.value;
+}else{
+_28[0].selected=true;
+return _28[0].value;
+}
+}else{
+if(this._multiValue){
+return dojo.map(dojo.filter(_28,function(i){
+return i.selected;
+}),function(i){
+return i.value;
+})||[];
+}
+}
+return "";
+},postMixInProperties:function(){
+this._multiValue=(this.multiple.toLowerCase()==="true");
+this.inherited(arguments);
+},_fillContent:function(){
+var _2d=this.options;
+if(!_2d){
+_2d=this.options=this.srcNodeRef?dojo.query(">",this.srcNodeRef).map(function(_2e){
+if(_2e.getAttribute("type")==="separator"){
+return {value:"",label:"",selected:false,disabled:false};
+}
+return {value:_2e.getAttribute("value"),label:String(_2e.innerHTML),selected:_2e.getAttribute("selected")||false,disabled:_2e.getAttribute("disabled")||false};
+},this):[];
+}
+if(!this.value){
+this.value=this._getValueFromOpts();
+}else{
+if(this._multiValue&&typeof this.value=="string"){
+this.value=this.value.split(",");
+}
+}
+},postCreate:function(){
+dojo.setSelectable(this.focusNode,false);
+this.inherited(arguments);
+this.connect(this,"onChange","_updateSelection");
+this.connect(this,"startup","_loadChildren");
+this._setValueAttr(this.value,null);
+},_addOptionItem:function(_2f){
+},_removeOptionItem:function(_30){
+},_setDisplay:function(_31){
+},_getChildren:function(){
+return [];
+},_getSelectedOptionsAttr:function(){
+return this.getOptions(this.attr("value"));
+}});
+}
diff --git a/dojox/form/_HasDropDown.js b/dojox/form/_HasDropDown.js
new file mode 100644
index 0000000..305ae40
--- /dev/null
+++ b/dojox/form/_HasDropDown.js
@@ -0,0 +1,179 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form._HasDropDown"]){
+dojo._hasResource["dojox.form._HasDropDown"]=true;
+dojo.provide("dojox.form._HasDropDown");
+dojo.require("dijit._Widget");
+dojo.declare("dojox.form._HasDropDown",null,{dropDownNode:null,popupStateNode:null,aroundNode:null,dropDown:null,autoWidth:true,_stopClickEvents:true,_onMenuMouseup:function(e){
+},_onDropDownMouse:function(e){
+if(e.type=="click"&&!this._seenKeydown){
+return;
+}
+this._seenKeydown=false;
+if(e.type=="mousedown"){
+this._docHandler=this.connect(dojo.doc,"onmouseup","_onDropDownMouseup");
+}
+if(this.disabled||this.readOnly){
+return;
+}
+if(this._stopClickEvents){
+dojo.stopEvent(e);
+}
+this.toggleDropDown();
+if(e.type=="click"||e.type=="keypress"){
+this._onDropDownMouseup();
+}
+},_onDropDownMouseup:function(e){
+if(e&&this._docHandler){
+this.disconnect(this._docHandler);
+}
+var _4=this.dropDown,_5=false;
+if(e&&this._opened){
+var t=e.target;
+while(t&&!_5){
+if(dojo.hasClass(t,"dijitPopup")){
+_5=true;
+}else{
+t=t.parentNode;
+}
+}
+if(_5){
+this._onMenuMouseup(e);
+return;
+}
+}
+if(this._opened&&_4.focus){
+window.setTimeout(dojo.hitch(_4,"focus"),1);
+}else{
+dijit.focus(this.focusNode);
+}
+},_setupDropdown:function(){
+this.dropDownNode=this.dropDownNode||this.focusNode||this.domNode;
+this.popupStateNode=this.popupStateNode||this.focusNode||this.dropDownNode;
+this.aroundNode=this.aroundNode||this.domNode;
+this.connect(this.dropDownNode,"onmousedown","_onDropDownMouse");
+this.connect(this.dropDownNode,"onclick","_onDropDownMouse");
+this.connect(this.dropDownNode,"onkeydown","_onDropDownKeydown");
+this.connect(this.dropDownNode,"onblur","_onDropDownBlur");
+this.connect(this.dropDownNode,"onkeypress","_onKey");
+if(this._setStateClass){
+this.connect(this,"openDropDown","_setStateClass");
+this.connect(this,"closeDropDown","_setStateClass");
+}
+},postCreate:function(){
+this._setupDropdown();
+this.inherited("postCreate",arguments);
+},startup:function(){
+dijit.popup.prepare(this.dropDown.domNode);
+this.inherited("startup",arguments);
+},destroyDescendants:function(){
+if(this.dropDown){
+this.dropDown.destroyRecursive();
+delete this.dropDown;
+}
+this.inherited("destroyDescendants",arguments);
+},_onDropDownKeydown:function(e){
+this._seenKeydown=true;
+},_onKeyPress:function(e){
+if(this._opened&&e.charOrCode==dojo.keys.ESCAPE&&!e.shiftKey&&!e.ctrlKey&&!e.altKey){
+this.toggleDropDown();
+dojo.stopEvent(e);
+return;
+}
+this.inherited(arguments);
+},_onDropDownBlur:function(e){
+this._seenKeydown=false;
+},_onKey:function(e){
+if(this.disabled||this.readOnly){
+return;
+}
+var d=this.dropDown;
+if(d&&this._opened&&d.handleKey){
+if(d.handleKey(e)===false){
+return;
+}
+}
+if(d&&this._opened&&e.keyCode==dojo.keys.ESCAPE){
+this.toggleDropDown();
+return;
+}
+if(e.keyCode==dojo.keys.DOWN_ARROW){
+this._onDropDownMouse(e);
+}
+},_onBlur:function(){
+this.closeDropDown();
+this.inherited("_onBlur",arguments);
+},isLoaded:function(){
+return true;
+},loadDropDown:function(_c){
+_c();
+},toggleDropDown:function(){
+if(this.disabled||this.readOnly){
+return;
+}
+this.focus();
+var _d=this.dropDown;
+if(!_d){
+return;
+}
+if(!this._opened){
+if(!this.isLoaded()){
+this.loadDropDown(dojo.hitch(this,"openDropDown"));
+return;
+}else{
+this.openDropDown();
+}
+}else{
+this.closeDropDown();
+}
+},openDropDown:function(){
+var _e=this.dropDown;
+var _f=_e.domNode.style.width;
+var _10=this;
+var _11=dijit.popup.open({parent:this,popup:_e,around:this.aroundNode,orient:this.isLeftToRight()?{"BL":"TL","BR":"TR","TL":"BL","TR":"BR"}:{"BR":"TR","BL":"TL","TR":"BR","TL":"BL"},onExecute:function(){
+_10.closeDropDown(true);
+},onCancel:function(){
+_10.closeDropDown(true);
+},onClose:function(){
+_e.domNode.style.width=_f;
+dojo.attr(_10.popupStateNode,"popupActive",false);
+dojo.removeClass(_10.popupStateNode,"dojoxHasDropDownOpen");
+_10._opened=false;
+_10.state="";
+}});
+if(this.autoWidth&&this.domNode.offsetWidth>_e.domNode.offsetWidth){
+var _12=null;
+if(!this.isLeftToRight()){
+_12=_e.domNode.parentNode;
+var _13=_12.offsetLeft+_12.offsetWidth;
+}
+if(_e.resize){
+_e.resize({w:this.domNode.offsetWidth});
+}else{
+dojo.marginBox(_e.domNode,{w:this.domNode.offsetWidth});
+}
+if(_12){
+_12.style.left=_13-this.domNode.offsetWidth+"px";
+}
+}
+dojo.attr(this.popupStateNode,"popupActive","true");
+dojo.addClass(_10.popupStateNode,"dojoxHasDropDownOpen");
+this._opened=true;
+this.state="Opened";
+return _11;
+},closeDropDown:function(_14){
+if(this._opened){
+dijit.popup.close(this.dropDown);
+if(_14){
+this.focus();
+}
+this._opened=false;
+this.state="";
+}
+}});
+}
diff --git a/dojox/form/_SelectStackMixin.js b/dojox/form/_SelectStackMixin.js
new file mode 100644
index 0000000..513e4c9
--- /dev/null
+++ b/dojox/form/_SelectStackMixin.js
@@ -0,0 +1,108 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form._SelectStackMixin"]){
+dojo._hasResource["dojox.form._SelectStackMixin"]=true;
+dojo.provide("dojox.form._SelectStackMixin");
+dojo.declare("dojox.form._SelectStackMixin",null,{stackId:"",stackPrefix:"",_paneIdFromOption:function(_1){
+return (this.stackPrefix||"")+_1;
+},_optionValFromPane:function(id){
+var sp=this.stackPrefix;
+if(sp&&id.indexOf(sp)===0){
+return id.substring(sp.length);
+}
+return id;
+},_togglePane:function(_4,_5){
+if(_4._shown!=undefined&&_4._shown==_5){
+return;
+}
+var _6=dojo.filter(_4.getDescendants(),"return item.name;");
+if(!_5){
+_7={};
+dojo.forEach(_6,function(w){
+_7[w.id]=w.disabled;
+w.attr("disabled",true);
+});
+_4._savedStates=_7;
+}else{
+var _7=_4._savedStates||{};
+dojo.forEach(_6,function(w){
+var _a=_7[w.id];
+if(_a==undefined){
+_a=false;
+}
+w.attr("disabled",_a);
+});
+delete _4._savedStates;
+}
+_4._shown=_5;
+},onAddChild:function(_b,_c){
+if(!this._panes[_b.id]){
+this._panes[_b.id]=_b;
+this.addOption({value:this._optionValFromPane(_b.id),label:_b.title});
+}
+if(!_b.onShow||!_b.onHide||_b._shown==undefined){
+_b.onShow=dojo.hitch(this,"_togglePane",_b,true);
+_b.onHide=dojo.hitch(this,"_togglePane",_b,false);
+_b.onHide();
+}
+},onRemoveChild:function(_d){
+if(this._panes[_d.id]){
+delete this._panes[_d.id];
+this.removeOption(this._optionValFromPane(_d.id));
+}
+},onSelectChild:function(_e){
+this._setValueAttr(this._optionValFromPane(_e.id));
+},onStartup:function(_f){
+var _10=_f.selected;
+this.addOption(dojo.filter(dojo.map(_f.children,function(c){
+var v=this._optionValFromPane(c.id);
+var _13=null;
+if(!this._panes[c.id]){
+this._panes[c.id]=c;
+_13={value:v,label:c.title};
+}
+if(!c.onShow||!c.onHide||c._shown==undefined){
+c.onShow=dojo.hitch(this,"_togglePane",c,true);
+c.onHide=dojo.hitch(this,"_togglePane",c,false);
+c.onHide();
+}
+if(this._savedValue&&v){
+_10=c;
+}
+return _13;
+},this),function(i){
+return i;
+}));
+delete this._savedValue;
+this.onSelectChild(_10);
+if(!_10._shown){
+this._togglePane(_10,true);
+}
+},postMixInProperties:function(){
+this._savedValue=this.value;
+this.inherited(arguments);
+this.connect(this,"onChange","_handleSelfOnChange");
+},postCreate:function(){
+this.inherited(arguments);
+this._panes={};
+this._subscriptions=[dojo.subscribe(this.stackId+"-startup",this,"onStartup"),dojo.subscribe(this.stackId+"-addChild",this,"onAddChild"),dojo.subscribe(this.stackId+"-removeChild",this,"onRemoveChild"),dojo.subscribe(this.stackId+"-selectChild",this,"onSelectChild")];
+var _15=dijit.byId(this.stackId);
+if(_15&&_15._started){
+this.onStartup({children:_15.getChildren(),selected:_15.selectedChildWidget});
+}
+},destroy:function(){
+dojo.forEach(this._subscriptions,dojo.unsubscribe);
+delete this._panes;
+this.inherited("destroy",arguments);
+},_handleSelfOnChange:function(val){
+var _17=this._panes[this._paneIdFromOption(val)];
+if(_17){
+dijit.byId(this.stackId).selectChild(_17);
+}
+}});
+}
diff --git a/dojox/form/manager/_ClassMixin.js b/dojox/form/manager/_ClassMixin.js
new file mode 100644
index 0000000..6ea5258
--- /dev/null
+++ b/dojox/form/manager/_ClassMixin.js
@@ -0,0 +1,31 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.manager._ClassMixin"]){
+dojo._hasResource["dojox.form.manager._ClassMixin"]=true;
+dojo.provide("dojox.form.manager._ClassMixin");
+dojo.require("dojox.form.manager._Mixin");
+(function(){
+var fm=dojox.form.manager,aa=fm.actionAdapter,ia=fm.inspectorAdapter;
+dojo.declare("dojox.form.manager._ClassMixin",null,{gatherClassState:function(_4,_5){
+var _6=this.inspect(ia(function(_7,_8){
+return dojo.hasClass(_8,_4);
+}),_5);
+return _6;
+},addClass:function(_9,_a){
+this.inspect(aa(function(_b,_c){
+dojo.addClass(_c,_9);
+}),_a);
+return this;
+},removeClass:function(_d,_e){
+this.inspect(aa(function(_f,_10){
+dojo.removeClass(_10,_d);
+}),_e);
+return this;
+}});
+})();
+}
diff --git a/dojox/form/manager/_DisplayMixin.js b/dojox/form/manager/_DisplayMixin.js
new file mode 100644
index 0000000..326abc7
--- /dev/null
+++ b/dojox/form/manager/_DisplayMixin.js
@@ -0,0 +1,27 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.manager._DisplayMixin"]){
+dojo._hasResource["dojox.form.manager._DisplayMixin"]=true;
+dojo.provide("dojox.form.manager._DisplayMixin");
+dojo.declare("dojox.form.manager._DisplayMixin",null,{gatherDisplayState:function(_1){
+var _2=this.inspectAttachedPoints(function(_3,_4){
+return dojo.style(_4,"display")!="none";
+},_1);
+return _2;
+},show:function(_5,_6){
+if(arguments.length<2){
+_6=true;
+}
+this.inspectAttachedPoints(function(_7,_8,_9){
+dojo.style(_8,"display",_9?"":"none");
+},_5,_6);
+return this;
+},hide:function(_a){
+return this.show(_a,false);
+}});
+}
diff --git a/dojox/form/manager/_EnableMixin.js b/dojox/form/manager/_EnableMixin.js
new file mode 100644
index 0000000..5a699d8
--- /dev/null
+++ b/dojox/form/manager/_EnableMixin.js
@@ -0,0 +1,43 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.manager._EnableMixin"]){
+dojo._hasResource["dojox.form.manager._EnableMixin"]=true;
+dojo.provide("dojox.form.manager._EnableMixin");
+dojo.require("dojox.form.manager._Mixin");
+(function(){
+var fm=dojox.form.manager,aa=fm.actionAdapter,ia=fm.inspectorAdapter;
+dojo.declare("dojox.form.manager._EnableMixin",null,{gatherEnableState:function(_4){
+var _5=this.inspectFormWidgets(ia(function(_6,_7){
+return !_7.attr("disabled");
+}),_4);
+if(this.inspectFormNodes){
+dojo.mixin(_5,this.inspectFormNodes(ia(function(_8,_9){
+return !dojo.attr(_9,"disabled");
+}),_4));
+}
+return _5;
+},enable:function(_a,_b){
+if(arguments.length<2||_b===undefined){
+_b=true;
+}
+this.inspectFormWidgets(aa(function(_c,_d,_e){
+_d.attr("disabled",!_e);
+}),_a,_b);
+if(this.inspectFormNodes){
+this.inspectFormNodes(aa(function(_f,_10,_11){
+dojo.attr(_10,"disabled",!_11);
+}),_a,_b);
+}
+return this;
+},disable:function(_12){
+var _13=this.gatherEnableState();
+this.enable(_12,false);
+return _13;
+}});
+})();
+}
diff --git a/dojox/form/manager/_FormMixin.js b/dojox/form/manager/_FormMixin.js
new file mode 100644
index 0000000..601680f
--- /dev/null
+++ b/dojox/form/manager/_FormMixin.js
@@ -0,0 +1,70 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.manager._FormMixin"]){
+dojo._hasResource["dojox.form.manager._FormMixin"]=true;
+dojo.provide("dojox.form.manager._FormMixin");
+dojo.require("dojox.form.manager._Mixin");
+(function(){
+var fm=dojox.form.manager,aa=fm.actionAdapter;
+dojo.declare("dojox.form.manager._FormMixin",null,{name:"",action:"",method:"",encType:"","accept-charset":"",accept:"",target:"",startup:function(){
+this.isForm=this.domNode.tagName.toLowerCase()=="form";
+if(this.isForm){
+this.connect(this.domNode,"onreset","_onReset");
+this.connect(this.domNode,"onsubmit","_onSubmit");
+}
+this.inherited(arguments);
+},_onReset:function(_3){
+var _4={returnValue:true,preventDefault:function(){
+this.returnValue=false;
+},stopPropagation:function(){
+},currentTarget:_3.currentTarget,target:_3.target};
+if(!(this.onReset(_4)===false)&&_4.returnValue){
+this.reset();
+}
+dojo.stopEvent(_3);
+return false;
+},onReset:function(){
+return true;
+},reset:function(){
+this.inspectFormWidgets(aa(function(_,_6){
+if(_6.reset){
+_6.reset();
+}
+}));
+if(this.isForm){
+this.domNode.reset();
+}
+return this;
+},_onSubmit:function(_7){
+if(this.onSubmit(_7)===false){
+dojo.stopEvent(_7);
+}
+},onSubmit:function(){
+return this.isValid();
+},submit:function(){
+if(this.isForm){
+if(!(this.onSubmit()===false)){
+this.domNode.submit();
+}
+}
+},isValid:function(){
+for(var _8 in this.formWidgets){
+var _9=false;
+aa(function(_,_b){
+if(!_b.attr("disabled")&&_b.isValid&&!_b.isValid()){
+_9=true;
+}
+}).call(this,null,this.formWidgets[_8].widget);
+if(_9){
+return false;
+}
+}
+return true;
+}});
+})();
+}
diff --git a/dojox/form/manager/_Mixin.js b/dojox/form/manager/_Mixin.js
new file mode 100644
index 0000000..392f5b6
--- /dev/null
+++ b/dojox/form/manager/_Mixin.js
@@ -0,0 +1,274 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.manager._Mixin"]){
+dojo._hasResource["dojox.form.manager._Mixin"]=true;
+dojo.provide("dojox.form.manager._Mixin");
+dojo.require("dijit._Widget");
+(function(){
+var fm=dojox.form.manager,aa=fm.actionAdapter=function(_3){
+return function(_4,_5,_6){
+if(dojo.isArray(_5)){
+dojo.forEach(_5,function(_7){
+_3.call(this,_4,_7,_6);
+},this);
+}else{
+_3.apply(this,arguments);
+}
+};
+},ia=fm.inspectorAdapter=function(_9){
+return function(_a,_b,_c){
+return _9.call(this,_a,dojo.isArray(_b)?_b[0]:_b,_c);
+};
+},_d={domNode:1,containerNode:1,srcNodeRef:1,bgIframe:1},_e=fm._keys=function(o){
+var _10=[],key;
+for(key in o){
+if(o.hasOwnProperty(key)){
+_10.push(key);
+}
+}
+return _10;
+},_12=function(_13){
+var _14=_13.attr("name");
+if(_14&&_13 instanceof dijit.form._FormWidget){
+if(_14 in this.formWidgets){
+var a=this.formWidgets[_14].widget;
+if(dojo.isArray(a)){
+a.push(_13);
+}else{
+this.formWidgets[_14].widget=[a,_13];
+}
+}else{
+this.formWidgets[_14]={widget:_13,connections:[]};
+}
+}else{
+_14=null;
+}
+return _14;
+},_16=function(_17){
+var _18={};
+aa(function(_,w){
+var o=w.attr("observer");
+if(o&&typeof o=="string"){
+dojo.forEach(o.split(","),function(o){
+o=dojo.trim(o);
+if(o&&dojo.isFunction(this[o])){
+_18[o]=1;
+}
+},this);
+}
+}).call(this,null,this.formWidgets[_17].widget);
+return _e(_18);
+},_1d=function(_1e,_1f){
+var t=this.formWidgets[_1e],w=t.widget,c=t.connections;
+if(c.length){
+dojo.forEach(c,dojo.disconnect);
+c=t.connections=[];
+}
+if(dojo.isArray(w)){
+dojo.forEach(w,function(w){
+dojo.forEach(_1f,function(o){
+c.push(dojo.connect(w,"onChange",this,function(evt){
+if(this.watch&&dojo.attr(w.focusNode,"checked")){
+this[o](w.attr("value"),_1e,w,evt);
+}
+}));
+},this);
+},this);
+}else{
+var _26=w.declaredClass=="dijit.form.Button"?"onClick":"onChange";
+dojo.forEach(_1f,function(o){
+c.push(dojo.connect(w,_26,this,function(evt){
+if(this.watch){
+this[o](w.attr("value"),_1e,w,evt);
+}
+}));
+},this);
+}
+};
+dojo.declare("dojox.form.manager._Mixin",null,{watch:true,startup:function(){
+if(this._started){
+return;
+}
+this.formWidgets={};
+this.formNodes={};
+this.registerWidgetDescendants(this);
+this.inherited(arguments);
+},destroy:function(){
+for(var _29 in this.formWidgets){
+dojo.forEach(this.formWidgets[_29].connections,dojo.disconnect);
+}
+this.formWidgets={};
+this.inherited(arguments);
+},registerWidget:function(_2a){
+if(typeof _2a=="string"){
+_2a=dijit.byId(_2a);
+}else{
+if(_2a.tagName&&_2a.cloneNode){
+_2a=dijit.byNode(_2a);
+}
+}
+var _2b=_12.call(this,_2a);
+if(_2b){
+_1d.call(this,_2b,_16.call(this,_2b));
+}
+return this;
+},unregisterWidget:function(_2c){
+if(_2c in this.formWidgets){
+dojo.forEach(this.formWidgets[_2c].connections,this.disconnect,this);
+delete this.formWidgets[_2c];
+}
+return this;
+},registerWidgetDescendants:function(_2d){
+if(typeof _2d=="string"){
+_2d=dijit.byId(_2d);
+}else{
+if(_2d.tagName&&_2d.cloneNode){
+_2d=dijit.byNode(_2d);
+}
+}
+var _2e=dojo.map(_2d.getDescendants(),_12,this);
+dojo.forEach(_2e,function(_2f){
+if(_2f){
+_1d.call(this,_2f,_16.call(this,_2f));
+}
+},this);
+return this.registerNodeDescendants?this.registerNodeDescendants(_2d.domNode):this;
+},unregisterWidgetDescendants:function(_30){
+if(typeof _30=="string"){
+_30=dijit.byId(_30);
+}else{
+if(_30.tagName&&_30.cloneNode){
+_30=dijit.byNode(_30);
+}
+}
+dojo.forEach(dojo.map(_30.getDescendants(),function(w){
+return w instanceof dijit.form._FormWidget&&w.attr("name")||null;
+}),function(_32){
+if(_32){
+this.unregisterNode(_32);
+}
+},this);
+return this.unregisterNodeDescendants?this.unregisterNodeDescendants(_30.domNode):this;
+},formWidgetValue:function(_33,_34){
+var _35=arguments.length==2&&_34!==undefined,_36;
+if(typeof _33=="string"){
+_33=this.formWidgets[_33];
+if(_33){
+_33=_33.widget;
+}
+}
+if(!_33){
+return null;
+}
+if(dojo.isArray(_33)){
+if(_35){
+dojo.forEach(_33,function(_37){
+_37.attr("checked",false);
+});
+dojo.forEach(_33,function(_38){
+_38.attr("checked",_38.attr("value")===_34);
+});
+return this;
+}
+dojo.some(_33,function(_39){
+if(dojo.attr(_39.focusNode,"checked")){
+_36=_39;
+return true;
+}
+return false;
+});
+return _36?_36.attr("value"):"";
+}
+if(_35){
+_33.attr("value",_34);
+return this;
+}
+return _33.attr("value");
+},formPointValue:function(_3a,_3b){
+if(_3a&&typeof _3a=="string"){
+_3a=this[_3a];
+}
+if(!_3a||!_3a.tagName||!_3a.cloneNode){
+return null;
+}
+if(!dojo.hasClass(_3a,"dojoFormValue")){
+return null;
+}
+if(arguments.length==2&&_3b!==undefined){
+_3a.innerHTML=_3b;
+return this;
+}
+return _3a.innerHTML;
+},inspectFormWidgets:function(_3c,_3d,_3e){
+var _3f,_40={};
+if(_3d){
+if(dojo.isArray(_3d)){
+dojo.forEach(_3d,function(_41){
+if(_41 in this.formWidgets){
+_40[_41]=_3c.call(this,_41,this.formWidgets[_41].widget,_3e);
+}
+},this);
+}else{
+for(_3f in _3d){
+if(_3f in this.formWidgets){
+_40[_3f]=_3c.call(this,_3f,this.formWidgets[_3f].widget,_3d[_3f]);
+}
+}
+}
+}else{
+for(_3f in this.formWidgets){
+_40[_3f]=_3c.call(this,_3f,this.formWidgets[_3f].widget,_3e);
+}
+}
+return _40;
+},inspectAttachedPoints:function(_42,_43,_44){
+var _45,_46={};
+if(_43){
+if(dojo.isArray(_43)){
+dojo.forEach(_43,function(_47){
+var _48=this[_47];
+if(_48&&_48.tagName&&_48.cloneNode){
+_46[_47]=_42.call(this,_47,_48,_44);
+}
+},this);
+}else{
+for(_45 in _43){
+var _49=this[_45];
+if(_49&&_49.tagName&&_49.cloneNode){
+_46[_45]=_42.call(this,_45,_49,_43[_45]);
+}
+}
+}
+}else{
+for(_45 in this){
+if(!(_45 in _d)){
+var _49=this[_45];
+if(_49&&_49.tagName&&_49.cloneNode){
+_46[_45]=_42.call(this,_45,_49,_44);
+}
+}
+}
+}
+return _46;
+},inspect:function(_4a,_4b,_4c){
+var _4d=this.inspectFormWidgets(function(_4e,_4f,_50){
+if(dojo.isArray(_4f)){
+return _4a.call(this,_4e,dojo.map(_4f,function(w){
+return w.domNode;
+}),_50);
+}
+return _4a.call(this,_4e,_4f.domNode,_50);
+},_4b,_4c);
+if(this.inspectFormNodes){
+dojo.mixin(_4d,this.inspectFormNodes(_4a,_4b,_4c));
+}
+return dojo.mixin(_4d,this.inspectAttachedPoints(_4a,_4b,_4c));
+}});
+})();
+dojo.extend(dijit._Widget,{observer:""});
+}
diff --git a/dojox/form/manager/_NodeMixin.js b/dojox/form/manager/_NodeMixin.js
new file mode 100644
index 0000000..85530f9
--- /dev/null
+++ b/dojox/form/manager/_NodeMixin.js
@@ -0,0 +1,239 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.manager._NodeMixin"]){
+dojo._hasResource["dojox.form.manager._NodeMixin"]=true;
+dojo.provide("dojox.form.manager._NodeMixin");
+dojo.require("dojox.form.manager._Mixin");
+(function(){
+var fm=dojox.form.manager,aa=fm.actionAdapter,_3=fm._keys,ce=fm.changeEvent=function(_5){
+var _6="onclick";
+switch(_5.tagName.toLowerCase()){
+case "textarea":
+_6="onkeyup";
+break;
+case "select":
+_6="onchange";
+break;
+case "input":
+switch(_5.type.toLowerCase()){
+case "text":
+case "password":
+_6="onkeyup";
+break;
+}
+break;
+}
+return _6;
+},_7=function(_8,_9){
+var _a=dojo.attr(_8,"name");
+_9=_9||this.domNode;
+if(_a&&!(_a in this.formWidgets)){
+for(var n=_8;n&&n!==_9;n=n.parentNode){
+if(dojo.attr(n,"widgetId")&&dijit.byNode(n) instanceof dijit.form._FormWidget){
+return null;
+}
+}
+if(_8.tagName.toLowerCase()=="input"&&_8.type.toLowerCase()=="radio"){
+var a=this.formNodes[_a];
+a=a&&a.node;
+if(a&&dojo.isArray(a)){
+a.push(_8);
+}else{
+this.formNodes[_a]={node:[_8],connections:[]};
+}
+}else{
+this.formNodes[_a]={node:_8,connections:[]};
+}
+}else{
+_a=null;
+}
+return _a;
+},_d=function(_e){
+var _f={};
+aa(function(_,n){
+var o=dojo.attr(n,"observer");
+if(o&&typeof o=="string"){
+dojo.forEach(o.split(","),function(o){
+o=dojo.trim(o);
+if(o&&dojo.isFunction(this[o])){
+_f[o]=1;
+}
+},this);
+}
+}).call(this,null,this.formNodes[_e].node);
+return _3(_f);
+},_14=function(_15,_16){
+var t=this.formNodes[_15],c=t.connections;
+if(c.length){
+dojo.forEach(c,dojo.disconnect);
+c=t.connections=[];
+}
+aa(function(_,n){
+var _1b=ce(n);
+dojo.forEach(_16,function(o){
+c.push(dojo.connect(n,_1b,this,function(evt){
+if(this.watch){
+this[o](this.formNodeValue(_15),_15,n,evt);
+}
+}));
+},this);
+}).call(this,null,t.node);
+};
+dojo.declare("dojox.form.manager._NodeMixin",null,{destroy:function(){
+for(var _1e in this.formNodes){
+dojo.forEach(this.formNodes[_1e].connections,dojo.disconnect);
+}
+this.formNodes={};
+this.inherited(arguments);
+},registerNode:function(_1f){
+if(typeof _1f=="string"){
+_1f=dojo.byId(_1f);
+}
+var _20=_7.call(this,_1f);
+if(_20){
+_14.call(this,_20,_d.call(this,_20));
+}
+return this;
+},unregisterNode:function(_21){
+if(_21 in this.formNodes){
+dojo.forEach(this.formNodes[_21].connections,this.disconnect,this);
+delete this.formNodes[_21];
+}
+return this;
+},registerNodeDescendants:function(_22){
+if(typeof _22=="string"){
+_22=dojo.byId(_22);
+}
+dojo.query("input, select, textarea, button",_22).map(function(n){
+return _7.call(this,n,_22);
+},this).forEach(function(_24){
+if(_24){
+_14.call(this,_24,_d.call(this,_24));
+}
+},this);
+return this;
+},unregisterNodeDescendants:function(_25){
+if(typeof _25=="string"){
+_25=dojo.byId(_25);
+}
+dojo.query("input, select, textarea, button",_25).map(function(n){
+return dojo.attr(_25,"name")||null;
+}).forEach(function(_27){
+if(_27){
+this.unregisterNode(_27);
+}
+},this);
+return this;
+},formNodeValue:function(_28,_29){
+var _2a=arguments.length==2&&_29!==undefined,_2b;
+if(typeof _28=="string"){
+_28=this.formNodes[_28];
+if(_28){
+_28=_28.node;
+}
+}
+if(!_28){
+return null;
+}
+if(dojo.isArray(_28)){
+if(_2a){
+dojo.forEach(_28,function(_2c){
+_2c.checked="";
+});
+dojo.forEach(_28,function(_2d){
+_2d.checked=_2d.value===_29?"checked":"";
+});
+return this;
+}
+dojo.some(_28,function(_2e){
+if(_2e.checked){
+_2b=_2e;
+return true;
+}
+return false;
+});
+return _2b?_2b.value:"";
+}
+switch(_28.tagName.toLowerCase()){
+case "select":
+if(_28.multiple){
+if(_2a){
+if(dojo.isArray(_29)){
+var _2f={};
+dojo.forEach(_29,function(v){
+_2f[v]=1;
+});
+dojo.query("> option",_28).forEach(function(opt){
+opt.selected=opt.value in _2f;
+});
+return this;
+}
+dojo.query("> option",_28).forEach(function(opt){
+opt.selected=opt.value===_29;
+});
+return this;
+}
+var _2b=dojo.query("> option",_28).filter(function(opt){
+return opt.selected;
+}).map(function(opt){
+return opt.value;
+});
+return _2b.length==1?_2b[0]:_2b;
+}
+if(_2a){
+dojo.query("> option",_28).forEach(function(opt){
+opt.selected=opt.value===_29;
+});
+return this;
+}
+return _28.value||"";
+case "button":
+if(_2a){
+_28.innerHTML=""+_29;
+return this;
+}
+return _28.innerHTML;
+case "input":
+if(_28.type.toLowerCase()=="checkbox"){
+if(_2a){
+_28.checked=_29?"checked":"";
+return this;
+}
+return Boolean(_28.checked);
+}
+}
+if(_2a){
+_28.value=""+_29;
+return this;
+}
+return _28.value;
+},inspectFormNodes:function(_36,_37,_38){
+var _39,_3a={};
+if(_37){
+if(dojo.isArray(_37)){
+dojo.forEach(_37,function(_3b){
+if(_3b in this.formNodes){
+_3a[_3b]=_36.call(this,_3b,this.formNodes[_3b].node,_38);
+}
+},this);
+}else{
+for(_39 in _37){
+if(_39 in this.formNodes){
+_3a[_39]=_36.call(this,_39,this.formNodes[_39].node,_37[_39]);
+}
+}
+}
+}else{
+for(_39 in this.formNodes){
+_3a[_39]=_36.call(this,_39,this.formNodes[_39].node,_38);
+}
+}
+return _3a;
+}});
+})();
+}
diff --git a/dojox/form/manager/_ValueMixin.js b/dojox/form/manager/_ValueMixin.js
new file mode 100644
index 0000000..013ac11
--- /dev/null
+++ b/dojox/form/manager/_ValueMixin.js
@@ -0,0 +1,48 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.form.manager._ValueMixin"]){
+dojo._hasResource["dojox.form.manager._ValueMixin"]=true;
+dojo.provide("dojox.form.manager._ValueMixin");
+dojo.declare("dojox.form.manager._ValueMixin",null,{elementValue:function(_1,_2){
+if(_1 in this.formWidgets){
+return this.formWidgetValue(_1,_2);
+}
+if(this.formNodes&&_1 in this.formNodes){
+return this.formNodeValue(_1,_2);
+}
+return this.formPointValue(_1,_2);
+},gatherFormValues:function(_3){
+var _4=this.inspectFormWidgets(function(_5){
+return this.formWidgetValue(_5);
+},_3);
+if(this.inspectFormNodes){
+dojo.mixin(_4,this.inspectFormNodes(function(_6){
+return this.formNodeValue(_6);
+},_3));
+}
+dojo.mixin(_4,this.inspectAttachedPoints(function(_7){
+return this.formPointValue(_7);
+},_3));
+return _4;
+},setFormValues:function(_8){
+if(_8){
+this.inspectFormWidgets(function(_9,_a,_b){
+this.formWidgetValue(_9,_b);
+},_8);
+if(this.inspectFormNodes){
+this.inspectFormNodes(function(_c,_d,_e){
+this.formNodeValue(_c,_e);
+},_8);
+}
+this.inspectAttachedPoints(function(_f,_10,_11){
+this.formPointValue(_f,_11);
+},_8);
+}
+return this;
+}});
+}
diff --git a/dojox/form/nls/PasswordValidator.js b/dojox/form/nls/PasswordValidator.js
new file mode 100644
index 0000000..4887d27
--- /dev/null
+++ b/dojox/form/nls/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Invalid Password.","nomatchMessage":"Passwords do not match."})
\ No newline at end of file
diff --git a/dojox/form/nls/ar/PasswordValidator.js b/dojox/form/nls/ar/PasswordValidator.js
new file mode 100644
index 0000000..7ab0a3c
--- /dev/null
+++ b/dojox/form/nls/ar/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"كلمة سرية غير صحيحة. ","nomatchMessage":"كلمات السرية غير مطابقة."})
\ No newline at end of file
diff --git a/dojox/form/nls/ca/PasswordValidator.js b/dojox/form/nls/ca/PasswordValidator.js
new file mode 100644
index 0000000..8b9ce17
--- /dev/null
+++ b/dojox/form/nls/ca/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"La contrasenya no és correcta","nomatchMessage":"Les contrasenyes no coincideixen"})
\ No newline at end of file
diff --git a/dojox/form/nls/cs/PasswordValidator.js b/dojox/form/nls/cs/PasswordValidator.js
new file mode 100644
index 0000000..0659853
--- /dev/null
+++ b/dojox/form/nls/cs/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Neplatné heslo.","nomatchMessage":"Hesla se neshodují."})
\ No newline at end of file
diff --git a/dojox/form/nls/da/PasswordValidator.js b/dojox/form/nls/da/PasswordValidator.js
new file mode 100644
index 0000000..3321341
--- /dev/null
+++ b/dojox/form/nls/da/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Ugyldig adgangskode.","nomatchMessage":"Adgangskoderne stemmer ikke overens."})
\ No newline at end of file
diff --git a/dojox/form/nls/de/PasswordValidator.js b/dojox/form/nls/de/PasswordValidator.js
new file mode 100644
index 0000000..201893b
--- /dev/null
+++ b/dojox/form/nls/de/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Ungültiges Kennwort.","nomatchMessage":"Die Kennwörter stimmen nicht überein."})
\ No newline at end of file
diff --git a/dojox/form/nls/el/PasswordValidator.js b/dojox/form/nls/el/PasswordValidator.js
new file mode 100644
index 0000000..ab8b9be
--- /dev/null
+++ b/dojox/form/nls/el/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Μη έγκυρος κωδικός πρόσβασης.","nomatchMessage":"Οι κωδικοί πρόσβασης δεν συμφωνούν."})
\ No newline at end of file
diff --git a/dojox/form/nls/es/PasswordValidator.js b/dojox/form/nls/es/PasswordValidator.js
new file mode 100644
index 0000000..131ecda
--- /dev/null
+++ b/dojox/form/nls/es/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Contraseña no válida.","nomatchMessage":"Las contraseñas no coinciden."})
\ No newline at end of file
diff --git a/dojox/form/nls/fi/PasswordValidator.js b/dojox/form/nls/fi/PasswordValidator.js
new file mode 100644
index 0000000..291e49c
--- /dev/null
+++ b/dojox/form/nls/fi/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Salasana ei kelpaa.","nomatchMessage":"Salasanat eivät täsmää."})
\ No newline at end of file
diff --git a/dojox/form/nls/fr/PasswordValidator.js b/dojox/form/nls/fr/PasswordValidator.js
new file mode 100644
index 0000000..590cbce
--- /dev/null
+++ b/dojox/form/nls/fr/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Mot de passe incorrect.","nomatchMessage":"Les mots de passe ne correspondent pas."})
\ No newline at end of file
diff --git a/dojox/form/nls/he/PasswordValidator.js b/dojox/form/nls/he/PasswordValidator.js
new file mode 100644
index 0000000..4995881
--- /dev/null
+++ b/dojox/form/nls/he/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"סיסמה לא חוקית.","nomatchMessage":"הסיסמאות אינן זהות."})
\ No newline at end of file
diff --git a/dojox/form/nls/hu/PasswordValidator.js b/dojox/form/nls/hu/PasswordValidator.js
new file mode 100644
index 0000000..1202b56
--- /dev/null
+++ b/dojox/form/nls/hu/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Érvénytelen jelszó.","nomatchMessage":"A jelszavak nem egyeznek."})
\ No newline at end of file
diff --git a/dojox/form/nls/it/PasswordValidator.js b/dojox/form/nls/it/PasswordValidator.js
new file mode 100644
index 0000000..af224e4
--- /dev/null
+++ b/dojox/form/nls/it/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Password non valida.","nomatchMessage":"Le password non corrispondono."})
\ No newline at end of file
diff --git a/dojox/form/nls/ja/PasswordValidator.js b/dojox/form/nls/ja/PasswordValidator.js
new file mode 100644
index 0000000..ac73c4b
--- /dev/null
+++ b/dojox/form/nls/ja/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"無効なパスワードです。","nomatchMessage":"パスワードが一致しません。"})
\ No newline at end of file
diff --git a/dojox/form/nls/ko/PasswordValidator.js b/dojox/form/nls/ko/PasswordValidator.js
new file mode 100644
index 0000000..48ebc29
--- /dev/null
+++ b/dojox/form/nls/ko/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"올바르지 않은 비밀번호","nomatchMessage":"비밀번호가 일치하지 않습니다."})
\ No newline at end of file
diff --git a/dojox/form/nls/nb/PasswordValidator.js b/dojox/form/nls/nb/PasswordValidator.js
new file mode 100644
index 0000000..79ebab1
--- /dev/null
+++ b/dojox/form/nls/nb/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Ugyldig passord.","nomatchMessage":"Passordene samsvarer ikke."})
\ No newline at end of file
diff --git a/dojox/form/nls/nl/PasswordValidator.js b/dojox/form/nls/nl/PasswordValidator.js
new file mode 100644
index 0000000..27df062
--- /dev/null
+++ b/dojox/form/nls/nl/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Ongeldig wachtwoord. ","nomatchMessage":"Wachtwoorden komen niet overeen."})
\ No newline at end of file
diff --git a/dojox/form/nls/pl/PasswordValidator.js b/dojox/form/nls/pl/PasswordValidator.js
new file mode 100644
index 0000000..d646c5d
--- /dev/null
+++ b/dojox/form/nls/pl/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Niepoprawne hasło.","nomatchMessage":"Hasła nie są zgodne."})
\ No newline at end of file
diff --git a/dojox/form/nls/pt-pt/PasswordValidator.js b/dojox/form/nls/pt-pt/PasswordValidator.js
new file mode 100644
index 0000000..4350e30
--- /dev/null
+++ b/dojox/form/nls/pt-pt/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Palavra-passe não válida.","nomatchMessage":"As palavras-passe não correspondem."})
\ No newline at end of file
diff --git a/dojox/form/nls/pt/PasswordValidator.js b/dojox/form/nls/pt/PasswordValidator.js
new file mode 100644
index 0000000..e2184d6
--- /dev/null
+++ b/dojox/form/nls/pt/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Senha Inválida.","nomatchMessage":"As senhas não correspondem."})
\ No newline at end of file
diff --git a/dojox/form/nls/ru/PasswordValidator.js b/dojox/form/nls/ru/PasswordValidator.js
new file mode 100644
index 0000000..8cf8df5
--- /dev/null
+++ b/dojox/form/nls/ru/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Неправильный пароль.","nomatchMessage":"Пароли не совпадают."})
\ No newline at end of file
diff --git a/dojox/form/nls/sk/PasswordValidator.js b/dojox/form/nls/sk/PasswordValidator.js
new file mode 100644
index 0000000..a4880b3
--- /dev/null
+++ b/dojox/form/nls/sk/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Neplatné heslo.","nomatchMessage":"Heslá sa nezhodujú."})
\ No newline at end of file
diff --git a/dojox/form/nls/sl/PasswordValidator.js b/dojox/form/nls/sl/PasswordValidator.js
new file mode 100644
index 0000000..4d8faba
--- /dev/null
+++ b/dojox/form/nls/sl/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Neveljavno geslo.","nomatchMessage":"Gesli se ne ujemata."})
\ No newline at end of file
diff --git a/dojox/form/nls/sv/PasswordValidator.js b/dojox/form/nls/sv/PasswordValidator.js
new file mode 100644
index 0000000..1c3abd0
--- /dev/null
+++ b/dojox/form/nls/sv/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Ogiltigt lösenord.","nomatchMessage":"Lösenorden stämmer inte överens."})
\ No newline at end of file
diff --git a/dojox/form/nls/th/PasswordValidator.js b/dojox/form/nls/th/PasswordValidator.js
new file mode 100644
index 0000000..e7371bf
--- /dev/null
+++ b/dojox/form/nls/th/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"รหัสผ่านไม่ถูกต้อง","nomatchMessage":"รหัสผ่านไม่ตรงกัน"})
\ No newline at end of file
diff --git a/dojox/form/nls/tr/PasswordValidator.js b/dojox/form/nls/tr/PasswordValidator.js
new file mode 100644
index 0000000..3e09bb0
--- /dev/null
+++ b/dojox/form/nls/tr/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Geçersiz Parola.","nomatchMessage":"Parolalar eşleşmiyor."})
\ No newline at end of file
diff --git a/dojox/form/nls/zh-tw/PasswordValidator.js b/dojox/form/nls/zh-tw/PasswordValidator.js
new file mode 100644
index 0000000..498f428
--- /dev/null
+++ b/dojox/form/nls/zh-tw/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"無效的密碼。","nomatchMessage":"密碼不符合。"})
\ No newline at end of file
diff --git a/dojox/form/nls/zh/PasswordValidator.js b/dojox/form/nls/zh/PasswordValidator.js
new file mode 100644
index 0000000..433aa7a
--- /dev/null
+++ b/dojox/form/nls/zh/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"密码无效。","nomatchMessage":"密码不匹配。"})
\ No newline at end of file
diff --git a/dojox/form/resources/BusyButton.css b/dojox/form/resources/BusyButton.css
new file mode 100644
index 0000000..e8ccae4
--- /dev/null
+++ b/dojox/form/resources/BusyButton.css
@@ -0,0 +1,8 @@
+
+.dojoxBusyButtonIcon {
+	width: 10px;
+	height: 10px;
+	vertical-align: middle;
+	margin-left: 4px;
+	background-image: url('images/loading_wheel.gif');
+}
diff --git a/dojox/form/resources/CheckedMultiSelect.css b/dojox/form/resources/CheckedMultiSelect.css
new file mode 100644
index 0000000..7a1464e
--- /dev/null
+++ b/dojox/form/resources/CheckedMultiSelect.css
@@ -0,0 +1,66 @@
+
+.dojoxMultiSelectSelect { display: none; }
+.dojoxMultiSelect {
+	border: solid black 1px;
+	margin: 1px 0;
+	overflow: scroll; 
+	overflow-y: scroll; 
+	overflow-x: hidden; 
+	height: 100px;
+}
+.dj_ie .dojoxMultiSelect,
+.dj_webkit .dojoxMultiSelect {
+	
+	padding-right: 15px;
+}
+.dojoxMultiSelectItem {
+	white-space: nowrap;
+	padding:.1em .2em;
+	cursor:default;
+}
+.dojoxMultiSelectDisabled *,
+.dojoxMultiSelectReadOnly * {
+	color:gray !important;
+}
+.dojoxMultiSelectItemLabel {
+	margin-left: .2em;
+}
+.tundra .dojoxMultiSelect {
+	margin: 0em 0.1em;
+}
+.tundra .dojoxMultiSelect {
+	background:#fff url("../../../dijit/themes/tundra/images/validationInputBg.png") repeat-x top left;
+	#background:#fff url('../../../dijit/themes/tundra/images/validationInputBg.gif') repeat-x top left;
+	border:1px solid #b3b3b3;
+	line-height: normal;
+}
+.tundra .dojoxMultiSelectFocused {
+	
+	border-color:#406b9b;
+}
+.soria .dojoxMultiSelect {
+	margin: 0em 0.1em;
+}
+.soria .dojoxMultiSelect {
+	background:#fff url("../../../dijit/themes/soria/images/validationInputBg.png") repeat-x top left;
+	#background:#fff url('../../../dijit/themes/soria/images/validationInputBg.gif') repeat-x top left;
+	border:1px solid #8ba0bd;
+	line-height: normal;
+}
+.soria .dojoxMultiSelectFocused {
+	
+	border-color:#406b9b;
+}
+.nihilo .dojoxMultiSelect {
+	margin: 0em 0.1em;
+}
+.nihilo .dojoxMultiSelect {
+	background:#fff url("../../../dijit/themes/nihilo/images/validationInputBg.png") repeat-x top left;
+	#background:#fff url('../../../dijit/themes/nihilo/images/validationInputBg.gif') repeat-x top left;
+	border:1px solid #d3d3d3;
+	line-height: normal;
+}
+.nihilo .dojoxMultiSelectFocused {
+	
+	border-color:#b3b3b3;
+}
diff --git a/dojox/form/resources/CheckedMultiSelect.html b/dojox/form/resources/CheckedMultiSelect.html
new file mode 100644
index 0000000..4144d82
--- /dev/null
+++ b/dojox/form/resources/CheckedMultiSelect.html
@@ -0,0 +1,4 @@
+<div class="dijit dijitReset dijitInline" dojoAttachEvent="onmousedown:_mouseDown,onclick:focus"
+	><select class="${baseClass}Select" multiple="true" dojoAttachPoint="containerNode,focusNode"></select
+	><div dojoAttachPoint="wrapperDiv"></div
+></div>
\ No newline at end of file
diff --git a/dojox/form/resources/DropDownSelect.css b/dojox/form/resources/DropDownSelect.css
new file mode 100644
index 0000000..ffa6ad5
--- /dev/null
+++ b/dojox/form/resources/DropDownSelect.css
@@ -0,0 +1,202 @@
+
+.dojoxDropDownSelect {
+	margin: 0.2em;
+}
+.dojoxDropDownSelect .dijitButtonNode {
+	text-align: left;
+}
+.dijitRtl .dojoxDropDownSelect .dijitButtonNode {
+	text-align: right;
+}
+.dijitToolbar .dojoxDropDownSelect {
+	margin: 0;
+}
+.dj_webkit .dijitToolbar .dojoxDropDownSelect {
+	padding-left: 0.3em;
+}
+.dijit_a11y .dojoxDropDownSelectDisabled .dijitButtonNode {
+	border-style: outset!important;
+	border-width: medium!important;
+	border-color: #999 !important;
+	color:#999 !important;
+}
+.dojoxDropDownSelect .dijitButtonContents {
+	padding: 0px;
+	border-right: none;
+	background: transparent none;
+}
+.dojoxDropDownSelectFixedWidth .dijitButtonContents {
+	width: 100%;
+}
+.dojoxDropDownSelect .dijitArrowButton {
+	width: 16px;
+}
+.dojoxDropDownSelectLabel *
+{
+	vertical-align: baseline;
+}
+.dojoxDropDownSelectSelectedOption * {
+	font-weight: bold;
+}
+.dojoxDropDownSelectMenu {
+	border-width: 1px;
+}
+.dojoxDropDownSelect .dijitButtonContents {
+	white-space: nowrap;
+}
+.tundra .dojoxDropDownSelectDisabled * {
+    cursor: not-allowed !important;
+}
+.tundra .dojoxDropDownSelectReadOnly * {
+    cursor: default !important;
+}
+.tundra .dojoxDropDownSelect .dijitButtonNode {
+	padding: 0px;
+}
+.tundra .dojoxDropDownSelect .dijitButtonContents {
+	padding-top: 1px;
+    background:#fff url("../../../dijit/themes/tundra/images/validationInputBg.png") repeat-x top left;
+    #background:#fff url('../../../dijit/themes/tundra/images/validationInputBg.gif') repeat-x top left;
+}
+.tundra .dojoxDropDownSelectHover .dijitButtonContents,
+.tundra .dojoxDropDownSelectActive .dijitButtonContents,
+.tundra .dojoxDropDownSelectOpened .dijitButtonContents,
+.tundra .dojoxDropDownSelectDisabled .dijitButtonContents,
+.tundra .dojoxDropDownSelectReadOnly .dijitButtonContents{
+	background: transparent none;
+}
+.dj_ie .tundra .dojoxDropDownSelect .dijitButtonContents {
+	padding-top: 0px;
+}
+.tundra .dojoxDropDownSelectDisabled .dijitButtonNode {
+    border-color: #d5d5d5 #bdbdbd #bdbdbd #d5d5d5;
+    background:#e4e4e4 url("../../../dijit/themes/tundra/images/buttonDisabled.png") top repeat-x;
+}
+.dj_ie .tundra .dojoxDropDownSelectDisabled  .dijitButtonNode * {
+	filter: gray() alpha(opacity=50); 
+}
+.tundra .dojoxDropDownSelectHover .dijitButtonNode {
+    border-color:#a5beda;
+    border-bottom-color:#5c7590;
+    border-right-color:#5c7590;
+    color:#243C5F;
+    background:#fcfdff url("../../../dijit/themes/tundra/images/buttonHover.png") repeat-x bottom;
+}
+.tundra .dojoxDropDownSelectActive .dijitButtonNode,
+.tundra .dojoxDropDownSelectOpened .dijitButtonNode {
+    border-color:#366dba;
+    background: #ededed url("../../../dijit/themes/tundra/images/buttonActive.png") bottom repeat-x;
+}
+.tundra .dojoxDropDownSelectMenu td {
+	padding: 0em;
+}
+.tundra .dojoxDropDownSelectMenu .dijitMenuItemIcon {
+	margin: 0.1em 0.2em;
+	display: none;
+}
+.tundra .dojoxDropDownSelectMenu .dijitMenuItemLabel,
+.tundra .dojoxDropDownSelectMenu .dijitMenuArrowCell {
+	padding: 0.1em 0.2em;
+}
+.soria .dojoxDropDownSelectDisabled * {
+    cursor: not-allowed !important;
+}
+.soria .dojoxDropDownSelectReadOnly * {
+    cursor: default !important;
+}
+.soria .dojoxDropDownSelect .dijitButtonNode {
+	padding: 0px;
+}
+.soria .dojoxDropDownSelect .dijitButtonContents {
+	padding-top: 1px;
+    background:#fff url("../../../dijit/themes/soria/images/validationInputBg.png") repeat-x top left;
+    #background:#fff url('../../../dijit/themes/soria/images/validationInputBg.gif') repeat-x top left;
+}
+.soria .dojoxDropDownSelectHover .dijitButtonContents,
+.soria .dojoxDropDownSelectActive .dijitButtonContents,
+.soria .dojoxDropDownSelectOpened .dijitButtonContents,
+.soria .dojoxDropDownSelectDisabled .dijitButtonContents,
+.soria .dojoxDropDownSelectReadOnly .dijitButtonContents{
+	background: transparent none;
+}
+.dj_ie .soria .dojoxDropDownSelect .dijitButtonContents {
+	padding-top: 0px;
+}
+.soria .dojoxDropDownSelectDisabled .dijitButtonNode {
+    border-color: #b9bbdd #b9bbdd #b9bbdd #b9bbdd;
+    background:#c3d3e5 url("../../../dijit/themes/soria/images/buttonDisabled.png") top repeat-x;
+}
+.dj_ie .soria .dojoxDropDownSelectDisabled  .dijitButtonNode * {
+	filter: gray() alpha(opacity=50); 
+}
+.soria .dojoxDropDownSelectHover .dijitButtonNode {
+    color:#000;
+    background:#acc5e2 url("../../../dijit/themes/soria/images/buttonHover.png") repeat-x top left;
+}
+.soria .dojoxDropDownSelectActive .dijitButtonNode,
+.soria .dojoxDropDownSelectOpened .dijitButtonNode {
+    border-color:#657c9c;
+    background: #91b4e5 url("../../../dijit/themes/soria/images/buttonActive.png") top left repeat-x;
+}
+.soria .dojoxDropDownSelectMenu td {
+	padding: 0em;
+}
+.soria .dojoxDropDownSelectMenu .dijitMenuItemIcon {
+	margin: 0.1em 0.2em;
+	display: none;
+}
+.soria .dojoxDropDownSelectMenu .dijitMenuItemLabel,
+.soria .dojoxDropDownSelectMenu .dijitMenuArrowCell {
+	padding: 0.1em 0.2em;
+}
+.nihilo .dojoxDropDownSelectDisabled * {
+    cursor: not-allowed !important;
+}
+.nihilo .dojoxDropDownSelectReadOnly * {
+    cursor: default !important;
+}
+.nihilo .dojoxDropDownSelect .dijitButtonNode {
+	padding: 0px;
+}
+.nihilo .dojoxDropDownSelect .dijitButtonContents {
+	padding-top: 1px;
+    background:#fff url("../../../dijit/themes/nihilo/images/validationInputBg.png") repeat-x top left;
+    #background:#fff url('../../../dijit/themes/nihilo/images/validationInputBg.gif') repeat-x top left;
+}
+.nihilo .dojoxDropDownSelectHover .dijitButtonContents,
+.nihilo .dojoxDropDownSelectActive .dijitButtonContents,
+.nihilo .dojoxDropDownSelectOpened .dijitButtonContents,
+.nihilo .dojoxDropDownSelectDisabled .dijitButtonContents,
+.nihilo .dojoxDropDownSelectReadOnly .dijitButtonContents{
+	background: transparent none;
+}
+.dj_ie .nihilo .dojoxDropDownSelect .dijitButtonContents {
+	padding-top: 0px;
+}
+.nihilo .dojoxDropDownSelectDisabled .dijitButtonNode {
+    border-color: #dedede;
+    background:#fafafa url("../../../dijit/themes/nihilo/images/buttonDisabled.png") top repeat-x;
+}
+.dj_ie .nihilo .dojoxDropDownSelectDisabled  .dijitButtonNode * {
+	filter: gray() alpha(opacity=50); 
+}
+.nihilo .dojoxDropDownSelectHover .dijitButtonNode {
+    color:#000;
+    background:#fcfcfc url("../../../dijit/themes/nihilo/images/buttonHover.png") repeat-x top left;
+}
+.nihilo .dojoxDropDownSelectActive .dijitButtonNode,
+.nihilo .dojoxDropDownSelectOpened .dijitButtonNode {
+    border-color:#dedede;
+    background: #f5f5f5 url("../../../dijit/themes/nihilo/images/buttonActive.png") top left repeat-x;
+}
+.nihilo .dojoxDropDownSelectMenu td {
+	padding: 0em;
+}
+.nihilo .dojoxDropDownSelectMenu .dijitMenuItemIcon {
+	margin: 0.1em 0.2em;
+	display: none;
+}
+.nihilo .dojoxDropDownSelectMenu .dijitMenuItemLabel,
+.nihilo .dojoxDropDownSelectMenu .dijitMenuArrowCell {
+	padding: 0.1em 0.2em;
+}
diff --git a/dojox/form/resources/DropDownSelect.html b/dojox/form/resources/DropDownSelect.html
new file mode 100644
index 0000000..f581434
--- /dev/null
+++ b/dojox/form/resources/DropDownSelect.html
@@ -0,0 +1,14 @@
+<table class='dijit dijitReset dijitInline dijitLeft'
+	dojoAttachPoint="dropDownNode,tableNode" cellspacing='0' cellpadding='0' waiRole="presentation"
+	dojoAttachEvent="onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse"
+	><tbody waiRole="presentation"><tr waiRole="presentation"
+		><td class="dijitReset dijitStretch dijitButtonContents dijitButtonNode" 
+			><span class="dijitReset dijitInline dijitButtonText"  dojoAttachPoint="containerNode,popupStateNode" id="${id}_label"></span
+			><input type="hidden" ${nameAttrSetting} dojoAttachPoint="valueNode" value="${value}" />
+		</td><td class="dijitReset dijitRight dijitButtonNode dijitArrowButton dijitDownArrowButton" 
+				dojoAttachPoint="focusNode,titleNode" waiRole="button" waiState="haspopup-true,labelledby-${id}_label"
+			><div class="dijitReset dijitArrowButtonInner"> </div
+			><div class="dijitReset dijitArrowButtonChar" waiRole="presentation">▼</div
+		></td
+	></tr></tbody
+></table>
diff --git a/dojox/form/resources/FileInput.css b/dojox/form/resources/FileInput.css
new file mode 100644
index 0000000..ffe477a
--- /dev/null
+++ b/dojox/form/resources/FileInput.css
@@ -0,0 +1,88 @@
+.dijitFileInput {
+	position:relative;
+	height:1.3em;
+	
+}
+.dijitFileInputReal {
+	position:absolute;
+	z-index:2;
+	filter:alpha(opacity:0);
+	opacity:0;
+	cursor:pointer;
+}
+.dijitFileInputRealBlind {
+	right:0;
+}
+.dijitFileInputReal:hover { cursor:pointer; } 
+.dijitFileInputButton,
+.dijitFileInputText {
+	border:1px solid #333;
+	padding:2px 12px 2px 12px; 
+	cursor:pointer;
+}
+.dijitFileInputButton {
+	z-index:3;
+	visibility:hidden;
+}
+.dijitFakeInput { position:absolute; top:0; left:0; z-index:1; white-space: nowrap; }
+.dijitProgressOverlay {
+	display:none;
+	width:250px;
+	height:1em;
+	position:absolute;
+	top:0; left:0;
+	border:1px solid #333;
+	background:#cad2de url('../../../dijit/themes/tundra/images/dijitProgressBarAnim.gif') repeat-x top left;
+	padding:2px;	
+}
+.tundra .dijitProgressOverlay {
+	border:1px solid #84a3d1;
+	background-color:#cad2de;
+}
+.tundra .dijitFakeInput input {
+	
+	padding: 0;
+	background:#fff url("../../../dijit/themes/tundra/images/validationInputBg.png") repeat-x top left;
+	border:1px solid #9b9b9b;
+	line-height: normal;
+}
+.tundra .dijitFileInputButton, 
+.tundra .dijitFileInputText {
+	border:1px solid #9b9b9b;
+	padding:0px 12px 0px 12px; 
+	background:#e9e9e9 url("../../../dijit/themes/tundra/images/buttonEnabled.png") repeat-x top;
+}
+.soria .dijitProgressOverlay {
+	border:1px solid #8BA0BD;
+	background-color:#cad2de; 
+}
+.soria .dijitFakeInput input {
+	border:1px solid #8BA0BD;
+	background:#fff url("../../../dijit/themes/soria/images/validationInputBg.png") repeat-x top left;
+	line-height:normal;
+	background-position:0 -30px; 
+	padding:0.2em 0.3em;
+}
+.soria .dijitFileInputButton,
+.soria .dijitFileInputText {
+	border:1px solid #8BA0BD;
+	padding:2px 12px 2px 12px;
+	background:#b7cdee url('../../../dijit/themes/soria/images/buttonEnabled.png') repeat-x; 
+}
+.nihilo .dijitProgressOverlay {
+	border:1px solid #DEDEDE;
+	background-color:#cad2de; 
+}
+.nihilo .dijitFakeInput input {
+	border:1px solid #DEDEDE;
+	background:#fff url("../../../dijit/themes/nihilo/images/validationInputBg.png") repeat-x top left;
+	line-height:normal;
+	background-position:0 -30px; 
+	padding:0.2em 0.3em;
+}
+.nihilo .dijitFileInputButton,
+.nihilo .dijitFileInputText {
+	border:1px solid #DEDEDE;
+	padding:2px 12px 2px 12px;
+	background:#b7cdee url('../../../dijit/themes/nihilo/images/buttonEnabled.png') repeat-x; 
+}
diff --git a/dojox/form/resources/FileInput.html b/dojox/form/resources/FileInput.html
new file mode 100644
index 0000000..4ffd120
--- /dev/null
+++ b/dojox/form/resources/FileInput.html
@@ -0,0 +1,9 @@
+<div class="dijitFileInput">
+	<input id="${id}" class="dijitFileInputReal" type="file" dojoAttachPoint="fileInput" name="${name}" />
+	<div class="dijitFakeInput">
+		<input class="dijitFileInputVisible" type="text" dojoAttachPoint="focusNode, inputNode" />
+		<div class="dijitInline dijitFileInputText" dojoAttachPoint="titleNode">${label}</div>
+		<div class="dijitInline dijitFileInputButton" dojoAttachPoint="cancelNode" 
+			dojoAttachEvent="onclick:reset">${cancelText}</div>
+	</div>
+</div>
diff --git a/dojox/form/resources/FileInputAuto.html b/dojox/form/resources/FileInputAuto.html
new file mode 100644
index 0000000..12b2148
--- /dev/null
+++ b/dojox/form/resources/FileInputAuto.html
@@ -0,0 +1,9 @@
+<div class="dijitFileInput">
+	<input id="${id}" name="${name}" class="dijitFileInputReal" type="file" dojoAttachPoint="fileInput" />
+	<div class="dijitFakeInput" dojoAttachPoint="fakeNodeHolder">
+		<input class="dijitFileInputVisible" type="text" dojoAttachPoint="focusNode, inputNode" />
+		<div class="dijitInline dijitFileInputText" dojoAttachPoint="titleNode">${label}</div>
+		<div class="dijitInline dijitFileInputButton" dojoAttachPoint="cancelNode" dojoAttachEvent="onclick:reset">${cancelText}</div>
+	</div>
+	<div class="dijitProgressOverlay" dojoAttachPoint="overlay"> </div>
+</div>
diff --git a/dojox/form/resources/FilePickerTextBox.css b/dojox/form/resources/FilePickerTextBox.css
new file mode 100644
index 0000000..f63c8a0
--- /dev/null
+++ b/dojox/form/resources/FilePickerTextBox.css
@@ -0,0 +1,468 @@
+.dojoxRollingList {
+	border: 1px solid #000;
+	height: 20em;
+	background-color: #FFF;
+	position: relative;
+}
+.dijitPopup .dojoxRollingList {
+	position: static;
+}
+.dojoxRollingListContainer {
+	overflow: scroll;
+	overflow-y: hidden;
+	overflow-x: scroll;
+	white-space: nowrap;
+}
+.dojoxRollingListButtons {
+	position: absolute;
+	right: 5px;
+	padding: 5px 0px;
+}
+.dojoxRollingListButtonsHidden .dojoxRollingListButtons {
+	display: none;
+}
+.dojoxRollingListPane {
+	overflow: scroll;
+	overflow-x: hidden;
+	overflow-y: scroll;
+	display:-moz-inline-box;		
+	display:inline-block;			
+	#zoom: 1; 
+	#display:inline; 
+	border:0;
+	padding:0;
+	vertical-align:middle;
+	#vertical-align: auto;	
+}
+.dojoxRollingListPane .dijitMenuItem td {
+	width: 1px;
+}
+.dojoxRollingListPane .dijitMenuItem td.dijitMenuItemLabel {
+	width: auto;
+}
+.dojoxRollingListPane .dijitMenuItemLabel,
+.dojoxRollingListPane .dijitMenuItemIcon {
+	position: static !important;
+}
+.dj_webkit .dojoxRollingListPane,
+.dj_ie .dojoxRollingListPane {
+	padding-right: 15px; 
+}
+.dojoxRollingListPane .dijitMenu {
+	border: none !important;
+}
+.dojoxRollingListItem {
+	cursor: default;
+}
+.tundra .dojoxRollingList {
+	border-color: #b3b3b3;
+}
+.tundra .dijitPopup .dojoxRollingList {
+	border-color: #406b9b;
+}
+.tundra .dojoxRollingListPane {
+	background-color: #f7f7f7;
+}
+.tundra .dojoxRollingListPane .dojoxRollingListItemHover,
+.tundra .dojoxRollingListPane .dojoxRollingListItemFocus {
+	background-color: #e3e3e3;
+}
+.tundra .dojoxRollingListPane .dojoxRollingListItemSelected {
+	color: #fff;
+	background-color: #999;
+	font-weight: bold;
+}
+.tundra .dojoxRollingListPaneCurrentSelected .dojoxRollingListItemSelected {
+	background-color: #3559ac;
+}
+.tundra .dojoxRollingListPane .dojoxRollingListItemHoverSelected,
+.tundra .dojoxRollingListPane .dojoxRollingListItemFocusSelected {
+	background-color: #9aacd6;
+}
+.tundra .dojoxRollingListItem {
+	font-family: inherit;
+}
+.soria .dojoxRollingList {
+	border-color: #8ba0bd;
+}
+.soria .dijitPopup .dojoxRollingList {
+	border-color: #406b9b;
+}
+.soria .dojoxRollingListPane {
+	background-color: #fff;
+}
+.soria .dojoxRollingListPane .dojoxRollingListItemHover, 
+.soria .dojoxRollingListPane .dojoxRollingListItemFocus {
+	background-color: #e3e3e3;
+}
+.soria .dojoxRollingListPane .dojoxRollingListItemSelected {
+	color: #243C5F;
+	background-color: #ccc;
+	font-weight: bold;
+}
+.soria .dojoxRollingListPaneCurrentSelected .dojoxRollingListItemSelected {
+	background-color: #d9e6f9;
+}
+.soria .dojoxRollingListPane .dojoxRollingListItemHoverSelected,
+.soria .dojoxRollingListPane .dojoxRollingListItemFocusSelected {
+	background-color: #ecf3fc;
+}
+.soria .dojoxRollingListItem {
+	font-family: inherit;
+}
+.nihilo .dojoxRollingList {
+	border-color: #d3d3d3;
+}
+.nihilo .dijitPopup .dojoxRollingList {
+	border-color: #b3b3b3;
+}
+.nihilo .dojoxRollingListPane {
+	background-color: #fff;
+}
+.nihilo .dojoxRollingListPane .dojoxRollingListItemHover,
+.nihilo .dojoxRollingListPane .dojoxRollingListItemFocus {
+	background-color: #e3e3e3;
+}
+.nihilo .dojoxRollingListPane .dojoxRollingListItemSelected {
+	color: #243C5F;
+	background-color: #ccc;
+	font-weight: bold;
+}
+.nihilo .dojoxRollingListPaneCurrentSelected .dojoxRollingListItemSelected {
+	background-color: #ffe284;
+}
+.nihilo .dojoxRollingListPane .dojoxRollingListItemHoverSelected,
+.nihilo .dojoxRollingListPane .dojoxRollingListItemFocusSelected {
+	background-color: #fff1c2;
+}
+.nihilo .dojoxRollingListItem {
+	font-family: inherit;
+}
+.dojoxFileInfoPane *{
+	white-space: normal;
+}
+.dojoxFileInfoLabel {
+	font-weight: bold;
+	white-space: nowrap;
+}
+.dojoxFileInfoPane {
+	width: 20em;
+}
+.tundra .dojoxFilePickerItem .dijitMenuItemIcon {
+	background-image: url(../../widget/FilePicker/images/tundraFileIcons.gif);
+	background-repeat: no-repeat;
+}
+.tundra .dojoxFilePickerItem .dojoxEmpty {
+	background-image: none;
+}
+.tundra .dojoxFilePickerItem .dojoxDirectoryItemIcon {
+	background-position: 0px;
+}
+.tundra .dojoxFilePickerItemSelected .dojoxDirectoryItemIcon {
+	background-position: -16px;
+}
+.tundra .dojoxFilePickerItem .dojoxFileItemIcon {
+	background-position: -32px;
+}
+.tundra .dojoxFilePickerItemSelected .dojoxFileItemIcon {
+	background-position: -48px;
+}
+.soria .dojoxFilePickerItem .dijitMenuItemIcon {
+	background-image: url(../../widget/FilePicker/images/soriaFileIcons.gif);
+	background-repeat: no-repeat;
+}
+.soria .dojoxFilePickerItem .dojoxEmpty {
+	background-image: none;
+}
+.soria .dojoxFilePickerItem .dojoxDirectoryItemIcon {
+	background-position: 0px;
+}
+.soria .dojoxFilePickerItemSelected .dojoxDirectoryItemIcon {
+	background-position: -16px;
+}
+.soria .dojoxFilePickerItem .dojoxFileItemIcon {
+	background-position: -32px;
+}
+.soria .dojoxFilePickerItemSelected .dojoxFileItemIcon {
+	background-position: -48px;
+}
+.nihilo .dojoxFilePickerItem .dijitMenuItemIcon {
+	background-image: url(../../widget/FilePicker/images/nihiloFileIcons.gif);
+	background-repeat: no-repeat;
+}
+.nihilo .dojoxFilePickerItem .dojoxEmpty {
+	background-image: none;
+}
+.nihilo .dojoxFilePickerItem .dojoxDirectoryItemIcon {
+	background-position: 0px;
+}
+.nihilo .dojoxFilePickerItemSelected .dojoxDirectoryItemIcon {
+	background-position: -16px;
+}
+.nihilo .dojoxFilePickerItem .dojoxFileItemIcon {
+	background-position: -32px;
+}
+.nihilo .dojoxFilePickerItemSelected .dojoxFileItemIcon {
+	background-position: -48px;
+}
+.dojoxFilePickerTextBox{
+	width: 30em;
+	vertical-align: middle;
+}
+.dojoxFilePickerTextBox input:focus{
+	outline: none;
+}
+.dojoxFilePickerTextBoxFocused{
+	outline: auto 5px -webkit-focus-ring-color;
+}
+.dojoxFilePickerTextBox INPUT{
+	border-left: solid black 1px;
+	display:inline;
+	position:static !important;
+	border:0 !important;	
+	margin:0 !important;
+	vertical-align:top !important;
+	visibility:visible !important;
+	background-color:transparent !important;
+	background-image:none !important;
+	width:100% !important;
+}
+.dijitRtl .dojoxFilePickerTextBox .dijitInputField {
+	border-right-width:1px !important;
+	border-left-width:0 !important;
+}
+.tundra .dojoxFilePickerTextBoxDisabled *
+{
+	cursor: not-allowed !important;
+}
+.tundra .dojoxFilePickerTextBox {
+	font-family: sans-serif;
+	font-size: 100%;
+}
+.tundra .dojoxFilePickerTextBox {
+	background:#fff url("../../../dijit/themes/tundra/images/validationInputBg.png") repeat-x top left;
+	#background:#fff url('../../../dijit/themes/tundra/images/validationInputBg.gif') repeat-x top left;
+	border:1px solid #b3b3b3;
+	line-height: normal;
+}
+.tundra .dojoxFilePickerTextBoxDisabled {
+	color: gray;
+}
+.dj_webkit .tundra .dojoxFilePickerTextBoxDisabled {
+	color: #eee;
+}
+.tundra .dojoxFilePickerTextBox .dijitInputField {
+	padding: 1px 0;
+}
+.tundra .dojoxFilePickerTextBox .dijitButtonNode {
+	padding: 1px 0.2em;
+}
+.tundra .dojoxFilePickerTextBox .dijitButtonNode{
+	border-color: #9b9b9b;
+	border-width: 0px 0px 0px 1px;
+	border-style: solid;
+}
+.tundra .dojoxFilePickerTextBoxFocused {
+	border-color:#406b9b;
+}
+.tundra .dojoxFilePickerTextBoxFocused .dijitButtonNode {
+	border-left-color:#366dba;
+}
+.dijitRtl .tundra .dojoxFilePickerTextBox .dijitButtonNode{
+	border-color: #9b9b9b;
+	border-width: 0px 1px 0px 0px;
+}
+.tundra .dojoxFilePickerTextBoxDisabled {
+	border-color: #d5d5d5 #d5d5d5 #bdbdbd #d5d5d5; 
+	background:#e4e4e4 url("../../../dijit/themes/tundra/images/buttonDisabled.png") top repeat-x;
+}
+.tundra .dojoxFilePickerTextBoxHover .dijitDownArrowButton {
+	border-color:		#a5beda; 
+	border-bottom-color:#5c7590; 
+	color:#000;
+	background:#fcfdff url("../../../dijit/themes/tundra/images/buttonHover.png") repeat-x bottom;
+}
+.tundra .dojoxFilePickerTextBoxActive .dijitDownArrowButton {
+	border-color:#366dba;
+	background: #ededed url("../../../dijit/themes/tundra/images/buttonActive.png") bottom repeat-x;
+}
+.tundra .dojoxFilePickerTextBox .dijitArrowButton .dijitArrowButtonInner {
+	background-image: url("images/tundraFolderSprite.gif");
+	background-repeat: no-repeat;
+	background-attachment: scroll;
+	background-position: left center;
+	height: auto;
+	width: 16px;
+	font-size: 100%;
+	font-size: inherit;
+}
+.tundra .dojoxFilePickerTextBox .dojoxHasDropDownOpen .dijitArrowButtonInner {
+	background-position: -16px;
+}
+.tundra .dojoxFilePickerTextBoxError {
+	background-color:#f9f7ba;
+	background-image:none;
+}
+.dj_ie6 .tundra .dojoxFilePickerTextBoxError INPUT {
+	background-color:#f9f7ba !important;
+}
+.tundra .dojoxFilePickerTextBoxErrorFocused {
+	background-color:#f9f999;
+	background-image:none;
+}
+.dj_ie6 .tundra .dojoxFilePickerTextBoxErrorFocused INPUT {
+	background-color:#f9f999 !important;
+}
+.nihilo .dojoxFilePickerTextBoxDisabled *
+{
+	cursor: not-allowed !important;
+}
+.nihilo .dojoxFilePickerTextBox{
+	margin: 0em 0.1em;
+}
+.nihilo .dojoxFilePickerTextBox {
+	background:#fff url("../../../dijit/themes/nihilo/images/validationInputBg.png") repeat-x top left;
+	#background:#fff url('../../../dijit/themes/nihilo/images/validationInputBg.gif') repeat-x top left;
+	border:1px solid #d3d3d3;
+	line-height: normal;
+}
+.nihilo .dojoxFilePickerTextBox .dijitButtonNode {
+	padding: 0 0.2em;
+}
+.nihilo .dojoxFilePickerTextBox .dijitButtonNode{
+	border-color: #d3d3d3;
+	border-left: 1px solid #d3d3d3;
+}
+.nihilo .dojoxFilePickerTextBoxDisabled {
+	color: gray;
+}
+.dj_safari .nihilo .dojoxFilePickerTextBoxDisabled {
+	color: #eee;
+}
+.nihilo .dojoxFilePickerTextBoxFocused {
+	border-color:#b3b3b3;
+}
+.nihilo .dojoxFilePickerTextBoxFocused .dijitButtonNode, {
+	border-left-color:#d3d3d3;
+}
+.dijitRtl .nihilo .dojoxFilePickerTextBox .dijitButtonNode {
+	border-color: #8ba0bd;
+	border-left: 0px solid #8ba0bd;
+	border-right: 1px solid #8ba0bd;
+}
+.nihilo .dojoxFilePickerTextBoxDisabled {
+	border-color: #dedede;
+	background:#fafafa url("../../../dijit/themes/nihilo/images/buttonDisabled.png") top repeat-x;
+	opacity: 0.60;
+}
+.nihilo .dojoxFilePickerTextBoxHover .dijitDownArrowButton {
+	color:#000;
+	background:#fcfcfc url("../../../dijit/themes/nihilo/images/buttonHover.png") repeat-x top left;
+}
+.nihilo .dojoxFilePickerTextBoxActive .dijitDownArrowButton {
+	border-color:#dedede;
+	background: #f5f5f5 url("../../../dijit/themes/nihilo/images/buttonActive.png") top left repeat-x;
+}
+.dijitRtl .nihilo .dojoxFilePickerTextBox .dijitButtonNode {
+	border-width: 0px 0px 0px 1px;
+}
+.nihilo .dojoxFilePickerTextBox .dijitArrowButton .dijitArrowButtonInner {
+	background:url("images/nihiloFolderSprite.gif") no-repeat left center;
+	width: 16px;
+}
+.nihilo .dojoxFilePickerTextBox .dojoxHasDropDownOpen .dijitArrowButtonInner {
+	background-position: -16px;
+}
+.nihilo .dojoxFilePickerTextBoxError {
+	border-color:#b3b3b3;
+	background-color:#f9f7ba;
+	background-image:none;
+}
+.dj_ie6 .nihilo .dojoxFilePickerTextBoxError INPUT {
+	background-color:#f9f7ba !important;
+}
+.nihilo .dojoxFilePickerTextBoxErrorFocused {
+	background-color:#ff6;
+	background-image:none;
+}
+.dj_ie6 .nihilo .dojoxFilePickerTextBoxErrorFocused INPUT {
+	background-color:#ff6 !important;
+}
+.soria .dojoxFilePickerTextBoxDisabled *
+{
+	cursor: not-allowed !important;
+}
+.soria .dojoxFilePickerTextBox{
+	margin: 0em 0.1em;
+}
+.soria .dojoxFilePickerTextBox {
+	background:#fff url("../images/validationInputBg.png") repeat-x top left;
+	#background:#fff url('../images/validationInputBg.gif') repeat-x top left;
+	border:1px solid #8ba0bd;
+	line-height: normal;
+}
+.soria .dojoxFilePickerTextBoxDisabled{
+	color: gray;
+}
+.dj_safari .soria .dojoxFilePickerTextBoxDisabled{
+	color: #eee;
+}
+.soria .dojoxFilePickerTextBox .dijitButtonNode {
+	padding: 0 0.2em;
+}
+.soria .dojoxFilePickerTextBox .dijitButtonNode{
+	border-color: #8ba0bd;
+	border-left: 1px solid #8ba0bd;
+}
+.soria .dojoxFilePickerTextBoxFocused {
+	border-color:#406b9b;
+}
+.soria .dojoxFilePickerTextBoxFocused .dijitButtonNode {
+	border-left-color:#8ba0bd;
+}
+.dijitRtl .soria .dojoxFilePickerTextBox .dijitButtonNode{
+	border-color: #8ba0bd;
+	border-left: 0px solid #8ba0bd;
+	border-right: 1px solid #8ba0bd;
+}
+.soria .dojoxFilePickerTextBox .dijitButtonNode {
+	border-width: 0px 0px 0px 1px;
+}
+.soria .dojoxFilePickerTextBoxDisabled{
+	border-color: #b9bbdd #b9bbdd #b9bbdd #b9bbdd;
+	background:#c3d3e5 url("../../../dijit/themes/soria/buttonDisabled.png") top repeat-x;
+	opacity: 0.60; 
+}
+.soria .dojoxFilePickerTextBoxHover .dijitDownArrowButton{
+	color:#000;
+	background:#acc5e2 url("../../../dijit/themes/soria/buttonHover.png") repeat-x top left;
+}
+.soria .dojoxFilePickerTextBoxActive .dijitDownArrowButton {
+	border-color:#657c9c;
+	background: #91b4e5 url("../../../dijit/themes/soria/buttonActive.png") top left repeat-x;
+}
+.dijitRtl .soria .dojoxFilePickerTextBox .dijitButtonNode {
+	border-width: 0px 0px 0px 1px;
+}
+.soria .dojoxFilePickerTextBox .dijitArrowButton .dijitArrowButtonInner {
+	background:url("images/soriaFolderSprite.gif") no-repeat left center;
+	width: 16px;
+}
+.soria .dojoxFilePickerTextBox .dojoxHasDropDownOpen .dijitArrowButtonInner {
+	background-position: -16px;
+}
+.soria .dojoxFilePickerTextBoxError {
+	border-color:#f3d118;
+	background-color:#f9f7ba;
+	background-image:none;
+}
+.dj_ie6 .soria .dojoxFilePickerTextBoxError INPUT {
+	background-color:#f9f7ba !important;
+}
+.soria .dojoxFilePickerTextBoxErrorFocused {
+	background-color:#ff6;
+	background-image:none;
+}
+.dj_ie6 .soria .dojoxFilePickerTextBoxErrorFocused INPUT {
+	background-color:#ff6 !important;
+}
diff --git a/dojox/form/resources/FilePickerTextBox.html b/dojox/form/resources/FilePickerTextBox.html
new file mode 100644
index 0000000..923f638
--- /dev/null
+++ b/dojox/form/resources/FilePickerTextBox.html
@@ -0,0 +1,18 @@
+<div class="dijit dijitReset dijitInlineTable dijitLeft"
+	id="widget_${id}"
+	dojoAttachEvent="onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse" waiRole="combobox" tabIndex="-1"
+	><div style="overflow:hidden;"
+		><div class='dijitReset dijitRight dijitButtonNode dijitArrowButton dijitDownArrowButton'
+			dojoAttachPoint="downArrowNode,dropDownNode,popupStateNode" waiRole="presentation"
+			><div class="dijitArrowButtonInner"> </div
+			><div class="dijitArrowButtonChar">▼</div
+		></div
+		><div class="dijitReset dijitValidationIcon"><br></div
+		><div class="dijitReset dijitValidationIconText">Χ</div
+		><div class="dijitReset dijitInputField"
+			><input type="text" autocomplete="off" ${nameAttrSetting} class='dijitReset'
+				dojoAttachEvent='onkeypress:_onKey' 
+				dojoAttachPoint='textbox,focusNode' waiRole="textbox" waiState="haspopup-true,autocomplete-list"
+		/></div
+	></div
+></div>
diff --git a/dojox/form/resources/FileUploader.css b/dojox/form/resources/FileUploader.css
new file mode 100644
index 0000000..72aac86
--- /dev/null
+++ b/dojox/form/resources/FileUploader.css
@@ -0,0 +1,61 @@
+.fileToUpload,
+.fileToUploadClose,
+.fileToUploadName,
+.fileToUploadSize{
+	height:18px;
+	line-height:18px;
+}
+.fileToUpload{
+	font-size:12px;
+	font-family:sans-serif;
+	padding:2px;
+	margin:0px;
+	width:100%;
+}
+.fileToUploadName{
+	text-align:left;
+	width:auto !important;
+}
+.fileToUploadSize{
+	width:30px !important;
+	text-align:right;
+}
+.dj_ie .fileToUploadSize{
+	padding-right:20px;
+}
+.fileToUploadClose{
+	background:url(../../../dijit/themes/tundra/images/tabClose.png) no-repeat 2px center;
+	width:18px !important;
+	cursor:pointer;
+}
+.fileToUploadClose:hover{
+	background:url(../../../dijit/themes/tundra/images/tabCloseHover.png) no-repeat 2px center;
+}
+.thumb{
+	height:50px;
+	padding:3px;
+	border:1px solid #ccc;
+	margin-bottom:3px;
+}
+.thumbPic{
+	width:50px;
+	height:50px;
+	text-align:center;
+	line-height:50px;
+	background-color:#000;
+	float:left;
+}
+.thumbPic img{
+	line-height:50px;
+	margin:auto auto;
+	display:block;
+}
+.thumbText{
+	float:left;
+	margin-left:5px;
+	font-size:10px;
+}
+.dj_ie object{
+	
+	display:block !important;
+}
diff --git a/dojox/form/resources/HorizontalRangeSlider.html b/dojox/form/resources/HorizontalRangeSlider.html
new file mode 100644
index 0000000..32c0532
--- /dev/null
+++ b/dojox/form/resources/HorizontalRangeSlider.html
@@ -0,0 +1,39 @@
+<table class="dijit dijitReset dijitSlider dojoxRangeSlider" cellspacing="0" cellpadding="0" border="0" rules="none"
+    ><tr class="dijitReset"
+        ><td class="dijitReset" colspan="2"></td
+        ><td dojoAttachPoint="containerNode,topDecoration" class="dijitReset" style="text-align:center;width:100%;"></td
+        ><td class="dijitReset" colspan="2"></td
+    ></tr
+    ><tr class="dijitReset"
+        ><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerH"
+            ><div class="dijitSliderDecrementIconH" tabIndex="-1" style="display:none" dojoAttachPoint="decrementButton" dojoAttachEvent="onclick: decrement"><span class="dijitSliderButtonInner">-</span></div
+        ></td
+        ><td class="dijitReset"
+            ><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperH dijitSliderLeftBumper dijitSliderLeftBumperH" dojoAttachEvent="onclick:_onClkDecBumper"></div
+        ></td
+        ><td class="dijitReset"
+            ><input dojoAttachPoint="valueNode" type="hidden" name="${name}"
+            /><div waiRole="presentation" class="dojoxRangeSliderBarContainer" dojoAttachPoint="sliderBarContainer"
+                ><div dojoAttachPoint="sliderHandle" tabIndex="${tabIndex}" class="dijitSliderMoveable" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onHandleClick" waiRole="slider" valuemin="${minimum}" valuemax="${maximum}"
+                    ><div class="dijitSliderImageHandle dijitSliderImageHandleH"></div
+                ></div
+                ><div waiRole="presentation" dojoAttachPoint="progressBar,focusNode" class="dijitSliderBar dijitSliderBarH dijitSliderProgressBar dijitSliderProgressBarH" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onBarClick"></div
+                ><div dojoAttachPoint="sliderHandleMax,focusNodeMax" tabIndex="${tabIndex}" class="dijitSliderMoveable" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onHandleClickMax" waiRole="sliderMax" valuemin="${minimum}" valuemax="${maximum}"
+                    ><div class="dijitSliderImageHandle dijitSliderImageHandleH"></div
+                ></div
+                ><div waiRole="presentation" dojoAttachPoint="remainingBar" class="dijitSliderBar dijitSliderBarH dijitSliderRemainingBar dijitSliderRemainingBarH" dojoAttachEvent="onmousedown:_onRemainingBarClick"></div
+            ></div
+        ></td
+        ><td class="dijitReset"
+            ><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperH dijitSliderRightBumper dijitSliderRightBumperH" dojoAttachEvent="onclick:_onClkIncBumper"></div
+        ></td
+        ><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerH"
+            ><div class="dijitSliderIncrementIconH" tabIndex="-1" style="display:none" dojoAttachPoint="incrementButton" dojoAttachEvent="onclick: increment"><span class="dijitSliderButtonInner">+</span></div
+        ></td
+    ></tr
+    ><tr class="dijitReset"
+        ><td class="dijitReset" colspan="2"></td
+        ><td dojoAttachPoint="containerNode,bottomDecoration" class="dijitReset" style="text-align:center;"></td
+        ><td class="dijitReset" colspan="2"></td
+    ></tr
+></table>
diff --git a/dojox/form/resources/PasswordValidator.html b/dojox/form/resources/PasswordValidator.html
new file mode 100644
index 0000000..80a55ae
--- /dev/null
+++ b/dojox/form/resources/PasswordValidator.html
@@ -0,0 +1,3 @@
+<div dojoAttachPoint="containerNode">
+	<input type="hidden" name="${name}" value="" dojoAttachPoint="focusNode" />
+</div>
\ No newline at end of file
diff --git a/dojox/form/resources/RangeSlider.css b/dojox/form/resources/RangeSlider.css
new file mode 100644
index 0000000..12b6da9
--- /dev/null
+++ b/dojox/form/resources/RangeSlider.css
@@ -0,0 +1,18 @@
+.dojoxRangeSlider .dijitSliderLeftBumperH, .dojoxRangeSlider .dijitSliderBottomBumperV  {
+    background:#FFFFFF !important;
+}
+.dojoxRangeSliderBarContainer {
+    position:relative;
+}
+.dojoxRangeSlider .dijitSliderProgressBarV {
+    position:relative !important;
+}
+.dojoxRangeSlider .dijitSliderProgressBar {
+    overflow:hidden;
+    cursor:pointer;
+    
+}
+.dojoxRangeSlider .dijitSliderProgressBarV {
+    position:absolute !important;
+    border-width: 0px;
+}
diff --git a/dojox/form/resources/Rating.css b/dojox/form/resources/Rating.css
new file mode 100644
index 0000000..fb190e7
--- /dev/null
+++ b/dojox/form/resources/Rating.css
@@ -0,0 +1,20 @@
+.dojoxRating ul {
+	padding:0;
+	margin:0;
+}
+.dojoxRatingStar {
+	display:inline-block;
+	background-image:url(images/rating_empty.gif);
+	background-position:left center;
+	position:relative;
+	height:15px;
+	width:15px;
+	float:left;
+}
+.dojoxRatingStarChecked {
+	background-image:url(images/rating_full.gif);
+}
+.dojoxRatingStarHover {
+	background-image:url(images/rating_full.gif);
+	opacity:.5;
+}
diff --git a/dojox/form/resources/RecieveFile.php b/dojox/form/resources/RecieveFile.php
new file mode 100644
index 0000000..aca541f
--- /dev/null
+++ b/dojox/form/resources/RecieveFile.php
@@ -0,0 +1,37 @@
+<?php
+
+// THIS IS AN EXAMPLE
+// you will obviously need to do more server side work than I am doing here to check and move your upload.
+// API is up for discussion, jump on http://dojotoolkit.org/forums
+
+// JSON.php is available in dojo svn checkout
+require("../../../dojo/tests/resources/JSON.php");
+$json = new Services_JSON();
+
+// fake delay
+sleep(3);
+$name = empty($_REQUEST['name'])? "default" : $_REQUEST['name'];
+if(is_array($_FILES)){
+	$ar = array(
+		// lets just pass lots of stuff back and see what we find.
+		// the _FILES aren't coming through in IE6 (maybe 7)
+		'status' => "success",
+		'name' => $name,
+		'request' => $_REQUEST,
+		'postvars' => $_POST,
+		'details' => $_FILES,
+		// and some static subarray just to see
+		'foo' => array('foo'=>"bar")
+	);
+
+}else{
+	$ar = array(
+		'status' => "failed",
+		'details' => ""
+	);
+}
+
+// yeah, seems you have to wrap iframeIO stuff in textareas?
+$foo = $json->encode($ar);
+?>
+<textarea><?php print $foo; ?></textarea>
diff --git a/dojox/form/resources/UploadFile.php b/dojox/form/resources/UploadFile.php
new file mode 100644
index 0000000..30fdea1
--- /dev/null
+++ b/dojox/form/resources/UploadFile.php
@@ -0,0 +1,226 @@
+<?php
+// summary
+//		Test file to handle image uploads (remove the image size check to upload non-images)
+//
+//		This file handles both Flash and HTML uploads
+//
+//		NOTE: This is obviously a PHP file, and thus you need PHP running for this to work
+//		NOTE: Directories must have write permissions
+//		NOTE: This code uses the GD library (to get image sizes), that sometimes is not pre-installed in a 
+//				standard PHP build. 
+//
+require("cLOG.php");
+function findTempDirectory()
+  {
+    if(isset($_ENV["TMP"]) && is_writable($_ENV["TMP"])) return $_ENV["TMP"];
+    elseif( is_writable(ini_get('upload_tmp_dir'))) return ini_get('upload_tmp_dir');
+    elseif(isset($_ENV["TEMP"]) && is_writable($_ENV["TEMP"])) return $_ENV["TEMP"];
+    elseif(is_writable("/tmp")) return "/tmp";
+    elseif(is_writable("/windows/temp")) return "/windows/temp";
+    elseif(is_writable("/winnt/temp")) return "/winnt/temp";
+    else return null;
+  }
+function trace($txt, $isArray=false){
+	//creating a text file that we can log to
+	// this is helpful on a remote server if you don't
+	//have access to the log files
+	//
+	//echo($txt."<br/>");
+	$log = new cLOG("../resources/upload.txt", false);
+	//$log->clear();
+	if($isArray){
+		$log->printr($txt);
+	}else{
+		$log->write($txt);
+	}
+}
+function getImageType($filename){
+	return strtolower(substr(strrchr($filename,"."),1));
+}
+trace("---------------------------------------------------------");
+
+//
+//
+//	EDIT ME: According to your local directory structure.
+// 	NOTE: Folders must have write permissions
+//
+$upload_path = "../resources/"; 	// where image will be uploaded, relative to this file
+$download_path = "../resources/";	// same folder as above, but relative to the HTML file
+
+//
+// 	NOTE: maintain this path for JSON services
+//
+require("../../../dojo/tests/resources/JSON.php");
+$json = new Services_JSON();
+
+//
+// 	Determine if this is a Flash upload, or an HTML upload
+//	
+//
+
+//		First combine relavant postVars
+$postdata = array();
+$data = "";
+foreach ($_POST as $nm => $val) {
+	$data .= $nm ."=" . $val . ",";	// string for flash
+	$postdata[$nm] = $val;			// array for html
+}
+trace("POSTDATA:");
+trace($postdata, true);
+
+$fieldName = "flashUploadFiles";//Filedata";
+
+if( isset($_FILES[$fieldName])){
+	//
+	// If the data passed has $fieldName, then it's Flash.
+	// NOTE: "Filedata" is the default fieldname, but we're using a custom fieldname.
+	//
+	trace("returnFlashdata.... ");
+	
+	trace("");
+	trace("ID:");
+	trace($_POST['testId']);
+	
+	trace("Flash POST:");
+	trace($_POST, true);
+	
+	
+	
+	trace("GET:");
+	trace($_GET, true);
+	
+	trace("FILES:");
+	trace($_FILES[$fieldName], true);
+	
+	trace("REQUEST:");
+	trace($_REQUEST, true);
+	
+	
+	
+	
+	
+	$returnFlashdata = true; //for dev
+	$m = move_uploaded_file($_FILES[$fieldName]['tmp_name'],  $upload_path . $_FILES[$fieldName]['name']);
+	$name = $_FILES[$fieldName]['name'];
+	$file = $upload_path . $name;
+	try{
+	  list($width, $height) = getimagesize($file);
+	} catch(Exception $e){
+	  $width=0;
+	  $height=0;
+	}
+	$type = getImageType($file);
+	trace("file: " . $file ."  ".$type." ".$width);
+	// 		Flash gets a string back:
+	
+	$data .='file='.$file.',name='.$name.',width='.$width.',height='.$height.',type='.$type;
+	if($returnFlashdata){
+		trace("returnFlashdata:\n=======================");
+		trace($data);
+		trace("=======================");
+		// echo sends data to Flash:
+		echo($data);
+		// return is just to stop the script:
+		return;
+	}
+
+
+
+
+}elseif( isset($_FILES['uploadedfile']) ){
+	//
+	// 	If the data passed has 'uploadedfile', then it's HTML. 
+	//	There may be better ways to check this, but this *is* just a test file.
+	//
+	$m = move_uploaded_file($_FILES['uploadedfile']['tmp_name'],  $upload_path . $_FILES['uploadedfile']['name']);
+	
+	trace("HTML single POST:");
+	trace($postdata, true);
+	
+	$name = $_FILES['uploadedfile']['name'];
+	$file = $upload_path . $name;
+	$type = getImageType($file);
+	try{
+	  list($width, $height) = getimagesize($file);
+	} catch(Exception $e){
+	  $width=0;
+	  $height=0;
+	}
+	trace("file: " . $file );
+	
+	$postdata['file'] = $file;
+	$postdata['name'] = $name;
+	$postdata['width'] = $width;
+	$postdata['height'] = $height;
+	$postdata['type'] = $type;
+	$postdata['size'] = filesize($file);
+
+}elseif( isset($_FILES['uploadedfile0']) ){
+	//
+	//	Multiple files have been passed from HTML
+	//
+	$cnt = 0;
+	trace("HTML multiple POST:");
+	trace($postdata, true);
+	
+	$_post = $postdata;
+	$postdata = array();
+	
+	while(isset($_FILES['uploadedfile'.$cnt])){
+	  trace("izzaa file");
+		$moved = move_uploaded_file($_FILES['uploadedfile'.$cnt]['tmp_name'],  $upload_path . $_FILES['uploadedfile'.$cnt]['name']);
+		trace("moved:" . $moved ."  ". $_FILES['uploadedfile'.$cnt]['name']);
+		if($moved){
+			$name = $_FILES['uploadedfile'.$cnt]['name'];
+			$file = $upload_path . $name;
+			$type = getImageType($file);
+			try{
+			  list($width, $height) = getimagesize($file);
+			} catch(Exception $e){
+			  $width=0;
+			  $height=0;
+			}
+			trace("file: " . $file );
+			
+			$_post['file'] = $file;
+			$_post['name'] = $name;
+			$_post['width'] = $width;
+			$_post['height'] = $height;
+			$_post['type'] = $type;
+			$_post['size'] = filesize($file);
+		  
+			trace($_post, true);
+			
+			$postdata[$cnt] = $_post;
+			
+		}elseif(strlen($_FILES['uploadedfile'.$cnt]['name'])){
+		  $postdata[$cnt] =array("ERROR" => "File could not be moved: ".$_FILES['uploadedfile'.$cnt]['name']);
+		}
+		$cnt++;
+	}
+	trace("HTML multiple POST done:");
+	foreach($postdata as $key => $value){
+		trace($value, true);
+	}
+}elseif(isset($_GET['rmFiles'])){
+	trace("DELETING FILES" . $_GET['rmFiles']);
+	$rmFiles = explode(";", $_GET['rmFiles']);
+	foreach($rmFiles as $f){
+		if($f && file_exists($f)){
+			trace("deleted:" . $f. ":" .unlink($f));
+		}
+	}
+
+}else{
+	trace("IMROPER DATA SENT... $FILES:");
+	trace($_FILES);
+	$postdata = array("ERROR" => "Improper data sent - no files found");
+}
+
+//HTML gets a json array back:
+$data = $json->encode($postdata);
+trace("Json Data Returned:");
+trace($data);
+// in a text field:
+?>
+<textarea><?php print $data; ?></textarea>
\ No newline at end of file
diff --git a/dojox/form/resources/VerticalRangeSlider.html b/dojox/form/resources/VerticalRangeSlider.html
new file mode 100644
index 0000000..777380c
--- /dev/null
+++ b/dojox/form/resources/VerticalRangeSlider.html
@@ -0,0 +1,50 @@
+<table class="dijitReset dijitSlider dojoxRangeSlider" cellspacing="0" cellpadding="0" border="0" rules="none"
+><tbody class="dijitReset"
+    ><tr class="dijitReset"
+        ><td class="dijitReset"></td
+        ><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerV"
+            ><div class="dijitSliderIncrementIconV" tabIndex="-1" style="display:none" dojoAttachPoint="incrementButton" dojoAttachEvent="onclick: increment"><span class="dijitSliderButtonInner">+</span></div
+        ></td
+        ><td class="dijitReset"></td
+    ></tr
+    ><tr class="dijitReset"
+        ><td class="dijitReset"></td
+        ><td class="dijitReset"
+            ><center><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperV dijitSliderTopBumper dijitSliderTopBumperV" dojoAttachEvent="onclick:_onClkIncBumper"></div></center
+        ></td
+        ><td class="dijitReset"></td
+    ></tr
+    ><tr class="dijitReset"
+        ><td dojoAttachPoint="leftDecoration" class="dijitReset" style="text-align:center;height:100%;"></td
+        ><td class="dijitReset" style="height:100%;"
+            ><input dojoAttachPoint="valueNode" type="hidden" name="${name}"
+            /><center waiRole="presentation" style="position:relative;height:100%;" dojoAttachPoint="sliderBarContainer"
+                ><div waiRole="presentation" dojoAttachPoint="remainingBar" class="dijitSliderBar dijitSliderBarV dijitSliderRemainingBar dijitSliderRemainingBarV" dojoAttachEvent="onmousedown:_onRemainingBarClick"
+                    ><div dojoAttachPoint="sliderHandle" tabIndex="${tabIndex}" class="dijitSliderMoveable" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onHandleClick" style="vertical-align:top;" waiRole="slider" valuemin="${minimum}" valuemax="${maximum}"
+                        ><div class="dijitSliderImageHandle dijitSliderImageHandleV"></div
+                    ></div
+                    ><div waiRole="presentation" dojoAttachPoint="progressBar,focusNode" tabIndex="${tabIndex}" class="dijitSliderBar dijitSliderBarV dijitSliderProgressBar dijitSliderProgressBarV" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onBarClick"
+                    ></div
+                    ><div dojoAttachPoint="sliderHandleMax,focusNodeMax" tabIndex="${tabIndex}" class="dijitSliderMoveable" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onHandleClickMax" style="vertical-align:top;" waiRole="slider" valuemin="${minimum}" valuemax="${maximum}"
+                        ><div class="dijitSliderImageHandle dijitSliderImageHandleV"></div
+                    ></div
+                ></div
+            ></center
+        ></td
+        ><td dojoAttachPoint="containerNode,rightDecoration" class="dijitReset" style="text-align:center;height:100%;"></td
+    ></tr
+    ><tr class="dijitReset"
+        ><td class="dijitReset"></td
+        ><td class="dijitReset"
+            ><center><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperV dijitSliderBottomBumper dijitSliderBottomBumperV" dojoAttachEvent="onclick:_onClkDecBumper"></div></center
+        ></td
+        ><td class="dijitReset"></td
+    ></tr
+    ><tr class="dijitReset"
+        ><td class="dijitReset"></td
+        ><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerV"
+            ><div class="dijitSliderDecrementIconV" tabIndex="-1" style="display:none" dojoAttachPoint="decrementButton" dojoAttachEvent="onclick: decrement"><span class="dijitSliderButtonInner">-</span></div
+        ></td
+        ><td class="dijitReset"></td
+    ></tr
+></tbody></table>
diff --git a/dojox/form/resources/_CheckedMultiSelectItem.html b/dojox/form/resources/_CheckedMultiSelectItem.html
new file mode 100644
index 0000000..fd7f421
--- /dev/null
+++ b/dojox/form/resources/_CheckedMultiSelectItem.html
@@ -0,0 +1,5 @@
+<div class="dijitReset ${baseClass}"
+	><input class="${baseClass}Box" dojoType="dijit.form.CheckBox" dojoAttachPoint="checkBox" 
+		dojoAttachEvent="_onClick:_changeBox" type="${_type.type}" baseClass="${_type.baseClass}"
+	><div class="dijitInline ${baseClass}Label" dojoAttachPoint="labelNode" dojoAttachEvent="onmousedown:_onMouse,onmouseover:_onMouse,onmouseout:_onMouse,onclick:_onClick"></div
+></div>
diff --git a/dojox/form/resources/cLOG.php b/dojox/form/resources/cLOG.php
new file mode 100644
index 0000000..6a9a217
--- /dev/null
+++ b/dojox/form/resources/cLOG.php
@@ -0,0 +1,54 @@
+<?php
+//
+//	summary
+//		Creates/Opens files for logging data
+//		Useful for logging iinformation on a remote server
+//		when you don't have access to log files
+//		Also helpful for XHRs - since the page doesn't change
+//		to the PHP location which normally shows log data
+//		or errors.
+//
+//
+ class cLOG {
+	var $logfile;
+	var $boolTimestamp;
+	function cLOG($filename, $boolTimestamp){
+		$this->boolTimestamp = $boolTimestamp;
+		$this->logfile = $filename;
+	}
+	function write($txt){
+		if($this->boolTimestamp){
+			$dt = date("y.m.d G.i.s");
+			$txt = "[". $dt ."]: ".$txt;
+		}
+		$fh = fopen($this->logfile, "a");
+		if(is_array($txt)){
+			//$txt = "::::::::".$txt;
+			$ar = $txt;
+			$txt = "Array:::::\n";
+			foreach($ar as $key => $value){
+				$txt += $key."=".$value."\n";
+			}
+		}
+		fwrite($fh, $txt."\n");
+		fclose($fh);
+	}
+	function clear(){
+		$fh = fopen($this->logfile, "w");
+		fwrite($fh, "");
+		fclose($fh);
+	}
+	function newline(){
+		$fh = fopen($this->logfile, "a");
+		fwrite($fh, "\n\n");
+		fclose($fh);
+	}
+	function printr($ar){
+		$txt = "";
+		foreach ($ar as $nm => $val) {
+			$txt .= "    ".$nm ." = " . $val . "\n";
+		}
+		$this->write($txt);
+	}
+}
+?>
\ No newline at end of file
diff --git a/dojox/form/resources/images/loading_wheel.gif b/dojox/form/resources/images/loading_wheel.gif
new file mode 100644
index 0000000..901a7e3
Binary files /dev/null and b/dojox/form/resources/images/loading_wheel.gif differ
diff --git a/dojox/form/resources/images/nihiloFolderSprite.gif b/dojox/form/resources/images/nihiloFolderSprite.gif
new file mode 100644
index 0000000..0034b54
Binary files /dev/null and b/dojox/form/resources/images/nihiloFolderSprite.gif differ
diff --git a/dojox/form/resources/images/rating_empty.gif b/dojox/form/resources/images/rating_empty.gif
new file mode 100644
index 0000000..8662c43
Binary files /dev/null and b/dojox/form/resources/images/rating_empty.gif differ
diff --git a/dojox/form/resources/images/rating_full.gif b/dojox/form/resources/images/rating_full.gif
new file mode 100644
index 0000000..6fe24bf
Binary files /dev/null and b/dojox/form/resources/images/rating_full.gif differ
diff --git a/dojox/form/resources/images/soriaFolderSprite.gif b/dojox/form/resources/images/soriaFolderSprite.gif
new file mode 100644
index 0000000..19e35c1
Binary files /dev/null and b/dojox/form/resources/images/soriaFolderSprite.gif differ
diff --git a/dojox/form/resources/images/tundraFolderSprite.gif b/dojox/form/resources/images/tundraFolderSprite.gif
new file mode 100644
index 0000000..6cf8c09
Binary files /dev/null and b/dojox/form/resources/images/tundraFolderSprite.gif differ
diff --git a/dojox/form/resources/uploader.swf b/dojox/form/resources/uploader.swf
new file mode 100644
index 0000000..60d03f6
Binary files /dev/null and b/dojox/form/resources/uploader.swf differ
diff --git a/dojox/fx.js b/dojox/fx.js
new file mode 100644
index 0000000..d8003ad
--- /dev/null
+++ b/dojox/fx.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.fx"]){
+dojo._hasResource["dojox.fx"]=true;
+dojo.provide("dojox.fx");
+dojo.require("dojox.fx._base");
+}
diff --git a/dojox/fx/README b/dojox/fx/README
new file mode 100644
index 0000000..30bc90d
--- /dev/null
+++ b/dojox/fx/README
@@ -0,0 +1,75 @@
+-------------------------------------------------------------------------------
+dojox.fx
+-------------------------------------------------------------------------------
+Version 1.0.0
+Release date: 10/31/2007
+-------------------------------------------------------------------------------
+Project state:
+experimental 
+-------------------------------------------------------------------------------
+Credits
+	Peter Higgins (dante)
+	Jonathan Bond-Caron (jbondc at gmail.com)
+	Shane O'Sullivan (shaneosullivan1 at gmail.com)
+	Bryan Forbes (bforbes)
+	Nicola Rizzo (nic)
+
+-------------------------------------------------------------------------------
+Project description
+
+	dojox.fx provides a class of animation effects to use, and
+	other animation and Effects additions to dojo base.
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+	dojox.fx requires dojo (core) and the dojo.fx package
+	dojox.fx.easing is deprecated, and exists in dojo.fx.easing. 
+	dojox.fx.flip requires dojo.fx
+	dojox.fx.scroll requires dojox.fx._core and dojo.fx
+
+-------------------------------------------------------------------------------
+Documentation
+
+	existing API surface: 
+
+	dojox.fx._base:
+	- dojox.fx.crossFade - crossfade two nodes easily
+	- dojox.fx.sizeTo - size a node about it's center to a new width/height
+	- dojox.fx.slideBy - slide a node by a t,l offset
+	- dojox.fx.highlight - animates the background color of a node, and returns
+		it to the color it was. 
+
+	(all use standard _Animation properties, like duration, easing, node, etc)
+
+	dojox.fx._core:
+	- dojox.fx._Line - a multi-dimensional _Line implementation, backwards compatible with
+		dojo._Line ... you might could safely do something akin to
+		dojo._Line = dojox.fx._Line;
+		and enable this for all dojo _Animations?
+
+	dojox.fx.style: - experimental CSS animation via class definitions
+	- dojox.fx.addClass - animate the effects of applying a class to a node
+	- dojox.fx.removeClass - "   "    "    "   removing a class from a node
+	- dojox.fx.toggleClass - wrapper for addClass/removeClass
+
+	dojox.fx.ext-dojo.NodeList - extensions to dojo.NodeList-fx wrapping the
+		relevant dojox.fx animations into dojo.NodeList 
+
+	dojox.fx.Shadow - Class to add drop shadows to a node
+
+	dojox.fx.flip - a Module providing pseudo-3d flip animations for nodes.
+		Currently experimental. 
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/dojo/dojox/trunk/fx.js
+http://svn.dojotoolkit.org/dojo/dojox/trunk/fx/*
+
+Install into the following directory structure:
+/dojox/fx/
+
+...which should be at the same level as your Dojo checkout.
+-------------------------------------------------------------------------------
diff --git a/dojox/fx/Shadow.js b/dojox/fx/Shadow.js
new file mode 100644
index 0000000..64e08f6
--- /dev/null
+++ b/dojox/fx/Shadow.js
@@ -0,0 +1,119 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.fx.Shadow"]){
+dojo._hasResource["dojox.fx.Shadow"]=true;
+dojo.provide("dojox.fx.Shadow");
+dojo.experimental("dojox.fx.Shadow");
+dojo.require("dijit._Widget");
+dojo.require("dojo.NodeList-fx");
+dojo.declare("dojox.fx.Shadow",dijit._Widget,{shadowPng:dojo.moduleUrl("dojox.fx","resources/shadow"),shadowThickness:7,shadowOffset:3,opacity:0.75,animate:false,node:null,startup:function(){
+this.inherited(arguments);
+this.node.style.position="relative";
+this.pieces={};
+var x1=-1*this.shadowThickness;
+var y0=this.shadowOffset;
+var y1=this.shadowOffset+this.shadowThickness;
+this._makePiece("tl","top",y0,"left",x1);
+this._makePiece("l","top",y1,"left",x1,"scale");
+this._makePiece("tr","top",y0,"left",0);
+this._makePiece("r","top",y1,"left",0,"scale");
+this._makePiece("bl","top",0,"left",x1);
+this._makePiece("b","top",0,"left",0,"crop");
+this._makePiece("br","top",0,"left",0);
+this.nodeList=dojo.query(".shadowPiece",this.node);
+this.setOpacity(this.opacity);
+this.resize();
+},_makePiece:function(_4,_5,_6,_7,_8,_9){
+var _a;
+var _b=this.shadowPng+_4.toUpperCase()+".png";
+if(dojo.isIE<7){
+_a=dojo.create("div");
+_a.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+_b+"'"+(_9?", sizingMethod='"+_9+"'":"")+")";
+}else{
+_a=dojo.create("img",{src:_b});
+}
+_a.style.position="absolute";
+_a.style[_5]=_6+"px";
+_a.style[_7]=_8+"px";
+_a.style.width=this.shadowThickness+"px";
+_a.style.height=this.shadowThickness+"px";
+dojo.addClass(_a,"shadowPiece");
+this.pieces[_4]=_a;
+this.node.appendChild(_a);
+},setOpacity:function(n,_d){
+if(dojo.isIE){
+return;
+}
+if(!_d){
+_d={};
+}
+if(this.animate){
+var _e=[];
+this.nodeList.forEach(function(_f){
+_e.push(dojo._fade(dojo.mixin(_d,{node:_f,end:n})));
+});
+dojo.fx.combine(_e).play();
+}else{
+this.nodeList.style("opacity",n);
+}
+},setDisabled:function(_10){
+if(_10){
+if(this.disabled){
+return;
+}
+if(this.animate){
+this.nodeList.fadeOut().play();
+}else{
+this.nodeList.style("visibility","hidden");
+}
+this.disabled=true;
+}else{
+if(!this.disabled){
+return;
+}
+if(this.animate){
+this.nodeList.fadeIn().play();
+}else{
+this.nodeList.style("visibility","visible");
+}
+this.disabled=false;
+}
+},resize:function(_11){
+var x;
+var y;
+if(_11){
+x=_11.x;
+y=_11.y;
+}else{
+var co=dojo._getBorderBox(this.node);
+x=co.w;
+y=co.h;
+}
+var _15=y-(this.shadowOffset+this.shadowThickness);
+if(_15<0){
+_15=0;
+}
+if(y<1){
+y=1;
+}
+if(x<1){
+x=1;
+}
+with(this.pieces){
+l.style.height=_15+"px";
+r.style.height=_15+"px";
+b.style.width=x+"px";
+bl.style.top=y+"px";
+b.style.top=y+"px";
+br.style.top=y+"px";
+tr.style.left=x+"px";
+r.style.left=x+"px";
+br.style.left=x+"px";
+}
+}});
+}
diff --git a/dojox/fx/_arg.js b/dojox/fx/_arg.js
new file mode 100644
index 0000000..7dff984
--- /dev/null
+++ b/dojox/fx/_arg.js
@@ -0,0 +1,19 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.fx._arg"]){
+dojo._hasResource["dojox.fx._arg"]=true;
+dojo.provide("dojox.fx._arg");
+dojox.fx._arg.StyleArgs=function(_1){
+this.node=_1.node;
+this.cssClass=_1.cssClass;
+};
+dojox.fx._arg.ShadowResizeArgs=function(_2){
+this.x=_2.x;
+this.y=_2.y;
+};
+}
diff --git a/dojox/fx/_base.js b/dojox/fx/_base.js
new file mode 100644
index 0000000..444e0d2
--- /dev/null
+++ b/dojox/fx/_base.js
@@ -0,0 +1,122 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.fx._base"]){
+dojo._hasResource["dojox.fx._base"]=true;
+dojo.provide("dojox.fx._base");
+dojo.require("dojo.fx");
+dojo.mixin(dojox.fx,{anim:dojo.anim,animateProperty:dojo.animateProperty,fadeTo:dojo._fade,fadeIn:dojo.fadeIn,fadeOut:dojo.fadeOut,combine:dojo.fx.combine,chain:dojo.fx.chain,slideTo:dojo.fx.slideTo,wipeIn:dojo.fx.wipeIn,wipeOut:dojo.fx.wipeOut});
+dojox.fx.sizeTo=function(_1){
+var _2=_1.node=dojo.byId(_1.node);
+var _3=_1.method||"chain";
+if(!_1.duration){
+_1.duration=500;
+}
+if(_3=="chain"){
+_1.duration=Math.floor(_1.duration/2);
+}
+var _4,_5,_6,_7,_8,_9=null;
+var _a=(function(n){
+return function(){
+var cs=dojo.getComputedStyle(n);
+var _d=cs.position;
+_4=(_d=="absolute"?n.offsetTop:parseInt(cs.top)||0);
+_6=(_d=="absolute"?n.offsetLeft:parseInt(cs.left)||0);
+_8=parseInt(cs.width);
+_9=parseInt(cs.height);
+_7=_6-Math.floor((_1.width-_8)/2);
+_5=_4-Math.floor((_1.height-_9)/2);
+if(_d!="absolute"&&_d!="relative"){
+var _e=dojo.coords(n,true);
+_4=_e.y;
+_6=_e.x;
+n.style.position="absolute";
+n.style.top=_4+"px";
+n.style.left=_6+"px";
+}
+};
+})(_2);
+_a();
+var _f=dojo.animateProperty(dojo.mixin({properties:{height:{start:_9,end:_1.height||0,unit:"px"},top:{start:_4,end:_5}}},_1));
+var _10=dojo.animateProperty(dojo.mixin({properties:{width:{start:_8,end:_1.width||0,unit:"px"},left:{start:_6,end:_7}}},_1));
+var _11=dojo.fx[(_1.method=="combine"?"combine":"chain")]([_f,_10]);
+dojo.connect(_11,"beforeBegin",_11,_a);
+return _11;
+};
+dojox.fx.slideBy=function(_12){
+var _13=_12.node=dojo.byId(_12.node);
+var top=null;
+var _15=null;
+var _16=(function(n){
+return function(){
+var cs=dojo.getComputedStyle(n);
+var pos=cs.position;
+top=(pos=="absolute"?n.offsetTop:parseInt(cs.top)||0);
+_15=(pos=="absolute"?n.offsetLeft:parseInt(cs.left)||0);
+if(pos!="absolute"&&pos!="relative"){
+var ret=dojo.coords(n,true);
+top=ret.y;
+_15=ret.x;
+n.style.position="absolute";
+n.style.top=top+"px";
+n.style.left=_15+"px";
+}
+};
+})(_13);
+_16();
+var _1b=dojo.animateProperty(dojo.mixin({properties:{top:top+(_12.top||0),left:_15+(_12.left||0)}},_12));
+dojo.connect(_1b,"beforeBegin",_1b,_16);
+return _1b;
+};
+dojox.fx.crossFade=function(_1c){
+if(dojo.isArray(_1c.nodes)){
+var _1d=_1c.nodes[0]=dojo.byId(_1c.nodes[0]);
+var op1=dojo.style(_1d,"opacity");
+var _1f=_1c.nodes[1]=dojo.byId(_1c.nodes[1]);
+var op2=dojo.style(_1f,"opacity");
+var _21=dojo.fx.combine([dojo[(op1==0?"fadeIn":"fadeOut")](dojo.mixin({node:_1d},_1c)),dojo[(op1==0?"fadeOut":"fadeIn")](dojo.mixin({node:_1f},_1c))]);
+return _21;
+}else{
+return false;
+}
+};
+dojox.fx.highlight=function(_22){
+var _23=_22.node=dojo.byId(_22.node);
+_22.duration=_22.duration||400;
+var _24=_22.color||"#ffff99";
+var _25=dojo.style(_23,"backgroundColor");
+var _26=(_25=="transparent"||_25=="rgba(0, 0, 0, 0)")?_25:false;
+var _27=dojo.animateProperty(dojo.mixin({properties:{backgroundColor:{start:_24,end:_25}}},_22));
+if(_26){
+dojo.connect(_27,"onEnd",_27,function(){
+_23.style.backgroundColor=_26;
+});
+}
+return _27;
+};
+dojox.fx.wipeTo=function(_28){
+_28.node=dojo.byId(_28.node);
+var _29=_28.node,s=_29.style;
+var dir=(_28.width?"width":"height");
+var _2c=_28[dir];
+var _2d={};
+_2d[dir]={start:function(){
+s.overflow="hidden";
+if(s.visibility=="hidden"||s.display=="none"){
+s[dir]="1px";
+s.display="";
+s.visibility="";
+return 1;
+}else{
+var now=dojo.style(_29,dir);
+return Math.max(now,1);
+}
+},end:_2c,unit:"px"};
+var _2f=dojo.animateProperty(dojo.mixin({properties:_2d},_28));
+return _2f;
+};
+}
diff --git a/dojox/fx/_core.js b/dojox/fx/_core.js
new file mode 100644
index 0000000..5d49d5d
--- /dev/null
+++ b/dojox/fx/_core.js
@@ -0,0 +1,32 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.fx._core"]){
+dojo._hasResource["dojox.fx._core"]=true;
+dojo.provide("dojox.fx._core");
+dojox.fx._Line=function(_1,_2){
+this.start=_1;
+this.end=_2;
+var _3=dojo.isArray(_1),d=(_3?[]:_2-_1);
+if(_3){
+dojo.forEach(this.start,function(s,i){
+d[i]=this.end[i]-s;
+},this);
+this.getValue=function(n){
+var _8=[];
+dojo.forEach(this.start,function(s,i){
+_8[i]=(d[i]*n)+s;
+},this);
+return _8;
+};
+}else{
+this.getValue=function(n){
+return (d*n)+this.start;
+};
+}
+};
+}
diff --git a/dojox/fx/easing.js b/dojox/fx/easing.js
new file mode 100644
index 0000000..771eb4e
--- /dev/null
+++ b/dojox/fx/easing.js
@@ -0,0 +1,14 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.fx.easing"]){
+dojo._hasResource["dojox.fx.easing"]=true;
+dojo.provide("dojox.fx.easing");
+dojo.deprecated("dojox.fx.easing","Upgraded to Core, use dojo.fx.easing instead","2.0");
+dojo.require("dojo.fx.easing");
+dojox.fx.easing=dojo.fx.easing;
+}
diff --git a/dojox/fx/ext-dojo/NodeList.js b/dojox/fx/ext-dojo/NodeList.js
new file mode 100644
index 0000000..59e8265
--- /dev/null
+++ b/dojox/fx/ext-dojo/NodeList.js
@@ -0,0 +1,25 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.fx.ext-dojo.NodeList"]){
+dojo._hasResource["dojox.fx.ext-dojo.NodeList"]=true;
+dojo.provide("dojox.fx.ext-dojo.NodeList");
+dojo.experimental("dojox.fx.ext-dojo.NodeList");
+dojo.require("dojo.NodeList-fx");
+dojo.require("dojox.fx");
+dojo.extend(dojo.NodeList,{sizeTo:function(_1){
+return this._anim(dojox.fx,"sizeTo",_1);
+},slideBy:function(_2){
+return this._anim(dojox.fx,"slideBy",_2);
+},highlight:function(_3){
+return this._anim(dojox.fx,"highlight",_3);
+},fadeTo:function(_4){
+return this._anim(dojo,"_fade",_4);
+},wipeTo:function(_5){
+return this._anim(dojox.fx,"wipeTo",_5);
+}});
+}
diff --git a/dojox/fx/flip.js b/dojox/fx/flip.js
new file mode 100644
index 0000000..441fbfe
--- /dev/null
+++ b/dojox/fx/flip.js
@@ -0,0 +1,183 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.fx.flip"]){
+dojo._hasResource["dojox.fx.flip"]=true;
+dojo.provide("dojox.fx.flip");
+dojo.experimental("dojox.fx.flip");
+dojo.require("dojo.fx");
+(function(){
+var _1="border",_2="Width",_3="Height",_4="Top",_5="Right",_6="Left",_7="Bottom";
+dojox.fx.flip=function(_8){
+var _9=dojo.create("div"),_a=_8.node=dojo.byId(_8.node),s=_a.style,_c=null,hs=null,pn=null,_f=_8.lightColor||"#dddddd",_10=_8.darkColor||"#555555",_11=dojo.style(_a,"backgroundColor"),_12=_8.endColor||_11,_13={},_14=[],_15=_8.duration?_8.duration/2:250,dir=_8.dir||"left",_17=0.9,_18="transparent",_19=_8.whichAnim,_1a=_8.axis||"center",_1b=_8.depth;
+var _1c=function(_1d){
+return ((new dojo.Color(_1d)).toHex()==="#000000")?"#000001":_1d;
+};
+if(dojo.isIE<7){
+_12=_1c(_12);
+_f=_1c(_f);
+_10=_1c(_10);
+_11=_1c(_11);
+_18="black";
+_9.style.filter="chroma(color='#000000')";
+}
+var _1e=(function(n){
+return function(){
+var ret=dojo.coords(n,true);
+_c={top:ret.y,left:ret.x,width:ret.w,height:ret.h};
+};
+})(_a);
+_1e();
+hs={position:"absolute",top:_c["top"]+"px",left:_c["left"]+"px",height:"0",width:"0",zIndex:_8.zIndex||(s.zIndex||0),border:"0 solid "+_18,fontSize:"0",visibility:"hidden"};
+var _21=[{},{top:_c["top"],left:_c["left"]}];
+var _22={left:[_6,_5,_4,_7,_2,_3,"end"+_3+"Min",_6,"end"+_3+"Max"],right:[_5,_6,_4,_7,_2,_3,"end"+_3+"Min",_6,"end"+_3+"Max"],top:[_4,_7,_6,_5,_3,_2,"end"+_2+"Min",_4,"end"+_2+"Max"],bottom:[_7,_4,_6,_5,_3,_2,"end"+_2+"Min",_4,"end"+_2+"Max"]};
+pn=_22[dir];
+if(typeof _1b!="undefined"){
+_1b=Math.max(0,Math.min(1,_1b))/2;
+_17=0.4+(0.5-_1b);
+}else{
+_17=Math.min(0.9,Math.max(0.4,_c[pn[5].toLowerCase()]/_c[pn[4].toLowerCase()]));
+}
+var p0=_21[0];
+for(var i=4;i<6;i++){
+if(_1a=="center"||_1a=="cube"){
+_c["end"+pn[i]+"Min"]=_c[pn[i].toLowerCase()]*_17;
+_c["end"+pn[i]+"Max"]=_c[pn[i].toLowerCase()]/_17;
+}else{
+if(_1a=="shortside"){
+_c["end"+pn[i]+"Min"]=_c[pn[i].toLowerCase()];
+_c["end"+pn[i]+"Max"]=_c[pn[i].toLowerCase()]/_17;
+}else{
+if(_1a=="longside"){
+_c["end"+pn[i]+"Min"]=_c[pn[i].toLowerCase()]*_17;
+_c["end"+pn[i]+"Max"]=_c[pn[i].toLowerCase()];
+}
+}
+}
+}
+if(_1a=="center"){
+p0[pn[2].toLowerCase()]=_c[pn[2].toLowerCase()]-(_c[pn[8]]-_c[pn[6]])/4;
+}else{
+if(_1a=="shortside"){
+p0[pn[2].toLowerCase()]=_c[pn[2].toLowerCase()]-(_c[pn[8]]-_c[pn[6]])/2;
+}
+}
+_13[pn[5].toLowerCase()]=_c[pn[5].toLowerCase()]+"px";
+_13[pn[4].toLowerCase()]="0";
+_13[_1+pn[1]+_2]=_c[pn[4].toLowerCase()]+"px";
+_13[_1+pn[1]+"Color"]=_11;
+p0[_1+pn[1]+_2]=0;
+p0[_1+pn[1]+"Color"]=_10;
+p0[_1+pn[2]+_2]=p0[_1+pn[3]+_2]=_1a!="cube"?(_c["end"+pn[5]+"Max"]-_c["end"+pn[5]+"Min"])/2:_c[pn[6]]/2;
+p0[pn[7].toLowerCase()]=_c[pn[7].toLowerCase()]+_c[pn[4].toLowerCase()]/2+(_8.shift||0);
+p0[pn[5].toLowerCase()]=_c[pn[6]];
+var p1=_21[1];
+p1[_1+pn[0]+"Color"]={start:_f,end:_12};
+p1[_1+pn[0]+_2]=_c[pn[4].toLowerCase()];
+p1[_1+pn[2]+_2]=0;
+p1[_1+pn[3]+_2]=0;
+p1[pn[5].toLowerCase()]={start:_c[pn[6]],end:_c[pn[5].toLowerCase()]};
+dojo.mixin(hs,_13);
+dojo.style(_9,hs);
+dojo.body().appendChild(_9);
+var _26=function(){
+dojo.destroy(_9);
+s.backgroundColor=_12;
+s.visibility="visible";
+};
+if(_19=="last"){
+for(i in p0){
+p0[i]={start:p0[i]};
+}
+p0[_1+pn[1]+"Color"]={start:_10,end:_12};
+p1=p0;
+}
+if(!_19||_19=="first"){
+_14.push(dojo.animateProperty({node:_9,duration:_15,properties:p0}));
+}
+if(!_19||_19=="last"){
+_14.push(dojo.animateProperty({node:_9,duration:_15,properties:p1,onEnd:_26}));
+}
+dojo.connect(_14[0],"play",function(){
+_9.style.visibility="visible";
+s.visibility="hidden";
+});
+return dojo.fx.chain(_14);
+};
+dojox.fx.flipCube=function(_27){
+var _28=[],mb=dojo.marginBox(_27.node),_2a=mb.w/2,_2b=mb.h/2,_2c={top:{pName:"height",args:[{whichAnim:"first",dir:"top",shift:-_2b},{whichAnim:"last",dir:"bottom",shift:_2b}]},right:{pName:"width",args:[{whichAnim:"first",dir:"right",shift:_2a},{whichAnim:"last",dir:"left",shift:-_2a}]},bottom:{pName:"height",args:[{whichAnim:"first",dir:"bottom",shift:_2b},{whichAnim:"last",dir:"top",shift:-_2b}]},left:{pName:"width",args:[{whichAnim:"first",dir:"left",shift:-_2a},{whichAnim:"last",dir [...]
+var d=_2c[_27.dir||"left"],p=d.args;
+_27.duration=_27.duration?_27.duration*2:500;
+_27.depth=0.8;
+_27.axis="cube";
+for(var i=p.length-1;i>=0;i--){
+dojo.mixin(_27,p[i]);
+_28.push(dojox.fx.flip(_27));
+}
+return dojo.fx.combine(_28);
+};
+dojox.fx.flipPage=function(_30){
+var n=_30.node,_32=dojo.coords(n,true),x=_32.x,y=_32.y,w=_32.w,h=_32.h,_37=dojo.style(n,"backgroundColor"),_38=_30.lightColor||"#dddddd",_39=_30.darkColor,_3a=dojo.create("div"),_3b=[],hn=[],dir=_30.dir||"right",pn={left:["left","right","x","w"],top:["top","bottom","y","h"],right:["left","left","x","w"],bottom:["top","top","y","h"]},_3f={right:[1,-1],left:[-1,1],top:[-1,1],bottom:[1,-1]};
+dojo.style(_3a,{position:"absolute",width:w+"px",height:h+"px",top:y+"px",left:x+"px",visibility:"hidden"});
+var hs=[];
+for(var i=0;i<2;i++){
+var r=i%2,d=r?pn[dir][1]:dir,wa=r?"last":"first",_45=r?_37:_38,_46=r?_45:_30.startColor||n.style.backgroundColor;
+hn[i]=dojo.clone(_3a);
+var _47=function(x){
+return function(){
+dojo.destroy(hn[x]);
+};
+}(i);
+dojo.body().appendChild(hn[i]);
+hs[i]={backgroundColor:r?_46:_37};
+hs[i][pn[dir][0]]=_32[pn[dir][2]]+_3f[dir][0]*i*_32[pn[dir][3]]+"px";
+dojo.style(hn[i],hs[i]);
+_3b.push(dojox.fx.flip({node:hn[i],dir:d,axis:"shortside",depth:_30.depth,duration:_30.duration/2,shift:_3f[dir][i]*_32[pn[dir][3]]/2,darkColor:_39,lightColor:_38,whichAnim:wa,endColor:_45}));
+dojo.connect(_3b[i],"onEnd",_47);
+}
+return dojo.fx.chain(_3b);
+};
+dojox.fx.flipGrid=function(_49){
+var _4a=_49.rows||4,_4b=_49.cols||4,_4c=[],_4d=dojo.create("div"),n=_49.node,_4f=dojo.coords(n,true),x=_4f.x,y=_4f.y,nw=_4f.w,nh=_4f.h,w=_4f.w/_4b,h=_4f.h/_4a,_56=[];
+dojo.style(_4d,{position:"absolute",width:w+"px",height:h+"px",backgroundColor:dojo.style(n,"backgroundColor")});
+for(var i=0;i<_4a;i++){
+var r=i%2,d=r?"right":"left",_5a=r?1:-1;
+var cn=dojo.clone(n);
+dojo.style(cn,{position:"absolute",width:nw+"px",height:nh+"px",top:y+"px",left:x+"px",clip:"rect("+i*h+"px,"+nw+"px,"+nh+"px,0)"});
+dojo.body().appendChild(cn);
+_4c[i]=[];
+for(var j=0;j<_4b;j++){
+var hn=dojo.clone(_4d),l=r?j:_4b-(j+1);
+var _5f=function(xn,_61,_62){
+return function(){
+if(!(_61%2)){
+dojo.style(xn,{clip:"rect("+_61*h+"px,"+(nw-(_62+1)*w)+"px,"+((_61+1)*h)+"px,0px)"});
+}else{
+dojo.style(xn,{clip:"rect("+_61*h+"px,"+nw+"px,"+((_61+1)*h)+"px,"+((_62+1)*w)+"px)"});
+}
+};
+}(cn,i,j);
+dojo.body().appendChild(hn);
+dojo.style(hn,{left:x+l*w+"px",top:y+i*h+"px",visibility:"hidden"});
+var a=dojox.fx.flipPage({node:hn,dir:d,duration:_49.duration||900,shift:_5a*w/2,depth:0.2,darkColor:_49.darkColor,lightColor:_49.lightColor,startColor:_49.startColor||_49.node.style.backgroundColor}),_64=function(xn){
+return function(){
+dojo.destroy(xn);
+};
+}(hn);
+dojo.connect(a,"play",this,_5f);
+dojo.connect(a,"play",this,_64);
+_4c[i].push(a);
+}
+_56.push(dojo.fx.chain(_4c[i]));
+}
+dojo.connect(_56[0],"play",function(){
+dojo.style(n,{visibility:"hidden"});
+});
+return dojo.fx.combine(_56);
+};
+})();
+}
diff --git a/dojox/fx/resources/shadowB.png b/dojox/fx/resources/shadowB.png
new file mode 100644
index 0000000..0da8a2a
Binary files /dev/null and b/dojox/fx/resources/shadowB.png differ
diff --git a/dojox/fx/resources/shadowBL.png b/dojox/fx/resources/shadowBL.png
new file mode 100644
index 0000000..4926283
Binary files /dev/null and b/dojox/fx/resources/shadowBL.png differ
diff --git a/dojox/fx/resources/shadowBR.png b/dojox/fx/resources/shadowBR.png
new file mode 100644
index 0000000..ee704df
Binary files /dev/null and b/dojox/fx/resources/shadowBR.png differ
diff --git a/dojox/fx/resources/shadowL.png b/dojox/fx/resources/shadowL.png
new file mode 100644
index 0000000..67ebc2e
Binary files /dev/null and b/dojox/fx/resources/shadowL.png differ
diff --git a/dojox/fx/resources/shadowR.png b/dojox/fx/resources/shadowR.png
new file mode 100644
index 0000000..8d0c99d
Binary files /dev/null and b/dojox/fx/resources/shadowR.png differ
diff --git a/dojox/fx/resources/shadowT.png b/dojox/fx/resources/shadowT.png
new file mode 100644
index 0000000..ea99436
Binary files /dev/null and b/dojox/fx/resources/shadowT.png differ
diff --git a/dojox/fx/resources/shadowTL.png b/dojox/fx/resources/shadowTL.png
new file mode 100644
index 0000000..388742a
Binary files /dev/null and b/dojox/fx/resources/shadowTL.png differ
diff --git a/dojox/fx/resources/shadowTR.png b/dojox/fx/resources/shadowTR.png
new file mode 100644
index 0000000..c9d4f04
Binary files /dev/null and b/dojox/fx/resources/shadowTR.png differ
diff --git a/dojox/fx/scroll.js b/dojox/fx/scroll.js
new file mode 100644
index 0000000..178f1c7
--- /dev/null
+++ b/dojox/fx/scroll.js
@@ -0,0 +1,33 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.fx.scroll"]){
+dojo._hasResource["dojox.fx.scroll"]=true;
+dojo.provide("dojox.fx.scroll");
+dojo.experimental("dojox.fx.scroll");
+dojo.require("dojox.fx._core");
+dojox.fx.smoothScroll=function(_1){
+if(!_1.target){
+_1.target=dojo.coords(_1.node,true);
+}
+var _2=dojo[(dojo.isIE?"isObject":"isFunction")](_1["win"].scrollTo);
+var _3=(_2)?(function(_4){
+_1.win.scrollTo(_4[0],_4[1]);
+}):(function(_5){
+_1.win.scrollLeft=_5[0];
+_1.win.scrollTop=_5[1];
+});
+var _6=new dojo._Animation(dojo.mixin({beforeBegin:function(){
+if(this.curve){
+delete this.curve;
+}
+var _7=_2?dojo._docScroll():{x:_1.win.scrollLeft,y:_1.win.scrollTop};
+_6.curve=new dojox.fx._Line([_7.x,_7.y],[_1.target.x,_1.target.y]);
+},onAnimate:_3},_1));
+return _6;
+};
+}
diff --git a/dojox/fx/split.js b/dojox/fx/split.js
new file mode 100644
index 0000000..b780b8e
--- /dev/null
+++ b/dojox/fx/split.js
@@ -0,0 +1,317 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.fx.split"]){
+dojo._hasResource["dojox.fx.split"]=true;
+dojo.provide("dojox.fx.split");
+dojo.require("dojo.fx");
+dojo.require("dojo.fx.easing");
+dojo.mixin(dojox.fx,{_split:function(_1){
+_1.rows=_1.rows||3;
+_1.columns=_1.columns||3;
+_1.duration=_1.duration||1000;
+var _2=_1.node=dojo.byId(_1.node),_3=dojo.coords(_2,true),_4=Math.ceil(_3.h/_1.rows),_5=Math.ceil(_3.w/_1.columns),_6=dojo.create(_2.tagName),_7=[],_8=dojo.create(_2.tagName),_9;
+dojo.style(_6,{position:"absolute",padding:"0",margin:"0",border:"none",top:_3.y+"px",left:_3.x+"px",height:_3.h+"px",width:_3.w+"px",background:"none",overflow:_1.crop?"hidden":"visible"});
+_2.parentNode.appendChild(_6);
+dojo.style(_8,{position:"absolute",border:"none",padding:"0",margin:"0",height:_4+"px",width:_5+"px",overflow:"hidden"});
+for(var y=0;y<_1.rows;y++){
+for(var x=0;x<_1.columns;x++){
+_9=dojo.clone(_8);
+var _c=dojo.clone(_2);
+_c.style.filter="";
+dojo.style(_9,{border:"none",overflow:"hidden",top:(_4*y)+"px",left:(_5*x)+"px"});
+dojo.style(_c,{position:"static",opacity:"1",marginTop:(-y*_4)+"px",marginLeft:(-x*_5)+"px"});
+_9.appendChild(_c);
+_6.appendChild(_9);
+var _d=_1.pieceAnimation(_9,x,y,_3);
+if(dojo.isArray(_d)){
+_7=_7.concat(_d);
+}else{
+_7.push(_d);
+}
+}
+}
+var _e=dojo.fx.combine(_7);
+dojo.connect(_e,"onEnd",_e,function(){
+_6.parentNode.removeChild(_6);
+});
+if(_1.onPlay){
+dojo.connect(_e,"onPlay",_e,_1.onPlay);
+}
+if(_1.onEnd){
+dojo.connect(_e,"onEnd",_e,_1.onEnd);
+}
+return _e;
+},explode:function(_f){
+var _10=_f.node=dojo.byId(_f.node);
+_f.rows=_f.rows||3;
+_f.columns=_f.columns||3;
+_f.distance=_f.distance||1;
+_f.duration=_f.duration||1000;
+_f.random=_f.random||0;
+if(!_f.fade){
+_f.fade=true;
+}
+if(typeof _f.sync=="undefined"){
+_f.sync=true;
+}
+_f.random=Math.abs(_f.random);
+_f.pieceAnimation=function(_11,x,y,_14){
+var _15=_14.h/_f.rows,_16=_14.w/_f.columns,_17=_f.distance*2,_18=_f.duration,ps=_11.style,_1a=parseInt(ps.top),_1b=parseInt(ps.left),_1c=0,_1d=0,_1e=0;
+if(_f.random){
+var _1f=(Math.random()*_f.random)+Math.max(1-_f.random,0);
+_17*=_1f;
+_18*=_1f;
+_1c=((_f.unhide&&_f.sync)||(!_f.unhide&&!_f.sync))?(_f.duration-_18):0;
+_1d=Math.random()-0.5;
+_1e=Math.random()-0.5;
+}
+var _20=((_14.h-_15)/2-_15*y),_21=((_14.w-_16)/2-_16*x),_22=Math.sqrt(Math.pow(_21,2)+Math.pow(_20,2)),_23=parseInt(_1a-_20*_17+_22*_1e),_24=parseInt(_1b-_21*_17+_22*_1d);
+var _25=dojo.animateProperty({node:_11,duration:_18,delay:_1c,easing:(_f.easing||(_f.unhide?dojo.fx.easing.sinOut:dojo.fx.easing.circOut)),beforeBegin:(_f.unhide?function(){
+if(_f.fade){
+dojo.style(_11,{opacity:"0"});
+}
+ps.top=_23+"px";
+ps.left=_24+"px";
+}:undefined),properties:{top:(_f.unhide?{start:_23,end:_1a}:{start:_1a,end:_23}),left:(_f.unhide?{start:_24,end:_1b}:{start:_1b,end:_24})}});
+if(_f.fade){
+var _26=dojo.animateProperty({node:_11,duration:_18,delay:_1c,easing:(_f.fadeEasing||dojo.fx.easing.quadOut),properties:{opacity:(_f.unhide?{start:"0",end:"1"}:{start:"1",end:"0"})}});
+return (_f.unhide?[_26,_25]:[_25,_26]);
+}else{
+return _25;
+}
+};
+var _27=dojox.fx._split(_f);
+if(_f.unhide){
+dojo.connect(_27,"onEnd",null,function(){
+dojo.style(_10,{opacity:"1"});
+});
+}else{
+dojo.connect(_27,"onPlay",null,function(){
+dojo.style(_10,{opacity:"0"});
+});
+}
+return _27;
+},converge:function(_28){
+_28.unhide=true;
+return dojox.fx.explode(_28);
+},disintegrate:function(_29){
+var _2a=_29.node=dojo.byId(_29.node);
+_29.rows=_29.rows||5;
+_29.columns=_29.columns||5;
+_29.duration=_29.duration||1500;
+_29.interval=_29.interval||_29.duration/(_29.rows+_29.columns*2);
+_29.distance=_29.distance||1.5;
+_29.random=_29.random||0;
+if(typeof _29.fade=="undefined"){
+_29.fade=true;
+}
+var _2b=Math.abs(_29.random),_2c=_29.duration-(_29.rows+_29.columns)*_29.interval;
+_29.pieceAnimation=function(_2d,x,y,_30){
+var _31=Math.random()*(_29.rows+_29.columns)*_29.interval,ps=_2d.style,_33=(_29.reverseOrder||_29.distance<0)?((x+y)*_29.interval):(((_29.rows+_29.columns)-(x+y))*_29.interval),_34=_31*_2b+Math.max(1-_2b,0)*_33,_35={};
+if(_29.unhide){
+_35.top={start:(parseInt(ps.top)-_30.h*_29.distance),end:parseInt(ps.top)};
+if(_29.fade){
+_35.opacity={start:"0",end:"1"};
+}
+}else{
+_35.top={end:(parseInt(ps.top)+_30.h*_29.distance)};
+if(_29.fade){
+_35.opacity={end:"0"};
+}
+}
+var _36=dojo.animateProperty({node:_2d,duration:_2c,delay:_34,easing:(_29.easing||(_29.unhide?dojo.fx.easing.sinIn:dojo.fx.easing.circIn)),properties:_35,beforeBegin:(_29.unhide?function(){
+if(_29.fade){
+dojo.style(_2d,{opacity:"0"});
+}
+ps.top=_35.top.start+"px";
+}:undefined)});
+return _36;
+};
+var _37=dojox.fx._split(_29);
+if(_29.unhide){
+dojo.connect(_37,"onEnd",_37,function(){
+dojo.style(_2a,{opacity:"1"});
+});
+}else{
+dojo.connect(_37,"onPlay",_37,function(){
+dojo.style(_2a,{opacity:"0"});
+});
+}
+return _37;
+},build:function(_38){
+_38.unhide=true;
+return dojox.fx.disintegrate(_38);
+},shear:function(_39){
+var _3a=_39.node=dojo.byId(_39.node);
+_39.rows=_39.rows||6;
+_39.columns=_39.columns||6;
+_39.duration=_39.duration||1000;
+_39.interval=_39.interval||0;
+_39.distance=_39.distance||1;
+_39.random=_39.random||0;
+if(typeof (_39.fade)=="undefined"){
+_39.fade=true;
+}
+var _3b=Math.abs(_39.random),_3c=(_39.duration-(_39.rows+_39.columns)*Math.abs(_39.interval));
+_39.pieceAnimation=function(_3d,x,y,_40){
+var _41=!(x%2),_42=!(y%2),_43=Math.random()*_3c,_44=(_39.reverseOrder)?(((_39.rows+_39.columns)-(x+y))*_39.interval):((x+y)*_39.interval),_45=_43*_3b+Math.max(1-_3b,0)*_44,_46={},ps=_3d.style;
+if(_39.fade){
+_46.opacity=(_39.unhide?{start:"0",end:"1"}:{end:"0"});
+}
+if(_39.columns==1){
+_41=_42;
+}else{
+if(_39.rows==1){
+_42=!_41;
+}
+}
+var _48=parseInt(ps.left),top=parseInt(ps.top),_4a=_39.distance*_40.w,_4b=_39.distance*_40.h;
+if(_39.unhide){
+if(_41==_42){
+_46.left=_41?{start:(_48-_4a),end:_48}:{start:(_48+_4a),end:_48};
+}else{
+_46.top=_41?{start:(top+_4b),end:top}:{start:(top-_4b),end:top};
+}
+}else{
+if(_41==_42){
+_46.left=_41?{end:(_48-_4a)}:{end:(_48+_4a)};
+}else{
+_46.top=_41?{end:(top+_4b)}:{end:(top-_4b)};
+}
+}
+var _4c=dojo.animateProperty({node:_3d,duration:_3c,delay:_45,easing:(_39.easing||dojo.fx.easing.sinInOut),properties:_46,beforeBegin:(_39.unhide?function(){
+if(_39.fade){
+ps.opacity="0";
+}
+if(_41==_42){
+ps.left=_46.left.start+"px";
+}else{
+ps.top=_46.top.start+"px";
+}
+}:undefined)});
+return _4c;
+};
+var _4d=dojox.fx._split(_39);
+if(_39.unhide){
+dojo.connect(_4d,"onEnd",_4d,function(){
+dojo.style(_3a,{opacity:"1"});
+});
+}else{
+dojo.connect(_4d,"onPlay",_4d,function(){
+dojo.style(_3a,{opacity:"0"});
+});
+}
+return _4d;
+},unShear:function(_4e){
+_4e.unhide=true;
+return dojox.fx.shear(_4e);
+},pinwheel:function(_4f){
+var _50=_4f.node=dojo.byId(_4f.node);
+_4f.rows=_4f.rows||4;
+_4f.columns=_4f.columns||4;
+_4f.duration=_4f.duration||1000;
+_4f.interval=_4f.interval||0;
+_4f.distance=_4f.distance||1;
+_4f.random=_4f.random||0;
+if(typeof _4f.fade=="undefined"){
+_4f.fade=true;
+}
+var _51=(_4f.duration-(_4f.rows+_4f.columns)*Math.abs(_4f.interval));
+_4f.pieceAnimation=function(_52,x,y,_55){
+var _56=_55.h/_4f.rows,_57=_55.w/_4f.columns,_58=!(x%2),_59=!(y%2),_5a=Math.random()*_51,_5b=(_4f.interval<0)?(((_4f.rows+_4f.columns)-(x+y))*_4f.interval*-1):((x+y)*_4f.interval),_5c=_5a*_4f.random+Math.max(1-_4f.random,0)*_5b,_5d={},ps=_52.style;
+if(_4f.fade){
+_5d.opacity=(_4f.unhide?{start:0,end:1}:{end:0});
+}
+if(_4f.columns==1){
+_58=!_59;
+}else{
+if(_4f.rows==1){
+_59=_58;
+}
+}
+var _5f=parseInt(ps.left),top=parseInt(ps.top);
+if(_58){
+if(_59){
+_5d.top=_4f.unhide?{start:top+_56*_4f.distance,end:top}:{start:top,end:top+_56*_4f.distance};
+}else{
+_5d.left=_4f.unhide?{start:_5f+_57*_4f.distance,end:_5f}:{start:_5f,end:_5f+_57*_4f.distance};
+}
+}
+if(_58!=_59){
+_5d.width=_4f.unhide?{start:_57*(1-_4f.distance),end:_57}:{start:_57,end:_57*(1-_4f.distance)};
+}else{
+_5d.height=_4f.unhide?{start:_56*(1-_4f.distance),end:_56}:{start:_56,end:_56*(1-_4f.distance)};
+}
+var _61=dojo.animateProperty({node:_52,duration:_51,delay:_5c,easing:(_4f.easing||dojo.fx.easing.sinInOut),properties:_5d,beforeBegin:(_4f.unhide?function(){
+if(_4f.fade){
+dojo.style(_52,"opacity",0);
+}
+if(_58){
+if(_59){
+ps.top=(top+_56*(1-_4f.distance))+"px";
+}else{
+ps.left=(_5f+_57*(1-_4f.distance))+"px";
+}
+}else{
+ps.left=_5f+"px";
+ps.top=top+"px";
+}
+if(_58!=_59){
+ps.width=(_57*(1-_4f.distance))+"px";
+}else{
+ps.height=(_56*(1-_4f.distance))+"px";
+}
+}:undefined)});
+return _61;
+};
+var _62=dojox.fx._split(_4f);
+if(_4f.unhide){
+dojo.connect(_62,"onEnd",_62,function(){
+dojo.style(_50,{opacity:"1"});
+});
+}else{
+dojo.connect(_62,"play",_62,function(){
+dojo.style(_50,{opacity:"0"});
+});
+}
+return _62;
+},unPinwheel:function(_63){
+_63.unhide=true;
+return dojox.fx.pinwheel(_63);
+},blockFadeOut:function(_64){
+var _65=_64.node=dojo.byId(_64.node);
+_64.rows=_64.rows||5;
+_64.columns=_64.columns||5;
+_64.duration=_64.duration||1000;
+_64.interval=_64.interval||_64.duration/(_64.rows+_64.columns*2);
+_64.random=_64.random||0;
+var _66=Math.abs(_64.random),_67=_64.duration-(_64.rows+_64.columns)*_64.interval;
+_64.pieceAnimation=function(_68,x,y,_6b){
+var _6c=Math.random()*_64.duration,_6d=(_64.reverseOrder)?(((_64.rows+_64.columns)-(x+y))*Math.abs(_64.interval)):((x+y)*_64.interval),_6e=_6c*_66+Math.max(1-_66,0)*_6d,_6f=dojo.animateProperty({node:_68,duration:_67,delay:_6e,easing:(_64.easing||dojo.fx.easing.sinInOut),properties:{opacity:(_64.unhide?{start:"0",end:"1"}:{start:"1",end:"0"})},beforeBegin:(_64.unhide?function(){
+dojo.style(_68,{opacity:"0"});
+}:function(){
+_68.style.filter="";
+})});
+return _6f;
+};
+var _70=dojox.fx._split(_64);
+if(_64.unhide){
+dojo.connect(_70,"onEnd",_70,function(){
+dojo.style(_65,{opacity:"1"});
+});
+}else{
+dojo.connect(_70,"onPlay",_70,function(){
+dojo.style(_65,{opacity:"0"});
+});
+}
+return _70;
+},blockFadeIn:function(_71){
+_71.unhide=true;
+return dojox.fx.blockFadeOut(_71);
+}});
+}
diff --git a/dojox/fx/style.js b/dojox/fx/style.js
new file mode 100644
index 0000000..dd01310
--- /dev/null
+++ b/dojox/fx/style.js
@@ -0,0 +1,69 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.fx.style"]){
+dojo._hasResource["dojox.fx.style"]=true;
+dojo.provide("dojox.fx.style");
+dojo.experimental("dojox.fx.style");
+dojo.require("dojo.fx");
+(function(){
+var d=dojo;
+var _2=function(_3){
+return d.map(dojox.fx._allowedProperties,function(_4){
+return _3[_4];
+});
+};
+var _5=function(_6,_7){
+var _8=_6.node=d.byId(_6.node);
+var cs=d.getComputedStyle(_8);
+var _a=_2(cs);
+d[(_7?"addClass":"removeClass")](_8,_6.cssClass);
+var _b=_2(cs);
+d[(_7?"removeClass":"addClass")](_8,_6.cssClass);
+var _c={},i=0;
+d.forEach(dojox.fx._allowedProperties,function(_e){
+if(_a[i]!=_b[i]){
+_c[_e]=parseInt(_b[i]);
+}
+i++;
+});
+return _c;
+};
+d.mixin(dojox.fx,{addClass:function(_f){
+var _10=_f.node=d.byId(_f.node);
+var _11=(function(n){
+return function(){
+d.addClass(n,_f.cssClass);
+n.style.cssText=_13;
+};
+})(_10);
+var _14=_5(_f,true);
+var _13=_10.style.cssText;
+var _15=d.animateProperty(d.mixin({properties:_14},_f));
+d.connect(_15,"onEnd",_15,_11);
+return _15;
+},removeClass:function(_16){
+var _17=(_16.node=dojo.byId(_16.node));
+var _18=(function(n){
+return function(){
+d.removeClass(n,_16.cssClass);
+n.style.cssText=_1a;
+};
+})(_17);
+var _1b=_5(_16,false);
+var _1a=_17.style.cssText;
+var _1c=d.animateProperty(d.mixin({properties:_1b},_16));
+d.connect(_1c,"onEnd",_1c,_18);
+return _1c;
+},toggleClass:function(_1d,_1e,_1f){
+if(typeof _1f=="undefined"){
+_1f=!d.hasClass(_1d,_1e);
+}
+return dojox.fx[(_1f?"addClass":"removeClass")]({node:_1d,cssClass:_1e});
+},_allowedProperties:["width","height","left","top","backgroundColor","color","borderBottomWidth","borderTopWidth","borderLeftWidth","borderRightWidth","paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginTop","marginRight","marginBottom","lineHeight","letterSpacing","fontSize"]});
+})();
+}
diff --git a/dojox/fx/text.js b/dojox/fx/text.js
new file mode 100644
index 0000000..54def74
--- /dev/null
+++ b/dojox/fx/text.js
@@ -0,0 +1,256 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.fx.text"]){
+dojo._hasResource["dojox.fx.text"]=true;
+dojo.provide("dojox.fx.text");
+dojo.require("dojo.fx");
+dojo.require("dojo.fx.easing");
+dojox.fx.text._split=function(_1){
+var _2=_1.node=dojo.byId(_1.node),s=_2.style,cs=dojo.getComputedStyle(_2),_5=dojo.coords(_2,true);
+_1.duration=_1.duration||1000;
+_1.words=_1.words||false;
+var _6=(_1.text&&typeof (_1.text)=="string")?_1.text:_2.innerHTML,_7=s.height,_8=s.width,_9=[];
+dojo.style(_2,{height:cs.height,width:cs.width});
+var _a=/(<\/?\w+((\s+\w+(\s*=\s*(?:".*?"|'.*?'|[^'">\s]+))?)+\s*|\s*)\/?>)/g;
+var _b=(_1.words?/(<\/?\w+((\s+\w+(\s*=\s*(?:".*?"|'.*?'|[^'">\s]+))?)+\s*|\s*)\/?>)\s*|([^\s<]+\s*)/g:/(<\/?\w+((\s+\w+(\s*=\s*(?:".*?"|'.*?'|[^'">\s]+))?)+\s*|\s*)\/?>)\s*|([^\s<]\s*)/g);
+var _c=(typeof _1.text=="string")?_1.text.match(_b):_2.innerHTML.match(_b);
+var _d="";
+var _e=0;
+var _f=0;
+for(var i=0;i<_c.length;i++){
+var _11=_c[i];
+if(!_11.match(_a)){
+_d+="<span>"+_11+"</span>";
+_e++;
+}else{
+_d+=_11;
+}
+}
+_2.innerHTML=_d;
+function _12(_13){
+var _14=_13.nextSibling;
+if(_13.tagName=="SPAN"&&_13.childNodes.length==1&&_13.firstChild.nodeType==3){
+var _15=dojo.coords(_13,true);
+_f++;
+dojo.style(_13,{padding:0,margin:0,top:(_1.crop?"0px":_15.t+"px"),left:(_1.crop?"0px":_15.l+"px"),display:"inline"});
+var _16=_1.pieceAnimation(_13,_15,_5,_f,_e);
+if(dojo.isArray(_16)){
+_9=_9.concat(_16);
+}else{
+_9[_9.length]=_16;
+}
+}else{
+if(_13.firstChild){
+_12(_13.firstChild);
+}
+}
+if(_14){
+_12(_14);
+}
+};
+_12(_2.firstChild);
+var _17=dojo.fx.combine(_9);
+dojo.connect(_17,"onEnd",_17,function(){
+_2.innerHTML=_6;
+dojo.style(_2,{height:_7,width:_8});
+});
+if(_1.onPlay){
+dojo.connect(_17,"onPlay",_17,_1.onPlay);
+}
+if(_1.onEnd){
+dojo.connect(_17,"onEnd",_17,_1.onEnd);
+}
+return _17;
+};
+dojox.fx.text.explode=function(_18){
+var _19=_18.node=dojo.byId(_18.node);
+var s=_19.style;
+_18.distance=_18.distance||1;
+_18.duration=_18.duration||1000;
+_18.random=_18.random||0;
+if(typeof (_18.fade)=="undefined"){
+_18.fade=true;
+}
+if(typeof (_18.sync)=="undefined"){
+_18.sync=true;
+}
+_18.random=Math.abs(_18.random);
+_18.pieceAnimation=function(_1b,_1c,_1d,_1e,_1f){
+var _20=_1c.h;
+var _21=_1c.w;
+var _22=_18.distance*2;
+var _23=_18.duration;
+var _24=parseFloat(_1b.style.top);
+var _25=parseFloat(_1b.style.left);
+var _26=0;
+var _27=0;
+var _28=0;
+if(_18.random){
+var _29=(Math.random()*_18.random)+Math.max(1-_18.random,0);
+_22*=_29;
+_23*=_29;
+_26=((_18.unhide&&_18.sync)||(!_18.unhide&&!_18.sync))?(_18.duration-_23):0;
+_27=Math.random()-0.5;
+_28=Math.random()-0.5;
+}
+var _2a=((_1d.h-_20)/2-(_1c.y-_1d.y));
+var _2b=((_1d.w-_21)/2-(_1c.x-_1d.x));
+var _2c=Math.sqrt(Math.pow(_2b,2)+Math.pow(_2a,2));
+var _2d=_24-_2a*_22+_2c*_28;
+var _2e=_25-_2b*_22+_2c*_27;
+var _2f=dojo.animateProperty({node:_1b,duration:_23,delay:_26,easing:(_18.easing||(_18.unhide?dojo.fx.easing.sinOut:dojo.fx.easing.circOut)),beforeBegin:(_18.unhide?function(){
+if(_18.fade){
+dojo.style(_1b,"opacity",0);
+}
+_1b.style.position=_18.crop?"relative":"absolute";
+_1b.style.top=_2d+"px";
+_1b.style.left=_2e+"px";
+}:function(){
+_1b.style.position=_18.crop?"relative":"absolute";
+}),properties:{top:(_18.unhide?{start:_2d,end:_24}:{start:_24,end:_2d}),left:(_18.unhide?{start:_2e,end:_25}:{start:_25,end:_2e})}});
+if(_18.fade){
+var _30=dojo.animateProperty({node:_1b,duration:_23,delay:_26,easing:(_18.fadeEasing||dojo.fx.easing.quadOut),properties:{opacity:(_18.unhide?{start:0,end:1}:{end:0})}});
+return (_18.unhide?[_30,_2f]:[_2f,_30]);
+}else{
+return _2f;
+}
+};
+var _31=dojox.fx.text._split(_18);
+return _31;
+};
+dojox.fx.text.converge=function(_32){
+_32.unhide=true;
+return dojox.fx.text.explode(_32);
+};
+dojox.fx.text.disintegrate=function(_33){
+var _34=_33.node=dojo.byId(_33.node);
+var s=_34.style;
+_33.duration=_33.duration||1500;
+_33.distance=_33.distance||1.5;
+_33.random=_33.random||0;
+if(!_33.fade){
+_33.fade=true;
+}
+var _36=Math.abs(_33.random);
+_33.pieceAnimation=function(_37,_38,_39,_3a,_3b){
+var _3c=_38.h;
+var _3d=_38.w;
+var _3e=_33.interval||(_33.duration/(1.5*_3b));
+var _3f=(_33.duration-_3b*_3e);
+var _40=Math.random()*_3b*_3e;
+var _41=(_33.reverseOrder||_33.distance<0)?(_3a*_3e):((_3b-_3a)*_3e);
+var _42=_40*_36+Math.max(1-_36,0)*_41;
+var _43={};
+if(_33.unhide){
+_43.top={start:(parseFloat(_37.style.top)-_39.h*_33.distance),end:parseFloat(_37.style.top)};
+if(_33.fade){
+_43.opacity={start:0,end:1};
+}
+}else{
+_43.top={end:(parseFloat(_37.style.top)+_39.h*_33.distance)};
+if(_33.fade){
+_43.opacity={end:0};
+}
+}
+var _44=dojo.animateProperty({node:_37,duration:_3f,delay:_42,easing:(_33.easing||(_33.unhide?dojo.fx.easing.sinIn:dojo.fx.easing.circIn)),properties:_43,beforeBegin:(_33.unhide?function(){
+if(_33.fade){
+dojo.style(_37,"opacity",0);
+}
+_37.style.position=_33.crop?"relative":"absolute";
+_37.style.top=_43.top.start+"px";
+}:function(){
+_37.style.position=_33.crop?"relative":"absolute";
+})});
+return _44;
+};
+var _45=dojox.fx.text._split(_33);
+return _45;
+};
+dojox.fx.text.build=function(_46){
+_46.unhide=true;
+return dojox.fx.text.disintegrate(_46);
+};
+dojox.fx.text.blockFadeOut=function(_47){
+var _48=_47.node=dojo.byId(_47.node);
+var s=_48.style;
+_47.duration=_47.duration||1000;
+_47.random=_47.random||0;
+var _4a=Math.abs(_47.random);
+_47.pieceAnimation=function(_4b,_4c,_4d,_4e,_4f){
+var _50=_47.interval||(_47.duration/(1.5*_4f));
+var _51=(_47.duration-_4f*_50);
+var _52=Math.random()*_4f*_50;
+var _53=(_47.reverseOrder)?((_4f-_4e)*_50):(_4e*_50);
+var _54=_52*_4a+Math.max(1-_4a,0)*_53;
+var _55=dojo.animateProperty({node:_4b,duration:_51,delay:_54,easing:(_47.easing||dojo.fx.easing.sinInOut),properties:{opacity:(_47.unhide?{start:0,end:1}:{end:0})},beforeBegin:(_47.unhide?function(){
+dojo.style(_4b,"opacity",0);
+}:undefined)});
+return _55;
+};
+var _56=dojox.fx.text._split(_47);
+return _56;
+};
+dojox.fx.text.blockFadeIn=function(_57){
+_57.unhide=true;
+return dojox.fx.text.blockFadeOut(_57);
+};
+dojox.fx.text.backspace=function(_58){
+var _59=_58.node=dojo.byId(_58.node);
+var s=_59.style;
+_58.words=false;
+_58.duration=_58.duration||2000;
+_58.random=_58.random||0;
+var _5b=Math.abs(_58.random);
+var _5c=10;
+_58.pieceAnimation=function(_5d,_5e,_5f,_60,_61){
+var _62=_58.interval||(_58.duration/(1.5*_61));
+var _63=_5d.textContent;
+var _64=_63.match(/\s/g);
+if(typeof (_58.wordDelay)=="undefined"){
+_58.wordDelay=_62*2;
+}
+if(!_58.unhide){
+_5c=(_61-_60-1)*_62;
+}
+var _65,_66;
+if(_58.fixed){
+if(_58.unhide){
+var _65=function(){
+dojo.style(_5d,"opacity",0);
+};
+}
+}else{
+if(_58.unhide){
+var _65=function(){
+_5d.style.display="none";
+};
+var _66=function(){
+_5d.style.display="inline";
+};
+}else{
+var _66=function(){
+_5d.style.display="none";
+};
+}
+}
+var _67=dojo.animateProperty({node:_5d,duration:1,delay:_5c,easing:(_58.easing||dojo.fx.easing.sinInOut),properties:{opacity:(_58.unhide?{start:0,end:1}:{end:0})},beforeBegin:_65,onEnd:_66});
+if(_58.unhide){
+var _68=Math.random()*_63.length*_62;
+var _69=_68*_5b/2+Math.max(1-_5b/2,0)*_58.wordDelay;
+_5c+=_68*_5b+Math.max(1-_5b,0)*_62*_63.length+(_69*(_64&&_63.lastIndexOf(_64[_64.length-1])==_63.length-1));
+}
+return _67;
+};
+var _6a=dojox.fx.text._split(_58);
+return _6a;
+};
+dojox.fx.text.type=function(_6b){
+_6b.unhide=true;
+return dojox.fx.text.backspace(_6b);
+};
+}
diff --git a/dojox/gfx.js b/dojox/gfx.js
new file mode 100644
index 0000000..b32ebf6
--- /dev/null
+++ b/dojox/gfx.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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 a compiled version of Dojo, built for deployment and not for
+	development. To get an editable version, please visit:
+
+		http://dojotoolkit.org
+
+	for documentation and information on getting the source.
+*/
+
+if(!dojo._hasResource["dojox.gfx.matrix"]){dojo._hasResource["dojox.gfx.matrix"]=true;dojo.provide("dojox.gfx.matrix");(function(){var m=dojox.gfx.matrix;var _2={};m._degToRad=function(_3){return _2[_3]||(_2[_3]=(Math.PI*_3/180));};m._radToDeg=function(_4){return _4/Math.PI*180;};m.Matrix2D=function(_5){if(_5){if(typeof _5=="number"){this.xx=this.yy=_5;}else{if(_5 instanceof Array){if(_5.length>0){var _6=m.normalize(_5[0]);for(var i=1;i<_5.length;++i){var l=_6,r=dojox.gfx.matrix.normaliz [...]
diff --git a/dojox/gfx.js.uncompressed.js b/dojox/gfx.js.uncompressed.js
new file mode 100644
index 0000000..90d0f29
--- /dev/null
+++ b/dojox/gfx.js.uncompressed.js
@@ -0,0 +1,926 @@
+/*
+	Copyright (c) 2004-2009, 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 a compiled version of Dojo, built for deployment and not for
+	development. To get an editable version, please visit:
+
+		http://dojotoolkit.org
+
+	for documentation and information on getting the source.
+*/
+
+if(!dojo._hasResource["dojox.gfx.matrix"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.matrix"] = true;
+dojo.provide("dojox.gfx.matrix");
+
+(function(){
+	var m = dojox.gfx.matrix;
+
+	// candidates for dojox.math:
+	var _degToRadCache = {};
+	m._degToRad = function(degree){
+		return _degToRadCache[degree] || (_degToRadCache[degree] = (Math.PI * degree / 180));
+	};
+	m._radToDeg = function(radian){ return radian / Math.PI * 180; };
+
+	m.Matrix2D = function(arg){
+		// summary: a 2D matrix object
+		// description: Normalizes a 2D matrix-like object. If arrays is passed,
+		//		all objects of the array are normalized and multiplied sequentially.
+		// arg: Object
+		//		a 2D matrix-like object, a number, or an array of such objects
+		if(arg){
+			if(typeof arg == "number"){
+				this.xx = this.yy = arg;
+			}else if(arg instanceof Array){
+				if(arg.length > 0){
+					var matrix = m.normalize(arg[0]);
+					// combine matrices
+					for(var i = 1; i < arg.length; ++i){
+						var l = matrix, r = dojox.gfx.matrix.normalize(arg[i]);
+						matrix = new m.Matrix2D();
+						matrix.xx = l.xx * r.xx + l.xy * r.yx;
+						matrix.xy = l.xx * r.xy + l.xy * r.yy;
+						matrix.yx = l.yx * r.xx + l.yy * r.yx;
+						matrix.yy = l.yx * r.xy + l.yy * r.yy;
+						matrix.dx = l.xx * r.dx + l.xy * r.dy + l.dx;
+						matrix.dy = l.yx * r.dx + l.yy * r.dy + l.dy;
+					}
+					dojo.mixin(this, matrix);
+				}
+			}else{
+				dojo.mixin(this, arg);
+			}
+		}
+	};
+
+	// the default (identity) matrix, which is used to fill in missing values
+	dojo.extend(m.Matrix2D, {xx: 1, xy: 0, yx: 0, yy: 1, dx: 0, dy: 0});
+
+	dojo.mixin(m, {
+		// summary: class constants, and methods of dojox.gfx.matrix
+
+		// matrix constants
+
+		// identity: dojox.gfx.matrix.Matrix2D
+		//		an identity matrix constant: identity * (x, y) == (x, y)
+		identity: new m.Matrix2D(),
+
+		// flipX: dojox.gfx.matrix.Matrix2D
+		//		a matrix, which reflects points at x = 0 line: flipX * (x, y) == (-x, y)
+		flipX:    new m.Matrix2D({xx: -1}),
+
+		// flipY: dojox.gfx.matrix.Matrix2D
+		//		a matrix, which reflects points at y = 0 line: flipY * (x, y) == (x, -y)
+		flipY:    new m.Matrix2D({yy: -1}),
+
+		// flipXY: dojox.gfx.matrix.Matrix2D
+		//		a matrix, which reflects points at the origin of coordinates: flipXY * (x, y) == (-x, -y)
+		flipXY:   new m.Matrix2D({xx: -1, yy: -1}),
+
+		// matrix creators
+
+		translate: function(a, b){
+			// summary: forms a translation matrix
+			// description: The resulting matrix is used to translate (move) points by specified offsets.
+			// a: Number: an x coordinate value
+			// b: Number: a y coordinate value
+			if(arguments.length > 1){
+				return new m.Matrix2D({dx: a, dy: b}); // dojox.gfx.matrix.Matrix2D
+			}
+			// branch
+			// a: dojox.gfx.Point: a point-like object, which specifies offsets for both dimensions
+			// b: null
+			return new m.Matrix2D({dx: a.x, dy: a.y}); // dojox.gfx.matrix.Matrix2D
+		},
+		scale: function(a, b){
+			// summary: forms a scaling matrix
+			// description: The resulting matrix is used to scale (magnify) points by specified offsets.
+			// a: Number: a scaling factor used for the x coordinate
+			// b: Number: a scaling factor used for the y coordinate
+			if(arguments.length > 1){
+				return new m.Matrix2D({xx: a, yy: b}); // dojox.gfx.matrix.Matrix2D
+			}
+			if(typeof a == "number"){
+				// branch
+				// a: Number: a uniform scaling factor used for the both coordinates
+				// b: null
+				return new m.Matrix2D({xx: a, yy: a}); // dojox.gfx.matrix.Matrix2D
+			}
+			// branch
+			// a: dojox.gfx.Point: a point-like object, which specifies scale factors for both dimensions
+			// b: null
+			return new m.Matrix2D({xx: a.x, yy: a.y}); // dojox.gfx.matrix.Matrix2D
+		},
+		rotate: function(angle){
+			// summary: forms a rotating matrix
+			// description: The resulting matrix is used to rotate points
+			//		around the origin of coordinates (0, 0) by specified angle.
+			// angle: Number: an angle of rotation in radians (>0 for CW)
+			var c = Math.cos(angle);
+			var s = Math.sin(angle);
+			return new m.Matrix2D({xx: c, xy: -s, yx: s, yy: c}); // dojox.gfx.matrix.Matrix2D
+		},
+		rotateg: function(degree){
+			// summary: forms a rotating matrix
+			// description: The resulting matrix is used to rotate points
+			//		around the origin of coordinates (0, 0) by specified degree.
+			//		See dojox.gfx.matrix.rotate() for comparison.
+			// degree: Number: an angle of rotation in degrees (>0 for CW)
+			return m.rotate(m._degToRad(degree)); // dojox.gfx.matrix.Matrix2D
+		},
+		skewX: function(angle) {
+			// summary: forms an x skewing matrix
+			// description: The resulting matrix is used to skew points in the x dimension
+			//		around the origin of coordinates (0, 0) by specified angle.
+			// angle: Number: an skewing angle in radians
+			return new m.Matrix2D({xy: Math.tan(angle)}); // dojox.gfx.matrix.Matrix2D
+		},
+		skewXg: function(degree){
+			// summary: forms an x skewing matrix
+			// description: The resulting matrix is used to skew points in the x dimension
+			//		around the origin of coordinates (0, 0) by specified degree.
+			//		See dojox.gfx.matrix.skewX() for comparison.
+			// degree: Number: an skewing angle in degrees
+			return m.skewX(m._degToRad(degree)); // dojox.gfx.matrix.Matrix2D
+		},
+		skewY: function(angle){
+			// summary: forms a y skewing matrix
+			// description: The resulting matrix is used to skew points in the y dimension
+			//		around the origin of coordinates (0, 0) by specified angle.
+			// angle: Number: an skewing angle in radians
+			return new m.Matrix2D({yx: Math.tan(angle)}); // dojox.gfx.matrix.Matrix2D
+		},
+		skewYg: function(degree){
+			// summary: forms a y skewing matrix
+			// description: The resulting matrix is used to skew points in the y dimension
+			//		around the origin of coordinates (0, 0) by specified degree.
+			//		See dojox.gfx.matrix.skewY() for comparison.
+			// degree: Number: an skewing angle in degrees
+			return m.skewY(m._degToRad(degree)); // dojox.gfx.matrix.Matrix2D
+		},
+		reflect: function(a, b){
+			// summary: forms a reflection matrix
+			// description: The resulting matrix is used to reflect points around a vector,
+			//		which goes through the origin.
+			// a: dojox.gfx.Point: a point-like object, which specifies a vector of reflection
+			// b: null
+			if(arguments.length == 1){
+				b = a.y;
+				a = a.x;
+			}
+			// branch
+			// a: Number: an x coordinate value
+			// b: Number: a y coordinate value
+
+			// make a unit vector
+			var a2 = a * a, b2 = b * b, n2 = a2 + b2, xy = 2 * a * b / n2;
+			return new m.Matrix2D({xx: 2 * a2 / n2 - 1, xy: xy, yx: xy, yy: 2 * b2 / n2 - 1}); // dojox.gfx.matrix.Matrix2D
+		},
+		project: function(a, b){
+			// summary: forms an orthogonal projection matrix
+			// description: The resulting matrix is used to project points orthogonally on a vector,
+			//		which goes through the origin.
+			// a: dojox.gfx.Point: a point-like object, which specifies a vector of projection
+			// b: null
+			if(arguments.length == 1){
+				b = a.y;
+				a = a.x;
+			}
+			// branch
+			// a: Number: an x coordinate value
+			// b: Number: a y coordinate value
+
+			// make a unit vector
+			var a2 = a * a, b2 = b * b, n2 = a2 + b2, xy = a * b / n2;
+			return new m.Matrix2D({xx: a2 / n2, xy: xy, yx: xy, yy: b2 / n2}); // dojox.gfx.matrix.Matrix2D
+		},
+
+		// ensure matrix 2D conformance
+		normalize: function(matrix){
+			// summary: converts an object to a matrix, if necessary
+			// description: Converts any 2D matrix-like object or an array of
+			//		such objects to a valid dojox.gfx.matrix.Matrix2D object.
+			// matrix: Object: an object, which is converted to a matrix, if necessary
+			return (matrix instanceof m.Matrix2D) ? matrix : new m.Matrix2D(matrix); // dojox.gfx.matrix.Matrix2D
+		},
+
+		// common operations
+
+		clone: function(matrix){
+			// summary: creates a copy of a 2D matrix
+			// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object to be cloned
+			var obj = new m.Matrix2D();
+			for(var i in matrix){
+				if(typeof(matrix[i]) == "number" && typeof(obj[i]) == "number" && obj[i] != matrix[i]) obj[i] = matrix[i];
+			}
+			return obj; // dojox.gfx.matrix.Matrix2D
+		},
+		invert: function(matrix){
+			// summary: inverts a 2D matrix
+			// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object to be inverted
+			var M = m.normalize(matrix),
+				D = M.xx * M.yy - M.xy * M.yx,
+				M = new m.Matrix2D({
+					xx: M.yy/D, xy: -M.xy/D,
+					yx: -M.yx/D, yy: M.xx/D,
+					dx: (M.xy * M.dy - M.yy * M.dx) / D,
+					dy: (M.yx * M.dx - M.xx * M.dy) / D
+				});
+			return M; // dojox.gfx.matrix.Matrix2D
+		},
+		_multiplyPoint: function(matrix, x, y){
+			// summary: applies a matrix to a point
+			// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix object to be applied
+			// x: Number: an x coordinate of a point
+			// y: Number: a y coordinate of a point
+			return {x: matrix.xx * x + matrix.xy * y + matrix.dx, y: matrix.yx * x + matrix.yy * y + matrix.dy}; // dojox.gfx.Point
+		},
+		multiplyPoint: function(matrix, /* Number||Point */ a, /* Number, optional */ b){
+			// summary: applies a matrix to a point
+			// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix object to be applied
+			// a: Number: an x coordinate of a point
+			// b: Number: a y coordinate of a point
+			var M = m.normalize(matrix);
+			if(typeof a == "number" && typeof b == "number"){
+				return m._multiplyPoint(M, a, b); // dojox.gfx.Point
+			}
+			// branch
+			// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix object to be applied
+			// a: dojox.gfx.Point: a point
+			// b: null
+			return m._multiplyPoint(M, a.x, a.y); // dojox.gfx.Point
+		},
+		multiply: function(matrix){
+			// summary: combines matrices by multiplying them sequentially in the given order
+			// matrix: dojox.gfx.matrix.Matrix2D...: a 2D matrix-like object,
+			//		all subsequent arguments are matrix-like objects too
+			var M = m.normalize(matrix);
+			// combine matrices
+			for(var i = 1; i < arguments.length; ++i){
+				var l = M, r = m.normalize(arguments[i]);
+				M = new m.Matrix2D();
+				M.xx = l.xx * r.xx + l.xy * r.yx;
+				M.xy = l.xx * r.xy + l.xy * r.yy;
+				M.yx = l.yx * r.xx + l.yy * r.yx;
+				M.yy = l.yx * r.xy + l.yy * r.yy;
+				M.dx = l.xx * r.dx + l.xy * r.dy + l.dx;
+				M.dy = l.yx * r.dx + l.yy * r.dy + l.dy;
+			}
+			return M; // dojox.gfx.matrix.Matrix2D
+		},
+
+		// high level operations
+
+		_sandwich: function(matrix, x, y){
+			// summary: applies a matrix at a centrtal point
+			// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object, which is applied at a central point
+			// x: Number: an x component of the central point
+			// y: Number: a y component of the central point
+			return m.multiply(m.translate(x, y), matrix, m.translate(-x, -y)); // dojox.gfx.matrix.Matrix2D
+		},
+		scaleAt: function(a, b, c, d){
+			// summary: scales a picture using a specified point as a center of scaling
+			// description: Compare with dojox.gfx.matrix.scale().
+			// a: Number: a scaling factor used for the x coordinate
+			// b: Number: a scaling factor used for the y coordinate
+			// c: Number: an x component of a central point
+			// d: Number: a y component of a central point
+
+			// accepts several signatures:
+			//	1) uniform scale factor, Point
+			//	2) uniform scale factor, x, y
+			//	3) x scale, y scale, Point
+			//	4) x scale, y scale, x, y
+
+			switch(arguments.length){
+				case 4:
+					// a and b are scale factor components, c and d are components of a point
+					return m._sandwich(m.scale(a, b), c, d); // dojox.gfx.matrix.Matrix2D
+				case 3:
+					if(typeof c == "number"){
+						// branch
+						// a: Number: a uniform scaling factor used for both coordinates
+						// b: Number: an x component of a central point
+						// c: Number: a y component of a central point
+						// d: null
+						return m._sandwich(m.scale(a), b, c); // dojox.gfx.matrix.Matrix2D
+					}
+					// branch
+					// a: Number: a scaling factor used for the x coordinate
+					// b: Number: a scaling factor used for the y coordinate
+					// c: dojox.gfx.Point: a central point
+					// d: null
+					return m._sandwich(m.scale(a, b), c.x, c.y); // dojox.gfx.matrix.Matrix2D
+			}
+			// branch
+			// a: Number: a uniform scaling factor used for both coordinates
+			// b: dojox.gfx.Point: a central point
+			// c: null
+			// d: null
+			return m._sandwich(m.scale(a), b.x, b.y); // dojox.gfx.matrix.Matrix2D
+		},
+		rotateAt: function(angle, a, b){
+			// summary: rotates a picture using a specified point as a center of rotation
+			// description: Compare with dojox.gfx.matrix.rotate().
+			// angle: Number: an angle of rotation in radians (>0 for CW)
+			// a: Number: an x component of a central point
+			// b: Number: a y component of a central point
+
+			// accepts several signatures:
+			//	1) rotation angle in radians, Point
+			//	2) rotation angle in radians, x, y
+
+			if(arguments.length > 2){
+				return m._sandwich(m.rotate(angle), a, b); // dojox.gfx.matrix.Matrix2D
+			}
+
+			// branch
+			// angle: Number: an angle of rotation in radians (>0 for CCW)
+			// a: dojox.gfx.Point: a central point
+			// b: null
+			return m._sandwich(m.rotate(angle), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+		},
+		rotategAt: function(degree, a, b){
+			// summary: rotates a picture using a specified point as a center of rotation
+			// description: Compare with dojox.gfx.matrix.rotateg().
+			// degree: Number: an angle of rotation in degrees (>0 for CW)
+			// a: Number: an x component of a central point
+			// b: Number: a y component of a central point
+
+			// accepts several signatures:
+			//	1) rotation angle in degrees, Point
+			//	2) rotation angle in degrees, x, y
+
+			if(arguments.length > 2){
+				return m._sandwich(m.rotateg(degree), a, b); // dojox.gfx.matrix.Matrix2D
+			}
+
+			// branch
+			// degree: Number: an angle of rotation in degrees (>0 for CCW)
+			// a: dojox.gfx.Point: a central point
+			// b: null
+			return m._sandwich(m.rotateg(degree), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+		},
+		skewXAt: function(angle, a, b){
+			// summary: skews a picture along the x axis using a specified point as a center of skewing
+			// description: Compare with dojox.gfx.matrix.skewX().
+			// angle: Number: an skewing angle in radians
+			// a: Number: an x component of a central point
+			// b: Number: a y component of a central point
+
+			// accepts several signatures:
+			//	1) skew angle in radians, Point
+			//	2) skew angle in radians, x, y
+
+			if(arguments.length > 2){
+				return m._sandwich(m.skewX(angle), a, b); // dojox.gfx.matrix.Matrix2D
+			}
+
+			// branch
+			// angle: Number: an skewing angle in radians
+			// a: dojox.gfx.Point: a central point
+			// b: null
+			return m._sandwich(m.skewX(angle), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+		},
+		skewXgAt: function(degree, a, b){
+			// summary: skews a picture along the x axis using a specified point as a center of skewing
+			// description: Compare with dojox.gfx.matrix.skewXg().
+			// degree: Number: an skewing angle in degrees
+			// a: Number: an x component of a central point
+			// b: Number: a y component of a central point
+
+			// accepts several signatures:
+			//	1) skew angle in degrees, Point
+			//	2) skew angle in degrees, x, y
+
+			if(arguments.length > 2){
+				return m._sandwich(m.skewXg(degree), a, b); // dojox.gfx.matrix.Matrix2D
+			}
+
+			// branch
+			// degree: Number: an skewing angle in degrees
+			// a: dojox.gfx.Point: a central point
+			// b: null
+			return m._sandwich(m.skewXg(degree), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+		},
+		skewYAt: function(angle, a, b){
+			// summary: skews a picture along the y axis using a specified point as a center of skewing
+			// description: Compare with dojox.gfx.matrix.skewY().
+			// angle: Number: an skewing angle in radians
+			// a: Number: an x component of a central point
+			// b: Number: a y component of a central point
+
+			// accepts several signatures:
+			//	1) skew angle in radians, Point
+			//	2) skew angle in radians, x, y
+
+			if(arguments.length > 2){
+				return m._sandwich(m.skewY(angle), a, b); // dojox.gfx.matrix.Matrix2D
+			}
+
+			// branch
+			// angle: Number: an skewing angle in radians
+			// a: dojox.gfx.Point: a central point
+			// b: null
+			return m._sandwich(m.skewY(angle), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+		},
+		skewYgAt: function(/* Number */ degree, /* Number||Point */ a, /* Number, optional */ b){
+			// summary: skews a picture along the y axis using a specified point as a center of skewing
+			// description: Compare with dojox.gfx.matrix.skewYg().
+			// degree: Number: an skewing angle in degrees
+			// a: Number: an x component of a central point
+			// b: Number: a y component of a central point
+
+			// accepts several signatures:
+			//	1) skew angle in degrees, Point
+			//	2) skew angle in degrees, x, y
+
+			if(arguments.length > 2){
+				return m._sandwich(m.skewYg(degree), a, b); // dojox.gfx.matrix.Matrix2D
+			}
+
+			// branch
+			// degree: Number: an skewing angle in degrees
+			// a: dojox.gfx.Point: a central point
+			// b: null
+			return m._sandwich(m.skewYg(degree), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+		}
+
+		//TODO: rect-to-rect mapping, scale-to-fit (isotropic and anisotropic versions)
+
+	});
+})();
+
+// propagate Matrix2D up
+dojox.gfx.Matrix2D = dojox.gfx.matrix.Matrix2D;
+
+}
+
+if(!dojo._hasResource["dojox.gfx._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx._base"] = true;
+dojo.provide("dojox.gfx._base");
+
+(function(){
+	var g = dojox.gfx, b = g._base;
+
+	// candidates for dojox.style (work on VML and SVG nodes)
+	g._hasClass = function(/*DomNode*/node, /*String*/classStr){
+		//	summary:
+		//		Returns whether or not the specified classes are a portion of the
+		//		class list currently applied to the node.
+		// return (new RegExp('(^|\\s+)'+classStr+'(\\s+|$)')).test(node.className)	// Boolean
+		var cls = node.getAttribute("className");
+		return cls && (" " + cls + " ").indexOf(" " + classStr + " ") >= 0;  // Boolean
+	}
+	g._addClass = function(/*DomNode*/node, /*String*/classStr){
+		//	summary:
+		//		Adds the specified classes to the end of the class list on the
+		//		passed node.
+		var cls = node.getAttribute("className") || "";
+		if(!cls || (" " + cls + " ").indexOf(" " + classStr + " ") < 0){
+			node.setAttribute("className", cls + (cls ? " " : "") + classStr);
+		}
+	}
+	g._removeClass = function(/*DomNode*/node, /*String*/classStr){
+		//	summary: Removes classes from node.
+		var cls = node.getAttribute("className");
+		if(cls){
+			node.setAttribute(
+				"className", 
+				cls.replace(new RegExp('(^|\\s+)' + classStr + '(\\s+|$)'), "$1$2")
+			);
+		}
+	}
+
+	// candidate for dojox.html.metrics (dynamic font resize handler is not implemented here)
+
+	//	derived from Morris John's emResized measurer
+	b._getFontMeasurements = function(){
+		//	summary:
+		//		Returns an object that has pixel equivilents of standard font
+		//		size values.
+		var heights = {
+			'1em': 0, '1ex': 0, '100%': 0, '12pt': 0, '16px': 0, 'xx-small': 0,
+			'x-small': 0, 'small': 0, 'medium': 0, 'large': 0, 'x-large': 0,
+			'xx-large': 0
+		};
+
+		if(dojo.isIE){
+			//	we do a font-size fix if and only if one isn't applied already.
+			//	NOTE: If someone set the fontSize on the HTML Element, this will kill it.
+			dojo.doc.documentElement.style.fontSize="100%";
+		}
+
+		//	set up the measuring node.
+		var div = dojo.doc.createElement("div");
+		var s = div.style;
+		s.position = "absolute";
+		s.left = "-100px";
+		s.top = "0px";
+		s.width = "30px";
+		s.height = "1000em";
+		s.border = "0px";
+		s.margin = "0px";
+		s.padding = "0px";
+		s.outline = "none";
+		s.lineHeight = "1";
+		s.overflow = "hidden";
+		dojo.body().appendChild(div);
+
+		//	do the measurements.
+		for(var p in heights){
+			div.style.fontSize = p;
+			heights[p] = Math.round(div.offsetHeight * 12/16) * 16/12 / 1000;
+		}
+
+		dojo.body().removeChild(div);
+		div = null;
+		return heights; 	//	object
+	};
+
+	var fontMeasurements = null;
+
+	b._getCachedFontMeasurements = function(recalculate){
+		if(recalculate || !fontMeasurements){
+			fontMeasurements = b._getFontMeasurements();
+		}
+		return fontMeasurements;
+	};
+
+	// candidate for dojox.html.metrics
+
+	var measuringNode = null, empty = {};
+	b._getTextBox = function(/* String */ text, /* Object */ style, /* String? */ className){
+		var m, s;
+		if(!measuringNode){
+			m = measuringNode = dojo.doc.createElement("div");
+			s = m.style;
+			s.position = "absolute";
+			s.left = "-10000px";
+			s.top = "0";
+			dojo.body().appendChild(m);
+		}else{
+			m = measuringNode;
+			s = m.style;
+		}
+		// reset styles
+		m.className = "";
+		s.border = "0";
+		s.margin = "0";
+		s.padding = "0";
+		s.outline = "0";
+		// set new style
+		if(arguments.length > 1 && style){
+			for(var i in style){
+				if(i in empty){ continue; }
+				s[i] = style[i];
+			}
+		}
+		// set classes
+		if(arguments.length > 2 && className){
+			m.className = className;
+		}
+		// take a measure
+		m.innerHTML = text;
+		return dojo.marginBox(m);
+	};
+
+	// candidate for dojo.dom
+
+	var uniqueId = 0;
+	b._getUniqueId = function(){
+		// summary: returns a unique string for use with any DOM element
+		var id;
+		do{
+			id = dojo._scopeName + "Unique" + (++uniqueId);
+		}while(dojo.byId(id));
+		return id;
+	};
+})();
+
+dojo.mixin(dojox.gfx, {
+	//	summary:
+	// 		defines constants, prototypes, and utility functions
+
+	// default shapes, which are used to fill in missing parameters
+	defaultPath: {
+		type: "path", path: ""
+	},
+	defaultPolyline: {
+		type: "polyline", points: []
+	},
+	defaultRect: {
+		type: "rect", x: 0, y: 0, width: 100, height: 100, r: 0
+	},
+	defaultEllipse: {
+		type: "ellipse", cx: 0, cy: 0, rx: 200, ry: 100
+	},
+	defaultCircle: {
+		type: "circle", cx: 0, cy: 0, r: 100
+	},
+	defaultLine: {
+		type: "line", x1: 0, y1: 0, x2: 100, y2: 100
+	},
+	defaultImage: {
+		type: "image", x: 0, y: 0, width: 0, height: 0, src: ""
+	},
+	defaultText: {
+		type: "text", x: 0, y: 0, text: "", align: "start",
+		decoration: "none", rotated: false, kerning: true
+	},
+	defaultTextPath: {
+		type: "textpath", text: "", align: "start",
+		decoration: "none", rotated: false, kerning: true
+	},
+
+	// default geometric attributes
+	defaultStroke: {
+		type: "stroke", color: "black", style: "solid", width: 1, 
+		cap: "butt", join: 4
+	},
+	defaultLinearGradient: {
+		type: "linear", x1: 0, y1: 0, x2: 100, y2: 100,
+		colors: [
+			{ offset: 0, color: "black" }, { offset: 1, color: "white" }
+		]
+	},
+	defaultRadialGradient: {
+		type: "radial", cx: 0, cy: 0, r: 100,
+		colors: [
+			{ offset: 0, color: "black" }, { offset: 1, color: "white" }
+		]
+	},
+	defaultPattern: {
+		type: "pattern", x: 0, y: 0, width: 0, height: 0, src: ""
+	},
+	defaultFont: {
+		type: "font", style: "normal", variant: "normal", 
+		weight: "normal", size: "10pt", family: "serif"
+	},
+
+	getDefault: (function(){
+		var typeCtorCache = {};
+		// a memoized delegate()
+		return function(/*String*/ type){
+			var t = typeCtorCache[type];
+			if(t){
+				return new t();
+			}
+			t = typeCtorCache[type] = function(){};
+			t.prototype = dojox.gfx[ "default" + type ];
+			return new t();
+		}
+	})(),
+
+	normalizeColor: function(/*Color*/ color){
+		//	summary:
+		// 		converts any legal color representation to normalized
+		// 		dojo.Color object
+		return (color instanceof dojo.Color) ? color : new dojo.Color(color); // dojo.Color
+	},
+	normalizeParameters: function(existed, update){
+		//	summary:
+		// 		updates an existing object with properties from an "update"
+		// 		object
+		//	existed: Object
+		//		the "target" object to be updated
+		//	update:  Object
+		//		the "update" object, whose properties will be used to update
+		//		the existed object
+		if(update){
+			var empty = {};
+			for(var x in existed){
+				if(x in update && !(x in empty)){
+					existed[x] = update[x];
+				}
+			}
+		}
+		return existed;	// Object
+	},
+	makeParameters: function(defaults, update){
+		//	summary:
+		// 		copies the original object, and all copied properties from the
+		// 		"update" object
+		//	defaults: Object
+		//		the object to be cloned before updating
+		//	update:   Object
+		//		the object, which properties are to be cloned during updating
+		if(!update){
+			// return dojo.clone(defaults);
+			return dojo.delegate(defaults);
+		}
+		var result = {};
+		for(var i in defaults){
+			if(!(i in result)){
+				result[i] = dojo.clone((i in update) ? update[i] : defaults[i]);
+			}
+		}
+		return result; // Object
+	},
+	formatNumber: function(x, addSpace){
+		// summary: converts a number to a string using a fixed notation
+		// x:			Number:		number to be converted
+		// addSpace:	Boolean?:	if it is true, add a space before a positive number
+		var val = x.toString();
+		if(val.indexOf("e") >= 0){
+			val = x.toFixed(4);
+		}else{
+			var point = val.indexOf(".");
+			if(point >= 0 && val.length - point > 5){
+				val = x.toFixed(4);
+			}
+		}
+		if(x < 0){
+			return val; // String
+		}
+		return addSpace ? " " + val : val; // String
+	},
+	// font operations
+	makeFontString: function(font){
+		// summary: converts a font object to a CSS font string
+		// font:	Object:	font object (see dojox.gfx.defaultFont)
+		return font.style + " " + font.variant + " " + font.weight + " " + font.size + " " + font.family; // Object
+	},
+	splitFontString: function(str){
+		// summary: converts a CSS font string to a font object
+		// str:		String:	a CSS font string
+		var font = dojox.gfx.getDefault("Font");
+		var t = str.split(/\s+/);
+		do{
+			if(t.length < 5){ break; }
+			font.style  = t[0];
+			font.varian = t[1];
+			font.weight = t[2];
+			var i = t[3].indexOf("/");
+			font.size = i < 0 ? t[3] : t[3].substring(0, i);
+			var j = 4;
+			if(i < 0){
+				if(t[4] == "/"){
+					j = 6;
+					break;
+				}
+				if(t[4].substr(0, 1) == "/"){
+					j = 5;
+					break;
+				}
+			}
+			if(j + 3 > t.length){ break; }
+			font.size = t[j];
+			font.family = t[j + 1];
+		}while(false);
+		return font;	// Object
+	},
+	// length operations
+	cm_in_pt: 72 / 2.54,	// Number: points per centimeter
+	mm_in_pt: 7.2 / 2.54,	// Number: points per millimeter
+	px_in_pt: function(){
+		// summary: returns a number of pixels per point
+		return dojox.gfx._base._getCachedFontMeasurements()["12pt"] / 12;	// Number
+	},
+	pt2px: function(len){
+		// summary: converts points to pixels
+		// len: Number: a value in points
+		return len * dojox.gfx.px_in_pt();	// Number
+	},
+	px2pt: function(len){
+		// summary: converts pixels to points
+		// len: Number: a value in pixels
+		return len / dojox.gfx.px_in_pt();	// Number
+	},
+	normalizedLength: function(len) {
+		// summary: converts any length value to pixels
+		// len: String: a length, e.g., "12pc"
+		if(len.length == 0) return 0;
+		if(len.length > 2){
+			var px_in_pt = dojox.gfx.px_in_pt();
+			var val = parseFloat(len);
+			switch(len.slice(-2)){
+				case "px": return val;
+				case "pt": return val * px_in_pt;
+				case "in": return val * 72 * px_in_pt;
+				case "pc": return val * 12 * px_in_pt;
+				case "mm": return val * dojox.gfx.mm_in_pt * px_in_pt;
+				case "cm": return val * dojox.gfx.cm_in_pt * px_in_pt;
+			}
+		}
+		return parseFloat(len);	// Number
+	},
+
+	// a constant used to split a SVG/VML path into primitive components
+	pathVmlRegExp: /([A-Za-z]+)|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g,
+	pathSvgRegExp: /([A-Za-z])|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g,
+
+	equalSources: function(a, b){
+		// summary: compares event sources, returns true if they are equal
+		return a && b && a == b;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.gfx"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx"] = true;
+dojo.provide("dojox.gfx");
+
+
+
+
+dojo.loadInit(function(){
+	//Since loaderInit can be fired before any dojo.provide/require calls,
+	//make sure the dojox.gfx object exists and only run this logic if dojox.gfx.renderer
+	//has not been defined yet.
+	var gfx = dojo.getObject("dojox.gfx", true), sl, flag, match;
+	if(!gfx.renderer){
+		var renderers = (typeof dojo.config.gfxRenderer == "string" ?
+			dojo.config.gfxRenderer : "svg,vml,silverlight,canvas").split(",");
+
+		// mobile platform detection
+		// TODO: move to the base?
+
+		var ua = navigator.userAgent, iPhoneOsBuild = 0, androidVersion = 0;
+		if(dojo.isSafari >= 3){
+			// detect mobile version of WebKit starting with "version 3"
+
+			//	comprehensive iPhone test.  Have to figure out whether it's SVG or Canvas based on the build.
+			//	iPhone OS build numbers from en.wikipedia.org.
+			if(ua.indexOf("iPhone") >= 0 || ua.indexOf("iPod") >= 0){
+				//	grab the build out of this.  Expression is a little nasty because we want
+				//		to be sure we have the whole version string.
+				match = ua.match(/Version\/(\d(\.\d)?(\.\d)?)\sMobile\/([^\s]*)\s?/);
+				if(match){
+					//	grab the build out of the match.  Only use the first three because of specific builds.
+					iPhoneOsBuild = parseInt(match[4].substr(0,3), 16);
+				}
+			}
+		}
+		if(dojo.isWebKit){
+			// Android detection
+			if(!iPhoneOsBuild){
+				match = ua.match(/Android\s+(\d+\.\d+)/);
+				if(match){
+					androidVersion = parseFloat(match[1]);
+					// Android 1.0-1.1 doesn't support SVG but supports Canvas
+				}
+			}
+		}
+
+		for(var i = 0; i < renderers.length; ++i){
+			switch(renderers[i]){
+				case "svg":
+					//	iPhone OS builds greater than 5F1 should have SVG.
+					if(!dojo.isIE && (!iPhoneOsBuild || iPhoneOsBuild >= 0x5f1) && !androidVersion && !dojo.isAIR){
+						dojox.gfx.renderer = "svg";
+					}
+					break;
+				case "vml":
+					if(dojo.isIE){
+						dojox.gfx.renderer = "vml";
+					}
+					break;
+				case "silverlight":
+					try{
+						if(dojo.isIE){
+							sl = new ActiveXObject("AgControl.AgControl");
+							if(sl && sl.IsVersionSupported("1.0")){
+								flag = true;
+							}
+						}else{
+							if(navigator.plugins["Silverlight Plug-In"]){
+								flag = true;
+							}
+						}
+					}catch(e){
+						flag = false;
+					}finally{
+						sl = null;
+					}
+					if(flag){ dojox.gfx.renderer = "silverlight"; }
+					break;
+				case "canvas":
+					//TODO: need more comprehensive test for Canvas
+					if(!dojo.isIE){
+						dojox.gfx.renderer = "canvas";
+					}
+					break;
+			}
+			if(dojox.gfx.renderer){ break; }
+		}
+		if(dojo.config.isDebug){
+			
+		}
+	}
+});
+
+// include a renderer conditionally
+dojo.requireIf(dojox.gfx.renderer == "svg", "dojox.gfx.svg");
+dojo.requireIf(dojox.gfx.renderer == "vml", "dojox.gfx.vml");
+dojo.requireIf(dojox.gfx.renderer == "silverlight", "dojox.gfx.silverlight");
+dojo.requireIf(dojox.gfx.renderer == "canvas", "dojox.gfx.canvas");
+
+}
+
diff --git a/dojox/gfx/Moveable.js b/dojox/gfx/Moveable.js
new file mode 100644
index 0000000..aa7c799
--- /dev/null
+++ b/dojox/gfx/Moveable.js
@@ -0,0 +1,53 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx.Moveable"]){
+dojo._hasResource["dojox.gfx.Moveable"]=true;
+dojo.provide("dojox.gfx.Moveable");
+dojo.require("dojox.gfx.Mover");
+dojo.declare("dojox.gfx.Moveable",null,{constructor:function(_1,_2){
+this.shape=_1;
+this.delay=(_2&&_2.delay>0)?_2.delay:0;
+this.mover=(_2&&_2.mover)?_2.mover:dojox.gfx.Mover;
+this.events=[this.shape.connect("onmousedown",this,"onMouseDown")];
+},destroy:function(){
+dojo.forEach(this.events,this.shape.disconnect,this.shape);
+this.events=this.shape=null;
+},onMouseDown:function(e){
+if(this.delay){
+this.events.push(this.shape.connect("onmousemove",this,"onMouseMove"));
+this.events.push(this.shape.connect("onmouseup",this,"onMouseUp"));
+this._lastX=e.clientX;
+this._lastY=e.clientY;
+}else{
+new this.mover(this.shape,e,this);
+}
+dojo.stopEvent(e);
+},onMouseMove:function(e){
+if(Math.abs(e.clientX-this._lastX)>this.delay||Math.abs(e.clientY-this._lastY)>this.delay){
+this.onMouseUp(e);
+new this.mover(this.shape,e,this);
+}
+dojo.stopEvent(e);
+},onMouseUp:function(e){
+this.shape.disconnect(this.events.pop());
+this.shape.disconnect(this.events.pop());
+},onMoveStart:function(_6){
+dojo.publish("/gfx/move/start",[_6]);
+dojo.addClass(dojo.body(),"dojoMove");
+},onMoveStop:function(_7){
+dojo.publish("/gfx/move/stop",[_7]);
+dojo.removeClass(dojo.body(),"dojoMove");
+},onFirstMove:function(_8){
+},onMove:function(_9,_a){
+this.onMoving(_9,_a);
+this.shape.applyLeftTransform(_a);
+this.onMoved(_9,_a);
+},onMoving:function(_b,_c){
+},onMoved:function(_d,_e){
+}});
+}
diff --git a/dojox/gfx/Mover.js b/dojox/gfx/Mover.js
new file mode 100644
index 0000000..0bf519d
--- /dev/null
+++ b/dojox/gfx/Mover.js
@@ -0,0 +1,38 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx.Mover"]){
+dojo._hasResource["dojox.gfx.Mover"]=true;
+dojo.provide("dojox.gfx.Mover");
+dojo.declare("dojox.gfx.Mover",null,{constructor:function(_1,e,_3){
+this.shape=_1;
+this.lastX=e.clientX;
+this.lastY=e.clientY;
+var h=this.host=_3,d=document,_6=dojo.connect(d,"onmousemove",this,"onFirstMove");
+this.events=[dojo.connect(d,"onmousemove",this,"onMouseMove"),dojo.connect(d,"onmouseup",this,"destroy"),dojo.connect(d,"ondragstart",dojo,"stopEvent"),dojo.connect(d,"onselectstart",dojo,"stopEvent"),_6];
+if(h&&h.onMoveStart){
+h.onMoveStart(this);
+}
+},onMouseMove:function(e){
+var x=e.clientX;
+var y=e.clientY;
+this.host.onMove(this,{dx:x-this.lastX,dy:y-this.lastY});
+this.lastX=x;
+this.lastY=y;
+dojo.stopEvent(e);
+},onFirstMove:function(){
+this.host.onFirstMove(this);
+dojo.disconnect(this.events.pop());
+},destroy:function(){
+dojo.forEach(this.events,dojo.disconnect);
+var h=this.host;
+if(h&&h.onMoveStop){
+h.onMoveStop(this);
+}
+this.events=this.shape=null;
+}});
+}
diff --git a/dojox/gfx/README b/dojox/gfx/README
new file mode 100644
index 0000000..808ba6b
--- /dev/null
+++ b/dojox/gfx/README
@@ -0,0 +1,102 @@
+-------------------------------------------------------------------------------
+dojox.gfx
+-------------------------------------------------------------------------------
+Version 1.100
+Release date: 08/01/2006
+-------------------------------------------------------------------------------
+Project state:
+beta
+HTMLCanvas renderer: experimental
+-------------------------------------------------------------------------------
+Credits
+	Eugene Lazutkin (eugene.lazutkin at gmail.com)
+	Kun Xi (bookstack at gmail.com)
+	Chris Mitchell (ccmitchellusa at gmail.com) HTML Canvas
+-------------------------------------------------------------------------------
+Project description
+
+Implementation of simple portable 2D graphics library.
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo Core
+-------------------------------------------------------------------------------
+Documentation
+
+Currently it can be found here: http://docs.google.com/Doc?id=d764479_1hnb2tn
+
+HTMLCanvas Renderer Status
+
+To use canvas rendering, insert 'canvas' at the beginning of the gfxRenderers list in your
+djConfig, for example:
+<script type="text/javascript" src="../../../dojo/dojo.js"
+	djConfig="parseOnLoad: true, gfxRenderer: 'canvas,svg,silverlight,vml'"></script>
+canvas currently will only render on non-IE browsers (see dojox/gfx.js for where the renderer is loaded);
+although it should be possible to use an IE canvas implementation (like Google's); however, it will be very slow.
+
+The following tests can be made to work with HTML Canvas with minor testcase modification:
+dojox/gfx/tests
+	test_gfx.html-Bugs #1
+	test_arc.html
+	test_bezier.html
+	test_pattern.html
+	test_gradient.html
+	test_linearGradient.html
+	test_image1.html - Limitation #3
+	test_transform.html - Bug #1
+	test_poly.html - Bug #1
+dojox/gfx/demos
+	butterfly.html - Bug #1
+	lion.html - Bug #1
+	tiger.html - Bug #1
+	circles.html - No event processing yet :(
+	creator.html
+dojox/chart
+	test_pie2d.html - Dojo Charts on iPhone anyone? :)
+	test_chart2d.html -
+
+	// To make charts work, the following line needs to be added to the end of the
+	// Chart2D.js render() method (prior to return)
+	if(this.surface.render){this.surface.render()};
+
+Known Limitations:
+1) event handling- plan is to capture all events at canvas, perform intersect/hit
+   tests (not implemented) against scene graph, then propogate event to top-most
+   intersected shape.  HtmlCanvas shape need intersectsStroke and intersectsBounds,
+   and intersects (region).
+2) SVG and VML are "live" scene graphs; eg. any state change to objects in the
+   scene automatically get rendered in next engine render pass. For canvas, it's
+   procedural, and current implementation requires application to call surface.render()
+   whenever scene needs to be updated. Plan is to do dirty region checking based
+   on bounding boxes (currently not properly computed), and track dirty areas anytime
+   state changes (invalidate) separate from render phase.
+   Add the following call where changes to the scene graph are complete and you want to
+   render:
+
+	if (surface.render){surface.render();}
+
+4) Text/Text Paths - Text shape is implemented using DIV overlays.  Many text styles are not
+   applied, and outline/fills are not possible.  This is due to limitations in Canvas spec.
+   Firefox 3.0 has proprietary text functions that we could test for and use once FF3 is out.
+   No luck on Safari.
+3) No Image skewing - Limitation of Canvas
+
+Known Bugs:
+1) Matrix xformations (applied from root to shape leaf nodes) not quite right--but very close.
+   Canvas does not have a built in transformation function that allows skewing.  Need to
+   track skew matrix with Shape, and perform other trans/rot/scale transformations without
+   using canvas transform functions.
+
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/gfx.js
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/gfx/*
+
+Install into the following directory structure:
+/dojox/gfx/
+
+...which should be at the same level as your Dojo checkout.
+-------------------------------------------------------------------------------
diff --git a/dojox/gfx/VectorText.js b/dojox/gfx/VectorText.js
new file mode 100644
index 0000000..165dad0
--- /dev/null
+++ b/dojox/gfx/VectorText.js
@@ -0,0 +1,366 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx.VectorText"]){
+dojo._hasResource["dojox.gfx.VectorText"]=true;
+dojo.provide("dojox.gfx.VectorText");
+dojo.require("dojox.gfx");
+dojo.require("dojox.xml.DomParser");
+dojo.require("dojox.html.metrics");
+(function(){
+dojo.mixin(dojox.gfx,{vectorFontFitting:{NONE:0,FLOW:1,FIT:2},defaultVectorText:{type:"vectortext",x:0,y:0,width:null,height:null,text:"",align:"start",decoration:"none",fitting:0,leading:1.5},defaultVectorFont:{type:"vectorfont",size:"10pt",family:null},_vectorFontCache:{},_svgFontCache:{},getVectorFont:function(_1){
+if(dojox.gfx._vectorFontCache[_1]){
+return dojox.gfx._vectorFontCache[_1];
+}
+return new dojox.gfx.VectorFont(_1);
+}});
+dojo.declare("dojox.gfx.VectorFont",null,{_entityRe:/&(quot|apos|lt|gt|amp|#x[^;]+|#\d+);/g,_decodeEntitySequence:function(_2){
+if(!_2.match(this._entityRe)){
+return;
+}
+var _3={amp:"&",apos:"'",quot:"\"",lt:"<",gt:">"};
+var r,_5="";
+while((r=this._entityRe.exec(_2))!==null){
+if(r[1].charAt(1)=="x"){
+_5+=String.fromCharCode(r[1].slice(2),16);
+}else{
+if(!isNaN(parseInt(r[1].slice(1),10))){
+_5+=String.fromCharCode(r[1].slice(1));
+}else{
+_5+=_3(r[1]);
+}
+}
+}
+return _5;
+},_parse:function(_6,_7){
+var _8=dojox.gfx._svgFontCache[_7]||dojox.xml.DomParser.parse(_6);
+var f=_8.documentElement.byName("font")[0],_a=_8.documentElement.byName("font-face")[0];
+var _b=parseFloat(_a.getAttribute("units-per-em")||1000,10);
+var _c={x:parseFloat(f.getAttribute("horiz-adv-x"),10),y:parseFloat(f.getAttribute("vert-adv-y")||0,10)};
+if(!_c.y){
+_c.y=_b;
+}
+var _d={horiz:{x:parseFloat(f.getAttribute("horiz-origin-x")||0,10),y:parseFloat(f.getAttribute("horiz-origin-y")||0,10)},vert:{x:parseFloat(f.getAttribute("vert-origin-x")||0,10),y:parseFloat(f.getAttribute("vert-origin-y")||0,10)}};
+var _e=_a.getAttribute("font-family"),_f=_a.getAttribute("font-style")||"all",_10=_a.getAttribute("font-variant")||"normal",_11=_a.getAttribute("font-weight")||"all",_12=_a.getAttribute("font-stretch")||"normal",_13=_a.getAttribute("unicode-range")||"U+0-10FFFF",_14=_a.getAttribute("panose-1")||"0 0 0 0 0 0 0 0 0 0",_15=_a.getAttribute("cap-height"),_16=parseFloat(_a.getAttribute("ascent")||(_b-_d.vert.y),10),_17=parseFloat(_a.getAttribute("descent")||_d.vert.y,10),_18={};
+var _19=_e;
+if(_a.byName("font-face-name")[0]){
+_19=_a.byName("font-face-name")[0].getAttribute("name");
+}
+if(dojox.gfx._vectorFontCache[_19]){
+return;
+}
+dojo.forEach(["alphabetic","ideographic","mathematical","hanging"],function(_1a){
+var a=_a.getAttribute(_1a);
+if(a!==null){
+_18[_1a]=parseFloat(a,10);
+}
+});
+var _1c=parseFloat(_8.documentElement.byName("missing-glyph")[0].getAttribute("horiz-adv-x")||_c.x,10);
+var _1d={},_1e={},g=_8.documentElement.byName("glyph");
+dojo.forEach(g,function(_20){
+var _21=_20.getAttribute("unicode"),_19=_20.getAttribute("glyph-name"),_22=parseFloat(_20.getAttribute("horiz-adv-x")||_c.x,10),_23=_20.getAttribute("d");
+if(_21.match(this._entityRe)){
+_21=this._decodeEntitySequence(_21);
+}
+var o={code:_21,name:_19,xAdvance:_22,path:_23};
+_1d[_21]=o;
+_1e[_19]=o;
+},this);
+var _25=_8.documentElement.byName("hkern");
+dojo.forEach(_25,function(_26,i){
+var k=-parseInt(_26.getAttribute("k"),10);
+var u1=_26.getAttribute("u1"),g1=_26.getAttribute("g1"),u2=_26.getAttribute("u2"),g2=_26.getAttribute("g2"),gl;
+if(u1){
+u1=this._decodeEntitySequence(u1);
+if(_1d[u1]){
+gl=_1d[u1];
+}
+}else{
+if(_1e[g1]){
+gl=_1e[g1];
+}
+}
+if(gl){
+if(!gl.kern){
+gl.kern={};
+}
+if(u2){
+u2=this._decodeEntitySequence(u2);
+gl.kern[u2]={x:k};
+}else{
+if(_1e[g2]){
+gl.kern[_1e[g2].code]={x:k};
+}
+}
+}
+},this);
+dojo.mixin(this,{family:_e,name:_19,style:_f,variant:_10,weight:_11,stretch:_12,range:_13,viewbox:{width:_b,height:_b},origin:_d,advance:dojo.mixin(_c,{missing:{x:_1c,y:_1c}}),ascent:_16,descent:_17,baseline:_18,glyphs:_1d});
+dojox.gfx._vectorFontCache[_19]=this;
+dojox.gfx._vectorFontCache[_7]=this;
+if(_19!=_e&&!dojox.gfx._vectorFontCache[_e]){
+dojox.gfx._vectorFontCache[_e]=this;
+}
+if(!dojox.gfx._svgFontCache[_7]){
+dojox.gfx._svgFontCache[_7]=_8;
+}
+},_clean:function(){
+var _2e=this.name,_2f=this.family;
+dojo.forEach(["family","name","style","variant","weight","stretch","range","viewbox","origin","advance","ascent","descent","baseline","glyphs"],function(_30){
+try{
+delete this[_30];
+}
+catch(e){
+}
+},this);
+if(dojox.gfx._vectorFontCache[_2e]){
+delete dojox.gfx._vectorFontCache[_2e];
+}
+if(dojox.gfx._vectorFontCache[_2f]){
+delete dojox.gfx._vectorFontCache[_2f];
+}
+return this;
+},constructor:function(url){
+this._defaultLeading=1.5;
+if(url!==undefined){
+this.load(url);
+}
+},load:function(url){
+this.onLoadBegin(url.toString());
+this._parse(dojox.gfx._svgFontCache[url.toString()]||dojo._getText(url.toString()),url.toString());
+this.onLoad(this);
+return this;
+},initialized:function(){
+return (this.glyphs!==null);
+},_round:function(n){
+return Math.round(1000*n)/1000;
+},_leading:function(_34){
+return this.viewbox.height*(_34||this._defaultLeading);
+},_normalize:function(str){
+return str.replace(/\s+/g,String.fromCharCode(32));
+},_getWidth:function(_36){
+var w=0,_38=0,_39=null;
+dojo.forEach(_36,function(_3a,i){
+_38=_3a.xAdvance;
+if(_36[i]&&_3a.kern&&_3a.kern[_36[i].code]){
+_38+=_3a.kern[_36[i].code].x;
+}
+w+=_38;
+_39=_3a;
+});
+if(_39&&_39.code==" "){
+w-=_39.xAdvance;
+}
+return this._round(w);
+},_getLongestLine:function(_3c){
+var _3d=0,idx=0;
+dojo.forEach(_3c,function(_3f,i){
+var max=Math.max(_3d,this._getWidth(_3f));
+if(max>_3d){
+_3d=max;
+idx=i;
+}
+},this);
+return {width:_3d,index:idx,line:_3c[idx]};
+},_trim:function(_42){
+var fn=function(arr){
+if(!arr.length){
+return;
+}
+if(arr[arr.length-1].code==" "){
+arr.splice(arr.length-1,1);
+}
+if(!arr.length){
+return;
+}
+if(arr[0].code==" "){
+arr.splice(0,1);
+}
+};
+if(dojo.isArray(_42[0])){
+dojo.forEach(_42,fn);
+}else{
+fn(_42);
+}
+return _42;
+},_split:function(_45,_46){
+var w=this._getWidth(_45),_48=Math.floor(w/_46),_49=[],cw=0,c=[],_4c=false;
+for(var i=0,l=_45.length;i<l;i++){
+if(_45[i].code==" "){
+_4c=true;
+}
+cw+=_45[i].xAdvance;
+if(i+1<l&&_45[i].kern&&_45[i].kern[_45[i+1].code]){
+cw+=_45[i].kern[_45[i+1].code].x;
+}
+if(cw>=_48){
+var chr=_45[i];
+while(_4c&&chr.code!=" "&&i>=0){
+chr=c.pop();
+i--;
+}
+_49.push(c);
+c=[];
+cw=0;
+_4c=false;
+}
+c.push(_45[i]);
+}
+if(c.length){
+_49.push(c);
+}
+return this._trim(_49);
+},_getSizeFactor:function(_50){
+_50+="";
+var _51=dojox.html.metrics.getCachedFontMeasurements(),_52=this.viewbox.height,f=_51["1em"],_54=parseFloat(_50,10);
+if(_50.indexOf("em")>-1){
+return this._round((_51["1em"]*_54)/_52);
+}else{
+if(_50.indexOf("ex")>-1){
+return this._round((_51["1ex"]*_54)/_52);
+}else{
+if(_50.indexOf("pt")>-1){
+return this._round(((_51["12pt"]/12)*_54)/_52);
+}else{
+if(_50.indexOf("px")>-1){
+return this._round(((_51["16px"]/16)*_54)/_52);
+}else{
+if(_50.indexOf("%")>-1){
+return this._round((_51["1em"]*(_54/100))/_52);
+}else{
+f=_51[_50]||_51.medium;
+return this._round(f/_52);
+}
+}
+}
+}
+}
+},_getFitFactor:function(_55,w,h,l){
+if(!h){
+return this._round(w/this._getWidth(_55));
+}else{
+var _59=this._getLongestLine(_55).width,_5a=(_55.length*(this.viewbox.height*l))-((this.viewbox.height*l)-this.viewbox.height);
+return this._round(Math.min(w/_59,h/_5a));
+}
+},_getBestFit:function(_5b,w,h,_5e){
+var _5f=32,_60=0,_61=_5f;
+while(_5f>0){
+var f=this._getFitFactor(this._split(_5b,_5f),w,h,_5e);
+if(f>_60){
+_60=f;
+_61=_5f;
+}
+_5f--;
+}
+return {scale:_60,lines:this._split(_5b,_61)};
+},_getBestFlow:function(_63,w,_65){
+var _66=[],cw=0,c=[],_69=false;
+for(var i=0,l=_63.length;i<l;i++){
+if(_63[i].code==" "){
+_69=true;
+}
+var tw=_63[i].xAdvance;
+if(i+1<l&&_63[i].kern&&_63[i].kern[_63[i+1].code]){
+tw+=_63[i].kern[_63[i+1].code].x;
+}
+cw+=_65*tw;
+if(cw>=w){
+var chr=_63[i];
+while(_69&&chr.code!=" "&&i>=0){
+chr=c.pop();
+i--;
+}
+_66.push(c);
+c=[];
+cw=0;
+_69=false;
+}
+c.push(_63[i]);
+}
+if(c.length){
+_66.push(c);
+}
+return this._trim(_66);
+},getWidth:function(_6e,_6f){
+return this._getWidth(dojo.map(this._normalize(_6e).split(""),function(chr){
+return this.glyphs[chr]||{xAdvance:this.advance.missing.x};
+},this))*(_6f||1);
+},getLineHeight:function(_71){
+return this.viewbox.height*(_71||1);
+},getCenterline:function(_72){
+return (_72||1)*(this.viewbox.height/2);
+},getBaseline:function(_73){
+return (_73||1)*(this.viewbox.height+this.descent);
+},draw:function(_74,_75,_76,_77,_78){
+if(!this.initialized()){
+throw new Error("dojox.gfx.VectorFont.draw(): we have not been initialized yet.");
+}
+var g=_74.createGroup();
+if(_75.x||_75.y){
+_74.applyTransform({dx:_75.x||0,dy:_75.y||0});
+}
+var _7a=dojo.map(this._normalize(_75.text).split(""),function(chr){
+return this.glyphs[chr]||{path:null,xAdvance:this.advance.missing.x};
+},this);
+var _7c=_76.size,_7d=_75.fitting,_7e=_75.width,_7f=_75.height,_80=_75.align,_81=_75.leading||this._defaultLeading;
+if(_7d){
+if((_7d==dojox.gfx.vectorFontFitting.FLOW&&!_7e)||(_7d==dojox.gfx.vectorFontFitting.FIT&&(!_7e||!_7f))){
+_7d=dojox.gfx.vectorFontFitting.NONE;
+}
+}
+var _82,_83;
+switch(_7d){
+case dojox.gfx.vectorFontFitting.FIT:
+var o=this._getBestFit(_7a,_7e,_7f,_81);
+_83=o.scale;
+_82=o.lines;
+break;
+case dojox.gfx.vectorFontFitting.FLOW:
+_83=this._getSizeFactor(_7c);
+_82=this._getBestFlow(_7a,_7e,_83);
+break;
+default:
+_83=this._getSizeFactor(_7c);
+_82=[_7a];
+}
+_82=dojo.filter(_82,function(_85){
+return _85.length>0;
+});
+var cy=0,_87=this._getLongestLine(_82).width;
+for(var i=0,l=_82.length;i<l;i++){
+var cx=0,_8b=_82[i],_8c=this._getWidth(_8b),lg=g.createGroup();
+for(var j=0;j<_8b.length;j++){
+var _8f=_8b[j];
+if(_8f.path!==null){
+var p=lg.createPath(_8f.path).setFill(_77);
+if(_78){
+p.setStroke(_78);
+}
+p.setTransform([dojox.gfx.matrix.flipY,dojox.gfx.matrix.translate(cx,-this.viewbox.height-this.descent)]);
+}
+cx+=_8f.xAdvance;
+if(j+1<_8b.length&&_8f.kern&&_8f.kern[_8b[j+1].code]){
+cx+=_8f.kern[_8b[j+1].code].x;
+}
+}
+var dx=0;
+if(_80=="middle"){
+dx=_87/2-_8c/2;
+}else{
+if(_80=="end"){
+dx=_87-_8c;
+}
+}
+lg.setTransform({dx:dx,dy:cy});
+cy+=this.viewbox.height*_81;
+}
+g.setTransform(dojox.gfx.matrix.scale(_83));
+return g;
+},onLoadBegin:function(url){
+},onLoad:function(_93){
+}});
+})();
+}
diff --git a/dojox/gfx/_base.js b/dojox/gfx/_base.js
new file mode 100644
index 0000000..6aaa0c1
--- /dev/null
+++ b/dojox/gfx/_base.js
@@ -0,0 +1,218 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx._base"]){
+dojo._hasResource["dojox.gfx._base"]=true;
+dojo.provide("dojox.gfx._base");
+(function(){
+var g=dojox.gfx,b=g._base;
+g._hasClass=function(_3,_4){
+var _5=_3.getAttribute("className");
+return _5&&(" "+_5+" ").indexOf(" "+_4+" ")>=0;
+};
+g._addClass=function(_6,_7){
+var _8=_6.getAttribute("className")||"";
+if(!_8||(" "+_8+" ").indexOf(" "+_7+" ")<0){
+_6.setAttribute("className",_8+(_8?" ":"")+_7);
+}
+};
+g._removeClass=function(_9,_a){
+var _b=_9.getAttribute("className");
+if(_b){
+_9.setAttribute("className",_b.replace(new RegExp("(^|\\s+)"+_a+"(\\s+|$)"),"$1$2"));
+}
+};
+b._getFontMeasurements=function(){
+var _c={"1em":0,"1ex":0,"100%":0,"12pt":0,"16px":0,"xx-small":0,"x-small":0,"small":0,"medium":0,"large":0,"x-large":0,"xx-large":0};
+if(dojo.isIE){
+dojo.doc.documentElement.style.fontSize="100%";
+}
+var _d=dojo.doc.createElement("div");
+var s=_d.style;
+s.position="absolute";
+s.left="-100px";
+s.top="0px";
+s.width="30px";
+s.height="1000em";
+s.border="0px";
+s.margin="0px";
+s.padding="0px";
+s.outline="none";
+s.lineHeight="1";
+s.overflow="hidden";
+dojo.body().appendChild(_d);
+for(var p in _c){
+_d.style.fontSize=p;
+_c[p]=Math.round(_d.offsetHeight*12/16)*16/12/1000;
+}
+dojo.body().removeChild(_d);
+_d=null;
+return _c;
+};
+var _10=null;
+b._getCachedFontMeasurements=function(_11){
+if(_11||!_10){
+_10=b._getFontMeasurements();
+}
+return _10;
+};
+var _12=null,_13={};
+b._getTextBox=function(_14,_15,_16){
+var m,s;
+if(!_12){
+m=_12=dojo.doc.createElement("div");
+s=m.style;
+s.position="absolute";
+s.left="-10000px";
+s.top="0";
+dojo.body().appendChild(m);
+}else{
+m=_12;
+s=m.style;
+}
+m.className="";
+s.border="0";
+s.margin="0";
+s.padding="0";
+s.outline="0";
+if(arguments.length>1&&_15){
+for(var i in _15){
+if(i in _13){
+continue;
+}
+s[i]=_15[i];
+}
+}
+if(arguments.length>2&&_16){
+m.className=_16;
+}
+m.innerHTML=_14;
+return dojo.marginBox(m);
+};
+var _1a=0;
+b._getUniqueId=function(){
+var id;
+do{
+id=dojo._scopeName+"Unique"+(++_1a);
+}while(dojo.byId(id));
+return id;
+};
+})();
+dojo.mixin(dojox.gfx,{defaultPath:{type:"path",path:""},defaultPolyline:{type:"polyline",points:[]},defaultRect:{type:"rect",x:0,y:0,width:100,height:100,r:0},defaultEllipse:{type:"ellipse",cx:0,cy:0,rx:200,ry:100},defaultCircle:{type:"circle",cx:0,cy:0,r:100},defaultLine:{type:"line",x1:0,y1:0,x2:100,y2:100},defaultImage:{type:"image",x:0,y:0,width:0,height:0,src:""},defaultText:{type:"text",x:0,y:0,text:"",align:"start",decoration:"none",rotated:false,kerning:true},defaultTextPath:{typ [...]
+var _1c={};
+return function(_1d){
+var t=_1c[_1d];
+if(t){
+return new t();
+}
+t=_1c[_1d]=function(){
+};
+t.prototype=dojox.gfx["default"+_1d];
+return new t();
+};
+})(),normalizeColor:function(_1f){
+return (_1f instanceof dojo.Color)?_1f:new dojo.Color(_1f);
+},normalizeParameters:function(_20,_21){
+if(_21){
+var _22={};
+for(var x in _20){
+if(x in _21&&!(x in _22)){
+_20[x]=_21[x];
+}
+}
+}
+return _20;
+},makeParameters:function(_24,_25){
+if(!_25){
+return dojo.delegate(_24);
+}
+var _26={};
+for(var i in _24){
+if(!(i in _26)){
+_26[i]=dojo.clone((i in _25)?_25[i]:_24[i]);
+}
+}
+return _26;
+},formatNumber:function(x,_29){
+var val=x.toString();
+if(val.indexOf("e")>=0){
+val=x.toFixed(4);
+}else{
+var _2b=val.indexOf(".");
+if(_2b>=0&&val.length-_2b>5){
+val=x.toFixed(4);
+}
+}
+if(x<0){
+return val;
+}
+return _29?" "+val:val;
+},makeFontString:function(_2c){
+return _2c.style+" "+_2c.variant+" "+_2c.weight+" "+_2c.size+" "+_2c.family;
+},splitFontString:function(str){
+var _2e=dojox.gfx.getDefault("Font");
+var t=str.split(/\s+/);
+do{
+if(t.length<5){
+break;
+}
+_2e.style=t[0];
+_2e.varian=t[1];
+_2e.weight=t[2];
+var i=t[3].indexOf("/");
+_2e.size=i<0?t[3]:t[3].substring(0,i);
+var j=4;
+if(i<0){
+if(t[4]=="/"){
+j=6;
+break;
+}
+if(t[4].substr(0,1)=="/"){
+j=5;
+break;
+}
+}
+if(j+3>t.length){
+break;
+}
+_2e.size=t[j];
+_2e.family=t[j+1];
+}while(false);
+return _2e;
+},cm_in_pt:72/2.54,mm_in_pt:7.2/2.54,px_in_pt:function(){
+return dojox.gfx._base._getCachedFontMeasurements()["12pt"]/12;
+},pt2px:function(len){
+return len*dojox.gfx.px_in_pt();
+},px2pt:function(len){
+return len/dojox.gfx.px_in_pt();
+},normalizedLength:function(len){
+if(len.length==0){
+return 0;
+}
+if(len.length>2){
+var _35=dojox.gfx.px_in_pt();
+var val=parseFloat(len);
+switch(len.slice(-2)){
+case "px":
+return val;
+case "pt":
+return val*_35;
+case "in":
+return val*72*_35;
+case "pc":
+return val*12*_35;
+case "mm":
+return val*dojox.gfx.mm_in_pt*_35;
+case "cm":
+return val*dojox.gfx.cm_in_pt*_35;
+}
+}
+return parseFloat(len);
+},pathVmlRegExp:/([A-Za-z]+)|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g,pathSvgRegExp:/([A-Za-z])|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g,equalSources:function(a,b){
+return a&&b&&a==b;
+}});
+}
diff --git a/dojox/gfx/arc.js b/dojox/gfx/arc.js
new file mode 100644
index 0000000..f707fed
--- /dev/null
+++ b/dojox/gfx/arc.js
@@ -0,0 +1,65 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx.arc"]){
+dojo._hasResource["dojox.gfx.arc"]=true;
+dojo.provide("dojox.gfx.arc");
+dojo.require("dojox.gfx.matrix");
+(function(){
+var m=dojox.gfx.matrix,_2=function(_3){
+var _4=Math.cos(_3),_5=Math.sin(_3),p2={x:_4+(4/3)*(1-_4),y:_5-(4/3)*_4*(1-_4)/_5};
+return {s:{x:_4,y:-_5},c1:{x:p2.x,y:-p2.y},c2:p2,e:{x:_4,y:_5}};
+},_7=2*Math.PI,_8=Math.PI/4,_9=Math.PI/8,_a=_8+_9,_b=_2(_9);
+dojo.mixin(dojox.gfx.arc,{unitArcAsBezier:_2,curvePI4:_b,arcAsBezier:function(_c,rx,ry,_f,_10,_11,x,y){
+_10=Boolean(_10);
+_11=Boolean(_11);
+var _14=m._degToRad(_f),rx2=rx*rx,ry2=ry*ry,pa=m.multiplyPoint(m.rotate(-_14),{x:(_c.x-x)/2,y:(_c.y-y)/2}),_18=pa.x*pa.x,_19=pa.y*pa.y,c1=Math.sqrt((rx2*ry2-rx2*_19-ry2*_18)/(rx2*_19+ry2*_18));
+if(isNaN(c1)){
+c1=0;
+}
+var ca={x:c1*rx*pa.y/ry,y:-c1*ry*pa.x/rx};
+if(_10==_11){
+ca={x:-ca.x,y:-ca.y};
+}
+var c=m.multiplyPoint([m.translate((_c.x+x)/2,(_c.y+y)/2),m.rotate(_14)],ca);
+var _1d=m.normalize([m.translate(c.x,c.y),m.rotate(_14),m.scale(rx,ry)]);
+var _1e=m.invert(_1d),sp=m.multiplyPoint(_1e,_c),ep=m.multiplyPoint(_1e,x,y),_21=Math.atan2(sp.y,sp.x),_22=Math.atan2(ep.y,ep.x),_23=_21-_22;
+if(_11){
+_23=-_23;
+}
+if(_23<0){
+_23+=_7;
+}else{
+if(_23>_7){
+_23-=_7;
+}
+}
+var _24=_9,_25=_b,_26=_11?_24:-_24,_27=[];
+for(var _28=_23;_28>0;_28-=_8){
+if(_28<_a){
+_24=_28/2;
+_25=_2(_24);
+_26=_11?_24:-_24;
+_28=0;
+}
+var c1,c2,e,M=m.normalize([_1d,m.rotate(_21+_26)]);
+if(_11){
+c1=m.multiplyPoint(M,_25.c1);
+c2=m.multiplyPoint(M,_25.c2);
+e=m.multiplyPoint(M,_25.e);
+}else{
+c1=m.multiplyPoint(M,_25.c2);
+c2=m.multiplyPoint(M,_25.c1);
+e=m.multiplyPoint(M,_25.s);
+}
+_27.push([c1.x,c1.y,c2.x,c2.y,e.x,e.y]);
+_21+=2*_26;
+}
+return _27;
+}});
+})();
+}
diff --git a/dojox/gfx/attach.js b/dojox/gfx/attach.js
new file mode 100644
index 0000000..b41d64b
--- /dev/null
+++ b/dojox/gfx/attach.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+dojo.require("dojox.gfx");
+dojo.requireIf(dojox.gfx.renderer=="svg","dojox.gfx.svg_attach");
+dojo.requireIf(dojox.gfx.renderer=="vml","dojox.gfx.vml_attach");
+dojo.requireIf(dojox.gfx.renderer=="silverlight","dojox.gfx.silverlight_attach");
+dojo.requireIf(dojox.gfx.renderer=="canvas","dojox.gfx.canvas_attach");
diff --git a/dojox/gfx/canvas.js b/dojox/gfx/canvas.js
new file mode 100644
index 0000000..8487423
--- /dev/null
+++ b/dojox/gfx/canvas.js
@@ -0,0 +1,498 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx.canvas"]){
+dojo._hasResource["dojox.gfx.canvas"]=true;
+dojo.provide("dojox.gfx.canvas");
+dojo.require("dojox.gfx._base");
+dojo.require("dojox.gfx.shape");
+dojo.require("dojox.gfx.path");
+dojo.require("dojox.gfx.arc");
+dojo.require("dojox.gfx.decompose");
+dojo.experimental("dojox.gfx.canvas");
+(function(){
+var g=dojox.gfx,gs=g.shape,ga=g.arc,m=g.matrix,mp=m.multiplyPoint,pi=Math.PI,_7=2*pi,_8=pi/2;
+dojo.extend(g.Shape,{_render:function(_9){
+_9.save();
+this._renderTransform(_9);
+this._renderShape(_9);
+this._renderFill(_9,true);
+this._renderStroke(_9,true);
+_9.restore();
+},_renderTransform:function(_a){
+if("canvasTransform" in this){
+var t=this.canvasTransform;
+_a.translate(t.dx,t.dy);
+_a.rotate(t.angle2);
+_a.scale(t.sx,t.sy);
+_a.rotate(t.angle1);
+}
+},_renderShape:function(_c){
+},_renderFill:function(_d,_e){
+if("canvasFill" in this){
+if("canvasFillImage" in this){
+this.canvasFill=_d.createPattern(this.canvasFillImage,"repeat");
+delete this.canvasFillImage;
+}
+_d.fillStyle=this.canvasFill;
+if(_e){
+_d.fill();
+}
+}else{
+_d.fillStyle="rgba(0,0,0,0.0)";
+}
+},_renderStroke:function(_f,_10){
+var s=this.strokeStyle;
+if(s){
+_f.strokeStyle=s.color.toString();
+_f.lineWidth=s.width;
+_f.lineCap=s.cap;
+if(typeof s.join=="number"){
+_f.lineJoin="miter";
+_f.miterLimit=s.join;
+}else{
+_f.lineJoin=s.join;
+}
+if(_10){
+_f.stroke();
+}
+}else{
+if(!_10){
+_f.strokeStyle="rgba(0,0,0,0.0)";
+}
+}
+},getEventSource:function(){
+return null;
+},connect:function(){
+},disconnect:function(){
+}});
+var _12=function(_13,_14,_15){
+var old=_13.prototype[_14];
+_13.prototype[_14]=_15?function(){
+this.surface.makeDirty();
+old.apply(this,arguments);
+_15.call(this);
+return this;
+}:function(){
+this.surface.makeDirty();
+return old.apply(this,arguments);
+};
+};
+_12(g.Shape,"setTransform",function(){
+if(this.matrix){
+this.canvasTransform=g.decompose(this.matrix);
+}else{
+delete this.canvasTransform;
+}
+});
+_12(g.Shape,"setFill",function(){
+var fs=this.fillStyle,f;
+if(fs){
+if(typeof (fs)=="object"&&"type" in fs){
+var ctx=this.surface.rawNode.getContext("2d");
+switch(fs.type){
+case "linear":
+case "radial":
+f=fs.type=="linear"?ctx.createLinearGradient(fs.x1,fs.y1,fs.x2,fs.y2):ctx.createRadialGradient(fs.cx,fs.cy,0,fs.cx,fs.cy,fs.r);
+dojo.forEach(fs.colors,function(_1a){
+f.addColorStop(_1a.offset,g.normalizeColor(_1a.color).toString());
+});
+break;
+case "pattern":
+var img=new Image(fs.width,fs.height);
+this.surface.downloadImage(img,fs.src);
+this.canvasFillImage=img;
+}
+}else{
+f=fs.toString();
+}
+this.canvasFill=f;
+}else{
+delete this.canvasFill;
+}
+});
+_12(g.Shape,"setStroke");
+_12(g.Shape,"setShape");
+dojo.declare("dojox.gfx.Group",g.Shape,{constructor:function(){
+gs.Container._init.call(this);
+},_render:function(ctx){
+ctx.save();
+this._renderTransform(ctx);
+this._renderFill(ctx);
+this._renderStroke(ctx);
+for(var i=0;i<this.children.length;++i){
+this.children[i]._render(ctx);
+}
+ctx.restore();
+}});
+dojo.declare("dojox.gfx.Rect",gs.Rect,{_renderShape:function(ctx){
+var s=this.shape,r=Math.min(s.r,s.height/2,s.width/2),xl=s.x,xr=xl+s.width,yt=s.y,yb=yt+s.height,xl2=xl+r,xr2=xr-r,yt2=yt+r,yb2=yb-r;
+ctx.beginPath();
+ctx.moveTo(xl2,yt);
+if(r){
+ctx.arc(xr2,yt2,r,-_8,0,false);
+ctx.arc(xr2,yb2,r,0,_8,false);
+ctx.arc(xl2,yb2,r,_8,pi,false);
+ctx.arc(xl2,yt2,r,pi,_8,false);
+}else{
+ctx.lineTo(xr2,yt);
+ctx.lineTo(xr,yb2);
+ctx.lineTo(xl2,yb);
+ctx.lineTo(xl,yt2);
+}
+ctx.closePath();
+}});
+var _29=[];
+(function(){
+var u=ga.curvePI4;
+_29.push(u.s,u.c1,u.c2,u.e);
+for(var a=45;a<360;a+=45){
+var r=m.rotateg(a);
+_29.push(mp(r,u.c1),mp(r,u.c2),mp(r,u.e));
+}
+})();
+dojo.declare("dojox.gfx.Ellipse",gs.Ellipse,{setShape:function(){
+g.Ellipse.superclass.setShape.apply(this,arguments);
+var s=this.shape,t,c1,c2,r=[],M=m.normalize([m.translate(s.cx,s.cy),m.scale(s.rx,s.ry)]);
+t=mp(M,_29[0]);
+r.push([t.x,t.y]);
+for(var i=1;i<_29.length;i+=3){
+c1=mp(M,_29[i]);
+c2=mp(M,_29[i+1]);
+t=mp(M,_29[i+2]);
+r.push([c1.x,c1.y,c2.x,c2.y,t.x,t.y]);
+}
+this.canvasEllipse=r;
+return this;
+},_renderShape:function(ctx){
+var r=this.canvasEllipse;
+ctx.beginPath();
+ctx.moveTo.apply(ctx,r[0]);
+for(var i=1;i<r.length;++i){
+ctx.bezierCurveTo.apply(ctx,r[i]);
+}
+ctx.closePath();
+}});
+dojo.declare("dojox.gfx.Circle",gs.Circle,{_renderShape:function(ctx){
+var s=this.shape;
+ctx.beginPath();
+ctx.arc(s.cx,s.cy,s.r,0,_7,1);
+}});
+dojo.declare("dojox.gfx.Line",gs.Line,{_renderShape:function(ctx){
+var s=this.shape;
+ctx.beginPath();
+ctx.moveTo(s.x1,s.y1);
+ctx.lineTo(s.x2,s.y2);
+}});
+dojo.declare("dojox.gfx.Polyline",gs.Polyline,{setShape:function(){
+g.Polyline.superclass.setShape.apply(this,arguments);
+var p=this.shape.points,f=p[0],r=[],c,i;
+if(p.length){
+if(typeof f=="number"){
+r.push(f,p[1]);
+i=2;
+}else{
+r.push(f.x,f.y);
+i=1;
+}
+for(;i<p.length;++i){
+c=p[i];
+if(typeof c=="number"){
+r.push(c,p[++i]);
+}else{
+r.push(c.x,c.y);
+}
+}
+}
+this.canvasPolyline=r;
+return this;
+},_renderShape:function(ctx){
+var p=this.canvasPolyline;
+if(p.length){
+ctx.beginPath();
+ctx.moveTo(p[0],p[1]);
+for(var i=2;i<p.length;i+=2){
+ctx.lineTo(p[i],p[i+1]);
+}
+}
+}});
+dojo.declare("dojox.gfx.Image",gs.Image,{setShape:function(){
+g.Image.superclass.setShape.apply(this,arguments);
+var img=new Image();
+this.surface.downloadImage(img,this.shape.src);
+this.canvasImage=img;
+return this;
+},_renderShape:function(ctx){
+var s=this.shape;
+ctx.drawImage(this.canvasImage,s.x,s.y,s.width,s.height);
+}});
+dojo.declare("dojox.gfx.Text",gs.Text,{_renderShape:function(ctx){
+var s=this.shape;
+}});
+_12(g.Text,"setFont");
+var _48={M:"_moveToA",m:"_moveToR",L:"_lineToA",l:"_lineToR",H:"_hLineToA",h:"_hLineToR",V:"_vLineToA",v:"_vLineToR",C:"_curveToA",c:"_curveToR",S:"_smoothCurveToA",s:"_smoothCurveToR",Q:"_qCurveToA",q:"_qCurveToR",T:"_qSmoothCurveToA",t:"_qSmoothCurveToR",A:"_arcTo",a:"_arcTo",Z:"_closePath",z:"_closePath"};
+dojo.declare("dojox.gfx.Path",g.path.Path,{constructor:function(){
+this.lastControl={};
+},setShape:function(){
+this.canvasPath=[];
+return g.Path.superclass.setShape.apply(this,arguments);
+},_updateWithSegment:function(_49){
+var _4a=dojo.clone(this.last);
+this[_48[_49.action]](this.canvasPath,_49.action,_49.args);
+this.last=_4a;
+g.Path.superclass._updateWithSegment.apply(this,arguments);
+},_renderShape:function(ctx){
+var r=this.canvasPath;
+ctx.beginPath();
+for(var i=0;i<r.length;i+=2){
+ctx[r[i]].apply(ctx,r[i+1]);
+}
+},_moveToA:function(_4e,_4f,_50){
+_4e.push("moveTo",[_50[0],_50[1]]);
+for(var i=2;i<_50.length;i+=2){
+_4e.push("lineTo",[_50[i],_50[i+1]]);
+}
+this.last.x=_50[_50.length-2];
+this.last.y=_50[_50.length-1];
+this.lastControl={};
+},_moveToR:function(_52,_53,_54){
+if("x" in this.last){
+_52.push("moveTo",[this.last.x+=_54[0],this.last.y+=_54[1]]);
+}else{
+_52.push("moveTo",[this.last.x=_54[0],this.last.y=_54[1]]);
+}
+for(var i=2;i<_54.length;i+=2){
+_52.push("lineTo",[this.last.x+=_54[i],this.last.y+=_54[i+1]]);
+}
+this.lastControl={};
+},_lineToA:function(_56,_57,_58){
+for(var i=0;i<_58.length;i+=2){
+_56.push("lineTo",[_58[i],_58[i+1]]);
+}
+this.last.x=_58[_58.length-2];
+this.last.y=_58[_58.length-1];
+this.lastControl={};
+},_lineToR:function(_5a,_5b,_5c){
+for(var i=0;i<_5c.length;i+=2){
+_5a.push("lineTo",[this.last.x+=_5c[i],this.last.y+=_5c[i+1]]);
+}
+this.lastControl={};
+},_hLineToA:function(_5e,_5f,_60){
+for(var i=0;i<_60.length;++i){
+_5e.push("lineTo",[_60[i],this.last.y]);
+}
+this.last.x=_60[_60.length-1];
+this.lastControl={};
+},_hLineToR:function(_62,_63,_64){
+for(var i=0;i<_64.length;++i){
+_62.push("lineTo",[this.last.x+=_64[i],this.last.y]);
+}
+this.lastControl={};
+},_vLineToA:function(_66,_67,_68){
+for(var i=0;i<_68.length;++i){
+_66.push("lineTo",[this.last.x,_68[i]]);
+}
+this.last.y=_68[_68.length-1];
+this.lastControl={};
+},_vLineToR:function(_6a,_6b,_6c){
+for(var i=0;i<_6c.length;++i){
+_6a.push("lineTo",[this.last.x,this.last.y+=_6c[i]]);
+}
+this.lastControl={};
+},_curveToA:function(_6e,_6f,_70){
+for(var i=0;i<_70.length;i+=6){
+_6e.push("bezierCurveTo",_70.slice(i,i+6));
+}
+this.last.x=_70[_70.length-2];
+this.last.y=_70[_70.length-1];
+this.lastControl.x=_70[_70.length-4];
+this.lastControl.y=_70[_70.length-3];
+this.lastControl.type="C";
+},_curveToR:function(_72,_73,_74){
+for(var i=0;i<_74.length;i+=6){
+_72.push("bezierCurveTo",[this.last.x+_74[i],this.last.y+_74[i+1],this.lastControl.x=this.last.x+_74[i+2],this.lastControl.y=this.last.y+_74[i+3],this.last.x+_74[i+4],this.last.y+_74[i+5]]);
+this.last.x+=_74[i+4];
+this.last.y+=_74[i+5];
+}
+this.lastControl.type="C";
+},_smoothCurveToA:function(_76,_77,_78){
+for(var i=0;i<_78.length;i+=4){
+var _7a=this.lastControl.type=="C";
+_76.push("bezierCurveTo",[_7a?2*this.last.x-this.lastControl.x:this.last.x,_7a?2*this.last.y-this.lastControl.y:this.last.y,_78[i],_78[i+1],_78[i+2],_78[i+3]]);
+this.lastControl.x=_78[i];
+this.lastControl.y=_78[i+1];
+this.lastControl.type="C";
+}
+this.last.x=_78[_78.length-2];
+this.last.y=_78[_78.length-1];
+},_smoothCurveToR:function(_7b,_7c,_7d){
+for(var i=0;i<_7d.length;i+=4){
+var _7f=this.lastControl.type=="C";
+_7b.push("bezierCurveTo",[_7f?2*this.last.x-this.lastControl.x:this.last.x,_7f?2*this.last.y-this.lastControl.y:this.last.y,this.last.x+_7d[i],this.last.y+_7d[i+1],this.last.x+_7d[i+2],this.last.y+_7d[i+3]]);
+this.lastControl.x=this.last.x+_7d[i];
+this.lastControl.y=this.last.y+_7d[i+1];
+this.lastControl.type="C";
+this.last.x+=_7d[i+2];
+this.last.y+=_7d[i+3];
+}
+},_qCurveToA:function(_80,_81,_82){
+for(var i=0;i<_82.length;i+=4){
+_80.push("quadraticCurveTo",_82.slice(i,i+4));
+}
+this.last.x=_82[_82.length-2];
+this.last.y=_82[_82.length-1];
+this.lastControl.x=_82[_82.length-4];
+this.lastControl.y=_82[_82.length-3];
+this.lastControl.type="Q";
+},_qCurveToR:function(_84,_85,_86){
+for(var i=0;i<_86.length;i+=4){
+_84.push("quadraticCurveTo",[this.lastControl.x=this.last.x+_86[i],this.lastControl.y=this.last.y+_86[i+1],this.last.x+_86[i+2],this.last.y+_86[i+3]]);
+this.last.x+=_86[i+2];
+this.last.y+=_86[i+3];
+}
+this.lastControl.type="Q";
+},_qSmoothCurveToA:function(_88,_89,_8a){
+for(var i=0;i<_8a.length;i+=2){
+var _8c=this.lastControl.type=="Q";
+_88.push("quadraticCurveTo",[this.lastControl.x=_8c?2*this.last.x-this.lastControl.x:this.last.x,this.lastControl.y=_8c?2*this.last.y-this.lastControl.y:this.last.y,_8a[i],_8a[i+1]]);
+this.lastControl.type="Q";
+}
+this.last.x=_8a[_8a.length-2];
+this.last.y=_8a[_8a.length-1];
+},_qSmoothCurveToR:function(_8d,_8e,_8f){
+for(var i=0;i<_8f.length;i+=2){
+var _91=this.lastControl.type=="Q";
+_8d.push("quadraticCurveTo",[this.lastControl.x=_91?2*this.last.x-this.lastControl.x:this.last.x,this.lastControl.y=_91?2*this.last.y-this.lastControl.y:this.last.y,this.last.x+_8f[i],this.last.y+_8f[i+1]]);
+this.lastControl.type="Q";
+this.last.x+=_8f[i];
+this.last.y+=_8f[i+1];
+}
+},_arcTo:function(_92,_93,_94){
+var _95=_93=="a";
+for(var i=0;i<_94.length;i+=7){
+var x1=_94[i+5],y1=_94[i+6];
+if(_95){
+x1+=this.last.x;
+y1+=this.last.y;
+}
+var _99=ga.arcAsBezier(this.last,_94[i],_94[i+1],_94[i+2],_94[i+3]?1:0,_94[i+4]?1:0,x1,y1);
+dojo.forEach(_99,function(p){
+_92.push("bezierCurveTo",p);
+});
+this.last.x=x1;
+this.last.y=y1;
+}
+this.lastControl={};
+},_closePath:function(_9b,_9c,_9d){
+_9b.push("closePath",[]);
+this.lastControl={};
+}});
+dojo.forEach(["moveTo","lineTo","hLineTo","vLineTo","curveTo","smoothCurveTo","qCurveTo","qSmoothCurveTo","arcTo","closePath"],function(_9e){
+_12(g.Path,_9e);
+});
+dojo.declare("dojox.gfx.TextPath",g.path.TextPath,{_renderShape:function(ctx){
+var s=this.shape;
+}});
+dojo.declare("dojox.gfx.Surface",gs.Surface,{constructor:function(){
+gs.Container._init.call(this);
+this.pendingImageCount=0;
+this.makeDirty();
+},setDimensions:function(_a1,_a2){
+this.width=g.normalizedLength(_a1);
+this.height=g.normalizedLength(_a2);
+if(!this.rawNode){
+return this;
+}
+this.rawNode.width=_a1;
+this.rawNode.height=_a2;
+this.makeDirty();
+return this;
+},getDimensions:function(){
+return this.rawNode?{width:this.rawNode.width,height:this.rawNode.height}:null;
+},_render:function(){
+if(this.pendingImageCount){
+return;
+}
+var ctx=this.rawNode.getContext("2d");
+ctx.save();
+ctx.clearRect(0,0,this.rawNode.width,this.rawNode.height);
+for(var i=0;i<this.children.length;++i){
+this.children[i]._render(ctx);
+}
+ctx.restore();
+if("pendingRender" in this){
+clearTimeout(this.pendingRender);
+delete this.pendingRender;
+}
+},makeDirty:function(){
+if(!this.pendingImagesCount&&!("pendingRender" in this)){
+this.pendingRender=setTimeout(dojo.hitch(this,this._render),0);
+}
+},downloadImage:function(img,url){
+var _a7=dojo.hitch(this,this.onImageLoad);
+if(!this.pendingImageCount++&&"pendingRender" in this){
+clearTimeout(this.pendingRender);
+delete this.pendingRender;
+}
+img.onload=_a7;
+img.onerror=_a7;
+img.onabort=_a7;
+img.src=url;
+},onImageLoad:function(){
+if(!--this.pendingImageCount){
+this._render();
+}
+},getEventSource:function(){
+return null;
+},connect:function(){
+},disconnect:function(){
+}});
+g.createSurface=function(_a8,_a9,_aa){
+if(!_a9){
+_a9="100%";
+}
+if(!_aa){
+_aa="100%";
+}
+var s=new g.Surface(),p=dojo.byId(_a8),c=p.ownerDocument.createElement("canvas");
+c.width=_a9;
+c.height=_aa;
+p.appendChild(c);
+s.rawNode=c;
+s._parent=p;
+s.surface=s;
+return s;
+};
+var C=gs.Container,_af={add:function(_b0){
+this.surface.makeDirty();
+return C.add.apply(this,arguments);
+},remove:function(_b1,_b2){
+this.surface.makeDirty();
+return C.remove.apply(this,arguments);
+},clear:function(){
+this.surface.makeDirty();
+return C.clear.apply(this,arguments);
+},_moveChildToFront:function(_b3){
+this.surface.makeDirty();
+return C._moveChildToFront.apply(this,arguments);
+},_moveChildToBack:function(_b4){
+this.surface.makeDirty();
+return C._moveChildToBack.apply(this,arguments);
+}};
+dojo.mixin(gs.Creator,{createObject:function(_b5,_b6){
+var _b7=new _b5();
+_b7.surface=this.surface;
+_b7.setShape(_b6);
+this.add(_b7);
+return _b7;
+}});
+dojo.extend(g.Group,_af);
+dojo.extend(g.Group,gs.Creator);
+dojo.extend(g.Surface,_af);
+dojo.extend(g.Surface,gs.Creator);
+})();
+}
diff --git a/dojox/gfx/canvas_attach.js b/dojox/gfx/canvas_attach.js
new file mode 100644
index 0000000..8862ba3
--- /dev/null
+++ b/dojox/gfx/canvas_attach.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+dojo.require("dojox.gfx.canvas");
+dojo.experimental("dojox.gfx.canvas_attach");
+dojox.gfx.attachNode=function(){
+return null;
+};
diff --git a/dojox/gfx/decompose.js b/dojox/gfx/decompose.js
new file mode 100644
index 0000000..91bb944
--- /dev/null
+++ b/dojox/gfx/decompose.js
@@ -0,0 +1,106 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx.decompose"]){
+dojo._hasResource["dojox.gfx.decompose"]=true;
+dojo.provide("dojox.gfx.decompose");
+dojo.require("dojox.gfx.matrix");
+(function(){
+var m=dojox.gfx.matrix;
+var eq=function(a,b){
+return Math.abs(a-b)<=0.000001*(Math.abs(a)+Math.abs(b));
+};
+var _5=function(r1,m1,r2,m2){
+if(!isFinite(r1)){
+return r2;
+}else{
+if(!isFinite(r2)){
+return r1;
+}
+}
+m1=Math.abs(m1),m2=Math.abs(m2);
+return (m1*r1+m2*r2)/(m1+m2);
+};
+var _a=function(_b){
+var M=new m.Matrix2D(_b);
+return dojo.mixin(M,{dx:0,dy:0,xy:M.yx,yx:M.xy});
+};
+var _d=function(_e){
+return (_e.xx*_e.yy<0||_e.xy*_e.yx>0)?-1:1;
+};
+var _f=function(_10){
+var M=m.normalize(_10),b=-M.xx-M.yy,c=M.xx*M.yy-M.xy*M.yx,d=Math.sqrt(b*b-4*c),l1=-(b+(b<0?-d:d))/2,l2=c/l1,vx1=M.xy/(l1-M.xx),vy1=1,vx2=M.xy/(l2-M.xx),vy2=1;
+if(eq(l1,l2)){
+vx1=1,vy1=0,vx2=0,vy2=1;
+}
+if(!isFinite(vx1)){
+vx1=1,vy1=(l1-M.xx)/M.xy;
+if(!isFinite(vy1)){
+vx1=(l1-M.yy)/M.yx,vy1=1;
+if(!isFinite(vx1)){
+vx1=1,vy1=M.yx/(l1-M.yy);
+}
+}
+}
+if(!isFinite(vx2)){
+vx2=1,vy2=(l2-M.xx)/M.xy;
+if(!isFinite(vy2)){
+vx2=(l2-M.yy)/M.yx,vy2=1;
+if(!isFinite(vx2)){
+vx2=1,vy2=M.yx/(l2-M.yy);
+}
+}
+}
+var d1=Math.sqrt(vx1*vx1+vy1*vy1),d2=Math.sqrt(vx2*vx2+vy2*vy2);
+if(!isFinite(vx1/=d1)){
+vx1=0;
+}
+if(!isFinite(vy1/=d1)){
+vy1=0;
+}
+if(!isFinite(vx2/=d2)){
+vx2=0;
+}
+if(!isFinite(vy2/=d2)){
+vy2=0;
+}
+return {value1:l1,value2:l2,vector1:{x:vx1,y:vy1},vector2:{x:vx2,y:vy2}};
+};
+var _1d=function(M,_1f){
+var _20=_d(M),a=_1f.angle1=(Math.atan2(M.yx,M.yy)+Math.atan2(-_20*M.xy,_20*M.xx))/2,cos=Math.cos(a),sin=Math.sin(a);
+_1f.sx=_5(M.xx/cos,cos,-M.xy/sin,sin);
+_1f.sy=_5(M.yy/cos,cos,M.yx/sin,sin);
+return _1f;
+};
+var _24=function(M,_26){
+var _27=_d(M),a=_26.angle2=(Math.atan2(_27*M.yx,_27*M.xx)+Math.atan2(-M.xy,M.yy))/2,cos=Math.cos(a),sin=Math.sin(a);
+_26.sx=_5(M.xx/cos,cos,M.yx/sin,sin);
+_26.sy=_5(M.yy/cos,cos,-M.xy/sin,sin);
+return _26;
+};
+dojox.gfx.decompose=function(_2b){
+var M=m.normalize(_2b),_2d={dx:M.dx,dy:M.dy,sx:1,sy:1,angle1:0,angle2:0};
+if(eq(M.xy,0)&&eq(M.yx,0)){
+return dojo.mixin(_2d,{sx:M.xx,sy:M.yy});
+}
+if(eq(M.xx*M.yx,-M.xy*M.yy)){
+return _1d(M,_2d);
+}
+if(eq(M.xx*M.xy,-M.yx*M.yy)){
+return _24(M,_2d);
+}
+var MT=_a(M),u=_f([M,MT]),v=_f([MT,M]),U=new m.Matrix2D({xx:u.vector1.x,xy:u.vector2.x,yx:u.vector1.y,yy:u.vector2.y}),VT=new m.Matrix2D({xx:v.vector1.x,xy:v.vector1.y,yx:v.vector2.x,yy:v.vector2.y}),S=new m.Matrix2D([m.invert(U),M,m.invert(VT)]);
+_1d(VT,_2d);
+S.xx*=_2d.sx;
+S.yy*=_2d.sy;
+_24(U,_2d);
+S.xx*=_2d.sx;
+S.yy*=_2d.sy;
+return dojo.mixin(_2d,{sx:S.xx,sy:S.yy});
+};
+})();
+}
diff --git a/dojox/gfx/fx.js b/dojox/gfx/fx.js
new file mode 100644
index 0000000..c3b42c1
--- /dev/null
+++ b/dojox/gfx/fx.js
@@ -0,0 +1,227 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx.fx"]){
+dojo._hasResource["dojox.gfx.fx"]=true;
+dojo.provide("dojox.gfx.fx");
+dojo.require("dojox.gfx.matrix");
+(function(){
+var d=dojo,g=dojox.gfx,m=g.matrix;
+var _4=function(_5,_6){
+this.start=_5,this.end=_6;
+};
+d.extend(_4,{getValue:function(r){
+return (this.end-this.start)*r+this.start;
+}});
+var _8=function(_9,_a,_b){
+this.start=_9,this.end=_a;
+this.unit=_b;
+};
+d.extend(_8,{getValue:function(r){
+return (this.end-this.start)*r+this.start+this.unit;
+}});
+var _d=function(_e,_f){
+this.start=_e,this.end=_f;
+this.temp=new dojo.Color();
+};
+d.extend(_d,{getValue:function(r){
+return d.blendColors(this.start,this.end,r,this.temp);
+}});
+var _11=function(_12){
+this.values=_12;
+this.length=_12.length;
+};
+d.extend(_11,{getValue:function(r){
+return this.values[Math.min(Math.floor(r*this.length),this.length-1)];
+}});
+var _14=function(_15,def){
+this.values=_15;
+this.def=def?def:{};
+};
+d.extend(_14,{getValue:function(r){
+var ret=dojo.clone(this.def);
+for(var i in this.values){
+ret[i]=this.values[i].getValue(r);
+}
+return ret;
+}});
+var _1a=function(_1b,_1c){
+this.stack=_1b;
+this.original=_1c;
+};
+d.extend(_1a,{getValue:function(r){
+var ret=[];
+dojo.forEach(this.stack,function(t){
+if(t instanceof m.Matrix2D){
+ret.push(t);
+return;
+}
+if(t.name=="original"&&this.original){
+ret.push(this.original);
+return;
+}
+if(!(t.name in m)){
+return;
+}
+var f=m[t.name];
+if(typeof f!="function"){
+ret.push(f);
+return;
+}
+var val=dojo.map(t.start,function(v,i){
+return (t.end[i]-v)*r+v;
+}),_24=f.apply(m,val);
+if(_24 instanceof m.Matrix2D){
+ret.push(_24);
+}
+},this);
+return ret;
+}});
+var _25=new d.Color(0,0,0,0);
+var _26=function(_27,obj,_29,def){
+if(_27.values){
+return new _11(_27.values);
+}
+var _2b,_2c,end;
+if(_27.start){
+_2c=g.normalizeColor(_27.start);
+}else{
+_2c=_2b=obj?(_29?obj[_29]:obj):def;
+}
+if(_27.end){
+end=g.normalizeColor(_27.end);
+}else{
+if(!_2b){
+_2b=obj?(_29?obj[_29]:obj):def;
+}
+end=_2b;
+}
+return new _d(_2c,end);
+};
+var _2e=function(_2f,obj,_31,def){
+if(_2f.values){
+return new _11(_2f.values);
+}
+var _33,_34,end;
+if(_2f.start){
+_34=_2f.start;
+}else{
+_34=_33=obj?obj[_31]:def;
+}
+if(_2f.end){
+end=_2f.end;
+}else{
+if(typeof _33!="number"){
+_33=obj?obj[_31]:def;
+}
+end=_33;
+}
+return new _4(_34,end);
+};
+g.fx.animateStroke=function(_36){
+if(!_36.easing){
+_36.easing=d._defaultEasing;
+}
+var _37=new d._Animation(_36),_38=_36.shape,_39;
+d.connect(_37,"beforeBegin",_37,function(){
+_39=_38.getStroke();
+var _3a=_36.color,_3b={},_3c,_3d,end;
+if(_3a){
+_3b.color=_26(_3a,_39,"color",_25);
+}
+_3a=_36.style;
+if(_3a&&_3a.values){
+_3b.style=new _11(_3a.values);
+}
+_3a=_36.width;
+if(_3a){
+_3b.width=_2e(_3a,_39,"width",1);
+}
+_3a=_36.cap;
+if(_3a&&_3a.values){
+_3b.cap=new _11(_3a.values);
+}
+_3a=_36.join;
+if(_3a){
+if(_3a.values){
+_3b.join=new _11(_3a.values);
+}else{
+_3d=_3a.start?_3a.start:(_39&&_39.join||0);
+end=_3a.end?_3a.end:(_39&&_39.join||0);
+if(typeof _3d=="number"&&typeof end=="number"){
+_3b.join=new _4(_3d,end);
+}
+}
+}
+this.curve=new _14(_3b,_39);
+});
+d.connect(_37,"onAnimate",_38,"setStroke");
+return _37;
+};
+g.fx.animateFill=function(_3f){
+if(!_3f.easing){
+_3f.easing=d._defaultEasing;
+}
+var _40=new d._Animation(_3f),_41=_3f.shape,_42;
+d.connect(_40,"beforeBegin",_40,function(){
+_42=_41.getFill();
+var _43=_3f.color,_44={};
+if(_43){
+this.curve=_26(_43,_42,"",_25);
+}
+});
+d.connect(_40,"onAnimate",_41,"setFill");
+return _40;
+};
+g.fx.animateFont=function(_45){
+if(!_45.easing){
+_45.easing=d._defaultEasing;
+}
+var _46=new d._Animation(_45),_47=_45.shape,_48;
+d.connect(_46,"beforeBegin",_46,function(){
+_48=_47.getFont();
+var _49=_45.style,_4a={},_4b,_4c,end;
+if(_49&&_49.values){
+_4a.style=new _11(_49.values);
+}
+_49=_45.variant;
+if(_49&&_49.values){
+_4a.variant=new _11(_49.values);
+}
+_49=_45.weight;
+if(_49&&_49.values){
+_4a.weight=new _11(_49.values);
+}
+_49=_45.family;
+if(_49&&_49.values){
+_4a.family=new _11(_49.values);
+}
+_49=_45.size;
+if(_49&&_49.unit){
+_4c=parseFloat(_49.start?_49.start:(_47.font&&_47.font.size||"0"));
+end=parseFloat(_49.end?_49.end:(_47.font&&_47.font.size||"0"));
+_4a.size=new _8(_4c,end,_49.unit);
+}
+this.curve=new _14(_4a,_48);
+});
+d.connect(_46,"onAnimate",_47,"setFont");
+return _46;
+};
+g.fx.animateTransform=function(_4e){
+if(!_4e.easing){
+_4e.easing=d._defaultEasing;
+}
+var _4f=new d._Animation(_4e),_50=_4e.shape,_51;
+d.connect(_4f,"beforeBegin",_4f,function(){
+_51=_50.getTransform();
+this.curve=new _1a(_4e.transform,_51);
+});
+d.connect(_4f,"onAnimate",_50,"setTransform");
+return _4f;
+};
+})();
+}
diff --git a/dojox/gfx/matrix.js b/dojox/gfx/matrix.js
new file mode 100644
index 0000000..72b90c8
--- /dev/null
+++ b/dojox/gfx/matrix.js
@@ -0,0 +1,168 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx.matrix"]){
+dojo._hasResource["dojox.gfx.matrix"]=true;
+dojo.provide("dojox.gfx.matrix");
+(function(){
+var m=dojox.gfx.matrix;
+var _2={};
+m._degToRad=function(_3){
+return _2[_3]||(_2[_3]=(Math.PI*_3/180));
+};
+m._radToDeg=function(_4){
+return _4/Math.PI*180;
+};
+m.Matrix2D=function(_5){
+if(_5){
+if(typeof _5=="number"){
+this.xx=this.yy=_5;
+}else{
+if(_5 instanceof Array){
+if(_5.length>0){
+var _6=m.normalize(_5[0]);
+for(var i=1;i<_5.length;++i){
+var l=_6,r=dojox.gfx.matrix.normalize(_5[i]);
+_6=new m.Matrix2D();
+_6.xx=l.xx*r.xx+l.xy*r.yx;
+_6.xy=l.xx*r.xy+l.xy*r.yy;
+_6.yx=l.yx*r.xx+l.yy*r.yx;
+_6.yy=l.yx*r.xy+l.yy*r.yy;
+_6.dx=l.xx*r.dx+l.xy*r.dy+l.dx;
+_6.dy=l.yx*r.dx+l.yy*r.dy+l.dy;
+}
+dojo.mixin(this,_6);
+}
+}else{
+dojo.mixin(this,_5);
+}
+}
+}
+};
+dojo.extend(m.Matrix2D,{xx:1,xy:0,yx:0,yy:1,dx:0,dy:0});
+dojo.mixin(m,{identity:new m.Matrix2D(),flipX:new m.Matrix2D({xx:-1}),flipY:new m.Matrix2D({yy:-1}),flipXY:new m.Matrix2D({xx:-1,yy:-1}),translate:function(a,b){
+if(arguments.length>1){
+return new m.Matrix2D({dx:a,dy:b});
+}
+return new m.Matrix2D({dx:a.x,dy:a.y});
+},scale:function(a,b){
+if(arguments.length>1){
+return new m.Matrix2D({xx:a,yy:b});
+}
+if(typeof a=="number"){
+return new m.Matrix2D({xx:a,yy:a});
+}
+return new m.Matrix2D({xx:a.x,yy:a.y});
+},rotate:function(_e){
+var c=Math.cos(_e);
+var s=Math.sin(_e);
+return new m.Matrix2D({xx:c,xy:-s,yx:s,yy:c});
+},rotateg:function(_11){
+return m.rotate(m._degToRad(_11));
+},skewX:function(_12){
+return new m.Matrix2D({xy:Math.tan(_12)});
+},skewXg:function(_13){
+return m.skewX(m._degToRad(_13));
+},skewY:function(_14){
+return new m.Matrix2D({yx:Math.tan(_14)});
+},skewYg:function(_15){
+return m.skewY(m._degToRad(_15));
+},reflect:function(a,b){
+if(arguments.length==1){
+b=a.y;
+a=a.x;
+}
+var a2=a*a,b2=b*b,n2=a2+b2,xy=2*a*b/n2;
+return new m.Matrix2D({xx:2*a2/n2-1,xy:xy,yx:xy,yy:2*b2/n2-1});
+},project:function(a,b){
+if(arguments.length==1){
+b=a.y;
+a=a.x;
+}
+var a2=a*a,b2=b*b,n2=a2+b2,xy=a*b/n2;
+return new m.Matrix2D({xx:a2/n2,xy:xy,yx:xy,yy:b2/n2});
+},normalize:function(_22){
+return (_22 instanceof m.Matrix2D)?_22:new m.Matrix2D(_22);
+},clone:function(_23){
+var obj=new m.Matrix2D();
+for(var i in _23){
+if(typeof (_23[i])=="number"&&typeof (obj[i])=="number"&&obj[i]!=_23[i]){
+obj[i]=_23[i];
+}
+}
+return obj;
+},invert:function(_26){
+var M=m.normalize(_26),D=M.xx*M.yy-M.xy*M.yx,M=new m.Matrix2D({xx:M.yy/D,xy:-M.xy/D,yx:-M.yx/D,yy:M.xx/D,dx:(M.xy*M.dy-M.yy*M.dx)/D,dy:(M.yx*M.dx-M.xx*M.dy)/D});
+return M;
+},_multiplyPoint:function(_29,x,y){
+return {x:_29.xx*x+_29.xy*y+_29.dx,y:_29.yx*x+_29.yy*y+_29.dy};
+},multiplyPoint:function(_2c,a,b){
+var M=m.normalize(_2c);
+if(typeof a=="number"&&typeof b=="number"){
+return m._multiplyPoint(M,a,b);
+}
+return m._multiplyPoint(M,a.x,a.y);
+},multiply:function(_30){
+var M=m.normalize(_30);
+for(var i=1;i<arguments.length;++i){
+var l=M,r=m.normalize(arguments[i]);
+M=new m.Matrix2D();
+M.xx=l.xx*r.xx+l.xy*r.yx;
+M.xy=l.xx*r.xy+l.xy*r.yy;
+M.yx=l.yx*r.xx+l.yy*r.yx;
+M.yy=l.yx*r.xy+l.yy*r.yy;
+M.dx=l.xx*r.dx+l.xy*r.dy+l.dx;
+M.dy=l.yx*r.dx+l.yy*r.dy+l.dy;
+}
+return M;
+},_sandwich:function(_35,x,y){
+return m.multiply(m.translate(x,y),_35,m.translate(-x,-y));
+},scaleAt:function(a,b,c,d){
+switch(arguments.length){
+case 4:
+return m._sandwich(m.scale(a,b),c,d);
+case 3:
+if(typeof c=="number"){
+return m._sandwich(m.scale(a),b,c);
+}
+return m._sandwich(m.scale(a,b),c.x,c.y);
+}
+return m._sandwich(m.scale(a),b.x,b.y);
+},rotateAt:function(_3c,a,b){
+if(arguments.length>2){
+return m._sandwich(m.rotate(_3c),a,b);
+}
+return m._sandwich(m.rotate(_3c),a.x,a.y);
+},rotategAt:function(_3f,a,b){
+if(arguments.length>2){
+return m._sandwich(m.rotateg(_3f),a,b);
+}
+return m._sandwich(m.rotateg(_3f),a.x,a.y);
+},skewXAt:function(_42,a,b){
+if(arguments.length>2){
+return m._sandwich(m.skewX(_42),a,b);
+}
+return m._sandwich(m.skewX(_42),a.x,a.y);
+},skewXgAt:function(_45,a,b){
+if(arguments.length>2){
+return m._sandwich(m.skewXg(_45),a,b);
+}
+return m._sandwich(m.skewXg(_45),a.x,a.y);
+},skewYAt:function(_48,a,b){
+if(arguments.length>2){
+return m._sandwich(m.skewY(_48),a,b);
+}
+return m._sandwich(m.skewY(_48),a.x,a.y);
+},skewYgAt:function(_4b,a,b){
+if(arguments.length>2){
+return m._sandwich(m.skewYg(_4b),a,b);
+}
+return m._sandwich(m.skewYg(_4b),a.x,a.y);
+}});
+})();
+dojox.gfx.Matrix2D=dojox.gfx.matrix.Matrix2D;
+}
diff --git a/dojox/gfx/move.js b/dojox/gfx/move.js
new file mode 100644
index 0000000..a67c27e
--- /dev/null
+++ b/dojox/gfx/move.js
@@ -0,0 +1,13 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx.move"]){
+dojo._hasResource["dojox.gfx.move"]=true;
+dojo.provide("dojox.gfx.move");
+dojo.require("dojox.gfx.Mover");
+dojo.require("dojox.gfx.Moveable");
+}
diff --git a/dojox/gfx/path.js b/dojox/gfx/path.js
new file mode 100644
index 0000000..8612651
--- /dev/null
+++ b/dojox/gfx/path.js
@@ -0,0 +1,277 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx.path"]){
+dojo._hasResource["dojox.gfx.path"]=true;
+dojo.provide("dojox.gfx.path");
+dojo.require("dojox.gfx.shape");
+dojo.declare("dojox.gfx.path.Path",dojox.gfx.Shape,{constructor:function(_1){
+this.shape=dojo.clone(dojox.gfx.defaultPath);
+this.segments=[];
+this.absolute=true;
+this.last={};
+this.rawNode=_1;
+},setAbsoluteMode:function(_2){
+this.absolute=typeof _2=="string"?(_2=="absolute"):_2;
+return this;
+},getAbsoluteMode:function(){
+return this.absolute;
+},getBoundingBox:function(){
+return (this.bbox&&("l" in this.bbox))?{x:this.bbox.l,y:this.bbox.t,width:this.bbox.r-this.bbox.l,height:this.bbox.b-this.bbox.t}:null;
+},getLastPosition:function(){
+return "x" in this.last?this.last:null;
+},_updateBBox:function(x,y){
+if(this.bbox&&("l" in this.bbox)){
+if(this.bbox.l>x){
+this.bbox.l=x;
+}
+if(this.bbox.r<x){
+this.bbox.r=x;
+}
+if(this.bbox.t>y){
+this.bbox.t=y;
+}
+if(this.bbox.b<y){
+this.bbox.b=y;
+}
+}else{
+this.bbox={l:x,b:y,r:x,t:y};
+}
+},_updateWithSegment:function(_5){
+var n=_5.args,l=n.length;
+switch(_5.action){
+case "M":
+case "L":
+case "C":
+case "S":
+case "Q":
+case "T":
+for(var i=0;i<l;i+=2){
+this._updateBBox(n[i],n[i+1]);
+}
+this.last.x=n[l-2];
+this.last.y=n[l-1];
+this.absolute=true;
+break;
+case "H":
+for(var i=0;i<l;++i){
+this._updateBBox(n[i],this.last.y);
+}
+this.last.x=n[l-1];
+this.absolute=true;
+break;
+case "V":
+for(var i=0;i<l;++i){
+this._updateBBox(this.last.x,n[i]);
+}
+this.last.y=n[l-1];
+this.absolute=true;
+break;
+case "m":
+var _9=0;
+if(!("x" in this.last)){
+this._updateBBox(this.last.x=n[0],this.last.y=n[1]);
+_9=2;
+}
+for(var i=_9;i<l;i+=2){
+this._updateBBox(this.last.x+=n[i],this.last.y+=n[i+1]);
+}
+this.absolute=false;
+break;
+case "l":
+case "t":
+for(var i=0;i<l;i+=2){
+this._updateBBox(this.last.x+=n[i],this.last.y+=n[i+1]);
+}
+this.absolute=false;
+break;
+case "h":
+for(var i=0;i<l;++i){
+this._updateBBox(this.last.x+=n[i],this.last.y);
+}
+this.absolute=false;
+break;
+case "v":
+for(var i=0;i<l;++i){
+this._updateBBox(this.last.x,this.last.y+=n[i]);
+}
+this.absolute=false;
+break;
+case "c":
+for(var i=0;i<l;i+=6){
+this._updateBBox(this.last.x+n[i],this.last.y+n[i+1]);
+this._updateBBox(this.last.x+n[i+2],this.last.y+n[i+3]);
+this._updateBBox(this.last.x+=n[i+4],this.last.y+=n[i+5]);
+}
+this.absolute=false;
+break;
+case "s":
+case "q":
+for(var i=0;i<l;i+=4){
+this._updateBBox(this.last.x+n[i],this.last.y+n[i+1]);
+this._updateBBox(this.last.x+=n[i+2],this.last.y+=n[i+3]);
+}
+this.absolute=false;
+break;
+case "A":
+for(var i=0;i<l;i+=7){
+this._updateBBox(n[i+5],n[i+6]);
+}
+this.last.x=n[l-2];
+this.last.y=n[l-1];
+this.absolute=true;
+break;
+case "a":
+for(var i=0;i<l;i+=7){
+this._updateBBox(this.last.x+=n[i+5],this.last.y+=n[i+6]);
+}
+this.absolute=false;
+break;
+}
+var _a=[_5.action];
+for(var i=0;i<l;++i){
+_a.push(dojox.gfx.formatNumber(n[i],true));
+}
+if(typeof this.shape.path=="string"){
+this.shape.path+=_a.join("");
+}else{
+Array.prototype.push.apply(this.shape.path,_a);
+}
+},_validSegments:{m:2,l:2,h:1,v:1,c:6,s:4,q:4,t:2,a:7,z:0},_pushSegment:function(_b,_c){
+var _d=this._validSegments[_b.toLowerCase()];
+if(typeof _d=="number"){
+if(_d){
+if(_c.length>=_d){
+var _e={action:_b,args:_c.slice(0,_c.length-_c.length%_d)};
+this.segments.push(_e);
+this._updateWithSegment(_e);
+}
+}else{
+var _e={action:_b,args:[]};
+this.segments.push(_e);
+this._updateWithSegment(_e);
+}
+}
+},_collectArgs:function(_f,_10){
+for(var i=0;i<_10.length;++i){
+var t=_10[i];
+if(typeof t=="boolean"){
+_f.push(t?1:0);
+}else{
+if(typeof t=="number"){
+_f.push(t);
+}else{
+if(t instanceof Array){
+this._collectArgs(_f,t);
+}else{
+if("x" in t&&"y" in t){
+_f.push(t.x,t.y);
+}
+}
+}
+}
+}
+},moveTo:function(){
+var _13=[];
+this._collectArgs(_13,arguments);
+this._pushSegment(this.absolute?"M":"m",_13);
+return this;
+},lineTo:function(){
+var _14=[];
+this._collectArgs(_14,arguments);
+this._pushSegment(this.absolute?"L":"l",_14);
+return this;
+},hLineTo:function(){
+var _15=[];
+this._collectArgs(_15,arguments);
+this._pushSegment(this.absolute?"H":"h",_15);
+return this;
+},vLineTo:function(){
+var _16=[];
+this._collectArgs(_16,arguments);
+this._pushSegment(this.absolute?"V":"v",_16);
+return this;
+},curveTo:function(){
+var _17=[];
+this._collectArgs(_17,arguments);
+this._pushSegment(this.absolute?"C":"c",_17);
+return this;
+},smoothCurveTo:function(){
+var _18=[];
+this._collectArgs(_18,arguments);
+this._pushSegment(this.absolute?"S":"s",_18);
+return this;
+},qCurveTo:function(){
+var _19=[];
+this._collectArgs(_19,arguments);
+this._pushSegment(this.absolute?"Q":"q",_19);
+return this;
+},qSmoothCurveTo:function(){
+var _1a=[];
+this._collectArgs(_1a,arguments);
+this._pushSegment(this.absolute?"T":"t",_1a);
+return this;
+},arcTo:function(){
+var _1b=[];
+this._collectArgs(_1b,arguments);
+this._pushSegment(this.absolute?"A":"a",_1b);
+return this;
+},closePath:function(){
+this._pushSegment("Z",[]);
+return this;
+},_setPath:function(_1c){
+var p=dojo.isArray(_1c)?_1c:_1c.match(dojox.gfx.pathSvgRegExp);
+this.segments=[];
+this.absolute=true;
+this.bbox={};
+this.last={};
+if(!p){
+return;
+}
+var _1e="",_1f=[],l=p.length;
+for(var i=0;i<l;++i){
+var t=p[i],x=parseFloat(t);
+if(isNaN(x)){
+if(_1e){
+this._pushSegment(_1e,_1f);
+}
+_1f=[];
+_1e=t;
+}else{
+_1f.push(x);
+}
+}
+this._pushSegment(_1e,_1f);
+},setShape:function(_24){
+dojox.gfx.Shape.prototype.setShape.call(this,typeof _24=="string"?{path:_24}:_24);
+var _25=this.shape.path;
+this.shape.path=[];
+this._setPath(_25);
+this.shape.path=this.shape.path.join("");
+return this;
+},_2PI:Math.PI*2});
+dojo.declare("dojox.gfx.path.TextPath",dojox.gfx.path.Path,{constructor:function(_26){
+if(!("text" in this)){
+this.text=dojo.clone(dojox.gfx.defaultTextPath);
+}
+if(!("fontStyle" in this)){
+this.fontStyle=dojo.clone(dojox.gfx.defaultFont);
+}
+},getText:function(){
+return this.text;
+},setText:function(_27){
+this.text=dojox.gfx.makeParameters(this.text,typeof _27=="string"?{text:_27}:_27);
+this._setText();
+return this;
+},getFont:function(){
+return this.fontStyle;
+},setFont:function(_28){
+this.fontStyle=typeof _28=="string"?dojox.gfx.splitFontString(_28):dojox.gfx.makeParameters(dojox.gfx.defaultFont,_28);
+this._setFont();
+return this;
+}});
+}
diff --git a/dojox/gfx/resources/Gillius.svg b/dojox/gfx/resources/Gillius.svg
new file mode 100644
index 0000000..a93cdab
--- /dev/null
+++ b/dojox/gfx/resources/Gillius.svg
@@ -0,0 +1,1272 @@
+<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" > 
+<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
+<defs>
+	<font horiz-adv-x="985">
+		<font-face
+			font-family="Gillius ADF No2"
+			units-per-em="2048"
+			panose-1="2 11 5 3 5 0 0 2 0 3"
+			ascent="1536"
+			descent="-512"
+			alphabetic="0" />
+<missing-glyph horiz-adv-x="573" />
+<glyph unicode=" " glyph-name="space" horiz-adv-x="614" />
+<glyph unicode="!" glyph-name="exclam" horiz-adv-x="444" d="M185 176T221 176T284 147T311 80T284 14T221 -16T158 13T131 80T158 146ZM307 797L289 461H156L133 797V1417H307V797Z" />
+<glyph unicode=""" glyph-name="quotedbl" horiz-adv-x="737" d="M264 772H141V1231H264V772ZM596 772H473V1231H596V772Z" />
+<glyph unicode="#" glyph-name="numbersign" horiz-adv-x="1265" d="M815 862H530L451 530H737L815 862ZM1241 862H928L854 530H1137V395H825L731 0H614L705 395H432L328 0H211L303 395H23V530H332L412 862H123V995H432L532 1393H651L555 995H844L938 1393H1053L963
+995H1241V862Z" />
+<glyph unicode="$" glyph-name="dollar" horiz-adv-x="954" d="M774 342Q774 367 769 389T757 427T736 459T710 484T677 504T641 520T599 533T557 544T512 555V125Q644 147 707 193T774 342ZM449 721V1130Q328 1117 266 1072T203 926Q203 884 215 853T248 801T301
+764T368 739T449 721ZM905 360Q905 38 512 2V-287H449V2Q367 2 255 28T66 88V246Q164 174 236 151T449 123V573Q66 641 66 909Q66 991 95 1055T177 1159T298 1222T449 1251V1477H512V1251Q618 1251 686 1233Q758 1216 829 1194V1044Q746 1093 690 1110Q588 1125
+512 1130V705Q583 694 638 679T745 637T831 574T885 484T905 360Z" />
+<glyph unicode="%" glyph-name="percent" horiz-adv-x="1613" d="M532 1061Q532 1116 523 1163T493 1250T435 1314T346 1337Q299 1337 263 1313T205 1248T173 1160T162 1061Q162 991 178 931T238 826T346 778Q398 778 436 802T493 869T522 959T532 1061ZM1450
+354Q1450 404 1441 450T1411 539T1354 606T1268 631Q1085 631 1081 354Q1081 302 1090 256T1119 168T1177 101T1268 76Q1316 76 1352 100T1408 165T1438 253T1450 354ZM635 1061Q635 987 619 921T569 801T478 714T346 682Q269 682 213 713T124 799T77 919T59 1061Q59
+1132 76 1198T126 1319T216 1408T346 1442Q404 1442 453 1420T535 1361T591 1274T624 1171T635 1061ZM1278 1442L453 -29H336L1161 1442H1278ZM1554 354Q1554 283 1538 218T1489 96T1399 5T1268 -29T1136 4T1044 93T993 215T975 354Q975 425 993 491T1046 611T1138
+698T1268 733Q1340 733 1396 699T1486 609T1537 488T1554 354Z" />
+<glyph unicode="&" glyph-name="ampersand" horiz-adv-x="1306" d="M877 240L379 772Q290 696 246 621T201 444Q201 290 301 200T555 109Q649 109 723 140T877 240ZM1288 -4H1085L954 141Q753 -29 539 -29Q333 -29 201 98T68 432Q68 662 307 868Q269 919 240
+991Q219 1054 219 1118Q219 1260 311 1348Q406 1442 561 1442Q632 1442 712 1423T850 1374V1212Q713 1311 580 1311Q477 1311 416 1253Q348 1199 348 1118Q348 1063 379 1004Q413 946 492 864L963 362Q1031 458 1056 541T1087 752H1229Q1207 526 1040 266L1288
+-4Z" />
+<glyph unicode="'" glyph-name="quotesingle" horiz-adv-x="409" d="M276 1417Q274 1330 274 1259T268 1107T244 958H166L135 1169V1417H276Z" />
+<glyph unicode="(" glyph-name="parenleft" horiz-adv-x="507" d="M477 -256H358Q82 197 82 610Q82 1013 358 1475H477Q347 1239 289 1047T227 610Q227 371 287 174T477 -256Z" />
+<glyph unicode=")" glyph-name="parenright" horiz-adv-x="509" d="M426 610Q426 402 349 171T150 -256H31Q161 -26 221 173T281 610Q281 847 220 1047T29 1475H150Q274 1271 350 1046T426 610Z" />
+<glyph unicode="*" glyph-name="asterisk" horiz-adv-x="913" d="M848 811L811 727L498 918V555H416V918L104 727L66 811L387 1001L66 1188L104 1276L416 1077V1442H498V1077L811 1276L848 1188L520 999L848 811Z" />
+<glyph unicode="+" glyph-name="plus" horiz-adv-x="1107" d="M1083 467H614V0H496V467H23V594H496V1059H614V594H1083V467Z" />
+<glyph unicode="," glyph-name="comma" horiz-adv-x="454" d="M338 209V66Q336 -11 245 -102T74 -197Q116 -169 142 -118T168 -10Q168 33 154 68V209H338Z" />
+<glyph unicode="-" glyph-name="hyphen" horiz-adv-x="749" d="M608 395H141V530H608V395Z" />
+<glyph unicode="." glyph-name="period" horiz-adv-x="477" d="M336 0H141V209H336V0Z" />
+<glyph unicode="/" glyph-name="slash" horiz-adv-x="643" d="M623 1417L150 -180H23L494 1417H623Z" />
+<glyph unicode="0" glyph-name="zero" horiz-adv-x="1126" d="M866 705Q866 1309 561 1309Q501 1309 453 1285T373 1224T320 1131T286 1025T269 908T261 800T260 705T261 610T268 503T286 388T320 282T374 190T453 130T561 106Q866 106 866 705ZM1012 705Q1012
+636 1007 570T989 429T954 290T898 166T817 64T706 -3T561 -29T417 -4T307 64T226 166T170 290T136 429T118 569T113 705Q113 774 117 839T135 979T168 1119T224 1244T304 1347T416 1416T561 1442T705 1417T816 1349T897 1246T954 1121T988 982T1007 841T1012 705Z"
+/>
+<glyph unicode="1" glyph-name="one" horiz-adv-x="585" d="M426 0H268V1264L55 1092V1251L256 1417H426V0Z" />
+<glyph unicode="2" glyph-name="two" d="M899 0H74V147Q110 185 335 433T578 702Q642 772 691 863T741 1030Q741 1153 660 1225T455 1298Q356 1298 268 1265T82 1169V1352Q155 1381 202 1397T317 1428T451 1442Q642 1442 764 1337T887 1040Q887 987 878 942T846
+851T804 776T748 692L262 147H899V0Z" />
+<glyph unicode="3" glyph-name="three" horiz-adv-x="1015" d="M911 410Q911 319 885 246T814 122T704 37T564 -13T401 -29Q250 -29 57 39V213Q134 159 210 138T397 117Q481 117 544 130T660 176T739 267T766 410Q766 481 741 535T669 622T564 670T434 686H289V825H440Q570
+825 651 882T735 1057Q735 1183 653 1240T434 1298Q371 1298 309 1287T208 1264T98 1227V1382Q285 1442 451 1442Q568 1442 663 1405T819 1284T881 1081Q881 971 817 889T635 764Q767 727 839 631T911 410Z" />
+<glyph unicode="4" glyph-name="four" horiz-adv-x="1040" d="M651 483V1264L166 483H651ZM997 338H805V0H651V338H51V516L600 1417H805V483H997V338Z" />
+<glyph unicode="5" glyph-name="five" horiz-adv-x="997" d="M911 451Q911 220 778 96T412 -29Q241 -29 70 31V209Q148 160 226 139T408 117Q571 117 667 202T764 451Q764 610 667 696T408 782Q304 782 260 771T127 715L213 1417H815V1268H315L264 895Q331 922
+440 928Q655 928 781 799T911 451Z" />
+<glyph unicode="6" glyph-name="six" horiz-adv-x="1075" d="M260 424Q260 276 341 191T565 106Q707 106 778 191T850 424Q850 574 777 671T565 768Q422 768 343 672T260 424ZM98 535Q98 685 136 833T236 1097T382 1298T555 1417H737Q654 1365 576 1293T433 1135T328
+954T287 768Q379 892 575 901Q712 901 809 838T951 668T997 424Q997 225 874 100T565 -29Q461 -29 380 1T247 83T160 208T112 362T98 535Z" />
+<glyph unicode="7" glyph-name="seven" horiz-adv-x="915" d="M866 1346L381 0H219L678 1266H33V1417H866V1346Z" />
+<glyph unicode="8" glyph-name="eight" horiz-adv-x="1097" d="M846 395Q846 531 766 606T547 682Q407 682 328 609T248 395Q248 253 327 180T547 106Q684 106 765 181T846 395ZM815 1061Q809 1193 736 1251T547 1309Q422 1309 353 1251T274 1061Q278 961 356
+889T543 817H547Q659 817 737 885T815 1061ZM989 395Q989 186 873 79T547 -29Q336 -29 218 78T100 395Q100 524 173 617T383 754Q252 801 192 869T131 1061Q131 1180 188 1268T339 1399T547 1442Q723 1442 841 1341T963 1061Q963 858 733 754Q982 665 989 395Z"
+/>
+<glyph unicode="9" glyph-name="nine" horiz-adv-x="1077" d="M813 965Q813 1113 732 1197T508 1282Q366 1282 295 1197T223 965Q223 893 240 832T292 723T381 648T508 621Q652 621 731 716T813 965ZM975 854Q975 703 937 556T837 292T691 90T518 -29H336Q505
+76 640 258T782 590Q723 534 663 514T498 487Q394 487 313 523T181 624T103 775T76 965Q76 1164 199 1289T508 1417Q612 1417 693 1387T826 1305T913 1180T961 1027T975 854Z" />
+<glyph unicode=":" glyph-name="colon" horiz-adv-x="477" d="M336 0H141V215H336V0ZM336 657H141V872H336V657Z" />
+<glyph unicode=";" glyph-name="semicolon" horiz-adv-x="460" d="M334 209V66Q332 -11 241 -102T70 -197Q112 -169 138 -118T164 -10Q164 33 150 68V209H334ZM336 657H147V872H336V657Z" />
+<glyph unicode="<" glyph-name="less" horiz-adv-x="1177" d="M1100 78L39 465V592L1100 981V842L217 528L1100 217V78Z" />
+<glyph unicode="=" glyph-name="equal" horiz-adv-x="1345" d="M1204 291H141V420H1204V291ZM1204 639H141V766H1204V639Z" />
+<glyph unicode=">" glyph-name="greater" horiz-adv-x="1179" d="M1141 465L78 78V217L961 528L78 842V981L1141 592V465Z" />
+<glyph unicode="?" glyph-name="question" horiz-adv-x="784" d="M302 176T338 176T401 147T428 80T401 14T338 -16T275 13T248 80T275 146ZM727 1112Q727 1067 718 1030T686 958T645 900T588 838L506 754Q471 714 460 700T433 663T414 619T409 571T406 496V375H264V524Q264
+622 293 683T395 823L475 907Q511 941 544 994T582 1102Q582 1200 514 1251T344 1303Q255 1303 185 1271T37 1171V1339Q126 1393 202 1417T377 1442Q535 1442 629 1356T727 1112Z" />
+<glyph unicode="@" glyph-name="at" horiz-adv-x="1689" d="M1098 508Q1098 640 1032 721Q959 797 852 797Q734 797 674 716T610 508Q610 384 674 302T854 219Q972 219 1033 300T1098 508ZM1628 625Q1628 375 1488 230T1100 82V209Q1056 154 980 120T819 86Q752
+86 696 110T601 174T535 269T494 383T481 508Q481 590 501 664T562 800T668 898T819 936Q1038 936 1100 811V920H1229V221Q1304 233 1360 269T1448 359T1497 478T1516 621Q1516 741 1470 857T1342 1065T1140 1213T881 1270H866Q714 1270 583 1209T364 1044T226
+803T176 514Q176 352 232 216T383 -11T603 -151T866 -201Q1095 -201 1294 -39L1370 -150Q1241 -245 1127 -290T866 -338Q703 -338 557 -277T304 -106T133 165T70 514Q70 645 101 768T199 1000T359 1190T587 1318T879 1366Q1049 1366 1192 1305T1429 1140T1576 904T1628
+625Z" />
+<glyph unicode="A" glyph-name="A" horiz-adv-x="1222" d="M872 516L614 1245L350 516H872ZM1206 0H1042L924 371H299L178 0H16L518 1417H702L1206 0Z" />
+<glyph unicode="B" glyph-name="B" horiz-adv-x="1146" d="M909 416Q909 563 832 623T602 684H297V141H602Q753 141 831 205T909 416ZM866 1051Q866 1269 580 1276H297V821H580Q707 821 785 878T866 1051ZM1063 395Q1063 292 1031 215T938 92T797 23T614 0H141V1417H594Q993
+1417 1008 1071Q1008 960 962 879T823 774V754Q936 720 999 622T1063 395Z" />
+<glyph unicode="C" glyph-name="C" horiz-adv-x="1196" d="M1130 104Q1050 42 939 7T719 -29Q562 -29 440 27T241 184T125 417T86 705Q86 829 110 938T184 1141T308 1300T487 1404T719 1442Q946 1442 1130 1311V1118Q1047 1214 953 1258T729 1303Q598 1303 502
+1257T350 1127T267 939T238 705Q238 602 255 515T309 352T403 224T542 141T729 111Q858 111 951 153T1130 291V104Z" />
+<glyph unicode="D" glyph-name="D" horiz-adv-x="1320" d="M1081 711Q1081 1005 949 1139T528 1276H295V141H528Q812 141 946 281T1081 711ZM1231 1085T1231 711T1053 169T500 0H141V1417H500Q875 1417 1053 1251Z" />
+<glyph unicode="E" glyph-name="E" horiz-adv-x="1030" d="M979 0H141V1417H963V1268H295V827H932V682H295V147H979V0Z" />
+<glyph unicode="F" glyph-name="F" horiz-adv-x="921" d="M889 1268H297V831H831V684H297V0H141V1417H889V1268Z" />
+<glyph unicode="G" glyph-name="G" horiz-adv-x="1316" d="M1221 127Q1014 -29 735 -29Q573 -29 448 25T245 178T126 410T86 705T125 1000T243 1232T446 1387T735 1442Q855 1442 973 1408T1186 1311V1120Q1083 1219 987 1261T750 1303Q613 1303 514 1260T356 1134T269
+947T238 705Q238 570 267 464T356 277T516 154T750 111Q919 111 1071 182V590H770V731H1221V127Z" />
+<glyph unicode="H" glyph-name="H" horiz-adv-x="1271" d="M1130 0H975V682H295V0H141V1417H295V827H975V1417H1130V0Z" />
+<glyph unicode="I" glyph-name="I" horiz-adv-x="436" d="M295 0H141V1417H295V0Z" />
+<glyph unicode="J" glyph-name="J" horiz-adv-x="428" d="M287 94Q287 -152 193 -276Q105 -387 -98 -387H-156V-244H-113Q30 -244 84 -172Q135 -96 135 94V1417H287V94Z" />
+<glyph unicode="K" glyph-name="K" horiz-adv-x="1171" d="M1174 0H961L297 692V0H141V1417H297V809L913 1417H1128L463 760L1174 0Z" />
+<glyph unicode="L" glyph-name="L" horiz-adv-x="962" d="M952 0H141V1417H297V147H952V0Z" />
+<glyph unicode="M" glyph-name="M" horiz-adv-x="1470" d="M1329 0H1176V1135L739 276L295 1135V0H141V1417H295L739 578L1176 1417H1329V0Z" />
+<glyph unicode="N" glyph-name="N" horiz-adv-x="1265" d="M1124 0H971L293 1141V0H141V1417H287L971 274V1417H1124V0Z" />
+<glyph unicode="O" glyph-name="O" horiz-adv-x="1374" d="M1133 705Q1133 797 1119 880T1070 1042T985 1177T856 1269T682 1303Q587 1303 510 1269T383 1177T299 1041T251 879T236 705Q236 617 251 534T300 373T384 237T511 144T682 109Q777 109 854 143T982
+235T1068 370T1118 531T1133 705ZM1284 824T1284 705T1262 479T1193 279T1076 117T906 10T682 -29Q532 -29 415 31T227 196T120 429T84 705Q84 820 106 926T175 1126T291 1291T460 1401T682 1442Q805 1442 906 1403T1076 1295T1193 1132T1262 931Z" />
+<glyph unicode="P" glyph-name="P" horiz-adv-x="1040" d="M825 995Q825 1133 751 1203T541 1276H295V719H541Q677 719 749 790T825 995ZM979 995Q979 783 866 679T541 575H295V0H141V1417H541Q753 1417 866 1312T979 995Z" />
+<glyph unicode="Q" glyph-name="Q" horiz-adv-x="1372" d="M1133 707Q1133 798 1119 881T1070 1043T985 1178T856 1269T682 1303Q587 1303 510 1269T383 1177T299 1041T251 880T236 707Q236 620 251 538T301 378T386 242T513 148T682 113T852 147T980 239T1066
+374T1117 534T1133 707ZM1284 707Q1284 192 928 20Q928 -17 985 -68T1075 -119Q1083 -121 1100 -121Q1144 -121 1197 -97T1282 -37Q1285 -105 1214 -175T1055 -246Q961 -246 873 -175T766 -20Q730 -20 713 -21T682 -23Q561 -23 461 16T292 124T176 285T106 484T84
+707Q84 822 106 927T175 1127T291 1291T460 1401T682 1442Q805 1442 906 1403T1076 1295T1193 1132T1262 932T1284 707Z" />
+<glyph unicode="R" glyph-name="R" horiz-adv-x="1112" d="M821 1016Q821 1269 539 1276H295V748H539Q672 748 746 816T821 1016ZM1092 0H930Q886 40 859 99T808 243T770 365Q656 606 520 606H506H295V0H141V1417H539Q973 1417 973 1016Q973 947 963 899T926 805T845
+727T709 672Q731 659 751 641T787 604T818 562T846 517T871 471T893 425T913 381T952 276T1015 120T1092 0Z" />
+<glyph unicode="S" glyph-name="S" horiz-adv-x="1067" d="M999 385Q999 295 974 224T904 106T796 28T659 -16T500 -29Q433 -29 354 -15T222 15T84 59V246Q293 109 500 109Q566 109 625 123T735 167T816 249T846 371Q846 436 827 481T766 557T682 604T569 639L461
+659Q387 676 333 695T230 744T151 814T104 910T86 1040Q86 1142 120 1220T215 1346T359 1418T541 1442Q631 1442 738 1422T922 1368V1200Q841 1241 801 1258T698 1289T559 1303Q490 1303 435 1291T333 1250T260 1173T231 1055Q231 1007 245 971T282 912T342 871T415
+844T502 823L616 803Q801 760 900 663T999 385Z" />
+<glyph unicode="T" glyph-name="T" horiz-adv-x="1142" d="M1122 1268H649V0H496V1268H20V1417H1122V1268Z" />
+<glyph unicode="U" glyph-name="U" horiz-adv-x="1253" d="M1124 528Q1124 265 1005 118T631 -29Q376 -29 253 117T129 528V1417H283V553Q283 468 291 404T323 282T385 188T485 130T631 109Q733 109 802 140T907 234T958 372T973 553V1417H1124V528Z" />
+<glyph unicode="V" glyph-name="V" horiz-adv-x="1226" d="M1206 1417L616 -29L20 1417H178L616 369L1044 1417H1206Z" />
+<glyph unicode="W" glyph-name="W" horiz-adv-x="1726" d="M1686 1417L1255 -29L860 1044L477 -29L43 1417H197L498 451L860 1450L1235 451L1532 1417H1686Z" />
+<glyph unicode="X" glyph-name="X" horiz-adv-x="1140" d="M1120 0H952L571 614L178 0H10L492 760L72 1417H240L582 881L926 1417H1094L666 737L1120 0Z" />
+<glyph unicode="Y" glyph-name="Y" horiz-adv-x="1091" d="M1094 1417L623 676V0H469V676L0 1417H168L547 821L926 1417H1094Z" />
+<glyph unicode="Z" glyph-name="Z" horiz-adv-x="1155" d="M1112 0H51V137L895 1266H70V1417H1090L1087 1282L244 147H1112V0Z" />
+<glyph unicode="[" glyph-name="bracketleft" horiz-adv-x="542" d="M508 -256H141V1477H508V1354H287V-137H508V-256Z" />
+<glyph unicode="\" glyph-name="backslash" horiz-adv-x="647" d="M623 -180H494L23 1417H150L623 -180Z" />
+<glyph unicode="]" glyph-name="bracketright" horiz-adv-x="542" d="M401 -256H35V-137H256V1354H35V1477H401V-256Z" />
+<glyph unicode="^" glyph-name="asciicircum" horiz-adv-x="1234" d="M1198 887L1016 889L616 1260L217 889L37 887L530 1417H702L1198 887Z" />
+<glyph unicode="_" glyph-name="underscore" horiz-adv-x="921" d="M926 -459H-20V-322H926V-459Z" />
+<glyph unicode="`" glyph-name="grave" horiz-adv-x="573" d="M510 1040H375L72 1352H250L510 1040Z" />
+<glyph unicode="a" glyph-name="a" horiz-adv-x="1024" d="M709 365V381Q693 416 636 443T516 471Q478 471 444 468T368 452T297 420T247 364T225 281Q225 193 282 149T430 104Q557 106 633 168T709 365ZM967 139Q964 75 924 29T819 -25Q769 -21 739 17T709 121Q655
+52 570 14T387 -25Q246 -25 168 52T86 270Q86 357 119 420T210 517T339 568T496 584Q544 584 604 567T709 522V582Q706 711 639 765T446 819Q352 819 283 791T150 700V852Q208 894 296 920T461 946Q850 946 850 584V176Q847 116 897 104H903Q936 104 967 139Z"
+/>
+<glyph unicode="b" glyph-name="b" horiz-adv-x="1062" d="M295 778V141Q376 106 479 106Q644 110 727 201T811 461Q811 626 726 720T479 815Q368 810 295 778ZM141 1417H295V920Q391 946 487 946Q711 946 838 815T965 461Q962 240 840 108T498 -25Q302 -25 141 51V1417Z" />
+<glyph unicode="c" glyph-name="c" horiz-adv-x="925" d="M852 33Q692 -25 561 -25Q342 -25 220 107T94 461Q94 684 220 815T571 946Q693 946 852 891V737Q763 780 715 795T580 815Q418 815 333 721T248 461Q248 293 331 202T580 106Q618 106 648 109T702 118T750
+134T798 156T852 184V33Z" />
+<glyph unicode="d" glyph-name="d" horiz-adv-x="1056" d="M764 778Q691 810 580 815Q418 815 333 721T248 461Q248 293 331 202T580 106Q683 106 764 141V778ZM918 1417V51Q757 -25 561 -25Q342 -25 220 107T94 461Q94 684 220 815T571 946Q668 946 764 920V1417H918Z" />
+<glyph unicode="e" glyph-name="e" horiz-adv-x="1015" d="M784 588Q784 685 711 750T520 815Q409 815 341 751T258 588H784ZM934 463H252V446Q252 284 332 199T557 113Q682 113 733 127T901 199V45Q722 -25 547 -25Q338 -25 216 107T94 453Q94 550 122 638T203
+795T338 905T520 946Q632 944 713 909T841 809T911 663T934 477V463Z" />
+<glyph unicode="f" glyph-name="f" horiz-adv-x="657" d="M610 1286H459Q420 1286 389 1237T358 1067V924H621V801H358V0H205V801H55V924H205V1051Q213 1414 461 1417H610V1286Z" />
+<glyph unicode="g" glyph-name="g" horiz-adv-x="927" d="M461 811Q378 811 320 752T262 610T320 469T461 410Q543 410 601 468T659 610T601 752T461 811ZM436 154Q548 154 652 118T828 6T901 -172Q901 -298 764 -395T436 -492Q250 -492 131 -396T12 -170Q12 -89
+62 -19T201 96Q90 158 90 244Q90 303 135 340T229 379Q141 467 141 606Q145 744 242 842T471 942Q534 942 602 922H862V807H713Q780 714 780 606Q780 467 687 369T461 270Q429 270 377 279T303 307Q231 307 231 246Q231 215 274 184T385 152Q403 154 436 154ZM434
+23Q307 23 236 -31T164 -172T235 -312T434 -365Q564 -365 645 -311T727 -172T646 -32T434 23Z" />
+<glyph unicode="h" glyph-name="h" horiz-adv-x="1067" d="M938 0H788V553Q788 682 739 746T571 813Q452 811 374 732T293 522V0H141V1417H293V797Q385 946 608 946Q720 946 796 894T905 757T938 561V0Z" />
+<glyph unicode="i" glyph-name="i" horiz-adv-x="436" d="M183 1417T219 1417T282 1388T309 1321T282 1255T219 1225T156 1254T129 1321T156 1387ZM295 0H141V924H295V0Z" />
+<glyph unicode="j" glyph-name="j" horiz-adv-x="440" d="M183 1417T219 1417T282 1388T309 1321T282 1255T219 1225T156 1254T129 1321T156 1387ZM299 -172Q299 -347 223 -426Q182 -472 121 -492L57 -377Q84 -367 113 -336Q141 -297 141 -172V924H299V-172Z" />
+<glyph unicode="k" glyph-name="k" horiz-adv-x="1024" d="M1001 0H788L297 440V0H141V1417H297V541L772 924H981L461 496L1001 0Z" />
+<glyph unicode="l" glyph-name="l" horiz-adv-x="409" d="M270 1417V0H119V1417H270Z" />
+<glyph unicode="m" glyph-name="m" horiz-adv-x="1646" d="M1516 0H1372V553Q1372 678 1327 744T1171 811Q1040 811 972 734T901 522V0H756V553Q756 682 712 746T555 811H547Q437 811 367 730T293 522V0H141V926H293V801Q345 865 428 905T600 946Q697 946 771
+895T883 760Q939 846 1025 896T1214 946Q1296 946 1356 914T1450 826T1500 703T1516 557V0Z" />
+<glyph unicode="n" glyph-name="n" horiz-adv-x="1067" d="M938 0H788V553Q788 682 738 746T571 811Q448 811 372 733T293 522V0H141V926H293V799Q346 873 429 909T608 946Q776 946 857 840T938 557V0Z" />
+<glyph unicode="o" glyph-name="o" horiz-adv-x="1062" d="M813 461Q812 552 780 629T681 757T528 809Q436 808 372 760T278 637T248 467Q248 421 255 377T281 284T330 200T411 140T528 115Q653 115 732 217T813 461ZM965 461Q964 329 914 221T764 45T528 -25Q333
+-21 214 121T92 461Q94 672 210 809T528 946Q618 946 692 918T816 843T900 733T949 602T965 461Z" />
+<glyph unicode="p" glyph-name="p" horiz-adv-x="1056" d="M289 145Q363 114 473 109Q634 109 719 203T805 463Q805 631 722 722T473 817Q367 817 289 782V145ZM135 -494V872Q293 948 492 948Q710 948 832 816T958 463Q958 240 832 109T481 -23Q389 -23 289 4V-494H135Z" />
+<glyph unicode="q" glyph-name="q" horiz-adv-x="1054" d="M762 145V782Q684 817 578 817Q412 814 329 723T246 463Q246 298 331 204T578 109Q688 114 762 145ZM915 -494H762V4Q661 -23 569 -23Q345 -23 219 108T92 463Q95 684 217 816T559 948Q758 948 915 872V-494Z" />
+<glyph unicode="r" glyph-name="r" horiz-adv-x="757" d="M664 700L659 702Q633 735 568 771T467 807H463Q411 803 375 773T323 700T301 624T295 563V0H141V926H295V801Q327 864 383 899T512 938Q565 938 626 911T729 840L664 700Z" />
+<glyph unicode="s" glyph-name="s" horiz-adv-x="903" d="M817 256Q817 194 794 145T732 64T642 13T537 -16T426 -25Q297 -25 88 31V199Q164 162 182 154T246 130T329 111T430 104Q473 104 510 110T585 130T645 174T670 244Q670 286 649 314T593 357T515 382T430
+401L373 414Q244 439 175 497T102 674Q102 749 132 803T216 888T331 932T465 946Q644 946 772 897V743Q710 772 674 787T602 808T485 817Q442 817 404 812T328 792T266 750T240 680Q240 656 250 637T278 605T317 582T364 565T414 553T461 543L512 528Q582 515 631
+498T726 450T794 371T817 256Z" />
+<glyph unicode="t" glyph-name="t" horiz-adv-x="706" d="M659 10Q580 -25 498 -29Q327 -29 252 50T176 303V803H68V924H176L262 1188H328V924H600V803H328V303Q328 192 361 147T498 102Q574 102 659 141V10Z" />
+<glyph unicode="u" glyph-name="u" horiz-adv-x="1073" d="M932 0H774V121Q721 58 637 17T465 -25Q299 -25 215 83T131 365V924H281V369Q281 243 331 177T500 111Q636 111 705 188T774 401V924H932V0Z" />
+<glyph unicode="v" glyph-name="v" d="M944 924L494 -29L43 924H184L494 276L803 924H944Z" />
+<glyph unicode="w" glyph-name="w" horiz-adv-x="1363" d="M1305 924L975 -29L684 659L385 -29L61 924H193L410 297L684 946L958 297L1174 924H1305Z" />
+<glyph unicode="x" glyph-name="x" horiz-adv-x="968" d="M930 0H770L481 373L193 0H33L410 485L63 924H229L492 586L750 924H913L563 477L930 0Z" />
+<glyph unicode="y" glyph-name="y" horiz-adv-x="970" d="M936 924L381 -354Q344 -414 288 -452T174 -494L123 -389Q157 -389 207 -355T276 -276L434 96L31 924H176L510 248L795 924H936Z" />
+<glyph unicode="z" glyph-name="z" horiz-adv-x="921" d="M840 0H74V154L662 788H94V924H840V770L254 135H840V0Z" />
+<glyph unicode="{" glyph-name="braceleft" horiz-adv-x="731" d="M702 -317H659Q447 -317 367 -246Q301 -180 301 27V256Q301 402 246 463Q195 520 55 520H12V641H55Q192 641 246 700Q301 758 301 901V1133Q301 1342 369 1407Q445 1474 659 1477H702V1358H653Q510
+1358 473 1313Q433 1270 430 1128V891Q430 736 391 684Q356 619 250 580Q360 544 391 483Q430 422 430 270V31Q430 -106 473 -152Q511 -194 653 -197H702V-317Z" />
+<glyph unicode="|" glyph-name="bar" horiz-adv-x="430" d="M289 -459H141V1483H289V-459Z" />
+<glyph unicode="}" glyph-name="braceright" horiz-adv-x="727" d="M715 520H674Q532 520 481 463Q428 404 428 256V27Q428 -176 358 -246Q284 -317 72 -317H29V-197H78Q216 -197 254 -154Q299 -109 299 31V270Q299 422 336 481Q370 545 483 580Q418 601 385 625T336
+684Q299 734 299 891V1128Q299 1272 254 1311Q217 1355 78 1358H29V1477H72Q282 1477 358 1407Q428 1344 428 1133V901Q428 757 481 698Q540 641 674 641H715V520Z" />
+<glyph unicode="~" glyph-name="asciitilde" horiz-adv-x="1277" d="M1167 537Q1096 477 1008 438Q926 413 858 410Q760 410 645 463L632 470Q619 476 596 485T544 503T477 519T403 526H397Q311 526 246 494Q190 471 106 385V526Q168 578 264 623Q340 651 418
+651Q454 651 535 631T657 590Q795 535 877 535Q937 535 1028 567Q1125 636 1167 674V537Z" />
+<hkern g1="parenleft" g2="J" k="-135" />
+<hkern g1="hyphen" g2="T" k="143" />
+<hkern g1="hyphen" g2="V" k="106" />
+<hkern g1="hyphen" g2="W" k="74" />
+<hkern g1="hyphen" g2="X" k="55" />
+<hkern g1="hyphen" g2="Y" k="131" />
+<hkern g1="A" g2="comma" k="-33" />
+<hkern g1="A" g2="period" k="-39" />
+<hkern g1="A" g2="A" k="-41" />
+<hkern g1="A" g2="C" k="41" />
+<hkern g1="A" g2="G" k="41" />
+<hkern g1="A" g2="O" k="39" />
+<hkern g1="A" g2="Q" k="39" />
+<hkern g1="A" g2="T" k="211" />
+<hkern g1="A" g2="U" k="39" />
+<hkern g1="A" g2="V" k="178" />
+<hkern g1="A" g2="W" k="141" />
+<hkern g1="A" g2="Y" k="190" />
+<hkern g1="A" g2="d" k="35" />
+<hkern g1="A" g2="f" k="51" />
+<hkern g1="A" g2="g" k="-25" />
+<hkern g1="A" g2="t" k="39" />
+<hkern g1="A" g2="v" k="88" />
+<hkern g1="A" g2="w" k="70" />
+<hkern g1="A" g2="y" k="82" />
+<hkern g1="A" g2="guillemotleft" k="33" />
+<hkern g1="A" g2="Adieresis" k="-41" />
+<hkern g1="A" g2="Ccedilla" k="41" />
+<hkern g1="A" g2="Ograve" k="39" />
+<hkern g1="A" g2="Oacute" k="39" />
+<hkern g1="A" g2="Ocircumflex" k="39" />
+<hkern g1="A" g2="Otilde" k="39" />
+<hkern g1="A" g2="Odieresis" k="39" />
+<hkern g1="A" g2="Ugrave" k="39" />
+<hkern g1="A" g2="Uacute" k="39" />
+<hkern g1="A" g2="Ucircumflex" k="39" />
+<hkern g1="A" g2="Udieresis" k="39" />
+<hkern g1="A" g2="Yacute" k="190" />
+<hkern g1="A" g2="ograve" k="29" />
+<hkern g1="A" g2="oacute" k="29" />
+<hkern g1="A" g2="ocircumflex" k="29" />
+<hkern g1="A" g2="otilde" k="25" />
+<hkern g1="A" g2="odieresis" k="20" />
+<hkern g1="A" g2="udieresis" k="20" />
+<hkern g1="A" g2="Ydieresis" k="190" />
+<hkern g1="A" g2="quoteright" k="104" />
+<hkern g1="A" g2="quotedblright" k="104" />
+<hkern g1="A" g2="guilsinglleft" k="33" />
+<hkern g1="B" g2="hyphen" k="-23" />
+<hkern g1="B" g2="V" k="51" />
+<hkern g1="B" g2="W" k="41" />
+<hkern g1="B" g2="Y" k="70" />
+<hkern g1="B" g2="y" k="29" />
+<hkern g1="C" g2="hyphen" k="307" />
+<hkern g1="C" g2="O" k="61" />
+<hkern g1="C" g2="v" k="184" />
+<hkern g1="C" g2="w" k="139" />
+<hkern g1="C" g2="y" k="182" />
+<hkern g1="C" g2="Oacute" k="61" />
+<hkern g1="C" g2="Odieresis" k="61" />
+<hkern g1="D" g2="A" k="47" />
+<hkern g1="D" g2="T" k="125" />
+<hkern g1="D" g2="V" k="63" />
+<hkern g1="D" g2="W" k="45" />
+<hkern g1="D" g2="X" k="86" />
+<hkern g1="D" g2="Y" k="98" />
+<hkern g1="D" g2="Agrave" k="47" />
+<hkern g1="D" g2="Aacute" k="47" />
+<hkern g1="D" g2="Acircumflex" k="47" />
+<hkern g1="D" g2="Atilde" k="47" />
+<hkern g1="D" g2="Adieresis" k="47" />
+<hkern g1="D" g2="Aring" k="47" />
+<hkern g1="E" g2="G" k="35" />
+<hkern g1="E" g2="c" k="55" />
+<hkern g1="E" g2="d" k="74" />
+<hkern g1="E" g2="v" k="39" />
+<hkern g1="E" g2="w" k="39" />
+<hkern g1="E" g2="y" k="31" />
+<hkern g1="F" g2="comma" k="199" />
+<hkern g1="F" g2="hyphen" k="195" />
+<hkern g1="F" g2="period" k="195" />
+<hkern g1="F" g2="A" k="152" />
+<hkern g1="F" g2="O" k="29" />
+<hkern g1="F" g2="a" k="76" />
+<hkern g1="F" g2="e" k="76" />
+<hkern g1="F" g2="o" k="72" />
+<hkern g1="F" g2="r" k="59" />
+<hkern g1="F" g2="u" k="51" />
+<hkern g1="F" g2="y" k="29" />
+<hkern g1="F" g2="Agrave" k="152" />
+<hkern g1="F" g2="Aacute" k="152" />
+<hkern g1="F" g2="Acircumflex" k="152" />
+<hkern g1="F" g2="Atilde" k="152" />
+<hkern g1="F" g2="Adieresis" k="152" />
+<hkern g1="F" g2="Aring" k="152" />
+<hkern g1="F" g2="Odieresis" k="29" />
+<hkern g1="F" g2="Oslash" k="39" />
+<hkern g1="F" g2="agrave" k="82" />
+<hkern g1="F" g2="aacute" k="86" />
+<hkern g1="F" g2="acircumflex" k="84" />
+<hkern g1="F" g2="atilde" k="74" />
+<hkern g1="F" g2="adieresis" k="74" />
+<hkern g1="F" g2="aring" k="74" />
+<hkern g1="F" g2="ae" k="76" />
+<hkern g1="F" g2="egrave" k="84" />
+<hkern g1="F" g2="eacute" k="86" />
+<hkern g1="F" g2="ecircumflex" k="86" />
+<hkern g1="F" g2="edieresis" k="78" />
+<hkern g1="F" g2="ograve" k="82" />
+<hkern g1="F" g2="oacute" k="84" />
+<hkern g1="F" g2="ocircumflex" k="82" />
+<hkern g1="F" g2="otilde" k="76" />
+<hkern g1="F" g2="odieresis" k="74" />
+<hkern g1="F" g2="oslash" k="80" />
+<hkern g1="F" g2="ugrave" k="63" />
+<hkern g1="F" g2="uacute" k="66" />
+<hkern g1="F" g2="ucircumflex" k="63" />
+<hkern g1="F" g2="udieresis" k="57" />
+<hkern g1="F" g2="oe" k="70" />
+<hkern g1="G" g2="T" k="31" />
+<hkern g1="G" g2="V" k="41" />
+<hkern g1="G" g2="W" k="41" />
+<hkern g1="G" g2="Y" k="43" />
+<hkern g1="K" g2="hyphen" k="98" />
+<hkern g1="K" g2="A" k="-49" />
+<hkern g1="K" g2="C" k="117" />
+<hkern g1="K" g2="G" k="117" />
+<hkern g1="K" g2="O" k="113" />
+<hkern g1="K" g2="Q" k="115" />
+<hkern g1="K" g2="U" k="43" />
+<hkern g1="K" g2="Y" k="-20" />
+<hkern g1="K" g2="a" k="29" />
+<hkern g1="K" g2="e" k="78" />
+<hkern g1="K" g2="o" k="82" />
+<hkern g1="K" g2="u" k="70" />
+<hkern g1="K" g2="v" k="201" />
+<hkern g1="K" g2="w" k="152" />
+<hkern g1="K" g2="y" k="182" />
+<hkern g1="K" g2="Adieresis" k="-49" />
+<hkern g1="K" g2="Aring" k="-49" />
+<hkern g1="K" g2="Ograve" k="113" />
+<hkern g1="K" g2="Oacute" k="113" />
+<hkern g1="K" g2="Ocircumflex" k="113" />
+<hkern g1="K" g2="Otilde" k="113" />
+<hkern g1="K" g2="Odieresis" k="113" />
+<hkern g1="K" g2="adieresis" k="35" />
+<hkern g1="K" g2="aring" k="39" />
+<hkern g1="K" g2="ae" k="29" />
+<hkern g1="K" g2="egrave" k="92" />
+<hkern g1="K" g2="eacute" k="94" />
+<hkern g1="K" g2="ecircumflex" k="92" />
+<hkern g1="K" g2="edieresis" k="86" />
+<hkern g1="K" g2="oacute" k="98" />
+<hkern g1="K" g2="odieresis" k="88" />
+<hkern g1="K" g2="udieresis" k="76" />
+<hkern g1="K" g2="OE" k="135" />
+<hkern g1="K" g2="oe" k="82" />
+<hkern g1="L" g2="hyphen" k="211" />
+<hkern g1="L" g2="A" k="-41" />
+<hkern g1="L" g2="C" k="135" />
+<hkern g1="L" g2="G" k="133" />
+<hkern g1="L" g2="O" k="129" />
+<hkern g1="L" g2="T" k="264" />
+<hkern g1="L" g2="U" k="102" />
+<hkern g1="L" g2="V" k="295" />
+<hkern g1="L" g2="W" k="221" />
+<hkern g1="L" g2="Y" k="244" />
+<hkern g1="L" g2="u" k="55" />
+<hkern g1="L" g2="y" k="190" />
+<hkern g1="L" g2="Aacute" k="-41" />
+<hkern g1="L" g2="Adieresis" k="-41" />
+<hkern g1="L" g2="Aring" k="-41" />
+<hkern g1="L" g2="AE" k="-43" />
+<hkern g1="L" g2="Ccedilla" k="137" />
+<hkern g1="L" g2="Ograve" k="129" />
+<hkern g1="L" g2="Oacute" k="129" />
+<hkern g1="L" g2="Ocircumflex" k="129" />
+<hkern g1="L" g2="Otilde" k="129" />
+<hkern g1="L" g2="Odieresis" k="129" />
+<hkern g1="L" g2="Udieresis" k="104" />
+<hkern g1="L" g2="udieresis" k="63" />
+<hkern g1="L" g2="quoteright" k="209" />
+<hkern g1="L" g2="quotedblright" k="209" />
+<hkern g1="N" g2="aacute" k="20" />
+<hkern g1="N" g2="eacute" k="23" />
+<hkern g1="N" g2="oacute" k="20" />
+<hkern g1="O" g2="comma" k="59" />
+<hkern g1="O" g2="period" k="49" />
+<hkern g1="O" g2="A" k="45" />
+<hkern g1="O" g2="T" k="117" />
+<hkern g1="O" g2="V" k="63" />
+<hkern g1="O" g2="W" k="49" />
+<hkern g1="O" g2="X" k="78" />
+<hkern g1="O" g2="Y" k="94" />
+<hkern g1="O" g2="Agrave" k="45" />
+<hkern g1="O" g2="Aacute" k="45" />
+<hkern g1="O" g2="Acircumflex" k="45" />
+<hkern g1="O" g2="Atilde" k="45" />
+<hkern g1="O" g2="Adieresis" k="45" />
+<hkern g1="O" g2="Aring" k="45" />
+<hkern g1="O" g2="AE" k="51" />
+<hkern g1="P" g2="comma" k="248" />
+<hkern g1="P" g2="hyphen" k="244" />
+<hkern g1="P" g2="period" k="244" />
+<hkern g1="P" g2="A" k="139" />
+<hkern g1="P" g2="a" k="66" />
+<hkern g1="P" g2="e" k="82" />
+<hkern g1="P" g2="i" k="37" />
+<hkern g1="P" g2="n" k="43" />
+<hkern g1="P" g2="o" k="80" />
+<hkern g1="P" g2="r" k="43" />
+<hkern g1="P" g2="s" k="47" />
+<hkern g1="P" g2="u" k="35" />
+<hkern g1="P" g2="Agrave" k="139" />
+<hkern g1="P" g2="Aacute" k="139" />
+<hkern g1="P" g2="Acircumflex" k="139" />
+<hkern g1="P" g2="Atilde" k="139" />
+<hkern g1="P" g2="Adieresis" k="139" />
+<hkern g1="P" g2="Aring" k="139" />
+<hkern g1="P" g2="AE" k="154" />
+<hkern g1="P" g2="agrave" k="74" />
+<hkern g1="P" g2="aacute" k="74" />
+<hkern g1="P" g2="acircumflex" k="63" />
+<hkern g1="P" g2="atilde" k="53" />
+<hkern g1="P" g2="adieresis" k="59" />
+<hkern g1="P" g2="aring" k="70" />
+<hkern g1="P" g2="ae" k="66" />
+<hkern g1="P" g2="egrave" k="94" />
+<hkern g1="P" g2="eacute" k="94" />
+<hkern g1="P" g2="ecircumflex" k="84" />
+<hkern g1="P" g2="edieresis" k="78" />
+<hkern g1="P" g2="ograve" k="92" />
+<hkern g1="P" g2="oacute" k="92" />
+<hkern g1="P" g2="ocircumflex" k="82" />
+<hkern g1="P" g2="otilde" k="74" />
+<hkern g1="P" g2="odieresis" k="74" />
+<hkern g1="P" g2="oslash" k="90" />
+<hkern g1="P" g2="ugrave" k="49" />
+<hkern g1="P" g2="uacute" k="49" />
+<hkern g1="P" g2="ucircumflex" k="43" />
+<hkern g1="P" g2="udieresis" k="39" />
+<hkern g1="P" g2="oe" k="78" />
+<hkern g1="Q" g2="A" k="43" />
+<hkern g1="Q" g2="Adieresis" k="43" />
+<hkern g1="R" g2="hyphen" k="29" />
+<hkern g1="R" g2="C" k="20" />
+<hkern g1="R" g2="G" k="20" />
+<hkern g1="R" g2="O" k="20" />
+<hkern g1="R" g2="Q" k="20" />
+<hkern g1="R" g2="T" k="78" />
+<hkern g1="R" g2="V" k="59" />
+<hkern g1="R" g2="W" k="47" />
+<hkern g1="R" g2="Y" k="76" />
+<hkern g1="R" g2="e" k="27" />
+<hkern g1="R" g2="o" k="29" />
+<hkern g1="R" g2="y" k="33" />
+<hkern g1="R" g2="Ccedilla" k="20" />
+<hkern g1="R" g2="Oacute" k="20" />
+<hkern g1="R" g2="Odieresis" k="20" />
+<hkern g1="R" g2="eacute" k="47" />
+<hkern g1="R" g2="oacute" k="51" />
+<hkern g1="R" g2="odieresis" k="39" />
+<hkern g1="R" g2="uacute" k="39" />
+<hkern g1="R" g2="udieresis" k="29" />
+<hkern g1="R" g2="OE" k="25" />
+<hkern g1="R" g2="oe" k="29" />
+<hkern g1="R" g2="quotesinglbase" k="-27" />
+<hkern g1="R" g2="quotedblbase" k="-27" />
+<hkern g1="S" g2="S" k="29" />
+<hkern g1="S" g2="T" k="33" />
+<hkern g1="S" g2="V" k="43" />
+<hkern g1="S" g2="W" k="47" />
+<hkern g1="S" g2="Y" k="41" />
+<hkern g1="S" g2="t" k="35" />
+<hkern g1="S" g2="quoteright" k="37" />
+<hkern g1="T" g2="comma" k="147" />
+<hkern g1="T" g2="hyphen" k="141" />
+<hkern g1="T" g2="period" k="141" />
+<hkern g1="T" g2="colon" k="141" />
+<hkern g1="T" g2="semicolon" k="143" />
+<hkern g1="T" g2="A" k="211" />
+<hkern g1="T" g2="C" k="117" />
+<hkern g1="T" g2="G" k="117" />
+<hkern g1="T" g2="H" k="23" />
+<hkern g1="T" g2="O" k="115" />
+<hkern g1="T" g2="S" k="41" />
+<hkern g1="T" g2="T" k="-51" />
+<hkern g1="T" g2="V" k="-39" />
+<hkern g1="T" g2="W" k="-27" />
+<hkern g1="T" g2="Y" k="-45" />
+<hkern g1="T" g2="a" k="242" />
+<hkern g1="T" g2="c" k="240" />
+<hkern g1="T" g2="e" k="240" />
+<hkern g1="T" g2="g" k="238" />
+<hkern g1="T" g2="h" k="27" />
+<hkern g1="T" g2="o" k="240" />
+<hkern g1="T" g2="r" k="236" />
+<hkern g1="T" g2="s" k="244" />
+<hkern g1="T" g2="u" k="238" />
+<hkern g1="T" g2="v" k="258" />
+<hkern g1="T" g2="w" k="256" />
+<hkern g1="T" g2="y" k="250" />
+<hkern g1="T" g2="z" k="248" />
+<hkern g1="T" g2="guillemotleft" k="248" />
+<hkern g1="T" g2="Agrave" k="211" />
+<hkern g1="T" g2="Aacute" k="211" />
+<hkern g1="T" g2="Acircumflex" k="211" />
+<hkern g1="T" g2="Atilde" k="211" />
+<hkern g1="T" g2="Adieresis" k="211" />
+<hkern g1="T" g2="Aring" k="211" />
+<hkern g1="T" g2="AE" k="223" />
+<hkern g1="T" g2="Ograve" k="115" />
+<hkern g1="T" g2="Oacute" k="115" />
+<hkern g1="T" g2="Ocircumflex" k="115" />
+<hkern g1="T" g2="Otilde" k="115" />
+<hkern g1="T" g2="Odieresis" k="115" />
+<hkern g1="T" g2="Oslash" k="123" />
+<hkern g1="T" g2="agrave" k="147" />
+<hkern g1="T" g2="aacute" k="238" />
+<hkern g1="T" g2="acircumflex" k="178" />
+<hkern g1="T" g2="atilde" k="113" />
+<hkern g1="T" g2="adieresis" k="119" />
+<hkern g1="T" g2="aring" k="115" />
+<hkern g1="T" g2="ae" k="242" />
+<hkern g1="T" g2="egrave" k="182" />
+<hkern g1="T" g2="eacute" k="244" />
+<hkern g1="T" g2="ecircumflex" k="199" />
+<hkern g1="T" g2="edieresis" k="137" />
+<hkern g1="T" g2="ograve" k="190" />
+<hkern g1="T" g2="oacute" k="248" />
+<hkern g1="T" g2="ocircumflex" k="203" />
+<hkern g1="T" g2="otilde" k="147" />
+<hkern g1="T" g2="odieresis" k="133" />
+<hkern g1="T" g2="oslash" k="244" />
+<hkern g1="T" g2="ugrave" k="186" />
+<hkern g1="T" g2="uacute" k="242" />
+<hkern g1="T" g2="ucircumflex" k="201" />
+<hkern g1="T" g2="udieresis" k="133" />
+<hkern g1="T" g2="OE" k="135" />
+<hkern g1="T" g2="oe" k="238" />
+<hkern g1="T" g2="guilsinglleft" k="248" />
+<hkern g1="U" g2="comma" k="45" />
+<hkern g1="U" g2="period" k="35" />
+<hkern g1="U" g2="A" k="41" />
+<hkern g1="U" g2="Aacute" k="41" />
+<hkern g1="U" g2="Acircumflex" k="41" />
+<hkern g1="U" g2="Atilde" k="41" />
+<hkern g1="U" g2="Adieresis" k="41" />
+<hkern g1="U" g2="Aring" k="41" />
+<hkern g1="U" g2="AE" k="47" />
+<hkern g1="V" g2="comma" k="168" />
+<hkern g1="V" g2="hyphen" k="104" />
+<hkern g1="V" g2="period" k="160" />
+<hkern g1="V" g2="colon" k="76" />
+<hkern g1="V" g2="semicolon" k="82" />
+<hkern g1="V" g2="A" k="178" />
+<hkern g1="V" g2="C" k="63" />
+<hkern g1="V" g2="G" k="63" />
+<hkern g1="V" g2="O" k="63" />
+<hkern g1="V" g2="S" k="29" />
+<hkern g1="V" g2="T" k="-37" />
+<hkern g1="V" g2="a" k="160" />
+<hkern g1="V" g2="e" k="160" />
+<hkern g1="V" g2="g" k="168" />
+<hkern g1="V" g2="i" k="27" />
+<hkern g1="V" g2="o" k="158" />
+<hkern g1="V" g2="r" k="133" />
+<hkern g1="V" g2="u" k="129" />
+<hkern g1="V" g2="y" k="94" />
+<hkern g1="V" g2="guillemotleft" k="172" />
+<hkern g1="V" g2="Agrave" k="178" />
+<hkern g1="V" g2="Aacute" k="178" />
+<hkern g1="V" g2="Acircumflex" k="178" />
+<hkern g1="V" g2="Atilde" k="178" />
+<hkern g1="V" g2="Adieresis" k="178" />
+<hkern g1="V" g2="Aring" k="178" />
+<hkern g1="V" g2="AE" k="190" />
+<hkern g1="V" g2="Ograve" k="63" />
+<hkern g1="V" g2="Oacute" k="63" />
+<hkern g1="V" g2="Ocircumflex" k="63" />
+<hkern g1="V" g2="Otilde" k="63" />
+<hkern g1="V" g2="Odieresis" k="63" />
+<hkern g1="V" g2="Oslash" k="70" />
+<hkern g1="V" g2="agrave" k="137" />
+<hkern g1="V" g2="aacute" k="162" />
+<hkern g1="V" g2="acircumflex" k="131" />
+<hkern g1="V" g2="atilde" k="100" />
+<hkern g1="V" g2="adieresis" k="113" />
+<hkern g1="V" g2="aring" k="109" />
+<hkern g1="V" g2="ae" k="160" />
+<hkern g1="V" g2="egrave" k="156" />
+<hkern g1="V" g2="eacute" k="168" />
+<hkern g1="V" g2="ecircumflex" k="143" />
+<hkern g1="V" g2="edieresis" k="125" />
+<hkern g1="V" g2="ograve" k="158" />
+<hkern g1="V" g2="oacute" k="168" />
+<hkern g1="V" g2="ocircumflex" k="145" />
+<hkern g1="V" g2="otilde" k="125" />
+<hkern g1="V" g2="odieresis" k="121" />
+<hkern g1="V" g2="oslash" k="166" />
+<hkern g1="V" g2="ugrave" k="135" />
+<hkern g1="V" g2="uacute" k="141" />
+<hkern g1="V" g2="ucircumflex" k="127" />
+<hkern g1="V" g2="udieresis" k="109" />
+<hkern g1="V" g2="OE" k="66" />
+<hkern g1="V" g2="oe" k="156" />
+<hkern g1="V" g2="quoteright" k="-20" />
+<hkern g1="V" g2="quotedblright" k="-20" />
+<hkern g1="V" g2="guilsinglleft" k="172" />
+<hkern g1="W" g2="comma" k="119" />
+<hkern g1="W" g2="hyphen" k="72" />
+<hkern g1="W" g2="period" k="111" />
+<hkern g1="W" g2="colon" k="55" />
+<hkern g1="W" g2="semicolon" k="59" />
+<hkern g1="W" g2="A" k="139" />
+<hkern g1="W" g2="C" k="47" />
+<hkern g1="W" g2="G" k="47" />
+<hkern g1="W" g2="O" k="45" />
+<hkern g1="W" g2="S" k="23" />
+<hkern g1="W" g2="T" k="-27" />
+<hkern g1="W" g2="a" k="117" />
+<hkern g1="W" g2="e" k="113" />
+<hkern g1="W" g2="g" k="121" />
+<hkern g1="W" g2="i" k="25" />
+<hkern g1="W" g2="o" k="113" />
+<hkern g1="W" g2="r" k="94" />
+<hkern g1="W" g2="u" k="92" />
+<hkern g1="W" g2="y" k="68" />
+<hkern g1="W" g2="guillemotleft" k="121" />
+<hkern g1="W" g2="Agrave" k="139" />
+<hkern g1="W" g2="Aacute" k="139" />
+<hkern g1="W" g2="Acircumflex" k="139" />
+<hkern g1="W" g2="Atilde" k="139" />
+<hkern g1="W" g2="Adieresis" k="139" />
+<hkern g1="W" g2="Aring" k="139" />
+<hkern g1="W" g2="AE" k="150" />
+<hkern g1="W" g2="Ograve" k="45" />
+<hkern g1="W" g2="Oacute" k="45" />
+<hkern g1="W" g2="Ocircumflex" k="45" />
+<hkern g1="W" g2="Otilde" k="45" />
+<hkern g1="W" g2="Odieresis" k="45" />
+<hkern g1="W" g2="Oslash" k="51" />
+<hkern g1="W" g2="agrave" k="117" />
+<hkern g1="W" g2="aacute" k="127" />
+<hkern g1="W" g2="acircumflex" k="106" />
+<hkern g1="W" g2="atilde" k="84" />
+<hkern g1="W" g2="adieresis" k="94" />
+<hkern g1="W" g2="aring" k="98" />
+<hkern g1="W" g2="ae" k="117" />
+<hkern g1="W" g2="egrave" k="121" />
+<hkern g1="W" g2="eacute" k="127" />
+<hkern g1="W" g2="ecircumflex" k="113" />
+<hkern g1="W" g2="edieresis" k="98" />
+<hkern g1="W" g2="ograve" k="123" />
+<hkern g1="W" g2="oacute" k="127" />
+<hkern g1="W" g2="ocircumflex" k="113" />
+<hkern g1="W" g2="otilde" k="98" />
+<hkern g1="W" g2="odieresis" k="98" />
+<hkern g1="W" g2="oslash" k="119" />
+<hkern g1="W" g2="ugrave" k="104" />
+<hkern g1="W" g2="uacute" k="109" />
+<hkern g1="W" g2="ucircumflex" k="98" />
+<hkern g1="W" g2="udieresis" k="86" />
+<hkern g1="W" g2="oe" k="111" />
+<hkern g1="W" g2="quoteright" k="-20" />
+<hkern g1="W" g2="quotedblright" k="-20" />
+<hkern g1="W" g2="guilsinglleft" k="121" />
+<hkern g1="X" g2="hyphen" k="55" />
+<hkern g1="X" g2="A" k="-31" />
+<hkern g1="X" g2="C" k="74" />
+<hkern g1="X" g2="G" k="74" />
+<hkern g1="X" g2="O" k="70" />
+<hkern g1="X" g2="Q" k="72" />
+<hkern g1="X" g2="e" k="51" />
+<hkern g1="X" g2="o" k="55" />
+<hkern g1="X" g2="u" k="47" />
+<hkern g1="X" g2="y" k="139" />
+<hkern g1="X" g2="Adieresis" k="-31" />
+<hkern g1="X" g2="Aring" k="-31" />
+<hkern g1="X" g2="Ograve" k="70" />
+<hkern g1="X" g2="Oacute" k="70" />
+<hkern g1="X" g2="Ocircumflex" k="70" />
+<hkern g1="X" g2="Otilde" k="70" />
+<hkern g1="X" g2="Odieresis" k="70" />
+<hkern g1="X" g2="adieresis" k="25" />
+<hkern g1="X" g2="egrave" k="70" />
+<hkern g1="X" g2="eacute" k="72" />
+<hkern g1="X" g2="ecircumflex" k="68" />
+<hkern g1="X" g2="edieresis" k="59" />
+<hkern g1="X" g2="ograve" k="72" />
+<hkern g1="X" g2="oacute" k="74" />
+<hkern g1="X" g2="ocircumflex" k="70" />
+<hkern g1="X" g2="otilde" k="63" />
+<hkern g1="X" g2="odieresis" k="61" />
+<hkern g1="X" g2="udieresis" k="55" />
+<hkern g1="X" g2="OE" k="84" />
+<hkern g1="X" g2="oe" k="55" />
+<hkern g1="Y" g2="comma" k="135" />
+<hkern g1="Y" g2="hyphen" k="131" />
+<hkern g1="Y" g2="period" k="131" />
+<hkern g1="Y" g2="colon" k="109" />
+<hkern g1="Y" g2="semicolon" k="113" />
+<hkern g1="Y" g2="A" k="190" />
+<hkern g1="Y" g2="C" k="94" />
+<hkern g1="Y" g2="G" k="94" />
+<hkern g1="Y" g2="O" k="94" />
+<hkern g1="Y" g2="S" k="43" />
+<hkern g1="Y" g2="T" k="-47" />
+<hkern g1="Y" g2="a" k="201" />
+<hkern g1="Y" g2="d" k="236" />
+<hkern g1="Y" g2="e" k="211" />
+<hkern g1="Y" g2="g" k="209" />
+<hkern g1="Y" g2="i" k="25" />
+<hkern g1="Y" g2="o" k="209" />
+<hkern g1="Y" g2="p" k="190" />
+<hkern g1="Y" g2="q" k="209" />
+<hkern g1="Y" g2="u" k="186" />
+<hkern g1="Y" g2="v" k="164" />
+<hkern g1="Y" g2="guillemotleft" k="227" />
+<hkern g1="Y" g2="Agrave" k="190" />
+<hkern g1="Y" g2="Aacute" k="190" />
+<hkern g1="Y" g2="Acircumflex" k="190" />
+<hkern g1="Y" g2="Atilde" k="190" />
+<hkern g1="Y" g2="Adieresis" k="190" />
+<hkern g1="Y" g2="Aring" k="190" />
+<hkern g1="Y" g2="AE" k="201" />
+<hkern g1="Y" g2="Ograve" k="94" />
+<hkern g1="Y" g2="Oacute" k="94" />
+<hkern g1="Y" g2="Ocircumflex" k="94" />
+<hkern g1="Y" g2="Otilde" k="94" />
+<hkern g1="Y" g2="Odieresis" k="94" />
+<hkern g1="Y" g2="Oslash" k="98" />
+<hkern g1="Y" g2="agrave" k="145" />
+<hkern g1="Y" g2="aacute" k="199" />
+<hkern g1="Y" g2="acircumflex" k="158" />
+<hkern g1="Y" g2="atilde" k="119" />
+<hkern g1="Y" g2="adieresis" k="129" />
+<hkern g1="Y" g2="aring" k="115" />
+<hkern g1="Y" g2="ae" k="201" />
+<hkern g1="Y" g2="egrave" k="178" />
+<hkern g1="Y" g2="eacute" k="213" />
+<hkern g1="Y" g2="ecircumflex" k="178" />
+<hkern g1="Y" g2="edieresis" k="147" />
+<hkern g1="Y" g2="ograve" k="186" />
+<hkern g1="Y" g2="oacute" k="217" />
+<hkern g1="Y" g2="ocircumflex" k="180" />
+<hkern g1="Y" g2="otilde" k="150" />
+<hkern g1="Y" g2="odieresis" k="145" />
+<hkern g1="Y" g2="oslash" k="215" />
+<hkern g1="Y" g2="ugrave" k="174" />
+<hkern g1="Y" g2="uacute" k="193" />
+<hkern g1="Y" g2="ucircumflex" k="168" />
+<hkern g1="Y" g2="udieresis" k="139" />
+<hkern g1="Y" g2="oe" k="209" />
+<hkern g1="Y" g2="guilsinglleft" k="229" />
+<hkern g1="Z" g2="O" k="86" />
+<hkern g1="Z" g2="v" k="168" />
+<hkern g1="Z" g2="y" k="158" />
+<hkern g1="Z" g2="Odieresis" k="86" />
+<hkern g1="a" g2="t" k="35" />
+<hkern g1="a" g2="v" k="70" />
+<hkern g1="a" g2="w" k="59" />
+<hkern g1="a" g2="y" k="63" />
+<hkern g1="b" g2="v" k="49" />
+<hkern g1="b" g2="w" k="39" />
+<hkern g1="b" g2="y" k="43" />
+<hkern g1="e" g2="t" k="27" />
+<hkern g1="e" g2="v" k="39" />
+<hkern g1="e" g2="w" k="33" />
+<hkern g1="e" g2="y" k="31" />
+<hkern g1="f" g2="comma" k="68" />
+<hkern g1="f" g2="hyphen" k="61" />
+<hkern g1="f" g2="period" k="61" />
+<hkern g1="f" g2="a" k="33" />
+<hkern g1="f" g2="e" k="63" />
+<hkern g1="f" g2="o" k="61" />
+<hkern g1="f" g2="s" k="29" />
+<hkern g1="f" g2="y" k="-31" />
+<hkern g1="f" g2="aacute" k="47" />
+<hkern g1="f" g2="adieresis" k="39" />
+<hkern g1="f" g2="aring" k="43" />
+<hkern g1="f" g2="ae" k="33" />
+<hkern g1="f" g2="egrave" k="78" />
+<hkern g1="f" g2="eacute" k="82" />
+<hkern g1="f" g2="ecircumflex" k="78" />
+<hkern g1="f" g2="edieresis" k="70" />
+<hkern g1="f" g2="idieresis" k="-31" />
+<hkern g1="f" g2="oacute" k="80" />
+<hkern g1="f" g2="odieresis" k="70" />
+<hkern g1="f" g2="oslash" k="70" />
+<hkern g1="f" g2="udieresis" k="20" />
+<hkern g1="f" g2="oe" k="59" />
+<hkern g1="g" g2="a" k="27" />
+<hkern g1="g" g2="e" k="29" />
+<hkern g1="g" g2="g" k="-70" />
+<hkern g1="g" g2="o" k="27" />
+<hkern g1="g" g2="adieresis" k="27" />
+<hkern g1="g" g2="aring" k="27" />
+<hkern g1="g" g2="ae" k="27" />
+<hkern g1="g" g2="egrave" k="29" />
+<hkern g1="g" g2="eacute" k="29" />
+<hkern g1="g" g2="ecircumflex" k="29" />
+<hkern g1="g" g2="edieresis" k="29" />
+<hkern g1="g" g2="oacute" k="27" />
+<hkern g1="g" g2="odieresis" k="27" />
+<hkern g1="h" g2="t" k="35" />
+<hkern g1="h" g2="y" k="35" />
+<hkern g1="h" g2="yacute" k="59" />
+<hkern g1="h" g2="ydieresis" k="51" />
+<hkern g1="h" g2="quoteright" k="252" />
+<hkern g1="k" g2="hyphen" k="133" />
+<hkern g1="k" g2="a" k="31" />
+<hkern g1="k" g2="e" k="78" />
+<hkern g1="k" g2="o" k="78" />
+<hkern g1="k" g2="u" k="29" />
+<hkern g1="k" g2="aacute" k="51" />
+<hkern g1="k" g2="adieresis" k="45" />
+<hkern g1="k" g2="aring" k="51" />
+<hkern g1="k" g2="ae" k="31" />
+<hkern g1="k" g2="eacute" k="100" />
+<hkern g1="k" g2="oacute" k="102" />
+<hkern g1="k" g2="odieresis" k="94" />
+<hkern g1="k" g2="udieresis" k="43" />
+<hkern g1="l" g2="v" k="47" />
+<hkern g1="l" g2="y" k="39" />
+<hkern g1="m" g2="v" k="43" />
+<hkern g1="m" g2="w" k="35" />
+<hkern g1="m" g2="y" k="35" />
+<hkern g1="n" g2="T" k="240" />
+<hkern g1="n" g2="v" k="43" />
+<hkern g1="n" g2="w" k="35" />
+<hkern g1="n" g2="y" k="35" />
+<hkern g1="o" g2="t" k="23" />
+<hkern g1="o" g2="v" k="47" />
+<hkern g1="o" g2="w" k="39" />
+<hkern g1="o" g2="x" k="51" />
+<hkern g1="o" g2="y" k="43" />
+<hkern g1="p" g2="t" k="25" />
+<hkern g1="p" g2="y" k="72" />
+<hkern g1="p" g2="yacute" k="72" />
+<hkern g1="p" g2="ydieresis" k="72" />
+<hkern g1="r" g2="comma" k="133" />
+<hkern g1="r" g2="hyphen" k="129" />
+<hkern g1="r" g2="period" k="129" />
+<hkern g1="r" g2="a" k="33" />
+<hkern g1="r" g2="c" k="57" />
+<hkern g1="r" g2="d" k="57" />
+<hkern g1="r" g2="e" k="59" />
+<hkern g1="r" g2="f" k="-20" />
+<hkern g1="r" g2="g" k="59" />
+<hkern g1="r" g2="h" k="23" />
+<hkern g1="r" g2="i" k="23" />
+<hkern g1="r" g2="j" k="23" />
+<hkern g1="r" g2="k" k="23" />
+<hkern g1="r" g2="m" k="23" />
+<hkern g1="r" g2="n" k="23" />
+<hkern g1="r" g2="o" k="55" />
+<hkern g1="r" g2="p" k="20" />
+<hkern g1="r" g2="q" k="55" />
+<hkern g1="r" g2="r" k="23" />
+<hkern g1="r" g2="s" k="20" />
+<hkern g1="r" g2="y" k="-20" />
+<hkern g1="r" g2="agrave" k="33" />
+<hkern g1="r" g2="aacute" k="33" />
+<hkern g1="r" g2="acircumflex" k="33" />
+<hkern g1="r" g2="adieresis" k="33" />
+<hkern g1="r" g2="aring" k="33" />
+<hkern g1="r" g2="ae" k="33" />
+<hkern g1="r" g2="ccedilla" k="55" />
+<hkern g1="r" g2="egrave" k="59" />
+<hkern g1="r" g2="eacute" k="59" />
+<hkern g1="r" g2="ecircumflex" k="59" />
+<hkern g1="r" g2="edieresis" k="59" />
+<hkern g1="r" g2="ograve" k="55" />
+<hkern g1="r" g2="oacute" k="55" />
+<hkern g1="r" g2="ocircumflex" k="55" />
+<hkern g1="r" g2="otilde" k="55" />
+<hkern g1="r" g2="odieresis" k="55" />
+<hkern g1="r" g2="oslash" k="63" />
+<hkern g1="r" g2="oe" k="53" />
+<hkern g1="r" g2="scaron" k="20" />
+<hkern g1="s" g2="s" k="25" />
+<hkern g1="t" g2="e" k="63" />
+<hkern g1="t" g2="h" k="25" />
+<hkern g1="t" g2="o" k="66" />
+<hkern g1="t" g2="t" k="25" />
+<hkern g1="t" g2="aacute" k="25" />
+<hkern g1="t" g2="atilde" k="23" />
+<hkern g1="t" g2="adieresis" k="23" />
+<hkern g1="t" g2="aring" k="25" />
+<hkern g1="t" g2="eacute" k="74" />
+<hkern g1="t" g2="oacute" k="76" />
+<hkern g1="t" g2="odieresis" k="74" />
+<hkern g1="t" g2="quoteright" k="86" />
+<hkern g1="u" g2="v" k="20" />
+<hkern g1="v" g2="comma" k="115" />
+<hkern g1="v" g2="hyphen" k="43" />
+<hkern g1="v" g2="period" k="104" />
+<hkern g1="v" g2="a" k="43" />
+<hkern g1="v" g2="c" k="47" />
+<hkern g1="v" g2="e" k="47" />
+<hkern g1="v" g2="g" k="55" />
+<hkern g1="v" g2="o" k="45" />
+<hkern g1="v" g2="s" k="29" />
+<hkern g1="v" g2="agrave" k="43" />
+<hkern g1="v" g2="aacute" k="43" />
+<hkern g1="v" g2="acircumflex" k="43" />
+<hkern g1="v" g2="atilde" k="43" />
+<hkern g1="v" g2="adieresis" k="43" />
+<hkern g1="v" g2="aring" k="43" />
+<hkern g1="v" g2="ae" k="43" />
+<hkern g1="v" g2="egrave" k="47" />
+<hkern g1="v" g2="eacute" k="47" />
+<hkern g1="v" g2="ecircumflex" k="47" />
+<hkern g1="v" g2="ograve" k="45" />
+<hkern g1="v" g2="oacute" k="45" />
+<hkern g1="v" g2="odieresis" k="45" />
+<hkern g1="v" g2="oslash" k="51" />
+<hkern g1="w" g2="comma" k="82" />
+<hkern g1="w" g2="hyphen" k="29" />
+<hkern g1="w" g2="period" k="74" />
+<hkern g1="w" g2="a" k="41" />
+<hkern g1="w" g2="c" k="39" />
+<hkern g1="w" g2="e" k="39" />
+<hkern g1="w" g2="g" k="47" />
+<hkern g1="w" g2="o" k="37" />
+<hkern g1="w" g2="s" k="27" />
+<hkern g1="w" g2="agrave" k="41" />
+<hkern g1="w" g2="aacute" k="41" />
+<hkern g1="w" g2="acircumflex" k="41" />
+<hkern g1="w" g2="atilde" k="41" />
+<hkern g1="w" g2="adieresis" k="41" />
+<hkern g1="w" g2="aring" k="41" />
+<hkern g1="w" g2="ae" k="41" />
+<hkern g1="w" g2="egrave" k="39" />
+<hkern g1="w" g2="eacute" k="39" />
+<hkern g1="w" g2="ecircumflex" k="39" />
+<hkern g1="w" g2="ograve" k="37" />
+<hkern g1="w" g2="oacute" k="37" />
+<hkern g1="w" g2="odieresis" k="37" />
+<hkern g1="w" g2="oslash" k="41" />
+<hkern g1="x" g2="c" k="49" />
+<hkern g1="x" g2="e" k="47" />
+<hkern g1="x" g2="o" k="49" />
+<hkern g1="x" g2="q" k="47" />
+<hkern g1="x" g2="eacute" k="47" />
+<hkern g1="x" g2="odieresis" k="49" />
+<hkern g1="y" g2="comma" k="109" />
+<hkern g1="y" g2="hyphen" k="35" />
+<hkern g1="y" g2="period" k="90" />
+<hkern g1="y" g2="semicolon" k="27" />
+<hkern g1="y" g2="a" k="35" />
+<hkern g1="y" g2="c" k="35" />
+<hkern g1="y" g2="d" k="35" />
+<hkern g1="y" g2="e" k="37" />
+<hkern g1="y" g2="g" k="66" />
+<hkern g1="y" g2="o" k="35" />
+<hkern g1="y" g2="q" k="63" />
+<hkern g1="y" g2="s" k="20" />
+<hkern g1="y" g2="agrave" k="35" />
+<hkern g1="y" g2="aacute" k="35" />
+<hkern g1="y" g2="acircumflex" k="35" />
+<hkern g1="y" g2="atilde" k="35" />
+<hkern g1="y" g2="adieresis" k="35" />
+<hkern g1="y" g2="aring" k="35" />
+<hkern g1="y" g2="ae" k="35" />
+<hkern g1="y" g2="egrave" k="37" />
+<hkern g1="y" g2="eacute" k="37" />
+<hkern g1="y" g2="ecircumflex" k="37" />
+<hkern g1="y" g2="ograve" k="35" />
+<hkern g1="y" g2="oacute" k="35" />
+<hkern g1="y" g2="odieresis" k="35" />
+<hkern g1="y" g2="oslash" k="43" />
+<hkern g1="y" g2="scaron" k="20" />
+<hkern g1="z" g2="c" k="41" />
+<hkern g1="z" g2="e" k="41" />
+<hkern g1="z" g2="o" k="41" />
+<hkern g1="z" g2="egrave" k="41" />
+<hkern g1="z" g2="eacute" k="41" />
+<hkern g1="z" g2="odieresis" k="41" />
+<hkern g1="z" g2="oslash" k="20" />
+<hkern g1="guillemotright" g2="A" k="35" />
+<hkern g1="guillemotright" g2="T" k="250" />
+<hkern g1="guillemotright" g2="V" k="172" />
+<hkern g1="guillemotright" g2="W" k="123" />
+<hkern g1="guillemotright" g2="Y" k="229" />
+<hkern g1="guillemotright" g2="Aacute" k="35" />
+<hkern g1="guillemotright" g2="Adieresis" k="35" />
+<hkern g1="guillemotright" g2="Aring" k="35" />
+<hkern g1="guillemotright" g2="AE" k="41" />
+<hkern g1="Agrave" g2="comma" k="-33" />
+<hkern g1="Agrave" g2="period" k="-39" />
+<hkern g1="Agrave" g2="C" k="41" />
+<hkern g1="Agrave" g2="G" k="41" />
+<hkern g1="Agrave" g2="O" k="39" />
+<hkern g1="Agrave" g2="Q" k="39" />
+<hkern g1="Agrave" g2="T" k="211" />
+<hkern g1="Agrave" g2="U" k="39" />
+<hkern g1="Agrave" g2="V" k="178" />
+<hkern g1="Agrave" g2="W" k="141" />
+<hkern g1="Agrave" g2="Y" k="190" />
+<hkern g1="Agrave" g2="d" k="35" />
+<hkern g1="Agrave" g2="v" k="88" />
+<hkern g1="Agrave" g2="w" k="70" />
+<hkern g1="Agrave" g2="y" k="82" />
+<hkern g1="Agrave" g2="Odieresis" k="51" />
+<hkern g1="Agrave" g2="Udieresis" k="51" />
+<hkern g1="Agrave" g2="quoteright" k="104" />
+<hkern g1="Aacute" g2="comma" k="-33" />
+<hkern g1="Aacute" g2="period" k="-39" />
+<hkern g1="Aacute" g2="C" k="41" />
+<hkern g1="Aacute" g2="G" k="41" />
+<hkern g1="Aacute" g2="O" k="39" />
+<hkern g1="Aacute" g2="Q" k="39" />
+<hkern g1="Aacute" g2="T" k="211" />
+<hkern g1="Aacute" g2="U" k="39" />
+<hkern g1="Aacute" g2="V" k="178" />
+<hkern g1="Aacute" g2="W" k="141" />
+<hkern g1="Aacute" g2="Y" k="190" />
+<hkern g1="Aacute" g2="d" k="35" />
+<hkern g1="Aacute" g2="g" k="-25" />
+<hkern g1="Aacute" g2="t" k="39" />
+<hkern g1="Aacute" g2="v" k="88" />
+<hkern g1="Aacute" g2="w" k="70" />
+<hkern g1="Aacute" g2="y" k="82" />
+<hkern g1="Aacute" g2="guillemotleft" k="33" />
+<hkern g1="Aacute" g2="Odieresis" k="51" />
+<hkern g1="Aacute" g2="Udieresis" k="51" />
+<hkern g1="Aacute" g2="udieresis" k="20" />
+<hkern g1="Aacute" g2="quoteright" k="104" />
+<hkern g1="Aacute" g2="guilsinglleft" k="33" />
+<hkern g1="Acircumflex" g2="comma" k="-33" />
+<hkern g1="Acircumflex" g2="period" k="-39" />
+<hkern g1="Acircumflex" g2="C" k="41" />
+<hkern g1="Acircumflex" g2="G" k="41" />
+<hkern g1="Acircumflex" g2="O" k="39" />
+<hkern g1="Acircumflex" g2="Q" k="39" />
+<hkern g1="Acircumflex" g2="T" k="211" />
+<hkern g1="Acircumflex" g2="U" k="39" />
+<hkern g1="Acircumflex" g2="V" k="178" />
+<hkern g1="Acircumflex" g2="W" k="141" />
+<hkern g1="Acircumflex" g2="Y" k="190" />
+<hkern g1="Acircumflex" g2="d" k="35" />
+<hkern g1="Acircumflex" g2="v" k="88" />
+<hkern g1="Acircumflex" g2="w" k="70" />
+<hkern g1="Acircumflex" g2="y" k="82" />
+<hkern g1="Acircumflex" g2="Odieresis" k="51" />
+<hkern g1="Acircumflex" g2="Udieresis" k="51" />
+<hkern g1="Acircumflex" g2="quoteright" k="104" />
+<hkern g1="Atilde" g2="comma" k="-33" />
+<hkern g1="Atilde" g2="period" k="-39" />
+<hkern g1="Atilde" g2="C" k="41" />
+<hkern g1="Atilde" g2="G" k="41" />
+<hkern g1="Atilde" g2="O" k="39" />
+<hkern g1="Atilde" g2="Q" k="39" />
+<hkern g1="Atilde" g2="T" k="211" />
+<hkern g1="Atilde" g2="U" k="39" />
+<hkern g1="Atilde" g2="V" k="178" />
+<hkern g1="Atilde" g2="W" k="141" />
+<hkern g1="Atilde" g2="Y" k="190" />
+<hkern g1="Atilde" g2="d" k="35" />
+<hkern g1="Atilde" g2="v" k="88" />
+<hkern g1="Atilde" g2="w" k="70" />
+<hkern g1="Atilde" g2="y" k="82" />
+<hkern g1="Atilde" g2="Odieresis" k="49" />
+<hkern g1="Atilde" g2="Udieresis" k="49" />
+<hkern g1="Atilde" g2="quoteright" k="104" />
+<hkern g1="Adieresis" g2="comma" k="-33" />
+<hkern g1="Adieresis" g2="period" k="-39" />
+<hkern g1="Adieresis" g2="A" k="-41" />
+<hkern g1="Adieresis" g2="C" k="41" />
+<hkern g1="Adieresis" g2="G" k="41" />
+<hkern g1="Adieresis" g2="O" k="39" />
+<hkern g1="Adieresis" g2="Q" k="39" />
+<hkern g1="Adieresis" g2="T" k="211" />
+<hkern g1="Adieresis" g2="U" k="39" />
+<hkern g1="Adieresis" g2="V" k="178" />
+<hkern g1="Adieresis" g2="W" k="141" />
+<hkern g1="Adieresis" g2="Y" k="190" />
+<hkern g1="Adieresis" g2="d" k="35" />
+<hkern g1="Adieresis" g2="f" k="51" />
+<hkern g1="Adieresis" g2="g" k="-25" />
+<hkern g1="Adieresis" g2="t" k="39" />
+<hkern g1="Adieresis" g2="v" k="88" />
+<hkern g1="Adieresis" g2="w" k="70" />
+<hkern g1="Adieresis" g2="y" k="82" />
+<hkern g1="Adieresis" g2="guillemotleft" k="33" />
+<hkern g1="Adieresis" g2="Adieresis" k="-35" />
+<hkern g1="Adieresis" g2="Ccedilla" k="41" />
+<hkern g1="Adieresis" g2="Ograve" k="51" />
+<hkern g1="Adieresis" g2="Oacute" k="51" />
+<hkern g1="Adieresis" g2="Ocircumflex" k="51" />
+<hkern g1="Adieresis" g2="Otilde" k="47" />
+<hkern g1="Adieresis" g2="Odieresis" k="51" />
+<hkern g1="Adieresis" g2="Ugrave" k="51" />
+<hkern g1="Adieresis" g2="Uacute" k="51" />
+<hkern g1="Adieresis" g2="Ucircumflex" k="51" />
+<hkern g1="Adieresis" g2="Udieresis" k="51" />
+<hkern g1="Adieresis" g2="Yacute" k="201" />
+<hkern g1="Adieresis" g2="ograve" k="29" />
+<hkern g1="Adieresis" g2="oacute" k="29" />
+<hkern g1="Adieresis" g2="ocircumflex" k="29" />
+<hkern g1="Adieresis" g2="otilde" k="25" />
+<hkern g1="Adieresis" g2="odieresis" k="20" />
+<hkern g1="Adieresis" g2="udieresis" k="20" />
+<hkern g1="Adieresis" g2="Ydieresis" k="195" />
+<hkern g1="Adieresis" g2="quoteright" k="104" />
+<hkern g1="Adieresis" g2="quotedblright" k="104" />
+<hkern g1="Adieresis" g2="guilsinglleft" k="33" />
+<hkern g1="Aring" g2="comma" k="-33" />
+<hkern g1="Aring" g2="period" k="-39" />
+<hkern g1="Aring" g2="C" k="41" />
+<hkern g1="Aring" g2="G" k="41" />
+<hkern g1="Aring" g2="O" k="39" />
+<hkern g1="Aring" g2="Q" k="39" />
+<hkern g1="Aring" g2="T" k="211" />
+<hkern g1="Aring" g2="U" k="39" />
+<hkern g1="Aring" g2="V" k="178" />
+<hkern g1="Aring" g2="W" k="141" />
+<hkern g1="Aring" g2="Y" k="190" />
+<hkern g1="Aring" g2="d" k="35" />
+<hkern g1="Aring" g2="f" k="51" />
+<hkern g1="Aring" g2="g" k="-25" />
+<hkern g1="Aring" g2="t" k="39" />
+<hkern g1="Aring" g2="v" k="88" />
+<hkern g1="Aring" g2="w" k="70" />
+<hkern g1="Aring" g2="y" k="82" />
+<hkern g1="Aring" g2="guillemotleft" k="33" />
+<hkern g1="Aring" g2="Odieresis" k="51" />
+<hkern g1="Aring" g2="Udieresis" k="51" />
+<hkern g1="Aring" g2="udieresis" k="20" />
+<hkern g1="Aring" g2="quoteright" k="104" />
+<hkern g1="Aring" g2="quotedblright" k="104" />
+<hkern g1="Aring" g2="guilsinglleft" k="33" />
+<hkern g1="AE" g2="hyphen" k="236" />
+<hkern g1="Eacute" g2="G" k="35" />
+<hkern g1="Eacute" g2="Q" k="33" />
+<hkern g1="Eacute" g2="c" k="55" />
+<hkern g1="Eth" g2="A" k="47" />
+<hkern g1="Eth" g2="V" k="63" />
+<hkern g1="Eth" g2="Y" k="98" />
+<hkern g1="Eth" g2="Adieresis" k="47" />
+<hkern g1="Eth" g2="Aring" k="47" />
+<hkern g1="Ograve" g2="T" k="117" />
+<hkern g1="Ograve" g2="V" k="63" />
+<hkern g1="Ograve" g2="Y" k="94" />
+<hkern g1="Oacute" g2="A" k="45" />
+<hkern g1="Oacute" g2="T" k="117" />
+<hkern g1="Oacute" g2="V" k="63" />
+<hkern g1="Oacute" g2="W" k="49" />
+<hkern g1="Oacute" g2="Y" k="94" />
+<hkern g1="Oacute" g2="Adieresis" k="55" />
+<hkern g1="Ocircumflex" g2="T" k="117" />
+<hkern g1="Ocircumflex" g2="V" k="63" />
+<hkern g1="Ocircumflex" g2="Y" k="94" />
+<hkern g1="Otilde" g2="T" k="117" />
+<hkern g1="Otilde" g2="V" k="63" />
+<hkern g1="Otilde" g2="Y" k="94" />
+<hkern g1="Odieresis" g2="comma" k="59" />
+<hkern g1="Odieresis" g2="period" k="49" />
+<hkern g1="Odieresis" g2="A" k="45" />
+<hkern g1="Odieresis" g2="T" k="117" />
+<hkern g1="Odieresis" g2="V" k="63" />
+<hkern g1="Odieresis" g2="W" k="49" />
+<hkern g1="Odieresis" g2="X" k="78" />
+<hkern g1="Odieresis" g2="Y" k="94" />
+<hkern g1="Odieresis" g2="Agrave" k="55" />
+<hkern g1="Odieresis" g2="Aacute" k="55" />
+<hkern g1="Odieresis" g2="Acircumflex" k="55" />
+<hkern g1="Odieresis" g2="Atilde" k="55" />
+<hkern g1="Odieresis" g2="Adieresis" k="55" />
+<hkern g1="Odieresis" g2="Aring" k="55" />
+<hkern g1="Odieresis" g2="AE" k="51" />
+<hkern g1="Oslash" g2="comma" k="72" />
+<hkern g1="Oslash" g2="period" k="55" />
+<hkern g1="Oslash" g2="A" k="51" />
+<hkern g1="Oslash" g2="X" k="35" />
+<hkern g1="Oslash" g2="Adieresis" k="51" />
+<hkern g1="Ugrave" g2="A" k="41" />
+<hkern g1="Ugrave" g2="Adieresis" k="53" />
+<hkern g1="Uacute" g2="comma" k="43" />
+<hkern g1="Uacute" g2="period" k="35" />
+<hkern g1="Uacute" g2="A" k="41" />
+<hkern g1="Uacute" g2="Adieresis" k="51" />
+<hkern g1="Ucircumflex" g2="A" k="41" />
+<hkern g1="Ucircumflex" g2="Adieresis" k="51" />
+<hkern g1="Udieresis" g2="comma" k="43" />
+<hkern g1="Udieresis" g2="period" k="35" />
+<hkern g1="Udieresis" g2="A" k="41" />
+<hkern g1="Udieresis" g2="Aacute" k="53" />
+<hkern g1="Udieresis" g2="Acircumflex" k="51" />
+<hkern g1="Udieresis" g2="Atilde" k="51" />
+<hkern g1="Udieresis" g2="Adieresis" k="51" />
+<hkern g1="Udieresis" g2="Aring" k="51" />
+<hkern g1="Udieresis" g2="AE" k="47" />
+<hkern g1="Thorn" g2="A" k="78" />
+<hkern g1="Thorn" g2="Aacute" k="78" />
+<hkern g1="Thorn" g2="Adieresis" k="78" />
+<hkern g1="Thorn" g2="Aring" k="78" />
+<hkern g1="Thorn" g2="AE" k="88" />
+<hkern g1="germandbls" g2="T" k="94" />
+<hkern g1="germandbls" g2="V" k="90" />
+<hkern g1="germandbls" g2="W" k="84" />
+<hkern g1="germandbls" g2="f" k="59" />
+<hkern g1="germandbls" g2="t" k="43" />
+<hkern g1="germandbls" g2="v" k="104" />
+<hkern g1="germandbls" g2="w" k="78" />
+<hkern g1="agrave" g2="t" k="49" />
+<hkern g1="agrave" g2="v" k="74" />
+<hkern g1="agrave" g2="w" k="63" />
+<hkern g1="agrave" g2="y" k="66" />
+<hkern g1="aacute" g2="t" k="51" />
+<hkern g1="aacute" g2="v" k="74" />
+<hkern g1="aacute" g2="w" k="63" />
+<hkern g1="aacute" g2="y" k="66" />
+<hkern g1="acircumflex" g2="t" k="47" />
+<hkern g1="adieresis" g2="t" k="47" />
+<hkern g1="adieresis" g2="v" k="74" />
+<hkern g1="adieresis" g2="w" k="63" />
+<hkern g1="adieresis" g2="y" k="66" />
+<hkern g1="adieresis" g2="germandbls" k="20" />
+<hkern g1="adieresis" g2="adieresis" k="20" />
+<hkern g1="aring" g2="t" k="49" />
+<hkern g1="aring" g2="v" k="74" />
+<hkern g1="aring" g2="w" k="63" />
+<hkern g1="aring" g2="y" k="66" />
+<hkern g1="ae" g2="v" k="37" />
+<hkern g1="ae" g2="w" k="33" />
+<hkern g1="ae" g2="y" k="29" />
+<hkern g1="egrave" g2="d" k="29" />
+<hkern g1="eacute" g2="d" k="29" />
+<hkern g1="eacute" g2="v" k="39" />
+<hkern g1="eacute" g2="w" k="33" />
+<hkern g1="eacute" g2="y" k="31" />
+<hkern g1="ecircumflex" g2="v" k="39" />
+<hkern g1="ecircumflex" g2="w" k="33" />
+<hkern g1="ecircumflex" g2="y" k="31" />
+<hkern g1="ograve" g2="v" k="47" />
+<hkern g1="ograve" g2="w" k="37" />
+<hkern g1="ograve" g2="y" k="41" />
+<hkern g1="oacute" g2="t" k="35" />
+<hkern g1="oacute" g2="v" k="47" />
+<hkern g1="oacute" g2="w" k="37" />
+<hkern g1="oacute" g2="y" k="41" />
+<hkern g1="ocircumflex" g2="t" k="33" />
+<hkern g1="ocircumflex" g2="v" k="47" />
+<hkern g1="odieresis" g2="t" k="31" />
+<hkern g1="odieresis" g2="v" k="47" />
+<hkern g1="odieresis" g2="w" k="37" />
+<hkern g1="odieresis" g2="x" k="51" />
+<hkern g1="odieresis" g2="y" k="41" />
+<hkern g1="udieresis" g2="v" k="20" />
+<hkern g1="yacute" g2="a" k="35" />
+<hkern g1="yacute" g2="c" k="35" />
+<hkern g1="yacute" g2="d" k="59" />
+<hkern g1="yacute" g2="e" k="37" />
+<hkern g1="yacute" g2="o" k="35" />
+<hkern g1="yacute" g2="adieresis" k="47" />
+<hkern g1="yacute" g2="odieresis" k="47" />
+<hkern g1="ydieresis" g2="a" k="35" />
+<hkern g1="ydieresis" g2="c" k="35" />
+<hkern g1="ydieresis" g2="d" k="51" />
+<hkern g1="ydieresis" g2="e" k="37" />
+<hkern g1="ydieresis" g2="o" k="35" />
+<hkern g1="ydieresis" g2="adieresis" k="43" />
+<hkern g1="ydieresis" g2="odieresis" k="45" />
+<hkern g1="ydieresis" g2="oslash" k="43" />
+<hkern g1="Scaron" g2="T" k="33" />
+<hkern g1="scaron" g2="w" k="33" />
+<hkern g1="quoteleft" g2="A" k="119" />
+<hkern g1="quoteleft" g2="T" k="-23" />
+<hkern g1="quoteleft" g2="V" k="-29" />
+<hkern g1="quoteleft" g2="W" k="-25" />
+<hkern g1="quoteleft" g2="Y" k="-29" />
+<hkern g1="quoteleft" g2="Aacute" k="119" />
+<hkern g1="quoteleft" g2="Adieresis" k="119" />
+<hkern g1="quoteleft" g2="Aring" k="119" />
+<hkern g1="quoteleft" g2="AE" k="131" />
+<hkern g1="quoteright" g2="A" k="125" />
+<hkern g1="quoteright" g2="d" k="254" />
+<hkern g1="quoteright" g2="t" k="55" />
+<hkern g1="quoteright" g2="Aacute" k="125" />
+<hkern g1="quoteright" g2="Adieresis" k="125" />
+<hkern g1="quoteright" g2="Aring" k="125" />
+<hkern g1="quoteright" g2="AE" k="139" />
+<hkern g1="quotedblleft" g2="A" k="119" />
+<hkern g1="quotedblleft" g2="T" k="-23" />
+<hkern g1="quotedblleft" g2="V" k="-29" />
+<hkern g1="quotedblleft" g2="W" k="-25" />
+<hkern g1="quotedblleft" g2="Y" k="-29" />
+<hkern g1="quotedblleft" g2="Aacute" k="119" />
+<hkern g1="quotedblleft" g2="Adieresis" k="119" />
+<hkern g1="quotedblleft" g2="Aring" k="119" />
+<hkern g1="quotedblleft" g2="AE" k="131" />
+<hkern g1="quotedblright" g2="A" k="125" />
+<hkern g1="quotedblright" g2="T" k="-27" />
+<hkern g1="quotedblright" g2="V" k="-29" />
+<hkern g1="quotedblright" g2="W" k="-25" />
+<hkern g1="quotedblright" g2="Y" k="-29" />
+<hkern g1="quotedblright" g2="Aacute" k="125" />
+<hkern g1="quotedblright" g2="Adieresis" k="125" />
+<hkern g1="quotedblright" g2="Aring" k="125" />
+<hkern g1="quotedblright" g2="AE" k="139" />
+<hkern g1="quotedblbase" g2="A" k="-51" />
+<hkern g1="quotedblbase" g2="T" k="131" />
+<hkern g1="quotedblbase" g2="V" k="156" />
+<hkern g1="quotedblbase" g2="W" k="106" />
+<hkern g1="quotedblbase" g2="Y" k="121" />
+<hkern g1="quotedblbase" g2="Adieresis" k="-51" />
+<hkern g1="quotedblbase" g2="AE" k="-51" />
+<hkern g1="guilsinglright" g2="A" k="35" />
+<hkern g1="guilsinglright" g2="T" k="250" />
+<hkern g1="guilsinglright" g2="V" k="172" />
+<hkern g1="guilsinglright" g2="W" k="123" />
+<hkern g1="guilsinglright" g2="Y" k="227" />
+<hkern g1="guilsinglright" g2="Aacute" k="35" />
+<hkern g1="guilsinglright" g2="Adieresis" k="35" />
+<hkern g1="guilsinglright" g2="Aring" k="35" />
+<hkern g1="guilsinglright" g2="AE" k="41" />
+</font>
+</defs>
+</svg>
diff --git a/dojox/gfx/resources/README b/dojox/gfx/resources/README
new file mode 100644
index 0000000..e938c47
--- /dev/null
+++ b/dojox/gfx/resources/README
@@ -0,0 +1,3 @@
+http://xmlgraphics.apache.org/batik/tools/font-converter.html
+
+
diff --git a/dojox/gfx/shape.js b/dojox/gfx/shape.js
new file mode 100644
index 0000000..5b34141
--- /dev/null
+++ b/dojox/gfx/shape.js
@@ -0,0 +1,366 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx.shape"]){
+dojo._hasResource["dojox.gfx.shape"]=true;
+dojo.provide("dojox.gfx.shape");
+dojo.require("dojox.gfx._base");
+dojo.declare("dojox.gfx.Shape",null,{constructor:function(){
+this.rawNode=null;
+this.shape=null;
+this.matrix=null;
+this.fillStyle=null;
+this.strokeStyle=null;
+this.bbox=null;
+this.parent=null;
+this.parentMatrix=null;
+},getNode:function(){
+return this.rawNode;
+},getShape:function(){
+return this.shape;
+},getTransform:function(){
+return this.matrix;
+},getFill:function(){
+return this.fillStyle;
+},getStroke:function(){
+return this.strokeStyle;
+},getParent:function(){
+return this.parent;
+},getBoundingBox:function(){
+return this.bbox;
+},getTransformedBoundingBox:function(){
+var b=this.getBoundingBox();
+if(!b){
+return null;
+}
+var m=this._getRealMatrix();
+var r=[];
+var g=dojox.gfx.matrix;
+r.push(g.multiplyPoint(m,b.x,b.y));
+r.push(g.multiplyPoint(m,b.x+b.width,b.y));
+r.push(g.multiplyPoint(m,b.x+b.width,b.y+b.height));
+r.push(g.multiplyPoint(m,b.x,b.y+b.height));
+return r;
+},getEventSource:function(){
+return this.rawNode;
+},setShape:function(_5){
+this.shape=dojox.gfx.makeParameters(this.shape,_5);
+this.bbox=null;
+return this;
+},setFill:function(_6){
+if(!_6){
+this.fillStyle=null;
+return this;
+}
+var f=null;
+if(typeof (_6)=="object"&&"type" in _6){
+switch(_6.type){
+case "linear":
+f=dojox.gfx.makeParameters(dojox.gfx.defaultLinearGradient,_6);
+break;
+case "radial":
+f=dojox.gfx.makeParameters(dojox.gfx.defaultRadialGradient,_6);
+break;
+case "pattern":
+f=dojox.gfx.makeParameters(dojox.gfx.defaultPattern,_6);
+break;
+}
+}else{
+f=dojox.gfx.normalizeColor(_6);
+}
+this.fillStyle=f;
+return this;
+},setStroke:function(_8){
+if(!_8){
+this.strokeStyle=null;
+return this;
+}
+if(typeof _8=="string"||dojo.isArray(_8)||_8 instanceof dojo.Color){
+_8={color:_8};
+}
+var s=this.strokeStyle=dojox.gfx.makeParameters(dojox.gfx.defaultStroke,_8);
+s.color=dojox.gfx.normalizeColor(s.color);
+return this;
+},setTransform:function(_a){
+this.matrix=dojox.gfx.matrix.clone(_a?dojox.gfx.matrix.normalize(_a):dojox.gfx.matrix.identity);
+return this._applyTransform();
+},_applyTransform:function(){
+return this;
+},moveToFront:function(){
+var p=this.getParent();
+if(p){
+p._moveChildToFront(this);
+this._moveToFront();
+}
+return this;
+},moveToBack:function(){
+var p=this.getParent();
+if(p){
+p._moveChildToBack(this);
+this._moveToBack();
+}
+return this;
+},_moveToFront:function(){
+},_moveToBack:function(){
+},applyRightTransform:function(_d){
+return _d?this.setTransform([this.matrix,_d]):this;
+},applyLeftTransform:function(_e){
+return _e?this.setTransform([_e,this.matrix]):this;
+},applyTransform:function(_f){
+return _f?this.setTransform([this.matrix,_f]):this;
+},removeShape:function(_10){
+if(this.parent){
+this.parent.remove(this,_10);
+}
+return this;
+},_setParent:function(_11,_12){
+this.parent=_11;
+return this._updateParentMatrix(_12);
+},_updateParentMatrix:function(_13){
+this.parentMatrix=_13?dojox.gfx.matrix.clone(_13):null;
+return this._applyTransform();
+},_getRealMatrix:function(){
+var m=this.matrix;
+var p=this.parent;
+while(p){
+if(p.matrix){
+m=dojox.gfx.matrix.multiply(p.matrix,m);
+}
+p=p.parent;
+}
+return m;
+}});
+dojox.gfx.shape._eventsProcessing={connect:function(_16,_17,_18){
+return arguments.length>2?dojo.connect(this.getEventSource(),_16,_17,_18):dojo.connect(this.getEventSource(),_16,_17);
+},disconnect:function(_19){
+dojo.disconnect(_19);
+}};
+dojo.extend(dojox.gfx.Shape,dojox.gfx.shape._eventsProcessing);
+dojox.gfx.shape.Container={_init:function(){
+this.children=[];
+},add:function(_1a){
+var _1b=_1a.getParent();
+if(_1b){
+_1b.remove(_1a,true);
+}
+this.children.push(_1a);
+return _1a._setParent(this,this._getRealMatrix());
+},remove:function(_1c,_1d){
+for(var i=0;i<this.children.length;++i){
+if(this.children[i]==_1c){
+if(_1d){
+}else{
+_1c.parent=null;
+_1c.parentMatrix=null;
+}
+this.children.splice(i,1);
+break;
+}
+}
+return this;
+},clear:function(){
+this.children=[];
+return this;
+},_moveChildToFront:function(_1f){
+for(var i=0;i<this.children.length;++i){
+if(this.children[i]==_1f){
+this.children.splice(i,1);
+this.children.push(_1f);
+break;
+}
+}
+return this;
+},_moveChildToBack:function(_21){
+for(var i=0;i<this.children.length;++i){
+if(this.children[i]==_21){
+this.children.splice(i,1);
+this.children.unshift(_21);
+break;
+}
+}
+return this;
+}};
+dojo.declare("dojox.gfx.shape.Surface",null,{constructor:function(){
+this.rawNode=null;
+this._parent=null;
+this._nodes=[];
+this._events=[];
+},destroy:function(){
+dojo.forEach(this._nodes,dojo.destroy);
+this._nodes=[];
+dojo.forEach(this._events,dojo.disconnect);
+this._events=[];
+this.rawNode=null;
+if(dojo.isIE){
+while(this._parent.lastChild){
+dojo.destroy(this._parent.lastChild);
+}
+}else{
+this._parent.innerHTML="";
+}
+this._parent=null;
+},getEventSource:function(){
+return this.rawNode;
+},_getRealMatrix:function(){
+return null;
+},isLoaded:true,onLoad:function(_23){
+},whenLoaded:function(_24,_25){
+var f=dojo.hitch(_24,_25);
+if(this.isLoaded){
+f(this);
+}else{
+var h=dojo.connect(this,"onLoad",function(_28){
+dojo.disconnect(h);
+f(_28);
+});
+}
+}});
+dojo.extend(dojox.gfx.shape.Surface,dojox.gfx.shape._eventsProcessing);
+dojo.declare("dojox.gfx.Point",null,{});
+dojo.declare("dojox.gfx.Rectangle",null,{});
+dojo.declare("dojox.gfx.shape.Rect",dojox.gfx.Shape,{constructor:function(_29){
+this.shape=dojox.gfx.getDefault("Rect");
+this.rawNode=_29;
+},getBoundingBox:function(){
+return this.shape;
+}});
+dojo.declare("dojox.gfx.shape.Ellipse",dojox.gfx.Shape,{constructor:function(_2a){
+this.shape=dojox.gfx.getDefault("Ellipse");
+this.rawNode=_2a;
+},getBoundingBox:function(){
+if(!this.bbox){
+var _2b=this.shape;
+this.bbox={x:_2b.cx-_2b.rx,y:_2b.cy-_2b.ry,width:2*_2b.rx,height:2*_2b.ry};
+}
+return this.bbox;
+}});
+dojo.declare("dojox.gfx.shape.Circle",dojox.gfx.Shape,{constructor:function(_2c){
+this.shape=dojox.gfx.getDefault("Circle");
+this.rawNode=_2c;
+},getBoundingBox:function(){
+if(!this.bbox){
+var _2d=this.shape;
+this.bbox={x:_2d.cx-_2d.r,y:_2d.cy-_2d.r,width:2*_2d.r,height:2*_2d.r};
+}
+return this.bbox;
+}});
+dojo.declare("dojox.gfx.shape.Line",dojox.gfx.Shape,{constructor:function(_2e){
+this.shape=dojox.gfx.getDefault("Line");
+this.rawNode=_2e;
+},getBoundingBox:function(){
+if(!this.bbox){
+var _2f=this.shape;
+this.bbox={x:Math.min(_2f.x1,_2f.x2),y:Math.min(_2f.y1,_2f.y2),width:Math.abs(_2f.x2-_2f.x1),height:Math.abs(_2f.y2-_2f.y1)};
+}
+return this.bbox;
+}});
+dojo.declare("dojox.gfx.shape.Polyline",dojox.gfx.Shape,{constructor:function(_30){
+this.shape=dojox.gfx.getDefault("Polyline");
+this.rawNode=_30;
+},setShape:function(_31,_32){
+if(_31&&_31 instanceof Array){
+dojox.gfx.Shape.prototype.setShape.call(this,{points:_31});
+if(_32&&this.shape.points.length){
+this.shape.points.push(this.shape.points[0]);
+}
+}else{
+dojox.gfx.Shape.prototype.setShape.call(this,_31);
+}
+return this;
+},getBoundingBox:function(){
+if(!this.bbox&&this.shape.points.length){
+var p=this.shape.points;
+var l=p.length;
+var t=p[0];
+var _36={l:t.x,t:t.y,r:t.x,b:t.y};
+for(var i=1;i<l;++i){
+t=p[i];
+if(_36.l>t.x){
+_36.l=t.x;
+}
+if(_36.r<t.x){
+_36.r=t.x;
+}
+if(_36.t>t.y){
+_36.t=t.y;
+}
+if(_36.b<t.y){
+_36.b=t.y;
+}
+}
+this.bbox={x:_36.l,y:_36.t,width:_36.r-_36.l,height:_36.b-_36.t};
+}
+return this.bbox;
+}});
+dojo.declare("dojox.gfx.shape.Image",dojox.gfx.Shape,{constructor:function(_38){
+this.shape=dojox.gfx.getDefault("Image");
+this.rawNode=_38;
+},getBoundingBox:function(){
+return this.shape;
+},setStroke:function(){
+return this;
+},setFill:function(){
+return this;
+}});
+dojo.declare("dojox.gfx.shape.Text",dojox.gfx.Shape,{constructor:function(_39){
+this.fontStyle=null;
+this.shape=dojox.gfx.getDefault("Text");
+this.rawNode=_39;
+},getFont:function(){
+return this.fontStyle;
+},setFont:function(_3a){
+this.fontStyle=typeof _3a=="string"?dojox.gfx.splitFontString(_3a):dojox.gfx.makeParameters(dojox.gfx.defaultFont,_3a);
+this._setFont();
+return this;
+}});
+dojox.gfx.shape.Creator={createShape:function(_3b){
+var gfx=dojox.gfx;
+switch(_3b.type){
+case gfx.defaultPath.type:
+return this.createPath(_3b);
+case gfx.defaultRect.type:
+return this.createRect(_3b);
+case gfx.defaultCircle.type:
+return this.createCircle(_3b);
+case gfx.defaultEllipse.type:
+return this.createEllipse(_3b);
+case gfx.defaultLine.type:
+return this.createLine(_3b);
+case gfx.defaultPolyline.type:
+return this.createPolyline(_3b);
+case gfx.defaultImage.type:
+return this.createImage(_3b);
+case gfx.defaultText.type:
+return this.createText(_3b);
+case gfx.defaultTextPath.type:
+return this.createTextPath(_3b);
+}
+return null;
+},createGroup:function(){
+return this.createObject(dojox.gfx.Group);
+},createRect:function(_3d){
+return this.createObject(dojox.gfx.Rect,_3d);
+},createEllipse:function(_3e){
+return this.createObject(dojox.gfx.Ellipse,_3e);
+},createCircle:function(_3f){
+return this.createObject(dojox.gfx.Circle,_3f);
+},createLine:function(_40){
+return this.createObject(dojox.gfx.Line,_40);
+},createPolyline:function(_41){
+return this.createObject(dojox.gfx.Polyline,_41);
+},createImage:function(_42){
+return this.createObject(dojox.gfx.Image,_42);
+},createText:function(_43){
+return this.createObject(dojox.gfx.Text,_43);
+},createPath:function(_44){
+return this.createObject(dojox.gfx.Path,_44);
+},createTextPath:function(_45){
+return this.createObject(dojox.gfx.TextPath,{}).setText(_45);
+},createObject:function(_46,_47){
+return null;
+}};
+}
diff --git a/dojox/gfx/silverlight.js b/dojox/gfx/silverlight.js
new file mode 100644
index 0000000..5512e6b
--- /dev/null
+++ b/dojox/gfx/silverlight.js
@@ -0,0 +1,499 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx.silverlight"]){
+dojo._hasResource["dojox.gfx.silverlight"]=true;
+dojo.provide("dojox.gfx.silverlight");
+dojo.require("dojox.gfx._base");
+dojo.require("dojox.gfx.shape");
+dojo.require("dojox.gfx.path");
+dojo.experimental("dojox.gfx.silverlight");
+dojox.gfx.silverlight.dasharray={solid:"none",shortdash:[4,1],shortdot:[1,1],shortdashdot:[4,1,1,1],shortdashdotdot:[4,1,1,1,1,1],dot:[1,3],dash:[4,3],longdash:[8,3],dashdot:[4,3,1,3],longdashdot:[8,3,1,3],longdashdotdot:[8,3,1,3,1,3]};
+dojox.gfx.silverlight.fontweight={normal:400,bold:700};
+dojox.gfx.silverlight.caps={butt:"Flat",round:"Round",square:"Square"};
+dojox.gfx.silverlight.joins={bevel:"Bevel",round:"Round"};
+dojox.gfx.silverlight.fonts={serif:"Times New Roman",times:"Times New Roman","sans-serif":"Arial",helvetica:"Arial",monotone:"Courier New",courier:"Courier New"};
+dojox.gfx.silverlight.hexColor=function(_1){
+var c=dojox.gfx.normalizeColor(_1),t=c.toHex(),a=Math.round(c.a*255);
+a=(a<0?0:a>255?255:a).toString(16);
+return "#"+(a.length<2?"0"+a:a)+t.slice(1);
+};
+dojo.extend(dojox.gfx.Shape,{setFill:function(_5){
+var p=this.rawNode.getHost().content,r=this.rawNode,f;
+if(!_5){
+this.fillStyle=null;
+this._setFillAttr(null);
+return this;
+}
+if(typeof (_5)=="object"&&"type" in _5){
+switch(_5.type){
+case "linear":
+this.fillStyle=f=dojox.gfx.makeParameters(dojox.gfx.defaultLinearGradient,_5);
+var _9=p.createFromXaml("<LinearGradientBrush/>");
+_9.mappingMode="Absolute";
+_9.startPoint=f.x1+","+f.y1;
+_9.endPoint=f.x2+","+f.y2;
+dojo.forEach(f.colors,function(c){
+var t=p.createFromXaml("<GradientStop/>");
+t.offset=c.offset;
+t.color=dojox.gfx.silverlight.hexColor(c.color);
+_9.gradientStops.add(t);
+});
+this._setFillAttr(_9);
+break;
+case "radial":
+this.fillStyle=f=dojox.gfx.makeParameters(dojox.gfx.defaultRadialGradient,_5);
+var _c=p.createFromXaml("<RadialGradientBrush/>"),c=dojox.gfx.matrix.multiplyPoint(dojox.gfx.matrix.invert(this._getAdjustedMatrix()),f.cx,f.cy),pt=c.x+","+c.y;
+_c.mappingMode="Absolute";
+_c.gradientOrigin=pt;
+_c.center=pt;
+_c.radiusX=_c.radiusY=f.r;
+dojo.forEach(f.colors,function(c){
+var t=p.createFromXaml("<GradientStop/>");
+t.offset=c.offset;
+t.color=dojox.gfx.silverlight.hexColor(c.color);
+_c.gradientStops.add(t);
+});
+this._setFillAttr(_c);
+break;
+case "pattern":
+this.fillStyle=null;
+this._setFillAttr(null);
+break;
+}
+return this;
+}
+this.fillStyle=f=dojox.gfx.normalizeColor(_5);
+var scb=p.createFromXaml("<SolidColorBrush/>");
+scb.color=f.toHex();
+scb.opacity=f.a;
+this._setFillAttr(scb);
+return this;
+},_setFillAttr:function(f){
+this.rawNode.fill=f;
+},setStroke:function(_13){
+var p=this.rawNode.getHost().content,r=this.rawNode;
+if(!_13){
+this.strokeStyle=null;
+r.stroke=null;
+return this;
+}
+if(typeof _13=="string"||dojo.isArray(_13)||_13 instanceof dojo.Color){
+_13={color:_13};
+}
+var s=this.strokeStyle=dojox.gfx.makeParameters(dojox.gfx.defaultStroke,_13);
+s.color=dojox.gfx.normalizeColor(s.color);
+if(s){
+var scb=p.createFromXaml("<SolidColorBrush/>");
+scb.color=s.color.toHex();
+scb.opacity=s.color.a;
+r.stroke=scb;
+r.strokeThickness=s.width;
+r.strokeStartLineCap=r.strokeEndLineCap=r.strokeDashCap=dojox.gfx.silverlight.caps[s.cap];
+if(typeof s.join=="number"){
+r.strokeLineJoin="Miter";
+r.strokeMiterLimit=s.join;
+}else{
+r.strokeLineJoin=dojox.gfx.silverlight.joins[s.join];
+}
+var da=s.style.toLowerCase();
+if(da in dojox.gfx.silverlight.dasharray){
+da=dojox.gfx.silverlight.dasharray[da];
+}
+if(da instanceof Array){
+da=dojo.clone(da);
+if(s.cap!="butt"){
+for(var i=0;i<da.length;i+=2){
+--da[i];
+if(da[i]<1){
+da[i]=1;
+}
+}
+for(var i=1;i<da.length;i+=2){
+++da[i];
+}
+}
+r.strokeDashArray=da.join(",");
+}else{
+r.strokeDashArray=null;
+}
+}
+return this;
+},_getParentSurface:function(){
+var _1a=this.parent;
+for(;_1a&&!(_1a instanceof dojox.gfx.Surface);_1a=_1a.parent){
+}
+return _1a;
+},_applyTransform:function(){
+var tm=this._getAdjustedMatrix(),r=this.rawNode;
+if(tm){
+var p=this.rawNode.getHost().content,m=p.createFromXaml("<MatrixTransform/>"),mm=p.createFromXaml("<Matrix/>");
+mm.m11=tm.xx;
+mm.m21=tm.xy;
+mm.m12=tm.yx;
+mm.m22=tm.yy;
+mm.offsetX=tm.dx;
+mm.offsetY=tm.dy;
+m.matrix=mm;
+r.renderTransform=m;
+}else{
+r.renderTransform=null;
+}
+return this;
+},setRawNode:function(_20){
+_20.fill=null;
+_20.stroke=null;
+this.rawNode=_20;
+},_moveToFront:function(){
+var c=this.parent.rawNode.children,r=this.rawNode;
+c.remove(r);
+c.add(r);
+return this;
+},_moveToBack:function(){
+var c=this.parent.rawNode.children,r=this.rawNode;
+c.remove(r);
+c.insert(0,r);
+return this;
+},_getAdjustedMatrix:function(){
+return this.matrix;
+}});
+dojo.declare("dojox.gfx.Group",dojox.gfx.Shape,{constructor:function(){
+dojox.gfx.silverlight.Container._init.call(this);
+},setRawNode:function(_25){
+this.rawNode=_25;
+}});
+dojox.gfx.Group.nodeType="Canvas";
+dojo.declare("dojox.gfx.Rect",dojox.gfx.shape.Rect,{setShape:function(_26){
+this.shape=dojox.gfx.makeParameters(this.shape,_26);
+this.bbox=null;
+var r=this.rawNode,n=this.shape;
+r.width=n.width;
+r.height=n.height;
+r.radiusX=r.radiusY=n.r;
+return this._applyTransform();
+},_getAdjustedMatrix:function(){
+var m=this.matrix,s=this.shape,d={dx:s.x,dy:s.y};
+return new dojox.gfx.Matrix2D(m?[m,d]:d);
+}});
+dojox.gfx.Rect.nodeType="Rectangle";
+dojo.declare("dojox.gfx.Ellipse",dojox.gfx.shape.Ellipse,{setShape:function(_2c){
+this.shape=dojox.gfx.makeParameters(this.shape,_2c);
+this.bbox=null;
+var r=this.rawNode,n=this.shape;
+r.width=2*n.rx;
+r.height=2*n.ry;
+return this._applyTransform();
+},_getAdjustedMatrix:function(){
+var m=this.matrix,s=this.shape,d={dx:s.cx-s.rx,dy:s.cy-s.ry};
+return new dojox.gfx.Matrix2D(m?[m,d]:d);
+}});
+dojox.gfx.Ellipse.nodeType="Ellipse";
+dojo.declare("dojox.gfx.Circle",dojox.gfx.shape.Circle,{setShape:function(_32){
+this.shape=dojox.gfx.makeParameters(this.shape,_32);
+this.bbox=null;
+var r=this.rawNode,n=this.shape;
+r.width=r.height=2*n.r;
+return this._applyTransform();
+},_getAdjustedMatrix:function(){
+var m=this.matrix,s=this.shape,d={dx:s.cx-s.r,dy:s.cy-s.r};
+return new dojox.gfx.Matrix2D(m?[m,d]:d);
+}});
+dojox.gfx.Circle.nodeType="Ellipse";
+dojo.declare("dojox.gfx.Line",dojox.gfx.shape.Line,{setShape:function(_38){
+this.shape=dojox.gfx.makeParameters(this.shape,_38);
+this.bbox=null;
+var r=this.rawNode,n=this.shape;
+r.x1=n.x1;
+r.y1=n.y1;
+r.x2=n.x2;
+r.y2=n.y2;
+return this;
+}});
+dojox.gfx.Line.nodeType="Line";
+dojo.declare("dojox.gfx.Polyline",dojox.gfx.shape.Polyline,{setShape:function(_3b,_3c){
+if(_3b&&_3b instanceof Array){
+this.shape=dojox.gfx.makeParameters(this.shape,{points:_3b});
+if(_3c&&this.shape.points.length){
+this.shape.points.push(this.shape.points[0]);
+}
+}else{
+this.shape=dojox.gfx.makeParameters(this.shape,_3b);
+}
+this.box=null;
+var p=this.shape.points,rp=[];
+for(var i=0;i<p.length;++i){
+if(typeof p[i]=="number"){
+rp.push(p[i],p[++i]);
+}else{
+rp.push(p[i].x,p[i].y);
+}
+}
+this.rawNode.points=rp.join(",");
+return this;
+}});
+dojox.gfx.Polyline.nodeType="Polyline";
+dojo.declare("dojox.gfx.Image",dojox.gfx.shape.Image,{setShape:function(_40){
+this.shape=dojox.gfx.makeParameters(this.shape,_40);
+this.bbox=null;
+var r=this.rawNode,n=this.shape;
+r.width=n.width;
+r.height=n.height;
+r.source=n.src;
+return this._applyTransform();
+},_getAdjustedMatrix:function(){
+var m=this.matrix,s=this.shape,d={dx:s.x,dy:s.y};
+return new dojox.gfx.Matrix2D(m?[m,d]:d);
+},setRawNode:function(_46){
+this.rawNode=_46;
+}});
+dojox.gfx.Image.nodeType="Image";
+dojo.declare("dojox.gfx.Text",dojox.gfx.shape.Text,{setShape:function(_47){
+this.shape=dojox.gfx.makeParameters(this.shape,_47);
+this.bbox=null;
+var r=this.rawNode,s=this.shape;
+r.text=s.text;
+r.textDecorations=s.decoration==="underline"?"Underline":"None";
+r["Canvas.Left"]=-10000;
+r["Canvas.Top"]=-10000;
+if(!this._delay){
+this._delay=window.setTimeout(dojo.hitch(this,"_delayAlignment"),10);
+}
+return this;
+},_delayAlignment:function(){
+var r=this.rawNode,s=this.shape,w=r.actualWidth,h=r.actualHeight,x=s.x,y=s.y-h*0.75;
+switch(s.align){
+case "middle":
+x-=w/2;
+break;
+case "end":
+x-=w;
+break;
+}
+this._delta={dx:x,dy:y};
+r["Canvas.Left"]=0;
+r["Canvas.Top"]=0;
+this._applyTransform();
+delete this._delay;
+},_getAdjustedMatrix:function(){
+var m=this.matrix,d=this._delta,x;
+if(m){
+x=d?[m,d]:m;
+}else{
+x=d?d:{};
+}
+return new dojox.gfx.Matrix2D(x);
+},setStroke:function(){
+return this;
+},_setFillAttr:function(f){
+this.rawNode.foreground=f;
+},setRawNode:function(_54){
+this.rawNode=_54;
+},getTextWidth:function(){
+return this.rawNode.actualWidth;
+}});
+dojox.gfx.Text.nodeType="TextBlock";
+dojo.declare("dojox.gfx.Path",dojox.gfx.path.Path,{_updateWithSegment:function(_55){
+dojox.gfx.Path.superclass._updateWithSegment.apply(this,arguments);
+var p=this.shape.path;
+if(typeof (p)=="string"){
+this.rawNode.data=p?p:null;
+}
+},setShape:function(_57){
+dojox.gfx.Path.superclass.setShape.apply(this,arguments);
+var p=this.shape.path;
+this.rawNode.data=p?p:null;
+return this;
+}});
+dojox.gfx.Path.nodeType="Path";
+dojo.declare("dojox.gfx.TextPath",dojox.gfx.path.TextPath,{_updateWithSegment:function(_59){
+},setShape:function(_5a){
+},_setText:function(){
+}});
+dojox.gfx.TextPath.nodeType="text";
+dojox.gfx.silverlight.surfaces={};
+dojox.gfx.silverlight.nullFunc=function(){
+};
+dojo.declare("dojox.gfx.Surface",dojox.gfx.shape.Surface,{constructor:function(){
+dojox.gfx.silverlight.Container._init.call(this);
+},destroy:function(){
+window[this._onLoadName]=dojox.gfx.silverlight.nullFunc;
+delete dojox.gfx.silverlight.surfaces[this.rawNode.name];
+this.inherited(arguments);
+},setDimensions:function(_5b,_5c){
+this.width=dojox.gfx.normalizedLength(_5b);
+this.height=dojox.gfx.normalizedLength(_5c);
+var p=this.rawNode&&this.rawNode.getHost();
+if(p){
+p.width=_5b;
+p.height=_5c;
+}
+return this;
+},getDimensions:function(){
+var p=this.rawNode&&this.rawNode.getHost();
+var t=p?{width:p.content.actualWidth,height:p.content.actualHeight}:null;
+if(t.width<=0){
+t.width=this.width;
+}
+if(t.height<=0){
+t.height=this.height;
+}
+return t;
+}});
+dojox.gfx.createSurface=function(_60,_61,_62){
+var s=new dojox.gfx.Surface();
+_60=dojo.byId(_60);
+s._parent=_60;
+var t=_60.ownerDocument.createElement("script");
+t.type="text/xaml";
+t.id=dojox.gfx._base._getUniqueId();
+t.text="<?xml version='1.0'?><Canvas xmlns='http://schemas.microsoft.com/client/2007' Name='"+dojox.gfx._base._getUniqueId()+"'/>";
+_60.parentNode.insertBefore(t,_60);
+s._nodes.push(t);
+var obj,_66=dojox.gfx._base._getUniqueId(),_67="__"+dojox.gfx._base._getUniqueId()+"_onLoad";
+s._onLoadName=_67;
+window[_67]=function(_68){
+
+if(!s.rawNode){
+s.rawNode=dojo.byId(_66).content.root;
+dojox.gfx.silverlight.surfaces[s.rawNode.name]=_60;
+s.onLoad(s);
+
+}
+};
+if(dojo.isSafari){
+obj="<embed type='application/x-silverlight' id='"+_66+"' width='"+_61+"' height='"+_62+" background='transparent'"+" source='#"+t.id+"'"+" windowless='true'"+" maxFramerate='60'"+" onLoad='"+_67+"'"+" onError='__dojoSilverlightError'"+" /><iframe style='visibility:hidden;height:0;width:0'/>";
+}else{
+obj="<object type='application/x-silverlight' data='data:application/x-silverlight,' id='"+_66+"' width='"+_61+"' height='"+_62+"'>"+"<param name='background' value='transparent' />"+"<param name='source' value='#"+t.id+"' />"+"<param name='windowless' value='true' />"+"<param name='maxFramerate' value='60' />"+"<param name='onLoad' value='"+_67+"' />"+"<param name='onError' value='__dojoSilverlightError' />"+"</object>";
+}
+_60.innerHTML=obj;
+var _69=dojo.byId(_66);
+if(_69.content&&_69.content.root){
+s.rawNode=_69.content.root;
+dojox.gfx.silverlight.surfaces[s.rawNode.name]=_60;
+}else{
+s.rawNode=null;
+s.isLoaded=false;
+}
+s._nodes.push(_69);
+s.width=dojox.gfx.normalizedLength(_61);
+s.height=dojox.gfx.normalizedLength(_62);
+return s;
+};
+__dojoSilverlightError=function(_6a,err){
+var t="Silverlight Error:\n"+"Code: "+err.ErrorCode+"\n"+"Type: "+err.ErrorType+"\n"+"Message: "+err.ErrorMessage+"\n";
+switch(err.ErrorType){
+case "ParserError":
+t+="XamlFile: "+err.xamlFile+"\n"+"Line: "+err.lineNumber+"\n"+"Position: "+err.charPosition+"\n";
+break;
+case "RuntimeError":
+t+="MethodName: "+err.methodName+"\n";
+if(err.lineNumber!=0){
+t+="Line: "+err.lineNumber+"\n"+"Position: "+err.charPosition+"\n";
+}
+break;
+}
+console.error(t);
+};
+dojox.gfx.silverlight.Font={_setFont:function(){
+var f=this.fontStyle,r=this.rawNode,fw=dojox.gfx.silverlight.fontweight,fo=dojox.gfx.silverlight.fonts,t=f.family.toLowerCase();
+r.fontStyle=f.style=="italic"?"Italic":"Normal";
+r.fontWeight=f.weight in fw?fw[f.weight]:f.weight;
+r.fontSize=dojox.gfx.normalizedLength(f.size);
+r.fontFamily=t in fo?fo[t]:f.family;
+if(!this._delay){
+this._delay=window.setTimeout(dojo.hitch(this,"_delayAlignment"),10);
+}
+}};
+dojox.gfx.silverlight.Container={_init:function(){
+dojox.gfx.shape.Container._init.call(this);
+},add:function(_72){
+if(this!=_72.getParent()){
+dojox.gfx.shape.Container.add.apply(this,arguments);
+this.rawNode.children.add(_72.rawNode);
+}
+return this;
+},remove:function(_73,_74){
+if(this==_73.getParent()){
+var _75=_73.rawNode.getParent();
+if(_75){
+_75.children.remove(_73.rawNode);
+}
+dojox.gfx.shape.Container.remove.apply(this,arguments);
+}
+return this;
+},clear:function(){
+this.rawNode.children.clear();
+return dojox.gfx.shape.Container.clear.apply(this,arguments);
+},_moveChildToFront:dojox.gfx.shape.Container._moveChildToFront,_moveChildToBack:dojox.gfx.shape.Container._moveChildToBack};
+dojo.mixin(dojox.gfx.shape.Creator,{createObject:function(_76,_77){
+if(!this.rawNode){
+return null;
+}
+var _78=new _76();
+var _79=this.rawNode.getHost().content.createFromXaml("<"+_76.nodeType+"/>");
+_78.setRawNode(_79);
+_78.setShape(_77);
+this.add(_78);
+return _78;
+}});
+dojo.extend(dojox.gfx.Text,dojox.gfx.silverlight.Font);
+dojo.extend(dojox.gfx.Group,dojox.gfx.silverlight.Container);
+dojo.extend(dojox.gfx.Group,dojox.gfx.shape.Creator);
+dojo.extend(dojox.gfx.Surface,dojox.gfx.silverlight.Container);
+dojo.extend(dojox.gfx.Surface,dojox.gfx.shape.Creator);
+(function(){
+var _7a=dojox.gfx.silverlight.surfaces;
+var _7b=function(s,a){
+var ev={target:s,currentTarget:s,preventDefault:function(){
+},stopPropagation:function(){
+}};
+if(a){
+try{
+ev.ctrlKey=a.ctrl;
+ev.shiftKey=a.shift;
+var p=a.getPosition(null);
+ev.x=ev.offsetX=ev.layerX=p.x;
+ev.y=ev.offsetY=ev.layerY=p.y;
+var _80=_7a[s.getHost().content.root.name];
+var t=dojo._abs(_80);
+ev.clientX=t.x+p.x;
+ev.clientY=t.y+p.y;
+}
+catch(e){
+}
+}
+return ev;
+};
+var _82=function(s,a){
+var ev={keyCode:a.platformKeyCode,ctrlKey:a.ctrl,shiftKey:a.shift};
+return ev;
+};
+var _86={onclick:{name:"MouseLeftButtonUp",fix:_7b},onmouseenter:{name:"MouseEnter",fix:_7b},onmouseleave:{name:"MouseLeave",fix:_7b},onmouseover:{name:"MouseEnter",fix:_7b},onmouseout:{name:"MouseLeave",fix:_7b},onmousedown:{name:"MouseLeftButtonDown",fix:_7b},onmouseup:{name:"MouseLeftButtonUp",fix:_7b},onmousemove:{name:"MouseMove",fix:_7b},onkeydown:{name:"KeyDown",fix:_82},onkeyup:{name:"KeyUp",fix:_82}};
+var _87={connect:function(_88,_89,_8a){
+var _8b,n=_88 in _86?_86[_88]:{name:_88,fix:function(){
+return {};
+}};
+if(arguments.length>2){
+_8b=this.getEventSource().addEventListener(n.name,function(s,a){
+dojo.hitch(_89,_8a)(n.fix(s,a));
+});
+}else{
+_8b=this.getEventSource().addEventListener(n.name,function(s,a){
+_89(n.fix(s,a));
+});
+}
+return {name:n.name,token:_8b};
+},disconnect:function(_91){
+this.getEventSource().removeEventListener(_91.name,_91.token);
+}};
+dojo.extend(dojox.gfx.Shape,_87);
+dojo.extend(dojox.gfx.Surface,_87);
+dojox.gfx.equalSources=function(a,b){
+return a&&b&&a.equals(b);
+};
+})();
+}
diff --git a/dojox/gfx/silverlight_attach.js b/dojox/gfx/silverlight_attach.js
new file mode 100644
index 0000000..b20fd2e
--- /dev/null
+++ b/dojox/gfx/silverlight_attach.js
@@ -0,0 +1,73 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+dojo.require("dojox.gfx.silverlight");
+dojo.experimental("dojox.gfx.silverlight_attach");
+(function(){
+dojox.gfx.attachNode=function(_1){
+return null;
+if(!_1){
+return null;
+}
+var s=null;
+switch(_1.tagName.toLowerCase()){
+case dojox.gfx.Rect.nodeType:
+s=new dojox.gfx.Rect(_1);
+break;
+case dojox.gfx.Ellipse.nodeType:
+if(_1.width==_1.height){
+s=new dojox.gfx.Circle(_1);
+}else{
+s=new dojox.gfx.Ellipse(_1);
+}
+break;
+case dojox.gfx.Polyline.nodeType:
+s=new dojox.gfx.Polyline(_1);
+break;
+case dojox.gfx.Path.nodeType:
+s=new dojox.gfx.Path(_1);
+break;
+case dojox.gfx.Line.nodeType:
+s=new dojox.gfx.Line(_1);
+break;
+case dojox.gfx.Image.nodeType:
+s=new dojox.gfx.Image(_1);
+break;
+case dojox.gfx.Text.nodeType:
+s=new dojox.gfx.Text(_1);
+_3(s);
+break;
+default:
+return null;
+}
+_4(s);
+if(!(s instanceof dojox.gfx.Image)){
+_5(s);
+_6(s);
+}
+_7(s);
+return s;
+};
+dojox.gfx.attachSurface=function(_8){
+return null;
+};
+var _5=function(_9){
+return null;
+};
+var _6=function(_a){
+return null;
+};
+var _7=function(_b){
+return null;
+};
+var _3=function(_c){
+return null;
+};
+var _4=function(_d){
+return null;
+};
+})();
diff --git a/dojox/gfx/svg.js b/dojox/gfx/svg.js
new file mode 100644
index 0000000..cc989ef
--- /dev/null
+++ b/dojox/gfx/svg.js
@@ -0,0 +1,446 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx.svg"]){
+dojo._hasResource["dojox.gfx.svg"]=true;
+dojo.provide("dojox.gfx.svg");
+dojo.require("dojox.gfx._base");
+dojo.require("dojox.gfx.shape");
+dojo.require("dojox.gfx.path");
+dojox.gfx.svg.xmlns={xlink:"http://www.w3.org/1999/xlink",svg:"http://www.w3.org/2000/svg"};
+dojox.gfx.svg.getRef=function(_1){
+if(!_1||_1=="none"){
+return null;
+}
+if(_1.match(/^url\(#.+\)$/)){
+return dojo.byId(_1.slice(5,-1));
+}
+if(_1.match(/^#dojoUnique\d+$/)){
+return dojo.byId(_1.slice(1));
+}
+return null;
+};
+dojox.gfx.svg.dasharray={solid:"none",shortdash:[4,1],shortdot:[1,1],shortdashdot:[4,1,1,1],shortdashdotdot:[4,1,1,1,1,1],dot:[1,3],dash:[4,3],longdash:[8,3],dashdot:[4,3,1,3],longdashdot:[8,3,1,3],longdashdotdot:[8,3,1,3,1,3]};
+dojo.extend(dojox.gfx.Shape,{setFill:function(_2){
+if(!_2){
+this.fillStyle=null;
+this.rawNode.setAttribute("fill","none");
+this.rawNode.setAttribute("fill-opacity",0);
+return this;
+}
+var f;
+var _4=function(x){
+this.setAttribute(x,f[x].toFixed(8));
+};
+if(typeof (_2)=="object"&&"type" in _2){
+switch(_2.type){
+case "linear":
+f=dojox.gfx.makeParameters(dojox.gfx.defaultLinearGradient,_2);
+var _6=this._setFillObject(f,"linearGradient");
+dojo.forEach(["x1","y1","x2","y2"],_4,_6);
+break;
+case "radial":
+f=dojox.gfx.makeParameters(dojox.gfx.defaultRadialGradient,_2);
+var _6=this._setFillObject(f,"radialGradient");
+dojo.forEach(["cx","cy","r"],_4,_6);
+break;
+case "pattern":
+f=dojox.gfx.makeParameters(dojox.gfx.defaultPattern,_2);
+var _7=this._setFillObject(f,"pattern");
+dojo.forEach(["x","y","width","height"],_4,_7);
+break;
+}
+this.fillStyle=f;
+return this;
+}
+var f=dojox.gfx.normalizeColor(_2);
+this.fillStyle=f;
+this.rawNode.setAttribute("fill",f.toCss());
+this.rawNode.setAttribute("fill-opacity",f.a);
+this.rawNode.setAttribute("fill-rule","evenodd");
+return this;
+},setStroke:function(_8){
+var rn=this.rawNode;
+if(!_8){
+this.strokeStyle=null;
+rn.setAttribute("stroke","none");
+rn.setAttribute("stroke-opacity",0);
+return this;
+}
+if(typeof _8=="string"||dojo.isArray(_8)||_8 instanceof dojo.Color){
+_8={color:_8};
+}
+var s=this.strokeStyle=dojox.gfx.makeParameters(dojox.gfx.defaultStroke,_8);
+s.color=dojox.gfx.normalizeColor(s.color);
+if(s){
+rn.setAttribute("stroke",s.color.toCss());
+rn.setAttribute("stroke-opacity",s.color.a);
+rn.setAttribute("stroke-width",s.width);
+rn.setAttribute("stroke-linecap",s.cap);
+if(typeof s.join=="number"){
+rn.setAttribute("stroke-linejoin","miter");
+rn.setAttribute("stroke-miterlimit",s.join);
+}else{
+rn.setAttribute("stroke-linejoin",s.join);
+}
+var da=s.style.toLowerCase();
+if(da in dojox.gfx.svg.dasharray){
+da=dojox.gfx.svg.dasharray[da];
+}
+if(da instanceof Array){
+da=dojo._toArray(da);
+for(var i=0;i<da.length;++i){
+da[i]*=s.width;
+}
+if(s.cap!="butt"){
+for(var i=0;i<da.length;i+=2){
+da[i]-=s.width;
+if(da[i]<1){
+da[i]=1;
+}
+}
+for(var i=1;i<da.length;i+=2){
+da[i]+=s.width;
+}
+}
+da=da.join(",");
+}
+rn.setAttribute("stroke-dasharray",da);
+rn.setAttribute("dojoGfxStrokeStyle",s.style);
+}
+return this;
+},_getParentSurface:function(){
+var _d=this.parent;
+for(;_d&&!(_d instanceof dojox.gfx.Surface);_d=_d.parent){
+}
+return _d;
+},_setFillObject:function(f,_f){
+var _10=dojox.gfx.svg.xmlns.svg;
+this.fillStyle=f;
+var _11=this._getParentSurface(),_12=_11.defNode,_13=this.rawNode.getAttribute("fill"),ref=dojox.gfx.svg.getRef(_13);
+if(ref){
+_13=ref;
+if(_13.tagName.toLowerCase()!=_f.toLowerCase()){
+var id=_13.id;
+_13.parentNode.removeChild(_13);
+_13=document.createElementNS(_10,_f);
+_13.setAttribute("id",id);
+_12.appendChild(_13);
+}else{
+while(_13.childNodes.length){
+_13.removeChild(_13.lastChild);
+}
+}
+}else{
+_13=document.createElementNS(_10,_f);
+_13.setAttribute("id",dojox.gfx._base._getUniqueId());
+_12.appendChild(_13);
+}
+if(_f=="pattern"){
+_13.setAttribute("patternUnits","userSpaceOnUse");
+var img=document.createElementNS(_10,"image");
+img.setAttribute("x",0);
+img.setAttribute("y",0);
+img.setAttribute("width",f.width.toFixed(8));
+img.setAttribute("height",f.height.toFixed(8));
+img.setAttributeNS(dojox.gfx.svg.xmlns.xlink,"href",f.src);
+_13.appendChild(img);
+}else{
+_13.setAttribute("gradientUnits","userSpaceOnUse");
+for(var i=0;i<f.colors.length;++i){
+var c=f.colors[i],t=document.createElementNS(_10,"stop"),cc=c.color=dojox.gfx.normalizeColor(c.color);
+t.setAttribute("offset",c.offset.toFixed(8));
+t.setAttribute("stop-color",cc.toCss());
+t.setAttribute("stop-opacity",cc.a);
+_13.appendChild(t);
+}
+}
+this.rawNode.setAttribute("fill","url(#"+_13.getAttribute("id")+")");
+this.rawNode.removeAttribute("fill-opacity");
+this.rawNode.setAttribute("fill-rule","evenodd");
+return _13;
+},_applyTransform:function(){
+var _1b=this.matrix;
+if(_1b){
+var tm=this.matrix;
+this.rawNode.setAttribute("transform","matrix("+tm.xx.toFixed(8)+","+tm.yx.toFixed(8)+","+tm.xy.toFixed(8)+","+tm.yy.toFixed(8)+","+tm.dx.toFixed(8)+","+tm.dy.toFixed(8)+")");
+}else{
+this.rawNode.removeAttribute("transform");
+}
+return this;
+},setRawNode:function(_1d){
+var r=this.rawNode=_1d;
+r.setAttribute("fill","none");
+r.setAttribute("fill-opacity",0);
+r.setAttribute("stroke","none");
+r.setAttribute("stroke-opacity",0);
+r.setAttribute("stroke-width",1);
+r.setAttribute("stroke-linecap","butt");
+r.setAttribute("stroke-linejoin","miter");
+r.setAttribute("stroke-miterlimit",4);
+},setShape:function(_1f){
+this.shape=dojox.gfx.makeParameters(this.shape,_1f);
+for(var i in this.shape){
+if(i!="type"){
+this.rawNode.setAttribute(i,this.shape[i]);
+}
+}
+return this;
+},_moveToFront:function(){
+this.rawNode.parentNode.appendChild(this.rawNode);
+return this;
+},_moveToBack:function(){
+this.rawNode.parentNode.insertBefore(this.rawNode,this.rawNode.parentNode.firstChild);
+return this;
+}});
+dojo.declare("dojox.gfx.Group",dojox.gfx.Shape,{constructor:function(){
+dojox.gfx.svg.Container._init.call(this);
+},setRawNode:function(_21){
+this.rawNode=_21;
+}});
+dojox.gfx.Group.nodeType="g";
+dojo.declare("dojox.gfx.Rect",dojox.gfx.shape.Rect,{setShape:function(_22){
+this.shape=dojox.gfx.makeParameters(this.shape,_22);
+this.bbox=null;
+for(var i in this.shape){
+if(i!="type"&&i!="r"){
+this.rawNode.setAttribute(i,this.shape[i]);
+}
+}
+if(this.shape.r){
+this.rawNode.setAttribute("ry",this.shape.r);
+this.rawNode.setAttribute("rx",this.shape.r);
+}
+return this;
+}});
+dojox.gfx.Rect.nodeType="rect";
+dojox.gfx.Ellipse=dojox.gfx.shape.Ellipse;
+dojox.gfx.Ellipse.nodeType="ellipse";
+dojox.gfx.Circle=dojox.gfx.shape.Circle;
+dojox.gfx.Circle.nodeType="circle";
+dojox.gfx.Line=dojox.gfx.shape.Line;
+dojox.gfx.Line.nodeType="line";
+dojo.declare("dojox.gfx.Polyline",dojox.gfx.shape.Polyline,{setShape:function(_24,_25){
+if(_24&&_24 instanceof Array){
+this.shape=dojox.gfx.makeParameters(this.shape,{points:_24});
+if(_25&&this.shape.points.length){
+this.shape.points.push(this.shape.points[0]);
+}
+}else{
+this.shape=dojox.gfx.makeParameters(this.shape,_24);
+}
+this.box=null;
+var _26=[],p=this.shape.points;
+for(var i=0;i<p.length;++i){
+if(typeof p[i]=="number"){
+_26.push(p[i].toFixed(8));
+}else{
+_26.push(p[i].x.toFixed(8));
+_26.push(p[i].y.toFixed(8));
+}
+}
+this.rawNode.setAttribute("points",_26.join(" "));
+return this;
+}});
+dojox.gfx.Polyline.nodeType="polyline";
+dojo.declare("dojox.gfx.Image",dojox.gfx.shape.Image,{setShape:function(_29){
+this.shape=dojox.gfx.makeParameters(this.shape,_29);
+this.bbox=null;
+var _2a=this.rawNode;
+for(var i in this.shape){
+if(i!="type"&&i!="src"){
+_2a.setAttribute(i,this.shape[i]);
+}
+}
+_2a.setAttributeNS(dojox.gfx.svg.xmlns.xlink,"href",this.shape.src);
+return this;
+}});
+dojox.gfx.Image.nodeType="image";
+dojo.declare("dojox.gfx.Text",dojox.gfx.shape.Text,{setShape:function(_2c){
+this.shape=dojox.gfx.makeParameters(this.shape,_2c);
+this.bbox=null;
+var r=this.rawNode,s=this.shape;
+r.setAttribute("x",s.x);
+r.setAttribute("y",s.y);
+r.setAttribute("text-anchor",s.align);
+r.setAttribute("text-decoration",s.decoration);
+r.setAttribute("rotate",s.rotated?90:0);
+r.setAttribute("kerning",s.kerning?"auto":0);
+r.setAttribute("text-rendering","optimizeLegibility");
+r.textContent=s.text;
+return this;
+},getTextWidth:function(){
+var _2f=this.rawNode,_30=_2f.parentNode,_31=_2f.cloneNode(true);
+_31.style.visibility="hidden";
+var _32=0,_33=_31.firstChild.nodeValue;
+_30.appendChild(_31);
+if(_33!=""){
+while(!_32){
+_32=parseInt(_31.getBBox().width);
+}
+}
+_30.removeChild(_31);
+return _32;
+}});
+dojox.gfx.Text.nodeType="text";
+dojo.declare("dojox.gfx.Path",dojox.gfx.path.Path,{_updateWithSegment:function(_34){
+dojox.gfx.Path.superclass._updateWithSegment.apply(this,arguments);
+if(typeof (this.shape.path)=="string"){
+this.rawNode.setAttribute("d",this.shape.path);
+}
+},setShape:function(_35){
+dojox.gfx.Path.superclass.setShape.apply(this,arguments);
+this.rawNode.setAttribute("d",this.shape.path);
+return this;
+}});
+dojox.gfx.Path.nodeType="path";
+dojo.declare("dojox.gfx.TextPath",dojox.gfx.path.TextPath,{_updateWithSegment:function(_36){
+dojox.gfx.Path.superclass._updateWithSegment.apply(this,arguments);
+this._setTextPath();
+},setShape:function(_37){
+dojox.gfx.Path.superclass.setShape.apply(this,arguments);
+this._setTextPath();
+return this;
+},_setTextPath:function(){
+if(typeof this.shape.path!="string"){
+return;
+}
+var r=this.rawNode;
+if(!r.firstChild){
+var tp=document.createElementNS(dojox.gfx.svg.xmlns.svg,"textPath"),tx=document.createTextNode("");
+tp.appendChild(tx);
+r.appendChild(tp);
+}
+var ref=r.firstChild.getAttributeNS(dojox.gfx.svg.xmlns.xlink,"href"),_3c=ref&&dojox.gfx.svg.getRef(ref);
+if(!_3c){
+var _3d=this._getParentSurface();
+if(_3d){
+var _3e=_3d.defNode;
+_3c=document.createElementNS(dojox.gfx.svg.xmlns.svg,"path");
+var id=dojox.gfx._base._getUniqueId();
+_3c.setAttribute("id",id);
+_3e.appendChild(_3c);
+r.firstChild.setAttributeNS(dojox.gfx.svg.xmlns.xlink,"href","#"+id);
+}
+}
+if(_3c){
+_3c.setAttribute("d",this.shape.path);
+}
+},_setText:function(){
+var r=this.rawNode;
+if(!r.firstChild){
+var tp=document.createElementNS(dojox.gfx.svg.xmlns.svg,"textPath"),tx=document.createTextNode("");
+tp.appendChild(tx);
+r.appendChild(tp);
+}
+r=r.firstChild;
+var t=this.text;
+r.setAttribute("alignment-baseline","middle");
+switch(t.align){
+case "middle":
+r.setAttribute("text-anchor","middle");
+r.setAttribute("startOffset","50%");
+break;
+case "end":
+r.setAttribute("text-anchor","end");
+r.setAttribute("startOffset","100%");
+break;
+default:
+r.setAttribute("text-anchor","start");
+r.setAttribute("startOffset","0%");
+break;
+}
+r.setAttribute("baseline-shift","0.5ex");
+r.setAttribute("text-decoration",t.decoration);
+r.setAttribute("rotate",t.rotated?90:0);
+r.setAttribute("kerning",t.kerning?"auto":0);
+r.firstChild.data=t.text;
+}});
+dojox.gfx.TextPath.nodeType="text";
+dojo.declare("dojox.gfx.Surface",dojox.gfx.shape.Surface,{constructor:function(){
+dojox.gfx.svg.Container._init.call(this);
+},destroy:function(){
+this.defNode=null;
+this.inherited(arguments);
+},setDimensions:function(_44,_45){
+if(!this.rawNode){
+return this;
+}
+this.rawNode.setAttribute("width",_44);
+this.rawNode.setAttribute("height",_45);
+return this;
+},getDimensions:function(){
+return this.rawNode?{width:this.rawNode.getAttribute("width"),height:this.rawNode.getAttribute("height")}:null;
+}});
+dojox.gfx.createSurface=function(_46,_47,_48){
+var s=new dojox.gfx.Surface();
+s.rawNode=document.createElementNS(dojox.gfx.svg.xmlns.svg,"svg");
+s.rawNode.setAttribute("width",_47);
+s.rawNode.setAttribute("height",_48);
+var _4a=document.createElementNS(dojox.gfx.svg.xmlns.svg,"defs");
+s.rawNode.appendChild(_4a);
+s.defNode=_4a;
+s._parent=dojo.byId(_46);
+s._parent.appendChild(s.rawNode);
+return s;
+};
+dojox.gfx.svg.Font={_setFont:function(){
+var f=this.fontStyle;
+this.rawNode.setAttribute("font-style",f.style);
+this.rawNode.setAttribute("font-variant",f.variant);
+this.rawNode.setAttribute("font-weight",f.weight);
+this.rawNode.setAttribute("font-size",f.size);
+this.rawNode.setAttribute("font-family",f.family);
+}};
+dojox.gfx.svg.Container={_init:function(){
+dojox.gfx.shape.Container._init.call(this);
+},add:function(_4c){
+if(this!=_4c.getParent()){
+this.rawNode.appendChild(_4c.rawNode);
+dojox.gfx.shape.Container.add.apply(this,arguments);
+}
+return this;
+},remove:function(_4d,_4e){
+if(this==_4d.getParent()){
+if(this.rawNode==_4d.rawNode.parentNode){
+this.rawNode.removeChild(_4d.rawNode);
+}
+dojox.gfx.shape.Container.remove.apply(this,arguments);
+}
+return this;
+},clear:function(){
+var r=this.rawNode;
+while(r.lastChild){
+r.removeChild(r.lastChild);
+}
+var d=this.defNode;
+if(d){
+while(d.lastChild){
+d.removeChild(d.lastChild);
+}
+r.appendChild(d);
+}
+return dojox.gfx.shape.Container.clear.apply(this,arguments);
+},_moveChildToFront:dojox.gfx.shape.Container._moveChildToFront,_moveChildToBack:dojox.gfx.shape.Container._moveChildToBack};
+dojo.mixin(dojox.gfx.shape.Creator,{createObject:function(_51,_52){
+if(!this.rawNode){
+return null;
+}
+var _53=new _51(),_54=document.createElementNS(dojox.gfx.svg.xmlns.svg,_51.nodeType);
+_53.setRawNode(_54);
+this.rawNode.appendChild(_54);
+_53.setShape(_52);
+this.add(_53);
+return _53;
+}});
+dojo.extend(dojox.gfx.Text,dojox.gfx.svg.Font);
+dojo.extend(dojox.gfx.TextPath,dojox.gfx.svg.Font);
+dojo.extend(dojox.gfx.Group,dojox.gfx.svg.Container);
+dojo.extend(dojox.gfx.Group,dojox.gfx.shape.Creator);
+dojo.extend(dojox.gfx.Surface,dojox.gfx.svg.Container);
+dojo.extend(dojox.gfx.Surface,dojox.gfx.shape.Creator);
+}
diff --git a/dojox/gfx/svg_attach.js b/dojox/gfx/svg_attach.js
new file mode 100644
index 0000000..bd06745
--- /dev/null
+++ b/dojox/gfx/svg_attach.js
@@ -0,0 +1,191 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+dojo.require("dojox.gfx.svg");
+dojo.experimental("dojox.gfx.svg_attach");
+(function(){
+dojox.gfx.attachNode=function(_1){
+if(!_1){
+return null;
+}
+var s=null;
+switch(_1.tagName.toLowerCase()){
+case dojox.gfx.Rect.nodeType:
+s=new dojox.gfx.Rect(_1);
+_3(s);
+break;
+case dojox.gfx.Ellipse.nodeType:
+s=new dojox.gfx.Ellipse(_1);
+_4(s,dojox.gfx.defaultEllipse);
+break;
+case dojox.gfx.Polyline.nodeType:
+s=new dojox.gfx.Polyline(_1);
+_4(s,dojox.gfx.defaultPolyline);
+break;
+case dojox.gfx.Path.nodeType:
+s=new dojox.gfx.Path(_1);
+_4(s,dojox.gfx.defaultPath);
+break;
+case dojox.gfx.Circle.nodeType:
+s=new dojox.gfx.Circle(_1);
+_4(s,dojox.gfx.defaultCircle);
+break;
+case dojox.gfx.Line.nodeType:
+s=new dojox.gfx.Line(_1);
+_4(s,dojox.gfx.defaultLine);
+break;
+case dojox.gfx.Image.nodeType:
+s=new dojox.gfx.Image(_1);
+_4(s,dojox.gfx.defaultImage);
+break;
+case dojox.gfx.Text.nodeType:
+var t=_1.getElementsByTagName("textPath");
+if(t&&t.length){
+s=new dojox.gfx.TextPath(_1);
+_4(s,dojox.gfx.defaultPath);
+_6(s);
+}else{
+s=new dojox.gfx.Text(_1);
+_7(s);
+}
+_8(s);
+break;
+default:
+return null;
+}
+if(!(s instanceof dojox.gfx.Image)){
+_9(s);
+_a(s);
+}
+_b(s);
+return s;
+};
+dojox.gfx.attachSurface=function(_c){
+var s=new dojox.gfx.Surface();
+s.rawNode=_c;
+var _e=_c.getElementsByTagName("defs");
+if(_e.length==0){
+return null;
+}
+s.defNode=_e[0];
+return s;
+};
+var _9=function(_f){
+var _10=_f.rawNode.getAttribute("fill");
+if(_10=="none"){
+_f.fillStyle=null;
+return;
+}
+var _11=null,_12=dojox.gfx.svg.getRef(_10);
+if(_12){
+switch(_12.tagName.toLowerCase()){
+case "lineargradient":
+_11=_13(dojox.gfx.defaultLinearGradient,_12);
+dojo.forEach(["x1","y1","x2","y2"],function(x){
+_11[x]=_12.getAttribute(x);
+});
+break;
+case "radialgradient":
+_11=_13(dojox.gfx.defaultRadialGradient,_12);
+dojo.forEach(["cx","cy","r"],function(x){
+_11[x]=_12.getAttribute(x);
+});
+_11.cx=_12.getAttribute("cx");
+_11.cy=_12.getAttribute("cy");
+_11.r=_12.getAttribute("r");
+break;
+case "pattern":
+_11=dojo.lang.shallowCopy(dojox.gfx.defaultPattern,true);
+dojo.forEach(["x","y","width","height"],function(x){
+_11[x]=_12.getAttribute(x);
+});
+_11.src=_12.firstChild.getAttributeNS(dojox.gfx.svg.xmlns.xlink,"href");
+break;
+}
+}else{
+_11=new dojo.Color(_10);
+var _17=_f.rawNode.getAttribute("fill-opacity");
+if(_17!=null){
+_11.a=_17;
+}
+}
+_f.fillStyle=_11;
+};
+var _13=function(_18,_19){
+var _1a=dojo.clone(_18);
+_1a.colors=[];
+for(var i=0;i<_19.childNodes.length;++i){
+_1a.colors.push({offset:_19.childNodes[i].getAttribute("offset"),color:new dojo.Color(_19.childNodes[i].getAttribute("stop-color"))});
+}
+return _1a;
+};
+var _a=function(_1c){
+var _1d=_1c.rawNode,_1e=_1d.getAttribute("stroke");
+if(_1e==null||_1e=="none"){
+_1c.strokeStyle=null;
+return;
+}
+var _1f=_1c.strokeStyle=dojo.clone(dojox.gfx.defaultStroke);
+var _20=new dojo.Color(_1e);
+if(_20){
+_1f.color=_20;
+_1f.color.a=_1d.getAttribute("stroke-opacity");
+_1f.width=_1d.getAttribute("stroke-width");
+_1f.cap=_1d.getAttribute("stroke-linecap");
+_1f.join=_1d.getAttribute("stroke-linejoin");
+if(_1f.join=="miter"){
+_1f.join=_1d.getAttribute("stroke-miterlimit");
+}
+_1f.style=_1d.getAttribute("dojoGfxStrokeStyle");
+}
+};
+var _b=function(_21){
+var _22=_21.rawNode.getAttribute("transform");
+if(_22.match(/^matrix\(.+\)$/)){
+var t=_22.slice(7,-1).split(",");
+_21.matrix=dojox.gfx.matrix.normalize({xx:parseFloat(t[0]),xy:parseFloat(t[2]),yx:parseFloat(t[1]),yy:parseFloat(t[3]),dx:parseFloat(t[4]),dy:parseFloat(t[5])});
+}else{
+_21.matrix=null;
+}
+};
+var _8=function(_24){
+var _25=_24.fontStyle=dojo.clone(dojox.gfx.defaultFont),r=_24.rawNode;
+_25.style=r.getAttribute("font-style");
+_25.variant=r.getAttribute("font-variant");
+_25.weight=r.getAttribute("font-weight");
+_25.size=r.getAttribute("font-size");
+_25.family=r.getAttribute("font-family");
+};
+var _4=function(_27,def){
+var _29=_27.shape=dojo.clone(def),r=_27.rawNode;
+for(var i in _29){
+_29[i]=r.getAttribute(i);
+}
+};
+var _3=function(_2c){
+_4(_2c,dojox.gfx.defaultRect);
+_2c.shape.r=Math.min(_2c.rawNode.getAttribute("rx"),_2c.rawNode.getAttribute("ry"));
+};
+var _7=function(_2d){
+var _2e=_2d.shape=dojo.clone(dojox.gfx.defaultText),r=_2d.rawNode;
+_2e.x=r.getAttribute("x");
+_2e.y=r.getAttribute("y");
+_2e.align=r.getAttribute("text-anchor");
+_2e.decoration=r.getAttribute("text-decoration");
+_2e.rotated=parseFloat(r.getAttribute("rotate"))!=0;
+_2e.kerning=r.getAttribute("kerning")=="auto";
+_2e.text=r.firstChild.nodeValue;
+};
+var _6=function(_30){
+var _31=_30.shape=dojo.clone(dojox.gfx.defaultTextPath),r=_30.rawNode;
+_31.align=r.getAttribute("text-anchor");
+_31.decoration=r.getAttribute("text-decoration");
+_31.rotated=parseFloat(r.getAttribute("rotate"))!=0;
+_31.kerning=r.getAttribute("kerning")=="auto";
+_31.text=r.firstChild.nodeValue;
+};
+})();
diff --git a/dojox/gfx/utils.js b/dojox/gfx/utils.js
new file mode 100644
index 0000000..62d140e
--- /dev/null
+++ b/dojox/gfx/utils.js
@@ -0,0 +1,84 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx.utils"]){
+dojo._hasResource["dojox.gfx.utils"]=true;
+dojo.provide("dojox.gfx.utils");
+dojo.require("dojox.gfx");
+(function(){
+var d=dojo,g=dojox.gfx,gu=g.utils;
+dojo.mixin(gu,{forEach:function(_4,f,o){
+o=o||d.global;
+f.call(o,_4);
+if(_4 instanceof g.Surface||_4 instanceof g.Group){
+d.forEach(_4.children,function(_7){
+gu.forEach(_7,f,o);
+});
+}
+},serialize:function(_8){
+var t={},v,_b=_8 instanceof g.Surface;
+if(_b||_8 instanceof g.Group){
+t.children=d.map(_8.children,gu.serialize);
+if(_b){
+return t.children;
+}
+}else{
+t.shape=_8.getShape();
+}
+if(_8.getTransform){
+v=_8.getTransform();
+if(v){
+t.transform=v;
+}
+}
+if(_8.getStroke){
+v=_8.getStroke();
+if(v){
+t.stroke=v;
+}
+}
+if(_8.getFill){
+v=_8.getFill();
+if(v){
+t.fill=v;
+}
+}
+if(_8.getFont){
+v=_8.getFont();
+if(v){
+t.font=v;
+}
+}
+return t;
+},toJson:function(_c,_d){
+return d.toJson(gu.serialize(_c),_d);
+},deserialize:function(_e,_f){
+if(_f instanceof Array){
+return d.map(_f,d.hitch(null,gu.deserialize,_e));
+}
+var _10=("shape" in _f)?_e.createShape(_f.shape):_e.createGroup();
+if("transform" in _f){
+_10.setTransform(_f.transform);
+}
+if("stroke" in _f){
+_10.setStroke(_f.stroke);
+}
+if("fill" in _f){
+_10.setFill(_f.fill);
+}
+if("font" in _f){
+_10.setFont(_f.font);
+}
+if("children" in _f){
+d.forEach(_f.children,d.hitch(null,gu.deserialize,_10));
+}
+return _10;
+},fromJson:function(_11,_12){
+return gu.deserialize(_11,d.fromJson(_12));
+}});
+})();
+}
diff --git a/dojox/gfx/vml.js b/dojox/gfx/vml.js
new file mode 100644
index 0000000..f787a1f
--- /dev/null
+++ b/dojox/gfx/vml.js
@@ -0,0 +1,900 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx.vml"]){
+dojo._hasResource["dojox.gfx.vml"]=true;
+dojo.provide("dojox.gfx.vml");
+dojo.require("dojox.gfx._base");
+dojo.require("dojox.gfx.shape");
+dojo.require("dojox.gfx.path");
+dojo.require("dojox.gfx.arc");
+(function(){
+var g=dojox.gfx,m=g.matrix,_3=g.vml,sh=g.shape;
+_3.xmlns="urn:schemas-microsoft-com:vml";
+_3.text_alignment={start:"left",middle:"center",end:"right"};
+_3._parseFloat=function(_5){
+return _5.match(/^\d+f$/i)?parseInt(_5)/65536:parseFloat(_5);
+};
+_3._bool={"t":1,"true":1};
+dojo.extend(g.Shape,{setFill:function(_6){
+if(!_6){
+this.fillStyle=null;
+this.rawNode.filled="f";
+return this;
+}
+var i,f,fo,a,s;
+if(typeof _6=="object"&&"type" in _6){
+switch(_6.type){
+case "linear":
+var _c=this._getRealMatrix();
+s=[];
+f=g.makeParameters(g.defaultLinearGradient,_6);
+a=f.colors;
+this.fillStyle=f;
+dojo.forEach(a,function(v,i,a){
+a[i].color=g.normalizeColor(v.color);
+});
+if(a[0].offset>0){
+s.push("0 "+a[0].color.toHex());
+}
+for(i=0;i<a.length;++i){
+s.push(a[i].offset.toFixed(8)+" "+a[i].color.toHex());
+}
+i=a.length-1;
+if(a[i].offset<1){
+s.push("1 "+a[i].color.toHex());
+}
+fo=this.rawNode.fill;
+fo.colors.value=s.join(";");
+fo.method="sigma";
+fo.type="gradient";
+var fc1=_c?m.multiplyPoint(_c,f.x1,f.y1):{x:f.x1,y:f.y1},fc2=_c?m.multiplyPoint(_c,f.x2,f.y2):{x:f.x2,y:f.y2};
+fo.angle=(m._radToDeg(Math.atan2(fc2.x-fc1.x,fc2.y-fc1.y))+180)%360;
+fo.on=true;
+break;
+case "radial":
+f=g.makeParameters(g.defaultRadialGradient,_6);
+this.fillStyle=f;
+var l=parseFloat(this.rawNode.style.left),t=parseFloat(this.rawNode.style.top),w=parseFloat(this.rawNode.style.width),h=parseFloat(this.rawNode.style.height),c=isNaN(w)?1:2*f.r/w;
+a=[];
+if(f.colors[0].offset>0){
+a.push({offset:1,color:g.normalizeColor(f.colors[0].color)});
+}
+dojo.forEach(f.colors,function(v,i){
+a.push({offset:1-v.offset*c,color:g.normalizeColor(v.color)});
+});
+i=a.length-1;
+while(i>=0&&a[i].offset<0){
+--i;
+}
+if(i<a.length-1){
+var q=a[i],p=a[i+1];
+p.color=dojo.blendColors(q.color,p.color,q.offset/(q.offset-p.offset));
+p.offset=0;
+while(a.length-i>2){
+a.pop();
+}
+}
+i=a.length-1,s=[];
+if(a[i].offset>0){
+s.push("0 "+a[i].color.toHex());
+}
+for(;i>=0;--i){
+s.push(a[i].offset.toFixed(8)+" "+a[i].color.toHex());
+}
+fo=this.rawNode.fill;
+fo.colors.value=s.join(";");
+fo.method="sigma";
+fo.type="gradientradial";
+if(isNaN(w)||isNaN(h)||isNaN(l)||isNaN(t)){
+fo.focusposition="0.5 0.5";
+}else{
+fo.focusposition=((f.cx-l)/w).toFixed(8)+" "+((f.cy-t)/h).toFixed(8);
+}
+fo.focussize="0 0";
+fo.on=true;
+break;
+case "pattern":
+f=g.makeParameters(g.defaultPattern,_6);
+this.fillStyle=f;
+fo=this.rawNode.fill;
+fo.type="tile";
+fo.src=f.src;
+if(f.width&&f.height){
+fo.size.x=g.px2pt(f.width);
+fo.size.y=g.px2pt(f.height);
+}
+fo.alignShape="f";
+fo.position.x=0;
+fo.position.y=0;
+fo.origin.x=f.width?f.x/f.width:0;
+fo.origin.y=f.height?f.y/f.height:0;
+fo.on=true;
+break;
+}
+this.rawNode.fill.opacity=1;
+return this;
+}
+this.fillStyle=g.normalizeColor(_6);
+fo=this.rawNode.fill;
+if(!fo){
+fo=this.rawNode.ownerDocument.createElement("v:fill");
+}
+fo.method="any";
+fo.type="solid";
+fo.opacity=this.fillStyle.a;
+this.rawNode.fillcolor=this.fillStyle.toHex();
+this.rawNode.filled=true;
+return this;
+},setStroke:function(_1b){
+if(!_1b){
+this.strokeStyle=null;
+this.rawNode.stroked="f";
+return this;
+}
+if(typeof _1b=="string"||dojo.isArray(_1b)||_1b instanceof dojo.Color){
+_1b={color:_1b};
+}
+var s=this.strokeStyle=g.makeParameters(g.defaultStroke,_1b);
+s.color=g.normalizeColor(s.color);
+var rn=this.rawNode;
+rn.stroked=true;
+rn.strokecolor=s.color.toCss();
+rn.strokeweight=s.width+"px";
+if(rn.stroke){
+rn.stroke.opacity=s.color.a;
+rn.stroke.endcap=this._translate(this._capMap,s.cap);
+if(typeof s.join=="number"){
+rn.stroke.joinstyle="miter";
+rn.stroke.miterlimit=s.join;
+}else{
+rn.stroke.joinstyle=s.join;
+}
+rn.stroke.dashstyle=s.style=="none"?"Solid":s.style;
+}
+return this;
+},_capMap:{butt:"flat"},_capMapReversed:{flat:"butt"},_translate:function(_1e,_1f){
+return (_1f in _1e)?_1e[_1f]:_1f;
+},_applyTransform:function(){
+if(this.fillStyle&&this.fillStyle.type=="linear"){
+this.setFill(this.fillStyle);
+}
+var _20=this._getRealMatrix();
+if(!_20){
+return this;
+}
+var _21=this.rawNode.skew;
+if(typeof _21=="undefined"){
+for(var i=0;i<this.rawNode.childNodes.length;++i){
+if(this.rawNode.childNodes[i].tagName=="skew"){
+_21=this.rawNode.childNodes[i];
+break;
+}
+}
+}
+if(_21){
+_21.on="f";
+var mt=_20.xx.toFixed(8)+" "+_20.xy.toFixed(8)+" "+_20.yx.toFixed(8)+" "+_20.yy.toFixed(8)+" 0 0",_24=Math.floor(_20.dx).toFixed()+"px "+Math.floor(_20.dy).toFixed()+"px",s=this.rawNode.style,l=parseFloat(s.left),t=parseFloat(s.top),w=parseFloat(s.width),h=parseFloat(s.height);
+if(isNaN(l)){
+l=0;
+}
+if(isNaN(t)){
+t=0;
+}
+if(isNaN(w)){
+w=1;
+}
+if(isNaN(h)){
+h=1;
+}
+var _2a=(-l/w-0.5).toFixed(8)+" "+(-t/h-0.5).toFixed(8);
+_21.matrix=mt;
+_21.origin=_2a;
+_21.offset=_24;
+_21.on=true;
+}
+return this;
+},_setDimensions:function(_2b,_2c){
+return this;
+},setRawNode:function(_2d){
+_2d.stroked="f";
+_2d.filled="f";
+this.rawNode=_2d;
+},_moveToFront:function(){
+this.rawNode.parentNode.appendChild(this.rawNode);
+return this;
+},_moveToBack:function(){
+var r=this.rawNode,p=r.parentNode,n=p.firstChild;
+p.insertBefore(r,n);
+if(n.tagName=="rect"){
+n.swapNode(r);
+}
+return this;
+},_getRealMatrix:function(){
+return this.parentMatrix?new g.Matrix2D([this.parentMatrix,this.matrix]):this.matrix;
+}});
+dojo.declare("dojox.gfx.Group",dojox.gfx.Shape,{constructor:function(){
+_3.Container._init.call(this);
+},_applyTransform:function(){
+var _31=this._getRealMatrix();
+for(var i=0;i<this.children.length;++i){
+this.children[i]._updateParentMatrix(_31);
+}
+return this;
+},_setDimensions:function(_33,_34){
+var r=this.rawNode,rs=r.style,bs=this.bgNode.style;
+rs.width=_33;
+rs.height=_34;
+r.coordsize=_33+" "+_34;
+bs.width=_33;
+bs.height=_34;
+for(var i=0;i<this.children.length;++i){
+this.children[i]._setDimensions(_33,_34);
+}
+return this;
+}});
+g.Group.nodeType="group";
+dojo.declare("dojox.gfx.Rect",dojox.gfx.shape.Rect,{setShape:function(_39){
+var _3a=this.shape=g.makeParameters(this.shape,_39);
+this.bbox=null;
+var r=Math.min(1,(_3a.r/Math.min(parseFloat(_3a.width),parseFloat(_3a.height)))).toFixed(8);
+var _3c=this.rawNode.parentNode,_3d=null;
+if(_3c){
+if(_3c.lastChild!==this.rawNode){
+for(var i=0;i<_3c.childNodes.length;++i){
+if(_3c.childNodes[i]===this.rawNode){
+_3d=_3c.childNodes[i+1];
+break;
+}
+}
+}
+_3c.removeChild(this.rawNode);
+}
+if(dojo.isIE>7){
+var _3f=this.rawNode.ownerDocument.createElement("v:roundrect");
+_3f.arcsize=r;
+_3f.style.display="inline-block";
+this.rawNode=_3f;
+}else{
+this.rawNode.arcsize=r;
+}
+if(_3c){
+if(_3d){
+_3c.insertBefore(this.rawNode,_3d);
+}else{
+_3c.appendChild(this.rawNode);
+}
+}
+var _40=this.rawNode.style;
+_40.left=_3a.x.toFixed();
+_40.top=_3a.y.toFixed();
+_40.width=(typeof _3a.width=="string"&&_3a.width.indexOf("%")>=0)?_3a.width:_3a.width.toFixed();
+_40.height=(typeof _3a.width=="string"&&_3a.height.indexOf("%")>=0)?_3a.height:_3a.height.toFixed();
+return this.setTransform(this.matrix).setFill(this.fillStyle).setStroke(this.strokeStyle);
+}});
+g.Rect.nodeType="roundrect";
+dojo.declare("dojox.gfx.Ellipse",dojox.gfx.shape.Ellipse,{setShape:function(_41){
+var _42=this.shape=g.makeParameters(this.shape,_41);
+this.bbox=null;
+var _43=this.rawNode.style;
+_43.left=(_42.cx-_42.rx).toFixed();
+_43.top=(_42.cy-_42.ry).toFixed();
+_43.width=(_42.rx*2).toFixed();
+_43.height=(_42.ry*2).toFixed();
+return this.setTransform(this.matrix);
+}});
+g.Ellipse.nodeType="oval";
+dojo.declare("dojox.gfx.Circle",dojox.gfx.shape.Circle,{setShape:function(_44){
+var _45=this.shape=g.makeParameters(this.shape,_44);
+this.bbox=null;
+var _46=this.rawNode.style;
+_46.left=(_45.cx-_45.r).toFixed();
+_46.top=(_45.cy-_45.r).toFixed();
+_46.width=(_45.r*2).toFixed();
+_46.height=(_45.r*2).toFixed();
+return this;
+}});
+g.Circle.nodeType="oval";
+dojo.declare("dojox.gfx.Line",dojox.gfx.shape.Line,{constructor:function(_47){
+if(_47){
+_47.setAttribute("dojoGfxType","line");
+}
+},setShape:function(_48){
+var _49=this.shape=g.makeParameters(this.shape,_48);
+this.bbox=null;
+this.rawNode.path.v="m"+_49.x1.toFixed()+" "+_49.y1.toFixed()+"l"+_49.x2.toFixed()+" "+_49.y2.toFixed()+"e";
+return this.setTransform(this.matrix);
+}});
+g.Line.nodeType="shape";
+dojo.declare("dojox.gfx.Polyline",dojox.gfx.shape.Polyline,{constructor:function(_4a){
+if(_4a){
+_4a.setAttribute("dojoGfxType","polyline");
+}
+},setShape:function(_4b,_4c){
+if(_4b&&_4b instanceof Array){
+this.shape=g.makeParameters(this.shape,{points:_4b});
+if(_4c&&this.shape.points.length){
+this.shape.points.push(this.shape.points[0]);
+}
+}else{
+this.shape=g.makeParameters(this.shape,_4b);
+}
+this.bbox=null;
+var _4d=[],p=this.shape.points;
+if(p.length>0){
+_4d.push("m");
+var k=1;
+if(typeof p[0]=="number"){
+_4d.push(p[0].toFixed());
+_4d.push(p[1].toFixed());
+k=2;
+}else{
+_4d.push(p[0].x.toFixed());
+_4d.push(p[0].y.toFixed());
+}
+if(p.length>k){
+_4d.push("l");
+for(var i=k;i<p.length;++i){
+if(typeof p[i]=="number"){
+_4d.push(p[i].toFixed());
+}else{
+_4d.push(p[i].x.toFixed());
+_4d.push(p[i].y.toFixed());
+}
+}
+}
+}
+_4d.push("e");
+this.rawNode.path.v=_4d.join(" ");
+return this.setTransform(this.matrix);
+}});
+g.Polyline.nodeType="shape";
+dojo.declare("dojox.gfx.Image",dojox.gfx.shape.Image,{setShape:function(_51){
+var _52=this.shape=g.makeParameters(this.shape,_51);
+this.bbox=null;
+this.rawNode.firstChild.src=_52.src;
+return this.setTransform(this.matrix);
+},_applyTransform:function(){
+var _53=this._getRealMatrix(),_54=this.rawNode,s=_54.style,_56=this.shape;
+if(_53){
+_53=m.multiply(_53,{dx:_56.x,dy:_56.y});
+}else{
+_53=m.normalize({dx:_56.x,dy:_56.y});
+}
+if(_53.xy==0&&_53.yx==0&&_53.xx>0&&_53.yy>0){
+s.filter="";
+s.width=Math.floor(_53.xx*_56.width);
+s.height=Math.floor(_53.yy*_56.height);
+s.left=Math.floor(_53.dx);
+s.top=Math.floor(_53.dy);
+}else{
+var ps=_54.parentNode.style;
+s.left="0px";
+s.top="0px";
+s.width=ps.width;
+s.height=ps.height;
+_53=m.multiply(_53,{xx:_56.width/parseInt(s.width),yy:_56.height/parseInt(s.height)});
+var f=_54.filters["DXImageTransform.Microsoft.Matrix"];
+if(f){
+f.M11=_53.xx;
+f.M12=_53.xy;
+f.M21=_53.yx;
+f.M22=_53.yy;
+f.Dx=_53.dx;
+f.Dy=_53.dy;
+}else{
+s.filter="progid:DXImageTransform.Microsoft.Matrix(M11="+_53.xx+", M12="+_53.xy+", M21="+_53.yx+", M22="+_53.yy+", Dx="+_53.dx+", Dy="+_53.dy+")";
+}
+}
+return this;
+},_setDimensions:function(_59,_5a){
+var r=this.rawNode,f=r.filters["DXImageTransform.Microsoft.Matrix"];
+if(f){
+var s=r.style;
+s.width=_59;
+s.height=_5a;
+return this._applyTransform();
+}
+return this;
+}});
+g.Image.nodeType="rect";
+dojo.declare("dojox.gfx.Text",dojox.gfx.shape.Text,{constructor:function(_5e){
+if(_5e){
+_5e.setAttribute("dojoGfxType","text");
+}
+this.fontStyle=null;
+},_alignment:{start:"left",middle:"center",end:"right"},setShape:function(_5f){
+this.shape=g.makeParameters(this.shape,_5f);
+this.bbox=null;
+var r=this.rawNode,s=this.shape,x=s.x,y=s.y.toFixed(),_64;
+switch(s.align){
+case "middle":
+x-=5;
+break;
+case "end":
+x-=10;
+break;
+}
+_64="m"+x.toFixed()+","+y+"l"+(x+10).toFixed()+","+y+"e";
+var p=null,t=null,c=r.childNodes;
+for(var i=0;i<c.length;++i){
+var tag=c[i].tagName;
+if(tag=="path"){
+p=c[i];
+if(t){
+break;
+}
+}else{
+if(tag=="textpath"){
+t=c[i];
+if(p){
+break;
+}
+}
+}
+}
+if(!p){
+p=r.ownerDocument.createElement("v:path");
+r.appendChild(p);
+}
+if(!t){
+t=r.ownerDocument.createElement("v:textpath");
+r.appendChild(t);
+}
+p.v=_64;
+p.textPathOk=true;
+t.on=true;
+var a=_3.text_alignment[s.align];
+t.style["v-text-align"]=a?a:"left";
+t.style["text-decoration"]=s.decoration;
+t.style["v-rotate-letters"]=s.rotated;
+t.style["v-text-kern"]=s.kerning;
+t.string=s.text;
+return this.setTransform(this.matrix);
+},_setFont:function(){
+var f=this.fontStyle,c=this.rawNode.childNodes;
+for(var i=0;i<c.length;++i){
+if(c[i].tagName=="textpath"){
+c[i].style.font=g.makeFontString(f);
+break;
+}
+}
+this.setTransform(this.matrix);
+},_getRealMatrix:function(){
+var _6e=g.Shape.prototype._getRealMatrix.call(this);
+if(_6e){
+_6e=m.multiply(_6e,{dy:-g.normalizedLength(this.fontStyle?this.fontStyle.size:"10pt")*0.35});
+}
+return _6e;
+},getTextWidth:function(){
+var _6f=this.rawNode,_70=_6f.style.display;
+_6f.style.display="inline";
+var _71=g.pt2px(parseFloat(_6f.currentStyle.width));
+_6f.style.display=_70;
+return _71;
+}});
+g.Text.nodeType="shape";
+g.path._calcArc=function(_72){
+var _73=Math.cos(_72),_74=Math.sin(_72),p2={x:_73+(4/3)*(1-_73),y:_74-(4/3)*_73*(1-_73)/_74};
+return {s:{x:_73,y:-_74},c1:{x:p2.x,y:-p2.y},c2:p2,e:{x:_73,y:_74}};
+};
+dojo.declare("dojox.gfx.Path",dojox.gfx.path.Path,{constructor:function(_76){
+if(_76&&!_76.getAttribute("dojoGfxType")){
+_76.setAttribute("dojoGfxType","path");
+}
+this.vmlPath="";
+this.lastControl={};
+},_updateWithSegment:function(_77){
+var _78=dojo.clone(this.last);
+g.Path.superclass._updateWithSegment.apply(this,arguments);
+var _79=this[this.renderers[_77.action]](_77,_78);
+if(typeof this.vmlPath=="string"){
+this.vmlPath+=_79.join("");
+this.rawNode.path.v=this.vmlPath+" r0,0 e";
+}else{
+Array.prototype.push.apply(this.vmlPath,_79);
+}
+},setShape:function(_7a){
+this.vmlPath=[];
+this.lastControl.type="";
+g.Path.superclass.setShape.apply(this,arguments);
+this.vmlPath=this.vmlPath.join("");
+this.rawNode.path.v=this.vmlPath+" r0,0 e";
+return this;
+},_pathVmlToSvgMap:{m:"M",l:"L",t:"m",r:"l",c:"C",v:"c",qb:"Q",x:"z",e:""},renderers:{M:"_moveToA",m:"_moveToR",L:"_lineToA",l:"_lineToR",H:"_hLineToA",h:"_hLineToR",V:"_vLineToA",v:"_vLineToR",C:"_curveToA",c:"_curveToR",S:"_smoothCurveToA",s:"_smoothCurveToR",Q:"_qCurveToA",q:"_qCurveToR",T:"_qSmoothCurveToA",t:"_qSmoothCurveToR",A:"_arcTo",a:"_arcTo",Z:"_closePath",z:"_closePath"},_addArgs:function(_7b,_7c,_7d,_7e){
+var n=_7c instanceof Array?_7c:_7c.args;
+for(var i=_7d;i<_7e;++i){
+_7b.push(" ",n[i].toFixed());
+}
+},_adjustRelCrd:function(_81,_82,_83){
+var n=_82 instanceof Array?_82:_82.args,l=n.length,_86=new Array(l),i=0,x=_81.x,y=_81.y;
+if(typeof x!="number"){
+_86[0]=x=n[0];
+_86[1]=y=n[1];
+i=2;
+}
+if(typeof _83=="number"&&_83!=2){
+var j=_83;
+while(j<=l){
+for(;i<j;i+=2){
+_86[i]=x+n[i];
+_86[i+1]=y+n[i+1];
+}
+x=_86[j-2];
+y=_86[j-1];
+j+=_83;
+}
+}else{
+for(;i<l;i+=2){
+_86[i]=(x+=n[i]);
+_86[i+1]=(y+=n[i+1]);
+}
+}
+return _86;
+},_adjustRelPos:function(_8b,_8c){
+var n=_8c instanceof Array?_8c:_8c.args,l=n.length,_8f=new Array(l);
+for(var i=0;i<l;++i){
+_8f[i]=(_8b+=n[i]);
+}
+return _8f;
+},_moveToA:function(_91){
+var p=[" m"],n=_91 instanceof Array?_91:_91.args,l=n.length;
+this._addArgs(p,n,0,2);
+if(l>2){
+p.push(" l");
+this._addArgs(p,n,2,l);
+}
+this.lastControl.type="";
+return p;
+},_moveToR:function(_95,_96){
+return this._moveToA(this._adjustRelCrd(_96,_95));
+},_lineToA:function(_97){
+var p=[" l"],n=_97 instanceof Array?_97:_97.args;
+this._addArgs(p,n,0,n.length);
+this.lastControl.type="";
+return p;
+},_lineToR:function(_9a,_9b){
+return this._lineToA(this._adjustRelCrd(_9b,_9a));
+},_hLineToA:function(_9c,_9d){
+var p=[" l"],y=" "+_9d.y.toFixed(),n=_9c instanceof Array?_9c:_9c.args,l=n.length;
+for(var i=0;i<l;++i){
+p.push(" ",n[i].toFixed(),y);
+}
+this.lastControl.type="";
+return p;
+},_hLineToR:function(_a3,_a4){
+return this._hLineToA(this._adjustRelPos(_a4.x,_a3),_a4);
+},_vLineToA:function(_a5,_a6){
+var p=[" l"],x=" "+_a6.x.toFixed(),n=_a5 instanceof Array?_a5:_a5.args,l=n.length;
+for(var i=0;i<l;++i){
+p.push(x," ",n[i].toFixed());
+}
+this.lastControl.type="";
+return p;
+},_vLineToR:function(_ac,_ad){
+return this._vLineToA(this._adjustRelPos(_ad.y,_ac),_ad);
+},_curveToA:function(_ae){
+var p=[],n=_ae instanceof Array?_ae:_ae.args,l=n.length,lc=this.lastControl;
+for(var i=0;i<l;i+=6){
+p.push(" c");
+this._addArgs(p,n,i,i+6);
+}
+lc.x=n[l-4];
+lc.y=n[l-3];
+lc.type="C";
+return p;
+},_curveToR:function(_b4,_b5){
+return this._curveToA(this._adjustRelCrd(_b5,_b4,6));
+},_smoothCurveToA:function(_b6,_b7){
+var p=[],n=_b6 instanceof Array?_b6:_b6.args,l=n.length,lc=this.lastControl,i=0;
+if(lc.type!="C"){
+p.push(" c");
+this._addArgs(p,[_b7.x,_b7.y],0,2);
+this._addArgs(p,n,0,4);
+lc.x=n[0];
+lc.y=n[1];
+lc.type="C";
+i=4;
+}
+for(;i<l;i+=4){
+p.push(" c");
+this._addArgs(p,[2*_b7.x-lc.x,2*_b7.y-lc.y],0,2);
+this._addArgs(p,n,i,i+4);
+lc.x=n[i];
+lc.y=n[i+1];
+}
+return p;
+},_smoothCurveToR:function(_bd,_be){
+return this._smoothCurveToA(this._adjustRelCrd(_be,_bd,4),_be);
+},_qCurveToA:function(_bf){
+var p=[],n=_bf instanceof Array?_bf:_bf.args,l=n.length,lc=this.lastControl;
+for(var i=0;i<l;i+=4){
+p.push(" qb");
+this._addArgs(p,n,i,i+4);
+}
+lc.x=n[l-4];
+lc.y=n[l-3];
+lc.type="Q";
+return p;
+},_qCurveToR:function(_c5,_c6){
+return this._qCurveToA(this._adjustRelCrd(_c6,_c5,4));
+},_qSmoothCurveToA:function(_c7,_c8){
+var p=[],n=_c7 instanceof Array?_c7:_c7.args,l=n.length,lc=this.lastControl,i=0;
+if(lc.type!="Q"){
+p.push(" qb");
+this._addArgs(p,[lc.x=_c8.x,lc.y=_c8.y],0,2);
+lc.type="Q";
+this._addArgs(p,n,0,2);
+i=2;
+}
+for(;i<l;i+=2){
+p.push(" qb");
+this._addArgs(p,[lc.x=2*_c8.x-lc.x,lc.y=2*_c8.y-lc.y],0,2);
+this._addArgs(p,n,i,i+2);
+}
+return p;
+},_qSmoothCurveToR:function(_ce,_cf){
+return this._qSmoothCurveToA(this._adjustRelCrd(_cf,_ce,2),_cf);
+},_arcTo:function(_d0,_d1){
+var p=[],n=_d0.args,l=n.length,_d5=_d0.action=="a";
+for(var i=0;i<l;i+=7){
+var x1=n[i+5],y1=n[i+6];
+if(_d5){
+x1+=_d1.x;
+y1+=_d1.y;
+}
+var _d9=g.arc.arcAsBezier(_d1,n[i],n[i+1],n[i+2],n[i+3]?1:0,n[i+4]?1:0,x1,y1);
+for(var j=0;j<_d9.length;++j){
+p.push(" c");
+var t=_d9[j];
+this._addArgs(p,t,0,t.length);
+}
+_d1.x=x1;
+_d1.y=y1;
+}
+this.lastControl.type="";
+return p;
+},_closePath:function(){
+this.lastControl.type="";
+return ["x"];
+}});
+g.Path.nodeType="shape";
+dojo.declare("dojox.gfx.TextPath",dojox.gfx.Path,{constructor:function(_dc){
+if(_dc){
+_dc.setAttribute("dojoGfxType","textpath");
+}
+this.fontStyle=null;
+if(!("text" in this)){
+this.text=dojo.clone(g.defaultTextPath);
+}
+if(!("fontStyle" in this)){
+this.fontStyle=dojo.clone(g.defaultFont);
+}
+},setText:function(_dd){
+this.text=g.makeParameters(this.text,typeof _dd=="string"?{text:_dd}:_dd);
+this._setText();
+return this;
+},setFont:function(_de){
+this.fontStyle=typeof _de=="string"?g.splitFontString(_de):g.makeParameters(g.defaultFont,_de);
+this._setFont();
+return this;
+},_setText:function(){
+this.bbox=null;
+var r=this.rawNode,s=this.text,p=null,t=null,c=r.childNodes;
+for(var i=0;i<c.length;++i){
+var tag=c[i].tagName;
+if(tag=="path"){
+p=c[i];
+if(t){
+break;
+}
+}else{
+if(tag=="textpath"){
+t=c[i];
+if(p){
+break;
+}
+}
+}
+}
+if(!p){
+p=this.rawNode.ownerDocument.createElement("v:path");
+r.appendChild(p);
+}
+if(!t){
+t=this.rawNode.ownerDocument.createElement("v:textpath");
+r.appendChild(t);
+}
+p.textPathOk=true;
+t.on=true;
+var a=_3.text_alignment[s.align];
+t.style["v-text-align"]=a?a:"left";
+t.style["text-decoration"]=s.decoration;
+t.style["v-rotate-letters"]=s.rotated;
+t.style["v-text-kern"]=s.kerning;
+t.string=s.text;
+},_setFont:function(){
+var f=this.fontStyle,c=this.rawNode.childNodes;
+for(var i=0;i<c.length;++i){
+if(c[i].tagName=="textpath"){
+c[i].style.font=g.makeFontString(f);
+break;
+}
+}
+}});
+g.TextPath.nodeType="shape";
+dojo.declare("dojox.gfx.Surface",dojox.gfx.shape.Surface,{constructor:function(){
+_3.Container._init.call(this);
+},setDimensions:function(_ea,_eb){
+this.width=g.normalizedLength(_ea);
+this.height=g.normalizedLength(_eb);
+if(!this.rawNode){
+return this;
+}
+var cs=this.clipNode.style,r=this.rawNode,rs=r.style,bs=this.bgNode.style,ps=this._parent.style,i;
+ps.width=_ea;
+ps.height=_eb;
+cs.width=_ea;
+cs.height=_eb;
+cs.clip="rect(0px "+_ea+"px "+_eb+"px 0px)";
+rs.width=_ea;
+rs.height=_eb;
+r.coordsize=_ea+" "+_eb;
+bs.width=_ea;
+bs.height=_eb;
+for(i=0;i<this.children.length;++i){
+this.children[i]._setDimensions(_ea,_eb);
+}
+return this;
+},getDimensions:function(){
+var t=this.rawNode?{width:g.normalizedLength(this.rawNode.style.width),height:g.normalizedLength(this.rawNode.style.height)}:null;
+if(t.width<=0){
+t.width=this.width;
+}
+if(t.height<=0){
+t.height=this.height;
+}
+return t;
+}});
+dojox.gfx.createSurface=function(_f3,_f4,_f5){
+if(!_f4){
+_f4="100%";
+}
+if(!_f5){
+_f5="100%";
+}
+var s=new g.Surface(),p=dojo.byId(_f3),c=s.clipNode=p.ownerDocument.createElement("div"),r=s.rawNode=p.ownerDocument.createElement("v:group"),cs=c.style,rs=r.style;
+if(dojo.isIE>7){
+rs.display="inline-block";
+}
+s._parent=p;
+s._nodes.push(c);
+p.style.width=_f4;
+p.style.height=_f5;
+cs.position="absolute";
+cs.width=_f4;
+cs.height=_f5;
+cs.clip="rect(0px "+_f4+"px "+_f5+"px 0px)";
+rs.position="absolute";
+rs.width=_f4;
+rs.height=_f5;
+r.coordsize=(_f4=="100%"?_f4:parseFloat(_f4))+" "+(_f5=="100%"?_f5:parseFloat(_f5));
+r.coordorigin="0 0";
+var b=s.bgNode=r.ownerDocument.createElement("v:rect"),bs=b.style;
+bs.left=bs.top=0;
+bs.width=rs.width;
+bs.height=rs.height;
+b.filled=b.stroked="f";
+r.appendChild(b);
+c.appendChild(r);
+p.appendChild(c);
+s.width=g.normalizedLength(_f4);
+s.height=g.normalizedLength(_f5);
+return s;
+};
+_3.Container={_init:function(){
+sh.Container._init.call(this);
+},add:function(_fe){
+if(this!=_fe.getParent()){
+this.rawNode.appendChild(_fe.rawNode);
+if(!_fe.getParent()){
+_fe.setFill(_fe.getFill());
+_fe.setStroke(_fe.getStroke());
+}
+sh.Container.add.apply(this,arguments);
+}
+return this;
+},remove:function(_ff,_100){
+if(this==_ff.getParent()){
+if(this.rawNode==_ff.rawNode.parentNode){
+this.rawNode.removeChild(_ff.rawNode);
+}
+sh.Container.remove.apply(this,arguments);
+}
+return this;
+},clear:function(){
+var r=this.rawNode;
+while(r.firstChild!=r.lastChild){
+if(r.firstChild!=this.bgNode){
+r.removeChild(r.firstChild);
+}
+if(r.lastChild!=this.bgNode){
+r.removeChild(r.lastChild);
+}
+}
+return sh.Container.clear.apply(this,arguments);
+},_moveChildToFront:sh.Container._moveChildToFront,_moveChildToBack:sh.Container._moveChildToBack};
+dojo.mixin(sh.Creator,{createGroup:function(){
+var node=this.createObject(g.Group,null);
+var r=node.rawNode.ownerDocument.createElement("v:rect");
+r.style.left=r.style.top=0;
+r.style.width=node.rawNode.style.width;
+r.style.height=node.rawNode.style.height;
+r.filled=r.stroked="f";
+node.rawNode.appendChild(r);
+node.bgNode=r;
+return node;
+},createImage:function(_104){
+if(!this.rawNode){
+return null;
+}
+var _105=new g.Image(),doc=this.rawNode.ownerDocument,node=doc.createElement("v:rect");
+node.stroked="f";
+node.style.width=this.rawNode.style.width;
+node.style.height=this.rawNode.style.height;
+var img=doc.createElement("v:imagedata");
+node.appendChild(img);
+_105.setRawNode(node);
+this.rawNode.appendChild(node);
+_105.setShape(_104);
+this.add(_105);
+return _105;
+},createRect:function(rect){
+if(!this.rawNode){
+return null;
+}
+var _10a=new g.Rect,node=this.rawNode.ownerDocument.createElement("v:roundrect");
+if(dojo.isIE>7){
+node.style.display="inline-block";
+}
+_10a.setRawNode(node);
+this.rawNode.appendChild(node);
+_10a.setShape(rect);
+this.add(_10a);
+return _10a;
+},createObject:function(_10c,_10d){
+if(!this.rawNode){
+return null;
+}
+var _10e=new _10c(),node=this.rawNode.ownerDocument.createElement("v:"+_10c.nodeType);
+_10e.setRawNode(node);
+this.rawNode.appendChild(node);
+switch(_10c){
+case g.Group:
+case g.Line:
+case g.Polyline:
+case g.Image:
+case g.Text:
+case g.Path:
+case g.TextPath:
+this._overrideSize(node);
+}
+_10e.setShape(_10d);
+this.add(_10e);
+return _10e;
+},_overrideSize:function(node){
+var s=this.rawNode.style,w=s.width,h=s.height;
+node.style.width=w;
+node.style.height=h;
+node.coordsize=parseInt(w)+" "+parseInt(h);
+}});
+dojo.extend(g.Group,_3.Container);
+dojo.extend(g.Group,sh.Creator);
+dojo.extend(g.Surface,_3.Container);
+dojo.extend(g.Surface,sh.Creator);
+})();
+}
diff --git a/dojox/gfx/vml_attach.js b/dojox/gfx/vml_attach.js
new file mode 100644
index 0000000..37e4a0d
--- /dev/null
+++ b/dojox/gfx/vml_attach.js
@@ -0,0 +1,300 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+dojo.require("dojox.gfx.vml");
+dojo.experimental("dojox.gfx.vml_attach");
+(function(){
+dojox.gfx.attachNode=function(_1){
+if(!_1){
+return null;
+}
+var s=null;
+switch(_1.tagName.toLowerCase()){
+case dojox.gfx.Rect.nodeType:
+s=new dojox.gfx.Rect(_1);
+_3(s);
+break;
+case dojox.gfx.Ellipse.nodeType:
+if(_1.style.width==_1.style.height){
+s=new dojox.gfx.Circle(_1);
+_4(s);
+}else{
+s=new dojox.gfx.Ellipse(_1);
+_5(s);
+}
+break;
+case dojox.gfx.Path.nodeType:
+switch(_1.getAttribute("dojoGfxType")){
+case "line":
+s=new dojox.gfx.Line(_1);
+_6(s);
+break;
+case "polyline":
+s=new dojox.gfx.Polyline(_1);
+_7(s);
+break;
+case "path":
+s=new dojox.gfx.Path(_1);
+_8(s);
+break;
+case "text":
+s=new dojox.gfx.Text(_1);
+_9(s);
+_a(s);
+_b(s);
+break;
+case "textpath":
+s=new dojox.gfx.TextPath(_1);
+_8(s);
+_9(s);
+_a(s);
+break;
+}
+break;
+case dojox.gfx.Image.nodeType:
+switch(_1.getAttribute("dojoGfxType")){
+case "image":
+s=new dojox.gfx.Image(_1);
+_c(s);
+_d(s);
+break;
+}
+break;
+default:
+return null;
+}
+if(!(s instanceof dojox.gfx.Image)){
+_e(s);
+_f(s);
+if(!(s instanceof dojox.gfx.Text)){
+_10(s);
+}
+}
+return s;
+};
+dojox.gfx.attachSurface=function(_11){
+var s=new dojox.gfx.Surface();
+s.clipNode=_11;
+var r=s.rawNode=_11.firstChild;
+var b=r.firstChild;
+if(!b||b.tagName!="rect"){
+return null;
+}
+s.bgNode=r;
+return s;
+};
+var _e=function(_15){
+var _16=null,r=_15.rawNode,fo=r.fill;
+if(fo.on&&fo.type=="gradient"){
+var _16=dojo.clone(dojox.gfx.defaultLinearGradient),rad=dojox.gfx.matrix._degToRad(fo.angle);
+_16.x2=Math.cos(rad);
+_16.y2=Math.sin(rad);
+_16.colors=[];
+var _1a=fo.colors.value.split(";");
+for(var i=0;i<_1a.length;++i){
+var t=_1a[i].match(/\S+/g);
+if(!t||t.length!=2){
+continue;
+}
+_16.colors.push({offset:dojox.gfx.vml._parseFloat(t[0]),color:new dojo.Color(t[1])});
+}
+}else{
+if(fo.on&&fo.type=="gradientradial"){
+var _16=dojo.clone(dojox.gfx.defaultRadialGradient),w=parseFloat(r.style.width),h=parseFloat(r.style.height);
+_16.cx=isNaN(w)?0:fo.focusposition.x*w;
+_16.cy=isNaN(h)?0:fo.focusposition.y*h;
+_16.r=isNaN(w)?1:w/2;
+_16.colors=[];
+var _1a=fo.colors.value.split(";");
+for(var i=_1a.length-1;i>=0;--i){
+var t=_1a[i].match(/\S+/g);
+if(!t||t.length!=2){
+continue;
+}
+_16.colors.push({offset:dojox.gfx.vml._parseFloat(t[0]),color:new dojo.Color(t[1])});
+}
+}else{
+if(fo.on&&fo.type=="tile"){
+var _16=dojo.clone(dojox.gfx.defaultPattern);
+_16.width=dojox.gfx.pt2px(fo.size.x);
+_16.height=dojox.gfx.pt2px(fo.size.y);
+_16.x=fo.origin.x*_16.width;
+_16.y=fo.origin.y*_16.height;
+_16.src=fo.src;
+}else{
+if(fo.on&&r.fillcolor){
+_16=new dojo.Color(r.fillcolor+"");
+_16.a=fo.opacity;
+}
+}
+}
+}
+_15.fillStyle=_16;
+};
+var _f=function(_1f){
+var r=_1f.rawNode;
+if(!r.stroked){
+_1f.strokeStyle=null;
+return;
+}
+var _21=_1f.strokeStyle=dojo.clone(dojox.gfx.defaultStroke),rs=r.stroke;
+_21.color=new dojo.Color(r.strokecolor.value);
+_21.width=dojox.gfx.normalizedLength(r.strokeweight+"");
+_21.color.a=rs.opacity;
+_21.cap=this._translate(this._capMapReversed,rs.endcap);
+_21.join=rs.joinstyle=="miter"?rs.miterlimit:rs.joinstyle;
+_21.style=rs.dashstyle;
+};
+var _10=function(_23){
+var s=_23.rawNode.skew,sm=s.matrix,so=s.offset;
+_23.matrix=dojox.gfx.matrix.normalize({xx:sm.xtox,xy:sm.ytox,yx:sm.xtoy,yy:sm.ytoy,dx:dojox.gfx.pt2px(so.x),dy:dojox.gfx.pt2px(so.y)});
+};
+var _27=function(_28){
+_28.bgNode=_28.rawNode.firstChild;
+};
+var _3=function(_29){
+var r=_29.rawNode,_2b=r.outerHTML.match(/arcsize = \"(\d*\.?\d+[%f]?)\"/)[1],_2c=r.style,_2d=parseFloat(_2c.width),_2e=parseFloat(_2c.height);
+_2b=(_2b.indexOf("%")>=0)?parseFloat(_2b)/100:dojox.gfx.vml._parseFloat(_2b);
+_29.shape=dojox.gfx.makeParameters(dojox.gfx.defaultRect,{x:parseInt(_2c.left),y:parseInt(_2c.top),width:_2d,height:_2e,r:Math.min(_2d,_2e)*_2b});
+};
+var _5=function(_2f){
+var _30=_2f.rawNode.style,rx=parseInt(_30.width)/2,ry=parseInt(_30.height)/2;
+_2f.shape=dojox.gfx.makeParameters(dojox.gfx.defaultEllipse,{cx:parseInt(_30.left)+rx,cy:parseInt(_30.top)+ry,rx:rx,ry:ry});
+};
+var _4=function(_33){
+var _34=_33.rawNode.style,r=parseInt(_34.width)/2;
+_33.shape=dojox.gfx.makeParameters(dojox.gfx.defaultCircle,{cx:parseInt(_34.left)+r,cy:parseInt(_34.top)+r,r:r});
+};
+var _6=function(_36){
+var _37=_36.shape=dojo.clone(dojox.gfx.defaultLine),p=_36.rawNode.path.v.match(dojox.gfx.pathVmlRegExp);
+do{
+if(p.length<7||p[0]!="m"||p[3]!="l"||p[6]!="e"){
+break;
+}
+_37.x1=parseInt(p[1]);
+_37.y1=parseInt(p[2]);
+_37.x2=parseInt(p[4]);
+_37.y2=parseInt(p[5]);
+}while(false);
+};
+var _7=function(_39){
+var _3a=_39.shape=dojo.clone(dojox.gfx.defaultPolyline),p=_39.rawNode.path.v.match(dojox.gfx.pathVmlRegExp);
+do{
+if(p.length<3||p[0]!="m"){
+break;
+}
+var x=parseInt(p[0]),y=parseInt(p[1]);
+if(isNaN(x)||isNaN(y)){
+break;
+}
+_3a.points.push({x:x,y:y});
+if(p.length<6||p[3]!="l"){
+break;
+}
+for(var i=4;i<p.length;i+=2){
+x=parseInt(p[i]);
+y=parseInt(p[i+1]);
+if(isNaN(x)||isNaN(y)){
+break;
+}
+_3a.points.push({x:x,y:y});
+}
+}while(false);
+};
+var _c=function(_3f){
+_3f.shape=dojo.clone(dojox.gfx.defaultImage);
+_3f.shape.src=_3f.rawNode.firstChild.src;
+};
+var _d=function(_40){
+var m=_40.rawNode.filters["DXImageTransform.Microsoft.Matrix"];
+_40.matrix=dojox.gfx.matrix.normalize({xx:m.M11,xy:m.M12,yx:m.M21,yy:m.M22,dx:m.Dx,dy:m.Dy});
+};
+var _9=function(_42){
+var _43=_42.shape=dojo.clone(dojox.gfx.defaultText),r=_42.rawNode,p=r.path.v.match(dojox.gfx.pathVmlRegExp);
+do{
+if(!p||p.length!=7){
+break;
+}
+var c=r.childNodes,i=0;
+for(;i<c.length&&c[i].tagName!="textpath";++i){
+}
+if(i>=c.length){
+break;
+}
+var s=c[i].style;
+_43.text=c[i].string;
+switch(s["v-text-align"]){
+case "left":
+_43.x=parseInt(p[1]);
+_43.align="start";
+break;
+case "center":
+_43.x=(parseInt(p[1])+parseInt(p[4]))/2;
+_43.align="middle";
+break;
+case "right":
+_43.x=parseInt(p[4]);
+_43.align="end";
+break;
+}
+_43.y=parseInt(p[2]);
+_43.decoration=s["text-decoration"];
+_43.rotated=s["v-rotate-letters"].toLowerCase() in dojox.gfx.vml._bool;
+_43.kerning=s["v-text-kern"].toLowerCase() in dojox.gfx.vml._bool;
+return;
+}while(false);
+_42.shape=null;
+};
+var _a=function(_49){
+var _4a=_49.fontStyle=dojo.clone(dojox.gfx.defaultFont),c=_49.rawNode.childNodes,i=0;
+for(;i<c.length&&c[i].tagName=="textpath";++i){
+}
+if(i>=c.length){
+_49.fontStyle=null;
+return;
+}
+var s=c[i].style;
+_4a.style=s.fontstyle;
+_4a.variant=s.fontvariant;
+_4a.weight=s.fontweight;
+_4a.size=s.fontsize;
+_4a.family=s.fontfamily;
+};
+var _b=function(_4e){
+_10(_4e);
+var _4f=_4e.matrix,fs=_4e.fontStyle;
+if(_4f&&fs){
+_4e.matrix=dojox.gfx.matrix.multiply(_4f,{dy:dojox.gfx.normalizedLength(fs.size)*0.35});
+}
+};
+var _8=function(_51){
+var _52=_51.shape=dojo.clone(dojox.gfx.defaultPath),p=_51.rawNode.path.v.match(dojox.gfx.pathVmlRegExp),t=[],_55=false,map=dojox.gfx.Path._pathVmlToSvgMap;
+for(var i=0;i<p.length;++p){
+var s=p[i];
+if(s in map){
+_55=false;
+t.push(map[s]);
+}else{
+if(!_55){
+var n=parseInt(s);
+if(isNaN(n)){
+_55=true;
+}else{
+t.push(n);
+}
+}
+}
+}
+var l=t.length;
+if(l>=4&&t[l-1]==""&&t[l-2]==0&&t[l-3]==0&&t[l-4]=="l"){
+t.splice(l-4,4);
+}
+if(l){
+_52.path=t.join(" ");
+}
+};
+})();
diff --git a/dojox/gfx3d.js b/dojox/gfx3d.js
new file mode 100644
index 0000000..3bab8ac
--- /dev/null
+++ b/dojox/gfx3d.js
@@ -0,0 +1,14 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx3d"]){
+dojo._hasResource["dojox.gfx3d"]=true;
+dojo.provide("dojox.gfx3d");
+dojo.require("dojox.gfx3d.matrix");
+dojo.require("dojox.gfx3d._base");
+dojo.require("dojox.gfx3d.object");
+}
diff --git a/dojox/gfx3d/README b/dojox/gfx3d/README
new file mode 100644
index 0000000..bc7ed4e
--- /dev/null
+++ b/dojox/gfx3d/README
@@ -0,0 +1,36 @@
+-------------------------------------------------------------------------------
+dojox.gfx3d
+-------------------------------------------------------------------------------
+Version 0.100
+Release date: 10/31/2007
+-------------------------------------------------------------------------------
+Project state:
+beta
+-------------------------------------------------------------------------------
+Credits
+	Kun Xi (bookstack at gmail.com)
+	Eugene Lazutkin (eugene.lazutkin at gmail.com)
+-------------------------------------------------------------------------------
+Project description
+
+Implementation of simple portable 3D graphics library.
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo Core, dojox.gfx.
+-------------------------------------------------------------------------------
+Documentation
+
+Not ready yet.
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/gfx3d.js
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/gfx3d/*
+
+Install into the following directory structure:
+/dojox/gfx3d/
+
+...which should be at the same level as your Dojo checkout.
+-------------------------------------------------------------------------------
diff --git a/dojox/gfx3d/_base.js b/dojox/gfx3d/_base.js
new file mode 100644
index 0000000..7f1a6c3
--- /dev/null
+++ b/dojox/gfx3d/_base.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx3d._base"]){
+dojo._hasResource["dojox.gfx3d._base"]=true;
+dojo.provide("dojox.gfx3d._base");
+dojo.mixin(dojox.gfx3d,{defaultEdges:{type:"edges",style:null,points:[]},defaultTriangles:{type:"triangles",style:null,points:[]},defaultQuads:{type:"quads",style:null,points:[]},defaultOrbit:{type:"orbit",center:{x:0,y:0,z:0},radius:50},defaultPath3d:{type:"path3d",path:[]},defaultPolygon:{type:"polygon",path:[]},defaultCube:{type:"cube",bottom:{x:0,y:0,z:0},top:{x:100,y:100,z:100}},defaultCylinder:{type:"cylinder",center:{x:0,y:0,z:0},height:100,radius:50}});
+}
diff --git a/dojox/gfx3d/gradient.js b/dojox/gfx3d/gradient.js
new file mode 100644
index 0000000..c3bd23d
--- /dev/null
+++ b/dojox/gfx3d/gradient.js
@@ -0,0 +1,28 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx3d.gradient"]){
+dojo._hasResource["dojox.gfx3d.gradient"]=true;
+dojo.provide("dojox.gfx3d.gradient");
+dojo.require("dojox.gfx3d.vector");
+dojo.require("dojox.gfx3d.matrix");
+(function(){
+var _1=function(a,b){
+return Math.sqrt(Math.pow(b.x-a.x,2)+Math.pow(b.y-a.y,2));
+};
+var N=32;
+dojox.gfx3d.gradient=function(_5,_6,_7,_8,_9,to,_b){
+var m=dojox.gfx3d.matrix,v=dojox.gfx3d.vector,mx=m.normalize(_b),f=m.multiplyPoint(mx,_8*Math.cos(_9)+_7.x,_8*Math.sin(_9)+_7.y,_7.z),t=m.multiplyPoint(mx,_8*Math.cos(to)+_7.x,_8*Math.sin(to)+_7.y,_7.z),c=m.multiplyPoint(mx,_7.x,_7.y,_7.z),_12=(to-_9)/N,r=_1(f,t)/2,mod=_5[_6.type],fin=_6.finish,pmt=_6.color,_17=[{offset:0,color:mod.call(_5,v.substract(f,c),fin,pmt)}];
+for(var a=_9+_12;a<to;a+=_12){
+var p=m.multiplyPoint(mx,_8*Math.cos(a)+_7.x,_8*Math.sin(a)+_7.y,_7.z),df=_1(f,p),dt=_1(t,p);
+_17.push({offset:df/(df+dt),color:mod.call(_5,v.substract(p,c),fin,pmt)});
+}
+_17.push({offset:1,color:mod.call(_5,v.substract(t,c),fin,pmt)});
+return {type:"linear",x1:0,y1:-r,x2:0,y2:r,colors:_17};
+};
+})();
+}
diff --git a/dojox/gfx3d/lighting.js b/dojox/gfx3d/lighting.js
new file mode 100644
index 0000000..88e098d
--- /dev/null
+++ b/dojox/gfx3d/lighting.js
@@ -0,0 +1,158 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx3d.lighting"]){
+dojo._hasResource["dojox.gfx3d.lighting"]=true;
+dojo.provide("dojox.gfx3d.lighting");
+dojo.require("dojox.gfx._base");
+(function(){
+var _1=dojox.gfx3d.lighting;
+dojo.mixin(dojox.gfx3d.lighting,{black:function(){
+return {r:0,g:0,b:0,a:1};
+},white:function(){
+return {r:1,g:1,b:1,a:1};
+},toStdColor:function(c){
+c=dojox.gfx.normalizeColor(c);
+return {r:c.r/255,g:c.g/255,b:c.b/255,a:c.a};
+},fromStdColor:function(c){
+return new dojo.Color([Math.round(255*c.r),Math.round(255*c.g),Math.round(255*c.b),c.a]);
+},scaleColor:function(s,c){
+return {r:s*c.r,g:s*c.g,b:s*c.b,a:s*c.a};
+},addColor:function(a,b){
+return {r:a.r+b.r,g:a.g+b.g,b:a.b+b.b,a:a.a+b.a};
+},multiplyColor:function(a,b){
+return {r:a.r*b.r,g:a.g*b.g,b:a.b*b.b,a:a.a*b.a};
+},saturateColor:function(c){
+return {r:c.r<0?0:c.r>1?1:c.r,g:c.g<0?0:c.g>1?1:c.g,b:c.b<0?0:c.b>1?1:c.b,a:c.a<0?0:c.a>1?1:c.a};
+},mixColor:function(c1,c2,s){
+return _1.addColor(_1.scaleColor(s,c1),_1.scaleColor(1-s,c2));
+},diff2Color:function(c1,c2){
+var r=c1.r-c2.r;
+var g=c1.g-c2.g;
+var b=c1.b-c2.b;
+var a=c1.a-c2.a;
+return r*r+g*g+b*b+a*a;
+},length2Color:function(c){
+return c.r*c.r+c.g*c.g+c.b*c.b+c.a*c.a;
+},dot:function(a,b){
+return a.x*b.x+a.y*b.y+a.z*b.z;
+},scale:function(s,v){
+return {x:s*v.x,y:s*v.y,z:s*v.z};
+},add:function(a,b){
+return {x:a.x+b.x,y:a.y+b.y,z:a.z+b.z};
+},saturate:function(v){
+return Math.min(Math.max(v,0),1);
+},length:function(v){
+return Math.sqrt(dojox.gfx3d.lighting.dot(v,v));
+},normalize:function(v){
+return _1.scale(1/_1.length(v),v);
+},faceforward:function(n,i){
+var p=dojox.gfx3d.lighting;
+var s=p.dot(i,n)<0?1:-1;
+return p.scale(s,n);
+},reflect:function(i,n){
+var p=dojox.gfx3d.lighting;
+return p.add(i,p.scale(-2*p.dot(i,n),n));
+},diffuse:function(_25,_26){
+var c=_1.black();
+for(var i=0;i<_26.length;++i){
+var l=_26[i],d=_1.dot(_1.normalize(l.direction),_25);
+c=_1.addColor(c,_1.scaleColor(d,l.color));
+}
+return _1.saturateColor(c);
+},specular:function(_2b,v,_2d,_2e){
+var c=_1.black();
+for(var i=0;i<_2e.length;++i){
+var l=_2e[i],h=_1.normalize(_1.add(_1.normalize(l.direction),v)),s=Math.pow(Math.max(0,_1.dot(_2b,h)),1/_2d);
+c=_1.addColor(c,_1.scaleColor(s,l.color));
+}
+return _1.saturateColor(c);
+},phong:function(_34,v,_36,_37){
+_34=_1.normalize(_34);
+var c=_1.black();
+for(var i=0;i<_37.length;++i){
+var l=_37[i],r=_1.reflect(_1.scale(-1,_1.normalize(v)),_34),s=Math.pow(Math.max(0,_1.dot(r,_1.normalize(l.direction))),_36);
+c=_1.addColor(c,_1.scaleColor(s,l.color));
+}
+return _1.saturateColor(c);
+}});
+dojo.declare("dojox.gfx3d.lighting.Model",null,{constructor:function(_3d,_3e,_3f,_40){
+this.incident=_1.normalize(_3d);
+this.lights=[];
+for(var i=0;i<_3e.length;++i){
+var l=_3e[i];
+this.lights.push({direction:_1.normalize(l.direction),color:_1.toStdColor(l.color)});
+}
+this.ambient=_1.toStdColor(_3f.color?_3f.color:"white");
+this.ambient=_1.scaleColor(_3f.intensity,this.ambient);
+this.ambient=_1.scaleColor(this.ambient.a,this.ambient);
+this.ambient.a=1;
+this.specular=_1.toStdColor(_40?_40:"white");
+this.specular=_1.scaleColor(this.specular.a,this.specular);
+this.specular.a=1;
+this.npr_cool={r:0,g:0,b:0.4,a:1};
+this.npr_warm={r:0.4,g:0.4,b:0.2,a:1};
+this.npr_alpha=0.2;
+this.npr_beta=0.6;
+this.npr_scale=0.6;
+},constant:function(_43,_44,_45){
+_45=_1.toStdColor(_45);
+var _46=_45.a,_47=_1.scaleColor(_46,_45);
+_47.a=_46;
+return _1.fromStdColor(_1.saturateColor(_47));
+},matte:function(_48,_49,_4a){
+if(typeof _49=="string"){
+_49=_1.finish[_49];
+}
+_4a=_1.toStdColor(_4a);
+_48=_1.faceforward(_1.normalize(_48),this.incident);
+var _4b=_1.scaleColor(_49.Ka,this.ambient),_4c=_1.saturate(-4*_1.dot(_48,this.incident)),_4d=_1.scaleColor(_4c*_49.Kd,_1.diffuse(_48,this.lights)),_4e=_1.scaleColor(_4a.a,_1.multiplyColor(_4a,_1.addColor(_4b,_4d)));
+_4e.a=_4a.a;
+return _1.fromStdColor(_1.saturateColor(_4e));
+},metal:function(_4f,_50,_51){
+if(typeof _50=="string"){
+_50=_1.finish[_50];
+}
+_51=_1.toStdColor(_51);
+_4f=_1.faceforward(_1.normalize(_4f),this.incident);
+var v=_1.scale(-1,this.incident),_53,_54,_55=_1.scaleColor(_50.Ka,this.ambient),_56=_1.saturate(-4*_1.dot(_4f,this.incident));
+if("phong" in _50){
+_53=_1.scaleColor(_56*_50.Ks*_50.phong,_1.phong(_4f,v,_50.phong_size,this.lights));
+}else{
+_53=_1.scaleColor(_56*_50.Ks,_1.specular(_4f,v,_50.roughness,this.lights));
+}
+_54=_1.scaleColor(_51.a,_1.addColor(_1.multiplyColor(_51,_55),_1.multiplyColor(this.specular,_53)));
+_54.a=_51.a;
+return _1.fromStdColor(_1.saturateColor(_54));
+},plastic:function(_57,_58,_59){
+if(typeof _58=="string"){
+_58=_1.finish[_58];
+}
+_59=_1.toStdColor(_59);
+_57=_1.faceforward(_1.normalize(_57),this.incident);
+var v=_1.scale(-1,this.incident),_5b,_5c,_5d=_1.scaleColor(_58.Ka,this.ambient),_5e=_1.saturate(-4*_1.dot(_57,this.incident)),_5f=_1.scaleColor(_5e*_58.Kd,_1.diffuse(_57,this.lights));
+if("phong" in _58){
+_5b=_1.scaleColor(_5e*_58.Ks*_58.phong,_1.phong(_57,v,_58.phong_size,this.lights));
+}else{
+_5b=_1.scaleColor(_5e*_58.Ks,_1.specular(_57,v,_58.roughness,this.lights));
+}
+_5c=_1.scaleColor(_59.a,_1.addColor(_1.multiplyColor(_59,_1.addColor(_5d,_5f)),_1.multiplyColor(this.specular,_5b)));
+_5c.a=_59.a;
+return _1.fromStdColor(_1.saturateColor(_5c));
+},npr:function(_60,_61,_62){
+if(typeof _61=="string"){
+_61=_1.finish[_61];
+}
+_62=_1.toStdColor(_62);
+_60=_1.faceforward(_1.normalize(_60),this.incident);
+var _63=_1.scaleColor(_61.Ka,this.ambient),_64=_1.saturate(-4*_1.dot(_60,this.incident)),_65=_1.scaleColor(_64*_61.Kd,_1.diffuse(_60,this.lights)),_66=_1.scaleColor(_62.a,_1.multiplyColor(_62,_1.addColor(_63,_65))),_67=_1.addColor(this.npr_cool,_1.scaleColor(this.npr_alpha,_66)),_68=_1.addColor(this.npr_warm,_1.scaleColor(this.npr_beta,_66)),d=(1+_1.dot(this.incident,_60))/2,_66=_1.scaleColor(this.npr_scale,_1.addColor(_66,_1.mixColor(_67,_68,d)));
+_66.a=_62.a;
+return _1.fromStdColor(_1.saturateColor(_66));
+}});
+})();
+dojox.gfx3d.lighting.finish={defaults:{Ka:0.1,Kd:0.6,Ks:0,roughness:0.05},dull:{Ka:0.1,Kd:0.6,Ks:0.5,roughness:0.15},shiny:{Ka:0.1,Kd:0.6,Ks:1,roughness:0.001},glossy:{Ka:0.1,Kd:0.6,Ks:1,roughness:0.0001},phong_dull:{Ka:0.1,Kd:0.6,Ks:0.5,phong:0.5,phong_size:1},phong_shiny:{Ka:0.1,Kd:0.6,Ks:1,phong:1,phong_size:200},phong_glossy:{Ka:0.1,Kd:0.6,Ks:1,phong:1,phong_size:300},luminous:{Ka:1,Kd:0,Ks:0,roughness:0.05},metalA:{Ka:0.35,Kd:0.3,Ks:0.8,roughness:1/20},metalB:{Ka:0.3,Kd:0.4,Ks:0.7,r [...]
+}
diff --git a/dojox/gfx3d/matrix.js b/dojox/gfx3d/matrix.js
new file mode 100644
index 0000000..bc68c44
--- /dev/null
+++ b/dojox/gfx3d/matrix.js
@@ -0,0 +1,158 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx3d.matrix"]){
+dojo._hasResource["dojox.gfx3d.matrix"]=true;
+dojo.provide("dojox.gfx3d.matrix");
+dojox.gfx3d.matrix._degToRad=function(_1){
+return Math.PI*_1/180;
+};
+dojox.gfx3d.matrix._radToDeg=function(_2){
+return _2/Math.PI*180;
+};
+dojox.gfx3d.matrix.Matrix3D=function(_3){
+if(_3){
+if(typeof _3=="number"){
+this.xx=this.yy=this.zz=_3;
+}else{
+if(_3 instanceof Array){
+if(_3.length>0){
+var m=dojox.gfx3d.matrix.normalize(_3[0]);
+for(var i=1;i<_3.length;++i){
+var l=m;
+var r=dojox.gfx3d.matrix.normalize(_3[i]);
+m=new dojox.gfx3d.matrix.Matrix3D();
+m.xx=l.xx*r.xx+l.xy*r.yx+l.xz*r.zx;
+m.xy=l.xx*r.xy+l.xy*r.yy+l.xz*r.zy;
+m.xz=l.xx*r.xz+l.xy*r.yz+l.xz*r.zz;
+m.yx=l.yx*r.xx+l.yy*r.yx+l.yz*r.zx;
+m.yy=l.yx*r.xy+l.yy*r.yy+l.yz*r.zy;
+m.yz=l.yx*r.xz+l.yy*r.yz+l.yz*r.zz;
+m.zx=l.zx*r.xx+l.zy*r.yx+l.zz*r.zx;
+m.zy=l.zx*r.xy+l.zy*r.yy+l.zz*r.zy;
+m.zz=l.zx*r.xz+l.zy*r.yz+l.zz*r.zz;
+m.dx=l.xx*r.dx+l.xy*r.dy+l.xz*r.dz+l.dx;
+m.dy=l.yx*r.dx+l.yy*r.dy+l.yz*r.dz+l.dy;
+m.dz=l.zx*r.dx+l.zy*r.dy+l.zz*r.dz+l.dz;
+}
+dojo.mixin(this,m);
+}
+}else{
+dojo.mixin(this,_3);
+}
+}
+}
+};
+dojo.extend(dojox.gfx3d.matrix.Matrix3D,{xx:1,xy:0,xz:0,yx:0,yy:1,yz:0,zx:0,zy:0,zz:1,dx:0,dy:0,dz:0});
+dojo.mixin(dojox.gfx3d.matrix,{identity:new dojox.gfx3d.matrix.Matrix3D(),translate:function(a,b,c){
+if(arguments.length>1){
+return new dojox.gfx3d.matrix.Matrix3D({dx:a,dy:b,dz:c});
+}
+return new dojox.gfx3d.matrix.Matrix3D({dx:a.x,dy:a.y,dz:a.z});
+},scale:function(a,b,c){
+if(arguments.length>1){
+return new dojox.gfx3d.matrix.Matrix3D({xx:a,yy:b,zz:c});
+}
+if(typeof a=="number"){
+return new dojox.gfx3d.matrix.Matrix3D({xx:a,yy:a,zz:a});
+}
+return new dojox.gfx3d.matrix.Matrix3D({xx:a.x,yy:a.y,zz:a.z});
+},rotateX:function(_e){
+var c=Math.cos(_e);
+var s=Math.sin(_e);
+return new dojox.gfx3d.matrix.Matrix3D({yy:c,yz:-s,zy:s,zz:c});
+},rotateXg:function(_11){
+return dojox.gfx3d.matrix.rotateX(dojox.gfx3d.matrix._degToRad(_11));
+},rotateY:function(_12){
+var c=Math.cos(_12);
+var s=Math.sin(_12);
+return new dojox.gfx3d.matrix.Matrix3D({xx:c,xz:s,zx:-s,zz:c});
+},rotateYg:function(_15){
+return dojox.gfx3d.matrix.rotateY(dojox.gfx3d.matrix._degToRad(_15));
+},rotateZ:function(_16){
+var c=Math.cos(_16);
+var s=Math.sin(_16);
+return new dojox.gfx3d.matrix.Matrix3D({xx:c,xy:-s,yx:s,yy:c});
+},rotateZg:function(_19){
+return dojox.gfx3d.matrix.rotateZ(dojox.gfx3d.matrix._degToRad(_19));
+},cameraTranslate:function(a,b,c){
+if(arguments.length>1){
+return new dojox.gfx3d.matrix.Matrix3D({dx:-a,dy:-b,dz:-c});
+}
+return new dojox.gfx3d.matrix.Matrix3D({dx:-a.x,dy:-a.y,dz:-a.z});
+},cameraRotateX:function(_1d){
+var c=Math.cos(-_1d);
+var s=Math.sin(-_1d);
+return new dojox.gfx3d.matrix.Matrix3D({yy:c,yz:-s,zy:s,zz:c});
+},cameraRotateXg:function(_20){
+return dojox.gfx3d.matrix.rotateX(dojox.gfx3d.matrix._degToRad(_20));
+},cameraRotateY:function(_21){
+var c=Math.cos(-_21);
+var s=Math.sin(-_21);
+return new dojox.gfx3d.matrix.Matrix3D({xx:c,xz:s,zx:-s,zz:c});
+},cameraRotateYg:function(_24){
+return dojox.gfx3d.matrix.rotateY(dojox.gfx3d.matrix._degToRad(_24));
+},cameraRotateZ:function(_25){
+var c=Math.cos(-_25);
+var s=Math.sin(-_25);
+return new dojox.gfx3d.matrix.Matrix3D({xx:c,xy:-s,yx:s,yy:c});
+},cameraRotateZg:function(_28){
+return dojox.gfx3d.matrix.rotateZ(dojox.gfx3d.matrix._degToRad(_28));
+},normalize:function(_29){
+return (_29 instanceof dojox.gfx3d.matrix.Matrix3D)?_29:new dojox.gfx3d.matrix.Matrix3D(_29);
+},clone:function(_2a){
+var obj=new dojox.gfx3d.matrix.Matrix3D();
+for(var i in _2a){
+if(typeof (_2a[i])=="number"&&typeof (obj[i])=="number"&&obj[i]!=_2a[i]){
+obj[i]=_2a[i];
+}
+}
+return obj;
+},invert:function(_2d){
+var m=dojox.gfx3d.matrix.normalize(_2d);
+var D=m.xx*m.yy*m.zz+m.xy*m.yz*m.zx+m.xz*m.yx*m.zy-m.xx*m.yz*m.zy-m.xy*m.yx*m.zz-m.xz*m.yy*m.zx;
+var M=new dojox.gfx3d.matrix.Matrix3D({xx:(m.yy*m.zz-m.yz*m.zy)/D,xy:(m.xz*m.zy-m.xy*m.zz)/D,xz:(m.xy*m.yz-m.xz*m.yy)/D,yx:(m.yz*m.zx-m.yx*m.zz)/D,yy:(m.xx*m.zz-m.xz*m.zx)/D,yz:(m.xz*m.yx-m.xx*m.yz)/D,zx:(m.yx*m.zy-m.yy*m.zx)/D,zy:(m.xy*m.zx-m.xx*m.zy)/D,zz:(m.xx*m.yy-m.xy*m.yx)/D,dx:-1*(m.xy*m.yz*m.dz+m.xz*m.dy*m.zy+m.dx*m.yy*m.zz-m.xy*m.dy*m.zz-m.xz*m.yy*m.dz-m.dx*m.yz*m.zy)/D,dy:(m.xx*m.yz*m.dz+m.xz*m.dy*m.zx+m.dx*m.yx*m.zz-m.xx*m.dy*m.zz-m.xz*m.yx*m.dz-m.dx*m.yz*m.zx)/D,dz:-1*(m.xx*m [...]
+return M;
+},_multiplyPoint:function(m,x,y,z){
+return {x:m.xx*x+m.xy*y+m.xz*z+m.dx,y:m.yx*x+m.yy*y+m.yz*z+m.dy,z:m.zx*x+m.zy*y+m.zz*z+m.dz};
+},multiplyPoint:function(_35,a,b,c){
+var m=dojox.gfx3d.matrix.normalize(_35);
+if(typeof a=="number"&&typeof b=="number"&&typeof c=="number"){
+return dojox.gfx3d.matrix._multiplyPoint(m,a,b,c);
+}
+return dojox.gfx3d.matrix._multiplyPoint(m,a.x,a.y,a.z);
+},multiply:function(_3a){
+var m=dojox.gfx3d.matrix.normalize(_3a);
+for(var i=1;i<arguments.length;++i){
+var l=m;
+var r=dojox.gfx3d.matrix.normalize(arguments[i]);
+m=new dojox.gfx3d.matrix.Matrix3D();
+m.xx=l.xx*r.xx+l.xy*r.yx+l.xz*r.zx;
+m.xy=l.xx*r.xy+l.xy*r.yy+l.xz*r.zy;
+m.xz=l.xx*r.xz+l.xy*r.yz+l.xz*r.zz;
+m.yx=l.yx*r.xx+l.yy*r.yx+l.yz*r.zx;
+m.yy=l.yx*r.xy+l.yy*r.yy+l.yz*r.zy;
+m.yz=l.yx*r.xz+l.yy*r.yz+l.yz*r.zz;
+m.zx=l.zx*r.xx+l.zy*r.yx+l.zz*r.zx;
+m.zy=l.zx*r.xy+l.zy*r.yy+l.zz*r.zy;
+m.zz=l.zx*r.xz+l.zy*r.yz+l.zz*r.zz;
+m.dx=l.xx*r.dx+l.xy*r.dy+l.xz*r.dz+l.dx;
+m.dy=l.yx*r.dx+l.yy*r.dy+l.yz*r.dz+l.dy;
+m.dz=l.zx*r.dx+l.zy*r.dy+l.zz*r.dz+l.dz;
+}
+return m;
+},_project:function(m,x,y,z){
+return {x:m.xx*x+m.xy*y+m.xz*z+m.dx,y:m.yx*x+m.yy*y+m.yz*z+m.dy,z:m.zx*x+m.zy*y+m.zz*z+m.dz};
+},project:function(_43,a,b,c){
+var m=dojox.gfx3d.matrix.normalize(_43);
+if(typeof a=="number"&&typeof b=="number"&&typeof c=="number"){
+return dojox.gfx3d.matrix._project(m,a,b,c);
+}
+return dojox.gfx3d.matrix._project(m,a.x,a.y,a.z);
+}});
+dojox.gfx3d.Matrix3D=dojox.gfx3d.matrix.Matrix3D;
+}
diff --git a/dojox/gfx3d/object.js b/dojox/gfx3d/object.js
new file mode 100644
index 0000000..749f369
--- /dev/null
+++ b/dojox/gfx3d/object.js
@@ -0,0 +1,614 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx3d.object"]){
+dojo._hasResource["dojox.gfx3d.object"]=true;
+dojo.provide("dojox.gfx3d.object");
+dojo.require("dojox.gfx");
+dojo.require("dojox.gfx3d.lighting");
+dojo.require("dojox.gfx3d.scheduler");
+dojo.require("dojox.gfx3d.vector");
+dojo.require("dojox.gfx3d.gradient");
+var out=function(o,x){
+if(arguments.length>1){
+o=x;
+}
+var e={};
+for(var i in o){
+if(i in e){
+continue;
+}
+}
+};
+dojo.declare("dojox.gfx3d.Object",null,{constructor:function(){
+this.object=null;
+this.matrix=null;
+this.cache=null;
+this.renderer=null;
+this.parent=null;
+this.strokeStyle=null;
+this.fillStyle=null;
+this.shape=null;
+},setObject:function(_5){
+this.object=dojox.gfx.makeParameters(this.object,_5);
+return this;
+},setTransform:function(_6){
+this.matrix=dojox.gfx3d.matrix.clone(_6?dojox.gfx3d.matrix.normalize(_6):dojox.gfx3d.identity,true);
+return this;
+},applyRightTransform:function(_7){
+return _7?this.setTransform([this.matrix,_7]):this;
+},applyLeftTransform:function(_8){
+return _8?this.setTransform([_8,this.matrix]):this;
+},applyTransform:function(_9){
+return _9?this.setTransform([this.matrix,_9]):this;
+},setFill:function(_a){
+this.fillStyle=_a;
+return this;
+},setStroke:function(_b){
+this.strokeStyle=_b;
+return this;
+},toStdFill:function(_c,_d){
+return (this.fillStyle&&typeof this.fillStyle["type"]!="undefined")?_c[this.fillStyle.type](_d,this.fillStyle.finish,this.fillStyle.color):this.fillStyle;
+},invalidate:function(){
+this.renderer.addTodo(this);
+},destroy:function(){
+if(this.shape){
+var p=this.shape.getParent();
+if(p){
+p.remove(this.shape);
+}
+this.shape=null;
+}
+},render:function(_f){
+throw "Pure virtual function, not implemented";
+},draw:function(_10){
+throw "Pure virtual function, not implemented";
+},getZOrder:function(){
+return 0;
+},getOutline:function(){
+return null;
+}});
+dojo.declare("dojox.gfx3d.Scene",dojox.gfx3d.Object,{constructor:function(){
+this.objects=[];
+this.todos=[];
+this.schedule=dojox.gfx3d.scheduler.zOrder;
+this._draw=dojox.gfx3d.drawer.conservative;
+},setFill:function(_11){
+this.fillStyle=_11;
+dojo.forEach(this.objects,function(_12){
+_12.setFill(_11);
+});
+return this;
+},setStroke:function(_13){
+this.strokeStyle=_13;
+dojo.forEach(this.objects,function(_14){
+_14.setStroke(_13);
+});
+return this;
+},render:function(_15,_16){
+var m=dojox.gfx3d.matrix.multiply(_15,this.matrix);
+if(_16){
+this.todos=this.objects;
+}
+dojo.forEach(this.todos,function(_18){
+_18.render(m,_16);
+});
+},draw:function(_19){
+this.objects=this.schedule(this.objects);
+this._draw(this.todos,this.objects,this.renderer);
+},addTodo:function(_1a){
+if(dojo.every(this.todos,function(_1b){
+return _1b!=_1a;
+})){
+this.todos.push(_1a);
+this.invalidate();
+}
+},invalidate:function(){
+this.parent.addTodo(this);
+},getZOrder:function(){
+var _1c=0;
+dojo.forEach(this.objects,function(_1d){
+_1c+=_1d.getZOrder();
+});
+return (this.objects.length>1)?_1c/this.objects.length:0;
+}});
+dojo.declare("dojox.gfx3d.Edges",dojox.gfx3d.Object,{constructor:function(){
+this.object=dojo.clone(dojox.gfx3d.defaultEdges);
+},setObject:function(_1e,_1f){
+this.object=dojox.gfx.makeParameters(this.object,(_1e instanceof Array)?{points:_1e,style:_1f}:_1e);
+return this;
+},getZOrder:function(){
+var _20=0;
+dojo.forEach(this.cache,function(_21){
+_20+=_21.z;
+});
+return (this.cache.length>1)?_20/this.cache.length:0;
+},render:function(_22){
+var m=dojox.gfx3d.matrix.multiply(_22,this.matrix);
+this.cache=dojo.map(this.object.points,function(_24){
+return dojox.gfx3d.matrix.multiplyPoint(m,_24);
+});
+},draw:function(){
+var c=this.cache;
+if(this.shape){
+this.shape.setShape("");
+}else{
+this.shape=this.renderer.createPath();
+}
+var p=this.shape.setAbsoluteMode("absolute");
+if(this.object.style=="strip"||this.object.style=="loop"){
+p.moveTo(c[0].x,c[0].y);
+dojo.forEach(c.slice(1),function(_27){
+p.lineTo(_27.x,_27.y);
+});
+if(this.object.style=="loop"){
+p.closePath();
+}
+}else{
+for(var i=0;i<this.cache.length;){
+p.moveTo(c[i].x,c[i].y);
+i++;
+p.lineTo(c[i].x,c[i].y);
+i++;
+}
+}
+p.setStroke(this.strokeStyle);
+}});
+dojo.declare("dojox.gfx3d.Orbit",dojox.gfx3d.Object,{constructor:function(){
+this.object=dojo.clone(dojox.gfx3d.defaultOrbit);
+},render:function(_29){
+var m=dojox.gfx3d.matrix.multiply(_29,this.matrix);
+var _2b=[0,Math.PI/4,Math.PI/3];
+var _2c=dojox.gfx3d.matrix.multiplyPoint(m,this.object.center);
+var _2d=dojo.map(_2b,function(_2e){
+return {x:this.center.x+this.radius*Math.cos(_2e),y:this.center.y+this.radius*Math.sin(_2e),z:this.center.z};
+},this.object);
+_2d=dojo.map(_2d,function(_2f){
+return dojox.gfx3d.matrix.multiplyPoint(m,_2f);
+});
+var _30=dojox.gfx3d.vector.normalize(_2d);
+_2d=dojo.map(_2d,function(_31){
+return dojox.gfx3d.vector.substract(_31,_2c);
+});
+var A={xx:_2d[0].x*_2d[0].y,xy:_2d[0].y*_2d[0].y,xz:1,yx:_2d[1].x*_2d[1].y,yy:_2d[1].y*_2d[1].y,yz:1,zx:_2d[2].x*_2d[2].y,zy:_2d[2].y*_2d[2].y,zz:1,dx:0,dy:0,dz:0};
+var B=dojo.map(_2d,function(_34){
+return -Math.pow(_34.x,2);
+});
+var X=dojox.gfx3d.matrix.multiplyPoint(dojox.gfx3d.matrix.invert(A),B[0],B[1],B[2]);
+var _36=Math.atan2(X.x,1-X.y)/2;
+var _37=dojo.map(_2d,function(_38){
+return dojox.gfx.matrix.multiplyPoint(dojox.gfx.matrix.rotate(-_36),_38.x,_38.y);
+});
+var a=Math.pow(_37[0].x,2);
+var b=Math.pow(_37[0].y,2);
+var c=Math.pow(_37[1].x,2);
+var d=Math.pow(_37[1].y,2);
+var rx=Math.sqrt((a*d-b*c)/(d-b));
+var ry=Math.sqrt((a*d-b*c)/(a-c));
+this.cache={cx:_2c.x,cy:_2c.y,rx:rx,ry:ry,theta:_36,normal:_30};
+},draw:function(_3f){
+if(this.shape){
+this.shape.setShape(this.cache);
+}else{
+this.shape=this.renderer.createEllipse(this.cache);
+}
+this.shape.applyTransform(dojox.gfx.matrix.rotateAt(this.cache.theta,this.cache.cx,this.cache.cy)).setStroke(this.strokeStyle).setFill(this.toStdFill(_3f,this.cache.normal));
+}});
+dojo.declare("dojox.gfx3d.Path3d",dojox.gfx3d.Object,{constructor:function(){
+this.object=dojo.clone(dojox.gfx3d.defaultPath3d);
+this.segments=[];
+this.absolute=true;
+this.last={};
+this.path="";
+},_collectArgs:function(_40,_41){
+for(var i=0;i<_41.length;++i){
+var t=_41[i];
+if(typeof (t)=="boolean"){
+_40.push(t?1:0);
+}else{
+if(typeof (t)=="number"){
+_40.push(t);
+}else{
+if(t instanceof Array){
+this._collectArgs(_40,t);
+}else{
+if("x" in t&&"y" in t){
+_40.push(t.x);
+_40.push(t.y);
+}
+}
+}
+}
+}
+},_validSegments:{m:3,l:3,z:0},_pushSegment:function(_44,_45){
+var _46=this._validSegments[_44.toLowerCase()],_47;
+if(typeof (_46)=="number"){
+if(_46){
+if(_45.length>=_46){
+_47={action:_44,args:_45.slice(0,_45.length-_45.length%_46)};
+this.segments.push(_47);
+}
+}else{
+_47={action:_44,args:[]};
+this.segments.push(_47);
+}
+}
+},moveTo:function(){
+var _48=[];
+this._collectArgs(_48,arguments);
+this._pushSegment(this.absolute?"M":"m",_48);
+return this;
+},lineTo:function(){
+var _49=[];
+this._collectArgs(_49,arguments);
+this._pushSegment(this.absolute?"L":"l",_49);
+return this;
+},closePath:function(){
+this._pushSegment("Z",[]);
+return this;
+},render:function(_4a){
+var m=dojox.gfx3d.matrix.multiply(_4a,this.matrix);
+var _4c="";
+var _4d=this._validSegments;
+dojo.forEach(this.segments,function(_4e){
+_4c+=_4e.action;
+for(var i=0;i<_4e.args.length;i+=_4d[_4e.action.toLowerCase()]){
+var pt=dojox.gfx3d.matrix.multiplyPoint(m,_4e.args[i],_4e.args[i+1],_4e.args[i+2]);
+_4c+=" "+pt.x+" "+pt.y;
+}
+});
+this.cache=_4c;
+},_draw:function(){
+return this.parent.createPath(this.cache);
+}});
+dojo.declare("dojox.gfx3d.Triangles",dojox.gfx3d.Object,{constructor:function(){
+this.object=dojo.clone(dojox.gfx3d.defaultTriangles);
+},setObject:function(_51,_52){
+if(_51 instanceof Array){
+this.object=dojox.gfx.makeParameters(this.object,{points:_51,style:_52});
+}else{
+this.object=dojox.gfx.makeParameters(this.object,_51);
+}
+return this;
+},render:function(_53){
+var m=dojox.gfx3d.matrix.multiply(_53,this.matrix);
+var c=dojo.map(this.object.points,function(_56){
+return dojox.gfx3d.matrix.multiplyPoint(m,_56);
+});
+this.cache=[];
+var _57=c.slice(0,2);
+var _58=c[0];
+if(this.object.style=="strip"){
+dojo.forEach(c.slice(2),function(_59){
+_57.push(_59);
+_57.push(_57[0]);
+this.cache.push(_57);
+_57=_57.slice(1,3);
+},this);
+}else{
+if(this.object.style=="fan"){
+dojo.forEach(c.slice(2),function(_5a){
+_57.push(_5a);
+_57.push(_58);
+this.cache.push(_57);
+_57=[_58,_5a];
+},this);
+}else{
+for(var i=0;i<c.length;){
+this.cache.push([c[i],c[i+1],c[i+2],c[i]]);
+i+=3;
+}
+}
+}
+},draw:function(_5c){
+this.cache=dojox.gfx3d.scheduler.bsp(this.cache,function(it){
+return it;
+});
+if(this.shape){
+this.shape.clear();
+}else{
+this.shape=this.renderer.createGroup();
+}
+dojo.forEach(this.cache,function(_5e){
+this.shape.createPolyline(_5e).setStroke(this.strokeStyle).setFill(this.toStdFill(_5c,dojox.gfx3d.vector.normalize(_5e)));
+},this);
+},getZOrder:function(){
+var _5f=0;
+dojo.forEach(this.cache,function(_60){
+_5f+=(_60[0].z+_60[1].z+_60[2].z)/3;
+});
+return (this.cache.length>1)?_5f/this.cache.length:0;
+}});
+dojo.declare("dojox.gfx3d.Quads",dojox.gfx3d.Object,{constructor:function(){
+this.object=dojo.clone(dojox.gfx3d.defaultQuads);
+},setObject:function(_61,_62){
+this.object=dojox.gfx.makeParameters(this.object,(_61 instanceof Array)?{points:_61,style:_62}:_61);
+return this;
+},render:function(_63){
+var m=dojox.gfx3d.matrix.multiply(_63,this.matrix),i;
+var c=dojo.map(this.object.points,function(_67){
+return dojox.gfx3d.matrix.multiplyPoint(m,_67);
+});
+this.cache=[];
+if(this.object.style=="strip"){
+var _68=c.slice(0,2);
+for(i=2;i<c.length;){
+_68=_68.concat([c[i],c[i+1],_68[0]]);
+this.cache.push(_68);
+_68=_68.slice(2,4);
+i+=2;
+}
+}else{
+for(i=0;i<c.length;){
+this.cache.push([c[i],c[i+1],c[i+2],c[i+3],c[i]]);
+i+=4;
+}
+}
+},draw:function(_69){
+this.cache=dojox.gfx3d.scheduler.bsp(this.cache,function(it){
+return it;
+});
+if(this.shape){
+this.shape.clear();
+}else{
+this.shape=this.renderer.createGroup();
+}
+for(var x=0;x<this.cache.length;x++){
+this.shape.createPolyline(this.cache[x]).setStroke(this.strokeStyle).setFill(this.toStdFill(_69,dojox.gfx3d.vector.normalize(this.cache[x])));
+}
+},getZOrder:function(){
+var _6c=0;
+for(var x=0;x<this.cache.length;x++){
+var i=this.cache[x];
+_6c+=(i[0].z+i[1].z+i[2].z+i[3].z)/4;
+}
+return (this.cache.length>1)?_6c/this.cache.length:0;
+}});
+dojo.declare("dojox.gfx3d.Polygon",dojox.gfx3d.Object,{constructor:function(){
+this.object=dojo.clone(dojox.gfx3d.defaultPolygon);
+},setObject:function(_6f){
+this.object=dojox.gfx.makeParameters(this.object,(_6f instanceof Array)?{path:_6f}:_6f);
+return this;
+},render:function(_70){
+var m=dojox.gfx3d.matrix.multiply(_70,this.matrix);
+this.cache=dojo.map(this.object.path,function(_72){
+return dojox.gfx3d.matrix.multiplyPoint(m,_72);
+});
+this.cache.push(this.cache[0]);
+},draw:function(_73){
+if(this.shape){
+this.shape.setShape({points:this.cache});
+}else{
+this.shape=this.renderer.createPolyline({points:this.cache});
+}
+this.shape.setStroke(this.strokeStyle).setFill(this.toStdFill(_73,dojox.gfx3d.matrix.normalize(this.cache)));
+},getZOrder:function(){
+var _74=0;
+for(var x=0;x<this.cache.length;x++){
+_74+=this.cache[x].z;
+}
+return (this.cache.length>1)?_74/this.cache.length:0;
+},getOutline:function(){
+return this.cache.slice(0,3);
+}});
+dojo.declare("dojox.gfx3d.Cube",dojox.gfx3d.Object,{constructor:function(){
+this.object=dojo.clone(dojox.gfx3d.defaultCube);
+this.polygons=[];
+},setObject:function(_76){
+this.object=dojox.gfx.makeParameters(this.object,_76);
+},render:function(_77){
+var a=this.object.top;
+var g=this.object.bottom;
+var b={x:g.x,y:a.y,z:a.z};
+var c={x:g.x,y:g.y,z:a.z};
+var d={x:a.x,y:g.y,z:a.z};
+var e={x:a.x,y:a.y,z:g.z};
+var f={x:g.x,y:a.y,z:g.z};
+var h={x:a.x,y:g.y,z:g.z};
+var _80=[a,b,c,d,e,f,g,h];
+var m=dojox.gfx3d.matrix.multiply(_77,this.matrix);
+var p=dojo.map(_80,function(_83){
+return dojox.gfx3d.matrix.multiplyPoint(m,_83);
+});
+a=p[0];
+b=p[1];
+c=p[2];
+d=p[3];
+e=p[4];
+f=p[5];
+g=p[6];
+h=p[7];
+this.cache=[[a,b,c,d,a],[e,f,g,h,e],[a,d,h,e,a],[d,c,g,h,d],[c,b,f,g,c],[b,a,e,f,b]];
+},draw:function(_84){
+this.cache=dojox.gfx3d.scheduler.bsp(this.cache,function(it){
+return it;
+});
+var _86=this.cache.slice(3);
+if(this.shape){
+this.shape.clear();
+}else{
+this.shape=this.renderer.createGroup();
+}
+for(var x=0;x<_86.length;x++){
+this.shape.createPolyline(_86[x]).setStroke(this.strokeStyle).setFill(this.toStdFill(_84,dojox.gfx3d.vector.normalize(_86[x])));
+}
+},getZOrder:function(){
+var top=this.cache[0][0];
+var _89=this.cache[1][2];
+return (top.z+_89.z)/2;
+}});
+dojo.declare("dojox.gfx3d.Cylinder",dojox.gfx3d.Object,{constructor:function(){
+this.object=dojo.clone(dojox.gfx3d.defaultCylinder);
+},render:function(_8a){
+var m=dojox.gfx3d.matrix.multiply(_8a,this.matrix);
+var _8c=[0,Math.PI/4,Math.PI/3];
+var _8d=dojox.gfx3d.matrix.multiplyPoint(m,this.object.center);
+var _8e=dojo.map(_8c,function(_8f){
+return {x:this.center.x+this.radius*Math.cos(_8f),y:this.center.y+this.radius*Math.sin(_8f),z:this.center.z};
+},this.object);
+_8e=dojo.map(_8e,function(_90){
+return dojox.gfx3d.vector.substract(dojox.gfx3d.matrix.multiplyPoint(m,_90),_8d);
+});
+var A={xx:_8e[0].x*_8e[0].y,xy:_8e[0].y*_8e[0].y,xz:1,yx:_8e[1].x*_8e[1].y,yy:_8e[1].y*_8e[1].y,yz:1,zx:_8e[2].x*_8e[2].y,zy:_8e[2].y*_8e[2].y,zz:1,dx:0,dy:0,dz:0};
+var B=dojo.map(_8e,function(_93){
+return -Math.pow(_93.x,2);
+});
+var X=dojox.gfx3d.matrix.multiplyPoint(dojox.gfx3d.matrix.invert(A),B[0],B[1],B[2]);
+var _95=Math.atan2(X.x,1-X.y)/2;
+var _96=dojo.map(_8e,function(_97){
+return dojox.gfx.matrix.multiplyPoint(dojox.gfx.matrix.rotate(-_95),_97.x,_97.y);
+});
+var a=Math.pow(_96[0].x,2);
+var b=Math.pow(_96[0].y,2);
+var c=Math.pow(_96[1].x,2);
+var d=Math.pow(_96[1].y,2);
+var rx=Math.sqrt((a*d-b*c)/(d-b));
+var ry=Math.sqrt((a*d-b*c)/(a-c));
+if(rx<ry){
+var t=rx;
+rx=ry;
+ry=t;
+_95-=Math.PI/2;
+}
+var top=dojox.gfx3d.matrix.multiplyPoint(m,dojox.gfx3d.vector.sum(this.object.center,{x:0,y:0,z:this.object.height}));
+var _a0=this.fillStyle.type=="constant"?this.fillStyle.color:dojox.gfx3d.gradient(this.renderer.lighting,this.fillStyle,this.object.center,this.object.radius,Math.PI,2*Math.PI,m);
+if(isNaN(rx)||isNaN(ry)||isNaN(_95)){
+rx=this.object.radius,ry=0,_95=0;
+}
+this.cache={center:_8d,top:top,rx:rx,ry:ry,theta:_95,gradient:_a0};
+},draw:function(){
+var c=this.cache,v=dojox.gfx3d.vector,m=dojox.gfx.matrix,_a4=[c.center,c.top],_a5=v.substract(c.top,c.center);
+if(v.dotProduct(_a5,this.renderer.lighting.incident)>0){
+_a4=[c.top,c.center];
+_a5=v.substract(c.center,c.top);
+}
+var _a6=this.renderer.lighting[this.fillStyle.type](_a5,this.fillStyle.finish,this.fillStyle.color),d=Math.sqrt(Math.pow(c.center.x-c.top.x,2)+Math.pow(c.center.y-c.top.y,2));
+if(this.shape){
+this.shape.clear();
+}else{
+this.shape=this.renderer.createGroup();
+}
+this.shape.createPath("").moveTo(0,-c.rx).lineTo(d,-c.rx).lineTo(d,c.rx).lineTo(0,c.rx).arcTo(c.ry,c.rx,0,true,true,0,-c.rx).setFill(c.gradient).setStroke(this.strokeStyle).setTransform([m.translate(_a4[0]),m.rotate(Math.atan2(_a4[1].y-_a4[0].y,_a4[1].x-_a4[0].x))]);
+if(c.rx>0&&c.ry>0){
+this.shape.createEllipse({cx:_a4[1].x,cy:_a4[1].y,rx:c.rx,ry:c.ry}).setFill(_a6).setStroke(this.strokeStyle).applyTransform(m.rotateAt(c.theta,_a4[1]));
+}
+}});
+dojo.declare("dojox.gfx3d.Viewport",dojox.gfx.Group,{constructor:function(){
+this.dimension=null;
+this.objects=[];
+this.todos=[];
+this.renderer=this;
+this.schedule=dojox.gfx3d.scheduler.zOrder;
+this.draw=dojox.gfx3d.drawer.conservative;
+this.deep=false;
+this.lights=[];
+this.lighting=null;
+},setCameraTransform:function(_a8){
+this.camera=dojox.gfx3d.matrix.clone(_a8?dojox.gfx3d.matrix.normalize(_a8):dojox.gfx3d.identity,true);
+this.invalidate();
+return this;
+},applyCameraRightTransform:function(_a9){
+return _a9?this.setCameraTransform([this.camera,_a9]):this;
+},applyCameraLeftTransform:function(_aa){
+return _aa?this.setCameraTransform([_aa,this.camera]):this;
+},applyCameraTransform:function(_ab){
+return this.applyCameraRightTransform(_ab);
+},setLights:function(_ac,_ad,_ae){
+this.lights=(_ac instanceof Array)?{sources:_ac,ambient:_ad,specular:_ae}:_ac;
+var _af={x:0,y:0,z:1};
+this.lighting=new dojox.gfx3d.lighting.Model(_af,this.lights.sources,this.lights.ambient,this.lights.specular);
+this.invalidate();
+return this;
+},addLights:function(_b0){
+return this.setLights(this.lights.sources.concat(_b0));
+},addTodo:function(_b1){
+if(dojo.every(this.todos,function(_b2){
+return _b2!=_b1;
+})){
+this.todos.push(_b1);
+}
+},invalidate:function(){
+this.deep=true;
+this.todos=this.objects;
+},setDimensions:function(dim){
+if(dim){
+var w=dojo.isString(dim.width)?parseInt(dim.width):dim.width;
+var h=dojo.isString(dim.height)?parseInt(dim.height):dim.height;
+var trs=this.rawNode.style;
+trs.height=h;
+trs.width=w;
+this.dimension={width:w,height:h};
+}else{
+this.dimension=null;
+}
+},render:function(){
+if(!this.todos.length){
+return;
+}
+var m=dojox.gfx3d.matrix;
+for(var x=0;x<this.todos.length;x++){
+this.todos[x].render(dojox.gfx3d.matrix.normalize([m.cameraRotateXg(180),m.cameraTranslate(0,this.dimension.height,0),this.camera]),this.deep);
+}
+this.objects=this.schedule(this.objects);
+this.draw(this.todos,this.objects,this);
+this.todos=[];
+this.deep=false;
+}});
+dojox.gfx3d.Viewport.nodeType=dojox.gfx.Group.nodeType;
+dojox.gfx3d._creators={createEdges:function(_b9,_ba){
+return this.create3DObject(dojox.gfx3d.Edges,_b9,_ba);
+},createTriangles:function(_bb,_bc){
+return this.create3DObject(dojox.gfx3d.Triangles,_bb,_bc);
+},createQuads:function(_bd,_be){
+return this.create3DObject(dojox.gfx3d.Quads,_bd,_be);
+},createPolygon:function(_bf){
+return this.create3DObject(dojox.gfx3d.Polygon,_bf);
+},createOrbit:function(_c0){
+return this.create3DObject(dojox.gfx3d.Orbit,_c0);
+},createCube:function(_c1){
+return this.create3DObject(dojox.gfx3d.Cube,_c1);
+},createCylinder:function(_c2){
+return this.create3DObject(dojox.gfx3d.Cylinder,_c2);
+},createPath3d:function(_c3){
+return this.create3DObject(dojox.gfx3d.Path3d,_c3);
+},createScene:function(){
+return this.create3DObject(dojox.gfx3d.Scene);
+},create3DObject:function(_c4,_c5,_c6){
+var obj=new _c4();
+this.adopt(obj);
+if(_c5){
+obj.setObject(_c5,_c6);
+}
+return obj;
+},adopt:function(obj){
+obj.renderer=this.renderer;
+obj.parent=this;
+this.objects.push(obj);
+this.addTodo(obj);
+return this;
+},abandon:function(obj,_ca){
+for(var i=0;i<this.objects.length;++i){
+if(this.objects[i]==obj){
+this.objects.splice(i,1);
+}
+}
+obj.parent=null;
+return this;
+},setScheduler:function(_cc){
+this.schedule=_cc;
+},setDrawer:function(_cd){
+this.draw=_cd;
+}};
+dojo.extend(dojox.gfx3d.Viewport,dojox.gfx3d._creators);
+dojo.extend(dojox.gfx3d.Scene,dojox.gfx3d._creators);
+delete dojox.gfx3d._creators;
+dojo.extend(dojox.gfx.Surface,{createViewport:function(){
+var _ce=this.createObject(dojox.gfx3d.Viewport,null,true);
+_ce.setDimensions(this.getDimensions());
+return _ce;
+}});
+}
diff --git a/dojox/gfx3d/scheduler.js b/dojox/gfx3d/scheduler.js
new file mode 100644
index 0000000..637aad3
--- /dev/null
+++ b/dojox/gfx3d/scheduler.js
@@ -0,0 +1,93 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx3d.scheduler"]){
+dojo._hasResource["dojox.gfx3d.scheduler"]=true;
+dojo.provide("dojox.gfx3d.scheduler");
+dojo.provide("dojox.gfx3d.drawer");
+dojo.require("dojox.gfx3d.vector");
+dojo.mixin(dojox.gfx3d.scheduler,{zOrder:function(_1,_2){
+_2=_2?_2:dojox.gfx3d.scheduler.order;
+_1.sort(function(a,b){
+return _2(b)-_2(a);
+});
+return _1;
+},bsp:function(_5,_6){
+_6=_6?_6:dojox.gfx3d.scheduler.outline;
+var p=new dojox.gfx3d.scheduler.BinarySearchTree(_5[0],_6);
+dojo.forEach(_5.slice(1),function(_8){
+p.add(_8,_6);
+});
+return p.iterate(_6);
+},order:function(it){
+return it.getZOrder();
+},outline:function(it){
+return it.getOutline();
+}});
+dojo.declare("dojox.gfx3d.scheduler.BinarySearchTree",null,{constructor:function(_b,_c){
+this.plus=null;
+this.minus=null;
+this.object=_b;
+var o=_c(_b);
+this.orient=o[0];
+this.normal=dojox.gfx3d.vector.normalize(o);
+},add:function(_e,_f){
+var _10=0.5,o=_f(_e),v=dojox.gfx3d.vector,n=this.normal,a=this.orient,BST=dojox.gfx3d.scheduler.BinarySearchTree;
+if(dojo.every(o,function(_16){
+return Math.floor(_10+v.dotProduct(n,v.substract(_16,a)))<=0;
+})){
+if(this.minus){
+this.minus.add(_e,_f);
+}else{
+this.minus=new BST(_e,_f);
+}
+}else{
+if(dojo.every(o,function(_17){
+return Math.floor(_10+v.dotProduct(n,v.substract(_17,a)))>=0;
+})){
+if(this.plus){
+this.plus.add(_e,_f);
+}else{
+this.plus=new BST(_e,_f);
+}
+}else{
+throw "The case: polygon cross siblings' plate is not implemneted yet";
+}
+}
+},iterate:function(_18){
+var _19=0.5;
+var v=dojox.gfx3d.vector;
+var _1b=[];
+var _1c=null;
+var _1d={x:0,y:0,z:-10000};
+if(Math.floor(_19+v.dotProduct(this.normal,v.substract(_1d,this.orient)))<=0){
+_1c=[this.plus,this.minus];
+}else{
+_1c=[this.minus,this.plus];
+}
+if(_1c[0]){
+_1b=_1b.concat(_1c[0].iterate());
+}
+_1b.push(this.object);
+if(_1c[1]){
+_1b=_1b.concat(_1c[1].iterate());
+}
+return _1b;
+}});
+dojo.mixin(dojox.gfx3d.drawer,{conservative:function(_1e,_1f,_20){
+dojo.forEach(this.objects,function(_21){
+_21.destroy();
+});
+dojo.forEach(_1f,function(_22){
+_22.draw(_20.lighting);
+});
+},chart:function(_23,_24,_25){
+dojo.forEach(this.todos,function(_26){
+_26.draw(_25.lighting);
+});
+}});
+}
diff --git a/dojox/gfx3d/vector.js b/dojox/gfx3d/vector.js
new file mode 100644
index 0000000..a1930cd
--- /dev/null
+++ b/dojox/gfx3d/vector.js
@@ -0,0 +1,61 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.gfx3d.vector"]){
+dojo._hasResource["dojox.gfx3d.vector"]=true;
+dojo.provide("dojox.gfx3d.vector");
+dojo.mixin(dojox.gfx3d.vector,{sum:function(){
+var v={x:0,y:0,z:0};
+dojo.forEach(arguments,function(_2){
+v.x+=_2.x;
+v.y+=_2.y;
+v.z+=_2.z;
+});
+return v;
+},center:function(){
+var l=arguments.length;
+if(l==0){
+return {x:0,y:0,z:0};
+}
+var v=dojox.gfx3d.vector.sum(arguments);
+return {x:v.x/l,y:v.y/l,z:v.z/l};
+},substract:function(a,b){
+return {x:a.x-b.x,y:a.y-b.y,z:a.z-b.z};
+},_crossProduct:function(x,y,z,u,v,w){
+return {x:y*w-z*v,y:z*u-x*w,z:x*v-y*u};
+},crossProduct:function(a,b,c,d,e,f){
+if(arguments.length==6&&dojo.every(arguments,function(_13){
+return typeof _13=="number";
+})){
+return dojox.gfx3d.vector._crossProduct(a,b,c,d,e,f);
+}
+return dojox.gfx3d.vector._crossProduct(a.x,a.y,a.z,b.x,b.y,b.z);
+},_dotProduct:function(x,y,z,u,v,w){
+return x*u+y*v+z*w;
+},dotProduct:function(a,b,c,d,e,f){
+if(arguments.length==6&&dojo.every(arguments,function(_20){
+return typeof _20=="number";
+})){
+return dojox.gfx3d.vector._dotProduct(a,b,c,d,e,f);
+}
+return dojox.gfx3d.vector._dotProduct(a.x,a.y,a.z,b.x,b.y,b.z);
+},normalize:function(a,b,c){
+var l,m,n;
+if(a instanceof Array){
+l=a[0];
+m=a[1];
+n=a[2];
+}else{
+l=a;
+m=b;
+n=c;
+}
+var u=dojox.gfx3d.vector.substract(m,l);
+var v=dojox.gfx3d.vector.substract(n,l);
+return dojox.gfx3d.vector.crossProduct(u,v);
+}});
+}
diff --git a/dojox/grid/DataGrid.js b/dojox/grid/DataGrid.js
new file mode 100644
index 0000000..69f19da
--- /dev/null
+++ b/dojox/grid/DataGrid.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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 a compiled version of Dojo, built for deployment and not for
+	development. To get an editable version, please visit:
+
+		http://dojotoolkit.org
+
+	for documentation and information on getting the source.
+*/
+
+if(!dojo._hasResource["dijit._base.focus"]){dojo._hasResource["dijit._base.focus"]=true;dojo.provide("dijit._base.focus");dojo.mixin(dijit,{_curFocus:null,_prevFocus:null,isCollapsed:function(){var _1=dojo.doc;if(_1.selection){var s=_1.selection;if(s.type=="Text"){return !s.createRange().htmlText.length;}else{return !s.createRange().length;}}else{var _3=dojo.global;var _4=_3.getSelection();if(dojo.isString(_4)){return !_4;}else{return !_4||_4.isCollapsed||!_4.toString();}}},getBookmark:f [...]
diff --git a/dojox/grid/DataGrid.js.uncompressed.js b/dojox/grid/DataGrid.js.uncompressed.js
new file mode 100644
index 0000000..73abb88
--- /dev/null
+++ b/dojox/grid/DataGrid.js.uncompressed.js
@@ -0,0 +1,14589 @@
+/*
+	Copyright (c) 2004-2009, 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 a compiled version of Dojo, built for deployment and not for
+	development. To get an editable version, please visit:
+
+		http://dojotoolkit.org
+
+	for documentation and information on getting the source.
+*/
+
+if(!dojo._hasResource["dijit._base.focus"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.focus"] = true;
+dojo.provide("dijit._base.focus");
+
+// summary:
+//		These functions are used to query or set the focus and selection.
+//
+//		Also, they trace when widgets become actived/deactivated,
+//		so that the widget can fire _onFocus/_onBlur events.
+//		"Active" here means something similar to "focused", but
+//		"focus" isn't quite the right word because we keep track of
+//		a whole stack of "active" widgets.  Example:  Combobutton --> Menu -->
+//		MenuItem.   The onBlur event for Combobutton doesn't fire due to focusing
+//		on the Menu or a MenuItem, since they are considered part of the
+//		Combobutton widget.  It only happens when focus is shifted
+//		somewhere completely different.
+
+dojo.mixin(dijit,
+{
+	// _curFocus: DomNode
+	//		Currently focused item on screen
+	_curFocus: null,
+
+	// _prevFocus: DomNode
+	//		Previously focused item on screen
+	_prevFocus: null,
+
+	isCollapsed: function(){
+		// summary:
+		//		Returns true if there is no text selected
+		var _document = dojo.doc;
+		if(_document.selection){ // IE
+			var s=_document.selection;
+			if(s.type=='Text'){
+				return !s.createRange().htmlText.length; // Boolean
+			}else{ //Control range
+				return !s.createRange().length; // Boolean
+			}
+		}else{
+			var _window = dojo.global;
+			var selection = _window.getSelection();
+			
+			if(dojo.isString(selection)){ // Safari
+				// TODO: this is dead code; safari is taking the else branch.  remove after 1.3.
+				return !selection; // Boolean
+			}else{ // Mozilla/W3
+				return !selection || selection.isCollapsed || !selection.toString(); // Boolean
+			}
+		}
+	},
+
+	getBookmark: function(){
+		// summary:
+		//		Retrieves a bookmark that can be used with moveToBookmark to return to the same range
+		var bookmark, selection = dojo.doc.selection;
+		if(selection){ // IE
+			var range = selection.createRange();
+			if(selection.type.toUpperCase()=='CONTROL'){
+				if(range.length){
+					bookmark=[];
+					var i=0,len=range.length;
+					while(i<len){
+						bookmark.push(range.item(i++));
+					}
+				}else{
+					bookmark=null;
+				}
+			}else{
+				bookmark = range.getBookmark();
+			}
+		}else{
+			if(window.getSelection){
+				selection = dojo.global.getSelection();
+				if(selection){
+					range = selection.getRangeAt(0);
+					bookmark = range.cloneRange();
+				}
+			}else{
+				console.warn("No idea how to store the current selection for this browser!");
+			}
+		}
+		return bookmark; // Array
+	},
+
+	moveToBookmark: function(/*Object*/bookmark){
+		// summary:
+		//		Moves current selection to a bookmark
+		// bookmark:
+		//		This should be a returned object from dojo.html.selection.getBookmark()
+		var _document = dojo.doc;
+		if(_document.selection){ // IE
+			var range;
+			if(dojo.isArray(bookmark)){
+				range = _document.body.createControlRange();
+				//range.addElement does not have call/apply method, so can not call it directly
+				//range is not available in "range.addElement(item)", so can't use that either
+				dojo.forEach(bookmark, function(n){
+					range.addElement(n);
+				});
+			}else{
+				range = _document.selection.createRange();
+				range.moveToBookmark(bookmark);
+			}
+			range.select();
+		}else{ //Moz/W3C
+			var selection = dojo.global.getSelection && dojo.global.getSelection();
+			if(selection && selection.removeAllRanges){
+				selection.removeAllRanges();
+				selection.addRange(bookmark);
+			}else{
+				console.warn("No idea how to restore selection for this browser!");
+			}
+		}
+	},
+
+	getFocus: function(/*Widget?*/menu, /*Window?*/openedForWindow){
+		// summary:
+		//		Returns the current focus and selection.
+		//		Called when a popup appears (either a top level menu or a dialog),
+		//		or when a toolbar/menubar receives focus
+		//
+		// menu:
+		//		The menu that's being opened
+		//
+		// openedForWindow:
+		//		iframe in which menu was opened
+		//
+		// returns:
+		//		A handle to restore focus/selection
+
+		return {
+			// Node to return focus to
+			node: menu && dojo.isDescendant(dijit._curFocus, menu.domNode) ? dijit._prevFocus : dijit._curFocus,
+
+			// Previously selected text
+			bookmark:
+				!dojo.withGlobal(openedForWindow||dojo.global, dijit.isCollapsed) ?
+				dojo.withGlobal(openedForWindow||dojo.global, dijit.getBookmark) :
+				null,
+
+			openedForWindow: openedForWindow
+		}; // Object
+	},
+
+	focus: function(/*Object || DomNode */ handle){
+		// summary:
+		//		Sets the focused node and the selection according to argument.
+		//		To set focus to an iframe's content, pass in the iframe itself.
+		// handle:
+		//		object returned by get(), or a DomNode
+
+		if(!handle){ return; }
+
+		var node = "node" in handle ? handle.node : handle,		// because handle is either DomNode or a composite object
+			bookmark = handle.bookmark,
+			openedForWindow = handle.openedForWindow;
+
+		// Set the focus
+		// Note that for iframe's we need to use the <iframe> to follow the parentNode chain,
+		// but we need to set focus to iframe.contentWindow
+		if(node){
+			var focusNode = (node.tagName.toLowerCase()=="iframe") ? node.contentWindow : node;
+			if(focusNode && focusNode.focus){
+				try{
+					// Gecko throws sometimes if setting focus is impossible,
+					// node not displayed or something like that
+					focusNode.focus();
+				}catch(e){/*quiet*/}
+			}			
+			dijit._onFocusNode(node);
+		}
+
+		// set the selection
+		// do not need to restore if current selection is not empty
+		// (use keyboard to select a menu item)
+		if(bookmark && dojo.withGlobal(openedForWindow||dojo.global, dijit.isCollapsed)){
+			if(openedForWindow){
+				openedForWindow.focus();
+			}
+			try{
+				dojo.withGlobal(openedForWindow||dojo.global, dijit.moveToBookmark, null, [bookmark]);
+			}catch(e){
+				/*squelch IE internal error, see http://trac.dojotoolkit.org/ticket/1984 */
+			}
+		}
+	},
+
+	// _activeStack: Array
+	//		List of currently active widgets (focused widget and it's ancestors)
+	_activeStack: [],
+
+	registerIframe: function(/*DomNode*/ iframe){
+		// summary:
+		//		Registers listeners on the specified iframe so that any click
+		//		or focus event on that iframe (or anything in it) is reported
+		//		as a focus/click event on the <iframe> itself.
+		// description:
+		//		Currently only used by editor.
+		dijit.registerWin(iframe.contentWindow, iframe);
+	},
+		
+
+	registerWin: function(/*Window?*/targetWindow, /*DomNode?*/ effectiveNode){
+		// summary:
+		//		Registers listeners on the specified window (either the main
+		//		window or an iframe's window) to detect when the user has clicked somewhere
+		//		or focused somewhere.
+		// description:
+		//		Users should call registerIframe() instead of this method.
+		// targetWindow:
+		//		If specified this is the window associated with the iframe,
+		//		i.e. iframe.contentWindow.
+		// effectiveNode:
+		//		If specified, report any focus events inside targetWindow as
+		//		an event on effectiveNode, rather than on evt.target.
+
+		// TODO: make this function private in 2.0; Editor/users should call registerIframe(),
+		// or if Editor stops using <iframe> altogether than we can probably just drop
+		// the whole public API.
+
+		dojo.connect(targetWindow.document, "onmousedown", function(evt){
+			dijit._justMouseDowned = true;
+			setTimeout(function(){ dijit._justMouseDowned = false; }, 0);
+			dijit._onTouchNode(effectiveNode||evt.target||evt.srcElement);
+		});
+		//dojo.connect(targetWindow, "onscroll", ???);
+
+		// Listen for blur and focus events on targetWindow's document.
+		// IIRC, I'm using attachEvent() rather than dojo.connect() because focus/blur events don't bubble
+		// through dojo.connect(), and also maybe to catch the focus events early, before onfocus handlers
+		// fire.
+		var doc = targetWindow.document;
+		if(doc){
+			if(dojo.isIE){
+				doc.attachEvent('onactivate', function(evt){
+					if(evt.srcElement.tagName.toLowerCase() != "#document"){
+						dijit._onFocusNode(effectiveNode||evt.srcElement);
+					}
+				});
+				doc.attachEvent('ondeactivate', function(evt){
+					dijit._onBlurNode(effectiveNode||evt.srcElement);
+				});
+			}else{
+				doc.addEventListener('focus', function(evt){
+					dijit._onFocusNode(effectiveNode||evt.target);
+				}, true);
+				doc.addEventListener('blur', function(evt){
+					dijit._onBlurNode(effectiveNode||evt.target);
+				}, true);
+			}
+		}
+		doc = null;	// prevent memory leak (apparent circular reference via closure)
+	},
+
+	_onBlurNode: function(/*DomNode*/ node){
+		// summary:
+		// 		Called when focus leaves a node.
+		//		Usually ignored, _unless_ it *isn't* follwed by touching another node,
+		//		which indicates that we tabbed off the last field on the page,
+		//		in which case every widget is marked inactive
+		dijit._prevFocus = dijit._curFocus;
+		dijit._curFocus = null;
+
+		if(dijit._justMouseDowned){
+			// the mouse down caused a new widget to be marked as active; this blur event
+			// is coming late, so ignore it.
+			return;
+		}
+
+		// if the blur event isn't followed by a focus event then mark all widgets as inactive.
+		if(dijit._clearActiveWidgetsTimer){
+			clearTimeout(dijit._clearActiveWidgetsTimer);
+		}
+		dijit._clearActiveWidgetsTimer = setTimeout(function(){
+			delete dijit._clearActiveWidgetsTimer;
+			dijit._setStack([]);
+			dijit._prevFocus = null;
+		}, 100);
+	},
+
+	_onTouchNode: function(/*DomNode*/ node){
+		// summary:
+		//		Callback when node is focused or mouse-downed
+
+		// ignore the recent blurNode event
+		if(dijit._clearActiveWidgetsTimer){
+			clearTimeout(dijit._clearActiveWidgetsTimer);
+			delete dijit._clearActiveWidgetsTimer;
+		}
+
+		// compute stack of active widgets (ex: ComboButton --> Menu --> MenuItem)
+		var newStack=[];
+		try{
+			while(node){
+				if(node.dijitPopupParent){
+					node=dijit.byId(node.dijitPopupParent).domNode;
+				}else if(node.tagName && node.tagName.toLowerCase()=="body"){
+					// is this the root of the document or just the root of an iframe?
+					if(node===dojo.body()){
+						// node is the root of the main document
+						break;
+					}
+					// otherwise, find the iframe this node refers to (can't access it via parentNode,
+					// need to do this trick instead). window.frameElement is supported in IE/FF/Webkit
+					node=dijit.getDocumentWindow(node.ownerDocument).frameElement;
+				}else{
+					var id = node.getAttribute && node.getAttribute("widgetId");
+					if(id){
+						newStack.unshift(id);
+					}
+					node=node.parentNode;
+				}
+			}
+		}catch(e){ /* squelch */ }
+
+		dijit._setStack(newStack);
+	},
+
+	_onFocusNode: function(/*DomNode*/ node){
+		// summary:
+		//		Callback when node is focused
+
+		if(!node){
+			return;
+		}
+
+		if(node.nodeType == 9){
+			// Ignore focus events on the document itself.  This is here so that
+			// (for example) clicking the up/down arrows of a spinner
+			// (which don't get focus) won't cause that widget to blur. (FF issue)
+			return;
+		}
+
+		dijit._onTouchNode(node);
+
+		if(node==dijit._curFocus){ return; }
+		if(dijit._curFocus){
+			dijit._prevFocus = dijit._curFocus;
+		}
+		dijit._curFocus = node;
+		dojo.publish("focusNode", [node]);
+	},
+
+	_setStack: function(newStack){
+		// summary:
+		//		The stack of active widgets has changed.  Send out appropriate events and records new stack.
+
+		var oldStack = dijit._activeStack;
+		dijit._activeStack = newStack;
+
+		// compare old stack to new stack to see how many elements they have in common
+		for(var nCommon=0; nCommon<Math.min(oldStack.length, newStack.length); nCommon++){
+			if(oldStack[nCommon] != newStack[nCommon]){
+				break;
+			}
+		}
+
+		// for all elements that have gone out of focus, send blur event
+		for(var i=oldStack.length-1; i>=nCommon; i--){
+			var widget = dijit.byId(oldStack[i]);
+			if(widget){
+				widget._focused = false;
+				widget._hasBeenBlurred = true;
+				if(widget._onBlur){
+					widget._onBlur();
+				}
+				if (widget._setStateClass){
+					widget._setStateClass();
+				}
+				dojo.publish("widgetBlur", [widget]);
+			}
+		}
+
+		// for all element that have come into focus, send focus event
+		for(i=nCommon; i<newStack.length; i++){
+			widget = dijit.byId(newStack[i]);
+			if(widget){
+				widget._focused = true;
+				if(widget._onFocus){
+					widget._onFocus();
+				}
+				if (widget._setStateClass){
+					widget._setStateClass();
+				}
+				dojo.publish("widgetFocus", [widget]);
+			}
+		}
+	}
+});
+
+// register top window and all the iframes it contains
+dojo.addOnLoad(function(){dijit.registerWin(window); });
+
+}
+
+if(!dojo._hasResource["dijit._base.manager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.manager"] = true;
+dojo.provide("dijit._base.manager");
+
+dojo.declare("dijit.WidgetSet", null, {
+	// summary:
+	//		A set of widgets indexed by id. A default instance of this class is 
+	//		available as `dijit.registry`
+	//
+	// example:
+	//		Create a small list of widgets:
+	//		|	var ws = new dijit.WidgetSet();
+	//		|	ws.add(dijit.byId("one"));
+	//		| 	ws.add(dijit.byId("two"));
+	//		|	// destroy both:
+	//		|	ws.forEach(function(w){ w.destroy(); });
+	//
+	// example:
+	//		Using dijit.registry:
+	//		|	dijit.registry.forEach(function(w){ /* do something */ });
+	
+	constructor: function(){
+		this._hash = {};
+	},
+
+	add: function(/*Widget*/ widget){
+		// summary:
+		//		Add a widget to this list. If a duplicate ID is detected, a error is thrown.
+		//
+		// widget: dijit._Widget
+		//		Any dijit._Widget subclass.
+		if(this._hash[widget.id]){
+			throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered");
+		}
+		this._hash[widget.id]=widget;
+	},
+
+	remove: function(/*String*/ id){
+		// summary:
+		//		Remove a widget from this WidgetSet. Does not destroy the widget; simply
+		//		removes the reference.
+		delete this._hash[id];
+	},
+
+	forEach: function(/*Function*/ func){
+		// summary:
+		//		Call specified function for each widget in this set.
+		//
+		// func:
+		//		A callback function to run for each item. Is passed a the widget.
+		//
+		// example:
+		//		Using the default `dijit.registry` instance:
+		//		|	dijit.registry.forEach(function(widget){
+		//		|			
+		//		|	});
+		for(var id in this._hash){
+			func(this._hash[id]);
+		}
+	},
+
+	filter: function(/*Function*/ filter){
+		// summary:
+		//		Filter down this WidgetSet to a smaller new WidgetSet
+		//		Works the same as `dojo.filter` and `dojo.NodeList.filter`
+		//		
+		// filter:
+		//		Callback function to test truthiness.
+		//
+		// example:
+		//		Arbitrary: select the odd widgets in this list
+		//		|	var i = 0;
+		//		|	dijit.registry.filter(function(w){
+		//		|		return ++i % 2 == 0;
+		//		|	}).forEach(function(w){ /* odd ones */ });
+
+		var res = new dijit.WidgetSet();
+		this.forEach(function(widget){
+			if(filter(widget)){ res.add(widget); }
+		});
+		return res; // dijit.WidgetSet
+	},
+
+	byId: function(/*String*/ id){
+		// summary:
+		//		Find a widget in this list by it's id. 
+		// example:
+		//		Test if an id is in a particular WidgetSet
+		//		| var ws = new dijit.WidgetSet();
+		//		| ws.add(dijit.byId("bar"));
+		//		| var t = ws.byId("bar") // returns a widget
+		//		| var x = ws.byId("foo"); // returns undefined
+		
+		return this._hash[id];	// dijit._Widget
+	},
+
+	byClass: function(/*String*/ cls){
+		// summary:
+		//		Reduce this widgetset to a new WidgetSet of a particular declaredClass
+		// 
+		// example:
+		//		Find all titlePane's in a page:
+		//		|	dijit.registry.byClass("dijit.TitlePane").forEach(function(tp){ tp.close(); });
+		
+		return this.filter(function(widget){ return widget.declaredClass==cls; });	// dijit.WidgetSet
+	}
+	
+});
+
+/*=====
+dijit.registry = {
+	// summary: A list of widgets on a page.
+	// description: Is an instance of `dijit.WidgetSet`
+};
+=====*/
+dijit.registry = new dijit.WidgetSet();
+
+dijit._widgetTypeCtr = {};
+
+dijit.getUniqueId = function(/*String*/widgetType){
+	// summary: Generates a unique id for a given widgetType
+
+	var id;
+	do{
+		id = widgetType + "_" +
+			(widgetType in dijit._widgetTypeCtr ?
+				++dijit._widgetTypeCtr[widgetType] : dijit._widgetTypeCtr[widgetType] = 0);
+	}while(dijit.byId(id));
+	return id; // String
+};
+
+dijit.findWidgets = function(/*DomNode*/ root){
+	// summary:
+	//		Search subtree under root, putting found widgets in outAry.
+	//		Doesn't search for nested widgets (ie, widgets inside other widgets)
+	
+	var outAry = [];
+
+	function getChildrenHelper(root){
+		var list = dojo.isIE ? root.children : root.childNodes, i = 0, node;
+		while(node = list[i++]){
+			if(node.nodeType != 1){ continue; }
+			var widgetId = node.getAttribute("widgetId");
+			if(widgetId){
+				var widget = dijit.byId(widgetId);
+				outAry.push(widget);
+			}else{
+				getChildrenHelper(node);
+			}
+		}
+	}
+
+	getChildrenHelper(root);
+	return outAry;
+};
+
+if(dojo.isIE){
+	// Only run this for IE because we think it's only necessary in that case,
+	// and because it causes problems on FF.  See bug #3531 for details.
+	dojo.addOnWindowUnload(function(){
+		dojo.forEach(dijit.findWidgets(dojo.body()), function(widget){
+			if(widget.destroyRecursive){
+				widget.destroyRecursive();
+			}else if(widget.destroy){
+				widget.destroy();
+			}
+		});
+	});
+}
+
+dijit.byId = function(/*String|Widget*/id){
+	// summary:
+	//		Returns a widget by it's id, or if passed a widget, no-op (like dojo.byId())
+	return (dojo.isString(id)) ? dijit.registry.byId(id) : id; // Widget
+};
+
+dijit.byNode = function(/* DOMNode */ node){
+	// summary:
+	//		Returns the widget corresponding to the given DOMNode
+	return dijit.registry.byId(node.getAttribute("widgetId")); // Widget
+};
+
+dijit.getEnclosingWidget = function(/* DOMNode */ node){
+	// summary:
+	//		Returns the widget whose DOM tree contains the specified DOMNode, or null if
+	//		the node is not contained within the DOM tree of any widget
+	while(node){
+		if(node.getAttribute && node.getAttribute("widgetId")){
+			return dijit.registry.byId(node.getAttribute("widgetId"));
+		}
+		node = node.parentNode;
+	}
+	return null;
+};
+
+// elements that are tab-navigable if they have no tabindex value set
+// (except for "a", which must have an href attribute)
+dijit._tabElements = {
+	area: true,
+	button: true,
+	input: true,
+	object: true,
+	select: true,
+	textarea: true
+};
+
+dijit._isElementShown = function(/*Element*/elem){
+	var style = dojo.style(elem);
+	return (style.visibility != "hidden")
+		&& (style.visibility != "collapsed")
+		&& (style.display != "none")
+		&& (dojo.attr(elem, "type") != "hidden");
+}
+
+dijit.isTabNavigable = function(/*Element*/elem){
+	// summary:
+	//		Tests if an element is tab-navigable
+	if(dojo.hasAttr(elem, "disabled")){ return false; }
+	var hasTabindex = dojo.hasAttr(elem, "tabindex");
+	var tabindex = dojo.attr(elem, "tabindex");
+	if(hasTabindex && tabindex >= 0) {
+		return true; // boolean
+	}
+	var name = elem.nodeName.toLowerCase();
+	if(((name == "a" && dojo.hasAttr(elem, "href"))
+			|| dijit._tabElements[name])
+		&& (!hasTabindex || tabindex >= 0)){
+		return true; // boolean
+	}
+	return false; // boolean
+};
+
+dijit._getTabNavigable = function(/*DOMNode*/root){
+	// summary:
+	//		Finds descendants of the specified root node.
+	//
+	// description:
+	//		Finds the following descendants of the specified root node:
+	//		* the first tab-navigable element in document order
+	//		  without a tabindex or with tabindex="0"
+	//		* the last tab-navigable element in document order
+	//		  without a tabindex or with tabindex="0"
+	//		* the first element in document order with the lowest
+	//		  positive tabindex value
+	//		* the last element in document order with the highest
+	//		  positive tabindex value
+	var first, last, lowest, lowestTabindex, highest, highestTabindex;
+	var walkTree = function(/*DOMNode*/parent){
+		dojo.query("> *", parent).forEach(function(child){
+			var isShown = dijit._isElementShown(child);
+			if(isShown && dijit.isTabNavigable(child)){
+				var tabindex = dojo.attr(child, "tabindex");
+				if(!dojo.hasAttr(child, "tabindex") || tabindex == 0){
+					if(!first){ first = child; }
+					last = child;
+				}else if(tabindex > 0){
+					if(!lowest || tabindex < lowestTabindex){
+						lowestTabindex = tabindex;
+						lowest = child;
+					}
+					if(!highest || tabindex >= highestTabindex){
+						highestTabindex = tabindex;
+						highest = child;
+					}
+				}
+			}
+			if(isShown && child.nodeName.toUpperCase() != 'SELECT'){ walkTree(child) }
+		});
+	};
+	if(dijit._isElementShown(root)){ walkTree(root) }
+	return { first: first, last: last, lowest: lowest, highest: highest };
+}
+dijit.getFirstInTabbingOrder = function(/*String|DOMNode*/root){
+	// summary:
+	//		Finds the descendant of the specified root node
+	//		that is first in the tabbing order
+	var elems = dijit._getTabNavigable(dojo.byId(root));
+	return elems.lowest ? elems.lowest : elems.first; // DomNode
+};
+
+dijit.getLastInTabbingOrder = function(/*String|DOMNode*/root){
+	// summary:
+	//		Finds the descendant of the specified root node
+	//		that is last in the tabbing order
+	var elems = dijit._getTabNavigable(dojo.byId(root));
+	return elems.last ? elems.last : elems.highest; // DomNode
+};
+
+/*=====
+dojo.mixin(dijit, {
+	// defaultDuration: Integer
+	//		The default animation speed (in ms) to use for all Dijit
+	//		transitional animations, unless otherwise specified 
+	//		on a per-instance basis. Defaults to 200, overrided by 
+	//		`djConfig.defaultDuration`
+	defaultDuration: 300
+});
+=====*/
+
+dijit.defaultDuration = dojo.config["defaultDuration"] || 200;
+
+}
+
+if(!dojo._hasResource["dojo.AdapterRegistry"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.AdapterRegistry"] = true;
+dojo.provide("dojo.AdapterRegistry");
+
+dojo.AdapterRegistry = function(/*Boolean?*/ returnWrappers){
+	//	summary:
+	//		A registry to make contextual calling/searching easier.
+	//	description:
+	//		Objects of this class keep list of arrays in the form [name, check,
+	//		wrap, directReturn] that are used to determine what the contextual
+	//		result of a set of checked arguments is. All check/wrap functions
+	//		in this registry should be of the same arity.
+	//	example:
+	//	|	// create a new registry
+	//	|	var reg = new dojo.AdapterRegistry();
+	//	|	reg.register("handleString",
+	//	|		dojo.isString,
+	//	|		function(str){
+	//	|			// do something with the string here
+	//	|		}
+	//	|	);
+	//	|	reg.register("handleArr",
+	//	|		dojo.isArray,
+	//	|		function(arr){
+	//	|			// do something with the array here
+	//	|		}
+	//	|	);
+	//	|
+	//	|	// now we can pass reg.match() *either* an array or a string and
+	//	|	// the value we pass will get handled by the right function
+	//	|	reg.match("someValue"); // will call the first function
+	//	|	reg.match(["someValue"]); // will call the second
+
+	this.pairs = [];
+	this.returnWrappers = returnWrappers || false; // Boolean
+}
+
+dojo.extend(dojo.AdapterRegistry, {
+	register: function(/*String*/ name, /*Function*/ check, /*Function*/ wrap, /*Boolean?*/ directReturn, /*Boolean?*/ override){
+		//	summary: 
+		//		register a check function to determine if the wrap function or
+		//		object gets selected
+		//	name:
+		//		a way to identify this matcher.
+		//	check:
+		//		a function that arguments are passed to from the adapter's
+		//		match() function.  The check function should return true if the
+		//		given arguments are appropriate for the wrap function.
+		//	directReturn:
+		//		If directReturn is true, the value passed in for wrap will be
+		//		returned instead of being called. Alternately, the
+		//		AdapterRegistry can be set globally to "return not call" using
+		//		the returnWrappers property. Either way, this behavior allows
+		//		the registry to act as a "search" function instead of a
+		//		function interception library.
+		//	override:
+		//		If override is given and true, the check function will be given
+		//		highest priority. Otherwise, it will be the lowest priority
+		//		adapter.
+		this.pairs[((override) ? "unshift" : "push")]([name, check, wrap, directReturn]);
+	},
+
+	match: function(/* ... */){
+		// summary:
+		//		Find an adapter for the given arguments. If no suitable adapter
+		//		is found, throws an exception. match() accepts any number of
+		//		arguments, all of which are passed to all matching functions
+		//		from the registered pairs.
+		for(var i = 0; i < this.pairs.length; i++){
+			var pair = this.pairs[i];
+			if(pair[1].apply(this, arguments)){
+				if((pair[3])||(this.returnWrappers)){
+					return pair[2];
+				}else{
+					return pair[2].apply(this, arguments);
+				}
+			}
+		}
+		throw new Error("No match found");
+	},
+
+	unregister: function(name){
+		// summary: Remove a named adapter from the registry
+
+		// FIXME: this is kind of a dumb way to handle this. On a large
+		// registry this will be slow-ish and we can use the name as a lookup
+		// should we choose to trade memory for speed.
+		for(var i = 0; i < this.pairs.length; i++){
+			var pair = this.pairs[i];
+			if(pair[0] == name){
+				this.pairs.splice(i, 1);
+				return true;
+			}
+		}
+		return false;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit._base.place"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.place"] = true;
+dojo.provide("dijit._base.place");
+
+
+
+// ported from dojo.html.util
+
+dijit.getViewport = function(){
+	// summary:
+	//		Returns the dimensions and scroll position of the viewable area of a browser window
+
+	var scrollRoot = (dojo.doc.compatMode == 'BackCompat')? dojo.body() : dojo.doc.documentElement;
+
+	// get scroll position
+	var scroll = dojo._docScroll(); // scrollRoot.scrollTop/Left should work
+	return { w: scrollRoot.clientWidth, h: scrollRoot.clientHeight, l: scroll.x, t: scroll.y };
+};
+
+/*=====
+dijit.__Position = function(){
+	// x: Integer
+	//		horizontal coordinate in pixels, relative to document body
+	// y: Integer
+	//		vertical coordinate in pixels, relative to document body
+
+	thix.x = x;
+	this.y = y;
+}
+=====*/
+
+
+dijit.placeOnScreen = function(
+	/* DomNode */			node,
+	/* dijit.__Position */	pos,
+	/* String[] */			corners,
+	/* dijit.__Position? */	padding){
+	//	summary:
+	//		Positions one of the node's corners at specified position
+	//		such that node is fully visible in viewport.
+	//	description:
+	//		NOTE: node is assumed to be absolutely or relatively positioned.
+	//	pos:
+	//		Object like {x: 10, y: 20}
+	//	corners:
+	//		Array of Strings representing order to try corners in, like ["TR", "BL"].
+	//		Possible values are:
+	//			* "BL" - bottom left
+	//			* "BR" - bottom right
+	//			* "TL" - top left
+	//			* "TR" - top right
+	//	padding:
+	//		set padding to put some buffer around the element you want to position.
+	//	example:	
+	//		Try to place node's top right corner at (10,20).
+	//		If that makes node go (partially) off screen, then try placing
+	//		bottom left corner at (10,20).
+	//	|	placeOnScreen(node, {x: 10, y: 20}, ["TR", "BL"])
+
+	var choices = dojo.map(corners, function(corner){
+		var c = { corner: corner, pos: {x:pos.x,y:pos.y} };
+		if(padding){
+			c.pos.x += corner.charAt(1) == 'L' ? padding.x : -padding.x;
+			c.pos.y += corner.charAt(0) == 'T' ? padding.y : -padding.y;
+		}
+		return c; 
+	});
+
+	return dijit._place(node, choices);
+}
+
+dijit._place = function(/*DomNode*/ node, /* Array */ choices, /* Function */ layoutNode){
+	// summary:
+	//		Given a list of spots to put node, put it at the first spot where it fits,
+	//		of if it doesn't fit anywhere then the place with the least overflow
+	// choices: Array
+	//		Array of elements like: {corner: 'TL', pos: {x: 10, y: 20} }
+	//		Above example says to put the top-left corner of the node at (10,20)
+	// layoutNode: Function(node, aroundNodeCorner, nodeCorner)
+	//		for things like tooltip, they are displayed differently (and have different dimensions)
+	//		based on their orientation relative to the parent.   This adjusts the popup based on orientation.
+
+	// get {x: 10, y: 10, w: 100, h:100} type obj representing position of
+	// viewport over document
+	var view = dijit.getViewport();
+
+	// This won't work if the node is inside a <div style="position: relative">,
+	// so reattach it to dojo.doc.body.   (Otherwise, the positioning will be wrong
+	// and also it might get cutoff)
+	if(!node.parentNode || String(node.parentNode.tagName).toLowerCase() != "body"){
+		dojo.body().appendChild(node);
+	}
+
+	var best = null;
+	dojo.some(choices, function(choice){
+		var corner = choice.corner;
+		var pos = choice.pos;
+
+		// configure node to be displayed in given position relative to button
+		// (need to do this in order to get an accurate size for the node, because
+		// a tooltips size changes based on position, due to triangle)
+		if(layoutNode){
+			layoutNode(node, choice.aroundCorner, corner);
+		}
+
+		// get node's size
+		var style = node.style;
+		var oldDisplay = style.display;
+		var oldVis = style.visibility;
+		style.visibility = "hidden";
+		style.display = "";
+		var mb = dojo.marginBox(node);
+		style.display = oldDisplay;
+		style.visibility = oldVis;
+
+		// coordinates and size of node with specified corner placed at pos,
+		// and clipped by viewport
+		var startX = (corner.charAt(1) == 'L' ? pos.x : Math.max(view.l, pos.x - mb.w)),
+			startY = (corner.charAt(0) == 'T' ? pos.y : Math.max(view.t, pos.y -  mb.h)),
+			endX = (corner.charAt(1) == 'L' ? Math.min(view.l + view.w, startX + mb.w) : pos.x),
+			endY = (corner.charAt(0) == 'T' ? Math.min(view.t + view.h, startY + mb.h) : pos.y),
+			width = endX - startX,
+			height = endY - startY,
+			overflow = (mb.w - width) + (mb.h - height);
+
+		if(best == null || overflow < best.overflow){
+			best = {
+				corner: corner,
+				aroundCorner: choice.aroundCorner,
+				x: startX,
+				y: startY,
+				w: width,
+				h: height,
+				overflow: overflow
+			};
+		}
+		return !overflow;
+	});
+
+	node.style.left = best.x + "px";
+	node.style.top = best.y + "px";
+	if(best.overflow && layoutNode){
+		layoutNode(node, best.aroundCorner, best.corner);
+	}
+	return best;
+}
+
+dijit.placeOnScreenAroundNode = function(
+	/* DomNode */		node,
+	/* DomNode */		aroundNode,
+	/* Object */		aroundCorners,
+	/* Function? */		layoutNode){
+
+	// summary:
+	//		Position node adjacent or kitty-corner to aroundNode
+	//		such that it's fully visible in viewport.
+	//
+	// description:
+	//		Place node such that corner of node touches a corner of
+	//		aroundNode, and that node is fully visible.
+	//
+	// aroundCorners:
+	//		Ordered list of pairs of corners to try matching up.
+	//		Each pair of corners is represented as a key/value in the hash,
+	//		where the key corresponds to the aroundNode's corner, and
+	//		the value corresponds to the node's corner:
+	//
+	//	|	{ aroundNodeCorner1: nodeCorner1, aroundNodeCorner2: nodeCorner2,  ...}
+	//
+	//		The following strings are used to represent the four corners:
+	//			* "BL" - bottom left
+	//			* "BR" - bottom right
+	//			* "TL" - top left
+	//			* "TR" - top right
+	//
+	// layoutNode: Function(node, aroundNodeCorner, nodeCorner)
+	//		For things like tooltip, they are displayed differently (and have different dimensions)
+	//		based on their orientation relative to the parent.   This adjusts the popup based on orientation.
+	//
+	// example:
+	//	|	dijit.placeOnScreenAroundNode(node, aroundNode, {'BL':'TL', 'TR':'BR'}); 
+	//		This will try to position node such that node's top-left corner is at the same position
+	//		as the bottom left corner of the aroundNode (ie, put node below
+	//		aroundNode, with left edges aligned).  If that fails it will try to put
+	// 		the bottom-right corner of node where the top right corner of aroundNode is
+	//		(ie, put node above aroundNode, with right edges aligned)
+	//
+
+	// get coordinates of aroundNode
+	aroundNode = dojo.byId(aroundNode);
+	var oldDisplay = aroundNode.style.display;
+	aroundNode.style.display="";
+	// #3172: use the slightly tighter border box instead of marginBox
+	var aroundNodeW = aroundNode.offsetWidth; //mb.w; 
+	var aroundNodeH = aroundNode.offsetHeight; //mb.h;
+	var aroundNodePos = dojo.coords(aroundNode, true);
+	aroundNode.style.display=oldDisplay;
+
+	// place the node around the calculated rectangle
+	return dijit._placeOnScreenAroundRect(node, 
+		aroundNodePos.x, aroundNodePos.y, aroundNodeW, aroundNodeH,	// rectangle
+		aroundCorners, layoutNode);
+};
+
+/*=====
+dijit.__Rectangle = function(){
+	// x: Integer
+	//		horizontal offset in pixels, relative to document body
+	// y: Integer
+	//		vertical offset in pixels, relative to document body
+	// width: Integer
+	//		width in pixels
+	// height: Integer
+	//		height in pixels
+
+	thix.x = x;
+	this.y = y;
+	thix.width = width;
+	this.height = height;
+}
+=====*/
+
+
+dijit.placeOnScreenAroundRectangle = function(
+	/* DomNode */			node,
+	/* dijit.__Rectangle */	aroundRect,
+	/* Object */			aroundCorners,
+	/* Function */			layoutNode){
+
+	// summary:
+	//		Like dijit.placeOnScreenAroundNode(), except that the "around"
+	//		parameter is an arbitrary rectangle on the screen (x, y, width, height)
+	//		instead of a dom node.
+
+	return dijit._placeOnScreenAroundRect(node, 
+		aroundRect.x, aroundRect.y, aroundRect.width, aroundRect.height,	// rectangle
+		aroundCorners, layoutNode);
+};
+
+dijit._placeOnScreenAroundRect = function(
+	/* DomNode */		node,
+	/* Number */		x,
+	/* Number */		y,
+	/* Number */		width,
+	/* Number */		height,
+	/* Object */		aroundCorners,
+	/* Function */		layoutNode){
+
+	// summary:
+	//		Like dijit.placeOnScreenAroundNode(), except it accepts coordinates
+	//		of a rectangle to place node adjacent to.
+
+	// TODO: combine with placeOnScreenAroundRectangle()
+
+	// Generate list of possible positions for node
+	var choices = [];
+	for(var nodeCorner in aroundCorners){
+		choices.push( {
+			aroundCorner: nodeCorner,
+			corner: aroundCorners[nodeCorner],
+			pos: {
+				x: x + (nodeCorner.charAt(1) == 'L' ? 0 : width),
+				y: y + (nodeCorner.charAt(0) == 'T' ? 0 : height)
+			}
+		});
+	}
+
+	return dijit._place(node, choices, layoutNode);
+};
+
+dijit.placementRegistry = new dojo.AdapterRegistry();
+dijit.placementRegistry.register("node",
+	function(n, x){
+		return typeof x == "object" &&
+			typeof x.offsetWidth != "undefined" && typeof x.offsetHeight != "undefined";
+	},
+	dijit.placeOnScreenAroundNode);
+dijit.placementRegistry.register("rect",
+	function(n, x){
+		return typeof x == "object" &&
+			"x" in x && "y" in x && "width" in x && "height" in x;
+	},
+	dijit.placeOnScreenAroundRectangle);
+
+dijit.placeOnScreenAroundElement = function(
+	/* DomNode */		node,
+	/* Object */		aroundElement,
+	/* Object */		aroundCorners,
+	/* Function */		layoutNode){
+
+	// summary:
+	//		Like dijit.placeOnScreenAroundNode(), except it accepts an arbitrary object
+	//		for the "around" argument and finds a proper processor to place a node.
+
+	return dijit.placementRegistry.match.apply(dijit.placementRegistry, arguments);
+};
+
+}
+
+if(!dojo._hasResource["dijit._base.window"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.window"] = true;
+dojo.provide("dijit._base.window");
+
+// TODO: remove this in 2.0, it's not used anymore, or at least not internally
+
+dijit.getDocumentWindow = function(doc){
+	// summary:
+	// 		Get window object associated with document doc
+
+	// In some IE versions (at least 6.0), document.parentWindow does not return a
+	// reference to the real window object (maybe a copy), so we must fix it as well
+	// We use IE specific execScript to attach the real window reference to
+	// document._parentWindow for later use
+	if(dojo.isIE && window !== document.parentWindow && !doc._parentWindow){
+		/*
+		In IE 6, only the variable "window" can be used to connect events (others
+		may be only copies).
+		*/
+		doc.parentWindow.execScript("document._parentWindow = window;", "Javascript");
+		//to prevent memory leak, unset it after use
+		//another possibility is to add an onUnload handler which seems overkill to me (liucougar)
+		var win = doc._parentWindow;
+		doc._parentWindow = null;
+		return win;	//	Window
+	}
+
+	return doc._parentWindow || doc.parentWindow || doc.defaultView;	//	Window
+}
+
+}
+
+if(!dojo._hasResource["dijit._base.popup"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.popup"] = true;
+dojo.provide("dijit._base.popup");
+
+
+
+
+
+dijit.popup = new function(){
+	// summary:
+	//		This class is used to show/hide widgets as popups.
+
+	var stack = [],
+		beginZIndex=1000,
+		idGen = 1;
+
+	this.prepare = function(/*DomNode*/ node){
+		// summary:
+		//		Prepares a node to be used as a popup
+		//
+		// description:
+		//		Attaches node to dojo.doc.body, and
+		//		positions it off screen, but not display:none, so that
+		//		the widget doesn't appear in the page flow and/or cause a blank
+		//		area at the bottom of the viewport (making scrollbar longer), but
+		//		initialization of contained widgets works correctly
+
+		var s = node.style;
+		s.visibility = "hidden";	// so TAB key doesn't navigate to hidden popup
+		s.position = "absolute";
+		s.top = "-9999px";
+		if(s.display == "none"){
+			s.display="";
+		}
+		dojo.body().appendChild(node);
+	};
+
+/*=====
+dijit.popup.__OpenArgs = function(){
+	// popup: Widget
+	//		widget to display
+	// parent: Widget
+	//		the button etc. that is displaying this popup
+	// around: DomNode
+	//		DOM node (typically a button); place popup relative to this node.  (Specify this *or* "x" and "y" parameters.)
+	// x: Integer
+	//		Absolute horizontal position (in pixels) to place node at.  (Specify this *or* "around" parameter.)
+	// y: Integer
+	//		Absolute vertical position (in pixels) to place node at.  (Specity this *or* "around" parameter.)
+	// orient: Object || String
+	//		When the around parameter is specified, orient should be an 
+	//		ordered list of tuples of the form (around-node-corner, popup-node-corner).
+	//		dijit.popup.open() tries to position the popup according to each tuple in the list, in order,
+	//		until the popup appears fully within the viewport.
+	//
+	//		The default value is {BL:'TL', TL:'BL'}, which represents a list of two tuples:
+	//			1. (BL, TL)
+	//			2. (TL, BL)
+	//		where BL means "bottom left" and "TL" means "top left".
+	//		So by default, it first tries putting the popup below the around node, left-aligning them,
+	//		and then tries to put it above the around node, still left-aligning them.   Note that the
+	//		default is horizontally reversed when in RTL mode.
+	//
+	//		When an (x,y) position is specified rather than an around node, orient is either
+	//		"R" or "L".  R (for right) means that it tries to put the popup to the right of the mouse,
+	//		specifically positioning the popup's top-right corner at the mouse position, and if that doesn't
+	//		fit in the viewport, then it tries, in order, the bottom-right corner, the top left corner,
+	//		and the top-right corner.
+	// onCancel: Function
+	//		callback when user has canceled the popup by
+	//			1. hitting ESC or
+	//			2. by using the popup widget's proprietary cancel mechanism (like a cancel button in a dialog);
+	//			   i.e. whenever popupWidget.onCancel() is called, args.onCancel is called
+	// onClose: Function
+	//		callback whenever this popup is closed
+	// onExecute: Function
+	//		callback when user "executed" on the popup/sub-popup by selecting a menu choice, etc. (top menu only)
+	// padding: dijit.__Position
+	//		adding a buffer around the opening position. This is only useful when around is not set.
+	this.popup = popup;
+	this.parent = parent;
+	this.around = around;
+	this.x = x;
+	this.y = y;
+	this.orient = orient;
+	this.onCancel = onCancel;
+	this.onClose = onClose;
+	this.onExecute = onExecute;
+	this.padding = padding;
+}
+=====*/
+	this.open = function(/*dijit.popup.__OpenArgs*/ args){
+		// summary:
+		//		Popup the widget at the specified position
+		//
+		// example:
+		//		opening at the mouse position
+		//		|		dijit.popup.open({popup: menuWidget, x: evt.pageX, y: evt.pageY});
+		//
+		// example:
+		//		opening the widget as a dropdown
+		//		|		dijit.popup.open({parent: this, popup: menuWidget, around: this.domNode, onClose: function(){...}  });
+		//
+		//		Note that whatever widget called dijit.popup.open() should also listen to its own _onBlur callback
+		//		(fired from _base/focus.js) to know that focus has moved somewhere else and thus the popup should be closed.
+
+		var widget = args.popup,
+			orient = args.orient || {'BL':'TL', 'TL':'BL'},
+			around = args.around,
+			id = (args.around && args.around.id) ? (args.around.id+"_dropdown") : ("popup_"+idGen++);
+
+		// make wrapper div to hold widget and possibly hold iframe behind it.
+		// we can't attach the iframe as a child of the widget.domNode because
+		// widget.domNode might be a <table>, <ul>, etc.
+		var wrapper = dojo.create("div",{
+			id: id, 
+			"class":"dijitPopup",
+			style:{
+				zIndex: beginZIndex + stack.length,
+				visibility:"hidden"
+			}
+		}, dojo.body());
+		dijit.setWaiRole(wrapper, "presentation");
+		
+		// prevent transient scrollbar causing misalign (#5776)
+		wrapper.style.left = wrapper.style.top = "0px";		
+
+		if(args.parent){
+			wrapper.dijitPopupParent=args.parent.id;
+		}
+
+		var s = widget.domNode.style;
+		s.display = "";
+		s.visibility = "";
+		s.position = "";
+		s.top = "0px";
+		wrapper.appendChild(widget.domNode);
+
+		var iframe = new dijit.BackgroundIframe(wrapper);
+
+		// position the wrapper node
+		var best = around ?
+			dijit.placeOnScreenAroundElement(wrapper, around, orient, widget.orient ? dojo.hitch(widget, "orient") : null) :
+			dijit.placeOnScreen(wrapper, args, orient == 'R' ? ['TR','BR','TL','BL'] : ['TL','BL','TR','BR'], args.padding);
+
+		wrapper.style.visibility = "visible";
+		// TODO: use effects to fade in wrapper
+
+		var handlers = [];
+
+		// Compute the closest ancestor popup that's *not* a child of another popup.
+		// Ex: For a TooltipDialog with a button that spawns a tree of menus, find the popup of the button.
+		var getTopPopup = function(){
+			for(var pi=stack.length-1; pi > 0 && stack[pi].parent === stack[pi-1].widget; pi--){
+				/* do nothing, just trying to get right value for pi */
+			}
+			return stack[pi];
+		}
+
+		// provide default escape and tab key handling
+		// (this will work for any widget, not just menu)
+		handlers.push(dojo.connect(wrapper, "onkeypress", this, function(evt){
+			if(evt.charOrCode == dojo.keys.ESCAPE && args.onCancel){
+				dojo.stopEvent(evt);
+				args.onCancel();
+			}else if(evt.charOrCode === dojo.keys.TAB){
+				dojo.stopEvent(evt);
+				var topPopup = getTopPopup();
+				if(topPopup && topPopup.onCancel){
+					topPopup.onCancel();
+				}
+			}
+		}));
+
+		// watch for cancel/execute events on the popup and notify the caller
+		// (for a menu, "execute" means clicking an item)
+		if(widget.onCancel){
+			handlers.push(dojo.connect(widget, "onCancel", null, args.onCancel));
+		}
+
+		handlers.push(dojo.connect(widget, widget.onExecute ? "onExecute" : "onChange", null, function(){
+			var topPopup = getTopPopup();
+			if(topPopup && topPopup.onExecute){
+				topPopup.onExecute();
+			}
+		}));
+
+		stack.push({
+			wrapper: wrapper,
+			iframe: iframe,
+			widget: widget,
+			parent: args.parent,
+			onExecute: args.onExecute,
+			onCancel: args.onCancel,
+ 			onClose: args.onClose,
+			handlers: handlers
+		});
+
+		if(widget.onOpen){
+			widget.onOpen(best);
+		}
+
+		return best;
+	};
+
+	this.close = function(/*Widget*/ popup){
+		// summary:
+		//		Close specified popup and any popups that it parented
+		while(dojo.some(stack, function(elem){return elem.widget == popup;})){
+			var top = stack.pop(),
+				wrapper = top.wrapper,
+				iframe = top.iframe,
+				widget = top.widget,
+				onClose = top.onClose;
+	
+			if(widget.onClose){
+				widget.onClose();
+			}
+			dojo.forEach(top.handlers, dojo.disconnect);
+	
+			// #2685: check if the widget still has a domNode so ContentPane can change its URL without getting an error
+			if(!widget||!widget.domNode){ return; }
+			
+			this.prepare(widget.domNode);
+
+			iframe.destroy();
+			dojo.destroy(wrapper);
+	
+			if(onClose){
+				onClose();
+			}
+		}
+	};
+}();
+
+dijit._frames = new function(){
+	// summary: cache of iframes
+	var queue = [];
+
+	this.pop = function(){
+		var iframe;
+		if(queue.length){
+			iframe = queue.pop();
+			iframe.style.display="";
+		}else{
+			if(dojo.isIE){
+				var burl = dojo.config["dojoBlankHtmlUrl"] || (dojo.moduleUrl("dojo", "resources/blank.html")+"") || "javascript:\"\"";
+				var html="<iframe src='" + burl + "'"
+					+ " style='position: absolute; left: 0px; top: 0px;"
+					+ "z-index: -1; filter:Alpha(Opacity=\"0\");'>";
+				iframe = dojo.doc.createElement(html);
+			}else{
+			 	iframe = dojo.create("iframe");
+				iframe.src = 'javascript:""';
+				iframe.className = "dijitBackgroundIframe";
+			}
+			iframe.tabIndex = -1; // Magic to prevent iframe from getting focus on tab keypress - as style didnt work.
+			dojo.body().appendChild(iframe);
+		}
+		return iframe;
+	};
+
+	this.push = function(iframe){
+		iframe.style.display="none";
+		if(dojo.isIE){
+			iframe.style.removeExpression("width");
+			iframe.style.removeExpression("height");
+		}
+		queue.push(iframe);
+	}
+}();
+
+
+dijit.BackgroundIframe = function(/* DomNode */node){
+	// summary:
+	//		For IE z-index schenanigans. id attribute is required.
+	//
+	// description:
+	//		new dijit.BackgroundIframe(node)
+	//			Makes a background iframe as a child of node, that fills
+	//			area (and position) of node
+
+	if(!node.id){ throw new Error("no id"); }
+	if(dojo.isIE < 7 || (dojo.isFF < 3 && dojo.hasClass(dojo.body(), "dijit_a11y"))){
+		var iframe = dijit._frames.pop();
+		node.appendChild(iframe);
+		if(dojo.isIE){
+			iframe.style.setExpression("width", dojo._scopeName + ".doc.getElementById('" + node.id + "').offsetWidth");
+			iframe.style.setExpression("height", dojo._scopeName + ".doc.getElementById('" + node.id + "').offsetHeight");
+		}
+		this.iframe = iframe;
+	}
+};
+
+dojo.extend(dijit.BackgroundIframe, {
+	destroy: function(){
+		//	summary: destroy the iframe
+		if(this.iframe){
+			dijit._frames.push(this.iframe);
+			delete this.iframe;
+		}
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit._base.scroll"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.scroll"] = true;
+dojo.provide("dijit._base.scroll");
+
+dijit.scrollIntoView = function(/* DomNode */node){
+	// summary:
+	//		Scroll the passed node into view, if it is not.
+
+	// don't rely on that node.scrollIntoView works just because the function is there
+	// it doesnt work in Konqueror or Opera even though the function is there and probably
+	//	not safari either
+	// native scrollIntoView() causes FF3's whole window to scroll if there is no scroll bar 
+	//	on the immediate parent
+	// dont like browser sniffs implementations but sometimes you have to use it
+	// It's not enough just to scroll the menu node into view if
+	// node.scrollIntoView hides part of the parent's scrollbar,
+	// so just manage the parent scrollbar ourselves
+
+	//var testdir="H"; //debug
+	try{ // catch unexpected/unrecreatable errors (#7808) since we can recover using a semi-acceptable native method
+	node = dojo.byId(node);
+	var doc = dojo.doc;
+	var body = dojo.body();
+	var html = body.parentNode;
+	// if FF2 (which is perfect) or an untested browser, then use the native method
+
+	if((!(dojo.isFF >= 3 || dojo.isIE || dojo.isWebKit) || node == body || node == html) && (typeof node.scrollIntoView == "function")){ // FF2 is perfect, too bad FF3 is not
+		node.scrollIntoView(false); // short-circuit to native if possible
+		return;
+	}
+	var ltr = dojo._isBodyLtr();
+	var isIE8strict = dojo.isIE >= 8 && !compatMode;
+	var rtl = !ltr && !isIE8strict; // IE8 flips scrolling so pretend it's ltr
+	// body and html elements are all messed up due to browser bugs and inconsistencies related to doctype
+	// normalize the values before proceeding (FF2 is not listed since its native behavior is perfect)
+	// for computation simplification, client and offset width and height are the same for body and html
+	// strict:       html:       |      body:       | compatMode:
+	//           width   height  |  width   height  |------------
+	//    ie*:  clientW  clientH | scrollW  clientH | CSS1Compat
+	//    ff3:  clientW  clientH |HscrollW  clientH | CSS1Compat
+	//    sf3:  clientW  clientH | clientW HclientH | CSS1Compat
+	//    op9:  clientW  clientH |HscrollW  clientH | CSS1Compat
+	// ---------------------------------------------|-----------
+	//   none:        html:      |      body:       |
+	//           width    height |  width   height  |
+	//    ie*: BclientW BclientH | clientW  clientH | BackCompat
+	//    ff3: BclientW BclientH | clientW  clientH | BackCompat
+	//    sf3:  clientW  clientH | clientW HclientH | CSS1Compat
+	//    op9: BclientW BclientH | clientW  clientH | BackCompat
+	// ---------------------------------------------|-----------
+	//  loose:        html:      |      body:       |
+	//           width    height |  width   height  |
+	//    ie*:  clientW  clientH | scrollW  clientH | CSS1Compat
+	//    ff3: BclientW BclientH | clientW  clientH | BackCompat
+	//    sf3:  clientW  clientH | clientW HclientH | CSS1Compat
+	//    op9:  clientW  clientH |HscrollW  clientH | CSS1Compat
+	var scrollRoot = body;
+	var compatMode = doc.compatMode == 'BackCompat';
+	if(compatMode){ // BODY is scrollable, HTML has same client size
+		// body client values already OK
+		html._offsetWidth = html._clientWidth = body._offsetWidth = body.clientWidth;
+		html._offsetHeight = html._clientHeight = body._offsetHeight = body.clientHeight;
+	}else{
+		if(dojo.isWebKit){
+			body._offsetWidth = body._clientWidth  = html.clientWidth;
+			body._offsetHeight = body._clientHeight = html.clientHeight;
+		}else{
+			scrollRoot = html;
+		}
+		html._offsetHeight = html.clientHeight;
+		html._offsetWidth  = html.clientWidth;
+	}
+
+	function isFixedPosition(element){
+		var ie = dojo.isIE;
+		return ((ie <= 6 || (ie >= 7 && compatMode))? false : (dojo.style(element, 'position').toLowerCase() == "fixed"));
+	}
+
+	function addPseudoAttrs(element){
+		var parent = element.parentNode;
+		var offsetParent = element.offsetParent;
+		if(offsetParent == null || isFixedPosition(element)){ // position:fixed has no real offsetParent
+			offsetParent = html; // prevents exeptions
+			parent = (element == body)? html : null;
+		}
+		// all the V/H object members below are to reuse code for both directions
+		element._offsetParent = offsetParent;
+		element._parent = parent;
+		//
+		//
+		var bp = dojo._getBorderExtents(element);
+		element._borderStart = { H:(isIE8strict && !ltr)? (bp.w-bp.l):bp.l, V:bp.t };
+		element._borderSize = { H:bp.w, V:bp.h };
+		element._scrolledAmount = { H:element.scrollLeft, V:element.scrollTop };
+		element._offsetSize = { H: element._offsetWidth||element.offsetWidth, V: element._offsetHeight||element.offsetHeight };
+		//
+		// IE8 flips everything in rtl mode except offsetLeft and borderLeft - so manually change offsetLeft to offsetRight here 
+		element._offsetStart = { H:(isIE8strict && !ltr)? offsetParent.clientWidth-element.offsetLeft-element._offsetSize.H:element.offsetLeft, V:element.offsetTop };
+		//
+		element._clientSize = { H:element._clientWidth||element.clientWidth, V:element._clientHeight||element.clientHeight };
+		if(element != body && element != html && element != node){
+			for(var dir in element._offsetSize){ // for both x and y directions
+				var scrollBarSize = element._offsetSize[dir] - element._clientSize[dir] - element._borderSize[dir];
+				//if(dir==testdir)
+				var hasScrollBar = element._clientSize[dir] > 0 && scrollBarSize > 0; // can't check for a specific scrollbar size since it changes dramatically as you zoom
+				//if(dir==testdir)
+				if(hasScrollBar){
+					element._offsetSize[dir] -= scrollBarSize;
+					if(dojo.isIE && rtl && dir=="H"){ element._offsetStart[dir] += scrollBarSize; }
+				}
+			}
+		}
+	}
+
+	var element = node;
+	while(element != null){
+		if(isFixedPosition(element)){ node.scrollIntoView(false); return; } //TODO: handle without native call
+		addPseudoAttrs(element);
+		element = element._parent;
+	}
+	if(dojo.isIE && node._parent){ // if no parent, then offsetParent._borderStart may not tbe set
+		var offsetParent = node._offsetParent;
+		//
+		node._offsetStart.H += offsetParent._borderStart.H;
+		node._offsetStart.V += offsetParent._borderStart.V;
+	}
+	if(dojo.isIE >= 7 && scrollRoot == html && rtl && body._offsetStart && body._offsetStart.H == 0){ // IE7 bug
+		var scroll = html.scrollWidth - html._offsetSize.H;
+		if(scroll > 0){
+			//
+			body._offsetStart.H = -scroll;
+		}
+	}
+	if(dojo.isIE <= 6 && !compatMode){
+		html._offsetSize.H += html._borderSize.H;
+		html._offsetSize.V += html._borderSize.V;
+	}
+	// eliminate offsetLeft/Top oddities by tweaking scroll for ease of computation
+	if(rtl && body._offsetStart && scrollRoot == html && html._scrolledAmount){
+		var ofs = body._offsetStart.H;
+		if(ofs < 0){
+			html._scrolledAmount.H += ofs;
+			body._offsetStart.H = 0;
+		}
+	}
+	element = node;
+	while(element){
+		var parent = element._parent;
+		if(!parent){ break; }
+			//
+			if(parent.tagName == "TD"){
+				var table = parent._parent._parent._parent; // point to TABLE
+				if(parent != element._offsetParent && parent._offsetParent != element._offsetParent){
+					parent = table; // child of TD has the same offsetParent as TABLE, so skip TD, TR, and TBODY (ie. verticalslider)
+				}
+			}
+			// check if this node and its parent share the same offsetParent
+			var relative = element._offsetParent == parent;
+			//
+			for(var dir in element._offsetStart){ // for both x and y directions
+				var otherDir = dir=="H"? "V" : "H";
+				if(rtl && dir=="H" && (parent != html) && (parent != body) && (dojo.isIE || dojo.isWebKit) && parent._clientSize.H > 0 && parent.scrollWidth > parent._clientSize.H){ // scroll starts on the right
+					var delta = parent.scrollWidth - parent._clientSize.H;
+					//
+					if(delta > 0){
+						parent._scrolledAmount.H -= delta;
+					} // match FF3 which has cool negative scrollLeft values
+				}
+				if(parent._offsetParent.tagName == "TABLE"){ // make it consistent
+					if(dojo.isIE){ // make it consistent with Safari and FF3 and exclude the starting TABLE border of TABLE children
+						parent._offsetStart[dir] -= parent._offsetParent._borderStart[dir];
+						parent._borderStart[dir] = parent._borderSize[dir] = 0;
+					}
+					else{
+						parent._offsetStart[dir] += parent._offsetParent._borderStart[dir];
+					}
+				}
+				//if(dir==testdir)
+				if(dojo.isIE){
+					//if(dir==testdir)
+					parent._offsetStart[dir] += parent._offsetParent._borderStart[dir];
+				}
+				//if(dir==testdir)
+				// underflow = visible gap between parent and this node taking scrolling into account
+				// if negative, part of the node is obscured by the parent's beginning and should be scrolled to become visible
+				var underflow = element._offsetStart[dir] - parent._scrolledAmount[dir] - (relative? 0 : parent._offsetStart[dir]) - parent._borderStart[dir];
+				// if overflow is positive, number of pixels obscured by the parent's end
+				var overflow = underflow + element._offsetSize[dir] - parent._offsetSize[dir] + parent._borderSize[dir];
+				//if(dir==testdir)
+				var scrollAttr = (dir=="H")? "scrollLeft" : "scrollTop";
+				// see if we should scroll forward or backward
+				var reverse = dir=="H" && rtl; // flip everything
+				var underflowScroll = reverse? -overflow : underflow;
+				var overflowScroll = reverse? -underflow : overflow;
+				// don't scroll if the over/underflow signs are opposite since that means that
+				// the node extends beyond parent's boundary in both/neither directions
+				var scrollAmount = (underflowScroll*overflowScroll <= 0)? 0 : Math[(underflowScroll < 0)? "max" : "min"](underflowScroll, overflowScroll);
+				//if(dir==testdir)
+				if(scrollAmount != 0){
+					var oldScroll = parent[scrollAttr];
+					parent[scrollAttr] += (reverse)? -scrollAmount : scrollAmount; // actually perform the scroll
+					var scrolledAmount = parent[scrollAttr] - oldScroll; // in case the scroll failed
+					//if(dir==testdir)
+				}
+				if(relative){
+					element._offsetStart[dir] += parent._offsetStart[dir];
+				}
+				element._offsetStart[dir] -= parent[scrollAttr];
+			}
+			element._parent = parent._parent;
+			element._offsetParent = parent._offsetParent;
+	}
+	parent = node;
+	var next;
+	while(parent && parent.removeAttribute){
+		next = parent.parentNode;
+		parent.removeAttribute('_offsetParent');
+		parent.removeAttribute('_parent');
+		parent = next;
+	}
+	}catch(error){
+		console.error('scrollIntoView: ' + error);
+		node.scrollIntoView(false);
+	}
+};
+
+}
+
+if(!dojo._hasResource["dijit._base.sniff"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.sniff"] = true;
+// summary:
+//		Applies pre-set CSS classes to the top-level HTML node, based on:
+// 			- browser (ex: dj_ie)
+//			- browser version (ex: dj_ie6)
+//			- box model (ex: dj_contentBox)
+//			- text direction (ex: dijitRtl)
+//
+//		In addition, browser, browser version, and box model are
+//		combined with an RTL flag when browser text is RTL.  ex: dj_ie-rtl.
+//
+//		Simply doing a require on this module will
+//		establish this CSS.  Modified version of Morris' CSS hack.
+
+dojo.provide("dijit._base.sniff");
+
+(function(){
+	
+	var d = dojo,
+		html = d.doc.documentElement,
+		ie = d.isIE,
+		opera = d.isOpera,
+		maj = Math.floor,
+		ff = d.isFF,
+		boxModel = d.boxModel.replace(/-/,''),
+		classes = {
+			dj_ie: ie,
+//			dj_ie55: ie == 5.5,
+			dj_ie6: maj(ie) == 6,
+			dj_ie7: maj(ie) == 7,
+			dj_iequirks: ie && d.isQuirks,
+			// NOTE: Opera not supported by dijit
+			dj_opera: opera,
+			dj_opera8: maj(opera) == 8,
+			dj_opera9: maj(opera) == 9,
+			dj_khtml: d.isKhtml,
+			dj_webkit: d.isWebKit,
+			dj_safari: d.isSafari,
+			dj_gecko: d.isMozilla,
+			dj_ff2: maj(ff) == 2,
+			dj_ff3: maj(ff) == 3
+		}; // no dojo unsupported browsers
+		
+	classes["dj_" + boxModel] = true;
+	
+	// apply browser, browser version, and box model class names
+	for(var p in classes){
+		if(classes[p]){
+			if(html.className){
+				html.className += " " + p;
+			}else{
+				html.className = p;
+			}
+		}
+	}
+
+	// If RTL mode then add dijitRtl flag plus repeat existing classes
+	// with -rtl extension
+	// (unshift is to make this code run after <body> node is loaded but before parser runs)
+	dojo._loaders.unshift(function(){
+		if(!dojo._isBodyLtr()){
+			html.className += " dijitRtl";
+			for(var p in classes){
+				if(classes[p]){
+					html.className += " " + p + "-rtl";
+				}
+			}
+		}
+	});
+	
+})();
+
+}
+
+if(!dojo._hasResource["dijit._base.typematic"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.typematic"] = true;
+dojo.provide("dijit._base.typematic");
+
+dijit.typematic = {
+	// summary:
+	//		These functions are used to repetitively call a user specified callback
+	//		method when a specific key or mouse click over a specific DOM node is
+	//		held down for a specific amount of time.
+	//		Only 1 such event is allowed to occur on the browser page at 1 time.
+
+	_fireEventAndReload: function(){
+		this._timer = null;
+		this._callback(++this._count, this._node, this._evt);
+		this._currentTimeout = (this._currentTimeout < 0) ? this._initialDelay : ((this._subsequentDelay > 1) ? this._subsequentDelay : Math.round(this._currentTimeout * this._subsequentDelay));
+		this._timer = setTimeout(dojo.hitch(this, "_fireEventAndReload"), this._currentTimeout);
+	},
+
+	trigger: function(/*Event*/ evt, /* Object */ _this, /*DOMNode*/ node, /* Function */ callback, /* Object */ obj, /* Number */ subsequentDelay, /* Number */ initialDelay){
+		// summary:
+		//	    Start a timed, repeating callback sequence.
+		//	    If already started, the function call is ignored.
+		//	    This method is not normally called by the user but can be
+		//	    when the normal listener code is insufficient.
+		// evt:
+		//		key or mouse event object to pass to the user callback
+		// _this:
+		//		pointer to the user's widget space.
+		// node:
+		//		the DOM node object to pass the the callback function
+		// callback:
+		//		function to call until the sequence is stopped called with 3 parameters:
+		// count:
+		//		integer representing number of repeated calls (0..n) with -1 indicating the iteration has stopped
+		// node:
+		//		the DOM node object passed in
+		// evt:
+		//		key or mouse event object
+		// obj:
+		//		user space object used to uniquely identify each typematic sequence
+		// subsequentDelay:
+		//		if > 1, the number of milliseconds until the 3->n events occur
+		//		or else the fractional time multiplier for the next event's delay, default=0.9
+		// initialDelay:
+		//		the number of milliseconds until the 2nd event occurs, default=500ms
+		if(obj != this._obj){
+			this.stop();
+			this._initialDelay = initialDelay || 500;
+			this._subsequentDelay = subsequentDelay || 0.90;
+			this._obj = obj;
+			this._evt = evt;
+			this._node = node;
+			this._currentTimeout = -1;
+			this._count = -1;
+			this._callback = dojo.hitch(_this, callback);
+			this._fireEventAndReload();
+		}
+	},
+
+	stop: function(){
+		// summary:
+		//	  Stop an ongoing timed, repeating callback sequence.
+		if(this._timer){
+			clearTimeout(this._timer);
+			this._timer = null;
+		}
+		if(this._obj){
+			this._callback(-1, this._node, this._evt);
+			this._obj = null;
+		}
+	},
+
+	addKeyListener: function(/*DOMNode*/ node, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay){
+		// summary:
+		//		Start listening for a specific typematic key.
+		//		See also the trigger method for other parameters.
+		// keyObject:
+		//		an object defining the key to listen for.
+		// charOrCode:
+		//		the printable character (string) or keyCode (number) to listen for.
+		// keyCode:
+		//		(deprecated - use charOrCode) the keyCode (number) to listen for (implies charCode = 0).
+		// charCode:
+		//		(deprecated - use charOrCode) the charCode (number) to listen for.
+		// ctrlKey:
+		//		desired ctrl key state to initiate the calback sequence:
+		//			- pressed (true)
+		//			- released (false)
+		//			- either (unspecified)
+		// altKey:
+		//		same as ctrlKey but for the alt key
+		// shiftKey:
+		//		same as ctrlKey but for the shift key
+		// returns:
+		//		an array of dojo.connect handles
+		if(keyObject.keyCode){
+			keyObject.charOrCode = keyObject.keyCode;
+			dojo.deprecated("keyCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.", "", "2.0");
+		}else if(keyObject.charCode){
+			keyObject.charOrCode = String.fromCharCode(keyObject.charCode);
+			dojo.deprecated("charCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.", "", "2.0");
+		}
+		return [
+			dojo.connect(node, "onkeypress", this, function(evt){
+				if(evt.charOrCode == keyObject.charOrCode &&
+				(keyObject.ctrlKey === undefined || keyObject.ctrlKey == evt.ctrlKey) &&
+				(keyObject.altKey === undefined || keyObject.altKey == evt.ctrlKey) &&
+				(keyObject.shiftKey === undefined || keyObject.shiftKey == evt.ctrlKey)){
+					dojo.stopEvent(evt);
+					dijit.typematic.trigger(keyObject, _this, node, callback, keyObject, subsequentDelay, initialDelay);
+				}else if(dijit.typematic._obj == keyObject){
+					dijit.typematic.stop();
+				}
+			}),
+			dojo.connect(node, "onkeyup", this, function(evt){
+				if(dijit.typematic._obj == keyObject){
+					dijit.typematic.stop();
+				}
+			})
+		];
+	},
+
+	addMouseListener: function(/*DOMNode*/ node, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay){
+		// summary:
+		//		Start listening for a typematic mouse click.
+		//		See the trigger method for other parameters.
+		// returns:
+		//		an array of dojo.connect handles
+		var dc = dojo.connect;
+		return [
+			dc(node, "mousedown", this, function(evt){
+				dojo.stopEvent(evt);
+				dijit.typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay);
+			}),
+			dc(node, "mouseup", this, function(evt){
+				dojo.stopEvent(evt);
+				dijit.typematic.stop();
+			}),
+			dc(node, "mouseout", this, function(evt){
+				dojo.stopEvent(evt);
+				dijit.typematic.stop();
+			}),
+			dc(node, "mousemove", this, function(evt){
+				dojo.stopEvent(evt);
+			}),
+			dc(node, "dblclick", this, function(evt){
+				dojo.stopEvent(evt);
+				if(dojo.isIE){
+					dijit.typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay);
+					setTimeout(dojo.hitch(this, dijit.typematic.stop), 50);
+				}
+			})
+		];
+	},
+
+	addListener: function(/*Node*/ mouseNode, /*Node*/ keyNode, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay){
+		// summary:
+		//		Start listening for a specific typematic key and mouseclick.
+		//		This is a thin wrapper to addKeyListener and addMouseListener.
+		//		See the addMouseListener and addKeyListener methods for other parameters.
+		// mouseNode:
+		//		the DOM node object to listen on for mouse events.
+		// keyNode:
+		//		the DOM node object to listen on for key events.
+		// returns:
+		//		an array of dojo.connect handles
+		return this.addKeyListener(keyNode, keyObject, _this, callback, subsequentDelay, initialDelay).concat(
+			this.addMouseListener(mouseNode, _this, callback, subsequentDelay, initialDelay));
+	}
+};
+
+}
+
+if(!dojo._hasResource["dijit._base.wai"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.wai"] = true;
+dojo.provide("dijit._base.wai");
+
+dijit.wai = {
+	onload: function(){
+		// summary:
+		//		Detects if we are in high-contrast mode or not
+
+		// This must be a named function and not an anonymous
+		// function, so that the widget parsing code can make sure it
+		// registers its onload function after this function.
+		// DO NOT USE "this" within this function.
+
+		// create div for testing if high contrast mode is on or images are turned off
+		var div = dojo.create("div",{
+			id: "a11yTestNode",
+			style:{
+				cssText:'border: 1px solid;'
+					+ 'border-color:red green;'
+					+ 'position: absolute;'
+					+ 'height: 5px;'
+					+ 'top: -999px;'
+					+ 'background-image: url("' + (dojo.config.blankGif || dojo.moduleUrl("dojo", "resources/blank.gif")) + '");'
+			}
+		}, dojo.body());
+
+		// test it
+		var cs = dojo.getComputedStyle(div);
+		if(cs){
+			var bkImg = cs.backgroundImage;
+			var needsA11y = (cs.borderTopColor==cs.borderRightColor) || (bkImg != null && (bkImg == "none" || bkImg == "url(invalid-url:)" ));
+			dojo[needsA11y ? "addClass" : "removeClass"](dojo.body(), "dijit_a11y");
+			if(dojo.isIE){
+				div.outerHTML = "";		// prevent mixed-content warning, see http://support.microsoft.com/kb/925014
+			}else{
+				dojo.body().removeChild(div);
+			}
+		}
+	}
+};
+
+// Test if computer is in high contrast mode.
+// Make sure the a11y test runs first, before widgets are instantiated.
+if(dojo.isIE || dojo.isMoz){	// NOTE: checking in Safari messes things up
+	dojo._loaders.unshift(dijit.wai.onload);
+}
+
+dojo.mixin(dijit,
+{
+	_XhtmlRoles: /banner|contentinfo|definition|main|navigation|search|note|secondary|seealso/,
+
+	hasWaiRole: function(/*Element*/ elem, /*String*/ role){
+		// summary:
+		//		Determines if an element has a particular non-XHTML role.
+		// returns:
+		//		True if elem has the specific non-XHTML role attribute and false if not.
+		// 		For backwards compatibility if role parameter not provided, 
+		// 		returns true if has non XHTML role 
+		var waiRole = this.getWaiRole(elem);		
+		return role ? (waiRole.indexOf(role) > -1) : (waiRole.length > 0);
+	},
+
+	getWaiRole: function(/*Element*/ elem){
+		// summary:
+		//		Gets the non-XHTML role for an element (which should be a wai role).
+		// returns:
+		//		The non-XHTML role of elem or an empty string if elem
+		//		does not have a role.
+		 return dojo.trim((dojo.attr(elem, "role") || "").replace(this._XhtmlRoles,"").replace("wairole:",""));
+	},
+
+	setWaiRole: function(/*Element*/ elem, /*String*/ role){
+		// summary:
+		//		Sets the role on an element.
+		// description:
+		//		In other than FF2 replace existing role attribute with new role.
+		//		FF3 supports XHTML and ARIA roles so    
+		//		if elem already has an XHTML role, append this role to XHTML role 
+		//		and remove other ARIA roles.
+		//		On Firefox 2 and below, "wairole:" is
+		//		prepended to the provided role value.
+
+		var curRole = dojo.attr(elem, "role") || "";
+		if(dojo.isFF < 3 || !this._XhtmlRoles.test(curRole)){
+			dojo.attr(elem, "role", dojo.isFF < 3 ? "wairole:" + role : role);
+		}else{
+			if((" "+ curRole +" ").indexOf(" " + role + " ") < 0){
+				var clearXhtml = dojo.trim(curRole.replace(this._XhtmlRoles, ""));
+				var cleanRole = dojo.trim(curRole.replace(clearXhtml, ""));	 
+         		dojo.attr(elem, "role", cleanRole + (cleanRole ? ' ' : '') + role);
+			}
+		}
+	},
+
+	removeWaiRole: function(/*Element*/ elem, /*String*/ role){
+		// summary:
+		//		Removes the specified non-XHTML role from an element.
+		// 		Removes role attribute if no specific role provided (for backwards compat.)
+
+		var roleValue = dojo.attr(elem, "role"); 
+		if(!roleValue){ return; }
+		if(role){
+			var searchRole = dojo.isFF < 3 ? "wairole:" + role : role;
+			var t = dojo.trim((" " + roleValue + " ").replace(" " + searchRole + " ", " "));
+			dojo.attr(elem, "role", t);
+		}else{
+			elem.removeAttribute("role");	
+		}
+	},
+
+	hasWaiState: function(/*Element*/ elem, /*String*/ state){
+		// summary:
+		//		Determines if an element has a given state.
+		// description:
+		//		On Firefox 2 and below, we check for an attribute in namespace
+		//		"http://www.w3.org/2005/07/aaa" with a name of the given state.
+		//		On all other browsers, we check for an attribute
+		//		called "aria-"+state.
+		// returns:
+		//		true if elem has a value for the given state and
+		//		false if it does not.
+		if(dojo.isFF < 3){
+			return elem.hasAttributeNS("http://www.w3.org/2005/07/aaa", state);
+		}
+		return elem.hasAttribute ? elem.hasAttribute("aria-"+state) : !!elem.getAttribute("aria-"+state);
+	},
+
+	getWaiState: function(/*Element*/ elem, /*String*/ state){
+		// summary:
+		//		Gets the value of a state on an element.
+		// description:
+		//		On Firefox 2 and below, we check for an attribute in namespace
+		//		"http://www.w3.org/2005/07/aaa" with a name of the given state.
+		//		On all other browsers, we check for an attribute called
+		//		"aria-"+state.
+		// returns:
+		//		The value of the requested state on elem
+		//		or an empty string if elem has no value for state.
+		if(dojo.isFF < 3){
+			return elem.getAttributeNS("http://www.w3.org/2005/07/aaa", state);
+		}
+		return elem.getAttribute("aria-"+state) || "";
+	},
+
+	setWaiState: function(/*Element*/ elem, /*String*/ state, /*String*/ value){
+		// summary:
+		//		Sets a state on an element.
+		// description:
+		//		On Firefox 2 and below, we set an attribute in namespace
+		//		"http://www.w3.org/2005/07/aaa" with a name of the given state.
+		//		On all other browsers, we set an attribute called
+		//		"aria-"+state.
+		if(dojo.isFF < 3){
+			elem.setAttributeNS("http://www.w3.org/2005/07/aaa",
+				"aaa:"+state, value);
+		}else{
+			elem.setAttribute("aria-"+state, value);
+		}
+	},
+
+	removeWaiState: function(/*Element*/ elem, /*String*/ state){
+		// summary:
+		//		Removes a state from an element.
+		// description:
+		//		On Firefox 2 and below, we remove the attribute in namespace
+		//		"http://www.w3.org/2005/07/aaa" with a name of the given state.
+		//		On all other browsers, we remove the attribute called
+		//		"aria-"+state.
+		if(dojo.isFF < 3){
+			elem.removeAttributeNS("http://www.w3.org/2005/07/aaa", state);
+		}else{
+			elem.removeAttribute("aria-"+state);
+		}
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base"] = true;
+dojo.provide("dijit._base");
+
+
+
+
+
+
+
+
+
+
+
+}
+
+if(!dojo._hasResource["dojo.date.stamp"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.date.stamp"] = true;
+dojo.provide("dojo.date.stamp");
+
+// Methods to convert dates to or from a wire (string) format using well-known conventions
+
+dojo.date.stamp.fromISOString = function(/*String*/formattedString, /*Number?*/defaultTime){
+	//	summary:
+	//		Returns a Date object given a string formatted according to a subset of the ISO-8601 standard.
+	//
+	//	description:
+	//		Accepts a string formatted according to a profile of ISO8601 as defined by
+	//		[RFC3339](http://www.ietf.org/rfc/rfc3339.txt), except that partial input is allowed.
+	//		Can also process dates as specified [by the W3C](http://www.w3.org/TR/NOTE-datetime)
+	//		The following combinations are valid:
+	//
+	//			* dates only
+	//			|	* yyyy
+	//			|	* yyyy-MM
+	//			|	* yyyy-MM-dd
+	// 			* times only, with an optional time zone appended
+	//			|	* THH:mm
+	//			|	* THH:mm:ss
+	//			|	* THH:mm:ss.SSS
+	// 			* and "datetimes" which could be any combination of the above
+	//
+	//		timezones may be specified as Z (for UTC) or +/- followed by a time expression HH:mm
+	//		Assumes the local time zone if not specified.  Does not validate.  Improperly formatted
+	//		input may return null.  Arguments which are out of bounds will be handled
+	// 		by the Date constructor (e.g. January 32nd typically gets resolved to February 1st)
+	//		Only years between 100 and 9999 are supported.
+	//
+  	//	formattedString:
+	//		A string such as 2005-06-30T08:05:00-07:00 or 2005-06-30 or T08:05:00
+	//
+	//	defaultTime:
+	//		Used for defaults for fields omitted in the formattedString.
+	//		Uses 1970-01-01T00:00:00.0Z by default.
+
+	if(!dojo.date.stamp._isoRegExp){
+		dojo.date.stamp._isoRegExp =
+//TODO: could be more restrictive and check for 00-59, etc.
+			/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(.\d+)?)?((?:[+-](\d{2}):(\d{2}))|Z)?)?$/;
+	}
+
+	var match = dojo.date.stamp._isoRegExp.exec(formattedString);
+	var result = null;
+
+	if(match){
+		match.shift();
+		if(match[1]){match[1]--;} // Javascript Date months are 0-based
+		if(match[6]){match[6] *= 1000;} // Javascript Date expects fractional seconds as milliseconds
+
+		if(defaultTime){
+			// mix in defaultTime.  Relatively expensive, so use || operators for the fast path of defaultTime === 0
+			defaultTime = new Date(defaultTime);
+			dojo.map(["FullYear", "Month", "Date", "Hours", "Minutes", "Seconds", "Milliseconds"], function(prop){
+				return defaultTime["get" + prop]();
+			}).forEach(function(value, index){
+				if(match[index] === undefined){
+					match[index] = value;
+				}
+			});
+		}
+		result = new Date(match[0]||1970, match[1]||0, match[2]||1, match[3]||0, match[4]||0, match[5]||0, match[6]||0);
+//		result.setFullYear(match[0]||1970); // for year < 100
+
+		var offset = 0;
+		var zoneSign = match[7] && match[7].charAt(0);
+		if(zoneSign != 'Z'){
+			offset = ((match[8] || 0) * 60) + (Number(match[9]) || 0);
+			if(zoneSign != '-'){ offset *= -1; }
+		}
+		if(zoneSign){
+			offset -= result.getTimezoneOffset();
+		}
+		if(offset){
+			result.setTime(result.getTime() + offset * 60000);
+		}
+	}
+
+	return result; // Date or null
+}
+
+/*=====
+	dojo.date.stamp.__Options = function(){
+		//	selector: String
+		//		"date" or "time" for partial formatting of the Date object.
+		//		Both date and time will be formatted by default.
+		//	zulu: Boolean
+		//		if true, UTC/GMT is used for a timezone
+		//	milliseconds: Boolean
+		//		if true, output milliseconds
+		this.selector = selector;
+		this.zulu = zulu;
+		this.milliseconds = milliseconds;
+	}
+=====*/
+
+dojo.date.stamp.toISOString = function(/*Date*/dateObject, /*dojo.date.stamp.__Options?*/options){
+	//	summary:
+	//		Format a Date object as a string according a subset of the ISO-8601 standard
+	//
+	//	description:
+	//		When options.selector is omitted, output follows [RFC3339](http://www.ietf.org/rfc/rfc3339.txt)
+	//		The local time zone is included as an offset from GMT, except when selector=='time' (time without a date)
+	//		Does not check bounds.  Only years between 100 and 9999 are supported.
+	//
+	//	dateObject:
+	//		A Date object
+
+	var _ = function(n){ return (n < 10) ? "0" + n : n; };
+	options = options || {};
+	var formattedDate = [];
+	var getter = options.zulu ? "getUTC" : "get";
+	var date = "";
+	if(options.selector != "time"){
+		var year = dateObject[getter+"FullYear"]();
+		date = ["0000".substr((year+"").length)+year, _(dateObject[getter+"Month"]()+1), _(dateObject[getter+"Date"]())].join('-');
+	}
+	formattedDate.push(date);
+	if(options.selector != "date"){
+		var time = [_(dateObject[getter+"Hours"]()), _(dateObject[getter+"Minutes"]()), _(dateObject[getter+"Seconds"]())].join(':');
+		var millis = dateObject[getter+"Milliseconds"]();
+		if(options.milliseconds){
+			time += "."+ (millis < 100 ? "0" : "") + _(millis);
+		}
+		if(options.zulu){
+			time += "Z";
+		}else if(options.selector != "time"){
+			var timezoneOffset = dateObject.getTimezoneOffset();
+			var absOffset = Math.abs(timezoneOffset);
+			time += (timezoneOffset > 0 ? "-" : "+") + 
+				_(Math.floor(absOffset/60)) + ":" + _(absOffset%60);
+		}
+		formattedDate.push(time);
+	}
+	return formattedDate.join('T'); // String
+}
+
+}
+
+if(!dojo._hasResource["dojo.parser"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.parser"] = true;
+dojo.provide("dojo.parser");
+
+
+dojo.parser = new function(){
+	// summary: The Dom/Widget parsing package
+
+	var d = dojo;
+	var dtName = d._scopeName + "Type";
+	var qry = "[" + dtName + "]";
+
+	var _anonCtr = 0, _anon = {};
+	var nameAnonFunc = function(/*Function*/anonFuncPtr, /*Object*/thisObj){
+		// summary:
+		//		Creates a reference to anonFuncPtr in thisObj with a completely
+		//		unique name. The new name is returned as a String. 
+		var nso = thisObj || _anon;
+		if(dojo.isIE){
+			var cn = anonFuncPtr["__dojoNameCache"];
+			if(cn && nso[cn] === anonFuncPtr){
+				return cn;
+			}
+		}
+		var name;
+		do{
+			name = "__" + _anonCtr++;
+		}while(name in nso)
+		nso[name] = anonFuncPtr;
+		return name; // String
+	}
+
+	function val2type(/*Object*/ value){
+		// summary:
+		//		Returns name of type of given value.
+
+		if(d.isString(value)){ return "string"; }
+		if(typeof value == "number"){ return "number"; }
+		if(typeof value == "boolean"){ return "boolean"; }
+		if(d.isFunction(value)){ return "function"; }
+		if(d.isArray(value)){ return "array"; } // typeof [] == "object"
+		if(value instanceof Date) { return "date"; } // assume timestamp
+		if(value instanceof d._Url){ return "url"; }
+		return "object";
+	}
+
+	function str2obj(/*String*/ value, /*String*/ type){
+		// summary:
+		//		Convert given string value to given type
+		switch(type){
+			case "string":
+				return value;
+			case "number":
+				return value.length ? Number(value) : NaN;
+			case "boolean":
+				// for checked/disabled value might be "" or "checked".  interpret as true.
+				return typeof value == "boolean" ? value : !(value.toLowerCase()=="false");
+			case "function":
+				if(d.isFunction(value)){
+					// IE gives us a function, even when we say something like onClick="foo"
+					// (in which case it gives us an invalid function "function(){ foo }"). 
+					//  Therefore, convert to string
+					value=value.toString();
+					value=d.trim(value.substring(value.indexOf('{')+1, value.length-1));
+				}
+				try{
+					if(value.search(/[^\w\.]+/i) != -1){
+						// TODO: "this" here won't work
+						value = nameAnonFunc(new Function(value), this);
+					}
+					return d.getObject(value, false);
+				}catch(e){ return new Function(); }
+			case "array":
+				return value ? value.split(/\s*,\s*/) : [];
+			case "date":
+				switch(value){
+					case "": return new Date("");	// the NaN of dates
+					case "now": return new Date();	// current date
+					default: return d.date.stamp.fromISOString(value);
+				}
+			case "url":
+				return d.baseUrl + value;
+			default:
+				return d.fromJson(value);
+		}
+	}
+
+	var instanceClasses = {
+		// map from fully qualified name (like "dijit.Button") to structure like
+		// { cls: dijit.Button, params: {label: "string", disabled: "boolean"} }
+	};
+	
+	function getClassInfo(/*String*/ className){
+		// className:
+		//		fully qualified name (like "dijit.form.Button")
+		// returns:
+		//		structure like
+		//			{ 
+		//				cls: dijit.Button, 
+		//				params: { label: "string", disabled: "boolean"}
+		//			}
+
+		if(!instanceClasses[className]){
+			// get pointer to widget class
+			var cls = d.getObject(className);
+			if(!d.isFunction(cls)){
+				throw new Error("Could not load class '" + className +
+					"'. Did you spell the name correctly and use a full path, like 'dijit.form.Button'?");
+			}
+			var proto = cls.prototype;
+	
+			// get table of parameter names & types
+			var params = {}, dummyClass = {};
+			for(var name in proto){
+				if(name.charAt(0)=="_"){ continue; } 	// skip internal properties
+				if(name in dummyClass){ continue; }		// skip "constructor" and "toString"
+				var defVal = proto[name];
+				params[name]=val2type(defVal);
+			}
+
+			instanceClasses[className] = { cls: cls, params: params };
+		}
+		return instanceClasses[className];
+	}
+
+	this._functionFromScript = function(script){
+		var preamble = "";
+		var suffix = "";
+		var argsStr = script.getAttribute("args");
+		if(argsStr){
+			d.forEach(argsStr.split(/\s*,\s*/), function(part, idx){
+				preamble += "var "+part+" = arguments["+idx+"]; ";
+			});
+		}
+		var withStr = script.getAttribute("with");
+		if(withStr && withStr.length){
+			d.forEach(withStr.split(/\s*,\s*/), function(part){
+				preamble += "with("+part+"){";
+				suffix += "}";
+			});
+		}
+		return new Function(preamble+script.innerHTML+suffix);
+	}
+
+	this.instantiate = function(/* Array */nodes, /* Object? */mixin){
+		// summary:
+		//		Takes array of nodes, and turns them into class instances and
+		//		potentially calls a layout method to allow them to connect with
+		//		any children		
+		// mixin: Object
+		//		An object that will be mixed in with each node in the array.
+		//		Values in the mixin will override values in the node, if they
+		//		exist.
+		var thelist = [];
+		mixin = mixin||{};
+		d.forEach(nodes, function(node){
+			if(!node){ return; }
+			var type = dtName in mixin?mixin[dtName]:node.getAttribute(dtName);
+			if(!type || !type.length){ return; }
+			var clsInfo = getClassInfo(type),
+				clazz = clsInfo.cls,
+				ps = clazz._noScript || clazz.prototype._noScript;
+
+			// read parameters (ie, attributes).
+			// clsInfo.params lists expected params like {"checked": "boolean", "n": "number"}
+			var params = {},
+				attributes = node.attributes;
+			for(var name in clsInfo.params){
+				var item = name in mixin?{value:mixin[name],specified:true}:attributes.getNamedItem(name);
+				if(!item || (!item.specified && (!dojo.isIE || name.toLowerCase()!="value"))){ continue; }
+				var value = item.value;
+				// Deal with IE quirks for 'class' and 'style'
+				switch(name){
+				case "class":
+					value = "className" in mixin?mixin.className:node.className;
+					break;
+				case "style":
+					value = "style" in mixin?mixin.style:(node.style && node.style.cssText); // FIXME: Opera?
+				}
+				var _type = clsInfo.params[name];
+				if(typeof value == "string"){
+					params[name] = str2obj(value, _type);
+				}else{
+					params[name] = value;
+				}
+			}
+
+			// Process <script type="dojo/*"> script tags
+			// <script type="dojo/method" event="foo"> tags are added to params, and passed to
+			// the widget on instantiation.
+			// <script type="dojo/method"> tags (with no event) are executed after instantiation
+			// <script type="dojo/connect" event="foo"> tags are dojo.connected after instantiation
+			// note: dojo/* script tags cannot exist in self closing widgets, like <input />
+			if(!ps){
+				var connects = [],	// functions to connect after instantiation
+					calls = [];		// functions to call after instantiation
+
+				d.query("> script[type^='dojo/']", node).orphan().forEach(function(script){
+					var event = script.getAttribute("event"),
+						type = script.getAttribute("type"),
+						nf = d.parser._functionFromScript(script);
+					if(event){
+						if(type == "dojo/connect"){
+							connects.push({event: event, func: nf});
+						}else{
+							params[event] = nf;
+						}
+					}else{
+						calls.push(nf);
+					}
+				});
+			}
+
+			var markupFactory = clazz["markupFactory"];
+			if(!markupFactory && clazz["prototype"]){
+				markupFactory = clazz.prototype["markupFactory"];
+			}
+			// create the instance
+			var instance = markupFactory ? markupFactory(params, node, clazz) : new clazz(params, node);
+			thelist.push(instance);
+
+			// map it to the JS namespace if that makes sense
+			var jsname = node.getAttribute("jsId");
+			if(jsname){
+				d.setObject(jsname, instance);
+			}
+
+			// process connections and startup functions
+			if(!ps){
+				d.forEach(connects, function(connect){
+					d.connect(instance, connect.event, null, connect.func);
+				});
+				d.forEach(calls, function(func){
+					func.call(instance);
+				});
+			}
+		});
+
+		// Call startup on each top level instance if it makes sense (as for
+		// widgets).  Parent widgets will recursively call startup on their
+		// (non-top level) children
+		d.forEach(thelist, function(instance){
+			if(	instance  && 
+				instance.startup &&
+				!instance._started && 
+				(!instance.getParent || !instance.getParent())
+			){
+				instance.startup();
+			}
+		});
+		return thelist;
+	};
+
+	this.parse = function(/*DomNode?*/ rootNode){
+		// summary:
+		//		Search specified node (or root node) recursively for class instances,
+		//		and instantiate them Searches for
+		//		dojoType="qualified.class.name"
+		var list = d.query(qry, rootNode);
+		// go build the object instances
+		var instances = this.instantiate(list);
+		return instances;
+	};
+}();
+
+//Register the parser callback. It should be the first callback
+//after the a11y test.
+
+(function(){
+	var parseRunner = function(){ 
+		if(dojo.config["parseOnLoad"] == true){
+			dojo.parser.parse(); 
+		}
+	};
+
+	// FIXME: need to clobber cross-dependency!!
+	if(dojo.exists("dijit.wai.onload") && (dijit.wai.onload === dojo._loaders[0])){
+		dojo._loaders.splice(1, 0, parseRunner);
+	}else{
+		dojo._loaders.unshift(parseRunner);
+	}
+})();
+
+}
+
+if(!dojo._hasResource["dijit._Widget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._Widget"] = true;
+dojo.provide("dijit._Widget");
+
+dojo.require( "dijit._base" );
+
+dojo.connect(dojo, "connect", 
+	function(/*Widget*/ widget, /*String*/ event){
+		if(widget && dojo.isFunction(widget._onConnect)){
+			widget._onConnect(event);
+		}
+	});
+
+dijit._connectOnUseEventHandler = function(/*Event*/ event){};
+
+(function(){
+
+var _attrReg = {};
+var getAttrReg = function(dc){
+	if(!_attrReg[dc]){
+		var r = [];
+		var attrs;
+		var proto = dojo.getObject(dc).prototype;
+		for(var fxName in proto){
+			if(dojo.isFunction(proto[fxName]) && (attrs = fxName.match(/^_set([a-zA-Z]*)Attr$/)) && attrs[1]){
+				r.push(attrs[1].charAt(0).toLowerCase() + attrs[1].substr(1));
+			}
+		}
+		_attrReg[dc] = r;
+	}
+	return _attrReg[dc]||[];
+}
+
+dojo.declare("dijit._Widget", null, {
+	// summary:
+	//		Base class for all dijit widgets. 	
+
+	// id: [const] String
+	//		A unique, opaque ID string that can be assigned by users or by the
+	//		system. If the developer passes an ID which is known not to be
+	//		unique, the specified ID is ignored and the system-generated ID is
+	//		used instead.
+	id: "",
+
+	// lang: [const] String
+	//		Rarely used.  Overrides the default Dojo locale used to render this widget,
+	//		as defined by the [HTML LANG](http://www.w3.org/TR/html401/struct/dirlang.html#adef-lang) attribute.
+	//		Value must be among the list of locales specified during by the Dojo bootstrap,
+	//		formatted according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt) (like en-us).
+	lang: "",
+
+	// dir: [const] String
+	//		Unsupported by Dijit, but here for completeness.  Dijit only supports setting text direction on the
+	//		entire document.
+	//		Bi-directional support, as defined by the [HTML DIR](http://www.w3.org/TR/html401/struct/dirlang.html#adef-dir)
+	//		attribute. Either left-to-right "ltr" or right-to-left "rtl".
+	dir: "",
+
+	// class: String
+	//		HTML class attribute
+	"class": "",
+
+	// style: String||Object
+	//		HTML style attributes as cssText string or name/value hash
+	style: "",
+
+	// title: String
+	//		HTML title attribute, used to specify the title of tabs, accordion panes, etc.
+	title: "",
+
+	// srcNodeRef: [readonly] DomNode
+	//		pointer to original dom node
+	srcNodeRef: null,
+
+	// domNode: [readonly] DomNode
+	//		This is our visible representation of the widget! Other DOM
+	//		Nodes may by assigned to other properties, usually through the
+	//		template system's dojoAttachPoint syntax, but the domNode
+	//		property is the canonical "top level" node in widget UI.
+	domNode: null,
+
+	// containerNode: [readonly] DomNode
+	//		Designates where children of the source dom node will be placed.
+	//		"Children" in this case refers to both dom nodes and widgets.
+	//		For example, for myWidget:
+	//
+	//		|	<div dojoType=myWidget>
+	//		|		<b> here's a plain dom node
+	//		|		<span dojoType=subWidget>and a widget</span>
+	//		|		<i> and another plain dom node </i>
+	//		|	</div>
+	//
+	//		containerNode would point to:
+	//
+	//		|		<b> here's a plain dom node
+	//		|		<span dojoType=subWidget>and a widget</span>
+	//		|		<i> and another plain dom node </i>
+	//
+	//		In templated widgets, "containerNode" is set via a
+	//		dojoAttachPoint assignment.
+	//
+	//		containerNode must be defined for any widget that accepts innerHTML
+	//		(like ContentPane or BorderContainer or even Button), and conversely
+	//		is null for widgets that don't, like TextBox.
+	containerNode: null,
+
+	// attributeMap: [protected] Object
+	//		attributeMap sets up a "binding" between attributes (aka properties)
+	//		of the widget and the widget's DOM.
+	//		Changes to widget attributes listed in attributeMap will be 
+	//		reflected into the DOM.
+	//
+	//		For example, calling attr('title', 'hello')
+	//		on a TitlePane will automatically cause the TitlePane's DOM to update
+	//		with the new title.
+	//
+	//		attributeMap is a hash where the key is an attribute of the widget,
+	//		and the value reflects a binding to a:
+	//
+	//		- DOM node attribute
+	// |		focus: {node: "focusNode", type: "attribute"}
+	// 		Maps this.focus to this.focusNode.focus
+	//
+	//		- DOM node innerHTML
+	//	|		title: { node: "titleNode", type: "innerHTML" }
+	//		Maps this.title to this.titleNode.innerHTML
+	//
+	//		- DOM node CSS class
+	// |		myClass: { node: "domNode", type: "class" }
+	//		Maps this.myClass to this.domNode.className
+	//
+	//		If the value is an array, then each element in the array matches one of the
+	//		formats of the above list.
+	//
+	//		There are also some shorthands for backwards compatibility:
+	//		- string --> { node: string, type: "attribute" }, for example:
+	//	|	"focusNode" ---> { node: "focusNode", type: "attribute" }
+	//		- "" --> { node: "domNode", type: "attribute" }
+	attributeMap: {id:"", dir:"", lang:"", "class":"", style:"", title:""},
+
+	// _deferredConnects: [protected] Object
+	//		attributeMap addendum for event handlers that should be connected only on first use
+	_deferredConnects: {
+		onClick: "",
+		onDblClick: "",
+		onKeyDown: "",
+		onKeyPress: "",
+		onKeyUp: "",
+		onMouseMove: "",
+		onMouseDown: "",
+		onMouseOut: "",
+		onMouseOver: "",
+		onMouseLeave: "",
+		onMouseEnter: "",
+		onMouseUp: ""},
+
+	onClick: dijit._connectOnUseEventHandler,
+	/*=====
+	onClick: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of mouse click events.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onDblClick: dijit._connectOnUseEventHandler,
+	/*=====
+	onDblClick: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of mouse double click events.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onKeyDown: dijit._connectOnUseEventHandler,
+	/*=====
+	onKeyDown: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of keys being pressed down.
+		// event:
+		//		key Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onKeyPress: dijit._connectOnUseEventHandler,
+	/*=====
+	onKeyPress: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of printable keys being typed.
+		// event:
+		//		key Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onKeyUp: dijit._connectOnUseEventHandler,
+	/*=====
+	onKeyUp: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of keys being released.
+		// event:
+		//		key Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseDown: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseDown: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse button is pressed down.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseMove: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseMove: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse moves over nodes contained within this widget.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseOut: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseOut: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse moves off of nodes contained within this widget.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseOver: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseOver: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse moves onto nodes contained within this widget.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseLeave: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseLeave: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse moves off of this widget.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseEnter: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseEnter: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse moves onto this widget.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+	onMouseUp: dijit._connectOnUseEventHandler,
+	/*=====
+	onMouseUp: function(event){
+		// summary: 
+		//		Connect to this function to receive notifications of when the mouse button is released.
+		// event:
+		//		mouse Event
+		// tags:
+		//		callback
+	},
+	=====*/
+
+	// Constants used in templates
+	
+	// _blankGif: [protected] URL
+	//		Used by <img> nodes in templates that really get there image via CSS background-image
+	_blankGif: (dojo.config.blankGif || dojo.moduleUrl("dojo", "resources/blank.gif")),
+
+	//////////// INITIALIZATION METHODS ///////////////////////////////////////
+
+	postscript: function(/*Object?*/params, /*DomNode|String*/srcNodeRef){
+		// summary:
+		//		Kicks off widget instantiation.  See create() for details.
+		// tags:
+		//		private
+		this.create(params, srcNodeRef);
+	},
+
+	create: function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){
+		// summary:
+		//		Kick off the life-cycle of a widget
+		// params:
+		//		Hash of initialization parameters for widget, including
+		//		scalar values (like title, duration etc.) and functions,
+		//		typically callbacks like onClick.
+		// srcNodeRef:
+		//		If a srcNodeRef (dom node) is specified:
+		//			- use srcNodeRef.innerHTML as my contents
+		//			- if this is a behavioral widget then apply behavior
+		//			  to that srcNodeRef 
+		//			- otherwise, replace srcNodeRef with my generated DOM
+		//			  tree
+		// description:
+		//		To understand the process by which widgets are instantiated, it
+		//		is critical to understand what other methods create calls and
+		//		which of them you'll want to override. Of course, adventurous
+		//		developers could override create entirely, but this should
+		//		only be done as a last resort.
+		//
+		//		Below is a list of the methods that are called, in the order
+		//		they are fired, along with notes about what they do and if/when
+		//		you should over-ride them in your widget:
+		//
+		// * postMixInProperties:
+		//	|	* a stub function that you can over-ride to modify
+		//		variables that may have been naively assigned by
+		//		mixInProperties
+		// * widget is added to manager object here
+		// * buildRendering:
+		//	|	* Subclasses use this method to handle all UI initialization
+		//		Sets this.domNode.  Templated widgets do this automatically
+		//		and otherwise it just uses the source dom node.
+		// * postCreate:
+		//	|	* a stub function that you can over-ride to modify take
+		//		actions once the widget has been placed in the UI
+		// tags:
+		//		private
+
+		// store pointer to original dom tree
+		this.srcNodeRef = dojo.byId(srcNodeRef);
+
+		// For garbage collection.  An array of handles returned by Widget.connect()
+		// Each handle returned from Widget.connect() is an array of handles from dojo.connect()
+		this._connects = [];
+
+		// To avoid double-connects, remove entries from _deferredConnects
+		// that have been setup manually by a subclass (ex, by dojoAttachEvent).
+		// If a subclass has redefined a callback (ex: onClick) then assume it's being
+		// connected to manually.
+		this._deferredConnects = dojo.clone(this._deferredConnects);
+		for(var attr in this.attributeMap){
+			delete this._deferredConnects[attr]; // can't be in both attributeMap and _deferredConnects
+		}
+		for(attr in this._deferredConnects){
+			if(this[attr] !== dijit._connectOnUseEventHandler){
+				delete this._deferredConnects[attr];	// redefined, probably dojoAttachEvent exists
+			}
+		}
+
+		//mixin our passed parameters
+		if(this.srcNodeRef && (typeof this.srcNodeRef.id == "string")){ this.id = this.srcNodeRef.id; }
+		if(params){
+			this.params = params;
+			dojo.mixin(this,params);
+		}
+		this.postMixInProperties();
+
+		// generate an id for the widget if one wasn't specified
+		// (be sure to do this before buildRendering() because that function might
+		// expect the id to be there.)
+		if(!this.id){
+			this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
+		}
+		dijit.registry.add(this);
+
+		this.buildRendering();
+
+		if(this.domNode){
+			// Copy attributes listed in attributeMap into the [newly created] DOM for the widget.
+			this._applyAttributes();
+
+			var source = this.srcNodeRef;
+			if(source && source.parentNode){
+				source.parentNode.replaceChild(this.domNode, source);
+			}
+
+			// If the developer has specified a handler as a widget parameter
+			// (ex: new Button({onClick: ...})
+			// then naturally need to connect from dom node to that handler immediately, 
+			for(attr in this.params){
+				this._onConnect(attr);
+			}
+		}
+		
+		if(this.domNode){
+			this.domNode.setAttribute("widgetId", this.id);
+		}
+		this.postCreate();
+
+		// If srcNodeRef has been processed and removed from the DOM (e.g. TemplatedWidget) then delete it to allow GC.
+		if(this.srcNodeRef && !this.srcNodeRef.parentNode){
+			delete this.srcNodeRef;
+		}	
+
+		this._created = true;
+	},
+
+	_applyAttributes: function(){
+		// summary:
+		//		Step during widget creation to copy all widget attributes to the
+		//		DOM as per attributeMap and _setXXXAttr functions.
+		// description:
+		//		Skips over blank/false attribute values, unless they were explicitly specified
+		//		as parameters to the widget, since those are the default anyway,
+		//		and setting tabIndex="" is different than not setting tabIndex at all.
+		//
+		//		It processes the attributes in the attribute map first, and then
+		//		it goes through and processes the attributes for the _setXXXAttr
+		//		functions that have been specified
+		// tags:
+		//		private
+		var condAttrApply = function(attr, scope){
+			if( (scope.params && attr in scope.params) || scope[attr]){
+				scope.attr(attr, scope[attr]);
+			}
+		};
+		for(var attr in this.attributeMap){
+			condAttrApply(attr, this);
+		}
+		dojo.forEach(getAttrReg(this.declaredClass), function(a){
+			if(!(a in this.attributeMap)){
+				condAttrApply(a, this);
+			}
+		}, this);
+	},
+
+	postMixInProperties: function(){
+		// summary:
+		//		Called after the parameters to the widget have been read-in,
+		//		but before the widget template is instantiated. Especially
+		//		useful to set properties that are referenced in the widget
+		//		template.
+		// tags:
+		//		protected
+	},
+
+	buildRendering: function(){
+		// summary:
+		//		Construct the UI for this widget, setting this.domNode.  Most
+		//		widgets will mixin `dijit._Templated`, which implements this
+		//		method.
+		// tags:
+		//		protected
+		this.domNode = this.srcNodeRef || dojo.create('div');
+	},
+
+	postCreate: function(){
+		// summary:
+		//		Called after a widget's dom has been setup
+		// tags:
+		//		protected
+	},
+
+	startup: function(){
+		// summary:
+		//		Called after a widget's children, and other widgets on the page, have been created.
+		//		Provides an opportunity to manipulate any children before they are displayed.
+		//		This is useful for composite widgets that need to control or layout sub-widgets.
+		//		Many layout widgets can use this as a wiring phase.
+		this._started = true;
+	},
+
+	//////////// DESTROY FUNCTIONS ////////////////////////////////
+
+	destroyRecursive: function(/*Boolean?*/ preserveDom){
+		// summary:
+		// 		Destroy this widget and it's descendants. This is the generic
+		// 		"destructor" function that all widget users should call to
+		// 		cleanly discard with a widget. Once a widget is destroyed, it's
+		// 		removed from the manager object.
+		// preserveDom:
+		//		If true, this method will leave the original Dom structure
+		//		alone of descendant Widgets. Note: This will NOT work with
+		//		dijit._Templated widgets.
+
+		this.destroyDescendants(preserveDom);
+		this.destroy(preserveDom);
+	},
+
+	destroy: function(/*Boolean*/ preserveDom){
+		// summary:
+		// 		Destroy this widget, but not its descendants.
+		//		Will, however, destroy internal widgets such as those used within a template.
+		// preserveDom: Boolean
+		//		If true, this method will leave the original Dom structure alone.
+		//		Note: This will not yet work with _Templated widgets
+
+		this.uninitialize();
+		dojo.forEach(this._connects, function(array){
+			dojo.forEach(array, dojo.disconnect);
+		});
+
+		// destroy widgets created as part of template, etc.
+		dojo.forEach(this._supportingWidgets||[], function(w){ 
+			if(w.destroy){
+				w.destroy();
+			}
+		});
+		
+		this.destroyRendering(preserveDom);
+		dijit.registry.remove(this.id);
+	},
+
+	destroyRendering: function(/*Boolean?*/ preserveDom){
+		// summary:
+		//		Destroys the DOM nodes associated with this widget
+		// preserveDom:
+		//		If true, this method will leave the original Dom structure alone
+		//		during tear-down. Note: this will not work with _Templated
+		//		widgets yet. 
+		// tags:
+		//		protected
+
+		if(this.bgIframe){
+			this.bgIframe.destroy(preserveDom);
+			delete this.bgIframe;
+		}
+
+		if(this.domNode){
+			if(preserveDom){
+				dojo.removeAttr(this.domNode, "widgetId");
+			}else{
+				dojo.destroy(this.domNode);
+			}
+			delete this.domNode;
+		}
+
+		if(this.srcNodeRef){
+			if(!preserveDom){
+				dojo.destroy(this.srcNodeRef);
+			}
+			delete this.srcNodeRef;
+		}
+	},
+
+	destroyDescendants: function(/*Boolean?*/ preserveDom){
+		// summary:
+		//		Recursively destroy the children of this widget and their
+		//		descendants.
+		// preserveDom:
+		//		If true, the preserveDom attribute is passed to all descendant
+		//		widget's .destroy() method. Not for use with _Templated
+		//		widgets.
+
+		// get all direct descendants and destroy them recursively
+		dojo.forEach(this.getChildren(), function(widget){ 
+			if(widget.destroyRecursive){
+				widget.destroyRecursive(preserveDom);
+			}
+		});
+	},
+
+
+	uninitialize: function(){
+		// summary:
+		//		Stub function. Override to implement custom widget tear-down
+		//		behavior.
+		// tags:
+		//		protected
+		return false;
+	},
+
+	////////////////// MISCELLANEOUS METHODS ///////////////////
+
+	onFocus: function(){
+		// summary:
+		//		Called when the widget becomes "active" because
+		//		it or a widget inside of it either has focus, or has recently
+		//		been clicked.
+		// tags:
+		//		callback
+	},
+
+	onBlur: function(){
+		// summary:
+		//		Called when the widget stops being "active" because
+		//		focus moved to something outside of it, or the user
+		//		clicked somewhere outside of it, or the widget was
+		//		hidden.
+		// tags:
+		//		callback
+	},
+
+	_onFocus: function(e){
+		// summary:
+		//		This is where widgets do processing for when they are active,
+		//		such as changing CSS classes.  See onFocus() for more details.
+		// tags:
+		//		protected
+		this.onFocus();
+	},
+
+	_onBlur: function(){
+		// summary:
+		//		This is where widgets do processing for when they stop being active,
+		//		such as changing CSS classes.  See onBlur() for more details.
+		// tags:
+		//		protected
+		this.onBlur();
+	},
+
+	_onConnect: function(/*String*/ event){
+		// summary:
+		//		Called when someone connects to one of my handlers.
+		//		"Turn on" that handler if it isn't active yet.
+		//
+		//		This is also called for every single initialization parameter
+		//		so need to do nothing for parameters like "id".
+		// tags:
+		//		private
+		if(event in this._deferredConnects){
+			var mapNode = this[this._deferredConnects[event]||'domNode'];
+			this.connect(mapNode, event.toLowerCase(), event);
+			delete this._deferredConnects[event];
+		}
+	},
+
+	_setClassAttr: function(/*String*/ value){
+		// summary:
+		//		Custom setter for the CSS "class" attribute
+		// tags:
+		//		protected
+		var mapNode = this[this.attributeMap["class"]||'domNode'];
+		dojo.removeClass(mapNode, this["class"])
+		this["class"] = value;
+		dojo.addClass(mapNode, value);
+	},
+
+	_setStyleAttr: function(/*String||Object*/ value){
+		// summary:
+		//		Sets the style attribut of the widget according to value,
+		//		which is either a hash like {height: "5px", width: "3px"}
+		//		or a plain string
+		// description:
+		//		Determines which node to set the style on based on style setting
+		//		in attributeMap.
+		// tags:
+		//		protected
+
+		var mapNode = this[this.attributeMap["style"]||'domNode'];
+		
+		// Note: technically we should revert any style setting made in a previous call
+		// to his method, but that's difficult to keep track of.
+
+		if(dojo.isObject(value)){
+			dojo.style(mapNode, value);
+		}else{
+			if(mapNode.style.cssText){
+				mapNode.style.cssText += "; " + value;
+			}else{
+				mapNode.style.cssText = value;
+			}
+		}
+
+		this["style"] = value;
+	},
+
+	setAttribute: function(/*String*/ attr, /*anything*/ value){
+		// summary:
+		//		Deprecated.  Use attr() instead.
+		// tags:
+		//		deprecated
+		dojo.deprecated(this.declaredClass+"::setAttribute() is deprecated. Use attr() instead.", "", "2.0");
+		this.attr(attr, value);
+	},
+	
+	_attrToDom: function(/*String*/ attr, /*String*/ value){
+		// summary:
+		//		Reflect a widget attribute (title, tabIndex, duration etc.) to
+		//		the widget DOM, as specified in attributeMap.
+		//
+		// description:
+		//		Also sets this["attr"] to the new value.
+		//		Note some attributes like "type"
+		//		cannot be processed this way as they are not mutable.
+		//
+		// tags:
+		//		private
+
+		var commands = this.attributeMap[attr];
+		dojo.forEach( dojo.isArray(commands) ? commands : [commands], function(command){
+
+			// Get target node and what we are doing to that node
+			var mapNode = this[command.node || command || "domNode"];	// DOM node
+			var type = command.type || "attribute";	// class, innerHTML, or attribute
+	
+			switch(type){
+				case "attribute":
+					if(dojo.isFunction(value)){ // functions execute in the context of the widget
+						value = dojo.hitch(this, value);
+					}
+					if(/^on[A-Z][a-zA-Z]*$/.test(attr)){ // eg. onSubmit needs to be onsubmit
+						attr = attr.toLowerCase();
+					}
+					dojo.attr(mapNode, attr, value);
+					break;
+				case "innerHTML":
+					mapNode.innerHTML = value;
+					break;
+				case "class":
+					dojo.removeClass(mapNode, this[attr]);
+					dojo.addClass(mapNode, value);
+					break;
+			}
+		}, this);
+		this[attr] = value;
+	},
+
+	attr: function(/*String|Object*/name, /*Object?*/value){
+		//	summary:
+		//		Set or get properties on a widget instance.
+		//	name:
+		//		The property to get or set. If an object is passed here and not
+		//		a string, its keys are used as names of attributes to be set
+		//		and the value of the object as values to set in the widget.
+		//	value:
+		//		Optional. If provided, attr() operates as a setter. If omitted,
+		//		the current value of the named property is returned.
+		//	description:
+		//		Get or set named properties on a widget. If no value is
+		//		provided, the current value of the attribute is returned,
+		//		potentially via a getter method. If a value is provided, then
+		//		the method acts as a setter, assigning the value to the name,
+		//		potentially calling any explicitly provided setters to handle
+		//		the operation. For instance, if the widget has properties "foo"
+		//		and "bar" and a method named "_setFooAttr", calling:
+		//	|	myWidget.attr("foo", "Howdy!");
+		//		would be equivalent to calling:
+		//	|	widget._setFooAttr("Howdy!");
+		//		while calling:
+		//	|	myWidget.attr("bar", "Howdy!");
+		//		would be the same as writing:
+		//	|	widget.bar = "Howdy!";
+		//		It also tries to copy the changes to the widget's DOM according
+		//		to settings in attributeMap (see description of `dijit._Widget.attributeMap`
+		//		for details)
+		//		For example, calling:
+		//	|	myTitlePane.attr("title", "Howdy!");
+		//		will do
+		//	|	myTitlePane.title = "Howdy!";
+		//	|	myTitlePane.title.innerHTML = "Howdy!";
+		//		It works for dom node attributes too.  Calling
+		//	|	widget.attr("disabled", true)
+		//		will set the disabled attribute on the widget's focusNode,
+		//		among other housekeeping for a change in disabled state.
+
+		//	open questions:
+		//		- how to handle build shortcut for attributes which want to map
+		//		into DOM attributes?
+		//		- what relationship should setAttribute()/attr() have to
+		//		layout() calls?
+		var args = arguments.length;
+		if(args == 1 && !dojo.isString(name)){
+			for(var x in name){ this.attr(x, name[x]); }
+			return this;
+		}
+		var names = this._getAttrNames(name);
+		if(args == 2){ // setter
+			if(this[names.s]){
+				// use the explicit setter
+				return this[names.s](value) || this;
+			}else{
+				// if param is specified as DOM node attribute, copy it
+				if(name in this.attributeMap){
+					this._attrToDom(name, value);
+				}
+
+				// FIXME: what about function assignments? Any way to connect() here?
+				this[name] = value;
+			}
+			return this;
+		}else{ // getter
+			if(this[names.g]){
+				return this[names.g]();
+			}else{
+				return this[name];
+			}
+		}
+	},
+
+	_attrPairNames: {},		// shared between all widgets
+	_getAttrNames: function(name){
+		// summary:
+		//		Helper function for Widget.attr().
+		//		Caches attribute name values so we don't do the string ops every time.
+		// tags:
+		//		private
+
+		var apn = this._attrPairNames;
+		if(apn[name]){ return apn[name]; }
+		var uc = name.charAt(0).toUpperCase() + name.substr(1);
+		return apn[name] = {
+			n: name+"Node",
+			s: "_set"+uc+"Attr",
+			g: "_get"+uc+"Attr"
+		};
+	},
+
+	toString: function(){
+		// summary:
+		//		Returns a string that represents the widget. When a widget is
+		//		cast to a string, this method will be used to generate the
+		//		output. Currently, it does not implement any sort of reversable
+		//		serialization.
+		return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String
+	},
+
+	getDescendants: function(){
+		// summary:
+		//		Returns all the widgets that contained by this, i.e., all widgets underneath this.containerNode.
+		//		This method should generally be avoided as it returns widgets declared in templates, which are
+		//		supposed to be internal/hidden, but it's left here for back-compat reasons.
+
+		if(this.containerNode){
+			var list = dojo.query('[widgetId]', this.containerNode);
+			return list.map(dijit.byNode);		// Array
+		}else{
+			return [];
+		}
+	},
+
+	getChildren: function(){
+		// summary:
+		//		Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
+		//		Does not return nested widgets, nor widgets that are part of this widget's template.
+		if(this.containerNode){
+			return dijit.findWidgets(this.containerNode);
+		}else{
+			return [];
+		}
+	},
+
+	// nodesWithKeyClick: [private] String[]
+	//		List of nodes that correctly handle click events via native browser support,
+	//		and don't need dijit's help
+	nodesWithKeyClick: ["input", "button"],
+
+	connect: function(
+			/*Object|null*/ obj,
+			/*String|Function*/ event,
+			/*String|Function*/ method){
+		// summary:
+		//		Connects specified obj/event to specified method of this object
+		//		and registers for disconnect() on widget destroy.
+		// description:
+		//		Provide widget-specific analog to dojo.connect, except with the
+		//		implicit use of this widget as the target object.
+		//		This version of connect also provides a special "ondijitclick"
+		//		event which triggers on a click or space-up, enter-down in IE
+		//		or enter press in FF (since often can't cancel enter onkeydown
+		//		in FF)
+		// example:
+		//	|	var btn = new dijit.form.Button();
+		//	|	// when foo.bar() is called, call the listener we're going to
+		//	|	// provide in the scope of btn
+		//	|	btn.connect(foo, "bar", function(){ 
+		//	|		
+		//	|	});
+		// tags:
+		//		protected
+
+		var d = dojo;
+		var dc = dojo.connect;
+		var handles =[];
+		if(event == "ondijitclick"){
+			// add key based click activation for unsupported nodes.
+			if(!this.nodesWithKeyClick[obj.nodeName]){
+				var m = d.hitch(this, method);
+				handles.push(
+					dc(obj, "onkeydown", this, function(e){
+						if(!d.isFF && e.keyCode == d.keys.ENTER &&
+							!e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){
+							return m(e);
+						}else if(e.keyCode == d.keys.SPACE){
+							// stop space down as it causes IE to scroll
+							// the browser window
+							d.stopEvent(e);
+						}
+			 		}),
+					dc(obj, "onkeyup", this, function(e){
+						if(e.keyCode == d.keys.SPACE && 
+							!e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){ return m(e); }
+					})
+				);
+			 	if(d.isFF){
+					handles.push(
+						dc(obj, "onkeypress", this, function(e){
+							if(e.keyCode == d.keys.ENTER &&
+								!e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){ return m(e); }
+						})
+					);
+			 	}
+			}
+			event = "onclick";
+		}
+		handles.push(dc(obj, event, this, method));
+
+		// return handles for FormElement and ComboBox
+		this._connects.push(handles);
+		return handles;
+	},
+
+	disconnect: function(/*Object*/ handles){
+		// summary:
+		//		Disconnects handle created by this.connect.
+		//		Also removes handle from this widget's list of connects
+		// tags:
+		//		protected
+		for(var i=0; i<this._connects.length; i++){
+			if(this._connects[i]==handles){
+				dojo.forEach(handles, dojo.disconnect);
+				this._connects.splice(i, 1);
+				return;
+			}
+		}
+	},
+
+	isLeftToRight: function(){
+		// summary:
+		//		Checks the page for text direction
+		// tags:
+		//		protected
+		return dojo._isBodyLtr(); //Boolean
+	},
+
+	isFocusable: function(){
+		// summary:
+		//		Return true if this widget can currently be focused
+		//		and false if not
+		return this.focus && (dojo.style(this.domNode, "display") != "none");
+	},
+	
+	placeAt: function(/* String|DomNode|_Widget */reference, /* String?|Int? */position){
+		// summary:
+		//		Place this widget's domNode reference somewhere in the DOM based
+		//		on standard dojo.place conventions, or passing a Widget reference that
+		//		contains and addChild member.
+		//
+		// description:
+		//		A convenience function provided in all _Widgets, providing a simple
+		//		shorthand mechanism to put an existing (or newly created) Widget
+		//		somewhere in the dom, and allow chaining.
+		//
+		// reference: 
+		//		The String id of a domNode, a domNode reference, or a reference to a Widget posessing 
+		//		an addChild method.
+		//
+		// position: 
+		//		If passed a string or domNode reference, the position argument
+		//		accepts a string just as dojo.place does, one of: "first", "last", 
+		//		"before", or "after". 
+		//
+		//		If passed a _Widget reference, and that widget reference has an ".addChild" method, 
+		//		it will be called passing this widget instance into that method, supplying the optional
+		//		position index passed.
+		//
+		// returns: dijit._Widget
+		//		Provides a useful return of the newly created dijit._Widget instance so you 
+		//		can "chain" this function by instantiating, placing, then saving the return value
+		//		to a variable. 
+		//
+		// example:
+		// | 	// create a Button with no srcNodeRef, and place it in the body:
+		// | 	var button = new dijit.form.Button({ label:"click" }).placeAt(dojo.body());
+		// | 	// now, 'button' is still the widget reference to the newly created button
+		// | 	dojo.connect(button, "onClick", function(e){  });
+		//
+		// example:
+		// |	// create a button out of a node with id="src" and append it to id="wrapper":
+		// | 	var button = new dijit.form.Button({},"src").placeAt("wrapper");
+		//
+		// example:
+		// |	// place a new button as the first element of some div
+		// |	var button = new dijit.form.Button({ label:"click" }).placeAt("wrapper","first");
+		//
+		// example: 
+		// |	// create a contentpane and add it to a TabContainer
+		// |	var tc = dijit.byId("myTabs");
+		// |	new dijit.layout.ContentPane({ href:"foo.html", title:"Wow!" }).placeAt(tc)
+
+		if(reference["declaredClass"] && reference["addChild"]){
+			reference.addChild(this, position);
+		}else{
+			dojo.place(this.domNode, reference, position);
+		}
+		return this;
+	}
+
+});
+
+})();
+
+}
+
+if(!dojo._hasResource["dojo.string"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.string"] = true;
+dojo.provide("dojo.string");
+
+/*=====
+dojo.string = { 
+	// summary: String utilities for Dojo
+};
+=====*/
+
+dojo.string.rep = function(/*String*/str, /*Integer*/num){
+	//	summary:
+	//		Efficiently replicate a string `n` times.
+	//	str:
+	//		the string to replicate
+	//	num:
+	//		number of times to replicate the string
+	
+	if(num <= 0 || !str){ return ""; }
+	
+	var buf = [];
+	for(;;){
+		if(num & 1){
+			buf.push(str);
+		}
+		if(!(num >>= 1)){ break; }
+		str += str;
+	}
+	return buf.join("");	// String
+};
+
+dojo.string.pad = function(/*String*/text, /*Integer*/size, /*String?*/ch, /*Boolean?*/end){
+	//	summary:
+	//		Pad a string to guarantee that it is at least `size` length by
+	//		filling with the character `ch` at either the start or end of the
+	//		string. Pads at the start, by default.
+	//	text:
+	//		the string to pad
+	//	size:
+	//		length to provide padding
+	//	ch:
+	//		character to pad, defaults to '0'
+	//	end:
+	//		adds padding at the end if true, otherwise pads at start
+	//	example:
+	//	|	// Fill the string to length 10 with "+" characters on the right.  Yields "Dojo++++++".
+	//	|	dojo.string.pad("Dojo", 10, "+", true);
+
+	if(!ch){
+		ch = '0';
+	}
+	var out = String(text),
+		pad = dojo.string.rep(ch, Math.ceil((size - out.length) / ch.length));
+	return end ? out + pad : pad + out;	// String
+};
+
+dojo.string.substitute = function(	/*String*/		template, 
+									/*Object|Array*/map, 
+									/*Function?*/	transform, 
+									/*Object?*/		thisObject){
+	//	summary:
+	//		Performs parameterized substitutions on a string. Throws an
+	//		exception if any parameter is unmatched.
+	//	template: 
+	//		a string with expressions in the form `${key}` to be replaced or
+	//		`${key:format}` which specifies a format function. keys are case-sensitive. 
+	//	map:
+	//		hash to search for substitutions
+	//	transform: 
+	//		a function to process all parameters before substitution takes
+	//		place, e.g. dojo.string.encodeXML
+	//	thisObject: 
+	//		where to look for optional format function; default to the global
+	//		namespace
+	//	example:
+	//	|	// returns "File 'foo.html' is not found in directory '/temp'."
+	//	|	dojo.string.substitute(
+	//	|		"File '${0}' is not found in directory '${1}'.",
+	//	|		["foo.html","/temp"]
+	//	|	);
+	//	|
+	//	|	// also returns "File 'foo.html' is not found in directory '/temp'."
+	//	|	dojo.string.substitute(
+	//	|		"File '${name}' is not found in directory '${info.dir}'.",
+	//	|		{ name: "foo.html", info: { dir: "/temp" } }
+	//	|	);
+	//	example:
+	//		use a transform function to modify the values:
+	//	|	// returns "file 'foo.html' is not found in directory '/temp'."
+	//	|	dojo.string.substitute(
+	//	|		"${0} is not found in ${1}.",
+	//	|		["foo.html","/temp"],
+	//	|		function(str){
+	//	|			// try to figure out the type
+	//	|			var prefix = (str.charAt(0) == "/") ? "directory": "file";
+	//	|			return prefix + " '" + str + "'";
+	//	|		}
+	//	|	);
+	//	example:
+	//		use a formatter
+	//	|	// returns "thinger -- howdy"
+	//	|	dojo.string.substitute(
+	//	|		"${0:postfix}", ["thinger"], null, {
+	//	|			postfix: function(value, key){
+	//	|				return value + " -- howdy";
+	//	|			}
+	//	|		}
+	//	|	);
+
+	thisObject = thisObject||dojo.global;
+	transform = (!transform) ? 
+					function(v){ return v; } : 
+					dojo.hitch(thisObject, transform);
+
+	return template.replace(/\$\{([^\s\:\}]+)(?:\:([^\s\:\}]+))?\}/g, function(match, key, format){
+		var value = dojo.getObject(key, false, map);
+		if(format){
+			value = dojo.getObject(format, false, thisObject).call(thisObject, value, key);
+		}
+		return transform(value, key).toString();
+	}); // string
+};
+
+/*=====
+dojo.string.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 taken from [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript).
+	//		The short yet performant version of this function is dojo.trim(),
+	//		which is part of Dojo base.  Uses String.prototype.trim instead, if available.
+	return "";	// String
+}
+=====*/
+
+dojo.string.trim = String.prototype.trim ?
+	dojo.trim : // aliasing to the native function
+	function(str){
+		str = str.replace(/^\s+/, '');
+		for(var i = str.length - 1; i >= 0; i--){
+			if(/\S/.test(str.charAt(i))){
+				str = str.substring(0, i + 1);
+				break;
+			}
+		}
+		return str;
+	};
+
+}
+
+if(!dojo._hasResource["dijit._Templated"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._Templated"] = true;
+dojo.provide("dijit._Templated");
+
+
+
+
+
+dojo.declare("dijit._Templated",
+	null,
+	{
+		//	summary:
+		//		Mixin for widgets that are instantiated from a template
+		// 
+
+		// templateString: [protected] String
+		//		A string that represents the widget template. Pre-empts the
+		//		templatePath. In builds that have their strings "interned", the
+		//		templatePath is converted to an inline templateString, thereby
+		//		preventing a synchronous network call.
+		templateString: null,
+
+		// templatePath: [protected] String
+		//		Path to template (HTML file) for this widget relative to dojo.baseUrl
+		templatePath: null,
+
+		// widgetsInTemplate: [protected] Boolean
+		//		Should we parse the template to find widgets that might be
+		//		declared in markup inside it?  False by default.
+		widgetsInTemplate: false,
+
+		// skipNodeCache: [protected] Boolean
+		//		If using a cached widget template node poses issues for a
+		//		particular widget class, it can set this property to ensure
+		//		that its template is always re-built from a string
+		_skipNodeCache: false,
+
+		_stringRepl: function(tmpl){
+			// summary:
+			//		Does substitution of ${foo} type properties in template string
+			// tags:
+			//		private
+			var className = this.declaredClass, _this = this;
+			// Cache contains a string because we need to do property replacement
+			// do the property replacement
+			return dojo.string.substitute(tmpl, this, function(value, key){
+				if(key.charAt(0) == '!'){ value = dojo.getObject(key.substr(1), false, _this); }
+				if(typeof value == "undefined"){ throw new Error(className+" template:"+key); } // a debugging aide
+				if(value == null){ return ""; }
+
+				// Substitution keys beginning with ! will skip the transform step,
+				// in case a user wishes to insert unescaped markup, e.g. ${!foo}
+				return key.charAt(0) == "!" ? value :
+					// Safer substitution, see heading "Attribute values" in
+					// http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2
+					value.toString().replace(/"/g,"""); //TODO: add &amp? use encodeXML method?
+			}, this);
+		},
+
+		// method over-ride
+		buildRendering: function(){
+			// summary:
+			//		Construct the UI for this widget from a template, setting this.domNode.
+			// tags:
+			//		protected
+
+			// Lookup cached version of template, and download to cache if it
+			// isn't there already.  Returns either a DomNode or a string, depending on
+			// whether or not the template contains ${foo} replacement parameters.
+			var cached = dijit._Templated.getCachedTemplate(this.templatePath, this.templateString, this._skipNodeCache);
+
+			var node;
+			if(dojo.isString(cached)){
+				node = dojo._toDom(this._stringRepl(cached));
+			}else{
+				// if it's a node, all we have to do is clone it
+				node = cached.cloneNode(true);
+			}
+
+			this.domNode = node;
+
+			// recurse through the node, looking for, and attaching to, our
+			// attachment points and events, which should be defined on the template node.
+			this._attachTemplateNodes(node);
+
+			if(this.widgetsInTemplate){
+				var cw = (this._supportingWidgets = dojo.parser.parse(node));
+				this._attachTemplateNodes(cw, function(n,p){
+					return n[p];
+				});
+			}
+
+			this._fillContent(this.srcNodeRef);
+		},
+
+		_fillContent: function(/*DomNode*/ source){
+			// summary:
+			//		Relocate source contents to templated container node.
+			//		this.containerNode must be able to receive children, or exceptions will be thrown.
+			// tags:
+			//		protected
+			var dest = this.containerNode;
+			if(source && dest){
+				while(source.hasChildNodes()){
+					dest.appendChild(source.firstChild);
+				}
+			}
+		},
+
+		_attachTemplateNodes: function(rootNode, getAttrFunc){
+			// summary:
+			//		Iterate through the template and attach functions and nodes accordingly.	
+			// description:		
+			//		Map widget properties and functions to the handlers specified in
+			//		the dom node and it's descendants. This function iterates over all
+			//		nodes and looks for these properties:
+			//			* dojoAttachPoint
+			//			* dojoAttachEvent	
+			//			* waiRole
+			//			* waiState
+			// rootNode: DomNode|Array[Widgets]
+			//		the node to search for properties. All children will be searched.
+			// getAttrFunc: Function?
+			//		a function which will be used to obtain property for a given
+			//		DomNode/Widget
+			// tags:
+			//		private
+
+			getAttrFunc = getAttrFunc || function(n,p){ return n.getAttribute(p); };
+
+			var nodes = dojo.isArray(rootNode) ? rootNode : (rootNode.all || rootNode.getElementsByTagName("*"));
+			var x = dojo.isArray(rootNode) ? 0 : -1;
+			for(; x<nodes.length; x++){
+				var baseNode = (x == -1) ? rootNode : nodes[x];
+				if(this.widgetsInTemplate && getAttrFunc(baseNode, "dojoType")){
+					continue;
+				}
+				// Process dojoAttachPoint
+				var attachPoint = getAttrFunc(baseNode, "dojoAttachPoint");
+				if(attachPoint){
+					var point, points = attachPoint.split(/\s*,\s*/);
+					while((point = points.shift())){
+						if(dojo.isArray(this[point])){
+							this[point].push(baseNode);
+						}else{
+							this[point]=baseNode;
+						}
+					}
+				}
+
+				// Process dojoAttachEvent
+				var attachEvent = getAttrFunc(baseNode, "dojoAttachEvent");
+				if(attachEvent){
+					// NOTE: we want to support attributes that have the form
+					// "domEvent: nativeEvent; ..."
+					var event, events = attachEvent.split(/\s*,\s*/);
+					var trim = dojo.trim;
+					while((event = events.shift())){
+						if(event){
+							var thisFunc = null;
+							if(event.indexOf(":") != -1){
+								// oh, if only JS had tuple assignment
+								var funcNameArr = event.split(":");
+								event = trim(funcNameArr[0]);
+								thisFunc = trim(funcNameArr[1]);
+							}else{
+								event = trim(event);
+							}
+							if(!thisFunc){
+								thisFunc = event;
+							}
+							this.connect(baseNode, event, thisFunc);
+						}
+					}
+				}
+
+				// waiRole, waiState
+				var role = getAttrFunc(baseNode, "waiRole");
+				if(role){
+					dijit.setWaiRole(baseNode, role);
+				}
+				var values = getAttrFunc(baseNode, "waiState");
+				if(values){
+					dojo.forEach(values.split(/\s*,\s*/), function(stateValue){
+						if(stateValue.indexOf('-') != -1){
+							var pair = stateValue.split('-');
+							dijit.setWaiState(baseNode, pair[0], pair[1]);
+						}
+					});
+				}
+			}
+		}
+	}
+);
+
+// key is either templatePath or templateString; object is either string or DOM tree
+dijit._Templated._templateCache = {};
+
+dijit._Templated.getCachedTemplate = function(templatePath, templateString, alwaysUseString){
+	// summary:
+	//		Static method to get a template based on the templatePath or
+	//		templateString key
+	// templatePath: String
+	//		The URL to get the template from. dojo.uri.Uri is often passed as well.
+	// templateString: String?
+	//		a string to use in lieu of fetching the template from a URL. Takes precedence
+	//		over templatePath
+	// returns: Mixed
+	//		Either string (if there are ${} variables that need to be replaced) or just
+	//		a DOM tree (if the node can be cloned directly)
+
+	// is it already cached?
+	var tmplts = dijit._Templated._templateCache;
+	var key = templateString || templatePath;
+	var cached = tmplts[key];
+	if(cached){
+		if(!cached.ownerDocument || cached.ownerDocument == dojo.doc){
+			// string or node of the same document
+			return cached;
+		}
+		// destroy the old cached node of a different document
+		dojo.destroy(cached);
+	}
+
+	// If necessary, load template string from template path
+	if(!templateString){
+		templateString = dijit._Templated._sanitizeTemplateString(dojo.trim(dojo._getText(templatePath)));
+	}
+
+	templateString = dojo.string.trim(templateString);
+
+	if(alwaysUseString || templateString.match(/\$\{([^\}]+)\}/g)){
+		// there are variables in the template so all we can do is cache the string
+		return (tmplts[key] = templateString); //String
+	}else{
+		// there are no variables in the template so we can cache the DOM tree
+		return (tmplts[key] = dojo._toDom(templateString)); //Node
+	}
+};
+
+dijit._Templated._sanitizeTemplateString = function(/*String*/tString){
+	// summary: 
+	//		Strips <?xml ...?> declarations so that external SVG and XML
+	// 		documents can be added to a document without worry. Also, if the string
+	//		is an HTML document, only the part inside the body tag is returned.
+	if(tString){
+		tString = tString.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, "");
+		var matches = tString.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
+		if(matches){
+			tString = matches[1];
+		}
+	}else{
+		tString = "";
+	}
+	return tString; //String
+};
+
+
+if(dojo.isIE){
+	dojo.addOnWindowUnload(function(){
+		var cache = dijit._Templated._templateCache;
+		for(var key in cache){
+			var value = cache[key];
+			if(!isNaN(value.nodeType)){ // isNode equivalent
+				dojo.destroy(value);
+			}
+			delete cache[key];
+		}
+	});
+}
+
+// These arguments can be specified for widgets which are used in templates.
+// Since any widget can be specified as sub widgets in template, mix it
+// into the base widget class.  (This is a hack, but it's effective.)
+dojo.extend(dijit._Widget,{
+	dojoAttachEvent: "",
+	dojoAttachPoint: "",
+	waiRole: "",
+	waiState:""
+});
+
+}
+
+if(!dojo._hasResource["dijit._Container"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._Container"] = true;
+dojo.provide("dijit._Container");
+
+dojo.declare("dijit._Container",
+	null,
+	{
+		// summary:
+		//		Mixin for widgets that contain a set of widget children.
+		// description:
+		//		Use this mixin for widgets that needs to know about and
+		//		keep track of their widget children. Suitable for widgets like BorderContainer
+		//		and TabContainer which contain (only) a set of child widgets.
+		//
+		//		It's not suitable for widgets like ContentPane
+		//		which contains mixed HTML (plain DOM nodes in addition to widgets),
+		//		and where contained widgets are not necessarily directly below
+		//		this.containerNode.   In that case calls like addChild(node, position)
+		//		wouldn't make sense.
+
+		// isContainer: [protected] Boolean
+		//		Just a flag indicating that this widget descends from dijit._Container
+		isContainer: true,
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			if(!this.containerNode){
+				// all widgets with descendants must set containerNode
+   				this.containerNode = this.domNode;
+			}
+		},
+
+		addChild: function(/*Widget*/ widget, /*int?*/ insertIndex){
+			// summary:
+			//		Makes the given widget a child of this widget.
+			// description:
+			//		Inserts specified child widget's dom node as a child of this widget's
+			//		container node, and possibly does other processing (such as layout).
+
+			var refNode = this.containerNode;
+			if(insertIndex && typeof insertIndex == "number"){
+				var children = this.getChildren();
+				if(children && children.length >= insertIndex){
+					refNode = children[insertIndex-1].domNode;
+					insertIndex = "after";
+				}
+			}
+			dojo.place(widget.domNode, refNode, insertIndex);
+
+			// If I've been started but the child widget hasn't been started,
+			// start it now.  Make sure to do this after widget has been
+			// inserted into the DOM tree, so it can see that it's being controlled by me,
+			// so it doesn't try to size itself.
+			if(this._started && !widget._started){
+				widget.startup();
+			}
+		},
+
+		removeChild: function(/*Widget or int*/ widget){
+			// summary:
+			//		Removes the passed widget instance from this widget but does
+			//		not destroy it.  You can also pass in an integer indicating
+			//		the index within the container to remove
+			if(typeof widget == "number" && widget > 0){
+				widget = this.getChildren()[widget];
+			}
+			// If we cannot find the widget, just return
+			if(!widget || !widget.domNode){ return; }
+			
+			var node = widget.domNode;
+			node.parentNode.removeChild(node);	// detach but don't destroy
+		},
+
+		_nextElement: function(node){
+			// summary:
+			//      Find the next (non-text, non-comment etc) node
+			// tags:
+			//      private
+			do{
+				node = node.nextSibling;
+			}while(node && node.nodeType != 1);
+			return node;
+		},
+
+		_firstElement: function(node){
+			// summary:
+			//      Find the first (non-text, non-comment etc) node
+			// tags:
+			//      private
+			node = node.firstChild;
+			if(node && node.nodeType != 1){
+				node = this._nextElement(node);
+			}
+			return node;
+		},
+
+		getChildren: function(){
+			// summary:
+			//		Returns array of children widgets.
+			// description:
+			//		Returns the widgets that are directly under this.containerNode.
+			return dojo.query("> [widgetId]", this.containerNode).map(dijit.byNode); // Widget[]
+		},
+
+		hasChildren: function(){
+			// summary:
+			//		Returns true if widget has children, i.e. if this.containerNode contains something.
+			return !!this._firstElement(this.containerNode); // Boolean
+		},
+
+		destroyDescendants: function(/*Boolean*/ preserveDom){
+			// summary:
+			//      Destroys all the widgets inside this.containerNode,
+			//      but not this widget itself
+			dojo.forEach(this.getChildren(), function(child){ child.destroyRecursive(preserveDom); });
+		},
+	
+		_getSiblingOfChild: function(/*Widget*/ child, /*int*/ dir){
+			// summary:
+			//		Get the next or previous widget sibling of child
+			// dir:
+			//		if 1, get the next sibling
+			//		if -1, get the previous sibling
+			// tags:
+			//      private
+			var node = child.domNode;
+			var which = (dir>0 ? "nextSibling" : "previousSibling");
+			do{
+				node = node[which];
+			}while(node && (node.nodeType != 1 || !dijit.byNode(node)));
+			return node ? dijit.byNode(node) : null;
+		},
+		
+		getIndexOfChild: function(/*Widget*/ child){
+			// summary:
+			//		Gets the index of the child in this container or -1 if not found
+			var children = this.getChildren();
+			for(var i=0, c; c=children[i]; i++){
+				if(c == child){ 
+					return i; // int
+				}
+			}
+			return -1; // int
+		}
+	}
+);
+
+}
+
+if(!dojo._hasResource["dijit._Contained"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._Contained"] = true;
+dojo.provide("dijit._Contained");
+
+dojo.declare("dijit._Contained",
+		null,
+		{
+			// summary
+			//		Mixin for widgets that are children of a container widget
+			//
+			// example:
+			// | 	// make a basic custom widget that knows about it's parents
+			// |	dojo.declare("my.customClass",[dijit._Widget,dijit._Contained],{});
+			// 
+			getParent: function(){
+				// summary:
+				//		Returns the parent widget of this widget, assuming the parent
+				//		implements dijit._Container
+				for(var p=this.domNode.parentNode; p; p=p.parentNode){
+					var id = p.getAttribute && p.getAttribute("widgetId");
+					if(id){
+						var parent = dijit.byId(id);
+						return parent.isContainer ? parent : null;
+					}
+				}
+				return null;
+			},
+
+			_getSibling: function(which){
+				// summary:
+				//      Returns next or previous sibling
+				// which:
+				//      Either "next" or "previous"
+				// tags:
+				//      private
+				var node = this.domNode;
+				do{
+					node = node[which+"Sibling"];
+				}while(node && node.nodeType != 1);
+				if(!node){ return null; } // null
+				var id = node.getAttribute("widgetId");
+				return dijit.byId(id);
+			},
+
+			getPreviousSibling: function(){
+				// summary:
+				//		Returns null if this is the first child of the parent,
+				//		otherwise returns the next element sibling to the "left".
+
+				return this._getSibling("previous"); // Mixed
+			},
+
+			getNextSibling: function(){
+				// summary:
+				//		Returns null if this is the last child of the parent,
+				//		otherwise returns the next element sibling to the "right".
+
+				return this._getSibling("next"); // Mixed
+			},
+			
+			getIndexInParent: function(){
+				// summary:
+				//		Returns the index of this widget within its container parent.
+				//		It returns -1 if the parent does not exist, or if the parent
+				//		is not a dijit._Container
+				
+				var p = this.getParent();
+				if(!p || !p.getIndexOfChild){
+					return -1; // int
+				}
+				return p.getIndexOfChild(this); // int
+			}
+		}
+	);
+
+
+}
+
+if(!dojo._hasResource["dijit.layout._LayoutWidget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.layout._LayoutWidget"] = true;
+dojo.provide("dijit.layout._LayoutWidget");
+
+
+
+
+
+dojo.declare("dijit.layout._LayoutWidget",
+	[dijit._Widget, dijit._Container, dijit._Contained],
+	{
+		// summary:
+		//		Base class for a _Container widget which is responsible for laying out its children.
+		//		Widgets which mixin this code must define layout() to lay out the children.
+
+		// baseClass: [protected extension] String
+		//		This class name is applied to the widget's domNode
+		//		and also may be used to generate names for sub nodes,
+		//		like for example dijitTabContainer-content.
+		baseClass: "dijitLayoutContainer",
+
+		// isLayoutContainer: [private deprecated] Boolean
+		//		TODO: this is unused, but maybe it *should* be used for a child to
+		//		detect whether the parent is going to call resize() on it or not
+		//		(see calls to getParent() and resize() in this file)
+		isLayoutContainer: true,
+
+		postCreate: function(){
+			dojo.addClass(this.domNode, "dijitContainer");
+			dojo.addClass(this.domNode, this.baseClass);
+			
+			// TODO: this.inherited()
+		},
+
+		startup: function(){
+			// summary:
+			//		Called after all the widgets have been instantiated and their
+			//		dom nodes have been inserted somewhere under dojo.doc.body.
+			//
+			//		Widgets should override this method to do any initialization
+			//		dependent on other widgets existing, and then call
+			//		this superclass method to finish things off.
+			//
+			//		startup() in subclasses shouldn't do anything
+			//		size related because the size of the widget hasn't been set yet.
+
+			if(this._started){ return; }
+
+			// TODO: seems like this code should be in _Container.startup().
+			// Then things that don't extend LayoutContainer (like GridContainer)
+			// would get the behavior for free.
+			dojo.forEach(this.getChildren(), function(child){ child.startup(); });
+
+			// If I am a top level widget
+			if(!this.getParent || !this.getParent()){
+				// Do recursive sizing and layout of all my descendants
+				// (passing in no argument to resize means that it has to glean the size itself)
+				this.resize();
+
+				// Since my parent isn't a layout container, and my style is width=height=100% (or something similar),
+				// then I need to watch when the window resizes, and size myself accordingly.
+				// (Passing in no arguments to resize means that it has to glean the size itself.)
+				// TODO: make one global listener to avoid getViewport() per widget.
+				this._viewport = dijit.getViewport();
+				this.connect(dojo.global, 'onresize', function(){
+					var newViewport = dijit.getViewport();
+					if(newViewport.w != this._viewport.w ||  newViewport.h != this._viewport.h){
+						this._viewport = newViewport;
+						this.resize();
+					}
+				});
+			}
+			
+			this.inherited(arguments);
+		},
+
+		resize: function(changeSize, resultSize){
+			// summary:
+			//		Call this to resize a widget, or after its size has changed.
+			// description:
+			//		Change size mode:
+			//			When changeSize is specified, changes the marginBox of this widget
+			//			 and forces it to relayout its contents accordingly.
+			//			changeSize may specify height, width, or both.
+			//
+			//			If resultSize is specified it indicates the size the widget will
+			//			become after changeSize has been applied.
+			//
+			//		Notification mode:
+			//			When changeSize is null, indicates that the caller has already changed
+			//			the size of the widget, or perhaps it changed because the browser
+			//			window was resized.  Tells widget to relayout it's contents accordingly.
+			//
+			//			If resultSize is also specified it indicates the size the widget has
+			//			become.
+			//
+			//		In either mode, this method also:
+			//			1. Sets this._borderBox and this._contentBox to the new size of
+			//				the widget.  Queries the current domNode size if necessary.
+			//			2. Calls layout() to resize contents (and maybe adjust child widgets).	
+			//
+			// changeSize: Object?
+			//		Sets the widget to this margin-box size and position.
+			//		May include any/all of the following properties:
+			//	|	{w: int, h: int, l: int, t: int}
+			//
+			// resultSize: Object?
+			//		The margin-box size of this widget after applying changeSize (if 
+			//		changeSize is specified).  If caller knows this size and
+			//		passes it in, we don't need to query the browser to get the size.
+			//	|	{w: int, h: int}
+
+			var node = this.domNode;
+
+			// set margin box size, unless it wasn't specified, in which case use current size
+			if(changeSize){
+				dojo.marginBox(node, changeSize);
+
+				// set offset of the node
+				if(changeSize.t){ node.style.top = changeSize.t + "px"; }
+				if(changeSize.l){ node.style.left = changeSize.l + "px"; }
+			}
+
+			// If either height or width wasn't specified by the user, then query node for it.
+			// But note that setting the margin box and then immediately querying dimensions may return
+			// inaccurate results, so try not to depend on it.
+			var mb = resultSize || {};
+			dojo.mixin(mb, changeSize || {});	// changeSize overrides resultSize
+			if ( !("h" in mb) || !("w" in mb) ){
+				mb = dojo.mixin(dojo.marginBox(node), mb);	// just use dojo.marginBox() to fill in missing values
+			}
+
+			// Compute and save the size of my border box and content box
+			// (w/out calling dojo.contentBox() since that may fail if size was recently set)
+			var cs = dojo.getComputedStyle(node);
+			var me = dojo._getMarginExtents(node, cs);
+			var be = dojo._getBorderExtents(node, cs);
+			var bb = (this._borderBox = {
+				w: mb.w - (me.w + be.w),
+				h: mb.h - (me.h + be.h)
+			});
+			var pe = dojo._getPadExtents(node, cs);
+			this._contentBox = {
+				l: dojo._toPixelValue(node, cs.paddingLeft),
+				t: dojo._toPixelValue(node, cs.paddingTop),
+				w: bb.w - pe.w,
+				h: bb.h - pe.h
+			};
+
+			// Callback for widget to adjust size of it's children
+			this.layout();
+		},
+
+		layout: function(){
+			// summary:
+			//		Widgets override this method to size and position their contents/children.
+			//		When this is called this._contentBox is guaranteed to be set (see resize()).
+			//
+			//		This is called after startup(), and also when the widget's size has been
+			//		changed.
+			// tags:
+			//		protected extension
+		},
+
+		_setupChild: function(/*Widget*/child){
+			// summary:
+			//		Common setup for initial children and children which are added after startup
+			// tags:
+			//		protected extension
+
+			dojo.addClass(child.domNode, this.baseClass+"-child");
+			if(child.baseClass){
+				dojo.addClass(child.domNode, this.baseClass+"-"+child.baseClass);
+			}
+		},
+
+		addChild: function(/*Widget*/ child, /*Integer?*/ insertIndex){
+			// Overrides _Container.addChild() to call _setupChild()
+			this.inherited(arguments);
+			if(this._started){
+				this._setupChild(child);
+			}
+		},
+
+		removeChild: function(/*Widget*/ child){
+			// Overrides _Container.removeChild() to remove class added by _setupChild()
+			dojo.removeClass(child.domNode, this.baseClass+"-child");
+			if(child.baseClass){
+				dojo.removeClass(child.domNode, this.baseClass+"-"+child.baseClass);
+			}
+			this.inherited(arguments);
+		}
+	}
+);
+
+dijit.layout.marginBox2contentBox = function(/*DomNode*/ node, /*Object*/ mb){
+	// summary:
+	//		Given the margin-box size of a node, return its content box size.
+	//		Functions like dojo.contentBox() but is more reliable since it doesn't have
+	//		to wait for the browser to compute sizes.
+	var cs = dojo.getComputedStyle(node);
+	var me = dojo._getMarginExtents(node, cs);
+	var pb = dojo._getPadBorderExtents(node, cs);
+	return {
+		l: dojo._toPixelValue(node, cs.paddingLeft),
+		t: dojo._toPixelValue(node, cs.paddingTop),
+		w: mb.w - (me.w + pb.w),
+		h: mb.h - (me.h + pb.h)
+	};
+};
+
+(function(){
+	var capitalize = function(word){
+		return word.substring(0,1).toUpperCase() + word.substring(1);
+	};
+
+	var size = function(widget, dim){
+		// size the child
+		widget.resize ? widget.resize(dim) : dojo.marginBox(widget.domNode, dim);
+
+		// record child's size, but favor our own numbers when we have them.
+		// the browser lies sometimes
+		dojo.mixin(widget, dojo.marginBox(widget.domNode));
+		dojo.mixin(widget, dim);
+	};
+
+	dijit.layout.layoutChildren = function(/*DomNode*/ container, /*Object*/ dim, /*Object[]*/ children){
+		// summary
+		//		Layout a bunch of child dom nodes within a parent dom node
+		// container:
+		//		parent node
+		// dim:
+		//		{l, t, w, h} object specifying dimensions of container into which to place children
+		// children:
+		//		an array like [ {domNode: foo, layoutAlign: "bottom" }, {domNode: bar, layoutAlign: "client"} ]
+
+		// copy dim because we are going to modify it
+		dim = dojo.mixin({}, dim);
+
+		dojo.addClass(container, "dijitLayoutContainer");
+
+		// Move "client" elements to the end of the array for layout.  a11y dictates that the author
+		// needs to be able to put them in the document in tab-order, but this algorithm requires that
+		// client be last.
+		children = dojo.filter(children, function(item){ return item.layoutAlign != "client"; })
+			.concat(dojo.filter(children, function(item){ return item.layoutAlign == "client"; }));
+
+		// set positions/sizes
+		dojo.forEach(children, function(child){
+			var elm = child.domNode,
+				pos = child.layoutAlign;
+
+			// set elem to upper left corner of unused space; may move it later
+			var elmStyle = elm.style;
+			elmStyle.left = dim.l+"px";
+			elmStyle.top = dim.t+"px";
+			elmStyle.bottom = elmStyle.right = "auto";
+
+			dojo.addClass(elm, "dijitAlign" + capitalize(pos));
+
+			// set size && adjust record of remaining space.
+			// note that setting the width of a <div> may affect it's height.
+			if(pos == "top" || pos == "bottom"){
+				size(child, { w: dim.w });
+				dim.h -= child.h;
+				if(pos=="top"){
+					dim.t += child.h;
+				}else{
+					elmStyle.top = dim.t + dim.h + "px";
+				}
+			}else if(pos == "left" || pos == "right"){
+				size(child, { h: dim.h });
+				dim.w -= child.w;
+				if(pos == "left"){
+					dim.l += child.w;
+				}else{
+					elmStyle.left = dim.l + dim.w + "px";
+				}
+			}else if(pos == "client"){
+				size(child, dim);
+			}
+		});
+	};
+
+})();
+
+}
+
+if(!dojo._hasResource["dijit.form._FormWidget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form._FormWidget"] = true;
+dojo.provide("dijit.form._FormWidget");
+
+
+
+
+dojo.declare("dijit.form._FormWidget", [dijit._Widget, dijit._Templated],
+	{
+	//
+	// summary:
+	//		Base class for widgets corresponding to native HTML elements such as <checkbox> or <button>,
+	//		which can be children of a <form> node or a `dijit.form.Form` widget.
+	//
+	// description:
+	//		Represents a single HTML element.
+	//		All these widgets should have these attributes just like native HTML input elements.
+	//		You can set them during widget construction or afterwards, via `dijit._Widget.attr`.
+	//
+	//	They also share some common methods.
+
+	// baseClass: [protected] String
+	//		Root CSS class of the widget (ex: dijitTextBox), used to add CSS classes of widget
+	//		(ex: "dijitTextBox dijitTextBoxInvalid dijitTextBoxFocused dijitTextBoxInvalidFocused")
+	//		See _setStateClass().
+	baseClass: "",
+
+	// name: String
+	//		Name used when submitting form; same as "name" attribute or plain HTML elements
+	name: "",
+
+	// alt: String
+	//		Corresponds to the native HTML <input> element's attribute.
+	alt: "",
+
+	// value: String
+	//		Corresponds to the native HTML <input> element's attribute.
+	value: "",
+
+	// type: String
+	//		Corresponds to the native HTML <input> element's attribute.
+	type: "text",
+
+	// tabIndex: Integer
+	//		Order fields are traversed when user hits the tab key
+	tabIndex: "0",
+
+	// disabled: Boolean
+	//		Should this widget respond to user input?
+	//		In markup, this is specified as "disabled='disabled'", or just "disabled".
+	disabled: false,
+
+	// readOnly: Boolean
+	//		Should this widget respond to user input?
+	//		In markup, this is specified as "readOnly".
+	//		Similar to disabled except readOnly form values are submitted.
+	readOnly: false,
+
+	// intermediateChanges: Boolean
+	//		Fires onChange for each value change or only on demand
+	intermediateChanges: false,
+
+	// scrollOnFocus: Boolean
+	//		On focus, should this widget scroll into view?
+	scrollOnFocus: true,
+
+	// These mixins assume that the focus node is an INPUT, as many but not all _FormWidgets are.
+	attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
+		value: "focusNode",
+		disabled: "focusNode",
+		readOnly: "focusNode",
+		id: "focusNode",
+		tabIndex: "focusNode",
+		alt: "focusNode"
+	}),
+
+	postMixInProperties: function(){
+		// Setup name=foo string to be referenced from the template (but only if a name has been specified)
+		// Unfortunately we can't use attributeMap to set the name due to IE limitations, see #8660
+		this.nameAttrSetting = this.name ? ("name='" + this.name + "'") : "";
+		this.inherited(arguments);
+	},
+
+	_setDisabledAttr: function(/*Boolean*/ value){
+		this.disabled = value;
+		dojo.attr(this.focusNode, 'disabled', value);
+		dijit.setWaiState(this.focusNode, "disabled", value);
+
+				if(value){
+					//reset those, because after the domNode is disabled, we can no longer receive
+					//mouse related events, see #4200
+					this._hovering = false;
+					this._active = false;
+					// remove the tabIndex, especially for FF
+					this.focusNode.removeAttribute('tabIndex');
+				}else{
+					this.focusNode.setAttribute('tabIndex', this.tabIndex);
+				}
+				this._setStateClass();
+	},
+
+	setDisabled: function(/*Boolean*/ disabled){
+		// summary:
+		//		Deprecated.   Use attr('disabled', ...) instead.
+		dojo.deprecated("setDisabled("+disabled+") is deprecated. Use attr('disabled',"+disabled+") instead.", "", "2.0");
+		this.attr('disabled', disabled);
+	},
+
+	_onFocus: function(e){
+		if(this.scrollOnFocus){
+			dijit.scrollIntoView(this.domNode);
+		}
+		this.inherited(arguments);
+	},
+
+	_onMouse : function(/*Event*/ event){
+		// summary:
+		//	Sets _hovering, _active, and stateModifier properties depending on mouse state,
+		//	then calls setStateClass() to set appropriate CSS classes for this.domNode.
+		//
+		//	To get a different CSS class for hover, send onmouseover and onmouseout events to this method.
+		//	To get a different CSS class while mouse button is depressed, send onmousedown to this method.
+
+		var mouseNode = event.currentTarget;
+		if(mouseNode && mouseNode.getAttribute){
+			this.stateModifier = mouseNode.getAttribute("stateModifier") || "";
+		}
+
+		if(!this.disabled){
+			switch(event.type){
+				case "mouseenter":
+				case "mouseover":
+					this._hovering = true;
+					this._active = this._mouseDown;
+					break;
+
+				case "mouseout":
+				case "mouseleave":
+					this._hovering = false;
+					this._active = false;
+					break;
+
+				case "mousedown" :
+					this._active = true;
+					this._mouseDown = true;
+					// set a global event to handle mouseup, so it fires properly
+					//	even if the cursor leaves the button
+					var mouseUpConnector = this.connect(dojo.body(), "onmouseup", function(){
+						//if user clicks on the button, even if the mouse is released outside of it,
+						//this button should get focus (which mimics native browser buttons)
+						if(this._mouseDown && this.isFocusable()){
+							this.focus();
+						}
+						this._active = false;
+						this._mouseDown = false;
+						this._setStateClass();
+						this.disconnect(mouseUpConnector);
+					});
+					break;
+			}
+			this._setStateClass();
+		}
+	},
+
+	isFocusable: function(){
+		// summary:
+		//		Tells if this widget is focusable or not.   Used internally by dijit.
+		// tags:
+		//		protected
+		return !this.disabled && !this.readOnly && this.focusNode && (dojo.style(this.domNode, "display") != "none");
+	},
+
+	focus: function(){
+		// summary:
+		//		Put focus on this widget
+		dijit.focus(this.focusNode);
+	},
+
+	_setStateClass: function(){
+		// summary:
+		//		Update the visual state of the widget by setting the css classes on this.domNode
+		//		(or this.stateNode if defined) by combining this.baseClass with
+		//		various suffixes that represent the current widget state(s).
+		//
+		// description:
+		//		In the case where a widget has multiple
+		//		states, it sets the class based on all possible
+		//	 	combinations.  For example, an invalid form widget that is being hovered
+		//		will be "dijitInput dijitInputInvalid dijitInputHover dijitInputInvalidHover".
+		//
+		//		For complex widgets with multiple regions, there can be various hover/active states,
+		//		such as "Hover" or "CloseButtonHover" (for tab buttons).
+		//		This is controlled by a stateModifier="CloseButton" attribute on the close button node.
+		//
+		//		The widget may have one or more of the following states, determined
+		//		by this.state, this.checked, this.valid, and this.selected:
+		//			- Error - ValidationTextBox sets this.state to "Error" if the current input value is invalid
+		//			- Checked - ex: a checkmark or a ToggleButton in a checked state, will have this.checked==true
+		//			- Selected - ex: currently selected tab will have this.selected==true
+		//
+		//		In addition, it may have one or more of the following states,
+		//		based on this.disabled and flags set in _onMouse (this._active, this._hovering, this._focused):
+		//			- Disabled	- if the widget is disabled
+		//			- Active		- if the mouse (or space/enter key?) is being pressed down
+		//			- Focused		- if the widget has focus
+		//			- Hover		- if the mouse is over the widget
+
+		// Compute new set of classes
+		var newStateClasses = this.baseClass.split(" ");
+
+		function multiply(modifier){
+			newStateClasses = newStateClasses.concat(dojo.map(newStateClasses, function(c){ return c+modifier; }), "dijit"+modifier);
+		}
+
+		if(this.checked){
+			multiply("Checked");
+		}
+		if(this.state){
+			multiply(this.state);
+		}
+		if(this.selected){
+			multiply("Selected");
+		}
+
+		if(this.disabled){
+			multiply("Disabled");
+		}else if(this.readOnly){
+			multiply("ReadOnly");
+		}else if(this._active){
+			multiply(this.stateModifier+"Active");
+		}else{
+			if(this._focused){
+				multiply("Focused");
+			}
+			if(this._hovering){
+				multiply(this.stateModifier+"Hover");
+			}
+		}
+
+		// Remove old state classes and add new ones.
+		// For performance concerns we only write into domNode.className once.
+		var tn = this.stateNode || this.domNode,
+			classHash = {};	// set of all classes (state and otherwise) for node
+
+		dojo.forEach(tn.className.split(" "), function(c){ classHash[c] = true; });
+
+		if("_stateClasses" in this){
+			dojo.forEach(this._stateClasses, function(c){ delete classHash[c]; });
+		}
+
+		dojo.forEach(newStateClasses, function(c){ classHash[c] = true; });
+
+		var newClasses = [];
+		for(var c in classHash){
+			newClasses.push(c);
+		}
+		tn.className = newClasses.join(" ");
+
+		this._stateClasses = newStateClasses;
+	},
+
+	compare: function(/*anything*/val1, /*anything*/val2){
+		// summary:
+		//		Compare 2 values (as returned by attr('value') for this widget).
+		// tags:
+		//		protected
+		if((typeof val1 == "number") && (typeof val2 == "number")){
+			return (isNaN(val1) && isNaN(val2))? 0 : (val1-val2);
+		}else if(val1 > val2){ return 1; }
+		else if(val1 < val2){ return -1; }
+		else { return 0; }
+	},
+
+	onChange: function(newValue){
+		// summary:
+		//		Callback when this widget's value is changed.
+		// tags:
+		//		callback
+	},
+
+	// _onChangeActive: [private] Boolean
+	//		Indicates that changes to the value should call onChange() callback.
+	//		This is false during widget initialization, to avoid calling onChange()
+	//		when the initial value is set.
+	_onChangeActive: false,
+
+	_handleOnChange: function(/*anything*/ newValue, /* Boolean? */ priorityChange){
+		// summary:
+		//		Called when the value of the widget is set.  Calls onChange() if appropriate
+		// newValue:
+		//		the new value
+		// priorityChange:
+		//		For a slider, for example, dragging the slider is priorityChange==false,
+		//		but on mouse up, it's priorityChange==true.  If intermediateChanges==true,
+		//		onChange is only called form priorityChange=true events.
+		// tags:
+		//		private
+		this._lastValue = newValue;
+		if(this._lastValueReported == undefined && (priorityChange === null || !this._onChangeActive)){
+			// this block executes not for a change, but during initialization,
+			// and is used to store away the original value (or for ToggleButton, the original checked state)
+			this._resetValue = this._lastValueReported = newValue;
+		}
+		if((this.intermediateChanges || priorityChange || priorityChange === undefined) &&
+			((typeof newValue != typeof this._lastValueReported) ||
+				this.compare(newValue, this._lastValueReported) != 0)){
+			this._lastValueReported = newValue;
+			if(this._onChangeActive){ this.onChange(newValue); }
+		}
+	},
+
+	create: function(){
+		// Overrides _Widget.create()
+		this.inherited(arguments);
+		this._onChangeActive = true;
+		this._setStateClass();
+	},
+
+	destroy: function(){
+		if(this._layoutHackHandle){
+			clearTimeout(this._layoutHackHandle);
+		}
+		this.inherited(arguments);
+	},
+
+	setValue: function(/*String*/ value){
+		// summary:
+		//		Deprecated.   Use attr('value', ...) instead.
+		dojo.deprecated("dijit.form._FormWidget:setValue("+value+") is deprecated.  Use attr('value',"+value+") instead.", "", "2.0");
+		this.attr('value', value);
+	},
+
+	getValue: function(){
+		// summary:
+		//		Deprecated.   Use attr('value') instead.
+		dojo.deprecated(this.declaredClass+"::getValue() is deprecated. Use attr('value') instead.", "", "2.0");
+		return this.attr('value');
+	},
+
+	_layoutHack: function(){
+		// summary:
+		//		Work around table sizing bugs on FF2 by forcing redraw
+
+		if(dojo.isFF == 2 && !this._layoutHackHandle){
+			var node=this.domNode;
+			var old = node.style.opacity;
+			node.style.opacity = "0.999";
+			this._layoutHackHandle = setTimeout(dojo.hitch(this, function(){
+				this._layoutHackHandle = null;
+				node.style.opacity = old;
+			}), 0);
+		}
+	}
+});
+
+dojo.declare("dijit.form._FormValueWidget", dijit.form._FormWidget,
+{
+	// summary:
+	//		Base class for widgets corresponding to native HTML elements such as <input> or <select> that have user changeable values.
+	// description:
+	//		Each _FormValueWidget represents a single input value, and has a (possibly hidden) <input> element,
+	//		to which it serializes it's input value, so that form submission (either normal submission or via FormBind?)
+	//		works as expected.
+
+	// Don't attempt to mixin the 'type', 'name' attributes here programatically -- they must be declared
+	// directly in the template as read by the parser in order to function. IE is known to specifically
+	// require the 'name' attribute at element creation time.   See #8484, #8660.
+	// TODO: unclear what that {value: ""} is for; FormWidget.attributeMap copies value to focusNode,
+	// so maybe {value: ""} is so the value *doesn't* get copied to focusNode?
+	// Seems like we really want value removed from attributeMap altogether
+	// (although there's no easy way to do that now)
+	attributeMap: dojo.delegate(dijit.form._FormWidget.prototype.attributeMap, { value: "" }),
+
+	postCreate: function(){
+		if(dojo.isIE || dojo.isWebKit){ // IE won't stop the event with keypress and Safari won't send an ESCAPE to keypress at all
+			this.connect(this.focusNode || this.domNode, "onkeydown", this._onKeyDown);
+		}
+		// Update our reset value if it hasn't yet been set (because this.attr
+		// is only called when there *is* a value
+		if(this._resetValue === undefined){
+			this._resetValue = this.value;
+		}
+	},
+
+	_setValueAttr: function(/*anything*/ newValue, /*Boolean, optional*/ priorityChange){
+		// summary:
+		//		Hook so attr('value', value) works.
+		// description:
+		//		Sets the value of the widget.
+		//		If the value has changed, then fire onChange event, unless priorityChange
+		//		is specified as null (or false?)
+		this.value = newValue;
+		this._handleOnChange(newValue, priorityChange);
+	},
+
+	_getValueAttr: function(/*String*/ value){
+		// summary:
+		//		Hook so attr('value') works.
+		return this._lastValue;
+	},
+
+	undo: function(){
+		// summary:
+		//		Restore the value to the last value passed to onChange
+		this._setValueAttr(this._lastValueReported, false);
+	},
+
+	reset: function(){
+		// summary:
+		//		Reset the widget's value to what it was at initialization time
+		this._hasBeenBlurred = false;
+		this._setValueAttr(this._resetValue, true);
+	},
+
+	_onKeyDown: function(e){
+		if(e.keyCode == dojo.keys.ESCAPE && !e.ctrlKey && !e.altKey){
+			var te;
+			if(dojo.isIE){ 
+				e.preventDefault(); // default behavior needs to be stopped here since keypress is too late
+				te = document.createEventObject();
+				te.keyCode = dojo.keys.ESCAPE;
+				te.shiftKey = e.shiftKey;
+				e.srcElement.fireEvent('onkeypress', te);
+			}else if(dojo.isWebKit){ // ESCAPE needs help making it into keypress
+				te = document.createEvent('Events');
+				te.initEvent('keypress', true, true);
+				te.keyCode = dojo.keys.ESCAPE;
+				te.shiftKey = e.shiftKey;
+				e.target.dispatchEvent(te);
+			}
+		}
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit.dijit"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.dijit"] = true;
+dojo.provide("dijit.dijit");
+
+/*=====
+dijit.dijit = {
+	// summary: A roll-up for common dijit methods
+	// description:
+	//	A rollup file for the build system including the core and common
+	//	dijit files.
+	//	
+	// example:
+	// | <script type="text/javascript" src="js/dojo/dijit/dijit.js"></script>
+	//
+};
+=====*/
+
+// All the stuff in _base (these are the function that are guaranteed available without an explicit dojo.require)
+
+
+// And some other stuff that we tend to pull in all the time anyway
+
+
+
+
+
+
+
+}
+
+if(!dojo._hasResource["dijit._KeyNavContainer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._KeyNavContainer"] = true;
+dojo.provide("dijit._KeyNavContainer");
+
+
+dojo.declare("dijit._KeyNavContainer",
+	[dijit._Container],
+	{
+
+		// summary:
+		//		A _Container with keyboard navigation of its children.
+		// description:
+		//		To use this mixin, call connectKeyNavHandlers() in
+		//		postCreate() and call startupKeyNavChildren() in startup().
+		//		It provides normalized keyboard and focusing code for Container
+		//		widgets.
+/*=====
+		// focusedChild: [protected] Widget
+		//		The currently focused child widget, or null if there isn't one
+		focusedChild: null,
+=====*/
+
+		// tabIndex: Integer
+		//		Tab index of the container; same as HTML tabindex attribute.
+		//		Note then when user tabs into the container, focus is immediately
+		//		moved to the first item in the container.
+		tabIndex: "0",
+
+
+		_keyNavCodes: {},
+
+		connectKeyNavHandlers: function(/*dojo.keys[]*/ prevKeyCodes, /*dojo.keys[]*/ nextKeyCodes){
+			// summary:
+			//		Call in postCreate() to attach the keyboard handlers
+			//		to the container.
+			// preKeyCodes: dojo.keys[]
+			//		Key codes for navigating to the previous child.
+			// nextKeyCodes: dojo.keys[]
+			//		Key codes for navigating to the next child.
+			// tags:
+			//		protected
+
+			var keyCodes = this._keyNavCodes = {};
+			var prev = dojo.hitch(this, this.focusPrev);
+			var next = dojo.hitch(this, this.focusNext);
+			dojo.forEach(prevKeyCodes, function(code){ keyCodes[code] = prev; });
+			dojo.forEach(nextKeyCodes, function(code){ keyCodes[code] = next; });
+			this.connect(this.domNode, "onkeypress", "_onContainerKeypress");
+			this.connect(this.domNode, "onfocus", "_onContainerFocus");
+		},
+
+		startupKeyNavChildren: function(){
+			// summary:
+			//		Call in startup() to set child tabindexes to -1
+			// tags:
+			//		protected
+			dojo.forEach(this.getChildren(), dojo.hitch(this, "_startupChild"));
+		},
+
+		addChild: function(/*Widget*/ widget, /*int?*/ insertIndex){
+			// summary:
+			//		Add a child to our _Container
+			dijit._KeyNavContainer.superclass.addChild.apply(this, arguments);
+			this._startupChild(widget);
+		},
+
+		focus: function(){
+			// summary:
+			//		Default focus() implementation: focus the first child.
+			this.focusFirstChild();
+		},
+
+		focusFirstChild: function(){
+			// summary:
+			//		Focus the first focusable child in the container.
+			// tags:
+			//		protected
+			this.focusChild(this._getFirstFocusableChild());
+		},
+
+		focusNext: function(){
+			// summary:
+			//		Focus the next widget or focal node (for widgets
+			//		with multiple focal nodes) within this container.
+			// tags:
+			//		protected
+			if(this.focusedChild && this.focusedChild.hasNextFocalNode
+					&& this.focusedChild.hasNextFocalNode()){
+				this.focusedChild.focusNext();
+				return;
+			}
+			var child = this._getNextFocusableChild(this.focusedChild, 1);
+			if(child.getFocalNodes){
+				this.focusChild(child, child.getFocalNodes()[0]);
+			}else{
+				this.focusChild(child);
+			}
+		},
+
+		focusPrev: function(){
+			// summary:
+			//		Focus the previous widget or focal node (for widgets
+			//		with multiple focal nodes) within this container.
+			// tags:
+			//		protected
+			if(this.focusedChild && this.focusedChild.hasPrevFocalNode
+					&& this.focusedChild.hasPrevFocalNode()){
+				this.focusedChild.focusPrev();
+				return;
+			}
+			var child = this._getNextFocusableChild(this.focusedChild, -1);
+			if(child.getFocalNodes){
+				var nodes = child.getFocalNodes();
+				this.focusChild(child, nodes[nodes.length-1]);
+			}else{
+				this.focusChild(child);
+			}
+		},
+
+		focusChild: function(/*Widget*/ widget, /*Node?*/ node){
+			// summary:
+			//		Focus widget. Optionally focus 'node' within widget.
+			// tags:
+			//		protected
+			if(widget){
+				if(this.focusedChild && widget !== this.focusedChild){
+					this._onChildBlur(this.focusedChild);
+				}
+				this.focusedChild = widget;
+				if(node && widget.focusFocalNode){
+					widget.focusFocalNode(node);
+				}else{
+					widget.focus();
+				}
+			}
+		},
+
+		_startupChild: function(/*Widget*/ widget){
+			// summary:
+			//		Set tabindex="-1" on focusable widgets so that we
+			// 		can focus them programmatically and by clicking.
+			//		Connect focus and blur handlers.
+			// tags:
+			//		private
+			if(widget.getFocalNodes){
+				dojo.forEach(widget.getFocalNodes(), function(node){
+					dojo.attr(node, "tabindex", -1);
+					this._connectNode(node);
+				}, this);
+			}else{
+				var node = widget.focusNode || widget.domNode;
+				if(widget.isFocusable()){
+					dojo.attr(node, "tabindex", -1);
+				}
+				this._connectNode(node);
+			}
+		},
+
+		_connectNode: function(/*Element*/ node){
+			// summary:
+			//		Monitor focus and blur events on the node
+			// tags:
+			//		private
+			this.connect(node, "onfocus", "_onNodeFocus");
+			this.connect(node, "onblur", "_onNodeBlur");
+		},
+
+		_onContainerFocus: function(evt){
+			// summary:
+			//		Handler for when the container gets focus
+			// description:
+			//		Initially the container itself has a tabIndex, but when it gets
+			//		focus, switch focus to first child...
+			// tags:
+			//		private
+
+			// Note that we can't use _onFocus() because switching focus from the
+			// _onFocus() handler confuses the focus.js code
+			// (because it causes _onFocusNode() to be called recursively)
+
+			// focus bubbles on Firefox,
+			// so just make sure that focus has really gone to the container
+			if(evt.target !== this.domNode){ return; }
+
+			this.focusFirstChild();
+			
+			// and then remove the container's tabIndex,
+			// so that tab or shift-tab will go to the fields after/before
+			// the container, rather than the container itself
+			dojo.removeAttr(this.domNode, "tabIndex");
+		},
+
+		_onBlur: function(evt){
+			// When focus is moved away the container, and it's descendant (popup) widgets,
+			// then restore the container's tabIndex so that user can tab to it again.
+			// Note that using _onBlur() so that this doesn't happen when focus is shifted
+			// to one of my child widgets (typically a popup)
+			if(this.tabIndex){
+				dojo.attr(this.domNode, "tabindex", this.tabIndex);
+			}
+			// TODO: this.inherited(arguments);
+		},
+
+		_onContainerKeypress: function(evt){
+			// summary:
+			//		When a key is pressed, if it's an arrow key etc. then
+			//		it's handled here.
+			// tags:
+			//		private
+			if(evt.ctrlKey || evt.altKey){ return; }
+			var func = this._keyNavCodes[evt.charOrCode];
+			if(func){
+				func();
+				dojo.stopEvent(evt);
+			}
+		},
+
+		_onNodeFocus: function(evt){
+			// summary:
+			//		Handler for onfocus event on a child node
+			// tags:
+			//		private
+
+			// record the child that has been focused
+			var widget = dijit.getEnclosingWidget(evt.target);
+			if(widget && widget.isFocusable()){
+				this.focusedChild = widget;
+			}
+			dojo.stopEvent(evt);
+		},
+
+		_onNodeBlur: function(evt){
+			// summary:
+			//		Handler for onblur event on a child node
+			// tags:
+			//		private
+			dojo.stopEvent(evt);
+		},
+
+		_onChildBlur: function(/*Widget*/ widget){
+			// summary:
+			//		Called when focus leaves a child widget to go
+			//		to a sibling widget.
+			// tags:
+			//		protected
+		},
+
+		_getFirstFocusableChild: function(){
+			// summary:
+			//		Returns first child that can be focused
+			return this._getNextFocusableChild(null, 1);
+		},
+
+		_getNextFocusableChild: function(child, dir){
+			// summary:
+			//		Returns the next or previous focusable child, compared
+			//		to "child"
+			// child: Widget
+			//		The current widget
+			// dir: Integer
+			//		* 1 = after
+			//		* -1 = before
+			if(child){
+				child = this._getSiblingOfChild(child, dir);
+			}
+			var children = this.getChildren();
+			for(var i=0; i < children.length; i++){
+				if(!child){
+					child = children[(dir>0) ? 0 : (children.length-1)];
+				}
+				if(child.isFocusable()){
+					return child;
+				}
+				child = this._getSiblingOfChild(child, dir);
+			}
+			// no focusable child found
+			return null;
+		}
+	}
+);
+
+}
+
+if(!dojo._hasResource["dijit.MenuItem"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.MenuItem"] = true;
+dojo.provide("dijit.MenuItem");
+
+
+
+
+
+dojo.declare("dijit.MenuItem",
+		[dijit._Widget, dijit._Templated, dijit._Contained],
+		{
+		// summary:
+		//		A line item in a Menu Widget
+
+		// Make 3 columns
+		// icon, label, and expand arrow (BiDi-dependent) indicating sub-menu
+		templateString:"<tr class=\"dijitReset dijitMenuItem\" dojoAttachPoint=\"focusNode\" waiRole=\"menuitem\" tabIndex=\"-1\"\n\t\tdojoAttachEvent=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset\" waiRole=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon\" dojoAttachPoint=\"iconNode\">\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" dojoAttachPoint=\"containerNode\"></td>\n\t<td class [...]
+
+		attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
+			label: { node: "containerNode", type: "innerHTML" },
+			iconClass: { node: "iconNode", type: "class" }
+		}),
+
+		// label: String
+		//		Menu text
+		label: '',
+
+		// iconClass: String
+		//		Class to apply to DOMNode to make it display an icon.
+		iconClass: "",
+
+		// accelKey: String
+		//		Text for the accelerator (shortcut) key combination.
+		//		Note that although Menu can display accelerator keys there
+		//		is no infrastructure to actually catch and execute these
+		//		accelerators.
+		accelKey: "",
+
+		// disabled: Boolean
+		//		If true, the menu item is disabled.
+		//		If false, the menu item is enabled.
+		disabled: false,
+
+		_fillContent: function(/*DomNode*/ source){
+			// If button label is specified as srcNodeRef.innerHTML rather than
+			// this.params.label, handle it here.
+			if(source && !("label" in this.params)){
+				this.attr('label', source.innerHTML);
+			}
+		},
+
+		postCreate: function(){
+			dojo.setSelectable(this.domNode, false);
+			dojo.attr(this.containerNode, "id", this.id+"_text");
+			dijit.setWaiState(this.domNode, "labelledby", this.id+"_text");
+		},
+
+		_onHover: function(){
+			// summary:
+			//		Handler when mouse is moved onto menu item
+			// tags:
+			//		protected
+			dojo.addClass(this.domNode, 'dijitMenuItemHover');
+			this.getParent().onItemHover(this);
+		},
+
+		_onUnhover: function(){
+			// summary:
+			//		Handler when mouse is moved off of menu item,
+			//		possibly to a child menu, or maybe to a sibling
+			//		menuitem or somewhere else entirely.
+			// tags:
+			//		protected
+
+			// if we are unhovering the currently selected item
+			// then unselect it
+			dojo.removeClass(this.domNode, 'dijitMenuItemHover');
+			this.getParent().onItemUnhover(this);
+		},
+
+		_onClick: function(evt){
+			// summary:
+			//		Internal handler for click events on MenuItem.
+			// tags:
+			//		private
+			this.getParent().onItemClick(this, evt);
+			dojo.stopEvent(evt);
+		},
+
+		onClick: function(/*Event*/ evt){
+			// summary:
+			//		User defined function to handle clicks
+			// tags:
+			//		callback
+		},
+
+		focus: function(){
+			// summary:
+			//		Focus on this MenuItem
+			try{
+				dijit.focus(this.focusNode);
+			}catch(e){
+				// this throws on IE (at least) in some scenarios
+			}
+		},
+
+		_onFocus: function(){
+			// summary:
+			//		This is called by the focus manager when focus
+			//		goes to this MenuItem or a child menu.
+			// tags:
+			//		protected
+			this._setSelected(true);
+
+			// TODO: this.inherited(arguments);
+		},
+
+		_setSelected: function(selected){
+			// summary:
+			//		Indicate that this node is the currently selected one
+			// tags:
+			//		private
+
+			/***
+			 * TODO: remove this method and calls to it, when _onBlur() is working for MenuItem.
+			 * Currently _onBlur() gets called when focus is moved from the MenuItem to a child menu.
+			 * That's not supposed to happen, but the problem is:
+			 * In order to allow dijit.popup's getTopPopup() to work,a sub menu's popupParent
+			 * points to the parent Menu, bypassing the parent MenuItem... thus the
+			 * MenuItem is not in the chain of active widgets and gets a premature call to
+			 * _onBlur()
+			 */
+			
+			dojo.toggleClass(this.domNode, "dijitMenuItemSelected", selected);
+		},
+
+		setLabel: function(/*String*/ content){
+			// summary:
+			//		Deprecated.   Use attr('label', ...) instead.
+			// tags:
+			//		deprecated
+			dojo.deprecated("dijit.MenuItem.setLabel() is deprecated.  Use attr('label', ...) instead.", "", "2.0");
+			this.attr("label", content);
+		},
+
+		setDisabled: function(/*Boolean*/ disabled){
+			// summary:
+			//		Deprecated.   Use attr('disabled', bool) instead.
+			// tags:
+			//		deprecated
+			dojo.deprecated("dijit.Menu.setDisabled() is deprecated.  Use attr('disabled', bool) instead.", "", "2.0");
+			this.attr('disabled', disabled);
+		},
+		_setDisabledAttr: function(/*Boolean*/ value){
+			// summary:
+			//		Hook for attr('disabled', ...) to work.
+			//		Enable or disable this menu item.
+			this.disabled = value;
+			dojo[value ? "addClass" : "removeClass"](this.domNode, 'dijitMenuItemDisabled');
+			dijit.setWaiState(this.focusNode, 'disabled', value ? 'true' : 'false');
+		},
+		_setAccelKeyAttr: function(/*String*/ value){
+			// summary:
+			//		Hook for attr('accelKey', ...) to work.
+			//		Set accelKey on this menu item.
+			this.accelKey=value;
+
+			this.accelKeyNode.style.display=value?"":"none";
+			this.accelKeyNode.innerHTML=value;
+			//have to use colSpan to make it work in IE
+			dojo.attr(this.containerNode,'colSpan',value?"1":"2");
+		}
+	});
+
+}
+
+if(!dojo._hasResource["dijit.PopupMenuItem"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.PopupMenuItem"] = true;
+dojo.provide("dijit.PopupMenuItem");
+
+
+
+dojo.declare("dijit.PopupMenuItem",
+		dijit.MenuItem,
+		{
+		_fillContent: function(){
+			// summary: 
+			//		When Menu is declared in markup, this code gets the menu label and
+			//		the popup widget from the srcNodeRef.
+			// description:
+			//		srcNodeRefinnerHTML contains both the menu item text and a popup widget
+			//		The first part holds the menu item text and the second part is the popup
+			// example: 
+			// |	<div dojoType="dijit.PopupMenuItem">
+			// |		<span>pick me</span>
+			// |		<popup> ... </popup>
+			// |	</div>
+			// tags:
+			//		protected
+
+			if(this.srcNodeRef){
+				var nodes = dojo.query("*", this.srcNodeRef);
+				dijit.PopupMenuItem.superclass._fillContent.call(this, nodes[0]);
+
+				// save pointer to srcNode so we can grab the drop down widget after it's instantiated
+				this.dropDownContainer = this.srcNodeRef;
+			}
+		},
+
+		startup: function(){
+			if(this._started){ return; }
+			this.inherited(arguments);
+
+			// we didn't copy the dropdown widget from the this.srcNodeRef, so it's in no-man's
+			// land now.  move it to dojo.doc.body.
+			if(!this.popup){
+				var node = dojo.query("[widgetId]", this.dropDownContainer)[0];
+				this.popup = dijit.byNode(node);
+			}
+			dojo.body().appendChild(this.popup.domNode);
+
+			this.popup.domNode.style.display="none";
+			if(this.arrowWrapper){
+				dojo.style(this.arrowWrapper, "visibility", "");
+			}
+			dijit.setWaiState(this.focusNode, "haspopup", "true");
+		},
+		
+		destroyDescendants: function(){
+			if(this.popup){
+				this.popup.destroyRecursive();
+				delete this.popup;
+			}
+			this.inherited(arguments);
+		}
+	});
+
+
+}
+
+if(!dojo._hasResource["dijit.CheckedMenuItem"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.CheckedMenuItem"] = true;
+dojo.provide("dijit.CheckedMenuItem");
+
+
+
+dojo.declare("dijit.CheckedMenuItem",
+		dijit.MenuItem,
+		{
+		// summary:
+		//		A checkbox-like menu item for toggling on and off
+		
+		templateString:"<tr class=\"dijitReset dijitMenuItem\" dojoAttachPoint=\"focusNode\" waiRole=\"menuitemcheckbox\" tabIndex=\"-1\"\n\t\tdojoAttachEvent=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset\" waiRole=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon dijitCheckedMenuItemIcon\" dojoAttachPoint=\"iconNode\">\n\t\t<span class=\"dijitCheckedMenuItemIconChar\">✓</span>\n\t</td>\n\t<td class=\ [...]
+
+		// checked: Boolean
+		//		Our checked state
+		checked: false,
+		_setCheckedAttr: function(/*Boolean*/ checked){
+			// summary:
+			//		Hook so attr('checked', bool) works.
+			//		Sets the class and state for the check box.
+			dojo.toggleClass(this.domNode, "dijitCheckedMenuItemChecked", checked);
+			dijit.setWaiState(this.domNode, "checked", checked);
+			this.checked = checked;
+		},
+
+		onChange: function(/*Boolean*/ checked){
+			// summary:
+			//		User defined function to handle check/uncheck events
+			// tags:
+			//		callback
+		},
+
+		_onClick: function(/*Event*/ e){
+			// summary:
+			//		Clicking this item just toggles its state
+			// tags:
+			//		private
+			if(!this.disabled){
+				this.attr("checked", !this.checked);
+				this.onChange(this.checked);
+			}
+			this.inherited(arguments);
+		}
+	});
+
+}
+
+if(!dojo._hasResource["dijit.MenuSeparator"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.MenuSeparator"] = true;
+dojo.provide("dijit.MenuSeparator");
+
+
+
+
+
+dojo.declare("dijit.MenuSeparator",
+		[dijit._Widget, dijit._Templated, dijit._Contained],
+		{
+		// summary:
+		//		A line between two menu items
+
+		templateString:"<tr class=\"dijitMenuSeparator\">\n\t<td colspan=\"4\">\n\t\t<div class=\"dijitMenuSeparatorTop\"></div>\n\t\t<div class=\"dijitMenuSeparatorBottom\"></div>\n\t</td>\n</tr>\n",
+
+		postCreate: function(){
+			dojo.setSelectable(this.domNode, false);
+		},
+		
+		isFocusable: function(){
+			// summary:
+			//		Override to always return false
+			// tags:
+			//		protected
+
+			return false; // Boolean
+		}
+	});
+
+
+}
+
+if(!dojo._hasResource["dijit.Menu"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.Menu"] = true;
+dojo.provide("dijit.Menu");
+
+
+
+
+
+dojo.declare("dijit._MenuBase",
+	[dijit._Widget, dijit._Templated, dijit._KeyNavContainer],
+{
+	// summary:
+	//		Base class for Menu and MenuBar
+
+	// parentMenu: [readonly] Widget
+	//		pointer to menu that displayed me
+	parentMenu: null,
+
+	// popupDelay: Integer
+	//		number of milliseconds before hovering (without clicking) causes the popup to automatically open.
+	popupDelay: 500,
+
+	startup: function(){
+		if(this._started){ return; }
+
+		dojo.forEach(this.getChildren(), function(child){ child.startup(); });
+		this.startupKeyNavChildren();
+
+		this.inherited(arguments);
+	},
+
+	onExecute: function(){
+		// summary:
+		//		Attach point for notification about when a menu item has been executed.
+		//		This is an internal mechanism used for Menus to signal to their parent to
+		//		close them, because they are about to execute the onClick handler.   In
+		//		general developers should not attach to or override this method.
+		// tags:
+		//		protected
+	},
+
+	onCancel: function(/*Boolean*/ closeAll){
+		// summary:
+		//		Attach point for notification about when the user cancels the current menu
+		//		This is an internal mechanism used for Menus to signal to their parent to
+		//		close them.  In general developers should not attach to or override this method.
+		// tags:
+		//		protected
+	},
+
+	_moveToPopup: function(/*Event*/ evt){
+		// summary:
+		//		This handles the right arrow key (left arrow key on RTL systems),
+		//		which will either open a submenu, or move to the next item in the
+		//		ancestor MenuBar
+		// tags:
+		//		private
+
+		if(this.focusedChild && this.focusedChild.popup && !this.focusedChild.disabled){
+			this.focusedChild._onClick(evt);
+		}else{
+			var topMenu = this._getTopMenu();
+			if(topMenu && topMenu._isMenuBar){
+				topMenu.focusNext();
+			}
+		}
+	},
+
+	onItemHover: function(/*MenuItem*/ item){
+		// summary:
+		//		Called when cursor is over a MenuItem.
+		// tags:
+		//		protected
+
+		// Don't do anything unless user has "activated" the menu by:
+		//		1) clicking it
+		//		2) tabbing into it
+		//		3) opening it from a parent menu (which automatically focuses it)
+		if(this.isActive){
+			this.focusChild(item);
+	
+			if(this.focusedChild.popup && !this.focusedChild.disabled && !this.hover_timer){
+				this.hover_timer = setTimeout(dojo.hitch(this, "_openPopup"), this.popupDelay);
+			}
+		}
+	},
+
+	_onChildBlur: function(item){
+		// summary:
+		//		Called when a child MenuItem becomes inactive because focus
+		//		has been removed from the MenuItem *and* it's descendant menus.
+		// tags:
+		//		private
+
+		item._setSelected(false);
+
+		// Close all popups that are open and descendants of this menu
+		dijit.popup.close(item.popup);
+		this._stopPopupTimer();
+	},
+
+	onItemUnhover: function(/*MenuItem*/ item){
+		// summary:
+		//		Callback fires when mouse exits a MenuItem
+		// tags:
+		//		protected
+		if(this.isActive){
+			this._stopPopupTimer();
+		}
+	},
+
+	_stopPopupTimer: function(){
+		// summary:
+		//		Cancels the popup timer because the user has stop hovering
+		//		on the MenuItem, etc.
+		// tags:
+		//		private
+		if(this.hover_timer){
+			clearTimeout(this.hover_timer);
+			this.hover_timer = null;
+		}
+	},
+
+	_getTopMenu: function(){
+		// summary:
+		//		Returns the top menu in this chain of Menus
+		// tags:
+		//		private
+		for(var top=this; top.parentMenu; top=top.parentMenu);
+		return top;
+	},
+
+	onItemClick: function(/*Widget*/ item, /*Event*/ evt){
+		// summary:
+		//		Handle clicks on an item.
+		// tags:
+		//		private
+		if(item.disabled){ return false; }
+
+		this.focusChild(item);
+
+		if(item.popup){
+			if(!this.is_open){
+				this._openPopup();
+			}
+		}else{
+			// before calling user defined handler, close hierarchy of menus
+			// and restore focus to place it was when menu was opened
+			this.onExecute();
+
+			// user defined handler for click
+			item.onClick(evt);
+		}
+	},
+
+	_openPopup: function(){
+		// summary:
+		//		Open the popup to the side of/underneath the current menu item
+		// tags:
+		//		protected
+
+		this._stopPopupTimer();
+		var from_item = this.focusedChild;
+		var popup = from_item.popup;
+
+		if(popup.isShowingNow){ return; }
+		popup.parentMenu = this;
+		var self = this;
+		dijit.popup.open({
+			parent: this,
+			popup: popup,
+			around: from_item.domNode,
+			orient: this._orient || (this.isLeftToRight() ? {'TR': 'TL', 'TL': 'TR'} : {'TL': 'TR', 'TR': 'TL'}),
+			onCancel: function(){
+				// called when the child menu is canceled
+				dijit.popup.close(popup);
+				from_item.focus();	// put focus back on my node
+				self.currentPopup = null;
+			},
+			onExecute: dojo.hitch(this, "_onDescendantExecute")
+		});
+
+		this.currentPopup = popup;
+
+		if(popup.focus){
+			// If user is opening the popup via keyboard (right arrow, or down arrow for MenuBar),
+			// if the cursor happens to collide with the popup, it will generate an onmouseover event
+			// even though the mouse wasn't moved.   Use a setTimeout() to call popup.focus so that
+			// our focus() call overrides the onmouseover event, rather than vice-versa.  (#8742)
+			setTimeout(dojo.hitch(popup, "focus"), 0);
+		}
+	},
+
+	onOpen: function(/*Event*/ e){
+		// summary:
+		//		Callback when this menu is opened.
+		//		This is called by the popup manager as notification that the menu
+		//		was opened.
+		// tags:
+		//		private
+
+		this.isShowingNow = true;
+	},
+
+	onClose: function(){
+		// summary:
+		//		Callback when this menu is closed.
+		//		This is called by the popup manager as notification that the menu
+		//		was closed.
+		// tags:
+		//		private
+
+		this._stopPopupTimer();
+		this.parentMenu = null;
+		this.isShowingNow = false;
+		this.currentPopup = null;
+		if(this.focusedChild){
+			this._onChildBlur(this.focusedChild);
+			this.focusedChild = null;
+		}
+	},
+
+	_onFocus: function(){
+		// summary:
+		//		Called when this Menu gets focus from:
+		//			1) clicking it
+		//			2) tabbing into it
+		//			3) being opened by a parent menu.
+		//		This is not called just from mouse hover.
+		// tags:
+		//		protected
+		this.isActive = true;
+		dojo.addClass(this.domNode, "dijitMenuActive");
+		dojo.removeClass(this.domNode, "dijitMenuPassive");
+		this.inherited(arguments);
+	},
+	
+	_onBlur: function(){
+		// summary:
+		//		Called when focus is moved away from this Menu and it's submenus.
+		// tags:
+		//		protected
+		this.isActive = false;
+		dojo.removeClass(this.domNode, "dijitMenuActive");
+		dojo.addClass(this.domNode, "dijitMenuPassive");
+
+		// If user blurs/clicks away from a MenuBar (or always visible Menu), then close all popped up submenus etc.
+		this.onClose();
+
+		this.inherited(arguments);
+	},
+
+	_onDescendantExecute: function(){
+		// summary:
+		//		Called when submenu is clicked.  Close hierarchy of menus.
+		// tags:
+		//		private
+		this.onClose();
+	}
+});
+
+dojo.declare("dijit.Menu",
+	dijit._MenuBase,
+	{
+	// summary
+	//		A context menu you can assign to multiple elements
+
+	// TODO: most of the code in here is just for context menu (right-click menu)
+	// support.  In retrospect that should have been a separate class (dijit.ContextMenu).
+	// Split them for 2.0
+
+	constructor: function(){
+		this._bindings = [];
+	},
+
+	templateString:"<table class=\"dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable\" waiRole=\"menu\" tabIndex=\"${tabIndex}\" dojoAttachEvent=\"onkeypress:_onKeyPress\">\n\t<tbody class=\"dijitReset\" dojoAttachPoint=\"containerNode\"></tbody>\n</table>\n",
+
+	// targetNodeIds: [const] String[]
+	//		Array of dom node ids of nodes to attach to.
+	//		Fill this with nodeIds upon widget creation and it becomes context menu for those nodes.
+	targetNodeIds: [],
+
+	// contextMenuForWindow: [const] Boolean
+	//		If true, right clicking anywhere on the window will cause this context menu to open.
+	//		If false, must specify targetNodeIds.
+	contextMenuForWindow: false,
+
+	// leftClickToOpen: [const] Boolean
+	//		If true, menu will open on left click instead of right click, similiar to a file menu.
+	leftClickToOpen: false,
+	
+	// _contextMenuWithMouse: [private] Boolean
+	//		Used to record mouse and keyboard events to determine if a context
+	//		menu is being opened with the keyboard or the mouse.
+	_contextMenuWithMouse: false,
+
+	postCreate: function(){
+		if(this.contextMenuForWindow){
+			this.bindDomNode(dojo.body());
+		}else{
+			dojo.forEach(this.targetNodeIds, this.bindDomNode, this);
+		}
+		var k = dojo.keys, l = this.isLeftToRight();
+		this._openSubMenuKey = l ? k.RIGHT_ARROW : k.LEFT_ARROW;
+		this._closeSubMenuKey = l ? k.LEFT_ARROW : k.RIGHT_ARROW;
+		this.connectKeyNavHandlers([k.UP_ARROW], [k.DOWN_ARROW]);
+	},
+
+	_onKeyPress: function(/*Event*/ evt){
+		// summary:
+		//		Handle keyboard based menu navigation.
+		// tags:
+		//		protected
+
+		if(evt.ctrlKey || evt.altKey){ return; }
+
+		switch(evt.charOrCode){
+			case this._openSubMenuKey:
+				this._moveToPopup(evt);
+				dojo.stopEvent(evt);
+				break;
+			case this._closeSubMenuKey:
+				if(this.parentMenu){
+					if(this.parentMenu._isMenuBar){
+						this.parentMenu.focusPrev();
+					}else{
+						this.onCancel(false);
+					}
+				}else{
+					dojo.stopEvent(evt);
+				}
+				break;
+		}
+	},
+
+	// thanks burstlib!
+	_iframeContentWindow: function(/* HTMLIFrameElement */iframe_el){
+		// summary:
+		//		Returns the window reference of the passed iframe
+		// tags:
+		//		private
+		var win = dijit.getDocumentWindow(dijit.Menu._iframeContentDocument(iframe_el)) ||
+			// Moz. TODO: is this available when defaultView isn't?
+			dijit.Menu._iframeContentDocument(iframe_el)['__parent__'] ||
+			(iframe_el.name && dojo.doc.frames[iframe_el.name]) || null;
+		return win;	//	Window
+	},
+
+	_iframeContentDocument: function(/* HTMLIFrameElement */iframe_el){
+		// summary:
+		//		Returns a reference to the document object inside iframe_el
+		// tags:
+		//		protected
+		var doc = iframe_el.contentDocument // W3
+			|| (iframe_el.contentWindow && iframe_el.contentWindow.document) // IE
+			|| (iframe_el.name && dojo.doc.frames[iframe_el.name] && dojo.doc.frames[iframe_el.name].document)
+			|| null;
+		return doc;	//	HTMLDocument
+	},
+
+	bindDomNode: function(/*String|DomNode*/ node){
+		// summary:
+		//		Attach menu to given node
+		node = dojo.byId(node);
+
+		//TODO: this is to support context popups in Editor.  Maybe this shouldn't be in dijit.Menu
+		var win = dijit.getDocumentWindow(node.ownerDocument);
+		if(node.tagName.toLowerCase()=="iframe"){
+			win = this._iframeContentWindow(node);
+			node = dojo.withGlobal(win, dojo.body);
+		}
+
+		// to capture these events at the top level,
+		// attach to document, not body
+		var cn = (node == dojo.body() ? dojo.doc : node);
+
+		node[this.id] = this._bindings.push([
+			dojo.connect(cn, (this.leftClickToOpen)?"onclick":"oncontextmenu", this, "_openMyself"),
+			dojo.connect(cn, "onkeydown", this, "_contextKey"),
+			dojo.connect(cn, "onmousedown", this, "_contextMouse")
+		]);
+	},
+
+	unBindDomNode: function(/*String|DomNode*/ nodeName){
+		// summary:
+		//		Detach menu from given node
+		var node = dojo.byId(nodeName);
+		if(node){
+			var bid = node[this.id]-1, b = this._bindings[bid];
+			dojo.forEach(b, dojo.disconnect);
+			delete this._bindings[bid];
+		}
+	},
+
+	_contextKey: function(e){
+		// summary:
+		//		Code to handle popping up editor using F10 key rather than mouse
+		// tags:
+		//		private
+		this._contextMenuWithMouse = false;
+		if(e.keyCode == dojo.keys.F10){
+			dojo.stopEvent(e);
+			if(e.shiftKey && e.type=="keydown"){
+				// FF: copying the wrong property from e will cause the system
+				// context menu to appear in spite of stopEvent. Don't know
+				// exactly which properties cause this effect.
+				var _e = { target: e.target, pageX: e.pageX, pageY: e.pageY };
+				_e.preventDefault = _e.stopPropagation = function(){};
+				// IE: without the delay, focus work in "open" causes the system
+				// context menu to appear in spite of stopEvent.
+				window.setTimeout(dojo.hitch(this, function(){ this._openMyself(_e); }), 1);
+			}
+		}
+	},
+
+	_contextMouse: function(e){
+		// summary:
+		//		Helper to remember when we opened the context menu with the mouse instead
+		//		of with the keyboard
+		// tags:
+		//		private
+		this._contextMenuWithMouse = true;
+	},
+
+	_openMyself: function(/*Event*/ e){
+		// summary:
+		//		Internal function for opening myself when the user
+		//		does a right-click or something similar
+		// tags:
+		//		private
+
+		if(this.leftClickToOpen&&e.button>0){
+			return;
+		}
+		dojo.stopEvent(e);
+
+		// Get coordinates.
+		// if we are opening the menu with the mouse or on safari open
+		// the menu at the mouse cursor
+		// (Safari does not have a keyboard command to open the context menu
+		// and we don't currently have a reliable way to determine
+		// _contextMenuWithMouse on Safari)
+		var x,y;
+		if(dojo.isSafari || this._contextMenuWithMouse){
+			x=e.pageX;
+			y=e.pageY;
+		}else{
+			// otherwise open near e.target
+			var coords = dojo.coords(e.target, true);
+			x = coords.x + 10;
+			y = coords.y + 10;
+		}
+
+		var self=this;
+		var savedFocus = dijit.getFocus(this);
+		function closeAndRestoreFocus(){
+			// user has clicked on a menu or popup
+			dijit.focus(savedFocus);
+			dijit.popup.close(self);
+		}
+		dijit.popup.open({
+			popup: this,
+			x: x,
+			y: y,
+			onExecute: closeAndRestoreFocus,
+			onCancel: closeAndRestoreFocus,
+			orient: this.isLeftToRight() ? 'L' : 'R'
+		});
+		this.focus();
+
+		this._onBlur = function(){
+			this.inherited('_onBlur', arguments);
+			// Usually the parent closes the child widget but if this is a context
+			// menu then there is no parent
+			dijit.popup.close(this);
+			// don't try to restore focus; user has clicked another part of the screen
+			// and set focus there
+		};
+	},
+
+	uninitialize: function(){
+ 		dojo.forEach(this.targetNodeIds, this.unBindDomNode, this);
+ 		this.inherited(arguments);
+	}
+}
+);
+
+// Back-compat (TODO: remove in 2.0)
+
+
+
+
+
+
+}
+
+if(!dojo._hasResource["dojox.html.metrics"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.html.metrics"] = true;
+dojo.provide("dojox.html.metrics");
+
+(function(){
+	var dhm = dojox.html.metrics;
+
+	//	derived from Morris John's emResized measurer
+	dhm.getFontMeasurements = function(){
+		//	summary
+		//	Returns an object that has pixel equivilents of standard font size values.
+		var heights = {
+			'1em':0, '1ex':0, '100%':0, '12pt':0, '16px':0, 'xx-small':0, 'x-small':0,
+			'small':0, 'medium':0, 'large':0, 'x-large':0, 'xx-large':0
+		};
+	
+		if(dojo.isIE){
+			//	we do a font-size fix if and only if one isn't applied already.
+			//	NOTE: If someone set the fontSize on the HTML Element, this will kill it.
+			dojo.doc.documentElement.style.fontSize="100%";
+		}
+	
+		//	set up the measuring node.
+		var div=dojo.doc.createElement("div");
+		var ds = div.style;
+		ds.position="absolute";
+		ds.left="-100px";
+		ds.top="0";
+		ds.width="30px";
+		ds.height="1000em";
+		ds.border="0";
+		ds.margin="0";
+		ds.padding="0";
+		ds.outline="0";
+		ds.lineHeight="1";
+		ds.overflow="hidden";
+		dojo.body().appendChild(div);
+	
+		//	do the measurements.
+		for(var p in heights){
+			ds.fontSize = p;
+			heights[p] = Math.round(div.offsetHeight * 12/16) * 16/12 / 1000;
+		}
+		
+		dojo.body().removeChild(div);
+		div = null;
+		return heights; 	//	object
+	};
+
+	var fontMeasurements = null;
+	
+	dhm.getCachedFontMeasurements = function(recalculate){
+		if(recalculate || !fontMeasurements){
+			fontMeasurements = dhm.getFontMeasurements();
+		}
+		return fontMeasurements;
+	};
+
+	var measuringNode = null, empty = {};
+	dhm.getTextBox = function(/* String */ text, /* Object */ style, /* String? */ className){
+		var m;
+		if(!measuringNode){
+			m = measuringNode = dojo.doc.createElement("div");
+			m.style.position = "absolute";
+			m.style.left = "-10000px";
+			m.style.top = "0";
+			dojo.body().appendChild(m);
+		}else{
+			m = measuringNode;
+		}
+		// reset styles
+		m.className = "";
+		m.style.border = "0";
+		m.style.margin = "0";
+		m.style.padding = "0";
+		m.style.outline = "0";
+		// set new style
+		if(arguments.length > 1 && style){
+			for(var i in style){
+				if(i in empty){ continue; }
+				m.style[i] = style[i];
+			}
+		}
+		// set classes
+		if(arguments.length > 2 && className){
+			m.className = className;
+		}
+		// take a measure
+		m.innerHTML = text;
+		return dojo.marginBox(m);
+	};
+
+	//	determine the scrollbar sizes on load.
+	var scroll={ w:16, h:16 };
+	dhm.getScrollbar=function(){ return { w:scroll.w, h:scroll.h }; };
+
+	dhm._fontResizeNode = null;
+
+	dhm.initOnFontResize = function(interval){
+		var f = dhm._fontResizeNode = dojo.doc.createElement("iframe");
+		var fs = f.style;
+		fs.position = "absolute";
+		fs.width = "5em";
+		fs.height = "10em";
+		fs.top = "-10000px";
+		if(dojo.isIE){
+			f.onreadystatechange = function(){
+				if(f.contentWindow.document.readyState == "complete"){
+					f.onresize = f.contentWindow.parent[dojox._scopeName].html.metrics._fontresize;
+				}
+			};
+		}else{
+			f.onload = function(){
+				f.contentWindow.onresize = f.contentWindow.parent[dojox._scopeName].html.metrics._fontresize;
+			};
+		}
+		//The script tag is to work around a known firebug race condition.  See comments in bug #9046
+		f.setAttribute("src", "javascript:'<html><head><script>if(\"loadFirebugConsole\" in window){window.loadFirebugConsole();}</script></head><body></body></html>'");
+		dojo.body().appendChild(f);
+		dhm.initOnFontResize = function(){};
+	};
+
+	dhm.onFontResize = function(){};
+	dhm._fontresize = function(){
+		dhm.onFontResize();
+	}
+
+	dojo.addOnUnload(function(){
+		// destroy our font resize iframe if we have one
+		var f = dhm._fontResizeNode;
+		if(f){
+			if(dojo.isIE && f.onresize){
+				f.onresize = null;
+			}else if(f.contentWindow && f.contentWindow.onresize){
+				f.contentWindow.onresize = null;
+			}
+			dhm._fontResizeNode = null;
+		}
+	});
+
+	dojo.addOnLoad(function(){
+		// getScrollbar metrics node
+		try{
+			var n=dojo.doc.createElement("div");
+			n.style.cssText = "top:0;left:0;width:100px;height:100px;overflow:scroll;position:absolute;visibility:hidden;";
+			dojo.body().appendChild(n);
+			scroll.w = n.offsetWidth - n.clientWidth;
+			scroll.h = n.offsetHeight - n.clientHeight;
+			dojo.body().removeChild(n);
+			//
+			delete n;
+		}catch(e){}
+
+		// text size poll setup
+		if("fontSizeWatch" in dojo.config && !!dojo.config.fontSizeWatch){
+			dhm.initOnFontResize();
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid.util"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.util"] = true;
+dojo.provide("dojox.grid.util");
+
+// summary: grid utility library
+(function(){
+	var dgu = dojox.grid.util;
+
+	dgu.na = '...';
+	dgu.rowIndexTag = "gridRowIndex";
+	dgu.gridViewTag = "gridView";
+
+
+	dgu.fire = function(ob, ev, args){
+		var fn = ob && ev && ob[ev];
+		return fn && (args ? fn.apply(ob, args) : ob[ev]());
+	};
+	
+	dgu.setStyleHeightPx = function(inElement, inHeight){
+		if(inHeight >= 0){
+			var s = inElement.style;
+			var v = inHeight + 'px';
+			if(inElement && s['height'] != v){
+				s['height'] = v;
+			}
+		}
+	};
+	
+	dgu.mouseEvents = [ 'mouseover', 'mouseout', /*'mousemove',*/ 'mousedown', 'mouseup', 'click', 'dblclick', 'contextmenu' ];
+
+	dgu.keyEvents = [ 'keyup', 'keydown', 'keypress' ];
+
+	dgu.funnelEvents = function(inNode, inObject, inMethod, inEvents){
+		var evts = (inEvents ? inEvents : dgu.mouseEvents.concat(dgu.keyEvents));
+		for (var i=0, l=evts.length; i<l; i++){
+			inObject.connect(inNode, 'on' + evts[i], inMethod);
+		}
+	},
+
+	dgu.removeNode = function(inNode){
+		inNode = dojo.byId(inNode);
+		inNode && inNode.parentNode && inNode.parentNode.removeChild(inNode);
+		return inNode;
+	};
+	
+	dgu.arrayCompare = function(inA, inB){
+		for(var i=0,l=inA.length; i<l; i++){
+			if(inA[i] != inB[i]){return false;}
+		}
+		return (inA.length == inB.length);
+	};
+	
+	dgu.arrayInsert = function(inArray, inIndex, inValue){
+		if(inArray.length <= inIndex){
+			inArray[inIndex] = inValue;
+		}else{
+			inArray.splice(inIndex, 0, inValue);
+		}
+	};
+	
+	dgu.arrayRemove = function(inArray, inIndex){
+		inArray.splice(inIndex, 1);
+	};
+	
+	dgu.arraySwap = function(inArray, inI, inJ){
+		var cache = inArray[inI];
+		inArray[inI] = inArray[inJ];
+		inArray[inJ] = cache;
+	};
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid._Scroller"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Scroller"] = true;
+dojo.provide("dojox.grid._Scroller");
+
+(function(){
+	var indexInParent = function(inNode){
+		var i=0, n, p=inNode.parentNode;
+		while((n = p.childNodes[i++])){
+			if(n == inNode){
+				return i - 1;
+			}
+		}
+		return -1;
+	};
+	
+	var cleanNode = function(inNode){
+		if(!inNode){
+			return;
+		}
+		var filter = function(inW){
+			return inW.domNode && dojo.isDescendant(inW.domNode, inNode, true);
+		}
+		var ws = dijit.registry.filter(filter);
+		for(var i=0, w; (w=ws[i]); i++){
+			w.destroy();
+		}
+		delete ws;
+	};
+
+	var getTagName = function(inNodeOrId){
+		var node = dojo.byId(inNodeOrId);
+		return (node && node.tagName ? node.tagName.toLowerCase() : '');
+	};
+	
+	var nodeKids = function(inNode, inTag){
+		var result = [];
+		var i=0, n;
+		while((n = inNode.childNodes[i++])){
+			if(getTagName(n) == inTag){
+				result.push(n);
+			}
+		}
+		return result;
+	};
+	
+	var divkids = function(inNode){
+		return nodeKids(inNode, 'div');
+	};
+
+	dojo.declare("dojox.grid._Scroller", null, {
+		constructor: function(inContentNodes){
+			this.setContentNodes(inContentNodes);
+			this.pageHeights = [];
+			this.pageNodes = [];
+			this.stack = [];
+		},
+		// specified
+		rowCount: 0, // total number of rows to manage
+		defaultRowHeight: 32, // default height of a row
+		keepRows: 100, // maximum number of rows that should exist at one time
+		contentNode: null, // node to contain pages
+		scrollboxNode: null, // node that controls scrolling
+		// calculated
+		defaultPageHeight: 0, // default height of a page
+		keepPages: 10, // maximum number of pages that should exists at one time
+		pageCount: 0,
+		windowHeight: 0,
+		firstVisibleRow: 0,
+		lastVisibleRow: 0,
+		averageRowHeight: 0, // the average height of a row
+		// private
+		page: 0,
+		pageTop: 0,
+		// init
+		init: function(inRowCount, inKeepRows, inRowsPerPage){
+			switch(arguments.length){
+				case 3: this.rowsPerPage = inRowsPerPage;
+				case 2: this.keepRows = inKeepRows;
+				case 1: this.rowCount = inRowCount;
+			}
+			this.defaultPageHeight = this.defaultRowHeight * this.rowsPerPage;
+			this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage);
+			this.setKeepInfo(this.keepRows);
+			this.invalidate();
+			if(this.scrollboxNode){
+				this.scrollboxNode.scrollTop = 0;
+				this.scroll(0);
+				this.scrollboxNode.onscroll = dojo.hitch(this, 'onscroll');
+			}
+		},
+		_getPageCount: function(rowCount, rowsPerPage){
+			return rowCount ? (Math.ceil(rowCount / rowsPerPage) || 1) : 0;
+		},
+		destroy: function(){
+			this.invalidateNodes();
+			delete this.contentNodes;
+			delete this.contentNode;
+			delete this.scrollboxNode;
+		},
+		setKeepInfo: function(inKeepRows){
+			this.keepRows = inKeepRows;
+			this.keepPages = !this.keepRows ? this.keepRows : Math.max(Math.ceil(this.keepRows / this.rowsPerPage), 2);
+		},
+		// nodes
+		setContentNodes: function(inNodes){
+			this.contentNodes = inNodes;
+			this.colCount = (this.contentNodes ? this.contentNodes.length : 0);
+			this.pageNodes = [];
+			for(var i=0; i<this.colCount; i++){
+				this.pageNodes[i] = [];
+			}
+		},
+		getDefaultNodes: function(){
+			return this.pageNodes[0] || [];
+		},
+		// updating
+		invalidate: function(){
+			this.invalidateNodes();
+			this.pageHeights = [];
+			this.height = (this.pageCount ? (this.pageCount - 1)* this.defaultPageHeight + this.calcLastPageHeight() : 0);
+			this.resize();
+		},
+		updateRowCount: function(inRowCount){
+			this.invalidateNodes();
+			this.rowCount = inRowCount;
+			// update page count, adjust document height
+			var oldPageCount = this.pageCount;
+			if(oldPageCount === 0){
+				//We want to have at least 1px in height to keep scroller.  Otherwise with an
+				//empty grid you can't scroll to see the header.
+				this.height = 1;
+			}
+			this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage);
+			if(this.pageCount < oldPageCount){
+				for(var i=oldPageCount-1; i>=this.pageCount; i--){
+					this.height -= this.getPageHeight(i);
+					delete this.pageHeights[i]
+				}
+			}else if(this.pageCount > oldPageCount){
+				this.height += this.defaultPageHeight * (this.pageCount - oldPageCount - 1) + this.calcLastPageHeight();
+			}
+			this.resize();
+		},
+		// implementation for page manager
+		pageExists: function(inPageIndex){
+			return Boolean(this.getDefaultPageNode(inPageIndex));
+		},
+		measurePage: function(inPageIndex){
+			var n = this.getDefaultPageNode(inPageIndex);
+			return (n&&n.innerHTML) ? n.offsetHeight : 0;
+		},
+		positionPage: function(inPageIndex, inPos){
+			for(var i=0; i<this.colCount; i++){
+				this.pageNodes[i][inPageIndex].style.top = inPos + 'px';
+			}
+		},
+		repositionPages: function(inPageIndex){
+			var nodes = this.getDefaultNodes();
+			var last = 0;
+
+			for(var i=0; i<this.stack.length; i++){
+				last = Math.max(this.stack[i], last);
+			}
+			//
+			var n = nodes[inPageIndex];
+			var y = (n ? this.getPageNodePosition(n) + this.getPageHeight(inPageIndex) : 0);
+			//
+			//
+			for(var p=inPageIndex+1; p<=last; p++){
+				n = nodes[p];
+				if(n){
+					//
+					if(this.getPageNodePosition(n) == y){
+						return;
+					}
+					//
+					this.positionPage(p, y);
+				}
+				y += this.getPageHeight(p);
+			}
+		},
+		installPage: function(inPageIndex){
+			for(var i=0; i<this.colCount; i++){
+				this.contentNodes[i].appendChild(this.pageNodes[i][inPageIndex]);
+			}
+		},
+		preparePage: function(inPageIndex, inReuseNode){
+			var p = (inReuseNode ? this.popPage() : null);
+			for(var i=0; i<this.colCount; i++){
+				var nodes = this.pageNodes[i];
+				var new_p = (p === null ? this.createPageNode() : this.invalidatePageNode(p, nodes));
+				new_p.pageIndex = inPageIndex;
+				new_p.id = (this._pageIdPrefix || "") + 'page-' + inPageIndex;
+				nodes[inPageIndex] = new_p;
+			}
+		},
+		// rendering implementation
+		renderPage: function(inPageIndex){
+			var nodes = [];
+			for(var i=0; i<this.colCount; i++){
+				nodes[i] = this.pageNodes[i][inPageIndex];
+			}
+			for(var i=0, j=inPageIndex*this.rowsPerPage; (i<this.rowsPerPage)&&(j<this.rowCount); i++, j++){
+				this.renderRow(j, nodes);
+			}
+		},
+		removePage: function(inPageIndex){
+			for(var i=0, j=inPageIndex*this.rowsPerPage; i<this.rowsPerPage; i++, j++){
+				this.removeRow(j);
+			}
+		},
+		destroyPage: function(inPageIndex){
+			for(var i=0; i<this.colCount; i++){
+				var n = this.invalidatePageNode(inPageIndex, this.pageNodes[i]);
+				if(n){
+					dojo.destroy(n);
+				}
+			}
+		},
+		pacify: function(inShouldPacify){
+		},
+		// pacification
+		pacifying: false,
+		pacifyTicks: 200,
+		setPacifying: function(inPacifying){
+			if(this.pacifying != inPacifying){
+				this.pacifying = inPacifying;
+				this.pacify(this.pacifying);
+			}
+		},
+		startPacify: function(){
+			this.startPacifyTicks = new Date().getTime();
+		},
+		doPacify: function(){
+			var result = (new Date().getTime() - this.startPacifyTicks) > this.pacifyTicks;
+			this.setPacifying(true);
+			this.startPacify();
+			return result;
+		},
+		endPacify: function(){
+			this.setPacifying(false);
+		},
+		// default sizing implementation
+		resize: function(){
+			if(this.scrollboxNode){
+				this.windowHeight = this.scrollboxNode.clientHeight;
+			}
+			for(var i=0; i<this.colCount; i++){
+				//We want to have 1px in height min to keep scroller.  Otherwise can't scroll
+				//and see header in empty grid.
+				dojox.grid.util.setStyleHeightPx(this.contentNodes[i], Math.max(1,this.height));
+			}
+			
+			// Calculate the average row height and update the defaults (row and page).
+			this.needPage(this.page, this.pageTop);
+			var rowsOnPage = (this.page < this.pageCount - 1) ? this.rowsPerPage : ((this.rowCount % this.rowsPerPage) || this.rowsPerPage);
+			var pageHeight = this.getPageHeight(this.page);
+			this.averageRowHeight = (pageHeight > 0 && rowsOnPage > 0) ? (pageHeight / rowsOnPage) : 0;
+		},
+		calcLastPageHeight: function(){
+			if(!this.pageCount){
+				return 0;
+			}
+			var lastPage = this.pageCount - 1;
+			var lastPageHeight = ((this.rowCount % this.rowsPerPage)||(this.rowsPerPage)) * this.defaultRowHeight;
+			this.pageHeights[lastPage] = lastPageHeight;
+			return lastPageHeight;
+		},
+		updateContentHeight: function(inDh){
+			this.height += inDh;
+			this.resize();
+		},
+		updatePageHeight: function(inPageIndex){
+			if(this.pageExists(inPageIndex)){
+				var oh = this.getPageHeight(inPageIndex);
+				var h = (this.measurePage(inPageIndex))||(oh);
+				this.pageHeights[inPageIndex] = h;
+				if((h)&&(oh != h)){
+					this.updateContentHeight(h - oh)
+					this.repositionPages(inPageIndex);
+				}
+			}
+		},
+		rowHeightChanged: function(inRowIndex){
+			this.updatePageHeight(Math.floor(inRowIndex / this.rowsPerPage));
+		},
+		// scroller core
+		invalidateNodes: function(){
+			while(this.stack.length){
+				this.destroyPage(this.popPage());
+			}
+		},
+		createPageNode: function(){
+			var p = document.createElement('div');
+			dojo.attr(p,"role","presentation");
+			p.style.position = 'absolute';
+			//p.style.width = '100%';
+			p.style[dojo._isBodyLtr() ? "left" : "right"] = '0';
+			return p;
+		},
+		getPageHeight: function(inPageIndex){
+			var ph = this.pageHeights[inPageIndex];
+			return (ph !== undefined ? ph : this.defaultPageHeight);
+		},
+		// FIXME: this is not a stack, it's a FIFO list
+		pushPage: function(inPageIndex){
+			return this.stack.push(inPageIndex);
+		},
+		popPage: function(){
+			return this.stack.shift();
+		},
+		findPage: function(inTop){
+			var i = 0, h = 0;
+			for(var ph = 0; i<this.pageCount; i++, h += ph){
+				ph = this.getPageHeight(i);
+				if(h + ph >= inTop){
+					break;
+				}
+			}
+			this.page = i;
+			this.pageTop = h;
+		},
+		buildPage: function(inPageIndex, inReuseNode, inPos){
+			this.preparePage(inPageIndex, inReuseNode);
+			this.positionPage(inPageIndex, inPos);
+			// order of operations is key below
+			this.installPage(inPageIndex);
+			this.renderPage(inPageIndex);
+			// order of operations is key above
+			this.pushPage(inPageIndex);
+		},
+		needPage: function(inPageIndex, inPos){
+			var h = this.getPageHeight(inPageIndex), oh = h;
+			if(!this.pageExists(inPageIndex)){
+				this.buildPage(inPageIndex, this.keepPages&&(this.stack.length >= this.keepPages), inPos);
+				h = this.measurePage(inPageIndex) || h;
+				this.pageHeights[inPageIndex] = h;
+				if(h && (oh != h)){
+					this.updateContentHeight(h - oh)
+				}
+			}else{
+				this.positionPage(inPageIndex, inPos);
+			}
+			return h;
+		},
+		onscroll: function(){
+			this.scroll(this.scrollboxNode.scrollTop);
+		},
+		scroll: function(inTop){
+			this.grid.scrollTop = inTop;
+			if(this.colCount){
+				this.startPacify();
+				this.findPage(inTop);
+				var h = this.height;
+				var b = this.getScrollBottom(inTop);
+				for(var p=this.page, y=this.pageTop; (p<this.pageCount)&&((b<0)||(y<b)); p++){
+					y += this.needPage(p, y);
+				}
+				this.firstVisibleRow = this.getFirstVisibleRow(this.page, this.pageTop, inTop);
+				this.lastVisibleRow = this.getLastVisibleRow(p - 1, y, b);
+				// indicates some page size has been updated
+				if(h != this.height){
+					this.repositionPages(p-1);
+				}
+				this.endPacify();
+			}
+		},
+		getScrollBottom: function(inTop){
+			return (this.windowHeight >= 0 ? inTop + this.windowHeight : -1);
+		},
+		// events
+		processNodeEvent: function(e, inNode){
+			var t = e.target;
+			while(t && (t != inNode) && t.parentNode && (t.parentNode.parentNode != inNode)){
+				t = t.parentNode;
+			}
+			if(!t || !t.parentNode || (t.parentNode.parentNode != inNode)){
+				return false;
+			}
+			var page = t.parentNode;
+			e.topRowIndex = page.pageIndex * this.rowsPerPage;
+			e.rowIndex = e.topRowIndex + indexInParent(t);
+			e.rowTarget = t;
+			return true;
+		},
+		processEvent: function(e){
+			return this.processNodeEvent(e, this.contentNode);
+		},
+		// virtual rendering interface
+		renderRow: function(inRowIndex, inPageNode){
+		},
+		removeRow: function(inRowIndex){
+		},
+		// page node operations
+		getDefaultPageNode: function(inPageIndex){
+			return this.getDefaultNodes()[inPageIndex];
+		},
+		positionPageNode: function(inNode, inPos){
+		},
+		getPageNodePosition: function(inNode){
+			return inNode.offsetTop;
+		},
+		invalidatePageNode: function(inPageIndex, inNodes){
+			var p = inNodes[inPageIndex];
+			if(p){
+				delete inNodes[inPageIndex];
+				this.removePage(inPageIndex, p);
+				cleanNode(p);
+				p.innerHTML = '';
+			}
+			return p;
+		},
+		// scroll control
+		getPageRow: function(inPage){
+			return inPage * this.rowsPerPage;
+		},
+		getLastPageRow: function(inPage){
+			return Math.min(this.rowCount, this.getPageRow(inPage + 1)) - 1;
+		},
+		getFirstVisibleRow: function(inPage, inPageTop, inScrollTop){
+			if(!this.pageExists(inPage)){
+				return 0;
+			}
+			var row = this.getPageRow(inPage);
+			var nodes = this.getDefaultNodes();
+			var rows = divkids(nodes[inPage]);
+			for(var i=0,l=rows.length; i<l && inPageTop<inScrollTop; i++, row++){
+				inPageTop += rows[i].offsetHeight;
+			}
+			return (row ? row - 1 : row);
+		},
+		getLastVisibleRow: function(inPage, inBottom, inScrollBottom){
+			if(!this.pageExists(inPage)){
+				return 0;
+			}
+			var nodes = this.getDefaultNodes();
+			var row = this.getLastPageRow(inPage);
+			var rows = divkids(nodes[inPage]);
+			for(var i=rows.length-1; i>=0 && inBottom>inScrollBottom; i--, row--){
+				inBottom -= rows[i].offsetHeight;
+			}
+			return row + 1;
+		},
+		findTopRow: function(inScrollTop){
+			var nodes = this.getDefaultNodes();
+			var rows = divkids(nodes[this.page]);
+			for(var i=0,l=rows.length,t=this.pageTop,h; i<l; i++){
+				h = rows[i].offsetHeight;
+				t += h;
+				if(t >= inScrollTop){
+					this.offset = h - (t - inScrollTop);
+					return i + this.page * this.rowsPerPage;
+				}
+			}
+			return -1;
+		},
+		findScrollTop: function(inRow){
+			var rowPage = Math.floor(inRow / this.rowsPerPage);
+			var t = 0;
+			for(var i=0; i<rowPage; i++){
+				t += this.getPageHeight(i);
+			}
+			this.pageTop = t;
+			this.needPage(rowPage, this.pageTop);
+
+			var nodes = this.getDefaultNodes();
+			var rows = divkids(nodes[rowPage]);
+			var r = inRow - this.rowsPerPage * rowPage;
+			for(var i=0,l=rows.length; i<l && i<r; i++){
+				t += rows[i].offsetHeight;
+			}
+			return t;
+		},
+		dummy: 0
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid.cells._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.cells._base"] = true;
+dojo.provide("dojox.grid.cells._base");
+
+
+
+(function(){
+	var focusSelectNode = function(inNode){
+		try{
+			dojox.grid.util.fire(inNode, "focus");
+			dojox.grid.util.fire(inNode, "select");
+		}catch(e){// IE sux bad
+		}
+	};
+	
+	var whenIdle = function(/*inContext, inMethod, args ...*/){
+		setTimeout(dojo.hitch.apply(dojo, arguments), 0);
+	};
+
+	var dgc = dojox.grid.cells;
+
+	dojo.declare("dojox.grid.cells._Base", null, {
+		// summary:
+		//	Respresents a grid cell and contains information about column options and methods
+		//	for retrieving cell related information.
+		//	Each column in a grid layout has a cell object and most events and many methods
+		//	provide access to these objects.
+		styles: '',
+		classes: '',
+		editable: false,
+		alwaysEditing: false,
+		formatter: null,
+		defaultValue: '...',
+		value: null,
+		hidden: false,
+		noresize: false,
+		//private
+		_valueProp: "value",
+		_formatPending: false,
+
+		constructor: function(inProps){
+			this._props = inProps || {};
+			dojo.mixin(this, inProps);
+		},
+
+		// data source
+		format: function(inRowIndex, inItem){
+			// summary:
+			//	provides the html for a given grid cell.
+			// inRowIndex: int
+			// grid row index
+			// returns: html for a given grid cell
+			var f, i=this.grid.edit.info, d=this.get ? this.get(inRowIndex, inItem) : (this.value || this.defaultValue);
+			d = (d && d.replace) ? d.replace(/</g, '<') : d;
+			if(this.editable && (this.alwaysEditing || (i.rowIndex==inRowIndex && i.cell==this))){
+				return this.formatEditing(d, inRowIndex);
+			}else{
+				var v = (d != this.defaultValue && (f = this.formatter)) ? f.call(this, d, inRowIndex) : d;
+				return (typeof v == "undefined" ? this.defaultValue : v);
+			}
+		},
+		formatEditing: function(inDatum, inRowIndex){
+			// summary:
+			//	formats the cell for editing
+			// inDatum: anything
+			//	cell data to edit
+			// inRowIndex: int
+			//	grid row index
+			// returns: string of html to place in grid cell
+		},
+		// utility
+		getNode: function(inRowIndex){
+			// summary:
+			//	gets the dom node for a given grid cell.
+			// inRowIndex: int
+			// grid row index
+			// returns: dom node for a given grid cell
+			return this.view.getCellNode(inRowIndex, this.index);
+		},
+		getHeaderNode: function(){
+			return this.view.getHeaderCellNode(this.index);
+		},
+		getEditNode: function(inRowIndex){
+			return (this.getNode(inRowIndex) || 0).firstChild || 0;
+		},
+		canResize: function(){
+			var uw = this.unitWidth;
+			return uw && (uw!=='auto');
+		},
+		isFlex: function(){
+			var uw = this.unitWidth;
+			return uw && dojo.isString(uw) && (uw=='auto' || uw.slice(-1)=='%');
+		},
+		// edit support
+		applyEdit: function(inValue, inRowIndex){
+			this.grid.edit.applyCellEdit(inValue, this, inRowIndex);
+		},
+		cancelEdit: function(inRowIndex){
+			this.grid.doCancelEdit(inRowIndex);
+		},
+		_onEditBlur: function(inRowIndex){
+			if(this.grid.edit.isEditCell(inRowIndex, this.index)){
+				//
+				this.grid.edit.apply();
+			}
+		},
+		registerOnBlur: function(inNode, inRowIndex){
+			if(this.commitOnBlur){
+				dojo.connect(inNode, "onblur", function(e){
+					// hack: if editor still thinks this editor is current some ms after it blurs, assume we've focused away from grid
+					setTimeout(dojo.hitch(this, "_onEditBlur", inRowIndex), 250);
+				});
+			}
+		},
+		//protected
+		needFormatNode: function(inDatum, inRowIndex){
+			this._formatPending = true;
+			whenIdle(this, "_formatNode", inDatum, inRowIndex);
+		},
+		cancelFormatNode: function(){
+			this._formatPending = false;
+		},
+		//private
+		_formatNode: function(inDatum, inRowIndex){
+			if(this._formatPending){
+				this._formatPending = false;
+				// make cell selectable
+				dojo.setSelectable(this.grid.domNode, true);
+				this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex);
+			}
+		},
+		//protected
+		formatNode: function(inNode, inDatum, inRowIndex){
+			// summary:
+			//	format the editing dom node. Use when editor is a widget.
+			// inNode: dom node
+			// dom node for the editor
+			// inDatum: anything
+			//	cell data to edit
+			// inRowIndex: int
+			//	grid row index
+			if(dojo.isIE){
+				// IE sux bad
+				whenIdle(this, "focus", inRowIndex, inNode);
+			}else{
+				this.focus(inRowIndex, inNode);
+			}
+		},
+		dispatchEvent: function(m, e){
+			if(m in this){
+				return this[m](e);
+			}
+		},
+		//public
+		getValue: function(inRowIndex){
+			// summary:
+			//	returns value entered into editor
+			// inRowIndex: int
+			// grid row index
+			// returns:
+			//	value of editor
+			return this.getEditNode(inRowIndex)[this._valueProp];
+		},
+		setValue: function(inRowIndex, inValue){
+			// summary:
+			//	set the value of the grid editor
+			// inRowIndex: int
+			// grid row index
+			// inValue: anything
+			//	value of editor
+			var n = this.getEditNode(inRowIndex);
+			if(n){
+				n[this._valueProp] = inValue
+			};
+		},
+		focus: function(inRowIndex, inNode){
+			// summary:
+			//	focus the grid editor
+			// inRowIndex: int
+			// grid row index
+			// inNode: dom node
+			//	editor node
+			focusSelectNode(inNode || this.getEditNode(inRowIndex));
+		},
+		save: function(inRowIndex){
+			// summary:
+			//	save editor state
+			// inRowIndex: int
+			// grid row index
+			this.value = this.value || this.getValue(inRowIndex);
+			//
+		},
+		restore: function(inRowIndex){
+			// summary:
+			//	restore editor state
+			// inRowIndex: int
+			// grid row index
+			this.setValue(inRowIndex, this.value);
+			//
+		},
+		//protected
+		_finish: function(inRowIndex){
+			// summary:
+			//	called when editing is completed to clean up editor
+			// inRowIndex: int
+			// grid row index
+			dojo.setSelectable(this.grid.domNode, false);
+			this.cancelFormatNode();
+		},
+		//public
+		apply: function(inRowIndex){
+			// summary:
+			//	apply edit from cell editor
+			// inRowIndex: int
+			// grid row index
+			this.applyEdit(this.getValue(inRowIndex), inRowIndex);
+			this._finish(inRowIndex);
+		},
+		cancel: function(inRowIndex){
+			// summary:
+			//	cancel cell edit
+			// inRowIndex: int
+			// grid row index
+			this.cancelEdit(inRowIndex);
+			this._finish(inRowIndex);
+		}
+	});
+	dgc._Base.markupFactory = function(node, cellDef){
+		var d = dojo;
+		var formatter = d.trim(d.attr(node, "formatter")||"");
+		if(formatter){
+			cellDef.formatter = dojo.getObject(formatter);
+		}
+		var get = d.trim(d.attr(node, "get")||"");
+		if(get){
+			cellDef.get = dojo.getObject(get);
+		}
+		var getBoolAttr = function(attr){
+			var value = d.trim(d.attr(node, attr)||"");
+			return value ? !(value.toLowerCase()=="false") : undefined;
+		}
+		cellDef.sortDesc = getBoolAttr("sortDesc");
+		cellDef.editable = getBoolAttr("editable");
+		cellDef.alwaysEditing = getBoolAttr("alwaysEditing");
+		cellDef.noresize = getBoolAttr("noresize");
+
+		var value = d.trim(d.attr(node, "loadingText")||d.attr(node, "defaultValue")||"");
+		if(value){
+			cellDef.defaultValue = value;
+		}
+
+		var getStrAttr = function(attr){
+			return d.trim(d.attr(node, attr)||"")||undefined;
+		};
+		cellDef.styles = getStrAttr("styles");
+		cellDef.headerStyles = getStrAttr("headerStyles");
+		cellDef.cellStyles = getStrAttr("cellStyles");
+		cellDef.classes = getStrAttr("classes");
+		cellDef.headerClasses = getStrAttr("headerClasses");
+		cellDef.cellClasses = getStrAttr("cellClasses");
+	}
+
+	dojo.declare("dojox.grid.cells.Cell", dgc._Base, {
+		// summary
+		// grid cell that provides a standard text input box upon editing
+		constructor: function(){
+			this.keyFilter = this.keyFilter;
+		},
+		// keyFilter: RegExp
+		//		optional regex for disallowing keypresses
+		keyFilter: null,
+		formatEditing: function(inDatum, inRowIndex){
+			this.needFormatNode(inDatum, inRowIndex);
+			return '<input class="dojoxGridInput" type="text" value="' + inDatum + '">';
+		},
+		formatNode: function(inNode, inDatum, inRowIndex){
+			this.inherited(arguments);
+			// FIXME: feels too specific for this interface
+			this.registerOnBlur(inNode, inRowIndex);
+		},
+		doKey: function(e){
+			if(this.keyFilter){
+				var key = String.fromCharCode(e.charCode);
+				if(key.search(this.keyFilter) == -1){
+					dojo.stopEvent(e);
+				}
+			}
+		},
+		_finish: function(inRowIndex){
+			this.inherited(arguments);
+			var n = this.getEditNode(inRowIndex);
+			try{
+				dojox.grid.util.fire(n, "blur");
+			}catch(e){}
+		}
+	});
+	dgc.Cell.markupFactory = function(node, cellDef){
+		dgc._Base.markupFactory(node, cellDef);
+		var d = dojo;
+		var keyFilter = d.trim(d.attr(node, "keyFilter")||"");
+		if(keyFilter){
+			cellDef.keyFilter = new RegExp(keyFilter);
+		}
+	}
+
+	dojo.declare("dojox.grid.cells.RowIndex", dgc.Cell, {
+		name: 'Row',
+
+		postscript: function(){
+			this.editable = false;
+		},
+		get: function(inRowIndex){
+			return inRowIndex + 1;
+		}
+	});
+	dgc.RowIndex.markupFactory = function(node, cellDef){
+		dgc.Cell.markupFactory(node, cellDef);
+	}
+
+	dojo.declare("dojox.grid.cells.Select", dgc.Cell, {
+		// summary:
+		// grid cell that provides a standard select for editing
+
+		// options: Array
+		// 		text of each item
+		options: null,
+
+		// values: Array
+		//		value for each item
+		values: null,
+
+		// returnIndex: Integer
+		// 		editor returns only the index of the selected option and not the value
+		returnIndex: -1,
+
+		constructor: function(inCell){
+			this.values = this.values || this.options;
+		},
+		formatEditing: function(inDatum, inRowIndex){
+			this.needFormatNode(inDatum, inRowIndex);
+			var h = [ '<select class="dojoxGridSelect">' ];
+			for (var i=0, o, v; ((o=this.options[i]) !== undefined)&&((v=this.values[i]) !== undefined); i++){
+				h.push("<option", (inDatum==v ? ' selected' : ''), ' value="' + v + '"', ">", o, "</option>");
+			}
+			h.push('</select>');
+			return h.join('');
+		},
+		getValue: function(inRowIndex){
+			var n = this.getEditNode(inRowIndex);
+			if(n){
+				var i = n.selectedIndex, o = n.options[i];
+				return this.returnIndex > -1 ? i : o.value || o.innerHTML;
+			}
+		}
+	});
+	dgc.Select.markupFactory = function(node, cell){
+		dgc.Cell.markupFactory(node, cell);
+		var d=dojo;
+		var options = d.trim(d.attr(node, "options")||"");
+		if(options){
+			var o = options.split(',');
+			if(o[0] != options){
+				cell.options = o;
+			}
+		}
+		var values = d.trim(d.attr(node, "values")||"");
+		if(values){
+			var v = values.split(',');
+			if(v[0] != values){
+				cell.values = v;
+			}
+		}
+	}
+
+	dojo.declare("dojox.grid.cells.AlwaysEdit", dgc.Cell, {
+		// summary:
+		// grid cell that is always in an editable state, regardless of grid editing state
+		alwaysEditing: true,
+		_formatNode: function(inDatum, inRowIndex){
+			this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex);
+		},
+		applyStaticValue: function(inRowIndex){
+			var e = this.grid.edit;
+			e.applyCellEdit(this.getValue(inRowIndex), this, inRowIndex);
+			e.start(this, inRowIndex, true);
+		}
+	});
+	dgc.AlwaysEdit.markupFactory = function(node, cell){
+		dgc.Cell.markupFactory(node, cell);
+	}
+
+	dojo.declare("dojox.grid.cells.Bool", dgc.AlwaysEdit, {
+		// summary:
+		// grid cell that provides a standard checkbox that is always on for editing
+		_valueProp: "checked",
+		formatEditing: function(inDatum, inRowIndex){
+			return '<input class="dojoxGridInput" type="checkbox"' + (inDatum ? ' checked="checked"' : '') + ' style="width: auto" />';
+		},
+		doclick: function(e){
+			if(e.target.tagName == 'INPUT'){
+				this.applyStaticValue(e.rowIndex);
+			}
+		}
+	});
+	dgc.Bool.markupFactory = function(node, cell){
+		dgc.AlwaysEdit.markupFactory(node, cell);
+	}
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid.cells"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.cells"] = true;
+dojo.provide("dojox.grid.cells");
+
+
+}
+
+if(!dojo._hasResource["dojo.dnd.common"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.common"] = true;
+dojo.provide("dojo.dnd.common");
+
+dojo.dnd._isMac = navigator.appVersion.indexOf("Macintosh") >= 0;
+dojo.dnd._copyKey = dojo.dnd._isMac ? "metaKey" : "ctrlKey";
+
+dojo.dnd.getCopyKeyState = function(e) {
+	// summary: abstracts away the difference between selection on Mac and PC,
+	//	and returns the state of the "copy" key to be pressed.
+	// e: Event: mouse event
+	return e[dojo.dnd._copyKey];	// Boolean
+};
+
+dojo.dnd._uniqueId = 0;
+dojo.dnd.getUniqueId = function(){
+	// summary: returns a unique string for use with any DOM element
+	var id;
+	do{
+		id = dojo._scopeName + "Unique" + (++dojo.dnd._uniqueId);
+	}while(dojo.byId(id));
+	return id;
+};
+
+dojo.dnd._empty = {};
+
+dojo.dnd.isFormElement = function(/*Event*/ e){
+	// summary: returns true, if user clicked on a form element
+	var t = e.target;
+	if(t.nodeType == 3 /*TEXT_NODE*/){
+		t = t.parentNode;
+	}
+	return " button textarea input select option ".indexOf(" " + t.tagName.toLowerCase() + " ") >= 0;	// Boolean
+};
+
+// doesn't take into account when multiple buttons are pressed
+dojo.dnd._lmb = dojo.isIE ? 1 : 0;	// left mouse button
+
+dojo.dnd._isLmbPressed = dojo.isIE ?
+	function(e){ return e.button & 1; } : // intentional bit-and
+	function(e){ return e.button === 0; };
+
+}
+
+if(!dojo._hasResource["dojo.dnd.autoscroll"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.autoscroll"] = true;
+dojo.provide("dojo.dnd.autoscroll");
+
+dojo.dnd.getViewport = function(){
+	// summary: returns a viewport size (visible part of the window)
+
+	// FIXME: need more docs!!
+	var d = dojo.doc, dd = d.documentElement, w = window, b = dojo.body();
+	if(dojo.isMozilla){
+		return {w: dd.clientWidth, h: w.innerHeight};	// Object
+	}else if(!dojo.isOpera && w.innerWidth){
+		return {w: w.innerWidth, h: w.innerHeight};		// Object
+	}else if (!dojo.isOpera && dd && dd.clientWidth){
+		return {w: dd.clientWidth, h: dd.clientHeight};	// Object
+	}else if (b.clientWidth){
+		return {w: b.clientWidth, h: b.clientHeight};	// Object
+	}
+	return null;	// Object
+};
+
+dojo.dnd.V_TRIGGER_AUTOSCROLL = 32;
+dojo.dnd.H_TRIGGER_AUTOSCROLL = 32;
+
+dojo.dnd.V_AUTOSCROLL_VALUE = 16;
+dojo.dnd.H_AUTOSCROLL_VALUE = 16;
+
+dojo.dnd.autoScroll = function(e){
+	// summary:
+	//		a handler for onmousemove event, which scrolls the window, if
+	//		necesary
+	// e: Event:
+	//		onmousemove event
+
+	// FIXME: needs more docs!
+	var v = dojo.dnd.getViewport(), dx = 0, dy = 0;
+	if(e.clientX < dojo.dnd.H_TRIGGER_AUTOSCROLL){
+		dx = -dojo.dnd.H_AUTOSCROLL_VALUE;
+	}else if(e.clientX > v.w - dojo.dnd.H_TRIGGER_AUTOSCROLL){
+		dx = dojo.dnd.H_AUTOSCROLL_VALUE;
+	}
+	if(e.clientY < dojo.dnd.V_TRIGGER_AUTOSCROLL){
+		dy = -dojo.dnd.V_AUTOSCROLL_VALUE;
+	}else if(e.clientY > v.h - dojo.dnd.V_TRIGGER_AUTOSCROLL){
+		dy = dojo.dnd.V_AUTOSCROLL_VALUE;
+	}
+	window.scrollBy(dx, dy);
+};
+
+dojo.dnd._validNodes = {"div": 1, "p": 1, "td": 1};
+dojo.dnd._validOverflow = {"auto": 1, "scroll": 1};
+
+dojo.dnd.autoScrollNodes = function(e){
+	// summary:
+	//		a handler for onmousemove event, which scrolls the first avaialble
+	//		Dom element, it falls back to dojo.dnd.autoScroll()
+	// e: Event:
+	//		onmousemove event
+
+	// FIXME: needs more docs!
+	for(var n = e.target; n;){
+		if(n.nodeType == 1 && (n.tagName.toLowerCase() in dojo.dnd._validNodes)){
+			var s = dojo.getComputedStyle(n);
+			if(s.overflow.toLowerCase() in dojo.dnd._validOverflow){
+				var b = dojo._getContentBox(n, s), t = dojo._abs(n, true);
+				//
+				var w = Math.min(dojo.dnd.H_TRIGGER_AUTOSCROLL, b.w / 2), 
+					h = Math.min(dojo.dnd.V_TRIGGER_AUTOSCROLL, b.h / 2),
+					rx = e.pageX - t.x, ry = e.pageY - t.y, dx = 0, dy = 0;
+				if(dojo.isWebKit || dojo.isOpera){
+					// FIXME: this code should not be here, it should be taken into account 
+					// either by the event fixing code, or the dojo._abs()
+					// FIXME: this code doesn't work on Opera 9.5 Beta
+					rx += dojo.body().scrollLeft, ry += dojo.body().scrollTop;
+				}
+				if(rx > 0 && rx < b.w){
+					if(rx < w){
+						dx = -w;
+					}else if(rx > b.w - w){
+						dx = w;
+					}
+				}
+				//
+				if(ry > 0 && ry < b.h){
+					if(ry < h){
+						dy = -h;
+					}else if(ry > b.h - h){
+						dy = h;
+					}
+				}
+				var oldLeft = n.scrollLeft, oldTop = n.scrollTop;
+				n.scrollLeft = n.scrollLeft + dx;
+				n.scrollTop  = n.scrollTop  + dy;
+				if(oldLeft != n.scrollLeft || oldTop != n.scrollTop){ return; }
+			}
+		}
+		try{
+			n = n.parentNode;
+		}catch(x){
+			n = null;
+		}
+	}
+	dojo.dnd.autoScroll(e);
+};
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Mover"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Mover"] = true;
+dojo.provide("dojo.dnd.Mover");
+
+
+
+
+dojo.declare("dojo.dnd.Mover", null, {
+	constructor: function(node, e, host){
+		// summary: an object, which makes a node follow the mouse, 
+		//	used as a default mover, and as a base class for custom movers
+		// node: Node: a node (or node's id) to be moved
+		// e: Event: a mouse event, which started the move;
+		//	only pageX and pageY properties are used
+		// host: Object?: object which implements the functionality of the move,
+		//	 and defines proper events (onMoveStart and onMoveStop)
+		this.node = dojo.byId(node);
+		this.marginBox = {l: e.pageX, t: e.pageY};
+		this.mouseButton = e.button;
+		var h = this.host = host, d = node.ownerDocument, 
+			firstEvent = dojo.connect(d, "onmousemove", this, "onFirstMove");
+		this.events = [
+			dojo.connect(d, "onmousemove", this, "onMouseMove"),
+			dojo.connect(d, "onmouseup",   this, "onMouseUp"),
+			// cancel text selection and text dragging
+			dojo.connect(d, "ondragstart",   dojo.stopEvent),
+			dojo.connect(d.body, "onselectstart", dojo.stopEvent),
+			firstEvent
+		];
+		// notify that the move has started
+		if(h && h.onMoveStart){
+			h.onMoveStart(this);
+		}
+	},
+	// mouse event processors
+	onMouseMove: function(e){
+		// summary: event processor for onmousemove
+		// e: Event: mouse event
+		dojo.dnd.autoScroll(e);
+		var m = this.marginBox;
+		this.host.onMove(this, {l: m.l + e.pageX, t: m.t + e.pageY});
+		dojo.stopEvent(e);
+	},
+	onMouseUp: function(e){
+		if(dojo.isWebKit && dojo.dnd._isMac && this.mouseButton == 2 ? 
+				e.button == 0 : this.mouseButton == e.button){
+			this.destroy();
+		}
+		dojo.stopEvent(e);
+	},
+	// utilities
+	onFirstMove: function(){
+		// summary: makes the node absolute; it is meant to be called only once. 
+		// 	relative and absolutely positioned nodes are assumed to use pixel units
+		var s = this.node.style, l, t, h = this.host;
+		switch(s.position){
+			case "relative":
+			case "absolute":
+				// assume that left and top values are in pixels already
+				l = Math.round(parseFloat(s.left));
+				t = Math.round(parseFloat(s.top));
+				break;
+			default:
+				s.position = "absolute";	// enforcing the absolute mode
+				var m = dojo.marginBox(this.node);
+				// event.pageX/pageY (which we used to generate the initial
+				// margin box) includes padding and margin set on the body.
+				// However, setting the node's position to absolute and then
+				// doing dojo.marginBox on it *doesn't* take that additional
+				// space into account - so we need to subtract the combined
+				// padding and margin.  We use getComputedStyle and
+				// _getMarginBox/_getContentBox to avoid the extra lookup of
+				// the computed style. 
+				var b = dojo.doc.body;
+				var bs = dojo.getComputedStyle(b);
+				var bm = dojo._getMarginBox(b, bs);
+				var bc = dojo._getContentBox(b, bs);
+				l = m.l - (bc.l - bm.l);
+				t = m.t - (bc.t - bm.t);
+				break;
+		}
+		this.marginBox.l = l - this.marginBox.l;
+		this.marginBox.t = t - this.marginBox.t;
+		if(h && h.onFirstMove){
+			h.onFirstMove(this);
+		}
+		dojo.disconnect(this.events.pop());
+	},
+	destroy: function(){
+		// summary: stops the move, deletes all references, so the object can be garbage-collected
+		dojo.forEach(this.events, dojo.disconnect);
+		// undo global settings
+		var h = this.host;
+		if(h && h.onMoveStop){
+			h.onMoveStop(this);
+		}
+		// destroy objects
+		this.events = this.node = this.host = null;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Moveable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Moveable"] = true;
+dojo.provide("dojo.dnd.Moveable");
+
+
+
+dojo.declare("dojo.dnd.Moveable", null, {
+	// object attributes (for markup)
+	handle: "",
+	delay: 0,
+	skip: false,
+	
+	constructor: function(node, params){
+		// summary: an object, which makes a node moveable
+		// node: Node: a node (or node's id) to be moved
+		// params: Object: an optional object with additional parameters;
+		//	following parameters are recognized:
+		//		handle: Node: a node (or node's id), which is used as a mouse handle
+		//			if omitted, the node itself is used as a handle
+		//		delay: Number: delay move by this number of pixels
+		//		skip: Boolean: skip move of form elements
+		//		mover: Object: a constructor of custom Mover
+		this.node = dojo.byId(node);
+		if(!params){ params = {}; }
+		this.handle = params.handle ? dojo.byId(params.handle) : null;
+		if(!this.handle){ this.handle = this.node; }
+		this.delay = params.delay > 0 ? params.delay : 0;
+		this.skip  = params.skip;
+		this.mover = params.mover ? params.mover : dojo.dnd.Mover;
+		this.events = [
+			dojo.connect(this.handle, "onmousedown", this, "onMouseDown"),
+			// cancel text selection and text dragging
+			dojo.connect(this.handle, "ondragstart",   this, "onSelectStart"),
+			dojo.connect(this.handle, "onselectstart", this, "onSelectStart")
+		];
+	},
+
+	// markup methods
+	markupFactory: function(params, node){
+		return new dojo.dnd.Moveable(node, params);
+	},
+
+	// methods
+	destroy: function(){
+		// summary: stops watching for possible move, deletes all references, so the object can be garbage-collected
+		dojo.forEach(this.events, dojo.disconnect);
+		this.events = this.node = this.handle = null;
+	},
+	
+	// mouse event processors
+	onMouseDown: function(e){
+		// summary: event processor for onmousedown, creates a Mover for the node
+		// e: Event: mouse event
+		if(this.skip && dojo.dnd.isFormElement(e)){ return; }
+		if(this.delay){
+			this.events.push(
+				dojo.connect(this.handle, "onmousemove", this, "onMouseMove"),
+				dojo.connect(this.handle, "onmouseup", this, "onMouseUp")
+			);
+			this._lastX = e.pageX;
+			this._lastY = e.pageY;
+		}else{
+			this.onDragDetected(e);
+		}
+		dojo.stopEvent(e);
+	},
+	onMouseMove: function(e){
+		// summary: event processor for onmousemove, used only for delayed drags
+		// e: Event: mouse event
+		if(Math.abs(e.pageX - this._lastX) > this.delay || Math.abs(e.pageY - this._lastY) > this.delay){
+			this.onMouseUp(e);
+			this.onDragDetected(e);
+		}
+		dojo.stopEvent(e);
+	},
+	onMouseUp: function(e){
+		// summary: event processor for onmouseup, used only for delayed drags
+		// e: Event: mouse event
+		for(var i = 0; i < 2; ++i){
+			dojo.disconnect(this.events.pop());
+		}
+		dojo.stopEvent(e);
+	},
+	onSelectStart: function(e){
+		// summary: event processor for onselectevent and ondragevent
+		// e: Event: mouse event
+		if(!this.skip || !dojo.dnd.isFormElement(e)){
+			dojo.stopEvent(e);
+		}
+	},
+	
+	// local events
+	onDragDetected: function(/* Event */ e){
+		// summary: called when the drag is detected,
+		// responsible for creation of the mover
+		new this.mover(this.node, e, this);
+	},
+	onMoveStart: function(/* dojo.dnd.Mover */ mover){
+		// summary: called before every move operation
+		dojo.publish("/dnd/move/start", [mover]);
+		dojo.addClass(dojo.body(), "dojoMove"); 
+		dojo.addClass(this.node, "dojoMoveItem"); 
+	},
+	onMoveStop: function(/* dojo.dnd.Mover */ mover){
+		// summary: called after every move operation
+		dojo.publish("/dnd/move/stop", [mover]);
+		dojo.removeClass(dojo.body(), "dojoMove");
+		dojo.removeClass(this.node, "dojoMoveItem");
+	},
+	onFirstMove: function(/* dojo.dnd.Mover */ mover){
+		// summary: called during the very first move notification,
+		//	can be used to initialize coordinates, can be overwritten.
+		
+		// default implementation does nothing
+	},
+	onMove: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
+		// summary: called during every move notification,
+		//	should actually move the node, can be overwritten.
+		this.onMoving(mover, leftTop);
+		var s = mover.node.style;
+		s.left = leftTop.l + "px";
+		s.top  = leftTop.t + "px";
+		this.onMoved(mover, leftTop);
+	},
+	onMoving: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
+		// summary: called before every incremental move,
+		//	can be overwritten.
+		
+		// default implementation does nothing
+	},
+	onMoved: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
+		// summary: called after every incremental move,
+		//	can be overwritten.
+		
+		// default implementation does nothing
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._Builder"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Builder"] = true;
+dojo.provide("dojox.grid._Builder");
+
+
+
+
+(function(){
+	var dg = dojox.grid;
+
+	var getTdIndex = function(td){
+		return td.cellIndex >=0 ? td.cellIndex : dojo.indexOf(td.parentNode.cells, td);
+	};
+	
+	var getTrIndex = function(tr){
+		return tr.rowIndex >=0 ? tr.rowIndex : dojo.indexOf(tr.parentNode.childNodes, tr);
+	};
+	
+	var getTr = function(rowOwner, index){
+		return rowOwner && ((rowOwner.rows||0)[index] || rowOwner.childNodes[index]);
+	};
+
+	var findTable = function(node){
+		for(var n=node; n && n.tagName!='TABLE'; n=n.parentNode);
+		return n;
+	};
+	
+	var ascendDom = function(inNode, inWhile){
+		for(var n=inNode; n && inWhile(n); n=n.parentNode);
+		return n;
+	};
+	
+	var makeNotTagName = function(inTagName){
+		var name = inTagName.toUpperCase();
+		return function(node){ return node.tagName != name; };
+	};
+
+	var rowIndexTag = dojox.grid.util.rowIndexTag;
+	var gridViewTag = dojox.grid.util.gridViewTag;
+
+	// base class for generating markup for the views
+	dg._Builder = dojo.extend(function(view){
+		if(view){
+			this.view = view;
+			this.grid = view.grid;
+		}
+	},{
+		view: null,
+		// boilerplate HTML
+		_table: '<table class="dojoxGridRowTable" border="0" cellspacing="0" cellpadding="0" role="'+(dojo.isFF<3 ? "wairole:" : "")+'presentation"',
+
+		// Returns the table variable as an array - and with the view width, if specified
+		getTableArray: function(){
+			var html = [this._table];
+			if(this.view.viewWidth){
+				html.push([' style="width:', this.view.viewWidth, ';"'].join(''));
+			}
+			html.push('>');
+			return html;
+		},
+		
+		// generate starting tags for a cell
+		generateCellMarkup: function(inCell, inMoreStyles, inMoreClasses, isHeader){
+			var result = [], html;
+			var waiPrefix = dojo.isFF<3 ? "wairole:" : "";
+			if(isHeader){
+				var sortInfo = inCell.index != inCell.grid.getSortIndex() ? "" : inCell.grid.sortInfo > 0 ? 'aria-sort="ascending"' : 'aria-sort="descending"';
+				html = ['<th tabIndex="-1" role="', waiPrefix, 'columnheader"', sortInfo];
+			}else{
+				html = ['<td tabIndex="-1" role="', waiPrefix, 'gridcell"'];
+			}
+			inCell.colSpan && html.push(' colspan="', inCell.colSpan, '"');
+			inCell.rowSpan && html.push(' rowspan="', inCell.rowSpan, '"');
+			html.push(' class="dojoxGridCell ');
+			inCell.classes && html.push(inCell.classes, ' ');
+			inMoreClasses && html.push(inMoreClasses, ' ');
+			// result[0] => td opener, style
+			result.push(html.join(''));
+			// SLOT: result[1] => td classes 
+			result.push('');
+			html = ['" idx="', inCell.index, '" style="'];
+			if(inMoreStyles && inMoreStyles[inMoreStyles.length-1] != ';'){
+				inMoreStyles += ';';
+			}
+			html.push(inCell.styles, inMoreStyles||'', inCell.hidden?'display:none;':'');
+			inCell.unitWidth && html.push('width:', inCell.unitWidth, ';');
+			// result[2] => markup
+			result.push(html.join(''));
+			// SLOT: result[3] => td style 
+			result.push('');
+			html = [ '"' ];
+			inCell.attrs && html.push(" ", inCell.attrs);
+			html.push('>');
+			// result[4] => td postfix
+			result.push(html.join(''));
+			// SLOT: result[5] => content
+			result.push('');
+			// result[6] => td closes
+			result.push(isHeader?'</th>':'</td>');
+			return result; // Array
+		},
+
+		// cell finding
+		isCellNode: function(inNode){
+			return Boolean(inNode && inNode!=dojo.doc && dojo.attr(inNode, "idx"));
+		},
+		
+		getCellNodeIndex: function(inCellNode){
+			return inCellNode ? Number(dojo.attr(inCellNode, "idx")) : -1;
+		},
+		
+		getCellNode: function(inRowNode, inCellIndex){
+			for(var i=0, row; row=getTr(inRowNode.firstChild, i); i++){
+				for(var j=0, cell; cell=row.cells[j]; j++){
+					if(this.getCellNodeIndex(cell) == inCellIndex){
+						return cell;
+					}
+				}
+			}
+		},
+		
+		findCellTarget: function(inSourceNode, inTopNode){
+			var n = inSourceNode;
+			while(n && (!this.isCellNode(n) || (n.offsetParent && gridViewTag in n.offsetParent.parentNode && n.offsetParent.parentNode[gridViewTag] != this.view.id)) && (n!=inTopNode)){
+				n = n.parentNode;
+			}
+			return n!=inTopNode ? n : null 
+		},
+		
+		// event decoration
+		baseDecorateEvent: function(e){
+			e.dispatch = 'do' + e.type;
+			e.grid = this.grid;
+			e.sourceView = this.view;
+			e.cellNode = this.findCellTarget(e.target, e.rowNode);
+			e.cellIndex = this.getCellNodeIndex(e.cellNode);
+			e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null);
+		},
+		
+		// event dispatch
+		findTarget: function(inSource, inTag){
+			var n = inSource;
+			while(n && (n!=this.domNode) && (!(inTag in n) || (gridViewTag in n && n[gridViewTag] != this.view.id))){
+				n = n.parentNode;
+			}
+			return (n != this.domNode) ? n : null; 
+		},
+
+		findRowTarget: function(inSource){
+			return this.findTarget(inSource, rowIndexTag);
+		},
+
+		isIntraNodeEvent: function(e){
+			try{
+				return (e.cellNode && e.relatedTarget && dojo.isDescendant(e.relatedTarget, e.cellNode));
+			}catch(x){
+				// e.relatedTarget has permission problem in FF if it's an input: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
+				return false;
+			}
+		},
+
+		isIntraRowEvent: function(e){
+			try{
+				var row = e.relatedTarget && this.findRowTarget(e.relatedTarget);
+				return !row && (e.rowIndex==-1) || row && (e.rowIndex==row.gridRowIndex);			
+			}catch(x){
+				// e.relatedTarget on INPUT has permission problem in FF: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
+				return false;
+			}
+		},
+
+		dispatchEvent: function(e){
+			if(e.dispatch in this){
+				return this[e.dispatch](e);
+			}
+		},
+
+		// dispatched event handlers
+		domouseover: function(e){
+			if(e.cellNode && (e.cellNode!=this.lastOverCellNode)){
+				this.lastOverCellNode = e.cellNode;
+				this.grid.onMouseOver(e);
+			}
+			this.grid.onMouseOverRow(e);
+		},
+
+		domouseout: function(e){
+			if(e.cellNode && (e.cellNode==this.lastOverCellNode) && !this.isIntraNodeEvent(e, this.lastOverCellNode)){
+				this.lastOverCellNode = null;
+				this.grid.onMouseOut(e);
+				if(!this.isIntraRowEvent(e)){
+					this.grid.onMouseOutRow(e);
+				}
+			}
+		},
+		
+		domousedown: function(e){
+			if (e.cellNode)
+				this.grid.onMouseDown(e);
+			this.grid.onMouseDownRow(e)
+		}
+	});
+
+	// Produces html for grid data content. Owned by grid and used internally 
+	// for rendering data. Override to implement custom rendering.
+	dg._ContentBuilder = dojo.extend(function(view){
+		dg._Builder.call(this, view);
+	},dg._Builder.prototype,{
+		update: function(){
+			this.prepareHtml();
+		},
+
+		// cache html for rendering data rows
+		prepareHtml: function(){
+			var defaultGet=this.grid.get, cells=this.view.structure.cells;
+			for(var j=0, row; (row=cells[j]); j++){
+				for(var i=0, cell; (cell=row[i]); i++){
+					cell.get = cell.get || (cell.value == undefined) && defaultGet;
+					cell.markup = this.generateCellMarkup(cell, cell.cellStyles, cell.cellClasses, false);
+				}
+			}
+		},
+
+		// time critical: generate html using cache and data source
+		generateHtml: function(inDataIndex, inRowIndex){
+			var
+				html = this.getTableArray(),
+				v = this.view,
+				cells = v.structure.cells,
+				item = this.grid.getItem(inRowIndex);
+
+			dojox.grid.util.fire(this.view, "onBeforeRow", [inRowIndex, cells]);
+			for(var j=0, row; (row=cells[j]); j++){
+				if(row.hidden || row.header){
+					continue;
+				}
+				html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">');
+				for(var i=0, cell, m, cc, cs; (cell=row[i]); i++){
+					m = cell.markup, cc = cell.customClasses = [], cs = cell.customStyles = [];
+					// content (format can fill in cc and cs as side-effects)
+					m[5] = cell.format(inRowIndex, item);
+					// classes
+					m[1] = cc.join(' ');
+					// styles
+					m[3] = cs.join(';');
+					// in-place concat
+					html.push.apply(html, m);
+				}
+				html.push('</tr>');
+			}
+			html.push('</table>');
+			return html.join(''); // String
+		},
+
+		decorateEvent: function(e){
+			e.rowNode = this.findRowTarget(e.target);
+			if(!e.rowNode){return false};
+			e.rowIndex = e.rowNode[rowIndexTag];
+			this.baseDecorateEvent(e);
+			e.cell = this.grid.getCell(e.cellIndex);
+			return true; // Boolean
+		}
+	});
+
+	// Produces html for grid header content. Owned by grid and used internally 
+	// for rendering data. Override to implement custom rendering.
+	dg._HeaderBuilder = dojo.extend(function(view){
+		this.moveable = null;
+		dg._Builder.call(this, view);
+	},dg._Builder.prototype,{
+		_skipBogusClicks: false,
+		overResizeWidth: 4,
+		minColWidth: 1,
+		
+		update: function(){
+			if(this.tableMap){
+				this.tableMap.mapRows(this.view.structure.cells);
+			}else{
+				this.tableMap = new dg._TableMap(this.view.structure.cells);
+			}
+		},
+
+		generateHtml: function(inGetValue, inValue){
+			var html = this.getTableArray(), cells = this.view.structure.cells;
+			
+			dojox.grid.util.fire(this.view, "onBeforeRow", [-1, cells]);
+			for(var j=0, row; (row=cells[j]); j++){
+				if(row.hidden){
+					continue;
+				}
+				html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">');
+				for(var i=0, cell, markup; (cell=row[i]); i++){
+					cell.customClasses = [];
+					cell.customStyles = [];
+					if(this.view.simpleStructure){
+						if(cell.headerClasses){
+							if(cell.headerClasses.indexOf('dojoDndItem') == -1){
+								cell.headerClasses += ' dojoDndItem';
+							}
+						}else{
+							cell.headerClasses = 'dojoDndItem';
+						}
+						if(cell.attrs){
+							if(cell.attrs.indexOf("dndType='gridColumn_") == -1){
+								cell.attrs += " dndType='gridColumn_" + this.grid.id + "'";
+							}
+						}else{
+							cell.attrs = "dndType='gridColumn_" + this.grid.id + "'";
+						}
+					}
+					markup = this.generateCellMarkup(cell, cell.headerStyles, cell.headerClasses, true);
+					// content
+					markup[5] = (inValue != undefined ? inValue : inGetValue(cell));
+					// styles
+					markup[3] = cell.customStyles.join(';');
+					// classes
+					markup[1] = cell.customClasses.join(' '); //(cell.customClasses ? ' ' + cell.customClasses : '');
+					html.push(markup.join(''));
+				}
+				html.push('</tr>');
+			}
+			html.push('</table>');
+			return html.join('');
+		},
+
+		// event helpers
+		getCellX: function(e){
+			var x = e.layerX;
+			if(dojo.isMoz){
+				var n = ascendDom(e.target, makeNotTagName("th"));
+				x -= (n && n.offsetLeft) || 0;
+				var t = e.sourceView.getScrollbarWidth();
+				if(!dojo._isBodyLtr() && e.sourceView.headerNode.scrollLeft < t)
+					x -= t;
+				//x -= getProp(ascendDom(e.target, mkNotTagName("td")), "offsetLeft") || 0;
+			}
+			var n = ascendDom(e.target, function(){
+				if(!n || n == e.cellNode){
+					return false;
+				}
+				// Mozilla 1.8 (FF 1.5) has a bug that makes offsetLeft = -parent border width
+				// when parent has border, overflow: hidden, and is positioned
+				// handle this problem here ... not a general solution!
+				x += (n.offsetLeft < 0 ? 0 : n.offsetLeft);
+				return true;
+			});
+			return x;
+		},
+
+		// event decoration
+		decorateEvent: function(e){
+			this.baseDecorateEvent(e);
+			e.rowIndex = -1;
+			e.cellX = this.getCellX(e);
+			return true;
+		},
+
+		// event handlers
+		// resizing
+		prepareResize: function(e, mod){
+			do{
+				var i = getTdIndex(e.cellNode);
+				e.cellNode = (i ? e.cellNode.parentNode.cells[i+mod] : null);
+				e.cellIndex = (e.cellNode ? this.getCellNodeIndex(e.cellNode) : -1);
+			}while(e.cellNode && e.cellNode.style.display == "none");
+			return Boolean(e.cellNode);
+		},
+
+		canResize: function(e){
+			if(!e.cellNode || e.cellNode.colSpan > 1){
+				return false;
+			}
+			var cell = this.grid.getCell(e.cellIndex); 
+			return !cell.noresize && cell.canResize();
+		},
+
+		overLeftResizeArea: function(e){
+			//Bugfix for crazy IE problem (#8807).  IE returns position information for the icon and text arrow divs
+			//as if they were still on the left instead of returning the position they were 'float: right' to.
+			//So, the resize check ends up checking the wrong adjacent cell.  This checks to see if the hover was over 
+			//the image or text nodes, then just ignored them/treat them not in scale range.
+			if(dojo.isIE){
+				var tN = e.target;
+				if(dojo.hasClass(tN, "dojoxGridArrowButtonNode") || 
+					dojo.hasClass(tN, "dojoxGridArrowButtonChar")){
+					return false;
+				}
+			}
+
+			if(dojo._isBodyLtr()){
+				return (e.cellIndex>0) && (e.cellX < this.overResizeWidth) && this.prepareResize(e, -1);
+			}
+			var t = e.cellNode && (e.cellX < this.overResizeWidth);
+			return t;
+		},
+
+		overRightResizeArea: function(e){
+			//Bugfix for crazy IE problem (#8807).  IE returns position information for the icon and text arrow divs
+			//as if they were still on the left instead of returning the position they were 'float: right' to.
+			//So, the resize check ends up checking the wrong adjacent cell.  This checks to see if the hover was over 
+			//the image or text nodes, then just ignored them/treat them not in scale range.
+			if(dojo.isIE){
+				var tN = e.target;
+				if(dojo.hasClass(tN, "dojoxGridArrowButtonNode") || 
+					dojo.hasClass(tN, "dojoxGridArrowButtonChar")){
+					return false;
+				}
+			}
+
+			if(dojo._isBodyLtr()){
+				return e.cellNode && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth);
+			}
+			return (e.cellIndex>0) && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth) && this.prepareResize(e, -1);
+		},
+
+		domousemove: function(e){
+			//
+			if(!this.moveable){
+				var c = (this.overRightResizeArea(e) ? 'e-resize' : (this.overLeftResizeArea(e) ? 'w-resize' : ''));
+				if(c && !this.canResize(e)){
+					c = 'not-allowed';
+				}
+				if(dojo.isIE){
+					var t = e.sourceView.headerNode.scrollLeft;
+					e.sourceView.headerNode.style.cursor = c || ''; //'default';
+					e.sourceView.headerNode.scrollLeft = t;
+				}else{
+					e.sourceView.headerNode.style.cursor = c || ''; //'default';
+				}
+				if(c){
+					dojo.stopEvent(e);
+				}
+			}
+		},
+
+		domousedown: function(e){
+			if(!this.moveable){
+				if((this.overRightResizeArea(e) || this.overLeftResizeArea(e)) && this.canResize(e)){
+					this.beginColumnResize(e);
+				}else{
+					this.grid.onMouseDown(e);
+					this.grid.onMouseOverRow(e);
+				}
+				//else{
+				//	this.beginMoveColumn(e);
+				//}
+			}
+		},
+
+		doclick: function(e) {
+			if(this._skipBogusClicks){
+				dojo.stopEvent(e);
+				return true;
+			}
+		},
+
+		// column resizing
+		beginColumnResize: function(e){
+			this.moverDiv = document.createElement("div");
+			dojo.style(this.moverDiv,{position: "absolute", left:0}); // to make DnD work with dir=rtl
+			dojo.body().appendChild(this.moverDiv);
+			var m = this.moveable = new dojo.dnd.Moveable(this.moverDiv);
+
+			var spanners = [], nodes = this.tableMap.findOverlappingNodes(e.cellNode);
+			for(var i=0, cell; (cell=nodes[i]); i++){
+				spanners.push({ node: cell, index: this.getCellNodeIndex(cell), width: cell.offsetWidth });
+				//
+			}
+
+			var view = e.sourceView;
+			var adj = dojo._isBodyLtr() ? 1 : -1;
+			var views = e.grid.views.views;
+			var followers = [];
+			for(var i=view.idx+adj, cView; (cView=views[i]); i=i+adj){
+				followers.push({ node: cView.headerNode, left: window.parseInt(cView.headerNode.style.left) });
+			}
+			var table = view.headerContentNode.firstChild;
+			var drag = {
+				scrollLeft: e.sourceView.headerNode.scrollLeft,
+				view: view,
+				node: e.cellNode,
+				index: e.cellIndex,
+				w: dojo.contentBox(e.cellNode).w,
+				vw: dojo.contentBox(view.headerNode).w,
+				table: table,
+				tw: dojo.contentBox(table).w,
+				spanners: spanners,
+				followers: followers
+			};
+
+			m.onMove = dojo.hitch(this, "doResizeColumn", drag);
+
+			dojo.connect(m, "onMoveStop", dojo.hitch(this, function(){
+				this.endResizeColumn(drag);
+				if(drag.node.releaseCapture){
+					drag.node.releaseCapture();
+				}
+				this.moveable.destroy();
+				delete this.moveable;
+				this.moveable = null;
+			}));
+
+			view.convertColPctToFixed();
+
+			if(e.cellNode.setCapture){
+				e.cellNode.setCapture();
+			}
+			m.onMouseDown(e);
+		},
+
+		doResizeColumn: function(inDrag, mover, leftTop){
+			var isLtr = dojo._isBodyLtr();
+			var deltaX = isLtr ? leftTop.l : -leftTop.l;
+			var w = inDrag.w + deltaX;
+			var vw = inDrag.vw + deltaX;
+			var tw = inDrag.tw + deltaX;
+			if(w >= this.minColWidth){
+				for(var i=0, s, sw; (s=inDrag.spanners[i]); i++){
+					sw = s.width + deltaX;
+					s.node.style.width = sw + 'px';
+					inDrag.view.setColWidth(s.index, sw);
+					//
+				}
+				for(var i=0, f, fl; (f=inDrag.followers[i]); i++){
+					fl = f.left + deltaX;
+					f.node.style.left = fl + 'px';
+				}
+				inDrag.node.style.width = w + 'px';
+				inDrag.view.setColWidth(inDrag.index, w);
+				inDrag.view.headerNode.style.width = vw + 'px';
+				inDrag.view.setColumnsWidth(tw);
+				if(!isLtr){
+					inDrag.view.headerNode.scrollLeft = inDrag.scrollLeft + deltaX;
+				}
+			}
+			if(inDrag.view.flexCells && !inDrag.view.testFlexCells()){
+				var t = findTable(inDrag.node);
+				t && (t.style.width = '');
+			}
+		},
+
+		endResizeColumn: function(inDrag){
+			dojo.destroy(this.moverDiv);
+			delete this.moverDiv;
+			this._skipBogusClicks = true;
+			var conn = dojo.connect(inDrag.view, "update", this, function(){
+				dojo.disconnect(conn);
+				this._skipBogusClicks = false;
+			});
+			setTimeout(dojo.hitch(inDrag.view, "update"), 50);
+		}
+	});
+
+	// Maps an html table into a structure parsable for information about cell row and col spanning.
+	// Used by HeaderBuilder.
+	dg._TableMap = dojo.extend(function(rows){
+		this.mapRows(rows);
+	},{
+		map: null,
+
+		mapRows: function(inRows){
+			// summary: Map table topography
+
+			//
+			// # of rows
+			var rowCount = inRows.length;
+			if(!rowCount){
+				return;
+			}
+			// map which columns and rows fill which cells
+			this.map = [];
+			for(var j=0, row; (row=inRows[j]); j++){
+				this.map[j] = [];
+			}
+			for(var j=0, row; (row=inRows[j]); j++){
+				for(var i=0, x=0, cell, colSpan, rowSpan; (cell=row[i]); i++){
+					while (this.map[j][x]){x++};
+					this.map[j][x] = { c: i, r: j };
+					rowSpan = cell.rowSpan || 1;
+					colSpan = cell.colSpan || 1;
+					for(var y=0; y<rowSpan; y++){
+						for(var s=0; s<colSpan; s++){
+							this.map[j+y][x+s] = this.map[j][x];
+						}
+					}
+					x += colSpan;
+				}
+			}
+			//this.dumMap();
+		},
+
+		dumpMap: function(){
+			for(var j=0, row, h=''; (row=this.map[j]); j++,h=''){
+				for(var i=0, cell; (cell=row[i]); i++){
+					h += cell.r + ',' + cell.c + '   ';
+				}
+				//
+			}
+		},
+
+		getMapCoords: function(inRow, inCol){
+			// summary: Find node's map coords by it's structure coords
+			for(var j=0, row; (row=this.map[j]); j++){
+				for(var i=0, cell; (cell=row[i]); i++){
+					if(cell.c==inCol && cell.r == inRow){
+						return { j: j, i: i };
+					}
+					//else{ };
+				}
+			}
+			return { j: -1, i: -1 };
+		},
+		
+		getNode: function(inTable, inRow, inCol){
+			// summary: Find a node in inNode's table with the given structure coords
+			var row = inTable && inTable.rows[inRow];
+			return row && row.cells[inCol];
+		},
+		
+		_findOverlappingNodes: function(inTable, inRow, inCol){
+			var nodes = [];
+			var m = this.getMapCoords(inRow, inCol);
+			//
+			var row = this.map[m.j];
+			for(var j=0, row; (row=this.map[j]); j++){
+				if(j == m.j){ continue; }
+				var rw = row[m.i];
+				//
+				var n = (rw?this.getNode(inTable, rw.r, rw.c):null);
+				if(n){ nodes.push(n); }
+			}
+			//
+			return nodes;
+		},
+		
+		findOverlappingNodes: function(inNode){
+			return this._findOverlappingNodes(findTable(inNode), getTrIndex(inNode.parentNode), getTdIndex(inNode));
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Container"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Container"] = true;
+dojo.provide("dojo.dnd.Container");
+
+
+
+
+/*
+	Container states:
+		""		- normal state
+		"Over"	- mouse over a container
+	Container item states:
+		""		- normal state
+		"Over"	- mouse over a container item
+*/
+
+dojo.declare("dojo.dnd.Container", null, {
+	// summary: a Container object, which knows when mouse hovers over it, 
+	//	and over which element it hovers
+	
+	// object attributes (for markup)
+	skipForm: false,
+	
+	constructor: function(node, params){
+		// summary: a constructor of the Container
+		// node: Node: node or node's id to build the container on
+		// params: Object: a dict of parameters, recognized parameters are:
+		//	creator: Function: a creator function, which takes a data item, and returns an object like that:
+		//		{node: newNode, data: usedData, type: arrayOfStrings}
+		//	skipForm: Boolean: don't start the drag operation, if clicked on form elements
+		//	dropParent: Node: node or node's id to use as the parent node for dropped items
+		//		(must be underneath the 'node' parameter in the DOM)
+		//	_skipStartup: Boolean: skip startup(), which collects children, for deferred initialization
+		//		(this is used in the markup mode)
+		this.node = dojo.byId(node);
+		if(!params){ params = {}; }
+		this.creator = params.creator || null;
+		this.skipForm = params.skipForm;
+		this.parent = params.dropParent && dojo.byId(params.dropParent);
+		
+		// class-specific variables
+		this.map = {};
+		this.current = null;
+
+		// states
+		this.containerState = "";
+		dojo.addClass(this.node, "dojoDndContainer");
+		
+		// mark up children
+		if(!(params && params._skipStartup)){
+			this.startup();
+		}
+
+		// set up events
+		this.events = [
+			dojo.connect(this.node, "onmouseover", this, "onMouseOver"),
+			dojo.connect(this.node, "onmouseout",  this, "onMouseOut"),
+			// cancel text selection and text dragging
+			dojo.connect(this.node, "ondragstart",   this, "onSelectStart"),
+			dojo.connect(this.node, "onselectstart", this, "onSelectStart")
+		];
+	},
+	
+	// object attributes (for markup)
+	creator: function(){},	// creator function, dummy at the moment
+	
+	// abstract access to the map
+	getItem: function(/*String*/ key){
+		// summary: returns a data item by its key (id)
+		return this.map[key];	// Object
+	},
+	setItem: function(/*String*/ key, /*Object*/ data){
+		// summary: associates a data item with its key (id)
+		this.map[key] = data;
+	},
+	delItem: function(/*String*/ key){
+		// summary: removes a data item from the map by its key (id)
+		delete this.map[key];
+	},
+	forInItems: function(/*Function*/ f, /*Object?*/ o){
+		// summary: iterates over a data map skipping members, which 
+		//	are present in the empty object (IE and/or 3rd-party libraries).
+		o = o || dojo.global;
+		var m = this.map, e = dojo.dnd._empty;
+		for(var i in m){
+			if(i in e){ continue; }
+			f.call(o, m[i], i, this);
+		}
+		return o;	// Object
+	},
+	clearItems: function(){
+		// summary: removes all data items from the map
+		this.map = {};
+	},
+	
+	// methods
+	getAllNodes: function(){
+		// summary: returns a list (an array) of all valid child nodes
+		return dojo.query("> .dojoDndItem", this.parent);	// NodeList
+	},
+	sync: function(){
+		// summary: synch up the node list with the data map
+		var map = {};
+		this.getAllNodes().forEach(function(node){
+			if(node.id){
+				var item = this.getItem(node.id);
+				if(item){
+					map[node.id] = item;
+					return;
+				}
+			}else{
+				node.id = dojo.dnd.getUniqueId();
+			}
+			var type = node.getAttribute("dndType"),
+				data = node.getAttribute("dndData");
+			map[node.id] = {
+				data: data || node.innerHTML,
+				type: type ? type.split(/\s*,\s*/) : ["text"]
+			};
+		}, this);
+		this.map = map;
+		return this;	// self
+	},
+	insertNodes: function(data, before, anchor){
+		// summary: inserts an array of new nodes before/after an anchor node
+		// data: Array: a list of data items, which should be processed by the creator function
+		// before: Boolean: insert before the anchor, if true, and after the anchor otherwise
+		// anchor: Node: the anchor node to be used as a point of insertion
+		if(!this.parent.firstChild){
+			anchor = null;
+		}else if(before){
+			if(!anchor){
+				anchor = this.parent.firstChild;
+			}
+		}else{
+			if(anchor){
+				anchor = anchor.nextSibling;
+			}
+		}
+		if(anchor){
+			for(var i = 0; i < data.length; ++i){
+				var t = this._normalizedCreator(data[i]);
+				this.setItem(t.node.id, {data: t.data, type: t.type});
+				this.parent.insertBefore(t.node, anchor);
+			}
+		}else{
+			for(var i = 0; i < data.length; ++i){
+				var t = this._normalizedCreator(data[i]);
+				this.setItem(t.node.id, {data: t.data, type: t.type});
+				this.parent.appendChild(t.node);
+			}
+		}
+		return this;	// self
+	},
+	destroy: function(){
+		// summary: prepares the object to be garbage-collected
+		dojo.forEach(this.events, dojo.disconnect);
+		this.clearItems();
+		this.node = this.parent = this.current = null;
+	},
+
+	// markup methods
+	markupFactory: function(params, node){
+		params._skipStartup = true;
+		return new dojo.dnd.Container(node, params);
+	},
+	startup: function(){
+		// summary: collects valid child items and populate the map
+		
+		// set up the real parent node
+		if(!this.parent){
+			// use the standard algorithm, if not assigned
+			this.parent = this.node;
+			if(this.parent.tagName.toLowerCase() == "table"){
+				var c = this.parent.getElementsByTagName("tbody");
+				if(c && c.length){ this.parent = c[0]; }
+			}
+		}
+		this.defaultCreator = dojo.dnd._defaultCreator(this.parent);
+
+		// process specially marked children
+		this.sync();
+	},
+
+	// mouse events
+	onMouseOver: function(e){
+		// summary: event processor for onmouseover
+		// e: Event: mouse event
+		var n = e.relatedTarget;
+		while(n){
+			if(n == this.node){ break; }
+			try{
+				n = n.parentNode;
+			}catch(x){
+				n = null;
+			}
+		}
+		if(!n){
+			this._changeState("Container", "Over");
+			this.onOverEvent();
+		}
+		n = this._getChildByEvent(e);
+		if(this.current == n){ return; }
+		if(this.current){ this._removeItemClass(this.current, "Over"); }
+		if(n){ this._addItemClass(n, "Over"); }
+		this.current = n;
+	},
+	onMouseOut: function(e){
+		// summary: event processor for onmouseout
+		// e: Event: mouse event
+		for(var n = e.relatedTarget; n;){
+			if(n == this.node){ return; }
+			try{
+				n = n.parentNode;
+			}catch(x){
+				n = null;
+			}
+		}
+		if(this.current){
+			this._removeItemClass(this.current, "Over");
+			this.current = null;
+		}
+		this._changeState("Container", "");
+		this.onOutEvent();
+	},
+	onSelectStart: function(e){
+		// summary: event processor for onselectevent and ondragevent
+		// e: Event: mouse event
+		if(!this.skipForm || !dojo.dnd.isFormElement(e)){
+			dojo.stopEvent(e);
+		}
+	},
+	
+	// utilities
+	onOverEvent: function(){
+		// summary: this function is called once, when mouse is over our container
+	},
+	onOutEvent: function(){
+		// summary: this function is called once, when mouse is out of our container
+	},
+	_changeState: function(type, newState){
+		// summary: changes a named state to new state value
+		// type: String: a name of the state to change
+		// newState: String: new state
+		var prefix = "dojoDnd" + type;
+		var state  = type.toLowerCase() + "State";
+		//dojo.replaceClass(this.node, prefix + newState, prefix + this[state]);
+		dojo.removeClass(this.node, prefix + this[state]);
+		dojo.addClass(this.node, prefix + newState);
+		this[state] = newState;
+	},
+	_addItemClass: function(node, type){
+		// summary: adds a class with prefix "dojoDndItem"
+		// node: Node: a node
+		// type: String: a variable suffix for a class name
+		dojo.addClass(node, "dojoDndItem" + type);
+	},
+	_removeItemClass: function(node, type){
+		// summary: removes a class with prefix "dojoDndItem"
+		// node: Node: a node
+		// type: String: a variable suffix for a class name
+		dojo.removeClass(node, "dojoDndItem" + type);
+	},
+	_getChildByEvent: function(e){
+		// summary: gets a child, which is under the mouse at the moment, or null
+		// e: Event: a mouse event
+		var node = e.target;
+		if(node){
+			for(var parent = node.parentNode; parent; node = parent, parent = node.parentNode){
+				if(parent == this.parent && dojo.hasClass(node, "dojoDndItem")){ return node; }
+			}
+		}
+		return null;
+	},
+	_normalizedCreator: function(item, hint){
+		// summary: adds all necessary data to the output of the user-supplied creator function
+		var t = (this.creator || this.defaultCreator).call(this, item, hint);
+		if(!dojo.isArray(t.type)){ t.type = ["text"]; }
+		if(!t.node.id){ t.node.id = dojo.dnd.getUniqueId(); }
+		dojo.addClass(t.node, "dojoDndItem");
+		return t;
+	}
+});
+
+dojo.dnd._createNode = function(tag){
+	// summary: returns a function, which creates an element of given tag 
+	//	(SPAN by default) and sets its innerHTML to given text
+	// tag: String: a tag name or empty for SPAN
+	if(!tag){ return dojo.dnd._createSpan; }
+	return function(text){	// Function
+		return dojo.create(tag, {innerHTML: text});	// Node
+	};
+};
+
+dojo.dnd._createTrTd = function(text){
+	// summary: creates a TR/TD structure with given text as an innerHTML of TD
+	// text: String: a text for TD
+	var tr = dojo.create("tr");
+	dojo.create("td", {innerHTML: text}, tr);
+	return tr;	// Node
+};
+
+dojo.dnd._createSpan = function(text){
+	// summary: creates a SPAN element with given text as its innerHTML
+	// text: String: a text for SPAN
+	return dojo.create("span", {innerHTML: text});	// Node
+};
+
+// dojo.dnd._defaultCreatorNodes: Object: a dicitionary, which maps container tag names to child tag names
+dojo.dnd._defaultCreatorNodes = {ul: "li", ol: "li", div: "div", p: "div"};
+
+dojo.dnd._defaultCreator = function(node){
+	// summary: takes a parent node, and returns an appropriate creator function
+	// node: Node: a container node
+	var tag = node.tagName.toLowerCase();
+	var c = tag == "tbody" || tag == "thead" ? dojo.dnd._createTrTd :
+			dojo.dnd._createNode(dojo.dnd._defaultCreatorNodes[tag]);
+	return function(item, hint){	// Function
+		var isObj = item && dojo.isObject(item), data, type, n;
+		if(isObj && item.tagName && item.nodeType && item.getAttribute){
+			// process a DOM node
+			data = item.getAttribute("dndData") || item.innerHTML;
+			type = item.getAttribute("dndType");
+			type = type ? type.split(/\s*,\s*/) : ["text"];
+			n = item;	// this node is going to be moved rather than copied
+		}else{
+			// process a DnD item object or a string
+			data = (isObj && item.data) ? item.data : item;
+			type = (isObj && item.type) ? item.type : ["text"];
+			n = (hint == "avatar" ? dojo.dnd._createSpan : c)(String(data));
+		}
+		n.id = dojo.dnd.getUniqueId();
+		return {node: n, data: data, type: type};
+	};
+};
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Selector"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Selector"] = true;
+dojo.provide("dojo.dnd.Selector");
+
+
+
+
+/*
+	Container item states:
+		""			- an item is not selected
+		"Selected"	- an item is selected
+		"Anchor"	- an item is selected, and is an anchor for a "shift" selection
+*/
+
+dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
+	// summary: a Selector object, which knows how to select its children
+	
+	constructor: function(node, params){
+		// summary: a constructor of the Selector
+		// node: Node: node or node's id to build the selector on
+		// params: Object: a dict of parameters, recognized parameters are:
+		//	singular: Boolean
+		//		allows selection of only one element, if true
+		//		the rest of parameters are passed to the container
+		//	autoSync: Boolean
+		//		autosynchronizes the source with its list of DnD nodes,
+		//		false by default
+		if(!params){ params = {}; }
+		this.singular = params.singular;
+		this.autoSync = params.autoSync;
+		// class-specific variables
+		this.selection = {};
+		this.anchor = null;
+		this.simpleSelection = false;
+		// set up events
+		this.events.push(
+			dojo.connect(this.node, "onmousedown", this, "onMouseDown"),
+			dojo.connect(this.node, "onmouseup",   this, "onMouseUp"));
+	},
+	
+	// object attributes (for markup)
+	singular: false,	// is singular property
+	
+	// methods
+	getSelectedNodes: function(){
+		// summary: returns a list (an array) of selected nodes
+		var t = new dojo.NodeList();
+		var e = dojo.dnd._empty;
+		for(var i in this.selection){
+			if(i in e){ continue; }
+			t.push(dojo.byId(i));
+		}
+		return t;	// Array
+	},
+	selectNone: function(){
+		// summary: unselects all items
+		return this._removeSelection()._removeAnchor();	// self
+	},
+	selectAll: function(){
+		// summary: selects all items
+		this.forInItems(function(data, id){
+			this._addItemClass(dojo.byId(id), "Selected");
+			this.selection[id] = 1;
+		}, this);
+		return this._removeAnchor();	// self
+	},
+	deleteSelectedNodes: function(){
+		// summary: deletes all selected items
+		var e = dojo.dnd._empty;
+		for(var i in this.selection){
+			if(i in e){ continue; }
+			var n = dojo.byId(i);
+			this.delItem(i);
+			dojo.destroy(n);
+		}
+		this.anchor = null;
+		this.selection = {};
+		return this;	// self
+	},
+	forInSelectedItems: function(/*Function*/ f, /*Object?*/ o){
+		// summary: iterates over selected items,
+		// see dojo.dnd.Container.forInItems() for details
+		o = o || dojo.global;
+		var s = this.selection, e = dojo.dnd._empty;
+		for(var i in s){
+			if(i in e){ continue; }
+			f.call(o, this.getItem(i), i, this);
+		}
+	},
+	sync: function(){
+		// summary: synch up the node list with the data map
+		
+		dojo.dnd.Selector.superclass.sync.call(this);
+		
+		// fix the anchor
+		if(this.anchor){
+			if(!this.getItem(this.anchor.id)){
+				this.anchor = null;
+			}
+		}
+		
+		// fix the selection
+		var t = [], e = dojo.dnd._empty;
+		for(var i in this.selection){
+			if(i in e){ continue; }
+			if(!this.getItem(i)){
+				t.push(i);
+			}
+		}
+		dojo.forEach(t, function(i){
+			delete this.selection[i];
+		}, this);
+		
+		return this;	// self
+	},
+	insertNodes: function(addSelected, data, before, anchor){
+		// summary: inserts new data items (see Container's insertNodes method for details)
+		// addSelected: Boolean: all new nodes will be added to selected items, if true, no selection change otherwise
+		// data: Array: a list of data items, which should be processed by the creator function
+		// before: Boolean: insert before the anchor, if true, and after the anchor otherwise
+		// anchor: Node: the anchor node to be used as a point of insertion
+		var oldCreator = this._normalizedCreator;
+		this._normalizedCreator = function(item, hint){
+			var t = oldCreator.call(this, item, hint);
+			if(addSelected){
+				if(!this.anchor){
+					this.anchor = t.node;
+					this._removeItemClass(t.node, "Selected");
+					this._addItemClass(this.anchor, "Anchor");
+				}else if(this.anchor != t.node){
+					this._removeItemClass(t.node, "Anchor");
+					this._addItemClass(t.node, "Selected");
+				}
+				this.selection[t.node.id] = 1;
+			}else{
+				this._removeItemClass(t.node, "Selected");
+				this._removeItemClass(t.node, "Anchor");
+			}
+			return t;
+		};
+		dojo.dnd.Selector.superclass.insertNodes.call(this, data, before, anchor);
+		this._normalizedCreator = oldCreator;
+		return this;	// self
+	},
+	destroy: function(){
+		// summary: prepares the object to be garbage-collected
+		dojo.dnd.Selector.superclass.destroy.call(this);
+		this.selection = this.anchor = null;
+	},
+
+	// markup methods
+	markupFactory: function(params, node){
+		params._skipStartup = true;
+		return new dojo.dnd.Selector(node, params);
+	},
+
+	// mouse events
+	onMouseDown: function(e){
+		// summary: event processor for onmousedown
+		// e: Event: mouse event
+		if(this.autoSync){ this.sync(); }
+		if(!this.current){ return; }
+		if(!this.singular && !dojo.dnd.getCopyKeyState(e) && !e.shiftKey && (this.current.id in this.selection)){
+			this.simpleSelection = true;
+			if(e.button === dojo.dnd._lmb){
+				// accept the left button and stop the event
+				// for IE we don't stop event when multiple buttons are pressed
+				dojo.stopEvent(e);
+			}
+			return;
+		}
+		if(!this.singular && e.shiftKey){
+			if(!dojo.dnd.getCopyKeyState(e)){
+				this._removeSelection();
+			}
+			var c = this.getAllNodes();
+			if(c.length){
+				if(!this.anchor){
+					this.anchor = c[0];
+					this._addItemClass(this.anchor, "Anchor");
+				}
+				this.selection[this.anchor.id] = 1;
+				if(this.anchor != this.current){
+					var i = 0;
+					for(; i < c.length; ++i){
+						var node = c[i];
+						if(node == this.anchor || node == this.current){ break; }
+					}
+					for(++i; i < c.length; ++i){
+						var node = c[i];
+						if(node == this.anchor || node == this.current){ break; }
+						this._addItemClass(node, "Selected");
+						this.selection[node.id] = 1;
+					}
+					this._addItemClass(this.current, "Selected");
+					this.selection[this.current.id] = 1;
+				}
+			}
+		}else{
+			if(this.singular){
+				if(this.anchor == this.current){
+					if(dojo.dnd.getCopyKeyState(e)){
+						this.selectNone();
+					}
+				}else{
+					this.selectNone();
+					this.anchor = this.current;
+					this._addItemClass(this.anchor, "Anchor");
+					this.selection[this.current.id] = 1;
+				}
+			}else{
+				if(dojo.dnd.getCopyKeyState(e)){
+					if(this.anchor == this.current){
+						delete this.selection[this.anchor.id];
+						this._removeAnchor();
+					}else{
+						if(this.current.id in this.selection){
+							this._removeItemClass(this.current, "Selected");
+							delete this.selection[this.current.id];
+						}else{
+							if(this.anchor){
+								this._removeItemClass(this.anchor, "Anchor");
+								this._addItemClass(this.anchor, "Selected");
+							}
+							this.anchor = this.current;
+							this._addItemClass(this.current, "Anchor");
+							this.selection[this.current.id] = 1;
+						}
+					}
+				}else{
+					if(!(this.current.id in this.selection)){
+						this.selectNone();
+						this.anchor = this.current;
+						this._addItemClass(this.current, "Anchor");
+						this.selection[this.current.id] = 1;
+					}
+				}
+			}
+		}
+		dojo.stopEvent(e);
+	},
+	onMouseUp: function(e){
+		// summary: event processor for onmouseup
+		// e: Event: mouse event
+		if(!this.simpleSelection){ return; }
+		this.simpleSelection = false;
+		this.selectNone();
+		if(this.current){
+			this.anchor = this.current;
+			this._addItemClass(this.anchor, "Anchor");
+			this.selection[this.current.id] = 1;
+		}
+	},
+	onMouseMove: function(e){
+		// summary: event processor for onmousemove
+		// e: Event: mouse event
+		this.simpleSelection = false;
+	},
+	
+	// utilities
+	onOverEvent: function(){
+		// summary: this function is called once, when mouse is over our container
+		this.onmousemoveEvent = dojo.connect(this.node, "onmousemove", this, "onMouseMove");
+	},
+	onOutEvent: function(){
+		// summary: this function is called once, when mouse is out of our container
+		dojo.disconnect(this.onmousemoveEvent);
+		delete this.onmousemoveEvent;
+	},
+	_removeSelection: function(){
+		// summary: unselects all items
+		var e = dojo.dnd._empty;
+		for(var i in this.selection){
+			if(i in e){ continue; }
+			var node = dojo.byId(i);
+			if(node){ this._removeItemClass(node, "Selected"); }
+		}
+		this.selection = {};
+		return this;	// self
+	},
+	_removeAnchor: function(){
+		if(this.anchor){
+			this._removeItemClass(this.anchor, "Anchor");
+			this.anchor = null;
+		}
+		return this;	// self
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Avatar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Avatar"] = true;
+dojo.provide("dojo.dnd.Avatar");
+
+
+
+dojo.declare("dojo.dnd.Avatar", null, {
+	// summary: an object, which represents transferred DnD items visually
+	// manager: Object: a DnD manager object
+
+	constructor: function(manager){
+		this.manager = manager;
+		this.construct();
+	},
+
+	// methods
+	construct: function(){
+		// summary: a constructor function;
+		//	it is separate so it can be (dynamically) overwritten in case of need
+		var a = dojo.create("table", {
+				"class": "dojoDndAvatar",
+				style: {
+					position: "absolute",
+					zIndex:   "1999",
+					margin:   "0px"
+				}
+			}),
+			b = dojo.create("tbody", null, a),
+			tr = dojo.create("tr", null, b),
+			td = dojo.create("td", {
+				innerHTML: this._generateText()
+			}, tr),
+			k = Math.min(5, this.manager.nodes.length), i = 0,
+			source = this.manager.source, node;
+		// we have to set the opacity on IE only after the node is live
+		dojo.attr(tr, {
+			"class": "dojoDndAvatarHeader",
+			style: {opacity: 0.9}
+		});
+		for(; i < k; ++i){
+			if(source.creator){
+				// create an avatar representation of the node
+				node = source._normalizedCreator(source.getItem(this.manager.nodes[i].id).data, "avatar").node;
+			}else{
+				// or just clone the node and hope it works
+				node = this.manager.nodes[i].cloneNode(true);
+				if(node.tagName.toLowerCase() == "tr"){
+					// insert extra table nodes
+					var table = dojo.create("table"),
+						tbody = dojo.create("tbody", null, table);
+					tbody.appendChild(node);
+					node = table;
+				}
+			}
+			node.id = "";
+			tr = dojo.create("tr", null, b);
+			td = dojo.create("td", null, tr);
+			td.appendChild(node);
+			dojo.attr(tr, {
+				"class": "dojoDndAvatarItem",
+				style: {opacity: (9 - i) / 10}
+			});
+		}
+		this.node = a;
+	},
+	destroy: function(){
+		// summary: a desctructor for the avatar, called to remove all references so it can be garbage-collected
+		dojo.destroy(this.node);
+		this.node = false;
+	},
+	update: function(){
+		// summary: updates the avatar to reflect the current DnD state
+		dojo[(this.manager.canDropFlag ? "add" : "remove") + "Class"](this.node, "dojoDndAvatarCanDrop");
+		// replace text
+		dojo.query("tr.dojoDndAvatarHeader td", this.node).forEach(function(node){
+			node.innerHTML = this._generateText();
+		}, this);
+	},
+	_generateText: function(){
+		// summary: generates a proper text to reflect copying or moving of items
+		return this.manager.nodes.length.toString();
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Manager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Manager"] = true;
+dojo.provide("dojo.dnd.Manager");
+
+
+
+
+
+dojo.declare("dojo.dnd.Manager", null, {
+	// summary: the manager of DnD operations (usually a singleton)
+	constructor: function(){
+		this.avatar  = null;
+		this.source = null;
+		this.nodes = [];
+		this.copy  = true;
+		this.target = null;
+		this.canDropFlag = false;
+		this.events = [];
+	},
+
+	// avatar's offset from the mouse
+	OFFSET_X: 16,
+	OFFSET_Y: 16,
+	
+	// methods
+	overSource: function(source){
+		// summary: called when a source detected a mouse-over conditiion
+		// source: Object: the reporter
+		if(this.avatar){
+			this.target = (source && source.targetState != "Disabled") ? source : null;
+			this.canDropFlag = Boolean(this.target);
+			this.avatar.update();
+		}
+		dojo.publish("/dnd/source/over", [source]);
+	},
+	outSource: function(source){
+		// summary: called when a source detected a mouse-out conditiion
+		// source: Object: the reporter
+		if(this.avatar){
+			if(this.target == source){
+				this.target = null;
+				this.canDropFlag = false;
+				this.avatar.update();
+				dojo.publish("/dnd/source/over", [null]);
+			}
+		}else{
+			dojo.publish("/dnd/source/over", [null]);
+		}
+	},
+	startDrag: function(source, nodes, copy){
+		// summary: called to initiate the DnD operation
+		// source: Object: the source which provides items
+		// nodes: Array: the list of transferred items
+		// copy: Boolean: copy items, if true, move items otherwise
+		this.source = source;
+		this.nodes  = nodes;
+		this.copy   = Boolean(copy); // normalizing to true boolean
+		this.avatar = this.makeAvatar();
+		dojo.body().appendChild(this.avatar.node);
+		dojo.publish("/dnd/start", [source, nodes, this.copy]);
+		this.events = [
+			dojo.connect(dojo.doc, "onmousemove", this, "onMouseMove"),
+			dojo.connect(dojo.doc, "onmouseup",   this, "onMouseUp"),
+			dojo.connect(dojo.doc, "onkeydown",   this, "onKeyDown"),
+			dojo.connect(dojo.doc, "onkeyup",     this, "onKeyUp"),
+			// cancel text selection and text dragging
+			dojo.connect(dojo.doc, "ondragstart",   dojo.stopEvent),
+			dojo.connect(dojo.body(), "onselectstart", dojo.stopEvent)
+		];
+		var c = "dojoDnd" + (copy ? "Copy" : "Move");
+		dojo.addClass(dojo.body(), c); 
+	},
+	canDrop: function(flag){
+		// summary: called to notify if the current target can accept items
+		var canDropFlag = Boolean(this.target && flag);
+		if(this.canDropFlag != canDropFlag){
+			this.canDropFlag = canDropFlag;
+			this.avatar.update();
+		}
+	},
+	stopDrag: function(){
+		// summary: stop the DnD in progress
+		dojo.removeClass(dojo.body(), "dojoDndCopy");
+		dojo.removeClass(dojo.body(), "dojoDndMove");
+		dojo.forEach(this.events, dojo.disconnect);
+		this.events = [];
+		this.avatar.destroy();
+		this.avatar = null;
+		this.source = this.target = null;
+		this.nodes = [];
+	},
+	makeAvatar: function(){
+		// summary: makes the avatar, it is separate to be overwritten dynamically, if needed
+		return new dojo.dnd.Avatar(this);
+	},
+	updateAvatar: function(){
+		// summary: updates the avatar, it is separate to be overwritten dynamically, if needed
+		this.avatar.update();
+	},
+	
+	// mouse event processors
+	onMouseMove: function(e){
+		// summary: event processor for onmousemove
+		// e: Event: mouse event
+		var a = this.avatar;
+		if(a){
+			dojo.dnd.autoScrollNodes(e);
+			//dojo.dnd.autoScroll(e);
+			var s = a.node.style;
+			s.left = (e.pageX + this.OFFSET_X) + "px";
+			s.top  = (e.pageY + this.OFFSET_Y) + "px";
+			var copy = Boolean(this.source.copyState(dojo.dnd.getCopyKeyState(e)));
+			if(this.copy != copy){ 
+				this._setCopyStatus(copy);
+			}
+		}
+	},
+	onMouseUp: function(e){
+		// summary: event processor for onmouseup
+		// e: Event: mouse event
+		if(this.avatar){
+			if(this.target && this.canDropFlag){
+				var copy = Boolean(this.source.copyState(dojo.dnd.getCopyKeyState(e))),
+				params = [this.source, this.nodes, copy, this.target];
+				dojo.publish("/dnd/drop/before", params);
+				dojo.publish("/dnd/drop", params);
+			}else{
+				dojo.publish("/dnd/cancel");
+			}
+			this.stopDrag();
+		}
+	},
+	
+	// keyboard event processors
+	onKeyDown: function(e){
+		// summary: event processor for onkeydown:
+		//	watching for CTRL for copy/move status, watching for ESCAPE to cancel the drag
+		// e: Event: keyboard event
+		if(this.avatar){
+			switch(e.keyCode){
+				case dojo.keys.CTRL:
+					var copy = Boolean(this.source.copyState(true));
+					if(this.copy != copy){ 
+						this._setCopyStatus(copy);
+					}
+					break;
+				case dojo.keys.ESCAPE:
+					dojo.publish("/dnd/cancel");
+					this.stopDrag();
+					break;
+			}
+		}
+	},
+	onKeyUp: function(e){
+		// summary: event processor for onkeyup, watching for CTRL for copy/move status
+		// e: Event: keyboard event
+		if(this.avatar && e.keyCode == dojo.keys.CTRL){
+			var copy = Boolean(this.source.copyState(false));
+			if(this.copy != copy){ 
+				this._setCopyStatus(copy);
+			}
+		}
+	},
+	
+	// utilities
+	_setCopyStatus: function(copy){
+		// summary: changes the copy status
+		// copy: Boolean: the copy status
+		this.copy = copy;
+		this.source._markDndStatus(this.copy);
+		this.updateAvatar();
+		dojo.removeClass(dojo.body(), "dojoDnd" + (this.copy ? "Move" : "Copy"));
+		dojo.addClass(dojo.body(), "dojoDnd" + (this.copy ? "Copy" : "Move"));
+	}
+});
+
+// summary: the manager singleton variable, can be overwritten, if needed
+dojo.dnd._manager = null;
+
+dojo.dnd.manager = function(){
+	// summary: returns the current DnD manager, creates one if it is not created yet
+	if(!dojo.dnd._manager){
+		dojo.dnd._manager = new dojo.dnd.Manager();
+	}
+	return dojo.dnd._manager;	// Object
+};
+
+}
+
+if(!dojo._hasResource["dojo.dnd.Source"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.dnd.Source"] = true;
+dojo.provide("dojo.dnd.Source");
+
+
+
+
+/*
+	Container property:
+		"Horizontal"- if this is the horizontal container
+	Source states:
+		""			- normal state
+		"Moved"		- this source is being moved
+		"Copied"	- this source is being copied
+	Target states:
+		""			- normal state
+		"Disabled"	- the target cannot accept an avatar
+	Target anchor state:
+		""			- item is not selected
+		"Before"	- insert point is before the anchor
+		"After"		- insert point is after the anchor
+*/
+
+/*=====
+dojo.dnd.__SourceArgs = function(){
+	//	summary:
+	//		a dict of parameters for DnD Source configuration. Note that any
+	//		property on Source elements may be configured, but this is the
+	//		short-list
+	//	isSource: Boolean?
+	//		can be used as a DnD source. Defaults to true.
+	//	accept: Array?
+	//		list of accepted types (text strings) for a target; defaults to
+	//		["text"]
+	//	autoSync: Boolean
+	//		if true refreshes the node list on every operation; false by default
+	//	copyOnly: Boolean?
+	//		copy items, if true, use a state of Ctrl key otherwise,
+	//		see selfCopy and selfAccept for more details
+	//	delay: Number
+	//		the move delay in pixels before detecting a drag; 0 by default
+	//	horizontal: Boolean?
+	//		a horizontal container, if true, vertical otherwise or when omitted
+	//	selfCopy: Boolean?
+	//		copy items by default when dropping on itself,
+	//		false by default, works only if copyOnly is true
+	//	selfAccept: Boolean?
+	//		accept its own items when copyOnly is true,
+	//		true by default, works only if copyOnly is true
+	//	withHandles: Boolean?
+	//		allows dragging only by handles, false by default
+	this.isSource = isSource;
+	this.accept = accept;
+	this.autoSync = autoSync;
+	this.copyOnly = copyOnly;
+	this.delay = delay;
+	this.horizontal = horizontal;
+	this.selfCopy = selfCopy;
+	this.selfAccept = selfAccept;
+	this.withHandles = withHandles;
+}
+=====*/
+
+dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
+	// summary: a Source object, which can be used as a DnD source, or a DnD target
+	
+	// object attributes (for markup)
+	isSource: true,
+	horizontal: false,
+	copyOnly: false,
+	selfCopy: false,
+	selfAccept: true,
+	skipForm: false,
+	withHandles: false,
+	autoSync: false,
+	delay: 0, // pixels
+	accept: ["text"],
+	
+	constructor: function(/*DOMNode|String*/node, /*dojo.dnd.__SourceArgs?*/params){
+		// summary: 
+		//		a constructor of the Source
+		// node:
+		//		node or node's id to build the source on
+		// params: 
+		//		any property of this class may be configured via the params
+		//		object which is mixed-in to the `dojo.dnd.Source` instance
+		dojo.mixin(this, dojo.mixin({}, params));
+		var type = this.accept;
+		if(type.length){
+			this.accept = {};
+			for(var i = 0; i < type.length; ++i){
+				this.accept[type[i]] = 1;
+			}
+		}
+		// class-specific variables
+		this.isDragging = false;
+		this.mouseDown = false;
+		this.targetAnchor = null;
+		this.targetBox = null;
+		this.before = true;
+		this._lastX = 0;
+		this._lastY = 0;
+		// states
+		this.sourceState  = "";
+		if(this.isSource){
+			dojo.addClass(this.node, "dojoDndSource");
+		}
+		this.targetState  = "";
+		if(this.accept){
+			dojo.addClass(this.node, "dojoDndTarget");
+		}
+		if(this.horizontal){
+			dojo.addClass(this.node, "dojoDndHorizontal");
+		}
+		// set up events
+		this.topics = [
+			dojo.subscribe("/dnd/source/over", this, "onDndSourceOver"),
+			dojo.subscribe("/dnd/start",  this, "onDndStart"),
+			dojo.subscribe("/dnd/drop",   this, "onDndDrop"),
+			dojo.subscribe("/dnd/cancel", this, "onDndCancel")
+		];
+	},
+	
+	// methods
+	checkAcceptance: function(source, nodes){
+		// summary: checks, if the target can accept nodes from this source
+		// source: Object: the source which provides items
+		// nodes: Array: the list of transferred items
+		if(this == source){
+			return !this.copyOnly || this.selfAccept;
+		}
+		for(var i = 0; i < nodes.length; ++i){
+			var type = source.getItem(nodes[i].id).type;
+			// type instanceof Array
+			var flag = false;
+			for(var j = 0; j < type.length; ++j){
+				if(type[j] in this.accept){
+					flag = true;
+					break;
+				}
+			}
+			if(!flag){
+				return false;	// Boolean
+			}
+		}
+		return true;	// Boolean
+	},
+	copyState: function(keyPressed, self){
+		// summary: Returns true, if we need to copy items, false to move.
+		//		It is separated to be overwritten dynamically, if needed.
+		// keyPressed: Boolean: the "copy" was pressed
+		// self: Boolean?: optional flag, which means that we are about to drop on itself
+		
+		if(keyPressed){ return true; }
+		if(arguments.length < 2){
+			self = this == dojo.dnd.manager().target;
+		}
+		if(self){
+			if(this.copyOnly){
+				return this.selfCopy;
+			}
+		}else{
+			return this.copyOnly;
+		}
+		return false;	// Boolean
+	},
+	destroy: function(){
+		// summary: prepares the object to be garbage-collected
+		dojo.dnd.Source.superclass.destroy.call(this);
+		dojo.forEach(this.topics, dojo.unsubscribe);
+		this.targetAnchor = null;
+	},
+
+	// markup methods
+	markupFactory: function(params, node){
+		params._skipStartup = true;
+		return new dojo.dnd.Source(node, params);
+	},
+
+	// mouse event processors
+	onMouseMove: function(e){
+		// summary: event processor for onmousemove
+		// e: Event: mouse event
+		if(this.isDragging && this.targetState == "Disabled"){ return; }
+		dojo.dnd.Source.superclass.onMouseMove.call(this, e);
+		var m = dojo.dnd.manager();
+		if(this.isDragging){
+			// calculate before/after
+			var before = false;
+			if(this.current){
+				if(!this.targetBox || this.targetAnchor != this.current){
+					this.targetBox = {
+						xy: dojo.coords(this.current, true),
+						w: this.current.offsetWidth,
+						h: this.current.offsetHeight
+					};
+				}
+				if(this.horizontal){
+					before = (e.pageX - this.targetBox.xy.x) < (this.targetBox.w / 2);
+				}else{
+					before = (e.pageY - this.targetBox.xy.y) < (this.targetBox.h / 2);
+				}
+			}
+			if(this.current != this.targetAnchor || before != this.before){
+				this._markTargetAnchor(before);
+				m.canDrop(!this.current || m.source != this || !(this.current.id in this.selection));
+			}
+		}else{
+			if(this.mouseDown && this.isSource &&
+					(Math.abs(e.pageX - this._lastX) > this.delay || Math.abs(e.pageY - this._lastY) > this.delay)){
+				var nodes = this.getSelectedNodes();
+				if(nodes.length){
+					m.startDrag(this, nodes, this.copyState(dojo.dnd.getCopyKeyState(e), true));
+				}
+			}
+		}
+	},
+	onMouseDown: function(e){
+		// summary: event processor for onmousedown
+		// e: Event: mouse event
+		if(!this.mouseDown && this._legalMouseDown(e) && (!this.skipForm || !dojo.dnd.isFormElement(e))){
+			this.mouseDown = true;
+			this._lastX = e.pageX;
+			this._lastY = e.pageY;
+			dojo.dnd.Source.superclass.onMouseDown.call(this, e);
+		}
+	},
+	onMouseUp: function(e){
+		// summary: event processor for onmouseup
+		// e: Event: mouse event
+		if(this.mouseDown){
+			this.mouseDown = false;
+			dojo.dnd.Source.superclass.onMouseUp.call(this, e);
+		}
+	},
+	
+	// topic event processors
+	onDndSourceOver: function(source){
+		// summary: topic event processor for /dnd/source/over, called when detected a current source
+		// source: Object: the source which has the mouse over it
+		if(this != source){
+			this.mouseDown = false;
+			if(this.targetAnchor){
+				this._unmarkTargetAnchor();
+			}
+		}else if(this.isDragging){
+			var m = dojo.dnd.manager();
+			m.canDrop(this.targetState != "Disabled" && (!this.current || m.source != this || !(this.current.id in this.selection)));
+		}
+	},
+	onDndStart: function(source, nodes, copy){
+		// summary: topic event processor for /dnd/start, called to initiate the DnD operation
+		// source: Object: the source which provides items
+		// nodes: Array: the list of transferred items
+		// copy: Boolean: copy items, if true, move items otherwise
+		if(this.autoSync){ this.sync(); }
+		if(this.isSource){
+			this._changeState("Source", this == source ? (copy ? "Copied" : "Moved") : "");
+		}
+		var accepted = this.accept && this.checkAcceptance(source, nodes);
+		this._changeState("Target", accepted ? "" : "Disabled");
+		if(this == source){
+			dojo.dnd.manager().overSource(this);
+		}
+		this.isDragging = true;
+	},
+	onDndDrop: function(source, nodes, copy, target){
+		// summary: topic event processor for /dnd/drop, called to finish the DnD operation
+		// source: Object: the source which provides items
+		// nodes: Array: the list of transferred items
+		// copy: Boolean: copy items, if true, move items otherwise
+		// target: Object: the target which accepts items
+		if(this == target){
+			// this one is for us => move nodes!
+			this.onDrop(source, nodes, copy);
+		}
+		this.onDndCancel();
+	},
+	onDndCancel: function(){
+		// summary: topic event processor for /dnd/cancel, called to cancel the DnD operation
+		if(this.targetAnchor){
+			this._unmarkTargetAnchor();
+			this.targetAnchor = null;
+		}
+		this.before = true;
+		this.isDragging = false;
+		this.mouseDown = false;
+		this._changeState("Source", "");
+		this._changeState("Target", "");
+	},
+	
+	// local events
+	onDrop: function(source, nodes, copy){
+		// summary: called only on the current target, when drop is performed
+		// source: Object: the source which provides items
+		// nodes: Array: the list of transferred items
+		// copy: Boolean: copy items, if true, move items otherwise
+		
+		if(this != source){
+			this.onDropExternal(source, nodes, copy);
+		}else{
+			this.onDropInternal(nodes, copy);
+		}
+	},
+	onDropExternal: function(source, nodes, copy){
+		// summary: called only on the current target, when drop is performed
+		//	from an external source
+		// source: Object: the source which provides items
+		// nodes: Array: the list of transferred items
+		// copy: Boolean: copy items, if true, move items otherwise
+		
+		var oldCreator = this._normalizedCreator;
+		// transferring nodes from the source to the target
+		if(this.creator){
+			// use defined creator
+			this._normalizedCreator = function(node, hint){
+				return oldCreator.call(this, source.getItem(node.id).data, hint);
+			};
+		}else{
+			// we have no creator defined => move/clone nodes
+			if(copy){
+				// clone nodes
+				this._normalizedCreator = function(node, hint){
+					var t = source.getItem(node.id);
+					var n = node.cloneNode(true);
+					n.id = dojo.dnd.getUniqueId();
+					return {node: n, data: t.data, type: t.type};
+				};
+			}else{
+				// move nodes
+				this._normalizedCreator = function(node, hint){
+					var t = source.getItem(node.id);
+					source.delItem(node.id);
+					return {node: node, data: t.data, type: t.type};
+				};
+			}
+		}
+		this.selectNone();
+		if(!copy && !this.creator){
+			source.selectNone();
+		}
+		this.insertNodes(true, nodes, this.before, this.current);
+		if(!copy && this.creator){
+			source.deleteSelectedNodes();
+		}
+		this._normalizedCreator = oldCreator;
+	},
+	onDropInternal: function(nodes, copy){
+		// summary: called only on the current target, when drop is performed
+		//	from the same target/source
+		// nodes: Array: the list of transferred items
+		// copy: Boolean: copy items, if true, move items otherwise
+		
+		var oldCreator = this._normalizedCreator;
+		// transferring nodes within the single source
+		if(this.current && this.current.id in this.selection){
+			// do nothing
+			return;
+		}
+		if(copy){
+			if(this.creator){
+				// create new copies of data items
+				this._normalizedCreator = function(node, hint){
+					return oldCreator.call(this, this.getItem(node.id).data, hint);
+				};
+			}else{
+				// clone nodes
+				this._normalizedCreator = function(node, hint){
+					var t = this.getItem(node.id);
+					var n = node.cloneNode(true);
+					n.id = dojo.dnd.getUniqueId();
+					return {node: n, data: t.data, type: t.type};
+				};
+			}
+		}else{
+			// move nodes
+			if(!this.current){
+				// do nothing
+				return;
+			}
+			this._normalizedCreator = function(node, hint){
+				var t = this.getItem(node.id);
+				return {node: node, data: t.data, type: t.type};
+			};
+		}
+		this._removeSelection();
+		this.insertNodes(true, nodes, this.before, this.current);
+		this._normalizedCreator = oldCreator;
+	},
+	onDraggingOver: function(){
+		// summary: called during the active DnD operation, when items
+		// are dragged over this target, and it is not disabled
+	},
+	onDraggingOut: function(){
+		// summary: called during the active DnD operation, when items
+		// are dragged away from this target, and it is not disabled
+	},
+	
+	// utilities
+	onOverEvent: function(){
+		// summary: this function is called once, when mouse is over our container
+		dojo.dnd.Source.superclass.onOverEvent.call(this);
+		dojo.dnd.manager().overSource(this);
+		if(this.isDragging && this.targetState != "Disabled"){
+			this.onDraggingOver();
+		}
+	},
+	onOutEvent: function(){
+		// summary: this function is called once, when mouse is out of our container
+		dojo.dnd.Source.superclass.onOutEvent.call(this);
+		dojo.dnd.manager().outSource(this);
+		if(this.isDragging && this.targetState != "Disabled"){
+			this.onDraggingOut();
+		}
+	},
+	_markTargetAnchor: function(before){
+		// summary: assigns a class to the current target anchor based on "before" status
+		// before: Boolean: insert before, if true, after otherwise
+		if(this.current == this.targetAnchor && this.before == before){ return; }
+		if(this.targetAnchor){
+			this._removeItemClass(this.targetAnchor, this.before ? "Before" : "After");
+		}
+		this.targetAnchor = this.current;
+		this.targetBox = null;
+		this.before = before;
+		if(this.targetAnchor){
+			this._addItemClass(this.targetAnchor, this.before ? "Before" : "After");
+		}
+	},
+	_unmarkTargetAnchor: function(){
+		// summary: removes a class of the current target anchor based on "before" status
+		if(!this.targetAnchor){ return; }
+		this._removeItemClass(this.targetAnchor, this.before ? "Before" : "After");
+		this.targetAnchor = null;
+		this.targetBox = null;
+		this.before = true;
+	},
+	_markDndStatus: function(copy){
+		// summary: changes source's state based on "copy" status
+		this._changeState("Source", copy ? "Copied" : "Moved");
+	},
+	_legalMouseDown: function(e){
+		// summary: checks if user clicked on "approved" items
+		// e: Event: mouse event
+		
+		// accept only the left mouse button
+		if(!dojo.dnd._isLmbPressed(e)){ return false; }
+		
+		if(!this.withHandles){ return true; }
+		
+		// check for handles
+		for(var node = e.target; node && node !== this.node; node = node.parentNode){
+			if(dojo.hasClass(node, "dojoDndHandle")){ return true; }
+			if(dojo.hasClass(node, "dojoDndItem")){ break; }
+		}
+		return false;	// Boolean
+	}
+});
+
+dojo.declare("dojo.dnd.Target", dojo.dnd.Source, {
+	// summary: a Target object, which can be used as a DnD target
+	
+	constructor: function(node, params){
+		// summary: a constructor of the Target --- see the Source constructor for details
+		this.isSource = false;
+		dojo.removeClass(this.node, "dojoDndSource");
+	},
+
+	// markup methods
+	markupFactory: function(params, node){
+		params._skipStartup = true;
+		return new dojo.dnd.Target(node, params);
+	}
+});
+
+dojo.declare("dojo.dnd.AutoSource", dojo.dnd.Source, {
+	// summary: a source, which syncs its DnD nodes by default
+	
+	constructor: function(node, params){
+		// summary: a constructor of the AutoSource --- see the Source constructor for details
+		this.autoSync = true;
+	},
+
+	// markup methods
+	markupFactory: function(params, node){
+		params._skipStartup = true;
+		return new dojo.dnd.AutoSource(node, params);
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._View"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._View"] = true;
+dojo.provide("dojox.grid._View");
+
+
+
+
+
+
+
+
+
+
+(function(){
+	// private
+	var getStyleText = function(inNode, inStyleText){
+		return inNode.style.cssText == undefined ? inNode.getAttribute("style") : inNode.style.cssText;
+	};
+
+	// public
+	dojo.declare('dojox.grid._View', [dijit._Widget, dijit._Templated], {
+		// summary:
+		//		A collection of grid columns. A grid is comprised of a set of views that stack horizontally.
+		//		Grid creates views automatically based on grid's layout structure.
+		//		Users should typically not need to access individual views directly.
+		//
+		// defaultWidth: String
+		//		Default width of the view
+		defaultWidth: "18em",
+
+		// viewWidth: String
+		// 		Width for the view, in valid css unit
+		viewWidth: "",
+
+		templateString:"<div class=\"dojoxGridView\" wairole=\"presentation\">\n\t<div class=\"dojoxGridHeader\" dojoAttachPoint=\"headerNode\" wairole=\"presentation\">\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\" wairole=\"presentation\">\n\t\t\t<div dojoAttachPoint=\"headerContentNode\" wairole=\"row\"></div>\n\t\t</div>\n\t</div>\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" dojoAttachPoint=\"hiddenFocusNode\" wairole=\"presentation\" />\n\t<input t [...]
+		
+		themeable: false,
+		classTag: 'dojoxGrid',
+		marginBottom: 0,
+		rowPad: 2,
+
+		// _togglingColumn: int
+		//		Width of the column being toggled (-1 for none)
+		_togglingColumn: -1,
+		
+		postMixInProperties: function(){
+			this.rowNodes = [];
+		},
+
+		postCreate: function(){
+			this.connect(this.scrollboxNode,"onscroll","doscroll");
+			dojox.grid.util.funnelEvents(this.contentNode, this, "doContentEvent", [ 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu', 'mousedown' ]);
+			dojox.grid.util.funnelEvents(this.headerNode, this, "doHeaderEvent", [ 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'click', 'contextmenu' ]);
+			this.content = new dojox.grid._ContentBuilder(this);
+			this.header = new dojox.grid._HeaderBuilder(this);
+			//BiDi: in RTL case, style width='9000em' causes scrolling problem in head node
+			if(!dojo._isBodyLtr()){
+				this.headerNodeContainer.style.width = "";
+			}
+		},
+
+		destroy: function(){
+			dojo.destroy(this.headerNode);
+			delete this.headerNode;
+			dojo.forEach(this.rowNodes, dojo.destroy);
+			this.rowNodes = [];
+			if(this.source){
+				this.source.destroy();
+			}
+			this.inherited(arguments);
+		},
+
+		// focus 
+		focus: function(){
+			if(dojo.isWebKit || dojo.isOpera){
+				this.hiddenFocusNode.focus();
+			}else{
+				this.scrollboxNode.focus();
+			}
+		},
+
+		setStructure: function(inStructure){
+			var vs = (this.structure = inStructure);
+			// FIXME: similar logic is duplicated in layout
+			if(vs.width && !isNaN(vs.width)){
+				this.viewWidth = vs.width + 'em';
+			}else{
+				this.viewWidth = vs.width || (vs.noscroll ? 'auto' : this.viewWidth); //|| this.defaultWidth;
+			}
+			this.onBeforeRow = vs.onBeforeRow;
+			this.onAfterRow = vs.onAfterRow;
+			this.noscroll = vs.noscroll;
+			if(this.noscroll){
+				this.scrollboxNode.style.overflow = "hidden";
+			}
+			this.simpleStructure = Boolean(vs.cells.length == 1);
+			// bookkeeping
+			this.testFlexCells();
+			// accomodate new structure
+			this.updateStructure();
+		},
+
+		testFlexCells: function(){
+			// FIXME: cheater, this function does double duty as initializer and tester
+			this.flexCells = false;
+			for(var j=0, row; (row=this.structure.cells[j]); j++){
+				for(var i=0, cell; (cell=row[i]); i++){
+					cell.view = this;
+					this.flexCells = this.flexCells || cell.isFlex();
+				}
+			}
+			return this.flexCells;
+		},
+
+		updateStructure: function(){
+			// header builder needs to update table map
+			this.header.update();
+			// content builder needs to update markup cache
+			this.content.update();
+		},
+
+		getScrollbarWidth: function(){
+			var hasScrollSpace = this.hasVScrollbar();
+			var overflow = dojo.style(this.scrollboxNode, "overflow");
+			if(this.noscroll || !overflow || overflow == "hidden"){
+				hasScrollSpace = false;
+			}else if(overflow == "scroll"){
+				hasScrollSpace = true;
+			}
+			return (hasScrollSpace ? dojox.html.metrics.getScrollbar().w : 0); // Integer
+		},
+
+		getColumnsWidth: function(){
+			return this.headerContentNode.firstChild.offsetWidth; // Integer
+		},
+
+		setColumnsWidth: function(width){
+			this.headerContentNode.firstChild.style.width = width + 'px';
+			if(this.viewWidth){
+				this.viewWidth = width + 'px';
+			}
+		},
+
+		getWidth: function(){
+			return this.viewWidth || (this.getColumnsWidth()+this.getScrollbarWidth()) +'px'; // String
+		},
+
+		getContentWidth: function(){
+			return Math.max(0, dojo._getContentBox(this.domNode).w - this.getScrollbarWidth()) + 'px'; // String
+		},
+
+		render: function(){
+			this.scrollboxNode.style.height = '';
+			this.renderHeader();
+			if(this._togglingColumn >= 0){
+				this.setColumnsWidth(this.getColumnsWidth() - this._togglingColumn);
+				this._togglingColumn = -1;
+			}
+			var cells = this.grid.layout.cells;
+			var getSibling = dojo.hitch(this, function(node, before){
+				var inc = before?-1:1;
+				var idx = this.header.getCellNodeIndex(node) + inc;
+				var cell = cells[idx];
+				while(cell && cell.getHeaderNode() && cell.getHeaderNode().style.display == "none"){
+					idx += inc;
+					cell = cells[idx];
+				}
+				if(cell){
+					return cell.getHeaderNode();
+				}
+				return null;
+			});
+			if(this.grid.columnReordering && this.simpleStructure){
+				if(this.source){
+					this.source.destroy();
+				}
+				this.source = new dojo.dnd.Source(this.headerContentNode.firstChild.rows[0], {
+					horizontal: true,
+					accept: [ "gridColumn_" + this.grid.id ],
+					viewIndex: this.index,
+					onMouseDown: dojo.hitch(this, function(e){
+						this.header.decorateEvent(e);
+						if((this.header.overRightResizeArea(e) || this.header.overLeftResizeArea(e)) &&
+							this.header.canResize(e) && !this.header.moveable){
+							this.header.beginColumnResize(e);
+						}else{
+							if(this.grid.headerMenu){
+								this.grid.headerMenu.onCancel(true);
+							}
+							// IE reports a left click as 1, where everything else reports 0
+							if(e.button === (dojo.isIE ? 1 : 0)){
+								dojo.dnd.Source.prototype.onMouseDown.call(this.source, e);
+							}
+						}
+					}),
+					_markTargetAnchor: dojo.hitch(this, function(before){
+						var src = this.source;
+						if(src.current == src.targetAnchor && src.before == before){ return; }
+						if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+							src._removeItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+						}
+						dojo.dnd.Source.prototype._markTargetAnchor.call(src, before);
+						if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+							src._addItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+						}						
+					}),
+					_unmarkTargetAnchor: dojo.hitch(this, function(){
+						var src = this.source;
+						if(!src.targetAnchor){ return; }
+						if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+							src._removeItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+						}
+						dojo.dnd.Source.prototype._unmarkTargetAnchor.call(src);
+					}),
+					destroy: dojo.hitch(this, function(){
+						dojo.disconnect(this._source_conn);
+						dojo.unsubscribe(this._source_sub);
+						dojo.dnd.Source.prototype.destroy.call(this.source);
+					})
+				});
+				this._source_conn = dojo.connect(this.source, "onDndDrop", this, "_onDndDrop");
+				this._source_sub = dojo.subscribe("/dnd/drop/before", this, "_onDndDropBefore");
+				this.source.startup();
+			}
+		},
+
+		_onDndDropBefore: function(source, nodes, copy){
+			if(dojo.dnd.manager().target !== this.source){
+				return;
+			}
+			this.source._targetNode = this.source.targetAnchor;
+			this.source._beforeTarget = this.source.before;
+			var views = this.grid.views.views;
+			var srcView = views[source.viewIndex];
+			var tgtView = views[this.index];
+			if(tgtView != srcView){
+				var s = srcView.convertColPctToFixed();
+				var t = tgtView.convertColPctToFixed();
+				if(s || t){
+					setTimeout(function(){
+						srcView.update();
+						tgtView.update();
+					}, 50);
+				}
+			}
+		},
+
+		_onDndDrop: function(source, nodes, copy){
+			if(dojo.dnd.manager().target !== this.source){
+				if(dojo.dnd.manager().source === this.source){
+					this._removingColumn = true;
+				}
+				return;
+			}
+
+			var getIdx = function(n){
+				return n ? dojo.attr(n, "idx") : null;
+			}
+			var w = dojo.marginBox(nodes[0]).w;
+			if(source.viewIndex !== this.index){
+				var views = this.grid.views.views;
+				var srcView = views[source.viewIndex];
+				var tgtView = views[this.index];
+				if(srcView.viewWidth && srcView.viewWidth != "auto"){
+					srcView.setColumnsWidth(srcView.getColumnsWidth() - w);
+				}
+				if(tgtView.viewWidth && tgtView.viewWidth != "auto"){
+					tgtView.setColumnsWidth(tgtView.getColumnsWidth());
+				}
+			}
+			var stn = this.source._targetNode;
+			var stb = this.source._beforeTarget;
+			var layout = this.grid.layout;
+			var idx = this.index;
+			delete this.source._targetNode;
+			delete this.source._beforeTarget;
+			
+			window.setTimeout(function(){
+				layout.moveColumn(
+					source.viewIndex,
+					idx,
+					getIdx(nodes[0]),
+					getIdx(stn),
+					stb
+				);
+			}, 1);
+		},
+
+		renderHeader: function(){
+			this.headerContentNode.innerHTML = this.header.generateHtml(this._getHeaderContent);
+			if(this.flexCells){
+				this.contentWidth = this.getContentWidth();
+				this.headerContentNode.firstChild.style.width = this.contentWidth;
+			}
+			dojox.grid.util.fire(this, "onAfterRow", [-1, this.structure.cells, this.headerContentNode]);
+		},
+
+		// note: not called in 'view' context
+		_getHeaderContent: function(inCell){
+			var n = inCell.name || inCell.grid.getCellName(inCell);
+			var ret = [ '<div class="dojoxGridSortNode' ];
+			
+			if(inCell.index != inCell.grid.getSortIndex()){
+				ret.push('">');
+			}else{
+				ret = ret.concat([ ' ',
+							inCell.grid.sortInfo > 0 ? 'dojoxGridSortUp' : 'dojoxGridSortDown',
+							'"><div class="dojoxGridArrowButtonChar">',
+							inCell.grid.sortInfo > 0 ? '▲' : '▼',
+							'</div><div class="dojoxGridArrowButtonNode" role="'+(dojo.isFF<3 ? "wairole:" : "")+'presentation"></div>' ]);
+			}
+			ret = ret.concat([n, '</div>']);
+			return ret.join('');
+		},
+
+		resize: function(){
+			this.adaptHeight();
+			this.adaptWidth();
+		},
+
+		hasHScrollbar: function(reset){
+			if(this._hasHScroll == undefined || reset){
+				if(this.noscroll){
+					this._hasHScroll = false;
+				}else{
+					var style = dojo.style(this.scrollboxNode, "overflow");
+					if(style == "hidden"){
+						this._hasHScroll = false;
+					}else if(style == "scroll"){
+						this._hasHScroll = true;
+					}else{
+						this._hasHScroll = (this.scrollboxNode.offsetWidth < this.contentNode.offsetWidth);
+					}
+				}
+			}
+			return this._hasHScroll; // Boolean
+		},
+
+		hasVScrollbar: function(reset){
+			if(this._hasVScroll == undefined || reset){
+				if(this.noscroll){
+					this._hasVScroll = false;
+				}else{
+					var style = dojo.style(this.scrollboxNode, "overflow");
+					if(style == "hidden"){
+						this._hasVScroll = false;
+					}else if(style == "scroll"){
+						this._hasVScroll = true;
+					}else{
+						this._hasVScroll = (this.scrollboxNode.offsetHeight < this.contentNode.offsetHeight);
+					}
+				}
+			}
+			return this._hasVScroll; // Boolean
+		},
+		
+		convertColPctToFixed: function(){
+			// Fix any percentage widths to be pixel values
+			var hasPct = false;
+			var cellNodes = dojo.query("th", this.headerContentNode);
+			var fixedWidths = dojo.map(cellNodes, function(c, vIdx){
+				var w = c.style.width;
+				dojo.attr(c, "vIdx", vIdx);
+				if(w && w.slice(-1) == "%"){
+					hasPct = true;
+				}else if(w && w.slice(-2) == "px"){
+					return window.parseInt(w, 10);
+				}
+				return dojo.contentBox(c).w;
+			});
+			if(hasPct){
+				dojo.forEach(this.grid.layout.cells, function(cell, idx){
+					if(cell.view == this){
+						var cellNode = cell.view.getHeaderCellNode(cell.index);
+						if(cellNode && dojo.hasAttr(cellNode, "vIdx")){
+							var vIdx = window.parseInt(dojo.attr(cellNode, "vIdx"));
+							this.setColWidth(idx, fixedWidths[vIdx]);
+							cellNodes[vIdx].style.width = cell.unitWidth;
+							dojo.removeAttr(cellNode, "vIdx");
+						}
+					}
+				}, this);
+				return true;
+			}
+			return false;
+		},
+
+		adaptHeight: function(minusScroll){
+			if(!this.grid._autoHeight){
+				var h = this.domNode.clientHeight;
+				if(minusScroll){
+					h -= dojox.html.metrics.getScrollbar().h;
+				}
+				dojox.grid.util.setStyleHeightPx(this.scrollboxNode, h);
+			}
+			this.hasVScrollbar(true);
+		},
+
+		adaptWidth: function(){
+			if(this.flexCells){
+				// the view content width
+				this.contentWidth = this.getContentWidth();
+				this.headerContentNode.firstChild.style.width = this.contentWidth;
+			}
+			// FIXME: it should be easier to get w from this.scrollboxNode.clientWidth, 
+			// but clientWidth seemingly does not include scrollbar width in some cases
+			var w = this.scrollboxNode.offsetWidth - this.getScrollbarWidth();
+			if(!this._removingColumn){
+				w = Math.max(w, this.getColumnsWidth()) + 'px';
+			}else{
+				w = Math.min(w, this.getColumnsWidth()) + 'px';
+				this._removingColumn = false;
+			}
+			var cn = this.contentNode;
+			cn.style.width = w;
+			this.hasHScrollbar(true);
+		},
+
+		setSize: function(w, h){
+			var ds = this.domNode.style;
+			var hs = this.headerNode.style;
+
+			if(w){
+				ds.width = w;
+				hs.width = w;
+			}
+			ds.height = (h >= 0 ? h + 'px' : '');
+		},
+
+		renderRow: function(inRowIndex){
+			var rowNode = this.createRowNode(inRowIndex);
+			this.buildRow(inRowIndex, rowNode);
+			this.grid.edit.restore(this, inRowIndex);
+			if(this._pendingUpdate){
+				window.clearTimeout(this._pendingUpdate);
+			}
+			this._pendingUpdate = window.setTimeout(dojo.hitch(this, function(){
+				window.clearTimeout(this._pendingUpdate);
+				delete this._pendingUpdate;
+				this.grid._resize();
+			}), 50);
+			return rowNode;
+		},
+
+		createRowNode: function(inRowIndex){
+			var node = document.createElement("div");
+			node.className = this.classTag + 'Row';
+			dojo.attr(node,"role","row");
+			node[dojox.grid.util.gridViewTag] = this.id;
+			node[dojox.grid.util.rowIndexTag] = inRowIndex;
+			this.rowNodes[inRowIndex] = node;
+			return node;
+		},
+
+		buildRow: function(inRowIndex, inRowNode){
+			this.buildRowContent(inRowIndex, inRowNode);
+			this.styleRow(inRowIndex, inRowNode);
+		},
+
+		buildRowContent: function(inRowIndex, inRowNode){
+			inRowNode.innerHTML = this.content.generateHtml(inRowIndex, inRowIndex); 
+			if(this.flexCells && this.contentWidth){
+				// FIXME: accessing firstChild here breaks encapsulation
+				inRowNode.firstChild.style.width = this.contentWidth;
+			}
+			dojox.grid.util.fire(this, "onAfterRow", [inRowIndex, this.structure.cells, inRowNode]);
+		},
+
+		rowRemoved:function(inRowIndex){
+			this.grid.edit.save(this, inRowIndex);
+			delete this.rowNodes[inRowIndex];
+		},
+
+		getRowNode: function(inRowIndex){
+			return this.rowNodes[inRowIndex];
+		},
+
+		getCellNode: function(inRowIndex, inCellIndex){
+			var row = this.getRowNode(inRowIndex);
+			if(row){
+				return this.content.getCellNode(row, inCellIndex);
+			}
+		},
+
+		getHeaderCellNode: function(inCellIndex){
+			if(this.headerContentNode){
+				return this.header.getCellNode(this.headerContentNode, inCellIndex);
+			}
+		},
+
+		// styling
+		styleRow: function(inRowIndex, inRowNode){
+			inRowNode._style = getStyleText(inRowNode);
+			this.styleRowNode(inRowIndex, inRowNode);
+		},
+
+		styleRowNode: function(inRowIndex, inRowNode){
+			if(inRowNode){
+				this.doStyleRowNode(inRowIndex, inRowNode);
+			}
+		},
+
+		doStyleRowNode: function(inRowIndex, inRowNode){
+			this.grid.styleRowNode(inRowIndex, inRowNode);
+		},
+
+		// updating
+		updateRow: function(inRowIndex){
+			var rowNode = this.getRowNode(inRowIndex);
+			if(rowNode){
+				rowNode.style.height = '';
+				this.buildRow(inRowIndex, rowNode);
+			}
+			return rowNode;
+		},
+
+		updateRowStyles: function(inRowIndex){
+			this.styleRowNode(inRowIndex, this.getRowNode(inRowIndex));
+		},
+
+		// scrolling
+		lastTop: 0,
+		firstScroll:0,
+
+		doscroll: function(inEvent){
+			//var s = dojo.marginBox(this.headerContentNode.firstChild);
+			var isLtr = dojo._isBodyLtr();
+			if(this.firstScroll < 2){
+				if((!isLtr && this.firstScroll == 1) || (isLtr && this.firstScroll == 0)){
+					var s = dojo.marginBox(this.headerNodeContainer);
+					if(dojo.isIE){
+						this.headerNodeContainer.style.width = s.w + this.getScrollbarWidth() + 'px';
+					}else if(dojo.isMoz){
+						//TODO currently only for FF, not sure for safari and opera
+						this.headerNodeContainer.style.width = s.w - this.getScrollbarWidth() + 'px';
+						//this.headerNodeContainer.style.width = s.w + 'px';
+						//set scroll to right in FF
+						this.scrollboxNode.scrollLeft = isLtr ?
+							this.scrollboxNode.clientWidth - this.scrollboxNode.scrollWidth :
+							this.scrollboxNode.scrollWidth - this.scrollboxNode.clientWidth;
+					}
+				}
+				this.firstScroll++;
+			}
+			this.headerNode.scrollLeft = this.scrollboxNode.scrollLeft;
+			// 'lastTop' is a semaphore to prevent feedback-loop with setScrollTop below
+			var top = this.scrollboxNode.scrollTop;
+			if(top != this.lastTop){
+				this.grid.scrollTo(top);
+			}
+		},
+
+		setScrollTop: function(inTop){
+			// 'lastTop' is a semaphore to prevent feedback-loop with doScroll above
+			this.lastTop = inTop;
+			this.scrollboxNode.scrollTop = inTop;
+			return this.scrollboxNode.scrollTop;
+		},
+
+		// event handlers (direct from DOM)
+		doContentEvent: function(e){
+			if(this.content.decorateEvent(e)){
+				this.grid.onContentEvent(e);
+			}
+		},
+
+		doHeaderEvent: function(e){
+			if(this.header.decorateEvent(e)){
+				this.grid.onHeaderEvent(e);
+			}
+		},
+
+		// event dispatch(from Grid)
+		dispatchContentEvent: function(e){
+			return this.content.dispatchEvent(e);
+		},
+
+		dispatchHeaderEvent: function(e){
+			return this.header.dispatchEvent(e);
+		},
+
+		// column resizing
+		setColWidth: function(inIndex, inWidth){
+			this.grid.setCellWidth(inIndex, inWidth + 'px');
+		},
+
+		update: function(){
+			this.content.update();
+			this.grid.update();
+			//get scroll after update or scroll left setting goes wrong on IE.
+			//See trac: #8040
+			var left = this.scrollboxNode.scrollLeft;
+			this.scrollboxNode.scrollLeft = left;
+			this.headerNode.scrollLeft = left;
+		}
+	});
+
+	dojo.declare("dojox.grid._GridAvatar", dojo.dnd.Avatar, {
+		construct: function(){
+			var dd = dojo.doc;
+
+			var a = dd.createElement("table");
+			a.cellPadding = a.cellSpacing = "0";
+			a.className = "dojoxGridDndAvatar";
+			a.style.position = "absolute";
+			a.style.zIndex = 1999;
+			a.style.margin = "0px"; // to avoid dojo.marginBox() problems with table's margins
+			var b = dd.createElement("tbody");
+			var tr = dd.createElement("tr");
+			var td = dd.createElement("td");
+			var img = dd.createElement("td");
+			tr.className = "dojoxGridDndAvatarItem";
+			img.className = "dojoxGridDndAvatarItemImage";
+			img.style.width = "16px";
+			var source = this.manager.source, node;
+			if(source.creator){
+				// create an avatar representation of the node
+				node = source._normailzedCreator(source.getItem(this.manager.nodes[0].id).data, "avatar").node;
+			}else{
+				// or just clone the node and hope it works
+				node = this.manager.nodes[0].cloneNode(true);
+				if(node.tagName.toLowerCase() == "tr"){
+					// insert extra table nodes
+					var table = dd.createElement("table"),
+						tbody = dd.createElement("tbody");
+					tbody.appendChild(node);
+					table.appendChild(tbody);
+					node = table;
+				}else if(node.tagName.toLowerCase() == "th"){
+					// insert extra table nodes
+					var table = dd.createElement("table"),
+						tbody = dd.createElement("tbody"),
+						r = dd.createElement("tr");
+					table.cellPadding = table.cellSpacing = "0";
+					r.appendChild(node);
+					tbody.appendChild(r);
+					table.appendChild(tbody);
+					node = table;
+				}
+			}
+			node.id = "";
+			td.appendChild(node);
+			tr.appendChild(img);
+			tr.appendChild(td);
+			dojo.style(tr, "opacity", 0.9);
+			b.appendChild(tr);
+
+			a.appendChild(b);
+			this.node = a;
+
+			var m = dojo.dnd.manager();
+			this.oldOffsetY = m.OFFSET_Y;
+			m.OFFSET_Y = 1;
+		},
+		destroy: function(){
+			dojo.dnd.manager().OFFSET_Y = this.oldOffsetY;
+			this.inherited(arguments);
+		}
+	});
+
+	var oldMakeAvatar = dojo.dnd.manager().makeAvatar;
+	dojo.dnd.manager().makeAvatar = function(){
+		var src = this.source;
+		if(src.viewIndex !== undefined){
+			return new dojox.grid._GridAvatar(this);
+		}
+		return oldMakeAvatar.call(dojo.dnd.manager());
+	}
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid._RowSelector"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._RowSelector"] = true;
+dojo.provide("dojox.grid._RowSelector");
+
+
+dojo.declare('dojox.grid._RowSelector', dojox.grid._View, {
+	// summary:
+	//	Custom grid view. If used in a grid structure, provides a small selectable region for grid rows.
+	defaultWidth: "2em",
+	noscroll: true,
+	padBorderWidth: 2,
+	buildRendering: function(){
+		this.inherited('buildRendering', arguments);
+		this.scrollboxNode.style.overflow = "hidden";
+		this.headerNode.style.visibility = "hidden";
+	},	
+	getWidth: function(){
+		return this.viewWidth || this.defaultWidth;
+	},
+	buildRowContent: function(inRowIndex, inRowNode){
+		var w = this.contentNode.offsetWidth - this.padBorderWidth 
+		inRowNode.innerHTML = '<table class="dojoxGridRowbarTable" style="width:' + w + 'px;" border="0" cellspacing="0" cellpadding="0" role="'+(dojo.isFF<3 ? "wairole:" : "")+'presentation"><tr><td class="dojoxGridRowbarInner"> </td></tr></table>';
+	},
+	renderHeader: function(){
+	},
+	resize: function(){
+		this.adaptHeight();
+	},
+	adaptWidth: function(){
+	},
+	// styling
+	doStyleRowNode: function(inRowIndex, inRowNode){
+		var n = [ "dojoxGridRowbar" ];
+		if(this.grid.rows.isOver(inRowIndex)){
+			n.push("dojoxGridRowbarOver");
+		}
+		if(this.grid.selection.isSelected(inRowIndex)){
+			n.push("dojoxGridRowbarSelected");
+		}
+		inRowNode.className = n.join(" ");
+	},
+	// event handlers
+	domouseover: function(e){
+		this.grid.onMouseOverRow(e);
+	},
+	domouseout: function(e){
+		if(!this.isIntraRowEvent(e)){
+			this.grid.onMouseOutRow(e);
+		}
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._Layout"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Layout"] = true;
+dojo.provide("dojox.grid._Layout");
+
+
+
+dojo.declare("dojox.grid._Layout", null, {
+	// summary:
+	//	Controls grid cell layout. Owned by grid and used internally.
+	constructor: function(inGrid){
+		this.grid = inGrid;
+	},
+	// flat array of grid cells
+	cells: [],
+	// structured array of grid cells
+	structure: null,
+	// default cell width
+	defaultWidth: '6em',
+
+	// methods
+	moveColumn: function(sourceViewIndex, destViewIndex, cellIndex, targetIndex, before){
+		var source_cells = this.structure[sourceViewIndex].cells[0];
+		var dest_cells = this.structure[destViewIndex].cells[0];
+
+		var cell = null;
+		var cell_ri = 0;
+		var target_ri = 0;
+
+		for(var i=0, c; c=source_cells[i]; i++){
+			if(c.index == cellIndex){
+				cell_ri = i;
+				break;
+			}
+		}
+		cell = source_cells.splice(cell_ri, 1)[0];
+		cell.view = this.grid.views.views[destViewIndex];
+
+		for(i=0, c=null; c=dest_cells[i]; i++){
+			if(c.index == targetIndex){
+				target_ri = i;
+				break;
+			}
+		}
+		if(!before){
+			target_ri += 1;
+		}
+		dest_cells.splice(target_ri, 0, cell);
+
+		var sortedCell = this.grid.getCell(this.grid.getSortIndex());
+		if(sortedCell){
+			sortedCell._currentlySorted = this.grid.getSortAsc();
+		}
+
+		this.cells = [];
+		var cellIndex = 0;
+		for(var i=0, v; v=this.structure[i]; i++){
+			for(var j=0, cs; cs=v.cells[j]; j++){
+				for(var k=0, c; c=cs[k]; k++){
+					c.index = cellIndex;
+					this.cells.push(c);
+					if("_currentlySorted" in c){
+						var si = cellIndex + 1;
+						si *= c._currentlySorted ? 1 : -1;
+						this.grid.sortInfo = si;
+						delete c._currentlySorted;
+					}
+					cellIndex++;
+				}
+			}
+		}
+		this.grid.setupHeaderMenu();
+		//this.grid.renderOnIdle();
+	},
+
+	setColumnVisibility: function(columnIndex, visible){
+		var cell = this.cells[columnIndex];
+		if(cell.hidden == visible){
+			cell.hidden = !visible;
+			var v = cell.view, w = v.viewWidth;
+			if(w && w != "auto"){
+				v._togglingColumn = dojo.marginBox(cell.getHeaderNode()).w || 0;
+			}
+			v.update();
+			return true;
+		}else{
+			return false;
+		}
+	},
+	
+	addCellDef: function(inRowIndex, inCellIndex, inDef){
+		var self = this;
+		var getCellWidth = function(inDef){
+			var w = 0;
+			if(inDef.colSpan > 1){
+				w = 0;
+			}else{
+				w = inDef.width || self._defaultCellProps.width || self.defaultWidth;
+
+				if(!isNaN(w)){
+					w = w + "em";
+				}
+			}
+			return w;
+		};
+
+		var props = {
+			grid: this.grid,
+			subrow: inRowIndex,
+			layoutIndex: inCellIndex,
+			index: this.cells.length
+		};
+
+		if(inDef && inDef instanceof dojox.grid.cells._Base){
+			var new_cell = dojo.clone(inDef);
+			props.unitWidth = getCellWidth(new_cell._props);
+			new_cell = dojo.mixin(new_cell, this._defaultCellProps, inDef._props, props);
+			return new_cell;
+		}
+
+		var cell_type = inDef.type || this._defaultCellProps.type || dojox.grid.cells.Cell;
+
+		props.unitWidth = getCellWidth(inDef);
+		return new cell_type(dojo.mixin({}, this._defaultCellProps, inDef, props));	
+	},
+	
+	addRowDef: function(inRowIndex, inDef){
+		var result = [];
+		var relSum = 0, pctSum = 0, doRel = true;
+		for(var i=0, def, cell; (def=inDef[i]); i++){
+			cell = this.addCellDef(inRowIndex, i, def);
+			result.push(cell);
+			this.cells.push(cell);
+			// Check and calculate the sum of all relative widths
+			if(doRel && cell.relWidth){
+				relSum += cell.relWidth;
+			}else if(cell.width){
+				var w = cell.width;
+				if(typeof w == "string" && w.slice(-1) == "%"){
+					pctSum += window.parseInt(w, 10);
+				}else if(w == "auto"){
+					// relative widths doesn't play nice with auto - since we
+					// don't have a way of knowing how much space the auto is 
+					// supposed to take up.
+					doRel = false;
+				}
+			}
+		}
+		if(relSum && doRel){
+			// We have some kind of relWidths specified - so change them to %
+			dojo.forEach(result, function(cell){
+				if(cell.relWidth){
+					cell.width = cell.unitWidth = ((cell.relWidth / relSum) * (100 - pctSum)) + "%";
+				}
+			});
+		}
+		return result;
+	
+	},
+
+	addRowsDef: function(inDef){
+		var result = [];
+		if(dojo.isArray(inDef)){
+			if(dojo.isArray(inDef[0])){
+				for(var i=0, row; inDef && (row=inDef[i]); i++){
+					result.push(this.addRowDef(i, row));
+				}
+			}else{
+				result.push(this.addRowDef(0, inDef));
+			}
+		}
+		return result;	
+	},
+	
+	addViewDef: function(inDef){
+		this._defaultCellProps = inDef.defaultCell || {};
+		if(inDef.width && inDef.width == "auto"){
+			delete inDef.width;
+		}
+		return dojo.mixin({}, inDef, {cells: this.addRowsDef(inDef.rows || inDef.cells)});
+	},
+	
+	setStructure: function(inStructure){
+		this.fieldIndex = 0;
+		this.cells = [];
+		var s = this.structure = [];
+
+		if(this.grid.rowSelector){
+			var sel = { type: dojox._scopeName + ".grid._RowSelector" };
+
+			if(dojo.isString(this.grid.rowSelector)){
+				var width = this.grid.rowSelector;
+
+				if(width == "false"){
+					sel = null;
+				}else if(width != "true"){
+					sel['width'] = width;
+				}
+			}else{
+				if(!this.grid.rowSelector){
+					sel = null;
+				}
+			}
+
+			if(sel){
+				s.push(this.addViewDef(sel));
+			}
+		}
+
+		var isCell = function(def){
+			return ("name" in def || "field" in def || "get" in def);
+		};
+
+		var isRowDef = function(def){
+			if(dojo.isArray(def)){
+				if(dojo.isArray(def[0]) || isCell(def[0])){
+					return true;
+				}
+			}
+			return false;
+		};
+
+		var isView = function(def){
+			return (def != null && dojo.isObject(def) &&
+					("cells" in def || "rows" in def || ("type" in def && !isCell(def))));
+		};
+
+		if(dojo.isArray(inStructure)){
+			var hasViews = false;
+			for(var i=0, st; (st=inStructure[i]); i++){
+				if(isView(st)){
+					hasViews = true;
+					break;
+				}
+			}
+			if(!hasViews){
+				s.push(this.addViewDef({ cells: inStructure }));
+			}else{
+				for(var i=0, st; (st=inStructure[i]); i++){
+					if(isRowDef(st)){
+						s.push(this.addViewDef({ cells: st }));
+					}else if(isView(st)){
+						s.push(this.addViewDef(st));
+					}
+				}
+			}
+		}else if(isView(inStructure)){
+			// it's a view object
+			s.push(this.addViewDef(inStructure));
+		}
+
+		this.cellCount = this.cells.length;
+		this.grid.setupHeaderMenu();
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._ViewManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._ViewManager"] = true;
+dojo.provide("dojox.grid._ViewManager");
+
+dojo.declare('dojox.grid._ViewManager', null, {
+	// summary:
+	//		A collection of grid views. Owned by grid and used internally for managing grid views.
+	// description:
+	//		Grid creates views automatically based on grid's layout structure.
+	//		Users should typically not need to access individual views or the views collection directly.
+	constructor: function(inGrid){
+		this.grid = inGrid;
+	},
+
+	defaultWidth: 200,
+
+	views: [],
+
+	// operations
+	resize: function(){
+		this.onEach("resize");
+	},
+
+	render: function(){
+		this.onEach("render");
+	},
+
+	// views
+	addView: function(inView){
+		inView.idx = this.views.length;
+		this.views.push(inView);
+	},
+
+	destroyViews: function(){
+		for(var i=0, v; v=this.views[i]; i++){
+			v.destroy();
+		}
+		this.views = [];
+	},
+
+	getContentNodes: function(){
+		var nodes = [];
+		for(var i=0, v; v=this.views[i]; i++){
+			nodes.push(v.contentNode);
+		}
+		return nodes;
+	},
+
+	forEach: function(inCallback){
+		for(var i=0, v; v=this.views[i]; i++){
+			inCallback(v, i);
+		}
+	},
+
+	onEach: function(inMethod, inArgs){
+		inArgs = inArgs || [];
+		for(var i=0, v; v=this.views[i]; i++){
+			if(inMethod in v){
+				v[inMethod].apply(v, inArgs);
+			}
+		}
+	},
+
+	// layout
+	normalizeHeaderNodeHeight: function(){
+		var rowNodes = [];
+		for(var i=0, v; (v=this.views[i]); i++){
+			if(v.headerContentNode.firstChild){
+				rowNodes.push(v.headerContentNode);
+			}
+		}
+		this.normalizeRowNodeHeights(rowNodes);
+	},
+
+	normalizeRowNodeHeights: function(inRowNodes){
+		var h = 0; 
+		for(var i=0, n, o; (n=inRowNodes[i]); i++){
+			h = Math.max(h, dojo.marginBox(n.firstChild).h);
+		}
+		h = (h >= 0 ? h : 0);
+		//
+		//
+		for(var i=0, n; (n=inRowNodes[i]); i++){
+			dojo.marginBox(n.firstChild, {h:h});
+		}
+		//
+		//
+		//
+		// querying the height here seems to help scroller measure the page on IE
+		if(inRowNodes&&inRowNodes[0]&&inRowNodes[0].parentNode){
+			inRowNodes[0].parentNode.offsetHeight;
+		}
+	},
+	
+	resetHeaderNodeHeight: function(){
+		for(var i=0, v, n; (v=this.views[i]); i++){
+			n = v.headerContentNode.firstChild;
+			if(n){
+				n.style.height = "";
+			}
+		}
+	},
+
+	renormalizeRow: function(inRowIndex){
+		var rowNodes = [];
+		for(var i=0, v, n; (v=this.views[i])&&(n=v.getRowNode(inRowIndex)); i++){
+			n.firstChild.style.height = '';
+			rowNodes.push(n);
+		}
+		this.normalizeRowNodeHeights(rowNodes);
+	},
+
+	getViewWidth: function(inIndex){
+		return this.views[inIndex].getWidth() || this.defaultWidth;
+	},
+
+	// must be called after view widths are properly set or height can be miscalculated
+	// if there are flex columns
+	measureHeader: function(){
+		// need to reset view header heights so they are properly measured.
+		this.resetHeaderNodeHeight();
+		this.forEach(function(inView){
+			inView.headerContentNode.style.height = '';
+		});
+		var h = 0;
+		// calculate maximum view header height
+		this.forEach(function(inView){
+			h = Math.max(inView.headerNode.offsetHeight, h);
+		});
+		return h;
+	},
+
+	measureContent: function(){
+		var h = 0;
+		this.forEach(function(inView){
+			h = Math.max(inView.domNode.offsetHeight, h);
+		});
+		return h;
+	},
+
+	findClient: function(inAutoWidth){
+		// try to use user defined client
+		var c = this.grid.elasticView || -1;
+		// attempt to find implicit client
+		if(c < 0){
+			for(var i=1, v; (v=this.views[i]); i++){
+				if(v.viewWidth){
+					for(i=1; (v=this.views[i]); i++){
+						if(!v.viewWidth){
+							c = i;
+							break;
+						}
+					}
+					break;
+				}
+			}
+		}
+		// client is in the middle by default
+		if(c < 0){
+			c = Math.floor(this.views.length / 2);
+		}
+		return c;
+	},
+
+	arrange: function(l, w){
+		var i, v, vw, len = this.views.length;
+		// find the client
+		var c = (w <= 0 ? len : this.findClient());
+		// layout views
+		var setPosition = function(v, l){
+			var ds = v.domNode.style;
+			var hs = v.headerNode.style;
+
+			if(!dojo._isBodyLtr()){
+				ds.right = l + 'px';
+				hs.right = l + 'px';
+			}else{
+				ds.left = l + 'px';
+				hs.left = l + 'px';
+			}
+			ds.top = 0 + 'px';
+			hs.top = 0;
+		}
+		// for views left of the client
+		//BiDi TODO: The left and right should not appear in BIDI environment. Should be replaced with 
+		//leading and tailing concept.
+		for(i=0; (v=this.views[i])&&(i<c); i++){
+			// get width
+			vw = this.getViewWidth(i);
+			// process boxes
+			v.setSize(vw, 0);
+			setPosition(v, l);
+			if(v.headerContentNode && v.headerContentNode.firstChild){
+				vw = v.getColumnsWidth()+v.getScrollbarWidth();
+			}else{
+				vw = v.domNode.offsetWidth;
+			}
+			// update position
+			l += vw;
+		}
+		// next view (is the client, i++ == c) 
+		i++;
+		// start from the right edge
+		var r = w;
+		// for views right of the client (iterated from the right)
+		for(var j=len-1; (v=this.views[j])&&(i<=j); j--){
+			// get width
+			vw = this.getViewWidth(j);
+			// set size
+			v.setSize(vw, 0);
+			// measure in pixels
+			vw = v.domNode.offsetWidth;
+			// update position
+			r -= vw;
+			// set position
+			setPosition(v, r);
+		}
+		if(c<len){
+			v = this.views[c];
+			// position the client box between left and right boxes	
+			vw = Math.max(1, r-l);
+			// set size
+			v.setSize(vw + 'px', 0);
+			setPosition(v, l);
+		}
+		return l;
+	},
+
+	// rendering
+	renderRow: function(inRowIndex, inNodes){
+		var rowNodes = [];
+		for(var i=0, v, n, rowNode; (v=this.views[i])&&(n=inNodes[i]); i++){
+			rowNode = v.renderRow(inRowIndex);
+			n.appendChild(rowNode);
+			rowNodes.push(rowNode);
+		}
+		this.normalizeRowNodeHeights(rowNodes);
+	},
+	
+	rowRemoved: function(inRowIndex){
+		this.onEach("rowRemoved", [ inRowIndex ]);
+	},
+	
+	// updating
+	updateRow: function(inRowIndex){
+		for(var i=0, v; v=this.views[i]; i++){
+			v.updateRow(inRowIndex);
+		}
+		this.renormalizeRow(inRowIndex);
+	},
+	
+	updateRowStyles: function(inRowIndex){
+		this.onEach("updateRowStyles", [ inRowIndex ]);
+	},
+	
+	// scrolling
+	setScrollTop: function(inTop){
+		var top = inTop;
+		for(var i=0, v; v=this.views[i]; i++){
+			top = v.setScrollTop(inTop);
+			// Work around IE not firing scroll events that cause header offset
+			// issues to occur.
+			if(dojo.isIE && v.headerNode && v.scrollboxNode){
+				v.headerNode.scrollLeft = v.scrollboxNode.scrollLeft;
+			}
+		}
+		return top;
+		//this.onEach("setScrollTop", [ inTop ]);
+	},
+	
+	getFirstScrollingView: function(){
+		// summary: Returns the first grid view with a scroll bar 
+		for(var i=0, v; (v=this.views[i]); i++){
+			if(v.hasHScrollbar() || v.hasVScrollbar()){
+				return v;
+			}
+		}
+	}
+	
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._RowManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._RowManager"] = true;
+dojo.provide("dojox.grid._RowManager");
+
+(function(){
+	var setStyleText = function(inNode, inStyleText){
+		if(inNode.style.cssText == undefined){
+			inNode.setAttribute("style", inStyleText);
+		}else{
+			inNode.style.cssText = inStyleText;
+		}
+	};
+
+	dojo.declare("dojox.grid._RowManager", null, {
+		//	Stores information about grid rows. Owned by grid and used internally.
+		constructor: function(inGrid){
+			this.grid = inGrid;
+		},
+		linesToEms: 2,
+		overRow: -2,
+		// styles
+		prepareStylingRow: function(inRowIndex, inRowNode){
+			return {
+				index: inRowIndex, 
+				node: inRowNode,
+				odd: Boolean(inRowIndex&1),
+				selected: this.grid.selection.isSelected(inRowIndex),
+				over: this.isOver(inRowIndex),
+				customStyles: "",
+				customClasses: "dojoxGridRow"
+			}
+		},
+		styleRowNode: function(inRowIndex, inRowNode){
+			var row = this.prepareStylingRow(inRowIndex, inRowNode);
+			this.grid.onStyleRow(row);
+			this.applyStyles(row);
+		},
+		applyStyles: function(inRow){
+			var i = inRow;
+
+			i.node.className = i.customClasses;
+			var h = i.node.style.height;
+			setStyleText(i.node, i.customStyles + ';' + (i.node._style||''));
+			i.node.style.height = h;
+		},
+		updateStyles: function(inRowIndex){
+			this.grid.updateRowStyles(inRowIndex);
+		},
+		// states and events
+		setOverRow: function(inRowIndex){
+			var last = this.overRow;
+			this.overRow = inRowIndex;
+			if((last!=this.overRow)&&(last >=0)){
+				this.updateStyles(last);
+			}
+			this.updateStyles(this.overRow);
+		},
+		isOver: function(inRowIndex){
+			return (this.overRow == inRowIndex);
+		}
+	});
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid._FocusManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._FocusManager"] = true;
+dojo.provide("dojox.grid._FocusManager");
+
+
+
+// focus management
+dojo.declare("dojox.grid._FocusManager", null, {
+	// summary:
+	//	Controls grid cell focus. Owned by grid and used internally for focusing.
+	//	Note: grid cell actually receives keyboard input only when cell is being edited.
+	constructor: function(inGrid){
+		this.grid = inGrid;
+		this.cell = null;
+		this.rowIndex = -1;
+		this._connects = [];
+		this._connects.push(dojo.connect(this.grid.domNode, "onfocus", this, "doFocus"));
+		this._connects.push(dojo.connect(this.grid.domNode, "onblur", this, "doBlur"));
+		this._connects.push(dojo.connect(this.grid.lastFocusNode, "onfocus", this, "doLastNodeFocus"));
+		this._connects.push(dojo.connect(this.grid.lastFocusNode, "onblur", this, "doLastNodeBlur"));
+		this._connects.push(dojo.connect(this.grid,"_onFetchComplete", this, "_delayedCellFocus"));
+		this._connects.push(dojo.connect(this.grid,"postrender", this, "_delayedHeaderFocus"));
+	},
+	destroy: function(){
+		dojo.forEach(this._connects, dojo.disconnect);
+		delete this.grid;
+		delete this.cell;
+	},
+	_colHeadNode: null,
+	_colHeadFocusIdx: null,
+	tabbingOut: false,
+	focusClass: "dojoxGridCellFocus",
+	focusView: null,
+	initFocusView: function(){
+		this.focusView = this.grid.views.getFirstScrollingView() || this.focusView;
+		this._initColumnHeaders();
+	},
+	isFocusCell: function(inCell, inRowIndex){
+		// summary:
+		//	states if the given cell is focused
+		// inCell: object
+		//	grid cell object
+		// inRowIndex: int
+		//	grid row index
+		// returns:
+		//	true of the given grid cell is focused
+		return (this.cell == inCell) && (this.rowIndex == inRowIndex);
+	},
+	isLastFocusCell: function(){
+		if(this.cell){
+			return (this.rowIndex == this.grid.rowCount-1) && (this.cell.index == this.grid.layout.cellCount-1);
+		}
+		return false;
+	},
+	isFirstFocusCell: function(){
+		if(this.cell){
+			return (this.rowIndex == 0) && (this.cell.index == 0);
+		}
+		return false;
+	},
+	isNoFocusCell: function(){
+		return (this.rowIndex < 0) || !this.cell;
+	},
+	isNavHeader: function(){
+		// summary:
+		//	states whether currently navigating among column headers.
+		// returns:
+		//	true if focus is on a column header; false otherwise. 
+		return (!!this._colHeadNode);
+	},
+	getHeaderIndex: function(){
+		// summary:
+		//	if one of the column headers currently has focus, return its index.
+		// returns:
+		//	index of the focused column header, or -1 if none have focus.
+		if(this._colHeadNode){
+			return dojo.indexOf(this._findHeaderCells(), this._colHeadNode);
+		}else{
+			return -1;
+		}
+	},
+	_focusifyCellNode: function(inBork){
+		var n = this.cell && this.cell.getNode(this.rowIndex);
+		if(n){
+			dojo.toggleClass(n, this.focusClass, inBork);
+			if(inBork){
+				var sl = this.scrollIntoView();
+				try{
+					if(!this.grid.edit.isEditing()){
+						dojox.grid.util.fire(n, "focus");
+						if(sl){ this.cell.view.scrollboxNode.scrollLeft = sl; }
+					}
+				}catch(e){}
+			}
+		}
+	},
+	_delayedCellFocus: function(){
+		if(this.isNavHeader()){
+				return;
+		}
+		var n = this.cell && this.cell.getNode(this.rowIndex);
+		if(n){ 
+			try{
+				if(!this.grid.edit.isEditing()){
+					dojo.toggleClass(n, this.focusClass, true);
+					dojox.grid.util.fire(n, "focus");
+				}
+			} 
+			catch(e){}
+		}
+	},
+	_delayedHeaderFocus: function(){
+		if(this.isNavHeader()){
+			this.focusHeader();
+			//this may need clickSelect?
+		}
+	},
+	_initColumnHeaders: function(){
+		this._connects.push(dojo.connect(this.grid.viewsHeaderNode, "onblur", this, "doBlurHeader"));
+		var headers = this._findHeaderCells();
+		for(var i = 0; i < headers.length; i++){
+			this._connects.push(dojo.connect(headers[i], "onfocus", this, "doColHeaderFocus"));
+			this._connects.push(dojo.connect(headers[i], "onblur", this, "doColHeaderBlur"));
+		}
+	},
+	_findHeaderCells: function(){
+		// This should be a one liner:
+		//	dojo.query("th[tabindex=-1]", this.grid.viewsHeaderNode);
+		// But there is a bug in dojo.query() for IE -- see trac #7037.
+		var allHeads = dojo.query("th", this.grid.viewsHeaderNode);
+		var headers = [];
+		for (var i = 0; i < allHeads.length; i++){
+			var aHead = allHeads[i];
+			var hasTabIdx = dojo.hasAttr(aHead, "tabindex");
+			var tabindex = dojo.attr(aHead, "tabindex");
+			if (hasTabIdx && tabindex < 0) {
+				headers.push(aHead);
+			}
+		}
+		return headers;
+	},
+	scrollIntoView: function(){
+		var info = (this.cell ? this._scrollInfo(this.cell) : null);
+		if(!info || !info.s){
+			return null;
+		}
+		var rt = this.grid.scroller.findScrollTop(this.rowIndex);
+		// place cell within horizontal view
+		if(info.n && info.sr){
+			if(info.n.offsetLeft + info.n.offsetWidth > info.sr.l + info.sr.w){
+				info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w;
+			}else if(info.n.offsetLeft < info.sr.l){
+				info.s.scrollLeft = info.n.offsetLeft;
+			}
+		}
+		// place cell within vertical view
+		if(info.r && info.sr){
+			if(rt + info.r.offsetHeight > info.sr.t + info.sr.h){
+				this.grid.setScrollTop(rt + info.r.offsetHeight - info.sr.h);
+			}else if(rt < info.sr.t){
+				this.grid.setScrollTop(rt);
+			}
+		}
+
+		return info.s.scrollLeft;
+	},
+	_scrollInfo: function(cell, domNode){
+		if(cell){
+			var cl = cell,
+				sbn = cl.view.scrollboxNode,
+				sbnr = {
+					w: sbn.clientWidth,
+					l: sbn.scrollLeft,
+					t: sbn.scrollTop,
+					h: sbn.clientHeight
+				},
+				rn = cl.view.getRowNode(this.rowIndex);
+			return {
+				c: cl,
+				s: sbn,
+				sr: sbnr,
+				n: (domNode ? domNode : cell.getNode(this.rowIndex)),
+				r: rn
+			};
+		}
+		return null;
+	},
+	_scrollHeader: function(currentIdx){
+		var info = null;
+		if(this._colHeadNode){
+			var cell = this.grid.getCell(currentIdx);
+			info = this._scrollInfo(cell, cell.getNode(0));
+		}
+		if(info && info.s && info.sr && info.n){
+			// scroll horizontally as needed.
+			var scroll = info.sr.l + info.sr.w;
+			if(info.n.offsetLeft + info.n.offsetWidth > scroll){
+				info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w;
+			}else if(info.n.offsetLeft < info.sr.l){
+				info.s.scrollLeft = info.n.offsetLeft;
+			}else if(dojo.isIE <= 7 && cell && cell.view.headerNode){
+				// Trac 7158: scroll dojoxGridHeader for IE7 and lower
+				cell.view.headerNode.scrollLeft = info.s.scrollLeft;
+			}
+		}
+	},
+	styleRow: function(inRow){
+		return;
+	},
+	setFocusIndex: function(inRowIndex, inCellIndex){
+		// summary:
+		//	focuses the given grid cell
+		// inRowIndex: int
+		//	grid row index
+		// inCellIndex: int
+		//	grid cell index
+		this.setFocusCell(this.grid.getCell(inCellIndex), inRowIndex);
+	},
+	setFocusCell: function(inCell, inRowIndex){
+		// summary:
+		//	focuses the given grid cell
+		// inCell: object
+		//	grid cell object
+		// inRowIndex: int
+		//	grid row index
+		if(inCell && !this.isFocusCell(inCell, inRowIndex)){
+			this.tabbingOut = false;
+			this._colHeadNode = this._colHeadFocusIdx = null;
+			this.focusGridView();
+			this._focusifyCellNode(false);
+			this.cell = inCell;
+			this.rowIndex = inRowIndex;
+			this._focusifyCellNode(true);
+		}
+		// even if this cell isFocusCell, the document focus may need to be rejiggered
+		// call opera on delay to prevent keypress from altering focus
+		if(dojo.isOpera){
+			setTimeout(dojo.hitch(this.grid, 'onCellFocus', this.cell, this.rowIndex), 1);
+		}else{
+			this.grid.onCellFocus(this.cell, this.rowIndex);
+		}
+	},
+	next: function(){
+		// summary:
+		//	focus next grid cell
+		if(this.cell){
+			var row=this.rowIndex, col=this.cell.index+1, cc=this.grid.layout.cellCount-1, rc=this.grid.rowCount-1;
+			if(col > cc){
+				col = 0;
+				row++;
+			}
+			if(row > rc){
+				col = cc;
+				row = rc;
+			}
+			if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+				var nextCell = this.grid.getCell(col);
+				if (!this.isLastFocusCell() && !nextCell.editable){
+					this.cell=nextCell;
+					this.rowIndex=row;
+					this.next();
+					return;
+				}
+			}
+			this.setFocusIndex(row, col);
+		}
+	},
+	previous: function(){
+		// summary:
+		//	focus previous grid cell
+		if(this.cell){
+			var row=(this.rowIndex || 0), col=(this.cell.index || 0) - 1;
+			if(col < 0){
+				col = this.grid.layout.cellCount-1;
+				row--;
+			}
+			if(row < 0){
+				row = 0;
+				col = 0;
+			}
+			if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+				var prevCell = this.grid.getCell(col);
+				if (!this.isFirstFocusCell() && !prevCell.editable){
+					this.cell=prevCell;
+					this.rowIndex=row;
+					this.previous();
+					return;
+				}
+			}
+			this.setFocusIndex(row, col);
+		}
+	},
+	move: function(inRowDelta, inColDelta) {
+		// summary:
+		//	focus grid cell or column header based on position relative to current focus
+		// inRowDelta: int
+		// vertical distance from current focus
+		// inColDelta: int
+		// horizontal distance from current focus
+
+		// Handle column headers.
+		if(this.isNavHeader()){
+			var headers = this._findHeaderCells();
+			var currentIdx = dojo.indexOf(headers, this._colHeadNode);
+			currentIdx += inColDelta;
+			if((currentIdx >= 0) && (currentIdx < headers.length)){
+				this._colHeadNode = headers[currentIdx];
+				this._colHeadFocusIdx = currentIdx;
+				this._scrollHeader(currentIdx);
+				this._colHeadNode.focus();
+			}
+		}else{
+			if(this.cell){
+				// Handle grid proper.
+				var sc = this.grid.scroller,
+					r = this.rowIndex,
+					rc = this.grid.rowCount-1,
+					row = Math.min(rc, Math.max(0, r+inRowDelta));
+				if(inRowDelta){
+					if(inRowDelta>0){
+						if(row > sc.getLastPageRow(sc.page)){
+							//need to load additional data, let scroller do that
+							this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r));
+						}
+					}else if(inRowDelta<0){
+						if(row <= sc.getPageRow(sc.page)){
+							//need to load additional data, let scroller do that
+							this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row));
+						}
+					}
+				}
+				var cc = this.grid.layout.cellCount-1,
+					i = this.cell.index,
+					col = Math.min(cc, Math.max(0, i+inColDelta));
+				this.setFocusIndex(row, col);
+				if(inRowDelta){
+					this.grid.updateRow(r);
+				}
+			}
+		}
+	},
+	previousKey: function(e){
+		if(this.grid.edit.isEditing()){
+			dojo.stopEvent(e);
+			this.previous();
+		}else if(!this.isNavHeader()){
+			this.focusHeader();
+			dojo.stopEvent(e);
+		}else{
+			this.tabOut(this.grid.domNode);
+		}
+	},
+	nextKey: function(e) {
+		var isEmpty = this.grid.rowCount == 0;
+		if(e.target === this.grid.domNode){
+			this.focusHeader();
+			dojo.stopEvent(e);
+		}else if(this.isNavHeader()){
+			// if tabbing from col header, then go to grid proper. If grid is empty this.grid.rowCount == 0
+			this._colHeadNode = this._colHeadFocusIdx= null;
+			if(this.isNoFocusCell() && !isEmpty){
+				this.setFocusIndex(0, 0);
+			}else if(this.cell && !isEmpty){
+				if(this.focusView && !this.focusView.rowNodes[this.rowIndex]){
+				// if rowNode for current index is undefined (likely as a result of a sort and because of #7304) 
+				// scroll to that row
+					this.grid.scrollToRow(this.rowIndex);
+				}
+				this.focusGrid();
+			}else{
+				this.tabOut(this.grid.lastFocusNode);
+			}
+		}else if(this.grid.edit.isEditing()){
+			dojo.stopEvent(e);
+			this.next();
+		}else{
+			this.tabOut(this.grid.lastFocusNode);
+		}
+	},
+	tabOut: function(inFocusNode){
+		this.tabbingOut = true;
+		inFocusNode.focus();
+	},
+	focusGridView: function(){
+		dojox.grid.util.fire(this.focusView, "focus");
+	},
+	focusGrid: function(inSkipFocusCell){
+		this.focusGridView();
+		this._focusifyCellNode(true);
+	},
+	focusHeader: function(){
+		var headerNodes = this._findHeaderCells();
+
+		if (!this._colHeadFocusIdx) {
+			if (this.isNoFocusCell()) {
+				this._colHeadFocusIdx = 0;
+			}
+			else {
+				this._colHeadFocusIdx = this.cell.index;
+			}
+		}
+		this._colHeadNode = headerNodes[this._colHeadFocusIdx];
+		if(this._colHeadNode){
+			dojox.grid.util.fire(this._colHeadNode, "focus");
+			this._focusifyCellNode(false);
+		}
+	},
+	doFocus: function(e){
+		// trap focus only for grid dom node
+		if(e && e.target != e.currentTarget){
+			dojo.stopEvent(e);
+			return;
+		}
+		// do not focus for scrolling if grid is about to blur
+		if(!this.tabbingOut){
+			this.focusHeader();
+		}
+		this.tabbingOut = false;
+		dojo.stopEvent(e);
+	},
+	doBlur: function(e){
+		dojo.stopEvent(e);	// FF2
+	},
+	doBlurHeader: function(e){
+		dojo.stopEvent(e);	// FF2
+	},
+	doLastNodeFocus: function(e){
+		if (this.tabbingOut){
+			this._focusifyCellNode(false);
+		}else if(this.grid.rowCount >0){
+			if (this.isNoFocusCell()){
+				this.setFocusIndex(0,0);
+			}
+			this._focusifyCellNode(true);
+		}else {
+			this.focusHeader();
+		}
+		this.tabbingOut = false;
+		dojo.stopEvent(e);	 // FF2
+	},
+	doLastNodeBlur: function(e){
+		dojo.stopEvent(e);	 // FF2
+	},
+	doColHeaderFocus: function(e){
+		dojo.toggleClass(e.target, this.focusClass, true);
+		this._scrollHeader(this.getHeaderIndex());
+	},
+	doColHeaderBlur: function(e){
+		dojo.toggleClass(e.target, this.focusClass, false);
+	}		
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._EditManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._EditManager"] = true;
+dojo.provide("dojox.grid._EditManager");
+
+
+
+dojo.declare("dojox.grid._EditManager", null, {
+	// summary:
+	//		Controls grid cell editing process. Owned by grid and used internally for editing.
+	constructor: function(inGrid){
+		// inGrid: dojox.Grid
+		//		The dojox.Grid this editor should be attached to
+		this.grid = inGrid;
+		this.connections = [];
+		if(dojo.isIE){
+			this.connections.push(dojo.connect(document.body, "onfocus", dojo.hitch(this, "_boomerangFocus")));
+		}
+	},
+	
+	info: {},
+
+	destroy: function(){
+		dojo.forEach(this.connections,dojo.disconnect);
+	},
+
+	cellFocus: function(inCell, inRowIndex){
+		// summary:
+		//		Invoke editing when cell is focused
+		// inCell: cell object
+		//		Grid cell object
+		// inRowIndex: Integer
+		//		Grid row index
+		if(this.grid.singleClickEdit || this.isEditRow(inRowIndex)){
+			// if same row or quick editing, edit
+			this.setEditCell(inCell, inRowIndex);
+		}else{
+			// otherwise, apply any pending row edits
+			this.apply();
+		}
+		// if dynamic or static editing...
+		if(this.isEditing() || (inCell && inCell.editable && inCell.alwaysEditing)){
+			// let the editor focus itself as needed
+			this._focusEditor(inCell, inRowIndex);
+		}
+	},
+
+	rowClick: function(e){
+		if(this.isEditing() && !this.isEditRow(e.rowIndex)){
+			this.apply();
+		}
+	},
+
+	styleRow: function(inRow){
+		if(inRow.index == this.info.rowIndex){
+			inRow.customClasses += ' dojoxGridRowEditing';
+		}
+	},
+
+	dispatchEvent: function(e){
+		var c = e.cell, ed = (c && c["editable"]) ? c : 0;
+		return ed && ed.dispatchEvent(e.dispatch, e);
+	},
+
+	// Editing
+	isEditing: function(){
+		// summary:
+		//		Indicates editing state of the grid.
+		// returns: Boolean
+		//	 	True if grid is actively editing
+		return this.info.rowIndex !== undefined;
+	},
+
+	isEditCell: function(inRowIndex, inCellIndex){
+		// summary:
+		//		Indicates if the given cell is being edited.
+		// inRowIndex: Integer
+		//		Grid row index
+		// inCellIndex: Integer
+		//		Grid cell index
+		// returns: Boolean
+		//	 	True if given cell is being edited
+		return (this.info.rowIndex === inRowIndex) && (this.info.cell.index == inCellIndex);
+	},
+
+	isEditRow: function(inRowIndex){
+		// summary:
+		//		Indicates if the given row is being edited.
+		// inRowIndex: Integer
+		//		Grid row index
+		// returns: Boolean
+		//	 	True if given row is being edited
+		return this.info.rowIndex === inRowIndex;
+	},
+
+	setEditCell: function(inCell, inRowIndex){
+		// summary:
+		//		Set the given cell to be edited
+		// inRowIndex: Integer
+		//		Grid row index
+		// inCell: Object
+		//		Grid cell object
+		if(!this.isEditCell(inRowIndex, inCell.index) && this.grid.canEdit && this.grid.canEdit(inCell, inRowIndex)){
+			this.start(inCell, inRowIndex, this.isEditRow(inRowIndex) || inCell.editable);
+		}
+	},
+
+	_focusEditor: function(inCell, inRowIndex){
+		dojox.grid.util.fire(inCell, "focus", [inRowIndex]);
+	},
+
+	focusEditor: function(){
+		if(this.isEditing()){
+			this._focusEditor(this.info.cell, this.info.rowIndex);
+		}
+	},
+
+	// implement fix for focus boomerang effect on IE
+	_boomerangWindow: 500,
+	_shouldCatchBoomerang: function(){
+		return this._catchBoomerang > new Date().getTime();
+	},
+	_boomerangFocus: function(){
+		//
+		if(this._shouldCatchBoomerang()){
+			// make sure we don't utterly lose focus
+			this.grid.focus.focusGrid();
+			// let the editor focus itself as needed
+			this.focusEditor();
+			// only catch once
+			this._catchBoomerang = 0;
+		}
+	},
+	_doCatchBoomerang: function(){
+		// give ourselves a few ms to boomerang IE focus effects
+		if(dojo.isIE){this._catchBoomerang = new Date().getTime() + this._boomerangWindow;}
+	},
+	// end boomerang fix API
+
+	start: function(inCell, inRowIndex, inEditing){
+		this.grid.beginUpdate();
+		this.editorApply();
+		if(this.isEditing() && !this.isEditRow(inRowIndex)){
+			this.applyRowEdit();
+			this.grid.updateRow(inRowIndex);
+		}
+		if(inEditing){
+			this.info = { cell: inCell, rowIndex: inRowIndex };
+			this.grid.doStartEdit(inCell, inRowIndex); 
+			this.grid.updateRow(inRowIndex);
+		}else{
+			this.info = {};
+		}
+		this.grid.endUpdate();
+		// make sure we don't utterly lose focus
+		this.grid.focus.focusGrid();
+		// let the editor focus itself as needed
+		this._focusEditor(inCell, inRowIndex);
+		// give ourselves a few ms to boomerang IE focus effects
+		this._doCatchBoomerang();
+	},
+
+	_editorDo: function(inMethod){
+		var c = this.info.cell
+		//c && c.editor && c.editor[inMethod](c, this.info.rowIndex);
+		c && c.editable && c[inMethod](this.info.rowIndex);
+	},
+
+	editorApply: function(){
+		this._editorDo("apply");
+	},
+
+	editorCancel: function(){
+		this._editorDo("cancel");
+	},
+
+	applyCellEdit: function(inValue, inCell, inRowIndex){
+		if(this.grid.canEdit(inCell, inRowIndex)){
+			this.grid.doApplyCellEdit(inValue, inRowIndex, inCell.field);
+		}
+	},
+
+	applyRowEdit: function(){
+		this.grid.doApplyEdit(this.info.rowIndex, this.info.cell.field);
+	},
+
+	apply: function(){
+		// summary:
+		//		Apply a grid edit
+		if(this.isEditing()){
+			this.grid.beginUpdate();
+			this.editorApply();
+			this.applyRowEdit();
+			this.info = {};
+			this.grid.endUpdate();
+			this.grid.focus.focusGrid();
+			this._doCatchBoomerang();
+		}
+	},
+
+	cancel: function(){
+		// summary:
+		//		Cancel a grid edit
+		if(this.isEditing()){
+			this.grid.beginUpdate();
+			this.editorCancel();
+			this.info = {};
+			this.grid.endUpdate();
+			this.grid.focus.focusGrid();
+			this._doCatchBoomerang();
+		}
+	},
+
+	save: function(inRowIndex, inView){
+		// summary:
+		//		Save the grid editing state
+		// inRowIndex: Integer
+		//		Grid row index
+		// inView: Object
+		//		Grid view
+		var c = this.info.cell;
+		if(this.isEditRow(inRowIndex) && (!inView || c.view==inView) && c.editable){
+			c.save(c, this.info.rowIndex);
+		}
+	},
+
+	restore: function(inView, inRowIndex){
+		// summary:
+		//		Restores the grid editing state
+		// inRowIndex: Integer
+		//		Grid row index
+		// inView: Object
+		//		Grid view
+		var c = this.info.cell;
+		if(this.isEditRow(inRowIndex) && c.view == inView && c.editable){
+			c.restore(c, this.info.rowIndex);
+		}
+	}
+});
+
+}
+
+if(!dojo._hasResource['dojox.grid.Selection']){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource['dojox.grid.Selection'] = true;
+dojo.provide('dojox.grid.Selection');
+
+dojo.declare("dojox.grid.Selection", null, {
+	// summary:
+	//		Manages row selection for grid. Owned by grid and used internally
+	//		for selection. Override to implement custom selection.
+
+	constructor: function(inGrid){
+		this.grid = inGrid;
+		this.selected = [];
+
+		this.setMode(inGrid.selectionMode);
+	},
+
+	mode: 'extended',
+
+	selected: null,
+	updating: 0,
+	selectedIndex: -1,
+
+	setMode: function(mode){
+		if(this.selected.length){
+			this.deselectAll();
+		}
+		if(mode != 'extended' && mode != 'multiple' && mode != 'single' && mode != 'none'){
+			this.mode = 'extended';
+		}else{
+			this.mode = mode;
+		}
+	},
+
+	onCanSelect: function(inIndex){
+		return this.grid.onCanSelect(inIndex);
+	},
+
+	onCanDeselect: function(inIndex){
+		return this.grid.onCanDeselect(inIndex);
+	},
+
+	onSelected: function(inIndex){
+	},
+
+	onDeselected: function(inIndex){
+	},
+
+	//onSetSelected: function(inIndex, inSelect) { };
+	onChanging: function(){
+	},
+
+	onChanged: function(){
+	},
+
+	isSelected: function(inIndex){
+		if(this.mode == 'none'){
+			return false;
+		}
+		return this.selected[inIndex];
+	},
+
+	getFirstSelected: function(){
+		if(!this.selected.length||this.mode == 'none'){ return -1; }
+		for(var i=0, l=this.selected.length; i<l; i++){
+			if(this.selected[i]){
+				return i;
+			}
+		}
+		return -1;
+	},
+
+	getNextSelected: function(inPrev){
+		if(this.mode == 'none'){ return -1; }
+		for(var i=inPrev+1, l=this.selected.length; i<l; i++){
+			if(this.selected[i]){
+				return i;
+			}
+		}
+		return -1;
+	},
+
+	getSelected: function(){
+		var result = [];
+		for(var i=0, l=this.selected.length; i<l; i++){
+			if(this.selected[i]){
+				result.push(i);
+			}
+		}
+		return result;
+	},
+
+	getSelectedCount: function(){
+		var c = 0;
+		for(var i=0; i<this.selected.length; i++){
+			if(this.selected[i]){
+				c++;
+			}
+		}
+		return c;
+	},
+
+	_beginUpdate: function(){
+		if(this.updating == 0){
+			this.onChanging();
+		}
+		this.updating++;
+	},
+
+	_endUpdate: function(){
+		this.updating--;
+		if(this.updating == 0){
+			this.onChanged();
+		}
+	},
+
+	select: function(inIndex){
+		if(this.mode == 'none'){ return; }
+		if(this.mode != 'multiple'){
+			this.deselectAll(inIndex);
+			this.addToSelection(inIndex);
+		}else{
+			this.toggleSelect(inIndex);
+		}
+	},
+
+	addToSelection: function(inIndex){
+		if(this.mode == 'none'){ return; }
+		inIndex = Number(inIndex);
+		if(this.selected[inIndex]){
+			this.selectedIndex = inIndex;
+		}else{
+			if(this.onCanSelect(inIndex) !== false){
+				this.selectedIndex = inIndex;
+				this._beginUpdate();
+				this.selected[inIndex] = true;
+				//this.grid.onSelected(inIndex);
+				this.onSelected(inIndex);
+				//this.onSetSelected(inIndex, true);
+				this._endUpdate();
+			}
+		}
+	},
+
+	deselect: function(inIndex){
+		if(this.mode == 'none'){ return; }
+		inIndex = Number(inIndex);
+		if(this.selectedIndex == inIndex){
+			this.selectedIndex = -1;
+		}
+		if(this.selected[inIndex]){
+			if(this.onCanDeselect(inIndex) === false){
+				return;
+			}
+			this._beginUpdate();
+			delete this.selected[inIndex];
+			//this.grid.onDeselected(inIndex);
+			this.onDeselected(inIndex);
+			//this.onSetSelected(inIndex, false);
+			this._endUpdate();
+		}
+	},
+
+	setSelected: function(inIndex, inSelect){
+		this[(inSelect ? 'addToSelection' : 'deselect')](inIndex);
+	},
+
+	toggleSelect: function(inIndex){
+		this.setSelected(inIndex, !this.selected[inIndex])
+	},
+
+	_range: function(inFrom, inTo, func){
+		var s = (inFrom >= 0 ? inFrom : inTo), e = inTo;
+		if(s > e){
+			e = s;
+			s = inTo;
+		}
+		for(var i=s; i<=e; i++){
+			func(i);
+		}
+	},
+
+	selectRange: function(inFrom, inTo){
+		this._range(inFrom, inTo, dojo.hitch(this, "addToSelection"));
+	},
+
+	deselectRange: function(inFrom, inTo){
+		this._range(inFrom, inTo, dojo.hitch(this, "deselect"));
+	},
+
+	insert: function(inIndex){
+		this.selected.splice(inIndex, 0, false);
+		if(this.selectedIndex >= inIndex){
+			this.selectedIndex++;
+		}
+	},
+
+	remove: function(inIndex){
+		this.selected.splice(inIndex, 1);
+		if(this.selectedIndex >= inIndex){
+			this.selectedIndex--;
+		}
+	},
+
+	deselectAll: function(inExcept){
+		for(var i in this.selected){
+			if((i!=inExcept)&&(this.selected[i]===true)){
+				this.deselect(i);
+			}
+		}
+	},
+
+	clickSelect: function(inIndex, inCtrlKey, inShiftKey){
+		if(this.mode == 'none'){ return; }
+		this._beginUpdate();
+		if(this.mode != 'extended'){
+			this.select(inIndex);
+		}else{
+			var lastSelected = this.selectedIndex;
+			if(!inCtrlKey){
+				this.deselectAll(inIndex);
+			}
+			if(inShiftKey){
+				this.selectRange(lastSelected, inIndex);
+			}else if(inCtrlKey){
+				this.toggleSelect(inIndex);
+			}else{
+				this.addToSelection(inIndex)
+			}
+		}
+		this._endUpdate();
+	},
+
+	clickSelectEvent: function(e){
+		this.clickSelect(e.rowIndex, dojo.dnd.getCopyKeyState(e), e.shiftKey);
+	},
+
+	clear: function(){
+		this._beginUpdate();
+		this.deselectAll();
+		this._endUpdate();
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid._Events"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Events"] = true;
+dojo.provide("dojox.grid._Events");
+
+dojo.declare("dojox.grid._Events", null, {
+	// summary:
+	//		_Grid mixin that provides default implementations for grid events.
+	// description: 
+	//		Default synthetic events dispatched for _Grid. dojo.connect to events to
+	//		retain default implementation or override them for custom handling.
+	
+	// cellOverClass: String
+	// 		css class to apply to grid cells over which the cursor is placed.
+	cellOverClass: "dojoxGridCellOver",
+	
+	onKeyEvent: function(e){
+		// summary: top level handler for Key Events
+		this.dispatchKeyEvent(e);
+	},
+
+	onContentEvent: function(e){
+		// summary: Top level handler for Content events
+		this.dispatchContentEvent(e);
+	},
+
+	onHeaderEvent: function(e){
+		// summary: Top level handler for header events
+		this.dispatchHeaderEvent(e);
+	},
+
+	onStyleRow: function(inRow){
+		// summary:
+		//		Perform row styling on a given row. Called whenever row styling is updated.
+		//
+		// inRow: Object
+		// 		Object containing row state information: selected, true if the row is selcted; over:
+		// 		true of the mouse is over the row; odd: true if the row is odd. Use customClasses and
+		// 		customStyles to control row css classes and styles; both properties are strings.
+		//
+		// example: onStyleRow({ selected: true, over:true, odd:false })
+		var i = inRow;
+		i.customClasses += (i.odd?" dojoxGridRowOdd":"") + (i.selected?" dojoxGridRowSelected":"") + (i.over?" dojoxGridRowOver":"");
+		this.focus.styleRow(inRow);
+		this.edit.styleRow(inRow);
+	},
+	
+	onKeyDown: function(e){
+		// summary:
+		// 		Grid key event handler. By default enter begins editing and applies edits, escape cancels an edit,
+		// 		tab, shift-tab, and arrow keys move grid cell focus.
+		if(e.altKey || e.metaKey){
+			return;
+		}
+		var dk = dojo.keys;
+		switch(e.keyCode){
+			case dk.ESCAPE:
+				this.edit.cancel();
+				break;
+			case dk.ENTER:
+				if(!this.edit.isEditing()){
+					var colIdx = this.focus.getHeaderIndex();
+					if(colIdx >= 0) {
+						this.setSortIndex(colIdx);
+						break;
+					}else {
+						this.selection.clickSelect(this.focus.rowIndex, dojo.dnd.getCopyKeyState(e), e.shiftKey);
+					}
+					dojo.stopEvent(e);
+				}
+				if(!e.shiftKey){
+					var isEditing = this.edit.isEditing();
+					this.edit.apply();
+					if(!isEditing){
+						this.edit.setEditCell(this.focus.cell, this.focus.rowIndex);
+					}
+				}
+				if (!this.edit.isEditing()){
+					var curView = this.focus.focusView || this.views.views[0];  //if no focusView than only one view
+					curView.content.decorateEvent(e);
+					this.onRowClick(e);
+				}
+				break;
+			case dk.SPACE:
+				if(!this.edit.isEditing()){
+					var colIdx = this.focus.getHeaderIndex();
+					if(colIdx >= 0) {
+						this.setSortIndex(colIdx);
+						break;
+					}else {
+						this.selection.clickSelect(this.focus.rowIndex, dojo.dnd.getCopyKeyState(e), e.shiftKey);
+					}
+					dojo.stopEvent(e);
+				}
+				break;
+			case dk.TAB:
+				this.focus[e.shiftKey ? 'previousKey' : 'nextKey'](e);
+				break;
+			case dk.LEFT_ARROW:
+			case dk.RIGHT_ARROW:
+				if(!this.edit.isEditing()){
+					dojo.stopEvent(e);
+					var offset = (e.keyCode == dk.LEFT_ARROW) ? 1 : -1;
+					if(dojo._isBodyLtr()){ offset *= -1; }
+					this.focus.move(0, offset);
+				}
+				break;
+			case dk.UP_ARROW:
+				if(!this.edit.isEditing() && this.focus.rowIndex != 0){
+					dojo.stopEvent(e);
+					this.focus.move(-1, 0);
+				}
+				break;
+			case dk.DOWN_ARROW:
+				if(!this.edit.isEditing() && this.store && this.focus.rowIndex+1 != this.rowCount){
+					dojo.stopEvent(e);
+					this.focus.move(1, 0);
+				}
+				break;
+			case dk.PAGE_UP:
+				if(!this.edit.isEditing() && this.focus.rowIndex != 0){
+					dojo.stopEvent(e);
+					if(this.focus.rowIndex != this.scroller.firstVisibleRow+1){
+						this.focus.move(this.scroller.firstVisibleRow-this.focus.rowIndex, 0);
+					}else{
+						this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex-1));
+						this.focus.move(this.scroller.firstVisibleRow-this.scroller.lastVisibleRow+1, 0);
+					}
+				}
+				break;
+			case dk.PAGE_DOWN:
+				if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.rowCount){
+					dojo.stopEvent(e);
+					if(this.focus.rowIndex != this.scroller.lastVisibleRow-1){
+						this.focus.move(this.scroller.lastVisibleRow-this.focus.rowIndex-1, 0);
+					}else{
+						this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex+1));
+						this.focus.move(this.scroller.lastVisibleRow-this.scroller.firstVisibleRow-1, 0);
+					}
+				}
+				break;
+		}
+	},
+	
+	onMouseOver: function(e){
+		// summary:
+		//		Event fired when mouse is over the grid.
+		// e: Event
+		//		Decorated event object contains reference to grid, cell, and rowIndex
+		e.rowIndex == -1 ? this.onHeaderCellMouseOver(e) : this.onCellMouseOver(e);
+	},
+	
+	onMouseOut: function(e){
+		// summary:
+		//		Event fired when mouse moves out of the grid.
+		// e: Event
+		//		Decorated event object that contains reference to grid, cell, and rowIndex
+		e.rowIndex == -1 ? this.onHeaderCellMouseOut(e) : this.onCellMouseOut(e);
+	},
+	
+	onMouseDown: function(e){
+		// summary:
+		//		Event fired when mouse is down inside grid.
+		// e: Event
+		//		Decorated event object that contains reference to grid, cell, and rowIndex
+		e.rowIndex == -1 ? this.onHeaderCellMouseDown(e) : this.onCellMouseDown(e);
+	},
+	
+	onMouseOverRow: function(e){
+		// summary:
+		//		Event fired when mouse is over any row (data or header).
+		// e: Event
+		//		Decorated event object contains reference to grid, cell, and rowIndex
+		if(!this.rows.isOver(e.rowIndex)){
+			this.rows.setOverRow(e.rowIndex);
+			e.rowIndex == -1 ? this.onHeaderMouseOver(e) : this.onRowMouseOver(e);
+		}
+	},
+	onMouseOutRow: function(e){
+		// summary:
+		//		Event fired when mouse moves out of any row (data or header).
+		// e: Event
+		//		Decorated event object contains reference to grid, cell, and rowIndex
+		if(this.rows.isOver(-1)){
+			this.onHeaderMouseOut(e);
+		}else if(!this.rows.isOver(-2)){
+			this.rows.setOverRow(-2);
+			this.onRowMouseOut(e);
+		}
+	},
+	
+	onMouseDownRow: function(e){
+		// summary:
+		//		Event fired when mouse is down inside grid row
+		// e: Event
+		//		Decorated event object that contains reference to grid, cell, and rowIndex
+		if(e.rowIndex != -1)
+			this.onRowMouseDown(e);
+	},
+
+	// cell events
+	onCellMouseOver: function(e){
+		// summary:
+		//		Event fired when mouse is over a cell.
+		// e: Event
+		//		Decorated event object contains reference to grid, cell, and rowIndex
+		if(e.cellNode){
+			dojo.addClass(e.cellNode, this.cellOverClass);
+		}
+	},
+	
+	onCellMouseOut: function(e){
+		// summary:
+		//		Event fired when mouse moves out of a cell.
+		// e: Event
+		//		Decorated event object which contains reference to grid, cell, and rowIndex
+		if(e.cellNode){
+			dojo.removeClass(e.cellNode, this.cellOverClass);
+		}
+	},
+	
+	onCellMouseDown: function(e){
+		// summary:
+		//		Event fired when mouse is down in a header cell.
+		// e: Event
+		// 		Decorated event object which contains reference to grid, cell, and rowIndex
+	},
+
+	onCellClick: function(e){
+		// summary:
+		//		Event fired when a cell is clicked.
+		// e: Event
+		//		Decorated event object which contains reference to grid, cell, and rowIndex
+		this._click[0] = this._click[1];
+		this._click[1] = e;
+		if(!this.edit.isEditCell(e.rowIndex, e.cellIndex)){
+			this.focus.setFocusCell(e.cell, e.rowIndex);
+		}
+		this.onRowClick(e);
+	},
+
+	onCellDblClick: function(e){
+		// summary:
+		//		Event fired when a cell is double-clicked.
+		// e: Event
+		//		Decorated event object contains reference to grid, cell, and rowIndex
+		if(dojo.isIE){
+			this.edit.setEditCell(this._click[1].cell, this._click[1].rowIndex);
+		}else if(this._click[0].rowIndex != this._click[1].rowIndex){
+			this.edit.setEditCell(this._click[0].cell, this._click[0].rowIndex);
+		}else{
+			this.edit.setEditCell(e.cell, e.rowIndex);
+		}
+		this.onRowDblClick(e);
+	},
+
+	onCellContextMenu: function(e){
+		// summary:
+		//		Event fired when a cell context menu is accessed via mouse right click.
+		// e: Event
+		//		Decorated event object which contains reference to grid, cell, and rowIndex
+		this.onRowContextMenu(e);
+	},
+
+	onCellFocus: function(inCell, inRowIndex){
+		// summary:
+		//		Event fired when a cell receives focus.
+		// inCell: Object
+		//		Cell object containing properties of the grid column.
+		// inRowIndex: Integer
+		//		Index of the grid row
+		this.edit.cellFocus(inCell, inRowIndex);
+	},
+
+	// row events
+	onRowClick: function(e){
+		// summary:
+		//		Event fired when a row is clicked.
+		// e: Event
+		//		Decorated event object which contains reference to grid, cell, and rowIndex
+		this.edit.rowClick(e);
+		this.selection.clickSelectEvent(e);
+	},
+
+	onRowDblClick: function(e){
+		// summary:
+		//		Event fired when a row is double clicked.
+		// e: Event
+		//		decorated event object which contains reference to grid, cell, and rowIndex
+	},
+
+	onRowMouseOver: function(e){
+		// summary:
+		//		Event fired when mouse moves over a data row.
+		// e: Event
+		//		Decorated event object which contains reference to grid, cell, and rowIndex
+	},
+
+	onRowMouseOut: function(e){
+		// summary:
+		//		Event fired when mouse moves out of a data row.
+		// e: Event
+		// 		Decorated event object contains reference to grid, cell, and rowIndex
+	},
+	
+	onRowMouseDown: function(e){
+		// summary:
+		//		Event fired when mouse is down in a row.
+		// e: Event
+		// 		Decorated event object which contains reference to grid, cell, and rowIndex
+	},
+
+	onRowContextMenu: function(e){
+		// summary:
+		//		Event fired when a row context menu is accessed via mouse right click.
+		// e: Event
+		// 		Decorated event object which contains reference to grid, cell, and rowIndex
+		dojo.stopEvent(e);
+	},
+
+	// header events
+	onHeaderMouseOver: function(e){
+		// summary:
+		//		Event fired when mouse moves over the grid header.
+		// e: Event
+		// 		Decorated event object contains reference to grid, cell, and rowIndex
+	},
+
+	onHeaderMouseOut: function(e){
+		// summary:
+		//		Event fired when mouse moves out of the grid header.
+		// e: Event
+		// 		Decorated event object which contains reference to grid, cell, and rowIndex
+	},
+
+	onHeaderCellMouseOver: function(e){
+		// summary:
+		//		Event fired when mouse moves over a header cell.
+		// e: Event
+		// 		Decorated event object which contains reference to grid, cell, and rowIndex
+		if(e.cellNode){
+			dojo.addClass(e.cellNode, this.cellOverClass);
+		}
+	},
+
+	onHeaderCellMouseOut: function(e){
+		// summary:
+		//		Event fired when mouse moves out of a header cell.
+		// e: Event
+		// 		Decorated event object which contains reference to grid, cell, and rowIndex
+		if(e.cellNode){
+			dojo.removeClass(e.cellNode, this.cellOverClass);
+		}
+	},
+	
+	onHeaderCellMouseDown: function(e) {
+		// summary:
+		//		Event fired when mouse is down in a header cell.
+		// e: Event
+		// 		Decorated event object which contains reference to grid, cell, and rowIndex
+	},
+
+	onHeaderClick: function(e){
+		// summary:
+		//		Event fired when the grid header is clicked.
+		// e: Event
+		// Decorated event object which contains reference to grid, cell, and rowIndex
+	},
+
+	onHeaderCellClick: function(e){
+		// summary:
+		//		Event fired when a header cell is clicked.
+		// e: Event
+		//		Decorated event object which contains reference to grid, cell, and rowIndex
+		this.setSortIndex(e.cell.index);
+		this.onHeaderClick(e);
+	},
+
+	onHeaderDblClick: function(e){
+		// summary:
+		//		Event fired when the grid header is double clicked.
+		// e: Event
+		//		Decorated event object which contains reference to grid, cell, and rowIndex
+	},
+
+	onHeaderCellDblClick: function(e){
+		// summary:
+		//		Event fired when a header cell is double clicked.
+		// e: Event
+		//		Decorated event object which contains reference to grid, cell, and rowIndex
+		this.onHeaderDblClick(e);
+	},
+
+	onHeaderCellContextMenu: function(e){
+		// summary:
+		//		Event fired when a header cell context menu is accessed via mouse right click.
+		// e: Event
+		//		Decorated event object which contains reference to grid, cell, and rowIndex
+		this.onHeaderContextMenu(e);
+	},
+
+	onHeaderContextMenu: function(e){
+		// summary:
+		//		Event fired when the grid header context menu is accessed via mouse right click.
+		// e: Event
+		//		Decorated event object which contains reference to grid, cell, and rowIndex
+		if(!this.headerMenu){
+			dojo.stopEvent(e);
+		}
+	},
+
+	// editing
+	onStartEdit: function(inCell, inRowIndex){
+		// summary:
+		//		Event fired when editing is started for a given grid cell
+		// inCell: Object
+		//		Cell object containing properties of the grid column.
+		// inRowIndex: Integer
+		//		Index of the grid row
+	},
+
+	onApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){
+		// summary:
+		//		Event fired when editing is applied for a given grid cell
+		// inValue: String
+		//		Value from cell editor
+		// inRowIndex: Integer
+		//		Index of the grid row
+		// inFieldIndex: Integer
+		//		Index in the grid's data store
+	},
+
+	onCancelEdit: function(inRowIndex){
+		// summary:
+		//		Event fired when editing is cancelled for a given grid cell
+		// inRowIndex: Integer
+		//		Index of the grid row
+	},
+
+	onApplyEdit: function(inRowIndex){
+		// summary:
+		//		Event fired when editing is applied for a given grid row
+		// inRowIndex: Integer
+		//		Index of the grid row
+	},
+
+	onCanSelect: function(inRowIndex){
+		// summary:
+		//		Event to determine if a grid row may be selected
+		// inRowIndex: Integer
+		//		Index of the grid row
+		// returns: Boolean
+		//		true if the row can be selected
+		return true;
+	},
+
+	onCanDeselect: function(inRowIndex){
+		// summary:
+		//		Event to determine if a grid row may be deselected
+		// inRowIndex: Integer
+		//		Index of the grid row
+		// returns: Boolean
+		//		true if the row can be deselected
+		return true;
+	},
+
+	onSelected: function(inRowIndex){
+		// summary:
+		//		Event fired when a grid row is selected
+		// inRowIndex: Integer
+		//		Index of the grid row
+		this.updateRowStyles(inRowIndex);
+	},
+
+	onDeselected: function(inRowIndex){
+		// summary:
+		//		Event fired when a grid row is deselected
+		// inRowIndex: Integer
+		//		Index of the grid row
+		this.updateRowStyles(inRowIndex);
+	},
+
+	onSelectionChanged: function(){
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojo.i18n"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.i18n"] = true;
+dojo.provide("dojo.i18n");
+
+/*=====
+dojo.i18n = {
+	// summary: Utility classes to enable loading of resources for internationalization (i18n)
+};
+=====*/
+
+dojo.i18n.getLocalization = function(/*String*/packageName, /*String*/bundleName, /*String?*/locale){
+	//	summary:
+	//		Returns an Object containing the localization for a given resource
+	//		bundle in a package, matching the specified locale.
+	//	description:
+	//		Returns a hash containing name/value pairs in its prototypesuch
+	//		that values can be easily overridden.  Throws an exception if the
+	//		bundle is not found.  Bundle must have already been loaded by
+	//		`dojo.requireLocalization()` or by a build optimization step.  NOTE:
+	//		try not to call this method as part of an object property
+	//		definition (`var foo = { bar: dojo.i18n.getLocalization() }`).  In
+	//		some loading situations, the bundle may not be available in time
+	//		for the object definition.  Instead, call this method inside a
+	//		function that is run after all modules load or the page loads (like
+	//		in `dojo.addOnLoad()`), or in a widget lifecycle method.
+	//	packageName:
+	//		package which is associated with this resource
+	//	bundleName:
+	//		the base filename of the resource bundle (without the ".js" suffix)
+	//	locale:
+	//		the variant to load (optional).  By default, the locale defined by
+	//		the host environment: dojo.locale
+
+	locale = dojo.i18n.normalizeLocale(locale);
+
+	// look for nearest locale match
+	var elements = locale.split('-');
+	var module = [packageName,"nls",bundleName].join('.');
+	var bundle = dojo._loadedModules[module];
+	if(bundle){
+		var localization;
+		for(var i = elements.length; i > 0; i--){
+			var loc = elements.slice(0, i).join('_');
+			if(bundle[loc]){
+				localization = bundle[loc];
+				break;
+			}
+		}
+		if(!localization){
+			localization = bundle.ROOT;
+		}
+
+		// make a singleton prototype so that the caller won't accidentally change the values globally
+		if(localization){
+			var clazz = function(){};
+			clazz.prototype = localization;
+			return new clazz(); // Object
+		}
+	}
+
+	throw new Error("Bundle not found: " + bundleName + " in " + packageName+" , locale=" + locale);
+};
+
+dojo.i18n.normalizeLocale = function(/*String?*/locale){
+	//	summary:
+	//		Returns canonical form of locale, as used by Dojo.
+	//
+	//  description:
+	//		All variants are case-insensitive and are separated by '-' as specified in [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt).
+	//		If no locale is specified, the dojo.locale is returned.  dojo.locale is defined by
+	//		the user agent's locale unless overridden by djConfig.
+
+	var result = locale ? locale.toLowerCase() : dojo.locale;
+	if(result == "root"){
+		result = "ROOT";
+	}
+	return result; // String
+};
+
+dojo.i18n._requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String?*/availableFlatLocales){
+	//	summary:
+	//		See dojo.requireLocalization()
+	//	description:
+	// 		Called by the bootstrap, but factored out so that it is only
+	// 		included in the build when needed.
+
+	var targetLocale = dojo.i18n.normalizeLocale(locale);
+ 	var bundlePackage = [moduleName, "nls", bundleName].join(".");
+	// NOTE: 
+	//		When loading these resources, the packaging does not match what is
+	//		on disk.  This is an implementation detail, as this is just a
+	//		private data structure to hold the loaded resources.  e.g.
+	//		`tests/hello/nls/en-us/salutations.js` is loaded as the object
+	//		`tests.hello.nls.salutations.en_us={...}` The structure on disk is
+	//		intended to be most convenient for developers and translators, but
+	//		in memory it is more logical and efficient to store in a different
+	//		order.  Locales cannot use dashes, since the resulting path will
+	//		not evaluate as valid JS, so we translate them to underscores.
+	
+	//Find the best-match locale to load if we have available flat locales.
+	var bestLocale = "";
+	if(availableFlatLocales){
+		var flatLocales = availableFlatLocales.split(",");
+		for(var i = 0; i < flatLocales.length; i++){
+			//Locale must match from start of string.
+			//Using ["indexOf"] so customBase builds do not see
+			//this as a dojo._base.array dependency.
+			if(targetLocale["indexOf"](flatLocales[i]) == 0){
+				if(flatLocales[i].length > bestLocale.length){
+					bestLocale = flatLocales[i];
+				}
+			}
+		}
+		if(!bestLocale){
+			bestLocale = "ROOT";
+		}		
+	}
+
+	//See if the desired locale is already loaded.
+	var tempLocale = availableFlatLocales ? bestLocale : targetLocale;
+	var bundle = dojo._loadedModules[bundlePackage];
+	var localizedBundle = null;
+	if(bundle){
+		if(dojo.config.localizationComplete && bundle._built){return;}
+		var jsLoc = tempLocale.replace(/-/g, '_');
+		var translationPackage = bundlePackage+"."+jsLoc;
+		localizedBundle = dojo._loadedModules[translationPackage];
+	}
+
+	if(!localizedBundle){
+		bundle = dojo["provide"](bundlePackage);
+		var syms = dojo._getModuleSymbols(moduleName);
+		var modpath = syms.concat("nls").join("/");
+		var parent;
+
+		dojo.i18n._searchLocalePath(tempLocale, availableFlatLocales, function(loc){
+			var jsLoc = loc.replace(/-/g, '_');
+			var translationPackage = bundlePackage + "." + jsLoc;
+			var loaded = false;
+			if(!dojo._loadedModules[translationPackage]){
+				// Mark loaded whether it's found or not, so that further load attempts will not be made
+				dojo["provide"](translationPackage);
+				var module = [modpath];
+				if(loc != "ROOT"){module.push(loc);}
+				module.push(bundleName);
+				var filespec = module.join("/") + '.js';
+				loaded = dojo._loadPath(filespec, null, function(hash){
+					// Use singleton with prototype to point to parent bundle, then mix-in result from loadPath
+					var clazz = function(){};
+					clazz.prototype = parent;
+					bundle[jsLoc] = new clazz();
+					for(var j in hash){ bundle[jsLoc][j] = hash[j]; }
+				});
+			}else{
+				loaded = true;
+			}
+			if(loaded && bundle[jsLoc]){
+				parent = bundle[jsLoc];
+			}else{
+				bundle[jsLoc] = parent;
+			}
+			
+			if(availableFlatLocales){
+				//Stop the locale path searching if we know the availableFlatLocales, since
+				//the first call to this function will load the only bundle that is needed.
+				return true;
+			}
+		});
+	}
+
+	//Save the best locale bundle as the target locale bundle when we know the
+	//the available bundles.
+	if(availableFlatLocales && targetLocale != bestLocale){
+		bundle[targetLocale.replace(/-/g, '_')] = bundle[bestLocale.replace(/-/g, '_')];
+	}
+};
+
+(function(){
+	// If other locales are used, dojo.requireLocalization should load them as
+	// well, by default. 
+	// 
+	// Override dojo.requireLocalization to do load the default bundle, then
+	// iterate through the extraLocale list and load those translations as
+	// well, unless a particular locale was requested.
+
+	var extra = dojo.config.extraLocale;
+	if(extra){
+		if(!extra instanceof Array){
+			extra = [extra];
+		}
+
+		var req = dojo.i18n._requireLocalization;
+		dojo.i18n._requireLocalization = function(m, b, locale, availableFlatLocales){
+			req(m,b,locale, availableFlatLocales);
+			if(locale){return;}
+			for(var i=0; i<extra.length; i++){
+				req(m,b,extra[i], availableFlatLocales);
+			}
+		};
+	}
+})();
+
+dojo.i18n._searchLocalePath = function(/*String*/locale, /*Boolean*/down, /*Function*/searchFunc){
+	//	summary:
+	//		A helper method to assist in searching for locale-based resources.
+	//		Will iterate through the variants of a particular locale, either up
+	//		or down, executing a callback function.  For example, "en-us" and
+	//		true will try "en-us" followed by "en" and finally "ROOT".
+
+	locale = dojo.i18n.normalizeLocale(locale);
+
+	var elements = locale.split('-');
+	var searchlist = [];
+	for(var i = elements.length; i > 0; i--){
+		searchlist.push(elements.slice(0, i).join('-'));
+	}
+	searchlist.push(false);
+	if(down){searchlist.reverse();}
+
+	for(var j = searchlist.length - 1; j >= 0; j--){
+		var loc = searchlist[j] || "ROOT";
+		var stop = searchFunc(loc);
+		if(stop){ break; }
+	}
+};
+
+dojo.i18n._preloadLocalizations = function(/*String*/bundlePrefix, /*Array*/localesGenerated){
+	//	summary:
+	//		Load built, flattened resource bundles, if available for all
+	//		locales used in the page. Only called by built layer files.
+
+	function preload(locale){
+		locale = dojo.i18n.normalizeLocale(locale);
+		dojo.i18n._searchLocalePath(locale, true, function(loc){
+			for(var i=0; i<localesGenerated.length;i++){
+				if(localesGenerated[i] == loc){
+					dojo["require"](bundlePrefix+"_"+loc);
+					return true; // Boolean
+				}
+			}
+			return false; // Boolean
+		});
+	}
+	preload();
+	var extra = dojo.config.extraLocale||[];
+	for(var i=0; i<extra.length; i++){
+		preload(extra[i]);
+	}
+};
+
+}
+
+if(!dojo._hasResource["dojox.grid._Grid"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid._Grid"] = true;
+dojo.provide("dojox.grid._Grid");
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+(function(){
+	var jobs = {
+		cancel: function(inHandle){
+			if(inHandle){
+				clearTimeout(inHandle);
+			}
+		},
+
+		jobs: [],
+
+		job: function(inName, inDelay, inJob){
+			jobs.cancelJob(inName);
+			var job = function(){
+				delete jobs.jobs[inName];
+				inJob();
+			}
+			jobs.jobs[inName] = setTimeout(job, inDelay);
+		},
+
+		cancelJob: function(inName){
+			jobs.cancel(jobs.jobs[inName]);
+		}
+	};
+
+	/*=====
+	dojox.grid.__CellDef = function(){
+		//	name: String?
+		//		The text to use in the header of the grid for this cell.
+		//	get: Function?
+		//		function(rowIndex){} rowIndex is of type Integer.  This
+		//		function will be called when a cell	requests data.  Returns the
+		//		unformatted data for the cell.
+		//	value: String?
+		//		If "get" is not specified, this is used as the data for the cell.
+		//	defaultValue: String?
+		//		If "get" and "value" aren't specified or if "get" returns an undefined
+		//		value, this is used as the data for the cell.  "formatter" is not run
+		//		on this if "get" returns an undefined value.
+		//	formatter: Function?
+		//		function(data, rowIndex){} data is of type anything, rowIndex
+		//		is of type Integer.  This function will be called after the cell
+		//		has its data but before it passes it back to the grid to render.
+		//		Returns the formatted version of the cell's data.
+		//	type: dojox.grid.cells._Base|Function?
+		//		TODO
+		//	editable: Boolean?
+		//		Whether this cell should be editable or not.
+		//	hidden: Boolean?
+		//		If true, the cell will not be displayed.
+		//	noresize: Boolean?
+		//		If true, the cell will not be able to be resized.
+		//	width: Integer|String?
+		//		A CSS size.  If it's an Integer, the width will be in em's.
+		//	colSpan: Integer?
+		//		How many columns to span this cell.  Will not work in the first
+		//		sub-row of cells.
+		//	rowSpan: Integer?
+		//		How many sub-rows to span this cell.
+		//	styles: String?
+		//		A string of styles to apply to both the header cell and main
+		//		grid cells.  Must end in a ';'.
+		//	headerStyles: String?
+		//		A string of styles to apply to just the header cell.  Must end
+		//		in a ';'
+		//	cellStyles: String?
+		//		A string of styles to apply to just the main grid cells.  Must
+		//		end in a ';'
+		//	classes: String?
+		//		A space separated list of classes to apply to both the header
+		//		cell and the main grid cells.
+		//	headerClasses: String?
+		//		A space separated list of classes to apply to just the header
+		//		cell.
+		//	cellClasses: String?
+		//		A space separated list of classes to apply to just the main
+		//		grid cells.
+		//	attrs: String?
+		//		A space separated string of attribute='value' pairs to add to
+		//		the header cell element and main grid cell elements.
+		this.name = name;
+		this.value = value;
+		this.get = get;
+		this.formatter = formatter;
+		this.type = type;
+		this.editable = editable;
+		this.hidden = hidden;
+		this.width = width;
+		this.colSpan = colSpan;
+		this.rowSpan = rowSpan;
+		this.styles = styles;
+		this.headerStyles = headerStyles;
+		this.cellStyles = cellStyles;
+		this.classes = classes;
+		this.headerClasses = headerClasses;
+		this.cellClasses = cellClasses;
+		this.attrs = attrs;
+	}
+	=====*/
+
+	/*=====
+	dojox.grid.__ViewDef = function(){
+		//	noscroll: Boolean?
+		//		If true, no scrollbars will be rendered without scrollbars.
+		//	width: Integer|String?
+		//		A CSS size.  If it's an Integer, the width will be in em's. If
+		//		"noscroll" is true, this value is ignored.
+		//	cells: dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]]?
+		//		The structure of the cells within this grid.
+		//	type: String?
+		//		A string containing the constructor of a subclass of
+		//		dojox.grid._View.  If this is not specified, dojox.grid._View
+		//		is used.
+		//	defaultCell: dojox.grid.__CellDef?
+		//		A cell definition with default values for all cells in this view.  If
+		//		a property is defined in a cell definition in the "cells" array and
+		//		this property, the cell definition's property will override this
+		//		property's property.
+		//	onBeforeRow: Function?
+		//		function(rowIndex, cells){} rowIndex is of type Integer, cells
+		//		is of type Array[dojox.grid.__CellDef[]].  This function is called
+		//		before each row of data is rendered.  Before the header is
+		//		rendered, rowIndex will be -1.  "cells" is a reference to the
+		//		internal structure of this view's cells so any changes you make to
+		//		it will persist between calls.
+		//	onAfterRow: Function?
+		//		function(rowIndex, cells, rowNode){} rowIndex is of type Integer, cells
+		//		is of type Array[dojox.grid.__CellDef[]], rowNode is of type DOMNode.
+		//		This function is called	after each row of data is rendered.  After the
+		//		header is rendered, rowIndex will be -1.  "cells" is a reference to the
+		//		internal structure of this view's cells so any changes you make to
+		//		it will persist between calls.
+		this.noscroll = noscroll;
+		this.width = width;
+		this.cells = cells;
+		this.type = type;
+		this.defaultCell = defaultCell;
+		this.onBeforeRow = onBeforeRow;
+		this.onAfterRow = onAfterRow;
+	}
+	=====*/
+
+	dojo.declare('dojox.grid._Grid',
+		[ dijit._Widget, dijit._Templated, dojox.grid._Events ],
+		{
+		// summary:
+		// 		A grid widget with virtual scrolling, cell editing, complex rows,
+		// 		sorting, fixed columns, sizeable columns, etc.
+		//
+		//	description:
+		//		_Grid provides the full set of grid features without any
+		//		direct connection to a data store.
+		//
+		//		The grid exposes a get function for the grid, or optionally
+		//		individual columns, to populate cell contents.
+		//
+		//		The grid is rendered based on its structure, an object describing
+		//		column and cell layout.
+		//
+		//	example:
+		//		A quick sample:
+		//
+		//		define a get function
+		//	|	function get(inRowIndex){ // called in cell context
+		//	|		return [this.index, inRowIndex].join(', ');
+		//	|	}
+		//
+		//		define the grid structure:
+		//	|	var structure = [ // array of view objects
+		//	|		{ cells: [// array of rows, a row is an array of cells
+		//	|			[
+		//	|				{ name: "Alpha", width: 6 },
+		//	|				{ name: "Beta" },
+		//	|				{ name: "Gamma", get: get }]
+		//	|		]}
+		//	|	];
+		//
+		//	|	<div id="grid"
+		//	|		rowCount="100" get="get"
+		//	|		structure="structure"
+		//	|		dojoType="dojox.grid._Grid"></div>
+
+		templateString:"<div class=\"dojoxGrid\" hidefocus=\"hidefocus\" wairole=\"grid\" dojoAttachEvent=\"onmouseout:_mouseOut\">\n\t<div class=\"dojoxGridMasterHeader\" dojoAttachPoint=\"viewsHeaderNode\" tabindex=\"-1\" wairole=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterView\" dojoAttachPoint=\"viewsNode\" wairole=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterMessages\" style=\"display: none;\" dojoAttachPoint=\"messagesNode\"></div>\n\t<span dojoAttachPoint=\"lastFocu [...]
+
+		// classTag: String
+		// 		CSS class applied to the grid's domNode
+		classTag: 'dojoxGrid',
+
+		get: function(inRowIndex){
+			// summary: Default data getter.
+			// description:
+			//		Provides data to display in a grid cell. Called in grid cell context.
+			//		So this.cell.index is the column index.
+			// inRowIndex: Integer
+			//		Row for which to provide data
+			// returns:
+			//		Data to display for a given grid cell.
+		},
+
+		// settings
+		// rowCount: Integer
+		//		Number of rows to display.
+		rowCount: 5,
+
+		// keepRows: Integer
+		//		Number of rows to keep in the rendering cache.
+		keepRows: 75,
+
+		// rowsPerPage: Integer
+		//		Number of rows to render at a time.
+		rowsPerPage: 25,
+
+		// autoWidth: Boolean
+		//		If autoWidth is true, grid width is automatically set to fit the data.
+		autoWidth: false,
+
+		// autoHeight: Boolean|Integer
+		//		If autoHeight is true, grid height is automatically set to fit the data.
+		//		If it is an integer, the height will be automatically set to fit the data
+		//		if there are fewer than that many rows - and the height will be set to show
+		//		that many rows if there are more
+		autoHeight: '',
+
+		// autoRender: Boolean
+		//		If autoRender is true, grid will render itself after initialization.
+		autoRender: true,
+
+		// defaultHeight: String
+		//		default height of the grid, measured in any valid css unit.
+		defaultHeight: '15em',
+		
+		// height: String
+		//		explicit height of the grid, measured in any valid css unit.  This will be populated (and overridden)
+		//		if the height: css attribute exists on the source node.
+		height: '',
+
+		// structure: dojox.grid.__ViewDef|dojox.grid.__ViewDef[]|dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]]
+		//		View layout defintion.
+		structure: null,
+
+		// elasticView: Integer
+		//	Override defaults and make the indexed grid view elastic, thus filling available horizontal space.
+		elasticView: -1,
+
+		// singleClickEdit: boolean
+		//		Single-click starts editing. Default is double-click
+		singleClickEdit: false,
+
+		// selectionMode: String
+		//		Set the selection mode of grid's Selection.  Value must be 'single', 'multiple',
+		//		or 'extended'.  Default is 'extended'.
+		selectionMode: 'extended',
+
+		// rowSelector: Boolean|String
+		// 		If set to true, will add a row selector view to this grid.  If set to a CSS width, will add
+		// 		a row selector of that width to this grid.
+		rowSelector: '',
+
+		// columnReordering: Boolean
+		// 		If set to true, will add drag and drop reordering to views with one row of columns.
+		columnReordering: false,
+
+		// headerMenu: dijit.Menu
+		// 		If set to a dijit.Menu, will use this as a context menu for the grid headers.
+		headerMenu: null,
+
+		// placeholderLabel: String
+		// 		Label of placeholders to search for in the header menu to replace with column toggling
+		// 		menu items.
+		placeholderLabel: "GridColumns",
+		
+		// selectable: Boolean
+		//		Set to true if you want to be able to select the text within the grid.
+		selectable: false,
+		
+		// Used to store the last two clicks, to ensure double-clicking occurs based on the intended row
+		_click: null,
+		
+		// loadingMessage: String
+		//  Message that shows while the grid is loading
+		loadingMessage: "<span class='dojoxGridLoading'>${loadingState}</span>",
+
+		// errorMessage: String
+		//  Message that shows when the grid encounters an error loading
+		errorMessage: "<span class='dojoxGridError'>${errorState}</span>",
+
+		// noDataMessage: String
+		//  Message that shows if the grid has no data - wrap it in a 
+		//  span with class 'dojoxGridNoData' if you want it to be
+		//  styled similar to the loading and error messages
+		noDataMessage: "",
+
+		// private
+		sortInfo: 0,
+		themeable: true,
+		_placeholders: null,
+
+		// initialization
+		buildRendering: function(){
+			this.inherited(arguments);
+			// reset get from blank function (needed for markup parsing) to null, if not changed
+			if(this.get == dojox.grid._Grid.prototype.get){
+				this.get = null;
+			}
+			if(!this.domNode.getAttribute('tabIndex')){
+				this.domNode.tabIndex = "0";
+			}
+			this.createScroller();
+			this.createLayout();
+			this.createViews();
+			this.createManagers();
+
+			this.createSelection();
+
+			this.connect(this.selection, "onSelected", "onSelected");
+			this.connect(this.selection, "onDeselected", "onDeselected");
+			this.connect(this.selection, "onChanged", "onSelectionChanged");
+
+			dojox.html.metrics.initOnFontResize();
+			this.connect(dojox.html.metrics, "onFontResize", "textSizeChanged");
+			dojox.grid.util.funnelEvents(this.domNode, this, 'doKeyEvent', dojox.grid.util.keyEvents);
+			this.connect(this, "onShow", "renderOnIdle");
+		},
+		
+		postMixInProperties: function(){
+			this.inherited(arguments);
+			var messages = dojo.i18n.getLocalization("dijit", "loading", this.lang);
+			this.loadingMessage = dojo.string.substitute(this.loadingMessage, messages);
+			this.errorMessage = dojo.string.substitute(this.errorMessage, messages);
+			if(this.srcNodeRef && this.srcNodeRef.style.height){
+				this.height = this.srcNodeRef.style.height;
+			}
+			// Call this to update our autoheight to start out
+			this._setAutoHeightAttr(this.autoHeight, true);
+		},
+		
+		postCreate: function(){
+			// replace stock styleChanged with one that triggers an update
+			this.styleChanged = this._styleChanged;
+			this._placeholders = [];
+			this._setHeaderMenuAttr(this.headerMenu);
+			this._setStructureAttr(this.structure);
+			this._click = [];
+		},
+
+		destroy: function(){
+			this.domNode.onReveal = null;
+			this.domNode.onSizeChange = null;
+
+			// Fixes IE domNode leak
+			delete this._click;
+
+			this.edit.destroy();
+			delete this.edit;
+
+			this.views.destroyViews();
+			if(this.scroller){
+				this.scroller.destroy();
+				delete this.scroller;
+			}
+			if(this.focus){
+				this.focus.destroy();
+				delete this.focus;
+			}
+			if(this.headerMenu&&this._placeholders.length){
+				dojo.forEach(this._placeholders, function(p){ p.unReplace(true); });
+				this.headerMenu.unBindDomNode(this.viewsHeaderNode);
+			}
+			this.inherited(arguments);
+		},
+
+		_setAutoHeightAttr: function(ah, skipRender){
+			// Calculate our autoheight - turn it into a boolean or an integer
+			if(typeof ah == "string"){
+				if(!ah || ah == "false"){
+					ah = false;
+				}else if (ah == "true"){
+					ah = true;
+				}else{
+					ah = window.parseInt(ah, 10);
+				}
+			}
+			if(typeof ah == "number"){
+				if(isNaN(ah)){
+					ah = false;
+				}
+				// Autoheight must be at least 1, if it's a number.  If it's
+				// less than 0, we'll take that to mean "all" rows (same as 
+				// autoHeight=true - if it is equal to zero, we'll take that
+				// to mean autoHeight=false
+				if(ah < 0){
+					ah = true;
+				}else if (ah === 0){
+					ah = false;
+				}
+			}
+			this.autoHeight = ah;
+			if(typeof ah == "boolean"){
+				this._autoHeight = ah;
+			}else if(typeof ah == "number"){
+				this._autoHeight = (ah >= this.attr('rowCount'));
+			}else{
+				this._autoHeight = false;
+			}
+			if(this._started && !skipRender){
+				this.render();
+			}
+		},
+
+		_getRowCountAttr: function(){
+			return this.updating && this.invalidated && this.invalidated.rowCount != undefined ?
+				this.invalidated.rowCount : this.rowCount;
+		},
+		
+		styleChanged: function(){
+			this.setStyledClass(this.domNode, '');
+		},
+
+		_styleChanged: function(){
+			this.styleChanged();
+			this.update();
+		},
+
+		textSizeChanged: function(){
+			setTimeout(dojo.hitch(this, "_textSizeChanged"), 1);
+		},
+
+		_textSizeChanged: function(){
+			if(this.domNode){
+				this.views.forEach(function(v){
+					v.content.update();
+				});
+				this.render();
+			}
+		},
+
+		sizeChange: function(){
+			jobs.job(this.id + 'SizeChange', 50, dojo.hitch(this, "update"));
+		},
+
+		renderOnIdle: function() {
+			setTimeout(dojo.hitch(this, "render"), 1);
+		},
+
+		createManagers: function(){
+			// summary:
+			//		create grid managers for various tasks including rows, focus, selection, editing
+
+			// row manager
+			this.rows = new dojox.grid._RowManager(this);
+			// focus manager
+			this.focus = new dojox.grid._FocusManager(this);
+			// edit manager
+			this.edit = new dojox.grid._EditManager(this);
+		},
+
+		createSelection: function(){
+			// summary:	Creates a new Grid selection manager.
+
+			// selection manager
+			this.selection = new dojox.grid.Selection(this);
+		},
+
+		createScroller: function(){
+			// summary: Creates a new virtual scroller
+			this.scroller = new dojox.grid._Scroller();
+			this.scroller.grid = this;
+			this.scroller._pageIdPrefix = this.id + '-';
+			this.scroller.renderRow = dojo.hitch(this, "renderRow");
+			this.scroller.removeRow = dojo.hitch(this, "rowRemoved");
+		},
+
+		createLayout: function(){
+			// summary: Creates a new Grid layout
+			this.layout = new dojox.grid._Layout(this);
+			this.connect(this.layout, "moveColumn", "onMoveColumn");
+		},
+
+		onMoveColumn: function(){
+			this.render();
+			this._resize();
+		},
+
+		// views
+		createViews: function(){
+			this.views = new dojox.grid._ViewManager(this);
+			this.views.createView = dojo.hitch(this, "createView");
+		},
+
+		createView: function(inClass, idx){
+			var c = dojo.getObject(inClass);
+			var view = new c({ grid: this, index: idx });
+			this.viewsNode.appendChild(view.domNode);
+			this.viewsHeaderNode.appendChild(view.headerNode);
+			this.views.addView(view);
+			return view;
+		},
+
+		buildViews: function(){
+			for(var i=0, vs; (vs=this.layout.structure[i]); i++){
+				this.createView(vs.type || dojox._scopeName + ".grid._View", i).setStructure(vs);
+			}
+			this.scroller.setContentNodes(this.views.getContentNodes());
+		},
+
+		_setStructureAttr: function(structure){
+			var s = structure;
+			if(s && dojo.isString(s)){
+				dojo.deprecated("dojox.grid._Grid.attr('structure', 'objVar')", "use dojox.grid._Grid.attr('structure', objVar) instead", "2.0");
+				s=dojo.getObject(s);
+			}
+			this.structure = s;
+			if(!s){
+				if(this.layout.structure){
+					s = this.layout.structure;
+				}else{
+					return;
+				}
+			}
+			this.views.destroyViews();
+			if(s !== this.layout.structure){
+				this.layout.setStructure(s);
+			}
+			this._structureChanged();
+		},
+
+		setStructure: function(/* dojox.grid.__ViewDef|dojox.grid.__ViewDef[]|dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]] */ inStructure){
+			// summary:
+			//		Install a new structure and rebuild the grid.
+			dojo.deprecated("dojox.grid._Grid.setStructure(obj)", "use dojox.grid._Grid.attr('structure', obj) instead.", "2.0");
+			this._setStructureAttr(inStructure);
+		},
+		
+		getColumnTogglingItems: function(){
+			// Summary: returns an array of dijit.CheckedMenuItem widgets that can be
+			//		added to a menu for toggling columns on and off.
+			return dojo.map(this.layout.cells, function(cell){
+				if(!cell.menuItems){ cell.menuItems = []; }
+
+				var self = this;
+				var item = new dijit.CheckedMenuItem({
+					label: cell.name,
+					checked: !cell.hidden,
+					_gridCell: cell,
+					onChange: function(checked){
+						if(self.layout.setColumnVisibility(this._gridCell.index, checked)){
+							var items = this._gridCell.menuItems;
+							if(items.length > 1){
+								dojo.forEach(items, function(item){
+									if(item !== this){
+										item.setAttribute("checked", checked);
+									}
+								}, this);
+							}
+							var checked = dojo.filter(self.layout.cells, function(c){
+								if(c.menuItems.length > 1){
+									dojo.forEach(c.menuItems, "item.attr('disabled', false);");
+								}else{
+									c.menuItems[0].attr('disabled', false);
+								}
+								return !c.hidden;
+							});
+							if(checked.length == 1){
+								dojo.forEach(checked[0].menuItems, "item.attr('disabled', true);");
+							}
+						}
+					},
+					destroy: function(){
+						var index = dojo.indexOf(this._gridCell.menuItems, this);
+						this._gridCell.menuItems.splice(index, 1);
+						delete this._gridCell;
+						dijit.CheckedMenuItem.prototype.destroy.apply(this, arguments);
+					}
+				});
+				cell.menuItems.push(item);
+				return item;
+			}, this); // dijit.CheckedMenuItem[]
+		},
+
+		_setHeaderMenuAttr: function(menu){
+			if(this._placeholders && this._placeholders.length){
+				dojo.forEach(this._placeholders, function(p){
+					p.unReplace(true);
+				});
+				this._placeholders = [];
+			}
+			if(this.headerMenu){
+				this.headerMenu.unBindDomNode(this.viewsHeaderNode);
+			}
+			this.headerMenu = menu;
+			if(!menu){ return; }
+
+			this.headerMenu.bindDomNode(this.viewsHeaderNode);
+			if(this.headerMenu.getPlaceholders){
+				this._placeholders = this.headerMenu.getPlaceholders(this.placeholderLabel);
+			}
+		},
+
+		setHeaderMenu: function(/* dijit.Menu */ menu){
+			dojo.deprecated("dojox.grid._Grid.setHeaderMenu(obj)", "use dojox.grid._Grid.attr('headerMenu', obj) instead.", "2.0");
+			this._setHeaderMenuAttr(menu);
+		},
+		
+		setupHeaderMenu: function(){
+			if(this._placeholders && this._placeholders.length){
+				dojo.forEach(this._placeholders, function(p){
+					if(p._replaced){
+						p.unReplace(true);
+					}
+					p.replace(this.getColumnTogglingItems());
+				}, this);
+			}
+		},
+
+		_fetch: function(start){
+			this.setScrollTop(0);
+		},
+
+		getItem: function(inRowIndex){
+			return null;
+		},
+		
+		showMessage: function(message){
+			if(message){
+				this.messagesNode.innerHTML = message;
+				this.messagesNode.style.display = "";
+			}else{
+				this.messagesNode.innerHTML = "";
+				this.messagesNode.style.display = "none";
+			}
+		},
+
+		_structureChanged: function() {
+			this.buildViews();
+			if(this.autoRender && this._started){
+				this.render();
+			}
+		},
+
+		hasLayout: function() {
+			return this.layout.cells.length;
+		},
+
+		// sizing
+		resize: function(changeSize, resultSize){
+			// summary:
+			//		Update the grid's rendering dimensions and resize it
+			this._resize(changeSize, resultSize);
+			this.sizeChange();
+		},
+
+		_getPadBorder: function() {
+			this._padBorder = this._padBorder || dojo._getPadBorderExtents(this.domNode);
+			return this._padBorder;
+		},
+
+		_getHeaderHeight: function(){
+			var vns = this.viewsHeaderNode.style, t = vns.display == "none" ? 0 : this.views.measureHeader();
+			vns.height = t + 'px';
+			// header heights are reset during measuring so must be normalized after measuring.
+			this.views.normalizeHeaderNodeHeight();
+			return t;
+		},
+		
+		_resize: function(changeSize, resultSize){
+			// if we have set up everything except the DOM, we cannot resize
+			var pn = this.domNode.parentNode;
+			if(!pn || pn.nodeType != 1 || !this.hasLayout() || pn.style.visibility == "hidden" || pn.style.display == "none"){
+				return;
+			}
+			// useful measurement
+			var padBorder = this._getPadBorder();
+			var hh = 0;
+			// grid height
+			if(this._autoHeight){
+				this.domNode.style.height = 'auto';
+				this.viewsNode.style.height = '';
+			}else if(typeof this.autoHeight == "number"){
+				var h = hh = this._getHeaderHeight();
+				h += (this.scroller.averageRowHeight * this.autoHeight);
+				this.domNode.style.height = h + "px";
+			}else if(this.flex > 0){
+			}else if(this.domNode.clientHeight <= padBorder.h){
+				if(pn == document.body){
+					this.domNode.style.height = this.defaultHeight;
+				}else if(this.height){
+					this.domNode.style.height = this.height;
+				}else{
+					this.fitTo = "parent";
+				}
+			}
+			// if we are given dimensions, size the grid's domNode to those dimensions
+			if(resultSize){
+				changeSize = resultSize;
+			}
+			if(changeSize){
+				dojo.marginBox(this.domNode, changeSize);
+				this.height = this.domNode.style.height;
+				delete this.fitTo;
+			}else if(this.fitTo == "parent"){
+				var h = dojo._getContentBox(pn).h;
+				dojo.marginBox(this.domNode, { h: Math.max(0, h) });
+			}
+
+			var h = dojo._getContentBox(this.domNode).h;
+			if(h == 0 && !this._autoHeight){
+				// We need to hide the header, since the Grid is essentially hidden.
+				this.viewsHeaderNode.style.display = "none";
+			}else{
+				// Otherwise, show the header and give it an appropriate height.
+				this.viewsHeaderNode.style.display = "block";
+				hh = this._getHeaderHeight();
+			}
+
+			// NOTE: it is essential that width be applied before height
+			// Header height can only be calculated properly after view widths have been set.
+			// This is because flex column width is naturally 0 in Firefox.
+			// Therefore prior to width sizing flex columns with spaces are maximally wrapped
+			// and calculated to be too tall.
+			this.adaptWidth();
+			this.adaptHeight(hh);
+
+			this.postresize();
+		},
+
+		adaptWidth: function() {
+			// private: sets width and position for views and update grid width if necessary
+			var w = this.autoWidth ? 0 : this.domNode.clientWidth || (this.domNode.offsetWidth - this._getPadBorder().w),
+				vw = this.views.arrange(1, w);
+			this.views.onEach("adaptWidth");
+			if (this.autoWidth)
+				this.domNode.style.width = vw + "px";
+		},
+
+		adaptHeight: function(inHeaderHeight){
+			// private: measures and normalizes header height, then sets view heights, and then updates scroller
+			// content extent
+			var t = inHeaderHeight || this._getHeaderHeight();
+			var h = (this._autoHeight ? -1 : Math.max(this.domNode.clientHeight - t, 0) || 0);
+			this.views.onEach('setSize', [0, h]);
+			this.views.onEach('adaptHeight');
+			if(!this._autoHeight){
+				var numScroll = 0, numNoScroll = 0;
+				var noScrolls = dojo.filter(this.views.views, function(v){
+					var has = v.hasHScrollbar();
+					if(has){ numScroll++; }else{ numNoScroll++; }
+					return (!has);
+				});
+				if(numScroll > 0 && numNoScroll > 0){
+					dojo.forEach(noScrolls, function(v){
+						v.adaptHeight(true);
+					});
+				}
+			}
+			if(this.autoHeight === true || h != -1 || (typeof this.autoHeight == "number" && this.autoHeight >= this.attr('rowCount'))){
+				this.scroller.windowHeight = h;
+			}else{
+				this.scroller.windowHeight = Math.max(this.domNode.clientHeight - t, 0);
+			}
+		},
+
+		// startup
+		startup: function(){
+			if(this._started){return;}
+			
+			this.inherited(arguments);
+
+			if(this.autoRender){
+				this.render();
+			}
+		},
+
+		// render
+		render: function(){
+			// summary:
+			//	Render the grid, headers, and views. Edit and scrolling states are reset. To retain edit and
+			// scrolling states, see Update.
+
+			if(!this.domNode){return;}
+			if(!this._started){return;}
+
+			if(!this.hasLayout()) {
+				this.scroller.init(0, this.keepRows, this.rowsPerPage);
+				return;
+			}
+			//
+			this.update = this.defaultUpdate;
+			this._render();
+		},
+
+		_render: function(){
+			this.scroller.init(this.attr('rowCount'), this.keepRows, this.rowsPerPage);
+			this.prerender();
+			this.setScrollTop(0);
+			this.postrender();
+		},
+
+		prerender: function(){
+			// if autoHeight, make sure scroller knows not to virtualize; everything must be rendered.
+			this.keepRows = this._autoHeight ? 0 : this.keepRows;
+			this.scroller.setKeepInfo(this.keepRows);
+			this.views.render();
+			this._resize();
+		},
+
+		postrender: function(){
+			this.postresize();
+			this.focus.initFocusView();
+			// make rows unselectable
+			dojo.setSelectable(this.domNode, this.selectable);
+		},
+
+		postresize: function(){
+			// views are position absolute, so they do not inflate the parent
+			if(this._autoHeight){
+				var size = Math.max(this.views.measureContent()) + 'px';
+				this.viewsNode.style.height = size;
+			}
+		},
+
+		renderRow: function(inRowIndex, inNodes){
+			// summary: private, used internally to render rows
+			this.views.renderRow(inRowIndex, inNodes);
+		},
+
+		rowRemoved: function(inRowIndex){
+			// summary: private, used internally to remove rows
+			this.views.rowRemoved(inRowIndex);
+		},
+
+		invalidated: null,
+
+		updating: false,
+
+		beginUpdate: function(){
+			// summary:
+			//		Use to make multiple changes to rows while queueing row updating.
+			// NOTE: not currently supporting nested begin/endUpdate calls
+			this.invalidated = [];
+			this.updating = true;
+		},
+
+		endUpdate: function(){
+			// summary:
+			//		Use after calling beginUpdate to render any changes made to rows.
+			this.updating = false;
+			var i = this.invalidated, r;
+			if(i.all){
+				this.update();
+			}else if(i.rowCount != undefined){
+				this.updateRowCount(i.rowCount);
+			}else{
+				for(r in i){
+					this.updateRow(Number(r));
+				}
+			}
+			this.invalidated = null;
+		},
+
+		// update
+		defaultUpdate: function(){
+			// note: initial update calls render and subsequently this function.
+			if(!this.domNode){return;}
+			if(this.updating){
+				this.invalidated.all = true;
+				return;
+			}
+			//this.edit.saveState(inRowIndex);
+			var lastScrollTop = this.scrollTop;
+			this.prerender();
+			this.scroller.invalidateNodes();
+			this.setScrollTop(lastScrollTop);
+			this.postrender();
+			//this.edit.restoreState(inRowIndex);
+		},
+
+		update: function(){
+			// summary:
+			//		Update the grid, retaining edit and scrolling states.
+			this.render();
+		},
+
+		updateRow: function(inRowIndex){
+			// summary:
+			//		Render a single row.
+			// inRowIndex: Integer
+			//		Index of the row to render
+			inRowIndex = Number(inRowIndex);
+			if(this.updating){
+				this.invalidated[inRowIndex]=true;
+			}else{
+				this.views.updateRow(inRowIndex);
+				this.scroller.rowHeightChanged(inRowIndex);
+			}
+		},
+
+		updateRows: function(startIndex, howMany){
+			// summary:
+			//		Render consecutive rows at once.
+			// startIndex: Integer
+			//		Index of the starting row to render
+			// howMany: Integer
+			//		How many rows to update.
+			startIndex = Number(startIndex);
+			howMany = Number(howMany);
+			if(this.updating){
+				for(var i=0; i<howMany; i++){
+					this.invalidated[i+startIndex]=true;
+				}
+			}else{
+				for(var i=0; i<howMany; i++){
+					this.views.updateRow(i+startIndex);
+				}
+				this.scroller.rowHeightChanged(startIndex);
+			}
+		},
+
+		updateRowCount: function(inRowCount){
+			//summary:
+			//	Change the number of rows.
+			// inRowCount: int
+			//	Number of rows in the grid.
+			if(this.updating){
+				this.invalidated.rowCount = inRowCount;
+			}else{
+				this.rowCount = inRowCount;
+				this._setAutoHeightAttr(this.autoHeight, true);
+				if(this.layout.cells.length){
+					this.scroller.updateRowCount(inRowCount);
+				}
+				this._resize();				
+				if(this.layout.cells.length){
+					this.setScrollTop(this.scrollTop);
+				}
+			}
+		},
+
+		updateRowStyles: function(inRowIndex){
+			// summary:
+			//		Update the styles for a row after it's state has changed.
+			this.views.updateRowStyles(inRowIndex);
+		},
+
+		rowHeightChanged: function(inRowIndex){
+			// summary:
+			//		Update grid when the height of a row has changed. Row height is handled automatically as rows
+			//		are rendered. Use this function only to update a row's height outside the normal rendering process.
+			// inRowIndex: Integer
+			// 		index of the row that has changed height
+
+			this.views.renormalizeRow(inRowIndex);
+			this.scroller.rowHeightChanged(inRowIndex);
+		},
+
+		// fastScroll: Boolean
+		//		flag modifies vertical scrolling behavior. Defaults to true but set to false for slower
+		//		scroll performance but more immediate scrolling feedback
+		fastScroll: true,
+
+		delayScroll: false,
+
+		// scrollRedrawThreshold: int
+		//	pixel distance a user must scroll vertically to trigger grid scrolling.
+		scrollRedrawThreshold: (dojo.isIE ? 100 : 50),
+
+		// scroll methods
+		scrollTo: function(inTop){
+			// summary:
+			//		Vertically scroll the grid to a given pixel position
+			// inTop: Integer
+			//		vertical position of the grid in pixels
+			if(!this.fastScroll){
+				this.setScrollTop(inTop);
+				return;
+			}
+			var delta = Math.abs(this.lastScrollTop - inTop);
+			this.lastScrollTop = inTop;
+			if(delta > this.scrollRedrawThreshold || this.delayScroll){
+				this.delayScroll = true;
+				this.scrollTop = inTop;
+				this.views.setScrollTop(inTop);
+				jobs.job('dojoxGridScroll', 200, dojo.hitch(this, "finishScrollJob"));
+			}else{
+				this.setScrollTop(inTop);
+			}
+		},
+
+		finishScrollJob: function(){
+			this.delayScroll = false;
+			this.setScrollTop(this.scrollTop);
+		},
+
+		setScrollTop: function(inTop){
+			this.scroller.scroll(this.views.setScrollTop(inTop));
+		},
+
+		scrollToRow: function(inRowIndex){
+			// summary:
+			//		Scroll the grid to a specific row.
+			// inRowIndex: Integer
+			// 		grid row index
+			this.setScrollTop(this.scroller.findScrollTop(inRowIndex) + 1);
+		},
+
+		// styling (private, used internally to style individual parts of a row)
+		styleRowNode: function(inRowIndex, inRowNode){
+			if(inRowNode){
+				this.rows.styleRowNode(inRowIndex, inRowNode);
+			}
+		},
+		
+		// called when the mouse leaves the grid so we can deselect all hover rows
+		_mouseOut: function(e){
+			this.rows.setOverRow(-2);
+		},
+	
+		// cells
+		getCell: function(inIndex){
+			// summary:
+			//		Retrieves the cell object for a given grid column.
+			// inIndex: Integer
+			// 		Grid column index of cell to retrieve
+			// returns:
+			//		a grid cell
+			return this.layout.cells[inIndex];
+		},
+
+		setCellWidth: function(inIndex, inUnitWidth) {
+			this.getCell(inIndex).unitWidth = inUnitWidth;
+		},
+
+		getCellName: function(inCell){
+			// summary: Returns the cell name of a passed cell
+			return "Cell " + inCell.index; // String
+		},
+
+		// sorting
+		canSort: function(inSortInfo){
+			// summary:
+			//		Determines if the grid can be sorted
+			// inSortInfo: Integer
+			//		Sort information, 1-based index of column on which to sort, positive for an ascending sort
+			// 		and negative for a descending sort
+			// returns: Boolean
+			//		True if grid can be sorted on the given column in the given direction
+		},
+
+		sort: function(){
+		},
+
+		getSortAsc: function(inSortInfo){
+			// summary:
+			//		Returns true if grid is sorted in an ascending direction.
+			inSortInfo = inSortInfo == undefined ? this.sortInfo : inSortInfo;
+			return Boolean(inSortInfo > 0); // Boolean
+		},
+
+		getSortIndex: function(inSortInfo){
+			// summary:
+			//		Returns the index of the column on which the grid is sorted
+			inSortInfo = inSortInfo == undefined ? this.sortInfo : inSortInfo;
+			return Math.abs(inSortInfo) - 1; // Integer
+		},
+
+		setSortIndex: function(inIndex, inAsc){
+			// summary:
+			// 		Sort the grid on a column in a specified direction
+			// inIndex: Integer
+			// 		Column index on which to sort.
+			// inAsc: Boolean
+			// 		If true, sort the grid in ascending order, otherwise in descending order
+			var si = inIndex +1;
+			if(inAsc != undefined){
+				si *= (inAsc ? 1 : -1);
+			} else if(this.getSortIndex() == inIndex){
+				si = -this.sortInfo;
+			}
+			this.setSortInfo(si);
+		},
+
+		setSortInfo: function(inSortInfo){
+			if(this.canSort(inSortInfo)){
+				this.sortInfo = inSortInfo;
+				this.sort();
+				this.update();
+			}
+		},
+
+		// DOM event handler
+		doKeyEvent: function(e){
+			e.dispatch = 'do' + e.type;
+			this.onKeyEvent(e);
+		},
+
+		// event dispatch
+		//: protected
+		_dispatch: function(m, e){
+			if(m in this){
+				return this[m](e);
+			}
+		},
+
+		dispatchKeyEvent: function(e){
+			this._dispatch(e.dispatch, e);
+		},
+
+		dispatchContentEvent: function(e){
+			this.edit.dispatchEvent(e) || e.sourceView.dispatchContentEvent(e) || this._dispatch(e.dispatch, e);
+		},
+
+		dispatchHeaderEvent: function(e){
+			e.sourceView.dispatchHeaderEvent(e) || this._dispatch('doheader' + e.type, e);
+		},
+
+		dokeydown: function(e){
+			this.onKeyDown(e);
+		},
+
+		doclick: function(e){
+			if(e.cellNode){
+				this.onCellClick(e);
+			}else{
+				this.onRowClick(e);
+			}
+		},
+
+		dodblclick: function(e){
+			if(e.cellNode){
+				this.onCellDblClick(e);
+			}else{
+				this.onRowDblClick(e);
+			}
+		},
+
+		docontextmenu: function(e){
+			if(e.cellNode){
+				this.onCellContextMenu(e);
+			}else{
+				this.onRowContextMenu(e);
+			}
+		},
+
+		doheaderclick: function(e){
+			if(e.cellNode){
+				this.onHeaderCellClick(e);
+			}else{
+				this.onHeaderClick(e);
+			}
+		},
+
+		doheaderdblclick: function(e){
+			if(e.cellNode){
+				this.onHeaderCellDblClick(e);
+			}else{
+				this.onHeaderDblClick(e);
+			}
+		},
+
+		doheadercontextmenu: function(e){
+			if(e.cellNode){
+				this.onHeaderCellContextMenu(e);
+			}else{
+				this.onHeaderContextMenu(e);
+			}
+		},
+
+		// override to modify editing process
+		doStartEdit: function(inCell, inRowIndex){
+			this.onStartEdit(inCell, inRowIndex);
+		},
+
+		doApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){
+			this.onApplyCellEdit(inValue, inRowIndex, inFieldIndex);
+		},
+
+		doCancelEdit: function(inRowIndex){
+			this.onCancelEdit(inRowIndex);
+		},
+
+		doApplyEdit: function(inRowIndex){
+			this.onApplyEdit(inRowIndex);
+		},
+
+		// row editing
+		addRow: function(){
+			// summary:
+			//		Add a row to the grid.
+			this.updateRowCount(this.attr('rowCount')+1);
+		},
+
+		removeSelectedRows: function(){
+			// summary:
+			//		Remove the selected rows from the grid.
+			this.updateRowCount(Math.max(0, this.attr('rowCount') - this.selection.getSelected().length));
+			this.selection.clear();
+		}
+
+	});
+
+	dojox.grid._Grid.markupFactory = function(props, node, ctor, cellFunc){
+		var d = dojo;
+		var widthFromAttr = function(n){
+			var w = d.attr(n, "width")||"auto";
+			if((w != "auto")&&(w.slice(-2) != "em")&&(w.slice(-1) != "%")){
+				w = parseInt(w)+"px";
+			}
+			return w;
+		}
+		// if(!props.store){  }
+		// if a structure isn't referenced, do we have enough
+		// data to try to build one automatically?
+		if(	!props.structure &&
+			node.nodeName.toLowerCase() == "table"){
+
+			// try to discover a structure
+			props.structure = d.query("> colgroup", node).map(function(cg){
+				var sv = d.attr(cg, "span");
+				var v = {
+					noscroll: (d.attr(cg, "noscroll") == "true") ? true : false,
+					__span: (!!sv ? parseInt(sv) : 1),
+					cells: []
+				};
+				if(d.hasAttr(cg, "width")){
+					v.width = widthFromAttr(cg);
+				}
+				return v; // for vendetta
+			});
+			if(!props.structure.length){
+				props.structure.push({
+					__span: Infinity,
+					cells: [] // catch-all view
+				});
+			}
+			// check to see if we're gonna have more than one view
+
+			// for each tr in our th, create a row of cells
+			d.query("thead > tr", node).forEach(function(tr, tr_idx){
+				var cellCount = 0;
+				var viewIdx = 0;
+				var lastViewIdx;
+				var cView = null;
+				d.query("> th", tr).map(function(th){
+					// what view will this cell go into?
+
+					// NOTE:
+					//		to prevent extraneous iteration, we start counters over
+					//		for each row, incrementing over the surface area of the
+					//		structure that colgroup processing generates and
+					//		creating cell objects for each <th> to place into those
+					//		cell groups.  There's a lot of state-keepking logic
+					//		here, but it is what it has to be.
+					if(!cView){ // current view book keeping
+						lastViewIdx = 0;
+						cView = props.structure[0];
+					}else if(cellCount >= (lastViewIdx+cView.__span)){
+						viewIdx++;
+						// move to allocating things into the next view
+						lastViewIdx += cView.__span;
+						var lastView = cView;
+						cView = props.structure[viewIdx];
+					}
+
+					// actually define the cell from what markup hands us
+					var cell = {
+						name: d.trim(d.attr(th, "name")||th.innerHTML),
+						colSpan: parseInt(d.attr(th, "colspan")||1, 10),
+						type: d.trim(d.attr(th, "cellType")||"")
+					};
+					cellCount += cell.colSpan;
+					var rowSpan = d.attr(th, "rowspan");
+					if(rowSpan){
+						cell.rowSpan = rowSpan;
+					}
+					if(d.hasAttr(th, "width")){
+						cell.width = widthFromAttr(th);
+					}
+					if(d.hasAttr(th, "relWidth")){
+						cell.relWidth = window.parseInt(dojo.attr(th, "relWidth"), 10);
+					}
+					if(d.hasAttr(th, "hidden")){
+						cell.hidden = d.attr(th, "hidden") == "true";
+					}
+
+					if(cellFunc){
+						cellFunc(th, cell);
+					}
+
+					cell.type = cell.type ? dojo.getObject(cell.type) : dojox.grid.cells.Cell;
+
+					if(cell.type && cell.type.markupFactory){
+						cell.type.markupFactory(th, cell);
+					}
+
+					if(!cView.cells[tr_idx]){
+						cView.cells[tr_idx] = [];
+					}
+					cView.cells[tr_idx].push(cell);
+				});
+			});
+		}
+
+		return new ctor(props, node);
+	}
+})();
+
+}
+
+if(!dojo._hasResource["dojox.grid.DataSelection"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.DataSelection"] = true;
+dojo.provide("dojox.grid.DataSelection");
+
+
+dojo.declare("dojox.grid.DataSelection", dojox.grid.Selection, {
+	getFirstSelected: function(){
+		var idx = dojox.grid.Selection.prototype.getFirstSelected.call(this);
+
+		if(idx == -1){ return null; }
+		return this.grid.getItem(idx);
+	},
+
+	getNextSelected: function(inPrev){
+		var old_idx = this.grid.getItemIndex(inPrev);
+		var idx = dojox.grid.Selection.prototype.getNextSelected.call(this, old_idx);
+
+		if(idx == -1){ return null; }
+		return this.grid.getItem(idx);
+	},
+
+	getSelected: function(){
+		var result = [];
+		for(var i=0, l=this.selected.length; i<l; i++){
+			if(this.selected[i]){
+				result.push(this.grid.getItem(i));
+			}
+		}
+		return result;
+	},
+
+	addToSelection: function(inItemOrIndex){
+		if(this.mode == 'none'){ return; }
+		var idx = null;
+		if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+			idx = inItemOrIndex;
+		}else{
+			idx = this.grid.getItemIndex(inItemOrIndex);
+		}
+		dojox.grid.Selection.prototype.addToSelection.call(this, idx);
+	},
+
+	deselect: function(inItemOrIndex){
+		if(this.mode == 'none'){ return; }
+		var idx = null;
+		if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+			idx = inItemOrIndex;
+		}else{
+			idx = this.grid.getItemIndex(inItemOrIndex);
+		}
+		dojox.grid.Selection.prototype.deselect.call(this, idx);
+	},
+
+	deselectAll: function(inItemOrIndex){
+		var idx = null;
+		if(inItemOrIndex || typeof inItemOrIndex == "number"){
+			if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+				idx = inItemOrIndex;
+			}else{
+				idx = this.grid.getItemIndex(inItemOrIndex);
+			}
+			dojox.grid.Selection.prototype.deselectAll.call(this, idx);
+		}else{
+			this.inherited(arguments);
+		}
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.grid.DataGrid"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.DataGrid"] = true;
+dojo.provide("dojox.grid.DataGrid");
+
+
+
+
+/*=====
+dojo.declare("dojox.grid.__DataCellDef", dojox.grid.__CellDef, {
+	constructor: function(){
+		//	field: String?
+		//		The attribute to read from the dojo.data item for the row.
+		//	get: Function?
+		//		function(rowIndex, item?){} rowIndex is of type Integer, item is of type
+		//		Object.  This function will be called when a cell requests data.  Returns
+		//		the unformatted data for the cell.
+	}
+});
+=====*/
+
+/*=====
+dojo.declare("dojox.grid.__DataViewDef", dojox.grid.__ViewDef, {
+	constructor: function(){
+		//	cells: dojox.grid.__DataCellDef[]|Array[dojox.grid.__DataCellDef[]]?
+		//		The structure of the cells within this grid.
+		//	defaultCell: dojox.grid.__DataCellDef?
+		//		A cell definition with default values for all cells in this view.  If
+		//		a property is defined in a cell definition in the "cells" array and
+		//		this property, the cell definition's property will override this
+		//		property's property.
+	}
+});
+=====*/
+
+dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
+	store: null,
+	query: null,
+	queryOptions: null,
+	fetchText: '...',
+
+/*=====
+	// structure: dojox.grid.__DataViewDef|dojox.grid.__DataViewDef[]|dojox.grid.__DataCellDef[]|Array[dojox.grid.__DataCellDef[]]
+	//		View layout defintion.
+	structure: '',
+=====*/
+
+	// You can specify items instead of a query, if you like.  They do not need
+	// to be loaded - but the must be items in the store
+	items: null,
+	
+	_store_connects: null,
+	_by_idty: null,
+	_by_idx: null,
+	_cache: null,
+	_pages: null,
+	_pending_requests: null,
+	_bop: -1,
+	_eop: -1,
+	_requests: 0,
+	rowCount: 0,
+
+	_isLoaded: false,
+	_isLoading: false,
+	
+	postCreate: function(){
+		this._pages = [];
+		this._store_connects = [];
+		this._by_idty = {};
+		this._by_idx = [];
+		this._cache = [];
+		this._pending_requests = {};
+
+		this._setStore(this.store);
+		this.inherited(arguments);
+	},
+
+	createSelection: function(){
+		this.selection = new dojox.grid.DataSelection(this);
+	},
+
+	get: function(inRowIndex, inItem){
+		return (!inItem ? this.defaultValue : (!this.field ? this.value : this.grid.store.getValue(inItem, this.field)));
+	},
+
+	_onSet: function(item, attribute, oldValue, newValue){
+		var idx = this.getItemIndex(item);
+		if(idx>-1){
+			this.updateRow(idx);
+		}
+	},
+
+	_addItem: function(item, index, noUpdate){
+		var idty = this._hasIdentity ? this.store.getIdentity(item) : dojo.toJson(this.query) + ":idx:" + index + ":sort:" + dojo.toJson(this.getSortProps());
+		var o = { idty: idty, item: item };
+		this._by_idty[idty] = this._by_idx[index] = o;
+		if(!noUpdate){
+			this.updateRow(index);
+		}
+	},
+
+	_onNew: function(item, parentInfo){
+		var rowCount = this.attr('rowCount');
+		this._addingItem = true;
+		this.updateRowCount(rowCount+1);
+		this._addingItem = false;
+		this._addItem(item, rowCount);
+		this.showMessage();
+	},
+
+	_onDelete: function(item){
+		var idx = this._getItemIndex(item, true);
+
+		if(idx >= 0){
+			var o = this._by_idx[idx];
+			this._by_idx.splice(idx, 1);
+			delete this._by_idty[o.idty];
+			this.updateRowCount(this.attr('rowCount')-1);
+			if(this.attr('rowCount') === 0){
+				this.showMessage(this.noDataMessage);
+			}
+		}
+	},
+
+	_onRevert: function(){
+		this._refresh();
+	},
+
+	setStore: function(store, query, queryOptions){
+		this._setQuery(query, queryOptions);
+		this._setStore(store);
+		this._refresh(true);
+	},
+	
+	setQuery: function(query, queryOptions){
+		this._setQuery(query, queryOptions);
+		this._refresh(true);
+	},
+	
+	setItems: function(items){
+		this.items = items;
+		this._setStore(this.store);
+		this._refresh(true);
+	},
+	
+	_setQuery: function(query, queryOptions){
+		this.query = query;
+		this.queryOptions = queryOptions || this.queryOptions;		
+	},
+
+	_setStore: function(store){
+		if(this.store&&this._store_connects){
+			dojo.forEach(this._store_connects,function(arr){
+				dojo.forEach(arr, dojo.disconnect);
+			});
+		}
+		this.store = store;
+
+		if(this.store){
+			var f = this.store.getFeatures();
+			var h = [];
+
+			this._canEdit = !!f["dojo.data.api.Write"] && !!f["dojo.data.api.Identity"];
+			this._hasIdentity = !!f["dojo.data.api.Identity"];
+
+			if(!!f["dojo.data.api.Notification"] && !this.items){
+				h.push(this.connect(this.store, "onSet", "_onSet"));
+				h.push(this.connect(this.store, "onNew", "_onNew"));
+				h.push(this.connect(this.store, "onDelete", "_onDelete"));
+			}
+			if(this._canEdit){
+				h.push(this.connect(this.store, "revert", "_onRevert"));
+			}
+
+			this._store_connects = h;
+		}
+	},
+
+	_onFetchBegin: function(size, req){
+		if(this.rowCount != size){
+			if(req.isRender){
+				this.scroller.init(size, this.keepRows, this.rowsPerPage);
+				this.rowCount = size;
+				this._setAutoHeightAttr(this.autoHeight, true);
+				this.prerender();
+			}else{
+				this.updateRowCount(size);
+			}
+		}
+	},
+
+	_onFetchComplete: function(items, req){
+		if(items && items.length > 0){
+			//
+			dojo.forEach(items, function(item, idx){
+				this._addItem(item, req.start+idx, true);
+			}, this);
+			this.updateRows(req.start, items.length);
+			if(req.isRender){
+				this.setScrollTop(0);
+				this.postrender();
+			}else if(this._lastScrollTop){
+				this.setScrollTop(this._lastScrollTop);
+			}
+		}
+		delete this._lastScrollTop;
+		if(!this._isLoaded){
+			this._isLoading = false;
+			this._isLoaded = true;
+			if(!items || !items.length){
+				this.showMessage(this.noDataMessage);
+				this.focus.initFocusView();
+			}else{
+				this.showMessage();
+			}
+		}
+		this._pending_requests[req.start] = false;
+	},
+
+	_onFetchError: function(err, req){
+		
+		delete this._lastScrollTop;
+		if(!this._isLoaded){
+			this._isLoading = false;
+			this._isLoaded = true;
+			this.showMessage(this.errorMessage);
+		}
+		this.onFetchError(err, req);
+	},
+
+	onFetchError: function(err, req){
+	},
+
+	_fetch: function(start, isRender){
+		var start = start || 0;
+		if(this.store && !this._pending_requests[start]){
+			if(!this._isLoaded && !this._isLoading){
+				this._isLoading = true;
+				this.showMessage(this.loadingMessage);
+			}
+			this._pending_requests[start] = true;
+			//
+			try{
+				if(this.items){
+					var items = this.items;
+					var store = this.store;
+					this.rowsPerPage = items.length
+					var req = {
+						start: start,
+						count: this.rowsPerPage,
+						isRender: isRender
+					};
+					this._onFetchBegin(items.length, req);
+					
+					// Load them if we need to
+					var waitCount = 0;
+					dojo.forEach(items, function(i){
+						if(!store.isItemLoaded(i)){ waitCount++; }
+					});
+					if(waitCount === 0){
+						this._onFetchComplete(items, req);
+					}else{
+						var onItem = function(item){
+							waitCount--;
+							if(waitCount === 0){
+								this._onFetchComplete(items, req);
+							}
+						};
+						dojo.forEach(items, function(i){
+							if(!store.isItemLoaded(i)){
+								store.loadItem({item: i, onItem: onItem, scope: this});
+							}
+						}, this);
+					}
+				}else{
+					this.store.fetch({
+						start: start,
+						count: this.rowsPerPage,
+						query: this.query,
+						sort: this.getSortProps(),
+						queryOptions: this.queryOptions,
+						isRender: isRender,
+						onBegin: dojo.hitch(this, "_onFetchBegin"),
+						onComplete: dojo.hitch(this, "_onFetchComplete"),
+						onError: dojo.hitch(this, "_onFetchError")
+					});
+				}
+			}catch(e){
+				this._onFetchError(e);
+			}
+		}
+	},
+
+	_clearData: function(){
+		this.updateRowCount(0);
+		this._by_idty = {};
+		this._by_idx = [];
+		this._pages = [];
+		this._bop = this._eop = -1;
+		this._isLoaded = false;
+		this._isLoading = false;
+	},
+
+	getItem: function(idx){
+		var data = this._by_idx[idx];
+		if(!data||(data&&!data.item)){
+			this._preparePage(idx);
+			return null;
+		}
+		return data.item;
+	},
+
+	getItemIndex: function(item){
+		return this._getItemIndex(item, false);
+	},
+	
+	_getItemIndex: function(item, isDeleted){
+		if(!isDeleted && !this.store.isItem(item)){
+			return -1;
+		}
+
+		var idty = this._hasIdentity ? this.store.getIdentity(item) : null;
+
+		for(var i=0, l=this._by_idx.length; i<l; i++){
+			var d = this._by_idx[i];
+			if(d && ((idty && d.idty == idty) || (d.item === item))){
+				return i;
+			}
+		}
+		return -1;
+	},
+
+	filter: function(query, reRender){
+		this.query = query;
+		if(reRender){
+			this._clearData();
+		}
+		this._fetch();
+	},
+
+	_getItemAttr: function(idx, attr){
+		var item = this.getItem(idx);
+		return (!item ? this.fetchText : this.store.getValue(item, attr));
+	},
+
+	// rendering
+	_render: function(){
+		if(this.domNode.parentNode){
+			this.scroller.init(this.attr('rowCount'), this.keepRows, this.rowsPerPage);
+			this.prerender();
+			this._fetch(0, true);
+		}
+	},
+
+	// paging
+	_requestsPending: function(inRowIndex){
+		return this._pending_requests[inRowIndex];
+	},
+
+	_rowToPage: function(inRowIndex){
+		return (this.rowsPerPage ? Math.floor(inRowIndex / this.rowsPerPage) : inRowIndex);
+	},
+
+	_pageToRow: function(inPageIndex){
+		return (this.rowsPerPage ? this.rowsPerPage * inPageIndex : inPageIndex);
+	},
+
+	_preparePage: function(inRowIndex){
+		if((inRowIndex < this._bop || inRowIndex >= this._eop) && !this._addingItem){
+			var pageIndex = this._rowToPage(inRowIndex);
+			this._needPage(pageIndex);
+			this._bop = pageIndex * this.rowsPerPage;
+			this._eop = this._bop + (this.rowsPerPage || this.attr('rowCount'));
+		}
+	},
+
+	_needPage: function(inPageIndex){
+		if(!this._pages[inPageIndex]){
+			this._pages[inPageIndex] = true;
+			this._requestPage(inPageIndex);
+		}
+	},
+
+	_requestPage: function(inPageIndex){
+		var row = this._pageToRow(inPageIndex);
+		var count = Math.min(this.rowsPerPage, this.attr('rowCount') - row);
+		if(count > 0){
+			this._requests++;
+			if(!this._requestsPending(row)){
+				setTimeout(dojo.hitch(this, "_fetch", row, false), 1);
+				//this.requestRows(row, count);
+			}
+		}
+	},
+
+	getCellName: function(inCell){
+		return inCell.field;
+		//
+	},
+
+	_refresh: function(isRender){
+		this._clearData();
+		this._fetch(0, isRender);
+	},
+
+	sort: function(){
+		this._lastScrollTop = this.scrollTop;
+		this._refresh();
+	},
+
+	canSort: function(){
+		return (!this._isLoading);
+	},
+
+	getSortProps: function(){
+		var c = this.getCell(this.getSortIndex());
+		if(!c){
+			return null;
+		}else{
+			var desc = c["sortDesc"];
+			var si = !(this.sortInfo>0);
+			if(typeof desc == "undefined"){
+				desc = si;
+			}else{
+				desc = si ? !desc : desc;
+			}
+			return [{ attribute: c.field, descending: desc }];
+		}
+	},
+
+	styleRowState: function(inRow){
+		// summary: Perform row styling
+		if(this.store && this.store.getState){
+			var states=this.store.getState(inRow.index), c='';
+			for(var i=0, ss=["inflight", "error", "inserting"], s; s=ss[i]; i++){
+				if(states[s]){
+					c = ' dojoxGridRow-' + s;
+					break;
+				}
+			}
+			inRow.customClasses += c;
+		}
+	},
+
+	onStyleRow: function(inRow){
+		this.styleRowState(inRow);
+		this.inherited(arguments);
+	},
+
+	// editing
+	canEdit: function(inCell, inRowIndex){
+		return this._canEdit;
+	},
+
+	_copyAttr: function(idx, attr){
+		var row = {};
+		var backstop = {};
+		var src = this.getItem(idx);
+		return this.store.getValue(src, attr);
+	},
+
+	doStartEdit: function(inCell, inRowIndex){
+		if(!this._cache[inRowIndex]){
+			this._cache[inRowIndex] = this._copyAttr(inRowIndex, inCell.field);
+		}
+		this.onStartEdit(inCell, inRowIndex);
+	},
+
+	doApplyCellEdit: function(inValue, inRowIndex, inAttrName){
+		this.store.fetchItemByIdentity({
+			identity: this._by_idx[inRowIndex].idty,
+			onItem: dojo.hitch(this, function(item){
+				var oldValue = this.store.getValue(item, inAttrName);
+				if(typeof oldValue == 'number'){
+					inValue = isNaN(inValue) ? inValue : parseFloat(inValue);
+				}else if(typeof oldValue == 'boolean'){
+					inValue = inValue == 'true' ? true : inValue == 'false' ? false : inValue;
+				}else if(oldValue instanceof Date){
+					var asDate = new Date(inValue);
+					inValue = isNaN(asDate.getTime()) ? inValue : asDate;
+				}
+				this.store.setValue(item, inAttrName, inValue);
+				this.onApplyCellEdit(inValue, inRowIndex, inAttrName);
+			})
+		});
+	},
+
+	doCancelEdit: function(inRowIndex){
+		var cache = this._cache[inRowIndex];
+		if(cache){
+			this.updateRow(inRowIndex);
+			delete this._cache[inRowIndex];
+		}
+		this.onCancelEdit.apply(this, arguments);
+	},
+
+	doApplyEdit: function(inRowIndex, inDataAttr){
+		var cache = this._cache[inRowIndex];
+		/*if(cache){
+			var data = this.getItem(inRowIndex);
+			if(this.store.getValue(data, inDataAttr) != cache){
+				this.update(cache, data, inRowIndex);
+			}
+			delete this._cache[inRowIndex];
+		}*/
+		this.onApplyEdit(inRowIndex);
+	},
+
+	removeSelectedRows: function(){
+		// summary:
+		//		Remove the selected rows from the grid.
+		if(this._canEdit){
+			this.edit.apply();
+			var items = this.selection.getSelected();
+			if(items.length){
+				dojo.forEach(items, this.store.deleteItem, this.store);
+				this.selection.clear();
+			}
+		}
+	}
+});
+
+dojox.grid.DataGrid.markupFactory = function(props, node, ctor, cellFunc){
+	return dojox.grid._Grid.markupFactory(props, node, ctor, function(node, cellDef){
+		var field = dojo.trim(dojo.attr(node, "field")||"");
+		if(field){
+			cellDef.field = field;
+		}
+		cellDef.field = cellDef.field||cellDef.name;
+		if(cellFunc){
+			cellFunc(node, cellDef);
+		}
+	});
+}
+
+}
+
+
+dojo.i18n._preloadLocalizations("dojox.grid.nls.DataGrid", ["ROOT","ar","ca","cs","da","de","de-de","el","en","en-gb","en-us","es","es-es","fi","fi-fi","fr","fr-fr","he","he-il","hu","it","it-it","ja","ja-jp","ko","ko-kr","nl","nl-nl","no","pl","pt","pt-br","pt-pt","ru","sk","sl","sv","th","tr","xx","zh","zh-cn","zh-tw"]);
diff --git a/dojox/grid/DataSelection.js b/dojox/grid/DataSelection.js
new file mode 100644
index 0000000..a8b8615
--- /dev/null
+++ b/dojox/grid/DataSelection.js
@@ -0,0 +1,68 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.DataSelection"]){
+dojo._hasResource["dojox.grid.DataSelection"]=true;
+dojo.provide("dojox.grid.DataSelection");
+dojo.require("dojox.grid.Selection");
+dojo.declare("dojox.grid.DataSelection",dojox.grid.Selection,{getFirstSelected:function(){
+var _1=dojox.grid.Selection.prototype.getFirstSelected.call(this);
+if(_1==-1){
+return null;
+}
+return this.grid.getItem(_1);
+},getNextSelected:function(_2){
+var _3=this.grid.getItemIndex(_2);
+var _4=dojox.grid.Selection.prototype.getNextSelected.call(this,_3);
+if(_4==-1){
+return null;
+}
+return this.grid.getItem(_4);
+},getSelected:function(){
+var _5=[];
+for(var i=0,l=this.selected.length;i<l;i++){
+if(this.selected[i]){
+_5.push(this.grid.getItem(i));
+}
+}
+return _5;
+},addToSelection:function(_8){
+if(this.mode=="none"){
+return;
+}
+var _9=null;
+if(typeof _8=="number"||typeof _8=="string"){
+_9=_8;
+}else{
+_9=this.grid.getItemIndex(_8);
+}
+dojox.grid.Selection.prototype.addToSelection.call(this,_9);
+},deselect:function(_a){
+if(this.mode=="none"){
+return;
+}
+var _b=null;
+if(typeof _a=="number"||typeof _a=="string"){
+_b=_a;
+}else{
+_b=this.grid.getItemIndex(_a);
+}
+dojox.grid.Selection.prototype.deselect.call(this,_b);
+},deselectAll:function(_c){
+var _d=null;
+if(_c||typeof _c=="number"){
+if(typeof _c=="number"||typeof _c=="string"){
+_d=_c;
+}else{
+_d=this.grid.getItemIndex(_c);
+}
+dojox.grid.Selection.prototype.deselectAll.call(this,_d);
+}else{
+this.inherited(arguments);
+}
+}});
+}
diff --git a/dojox/grid/Grid.js b/dojox/grid/Grid.js
new file mode 100644
index 0000000..8590e0c
--- /dev/null
+++ b/dojox/grid/Grid.js
@@ -0,0 +1,13 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.Grid"]){
+dojo._hasResource["dojox.grid.Grid"]=true;
+dojo.provide("dojox.grid.Grid");
+dojo.require("dojox.grid.compat.Grid");
+dojo.deprecated("dojox.grid.Grid");
+}
diff --git a/dojox/grid/README b/dojox/grid/README
new file mode 100644
index 0000000..14ce050
--- /dev/null
+++ b/dojox/grid/README
@@ -0,0 +1,44 @@
+-------------------------------------------------------------------------------
+dojox.grid
+-------------------------------------------------------------------------------
+Version 1.00
+Release date: 10/04/2007
+-------------------------------------------------------------------------------
+Project state:
+beta
+-------------------------------------------------------------------------------
+Credits
+	Scott J. Miles (sjmiles at activegrid.com)
+	Steve Orvell (sorvell at activegrid.com)
+	Bryan Forbes (bryan AT reigndropsfall.net)
+-------------------------------------------------------------------------------
+Project description
+
+TurboGrid has been made available in Dojo and is now the dojox.grid!
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo Core
+Dojo Base (dnd)
+Dijit Templated Widget
+dojox.html (metrics)
+-------------------------------------------------------------------------------
+Documentation
+
+None available for this version yet.
+
+See http://www.turboajax.com/products/turbogrid/ for legacy documentation.
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/grid/*
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/html/*
+
+Install into the following directory structure:
+/dojox/grid/
+/dojox/html/
+
+...which should be at the same level as your Dojo checkout.
+-------------------------------------------------------------------------------
diff --git a/dojox/grid/Selection.js b/dojox/grid/Selection.js
new file mode 100644
index 0000000..68f062e
--- /dev/null
+++ b/dojox/grid/Selection.js
@@ -0,0 +1,189 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.Selection"]){
+dojo._hasResource["dojox.grid.Selection"]=true;
+dojo.provide("dojox.grid.Selection");
+dojo.declare("dojox.grid.Selection",null,{constructor:function(_1){
+this.grid=_1;
+this.selected=[];
+this.setMode(_1.selectionMode);
+},mode:"extended",selected:null,updating:0,selectedIndex:-1,setMode:function(_2){
+if(this.selected.length){
+this.deselectAll();
+}
+if(_2!="extended"&&_2!="multiple"&&_2!="single"&&_2!="none"){
+this.mode="extended";
+}else{
+this.mode=_2;
+}
+},onCanSelect:function(_3){
+return this.grid.onCanSelect(_3);
+},onCanDeselect:function(_4){
+return this.grid.onCanDeselect(_4);
+},onSelected:function(_5){
+},onDeselected:function(_6){
+},onChanging:function(){
+},onChanged:function(){
+},isSelected:function(_7){
+if(this.mode=="none"){
+return false;
+}
+return this.selected[_7];
+},getFirstSelected:function(){
+if(!this.selected.length||this.mode=="none"){
+return -1;
+}
+for(var i=0,l=this.selected.length;i<l;i++){
+if(this.selected[i]){
+return i;
+}
+}
+return -1;
+},getNextSelected:function(_a){
+if(this.mode=="none"){
+return -1;
+}
+for(var i=_a+1,l=this.selected.length;i<l;i++){
+if(this.selected[i]){
+return i;
+}
+}
+return -1;
+},getSelected:function(){
+var _d=[];
+for(var i=0,l=this.selected.length;i<l;i++){
+if(this.selected[i]){
+_d.push(i);
+}
+}
+return _d;
+},getSelectedCount:function(){
+var c=0;
+for(var i=0;i<this.selected.length;i++){
+if(this.selected[i]){
+c++;
+}
+}
+return c;
+},_beginUpdate:function(){
+if(this.updating==0){
+this.onChanging();
+}
+this.updating++;
+},_endUpdate:function(){
+this.updating--;
+if(this.updating==0){
+this.onChanged();
+}
+},select:function(_12){
+if(this.mode=="none"){
+return;
+}
+if(this.mode!="multiple"){
+this.deselectAll(_12);
+this.addToSelection(_12);
+}else{
+this.toggleSelect(_12);
+}
+},addToSelection:function(_13){
+if(this.mode=="none"){
+return;
+}
+_13=Number(_13);
+if(this.selected[_13]){
+this.selectedIndex=_13;
+}else{
+if(this.onCanSelect(_13)!==false){
+this.selectedIndex=_13;
+this._beginUpdate();
+this.selected[_13]=true;
+this.onSelected(_13);
+this._endUpdate();
+}
+}
+},deselect:function(_14){
+if(this.mode=="none"){
+return;
+}
+_14=Number(_14);
+if(this.selectedIndex==_14){
+this.selectedIndex=-1;
+}
+if(this.selected[_14]){
+if(this.onCanDeselect(_14)===false){
+return;
+}
+this._beginUpdate();
+delete this.selected[_14];
+this.onDeselected(_14);
+this._endUpdate();
+}
+},setSelected:function(_15,_16){
+this[(_16?"addToSelection":"deselect")](_15);
+},toggleSelect:function(_17){
+this.setSelected(_17,!this.selected[_17]);
+},_range:function(_18,_19,_1a){
+var s=(_18>=0?_18:_19),e=_19;
+if(s>e){
+e=s;
+s=_19;
+}
+for(var i=s;i<=e;i++){
+_1a(i);
+}
+},selectRange:function(_1e,_1f){
+this._range(_1e,_1f,dojo.hitch(this,"addToSelection"));
+},deselectRange:function(_20,_21){
+this._range(_20,_21,dojo.hitch(this,"deselect"));
+},insert:function(_22){
+this.selected.splice(_22,0,false);
+if(this.selectedIndex>=_22){
+this.selectedIndex++;
+}
+},remove:function(_23){
+this.selected.splice(_23,1);
+if(this.selectedIndex>=_23){
+this.selectedIndex--;
+}
+},deselectAll:function(_24){
+for(var i in this.selected){
+if((i!=_24)&&(this.selected[i]===true)){
+this.deselect(i);
+}
+}
+},clickSelect:function(_26,_27,_28){
+if(this.mode=="none"){
+return;
+}
+this._beginUpdate();
+if(this.mode!="extended"){
+this.select(_26);
+}else{
+var _29=this.selectedIndex;
+if(!_27){
+this.deselectAll(_26);
+}
+if(_28){
+this.selectRange(_29,_26);
+}else{
+if(_27){
+this.toggleSelect(_26);
+}else{
+this.addToSelection(_26);
+}
+}
+}
+this._endUpdate();
+},clickSelectEvent:function(e){
+this.clickSelect(e.rowIndex,dojo.dnd.getCopyKeyState(e),e.shiftKey);
+},clear:function(){
+this._beginUpdate();
+this.deselectAll();
+this._endUpdate();
+}});
+}
diff --git a/dojox/grid/VirtualGrid.js b/dojox/grid/VirtualGrid.js
new file mode 100644
index 0000000..4793a3e
--- /dev/null
+++ b/dojox/grid/VirtualGrid.js
@@ -0,0 +1,13 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.VirtualGrid"]){
+dojo._hasResource["dojox.grid.VirtualGrid"]=true;
+dojo.provide("dojox.grid.VirtualGrid");
+dojo.require("dojox.grid.compat.VirtualGrid");
+dojo.deprecated("dojox.grid.VirtualGrid");
+}
diff --git a/dojox/grid/_Builder.js b/dojox/grid/_Builder.js
new file mode 100644
index 0000000..65df126
--- /dev/null
+++ b/dojox/grid/_Builder.js
@@ -0,0 +1,469 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid._Builder"]){
+dojo._hasResource["dojox.grid._Builder"]=true;
+dojo.provide("dojox.grid._Builder");
+dojo.require("dojox.grid.util");
+dojo.require("dojo.dnd.Moveable");
+(function(){
+var dg=dojox.grid;
+var _2=function(td){
+return td.cellIndex>=0?td.cellIndex:dojo.indexOf(td.parentNode.cells,td);
+};
+var _4=function(tr){
+return tr.rowIndex>=0?tr.rowIndex:dojo.indexOf(tr.parentNode.childNodes,tr);
+};
+var _6=function(_7,_8){
+return _7&&((_7.rows||0)[_8]||_7.childNodes[_8]);
+};
+var _9=function(_a){
+for(var n=_a;n&&n.tagName!="TABLE";n=n.parentNode){
+}
+return n;
+};
+var _c=function(_d,_e){
+for(var n=_d;n&&_e(n);n=n.parentNode){
+}
+return n;
+};
+var _10=function(_11){
+var _12=_11.toUpperCase();
+return function(_13){
+return _13.tagName!=_12;
+};
+};
+var _14=dojox.grid.util.rowIndexTag;
+var _15=dojox.grid.util.gridViewTag;
+dg._Builder=dojo.extend(function(_16){
+if(_16){
+this.view=_16;
+this.grid=_16.grid;
+}
+},{view:null,_table:"<table class=\"dojoxGridRowTable\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" role=\""+(dojo.isFF<3?"wairole:":"")+"presentation\"",getTableArray:function(){
+var _17=[this._table];
+if(this.view.viewWidth){
+_17.push([" style=\"width:",this.view.viewWidth,";\""].join(""));
+}
+_17.push(">");
+return _17;
+},generateCellMarkup:function(_18,_19,_1a,_1b){
+var _1c=[],_1d;
+var _1e=dojo.isFF<3?"wairole:":"";
+if(_1b){
+var _1f=_18.index!=_18.grid.getSortIndex()?"":_18.grid.sortInfo>0?"aria-sort=\"ascending\"":"aria-sort=\"descending\"";
+_1d=["<th tabIndex=\"-1\" role=\"",_1e,"columnheader\"",_1f];
+}else{
+_1d=["<td tabIndex=\"-1\" role=\"",_1e,"gridcell\""];
+}
+_18.colSpan&&_1d.push(" colspan=\"",_18.colSpan,"\"");
+_18.rowSpan&&_1d.push(" rowspan=\"",_18.rowSpan,"\"");
+_1d.push(" class=\"dojoxGridCell ");
+_18.classes&&_1d.push(_18.classes," ");
+_1a&&_1d.push(_1a," ");
+_1c.push(_1d.join(""));
+_1c.push("");
+_1d=["\" idx=\"",_18.index,"\" style=\""];
+if(_19&&_19[_19.length-1]!=";"){
+_19+=";";
+}
+_1d.push(_18.styles,_19||"",_18.hidden?"display:none;":"");
+_18.unitWidth&&_1d.push("width:",_18.unitWidth,";");
+_1c.push(_1d.join(""));
+_1c.push("");
+_1d=["\""];
+_18.attrs&&_1d.push(" ",_18.attrs);
+_1d.push(">");
+_1c.push(_1d.join(""));
+_1c.push("");
+_1c.push(_1b?"</th>":"</td>");
+return _1c;
+},isCellNode:function(_20){
+return Boolean(_20&&_20!=dojo.doc&&dojo.attr(_20,"idx"));
+},getCellNodeIndex:function(_21){
+return _21?Number(dojo.attr(_21,"idx")):-1;
+},getCellNode:function(_22,_23){
+for(var i=0,row;row=_6(_22.firstChild,i);i++){
+for(var j=0,_27;_27=row.cells[j];j++){
+if(this.getCellNodeIndex(_27)==_23){
+return _27;
+}
+}
+}
+},findCellTarget:function(_28,_29){
+var n=_28;
+while(n&&(!this.isCellNode(n)||(n.offsetParent&&_15 in n.offsetParent.parentNode&&n.offsetParent.parentNode[_15]!=this.view.id))&&(n!=_29)){
+n=n.parentNode;
+}
+return n!=_29?n:null;
+},baseDecorateEvent:function(e){
+e.dispatch="do"+e.type;
+e.grid=this.grid;
+e.sourceView=this.view;
+e.cellNode=this.findCellTarget(e.target,e.rowNode);
+e.cellIndex=this.getCellNodeIndex(e.cellNode);
+e.cell=(e.cellIndex>=0?this.grid.getCell(e.cellIndex):null);
+},findTarget:function(_2c,_2d){
+var n=_2c;
+while(n&&(n!=this.domNode)&&(!(_2d in n)||(_15 in n&&n[_15]!=this.view.id))){
+n=n.parentNode;
+}
+return (n!=this.domNode)?n:null;
+},findRowTarget:function(_2f){
+return this.findTarget(_2f,_14);
+},isIntraNodeEvent:function(e){
+try{
+return (e.cellNode&&e.relatedTarget&&dojo.isDescendant(e.relatedTarget,e.cellNode));
+}
+catch(x){
+return false;
+}
+},isIntraRowEvent:function(e){
+try{
+var row=e.relatedTarget&&this.findRowTarget(e.relatedTarget);
+return !row&&(e.rowIndex==-1)||row&&(e.rowIndex==row.gridRowIndex);
+}
+catch(x){
+return false;
+}
+},dispatchEvent:function(e){
+if(e.dispatch in this){
+return this[e.dispatch](e);
+}
+},domouseover:function(e){
+if(e.cellNode&&(e.cellNode!=this.lastOverCellNode)){
+this.lastOverCellNode=e.cellNode;
+this.grid.onMouseOver(e);
+}
+this.grid.onMouseOverRow(e);
+},domouseout:function(e){
+if(e.cellNode&&(e.cellNode==this.lastOverCellNode)&&!this.isIntraNodeEvent(e,this.lastOverCellNode)){
+this.lastOverCellNode=null;
+this.grid.onMouseOut(e);
+if(!this.isIntraRowEvent(e)){
+this.grid.onMouseOutRow(e);
+}
+}
+},domousedown:function(e){
+if(e.cellNode){
+this.grid.onMouseDown(e);
+}
+this.grid.onMouseDownRow(e);
+}});
+dg._ContentBuilder=dojo.extend(function(_37){
+dg._Builder.call(this,_37);
+},dg._Builder.prototype,{update:function(){
+this.prepareHtml();
+},prepareHtml:function(){
+var _38=this.grid.get,_39=this.view.structure.cells;
+for(var j=0,row;(row=_39[j]);j++){
+for(var i=0,_3d;(_3d=row[i]);i++){
+_3d.get=_3d.get||(_3d.value==undefined)&&_38;
+_3d.markup=this.generateCellMarkup(_3d,_3d.cellStyles,_3d.cellClasses,false);
+}
+}
+},generateHtml:function(_3e,_3f){
+var _40=this.getTableArray(),v=this.view,_42=v.structure.cells,_43=this.grid.getItem(_3f);
+dojox.grid.util.fire(this.view,"onBeforeRow",[_3f,_42]);
+for(var j=0,row;(row=_42[j]);j++){
+if(row.hidden||row.header){
+continue;
+}
+_40.push(!row.invisible?"<tr>":"<tr class=\"dojoxGridInvisible\">");
+for(var i=0,_47,m,cc,cs;(_47=row[i]);i++){
+m=_47.markup,cc=_47.customClasses=[],cs=_47.customStyles=[];
+m[5]=_47.format(_3f,_43);
+m[1]=cc.join(" ");
+m[3]=cs.join(";");
+_40.push.apply(_40,m);
+}
+_40.push("</tr>");
+}
+_40.push("</table>");
+return _40.join("");
+},decorateEvent:function(e){
+e.rowNode=this.findRowTarget(e.target);
+if(!e.rowNode){
+return false;
+}
+e.rowIndex=e.rowNode[_14];
+this.baseDecorateEvent(e);
+e.cell=this.grid.getCell(e.cellIndex);
+return true;
+}});
+dg._HeaderBuilder=dojo.extend(function(_4c){
+this.moveable=null;
+dg._Builder.call(this,_4c);
+},dg._Builder.prototype,{_skipBogusClicks:false,overResizeWidth:4,minColWidth:1,update:function(){
+if(this.tableMap){
+this.tableMap.mapRows(this.view.structure.cells);
+}else{
+this.tableMap=new dg._TableMap(this.view.structure.cells);
+}
+},generateHtml:function(_4d,_4e){
+var _4f=this.getTableArray(),_50=this.view.structure.cells;
+dojox.grid.util.fire(this.view,"onBeforeRow",[-1,_50]);
+for(var j=0,row;(row=_50[j]);j++){
+if(row.hidden){
+continue;
+}
+_4f.push(!row.invisible?"<tr>":"<tr class=\"dojoxGridInvisible\">");
+for(var i=0,_54,_55;(_54=row[i]);i++){
+_54.customClasses=[];
+_54.customStyles=[];
+if(this.view.simpleStructure){
+if(_54.headerClasses){
+if(_54.headerClasses.indexOf("dojoDndItem")==-1){
+_54.headerClasses+=" dojoDndItem";
+}
+}else{
+_54.headerClasses="dojoDndItem";
+}
+if(_54.attrs){
+if(_54.attrs.indexOf("dndType='gridColumn_")==-1){
+_54.attrs+=" dndType='gridColumn_"+this.grid.id+"'";
+}
+}else{
+_54.attrs="dndType='gridColumn_"+this.grid.id+"'";
+}
+}
+_55=this.generateCellMarkup(_54,_54.headerStyles,_54.headerClasses,true);
+_55[5]=(_4e!=undefined?_4e:_4d(_54));
+_55[3]=_54.customStyles.join(";");
+_55[1]=_54.customClasses.join(" ");
+_4f.push(_55.join(""));
+}
+_4f.push("</tr>");
+}
+_4f.push("</table>");
+return _4f.join("");
+},getCellX:function(e){
+var x=e.layerX;
+if(dojo.isMoz){
+var n=_c(e.target,_10("th"));
+x-=(n&&n.offsetLeft)||0;
+var t=e.sourceView.getScrollbarWidth();
+if(!dojo._isBodyLtr()&&e.sourceView.headerNode.scrollLeft<t){
+x-=t;
+}
+}
+var n=_c(e.target,function(){
+if(!n||n==e.cellNode){
+return false;
+}
+x+=(n.offsetLeft<0?0:n.offsetLeft);
+return true;
+});
+return x;
+},decorateEvent:function(e){
+this.baseDecorateEvent(e);
+e.rowIndex=-1;
+e.cellX=this.getCellX(e);
+return true;
+},prepareResize:function(e,mod){
+do{
+var i=_2(e.cellNode);
+e.cellNode=(i?e.cellNode.parentNode.cells[i+mod]:null);
+e.cellIndex=(e.cellNode?this.getCellNodeIndex(e.cellNode):-1);
+}while(e.cellNode&&e.cellNode.style.display=="none");
+return Boolean(e.cellNode);
+},canResize:function(e){
+if(!e.cellNode||e.cellNode.colSpan>1){
+return false;
+}
+var _5f=this.grid.getCell(e.cellIndex);
+return !_5f.noresize&&_5f.canResize();
+},overLeftResizeArea:function(e){
+if(dojo.isIE){
+var tN=e.target;
+if(dojo.hasClass(tN,"dojoxGridArrowButtonNode")||dojo.hasClass(tN,"dojoxGridArrowButtonChar")){
+return false;
+}
+}
+if(dojo._isBodyLtr()){
+return (e.cellIndex>0)&&(e.cellX<this.overResizeWidth)&&this.prepareResize(e,-1);
+}
+var t=e.cellNode&&(e.cellX<this.overResizeWidth);
+return t;
+},overRightResizeArea:function(e){
+if(dojo.isIE){
+var tN=e.target;
+if(dojo.hasClass(tN,"dojoxGridArrowButtonNode")||dojo.hasClass(tN,"dojoxGridArrowButtonChar")){
+return false;
+}
+}
+if(dojo._isBodyLtr()){
+return e.cellNode&&(e.cellX>=e.cellNode.offsetWidth-this.overResizeWidth);
+}
+return (e.cellIndex>0)&&(e.cellX>=e.cellNode.offsetWidth-this.overResizeWidth)&&this.prepareResize(e,-1);
+},domousemove:function(e){
+if(!this.moveable){
+var c=(this.overRightResizeArea(e)?"e-resize":(this.overLeftResizeArea(e)?"w-resize":""));
+if(c&&!this.canResize(e)){
+c="not-allowed";
+}
+if(dojo.isIE){
+var t=e.sourceView.headerNode.scrollLeft;
+e.sourceView.headerNode.style.cursor=c||"";
+e.sourceView.headerNode.scrollLeft=t;
+}else{
+e.sourceView.headerNode.style.cursor=c||"";
+}
+if(c){
+dojo.stopEvent(e);
+}
+}
+},domousedown:function(e){
+if(!this.moveable){
+if((this.overRightResizeArea(e)||this.overLeftResizeArea(e))&&this.canResize(e)){
+this.beginColumnResize(e);
+}else{
+this.grid.onMouseDown(e);
+this.grid.onMouseOverRow(e);
+}
+}
+},doclick:function(e){
+if(this._skipBogusClicks){
+dojo.stopEvent(e);
+return true;
+}
+},beginColumnResize:function(e){
+this.moverDiv=document.createElement("div");
+dojo.style(this.moverDiv,{position:"absolute",left:0});
+dojo.body().appendChild(this.moverDiv);
+var m=this.moveable=new dojo.dnd.Moveable(this.moverDiv);
+var _6c=[],_6d=this.tableMap.findOverlappingNodes(e.cellNode);
+for(var i=0,_6f;(_6f=_6d[i]);i++){
+_6c.push({node:_6f,index:this.getCellNodeIndex(_6f),width:_6f.offsetWidth});
+}
+var _70=e.sourceView;
+var adj=dojo._isBodyLtr()?1:-1;
+var _72=e.grid.views.views;
+var _73=[];
+for(var i=_70.idx+adj,_74;(_74=_72[i]);i=i+adj){
+_73.push({node:_74.headerNode,left:window.parseInt(_74.headerNode.style.left)});
+}
+var _75=_70.headerContentNode.firstChild;
+var _76={scrollLeft:e.sourceView.headerNode.scrollLeft,view:_70,node:e.cellNode,index:e.cellIndex,w:dojo.contentBox(e.cellNode).w,vw:dojo.contentBox(_70.headerNode).w,table:_75,tw:dojo.contentBox(_75).w,spanners:_6c,followers:_73};
+m.onMove=dojo.hitch(this,"doResizeColumn",_76);
+dojo.connect(m,"onMoveStop",dojo.hitch(this,function(){
+this.endResizeColumn(_76);
+if(_76.node.releaseCapture){
+_76.node.releaseCapture();
+}
+this.moveable.destroy();
+delete this.moveable;
+this.moveable=null;
+}));
+_70.convertColPctToFixed();
+if(e.cellNode.setCapture){
+e.cellNode.setCapture();
+}
+m.onMouseDown(e);
+},doResizeColumn:function(_77,_78,_79){
+var _7a=dojo._isBodyLtr();
+var _7b=_7a?_79.l:-_79.l;
+var w=_77.w+_7b;
+var vw=_77.vw+_7b;
+var tw=_77.tw+_7b;
+if(w>=this.minColWidth){
+for(var i=0,s,sw;(s=_77.spanners[i]);i++){
+sw=s.width+_7b;
+s.node.style.width=sw+"px";
+_77.view.setColWidth(s.index,sw);
+}
+for(var i=0,f,fl;(f=_77.followers[i]);i++){
+fl=f.left+_7b;
+f.node.style.left=fl+"px";
+}
+_77.node.style.width=w+"px";
+_77.view.setColWidth(_77.index,w);
+_77.view.headerNode.style.width=vw+"px";
+_77.view.setColumnsWidth(tw);
+if(!_7a){
+_77.view.headerNode.scrollLeft=_77.scrollLeft+_7b;
+}
+}
+if(_77.view.flexCells&&!_77.view.testFlexCells()){
+var t=_9(_77.node);
+t&&(t.style.width="");
+}
+},endResizeColumn:function(_85){
+dojo.destroy(this.moverDiv);
+delete this.moverDiv;
+this._skipBogusClicks=true;
+var _86=dojo.connect(_85.view,"update",this,function(){
+dojo.disconnect(_86);
+this._skipBogusClicks=false;
+});
+setTimeout(dojo.hitch(_85.view,"update"),50);
+}});
+dg._TableMap=dojo.extend(function(_87){
+this.mapRows(_87);
+},{map:null,mapRows:function(_88){
+var _89=_88.length;
+if(!_89){
+return;
+}
+this.map=[];
+for(var j=0,row;(row=_88[j]);j++){
+this.map[j]=[];
+}
+for(var j=0,row;(row=_88[j]);j++){
+for(var i=0,x=0,_8e,_8f,_90;(_8e=row[i]);i++){
+while(this.map[j][x]){
+x++;
+}
+this.map[j][x]={c:i,r:j};
+_90=_8e.rowSpan||1;
+_8f=_8e.colSpan||1;
+for(var y=0;y<_90;y++){
+for(var s=0;s<_8f;s++){
+this.map[j+y][x+s]=this.map[j][x];
+}
+}
+x+=_8f;
+}
+}
+},dumpMap:function(){
+for(var j=0,row,h="";(row=this.map[j]);j++,h=""){
+for(var i=0,_97;(_97=row[i]);i++){
+h+=_97.r+","+_97.c+"   ";
+}
+}
+},getMapCoords:function(_98,_99){
+for(var j=0,row;(row=this.map[j]);j++){
+for(var i=0,_9d;(_9d=row[i]);i++){
+if(_9d.c==_99&&_9d.r==_98){
+return {j:j,i:i};
+}
+}
+}
+return {j:-1,i:-1};
+},getNode:function(_9e,_9f,_a0){
+var row=_9e&&_9e.rows[_9f];
+return row&&row.cells[_a0];
+},_findOverlappingNodes:function(_a2,_a3,_a4){
+var _a5=[];
+var m=this.getMapCoords(_a3,_a4);
+var row=this.map[m.j];
+for(var j=0,row;(row=this.map[j]);j++){
+if(j==m.j){
+continue;
+}
+var rw=row[m.i];
+var n=(rw?this.getNode(_a2,rw.r,rw.c):null);
+if(n){
+_a5.push(n);
+}
+}
+return _a5;
+},findOverlappingNodes:function(_ab){
+return this._findOverlappingNodes(_9(_ab),_4(_ab.parentNode),_2(_ab));
+}});
+})();
+}
diff --git a/dojox/grid/_EditManager.js b/dojox/grid/_EditManager.js
new file mode 100644
index 0000000..632bcda
--- /dev/null
+++ b/dojox/grid/_EditManager.js
@@ -0,0 +1,129 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid._EditManager"]){
+dojo._hasResource["dojox.grid._EditManager"]=true;
+dojo.provide("dojox.grid._EditManager");
+dojo.require("dojox.grid.util");
+dojo.declare("dojox.grid._EditManager",null,{constructor:function(_1){
+this.grid=_1;
+this.connections=[];
+if(dojo.isIE){
+this.connections.push(dojo.connect(document.body,"onfocus",dojo.hitch(this,"_boomerangFocus")));
+}
+},info:{},destroy:function(){
+dojo.forEach(this.connections,dojo.disconnect);
+},cellFocus:function(_2,_3){
+if(this.grid.singleClickEdit||this.isEditRow(_3)){
+this.setEditCell(_2,_3);
+}else{
+this.apply();
+}
+if(this.isEditing()||(_2&&_2.editable&&_2.alwaysEditing)){
+this._focusEditor(_2,_3);
+}
+},rowClick:function(e){
+if(this.isEditing()&&!this.isEditRow(e.rowIndex)){
+this.apply();
+}
+},styleRow:function(_5){
+if(_5.index==this.info.rowIndex){
+_5.customClasses+=" dojoxGridRowEditing";
+}
+},dispatchEvent:function(e){
+var c=e.cell,ed=(c&&c["editable"])?c:0;
+return ed&&ed.dispatchEvent(e.dispatch,e);
+},isEditing:function(){
+return this.info.rowIndex!==undefined;
+},isEditCell:function(_9,_a){
+return (this.info.rowIndex===_9)&&(this.info.cell.index==_a);
+},isEditRow:function(_b){
+return this.info.rowIndex===_b;
+},setEditCell:function(_c,_d){
+if(!this.isEditCell(_d,_c.index)&&this.grid.canEdit&&this.grid.canEdit(_c,_d)){
+this.start(_c,_d,this.isEditRow(_d)||_c.editable);
+}
+},_focusEditor:function(_e,_f){
+dojox.grid.util.fire(_e,"focus",[_f]);
+},focusEditor:function(){
+if(this.isEditing()){
+this._focusEditor(this.info.cell,this.info.rowIndex);
+}
+},_boomerangWindow:500,_shouldCatchBoomerang:function(){
+return this._catchBoomerang>new Date().getTime();
+},_boomerangFocus:function(){
+if(this._shouldCatchBoomerang()){
+this.grid.focus.focusGrid();
+this.focusEditor();
+this._catchBoomerang=0;
+}
+},_doCatchBoomerang:function(){
+if(dojo.isIE){
+this._catchBoomerang=new Date().getTime()+this._boomerangWindow;
+}
+},start:function(_10,_11,_12){
+this.grid.beginUpdate();
+this.editorApply();
+if(this.isEditing()&&!this.isEditRow(_11)){
+this.applyRowEdit();
+this.grid.updateRow(_11);
+}
+if(_12){
+this.info={cell:_10,rowIndex:_11};
+this.grid.doStartEdit(_10,_11);
+this.grid.updateRow(_11);
+}else{
+this.info={};
+}
+this.grid.endUpdate();
+this.grid.focus.focusGrid();
+this._focusEditor(_10,_11);
+this._doCatchBoomerang();
+},_editorDo:function(_13){
+var c=this.info.cell;
+c&&c.editable&&c[_13](this.info.rowIndex);
+},editorApply:function(){
+this._editorDo("apply");
+},editorCancel:function(){
+this._editorDo("cancel");
+},applyCellEdit:function(_15,_16,_17){
+if(this.grid.canEdit(_16,_17)){
+this.grid.doApplyCellEdit(_15,_17,_16.field);
+}
+},applyRowEdit:function(){
+this.grid.doApplyEdit(this.info.rowIndex,this.info.cell.field);
+},apply:function(){
+if(this.isEditing()){
+this.grid.beginUpdate();
+this.editorApply();
+this.applyRowEdit();
+this.info={};
+this.grid.endUpdate();
+this.grid.focus.focusGrid();
+this._doCatchBoomerang();
+}
+},cancel:function(){
+if(this.isEditing()){
+this.grid.beginUpdate();
+this.editorCancel();
+this.info={};
+this.grid.endUpdate();
+this.grid.focus.focusGrid();
+this._doCatchBoomerang();
+}
+},save:function(_18,_19){
+var c=this.info.cell;
+if(this.isEditRow(_18)&&(!_19||c.view==_19)&&c.editable){
+c.save(c,this.info.rowIndex);
+}
+},restore:function(_1b,_1c){
+var c=this.info.cell;
+if(this.isEditRow(_1c)&&c.view==_1b&&c.editable){
+c.restore(c,this.info.rowIndex);
+}
+}});
+}
diff --git a/dojox/grid/_Events.js b/dojox/grid/_Events.js
new file mode 100644
index 0000000..ea2c26d
--- /dev/null
+++ b/dojox/grid/_Events.js
@@ -0,0 +1,218 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid._Events"]){
+dojo._hasResource["dojox.grid._Events"]=true;
+dojo.provide("dojox.grid._Events");
+dojo.declare("dojox.grid._Events",null,{cellOverClass:"dojoxGridCellOver",onKeyEvent:function(e){
+this.dispatchKeyEvent(e);
+},onContentEvent:function(e){
+this.dispatchContentEvent(e);
+},onHeaderEvent:function(e){
+this.dispatchHeaderEvent(e);
+},onStyleRow:function(_4){
+var i=_4;
+i.customClasses+=(i.odd?" dojoxGridRowOdd":"")+(i.selected?" dojoxGridRowSelected":"")+(i.over?" dojoxGridRowOver":"");
+this.focus.styleRow(_4);
+this.edit.styleRow(_4);
+},onKeyDown:function(e){
+if(e.altKey||e.metaKey){
+return;
+}
+var dk=dojo.keys;
+switch(e.keyCode){
+case dk.ESCAPE:
+this.edit.cancel();
+break;
+case dk.ENTER:
+if(!this.edit.isEditing()){
+var _8=this.focus.getHeaderIndex();
+if(_8>=0){
+this.setSortIndex(_8);
+break;
+}else{
+this.selection.clickSelect(this.focus.rowIndex,dojo.dnd.getCopyKeyState(e),e.shiftKey);
+}
+dojo.stopEvent(e);
+}
+if(!e.shiftKey){
+var _9=this.edit.isEditing();
+this.edit.apply();
+if(!_9){
+this.edit.setEditCell(this.focus.cell,this.focus.rowIndex);
+}
+}
+if(!this.edit.isEditing()){
+var _a=this.focus.focusView||this.views.views[0];
+_a.content.decorateEvent(e);
+this.onRowClick(e);
+}
+break;
+case dk.SPACE:
+if(!this.edit.isEditing()){
+var _8=this.focus.getHeaderIndex();
+if(_8>=0){
+this.setSortIndex(_8);
+break;
+}else{
+this.selection.clickSelect(this.focus.rowIndex,dojo.dnd.getCopyKeyState(e),e.shiftKey);
+}
+dojo.stopEvent(e);
+}
+break;
+case dk.TAB:
+this.focus[e.shiftKey?"previousKey":"nextKey"](e);
+break;
+case dk.LEFT_ARROW:
+case dk.RIGHT_ARROW:
+if(!this.edit.isEditing()){
+dojo.stopEvent(e);
+var _b=(e.keyCode==dk.LEFT_ARROW)?1:-1;
+if(dojo._isBodyLtr()){
+_b*=-1;
+}
+this.focus.move(0,_b);
+}
+break;
+case dk.UP_ARROW:
+if(!this.edit.isEditing()&&this.focus.rowIndex!=0){
+dojo.stopEvent(e);
+this.focus.move(-1,0);
+}
+break;
+case dk.DOWN_ARROW:
+if(!this.edit.isEditing()&&this.store&&this.focus.rowIndex+1!=this.rowCount){
+dojo.stopEvent(e);
+this.focus.move(1,0);
+}
+break;
+case dk.PAGE_UP:
+if(!this.edit.isEditing()&&this.focus.rowIndex!=0){
+dojo.stopEvent(e);
+if(this.focus.rowIndex!=this.scroller.firstVisibleRow+1){
+this.focus.move(this.scroller.firstVisibleRow-this.focus.rowIndex,0);
+}else{
+this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex-1));
+this.focus.move(this.scroller.firstVisibleRow-this.scroller.lastVisibleRow+1,0);
+}
+}
+break;
+case dk.PAGE_DOWN:
+if(!this.edit.isEditing()&&this.focus.rowIndex+1!=this.rowCount){
+dojo.stopEvent(e);
+if(this.focus.rowIndex!=this.scroller.lastVisibleRow-1){
+this.focus.move(this.scroller.lastVisibleRow-this.focus.rowIndex-1,0);
+}else{
+this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex+1));
+this.focus.move(this.scroller.lastVisibleRow-this.scroller.firstVisibleRow-1,0);
+}
+}
+break;
+}
+},onMouseOver:function(e){
+e.rowIndex==-1?this.onHeaderCellMouseOver(e):this.onCellMouseOver(e);
+},onMouseOut:function(e){
+e.rowIndex==-1?this.onHeaderCellMouseOut(e):this.onCellMouseOut(e);
+},onMouseDown:function(e){
+e.rowIndex==-1?this.onHeaderCellMouseDown(e):this.onCellMouseDown(e);
+},onMouseOverRow:function(e){
+if(!this.rows.isOver(e.rowIndex)){
+this.rows.setOverRow(e.rowIndex);
+e.rowIndex==-1?this.onHeaderMouseOver(e):this.onRowMouseOver(e);
+}
+},onMouseOutRow:function(e){
+if(this.rows.isOver(-1)){
+this.onHeaderMouseOut(e);
+}else{
+if(!this.rows.isOver(-2)){
+this.rows.setOverRow(-2);
+this.onRowMouseOut(e);
+}
+}
+},onMouseDownRow:function(e){
+if(e.rowIndex!=-1){
+this.onRowMouseDown(e);
+}
+},onCellMouseOver:function(e){
+if(e.cellNode){
+dojo.addClass(e.cellNode,this.cellOverClass);
+}
+},onCellMouseOut:function(e){
+if(e.cellNode){
+dojo.removeClass(e.cellNode,this.cellOverClass);
+}
+},onCellMouseDown:function(e){
+},onCellClick:function(e){
+this._click[0]=this._click[1];
+this._click[1]=e;
+if(!this.edit.isEditCell(e.rowIndex,e.cellIndex)){
+this.focus.setFocusCell(e.cell,e.rowIndex);
+}
+this.onRowClick(e);
+},onCellDblClick:function(e){
+if(dojo.isIE){
+this.edit.setEditCell(this._click[1].cell,this._click[1].rowIndex);
+}else{
+if(this._click[0].rowIndex!=this._click[1].rowIndex){
+this.edit.setEditCell(this._click[0].cell,this._click[0].rowIndex);
+}else{
+this.edit.setEditCell(e.cell,e.rowIndex);
+}
+}
+this.onRowDblClick(e);
+},onCellContextMenu:function(e){
+this.onRowContextMenu(e);
+},onCellFocus:function(_18,_19){
+this.edit.cellFocus(_18,_19);
+},onRowClick:function(e){
+this.edit.rowClick(e);
+this.selection.clickSelectEvent(e);
+},onRowDblClick:function(e){
+},onRowMouseOver:function(e){
+},onRowMouseOut:function(e){
+},onRowMouseDown:function(e){
+},onRowContextMenu:function(e){
+dojo.stopEvent(e);
+},onHeaderMouseOver:function(e){
+},onHeaderMouseOut:function(e){
+},onHeaderCellMouseOver:function(e){
+if(e.cellNode){
+dojo.addClass(e.cellNode,this.cellOverClass);
+}
+},onHeaderCellMouseOut:function(e){
+if(e.cellNode){
+dojo.removeClass(e.cellNode,this.cellOverClass);
+}
+},onHeaderCellMouseDown:function(e){
+},onHeaderClick:function(e){
+},onHeaderCellClick:function(e){
+this.setSortIndex(e.cell.index);
+this.onHeaderClick(e);
+},onHeaderDblClick:function(e){
+},onHeaderCellDblClick:function(e){
+this.onHeaderDblClick(e);
+},onHeaderCellContextMenu:function(e){
+this.onHeaderContextMenu(e);
+},onHeaderContextMenu:function(e){
+if(!this.headerMenu){
+dojo.stopEvent(e);
+}
+},onStartEdit:function(_2b,_2c){
+},onApplyCellEdit:function(_2d,_2e,_2f){
+},onCancelEdit:function(_30){
+},onApplyEdit:function(_31){
+},onCanSelect:function(_32){
+return true;
+},onCanDeselect:function(_33){
+return true;
+},onSelected:function(_34){
+this.updateRowStyles(_34);
+},onDeselected:function(_35){
+this.updateRowStyles(_35);
+},onSelectionChanged:function(){
+}});
+}
diff --git a/dojox/grid/_FocusManager.js b/dojox/grid/_FocusManager.js
new file mode 100644
index 0000000..c5922b1
--- /dev/null
+++ b/dojox/grid/_FocusManager.js
@@ -0,0 +1,356 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid._FocusManager"]){
+dojo._hasResource["dojox.grid._FocusManager"]=true;
+dojo.provide("dojox.grid._FocusManager");
+dojo.require("dojox.grid.util");
+dojo.declare("dojox.grid._FocusManager",null,{constructor:function(_1){
+this.grid=_1;
+this.cell=null;
+this.rowIndex=-1;
+this._connects=[];
+this._connects.push(dojo.connect(this.grid.domNode,"onfocus",this,"doFocus"));
+this._connects.push(dojo.connect(this.grid.domNode,"onblur",this,"doBlur"));
+this._connects.push(dojo.connect(this.grid.lastFocusNode,"onfocus",this,"doLastNodeFocus"));
+this._connects.push(dojo.connect(this.grid.lastFocusNode,"onblur",this,"doLastNodeBlur"));
+this._connects.push(dojo.connect(this.grid,"_onFetchComplete",this,"_delayedCellFocus"));
+this._connects.push(dojo.connect(this.grid,"postrender",this,"_delayedHeaderFocus"));
+},destroy:function(){
+dojo.forEach(this._connects,dojo.disconnect);
+delete this.grid;
+delete this.cell;
+},_colHeadNode:null,_colHeadFocusIdx:null,tabbingOut:false,focusClass:"dojoxGridCellFocus",focusView:null,initFocusView:function(){
+this.focusView=this.grid.views.getFirstScrollingView()||this.focusView;
+this._initColumnHeaders();
+},isFocusCell:function(_2,_3){
+return (this.cell==_2)&&(this.rowIndex==_3);
+},isLastFocusCell:function(){
+if(this.cell){
+return (this.rowIndex==this.grid.rowCount-1)&&(this.cell.index==this.grid.layout.cellCount-1);
+}
+return false;
+},isFirstFocusCell:function(){
+if(this.cell){
+return (this.rowIndex==0)&&(this.cell.index==0);
+}
+return false;
+},isNoFocusCell:function(){
+return (this.rowIndex<0)||!this.cell;
+},isNavHeader:function(){
+return (!!this._colHeadNode);
+},getHeaderIndex:function(){
+if(this._colHeadNode){
+return dojo.indexOf(this._findHeaderCells(),this._colHeadNode);
+}else{
+return -1;
+}
+},_focusifyCellNode:function(_4){
+var n=this.cell&&this.cell.getNode(this.rowIndex);
+if(n){
+dojo.toggleClass(n,this.focusClass,_4);
+if(_4){
+var sl=this.scrollIntoView();
+try{
+if(!this.grid.edit.isEditing()){
+dojox.grid.util.fire(n,"focus");
+if(sl){
+this.cell.view.scrollboxNode.scrollLeft=sl;
+}
+}
+}
+catch(e){
+}
+}
+}
+},_delayedCellFocus:function(){
+if(this.isNavHeader()){
+return;
+}
+var n=this.cell&&this.cell.getNode(this.rowIndex);
+if(n){
+try{
+if(!this.grid.edit.isEditing()){
+dojo.toggleClass(n,this.focusClass,true);
+dojox.grid.util.fire(n,"focus");
+}
+}
+catch(e){
+}
+}
+},_delayedHeaderFocus:function(){
+if(this.isNavHeader()){
+this.focusHeader();
+}
+},_initColumnHeaders:function(){
+this._connects.push(dojo.connect(this.grid.viewsHeaderNode,"onblur",this,"doBlurHeader"));
+var _8=this._findHeaderCells();
+for(var i=0;i<_8.length;i++){
+this._connects.push(dojo.connect(_8[i],"onfocus",this,"doColHeaderFocus"));
+this._connects.push(dojo.connect(_8[i],"onblur",this,"doColHeaderBlur"));
+}
+},_findHeaderCells:function(){
+var _a=dojo.query("th",this.grid.viewsHeaderNode);
+var _b=[];
+for(var i=0;i<_a.length;i++){
+var _d=_a[i];
+var _e=dojo.hasAttr(_d,"tabindex");
+var _f=dojo.attr(_d,"tabindex");
+if(_e&&_f<0){
+_b.push(_d);
+}
+}
+return _b;
+},scrollIntoView:function(){
+var _10=(this.cell?this._scrollInfo(this.cell):null);
+if(!_10||!_10.s){
+return null;
+}
+var rt=this.grid.scroller.findScrollTop(this.rowIndex);
+if(_10.n&&_10.sr){
+if(_10.n.offsetLeft+_10.n.offsetWidth>_10.sr.l+_10.sr.w){
+_10.s.scrollLeft=_10.n.offsetLeft+_10.n.offsetWidth-_10.sr.w;
+}else{
+if(_10.n.offsetLeft<_10.sr.l){
+_10.s.scrollLeft=_10.n.offsetLeft;
+}
+}
+}
+if(_10.r&&_10.sr){
+if(rt+_10.r.offsetHeight>_10.sr.t+_10.sr.h){
+this.grid.setScrollTop(rt+_10.r.offsetHeight-_10.sr.h);
+}else{
+if(rt<_10.sr.t){
+this.grid.setScrollTop(rt);
+}
+}
+}
+return _10.s.scrollLeft;
+},_scrollInfo:function(_12,_13){
+if(_12){
+var cl=_12,sbn=cl.view.scrollboxNode,_16={w:sbn.clientWidth,l:sbn.scrollLeft,t:sbn.scrollTop,h:sbn.clientHeight},rn=cl.view.getRowNode(this.rowIndex);
+return {c:cl,s:sbn,sr:_16,n:(_13?_13:_12.getNode(this.rowIndex)),r:rn};
+}
+return null;
+},_scrollHeader:function(_18){
+var _19=null;
+if(this._colHeadNode){
+var _1a=this.grid.getCell(_18);
+_19=this._scrollInfo(_1a,_1a.getNode(0));
+}
+if(_19&&_19.s&&_19.sr&&_19.n){
+var _1b=_19.sr.l+_19.sr.w;
+if(_19.n.offsetLeft+_19.n.offsetWidth>_1b){
+_19.s.scrollLeft=_19.n.offsetLeft+_19.n.offsetWidth-_19.sr.w;
+}else{
+if(_19.n.offsetLeft<_19.sr.l){
+_19.s.scrollLeft=_19.n.offsetLeft;
+}else{
+if(dojo.isIE<=7&&_1a&&_1a.view.headerNode){
+_1a.view.headerNode.scrollLeft=_19.s.scrollLeft;
+}
+}
+}
+}
+},styleRow:function(_1c){
+return;
+},setFocusIndex:function(_1d,_1e){
+this.setFocusCell(this.grid.getCell(_1e),_1d);
+},setFocusCell:function(_1f,_20){
+if(_1f&&!this.isFocusCell(_1f,_20)){
+this.tabbingOut=false;
+this._colHeadNode=this._colHeadFocusIdx=null;
+this.focusGridView();
+this._focusifyCellNode(false);
+this.cell=_1f;
+this.rowIndex=_20;
+this._focusifyCellNode(true);
+}
+if(dojo.isOpera){
+setTimeout(dojo.hitch(this.grid,"onCellFocus",this.cell,this.rowIndex),1);
+}else{
+this.grid.onCellFocus(this.cell,this.rowIndex);
+}
+},next:function(){
+if(this.cell){
+var row=this.rowIndex,col=this.cell.index+1,cc=this.grid.layout.cellCount-1,rc=this.grid.rowCount-1;
+if(col>cc){
+col=0;
+row++;
+}
+if(row>rc){
+col=cc;
+row=rc;
+}
+if(this.grid.edit.isEditing()){
+var _25=this.grid.getCell(col);
+if(!this.isLastFocusCell()&&!_25.editable){
+this.cell=_25;
+this.rowIndex=row;
+this.next();
+return;
+}
+}
+this.setFocusIndex(row,col);
+}
+},previous:function(){
+if(this.cell){
+var row=(this.rowIndex||0),col=(this.cell.index||0)-1;
+if(col<0){
+col=this.grid.layout.cellCount-1;
+row--;
+}
+if(row<0){
+row=0;
+col=0;
+}
+if(this.grid.edit.isEditing()){
+var _28=this.grid.getCell(col);
+if(!this.isFirstFocusCell()&&!_28.editable){
+this.cell=_28;
+this.rowIndex=row;
+this.previous();
+return;
+}
+}
+this.setFocusIndex(row,col);
+}
+},move:function(_29,_2a){
+if(this.isNavHeader()){
+var _2b=this._findHeaderCells();
+var _2c=dojo.indexOf(_2b,this._colHeadNode);
+_2c+=_2a;
+if((_2c>=0)&&(_2c<_2b.length)){
+this._colHeadNode=_2b[_2c];
+this._colHeadFocusIdx=_2c;
+this._scrollHeader(_2c);
+this._colHeadNode.focus();
+}
+}else{
+if(this.cell){
+var sc=this.grid.scroller,r=this.rowIndex,rc=this.grid.rowCount-1,row=Math.min(rc,Math.max(0,r+_29));
+if(_29){
+if(_29>0){
+if(row>sc.getLastPageRow(sc.page)){
+this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r));
+}
+}else{
+if(_29<0){
+if(row<=sc.getPageRow(sc.page)){
+this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row));
+}
+}
+}
+}
+var cc=this.grid.layout.cellCount-1,i=this.cell.index,col=Math.min(cc,Math.max(0,i+_2a));
+this.setFocusIndex(row,col);
+if(_29){
+this.grid.updateRow(r);
+}
+}
+}
+},previousKey:function(e){
+if(this.grid.edit.isEditing()){
+dojo.stopEvent(e);
+this.previous();
+}else{
+if(!this.isNavHeader()){
+this.focusHeader();
+dojo.stopEvent(e);
+}else{
+this.tabOut(this.grid.domNode);
+}
+}
+},nextKey:function(e){
+var _36=this.grid.rowCount==0;
+if(e.target===this.grid.domNode){
+this.focusHeader();
+dojo.stopEvent(e);
+}else{
+if(this.isNavHeader()){
+this._colHeadNode=this._colHeadFocusIdx=null;
+if(this.isNoFocusCell()&&!_36){
+this.setFocusIndex(0,0);
+}else{
+if(this.cell&&!_36){
+if(this.focusView&&!this.focusView.rowNodes[this.rowIndex]){
+this.grid.scrollToRow(this.rowIndex);
+}
+this.focusGrid();
+}else{
+this.tabOut(this.grid.lastFocusNode);
+}
+}
+}else{
+if(this.grid.edit.isEditing()){
+dojo.stopEvent(e);
+this.next();
+}else{
+this.tabOut(this.grid.lastFocusNode);
+}
+}
+}
+},tabOut:function(_37){
+this.tabbingOut=true;
+_37.focus();
+},focusGridView:function(){
+dojox.grid.util.fire(this.focusView,"focus");
+},focusGrid:function(_38){
+this.focusGridView();
+this._focusifyCellNode(true);
+},focusHeader:function(){
+var _39=this._findHeaderCells();
+if(!this._colHeadFocusIdx){
+if(this.isNoFocusCell()){
+this._colHeadFocusIdx=0;
+}else{
+this._colHeadFocusIdx=this.cell.index;
+}
+}
+this._colHeadNode=_39[this._colHeadFocusIdx];
+if(this._colHeadNode){
+dojox.grid.util.fire(this._colHeadNode,"focus");
+this._focusifyCellNode(false);
+}
+},doFocus:function(e){
+if(e&&e.target!=e.currentTarget){
+dojo.stopEvent(e);
+return;
+}
+if(!this.tabbingOut){
+this.focusHeader();
+}
+this.tabbingOut=false;
+dojo.stopEvent(e);
+},doBlur:function(e){
+dojo.stopEvent(e);
+},doBlurHeader:function(e){
+dojo.stopEvent(e);
+},doLastNodeFocus:function(e){
+if(this.tabbingOut){
+this._focusifyCellNode(false);
+}else{
+if(this.grid.rowCount>0){
+if(this.isNoFocusCell()){
+this.setFocusIndex(0,0);
+}
+this._focusifyCellNode(true);
+}else{
+this.focusHeader();
+}
+}
+this.tabbingOut=false;
+dojo.stopEvent(e);
+},doLastNodeBlur:function(e){
+dojo.stopEvent(e);
+},doColHeaderFocus:function(e){
+dojo.toggleClass(e.target,this.focusClass,true);
+this._scrollHeader(this.getHeaderIndex());
+},doColHeaderBlur:function(e){
+dojo.toggleClass(e.target,this.focusClass,false);
+}});
+}
diff --git a/dojox/grid/_Grid.js b/dojox/grid/_Grid.js
new file mode 100644
index 0000000..8cbde88
--- /dev/null
+++ b/dojox/grid/_Grid.js
@@ -0,0 +1,706 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid._Grid"]){
+dojo._hasResource["dojox.grid._Grid"]=true;
+dojo.provide("dojox.grid._Grid");
+dojo.require("dijit.dijit");
+dojo.require("dijit.Menu");
+dojo.require("dojox.html.metrics");
+dojo.require("dojox.grid.util");
+dojo.require("dojox.grid._Scroller");
+dojo.require("dojox.grid._Layout");
+dojo.require("dojox.grid._View");
+dojo.require("dojox.grid._ViewManager");
+dojo.require("dojox.grid._RowManager");
+dojo.require("dojox.grid._FocusManager");
+dojo.require("dojox.grid._EditManager");
+dojo.require("dojox.grid.Selection");
+dojo.require("dojox.grid._RowSelector");
+dojo.require("dojox.grid._Events");
+dojo.requireLocalization("dijit","loading",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+(function(){
+var _1={cancel:function(_2){
+if(_2){
+clearTimeout(_2);
+}
+},jobs:[],job:function(_3,_4,_5){
+_1.cancelJob(_3);
+var _6=function(){
+delete _1.jobs[_3];
+_5();
+};
+_1.jobs[_3]=setTimeout(_6,_4);
+},cancelJob:function(_7){
+_1.cancel(_1.jobs[_7]);
+}};
+dojo.declare("dojox.grid._Grid",[dijit._Widget,dijit._Templated,dojox.grid._Events],{templateString:"<div class=\"dojoxGrid\" hidefocus=\"hidefocus\" wairole=\"grid\" dojoAttachEvent=\"onmouseout:_mouseOut\">\n\t<div class=\"dojoxGridMasterHeader\" dojoAttachPoint=\"viewsHeaderNode\" tabindex=\"-1\" wairole=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterView\" dojoAttachPoint=\"viewsNode\" wairole=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterMessages\" style=\"display:  [...]
+},rowCount:5,keepRows:75,rowsPerPage:25,autoWidth:false,autoHeight:"",autoRender:true,defaultHeight:"15em",height:"",structure:null,elasticView:-1,singleClickEdit:false,selectionMode:"extended",rowSelector:"",columnReordering:false,headerMenu:null,placeholderLabel:"GridColumns",selectable:false,_click:null,loadingMessage:"<span class='dojoxGridLoading'>${loadingState}</span>",errorMessage:"<span class='dojoxGridError'>${errorState}</span>",noDataMessage:"",sortInfo:0,themeable:true,_plac [...]
+this.inherited(arguments);
+if(this.get==dojox.grid._Grid.prototype.get){
+this.get=null;
+}
+if(!this.domNode.getAttribute("tabIndex")){
+this.domNode.tabIndex="0";
+}
+this.createScroller();
+this.createLayout();
+this.createViews();
+this.createManagers();
+this.createSelection();
+this.connect(this.selection,"onSelected","onSelected");
+this.connect(this.selection,"onDeselected","onDeselected");
+this.connect(this.selection,"onChanged","onSelectionChanged");
+dojox.html.metrics.initOnFontResize();
+this.connect(dojox.html.metrics,"onFontResize","textSizeChanged");
+dojox.grid.util.funnelEvents(this.domNode,this,"doKeyEvent",dojox.grid.util.keyEvents);
+this.connect(this,"onShow","renderOnIdle");
+},postMixInProperties:function(){
+this.inherited(arguments);
+var _9=dojo.i18n.getLocalization("dijit","loading",this.lang);
+this.loadingMessage=dojo.string.substitute(this.loadingMessage,_9);
+this.errorMessage=dojo.string.substitute(this.errorMessage,_9);
+if(this.srcNodeRef&&this.srcNodeRef.style.height){
+this.height=this.srcNodeRef.style.height;
+}
+this._setAutoHeightAttr(this.autoHeight,true);
+},postCreate:function(){
+this.styleChanged=this._styleChanged;
+this._placeholders=[];
+this._setHeaderMenuAttr(this.headerMenu);
+this._setStructureAttr(this.structure);
+this._click=[];
+},destroy:function(){
+this.domNode.onReveal=null;
+this.domNode.onSizeChange=null;
+delete this._click;
+this.edit.destroy();
+delete this.edit;
+this.views.destroyViews();
+if(this.scroller){
+this.scroller.destroy();
+delete this.scroller;
+}
+if(this.focus){
+this.focus.destroy();
+delete this.focus;
+}
+if(this.headerMenu&&this._placeholders.length){
+dojo.forEach(this._placeholders,function(p){
+p.unReplace(true);
+});
+this.headerMenu.unBindDomNode(this.viewsHeaderNode);
+}
+this.inherited(arguments);
+},_setAutoHeightAttr:function(ah,_c){
+if(typeof ah=="string"){
+if(!ah||ah=="false"){
+ah=false;
+}else{
+if(ah=="true"){
+ah=true;
+}else{
+ah=window.parseInt(ah,10);
+}
+}
+}
+if(typeof ah=="number"){
+if(isNaN(ah)){
+ah=false;
+}
+if(ah<0){
+ah=true;
+}else{
+if(ah===0){
+ah=false;
+}
+}
+}
+this.autoHeight=ah;
+if(typeof ah=="boolean"){
+this._autoHeight=ah;
+}else{
+if(typeof ah=="number"){
+this._autoHeight=(ah>=this.attr("rowCount"));
+}else{
+this._autoHeight=false;
+}
+}
+if(this._started&&!_c){
+this.render();
+}
+},_getRowCountAttr:function(){
+return this.updating&&this.invalidated&&this.invalidated.rowCount!=undefined?this.invalidated.rowCount:this.rowCount;
+},styleChanged:function(){
+this.setStyledClass(this.domNode,"");
+},_styleChanged:function(){
+this.styleChanged();
+this.update();
+},textSizeChanged:function(){
+setTimeout(dojo.hitch(this,"_textSizeChanged"),1);
+},_textSizeChanged:function(){
+if(this.domNode){
+this.views.forEach(function(v){
+v.content.update();
+});
+this.render();
+}
+},sizeChange:function(){
+_1.job(this.id+"SizeChange",50,dojo.hitch(this,"update"));
+},renderOnIdle:function(){
+setTimeout(dojo.hitch(this,"render"),1);
+},createManagers:function(){
+this.rows=new dojox.grid._RowManager(this);
+this.focus=new dojox.grid._FocusManager(this);
+this.edit=new dojox.grid._EditManager(this);
+},createSelection:function(){
+this.selection=new dojox.grid.Selection(this);
+},createScroller:function(){
+this.scroller=new dojox.grid._Scroller();
+this.scroller.grid=this;
+this.scroller._pageIdPrefix=this.id+"-";
+this.scroller.renderRow=dojo.hitch(this,"renderRow");
+this.scroller.removeRow=dojo.hitch(this,"rowRemoved");
+},createLayout:function(){
+this.layout=new dojox.grid._Layout(this);
+this.connect(this.layout,"moveColumn","onMoveColumn");
+},onMoveColumn:function(){
+this.render();
+this._resize();
+},createViews:function(){
+this.views=new dojox.grid._ViewManager(this);
+this.views.createView=dojo.hitch(this,"createView");
+},createView:function(_e,_f){
+var c=dojo.getObject(_e);
+var _11=new c({grid:this,index:_f});
+this.viewsNode.appendChild(_11.domNode);
+this.viewsHeaderNode.appendChild(_11.headerNode);
+this.views.addView(_11);
+return _11;
+},buildViews:function(){
+for(var i=0,vs;(vs=this.layout.structure[i]);i++){
+this.createView(vs.type||dojox._scopeName+".grid._View",i).setStructure(vs);
+}
+this.scroller.setContentNodes(this.views.getContentNodes());
+},_setStructureAttr:function(_14){
+var s=_14;
+if(s&&dojo.isString(s)){
+dojo.deprecated("dojox.grid._Grid.attr('structure', 'objVar')","use dojox.grid._Grid.attr('structure', objVar) instead","2.0");
+s=dojo.getObject(s);
+}
+this.structure=s;
+if(!s){
+if(this.layout.structure){
+s=this.layout.structure;
+}else{
+return;
+}
+}
+this.views.destroyViews();
+if(s!==this.layout.structure){
+this.layout.setStructure(s);
+}
+this._structureChanged();
+},setStructure:function(_16){
+dojo.deprecated("dojox.grid._Grid.setStructure(obj)","use dojox.grid._Grid.attr('structure', obj) instead.","2.0");
+this._setStructureAttr(_16);
+},getColumnTogglingItems:function(){
+return dojo.map(this.layout.cells,function(_17){
+if(!_17.menuItems){
+_17.menuItems=[];
+}
+var _18=this;
+var _19=new dijit.CheckedMenuItem({label:_17.name,checked:!_17.hidden,_gridCell:_17,onChange:function(_1a){
+if(_18.layout.setColumnVisibility(this._gridCell.index,_1a)){
+var _1b=this._gridCell.menuItems;
+if(_1b.length>1){
+dojo.forEach(_1b,function(_1c){
+if(_1c!==this){
+_1c.setAttribute("checked",_1a);
+}
+},this);
+}
+var _1a=dojo.filter(_18.layout.cells,function(c){
+if(c.menuItems.length>1){
+dojo.forEach(c.menuItems,"item.attr('disabled', false);");
+}else{
+c.menuItems[0].attr("disabled",false);
+}
+return !c.hidden;
+});
+if(_1a.length==1){
+dojo.forEach(_1a[0].menuItems,"item.attr('disabled', true);");
+}
+}
+},destroy:function(){
+var _1e=dojo.indexOf(this._gridCell.menuItems,this);
+this._gridCell.menuItems.splice(_1e,1);
+delete this._gridCell;
+dijit.CheckedMenuItem.prototype.destroy.apply(this,arguments);
+}});
+_17.menuItems.push(_19);
+return _19;
+},this);
+},_setHeaderMenuAttr:function(_1f){
+if(this._placeholders&&this._placeholders.length){
+dojo.forEach(this._placeholders,function(p){
+p.unReplace(true);
+});
+this._placeholders=[];
+}
+if(this.headerMenu){
+this.headerMenu.unBindDomNode(this.viewsHeaderNode);
+}
+this.headerMenu=_1f;
+if(!_1f){
+return;
+}
+this.headerMenu.bindDomNode(this.viewsHeaderNode);
+if(this.headerMenu.getPlaceholders){
+this._placeholders=this.headerMenu.getPlaceholders(this.placeholderLabel);
+}
+},setHeaderMenu:function(_21){
+dojo.deprecated("dojox.grid._Grid.setHeaderMenu(obj)","use dojox.grid._Grid.attr('headerMenu', obj) instead.","2.0");
+this._setHeaderMenuAttr(_21);
+},setupHeaderMenu:function(){
+if(this._placeholders&&this._placeholders.length){
+dojo.forEach(this._placeholders,function(p){
+if(p._replaced){
+p.unReplace(true);
+}
+p.replace(this.getColumnTogglingItems());
+},this);
+}
+},_fetch:function(_23){
+this.setScrollTop(0);
+},getItem:function(_24){
+return null;
+},showMessage:function(_25){
+if(_25){
+this.messagesNode.innerHTML=_25;
+this.messagesNode.style.display="";
+}else{
+this.messagesNode.innerHTML="";
+this.messagesNode.style.display="none";
+}
+},_structureChanged:function(){
+this.buildViews();
+if(this.autoRender&&this._started){
+this.render();
+}
+},hasLayout:function(){
+return this.layout.cells.length;
+},resize:function(_26,_27){
+this._resize(_26,_27);
+this.sizeChange();
+},_getPadBorder:function(){
+this._padBorder=this._padBorder||dojo._getPadBorderExtents(this.domNode);
+return this._padBorder;
+},_getHeaderHeight:function(){
+var vns=this.viewsHeaderNode.style,t=vns.display=="none"?0:this.views.measureHeader();
+vns.height=t+"px";
+this.views.normalizeHeaderNodeHeight();
+return t;
+},_resize:function(_2a,_2b){
+var pn=this.domNode.parentNode;
+if(!pn||pn.nodeType!=1||!this.hasLayout()||pn.style.visibility=="hidden"||pn.style.display=="none"){
+return;
+}
+var _2d=this._getPadBorder();
+var hh=0;
+if(this._autoHeight){
+this.domNode.style.height="auto";
+this.viewsNode.style.height="";
+}else{
+if(typeof this.autoHeight=="number"){
+var h=hh=this._getHeaderHeight();
+h+=(this.scroller.averageRowHeight*this.autoHeight);
+this.domNode.style.height=h+"px";
+}else{
+if(this.flex>0){
+}else{
+if(this.domNode.clientHeight<=_2d.h){
+if(pn==document.body){
+this.domNode.style.height=this.defaultHeight;
+}else{
+if(this.height){
+this.domNode.style.height=this.height;
+}else{
+this.fitTo="parent";
+}
+}
+}
+}
+}
+}
+if(_2b){
+_2a=_2b;
+}
+if(_2a){
+dojo.marginBox(this.domNode,_2a);
+this.height=this.domNode.style.height;
+delete this.fitTo;
+}else{
+if(this.fitTo=="parent"){
+var h=dojo._getContentBox(pn).h;
+dojo.marginBox(this.domNode,{h:Math.max(0,h)});
+}
+}
+var h=dojo._getContentBox(this.domNode).h;
+if(h==0&&!this._autoHeight){
+this.viewsHeaderNode.style.display="none";
+}else{
+this.viewsHeaderNode.style.display="block";
+hh=this._getHeaderHeight();
+}
+this.adaptWidth();
+this.adaptHeight(hh);
+this.postresize();
+},adaptWidth:function(){
+var w=this.autoWidth?0:this.domNode.clientWidth||(this.domNode.offsetWidth-this._getPadBorder().w),vw=this.views.arrange(1,w);
+this.views.onEach("adaptWidth");
+if(this.autoWidth){
+this.domNode.style.width=vw+"px";
+}
+},adaptHeight:function(_32){
+var t=_32||this._getHeaderHeight();
+var h=(this._autoHeight?-1:Math.max(this.domNode.clientHeight-t,0)||0);
+this.views.onEach("setSize",[0,h]);
+this.views.onEach("adaptHeight");
+if(!this._autoHeight){
+var _35=0,_36=0;
+var _37=dojo.filter(this.views.views,function(v){
+var has=v.hasHScrollbar();
+if(has){
+_35++;
+}else{
+_36++;
+}
+return (!has);
+});
+if(_35>0&&_36>0){
+dojo.forEach(_37,function(v){
+v.adaptHeight(true);
+});
+}
+}
+if(this.autoHeight===true||h!=-1||(typeof this.autoHeight=="number"&&this.autoHeight>=this.attr("rowCount"))){
+this.scroller.windowHeight=h;
+}else{
+this.scroller.windowHeight=Math.max(this.domNode.clientHeight-t,0);
+}
+},startup:function(){
+if(this._started){
+return;
+}
+this.inherited(arguments);
+if(this.autoRender){
+this.render();
+}
+},render:function(){
+if(!this.domNode){
+return;
+}
+if(!this._started){
+return;
+}
+if(!this.hasLayout()){
+this.scroller.init(0,this.keepRows,this.rowsPerPage);
+return;
+}
+this.update=this.defaultUpdate;
+this._render();
+},_render:function(){
+this.scroller.init(this.attr("rowCount"),this.keepRows,this.rowsPerPage);
+this.prerender();
+this.setScrollTop(0);
+this.postrender();
+},prerender:function(){
+this.keepRows=this._autoHeight?0:this.keepRows;
+this.scroller.setKeepInfo(this.keepRows);
+this.views.render();
+this._resize();
+},postrender:function(){
+this.postresize();
+this.focus.initFocusView();
+dojo.setSelectable(this.domNode,this.selectable);
+},postresize:function(){
+if(this._autoHeight){
+var _3b=Math.max(this.views.measureContent())+"px";
+this.viewsNode.style.height=_3b;
+}
+},renderRow:function(_3c,_3d){
+this.views.renderRow(_3c,_3d);
+},rowRemoved:function(_3e){
+this.views.rowRemoved(_3e);
+},invalidated:null,updating:false,beginUpdate:function(){
+this.invalidated=[];
+this.updating=true;
+},endUpdate:function(){
+this.updating=false;
+var i=this.invalidated,r;
+if(i.all){
+this.update();
+}else{
+if(i.rowCount!=undefined){
+this.updateRowCount(i.rowCount);
+}else{
+for(r in i){
+this.updateRow(Number(r));
+}
+}
+}
+this.invalidated=null;
+},defaultUpdate:function(){
+if(!this.domNode){
+return;
+}
+if(this.updating){
+this.invalidated.all=true;
+return;
+}
+var _41=this.scrollTop;
+this.prerender();
+this.scroller.invalidateNodes();
+this.setScrollTop(_41);
+this.postrender();
+},update:function(){
+this.render();
+},updateRow:function(_42){
+_42=Number(_42);
+if(this.updating){
+this.invalidated[_42]=true;
+}else{
+this.views.updateRow(_42);
+this.scroller.rowHeightChanged(_42);
+}
+},updateRows:function(_43,_44){
+_43=Number(_43);
+_44=Number(_44);
+if(this.updating){
+for(var i=0;i<_44;i++){
+this.invalidated[i+_43]=true;
+}
+}else{
+for(var i=0;i<_44;i++){
+this.views.updateRow(i+_43);
+}
+this.scroller.rowHeightChanged(_43);
+}
+},updateRowCount:function(_46){
+if(this.updating){
+this.invalidated.rowCount=_46;
+}else{
+this.rowCount=_46;
+this._setAutoHeightAttr(this.autoHeight,true);
+if(this.layout.cells.length){
+this.scroller.updateRowCount(_46);
+}
+this._resize();
+if(this.layout.cells.length){
+this.setScrollTop(this.scrollTop);
+}
+}
+},updateRowStyles:function(_47){
+this.views.updateRowStyles(_47);
+},rowHeightChanged:function(_48){
+this.views.renormalizeRow(_48);
+this.scroller.rowHeightChanged(_48);
+},fastScroll:true,delayScroll:false,scrollRedrawThreshold:(dojo.isIE?100:50),scrollTo:function(_49){
+if(!this.fastScroll){
+this.setScrollTop(_49);
+return;
+}
+var _4a=Math.abs(this.lastScrollTop-_49);
+this.lastScrollTop=_49;
+if(_4a>this.scrollRedrawThreshold||this.delayScroll){
+this.delayScroll=true;
+this.scrollTop=_49;
+this.views.setScrollTop(_49);
+_1.job("dojoxGridScroll",200,dojo.hitch(this,"finishScrollJob"));
+}else{
+this.setScrollTop(_49);
+}
+},finishScrollJob:function(){
+this.delayScroll=false;
+this.setScrollTop(this.scrollTop);
+},setScrollTop:function(_4b){
+this.scroller.scroll(this.views.setScrollTop(_4b));
+},scrollToRow:function(_4c){
+this.setScrollTop(this.scroller.findScrollTop(_4c)+1);
+},styleRowNode:function(_4d,_4e){
+if(_4e){
+this.rows.styleRowNode(_4d,_4e);
+}
+},_mouseOut:function(e){
+this.rows.setOverRow(-2);
+},getCell:function(_50){
+return this.layout.cells[_50];
+},setCellWidth:function(_51,_52){
+this.getCell(_51).unitWidth=_52;
+},getCellName:function(_53){
+return "Cell "+_53.index;
+},canSort:function(_54){
+},sort:function(){
+},getSortAsc:function(_55){
+_55=_55==undefined?this.sortInfo:_55;
+return Boolean(_55>0);
+},getSortIndex:function(_56){
+_56=_56==undefined?this.sortInfo:_56;
+return Math.abs(_56)-1;
+},setSortIndex:function(_57,_58){
+var si=_57+1;
+if(_58!=undefined){
+si*=(_58?1:-1);
+}else{
+if(this.getSortIndex()==_57){
+si=-this.sortInfo;
+}
+}
+this.setSortInfo(si);
+},setSortInfo:function(_5a){
+if(this.canSort(_5a)){
+this.sortInfo=_5a;
+this.sort();
+this.update();
+}
+},doKeyEvent:function(e){
+e.dispatch="do"+e.type;
+this.onKeyEvent(e);
+},_dispatch:function(m,e){
+if(m in this){
+return this[m](e);
+}
+},dispatchKeyEvent:function(e){
+this._dispatch(e.dispatch,e);
+},dispatchContentEvent:function(e){
+this.edit.dispatchEvent(e)||e.sourceView.dispatchContentEvent(e)||this._dispatch(e.dispatch,e);
+},dispatchHeaderEvent:function(e){
+e.sourceView.dispatchHeaderEvent(e)||this._dispatch("doheader"+e.type,e);
+},dokeydown:function(e){
+this.onKeyDown(e);
+},doclick:function(e){
+if(e.cellNode){
+this.onCellClick(e);
+}else{
+this.onRowClick(e);
+}
+},dodblclick:function(e){
+if(e.cellNode){
+this.onCellDblClick(e);
+}else{
+this.onRowDblClick(e);
+}
+},docontextmenu:function(e){
+if(e.cellNode){
+this.onCellContextMenu(e);
+}else{
+this.onRowContextMenu(e);
+}
+},doheaderclick:function(e){
+if(e.cellNode){
+this.onHeaderCellClick(e);
+}else{
+this.onHeaderClick(e);
+}
+},doheaderdblclick:function(e){
+if(e.cellNode){
+this.onHeaderCellDblClick(e);
+}else{
+this.onHeaderDblClick(e);
+}
+},doheadercontextmenu:function(e){
+if(e.cellNode){
+this.onHeaderCellContextMenu(e);
+}else{
+this.onHeaderContextMenu(e);
+}
+},doStartEdit:function(_68,_69){
+this.onStartEdit(_68,_69);
+},doApplyCellEdit:function(_6a,_6b,_6c){
+this.onApplyCellEdit(_6a,_6b,_6c);
+},doCancelEdit:function(_6d){
+this.onCancelEdit(_6d);
+},doApplyEdit:function(_6e){
+this.onApplyEdit(_6e);
+},addRow:function(){
+this.updateRowCount(this.attr("rowCount")+1);
+},removeSelectedRows:function(){
+this.updateRowCount(Math.max(0,this.attr("rowCount")-this.selection.getSelected().length));
+this.selection.clear();
+}});
+dojox.grid._Grid.markupFactory=function(_6f,_70,_71,_72){
+var d=dojo;
+var _74=function(n){
+var w=d.attr(n,"width")||"auto";
+if((w!="auto")&&(w.slice(-2)!="em")&&(w.slice(-1)!="%")){
+w=parseInt(w)+"px";
+}
+return w;
+};
+if(!_6f.structure&&_70.nodeName.toLowerCase()=="table"){
+_6f.structure=d.query("> colgroup",_70).map(function(cg){
+var sv=d.attr(cg,"span");
+var v={noscroll:(d.attr(cg,"noscroll")=="true")?true:false,__span:(!!sv?parseInt(sv):1),cells:[]};
+if(d.hasAttr(cg,"width")){
+v.width=_74(cg);
+}
+return v;
+});
+if(!_6f.structure.length){
+_6f.structure.push({__span:Infinity,cells:[]});
+}
+d.query("thead > tr",_70).forEach(function(tr,_7b){
+var _7c=0;
+var _7d=0;
+var _7e;
+var _7f=null;
+d.query("> th",tr).map(function(th){
+if(!_7f){
+_7e=0;
+_7f=_6f.structure[0];
+}else{
+if(_7c>=(_7e+_7f.__span)){
+_7d++;
+_7e+=_7f.__span;
+var _81=_7f;
+_7f=_6f.structure[_7d];
+}
+}
+var _82={name:d.trim(d.attr(th,"name")||th.innerHTML),colSpan:parseInt(d.attr(th,"colspan")||1,10),type:d.trim(d.attr(th,"cellType")||"")};
+_7c+=_82.colSpan;
+var _83=d.attr(th,"rowspan");
+if(_83){
+_82.rowSpan=_83;
+}
+if(d.hasAttr(th,"width")){
+_82.width=_74(th);
+}
+if(d.hasAttr(th,"relWidth")){
+_82.relWidth=window.parseInt(dojo.attr(th,"relWidth"),10);
+}
+if(d.hasAttr(th,"hidden")){
+_82.hidden=d.attr(th,"hidden")=="true";
+}
+if(_72){
+_72(th,_82);
+}
+_82.type=_82.type?dojo.getObject(_82.type):dojox.grid.cells.Cell;
+if(_82.type&&_82.type.markupFactory){
+_82.type.markupFactory(th,_82);
+}
+if(!_7f.cells[_7b]){
+_7f.cells[_7b]=[];
+}
+_7f.cells[_7b].push(_82);
+});
+});
+}
+return new _71(_6f,_70);
+};
+})();
+}
diff --git a/dojox/grid/_Layout.js b/dojox/grid/_Layout.js
new file mode 100644
index 0000000..2cb31db
--- /dev/null
+++ b/dojox/grid/_Layout.js
@@ -0,0 +1,213 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid._Layout"]){
+dojo._hasResource["dojox.grid._Layout"]=true;
+dojo.provide("dojox.grid._Layout");
+dojo.require("dojox.grid.cells");
+dojo.require("dojox.grid._RowSelector");
+dojo.declare("dojox.grid._Layout",null,{constructor:function(_1){
+this.grid=_1;
+},cells:[],structure:null,defaultWidth:"6em",moveColumn:function(_2,_3,_4,_5,_6){
+var _7=this.structure[_2].cells[0];
+var _8=this.structure[_3].cells[0];
+var _9=null;
+var _a=0;
+var _b=0;
+for(var i=0,c;c=_7[i];i++){
+if(c.index==_4){
+_a=i;
+break;
+}
+}
+_9=_7.splice(_a,1)[0];
+_9.view=this.grid.views.views[_3];
+for(i=0,c=null;c=_8[i];i++){
+if(c.index==_5){
+_b=i;
+break;
+}
+}
+if(!_6){
+_b+=1;
+}
+_8.splice(_b,0,_9);
+var _e=this.grid.getCell(this.grid.getSortIndex());
+if(_e){
+_e._currentlySorted=this.grid.getSortAsc();
+}
+this.cells=[];
+var _4=0;
+for(var i=0,v;v=this.structure[i];i++){
+for(var j=0,cs;cs=v.cells[j];j++){
+for(var k=0,c;c=cs[k];k++){
+c.index=_4;
+this.cells.push(c);
+if("_currentlySorted" in c){
+var si=_4+1;
+si*=c._currentlySorted?1:-1;
+this.grid.sortInfo=si;
+delete c._currentlySorted;
+}
+_4++;
+}
+}
+}
+this.grid.setupHeaderMenu();
+},setColumnVisibility:function(_14,_15){
+var _16=this.cells[_14];
+if(_16.hidden==_15){
+_16.hidden=!_15;
+var v=_16.view,w=v.viewWidth;
+if(w&&w!="auto"){
+v._togglingColumn=dojo.marginBox(_16.getHeaderNode()).w||0;
+}
+v.update();
+return true;
+}else{
+return false;
+}
+},addCellDef:function(_19,_1a,_1b){
+var _1c=this;
+var _1d=function(_1e){
+var w=0;
+if(_1e.colSpan>1){
+w=0;
+}else{
+w=_1e.width||_1c._defaultCellProps.width||_1c.defaultWidth;
+if(!isNaN(w)){
+w=w+"em";
+}
+}
+return w;
+};
+var _20={grid:this.grid,subrow:_19,layoutIndex:_1a,index:this.cells.length};
+if(_1b&&_1b instanceof dojox.grid.cells._Base){
+var _21=dojo.clone(_1b);
+_20.unitWidth=_1d(_21._props);
+_21=dojo.mixin(_21,this._defaultCellProps,_1b._props,_20);
+return _21;
+}
+var _22=_1b.type||this._defaultCellProps.type||dojox.grid.cells.Cell;
+_20.unitWidth=_1d(_1b);
+return new _22(dojo.mixin({},this._defaultCellProps,_1b,_20));
+},addRowDef:function(_23,_24){
+var _25=[];
+var _26=0,_27=0,_28=true;
+for(var i=0,def,_2b;(def=_24[i]);i++){
+_2b=this.addCellDef(_23,i,def);
+_25.push(_2b);
+this.cells.push(_2b);
+if(_28&&_2b.relWidth){
+_26+=_2b.relWidth;
+}else{
+if(_2b.width){
+var w=_2b.width;
+if(typeof w=="string"&&w.slice(-1)=="%"){
+_27+=window.parseInt(w,10);
+}else{
+if(w=="auto"){
+_28=false;
+}
+}
+}
+}
+}
+if(_26&&_28){
+dojo.forEach(_25,function(_2d){
+if(_2d.relWidth){
+_2d.width=_2d.unitWidth=((_2d.relWidth/_26)*(100-_27))+"%";
+}
+});
+}
+return _25;
+},addRowsDef:function(_2e){
+var _2f=[];
+if(dojo.isArray(_2e)){
+if(dojo.isArray(_2e[0])){
+for(var i=0,row;_2e&&(row=_2e[i]);i++){
+_2f.push(this.addRowDef(i,row));
+}
+}else{
+_2f.push(this.addRowDef(0,_2e));
+}
+}
+return _2f;
+},addViewDef:function(_32){
+this._defaultCellProps=_32.defaultCell||{};
+if(_32.width&&_32.width=="auto"){
+delete _32.width;
+}
+return dojo.mixin({},_32,{cells:this.addRowsDef(_32.rows||_32.cells)});
+},setStructure:function(_33){
+this.fieldIndex=0;
+this.cells=[];
+var s=this.structure=[];
+if(this.grid.rowSelector){
+var sel={type:dojox._scopeName+".grid._RowSelector"};
+if(dojo.isString(this.grid.rowSelector)){
+var _36=this.grid.rowSelector;
+if(_36=="false"){
+sel=null;
+}else{
+if(_36!="true"){
+sel["width"]=_36;
+}
+}
+}else{
+if(!this.grid.rowSelector){
+sel=null;
+}
+}
+if(sel){
+s.push(this.addViewDef(sel));
+}
+}
+var _37=function(def){
+return ("name" in def||"field" in def||"get" in def);
+};
+var _39=function(def){
+if(dojo.isArray(def)){
+if(dojo.isArray(def[0])||_37(def[0])){
+return true;
+}
+}
+return false;
+};
+var _3b=function(def){
+return (def!=null&&dojo.isObject(def)&&("cells" in def||"rows" in def||("type" in def&&!_37(def))));
+};
+if(dojo.isArray(_33)){
+var _3d=false;
+for(var i=0,st;(st=_33[i]);i++){
+if(_3b(st)){
+_3d=true;
+break;
+}
+}
+if(!_3d){
+s.push(this.addViewDef({cells:_33}));
+}else{
+for(var i=0,st;(st=_33[i]);i++){
+if(_39(st)){
+s.push(this.addViewDef({cells:st}));
+}else{
+if(_3b(st)){
+s.push(this.addViewDef(st));
+}
+}
+}
+}
+}else{
+if(_3b(_33)){
+s.push(this.addViewDef(_33));
+}
+}
+this.cellCount=this.cells.length;
+this.grid.setupHeaderMenu();
+}});
+}
diff --git a/dojox/grid/_RowManager.js b/dojox/grid/_RowManager.js
new file mode 100644
index 0000000..3521b8d
--- /dev/null
+++ b/dojox/grid/_RowManager.js
@@ -0,0 +1,46 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid._RowManager"]){
+dojo._hasResource["dojox.grid._RowManager"]=true;
+dojo.provide("dojox.grid._RowManager");
+(function(){
+var _1=function(_2,_3){
+if(_2.style.cssText==undefined){
+_2.setAttribute("style",_3);
+}else{
+_2.style.cssText=_3;
+}
+};
+dojo.declare("dojox.grid._RowManager",null,{constructor:function(_4){
+this.grid=_4;
+},linesToEms:2,overRow:-2,prepareStylingRow:function(_5,_6){
+return {index:_5,node:_6,odd:Boolean(_5&1),selected:this.grid.selection.isSelected(_5),over:this.isOver(_5),customStyles:"",customClasses:"dojoxGridRow"};
+},styleRowNode:function(_7,_8){
+var _9=this.prepareStylingRow(_7,_8);
+this.grid.onStyleRow(_9);
+this.applyStyles(_9);
+},applyStyles:function(_a){
+var i=_a;
+i.node.className=i.customClasses;
+var h=i.node.style.height;
+_1(i.node,i.customStyles+";"+(i.node._style||""));
+i.node.style.height=h;
+},updateStyles:function(_d){
+this.grid.updateRowStyles(_d);
+},setOverRow:function(_e){
+var _f=this.overRow;
+this.overRow=_e;
+if((_f!=this.overRow)&&(_f>=0)){
+this.updateStyles(_f);
+}
+this.updateStyles(this.overRow);
+},isOver:function(_10){
+return (this.overRow==_10);
+}});
+})();
+}
diff --git a/dojox/grid/_RowSelector.js b/dojox/grid/_RowSelector.js
new file mode 100644
index 0000000..060d225
--- /dev/null
+++ b/dojox/grid/_RowSelector.js
@@ -0,0 +1,41 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid._RowSelector"]){
+dojo._hasResource["dojox.grid._RowSelector"]=true;
+dojo.provide("dojox.grid._RowSelector");
+dojo.require("dojox.grid._View");
+dojo.declare("dojox.grid._RowSelector",dojox.grid._View,{defaultWidth:"2em",noscroll:true,padBorderWidth:2,buildRendering:function(){
+this.inherited("buildRendering",arguments);
+this.scrollboxNode.style.overflow="hidden";
+this.headerNode.style.visibility="hidden";
+},getWidth:function(){
+return this.viewWidth||this.defaultWidth;
+},buildRowContent:function(_1,_2){
+var w=this.contentNode.offsetWidth-this.padBorderWidth;
+_2.innerHTML="<table class=\"dojoxGridRowbarTable\" style=\"width:"+w+"px;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" role=\""+(dojo.isFF<3?"wairole:":"")+"presentation\"><tr><td class=\"dojoxGridRowbarInner\"> </td></tr></table>";
+},renderHeader:function(){
+},resize:function(){
+this.adaptHeight();
+},adaptWidth:function(){
+},doStyleRowNode:function(_4,_5){
+var n=["dojoxGridRowbar"];
+if(this.grid.rows.isOver(_4)){
+n.push("dojoxGridRowbarOver");
+}
+if(this.grid.selection.isSelected(_4)){
+n.push("dojoxGridRowbarSelected");
+}
+_5.className=n.join(" ");
+},domouseover:function(e){
+this.grid.onMouseOverRow(e);
+},domouseout:function(e){
+if(!this.isIntraRowEvent(e)){
+this.grid.onMouseOutRow(e);
+}
+}});
+}
diff --git a/dojox/grid/_Scroller.js b/dojox/grid/_Scroller.js
new file mode 100644
index 0000000..0c88b42
--- /dev/null
+++ b/dojox/grid/_Scroller.js
@@ -0,0 +1,378 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid._Scroller"]){
+dojo._hasResource["dojox.grid._Scroller"]=true;
+dojo.provide("dojox.grid._Scroller");
+(function(){
+var _1=function(_2){
+var i=0,n,p=_2.parentNode;
+while((n=p.childNodes[i++])){
+if(n==_2){
+return i-1;
+}
+}
+return -1;
+};
+var _6=function(_7){
+if(!_7){
+return;
+}
+var _8=function(_9){
+return _9.domNode&&dojo.isDescendant(_9.domNode,_7,true);
+};
+var ws=dijit.registry.filter(_8);
+for(var i=0,w;(w=ws[i]);i++){
+w.destroy();
+}
+delete ws;
+};
+var _d=function(_e){
+var _f=dojo.byId(_e);
+return (_f&&_f.tagName?_f.tagName.toLowerCase():"");
+};
+var _10=function(_11,_12){
+var _13=[];
+var i=0,n;
+while((n=_11.childNodes[i++])){
+if(_d(n)==_12){
+_13.push(n);
+}
+}
+return _13;
+};
+var _16=function(_17){
+return _10(_17,"div");
+};
+dojo.declare("dojox.grid._Scroller",null,{constructor:function(_18){
+this.setContentNodes(_18);
+this.pageHeights=[];
+this.pageNodes=[];
+this.stack=[];
+},rowCount:0,defaultRowHeight:32,keepRows:100,contentNode:null,scrollboxNode:null,defaultPageHeight:0,keepPages:10,pageCount:0,windowHeight:0,firstVisibleRow:0,lastVisibleRow:0,averageRowHeight:0,page:0,pageTop:0,init:function(_19,_1a,_1b){
+switch(arguments.length){
+case 3:
+this.rowsPerPage=_1b;
+case 2:
+this.keepRows=_1a;
+case 1:
+this.rowCount=_19;
+}
+this.defaultPageHeight=this.defaultRowHeight*this.rowsPerPage;
+this.pageCount=this._getPageCount(this.rowCount,this.rowsPerPage);
+this.setKeepInfo(this.keepRows);
+this.invalidate();
+if(this.scrollboxNode){
+this.scrollboxNode.scrollTop=0;
+this.scroll(0);
+this.scrollboxNode.onscroll=dojo.hitch(this,"onscroll");
+}
+},_getPageCount:function(_1c,_1d){
+return _1c?(Math.ceil(_1c/_1d)||1):0;
+},destroy:function(){
+this.invalidateNodes();
+delete this.contentNodes;
+delete this.contentNode;
+delete this.scrollboxNode;
+},setKeepInfo:function(_1e){
+this.keepRows=_1e;
+this.keepPages=!this.keepRows?this.keepRows:Math.max(Math.ceil(this.keepRows/this.rowsPerPage),2);
+},setContentNodes:function(_1f){
+this.contentNodes=_1f;
+this.colCount=(this.contentNodes?this.contentNodes.length:0);
+this.pageNodes=[];
+for(var i=0;i<this.colCount;i++){
+this.pageNodes[i]=[];
+}
+},getDefaultNodes:function(){
+return this.pageNodes[0]||[];
+},invalidate:function(){
+this.invalidateNodes();
+this.pageHeights=[];
+this.height=(this.pageCount?(this.pageCount-1)*this.defaultPageHeight+this.calcLastPageHeight():0);
+this.resize();
+},updateRowCount:function(_21){
+this.invalidateNodes();
+this.rowCount=_21;
+var _22=this.pageCount;
+if(_22===0){
+this.height=1;
+}
+this.pageCount=this._getPageCount(this.rowCount,this.rowsPerPage);
+if(this.pageCount<_22){
+for(var i=_22-1;i>=this.pageCount;i--){
+this.height-=this.getPageHeight(i);
+delete this.pageHeights[i];
+}
+}else{
+if(this.pageCount>_22){
+this.height+=this.defaultPageHeight*(this.pageCount-_22-1)+this.calcLastPageHeight();
+}
+}
+this.resize();
+},pageExists:function(_24){
+return Boolean(this.getDefaultPageNode(_24));
+},measurePage:function(_25){
+var n=this.getDefaultPageNode(_25);
+return (n&&n.innerHTML)?n.offsetHeight:0;
+},positionPage:function(_27,_28){
+for(var i=0;i<this.colCount;i++){
+this.pageNodes[i][_27].style.top=_28+"px";
+}
+},repositionPages:function(_2a){
+var _2b=this.getDefaultNodes();
+var _2c=0;
+for(var i=0;i<this.stack.length;i++){
+_2c=Math.max(this.stack[i],_2c);
+}
+var n=_2b[_2a];
+var y=(n?this.getPageNodePosition(n)+this.getPageHeight(_2a):0);
+for(var p=_2a+1;p<=_2c;p++){
+n=_2b[p];
+if(n){
+if(this.getPageNodePosition(n)==y){
+return;
+}
+this.positionPage(p,y);
+}
+y+=this.getPageHeight(p);
+}
+},installPage:function(_31){
+for(var i=0;i<this.colCount;i++){
+this.contentNodes[i].appendChild(this.pageNodes[i][_31]);
+}
+},preparePage:function(_33,_34){
+var p=(_34?this.popPage():null);
+for(var i=0;i<this.colCount;i++){
+var _37=this.pageNodes[i];
+var _38=(p===null?this.createPageNode():this.invalidatePageNode(p,_37));
+_38.pageIndex=_33;
+_38.id=(this._pageIdPrefix||"")+"page-"+_33;
+_37[_33]=_38;
+}
+},renderPage:function(_39){
+var _3a=[];
+for(var i=0;i<this.colCount;i++){
+_3a[i]=this.pageNodes[i][_39];
+}
+for(var i=0,j=_39*this.rowsPerPage;(i<this.rowsPerPage)&&(j<this.rowCount);i++,j++){
+this.renderRow(j,_3a);
+}
+},removePage:function(_3d){
+for(var i=0,j=_3d*this.rowsPerPage;i<this.rowsPerPage;i++,j++){
+this.removeRow(j);
+}
+},destroyPage:function(_40){
+for(var i=0;i<this.colCount;i++){
+var n=this.invalidatePageNode(_40,this.pageNodes[i]);
+if(n){
+dojo.destroy(n);
+}
+}
+},pacify:function(_43){
+},pacifying:false,pacifyTicks:200,setPacifying:function(_44){
+if(this.pacifying!=_44){
+this.pacifying=_44;
+this.pacify(this.pacifying);
+}
+},startPacify:function(){
+this.startPacifyTicks=new Date().getTime();
+},doPacify:function(){
+var _45=(new Date().getTime()-this.startPacifyTicks)>this.pacifyTicks;
+this.setPacifying(true);
+this.startPacify();
+return _45;
+},endPacify:function(){
+this.setPacifying(false);
+},resize:function(){
+if(this.scrollboxNode){
+this.windowHeight=this.scrollboxNode.clientHeight;
+}
+for(var i=0;i<this.colCount;i++){
+dojox.grid.util.setStyleHeightPx(this.contentNodes[i],Math.max(1,this.height));
+}
+this.needPage(this.page,this.pageTop);
+var _47=(this.page<this.pageCount-1)?this.rowsPerPage:((this.rowCount%this.rowsPerPage)||this.rowsPerPage);
+var _48=this.getPageHeight(this.page);
+this.averageRowHeight=(_48>0&&_47>0)?(_48/_47):0;
+},calcLastPageHeight:function(){
+if(!this.pageCount){
+return 0;
+}
+var _49=this.pageCount-1;
+var _4a=((this.rowCount%this.rowsPerPage)||(this.rowsPerPage))*this.defaultRowHeight;
+this.pageHeights[_49]=_4a;
+return _4a;
+},updateContentHeight:function(_4b){
+this.height+=_4b;
+this.resize();
+},updatePageHeight:function(_4c){
+if(this.pageExists(_4c)){
+var oh=this.getPageHeight(_4c);
+var h=(this.measurePage(_4c))||(oh);
+this.pageHeights[_4c]=h;
+if((h)&&(oh!=h)){
+this.updateContentHeight(h-oh);
+this.repositionPages(_4c);
+}
+}
+},rowHeightChanged:function(_4f){
+this.updatePageHeight(Math.floor(_4f/this.rowsPerPage));
+},invalidateNodes:function(){
+while(this.stack.length){
+this.destroyPage(this.popPage());
+}
+},createPageNode:function(){
+var p=document.createElement("div");
+dojo.attr(p,"role","presentation");
+p.style.position="absolute";
+p.style[dojo._isBodyLtr()?"left":"right"]="0";
+return p;
+},getPageHeight:function(_51){
+var ph=this.pageHeights[_51];
+return (ph!==undefined?ph:this.defaultPageHeight);
+},pushPage:function(_53){
+return this.stack.push(_53);
+},popPage:function(){
+return this.stack.shift();
+},findPage:function(_54){
+var i=0,h=0;
+for(var ph=0;i<this.pageCount;i++,h+=ph){
+ph=this.getPageHeight(i);
+if(h+ph>=_54){
+break;
+}
+}
+this.page=i;
+this.pageTop=h;
+},buildPage:function(_58,_59,_5a){
+this.preparePage(_58,_59);
+this.positionPage(_58,_5a);
+this.installPage(_58);
+this.renderPage(_58);
+this.pushPage(_58);
+},needPage:function(_5b,_5c){
+var h=this.getPageHeight(_5b),oh=h;
+if(!this.pageExists(_5b)){
+this.buildPage(_5b,this.keepPages&&(this.stack.length>=this.keepPages),_5c);
+h=this.measurePage(_5b)||h;
+this.pageHeights[_5b]=h;
+if(h&&(oh!=h)){
+this.updateContentHeight(h-oh);
+}
+}else{
+this.positionPage(_5b,_5c);
+}
+return h;
+},onscroll:function(){
+this.scroll(this.scrollboxNode.scrollTop);
+},scroll:function(_5f){
+this.grid.scrollTop=_5f;
+if(this.colCount){
+this.startPacify();
+this.findPage(_5f);
+var h=this.height;
+var b=this.getScrollBottom(_5f);
+for(var p=this.page,y=this.pageTop;(p<this.pageCount)&&((b<0)||(y<b));p++){
+y+=this.needPage(p,y);
+}
+this.firstVisibleRow=this.getFirstVisibleRow(this.page,this.pageTop,_5f);
+this.lastVisibleRow=this.getLastVisibleRow(p-1,y,b);
+if(h!=this.height){
+this.repositionPages(p-1);
+}
+this.endPacify();
+}
+},getScrollBottom:function(_64){
+return (this.windowHeight>=0?_64+this.windowHeight:-1);
+},processNodeEvent:function(e,_66){
+var t=e.target;
+while(t&&(t!=_66)&&t.parentNode&&(t.parentNode.parentNode!=_66)){
+t=t.parentNode;
+}
+if(!t||!t.parentNode||(t.parentNode.parentNode!=_66)){
+return false;
+}
+var _68=t.parentNode;
+e.topRowIndex=_68.pageIndex*this.rowsPerPage;
+e.rowIndex=e.topRowIndex+_1(t);
+e.rowTarget=t;
+return true;
+},processEvent:function(e){
+return this.processNodeEvent(e,this.contentNode);
+},renderRow:function(_6a,_6b){
+},removeRow:function(_6c){
+},getDefaultPageNode:function(_6d){
+return this.getDefaultNodes()[_6d];
+},positionPageNode:function(_6e,_6f){
+},getPageNodePosition:function(_70){
+return _70.offsetTop;
+},invalidatePageNode:function(_71,_72){
+var p=_72[_71];
+if(p){
+delete _72[_71];
+this.removePage(_71,p);
+_6(p);
+p.innerHTML="";
+}
+return p;
+},getPageRow:function(_74){
+return _74*this.rowsPerPage;
+},getLastPageRow:function(_75){
+return Math.min(this.rowCount,this.getPageRow(_75+1))-1;
+},getFirstVisibleRow:function(_76,_77,_78){
+if(!this.pageExists(_76)){
+return 0;
+}
+var row=this.getPageRow(_76);
+var _7a=this.getDefaultNodes();
+var _7b=_16(_7a[_76]);
+for(var i=0,l=_7b.length;i<l&&_77<_78;i++,row++){
+_77+=_7b[i].offsetHeight;
+}
+return (row?row-1:row);
+},getLastVisibleRow:function(_7e,_7f,_80){
+if(!this.pageExists(_7e)){
+return 0;
+}
+var _81=this.getDefaultNodes();
+var row=this.getLastPageRow(_7e);
+var _83=_16(_81[_7e]);
+for(var i=_83.length-1;i>=0&&_7f>_80;i--,row--){
+_7f-=_83[i].offsetHeight;
+}
+return row+1;
+},findTopRow:function(_85){
+var _86=this.getDefaultNodes();
+var _87=_16(_86[this.page]);
+for(var i=0,l=_87.length,t=this.pageTop,h;i<l;i++){
+h=_87[i].offsetHeight;
+t+=h;
+if(t>=_85){
+this.offset=h-(t-_85);
+return i+this.page*this.rowsPerPage;
+}
+}
+return -1;
+},findScrollTop:function(_8c){
+var _8d=Math.floor(_8c/this.rowsPerPage);
+var t=0;
+for(var i=0;i<_8d;i++){
+t+=this.getPageHeight(i);
+}
+this.pageTop=t;
+this.needPage(_8d,this.pageTop);
+var _90=this.getDefaultNodes();
+var _91=_16(_90[_8d]);
+var r=_8c-this.rowsPerPage*_8d;
+for(var i=0,l=_91.length;i<l&&i<r;i++){
+t+=_91[i].offsetHeight;
+}
+return t;
+},dummy:0});
+})();
+}
diff --git a/dojox/grid/_View.js b/dojox/grid/_View.js
new file mode 100644
index 0000000..dc11594
--- /dev/null
+++ b/dojox/grid/_View.js
@@ -0,0 +1,501 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid._View"]){
+dojo._hasResource["dojox.grid._View"]=true;
+dojo.provide("dojox.grid._View");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dojox.grid._Builder");
+dojo.require("dojox.html.metrics");
+dojo.require("dojox.grid.util");
+dojo.require("dojo.dnd.Source");
+dojo.require("dojo.dnd.Manager");
+(function(){
+var _1=function(_2,_3){
+return _2.style.cssText==undefined?_2.getAttribute("style"):_2.style.cssText;
+};
+dojo.declare("dojox.grid._View",[dijit._Widget,dijit._Templated],{defaultWidth:"18em",viewWidth:"",templateString:"<div class=\"dojoxGridView\" wairole=\"presentation\">\n\t<div class=\"dojoxGridHeader\" dojoAttachPoint=\"headerNode\" wairole=\"presentation\">\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\" wairole=\"presentation\">\n\t\t\t<div dojoAttachPoint=\"headerContentNode\" wairole=\"row\"></div>\n\t\t</div>\n\t</div>\n\t<input type=\"checkbox\" class=\"d [...]
+this.rowNodes=[];
+},postCreate:function(){
+this.connect(this.scrollboxNode,"onscroll","doscroll");
+dojox.grid.util.funnelEvents(this.contentNode,this,"doContentEvent",["mouseover","mouseout","click","dblclick","contextmenu","mousedown"]);
+dojox.grid.util.funnelEvents(this.headerNode,this,"doHeaderEvent",["dblclick","mouseover","mouseout","mousemove","mousedown","click","contextmenu"]);
+this.content=new dojox.grid._ContentBuilder(this);
+this.header=new dojox.grid._HeaderBuilder(this);
+if(!dojo._isBodyLtr()){
+this.headerNodeContainer.style.width="";
+}
+},destroy:function(){
+dojo.destroy(this.headerNode);
+delete this.headerNode;
+dojo.forEach(this.rowNodes,dojo.destroy);
+this.rowNodes=[];
+if(this.source){
+this.source.destroy();
+}
+this.inherited(arguments);
+},focus:function(){
+if(dojo.isWebKit||dojo.isOpera){
+this.hiddenFocusNode.focus();
+}else{
+this.scrollboxNode.focus();
+}
+},setStructure:function(_4){
+var vs=(this.structure=_4);
+if(vs.width&&!isNaN(vs.width)){
+this.viewWidth=vs.width+"em";
+}else{
+this.viewWidth=vs.width||(vs.noscroll?"auto":this.viewWidth);
+}
+this.onBeforeRow=vs.onBeforeRow;
+this.onAfterRow=vs.onAfterRow;
+this.noscroll=vs.noscroll;
+if(this.noscroll){
+this.scrollboxNode.style.overflow="hidden";
+}
+this.simpleStructure=Boolean(vs.cells.length==1);
+this.testFlexCells();
+this.updateStructure();
+},testFlexCells:function(){
+this.flexCells=false;
+for(var j=0,_7;(_7=this.structure.cells[j]);j++){
+for(var i=0,_9;(_9=_7[i]);i++){
+_9.view=this;
+this.flexCells=this.flexCells||_9.isFlex();
+}
+}
+return this.flexCells;
+},updateStructure:function(){
+this.header.update();
+this.content.update();
+},getScrollbarWidth:function(){
+var _a=this.hasVScrollbar();
+var _b=dojo.style(this.scrollboxNode,"overflow");
+if(this.noscroll||!_b||_b=="hidden"){
+_a=false;
+}else{
+if(_b=="scroll"){
+_a=true;
+}
+}
+return (_a?dojox.html.metrics.getScrollbar().w:0);
+},getColumnsWidth:function(){
+return this.headerContentNode.firstChild.offsetWidth;
+},setColumnsWidth:function(_c){
+this.headerContentNode.firstChild.style.width=_c+"px";
+if(this.viewWidth){
+this.viewWidth=_c+"px";
+}
+},getWidth:function(){
+return this.viewWidth||(this.getColumnsWidth()+this.getScrollbarWidth())+"px";
+},getContentWidth:function(){
+return Math.max(0,dojo._getContentBox(this.domNode).w-this.getScrollbarWidth())+"px";
+},render:function(){
+this.scrollboxNode.style.height="";
+this.renderHeader();
+if(this._togglingColumn>=0){
+this.setColumnsWidth(this.getColumnsWidth()-this._togglingColumn);
+this._togglingColumn=-1;
+}
+var _d=this.grid.layout.cells;
+var _e=dojo.hitch(this,function(_f,_10){
+var inc=_10?-1:1;
+var idx=this.header.getCellNodeIndex(_f)+inc;
+var _13=_d[idx];
+while(_13&&_13.getHeaderNode()&&_13.getHeaderNode().style.display=="none"){
+idx+=inc;
+_13=_d[idx];
+}
+if(_13){
+return _13.getHeaderNode();
+}
+return null;
+});
+if(this.grid.columnReordering&&this.simpleStructure){
+if(this.source){
+this.source.destroy();
+}
+this.source=new dojo.dnd.Source(this.headerContentNode.firstChild.rows[0],{horizontal:true,accept:["gridColumn_"+this.grid.id],viewIndex:this.index,onMouseDown:dojo.hitch(this,function(e){
+this.header.decorateEvent(e);
+if((this.header.overRightResizeArea(e)||this.header.overLeftResizeArea(e))&&this.header.canResize(e)&&!this.header.moveable){
+this.header.beginColumnResize(e);
+}else{
+if(this.grid.headerMenu){
+this.grid.headerMenu.onCancel(true);
+}
+if(e.button===(dojo.isIE?1:0)){
+dojo.dnd.Source.prototype.onMouseDown.call(this.source,e);
+}
+}
+}),_markTargetAnchor:dojo.hitch(this,function(_15){
+var src=this.source;
+if(src.current==src.targetAnchor&&src.before==_15){
+return;
+}
+if(src.targetAnchor&&_e(src.targetAnchor,src.before)){
+src._removeItemClass(_e(src.targetAnchor,src.before),src.before?"After":"Before");
+}
+dojo.dnd.Source.prototype._markTargetAnchor.call(src,_15);
+if(src.targetAnchor&&_e(src.targetAnchor,src.before)){
+src._addItemClass(_e(src.targetAnchor,src.before),src.before?"After":"Before");
+}
+}),_unmarkTargetAnchor:dojo.hitch(this,function(){
+var src=this.source;
+if(!src.targetAnchor){
+return;
+}
+if(src.targetAnchor&&_e(src.targetAnchor,src.before)){
+src._removeItemClass(_e(src.targetAnchor,src.before),src.before?"After":"Before");
+}
+dojo.dnd.Source.prototype._unmarkTargetAnchor.call(src);
+}),destroy:dojo.hitch(this,function(){
+dojo.disconnect(this._source_conn);
+dojo.unsubscribe(this._source_sub);
+dojo.dnd.Source.prototype.destroy.call(this.source);
+})});
+this._source_conn=dojo.connect(this.source,"onDndDrop",this,"_onDndDrop");
+this._source_sub=dojo.subscribe("/dnd/drop/before",this,"_onDndDropBefore");
+this.source.startup();
+}
+},_onDndDropBefore:function(_18,_19,_1a){
+if(dojo.dnd.manager().target!==this.source){
+return;
+}
+this.source._targetNode=this.source.targetAnchor;
+this.source._beforeTarget=this.source.before;
+var _1b=this.grid.views.views;
+var _1c=_1b[_18.viewIndex];
+var _1d=_1b[this.index];
+if(_1d!=_1c){
+var s=_1c.convertColPctToFixed();
+var t=_1d.convertColPctToFixed();
+if(s||t){
+setTimeout(function(){
+_1c.update();
+_1d.update();
+},50);
+}
+}
+},_onDndDrop:function(_20,_21,_22){
+if(dojo.dnd.manager().target!==this.source){
+if(dojo.dnd.manager().source===this.source){
+this._removingColumn=true;
+}
+return;
+}
+var _23=function(n){
+return n?dojo.attr(n,"idx"):null;
+};
+var w=dojo.marginBox(_21[0]).w;
+if(_20.viewIndex!==this.index){
+var _26=this.grid.views.views;
+var _27=_26[_20.viewIndex];
+var _28=_26[this.index];
+if(_27.viewWidth&&_27.viewWidth!="auto"){
+_27.setColumnsWidth(_27.getColumnsWidth()-w);
+}
+if(_28.viewWidth&&_28.viewWidth!="auto"){
+_28.setColumnsWidth(_28.getColumnsWidth());
+}
+}
+var stn=this.source._targetNode;
+var stb=this.source._beforeTarget;
+var _2b=this.grid.layout;
+var idx=this.index;
+delete this.source._targetNode;
+delete this.source._beforeTarget;
+window.setTimeout(function(){
+_2b.moveColumn(_20.viewIndex,idx,_23(_21[0]),_23(stn),stb);
+},1);
+},renderHeader:function(){
+this.headerContentNode.innerHTML=this.header.generateHtml(this._getHeaderContent);
+if(this.flexCells){
+this.contentWidth=this.getContentWidth();
+this.headerContentNode.firstChild.style.width=this.contentWidth;
+}
+dojox.grid.util.fire(this,"onAfterRow",[-1,this.structure.cells,this.headerContentNode]);
+},_getHeaderContent:function(_2d){
+var n=_2d.name||_2d.grid.getCellName(_2d);
+var ret=["<div class=\"dojoxGridSortNode"];
+if(_2d.index!=_2d.grid.getSortIndex()){
+ret.push("\">");
+}else{
+ret=ret.concat([" ",_2d.grid.sortInfo>0?"dojoxGridSortUp":"dojoxGridSortDown","\"><div class=\"dojoxGridArrowButtonChar\">",_2d.grid.sortInfo>0?"▲":"▼","</div><div class=\"dojoxGridArrowButtonNode\" role=\""+(dojo.isFF<3?"wairole:":"")+"presentation\"></div>"]);
+}
+ret=ret.concat([n,"</div>"]);
+return ret.join("");
+},resize:function(){
+this.adaptHeight();
+this.adaptWidth();
+},hasHScrollbar:function(_30){
+if(this._hasHScroll==undefined||_30){
+if(this.noscroll){
+this._hasHScroll=false;
+}else{
+var _31=dojo.style(this.scrollboxNode,"overflow");
+if(_31=="hidden"){
+this._hasHScroll=false;
+}else{
+if(_31=="scroll"){
+this._hasHScroll=true;
+}else{
+this._hasHScroll=(this.scrollboxNode.offsetWidth<this.contentNode.offsetWidth);
+}
+}
+}
+}
+return this._hasHScroll;
+},hasVScrollbar:function(_32){
+if(this._hasVScroll==undefined||_32){
+if(this.noscroll){
+this._hasVScroll=false;
+}else{
+var _33=dojo.style(this.scrollboxNode,"overflow");
+if(_33=="hidden"){
+this._hasVScroll=false;
+}else{
+if(_33=="scroll"){
+this._hasVScroll=true;
+}else{
+this._hasVScroll=(this.scrollboxNode.offsetHeight<this.contentNode.offsetHeight);
+}
+}
+}
+}
+return this._hasVScroll;
+},convertColPctToFixed:function(){
+var _34=false;
+var _35=dojo.query("th",this.headerContentNode);
+var _36=dojo.map(_35,function(c,_38){
+var w=c.style.width;
+dojo.attr(c,"vIdx",_38);
+if(w&&w.slice(-1)=="%"){
+_34=true;
+}else{
+if(w&&w.slice(-2)=="px"){
+return window.parseInt(w,10);
+}
+}
+return dojo.contentBox(c).w;
+});
+if(_34){
+dojo.forEach(this.grid.layout.cells,function(_3a,idx){
+if(_3a.view==this){
+var _3c=_3a.view.getHeaderCellNode(_3a.index);
+if(_3c&&dojo.hasAttr(_3c,"vIdx")){
+var _3d=window.parseInt(dojo.attr(_3c,"vIdx"));
+this.setColWidth(idx,_36[_3d]);
+_35[_3d].style.width=_3a.unitWidth;
+dojo.removeAttr(_3c,"vIdx");
+}
+}
+},this);
+return true;
+}
+return false;
+},adaptHeight:function(_3e){
+if(!this.grid._autoHeight){
+var h=this.domNode.clientHeight;
+if(_3e){
+h-=dojox.html.metrics.getScrollbar().h;
+}
+dojox.grid.util.setStyleHeightPx(this.scrollboxNode,h);
+}
+this.hasVScrollbar(true);
+},adaptWidth:function(){
+if(this.flexCells){
+this.contentWidth=this.getContentWidth();
+this.headerContentNode.firstChild.style.width=this.contentWidth;
+}
+var w=this.scrollboxNode.offsetWidth-this.getScrollbarWidth();
+if(!this._removingColumn){
+w=Math.max(w,this.getColumnsWidth())+"px";
+}else{
+w=Math.min(w,this.getColumnsWidth())+"px";
+this._removingColumn=false;
+}
+var cn=this.contentNode;
+cn.style.width=w;
+this.hasHScrollbar(true);
+},setSize:function(w,h){
+var ds=this.domNode.style;
+var hs=this.headerNode.style;
+if(w){
+ds.width=w;
+hs.width=w;
+}
+ds.height=(h>=0?h+"px":"");
+},renderRow:function(_46){
+var _47=this.createRowNode(_46);
+this.buildRow(_46,_47);
+this.grid.edit.restore(this,_46);
+if(this._pendingUpdate){
+window.clearTimeout(this._pendingUpdate);
+}
+this._pendingUpdate=window.setTimeout(dojo.hitch(this,function(){
+window.clearTimeout(this._pendingUpdate);
+delete this._pendingUpdate;
+this.grid._resize();
+}),50);
+return _47;
+},createRowNode:function(_48){
+var _49=document.createElement("div");
+_49.className=this.classTag+"Row";
+dojo.attr(_49,"role","row");
+_49[dojox.grid.util.gridViewTag]=this.id;
+_49[dojox.grid.util.rowIndexTag]=_48;
+this.rowNodes[_48]=_49;
+return _49;
+},buildRow:function(_4a,_4b){
+this.buildRowContent(_4a,_4b);
+this.styleRow(_4a,_4b);
+},buildRowContent:function(_4c,_4d){
+_4d.innerHTML=this.content.generateHtml(_4c,_4c);
+if(this.flexCells&&this.contentWidth){
+_4d.firstChild.style.width=this.contentWidth;
+}
+dojox.grid.util.fire(this,"onAfterRow",[_4c,this.structure.cells,_4d]);
+},rowRemoved:function(_4e){
+this.grid.edit.save(this,_4e);
+delete this.rowNodes[_4e];
+},getRowNode:function(_4f){
+return this.rowNodes[_4f];
+},getCellNode:function(_50,_51){
+var row=this.getRowNode(_50);
+if(row){
+return this.content.getCellNode(row,_51);
+}
+},getHeaderCellNode:function(_53){
+if(this.headerContentNode){
+return this.header.getCellNode(this.headerContentNode,_53);
+}
+},styleRow:function(_54,_55){
+_55._style=_1(_55);
+this.styleRowNode(_54,_55);
+},styleRowNode:function(_56,_57){
+if(_57){
+this.doStyleRowNode(_56,_57);
+}
+},doStyleRowNode:function(_58,_59){
+this.grid.styleRowNode(_58,_59);
+},updateRow:function(_5a){
+var _5b=this.getRowNode(_5a);
+if(_5b){
+_5b.style.height="";
+this.buildRow(_5a,_5b);
+}
+return _5b;
+},updateRowStyles:function(_5c){
+this.styleRowNode(_5c,this.getRowNode(_5c));
+},lastTop:0,firstScroll:0,doscroll:function(_5d){
+var _5e=dojo._isBodyLtr();
+if(this.firstScroll<2){
+if((!_5e&&this.firstScroll==1)||(_5e&&this.firstScroll==0)){
+var s=dojo.marginBox(this.headerNodeContainer);
+if(dojo.isIE){
+this.headerNodeContainer.style.width=s.w+this.getScrollbarWidth()+"px";
+}else{
+if(dojo.isMoz){
+this.headerNodeContainer.style.width=s.w-this.getScrollbarWidth()+"px";
+this.scrollboxNode.scrollLeft=_5e?this.scrollboxNode.clientWidth-this.scrollboxNode.scrollWidth:this.scrollboxNode.scrollWidth-this.scrollboxNode.clientWidth;
+}
+}
+}
+this.firstScroll++;
+}
+this.headerNode.scrollLeft=this.scrollboxNode.scrollLeft;
+var top=this.scrollboxNode.scrollTop;
+if(top!=this.lastTop){
+this.grid.scrollTo(top);
+}
+},setScrollTop:function(_61){
+this.lastTop=_61;
+this.scrollboxNode.scrollTop=_61;
+return this.scrollboxNode.scrollTop;
+},doContentEvent:function(e){
+if(this.content.decorateEvent(e)){
+this.grid.onContentEvent(e);
+}
+},doHeaderEvent:function(e){
+if(this.header.decorateEvent(e)){
+this.grid.onHeaderEvent(e);
+}
+},dispatchContentEvent:function(e){
+return this.content.dispatchEvent(e);
+},dispatchHeaderEvent:function(e){
+return this.header.dispatchEvent(e);
+},setColWidth:function(_66,_67){
+this.grid.setCellWidth(_66,_67+"px");
+},update:function(){
+this.content.update();
+this.grid.update();
+var _68=this.scrollboxNode.scrollLeft;
+this.scrollboxNode.scrollLeft=_68;
+this.headerNode.scrollLeft=_68;
+}});
+dojo.declare("dojox.grid._GridAvatar",dojo.dnd.Avatar,{construct:function(){
+var dd=dojo.doc;
+var a=dd.createElement("table");
+a.cellPadding=a.cellSpacing="0";
+a.className="dojoxGridDndAvatar";
+a.style.position="absolute";
+a.style.zIndex=1999;
+a.style.margin="0px";
+var b=dd.createElement("tbody");
+var tr=dd.createElement("tr");
+var td=dd.createElement("td");
+var img=dd.createElement("td");
+tr.className="dojoxGridDndAvatarItem";
+img.className="dojoxGridDndAvatarItemImage";
+img.style.width="16px";
+var _6f=this.manager.source,_70;
+if(_6f.creator){
+_70=_6f._normailzedCreator(_6f.getItem(this.manager.nodes[0].id).data,"avatar").node;
+}else{
+_70=this.manager.nodes[0].cloneNode(true);
+if(_70.tagName.toLowerCase()=="tr"){
+var _71=dd.createElement("table"),_72=dd.createElement("tbody");
+_72.appendChild(_70);
+_71.appendChild(_72);
+_70=_71;
+}else{
+if(_70.tagName.toLowerCase()=="th"){
+var _71=dd.createElement("table"),_72=dd.createElement("tbody"),r=dd.createElement("tr");
+_71.cellPadding=_71.cellSpacing="0";
+r.appendChild(_70);
+_72.appendChild(r);
+_71.appendChild(_72);
+_70=_71;
+}
+}
+}
+_70.id="";
+td.appendChild(_70);
+tr.appendChild(img);
+tr.appendChild(td);
+dojo.style(tr,"opacity",0.9);
+b.appendChild(tr);
+a.appendChild(b);
+this.node=a;
+var m=dojo.dnd.manager();
+this.oldOffsetY=m.OFFSET_Y;
+m.OFFSET_Y=1;
+},destroy:function(){
+dojo.dnd.manager().OFFSET_Y=this.oldOffsetY;
+this.inherited(arguments);
+}});
+var _75=dojo.dnd.manager().makeAvatar;
+dojo.dnd.manager().makeAvatar=function(){
+var src=this.source;
+if(src.viewIndex!==undefined){
+return new dojox.grid._GridAvatar(this);
+}
+return _75.call(dojo.dnd.manager());
+};
+})();
+}
diff --git a/dojox/grid/_ViewManager.js b/dojox/grid/_ViewManager.js
new file mode 100644
index 0000000..ad50a43
--- /dev/null
+++ b/dojox/grid/_ViewManager.js
@@ -0,0 +1,189 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid._ViewManager"]){
+dojo._hasResource["dojox.grid._ViewManager"]=true;
+dojo.provide("dojox.grid._ViewManager");
+dojo.declare("dojox.grid._ViewManager",null,{constructor:function(_1){
+this.grid=_1;
+},defaultWidth:200,views:[],resize:function(){
+this.onEach("resize");
+},render:function(){
+this.onEach("render");
+},addView:function(_2){
+_2.idx=this.views.length;
+this.views.push(_2);
+},destroyViews:function(){
+for(var i=0,v;v=this.views[i];i++){
+v.destroy();
+}
+this.views=[];
+},getContentNodes:function(){
+var _5=[];
+for(var i=0,v;v=this.views[i];i++){
+_5.push(v.contentNode);
+}
+return _5;
+},forEach:function(_8){
+for(var i=0,v;v=this.views[i];i++){
+_8(v,i);
+}
+},onEach:function(_b,_c){
+_c=_c||[];
+for(var i=0,v;v=this.views[i];i++){
+if(_b in v){
+v[_b].apply(v,_c);
+}
+}
+},normalizeHeaderNodeHeight:function(){
+var _f=[];
+for(var i=0,v;(v=this.views[i]);i++){
+if(v.headerContentNode.firstChild){
+_f.push(v.headerContentNode);
+}
+}
+this.normalizeRowNodeHeights(_f);
+},normalizeRowNodeHeights:function(_12){
+var h=0;
+for(var i=0,n,o;(n=_12[i]);i++){
+h=Math.max(h,dojo.marginBox(n.firstChild).h);
+}
+h=(h>=0?h:0);
+for(var i=0,n;(n=_12[i]);i++){
+dojo.marginBox(n.firstChild,{h:h});
+}
+if(_12&&_12[0]&&_12[0].parentNode){
+_12[0].parentNode.offsetHeight;
+}
+},resetHeaderNodeHeight:function(){
+for(var i=0,v,n;(v=this.views[i]);i++){
+n=v.headerContentNode.firstChild;
+if(n){
+n.style.height="";
+}
+}
+},renormalizeRow:function(_1a){
+var _1b=[];
+for(var i=0,v,n;(v=this.views[i])&&(n=v.getRowNode(_1a));i++){
+n.firstChild.style.height="";
+_1b.push(n);
+}
+this.normalizeRowNodeHeights(_1b);
+},getViewWidth:function(_1f){
+return this.views[_1f].getWidth()||this.defaultWidth;
+},measureHeader:function(){
+this.resetHeaderNodeHeight();
+this.forEach(function(_20){
+_20.headerContentNode.style.height="";
+});
+var h=0;
+this.forEach(function(_22){
+h=Math.max(_22.headerNode.offsetHeight,h);
+});
+return h;
+},measureContent:function(){
+var h=0;
+this.forEach(function(_24){
+h=Math.max(_24.domNode.offsetHeight,h);
+});
+return h;
+},findClient:function(_25){
+var c=this.grid.elasticView||-1;
+if(c<0){
+for(var i=1,v;(v=this.views[i]);i++){
+if(v.viewWidth){
+for(i=1;(v=this.views[i]);i++){
+if(!v.viewWidth){
+c=i;
+break;
+}
+}
+break;
+}
+}
+}
+if(c<0){
+c=Math.floor(this.views.length/2);
+}
+return c;
+},arrange:function(l,w){
+var i,v,vw,len=this.views.length;
+var c=(w<=0?len:this.findClient());
+var _30=function(v,l){
+var ds=v.domNode.style;
+var hs=v.headerNode.style;
+if(!dojo._isBodyLtr()){
+ds.right=l+"px";
+hs.right=l+"px";
+}else{
+ds.left=l+"px";
+hs.left=l+"px";
+}
+ds.top=0+"px";
+hs.top=0;
+};
+for(i=0;(v=this.views[i])&&(i<c);i++){
+vw=this.getViewWidth(i);
+v.setSize(vw,0);
+_30(v,l);
+if(v.headerContentNode&&v.headerContentNode.firstChild){
+vw=v.getColumnsWidth()+v.getScrollbarWidth();
+}else{
+vw=v.domNode.offsetWidth;
+}
+l+=vw;
+}
+i++;
+var r=w;
+for(var j=len-1;(v=this.views[j])&&(i<=j);j--){
+vw=this.getViewWidth(j);
+v.setSize(vw,0);
+vw=v.domNode.offsetWidth;
+r-=vw;
+_30(v,r);
+}
+if(c<len){
+v=this.views[c];
+vw=Math.max(1,r-l);
+v.setSize(vw+"px",0);
+_30(v,l);
+}
+return l;
+},renderRow:function(_37,_38){
+var _39=[];
+for(var i=0,v,n,_3d;(v=this.views[i])&&(n=_38[i]);i++){
+_3d=v.renderRow(_37);
+n.appendChild(_3d);
+_39.push(_3d);
+}
+this.normalizeRowNodeHeights(_39);
+},rowRemoved:function(_3e){
+this.onEach("rowRemoved",[_3e]);
+},updateRow:function(_3f){
+for(var i=0,v;v=this.views[i];i++){
+v.updateRow(_3f);
+}
+this.renormalizeRow(_3f);
+},updateRowStyles:function(_42){
+this.onEach("updateRowStyles",[_42]);
+},setScrollTop:function(_43){
+var top=_43;
+for(var i=0,v;v=this.views[i];i++){
+top=v.setScrollTop(_43);
+if(dojo.isIE&&v.headerNode&&v.scrollboxNode){
+v.headerNode.scrollLeft=v.scrollboxNode.scrollLeft;
+}
+}
+return top;
+},getFirstScrollingView:function(){
+for(var i=0,v;(v=this.views[i]);i++){
+if(v.hasHScrollbar()||v.hasVScrollbar()){
+return v;
+}
+}
+}});
+}
diff --git a/dojox/grid/_grid/Grid.css b/dojox/grid/_grid/Grid.css
new file mode 100644
index 0000000..123de2b
--- /dev/null
+++ b/dojox/grid/_grid/Grid.css
@@ -0,0 +1,201 @@
+.dojoxGrid {
+	position: relative;
+	background-color: #EBEADB;
+	font-family: Geneva, Arial, Helvetica, sans-serif;
+	-moz-outline-style: none;
+	outline: none;
+	overflow: hidden;
+	height: 0;
+}
+.dojoxGrid table {
+	padding: 0;
+}
+.dojoxGrid td {
+	-moz-outline: none;
+}
+.dojoxGrid-master-header {
+	position: relative;
+}
+.dojoxGrid-master-view  {
+	position: relative;
+}
+.dojoxGrid-view {
+	position: absolute;
+	overflow: hidden;
+}
+.dojoxGrid-header {
+	position: absolute;
+	overflow: hidden;
+}
+.dojoxGrid-header {
+	background-color: #E8E1CF;
+}
+.dojoxGrid-header table {
+	text-align: center;
+}
+.dojoxGrid-header .dojoxGrid-cell-content {
+	text-align: center;
+}
+.dojoxGrid-header .dojoxGrid-cell { 
+	border: 1px solid;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	background: url(../compat/_grid/images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+	padding-bottom: 2px;
+}
+.dojoxGrid-header .dojoxGrid-cell-over {
+	background-image: none;
+	background-color: white;
+	border-bottom-color: #FEBE47;
+	margin-bottom: 0;
+	padding-bottom: 0;
+	border-bottom-width: 3px;
+}
+.dojoxGrid-sort-down {
+	background: url(../compat/_grid/images/grid_sort_down.gif) left no-repeat; 
+	padding-left:16px;
+	margin-left:4px;
+}
+.dojoxGrid-sort-up {
+	background: url(../compat/_grid/images/grid_sort_up.gif) left no-repeat; 
+	padding-left:16px;
+	margin-left:4px;
+}
+.dojoxGrid-scrollbox {
+	position: relative;
+	overflow: scroll;
+	background-color: white;
+	width: 100%;
+}
+.dojoxGrid-content {
+	position: relative;
+	overflow: hidden;
+	 -moz-outline-style: none;
+	outline: none;
+}
+.dojoxGrid-rowbar { 
+	border: 1px solid;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	border-top: none;
+	background: url(../compat/_grid/images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+}
+.dojoxGrid-rowbar-inner {
+	border-top: 1px solid #F6F4EB;
+}
+.dojoxGrid-rowbar-over {
+	background-image: none;
+	background-color: white;
+	border-top-color: #FEBE47;
+	border-bottom-color: #FEBE47;
+}
+.dojoxGrid-rowbar-selected {
+	background-color: #D9E8F9;
+	background-image: none;
+	
+	background-position: center;
+	background-repeat: no-repeat;
+}
+.dojoxGrid-row {
+	position: relative;
+	width: 9000em;
+}
+.dojoxGrid-row {
+	
+	border: 1px solid #E8E4D8;
+	border-color: #F8F7F1;
+	
+	border-left: none;
+	border-right: none;
+	background-color: white;
+	border-top: none;
+}
+.dojoxGrid-row-over {
+	border-top-color: #FEBE47;
+	border-bottom-color: #FEBE47;
+	
+	
+	
+}
+.dojoxGrid-row-odd {
+	background-color: #FFFDF3;
+	
+}
+.dojoxGrid-row-selected {
+	background-color: #D9E8F9;
+}
+.dojoxGrid-row-table {
+	table-layout: fixed;
+	width: 0;
+}
+.dojoxGrid-invisible {
+	visibility: hidden;
+}		
+.Xdojo-ie .dojoxGrid-invisible {
+	display: none;
+}		
+.dojoxGrid-invisible td, .dojoxGrid-header .dojoxGrid-invisible td {
+	border-top-width: 0;
+	border-bottom-width: 0;
+	padding-top: 0;
+	padding-bottom: 0;
+	height: 0;
+	overflow: hidden;
+}
+.dojoxGrid-cell {
+	border: 1px solid;
+	border-color: #EBEADB;
+	border-right-color: #D5CDB5;
+	padding: 3px 3px 3px 3px;
+	text-align: left;
+	overflow: hidden;
+}
+.dojoxGrid-cell-focus {
+	border: 1px dashed blue;
+}
+.dojoxGrid-cell-over {
+	border: 1px dotted #FEBE47;
+}
+.dojoxGrid-cell-focus.dojoxGrid-cell-over {
+	border: 1px dotted green;
+}
+.dojoxGrid-cell-clip {
+	width: 100%;
+	overflow: hidden;
+	white-space:nowrap;
+	text-overflow: ellipsis;
+}
+.dojoxGrid-row-editing td {
+	background-color: #F4FFF4;
+}
+.dojoxGrid-row-inserting td {
+	background-color: #F4FFF4;
+}
+.dojoxGrid-row-inflight td {
+	background-color: #F2F7B7;
+}
+.dojoxGrid-row-error td {
+	background-color: #F8B8B6;
+}
+.dojoxGrid-input, .dojoxGrid-select, .dojoxGrid-textarea {
+	margin: 0;
+	padding: 0;
+	border-style: none;
+	width: 100%;
+	font-size: 100%;
+	font-family: inherit;
+}
+.dojoxGrid-hidden-focus {
+	position: absolute;
+	left: -1000px;
+	top: -1000px;
+	height: 0px, width: 0px;
+}
+.gridArrowButtonChar {
+	display:none !important;
+}
+.dijit_a11y .gridArrowButtonChar {
+	display:inline !important;
+}
+.dijit_a11y .dojoxGrid-sort-down, .dijit_a11y .dojoxGrid-sort-up {
+	margin-left: 0;
+	padding-left: 0;
+}
diff --git a/dojox/grid/_grid/Grid_rtl.css b/dojox/grid/_grid/Grid_rtl.css
new file mode 100644
index 0000000..88ab215
--- /dev/null
+++ b/dojox/grid/_grid/Grid_rtl.css
@@ -0,0 +1,8 @@
+.dijitRtl .dojoxGrid-header table {
+}
+.dj_ie .dijitRtl .dojoxGrid-header table {
+	float:none;
+}
+.dijitRtl .dojoxGrid-content {
+	float:left;
+}
diff --git a/dojox/grid/_grid/nihiloGrid.css b/dojox/grid/_grid/nihiloGrid.css
new file mode 100644
index 0000000..6d57d61
--- /dev/null
+++ b/dojox/grid/_grid/nihiloGrid.css
@@ -0,0 +1,211 @@
+.nihilo .dojoxGrid {
+	position: relative;
+	background-color: #e9e9e9;
+	font-size: 0.85em; 
+	-moz-outline-style: none;
+	outline: none;
+	overflow: hidden;
+	height: 0;
+}
+.nihilo .dojoxGrid table {
+	padding: 0;
+}
+.nihilo .dojoxGrid td {
+	-moz-outline: none;
+}
+.nihilo .dojoxGrid-master-header {
+	position: relative;
+}
+.nihilo .dojoxGrid-master-view  {
+	position: relative;
+}
+.nihilo .dojoxGrid-view {
+	position: absolute;
+	overflow: hidden;
+}
+.nihilo .dojoxGrid-header {
+	position: absolute;
+	overflow: hidden;
+}
+.nihilo .dojoxGrid-header {
+	background-color:  #e9e9e9;
+}
+.nihilo .dojoxGrid-header table {
+	text-align: center;
+}
+.nihilo .dojoxGrid-header .dojoxGrid-cell-content {
+	text-align: center;
+}
+.nihilo .dojoxGrid-header .dojoxGrid-cell { 
+	border: 1px solid transparent;
+	
+	border-color: white #ACA899 #919191 white;
+	background: url(../compat/../../../dijit/themes/nihilo/images/titleBar.png) #e9e9e9 repeat-x top;
+	padding-bottom: 2px;
+	color: #000 !important;
+}
+.nihilo .dojoxGrid-header .dojoxGrid-cell-over {
+	background: url(../compat/../../../dijit/themes/nihilo/images/titleBarActive.png) #e9e9e9 repeat-x top;
+}
+.nihilo .dojoxGrid-sort-down {
+	background: url(../compat/_grid/images/grid_sort_down.gif) right no-repeat;
+	padding-left: 0px;
+	margin-left: 0px;
+}
+.nihilo .dojoxGrid-sort-up {
+	background: url(../compat/_grid/images/grid_sort_up.gif) right no-repeat;
+	padding-left: 0px;
+	margin-left: 0px;
+}
+.nihilo .gridArrowButtonChar {
+	display:none !important;
+}
+.dijit_a11y .gridArrowButtonChar {
+	display:inline !important;
+}
+.nihilo .dojoxGrid-scrollbox {
+	position: relative;
+	overflow: scroll;
+	background-color: #fefefe;
+	width: 100%;
+}
+.nihilo .dojoxGrid-content {
+	position: relative;
+	overflow: hidden;
+	 -moz-outline-style: none;
+	outline: none;
+}
+.nihilo .dojoxGrid-rowbar { 
+	border: none;
+	
+	background: url(../compat/_grid/images/titleBar.png) #e9e9e9 repeat-y right;
+	border-right: 1px solid #cccccc;
+	padding: 0px;
+}
+.nihilo .dojoxGrid-rowbar-inner {
+	border: none;
+	border-bottom: 1px solid #cccccc;
+}
+.nihilo .dojoxGrid-rowbar-over {
+	background: url(../compat/_grid/images/titleBarActive.png) #e9e9e9 repeat-y right;
+}
+.nihilo .dojoxGrid-rowbar-selected {
+	background-color: #D9E8F9;
+	background-image: none;
+	background: url(../compat/../../../dijit/themes/nihilo/images/titleBar.png) #dddddd repeat-x top;
+	border-right: 1px solid #cccccc;
+	background-position: center;
+	background-repeat: no-repeat;
+}
+.nihilo .dojoxGrid-row {
+	position: relative;
+	width: 9000em;
+}
+.nihilo .dojoxGrid-row {
+	border: none;
+	border-left: none;
+	border-right: none;
+	background-color: white;
+	border-top: none;
+}
+.nihilo .dojoxGrid-row-over {
+	border-top-color: #cccccc;
+	border-bottom-color: #cccccc;
+}
+.nihilo .dojoxGrid-row-over .dojoxGrid-cell {
+	background-color: #ffe284; 
+}
+.nihilo .dojoxGrid-row-odd {
+	background-color: #f2f5f9;
+	
+}
+.nihilo .dojoxGrid-row-selected {
+	background-color: #aec7e3;
+}
+.nihilo .dojoxGrid-row-table {
+	table-layout: fixed;
+	width: 0;
+	border-collapse: collapse;
+}
+.nihilo .dojoxGrid-invisible {
+	visibility: hidden;
+}		
+.nihilo .Xdojo-ie .dojoxGrid-invisible {
+	display: none;
+}		
+.nihilo .dojoxGrid-invisible td, .dojoxGrid-header .dojoxGrid-invisible td {
+	border-top-width: 0;
+	border-bottom-width: 0;
+	padding-top: 0;
+	padding-bottom: 0;
+	height: 0;
+	overflow: hidden;
+}
+.nihilo .dojoxGrid-cell {
+	border: 1px dotted #D5CDB5;
+	padding: 3px 3px 3px 3px;
+	text-align: left;
+	overflow: hidden;
+}
+.dj_ie6 .nihilo .dojoxGrid-cell {
+	border: 1px solid white;
+	border-right: 1px solid #D5CDB5;
+}
+.nihilo .dojoxGrid-cell-focus {
+	border: 1px dotted #a6a6a6;
+}
+.nihilo .dojoxGrid-cell-over {
+	border: 1px dotted #a6a6a6;
+}
+.nihilo .dojoxGrid-cell-focus.dojoxGrid-cell-over {
+	border: 1px dotted #595959;
+}
+.nihilo .dojoxGrid-cell-clip {
+	width: 100%;
+	overflow: hidden;
+	white-space:nowrap;
+	text-overflow: ellipsis;
+}
+.nihilo .dojoxGrid-row-editing td {
+	
+	background-color: #ffe284; 
+	
+}
+.nihilo .dojoxGrid-row-inserting td {
+	background-color: #F4FFF4;
+}
+.nihilo .dojoxGrid-row-inflight td {
+	background-color: #F2F7B7;
+}
+.nihilo .dojoxGrid-row-error td {
+	background-color: #F8B8B6;
+}
+.nihilo .dojoxGrid-input,
+.nihilo .dojoxGrid-select,
+.nihilo .dojoxGrid-textarea {
+	margin: 0;
+	padding: 0px;
+	border-style: none;
+	width: 100%;
+	font-size: 100%;
+	font-family: inherit;
+}
+.dojoxGrid-hidden-focus {
+	position: absolute;
+	left: -1000px;
+	top: -1000px;
+	height: 0px, width: 0px;
+}
+.dijit_a11y .dojoxGrid-rowbar-selected { 
+	border-top: 1px solid white;
+	border-bottom: 1px dashed black;
+	border-top: 0;
+	background: none;
+}
+.dijit_a11y .dojoxGrid-rowbar-selected .dojoxGrid-rowbar-inner {
+	border: 0;
+	border-top: 1px solid white;
+}
+.dijit_a11y .dojoxGrid-row-selected {
+	border-bottom: 1px dashed black;
+}
diff --git a/dojox/grid/_grid/soriaGrid.css b/dojox/grid/_grid/soriaGrid.css
new file mode 100644
index 0000000..89dc956
--- /dev/null
+++ b/dojox/grid/_grid/soriaGrid.css
@@ -0,0 +1,212 @@
+.soria .dojoxGrid {
+	position: relative;
+	background-color: #e9e9e9;
+	font-size: 0.85em; 
+	-moz-outline-style: none;
+	outline: none;
+	overflow: hidden;
+	height: 0;
+}
+.soria .dojoxGrid table {
+	padding: 0;
+}
+.soria .dojoxGrid td {
+	-moz-outline: none;
+}
+.soria .dojoxGrid-master-header {
+	position: relative;
+}
+.soria .dojoxGrid-master-view  {
+	position: relative;
+}
+.soria .dojoxGrid-view {
+	position: absolute;
+	overflow: hidden;
+}
+.soria .dojoxGrid-header {
+	position: absolute;
+	overflow: hidden;
+}
+.soria .dojoxGrid-header {
+	background-color:  #e9e9e9;
+}
+.soria .dojoxGrid-header table {
+	text-align: center;
+}
+.soria .dojoxGrid-header .dojoxGrid-cell-content {
+	text-align: center;
+}
+.soria .dojoxGrid-header .dojoxGrid-cell { 
+	border: 1px solid transparent;
+	
+	border-color: white #ACA899 #919191 white;
+	background: url(../compat/../../../dijit/themes/soria/images/titleBar.png) #e9e9e9 repeat-x top;
+	padding-bottom: 2px;
+	color: #000 !important;
+}
+.soria .dojoxGrid-header .dojoxGrid-cell-over {
+	background: url(../compat/../../../dijit/themes/soria/images/titleBarActive.png) #e9e9e9 repeat-x top;
+}
+.soria .dojoxGrid-sort-down {
+	background: url(../compat/_grid/images/grid_sort_down.gif) right no-repeat;
+	padding-left: 0px;
+	margin-left: 0px;
+}
+.soria .dojoxGrid-sort-up {
+	background: url(../compat/_grid/images/grid_sort_up.gif) right no-repeat;
+	padding-left: 0px;
+	margin-left: 0px;
+}
+.soria .gridArrowButtonChar {
+	display:none !important;
+}
+.dijit_a11y .gridArrowButtonChar {
+	display:inline !important;
+}
+.soria .dojoxGrid-scrollbox {
+	position: relative;
+	overflow: scroll;
+	background-color: #fefefe;
+	width: 100%;
+}
+.soria .dojoxGrid-content {
+	position: relative;
+	overflow: hidden;
+	 -moz-outline-style: none;
+	outline: none;
+}
+.soria .dojoxGrid-rowbar { 
+	border: none;
+	
+	background: url(../compat/_grid/images/titleBar.png) #e9e9e9 repeat-y right;
+	border-right: 1px solid #cccccc;
+	padding: 0px;
+}
+.soria .dojoxGrid-rowbar-inner {
+	border: none;
+	border-bottom: 1px solid #cccccc;
+}
+.soria .dojoxGrid-rowbar-over {
+	background: url(../compat/_grid/images/titleBarActive.png) #e9e9e9 repeat-y right;
+}
+.soria .dojoxGrid-rowbar-selected {
+	background-color: #D9E8F9;
+	background-image: none;
+	background: url(../compat/../../../dijit/themes/soria/images/titleBar.png) #dddddd repeat-x top;
+	border-right: 1px solid #cccccc;
+	background-position: center;
+	background-repeat: no-repeat;
+}
+.soria .dojoxGrid-row {
+	position: relative;
+	width: 9000em;
+}
+.soria .dojoxGrid-row {
+	border: none;
+	border-left: none;
+	border-right: none;
+	background-color: white;
+	border-top: none;
+}
+.soria .dojoxGrid-row-over {
+	border-top-color: #cccccc;
+	border-bottom-color: #cccccc;
+}
+.soria .dojoxGrid-row-over .dojoxGrid-cell {
+	background-color: #60a1ea; 
+	color:#fff;
+}
+.soria .dojoxGrid-row-odd {
+	background-color: #f2f5f9;
+	
+}
+.soria .dojoxGrid-row-selected {
+	background-color: #aec7e3;
+}
+.soria .dojoxGrid-row-table {
+	table-layout: fixed;
+	width: 0;
+	border-collapse: collapse;
+}
+.soria .dojoxGrid-invisible {
+	visibility: hidden;
+}		
+.soria .Xdojo-ie .dojoxGrid-invisible {
+	display: none;
+}		
+.soria .dojoxGrid-invisible td, .dojoxGrid-header .dojoxGrid-invisible td {
+	border-top-width: 0;
+	border-bottom-width: 0;
+	padding-top: 0;
+	padding-bottom: 0;
+	height: 0;
+	overflow: hidden;
+}
+.soria .dojoxGrid-cell {
+	border: 1px dotted #D5CDB5;
+	padding: 3px 3px 3px 3px;
+	text-align: left;
+	overflow: hidden;
+}
+.dj_ie6 .soria .dojoxGrid-cell {
+	border: 1px solid white;
+	border-right: 1px solid #D5CDB5;
+}
+.soria .dojoxGrid-cell-focus {
+	border: 1px dotted #a6a6a6;
+}
+.soria .dojoxGrid-cell-over {
+	border: 1px dotted #a6a6a6;
+}
+.soria .dojoxGrid-cell-focus.dojoxGrid-cell-over {
+	border: 1px dotted #595959;
+}
+.soria .dojoxGrid-cell-clip {
+	width: 100%;
+	overflow: hidden;
+	white-space:nowrap;
+	text-overflow: ellipsis;
+}
+.soria .dojoxGrid-row-editing td {
+	
+	background-color: #60a1ea; 
+	
+}
+.soria .dojoxGrid-row-inserting td {
+	background-color: #F4FFF4;
+}
+.soria .dojoxGrid-row-inflight td {
+	background-color: #F2F7B7;
+}
+.soria .dojoxGrid-row-error td {
+	background-color: #F8B8B6;
+}
+.soria .dojoxGrid-input,
+.soria .dojoxGrid-select,
+.soria .dojoxGrid-textarea {
+	margin: 0;
+	padding: 0px;
+	border-style: none;
+	width: 100%;
+	font-size: 100%;
+	font-family: inherit;
+}
+.dojoxGrid-hidden-focus {
+	position: absolute;
+	left: -1000px;
+	top: -1000px;
+	height: 0px, width: 0px;
+}
+.dijit_a11y .dojoxGrid-rowbar-selected { 
+	border-top: 1px solid white;
+	border-bottom: 1px dashed black;
+	border-top: 0;
+	background: none;
+}
+.dijit_a11y .dojoxGrid-rowbar-selected .dojoxGrid-rowbar-inner {
+	border: 0;
+	border-top: 1px solid white;
+}
+.dijit_a11y .dojoxGrid-row-selected {
+	border-bottom: 1px dashed black;
+}
diff --git a/dojox/grid/_grid/tundraGrid.css b/dojox/grid/_grid/tundraGrid.css
new file mode 100644
index 0000000..3bed74b
--- /dev/null
+++ b/dojox/grid/_grid/tundraGrid.css
@@ -0,0 +1,215 @@
+.tundra .dojoxGrid {
+	position: relative;
+	background-color: #e9e9e9;
+	font-size: 0.85em; 
+	-moz-outline-style: none;
+	outline: none;
+	overflow: hidden;
+	height: 0;
+}
+.tundra .dojoxGrid table {
+	padding: 0;
+}
+.tundra .dojoxGrid td {
+	-moz-outline: none;
+}
+.tundra .dojoxGrid-master-header {
+	position: relative;
+}
+.tundra .dojoxGrid-master-view  {
+	position: relative;
+}
+.tundra .dojoxGrid-view {
+	position: absolute;
+	overflow: hidden;
+}
+.tundra .dojoxGrid-header {
+	position: absolute;
+	overflow: hidden;
+}
+.tundra .dojoxGrid-header {
+	background-color:  #e9e9e9;
+}
+.tundra .dojoxGrid-header table {
+	text-align: center;
+}
+.tundra .dojoxGrid-header .dojoxGrid-cell-content {
+	text-align: center;
+}
+.tundra .dojoxGrid-header .dojoxGrid-cell { 
+	border: 1px solid transparent;
+	
+	border-color: white #ACA899 #919191 white;
+	background: url(../compat/../../../dijit/themes/tundra/images/tabEnabled.png) #e9e9e9 repeat-x top;
+	padding-bottom: 2px;
+	color: #000 !important;
+}
+.tundra .dojoxGrid-header .dojoxGrid-cell-over {
+	background: url(../compat/../../../dijit/themes/tundra/images/tabHover.png) #e9e9e9 repeat-x top;
+	color: #000 !important;
+}
+.tundra .dojoxGrid-sort-down {
+	background: url(../compat/../../../dijit/themes/tundra/images/smallArrowDown.png) right no-repeat;
+	padding-left: 0px;
+	margin-left: 0px;
+}
+.tundra .dojoxGrid-sort-up {
+	background: url(../compat/../../../dijit/themes/tundra/images/smallArrowUp.png) right no-repeat;
+	padding-left: 0px;
+	margin-left: 0px;
+}
+.tundra .gridArrowButtonChar {
+	display:none !important;
+}
+.dijit_a11y .gridArrowButtonChar {
+	display:inline !important;
+}
+.tundra .dojoxGrid-scrollbox {
+	position: relative;
+	overflow: scroll;
+	background-color: #fefefe;
+	width: 100%;
+}
+.tundra .dojoxGrid-content {
+	position: relative;
+	overflow: hidden;
+	 -moz-outline-style: none;
+	outline: none;
+}
+.tundra .dojoxGrid-rowbar { 
+	border: none;
+	
+	background: url(../compat/_grid/images/tabEnabled_rotated.png) #e9e9e9 repeat-y right;
+	border-right: 1px solid #cccccc;
+	padding: 0px;
+}
+.tundra .dojoxGrid-rowbar-inner {
+	border: none;
+	border-bottom: 1px solid #cccccc;
+}
+.tundra .dojoxGrid-rowbar-over {
+	background: url(../compat/_grid/images/tabHover_rotated.png) #e9e9e9 repeat-y right;
+}
+.tundra .dojoxGrid-rowbar-selected {
+	background-color: #D9E8F9;
+	background-image: none;
+	background: url(../compat/../../../dijit/themes/tundra/images/tabDisabled.png) #dddddd repeat-x top;
+	border-right: 1px solid #cccccc;
+	background-position: center;
+	background-repeat: no-repeat;
+}
+.tundra .dojoxGrid-row {
+	position: relative;
+	width: 9000em;
+}
+.tundra .dojoxGrid-row {
+	border: none;
+	border-left: none;
+	border-right: none;
+	background-color: white;
+	border-top: none;
+}
+.tundra .dojoxGrid-row-over {
+	border-top-color: #cccccc;
+	border-bottom-color: #cccccc;
+}
+.tundra .dojoxGrid-row-over .dojoxGrid-cell {
+	background-color: #60a1ea; 
+	color:#fff;
+	
+}
+.tundra .dojoxGrid-row-odd {
+	background-color: #f2f5f9;
+	
+}
+.tundra .dojoxGrid-row-selected {
+	background-color: #aec7e3;
+	
+}
+.tundra .dojoxGrid-row-table {
+	table-layout: fixed;
+	width: 0;
+	border-collapse: collapse;
+}
+.tundra .dojoxGrid-invisible {
+	visibility: hidden;
+}		
+.tundra .Xdojo-ie .dojoxGrid-invisible {
+	display: none;
+}		
+.tundra .dojoxGrid-invisible td, .dojoxGrid-header .dojoxGrid-invisible td {
+	border-top-width: 0;
+	border-bottom-width: 0;
+	padding-top: 0;
+	padding-bottom: 0;
+	height: 0;
+	overflow: hidden;
+}
+.tundra .dojoxGrid-cell {
+	border: 1px dotted #D5CDB5;
+	padding: 3px 3px 3px 3px;
+	text-align: left;
+	overflow: hidden;
+}
+.dj_ie6 .tundra .dojoxGrid-cell {
+	border: 1px solid white;
+	border-right: 1px solid #D5CDB5;
+}
+.tundra .dojoxGrid-cell-focus {
+	border: 1px dotted #a6a6a6;
+}
+.tundra .dojoxGrid-cell-over {
+	border: 1px dotted #a6a6a6;
+}
+.tundra .dojoxGrid-cell-focus.dojoxGrid-cell-over {
+	border: 1px dotted #595959;
+}
+.tundra .dojoxGrid-cell-clip {
+	width: 100%;
+	overflow: hidden;
+	white-space:nowrap;
+	text-overflow: ellipsis;
+}
+.tundra .dojoxGrid-row-editing td {
+	
+	background-color: #60a1ea; 
+	
+}
+.tundra .dojoxGrid-row-inserting td {
+	background-color: #F4FFF4;
+}
+.tundra .dojoxGrid-row-inflight td {
+	background-color: #F2F7B7;
+}
+.tundra .dojoxGrid-row-error td {
+	background-color: #F8B8B6;
+}
+.tundra .dojoxGrid-input,
+.tundra .dojoxGrid-select,
+.tundra .dojoxGrid-textarea {
+	margin: 0;
+	padding: 0px;
+	border-style: none;
+	width: 100%;
+	font-size: 100%;
+	font-family: inherit;
+}
+.dojoxGrid-hidden-focus {
+	position: absolute;
+	left: -1000px;
+	top: -1000px;
+	height: 0px, width: 0px;
+}
+.dijit_a11y .dojoxGrid-rowbar-selected { 
+	border-top: 1px solid white;
+	border-bottom: 1px dashed black;
+	border-top: 0;
+	background: none;
+}
+.dijit_a11y .dojoxGrid-rowbar-selected .dojoxGrid-rowbar-inner {
+	border: 0;
+	border-top: 1px solid white;
+}
+.dijit_a11y .dojoxGrid-row-selected {
+	border-bottom: 1px dashed black;
+}
diff --git a/dojox/grid/cells.js b/dojox/grid/cells.js
new file mode 100644
index 0000000..42a7cee
--- /dev/null
+++ b/dojox/grid/cells.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.cells"]){
+dojo._hasResource["dojox.grid.cells"]=true;
+dojo.provide("dojox.grid.cells");
+dojo.require("dojox.grid.cells._base");
+}
diff --git a/dojox/grid/cells/_base.js b/dojox/grid/cells/_base.js
new file mode 100644
index 0000000..558390d
--- /dev/null
+++ b/dojox/grid/cells/_base.js
@@ -0,0 +1,236 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.cells._base"]){
+dojo._hasResource["dojox.grid.cells._base"]=true;
+dojo.provide("dojox.grid.cells._base");
+dojo.require("dojox.grid.util");
+(function(){
+var _1=function(_2){
+try{
+dojox.grid.util.fire(_2,"focus");
+dojox.grid.util.fire(_2,"select");
+}
+catch(e){
+}
+};
+var _3=function(){
+setTimeout(dojo.hitch.apply(dojo,arguments),0);
+};
+var _4=dojox.grid.cells;
+dojo.declare("dojox.grid.cells._Base",null,{styles:"",classes:"",editable:false,alwaysEditing:false,formatter:null,defaultValue:"...",value:null,hidden:false,noresize:false,_valueProp:"value",_formatPending:false,constructor:function(_5){
+this._props=_5||{};
+dojo.mixin(this,_5);
+},format:function(_6,_7){
+var f,i=this.grid.edit.info,d=this.get?this.get(_6,_7):(this.value||this.defaultValue);
+d=(d&&d.replace)?d.replace(/</g,"<"):d;
+if(this.editable&&(this.alwaysEditing||(i.rowIndex==_6&&i.cell==this))){
+return this.formatEditing(d,_6);
+}else{
+var v=(d!=this.defaultValue&&(f=this.formatter))?f.call(this,d,_6):d;
+return (typeof v=="undefined"?this.defaultValue:v);
+}
+},formatEditing:function(_c,_d){
+},getNode:function(_e){
+return this.view.getCellNode(_e,this.index);
+},getHeaderNode:function(){
+return this.view.getHeaderCellNode(this.index);
+},getEditNode:function(_f){
+return (this.getNode(_f)||0).firstChild||0;
+},canResize:function(){
+var uw=this.unitWidth;
+return uw&&(uw!=="auto");
+},isFlex:function(){
+var uw=this.unitWidth;
+return uw&&dojo.isString(uw)&&(uw=="auto"||uw.slice(-1)=="%");
+},applyEdit:function(_12,_13){
+this.grid.edit.applyCellEdit(_12,this,_13);
+},cancelEdit:function(_14){
+this.grid.doCancelEdit(_14);
+},_onEditBlur:function(_15){
+if(this.grid.edit.isEditCell(_15,this.index)){
+this.grid.edit.apply();
+}
+},registerOnBlur:function(_16,_17){
+if(this.commitOnBlur){
+dojo.connect(_16,"onblur",function(e){
+setTimeout(dojo.hitch(this,"_onEditBlur",_17),250);
+});
+}
+},needFormatNode:function(_19,_1a){
+this._formatPending=true;
+_3(this,"_formatNode",_19,_1a);
+},cancelFormatNode:function(){
+this._formatPending=false;
+},_formatNode:function(_1b,_1c){
+if(this._formatPending){
+this._formatPending=false;
+dojo.setSelectable(this.grid.domNode,true);
+this.formatNode(this.getEditNode(_1c),_1b,_1c);
+}
+},formatNode:function(_1d,_1e,_1f){
+if(dojo.isIE){
+_3(this,"focus",_1f,_1d);
+}else{
+this.focus(_1f,_1d);
+}
+},dispatchEvent:function(m,e){
+if(m in this){
+return this[m](e);
+}
+},getValue:function(_22){
+return this.getEditNode(_22)[this._valueProp];
+},setValue:function(_23,_24){
+var n=this.getEditNode(_23);
+if(n){
+n[this._valueProp]=_24;
+}
+},focus:function(_26,_27){
+_1(_27||this.getEditNode(_26));
+},save:function(_28){
+this.value=this.value||this.getValue(_28);
+},restore:function(_29){
+this.setValue(_29,this.value);
+},_finish:function(_2a){
+dojo.setSelectable(this.grid.domNode,false);
+this.cancelFormatNode();
+},apply:function(_2b){
+this.applyEdit(this.getValue(_2b),_2b);
+this._finish(_2b);
+},cancel:function(_2c){
+this.cancelEdit(_2c);
+this._finish(_2c);
+}});
+_4._Base.markupFactory=function(_2d,_2e){
+var d=dojo;
+var _30=d.trim(d.attr(_2d,"formatter")||"");
+if(_30){
+_2e.formatter=dojo.getObject(_30);
+}
+var get=d.trim(d.attr(_2d,"get")||"");
+if(get){
+_2e.get=dojo.getObject(get);
+}
+var _32=function(_33){
+var _34=d.trim(d.attr(_2d,_33)||"");
+return _34?!(_34.toLowerCase()=="false"):undefined;
+};
+_2e.sortDesc=_32("sortDesc");
+_2e.editable=_32("editable");
+_2e.alwaysEditing=_32("alwaysEditing");
+_2e.noresize=_32("noresize");
+var _35=d.trim(d.attr(_2d,"loadingText")||d.attr(_2d,"defaultValue")||"");
+if(_35){
+_2e.defaultValue=_35;
+}
+var _36=function(_37){
+return d.trim(d.attr(_2d,_37)||"")||undefined;
+};
+_2e.styles=_36("styles");
+_2e.headerStyles=_36("headerStyles");
+_2e.cellStyles=_36("cellStyles");
+_2e.classes=_36("classes");
+_2e.headerClasses=_36("headerClasses");
+_2e.cellClasses=_36("cellClasses");
+};
+dojo.declare("dojox.grid.cells.Cell",_4._Base,{constructor:function(){
+this.keyFilter=this.keyFilter;
+},keyFilter:null,formatEditing:function(_38,_39){
+this.needFormatNode(_38,_39);
+return "<input class=\"dojoxGridInput\" type=\"text\" value=\""+_38+"\">";
+},formatNode:function(_3a,_3b,_3c){
+this.inherited(arguments);
+this.registerOnBlur(_3a,_3c);
+},doKey:function(e){
+if(this.keyFilter){
+var key=String.fromCharCode(e.charCode);
+if(key.search(this.keyFilter)==-1){
+dojo.stopEvent(e);
+}
+}
+},_finish:function(_3f){
+this.inherited(arguments);
+var n=this.getEditNode(_3f);
+try{
+dojox.grid.util.fire(n,"blur");
+}
+catch(e){
+}
+}});
+_4.Cell.markupFactory=function(_41,_42){
+_4._Base.markupFactory(_41,_42);
+var d=dojo;
+var _44=d.trim(d.attr(_41,"keyFilter")||"");
+if(_44){
+_42.keyFilter=new RegExp(_44);
+}
+};
+dojo.declare("dojox.grid.cells.RowIndex",_4.Cell,{name:"Row",postscript:function(){
+this.editable=false;
+},get:function(_45){
+return _45+1;
+}});
+_4.RowIndex.markupFactory=function(_46,_47){
+_4.Cell.markupFactory(_46,_47);
+};
+dojo.declare("dojox.grid.cells.Select",_4.Cell,{options:null,values:null,returnIndex:-1,constructor:function(_48){
+this.values=this.values||this.options;
+},formatEditing:function(_49,_4a){
+this.needFormatNode(_49,_4a);
+var h=["<select class=\"dojoxGridSelect\">"];
+for(var i=0,o,v;((o=this.options[i])!==undefined)&&((v=this.values[i])!==undefined);i++){
+h.push("<option",(_49==v?" selected":"")," value=\""+v+"\"",">",o,"</option>");
+}
+h.push("</select>");
+return h.join("");
+},getValue:function(_4f){
+var n=this.getEditNode(_4f);
+if(n){
+var i=n.selectedIndex,o=n.options[i];
+return this.returnIndex>-1?i:o.value||o.innerHTML;
+}
+}});
+_4.Select.markupFactory=function(_53,_54){
+_4.Cell.markupFactory(_53,_54);
+var d=dojo;
+var _56=d.trim(d.attr(_53,"options")||"");
+if(_56){
+var o=_56.split(",");
+if(o[0]!=_56){
+_54.options=o;
+}
+}
+var _58=d.trim(d.attr(_53,"values")||"");
+if(_58){
+var v=_58.split(",");
+if(v[0]!=_58){
+_54.values=v;
+}
+}
+};
+dojo.declare("dojox.grid.cells.AlwaysEdit",_4.Cell,{alwaysEditing:true,_formatNode:function(_5a,_5b){
+this.formatNode(this.getEditNode(_5b),_5a,_5b);
+},applyStaticValue:function(_5c){
+var e=this.grid.edit;
+e.applyCellEdit(this.getValue(_5c),this,_5c);
+e.start(this,_5c,true);
+}});
+_4.AlwaysEdit.markupFactory=function(_5e,_5f){
+_4.Cell.markupFactory(_5e,_5f);
+};
+dojo.declare("dojox.grid.cells.Bool",_4.AlwaysEdit,{_valueProp:"checked",formatEditing:function(_60,_61){
+return "<input class=\"dojoxGridInput\" type=\"checkbox\""+(_60?" checked=\"checked\"":"")+" style=\"width: auto\" />";
+},doclick:function(e){
+if(e.target.tagName=="INPUT"){
+this.applyStaticValue(e.rowIndex);
+}
+}});
+_4.Bool.markupFactory=function(_63,_64){
+_4.AlwaysEdit.markupFactory(_63,_64);
+};
+})();
+}
diff --git a/dojox/grid/cells/dijit.js b/dojox/grid/cells/dijit.js
new file mode 100644
index 0000000..442b294
--- /dev/null
+++ b/dojox/grid/cells/dijit.js
@@ -0,0 +1,178 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.cells.dijit"]){
+dojo._hasResource["dojox.grid.cells.dijit"]=true;
+dojo.provide("dojox.grid.cells.dijit");
+dojo.require("dojox.grid.cells");
+dojo.require("dijit.form.DateTextBox");
+dojo.require("dijit.form.TimeTextBox");
+dojo.require("dijit.form.ComboBox");
+dojo.require("dojo.data.ItemFileReadStore");
+dojo.require("dijit.form.CheckBox");
+dojo.require("dijit.form.TextBox");
+dojo.require("dijit.form.NumberSpinner");
+dojo.require("dijit.form.NumberTextBox");
+dojo.require("dijit.form.CurrencyTextBox");
+dojo.require("dijit.form.HorizontalSlider");
+dojo.require("dijit.Editor");
+(function(){
+var _1=dojox.grid.cells;
+dojo.declare("dojox.grid.cells._Widget",_1._Base,{widgetClass:dijit.form.TextBox,constructor:function(_2){
+this.widget=null;
+if(typeof this.widgetClass=="string"){
+dojo.deprecated("Passing a string to widgetClass is deprecated","pass the widget class object instead","2.0");
+this.widgetClass=dojo.getObject(this.widgetClass);
+}
+},formatEditing:function(_3,_4){
+this.needFormatNode(_3,_4);
+return "<div></div>";
+},getValue:function(_5){
+return this.widget.attr("value");
+},setValue:function(_6,_7){
+if(this.widget&&this.widget.attr){
+if(this.widget.onLoadDeferred){
+var _8=this;
+this.widget.onLoadDeferred.addCallback(function(){
+_8.widget.attr("value",_7==null?"":_7);
+});
+}else{
+this.widget.attr("value",_7);
+}
+}else{
+this.inherited(arguments);
+}
+},getWidgetProps:function(_9){
+return dojo.mixin({},this.widgetProps||{},{constraints:dojo.mixin({},this.constraint)||{},value:_9});
+},createWidget:function(_a,_b,_c){
+return new this.widgetClass(this.getWidgetProps(_b),_a);
+},attachWidget:function(_d,_e,_f){
+_d.appendChild(this.widget.domNode);
+this.setValue(_f,_e);
+},formatNode:function(_10,_11,_12){
+if(!this.widgetClass){
+return _11;
+}
+if(!this.widget){
+this.widget=this.createWidget.apply(this,arguments);
+}else{
+this.attachWidget.apply(this,arguments);
+}
+this.sizeWidget.apply(this,arguments);
+this.grid.rowHeightChanged(_12);
+this.focus();
+},sizeWidget:function(_13,_14,_15){
+var p=this.getNode(_15),box=dojo.contentBox(p);
+dojo.marginBox(this.widget.domNode,{w:box.w});
+},focus:function(_18,_19){
+if(this.widget){
+setTimeout(dojo.hitch(this.widget,function(){
+dojox.grid.util.fire(this,"focus");
+}),0);
+}
+},_finish:function(_1a){
+this.inherited(arguments);
+dojox.grid.util.removeNode(this.widget.domNode);
+}});
+_1._Widget.markupFactory=function(_1b,_1c){
+_1._Base.markupFactory(_1b,_1c);
+var d=dojo;
+var _1e=d.trim(d.attr(_1b,"widgetProps")||"");
+var _1f=d.trim(d.attr(_1b,"constraint")||"");
+var _20=d.trim(d.attr(_1b,"widgetClass")||"");
+if(_1e){
+_1c.widgetProps=d.fromJson(_1e);
+}
+if(_1f){
+_1c.constraint=d.fromJson(_1f);
+}
+if(_20){
+_1c.widgetClass=d.getObject(_20);
+}
+};
+dojo.declare("dojox.grid.cells.ComboBox",_1._Widget,{widgetClass:dijit.form.ComboBox,getWidgetProps:function(_21){
+var _22=[];
+dojo.forEach(this.options,function(o){
+_22.push({name:o,value:o});
+});
+var _24=new dojo.data.ItemFileReadStore({data:{identifier:"name",items:_22}});
+return dojo.mixin({},this.widgetProps||{},{value:_21,store:_24});
+},getValue:function(){
+var e=this.widget;
+e.attr("displayedValue",e.attr("displayedValue"));
+return e.attr("value");
+}});
+_1.ComboBox.markupFactory=function(_26,_27){
+_1._Widget.markupFactory(_26,_27);
+var d=dojo;
+var _29=d.trim(d.attr(_26,"options")||"");
+if(_29){
+var o=_29.split(",");
+if(o[0]!=_29){
+_27.options=o;
+}
+}
+};
+dojo.declare("dojox.grid.cells.DateTextBox",_1._Widget,{widgetClass:dijit.form.DateTextBox,setValue:function(_2b,_2c){
+if(this.widget){
+this.widget.attr("value",new Date(_2c));
+}else{
+this.inherited(arguments);
+}
+},getWidgetProps:function(_2d){
+return dojo.mixin(this.inherited(arguments),{value:new Date(_2d)});
+}});
+_1.DateTextBox.markupFactory=function(_2e,_2f){
+_1._Widget.markupFactory(_2e,_2f);
+};
+dojo.declare("dojox.grid.cells.CheckBox",_1._Widget,{widgetClass:dijit.form.CheckBox,getValue:function(){
+return this.widget.checked;
+},setValue:function(_30,_31){
+if(this.widget&&this.widget.attributeMap.checked){
+this.widget.attr("checked",_31);
+}else{
+this.inherited(arguments);
+}
+},sizeWidget:function(_32,_33,_34){
+return;
+}});
+_1.CheckBox.markupFactory=function(_35,_36){
+_1._Widget.markupFactory(_35,_36);
+};
+dojo.declare("dojox.grid.cells.Editor",_1._Widget,{widgetClass:dijit.Editor,getWidgetProps:function(_37){
+return dojo.mixin({},this.widgetProps||{},{height:this.widgetHeight||"100px"});
+},createWidget:function(_38,_39,_3a){
+var _3b=new this.widgetClass(this.getWidgetProps(_39),_38);
+dojo.connect(_3b,"onLoad",dojo.hitch(this,"populateEditor"));
+return _3b;
+},formatNode:function(_3c,_3d,_3e){
+this.content=_3d;
+this.inherited(arguments);
+if(dojo.isMoz){
+var e=this.widget;
+e.open();
+if(this.widgetToolbar){
+dojo.place(e.toolbar.domNode,e.editingArea,"before");
+}
+}
+},populateEditor:function(){
+this.widget.attr("value",this.content);
+this.widget.placeCursorAtEnd();
+}});
+_1.Editor.markupFactory=function(_40,_41){
+_1._Widget.markupFactory(_40,_41);
+var d=dojo;
+var h=dojo.trim(dojo.attr(_40,"widgetHeight")||"");
+if(h){
+if((h!="auto")&&(h.substr(-2)!="em")){
+h=parseInt(h)+"px";
+}
+_41.widgetHeight=h;
+}
+};
+})();
+}
diff --git a/dojox/grid/compat/Grid.js b/dojox/grid/compat/Grid.js
new file mode 100644
index 0000000..575fcd6
--- /dev/null
+++ b/dojox/grid/compat/Grid.js
@@ -0,0 +1,197 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat.Grid"]){
+dojo._hasResource["dojox.grid.compat.Grid"]=true;
+dojo.provide("dojox.grid.compat.Grid");
+dojo.require("dojox.grid.compat.VirtualGrid");
+dojo.require("dojox.grid.compat._data.model");
+dojo.require("dojox.grid.compat._data.editors");
+dojo.require("dojox.grid.compat._data.dijitEditors");
+dojo.declare("dojox.Grid",dojox.VirtualGrid,{model:"dojox.grid.data.Table",postCreate:function(){
+if(this.model){
+var m=this.model;
+if(dojo.isString(m)){
+m=dojo.getObject(m);
+}
+this.model=(dojo.isFunction(m))?new m():m;
+this._setModel(this.model);
+}
+this.inherited(arguments);
+},destroy:function(){
+this.setModel(null);
+this.inherited(arguments);
+},_structureChanged:function(){
+this.indexCellFields();
+this.inherited(arguments);
+},_setModel:function(_2){
+this.model=_2;
+if(this.model){
+this.model.observer(this);
+this.model.measure();
+this.indexCellFields();
+}
+},setModel:function(_3){
+if(this.model){
+this.model.notObserver(this);
+}
+this._setModel(_3);
+},get:function(_4){
+return this.grid.model.getDatum(_4,this.fieldIndex);
+},modelAllChange:function(){
+this.rowCount=(this.model?this.model.getRowCount():0);
+this.updateRowCount(this.rowCount);
+},modelBeginUpdate:function(){
+this.beginUpdate();
+},modelEndUpdate:function(){
+this.endUpdate();
+},modelRowChange:function(_5,_6){
+this.updateRow(_6);
+},modelDatumChange:function(_7,_8,_9){
+this.updateRow(_8);
+},modelFieldsChange:function(){
+this.indexCellFields();
+this.render();
+},modelInsertion:function(_a){
+this.updateRowCount(this.model.getRowCount());
+},modelRemoval:function(_b){
+this.updateRowCount(this.model.getRowCount());
+},getCellName:function(_c){
+var v=this.model.fields.values,i=_c.fieldIndex;
+return i>=0&&i<v.length&&v[i].name||this.inherited(arguments);
+},indexCellFields:function(){
+var _f=this.layout.cells;
+for(var i=0,c;_f&&(c=_f[i]);i++){
+if(dojo.isString(c.field)){
+c.fieldIndex=this.model.fields.indexOf(c.field);
+}
+}
+},refresh:function(){
+this.edit.cancel();
+this.model.measure();
+},canSort:function(_12){
+var f=this.getSortField(_12);
+return f&&this.model.canSort(f);
+},getSortField:function(_14){
+var c=this.getCell(this.getSortIndex(_14));
+return (c.fieldIndex+1)*(this.sortInfo>0?1:-1);
+},sort:function(){
+this.edit.apply();
+this.model.sort(this.getSortField());
+},addRow:function(_16,_17){
+this.edit.apply();
+var i=_17||-1;
+if(i<0){
+i=this.selection.getFirstSelected()||0;
+}
+if(i<0){
+i=0;
+}
+this.model.insert(_16,i);
+this.model.beginModifyRow(i);
+for(var j=0,c;((c=this.getCell(j))&&!c.editor);j++){
+}
+if(c&&c.editor){
+this.edit.setEditCell(c,i);
+this.focus.setFocusCell(c,i);
+}else{
+this.focus.setFocusCell(this.getCell(0),i);
+}
+},removeSelectedRows:function(){
+this.edit.apply();
+var s=this.selection.getSelected();
+if(s.length){
+this.model.remove(s);
+this.selection.clear();
+}
+},canEdit:function(_1c,_1d){
+return (this.model.canModify?this.model.canModify(_1d):true);
+},doStartEdit:function(_1e,_1f){
+this.model.beginModifyRow(_1f);
+this.onStartEdit(_1e,_1f);
+},doApplyCellEdit:function(_20,_21,_22){
+this.model.setDatum(_20,_21,_22);
+this.onApplyCellEdit(_20,_21,_22);
+},doCancelEdit:function(_23){
+this.model.cancelModifyRow(_23);
+this.onCancelEdit.apply(this,arguments);
+},doApplyEdit:function(_24){
+this.model.endModifyRow(_24);
+this.onApplyEdit(_24);
+},styleRowState:function(_25){
+if(this.model.getState){
+var _26=this.model.getState(_25.index),c="";
+for(var i=0,ss=["inflight","error","inserting"],s;s=ss[i];i++){
+if(_26[s]){
+c=" dojoxGrid-row-"+s;
+break;
+}
+}
+_25.customClasses+=c;
+}
+},onStyleRow:function(_2b){
+this.styleRowState(_2b);
+this.inherited(arguments);
+}});
+dojox.Grid.markupFactory=function(_2c,_2d,_2e){
+var d=dojo;
+var _30=function(n){
+var w=d.attr(n,"width")||"auto";
+if((w!="auto")&&(w.substr(-2)!="em")){
+w=parseInt(w)+"px";
+}
+return w;
+};
+if(!_2c.model&&d.hasAttr(_2d,"store")){
+var _33=_2d.cloneNode(false);
+d.attr(_33,{"jsId":null,"dojoType":d.attr(_2d,"dataModelClass")||"dojox.grid.data.DojoData"});
+_2c.model=d.parser.instantiate([_33])[0];
+}
+if(!_2c.structure&&_2d.nodeName.toLowerCase()=="table"){
+_2c.structure=d.query("> colgroup",_2d).map(function(cg){
+var sv=d.attr(cg,"span");
+var v={noscroll:(d.attr(cg,"noscroll")=="true")?true:false,__span:(!!sv?parseInt(sv):1),cells:[]};
+if(d.hasAttr(cg,"width")){
+v.width=_30(cg);
+}
+return v;
+});
+if(!_2c.structure.length){
+_2c.structure.push({__span:Infinity,cells:[]});
+}
+d.query("thead > tr",_2d).forEach(function(tr,_38){
+var _39=0;
+var _3a=0;
+var _3b;
+var _3c=null;
+d.query("> th",tr).map(function(th){
+if(!_3c){
+_3b=0;
+_3c=_2c.structure[0];
+}else{
+if(_39>=(_3b+_3c.__span)){
+_3a++;
+_3b+=_3c.__span;
+var _3e=_3c;
+_3c=_2c.structure[_3a];
+}
+}
+var _3f={name:d.trim(d.attr(th,"name")||th.innerHTML),field:d.trim(d.attr(th,"field")||""),colSpan:parseInt(d.attr(th,"colspan")||1)};
+_39+=_3f.colSpan;
+_3f.field=_3f.field||_3f.name;
+_3f.width=_30(th);
+if(!_3c.cells[_38]){
+_3c.cells[_38]=[];
+}
+_3c.cells[_38].push(_3f);
+});
+});
+}
+return new dojox.Grid(_2c,_2d);
+};
+dojox.grid.Grid=dojox.Grid;
+}
diff --git a/dojox/grid/compat/README b/dojox/grid/compat/README
new file mode 100644
index 0000000..f9dade3
--- /dev/null
+++ b/dojox/grid/compat/README
@@ -0,0 +1,39 @@
+-------------------------------------------------------------------------------
+dojox.grid
+-------------------------------------------------------------------------------
+Version 1.00
+Release date: 10/04/2007
+-------------------------------------------------------------------------------
+Project state:
+beta
+-------------------------------------------------------------------------------
+Credits
+	Scott J. Miles (sjmiles at activegrid.com)
+	Steve Orvell (sorvell at activegrid.com)
+-------------------------------------------------------------------------------
+Project description
+
+TurboGrid has been made available in Dojo and is now the dojox.grid!
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo Core
+Dijit Templated Widget
+-------------------------------------------------------------------------------
+Documentation
+
+None available for this version yet.
+
+See http://www.turboajax.com/products/turbogrid/ for legacy documentation.
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/grid/*
+
+Install into the following directory structure:
+/dojox/grid/
+
+...which should be at the same level as your Dojo checkout.
+-------------------------------------------------------------------------------
diff --git a/dojox/grid/compat/VirtualGrid.js b/dojox/grid/compat/VirtualGrid.js
new file mode 100644
index 0000000..47daf47
--- /dev/null
+++ b/dojox/grid/compat/VirtualGrid.js
@@ -0,0 +1,408 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat.VirtualGrid"]){
+dojo._hasResource["dojox.grid.compat.VirtualGrid"]=true;
+dojo.provide("dojox.grid.compat.VirtualGrid");
+dojo.require("dojox.grid.compat._grid.lib");
+dojo.require("dojox.grid.compat._grid.scroller");
+dojo.require("dojox.grid.compat._grid.view");
+dojo.require("dojox.grid.compat._grid.views");
+dojo.require("dojox.grid.compat._grid.layout");
+dojo.require("dojox.grid.compat._grid.rows");
+dojo.require("dojox.grid.compat._grid.focus");
+dojo.require("dojox.grid.compat._grid.selection");
+dojo.require("dojox.grid.compat._grid.edit");
+dojo.require("dojox.grid.compat._grid.rowbar");
+dojo.require("dojox.grid.compat._grid.publicEvents");
+dojo.declare("dojox.VirtualGrid",[dijit._Widget,dijit._Templated],{templateString:"<div class=\"dojoxGrid\" hidefocus=\"hidefocus\" role=\"wairole:grid\">\n\t<div class=\"dojoxGrid-master-header\" dojoAttachPoint=\"viewsHeaderNode\"></div>\n\t<div class=\"dojoxGrid-master-view\" dojoAttachPoint=\"viewsNode\"></div>\n\t<span dojoAttachPoint=\"lastFocusNode\" tabindex=\"0\"></span>\n</div>\n",classTag:"dojoxGrid",get:function(_1){
+},rowCount:5,keepRows:75,rowsPerPage:25,autoWidth:false,autoHeight:false,autoRender:true,defaultHeight:"15em",structure:"",elasticView:-1,singleClickEdit:false,_click:null,sortInfo:0,themeable:true,buildRendering:function(){
+this.inherited(arguments);
+if(this.get==dojox.VirtualGrid.prototype.get){
+this.get=null;
+}
+if(!this.domNode.getAttribute("tabIndex")){
+this.domNode.tabIndex="0";
+}
+this.createScroller();
+this.createLayout();
+this.createViews();
+this.createManagers();
+dojox.grid.initTextSizePoll();
+this.connect(dojox.grid,"textSizeChanged","textSizeChanged");
+dojox.grid.funnelEvents(this.domNode,this,"doKeyEvent",dojox.grid.keyEvents);
+this.connect(this,"onShow","renderOnIdle");
+},postCreate:function(){
+this.styleChanged=this._styleChanged;
+this.setStructure(this.structure);
+this._click=[];
+},destroy:function(){
+this.domNode.onReveal=null;
+this.domNode.onSizeChange=null;
+this.edit.destroy();
+this.views.destroyViews();
+this.inherited(arguments);
+},styleChanged:function(){
+this.setStyledClass(this.domNode,"");
+},_styleChanged:function(){
+this.styleChanged();
+this.update();
+},textSizeChanged:function(){
+setTimeout(dojo.hitch(this,"_textSizeChanged"),1);
+},_textSizeChanged:function(){
+if(this.domNode){
+this.views.forEach(function(v){
+v.content.update();
+});
+this.render();
+}
+},sizeChange:function(){
+dojox.grid.jobs.job(this.id+"SizeChange",50,dojo.hitch(this,"update"));
+},renderOnIdle:function(){
+setTimeout(dojo.hitch(this,"render"),1);
+},createManagers:function(){
+this.rows=new dojox.grid.rows(this);
+this.focus=new dojox.grid.focus(this);
+this.selection=new dojox.grid.selection(this);
+this.edit=new dojox.grid.edit(this);
+},createScroller:function(){
+this.scroller=new dojox.grid.scroller.columns();
+this.scroller._pageIdPrefix=this.id+"-";
+this.scroller.renderRow=dojo.hitch(this,"renderRow");
+this.scroller.removeRow=dojo.hitch(this,"rowRemoved");
+},createLayout:function(){
+this.layout=new dojox.grid.layout(this);
+},createViews:function(){
+this.views=new dojox.grid.views(this);
+this.views.createView=dojo.hitch(this,"createView");
+},createView:function(_3){
+if(dojo.isAIR){
+var _4=window;
+var _5=_3.split(".");
+for(var i=0;i<_5.length;i++){
+if(typeof _4[_5[i]]=="undefined"){
+var _7=_5[0];
+for(var j=1;j<=i;j++){
+_7+="."+_5[j];
+}
+throw new Error(_7+" is undefined");
+}
+_4=_4[_5[i]];
+}
+var c=_4;
+}else{
+var c=eval(_3);
+}
+var _a=new c({grid:this});
+this.viewsNode.appendChild(_a.domNode);
+this.viewsHeaderNode.appendChild(_a.headerNode);
+this.views.addView(_a);
+return _a;
+},buildViews:function(){
+for(var i=0,vs;(vs=this.layout.structure[i]);i++){
+this.createView(vs.type||dojox._scopeName+".GridView").setStructure(vs);
+}
+this.scroller.setContentNodes(this.views.getContentNodes());
+},setStructure:function(_d){
+this.views.destroyViews();
+this.structure=_d;
+if((this.structure)&&(dojo.isString(this.structure))){
+this.structure=dojox.grid.getProp(this.structure);
+}
+if(!this.structure){
+this.structure=window["layout"];
+}
+if(!this.structure){
+return;
+}
+this.layout.setStructure(this.structure);
+this._structureChanged();
+},_structureChanged:function(){
+this.buildViews();
+if(this.autoRender){
+this.render();
+}
+},hasLayout:function(){
+return this.layout.cells.length;
+},resize:function(_e){
+this._sizeBox=_e;
+this._resize();
+this.sizeChange();
+},_getPadBorder:function(){
+this._padBorder=this._padBorder||dojo._getPadBorderExtents(this.domNode);
+return this._padBorder;
+},_resize:function(){
+if(!this.domNode.parentNode||this.domNode.parentNode.nodeType!=1||!this.hasLayout()){
+return;
+}
+var _f=this._getPadBorder();
+if(this.autoHeight){
+this.domNode.style.height="auto";
+this.viewsNode.style.height="";
+}else{
+if(this.flex>0){
+}else{
+if(this.domNode.clientHeight<=_f.h){
+if(this.domNode.parentNode==document.body){
+this.domNode.style.height=this.defaultHeight;
+}else{
+this.fitTo="parent";
+}
+}
+}
+}
+if(this._sizeBox){
+dojo.contentBox(this.domNode,this._sizeBox);
+}else{
+if(this.fitTo=="parent"){
+var h=dojo._getContentBox(this.domNode.parentNode).h;
+dojo.marginBox(this.domNode,{h:Math.max(0,h)});
+}
+}
+var h=dojo._getContentBox(this.domNode).h;
+if(h==0&&!this.autoHeight){
+this.viewsHeaderNode.style.display="none";
+}else{
+this.viewsHeaderNode.style.display="block";
+}
+this.adaptWidth();
+this.adaptHeight();
+this.scroller.defaultRowHeight=this.rows.getDefaultHeightPx()+1;
+this.postresize();
+},adaptWidth:function(){
+var w=this.autoWidth?0:this.domNode.clientWidth||(this.domNode.offsetWidth-this._getPadBorder().w);
+var vw=this.views.arrange(1,w);
+this.views.onEach("adaptWidth");
+if(this.autoWidth){
+this.domNode.style.width=vw+"px";
+}
+},adaptHeight:function(){
+var vns=this.viewsHeaderNode.style,t=vns.display=="none"?0:this.views.measureHeader();
+vns.height=t+"px";
+this.views.normalizeHeaderNodeHeight();
+var h=(this.autoHeight?-1:Math.max(this.domNode.clientHeight-t,0)||0);
+this.views.onEach("setSize",[0,h]);
+this.views.onEach("adaptHeight");
+this.scroller.windowHeight=h;
+},render:function(){
+if(!this.domNode){
+return;
+}
+if(!this.hasLayout()){
+this.scroller.init(0,this.keepRows,this.rowsPerPage);
+return;
+}
+this.update=this.defaultUpdate;
+this.scroller.init(this.rowCount,this.keepRows,this.rowsPerPage);
+this.prerender();
+this.setScrollTop(0);
+this.postrender();
+},prerender:function(){
+this.keepRows=this.autoHeight?0:this.constructor.prototype.keepRows;
+this.scroller.setKeepInfo(this.keepRows);
+this.views.render();
+this._resize();
+},postrender:function(){
+this.postresize();
+this.focus.initFocusView();
+dojo.setSelectable(this.domNode,false);
+},postresize:function(){
+if(this.autoHeight){
+this.viewsNode.style.height=this.views.measureContent()+"px";
+}
+},renderRow:function(_16,_17){
+this.views.renderRow(_16,_17);
+},rowRemoved:function(_18){
+this.views.rowRemoved(_18);
+},invalidated:null,updating:false,beginUpdate:function(){
+if(this.invalidated==null){
+this.invalidated={rows:[],count:1,all:false,rowCount:undefined};
+}else{
+this.invalidated.count++;
+}
+this.updating=true;
+},endUpdate:function(){
+var i=this.invalidated;
+if(--i.count===0){
+this.updating=false;
+if(i.rows.length>0){
+for(var r in i.rows){
+this.updateRow(Number(r));
+}
+this.invalidated.rows=[];
+}
+if(i.rowCount!=undefined){
+this.updateRowCount(i.rowCount);
+i.rowCount=undefined;
+}
+if(i.all){
+this.update();
+i.all=false;
+}
+}
+},defaultUpdate:function(){
+if(!this.domNode){
+return;
+}
+if(this.updating){
+this.invalidated.all=true;
+return;
+}
+this.prerender();
+this.scroller.invalidateNodes();
+this.setScrollTop(this.scrollTop);
+this.postrender();
+},update:function(){
+this.render();
+},updateRow:function(_1b){
+_1b=Number(_1b);
+if(this.updating){
+this.invalidated.rows[_1b]=true;
+}else{
+this.views.updateRow(_1b,this.rows.getHeight(_1b));
+this.scroller.rowHeightChanged(_1b);
+}
+},updateRowCount:function(_1c){
+if(this.updating){
+this.invalidated.rowCount=_1c;
+}else{
+this.rowCount=_1c;
+if(this.layout.cells.length){
+this.scroller.updateRowCount(_1c);
+this.setScrollTop(this.scrollTop);
+}
+this._resize();
+}
+},updateRowStyles:function(_1d){
+this.views.updateRowStyles(_1d);
+},rowHeightChanged:function(_1e){
+this.views.renormalizeRow(_1e);
+this.scroller.rowHeightChanged(_1e);
+},fastScroll:true,delayScroll:false,scrollRedrawThreshold:(dojo.isIE?100:50),scrollTo:function(_1f){
+if(!this.fastScroll){
+this.setScrollTop(_1f);
+return;
+}
+var _20=Math.abs(this.lastScrollTop-_1f);
+this.lastScrollTop=_1f;
+if(_20>this.scrollRedrawThreshold||this.delayScroll){
+this.delayScroll=true;
+this.scrollTop=_1f;
+this.views.setScrollTop(_1f);
+dojox.grid.jobs.job("dojoxGrid-scroll",200,dojo.hitch(this,"finishScrollJob"));
+}else{
+this.setScrollTop(_1f);
+}
+},finishScrollJob:function(){
+this.delayScroll=false;
+this.setScrollTop(this.scrollTop);
+},setScrollTop:function(_21){
+this.scrollTop=this.views.setScrollTop(_21);
+this.scroller.scroll(this.scrollTop);
+},scrollToRow:function(_22){
+this.setScrollTop(this.scroller.findScrollTop(_22)+1);
+},styleRowNode:function(_23,_24){
+if(_24){
+this.rows.styleRowNode(_23,_24);
+}
+},getCell:function(_25){
+return this.layout.cells[_25];
+},setCellWidth:function(_26,_27){
+this.getCell(_26).unitWidth=_27;
+},getCellName:function(_28){
+return "Cell "+_28.index;
+},canSort:function(_29){
+},sort:function(){
+},getSortAsc:function(_2a){
+_2a=_2a==undefined?this.sortInfo:_2a;
+return Boolean(_2a>0);
+},getSortIndex:function(_2b){
+_2b=_2b==undefined?this.sortInfo:_2b;
+return Math.abs(_2b)-1;
+},setSortIndex:function(_2c,_2d){
+var si=_2c+1;
+if(_2d!=undefined){
+si*=(_2d?1:-1);
+}else{
+if(this.getSortIndex()==_2c){
+si=-this.sortInfo;
+}
+}
+this.setSortInfo(si);
+},setSortInfo:function(_2f){
+if(this.canSort(_2f)){
+this.sortInfo=_2f;
+this.sort();
+this.update();
+}
+},doKeyEvent:function(e){
+e.dispatch="do"+e.type;
+this.onKeyEvent(e);
+},_dispatch:function(m,e){
+if(m in this){
+return this[m](e);
+}
+},dispatchKeyEvent:function(e){
+this._dispatch(e.dispatch,e);
+},dispatchContentEvent:function(e){
+this.edit.dispatchEvent(e)||e.sourceView.dispatchContentEvent(e)||this._dispatch(e.dispatch,e);
+},dispatchHeaderEvent:function(e){
+e.sourceView.dispatchHeaderEvent(e)||this._dispatch("doheader"+e.type,e);
+},dokeydown:function(e){
+this.onKeyDown(e);
+},doclick:function(e){
+if(e.cellNode){
+this.onCellClick(e);
+}else{
+this.onRowClick(e);
+}
+},dodblclick:function(e){
+if(e.cellNode){
+this.onCellDblClick(e);
+}else{
+this.onRowDblClick(e);
+}
+},docontextmenu:function(e){
+if(e.cellNode){
+this.onCellContextMenu(e);
+}else{
+this.onRowContextMenu(e);
+}
+},doheaderclick:function(e){
+if(e.cellNode){
+this.onHeaderCellClick(e);
+}else{
+this.onHeaderClick(e);
+}
+},doheaderdblclick:function(e){
+if(e.cellNode){
+this.onHeaderCellDblClick(e);
+}else{
+this.onHeaderDblClick(e);
+}
+},doheadercontextmenu:function(e){
+if(e.cellNode){
+this.onHeaderCellContextMenu(e);
+}else{
+this.onHeaderContextMenu(e);
+}
+},doStartEdit:function(_3d,_3e){
+this.onStartEdit(_3d,_3e);
+},doApplyCellEdit:function(_3f,_40,_41){
+this.onApplyCellEdit(_3f,_40,_41);
+},doCancelEdit:function(_42){
+this.onCancelEdit(_42);
+},doApplyEdit:function(_43){
+this.onApplyEdit(_43);
+},addRow:function(){
+this.updateRowCount(this.rowCount+1);
+},removeSelectedRows:function(){
+this.updateRowCount(Math.max(0,this.rowCount-this.selection.getSelected().length));
+this.selection.clear();
+}});
+dojo.mixin(dojox.VirtualGrid.prototype,dojox.grid.publicEvents);
+}
diff --git a/dojox/grid/compat/_data/dijitEditors.js b/dojox/grid/compat/_data/dijitEditors.js
new file mode 100644
index 0000000..e209114
--- /dev/null
+++ b/dojox/grid/compat/_data/dijitEditors.js
@@ -0,0 +1,128 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat._data.dijitEditors"]){
+dojo._hasResource["dojox.grid.compat._data.dijitEditors"]=true;
+dojo.provide("dojox.grid.compat._data.dijitEditors");
+dojo.require("dojox.grid.compat._data.editors");
+dojo.require("dijit.form.DateTextBox");
+dojo.require("dijit.form.TimeTextBox");
+dojo.require("dijit.form.ComboBox");
+dojo.require("dojo.data.ItemFileReadStore");
+dojo.require("dijit.form.CheckBox");
+dojo.require("dijit.form.TextBox");
+dojo.require("dijit.form.NumberSpinner");
+dojo.require("dijit.form.NumberTextBox");
+dojo.require("dijit.form.CurrencyTextBox");
+dojo.require("dijit.form.Slider");
+dojo.require("dijit.Editor");
+dojo.declare("dojox.grid.editors.Dijit",dojox.grid.editors.base,{editorClass:"dijit.form.TextBox",constructor:function(_1){
+this.editor=null;
+this.editorClass=dojo.getObject(this.cell.editorClass||this.editorClass);
+},format:function(_2,_3){
+this.needFormatNode(_2,_3);
+return "<div></div>";
+},getValue:function(_4){
+return this.editor.getValue();
+},setValue:function(_5,_6){
+if(this.editor&&this.editor.setValue){
+if(this.editor.onLoadDeferred){
+var _7=this;
+this.editor.onLoadDeferred.addCallback(function(){
+_7.editor.setValue(_6==null?"":_6);
+});
+}else{
+this.editor.setValue(_6);
+}
+}else{
+this.inherited(arguments);
+}
+},getEditorProps:function(_8){
+return dojo.mixin({},this.cell.editorProps||{},{constraints:dojo.mixin({},this.cell.constraint)||{},value:_8});
+},createEditor:function(_9,_a,_b){
+return new this.editorClass(this.getEditorProps(_a),_9);
+},attachEditor:function(_c,_d,_e){
+_c.appendChild(this.editor.domNode);
+this.setValue(_e,_d);
+},formatNode:function(_f,_10,_11){
+if(!this.editorClass){
+return _10;
+}
+if(!this.editor){
+this.editor=this.createEditor.apply(this,arguments);
+}else{
+this.attachEditor.apply(this,arguments);
+}
+this.sizeEditor.apply(this,arguments);
+this.cell.grid.rowHeightChanged(_11);
+this.focus();
+},sizeEditor:function(_12,_13,_14){
+var p=this.cell.getNode(_14),box=dojo.contentBox(p);
+dojo.marginBox(this.editor.domNode,{w:box.w});
+},focus:function(_17,_18){
+if(this.editor){
+setTimeout(dojo.hitch(this.editor,function(){
+dojox.grid.fire(this,"focus");
+}),0);
+}
+},_finish:function(_19){
+this.inherited(arguments);
+dojox.grid.removeNode(this.editor.domNode);
+}});
+dojo.declare("dojox.grid.editors.ComboBox",dojox.grid.editors.Dijit,{editorClass:"dijit.form.ComboBox",getEditorProps:function(_1a){
+var _1b=[];
+dojo.forEach(this.cell.options,function(o){
+_1b.push({name:o,value:o});
+});
+var _1d=new dojo.data.ItemFileReadStore({data:{identifier:"name",items:_1b}});
+return dojo.mixin({},this.cell.editorProps||{},{value:_1a,store:_1d});
+},getValue:function(){
+var e=this.editor;
+e.setDisplayedValue(e.getDisplayedValue());
+return e.getValue();
+}});
+dojo.declare("dojox.grid.editors.DateTextBox",dojox.grid.editors.Dijit,{editorClass:"dijit.form.DateTextBox",setValue:function(_1f,_20){
+if(this.editor){
+this.editor.setValue(new Date(_20));
+}else{
+this.inherited(arguments);
+}
+},getEditorProps:function(_21){
+return dojo.mixin(this.inherited(arguments),{value:new Date(_21)});
+}});
+dojo.declare("dojox.grid.editors.CheckBox",dojox.grid.editors.Dijit,{editorClass:"dijit.form.CheckBox",getValue:function(){
+return this.editor.checked;
+},setValue:function(_22,_23){
+if(this.editor&&this.editor.setAttribute){
+this.editor.setAttribute("checked",_23);
+}else{
+this.inherited(arguments);
+}
+},sizeEditor:function(_24,_25,_26){
+return;
+}});
+dojo.declare("dojox.grid.editors.Editor",dojox.grid.editors.Dijit,{editorClass:"dijit.Editor",getEditorProps:function(_27){
+return dojo.mixin({},this.cell.editorProps||{},{height:this.cell.editorHeight||"100px"});
+},createEditor:function(_28,_29,_2a){
+var _2b=new this.editorClass(this.getEditorProps(_29),_28);
+dojo.connect(_2b,"onLoad",dojo.hitch(this,"populateEditor"));
+return _2b;
+},formatNode:function(_2c,_2d,_2e){
+this.content=_2d;
+this.inherited(arguments);
+if(dojo.isMoz){
+var e=this.editor;
+e.open();
+if(this.cell.editorToolbar){
+dojo.place(e.toolbar.domNode,e.editingArea,"before");
+}
+}
+},populateEditor:function(){
+this.editor.setValue(this.content);
+this.editor.placeCursorAtEnd();
+}});
+}
diff --git a/dojox/grid/compat/_data/editors.js b/dojox/grid/compat/_data/editors.js
new file mode 100644
index 0000000..8ebe268
--- /dev/null
+++ b/dojox/grid/compat/_data/editors.js
@@ -0,0 +1,122 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat._data.editors"]){
+dojo._hasResource["dojox.grid.compat._data.editors"]=true;
+dojo.provide("dojox.grid.compat._data.editors");
+dojo.provide("dojox.grid.compat.editors");
+dojo.declare("dojox.grid.editors.Base",null,{constructor:function(_1){
+this.cell=_1;
+},_valueProp:"value",_formatPending:false,format:function(_2,_3){
+},needFormatNode:function(_4,_5){
+this._formatPending=true;
+dojox.grid.whenIdle(this,"_formatNode",_4,_5);
+},cancelFormatNode:function(){
+this._formatPending=false;
+},_formatNode:function(_6,_7){
+if(this._formatPending){
+this._formatPending=false;
+dojo.setSelectable(this.cell.grid.domNode,true);
+this.formatNode(this.getNode(_7),_6,_7);
+}
+},getNode:function(_8){
+return (this.cell.getNode(_8)||0).firstChild||0;
+},formatNode:function(_9,_a,_b){
+if(dojo.isIE){
+dojox.grid.whenIdle(this,"focus",_b,_9);
+}else{
+this.focus(_b,_9);
+}
+},dispatchEvent:function(m,e){
+if(m in this){
+return this[m](e);
+}
+},getValue:function(_e){
+return this.getNode(_e)[this._valueProp];
+},setValue:function(_f,_10){
+var n=this.getNode(_f);
+if(n){
+n[this._valueProp]=_10;
+}
+},focus:function(_12,_13){
+dojox.grid.focusSelectNode(_13||this.getNode(_12));
+},save:function(_14){
+this.value=this.value||this.getValue(_14);
+},restore:function(_15){
+this.setValue(_15,this.value);
+},_finish:function(_16){
+dojo.setSelectable(this.cell.grid.domNode,false);
+this.cancelFormatNode(this.cell);
+},apply:function(_17){
+this.cell.applyEdit(this.getValue(_17),_17);
+this._finish(_17);
+},cancel:function(_18){
+this.cell.cancelEdit(_18);
+this._finish(_18);
+}});
+dojox.grid.editors.base=dojox.grid.editors.Base;
+dojo.declare("dojox.grid.editors.Input",dojox.grid.editors.Base,{constructor:function(_19){
+this.keyFilter=this.keyFilter||this.cell.keyFilter;
+},keyFilter:null,format:function(_1a,_1b){
+this.needFormatNode(_1a,_1b);
+return "<input class=\"dojoxGrid-input\" type=\"text\" value=\""+_1a+"\">";
+},formatNode:function(_1c,_1d,_1e){
+this.inherited(arguments);
+this.cell.registerOnBlur(_1c,_1e);
+},doKey:function(e){
+if(this.keyFilter){
+var key=String.fromCharCode(e.charCode);
+if(key.search(this.keyFilter)==-1){
+dojo.stopEvent(e);
+}
+}
+},_finish:function(_21){
+this.inherited(arguments);
+var n=this.getNode(_21);
+try{
+dojox.grid.fire(n,"blur");
+}
+catch(e){
+}
+}});
+dojox.grid.editors.input=dojox.grid.editors.Input;
+dojo.declare("dojox.grid.editors.Select",dojox.grid.editors.Input,{constructor:function(_23){
+this.options=this.options||this.cell.options;
+this.values=this.values||this.cell.values||this.options;
+},format:function(_24,_25){
+this.needFormatNode(_24,_25);
+var h=["<select class=\"dojoxGrid-select\">"];
+for(var i=0,o,v;((o=this.options[i])!==undefined)&&((v=this.values[i])!==undefined);i++){
+h.push("<option",(_24==v?" selected":"")," value=\""+v+"\"",">",o,"</option>");
+}
+h.push("</select>");
+return h.join("");
+},getValue:function(_2a){
+var n=this.getNode(_2a);
+if(n){
+var i=n.selectedIndex,o=n.options[i];
+return this.cell.returnIndex?i:o.value||o.innerHTML;
+}
+}});
+dojox.grid.editors.select=dojox.grid.editors.Select;
+dojo.declare("dojox.grid.editors.AlwaysOn",dojox.grid.editors.Input,{alwaysOn:true,_formatNode:function(_2e,_2f){
+this.formatNode(this.getNode(_2f),_2e,_2f);
+},applyStaticValue:function(_30){
+var e=this.cell.grid.edit;
+e.applyCellEdit(this.getValue(_30),this.cell,_30);
+e.start(this.cell,_30,true);
+}});
+dojox.grid.editors.alwaysOn=dojox.grid.editors.AlwaysOn;
+dojo.declare("dojox.grid.editors.Bool",dojox.grid.editors.AlwaysOn,{_valueProp:"checked",format:function(_32,_33){
+return "<input class=\"dojoxGrid-input\" type=\"checkbox\""+(_32?" checked=\"checked\"":"")+" style=\"width: auto\" />";
+},doclick:function(e){
+if(e.target.tagName=="INPUT"){
+this.applyStaticValue(e.rowIndex);
+}
+}});
+dojox.grid.editors.bool=dojox.grid.editors.Bool;
+}
diff --git a/dojox/grid/compat/_data/fields.js b/dojox/grid/compat/_data/fields.js
new file mode 100644
index 0000000..cc17b26
--- /dev/null
+++ b/dojox/grid/compat/_data/fields.js
@@ -0,0 +1,84 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat._data.fields"]){
+dojo._hasResource["dojox.grid.compat._data.fields"]=true;
+dojo.provide("dojox.grid.compat._data.fields");
+dojo.declare("dojox.grid.data.Mixer",null,{constructor:function(){
+this.defaultValue={};
+this.values=[];
+},count:function(){
+return this.values.length;
+},clear:function(){
+this.values=[];
+},build:function(_1){
+var _2=dojo.mixin({owner:this},this.defaultValue);
+_2.key=_1;
+this.values[_1]=_2;
+return _2;
+},getDefault:function(){
+return this.defaultValue;
+},setDefault:function(_3){
+for(var i=0,a;(a=arguments[i]);i++){
+dojo.mixin(this.defaultValue,a);
+}
+},get:function(_6){
+return this.values[_6]||this.build(_6);
+},_set:function(_7,_8){
+var v=this.get(_7);
+for(var i=1;i<arguments.length;i++){
+dojo.mixin(v,arguments[i]);
+}
+this.values[_7]=v;
+},set:function(){
+if(arguments.length<1){
+return;
+}
+var a=arguments[0];
+if(!dojo.isArray(a)){
+this._set.apply(this,arguments);
+}else{
+if(a.length&&a[0]["default"]){
+this.setDefault(a.shift());
+}
+for(var i=0,l=a.length;i<l;i++){
+this._set(i,a[i]);
+}
+}
+},insert:function(_e,_f){
+if(_e>=this.values.length){
+this.values[_e]=_f;
+}else{
+this.values.splice(_e,0,_f);
+}
+},remove:function(_10){
+this.values.splice(_10,1);
+},swap:function(_11,_12){
+dojox.grid.arraySwap(this.values,_11,_12);
+},move:function(_13,_14){
+dojox.grid.arrayMove(this.values,_13,_14);
+}});
+dojox.grid.data.compare=function(a,b){
+return (a>b?1:(a==b?0:-1));
+};
+dojo.declare("dojox.grid.data.Field",null,{constructor:function(_17){
+this.name=_17;
+this.compare=dojox.grid.data.compare;
+},na:dojox.grid.na});
+dojo.declare("dojox.grid.data.Fields",dojox.grid.data.Mixer,{constructor:function(_18){
+var _19=_18?_18:dojox.grid.data.Field;
+this.defaultValue=new _19();
+},indexOf:function(_1a){
+for(var i=0;i<this.values.length;i++){
+var v=this.values[i];
+if(v&&v.key==_1a){
+return i;
+}
+}
+return -1;
+}});
+}
diff --git a/dojox/grid/compat/_data/model.js b/dojox/grid/compat/_data/model.js
new file mode 100644
index 0000000..88217c1
--- /dev/null
+++ b/dojox/grid/compat/_data/model.js
@@ -0,0 +1,490 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat._data.model"]){
+dojo._hasResource["dojox.grid.compat._data.model"]=true;
+dojo.provide("dojox.grid.compat._data.model");
+dojo.require("dojox.grid.compat._data.fields");
+dojo.declare("dojox.grid.data.Model",null,{constructor:function(_1,_2){
+this.observers=[];
+this.fields=new dojox.grid.data.Fields();
+if(_1){
+this.fields.set(_1);
+}
+this.setData(_2);
+},count:0,updating:0,observer:function(_3,_4){
+this.observers.push({o:_3,p:_4||"model"});
+},notObserver:function(_5){
+for(var i=0,m,o;(o=this.observers[i]);i++){
+if(o.o==_5){
+this.observers.splice(i,1);
+return;
+}
+}
+},notify:function(_9,_a){
+var a=_a||[];
+for(var i=0,m,o;(o=this.observers[i]);i++){
+m=o.p+_9;
+o=o.o;
+(m in o)&&(o[m].apply(o,a));
+}
+},clear:function(){
+this.fields.clear();
+this.clearData();
+},beginUpdate:function(){
+this.notify("BeginUpdate",arguments);
+},endUpdate:function(){
+this.notify("EndUpdate",arguments);
+},clearData:function(){
+this.setData(null);
+},change:function(){
+this.notify("Change",arguments);
+},insertion:function(){
+this.notify("Insertion",arguments);
+this.notify("Change",arguments);
+},removal:function(){
+this.notify("Removal",arguments);
+this.notify("Change",arguments);
+},insert:function(_f){
+if(!this._insert.apply(this,arguments)){
+return false;
+}
+this.insertion.apply(this,dojo._toArray(arguments,1));
+return true;
+},remove:function(_10){
+if(!this._remove.apply(this,arguments)){
+return false;
+}
+this.removal.apply(this,arguments);
+return true;
+},canSort:function(){
+return this.sort!=null;
+},generateComparator:function(_11,_12,_13,_14){
+return function(a,b){
+var _17=_11(a[_12],b[_12]);
+return _17?(_13?_17:-_17):_14&&_14(a,b);
+};
+},makeComparator:function(_18){
+var idx,col,_1b,_1c=null;
+for(var i=_18.length-1;i>=0;i--){
+idx=_18[i];
+col=Math.abs(idx)-1;
+if(col>=0){
+_1b=this.fields.get(col);
+_1c=this.generateComparator(_1b.compare,_1b.key,idx>0,_1c);
+}
+}
+return _1c;
+},sort:null,dummy:0});
+dojo.declare("dojox.grid.data.Rows",dojox.grid.data.Model,{allChange:function(){
+this.notify("AllChange",arguments);
+this.notify("Change",arguments);
+},rowChange:function(){
+this.notify("RowChange",arguments);
+},datumChange:function(){
+this.notify("DatumChange",arguments);
+},beginModifyRow:function(_1e){
+if(!this.cache[_1e]){
+this.cache[_1e]=this.copyRow(_1e);
+}
+},endModifyRow:function(_1f){
+var _20=this.cache[_1f];
+if(_20){
+var _21=this.getRow(_1f);
+if(!dojox.grid.arrayCompare(_20,_21)){
+this.update(_20,_21,_1f);
+}
+delete this.cache[_1f];
+}
+},cancelModifyRow:function(_22){
+var _23=this.cache[_22];
+if(_23){
+this.setRow(_23,_22);
+delete this.cache[_22];
+}
+}});
+dojo.declare("dojox.grid.data.Table",dojox.grid.data.Rows,{constructor:function(){
+this.cache=[];
+},colCount:0,data:null,cache:null,measure:function(){
+this.count=this.getRowCount();
+this.colCount=this.getColCount();
+this.allChange();
+},getRowCount:function(){
+return (this.data?this.data.length:0);
+},getColCount:function(){
+return (this.data&&this.data.length?this.data[0].length:this.fields.count());
+},badIndex:function(_24,_25){
+console.error("dojox.grid.data.Table: badIndex");
+},isGoodIndex:function(_26,_27){
+return (_26>=0&&_26<this.count&&(arguments.length<2||(_27>=0&&_27<this.colCount)));
+},getRow:function(_28){
+return this.data[_28];
+},copyRow:function(_29){
+return this.getRow(_29).slice(0);
+},getDatum:function(_2a,_2b){
+return this.data[_2a][_2b];
+},get:function(){
+throw ("Plain \"get\" no longer supported. Use \"getRow\" or \"getDatum\".");
+},setData:function(_2c){
+this.data=(_2c||[]);
+this.allChange();
+},setRow:function(_2d,_2e){
+this.data[_2e]=_2d;
+this.rowChange(_2d,_2e);
+this.change();
+},setDatum:function(_2f,_30,_31){
+this.data[_30][_31]=_2f;
+this.datumChange(_2f,_30,_31);
+},set:function(){
+throw ("Plain \"set\" no longer supported. Use \"setData\", \"setRow\", or \"setDatum\".");
+},setRows:function(_32,_33){
+for(var i=0,l=_32.length,r=_33;i<l;i++,r++){
+this.setRow(_32[i],r);
+}
+},update:function(_37,_38,_39){
+return true;
+},_insert:function(_3a,_3b){
+dojox.grid.arrayInsert(this.data,_3b,_3a);
+this.count++;
+return true;
+},_remove:function(_3c){
+for(var i=_3c.length-1;i>=0;i--){
+dojox.grid.arrayRemove(this.data,_3c[i]);
+}
+this.count-=_3c.length;
+return true;
+},sort:function(){
+this.data.sort(this.makeComparator(arguments));
+},swap:function(_3e,_3f){
+dojox.grid.arraySwap(this.data,_3e,_3f);
+this.rowChange(this.getRow(_3e),_3e);
+this.rowChange(this.getRow(_3f),_3f);
+this.change();
+},dummy:0});
+dojo.declare("dojox.grid.data.Objects",dojox.grid.data.Table,{constructor:function(_40,_41,_42){
+if(!_40){
+this.autoAssignFields();
+}
+},allChange:function(){
+this.notify("FieldsChange");
+this.inherited(arguments);
+},autoAssignFields:function(){
+var d=this.data[0],i=0,_45;
+for(var f in d){
+_45=this.fields.get(i++);
+if(!dojo.isString(_45.key)){
+_45.key=f;
+}
+}
+},setData:function(_47){
+this.data=(_47||[]);
+this.autoAssignFields();
+this.allChange();
+},getDatum:function(_48,_49){
+return this.data[_48][this.fields.get(_49).key];
+}});
+dojo.declare("dojox.grid.data.Dynamic",dojox.grid.data.Table,{constructor:function(){
+this.page=[];
+this.pages=[];
+},page:null,pages:null,rowsPerPage:100,requests:0,bop:-1,eop:-1,clearData:function(){
+this.pages=[];
+this.bop=this.eop=-1;
+this.setData([]);
+},getRowCount:function(){
+return this.count;
+},getColCount:function(){
+return this.fields.count();
+},setRowCount:function(_4a){
+this.count=_4a;
+this.change();
+},requestsPending:function(_4b){
+},rowToPage:function(_4c){
+return (this.rowsPerPage?Math.floor(_4c/this.rowsPerPage):_4c);
+},pageToRow:function(_4d){
+return (this.rowsPerPage?this.rowsPerPage*_4d:_4d);
+},requestRows:function(_4e,_4f){
+},rowsProvided:function(_50,_51){
+this.requests--;
+if(this.requests==0){
+this.requestsPending(false);
+}
+},requestPage:function(_52){
+var row=this.pageToRow(_52);
+var _54=Math.min(this.rowsPerPage,this.count-row);
+if(_54>0){
+this.requests++;
+this.requestsPending(true);
+setTimeout(dojo.hitch(this,"requestRows",row,_54),1);
+}
+},needPage:function(_55){
+if(!this.pages[_55]){
+this.pages[_55]=true;
+this.requestPage(_55);
+}
+},preparePage:function(_56,_57){
+if(_56<this.bop||_56>=this.eop){
+var _58=this.rowToPage(_56);
+this.needPage(_58);
+this.bop=_58*this.rowsPerPage;
+this.eop=this.bop+(this.rowsPerPage||this.count);
+}
+},isRowLoaded:function(_59){
+return Boolean(this.data[_59]);
+},removePages:function(_5a){
+for(var i=0,r;((r=_5a[i])!=undefined);i++){
+this.pages[this.rowToPage(r)]=false;
+}
+this.bop=this.eop=-1;
+},remove:function(_5d){
+this.removePages(_5d);
+dojox.grid.data.Table.prototype.remove.apply(this,arguments);
+},getRow:function(_5e){
+var row=this.data[_5e];
+if(!row){
+this.preparePage(_5e);
+}
+return row;
+},getDatum:function(_60,_61){
+var row=this.getRow(_60);
+return (row?row[_61]:this.fields.get(_61).na);
+},setDatum:function(_63,_64,_65){
+var row=this.getRow(_64);
+if(row){
+row[_65]=_63;
+this.datumChange(_63,_64,_65);
+}else{
+console.error("["+this.declaredClass+"] dojox.grid.data.dynamic.set: cannot set data on a non-loaded row");
+}
+},canSort:function(){
+return false;
+}});
+dojox.grid.data.table=dojox.grid.data.Table;
+dojox.grid.data.dynamic=dojox.grid.data.Dynamic;
+dojo.declare("dojox.grid.data.DojoData",dojox.grid.data.Dynamic,{constructor:function(_67,_68,_69){
+this.count=1;
+this._rowIdentities={};
+this._currentlyProcessing=[];
+if(_69){
+dojo.mixin(this,_69);
+}
+if(this.store){
+var f=this.store.getFeatures();
+this._canNotify=f["dojo.data.api.Notification"];
+this._canWrite=f["dojo.data.api.Write"];
+this._canIdentify=f["dojo.data.api.Identity"];
+if(this._canNotify){
+dojo.connect(this.store,"onSet",this,"_storeDatumChange");
+dojo.connect(this.store,"onDelete",this,"_storeDatumDelete");
+dojo.connect(this.store,"onNew",this,"_storeDatumNew");
+}
+if(this._canWrite){
+dojo.connect(this.store,"revert",this,"refresh");
+}
+}
+},markupFactory:function(_6b,_6c){
+return new dojox.grid.data.DojoData(null,null,_6b);
+},query:{name:"*"},store:null,_currentlyProcessing:null,_canNotify:false,_canWrite:false,_canIdentify:false,_rowIdentities:{},clientSort:false,sortFields:null,queryOptions:null,setData:function(_6d){
+this.store=_6d;
+this.data=[];
+this.allChange();
+},setRowCount:function(_6e){
+this.count=_6e;
+this.allChange();
+},beginReturn:function(_6f){
+if(this.count!=_6f){
+this.setRowCount(_6f);
+}
+},_setupFields:function(_70){
+if(this.fields._nameMaps){
+return;
+}
+var m={};
+var _72=dojo.map(this.store.getAttributes(_70),function(_73,idx){
+m[_73]=idx;
+m[idx+".idx"]=_73;
+return {name:_73,key:_73};
+},this);
+this.fields._nameMaps=m;
+this.fields.set(_72);
+this.notify("FieldsChange");
+},_getRowFromItem:function(_75){
+},_createRow:function(_76){
+var row={};
+row.__dojo_data_item=_76;
+dojo.forEach(this.fields.values,function(a){
+var _79=this.store.getValue(_76,a.name);
+row[a.name]=(_79===undefined||_79===null)?"":_79;
+},this);
+return row;
+},processRows:function(_7a,_7b){
+if(!_7a||_7a.length==0){
+return;
+}
+this._setupFields(_7a[0]);
+dojo.forEach(_7a,function(_7c,idx){
+var row=this._createRow(_7c);
+this._setRowId(_7c,_7b.start,idx);
+this.setRow(row,_7b.start+idx);
+},this);
+this.endUpdate();
+},requestRows:function(_7f,_80){
+this.beginUpdate();
+var row=_7f||0;
+var _82={start:row,count:this.rowsPerPage,query:this.query,sort:this.sortFields,queryOptions:this.queryOptions,onBegin:dojo.hitch(this,"beginReturn"),onComplete:dojo.hitch(this,"processRows"),onError:dojo.hitch(this,"processError")};
+this.store.fetch(_82);
+},getDatum:function(_83,_84){
+var row=this.getRow(_83);
+var _86=this.fields.values[_84];
+return row&&_86?row[_86.name]:_86?_86.na:"?";
+},setDatum:function(_87,_88,_89){
+var n=this.fields._nameMaps[_89+".idx"];
+if(n){
+this.data[_88][n]=_87;
+this.datumChange(_87,_88,_89);
+}
+},copyRow:function(_8b){
+var row={};
+var _8d={};
+var src=this.getRow(_8b);
+for(var x in src){
+if(src[x]!=_8d[x]){
+row[x]=src[x];
+}
+}
+return row;
+},_attrCompare:function(_90,_91){
+dojo.forEach(this.fields.values,function(a){
+if(_90[a.name]!=_91[a.name]){
+return false;
+}
+},this);
+return true;
+},endModifyRow:function(_93){
+var _94=this.cache[_93];
+if(_94){
+var _95=this.getRow(_93);
+if(!this._attrCompare(_94,_95)){
+this.update(_94,_95,_93);
+}
+delete this.cache[_93];
+}
+},cancelModifyRow:function(_96){
+var _97=this.cache[_96];
+if(_97){
+this.setRow(_97,_96);
+delete this.cache[_96];
+}
+},_setRowId:function(_98,_99,idx){
+if(this._canIdentify){
+this._rowIdentities[this.store.getIdentity(_98)]={rowId:_99+idx,item:_98};
+}else{
+var _9b=dojo.toJson(this.query)+":start:"+_99+":idx:"+idx+":sort:"+dojo.toJson(this.sortFields);
+this._rowIdentities[_9b]={rowId:_99+idx,item:_98};
+}
+},_getRowId:function(_9c,_9d){
+var _9e=null;
+if(this._canIdentify&&!_9d){
+var _9f=this._rowIdentities[this.store.getIdentity(_9c)];
+if(_9f){
+_9e=_9f.rowId;
+}
+}else{
+var id;
+for(id in this._rowIdentities){
+if(this._rowIdentities[id].item===_9c){
+_9e=this._rowIdentities[id].rowId;
+break;
+}
+}
+}
+return _9e;
+},_storeDatumChange:function(_a1,_a2,_a3,_a4){
+var _a5=this._getRowId(_a1);
+var row=this.getRow(_a5);
+if(row){
+row[_a2]=_a4;
+var _a7=this.fields._nameMaps[_a2];
+this.notify("DatumChange",[_a4,_a5,_a7]);
+}
+},_storeDatumDelete:function(_a8){
+if(dojo.indexOf(this._currentlyProcessing,_a8)!=-1){
+return;
+}
+var _a9=this._getRowId(_a8,true);
+if(_a9!=null){
+this._removeItems([_a9]);
+}
+},_storeDatumNew:function(_aa){
+if(this._disableNew){
+return;
+}
+this._insertItem(_aa,this.data.length);
+},insert:function(_ab,_ac){
+this._disableNew=true;
+var i=this.store.newItem(_ab);
+this._disableNew=false;
+this._insertItem(i,_ac);
+},_insertItem:function(_ae,_af){
+if(!this.fields._nameMaps){
+this._setupFields(_ae);
+}
+var row=this._createRow(_ae);
+for(var i in this._rowIdentities){
+var _b2=this._rowIdentities[i];
+if(_b2.rowId>=_af){
+_b2.rowId++;
+}
+}
+this._setRowId(_ae,0,_af);
+dojox.grid.data.Dynamic.prototype.insert.apply(this,[row,_af]);
+},datumChange:function(_b3,_b4,_b5){
+if(this._canWrite){
+var row=this.getRow(_b4);
+var _b7=this.fields._nameMaps[_b5+".idx"];
+this.store.setValue(row.__dojo_data_item,_b7,_b3);
+}else{
+this.notify("DatumChange",arguments);
+}
+},insertion:function(){
+this.notify("Insertion",arguments);
+this.notify("Change",arguments);
+},removal:function(){
+this.notify("Removal",arguments);
+this.notify("Change",arguments);
+},remove:function(_b8){
+for(var i=_b8.length-1;i>=0;i--){
+var _ba=this.data[_b8[i]].__dojo_data_item;
+this._currentlyProcessing.push(_ba);
+this.store.deleteItem(_ba);
+}
+this._removeItems(_b8);
+this._currentlyProcessing=[];
+},_removeItems:function(_bb){
+dojox.grid.data.Dynamic.prototype.remove.apply(this,arguments);
+this._rowIdentities={};
+for(var i=0;i<this.data.length;i++){
+this._setRowId(this.data[i].__dojo_data_item,0,i);
+}
+},canSort:function(){
+return true;
+},sort:function(_bd){
+var col=Math.abs(_bd)-1;
+this.sortFields=[{"attribute":this.fields.values[col].name,"descending":(_bd>0)}];
+this.refresh();
+},refresh:function(){
+this.clearData(true);
+this.requestRows();
+},clearData:function(_bf){
+this._rowIdentities={};
+this.pages=[];
+this.bop=this.eop=-1;
+this.count=0;
+this.setData((_bf?this.store:[]));
+},processError:function(_c0,_c1){
+
+}});
+}
diff --git a/dojox/grid/compat/_grid/Grid.css b/dojox/grid/compat/_grid/Grid.css
new file mode 100644
index 0000000..655be54
--- /dev/null
+++ b/dojox/grid/compat/_grid/Grid.css
@@ -0,0 +1,201 @@
+.dojoxGrid {
+	position: relative;
+	background-color: #EBEADB;
+	font-family: Geneva, Arial, Helvetica, sans-serif;
+	-moz-outline-style: none;
+	outline: none;
+	overflow: hidden;
+	height: 0;
+}
+.dojoxGrid table {
+	padding: 0;
+}
+.dojoxGrid td {
+	-moz-outline: none;
+}
+.dojoxGrid-master-header {
+	position: relative;
+}
+.dojoxGrid-master-view  {
+	position: relative;
+}
+.dojoxGrid-view {
+	position: absolute;
+	overflow: hidden;
+}
+.dojoxGrid-header {
+	position: absolute;
+	overflow: hidden;
+}
+.dojoxGrid-header {
+	background-color: #E8E1CF;
+}
+.dojoxGrid-header table {
+	text-align: center;
+}
+.dojoxGrid-header .dojoxGrid-cell-content {
+	text-align: center;
+}
+.dojoxGrid-header .dojoxGrid-cell { 
+	border: 1px solid;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+	padding-bottom: 2px;
+}
+.dojoxGrid-header .dojoxGrid-cell-over {
+	background-image: none;
+	background-color: white;
+	border-bottom-color: #FEBE47;
+	margin-bottom: 0;
+	padding-bottom: 0;
+	border-bottom-width: 3px;
+}
+.dojoxGrid-sort-down {
+	background: url(images/grid_sort_down.gif) left no-repeat; 
+	padding-left:16px;
+	margin-left:4px;
+}
+.dojoxGrid-sort-up {
+	background: url(images/grid_sort_up.gif) left no-repeat; 
+	padding-left:16px;
+	margin-left:4px;
+}
+.dojoxGrid-scrollbox {
+	position: relative;
+	overflow: scroll;
+	background-color: white;
+	width: 100%;
+}
+.dojoxGrid-content {
+	position: relative;
+	overflow: hidden;
+	 -moz-outline-style: none;
+	outline: none;
+}
+.dojoxGrid-rowbar { 
+	border: 1px solid;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	border-top: none;
+	background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+}
+.dojoxGrid-rowbar-inner {
+	border-top: 1px solid #F6F4EB;
+}
+.dojoxGrid-rowbar-over {
+	background-image: none;
+	background-color: white;
+	border-top-color: #FEBE47;
+	border-bottom-color: #FEBE47;
+}
+.dojoxGrid-rowbar-selected {
+	background-color: #D9E8F9;
+	background-image: none;
+	
+	background-position: center;
+	background-repeat: no-repeat;
+}
+.dojoxGrid-row {
+	position: relative;
+	width: 9000em;
+}
+.dojoxGrid-row {
+	
+	border: 1px solid #E8E4D8;
+	border-color: #F8F7F1;
+	
+	border-left: none;
+	border-right: none;
+	background-color: white;
+	border-top: none;
+}
+.dojoxGrid-row-over {
+	border-top-color: #FEBE47;
+	border-bottom-color: #FEBE47;
+	
+	
+	
+}
+.dojoxGrid-row-odd {
+	background-color: #FFFDF3;
+	
+}
+.dojoxGrid-row-selected {
+	background-color: #D9E8F9;
+}
+.dojoxGrid-row-table {
+	table-layout: fixed;
+	width: 0;
+}
+.dojoxGrid-invisible {
+	visibility: hidden;
+}		
+.Xdojo-ie .dojoxGrid-invisible {
+	display: none;
+}		
+.dojoxGrid-invisible td, .dojoxGrid-header .dojoxGrid-invisible td {
+	border-top-width: 0;
+	border-bottom-width: 0;
+	padding-top: 0;
+	padding-bottom: 0;
+	height: 0;
+	overflow: hidden;
+}
+.dojoxGrid-cell {
+	border: 1px solid;
+	border-color: #EBEADB;
+	border-right-color: #D5CDB5;
+	padding: 3px 3px 3px 3px;
+	text-align: left;
+	overflow: hidden;
+}
+.dojoxGrid-cell-focus {
+	border: 1px dashed blue;
+}
+.dojoxGrid-cell-over {
+	border: 1px dotted #FEBE47;
+}
+.dojoxGrid-cell-focus.dojoxGrid-cell-over {
+	border: 1px dotted green;
+}
+.dojoxGrid-cell-clip {
+	width: 100%;
+	overflow: hidden;
+	white-space:nowrap;
+	text-overflow: ellipsis;
+}
+.dojoxGrid-row-editing td {
+	background-color: #F4FFF4;
+}
+.dojoxGrid-row-inserting td {
+	background-color: #F4FFF4;
+}
+.dojoxGrid-row-inflight td {
+	background-color: #F2F7B7;
+}
+.dojoxGrid-row-error td {
+	background-color: #F8B8B6;
+}
+.dojoxGrid-input, .dojoxGrid-select, .dojoxGrid-textarea {
+	margin: 0;
+	padding: 0;
+	border-style: none;
+	width: 100%;
+	font-size: 100%;
+	font-family: inherit;
+}
+.dojoxGrid-hidden-focus {
+	position: absolute;
+	left: -1000px;
+	top: -1000px;
+	height: 0px, width: 0px;
+}
+.gridArrowButtonChar {
+	display:none !important;
+}
+.dijit_a11y .gridArrowButtonChar {
+	display:inline !important;
+}
+.dijit_a11y .dojoxGrid-sort-down, .dijit_a11y .dojoxGrid-sort-up {
+	margin-left: 0;
+	padding-left: 0;
+}
diff --git a/dojox/grid/compat/_grid/Grid_rtl.css b/dojox/grid/compat/_grid/Grid_rtl.css
new file mode 100644
index 0000000..88ab215
--- /dev/null
+++ b/dojox/grid/compat/_grid/Grid_rtl.css
@@ -0,0 +1,8 @@
+.dijitRtl .dojoxGrid-header table {
+}
+.dj_ie .dijitRtl .dojoxGrid-header table {
+	float:none;
+}
+.dijitRtl .dojoxGrid-content {
+	float:left;
+}
diff --git a/dojox/grid/compat/_grid/builder.js b/dojox/grid/compat/_grid/builder.js
new file mode 100644
index 0000000..411e575
--- /dev/null
+++ b/dojox/grid/compat/_grid/builder.js
@@ -0,0 +1,353 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat._grid.builder"]){
+dojo._hasResource["dojox.grid.compat._grid.builder"]=true;
+dojo.provide("dojox.grid.compat._grid.builder");
+dojo.require("dojox.grid.compat._grid.drag");
+dojo.declare("dojox.grid.Builder",null,{constructor:function(_1){
+this.view=_1;
+this.grid=_1.grid;
+},view:null,_table:"<table class=\"dojoxGrid-row-table\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" role=\"wairole:presentation\">",generateCellMarkup:function(_2,_3,_4,_5){
+var _6=[],_7;
+if(_5){
+_7=["<th tabIndex=\"-1\" role=\"wairole:columnheader\""];
+}else{
+_7=["<td tabIndex=\"-1\" role=\"wairole:gridcell\""];
+}
+_2.colSpan&&_7.push(" colspan=\"",_2.colSpan,"\"");
+_2.rowSpan&&_7.push(" rowspan=\"",_2.rowSpan,"\"");
+_7.push(" class=\"dojoxGrid-cell ");
+_2.classes&&_7.push(_2.classes," ");
+_4&&_7.push(_4," ");
+_6.push(_7.join(""));
+_6.push("");
+_7=["\" idx=\"",_2.index,"\" style=\""];
+_7.push(_2.styles,_3||"");
+_2.unitWidth&&_7.push("width:",_2.unitWidth,";");
+_6.push(_7.join(""));
+_6.push("");
+_7=["\""];
+_2.attrs&&_7.push(" ",_2.attrs);
+_7.push(">");
+_6.push(_7.join(""));
+_6.push("");
+_6.push("</td>");
+return _6;
+},isCellNode:function(_8){
+return Boolean(_8&&_8.getAttribute&&_8.getAttribute("idx"));
+},getCellNodeIndex:function(_9){
+return _9?Number(_9.getAttribute("idx")):-1;
+},getCellNode:function(_a,_b){
+for(var i=0,_d;_d=dojox.grid.getTr(_a.firstChild,i);i++){
+for(var j=0,_f;_f=_d.cells[j];j++){
+if(this.getCellNodeIndex(_f)==_b){
+return _f;
+}
+}
+}
+},findCellTarget:function(_10,_11){
+var n=_10;
+while(n&&(!this.isCellNode(n)||(dojox.grid.gridViewTag in n.offsetParent.parentNode&&n.offsetParent.parentNode[dojox.grid.gridViewTag]!=this.view.id))&&(n!=_11)){
+n=n.parentNode;
+}
+return n!=_11?n:null;
+},baseDecorateEvent:function(e){
+e.dispatch="do"+e.type;
+e.grid=this.grid;
+e.sourceView=this.view;
+e.cellNode=this.findCellTarget(e.target,e.rowNode);
+e.cellIndex=this.getCellNodeIndex(e.cellNode);
+e.cell=(e.cellIndex>=0?this.grid.getCell(e.cellIndex):null);
+},findTarget:function(_14,_15){
+var n=_14;
+while(n&&(n!=this.domNode)&&(!(_15 in n)||(dojox.grid.gridViewTag in n&&n[dojox.grid.gridViewTag]!=this.view.id))){
+n=n.parentNode;
+}
+return (n!=this.domNode)?n:null;
+},findRowTarget:function(_17){
+return this.findTarget(_17,dojox.grid.rowIndexTag);
+},isIntraNodeEvent:function(e){
+try{
+return (e.cellNode&&e.relatedTarget&&dojo.isDescendant(e.relatedTarget,e.cellNode));
+}
+catch(x){
+return false;
+}
+},isIntraRowEvent:function(e){
+try{
+var row=e.relatedTarget&&this.findRowTarget(e.relatedTarget);
+return !row&&(e.rowIndex==-1)||row&&(e.rowIndex==row.gridRowIndex);
+}
+catch(x){
+return false;
+}
+},dispatchEvent:function(e){
+if(e.dispatch in this){
+return this[e.dispatch](e);
+}
+},domouseover:function(e){
+if(e.cellNode&&(e.cellNode!=this.lastOverCellNode)){
+this.lastOverCellNode=e.cellNode;
+this.grid.onMouseOver(e);
+}
+this.grid.onMouseOverRow(e);
+},domouseout:function(e){
+if(e.cellNode&&(e.cellNode==this.lastOverCellNode)&&!this.isIntraNodeEvent(e,this.lastOverCellNode)){
+this.lastOverCellNode=null;
+this.grid.onMouseOut(e);
+if(!this.isIntraRowEvent(e)){
+this.grid.onMouseOutRow(e);
+}
+}
+},domousedown:function(e){
+if(e.cellNode){
+this.grid.onMouseDown(e);
+}
+this.grid.onMouseDownRow(e);
+}});
+dojo.declare("dojox.grid.contentBuilder",dojox.grid.Builder,{update:function(){
+this.prepareHtml();
+},prepareHtml:function(){
+var _1f=this.grid.get,_20=this.view.structure.rows;
+for(var j=0,row;(row=_20[j]);j++){
+for(var i=0,_24;(_24=row[i]);i++){
+_24.get=_24.get||(_24.value==undefined)&&_1f;
+_24.markup=this.generateCellMarkup(_24,_24.cellStyles,_24.cellClasses,false);
+}
+}
+},generateHtml:function(_25,_26){
+var _27=[this._table],v=this.view,obr=v.onBeforeRow,_2a=v.structure.rows;
+obr&&obr(_26,_2a);
+for(var j=0,row;(row=_2a[j]);j++){
+if(row.hidden||row.header){
+continue;
+}
+_27.push(!row.invisible?"<tr>":"<tr class=\"dojoxGrid-invisible\">");
+for(var i=0,_2e,m,cc,cs;(_2e=row[i]);i++){
+m=_2e.markup,cc=_2e.customClasses=[],cs=_2e.customStyles=[];
+m[5]=_2e.format(_25);
+m[1]=cc.join(" ");
+m[3]=cs.join(";");
+_27.push.apply(_27,m);
+}
+_27.push("</tr>");
+}
+_27.push("</table>");
+return _27.join("");
+},decorateEvent:function(e){
+e.rowNode=this.findRowTarget(e.target);
+if(!e.rowNode){
+return false;
+}
+e.rowIndex=e.rowNode[dojox.grid.rowIndexTag];
+this.baseDecorateEvent(e);
+e.cell=this.grid.getCell(e.cellIndex);
+return true;
+}});
+dojo.declare("dojox.grid.headerBuilder",dojox.grid.Builder,{bogusClickTime:0,overResizeWidth:4,minColWidth:1,_table:"<table class=\"dojoxGrid-row-table\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" role=\"wairole:presentation\"",update:function(){
+this.tableMap=new dojox.grid.tableMap(this.view.structure.rows);
+},generateHtml:function(_33,_34){
+var _35=[this._table],_36=this.view.structure.rows;
+if(this.view.viewWidth){
+_35.push([" style=\"width:",this.view.viewWidth,";\""].join(""));
+}
+_35.push(">");
+dojox.grid.fire(this.view,"onBeforeRow",[-1,_36]);
+for(var j=0,row;(row=_36[j]);j++){
+if(row.hidden){
+continue;
+}
+_35.push(!row.invisible?"<tr>":"<tr class=\"dojoxGrid-invisible\">");
+for(var i=0,_3a,_3b;(_3a=row[i]);i++){
+_3a.customClasses=[];
+_3a.customStyles=[];
+_3b=this.generateCellMarkup(_3a,_3a.headerStyles,_3a.headerClasses,true);
+_3b[5]=(_34!=undefined?_34:_33(_3a));
+_3b[3]=_3a.customStyles.join(";");
+_3b[1]=_3a.customClasses.join(" ");
+_35.push(_3b.join(""));
+}
+_35.push("</tr>");
+}
+_35.push("</table>");
+return _35.join("");
+},getCellX:function(e){
+var x=e.layerX;
+if(dojo.isMoz){
+var n=dojox.grid.ascendDom(e.target,dojox.grid.makeNotTagName("th"));
+x-=(n&&n.offsetLeft)||0;
+var t=e.sourceView.getScrollbarWidth();
+if(!dojo._isBodyLtr()&&e.sourceView.headerNode.scrollLeft<t){
+x-=t;
+}
+}
+var n=dojox.grid.ascendDom(e.target,function(){
+if(!n||n==e.cellNode){
+return false;
+}
+x+=(n.offsetLeft<0?0:n.offsetLeft);
+return true;
+});
+return x;
+},decorateEvent:function(e){
+this.baseDecorateEvent(e);
+e.rowIndex=-1;
+e.cellX=this.getCellX(e);
+return true;
+},prepareResize:function(e,mod){
+var i=dojox.grid.getTdIndex(e.cellNode);
+e.cellNode=(i?e.cellNode.parentNode.cells[i+mod]:null);
+e.cellIndex=(e.cellNode?this.getCellNodeIndex(e.cellNode):-1);
+return Boolean(e.cellNode);
+},canResize:function(e){
+if(!e.cellNode||e.cellNode.colSpan>1){
+return false;
+}
+var _45=this.grid.getCell(e.cellIndex);
+return !_45.noresize&&!_45.isFlex();
+},overLeftResizeArea:function(e){
+if(dojo._isBodyLtr()){
+return (e.cellIndex>0)&&(e.cellX<this.overResizeWidth)&&this.prepareResize(e,-1);
+}
+var t=e.cellNode&&(e.cellX<this.overResizeWidth);
+return;
+},overRightResizeArea:function(e){
+if(dojo._isBodyLtr()){
+return e.cellNode&&(e.cellX>=e.cellNode.offsetWidth-this.overResizeWidth);
+}
+return (e.cellIndex>0)&&(e.cellX>=e.cellNode.offsetWidth-this.overResizeWidth)&&this.prepareResize(e,-1);
+},domousemove:function(e){
+var c=(this.overRightResizeArea(e)?"e-resize":(this.overLeftResizeArea(e)?"w-resize":""));
+if(c&&!this.canResize(e)){
+c="not-allowed";
+}
+e.sourceView.headerNode.style.cursor=c||"";
+if(c){
+dojo.stopEvent(e);
+}
+},domousedown:function(e){
+if(!dojox.grid.drag.dragging){
+if((this.overRightResizeArea(e)||this.overLeftResizeArea(e))&&this.canResize(e)){
+this.beginColumnResize(e);
+}else{
+this.grid.onMouseDown(e);
+this.grid.onMouseOverRow(e);
+}
+}
+},doclick:function(e){
+if(new Date().getTime()<this.bogusClickTime){
+dojo.stopEvent(e);
+return true;
+}
+},beginColumnResize:function(e){
+dojo.stopEvent(e);
+var _4e=[],_4f=this.tableMap.findOverlappingNodes(e.cellNode);
+for(var i=0,_51;(_51=_4f[i]);i++){
+_4e.push({node:_51,index:this.getCellNodeIndex(_51),width:_51.offsetWidth});
+}
+var _52={scrollLeft:e.sourceView.headerNode.scrollLeft,view:e.sourceView,node:e.cellNode,index:e.cellIndex,w:e.cellNode.clientWidth,spanners:_4e};
+dojox.grid.drag.start(e.cellNode,dojo.hitch(this,"doResizeColumn",_52),dojo.hitch(this,"endResizeColumn",_52),e);
+},doResizeColumn:function(_53,_54){
+var _55=dojo._isBodyLtr();
+if(_55){
+var w=_53.w+_54.deltaX;
+}else{
+var w=_53.w-_54.deltaX;
+}
+if(w>=this.minColWidth){
+for(var i=0,s,sw;(s=_53.spanners[i]);i++){
+if(_55){
+sw=s.width+_54.deltaX;
+}else{
+sw=s.width-_54.deltaX;
+}
+s.node.style.width=sw+"px";
+_53.view.setColWidth(s.index,sw);
+}
+_53.node.style.width=w+"px";
+_53.view.setColWidth(_53.index,w);
+if(!_55){
+_53.view.headerNode.scrollLeft=(_53.scrollLeft-_54.deltaX);
+}
+}
+if(_53.view.flexCells&&!_53.view.testFlexCells()){
+var t=dojox.grid.findTable(_53.node);
+t&&(t.style.width="");
+}
+},endResizeColumn:function(_5b){
+this.bogusClickTime=new Date().getTime()+30;
+setTimeout(dojo.hitch(_5b.view,"update"),50);
+}});
+dojo.declare("dojox.grid.tableMap",null,{constructor:function(_5c){
+this.mapRows(_5c);
+},map:null,mapRows:function(_5d){
+var _5e=_5d.length;
+if(!_5e){
+return;
+}
+this.map=[];
+for(var j=0,row;(row=_5d[j]);j++){
+this.map[j]=[];
+}
+for(var j=0,row;(row=_5d[j]);j++){
+for(var i=0,x=0,_63,_64,_65;(_63=row[i]);i++){
+while(this.map[j][x]){
+x++;
+}
+this.map[j][x]={c:i,r:j};
+_65=_63.rowSpan||1;
+_64=_63.colSpan||1;
+for(var y=0;y<_65;y++){
+for(var s=0;s<_64;s++){
+this.map[j+y][x+s]=this.map[j][x];
+}
+}
+x+=_64;
+}
+}
+},dumpMap:function(){
+for(var j=0,row,h="";(row=this.map[j]);j++,h=""){
+for(var i=0,_6c;(_6c=row[i]);i++){
+h+=_6c.r+","+_6c.c+"   ";
+}
+
+}
+},getMapCoords:function(_6d,_6e){
+for(var j=0,row;(row=this.map[j]);j++){
+for(var i=0,_72;(_72=row[i]);i++){
+if(_72.c==_6e&&_72.r==_6d){
+return {j:j,i:i};
+}
+}
+}
+return {j:-1,i:-1};
+},getNode:function(_73,_74,_75){
+var row=_73&&_73.rows[_74];
+return row&&row.cells[_75];
+},_findOverlappingNodes:function(_77,_78,_79){
+var _7a=[];
+var m=this.getMapCoords(_78,_79);
+var row=this.map[m.j];
+for(var j=0,row;(row=this.map[j]);j++){
+if(j==m.j){
+continue;
+}
+with(row[m.i]){
+var n=this.getNode(_77,r,c);
+if(n){
+_7a.push(n);
+}
+}
+}
+return _7a;
+},findOverlappingNodes:function(_7f){
+return this._findOverlappingNodes(dojox.grid.findTable(_7f),dojox.grid.getTrIndex(_7f.parentNode),dojox.grid.getTdIndex(_7f));
+}});
+dojox.grid.rowIndexTag="gridRowIndex";
+dojox.grid.gridViewTag="gridView";
+}
diff --git a/dojox/grid/compat/_grid/cell.js b/dojox/grid/compat/_grid/cell.js
new file mode 100644
index 0000000..e5e9faf
--- /dev/null
+++ b/dojox/grid/compat/_grid/cell.js
@@ -0,0 +1,44 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat._grid.cell"]){
+dojo._hasResource["dojox.grid.compat._grid.cell"]=true;
+dojo.provide("dojox.grid.compat._grid.cell");
+dojo.declare("dojox.grid.cell",null,{styles:"",constructor:function(_1){
+dojo.mixin(this,_1);
+if(this.editor){
+this.editor=new this.editor(this);
+}
+},format:function(_2){
+var f,i=this.grid.edit.info,d=this.get?this.get(_2):this.value;
+d=(d&&d.replace)?d.replace(/</g,"<"):d;
+if(this.editor&&(this.editor.alwaysOn||(i.rowIndex==_2&&i.cell==this))){
+return this.editor.format(d,_2);
+}else{
+return (f=this.formatter)?f.call(this,d,_2):d;
+}
+},getNode:function(_6){
+return this.view.getCellNode(_6,this.index);
+},isFlex:function(){
+var uw=this.unitWidth;
+return uw&&(uw=="auto"||uw.slice(-1)=="%");
+},applyEdit:function(_8,_9){
+this.grid.edit.applyCellEdit(_8,this,_9);
+},cancelEdit:function(_a){
+this.grid.doCancelEdit(_a);
+},_onEditBlur:function(_b){
+if(this.grid.edit.isEditCell(_b,this.index)){
+this.grid.edit.apply();
+}
+},registerOnBlur:function(_c,_d){
+if(this.commitOnBlur){
+dojo.connect(_c,"onblur",function(e){
+setTimeout(dojo.hitch(this,"_onEditBlur",_d),250);
+});
+}
+}});
+}
diff --git a/dojox/grid/compat/_grid/drag.js b/dojox/grid/compat/_grid/drag.js
new file mode 100644
index 0000000..ab33cd7
--- /dev/null
+++ b/dojox/grid/compat/_grid/drag.js
@@ -0,0 +1,91 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat._grid.drag"]){
+dojo._hasResource["dojox.grid.compat._grid.drag"]=true;
+dojo.provide("dojox.grid.compat._grid.drag");
+(function(){
+var _1=dojox.grid.drag={};
+_1.dragging=false;
+_1.hysteresis=2;
+_1.capture=function(_2){
+if(_2.setCapture){
+_2.setCapture();
+}else{
+document.addEventListener("mousemove",_2.onmousemove,true);
+document.addEventListener("mouseup",_2.onmouseup,true);
+document.addEventListener("click",_2.onclick,true);
+}
+};
+_1.release=function(_3){
+if(_3.releaseCapture){
+_3.releaseCapture();
+}else{
+document.removeEventListener("click",_3.onclick,true);
+document.removeEventListener("mouseup",_3.onmouseup,true);
+document.removeEventListener("mousemove",_3.onmousemove,true);
+}
+};
+_1.start=function(_4,_5,_6,_7,_8){
+if(!_4||_1.dragging){
+
+return;
+}
+_1.dragging=true;
+_1.elt=_4;
+_1.events={drag:_5||dojox.grid.nop,end:_6||dojox.grid.nop,start:_8||dojox.grid.nop,oldmove:_4.onmousemove,oldup:_4.onmouseup,oldclick:_4.onclick};
+_1.positionX=(_7&&("screenX" in _7)?_7.screenX:false);
+_1.positionY=(_7&&("screenY" in _7)?_7.screenY:false);
+_1.started=(_1.position===false);
+_4.onmousemove=_1.mousemove;
+_4.onmouseup=_1.mouseup;
+_4.onclick=_1.click;
+_1.capture(_1.elt);
+};
+_1.end=function(){
+_1.release(_1.elt);
+_1.elt.onmousemove=_1.events.oldmove;
+_1.elt.onmouseup=_1.events.oldup;
+_1.elt.onclick=_1.events.oldclick;
+_1.elt=null;
+try{
+if(_1.started){
+_1.events.end();
+}
+}
+finally{
+_1.dragging=false;
+}
+};
+_1.calcDelta=function(_9){
+_9.deltaX=_9.screenX-_1.positionX;
+_9.deltaY=_9.screenY-_1.positionY;
+};
+_1.hasMoved=function(_a){
+return Math.abs(_a.deltaX)+Math.abs(_a.deltaY)>_1.hysteresis;
+};
+_1.mousemove=function(_b){
+_b=dojo.fixEvent(_b);
+dojo.stopEvent(_b);
+_1.calcDelta(_b);
+if((!_1.started)&&(_1.hasMoved(_b))){
+_1.events.start(_b);
+_1.started=true;
+}
+if(_1.started){
+_1.events.drag(_b);
+}
+};
+_1.mouseup=function(_c){
+dojo.stopEvent(dojo.fixEvent(_c));
+_1.end();
+};
+_1.click=function(_d){
+dojo.stopEvent(dojo.fixEvent(_d));
+};
+})();
+}
diff --git a/dojox/grid/compat/_grid/edit.js b/dojox/grid/compat/_grid/edit.js
new file mode 100644
index 0000000..8ad756d
--- /dev/null
+++ b/dojox/grid/compat/_grid/edit.js
@@ -0,0 +1,128 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat._grid.edit"]){
+dojo._hasResource["dojox.grid.compat._grid.edit"]=true;
+dojo.provide("dojox.grid.compat._grid.edit");
+dojo.declare("dojox.grid.edit",null,{constructor:function(_1){
+this.grid=_1;
+this.connections=[];
+if(dojo.isIE){
+this.connections.push(dojo.connect(document.body,"onfocus",dojo.hitch(this,"_boomerangFocus")));
+}
+},info:{},destroy:function(){
+dojo.forEach(this.connections,dojo.disconnect);
+},cellFocus:function(_2,_3){
+if(this.grid.singleClickEdit||this.isEditRow(_3)){
+this.setEditCell(_2,_3);
+}else{
+this.apply();
+}
+if(this.isEditing()||(_2&&(_2.editor||0).alwaysOn)){
+this._focusEditor(_2,_3);
+}
+},rowClick:function(e){
+if(this.isEditing()&&!this.isEditRow(e.rowIndex)){
+this.apply();
+}
+},styleRow:function(_5){
+if(_5.index==this.info.rowIndex){
+_5.customClasses+=" dojoxGrid-row-editing";
+}
+},dispatchEvent:function(e){
+var c=e.cell,ed=c&&c.editor;
+return ed&&ed.dispatchEvent(e.dispatch,e);
+},isEditing:function(){
+return this.info.rowIndex!==undefined;
+},isEditCell:function(_9,_a){
+return (this.info.rowIndex===_9)&&(this.info.cell.index==_a);
+},isEditRow:function(_b){
+return this.info.rowIndex===_b;
+},setEditCell:function(_c,_d){
+if(!this.isEditCell(_d,_c.index)&&this.grid.canEdit(_c,_d)){
+this.start(_c,_d,this.isEditRow(_d)||_c.editor);
+}
+},_focusEditor:function(_e,_f){
+dojox.grid.fire(_e.editor,"focus",[_f]);
+},focusEditor:function(){
+if(this.isEditing()){
+this._focusEditor(this.info.cell,this.info.rowIndex);
+}
+},_boomerangWindow:500,_shouldCatchBoomerang:function(){
+return this._catchBoomerang>new Date().getTime();
+},_boomerangFocus:function(){
+if(this._shouldCatchBoomerang()){
+this.grid.focus.focusGrid();
+this.focusEditor();
+this._catchBoomerang=0;
+}
+},_doCatchBoomerang:function(){
+if(dojo.isIE){
+this._catchBoomerang=new Date().getTime()+this._boomerangWindow;
+}
+},start:function(_10,_11,_12){
+this.grid.beginUpdate();
+this.editorApply();
+if(this.isEditing()&&!this.isEditRow(_11)){
+this.applyRowEdit();
+this.grid.updateRow(_11);
+}
+if(_12){
+this.info={cell:_10,rowIndex:_11};
+this.grid.doStartEdit(_10,_11);
+this.grid.updateRow(_11);
+}else{
+this.info={};
+}
+this.grid.endUpdate();
+this.grid.focus.focusGrid();
+this._focusEditor(_10,_11);
+this._doCatchBoomerang();
+},_editorDo:function(_13){
+var c=this.info.cell;
+c&&c.editor&&c.editor[_13](this.info.rowIndex);
+},editorApply:function(){
+this._editorDo("apply");
+},editorCancel:function(){
+this._editorDo("cancel");
+},applyCellEdit:function(_15,_16,_17){
+if(this.grid.canEdit(_16,_17)){
+this.grid.doApplyCellEdit(_15,_17,_16.fieldIndex);
+}
+},applyRowEdit:function(){
+this.grid.doApplyEdit(this.info.rowIndex);
+},apply:function(){
+if(this.isEditing()){
+this.grid.beginUpdate();
+this.editorApply();
+this.applyRowEdit();
+this.info={};
+this.grid.endUpdate();
+this.grid.focus.focusGrid();
+this._doCatchBoomerang();
+}
+},cancel:function(){
+if(this.isEditing()){
+this.grid.beginUpdate();
+this.editorCancel();
+this.info={};
+this.grid.endUpdate();
+this.grid.focus.focusGrid();
+this._doCatchBoomerang();
+}
+},save:function(_18,_19){
+var c=this.info.cell;
+if(this.isEditRow(_18)&&(!_19||c.view==_19)&&c.editor){
+c.editor.save(c,this.info.rowIndex);
+}
+},restore:function(_1b,_1c){
+var c=this.info.cell;
+if(this.isEditRow(_1c)&&c.view==_1b&&c.editor){
+c.editor.restore(c,this.info.rowIndex);
+}
+}});
+}
diff --git a/dojox/grid/compat/_grid/focus.js b/dojox/grid/compat/_grid/focus.js
new file mode 100644
index 0000000..ceac6ec
--- /dev/null
+++ b/dojox/grid/compat/_grid/focus.js
@@ -0,0 +1,137 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat._grid.focus"]){
+dojo._hasResource["dojox.grid.compat._grid.focus"]=true;
+dojo.provide("dojox.grid.compat._grid.focus");
+dojo.declare("dojox.grid.focus",null,{constructor:function(_1){
+this.grid=_1;
+this.cell=null;
+this.rowIndex=-1;
+dojo.connect(this.grid.domNode,"onfocus",this,"doFocus");
+},tabbingOut:false,focusClass:"dojoxGrid-cell-focus",focusView:null,initFocusView:function(){
+this.focusView=this.grid.views.getFirstScrollingView();
+},isFocusCell:function(_2,_3){
+return (this.cell==_2)&&(this.rowIndex==_3);
+},isLastFocusCell:function(){
+return (this.rowIndex==this.grid.rowCount-1)&&(this.cell.index==this.grid.layout.cellCount-1);
+},isFirstFocusCell:function(){
+return (this.rowIndex==0)&&(this.cell.index==0);
+},isNoFocusCell:function(){
+return (this.rowIndex<0)||!this.cell;
+},_focusifyCellNode:function(_4){
+var n=this.cell&&this.cell.getNode(this.rowIndex);
+if(n){
+dojo.toggleClass(n,this.focusClass,_4);
+if(_4){
+this.scrollIntoView();
+try{
+if(!this.grid.edit.isEditing()){
+dojox.grid.fire(n,"focus");
+}
+}
+catch(e){
+}
+}
+}
+},scrollIntoView:function(){
+if(!this.cell){
+return;
+}
+var c=this.cell,s=c.view.scrollboxNode,sr={w:s.clientWidth,l:s.scrollLeft,t:s.scrollTop,h:s.clientHeight},n=c.getNode(this.rowIndex),r=c.view.getRowNode(this.rowIndex),rt=this.grid.scroller.findScrollTop(this.rowIndex);
+if(n.offsetLeft+n.offsetWidth>sr.l+sr.w){
+s.scrollLeft=n.offsetLeft+n.offsetWidth-sr.w;
+}else{
+if(n.offsetLeft<sr.l){
+s.scrollLeft=n.offsetLeft;
+}
+}
+if(rt+r.offsetHeight>sr.t+sr.h){
+this.grid.setScrollTop(rt+r.offsetHeight-sr.h);
+}else{
+if(rt<sr.t){
+this.grid.setScrollTop(rt);
+}
+}
+},styleRow:function(_c){
+return;
+},setFocusIndex:function(_d,_e){
+this.setFocusCell(this.grid.getCell(_e),_d);
+},setFocusCell:function(_f,_10){
+if(_f&&!this.isFocusCell(_f,_10)){
+this.tabbingOut=false;
+this.focusGridView();
+this._focusifyCellNode(false);
+this.cell=_f;
+this.rowIndex=_10;
+this._focusifyCellNode(true);
+}
+if(dojo.isOpera){
+setTimeout(dojo.hitch(this.grid,"onCellFocus",this.cell,this.rowIndex),1);
+}else{
+this.grid.onCellFocus(this.cell,this.rowIndex);
+}
+},next:function(){
+var row=this.rowIndex,col=this.cell.index+1,cc=this.grid.layout.cellCount-1,rc=this.grid.rowCount-1;
+if(col>cc){
+col=0;
+row++;
+}
+if(row>rc){
+col=cc;
+row=rc;
+}
+this.setFocusIndex(row,col);
+},previous:function(){
+var row=(this.rowIndex||0),col=(this.cell.index||0)-1;
+if(col<0){
+col=this.grid.layout.cellCount-1;
+row--;
+}
+if(row<0){
+row=0;
+col=0;
+}
+this.setFocusIndex(row,col);
+},move:function(_17,_18){
+var rc=this.grid.rowCount-1,cc=this.grid.layout.cellCount-1,r=this.rowIndex,i=this.cell.index,row=Math.min(rc,Math.max(0,r+_17)),col=Math.min(cc,Math.max(0,i+_18));
+this.setFocusIndex(row,col);
+if(_17){
+this.grid.updateRow(r);
+}
+},previousKey:function(e){
+if(this.isFirstFocusCell()){
+this.tabOut(this.grid.domNode);
+}else{
+dojo.stopEvent(e);
+this.previous();
+}
+},nextKey:function(e){
+if(this.isLastFocusCell()){
+this.tabOut(this.grid.lastFocusNode);
+}else{
+dojo.stopEvent(e);
+this.next();
+}
+},tabOut:function(_21){
+this.tabbingOut=true;
+_21.focus();
+},focusGridView:function(){
+dojox.grid.fire(this.focusView,"focus");
+},focusGrid:function(_22){
+this.focusGridView();
+this._focusifyCellNode(true);
+},doFocus:function(e){
+if(e&&e.target!=e.currentTarget){
+return;
+}
+if(!this.tabbingOut&&this.isNoFocusCell()){
+this.setFocusIndex(0,0);
+}
+this.tabbingOut=false;
+}});
+}
diff --git a/dojox/grid/compat/_grid/images/grid_dx_gradient.gif b/dojox/grid/compat/_grid/images/grid_dx_gradient.gif
new file mode 100644
index 0000000..57f67ba
Binary files /dev/null and b/dojox/grid/compat/_grid/images/grid_dx_gradient.gif differ
diff --git a/dojox/grid/compat/_grid/images/grid_sort_down.gif b/dojox/grid/compat/_grid/images/grid_sort_down.gif
new file mode 100644
index 0000000..7a73f82
Binary files /dev/null and b/dojox/grid/compat/_grid/images/grid_sort_down.gif differ
diff --git a/dojox/grid/compat/_grid/images/grid_sort_up.gif b/dojox/grid/compat/_grid/images/grid_sort_up.gif
new file mode 100644
index 0000000..9452da0
Binary files /dev/null and b/dojox/grid/compat/_grid/images/grid_sort_up.gif differ
diff --git a/dojox/grid/compat/_grid/images/tabEnabled_rotated.png b/dojox/grid/compat/_grid/images/tabEnabled_rotated.png
new file mode 100644
index 0000000..e326abd
Binary files /dev/null and b/dojox/grid/compat/_grid/images/tabEnabled_rotated.png differ
diff --git a/dojox/grid/compat/_grid/images/tabHover_rotated.png b/dojox/grid/compat/_grid/images/tabHover_rotated.png
new file mode 100644
index 0000000..1a30e10
Binary files /dev/null and b/dojox/grid/compat/_grid/images/tabHover_rotated.png differ
diff --git a/dojox/grid/compat/_grid/layout.js b/dojox/grid/compat/_grid/layout.js
new file mode 100644
index 0000000..61f99b9
--- /dev/null
+++ b/dojox/grid/compat/_grid/layout.js
@@ -0,0 +1,56 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat._grid.layout"]){
+dojo._hasResource["dojox.grid.compat._grid.layout"]=true;
+dojo.provide("dojox.grid.compat._grid.layout");
+dojo.require("dojox.grid.compat._grid.cell");
+dojo.declare("dojox.grid.layout",null,{constructor:function(_1){
+this.grid=_1;
+},cells:[],structure:null,defaultWidth:"6em",setStructure:function(_2){
+this.fieldIndex=0;
+this.cells=[];
+var s=this.structure=[];
+for(var i=0,_5,_6;(_5=_2[i]);i++){
+s.push(this.addViewDef(_5));
+}
+this.cellCount=this.cells.length;
+},addViewDef:function(_7){
+this._defaultCellProps=_7.defaultCell||{};
+return dojo.mixin({},_7,{rows:this.addRowsDef(_7.rows||_7.cells)});
+},addRowsDef:function(_8){
+var _9=[];
+for(var i=0,_b;_8&&(_b=_8[i]);i++){
+_9.push(this.addRowDef(i,_b));
+}
+return _9;
+},addRowDef:function(_c,_d){
+var _e=[];
+for(var i=0,def,_11;(def=_d[i]);i++){
+_11=this.addCellDef(_c,i,def);
+_e.push(_11);
+this.cells.push(_11);
+}
+return _e;
+},addCellDef:function(_12,_13,_14){
+var w=0;
+if(_14.colSpan>1){
+w=0;
+}else{
+if(!isNaN(_14.width)){
+w=_14.width+"em";
+}else{
+w=_14.width||this.defaultWidth;
+}
+}
+var _16=_14.field!=undefined?_14.field:(_14.get?-1:this.fieldIndex);
+if((_14.field!=undefined)||!_14.get){
+this.fieldIndex=(_14.field>-1?_14.field:this.fieldIndex)+1;
+}
+return new dojox.grid.cell(dojo.mixin({},this._defaultCellProps,_14,{grid:this.grid,subrow:_12,layoutIndex:_13,index:this.cells.length,fieldIndex:_16,unitWidth:w}));
+}});
+}
diff --git a/dojox/grid/compat/_grid/lib.js b/dojox/grid/compat/_grid/lib.js
new file mode 100644
index 0000000..b7be80c
--- /dev/null
+++ b/dojox/grid/compat/_grid/lib.js
@@ -0,0 +1,184 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat._grid.lib"]){
+dojo._hasResource["dojox.grid.compat._grid.lib"]=true;
+dojo.provide("dojox.grid.compat._grid.lib");
+dojo.mixin(dojox.grid,{na:"...",nop:function(){
+},getTdIndex:function(td){
+return td.cellIndex>=0?td.cellIndex:dojo.indexOf(td.parentNode.cells,td);
+},getTrIndex:function(tr){
+return tr.rowIndex>=0?tr.rowIndex:dojo.indexOf(tr.parentNode.childNodes,tr);
+},getTr:function(_3,_4){
+return _3&&((_3.rows||0)[_4]||_3.childNodes[_4]);
+},getTd:function(_5,_6,_7){
+return (dojox.grid.getTr(_5,_6)||0)[_7];
+},findTable:function(_8){
+for(var n=_8;n&&n.tagName!="TABLE";n=n.parentNode){
+}
+return n;
+},ascendDom:function(_a,_b){
+for(var n=_a;n&&_b(n);n=n.parentNode){
+}
+return n;
+},makeNotTagName:function(_d){
+var _e=_d.toUpperCase();
+return function(_f){
+return _f.tagName!=_e;
+};
+},fire:function(ob,ev,_12){
+var fn=ob&&ev&&ob[ev];
+return fn&&(_12?fn.apply(ob,_12):ob[ev]());
+},setStyleText:function(_14,_15){
+if(_14.style.cssText==undefined){
+_14.setAttribute("style",_15);
+}else{
+_14.style.cssText=_15;
+}
+},getStyleText:function(_16,_17){
+return (_16.style.cssText==undefined?_16.getAttribute("style"):_16.style.cssText);
+},setStyle:function(_18,_19,_1a){
+if(_18&&_18.style[_19]!=_1a){
+_18.style[_19]=_1a;
+}
+},setStyleHeightPx:function(_1b,_1c){
+if(_1c>=0){
+dojox.grid.setStyle(_1b,"height",_1c+"px");
+}
+},mouseEvents:["mouseover","mouseout","mousedown","mouseup","click","dblclick","contextmenu"],keyEvents:["keyup","keydown","keypress"],funnelEvents:function(_1d,_1e,_1f,_20){
+var _21=(_20?_20:dojox.grid.mouseEvents.concat(dojox.grid.keyEvents));
+for(var i=0,l=_21.length;i<l;i++){
+dojo.connect(_1d,"on"+_21[i],_1e,_1f);
+}
+},removeNode:function(_24){
+_24=dojo.byId(_24);
+_24&&_24.parentNode&&_24.parentNode.removeChild(_24);
+return _24;
+},getScrollbarWidth:function(){
+if(this._scrollBarWidth){
+return this._scrollBarWidth;
+}
+this._scrollBarWidth=18;
+try{
+var e=document.createElement("div");
+e.style.cssText="top:0;left:0;width:100px;height:100px;overflow:scroll;position:absolute;visibility:hidden;";
+document.body.appendChild(e);
+this._scrollBarWidth=e.offsetWidth-e.clientWidth;
+document.body.removeChild(e);
+delete e;
+}
+catch(ex){
+}
+return this._scrollBarWidth;
+},getRef:function(_26,_27,_28){
+var obj=_28||dojo.global,_2a=_26.split("."),_2b=_2a.pop();
+for(var i=0,p;obj&&(p=_2a[i]);i++){
+obj=(p in obj?obj[p]:(_27?obj[p]={}:undefined));
+}
+return {obj:obj,prop:_2b};
+},getProp:function(_2e,_2f,_30){
+with(dojox.grid.getRef(_2e,_2f,_30)){
+return (obj)&&(prop)&&(prop in obj?obj[prop]:(_2f?obj[prop]={}:undefined));
+}
+},indexInParent:function(_31){
+var i=0,n,p=_31.parentNode;
+while((n=p.childNodes[i++])){
+if(n==_31){
+return i-1;
+}
+}
+return -1;
+},cleanNode:function(_35){
+if(!_35){
+return;
+}
+var _36=function(inW){
+return inW.domNode&&dojo.isDescendant(inW.domNode,_35,true);
+};
+var ws=dijit.registry.filter(_36);
+for(var i=0,w;(w=ws[i]);i++){
+w.destroy();
+}
+delete ws;
+},getTagName:function(_3b){
+var _3c=dojo.byId(_3b);
+return (_3c&&_3c.tagName?_3c.tagName.toLowerCase():"");
+},nodeKids:function(_3d,_3e){
+var _3f=[];
+var i=0,n;
+while((n=_3d.childNodes[i++])){
+if(dojox.grid.getTagName(n)==_3e){
+_3f.push(n);
+}
+}
+return _3f;
+},divkids:function(_42){
+return dojox.grid.nodeKids(_42,"div");
+},focusSelectNode:function(_43){
+try{
+dojox.grid.fire(_43,"focus");
+dojox.grid.fire(_43,"select");
+}
+catch(e){
+}
+},whenIdle:function(){
+setTimeout(dojo.hitch.apply(dojo,arguments),0);
+},arrayCompare:function(inA,inB){
+for(var i=0,l=inA.length;i<l;i++){
+if(inA[i]!=inB[i]){
+return false;
+}
+}
+return (inA.length==inB.length);
+},arrayInsert:function(_48,_49,_4a){
+if(_48.length<=_49){
+_48[_49]=_4a;
+}else{
+_48.splice(_49,0,_4a);
+}
+},arrayRemove:function(_4b,_4c){
+_4b.splice(_4c,1);
+},arraySwap:function(_4d,inI,inJ){
+var _50=_4d[inI];
+_4d[inI]=_4d[inJ];
+_4d[inJ]=_50;
+},initTextSizePoll:function(_51){
+var f=document.createElement("div");
+with(f.style){
+top="0px";
+left="0px";
+position="absolute";
+visibility="hidden";
+}
+f.innerHTML="TheQuickBrownFoxJumpedOverTheLazyDog";
+document.body.appendChild(f);
+var fw=f.offsetWidth;
+var job=function(){
+if(f.offsetWidth!=fw){
+fw=f.offsetWidth;
+dojox.grid.textSizeChanged();
+}
+};
+window.setInterval(job,_51||200);
+dojox.grid.initTextSizePoll=dojox.grid.nop;
+},textSizeChanged:function(){
+}});
+dojox.grid.jobs={cancel:function(_55){
+if(_55){
+window.clearTimeout(_55);
+}
+},jobs:[],job:function(_56,_57,_58){
+dojox.grid.jobs.cancelJob(_56);
+var job=function(){
+delete dojox.grid.jobs.jobs[_56];
+_58();
+};
+dojox.grid.jobs.jobs[_56]=setTimeout(job,_57);
+},cancelJob:function(_5a){
+dojox.grid.jobs.cancel(dojox.grid.jobs.jobs[_5a]);
+}};
+}
diff --git a/dojox/grid/compat/_grid/nihiloGrid.css b/dojox/grid/compat/_grid/nihiloGrid.css
new file mode 100644
index 0000000..b96f410
--- /dev/null
+++ b/dojox/grid/compat/_grid/nihiloGrid.css
@@ -0,0 +1,211 @@
+.nihilo .dojoxGrid {
+	position: relative;
+	background-color: #e9e9e9;
+	font-size: 0.85em; 
+	-moz-outline-style: none;
+	outline: none;
+	overflow: hidden;
+	height: 0;
+}
+.nihilo .dojoxGrid table {
+	padding: 0;
+}
+.nihilo .dojoxGrid td {
+	-moz-outline: none;
+}
+.nihilo .dojoxGrid-master-header {
+	position: relative;
+}
+.nihilo .dojoxGrid-master-view  {
+	position: relative;
+}
+.nihilo .dojoxGrid-view {
+	position: absolute;
+	overflow: hidden;
+}
+.nihilo .dojoxGrid-header {
+	position: absolute;
+	overflow: hidden;
+}
+.nihilo .dojoxGrid-header {
+	background-color:  #e9e9e9;
+}
+.nihilo .dojoxGrid-header table {
+	text-align: center;
+}
+.nihilo .dojoxGrid-header .dojoxGrid-cell-content {
+	text-align: center;
+}
+.nihilo .dojoxGrid-header .dojoxGrid-cell { 
+	border: 1px solid transparent;
+	
+	border-color: white #ACA899 #919191 white;
+	background: url(../../../../dijit/themes/nihilo/images/titleBar.png) #e9e9e9 repeat-x top;
+	padding-bottom: 2px;
+	color: #000 !important;
+}
+.nihilo .dojoxGrid-header .dojoxGrid-cell-over {
+	background: url(../../../../dijit/themes/nihilo/images/titleBarActive.png) #e9e9e9 repeat-x top;
+}
+.nihilo .dojoxGrid-sort-down {
+	background: url(images/grid_sort_down.gif) right no-repeat;
+	padding-left: 0px;
+	margin-left: 0px;
+}
+.nihilo .dojoxGrid-sort-up {
+	background: url(images/grid_sort_up.gif) right no-repeat;
+	padding-left: 0px;
+	margin-left: 0px;
+}
+.nihilo .gridArrowButtonChar {
+	display:none !important;
+}
+.dijit_a11y .gridArrowButtonChar {
+	display:inline !important;
+}
+.nihilo .dojoxGrid-scrollbox {
+	position: relative;
+	overflow: scroll;
+	background-color: #fefefe;
+	width: 100%;
+}
+.nihilo .dojoxGrid-content {
+	position: relative;
+	overflow: hidden;
+	 -moz-outline-style: none;
+	outline: none;
+}
+.nihilo .dojoxGrid-rowbar { 
+	border: none;
+	
+	background: url(images/titleBar.png) #e9e9e9 repeat-y right;
+	border-right: 1px solid #cccccc;
+	padding: 0px;
+}
+.nihilo .dojoxGrid-rowbar-inner {
+	border: none;
+	border-bottom: 1px solid #cccccc;
+}
+.nihilo .dojoxGrid-rowbar-over {
+	background: url(images/titleBarActive.png) #e9e9e9 repeat-y right;
+}
+.nihilo .dojoxGrid-rowbar-selected {
+	background-color: #D9E8F9;
+	background-image: none;
+	background: url(../../../../dijit/themes/nihilo/images/titleBar.png) #dddddd repeat-x top;
+	border-right: 1px solid #cccccc;
+	background-position: center;
+	background-repeat: no-repeat;
+}
+.nihilo .dojoxGrid-row {
+	position: relative;
+	width: 9000em;
+}
+.nihilo .dojoxGrid-row {
+	border: none;
+	border-left: none;
+	border-right: none;
+	background-color: white;
+	border-top: none;
+}
+.nihilo .dojoxGrid-row-over {
+	border-top-color: #cccccc;
+	border-bottom-color: #cccccc;
+}
+.nihilo .dojoxGrid-row-over .dojoxGrid-cell {
+	background-color: #ffe284; 
+}
+.nihilo .dojoxGrid-row-odd {
+	background-color: #f2f5f9;
+	
+}
+.nihilo .dojoxGrid-row-selected {
+	background-color: #aec7e3;
+}
+.nihilo .dojoxGrid-row-table {
+	table-layout: fixed;
+	width: 0;
+	border-collapse: collapse;
+}
+.nihilo .dojoxGrid-invisible {
+	visibility: hidden;
+}		
+.nihilo .Xdojo-ie .dojoxGrid-invisible {
+	display: none;
+}		
+.nihilo .dojoxGrid-invisible td, .dojoxGrid-header .dojoxGrid-invisible td {
+	border-top-width: 0;
+	border-bottom-width: 0;
+	padding-top: 0;
+	padding-bottom: 0;
+	height: 0;
+	overflow: hidden;
+}
+.nihilo .dojoxGrid-cell {
+	border: 1px dotted #D5CDB5;
+	padding: 3px 3px 3px 3px;
+	text-align: left;
+	overflow: hidden;
+}
+.dj_ie6 .nihilo .dojoxGrid-cell {
+	border: 1px solid white;
+	border-right: 1px solid #D5CDB5;
+}
+.nihilo .dojoxGrid-cell-focus {
+	border: 1px dotted #a6a6a6;
+}
+.nihilo .dojoxGrid-cell-over {
+	border: 1px dotted #a6a6a6;
+}
+.nihilo .dojoxGrid-cell-focus.dojoxGrid-cell-over {
+	border: 1px dotted #595959;
+}
+.nihilo .dojoxGrid-cell-clip {
+	width: 100%;
+	overflow: hidden;
+	white-space:nowrap;
+	text-overflow: ellipsis;
+}
+.nihilo .dojoxGrid-row-editing td {
+	
+	background-color: #ffe284; 
+	
+}
+.nihilo .dojoxGrid-row-inserting td {
+	background-color: #F4FFF4;
+}
+.nihilo .dojoxGrid-row-inflight td {
+	background-color: #F2F7B7;
+}
+.nihilo .dojoxGrid-row-error td {
+	background-color: #F8B8B6;
+}
+.nihilo .dojoxGrid-input,
+.nihilo .dojoxGrid-select,
+.nihilo .dojoxGrid-textarea {
+	margin: 0;
+	padding: 0px;
+	border-style: none;
+	width: 100%;
+	font-size: 100%;
+	font-family: inherit;
+}
+.dojoxGrid-hidden-focus {
+	position: absolute;
+	left: -1000px;
+	top: -1000px;
+	height: 0px, width: 0px;
+}
+.dijit_a11y .dojoxGrid-rowbar-selected { 
+	border-top: 1px solid white;
+	border-bottom: 1px dashed black;
+	border-top: 0;
+	background: none;
+}
+.dijit_a11y .dojoxGrid-rowbar-selected .dojoxGrid-rowbar-inner {
+	border: 0;
+	border-top: 1px solid white;
+}
+.dijit_a11y .dojoxGrid-row-selected {
+	border-bottom: 1px dashed black;
+}
diff --git a/dojox/grid/compat/_grid/publicEvents.js b/dojox/grid/compat/_grid/publicEvents.js
new file mode 100644
index 0000000..945ba02
--- /dev/null
+++ b/dojox/grid/compat/_grid/publicEvents.js
@@ -0,0 +1,182 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat._grid.publicEvents"]){
+dojo._hasResource["dojox.grid.compat._grid.publicEvents"]=true;
+dojo.provide("dojox.grid.compat._grid.publicEvents");
+dojox.grid.publicEvents={cellOverClass:"dojoxGrid-cell-over",onKeyEvent:function(e){
+this.dispatchKeyEvent(e);
+},onContentEvent:function(e){
+this.dispatchContentEvent(e);
+},onHeaderEvent:function(e){
+this.dispatchHeaderEvent(e);
+},onStyleRow:function(_4){
+with(_4){
+customClasses+=(odd?" dojoxGrid-row-odd":"")+(selected?" dojoxGrid-row-selected":"")+(over?" dojoxGrid-row-over":"");
+}
+this.focus.styleRow(_4);
+this.edit.styleRow(_4);
+},onKeyDown:function(e){
+if(e.altKey||e.ctrlKey||e.metaKey){
+return;
+}
+var dk=dojo.keys;
+switch(e.keyCode){
+case dk.ESCAPE:
+this.edit.cancel();
+break;
+case dk.ENTER:
+if(!e.shiftKey){
+var _7=this.edit.isEditing();
+this.edit.apply();
+if(!_7){
+this.edit.setEditCell(this.focus.cell,this.focus.rowIndex);
+}
+}
+break;
+case dk.TAB:
+this.focus[e.shiftKey?"previousKey":"nextKey"](e);
+break;
+case dk.LEFT_ARROW:
+case dk.RIGHT_ARROW:
+if(!this.edit.isEditing()){
+dojo.stopEvent(e);
+var _8=(e.keyCode==dk.LEFT_ARROW)?1:-1;
+if(dojo._isBodyLtr()){
+_8*=-1;
+}
+this.focus.move(0,_8);
+}
+break;
+case dk.UP_ARROW:
+if(!this.edit.isEditing()&&this.focus.rowIndex!=0){
+dojo.stopEvent(e);
+this.focus.move(-1,0);
+}
+break;
+case dk.DOWN_ARROW:
+if(!this.edit.isEditing()&&this.focus.rowIndex+1!=this.model.count){
+dojo.stopEvent(e);
+this.focus.move(1,0);
+}
+break;
+case dk.PAGE_UP:
+if(!this.edit.isEditing()&&this.focus.rowIndex!=0){
+dojo.stopEvent(e);
+if(this.focus.rowIndex!=this.scroller.firstVisibleRow+1){
+this.focus.move(this.scroller.firstVisibleRow-this.focus.rowIndex,0);
+}else{
+this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex-1));
+this.focus.move(this.scroller.firstVisibleRow-this.scroller.lastVisibleRow+1,0);
+}
+}
+break;
+case dk.PAGE_DOWN:
+if(!this.edit.isEditing()&&this.focus.rowIndex+1!=this.model.count){
+dojo.stopEvent(e);
+if(this.focus.rowIndex!=this.scroller.lastVisibleRow-1){
+this.focus.move(this.scroller.lastVisibleRow-this.focus.rowIndex-1,0);
+}else{
+this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex+1));
+this.focus.move(this.scroller.lastVisibleRow-this.scroller.firstVisibleRow-1,0);
+}
+}
+break;
+}
+},onMouseOver:function(e){
+e.rowIndex==-1?this.onHeaderCellMouseOver(e):this.onCellMouseOver(e);
+},onMouseOut:function(e){
+e.rowIndex==-1?this.onHeaderCellMouseOut(e):this.onCellMouseOut(e);
+},onMouseDown:function(e){
+e.rowIndex==-1?this.onHeaderCellMouseDown(e):this.onCellMouseDown(e);
+},onMouseOverRow:function(e){
+if(!this.rows.isOver(e.rowIndex)){
+this.rows.setOverRow(e.rowIndex);
+e.rowIndex==-1?this.onHeaderMouseOver(e):this.onRowMouseOver(e);
+}
+},onMouseOutRow:function(e){
+if(this.rows.isOver(-1)){
+this.onHeaderMouseOut(e);
+}else{
+if(!this.rows.isOver(-2)){
+this.rows.setOverRow(-2);
+this.onRowMouseOut(e);
+}
+}
+},onMouseDownRow:function(e){
+if(e.rowIndex!=-1){
+this.onRowMouseDown(e);
+}
+},onCellMouseOver:function(e){
+dojo.addClass(e.cellNode,this.cellOverClass);
+},onCellMouseOut:function(e){
+dojo.removeClass(e.cellNode,this.cellOverClass);
+},onCellMouseDown:function(e){
+},onCellClick:function(e){
+this._click[0]=this._click[1];
+this._click[1]=e;
+if(!this.edit.isEditCell(e.rowIndex,e.cellIndex)){
+this.focus.setFocusCell(e.cell,e.rowIndex);
+}
+this.onRowClick(e);
+},onCellDblClick:function(e){
+if(dojo.isIE){
+this.edit.setEditCell(this._click[1].cell,this._click[1].rowIndex);
+}else{
+if(this._click[0].rowIndex!=this._click[1].rowIndex){
+this.edit.setEditCell(this._click[0].cell,this._click[0].rowIndex);
+}else{
+this.edit.setEditCell(e.cell,e.rowIndex);
+}
+}
+this.onRowDblClick(e);
+},onCellContextMenu:function(e){
+this.onRowContextMenu(e);
+},onCellFocus:function(_15,_16){
+this.edit.cellFocus(_15,_16);
+},onRowClick:function(e){
+this.edit.rowClick(e);
+this.selection.clickSelectEvent(e);
+},onRowDblClick:function(e){
+},onRowMouseOver:function(e){
+},onRowMouseOut:function(e){
+},onRowMouseDown:function(e){
+},onRowContextMenu:function(e){
+dojo.stopEvent(e);
+},onHeaderMouseOver:function(e){
+},onHeaderMouseOut:function(e){
+},onHeaderCellMouseOver:function(e){
+dojo.addClass(e.cellNode,this.cellOverClass);
+},onHeaderCellMouseOut:function(e){
+dojo.removeClass(e.cellNode,this.cellOverClass);
+},onHeaderCellMouseDown:function(e){
+},onHeaderClick:function(e){
+},onHeaderCellClick:function(e){
+this.setSortIndex(e.cell.index);
+this.onHeaderClick(e);
+},onHeaderDblClick:function(e){
+},onHeaderCellDblClick:function(e){
+this.onHeaderDblClick(e);
+},onHeaderCellContextMenu:function(e){
+this.onHeaderContextMenu(e);
+},onHeaderContextMenu:function(e){
+dojo.stopEvent(e);
+},onStartEdit:function(_28,_29){
+},onApplyCellEdit:function(_2a,_2b,_2c){
+},onCancelEdit:function(_2d){
+},onApplyEdit:function(_2e){
+},onCanSelect:function(_2f){
+return true;
+},onCanDeselect:function(_30){
+return true;
+},onSelected:function(_31){
+this.updateRowStyles(_31);
+},onDeselected:function(_32){
+this.updateRowStyles(_32);
+},onSelectionChanged:function(){
+}};
+}
diff --git a/dojox/grid/compat/_grid/rowbar.js b/dojox/grid/compat/_grid/rowbar.js
new file mode 100644
index 0000000..d7e7c73
--- /dev/null
+++ b/dojox/grid/compat/_grid/rowbar.js
@@ -0,0 +1,41 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat._grid.rowbar"]){
+dojo._hasResource["dojox.grid.compat._grid.rowbar"]=true;
+dojo.provide("dojox.grid.compat._grid.rowbar");
+dojo.require("dojox.grid.compat._grid.view");
+dojo.declare("dojox.GridRowView",dojox.GridView,{defaultWidth:"3em",noscroll:true,padBorderWidth:2,buildRendering:function(){
+this.inherited("buildRendering",arguments);
+this.scrollboxNode.style.overflow="hidden";
+this.headerNode.style.visibility="hidden";
+},getWidth:function(){
+return this.viewWidth||this.defaultWidth;
+},buildRowContent:function(_1,_2){
+var w=this.contentNode.offsetWidth-this.padBorderWidth;
+_2.innerHTML="<table style=\"width:"+w+"px;\" role=\"wairole:presentation\"><tr><td class=\"dojoxGrid-rowbar-inner\"></td></tr></table>";
+},renderHeader:function(){
+},resize:function(){
+this.adaptHeight();
+},adaptWidth:function(){
+},doStyleRowNode:function(_4,_5){
+var n=["dojoxGrid-rowbar"];
+if(this.grid.rows.isOver(_4)){
+n.push("dojoxGrid-rowbar-over");
+}
+if(this.grid.selection.isSelected(_4)){
+n.push("dojoxGrid-rowbar-selected");
+}
+_5.className=n.join(" ");
+},domouseover:function(e){
+this.grid.onMouseOverRow(e);
+},domouseout:function(e){
+if(!this.isIntraRowEvent(e)){
+this.grid.onMouseOutRow(e);
+}
+}});
+}
diff --git a/dojox/grid/compat/_grid/rows.js b/dojox/grid/compat/_grid/rows.js
new file mode 100644
index 0000000..fc36372
--- /dev/null
+++ b/dojox/grid/compat/_grid/rows.js
@@ -0,0 +1,42 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat._grid.rows"]){
+dojo._hasResource["dojox.grid.compat._grid.rows"]=true;
+dojo.provide("dojox.grid.compat._grid.rows");
+dojo.declare("dojox.grid.rows",null,{constructor:function(_1){
+this.grid=_1;
+},linesToEms:2,defaultRowHeight:1,overRow:-2,getHeight:function(_2){
+return "";
+},getDefaultHeightPx:function(){
+return 32;
+},prepareStylingRow:function(_3,_4){
+return {index:_3,node:_4,odd:Boolean(_3&1),selected:this.grid.selection.isSelected(_3),over:this.isOver(_3),customStyles:"",customClasses:"dojoxGrid-row"};
+},styleRowNode:function(_5,_6){
+var _7=this.prepareStylingRow(_5,_6);
+this.grid.onStyleRow(_7);
+this.applyStyles(_7);
+},applyStyles:function(_8){
+with(_8){
+node.className=customClasses;
+var h=node.style.height;
+dojox.grid.setStyleText(node,customStyles+";"+(node._style||""));
+node.style.height=h;
+}
+},updateStyles:function(_a){
+this.grid.updateRowStyles(_a);
+},setOverRow:function(_b){
+var _c=this.overRow;
+this.overRow=_b;
+if((_c!=this.overRow)&&(_c>=0)){
+this.updateStyles(_c);
+}
+this.updateStyles(this.overRow);
+},isOver:function(_d){
+return (this.overRow==_d);
+}});
+}
diff --git a/dojox/grid/compat/_grid/scroller.js b/dojox/grid/compat/_grid/scroller.js
new file mode 100644
index 0000000..7ed90fe
--- /dev/null
+++ b/dojox/grid/compat/_grid/scroller.js
@@ -0,0 +1,373 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat._grid.scroller"]){
+dojo._hasResource["dojox.grid.compat._grid.scroller"]=true;
+dojo.provide("dojox.grid.compat._grid.scroller");
+dojo.declare("dojox.grid.scroller.base",null,{constructor:function(){
+this.pageHeights=[];
+this.stack=[];
+},rowCount:0,defaultRowHeight:10,keepRows:100,contentNode:null,scrollboxNode:null,defaultPageHeight:0,keepPages:10,pageCount:0,windowHeight:0,firstVisibleRow:0,lastVisibleRow:0,page:0,pageTop:0,init:function(_1,_2,_3){
+switch(arguments.length){
+case 3:
+this.rowsPerPage=_3;
+case 2:
+this.keepRows=_2;
+case 1:
+this.rowCount=_1;
+}
+this.defaultPageHeight=this.defaultRowHeight*this.rowsPerPage;
+this.pageCount=Math.ceil(this.rowCount/this.rowsPerPage);
+this.setKeepInfo(this.keepRows);
+this.invalidate();
+if(this.scrollboxNode){
+this.scrollboxNode.scrollTop=0;
+this.scroll(0);
+this.scrollboxNode.onscroll=dojo.hitch(this,"onscroll");
+}
+},setKeepInfo:function(_4){
+this.keepRows=_4;
+this.keepPages=!this.keepRows?this.keepRows:Math.max(Math.ceil(this.keepRows/this.rowsPerPage),2);
+},invalidate:function(){
+this.invalidateNodes();
+this.pageHeights=[];
+this.height=(this.pageCount?(this.pageCount-1)*this.defaultPageHeight+this.calcLastPageHeight():0);
+this.resize();
+},updateRowCount:function(_5){
+this.invalidateNodes();
+this.rowCount=_5;
+var _6=this.pageCount;
+this.pageCount=Math.ceil(this.rowCount/this.rowsPerPage);
+if(this.pageCount<_6){
+for(var i=_6-1;i>=this.pageCount;i--){
+this.height-=this.getPageHeight(i);
+delete this.pageHeights[i];
+}
+}else{
+if(this.pageCount>_6){
+this.height+=this.defaultPageHeight*(this.pageCount-_6-1)+this.calcLastPageHeight();
+}
+}
+this.resize();
+},pageExists:function(_8){
+},measurePage:function(_9){
+},positionPage:function(_a,_b){
+},repositionPages:function(_c){
+},installPage:function(_d){
+},preparePage:function(_e,_f,_10){
+},renderPage:function(_11){
+},removePage:function(_12){
+},pacify:function(_13){
+},pacifying:false,pacifyTicks:200,setPacifying:function(_14){
+if(this.pacifying!=_14){
+this.pacifying=_14;
+this.pacify(this.pacifying);
+}
+},startPacify:function(){
+this.startPacifyTicks=new Date().getTime();
+},doPacify:function(){
+var _15=(new Date().getTime()-this.startPacifyTicks)>this.pacifyTicks;
+this.setPacifying(true);
+this.startPacify();
+return _15;
+},endPacify:function(){
+this.setPacifying(false);
+},resize:function(){
+if(this.scrollboxNode){
+this.windowHeight=this.scrollboxNode.clientHeight;
+}
+dojox.grid.setStyleHeightPx(this.contentNode,this.height);
+},calcLastPageHeight:function(){
+if(!this.pageCount){
+return 0;
+}
+var _16=this.pageCount-1;
+var _17=((this.rowCount%this.rowsPerPage)||(this.rowsPerPage))*this.defaultRowHeight;
+this.pageHeights[_16]=_17;
+return _17;
+},updateContentHeight:function(_18){
+this.height+=_18;
+this.resize();
+},updatePageHeight:function(_19){
+if(this.pageExists(_19)){
+var oh=this.getPageHeight(_19);
+var h=(this.measurePage(_19))||(oh);
+this.pageHeights[_19]=h;
+if((h)&&(oh!=h)){
+this.updateContentHeight(h-oh);
+this.repositionPages(_19);
+}
+}
+},rowHeightChanged:function(_1c){
+this.updatePageHeight(Math.floor(_1c/this.rowsPerPage));
+},invalidateNodes:function(){
+while(this.stack.length){
+this.destroyPage(this.popPage());
+}
+},createPageNode:function(){
+var p=document.createElement("div");
+p.style.position="absolute";
+p.style[dojo._isBodyLtr()?"left":"right"]="0";
+return p;
+},getPageHeight:function(_1e){
+var ph=this.pageHeights[_1e];
+return (ph!==undefined?ph:this.defaultPageHeight);
+},pushPage:function(_20){
+return this.stack.push(_20);
+},popPage:function(){
+return this.stack.shift();
+},findPage:function(_21){
+var i=0,h=0;
+for(var ph=0;i<this.pageCount;i++,h+=ph){
+ph=this.getPageHeight(i);
+if(h+ph>=_21){
+break;
+}
+}
+this.page=i;
+this.pageTop=h;
+},buildPage:function(_25,_26,_27){
+this.preparePage(_25,_26);
+this.positionPage(_25,_27);
+this.installPage(_25);
+this.renderPage(_25);
+this.pushPage(_25);
+},needPage:function(_28,_29){
+var h=this.getPageHeight(_28),oh=h;
+if(!this.pageExists(_28)){
+this.buildPage(_28,this.keepPages&&(this.stack.length>=this.keepPages),_29);
+h=this.measurePage(_28)||h;
+this.pageHeights[_28]=h;
+if(h&&(oh!=h)){
+this.updateContentHeight(h-oh);
+}
+}else{
+this.positionPage(_28,_29);
+}
+return h;
+},onscroll:function(){
+this.scroll(this.scrollboxNode.scrollTop);
+},scroll:function(_2c){
+this.startPacify();
+this.findPage(_2c);
+var h=this.height;
+var b=this.getScrollBottom(_2c);
+for(var p=this.page,y=this.pageTop;(p<this.pageCount)&&((b<0)||(y<b));p++){
+y+=this.needPage(p,y);
+}
+this.firstVisibleRow=this.getFirstVisibleRow(this.page,this.pageTop,_2c);
+this.lastVisibleRow=this.getLastVisibleRow(p-1,y,b);
+if(h!=this.height){
+this.repositionPages(p-1);
+}
+this.endPacify();
+},getScrollBottom:function(_31){
+return (this.windowHeight>=0?_31+this.windowHeight:-1);
+},processNodeEvent:function(e,_33){
+var t=e.target;
+while(t&&(t!=_33)&&t.parentNode&&(t.parentNode.parentNode!=_33)){
+t=t.parentNode;
+}
+if(!t||!t.parentNode||(t.parentNode.parentNode!=_33)){
+return false;
+}
+var _35=t.parentNode;
+e.topRowIndex=_35.pageIndex*this.rowsPerPage;
+e.rowIndex=e.topRowIndex+dojox.grid.indexInParent(t);
+e.rowTarget=t;
+return true;
+},processEvent:function(e){
+return this.processNodeEvent(e,this.contentNode);
+},dummy:0});
+dojo.declare("dojox.grid.scroller",dojox.grid.scroller.base,{constructor:function(){
+this.pageNodes=[];
+},renderRow:function(_37,_38){
+},removeRow:function(_39){
+},getDefaultNodes:function(){
+return this.pageNodes;
+},getDefaultPageNode:function(_3a){
+return this.getDefaultNodes()[_3a];
+},positionPageNode:function(_3b,_3c){
+_3b.style.top=_3c+"px";
+},getPageNodePosition:function(_3d){
+return _3d.offsetTop;
+},repositionPageNodes:function(_3e,_3f){
+var _40=0;
+for(var i=0;i<this.stack.length;i++){
+_40=Math.max(this.stack[i],_40);
+}
+var n=_3f[_3e];
+var y=(n?this.getPageNodePosition(n)+this.getPageHeight(_3e):0);
+for(var p=_3e+1;p<=_40;p++){
+n=_3f[p];
+if(n){
+if(this.getPageNodePosition(n)==y){
+return;
+}
+this.positionPage(p,y);
+}
+y+=this.getPageHeight(p);
+}
+},invalidatePageNode:function(_45,_46){
+var p=_46[_45];
+if(p){
+delete _46[_45];
+this.removePage(_45,p);
+dojox.grid.cleanNode(p);
+p.innerHTML="";
+}
+return p;
+},preparePageNode:function(_48,_49,_4a){
+var p=(_49===null?this.createPageNode():this.invalidatePageNode(_49,_4a));
+p.pageIndex=_48;
+p.id=(this._pageIdPrefix||"")+"page-"+_48;
+_4a[_48]=p;
+},pageExists:function(_4c){
+return Boolean(this.getDefaultPageNode(_4c));
+},measurePage:function(_4d){
+var p=this.getDefaultPageNode(_4d);
+var h=p.offsetHeight;
+if(!this._defaultRowHeight){
+if(p){
+this._defaultRowHeight=8;
+var fr=p.firstChild;
+if(fr){
+var _51=dojo.doc.createTextNode("T");
+fr.appendChild(_51);
+this._defaultRowHeight=fr.offsetHeight;
+fr.removeChild(_51);
+}
+}
+}
+return (this.rowsPerPage==h)?(h*this._defaultRowHeight):h;
+},positionPage:function(_52,_53){
+this.positionPageNode(this.getDefaultPageNode(_52),_53);
+},repositionPages:function(_54){
+this.repositionPageNodes(_54,this.getDefaultNodes());
+},preparePage:function(_55,_56){
+this.preparePageNode(_55,(_56?this.popPage():null),this.getDefaultNodes());
+},installPage:function(_57){
+this.contentNode.appendChild(this.getDefaultPageNode(_57));
+},destroyPage:function(_58){
+var p=this.invalidatePageNode(_58,this.getDefaultNodes());
+dojox.grid.removeNode(p);
+},renderPage:function(_5a){
+var _5b=this.pageNodes[_5a];
+for(var i=0,j=_5a*this.rowsPerPage;(i<this.rowsPerPage)&&(j<this.rowCount);i++,j++){
+this.renderRow(j,_5b);
+}
+},removePage:function(_5e){
+for(var i=0,j=_5e*this.rowsPerPage;i<this.rowsPerPage;i++,j++){
+this.removeRow(j);
+}
+},getPageRow:function(_61){
+return _61*this.rowsPerPage;
+},getLastPageRow:function(_62){
+return Math.min(this.rowCount,this.getPageRow(_62+1))-1;
+},getFirstVisibleRowNodes:function(_63,_64,_65,_66){
+var row=this.getPageRow(_63);
+var _68=dojox.grid.divkids(_66[_63]);
+for(var i=0,l=_68.length;i<l&&_64<_65;i++,row++){
+_64+=_68[i].offsetHeight;
+}
+return (row?row-1:row);
+},getFirstVisibleRow:function(_6b,_6c,_6d){
+if(!this.pageExists(_6b)){
+return 0;
+}
+return this.getFirstVisibleRowNodes(_6b,_6c,_6d,this.getDefaultNodes());
+},getLastVisibleRowNodes:function(_6e,_6f,_70,_71){
+var row=this.getLastPageRow(_6e);
+var _73=dojox.grid.divkids(_71[_6e]);
+for(var i=_73.length-1;i>=0&&_6f>_70;i--,row--){
+_6f-=_73[i].offsetHeight;
+}
+return row+1;
+},getLastVisibleRow:function(_75,_76,_77){
+if(!this.pageExists(_75)){
+return 0;
+}
+return this.getLastVisibleRowNodes(_75,_76,_77,this.getDefaultNodes());
+},findTopRowForNodes:function(_78,_79){
+var _7a=dojox.grid.divkids(_79[this.page]);
+for(var i=0,l=_7a.length,t=this.pageTop,h;i<l;i++){
+h=_7a[i].offsetHeight;
+t+=h;
+if(t>=_78){
+this.offset=h-(t-_78);
+return i+this.page*this.rowsPerPage;
+}
+}
+return -1;
+},findScrollTopForNodes:function(_7f,_80){
+var _81=Math.floor(_7f/this.rowsPerPage);
+var t=0;
+for(var i=0;i<_81;i++){
+t+=this.getPageHeight(i);
+}
+this.pageTop=t;
+this.needPage(_81,this.pageTop);
+var _84=dojox.grid.divkids(_80[_81]);
+var r=_7f-this.rowsPerPage*_81;
+for(var i=0,l=_84.length;i<l&&i<r;i++){
+t+=_84[i].offsetHeight;
+}
+return t;
+},findTopRow:function(_87){
+return this.findTopRowForNodes(_87,this.getDefaultNodes());
+},findScrollTop:function(_88){
+return this.findScrollTopForNodes(_88,this.getDefaultNodes());
+},dummy:0});
+dojo.declare("dojox.grid.scroller.columns",dojox.grid.scroller,{constructor:function(_89){
+this.setContentNodes(_89);
+},setContentNodes:function(_8a){
+this.contentNodes=_8a;
+this.colCount=(this.contentNodes?this.contentNodes.length:0);
+this.pageNodes=[];
+for(var i=0;i<this.colCount;i++){
+this.pageNodes[i]=[];
+}
+},getDefaultNodes:function(){
+return this.pageNodes[0]||[];
+},scroll:function(_8c){
+if(this.colCount){
+dojox.grid.scroller.prototype.scroll.call(this,_8c);
+}
+},resize:function(){
+if(this.scrollboxNode){
+this.windowHeight=this.scrollboxNode.clientHeight;
+}
+for(var i=0;i<this.colCount;i++){
+dojox.grid.setStyleHeightPx(this.contentNodes[i],this.height);
+}
+},positionPage:function(_8e,_8f){
+for(var i=0;i<this.colCount;i++){
+this.positionPageNode(this.pageNodes[i][_8e],_8f);
+}
+},preparePage:function(_91,_92){
+var p=(_92?this.popPage():null);
+for(var i=0;i<this.colCount;i++){
+this.preparePageNode(_91,p,this.pageNodes[i]);
+}
+},installPage:function(_95){
+for(var i=0;i<this.colCount;i++){
+this.contentNodes[i].appendChild(this.pageNodes[i][_95]);
+}
+},destroyPage:function(_97){
+for(var i=0;i<this.colCount;i++){
+dojox.grid.removeNode(this.invalidatePageNode(_97,this.pageNodes[i]));
+}
+},renderPage:function(_99){
+var _9a=[];
+for(var i=0;i<this.colCount;i++){
+_9a[i]=this.pageNodes[i][_99];
+}
+for(var i=0,j=_99*this.rowsPerPage;(i<this.rowsPerPage)&&(j<this.rowCount);i++,j++){
+this.renderRow(j,_9a);
+}
+}});
+}
diff --git a/dojox/grid/compat/_grid/selection.js b/dojox/grid/compat/_grid/selection.js
new file mode 100644
index 0000000..fa636ca
--- /dev/null
+++ b/dojox/grid/compat/_grid/selection.js
@@ -0,0 +1,153 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat._grid.selection"]){
+dojo._hasResource["dojox.grid.compat._grid.selection"]=true;
+dojo.provide("dojox.grid.compat._grid.selection");
+dojo.declare("dojox.grid.selection",null,{constructor:function(_1){
+this.grid=_1;
+this.selected=[];
+},multiSelect:true,selected:null,updating:0,selectedIndex:-1,onCanSelect:function(_2){
+return this.grid.onCanSelect(_2);
+},onCanDeselect:function(_3){
+return this.grid.onCanDeselect(_3);
+},onSelected:function(_4){
+return this.grid.onSelected(_4);
+},onDeselected:function(_5){
+return this.grid.onDeselected(_5);
+},onChanging:function(){
+},onChanged:function(){
+return this.grid.onSelectionChanged();
+},isSelected:function(_6){
+return this.selected[_6];
+},getFirstSelected:function(){
+for(var i=0,l=this.selected.length;i<l;i++){
+if(this.selected[i]){
+return i;
+}
+}
+return -1;
+},getNextSelected:function(_9){
+for(var i=_9+1,l=this.selected.length;i<l;i++){
+if(this.selected[i]){
+return i;
+}
+}
+return -1;
+},getSelected:function(){
+var _c=[];
+for(var i=0,l=this.selected.length;i<l;i++){
+if(this.selected[i]){
+_c.push(i);
+}
+}
+return _c;
+},getSelectedCount:function(){
+var c=0;
+for(var i=0;i<this.selected.length;i++){
+if(this.selected[i]){
+c++;
+}
+}
+return c;
+},beginUpdate:function(){
+if(this.updating==0){
+this.onChanging();
+}
+this.updating++;
+},endUpdate:function(){
+this.updating--;
+if(this.updating==0){
+this.onChanged();
+}
+},select:function(_11){
+this.unselectAll(_11);
+this.addToSelection(_11);
+},addToSelection:function(_12){
+_12=Number(_12);
+if(this.selected[_12]){
+this.selectedIndex=_12;
+}else{
+if(this.onCanSelect(_12)!==false){
+this.selectedIndex=_12;
+this.beginUpdate();
+this.selected[_12]=true;
+this.grid.onSelected(_12);
+this.endUpdate();
+}
+}
+},deselect:function(_13){
+_13=Number(_13);
+if(this.selectedIndex==_13){
+this.selectedIndex=-1;
+}
+if(this.selected[_13]){
+if(this.onCanDeselect(_13)===false){
+return;
+}
+this.beginUpdate();
+delete this.selected[_13];
+this.grid.onDeselected(_13);
+this.endUpdate();
+}
+},setSelected:function(_14,_15){
+this[(_15?"addToSelection":"deselect")](_14);
+},toggleSelect:function(_16){
+this.setSelected(_16,!this.selected[_16]);
+},insert:function(_17){
+this.selected.splice(_17,0,false);
+if(this.selectedIndex>=_17){
+this.selectedIndex++;
+}
+},remove:function(_18){
+this.selected.splice(_18,1);
+if(this.selectedIndex>=_18){
+this.selectedIndex--;
+}
+},unselectAll:function(_19){
+for(var i in this.selected){
+if((i!=_19)&&(this.selected[i]===true)){
+this.deselect(i);
+}
+}
+},shiftSelect:function(_1b,_1c){
+var s=(_1b>=0?_1b:_1c),e=_1c;
+if(s>e){
+e=s;
+s=_1c;
+}
+for(var i=s;i<=e;i++){
+this.addToSelection(i);
+}
+},clickSelect:function(_20,_21,_22){
+this.beginUpdate();
+if(!this.multiSelect){
+this.select(_20);
+}else{
+var _23=this.selectedIndex;
+if(!_21){
+this.unselectAll(_20);
+}
+if(_22){
+this.shiftSelect(_23,_20);
+}else{
+if(_21){
+this.toggleSelect(_20);
+}else{
+this.addToSelection(_20);
+}
+}
+}
+this.endUpdate();
+},clickSelectEvent:function(e){
+this.clickSelect(e.rowIndex,dojo.dnd.getCopyKeyState(e),e.shiftKey);
+},clear:function(){
+this.beginUpdate();
+this.unselectAll();
+this.endUpdate();
+}});
+}
diff --git a/dojox/grid/compat/_grid/soriaGrid.css b/dojox/grid/compat/_grid/soriaGrid.css
new file mode 100644
index 0000000..96e80d2
--- /dev/null
+++ b/dojox/grid/compat/_grid/soriaGrid.css
@@ -0,0 +1,212 @@
+.soria .dojoxGrid {
+	position: relative;
+	background-color: #e9e9e9;
+	font-size: 0.85em; 
+	-moz-outline-style: none;
+	outline: none;
+	overflow: hidden;
+	height: 0;
+}
+.soria .dojoxGrid table {
+	padding: 0;
+}
+.soria .dojoxGrid td {
+	-moz-outline: none;
+}
+.soria .dojoxGrid-master-header {
+	position: relative;
+}
+.soria .dojoxGrid-master-view  {
+	position: relative;
+}
+.soria .dojoxGrid-view {
+	position: absolute;
+	overflow: hidden;
+}
+.soria .dojoxGrid-header {
+	position: absolute;
+	overflow: hidden;
+}
+.soria .dojoxGrid-header {
+	background-color:  #e9e9e9;
+}
+.soria .dojoxGrid-header table {
+	text-align: center;
+}
+.soria .dojoxGrid-header .dojoxGrid-cell-content {
+	text-align: center;
+}
+.soria .dojoxGrid-header .dojoxGrid-cell { 
+	border: 1px solid transparent;
+	
+	border-color: white #ACA899 #919191 white;
+	background: url(../../../../dijit/themes/soria/images/titleBar.png) #e9e9e9 repeat-x top;
+	padding-bottom: 2px;
+	color: #000 !important;
+}
+.soria .dojoxGrid-header .dojoxGrid-cell-over {
+	background: url(../../../../dijit/themes/soria/images/titleBarActive.png) #e9e9e9 repeat-x top;
+}
+.soria .dojoxGrid-sort-down {
+	background: url(images/grid_sort_down.gif) right no-repeat;
+	padding-left: 0px;
+	margin-left: 0px;
+}
+.soria .dojoxGrid-sort-up {
+	background: url(images/grid_sort_up.gif) right no-repeat;
+	padding-left: 0px;
+	margin-left: 0px;
+}
+.soria .gridArrowButtonChar {
+	display:none !important;
+}
+.dijit_a11y .gridArrowButtonChar {
+	display:inline !important;
+}
+.soria .dojoxGrid-scrollbox {
+	position: relative;
+	overflow: scroll;
+	background-color: #fefefe;
+	width: 100%;
+}
+.soria .dojoxGrid-content {
+	position: relative;
+	overflow: hidden;
+	 -moz-outline-style: none;
+	outline: none;
+}
+.soria .dojoxGrid-rowbar { 
+	border: none;
+	
+	background: url(images/titleBar.png) #e9e9e9 repeat-y right;
+	border-right: 1px solid #cccccc;
+	padding: 0px;
+}
+.soria .dojoxGrid-rowbar-inner {
+	border: none;
+	border-bottom: 1px solid #cccccc;
+}
+.soria .dojoxGrid-rowbar-over {
+	background: url(images/titleBarActive.png) #e9e9e9 repeat-y right;
+}
+.soria .dojoxGrid-rowbar-selected {
+	background-color: #D9E8F9;
+	background-image: none;
+	background: url(../../../../dijit/themes/soria/images/titleBar.png) #dddddd repeat-x top;
+	border-right: 1px solid #cccccc;
+	background-position: center;
+	background-repeat: no-repeat;
+}
+.soria .dojoxGrid-row {
+	position: relative;
+	width: 9000em;
+}
+.soria .dojoxGrid-row {
+	border: none;
+	border-left: none;
+	border-right: none;
+	background-color: white;
+	border-top: none;
+}
+.soria .dojoxGrid-row-over {
+	border-top-color: #cccccc;
+	border-bottom-color: #cccccc;
+}
+.soria .dojoxGrid-row-over .dojoxGrid-cell {
+	background-color: #60a1ea; 
+	color:#fff;
+}
+.soria .dojoxGrid-row-odd {
+	background-color: #f2f5f9;
+	
+}
+.soria .dojoxGrid-row-selected {
+	background-color: #aec7e3;
+}
+.soria .dojoxGrid-row-table {
+	table-layout: fixed;
+	width: 0;
+	border-collapse: collapse;
+}
+.soria .dojoxGrid-invisible {
+	visibility: hidden;
+}		
+.soria .Xdojo-ie .dojoxGrid-invisible {
+	display: none;
+}		
+.soria .dojoxGrid-invisible td, .dojoxGrid-header .dojoxGrid-invisible td {
+	border-top-width: 0;
+	border-bottom-width: 0;
+	padding-top: 0;
+	padding-bottom: 0;
+	height: 0;
+	overflow: hidden;
+}
+.soria .dojoxGrid-cell {
+	border: 1px dotted #D5CDB5;
+	padding: 3px 3px 3px 3px;
+	text-align: left;
+	overflow: hidden;
+}
+.dj_ie6 .soria .dojoxGrid-cell {
+	border: 1px solid white;
+	border-right: 1px solid #D5CDB5;
+}
+.soria .dojoxGrid-cell-focus {
+	border: 1px dotted #a6a6a6;
+}
+.soria .dojoxGrid-cell-over {
+	border: 1px dotted #a6a6a6;
+}
+.soria .dojoxGrid-cell-focus.dojoxGrid-cell-over {
+	border: 1px dotted #595959;
+}
+.soria .dojoxGrid-cell-clip {
+	width: 100%;
+	overflow: hidden;
+	white-space:nowrap;
+	text-overflow: ellipsis;
+}
+.soria .dojoxGrid-row-editing td {
+	
+	background-color: #60a1ea; 
+	
+}
+.soria .dojoxGrid-row-inserting td {
+	background-color: #F4FFF4;
+}
+.soria .dojoxGrid-row-inflight td {
+	background-color: #F2F7B7;
+}
+.soria .dojoxGrid-row-error td {
+	background-color: #F8B8B6;
+}
+.soria .dojoxGrid-input,
+.soria .dojoxGrid-select,
+.soria .dojoxGrid-textarea {
+	margin: 0;
+	padding: 0px;
+	border-style: none;
+	width: 100%;
+	font-size: 100%;
+	font-family: inherit;
+}
+.dojoxGrid-hidden-focus {
+	position: absolute;
+	left: -1000px;
+	top: -1000px;
+	height: 0px, width: 0px;
+}
+.dijit_a11y .dojoxGrid-rowbar-selected { 
+	border-top: 1px solid white;
+	border-bottom: 1px dashed black;
+	border-top: 0;
+	background: none;
+}
+.dijit_a11y .dojoxGrid-rowbar-selected .dojoxGrid-rowbar-inner {
+	border: 0;
+	border-top: 1px solid white;
+}
+.dijit_a11y .dojoxGrid-row-selected {
+	border-bottom: 1px dashed black;
+}
diff --git a/dojox/grid/compat/_grid/tundraGrid.css b/dojox/grid/compat/_grid/tundraGrid.css
new file mode 100644
index 0000000..6314778
--- /dev/null
+++ b/dojox/grid/compat/_grid/tundraGrid.css
@@ -0,0 +1,215 @@
+.tundra .dojoxGrid {
+	position: relative;
+	background-color: #e9e9e9;
+	font-size: 0.85em; 
+	-moz-outline-style: none;
+	outline: none;
+	overflow: hidden;
+	height: 0;
+}
+.tundra .dojoxGrid table {
+	padding: 0;
+}
+.tundra .dojoxGrid td {
+	-moz-outline: none;
+}
+.tundra .dojoxGrid-master-header {
+	position: relative;
+}
+.tundra .dojoxGrid-master-view  {
+	position: relative;
+}
+.tundra .dojoxGrid-view {
+	position: absolute;
+	overflow: hidden;
+}
+.tundra .dojoxGrid-header {
+	position: absolute;
+	overflow: hidden;
+}
+.tundra .dojoxGrid-header {
+	background-color:  #e9e9e9;
+}
+.tundra .dojoxGrid-header table {
+	text-align: center;
+}
+.tundra .dojoxGrid-header .dojoxGrid-cell-content {
+	text-align: center;
+}
+.tundra .dojoxGrid-header .dojoxGrid-cell { 
+	border: 1px solid transparent;
+	
+	border-color: white #ACA899 #919191 white;
+	background: url(../../../../dijit/themes/tundra/images/tabEnabled.png) #e9e9e9 repeat-x top;
+	padding-bottom: 2px;
+	color: #000 !important;
+}
+.tundra .dojoxGrid-header .dojoxGrid-cell-over {
+	background: url(../../../../dijit/themes/tundra/images/tabHover.png) #e9e9e9 repeat-x top;
+	color: #000 !important;
+}
+.tundra .dojoxGrid-sort-down {
+	background: url(../../../../dijit/themes/tundra/images/smallArrowDown.png) right no-repeat;
+	padding-left: 0px;
+	margin-left: 0px;
+}
+.tundra .dojoxGrid-sort-up {
+	background: url(../../../../dijit/themes/tundra/images/smallArrowUp.png) right no-repeat;
+	padding-left: 0px;
+	margin-left: 0px;
+}
+.tundra .gridArrowButtonChar {
+	display:none !important;
+}
+.dijit_a11y .gridArrowButtonChar {
+	display:inline !important;
+}
+.tundra .dojoxGrid-scrollbox {
+	position: relative;
+	overflow: scroll;
+	background-color: #fefefe;
+	width: 100%;
+}
+.tundra .dojoxGrid-content {
+	position: relative;
+	overflow: hidden;
+	 -moz-outline-style: none;
+	outline: none;
+}
+.tundra .dojoxGrid-rowbar { 
+	border: none;
+	
+	background: url(images/tabEnabled_rotated.png) #e9e9e9 repeat-y right;
+	border-right: 1px solid #cccccc;
+	padding: 0px;
+}
+.tundra .dojoxGrid-rowbar-inner {
+	border: none;
+	border-bottom: 1px solid #cccccc;
+}
+.tundra .dojoxGrid-rowbar-over {
+	background: url(images/tabHover_rotated.png) #e9e9e9 repeat-y right;
+}
+.tundra .dojoxGrid-rowbar-selected {
+	background-color: #D9E8F9;
+	background-image: none;
+	background: url(../../../../dijit/themes/tundra/images/tabDisabled.png) #dddddd repeat-x top;
+	border-right: 1px solid #cccccc;
+	background-position: center;
+	background-repeat: no-repeat;
+}
+.tundra .dojoxGrid-row {
+	position: relative;
+	width: 9000em;
+}
+.tundra .dojoxGrid-row {
+	border: none;
+	border-left: none;
+	border-right: none;
+	background-color: white;
+	border-top: none;
+}
+.tundra .dojoxGrid-row-over {
+	border-top-color: #cccccc;
+	border-bottom-color: #cccccc;
+}
+.tundra .dojoxGrid-row-over .dojoxGrid-cell {
+	background-color: #60a1ea; 
+	color:#fff;
+	
+}
+.tundra .dojoxGrid-row-odd {
+	background-color: #f2f5f9;
+	
+}
+.tundra .dojoxGrid-row-selected {
+	background-color: #aec7e3;
+	
+}
+.tundra .dojoxGrid-row-table {
+	table-layout: fixed;
+	width: 0;
+	border-collapse: collapse;
+}
+.tundra .dojoxGrid-invisible {
+	visibility: hidden;
+}		
+.tundra .Xdojo-ie .dojoxGrid-invisible {
+	display: none;
+}		
+.tundra .dojoxGrid-invisible td, .dojoxGrid-header .dojoxGrid-invisible td {
+	border-top-width: 0;
+	border-bottom-width: 0;
+	padding-top: 0;
+	padding-bottom: 0;
+	height: 0;
+	overflow: hidden;
+}
+.tundra .dojoxGrid-cell {
+	border: 1px dotted #D5CDB5;
+	padding: 3px 3px 3px 3px;
+	text-align: left;
+	overflow: hidden;
+}
+.dj_ie6 .tundra .dojoxGrid-cell {
+	border: 1px solid white;
+	border-right: 1px solid #D5CDB5;
+}
+.tundra .dojoxGrid-cell-focus {
+	border: 1px dotted #a6a6a6;
+}
+.tundra .dojoxGrid-cell-over {
+	border: 1px dotted #a6a6a6;
+}
+.tundra .dojoxGrid-cell-focus.dojoxGrid-cell-over {
+	border: 1px dotted #595959;
+}
+.tundra .dojoxGrid-cell-clip {
+	width: 100%;
+	overflow: hidden;
+	white-space:nowrap;
+	text-overflow: ellipsis;
+}
+.tundra .dojoxGrid-row-editing td {
+	
+	background-color: #60a1ea; 
+	
+}
+.tundra .dojoxGrid-row-inserting td {
+	background-color: #F4FFF4;
+}
+.tundra .dojoxGrid-row-inflight td {
+	background-color: #F2F7B7;
+}
+.tundra .dojoxGrid-row-error td {
+	background-color: #F8B8B6;
+}
+.tundra .dojoxGrid-input,
+.tundra .dojoxGrid-select,
+.tundra .dojoxGrid-textarea {
+	margin: 0;
+	padding: 0px;
+	border-style: none;
+	width: 100%;
+	font-size: 100%;
+	font-family: inherit;
+}
+.dojoxGrid-hidden-focus {
+	position: absolute;
+	left: -1000px;
+	top: -1000px;
+	height: 0px, width: 0px;
+}
+.dijit_a11y .dojoxGrid-rowbar-selected { 
+	border-top: 1px solid white;
+	border-bottom: 1px dashed black;
+	border-top: 0;
+	background: none;
+}
+.dijit_a11y .dojoxGrid-rowbar-selected .dojoxGrid-rowbar-inner {
+	border: 0;
+	border-top: 1px solid white;
+}
+.dijit_a11y .dojoxGrid-row-selected {
+	border-bottom: 1px dashed black;
+}
diff --git a/dojox/grid/compat/_grid/view.js b/dojox/grid/compat/_grid/view.js
new file mode 100644
index 0000000..6e60837
--- /dev/null
+++ b/dojox/grid/compat/_grid/view.js
@@ -0,0 +1,214 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat._grid.view"]){
+dojo._hasResource["dojox.grid.compat._grid.view"]=true;
+dojo.provide("dojox.grid.compat._grid.view");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dojox.grid.compat._grid.builder");
+dojo.declare("dojox.GridView",[dijit._Widget,dijit._Templated],{defaultWidth:"18em",viewWidth:"",templateString:"<div class=\"dojoxGrid-view\">\n\t<div class=\"dojoxGrid-header\" dojoAttachPoint=\"headerNode\">\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\">\n\t\t\t<div dojoAttachPoint=\"headerContentNode\"></div>\n\t\t</div>\n\t</div>\n\t<input type=\"checkbox\" class=\"dojoxGrid-hidden-focus\" dojoAttachPoint=\"hiddenFocusNode\" />\n\t<input type=\"checkbox\"  [...]
+this.rowNodes=[];
+},postCreate:function(){
+this.connect(this.scrollboxNode,"onscroll","doscroll");
+dojox.grid.funnelEvents(this.contentNode,this,"doContentEvent",["mouseover","mouseout","click","dblclick","contextmenu","mousedown"]);
+dojox.grid.funnelEvents(this.headerNode,this,"doHeaderEvent",["dblclick","mouseover","mouseout","mousemove","mousedown","click","contextmenu"]);
+this.content=new dojox.grid.contentBuilder(this);
+this.header=new dojox.grid.headerBuilder(this);
+if(!dojo._isBodyLtr()){
+this.headerNodeContainer.style.width="";
+}
+},destroy:function(){
+dojox.grid.removeNode(this.headerNode);
+this.inherited("destroy",arguments);
+},focus:function(){
+if(dojo.isWebKit||dojo.isOpera){
+this.hiddenFocusNode.focus();
+}else{
+this.scrollboxNode.focus();
+}
+},setStructure:function(_1){
+var vs=(this.structure=_1);
+if(vs.width&&!isNaN(vs.width)){
+this.viewWidth=vs.width+"em";
+}else{
+this.viewWidth=vs.width||this.viewWidth;
+}
+this.onBeforeRow=vs.onBeforeRow;
+this.noscroll=vs.noscroll;
+if(this.noscroll){
+this.scrollboxNode.style.overflow="hidden";
+}
+this.testFlexCells();
+this.updateStructure();
+},testFlexCells:function(){
+this.flexCells=false;
+for(var j=0,_4;(_4=this.structure.rows[j]);j++){
+for(var i=0,_6;(_6=_4[i]);i++){
+_6.view=this;
+this.flexCells=this.flexCells||_6.isFlex();
+}
+}
+return this.flexCells;
+},updateStructure:function(){
+this.header.update();
+this.content.update();
+},getScrollbarWidth:function(){
+return (this.noscroll?0:dojox.grid.getScrollbarWidth());
+},getColumnsWidth:function(){
+return this.headerContentNode.firstChild.offsetWidth;
+},getWidth:function(){
+return this.viewWidth||(this.getColumnsWidth()+this.getScrollbarWidth())+"px";
+},getContentWidth:function(){
+return Math.max(0,dojo._getContentBox(this.domNode).w-this.getScrollbarWidth())+"px";
+},render:function(){
+this.scrollboxNode.style.height="";
+this.renderHeader();
+},renderHeader:function(){
+this.headerContentNode.innerHTML=this.header.generateHtml(this._getHeaderContent);
+},_getHeaderContent:function(_7){
+var n=_7.name||_7.grid.getCellName(_7);
+if(_7.index!=_7.grid.getSortIndex()){
+return n;
+}
+return ["<div class=\"",_7.grid.sortInfo>0?"dojoxGrid-sort-down":"dojoxGrid-sort-up","\"><div class=\"gridArrowButtonChar\">",_7.grid.sortInfo>0?"▼":"▲","</div>",n,"</div>"].join("");
+},resize:function(){
+this.adaptHeight();
+this.adaptWidth();
+},hasScrollbar:function(){
+return (this.scrollboxNode.clientHeight!=this.scrollboxNode.offsetHeight);
+},adaptHeight:function(){
+if(!this.grid.autoHeight){
+var h=this.domNode.clientHeight;
+if(!this.hasScrollbar()){
+h-=dojox.grid.getScrollbarWidth();
+}
+dojox.grid.setStyleHeightPx(this.scrollboxNode,h);
+}
+},adaptWidth:function(){
+if(this.flexCells){
+this.contentWidth=this.getContentWidth();
+this.headerContentNode.firstChild.style.width=this.contentWidth;
+}
+var w=this.scrollboxNode.offsetWidth-this.getScrollbarWidth();
+w=Math.max(w,this.getColumnsWidth())+"px";
+with(this.contentNode){
+style.width="";
+offsetWidth;
+style.width=w;
+}
+},setSize:function(w,h){
+with(this.domNode.style){
+if(w){
+width=w;
+}
+height=(h>=0?h+"px":"");
+}
+with(this.headerNode.style){
+if(w){
+width=w;
+}
+}
+},renderRow:function(_d,_e){
+var _f=this.createRowNode(_d);
+this.buildRow(_d,_f,_e);
+this.grid.edit.restore(this,_d);
+return _f;
+},createRowNode:function(_10){
+var _11=document.createElement("div");
+_11.className=this.classTag+"-row";
+_11[dojox.grid.gridViewTag]=this.id;
+_11[dojox.grid.rowIndexTag]=_10;
+this.rowNodes[_10]=_11;
+return _11;
+},buildRow:function(_12,_13){
+this.buildRowContent(_12,_13);
+this.styleRow(_12,_13);
+},buildRowContent:function(_14,_15){
+_15.innerHTML=this.content.generateHtml(_14,_14);
+if(this.flexCells){
+_15.firstChild.style.width=this.contentWidth;
+}
+},rowRemoved:function(_16){
+this.grid.edit.save(this,_16);
+delete this.rowNodes[_16];
+},getRowNode:function(_17){
+return this.rowNodes[_17];
+},getCellNode:function(_18,_19){
+var row=this.getRowNode(_18);
+if(row){
+return this.content.getCellNode(row,_19);
+}
+},styleRow:function(_1b,_1c){
+_1c._style=dojox.grid.getStyleText(_1c);
+this.styleRowNode(_1b,_1c);
+},styleRowNode:function(_1d,_1e){
+if(_1e){
+this.doStyleRowNode(_1d,_1e);
+}
+},doStyleRowNode:function(_1f,_20){
+this.grid.styleRowNode(_1f,_20);
+},updateRow:function(_21,_22,_23){
+var _24=this.getRowNode(_21);
+if(_24){
+_24.style.height="";
+this.buildRow(_21,_24);
+}
+return _24;
+},updateRowStyles:function(_25){
+this.styleRowNode(_25,this.getRowNode(_25));
+},lastTop:0,firstScroll:0,doscroll:function(_26){
+var _27=dojo._isBodyLtr();
+if(this.firstScroll<2){
+if((!_27&&this.firstScroll==1)||(_27&&this.firstScroll==0)){
+var s=dojo.marginBox(this.headerNodeContainer);
+if(dojo.isIE){
+this.headerNodeContainer.style.width=s.w+this.getScrollbarWidth()+"px";
+}else{
+if(dojo.isMoz){
+this.headerNodeContainer.style.width=s.w-this.getScrollbarWidth()+"px";
+if(_27){
+this.scrollboxNode.scrollLeft=this.scrollboxNode.scrollWidth-this.scrollboxNode.clientWidth;
+}else{
+this.scrollboxNode.scrollLeft=this.scrollboxNode.clientWidth-this.scrollboxNode.scrollWidth;
+}
+}
+}
+}
+this.firstScroll++;
+}
+this.headerNode.scrollLeft=this.scrollboxNode.scrollLeft;
+var top=this.scrollboxNode.scrollTop;
+if(top!=this.lastTop){
+this.grid.scrollTo(top);
+}
+},setScrollTop:function(_2a){
+this.lastTop=_2a;
+this.scrollboxNode.scrollTop=_2a;
+return this.scrollboxNode.scrollTop;
+},doContentEvent:function(e){
+if(this.content.decorateEvent(e)){
+this.grid.onContentEvent(e);
+}
+},doHeaderEvent:function(e){
+if(this.header.decorateEvent(e)){
+this.grid.onHeaderEvent(e);
+}
+},dispatchContentEvent:function(e){
+return this.content.dispatchEvent(e);
+},dispatchHeaderEvent:function(e){
+return this.header.dispatchEvent(e);
+},setColWidth:function(_2f,_30){
+this.grid.setCellWidth(_2f,_30+"px");
+},update:function(){
+var _31=this.scrollboxNode.scrollLeft;
+this.content.update();
+this.grid.update();
+this.scrollboxNode.scrollLeft=_31;
+this.headerNode.scrollLeft=_31;
+}});
+}
diff --git a/dojox/grid/compat/_grid/views.js b/dojox/grid/compat/_grid/views.js
new file mode 100644
index 0000000..0049187
--- /dev/null
+++ b/dojox/grid/compat/_grid/views.js
@@ -0,0 +1,190 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.compat._grid.views"]){
+dojo._hasResource["dojox.grid.compat._grid.views"]=true;
+dojo.provide("dojox.grid.compat._grid.views");
+dojo.declare("dojox.grid.views",null,{constructor:function(_1){
+this.grid=_1;
+},defaultWidth:200,views:[],resize:function(){
+this.onEach("resize");
+},render:function(){
+this.onEach("render");
+},addView:function(_2){
+_2.idx=this.views.length;
+this.views.push(_2);
+},destroyViews:function(){
+for(var i=0,v;v=this.views[i];i++){
+v.destroy();
+}
+this.views=[];
+},getContentNodes:function(){
+var _5=[];
+for(var i=0,v;v=this.views[i];i++){
+_5.push(v.contentNode);
+}
+return _5;
+},forEach:function(_8){
+for(var i=0,v;v=this.views[i];i++){
+_8(v,i);
+}
+},onEach:function(_b,_c){
+_c=_c||[];
+for(var i=0,v;v=this.views[i];i++){
+if(_b in v){
+v[_b].apply(v,_c);
+}
+}
+},normalizeHeaderNodeHeight:function(){
+var _f=[];
+for(var i=0,v;(v=this.views[i]);i++){
+if(v.headerContentNode.firstChild){
+_f.push(v.headerContentNode);
+}
+}
+this.normalizeRowNodeHeights(_f);
+},normalizeRowNodeHeights:function(_12){
+var h=0;
+for(var i=0,n,o;(n=_12[i]);i++){
+h=Math.max(h,(n.firstChild.clientHeight)||(n.firstChild.offsetHeight));
+}
+h=(h>=0?h:0);
+var hpx=h+"px";
+for(var i=0,n;(n=_12[i]);i++){
+if(n.firstChild.clientHeight!=h){
+n.firstChild.style.height=hpx;
+}
+}
+if(_12&&_12[0]){
+_12[0].parentNode.offsetHeight;
+}
+},resetHeaderNodeHeight:function(){
+for(var i=0,v,n;(v=this.views[i]);i++){
+n=v.headerContentNode.firstChild;
+if(n){
+n.style.height="";
+}
+}
+},renormalizeRow:function(_1b){
+var _1c=[];
+for(var i=0,v,n;(v=this.views[i])&&(n=v.getRowNode(_1b));i++){
+n.firstChild.style.height="";
+_1c.push(n);
+}
+this.normalizeRowNodeHeights(_1c);
+},getViewWidth:function(_20){
+return this.views[_20].getWidth()||this.defaultWidth;
+},measureHeader:function(){
+this.resetHeaderNodeHeight();
+this.forEach(function(_21){
+_21.headerContentNode.style.height="";
+});
+var h=0;
+this.forEach(function(_23){
+h=Math.max(_23.headerNode.offsetHeight,h);
+});
+return h;
+},measureContent:function(){
+var h=0;
+this.forEach(function(_25){
+h=Math.max(_25.domNode.offsetHeight,h);
+});
+return h;
+},findClient:function(_26){
+var c=this.grid.elasticView||-1;
+if(c<0){
+for(var i=1,v;(v=this.views[i]);i++){
+if(v.viewWidth){
+for(i=1;(v=this.views[i]);i++){
+if(!v.viewWidth){
+c=i;
+break;
+}
+}
+break;
+}
+}
+}
+if(c<0){
+c=Math.floor(this.views.length/2);
+}
+return c;
+},arrange:function(l,w){
+var i,v,vw,len=this.views.length;
+var c=(w<=0?len:this.findClient());
+var _31=function(v,l){
+with(v.domNode.style){
+if(!dojo._isBodyLtr()){
+right=l+"px";
+}else{
+left=l+"px";
+}
+top=0+"px";
+}
+with(v.headerNode.style){
+if(!dojo._isBodyLtr()){
+right=l+"px";
+}else{
+left=l+"px";
+}
+top=0;
+}
+};
+for(i=0;(v=this.views[i])&&(i<c);i++){
+vw=this.getViewWidth(i);
+v.setSize(vw,0);
+_31(v,l);
+vw=v.domNode.offsetWidth;
+l+=vw;
+}
+i++;
+var r=w;
+for(var j=len-1;(v=this.views[j])&&(i<=j);j--){
+vw=this.getViewWidth(j);
+v.setSize(vw,0);
+vw=v.domNode.offsetWidth;
+r-=vw;
+_31(v,r);
+}
+if(c<len){
+v=this.views[c];
+vw=Math.max(1,r-l);
+v.setSize(vw+"px",0);
+_31(v,l);
+}
+return l;
+},renderRow:function(_36,_37){
+var _38=[];
+for(var i=0,v,n,_3c;(v=this.views[i])&&(n=_37[i]);i++){
+_3c=v.renderRow(_36);
+n.appendChild(_3c);
+_38.push(_3c);
+}
+this.normalizeRowNodeHeights(_38);
+},rowRemoved:function(_3d){
+this.onEach("rowRemoved",[_3d]);
+},updateRow:function(_3e,_3f){
+for(var i=0,v;v=this.views[i];i++){
+v.updateRow(_3e,_3f);
+}
+this.renormalizeRow(_3e);
+},updateRowStyles:function(_42){
+this.onEach("updateRowStyles",[_42]);
+},setScrollTop:function(_43){
+var top=_43;
+for(var i=0,v;v=this.views[i];i++){
+top=v.setScrollTop(_43);
+}
+return top;
+},getFirstScrollingView:function(){
+for(var i=0,v;(v=this.views[i]);i++){
+if(v.hasScrollbar()){
+return v;
+}
+}
+}});
+}
diff --git a/dojox/grid/compat/resources/GridView.html b/dojox/grid/compat/resources/GridView.html
new file mode 100644
index 0000000..d86782d
--- /dev/null
+++ b/dojox/grid/compat/resources/GridView.html
@@ -0,0 +1,12 @@
+<div class="dojoxGrid-view">
+	<div class="dojoxGrid-header" dojoAttachPoint="headerNode">
+		<div dojoAttachPoint="headerNodeContainer" style="width:9000em">
+			<div dojoAttachPoint="headerContentNode"></div>
+		</div>
+	</div>
+	<input type="checkbox" class="dojoxGrid-hidden-focus" dojoAttachPoint="hiddenFocusNode" />
+	<input type="checkbox" class="dojoxGrid-hidden-focus" />
+	<div class="dojoxGrid-scrollbox" dojoAttachPoint="scrollboxNode">
+		<div class="dojoxGrid-content" dojoAttachPoint="contentNode" hidefocus="hidefocus"></div>
+	</div>
+</div>
\ No newline at end of file
diff --git a/dojox/grid/compat/resources/VirtualGrid.html b/dojox/grid/compat/resources/VirtualGrid.html
new file mode 100644
index 0000000..7253108
--- /dev/null
+++ b/dojox/grid/compat/resources/VirtualGrid.html
@@ -0,0 +1,5 @@
+<div class="dojoxGrid" hidefocus="hidefocus" role="wairole:grid">
+	<div class="dojoxGrid-master-header" dojoAttachPoint="viewsHeaderNode"></div>
+	<div class="dojoxGrid-master-view" dojoAttachPoint="viewsNode"></div>
+	<span dojoAttachPoint="lastFocusNode" tabindex="0"></span>
+</div>
diff --git a/dojox/grid/compat/tests/databaseModel.js b/dojox/grid/compat/tests/databaseModel.js
new file mode 100644
index 0000000..6f92b52
--- /dev/null
+++ b/dojox/grid/compat/tests/databaseModel.js
@@ -0,0 +1,337 @@
+if(!dojo._hasResource["dojox.grid.compat.tests.databaseModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.compat.tests.databaseModel"] = true;
+dojo.provide("dojox.grid.compat.tests.databaseModel");
+dojo.require("dojox.grid.compat._data.model");
+
+// Provides a sparse array that is also traversable inorder 
+// with basic Array:
+//   - iterating by index is slow for large sparse arrays
+//   - for...in iteration is in order of element creation 
+// maintains a secondary index for interating
+// over sparse elements inorder
+dojo.declare("dojox.grid.Sparse", null, {
+	constructor: function() {
+		this.clear();
+	},
+	clear: function() {
+		this.indices = [];
+		this.values = [];
+	},
+	length: function() {
+		return this.indices.length;
+	},
+	set: function(inIndex, inValue) {
+		for (var i=0,l=this.indices.length; i<l; i++) {
+			if (this.indices[i] >= inIndex) 
+				break;
+		}
+		if (this.indices[i] != inIndex) 
+			this.indices.splice(i, 0, inIndex);
+		this.values[inIndex] = inValue;
+	},
+	get: function(inIndex) {
+		return this.values[inIndex];
+	},
+	remove: function(inIndex) {
+		for (var i=0,l=this.indices.length; i<l; i++) 
+			if (this.indices[i] == inIndex) {
+				this.indices.splice(i, 1);
+				break;
+			}
+		delete this.values[inIndex];
+	},
+	inorder: function(inFor) {
+		for (var i=0,l=this.indices.length, ix; i<l; i++) {
+			ix = this.indices[i];
+			if (inFor(this.values[ix], ix) === false)
+				break;
+		}
+	}
+});
+
+// sample custom model implementation that works with mysql server.
+dojo.declare("dojox.grid.data.DbTable", dojox.grid.data.Dynamic, {
+	delayedInsertCommit: true,
+	constructor: function(inFields, inData, inServer, inDatabase, inTable) {
+		this.server = inServer;
+		this.database = inDatabase;
+		this.table = inTable;
+		this.stateNames = ['inflight', 'inserting', 'removing', 'error'];
+		this.clearStates();
+		this.clearSort();
+	},
+	clearData: function() {
+		this.cache = [ ];
+		this.clearStates();
+		this.inherited(arguments);
+	},
+	clearStates: function() {
+		this.states = {};
+		for (var i=0, s; (s=this.stateNames[i]); i++) {
+			delete this.states[s];
+			this.states[s] = new dojox.grid.Sparse();
+		}
+	},
+	// row state information
+	getState: function(inRowIndex) {
+		for (var i=0, r={}, s; (s=this.stateNames[i]); i++)
+			r[s] = this.states[s].get(inRowIndex);
+		return r;
+	},
+	setState: function(inRowIndex, inState, inValue) {
+		this.states[inState].set(inRowIndex, inValue||true);
+	},
+	clearState: function(inRowIndex, inState) {
+		if (arguments.length == 1) {
+			for (var i=0, s; (s=this.stateNames[i]); i++)
+				this.states[s].remove(inRowIndex);
+		}	else {
+			for (var i=1, l=arguments.length, arg; (i<l) &&((arg=arguments[i])!=undefined); i++)
+				this.states[arg].remove(inRowIndex);
+		}
+	},
+	setStateForIndexes: function(inRowIndexes, inState, inValue) {
+		for (var i=inRowIndexes.length-1, k; (i>=0) && ((k=inRowIndexes[i])!=undefined); i--)
+			this.setState(k, inState, inValue);
+	},
+	clearStateForIndexes: function(inRowIndexes, inState) {
+		for (var i=inRowIndexes.length-1, k; (i>=0) && ((k=inRowIndexes[i])!=undefined); i--)
+			this.clearState(k, inState);
+	},
+	//$ Return boolean stating whether or not an operation is in progress that may change row indexing.
+	isAddRemoving: function() {
+		return Boolean(this.states['inserting'].length() || this.states['removing'].length());
+	},
+	isInflight: function() {
+		return Boolean(this.states['inflight'].length());
+	},
+	//$ Return boolean stating if the model is currently undergoing any type of edit.
+	isEditing: function() {
+		for (var i=0, r={}, s; (s=this.stateNames[i]); i++)
+			if (this.states[s].length())
+				return true;
+	},
+	//$ Return true if ok to modify the given row. Override as needed, using model editing state information.
+	canModify: function(inRowIndex) {
+		return !this.getState(inRowIndex).inflight && !(this.isInflight() && this.isAddRemoving());
+	},
+	// server send / receive
+	getSendParams: function(inParams) {
+		var p = {
+			database: this.database || '',
+			table: this.table || ''
+		}
+		return dojo.mixin(p, inParams || {});
+	},
+	send: function(inAsync, inParams, inCallbacks) {
+		//console.log('send', inParams.command);
+		var p = this.getSendParams(inParams);
+		var d = dojo.xhrPost({
+			url: this.server,
+			content: p,
+			handleAs: 'json-comment-filtered',
+			contentType: "application/x-www-form-urlencoded; charset=utf-8",
+			sync: !inAsync
+		});
+		d.addCallbacks(dojo.hitch(this, "receive", inCallbacks), dojo.hitch(this, "receiveError", inCallbacks));
+		return d;
+	},
+	_callback: function(cb, eb, data) {
+		try{ cb && cb(data); } 
+		catch(e){ eb && eb(data, e); }
+	},
+	receive: function(inCallbacks, inData) {
+		inCallbacks && this._callback(inCallbacks.callback, inCallbacks.errback, inData);
+	},
+	receiveError: function(inCallbacks, inErr) {
+		this._callback(inCallbacks.errback, null, inErr)
+	},
+	encodeRow: function(inParams, inRow, inPrefix) {
+		for (var i=0, l=inRow.length; i < l; i++)
+			inParams['_' + (inPrefix ? inPrefix : '') + i] = (inRow[i] ? inRow[i] : '');
+	},
+	measure: function() {
+		this.send(true, { command: 'info' }, { callback: dojo.hitch(this, this.callbacks.info) });
+	},
+	fetchRowCount: function(inCallbacks) {
+		this.send(true, { command: 'count' }, inCallbacks);
+	},
+	// server commits
+	commitEdit: function(inOldData, inNewData, inRowIndex, inCallbacks) {
+		this.setState(inRowIndex, "inflight", true);
+		var params = {command: 'update'};
+		this.encodeRow(params, inOldData, 'o');
+		this.encodeRow(params, inNewData);
+		this.send(true, params, inCallbacks);
+	},
+	commitInsert: function(inRowIndex, inNewData, inCallbacks) {
+		this.setState(inRowIndex, "inflight", true);
+		var params = {command: 'insert'};
+		this.encodeRow(params, inNewData);
+		this.send(true, params, inCallbacks);
+	},
+	// NOTE: supported only in tables with pk
+	commitDelete: function(inRows, inCallbacks) {
+		var params = { 
+			command: 'delete',
+			count: inRows.length
+		}	
+		var pk = this.getPkIndex();
+		if (pk < 0)
+			return;
+		for (var i=0; i < inRows.length; i++)	{
+			params['_' + i] = inRows[i][pk];
+		}	
+		this.send(true, params, inCallbacks);
+	},
+	getUpdateCallbacks: function(inRowIndex) {
+		return {
+			callback: dojo.hitch(this, this.callbacks.update, inRowIndex), 
+			errback: dojo.hitch(this, this.callbacks.updateError, inRowIndex)
+		};
+	},
+	// primary key from fields
+	getPkIndex: function() {
+		for (var i=0, l=this.fields.count(), f; (i<l) && (f=this.fields.get(i)); i++)
+			if (f.Key = 'PRI')
+				return i;
+		return -1;		
+	},
+	// model implementations
+	update: function(inOldData, inNewData, inRowIndex) {
+		var cbs = this.getUpdateCallbacks(inRowIndex);
+		if (this.getState(inRowIndex).inserting)
+			this.commitInsert(inRowIndex, inNewData, cbs);
+		else
+			this.commitEdit(this.cache[inRowIndex] || inOldData, inNewData, inRowIndex, cbs);
+		// set push data immediately to model	so reflectd while committing
+		this.setRow(inNewData, inRowIndex);
+	},
+	insert: function(inData, inRowIndex) {
+		this.setState(inRowIndex, 'inserting', true);
+		if (!this.delayedInsertCommit)
+			this.commitInsert(inRowIndex, inData, this.getUpdateCallbacks(inRowIndex));
+		return this.inherited(arguments);
+	},
+	remove: function(inRowIndexes) {
+		var rows = [];
+		for (var i=0, r=0, indexes=[]; (r=inRowIndexes[i]) !== undefined; i++)
+			if (!this.getState(r).inserting) {
+				rows.push(this.getRow(r));
+				indexes.push(r);
+				this.setState(r, 'removing');
+			}
+		var cbs = {
+			callback: dojo.hitch(this, this.callbacks.remove, indexes),
+			errback: dojo.hitch(this, this.callbacks.removeError, indexes)
+		};
+		this.commitDelete(rows, cbs);
+		dojox.grid.data.Dynamic.prototype.remove.apply(this, arguments);
+	},
+	cancelModifyRow: function(inRowIndex) {
+		if (this.isDelayedInsert(inRowIndex)) {
+			this.removeInsert(inRowIndex);
+		} else
+			this.finishUpdate(inRowIndex);
+	},	
+	finishUpdate: function(inRowIndex, inData) {
+		this.clearState(inRowIndex);
+		var d = (inData&&inData[0]) || this.cache[inRowIndex];
+		if (d)
+			this.setRow(d, inRowIndex);
+		delete this.cache[inRowIndex];
+	},
+	isDelayedInsert: function(inRowIndex) {
+		return (this.delayedInsertCommit && this.getState(inRowIndex).inserting);
+	},
+	removeInsert: function(inRowIndex) {
+		this.clearState(inRowIndex);
+		dojox.grid.data.Dynamic.prototype.remove.call(this, [inRowIndex]);
+	},
+	// request data 
+	requestRows: function(inRowIndex, inCount)	{
+		var params = { 
+			command: 'select',
+			orderby: this.sortField, 
+			desc: (this.sortDesc ? "true" : ''),
+			offset: inRowIndex, 
+			limit: inCount
+		}
+		this.send(true, params, {callback: dojo.hitch(this, this.callbacks.rows, inRowIndex)});
+	},
+	// sorting
+	canSort: function () { 
+		return true; 
+	},
+	setSort: function(inSortIndex) {
+		this.sortField = this.fields.get(Math.abs(inSortIndex) - 1).name || inSortIndex;
+		this.sortDesc = (inSortIndex < 0);
+	},
+	sort: function(inSortIndex) {
+		this.setSort(inSortIndex);
+		this.clearData();
+	},
+	clearSort: function(){
+		this.sortField = '';
+		this.sortDesc = false;
+	},
+	endModifyRow: function(inRowIndex){
+		var cache = this.cache[inRowIndex];
+		var m = false;
+		if(cache){
+			var data = this.getRow(inRowIndex);
+			if(!dojox.grid.arrayCompare(cache, data)){
+				m = true;
+				this.update(cache, data, inRowIndex);
+			}	
+		}
+		if (!m)
+			this.cancelModifyRow(inRowIndex);
+	},
+	// server callbacks (called with this == model)
+	callbacks: {
+		update: function(inRowIndex, inData) {
+			console.log('received update', arguments);
+			if (inData.error)
+				this.updateError(inData)
+			else
+				this.finishUpdate(inRowIndex, inData);
+		},
+		updateError: function(inRowIndex) {
+			this.clearState(inRowIndex, 'inflight');
+			this.setState(inRowIndex, "error", "update failed: " + inRowIndex);
+			this.rowChange(this.getRow(inRowIndex), inRowIndex);
+		},
+		remove: function(inRowIndexes) {
+			this.clearStateForIndexes(inRowIndexes);
+		},
+		removeError: function(inRowIndexes) {
+			this.clearStateForIndexes(inRowIndexes);
+			alert('Removal error. Please refresh.');
+		},
+		rows: function(inRowIndex, inData) {
+			//this.beginUpdate();
+			for (var i=0, l=inData.length; i<l; i++)
+				this.setRow(inData[i], inRowIndex + i);
+			//this.endUpdate();
+			//this.allChange();
+		},
+		count: function(inRowCount) {
+			this.count = Number(inRowCount);
+			this.clearData();
+		},
+		info: function(inInfo) {
+			this.fields.clear();
+			for (var i=0, c; (c=inInfo.columns[i]); i++) {
+				c.name = c.Field;
+				this.fields.set(i, c);
+			}
+			this.table = inInfo.table;
+			this.database = inInfo.database;
+			this.notify("MetaData", arguments);
+			this.callbacks.count.call(this, inInfo.count);
+		}
+	}
+});
+
+}
diff --git a/dojox/grid/compat/tests/images/closed.gif b/dojox/grid/compat/tests/images/closed.gif
new file mode 100644
index 0000000..7d3afa4
Binary files /dev/null and b/dojox/grid/compat/tests/images/closed.gif differ
diff --git a/dojox/grid/compat/tests/images/flatScreen.gif b/dojox/grid/compat/tests/images/flatScreen.gif
new file mode 100644
index 0000000..05edd72
Binary files /dev/null and b/dojox/grid/compat/tests/images/flatScreen.gif differ
diff --git a/dojox/grid/compat/tests/images/open.gif b/dojox/grid/compat/tests/images/open.gif
new file mode 100644
index 0000000..37efd2c
Binary files /dev/null and b/dojox/grid/compat/tests/images/open.gif differ
diff --git a/dojox/grid/compat/tests/support/books.xml b/dojox/grid/compat/tests/support/books.xml
new file mode 100644
index 0000000..4c330e6
--- /dev/null
+++ b/dojox/grid/compat/tests/support/books.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<books>
+	<book>
+		<isbn>1</isbn>
+		<title>Title of 1</title>
+		<author>Author of 1</author>
+	</book>
+	<book>
+		<isbn>2</isbn>
+		<title>Title of 2</title>
+		<author>Author of 2</author>
+	</book>
+	<book>
+		<isbn>3</isbn>
+		<title>Title of 3</title>
+		<author>Author of 3</author>
+	</book>
+	<book>
+		<isbn>4</isbn>
+		<title>Title of 4</title>
+		<author>Author of 4</author>
+	</book>
+	<book>
+		<isbn>5</isbn>
+		<title>Title of 5</title>
+		<author>Author of 5</author>
+	</book>
+	<book>
+		<isbn>6</isbn>
+		<title>Title of 6</title>
+		<author>Author of 6</author>
+	</book>
+	<book>
+		<isbn>7</isbn>
+		<title>Title of 7</title>
+		<author>Author of 7</author>
+	</book>
+	<book>
+		<isbn>8</isbn>
+		<title>Title of 8</title>
+		<author>Author of 8</author>
+	</book>
+	<book>
+		<isbn>9</isbn>
+		<title>Title of 9</title>
+		<author>Author of 9</author>
+	</book>
+	<book>
+		<isbn>10</isbn>
+		<title>Title of 10</title>
+		<author>Author of 10</author>
+	</book>
+	<book>
+		<isbn>11</isbn>
+		<title>Title of 11</title>
+		<author>Author of 11</author>
+	</book>
+	<book>
+		<isbn>12</isbn>
+		<title>Title of 12</title>
+		<author>Author of 12</author>
+	</book>
+	<book>
+		<isbn>13</isbn>
+		<title>Title of 13</title>
+		<author>Author of 13</author>
+	</book>
+	<book>
+		<isbn>14</isbn>
+		<title>Title of 14</title>
+		<author>Author of 14</author>
+	</book>
+	<book>
+		<isbn>15</isbn>
+		<title>Title of 15</title>
+		<author>Author of 15</author>
+	</book>
+	<book>
+		<isbn>16</isbn>
+		<title>Title of 16</title>
+		<author>Author of 16</author>
+	</book>
+	<book>
+		<isbn>17</isbn>
+		<title>Title of 17</title>
+		<author>Author of 17</author>
+	</book>
+	<book>
+		<isbn>18</isbn>
+		<title>Title of 18</title>
+		<author>Author of 18</author>
+	</book>
+	<book>
+		<isbn>19</isbn>
+		<title>Title of 19</title>
+		<author>Author of 19</author>
+	</book>
+	<book>
+		<isbn>20</isbn>
+		<title>Title of 20</title>
+		<author>Author of 20</author>
+	</book>
+</books>
diff --git a/dojox/grid/compat/tests/support/data.php b/dojox/grid/compat/tests/support/data.php
new file mode 100644
index 0000000..1beb6f0
--- /dev/null
+++ b/dojox/grid/compat/tests/support/data.php
@@ -0,0 +1,379 @@
+<?php
+	// db settings
+	$dbserver = 'localhost';
+	$dbuser = 'root';
+	$dbpassword = 'root';
+	
+	error_reporting(E_ALL);
+	
+	/*
+		Simple protocol:
+			- Inputs via POST variables. 
+			- Output is a string that can be evaluated into a JSON
+			  First element of the array contains return status.
+				
+		This simplified tutorial code should not be deployed without a security review.
+	*/
+	
+	@include "json.php";
+	
+	// set up response encoding 
+	header("Content-Type: text/html; charset=utf-8");
+
+	// util
+	function getPostString($inName) {
+		// make sure input strings are 'clean'
+		return mysql_real_escape_string(@$_POST[$inName]);
+	}
+		
+	// used for json encoding
+	$json = new Services_JSON();
+	
+	function echoJson($inData) {
+		global $json;
+		// delay in ms
+		$delay = getPostString('delay');
+		if (!empty($delay))
+			usleep($delay * 1000);
+		echo '/* ' . $json->encode($inData) . ' */';
+	}
+	
+	function error($inMessage) {
+		$inMessage = str_replace('"', '\\"', $inMessage);
+		error_log($inMessage);
+		//echo '/* ({error: true, message: "' . $inMessage . '"}) */';
+		echoJson(array('error' => true, 'message' => $inMessage));
+		exit;
+	}
+
+
+	function getArray($inResult, $inArray="true") {
+		$o = Array();
+		while ($row = ($inArray ? mysql_fetch_row($inResult) : mysql_fetch_object($inResult)))
+			$o[] = $row;
+		return $o;	
+	}
+	
+	// connect to DB
+	mysql_connect($dbserver, $dbuser, $dbpassword);
+
+	// select DB
+	$database = getPostString("database");
+	$database = ($database ? $database : $db);
+	if (!mysql_select_db($database))
+		error('failed to select db: ' . mysql_error());
+
+	// select table
+	$table = getPostString("table");
+	$table = ($table ? $table : $dbtable);
+
+	// cache
+	$colCache = NULL;
+	$pkCache = NULL;
+
+	// set UTF8 output (MySql > 4.0)
+	mysql_query("SET NAMES UTF8");
+	
+	// server, database, table meta data
+	function getDatabases() {
+		$result = mysql_query("SHOW DATABASES");
+		$output = Array();
+		while ($row = mysql_fetch_row($result)) {
+			$r = strtolower($row[0]);
+			if ($r != 'mysql' && $r != 'information_schema')
+				$output[] = $row[0];
+		}	
+		return $output;	
+	}
+	
+	function getTables() {
+		global $database;
+		$result = mysql_query("SHOW TABLES FROM $database");
+		$output = Array();
+		while ($row = mysql_fetch_row($result))
+			$output[] = $row[0];
+		return $output;	
+	}
+	
+	function getColumns() {
+		global $table, $colCache;
+		if (!$colCache) {
+			$result = mysql_query("SHOW COLUMNS FROM `$table`");
+			return getArray($result, false);
+			$colCache = getArray($result, false);
+		}
+		return $colCache;	
+	}
+	
+	// returns object: $this->name, $this->index
+	function getPk() {
+		global $pkCache;
+		if (!$pkCache) {
+			$k = '';
+			$columns = getColumns();
+			for ($i=0; $i < count($columns); $i++) {
+				$c = $columns[$i];
+				if ($c->Key == 'PRI') {
+					$k = $c->Field;
+					break;
+				}	
+			}
+			$pkCache->index = $i;
+			$pkCache->name = $k;
+		}	
+		return $pkCache;
+	}
+	
+	function getTableInfo() {
+		global $table, $database;
+		$c = getColumns();
+		$r = rowcount();
+		return array("count" => $r, "columns" => $c, "database" => $database, "table" => $table);
+	}
+	
+	function getOldPostPkValue() {
+		$pk = getPk();
+		return getPostString('_o' . $pk->index);
+	}
+	
+	function getNewPostPkValue() {
+		$pk = getPk();
+		return getPostString('_' . $pk->index);
+	}
+	
+	function getPostColumns() {
+		$columns = getColumns();
+		for ($i=0, $a=array(), $p; (($p=getPostString("_".$i)) != ''); $i++) {
+			$r = new stdClass();
+			$r->name = $columns[$i]->Field;
+			$r->value = $p;
+			$a[] = $r;
+		}	
+		return $a;
+	}
+	
+	function getOrderBy() {
+		$ob = getPostString("orderby");
+		if (is_numeric($ob)) {
+			$columns = getColumns();
+			$ob = $columns[intval($ob)-1]->Field;
+		}
+		return $ob;
+	}
+	
+	function getWhere() {
+		$w = getPostString("where");
+		return ($w ? " WHERE $w" : "");
+	}
+	
+	// basic operations
+	function rowcount()	{
+		global $table;
+		$query = "SELECT COUNT(*) FROM `$table`" . getWhere();
+		$result = mysql_query($query);
+		if (!$result)
+			error("failed to perform query: $query. " . mysql_error());
+		if ($row = mysql_fetch_row($result))
+			return $row[0];
+		else
+			return 0;
+	}
+	
+	function select($inQuery = '') {
+		global $table;
+		// built limit clause
+		$lim = (int)getPostString("limit");
+		$off = (int)getPostString("offset");
+		$limit = ($lim || $off ? " LIMIT $off, $lim" : "");
+		// build order by clause
+		$desc = (boolean)getPostString("desc");
+		$ob = getOrderBy();
+		$orderby = ($ob ? " ORDER BY `" . $ob . "`" . ($desc ? " DESC" : "") : "");
+		// build query
+		$query = ($inQuery ? $inQuery : "SELECT * FROM `$table`" . getWhere() . $orderby . $limit);
+		// execute query
+		if (!$result = mysql_query($query))
+			error("failed to perform query: $query. " . mysql_error());
+		// fetch each result row 
+		return getArray($result);
+	}
+
+	function reflectRow() {
+		global $table;
+		$pk = getPk();
+		$key = getNewPostPkValue();			
+		$where = "`$pk->name`=\"$key\"";
+		return select("SELECT * FROM `$table` WHERE $where LIMIT 1");
+	}
+	
+	function update() {
+		// build set clause
+		for ($i=0, $set = array(), $cols = getPostColumns(), $v; ($v=$cols[$i]); $i++)
+			$set[] = "`$v->name` = '$v->value'";
+		$set = implode(', ', $set);
+		// our table
+		global $table;
+		// build query
+		$pk = getPk();
+		$pkValue = getOldPostPkValue();
+		$query = "UPDATE `$table` SET $set WHERE `$pk->name` = '$pkValue' LIMIT 1";
+		// execute query
+		if (!mysql_query($query))
+			error("failed to perform query: [$query]. " .
+					"MySql says: [" . mysql_error() ."]");
+		else {
+			return reflectRow();
+		}	
+	}
+	
+	function insert() {
+		global $table;
+		// build values clause
+		for ($i=0, $values = array(), $cols = getPostColumns(), $v; ($v=$cols[$i]); $i++)
+			$values[] = $v->value;
+		$values = '"' . implode('", "', $values) . '"';			
+		// build query
+		$query = "INSERT INTO `$table` VALUES($values)";
+		// execute query
+		if (!mysql_query($query))
+			error("failed to perform query: [$query]. " .
+					"MySql says: [" . mysql_error() ."]");
+		else {
+			return reflectRow();
+		}
+	}
+	
+	function delete() {
+		global $table;
+		// build query
+		$n = getPostString("count");
+		$pk = getPk();
+		for ($i = 0, $deleted=array(); $i < $n; $i++) {
+			$key = getPostString("_$i");
+			array_push($deleted, $key);
+			$query = "DELETE FROM `$table` WHERE `$pk->name`=\"$key\" LIMIT 1";
+			// execute query
+			if (!mysql_query($query) || mysql_affected_rows() != 1)
+				error("failed to perform query: [$query]. " .
+					"Affected rows: " . mysql_affected_rows() .". " . 
+					"MySql says: [" . mysql_error() ."]");
+		}	
+		return $deleted;			
+	}
+	
+	// find (full text search)
+	function findData($inFindCol, $inFind, $inOrderBy, $inFullText) {
+		global $table;
+		$where = ($inFullText ? "WHERE MATCH(`$inFindCol`) AGAINST ('$inFind')" : "WHERE $inFindCol LIKE '$inFind'");
+		$query = "SELECT * FROM $table $where $inOrderBy";
+		$result = mysql_query($query);
+		// return rows
+		return getArray($result);
+	}
+	
+	// binary search through sorted data, supports start point ($inFindFrom) and direction ($inFindForward)
+	function findRow($inData, $inFindFrom=-1, $inFindForward) {
+		$b = -1;
+		$l = count($inData);
+		if (!$inData)
+			return $b;
+		if (!$inFindFrom==-1 || $l < 2)
+			$b = 0;
+		else {
+			// binary search
+			$t = $l-1;
+			$b = 0;
+			while ($b <= $t) {
+				$p = floor(($b+$t)/2);
+				$d = $inData[$p][0];
+				if ($d < $inFindFrom)
+					$b = $p + 1;
+				else if ($d > $inFindFrom)
+					$t = $p - 1;
+				else {
+					$b = $p;
+					break;
+				}	
+			}	
+			if ($inFindFrom == $inData[$b][0]) {
+				// add or subtract 1
+				$b = ($inFindForward ? ($b+1 > $l-1 ? 0 : $b+1) : ($b-1 < 0 ? $l-1 : $b-1) );
+			}	
+			else if (!$inFindForward)
+				// subtract 1
+				$b = ($b-1 < 0 ? $l-1 : $b-1);
+		}	
+		return $inData[$b][0];
+	}
+	
+	function buildFindWhere($inFindData, $inKey, $inCol) {
+		$o = Array();
+		foreach($inFindData as $row)
+			$o[] = $inCol . "='" . $row[$inKey] . "'";
+		return (count($o) ? ' WHERE ' . implode(' OR ', $o) : '');
+	}
+		
+	function find($inFindCol, $inFind='', $inOb='', $inFindFrom=0, $inFindForward=true, $inFullText=true) {
+		global $table;
+		// build order by clause
+		$desc = (boolean)getPostString("desc");
+		if (!$inOb)
+			$inOb = getOrderBy();
+		if ($inOb)
+			$inOb = "`" . $inOb . "`"	;
+		$orderby = ($inOb ? " ORDER BY $inOb " . ($desc ? " DESC" : "") : "");
+		// update inputs from post
+		if (!$inFind)
+			$inFind = getPostString('findText');
+		if (!$inFindCol)
+			$inFindCol = getPostString('findCol');	
+		if (empty($inFindFrom))
+			$inFindFrom = getPostString('findFrom');
+		$ff = getPostString('findForward');
+		if ($ff)
+			$inFindForward = (strtolower($ff) == 'true' ? true : false);
+		$ft = getPostString('findFullText');
+		if ($ft)
+			$inFullText = (strtolower($ft) == 'true' ? true : false);	
+		
+		// get find data
+		$f = findData($inFindCol, $inFind, $orderby,  $inFullText);
+		$pk = getPk();
+
+		// execute query
+		$where = buildFindWhere($f, $pk->index, 'f');
+		$query = "SELECT Row, f FROM (SELECT @row := @row + 1 AS Row, $pk->name as f FROM `$table` $orderby) AS tempTable $where";
+		mysql_query('SET @row = -1;');
+		if (!$result = mysql_query($query))
+			error("failed to perform query: $query. " . mysql_error());
+		
+		// return row number 
+		return findRow(getArray($result), $inFindFrom, $inFindForward);
+	}
+	
+	// our command list
+	$cmds = array( 
+		"count" => "rowcount", 
+		"select" => "select",
+		"update" => "update",
+		"insert" => "insert",
+		"delete" => "delete",
+		"find" => "find",
+		"databases" => "getDatabases",
+		"tables" => "getTables",
+		"columns" => "getColumns",
+		"info" => "getTableInfo"
+	);
+		
+	// process input params
+	$cmd = @$_POST["command"];
+	
+	//$cmd="select";
+	
+	// dispatch command
+	$func = @$cmds[$cmd];
+	if (function_exists($func)) 
+		echoJson(call_user_func($func));
+	else
+		error("bad command");
+?>
diff --git a/dojox/grid/compat/tests/support/geography.xml b/dojox/grid/compat/tests/support/geography.xml
new file mode 100644
index 0000000..070a8c1
--- /dev/null
+++ b/dojox/grid/compat/tests/support/geography.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<opml version="1.0">
+	<head>
+		<title>geography.opml</title>
+		<dateCreated>2006-11-10</dateCreated>
+		<dateModified>2006-11-13</dateModified>
+		<ownerName>Magellan, Ferdinand</ownerName>
+	</head>
+	<body>
+		<outline text="Africa" type="continent">
+			<outline text="Egypt" type="country"/>
+			<outline text="Kenya" type="country">
+				<outline text="Nairobi" type="city"/>
+				<outline text="Mombasa" type="city"/>
+			</outline>
+			<outline text="Sudan" type="country">
+				<outline text="Khartoum" type="city"/>
+			</outline>
+		</outline>
+		<outline text="Asia" type="continent">
+			<outline text="China" type="country"/>
+			<outline text="India" type="country"/>
+			<outline text="Russia" type="country"/>
+			<outline text="Mongolia" type="country"/>
+		</outline>
+		<outline text="Australia" type="continent" population="21 million">
+			<outline text="Australia" type="country" population="21 million"/>
+		</outline>
+		<outline text="Europe" type="continent">
+			<outline text="Germany" type="country"/>
+			<outline text="France" type="country"/>
+			<outline text="Spain" type="country"/>
+			<outline text="Italy" type="country"/>
+		</outline>
+		<outline text="North America" type="continent">
+			<outline text="Mexico" type="country" population="108 million" area="1,972,550 sq km">
+				<outline text="Mexico City" type="city" population="19 million" timezone="-6 UTC"/>
+				<outline text="Guadalajara" type="city" population="4 million" timezone="-6 UTC"/>
+			</outline>
+			<outline text="Canada" type="country" population="33 million" area="9,984,670 sq km">
+				<outline text="Ottawa" type="city" population="0.9 million" timezone="-5 UTC"/>
+				<outline text="Toronto" type="city" population="2.5 million" timezone="-5 UTC"/>
+			</outline>
+			<outline text="United States of America" type="country"/>
+		</outline>
+		<outline text="South America" type="continent">
+			<outline text="Brazil" type="country" population="186 million"/>
+			<outline text="Argentina" type="country" population="40 million"/>
+		</outline>
+	</body>
+</opml>
diff --git a/dojox/grid/compat/tests/support/json.php b/dojox/grid/compat/tests/support/json.php
new file mode 100644
index 0000000..84e3dfa
--- /dev/null
+++ b/dojox/grid/compat/tests/support/json.php
@@ -0,0 +1,794 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/** 
+* Converts to and from JSON format.
+* 
+* JSON (JavaScript Object Notation) is a lightweight data-interchange
+* format. It is easy for humans to read and write. It is easy for machines
+* to parse and generate. It is based on a subset of the JavaScript
+* Programming Language, Standard ECMA-262 3rd Edition - December 1999.
+* This feature can also be found in  Python. JSON is a text format that is
+* completely language independent but uses conventions that are familiar
+* to programmers of the C-family of languages, including C, C++, C#, Java,
+* JavaScript, Perl, TCL, and many others. These properties make JSON an
+* ideal data-interchange language.
+* 
+* This package provides a simple encoder and decoder for JSON notation. It
+* is intended for use with client-side Javascript applications that make
+* use of HTTPRequest to perform server communication functions - data can
+* be encoded into JSON notation for use in a client-side javascript, or
+* decoded from incoming Javascript requests. JSON format is native to
+* Javascript, and can be directly eval()'ed with no further parsing
+* overhead
+*
+* All strings should be in ASCII or UTF-8 format!
+*
+* LICENSE: Redistribution and use in source and binary forms, with or
+* without modification, are permitted provided that the following
+* conditions are met: Redistributions of source code must retain the
+* above copyright notice, this list of conditions and the following
+* disclaimer. Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+* 
+* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+* NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+* DAMAGE.
+* 
+* @category   
+* @package     Services_JSON
+* @author      Michal Migurski <mike-json at teczno.com>
+* @author      Matt Knapp <mdknapp[at]gmail[dot]com>
+* @author      Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
+* @copyright   2005 Michal Migurski
+* @license     http://www.opensource.org/licenses/bsd-license.php
+* @link        http://pear.php.net/pepr/pepr-proposal-show.php?id=198
+*/
+
+/**
+* Marker constant for Services_JSON::decode(), used to flag stack state
+*/
+define('SERVICES_JSON_SLICE',   1);
+
+/**
+* Marker constant for Services_JSON::decode(), used to flag stack state
+*/
+define('SERVICES_JSON_IN_STR',  2);
+
+/**
+* Marker constant for Services_JSON::decode(), used to flag stack state
+*/
+define('SERVICES_JSON_IN_ARR',  4);
+
+/**
+* Marker constant for Services_JSON::decode(), used to flag stack state
+*/
+define('SERVICES_JSON_IN_OBJ',  8);
+
+/**
+* Marker constant for Services_JSON::decode(), used to flag stack state
+*/
+define('SERVICES_JSON_IN_CMT', 16);
+
+/**
+* Behavior switch for Services_JSON::decode()
+*/
+define('SERVICES_JSON_LOOSE_TYPE', 10);
+
+/**
+* Behavior switch for Services_JSON::decode()
+*/
+define('SERVICES_JSON_STRICT_TYPE', 11);
+
+/**
+* Encodings
+*/
+define('SERVICES_JSON_ISO_8859_1', 'iso-8859-1');
+define('SERVICES_JSON_UTF_8', 'utf-8');
+
+/** 
+* Converts to and from JSON format.
+*
+* Brief example of use:
+*
+* <code>
+* // create a new instance of Services_JSON
+* $json = new Services_JSON();
+* 
+* // convert a complexe value to JSON notation, and send it to the browser
+* $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
+* $output = $json->encode($value);
+*
+* print($output);
+* // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
+* 
+* // accept incoming POST data, assumed to be in JSON notation
+* $input = file_get_contents('php://input', 1000000);
+* $value = $json->decode($input);
+* </code>
+*/
+class Services_JSON
+{
+   /**
+    * constructs a new JSON instance
+    *
+		//>> SJM2005
+    * @param    string  $encoding 	Strings are input/output in this encoding
+    * @param    int    $encode 	Encode input is expected in this character encoding
+		//<< SJM2005
+		*
+    * @param    int     $use    object behavior: when encoding or decoding,
+    *                           be loose or strict about object/array usage
+    *
+    *                           possible values:
+    *                           - SERVICES_JSON_STRICT_TYPE: strict typing, default.
+    *                                                        "{...}" syntax creates objects in decode().
+    *                           - SERVICES_JSON_LOOSE_TYPE:  loose typing.
+    *                                                        "{...}" syntax creates associative arrays in decode().
+    */
+    function Services_JSON($encoding = SERVICES_JSON_UTF_8, $use = SERVICES_JSON_STRICT_TYPE)
+    {
+			//>> SJM2005
+			$this->encoding = $encoding;
+			//<< SJM2005
+			
+			$this->use = $use;
+    }
+
+   /**
+    * convert a string from one UTF-16 char to one UTF-8 char
+    *
+    * Normally should be handled by mb_convert_encoding, but
+    * provides a slower PHP-only method for installations
+    * that lack the multibye string extension.
+    *
+    * @param    string  $utf16  UTF-16 character
+    * @return   string  UTF-8 character
+    * @access   private
+    */
+    function utf162utf8($utf16)
+    {
+        // oh please oh please oh please oh please oh please
+        if(function_exists('mb_convert_encoding'))
+            return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
+        
+        $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
+
+        switch(true) {
+            case ((0x7F & $bytes) == $bytes):
+                // this case should never be reached, because we are in ASCII range
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0x7F & $bytes);
+
+            case (0x07FF & $bytes) == $bytes:
+                // return a 2-byte UTF-8 character
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0xC0 | (($bytes >> 6) & 0x1F))
+                     . chr(0x80 | ($bytes & 0x3F));
+
+            case (0xFFFF & $bytes) == $bytes:
+                // return a 3-byte UTF-8 character
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0xE0 | (($bytes >> 12) & 0x0F))
+                     . chr(0x80 | (($bytes >> 6) & 0x3F))
+                     . chr(0x80 | ($bytes & 0x3F));
+        }
+
+        // ignoring UTF-32 for now, sorry
+        return '';
+    }        
+
+   /**
+    * convert a string from one UTF-8 char to one UTF-16 char
+    *
+    * Normally should be handled by mb_convert_encoding, but
+    * provides a slower PHP-only method for installations
+    * that lack the multibye string extension.
+    *
+    * @param    string  $utf8   UTF-8 character
+    * @return   string  UTF-16 character
+    * @access   private
+    */
+    function utf82utf16($utf8)
+    {
+        // oh please oh please oh please oh please oh please
+        if(function_exists('mb_convert_encoding'))
+            return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
+        
+        switch(strlen($utf8)) {
+            case 1:
+                // this case should never be reached, because we are in ASCII range
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return $utf8;
+
+            case 2:
+                // return a UTF-16 character from a 2-byte UTF-8 char
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0x07 & (ord($utf8{0}) >> 2))
+                     . chr((0xC0 & (ord($utf8{0}) << 6))
+                         | (0x3F & ord($utf8{1})));
+                
+            case 3:
+                // return a UTF-16 character from a 3-byte UTF-8 char
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr((0xF0 & (ord($utf8{0}) << 4))
+                         | (0x0F & (ord($utf8{1}) >> 2)))
+                     . chr((0xC0 & (ord($utf8{1}) << 6))
+                         | (0x7F & ord($utf8{2})));
+        }
+
+        // ignoring UTF-32 for now, sorry
+        return '';
+    }        
+
+   /**
+    * encodes an arbitrary variable into JSON format
+    *
+    * @param    mixed   $var    any number, boolean, string, array, or object to be encoded.
+    *                           see argument 1 to Services_JSON() above for array-parsing behavior.
+    *                           if var is a strng, note that encode() always expects it
+    *                           to be in ASCII or UTF-8 format!
+    *
+    * @return   string  JSON string representation of input var
+    * @access   public
+    */
+    function encode($var)
+    {
+        switch (gettype($var)) {
+            case 'boolean':
+                return $var ? 'true' : 'false';
+            
+            case 'NULL':
+                return 'null';
+            
+            case 'integer':
+                return (int) $var;
+                
+            case 'double':
+            case 'float':
+                return (float) $var;
+                
+            case 'string':
+								//>> SJM2005
+								if ($this->encoding == SERVICES_JSON_UTF_8)
+									;
+								else if ($this->encoding == SERVICES_JSON_ISO_8859_1)
+									$var = utf8_encode($var); 
+								else if (!function_exists('mb_convert_encoding'))
+									die('Requested encoding requires mb_strings extension.');
+								else 
+									$var = mb_convert_encoding($var, "utf-8", $this->encoding);
+								//<< SJM2005
+											
+                // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
+                $ascii = '';
+                $strlen_var = strlen($var);
+
+               /*
+                * Iterate over every character in the string,
+                * escaping with a slash or encoding to UTF-8 where necessary
+                */
+                for ($c = 0; $c < $strlen_var; ++$c) {
+                    
+                    $ord_var_c = ord($var{$c});
+                    
+                    switch (true) {
+                        case $ord_var_c == 0x08:
+                            $ascii .= '\b';
+                            break;
+                        case $ord_var_c == 0x09:
+                            $ascii .= '\t';
+                            break;
+                        case $ord_var_c == 0x0A:
+                            $ascii .= '\n';
+                            break;
+                        case $ord_var_c == 0x0C:
+                            $ascii .= '\f';
+                            break;
+                        case $ord_var_c == 0x0D:
+                            $ascii .= '\r';
+                            break;
+
+                        case $ord_var_c == 0x22:
+                        case $ord_var_c == 0x2F:
+                        case $ord_var_c == 0x5C:
+                            // double quote, slash, slosh
+                            $ascii .= '\\'.$var{$c};
+                            break;
+                         
+                        case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
+                            // characters U-00000000 - U-0000007F (same as ASCII)
+                            $ascii .= $var{$c};
+                            break;
+                        
+                        case (($ord_var_c & 0xE0) == 0xC0):
+                            // characters U-00000080 - U-000007FF, mask 110XXXXX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
+                            $c += 1;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+    
+                        case (($ord_var_c & 0xF0) == 0xE0):
+                            // characters U-00000800 - U-0000FFFF, mask 1110XXXX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}));
+                            $c += 2;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+    
+                        case (($ord_var_c & 0xF8) == 0xF0):
+                            // characters U-00010000 - U-001FFFFF, mask 11110XXX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}),
+                                         ord($var{$c + 3}));
+                            $c += 3;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+    
+                        case (($ord_var_c & 0xFC) == 0xF8):
+                            // characters U-00200000 - U-03FFFFFF, mask 111110XX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}),
+                                         ord($var{$c + 3}),
+                                         ord($var{$c + 4}));
+                            $c += 4;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+    
+                        case (($ord_var_c & 0xFE) == 0xFC):
+                            // characters U-04000000 - U-7FFFFFFF, mask 1111110X
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}),
+                                         ord($var{$c + 3}),
+                                         ord($var{$c + 4}),
+                                         ord($var{$c + 5}));
+                            $c += 5;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+                    }
+                }
+                
+                return '"'.$ascii.'"';
+                
+            case 'array':
+               /*
+                * As per JSON spec if any array key is not an integer
+                * we must treat the the whole array as an object. We
+                * also try to catch a sparsely populated associative
+                * array with numeric keys here because some JS engines
+                * will create an array with empty indexes up to
+                * max_index which can cause memory issues and because
+                * the keys, which may be relevant, will be remapped
+                * otherwise.
+                * 
+                * As per the ECMA and JSON specification an object may
+                * have any string as a property. Unfortunately due to
+                * a hole in the ECMA specification if the key is a
+                * ECMA reserved word or starts with a digit the
+                * parameter is only accessible using ECMAScript's
+                * bracket notation.
+                */
+                
+                // treat as a JSON object  
+                if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
+                    return '{' .
+                           join(',', array_map(array($this, 'name_value'),
+                                               array_keys($var),
+                                               array_values($var)))
+                           . '}';
+                }
+
+                // treat it like a regular array
+                return '[' . join(',', array_map(array($this, 'encode'), $var)) . ']';
+                
+            case 'object':
+                $vars = get_object_vars($var);
+                return '{' .
+                       join(',', array_map(array($this, 'name_value'),
+                                           array_keys($vars),
+                                           array_values($vars)))
+                       . '}';
+
+            default:
+                return '';
+        }
+    }
+    
+   /**
+    * array-walking function for use in generating JSON-formatted name-value pairs
+    *
+    * @param    string  $name   name of key to use
+    * @param    mixed   $value  reference to an array element to be encoded
+    *
+    * @return   string  JSON-formatted name-value pair, like '"name":value'
+    * @access   private
+    */
+    function name_value($name, $value)
+    {
+        return $this->encode(strval($name)) . ':' . $this->encode($value);
+    }        
+
+   /**
+    * reduce a string by removing leading and trailing comments and whitespace
+    *
+    * @param    $str    string      string value to strip of comments and whitespace
+    *
+    * @return   string  string value stripped of comments and whitespace
+    * @access   private
+    */
+    function reduce_string($str)
+    {
+        $str = preg_replace(array(
+        
+                // eliminate single line comments in '// ...' form
+                '#^\s*//(.+)$#m',
+    
+                // eliminate multi-line comments in '/* ... */' form, at start of string
+                '#^\s*/\*(.+)\*/#Us',
+    
+                // eliminate multi-line comments in '/* ... */' form, at end of string
+                '#/\*(.+)\*/\s*$#Us'
+    
+            ), '', $str);
+        
+        // eliminate extraneous space
+        return trim($str);
+    }
+
+   /**
+    * decodes a JSON string into appropriate variable
+    *
+    * @param    string  $str    JSON-formatted string
+    *
+    * @return   mixed   number, boolean, string, array, or object
+    *                   corresponding to given JSON input string.
+    *                   See argument 1 to Services_JSON() above for object-output behavior.
+    *                   Note that decode() always returns strings
+    *                   in ASCII or UTF-8 format!
+    * @access   public
+    */
+    function decode($str)
+    {
+				$str = $this->reduce_string($str);
+   			
+        switch (strtolower($str)) {
+            case 'true':
+                return true;
+
+            case 'false':
+                return false;
+            
+            case 'null':
+                return null;
+            
+            default:
+                if (is_numeric($str)) {
+                    // Lookie-loo, it's a number
+
+                    // This would work on its own, but I'm trying to be
+                    // good about returning integers where appropriate:
+                    // return (float)$str;
+
+                    // Return float or int, as appropriate
+                    return ((float)$str == (integer)$str)
+                        ? (integer)$str
+                        : (float)$str;
+                    
+                } elseif (preg_match('/^("|\').+(\1)$/s', $str, $m) && $m[1] == $m[2]) {
+                    // STRINGS RETURNED IN UTF-8 FORMAT
+                    $delim = substr($str, 0, 1);
+                    $chrs = substr($str, 1, -1);
+                    $utf8 = '';
+                    $strlen_chrs = strlen($chrs);
+                    
+                    for ($c = 0; $c < $strlen_chrs; ++$c) {
+                    
+                        $substr_chrs_c_2 = substr($chrs, $c, 2);
+                        $ord_chrs_c = ord($chrs{$c});
+                        
+                        switch (true) {
+                            case $substr_chrs_c_2 == '\b':
+                                $utf8 .= chr(0x08);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\t':
+                                $utf8 .= chr(0x09);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\n':
+                                $utf8 .= chr(0x0A);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\f':
+                                $utf8 .= chr(0x0C);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\r':
+                                $utf8 .= chr(0x0D);
+                                ++$c;
+                                break;
+
+                            case $substr_chrs_c_2 == '\\"':
+                            case $substr_chrs_c_2 == '\\\'':
+                            case $substr_chrs_c_2 == '\\\\':
+                            case $substr_chrs_c_2 == '\\/':
+                                if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
+                                   ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
+                                    $utf8 .= $chrs{++$c};
+                                }
+                                break;
+                                
+                            case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
+																//echo ' matching single escaped unicode character from ' . substr($chrs, $c, 6);
+                                // single, escaped unicode character
+                                $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
+                                       . chr(hexdec(substr($chrs, ($c + 4), 2)));
+                                $utf8 .= $this->utf162utf8($utf16);
+                                $c += 5;
+                                break;
+        
+                            case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
+                                $utf8 .= $chrs{$c};
+                                break;
+        
+                            case ($ord_chrs_c & 0xE0) == 0xC0:
+                                // characters U-00000080 - U-000007FF, mask 110XXXXX
+                                //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 2);
+                                ++$c;
+                                break;
+    
+                            case ($ord_chrs_c & 0xF0) == 0xE0:
+                                // characters U-00000800 - U-0000FFFF, mask 1110XXXX
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 3);
+                                $c += 2;
+                                break;
+    
+                            case ($ord_chrs_c & 0xF8) == 0xF0:
+                                // characters U-00010000 - U-001FFFFF, mask 11110XXX
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 4);
+                                $c += 3;
+                                break;
+    
+                            case ($ord_chrs_c & 0xFC) == 0xF8:
+                                // characters U-00200000 - U-03FFFFFF, mask 111110XX
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 5);
+                                $c += 4;
+                                break;
+    
+                            case ($ord_chrs_c & 0xFE) == 0xFC:
+                                // characters U-04000000 - U-7FFFFFFF, mask 1111110X
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 6);
+                                $c += 5;
+                                break;
+
+                        }
+
+                    }
+                    
+										//>> SJM2005
+										if ($this->encoding == SERVICES_JSON_UTF_8)
+	                    return $utf8;
+										if ($this->encoding == SERVICES_JSON_ISO_8859_1)
+											return utf8_decode($utf8);
+										else if (!function_exists('mb_convert_encoding'))
+											die('Requested encoding requires mb_strings extension.');
+										else 
+											return mb_convert_encoding($utf8, $this->encoding, SERVICES_JSON_UTF_8);
+										//<< SJM2005
+										
+                    return $utf8;
+                
+                } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
+                    // array, or object notation
+                    if ($str{0} == '[') {
+                        $stk = array(SERVICES_JSON_IN_ARR);
+                        $arr = array();
+                    } else {
+                        if ($this->use == SERVICES_JSON_LOOSE_TYPE) {
+                            $stk = array(SERVICES_JSON_IN_OBJ);
+                            $obj = array();
+                        } else {
+                            $stk = array(SERVICES_JSON_IN_OBJ);
+                            $obj = new stdClass();
+                        }
+                    }
+                    
+                    array_push($stk, array('what'  => SERVICES_JSON_SLICE,
+                                           'where' => 0,
+                                           'delim' => false));
+
+                    $chrs = substr($str, 1, -1);
+                    $chrs = $this->reduce_string($chrs);
+                    
+                    if ($chrs == '') {
+                        if (reset($stk) == SERVICES_JSON_IN_ARR) {
+                            return $arr;
+
+                        } else {
+                            return $obj;
+
+                        }
+                    }
+
+                    //print("\nparsing {$chrs}\n");
+                    
+                    $strlen_chrs = strlen($chrs);
+                    for ($c = 0; $c <= $strlen_chrs; ++$c) {
+                    
+                        $top = end($stk);
+                        $substr_chrs_c_2 = substr($chrs, $c, 2);
+                    
+                        if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
+                            // found a comma that is not inside a string, array, etc.,
+                            // OR we've reached the end of the character list
+                            $slice = substr($chrs, $top['where'], ($c - $top['where']));
+                            array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
+                            //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                            if (reset($stk) == SERVICES_JSON_IN_ARR) {
+                                // we are in an array, so just push an element onto the stack
+                                array_push($arr, $this->decode($slice));
+
+                            } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
+                                // we are in an object, so figure
+                                // out the property name and set an
+                                // element in an associative array,
+                                // for now
+                                if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+                                    // "name":value pair
+                                    $key = $this->decode($parts[1]);
+                                    $val = $this->decode($parts[2]);
+
+                                    if ($this->use == SERVICES_JSON_LOOSE_TYPE) {
+                                        $obj[$key] = $val;
+                                    } else {
+                                        $obj->$key = $val;
+                                    }
+                                } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+                                    // name:value pair, where name is unquoted
+                                    $key = $parts[1];
+                                    $val = $this->decode($parts[2]);
+
+                                    if ($this->use == SERVICES_JSON_LOOSE_TYPE) {
+                                        $obj[$key] = $val;
+                                    } else {
+                                        $obj->$key = $val;
+                                    }
+                                }
+
+                            }
+
+                        } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
+                            // found a quote, and we are not inside a string
+                            array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
+                            //print("Found start of string at {$c}\n");
+
+												//>> SAO2006				 
+                        /*} elseif (($chrs{$c} == $top['delim']) &&
+                                 ($top['what'] == SERVICES_JSON_IN_STR) &&
+                                 (($chrs{$c - 1} != '\\')  ||
+																 ($chrs{$c - 1} == '\\' && $chrs{$c - 2} == '\\'))) {*/
+												} elseif ($chrs{$c} == $top['delim'] &&
+                          		$top['what'] == SERVICES_JSON_IN_STR) {			 
+														//print("Found potential end of string at {$c}\n");
+														// verify quote is not escaped: it has no or an even number of \\ before it.
+														for ($i=0; ($chrs{$c - ($i+1)} == '\\'); $i++);
+														/*$i = 0;		
+														while (	$chrs{$c - ($i+1)} == '\\')
+															$i++;*/
+														//print("Found {$i} \ before delim\n");
+														if ($i % 2 != 0)
+														{	
+															//print("delim escaped, not end of string\n");
+															continue;	 
+														} 
+												//>> SAO2006		
+                            // found a quote, we're in a string, and it's not escaped
+                            array_pop($stk);
+                            //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
+
+                        } elseif (($chrs{$c} == '[') &&
+                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+                            // found a left-bracket, and we are in an array, object, or slice
+                            array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
+                            //print("Found start of array at {$c}\n");
+
+                        } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
+                            // found a right-bracket, and we're in an array
+                            array_pop($stk);
+                            //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                        } elseif (($chrs{$c} == '{') &&
+                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+                            // found a left-brace, and we are in an array, object, or slice
+                            array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
+                            //print("Found start of object at {$c}\n");
+
+                        } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
+                            // found a right-brace, and we're in an object
+                            array_pop($stk);
+                            //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                        } elseif (($substr_chrs_c_2 == '/*') &&
+                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+                            // found a comment start, and we are in an array, object, or slice
+                            array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
+                            $c++;
+                            //print("Found start of comment at {$c}\n");
+
+                        } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
+                            // found a comment end, and we're in one now
+                            array_pop($stk);
+                            $c++;
+                            
+                            for ($i = $top['where']; $i <= $c; ++$i)
+                                $chrs = substr_replace($chrs, ' ', $i, 1);
+                            
+                            //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                        }
+                    
+                    }
+                    
+                    if (reset($stk) == SERVICES_JSON_IN_ARR) {
+                        return $arr;
+
+                    } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
+                        return $obj;
+
+                    }
+                
+                }
+        }
+    }
+    
+}
+
+	/*function hex($s)
+	{
+		$l = strlen($s);
+		for ($i=0; $i < $l; $i++)
+			//echo '['.(ord($s{$i})).']';
+			echo '['.bin2hex($s{$i}).']';
+	}
+ 
+	//$d = '["hello world\\""]';
+	$d = '["\\\\\\"hello world,\\\\\\""]';
+	//$d = '["\\\\", "\\\\"]';
+	hex($d);
+	$test = new Services_JSON();
+	echo('<pre>');
+	print_r($d . "\n");
+	print_r($test->decode($d));
+	echo('</pre>');
+	*/	
+?>
\ No newline at end of file
diff --git a/dojox/grid/compat/tests/support/movies.csv b/dojox/grid/compat/tests/support/movies.csv
new file mode 100644
index 0000000..baf71eb
--- /dev/null
+++ b/dojox/grid/compat/tests/support/movies.csv
@@ -0,0 +1,9 @@
+Title, Year, Producer
+City of God, 2002, Katia Lund
+Rain,, Christine Jeffs
+2001: A Space Odyssey, , Stanley Kubrick
+"This is a ""fake"" movie title", 1957, Sidney Lumet
+Alien, 1979   , Ridley Scott
+"The Sequel to ""Dances With Wolves.""", 1982, Ridley Scott
+"Caine Mutiny, The", 1954, "Dymtryk ""the King"", Edward"
+
diff --git a/dojox/grid/compat/tests/support/test_data.js b/dojox/grid/compat/tests/support/test_data.js
new file mode 100644
index 0000000..4707380
--- /dev/null
+++ b/dojox/grid/compat/tests/support/test_data.js
@@ -0,0 +1,30 @@
+// example sample data and code
+(function(){
+	// some sample data
+	// global var "data"
+	data = [ 
+		[ "normal", false, "new", 'But are not followed by two hexadecimal', 29.91, 10, false ],
+		[ "important", false, "new", 'Because a % sign always indicates', 9.33, -5, false ],
+		[ "important", false, "read", 'Signs can be selectively', 19.34, 0, true ],
+		[ "note", false, "read", 'However the reserved characters', 15.63, 0, true ],
+		[ "normal", false, "replied", 'It is therefore necessary', 24.22, 5.50, true ],
+		[ "important", false, "replied", 'To problems of corruption by', 9.12, -3, true ],
+		[ "note", false, "replied", 'Which would simply be awkward in', 12.15, -4, false ]
+	];
+	var rows = 100;
+	for(var i=0, l=data.length; i<rows-l; i++){
+		data.push(data[i%l].slice(0));
+	}
+
+	// global var "model"
+	model = new dojox.grid.data.Table(null, data);
+
+	// simple display of row info; based on model observation
+	// global var "modelChange"
+	modelChange = function(){
+		var n = dojo.byId('rowCount');
+		if(n){
+			n.innerHTML = Number(model.getRowCount()) + ' row(s)';
+		}
+	}
+})();
diff --git a/dojox/grid/compat/tests/support/test_data_objects.js b/dojox/grid/compat/tests/support/test_data_objects.js
new file mode 100644
index 0000000..3d6e43a
--- /dev/null
+++ b/dojox/grid/compat/tests/support/test_data_objects.js
@@ -0,0 +1,31 @@
+// example sample data and code
+(function(){
+	// some sample data
+	// global var "data"
+	data = [ 
+		{ col1: "normal", col2: false, col3: "new", col4: 'But are not followed by two hexadecimal', col5: 29.91, col6: 10, col7: false },
+		{ col1: "important", col2: false, col3: "new", col4: 'Because a % sign always indicates', col5: 9.33, col6: -5, col7: false },
+		{ col1: "important", col2: false, col3: "read", col4: 'Signs can be selectively', col5: 19.34, col6: 0, col7: true },
+		{ col1: "note", col2: false, col3: "read", col4: 'However the reserved characters', col5: 15.63, col6: 0, col7: true },
+		{ col1: "normal", col2: false, col3: "replied", col4: 'It is therefore necessary', col5: 24.22, col6: 5.50, col7: true },
+		{ col1: "important", col2: false, col3: "replied", col4: 'To problems of corruption by', col5: 9.12, col6: -3, col7: true },
+		{ col1: "note", col2: false, col3: "replied", col4: 'Which would simply be awkward in', col5: 12.15, col6: -4, col7: false }
+	];
+	var rows = 100;
+	for(var i=0, l=data.length; i<rows-l; i++){
+		data.push(dojo.mixin({}, data[i%l]));
+	}
+
+	// global var "model"
+	model = new dojox.grid.data.Objects(null, [ { col1: "fake" } ]);
+	model2 = new dojox.grid.data.Objects(null, [ { col1: "fake" } ]);
+
+	// simple display of row info; based on model observation
+	// global var "modelChange"
+	modelChange = function(){
+		var n = dojo.byId('rowCount');
+		if(n){
+			n.innerHTML = Number(model.getRowCount()) + ' row(s)';
+		}
+	}
+})();
diff --git a/dojox/grid/compat/tests/support/testtbl.sql b/dojox/grid/compat/tests/support/testtbl.sql
new file mode 100644
index 0000000..ffe2af3
--- /dev/null
+++ b/dojox/grid/compat/tests/support/testtbl.sql
@@ -0,0 +1,944 @@
+/*
+MySQL Data Transfer
+Source Host: localhost
+Source Database: test
+Target Host: localhost
+Target Database: test
+Date: 12/14/2006 12:13:30 PM
+*/
+
+SET FOREIGN_KEY_CHECKS=0;
+-- ----------------------------
+-- Table structure for testtbl
+-- ----------------------------
+CREATE TABLE `testtbl` (
+  `Id` int(10) unsigned NOT NULL,
+  `Name` varchar(45) NOT NULL default '',
+  `Message` varchar(255) default NULL,
+  `Date` date default '2005-01-01',
+  PRIMARY KEY  (`Id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='InnoDB free: 4096 kB; InnoDB free: 4096 kB; InnoDB free: 409';
+
+-- ----------------------------
+-- Records 
+-- ----------------------------
+INSERT INTO `testtbl` VALUES ('363', ' Lopez, Felipe', ' 0.26', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('364', ' Lopez, Javy', ' 0.267', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('365', ' Lopez, L', ' 0.27', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('366', ' Lopez, Luis', ' 0.244', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('367', ' Lopez, Mendy', ' 0.241', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('368', ' Loretta, Mark', ' 0.289', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('369', ' Lowell, Mike', ' 0.283', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('370', ' Lugo, Julio', ' 0.263', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('371', ' Lunar, Fernando', ' 0.246', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('372', ' Mabry, John', ' 0.208', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('373', ' Machado, Robert', ' 0.222', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('374', ' Macias, Jose', ' 0.268', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('375', ' Mackowiak, Rob', ' 0.266', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('376', ' Magadan, Dave', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('377', ' Magee, Wendell', ' 0.213', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('378', ' Magruder, Chris', ' 0.172', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('379', ' Marrero, Eli', ' 0.266', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('380', ' Martin, Al', ' 0.24', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('381', ' Martinez, Dave', ' 0.287', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('382', ' Martinez, Edgar', ' 0.306', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('383', ' Martinez, Felix', ' 0.247', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('384', ' Martinez, Ramon', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('385', ' Martinez, Ramone', ' 0.253', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('386', ' Martinez, Sandy', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('387', ' Martinez, Tino', ' 0.28', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('388', ' Mateo, Henry', ' 0.333', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('389', ' Mateo, Ruben', ' 0.248', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('390', ' Matheny, Mike', ' 0.218', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('391', ' Matos, Luis', ' 0.214', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('392', ' Mattess, Troy', ' 0.467', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('393', ' Matthews, Gary', ' 0.227', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('394', ' Maurer, Dave', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('395', ' Maxwell, Jason', ' 0.191', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('396', ' Mayne, Brent', ' 0.285', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('397', ' McCarty, David', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('398', ' McCracken, Quinton', ' 0.219', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('399', ' McDonald, Donzell', ' 0.333', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('400', ' McDonald, John', ' 0.091', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('401', ' McDonald, Keith', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('402', ' McEwing, Joe', ' 0.283', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('403', ' McGriff, Fred', ' 0.306', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('404', ' McGuire, Ryan', ' 0.185', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('405', ' McGwire, Mark', ' 0.187', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('406', ' McLemore, Mark', ' 0.286', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('407', ' McMillon, Billy', ' 0.217', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('408', ' McRae, Scott', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('409', ' Meares, Pat', ' 0.211', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('410', ' Melhuse, Adam', ' 0.183', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('411', ' Mendez, Donaldo', ' 0.153', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('412', ' Menechino, Frank', ' 0.242', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('413', ' Merced, Orlando', ' 0.263', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('414', ' Merloni, Lou', ' 0.267', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('415', ' Meyers, Chad', ' 0.118', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('416', ' Michaels, Jason', ' 0.167', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('417', ' Mientkiewicz, Doug', ' 0.306', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('418', ' Millar, Kevin', ' 0.314', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('419', ' Miller, Corky', ' 0.184', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('420', ' Miller, Damian', ' 0.271', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('421', ' Minor, Damion', ' 0.156', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('422', ' Minor, Ryan', ' 0.158', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('423', ' Mirabelli, Doug', ' 0.226', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('424', ' Moeller, Chad', ' 0.232', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('425', ' Mohr, Dustan', ' 0.235', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('426', ' Molina, Ben', ' 0.262', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('427', ' Molina, Jose', ' 0.27', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('428', ' Mondesi, Raul', ' 0.252', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('429', ' Monroe, Craig', ' 0.212', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('430', ' Mora, Melvin', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('431', ' Mordecai, Mike', ' 0.28', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('432', ' Morris, Warren', ' 0.204', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('433', ' Mottola, Chad', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('434', ' Mouton, James', ' 0.246', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('435', ' Mouton, Lyle', ' 0.059', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('436', ' Mueller, Bill', ' 0.295', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('437', ' Munson, Eric', ' 0.152', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('438', ' Murray, Calvin', ' 0.245', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('439', ' Myers, Greg', ' 0.224', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('440', ' Nevin, Phil', ' 0.306', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('441', ' Newhan, David', ' 0.333', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('442', ' Nieves, Jose', ' 0.245', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('443', ' Nixon, Trot', ' 0.28', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('444', ' Norton, Greg', ' 0.267', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('445', ' Nunez, Abraham', ' 0.262', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('446', ' Ochoa, Alex', ' 0.276', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('447', ' Offerman, Jose', ' 0.267', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('448', ' Ojeda, Augie', ' 0.201', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('449', ' O\\\'Leary, Troy', ' 0.24', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('450', ' Olerud, John', ' 0.302', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('451', ' Oliver, Joe', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('452', ' O\\\'Neill, Paul', ' 0.267', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('453', ' Ordaz, Luis', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('454', ' Ordonez, Magglio', ' 0.305', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('455', ' Ordonez, Rey', ' 0.247', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('456', ' Ortega, Bill', ' 0.2', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('457', ' Ortiz, David', ' 0.234', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('458', ' Ortiz, Hector', ' 0.247', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('459', ' Ortiz, Jose', ' 0.24', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('460', ' Osik, Keith', ' 0.208', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('461', ' Overbay, Lyle', ' 0.5', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('462', ' Owens, Eric', ' 0.253', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('463', ' Palmeiro, Orlando', ' 0.243', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('464', ' Palmeiro, Rafael', ' 0.273', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('465', ' Palmer, Dean', ' 0.222', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('466', ' Paquette, Craig', ' 0.282', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('467', ' Patterson, Corey', ' 0.221', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('468', ' Patterson, Jarrod', ' 0.268', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('469', ' Paul, Josh', ' 0.266', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('470', ' Payton, Jay', ' 0.255', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('471', ' Pena, Angel', ' 0.204', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('472', ' Pena, Carlos', ' 0.258', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('473', ' Pena, Elvis', ' 0.225', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('474', ' Perez, Eddie', ' 0.3', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('475', ' Perez, Neifi', ' 0.279', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('476', ' Perez, Robert', ' 0.2', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('477', ' Perez, Santiago', ' 0.198', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('478', ' Perez, Thomas', ' 0.304', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('479', ' Perez, Timoniel', ' 0.247', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('480', ' Perry, Herbert', ' 0.256', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('481', ' Peters, Chris', ' 0.091', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('482', ' Petrick, Ben', ' 0.238', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('483', ' Phelps, Josh', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('484', ' Phillips, Jason', ' 0.143', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('485', ' Piatt, Adam', ' 0.211', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('486', ' Piazza, Mike', ' 0.3', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('487', ' Pickering, Calvin', ' 0.278', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('488', ' Pierre, Juan', ' 0.327', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('489', ' Pierzynski, A.J.', ' 0.289', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('490', ' Podsednik, Scott', ' 0.167', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('491', ' Polanco, Placido', ' 0.307', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('492', ' Porter, Bo', ' 0.23', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('493', ' Posada, Jorge', ' 0.277', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('494', ' Powell, Dante', ' 0.333', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('495', ' Pratt, Todd', ' 0.185', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('496', ' Pride, Curtis', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('497', ' Prince, Tom', ' 0.219', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('498', ' Pujols, Albert', ' 0.329', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('499', ' Punto, Nick', ' 0.4', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('500', ' Quevado, Ruben', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('501', ' Quinn, Mark', ' 0.269', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('502', ' Raines, Tim', ' 0.174', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('503', ' Raines, Tim', ' 0.303', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('504', ' Ramirez, Aramis', ' 0.3', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('505', ' Ramirez, Julio', ' 0.081', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('506', ' Ramirez, Manny', ' 0.306', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('507', ' Randa, Joe', ' 0.253', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('508', ' Ransom, Cody', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('509', ' Reboulet, Jeff', ' 0.266', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('510', ' Redman, Tim', ' 0.224', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('511', ' Redmond, Mike', ' 0.312', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('512', ' Reese, Pokey', ' 0.224', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('513', ' Relaford, Desi', ' 0.302', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('514', ' Renteria, Edgar', ' 0.26', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('515', ' Richard, Chris', ' 0.265', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('516', ' Riggs, Adam', ' 0.194', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('517', ' Rios, Armando', ' 0.26', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('518', ' Ripken, Cal', ' 0.239', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('519', ' Rivas, Luis', ' 0.266', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('520', ' Rivera, Juan', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('521', ' Rivera, Mike', ' 0.333', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('522', ' Rivera, Ruben', ' 0.255', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('523', ' Roberts, Brian', ' 0.253', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('524', ' Roberts, Dave', ' 0.333', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('525', ' Robinson, Kerry', ' 0.285', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('526', ' Rodriguez, Alex', ' 0.318', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('527', ' Rodriguez, Henry', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('528', ' Rodriguez, Ivan', ' 0.308', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('529', ' Rolen, Scott', ' 0.289', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('530', ' Rollins, Jimmy', ' 0.274', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('531', ' Rolls, Damian', ' 0.262', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('532', ' Rowand, Aaron', ' 0.293', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('533', ' Ruffin, Johnny', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('534', ' Ryan, Rob', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('535', ' Sadler, Donnie', ' 0.162', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('536', ' Saenz, Olmedo', ' 0.22', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('537', ' Salmon, Tim', ' 0.227', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('538', ' Sanchez, Alex', ' 0.206', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('539', ' Sanchez, Rey', ' 0.281', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('540', ' Sandberg, Jared', ' 0.206', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('541', ' Sanders, Anthony', ' 0.176', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('542', ' Sanders, Deion', ' 0.173', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('543', ' Sanders, Reggie', ' 0.263', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('544', ' Santana, Pedro', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('545', ' Santangelo, F.P.', ' 0.197', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('546', ' Santiago, Benito', ' 0.262', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('547', ' Santos, Angel', ' 0.125', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('548', ' Saturria, Luis', ' 0.2', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('549', ' Schneider, Brian', ' 0.317', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('550', ' Schourek, Pete', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('551', ' Seabol, Scott', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('552', ' Sefcik, Kevin', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('553', ' Segui, David', ' 0.301', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('554', ' Seguignol, Fernando', ' 0.14', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('555', ' Selby, Bill', ' 0.228', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('556', ' Servais, Scott', ' 0.375', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('557', ' Sexson, Richie', ' 0.271', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('558', ' Sheets, Andy', ' 0.196', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('559', ' Sheffield, Gary', ' 0.311', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('560', ' Sheldon, Scott', ' 0.2', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('561', ' Shinjo, Tsuyoshi', ' 0.268', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('562', ' Shumpert, Terry', ' 0.289', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('563', ' Sierra, Ruben', ' 0.291', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('564', ' Simmons, Brian', ' 0.178', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('565', ' Simon, Randall', ' 0.305', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('566', ' Singleton, Chris', ' 0.298', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('567', ' Smith, Bobby', ' 0.105', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('568', ' Smith, Jason', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('569', ' Smith, Mark', ' 0.242', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('570', ' Snow, J.T.', ' 0.246', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('571', ' Sojo, Luis', ' 0.165', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('572', ' Soriano, Alfonso', ' 0.268', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('573', ' Sosa, Juan', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('574', ' Sosa, Sammy', ' 0.328', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('575', ' Spencer, Shane', ' 0.258', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('576', ' Spiers, Bill', ' 0.333', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('577', ' Spiezio, Scott', ' 0.271', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('578', ' Spivey, Junior', ' 0.258', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('579', ' Sprague, Ed', ' 0.298', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('580', ' Stairs, Matt', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('581', ' Stevens, Lee', ' 0.245', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('582', ' Stewart, Shannon', ' 0.316', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('583', ' Stinnett, Kelly', ' 0.257', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('584', ' Stynes, Chris', ' 0.28', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('585', ' Surhoff, B.J.', ' 0.271', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('586', ' Sutton, Larry', ' 0.119', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('587', ' Suzuki, Ichiro', ' 0.35', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('588', ' Sweeney, Mark', ' 0.258', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('589', ' Sweeney, Mike', ' 0.304', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('590', ' Tapani, Kevin', ' 0.24', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('591', ' Tatis, Fernando', ' 0.255', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('592', ' Taubensee, Eddie', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('593', ' Taylor, Reggie', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('594', ' Tejada, Miguel', ' 0.267', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('595', ' Thomas, Frank', ' 0.221', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('596', ' Thome, Jim', ' 0.291', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('597', ' Thompson, Ryan', ' 0.29', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('598', ' Toca, Jorge', ' 0.176', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('599', ' Torrealba, Steve', ' 0.5', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('600', ' Torrealba, Yorvit', ' 0.5', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('601', ' Tracy, Andy', ' 0.109', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('602', ' Trammell, Bubba', ' 0.261', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('603', ' Truby, Chris', ' 0.206', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('604', ' Tucker, Michael', ' 0.252', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('605', ' Tyner, Jason', ' 0.28', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('606', ' Uribe, Juan', ' 0.3', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('607', ' Valdez, Mario', ' 0.278', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('608', ' Valent, Eric', ' 0.098', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('609', ' Valentin, John', ' 0.2', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('610', ' Valentin, Jose', ' 0.258', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('611', ' VanderWal, John', ' 0.27', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('612', ' Varitek, Jason', ' 0.293', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('613', ' Vaughn, Greg', ' 0.233', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('614', ' Vazquez, Ramon', ' 0.229', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('615', ' Velandia, Jorge', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('616', ' Velarde, Randy', ' 0.278', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('617', ' Ventura, Robin', ' 0.237', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('618', ' Veras, Quilvio', ' 0.252', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('619', ' Vidro, Jose', ' 0.319', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('620', ' Vina, Fernando', ' 0.303', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('621', ' Vizcaino, Jose', ' 0.277', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('622', ' Vizquel, Omar', ' 0.255', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('623', ' Wakeland, Chris', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('624', ' Walbeck, Matt', ' 1', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('625', ' Walker, Larry', ' 0.35', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('626', ' Walker, Todd', ' 0.296', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('627', ' Ward, Daryle', ' 0.263', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('628', ' Ward, Turner', ' 0.267', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('629', ' Wehner, John', ' 0.196', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('630', ' Wells, Vernon', ' 0.313', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('631', ' White, Devon', ' 0.277', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('632', ' White, Rondell', ' 0.307', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('633', ' Whiteside, Matt', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('634', ' Wilkerson, Brad', ' 0.205', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('635', ' Wilkins, Rick', ' 0.182', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('636', ' Williams, Bernie', ' 0.307', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('637', ' Williams, Gerald', ' 0.201', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('638', ' Williams, Matt', ' 0.275', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('639', ' Wilson, Craig', ' 0.31', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('640', ' Wilson, Dan', ' 0.265', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('641', ' Wilson, Enrique', ' 0.211', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('642', ' Wilson, Jack', ' 0.223', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('643', ' Wilson, Preston', ' 0.274', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('644', ' Wilson, Tom', ' 0.19', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('645', ' Wilson, Vance', ' 0.298', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('646', ' Winn, Randy', ' 0.273', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('647', ' Witt, Kevin', ' 0.185', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('648', ' Womack, Tony', ' 0.266', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('649', ' Woodward, Chris', ' 0.19', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('650', ' Wooten, Shawn', ' 0.312', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('651', ' Young, Dmitri', ' 0.302', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('652', ' Young, Eric', ' 0.279', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('653', ' Young, Kevin', ' 0.232', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('654', ' Young, Mike', ' 0.249', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('655', ' Zaun, Greg', ' 0.32', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('656', ' Zeile, Todd', ' 0.266', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('657', ' Zuleta, Julio', ' 0.217', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('658', ' Abernathy, Brent', ' 0.242', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('659', ' Abreu, Bob', ' 0.308', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('660', ' Agbayani, Benny', ' 0.227', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('661', ' Alcantara, Israel', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('662', ' Aldridge, Cory', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('663', ' Alfonzo, Edgardo', ' 0.308', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('664', ' Alicea, Luis', ' 0.228', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('665', ' Allen, Chad', ' 0.1', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('666', ' Allen, Luke', ' 0.143', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('667', ' Alomar, Roberto', ' 0.266', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('668', ' Alomar, Sandy', ' 0.279', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('669', ' Alou, Moises', ' 0.275', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('670', ' Alvarez, Tony', ' 0.308', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('671', ' Amezaga, Alfredo', ' 0.538', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('672', ' Anderson, Brady', ' 0.163', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('673', ' Anderson, Garret', ' 0.306', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('674', ' Anderson, Marlon', ' 0.258', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('675', ' Andrews, Shane', ' 0.077', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('676', ' Arias, Alex', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('677', ' Aurilia, Rich', ' 0.257', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('678', ' Ausmus, Brad', ' 0.257', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('679', ' Aven, Bruce', ' 0.118', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('680', ' Baerga, Carlos', ' 0.286', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('681', ' Bagwell, Jeff', ' 0.291', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('682', ' Bako, Paul', ' 0.235', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('683', ' Banks, Brian', ' 0.321', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('684', ' Barajas, Rod', ' 0.234', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('685', ' Bard, Josh', ' 0.222', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('686', ' Barker, Kevin', ' 0.158', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('687', ' Barrett, Michael', ' 0.263', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('688', ' Batista, Tony', ' 0.244', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('689', ' Bautista, Danny', ' 0.325', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('690', ' Bell, David', ' 0.261', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('691', ' Bell, Jay', ' 0.163', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('692', ' Belle, Albert', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('693', ' Bellhorn, Mark', ' 0.258', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('694', ' Belliard, Ron', ' 0.211', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('695', ' Bellinger, Clay', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('696', ' Beltran, Carlos', ' 0.273', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('697', ' Beltre, Adrian', ' 0.257', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('698', ' Benard, Marvin', ' 0.276', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('699', ' Benjamin, Mike', ' 0.15', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('700', ' Bennett, Gary', ' 0.265', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('701', ' Berg, David', ' 0.27', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('702', ' Berger, Brandon', ' 0.201', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('703', ' Bergeron, Peter', ' 0.187', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('704', ' Berkman, Lance', ' 0.292', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('705', ' Berroa, Angel', ' 0.227', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('706', ' Bigbie, Larry', ' 0.176', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('707', ' Biggio, Craig', ' 0.253', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('708', ' Blake, Casey', ' 0.2', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('709', ' Blalock, Hank', ' 0.211', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('710', ' Blanco, Henry', ' 0.204', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('711', ' Bloomquist, Willie', ' 0.455', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('712', ' Blum, Geoff', ' 0.283', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('713', ' Bocachica, Hiram', ' 0.22', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('714', ' Bonds, Barry', ' 0.37', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('715', ' Boone, Aaron', ' 0.241', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('716', ' Boone, Bret', ' 0.278', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('717', ' Borchard, Joe', ' 0.222', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('718', ' Borders, Pat', ' 0.5', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('719', ' Bordick, Mike', ' 0.232', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('720', ' Bradley, Milton', ' 0.249', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('721', ' Bragg, Darren', ' 0.269', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('722', ' Branyan, Russell', ' 0.228', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('723', ' Brito, Juan', ' 0.304', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('724', ' Broussard, Ben', ' 0.241', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('725', ' Brown, Adrian', ' 0.216', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('726', ' Brown, Dermal', ' 0.235', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('727', ' Brown, Kevin', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('728', ' Brown, Roosevelt', ' 0.211', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('729', ' Buchanan, Brian', ' 0.269', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('730', ' Burks, Ellis', ' 0.301', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('731', ' Burnitz, Jeromy', ' 0.215', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('732', ' Burrell, Pat', ' 0.282', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('733', ' Burroughs, Sean', ' 0.271', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('734', ' Bush, Homer', ' 0.227', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('735', ' Butler, Brent', ' 0.259', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('736', ' Byrd, Marlon', ' 0.229', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('737', ' Byrnes, Eric', ' 0.245', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('738', ' Cabrera, Jolbert', ' 0.143', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('739', ' Cabrera, Orlando', ' 0.263', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('740', ' Cairo, Miguel', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('741', ' Cameron, Mike', ' 0.239', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('742', ' Canizaro, Jay', ' 0.214', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('743', ' Cardona, Javier', ' 0.103', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('744', ' Carroll, Jamey', ' 0.31', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('745', ' Caruso, Mike', ' 0.1', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('746', ' Casanova, Raul', ' 0.182', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('747', ' Casey, Sean', ' 0.261', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('748', ' Cash, Kevin', ' 0.143', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('749', ' Castilla, Vinny', ' 0.232', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('750', ' Castillo, Alberto', ' 0.135', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('751', ' Castillo, Luis', ' 0.305', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('752', ' Castro, Juan', ' 0.22', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('753', ' Castro, Ramon', ' 0.238', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('754', ' Catalanotto, Frank', ' 0.269', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('755', ' Cedeno, Roger', ' 0.26', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('756', ' Cepicky, Matt', ' 0.216', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('757', ' Chavez, Endy', ' 0.296', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('758', ' Chavez, Eric', ' 0.275', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('759', ' Chavez, Raul', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('760', ' Chen, Chin-Feng', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('761', ' Choi, Hee Seop', ' 0.18', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('762', ' Christensen, McKay', ' 0.333', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('763', ' Christenson, Ryan', ' 0.155', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('764', ' Cintron, Alex', ' 0.213', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('765', ' Cirillo, Jeff', ' 0.249', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('766', ' Clark, Brady', ' 0.192', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('767', ' Clark, Howie', ' 0.302', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('768', ' Clark, Tony', ' 0.207', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('769', ' Clayton, Royce', ' 0.251', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('770', ' Colangelo, Mike', ' 0.174', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('771', ' Colbrunn, Greg', ' 0.333', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('772', ' Coleman, Michael', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('773', ' Collier, Lou', ' 0.091', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('774', ' Conine, Jeff', ' 0.273', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('775', ' Conti, Jason', ' 0.257', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('776', ' Coolbaugh, Mike', ' 0.083', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('777', ' Coomer, Ron', ' 0.264', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('778', ' Cora, Alex', ' 0.291', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('779', ' Cordero, Wil', ' 0.267', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('780', ' Cordova, Marty', ' 0.253', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('781', ' Cota, Humberto', ' 0.294', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('782', ' Counsell, Craig', ' 0.282', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('783', ' Cox, Steve', ' 0.254', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('784', ' Crawford, Carl', ' 0.259', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('785', ' Crede, Joe', ' 0.285', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('786', ' Crespo, Cesar', ' 0.172', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('787', ' Crisp, Covelli', ' 0.26', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('788', ' Cruz, Deivi', ' 0.263', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('789', ' Cruz, Ivan', ' 0.357', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('790', ' Cruz, Jacob', ' 0.273', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('791', ' Cruz, Jose', ' 0.245', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('792', ' Cuddyer, Michael', ' 0.259', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('793', ' Cust, Jack', ' 0.169', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('794', ' Damon, Johnny', ' 0.286', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('795', ' Daubach, Brian', ' 0.266', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('796', ' DaVanon, Jeff', ' 0.167', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('797', ' Davis, Ben', ' 0.259', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('798', ' Davis, J.J.', ' 0.1', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('799', ' Dawkins, Travis', ' 0.125', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('800', ' DeHaan, Kory', ' 0.091', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('801', ' Delgado, Carlos', ' 0.277', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('802', ' Delgado, Wilson', ' 0.2', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('803', ' Dellucci, David', ' 0.245', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('804', ' DeRosa, Mark', ' 0.297', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('805', ' DeShields, Delino', ' 0.192', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('806', ' Diaz, Einar', ' 0.206', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('807', ' Diaz, Juan Carlos', ' 0.286', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('808', ' DiFelice, Mike', ' 0.23', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('809', ' Donnels, Chris', ' 0.238', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('810', ' Drew, J.D.', ' 0.252', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('811', ' Dunn, Adam', ' 0.249', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('812', ' Dunston, Shawon', ' 0.231', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('813', ' Dunwoody, Todd', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('814', ' Durazo, Erubiel', ' 0.261', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('815', ' Durham, Ray', ' 0.289', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('816', ' Dye, Jermaine', ' 0.252', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('817', ' Easley, Damion', ' 0.224', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('818', ' Echevarria, Angel', ' 0.306', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('819', ' Eckstein, David', ' 0.293', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('820', ' Edmonds, Jim', ' 0.311', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('821', ' Ellis, Mark', ' 0.272', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('822', ' Encarnacion, Juan', ' 0.271', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('823', ' Encarnacion, Mario', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('824', ' Ensberg, Morgan', ' 0.242', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('825', ' Erstad, Darin', ' 0.283', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('826', ' Escalona, Felix', ' 0.217', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('827', ' Escobar, Alex', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('828', ' Estalella, Bobby', ' 0.205', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('829', ' Estrada, Johnny', ' 0.118', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('830', ' Everett, Adam', ' 0.193', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('831', ' Everett, Carl', ' 0.267', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('832', ' Fabregas, Jorge', ' 0.181', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('833', ' Fasano, Sal', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('834', ' Febles, Carlos', ' 0.245', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('835', ' Feliz, Pedro', ' 0.253', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('836', ' Fick, Robert', ' 0.27', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('837', ' Figgins, Chone', ' 0.167', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('838', ' Finley, Steve', ' 0.287', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('839', ' Flaherty, John', ' 0.26', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('840', ' Fletcher, Darrin', ' 0.22', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('841', ' Flores, Jose', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('842', ' Floyd, Cliff', ' 0.288', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('843', ' Fordyce, Brook', ' 0.231', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('844', ' Fox, Andy', ' 0.251', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('845', ' Franco, Julio', ' 0.284', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('846', ' Franco, Matt', ' 0.317', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('847', ' Fryman, Travis', ' 0.217', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('848', ' Fullmer, Brad', ' 0.289', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('849', ' Furcal, Rafael', ' 0.275', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('850', ' Galarraga, Andres', ' 0.26', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('851', ' Gant, Ron', ' 0.262', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('852', ' Garcia, Jesse', ' 0.197', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('853', ' Garcia, Karim', ' 0.297', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('854', ' Garcia, Luis', ' 0.333', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('855', ' Garciaparra, Nomar', ' 0.31', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('856', ' German, Esteban', ' 0.2', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('857', ' Giambi, Jason', ' 0.314', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('858', ' Giambi, Jeremy', ' 0.259', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('859', ' Gibbons, Jay', ' 0.247', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('860', ' Gil, Benji', ' 0.285', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('861', ' Gil, Geronimo', ' 0.232', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('862', ' Giles, Brian', ' 0.298', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('863', ' Giles, Marcus', ' 0.23', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('864', ' Ginter, Keith', ' 0.235', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('865', ' Gipson, Charles', ' 0.236', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('866', ' Girardi, Joe', ' 0.226', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('867', ' Glanville, Doug', ' 0.249', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('868', ' Glaus, Troy', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('869', ' Gload, Ross', ' 0.258', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('870', ' Gomez, Alexis', ' 0.2', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('871', ' Gomez, Chris', ' 0.265', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('872', ' Gonzalez, Alex', ' 0.225', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('873', ' Gonzalez, Alex', ' 0.248', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('874', ' Gonzalez, Juan', ' 0.282', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('875', ' Gonzalez, Luis', ' 0.288', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('876', ' Gonzalez, Raul', ' 0.26', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('877', ' Gonzalez, Wiki', ' 0.22', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('878', ' Goodwin, Tom', ' 0.26', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('879', ' Grabowski, Jason', ' 0.375', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('880', ' Grace, Mark', ' 0.252', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('881', ' Graffanino, Tony', ' 0.262', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('882', ' Green, Nick', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('883', ' Green, Shawn', ' 0.285', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('884', ' Greene, Todd', ' 0.268', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('885', ' Greer, Rusty', ' 0.296', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('886', ' Grieve, Ben', ' 0.251', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('887', ' Griffey, Ken', ' 0.264', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('888', ' Grissom, Marquis', ' 0.277', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('889', ' Grudzielanek, Mark', ' 0.271', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('890', ' Guerrero, Vladimir', ' 0.336', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('891', ' Guerrero, Wilton', ' 0.221', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('892', ' Guiel, Aaron', ' 0.233', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('893', ' Guillen, Carlos', ' 0.261', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('894', ' Guillen, Jose', ' 0.238', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('895', ' Gutierrez, Ricky', ' 0.275', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('896', ' Guzman, Christian', ' 0.273', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('897', ' Hafner, Travis', ' 0.242', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('898', ' Hairston, Jerry', ' 0.268', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('899', ' Hall, Bill', ' 0.194', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('900', ' Hall, Toby', ' 0.258', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('901', ' Halter, Shane', ' 0.239', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('902', ' Hammonds, Jeffrey', ' 0.257', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('903', ' Hansen, Dave', ' 0.292', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('904', ' Harris, Lenny', ' 0.305', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('905', ' Harris, Willie', ' 0.233', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('906', ' Hart, Jason', ' 0.267', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('907', ' Haselman, Bill', ' 0.246', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('908', ' Hatteberg, Scott', ' 0.28', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('909', ' Helms, Wes', ' 0.243', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('910', ' Helton, Todd', ' 0.329', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('911', ' Henderson, Rickey', ' 0.223', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('912', ' Henson, Drew', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('913', ' Hermansen, Chad', ' 0.207', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('914', ' Hernandez, Jose', ' 0.288', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('915', ' Hernandez, Ramon', ' 0.233', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('916', ' Hidalgo, Richard', ' 0.235', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('917', ' Higginson, Bobby', ' 0.282', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('918', ' Hill, Bobby', ' 0.253', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('919', ' Hillenbrand, Shea', ' 0.293', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('920', ' Hinch, A.J.', ' 0.249', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('921', ' Hinske, Eric', ' 0.279', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('922', ' Hocking, Denny', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('923', ' Hollandsworth, Todd', ' 0.284', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('924', ' Hollins, Dave', ' 0.118', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('925', ' Hoover, Paul', ' 0.176', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('926', ' Houston, Tyler', ' 0.281', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('927', ' Hubbard, Trenidad', ' 0.209', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('928', ' Huckaby, Ken', ' 0.245', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('929', ' Hudson, Orlando', ' 0.276', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('930', ' Huff, Aubrey', ' 0.313', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('931', ' Hundley, Todd', ' 0.211', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('932', ' Hunter, Brian L.', ' 0.269', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('933', ' Hunter, Torii', ' 0.289', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('934', ' Hyzdu, Adam', ' 0.232', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('935', ' Ibanez, Raul', ' 0.294', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('936', ' Infante, Omar', ' 0.333', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('937', ' Inge, Brandon', ' 0.202', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('938', ' Izturis, Cesar', ' 0.232', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('939', ' Jackson, Damian', ' 0.257', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('940', ' Jackson, Ryan', ' 0.333', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('941', ' Jenkins, Geoff', ' 0.243', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('942', ' Jensen, Marcus', ' 0.114', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('943', ' Jeter, Derek', ' 0.297', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('944', ' Jimenez, D\\\'Angelo', ' 0.252', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('945', ' Johnson, Charles', ' 0.217', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('946', ' Johnson, Mark', ' 0.209', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('947', ' Johnson, Mark P.', ' 0.137', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('948', ' Johnson, Nick', ' 0.243', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('949', ' Johnson, Russ', ' 0.216', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('950', ' Jones, Andruw', ' 0.264', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('951', ' Jones, Chipper', ' 0.327', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('952', ' Jones, Jacque', ' 0.3', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('953', ' Jordan, Brian', ' 0.285', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('954', ' Jose, Felix', ' 0.263', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('955', ' Justice, David', ' 0.266', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('956', ' Kapler, Gabe', ' 0.279', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('957', ' Karros, Eric', ' 0.271', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('958', ' Kearns, Austin', ' 0.315', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('959', ' Kelly, Kenny', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('960', ' Kendall, Jason', ' 0.283', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('961', ' Kennedy, Adam', ' 0.312', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('962', ' Kent, Jeff', ' 0.313', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('963', ' Kielty, Bobby', ' 0.291', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('964', ' Kingsale, Eugene', ' 0.283', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('965', ' Kinkade, Mike', ' 0.38', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('966', ' Klassen, Danny', ' 0.333', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('967', ' Klesko, Ryan', ' 0.3', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('968', ' Knoblauch, Chuck', ' 0.21', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('969', ' Konerko, Paul', ' 0.304', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('970', ' Koskie, Corey', ' 0.267', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('971', ' Kotsay, Mark', ' 0.292', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('972', ' Kreuter, Chad', ' 0.263', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('973', ' Lamb, David', ' 0.1', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('974', ' Lamb, Mike', ' 0.283', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('975', ' Lampkin, Tom', ' 0.217', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('976', ' Lane, Jason', ' 0.29', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('977', ' Langerhans, Ryan', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('978', ' Lankford, Ray', ' 0.224', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('979', ' Larkin, Barry', ' 0.245', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('980', ' LaRocca, Greg', ' 0.269', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('981', ' Larson, Brandon', ' 0.275', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('982', ' LaRue, Jason', ' 0.249', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('983', ' Lawrence, Joe', ' 0.18', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('984', ' Lawton, Matt', ' 0.236', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('985', ' LeCroy, Matt', ' 0.26', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('986', ' Ledee, Ricky', ' 0.227', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('987', ' Lee, Carlos', ' 0.264', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('988', ' Lee, Derrek', ' 0.27', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('989', ' Lee, Travis', ' 0.265', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('990', ' Leon, Jose', ' 0.247', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('991', ' Lesher, Brian', ' 0.132', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('992', ' Lewis, Darren', ' 0.241', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('993', ' Lieberthal, Mike', ' 0.279', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('994', ' Liefer, Jeff', ' 0.23', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('995', ' Little, Mark', ' 0.208', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('996', ' Lo Duca, Paul', ' 0.281', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('997', ' Lockhart, Keith', ' 0.216', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('998', ' Lofton, Kenny', ' 0.261', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('999', ' Lombard, George', ' 0.241', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1000', ' Long, Terrence', ' 0.24', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1001', ' Lopez, Felipe', ' 0.227', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1002', ' Lopez, Javy', ' 0.233', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1003', ' Lopez, Luis', ' 0.197', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1004', ' Lopez, Mendy', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1005', ' Loretta, Mark', ' 0.304', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1006', ' Lowell, Mike', ' 0.276', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1007', ' Ludwick, Ryan', ' 0.235', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1008', ' Lugo, Julio', ' 0.261', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1009', ' Lunar, Fernando', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1010', ' Lunsford, Trey', ' 0.667', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1011', ' Mabry, John', ' 0.276', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1012', ' Machado, Robert', ' 0.261', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1013', ' Macias, Jose', ' 0.249', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1014', ' Mackowiak, Rob', ' 0.244', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1015', ' Magee, Wendell', ' 0.271', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1016', ' Magruder, Chris', ' 0.217', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1017', ' Mahoney, Mike', ' 0.207', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1018', ' Malloy, Marty', ' 0.12', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1019', ' Marrero, Eli', ' 0.262', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1020', ' Martinez, Dave', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1021', ' Martinez, Edgar', ' 0.277', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1022', ' Martinez, Ramon', ' 0.271', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1023', ' Martinez, Tino', ' 0.262', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1024', ' Martinez, Victor', ' 0.281', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1025', ' Mateo, Henry', ' 0.174', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1026', ' Mateo, Ruben', ' 0.256', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1027', ' Matheny, Mike', ' 0.244', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1028', ' Matos, Julios', ' 0.238', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1029', ' Matos, Luis', ' 0.129', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1030', ' Matthews, Gary', ' 0.275', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1031', ' Mayne, Brent', ' 0.236', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1032', ' McCarty, David', ' 0.136', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1033', ' McCracken, Quinton', ' 0.309', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1034', ' McDonald, Donzell', ' 0.182', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1035', ' McDonald, John', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1036', ' McEwing, Joe', ' 0.199', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1037', ' McGriff, Fred', ' 0.273', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1038', ' McGuire, Ryan', ' 0.077', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1039', ' McKay, Cody', ' 0.667', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1040', ' McKeel, Walt', ' 0.308', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1041', ' McLemore, Mark', ' 0.27', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1042', ' Meares, Pat', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1043', ' Meluskey, Mitch', ' 0.222', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1044', ' Mench, Kevin', ' 0.26', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1045', ' Menechino, Frank', ' 0.205', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1046', ' Merced, Orlando', ' 0.287', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1047', ' Merloni, Lou', ' 0.247', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1048', ' Michaels, Jason', ' 0.267', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1049', ' Mientkiewicz, Doug', ' 0.261', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1050', ' Millar, Kevin', ' 0.306', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1051', ' Miller, Corky', ' 0.254', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1052', ' Miller, Damian', ' 0.249', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1053', ' Minor, Damon', ' 0.237', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1054', ' Mirabelli, Doug', ' 0.225', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1055', ' Moeller, Chad', ' 0.286', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1056', ' Mohr, Dustan', ' 0.269', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1057', ' Molina, Ben', ' 0.245', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1058', ' Molina, Izzy', ' 0.333', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1059', ' Molina, Jose', ' 0.271', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1060', ' Mondesi, Raul', ' 0.232', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1061', ' Monroe, Craig', ' 0.12', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1062', ' Mora, Melvin', ' 0.233', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1063', ' Mordecai, Mike', ' 0.245', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1064', ' Moriarty, Mike', ' 0.188', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1065', ' Morris, Warren', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1066', ' Mueller, Bill', ' 0.262', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1067', ' Munson, Eric', ' 0.186', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1068', ' Murray, Calvin', ' 0.146', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1069', ' Myers, Greg', ' 0.222', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1070', ' Nelson, Bryant', ' 0.265', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1071', ' Nevin, Phil', ' 0.285', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1072', ' Nieves, Jose', ' 0.289', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1073', ' Nieves, Wil', ' 0.181', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1074', ' Nixon, Trot', ' 0.256', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1075', ' Norton, Greg', ' 0.22', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1076', ' Nunez, Abraham', ' 0.233', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1077', ' Nunez, Abraham', ' 0.118', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1078', ' O\\\'Leary, Troy', ' 0.286', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1079', ' Ochoa, Alex', ' 0.261', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1080', ' Offerman, Jose', ' 0.232', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1081', ' Ojeda, Augie', ' 0.186', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1082', ' Olerud, John', ' 0.3', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1083', ' Olivo, Miguel', ' 0.211', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1084', ' Ordaz, Luis', ' 0.223', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1085', ' Ordonez, Magglio', ' 0.32', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1086', ' Ordonez, Rey', ' 0.254', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1087', ' Orie, Kevin', ' 0.281', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1088', ' Ortiz, David', ' 0.272', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1089', ' Ortiz, Hector', ' 0.214', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1090', ' Ortiz, Jose', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1091', ' Osik, Keith', ' 0.16', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1092', ' Overbay, Lyle', ' 0.1', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1093', ' Owens, Eric', ' 0.27', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1094', ' Ozuna, Pablo', ' 0.277', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1095', ' Palmeiro, Orlando', ' 0.3', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1096', ' Palmeiro, Rafael', ' 0.273', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1097', ' Palmer, Dean', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1098', ' Paquette, Craig', ' 0.194', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1099', ' Patterson, Corey', ' 0.253', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1100', ' Paul, Josh', ' 0.24', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1101', ' Payton, Jay', ' 0.303', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1102', ' Pelaez, Alex', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1103', ' Pellow, Kip', ' 0.238', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1104', ' Pena, Carlos', ' 0.242', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1105', ' Pena, Wily Mo', ' 0.222', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1106', ' Perez, Eddie', ' 0.214', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1107', ' Perez, Eduardo', ' 0.201', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1108', ' Perez, Neifi', ' 0.236', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1109', ' Perez, Timoniel', ' 0.295', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1110', ' Perez, Tomas', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1111', ' Perry, Chan', ' 0.091', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1112', ' Perry, Herbert', ' 0.276', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1113', ' Petrick, Ben', ' 0.211', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1114', ' Phelps, Josh', ' 0.309', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1115', ' Phillips, Brandon', ' 0.258', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1116', ' Phillips, Jason', ' 0.368', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1117', ' Piatt, Adam', ' 0.234', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1118', ' Piazza, Mike', ' 0.28', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1119', ' Pickering, Calvin', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1120', ' Pierre, Juan', ' 0.287', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1121', ' Pierzynski, A.J.', ' 0.3', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1122', ' Podsednik, Scott', ' 0.2', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1123', ' Polanco, Placido', ' 0.288', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1124', ' Posada, Jorge', ' 0.268', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1125', ' Pratt, Todd', ' 0.311', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1126', ' Prince, Tom', ' 0.224', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1127', ' Pujols, Albert', ' 0.314', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1128', ' Punto, Nick', ' 0.167', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1129', ' Quinn, Mark', ' 0.237', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1130', ' Raines, Tim', ' 0.191', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1131', ' Ramirez, Aramis', ' 0.234', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1132', ' Ramirez, Julio', ' 0.281', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1133', ' Ramirez, Manny', ' 0.349', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1134', ' Randa, Joe', ' 0.282', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1135', ' Ransom, Cody', ' 0.667', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1136', ' Reboulet, Jeff', ' 0.208', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1137', ' Redmond, Mike', ' 0.305', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1138', ' Reese, Pokey', ' 0.264', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1139', ' Relaford, Desi', ' 0.267', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1140', ' Renteria, Edgar', ' 0.305', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1141', ' Restovich, Mike', ' 0.308', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1142', ' Richard, Chris', ' 0.232', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1143', ' Rios, Armando', ' 0.264', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1144', ' Rivas, Luis', ' 0.256', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1145', ' Rivera, Juan', ' 0.265', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1146', ' Rivera, Mike', ' 0.227', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1147', ' Rivera, Ruben', ' 0.209', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1148', ' Roberts, Brian', ' 0.227', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1149', ' Roberts, Dave', ' 0.277', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1150', ' Robinson, Kerry', ' 0.26', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1151', ' Rodriguez, Alex', ' 0.3', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1152', ' Rodriguez, Henry', ' 0.05', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1153', ' Rodriguez, Ivan', ' 0.314', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1154', ' Rogers, Ed', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1155', ' Rolen, Scott', ' 0.266', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1156', ' Rollins, Jimmy', ' 0.245', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1157', ' Rolls, Damian', ' 0.292', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1158', ' Romano, Jason', ' 0.253', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1159', ' Ross, David', ' 0.2', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1160', ' Rowand, Aaron', ' 0.258', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1161', ' Ruan, Wilken', ' 0.273', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1162', ' Rushford, Jim', ' 0.143', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1163', ' Ryan, Mike', ' 0.091', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1164', ' Sadler, Donnie', ' 0.163', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1165', ' Saenz, Olmedo', ' 0.276', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1166', ' Salazar, Oscar', ' 0.19', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1167', ' Salmon, Tim', ' 0.286', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1168', ' Sanchez, Alex', ' 0.289', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1169', ' Sanchez, Freddy', ' 0.188', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1170', ' Sanchez, Rey', ' 0.286', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1171', ' Sandberg, Jared', ' 0.229', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1172', ' Sanders, Reggie', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1173', ' Santiago, Benito', ' 0.278', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1174', ' Santiago, Ramon', ' 0.243', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1175', ' Schneider, Brian', ' 0.275', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1176', ' Scutaro, Marcos', ' 0.222', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1177', ' Sears, Todd', ' 0.333', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1178', ' Segui, David', ' 0.263', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1179', ' Selby, Bill', ' 0.214', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1180', ' Sexson, Richie', ' 0.279', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1181', ' Sheets, Andy', ' 0.248', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1182', ' Sheffield, Gary', ' 0.307', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1183', ' Shinjo, Tsuyoshi', ' 0.238', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1184', ' Shumpert, Terry', ' 0.235', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1185', ' Sierra, Ruben', ' 0.27', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1186', ' Simon, Randall', ' 0.301', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1187', ' Singleton, Chris', ' 0.262', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1188', ' Smith, Bobby', ' 0.175', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1189', ' Smith, Jason', ' 0.2', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1190', ' Snead, Esix', ' 0.308', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1191', ' Snelling, Chris', ' 0.148', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1192', ' Snow, J.T.', ' 0.246', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1193', ' Snyder, Earl', ' 0.2', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1194', ' Soriano, Alfonso', ' 0.3', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1195', ' Sosa, Sammy', ' 0.288', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1196', ' Spencer, Shane', ' 0.247', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1197', ' Spiezio, Scott', ' 0.285', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1198', ' Spivey, Junior', ' 0.301', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1199', ' Stairs, Matt', ' 0.244', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1200', ' Stevens, Lee', ' 0.204', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1201', ' Stewart, Shannon', ' 0.303', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1202', ' Stinnett, Kelly', ' 0.226', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1203', ' Stynes, Chris', ' 0.241', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1204', ' Surhoff, B.J.', ' 0.293', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1205', ' Sutton, Larry', ' 0.105', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1206', ' Suzuki, Ichiro', ' 0.321', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1207', ' Swann, Pedro', ' 0.083', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1208', ' Sweeney, Mark', ' 0.169', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1209', ' Sweeney, Mike', ' 0.34', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1210', ' Taguchi, So', ' 0.4', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1211', ' Tarasco, Tony', ' 0.25', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1212', ' Tatis, Fernando', ' 0.228', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1213', ' Taubensee, Eddie', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1214', ' Taylor, Reggie', ' 0.254', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1215', ' Tejada, Miguel', ' 0.308', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1216', ' Thames, Marcus', ' 0.231', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1217', ' Thomas, Frank', ' 0.252', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1218', ' Thome, Jim', ' 0.304', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1219', ' Thompson, Ryan', ' 0.248', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1220', ' Thurston, Joe', ' 0.462', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1221', ' Toca, Jorge', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1222', ' Torcato, Tony', ' 0.273', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1223', ' Torrealba, Steve', ' 0.059', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1224', ' Torrealba, Yorvit', ' 0.279', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1225', ' Torres, Andres', ' 0.2', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1226', ' Trammell, Bubba', ' 0.243', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1227', ' Truby, Chris', ' 0.215', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1228', ' Tucker, Michael', ' 0.248', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1229', ' Tyner, Jason', ' 0.214', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1230', ' Ugueto, Luis', ' 0.217', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1231', ' Uribe, Juan', ' 0.24', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1232', ' Valdez, Mario', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1233', ' Valent, Eric', ' 0.2', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1234', ' Valentin, Javier', ' 0.5', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1235', ' Valentin, John', ' 0.24', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1236', ' Valentin, Jose', ' 0.249', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1237', ' Vander Wal, John', ' 0.26', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1238', ' Varitek, Jason', ' 0.266', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1239', ' Vaughn, Greg', ' 0.163', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1240', ' Vaughn, Mo', ' 0.259', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1241', ' Vazquez, Ramon', ' 0.274', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1242', ' Velarde, Randy', ' 0.226', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1243', ' Ventura, Robin', ' 0.247', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1244', ' Vidro, Jose', ' 0.315', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1245', ' Vina, Fernando', ' 0.27', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1246', ' Vizcaino, Jose', ' 0.303', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1247', ' Vizquel, Omar', ' 0.275', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1248', ' Walbeck, Matt', ' 0.235', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1249', ' Walker, Larry', ' 0.338', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1250', ' Walker, Todd', ' 0.299', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1251', ' Ward, Daryle', ' 0.276', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1252', ' Wathan, Dusty', ' 0.6', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1253', ' Wells, Vernon', ' 0.275', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1254', ' Werth, Jayson', ' 0.261', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1255', ' Wesson, Barry', ' 0.2', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1256', ' White, Rondell', ' 0.24', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1257', ' Widger, Chris', ' 0.297', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1258', ' Wigginton, Ty', ' 0.302', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1259', ' Wilkerson, Brad', ' 0.266', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1260', ' Williams, Bernie', ' 0.333', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1261', ' Williams, Gerald', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1262', ' Williams, Matt', ' 0.26', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1263', ' Wilson, Craig', ' 0.264', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1264', ' Wilson, Dan', ' 0.295', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1265', ' Wilson, Enrique', ' 0.181', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1266', ' Wilson, Jack', ' 0.252', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1267', ' Wilson, Preston', ' 0.243', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1268', ' Wilson, Tom', ' 0.257', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1269', ' Wilson, Vance', ' 0.245', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1270', ' Winn, Randy', ' 0.298', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1271', ' Wise, DeWayne', ' 0.179', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1272', ' Womack, Tony', ' 0.271', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1273', ' Woodward, Chris', ' 0.276', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1274', ' Wooten, Shawn', ' 0.292', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1275', ' Wright, Ron', ' 0', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1276', ' Young, Dmitri', ' 0.284', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1277', ' Young, Eric', ' 0.28', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1278', ' Young, Kevin', ' 0.246', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1279', ' Young, Michael', ' 0.262', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1280', ' Zaun, Greg', ' 0.222', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1281', ' Zeile, Todd', ' 0.273', '2005-01-01');
+INSERT INTO `testtbl` VALUES ('1282', ' Zinter, Alan', ' 0.136', '2005-01-01');
diff --git a/dojox/grid/compat/tests/support/yahoo_search.js b/dojox/grid/compat/tests/support/yahoo_search.js
new file mode 100644
index 0000000..a013b5d
--- /dev/null
+++ b/dojox/grid/compat/tests/support/yahoo_search.js
@@ -0,0 +1,131 @@
+// model that works with Yahoo Search API
+dojo.declare("dojox.grid.data.yahooSearch", dojox.grid.data.dynamic, 
+	function(inFields, inData) {
+		this.rowsPerPage = 20;
+		this.fieldNames = [];
+		for (var i=0, f; (f=inFields[i]); i++)
+			this.fieldNames.push(f.name);
+	}, {
+	clearData: function() {
+		turbo.widgets.TurboGrid.data.dynamic.prototype.clearData.apply(this, arguments);
+	},
+	// server send / receive
+	encodeParam: function(inName, inValue) {
+		return turbo.printf('&%s=%s', inName, inValue);
+	},
+	getParams: function(inParams) {
+		var url = this.url;
+		url += '?appid=turboajax';
+		inParams = inParams || {};
+		inParams.output = 'json';
+		inParams.results = this.rowsPerPage;
+		inParams.query = turbo.$('searchInput').value.replace(/ /g, '+');
+		for (var i in inParams)
+			if (inParams[i] != undefined)
+				url += this.encodeParam(i, inParams[i]);
+		return url;
+	},
+	send: function(inAsync, inParams, inOnReceive, inOnError) {
+		var p = this.getParams(inParams);
+		dojo.io.bind({
+			url: "support/proxy.php",
+			method: "post",
+			content: {url: p },
+			contentType: "application/x-www-form-urlencoded; charset=utf-8",
+			mimetype: 'text/json',
+			sync: !inAsync,
+			load: turbo.bindArgs(this, "receive", inOnReceive, inOnError),
+			error: turbo.bindArgs(this, "error", inOnError) 
+		});
+		this.onSend(inParams);
+	},
+	receive: function(inOnReceive, inOnError, inEvt, inData) {
+		try {
+			inData = inData.ResultSet;
+			inOnReceive(inData);
+			this.onReceive(inData);					
+		} catch(e) {
+			if (inOnError)
+				inOnError(inData);
+		}
+	},
+	error: function(inOnError, inTyp, inErr) {
+		var m = 'io error: ' + inErr.message;
+		alert(m);
+		if (inOnError)
+			inOnError(m);
+	},
+	fetchRowCount: function(inCallback) {
+		this.send(true, inCallback );
+	},
+	// request data 
+	requestRows: function(inRowIndex, inCount)	{
+		inRowIndex = (inRowIndex == undefined ? 0 : inRowIndex);
+		var params = { 
+			start: inRowIndex + 1
+		}
+		this.send(true, params, turbo.bindArgs(this, this.processRows));
+	},
+	// server callbacks
+	processRows: function(inData) {
+		for (var i=0, l=inData.totalResultsReturned, s=inData.firstResultPosition; i<l; i++) {
+			this.setRow(inData.Result[i], s - 1 + i);
+		}
+		// yahoo says 1000 is max results to return
+		var c = Math.min(1000, inData.totalResultsAvailable);
+		if (this.count != c) {
+			this.setRowCount(c);
+			this.allChange();
+			this.onInitializeData(inData);
+		}
+	},
+	getDatum: function(inRowIndex, inColIndex) {
+		var row = this.getRow(inRowIndex);
+		var field = this.fields.get(inColIndex);
+		return (inColIndex == undefined ? row : (row ? row[field.name] : field.na));
+	},
+	// events
+	onInitializeData: turbo.nop,
+	onSend: turbo.nop,
+	onReceive: turbo.nop
+});
+
+// report
+modelChange = function() {
+	var n = turbo.$('rowCount');
+	if (n)
+		n.innerHTML = turbo.printf('about %s row(s)', model.count);
+}
+
+
+// some data formatters
+formatLink = function(inData, inRowIndex) {
+	if (!inData[0] || !inData[1])
+		return ' ';
+	return turbo.supplant('<a target="_blank" href="{href}">{text}</a>', {href: inData[0], text: inData[1] });
+};
+
+formatImage = function(inData, inRowIndex) {
+	if (!inData[0] || !inData[1])
+		return ' ';
+	var o = {
+		href: inData[0], 
+		src: inData[1].Url,
+		width: inData[1].Width,
+		height: inData[1].Height
+	}	
+	return turbo.supplant('<a href="{href}" target="_blank"><img border=0 src="{src}" width="{width}" height="{height}"></a>', o);
+};
+
+formatDate = function(inDatum, inRowIndex) {
+	if (inDatum == '')
+		return ' ';
+	var d = new Date(inDatum * 1000);
+	return turbo.printf('%s/%s/%s', d.getMonth(), d.getDate(), d.getFullYear());
+};
+
+formatDimensions = function(inData, inRowIndex) {
+	if (!inData[0] || !inData[1])
+		return ' ';
+	return inData[0] + ' x ' + inData[1];
+}
diff --git a/dojox/grid/compat/tests/test_change_structure.html b/dojox/grid/compat/tests/test_change_structure.html
new file mode 100644
index 0000000..ddb45fd
--- /dev/null
+++ b/dojox/grid/compat/tests/test_change_structure.html
@@ -0,0 +1,124 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>dojox.Grid Change Structure Example</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../_grid/Grid.css";
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+		}
+		.heading {
+			font-weight: bold;
+			padding-bottom: 0.25em;
+		}
+				
+		#grid { 
+			border: 1px solid #333;
+			width: 48em;
+			height: 30em;
+		}
+		
+		#grid .dojoxGrid-cell {
+			text-align: center;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");
+	</script>
+	<script type="text/javascript">
+
+		// get can return data for a cell of the grid
+		function get(inRowIndex) {
+			return [this.index, inRowIndex].join(', ');
+		}
+
+		// grid structure
+		// a grid view is a group of columns
+		
+		// a special view providing selection feedback
+		var rowBar = {type: 'dojox.GridRowView', width: '20px' };
+		
+		// a view without scrollbars
+		var view0 = {
+			noscroll: true,
+			cells: [[
+				{name: 'Alpha', value: '<input name="" type="checkbox" value="0">'},
+				{name: 'Beta', get: get, width: 4.5}
+		]]};
+		
+		var view1 = {
+			cells: [[
+				{name: 'Apple', value: '<button>Apple</button>'},
+				{name: 'Banana', get: get},
+				{name: 'Beans', value: 'Happy to be grid!'},
+				{name: 'Kiwi', get: get},
+				{name: 'Orange', value: '<img src="images/flatScreen.gif" height="48" width="48">'},
+				{name: 'Pear', get: get},
+				{name: 'Tomato', width: 20, value: '<input name="" type="file">'}
+		]]};
+		
+		var view2 = {
+			noscroll: true,
+			cells: [
+				[
+					{name: 'Alpha', value: '<input name="" type="checkbox" value="0">', rowSpan: 2},
+					{name: 'Beta', get: get, width: 4.5}
+				], [
+					{name: 'Gamma', get: get}
+				],
+				[
+					{name: 'Epsilon', value: '<button>Epsilon</button>', colSpan: 2}
+				]
+			]	
+		}
+		
+		var view3 = {
+			cells: [
+				[	
+					{name: 'Apple', value: '<button>Apple</button>', rowSpan: 3},
+					{name: 'Banana', get: get, width: 20},
+					{name: 'Kiwi', get: get, width: 20},
+					{name: 'Pear', get: get, width: 20}
+				],
+				[
+					{name: 'Beans', value: 'Happy to be grid!'},
+					{name: 'Orange', value: '<img src="images/flatScreen.gif" height="48" width="48">'},
+					{name: 'Tomato', value: '<input name="" type="file">'}
+				], [
+					{name: 'Zuchini', value: '<span style="letter-spacing: 10em;">wide</span>', colSpan: 3}
+				]
+			]};
+		
+		
+		// a grid structure is an array of views.
+		// By default the middle view will be 'elastic', sized to fit the remaining space left by other views
+		// grid.elasticView can also be manually set
+		var structure = [ rowBar, view0, view1 ];
+		var structure2 = [ rowBar, view2, view3 ];
+		
+		
+		var l2 = false;
+		toggleStructure = function() {
+			l2 = !l2;
+			grid.scrollToRow(0);
+			grid.setStructure(l2 ? structure2 : structure);
+		}
+		
+		dojo.addOnLoad(function() {
+			window["grid"] = dijit.byId("grid");
+		});
+</script>
+</head>
+<body>
+<div class="heading">dojox.VirtualGrid Change Structure Example</div>
+<p>
+	<button onclick="toggleStructure()">Change Structure</button>
+</p>	
+<div id="grid" dojoType="dojox.VirtualGrid" structure="structure" rowCount="100000" elasticView="2"></div>
+
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_custom_sort.html b/dojox/grid/compat/tests/test_custom_sort.html
new file mode 100644
index 0000000..f09c936
--- /dev/null
+++ b/dojox/grid/compat/tests/test_custom_sort.html
@@ -0,0 +1,86 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>Custom Sort Test - dojox.Grid</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../_grid/Grid.css";
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+		}
+		.heading {
+			font-weight: bold;
+			padding-bottom: 0.25em;
+		}
+				
+		#grid {
+			border: 1px solid #333;
+			width: 35em;
+			height: 30em;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+	<!--<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");
+	</script>-->
+	<!-- Debugging -->
+	<script type="text/javascript" src="../_grid/lib.js"></script>
+	<script type="text/javascript" src="../_grid/drag.js"></script>
+	<script type="text/javascript" src="../_grid/scroller.js"></script>
+	<script type="text/javascript" src="../_grid/builder.js"></script>
+	<script type="text/javascript" src="../_grid/cell.js"></script>
+	<script type="text/javascript" src="../_grid/layout.js"></script>
+	<script type="text/javascript" src="../_grid/rows.js"></script>
+	<script type="text/javascript" src="../_grid/focus.js"></script>
+	<script type="text/javascript" src="../_grid/selection.js"></script>
+	<script type="text/javascript" src="../_grid/edit.js"></script>
+	<script type="text/javascript" src="../_grid/view.js"></script>
+	<script type="text/javascript" src="../_grid/views.js"></script>
+	<script type="text/javascript" src="../_grid/rowbar.js"></script>
+	<script type="text/javascript" src="../_grid/publicEvents.js"></script>
+	<script type="text/javascript" src="../VirtualGrid.js"></script>
+	<script type="text/javascript" src="../_data/fields.js"></script>
+	<script type="text/javascript" src="../_data/model.js"></script>
+	<script type="text/javascript" src="../_data/editors.js"></script>
+	<script type="text/javascript" src="../Grid.js"></script>
+	<script type="text/javascript" src="support/test_data.js"></script>
+	<script type="text/javascript">
+		// here is a custom compare function that can drive the sorting engine
+		// of course, this is only valid for client-side data sets
+		compare2ndLetter = function(inA, inB) {
+			// sort on the second letter
+			// return <0, 0, >0
+			return inA.charCodeAt(1) - inB.charCodeAt(1);
+		}
+		
+		// custom compare functions for sorting belong to the data model
+		// data model keeps this kind of metadata in a object called 'fields'
+		
+		// you can install the custom compare function directly into fields
+		// model.fields.get(3).compare = compare2ndLetter;
+		
+		// or you could setup fields when instantiating the model
+		model = new dojox.grid.data.Table([{}, {}, {}, {compare: compare2ndLetter}], data);
+		
+		// a grid view is a group of columns
+		var view1 = {
+			cells: [[
+				{name: 'Column 0'}, {name: 'Column 1'}, {name: 'Column 2'}, {name: 'Column 3', width: "auto"}, {name: 'Column 4'}
+			],[
+				{name: 'Column 5'}, {name: 'Column 6'}, {name: 'Column 7'}, {name: 'Column 8', field: 3, colSpan: 2}
+			]]
+		};
+		// a grid layout is an array of views.
+		var layout = [ view1 ];
+</script>
+</head>
+<body>
+<div class="heading">dojox.Grid Custom Sort Test</div>
+<br />
+<b>Column 3</b>'s data field has a custom sorter that sorts by the 2nd letter in the string.
+<br /><br />
+<div id="grid" dojoType="dojox.Grid" model="model" structure="layout"></div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_dojo_data_edit.html b/dojox/grid/compat/tests/test_dojo_data_edit.html
new file mode 100644
index 0000000..176d3c2
--- /dev/null
+++ b/dojox/grid/compat/tests/test_dojo_data_edit.html
@@ -0,0 +1,124 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>Test dojox.Grid Editing with DojoData model</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+<style>
+	@import "../../_grid/Grid.css";
+	body {
+		font-family: Tahoma, Arial, Helvetica, sans-serif;
+		font-size: 11px;
+	}
+	.dojoxGrid-row-editing td {
+		background-color: #F4FFF4;
+	}
+	.dojoxGrid input, .dojoxGrid select, .dojoxGrid textarea {
+		margin: 0;
+		padding: 0;
+		border-style: none;
+		width: 100%;
+		font-size: 100%;
+		font-family: inherit;
+	}
+	.dojoxGrid input {
+	}
+	.dojoxGrid select {
+	}
+	.dojoxGrid textarea {
+	}
+	#controls {
+		padding: 6px 0;
+	}
+	#grid {
+		width: 850px;
+		height: 350px;
+		border: 1px solid silver;
+	}
+</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="isDebug: true, debugAtAllCosts: false, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.data.ItemFileWriteStore");
+		dojo.require("dojo.parser");
+	</script>
+
+	<script type="text/javascript">
+		function getRow(inRowIndex){
+			return ' ' + inRowIndex;
+		}
+		
+		var layoutCountries = [
+			// view 0
+			{ type: 'dojox.GridRowView', width: '20px' },
+			// view 1
+			{ cells: [[{ name: "Row", get: getRow, width: 5}]], noscroll: true},
+			// view 2
+			{ cells: [[
+				{ field: 0, width: 'auto' },
+				{ width: 8 }
+			]]}
+		];
+		
+		removeItem = function() {
+			// Removes the first item in the model from the store
+			// Grid should reflect removal of the first item and items should be re-indexed
+			jsonStore.deleteItem(dataModel.data[0].__dojo_data_item);
+		}
+		
+		var i = 0;
+		addItem = function() {
+			grid.addRow({name: "country"+(i++), type: "country"});
+		}
+		addItemToStore = function() {
+			// Adds a new item to the store
+			// Grid should reflect the new item.
+			jsonStore.newItem({name: "country"+(i++), type: "country"});
+		}
+	</script>
+</head>
+<body class="tundra">
+<h2>
+	dojox.Grid Basic Editing test
+</h2>
+<div id="controls">
+	<button onclick="grid.refresh()">Refresh</button>   
+	<button onclick="dataModel.clearData(true)">Clear Data (Model)</button>   
+	<button onclick="dataModel.refresh()">Refresh (Model)</button>   
+	<button onclick="grid.edit.focusEditor()">Focus Editor</button>
+	<button onclick="grid.focus.next()">Next Focus</button>   
+	<button onclick="addItem()">Add</button>
+	<button onclick="grid.removeSelectedRows()">Remove</button>   
+	<button onclick="jsonStore.revert()">Revert (Store)</button>
+	<button onclick="removeItem()">Remove (Store)</button>
+	<button onclick="addItemToStore()">Add (Store)</button>   
+	<button onclick="grid.edit.apply()">Apply</button>
+	<button onclick="grid.edit.cancel()">Cancel</button>   
+	<button onclick="grid.singleClickEdit = !grid.singleClickEdit">Toggle singleClickEdit</button> 
+</div>
+<span dojoType="dojo.data.ItemFileWriteStore" 
+	 jsId="jsonStore" url="../../../../dijit/tests/_data/countries.json">
+</span>
+<span dojoType="dojox.grid.data.DojoData" 
+	  jsId="dataModel" 
+	  rowsPerPage="20"
+	  store="jsonStore" 
+	  query="{ name : '*' }">
+</span>
+<div id="grid" jsId="grid" dojoType="dojox.Grid" elasticView="2" 
+	 model="dataModel" structure="layoutCountries">
+</div>
+<span dojoType="dojox.grid.data.DojoData" 
+	  jsId="dataModel2" 
+	  rowsPerPage="20"
+	  store="jsonStore" 
+	  query="{ name : '*' }">
+</span>
+<div id="grid2" dojoType="dojox.Grid" elasticView="2" 
+	 model="dataModel2" structure="layoutCountries">
+</div>
+</body>
+</html>
+
+
+
diff --git a/dojox/grid/compat/tests/test_dojo_data_empty.html b/dojox/grid/compat/tests/test_dojo_data_empty.html
new file mode 100644
index 0000000..4f9c1e2
--- /dev/null
+++ b/dojox/grid/compat/tests/test_dojo_data_empty.html
@@ -0,0 +1,63 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
+<html> 
+<head> 
+<title>dojox.Grid with Dojo.Data via binding</title> 
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta> 
+	<style type="text/css"> 
+		@import "../../../../dojo/resources/dojo.css"; 
+		@import "../../_grid/Grid.css"; 
+		#grid { 
+			width: 65em; 
+			height: 25em; 
+		}
+	</style> 
+	<script type="text/javascript" src="../../../../dojo/dojo.js"  
+					djConfig="isDebug: true, debugAtAllCosts: false, parseOnLoad: true"></script> 
+	<script type="text/javascript"> 
+					dojo.require("dojox.grid.Grid"); 
+					dojo.require("dojo.data.ItemFileWriteStore"); 
+					dojo.require("dojo.parser"); 
+					dojo.require("dijit.form.Button"); 
+	</script> 
+	<script type="text/javascript"> 
+		function getRow(inRowIndex){ 
+						return ' ' + inRowIndex; 
+		}
+
+		var layoutCountries = [ 
+						// view 0 
+						{ type: 'dojox.GridRowView', width: '20px' }, 
+						// view 1 
+						{ cells: [[{ name: "Row", get: getRow, width: 5}]], noscroll: true}, 
+						// view 2 
+						{ cells: [[ 
+										{ name: "field 0", field: 0, width: 8 }, 
+										{ name: "field 1", width: 8 } 
+						]]} 
+		];
+		
+		var emptyData = { identifier: 'name', label: 'name', items: []}; 
+		var jsonStore = new dojo.data.ItemFileWriteStore({data: emptyData}); 
+		var numItems = 0; 
+	</script> 
+</head> 
+<body class="tundra"> 
+				<h5>dojox.Grid using initially-empty Dojo.Data write stores and then adding an item.  Item should show up correctly (no "?"s) when added.</h5> 
+		<br> 
+				<span dojoType="dojox.grid.data.DojoData"  
+								jsId="dataModel"  
+								rowsPerPage="20" 
+								store="jsonStore" count="0"> 
+				</span> 
+				<div id="grid" dojoType="dojox.Grid" elasticView="2"  
+								model="dataModel" structure="layoutCountries"> 
+				</div> 
+				<button dojoType="dijit.form.Button"> 
+								<script type="dojo/method" event="onClick"> 
+												numItems++; 
+												jsonStore.newItem({name: numItems + "-person Land", type: "city", population: numItems}); 
+								</script> 
+								Add Item 
+				</button> 
+</body> 
+</html> 
\ No newline at end of file
diff --git a/dojox/grid/compat/tests/test_dojo_data_model.html b/dojox/grid/compat/tests/test_dojo_data_model.html
new file mode 100644
index 0000000..94447b1
--- /dev/null
+++ b/dojox/grid/compat/tests/test_dojo_data_model.html
@@ -0,0 +1,84 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>dojox.Grid with Dojo.Data via binding</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../_grid/tundraGrid.css";
+		
+		#grid, #grid2 {
+			width: 65em;
+			height: 25em;
+			padding: 1px;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="isDebug: true, debugAtAllCosts: false, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.data.ItemFileReadStore");
+		dojo.require("dojox.data.CsvStore");
+		dojo.require("dojo.parser");
+	</script>
+	<script type="text/javascript">
+		function getRow(inRowIndex){
+			return ' ' + inRowIndex;
+		}
+		
+		var layoutMovies = [
+			// view 0
+			{ type: 'dojox.GridRowView', width: '20px' },
+			// view 1
+			{ cells: [[{ name: "Row", get: getRow, width: 5}]], noscroll: true},
+			// view 2
+			{ cells: [[
+				{ field: "Title", width: 'auto' },
+				{ field: "Year", width: 5 },
+				{ field: "Producer", width: 20 }
+			]]}
+		];
+		
+		var layoutCountries = [
+			// view 0
+			{ type: 'dojox.GridRowView', width: '20px' },
+			// view 1
+			{ cells: [[{ name: "Row", get: getRow, width: 5}]], noscroll: true},
+			// view 2
+			{ cells: [[
+				{ field: 0, width: 'auto' },
+				{ width: 8 }
+			]]}
+		];
+	</script>
+</head>
+<body class="tundra">
+	<h5>dojox.Grid using Dojo.Data stores via simple binding</h5>
+	<span dojoType="dojox.data.CsvStore" 
+		jsId="csvStore" url="support/movies.csv">
+	</span>
+	<span dojoType="dojox.grid.data.DojoData" 
+		jsId="dataModel"
+		store="csvStore"
+		rowsPerPage="5"
+		query="{ Title: '*' }"
+		clientSort="true">
+	</span>
+	<div id="grid" dojoType="dojox.Grid" elasticView="2" 
+		model="dataModel" structure="layoutMovies">
+	</div>
+
+	<span dojoType="dojo.data.ItemFileReadStore" 
+		jsId="jsonStore" url="../../../../dijit/tests/_data/countries.json">
+	</span>
+	<span dojoType="dojox.grid.data.DojoData" 
+		jsId="dataModel2" 
+		rowsPerPage="20"
+		store="jsonStore" 
+		query="{ name : '*' }">
+	</span>
+	<div id="grid2" dojoType="dojox.Grid" elasticView="2" 
+		model="dataModel2" structure="layoutCountries">
+	</div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_dojo_data_model_EmptyResultSet.html b/dojox/grid/compat/tests/test_dojo_data_model_EmptyResultSet.html
new file mode 100644
index 0000000..7739acf
--- /dev/null
+++ b/dojox/grid/compat/tests/test_dojo_data_model_EmptyResultSet.html
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>dojox.Grid with Dojo.Data via binding</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../_grid/tundraGrid.css";
+		
+		#grid {
+			width: 65em;
+			height: 25em;
+			padding: 1px;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="isDebug: true, debugAtAllCosts: false, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.data.ItemFileReadStore");
+		dojo.require("dojo.parser");
+	</script>
+	<script type="text/javascript">
+		function getRow(inRowIndex){
+			return ' ' + inRowIndex;
+		}
+    
+		var layoutCountries = [
+			// view 0
+			{ type: 'dojox.GridRowView', width: '20px' },
+			// view 1
+			{ cells: [[{ name: "Row", get: getRow, width: 5}]], noscroll: true},
+			// view 2
+			{ cells: [[
+				{ name: "field 0", field: 0, width: 8 },
+				{ name: "field 1", width: 8 }
+			]]}
+		];
+	</script>
+</head>
+<body class="tundra">
+	<h5>dojox.Grid using Dojo.Data stores where a query returns no results.  No errors should be reported in Firebug and the grid should be empty</h5>
+    <br>
+	<span dojoType="dojo.data.ItemFileReadStore" 
+		jsId="jsonStore" url="../../../../dijit/tests/_data/countries.json">
+	</span>
+	<span dojoType="dojox.grid.data.DojoData" 
+		jsId="dataModel" 
+		rowsPerPage="20"
+		store="jsonStore" 
+		query="{ noSuchAttr : '*' }">
+	</span>
+	<div id="grid" dojoType="dojox.Grid" elasticView="2" 
+		model="dataModel" structure="layoutCountries">
+	</div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_dojo_data_model_multiStores.html b/dojox/grid/compat/tests/test_dojo_data_model_multiStores.html
new file mode 100644
index 0000000..2c69233
--- /dev/null
+++ b/dojox/grid/compat/tests/test_dojo_data_model_multiStores.html
@@ -0,0 +1,291 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>dojox.Grid with Dojo.Data via binding.  Multiple Store implementations.</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../../../dijit/themes/tundra/tundra.css";
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+		@import "../../_grid/tundraGrid.css";
+		
+		#grid, #grid2, #grid3, #grid4, #grid5, #grid6{
+			width: 65em;
+			height: 25em;
+			padding: 1px;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="isDebug: true, debugAtAllCosts: false, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.data.ItemFileReadStore");
+		dojo.require("dojox.data.CsvStore");
+		dojo.require("dojox.data.XmlStore");
+		dojo.require("dojox.data.FlickrStore");
+		dojo.require("dojox.data.OpmlStore");
+		dojo.require("dojox.data.HtmlStore");
+		dojo.require("dojo.parser");
+	</script>
+
+	<script type="text/javascript">
+		function getRow(inRowIndex){
+			return ' ' + inRowIndex;
+		}
+		
+		var formatHref = function(attribute, rowIndex) {
+			model = dataModel4;
+			if(!model)
+				return "?";
+			var value = model.getRow(rowIndex);
+			if(value && value[attribute])
+				return "<a href=\"" + value[attribute] + "\" target=\"_blank\">Image Link</a>";
+			return "";
+		}
+
+		var layoutMovies = [
+			// view 0
+			{ type: 'dojox.GridRowView', width: '20px' },
+			// view 1
+			{ cells: [[{ name: "Row", get: getRow, width: 5}]], noscroll: true},
+			// view 2
+			{ cells: [[
+				{ field: "Title", width: 'auto' },
+				{ field: "Year", width: 5 },
+				{ field: "Producer", width: 20 }
+			]]}
+		];
+		
+		var layoutCountries = [
+			// view 0
+			{ type: 'dojox.GridRowView', width: '20px' },
+			// view 1
+			{ cells: [[{ name: "Row", get: getRow, width: 5}]], noscroll: true},
+			// view 2
+			{ cells: [[
+				{ field: 0, width: 'auto' },
+				{ width: 8 }
+			]]}
+		];
+
+		var layoutBooks = [
+			// view 0
+			{ type: 'dojox.GridRowView', width: '20px' },
+			// view 1
+			{ cells: [[{ name: "Row", get: getRow, width: 5}]], noscroll: true},
+			// view 2
+			{ cells: [[
+				{ field: "title", width: 'auto' },
+				{ field: "isbn", width: '8' }
+			]]}
+		];
+
+		//Lay out the Flickr data so one column is a URL.  This makes use of the
+		//get function of a cell.
+		var layoutFlickrData = [
+			// view 0
+			{ type: 'dojox.GridRowView', width: '20px' },
+			// view 1
+			{ cells: [[{ name: "Row", get: getRow, width: 5}]], noscroll: true},
+			// view 2
+			{ cells: [[
+				{ name: "Title", field: "title", width: 'auto' },
+				{ name: "Image URL", field: "imageUrl", width: '15', get: dojo.partial(formatHref, "imageUrl")}
+			]]}
+		];
+
+		var layoutOpmlData = [
+			// view 0
+			{ type: 'dojox.GridRowView', width: '20px' },
+			// view 1
+			{ cells: [[{ name: "Row", get: getRow, width: 5}]], noscroll: true},
+			// view 2
+			{ cells: [[
+				{ name: 'Name', field: 'text', width: 'auto'},
+				{ name: 'Type', field: 'type', width: '8' }
+			]]}
+		];
+
+		var layoutHtmlTable = [
+			// view 0
+			{ type: 'dojox.GridRowView', width: '20px' },
+			// view 1
+			{ cells: [[{ name: "Row", get: getRow, width: 5}]], noscroll: true},
+			// view 2
+			{ cells: [[
+				{ name: 'Column 1', field: 'Column 1', width: 'auto'},
+				{ name: 'Column 2', field: 'Column 2', width: 'auto'},
+				{ name: 'Column 3', field: 'Column 3', width: 'auto'},
+				{ name: 'Column 4', field: 'Column 4', width: 'auto'}
+			]]}
+		];
+	</script>
+</head>
+<body class="tundra">
+	<h1>dojox.Grid using Dojo.Data stores via simple binding with multiple store implementations.</h1>
+	<p>
+		This page demonstrates the Grid can display data accessed by dojo.data implementing Datastores.  
+		Each of the datastores used stores data in a different format, and as this test and demonstration
+		page shows, the logic for rendering the data is virtually identical.  You define your source store,
+		you define the model for accessing the data, which is ij this case the dojox.grid.data.DojoData model
+		and then you define the layout, which maps the data attribute names to columns in the grid.  You can 
+		even perform cusomization of what is displayed, as demonstrated in the dojox.data.FlickrStore layout.  
+		The image url is displayed as a clickable link that opens a new page.
+	</p>
+	<p>
+		The choice of stores used were ones that did not require back end services to function for sake of 
+		simplicity.  There is no reason that dojox.data.QueryReadStore could not be used with grid as well,
+		it just requires a back end service to send it the query results.
+	</p>
+	<p><b>Stores used:</b></p>
+	<ul>
+		<li>dojo.data.ItemFileReadStore</li>
+		<li>dojox.data.CvsStore</li>
+		<li>dojox.data.XmlStore</li>
+		<li>dojox.data.FlickrStore</li>
+		<li>dojox.data.OpmlStore</li>
+		<li>dojox.data.HtmlTableStore</li>
+	</ul>
+
+	<h2>dojo.data.ItemFileReadStore:</h2>
+	<i>Displays a list of countries through ItemFileReadStore format.</i>
+	<span dojoType="dojo.data.ItemFileReadStore" 
+		jsId="jsonStore" url="../../../../dijit/tests/_data/countries.json">
+	</span>
+	<span dojoType="dojox.grid.data.DojoData" 
+		jsId="dataModel" 
+		rowsPerPage="20"
+		store="jsonStore" 
+		query="{ name : '*' }">
+	</span>
+	<div id="grid" dojoType="dojox.Grid" elasticView="2" 
+		model="dataModel" structure="layoutCountries">
+	</div>
+
+
+	<h2>dojox.data.CsvStore:</h2>
+	<i>Displays a list of movies that were stored in CSV format.</i>
+	<span dojoType="dojox.data.CsvStore" 
+		jsId="csvStore" url="support/movies.csv">
+	</span>
+	<span dojoType="dojox.grid.data.DojoData" 
+		jsId="dataModel2"
+		store="csvStore"
+		rowsPerPage="5"
+		query="{ Title: '*' }"
+		clientSort="true">
+	</span>
+	<div id="grid2" dojoType="dojox.Grid" elasticView="2" 
+		model="dataModel2" structure="layoutMovies">
+
+	</div>
+
+	<h2>dojox.data.XmlStore:</h2>
+	<i>Displays a list of books that were stored in XML format.</i>
+	<span dojoType="dojox.data.XmlStore" 
+		jsId="xmlStore" url="support/books.xml">
+	</span>
+	<span dojoType="dojox.grid.data.DojoData" 
+		jsId="dataModel3" 
+		rowsPerPage="5"
+		store="xmlStore" 
+		query="{ title : '*' }">
+	</span>
+	<div id="grid3" dojoType="dojox.Grid" elasticView="2" 
+		model="dataModel3" structure="layoutBooks">
+	</div>
+
+
+	<h2>dojox.data.FlickrStore:</h2>
+	<i>Displays Flickr imformation on 3DNY (Dojo Developer Days, New York) from the flickr public photo feed, accessed via the FlickrStore dojo.data implementation.</i>
+	<span dojoType="dojox.data.FlickrStore" 
+		jsId="flickrStore">
+	</span>
+	<span dojoType="dojox.grid.data.DojoData" 
+		jsId="dataModel4" 
+		rowsPerPage="5"
+		store="flickrStore" 
+		query="{ tags : '3dny' }">
+	</span>
+	<div id="grid4" dojoType="dojox.Grid" elasticView="2" 
+		model="dataModel4" structure="layoutFlickrData">
+	</div>
+
+
+	<h2>dojox.data.OpmlStore:</h2>
+	<i>Scans an Opml based document for all items of type 'country'</i> 
+	<span dojoType="dojox.data.OpmlStore" 
+		jsId="opmlStore" url="support/geography.xml">
+	</span>
+	<span dojoType="dojox.grid.data.DojoData" 
+		jsId="dataModel5" 
+		rowsPerPage="5"
+		store="opmlStore" 
+		query="{ type : 'country' }"
+		queryOptions="{deep: true}"
+		sortFields="[ { attribute : 'text' } ]">
+	</span>
+	<div id="grid5" dojoType="dojox.Grid" elasticView="2" 
+		model="dataModel5" structure="layoutOpmlData">
+	</div>
+
+
+	<h2>dojox.data.HtmlStore:</h2>
+	<i>Loads the grid from an HTML Table.</i> 
+	<span dojoType="dojox.data.HtmlStore" 
+		jsId="htmlStore" dataId="tableExample">
+	</span>
+	<span dojoType="dojox.grid.data.DojoData" 
+		jsId="dataModel6" 
+		rowsPerPage="5"
+		store="htmlStore" 
+		query="{}">
+	</span>
+	<div id="grid6" dojoType="dojox.Grid" elasticView="2" 
+		model="dataModel6" structure="layoutHtmlTable">
+	</div>
+
+	<!-- 
+		Inline data table to be displayed bu the grid! 
+		This is accessed via the dojox.data.HtmlTableStore
+	-->
+	<table id="tableExample" style="display: none;">
+		<thead>
+			<tr>
+				<th>Column 1</th>
+				<th>Column 2</th>
+				<th>Column 3</th>
+				<th>Column 4</th>
+			</tr>
+		</thead>
+		<tbody>
+			<tr>
+				<td>This</td>
+				<td>is</td>
+				<td></td>
+				<td>empty in column 3</td>
+			</tr>
+			<tr>
+				<td>This</td>
+				<td>is</td>
+				<td>a</td>
+				<td>value</td>
+			</tr>
+			<tr>
+				<td>Who?</td>
+				<td>What?</td>
+				<td>When?</td>
+				<td>Where?</td>
+			</tr>
+			<tr>
+				<td>She</td>
+				<td>sells</td>
+				<td>sea</td>
+				<td>shells</td>
+			</tr>
+		</tbody>
+	</table>
+</body>
+</html>
+
+
diff --git a/dojox/grid/compat/tests/test_dojo_data_model_processError.html b/dojox/grid/compat/tests/test_dojo_data_model_processError.html
new file mode 100644
index 0000000..68f3710
--- /dev/null
+++ b/dojox/grid/compat/tests/test_dojo_data_model_processError.html
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>dojox.Grid with Dojo.Data model with trapping of data store errors.</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../../../dijit/themes/tundra/tundra.css";
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+		@import "../../_grid/tundraGrid.css";
+		
+		#grid{
+			width: 65em;
+			height: 25em;
+			padding: 1px;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="isDebug: true, debugAtAllCosts: false, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojox.data.CsvStore");
+		dojo.require("dojo.parser");
+	</script>
+
+	<script type="text/javascript">
+		var layoutMovies = [
+			{ cells: [[
+				{ name: "Title", field: "Title", width: 'auto' },
+				{ name: "Year", field: "Year", width: 5 },
+				{ name: "Producer", field: "Producer", width: 20 }
+			]]}
+		];
+		
+	</script>
+</head>
+<body class="tundra">
+	<h1>dojox.Grid using Dojo.Data stores via simple binding</h1>
+
+	<h2>dojox.data.CsvStore:</h2>.
+	<i>This grid does not load data.  The data store references a non-existent URL on purpose.  It should trigger a failure that we catch and display in an alert</i>
+	<span dojoType="dojox.data.CsvStore" 
+		jsId="csvStore" url="support/NoSuchMovieFile.csv">
+	</span>
+	<span dojoType="dojox.grid.data.DojoData" 
+		jsId="dataModel"
+		store="csvStore"
+		rowsPerPage="5"
+		query="{ Title: '*' }"
+		clientSort="true">
+		<!-- 
+			This uses the dojo/connect API to link to the processError handler of the model. 
+			It allows a declarative way to hook to the handler on the model.
+		-->
+		<script type="dojo/connect" event="processError" args="error, request">
+			alert("Error was encountered when store was queried: " + dojo.toJson(error, true));
+		</script>
+	</span>
+	<div id="grid" dojoType="dojox.Grid" elasticView="2" 
+		model="dataModel" structure="layoutMovies">
+	</div>
+</body>
+</html>
+
+
diff --git a/dojox/grid/compat/tests/test_dojo_data_notification.html b/dojox/grid/compat/tests/test_dojo_data_notification.html
new file mode 100644
index 0000000..5ed8c29
--- /dev/null
+++ b/dojox/grid/compat/tests/test_dojo_data_notification.html
@@ -0,0 +1,114 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>dojox.Grid with Dojo.Data via binding</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../_grid/tundraGrid.css";
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../../../dijit/themes/tundra/tundra.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+		
+		#grid, #grid2, #grid3 {
+			width: 65em;
+			height: 25em;
+			padding: 1px;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="isDebug: true, debugAtAllCosts: false, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojox.data.CsvStore");
+		dojo.require("dojo.data.ItemFileWriteStore");
+		dojo.require("dojo.parser");
+	</script>
+	<script type="text/javascript">
+		function getRow(inRowIndex){
+			return ' ' + inRowIndex;
+		}
+
+		var iEditor = dojox.grid.editors.Input;
+		var layoutMovies = [
+			// view 0
+			{ type: 'dojox.GridRowView', width: '20px' },
+			// view 1
+			{ cells: [[{ name: "Row", get: getRow, width: 5}]], noscroll: true},
+			// view 2
+			{ cells: [[
+				{ field: "Title", editor: iEditor, width: 'auto' },
+				{ field: "Year",  editor: iEditor, width: 5 },
+				{ field: "Producer", editor: iEditor, width: 20 }
+			]]}
+		];
+
+		var layoutCountries = [
+			// view 0
+			{ type: 'dojox.GridRowView', width: '20px' },
+			// view 1
+			{ cells: [[{ name: "Row", get: getRow, width: 5}]], noscroll: true},
+			// view 2
+			{ cells: [[
+				{ field: "name", name: "Name", width: 'auto' },
+				{ field: "type", name: "Type", editor: iEditor, width: 'auto' }
+			]]}
+		];
+	</script>
+</head>
+<body class="tundra">
+	<h1>dojox.Grid using Dojo.Data stores via simple binding</h1>
+	<!--
+	<br>
+	<span dojoType="dojox.data.CsvStore" 
+		jsId="csvStore" url="support/movies.csv">
+	</span>
+	<span dojoType="dojox.grid.data.DojoData" 
+		jsId="dataModel"
+		store="csvStore"
+		rowsPerPage="5"
+		query="{ Title: '*' }"
+		clientSort="true">
+	</span>
+	<div id="grid" dojoType="dojox.Grid" elasticView="2" 
+		model="dataModel" structure="layoutMovies">
+	</div>
+	-->
+	<br>
+	<h3>Update some of the types</h3>
+	<button onclick="updateCountryTypes();">Go!</button>
+	<script>
+		function updateCountryTypes(){
+			// get everything starting with "A"
+			jsonStore.fetch({
+				query: { name: "A*" },
+				onComplete: function(items, result){
+					// change 'em!
+					dojo.forEach(items, function(item){
+						jsonStore.setValue(item, "type", "thinger");
+						// console.debug(item);
+					});
+				}
+			});
+		}
+	</script>
+
+	<span dojoType="dojo.data.ItemFileWriteStore" 
+		jsId="jsonStore" url="../../../../dijit/tests/_data/countries.json">
+	</span>
+	<span dojoType="dojox.grid.data.DojoData" 
+		jsId="dataModel2" 
+		rowsPerPage="20"
+		store="jsonStore" 
+		clientSort="true"
+		query="{ name : '*' }">
+	</span>
+	<div id="grid2" dojoType="dojox.Grid" elasticView="2" 
+		model="dataModel2" structure="layoutCountries">
+	</div>
+
+	<div id="grid3" dojoType="dojox.Grid" elasticView="2" 
+		model="dataModel2" structure="layoutCountries">
+	</div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_edit.html b/dojox/grid/compat/tests/test_edit.html
new file mode 100644
index 0000000..016433a
--- /dev/null
+++ b/dojox/grid/compat/tests/test_edit.html
@@ -0,0 +1,149 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+<title>Test dojox.Grid Editing</title>
+<style>
+	@import "../../_grid/Grid.css";
+	body {
+		font-family: Tahoma, Arial, Helvetica, sans-serif;
+		font-size: 11px;
+	}
+	.dojoxGrid-row-editing td {
+		background-color: #F4FFF4;
+	}
+	.dojoxGrid input, .dojoxGrid select, .dojoxGrid textarea {
+		margin: 0;
+		padding: 0;
+		border-style: none;
+		width: 100%;
+		font-size: 100%;
+		font-family: inherit;
+	}
+	.dojoxGrid input {
+	}
+	.dojoxGrid select {
+	}
+	.dojoxGrid textarea {
+	}
+	#controls {
+		padding: 6px 0;
+	}
+	#grid {
+		width: 850px;
+		height: 350px;
+		border: 1px solid silver;
+	}
+</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+	<!--<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");
+	</script>-->
+	<!-- Debugging -->
+	<script type="text/javascript" src="../_grid/lib.js"></script>
+	<script type="text/javascript" src="../_grid/drag.js"></script>
+	<script type="text/javascript" src="../_grid/scroller.js"></script>
+	<script type="text/javascript" src="../_grid/builder.js"></script>
+	<script type="text/javascript" src="../_grid/cell.js"></script>
+	<script type="text/javascript" src="../_grid/layout.js"></script>
+	<script type="text/javascript" src="../_grid/rows.js"></script>
+	<script type="text/javascript" src="../_grid/focus.js"></script>
+	<script type="text/javascript" src="../_grid/selection.js"></script>
+	<script type="text/javascript" src="../_grid/edit.js"></script>
+	<script type="text/javascript" src="../_grid/view.js"></script>
+	<script type="text/javascript" src="../_grid/views.js"></script>
+	<script type="text/javascript" src="../_grid/rowbar.js"></script>
+	<script type="text/javascript" src="../_grid/publicEvents.js"></script>
+	<script type="text/javascript" src="../VirtualGrid.js"></script>
+	<script type="text/javascript" src="../_data/fields.js"></script>
+	<script type="text/javascript" src="../_data/model.js"></script>
+	<script type="text/javascript" src="../_data/editors.js"></script>
+	<script type="text/javascript" src="../Grid.js"></script>
+	<script type="text/javascript">
+	// ==========================================================================
+	// Create a data model
+	// ==========================================================================
+	data = [ 
+		[ 0, false, "new", 'But are not followed by two hexadecimal', 29.91, 10, false ],
+		[ 1, false, "new", 'Because a % sign always indicates', 9.33, -5, false ],
+		[ 1, false, "read", 'Signs can be selectively', 19.34, 0, true ],
+		[ 2, false, "read", 'However the reserved characters', 15.63, 0, true ],
+		[ 0, false, "replied", 'It is therefore necessary', 24.22, 5.50, true ],
+		[ 1, false, "replied", 'To problems of corruption by', 9.12, -3, true ],
+		[ 2, false, "replied", 'Which would simply be awkward in', 12.15, -4, false ]
+	];
+	var rows = 10000;
+	for(var i=0, l=data.length; i<rows-l; i++){
+		data.push(data[i%l].slice(0));
+	}
+	model = new dojox.grid.data.Table(null, data);
+	// ==========================================================================
+	// Tie some UI to the data model
+	// ==========================================================================
+	model.observer(this);
+	modelChange = function() {
+		dojo.byId("rowCount").innerHTML = 'Row count: ' + model.count; 
+	}
+	// ==========================================================================
+	// Custom formatter
+	// ==========================================================================
+	formatMoney = function(inDatum) {
+		return isNaN(inDatum) ? '...' : '$' + parseFloat(inDatum).toFixed(2);
+	}
+	// ==========================================================================
+	// Grid structure
+	// ==========================================================================
+	statusCell = { field: 2, name: 'Status', styles: 'text-align: center;', editor: dojox.grid.editors.Select, options: [ "new", "read", "replied" ] };
+	gridLayout = [{
+		type: 'dojox.GridRowView', width: '20px'
+	},{
+		defaultCell: { width: 8, editor: dojox.grid.editors.Input, styles: 'text-align: right;'  },
+		rows: [[
+			{ name: 'Id', width: 3, get: function(inRowIndex) { return inRowIndex+1;} },
+			{ name: 'Priority', styles: 'text-align: center;', editor: dojox.grid.editors.Select, options: ["normal", "note", "important"], values: [0, 1, 2], formatter: function(inDatum) { return this.options[inDatum]}},
+			{ name: 'Mark', width: 3, styles: 'text-align: center;', editor: dojox.grid.editors.Bool },
+			statusCell,
+			{ name: 'Message', styles: '', width: '100%' },
+			{ name: 'Amount', formatter: formatMoney },
+			{ name: 'Amount', field: 4, formatter: formatMoney }
+		]]
+	},{
+		defaultCell: { width: 4, editor: dojox.grid.editors.Input, styles: 'text-align: right;' },
+		rows: [[
+			{ name: 'Mark', width: 3, field: 1, styles: 'text-align: center;', editor: dojox.grid.editors.Bool}, 
+			statusCell,
+			{ name: 'Amount', field: 4, formatter: formatMoney},
+			{ name: 'Detail', value: 'Detail'}
+		]]
+	}];
+	// ==========================================================================
+	// UI Action
+	// ==========================================================================
+	addRow = function(){
+		grid.addRow([ "normal", false, "new", 'Now is the time for all good men to come to the aid of their party.', 99.99, 9.99, false ]);
+	}
+</script>
+</head>
+<body>
+<h2>
+	dojox.Grid Basic Editing test
+</h2>
+<div id="controls">
+	<button onclick="grid.refresh()">Refresh</button>   
+	<button onclick="grid.edit.focusEditor()">Focus Editor</button>
+	<button onclick="grid.focus.next()">Next Focus</button>   
+	<button onclick="addRow()">Add Row</button>
+	<button onclick="grid.removeSelectedRows()">Remove</button>   
+	<button onclick="grid.edit.apply()">Apply</button>
+	<button onclick="grid.edit.cancel()">Cancel</button>   
+	<button onclick="grid.singleClickEdit = !grid.singleClickEdit">Toggle singleClickEdit</button> 
+</div>
+<br />
+<div id="grid" dojoType="dojox.Grid" 
+	jsId="grid"
+	model="model" structure="gridLayout"></div>
+<br />
+<div id="rowCount"></div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_edit_canEdit.html b/dojox/grid/compat/tests/test_edit_canEdit.html
new file mode 100644
index 0000000..84b71a8
--- /dev/null
+++ b/dojox/grid/compat/tests/test_edit_canEdit.html
@@ -0,0 +1,156 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+<title>Test dojox.Grid Editing</title>
+<style>
+	@import "../../_grid/Grid.css";
+	body {
+		font-family: Tahoma, Arial, Helvetica, sans-serif;
+		font-size: 11px;
+	}
+	.dojoxGrid-row-editing td {
+		background-color: #F4FFF4;
+	}
+	.dojoxGrid input, .dojoxGrid select, .dojoxGrid textarea {
+		margin: 0;
+		padding: 0;
+		border-style: none;
+		width: 100%;
+		font-size: 100%;
+		font-family: inherit;
+	}
+	.dojoxGrid input {
+	}
+	.dojoxGrid select {
+	}
+	.dojoxGrid textarea {
+	}
+	#controls {
+		padding: 6px 0;
+	}
+	#grid {
+		width: 850px;
+		height: 350px;
+		border: 1px solid silver;
+	}
+</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+	<!--<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");
+	</script>-->
+	<!-- Debugging -->
+	<script type="text/javascript" src="../_grid/lib.js"></script>
+	<script type="text/javascript" src="../_grid/drag.js"></script>
+	<script type="text/javascript" src="../_grid/scroller.js"></script>
+	<script type="text/javascript" src="../_grid/builder.js"></script>
+	<script type="text/javascript" src="../_grid/cell.js"></script>
+	<script type="text/javascript" src="../_grid/layout.js"></script>
+	<script type="text/javascript" src="../_grid/rows.js"></script>
+	<script type="text/javascript" src="../_grid/focus.js"></script>
+	<script type="text/javascript" src="../_grid/selection.js"></script>
+	<script type="text/javascript" src="../_grid/edit.js"></script>
+	<script type="text/javascript" src="../_grid/view.js"></script>
+	<script type="text/javascript" src="../_grid/views.js"></script>
+	<script type="text/javascript" src="../_grid/rowbar.js"></script>
+	<script type="text/javascript" src="../_grid/publicEvents.js"></script>
+	<script type="text/javascript" src="../VirtualGrid.js"></script>
+	<script type="text/javascript" src="../_data/fields.js"></script>
+	<script type="text/javascript" src="../_data/model.js"></script>
+	<script type="text/javascript" src="../_data/editors.js"></script>
+	<script type="text/javascript" src="../Grid.js"></script>
+	<script type="text/javascript">
+	// ==========================================================================
+	// Create a data model
+	// ==========================================================================
+	data = [ 
+		[ "normal", false, "new", 'But are not followed by two hexadecimal', 29.91, 10, false ],
+		[ "important", false, "new", 'Because a % sign always indicates', 9.33, -5, false ],
+		[ "important", false, "read", 'Signs can be selectively', 19.34, 0, true ],
+		[ "note", false, "read", 'However the reserved characters', 15.63, 0, true ],
+		[ "normal", false, "replied", 'It is therefore necessary', 24.22, 5.50, true ],
+		[ "important", false, "replied", 'To problems of corruption by', 9.12, -3, true ],
+		[ "note", false, "replied", 'Which would simply be awkward in', 12.15, -4, false ]
+	];
+	var rows = 10000;
+	for(var i=0, l=data.length; i<rows-l; i++){
+		data.push(data[i%l].slice(0));
+	}
+	model = new dojox.grid.data.Table(null, data);
+	// ==========================================================================
+	// Tie some UI to the data model
+	// ==========================================================================
+	model.observer(this);
+	modelChange = function() {
+		dojo.byId("rowCount").innerHTML = 'Row count: ' + model.count; 
+	}
+	// ==========================================================================
+	// Custom formatter
+	// ==========================================================================
+	formatMoney = function(inDatum) {
+		return isNaN(inDatum) ? '...' : '$' + parseFloat(inDatum).toFixed(2);
+	}
+	// ==========================================================================
+	// Grid structure
+	// ==========================================================================
+	statusCell = { field: 2, name: 'Status', styles: 'text-align: center;', editor: dojox.grid.editors.Select, options: [ "new", "read", "replied" ] };
+	gridLayout = [{
+		type: 'dojox.GridRowView', width: '20px'
+	},{
+		defaultCell: { width: 8, editor: dojox.grid.editors.Input, styles: 'text-align: right;'  },
+		rows: [[
+			{ name: 'Id', width: 3, get: function(inRowIndex) { return inRowIndex+1;} },
+			{ name: 'Priority', styles: 'text-align: center;', editor: dojox.grid.editors.Select, options: ["normal", "note", "important"]},
+			{ name: 'Mark', width: 3, styles: 'text-align: center;', editor: dojox.grid.editors.Bool },
+			statusCell,
+			{ name: 'Message', styles: '', width: '100%' },
+			{ name: 'Amount', formatter: formatMoney },
+			{ name: 'Amount', field: 4, formatter: formatMoney }
+		]]
+	},{
+		defaultCell: { width: 4, editor: dojox.grid.editors.Input, styles: 'text-align: right;' },
+		rows: [[
+			{ name: 'Mark', width: 3, field: 1, styles: 'text-align: center;', editor: dojox.grid.editors.Bool}, 
+			statusCell,
+			{ name: 'Amount', field: 4, formatter: formatMoney},
+			{ name: 'Detail', value: 'Detail'}
+		]]
+	}];
+	// ==========================================================================
+	// UI Action
+	// ==========================================================================
+	addRow = function(){
+		grid.addRow([ "normal", false, "new", 'Now is the time for all good men to come to the aid of their party.', 99.99, 9.99, false ]);
+	}
+	
+	dojo.addOnLoad(function() {
+		// simple canEdit logic
+		grid.canEdit = function(inCell, inRowIndex) {
+			return !(inCell.index > 1 && inCell.index < 5)
+		}
+	});
+</script>
+</head>
+<body>
+<h2>
+	dojox.Grid Basic Editing test
+</h2>
+<div id="controls">
+	<button onclick="grid.refresh()">Refresh</button>   
+	<button onclick="grid.edit.focusEditor()">Focus Editor</button>
+	<button onclick="grid.focus.next()">Next Focus</button>   
+	<button onclick="addRow()">Add Row</button>
+	<button onclick="grid.removeSelectedRows()">Remove</button>   
+	<button onclick="grid.edit.apply()">Apply</button>
+	<button onclick="grid.edit.cancel()">Cancel</button>   
+	<button onclick="grid.singleClickEdit = !grid.singleClickEdit">Toggle singleClickEdit</button> 
+</div>
+<br />
+<div id="grid" dojoType="dojox.Grid" 
+	jsId="grid"
+	model="model" structure="gridLayout"></div>
+<br />
+<div id="rowCount"></div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_edit_dijit.html b/dojox/grid/compat/tests/test_edit_dijit.html
new file mode 100644
index 0000000..f4769e4
--- /dev/null
+++ b/dojox/grid/compat/tests/test_edit_dijit.html
@@ -0,0 +1,137 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<title>Test dojox.Grid Editing</title>
+	<style type="text/css">
+		@import "../../_grid/tundraGrid.css";
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../../../dijit/themes/tundra/tundra.css";
+		@import "../../../../dijit/themes/tundra/tundra_rtl.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+		#controls button {
+			margin-left: 10px;
+		}
+		#grid {
+			width: 850px;
+			height: 350px;
+			border: 1px solid silver;
+		}
+		</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");
+
+		// ==========================================================================
+		// Create a data model
+		// ==========================================================================
+		
+		s = (new Date()).getTime();
+		
+		data = [ 
+			[ "normal", false, "new", 'But are not followed by two hexadecimal', 29.91, 10, false, s],
+			[ "important", false, "new", 'Because a % sign always indicates', 9.33, -5, false, s ],
+			[ "important", false, "read", 'Signs can be selectively', 19.34, 0, true, s ],
+			[ "note", false, "read", 'However the reserved characters', 15.63, 0, true, s ],
+			[ "normal", false, "replied", 'It is therefore necessary', 24.22, 5.50, true, s ],
+			[ "important", false, "replied", 'To problems of corruption by', 9.12, -3, true, s ],
+			[ "note", false, "replied", 'Which would simply be awkward in', 12.15, -4, false, s ]
+		];
+		var rows = 100;
+		for(var i=0, l=data.length; i<rows; i++){
+			data.push(data[i%l].slice(0));
+		}
+		model = new dojox.grid.data.Table(null, data);
+		// ==========================================================================
+		// Tie some UI to the data model
+		// ==========================================================================
+		model.observer(this);
+		modelChange = function(){
+			dojo.byId("rowCount").innerHTML = 'Row count: ' + model.count; 
+		}
+		/*
+		modelInsertion = modelDatumChange = function(a1, a2, a3){
+			console.debug(a1, a2, a3);
+		}
+		*/
+		// ==========================================================================
+		// Custom formatters
+		// ==========================================================================
+		formatCurrency = function(inDatum){
+			return isNaN(inDatum) ? '...' : dojo.currency.format(inDatum, this.constraint);
+		}
+		formatDate = function(inDatum){
+			return dojo.date.locale.format(new Date(inDatum), this.constraint);
+		}
+		// ==========================================================================
+		// Grid structure
+		// ==========================================================================
+		statusCell = {
+			field: 2, name: 'Status', 
+			styles: 'text-align: center;', 
+			editor: dojox.grid.editors.Select, 
+			options: [ "new", "read", "replied" ]
+		};
+
+		gridLayout = [{
+			type: 'dojox.GridRowView', width: '20px'
+		},{
+			defaultCell: { width: 8, editor: dojox.grid.editors.Input, styles: 'text-align: right;'  },
+			rows: [[
+				{ name: 'Id', 
+					get: function(inRowIndex) { return inRowIndex+1;}, 
+					editor: dojox.grid.editors.Dijit,
+					editorClass: "dijit.form.NumberSpinner" },
+				{ name: 'Date', width: 10, field: 7, 
+					editor: dojox.grid.editors.DateTextBox, 
+					formatter: formatDate, 
+					constraint: {formatLength: 'long', selector: "date"}},
+				{ name: 'Priority', styles: 'text-align: center;', field: 0, 
+					editor: dojox.grid.editors.ComboBox, 
+					options: ["normal", "note", "important"], width: 10},
+				{ name: 'Mark', width: 3, styles: 'text-align: center;', 
+					editor: dojox.grid.editors.CheckBox},
+				statusCell,
+				{ name: 'Message', styles: '', width: '100%', 
+					editor: dojox.grid.editors.Editor, editorToolbar: true },
+				{ name: 'Amount', formatter: formatCurrency, constraint: {currency: 'EUR'}, 
+					editor: dojox.grid.editors.Dijit, editorClass: "dijit.form.CurrencyTextBox" },
+				{ name: 'Amount', field: 4, formatter: formatCurrency, constraint: {currency: 'EUR'}, 
+					editor: dojox.grid.editors.Dijit, editorClass: "dijit.form.HorizontalSlider", width: 10}
+			]]
+		}];
+		// ==========================================================================
+		// UI Action
+		// ==========================================================================
+		addRow = function(){
+			grid.addRow([
+				"normal", false, "new", 
+				'Now is the time for all good men to come to the aid of their party.', 
+				99.99, 9.99, false 
+			]);
+		}
+	</script>
+</head>
+<body class="tundra">
+	<h1>dojox.Grid Basic Editing test</h1>
+	<br />
+	<div id="controls">
+		<button onclick="grid.refresh()">Refresh</button>
+		<button onclick="grid.edit.focusEditor()">Focus Editor</button>
+		<button onclick="grid.focus.next()">Next Focus</button>
+		<button onclick="addRow()">Add Row</button>
+		<button onclick="grid.removeSelectedRows()">Remove</button>
+		<button onclick="grid.edit.apply()">Apply</button>
+		<button onclick="grid.edit.cancel()">Cancel</button>
+		<button onclick="grid.singleClickEdit = !grid.singleClickEdit">Toggle singleClickEdit</button>
+	</div>
+	<br />
+	<div id="grid" jsId="grid" dojoType="dojox.Grid" model="model" structure="gridLayout"></div>
+	<br />
+	<div id="rowCount"></div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_events.html b/dojox/grid/compat/tests/test_events.html
new file mode 100644
index 0000000..46afe9f
--- /dev/null
+++ b/dojox/grid/compat/tests/test_events.html
@@ -0,0 +1,174 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>Test dojox.Grid Events</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../_grid/Grid.css";
+		body,td,th {
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+		}	
+		#grid { 
+			border: 1px solid;
+			border-top-color: #F6F4EB;
+			border-right-color: #ACA899;
+			border-bottom-color: #ACA899;
+			border-left-color: #F6F4EB;
+		}
+		#grid {
+			width: 50em;
+			height: 20em;
+			padding: 1px;
+			overflow: hidden;
+			font-size: small;
+		}
+		h3 {
+			margin: 10px 0 2px 0;
+		}
+		.fade {
+			/*background-image:url(images/fade.gif);*/
+		}
+		.no-fade {
+			/*background-image: none;*/
+		}
+		#eventGrid {
+			float: right;
+			font-size: small;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");
+	</script>
+	<script type="text/javascript">
+		// events to track
+		var eventRows = [
+			{ name: 'onCellClick' },
+			{ name: 'onRowClick', properties: ['rowIndex'] },
+			{ name: 'onCellDblClick' },
+			{ name: 'onRowDblClick', properties: ['rowIndex'] },
+			{ name: 'onCellMouseOver' },
+			{ name: 'onCellMouseOut' },
+			{ name: 'onCellMouseDown' },
+			{ name: 'onRowMouseOver' },
+			{ name: 'onRowMouseOut' },
+			{ name: 'onRowMouseDown' },
+			{ name: 'onHeaderCellClick' },
+			{ name: 'onHeaderClick', properties: ['rowIndex'] },
+			{ name: 'onHeaderCellDblClick' },
+			{ name: 'onHeaderDblClick', properties: ['rowIndex'] },
+			{ name: 'onHeaderCellMouseOver' },
+			{ name: 'onHeaderCellMouseOut' },
+			{ name: 'onHeaderCellMouseDown' },
+			{ name: 'onHeaderMouseOver' },
+			{ name: 'onHeaderMouseOut' },
+			{ name: 'onKeyDown', properties: ['keyCode'] },
+			{ name: 'onCellContextMenu' },
+			{ name: 'onRowContextMenu', properties: ['rowIndex'] },
+			{ name: 'onHeaderCellContextMenu' },
+			{ name: 'onHeaderContextMenu', properties: ['rowIndex'] }
+		];	
+		
+		getEventName = function(inRowIndex) {
+			return eventRows[inRowIndex].name;
+		};
+		
+		getEventData = function(inRowIndex) {
+			var d = eventRows[inRowIndex].data;
+			var r = [];
+			if (d)
+				for (var i in d)
+					r.push(d[i]);
+			else
+				r.push('na')
+			return r.join(', ');
+		}
+		
+		// grid structure for event tracking grid.
+		var eventView = {
+			noscroll: true,
+			cells: [[
+				{ name: 'Event', get: getEventName, width: 12 },
+				{ name: 'Data', get: getEventData, width: 10 }
+			]]
+		}
+		var eventLayout = [	eventView	];
+		
+		var fade = function(inNode) {
+			if (!inNode || !inNode.style) return;
+			var c = 150, step = 5, delay = 20;
+			var animate = function() {
+				c = Math.min(c + step, 255);
+				inNode.style.backgroundColor = "rgb(" + c + ", " + c + ", 255)";
+				if (c < 255) window.setTimeout(animate, delay);
+			}
+			animate();
+		}
+		
+		// setup a fade on a row. Must do this way to avoid caching of fade gif
+		updateRowFade = function(inRowIndex) {
+			var n = eventGrid.views.views[0].getRowNode(inRowIndex);
+			fade(n);
+		}
+		
+		// store data about event. By default track event.rowIndex and event.cell.index, but eventRows can specify params, which are event properties to track.
+		setEventData = function(inIndex, inEvent) {
+			var eRow = eventRows[inIndex];
+			eRow.data = {};
+			var properties = eRow.properties;
+			if (properties)
+				for (var i=0, l=properties.length, p; (p=properties[i] || i < l); i++)
+					eRow.data[p] = inEvent[p];
+			else
+				eRow.data =  {
+					row: (inEvent.rowIndex != undefined ? Number(inEvent.rowIndex) : 'na'), 
+					cell: (inEvent.cell && inEvent.cell.index != undefined ? inEvent.cell.index : 'na')
+				}	
+			eventGrid.updateRow(inIndex);
+			updateRowFade(inIndex);
+		}
+		
+		// setup grid events for all events being tracked.
+		setGridEvents = function() {
+			var makeEvent = function(inIndex, inName) {
+				return function(e) {
+					setEventData(inIndex, e);
+					dojox.VirtualGrid.prototype[inName].apply(this, arguments);
+				}
+			}
+			for (var i=0, e; (e=eventRows[i]); i++)
+				grid[e.name] = makeEvent(i, e.name);
+		}
+				
+		// Grid structure
+		var layout = [// array of view objects
+			{ type: 'dojox.GridRowView', width: '20px' },
+			{ noscroll: true, cells: [// array of rows, a row is an array of cells
+					[{ name: "Alpha", value: '<input type="checkbox"></input>', rowSpan: 2, width: 6, styles: 'text-align:center;' }, { name: "Alpha2", value: "Alpha2" }], 
+					[{ name: "Alpha3", value: "Alpha3" }]
+			]},
+			{ cells: [
+					[{ name: "Beta", value: 'simple'}, { name: "Beta2", value: "Beta2" }, { name: "Beta3", value: "Beta3" }, { name: "Beta4", value: "Beta4" }, { name: "Beta5", value: "Beta5" }], 
+				 	[{ name: "Summary", colSpan: 5, value: 'Summary' }]
+			]},
+			{	noscroll: true, cells: [
+					[{ name: "Gamma", value: "Gamma" }, { name: "Gamma2", value: "<button>Radiate</button>", styles: 'text-align:center;' }]]
+			}];
+		
+		dojo.addOnLoad(function() {
+			window["grid"] = dijit.byId("grid");
+			window["eventGrid"] = dijit.byId("eventGrid");
+			grid.rows.defaultRowHeight = 4;
+			setGridEvents(); 
+			eventGrid.updateRowCount(eventRows.length);
+			dojo.debug = console.log;
+		});	
+	</script>
+</head>
+<body>
+<h3>dojox.Grid Event Tracking</h3>
+<div id="eventGrid" autoWidth="true" autoHeight="true" structure="eventLayout" dojoType="dojox.VirtualGrid"></div>
+<div id="grid" rowCount="100" dojoType="dojox.VirtualGrid"></div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_expand.html b/dojox/grid/compat/tests/test_expand.html
new file mode 100644
index 0000000..cd538e9
--- /dev/null
+++ b/dojox/grid/compat/tests/test_expand.html
@@ -0,0 +1,107 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>Test dojox.Grid Expand Rows</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../_grid/Grid.css";
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+		}
+		.heading {
+			font-weight: bold;
+			padding-bottom: 0.25em;
+		}
+		
+		.bigHello {
+			height: 110px;
+			line-height: 110px;
+			text-align: center;
+			font-weight: bold;
+			font-size: 30px;
+		}	
+				
+		#grid { 
+			border: 1px solid #333;
+			height: 30em;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");
+	</script>
+	<script type="text/javascript">
+		// grid structure
+		// a grid view is a group of columns
+		
+		// a special view providing selection feedback
+		var rowBar = {type: 'dojox.GridRowView', width: '20px' };
+		
+		// inRow is an array of subRows. we hide the summary subRow except for every nth row
+		function onBeforeRow(inDataIndex, inRow) {
+			inRow[1].hidden = (!this.grid || !this.grid.expandedRows || !this.grid.expandedRows[inDataIndex]);
+		}
+		
+		var view = {
+			onBeforeRow: onBeforeRow,
+			cells: [
+				[
+					{ name: 'Whatever', width: 4.5, get: getCheck, styles: 'text-align: center;' },
+					{name: 'Column 0'},
+					{name: 'Column 1'},
+					{name: 'Column 2'},
+					{name: 'Column 3'},
+					{name: 'Column 4'}
+				],
+				[ { name: 'Detail', colSpan: 6, get: getDetail } ]
+			]
+		};
+		
+		// a grid structure is an array of views.
+		var structure = [ rowBar, view ];
+		
+		// get can return data for each cell of the grid
+		function get(inRowIndex) {
+			return [this.index, inRowIndex].join(', ');
+		}
+		
+		function getDetail(inRowIndex) {
+			if (this.grid.expandedRows[inRowIndex]) {
+				var n = (inRowIndex % 2);
+				switch (n) {
+					case 0:
+						return 'Hello World!';
+					default:
+						return '<div class="bigHello">Hello World!</div>';
+				}
+			} else
+				return '';
+		}
+		
+		function toggle(inIndex, inShow) {
+			grid.expandedRows[inIndex] = inShow;
+			grid.updateRow(inIndex);
+		}
+		
+		function getCheck(inRowIndex) {
+			if (!this.grid.expandedRows)
+				this.grid.expandedRows = [ ];
+			var image = (this.grid.expandedRows[inRowIndex] ? 'open.gif' : 'closed.gif');
+			var show = (this.grid.expandedRows[inRowIndex] ? 'false' : 'true')
+			return '<img src="images/' + image + '" onclick="toggle(' + inRowIndex + ', ' + show + ')" height="11" width="11">';
+		}
+
+	dojo.addOnLoad(function() {
+		window["grid"] = dijit.byId("grid");
+	});
+</script>
+</head>
+<body>
+<div class="heading">dojox.Grid Expand Row Example</div>
+
+<div id="grid" dojoType="dojox.VirtualGrid" get="get" structure="structure" rowCount="100000" autoWidth="true"></div>
+
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_grid.html b/dojox/grid/compat/tests/test_grid.html
new file mode 100644
index 0000000..b185776
--- /dev/null
+++ b/dojox/grid/compat/tests/test_grid.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>Test dojox.Grid Basic</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../_grid/Grid.css";
+		@import "../../_grid/tundraGrid.css";
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../../../dijit/themes/tundra/tundra.css";
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+		}
+		.heading {
+			font-weight: bold;
+			padding-bottom: 0.25em;
+		}
+				
+		#grid {
+			border: 1px solid #333;
+			width: 35em;
+			height: 30em;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");
+	</script>
+	<script type="text/javascript" src="support/test_data.js"></script>
+	<script type="text/javascript">
+		// a grid view is a group of columns
+		var view1 = {
+			cells: [[
+				{name: 'Column 0'}, {name: 'Column 1'}, {name: 'Column 2'}, {name: 'Column 3', width: "150px"}, {name: 'Column 4'}
+			],[
+				{name: 'Column 5'}, {name: 'Column 6'}, {name: 'Column 7'}, {name: 'Column 8', field: 3, colSpan: 2}
+			]]
+		};
+		// a grid layout is an array of views.
+		var layout = [ view1 ];
+</script>
+</head>
+<body>
+<div class="heading">dojox.Grid Basic Test</div>
+<div jsid="grid" id="grid" dojoType="dojox.Grid" model="model" structure="layout"></div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_grid_dlg.html b/dojox/grid/compat/tests/test_grid_dlg.html
new file mode 100644
index 0000000..17470e7
--- /dev/null
+++ b/dojox/grid/compat/tests/test_grid_dlg.html
@@ -0,0 +1,88 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>Test dojox.Grid Basic</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+    <script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+    <script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+
+    
+    <style type="text/css">
+		@import "../../_grid/Grid.css";
+        @import "../../../../dojo/resources/dojo.css";
+        @import "../../../../dijit/tests/css/dijitTests.css";
+		table { border: none; }
+        
+        body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+		}
+		.heading {
+			font-weight: bold;
+			padding-bottom: 0.25em;
+		}
+				
+		#grid { 
+			border: 1px solid #333;
+			width: 400px;
+			height: 500px;
+		}
+	</style>
+	<!--<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");
+	</script>-->
+	<!-- Debugging -->
+	<script type="text/javascript" src="../_grid/lib.js"></script>
+	<script type="text/javascript" src="../_grid/drag.js"></script>
+	<script type="text/javascript" src="../_grid/scroller.js"></script>
+	<script type="text/javascript" src="../_grid/builder.js"></script>
+	<script type="text/javascript" src="../_grid/cell.js"></script>
+	<script type="text/javascript" src="../_grid/layout.js"></script>
+	<script type="text/javascript" src="../_grid/rows.js"></script>
+	<script type="text/javascript" src="../_grid/focus.js"></script>
+	<script type="text/javascript" src="../_grid/selection.js"></script>
+	<script type="text/javascript" src="../_grid/edit.js"></script>
+	<script type="text/javascript" src="../_grid/view.js"></script>
+	<script type="text/javascript" src="../_grid/views.js"></script>
+	<script type="text/javascript" src="../_grid/rowbar.js"></script>
+	<script type="text/javascript" src="../_grid/publicEvents.js"></script>
+	<script type="text/javascript" src="../VirtualGrid.js"></script>
+	<script type="text/javascript" src="../_data/fields.js"></script>
+	<script type="text/javascript" src="../_data/model.js"></script>
+	<script type="text/javascript" src="../_data/editors.js"></script>
+	<script type="text/javascript" src="../Grid.js"></script>
+	<script type="text/javascript" src="support/test_data.js"></script>
+	<script type="text/javascript">
+		// a grid view is a group of columns
+		var view1 = {
+			cells: [[
+				{name: 'Column 0'}, {name: 'Column 1'}, {name: 'Column 2'}, {name: 'Column 3', width: "150px"}, {name: 'Column 4'}
+			],[
+				{name: 'Column 5'}, {name: 'Column 6'}, {name: 'Column 7'}, {name: 'Column 8', field: 3, colSpan: 2}
+			]]
+		};
+		// a grid layout is an array of views.
+		var layout = [ view1 ];
+        dojo.require("dijit.Dialog");
+        dojo.require("dijit.form.Button");
+        dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+                
+        function openDialog() {
+            var dialog = dijit.byId('dialog');
+            dialog.show();
+        }
+</script>
+</head>
+<body>
+<div class="heading">dojox.Grid Basic Test</div>
+<button onclick="openDialog()">open</button>
+<div id="dialog" dojoType="dijit.Dialog" title="First Dialog">
+    <table>
+        <tr><td><div id="grid" dojoType="dojox.Grid" model="model" structure="layout"></div></td></tr>
+        <tr><td><button dojoType="dijit.form.Button" type="submit">close</button></td></tr>
+    </table>
+</div>
+
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_grid_headerHeight.html b/dojox/grid/compat/tests/test_grid_headerHeight.html
new file mode 100644
index 0000000..589b8a7
--- /dev/null
+++ b/dojox/grid/compat/tests/test_grid_headerHeight.html
@@ -0,0 +1,84 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>Test dojox.Grid Basic</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../_grid/Grid.css";
+		@import "../../_grid/tundraGrid.css";
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../../../dijit/themes/tundra/tundra.css";
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+		}
+		.heading {
+			font-weight: bold;
+			padding-bottom: 0.25em;
+		}
+				
+		#grid {
+			border: 1px solid #333;
+			width: 65em;
+			height: 30em;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+	<!--<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");
+	</script>-->
+	<!-- Debugging -->
+	<script type="text/javascript" src="../_grid/lib.js"></script>
+	<script type="text/javascript" src="../_grid/drag.js"></script>
+	<script type="text/javascript" src="../_grid/scroller.js"></script>
+	<script type="text/javascript" src="../_grid/builder.js"></script>
+	<script type="text/javascript" src="../_grid/cell.js"></script>
+	<script type="text/javascript" src="../_grid/layout.js"></script>
+	<script type="text/javascript" src="../_grid/rows.js"></script>
+	<script type="text/javascript" src="../_grid/focus.js"></script>
+	<script type="text/javascript" src="../_grid/selection.js"></script>
+	<script type="text/javascript" src="../_grid/edit.js"></script>
+	<script type="text/javascript" src="../_grid/view.js"></script>
+	<script type="text/javascript" src="../_grid/views.js"></script>
+	<script type="text/javascript" src="../_grid/rowbar.js"></script>
+	<script type="text/javascript" src="../_grid/publicEvents.js"></script>
+	<script type="text/javascript" src="../VirtualGrid.js"></script>
+	<script type="text/javascript" src="../_data/fields.js"></script>
+	<script type="text/javascript" src="../_data/model.js"></script>
+	<script type="text/javascript" src="../_data/editors.js"></script>
+	<script type="text/javascript" src="../Grid.js"></script>
+	<script type="text/javascript" src="support/test_data.js"></script>
+	<script type="text/javascript">
+		// a grid view is a group of columns
+		var view1 = {
+			cells: [[
+				{name: 'Column 0'}, {name: 'Column 1', width: "10em"}, {name: 'Column 2', width:"100px"}, {name: 'Column 3 is 25%', width: "25%"}, {name: 'Column 4 is 75% of the remaining space', width: "75%"}
+			]]
+		};
+		// a grid layout is an array of views.
+		var layout = [ view1 ];
+		
+		
+		var layout2 = [// array of view objects
+			{ type: 'dojox.GridRowView', width: '20px' },
+			{ noscroll: true, cells: [// array of rows, a row is an array of cells
+					[{ name: "Alpha", value: '<input type="checkbox"></input>', rowSpan: 2, width: 6, styles: 'text-align:center;' }, { name: "Alpha 2", value: "Alpha2" }], 
+					[{ name: "Alpha 3", value: "Alpha3" }]
+			]},
+			{ cells: [
+					[{ name: "Beta", value: 'simple'}, { name: "Beta 2", value: "Beta 2" }, { name: "Beta 3", value: "Beta 3" }, { name: "Beta 4", value: "Beta 4", width: "auto" }, { name: "Beta 5 is good", value: "Beta 5", width: "auto" }], 
+				 	[{ name: "Summary", colSpan: 5, value: 'Summary' }]
+			]},
+			{	noscroll: true, cells: [
+					[{ name: "Gamma", value: "Gamma" }, { name: "Gamma2", value: "<button>Radiate</button>", styles: 'text-align:center;' }]]
+			}];
+</script>
+</head>
+<body>
+<div class="heading">dojox.Grid Basic Test</div>
+<div jsid="grid" id="grid" dojoType="dojox.Grid" model="model" structure="layout"></div>
+<br /><br />
+<div jsid="grid2" id="grid2" dojoType="dojox.VirtualGrid" model="model" structure="layout2" rowCount="50"></div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_grid_layout.html b/dojox/grid/compat/tests/test_grid_layout.html
new file mode 100644
index 0000000..26be43e
--- /dev/null
+++ b/dojox/grid/compat/tests/test_grid_layout.html
@@ -0,0 +1,112 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>dojox.Grid in Layout Demo</title>
+	<style type="text/css">
+		@import "../../_grid/Grid.css";
+		@import "../../_grid/tundraGrid.css";
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../../../dijit/themes/tundra/tundra.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+
+		html, body{	
+			width: 100%;	/* make the body expand to fill the visible window */
+			height: 100%;
+			padding: 0 0 0 0;
+			margin: 0 0 0 0;
+			overflow: hidden;
+		}
+		.dijitSplitPane{
+			margin: 5px;
+		}
+		
+		/* make grid containers overflow hidden */
+		body .dijitContentPane {
+			overflow: hidden;
+		}
+		#rightPane {
+			margin: 0;
+		}
+	</style>
+
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		djConfig="parseOnLoad: true, isDebug: false"></script>
+	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+
+	<script type="text/javascript">
+		dojo.require("dijit.layout.LayoutContainer");
+		dojo.require("dijit.layout.ContentPane");
+		dojo.require("dijit.layout.LinkPane");
+		dojo.require("dijit.layout.SplitContainer");
+		dojo.require("dijit.layout.TabContainer");
+		
+		dojo.require("dojox.grid.Grid");
+		
+		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+	</script>
+	<script type="text/javascript" src="support/test_data.js"></script>
+	<script type="text/javascript">
+			// a grid view is a group of columns
+			var view1 = {
+				cells: [[
+					{name: 'Column 0'}, {name: 'Column 1'}, {name: 'Column 2'}, {name: 'Column 3', width: "150px"}, {name: 'Column 4'}
+				],[
+					{name: 'Column 5'}, {name: 'Column 6'}, {name: 'Column 7'}, {name: 'Column 8', field: 3, colSpan: 2}
+				]]
+			};
+			// a grid layout is an array of views.
+			var layout = [ view1 ];
+			var layout2 = [ {
+				cells: [[
+					{name: 'Alpha'}, {name: 'Beta'}, {name: 'Gamma'}, {name: 'Delta', width: "150px"}, {name: 'Epsilon'}, {name: 'Nexilon'}, {name: 'Zeta'}, {name: 'Eta', field: 0}, {name: 'Omega' }
+				]]
+			} 
+		];
+		//
+		dojo.addOnLoad(function(){
+			dijit.byId("grid3").update();
+		});
+	</script>
+</head>
+<body class="tundra">
+	<div id="outer" dojoType="dijit.layout.LayoutContainer"
+		style="width: 100%; height: 100%;">
+		<div id="topBar" dojoType="dijit.layout.ContentPane" layoutAlign="top"
+			style="background-color: #274383; color: white;">
+			top bar
+		</div>
+		<div id="bottomBar" dojoType="dijit.layout.ContentPane" layoutAlign="bottom"
+			style="background-color: #274383; color: white;">
+			bottom bar
+		</div>
+		<div id="horizontalSplit" dojoType="dijit.layout.SplitContainer"
+			orientation="horizontal"
+			sizerWidth="5"
+			activeSizing="0"
+			layoutAlign="client"
+		>
+			<div id="leftPane" dojoType="dijit.layout.ContentPane"
+				 sizeMin="20" sizeShare="20">
+				Left side
+			</div>
+
+			<div id="rightPane"
+				dojoType="dijit.layout.SplitContainer"
+				orientation="vertical"
+				sizerWidth="5"
+				activeSizing="0"
+				sizeMin="50" sizeShare="80"
+			>
+				<div id="mainTabContainer" dojoType="dijit.layout.TabContainer" sizeMin="20" sizeShare="70">
+					<div id="grid1" dojoType="dojox.Grid" model="model" title="Tab 1"></div>
+					<div id="grid2" dojoType="dojox.Grid" model="model" structure="layout2" title="Tab 2"></div>
+				</div>
+				<div id="bottomRight" dojoType="dijit.layout.ContentPane" sizeMin="20" sizeShare="30">
+					<div id="grid3" dojoType="dojox.Grid" model="model" structure="layout2"></div>
+				</div>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_grid_layout_LayoutContainer.html b/dojox/grid/compat/tests/test_grid_layout_LayoutContainer.html
new file mode 100644
index 0000000..a51d1c7
--- /dev/null
+++ b/dojox/grid/compat/tests/test_grid_layout_LayoutContainer.html
@@ -0,0 +1,87 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>dojox.Grid in Layout Demo</title>
+	<style type="text/css">
+		@import "../../_grid/Grid.css";
+		@import "../../_grid/tundraGrid.css";
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../../../dijit/themes/tundra/tundra.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+
+		html, body{	
+			width: 100%;	/* make the body expand to fill the visible window */
+			height: 100%;
+			padding: 0 0 0 0;
+			margin: 0 0 0 0;
+			overflow: hidden;
+		}
+		.dijitSplitPane{
+			margin: 5px;
+		}
+		
+		/* make grid containers overflow hidden */
+		body .dijitContentPane {
+			overflow: hidden;
+		}
+		#rightPane {
+			margin: 0;
+		}
+	</style>
+
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		djConfig="parseOnLoad: true, isDebug: false"></script>
+	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+
+	<script type="text/javascript">
+		dojo.require("dijit.layout.LayoutContainer");
+		dojo.require("dijit.layout.ContentPane");
+		dojo.require("dijit.layout.LinkPane");
+		dojo.require("dijit.layout.SplitContainer");
+		dojo.require("dijit.layout.TabContainer");
+		
+		dojo.require("dojox.grid.Grid");
+		
+		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+	</script>
+	<script type="text/javascript" src="support/test_data.js"></script>
+	<script type="text/javascript">
+			// a grid view is a group of columns
+			var view1 = {
+				cells: [[
+					{name: 'Column 0'}, {name: 'Column 1'}, {name: 'Column 2'}, {name: 'Column 3', width: "150px"}, {name: 'Column 4'}
+				],[
+					{name: 'Column 5'}, {name: 'Column 6'}, {name: 'Column 7'}, {name: 'Column 8', field: 3, colSpan: 2}
+				]]
+			};
+			// a grid layout is an array of views.
+			var layout = [ view1 ];
+			var layout2 = [ {
+				cells: [[
+					{name: 'Alpha'}, {name: 'Beta'}, {name: 'Gamma'}, {name: 'Delta', width: "150px"}, {name: 'Epsilon'}, {name: 'Nexilon'}, {name: 'Zeta'}, {name: 'Eta', field: 0}, {name: 'Omega' }
+				]]
+			} 
+		];
+		//
+	</script>
+</head>
+<body class="tundra">
+	<div id="outer" dojoType="dijit.layout.LayoutContainer"
+		style="width: 100%; height: 100%;">
+		
+		<div id="topBar" dojoType="dijit.layout.ContentPane" layoutAlign="top"
+			style="background-color: #274383; color: white; height:100px">
+			top bar
+		</div>
+		<div id="bottomBar" dojoType="dijit.layout.ContentPane" layoutAlign="bottom"
+			style="background-color: #274383; color: white;">
+			bottom bar
+		</div>
+
+		<div id="grid1" dojoType="dojox.Grid" model="model" layoutAlign="client"></div>
+				
+		
+	</div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_grid_layout_borderContainer.html b/dojox/grid/compat/tests/test_grid_layout_borderContainer.html
new file mode 100644
index 0000000..81fef77
--- /dev/null
+++ b/dojox/grid/compat/tests/test_grid_layout_borderContainer.html
@@ -0,0 +1,98 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+	<head>
+		<title>Test dojox.Grid Editing</title>
+		<style>
+			@import "../../_grid/tundraGrid.css";
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/themes/tundra/tundra.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+
+			html, body {
+				width: 100%;	/* make the body expand to fill the visible window */
+				height: 100%;
+				overflow: hidden;	/* erase window level scrollbars */
+				padding: 0 0 0 0;
+				margin: 0 0 0 0;
+			}
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js"
+			djConfig="isDebug:false, parseOnLoad: true"></script>
+
+		<script type="text/javascript">
+			dojo.require("dojox.grid.Grid");
+			dojo.require("dijit.layout.BorderContainer");
+			dojo.require("dijit.layout.ContentPane");
+			dojo.require("dojo.parser");
+		</script>
+
+		<script type="text/javascript">
+			// ==========================================================================
+			// Create a data model
+			// ==========================================================================
+			data = [ 
+				[ "normal", false, "new", 'But are not followed by two hexadecimal', 29.91, 10, false ],
+				[ "important", false, "new", 'Because a % sign always indicates', 9.33, -5, false ],
+				[ "important", false, "read", 'Signs can be selectively', 19.34, 0, true ],
+				[ "note", false, "read", 'However the reserved characters', 15.63, 0, true ],
+				[ "normal", false, "replied", 'It is therefore necessary', 24.22, 5.50, true ],
+				[ "important", false, "replied", 'To problems of corruption by', 9.12, -3, true ],
+				[ "note", false, "replied", 'Which would simply be awkward in', 12.15, -4, false ]
+			];
+			var rows = 10000;
+			for(var i=0, l=data.length; i<rows-l; i++){
+				data.push(data[i%l].slice(0));
+			}
+			model = new dojox.grid.data.Table(null, data);
+
+			// ==========================================================================
+			// Grid structure
+			// ==========================================================================
+			gridLayout = [
+				{
+					type: 'dojox.GridRowView', width: '20px'
+				},
+				{
+					defaultCell: { width: 8, editor: dojox.grid.editors.Input, styles: 'text-align: right;'  },
+					rows: [
+						[
+							{ name: 'Id', width: 3, get: function(inRowIndex){ return inRowIndex+1;} },
+							{ name: 'Priority', styles: 'text-align: center;', editor: dojox.grid.editors.Select, options: ["normal", "note", "important"]},
+							{ name: 'Mark', width: 3, styles: 'text-align: center;', editor: dojox.grid.editors.Bool },
+							{ name: 'Status', field: 2, styles: 'text-align: center;', editor: dojox.grid.editors.Select, options: [ "new", "read", "replied" ]},
+							{ name: 'Message', styles: '', width: '100%' },
+							{ name: 'Amount'}
+						]
+					]
+				}
+			];
+		</script>
+	</head>
+	<body class="tundra">
+<div dojoType="dijit.layout.BorderContainer"  liveSplitters="false" persist="true"
+          id="verticalSplitParam" design="headline" style="width: 100%; height: 100%;">
+
+  <div dojoType="dijit.layout.ContentPane" id="mybuttons" region="top" 
+            splitter="true"  style="width: 100%; height: 10%;">  
+
+	    <div id="controls">
+		     <button onclick="grid.refresh()">Refresh</button>
+		     <button onclick="grid.edit.focusEditor()">Focus Editor</button>
+		     <button onclick="grid.focus.next()">Next Focus</button>
+		     <button onclick="addRow()">Add Row</button>
+		     <button onclick="grid.removeSelectedRows()">Remove</button>
+		     <button onclick="grid.edit.apply()">Apply</button>
+		     <button onclick="grid.edit.cancel()">Cancel</button>
+		     <button onclick="grid.singleClickEdit = !grid.singleClickEdit">Toggle singleClickEdit</button>
+	    </div>
+  </div>
+
+  <div dojoType="dijit.layout.ContentPane" id="gridContainer1" region="center" splitter="true" style="background: red;" > 
+	    <div jsId="grid" class="myGrid" 		dojoType="dojox.Grid" model="model" 	structure="gridLayout"></div>
+  </div>
+
+</div>
+
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_grid_object_model_change.html b/dojox/grid/compat/tests/test_grid_object_model_change.html
new file mode 100644
index 0000000..bb8c5f3
--- /dev/null
+++ b/dojox/grid/compat/tests/test_grid_object_model_change.html
@@ -0,0 +1,86 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>Test dojox.grid.data.Objects model change</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../_grid/Grid.css";
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+		}
+		.heading {
+			font-weight: bold;
+			padding-bottom: 0.25em;
+		}
+				
+		#grid {
+			border: 1px solid #333;
+			width: 35em;
+			height: 30em;
+		}
+		#grid2 {
+			border: 1px solid #333;
+			width: 35em;
+			height: 30em;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+	<!--<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");
+	</script>-->
+	<!-- Debugging -->
+	<script type="text/javascript" src="../_grid/lib.js"></script>
+	<script type="text/javascript" src="../_grid/drag.js"></script>
+	<script type="text/javascript" src="../_grid/scroller.js"></script>
+	<script type="text/javascript" src="../_grid/builder.js"></script>
+	<script type="text/javascript" src="../_grid/cell.js"></script>
+	<script type="text/javascript" src="../_grid/layout.js"></script>
+	<script type="text/javascript" src="../_grid/rows.js"></script>
+	<script type="text/javascript" src="../_grid/focus.js"></script>
+	<script type="text/javascript" src="../_grid/selection.js"></script>
+	<script type="text/javascript" src="../_grid/edit.js"></script>
+	<script type="text/javascript" src="../_grid/view.js"></script>
+	<script type="text/javascript" src="../_grid/views.js"></script>
+	<script type="text/javascript" src="../_grid/rowbar.js"></script>
+	<script type="text/javascript" src="../_grid/publicEvents.js"></script>
+	<script type="text/javascript" src="../VirtualGrid.js"></script>
+	<script type="text/javascript" src="../_data/fields.js"></script>
+	<script type="text/javascript" src="../_data/model.js"></script>
+	<script type="text/javascript" src="../_data/editors.js"></script>
+	<script type="text/javascript" src="../Grid.js"></script>
+	<script type="text/javascript" src="support/test_data_objects.js"></script>
+	<script type="text/javascript">
+		// a grid view is a group of columns
+		var view1 = {
+			cells: [[
+				{name: 'Column 0', field: 'col1'},
+				{name: 'Column 1', field: 'col2'},
+				{name: 'Column 2', field: 'col3'},
+				{name: 'Column 3', field: 'col4', width: "150px"},
+				{name: 'Column 4', field: 'col5'}
+			],[
+				{name: 'Column 5', field: 'col6'},
+				{name: 'Column 6', field: 'col7'},
+				{name: 'Column 7'},
+				{name: 'Column 8', field: 'col4', colSpan: 2}
+			]]
+		};
+		// a grid layout is an array of views.
+		var layout = [ view1 ];
+
+		dojo.addOnLoad(function(){
+			model.setData(data);
+
+			var newModel = new dojox.grid.data.Objects(null, data);
+			dijit.byId("grid2").setModel(newModel);
+		});
+</script>
+</head>
+<body>
+<div class="heading">dojox.grid.data.Objects model change</div>
+<div id="grid" dojoType="dojox.Grid" model="model" structure="layout"></div>
+<div id="grid2" dojoType="dojox.Grid" model="model2" structure="layout"></div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_grid_programmatic.html b/dojox/grid/compat/tests/test_grid_programmatic.html
new file mode 100644
index 0000000..79c32ab
--- /dev/null
+++ b/dojox/grid/compat/tests/test_grid_programmatic.html
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+	<head>
+		<title>Test dojox.Grid Programmatic Instantiation</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../_grid/tundraGrid.css";
+			.heading {
+				font-weight: bold;
+				padding-bottom: 0.25em;
+			}
+					
+			#grid { 
+				border: 1px solid #333;
+				width: 50em;
+				height: 30em;
+			}
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" 
+			djConfig="isDebug:false, debugAtAllCosts: false, parseOnLoad: true"></script>
+		<script type="text/javascript">
+			dojo.require("dojox.grid.Grid");
+			dojo.require("dojo.parser");
+		</script>
+		<script type="text/javascript" src="support/test_data.js"></script>
+		<script type="text/javascript">
+			dojo.addOnLoad(function(){
+				// a grid view is a group of columns
+				var view1 = {
+					cells: [
+						[
+							{name: 'Column 0'}, 
+							{name: 'Column 1'}, 
+							{name: 'Column 2'}, 
+							{name: 'Column 3', width: "150px"}, 
+							{name: 'Column 4'}
+						],
+						[
+							{name: 'Column 5'}, 
+							{name: 'Column 6'}, 
+							{name: 'Column 7'}, 
+							{name: 'Column 8', field: 3, colSpan: 2}
+						]
+					]
+				};
+				// a grid layout is an array of views.
+				var layout = [ view1 ];
+
+				var grid = new dojox.Grid({
+					"id": "grid",
+					"model": model,
+					"structure": layout
+				});
+				dojo.byId("gridContainer").appendChild(grid.domNode);
+				grid.render();
+			});
+		</script>
+	</head>
+	<body class="tundra">
+		<div class="heading">dojox.Grid Programmatic Instantiation Test</div>
+		<div id="gridContainer"></div>
+	</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_grid_programmatic_layout.html b/dojox/grid/compat/tests/test_grid_programmatic_layout.html
new file mode 100644
index 0000000..e30614c
--- /dev/null
+++ b/dojox/grid/compat/tests/test_grid_programmatic_layout.html
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+	<head>
+		<title>Test dojox.Grid Programmatic Instantiation</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+		<style type="text/css">
+			@import "../../_grid/tundraGrid.css";
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/themes/tundra/tundra.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			.heading {
+				font-weight: bold;
+				padding-bottom: 0.25em;
+			}
+					
+			#grid { 
+				width: 100%;
+				height: 100%;
+			}
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" 
+			djConfig="isDebug:false, debugAtAllCosts: false, parseOnLoad: true"></script>
+		<script type="text/javascript">
+			dojo.require("dijit.layout.TabContainer");
+			dojo.require("dijit.layout.ContentPane");
+			dojo.require("dojox.grid.Grid");
+			dojo.require("dojo.parser");
+		</script>
+		<script type="text/javascript" src="support/test_data.js"></script>
+		<script type="text/javascript">
+			dojo.addOnLoad(function(){
+				// a grid view is a group of columns
+				var view1 = {
+					cells: [
+						[
+							{name: 'Column 0'}, 
+							{name: 'Column 1'}, 
+							{name: 'Column 2'}, 
+							{name: 'Column 3', width: "150px"}, 
+							{name: 'Column 4'}
+						],
+						[
+							{name: 'Column 5'}, 
+							{name: 'Column 6'}, 
+							{name: 'Column 7'}, 
+							{name: 'Column 8', field: 3, colSpan: 2}
+						]
+					]
+				};
+				// a grid layout is an array of views.
+				var layout = [ view1 ];
+
+				var grid = new dojox.Grid({
+					title: "tab 1",
+					id: "grid",
+					model: model,
+					structure: layout
+				});
+				dijit.byId("mainTabContainer").addChild(grid, 0);
+				grid.render();
+			});
+		</script>
+	</head>
+	<body class="tundra">
+		<div class="heading">dojox.Grid Programmatic Instantiation Test</div>
+		<div id="mainTabContainer" dojoType="dijit.layout.TabContainer"
+			style="height: 300px; width: 100%;">
+			<div dojoType="dijit.layout.ContentPane" title="Tab 2">
+				... stuff ...
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_grid_rtl.html b/dojox/grid/compat/tests/test_grid_rtl.html
new file mode 100644
index 0000000..056a8b2
--- /dev/null
+++ b/dojox/grid/compat/tests/test_grid_rtl.html
@@ -0,0 +1,71 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>Test dojox.Grid Basic</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../_grid/Grid.css";
+		@import "../../_grid/Grid_rtl.css";
+		@import "../../_grid/tundraGrid.css";
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../../../dijit/themes/tundra/tundra.css";
+		@import "../../../../dijit/themes/tundra/tundra_rtl.css";
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+		}
+		.heading {
+			font-weight: bold;
+			padding-bottom: 0.25em;
+		}
+				
+		#grid {
+			border: 1px solid #333;
+			width: 35em;
+			height: 30em;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<!--<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");
+	</script>-->
+	<!-- Debugging -->
+	<script type="text/javascript" src="../_grid/lib.js"></script>
+	<script type="text/javascript" src="../_grid/drag.js"></script>
+	<script type="text/javascript" src="../_grid/scroller.js"></script>
+	<script type="text/javascript" src="../_grid/builder.js"></script>
+	<script type="text/javascript" src="../_grid/cell.js"></script>
+	<script type="text/javascript" src="../_grid/layout.js"></script>
+	<script type="text/javascript" src="../_grid/rows.js"></script>
+	<script type="text/javascript" src="../_grid/focus.js"></script>
+	<script type="text/javascript" src="../_grid/selection.js"></script>
+	<script type="text/javascript" src="../_grid/edit.js"></script>
+	<script type="text/javascript" src="../_grid/view.js"></script>
+	<script type="text/javascript" src="../_grid/views.js"></script>
+	<script type="text/javascript" src="../_grid/rowbar.js"></script>
+	<script type="text/javascript" src="../_grid/publicEvents.js"></script>
+	<script type="text/javascript" src="../VirtualGrid.js"></script>
+	<script type="text/javascript" src="../_data/fields.js"></script>
+	<script type="text/javascript" src="../_data/model.js"></script>
+	<script type="text/javascript" src="../_data/editors.js"></script>
+	<script type="text/javascript" src="../Grid.js"></script>
+	<script type="text/javascript" src="support/test_data.js"></script>
+	<script type="text/javascript">
+		// a grid view is a group of columns
+		var view1 = {
+			cells: [[
+				{name: 'Column 0'}, {name: 'Column 1'}, {name: 'Column 2'}, {name: 'Column 3', width: "150px"}, {name: 'Column 4'}
+			],[
+				{name: 'Column 5'}, {name: 'Column 6'}, {name: 'Column 7'}, {name: 'Column 8', field: 3, colSpan: 2}
+			]]
+		};
+		// a grid layout is an array of views.
+		var layout = [ view1 ];
+</script>
+</head>
+<body dir="rtl">
+<div class="heading">dojox.Grid Basic Test</div>
+<div id="grid" dojoType="dojox.Grid" model="model" structure="layout"></div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_grid_themes.html b/dojox/grid/compat/tests/test_grid_themes.html
new file mode 100644
index 0000000..e96edc1
--- /dev/null
+++ b/dojox/grid/compat/tests/test_grid_themes.html
@@ -0,0 +1,118 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>dojox.Grid themes</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../_grid/tundraGrid.css";
+		@import "../../_grid/soriaGrid.css";
+		@import "../../_grid/nihiloGrid.css";
+		
+		#grid, #grid2 {
+			width: 65em;
+			height: 25em;
+			padding: 1px;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="isDebug: true, debugAtAllCosts: false, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.data.ItemFileReadStore");
+		dojo.require("dojox.data.CsvStore");
+		dojo.require("dojo.parser");
+	</script>
+
+</head>
+<body>
+	<h5>dojox.grid.Grid structure from markup (tundra theme)</h5>
+	<span dojoType="dojox.data.CsvStore" 
+		jsId="csvStore" url="support/movies.csv">
+	</span>
+
+	<table class="tundra" dojoType="dojox.grid.Grid"
+		store="csvStore"
+		query="{ Title: '*' }"
+		clientSort="true"
+		style="width: 800px; height: 300px;">
+		<thead>
+			<tr>
+				<th width="300px" field="Title">Title of Movie</th>
+
+				<th width="5em">Year</th>
+			</tr>
+			<tr>
+				<th colspan="2">Producer</th>
+			</tr>
+		</thead>
+	</table>
+
+	<span dojoType="dojo.data.ItemFileReadStore" 
+		jsId="jsonStore" url="../../../../dijit/tests/_data/countries.json">
+	</span>
+	<h5>Locked views specified with tables and colgroups (soria theme)</h5>
+
+	<table class="soria" dojoType="dojox.grid.Grid"
+		store="jsonStore"
+		rowsPerPage="20"
+		query="{ name: '*' }"
+		style="width: 600px; height: 300px;">
+		<colgroup span="1" noscroll="true" width="300px"></colgroup>
+		<colgroup span="4"></colgroup>
+		<thead>
+
+			<tr>
+				<th field="name">Country/Continent Name</th>
+				<th width="100px" field="population">Population</th>
+				<th width="100px" field="area">Land Mass</th>
+				<th width="100px" field="timezone">Time Zone</th>
+				<th width="5em" field="type">Type</th>
+
+			</tr>
+		</thead>
+	</table>
+
+	<h5>A "regular" Grid from markup (no table defintion, nihilo theme)</h5>
+	<script type="text/javascript">
+		// helper functions and structure definitions for the old markup construction syntax
+		function getRow(inRowIndex){
+			return ' ' + inRowIndex;
+		}
+		
+		var layoutCountries = [
+			// view 0
+			{ type: 'dojox.GridRowView', width: '20px' },
+			// view 1
+			{
+				cells: [
+					[
+						{ name: "Row", get: getRow, width: 5}
+					]
+				],
+				noscroll: true
+			},
+			// view 2
+			{
+				cells: [
+					[
+						{ field: 0, width: 'auto' },
+						{ width: 8 }
+					]
+				]
+			}
+		];
+	</script>
+	<span dojoType="dojox.grid.data.DojoData" 
+		jsId="dataModel2" 
+		rowsPerPage="20"
+		store="jsonStore" 
+		query="{ name : '*' }">
+	</span>
+
+	<div class="nihilo" id="grid2" dojoType="dojox.grid.Grid" elasticView="2" 
+		model="dataModel2" structure="layoutCountries">
+	</div>
+
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_grid_tooltip_menu.html b/dojox/grid/compat/tests/test_grid_tooltip_menu.html
new file mode 100644
index 0000000..a7df88d
--- /dev/null
+++ b/dojox/grid/compat/tests/test_grid_tooltip_menu.html
@@ -0,0 +1,162 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>Test dojox.Grid Basic</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../_grid/Grid.css";
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../../../dijit/themes/dijit.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+		}
+		.heading {
+			font-weight: bold;
+			padding-bottom: 0.25em;
+		}
+				
+		#grid { 
+			border: 1px solid #333;
+			width: 35em;
+			height: 30em;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dijit.Tooltip");
+		dojo.require("dijit.Menu");
+		dojo.require("dijit.ColorPalette");
+		dojo.require("dojo.parser");
+	</script>
+	<script type="text/javascript" src="support/test_data.js"></script>
+	<script type="text/javascript">
+		// a grid view is a group of columns
+		var view1 = {
+			cells: [[
+				{name: 'Column 0'}, {name: 'Column 1'}, {name: 'Column 2'}, {name: 'Column 3', width: "150px"}, {name: 'Column 4'}
+			],[
+				{name: 'Column 5'}, {name: 'Column 6'}, {name: 'Column 7'}, {name: 'Column 8', field: 3, colSpan: 2}
+			]]
+		};
+		// a grid layout is an array of views.
+		var layout = [ view1 ];
+		
+		dojo.addOnLoad(function() {
+			window["grid"] = dijit.byId("grid");
+			var 
+				showTooltip = function(e) {
+					if(gridTooltipEnabled){
+						var msg = "This is cell " + e.rowIndex + ", " + e.cellIndex;
+						dijit.showTooltip(msg, e.cellNode);
+					}
+				},
+				hideTooltip = function(e) {
+					dijit.hideTooltip(e.cellNode);
+					// FIXME: make sure that pesky tooltip doesn't reappear!
+					// would be nice if there were a way to hide tooltip without regard to aroundNode.
+					dijit._masterTT._onDeck=null;
+				}
+			
+			// cell tooltip
+			dojo.connect(grid, "onCellMouseOver", showTooltip);
+			dojo.connect(grid, "onCellMouseOut", hideTooltip);
+			// header cell tooltip
+			dojo.connect(grid, "onHeaderCellMouseOver", showTooltip);
+			dojo.connect(grid, "onHeaderCellMouseOut", hideTooltip);
+
+			// grid menu
+			window["gridMenu"] = dijit.byId("gridMenu");
+			gridMenu.bindDomNode(grid.domNode);
+			// prevent grid methods from killing the context menu event by implementing our own handler
+			grid.onCellContextMenu = function(e) {
+				cellNode = e.cellNode;
+			};
+			grid.onHeaderContextMenu = function(e) {
+				cellNode = e.cellNode;
+			};
+		});
+		
+		function reportCell() {
+			if(cellNode){
+				alert("Cell contents:  " + cellNode.innerHTML);
+				cellNode = null;
+			}
+		}
+		
+		gridTooltipEnabled = true;
+		function toggleTooltip(button){
+			gridTooltipEnabled = !gridTooltipEnabled;
+			button.value = gridTooltipEnabled ? "Disable Grid Tooltip" : "Enable Grid Tooltip";
+		}
+		
+		gridMenuEnabled = true;
+		function toggleMenu(button){
+			gridMenuEnabled = !gridMenuEnabled;
+			button.value = gridMenuEnabled ? "Disable Grid Menu" : "Enable Grid Menu";
+			gridMenu[gridMenuEnabled ? "bindDomNode" : "unBindDomNode"](grid.domNode);
+		}
+</script>
+</head>
+<body>
+<div dojoType="dijit.Menu" id="gridMenu"  style="display: none;">
+	<div dojoType="dijit.MenuItem" onClick="reportCell">See cell text...</div>
+	<div dojoType="dijit.MenuItem" disabled="true">Disabled Item</div>
+	<div dojoType="dijit.MenuSeparator"></div>
+	<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconCut"
+		onClick="alert('not actually cutting anything, just a test!')">Cut</div>
+	<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconCopy"
+		onClick="alert('not actually copying anything, just a test!')">Copy</div>
+	<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconPaste"
+		onClick="alert('not actually pasting anything, just a test!')">Paste</div>
+	<div dojoType="dijit.MenuSeparator"></div>
+</div>
+<div dojoType="dijit.Menu" id="submenu1" contextMenuForWindow="true" style="display: none;">
+	<div dojoType="dijit.MenuItem" onClick="alert('Hello world');">Enabled Item</div>
+	<div dojoType="dijit.MenuItem" disabled="true">Disabled Item</div>
+	<div dojoType="dijit.MenuSeparator"></div>
+	<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconCut"
+		onClick="alert('not actually cutting anything, just a test!')">Cut</div>
+	<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconCopy"
+		onClick="alert('not actually copying anything, just a test!')">Copy</div>
+	<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconPaste"
+		onClick="alert('not actually pasting anything, just a test!')">Paste</div>
+	<div dojoType="dijit.MenuSeparator"></div>
+	<div dojoType="dijit.PopupMenuItem">
+		<span>Enabled Submenu</span>
+		<div dojoType="dijit.Menu" id="submenu2">
+			<div dojoType="dijit.MenuItem" onClick="alert('Submenu 1!')">Submenu Item One</div>
+			<div dojoType="dijit.MenuItem" onClick="alert('Submenu 2!')">Submenu Item Two</div>
+			<div dojoType="dijit.PopupMenuItem">
+				<span>Deeper Submenu</span>
+				<div dojoType="dijit.Menu" id="submenu4">
+					<div dojoType="dijit.MenuItem" onClick="alert('Sub-submenu 1!')">Sub-sub-menu Item One</div>
+					<div dojoType="dijit.MenuItem" onClick="alert('Sub-submenu 2!')">Sub-sub-menu Item Two</div>
+				</div>
+			</div>
+		</div>
+	</div>
+	<div dojoType="dijit.PopupMenuItem" disabled="true">
+		<span>Disabled Submenu</span>
+		<div dojoType="dijit.Menu" id="submenu3" style="display: none;">
+			<div dojoType="dijit.MenuItem" onClick="alert('Submenu 1!')">Submenu Item One</div>
+			<div dojoType="dijit.MenuItem" onClick="alert('Submenu 2!')">Submenu Item Two</div>
+		</div>
+	</div>
+	<div dojoType="dijit.PopupMenuItem">
+		<span>Different popup</span>
+		<div dojoType="dijit.ColorPalette"></div>
+	</div>
+</div>
+<div class="heading">dojox.Grid Basic Test</div>
+<p>
+	<input type="button" onclick="toggleTooltip(this)" value="Disable Grid Tooltip">  
+	<input type="button" onclick="toggleMenu(this)" value="Disable Grid Menu">  <br />
+	Note: when the grid menu is disabled, the document's dijit context menu should be shown over the grid.
+</p>
+<div id="grid" dojoType="dojox.Grid" model="model" structure="layout"></div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_keyboard.html b/dojox/grid/compat/tests/test_keyboard.html
new file mode 100644
index 0000000..9927e4d
--- /dev/null
+++ b/dojox/grid/compat/tests/test_keyboard.html
@@ -0,0 +1,90 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>Test dojox.Grid Basic</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../_grid/Grid.css";
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+		}
+		.heading {
+			font-weight: bold;
+			padding-bottom: 0.25em;
+		}
+				
+		#grid { 
+			border: 1px solid #333;
+			width: 35em;
+			height: 30em;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<!--<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");
+	</script>-->
+	<!-- Debugging -->
+	<script type="text/javascript" src="../_grid/lib.js"></script>
+	<script type="text/javascript" src="../_grid/drag.js"></script>
+	<script type="text/javascript" src="../_grid/scroller.js"></script>
+	<script type="text/javascript" src="../_grid/builder.js"></script>
+	<script type="text/javascript" src="../_grid/cell.js"></script>
+	<script type="text/javascript" src="../_grid/layout.js"></script>
+	<script type="text/javascript" src="../_grid/rows.js"></script>
+	<script type="text/javascript" src="../_grid/focus.js"></script>
+	<script type="text/javascript" src="../_grid/selection.js"></script>
+	<script type="text/javascript" src="../_grid/edit.js"></script>
+	<script type="text/javascript" src="../_grid/view.js"></script>
+	<script type="text/javascript" src="../_grid/views.js"></script>
+	<script type="text/javascript" src="../_grid/rowbar.js"></script>
+	<script type="text/javascript" src="../_grid/publicEvents.js"></script>
+	<script type="text/javascript" src="../VirtualGrid.js"></script>
+	<script type="text/javascript" src="../_data/fields.js"></script>
+	<script type="text/javascript" src="../_data/model.js"></script>
+	<script type="text/javascript" src="../_data/editors.js"></script>
+	<script type="text/javascript" src="../Grid.js"></script>
+	<script type="text/javascript" src="support/test_data.js"></script>
+	<script type="text/javascript">
+		// a grid view is a group of columns
+		var view1 = {
+			cells: [[
+				{name: 'Column 0'}, {name: 'Column 1'}, {name: 'Column 2'}, {name: 'Column 3', width: "150px"}, {name: 'Column 4'},
+				{name: 'Column 5'}, {name: 'Column 6'}, {name: 'Column 7', field: 0}, {name: 'Column 8'},
+				{name: 'Column 9'}, {name: 'Column 10'}, {name: 'Column 11', field: 0}, {name: 'Column 12', width: "150px"}, {name: 'Column 13'},
+				{name: 'Column 14'}, {name: 'Column 15'}, {name: 'Column 16', field: 0}, {name: 'Column 17'}
+			]]
+		};
+		// a grid layout is an array of views.
+		var layout = [ view1 ];
+		
+		
+		function keyDown(e) {
+			switch(e.keyCode){
+				case dojo.keys.LEFT_ARROW:
+					console.log('left arrow!');
+					break;
+				case dojo.keys.RIGHT_ARROW:
+					console.log('right arrow!');
+					break;
+				case dojo.keys.ENTER:
+					console.log('enter!');
+					break;
+			}
+			
+			
+		}
+		
+		dojo.addOnLoad(function() {
+			window["grid"] = dijit.byId("grid");
+			dojo.connect(grid, "onKeyDown", keyDown);
+		});
+		
+</script>
+</head>
+<body>
+<div class="heading">dojox.Grid Basic Test</div>
+<div id="grid" dojoType="dojox.Grid" model="model" structure="layout"></div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_markup.html b/dojox/grid/compat/tests/test_markup.html
new file mode 100644
index 0000000..84acb82
--- /dev/null
+++ b/dojox/grid/compat/tests/test_markup.html
@@ -0,0 +1,112 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>dojox.Grid with Dojo.Data via binding</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../_grid/tundraGrid.css";
+		
+		#grid, #grid2 {
+			width: 65em;
+			height: 25em;
+			padding: 1px;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="isDebug: true, debugAtAllCosts: false, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.data.ItemFileReadStore");
+		dojo.require("dojox.data.CsvStore");
+		dojo.require("dojo.parser");
+	</script>
+</head>
+<body class="tundra">
+	<h5>dojox.grid.Grid structure from markup</h5>
+	<span dojoType="dojox.data.CsvStore" 
+		jsId="csvStore" url="support/movies.csv">
+	</span>
+
+	<table dojoType="dojox.grid.Grid"
+		store="csvStore"
+		query="{ Title: '*' }"
+		clientSort="true"
+		style="width: 800px; height: 300px;">
+		<thead>
+			<tr>
+				<th width="300px" field="Title">Title of Movie</th>
+				<th width="5em">Year</th>
+			</tr>
+			<tr>
+				<th colspan="2">Producer</th>
+			</tr>
+		</thead>
+	</table>
+
+
+	<span dojoType="dojo.data.ItemFileReadStore" 
+		jsId="jsonStore" url="../../../../dijit/tests/_data/countries.json">
+	</span>
+	<h5>Locked views specified with tables and colgroups</h5>
+
+	<table dojoType="dojox.grid.Grid"
+		store="jsonStore"
+		rowsPerPage="20"
+		query="{ name: '*' }"
+		style="width: 600px; height: 300px;">
+		<colgroup span="1" noscroll="true" width="300px"></colgroup>
+		<colgroup span="4"></colgroup>
+		<thead>
+			<tr>
+				<th field="name">Country/Continent Name</th>
+				<th width="100px" field="population">Population</th>
+				<th width="100px" field="area">Land Mass</th>
+				<th width="100px" field="timezone">Time Zone</th>
+				<th width="5em" field="type">Type</th>
+			</tr>
+		</thead>
+	</table>
+
+	<h5>A "regular" Grid from markup (no table defintion)</h5>
+	<script type="text/javascript">
+		// helper functions and structure definitions for the old markup construction syntax
+		function getRow(inRowIndex){
+			return ' ' + inRowIndex;
+		}
+		
+		var layoutCountries = [
+			// view 0
+			{ type: 'dojox.GridRowView', width: '20px' },
+			// view 1
+			{
+				cells: [
+					[
+						{ name: "Row", get: getRow, width: 5}
+					]
+				],
+				noscroll: true
+			},
+			// view 2
+			{
+				cells: [
+					[
+						{ field: 0, width: 'auto' },
+						{ width: 8 }
+					]
+				]
+			}
+		];
+	</script>
+	<span dojoType="dojox.grid.data.DojoData" 
+		jsId="dataModel2" 
+		rowsPerPage="20"
+		store="jsonStore" 
+		query="{ name : '*' }">
+	</span>
+	<div id="grid2" dojoType="dojox.grid.Grid" elasticView="2" 
+		model="dataModel2" structure="layoutCountries">
+	</div>
+
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_mysql_edit.html b/dojox/grid/compat/tests/test_mysql_edit.html
new file mode 100644
index 0000000..e2617c0
--- /dev/null
+++ b/dojox/grid/compat/tests/test_mysql_edit.html
@@ -0,0 +1,155 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html debug="true">
+<head>
+	<title>dojox.Grid Test: Mysql Table Editing</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style>
+		@import "../../_grid/tundraGrid.css";
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../../../dijit/themes/tundra/tundra.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+
+		.grid {
+			height: 30em;
+		}
+	</style>
+
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+	<!--<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojox.grid.tests.databaseModel");
+		dojo.require("dojo.parser");
+	</script>-->
+	<!-- Debugging -->
+	<script type="text/javascript" src="../_grid/lib.js"></script>
+	<script type="text/javascript" src="../_grid/drag.js"></script>
+	<script type="text/javascript" src="../_grid/scroller.js"></script>
+	<script type="text/javascript" src="../_grid/builder.js"></script>
+	<script type="text/javascript" src="../_grid/cell.js"></script>
+	<script type="text/javascript" src="../_grid/layout.js"></script>
+	<script type="text/javascript" src="../_grid/rows.js"></script>
+	<script type="text/javascript" src="../_grid/focus.js"></script>
+	<script type="text/javascript" src="../_grid/selection.js"></script>
+	<script type="text/javascript" src="../_grid/edit.js"></script>
+	<script type="text/javascript" src="../_grid/view.js"></script>
+	<script type="text/javascript" src="../_grid/views.js"></script>
+	<script type="text/javascript" src="../_grid/rowbar.js"></script>
+	<script type="text/javascript" src="../_grid/publicEvents.js"></script>
+	<script type="text/javascript" src="../VirtualGrid.js"></script>
+	<script type="text/javascript" src="../_data/fields.js"></script>
+	<script type="text/javascript" src="../_data/model.js"></script>
+	<script type="text/javascript" src="../_data/editors.js"></script>
+	<script type="text/javascript" src="../_data/dijitEditors.js"></script>
+	<script type="text/javascript" src="../Grid.js"></script>
+	<script type="text/javascript" src="databaseModel.js"></script>
+	<script type="text/javascript">
+		var model = new dojox.grid.data.DbTable(null, null, 'support/data.php', "test", "testtbl");
+		// simple display of row info; based on model observing.
+		modelChange = function() {
+			dojo.byId('rowCount').innerHTML = model.count + ' row(s)';
+		}
+		model.observer(this);
+		
+		// yay, let's deal with MySql date types, at least a little bit...
+		// NOTE: supports only default date formatting YYYY-MM-DD HH:MM:SS or YY-MM-DD HH:MM:SS
+		mysqlDateToJsDate = function(inMysqlDateTime, inDateDelim, inTimeDelim) {
+			var dt = inMysqlDateTime.split(' '), d = dt[0], t = dt[1], r;
+			d = d&&d.split(inDateDelim||'-');
+			t = t&&t.split(inTimeDelim||':');
+			if (d && d.length == 3) {
+				r = new Date();
+				r.setYear(d[0]);
+				r.setMonth(parseInt(d[1])-1);
+				r.setDate(d[2]);
+			}
+			if (t && t.length == 3) {
+				r = r || new Date();
+				r.setHours(t[0]);
+				r.setMinutes(t[1]);
+				r.setSeconds(t[2]);
+			}
+			return r || new Date(inMysqlDateTime);
+		}
+		
+		jsDateToMySqlDate = function(inDate) {
+			var
+				d = new Date(inDate),
+				y = d.getFullYear(),
+				m = dojo.string.pad(d.getMonth() + 1),
+				dd = dojo.string.pad(d.getDate())
+			return dojo.string.substitute("${0}-${1}-${2}",[y, m, dd]);
+		};
+		
+		// custom simple MySql date formatter
+		formatMySqlDate = function(inDatum) {
+			return inDatum != dojox.grid.na ? dojo.date.locale.format(mysqlDateToJsDate(inDatum), this.constraint) : dojox.grid.na;
+		}
+		
+		// custom simple MySql date editor
+		dojo.declare("mySqlDateEditor", dojox.grid.editors.DateTextBox, {
+			format: function(inDatum, inRowIndex){
+				inDatum = mysqlDateToJsDate(inDatum);
+				return this.inherited(arguments, [inDatum, inRowIndex]);
+			},
+			getValue: function(inRowIndex){
+				var v = this.editor.getValue(), fv = jsDateToMySqlDate(v);
+				return fv;
+			}
+		});
+		
+		var gridLayout = [ 
+			{ type: "dojox.GridRowView", width: "20px" },
+			{
+			defaultCell: { width: 6, editor: dojox.grid.editors.Dijit }, 
+			cells: [[
+				{ name: 'Id', styles: 'text-align: right;', editorClass: "dijit.form.NumberTextBox" }, 
+				{ name: 'Name', width: 20},
+				{ name: 'Message', styles: 'text-align: right;'},
+				{ name: 'Date', 
+					editor: mySqlDateEditor, 
+					formatter: formatMySqlDate, 
+					constraint: {selector: "date"}, 
+					width: 10, 
+					styles: 'text-align:right;'}
+			]]}
+		];
+
+		function waitMessage() {
+			alert('Edit in progress, please wait.');
+		}
+		
+		function getDefaultRow() {
+			return ['', '', '', jsDateToMySqlDate(new Date())];
+		}
+		function addRow() {
+			if(model.canModify()){
+				grid.addRow(getDefaultRow());
+			}else{
+				waitMessage();
+			}
+		}
+		
+		function removeSelected(){
+			if(model.canModify()){
+				grid.removeSelectedRows();
+			}else{
+				waitMessage();
+			}
+		}
+	</script>
+</head>
+<body class="tundra">
+	<h1>dojox.Grid Test: Mysql Table Editing</h1>
+	<br>
+	<button onclick="addRow()">Add Row</button>  
+	<button onclick="removeSelected()">Remove Selected</button>  
+	<button onclick="grid.edit.apply()">Apply Edit</button>  
+	<button onclick="grid.edit.cancel()">Cancel Edit</button>  
+	<button onclick="grid.refresh()">Refresh</button>
+	<br><br>
+	<div jsId="grid" class="grid" structure="gridLayout" dojoType="dojox.Grid" model="model" singleClickEdit="true" autoWidth="true"></div>
+	<div id="rowCount"></div>
+	<p>Note: This test requires MySql and PHP and works with the database table available in support/testtbl.sql.</p>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_sizing.html b/dojox/grid/compat/tests/test_sizing.html
new file mode 100644
index 0000000..e25b0d7
--- /dev/null
+++ b/dojox/grid/compat/tests/test_sizing.html
@@ -0,0 +1,175 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>dojox.Grid Sizing Example</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../_grid/tundraGrid.css";
+		
+		.heading {
+			font-weight: bold;
+			padding-bottom: 0.25em;
+		}
+		
+		#container {
+			width: 400px;
+			height: 200px;
+			border: 4px double #333; 
+		}
+				
+		#grid { 
+			border: 1px solid #333;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");
+	</script>
+	<!-- Debugging -->
+	<script type="text/javascript" src="../_grid/lib.js"></script>
+	<script type="text/javascript" src="../_grid/drag.js"></script>
+	<script type="text/javascript" src="../_grid/scroller.js"></script>
+	<script type="text/javascript" src="../_grid/builder.js"></script>
+	<script type="text/javascript" src="../_grid/cell.js"></script>
+	<script type="text/javascript" src="../_grid/layout.js"></script>
+	<script type="text/javascript" src="../_grid/rows.js"></script>
+	<script type="text/javascript" src="../_grid/focus.js"></script>
+	<script type="text/javascript" src="../_grid/selection.js"></script>
+	<script type="text/javascript" src="../_grid/edit.js"></script>
+	<script type="text/javascript" src="../_grid/view.js"></script>
+	<script type="text/javascript" src="../_grid/views.js"></script>
+	<script type="text/javascript" src="../_grid/rowbar.js"></script>
+	<script type="text/javascript" src="../_grid/publicEvents.js"></script>
+	<script type="text/javascript" src="../VirtualGrid.js"></script>
+	<script type="text/javascript" src="../_data/fields.js"></script>
+	<script type="text/javascript" src="../_data/model.js"></script>
+	<script type="text/javascript" src="../_data/editors.js"></script>
+	<script type="text/javascript" src="../Grid.js"></script>
+	<script type="text/javascript" src="support/test_data.js"></script>
+	<script type="text/javascript">
+		data = [ 
+			[ "normal", false, "new", 'But are not followed by two hexadecimal', 29.91, 10, false ],
+			[ "important", false, "new", 'Because a % sign always indicates', 9.33, -5, false ],
+			[ "important", false, "read", 'Signs can be selectively', 19.34, 0, true ],
+			[ "note", false, "read", 'However the reserved characters', 15.63, 0, true ],
+			[ "normal", false, "replied", 'It is therefore necessary', 24.22, 5.50, true ],
+			[ "important", false, "replied", 'To problems of corruption by', 9.12, -3, true ],
+			[ "note", false, "replied", 'Which would simply be awkward in', 12.15, -4, false ]
+		];
+		model = new dojox.grid.data.table(null, data);
+		
+		// grid structure
+		// a grid view is a group of columns
+		// a special view providing selection feedback
+		var rowBar = {type: 'dojox.GridRowView', width: '20px'};
+		
+		// a view without scrollbars
+		var leftView = {
+			noscroll: true,
+			cells: [[
+				{name: 'Column 0'},
+				{name: 'Column 1'}
+		]]};
+		
+		var middleView = {
+			cells: [[
+				{name: 'Column 2'},
+				{name: 'Column 3'},
+				{name: 'Column 4'},
+				{name: 'Column 5'},
+				{name: 'Column 6'}
+		]]};
+		
+		// a grid structure is an array of views.
+		var structure = [ rowBar, leftView, middleView];
+		
+		// get can return data for each cell of the grid
+		function get(inRowIndex) {
+			return [this.index, inRowIndex].join(', ');
+		}
+		
+		function resizeInfo() {
+			setTimeout(function() {
+				dojo.byId('gridWidth').value = grid.domNode.clientWidth;
+				dojo.byId('gridHeight').value = grid.domNode.clientHeight;
+			}, 1);
+		}
+		
+		function resizeGrid() {
+			grid.autoHeight = false;
+			grid.autoWidth = false;
+			var
+				w = Number(dojo.byId('gridWidth').value),
+				h = Number(dojo.byId('gridHeight').value);
+			
+			dojo.contentBox(grid.domNode, {w: w, h: h});
+			grid.update();
+		}
+		
+		function fitWidth() {
+			grid.autoWidth = true;
+			grid.autoHeight = false;
+			grid.update();
+		}
+		
+		function fitHeight() {
+			grid.autoWidth = false;
+			grid.autoHeight = true;
+			grid.update();
+		}
+		
+		function fitBoth() {
+			grid.autoWidth = true;
+			grid.autoHeight = true;
+			grid.update();
+		}
+		
+		function sizeDefault() {
+			grid.autoWidth = false;
+			grid.autoHeight = false;
+			grid.domNode.style.width = '';
+			grid.domNode.style.height = 0;
+			grid.update();
+		}
+		
+		dojo.addOnLoad(function() {
+			window["grid"] = dijit.byId("grid");
+			dojo.byId('gridWidth').value = 500;
+			dojo.byId('gridHeight').value = 200;
+			dojo.connect(grid, 'update', resizeInfo);
+			resizeGrid();
+			window["grid1"] = dijit.byId("grid1");
+		});
+		
+	
+</script>
+</head>
+<body class="tundra">
+<div class="heading">dojox.Grid Sizing Test</div>
+	Grid width: <input id="gridWidth" type="text">  
+	and height: <input id="gridHeight" type="text"> 
+	<button onclick="resizeGrid()">Resize Grid</button><br><br>
+	<button onclick="fitWidth()">Fit Data Width</button> 
+	<button onclick="fitHeight()">Fit Data Height</button> 
+	<button onclick="fitBoth()">Fit Data Width & Height</button>
+	<button onclick="sizeDefault()">DefaultSize</button><br><br>
+	<div id="grid" dojoType="dojox.Grid" autoWidth="true" autoHeight="true" model="model" structure="structure" elasticView="2"></div>
+	
+	<p>Grid fits to a sized container by default:</p>
+	<div id="container">
+		<div id="grid1" dojoType="dojox.VirtualGrid" get="get" structure="structure" rowCount="10" elasticView="2"></div>
+	</div>
+
+	<p> Grid is essentially hidden (height of zero) when parent container is unsized 
+		(nothing, including the header, should be displayed):</p>
+	<div id="unsizedContainer">
+		<div id="grid2" dojoType="dojox.VirtualGrid" get="get" structure="structure" rowCount="10" elasticView="2"></div>
+	</div>
+
+	<p> Grid is autoHeight and autoWidth via markup</p>
+		<div id="grid3" dojoType="dojox.VirtualGrid" autoWidth="true" autoHeight="true" get="get" structure="structure" rowCount="10" elasticView="2"></div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_sizing_100rows.html b/dojox/grid/compat/tests/test_sizing_100rows.html
new file mode 100644
index 0000000..ca13426
--- /dev/null
+++ b/dojox/grid/compat/tests/test_sizing_100rows.html
@@ -0,0 +1,168 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>dojox.Grid Sizing Example</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../_grid/tundraGrid.css";
+		
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+		}
+		.heading {
+			font-weight: bold;
+			padding-bottom: 0.25em;
+		}
+		
+		#container {
+			width: 400px;
+			height: 200px;
+			border: 4px double #333; 
+		}
+				
+		#grid { 
+			border: 1px solid #333;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		/*dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");*/
+	</script>
+	<!-- Debugging -->
+	<script type="text/javascript" src="../_grid/lib.js"></script>
+	<script type="text/javascript" src="../_grid/drag.js"></script>
+	<script type="text/javascript" src="../_grid/scroller.js"></script>
+	<script type="text/javascript" src="../_grid/builder.js"></script>
+	<script type="text/javascript" src="../_grid/cell.js"></script>
+	<script type="text/javascript" src="../_grid/layout.js"></script>
+	<script type="text/javascript" src="../_grid/rows.js"></script>
+	<script type="text/javascript" src="../_grid/focus.js"></script>
+	<script type="text/javascript" src="../_grid/selection.js"></script>
+	<script type="text/javascript" src="../_grid/edit.js"></script>
+	<script type="text/javascript" src="../_grid/view.js"></script>
+	<script type="text/javascript" src="../_grid/views.js"></script>
+	<script type="text/javascript" src="../_grid/rowbar.js"></script>
+	<script type="text/javascript" src="../_grid/publicEvents.js"></script>
+	<script type="text/javascript" src="../VirtualGrid.js"></script>
+	<script type="text/javascript" src="../_data/fields.js"></script>
+	<script type="text/javascript" src="../_data/model.js"></script>
+	<script type="text/javascript" src="../_data/editors.js"></script>
+	<script type="text/javascript" src="../Grid.js"></script>
+	<script type="text/javascript" src="support/test_data.js"></script>
+	<script type="text/javascript">
+		// grid structure
+		// a grid view is a group of columns
+		// a special view providing selection feedback
+		var rowBar = {type: 'dojox.GridRowView', width: '20px'};
+		
+		// a view without scrollbars
+		var leftView = {
+			noscroll: true,
+			cells: [[
+				{name: 'Column 0'},
+				{name: 'Column 1'}
+		]]};
+		
+		var middleView = {
+			cells: [[
+				{name: 'Column 2'},
+				{name: 'Column 3'},
+				{name: 'Column 4'},
+				{name: 'Column 5'},
+				{name: 'Column 6'}
+		]]};
+		
+		// a grid structure is an array of views.
+		var structure = [ rowBar, leftView, middleView];
+		
+		// get can return data for each cell of the grid
+		function get(inRowIndex) {
+			return [this.index, inRowIndex].join(', ');
+		}
+		
+		function resizeInfo() {
+			setTimeout(function() {
+				dojo.byId('gridWidth').value = grid.domNode.clientWidth;
+				dojo.byId('gridHeight').value = grid.domNode.clientHeight;
+			}, 1);
+		}
+		
+		function resizeGrid() {
+			grid.autoHeight = false;
+			grid.autoWidth = false;
+			var
+				w = Number(dojo.byId('gridWidth').value),
+				h = Number(dojo.byId('gridHeight').value);
+			
+			dojo.contentBox(grid.domNode, {w: w, h: h});
+			grid.update();
+		}
+		
+		function fitWidth() {
+			grid.autoWidth = true;
+			grid.autoHeight = false;
+			grid.update();
+		}
+		
+		function fitHeight() {
+			grid.autoWidth = false;
+			grid.autoHeight = true;
+			grid.update();
+		}
+		
+		function fitBoth() {
+			grid.autoWidth = true;
+			grid.autoHeight = true;
+			grid.update();
+		}
+		
+		function sizeDefault() {
+			grid.autoWidth = false;
+			grid.autoHeight = false;
+			grid.domNode.style.width = '';
+			grid.domNode.style.height = 0;
+			grid.update();
+		}
+		
+		dojo.addOnLoad(function() {
+			window["grid"] = dijit.byId("grid");
+			dojo.byId('gridWidth').value = 500;
+			dojo.byId('gridHeight').value = 200;
+			dojo.connect(grid, 'update', resizeInfo);
+			resizeGrid();
+			window["grid1"] = dijit.byId("grid1");
+		});
+		
+	
+</script>
+</head>
+<body class="tundra">
+<div class="heading">dojox.Grid Sizing Test</div>
+	Grid width: <input id="gridWidth" type="text">  
+	and height: <input id="gridHeight" type="text"> 
+	<button onclick="resizeGrid()">Resize Grid</button><br><br>
+	<button onclick="fitWidth()">Fit Data Width</button> 
+	<button onclick="fitHeight()">Fit Data Height</button> 
+	<button onclick="fitBoth()">Fit Data Width & Height</button>
+	<button onclick="sizeDefault()">DefaultSize</button><br><br>
+	<div id="grid" dojoType="dojox.Grid" autoWidth="true" autoHeight="true" model="model" structure="structure" elasticView="2"></div>
+	
+	<p>Grid fits to a sized container by default:</p>
+	<div id="container">
+		<div id="grid1" dojoType="dojox.VirtualGrid" get="get" structure="structure" rowCount="10" elasticView="2"></div>
+	</div>
+
+	<p> Grid is essentially hidden (height of zero) when parent container is unsized 
+		(nothing, including the header, should be displayed):</p>
+	<div id="unsizedContainer">
+		<div id="grid2" dojoType="dojox.VirtualGrid" get="get" structure="structure" rowCount="10" elasticView="2"></div>
+	</div>
+
+	<p> Grid is autoHeight and autoWidth via markup</p>
+		<div id="grid3" dojoType="dojox.VirtualGrid" autoWidth="true" autoHeight="true" get="get" structure="structure" rowCount="100" elasticView="2"></div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_sizing_ResizeHandle.html b/dojox/grid/compat/tests/test_sizing_ResizeHandle.html
new file mode 100644
index 0000000..10cdb08
--- /dev/null
+++ b/dojox/grid/compat/tests/test_sizing_ResizeHandle.html
@@ -0,0 +1,113 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>dojox.Grid Sizing Example</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+		@import "../../_grid/tundraGrid.css";
+		@import "../../../layout/resources/ResizeHandle.css";
+
+		.heading {
+			font-weight: bold;
+			padding-bottom: 0.25em;
+		}
+		
+		#bar, #container {
+			width: 400px;
+			height: 200px;
+			border: 4px double #333; 
+		}
+				
+		#grid { 
+			border: 1px solid #333;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="isDebug:true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");
+		dojo.require("dojox.layout.ResizeHandle");
+	</script>
+	<script type="text/javascript">
+		data = [ 
+			[ "normal", false, "new", 'But are not followed by two hexadecimal', 29.91, 10, false ],
+			[ "important", false, "new", 'Because a % sign always indicates', 9.33, -5, false ],
+			[ "important", false, "read", 'Signs can be selectively', 19.34, 0, true ],
+			[ "note", false, "read", 'However the reserved characters', 15.63, 0, true ],
+			[ "normal", false, "replied", 'It is therefore necessary', 24.22, 5.50, true ],
+			[ "important", false, "replied", 'To problems of corruption by', 9.12, -3, true ],
+			[ "note", false, "replied", 'Which would simply be awkward in', 12.15, -4, false ]
+		];
+		model = new dojox.grid.data.table(null, data);
+		
+		// grid structure
+		// a grid view is a group of columns
+		// a special view providing selection feedback
+		var rowBar = {type: 'dojox.GridRowView', width: '20px'};
+		
+		// a view without scrollbars
+		var leftView = {
+			noscroll: false,
+			cells: [[
+				{name: 'Column 0'},
+				{name: 'Column 1'}
+		]]};
+		
+		var middleView = {
+			cells: [[
+				{name: 'Column 2'},
+				{name: 'Column 3'},
+				{name: 'Column 4'},
+				{name: 'Column 5'},
+				{name: 'Column 6'}
+		]]};
+		
+		// a grid structure is an array of views.
+		var structure = [ rowBar, leftView, middleView];
+		
+		// get can return data for each cell of the grid
+		function get(inRowIndex) {
+			return [this.index, inRowIndex].join(', ');
+		}
+
+		dojo.addOnLoad(function(){
+			var hand = new dojox.layout.ResizeHandle({
+				targetContainer: dojo.byId("bar"),
+				animateSizing: false,
+				onResize: function(e){
+					setTimeout(dojo.hitch(aGrid,"resize",e),25);
+				}
+			},"hand0");
+		});
+		
+	
+</script>
+</head>
+<body class="tundra">
+<div class="heading">dojox.Grid Sizing Test w/ the experimental dojox.layout.ResizeHandle</div>
+	
+	<p>While this test should work, dojox.layout.ResizeHandle is experimental.</p>
+	
+	<div id="bar" style="position:relative">
+		<div jsId="aGrid" id="grid" dojoType="dojox.Grid" model="model" structure="structure" elasticView="2"></div>
+		<div id="hand0"></div>
+	</div>
+	
+	<p>Grid fits to a sized container by default:</p>
+	<div id="container" style="position:relative">
+		<div jsId="theGrid" id="grid1" dojoType="dojox.VirtualGrid" get="get" structure="structure" rowCount="75" elasticView="2"></div>
+		<div id="hand1" dojoType="dojox.layout.ResizeHandle" targetId="container" onResize="setTimeout(dojo.hitch(theGrid,'update'),50)" animateSizing="false"></div>
+	</div>
+	
+	<p>I am here to take up</p>
+
+	<p>space</p>
+
+	<p>as much as needed.</p>
+		
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_styling.html b/dojox/grid/compat/tests/test_styling.html
new file mode 100644
index 0000000..b78904a
--- /dev/null
+++ b/dojox/grid/compat/tests/test_styling.html
@@ -0,0 +1,131 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>dojox.Grid Styling Test</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../_grid/Grid.css";
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+		}
+		.heading {
+			font-weight: bold;
+			padding-bottom: 0.25em;
+		}
+				
+		#grid { 
+			border: 1px solid #333;
+			width: 45em;
+			height: 30em;
+		}
+		
+		#grid .dojoxGrid-row {
+			border: none;
+		}
+		
+		#grid .dojoxGrid-row-table {
+			border-collapse: collapse;
+		}
+		
+		#grid .dojoxGrid-cell {
+			border: none;
+			padding: 10px;
+		}
+		
+		.selectedRow .dojoxGrid-cell {
+			background-color: #003366;
+			color: white;
+		}
+		
+		.specialRow .dojoxGrid-cell {
+			background-color: dimgray;
+		}
+		
+		.selectedRow.specialRow .dojoxGrid-cell {
+			text-decoration: line-through;
+			/* duplicate selection background-color so has precendence over specialRow background-color */
+			background-color: #003366;
+		}
+		
+		/* in the yellow column, assign specific decoration for special rows that are selected */
+		.selectedRow.specialRow .yellowColumnData {
+			text-decoration: line-through underline;
+		}
+		
+		.yellowColumn {
+			color: #006666;
+		}
+			
+		.overRow .dojoxGrid-cell {
+			text-decoration: underline;
+		}
+		
+		.greenColumn {
+			color: yellow;
+			background-color: #006666;
+			font-style: italic;
+		}	
+		.yellowColumnData {
+			background-color: yellow;
+			text-decoration: underline;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");
+	</script>
+	<script type="text/javascript" src="support/test_data.js"></script>
+	<script type="text/javascript">
+		// grid structure
+		// a grid view is a group of columns
+		
+		// a view without scrollbars
+		var leftView = {
+			noscroll: true,
+			cells: [[
+				{name: 'Column 0', width: 5, headerStyles: 'padding-bottom: 2px;', styles: 'border-bottom: 1px dashed #333; border-right: 1px dashed #333; padding: 6px;'},
+				{name: 'Column 1', width: 5, headerStyles: 'padding-bottom: 2px;', styles: 'text-align: right; border-bottom: 1px dashed #333; border-right: 1px dashed #333; padding: 6px;'}
+		]]};
+		
+		var middleView = {
+			cells: [[
+				{name: 'Column 2'},
+				{name: 'Column 3', headerStyles: 'background-image: none; background-color: #003333;', classes: 'greenColumn'},
+				{name: 'Column 4', cellClasses: 'yellowColumnData', classes: 'yellowColumn', styles: 'text-align: center;' },
+				{name: 'Column 5', headerStyles: 'background-image: none; background-color: #003333;', classes: 'greenColumn'},
+				{name: 'Column 6'},
+				{name: 'Column 7'}
+		]]};
+		
+		// a grid structure is an array of views.
+		var structure = [ leftView, middleView ];
+		
+		function onStyleRow(inRow) {
+			with (inRow) {
+				var i = index % 10;
+				var special = (i > 2 && i < 6);
+				if (odd)
+					customStyles += ' color: orange;';
+				if (selected)	
+					customClasses += ' selectedRow';
+				if (special)	
+					customClasses += ' specialRow';
+				if (over)	
+					customClasses += ' overRow';
+				if (!over && !selected)
+					dojox.Grid.prototype.onStyleRow.apply(this, arguments);
+			}	
+		}
+		
+		dojo.addOnLoad(function() {
+			window["grid"] = dijit.byId('grid');
+		});
+</script>
+</head>
+<body>
+<div class="heading">dojox.Grid Styling Example</div>
+<div id="grid" dojoType="dojox.Grid" onStyleRow="onStyleRow" model="model" structure="structure"></div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_subgrid.html b/dojox/grid/compat/tests/test_subgrid.html
new file mode 100644
index 0000000..601933f
--- /dev/null
+++ b/dojox/grid/compat/tests/test_subgrid.html
@@ -0,0 +1,179 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<title>dojox.Grid Subgrid Test</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+</meta>
+<style>
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../_grid/tundraGrid.css";
+		
+		body { font-size: 1.0em; }
+		#grid {
+			height: 400px;
+			border: 1px solid silver;
+		}
+		.text-oneline {
+			white-space: nowrap;
+			overflow: hidden;
+			text-overflow: ellipsis;
+		}
+		.text-scrolling {
+			height: 4em;
+			overflow: auto;
+		}
+		.text-scrolling {
+			width: 21.5em;
+		}
+	</style>
+	
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="isDebug:true, debugAtAllCosts: false, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");
+	</script>
+	<script type="text/javascript">
+		data = [ 
+			[ '3 stars', 'Averagia', 'Averagia', 8.99, 'An authentic experience defined by the intense layer of frothy, real facts. This combination package includes special T DISCS that work with your system to produce a perfectly serene experience. $8.99 per package. Please choose Regular (#NS1) or Decaffeinated (#NS4).' ],
+		 	[ '2 stars', 'Cheapy', 'Cheapy', 6.29, 'Power and subtlety intersect for an experience with real character. Imported from Europe just for you. 16 T DISCS per package. $6.29 per package. #NJ4.' ],
+		 	[ '4 stars', 'Luxuria', 'Luxuria', 6.49, 'A bold statement from the respected European brand Luxuria, topped with delicate zanthum. Imported exclusively for you. 18 T DISCS per package. $6.49 per package. #N42.</div>' ],
+		 	[ '5 stars', 'Ultimo', 'Ultimo', 4.59, "A rich sensation of delicious experience, brought to you by one of Europe's oldest brands. A pure indulgence. 8 T DISCS per package. $4.59 per package. #NJ0." ]
+		];		 
+
+		getDetailData = function(inRowIndex) {
+			var row = data[this.grid.dataRow % data.length];
+			switch (this.index) {
+				case 0:
+					return row[0]; //'<img src="images/sample/' + row[0] + '" width="109" height="75">';
+				case 1:
+					return (100000000 + this.grid.dataRow).toString().slice(1);
+				case 2:
+					return row[3];
+				case 3:
+					return row[1];
+				case 4:
+					return row[2];
+				case 5:
+					return row[4];
+				default: 
+					return row[this.index];
+			}
+		}		 
+		
+		getName = function(inRowIndex) {
+			var row = data[inRowIndex % data.length];
+			return row[2];
+		}		 
+		
+		// Main grid structure 
+		var gridCells = [
+			{ type: 'dojox.GridRowView', width: '20px' }, 
+			{ 
+				onBeforeRow: function(inDataIndex, inSubRows) {
+					inSubRows[1].hidden = !detailRows[inDataIndex];
+				},
+				cells: [[
+					{ name: '', width: 3, get: getCheck, styles: 'text-align: center;' }, { name: 'Name', get: getName, width: 40 }
+				], [
+					{ name: '', get: getDetail, colSpan: 2, styles: 'padding: 0; margin: 0;'}
+				]]
+			}
+		];
+		
+		// html for the +/- cell
+		function getCheck(inRowIndex) { 
+			var image = (detailRows[inRowIndex] ? 'open.gif' : 'closed.gif');
+			var show = (detailRows[inRowIndex] ? 'false' : 'true')
+			return '<img height="11" width="11" src="images/' + image + '" onclick="toggleDetail(' + inRowIndex + ', ' + show + ')">';
+		}
+		
+		// provide html for the Detail cell in the master grid		
+		function getDetail(inRowIndex) {
+			var cell = this;
+			// we can affect styles and content here, but we have to wait to access actual nodes
+			setTimeout(function() { buildSubgrid(inRowIndex, cell); }, 1);
+			// look for a subgrid
+			var subGrid = dijit.byId(makeSubgridId(inRowIndex));
+			var h = (subGrid ? subGrid.cacheHeight : "120") + "px";
+			// insert a placeholder
+			return '<div style="height: ' + h + '; background-color: white;"></div>';
+		}
+		
+		// the Detail cell contains a subgrid which we set up below
+		
+			var subGridCells = [{
+				noscroll: true,
+				cells: [
+					[{ name: "Rating", rowSpan: 2, width: 10, noresize: true, styles: 'text-align:center;' }, 
+							{ name: "Sku" }, 
+							{ name: "Price" }, 
+							{ name: "Vendor" }, 
+							{ name: "Name", width: "auto" }], 
+					[{ name: "Description", colSpan: 4 }]
+				]}];
+
+			var subGridProps = {
+				structure: subGridCells, 
+				rowCount: 1, 
+				autoHeight: true, 
+				autoRender: false,
+				"get": getDetailData
+			};
+	
+			// identify subgrids by their row indices
+			function makeSubgridId(inRowIndex) {
+				return grid.widgetId + "_subGrid_" + inRowIndex;
+			}
+	
+			// if a subgrid exists at inRowIndex, detach it from the DOM
+			function detachSubgrid(inRowIndex) {
+				var subGrid = dijit.byId(makeSubgridId(inRowIndex));
+				if (subGrid)
+					dojox.grid.removeNode(subGrid.domNode);
+			}
+			
+			// render a subgrid into inCell at inRowIndex
+			function buildSubgrid(inRowIndex, inCell) {
+				var n = inCell.getNode(inRowIndex).firstChild;
+				var id = makeSubgridId(inRowIndex);
+				var subGrid = dijit.byId(id);
+				if (subGrid) {
+					n.appendChild(subGrid.domNode);
+				} else {
+					subGridProps.dataRow = inRowIndex;
+					subGridProps.widgetId = id;
+					subGrid = new dojox.VirtualGrid(subGridProps, n);
+				}
+				if (subGrid) {
+					subGrid.render();
+					subGrid.cacheHeight = subGrid.domNode.offsetHeight;
+					inCell.grid.rowHeightChanged(inRowIndex);
+				}	
+			}
+					
+			// destroy subgrid at inRowIndex
+			function destroySubgrid(inRowIndex) {
+				var subGrid = dijit.byId(makeSubgridId(inRowIndex));
+				if (subGrid) subGrid.destroy();
+			}
+		
+		// when user clicks the +/-
+		detailRows = [];
+		function toggleDetail(inIndex, inShow) {
+			if (!inShow) detachSubgrid(inIndex);
+			detailRows[inIndex] = inShow;
+			grid.updateRow(inIndex);
+		}
+		
+		dojo.addOnLoad(function() {
+			window["grid"] = dijit.byId("grid");
+			dojo.connect(grid, 'rowRemoved', destroySubgrid);
+		});
+	</script>
+</head>
+<body class="tundra">
+	<div style="font-weight: bold; padding-bottom: 0.25em;">dojox.Grid showing sub-grid.</div>
+	<div id="grid" dojoType="dojox.VirtualGrid" structure="gridCells" rowCount="100000" autoWidth="true"></div>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_tundra_edit.html b/dojox/grid/compat/tests/test_tundra_edit.html
new file mode 100644
index 0000000..f7fb39c
--- /dev/null
+++ b/dojox/grid/compat/tests/test_tundra_edit.html
@@ -0,0 +1,139 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+	<head>
+		<title>Test dojox.Grid Editing</title>
+		<style>
+			@import "../../_grid/tundraGrid.css";
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/themes/tundra/tundra.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+
+			.dojoxGrid-row-editing td {
+				background-color: #F4FFF4;
+			}
+			.dojoxGrid input, .dojoxGrid select, .dojoxGrid textarea {
+				margin: 0;
+				padding: 0;
+				border-style: none;
+				width: 100%;
+				font-size: 100%;
+				font-family: inherit;
+			}
+			.dojoxGrid input {
+			}
+			.dojoxGrid select {
+			}
+			.dojoxGrid textarea {
+			}
+
+			#controls {
+				padding: 6px 0;
+			}
+			#controls button {
+				margin-left: 10px;
+			}
+			.myGrid {
+				width: 850px;
+				height: 350px;
+				border: 1px solid silver;
+			}
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js"
+			djConfig="isDebug:false, parseOnLoad: true"></script>
+		<script type="text/javascript">
+			dojo.require("dojox.grid.Grid");
+			dojo.require("dojo.parser");
+		</script>
+		<script type="text/javascript">
+			// ==========================================================================
+			// Create a data model
+			// ==========================================================================
+			data = [ 
+				[ "normal", false, "new", 'But are not followed by two hexadecimal', 29.91, 10, false ],
+				[ "important", false, "new", 'Because a % sign always indicates', 9.33, -5, false ],
+				[ "important", false, "read", 'Signs can be selectively', 19.34, 0, true ],
+				[ "note", false, "read", 'However the reserved characters', 15.63, 0, true ],
+				[ "normal", false, "replied", 'It is therefore necessary', 24.22, 5.50, true ],
+				[ "important", false, "replied", 'To problems of corruption by', 9.12, -3, true ],
+				[ "note", false, "replied", 'Which would simply be awkward in', 12.15, -4, false ]
+			];
+			var rows = 10000;
+			for(var i=0, l=data.length; i<rows-l; i++){
+				data.push(data[i%l].slice(0));
+			}
+			model = new dojox.grid.data.Table(null, data);
+
+			// ==========================================================================
+			// Tie some UI to the data model
+			// ==========================================================================
+			model.observer(this);
+			modelChange = function(){
+				dojo.byId("rowCount").innerHTML = 'Row count: ' + model.count; 
+			}
+
+			// ==========================================================================
+			// Custom formatter
+			// ==========================================================================
+			formatMoney = function(inDatum){
+				return isNaN(inDatum) ? '...' : '$' + parseFloat(inDatum).toFixed(2);
+			}
+
+			// ==========================================================================
+			// Grid structure
+			// ==========================================================================
+			statusCell = { 
+				field: 2,
+				name: 'Status',
+				styles: 'text-align: center;',
+				editor: dojox.grid.editors.Select,
+				options: [ "new", "read", "replied" ]
+			};
+
+			gridLayout = [
+				{
+					type: 'dojox.GridRowView', width: '20px'
+				},
+				{
+					defaultCell: { width: 8, editor: dojox.grid.editors.Input, styles: 'text-align: right;'  },
+					rows: [
+						[
+							{ name: 'Id', width: 3, get: function(inRowIndex){ return inRowIndex+1;} },
+							{ name: 'Priority', styles: 'text-align: center;', editor: dojox.grid.editors.Select, options: ["normal", "note", "important"]},
+							{ name: 'Mark', width: 3, styles: 'text-align: center;', editor: dojox.grid.editors.Bool },
+							statusCell,
+							{ name: 'Message', styles: '', width: '100%' },
+							{ name: 'Amount', formatter: formatMoney }
+						]
+					]
+				}
+			];
+			// ==========================================================================
+			// UI Action
+			// ==========================================================================
+			addRow = function() {
+				grid.addRow([ "normal", false, "new", 'Now is the time for all good men to come to the aid of their party.', 99.99, 9.99, false ]);
+			}
+		</script>
+	</head>
+	<body class="tundra">
+	<h1>dojox.Grid Basic Editing test</h1>
+	<br />
+	<div id="controls">
+		<button onclick="grid.refresh()">Refresh</button>
+		<button onclick="grid.edit.focusEditor()">Focus Editor</button>
+		<button onclick="grid.focus.next()">Next Focus</button>
+		<button onclick="addRow()">Add Row</button>
+		<button onclick="grid.removeSelectedRows()">Remove</button>
+		<button onclick="grid.edit.apply()">Apply</button>
+		<button onclick="grid.edit.cancel()">Cancel</button>
+		<button onclick="grid.singleClickEdit = !grid.singleClickEdit">Toggle singleClickEdit</button>
+	</div>
+	<br />
+	<div jsId="grid" class="myGrid" 
+		dojoType="dojox.Grid" model="model" 
+		structure="gridLayout"></div>
+	<br />
+	<div id="rowCount"></div>
+	</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_yahoo_images.html b/dojox/grid/compat/tests/test_yahoo_images.html
new file mode 100644
index 0000000..fc91ff2
--- /dev/null
+++ b/dojox/grid/compat/tests/test_yahoo_images.html
@@ -0,0 +1,148 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>dojox.Grid - Image Search Test</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style>
+		@import "../../_grid/Grid.css";
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+		}
+		.grid {
+			height: 30em;
+			width: 51em;
+			border: 1px solid silver;
+		}
+		#info { width: 700px; }
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="debugAtAllCosts: false, isDebug:false, parseOnLoad: true">
+	</script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");
+	</script>
+	<script type="text/javascript" src="yahooSearch.js"></script>	
+	<script type="text/javascript">
+		// model fields
+		imageFields = [
+			{ name: 'Title', na: '' }, 
+			{ name: 'Thumbnail', na: ''},
+			{ name: 'Summary', na: '' },
+			{ name: 'Url', na: '' },
+			{ name: 'FileSize', na: ''},
+			{ name: 'Height', na: ''},
+			{ name: 'Width', na: ''}
+		];
+		// create data model
+		var model = new dojox.grid.data.yahooSearch(imageFields, null, "searchInput");
+		model.url = 'http://search.yahooapis.com/ImageSearchService/V1/imageSearch';
+		model.observer(this);
+		
+		// report some model send/receive status
+		model.onSend = function(inParams){
+			dojo.byId('sendInfo').innerHTML = dojo.string.substitute(
+				'Request rows ${0} to ${1}.&nbsp ',
+				[inParams.start, inParams.start + inParams.results -1]
+			);
+		}
+		model.onReceive = function(inData) {
+			dojo.byId('receiveInfo').innerHTML = dojo.string.substitute(
+				'Receive rows ${0} to ${1}.&nbsp ', 
+				[
+					inData.firstResultPosition, 
+					inData.firstResultPosition + inData.totalResultsReturned-1
+				]
+			);
+		}
+
+
+		// Define grid structure
+		// remove the height from the header image cell / row cells have a default height so there's less adjustment when thumb comes in.
+		beforeImageRow = function(inRowIndex, inSubRows){
+			inSubRows[0].hidden = (inRowIndex == -1);
+		}
+		
+		var imageLayout = [ 
+			{ onBeforeRow: beforeImageRow,
+				cells: [
+					[	{ name: 'Image', cellStyles: "height: 100px;", styles: "text-align: center;", width: 12, field: 3, extraField: 1, formatter: formatImage },
+						{ name: 'Image', cellStyles: "height: 100px;", styles: "text-align: center;", width: 12, field: 3, extraField: 1, formatter: formatImage },
+						{ name: 'Image', cellStyles: "height: 100px;", styles: "text-align: center;", width: 12, field: 3, extraField: 1, formatter: formatImage },
+						{ name: 'Image', cellStyles: "height: 100px;", styles: "text-align: center;", width: 12, field: 3, extraField: 1, formatter: formatImage }
+					]
+			]}
+		];
+		
+		// Create grid subclass to function as we need to display images only.
+		// adds indirection between model row and grid row.
+		dojo.declare("dojox.ImageGrid", dojox.Grid, {
+			postCreate: function() {
+				this.inherited(arguments);
+				this.modelDatumChange = this.modelRowChange;
+				this.colCount = this.layout.cells.length;
+			},
+			getDataRowIndex: function(inCell, inRowIndex) {
+				var r = inCell.index + Math.floor(inRowIndex * this.colCount);
+				return r;
+			},
+			// called in cell context
+			get: function(inRowIndex) {
+				var r = this.grid.getDataRowIndex(this, inRowIndex);
+				return dojox.Grid.prototype.get.call(this, r);
+			},
+			modelAllChange: function(){
+				this.rowCount = Math.ceil(this.model.getRowCount() / this.colCount);
+				this.updateRowCount(this.rowCount);
+			},
+			modelRowChange: function(inData, inRowIndex) {
+				if(
+					(inRowIndex % this.colCount == this.colCount - 1)||
+					(inRowIndex == this.model.count - 1)
+				){
+					this.updateRow(Math.floor(inRowIndex / this.colCount));
+				}
+			}
+		});
+		
+		getCellData = function(inCell, inRowIndex, inField) {
+			var m = inCell.grid.model, r = inCell.grid.getDataRowIndex(inCell, inRowIndex);
+			return m.getDatum(r, inField);
+		}
+		
+		// execute search
+		doSearch = function(){
+			model.clearData();
+			model.setRowCount(0);
+			grid.render();
+			grid.resize();
+			model.requestRows();
+		}
+		
+		dojo.addOnLoad(function(){
+			dojo.query("#searchInput").onkeypress(function(e){
+				if(e.keyCode == dojo.keys.ENTER){ doSearch(); }
+			});
+			doSearch();
+		});
+		
+	</script>
+</head>
+<body>
+	<div style="font-weight: bold; padding-bottom: 0.25em;">dojox.Grid - Image Search Test</div>
+	<input id="searchInput" type="text" value="apple">
+	<button onclick="doSearch()" style="clear: both;">Search</button>
+	<div jsId="grid" class="grid" structure="imageLayout" dojoType="dojox.ImageGrid" model="model"></div>
+	<br>
+	<div id="info">
+		<div id="rowCount" style="float: left"></div>
+		<div style="float: right">
+			<div id="sendInfo" style="text-align: right"></div>
+			<div id="receiveInfo" style="text-align: right"></div>
+		</div>
+	</div>
+	<br /><br />
+	<p>Note: requires PHP for proxy.</p>
+	</body>
+</html>
diff --git a/dojox/grid/compat/tests/test_yahoo_search.html b/dojox/grid/compat/tests/test_yahoo_search.html
new file mode 100644
index 0000000..502a1ca
--- /dev/null
+++ b/dojox/grid/compat/tests/test_yahoo_search.html
@@ -0,0 +1,141 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>dojox.Grid - Yahoo Search Test</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style>
+		@import "../../_grid/Grid.css";
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+		}
+		.grid {
+			height: 30em;
+		}
+		
+		#info {
+			width: 700px;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.Grid");
+		dojo.require("dojo.parser");
+	</script>
+	<script type="text/javascript" src="yahooSearch.js"></script>
+	<script type="text/javascript">
+		webFields = [
+			{ name: 'Title', na: '' }, 
+			{ name: 'ModificationDate', na: ''},
+			{ name: 'Summary', na: ' ' },
+			{ name: 'Url', na: '' },
+			{ name: 'MimeType', na: ' '},
+			{ name: 'DisplayUrl', na: ' '}
+		];
+		
+		imageFields = [		
+			{ name: 'Title', na: '' }, 
+			{ name: 'Thumbnail', na: ''},
+			{ name: 'Summary', na: '' },
+			{ name: 'Url', na: '' },
+			{ name: 'FileSize', na: ''},
+			{ name: 'Height', na: ''},
+			{ name: 'Width', na: ''}
+		];
+
+		var model = new dojox.grid.data.yahooSearch(imageFields, null, "searchInput");
+		model.observer(this);
+		// report some model send/receive status
+		model.onSend = function(inParams) {
+			dojo.byId('sendInfo').innerHTML = dojo.string.substitute('Request rows ${0} to ${1}.&nbsp ', [inParams.start, inParams.start + inParams.results -1] );
+		}
+		model.onReceive = function(inData) {
+			dojo.byId('receiveInfo').innerHTML = dojo.string.substitute('Receive rows ${0} to ${1}.&nbsp ', [inData.firstResultPosition, inData.firstResultPosition + inData.totalResultsReturned-1]);
+		}
+
+		
+		var webLayout = [ 
+			{ type: 'dojox.GridRowView', width: '20px' },
+			{ noscroll: true,
+				cells: [
+					[ { name: 'Row', width: 3, styles: 'text-align: center;', get: function(inRowIndex) { return inRowIndex + 1 } }]
+				]
+			},
+			{ cells: [
+					[	{ name: 'Site', width: 30, field: 3, extraField: 0, formatter: formatLink }, { name: 'Date', width: 10, field: 1, formatter: formatDate} ],
+					[	{ name: 'Display Url', width: 30, field: 5, styles: 'color: green; size: small;' }, { name: 'Type', width: 10, field: 4, styles: ' font-style: italic; color: gray; size: small;'} ],
+					[ { name: 'Summary',  width: 40, colSpan: 2, field: 2 } ]
+			]}
+		];
+		
+		// remove the height from the header image cell / row cells have a default height so there's less adjustment when thumb comes in.
+		beforeImageRow = function(inRowIndex, inSubRow) {
+			inSubRow[0][0].cellStyles = (inRowIndex == -1 ? '' : 'height: 100px;');
+			inSubRow[1][0].cellStyles = (inRowIndex == -1 ? '' : 'vertical-align: top; height: 75px;');
+		}
+		
+		var imageLayout = [ 
+			{ type: 'dojox.GridRowView', width: '20px' },
+			{ noscroll: true,
+				cells: [
+					[ { name: 'Row', width: 3, styles: 'text-align: center;', get: function(inRowIndex) { return inRowIndex + 1 } }]
+				]
+			},
+			{ onBeforeRow: beforeImageRow,
+				cells: [
+					[	{ name: 'Image', cellStyles: "height: 100px;", styles: "text-align: center;", width: 13, rowSpan: 2, field: 3, extraField: 1, formatter: formatImage },
+						{ name: 'Title', cellStyles: "height: 10px;", width: 14, field: 3, extraField: 0, formatter: formatLink }, 
+						{ name: 'Size', width: 8, field: 4, styles: "font-style: italic; text-align: center;" },
+						{ name: 'Dimensions', width: 8, field: 6, extraField: 5, styles: "text-align: center;", formatter: formatDimensions }
+					],
+					[ { name: 'Summary',  cellStyles: "vertical-align: top; height: 75px;", colSpan: 3, field: 2 } ]
+			]}
+		];
+		
+		// execute search
+		doSearch = function() {
+			var web = dojo.byId('webRb').checked;
+			model.setRowCount(0);
+			model.clear();
+			model.fields.set(web ? webFields : imageFields);
+			model.url = 'http://search.yahooapis.com/' + (web ? 'WebSearchService/V1/webSearch' : 'ImageSearchService/V1/imageSearch');
+			grid.scrollToRow(0);
+			grid.setStructure(web ? webLayout : imageLayout);
+			model.requestRows();
+		}
+		
+		// do search on enter...
+		keypress = function(e) {
+			if (e.keyCode == dojo.keys.ENTER)
+				doSearch();
+		}
+
+		dojo.addOnLoad(function() {
+			dojo.byId('webRb').checked = "checked";
+			dojo.connect(dojo.byId("searchInput"), "keypress", keypress);
+			doSearch();
+		});
+
+	</script>
+</head>
+<body>
+<div style="font-weight: bold; padding-bottom: 0.25em;">dojox.Grid - Yahoo Search Test</div>
+<div style="padding-bottom: 3px;">
+	<label><input id="webRb" type="radio" name="searchType" checked>Web</label>  
+	<label><input id="imageRb" type="radio" name="searchType">Images</label>
+</div>	
+<input id="searchInput" type="text" value="apple">  
+<button onclick="doSearch()">Search</button><br><br>
+<div jsId="grid" class="grid" autoWidth="true" structure="webLayout" dojoType="dojox.Grid" model="model" elasticView="1"></div>
+<br>
+<div id="info">
+	<div id="rowCount" style="float: left"></div>
+	<div style="float: right">
+		<div id="sendInfo" style="text-align: right"></div>
+		<div id="receiveInfo" style="text-align: right"></div>
+	</div>
+</div>
+<br /><br />
+<p>Note: requires PHP for proxy.</p>
+</body>
+</html>
diff --git a/dojox/grid/compat/tests/yahooSearch.js b/dojox/grid/compat/tests/yahooSearch.js
new file mode 100644
index 0000000..1d57a8e
--- /dev/null
+++ b/dojox/grid/compat/tests/yahooSearch.js
@@ -0,0 +1,137 @@
+dojo.require("dojo.io.script")
+dojo.require("dojox.rpc.Service");
+
+// model that works with Yahoo Search API
+dojo.declare("dojox.grid.data.yahooSearch", dojox.grid.data.Dynamic, {
+	constructor: function(inFields, inData, inSearchNode){
+		this.rowsPerPage = 20;
+		this.searchNode = inSearchNode;
+		this.fieldNames = dojo.map(inFields, "return item.name;");
+		this.yahoo = new dojox.rpc.Service(
+			dojo.moduleUrl("dojox.rpc.SMDLibrary", "yahoo.smd")
+		);
+	},
+	// server send / receive
+	send: function(inAsync, inParams, inOnReceive, inOnError){
+		var d = this.yahoo.imageSearch(
+			dojo.mixin({ 
+				results: this.rowsPerPage,
+				query: this.getQuery()
+			}, inParams)
+		);
+		d.addCallbacks(
+			dojo.hitch(this, "receive", inOnReceive, inOnError), 
+			dojo.hitch(this, "error", inOnError)
+		);
+		this.onSend(inParams);
+		return d;
+	},
+	receive: function(inOnReceive, inOnError, inData){
+		try{
+			inData = inData.ResultSet;
+			inOnReceive(inData);
+			this.onReceive(inData);
+		}catch(e){
+			if(inOnError){
+				inOnError(inData);
+			}
+		}
+	},
+	error: function(inOnError, inErr) {
+		var m = 'io error: ' + inErr.message;
+		alert(m);
+		if (inOnError)
+			inOnError(m);
+	},
+	encodeParam: function(inName, inValue) {
+		return dojo.string.substitute('&${0}=${1}', [inName, inValue]);
+	},
+	getQuery: function(){
+		return dojo.byId(this.searchNode).value.replace(/ /g, '+');
+	},
+	fetchRowCount: function(inCallback){
+		this.send(true, inCallback);
+	},
+	// request data 
+	requestRows: function(inRowIndex, inCount){
+		inRowIndex = (inRowIndex == undefined ? 0 : inRowIndex);
+		var params = { 
+			start: inRowIndex + 1
+		}
+		this.send(true, params, dojo.hitch(this, this.processRows));
+	},
+	// server callbacks
+	processRows: function(inData){
+		for(var i=0, l=inData.totalResultsReturned, s=inData.firstResultPosition; i<l; i++){
+			this.setRow(inData.Result[i], s - 1 + i);
+		}
+		// yahoo says 1000 is max results to return
+		var c = Math.min(1000, inData.totalResultsAvailable);
+		if(this.count != c){
+			this.setRowCount(c);
+			this.allChange();
+			this.onInitializeData(inData);
+		}
+	},
+	getDatum: function(inRowIndex, inColIndex){
+		var row = this.getRow(inRowIndex);
+		var field = this.fields.get(inColIndex);
+		return (inColIndex == undefined ? row : (row ? row[field.name] : field.na));
+	},
+	// events
+	onInitializeData: function(){ },
+	onSend: function(){ },
+	onReceive: function(){ }
+});
+
+// report
+modelChange = function(){
+	var n = dojo.byId('rowCount');
+	if(n){
+		n.innerHTML = dojo.string.substitute('about ${0} row(s)', [model.count]);
+	}
+}
+
+
+// some data formatters
+getCellData = function(inCell, inRowIndex, inField){
+	var m = inCell.grid.model;
+	return m.getDatum(inRowIndex, inField);
+}
+
+formatLink = function(inData, inRowIndex){
+	if(!inData){ return ' '; }
+	var text = getCellData(this, inRowIndex, this.extraField);
+	return dojo.string.substitute(
+		'<a target="_blank" href="${href}">${text}</a>', 
+		{ href: inData, text: text }
+	);
+};
+
+formatImage = function(inData, inRowIndex){
+	if(!inData){ return ' '; }
+	var info = getCellData(this, inRowIndex, this.extraField);
+	var o = {
+		href: inData, 
+		src: info.Url,
+		width: info.Width,
+		height: info.Height
+	}
+	return dojo.string.substitute(
+		'<a href="${href}" target="_blank"><img border=0 src="${src}" width="${width}" height="${height}"></a>', o);
+};
+
+formatDate = function(inDatum, inRowIndex){
+	if(!inDatum){ return ' '; }
+	var d = new Date(inDatum * 1000);
+	return dojo.string.substitute(
+		"${0}/${1}/${2}",
+		[ d.getMonth()+1, d.getDate(), d.getFullYear() ]
+	);
+};
+
+formatDimensions = function(inData, inRowIndex){
+	if(!inData){ return ' '; }
+	var w = inData, h = getCellData(this, inRowIndex, this.extraField);
+	return w + ' x ' + h;
+}
diff --git a/dojox/grid/nls/DataGrid_ROOT.js b/dojox/grid/nls/DataGrid_ROOT.js
new file mode 100644
index 0000000..a95f772
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_ROOT.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ROOT");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ROOT");dijit.nls.loading.ROOT={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
diff --git a/dojox/grid/nls/DataGrid_ar.js b/dojox/grid/nls/DataGrid_ar.js
new file mode 100644
index 0000000..6ac1ce7
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_ar.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ar");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ar");dijit.nls.loading.ar={"loadingState":"جاري التحميل...","errorState":"عفوا، حدث خطأ"};
diff --git a/dojox/grid/nls/DataGrid_ca.js b/dojox/grid/nls/DataGrid_ca.js
new file mode 100644
index 0000000..4772c8c
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_ca.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ca");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ca");dijit.nls.loading.ca={"loadingState":"S'està carregant...","errorState":"Ens sap greu. S'ha produït un error."};
diff --git a/dojox/grid/nls/DataGrid_cs.js b/dojox/grid/nls/DataGrid_cs.js
new file mode 100644
index 0000000..1f896c1
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_cs.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_cs");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.cs");dijit.nls.loading.cs={"loadingState":"Probíhá načítání...","errorState":"Omlouváme se, došlo k chybě"};
diff --git a/dojox/grid/nls/DataGrid_da.js b/dojox/grid/nls/DataGrid_da.js
new file mode 100644
index 0000000..cd0891e
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_da.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_da");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.da");dijit.nls.loading.da={"loadingState":"Indlæser...","errorState":"Der er opstået en fejl"};
diff --git a/dojox/grid/nls/DataGrid_de-de.js b/dojox/grid/nls/DataGrid_de-de.js
new file mode 100644
index 0000000..091508c
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_de-de.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_de-de");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.de_de");dijit.nls.loading.de_de={"loadingState":"Wird geladen...","errorState":"Es ist ein Fehler aufgetreten."};
diff --git a/dojox/grid/nls/DataGrid_de.js b/dojox/grid/nls/DataGrid_de.js
new file mode 100644
index 0000000..8c376f9
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_de.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_de");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.de");dijit.nls.loading.de={"loadingState":"Wird geladen...","errorState":"Es ist ein Fehler aufgetreten."};
diff --git a/dojox/grid/nls/DataGrid_el.js b/dojox/grid/nls/DataGrid_el.js
new file mode 100644
index 0000000..f52ad5a
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_el.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_el");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.el");dijit.nls.loading.el={"loadingState":"Φόρτωση...","errorState":"Σας ζητούμε συγνώμη, παρουσιάστηκε σφάλμα"};
diff --git a/dojox/grid/nls/DataGrid_en-gb.js b/dojox/grid/nls/DataGrid_en-gb.js
new file mode 100644
index 0000000..979fa29
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_en-gb.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_en-gb");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.en_gb");dijit.nls.loading.en_gb={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
diff --git a/dojox/grid/nls/DataGrid_en-us.js b/dojox/grid/nls/DataGrid_en-us.js
new file mode 100644
index 0000000..a18e498
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_en-us.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_en-us");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.en_us");dijit.nls.loading.en_us={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
diff --git a/dojox/grid/nls/DataGrid_en.js b/dojox/grid/nls/DataGrid_en.js
new file mode 100644
index 0000000..2d189ff
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_en.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_en");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.en");dijit.nls.loading.en={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
diff --git a/dojox/grid/nls/DataGrid_es-es.js b/dojox/grid/nls/DataGrid_es-es.js
new file mode 100644
index 0000000..4d7081a
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_es-es.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_es-es");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.es_es");dijit.nls.loading.es_es={"loadingState":"Cargando...","errorState":"Lo siento, se ha producido un error"};
diff --git a/dojox/grid/nls/DataGrid_es.js b/dojox/grid/nls/DataGrid_es.js
new file mode 100644
index 0000000..de8a105
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_es.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_es");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.es");dijit.nls.loading.es={"loadingState":"Cargando...","errorState":"Lo siento, se ha producido un error"};
diff --git a/dojox/grid/nls/DataGrid_fi-fi.js b/dojox/grid/nls/DataGrid_fi-fi.js
new file mode 100644
index 0000000..5300b36
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_fi-fi.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_fi-fi");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fi_fi");dijit.nls.loading.fi_fi={"loadingState":"Lataus on meneillään...","errorState":"On ilmennyt virhe."};
diff --git a/dojox/grid/nls/DataGrid_fi.js b/dojox/grid/nls/DataGrid_fi.js
new file mode 100644
index 0000000..04f4d1a
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_fi.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_fi");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fi");dijit.nls.loading.fi={"loadingState":"Lataus on meneillään...","errorState":"On ilmennyt virhe."};
diff --git a/dojox/grid/nls/DataGrid_fr-fr.js b/dojox/grid/nls/DataGrid_fr-fr.js
new file mode 100644
index 0000000..9d007ff
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_fr-fr.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_fr-fr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fr_fr");dijit.nls.loading.fr_fr={"loadingState":"Chargement...","errorState":"Une erreur est survenue"};
diff --git a/dojox/grid/nls/DataGrid_fr.js b/dojox/grid/nls/DataGrid_fr.js
new file mode 100644
index 0000000..db846cc
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_fr.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_fr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.fr");dijit.nls.loading.fr={"loadingState":"Chargement...","errorState":"Une erreur est survenue"};
diff --git a/dojox/grid/nls/DataGrid_he-il.js b/dojox/grid/nls/DataGrid_he-il.js
new file mode 100644
index 0000000..cd3b2d5
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_he-il.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_he-il");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.he_il");dijit.nls.loading.he_il={"loadingState":"טעינה...‏","errorState":"אירעה שגיאה"};
diff --git a/dojox/grid/nls/DataGrid_he.js b/dojox/grid/nls/DataGrid_he.js
new file mode 100644
index 0000000..dae1263
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_he.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_he");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.he");dijit.nls.loading.he={"loadingState":"טעינה...‏","errorState":"אירעה שגיאה"};
diff --git a/dojox/grid/nls/DataGrid_hu.js b/dojox/grid/nls/DataGrid_hu.js
new file mode 100644
index 0000000..1d797c2
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_hu.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_hu");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.hu");dijit.nls.loading.hu={"loadingState":"Betöltés...","errorState":"Sajnálom, hiba történt"};
diff --git a/dojox/grid/nls/DataGrid_it-it.js b/dojox/grid/nls/DataGrid_it-it.js
new file mode 100644
index 0000000..79a0800
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_it-it.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_it-it");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.it_it");dijit.nls.loading.it_it={"loadingState":"Caricamento in corso...","errorState":"Si è verificato un errore"};
diff --git a/dojox/grid/nls/DataGrid_it.js b/dojox/grid/nls/DataGrid_it.js
new file mode 100644
index 0000000..dbe95e8
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_it.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_it");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.it");dijit.nls.loading.it={"loadingState":"Caricamento in corso...","errorState":"Si è verificato un errore"};
diff --git a/dojox/grid/nls/DataGrid_ja-jp.js b/dojox/grid/nls/DataGrid_ja-jp.js
new file mode 100644
index 0000000..f74a69a
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_ja-jp.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ja-jp");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ja_jp");dijit.nls.loading.ja_jp={"loadingState":"ロード中...","errorState":"エラーが発生しました。"};
diff --git a/dojox/grid/nls/DataGrid_ja.js b/dojox/grid/nls/DataGrid_ja.js
new file mode 100644
index 0000000..db1f3ae
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_ja.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ja");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ja");dijit.nls.loading.ja={"loadingState":"ロード中...","errorState":"エラーが発生しました。"};
diff --git a/dojox/grid/nls/DataGrid_ko-kr.js b/dojox/grid/nls/DataGrid_ko-kr.js
new file mode 100644
index 0000000..81e6a54
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_ko-kr.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ko-kr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ko_kr");dijit.nls.loading.ko_kr={"loadingState":"로드 중...","errorState":"죄송합니다. 오류가 발생했습니다."};
diff --git a/dojox/grid/nls/DataGrid_ko.js b/dojox/grid/nls/DataGrid_ko.js
new file mode 100644
index 0000000..5012b35
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_ko.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ko");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ko");dijit.nls.loading.ko={"loadingState":"로드 중...","errorState":"죄송합니다. 오류가 발생했습니다."};
diff --git a/dojox/grid/nls/DataGrid_nl-nl.js b/dojox/grid/nls/DataGrid_nl-nl.js
new file mode 100644
index 0000000..9813f74
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_nl-nl.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_nl-nl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.nl_nl");dijit.nls.loading.nl_nl={"loadingState":"Bezig met laden...","errorState":"Er is een fout opgetreden"};
diff --git a/dojox/grid/nls/DataGrid_nl.js b/dojox/grid/nls/DataGrid_nl.js
new file mode 100644
index 0000000..dadd520
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_nl.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_nl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.nl");dijit.nls.loading.nl={"loadingState":"Bezig met laden...","errorState":"Er is een fout opgetreden"};
diff --git a/dojox/grid/nls/DataGrid_no.js b/dojox/grid/nls/DataGrid_no.js
new file mode 100644
index 0000000..ff42bdc
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_no.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_no");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.no");dijit.nls.loading.no={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
diff --git a/dojox/grid/nls/DataGrid_pl.js b/dojox/grid/nls/DataGrid_pl.js
new file mode 100644
index 0000000..1383697
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_pl.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_pl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pl");dijit.nls.loading.pl={"loadingState":"Ładowanie...","errorState":"Niestety, wystąpił błąd"};
diff --git a/dojox/grid/nls/DataGrid_pt-br.js b/dojox/grid/nls/DataGrid_pt-br.js
new file mode 100644
index 0000000..4548bb7
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_pt-br.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_pt-br");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pt_br");dijit.nls.loading.pt_br={"loadingState":"Carregando...","errorState":"Desculpe, ocorreu um erro"};
diff --git a/dojox/grid/nls/DataGrid_pt-pt.js b/dojox/grid/nls/DataGrid_pt-pt.js
new file mode 100644
index 0000000..a713464
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_pt-pt.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_pt-pt");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pt_pt");dijit.nls.loading.pt_pt={"loadingState":"A carregar...","errorState":"Lamentamos, mas ocorreu um erro"};
diff --git a/dojox/grid/nls/DataGrid_pt.js b/dojox/grid/nls/DataGrid_pt.js
new file mode 100644
index 0000000..3ba7a88
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_pt.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_pt");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.pt");dijit.nls.loading.pt={"loadingState":"Carregando...","errorState":"Desculpe, ocorreu um erro"};
diff --git a/dojox/grid/nls/DataGrid_ru.js b/dojox/grid/nls/DataGrid_ru.js
new file mode 100644
index 0000000..22e6000
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_ru.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_ru");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.ru");dijit.nls.loading.ru={"loadingState":"Загрузка...","errorState":"Извините, возникла ошибка"};
diff --git a/dojox/grid/nls/DataGrid_sk.js b/dojox/grid/nls/DataGrid_sk.js
new file mode 100644
index 0000000..1df6472
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_sk.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_sk");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.sk");dijit.nls.loading.sk={"loadingState":"Zavádzanie...","errorState":"Nastala chyba"};
diff --git a/dojox/grid/nls/DataGrid_sl.js b/dojox/grid/nls/DataGrid_sl.js
new file mode 100644
index 0000000..4bd6a1f
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_sl.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_sl");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.sl");dijit.nls.loading.sl={"loadingState":"Nalaganje...","errorState":"Oprostite, prišlo je do napake."};
diff --git a/dojox/grid/nls/DataGrid_sv.js b/dojox/grid/nls/DataGrid_sv.js
new file mode 100644
index 0000000..bbd3927
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_sv.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_sv");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.sv");dijit.nls.loading.sv={"loadingState":"Läser in...","errorState":"Det uppstod ett fel."};
diff --git a/dojox/grid/nls/DataGrid_th.js b/dojox/grid/nls/DataGrid_th.js
new file mode 100644
index 0000000..5bf0e6e
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_th.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_th");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.th");dijit.nls.loading.th={"loadingState":"กำลังโหลด...","errorState":"ขออภัย เกิดข้อผิดพลาด"};
diff --git a/dojox/grid/nls/DataGrid_tr.js b/dojox/grid/nls/DataGrid_tr.js
new file mode 100644
index 0000000..daaccd6
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_tr.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_tr");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.tr");dijit.nls.loading.tr={"loadingState":"Yükleniyor...","errorState":"Üzgünüz, bir hata oluştu"};
diff --git a/dojox/grid/nls/DataGrid_xx.js b/dojox/grid/nls/DataGrid_xx.js
new file mode 100644
index 0000000..2b58b5c
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_xx.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_xx");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.xx");dijit.nls.loading.xx={"loadingState":"Loading...","errorState":"Sorry, an error occurred"};
diff --git a/dojox/grid/nls/DataGrid_zh-cn.js b/dojox/grid/nls/DataGrid_zh-cn.js
new file mode 100644
index 0000000..e862be9
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_zh-cn.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_zh-cn");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.zh_cn");dijit.nls.loading.zh_cn={"loadingState":"正在加载...","errorState":"对不起,发生了错误"};
diff --git a/dojox/grid/nls/DataGrid_zh-tw.js b/dojox/grid/nls/DataGrid_zh-tw.js
new file mode 100644
index 0000000..7cbfddf
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_zh-tw.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_zh-tw");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.zh_tw");dijit.nls.loading.zh_tw={"loadingState":"載入中...","errorState":"抱歉,發生錯誤"};
diff --git a/dojox/grid/nls/DataGrid_zh.js b/dojox/grid/nls/DataGrid_zh.js
new file mode 100644
index 0000000..aa7d899
--- /dev/null
+++ b/dojox/grid/nls/DataGrid_zh.js
@@ -0,0 +1 @@
+dojo.provide("dojox.grid.nls.DataGrid_zh");dojo.provide("dijit.nls.loading");dijit.nls.loading._built=true;dojo.provide("dijit.nls.loading.zh");dijit.nls.loading.zh={"loadingState":"正在加载...","errorState":"对不起,发生了错误"};
diff --git a/dojox/grid/resources/Grid.css b/dojox/grid/resources/Grid.css
new file mode 100644
index 0000000..058edf9
--- /dev/null
+++ b/dojox/grid/resources/Grid.css
@@ -0,0 +1,269 @@
+.dojoxGrid {
+	position: relative;
+	background-color: #EBEADB;
+	font-family: Geneva, Arial, Helvetica, sans-serif;
+	-moz-outline-style: none;
+	outline: none;
+	overflow: hidden;
+	height: 0;
+}
+.dojoxGrid table {
+	padding: 0;
+}
+.dojoxGrid td {
+	-moz-outline: none;
+}
+.dojoxGridMasterHeader {
+	position: relative;
+}
+.dojoxGridMasterView  {
+	position: relative;
+}
+.dojoxGridMasterMessages {
+	position: relative;
+	padding: 1em;
+	text-align: center;
+	background-color: white;
+}
+.dojoxGridView {
+	position: absolute;
+	overflow: hidden;
+}
+.dojoxGridHeader {
+	position: absolute;
+	overflow: hidden;
+}
+.dojoxGridHeader {
+	background-color: #E8E1CF;
+}
+.dojoxGridHeader table {
+	text-align: center;
+}
+.dojoxGridHeader .dojoxGridCell { 
+	border: 1px solid;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+	padding-bottom: 2px;
+}
+.dojoxGridHeader .dojoxGridCellOver {
+	background-image: none;
+	background-color: white;
+	border-bottom-color: #FEBE47;
+	margin-bottom: 0;
+	padding-bottom: 0;
+	border-bottom-width: 3px;
+}
+.dojoxGridHeader .dojoxGridCellFocus {
+	border: 1px dashed blue;
+}
+.dojoxGridHeader.dojoxGridCellFocus.dojoxGridCellOver {
+	background-image: none;
+	background-color: white;
+	border-bottom-color: #FEBE47;
+	margin-bottom: 0;
+	padding-bottom: 0;
+	border-bottom-width: 3px;
+}
+.dojoxGridArrowButtonNode {
+	display: none;
+	padding-left: 16px;
+}
+.dojoxGridArrowButtonChar {
+	display:inline;
+}
+ 
+.dojoxGridArrowButtonNode:hover {
+        cursor: default;
+}
+.dojoxGridArrowButtonChar:hover {
+        cursor: default;
+}
+.dojoxGridSortUp:hover {
+        cursor: default;
+}
+.dojoxGridSortDown:hover {
+        cursor: default;
+}
+.dijit_a11y .dojoxGridArrowButtonChar {
+	display:inline !important;
+}
+.dojoxGridScrollbox {
+	position: relative;
+	overflow: auto;
+	background-color: white;
+	width: 100%;
+}
+.dojoxGridContent {
+	position: relative;
+	overflow: hidden;
+	 -moz-outline-style: none;
+	outline: none;
+}
+.dojoxGridRowbar { 
+	border: 1px solid;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	border-top: none;
+	background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+}
+.dojoxGridRowbarInner {
+	border-top: 1px solid #F6F4EB;
+}
+.dojoxGridRowbarOver {
+	background-image: none;
+	background-color: white;
+	border-top-color: #FEBE47;
+	border-bottom-color: #FEBE47;
+}
+.dojoxGridRowbarSelected {
+	background-color: #D9E8F9;
+}
+.dojoxGridRow {
+	position: relative;
+	width: 9000em;
+}
+.dojoxGridRow {
+	
+	border: 1px solid #E8E4D8;
+	border-color: #F8F7F1;
+	
+	border-left: none;
+	border-right: none;
+	background-color: white;
+	border-top: none;
+}
+.dojoxGridRowOver {
+	border-top-color: #FEBE47;
+	border-bottom-color: #FEBE47;
+	
+	
+	
+}
+.dojoxGridRowOdd {
+	background-color: #FFFDF3;
+	
+}
+.dojoxGridRowSelected {
+	background-color: #D9E8F9;
+}
+.dojoxGridRowTable {
+	table-layout: fixed;
+	width: 0;
+	empty-cells: show;
+}
+.dj_ie .dojoxGridRowTable {
+	border-collapse: collapse;
+}
+.dojoxGridInvisible {
+	visibility: hidden;
+}		
+.Xdojo-ie .dojoxGridInvisible {
+	display: none;
+}		
+.dojoxGridInvisible td, .dojoxGridHeader .dojoxGridInvisible td {
+	border-top-width: 0;
+	border-bottom-width: 0;
+	padding-top: 0;
+	padding-bottom: 0;
+	height: 0;
+	overflow: hidden;
+}
+.dojoxGridCell {
+	border: 1px solid;
+	border-color: #EBEADB;
+	border-right-color: #D5CDB5;
+	padding: 3px 3px 3px 3px;
+	text-align: left;
+	overflow: hidden;
+}
+.dojoxGridCellFocus {
+	border: 1px dashed blue;
+}
+.dojoxGridCellOver {
+	border: 1px dotted #FEBE47;
+}
+.dojoxGridCellFocus.dojoxGridCellOver {
+	border: 1px dashed green;
+}
+.dojoxGridRowEditing td {
+	background-color: #F4FFF4;
+}
+.dojoxGridRow-inserting td {
+	background-color: #F4FFF4;
+}
+.dojoxGridRow-inflight td {
+	background-color: #F2F7B7;
+}
+.dojoxGridRow-error td {
+	background-color: #F8B8B6;
+}
+.dojoxGridInput, .dojoxGridSelect, .dojoxGridTextarea {
+	margin: 0;
+	padding: 0;
+	border-style: none;
+	width: 100%;
+	font-size: 100%;
+	font-family: inherit;
+}
+.dojoxGridHiddenFocus {
+	position: absolute;
+	top: -1000px;
+	height: 0;
+	width: 0;
+}
+.dijit_a11y .dojoxGridRowbarSelected { 
+	border-top: 1px solid white;
+	border-bottom: 1px dashed black;
+	border-top: 0;
+	background: none;
+}
+.dijit_a11y .dojoxGridRowbarSelected .dojoxGridRowbarInner {
+	border: 0;
+	border-top: 1px solid white;
+}
+.dijit_a11y .dojoxGridRowSelected {
+	border: 1px solid black !important;
+}
+.dojoxGridDndAvatar {
+	font-size: 100%;
+}
+.dojoxGrid .dojoDndItemBefore {
+	border-left-color: red;
+}
+.dojoxGrid .dojoDndItemAfter {
+	border-right-color: red;
+}
+.dojoxGridDndAvatarItem	td {
+	border: 1px solid;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+	padding: 0pt;
+	margin: 0pt;
+}
+.dojoxGridDndAvatarItem	td.dojoxGridDndAvatarItemImage {
+	border: 0;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	background-color: transparent;
+	padding: 3px;
+	padding-bottom: 2px;
+	margin: 0;
+}
+.dojoDndMove .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+	background-image: url(../../../dojo/resources/images/dndNoMove.png);
+	background-repeat: no-repeat;
+	background-position: center center;
+}
+.dojoDndCopy .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+	background-image: url(../../../dojo/resources/images/dndNoCopy.png);
+	background-repeat: no-repeat;
+	background-position: center center;
+}
+.dojoDndMove .dojoDndAvatarCanDrop .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+	background-image: url(../../../dojo/resources/images/dndMove.png);
+	background-repeat: no-repeat;
+	background-position: center center;
+}
+.dojoDndCopy .dojoDndAvatarCanDrop .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+	background-image: url(../../../dojo/resources/images/dndCopy.png);
+	background-repeat: no-repeat;
+	background-position: center center;
+}
diff --git a/dojox/grid/resources/Grid_rtl.css b/dojox/grid/resources/Grid_rtl.css
new file mode 100644
index 0000000..d73877b
--- /dev/null
+++ b/dojox/grid/resources/Grid_rtl.css
@@ -0,0 +1,11 @@
+.dijitRtl .dojoxGridHeader table {
+}
+.dj_ie .dijitRtl .dojoxGridHeader table {
+	float:none;
+}
+.dijitRtl .dojoxGridContent {
+	float:left;
+}
+.dijitRtl .dojoxGridCell {
+	text-align:right;
+}
diff --git a/dojox/grid/resources/View.html b/dojox/grid/resources/View.html
new file mode 100644
index 0000000..4c32705
--- /dev/null
+++ b/dojox/grid/resources/View.html
@@ -0,0 +1,12 @@
+<div class="dojoxGridView" wairole="presentation">
+	<div class="dojoxGridHeader" dojoAttachPoint="headerNode" wairole="presentation">
+		<div dojoAttachPoint="headerNodeContainer" style="width:9000em" wairole="presentation">
+			<div dojoAttachPoint="headerContentNode" wairole="row"></div>
+		</div>
+	</div>
+	<input type="checkbox" class="dojoxGridHiddenFocus" dojoAttachPoint="hiddenFocusNode" wairole="presentation" />
+	<input type="checkbox" class="dojoxGridHiddenFocus" wairole="presentation" />
+	<div class="dojoxGridScrollbox" dojoAttachPoint="scrollboxNode" wairole="presentation">
+		<div class="dojoxGridContent" dojoAttachPoint="contentNode" hidefocus="hidefocus" wairole="presentation"></div>
+	</div>
+</div>
diff --git a/dojox/grid/resources/_Grid.html b/dojox/grid/resources/_Grid.html
new file mode 100644
index 0000000..ac655f1
--- /dev/null
+++ b/dojox/grid/resources/_Grid.html
@@ -0,0 +1,6 @@
+<div class="dojoxGrid" hidefocus="hidefocus" wairole="grid" dojoAttachEvent="onmouseout:_mouseOut">
+	<div class="dojoxGridMasterHeader" dojoAttachPoint="viewsHeaderNode" tabindex="-1" wairole="presentation"></div>
+	<div class="dojoxGridMasterView" dojoAttachPoint="viewsNode" wairole="presentation"></div>
+	<div class="dojoxGridMasterMessages" style="display: none;" dojoAttachPoint="messagesNode"></div>
+	<span dojoAttachPoint="lastFocusNode" tabindex="0"></span>
+</div>
diff --git a/dojox/grid/resources/images/grid_dx_gradient.gif b/dojox/grid/resources/images/grid_dx_gradient.gif
new file mode 100644
index 0000000..57f67ba
Binary files /dev/null and b/dojox/grid/resources/images/grid_dx_gradient.gif differ
diff --git a/dojox/grid/resources/images/grid_sort_down.gif b/dojox/grid/resources/images/grid_sort_down.gif
new file mode 100644
index 0000000..7a73f82
Binary files /dev/null and b/dojox/grid/resources/images/grid_sort_down.gif differ
diff --git a/dojox/grid/resources/images/grid_sort_up.gif b/dojox/grid/resources/images/grid_sort_up.gif
new file mode 100644
index 0000000..9452da0
Binary files /dev/null and b/dojox/grid/resources/images/grid_sort_up.gif differ
diff --git a/dojox/grid/resources/images/tabEnabled_rotated.png b/dojox/grid/resources/images/tabEnabled_rotated.png
new file mode 100644
index 0000000..e326abd
Binary files /dev/null and b/dojox/grid/resources/images/tabEnabled_rotated.png differ
diff --git a/dojox/grid/resources/images/tabHover_rotated.png b/dojox/grid/resources/images/tabHover_rotated.png
new file mode 100644
index 0000000..1a30e10
Binary files /dev/null and b/dojox/grid/resources/images/tabHover_rotated.png differ
diff --git a/dojox/grid/resources/nihiloGrid.css b/dojox/grid/resources/nihiloGrid.css
new file mode 100644
index 0000000..b5da8d9
--- /dev/null
+++ b/dojox/grid/resources/nihiloGrid.css
@@ -0,0 +1,399 @@
+.dojoxGrid {
+	position: relative;
+	background-color: #EBEADB;
+	font-family: Geneva, Arial, Helvetica, sans-serif;
+	-moz-outline-style: none;
+	outline: none;
+	overflow: hidden;
+	height: 0;
+}
+.dojoxGrid table {
+	padding: 0;
+}
+.dojoxGrid td {
+	-moz-outline: none;
+}
+.dojoxGridMasterHeader {
+	position: relative;
+}
+.dojoxGridMasterView  {
+	position: relative;
+}
+.dojoxGridMasterMessages {
+	position: relative;
+	padding: 1em;
+	text-align: center;
+	background-color: white;
+}
+.dojoxGridView {
+	position: absolute;
+	overflow: hidden;
+}
+.dojoxGridHeader {
+	position: absolute;
+	overflow: hidden;
+}
+.dojoxGridHeader {
+	background-color: #E8E1CF;
+}
+.dojoxGridHeader table {
+	text-align: center;
+}
+.dojoxGridHeader .dojoxGridCell { 
+	border: 1px solid;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+	padding-bottom: 2px;
+}
+.dojoxGridHeader .dojoxGridCellOver {
+	background-image: none;
+	background-color: white;
+	border-bottom-color: #FEBE47;
+	margin-bottom: 0;
+	padding-bottom: 0;
+	border-bottom-width: 3px;
+}
+.dojoxGridHeader .dojoxGridCellFocus {
+	border: 1px dashed blue;
+}
+.dojoxGridHeader.dojoxGridCellFocus.dojoxGridCellOver {
+	background-image: none;
+	background-color: white;
+	border-bottom-color: #FEBE47;
+	margin-bottom: 0;
+	padding-bottom: 0;
+	border-bottom-width: 3px;
+}
+.dojoxGridArrowButtonNode {
+	display: none;
+	padding-left: 16px;
+}
+.dojoxGridArrowButtonChar {
+	display:inline;
+}
+ 
+.dojoxGridArrowButtonNode:hover {
+        cursor: default;
+}
+.dojoxGridArrowButtonChar:hover {
+        cursor: default;
+}
+.dojoxGridSortUp:hover {
+        cursor: default;
+}
+.dojoxGridSortDown:hover {
+        cursor: default;
+}
+.dijit_a11y .dojoxGridArrowButtonChar {
+	display:inline !important;
+}
+.dojoxGridScrollbox {
+	position: relative;
+	overflow: auto;
+	background-color: white;
+	width: 100%;
+}
+.dojoxGridContent {
+	position: relative;
+	overflow: hidden;
+	 -moz-outline-style: none;
+	outline: none;
+}
+.dojoxGridRowbar { 
+	border: 1px solid;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	border-top: none;
+	background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+}
+.dojoxGridRowbarInner {
+	border-top: 1px solid #F6F4EB;
+}
+.dojoxGridRowbarOver {
+	background-image: none;
+	background-color: white;
+	border-top-color: #FEBE47;
+	border-bottom-color: #FEBE47;
+}
+.dojoxGridRowbarSelected {
+	background-color: #D9E8F9;
+}
+.dojoxGridRow {
+	position: relative;
+	width: 9000em;
+}
+.dojoxGridRow {
+	
+	border: 1px solid #E8E4D8;
+	border-color: #F8F7F1;
+	
+	border-left: none;
+	border-right: none;
+	background-color: white;
+	border-top: none;
+}
+.dojoxGridRowOver {
+	border-top-color: #FEBE47;
+	border-bottom-color: #FEBE47;
+	
+	
+	
+}
+.dojoxGridRowOdd {
+	background-color: #FFFDF3;
+	
+}
+.dojoxGridRowSelected {
+	background-color: #D9E8F9;
+}
+.dojoxGridRowTable {
+	table-layout: fixed;
+	width: 0;
+	empty-cells: show;
+}
+.dj_ie .dojoxGridRowTable {
+	border-collapse: collapse;
+}
+.dojoxGridInvisible {
+	visibility: hidden;
+}		
+.Xdojo-ie .dojoxGridInvisible {
+	display: none;
+}		
+.dojoxGridInvisible td, .dojoxGridHeader .dojoxGridInvisible td {
+	border-top-width: 0;
+	border-bottom-width: 0;
+	padding-top: 0;
+	padding-bottom: 0;
+	height: 0;
+	overflow: hidden;
+}
+.dojoxGridCell {
+	border: 1px solid;
+	border-color: #EBEADB;
+	border-right-color: #D5CDB5;
+	padding: 3px 3px 3px 3px;
+	text-align: left;
+	overflow: hidden;
+}
+.dojoxGridCellFocus {
+	border: 1px dashed blue;
+}
+.dojoxGridCellOver {
+	border: 1px dotted #FEBE47;
+}
+.dojoxGridCellFocus.dojoxGridCellOver {
+	border: 1px dashed green;
+}
+.dojoxGridRowEditing td {
+	background-color: #F4FFF4;
+}
+.dojoxGridRow-inserting td {
+	background-color: #F4FFF4;
+}
+.dojoxGridRow-inflight td {
+	background-color: #F2F7B7;
+}
+.dojoxGridRow-error td {
+	background-color: #F8B8B6;
+}
+.dojoxGridInput, .dojoxGridSelect, .dojoxGridTextarea {
+	margin: 0;
+	padding: 0;
+	border-style: none;
+	width: 100%;
+	font-size: 100%;
+	font-family: inherit;
+}
+.dojoxGridHiddenFocus {
+	position: absolute;
+	top: -1000px;
+	height: 0;
+	width: 0;
+}
+.dijit_a11y .dojoxGridRowbarSelected { 
+	border-top: 1px solid white;
+	border-bottom: 1px dashed black;
+	border-top: 0;
+	background: none;
+}
+.dijit_a11y .dojoxGridRowbarSelected .dojoxGridRowbarInner {
+	border: 0;
+	border-top: 1px solid white;
+}
+.dijit_a11y .dojoxGridRowSelected {
+	border: 1px solid black !important;
+}
+.dojoxGridDndAvatar {
+	font-size: 100%;
+}
+.dojoxGrid .dojoDndItemBefore {
+	border-left-color: red;
+}
+.dojoxGrid .dojoDndItemAfter {
+	border-right-color: red;
+}
+.dojoxGridDndAvatarItem	td {
+	border: 1px solid;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+	padding: 0pt;
+	margin: 0pt;
+}
+.dojoxGridDndAvatarItem	td.dojoxGridDndAvatarItemImage {
+	border: 0;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	background-color: transparent;
+	padding: 3px;
+	padding-bottom: 2px;
+	margin: 0;
+}
+.dojoDndMove .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+	background-image: url(../../../dojo/resources/images/dndNoMove.png);
+	background-repeat: no-repeat;
+	background-position: center center;
+}
+.dojoDndCopy .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+	background-image: url(../../../dojo/resources/images/dndNoCopy.png);
+	background-repeat: no-repeat;
+	background-position: center center;
+}
+.dojoDndMove .dojoDndAvatarCanDrop .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+	background-image: url(../../../dojo/resources/images/dndMove.png);
+	background-repeat: no-repeat;
+	background-position: center center;
+}
+.dojoDndCopy .dojoDndAvatarCanDrop .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+	background-image: url(../../../dojo/resources/images/dndCopy.png);
+	background-repeat: no-repeat;
+	background-position: center center;
+}
+.nihilo .dojoxGrid {
+	background-color: #e9e9e9;
+	font-size: 0.85em; 
+}
+.nihilo .dojoxGridMasterMessages {
+	background-color: #fefefe;
+}
+.nihilo .dojoxGridHeader {
+	background-color:  #e9e9e9;
+}
+.nihilo .dojoxGridHeader .dojoxGridCell { 
+	border-width: 1px;
+	padding-bottom: 0px;
+	border-color: transparent #ACA899 #919191 transparent;
+	background: url(../../../dijit/themes/nihilo/images/titleBar.png) #e9e9e9 repeat-x top;
+	color: #000 !important;
+}
+.nihilo .dojoxGridHeader .dojoxGridCellOver {
+	background: url(../../../dijit/themes/nihilo/images/titleBarActive.png) #e9e9e9 repeat-x top;
+}
+.nihilo .dojoxGridHeader .dojoxGridCellFocus {
+	border-color: #ACA899 #919191;
+	border-style: dashed;	
+}
+.nihilo .dojoxGridArrowButtonChar {
+	float: right;
+	display: none;
+}
+.nihilo .dojoxGridArrowButtonNode {
+	display: block !important;
+	padding-left: 0px;
+	float: right;
+	background:url("../../../dijit/themes/nihilo/images/spriteArrows.png") left center no-repeat;
+	width: 11px;
+	height: 1em;
+	margin-top: 1px;
+}
+.dj_ie6 .nihilo .dojoxGridArrowButtonNode {
+	background-image:url("../../../dijit/themes/nihilo/images/spriteArrows.gif");
+	margin-left: 0px;
+}
+.nihilo .dojoxGridSortUp .dojoxGridArrowButtonNode {
+	background-position: -21px;
+}
+.dijit_a11y .nihilo .dojoxGridArrowButtonNode {
+	display: none !important;
+}
+.nihilo .dojoxGridScrollbox {
+	background-color: #fefefe;
+}
+.nihilo .dojoxGridRowbar { 
+	border: none;
+	background: url(../../../dijit/themes/nihilo/images/titleBar.png) #e9e9e9 repeat-y right;
+	border-right: 1px solid #ccc;
+	padding: 0px;
+}
+.nihilo .dojoxGridRowbarInner {
+	border: none;
+	border-bottom: 1px solid #ccc;
+}
+.nihilo .dojoxGridRowbarOver {
+	background: url(../../../dijit/themes/nihilo/images/titleBarActive.png) #e9e9e9 repeat-y right;
+}
+.nihilo .dojoxGridRowbarSelected {
+	background: #D9E8F9 url(../../../dijit/themes/nihilo/images/titleBar.png) #ddd no-repeat center;
+	border-right: 1px solid #ccc;
+}
+.nihilo .dojoxGridRow {
+	border: none;
+	background-color: white;
+}
+.nihilo .dojoxGridRowOver {
+	border-top-color: #ccc;
+	border-bottom-color: #ccc;
+}
+.nihilo .dojoxGridRowOver .dojoxGridCell {
+	background-color: #ffe284; 
+}
+.nihilo .dojoxGridRowOdd {
+	background-color: #f2f5f9;
+}
+.nihilo .dojoxGridRowSelected {
+	background-color: #aec7e3;
+}
+.dijit_a11y .nihilo .dojoxGridRowSelected { 
+	background-color: #aec7e3; 
+	border-style: solid; 
+} 
+.nihilo .dojoxGridCell {
+	border: 1px dotted #D5CDB5;
+	border-left-color: transparent;
+	border-top-color: transparent;
+}
+.dj_ff2 .nihilo .dojoxGridCell {
+	border-left-width: 0px;
+	border-top-width: 0px;
+}
+.dj_ie6 .nihilo .dojoxGridCell {
+	border: 1px solid white;
+	border-right: 1px solid #D5CDB5;
+}
+.nihilo .dojoxGridCellFocus {
+	border: 1px dashed darkblue;
+}
+.nihilo .dojoxGridCellOver {
+	border: 1px dotted #a6a6a6;
+}
+.nihilo .dojoxGridCellFocus.dojoxGridCellOver {
+	border: 1px dashed darkblue;
+}
+.nihilo .dojoxGridRowEditing td {
+	
+	background-color: #ffe284; 
+	
+}
+.nihilo .dojoxGridRow-inserting td {
+	background-color: #F4FFF4;
+}
+.nihilo .dojoxGridRow-inflight td {
+	background-color: #F2F7B7;
+}
+.nihilo .dojoxGridRow-error td {
+	background-color: #F8B8B6;
+}
+.nihilo .dojoxGrid .dojoDndItemBefore {
+	border-left-color: #ffe284;
+}
+.nihilo .dojoxGrid .dojoDndItemAfter {
+	border-right-color: #ffe284;
+}
diff --git a/dojox/grid/resources/soriaGrid.css b/dojox/grid/resources/soriaGrid.css
new file mode 100644
index 0000000..48ff246
--- /dev/null
+++ b/dojox/grid/resources/soriaGrid.css
@@ -0,0 +1,400 @@
+.dojoxGrid {
+	position: relative;
+	background-color: #EBEADB;
+	font-family: Geneva, Arial, Helvetica, sans-serif;
+	-moz-outline-style: none;
+	outline: none;
+	overflow: hidden;
+	height: 0;
+}
+.dojoxGrid table {
+	padding: 0;
+}
+.dojoxGrid td {
+	-moz-outline: none;
+}
+.dojoxGridMasterHeader {
+	position: relative;
+}
+.dojoxGridMasterView  {
+	position: relative;
+}
+.dojoxGridMasterMessages {
+	position: relative;
+	padding: 1em;
+	text-align: center;
+	background-color: white;
+}
+.dojoxGridView {
+	position: absolute;
+	overflow: hidden;
+}
+.dojoxGridHeader {
+	position: absolute;
+	overflow: hidden;
+}
+.dojoxGridHeader {
+	background-color: #E8E1CF;
+}
+.dojoxGridHeader table {
+	text-align: center;
+}
+.dojoxGridHeader .dojoxGridCell { 
+	border: 1px solid;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+	padding-bottom: 2px;
+}
+.dojoxGridHeader .dojoxGridCellOver {
+	background-image: none;
+	background-color: white;
+	border-bottom-color: #FEBE47;
+	margin-bottom: 0;
+	padding-bottom: 0;
+	border-bottom-width: 3px;
+}
+.dojoxGridHeader .dojoxGridCellFocus {
+	border: 1px dashed blue;
+}
+.dojoxGridHeader.dojoxGridCellFocus.dojoxGridCellOver {
+	background-image: none;
+	background-color: white;
+	border-bottom-color: #FEBE47;
+	margin-bottom: 0;
+	padding-bottom: 0;
+	border-bottom-width: 3px;
+}
+.dojoxGridArrowButtonNode {
+	display: none;
+	padding-left: 16px;
+}
+.dojoxGridArrowButtonChar {
+	display:inline;
+}
+ 
+.dojoxGridArrowButtonNode:hover {
+        cursor: default;
+}
+.dojoxGridArrowButtonChar:hover {
+        cursor: default;
+}
+.dojoxGridSortUp:hover {
+        cursor: default;
+}
+.dojoxGridSortDown:hover {
+        cursor: default;
+}
+.dijit_a11y .dojoxGridArrowButtonChar {
+	display:inline !important;
+}
+.dojoxGridScrollbox {
+	position: relative;
+	overflow: auto;
+	background-color: white;
+	width: 100%;
+}
+.dojoxGridContent {
+	position: relative;
+	overflow: hidden;
+	 -moz-outline-style: none;
+	outline: none;
+}
+.dojoxGridRowbar { 
+	border: 1px solid;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	border-top: none;
+	background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+}
+.dojoxGridRowbarInner {
+	border-top: 1px solid #F6F4EB;
+}
+.dojoxGridRowbarOver {
+	background-image: none;
+	background-color: white;
+	border-top-color: #FEBE47;
+	border-bottom-color: #FEBE47;
+}
+.dojoxGridRowbarSelected {
+	background-color: #D9E8F9;
+}
+.dojoxGridRow {
+	position: relative;
+	width: 9000em;
+}
+.dojoxGridRow {
+	
+	border: 1px solid #E8E4D8;
+	border-color: #F8F7F1;
+	
+	border-left: none;
+	border-right: none;
+	background-color: white;
+	border-top: none;
+}
+.dojoxGridRowOver {
+	border-top-color: #FEBE47;
+	border-bottom-color: #FEBE47;
+	
+	
+	
+}
+.dojoxGridRowOdd {
+	background-color: #FFFDF3;
+	
+}
+.dojoxGridRowSelected {
+	background-color: #D9E8F9;
+}
+.dojoxGridRowTable {
+	table-layout: fixed;
+	width: 0;
+	empty-cells: show;
+}
+.dj_ie .dojoxGridRowTable {
+	border-collapse: collapse;
+}
+.dojoxGridInvisible {
+	visibility: hidden;
+}		
+.Xdojo-ie .dojoxGridInvisible {
+	display: none;
+}		
+.dojoxGridInvisible td, .dojoxGridHeader .dojoxGridInvisible td {
+	border-top-width: 0;
+	border-bottom-width: 0;
+	padding-top: 0;
+	padding-bottom: 0;
+	height: 0;
+	overflow: hidden;
+}
+.dojoxGridCell {
+	border: 1px solid;
+	border-color: #EBEADB;
+	border-right-color: #D5CDB5;
+	padding: 3px 3px 3px 3px;
+	text-align: left;
+	overflow: hidden;
+}
+.dojoxGridCellFocus {
+	border: 1px dashed blue;
+}
+.dojoxGridCellOver {
+	border: 1px dotted #FEBE47;
+}
+.dojoxGridCellFocus.dojoxGridCellOver {
+	border: 1px dashed green;
+}
+.dojoxGridRowEditing td {
+	background-color: #F4FFF4;
+}
+.dojoxGridRow-inserting td {
+	background-color: #F4FFF4;
+}
+.dojoxGridRow-inflight td {
+	background-color: #F2F7B7;
+}
+.dojoxGridRow-error td {
+	background-color: #F8B8B6;
+}
+.dojoxGridInput, .dojoxGridSelect, .dojoxGridTextarea {
+	margin: 0;
+	padding: 0;
+	border-style: none;
+	width: 100%;
+	font-size: 100%;
+	font-family: inherit;
+}
+.dojoxGridHiddenFocus {
+	position: absolute;
+	top: -1000px;
+	height: 0;
+	width: 0;
+}
+.dijit_a11y .dojoxGridRowbarSelected { 
+	border-top: 1px solid white;
+	border-bottom: 1px dashed black;
+	border-top: 0;
+	background: none;
+}
+.dijit_a11y .dojoxGridRowbarSelected .dojoxGridRowbarInner {
+	border: 0;
+	border-top: 1px solid white;
+}
+.dijit_a11y .dojoxGridRowSelected {
+	border: 1px solid black !important;
+}
+.dojoxGridDndAvatar {
+	font-size: 100%;
+}
+.dojoxGrid .dojoDndItemBefore {
+	border-left-color: red;
+}
+.dojoxGrid .dojoDndItemAfter {
+	border-right-color: red;
+}
+.dojoxGridDndAvatarItem	td {
+	border: 1px solid;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+	padding: 0pt;
+	margin: 0pt;
+}
+.dojoxGridDndAvatarItem	td.dojoxGridDndAvatarItemImage {
+	border: 0;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	background-color: transparent;
+	padding: 3px;
+	padding-bottom: 2px;
+	margin: 0;
+}
+.dojoDndMove .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+	background-image: url(../../../dojo/resources/images/dndNoMove.png);
+	background-repeat: no-repeat;
+	background-position: center center;
+}
+.dojoDndCopy .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+	background-image: url(../../../dojo/resources/images/dndNoCopy.png);
+	background-repeat: no-repeat;
+	background-position: center center;
+}
+.dojoDndMove .dojoDndAvatarCanDrop .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+	background-image: url(../../../dojo/resources/images/dndMove.png);
+	background-repeat: no-repeat;
+	background-position: center center;
+}
+.dojoDndCopy .dojoDndAvatarCanDrop .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+	background-image: url(../../../dojo/resources/images/dndCopy.png);
+	background-repeat: no-repeat;
+	background-position: center center;
+}
+.soria .dojoxGrid {
+	background-color: #e9e9e9;
+	font-size: 0.85em; 
+}
+.soria .dojoxGridMasterMessages {
+	background-color: #fefefe;
+}
+.soria .dojoxGridHeader {
+	background-color:  #e9e9e9;
+}
+.soria .dojoxGridHeader .dojoxGridCell { 
+	border-width: 1px;
+	padding-bottom: 0px;
+	border-color: transparent #ACA899 #919191 transparent;
+	background: url(../../../dijit/themes/soria/images/titleBar.png) #e9e9e9 repeat-x top;
+	color: #000 !important;
+}
+.soria .dojoxGridHeader .dojoxGridCellOver {
+	background: url(../../../dijit/themes/soria/images/titleBarActive.png) #e9e9e9 repeat-x top;
+}
+.soria .dojoxGridHeader .dojoxGridCellFocus {
+	border-color: #ACA899 #919191;
+	border-style: dashed;	
+}
+.soria .dojoxGridArrowButtonChar {
+	float: right;
+	display: none;
+}
+.soria .dojoxGridArrowButtonNode {
+	display: block !important;
+	padding-left: 0px;
+	float: right;
+	background:url("../../../dijit/themes/soria/images/spriteArrows.png") no-repeat left center;
+	margin-top: 2px;
+	width: 11px;
+	height: 1em;
+}
+.dj_ie6 .soria .dojoxGridArrowButtonNode {
+	background-image:url("../../../dijit/themes/soria/images/spriteArrows.gif");
+	margin-left: 0px;
+}
+.soria .dojoxGridSortUp .dojoxGridArrowButtonNode {
+	background-position: -21px;
+}
+.dijit_a11y .soria .dojoxGridArrowButtonNode {
+	display: none !important;
+}
+.soria .dojoxGridScrollbox {
+	background-color: #fefefe;
+}
+.soria .dojoxGridRowbar { 
+	border: none;
+	background: url(../../../dijit/themes/soria/images/titleBar.png) #e9e9e9 repeat-y right;
+	border-right: 1px solid #ccc;
+	padding: 0px;
+}
+.soria .dojoxGridRowbarInner {
+	border: none;
+	border-bottom: 1px solid #ccc;
+}
+.soria .dojoxGridRowbarOver {
+	background: url(../../../dijit/themes/soria/images/titleBarActive.png) #e9e9e9 repeat-y right;
+}
+.soria .dojoxGridRowbarSelected {
+	background: #D9E8F9 url(../../../dijit/themes/soria/images/titleBar.png) #ddd no-repeat center;
+	border-right: 1px solid #ccc;
+}
+.soria .dojoxGridRow {
+	border: none;
+	background-color: white;
+}
+.soria .dojoxGridRowOver {
+	border-top-color: #ccc;
+	border-bottom-color: #ccc;
+}
+.soria .dojoxGridRowOver .dojoxGridCell {
+	background-color: #60a1ea; 
+	color:#fff;
+}
+.soria .dojoxGridRowOdd {
+	background-color: #f2f5f9;
+}
+.soria .dojoxGridRowSelected {
+	background-color: #aec7e3;
+}
+.dijit_a11y .soria .dojoxGridRowSelected { 
+    background-color: #aec7e3;     
+    border-style: solid;     
+}   
+.soria .dojoxGridCell {
+	border: 1px dotted #D5CDB5;
+	border-left-color: transparent;
+	border-top-color: transparent;
+}
+.dj_ff2 .soria .dojoxGridCell {
+	border-left-width: 0px;
+	border-top-width: 0px;
+}
+.dj_ie6 .soria .dojoxGridCell {
+	border: 1px solid white;
+	border-right: 1px solid #D5CDB5;
+}
+.soria .dojoxGridCellFocus {
+	border: 1px dashed darkblue;
+}
+.soria .dojoxGridCellOver {
+	border: 1px dotted #a6a6a6;
+}
+.soria .dojoxGridCellFocus.dojoxGridCellOver {
+	border: 1px dashed darkblue;
+}
+.soria .dojoxGridRowEditing td {
+	
+	background-color: #60a1ea; 
+	
+}
+.soria .dojoxGridRow-inserting td {
+	background-color: #F4FFF4;
+}
+.soria .dojoxGridRow-inflight td {
+	background-color: #F2F7B7;
+}
+.soria .dojoxGridRow-error td {
+	background-color: #F8B8B6;
+}
+.soria .dojoxGrid .dojoDndItemBefore {
+	border-left-color: #4B5AAA;
+}
+.soria .dojoxGrid .dojoDndItemAfter {
+	border-right-color: #4B5AAA;
+}
diff --git a/dojox/grid/resources/tundraGrid.css b/dojox/grid/resources/tundraGrid.css
new file mode 100644
index 0000000..6812416
--- /dev/null
+++ b/dojox/grid/resources/tundraGrid.css
@@ -0,0 +1,423 @@
+.dojoxGrid {
+	position: relative;
+	background-color: #EBEADB;
+	font-family: Geneva, Arial, Helvetica, sans-serif;
+	-moz-outline-style: none;
+	outline: none;
+	overflow: hidden;
+	height: 0;
+}
+.dojoxGrid table {
+	padding: 0;
+}
+.dojoxGrid td {
+	-moz-outline: none;
+}
+.dojoxGridMasterHeader {
+	position: relative;
+}
+.dojoxGridMasterView  {
+	position: relative;
+}
+.dojoxGridMasterMessages {
+	position: relative;
+	padding: 1em;
+	text-align: center;
+	background-color: white;
+}
+.dojoxGridView {
+	position: absolute;
+	overflow: hidden;
+}
+.dojoxGridHeader {
+	position: absolute;
+	overflow: hidden;
+}
+.dojoxGridHeader {
+	background-color: #E8E1CF;
+}
+.dojoxGridHeader table {
+	text-align: center;
+}
+.dojoxGridHeader .dojoxGridCell { 
+	border: 1px solid;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+	padding-bottom: 2px;
+}
+.dojoxGridHeader .dojoxGridCellOver {
+	background-image: none;
+	background-color: white;
+	border-bottom-color: #FEBE47;
+	margin-bottom: 0;
+	padding-bottom: 0;
+	border-bottom-width: 3px;
+}
+.dojoxGridHeader .dojoxGridCellFocus {
+	border: 1px dashed blue;
+}
+.dojoxGridHeader.dojoxGridCellFocus.dojoxGridCellOver {
+	background-image: none;
+	background-color: white;
+	border-bottom-color: #FEBE47;
+	margin-bottom: 0;
+	padding-bottom: 0;
+	border-bottom-width: 3px;
+}
+.dojoxGridArrowButtonNode {
+	display: none;
+	padding-left: 16px;
+}
+.dojoxGridArrowButtonChar {
+	display:inline;
+}
+ 
+.dojoxGridArrowButtonNode:hover {
+        cursor: default;
+}
+.dojoxGridArrowButtonChar:hover {
+        cursor: default;
+}
+.dojoxGridSortUp:hover {
+        cursor: default;
+}
+.dojoxGridSortDown:hover {
+        cursor: default;
+}
+.dijit_a11y .dojoxGridArrowButtonChar {
+	display:inline !important;
+}
+.dojoxGridScrollbox {
+	position: relative;
+	overflow: auto;
+	background-color: white;
+	width: 100%;
+}
+.dojoxGridContent {
+	position: relative;
+	overflow: hidden;
+	 -moz-outline-style: none;
+	outline: none;
+}
+.dojoxGridRowbar { 
+	border: 1px solid;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	border-top: none;
+	background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+}
+.dojoxGridRowbarInner {
+	border-top: 1px solid #F6F4EB;
+}
+.dojoxGridRowbarOver {
+	background-image: none;
+	background-color: white;
+	border-top-color: #FEBE47;
+	border-bottom-color: #FEBE47;
+}
+.dojoxGridRowbarSelected {
+	background-color: #D9E8F9;
+}
+.dojoxGridRow {
+	position: relative;
+	width: 9000em;
+}
+.dojoxGridRow {
+	
+	border: 1px solid #E8E4D8;
+	border-color: #F8F7F1;
+	
+	border-left: none;
+	border-right: none;
+	background-color: white;
+	border-top: none;
+}
+.dojoxGridRowOver {
+	border-top-color: #FEBE47;
+	border-bottom-color: #FEBE47;
+	
+	
+	
+}
+.dojoxGridRowOdd {
+	background-color: #FFFDF3;
+	
+}
+.dojoxGridRowSelected {
+	background-color: #D9E8F9;
+}
+.dojoxGridRowTable {
+	table-layout: fixed;
+	width: 0;
+	empty-cells: show;
+}
+.dj_ie .dojoxGridRowTable {
+	border-collapse: collapse;
+}
+.dojoxGridInvisible {
+	visibility: hidden;
+}		
+.Xdojo-ie .dojoxGridInvisible {
+	display: none;
+}		
+.dojoxGridInvisible td, .dojoxGridHeader .dojoxGridInvisible td {
+	border-top-width: 0;
+	border-bottom-width: 0;
+	padding-top: 0;
+	padding-bottom: 0;
+	height: 0;
+	overflow: hidden;
+}
+.dojoxGridCell {
+	border: 1px solid;
+	border-color: #EBEADB;
+	border-right-color: #D5CDB5;
+	padding: 3px 3px 3px 3px;
+	text-align: left;
+	overflow: hidden;
+}
+.dojoxGridCellFocus {
+	border: 1px dashed blue;
+}
+.dojoxGridCellOver {
+	border: 1px dotted #FEBE47;
+}
+.dojoxGridCellFocus.dojoxGridCellOver {
+	border: 1px dashed green;
+}
+.dojoxGridRowEditing td {
+	background-color: #F4FFF4;
+}
+.dojoxGridRow-inserting td {
+	background-color: #F4FFF4;
+}
+.dojoxGridRow-inflight td {
+	background-color: #F2F7B7;
+}
+.dojoxGridRow-error td {
+	background-color: #F8B8B6;
+}
+.dojoxGridInput, .dojoxGridSelect, .dojoxGridTextarea {
+	margin: 0;
+	padding: 0;
+	border-style: none;
+	width: 100%;
+	font-size: 100%;
+	font-family: inherit;
+}
+.dojoxGridHiddenFocus {
+	position: absolute;
+	top: -1000px;
+	height: 0;
+	width: 0;
+}
+.dijit_a11y .dojoxGridRowbarSelected { 
+	border-top: 1px solid white;
+	border-bottom: 1px dashed black;
+	border-top: 0;
+	background: none;
+}
+.dijit_a11y .dojoxGridRowbarSelected .dojoxGridRowbarInner {
+	border: 0;
+	border-top: 1px solid white;
+}
+.dijit_a11y .dojoxGridRowSelected {
+	border: 1px solid black !important;
+}
+.dojoxGridDndAvatar {
+	font-size: 100%;
+}
+.dojoxGrid .dojoDndItemBefore {
+	border-left-color: red;
+}
+.dojoxGrid .dojoDndItemAfter {
+	border-right-color: red;
+}
+.dojoxGridDndAvatarItem	td {
+	border: 1px solid;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+	padding: 0pt;
+	margin: 0pt;
+}
+.dojoxGridDndAvatarItem	td.dojoxGridDndAvatarItemImage {
+	border: 0;
+	border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+	background-color: transparent;
+	padding: 3px;
+	padding-bottom: 2px;
+	margin: 0;
+}
+.dojoDndMove .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+	background-image: url(../../../dojo/resources/images/dndNoMove.png);
+	background-repeat: no-repeat;
+	background-position: center center;
+}
+.dojoDndCopy .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+	background-image: url(../../../dojo/resources/images/dndNoCopy.png);
+	background-repeat: no-repeat;
+	background-position: center center;
+}
+.dojoDndMove .dojoDndAvatarCanDrop .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+	background-image: url(../../../dojo/resources/images/dndMove.png);
+	background-repeat: no-repeat;
+	background-position: center center;
+}
+.dojoDndCopy .dojoDndAvatarCanDrop .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+	background-image: url(../../../dojo/resources/images/dndCopy.png);
+	background-repeat: no-repeat;
+	background-position: center center;
+}
+.tundra .dojoxGrid {
+	background-color: #e9e9e9;
+	font-size: 0.85em; 
+}
+.tundra .dojoxGridMasterMessages {
+	background-color: #fefefe;
+}
+.tundra .dojoxGridLoading, 
+.tundra .dojoxGridError {
+	background-position:left center;
+	background-repeat: no-repeat;
+	padding-left:25px;
+}
+.dijitRtl .tundra .dojoxGridLoading, 
+.dijitRtl .tundra .dojoxGridError,
+.dijitRtl .tundra .dojoxGridNoData {
+	background-position:right;
+	padding-right:25px;
+	padding-left:0px;
+}
+.tundra .dojoxGridLoading {
+	background-image: url('../../../dijit/themes/tundra/images/loading.gif');
+}
+.tundra .dojoxGridError {
+	background-image: url('../../../dijit/themes/tundra/images/warning.png');
+}
+.tundra .dojoxGridHeader {
+	background-color:  #e9e9e9;
+}
+.tundra .dojoxGridHeader .dojoxGridCell { 
+	border-width: 1px;
+	padding-bottom: 0px;
+	border-color: transparent #ACA899 #919191 transparent;
+	background: url(../../../dijit/themes/tundra/images/tabEnabled.png) #e9e9e9 repeat-x top;
+	color: #000 !important;
+}
+.tundra .dojoxGridHeader .dojoxGridCellOver {
+	background: url(../../../dijit/themes/tundra/images/tabHover.png) #e9e9e9 repeat-x top;
+	color: #000 !important;
+}
+.tundra .dojoxGridHeader .dojoxGridCellFocus {
+	border-color: #ACA899 #919191;
+	border-style: dashed;	
+}
+.tundra .dojoxGridArrowButtonChar {
+	float: right;
+	display: none;
+}
+.tundra .dojoxGridArrowButtonNode {
+	display: block !important;
+	padding-left: 0px;
+	float: right;
+	background:url("../../../dijit/themes/tundra/images/spriteArrows.png") no-repeat left center;
+	width: 7px;
+	height: 1em;
+	margin: 2px 4px 0px 5px;
+}
+.dj_ie6 .tundra .dojoxGridArrowButtonNode {
+	background-image:url("../../../dijit/themes/tundra/images/spriteArrows.gif");
+	margin-left: 0px;
+}
+.tundra .dojoxGridSortUp .dojoxGridArrowButtonNode {
+	background-position: -21px;
+}
+.dijit_a11y .tundra .dojoxGridArrowButtonNode {
+	display: none !important;
+}
+.tundra .dojoxGridScrollbox {
+	background-color: #fefefe;
+}
+.tundra .dojoxGridRowbar { 
+	border: none;
+	background: url(images/tabEnabled_rotated.png) #e9e9e9 repeat-y right;
+	border-right: 1px solid #ccc;
+	padding: 0px;
+}
+.tundra .dojoxGridRowbarInner {
+	border: none;
+	border-bottom: 1px solid #ccc;
+}
+.tundra .dojoxGridRowbarOver {
+	background: url(images/tabHover_rotated.png) #e9e9e9 repeat-y right;
+}
+.tundra .dojoxGridRowbarSelected {
+	background: #D8E8F9 url(../../../dijit/themes/tundra/images/tabDisabled.png) #ddd no-repeat center;
+	border-right: 1px solid #ccc;
+}
+.tundra .dojoxGridRow {
+	border: none;
+	background-color: white;
+}
+.tundra .dojoxGridRowOver {
+	border-top-color: #ccc;
+	border-bottom-color: #ccc;
+}
+.tundra .dojoxGridRowOver .dojoxGridCell {
+	background-color: #60a1ea; 
+	color:#fff;
+}
+.tundra .dojoxGridRowOver .dojoxGridCell .dijit {
+	color: #000;
+}
+.tundra .dojoxGridRowOdd {
+	background-color: #f2f5f9;
+}
+.tundra .dojoxGridRowSelected {
+	background-color: #aec7e3;
+}
+.dijit_a11y .tundra .dojoxGridRowSelected { 
+    background-color: #aec7e3;     
+    border-style: solid;     
+}   
+.tundra .dojoxGridCell {
+	border: 1px dotted #D5CDB5;
+	border-left-color: transparent;
+	border-top-color: transparent;
+}
+.dj_ff2 .tundra .dojoxGridCell {
+	border-left-width: 0px;
+	border-top-width: 0px;
+}
+.dj_ie6 .tundra .dojoxGridCell {
+	border: 1px solid white;
+	border-right: 1px solid #D5CDB5;
+}
+.tundra .dojoxGridCellFocus {
+	border: 1px dashed darkblue;
+}
+.tundra .dojoxGridCellOver {
+	border: 1px dotted #a6a6a6;
+}
+.tundra .dojoxGridCellFocus.dojoxGridCellOver {
+	border: 1px dashed darkblue;
+}
+.tundra .dojoxGridRowEditing td {
+	
+	background-color: #60a1ea; 
+	
+}
+.tundra .dojoxGridRow-inserting td {
+	background-color: #F4FFF4;
+}
+.tundra .dojoxGridRow-inflight td {
+	background-color: #F2F7B7;
+}
+.tundra .dojoxGridRow-error td {
+	background-color: #F8B8B6;
+}
+.tundra .dojoxGrid .dojoDndItemBefore {
+	border-left-color: #3559ac;
+}
+.tundra .dojoxGrid .dojoDndItemAfter {
+	border-right-color: #3559ac;
+}
diff --git a/dojox/grid/util.js b/dojox/grid/util.js
new file mode 100644
index 0000000..449d943
--- /dev/null
+++ b/dojox/grid/util.js
@@ -0,0 +1,65 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.grid.util"]){
+dojo._hasResource["dojox.grid.util"]=true;
+dojo.provide("dojox.grid.util");
+(function(){
+var _1=dojox.grid.util;
+_1.na="...";
+_1.rowIndexTag="gridRowIndex";
+_1.gridViewTag="gridView";
+_1.fire=function(ob,ev,_4){
+var fn=ob&&ev&&ob[ev];
+return fn&&(_4?fn.apply(ob,_4):ob[ev]());
+};
+_1.setStyleHeightPx=function(_6,_7){
+if(_7>=0){
+var s=_6.style;
+var v=_7+"px";
+if(_6&&s["height"]!=v){
+s["height"]=v;
+}
+}
+};
+_1.mouseEvents=["mouseover","mouseout","mousedown","mouseup","click","dblclick","contextmenu"];
+_1.keyEvents=["keyup","keydown","keypress"];
+_1.funnelEvents=function(_a,_b,_c,_d){
+var _e=(_d?_d:_1.mouseEvents.concat(_1.keyEvents));
+for(var i=0,l=_e.length;i<l;i++){
+_b.connect(_a,"on"+_e[i],_c);
+}
+},_1.removeNode=function(_11){
+_11=dojo.byId(_11);
+_11&&_11.parentNode&&_11.parentNode.removeChild(_11);
+return _11;
+};
+_1.arrayCompare=function(inA,inB){
+for(var i=0,l=inA.length;i<l;i++){
+if(inA[i]!=inB[i]){
+return false;
+}
+}
+return (inA.length==inB.length);
+};
+_1.arrayInsert=function(_16,_17,_18){
+if(_16.length<=_17){
+_16[_17]=_18;
+}else{
+_16.splice(_17,0,_18);
+}
+};
+_1.arrayRemove=function(_19,_1a){
+_19.splice(_1a,1);
+};
+_1.arraySwap=function(_1b,inI,inJ){
+var _1e=_1b[inI];
+_1b[inI]=_1b[inJ];
+_1b[inJ]=_1e;
+};
+})();
+}
diff --git a/dojox/help/README b/dojox/help/README
new file mode 100644
index 0000000..00a69a8
--- /dev/null
+++ b/dojox/help/README
@@ -0,0 +1,35 @@
+-------------------------------------------------------------------------------
+dojox.help
+-------------------------------------------------------------------------------
+Version 0.0
+Release date: 3/13/2008
+-------------------------------------------------------------------------------
+Project state:
+experimental
+-------------------------------------------------------------------------------
+Credits
+	Neil Roberts (pottedmeat at dojotoolkit.org)
+	Wolfram Kriesing (wolfram at kriesing.de)
+-------------------------------------------------------------------------------
+Project description
+
+Provide functionality for quick access to available documentation while
+working in the browser.
+-------------------------------------------------------------------------------
+Dependencies:
+
+dojo
+dojox.rpc
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/help/*
+
+Install into the following directory structure:
+/dojox/help/
+
+...which should be at the same level as your Dojo checkout.
+
+And run: dojo.require("dojox.help.console") in your console
+-------------------------------------------------------------------------------
diff --git a/dojox/help/_base.js b/dojox/help/_base.js
new file mode 100644
index 0000000..3fb4c4f
--- /dev/null
+++ b/dojox/help/_base.js
@@ -0,0 +1,388 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.help._base"]){
+dojo._hasResource["dojox.help._base"]=true;
+dojo.provide("dojox.help._base");
+dojo.require("dojox.rpc.Service");
+dojo.require("dojo.io.script");
+dojo.experimental("dojox.help");
+console.warn("Script causes side effects (on numbers, strings, and booleans). Call dojox.help.noConflict() if you plan on executing code.");
+dojox.help={locate:function(_1,_2,_3){
+_3=_3||20;
+var _4=[];
+var _5={};
+var _6;
+if(_2){
+if(!dojo.isArray(_2)){
+_2=[_2];
+}
+for(var i=0,_8;_8=_2[i];i++){
+_6=_8;
+if(dojo.isString(_8)){
+_8=dojo.getObject(_8);
+if(!_8){
+continue;
+}
+}else{
+if(dojo.isObject(_8)){
+_6=_8.__name__;
+}else{
+continue;
+}
+}
+_4.push(_8);
+if(_6){
+_6=_6.split(".")[0];
+if(!_5[_6]&&dojo.indexOf(dojox.help._namespaces,_6)==-1){
+dojox.help.refresh(_6);
+}
+_5[_6]=true;
+}
+}
+}
+if(!_4.length){
+_4.push({__name__:"window"});
+dojo.forEach(dojox.help._namespaces,function(_9){
+_5[_9]=true;
+});
+}
+var _a=_1.toLowerCase();
+var _b=[];
+out:
+for(var i=0,_8;_8=_4[i];i++){
+var _c=_8.__name__||"";
+var _d=dojo.some(_4,function(_e){
+_e=_e.__name__||"";
+return (_c.indexOf(_e+".")==0);
+});
+if(_c&&!_d){
+_6=_c.split(".")[0];
+var _f=[];
+if(_c=="window"){
+for(_6 in dojox.help._names){
+if(dojo.isArray(dojox.help._names[_6])){
+_f=_f.concat(dojox.help._names[_6]);
+}
+}
+}else{
+_f=dojox.help._names[_6];
+}
+for(var j=0,_11;_11=_f[j];j++){
+if((_c=="window"||_11.indexOf(_c+".")==0)&&_11.toLowerCase().indexOf(_a)!=-1){
+if(_11.slice(-10)==".prototype"){
+continue;
+}
+var obj=dojo.getObject(_11);
+if(obj){
+_b.push([_11,obj]);
+if(_b.length==_3){
+break out;
+}
+}
+}
+}
+}
+}
+dojox.help._displayLocated(_b);
+if(!+dojo.isFF){
+return "";
+}
+},refresh:function(_13,_14){
+if(arguments.length<2){
+_14=true;
+}
+dojox.help._recurse(_13,_14);
+},noConflict:function(_15){
+if(arguments.length){
+return dojox.help._noConflict(_15);
+}else{
+while(dojox.help._overrides.length){
+var _16=dojox.help._overrides.pop();
+var _17=_16[0];
+var key=_16[1];
+var _19=_17[key];
+_17[key]=dojox.help._noConflict(_19);
+}
+}
+},init:function(_1a,_1b){
+if(_1a){
+dojox.help._namespaces.concat(_1a);
+}
+dojo.addOnLoad(function(){
+dojo.require=(function(_1c){
+return function(){
+dojox.help.noConflict();
+_1c.apply(dojo,arguments);
+if(dojox.help._timer){
+clearTimeout(dojox.help._timer);
+}
+dojox.help._timer=setTimeout(function(){
+dojo.addOnLoad(function(){
+dojox.help.refresh();
+dojox.help._timer=false;
+});
+},500);
+};
+})(dojo.require);
+dojox.help._recurse();
+});
+},_noConflict:function(_1d){
+if(_1d instanceof String){
+return _1d.toString();
+}else{
+if(_1d instanceof Number){
+return +_1d;
+}else{
+if(_1d instanceof Boolean){
+return (_1d==true);
+}else{
+if(dojo.isObject(_1d)){
+delete _1d.__name__;
+delete _1d.help;
+}
+}
+}
+}
+return _1d;
+},_namespaces:["dojo","dojox","dijit","djConfig"],_rpc:new dojox.rpc.Service(dojo.moduleUrl("dojox.rpc.SMDLibrary","dojo-api.smd")),_attributes:["summary","type","returns","parameters"],_clean:function(_1e){
+var obj={};
+for(var i=0,_21;_21=dojox.help._attributes[i];i++){
+var _22=_1e["__"+_21+"__"];
+if(_22){
+obj[_21]=_22;
+}
+}
+return obj;
+},_displayLocated:function(_23){
+throw new Error("_displayLocated should be overridden in one of the dojox.help packages");
+},_displayHelp:function(_24,obj){
+throw new Error("_displayHelp should be overridden in one of the dojox.help packages");
+},_addVersion:function(obj){
+if(obj.name){
+obj.version=[dojo.version.major,dojo.version.minor,dojo.version.patch].join(".");
+var _27=obj.name.split(".");
+if(_27[0]=="dojo"||_27[0]=="dijit"||_27[0]=="dojox"){
+obj.project=_27[0];
+}
+}
+return obj;
+},_stripPrototype:function(_28){
+var _29=_28.replace(/\.prototype(\.|$)/g,".");
+var _2a=_29;
+if(_29.slice(-1)=="."){
+_2a=_29=_29.slice(0,-1);
+}else{
+_29=_28;
+}
+return [_2a,_29];
+},_help:function(){
+var _2b=this.__name__;
+var _2c=dojox.help._stripPrototype(_2b)[0];
+var _2d=[];
+for(var i=0,_2f;_2f=dojox.help._attributes[i];i++){
+if(!this["__"+_2f+"__"]){
+_2d.push(_2f);
+}
+}
+dojox.help._displayHelp(true,{name:this.__name__});
+if(!_2d.length||this.__searched__){
+dojox.help._displayHelp(false,dojox.help._clean(this));
+}else{
+this.__searched__=true;
+dojox.help._rpc.get(dojox.help._addVersion({name:_2c,exact:true,attributes:_2d})).addCallback(this,function(_30){
+if(this.toString===dojox.help._toString){
+this.toString(_30);
+}
+if(_30&&_30.length){
+_30=_30[0];
+for(var i=0,_2f;_2f=dojox.help._attributes[i];i++){
+if(_30[_2f]){
+this["__"+_2f+"__"]=_30[_2f];
+}
+}
+dojox.help._displayHelp(false,dojox.help._clean(this));
+}else{
+dojox.help._displayHelp(false,false);
+}
+});
+}
+if(!+dojo.isFF){
+return "";
+}
+},_parse:function(_32){
+delete this.__searching__;
+if(_32&&_32.length){
+var _33=_32[0].parameters;
+if(_33){
+var _34=["function ",this.__name__,"("];
+this.__parameters__=_33;
+for(var i=0,_36;_36=_33[i];i++){
+if(i){
+_34.push(", ");
+}
+_34.push(_36.name);
+if(_36.types){
+var _37=[];
+for(var j=0,_39;_39=_36.types[j];j++){
+_37.push(_39.title);
+}
+if(_37.length){
+_34.push(": ");
+_34.push(_37.join("|"));
+}
+}
+if(_36.repeating){
+_34.push("...");
+}
+if(_36.optional){
+_34.push("?");
+}
+}
+_34.push(")");
+this.__source__=this.__source__.replace(/function[^\(]*\([^\)]*\)/,_34.join(""));
+}
+if(this.__output__){
+delete this.__output__;
+
+}
+}else{
+dojox.help._displayHelp(false,false);
+}
+},_toStrings:{},_toString:function(_3a){
+if(!this.__source__){
+return this.__name__;
+}
+var _3b=(!this.__parameters__);
+this.__parameters__=[];
+if(_3a){
+dojox.help._parse.call(this,_3a);
+}else{
+if(_3b){
+this.__searching__=true;
+dojox.help._toStrings[dojox.help._stripPrototype(this.__name__)[0]]=this;
+if(dojox.help._toStringTimer){
+clearTimeout(dojox.help._toStringTimer);
+}
+dojox.help._toStringTimer=setTimeout(function(){
+dojox.help.__toString();
+},50);
+}
+}
+if(!_3b||!this.__searching__){
+return this.__source__;
+}
+var _3c="function Loading info for "+this.__name__+"... (watch console for result) {}";
+if(!+dojo.isFF){
+this.__output__=true;
+return _3c;
+}
+return {toString:dojo.hitch(this,function(){
+this.__output__=true;
+return _3c;
+})};
+},__toString:function(){
+if(dojox.help._toStringTimer){
+clearTimeout(dojox.help._toStringTimer);
+}
+var _3d=[];
+dojox.help.noConflict(dojox.help._toStrings);
+for(var _3e in dojox.help._toStrings){
+_3d.push(_3e);
+}
+while(_3d.length){
+dojox.help._rpc.batch(dojox.help._addVersion({names:_3d.splice(-50,50),exact:true,attributes:["parameters"]})).addCallback(this,function(_3f){
+for(var i=0,_41;_41=_3f[i];i++){
+var fn=dojox.help._toStrings[_41.name];
+if(fn){
+dojox.help._parse.call(fn,[_41]);
+delete dojox.help._toStrings[_41.name];
+}
+}
+});
+}
+},_overrides:[],_recursions:[],_names:{},_recurse:function(_43,_44){
+if(arguments.length<2){
+_44=true;
+}
+var _45=[];
+if(_43&&dojo.isString(_43)){
+dojox.help.__recurse(dojo.getObject(_43),_43,_43,_45,_44);
+}else{
+for(var i=0,ns;ns=dojox.help._namespaces[i];i++){
+if(window[ns]){
+dojox.help._recursions.push([window[ns],ns,ns]);
+window[ns].__name__=ns;
+if(!window[ns].help){
+window[ns].help=dojox.help._help;
+}
+}
+}
+}
+while(dojox.help._recursions.length){
+var _48=dojox.help._recursions.shift();
+dojox.help.__recurse(_48[0],_48[1],_48[2],_45,_44);
+}
+for(var i=0,_49;_49=_45[i];i++){
+delete _49.__seen__;
+}
+},__recurse:function(_4a,_4b,_4c,_4d,_4e){
+for(var key in _4a){
+if(key.match(/([^\w_.$]|__[\w_.$]+__)/)){
+continue;
+}
+var _50=_4a[key];
+if(typeof _50=="undefined"||_50===document||_50===window||_50===dojox.help._toString||_50===dojox.help._help||_50===null||(+dojo.isIE&&_50.tagName)||_50.__seen__){
+continue;
+}
+var _51=dojo.isFunction(_50);
+var _52=dojo.isObject(_50)&&!dojo.isArray(_50)&&!_50.nodeType;
+var _53=(_4c)?(_4c+"."+key):key;
+if(_53=="dojo._blockAsync"){
+continue;
+}
+if(!_50.__name__){
+var _54=null;
+if(dojo.isString(_50)){
+_54=String;
+}else{
+if(typeof _50=="number"){
+_54=Number;
+}else{
+if(typeof _50=="boolean"){
+_54=Boolean;
+}
+}
+}
+if(_54){
+_50=_4a[key]=new _54(_50);
+}
+}
+_50.__seen__=true;
+_50.__name__=_53;
+(dojox.help._names[_4b]=dojox.help._names[_4b]||[]).push(_53);
+_4d.push(_50);
+if(!_51){
+dojox.help._overrides.push([_4a,key]);
+}
+if((_51||_52)&&_4e){
+dojox.help._recursions.push([_50,_4b,_53]);
+}
+if(_51){
+if(!_50.__source__){
+_50.__source__=_50.toString().replace(/^function\b ?/,"function "+_53);
+}
+if(_50.toString===Function.prototype.toString){
+_50.toString=dojox.help._toString;
+}
+}
+if(!_50.help){
+_50.help=dojox.help._help;
+}
+}
+}};
+}
diff --git a/dojox/help/console.js b/dojox/help/console.js
new file mode 100644
index 0000000..f4db2ea
--- /dev/null
+++ b/dojox/help/console.js
@@ -0,0 +1,88 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.help.console"]){
+dojo._hasResource["dojox.help.console"]=true;
+dojo.provide("dojox.help.console");
+dojo.require("dojox.help._base");
+dojo.mixin(dojox.help,{_plainText:function(_1){
+return _1.replace(/(<[^>]*>|&[^;]{2,6};)/g,"");
+},_displayLocated:function(_2){
+var _3={};
+dojo.forEach(_2,function(_4){
+_3[_4[0]]=(+dojo.isFF)?{toString:function(){
+return "Click to view";
+},item:_4[1]}:_4[1];
+});
+
+},_displayHelp:function(_5,_6){
+if(_5){
+var _7="Help for: "+_6.name;
+
+var _8="";
+for(var i=0;i<_7.length;i++){
+_8+="=";
+}
+
+}else{
+if(!_6){
+
+}else{
+var _a=false;
+for(var _b in _6){
+var _c=_6[_b];
+if(_b=="returns"&&_6.type!="Function"&&_6.type!="Constructor"){
+continue;
+}
+if(_c&&(!dojo.isArray(_c)||_c.length)){
+_a=true;
+
+_c=dojo.isString(_c)?dojox.help._plainText(_c):_c;
+if(_b=="returns"){
+var _d=dojo.map(_c.types||[],"return item.title;").join("|");
+if(_c.summary){
+if(_d){
+_d+=": ";
+}
+_d+=dojox.help._plainText(_c.summary);
+}
+
+}else{
+if(_b=="parameters"){
+for(var j=0,_f;_f=_c[j];j++){
+var _10=dojo.map(_f.types,"return item.title").join("|");
+
+var _11="";
+if(_f.optional){
+_11+="Optional. ";
+}
+if(_f.repating){
+_11+="Repeating. ";
+}
+_11+=dojox.help._plainText(_f.summary);
+if(_11){
+_11="  - "+_11;
+for(var k=0;k<_f.name.length;k++){
+_11=" "+_11;
+}
+
+}
+}
+}else{
+
+}
+}
+}
+}
+if(!_a){
+
+}
+}
+}
+}});
+dojox.help.init();
+}
diff --git a/dojox/highlight.js b/dojox/highlight.js
new file mode 100644
index 0000000..514b7e3
--- /dev/null
+++ b/dojox/highlight.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight"]){
+dojo._hasResource["dojox.highlight"]=true;
+dojo.provide("dojox.highlight");
+dojo.require("dojox.highlight._base");
+}
diff --git a/dojox/highlight/README b/dojox/highlight/README
new file mode 100644
index 0000000..cdaed12
--- /dev/null
+++ b/dojox/highlight/README
@@ -0,0 +1,31 @@
+-------------------------------------------------------------------------------
+dojox.highlight
+-------------------------------------------------------------------------------
+Version 1.0
+Release date: 11/25/2007
+-------------------------------------------------------------------------------
+Project state:
+beta
+-------------------------------------------------------------------------------
+Credits
+	Ivan Sagalaev (softwaremaniacs.org) Author
+	Peter Higgins (dante) Dojo port
+-------------------------------------------------------------------------------
+Project description
+
+A syntax highlighting engine for the Dojo Toolkit
+-------------------------------------------------------------------------------
+Dependencies:
+
+dojo base only.
+-------------------------------------------------------------------------------
+Documentation
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+simply get the dojox/highlight folder (and dojox/highlight.js)  from the 
+dojox SVN repository, and include in your page via 
+
+dojo.require("dojox.highlight");
+
diff --git a/dojox/highlight/_base.js b/dojox/highlight/_base.js
new file mode 100644
index 0000000..661dc25
--- /dev/null
+++ b/dojox/highlight/_base.js
@@ -0,0 +1,327 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight._base"]){
+dojo._hasResource["dojox.highlight._base"]=true;
+dojo.provide("dojox.highlight._base");
+(function(){
+var dh=dojox.highlight,_2="\\b(0x[A-Za-z0-9]+|\\d+(\\.\\d+)?)";
+dh.constants={IDENT_RE:"[a-zA-Z][a-zA-Z0-9_]*",UNDERSCORE_IDENT_RE:"[a-zA-Z_][a-zA-Z0-9_]*",NUMBER_RE:"\\b\\d+(\\.\\d+)?",C_NUMBER_RE:_2,APOS_STRING_MODE:{className:"string",begin:"'",end:"'",illegal:"\\n",contains:["escape"],relevance:0},QUOTE_STRING_MODE:{className:"string",begin:"\"",end:"\"",illegal:"\\n",contains:["escape"],relevance:0},BACKSLASH_ESCAPE:{className:"escape",begin:"\\\\.",end:"^",relevance:0},C_LINE_COMMENT_MODE:{className:"comment",begin:"//",end:"$",relevance:0},C_B [...]
+function _3(_4){
+return _4.replace(/&/gm,"&").replace(/</gm,"<").replace(/>/gm,">");
+};
+function _5(_6){
+return dojo.every(_6.childNodes,function(_7){
+return _7.nodeType==3||String(_7.nodeName).toLowerCase()=="br";
+});
+};
+function _8(_9){
+var _a=[];
+dojo.forEach(_9.childNodes,function(_b){
+if(_b.nodeType==3){
+_a.push(_b.nodeValue);
+}else{
+if(String(_b.nodeName).toLowerCase()=="br"){
+_a.push("\n");
+}else{
+throw "Complex markup";
+}
+}
+});
+return _a.join("");
+};
+function _c(_d){
+if(!_d.keywordGroups){
+for(var _e in _d.keywords){
+var kw=_d.keywords[_e];
+if(kw instanceof Object){
+_d.keywordGroups=_d.keywords;
+}else{
+_d.keywordGroups={keyword:_d.keywords};
+}
+break;
+}
+}
+};
+function _10(_11){
+if(_11.defaultMode&&_11.modes){
+_c(_11.defaultMode);
+dojo.forEach(_11.modes,_c);
+}
+};
+var _12=function(_13,_14){
+this.langName=_13;
+this.lang=dh.languages[_13];
+this.modes=[this.lang.defaultMode];
+this.relevance=0;
+this.keywordCount=0;
+this.result=[];
+if(!this.lang.defaultMode.illegalRe){
+this.buildRes();
+_10(this.lang);
+}
+try{
+this.highlight(_14);
+this.result=this.result.join("");
+}
+catch(e){
+if(e=="Illegal"){
+this.relevance=0;
+this.keywordCount=0;
+this.partialResult=this.result.join("");
+this.result=_3(_14);
+}else{
+throw e;
+}
+}
+};
+dojo.extend(_12,{buildRes:function(){
+dojo.forEach(this.lang.modes,function(_15){
+if(_15.begin){
+_15.beginRe=this.langRe("^"+_15.begin);
+}
+if(_15.end){
+_15.endRe=this.langRe("^"+_15.end);
+}
+if(_15.illegal){
+_15.illegalRe=this.langRe("^(?:"+_15.illegal+")");
+}
+},this);
+this.lang.defaultMode.illegalRe=this.langRe("^(?:"+this.lang.defaultMode.illegal+")");
+},subMode:function(_16){
+var _17=this.modes[this.modes.length-1].contains;
+if(_17){
+var _18=this.lang.modes;
+for(var i=0;i<_17.length;++i){
+var _1a=_17[i];
+for(var j=0;j<_18.length;++j){
+var _1c=_18[j];
+if(_1c.className==_1a&&_1c.beginRe.test(_16)){
+return _1c;
+}
+}
+}
+}
+return null;
+},endOfMode:function(_1d){
+for(var i=this.modes.length-1;i>=0;--i){
+var _1f=this.modes[i];
+if(_1f.end&&_1f.endRe.test(_1d)){
+return this.modes.length-i;
+}
+if(!_1f.endsWithParent){
+break;
+}
+}
+return 0;
+},isIllegal:function(_20){
+var _21=this.modes[this.modes.length-1].illegalRe;
+return _21&&_21.test(_20);
+},langRe:function(_22,_23){
+var _24="m"+(this.lang.case_insensitive?"i":"")+(_23?"g":"");
+return new RegExp(_22,_24);
+},buildTerminators:function(){
+var _25=this.modes[this.modes.length-1],_26={};
+if(_25.contains){
+dojo.forEach(this.lang.modes,function(_27){
+if(dojo.indexOf(_25.contains,_27.className)>=0){
+_26[_27.begin]=1;
+}
+});
+}
+for(var i=this.modes.length-1;i>=0;--i){
+var m=this.modes[i];
+if(m.end){
+_26[m.end]=1;
+}
+if(!m.endsWithParent){
+break;
+}
+}
+if(_25.illegal){
+_26[_25.illegal]=1;
+}
+var t=[];
+for(i in _26){
+t.push(i);
+}
+_25.terminatorsRe=this.langRe("("+t.join("|")+")");
+},eatModeChunk:function(_2b,_2c){
+var _2d=this.modes[this.modes.length-1];
+if(!_2d.terminatorsRe){
+this.buildTerminators();
+}
+_2b=_2b.substr(_2c);
+var _2e=_2d.terminatorsRe.exec(_2b);
+if(!_2e){
+return {buffer:_2b,lexeme:"",end:true};
+}
+return {buffer:_2e.index?_2b.substr(0,_2e.index):"",lexeme:_2e[0],end:false};
+},keywordMatch:function(_2f,_30){
+var _31=_30[0];
+if(this.lang.case_insensitive){
+_31=_31.toLowerCase();
+}
+for(var _32 in _2f.keywordGroups){
+if(_31 in _2f.keywordGroups[_32]){
+return _32;
+}
+}
+return "";
+},buildLexemes:function(_33){
+var _34={};
+dojo.forEach(_33.lexems,function(_35){
+_34[_35]=1;
+});
+var t=[];
+for(var i in _34){
+t.push(i);
+}
+_33.lexemsRe=this.langRe("("+t.join("|")+")",true);
+},processKeywords:function(_38){
+var _39=this.modes[this.modes.length-1];
+if(!_39.keywords||!_39.lexems){
+return _3(_38);
+}
+if(!_39.lexemsRe){
+this.buildLexemes(_39);
+}
+_39.lexemsRe.lastIndex=0;
+var _3a=[],_3b=0,_3c=_39.lexemsRe.exec(_38);
+while(_3c){
+_3a.push(_3(_38.substr(_3b,_3c.index-_3b)));
+var _3d=this.keywordMatch(_39,_3c);
+if(_3d){
+++this.keywordCount;
+_3a.push("<span class=\""+_3d+"\">"+_3(_3c[0])+"</span>");
+}else{
+_3a.push(_3(_3c[0]));
+}
+_3b=_39.lexemsRe.lastIndex;
+_3c=_39.lexemsRe.exec(_38);
+}
+_3a.push(_3(_38.substr(_3b,_38.length-_3b)));
+return _3a.join("");
+},processModeInfo:function(_3e,_3f,end){
+var _41=this.modes[this.modes.length-1];
+if(end){
+this.result.push(this.processKeywords(_41.buffer+_3e));
+return;
+}
+if(this.isIllegal(_3f)){
+throw "Illegal";
+}
+var _42=this.subMode(_3f);
+if(_42){
+_41.buffer+=_3e;
+this.result.push(this.processKeywords(_41.buffer));
+if(_42.excludeBegin){
+this.result.push(_3f+"<span class=\""+_42.className+"\">");
+_42.buffer="";
+}else{
+this.result.push("<span class=\""+_42.className+"\">");
+_42.buffer=_3f;
+}
+this.modes.push(_42);
+this.relevance+=typeof _42.relevance=="number"?_42.relevance:1;
+return;
+}
+var _43=this.endOfMode(_3f);
+if(_43){
+_41.buffer+=_3e;
+if(_41.excludeEnd){
+this.result.push(this.processKeywords(_41.buffer)+"</span>"+_3f);
+}else{
+this.result.push(this.processKeywords(_41.buffer+_3f)+"</span>");
+}
+while(_43>1){
+this.result.push("</span>");
+--_43;
+this.modes.pop();
+}
+this.modes.pop();
+this.modes[this.modes.length-1].buffer="";
+return;
+}
+},highlight:function(_44){
+var _45=0;
+this.lang.defaultMode.buffer="";
+do{
+var _46=this.eatModeChunk(_44,_45);
+this.processModeInfo(_46.buffer,_46.lexeme,_46.end);
+_45+=_46.buffer.length+_46.lexeme.length;
+}while(!_46.end);
+if(this.modes.length>1){
+throw "Illegal";
+}
+}});
+function _47(_48,_49,_4a){
+if(String(_48.tagName).toLowerCase()=="code"&&String(_48.parentNode.tagName).toLowerCase()=="pre"){
+var _4b=document.createElement("div"),_4c=_48.parentNode.parentNode;
+_4b.innerHTML="<pre><code class=\""+_49+"\">"+_4a+"</code></pre>";
+_4c.replaceChild(_4b.firstChild,_48.parentNode);
+}else{
+_48.className=_49;
+_48.innerHTML=_4a;
+}
+};
+function _4d(_4e,str){
+var _50=new _12(_4e,str);
+return {result:_50.result,langName:_4e,partialResult:_50.partialResult};
+};
+function _51(_52,_53){
+var _54=_4d(_53,_8(_52));
+_47(_52,_52.className,_54.result);
+};
+function _55(str){
+var _57="",_58="",_59=2,_5a=str;
+for(var key in dh.languages){
+if(!dh.languages[key].defaultMode){
+continue;
+}
+var _5c=new _12(key,_5a),_5d=_5c.keywordCount+_5c.relevance,_5e=0;
+if(!_57||_5d>_5e){
+_5e=_5d;
+_57=_5c.result;
+_58=_5c.langName;
+}
+}
+return {result:_57,langName:_58};
+};
+function _5f(_60){
+var _61=_55(_8(_60));
+if(_61.result){
+_47(_60,_61.langName,_61.result);
+}
+};
+dojox.highlight.processString=function(str,_63){
+return _63?_4d(_63,str):_55(str);
+};
+dojox.highlight.init=function(_64){
+_64=dojo.byId(_64);
+if(dojo.hasClass(_64,"no-highlight")){
+return;
+}
+if(!_5(_64)){
+return;
+}
+var _65=_64.className.split(/\s+/),_66=dojo.some(_65,function(_67){
+if(_67.charAt(0)!="_"&&dh.languages[_67]){
+_51(_64,_67);
+return true;
+}
+return false;
+});
+if(!_66){
+_5f(_64);
+}
+};
+dh.Code=function(p,n){
+dh.init(n);
+};
+})();
+}
diff --git a/dojox/highlight/languages/_all.js b/dojox/highlight/languages/_all.js
new file mode 100644
index 0000000..6b14093
--- /dev/null
+++ b/dojox/highlight/languages/_all.js
@@ -0,0 +1,14 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight.languages._all"]){
+dojo._hasResource["dojox.highlight.languages._all"]=true;
+dojo.provide("dojox.highlight.languages._all");
+dojo.require("dojox.highlight.languages._static");
+dojo.require("dojox.highlight.languages._dynamic");
+dojo.require("dojox.highlight.languages._www");
+}
diff --git a/dojox/highlight/languages/_dynamic.js b/dojox/highlight/languages/_dynamic.js
new file mode 100644
index 0000000..3dbc751
--- /dev/null
+++ b/dojox/highlight/languages/_dynamic.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight.languages._dynamic"]){
+dojo._hasResource["dojox.highlight.languages._dynamic"]=true;
+dojo.provide("dojox.highlight.languages._dynamic");
+dojo.require("dojox.highlight.languages.python");
+}
diff --git a/dojox/highlight/languages/_static.js b/dojox/highlight/languages/_static.js
new file mode 100644
index 0000000..7bd46c5
--- /dev/null
+++ b/dojox/highlight/languages/_static.js
@@ -0,0 +1,13 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight.languages._static"]){
+dojo._hasResource["dojox.highlight.languages._static"]=true;
+dojo.provide("dojox.highlight.languages._static");
+dojo.require("dojox.highlight.languages.cpp");
+dojo.require("dojox.highlight.languages.delphi");
+}
diff --git a/dojox/highlight/languages/_www.js b/dojox/highlight/languages/_www.js
new file mode 100644
index 0000000..50aac43
--- /dev/null
+++ b/dojox/highlight/languages/_www.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight.languages._www"]){
+dojo._hasResource["dojox.highlight.languages._www"]=true;
+dojo.provide("dojox.highlight.languages._www");
+dojo.require("dojox.highlight.languages.xml");
+dojo.require("dojox.highlight.languages.html");
+dojo.require("dojox.highlight.languages.css");
+dojo.require("dojox.highlight.languages.django");
+dojo.require("dojox.highlight.languages.javascript");
+}
diff --git a/dojox/highlight/languages/cpp.js b/dojox/highlight/languages/cpp.js
new file mode 100644
index 0000000..a5e2cd7
--- /dev/null
+++ b/dojox/highlight/languages/cpp.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight.languages.cpp"]){
+dojo._hasResource["dojox.highlight.languages.cpp"]=true;
+dojo.provide("dojox.highlight.languages.cpp");
+dojo.require("dojox.highlight._base");
+(function(){
+var dh=dojox.highlight,_2=dh.constants;
+dh.languages.cpp={defaultMode:{lexems:[_2.UNDERSCORE_IDENT_RE],illegal:"</",contains:["comment","string","number","preprocessor"],keywords:{"false":1,"int":1,"float":1,"while":1,"private":1,"char":1,"catch":1,"export":1,"virtual":1,"operator":2,"sizeof":2,"dynamic_cast":2,"typedef":2,"const_cast":2,"const":1,"struct":1,"for":1,"static_cast":2,"union":1,"namespace":1,"unsigned":1,"long":1,"throw":1,"volatile":2,"static":1,"protected":1,"bool":1,"template":1,"mutable":1,"if":1,"public":1," [...]
+})();
+}
diff --git a/dojox/highlight/languages/css.js b/dojox/highlight/languages/css.js
new file mode 100644
index 0000000..3d0a02a
--- /dev/null
+++ b/dojox/highlight/languages/css.js
@@ -0,0 +1,17 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight.languages.css"]){
+dojo._hasResource["dojox.highlight.languages.css"]=true;
+dojo.provide("dojox.highlight.languages.css");
+dojo.require("dojox.highlight._base");
+dojo.require("dojox.highlight.languages.html");
+(function(){
+var dh=dojox.highlight,_2=dh.constants,_3=dh.languages;
+_3.css={defaultMode:{contains:["id","class","attr_selector","rules","comment"],keywords:_3.html.HTML_TAGS,lexems:[_2.IDENT_RE],illegal:"="},case_insensitive:true,modes:[{className:"id",begin:"\\#[A-Za-z0-9_-]+",end:"^"},{className:"class",begin:"\\.[A-Za-z0-9_-]+",end:"^",relevance:0},{className:"attr_selector",begin:"\\[",end:"\\]",illegal:"$"},{className:"rules",begin:"{",end:"}",lexems:["[A-Za-z-]+"],keywords:{"play-during":1,"counter-reset":1,"counter-increment":1,"min-height":1,"quo [...]
+})();
+}
diff --git a/dojox/highlight/languages/delphi.js b/dojox/highlight/languages/delphi.js
new file mode 100644
index 0000000..6b91028
--- /dev/null
+++ b/dojox/highlight/languages/delphi.js
@@ -0,0 +1,18 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight.languages.delphi"]){
+dojo._hasResource["dojox.highlight.languages.delphi"]=true;
+dojo.provide("dojox.highlight.languages.delphi");
+dojo.require("dojox.highlight._base");
+(function(){
+var _1={"and":1,"safecall":1,"cdecl":1,"then":1,"string":1,"exports":1,"library":1,"not":1,"pascal":1,"set":1,"virtual":1,"file":1,"in":1,"array":1,"label":1,"packed":1,"end.":1,"index":1,"while":1,"const":1,"raise":1,"for":1,"to":1,"implementation":1,"with":1,"except":1,"overload":1,"destructor":1,"downto":1,"finally":1,"program":1,"exit":1,"unit":1,"inherited":1,"override":1,"if":1,"type":1,"until":1,"function":1,"do":1,"begin":1,"repeat":1,"goto":1,"nil":1,"far":1,"initialization":1," [...]
+var _2={"safecall":1,"stdcall":1,"pascal":1,"stored":1,"const":1,"implementation":1,"finalization":1,"except":1,"to":1,"finally":1,"program":1,"inherited":1,"override":1,"then":1,"exports":1,"string":1,"read":1,"not":1,"mod":1,"shr":1,"try":1,"div":1,"shl":1,"set":1,"library":1,"message":1,"packed":1,"index":1,"for":1,"near":1,"overload":1,"label":1,"downto":1,"exit":1,"public":1,"goto":1,"interface":1,"asm":1,"on":1,"of":1,"constructor":1,"or":1,"private":1,"array":1,"unit":1,"raise":1, [...]
+var dh=dojox.highlight,_4=dh.constants;
+dh.languages.delphi={defaultMode:{lexems:[_4.IDENT_RE],illegal:"(\"|\\$[G-Zg-z]|\\/\\*|</)",contains:["comment","string","number","function","class"],keywords:_1},case_insensitive:true,modes:[{className:"comment",begin:"{",end:"}"},{className:"comment",begin:"\\(\\*",end:"\\*\\)",relevance:10},_4.C_LINE_COMMENT_MODE,{className:"number",begin:_4.NUMBER_RE,end:"^",relevance:0},{className:"string",begin:"'",end:"'",contains:["quote"],relevance:0},{className:"string",begin:"(#\\d+)+",end:"^" [...]
+})();
+}
diff --git a/dojox/highlight/languages/django.js b/dojox/highlight/languages/django.js
new file mode 100644
index 0000000..a86cdf9
--- /dev/null
+++ b/dojox/highlight/languages/django.js
@@ -0,0 +1,18 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight.languages.django"]){
+dojo._hasResource["dojox.highlight.languages.django"]=true;
+dojo.provide("dojox.highlight.languages.django");
+dojo.require("dojox.highlight._base");
+dojo.require("dojox.highlight.languages.xml");
+dojo.require("dojox.highlight.languages.html");
+(function(){
+var dh=dojox.highlight,_2=dh.constants,_3=dh.languages,x=_3.xml,h=_3.html;
+_3.django={defaultMode:{contains:["tag","comment","doctype","template_comment","template_tag","variable"]},case_insensitive:true,modes:[x.XML_COMMENT,h.HTML_DOCTYPE,{className:"tag",lexems:[_2.IDENT_RE],keywords:h.HTML_TAGS,begin:"<[A-Za-z/]",end:">",contains:["attribute","template_comment","template_tag","variable"]},x.XML_ATTR,h.HTML_ATTR,{className:"value",begin:"\"",end:"\"",contains:["template_comment","template_tag","variable"]},h.HTML_VALUE,{className:"template_comment",begin:"\\{ [...]
+})();
+}
diff --git a/dojox/highlight/languages/html.js b/dojox/highlight/languages/html.js
new file mode 100644
index 0000000..8b6116c
--- /dev/null
+++ b/dojox/highlight/languages/html.js
@@ -0,0 +1,21 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight.languages.html"]){
+dojo._hasResource["dojox.highlight.languages.html"]=true;
+dojo.provide("dojox.highlight.languages.html");
+dojo.require("dojox.highlight._base");
+dojo.require("dojox.highlight.languages.xml");
+(function(){
+var _1={"code":1,"kbd":1,"font":1,"noscript":1,"style":1,"img":1,"title":1,"menu":1,"tt":1,"tr":1,"param":1,"li":1,"tfoot":1,"th":1,"input":1,"td":1,"dl":1,"blockquote":1,"fieldset":1,"big":1,"dd":1,"abbr":1,"optgroup":1,"dt":1,"button":1,"isindex":1,"p":1,"small":1,"div":1,"dir":1,"em":1,"frame":1,"meta":1,"sub":1,"bdo":1,"label":1,"acronym":1,"sup":1,"body":1,"xml":1,"basefont":1,"base":1,"br":1,"address":1,"strong":1,"legend":1,"ol":1,"script":1,"caption":1,"s":1,"col":1,"h2":1,"h3":1 [...]
+var _2={className:"doctype",begin:"<!DOCTYPE",end:">",relevance:10};
+var _3={className:"attribute",begin:" [a-zA-Z]+",end:"^"};
+var _4={className:"value",begin:"[a-zA-Z0-9]+",end:"^"};
+var dh=dojox.highlight,_6=dh.constants,_7=dh.languages,x=_7.xml;
+_7.html={defaultMode:{contains:["tag","comment","doctype"]},case_insensitive:true,modes:[x.XML_COMMENT,_2,{className:"tag",lexems:[_6.IDENT_RE],keywords:_1,begin:"<[A-Za-z/]",end:">",contains:["attribute"],illegal:"[\\+\\.]"},x.XML_ATTR,_3,x.XML_VALUE,_4],HTML_TAGS:_1,HTML_DOCTYPE:_2,HTML_ATTR:_3,HTML_VALUE:_4};
+})();
+}
diff --git a/dojox/highlight/languages/javascript.js b/dojox/highlight/languages/javascript.js
new file mode 100644
index 0000000..c44ef18
--- /dev/null
+++ b/dojox/highlight/languages/javascript.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight.languages.javascript"]){
+dojo._hasResource["dojox.highlight.languages.javascript"]=true;
+dojo.provide("dojox.highlight.languages.javascript");
+dojo.require("dojox.highlight._base");
+(function(){
+var dh=dojox.highlight,_2=dh.constants;
+dh.languages.javascript={defaultMode:{lexems:[_2.UNDERSCORE_IDENT_RE],contains:["string","comment","number","regexp","function"],keywords:{"keyword":{"in":1,"if":1,"for":1,"while":1,"finally":1,"var":1,"new":1,"function":1,"do":1,"return":1,"void":1,"else":1,"break":1,"catch":1,"instanceof":1,"with":1,"throw":1,"case":1,"default":1,"try":1,"this":1,"switch":1,"continue":1,"typeof":1,"delete":1},"literal":{"true":1,"false":1,"null":1}}},modes:[_2.C_LINE_COMMENT_MODE,_2.C_BLOCK_COMMENT_MOD [...]
+})();
+}
diff --git a/dojox/highlight/languages/pygments/_html.js b/dojox/highlight/languages/pygments/_html.js
new file mode 100644
index 0000000..896993a
--- /dev/null
+++ b/dojox/highlight/languages/pygments/_html.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight.languages.pygments._html"]){
+dojo._hasResource["dojox.highlight.languages.pygments._html"]=true;
+dojo.provide("dojox.highlight.languages.pygments._html");
+dojox.highlight.languages.pygments._html.tags={"code":1,"kbd":1,"font":1,"noscript":1,"style":1,"img":1,"title":1,"menu":1,"tt":1,"tr":1,"param":1,"li":1,"tfoot":1,"th":1,"input":1,"td":1,"dl":1,"blockquote":1,"fieldset":1,"big":1,"dd":1,"abbr":1,"optgroup":1,"dt":1,"button":1,"isindex":1,"p":1,"small":1,"div":1,"dir":1,"em":1,"frame":1,"meta":1,"sub":1,"bdo":1,"label":1,"acronym":1,"sup":1,"body":1,"xml":1,"basefont":1,"base":1,"br":1,"address":1,"strong":1,"legend":1,"ol":1,"script":1, [...]
+}
diff --git a/dojox/highlight/languages/pygments/_www.js b/dojox/highlight/languages/pygments/_www.js
new file mode 100644
index 0000000..29fea91
--- /dev/null
+++ b/dojox/highlight/languages/pygments/_www.js
@@ -0,0 +1,15 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight.languages.pygments._www"]){
+dojo._hasResource["dojox.highlight.languages.pygments._www"]=true;
+dojo.provide("dojox.highlight.languages.pygments._www");
+dojo.require("dojox.highlight.languages.pygments.xml");
+dojo.require("dojox.highlight.languages.pygments.html");
+dojo.require("dojox.highlight.languages.pygments.css");
+dojo.require("dojox.highlight.languages.pygments.javascript");
+}
diff --git a/dojox/highlight/languages/pygments/css.js b/dojox/highlight/languages/pygments/css.js
new file mode 100644
index 0000000..de9871c
--- /dev/null
+++ b/dojox/highlight/languages/pygments/css.js
@@ -0,0 +1,17 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight.languages.pygments.css"]){
+dojo._hasResource["dojox.highlight.languages.pygments.css"]=true;
+dojo.provide("dojox.highlight.languages.pygments.css");
+dojo.require("dojox.highlight._base");
+dojo.require("dojox.highlight.languages.pygments._html");
+(function(){
+var dh=dojox.highlight,_2=dh.languages;
+_2.css={defaultMode:{lexems:["\\b[a-zA-Z0-9]+\\b","\\b at media\b"],keywords:{"keyword":{"@media":1},"name tag":_2.pygments._html.tags},contains:["comment","string single","string double","punctuation","name decorator","name class","name function","_content"]},modes:[{className:"comment",begin:"/\\*",end:"\\*/",relevance:0},{className:"comment preproc",begin:"@[a-z][a-zA-Z]*",end:"^"},{className:"comment preproc",begin:"\\!important\\b",end:"^"},{className:"number",begin:"\\#[a-fA-F0-9]{3}\ [...]
+})();
+}
diff --git a/dojox/highlight/languages/pygments/html.js b/dojox/highlight/languages/pygments/html.js
new file mode 100644
index 0000000..2c769b1
--- /dev/null
+++ b/dojox/highlight/languages/pygments/html.js
@@ -0,0 +1,21 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight.languages.pygments.html"]){
+dojo._hasResource["dojox.highlight.languages.pygments.html"]=true;
+dojo.provide("dojox.highlight.languages.pygments.html");
+dojo.require("dojox.highlight._base");
+dojo.require("dojox.highlight.languages.pygments._html");
+(function(){
+var dh=dojox.highlight,_2=dh.languages,_3=[],ht=_2.pygments._html.tags;
+for(var _5 in ht){
+_3.push(_5);
+}
+_3="\\b("+_3.join("|")+")\\b";
+_2.html={case_insensitive:true,defaultMode:{contains:["name entity","comment","comment preproc","_script","_style","_tag"]},modes:[{className:"comment",begin:"<!--",end:"-->"},{className:"comment preproc",begin:"\\<\\!\\[CDATA\\[",end:"\\]\\]\\>"},{className:"comment preproc",begin:"\\<\\!",end:"\\>"},{className:"string",begin:"'",end:"'",illegal:"\\n",relevance:0},{className:"string",begin:"\"",end:"\"",illegal:"\\n",relevance:0},{className:"name entity",begin:"\\&[a-z]+;",end:"^"},{cla [...]
+})();
+}
diff --git a/dojox/highlight/languages/pygments/javascript.js b/dojox/highlight/languages/pygments/javascript.js
new file mode 100644
index 0000000..e378d64
--- /dev/null
+++ b/dojox/highlight/languages/pygments/javascript.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight.languages.pygments.javascript"]){
+dojo._hasResource["dojox.highlight.languages.pygments.javascript"]=true;
+dojo.provide("dojox.highlight.languages.pygments.javascript");
+dojo.require("dojox.highlight._base");
+(function(){
+var dh=dojox.highlight,_2=dh.constants;
+dh.languages.javascript={defaultMode:{lexems:["\\b[a-zA-Z]+"],keywords:{"keyword":{"for":1,"in":1,"while":1,"do":1,"break":1,"return":1,"continue":1,"if":1,"else":1,"throw":1,"try":1,"catch":1,"var":1,"with":1,"const":1,"label":1,"function":1,"new":1,"typeof":1,"instanceof":1},"keyword constant":{"true":1,"false":1,"null":1,"NaN":1,"Infinity":1,"undefined":1},"name builtin":{"Array":1,"Boolean":1,"Date":1,"Error":1,"Function":1,"Math":1,"netscape":1,"Number":1,"Object":1,"Packages":1,"Re [...]
+})();
+}
diff --git a/dojox/highlight/languages/pygments/xml.js b/dojox/highlight/languages/pygments/xml.js
new file mode 100644
index 0000000..f1adc1d
--- /dev/null
+++ b/dojox/highlight/languages/pygments/xml.js
@@ -0,0 +1,14 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight.languages.pygments.xml"]){
+dojo._hasResource["dojox.highlight.languages.pygments.xml"]=true;
+dojo.provide("dojox.highlight.languages.pygments.xml");
+dojo.require("dojox.highlight._base");
+dojox.highlight.languages.pygments.xml={a:1};
+dojox.highlight.languages.xml={defaultMode:{contains:["name entity","comment","comment preproc","_tag"]},modes:[{className:"comment",begin:"<!--",end:"-->"},{className:"comment preproc",begin:"\\<\\!\\[CDATA\\[",end:"\\]\\]\\>"},{className:"comment preproc",begin:"\\<\\!",end:"\\>"},{className:"comment preproc",begin:"\\<\\?",end:"\\?\\>",relevance:5},{className:"string",begin:"'",end:"'",illegal:"\\n",relevance:0},{className:"string",begin:"\"",end:"\"",illegal:"\\n",relevance:0},{class [...]
+}
diff --git a/dojox/highlight/languages/python.js b/dojox/highlight/languages/python.js
new file mode 100644
index 0000000..9266354
--- /dev/null
+++ b/dojox/highlight/languages/python.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight.languages.python"]){
+dojo._hasResource["dojox.highlight.languages.python"]=true;
+dojo.provide("dojox.highlight.languages.python");
+dojo.require("dojox.highlight._base");
+(function(){
+var dh=dojox.highlight,_2=dh.constants;
+dh.languages.python={defaultMode:{lexems:[_2.UNDERSCORE_IDENT_RE],illegal:"(</|->)",contains:["comment","string","function","class","number","decorator"],keywords:{"and":1,"elif":1,"is":1,"global":1,"as":1,"in":1,"if":1,"from":1,"raise":1,"for":1,"except":1,"finally":1,"print":1,"import":1,"pass":1,"None":1,"return":1,"exec":1,"else":1,"break":1,"not":1,"with":1,"class":1,"assert":1,"yield":1,"try":1,"while":1,"continue":1,"del":1,"or":1,"def":1,"lambda":1}},modes:[{className:"function", [...]
+})();
+}
diff --git a/dojox/highlight/languages/sql.js b/dojox/highlight/languages/sql.js
new file mode 100644
index 0000000..2ea4060
--- /dev/null
+++ b/dojox/highlight/languages/sql.js
@@ -0,0 +1,17 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight.languages.sql"]){
+dojo._hasResource["dojox.highlight.languages.sql"]=true;
+dojo.provide("dojox.highlight.languages.sql");
+dojo.require("dojox.highlight._base");
+(function(){
+var _1={"all":1,"partial":1,"global":1,"month":1,"current_timestamp":1,"using":1,"go":1,"revoke":1,"smallint":1,"indicator":1,"end-exec":1,"disconnect":1,"zone":1,"with":1,"character":1,"assertion":1,"to":1,"add":1,"current_user":1,"usage":1,"input":1,"local":1,"alter":1,"match":1,"collate":1,"real":1,"then":1,"rollback":1,"get":1,"read":1,"timestamp":1,"session_user":1,"not":1,"integer":1,"bit":1,"unique":1,"day":1,"minute":1,"desc":1,"insert":1,"execute":1,"like":1,"level":1,"decimal": [...]
+var dh=dojox.highlight,_3=dh.constants;
+dh.languages.sql={case_insensitive:true,defaultMode:{lexems:[_3.IDENT_RE],contains:["string","number","comment"],keywords:{"keyword":_1,"aggregate":{"count":1,"sum":1,"min":1,"max":1,"avg":1}}},modes:[_3.C_NUMBER_MODE,_3.C_BLOCK_COMMENT_MODE,{className:"comment",begin:"--",end:"$"},{className:"string",begin:"'",end:"'",contains:["escape","squote"],relevance:0},{className:"squote",begin:"''",end:"^"},{className:"string",begin:"\"",end:"\"",contains:["escape","dquote"],relevance:0},{classN [...]
+})();
+}
diff --git a/dojox/highlight/languages/xml.js b/dojox/highlight/languages/xml.js
new file mode 100644
index 0000000..daa2fa0
--- /dev/null
+++ b/dojox/highlight/languages/xml.js
@@ -0,0 +1,19 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.highlight.languages.xml"]){
+dojo._hasResource["dojox.highlight.languages.xml"]=true;
+dojo.provide("dojox.highlight.languages.xml");
+dojo.require("dojox.highlight._base");
+(function(){
+var _1={className:"comment",begin:"<!--",end:"-->"};
+var _2={className:"attribute",begin:" [a-zA-Z-]+=",end:"^",contains:["value"]};
+var _3={className:"value",begin:"\"",end:"\""};
+var dh=dojox.highlight,_5=dh.constants;
+dh.languages.xml={defaultMode:{contains:["pi","comment","cdata","tag"]},case_insensitive:true,modes:[{className:"pi",begin:"<\\?",end:"\\?>",relevance:10},_1,{className:"cdata",begin:"<\\!\\[CDATA\\[",end:"\\]\\]>"},{className:"tag",begin:"</?",end:">",contains:["title","tag_internal"],relevance:1.5},{className:"title",begin:"[A-Za-z:_][A-Za-z0-9\\._:-]+",end:"^",relevance:0},{className:"tag_internal",begin:"^",endsWithParent:true,contains:["attribute"],relevance:0,illegal:"[\\+\\.]"},_2 [...]
+})();
+}
diff --git a/dojox/highlight/resources/highlight.css b/dojox/highlight/resources/highlight.css
new file mode 100644
index 0000000..45a61a3
--- /dev/null
+++ b/dojox/highlight/resources/highlight.css
@@ -0,0 +1,51 @@
+
+.string,
+.function .title,
+.class .title, 
+.tag .attribute .value,
+.css .rules .value,
+.preprocessor,
+.ruby .symbol,
+.ruby .instancevar,
+.ruby .class .parent,
+.built_in,
+.sql .aggregate,
+.django .template_tag,
+.django .variable,
+.smalltalk .class {
+	color: #800;
+}
+.comment,
+.java .annotation,
+.template_comment {
+	color: #888;
+}
+.number,
+.regexp,
+.javascript .literal,
+.smalltalk .symbol,
+.smalltalk .char {
+	color: #080;
+}
+.javadoc,
+.ruby .string,
+.python .decorator,
+.django .filter .argument,
+.smalltalk .localvars,
+.smalltalk .array,
+.css .attr_selector,
+.xml .pi {
+	color: #88F;
+}
+.keyword,
+.css .id,
+.phpdoc,
+.function .title,
+.class .title,
+.vbscript .built_in,
+.sql .aggregate,
+.rsl .built_in,
+.smalltalk .class,
+.xml .tag .title {
+	font-weight: bold;
+}
diff --git a/dojox/highlight/resources/pygments/autumn.css b/dojox/highlight/resources/pygments/autumn.css
new file mode 100644
index 0000000..b1846f4
--- /dev/null
+++ b/dojox/highlight/resources/pygments/autumn.css
@@ -0,0 +1,22 @@
+
+code .comment {color: #aaa; font-style: italic}
+code .comment.preproc {color: #4c8317; font-style: normal}
+code .comment.special {color: #00a}
+code .keyword {color: #00a}
+code .keyword.type {color: #0aa}
+code .operator.word {color: #00a}
+code .name.builtin {color: #0aa}
+code .name.function {color: #0a0}
+code .name.class {color: #0a0; text-decoration: underline}
+code .name.namespace {color: #0aa; text-decoration: underline}
+code .name.exception {color: #D2413A; font-weight: bold}
+code .name.variable {color: #a00}
+code .name.constant {color: #a00}
+code .name.entity {color: #800; font-weight: bold}
+code .name.attribute {color: #1e90ff}
+code .name.tag {color: #1e90ff; font-weight: bold}
+code .name.decorator {color: #888}
+code .string {color: #a50}
+code .string.regex {color: #099}
+code .string.symbol {color: #00a}
+code .number {color: #099}
diff --git a/dojox/highlight/resources/pygments/borland.css b/dojox/highlight/resources/pygments/borland.css
new file mode 100644
index 0000000..85fb11f
--- /dev/null
+++ b/dojox/highlight/resources/pygments/borland.css
@@ -0,0 +1,11 @@
+
+code .comment {color: #080; font-style: italic}
+code .comment.preproc {color: #008080; font-style: normal}
+code .comment.special {font-weight: bold; font-style: normal}
+code .keyword {color: #000080; font-weight: bold}
+code .operator.word {font-weight: bold}
+code .name.attribute {color: #f00}
+code .name.tag {color: #000080; font-weight: bold}
+code .string {color: #00f}
+code .string.char {color: #800080}
+code .number {color: #00f}
diff --git a/dojox/highlight/resources/pygments/colorful.css b/dojox/highlight/resources/pygments/colorful.css
new file mode 100644
index 0000000..06de503
--- /dev/null
+++ b/dojox/highlight/resources/pygments/colorful.css
@@ -0,0 +1,37 @@
+
+code .comment {color: #888}
+code .comment.preproc {color: #579}
+code .comment.special {color: #c00; font-weight: bold}
+code .keyword {color: #080; font-weight: bold}
+code .keyword.pseudo {color: #038}
+code .keyword.type {color: #339}
+code .operator {color: #333}
+code .operator.word {color: #000; font-weight: bold}
+code .name.builtin {color: #007020}
+code .name.function {color: #06b; font-weight: bold}
+code .name.class {color: #b06; font-weight: bold}
+code .name.namespace {color: #0e84b5; font-weight: bold}
+code .name.exception {color: #f00; font-weight: bold}
+code .name.variable {color: #963}
+code .name.variable.instance {color: #33b}
+code .name.variable.class {color: #369}
+code .name.variable.global {color: #d70; font-weight: bold}
+code .name.constant {color: #036; font-weight: bold}
+code .name.label {color: #970; font-weight: bold}
+code .name.entity {color: #800; font-weight: bold}
+code .name.attribute {color: #00c}
+code .name.tag {color: #070}
+code .name.decorator {color: #555; font-weight: bold}
+code .string {background-color: #fff0f0}
+code .string.char {color: #04d; background-color: transparent}
+code .string.doc {color: #d42; background-color: transparent}
+code .string.interpol {background-color: #eee}
+code .string.escape {color: #666; font-weight: bold}
+code .string.regex {color: #000; background-color: #fff0f0}
+code .string.symbol {color: #a60; background-color: transparent}
+code .string.other {color: #d20}
+code .number {color: #60e}
+code .number.integer {color: #00d}
+code .number.float {color: #60e}
+code .number.hex {color: #058}
+code .number.oct {color: #40e}
diff --git a/dojox/highlight/resources/pygments/default.css b/dojox/highlight/resources/pygments/default.css
new file mode 100644
index 0000000..f0b5f05
--- /dev/null
+++ b/dojox/highlight/resources/pygments/default.css
@@ -0,0 +1,28 @@
+
+code {background-color: #f8f8f8}
+code .comment {color: #408080; font-style: italic}
+code .comment.preproc {color: #bc7a00; font-style: normal}
+code .keyword {color: #008000; font-weight: bold}
+code .keyword.pseudo {font-weight: normal}
+code .operator {color: #666}
+code .operator.word {color: #a2f}
+code .name.builtin {color: #008000}
+code .name.function {color: #00f}
+code .name.class {color: #00f; font-weight: bold}
+code .name.namespace {color: #00f; font-weight: bold}
+code .name.exception {color: #d2413a; font-weight: bold}
+code .name.variable {color: #19177c}
+code .name.constant {color: #800}
+code .name.label {color: #a0a000}
+code .name.entity {color: #999; font-weight: bold}
+code .name.attribute {color: #7d9029}
+code .name.tag {color: #008000; font-weight: bold}
+code .name.decorator {color: #a2f}
+code .string {color: #ba2121}
+code .string.doc {font-style: italic}
+code .string.interpol {color: #b68; font-weight: bold}
+code .string.escape {color: #b62; font-weight: bold}
+code .string.regex {color: #b68}
+code .string.symbol {color: #19177c}
+code .string.other {color: #008000}
+code .number {color: #666}
diff --git a/dojox/highlight/resources/pygments/emacs.css b/dojox/highlight/resources/pygments/emacs.css
new file mode 100644
index 0000000..8c815ed
--- /dev/null
+++ b/dojox/highlight/resources/pygments/emacs.css
@@ -0,0 +1,29 @@
+
+code {background-color: #f8f8f8}
+code .comment {color: #080; font-style: italic}
+code .comment.preproc {font-style: normal}
+code .comment.special {font-style: normal; font-weight: bold}
+code .keyword {color: #a2f; font-weight: bold}
+code .keyword.pseudo {font-weight: normal}
+code .operator {color: #666}
+code .operator.word {color: #a2f; font-weight: bold}
+code .name.builtin {color: #a2f}
+code .name.function {color: #00a000}
+code .name.class {color: #00f}
+code .name.namespace {color: #00f; font-weight: bold}
+code .name.exception {color: #d2413a; font-weight: bold}
+code .name.variable {color: #b8860b}
+code .name.constant {color: #800}
+code .name.label {color: #a0a000}
+code .name.entity {color: #999; font-weight: bold}
+code .name.attribute {color: #b44}
+code .name.tag {color: #008000; font-weight: bold}
+code .name.decorator {color: #a2f}
+code .string {color: #b44}
+code .string.doc {font-style: italic}
+code .string.interpol {color: #b68; font-weight: bold}
+code .string.escape {color: #b62; font-weight: bold}
+code .string.regex {color: #b68}
+code .string.symbol {color: #b8860b}
+code .string.other {color: #008000}
+code .number {color: #666}
diff --git a/dojox/highlight/resources/pygments/friendly.css b/dojox/highlight/resources/pygments/friendly.css
new file mode 100644
index 0000000..c4d392a
--- /dev/null
+++ b/dojox/highlight/resources/pygments/friendly.css
@@ -0,0 +1,29 @@
+
+code {background-color: #f8f8f8}
+code .comment {color: #60a0b0; font-style: italic}
+code .comment.preproc {color: #007020; font-style: normal}
+code .comment.special {background-color: #fff0f0; font-style: normal}
+code .keyword {color: #007020; font-weight: bold}
+code .keyword.pseudo {font-weight: normal}
+code .operator {color: #666}
+code .operator.word {color: #007020; font-weight: bold}
+code .name.builtin {color: #007020}
+code .name.function {color: #06287e}
+code .name.class {color: #0e84b5; font-weight: bold}
+code .name.namespace {color: #0e84b5; font-weight: bold}
+code .name.exception {color: #007020}
+code .name.variable {color: #bb60d5}
+code .name.constant {color: #60add5}
+code .name.label {color: #002070; font-weight: bold}
+code .name.entity {color: #d55537; font-weight: bold}
+code .name.attribute {color: #4070a0}
+code .name.tag {color: #062873; font-weight: bold}
+code .name.decorator {color: #555; font-weight: bold}
+code .string {color: #4070a0}
+code .string.doc {font-style: italic}
+code .string.interpol {color: #70a0d0; font-style: italic}
+code .string.escape {color: #4070a0; font-weight: bold}
+code .string.regex {color: #235388}
+code .string.symbol {color: #517918}
+code .string.other {color: #c65d09}
+code .number {color: #40a070}
diff --git a/dojox/highlight/resources/pygments/fruity.css b/dojox/highlight/resources/pygments/fruity.css
new file mode 100644
index 0000000..019fa02
--- /dev/null
+++ b/dojox/highlight/resources/pygments/fruity.css
@@ -0,0 +1,14 @@
+
+code {background-color: #111; color: #fff}
+code .comment {color: #080; background-color: #0f140f; font-style: italic}
+code .comment.preproc {color: #ff0007; font-weight: bold}
+code .keyword {color: #fb660a; font-weight: bold}
+code .keyword.pseudo {font-weight: normal}
+code .keyword.type {color: #cdcaa9; font-weight: bold}
+code .name.function {color: #ff0086; font-weight: bold}
+code .name.variable {color: #fb660a}
+code .name.constant {color: #0086d2}
+code .name.attribute {color: #ff0086; font-weight: bold}
+code .name.tag {color: #fb660a; font-weight: bold}
+code .string {color: #0086d2}
+code .number {color: #0086f7; font-weight: bold}
diff --git a/dojox/highlight/resources/pygments/manni.css b/dojox/highlight/resources/pygments/manni.css
new file mode 100644
index 0000000..0cbf7e6
--- /dev/null
+++ b/dojox/highlight/resources/pygments/manni.css
@@ -0,0 +1,30 @@
+
+code {background-color: #f0f3f3}
+code .comment {color: #09f; font-style: italic}
+code .comment.preproc {color: #099; font-style: normal}
+code .comment.special {font-weight: bold}
+code .keyword {color: #069; font-weight: bold}
+code .keyword.pseudo {font-weight: normal}
+code .keyword.type {color: #078}
+code .operator {color: #555}
+code .operator.word {color: #000; font-weight: bold}
+code .name.builtin {color: #366}
+code .name.function {color: #c0f}
+code .name.class {color: #0a8; font-weight: bold}
+code .name.namespace {color: #0cf; font-weight: bold}
+code .name.exception {color: #c00; font-weight: bold}
+code .name.variable {color: #033}
+code .name.constant {color: #360}
+code .name.label {color: #99f}
+code .name.entity {color: #999; font-weight: bold}
+code .name.attribute {color: #309}
+code .name.tag {color: #309; font-weight: bold}
+code .name.decorator {color: #99f}
+code .string {color: #c30}
+code .string.doc {font-style: italic}
+code .string.interpol {color: #a00}
+code .string.escape {color: #c30; font-weight: bold}
+code .string.regex {color: #3aa}
+code .string.symbol {color: #fc3}
+code .string.other {color: #c30}
+code .number {color: #f60}
diff --git a/dojox/highlight/resources/pygments/murphy.css b/dojox/highlight/resources/pygments/murphy.css
new file mode 100644
index 0000000..971b505
--- /dev/null
+++ b/dojox/highlight/resources/pygments/murphy.css
@@ -0,0 +1,37 @@
+
+code .comment {color: #666; font-style: italic}
+code .comment.preproc {color: #579; font-style: normal}
+code .comment.special {color: #c00; font-weight: bold}
+code .keyword {color: #289; font-weight: bold}
+code .keyword.pseudo {color: #08f}
+code .keyword.type {color: #66f}
+code .operator {color: #333}
+code .operator.word {color: #000; font-weight: bold}
+code .name.builtin {color: #072}
+code .name.function {color: #5ed; font-weight: bold}
+code .name.class {color: #e9e; font-weight: bold}
+code .name.namespace {color: #0e84b5; font-weight: bold}
+code .name.exception {color: #f00; font-weight: bold}
+code .name.variable {color: #036}
+code .name.variable.instance {color: #aaf}
+code .name.variable.class {color: #ccf}
+code .name.variable.global {color: #f84}
+code .name.constant {color: #5ed; font-weight: bold}
+code .name.label {color: #970; font-weight: bold}
+code .name.entity {color: #800}
+code .name.attribute {color: #007}
+code .name.tag {color: #070}
+code .name.decorator {color: #555; font-weight: bold}
+code .string {background-color: #e0e0ff}
+code .string.char {color: #88f; background-color: transparent}
+code .string.doc {color: #d42; background-color: transparent}
+code .string.interpol {background-color: #eee}
+code .string.escape {color: #666; font-weight: bold}
+code .string.regex {color: #000; background-color: #e0e0ff}
+code .string.symbol {color: #fc8; background-color: transparent}
+code .string.other {color: #f88}
+code .number {color: #60e; font-weight: bold}
+code .number.integer {color: #66f; font-weight: bold}
+code .number.float {color: #60e; font-weight: bold}
+code .number.hex {color: #058; font-weight: bold}
+code .number.oct {color: #40e; font-weight: bold}
diff --git a/dojox/highlight/resources/pygments/native.css b/dojox/highlight/resources/pygments/native.css
new file mode 100644
index 0000000..47c361d
--- /dev/null
+++ b/dojox/highlight/resources/pygments/native.css
@@ -0,0 +1,21 @@
+
+code {background-color: #202020; color: #d0d0d0}
+code .comment {color: #999; font-style: italic}
+code .comment.preproc {color: #cd2828; font-style: normal; font-weight: bold}
+code .comment.special {color: #e50808; font-style: normal; font-weight: bold; background-color: #520000}
+code .keyword {color: #6ab825; font-weight: bold}
+code .keyword.pseudo {font-weight: normal}
+code .operator.word {color: #6ab825; font-weight: bold}
+code .name.builtin {color: #24909d}
+code .name.function {color: #40ffff}
+code .name.class {color: #447fcf; text-decoration: underline}
+code .name.namespace {color: #447fcf; text-decoration: underline}
+code .name.exception {color: #bbb}
+code .name.variable {color: #40ffff}
+code .name.constant {color: #40ffff}
+code .name.attribute {color: #bbb}
+code .name.tag {color: #6ab825; font-weight: bold}
+code .name.decorator {color: #ffa500}
+code .string {color: #ed9d13}
+code .string.other {color: #ffa500}
+code .number {color: #3677a9}
diff --git a/dojox/highlight/resources/pygments/pastie.css b/dojox/highlight/resources/pygments/pastie.css
new file mode 100644
index 0000000..d5e20e3
--- /dev/null
+++ b/dojox/highlight/resources/pygments/pastie.css
@@ -0,0 +1,30 @@
+
+code .comment {color: #888}
+code .comment.preproc {color: #c00; font-weight: bold}
+code .comment.special {color: #c00; font-weight: bold; background-color: #fff0f0}
+code .keyword {color: #008800; font-weight: bold}
+code .keyword.pseudo {font-weight: normal}
+code .keyword.type {color: #888}
+code .operator.word {color: #080}
+code .name.builtin {color: #038}
+code .name.function {color: #06b; font-weight: bold}
+code .name.class {color: #b06; font-weight: bold}
+code .name.namespace {color: #b06; font-weight: bold}
+code .name.exception {color: #b06; font-weight: bold}
+code .name.variable {color: #369}
+code .name.variable.class {color: #369}
+code .name.variable.instance {color: #33b}
+code .name.variable.global {color: #d70}
+code .name.constant {color: #036; font-weight: bold}
+code .name.label {color: #369; font-style: italic}
+code .name.attribute {color: #369}
+code .name.tag {color: #b06; font-weight: bold}
+code .name.decorator {color: #555}
+code .name.property {color: #369; font-weight: bold}
+code .string {color: #d20; background-color: #fff0f0}
+code .string.interpol {color: #33b}
+code .string.escape {color: #04d}
+code .string.regex {color: #080; background-color: #fff0f0}
+code .string.symbol {color: #a60}
+code .string.other {color: #2b2; background-color: #f0fff0}
+code .number {color: #00d; font-weight: bold}
diff --git a/dojox/highlight/resources/pygments/perldoc.css b/dojox/highlight/resources/pygments/perldoc.css
new file mode 100644
index 0000000..e9253e6
--- /dev/null
+++ b/dojox/highlight/resources/pygments/perldoc.css
@@ -0,0 +1,23 @@
+
+code {background-color: #eed}
+code .comment {color: #228b22}
+code .comment.preproc {color: #1e889b}
+code .comment.special {color: #8b008b; font-weight: bold}
+code .keyword {color: #8b008b; font-weight: bold}
+code .keyword.type {color: #a7a7a7}
+code .operator.word {color: #8b008b}
+code .name.builtin {color: #658b00}
+code .name.function {color: #008b45}
+code .name.class {color: #008b45; font-weight: bold}
+code .name.namespace {color: #008b45; text-decoration: underline}
+code .name.exception {color: #008b45; font-weight: bold}
+code .name.variable {color: #00688b}
+code .name.constant {color: #00688b}
+code .name.attribute {color: #658b00}
+code .name.tag {color: #8b008b; font-weight: bold}
+code .name.decorator {color: #707a7c}
+code .string {color: #cd5555}
+code .string.regex {color: #1c7e71}
+code .string.other {color: #cb6c20}
+code .string.heredoc {color: #1c7e71; font-style: italic}
+code .number {color: #b452cd}
diff --git a/dojox/highlight/resources/pygments/trac.css b/dojox/highlight/resources/pygments/trac.css
new file mode 100644
index 0000000..2085719
--- /dev/null
+++ b/dojox/highlight/resources/pygments/trac.css
@@ -0,0 +1,20 @@
+
+code .comment {color: #998; font-style: italic}
+code .comment.preproc {color: #999; font-style: normal; font-weight: bold}
+code .comment.special {color: #999; font-weight: bold}
+code .keyword {font-weight: bold}
+code .keyword.type {color: #458}
+code .operator {font-weight: bold}
+code .name.builtin {color: #999}
+code .name.function {color: #900; font-weight: bold}
+code .name.class {color: #458; font-weight: bold}
+code .name.namespace {color: #555}
+code .name.exception {color: #900; font-weight: bold}
+code .name.variable {color: #008080}
+code .name.constant {color: #008080}
+code .name.entity {color: #800080}
+code .name.attribute {color: #008080}
+code .name.tag {color: #000080}
+code .string {color: #b84}
+code .string.regex {color: #808000}
+code .number {color: #099}
diff --git a/dojox/html.js b/dojox/html.js
new file mode 100644
index 0000000..0e2c7d3
--- /dev/null
+++ b/dojox/html.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.html"]){
+dojo._hasResource["dojox.html"]=true;
+dojo.provide("dojox.html");
+dojo.require("dojox.html._base");
+}
diff --git a/dojox/html/README b/dojox/html/README
new file mode 100644
index 0000000..ef38d50
--- /dev/null
+++ b/dojox/html/README
@@ -0,0 +1,46 @@
+-------------------------------------------------------------------------------
+dojox.html
+-------------------------------------------------------------------------------
+Version 0.2
+Release date: 04/24/2008
+-------------------------------------------------------------------------------
+Project state:
+beta
+-------------------------------------------------------------------------------
+Credits
+	Eugene Lazutkin (eugene.lazutkin AT gmail.com)
+	Scott J. Miles (sjmiles AT activegrid.com)
+	Steve Orvell (sorvell AT activegrid.com)
+	Tom Trenka (ttrenka AT gmail.com)
+	Bryan Forbes (bryan AT reigndropsfall.net)
+    Mike Wilcox - dojox.html.styles (anm8tr AT yahoo.com)
+-------------------------------------------------------------------------------
+Project description
+
+This project aims to add html functions that aren't used often enough to
+warrant going into Dojo Core but should not be duplicated.  For instance, font
+measurement routines aren't used by the majority of developers, but are complex
+enough to not be duplicated.
+Styles adds the ability to create and remove dynamic cssRules, as well as 
+manipulate document style sheets.
+-------------------------------------------------------------------------------
+Dependencies:
+
+dojox.html nor dojox.html.styles have dependencies, outside of Dojo Core.
+-------------------------------------------------------------------------------
+Documentation
+
+To automatically initialize the font resize callback, add "fontSizeWatch: true"
+to your djConfig.
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/html.js
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/html/*
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/html/styles.js
+Install into the following directory structure:
+/dojox/html/
+
+...which should be at the same level as your Dojo checkout.
+-------------------------------------------------------------------------------
diff --git a/dojox/html/_base.js b/dojox/html/_base.js
new file mode 100644
index 0000000..51347a3
--- /dev/null
+++ b/dojox/html/_base.js
@@ -0,0 +1,177 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.html._base"]){
+dojo._hasResource["dojox.html._base"]=true;
+dojo.provide("dojox.html._base");
+dojo.require("dojo.html");
+(function(){
+if(dojo.isIE){
+var _1=/(AlphaImageLoader\([^)]*?src=(['"]))(?![a-z]+:|\/)([^\r\n;}]+?)(\2[^)]*\)\s*[;}]?)/g;
+}
+var _2=/(?:(?:@import\s*(['"])(?![a-z]+:|\/)([^\r\n;{]+?)\1)|url\(\s*(['"]?)(?![a-z]+:|\/)([^\r\n;]+?)\3\s*\))([a-z, \s]*[;}]?)/g;
+var _3=dojox.html._adjustCssPaths=function(_4,_5){
+if(!_5||!_4){
+return;
+}
+if(_1){
+_5=_5.replace(_1,function(_6,_7,_8,_9,_a){
+return _7+(new dojo._Url(_4,"./"+_9).toString())+_a;
+});
+}
+return _5.replace(_2,function(_b,_c,_d,_e,_f,_10){
+if(_d){
+return "@import \""+(new dojo._Url(_4,"./"+_d).toString())+"\""+_10;
+}else{
+return "url("+(new dojo._Url(_4,"./"+_f).toString())+")"+_10;
+}
+});
+};
+var _11=/(<[a-z][a-z0-9]*\s[^>]*)(?:(href|src)=(['"]?)([^>]*?)\3|style=(['"]?)([^>]*?)\5)([^>]*>)/gi;
+var _12=dojox.html._adjustHtmlPaths=function(_13,_14){
+var url=_13||"./";
+return _14.replace(_11,function(tag,_17,_18,_19,_1a,_1b,_1c,end){
+return _17+(_18?(_18+"="+_19+(new dojo._Url(url,_1a).toString())+_19):("style="+_1b+_3(url,_1c)+_1b))+end;
+});
+};
+var _1e=dojox.html._snarfStyles=function(_1f,_20,_21){
+_21.attributes=[];
+return _20.replace(/(?:<style([^>]*)>([\s\S]*?)<\/style>|<link\s+(?=[^>]*rel=['"]?stylesheet)([^>]*?href=(['"])([^>]*?)\4[^>\/]*)\/?>)/gi,function(_22,_23,_24,_25,_26,_27){
+var i,_29=(_23||_25||"").replace(/^\s*([\s\S]*?)\s*$/i,"$1");
+if(_24){
+i=_21.push(_1f?_3(_1f,_24):_24);
+}else{
+i=_21.push("@import \""+_27+"\";");
+_29=_29.replace(/\s*(?:rel|href)=(['"])?[^\s]*\1\s*/gi,"");
+}
+if(_29){
+_29=_29.split(/\s+/);
+var _2a={},tmp;
+for(var j=0,e=_29.length;j<e;j++){
+tmp=_29[j].split("=");
+_2a[tmp[0]]=tmp[1].replace(/^\s*['"]?([\s\S]*?)['"]?\s*$/,"$1");
+}
+_21.attributes[i-1]=_2a;
+}
+return "";
+});
+};
+var _2e=dojox.html._snarfScripts=function(_2f,_30){
+_30.code="";
+function _31(src){
+if(_30.downloadRemote){
+dojo.xhrGet({url:src,sync:true,load:function(_33){
+_30.code+=_33+";";
+},error:_30.errBack});
+}
+};
+return _2f.replace(/<script\s*(?![^>]*type=['"]?dojo)(?:[^>]*?(?:src=(['"]?)([^>]*?)\1[^>]*)?)*>([\s\S]*?)<\/script>/gi,function(_34,_35,src,_37){
+if(src){
+_31(src);
+}else{
+_30.code+=_37;
+}
+return "";
+});
+};
+var _38=dojox.html.evalInGlobal=function(_39,_3a){
+_3a=_3a||dojo.doc.body;
+var n=_3a.ownerDocument.createElement("script");
+n.type="text/javascript";
+_3a.appendChild(n);
+n.text=_39;
+};
+dojo.declare("dojox.html._ContentSetter",[dojo.html._ContentSetter],{adjustPaths:false,referencePath:".",renderStyles:false,executeScripts:false,scriptHasHooks:false,scriptHookReplacement:null,_renderStyles:function(_3c){
+this._styleNodes=[];
+var st,att,_3f,doc=this.node.ownerDocument;
+var _41=doc.getElementsByTagName("head")[0];
+for(var i=0,e=_3c.length;i<e;i++){
+_3f=_3c[i];
+att=_3c.attributes[i];
+st=doc.createElement("style");
+st.setAttribute("type","text/css");
+for(var x in att){
+st.setAttribute(x,att[x]);
+}
+this._styleNodes.push(st);
+_41.appendChild(st);
+if(st.styleSheet){
+st.styleSheet.cssText=_3f;
+}else{
+st.appendChild(doc.createTextNode(_3f));
+}
+}
+},empty:function(){
+this.inherited("empty",arguments);
+this._styles=[];
+},onBegin:function(){
+this.inherited("onBegin",arguments);
+var _45=this.content,_46=this.node;
+var _47=this._styles;
+if(dojo.isString(_45)){
+if(this.adjustPaths&&this.referencePath){
+_45=_12(this.referencePath,_45);
+}
+if(this.renderStyles||this.cleanContent){
+_45=_1e(this.referencePath,_45,_47);
+}
+if(this.executeScripts){
+var _t=this;
+var _49={downloadRemote:true,errBack:function(e){
+_t._onError.call(_t,"Exec","Error downloading remote script in \""+_t.id+"\"",e);
+}};
+_45=_2e(_45,_49);
+this._code=_49.code;
+}
+}
+this.content=_45;
+},onEnd:function(){
+var _4b=this._code,_4c=this._styles;
+if(this._styleNodes&&this._styleNodes.length){
+while(this._styleNodes.length){
+dojo.destroy(this._styleNodes.pop());
+}
+}
+if(this.renderStyles&&_4c&&_4c.length){
+this._renderStyles(_4c);
+}
+if(this.executeScripts&&_4b){
+if(this.cleanContent){
+_4b=_4b.replace(/(<!--|(?:\/\/)?-->|<!\[CDATA\[|\]\]>)/g,"");
+}
+if(this.scriptHasHooks){
+_4b=_4b.replace(/_container_(?!\s*=[^=])/g,this.scriptHookReplacement);
+}
+try{
+_38(_4b,this.node);
+}
+catch(e){
+this._onError("Exec","Error eval script in "+this.id+", "+e.message,e);
+}
+}
+this.inherited("onEnd",arguments);
+},tearDown:function(){
+this.inherited(arguments);
+delete this._styles;
+if(this._styleNodes&&this._styleNodes.length){
+while(this._styleNodes.length){
+dojo.destroy(this._styleNodes.pop());
+}
+}
+delete this._styleNodes;
+dojo.mixin(this,dojo.getObject(this.declaredClass).prototype);
+}});
+dojox.html.set=function(_4d,_4e,_4f){
+if(!_4f){
+return dojo.html._setNodeContent(_4d,_4e,true);
+}else{
+var op=new dojox.html._ContentSetter(dojo.mixin(_4f,{content:_4e,node:_4d}));
+return op.set();
+}
+};
+})();
+}
diff --git a/dojox/html/metrics.js b/dojox/html/metrics.js
new file mode 100644
index 0000000..20dbd1e
--- /dev/null
+++ b/dojox/html/metrics.js
@@ -0,0 +1,141 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.html.metrics"]){
+dojo._hasResource["dojox.html.metrics"]=true;
+dojo.provide("dojox.html.metrics");
+(function(){
+var _1=dojox.html.metrics;
+_1.getFontMeasurements=function(){
+var _2={"1em":0,"1ex":0,"100%":0,"12pt":0,"16px":0,"xx-small":0,"x-small":0,"small":0,"medium":0,"large":0,"x-large":0,"xx-large":0};
+if(dojo.isIE){
+dojo.doc.documentElement.style.fontSize="100%";
+}
+var _3=dojo.doc.createElement("div");
+var ds=_3.style;
+ds.position="absolute";
+ds.left="-100px";
+ds.top="0";
+ds.width="30px";
+ds.height="1000em";
+ds.border="0";
+ds.margin="0";
+ds.padding="0";
+ds.outline="0";
+ds.lineHeight="1";
+ds.overflow="hidden";
+dojo.body().appendChild(_3);
+for(var p in _2){
+ds.fontSize=p;
+_2[p]=Math.round(_3.offsetHeight*12/16)*16/12/1000;
+}
+dojo.body().removeChild(_3);
+_3=null;
+return _2;
+};
+var _6=null;
+_1.getCachedFontMeasurements=function(_7){
+if(_7||!_6){
+_6=_1.getFontMeasurements();
+}
+return _6;
+};
+var _8=null,_9={};
+_1.getTextBox=function(_a,_b,_c){
+var m;
+if(!_8){
+m=_8=dojo.doc.createElement("div");
+m.style.position="absolute";
+m.style.left="-10000px";
+m.style.top="0";
+dojo.body().appendChild(m);
+}else{
+m=_8;
+}
+m.className="";
+m.style.border="0";
+m.style.margin="0";
+m.style.padding="0";
+m.style.outline="0";
+if(arguments.length>1&&_b){
+for(var i in _b){
+if(i in _9){
+continue;
+}
+m.style[i]=_b[i];
+}
+}
+if(arguments.length>2&&_c){
+m.className=_c;
+}
+m.innerHTML=_a;
+return dojo.marginBox(m);
+};
+var _f={w:16,h:16};
+_1.getScrollbar=function(){
+return {w:_f.w,h:_f.h};
+};
+_1._fontResizeNode=null;
+_1.initOnFontResize=function(_10){
+var f=_1._fontResizeNode=dojo.doc.createElement("iframe");
+var fs=f.style;
+fs.position="absolute";
+fs.width="5em";
+fs.height="10em";
+fs.top="-10000px";
+if(dojo.isIE){
+f.onreadystatechange=function(){
+if(f.contentWindow.document.readyState=="complete"){
+f.onresize=f.contentWindow.parent[dojox._scopeName].html.metrics._fontresize;
+}
+};
+}else{
+f.onload=function(){
+f.contentWindow.onresize=f.contentWindow.parent[dojox._scopeName].html.metrics._fontresize;
+};
+}
+f.setAttribute("src","javascript:'<html><head><script>if(\"loadFirebugConsole\" in window){window.loadFirebugConsole();}</script></head><body></body></html>'");
+dojo.body().appendChild(f);
+_1.initOnFontResize=function(){
+};
+};
+_1.onFontResize=function(){
+};
+_1._fontresize=function(){
+_1.onFontResize();
+};
+dojo.addOnUnload(function(){
+var f=_1._fontResizeNode;
+if(f){
+if(dojo.isIE&&f.onresize){
+f.onresize=null;
+}else{
+if(f.contentWindow&&f.contentWindow.onresize){
+f.contentWindow.onresize=null;
+}
+}
+_1._fontResizeNode=null;
+}
+});
+dojo.addOnLoad(function(){
+try{
+var n=dojo.doc.createElement("div");
+n.style.cssText="top:0;left:0;width:100px;height:100px;overflow:scroll;position:absolute;visibility:hidden;";
+dojo.body().appendChild(n);
+_f.w=n.offsetWidth-n.clientWidth;
+_f.h=n.offsetHeight-n.clientHeight;
+dojo.body().removeChild(n);
+delete n;
+}
+catch(e){
+}
+if("fontSizeWatch" in dojo.config&&!!dojo.config.fontSizeWatch){
+_1.initOnFontResize();
+}
+});
+})();
+}
diff --git a/dojox/html/styles.js b/dojox/html/styles.js
new file mode 100644
index 0000000..71078d9
--- /dev/null
+++ b/dojox/html/styles.js
@@ -0,0 +1,194 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.html.styles"]){
+dojo._hasResource["dojox.html.styles"]=true;
+dojo.provide("dojox.html.styles");
+(function(){
+var _1={};
+var _2={};
+var _3=[];
+var _4=[];
+dojox.html.insertCssRule=function(_5,_6,_7){
+var ss=dojox.html.getDynamicStyleSheet(_7);
+var _9=_5+" {"+_6+"}";
+
+if(dojo.isIE){
+ss.cssText+=_9;
+
+}else{
+if(ss.sheet){
+ss.sheet.insertRule(_9,ss._indicies.length);
+}else{
+ss.appendChild(dojo.doc.createTextNode(_9));
+}
+}
+ss._indicies.push(_5+" "+_6);
+return _5;
+};
+dojox.html.removeCssRule=function(_a,_b,_c){
+var ss;
+var _e=-1;
+for(var nm in _1){
+if(_c&&_c!=nm){
+continue;
+}
+ss=_1[nm];
+for(var i=0;i<ss._indicies.length;i++){
+if(_a+" "+_b==ss._indicies[i]){
+_e=i;
+break;
+}
+}
+if(_e>-1){
+break;
+}
+}
+if(!ss){
+
+return false;
+}
+if(_e==-1){
+
+return false;
+}
+ss._indicies.splice(_e,1);
+if(dojo.isIE){
+ss.removeRule(_e);
+}else{
+if(ss.sheet){
+ss.sheet.deleteRule(_e);
+}else{
+if(document.styleSheets[0]){
+
+}
+}
+}
+return true;
+};
+dojox.html.getStyleSheet=function(_11){
+if(_1[_11||"default"]){
+return _1[_11||"default"];
+}
+if(!_11){
+return false;
+}
+var _12=dojox.html.getStyleSheets();
+if(_12[_11]){
+return dojox.html.getStyleSheets()[_11];
+}
+for(var nm in _12){
+if(_12[nm].href&&_12[nm].href.indexOf(_11)>-1){
+return _12[nm];
+}
+}
+return false;
+};
+dojox.html.getDynamicStyleSheet=function(_14){
+if(!_14){
+_14="default";
+}
+if(!_1[_14]){
+if(dojo.doc.createStyleSheet){
+_1[_14]=dojo.doc.createStyleSheet();
+_1[_14].title=_14;
+}else{
+_1[_14]=dojo.doc.createElement("style");
+_1[_14].setAttribute("type","text/css");
+dojo.doc.getElementsByTagName("head")[0].appendChild(_1[_14]);
+
+}
+_1[_14]._indicies=[];
+}
+return _1[_14];
+};
+dojox.html.enableStyleSheet=function(_15){
+var ss=dojox.html.getStyleSheet(_15);
+if(ss){
+if(ss.sheet){
+ss.sheet.disabled=false;
+}else{
+ss.disabled=false;
+}
+}
+};
+dojox.html.disableStyleSheet=function(_17){
+var ss=dojox.html.getStyleSheet(_17);
+if(ss){
+if(ss.sheet){
+ss.sheet.disabled=true;
+}else{
+ss.disabled=true;
+}
+}
+};
+dojox.html.activeStyleSheet=function(_19){
+var _1a=dojox.html.getToggledStyleSheets();
+if(arguments.length==1){
+dojo.forEach(_1a,function(s){
+s.disabled=(s.title==_19)?false:true;
+});
+}else{
+for(var i=0;i<_1a.length;i++){
+if(_1a[i].disabled==false){
+return _1a[i];
+}
+}
+}
+return true;
+};
+dojox.html.getPreferredStyleSheet=function(){
+};
+dojox.html.getToggledStyleSheets=function(){
+if(!_3.length){
+var _1d=dojox.html.getStyleSheets();
+for(var nm in _1d){
+if(_1d[nm].title){
+_3.push(_1d[nm]);
+}
+}
+}
+return _3;
+};
+dojox.html.getStyleSheets=function(){
+if(_2.collected){
+return _2;
+}
+var _1f=dojo.doc.styleSheets;
+dojo.forEach(_1f,function(n){
+var s=(n.sheet)?n.sheet:n;
+var _22=s.title||s.href;
+if(dojo.isIE){
+if(s.cssText.indexOf("#default#VML")==-1){
+if(s.href){
+_2[_22]=s;
+}else{
+if(s.imports.length){
+dojo.forEach(s.imports,function(si){
+_2[si.title||si.href]=si;
+});
+}else{
+_2[_22]=s;
+}
+}
+}
+}else{
+_2[_22]=s;
+_2[_22].id=s.ownerNode.id;
+dojo.forEach(s.cssRules,function(r){
+if(r.href){
+_2[r.href]=r.styleSheet;
+_2[r.href].id=s.ownerNode.id;
+}
+});
+}
+});
+_2.collected=true;
+return _2;
+};
+})();
+}
diff --git a/dojox/image.js b/dojox/image.js
new file mode 100644
index 0000000..8d40a54
--- /dev/null
+++ b/dojox/image.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.image"]){
+dojo._hasResource["dojox.image"]=true;
+dojo.provide("dojox.image");
+dojo.require("dojox.image._base");
+}
diff --git a/dojox/image/Badge.js b/dojox/image/Badge.js
new file mode 100644
index 0000000..5ca3839
--- /dev/null
+++ b/dojox/image/Badge.js
@@ -0,0 +1,103 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.image.Badge"]){
+dojo._hasResource["dojox.image.Badge"]=true;
+dojo.provide("dojox.image.Badge");
+dojo.experimental("dojox.image.Badge");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dojo.fx.easing");
+dojo.declare("dojox.image.Badge",[dijit._Widget,dijit._Templated],{baseClass:"dojoxBadge",templateString:"<div class=\"dojoxBadge\" dojoAttachPoint=\"containerNode\"></div>",children:"div.dojoxBadgeImage",rows:4,cols:5,cellSize:50,delay:2000,threads:1,easing:"dojo.fx.easing.backOut",startup:function(){
+if(this._started){
+return;
+}
+if(dojo.isString(this.easing)){
+this.easing=dojo.getObject(this.easing);
+}
+this.inherited(arguments);
+this._init();
+},_init:function(){
+var _1=0,_w=this.cellSize;
+dojo.style(this.domNode,{width:_w*this.cols+"px",height:_w*this.rows+"px"});
+this._nl=dojo.query(this.children,this.containerNode).forEach(function(n,_4){
+var _5=_4%this.cols,t=_1*_w,l=_5*_w;
+dojo.style(n,{top:t+"px",left:l+"px",width:_w-2+"px",height:_w-2+"px"});
+if(_5==this.cols-1){
+_1++;
+}
+dojo.addClass(n,this.baseClass+"Image");
+},this);
+var l=this._nl.length;
+while(this.threads--){
+var s=Math.floor(Math.random()*l);
+setTimeout(dojo.hitch(this,"_enbiggen",{target:this._nl[s]}),this.delay*this.threads);
+}
+},_getCell:function(n){
+var _b=this._nl.indexOf(n);
+if(_b>=0){
+var _c=_b%this.cols;
+var _d=Math.floor(_b/this.cols);
+return {x:_c,y:_d,n:this._nl[_b],io:_b};
+}else{
+return undefined;
+}
+},_getImage:function(){
+return "url('')";
+},_enbiggen:function(e){
+var _f=this._getCell(e.target||e);
+if(_f){
+var _cc=(this.cellSize*2)-2;
+var _11={height:_cc,width:_cc};
+var _12=function(){
+return Math.round(Math.random());
+};
+if(_f.x==this.cols-1||(_f.x>0&&_12())){
+_11.left=this.cellSize*(_f.x-1);
+}
+if(_f.y==this.rows-1||(_f.y>0&&_12())){
+_11.top=this.cellSize*(_f.y-1);
+}
+var bc=this.baseClass;
+dojo.addClass(_f.n,bc+"Top");
+dojo.addClass(_f.n,bc+"Seen");
+dojo.animateProperty({node:_f.n,properties:_11,onEnd:dojo.hitch(this,"_loadUnder",_f,_11),easing:this.easing}).play();
+}
+},_loadUnder:function(_14,_15){
+var idx=_14.io;
+var _17=[];
+var _18=(_15.left>=0);
+var _19=(_15.top>=0);
+var c=this.cols,e=idx+(_18?-1:1),f=idx+(_19?-c:c),g=(_19?(_18?e-c:f+1):(_18?f-1:e+c)),bc=this.baseClass;
+dojo.forEach([e,f,g],function(x){
+var n=this._nl[x];
+if(n){
+if(dojo.hasClass(n,bc+"Seen")){
+dojo.removeClass(n,bc+"Seen");
+}
+}
+},this);
+setTimeout(dojo.hitch(this,"_disenbiggen",_14,_15),this.delay*1.25);
+},_disenbiggen:function(_21,_22){
+if(_22.top>=0){
+_22.top+=this.cellSize;
+}
+if(_22.left>=0){
+_22.left+=this.cellSize;
+}
+var _cc=this.cellSize-2;
+dojo.animateProperty({node:_21.n,properties:dojo.mixin(_22,{width:_cc,height:_cc}),onEnd:dojo.hitch(this,"_cycle",_21,_22)}).play(5);
+},_cycle:function(_24,_25){
+var bc=this.baseClass;
+dojo.removeClass(_24.n,bc+"Top");
+var ns=this._nl.filter(function(n){
+return !dojo.hasClass(n,bc+"Seen");
+});
+var c=ns[Math.floor(Math.random()*ns.length)];
+setTimeout(dojo.hitch(this,"_enbiggen",{target:c}),this.delay/2);
+}});
+}
diff --git a/dojox/image/FlickrBadge.js b/dojox/image/FlickrBadge.js
new file mode 100644
index 0000000..d5da30d
--- /dev/null
+++ b/dojox/image/FlickrBadge.js
@@ -0,0 +1,60 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.image.FlickrBadge"]){
+dojo._hasResource["dojox.image.FlickrBadge"]=true;
+dojo.provide("dojox.image.FlickrBadge");
+dojo.require("dojox.image.Badge");
+dojo.require("dojox.data.FlickrRestStore");
+dojo.declare("dojox.image.FlickrBadge",dojox.image.Badge,{children:"a.flickrImage",userid:"",username:"",setid:"",tags:"",searchText:"",target:"",apikey:"8c6803164dbc395fb7131c9d54843627",_store:null,postCreate:function(){
+if(this.username&&!this.userid){
+var _1=dojo.io.script.get({url:"http://www.flickr.com/services/rest/",preventCache:true,content:{format:"json",method:"flickr.people.findByUsername",api_key:this.apikey,username:this.username},callbackParamName:"jsoncallback"});
+_1.addCallback(this,function(_2){
+if(_2.user&&_2.user.nsid){
+this.userid=_2.user.nsid;
+if(!this._started){
+this.startup();
+}
+}
+});
+}
+},startup:function(){
+if(this._started){
+return;
+}
+if(this.userid){
+var _3={userid:this.userid};
+if(this.setid){
+_3["setid"]=this.setid;
+}
+if(this.tags){
+_3.tags=this.tags;
+}
+if(this.searchText){
+_3.text=this.searchText;
+}
+var _4=arguments;
+this._store=new dojox.data.FlickrRestStore({apikey:this.apikey});
+this._store.fetch({count:this.cols*this.rows,query:_3,onComplete:dojo.hitch(this,function(_5){
+dojo.forEach(_5,function(_6){
+var a=dojo.doc.createElement("a");
+dojo.addClass(a,"flickrImage");
+a.href=this._store.getValue(_6,"link");
+if(this.target){
+a.target=this.target;
+}
+var _8=dojo.doc.createElement("img");
+_8.src=this._store.getValue(_6,"imageUrlThumb");
+dojo.style(_8,{width:"100%",height:"100%"});
+a.appendChild(_8);
+this.domNode.appendChild(a);
+},this);
+dojox.image.Badge.prototype.startup.call(this,_4);
+})});
+}
+}});
+}
diff --git a/dojox/image/Gallery.js b/dojox/image/Gallery.js
new file mode 100644
index 0000000..4b324ea
--- /dev/null
+++ b/dojox/image/Gallery.js
@@ -0,0 +1,60 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.image.Gallery"]){
+dojo._hasResource["dojox.image.Gallery"]=true;
+dojo.provide("dojox.image.Gallery");
+dojo.experimental("dojox.image.Gallery");
+dojo.require("dojo.fx");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dojox.image.ThumbnailPicker");
+dojo.require("dojox.image.SlideShow");
+dojo.declare("dojox.image.Gallery",[dijit._Widget,dijit._Templated],{imageHeight:375,imageWidth:500,pageSize:dojox.image.SlideShow.prototype.pageSize,autoLoad:true,linkAttr:"link",imageThumbAttr:"imageUrlThumb",imageLargeAttr:"imageUrl",titleAttr:"title",slideshowInterval:3,templateString:"<div dojoAttachPoint=\"outerNode\" class=\"imageGalleryWrapper\">\n\t<div dojoAttachPoint=\"thumbPickerNode\"></div>\n\t<div dojoAttachPoint=\"slideShowNode\"></div>\n</div>\n",postCreate:function(){
+this.widgetid=this.id;
+this.inherited(arguments);
+this.thumbPicker=new dojox.image.ThumbnailPicker({linkAttr:this.linkAttr,imageLargeAttr:this.imageLargeAttr,imageThumbAttr:this.imageThumbAttr,titleAttr:this.titleAttr,useLoadNotifier:true,size:this.imageWidth},this.thumbPickerNode);
+this.slideShow=new dojox.image.SlideShow({imageHeight:this.imageHeight,imageWidth:this.imageWidth,autoLoad:this.autoLoad,linkAttr:this.linkAttr,imageLargeAttr:this.imageLargeAttr,titleAttr:this.titleAttr,slideshowInterval:this.slideshowInterval,pageSize:this.pageSize},this.slideShowNode);
+var _1=this;
+dojo.subscribe(this.slideShow.getShowTopicName(),function(_2){
+_1.thumbPicker._showThumbs(_2.index);
+});
+dojo.subscribe(this.thumbPicker.getClickTopicName(),function(_3){
+_1.slideShow.showImage(_3.index);
+});
+dojo.subscribe(this.thumbPicker.getShowTopicName(),function(_4){
+_1.slideShow.moveImageLoadingPointer(_4.index);
+});
+dojo.subscribe(this.slideShow.getLoadTopicName(),function(_5){
+_1.thumbPicker.markImageLoaded(_5);
+});
+this._centerChildren();
+},setDataStore:function(_6,_7,_8){
+this.thumbPicker.setDataStore(_6,_7,_8);
+this.slideShow.setDataStore(_6,_7,_8);
+},reset:function(){
+this.slideShow.reset();
+this.thumbPicker.reset();
+},showNextImage:function(_9){
+this.slideShow.showNextImage();
+},toggleSlideshow:function(){
+this.slideShow.toggleSlideshow();
+},showImage:function(_a,_b){
+this.slideShow.showImage(_a,_b);
+},_centerChildren:function(){
+var _c=dojo.marginBox(this.thumbPicker.outerNode);
+var _d=dojo.marginBox(this.slideShow.outerNode);
+var _e=(_c.w-_d.w)/2;
+if(_e>0){
+dojo.style(this.slideShow.outerNode,"marginLeft",_e+"px");
+}else{
+if(_e<0){
+dojo.style(this.thumbPicker.outerNode,"marginLeft",(_e*-1)+"px");
+}
+}
+}});
+}
diff --git a/dojox/image/Lightbox.js b/dojox/image/Lightbox.js
new file mode 100644
index 0000000..e57065b
--- /dev/null
+++ b/dojox/image/Lightbox.js
@@ -0,0 +1,246 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.image.Lightbox"]){
+dojo._hasResource["dojox.image.Lightbox"]=true;
+dojo.provide("dojox.image.Lightbox");
+dojo.experimental("dojox.image.Lightbox");
+dojo.require("dijit.Dialog");
+dojo.require("dojox.fx._base");
+dojo.declare("dojox.image.Lightbox",dijit._Widget,{group:"",title:"",href:"",duration:500,modal:false,_allowPassthru:false,_attachedDialog:null,startup:function(){
+this.inherited(arguments);
+var _1=dijit.byId("dojoxLightboxDialog");
+if(_1){
+this._attachedDialog=_1;
+}else{
+this._attachedDialog=new dojox.image.LightboxDialog({id:"dojoxLightboxDialog"});
+this._attachedDialog.startup();
+}
+if(!this.store){
+this._addSelf();
+this.connect(this.domNode,"onclick","_handleClick");
+}
+},_addSelf:function(){
+this._attachedDialog.addImage({href:this.href,title:this.title},this.group||null);
+},_handleClick:function(e){
+if(!this._allowPassthru){
+e.preventDefault();
+}else{
+return;
+}
+this.show();
+},show:function(){
+this._attachedDialog.show(this);
+},hide:function(){
+this._attachedDialog.hide();
+},disable:function(){
+this._allowPassthru=true;
+},enable:function(){
+this._allowPassthru=false;
+},onClick:function(){
+}});
+dojo.declare("dojox.image.LightboxDialog",dijit.Dialog,{title:"",inGroup:null,imgUrl:dijit._Widget.prototype._blankGif,errorMessage:"Image not found.",adjust:true,modal:false,_groups:{XnoGroupX:[]},errorImg:dojo.moduleUrl("dojox.image","resources/images/warning.png"),_fixSizes:false,templateString:"<div class=\"dojoxLightbox\" dojoAttachPoint=\"containerNode\">\n\t<div style=\"position:relative\">\n\t\t<div dojoAttachPoint=\"imageContainer\" class=\"dojoxLightboxContainer\" dojoAttachEve [...]
+this.inherited(arguments);
+this._animConnects=[];
+this.connect(this.nextNode,"onclick","_nextImage");
+this.connect(this.prevNode,"onclick","_prevImage");
+this.connect(this.closeNode,"onclick","hide");
+this._makeAnims();
+this._vp=dijit.getViewport();
+return this;
+},show:function(_3){
+var _t=this;
+this._lastGroup=_3;
+if(!_t.open){
+_t.inherited(arguments);
+this._modalconnects.push(dojo.connect(dojo.global,"onscroll",this,"_position"),dojo.connect(dojo.global,"onresize",this,"_position"),dojo.connect(dojo.body(),"onkeypress",this,"_handleKey"));
+if(!_3.modal){
+this._modalconnects.push(dojo.connect(dijit._underlay.domNode,"onclick",this,"onCancel"));
+}
+}
+if(this._wasStyled){
+dojo.destroy(_t.imgNode);
+_t.imgNode=dojo.create("img",null,_t.imageContainer,"first");
+_t._makeAnims();
+_t._wasStyled=false;
+}
+dojo.style(_t.imgNode,"opacity","0");
+dojo.style(_t.titleNode,"opacity","0");
+var _5=_3.href;
+if((_3.group&&_3!=="XnoGroupX")||_t.inGroup){
+if(!_t.inGroup){
+_t.inGroup=_t._groups[(_3.group)];
+dojo.forEach(_t.inGroup,function(g,i){
+if(g.href==_3.href){
+_t._index=i;
+}
+},_t);
+}
+if(!_t._index){
+_t._index=0;
+_5=_t.inGroup[_t._index].href;
+}
+_t.groupCount.innerHTML=" ("+(_t._index+1)+" of "+_t.inGroup.length+")";
+_t.prevNode.style.visibility="visible";
+_t.nextNode.style.visibility="visible";
+}else{
+_t.groupCount.innerHTML="";
+_t.prevNode.style.visibility="hidden";
+_t.nextNode.style.visibility="hidden";
+}
+if(!_3.leaveTitle){
+_t.textNode.innerHTML=_3.title;
+}
+_t._ready(_5);
+},_ready:function(_8){
+var _t=this;
+_t._imgError=dojo.connect(_t.imgNode,"error",_t,function(){
+dojo.disconnect(_t._imgError);
+_t.imgNode.src=_t.errorImg;
+_t.textNode.innerHTML=_t.errorMessage;
+});
+_t._imgConnect=dojo.connect(_t.imgNode,"load",_t,function(e){
+_t.resizeTo({w:_t.imgNode.width,h:_t.imgNode.height,duration:_t.duration});
+dojo.disconnect(_t._imgConnect);
+if(_t._imgError){
+dojo.disconnect(_t._imgError);
+}
+});
+_t.imgNode.src=_8;
+},_nextImage:function(){
+if(!this.inGroup){
+return;
+}
+if(this._index+1<this.inGroup.length){
+this._index++;
+}else{
+this._index=0;
+}
+this._loadImage();
+},_prevImage:function(){
+if(this.inGroup){
+if(this._index==0){
+this._index=this.inGroup.length-1;
+}else{
+this._index--;
+}
+this._loadImage();
+}
+},_loadImage:function(){
+this._loadingAnim.play(1);
+},_prepNodes:function(){
+this._imageReady=false;
+this.show({href:this.inGroup[this._index].href,title:this.inGroup[this._index].title});
+},resizeTo:function(_b,_c){
+var _d=dojo.boxModel=="border-box"?dojo._getBorderExtents(this.domNode).w:0,_e=_c||{h:30};
+this._lastTitleSize=_e;
+if(this.adjust&&(_b.h+_e.h+_d+80>this._vp.h||_b.w+_d+60>this._vp.w)){
+this._lastSize=_b;
+_b=this._scaleToFit(_b);
+}
+this._currentSize=_b;
+var _f=dojox.fx.sizeTo({node:this.containerNode,duration:_b.duration||this.duration,width:_b.w+_d,height:_b.h+_e.h+_d});
+this.connect(_f,"onEnd","_showImage");
+_f.play(15);
+},_scaleToFit:function(_10){
+var ns={};
+if(this._vp.h>this._vp.w){
+ns.w=this._vp.w-80;
+ns.h=ns.w*(_10.h/_10.w);
+}else{
+ns.h=this._vp.h-60-this._lastTitleSize.h;
+ns.w=ns.h*(_10.w/_10.h);
+}
+this._wasStyled=true;
+this._setImageSize(ns);
+ns.duration=_10.duration;
+return ns;
+},_setImageSize:function(_12){
+var s=this.imgNode;
+s.height=_12.h;
+s.width=_12.w;
+},_size:function(){
+},_position:function(e){
+this._vp=dijit.getViewport();
+this.inherited(arguments);
+if(e&&e.type=="resize"){
+if(this._wasStyled){
+this._setImageSize(this._lastSize);
+this.resizeTo(this._lastSize);
+}else{
+if(this.imgNode.height+80>this._vp.h||this.imgNode.width+60>this._vp.h){
+this.resizeTo({w:this.imgNode.width,h:this.imgNode.height});
+}
+}
+}
+},_showImage:function(){
+this._showImageAnim.play(1);
+},_showNav:function(){
+var _15=dojo.marginBox(this.titleNode);
+if(_15.h>this._lastTitleSize.h){
+this.resizeTo(this._wasStyled?this._lastSize:this._currentSize,_15);
+}else{
+this._showNavAnim.play(1);
+}
+},hide:function(){
+dojo.fadeOut({node:this.titleNode,duration:200,onEnd:dojo.hitch(this,function(){
+this.imgNode.src=this._blankGif;
+})}).play(5);
+this.inherited(arguments);
+this.inGroup=null;
+this._index=null;
+},addImage:function(_16,_17){
+var g=_17;
+if(!_16.href){
+return;
+}
+if(g){
+if(!this._groups[g]){
+this._groups[g]=[];
+}
+this._groups[g].push(_16);
+}else{
+this._groups["XnoGroupX"].push(_16);
+}
+},_handleKey:function(e){
+if(!this.open){
+return;
+}
+var dk=dojo.keys;
+switch(e.charOrCode){
+case dk.ESCAPE:
+this.hide();
+break;
+case dk.DOWN_ARROW:
+case dk.RIGHT_ARROW:
+case 78:
+this._nextImage();
+break;
+case dk.UP_ARROW:
+case dk.LEFT_ARROW:
+case 80:
+this._prevImage();
+break;
+}
+},_makeAnims:function(){
+dojo.forEach(this._animConnects,dojo.disconnect);
+this._animConnects=[];
+this._showImageAnim=dojo.fadeIn({node:this.imgNode,duration:this.duration});
+this._animConnects.push(dojo.connect(this._showImageAnim,"onEnd",this,"_showNav"));
+this._loadingAnim=dojo.fx.combine([dojo.fadeOut({node:this.imgNode,duration:175}),dojo.fadeOut({node:this.titleNode,duration:175})]);
+this._animConnects.push(dojo.connect(this._loadingAnim,"onEnd",this,"_prepNodes"));
+this._showNavAnim=dojo.fadeIn({node:this.titleNode,duration:225});
+},onClick:function(_1b){
+},_onImageClick:function(e){
+if(e&&e.target==this.imgNode){
+this.onClick(this._lastGroup);
+if(this._lastGroup.declaredClass){
+this._lastGroup.onClick(this._lastGroup);
+}
+}
+}});
+}
diff --git a/dojox/image/LightboxNano.js b/dojox/image/LightboxNano.js
new file mode 100644
index 0000000..0e05c88
--- /dev/null
+++ b/dojox/image/LightboxNano.js
@@ -0,0 +1,110 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.image.LightboxNano"]){
+dojo._hasResource["dojox.image.LightboxNano"]=true;
+dojo.provide("dojox.image.LightboxNano");
+dojo.require("dojo.fx");
+(function(d){
+var _2=function(){
+var _3=(d.doc.compatMode=="BackCompat")?d.body():d.doc.documentElement,_4=dojo._docScroll();
+return {w:_3.clientWidth,h:_3.clientHeight,l:_4.x,t:_4.y};
+},_5="absolute";
+d.declare("dojox.image.LightboxNano",null,{href:"",duration:500,preloadDelay:5000,constructor:function(p,n){
+var _8=this;
+d.mixin(_8,p);
+n=dojo.byId(n);
+if(!/a/i.test(n.tagName)){
+var a=d.create("a",{href:_8.href,"class":n.className},n,"after");
+n.className="";
+a.appendChild(n);
+n=a;
+}
+d.style(n,{display:"block",position:"relative"});
+_8._createDiv("dojoxEnlarge",n);
+_8._node=n;
+d.setSelectable(n,false);
+_8._onClickEvt=d.connect(n,"onclick",_8,"_load");
+setTimeout(function(){
+(new Image()).src=_8.href;
+_8._hideLoading();
+},_8.preloadDelay);
+},destroy:function(){
+var a=this._connects||[];
+a.push(this._onClickEvt);
+d.forEach(a,d.disconnect);
+d.destroy(this._node);
+},_createDiv:function(_b,_c,_d){
+return d.create("div",{"class":_b,style:{position:_5,display:_d?"":"none"}},_c);
+},_load:function(e){
+var _f=this;
+d.stopEvent(e);
+if(!_f._loading){
+_f._loading=true;
+_f._reset();
+var n=d.query("img",_f._node)[0],a=d._abs(n,true),c=d.contentBox(n),b=d._getBorderExtents(n),i=_f._img=d.create("img",{style:{visibility:"hidden",cursor:"pointer",position:_5,top:0,left:0,zIndex:9999999}},d.body()),ln=_f._loadingNode;
+if(ln==null){
+_f._loadingNode=ln=_f._createDiv("dojoxLoading",_f._node,true);
+var l=d.marginBox(ln);
+d.style(ln,{left:parseInt((c.w-l.w)/2)+"px",top:parseInt((c.h-l.h)/2)+"px"});
+}
+c.x=a.x-10+b.l;
+c.y=a.y-10+b.t;
+_f._start=c;
+_f._connects=[d.connect(i,"onload",_f,"_show")];
+i.src=_f.href;
+}
+},_hideLoading:function(){
+if(this._loadingNode){
+d.style(this._loadingNode,"display","none");
+}
+this._loadingNode=false;
+},_show:function(){
+var _17=this,vp=_2(),w=_17._img.width,h=_17._img.height,vpw=parseInt((vp.w-20)*0.9),vph=parseInt((vp.h-20)*0.9),dd=d.doc,bg=_17._bg=d.create("div",{style:{backgroundColor:"#000",opacity:0,position:_5,zIndex:9999998}},d.body()),ln=_17._loadingNode;
+if(_17._loadingNode){
+_17._hideLoading();
+}
+d.style(_17._img,{border:"10px solid #fff",visibility:"visible"});
+d.style(_17._node,"visibility","hidden");
+_17._loading=false;
+_17._connects=_17._connects.concat([d.connect(dd,"onmousedown",_17,"_hide"),d.connect(dd,"onkeypress",_17,"_key"),d.connect(window,"onresize",_17,"_sizeBg")]);
+if(w>vpw){
+h=h*vpw/w;
+w=vpw;
+}
+if(h>vph){
+w=w*vph/h;
+h=vph;
+}
+_17._end={x:(vp.w-20-w)/2+vp.l,y:(vp.h-20-h)/2+vp.t,w:w,h:h};
+_17._sizeBg();
+d.fx.combine([_17._anim(_17._img,_17._coords(_17._start,_17._end)),_17._anim(bg,{opacity:0.5})]).play();
+},_sizeBg:function(){
+var dd=d.doc.documentElement;
+d.style(this._bg,{top:0,left:0,width:dd.scrollWidth+"px",height:dd.scrollHeight+"px"});
+},_key:function(e){
+d.stopEvent(e);
+this._hide();
+},_coords:function(s,e){
+return {left:{start:s.x,end:e.x},top:{start:s.y,end:e.y},width:{start:s.w,end:e.w},height:{start:s.h,end:e.h}};
+},_hide:function(){
+var _24=this;
+d.forEach(_24._connects,d.disconnect);
+_24._connects=[];
+d.fx.combine([_24._anim(_24._img,_24._coords(_24._end,_24._start),"_reset"),_24._anim(_24._bg,{opacity:0})]).play();
+},_reset:function(){
+d.style(this._node,"visibility","visible");
+d.forEach([this._img,this._bg],function(n){
+d.destroy(n);
+n=null;
+});
+this._node.focus();
+},_anim:function(_26,_27,_28){
+return d.animateProperty({node:_26,duration:this.duration,properties:_27,onEnd:_28?d.hitch(this,_28):null});
+}});
+})(dojo);
+}
diff --git a/dojox/image/Magnifier.js b/dojox/image/Magnifier.js
new file mode 100644
index 0000000..f4681d2
--- /dev/null
+++ b/dojox/image/Magnifier.js
@@ -0,0 +1,41 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.image.Magnifier"]){
+dojo._hasResource["dojox.image.Magnifier"]=true;
+dojo.provide("dojox.image.Magnifier");
+dojo.require("dojox.gfx");
+dojo.require("dojox.image.MagnifierLite");
+dojo.declare("dojox.image.Magnifier",[dojox.image.MagnifierLite],{_createGlass:function(){
+this.glassNode=dojo.doc.createElement("div");
+this.surfaceNode=this.glassNode.appendChild(dojo.doc.createElement("div"));
+dojo.addClass(this.glassNode,"glassNode");
+dojo.body().appendChild(this.glassNode);
+with(this.glassNode.style){
+height=this.glassSize+"px";
+width=this.glassSize+"px";
+}
+this.surface=dojox.gfx.createSurface(this.surfaceNode,this.glassSize,this.glassSize);
+this.img=this.surface.createImage({src:this.domNode.src,width:this._zoomSize.w,height:this._zoomSize.h});
+},_placeGlass:function(e){
+var x=e.pageX-2;
+var y=e.pageY-2;
+var _4=this.offset.x+this.offset.w+2;
+var _5=this.offset.y+this.offset.h+2;
+if(x<this.offset.x||y<this.offset.y||x>_4||y>_5){
+this._hideGlass();
+}else{
+this.inherited(arguments);
+}
+},_setImage:function(e){
+var _7=(e.pageX-this.offset.l)/this.offset.w;
+var _8=(e.pageY-this.offset.t)/this.offset.h;
+var x=(this._zoomSize.w*_7*-1)+(this.glassSize*_7);
+var y=(this._zoomSize.h*_8*-1)+(this.glassSize*_8);
+this.img.setShape({x:x,y:y});
+}});
+}
diff --git a/dojox/image/MagnifierLite.js b/dojox/image/MagnifierLite.js
new file mode 100644
index 0000000..ded4761
--- /dev/null
+++ b/dojox/image/MagnifierLite.js
@@ -0,0 +1,53 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.image.MagnifierLite"]){
+dojo._hasResource["dojox.image.MagnifierLite"]=true;
+dojo.provide("dojox.image.MagnifierLite");
+dojo.experimental("dojox.image.MagnifierLite");
+dojo.require("dijit._Widget");
+dojo.declare("dojox.image.MagnifierLite",dijit._Widget,{glassSize:125,scale:6,postCreate:function(){
+this.inherited(arguments);
+this._adjustScale();
+this._createGlass();
+this.connect(this.domNode,"onmouseenter","_showGlass");
+this.connect(this.glassNode,"onmousemove","_placeGlass");
+this.connect(this.img,"onmouseout","_hideGlass");
+this.connect(window,"onresize","_adjustScale");
+},_createGlass:function(){
+var _1=this.glassNode=dojo.doc.createElement("div");
+this.surfaceNode=_1.appendChild(dojo.doc.createElement("div"));
+dojo.addClass(_1,"glassNode");
+dojo.body().appendChild(_1);
+dojo.style(_1,{height:this.glassSize+"px",width:this.glassSize+"px"});
+this.img=dojo.clone(this.domNode);
+_1.appendChild(this.img);
+dojo.style(this.img,{position:"relative",top:0,left:0,width:this._zoomSize.w+"px",height:this._zoomSize.h+"px"});
+},_adjustScale:function(){
+this.offset=dojo.coords(this.domNode,true);
+this._imageSize={w:this.offset.w,h:this.offset.h};
+this._zoomSize={w:this._imageSize.w*this.scale,h:this._imageSize.h*this.scale};
+},_showGlass:function(e){
+this._placeGlass(e);
+dojo.style(this.glassNode,{visibility:"visible",display:""});
+},_hideGlass:function(e){
+dojo.style(this.glassNode,{visibility:"hidden",display:"none"});
+},_placeGlass:function(e){
+this._setImage(e);
+var _5=Math.floor(this.glassSize/2);
+dojo.style(this.glassNode,{top:Math.floor(e.pageY-_5)+"px",left:Math.floor(e.pageX-_5)+"px"});
+},_setImage:function(e){
+var _7=(e.pageX-this.offset.l)/this.offset.w;
+var _8=(e.pageY-this.offset.t)/this.offset.h;
+var x=(this._zoomSize.w*_7*-1)+(this.glassSize*_7);
+var y=(this._zoomSize.h*_8*-1)+(this.glassSize*_8);
+dojo.style(this.img,{top:y+"px",left:x+"px"});
+},destroy:function(_b){
+dojo.destroy(this.glassNode);
+this.inherited(arguments);
+}});
+}
diff --git a/dojox/image/README b/dojox/image/README
new file mode 100644
index 0000000..cbe32f3
--- /dev/null
+++ b/dojox/image/README
@@ -0,0 +1,88 @@
+-------------------------------------------------------------------------------
+dojox.image - Image Related Widgets and Components
+-------------------------------------------------------------------------------
+Version 1.0
+Release date: 10/31/07
+-------------------------------------------------------------------------------
+Project state:
+
+[Badge] experimental
+[FlickrBadge] experimental
+[Gallery] experimental
+[Lightbox] beta
+[Magnifier] experimental
+[MagnifierLite] experimental
+[SlideShow] experimental
+[ThumbnailPicker] experimental
+
+-------------------------------------------------------------------------------
+Credits
+
+[Badge] Peter Higgins (dante)
+[FlickrBadge] Bryan Forbes (BryanForbes)
+[Gallery] Shane O'Sullivan (sos)
+[Lightbox] Peter Higgins (dante)
+[Magnifier] Peter Higgins (dante)
+[MagnifierLite] Peter Higgins (dante)
+[SlideShow] Shane O'Sullivan (sos)
+[ThumbnailPicker] Shane O'Sullivan (sos)
+
+-------------------------------------------------------------------------------
+Project description 
+
+	A class to provide a common API for images, and home for image
+	related Widgets.
+ 
+-------------------------------------------------------------------------------
+Dependencies:
+
+	LightBox: dojo core, dojox.fx and optionally dojox.data. uses
+	either tundra or soria theme, no standalone icons.
+
+	SlideShow: dojo core, dojo.fx, and dojo.data (optional 
+	dojox.data store implementations apply)
+
+	ThumbNailPicker: dojo core, dojo.fx and dojo.data. Combined
+	with a SlideShow, creates a sample Gallery app.
+
+	Gallery: core, dojox.image.SlideShow, dojox.image.ThumbNailPicker
+
+	Magnifier: (prototype) dojo core, dijit._Widget, dojox.gfx
+	
+	Badge: (prototype) dojo core, dijit._Widget + _Templated 
+
+-------------------------------------------------------------------------------
+Documentation
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/dojo/dojox/trunk/image/*
+
+Install into the following directory structure:
+/dojox/image/
+
+...which should be at the same level as your Dojo checkout.
+-------------------------------------------------------------------------------
+Additional Notes
+
+	LightBox: currently works as individual items, and grouped items,
+	but usage of dojo.data is broken (atm). the API is subject to 
+ 	change, and is marked accordingly.
+
+	Hoping to implement: Carossel, and Reflect using
+	a common API provided by dojox.image.Pane (?) 
+
+	SlideShow: Shows an image, one by one, from a datastore. Acts
+	as standing ImagePane implementation, 
+
+	Gallery: A combination Thumbnail view and SlideShow, using
+	a datastore, and providing navigation, and common API. 
+
+	Magnifier: Unobtrusive way to attach a hovering window window
+	when moving the mouse over an image. The window shows a a zoomed
+	version of the original source. (prototype)
+
+	Badge: (prototype) A Javascript version of a FlickrBadge thingr, 
+	which loops through and sizes children in a loop.
diff --git a/dojox/image/SlideShow.js b/dojox/image/SlideShow.js
new file mode 100644
index 0000000..d60ec3f
--- /dev/null
+++ b/dojox/image/SlideShow.js
@@ -0,0 +1,371 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.image.SlideShow"]){
+dojo._hasResource["dojox.image.SlideShow"]=true;
+dojo.provide("dojox.image.SlideShow");
+dojo.require("dojo.string");
+dojo.require("dojo.fx");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.declare("dojox.image.SlideShow",[dijit._Widget,dijit._Templated],{imageHeight:375,imageWidth:500,title:"",titleTemplate:"${title} <span class=\"slideShowCounterText\">(${current} of ${total})</span>",noLink:false,loop:true,hasNav:true,images:[],pageSize:20,autoLoad:true,autoStart:false,fixedHeight:false,imageStore:null,linkAttr:"link",imageLargeAttr:"imageUrl",titleAttr:"title",slideshowInterval:3,templateString:"<div dojoAttachPoint=\"outerNode\" class=\"slideShowWrapper\">\n\t<div [...]
+this.inherited(arguments);
+var _1=document.createElement("img");
+_1.setAttribute("width",this.imageWidth);
+_1.setAttribute("height",this.imageHeight);
+if(this.hasNav){
+dojo.connect(this.outerNode,"onmouseover",this,function(_2){
+try{
+this._showNav();
+}
+catch(e){
+}
+});
+dojo.connect(this.outerNode,"onmouseout",this,function(_3){
+try{
+this._hideNav(_3);
+}
+catch(e){
+}
+});
+}
+this.outerNode.style.width=this.imageWidth+"px";
+_1.setAttribute("src",this._blankGif);
+var _4=this;
+this.largeNode.appendChild(_1);
+this._tmpImage=this._currentImage=_1;
+this._fitSize(true);
+this._loadImage(0,dojo.hitch(this,"showImage",0));
+this._calcNavDimensions();
+},setDataStore:function(_5,_6,_7){
+this.reset();
+var _8=this;
+this._request={query:{},start:_6.start||0,count:_6.count||this.pageSize,onBegin:function(_9,_a){
+_8.maxPhotos=_9;
+}};
+if(_6.query){
+dojo.mixin(this._request.query,_6.query);
+}
+if(_7){
+dojo.forEach(["imageLargeAttr","linkAttr","titleAttr"],function(_b){
+if(_7[_b]){
+this[_b]=_7[_b];
+}
+},this);
+}
+var _c=function(_d){
+_8.maxPhotos=_d.length;
+_8.showImage(0);
+_8._request.onComplete=null;
+if(_8.autoStart){
+_8.toggleSlideShow();
+}
+};
+this.imageStore=_5;
+this._request.onComplete=_c;
+this._request.start=0;
+this.imageStore.fetch(this._request);
+},reset:function(){
+while(this.largeNode.firstChild){
+this.largeNode.removeChild(this.largeNode.firstChild);
+}
+this.largeNode.appendChild(this._tmpImage);
+while(this.hiddenNode.firstChild){
+this.hiddenNode.removeChild(this.hiddenNode.firstChild);
+}
+dojo.forEach(this.images,function(_e){
+if(_e&&_e.parentNode){
+_e.parentNode.removeChild(_e);
+}
+});
+this.images=[];
+this.isInitialized=false;
+this._imageCounter=0;
+},isImageLoaded:function(_f){
+return this.images&&this.images.length>_f&&this.images[_f];
+},moveImageLoadingPointer:function(_10){
+this._imageCounter=_10;
+},destroy:function(){
+if(this._slideId){
+this._stop();
+}
+this.inherited(arguments);
+},showNextImage:function(_11,_12){
+if(_11&&this._timerCancelled){
+return false;
+}
+if(this.imageIndex+1>=this.maxPhotos){
+if(_11&&(this.loop||_12)){
+this.imageIndex=-1;
+}else{
+if(this._slideId){
+this._stop();
+}
+return false;
+}
+}
+this.showImage(this.imageIndex+1,dojo.hitch(this,function(){
+if(_11){
+this._startTimer();
+}
+}));
+return true;
+},toggleSlideShow:function(){
+if(this._slideId){
+this._stop();
+}else{
+dojo.toggleClass(this.domNode,"slideShowPaused");
+this._timerCancelled=false;
+if(this.images[this.imageIndex]&&this.images[this.imageIndex]._img.complete){
+var _13=this.showNextImage(true,true);
+if(!_13){
+this._stop();
+}
+}else{
+var idx=this.imageIndex;
+var _15=dojo.subscribe(this.getShowTopicName(),dojo.hitch(this,function(_16){
+setTimeout(dojo.hitch(this,function(){
+if(_16.index==idx){
+var _17=this.showNextImage(true,true);
+if(!_17){
+this._stop();
+}
+dojo.unsubscribe(_15);
+}
+}),this.slideshowInterval*1000);
+}));
+dojo.publish(this.getShowTopicName(),[{index:idx,title:"",url:""}]);
+}
+}
+},getShowTopicName:function(){
+return (this.widgetId||this.id)+"/imageShow";
+},getLoadTopicName:function(){
+return (this.widgetId?this.widgetId:this.id)+"/imageLoad";
+},showImage:function(_18,_19){
+if(!_19&&this._slideId){
+this.toggleSlideShow();
+}
+var _1a=this;
+var _1b=this.largeNode.getElementsByTagName("div");
+this.imageIndex=_18;
+var _1c=function(){
+if(_1a.images[_18]){
+while(_1a.largeNode.firstChild){
+_1a.largeNode.removeChild(_1a.largeNode.firstChild);
+}
+dojo.style(_1a.images[_18],"opacity",0);
+_1a.largeNode.appendChild(_1a.images[_18]);
+_1a._currentImage=_1a.images[_18]._img;
+_1a._fitSize();
+var _1d=function(a,b,c){
+var img=_1a.images[_18].firstChild;
+if(img.tagName.toLowerCase()!="img"){
+img=img.firstChild;
+}
+var _22=img.getAttribute("title")||"";
+if(_1a._navShowing){
+_1a._showNav(true);
+}
+dojo.publish(_1a.getShowTopicName(),[{index:_18,title:_22,url:img.getAttribute("src")}]);
+if(_19){
+_19(a,b,c);
+}
+_1a._setTitle(_22);
+};
+dojo.fadeIn({node:_1a.images[_18],duration:300,onEnd:_1d}).play();
+}else{
+_1a._loadImage(_18,function(){
+dojo.publish(_1a.getLoadTopicName(),[_18]);
+_1a.showImage(_18,_19);
+});
+}
+};
+if(_1b&&_1b.length>0){
+dojo.fadeOut({node:_1b[0],duration:300,onEnd:function(){
+_1a.hiddenNode.appendChild(_1b[0]);
+_1c();
+}}).play();
+}else{
+_1c();
+}
+},_fitSize:function(_23){
+if(!this.fixedHeight||_23){
+var _24=(this._currentImage.height+(this.hasNav?20:0));
+dojo.style(this.innerWrapper,"height",_24+"px");
+return;
+}
+dojo.style(this.largeNode,"paddingTop",this._getTopPadding()+"px");
+},_getTopPadding:function(){
+if(!this.fixedHeight){
+return 0;
+}
+return (this.imageHeight-this._currentImage.height)/2;
+},_loadNextImage:function(){
+if(!this.autoLoad){
+return;
+}
+while(this.images.length>=this._imageCounter&&this.images[this._imageCounter]){
+this._imageCounter++;
+}
+this._loadImage(this._imageCounter);
+},_loadImage:function(_25,_26){
+if(this.images[_25]||!this._request){
+return;
+}
+var _27=_25-(_25%this.pageSize);
+this._request.start=_27;
+this._request.onComplete=function(_28){
+var _29=_25-_27;
+if(_28&&_28.length>_29){
+_2a(_28[_29]);
+}else{
+}
+};
+var _2b=this;
+var _2a=function(_2c){
+var url=_2b.imageStore.getValue(_2c,_2b.imageLargeAttr);
+var img=new Image();
+var div=document.createElement("div");
+div._img=img;
+var _30=_2b.imageStore.getValue(_2c,_2b.linkAttr);
+if(!_30||_2b.noLink){
+div.appendChild(img);
+}else{
+var a=document.createElement("a");
+a.setAttribute("href",_30);
+a.setAttribute("target","_blank");
+div.appendChild(a);
+a.appendChild(img);
+}
+div.setAttribute("id",_2b.id+"_imageDiv"+_25);
+dojo.connect(img,"onload",function(){
+_2b._fitImage(img);
+div.setAttribute("width",_2b.imageWidth);
+div.setAttribute("height",_2b.imageHeight);
+dojo.publish(_2b.getLoadTopicName(),[_25]);
+setTimeout(_2b._loadNextImage,1);
+if(_26){
+_26();
+}
+});
+_2b.hiddenNode.appendChild(div);
+var _32=document.createElement("div");
+dojo.addClass(_32,"slideShowTitle");
+div.appendChild(_32);
+_2b.images[_25]=div;
+img.setAttribute("src",url);
+var _33=_2b.imageStore.getValue(_2c,_2b.titleAttr);
+if(_33){
+img.setAttribute("title",_33);
+}
+};
+this.imageStore.fetch(this._request);
+},_stop:function(){
+if(this._slideId){
+clearTimeout(this._slideId);
+}
+this._slideId=null;
+this._timerCancelled=true;
+dojo.removeClass(this.domNode,"slideShowPaused");
+},_prev:function(){
+if(this.imageIndex<1){
+return;
+}
+this.showImage(this.imageIndex-1);
+},_next:function(){
+this.showNextImage();
+},_startTimer:function(){
+var id=this.id;
+this._slideId=setTimeout(function(){
+dijit.byId(id).showNextImage(true);
+},this.slideshowInterval*1000);
+},_calcNavDimensions:function(){
+dojo.style(this.navNode,"position","absolute");
+dojo.style(this.navNode,"top","-10000px");
+dojo._setOpacity(this.navNode,99);
+this.navPlay._size=dojo.marginBox(this.navPlay);
+this.navPrev._size=dojo.marginBox(this.navPrev);
+this.navNext._size=dojo.marginBox(this.navNext);
+dojo._setOpacity(this.navNode,0);
+dojo.style(this.navNode,"position","");
+dojo.style(this.navNode,"top","");
+},_setTitle:function(_35){
+this.titleNode.innerHTML=dojo.string.substitute(this.titleTemplate,{title:_35,current:1+this.imageIndex,total:this.maxPhotos||""});
+},_fitImage:function(img){
+var _37=img.width;
+var _38=img.height;
+if(_37>this.imageWidth){
+_38=Math.floor(_38*(this.imageWidth/_37));
+img.height=_38;
+img.width=_37=this.imageWidth;
+}
+if(_38>this.imageHeight){
+_37=Math.floor(_37*(this.imageHeight/_38));
+img.height=this.imageHeight;
+img.width=_37;
+}
+},_handleClick:function(e){
+switch(e.target){
+case this.navNext:
+this._next();
+break;
+case this.navPrev:
+this._prev();
+break;
+case this.navPlay:
+this.toggleSlideShow();
+break;
+}
+},_showNav:function(_3a){
+if(this._navShowing&&!_3a){
+return;
+}
+dojo.style(this.navNode,"marginTop","0px");
+dojo.style(this.navPlay,"marginLeft","0px");
+var _3b=dojo.marginBox(this.outerNode);
+var _3c=this._currentImage.height-this.navPlay._size.h-10+this._getTopPadding();
+if(_3c>this._currentImage.height){
+_3c+=10;
+}
+dojo[this.imageIndex<1?"addClass":"removeClass"](this.navPrev,"slideShowCtrlHide");
+dojo[this.imageIndex+1>=this.maxPhotos?"addClass":"removeClass"](this.navNext,"slideShowCtrlHide");
+var _3d=this;
+if(this._navAnim){
+this._navAnim.stop();
+}
+if(this._navShowing){
+return;
+}
+this._navAnim=dojo.fadeIn({node:this.navNode,duration:300,onEnd:function(){
+_3d._navAnim=null;
+}});
+this._navAnim.play();
+this._navShowing=true;
+},_hideNav:function(e){
+if(!e||!this._overElement(this.outerNode,e)){
+var _3f=this;
+if(this._navAnim){
+this._navAnim.stop();
+}
+this._navAnim=dojo.fadeOut({node:this.navNode,duration:300,onEnd:function(){
+_3f._navAnim=null;
+}});
+this._navAnim.play();
+this._navShowing=false;
+}
+},_overElement:function(_40,e){
+if(typeof (dojo)=="undefined"){
+return false;
+}
+_40=dojo.byId(_40);
+var m={x:e.pageX,y:e.pageY};
+var bb=dojo._getBorderBox(_40);
+var _44=dojo.coords(_40,true);
+var _45=_44.x;
+return (m.x>=_45&&m.x<=(_45+bb.w)&&m.y>=_44.y&&m.y<=(top+bb.h));
+}});
+}
diff --git a/dojox/image/ThumbnailPicker.js b/dojox/image/ThumbnailPicker.js
new file mode 100644
index 0000000..5ebaedc
--- /dev/null
+++ b/dojox/image/ThumbnailPicker.js
@@ -0,0 +1,300 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.image.ThumbnailPicker"]){
+dojo._hasResource["dojox.image.ThumbnailPicker"]=true;
+dojo.provide("dojox.image.ThumbnailPicker");
+dojo.experimental("dojox.image.ThumbnailPicker");
+dojo.require("dojox.fx.scroll");
+dojo.require("dojo.fx.easing");
+dojo.require("dojo.fx");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.declare("dojox.image.ThumbnailPicker",[dijit._Widget,dijit._Templated],{imageStore:null,request:null,size:500,thumbHeight:75,thumbWidth:100,useLoadNotifier:false,useHyperlink:false,hyperlinkTarget:"new",isClickable:true,isScrollable:true,isHorizontal:true,autoLoad:true,linkAttr:"link",imageThumbAttr:"imageUrlThumb",imageLargeAttr:"imageUrl",pageSize:20,titleAttr:"title",templateString:"<div dojoAttachPoint=\"outerNode\" class=\"thumbOuter\">\n\t<div dojoAttachPoint=\"navPrev\" class [...]
+this.widgetid=this.id;
+this.inherited(arguments);
+this.pageSize=Number(this.pageSize);
+this._scrollerSize=this.size-(51*2);
+var _1=this._sizeProperty=this.isHorizontal?"width":"height";
+dojo.style(this.outerNode,"textAlign","center");
+dojo.style(this.outerNode,_1,this.size+"px");
+dojo.style(this.thumbScroller,_1,this._scrollerSize+"px");
+if(this.useHyperlink){
+dojo.subscribe(this.getClickTopicName(),this,function(_2){
+var _3=_2.index;
+var _4=this.imageStore.getValue(_2.data,this.linkAttr);
+if(!_4){
+return;
+}
+if(this.hyperlinkTarget=="new"){
+window.open(_4);
+}else{
+window.location=_4;
+}
+});
+}
+if(this.isClickable){
+dojo.addClass(this.thumbsNode,"thumbClickable");
+}
+this._totalSize=0;
+this.init();
+},init:function(){
+if(this.isInitialized){
+return false;
+}
+var _5=this.isHorizontal?"Horiz":"Vert";
+dojo.addClass(this.navPrev,"prev"+_5);
+dojo.addClass(this.navNext,"next"+_5);
+dojo.addClass(this.thumbsNode,"thumb"+_5);
+dojo.addClass(this.outerNode,"thumb"+_5);
+this.navNextImg.setAttribute("src",this._blankGif);
+this.navPrevImg.setAttribute("src",this._blankGif);
+this.connect(this.navPrev,"onclick","_prev");
+this.connect(this.navNext,"onclick","_next");
+this.isInitialized=true;
+if(this.isHorizontal){
+this._offsetAttr="offsetLeft";
+this._sizeAttr="offsetWidth";
+this._scrollAttr="scrollLeft";
+}else{
+this._offsetAttr="offsetTop";
+this._sizeAttr="offsetHeight";
+this._scrollAttr="scrollTop";
+}
+this._updateNavControls();
+if(this.imageStore&&this.request){
+this._loadNextPage();
+}
+return true;
+},getClickTopicName:function(){
+return (this.widgetId||this.id)+"/select";
+},getShowTopicName:function(){
+return (this.widgetId||this.id)+"/show";
+},setDataStore:function(_6,_7,_8){
+this.reset();
+this.request={query:{},start:_7.start||0,count:_7.count||10,onBegin:dojo.hitch(this,function(_9){
+this._maxPhotos=_9;
+})};
+if(_7.query){
+dojo.mixin(this.request.query,_7.query);
+}
+if(_8){
+dojo.forEach(["imageThumbAttr","imageLargeAttr","linkAttr","titleAttr"],function(_a){
+if(_8[_a]){
+this[_a]=_8[_a];
+}
+},this);
+}
+this.request.start=0;
+this.request.count=this.pageSize;
+this.imageStore=_6;
+if(!this.init()){
+this._loadNextPage();
+}
+},reset:function(){
+this._loadedImages={};
+dojo.forEach(this._thumbs,function(_b){
+if(_b){
+if(_b.parentNode){
+_b.parentNode.removeChild(_b);
+}
+}
+});
+this._thumbs=[];
+this.isInitialized=false;
+this._noImages=true;
+},isVisible:function(_c){
+var _d=this._thumbs[_c];
+if(!_d){
+return false;
+}
+var _e=this.isHorizontal?"offsetLeft":"offsetTop";
+var _f=this.isHorizontal?"offsetWidth":"offsetHeight";
+var _10=this.isHorizontal?"scrollLeft":"scrollTop";
+var _11=_d[_e]-this.thumbsNode[_e];
+return (_11>=this.thumbScroller[_10]&&_11+_d[_f]<=this.thumbScroller[_10]+this._scrollerSize);
+},_next:function(){
+var pos=this.isHorizontal?"offsetLeft":"offsetTop";
+var _13=this.isHorizontal?"offsetWidth":"offsetHeight";
+var _14=this.thumbsNode[pos];
+var _15=this._thumbs[this._thumbIndex];
+var _16=_15[pos]-_14;
+var _17=-1,img;
+for(var i=this._thumbIndex+1;i<this._thumbs.length;i++){
+img=this._thumbs[i];
+if(img[pos]-_14+img[_13]-_16>this._scrollerSize){
+this._showThumbs(i);
+return;
+}
+}
+},_prev:function(){
+if(this.thumbScroller[this.isHorizontal?"scrollLeft":"scrollTop"]==0){
+return;
+}
+var pos=this.isHorizontal?"offsetLeft":"offsetTop";
+var _1b=this.isHorizontal?"offsetWidth":"offsetHeight";
+var _1c=this._thumbs[this._thumbIndex];
+var _1d=_1c[pos]-this.thumbsNode[pos];
+var _1e=-1,img;
+for(var i=this._thumbIndex-1;i>-1;i--){
+img=this._thumbs[i];
+if(_1d-img[pos]>this._scrollerSize){
+this._showThumbs(i+1);
+return;
+}
+}
+this._showThumbs(0);
+},_checkLoad:function(img,_22){
+dojo.publish(this.getShowTopicName(),[{index:_22}]);
+this._updateNavControls();
+this._loadingImages={};
+this._thumbIndex=_22;
+if(this.thumbsNode.offsetWidth-img.offsetLeft<(this._scrollerSize*2)){
+this._loadNextPage();
+}
+},_showThumbs:function(_23){
+_23=Math.min(Math.max(_23,0),this._maxPhotos);
+if(_23>=this._maxPhotos){
+return;
+}
+var img=this._thumbs[_23];
+if(!img){
+return;
+}
+var _25=img.offsetLeft-this.thumbsNode.offsetLeft;
+var top=img.offsetTop-this.thumbsNode.offsetTop;
+var _27=this.isHorizontal?_25:top;
+if((_27>=this.thumbScroller[this._scrollAttr])&&(_27+img[this._sizeAttr]<=this.thumbScroller[this._scrollAttr]+this._scrollerSize)){
+return;
+}
+if(this.isScrollable){
+var _28=this.isHorizontal?{x:_25,y:0}:{x:0,y:top};
+dojox.fx.smoothScroll({target:_28,win:this.thumbScroller,duration:300,easing:dojo.fx.easing.easeOut,onEnd:dojo.hitch(this,"_checkLoad",img,_23)}).play(10);
+}else{
+if(this.isHorizontal){
+this.thumbScroller.scrollLeft=_25;
+}else{
+this.thumbScroller.scrollTop=top;
+}
+this._checkLoad(img,_23);
+}
+},markImageLoaded:function(_29){
+var _2a=dojo.byId("loadingDiv_"+this.widgetid+"_"+_29);
+if(_2a){
+this._setThumbClass(_2a,"thumbLoaded");
+}
+this._loadedImages[_29]=true;
+},_setThumbClass:function(_2b,_2c){
+if(!this.autoLoad){
+return;
+}
+dojo.addClass(_2b,_2c);
+},_loadNextPage:function(){
+if(this._loadInProgress){
+return;
+}
+this._loadInProgress=true;
+var _2d=this.request.start+(this._noImages?0:this.pageSize);
+var pos=_2d;
+while(pos<this._thumbs.length&&this._thumbs[pos]){
+pos++;
+}
+var _2f=function(_30,_31){
+if(_30&&_30.length){
+var _32=0;
+var _33=dojo.hitch(this,function(){
+if(_32>=_30.length){
+this._loadInProgress=false;
+return;
+}
+var _34=_32++;
+this._loadImage(_30[_34],pos+_34,_33);
+});
+_33();
+this._updateNavControls();
+}else{
+this._loadInProgress=false;
+}
+};
+var _35=function(){
+this._loadInProgress=false;
+
+};
+this.request.onComplete=dojo.hitch(this,_2f);
+this.request.onError=dojo.hitch(this,_35);
+this.request.start=_2d;
+this._noImages=false;
+this.imageStore.fetch(this.request);
+},_loadImage:function(_36,_37,_38){
+var url=this.imageStore.getValue(_36,this.imageThumbAttr);
+var img=document.createElement("img");
+var _3b=document.createElement("div");
+_3b.setAttribute("id","img_"+this.widgetid+"_"+_37);
+_3b.appendChild(img);
+img._index=_37;
+img._data=_36;
+this._thumbs[_37]=_3b;
+var _3c;
+if(this.useLoadNotifier){
+_3c=document.createElement("div");
+_3c.setAttribute("id","loadingDiv_"+this.widgetid+"_"+_37);
+this._setThumbClass(_3c,this._loadedImages[_37]?"thumbLoaded":"thumbNotifier");
+_3b.appendChild(_3c);
+}
+var _3d=dojo.marginBox(this.thumbsNode);
+var _3e;
+var _3f;
+if(this.isHorizontal){
+_3e=this.thumbWidth;
+_3f="w";
+}else{
+_3e=this.thumbHeight;
+_3f="h";
+}
+_3d=_3d[_3f];
+var sl=this.thumbScroller.scrollLeft,st=this.thumbScroller.scrollTop;
+dojo.style(this.thumbsNode,this._sizeProperty,(_3d+_3e+20)+"px");
+this.thumbScroller.scrollLeft=sl;
+this.thumbScroller.scrollTop=st;
+this.thumbsNode.appendChild(_3b);
+dojo.connect(img,"onload",this,function(){
+var _42=dojo.marginBox(img)[_3f];
+this._totalSize+=(Number(_42)+4);
+dojo.style(this.thumbsNode,this._sizeProperty,this._totalSize+"px");
+if(this.useLoadNotifier){
+dojo.style(_3c,"width",(img.width-4)+"px");
+}
+dojo.style(_3b,"width",img.width+"px");
+_38();
+return false;
+});
+dojo.connect(img,"onclick",this,function(evt){
+dojo.publish(this.getClickTopicName(),[{index:evt.target._index,data:evt.target._data,url:img.getAttribute("src"),largeUrl:this.imageStore.getValue(_36,this.imageLargeAttr),title:this.imageStore.getValue(_36,this.titleAttr),link:this.imageStore.getValue(_36,this.linkAttr)}]);
+return false;
+});
+dojo.addClass(img,"imageGalleryThumb");
+img.setAttribute("src",url);
+var _44=this.imageStore.getValue(_36,this.titleAttr);
+if(_44){
+img.setAttribute("title",_44);
+}
+this._updateNavControls();
+},_updateNavControls:function(){
+var _45=[];
+var _46=function(_47,add){
+var fn=add?"addClass":"removeClass";
+dojo[fn](_47,"enabled");
+dojo[fn](_47,"thumbClickable");
+};
+var pos=this.isHorizontal?"scrollLeft":"scrollTop";
+var _4b=this.isHorizontal?"offsetWidth":"offsetHeight";
+_46(this.navPrev,(this.thumbScroller[pos]>0));
+var _4c=this._thumbs[this._thumbs.length-1];
+var _4d=(this.thumbScroller[pos]+this._scrollerSize<this.thumbsNode[_4b]);
+_46(this.navNext,_4d);
+}});
+}
diff --git a/dojox/image/_base.js b/dojox/image/_base.js
new file mode 100644
index 0000000..eba106f
--- /dev/null
+++ b/dojox/image/_base.js
@@ -0,0 +1,27 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.image._base"]){
+dojo._hasResource["dojox.image._base"]=true;
+dojo.provide("dojox.image._base");
+(function(d){
+var _2;
+dojox.image.preload=function(_3){
+if(!_2){
+_2=d.create("div",{style:{position:"absolute",top:"-9999px",display:"none"}},d.body());
+}
+d.forEach(_3,function(_4){
+d.create("img",{src:_4},_2);
+});
+};
+if(d.config.preloadImages){
+d.addOnLoad(function(){
+dojox.image.preload(d.config.preloadImages);
+});
+}
+})(dojo);
+}
diff --git a/dojox/image/resources/Badge.css b/dojox/image/resources/Badge.css
new file mode 100644
index 0000000..ff4fd57
--- /dev/null
+++ b/dojox/image/resources/Badge.css
@@ -0,0 +1,30 @@
+
+.dojoxBadge {
+	position:relative;
+}
+.dojoxBadge .dojoxBadgeImage {
+	position:absolute;
+	top:0; left:0;
+	margin:0;
+	padding:0;
+}
+.dojoxBadge {
+	margin:0; padding:0;
+	border:1px solid #eee;
+}
+.dojoxBadge .dojoxBadgeImage {
+	overflow:hidden;
+	margin-left:1px;
+	margin-top:1px;
+	background:#ededed;
+	z-index:90;
+}
+.dojoxBadge .dojoxBadgeSeen {
+	background-color:#dedede;
+}
+.dojoxBadge .dojoxBadgeOver {
+	background-color:green !important;
+}
+.dojoxBadge .dojoxBadgeTop {
+	z-index:99;
+}
diff --git a/dojox/image/resources/Gallery.css b/dojox/image/resources/Gallery.css
new file mode 100644
index 0000000..6ddd333
--- /dev/null
+++ b/dojox/image/resources/Gallery.css
@@ -0,0 +1,5 @@
+
+.imageGalleryWrapper {
+	padding-bottom: 20px;
+	text-align: center;
+}
diff --git a/dojox/image/resources/Gallery.html b/dojox/image/resources/Gallery.html
new file mode 100644
index 0000000..571dc4f
--- /dev/null
+++ b/dojox/image/resources/Gallery.html
@@ -0,0 +1,4 @@
+<div dojoAttachPoint="outerNode" class="imageGalleryWrapper">
+	<div dojoAttachPoint="thumbPickerNode"></div>
+	<div dojoAttachPoint="slideShowNode"></div>
+</div>
\ No newline at end of file
diff --git a/dojox/image/resources/Lightbox.css b/dojox/image/resources/Lightbox.css
new file mode 100644
index 0000000..37ecc54
--- /dev/null
+++ b/dojox/image/resources/Lightbox.css
@@ -0,0 +1,82 @@
+
+.dijitDialogUnderlay {
+	background-color:#000; 
+}
+.dojoxLightbox {
+	position:absolute;
+	z-index:999;
+	overflow:hidden;
+	width:100px;
+	height:100px; 
+	border:11px solid #fff;
+	background:#fff url('images/loading.gif') no-repeat center center;
+        
+	-webkit-box-shadow: 0px 6px 10px #636363; 
+	-webkit-border-radius: 3px;
+	-moz-border-radius:4px;
+        border-radius: 4px;
+}
+.dojoxLightboxContainer {
+	position:absolute;
+	top:0; left:0; 
+}
+.dojoxLightboxFooter {
+	padding-bottom:5px;
+	position:relative;
+	bottom:0;
+	left:0;
+	margin-top:8px;
+	color:#333;
+	z-index:1000;
+	font-size:10pt;
+}
+.dojoxLightboxGroupText {
+	color:#666; 
+	font-size:8pt;
+}
+.LightboxNext,
+.LightboxPrev,
+.LightboxClose {
+	float:right;
+	width:16px;
+	height:16px;
+	cursor:pointer;
+}
+.nihilo .LightboxClose,
+.tundra .LightboxClose {
+	background:url('images/close.png') no-repeat center center;
+}
+.di_ie6 .nihilo .LightboxClose,
+.dj_ie6 .tundra .LightboxClose {
+	background:url('images/close.gif') no-repeat center center;
+}
+.nihilo .LightboxNext,
+.tundra .LightboxNext {
+	background:url('images/right.png') no-repeat center center;
+}
+.dj_ie6 .nihilo .LightboxNext,
+.dj_ie6 .tundra .LightboxNext {
+	background:url('images/right.gif') no-repeat center center;
+}
+.nihilo .LightboxPrev,
+.tundra .LightboxPrev {
+	background:url('images/left.png') no-repeat center center;
+}
+.dj_ie6 .nihilo .LightboxPrev,
+.dj_ie6 .tundra .LightboxPrev {
+	background:url('images/left.gif') no-repeat center center;
+}
+.soria .LightboxClose,
+.soria .LightboxNext,
+.soria .LightboxPrev {
+	width:15px;
+	height:15px;
+	background:url('../../../dijit/themes/soria/images/spriteRoundedIconsSmall.png') no-repeat center center;
+	background-position:-60px;
+}
+.soria .LightboxNext {
+	background-position:-30px 0;
+}
+.soria .LightboxPrev {
+	background-position:0 0;
+}
diff --git a/dojox/image/resources/Lightbox.html b/dojox/image/resources/Lightbox.html
new file mode 100644
index 0000000..32a72ef
--- /dev/null
+++ b/dojox/image/resources/Lightbox.html
@@ -0,0 +1,13 @@
+<div class="dojoxLightbox" dojoAttachPoint="containerNode">
+	<div style="position:relative">
+		<div dojoAttachPoint="imageContainer" class="dojoxLightboxContainer" dojoAttachEvent="onclick: _onImageClick">
+			<img dojoAttachPoint="imgNode" src="${imgUrl}" class="dojoxLightboxImage" alt="${title}">
+			<div class="dojoxLightboxFooter" dojoAttachPoint="titleNode">
+				<div class="dijitInline LightboxClose" dojoAttachPoint="closeNode"></div>
+				<div class="dijitInline LightboxNext" dojoAttachPoint="nextNode"></div>	
+				<div class="dijitInline LightboxPrev" dojoAttachPoint="prevNode"></div>
+				<div class="dojoxLightboxText" dojoAttachPoint="titleTextNode"><span dojoAttachPoint="textNode">${title}</span><span dojoAttachPoint="groupCount" class="dojoxLightboxGroupText"></span></div>
+			</div>
+		</div>
+	</div>
+</div>
\ No newline at end of file
diff --git a/dojox/image/resources/Magnifier.css b/dojox/image/resources/Magnifier.css
new file mode 100644
index 0000000..85eba72
--- /dev/null
+++ b/dojox/image/resources/Magnifier.css
@@ -0,0 +1,5 @@
+.glassNode {
+	overflow:hidden;
+	position:absolute;
+	visibility:hidden;
+}
diff --git a/dojox/image/resources/SlideShow.css b/dojox/image/resources/SlideShow.css
new file mode 100644
index 0000000..a5684fc
--- /dev/null
+++ b/dojox/image/resources/SlideShow.css
@@ -0,0 +1,104 @@
+
+.slideShowWrapper { 
+	position:relative; 
+	background:#fff;
+	padding:8px; 
+	border:1px solid #333;	
+	padding-bottom:20px;
+	overflow:hidden;
+	text-align: center;
+	-moz-border-radius:3pt;
+	-webkit-border-radius:4pt;
+	-webkit-drop-shadow:#ccc 4pt; 
+}
+.slideShowNav { 
+	position:absolute;
+	bottom:-18px;	
+	left:0px;
+	padding:0px 3px 2px 0px;
+	background-color:#fff; 
+	width:100%;
+}
+.slideShowNavWrapper { float:right;  }
+.slideShowTitle {
+	float:left;
+	color:#333;
+	font-size:10pt;
+}
+.slideShowTitle .slideShowCounterText {
+	font-size:6pt; color:#666; 
+}
+.slideShowHidden {
+	position:absolute;
+	display: none;
+	height: 1px;
+	width: 1px;
+}
+.slideShowImageWrapper {
+	position:relative;
+	text-align: center;
+	margin-top: -42px;
+	float: left;
+	width: 100%;
+}
+.slideShowImageWrapper img {
+	border: 0px none;
+}
+.slideShowNotifier {
+	background-color: red;
+	width: 100px;
+	height: 5px;
+	font-size: 1%;
+}
+.slideShowSlideShow {
+	position:absolute;
+	top:30px; 
+	padding: 0 5px;
+	border: 0px;
+	text-decoration: none; 
+	color: #2e6ab1;
+}
+.slideShowLoading { background-color: #fad66a; }
+.slideShowLoaded { background-color: transparent; }
+.slideShowCtrlPrev {
+	background-position: -96px 0px; 
+	float: left;
+}
+.slideShowCtrlNext {
+	background-position: -144px 0px;
+	float: right;
+}
+.slideShowCtrlPlay {
+	background-position: -190px 0px;
+	position: absolute;
+}
+.slideShowPaused .slideShowCtrlPlay {
+	background-position: -236px 0px;
+	position: absolute;
+}
+.slideShowCtrl span.slideShowCtrlHide {
+	background-image: url("../../../dojo/resources/blank.gif");
+	cursor: auto;
+}
+.slideShowCtrl {
+	height: 50px;
+	width: 100%;
+	position: relative;
+	z-index:999;
+	float: left;
+}
+.slideShowCtrl span {
+	width: 50px;
+	height: 100%;
+	background-image: url("images/buttons.png");
+	cursor: pointer;
+}
+.dj_ie .slideShowCtrl span {
+	background-image: url("images/buttons.gif");
+}
+.dj_ie6 .slideShowPager li.currentpage,
+.dj_ie6 .pagination li.disablepage{
+    
+    margin-right: 5px;
+    padding-right: 0;
+}
diff --git a/dojox/image/resources/SlideShow.html b/dojox/image/resources/SlideShow.html
new file mode 100644
index 0000000..fa4aca6
--- /dev/null
+++ b/dojox/image/resources/SlideShow.html
@@ -0,0 +1,14 @@
+<div dojoAttachPoint="outerNode" class="slideShowWrapper">
+	<div style="position:relative;" dojoAttachPoint="innerWrapper">
+		<div class="slideShowNav" dojoAttachEvent="onclick: _handleClick">
+			<div class="dijitInline slideShowTitle" dojoAttachPoint="titleNode">${title}</div>
+		</div>
+		<div dojoAttachPoint="navNode" class="slideShowCtrl" dojoAttachEvent="onclick: _handleClick">
+			<span dojoAttachPoint="navPrev" class="slideShowCtrlPrev"></span>
+			<span dojoAttachPoint="navPlay" class="slideShowCtrlPlay"></span>
+			<span dojoAttachPoint="navNext" class="slideShowCtrlNext"></span>
+		</div>
+		<div dojoAttachPoint="largeNode" class="slideShowImageWrapper"></div>		
+		<div dojoAttachPoint="hiddenNode" class="slideShowHidden"></div>
+	</div>
+</div>
\ No newline at end of file
diff --git a/dojox/image/resources/ThumbnailPicker.css b/dojox/image/resources/ThumbnailPicker.css
new file mode 100644
index 0000000..28803b0
--- /dev/null
+++ b/dojox/image/resources/ThumbnailPicker.css
@@ -0,0 +1,108 @@
+
+.thumbWrapper .thumbNav {
+	background-repeat: no-repeat;	
+	background-position: center;
+	padding-top: 1px;
+	width: 30px;
+	height: 100%;
+}
+.thumbOuter {
+	padding-bottom: 2px;
+}
+.thumbOuter.thumbHoriz {
+	width: 500px;
+	height: 85px;
+}
+.thumbOuter.thumbVert {
+	width: 100px;
+	height: 400px;
+}
+.thumbOuter .enabled {
+	background: transparent url("images/buttons.png") no-repeat center center;
+}
+.dj_ie6 .thumbOuter .enabled { background-image: url("images/buttons.gif"); }
+.thumbOuter .thumbNav img {
+	width: 48px;
+	height: 75px;
+}
+.thumbOuter .thumbClickable div {
+	cursor: pointer;
+}
+.thumbOuter .prevHoriz {
+	background-position: -96px 12px;
+	position: relative;
+	float: left;
+	height: 100%;
+}
+.thumbOuter .nextHoriz {
+	background-position: -144px 12px;
+	position: relative;
+	float: right;
+	height: 100%;
+}
+.thumbOuter .prevVert {
+	background-position: 0px 0px;
+	height: 48px;
+	width:48px;
+	margin-left:24px;
+}
+.thumbOuter .nextVert {
+	background-position: -48px 0px;
+	height: 48px;
+	width:48px;
+	margin-left:24px;
+}
+.thumbWrapper img {
+	height: 75px;
+	max-width: 100px;
+	width: expression(this.width > 100 ? 100: true);
+}
+.thumbWrapper .thumbNav .imageGalleryThumb {
+	height: 50px;
+}
+.thumbWrapper .thumbNotifier {
+	background-color: red;
+	width: 0px;
+	margin-left: 2px;
+	height: 5px;
+	font-size: 1%;
+}
+.thumbWrapper .thumbLoaded {
+	background-color: transparent;	
+}
+.thumbScroller {
+	overflow-x: hidden;
+	overflow-y: hidden;
+	white-space: nowrap;
+	text-align: center;
+}
+.thumbHoriz .thumbScroller {
+	width: 500px;
+	height: 85px;
+	float: left;
+}
+.thumbVert .thumbScroller {
+	height: 500px;
+	width: 100px;	
+}
+.thumbWrapper {
+	float: left;
+}
+.thumbVert .thumbWrapper {
+	width: 100px;
+	height: 10px;
+}
+.thumbHoriz .thumbWapper {
+	height:85px;
+	width: 10px;
+}
+.thumbWrapper.thumbHoriz div {
+	float: left;
+	padding-right: 2px;
+}
+.thumbWrapper.thumbVert {
+	width: 100px;
+}
+.thumbWrapper.thumbVert div {
+	padding-bottom: 2px;
+}
diff --git a/dojox/image/resources/ThumbnailPicker.html b/dojox/image/resources/ThumbnailPicker.html
new file mode 100644
index 0000000..561ce2d
--- /dev/null
+++ b/dojox/image/resources/ThumbnailPicker.html
@@ -0,0 +1,11 @@
+<div dojoAttachPoint="outerNode" class="thumbOuter">
+	<div dojoAttachPoint="navPrev" class="thumbNav thumbClickable">
+	  <img src="" dojoAttachPoint="navPrevImg"/>    
+	</div>
+	<div dojoAttachPoint="thumbScroller" class="thumbScroller">
+	  <div dojoAttachPoint="thumbsNode" class="thumbWrapper"></div>
+	</div>
+	<div dojoAttachPoint="navNext" class="thumbNav thumbClickable">
+	  <img src="" dojoAttachPoint="navNextImg"/>  
+	</div>
+</div>
\ No newline at end of file
diff --git a/dojox/image/resources/image.css b/dojox/image/resources/image.css
new file mode 100644
index 0000000..2c6c868
--- /dev/null
+++ b/dojox/image/resources/image.css
@@ -0,0 +1,330 @@
+
+.dijitDialogUnderlay {
+	background-color:#000; 
+}
+.dojoxLightbox {
+	position:absolute;
+	z-index:999;
+	overflow:hidden;
+	width:100px;
+	height:100px; 
+	border:11px solid #fff;
+	background:#fff url(images/loading.gif) no-repeat center center;
+        
+	-webkit-box-shadow: 0px 6px 10px #636363; 
+	-webkit-border-radius: 3px;
+	-moz-border-radius:4px;
+        border-radius: 4px;
+}
+.dojoxLightboxContainer {
+	position:absolute;
+	top:0; left:0; 
+}
+.dojoxLightboxFooter {
+	padding-bottom:5px;
+	position:relative;
+	bottom:0;
+	left:0;
+	margin-top:8px;
+	color:#333;
+	z-index:1000;
+	font-size:10pt;
+}
+.dojoxLightboxGroupText {
+	color:#666; 
+	font-size:8pt;
+}
+.LightboxNext,
+.LightboxPrev,
+.LightboxClose {
+	float:right;
+	width:16px;
+	height:16px;
+	cursor:pointer;
+}
+.nihilo .LightboxClose,
+.tundra .LightboxClose {
+	background:url(images/close.png) no-repeat center center;
+}
+.di_ie6 .nihilo .LightboxClose,
+.dj_ie6 .tundra .LightboxClose {
+	background:url(images/close.gif) no-repeat center center;
+}
+.nihilo .LightboxNext,
+.tundra .LightboxNext {
+	background:url(images/right.png) no-repeat center center;
+}
+.dj_ie6 .nihilo .LightboxNext,
+.dj_ie6 .tundra .LightboxNext {
+	background:url(images/right.gif) no-repeat center center;
+}
+.nihilo .LightboxPrev,
+.tundra .LightboxPrev {
+	background:url(images/left.png) no-repeat center center;
+}
+.dj_ie6 .nihilo .LightboxPrev,
+.dj_ie6 .tundra .LightboxPrev {
+	background:url(images/left.gif) no-repeat center center;
+}
+.soria .LightboxClose,
+.soria .LightboxNext,
+.soria .LightboxPrev {
+	width:15px;
+	height:15px;
+	background:url(../../../dijit/themes/soria/images/spriteRoundedIconsSmall.png) no-repeat center center;
+	background-position:-60px;
+}
+.soria .LightboxNext {
+	background-position:-30px 0;
+}
+.soria .LightboxPrev {
+	background-position:0 0;
+}
+.slideShowWrapper { 
+	position:relative; 
+	background:#fff;
+	padding:8px; 
+	border:1px solid #333;	
+	padding-bottom:20px;
+	overflow:hidden;
+	text-align: center;
+	-moz-border-radius:3pt;
+	-webkit-border-radius:4pt;
+	-webkit-drop-shadow:#ccc 4pt; 
+}
+.slideShowNav { 
+	position:absolute;
+	bottom:-18px;	
+	left:0px;
+	padding:0px 3px 2px 0px;
+	background-color:#fff; 
+	width:100%;
+}
+.slideShowNavWrapper { float:right;  }
+.slideShowTitle {
+	float:left;
+	color:#333;
+	font-size:10pt;
+}
+.slideShowTitle .slideShowCounterText {
+	font-size:6pt; color:#666; 
+}
+.slideShowHidden {
+	position:absolute;
+	display: none;
+	height: 1px;
+	width: 1px;
+}
+.slideShowImageWrapper {
+	position:relative;
+	text-align: center;
+	margin-top: -42px;
+	float: left;
+	width: 100%;
+}
+.slideShowImageWrapper img {
+	border: 0px none;
+}
+.slideShowNotifier {
+	background-color: red;
+	width: 100px;
+	height: 5px;
+	font-size: 1%;
+}
+.slideShowSlideShow {
+	position:absolute;
+	top:30px; 
+	padding: 0 5px;
+	border: 0px;
+	text-decoration: none; 
+	color: #2e6ab1;
+}
+.slideShowLoading { background-color: #fad66a; }
+.slideShowLoaded { background-color: transparent; }
+.slideShowCtrlPrev {
+	background-position: -96px 0px; 
+	float: left;
+}
+.slideShowCtrlNext {
+	background-position: -144px 0px;
+	float: right;
+}
+.slideShowCtrlPlay {
+	background-position: -190px 0px;
+	position: absolute;
+}
+.slideShowPaused .slideShowCtrlPlay {
+	background-position: -236px 0px;
+	position: absolute;
+}
+.slideShowCtrl span.slideShowCtrlHide {
+	background-image: url(../../../dojo/resources/blank.gif);
+	cursor: auto;
+}
+.slideShowCtrl {
+	height: 50px;
+	width: 100%;
+	position: relative;
+	z-index:999;
+	float: left;
+}
+.slideShowCtrl span {
+	width: 50px;
+	height: 100%;
+	background-image: url(images/buttons.png);
+	cursor: pointer;
+}
+.dj_ie .slideShowCtrl span {
+	background-image: url(images/buttons.gif);
+}
+.dj_ie6 .slideShowPager li.currentpage,
+.dj_ie6 .pagination li.disablepage{
+    
+    margin-right: 5px;
+    padding-right: 0;
+}
+.thumbWrapper .thumbNav {
+	background-repeat: no-repeat;	
+	background-position: center;
+	padding-top: 1px;
+	width: 30px;
+	height: 100%;
+}
+.thumbOuter {
+	padding-bottom: 2px;
+}
+.thumbOuter.thumbHoriz {
+	width: 500px;
+	height: 85px;
+}
+.thumbOuter.thumbVert {
+	width: 100px;
+	height: 400px;
+}
+.thumbOuter .enabled {
+	background: transparent url(images/buttons.png) no-repeat center center;
+}
+.dj_ie6 .thumbOuter .enabled { background-image: url(images/buttons.gif); }
+.thumbOuter .thumbNav img {
+	width: 48px;
+	height: 75px;
+}
+.thumbOuter .thumbClickable div {
+	cursor: pointer;
+}
+.thumbOuter .prevHoriz {
+	background-position: -96px 12px;
+	position: relative;
+	float: left;
+	height: 100%;
+}
+.thumbOuter .nextHoriz {
+	background-position: -144px 12px;
+	position: relative;
+	float: right;
+	height: 100%;
+}
+.thumbOuter .prevVert {
+	background-position: 0px 0px;
+	height: 48px;
+	width:48px;
+	margin-left:24px;
+}
+.thumbOuter .nextVert {
+	background-position: -48px 0px;
+	height: 48px;
+	width:48px;
+	margin-left:24px;
+}
+.thumbWrapper img {
+	height: 75px;
+	max-width: 100px;
+	width: expression(this.width > 100 ? 100: true);
+}
+.thumbWrapper .thumbNav .imageGalleryThumb {
+	height: 50px;
+}
+.thumbWrapper .thumbNotifier {
+	background-color: red;
+	width: 0px;
+	margin-left: 2px;
+	height: 5px;
+	font-size: 1%;
+}
+.thumbWrapper .thumbLoaded {
+	background-color: transparent;	
+}
+.thumbScroller {
+	overflow-x: hidden;
+	overflow-y: hidden;
+	white-space: nowrap;
+	text-align: center;
+}
+.thumbHoriz .thumbScroller {
+	width: 500px;
+	height: 85px;
+	float: left;
+}
+.thumbVert .thumbScroller {
+	height: 500px;
+	width: 100px;	
+}
+.thumbWrapper {
+	float: left;
+}
+.thumbVert .thumbWrapper {
+	width: 100px;
+	height: 10px;
+}
+.thumbHoriz .thumbWapper {
+	height:85px;
+	width: 10px;
+}
+.thumbWrapper.thumbHoriz div {
+	float: left;
+	padding-right: 2px;
+}
+.thumbWrapper.thumbVert {
+	width: 100px;
+}
+.thumbWrapper.thumbVert div {
+	padding-bottom: 2px;
+}
+.imageGalleryWrapper {
+	padding-bottom: 20px;
+	text-align: center;
+}
+.dojoxBadge {
+	position:relative;
+}
+.dojoxBadge .dojoxBadgeImage {
+	position:absolute;
+	top:0; left:0;
+	margin:0;
+	padding:0;
+}
+.dojoxBadge {
+	margin:0; padding:0;
+	border:1px solid #eee;
+}
+.dojoxBadge .dojoxBadgeImage {
+	overflow:hidden;
+	margin-left:1px;
+	margin-top:1px;
+	background:#ededed;
+	z-index:90;
+}
+.dojoxBadge .dojoxBadgeSeen {
+	background-color:#dedede;
+}
+.dojoxBadge .dojoxBadgeOver {
+	background-color:green !important;
+}
+.dojoxBadge .dojoxBadgeTop {
+	z-index:99;
+}
+.glassNode {
+	overflow:hidden;
+	position:absolute;
+	visibility:hidden;
+}
diff --git a/dojox/image/resources/images/buttons.gif b/dojox/image/resources/images/buttons.gif
new file mode 100644
index 0000000..5f9081f
Binary files /dev/null and b/dojox/image/resources/images/buttons.gif differ
diff --git a/dojox/image/resources/images/buttons.png b/dojox/image/resources/images/buttons.png
new file mode 100644
index 0000000..306e2f8
Binary files /dev/null and b/dojox/image/resources/images/buttons.png differ
diff --git a/dojox/image/resources/images/close.gif b/dojox/image/resources/images/close.gif
new file mode 100644
index 0000000..ca97265
Binary files /dev/null and b/dojox/image/resources/images/close.gif differ
diff --git a/dojox/image/resources/images/close.png b/dojox/image/resources/images/close.png
new file mode 100644
index 0000000..1ac9d10
Binary files /dev/null and b/dojox/image/resources/images/close.png differ
diff --git a/dojox/image/resources/images/close_dark.png b/dojox/image/resources/images/close_dark.png
new file mode 100644
index 0000000..105fe55
Binary files /dev/null and b/dojox/image/resources/images/close_dark.png differ
diff --git a/dojox/image/resources/images/left.gif b/dojox/image/resources/images/left.gif
new file mode 100644
index 0000000..8db89c4
Binary files /dev/null and b/dojox/image/resources/images/left.gif differ
diff --git a/dojox/image/resources/images/left.png b/dojox/image/resources/images/left.png
new file mode 100644
index 0000000..0848dba
Binary files /dev/null and b/dojox/image/resources/images/left.png differ
diff --git a/dojox/image/resources/images/loading.gif b/dojox/image/resources/images/loading.gif
new file mode 100644
index 0000000..e4ab783
Binary files /dev/null and b/dojox/image/resources/images/loading.gif differ
diff --git a/dojox/image/resources/images/right.gif b/dojox/image/resources/images/right.gif
new file mode 100644
index 0000000..adfc443
Binary files /dev/null and b/dojox/image/resources/images/right.gif differ
diff --git a/dojox/image/resources/images/right.png b/dojox/image/resources/images/right.png
new file mode 100644
index 0000000..7cab686
Binary files /dev/null and b/dojox/image/resources/images/right.png differ
diff --git a/dojox/image/resources/images/warning.png b/dojox/image/resources/images/warning.png
new file mode 100644
index 0000000..a52a55f
Binary files /dev/null and b/dojox/image/resources/images/warning.png differ
diff --git a/dojox/io/OAuth.js b/dojox/io/OAuth.js
new file mode 100644
index 0000000..e174de5
--- /dev/null
+++ b/dojox/io/OAuth.js
@@ -0,0 +1,174 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.io.OAuth"]){
+dojo._hasResource["dojox.io.OAuth"]=true;
+dojo.provide("dojox.io.OAuth");
+dojo.require("dojox.encoding.digests.SHA1");
+dojox.io.OAuth=new (function(){
+var _1=this.encode=function(s){
+if(!s){
+return "";
+}
+return encodeURIComponent(s).replace(/\!/g,"%21").replace(/\*/g,"%2A").replace(/\'/g,"%27").replace(/\(/g,"%28").replace(/\)/g,"%29");
+};
+var _3=this.decode=function(_4){
+var a=[],_6=_4.split("&");
+for(var i=0,l=_6.length;i<l;i++){
+var _9=_6[i];
+if(_6[i]==""){
+continue;
+}
+if(_6[i].indexOf("=")>-1){
+var _a=_6[i].split("=");
+a.push([decodeURIComponent(_a[0]),decodeURIComponent(_a[1])]);
+}else{
+a.push([decodeURIComponent(_6[i]),null]);
+}
+}
+return a;
+};
+function _b(_c){
+var _d=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],_e=/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,_f=_e.exec(_c),map={},i=_d.length;
+while(i--){
+map[_d[i]]=_f[i]||"";
+}
+var p=map.protocol.toLowerCase(),a=map.authority.toLowerCase(),b=(p=="http"&&map.port==80)||(p=="https"&&map.port==443);
+if(b){
+if(a.lastIndexOf(":")>-1){
+a=a.substring(0,a.lastIndexOf(":"));
+}
+}
+var _15=map.path||"/";
+map.url=p+"://"+a+_15;
+return map;
+};
+var tab="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
+function _17(_18){
+var s="",tl=tab.length;
+for(var i=0;i<_18;i++){
+s+=tab.charAt(Math.floor(Math.random()*tl));
+}
+return s;
+};
+function _1c(){
+return Math.floor(new Date().valueOf()/1000)-2;
+};
+function _1d(_1e,key,_20){
+if(_20&&_20!="PLAINTEXT"&&_20!="HMAC-SHA1"){
+throw new Error("dojox.io.OAuth: the only supported signature encodings are PLAINTEXT and HMAC-SHA1.");
+}
+if(_20=="PLAINTEXT"){
+return key;
+}else{
+return dojox.encoding.digests.SHA1._hmac(_1e,key);
+}
+};
+function key(_22){
+return _1(_22.consumer.secret)+"&"+(_22.token&&_22.token.secret?_1(_22.token.secret):"");
+};
+function _23(_24,oaa){
+var o={oauth_consumer_key:oaa.consumer.key,oauth_nonce:_17(16),oauth_signature_method:oaa.sig_method||"HMAC-SHA1",oauth_timestamp:_1c(),oauth_version:"1.0"};
+if(oaa.token){
+o.oauth_token=oaa.token.key;
+}
+_24.content=dojo.mixin(_24.content||{},o);
+};
+function _27(_28){
+var _29=[{}],_2a;
+if(_28.form){
+if(!_28.content){
+_28.content={};
+}
+var _2b=dojo.byId(_28.form);
+var _2c=_2b.getAttributeNode("action");
+_28.url=_28.url||(_2c?_2c.value:null);
+_2a=dojo.formToObject(_2b);
+delete _28.form;
+}
+if(_2a){
+_29.push(_2a);
+}
+if(_28.content){
+_29.push(_28.content);
+}
+var map=_b(_28.url);
+if(map.query){
+var tmp=dojo.queryToObject(map.query);
+for(var p in tmp){
+tmp[p]=encodeURIComponent(tmp[p]);
+}
+_29.push(tmp);
+}
+_28._url=map.url;
+var a=[];
+for(var i=0,l=_29.length;i<l;i++){
+var _33=_29[i];
+for(var p in _33){
+if(dojo.isArray(_33[p])){
+for(var j=0,jl=_33.length;j<jl;j++){
+a.push([p,_33[j]]);
+}
+}else{
+a.push([p,_33[p]]);
+}
+}
+}
+_28._parameters=a;
+return _28;
+};
+function _36(_37,_38,oaa){
+_23(_38,oaa);
+_27(_38);
+var a=_38._parameters;
+a.sort(function(a,b){
+if(a[0]>b[0]){
+return 1;
+}
+if(a[0]<b[0]){
+return -1;
+}
+if(a[1]>b[1]){
+return 1;
+}
+if(a[1]<b[1]){
+return -1;
+}
+return 0;
+});
+var s=dojo.map(a,function(_3e){
+return _1(_3e[0])+"%3D"+_1(_3e[1]||"");
+}).join("%26");
+var _3f=_37.toUpperCase()+"&"+_1(_38._url)+"&"+s;
+return _3f;
+};
+function _40(_41,_42,oaa){
+var k=key(oaa),_45=_36(_41,_42,oaa),s=_1d(_45,k,oaa.sig_method||"HMAC-SHA1");
+_42.content["oauth_signature"]=s;
+return _42;
+};
+this.sign=function(_47,_48,oaa){
+return _40(_47,_48,oaa);
+};
+this.xhr=function(_4a,_4b,oaa,_4d){
+_40(_4a,_4b,oaa);
+return dojo.xhr(_4a,_4b,_4d);
+};
+this.xhrGet=function(_4e,oaa){
+return this.xhr("GET",_4e,oaa);
+};
+this.xhrPost=this.xhrRawPost=function(_50,oaa){
+return this.xhr("POST",_50,oaa,true);
+};
+this.xhrPut=this.xhrRawPut=function(_52,oaa){
+return this.xhr("PUT",_52,oaa,true);
+};
+this.xhrDelete=function(_54,oaa){
+return this.xhr("DELETE",_54,oaa);
+};
+})();
+}
diff --git a/dojox/io/README b/dojox/io/README
new file mode 100644
index 0000000..ed35581
--- /dev/null
+++ b/dojox/io/README
@@ -0,0 +1,82 @@
+-------------------------------------------------------------------------------
+DojoX IO
+-------------------------------------------------------------------------------
+Version 0.4.0
+Release date: 07/04/2008
+-------------------------------------------------------------------------------
+Project state:
+experimental
+-------------------------------------------------------------------------------
+Credits
+	Bryan Forbes (bryan AT reigndropsfall.net)
+	Kris Zyp (kris AT sitepen.com)
+	James Burke (jburke AT dojotoolkit.org)
+	Tom Trenka (ttrenka AT gmail.com)
+	
+-------------------------------------------------------------------------------
+Project description
+
+	A Collection of advanced and experimental IO modules:
+	
+	* scriptFrame.js - Uses an iframe for dojo.io.script requests. Useful in some
+	long-polling comet situations in Firefox and Opera. Those browsers execute scripts
+	in DOM order, not network-receive order, so a long-polling script will block other
+	dynamically appended scripts from running until it completes. By using an iframe
+	for the dojo.io.script requests, this issue can be avoided.
+
+	* xhrMultiPart.js - Constructs multi-part mime XHR requests. Useful when wanting
+	multi-part requests but not using a form with a file input. Note that it does not
+	allow you to send files from local disks -- a form with a file input is required
+	for that use case. xhrMultipart is not useful in that use case.
+
+	* xhrPlugins.js - An adapter registry for having multiple XHR handlers (like
+	XDomainRequest, CS-XHR, proxy, and window.name)
+
+	* windowName.js - Cross-domain transport using window.name
+	xhrWindowNamePlugin.js - window.name plugin for XHR adapter registry
+
+	* httpParse.js - HTTP message parser. Parses to an XHR like interface.
+	
+	* OAuth.js - Object to be used for signing OpenAuth requests.  Includes easy
+		wrappers for xhr.
+	
+-------------------------------------------------------------------------------
+Dependencies:
+
+DojoX IO xhrMultiPart depends on Dojo Core and DojoX UUID's generateRandomUuid 
+function.
+
+xhrWindowNamePlugin depends on dojox.secure.capability for safe JSON parsing
+
+OAuth depends on dojox.encoding.digests.SHA1.
+-------------------------------------------------------------------------------
+Documentation
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/uuid.js
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/uuid/*
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/secure/*
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/encoding/digests/*
+
+Install into the following directory structure:
+/dojox/uuid/
+/dojox/secure/
+/dojox/encoding/digests/
+
+AND
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/io/*
+
+Install into the following directory structure:
+/dojox/io/
+
+...both of which should be at the same level as your Dojo checkout.
+-------------------------------------------------------------------------------
+Additional Notes
+
+The information contained in this README does not pertain to DojoX XHR IFrame Proxy.  
+For that information see proxy/README.
diff --git a/dojox/io/httpParse.js b/dojox/io/httpParse.js
new file mode 100644
index 0000000..4c2d578
--- /dev/null
+++ b/dojox/io/httpParse.js
@@ -0,0 +1,66 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.io.httpParse"]){
+dojo._hasResource["dojox.io.httpParse"]=true;
+dojo.provide("dojox.io.httpParse");
+dojox.io.httpParse=function(_1,_2,_3){
+var _4=[];
+var _5=_1.length;
+do{
+var _6={};
+var _7=_1.match(/(\n*[^\n]+)/);
+if(!_7){
+return null;
+}
+_1=_1.substring(_7[0].length+1);
+_7=_7[1];
+var _8=_1.match(/([^\n]+\n)*/)[0];
+_1=_1.substring(_8.length);
+var _9=_1.substring(0,1);
+_1=_1.substring(1);
+_8=(_2||"")+_8;
+var _a=_8;
+_8=_8.match(/[^:\n]+:[^\n]+\n/g);
+for(var j=0;j<_8.length;j++){
+var _c=_8[j].indexOf(":");
+_6[_8[j].substring(0,_c)]=_8[j].substring(_c+1).replace(/(^[ \r\n]*)|([ \r\n]*)$/g,"");
+}
+_7=_7.split(" ");
+var _d={status:parseInt(_7[1],10),statusText:_7[2],readyState:3,getAllResponseHeaders:function(){
+return _a;
+},getResponseHeader:function(_e){
+return _6[_e];
+}};
+var _f=_6["Content-Length"];
+var _10;
+if(_f){
+if(_f<=_1.length){
+_10=_1.substring(0,_f);
+}else{
+return _4;
+}
+}else{
+if((_10=_1.match(/(.*)HTTP\/\d\.\d \d\d\d[\w\s]*\n/))){
+_10=_10[0];
+}else{
+if(!_3||_9=="\n"){
+_10=_1;
+}else{
+return _4;
+}
+}
+}
+_4.push(_d);
+_1=_1.substring(_10.length);
+_d.responseText=_10;
+_d.readyState=4;
+_d._lastIndex=_5-_1.length;
+}while(_1);
+return _4;
+};
+}
diff --git a/dojox/io/proxy/README b/dojox/io/proxy/README
new file mode 100644
index 0000000..8898a56
--- /dev/null
+++ b/dojox/io/proxy/README
@@ -0,0 +1,82 @@
+-------------------------------------------------------------------------------
+Project Name
+-------------------------------------------------------------------------------
+Version 0.6
+Release date: 01/31/2008
+-------------------------------------------------------------------------------
+Project state:
+experimental
+-------------------------------------------------------------------------------
+Credits
+	James Burke (jburke at dojotoolkit.org)
+-------------------------------------------------------------------------------
+Project description
+
+The XHR IFrame Proxy (xip) allows you to do cross-domain XMLHttpRequests (XHRs).
+It works by using two iframes, one your domain (xip_client.html), one on the 
+other domain (xip_server.html). They use fragment IDs in the iframe URLs to pass
+messages to each other. The xip.js file defines dojox.io.proxy.xip. This module
+intercepts XHR calls made by the Dojo XHR methods (dojo.xhr* methods). The module
+returns a facade object that acts like an XHR object. Once send is called on the
+facade, the facade's data is serialized, given to xip_client.html. xip_client.html
+then passes the serialized data to xip_server.html by changing xip_server.html's
+URL fragment ID (the #xxxx part of an URL). xip_server.html deserializes the
+message fragments, and does an XHR call, gets the response, and serializes the
+data. The serialized data is then passed back to xip_client.html by changing
+xip_client.html's fragment ID. Then the response is deserialized and used as
+the response inside the facade XHR object that was created by dojox.io.proxy.xip.
+-------------------------------------------------------------------------------
+Dependencies:
+
+xip.js: Dojo Core, dojox.data.dom
+xip_client.html: none
+xip_server.html: none (but see Additional Notes section)
+-------------------------------------------------------------------------------
+Documentation
+
+There is some documentation that applies to the Dojo 0.4.x version of these files:
+http://dojotoolkit.org/book/dojo-book-0-4/part-5-connecting-pieces/i-o/cross-domain-xmlhttprequest-using-iframe-proxy
+
+The general theory still applies to this code, but the specifics are different
+for the Dojo 0.9+ codebase. Doc updates hopefully after the basic code is ported.
+
+The current implementation destroys the iframes used for a request after the request
+completes. This seems to cause a memory leak, particularly in IE. So, it is not
+suited for doing polling cross-domain requests.
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojox SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/io/proxy/xip.js
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/io/proxy/xip_client.html
+
+Install into the following directory structure:
+/dojox/io/proxy/
+
+...which should be at the same level as your Dojo checkout.
+
+Grab the following from the Dojox SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/io/proxy/xip_server.html
+
+and install it on the domain that you want to allow receiving cross-domain
+requests. Be sure to read the documentation, the Additional Notes below, and
+the in-file comments.
+-------------------------------------------------------------------------------
+Additional Notes
+
+xip_client.html and xip_server.html do not work right away. You need to uncomment
+out the script tags in the files. Additionally, xip_server.html requires a JS file,
+isAllowed.js, to be defined. See the notes in xip_server.html for more informaiton.
+
+XDOMAIN BUILD INSTRUCTIONS:
+The dojox.io.proxy module requires some setup to use with an xdomain build.
+The xip_client.html file has to be served from the same domain as your web page.
+It cannot be served from the domain that has the xdomain build. Download xip_client.html
+and install it on your server. Then set djConfig.xipClientUrl to the local path
+of xip_client.html (just use a path, not a whole URL, since it will be on the same
+domain as the page). The path to the file should be the path relative to the web
+page that is using dojox.io.proxy.
+
+
+
+
diff --git a/dojox/io/proxy/tests/frag.xml b/dojox/io/proxy/tests/frag.xml
new file mode 100644
index 0000000..6904bba
--- /dev/null
+++ b/dojox/io/proxy/tests/frag.xml
@@ -0,0 +1,4 @@
+<response>
+<foo>This is the foo text node value</foo>
+<bar>This is the bar text node value</bar>
+</response>
diff --git a/dojox/io/proxy/tests/xip.html b/dojox/io/proxy/tests/xip.html
new file mode 100644
index 0000000..5a5ba5f
--- /dev/null
+++ b/dojox/io/proxy/tests/xip.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+        "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>XHR IFrame Proxy Tests</title>
+	<style type="text/css">
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../../../dijit/themes/tundra/tundra.css";
+		@import "../../../../dijit/themes/dijit.css";
+	</style>
+
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		djConfig="isDebug:true"></script>
+	<script type="text/javascript" src="../xip.js"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.io.proxy.xip");
+
+		function testXmlGet(){
+/*
+			//Normal xhrGet call.
+			dojo.xhrGet({
+				url: "frag.xml",
+				handleAs: "xml",
+				load: function(result, ioArgs){
+					var foo = result.getElementsByTagName("foo").item(0);
+
+					dojo.byId("xmlGetOut").innerHTML = "Success: First foobar value is: " + foo.firstChild.nodeValue;
+				}
+			});
+*/
+
+			//xip xhrGet call.
+			dojo.xhrGet({
+				iframeProxyUrl: "../xip_server.html",
+				url: "tests/frag.xml",
+				handleAs: "xml",
+				load: function(result, ioArgs){
+					var foo = result.getElementsByTagName("foo").item(0);
+
+					dojo.byId("xmlGetOut").innerHTML = "Success: First foobar value is: " + foo.firstChild.nodeValue;
+				}
+			});
+
+		}
+
+		dojo.addOnLoad(function(){
+
+		});
+	</script>
+</head>
+<body class="tundra">
+
+<h1>XHR IFrame Proxy Tests</h1>
+<p>Run this test from a web server, not from local disk.</p>
+
+<p>
+<button onclick="testXmlGet()">Test XML GET</button>
+</p>
+<div id="xmlGetOut"></div>
+
+</body>
+</html>
diff --git a/dojox/io/proxy/xip.js b/dojox/io/proxy/xip.js
new file mode 100644
index 0000000..568113b
--- /dev/null
+++ b/dojox/io/proxy/xip.js
@@ -0,0 +1,260 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.io.proxy.xip"]){
+dojo._hasResource["dojox.io.proxy.xip"]=true;
+dojo.provide("dojox.io.proxy.xip");
+dojo.require("dojo.io.iframe");
+dojo.require("dojox.data.dom");
+dojox.io.proxy.xip={xipClientUrl:((dojo.config||djConfig)["xipClientUrl"])||dojo.moduleUrl("dojox.io.proxy","xip_client.html"),urlLimit:4000,_callbackName:(dojox._scopeName||"dojox")+".io.proxy.xip.fragmentReceived",_state:{},_stateIdCounter:0,_isWebKit:navigator.userAgent.indexOf("WebKit")!=-1,send:function(_1){
+var _2=this.xipClientUrl;
+if(_2.split(":")[0].match(/javascript/i)||_1._ifpServerUrl.split(":")[0].match(/javascript/i)){
+return;
+}
+var _3=_2.indexOf(":");
+var _4=_2.indexOf("/");
+if(_3==-1||_4<_3){
+var _5=window.location.href;
+if(_4==0){
+_2=_5.substring(0,_5.indexOf("/",9))+_2;
+}else{
+_2=_5.substring(0,(_5.lastIndexOf("/")+1))+_2;
+}
+}
+this.fullXipClientUrl=_2;
+if(typeof document.postMessage!="undefined"){
+document.addEventListener("message",dojo.hitch(this,this.fragmentReceivedEvent),false);
+}
+this.send=this._realSend;
+return this._realSend(_1);
+},_realSend:function(_6){
+var _7="XhrIframeProxy"+(this._stateIdCounter++);
+_6._stateId=_7;
+var _8=_6._ifpServerUrl+"#0:init:id="+_7+"&client="+encodeURIComponent(this.fullXipClientUrl)+"&callback="+encodeURIComponent(this._callbackName);
+this._state[_7]={facade:_6,stateId:_7,clientFrame:dojo.io.iframe.create(_7,"",_8),isSending:false,serverUrl:_6._ifpServerUrl,requestData:null,responseMessage:"",requestParts:[],idCounter:1,partIndex:0,serverWindow:null};
+return _7;
+},receive:function(_9,_a){
+var _b={};
+var _c=_a.split("&");
+for(var i=0;i<_c.length;i++){
+if(_c[i]){
+var _e=_c[i].split("=");
+_b[decodeURIComponent(_e[0])]=decodeURIComponent(_e[1]);
+}
+}
+var _f=this._state[_9];
+var _10=_f.facade;
+_10._setResponseHeaders(_b.responseHeaders);
+if(_b.status==0||_b.status){
+_10.status=parseInt(_b.status,10);
+}
+if(_b.statusText){
+_10.statusText=_b.statusText;
+}
+if(_b.responseText){
+_10.responseText=_b.responseText;
+var _11=_10.getResponseHeader("Content-Type");
+if(_11){
+var _12=_11.split(";")[0];
+if(_12.indexOf("application/xml")==0||_12.indexOf("text/xml")==0){
+_10.responseXML=dojox.data.dom.createDocument(_b.responseText,_11);
+}
+}
+}
+_10.readyState=4;
+this.destroyState(_9);
+},frameLoaded:function(_13){
+var _14=this._state[_13];
+var _15=_14.facade;
+var _16=[];
+for(var _17 in _15._requestHeaders){
+_16.push(_17+": "+_15._requestHeaders[_17]);
+}
+var _18={uri:_15._uri};
+if(_16.length>0){
+_18.requestHeaders=_16.join("\r\n");
+}
+if(_15._method){
+_18.method=_15._method;
+}
+if(_15._bodyData){
+_18.data=_15._bodyData;
+}
+this.sendRequest(_13,dojo.objectToQuery(_18));
+},destroyState:function(_19){
+var _1a=this._state[_19];
+if(_1a){
+delete this._state[_19];
+var _1b=_1a.clientFrame.parentNode;
+_1b.removeChild(_1a.clientFrame);
+_1a.clientFrame=null;
+_1a=null;
+}
+},createFacade:function(){
+if(arguments&&arguments[0]&&arguments[0].iframeProxyUrl){
+return new dojox.io.proxy.xip.XhrIframeFacade(arguments[0].iframeProxyUrl);
+}else{
+return dojox.io.proxy.xip._xhrObjOld.apply(dojo,arguments);
+}
+},sendRequest:function(_1c,_1d){
+var _1e=this._state[_1c];
+if(!_1e.isSending){
+_1e.isSending=true;
+_1e.requestData=_1d||"";
+_1e.serverWindow=frames[_1e.stateId];
+if(!_1e.serverWindow){
+_1e.serverWindow=document.getElementById(_1e.stateId).contentWindow;
+}
+if(typeof document.postMessage=="undefined"){
+if(_1e.serverWindow.contentWindow){
+_1e.serverWindow=_1e.serverWindow.contentWindow;
+}
+}
+this.sendRequestStart(_1c);
+}
+},sendRequestStart:function(_1f){
+var _20=this._state[_1f];
+_20.requestParts=[];
+var _21=_20.requestData;
+var _22=_20.serverUrl.length;
+var _23=this.urlLimit-_22;
+var _24=0;
+while((_21.length-_24)+_22>this.urlLimit){
+var _25=_21.substring(_24,_24+_23);
+var _26=_25.lastIndexOf("%");
+if(_26==_25.length-1||_26==_25.length-2){
+_25=_25.substring(0,_26);
+}
+_20.requestParts.push(_25);
+_24+=_25.length;
+}
+_20.requestParts.push(_21.substring(_24,_21.length));
+_20.partIndex=0;
+this.sendRequestPart(_1f);
+},sendRequestPart:function(_27){
+var _28=this._state[_27];
+if(_28.partIndex<_28.requestParts.length){
+var _29=_28.requestParts[_28.partIndex];
+var cmd="part";
+if(_28.partIndex+1==_28.requestParts.length){
+cmd="end";
+}else{
+if(_28.partIndex==0){
+cmd="start";
+}
+}
+this.setServerUrl(_27,cmd,_29);
+_28.partIndex++;
+}
+},setServerUrl:function(_2b,cmd,_2d){
+var _2e=this.makeServerUrl(_2b,cmd,_2d);
+var _2f=this._state[_2b];
+if(this._isWebKit){
+_2f.serverWindow.location=_2e;
+}else{
+_2f.serverWindow.location.replace(_2e);
+}
+},makeServerUrl:function(_30,cmd,_32){
+var _33=this._state[_30];
+var _34=_33.serverUrl+"#"+(_33.idCounter++)+":"+cmd;
+if(_32){
+_34+=":"+_32;
+}
+return _34;
+},fragmentReceivedEvent:function(evt){
+if(evt.uri.split("#")[0]==this.fullXipClientUrl){
+this.fragmentReceived(evt.data);
+}
+},fragmentReceived:function(_36){
+var _37=_36.indexOf("#");
+var _38=_36.substring(0,_37);
+var _39=_36.substring(_37+1,_36.length);
+var msg=this.unpackMessage(_39);
+var _3b=this._state[_38];
+switch(msg.command){
+case "loaded":
+this.frameLoaded(_38);
+break;
+case "ok":
+this.sendRequestPart(_38);
+break;
+case "start":
+_3b.responseMessage=""+msg.message;
+this.setServerUrl(_38,"ok");
+break;
+case "part":
+_3b.responseMessage+=msg.message;
+this.setServerUrl(_38,"ok");
+break;
+case "end":
+this.setServerUrl(_38,"ok");
+_3b.responseMessage+=msg.message;
+this.receive(_38,_3b.responseMessage);
+break;
+}
+},unpackMessage:function(_3c){
+var _3d=_3c.split(":");
+var _3e=_3d[1];
+_3c=_3d[2]||"";
+var _3f=null;
+if(_3e=="init"){
+var _40=_3c.split("&");
+_3f={};
+for(var i=0;i<_40.length;i++){
+var _42=_40[i].split("=");
+_3f[decodeURIComponent(_42[0])]=decodeURIComponent(_42[1]);
+}
+}
+return {command:_3e,message:_3c,config:_3f};
+}};
+dojox.io.proxy.xip._xhrObjOld=dojo._xhrObj;
+dojo._xhrObj=dojox.io.proxy.xip.createFacade;
+dojox.io.proxy.xip.XhrIframeFacade=function(_43){
+this._requestHeaders={};
+this._allResponseHeaders=null;
+this._responseHeaders={};
+this._method=null;
+this._uri=null;
+this._bodyData=null;
+this.responseText=null;
+this.responseXML=null;
+this.status=null;
+this.statusText=null;
+this.readyState=0;
+this._ifpServerUrl=_43;
+this._stateId=null;
+};
+dojo.extend(dojox.io.proxy.xip.XhrIframeFacade,{open:function(_44,uri){
+this._method=_44;
+this._uri=uri;
+this.readyState=1;
+},setRequestHeader:function(_46,_47){
+this._requestHeaders[_46]=_47;
+},send:function(_48){
+this._bodyData=_48;
+this._stateId=dojox.io.proxy.xip.send(this);
+this.readyState=2;
+},abort:function(){
+dojox.io.proxy.xip.destroyState(this._stateId);
+},getAllResponseHeaders:function(){
+return this._allResponseHeaders;
+},getResponseHeader:function(_49){
+return this._responseHeaders[_49];
+},_setResponseHeaders:function(_4a){
+if(_4a){
+this._allResponseHeaders=_4a;
+_4a=_4a.replace(/\r/g,"");
+var _4b=_4a.split("\n");
+for(var i=0;i<_4b.length;i++){
+if(_4b[i]){
+var _4d=_4b[i].split(": ");
+this._responseHeaders[_4d[0]]=_4d[1];
+}
+}
+}
+}});
+}
diff --git a/dojox/io/proxy/xip_client.html b/dojox/io/proxy/xip_client.html
new file mode 100644
index 0000000..c51a839
--- /dev/null
+++ b/dojox/io/proxy/xip_client.html
@@ -0,0 +1,102 @@
+<!--
+	/*
+		Copyright (c) 2004-2008, The Dojo Foundation
+		All Rights Reserved.
+	
+		Licensed under the Academic Free License version 2.1 or above OR the
+		modified BSD license. For more information on Dojo licensing, see:
+	
+			http://dojotoolkit.org/community/licensing.shtml
+	*/
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+	<title></title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<!-- Security protection: uncomment the start and end script tags to enable. -->
+	<!-- script type="text/javascript" -->
+	// <!--
+	
+	function pollHash(){
+		//Can't use location.hash because at least Firefox does a decodeURIComponent on it.
+		var urlParts = window.location.href.split("#");
+		if(urlParts.length == 2){
+			var newHash = urlParts[1];
+			if(newHash != xipCurrentHash){
+				try{
+					callMaster(xipStateId, newHash);
+				}catch(e){
+					//Make sure to not keep processing the error hash value.
+					xipCurrentHash = newHash;
+					throw e;
+				}
+				xipCurrentHash = newHash;
+			}
+		}
+	}
+
+	function unpackMessage(encodedMessage){
+		var parts = encodedMessage.split(":");
+		var command = parts[1];
+		encodedMessage = parts[2] || "";
+
+		var config = null;
+		if(command == "init"){
+			var configParts = encodedMessage.split("&");
+			config = {};
+			for(var i = 0; i < configParts.length; i++){
+				var nameValue = configParts[i].split("=");
+				config[decodeURIComponent(nameValue[0])] = decodeURIComponent(nameValue[1]);
+			}
+		}
+		return {command: command, message: encodedMessage, config: config};
+	}
+
+	//************** Init **************************
+	xipCurrentHash = "";
+	
+	//Decode the init params
+	var fragId = window.location.href.split("#")[1];
+	var config = unpackMessage(fragId).config;
+
+	xipStateId = config.id;
+	xipMasterFrame = parent.parent;
+
+	//Set up an HTML5 messaging publisher if postMessage exists.
+	//As of this writing, this is only useful to get Opera 9.25+ to work.
+	if(typeof document.postMessage != "undefined"){
+		callMaster = function(stateId, message){
+			xipMasterFrame.document.postMessage(stateId + "#" + message);
+		}
+	}else{
+		var parts = config.callback.split(".");
+		xipCallbackObject = xipMasterFrame;
+		for(var i = 0; i < parts.length - 1; i++){
+			xipCallbackObject = xipCallbackObject[parts[i]];
+		}
+		xipCallback = parts[parts.length - 1];
+
+		callMaster = function(stateId, message){
+			xipCallbackObject[xipCallback](stateId + "#" + message);
+		}
+	}
+
+	//Call the master frame to let it know it is OK to start sending.
+	callMaster(xipStateId, "0:loaded");
+	
+	//Start counter to inspect hash value.
+	setInterval(pollHash, 10);
+
+	// -->
+	<!-- </script> -->
+</head>
+<body>
+	<h4>The Dojo Toolkit -- xip_client.html</h4>
+
+	<p>This file is used for Dojo's XMLHttpRequest Iframe Proxy. This is the "client" file used
+	internally by dojox.io.proxy.xip.</p>
+</body>
+</html>
diff --git a/dojox/io/proxy/xip_server.html b/dojox/io/proxy/xip_server.html
new file mode 100644
index 0000000..01b7274
--- /dev/null
+++ b/dojox/io/proxy/xip_server.html
@@ -0,0 +1,382 @@
+<!--
+	/*
+		Copyright (c) 2004-2008, The Dojo Foundation
+		All Rights Reserved.
+	
+		Licensed under the Academic Free License version 2.1 or above OR the
+		modified BSD license. For more information on Dojo licensing, see:
+	
+			http://dojotoolkit.org/community/licensing.shtml
+	*/
+	Pieces taken from Dojo source to make this file stand-alone
+-->
+<html>
+<head>
+	<title></title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<script type="text/javascript" src="isAllowed.js"></script>
+	<!--
+	BY DEFAULT THIS FILE DOES NOT WORK SO THAT YOU DON'T ACCIDENTALLY EXPOSE
+	ALL OF YOUR XHR-ENABLED SERVICES ON YOUR SITE. 
+	
+	In order for this file to work, you need to uncomment the start and end script tags,
+	and you should define a function with the following signature:
+	
+	function isAllowedRequest(request){
+		return false;	
+	}
+	
+	Return true out of the function if you want to allow the cross-domain request.
+	
+	DON'T DEFINE THIS FUNCTION IN THIS FILE! Define it in a separate file called isAllowed.js
+	and include it in this page with a script tag that has a src attribute pointing to the file.
+	See the very first script tag in this file for an example. You do not have to place the
+	script file in the same directory as this file, just update the path above if you move it
+	somewhere else.
+	
+	Customize the isAllowedRequest function to restrict what types of requests are allowed
+	for this server. The request object has the following properties:
+	- requestHeaders: an object with the request headers that are to be added to
+	                  the XHR request.
+	- method: the HTTP method (GET, POST, etc...)
+	- uri: The URI for the request.
+	- data: The URL-encoded data for the request. For a GET request, this would
+	        be the querystring parameters. For a POST request, it wll be the
+	        body data.
+	        
+	See xip_client.html for more info on the xip fragment identifier protocol.	
+	-->
+	
+	<!-- Security protection: uncomment the script tag to enable. -->
+	<!-- script type="text/javascript" -->
+	// <!--
+		//Core XHR handling taken from Dojo IO code.
+		dojo = {};
+		dojo.hostenv = {};
+		// These are in order of decreasing likelihood; this will change in time.
+		dojo.hostenv._XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'];
+		
+		dojo.hostenv.getXmlhttpObject = function(){
+				var http = null;
+			var last_e = null;
+			try{ http = new XMLHttpRequest(); }catch(e){}
+				if(!http){
+				for(var i=0; i<3; ++i){
+					var progid = dojo.hostenv._XMLHTTP_PROGIDS[i];
+					try{
+						http = new ActiveXObject(progid);
+					}catch(e){
+						last_e = e;
+					}
+		
+					if(http){
+						dojo.hostenv._XMLHTTP_PROGIDS = [progid];  // so faster next time
+						break;
+					}
+				}
+		
+				/*if(http && !http.toString) {
+					http.toString = function() { "[object XMLHttpRequest]"; }
+				}*/
+			}
+		
+			if(!http){
+				throw "xip_server.html: XMLHTTP not available: " + last_e;
+			}
+		
+			return http;
+		}
+
+		dojo.setHeaders = function(http, headers){
+			if(headers) {
+				for(var header in headers) {
+					var headerValue = headers[header];
+					http.setRequestHeader(header, headerValue);
+				}
+			}
+		}
+
+	//MSIE has the lowest limit for URLs with fragment identifiers,
+	//at around 4K. Choosing a slightly smaller number for good measure.
+	xipUrlLimit = 4000;
+	xipIdCounter = 1;
+
+	function xipServerInit(){
+		xipStateId = "";
+		xipCurrentHash = "";
+		xipRequestMessage = "";
+		xipResponseParts = [];
+		xipPartIndex = 0;
+	}
+
+	function pollHash(){
+		//Can't use location.hash because at least Firefox does a decodeURIComponent on it.
+		var urlParts = window.location.href.split("#");
+		if(urlParts.length == 2){
+			var newHash = urlParts[1];
+			if(newHash != xipCurrentHash){
+				try{
+					messageReceived(newHash);
+				}catch(e){
+					//Make sure to not keep processing the error hash value.
+					xipCurrentHash = newHash;
+					throw e;
+				}
+				xipCurrentHash = newHash;
+			}
+		}
+	}
+
+	function messageReceived(encodedData){
+		var msg = unpackMessage(encodedData);
+		
+		switch(msg.command){
+			case "ok":
+				sendResponsePart();
+				break;
+			case "start":
+				xipRequestMessage = "";
+				xipRequestMessage += msg.message;
+				setClientUrl("ok");
+				break;
+			case "part":
+				xipRequestMessage += msg.message;			
+				setClientUrl("ok");
+				break;
+			case "end":
+				setClientUrl("ok");
+				xipRequestMessage += msg.message;
+				sendXhr();
+				break;
+		}
+	}
+
+	function sendResponse(encodedData){
+		//Break the message into parts, if necessary.
+		xipResponseParts = [];
+		var resData = encodedData;
+		var urlLength = xipClientUrl.length;
+		var partLength = xipUrlLimit - urlLength;
+		var resIndex = 0;
+
+		while((resData.length - resIndex) + urlLength > xipUrlLimit){
+			var part = resData.substring(resIndex, resIndex + partLength);
+			//Safari will do some extra hex escaping unless we keep the original hex
+			//escaping complete.
+			var percentIndex = part.lastIndexOf("%");
+			if(percentIndex == part.length - 1 || percentIndex == part.length - 2){
+				part = part.substring(0, percentIndex);
+			}
+			xipResponseParts.push(part);
+			resIndex += part.length;
+		}
+		xipResponseParts.push(resData.substring(resIndex, resData.length));
+		
+		xipPartIndex = 0;
+		sendResponsePart();
+	}
+	
+	function sendResponsePart(){
+		if(xipPartIndex < xipResponseParts.length){
+			//Get the message part.
+			var partData = xipResponseParts[xipPartIndex];
+			
+			//Get the command.
+			var cmd = "part";
+			if(xipPartIndex + 1 == xipResponseParts.length){
+				cmd = "end";
+			}else if (xipPartIndex == 0){
+				cmd = "start";
+			}
+
+			setClientUrl(cmd, partData);
+			xipPartIndex++;
+		}else{
+			xipServerInit();
+		}
+	}
+
+	function setClientUrl(cmd, message){
+		var clientUrl = makeClientUrl(cmd, message);
+		//Safari won't let us replace across domains.
+		if(navigator.userAgent.indexOf("Safari") == -1){
+			xipClientWindow.location.replace(clientUrl);
+		}else{
+			xipClientWindow.location = clientUrl;
+		}
+	}
+
+	function makeClientUrl(cmd, message){
+		var clientUrl = xipClientUrl + "#" + (xipIdCounter++) + ":" + cmd;
+		if(message){
+			clientUrl += ":" + message;
+		}
+		return clientUrl
+	}
+
+	function xhrDone(xhr){
+		/* Need to pull off and return the following data:
+			- responseHeaders
+			- status
+			- statusText
+			- responseText
+		*/
+		var response = {};
+	
+		if(typeof(xhr.getAllResponseHeaders) != "undefined"){
+			var allHeaders = xhr.getAllResponseHeaders();
+			if(allHeaders){
+				response.responseHeaders = allHeaders;
+			}
+		}
+		
+		if(xhr.status == 0 || xhr.status){
+			response.status = xhr.status;
+		}
+		
+		if(xhr.statusText){
+			response.statusText = xhr.statusText;
+		}
+		
+		if(xhr.responseText){
+			response.responseText = xhr.responseText;
+		}
+	
+		//Build a string of the response object.
+		var result = "";
+		var isFirst = true;
+		for (var param in response){
+			if(isFirst){
+				isFirst = false;
+			}else{
+				result += "&";
+			}
+			result += param + "=" + encodeURIComponent(response[param]);
+		}
+		sendResponse(result);
+	}
+
+	function sendXhr(){
+		var request = {};
+		var nvPairs = xipRequestMessage.split("&");
+		var i = 0;
+		var nameValue = null;
+		for(i = 0; i < nvPairs.length; i++){
+			if(nvPairs[i]){
+				var nameValue = nvPairs[i].split("=");
+				request[decodeURIComponent(nameValue[0])] = decodeURIComponent(nameValue[1]);
+			}
+		}
+
+		//Split up the request headers, if any.
+		var headers = {};
+		if(request.requestHeaders){
+			nvPairs = request.requestHeaders.split("\r\n");
+			for(i = 0; i < nvPairs.length; i++){
+				if(nvPairs[i]){
+					nameValue = nvPairs[i].split(": ");
+					headers[decodeURIComponent(nameValue[0])] = decodeURIComponent(nameValue[1]);
+				}
+			}
+
+			request.requestHeaders = headers;
+		}
+		
+		if(isAllowedRequest(request)){
+		
+			//The request is allowed, so set up the XHR object.
+			var xhr = dojo.hostenv.getXmlhttpObject();
+			
+			//Start timer to look for readyState.
+			var xhrIntervalId = setInterval(function(){
+			
+				if(xhr.readyState == 4){
+					clearInterval(xhrIntervalId);
+					xhrDone(xhr);
+				}
+			}, 10);
+
+			//Actually start up the XHR request.
+			xhr.open(request.method, request.uri, true);
+			dojo.setHeaders(xhr, request.requestHeaders);
+			
+			var content = "";
+			if(request.data){
+				content = request.data;
+			}
+
+			try{
+				xhr.send(content);
+			}catch(e){
+				if(typeof xhr.abort == "function"){
+					xhr.abort();
+					xhrDone({status: 404, statusText: "xip_server.html error: " + e});
+				}
+			}
+		}
+	}
+
+	function unpackMessage(encodedMessage){
+		var parts = encodedMessage.split(":");
+		var command = parts[1];
+		encodedMessage = parts[2] || "";
+
+		var config = null;
+		if(command == "init"){
+			var configParts = encodedMessage.split("&");
+			config = {};
+			for(var i = 0; i < configParts.length; i++){
+				var nameValue = configParts[i].split("=");
+				config[decodeURIComponent(nameValue[0])] = decodeURIComponent(nameValue[1]);
+			}
+		}
+		return {command: command, message: encodedMessage, config: config};
+	}
+
+	function onServerLoad(){
+		xipServerInit();
+
+		//Decode the init params
+		var config = unpackMessage(window.location.href.split("#")[1]).config;
+
+		xipStateId = config.id;
+		xipClientUrl = config.client;
+		
+		//Make sure we don't have a javascript: url, just for good measure.
+		if(xipClientUrl.split(":")[0].match(/javascript/i)){
+			throw "Invalid client URL";
+		}
+		if(!xipStateId.match(/^XhrIframeProxy[0-9]+$/)){
+			throw "Invalid state ID";
+		}
+	
+		setInterval(pollHash, 10);
+		
+		var serverUrl = window.location.href.split("#")[0];
+		document.getElementById("iframeHolder").innerHTML = '<iframe name="'
+			+ xipStateId + '_clientEndPoint'
+			+ '" src="javascript:false">'
+			+ '</iframe>';
+		xipClientWindow = document.getElementsByTagName("iframe")[0];
+		xipClientWindow.src = makeClientUrl("init", 'id=' + xipStateId + "&callback=" + encodeURIComponent(config.callback));
+		if(xipClientWindow.contentWindow){
+			xipClientWindow = xipClientWindow.contentWindow;
+		}
+	}
+
+	if(typeof(window.addEventListener) == "undefined"){
+		window.attachEvent("onload", onServerLoad);
+	}else{
+		window.addEventListener('load', onServerLoad, false);
+	}
+	// -->
+	<!-- </script> -->
+</head>
+<body>
+	<h4>The Dojo Toolkit -- xip_server.html</h4>
+
+	<p>This file is used for Dojo's XMLHttpRequest Iframe Proxy. This is the the file
+	that should go on the server that will actually be doing the XHR request.</p>
+	<div id="iframeHolder"></div>
+</body>
+</html>
diff --git a/dojox/io/scriptFrame.js b/dojox/io/scriptFrame.js
new file mode 100644
index 0000000..68387b1
--- /dev/null
+++ b/dojox/io/scriptFrame.js
@@ -0,0 +1,52 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.io.scriptFrame"]){
+dojo._hasResource["dojox.io.scriptFrame"]=true;
+dojo.provide("dojox.io.scriptFrame");
+dojo.require("dojo.io.script");
+dojo.require("dojo.io.iframe");
+(function(){
+var _1=dojo.io.script;
+dojox.io.scriptFrame={_waiters:{},_loadedIds:{},_getWaiters:function(_2){
+return this._waiters[_2]||(this._waiters[_2]=[]);
+},_fixAttachUrl:function(_3){
+},_loaded:function(_4){
+var _5=this._getWaiters(_4);
+this._loadedIds[_4]=true;
+this._waiters[_4]=null;
+for(var i=0;i<_5.length;i++){
+var _7=_5[i];
+_7.frameDoc=dojo.io.iframe.doc(dojo.byId(_4));
+_1.attach(_7.id,_7.url,_7.frameDoc);
+}
+}};
+var _8=_1._canAttach;
+var _9=dojox.io.scriptFrame;
+_1._canAttach=function(_a){
+var _b=_a.args.frameDoc;
+if(_b&&dojo.isString(_b)){
+var _c=dojo.byId(_b);
+var _d=_9._getWaiters(_b);
+if(!_c){
+_d.push(_a);
+dojo.io.iframe.create(_b,dojox._scopeName+".io.scriptFrame._loaded('"+_b+"');");
+}else{
+if(_9._loadedIds[_b]){
+_a.frameDoc=dojo.io.iframe.doc(_c);
+this.attach(_a.id,_a.url,_a.frameDoc);
+}else{
+_d.push(_a);
+}
+}
+return false;
+}else{
+return _8.apply(this,arguments);
+}
+};
+})();
+}
diff --git a/dojox/io/windowName.js b/dojox/io/windowName.js
new file mode 100644
index 0000000..7566ca8
--- /dev/null
+++ b/dojox/io/windowName.js
@@ -0,0 +1,156 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.io.windowName"]){
+dojo._hasResource["dojox.io.windowName"]=true;
+dojo.provide("dojox.io.windowName");
+dojox.io.windowName={send:function(_1,_2){
+_2.url+=(_2.url.match(/\?/)?"&":"?")+"windowname="+(_2.authElement?"auth":true);
+var _3=_2.authElement;
+var _4=function(_5){
+try{
+var _6=_7.ioArgs.frame.contentWindow.document;
+_6.write(" ");
+_6.close();
+}
+catch(e){
+}
+(_3||dojo.body()).removeChild(_7.ioArgs.outerFrame);
+return _5;
+};
+var _7=dojo._ioSetArgs(_2,_4,_4,_4);
+if(_2.timeout){
+setTimeout(function(){
+if(_7.fired==-1){
+_7.callback(new Error("Timeout"));
+}
+},_2.timeout);
+}
+var _8=dojox.io.windowName;
+if(dojo.body()){
+_8._send(_7,_1,_3,_2.onAuthLoad);
+}else{
+dojo.addOnLoad(function(){
+_8._send(_7,_1,_3,_2.onAuthLoad);
+});
+}
+return _7;
+},_send:function(_9,_a,_b,_c){
+var _d=_9.ioArgs;
+var _e=dojox.io.windowName._frameNum++;
+var _f=(dojo.config["dojoCallbackUrl"]||dojo.moduleUrl("dojo","resources/blank.html"))+"#"+_e;
+var _10=new dojo._Url(window.location,_f);
+var doc=dojo.doc;
+var _12=_b||dojo.body();
+function _13(_14){
+_14.style.width="100%";
+_14.style.height="100%";
+_14.style.border="0px";
+};
+if(dojo.isMoz&&![].reduce){
+var _15=doc.createElement("iframe");
+_13(_15);
+if(!_b){
+_15.style.display="none";
+}
+_12.appendChild(_15);
+var _16=_15.contentWindow;
+doc=_16.document;
+doc.write("<html><body margin='0px'><iframe style='width:100%;height:100%;border:0px' name='protectedFrame'></iframe></body></html>");
+doc.close();
+var _17=_16[0];
+_16.__defineGetter__(0,function(){
+});
+_16.__defineGetter__("protectedFrame",function(){
+});
+doc=_17.document;
+doc.write("<html><body margin='0px'></body></html>");
+doc.close();
+_12=doc.body;
+}
+var _18=_d.frame=_18=doc.createElement(dojo.isIE?"<iframe name=\""+_10+"\" onload=\"dojox.io.windowName["+_e+"]()\">":"iframe");
+_13(_18);
+_d.outerFrame=_15=_15||_18;
+if(!_b){
+_15.style.display="none";
+}
+var _19=0;
+function _1a(){
+var _1b=_18.contentWindow.name;
+if(typeof _1b=="string"){
+if(_1b!=_10){
+_19=2;
+_9.ioArgs.hash=_18.contentWindow.location.hash;
+_9.callback(_1b);
+}
+}
+};
+dojox.io.windowName[_e]=_18.onload=function(){
+try{
+if(!dojo.isMoz&&_18.contentWindow.location=="about:blank"){
+return;
+}
+}
+catch(e){
+}
+if(!_19){
+_19=1;
+if(_b){
+if(_c){
+_c();
+}
+}else{
+_18.contentWindow.location=_f;
+}
+}
+try{
+if(_19<2){
+_1a();
+}
+}
+catch(e){
+}
+};
+_18.name=_10;
+if(_a.match(/GET/i)){
+dojo._ioAddQueryToUrl(_d);
+_18.src=_d.url;
+_12.appendChild(_18);
+if(_18.contentWindow){
+_18.contentWindow.location.replace(_d.url);
+}
+}else{
+if(_a.match(/POST/i)){
+_12.appendChild(_18);
+var _1c=dojo.doc.createElement("form");
+dojo.body().appendChild(_1c);
+var _1d=dojo.queryToObject(_d.query);
+for(var i in _1d){
+var _1f=_1d[i];
+_1f=_1f instanceof Array?_1f:[_1f];
+for(var j=0;j<_1f.length;j++){
+var _21=doc.createElement("input");
+_21.type="hidden";
+_21.name=i;
+_21.value=_1f[j];
+_1c.appendChild(_21);
+}
+}
+_1c.method="POST";
+_1c.action=_d.url;
+_1c.target=_10;
+_1c.submit();
+_1c.parentNode.removeChild(_1c);
+}else{
+throw new Error("Method "+_a+" not supported with the windowName transport");
+}
+}
+if(_18.contentWindow){
+_18.contentWindow.name=_10;
+}
+},_frameNum:0};
+}
diff --git a/dojox/io/xhrMultiPart.js b/dojox/io/xhrMultiPart.js
new file mode 100644
index 0000000..2702614
--- /dev/null
+++ b/dojox/io/xhrMultiPart.js
@@ -0,0 +1,71 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.io.xhrMultiPart"]){
+dojo._hasResource["dojox.io.xhrMultiPart"]=true;
+dojo.provide("dojox.io.xhrMultiPart");
+dojo.require("dojox.uuid.generateRandomUuid");
+(function(){
+function _1(_2,_3){
+if(!_2["name"]&&!_2["content"]){
+throw new Error("Each part of a multi-part request requires 'name' and 'content'.");
+}
+var _4=[];
+_4.push("--"+_3,"Content-Disposition: form-data; name=\""+_2.name+"\""+(_2["filename"]?"; filename=\""+_2.filename+"\"":""));
+if(_2["contentType"]){
+var ct="Content-Type: "+_2.contentType;
+if(_2["charset"]){
+ct+="; Charset="+_2.charset;
+}
+_4.push(ct);
+}
+if(_2["contentTransferEncoding"]){
+_4.push("Content-Transfer-Encoding: "+_2.contentTransferEncoding);
+}
+_4.push("",_2.content);
+return _4;
+};
+function _6(_7,_8){
+var o=dojo.formToObject(_7),_a=[];
+for(var p in o){
+if(dojo.isArray(o[p])){
+dojo.forEach(o[p],function(_c){
+_a=_a.concat(_1({name:p,content:_c},_8));
+});
+}else{
+_a=_a.concat(_1({name:p,content:o[p]},_8));
+}
+}
+return _a;
+};
+dojox.io.xhrMultiPart=function(_d){
+if(!_d["file"]&&!_d["content"]&&!_d["form"]){
+throw new Error("content, file or form must be provided to dojox.io.xhrMultiPart's arguments");
+}
+var _e=dojox.uuid.generateRandomUuid(),_f=[],out="";
+if(_d["file"]||_d["content"]){
+var v=_d["file"]||_d["content"];
+dojo.forEach((dojo.isArray(v)?v:[v]),function(_12){
+_f=_f.concat(_1(_12,_e));
+});
+}else{
+if(_d["form"]){
+if(dojo.query("input[type=file]",_d["form"]).length){
+throw new Error("dojox.io.xhrMultiPart cannot post files that are values of an INPUT TYPE=FILE.  Use dojo.io.iframe.send() instead.");
+}
+_f=_6(_d["form"],_e);
+}
+}
+if(_f.length){
+_f.push("--"+_e+"--","");
+out=_f.join("\r\n");
+}
+
+return dojo.rawXhrPost(dojo.mixin(_d,{contentType:"multipart/form-data; boundary="+_e,postData:out}));
+};
+})();
+}
diff --git a/dojox/io/xhrPlugins.js b/dojox/io/xhrPlugins.js
new file mode 100644
index 0000000..c86c1d6
--- /dev/null
+++ b/dojox/io/xhrPlugins.js
@@ -0,0 +1,110 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.io.xhrPlugins"]){
+dojo._hasResource["dojox.io.xhrPlugins"]=true;
+dojo.provide("dojox.io.xhrPlugins");
+dojo.require("dojo.AdapterRegistry");
+dojo.require("dojo._base.xhr");
+(function(){
+var _1;
+var _2;
+dojox.io.xhrPlugins.register=function(){
+if(!_1){
+_1=new dojo.AdapterRegistry();
+_2=dojox.io.xhrPlugins.plainXhr=dojo._defaultXhr||dojo.xhr;
+dojo[dojo._defaultXhr?"_defaultXhr":"xhr"]=function(_3,_4,_5){
+return _1.match.apply(_1,arguments);
+};
+_1.register("xhr",function(_6,_7){
+if(!_7.url.match(/^\w*:\/\//)){
+return true;
+}
+var _8=window.location.href.match(/^.*?\/\/.*?\//)[0];
+return _7.url.substring(0,_8.length)==_8;
+},_2);
+}
+return _1.register.apply(_1,arguments);
+};
+dojox.io.xhrPlugins.addProxy=function(_9){
+dojox.io.xhrPlugins.register("proxy",function(_a,_b){
+return true;
+},function(_c,_d,_e){
+_d.url=_9+encodeURIComponent(_d.url);
+return _2.call(dojo,_c,_d,_e);
+});
+};
+var _f;
+dojox.io.xhrPlugins.addCrossSiteXhr=function(url,_11){
+if(_f===undefined&&window.XMLHttpRequest){
+try{
+var xhr=new XMLHttpRequest();
+xhr.open("GET","http://fnadkfna.com",true);
+_f=true;
+}
+catch(e){
+_f=false;
+}
+}
+dojox.io.xhrPlugins.register("cs-xhr",function(_13,_14){
+return (_f||(window.XDomainRequest&&_14.sync!==true&&(_13=="GET"||_13=="POST"||_11)))&&(_14.url.substring(0,url.length)==url);
+},_f?_2:function(){
+var _15=dojo._xhrObj;
+dojo._xhrObj=function(){
+var xdr=new XDomainRequest();
+xdr.readyState=1;
+xdr.setRequestHeader=function(){
+};
+xdr.getResponseHeader=function(_17){
+return _17=="Content-Type"?xdr.contentType:null;
+};
+function _18(_19,_1a){
+return function(){
+xdr.readyState=_1a;
+xdr.status=_19;
+};
+};
+xdr.onload=_18(200,4);
+xdr.onprogress=_18(200,3);
+xdr.onerror=_18(404,4);
+return xdr;
+};
+var dfd=(_11?_11(_2):_2).apply(dojo,arguments);
+dojo._xhrObj=_15;
+return dfd;
+});
+};
+dojox.io.xhrPlugins.fullHttpAdapter=function(_1c,_1d){
+return function(_1e,_1f,_20){
+var _21={};
+var _22={};
+if(_1e!="GET"){
+_22["http-method"]=_1e;
+if(_1f.putData&&_1d){
+_21["http-content"]=_1f.putData;
+delete _1f.putData;
+_20=false;
+}
+if(_1f.postData&&_1d){
+_21["http-content"]=_1f.postData;
+delete _1f.postData;
+_20=false;
+}
+_1e="POST";
+}
+for(var i in _1f.headers){
+var _24=i.match(/^X-/)?i.substring(2).replace(/-/g,"_").toLowerCase():("http-"+i);
+_22[_24]=_1f.headers[i];
+}
+_1f.query=dojo.objectToQuery(_22);
+dojo._ioAddQueryToUrl(_1f);
+_1f.content=dojo.mixin(_1f.content||{},_21);
+return _1c.call(dojo,_1e,_1f,_20);
+};
+};
+})();
+}
diff --git a/dojox/io/xhrScriptPlugin.js b/dojox/io/xhrScriptPlugin.js
new file mode 100644
index 0000000..0763567
--- /dev/null
+++ b/dojox/io/xhrScriptPlugin.js
@@ -0,0 +1,28 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.io.xhrScriptPlugin"]){
+dojo._hasResource["dojox.io.xhrScriptPlugin"]=true;
+dojo.provide("dojox.io.xhrScriptPlugin");
+dojo.require("dojox.io.xhrPlugins");
+dojo.require("dojo.io.script");
+dojo.require("dojox.io.scriptFrame");
+dojox.io.xhrScriptPlugin=function(_1,_2,_3){
+dojox.io.xhrPlugins.register("script",function(_4,_5){
+return _5.sync!==true&&(_4=="GET"||_3)&&(_5.url.substring(0,_1.length)==_1);
+},function(_6,_7,_8){
+var _9=function(){
+_7.callbackParamName=_2;
+if(dojo.body()){
+_7.frameDoc="frame"+Math.random();
+}
+return dojo.io.script.get(_7);
+};
+return (_3?_3(_9,true):_9)(_6,_7,_8);
+});
+};
+}
diff --git a/dojox/io/xhrWindowNamePlugin.js b/dojox/io/xhrWindowNamePlugin.js
new file mode 100644
index 0000000..e4974b3
--- /dev/null
+++ b/dojox/io/xhrWindowNamePlugin.js
@@ -0,0 +1,37 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.io.xhrWindowNamePlugin"]){
+dojo._hasResource["dojox.io.xhrWindowNamePlugin"]=true;
+dojo.provide("dojox.io.xhrWindowNamePlugin");
+dojo.require("dojox.io.xhrPlugins");
+dojo.require("dojox.io.windowName");
+dojo.require("dojox.io.httpParse");
+dojo.require("dojox.secure.capability");
+dojox.io.xhrWindowNamePlugin=function(_1,_2,_3){
+dojox.io.xhrPlugins.register("windowName",function(_4,_5){
+return _5.sync!==true&&(_4=="GET"||_4=="POST"||_2)&&(_5.url.substring(0,_1.length)==_1);
+},function(_6,_7,_8){
+var _9=dojox.io.windowName.send;
+var _a=(_2?_2(_9,true):_9)(_6,_7,_8);
+_a.addCallback(function(_b){
+var _c=_a.ioArgs;
+_c.xhr={getResponseHeader:function(_d){
+return dojo.queryToObject(_c.hash.match(/[^#]*$/)[0])[_d];
+}};
+if(_c.handleAs=="json"){
+if(!_3){
+dojox.secure.capability.validate(_b,["Date"],{});
+}
+return dojo.fromJson(_b);
+}
+return dojo._contentHandlers[_c.handleAs||"text"]({responseText:_b});
+});
+return _a;
+});
+};
+}
diff --git a/dojox/json/README b/dojox/json/README
new file mode 100644
index 0000000..b80d139
--- /dev/null
+++ b/dojox/json/README
@@ -0,0 +1,42 @@
+-------------------------------------------------------------------------------
+DojoX JSON Modules
+-------------------------------------------------------------------------------
+Version 0.1
+Release date: 07/06/2008
+-------------------------------------------------------------------------------
+Project state:
+beta
+-------------------------------------------------------------------------------
+Credits
+	Kris Zyp (kris at sitepen.com)
+-------------------------------------------------------------------------------
+Project description
+JSONQuery (dojox.json.query) - A comprehensive object data query tool
+JSON Schema (dojox.json.schema) - An object validation tool based on JSON Schema
+JSON Referencing (dojox.json.ref) - JSON Referencing capable serializer and
+deserializer.
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+dojox.json.ref uses dojo.date.stamp
+-------------------------------------------------------------------------------
+Documentation
+See the Dojo API tool (http://dojotoolkit.org/api)
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/json/*
+
+Install into the following directory structure:
+/dojox/json/
+
+...which should be at the same level as your Dojo checkout.
+
+/dojox/json/*
+
+Require in the dojox.data stores you wish to use.
+-------------------------------------------------------------------------------
+Additional Notes
+
diff --git a/dojox/json/query.js b/dojox/json/query.js
new file mode 100644
index 0000000..2a8efd3
--- /dev/null
+++ b/dojox/json/query.js
@@ -0,0 +1,142 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.json.query"]){
+dojo._hasResource["dojox.json.query"]=true;
+dojo.provide("dojox.json.query");
+(function(){
+function _1(_2,_3,_4,_5){
+var _6=_2.length,_7=[];
+_4=_4||_6;
+_3=(_3<0)?Math.max(0,_3+_6):Math.min(_6,_3);
+_4=(_4<0)?Math.max(0,_4+_6):Math.min(_6,_4);
+for(var i=_3;i<_4;i+=_5){
+_7.push(_2[i]);
+}
+return _7;
+};
+function _9(_a,_b){
+var _c=[];
+function _d(_e){
+if(_b){
+if(_b===true&&!(_e instanceof Array)){
+_c.push(_e);
+}else{
+if(_e[_b]){
+_c.push(_e[_b]);
+}
+}
+}
+for(var i in _e){
+var val=_e[i];
+if(!_b){
+_c.push(val);
+}else{
+if(val&&typeof val=="object"){
+_d(val);
+}
+}
+}
+};
+if(_b instanceof Array){
+if(_b.length==1){
+return _a[_b[0]];
+}
+for(var i=0;i<_b.length;i++){
+_c.push(_a[_b[i]]);
+}
+}else{
+_d(_a);
+}
+return _c;
+};
+function _12(_13,_14){
+var _15=[];
+var _16={};
+for(var i=0,l=_13.length;i<l;++i){
+var _19=_13[i];
+if(_14(_19,i,_13)){
+if((typeof _19=="object")&&_19){
+if(!_19.__included){
+_19.__included=true;
+_15.push(_19);
+}
+}else{
+if(!_16[_19+typeof _19]){
+_16[_19+typeof _19]=true;
+_15.push(_19);
+}
+}
+}
+}
+for(i=0,l=_15.length;i<l;++i){
+if(_15[i]){
+delete _15[i].__included;
+}
+}
+return _15;
+};
+dojox.json.query=function(_1a,obj){
+var _1c=0;
+var str=[];
+_1a=_1a.replace(/"(\\.|[^"\\])*"|'(\\.|[^'\\])*'|[\[\]]/g,function(t){
+_1c+=t=="["?1:t=="]"?-1:0;
+return (t=="]"&&_1c>0)?"`]":(t.charAt(0)=="\""||t.charAt(0)=="'")?"`"+(str.push(t)-1):t;
+});
+var _1f="";
+function _20(_21){
+_1f=_21+"("+_1f;
+};
+function _22(t,a,b,c,d,e,f,g){
+return str[g].match(/[\*\?]/)||f=="~"?"/^"+str[g].substring(1,str[g].length-1).replace(/\\([btnfr\\"'])|([^\w\*\?])/g,"\\$1$2").replace(/([\*\?])/g,"[\\w\\W]$1")+(f=="~"?"$/i":"$/")+".test("+a+")":t;
+};
+_1a.replace(/(\]|\)|push|pop|shift|splice|sort|reverse)\s*\(/,function(){
+throw new Error("Unsafe function call");
+});
+_1a=_1a.replace(/([^=]=)([^=])/g,"$1=$2").replace(/@|(\.\s*)?[a-zA-Z\$_]+(\s*:)?/g,function(t){
+return t.charAt(0)=="."?t:t=="@"?"$obj":(t.match(/:|^(\$|Math|true|false|null)$/)?"":"$obj.")+t;
+}).replace(/\.?\.?\[(`\]|[^\]])*\]|\?.*|\.\.([\w\$_]+)|\.\*/g,function(t,a,b){
+var _2f=t.match(/^\.?\.?(\[\s*\^?\?|\^?\?|\[\s*==)(.*?)\]?$/);
+if(_2f){
+var _30="";
+if(t.match(/^\./)){
+_20("expand");
+_30=",true)";
+}
+_20(_2f[1].match(/\=/)?"dojo.map":_2f[1].match(/\^/)?"distinctFilter":"dojo.filter");
+return _30+",function($obj){return "+_2f[2]+"})";
+}
+_2f=t.match(/^\[\s*([\/\\].*)\]/);
+if(_2f){
+return ".concat().sort(function(a,b){"+_2f[1].replace(/\s*,?\s*([\/\\])\s*([^,\\\/]+)/g,function(t,a,b){
+return "var av= "+b.replace(/\$obj/,"a")+",bv= "+b.replace(/\$obj/,"b")+";if(av>bv||bv==null){return "+(a=="/"?1:-1)+";}\n"+"if(bv>av||av==null){return "+(a=="/"?-1:1)+";}\n";
+})+"return 0;})";
+}
+_2f=t.match(/^\[(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)\]/);
+if(_2f){
+_20("slice");
+return ","+(_2f[1]||0)+","+(_2f[2]||0)+","+(_2f[3]||1)+")";
+}
+if(t.match(/^\.\.|\.\*|\[\s*\*\s*\]|,/)){
+_20("expand");
+return (t.charAt(1)=="."?",'"+b+"'":t.match(/,/)?","+t:"")+")";
+}
+return t;
+}).replace(/(\$obj\s*((\.\s*[\w_$]+\s*)|(\[\s*`([0-9]+)\s*`\]))*)(==|~)\s*`([0-9]+)/g,_22).replace(/`([0-9]+)\s*(==|~)\s*(\$obj\s*((\.\s*[\w_$]+)|(\[\s*`([0-9]+)\s*`\]))*)/g,function(t,a,b,c,d,e,f,g){
+return _22(t,c,d,e,f,g,b,a);
+});
+_1a=_1f+(_1a.charAt(0)=="$"?"":"$")+_1a.replace(/`([0-9]+|\])/g,function(t,a){
+return a=="]"?"]":str[a];
+});
+var _3e=eval("1&&function($,$1,$2,$3,$4,$5,$6,$7,$8,$9){var $obj=$;return "+_1a+"}");
+for(var i=0;i<arguments.length-1;i++){
+arguments[i]=arguments[i+1];
+}
+return obj?_3e.apply(this,arguments):_3e;
+};
+})();
+}
diff --git a/dojox/json/ref.js b/dojox/json/ref.js
new file mode 100644
index 0000000..0766fc4
--- /dev/null
+++ b/dojox/json/ref.js
@@ -0,0 +1,233 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.json.ref"]){
+dojo._hasResource["dojox.json.ref"]=true;
+dojo.provide("dojox.json.ref");
+dojo.require("dojo.date.stamp");
+dojox.json.ref={resolveJson:function(_1,_2){
+_2=_2||{};
+var _3=_2.idAttribute||"id";
+var _4=_2.idPrefix||"";
+var _5=_2.assignAbsoluteIds;
+var _6=_2.index||{};
+var _7=_2.timeStamps;
+var _8,_9=[];
+var _a=/^(.*\/)?(\w+:\/\/)|[^\/\.]+\/\.\.\/|^.*\/(\/)/;
+var _b=this._addProp;
+var F=function(){
+};
+function _d(it,_f,_10,_11,_12){
+var _13,val,id=_3 in it?it[_3]:_10;
+if(id!==undefined){
+id=(_4+id).replace(_a,"$2$3");
+}
+var _16=_12||it;
+if(id!==undefined){
+if(_5){
+it.__id=id;
+}
+if(_2.schemas&&(!(it instanceof Array))&&(val=id.match(/^(.+\/)[^\.\[]*$/))){
+_11=_2.schemas[val[1]];
+}
+if(_6[id]&&((it instanceof Array)==(_6[id] instanceof Array))){
+_16=_6[id];
+delete _16.$ref;
+_13=true;
+}else{
+var _17=_11&&_11.prototype;
+if(_17){
+F.prototype=_17;
+_16=new F();
+}
+}
+_6[id]=_16;
+if(_7){
+_7[id]=_2.time;
+}
+}
+var _18=_11&&_11.properties;
+var _19=it.length;
+for(var i in it){
+if(i==_19){
+break;
+}
+if(it.hasOwnProperty(i)){
+val=it[i];
+var _1b=_18&&_18[i];
+if(_1b&&_1b.format=="date-time"&&typeof val=="string"){
+val=dojo.date.stamp.fromISOString(val);
+}else{
+if((typeof val=="object")&&val&&!(val instanceof Date)){
+_8=val.$ref;
+if(_8){
+delete it[i];
+var _1c=_8.replace(/(#)([^\.\[])/,"$1.$2").match(/(^([^\[]*\/)?[^#\.\[]*)#?([\.\[].*)?/);
+if((_8=(_1c[1]=="$"||_1c[1]=="this"||_1c[1]=="")?_1:_6[(_4+_1c[1]).replace(_a,"$2$3")])){
+if(_1c[3]){
+_1c[3].replace(/(\[([^\]]+)\])|(\.?([^\.\[]+))/g,function(t,a,b,c,d){
+_8=_8&&_8[b?b.replace(/[\"\'\\]/,""):d];
+});
+}
+}
+if(_8){
+val=_8;
+}else{
+if(!_f){
+var _22;
+if(!_22){
+_9.push(_16);
+}
+_22=true;
+}else{
+val=_d(val,false,val.$ref,_1b);
+val._loadObject=_2.loader;
+}
+}
+}else{
+if(!_f){
+val=_d(val,_9==it,id&&_b(id,i),_1b,_16!=it&&typeof _16[i]=="object"&&_16[i]);
+}
+}
+}
+}
+it[i]=val;
+if(_16!=it&&!_16.__isDirty){
+var old=_16[i];
+_16[i]=val;
+if(_13&&val!==old&&!_16._loadObject&&!(val instanceof Date&&old instanceof Date&&val.getTime()==old.getTime())&&!(typeof val=="function"&&typeof old=="function"&&val.toString()==old.toString())&&_6.onUpdate){
+_6.onUpdate(_16,i,old,val);
+}
+}
+}
+}
+if(_13){
+for(i in _16){
+if(!_16.__isDirty&&_16.hasOwnProperty(i)&&!it.hasOwnProperty(i)&&i!="__id"&&i!="__clientId"&&!(_16 instanceof Array&&isNaN(i))){
+if(_6.onUpdate&&i!="_loadObject"&&i!="_idAttr"){
+_6.onUpdate(_16,i,_16[i],undefined);
+}
+delete _16[i];
+while(_16 instanceof Array&&_16.length&&_16[_16.length-1]===undefined){
+_16.length--;
+}
+}
+}
+}else{
+if(_6.onLoad){
+_6.onLoad(_16);
+}
+}
+return _16;
+};
+if(_1&&typeof _1=="object"){
+_1=_d(_1,false,_2.defaultId);
+_d(_9,false);
+}
+return _1;
+},fromJson:function(str,_25){
+function ref(_27){
+return {$ref:_27};
+};
+try{
+var _28=eval("("+str+")");
+}
+catch(e){
+throw new SyntaxError("Invalid JSON string: "+e.message+" parsing: "+str);
+}
+if(_28){
+return this.resolveJson(_28,_25);
+}
+return _28;
+},toJson:function(it,_2a,_2b,_2c){
+var _2d=this._useRefs;
+var _2e=this._addProp;
+_2b=_2b||"";
+var _2f={};
+var _30={};
+function _31(it,_33,_34){
+if(typeof it=="object"&&it){
+var _35;
+if(it instanceof Date){
+return "\""+dojo.date.stamp.toISOString(it,{zulu:true})+"\"";
+}
+var id=it.__id;
+if(id){
+if(_33!="#"&&((_2d&&!id.match(/#/))||_2f[id])){
+var ref=id;
+if(id.charAt(0)!="#"){
+if(it.__clientId==id){
+ref="cid:"+id;
+}else{
+if(id.substring(0,_2b.length)==_2b){
+ref=id.substring(_2b.length);
+}else{
+ref=id;
+}
+}
+}
+return _31({$ref:ref},"#");
+}
+_33=id;
+}else{
+it.__id=_33;
+_30[_33]=it;
+}
+_2f[_33]=it;
+_34=_34||"";
+var _38=_2a?_34+dojo.toJsonIndentStr:"";
+var _39=_2a?"\n":"";
+var sep=_2a?" ":"";
+if(it instanceof Array){
+var res=dojo.map(it,function(obj,i){
+var val=_31(obj,_2e(_33,i),_38);
+if(typeof val!="string"){
+val="undefined";
+}
+return _39+_38+val;
+});
+return "["+res.join(","+sep)+_39+_34+"]";
+}
+var _3f=[];
+for(var i in it){
+if(it.hasOwnProperty(i)){
+var _41;
+if(typeof i=="number"){
+_41="\""+i+"\"";
+}else{
+if(typeof i=="string"&&(i.charAt(0)!="_"||i.charAt(1)!="_")){
+_41=dojo._escapeString(i);
+}else{
+continue;
+}
+}
+var val=_31(it[i],_2e(_33,i),_38);
+if(typeof val!="string"){
+continue;
+}
+_3f.push(_39+_38+_41+":"+sep+val);
+}
+}
+return "{"+_3f.join(","+sep)+_39+_34+"}";
+}else{
+if(typeof it=="function"&&dojox.json.ref.serializeFunctions){
+return it.toString();
+}
+}
+return dojo.toJson(it);
+};
+var _43=_31(it,"#","");
+if(!_2c){
+for(var i in _30){
+delete _30[i].__id;
+}
+}
+return _43;
+},_addProp:function(id,_46){
+return id+(id.match(/#/)?id.length==1?"":".":"#")+_46;
+},_useRefs:false,serializeFunctions:false};
+}
diff --git a/dojox/json/schema.js b/dojox/json/schema.js
new file mode 100644
index 0000000..0a797d7
--- /dev/null
+++ b/dojox/json/schema.js
@@ -0,0 +1,174 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.json.schema"]){
+dojo._hasResource["dojox.json.schema"]=true;
+dojo.provide("dojox.json.schema");
+dojox.json.schema.validate=function(_1,_2){
+return this._validate(_1,_2,false);
+};
+dojox.json.schema.checkPropertyChange=function(_3,_4){
+return this._validate(_3,_4,true);
+};
+dojox.json.schema.mustBeValid=function(_5){
+if(!_5.valid){
+throw new Error(dojo.map(_5.errors,function(_6){
+return _6.property+" "+_6.message;
+}).join(","));
+}
+};
+dojox.json.schema._validate=function(_7,_8,_9){
+var _a=[];
+function _b(_c,_d,_e,i){
+if(typeof _d!="object"){
+return null;
+}
+_e+=_e?typeof i=="number"?"["+i+"]":typeof i=="undefined"?"":"."+i:i;
+function _10(_11){
+_a.push({property:_e,message:_11});
+};
+if(_9&&_d.readonly){
+_10("is a readonly field, it can not be changed");
+}
+if(_d instanceof Array){
+if(!(_c instanceof Array)){
+return [{property:_e,message:"An array tuple is required"}];
+}
+for(i=0;i<_d.length;i++){
+_a.concat(_b(_c[i],_d[i],_e,i));
+}
+return _a;
+}
+if(_d["extends"]){
+_b(_c,_d["extends"],_e,i);
+}
+function _12(_13,_14){
+if(_13){
+if(typeof _13=="string"&&_13!="any"&&(_13=="null"?_14!==null:typeof _14!=_13)&&!(_14 instanceof Array&&_13=="array")&&!(_13=="integer"&&_14%1===0)){
+return [{property:_e,message:(typeof _14)+" value found, but a "+_13+" is required"}];
+}
+if(_13 instanceof Array){
+var _15=[];
+for(var j=0;j<_13.length;j++){
+if(!(_15=_12(_13[j],_14)).length){
+break;
+}
+}
+if(_15.length){
+return _15;
+}
+}else{
+if(typeof _13=="object"){
+_b(_14,_13,_e);
+}
+}
+}
+return [];
+};
+if(_c!==null){
+if(_c===undefined){
+if(!_d.optional){
+_10("is missing and it is not optional");
+}
+}else{
+_a=_a.concat(_12(_d.type,_c));
+if(_d.disallow&&!_12(_d.disallow,_c).length){
+_10(" disallowed value was matched");
+}
+if(_c instanceof Array){
+if(_d.items){
+for(i=0,l=_c.length;i<l;i++){
+_a.concat(_b(_c[i],_d.items,_e,i));
+}
+}
+if(_d.minItems&&_c.length<_d.minItems){
+_10("There must be a minimum of "+_d.minItems+" in the array");
+}
+if(_d.maxItems&&_c.length>_d.maxItems){
+_10("There must be a maximum of "+_d.maxItems+" in the array");
+}
+}else{
+if(_d.properties&&typeof _c=="object"){
+_a.concat(_17(_c,_d.properties,_e,_d.additionalProperties));
+}
+}
+if(_d.pattern&&typeof _c=="string"&&!_c.match(_d.pattern)){
+_10("does not match the regex pattern "+_d.pattern);
+}
+if(_d.maxLength&&typeof _c=="string"&&_c.length>_d.maxLength){
+_10("may only be "+_d.maxLength+" characters long");
+}
+if(_d.minLength&&typeof _c=="string"&&_c.length<_d.minLength){
+_10("must be at least "+_d.minLength+" characters long");
+}
+if(typeof _d.minimum!==undefined&&typeof _c==typeof _d.minimum&&_d.minimum>_c){
+_10("must have a minimum value of "+_d.minimum);
+}
+if(typeof _d.maximum!==undefined&&typeof _c==typeof _d.maximum&&_d.maximum<_c){
+_10("must have a maximum value of "+_d.maximum);
+}
+if(_d["enum"]){
+var _18=_d["enum"];
+l=_18.length;
+var _19;
+for(var j=0;j<l;j++){
+if(_18[j]===_c){
+_19=1;
+break;
+}
+}
+if(!_19){
+_10("does not have a value in the enumeration "+_18.join(", "));
+}
+}
+if(typeof _d.maxDecimal=="number"&&(_c*10^_d.maxDecimal)%1){
+_10("may only have "+_d.maxDecimal+" digits of decimal places");
+}
+}
+}
+return null;
+};
+function _17(_1b,_1c,_1d,_1e){
+if(typeof _1c=="object"){
+if(typeof _1b!="object"||_1b instanceof Array){
+_a.push({property:_1d,message:"an object is required"});
+}
+for(var i in _1c){
+if(_1c.hasOwnProperty(i)){
+var _20=_1b[i];
+var _21=_1c[i];
+_b(_20,_21,_1d,i);
+}
+}
+}
+for(i in _1b){
+if(_1b.hasOwnProperty(i)&&(i.charAt(0)!="_"||i.charAt(0)!="_")&&_1c&&!_1c[i]&&_1e===false){
+_a.push({property:_1d,message:(typeof _20)+"The property "+i+" is not defined in the schema and the schema does not allow additional properties"});
+}
+var _22=_1c&&_1c[i]&&_1c[i].requires;
+if(_22&&!(_22 in _1b)){
+_a.push({property:_1d,message:"the presence of the property "+i+" requires that "+_22+" also be present"});
+}
+_20=_1b[i];
+if(_1c&&typeof _1c=="object"&&!(i in _1c)){
+_b(_20,_1e,_1d,i);
+}
+if(!_9&&_20&&_20.$schema){
+_a=_a.concat(_b(_20,_20.$schema,_1d,i));
+}
+}
+return _a;
+};
+if(_8){
+_b(_7,_8,"","");
+}
+if(!_9&&_7.$schema){
+_b(_7,_7.$schema,"","");
+}
+return {valid:!_a.length,errors:_a};
+};
+}
diff --git a/dojox/jsonPath.js b/dojox/jsonPath.js
new file mode 100644
index 0000000..8ee5897
--- /dev/null
+++ b/dojox/jsonPath.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.jsonPath"]){
+dojo._hasResource["dojox.jsonPath"]=true;
+dojo.provide("dojox.jsonPath");
+dojo.require("dojox.jsonPath.query");
+}
diff --git a/dojox/jsonPath/README b/dojox/jsonPath/README
new file mode 100644
index 0000000..a37dec6
--- /dev/null
+++ b/dojox/jsonPath/README
@@ -0,0 +1,126 @@
+-------------------------------------------------------------------------------
+dojox.jsonPath
+-------------------------------------------------------------------------------
+Version 1.0
+Release date: 11/14/2007
+-------------------------------------------------------------------------------
+Project state: beta
+-------------------------------------------------------------------------------
+Project authors
+	Dustin Machi
+	Kris Zyp
+-------------------------------------------------------------------------------
+Project description
+
+jsonPath is a query system similar in idea to xpath, but for use against
+javascript objects.  This code is a port of the jsonPath code at 
+http://code.google.com/p/jsonpath/.  It was contributed under CLA by Stefan
+Goessner.  Thanks Stefan! 
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo Core (package loader).
+-------------------------------------------------------------------------------
+Documentation
+
+Usage:
+
+var matches = dojox.jsonPath.query(objectToQuery, jsonPathExpresson)
+
+Expressions:
+
+	$			The Root Object
+	@			The current object/element
+	. or []			The child operator
+	..			Recursive descent
+	*			all objects
+	[]			subscript operator
+	[,]			Union operator
+	[start:end:step]	array slice operator
+	?()			applies a filter/script expression
+	()			script expresions
+
+	some examples:
+
+	Given the following test data set:
+
+	var json = 
+                  { "store": {
+                        "book": [ 
+                          { "category": "reference",
+                                "author": "Nigel Rees",
+                                "title": "Sayings of the Century",
+                                "price": 8.95
+                          },
+                          { "category": "fiction",
+                                "author": "Evelyn Waugh",
+                                "title": "Sword of Honour",
+                                "price": 12.99
+                          },
+                          { "category": "fiction",
+                                "author": "Herman Melville",
+                                "title": "Moby Dick",
+                                "isbn": "0-553-21311-3",
+                                "price": 8.99
+                          },
+                          { "category": "fiction",
+                                "author": "J. R. R. Tolkien",
+                                "title": "The Lord of the Rings",
+                                "isbn": "0-395-19395-8",
+                                "price": 22.99
+                          }
+                        ],
+                        "bicycle": {
+                          "color": "red",
+                          "price": 19.95
+                        }
+                  }
+                };
+
+	Here are some example queries and their output:
+
+   	$.store.book[*].author 
+	["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"]
+
+	$..author
+	["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"]
+
+	$.store.*
+	[[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}],{"color":"red","price":19.95}]
+
+	$.store..price
+	[8.95,12.99,8.99,22.99,19.95]
+
+	$..book[(@.length-1)]
+	[{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}]
+
+	$..book[-1]
+	[{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}]
+
+	$..book[0,1]
+	[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99}]
+	
+	$..book[:2]
+	[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99}]
+
+	$..book[?(@.isbn)]
+	[{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}]
+
+	$..book[?(@.price<10)]
+	[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99}]
+
+	$..*
+	[{"book":[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}],"bicycle":{"color":"red","price":19.95}},[{"category":"reference","author" [...]
+
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/jsonPath
+
+Install into the following directory structure:
+/dojox/jsonPath/
+
+...which should be at the same level as your Dojo checkout.
diff --git a/dojox/jsonPath/query.js b/dojox/jsonPath/query.js
new file mode 100644
index 0000000..1e68046
--- /dev/null
+++ b/dojox/jsonPath/query.js
@@ -0,0 +1,204 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.jsonPath.query"]){
+dojo._hasResource["dojox.jsonPath.query"]=true;
+dojo.provide("dojox.jsonPath.query");
+dojox.jsonPath.query=function(_1,_2,_3){
+var re=dojox.jsonPath._regularExpressions;
+if(!_3){
+_3={};
+}
+var _5=[];
+function _6(i){
+return _5[i];
+};
+var _8;
+if(_3.resultType=="PATH"&&_3.evalType=="RESULT"){
+throw Error("RESULT based evaluation not supported with PATH based results");
+}
+var P={resultType:_3.resultType||"VALUE",normalize:function(_a){
+var _b=[];
+_a=_a.replace(/'([^']|'')*'/g,function(t){
+return "_str("+(_5.push(eval(t))-1)+")";
+});
+var ll=-1;
+while(ll!=_b.length){
+ll=_b.length;
+_a=_a.replace(/(\??\([^\(\)]*\))/g,function($0){
+return "#"+(_b.push($0)-1);
+});
+}
+_a=_a.replace(/[\['](#[0-9]+)[\]']/g,"[$1]").replace(/'?\.'?|\['?/g,";").replace(/;;;|;;/g,";..;").replace(/;$|'?\]|'$/g,"");
+ll=-1;
+while(ll!=_a){
+ll=_a;
+_a=_a.replace(/#([0-9]+)/g,function($0,$1){
+return _b[$1];
+});
+}
+return _a.split(";");
+},asPaths:function(_11){
+for(var j=0;j<_11.length;j++){
+var p="$";
+var x=_11[j];
+for(var i=1,n=x.length;i<n;i++){
+p+=/^[0-9*]+$/.test(x[i])?("["+x[i]+"]"):("['"+x[i]+"']");
+}
+_11[j]=p;
+}
+return _11;
+},exec:function(_17,val,rb){
+var _1a=["$"];
+var _1b=rb?val:[val];
+var _1c=[_1a];
+function add(v,p,def){
+if(v&&v.hasOwnProperty(p)&&P.resultType!="VALUE"){
+_1c.push(_1a.concat([p]));
+}
+if(def){
+_1b=v[p];
+}else{
+if(v&&v.hasOwnProperty(p)){
+_1b.push(v[p]);
+}
+}
+};
+function _21(v){
+_1b.push(v);
+_1c.push(_1a);
+P.walk(v,function(i){
+if(typeof v[i]==="object"){
+var _24=_1a;
+_1a=_1a.concat(i);
+_21(v[i]);
+_1a=_24;
+}
+});
+};
+function _25(loc,val){
+if(val instanceof Array){
+var len=val.length,_29=0,end=len,_2b=1;
+loc.replace(/^(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)$/g,function($0,$1,$2,$3){
+_29=parseInt($1||_29);
+end=parseInt($2||end);
+_2b=parseInt($3||_2b);
+});
+_29=(_29<0)?Math.max(0,_29+len):Math.min(len,_29);
+end=(end<0)?Math.max(0,end+len):Math.min(len,end);
+for(var i=_29;i<end;i+=_2b){
+add(val,i);
+}
+}
+};
+function _31(str){
+var i=loc.match(/^_str\(([0-9]+)\)$/);
+return i?_5[i[1]]:str;
+};
+function _35(val){
+if(/^\(.*?\)$/.test(loc)){
+add(val,P.eval(loc,val),rb);
+}else{
+if(loc==="*"){
+P.walk(val,rb&&val instanceof Array?function(i){
+P.walk(val[i],function(j){
+add(val[i],j);
+});
+}:function(i){
+add(val,i);
+});
+}else{
+if(loc===".."){
+_21(val);
+}else{
+if(/,/.test(loc)){
+for(var s=loc.split(/'?,'?/),i=0,n=s.length;i<n;i++){
+add(val,_31(s[i]));
+}
+}else{
+if(/^\?\(.*?\)$/.test(loc)){
+P.walk(val,function(i){
+if(P.eval(loc.replace(/^\?\((.*?)\)$/,"$1"),val[i])){
+add(val,i);
+}
+});
+}else{
+if(/^(-?[0-9]*):(-?[0-9]*):?([0-9]*)$/.test(loc)){
+_25(loc,val);
+}else{
+loc=_31(loc);
+if(rb&&val instanceof Array&&!/^[0-9*]+$/.test(loc)){
+P.walk(val,function(i){
+add(val[i],loc);
+});
+}else{
+add(val,loc,rb);
+}
+}
+}
+}
+}
+}
+}
+};
+while(_17.length){
+var loc=_17.shift();
+if((val=_1b)===null||val===undefined){
+return val;
+}
+_1b=[];
+var _3f=_1c;
+_1c=[];
+if(rb){
+_35(val);
+}else{
+P.walk(val,function(i){
+_1a=_3f[i]||_1a;
+_35(val[i]);
+});
+}
+}
+if(P.resultType=="BOTH"){
+_1c=P.asPaths(_1c);
+var _41=[];
+for(var i=0;i<_1c.length;i++){
+_41.push({path:_1c[i],value:_1b[i]});
+}
+return _41;
+}
+return P.resultType=="PATH"?P.asPaths(_1c):_1b;
+},walk:function(val,f){
+if(val instanceof Array){
+for(var i=0,n=val.length;i<n;i++){
+if(i in val){
+f(i);
+}
+}
+}else{
+if(typeof val==="object"){
+for(var m in val){
+if(val.hasOwnProperty(m)){
+f(m);
+}
+}
+}
+}
+},eval:function(x,_v){
+try{
+return $&&_v&&eval(x.replace(/@/g,"_v"));
+}
+catch(e){
+throw new SyntaxError("jsonPath: "+e.message+": "+x.replace(/@/g,"_v").replace(/\^/g,"_a"));
+}
+}};
+var $=_1;
+if(_2&&_1){
+return P.exec(P.normalize(_2).slice(1),_1,_3.evalType=="RESULT");
+}
+return false;
+};
+}
diff --git a/dojox/lang/LICENSE b/dojox/lang/LICENSE
new file mode 100644
index 0000000..d84a6aa
--- /dev/null
+++ b/dojox/lang/LICENSE
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2007 Oliver Steele
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/dojox/lang/README b/dojox/lang/README
new file mode 100644
index 0000000..8a08bbb
--- /dev/null
+++ b/dojox/lang/README
@@ -0,0 +1,50 @@
+-------------------------------------------------------------------------------
+dojox.lang
+-------------------------------------------------------------------------------
+Version 0.991
+Release date: 07/30/2007
+-------------------------------------------------------------------------------
+Project state:
+beta
+-------------------------------------------------------------------------------
+Credits
+	Eugene Lazutkin (eugene.lazutkin at gmail.com)
+	Kris Zyp (kris at sitepen.com)
+-------------------------------------------------------------------------------
+Project description
+
+Implementation of common functional operations, and provisions, aspect-oriented
+helpers. Later we can add other JS language-related helpers.
+
+dojox.lang.observable - Provides construction of objects that such that 
+property access and modification can be controlled, i.e. provides a form of
+getters/setters.
+-------------------------------------------------------------------------------
+Dependencies:
+
+None.
+-------------------------------------------------------------------------------
+Documentation
+
+For now:
+
+dojox.lang.functional:
+http://lazutkin.com/blog/2008/jan/12/functional-fun-javascript-dojo/
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/src/dojo/dojox/trunk/lang/*
+
+Install into the following directory structure:
+/dojox/lang/
+
+...which should be at the same level as your Dojo checkout.
+-------------------------------------------------------------------------------
+Additional Notes
+
+See tests and the source for more details.
+
+LICENSE in this directory contains the MIT license by Oliver Steele for
+dojox.lang.functional.lambda, which was derived from his original implementation.
diff --git a/dojox/lang/aspect.js b/dojox/lang/aspect.js
new file mode 100644
index 0000000..57f853c
--- /dev/null
+++ b/dojox/lang/aspect.js
@@ -0,0 +1,212 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.aspect"]){
+dojo._hasResource["dojox.lang.aspect"]=true;
+dojo.provide("dojox.lang.aspect");
+(function(){
+var d=dojo,_2=dojox.lang.aspect,ap=Array.prototype,_4=[],_5;
+var _6=function(){
+this.next_before=this.prev_before=this.next_around=this.prev_around=this.next_afterReturning=this.prev_afterReturning=this.next_afterThrowing=this.prev_afterThrowing=this;
+this.counter=0;
+};
+d.extend(_6,{add:function(_7){
+var _8=d.isFunction(_7),_9={advice:_7,dynamic:_8};
+this._add(_9,"before","",_8,_7);
+this._add(_9,"around","",_8,_7);
+this._add(_9,"after","Returning",_8,_7);
+this._add(_9,"after","Throwing",_8,_7);
+++this.counter;
+return _9;
+},_add:function(_a,_b,_c,_d,_e){
+var _f=_b+_c;
+if(_d||_e[_b]||(_c&&_e[_f])){
+var _10="next_"+_f,_11="prev_"+_f;
+(_a[_11]=this[_11])[_10]=_a;
+(_a[_10]=this)[_11]=_a;
+}
+},remove:function(_12){
+this._remove(_12,"before");
+this._remove(_12,"around");
+this._remove(_12,"afterReturning");
+this._remove(_12,"afterThrowing");
+--this.counter;
+},_remove:function(_13,_14){
+var _15="next_"+_14,_16="prev_"+_14;
+if(_13[_15]){
+_13[_15][_16]=_13[_16];
+_13[_16][_15]=_13[_15];
+}
+},isEmpty:function(){
+return !this.counter;
+}});
+var _17=function(){
+return function(){
+var _18=arguments.callee,_19=_18.advices,ret,i,a,e,t;
+if(_5){
+_4.push(_5);
+}
+_5={instance:this,joinPoint:_18,depth:_4.length,around:_19.prev_around,dynAdvices:[],dynIndex:0};
+try{
+for(i=_19.prev_before;i!=_19;i=i.prev_before){
+if(i.dynamic){
+_5.dynAdvices.push(a=new i.advice(_5));
+if(t=a.before){
+t.apply(a,arguments);
+}
+}else{
+t=i.advice;
+t.before.apply(t,arguments);
+}
+}
+try{
+ret=(_19.prev_around==_19?_18.target:_2.proceed).apply(this,arguments);
+}
+catch(e){
+_5.dynIndex=_5.dynAdvices.length;
+for(i=_19.next_afterThrowing;i!=_19;i=i.next_afterThrowing){
+a=i.dynamic?_5.dynAdvices[--_5.dynIndex]:i.advice;
+if(t=a.afterThrowing){
+t.call(a,e);
+}
+if(t=a.after){
+t.call(a);
+}
+}
+throw e;
+}
+_5.dynIndex=_5.dynAdvices.length;
+for(i=_19.next_afterReturning;i!=_19;i=i.next_afterReturning){
+a=i.dynamic?_5.dynAdvices[--_5.dynIndex]:i.advice;
+if(t=a.afterReturning){
+t.call(a,ret);
+}
+if(t=a.after){
+t.call(a);
+}
+}
+var ls=_18._listeners;
+for(i in ls){
+if(!(i in ap)){
+ls[i].apply(this,arguments);
+}
+}
+}
+finally{
+for(i=0;i<_5.dynAdvices.length;++i){
+a=_5.dynAdvices[i];
+if(a.destroy){
+a.destroy();
+}
+}
+_5=_4.length?_4.pop():null;
+}
+return ret;
+};
+};
+_2.advise=function(obj,_21,_22){
+if(typeof obj!="object"){
+obj=obj.prototype;
+}
+var _23=[];
+if(!(_21 instanceof Array)){
+_21=[_21];
+}
+for(var j=0;j<_21.length;++j){
+var t=_21[j];
+if(t instanceof RegExp){
+for(var i in obj){
+if(d.isFunction(obj[i])&&t.test(i)){
+_23.push(i);
+}
+}
+}else{
+if(d.isFunction(obj[t])){
+_23.push(t);
+}
+}
+}
+if(!d.isArray(_22)){
+_22=[_22];
+}
+return _2.adviseRaw(obj,_23,_22);
+};
+_2.adviseRaw=function(obj,_28,_29){
+if(!_28.length||!_29.length){
+return null;
+}
+var m={},al=_29.length;
+for(var i=_28.length-1;i>=0;--i){
+var _2d=_28[i],o=obj[_2d],ao=new Array(al),t=o.advices;
+if(!t){
+var x=obj[_2d]=_17();
+x.target=o.target||o;
+x.targetName=_2d;
+x._listeners=o._listeners||[];
+x.advices=new _6;
+t=x.advices;
+}
+for(var j=0;j<al;++j){
+ao[j]=t.add(_29[j]);
+}
+m[_2d]=ao;
+}
+return [obj,m];
+};
+_2.unadvise=function(_33){
+if(!_33){
+return;
+}
+var obj=_33[0],_35=_33[1];
+for(var _36 in _35){
+var o=obj[_36],t=o.advices,ao=_35[_36];
+for(var i=ao.length-1;i>=0;--i){
+t.remove(ao[i]);
+}
+if(t.isEmpty()){
+var _3b=true,ls=o._listeners;
+if(ls.length){
+for(i in ls){
+if(!(i in ap)){
+_3b=false;
+break;
+}
+}
+}
+if(_3b){
+obj[_36]=o.target;
+}else{
+var x=obj[_36]=d._listener.getDispatcher();
+x.target=o.target;
+x._listeners=ls;
+}
+}
+}
+};
+_2.getContext=function(){
+return _5;
+};
+_2.getContextStack=function(){
+return _4;
+};
+_2.proceed=function(){
+var _3e=_5.joinPoint,_3f=_3e.advices;
+for(var c=_5.around;c!=_3f;c=_5.around){
+_5.around=c.prev_around;
+if(c.dynamic){
+var a=_5.dynAdvices[_5.dynIndex++],t=a.around;
+if(t){
+return t.apply(a,arguments);
+}
+}else{
+return c.advice.around.apply(c.advice,arguments);
+}
+}
+return _3e.target.apply(_5.instance,arguments);
+};
+})();
+}
diff --git a/dojox/lang/aspect/cflow.js b/dojox/lang/aspect/cflow.js
new file mode 100644
index 0000000..27917bd
--- /dev/null
+++ b/dojox/lang/aspect/cflow.js
@@ -0,0 +1,43 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.aspect.cflow"]){
+dojo._hasResource["dojox.lang.aspect.cflow"]=true;
+dojo.provide("dojox.lang.aspect.cflow");
+(function(){
+var _1=dojox.lang.aspect;
+_1.cflow=function(_2,_3){
+if(arguments.length>1&&!(_3 instanceof Array)){
+_3=[_3];
+}
+var _4=_1.getContextStack();
+for(var i=_4.length-1;i>=0;--i){
+var c=_4[i];
+if(_2&&c.instance!=_2){
+continue;
+}
+if(!_3){
+return true;
+}
+var n=c.joinPoint.targetName;
+for(var j=_3.length-1;j>=0;--j){
+var m=_3[j];
+if(m instanceof RegExp){
+if(m.test(n)){
+return true;
+}
+}else{
+if(n==m){
+return true;
+}
+}
+}
+}
+return false;
+};
+})();
+}
diff --git a/dojox/lang/aspect/counter.js b/dojox/lang/aspect/counter.js
new file mode 100644
index 0000000..d2e0ad9
--- /dev/null
+++ b/dojox/lang/aspect/counter.js
@@ -0,0 +1,27 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.aspect.counter"]){
+dojo._hasResource["dojox.lang.aspect.counter"]=true;
+dojo.provide("dojox.lang.aspect.counter");
+(function(){
+var _1=dojox.lang.aspect;
+var _2=function(){
+this.reset();
+};
+dojo.extend(_2,{before:function(){
+++this.calls;
+},afterThrowing:function(){
+++this.errors;
+},reset:function(){
+this.calls=this.errors=0;
+}});
+_1.counter=function(){
+return new _2;
+};
+})();
+}
diff --git a/dojox/lang/aspect/memoizer.js b/dojox/lang/aspect/memoizer.js
new file mode 100644
index 0000000..ed4443e
--- /dev/null
+++ b/dojox/lang/aspect/memoizer.js
@@ -0,0 +1,47 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.aspect.memoizer"]){
+dojo._hasResource["dojox.lang.aspect.memoizer"]=true;
+dojo.provide("dojox.lang.aspect.memoizer");
+(function(){
+var _1=dojox.lang.aspect;
+var _2={around:function(_3){
+var _4=_1.getContext(),_5=_4.joinPoint,_6=_4.instance,t,u,_9;
+if((t=_6.__memoizerCache)&&(t=t[_5.targetName])&&(_3 in t)){
+return t[_3];
+}
+var _9=_1.proceed.apply(null,arguments);
+if(!(t=_6.__memoizerCache)){
+t=_6.__memoizerCache={};
+}
+if(!(u=t[_5.targetName])){
+u=t[_5.targetName]={};
+}
+return u[_3]=_9;
+}};
+var _a=function(_b){
+return {around:function(){
+var _c=_1.getContext(),_d=_c.joinPoint,_e=_c.instance,t,u,ret,key=_b.apply(_e,arguments);
+if((t=_e.__memoizerCache)&&(t=t[_d.targetName])&&(key in t)){
+return t[key];
+}
+var ret=_1.proceed.apply(null,arguments);
+if(!(t=_e.__memoizerCache)){
+t=_e.__memoizerCache={};
+}
+if(!(u=t[_d.targetName])){
+u=t[_d.targetName]={};
+}
+return u[key]=ret;
+}};
+};
+_1.memoizer=function(_13){
+return arguments.length==0?_2:_a(_13);
+};
+})();
+}
diff --git a/dojox/lang/aspect/memoizerGuard.js b/dojox/lang/aspect/memoizerGuard.js
new file mode 100644
index 0000000..8dfce11
--- /dev/null
+++ b/dojox/lang/aspect/memoizerGuard.js
@@ -0,0 +1,35 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.aspect.memoizerGuard"]){
+dojo._hasResource["dojox.lang.aspect.memoizerGuard"]=true;
+dojo.provide("dojox.lang.aspect.memoizerGuard");
+(function(){
+var _1=dojox.lang.aspect,_2=function(_3){
+var _4=_1.getContext().instance,t;
+if(!(t=_4.__memoizerCache)){
+return;
+}
+if(arguments.length==0){
+delete _4.__memoizerCache;
+}else{
+if(dojo.isArray(_3)){
+dojo.forEach(_3,function(m){
+delete t[m];
+});
+}else{
+delete t[_3];
+}
+}
+};
+_1.memoizerGuard=function(_7){
+return {after:function(){
+_2(_7);
+}};
+};
+})();
+}
diff --git a/dojox/lang/aspect/profiler.js b/dojox/lang/aspect/profiler.js
new file mode 100644
index 0000000..33005d7
--- /dev/null
+++ b/dojox/lang/aspect/profiler.js
@@ -0,0 +1,30 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.aspect.profiler"]){
+dojo._hasResource["dojox.lang.aspect.profiler"]=true;
+dojo.provide("dojox.lang.aspect.profiler");
+(function(){
+var _1=dojox.lang.aspect,_2=0;
+var _3=function(_4){
+this.args=_4?[_4]:[];
+this.inCall=0;
+};
+dojo.extend(_3,{before:function(){
+if(!(this.inCall++)){
+console.profile.apply(console,this.args);
+}
+},after:function(){
+if(!--this.inCall){
+
+}
+}});
+_1.profiler=function(_5){
+return new _3(_5);
+};
+})();
+}
diff --git a/dojox/lang/aspect/timer.js b/dojox/lang/aspect/timer.js
new file mode 100644
index 0000000..71f888e
--- /dev/null
+++ b/dojox/lang/aspect/timer.js
@@ -0,0 +1,30 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.aspect.timer"]){
+dojo._hasResource["dojox.lang.aspect.timer"]=true;
+dojo.provide("dojox.lang.aspect.timer");
+(function(){
+var _1=dojox.lang.aspect,_2=0;
+var _3=function(_4){
+this.name=_4||("DojoAopTimer #"+ ++_2);
+this.inCall=0;
+};
+dojo.extend(_3,{before:function(){
+if(!(this.inCall++)){
+
+}
+},after:function(){
+if(!--this.inCall){
+
+}
+}});
+_1.timer=function(_5){
+return new _3(_5);
+};
+})();
+}
diff --git a/dojox/lang/aspect/tracer.js b/dojox/lang/aspect/tracer.js
new file mode 100644
index 0000000..9aa5335
--- /dev/null
+++ b/dojox/lang/aspect/tracer.js
@@ -0,0 +1,38 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.aspect.tracer"]){
+dojo._hasResource["dojox.lang.aspect.tracer"]=true;
+dojo.provide("dojox.lang.aspect.tracer");
+(function(){
+var _1=dojox.lang.aspect;
+var _2=function(_3){
+this.method=_3?"group":"log";
+if(_3){
+this.after=this._after;
+}
+};
+dojo.extend(_2,{before:function(){
+var _4=_1.getContext(),_5=_4.joinPoint,_6=Array.prototype.join.call(arguments,", ");
+console[this.method](_4.instance,"=>",_5.targetName+"("+_6+")");
+},afterReturning:function(_7){
+var _8=_1.getContext().joinPoint;
+if(typeof _7!="undefined"){
+
+}else{
+
+}
+},afterThrowing:function(_9){
+
+},_after:function(_a){
+
+}});
+_1.tracer=function(_b){
+return new _2(_b);
+};
+})();
+}
diff --git a/dojox/lang/functional.js b/dojox/lang/functional.js
new file mode 100644
index 0000000..364aed0
--- /dev/null
+++ b/dojox/lang/functional.js
@@ -0,0 +1,14 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.functional"]){
+dojo._hasResource["dojox.lang.functional"]=true;
+dojo.provide("dojox.lang.functional");
+dojo.require("dojox.lang.functional.lambda");
+dojo.require("dojox.lang.functional.array");
+dojo.require("dojox.lang.functional.object");
+}
diff --git a/dojox/lang/functional/array.js b/dojox/lang/functional/array.js
new file mode 100644
index 0000000..9b964cc
--- /dev/null
+++ b/dojox/lang/functional/array.js
@@ -0,0 +1,161 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.functional.array"]){
+dojo._hasResource["dojox.lang.functional.array"]=true;
+dojo.provide("dojox.lang.functional.array");
+dojo.require("dojox.lang.functional.lambda");
+(function(){
+var d=dojo,df=dojox.lang.functional,_3={};
+d.mixin(df,{filter:function(a,f,o){
+if(typeof a=="string"){
+a=a.split("");
+}
+o=o||d.global;
+f=df.lambda(f);
+var t=[],v,i,n;
+if(d.isArray(a)){
+for(i=0,n=a.length;i<n;++i){
+v=a[i];
+if(f.call(o,v,i,a)){
+t.push(v);
+}
+}
+}else{
+if(typeof a.hasNext=="function"&&typeof a.next=="function"){
+for(i=0;a.hasNext();){
+v=a.next();
+if(f.call(o,v,i++,a)){
+t.push(v);
+}
+}
+}else{
+for(i in a){
+if(!(i in _3)){
+v=a[i];
+if(f.call(o,v,i,a)){
+t.push(v);
+}
+}
+}
+}
+}
+return t;
+},forEach:function(a,f,o){
+if(typeof a=="string"){
+a=a.split("");
+}
+o=o||d.global;
+f=df.lambda(f);
+var i,n;
+if(d.isArray(a)){
+for(i=0,n=a.length;i<n;f.call(o,a[i],i,a),++i){
+}
+}else{
+if(typeof a.hasNext=="function"&&typeof a.next=="function"){
+for(i=0;a.hasNext();f.call(o,a.next(),i++,a)){
+}
+}else{
+for(i in a){
+if(!(i in _3)){
+f.call(o,a[i],i,a);
+}
+}
+}
+}
+return o;
+},map:function(a,f,o){
+if(typeof a=="string"){
+a=a.split("");
+}
+o=o||d.global;
+f=df.lambda(f);
+var t,n,i;
+if(d.isArray(a)){
+t=new Array(n=a.length);
+for(i=0;i<n;t[i]=f.call(o,a[i],i,a),++i){
+}
+}else{
+if(typeof a.hasNext=="function"&&typeof a.next=="function"){
+t=[];
+for(i=0;a.hasNext();t.push(f.call(o,a.next(),i++,a))){
+}
+}else{
+t=[];
+for(i in a){
+if(!(i in _3)){
+t.push(f.call(o,a[i],i,a));
+}
+}
+}
+}
+return t;
+},every:function(a,f,o){
+if(typeof a=="string"){
+a=a.split("");
+}
+o=o||d.global;
+f=df.lambda(f);
+var i,n;
+if(d.isArray(a)){
+for(i=0,n=a.length;i<n;++i){
+if(!f.call(o,a[i],i,a)){
+return false;
+}
+}
+}else{
+if(typeof a.hasNext=="function"&&typeof a.next=="function"){
+for(i=0;a.hasNext();){
+if(!f.call(o,a.next(),i++,a)){
+return false;
+}
+}
+}else{
+for(i in a){
+if(!(i in _3)){
+if(!f.call(o,a[i],i,a)){
+return false;
+}
+}
+}
+}
+}
+return true;
+},some:function(a,f,o){
+if(typeof a=="string"){
+a=a.split("");
+}
+o=o||d.global;
+f=df.lambda(f);
+var i,n;
+if(d.isArray(a)){
+for(i=0,n=a.length;i<n;++i){
+if(f.call(o,a[i],i,a)){
+return true;
+}
+}
+}else{
+if(typeof a.hasNext=="function"&&typeof a.next=="function"){
+for(i=0;a.hasNext();){
+if(f.call(o,a.next(),i++,a)){
+return true;
+}
+}
+}else{
+for(i in a){
+if(!(i in _3)){
+if(f.call(o,a[i],i,a)){
+return true;
+}
+}
+}
+}
+}
+return false;
+}});
+})();
+}
diff --git a/dojox/lang/functional/binrec.js b/dojox/lang/functional/binrec.js
new file mode 100644
index 0000000..8d48b8a
--- /dev/null
+++ b/dojox/lang/functional/binrec.js
@@ -0,0 +1,62 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.functional.binrec"]){
+dojo._hasResource["dojox.lang.functional.binrec"]=true;
+dojo.provide("dojox.lang.functional.binrec");
+dojo.require("dojox.lang.functional.lambda");
+dojo.require("dojox.lang.functional.util");
+(function(){
+var df=dojox.lang.functional,_2=df.inlineLambda,_x="_x",_4=["_z.r","_r","_z.a"];
+df.binrec=function(_5,_6,_7,_8){
+var c,t,b,a,cs,ts,bs,as,_11={},_12={},_13=function(x){
+_11[x]=1;
+};
+if(typeof _5=="string"){
+cs=_2(_5,_x,_13);
+}else{
+c=df.lambda(_5);
+cs="_c.apply(this, _x)";
+_12["_c=_t.c"]=1;
+}
+if(typeof _6=="string"){
+ts=_2(_6,_x,_13);
+}else{
+t=df.lambda(_6);
+ts="_t.apply(this, _x)";
+}
+if(typeof _7=="string"){
+bs=_2(_7,_x,_13);
+}else{
+b=df.lambda(_7);
+bs="_b.apply(this, _x)";
+_12["_b=_t.b"]=1;
+}
+if(typeof _8=="string"){
+as=_2(_8,_4,_13);
+}else{
+a=df.lambda(_8);
+as="_a.call(this, _z.r, _r, _z.a)";
+_12["_a=_t.a"]=1;
+}
+var _15=df.keys(_11),_16=df.keys(_12),f=new Function([],"var _x=arguments,_y,_z,_r".concat(_15.length?","+_15.join(","):"",_16.length?",_t=_x.callee,"+_16.join(","):"",t?(_16.length?",_t=_t.t":"_t=_x.callee.t"):"",";while(!",cs,"){_r=",bs,";_y={p:_y,a:_r[1]};_z={p:_z,a:_x};_x=_r[0]}for(;;){do{_r=",ts,";if(!_z)return _r;while(\"r\" in _z){_r=",as,";if(!(_z=_z.p))return _r}_z.r=_r;_x=_y.a;_y=_y.p}while(",cs,");do{_r=",bs,";_y={p:_y,a:_r[1]};_z={p:_z,a:_x};_x=_r[0]}while(!",cs,")}"));
+if(c){
+f.c=c;
+}
+if(t){
+f.t=t;
+}
+if(b){
+f.b=b;
+}
+if(a){
+f.a=a;
+}
+return f;
+};
+})();
+}
diff --git a/dojox/lang/functional/curry.js b/dojox/lang/functional/curry.js
new file mode 100644
index 0000000..e547fa1
--- /dev/null
+++ b/dojox/lang/functional/curry.js
@@ -0,0 +1,64 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.functional.curry"]){
+dojo._hasResource["dojox.lang.functional.curry"]=true;
+dojo.provide("dojox.lang.functional.curry");
+dojo.require("dojox.lang.functional.lambda");
+(function(){
+var df=dojox.lang.functional,ap=Array.prototype;
+var _3=function(_4){
+return function(){
+var _5=_4.args.concat(ap.slice.call(arguments,0));
+if(arguments.length+_4.args.length<_4.arity){
+return _3({func:_4.func,arity:_4.arity,args:_5});
+}
+return _4.func.apply(this,_5);
+};
+};
+dojo.mixin(df,{curry:function(f,_7){
+f=df.lambda(f);
+_7=typeof _7=="number"?_7:f.length;
+return _3({func:f,arity:_7,args:[]});
+},arg:{},partial:function(f){
+var a=arguments,l=a.length,_b=new Array(l-1),p=[],i=1,t;
+f=df.lambda(f);
+for(;i<l;++i){
+t=a[i];
+_b[i-1]=t;
+if(t===df.arg){
+p.push(i-1);
+}
+}
+return function(){
+var t=ap.slice.call(_b,0),i=0,l=p.length;
+for(;i<l;++i){
+t[p[i]]=arguments[i];
+}
+return f.apply(this,t);
+};
+},mixer:function(f,mix){
+f=df.lambda(f);
+return function(){
+var t=new Array(mix.length),i=0,l=mix.length;
+for(;i<l;++i){
+t[i]=arguments[mix[i]];
+}
+return f.apply(this,t);
+};
+},flip:function(f){
+f=df.lambda(f);
+return function(){
+var a=arguments,l=a.length-1,t=new Array(l+1),i=0;
+for(;i<=l;++i){
+t[l-i]=a[i];
+}
+return f.apply(this,t);
+};
+}});
+})();
+}
diff --git a/dojox/lang/functional/fold.js b/dojox/lang/functional/fold.js
new file mode 100644
index 0000000..03fad93
--- /dev/null
+++ b/dojox/lang/functional/fold.js
@@ -0,0 +1,104 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.functional.fold"]){
+dojo._hasResource["dojox.lang.functional.fold"]=true;
+dojo.provide("dojox.lang.functional.fold");
+dojo.require("dojox.lang.functional.lambda");
+(function(){
+var d=dojo,df=dojox.lang.functional,_3={};
+d.mixin(df,{foldl:function(a,f,z,o){
+if(typeof a=="string"){
+a=a.split("");
+}
+o=o||d.global;
+f=df.lambda(f);
+var i,n;
+if(d.isArray(a)){
+for(i=0,n=a.length;i<n;z=f.call(o,z,a[i],i,a),++i){
+}
+}else{
+if(typeof a.hasNext=="function"&&typeof a.next=="function"){
+for(i=0;a.hasNext();z=f.call(o,z,a.next(),i++,a)){
+}
+}else{
+for(i in a){
+if(!(i in _3)){
+z=f.call(o,z,a[i],i,a);
+}
+}
+}
+}
+return z;
+},foldl1:function(a,f,o){
+if(typeof a=="string"){
+a=a.split("");
+}
+o=o||d.global;
+f=df.lambda(f);
+var z,i,n;
+if(d.isArray(a)){
+z=a[0];
+for(i=1,n=a.length;i<n;z=f.call(o,z,a[i],i,a),++i){
+}
+}else{
+if(typeof a.hasNext=="function"&&typeof a.next=="function"){
+if(a.hasNext()){
+z=a.next();
+for(i=1;a.hasNext();z=f.call(o,z,a.next(),i++,a)){
+}
+}
+}else{
+var _10=true;
+for(i in a){
+if(!(i in _3)){
+if(_10){
+z=a[i];
+_10=false;
+}else{
+z=f.call(o,z,a[i],i,a);
+}
+}
+}
+}
+}
+return z;
+},foldr:function(a,f,z,o){
+if(typeof a=="string"){
+a=a.split("");
+}
+o=o||d.global;
+f=df.lambda(f);
+for(var i=a.length;i>0;--i,z=f.call(o,z,a[i],i,a)){
+}
+return z;
+},foldr1:function(a,f,o){
+if(typeof a=="string"){
+a=a.split("");
+}
+o=o||d.global;
+f=df.lambda(f);
+var n=a.length,z=a[n-1],i=n-1;
+for(;i>0;--i,z=f.call(o,z,a[i],i,a)){
+}
+return z;
+},reduce:function(a,f,z){
+return arguments.length<3?df.foldl1(a,f):df.foldl(a,f,z);
+},reduceRight:function(a,f,z){
+return arguments.length<3?df.foldr1(a,f):df.foldr(a,f,z);
+},unfold:function(pr,f,g,z,o){
+o=o||d.global;
+f=df.lambda(f);
+g=df.lambda(g);
+pr=df.lambda(pr);
+var t=[];
+for(;!pr.call(o,z);t.push(f.call(o,z)),z=g.call(o,z)){
+}
+return t;
+}});
+})();
+}
diff --git a/dojox/lang/functional/lambda.js b/dojox/lang/functional/lambda.js
new file mode 100644
index 0000000..a9d5221
--- /dev/null
+++ b/dojox/lang/functional/lambda.js
@@ -0,0 +1,89 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.functional.lambda"]){
+dojo._hasResource["dojox.lang.functional.lambda"]=true;
+dojo.provide("dojox.lang.functional.lambda");
+(function(){
+var df=dojox.lang.functional,_2={};
+var _3="ab".split(/a*/).length>1?String.prototype.split:function(_4){
+var r=this.split.call(this,_4),m=_4.exec(this);
+if(m&&m.index==0){
+r.unshift("");
+}
+return r;
+};
+var _7=function(s){
+var _9=[],_a=_3.call(s,/\s*->\s*/m);
+if(_a.length>1){
+while(_a.length){
+s=_a.pop();
+_9=_a.pop().split(/\s*,\s*|\s+/m);
+if(_a.length){
+_a.push("(function("+_9+"){return ("+s+")})");
+}
+}
+}else{
+if(s.match(/\b_\b/)){
+_9=["_"];
+}else{
+var l=s.match(/^\s*(?:[+*\/%&|\^\.=<>]|!=)/m),r=s.match(/[+\-*\/%&|\^\.=<>!]\s*$/m);
+if(l||r){
+if(l){
+_9.push("$1");
+s="$1"+s;
+}
+if(r){
+_9.push("$2");
+s=s+"$2";
+}
+}else{
+var _d=s.replace(/(?:\b[A-Z]|\.[a-zA-Z_$])[a-zA-Z_$\d]*|[a-zA-Z_$][a-zA-Z_$\d]*:|this|true|false|null|undefined|typeof|instanceof|in|delete|new|void|arguments|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|escape|eval|isFinite|isNaN|parseFloat|parseInt|unescape|dojo|dijit|dojox|window|document|'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"/g,"").match(/([a-z_$][a-z_$\d]*)/gi)||[],t={};
+dojo.forEach(_d,function(v){
+if(!(v in t)){
+_9.push(v);
+t[v]=1;
+}
+});
+}
+}
+}
+return {args:_9,body:s};
+};
+var _10=function(a){
+return a.length?function(){
+var i=a.length-1,x=df.lambda(a[i]).apply(this,arguments);
+for(--i;i>=0;--i){
+x=df.lambda(a[i]).call(this,x);
+}
+return x;
+}:function(x){
+return x;
+};
+};
+dojo.mixin(df,{rawLambda:function(s){
+return _7(s);
+},buildLambda:function(s){
+s=_7(s);
+return "function("+s.args.join(",")+"){return ("+s.body+");}";
+},lambda:function(s){
+if(typeof s=="function"){
+return s;
+}
+if(s instanceof Array){
+return _10(s);
+}
+if(s in _2){
+return _2[s];
+}
+s=_7(s);
+return _2[s]=new Function(s.args,"return ("+s.body+");");
+},clearLambdaCache:function(){
+_2={};
+}});
+})();
+}
diff --git a/dojox/lang/functional/linrec.js b/dojox/lang/functional/linrec.js
new file mode 100644
index 0000000..2a8f042
--- /dev/null
+++ b/dojox/lang/functional/linrec.js
@@ -0,0 +1,62 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.functional.linrec"]){
+dojo._hasResource["dojox.lang.functional.linrec"]=true;
+dojo.provide("dojox.lang.functional.linrec");
+dojo.require("dojox.lang.functional.lambda");
+dojo.require("dojox.lang.functional.util");
+(function(){
+var df=dojox.lang.functional,_2=df.inlineLambda,_x="_x",_4=["_r","_y.a"];
+df.linrec=function(_5,_6,_7,_8){
+var c,t,b,a,cs,ts,bs,as,_11={},_12={},_13=function(x){
+_11[x]=1;
+};
+if(typeof _5=="string"){
+cs=_2(_5,_x,_13);
+}else{
+c=df.lambda(_5);
+cs="_c.apply(this, _x)";
+_12["_c=_t.c"]=1;
+}
+if(typeof _6=="string"){
+ts=_2(_6,_x,_13);
+}else{
+t=df.lambda(_6);
+ts="_t.t.apply(this, _x)";
+}
+if(typeof _7=="string"){
+bs=_2(_7,_x,_13);
+}else{
+b=df.lambda(_7);
+bs="_b.apply(this, _x)";
+_12["_b=_t.b"]=1;
+}
+if(typeof _8=="string"){
+as=_2(_8,_4,_13);
+}else{
+a=df.lambda(_8);
+as="_a.call(this, _r, _y.a)";
+_12["_a=_t.a"]=1;
+}
+var _15=df.keys(_11),_16=df.keys(_12),f=new Function([],"var _x=arguments,_y,_r".concat(_15.length?","+_15.join(","):"",_16.length?",_t=_x.callee,"+_16.join(","):t?",_t=_x.callee":"",";for(;!",cs,";_x=",bs,"){_y={p:_y,a:_x}}_r=",ts,";for(;_y;_y=_y.p){_r=",as,"}return _r"));
+if(c){
+f.c=c;
+}
+if(t){
+f.t=t;
+}
+if(b){
+f.b=b;
+}
+if(a){
+f.a=a;
+}
+return f;
+};
+})();
+}
diff --git a/dojox/lang/functional/listcomp.js b/dojox/lang/functional/listcomp.js
new file mode 100644
index 0000000..fa60f34
--- /dev/null
+++ b/dojox/lang/functional/listcomp.js
@@ -0,0 +1,33 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.functional.listcomp"]){
+dojo._hasResource["dojox.lang.functional.listcomp"]=true;
+dojo.provide("dojox.lang.functional.listcomp");
+(function(){
+var _1=/\bfor\b|\bif\b/gm;
+var _2=function(s){
+var _4=s.split(_1),_5=s.match(_1),_6=["var r = [];"],_7=[],i=0,l=_5.length;
+while(i<l){
+var a=_5[i],f=_4[++i];
+if(a=="for"&&!/^\s*\(\s*(;|var)/.test(f)){
+f=f.replace(/^\s*\(/,"(var ");
+}
+_6.push(a,f,"{");
+_7.push("}");
+}
+return _6.join("")+"r.push("+_4[0]+");"+_7.join("")+"return r;";
+};
+dojo.mixin(dojox.lang.functional,{buildListcomp:function(s){
+return "function(){"+_2(s)+"}";
+},compileListcomp:function(s){
+return new Function([],_2(s));
+},listcomp:function(s){
+return (new Function([],_2(s)))();
+}});
+})();
+}
diff --git a/dojox/lang/functional/multirec.js b/dojox/lang/functional/multirec.js
new file mode 100644
index 0000000..4eb5a50
--- /dev/null
+++ b/dojox/lang/functional/multirec.js
@@ -0,0 +1,62 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.functional.multirec"]){
+dojo._hasResource["dojox.lang.functional.multirec"]=true;
+dojo.provide("dojox.lang.functional.multirec");
+dojo.require("dojox.lang.functional.lambda");
+dojo.require("dojox.lang.functional.util");
+(function(){
+var df=dojox.lang.functional,_2=df.inlineLambda,_x="_x",_4=["_y.r","_y.o"];
+df.multirec=function(_5,_6,_7,_8){
+var c,t,b,a,cs,ts,bs,as,_11={},_12={},_13=function(x){
+_11[x]=1;
+};
+if(typeof _5=="string"){
+cs=_2(_5,_x,_13);
+}else{
+c=df.lambda(_5);
+cs="_c.apply(this, _x)";
+_12["_c=_t.c"]=1;
+}
+if(typeof _6=="string"){
+ts=_2(_6,_x,_13);
+}else{
+t=df.lambda(_6);
+ts="_t.apply(this, _x)";
+}
+if(typeof _7=="string"){
+bs=_2(_7,_x,_13);
+}else{
+b=df.lambda(_7);
+bs="_b.apply(this, _x)";
+_12["_b=_t.b"]=1;
+}
+if(typeof _8=="string"){
+as=_2(_8,_4,_13);
+}else{
+a=df.lambda(_8);
+as="_a.call(this, _y.r, _y.o)";
+_12["_a=_t.a"]=1;
+}
+var _15=df.keys(_11),_16=df.keys(_12),f=new Function([],"var _y={a:arguments},_x,_r,_z,_i".concat(_15.length?","+_15.join(","):"",_16.length?",_t=arguments.callee,"+_16.join(","):"",t?(_16.length?",_t=_t.t":"_t=arguments.callee.t"):"",";for(;;){for(;;){if(_y.o){_r=",as,";break}_x=_y.a;if(",cs,"){_r=",ts,";break}_y.o=_x;_x=",bs,";_y.r=[];_z=_y;for(_i=_x.length-1;_i>=0;--_i){_y={p:_y,a:_x[_i],z:_z}}}if(!(_z=_y.z)){return _r}_z.r.push(_r);_y=_y.p}"));
+if(c){
+f.c=c;
+}
+if(t){
+f.t=t;
+}
+if(b){
+f.b=b;
+}
+if(a){
+f.a=a;
+}
+return f;
+};
+})();
+}
diff --git a/dojox/lang/functional/numrec.js b/dojox/lang/functional/numrec.js
new file mode 100644
index 0000000..ebc6a32
--- /dev/null
+++ b/dojox/lang/functional/numrec.js
@@ -0,0 +1,33 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.functional.numrec"]){
+dojo._hasResource["dojox.lang.functional.numrec"]=true;
+dojo.provide("dojox.lang.functional.numrec");
+dojo.require("dojox.lang.functional.lambda");
+dojo.require("dojox.lang.functional.util");
+(function(){
+var df=dojox.lang.functional,_2=df.inlineLambda,_3=["_r","_i"];
+df.numrec=function(_4,_5){
+var a,as,_8={},_9=function(x){
+_8[x]=1;
+};
+if(typeof _5=="string"){
+as=_2(_5,_3,_9);
+}else{
+a=df.lambda(_5);
+as="_a.call(this, _r, _i)";
+}
+var _b=df.keys(_8),f=new Function(["_x"],"var _t=arguments.callee,_r=_t.t,_i".concat(_b.length?","+_b.join(","):"",a?",_a=_t.a":"",";for(_i=1;_i<=_x;++_i){_r=",as,"}return _r"));
+f.t=_4;
+if(a){
+f.a=a;
+}
+return f;
+};
+})();
+}
diff --git a/dojox/lang/functional/object.js b/dojox/lang/functional/object.js
new file mode 100644
index 0000000..9b493c3
--- /dev/null
+++ b/dojox/lang/functional/object.js
@@ -0,0 +1,64 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.functional.object"]){
+dojo._hasResource["dojox.lang.functional.object"]=true;
+dojo.provide("dojox.lang.functional.object");
+dojo.require("dojox.lang.functional.lambda");
+(function(){
+var d=dojo,df=dojox.lang.functional,_3={};
+d.mixin(df,{keys:function(_4){
+var t=[];
+for(var i in _4){
+if(!(i in _3)){
+t.push(i);
+}
+}
+return t;
+},values:function(_7){
+var t=[];
+for(var i in _7){
+if(!(i in _3)){
+t.push(_7[i]);
+}
+}
+return t;
+},filterIn:function(_a,f,o){
+o=o||d.global;
+f=df.lambda(f);
+var t={},v,i;
+for(i in _a){
+if(!(i in _3)){
+v=_a[i];
+if(f.call(o,v,i,_a)){
+t[i]=v;
+}
+}
+}
+return t;
+},forIn:function(obj,f,o){
+o=o||d.global;
+f=df.lambda(f);
+for(var i in obj){
+if(!(i in _3)){
+f.call(o,obj[i],i,obj);
+}
+}
+return o;
+},mapIn:function(obj,f,o){
+o=o||d.global;
+f=df.lambda(f);
+var t={},i;
+for(i in obj){
+if(!(i in _3)){
+t[i]=f.call(o,obj[i],i,obj);
+}
+}
+return t;
+}});
+})();
+}
diff --git a/dojox/lang/functional/reversed.js b/dojox/lang/functional/reversed.js
new file mode 100644
index 0000000..4baea00
--- /dev/null
+++ b/dojox/lang/functional/reversed.js
@@ -0,0 +1,72 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.functional.reversed"]){
+dojo._hasResource["dojox.lang.functional.reversed"]=true;
+dojo.provide("dojox.lang.functional.reversed");
+dojo.require("dojox.lang.functional.lambda");
+(function(){
+var d=dojo,df=dojox.lang.functional;
+d.mixin(df,{filterRev:function(a,f,o){
+if(typeof a=="string"){
+a=a.split("");
+}
+o=o||d.global;
+f=df.lambda(f);
+var t=[],v,i=a.length-1;
+for(;i>=0;--i){
+v=a[i];
+if(f.call(o,v,i,a)){
+t.push(v);
+}
+}
+return t;
+},forEachRev:function(a,f,o){
+if(typeof a=="string"){
+a=a.split("");
+}
+o=o||d.global;
+f=df.lambda(f);
+for(var i=a.length-1;i>=0;f.call(o,a[i],i,a),--i){
+}
+},mapRev:function(a,f,o){
+if(typeof a=="string"){
+a=a.split("");
+}
+o=o||d.global;
+f=df.lambda(f);
+var n=a.length,t=new Array(n),i=n-1,j=0;
+for(;i>=0;t[j++]=f.call(o,a[i],i,a),--i){
+}
+return t;
+},everyRev:function(a,f,o){
+if(typeof a=="string"){
+a=a.split("");
+}
+o=o||d.global;
+f=df.lambda(f);
+for(var i=a.length-1;i>=0;--i){
+if(!f.call(o,a[i],i,a)){
+return false;
+}
+}
+return true;
+},someRev:function(a,f,o){
+if(typeof a=="string"){
+a=a.split("");
+}
+o=o||d.global;
+f=df.lambda(f);
+for(var i=a.length-1;i>=0;--i){
+if(f.call(o,a[i],i,a)){
+return true;
+}
+}
+return false;
+}});
+})();
+}
diff --git a/dojox/lang/functional/scan.js b/dojox/lang/functional/scan.js
new file mode 100644
index 0000000..aa1e738
--- /dev/null
+++ b/dojox/lang/functional/scan.js
@@ -0,0 +1,98 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.functional.scan"]){
+dojo._hasResource["dojox.lang.functional.scan"]=true;
+dojo.provide("dojox.lang.functional.scan");
+dojo.require("dojox.lang.functional.lambda");
+(function(){
+var d=dojo,df=dojox.lang.functional,_3={};
+d.mixin(df,{scanl:function(a,f,z,o){
+if(typeof a=="string"){
+a=a.split("");
+}
+o=o||d.global;
+f=df.lambda(f);
+var t,n,i;
+if(d.isArray(a)){
+t=new Array((n=a.length)+1);
+t[0]=z;
+for(i=0;i<n;z=f.call(o,z,a[i],i,a),t[++i]=z){
+}
+}else{
+if(typeof a.hasNext=="function"&&typeof a.next=="function"){
+t=[z];
+for(i=0;a.hasNext();t.push(z=f.call(o,z,a.next(),i++,a))){
+}
+}else{
+t=[z];
+for(i in a){
+if(!(i in _3)){
+t.push(z=f.call(o,z,a[i],i,a));
+}
+}
+}
+}
+return t;
+},scanl1:function(a,f,o){
+if(typeof a=="string"){
+a=a.split("");
+}
+o=o||d.global;
+f=df.lambda(f);
+var t,n,z,_11=true;
+if(d.isArray(a)){
+t=new Array(n=a.length);
+t[0]=z=a[0];
+for(var i=1;i<n;t[i]=z=f.call(o,z,a[i],i,a),++i){
+}
+}else{
+if(typeof a.hasNext=="function"&&typeof a.next=="function"){
+if(a.hasNext()){
+t=[z=a.next()];
+for(var i=1;a.hasNext();t.push(z=f.call(o,z,a.next(),i++,a))){
+}
+}
+}else{
+for(var i in a){
+if(!(i in _3)){
+if(_11){
+t=[z=a[i]];
+_11=false;
+}else{
+t.push(z=f.call(o,z,a[i],i,a));
+}
+}
+}
+}
+}
+return t;
+},scanr:function(a,f,z,o){
+if(typeof a=="string"){
+a=a.split("");
+}
+o=o||d.global;
+f=df.lambda(f);
+var n=a.length,t=new Array(n+1),i=n;
+t[n]=z;
+for(;i>0;--i,z=f.call(o,z,a[i],i,a),t[i]=z){
+}
+return t;
+},scanr1:function(a,f,o){
+if(typeof a=="string"){
+a=a.split("");
+}
+o=o||d.global;
+f=df.lambda(f);
+var n=a.length,t=new Array(n),z=a[n-1],i=n-1;
+t[i]=z;
+for(;i>0;--i,z=f.call(o,z,a[i],i,a),t[i]=z){
+}
+return t;
+}});
+})();
+}
diff --git a/dojox/lang/functional/sequence.js b/dojox/lang/functional/sequence.js
new file mode 100644
index 0000000..210e222
--- /dev/null
+++ b/dojox/lang/functional/sequence.js
@@ -0,0 +1,32 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.functional.sequence"]){
+dojo._hasResource["dojox.lang.functional.sequence"]=true;
+dojo.provide("dojox.lang.functional.sequence");
+dojo.require("dojox.lang.functional.lambda");
+(function(){
+var d=dojo,df=dojox.lang.functional;
+d.mixin(df,{repeat:function(n,f,z,o){
+o=o||d.global;
+f=df.lambda(f);
+var t=new Array(n),i=1;
+t[0]=z;
+for(;i<n;t[i]=z=f.call(o,z),++i){
+}
+return t;
+},until:function(pr,f,z,o){
+o=o||d.global;
+f=df.lambda(f);
+pr=df.lambda(pr);
+var t=[];
+for(;!pr.call(o,z);t.push(z),z=f.call(o,z)){
+}
+return t;
+}});
+})();
+}
diff --git a/dojox/lang/functional/tailrec.js b/dojox/lang/functional/tailrec.js
new file mode 100644
index 0000000..942dc34
--- /dev/null
+++ b/dojox/lang/functional/tailrec.js
@@ -0,0 +1,52 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.functional.tailrec"]){
+dojo._hasResource["dojox.lang.functional.tailrec"]=true;
+dojo.provide("dojox.lang.functional.tailrec");
+dojo.require("dojox.lang.functional.lambda");
+dojo.require("dojox.lang.functional.util");
+(function(){
+var df=dojox.lang.functional,_2=df.inlineLambda,_x="_x";
+df.tailrec=function(_4,_5,_6){
+var c,t,b,cs,ts,bs,_d={},_e={},_f=function(x){
+_d[x]=1;
+};
+if(typeof _4=="string"){
+cs=_2(_4,_x,_f);
+}else{
+c=df.lambda(_4);
+cs="_c.apply(this, _x)";
+_e["_c=_t.c"]=1;
+}
+if(typeof _5=="string"){
+ts=_2(_5,_x,_f);
+}else{
+t=df.lambda(_5);
+ts="_t.t.apply(this, _x)";
+}
+if(typeof _6=="string"){
+bs=_2(_6,_x,_f);
+}else{
+b=df.lambda(_6);
+bs="_b.apply(this, _x)";
+_e["_b=_t.b"]=1;
+}
+var _11=df.keys(_d),_12=df.keys(_e),f=new Function([],"var _x=arguments,_t=_x.callee,_c=_t.c,_b=_t.b".concat(_11.length?","+_11.join(","):"",_12.length?",_t=_x.callee,"+_12.join(","):t?",_t=_x.callee":"",";for(;!",cs,";_x=",bs,");return ",ts));
+if(c){
+f.c=c;
+}
+if(t){
+f.t=t;
+}
+if(b){
+f.b=b;
+}
+return f;
+};
+})();
+}
diff --git a/dojox/lang/functional/util.js b/dojox/lang/functional/util.js
new file mode 100644
index 0000000..f30237d
--- /dev/null
+++ b/dojox/lang/functional/util.js
@@ -0,0 +1,33 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.functional.util"]){
+dojo._hasResource["dojox.lang.functional.util"]=true;
+dojo.provide("dojox.lang.functional.util");
+dojo.require("dojox.lang.functional.lambda");
+(function(){
+var df=dojox.lang.functional;
+dojo.mixin(df,{inlineLambda:function(_2,_3,_4){
+var s=df.rawLambda(_2);
+if(_4){
+df.forEach(s.args,_4);
+}
+var ap=typeof _3=="string",n=ap?s.args.length:Math.min(s.args.length,_3.length),a=new Array(4*n+4),i,j=1;
+for(i=0;i<n;++i){
+a[j++]=s.args[i];
+a[j++]="=";
+a[j++]=ap?_3+"["+i+"]":_3[i];
+a[j++]=",";
+}
+a[0]="(";
+a[j++]="(";
+a[j++]=s.body;
+a[j]="))";
+return a.join("");
+}});
+})();
+}
diff --git a/dojox/lang/functional/zip.js b/dojox/lang/functional/zip.js
new file mode 100644
index 0000000..0c13aa8
--- /dev/null
+++ b/dojox/lang/functional/zip.js
@@ -0,0 +1,28 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.functional.zip"]){
+dojo._hasResource["dojox.lang.functional.zip"]=true;
+dojo.provide("dojox.lang.functional.zip");
+(function(){
+var df=dojox.lang.functional;
+dojo.mixin(df,{zip:function(){
+var n=arguments[0].length,m=arguments.length,i=1,t=new Array(n),j,p;
+for(;i<m;n=Math.min(n,arguments[i++].length)){
+}
+for(i=0;i<n;++i){
+p=new Array(m);
+for(j=0;j<m;p[j]=arguments[j][i],++j){
+}
+t[i]=p;
+}
+return t;
+},unzip:function(a){
+return df.zip.apply(null,a);
+}});
+})();
+}
diff --git a/dojox/lang/observable.js b/dojox/lang/observable.js
new file mode 100644
index 0000000..3a6600a
--- /dev/null
+++ b/dojox/lang/observable.js
@@ -0,0 +1,153 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.observable"]){
+dojo._hasResource["dojox.lang.observable"]=true;
+dojo.provide("dojox.lang.observable");
+dojo.experimental("dojox.lang.observable");
+dojox.lang.observable=function(_1,_2,_3,_4){
+return dojox.lang.makeObservable(_2,_3,_4)(_1);
+};
+dojox.lang.makeObservable=function(_5,_6,_7,_8){
+_8=_8||{};
+_7=_7||function(_9,_a,_b,_c){
+return _a[_b].apply(_9,_c);
+};
+function _d(_e,_f,i){
+return function(){
+return _7(_e,_f,i,arguments);
+};
+};
+if(dojox.lang.lettableWin){
+var _11=dojox.lang.makeObservable;
+_11.inc=(_11.inc||0)+1;
+var _12="gettable_"+_11.inc;
+dojox.lang.lettableWin[_12]=_5;
+var _13="settable_"+_11.inc;
+dojox.lang.lettableWin[_13]=_6;
+var _14={};
+return function(_15){
+if(_15.__observable){
+return _15.__observable;
+}
+if(_15.data__){
+throw new Error("Can wrap an object that is already wrapped");
+}
+var _16=[],i,l;
+for(i in _8){
+_16.push(i);
+}
+var _19={type:1,event:1};
+for(i in _15){
+if(i.match(/^[a-zA-Z][\w\$_]*$/)&&!(i in _8)&&!(i in _19)){
+_16.push(i);
+}
+}
+var _1a=_16.join(",");
+var _1b,_1c=_14[_1a];
+if(!_1c){
+var _1d="dj_lettable_"+(_11.inc++);
+var _1e=_1d+"_dj_getter";
+var _1f=["Class "+_1d,"\tPublic data__"];
+for(i=0,l=_16.length;i<l;i++){
+_1b=_16[i];
+var _20=typeof _15[_1b];
+if(_20=="function"||_8[_1b]){
+_1f.push("  Public "+_1b);
+}else{
+if(_20!="object"){
+_1f.push("\tPublic Property Let "+_1b+"(val)","\t\tCall "+_13+"(me.data__,\""+_1b+"\",val)","\tEnd Property","\tPublic Property Get "+_1b,"\t\t"+_1b+" = "+_12+"(me.data__,\""+_1b+"\")","\tEnd Property");
+}
+}
+}
+_1f.push("End Class");
+_1f.push("Function "+_1e+"()","\tDim tmp","\tSet tmp = New "+_1d,"\tSet "+_1e+" = tmp","End Function");
+dojox.lang.lettableWin.vbEval(_1f.join("\n"));
+_14[_1a]=_1c=function(){
+return dojox.lang.lettableWin.construct(_1e);
+};
+}
+
+var _21=_1c();
+_21.data__=_15;
+
+try{
+_15.__observable=_21;
+}
+catch(e){
+}
+for(i=0,l=_16.length;i<l;i++){
+_1b=_16[i];
+try{
+var val=_15[_1b];
+}
+catch(e){
+
+}
+if(typeof val=="function"||_8[_1b]){
+_21[_1b]=_d(_21,_15,_1b);
+}
+}
+return _21;
+};
+}else{
+return function(_23){
+if(_23.__observable){
+return _23.__observable;
+}
+var _24=_23 instanceof Array?[]:{};
+_24.data__=_23;
+for(var i in _23){
+if(i.charAt(0)!="_"){
+if(typeof _23[i]=="function"){
+_24[i]=_d(_24,_23,i);
+}else{
+if(typeof _23[i]!="object"){
+(function(i){
+_24.__defineGetter__(i,function(){
+return _5(_23,i);
+});
+_24.__defineSetter__(i,function(_27){
+return _6(_23,i,_27);
+});
+})(i);
+}
+}
+}
+}
+for(i in _8){
+_24[i]=_d(_24,_23,i);
+}
+_23.__observable=_24;
+return _24;
+};
+}
+};
+if(!{}.__defineGetter__){
+if(dojo.isIE){
+var frame;
+if(document.body){
+frame=document.createElement("iframe");
+document.body.appendChild(frame);
+}else{
+document.write("<iframe id='dj_vb_eval_frame'></iframe>");
+frame=document.getElementById("dj_vb_eval_frame");
+}
+frame.style.display="none";
+var doc=frame.contentWindow.document;
+dojox.lang.lettableWin=frame.contentWindow;
+doc.write("<html><head><script language=\"VBScript\" type=\"text/VBScript\">"+"Function vb_global_eval(code)"+"ExecuteGlobal(code)"+"End Function"+"</script>"+"<script type=\"text/javascript\">"+"function vbEval(code){ \n"+"return vb_global_eval(code);"+"}"+"function construct(name){ \n"+"return window[name]();"+"}"+"</script>"+"</head><body>vb-eval</body></html>");
+doc.close();
+}else{
+throw new Error("This browser does not support getters and setters");
+}
+}
+dojox.lang.ReadOnlyProxy=dojox.lang.makeObservable(function(obj,i){
+return obj[i];
+},function(obj,i,_2c){
+});
+}
diff --git a/dojox/lang/oo/Decorator.js b/dojox/lang/oo/Decorator.js
new file mode 100644
index 0000000..4cd68b1
--- /dev/null
+++ b/dojox/lang/oo/Decorator.js
@@ -0,0 +1,24 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.oo.Decorator"]){
+dojo._hasResource["dojox.lang.oo.Decorator"]=true;
+dojo.provide("dojox.lang.oo.Decorator");
+(function(){
+var oo=dojox.lang.oo,D=oo.Decorator=function(_3,_4){
+this.value=_3;
+this.decorator=typeof _4=="object"?function(){
+return _4.exec.apply(_4,arguments);
+}:_4;
+};
+oo.makeDecorator=function(_5){
+return function(_6){
+return new D(_6,_5);
+};
+};
+})();
+}
diff --git a/dojox/lang/oo/Filter.js b/dojox/lang/oo/Filter.js
new file mode 100644
index 0000000..74e01af
--- /dev/null
+++ b/dojox/lang/oo/Filter.js
@@ -0,0 +1,28 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.oo.Filter"]){
+dojo._hasResource["dojox.lang.oo.Filter"]=true;
+dojo.provide("dojox.lang.oo.Filter");
+(function(){
+var oo=dojox.lang.oo,F=oo.Filter=function(_3,_4){
+this.bag=_3;
+this.filter=typeof _4=="object"?function(){
+return _4.exec.apply(_4,arguments);
+}:_4;
+};
+var _5=function(_6){
+this.map=_6;
+};
+_5.prototype.exec=function(_7){
+return this.map.hasOwnProperty(_7)?this.map[_7]:_7;
+};
+oo.filter=function(_8,_9){
+return new F(_8,new _5(_9));
+};
+})();
+}
diff --git a/dojox/lang/oo/aop.js b/dojox/lang/oo/aop.js
new file mode 100644
index 0000000..e4b93da
--- /dev/null
+++ b/dojox/lang/oo/aop.js
@@ -0,0 +1,55 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.oo.aop"]){
+dojo._hasResource["dojox.lang.oo.aop"]=true;
+dojo.provide("dojox.lang.oo.aop");
+dojo.require("dojox.lang.oo.Decorator");
+dojo.require("dojox.lang.oo.chain");
+dojo.require("dojox.lang.oo.general");
+(function(){
+var oo=dojox.lang.oo,md=oo.makeDecorator,_3=oo.aop;
+_3.before=oo.chain.before;
+_3.around=oo.general.wrap;
+_3.afterReturning=md(function(_4,_5,_6){
+return dojo.isFunction(_6)?function(){
+var _7=_6.apply(this,arguments);
+_5.call(this,_7);
+return _7;
+}:function(){
+_5.call(this);
+};
+});
+_3.afterThrowing=md(function(_8,_9,_a){
+return dojo.isFunction(_a)?function(){
+var _b;
+try{
+_b=_a.apply(this,arguments);
+}
+catch(e){
+_9.call(this,e);
+throw e;
+}
+return _b;
+}:_a;
+});
+_3.after=md(function(_c,_d,_e){
+return dojo.isFunction(_e)?function(){
+var _f;
+try{
+_f=_e.apply(this,arguments);
+}
+finally{
+_d.call(this);
+}
+return _f;
+}:function(){
+_d.call(this);
+};
+});
+})();
+}
diff --git a/dojox/lang/oo/declare.js b/dojox/lang/oo/declare.js
new file mode 100644
index 0000000..cba6d8c
--- /dev/null
+++ b/dojox/lang/oo/declare.js
@@ -0,0 +1,173 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.oo.declare"]){
+dojo._hasResource["dojox.lang.oo.declare"]=true;
+dojo.provide("dojox.lang.oo.declare");
+dojo.experimental("dojox.lang.oo.mixin");
+(function(){
+var d=dojo,oo=dojox.lang.oo,op=Object.prototype,_4=d.isFunction,_5=function(){
+},_6,i,_8=function(a,f){
+for(var i=0,l=a.length;i<l;++i){
+f(a[i]);
+}
+},_d=function(_e,_f){
+if(_e){
+throw new Error("declare: "+_f);
+}
+},mix=function(_11,_12,_13){
+var t=_11[_13],s=_12[_13];
+return t!==s&&s!==op[_13]?_11[_13]=s:0;
+},_16=function(_17,_18,_19){
+var t=mix(_17,_18,_19);
+if(_4(t)){
+t.nom=_19;
+}
+},_1b=function(_1c,_1d,mix){
+for(var _1f in _1d){
+mix(_1c,_1d,_1f);
+}
+_8(_6,function(_20){
+if(_20 in _1d){
+mix(_1c,_1d,_20);
+}
+});
+},_21=function(_22,_23){
+var m=_23._meta,mb=_22.bases;
+m&&mb.push(m.bases);
+mb.push(_23);
+};
+for(i in {toString:1}){
+_6=[];
+break;
+}
+_6=_6||["hasOwnProperty","valueOf","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString"];
+oo.makeDeclare=function(_26,_27){
+var _28={constructor:"after"},_29=function(_2a,_2b){
+var fs=[],mb=_2a.bases,i,l,t,c,m,h;
+for(i=0,l=mb.length;i<l;++i){
+(t=(c=mb[i])&&(m=c._meta)&&(h=m.hidden)?(_2b in h)&&h[_2b]:c.prototype[_2b])&&fs.push(t);
+}
+(t=_2a.hidden[_2b])&&fs.push(t);
+return _28[_2b]==="after"?fs:fs.reverse();
+},_33=function(_34,_35,a){
+var c=this.constructor,m=c._meta,_39=c._cache,_3a,i,l,f,n,ch,s,x;
+if(typeof _34!="string"){
+a=_35;
+_35=_34;
+_34="";
+}
+_3a=_33.caller;
+n=_3a.nom;
+_d(n&&_34&&n!==_34,"calling inherited() with a different name: "+_34);
+_34=_34||n;
+ch=_39[_34];
+if(!ch){
+_d(!_34,"can't deduce a name to call inherited()");
+_d(typeof _28[_34]=="string","chained method: "+_34);
+ch=_39[_34]=_29(m,_34);
+}
+do{
+s=this._inherited,n=s.length-1;
+if(n>=0){
+x=s[n];
+if(x.name===_34&&ch[x.pos]===_3a&&_3a.caller===_33){
+break;
+}
+}
+for(i=0,l=ch.length;i<l&&ch[i]!==_3a;++i){
+}
+if(i==l){
+this[_34]===_3a&&(i=-1)||_d(1,"can't find the caller for inherited()");
+}
+s.push(x={name:_34,start:i,pos:i});
+}while(false);
+f=ch[++x.pos];
+try{
+return f?f.apply(this,a||_35):undefined;
+}
+finally{
+x.start==--x.pos&&s.pop();
+}
+};
+_26=_26||[];
+_8(_26,function(_41){
+_28[_41]="before";
+});
+_27=_27||[];
+_8(_27,function(_42){
+_28[_42]="after";
+});
+return function(_43,_44,_45){
+var _46,_47,i,l,t,f,_4b,_4c={},_4d={bases:[]};
+if(typeof _43!="string"){
+_45=_44;
+_44=_43;
+_43="";
+}
+if(d.isArray(_44)){
+_46=_44;
+_44=_46[0];
+}
+if(_44){
+_21(_4d,_44);
+if(_46){
+for(i=1,l=_46.length;i<l;++i){
+_d(!(t=_46[i]),"mixin #"+i+" is null");
+_21(_4d,t);
+_5.prototype=_44.prototype;
+_47=new _5;
+_1b(_47,t.prototype,mix);
+(_4b=function(){
+}).superclass=_44;
+_4b.prototype=_47;
+_44=_47.constructor=_4b;
+}
+}
+_5.prototype=_44.prototype;
+_47=new _5;
+}else{
+_47={};
+}
+_1b(_47,(_4d.hidden=_45||{}),_16);
+_4d.bases=_4d.bases.concat.apply([],_4d.bases);
+_8(_27.concat(_26),function(_4e){
+(_47[_4e]=function(){
+var c=this.constructor,t=_29(c._meta,_4e),l=t.length,f=function(){
+for(var i=0;i<l;++i){
+t[i].apply(this,arguments);
+}
+};
+f.nom=_4e;
+(c.prototype[_4e]=f).apply(this,arguments);
+}).nom=_4e;
+});
+_47.inherited=_33;
+t=_29(_4d,"constructor");
+_4b=function(){
+this._inherited=[];
+var a=arguments,_52=a,a0=a[0],f,i,l;
+a=a0&&(f=a0.preamble)&&f.apply(this,a)||a;
+a=(f=this.preamble)&&f.apply(this,a)||a;
+for(i=0,l=t.length-1;i<l;++i){
+t[i].apply(this,a);
+}
+l>=0&&t[i].apply(this,t[i]===_4b._meta.hidden.constructor?_52:a);
+(f=this.postscript)&&f.apply(this,_52);
+};
+_4b._meta=_4d;
+_4b._cache={};
+_4b.superclass=_44&&_44.prototype;
+_47.constructor=_4b;
+_4b.prototype=_47;
+_43&&d.setObject(_47.declaredClass=_43,_4b);
+return _4b;
+};
+};
+oo.declare=oo.makeDeclare();
+})();
+}
diff --git a/dojox/lang/oo/general.js b/dojox/lang/oo/general.js
new file mode 100644
index 0000000..99016a3
--- /dev/null
+++ b/dojox/lang/oo/general.js
@@ -0,0 +1,49 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.oo.general"]){
+dojo._hasResource["dojox.lang.oo.general"]=true;
+dojo.provide("dojox.lang.oo.general");
+dojo.require("dojox.lang.oo.Decorator");
+(function(){
+var oo=dojox.lang.oo,md=oo.makeDecorator,_3=oo.general;
+_3.augment=md(function(_4,_5,_6){
+return typeof _6=="undefined"?_5:_6;
+});
+_3.override=md(function(_7,_8,_9){
+return typeof _9!="undefined"?_8:_9;
+});
+_3.shuffle=md(function(_a,_b,_c){
+return dojo.isFunction(_c)?function(){
+return _c.apply(this,_b.apply(this,arguments));
+}:_c;
+});
+_3.wrap=md(function(_d,_e,_f){
+return function(){
+return _e.call(this,_f,arguments);
+};
+});
+_3.tap=md(function(_10,_11,_12){
+return function(){
+_11.apply(this,arguments);
+return this;
+};
+});
+_3.before=md(function(_13,_14,_15){
+return dojo.isFunction(_15)?function(){
+_14.apply(this,arguments);
+return _15.apply(this,arguments);
+}:_14;
+});
+_3.after=md(function(_16,_17,_18){
+return dojo.isFunction(_18)?function(){
+_18.apply(this,arguments);
+return _17.apply(this,arguments);
+}:_17;
+});
+})();
+}
diff --git a/dojox/lang/oo/mixin.js b/dojox/lang/oo/mixin.js
new file mode 100644
index 0000000..a986085
--- /dev/null
+++ b/dojox/lang/oo/mixin.js
@@ -0,0 +1,67 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.oo.mixin"]){
+dojo._hasResource["dojox.lang.oo.mixin"]=true;
+dojo.provide("dojox.lang.oo.mixin");
+dojo.experimental("dojox.lang.oo.mixin");
+dojo.require("dojox.lang.oo.Filter");
+dojo.require("dojox.lang.oo.Decorator");
+(function(){
+var oo=dojox.lang.oo,_2=oo.Filter,_3=oo.Decorator,_4={},_5=function(_6){
+return _6;
+},_7=function(_8,_9,_a){
+return _9;
+},_b=function(_c,_d,_e,_f){
+_c[_d]=_e;
+},_10={},_11=oo.applyDecorator=function(_12,_13,_14,_15){
+if(_14 instanceof _3){
+var d=_14.decorator;
+_14=_11(_12,_13,_14.value,_15);
+return d(_13,_14,_15);
+}
+return _12(_13,_14,_15);
+};
+oo.__mixin=function(_17,_18,_19,_1a,_1b){
+var _1c,_1d,_1e,_1f,_20;
+for(_1c in _18){
+if(!(_1c in _4)){
+_1e=_18[_1c];
+_1d=_1a(_1c,_17,_18,_1e);
+if(_1d){
+_20=_17[_1d];
+_1f=_11(_19,_1d,_1e,_20);
+if(_20!==_1f){
+_1b(_17,_1d,_1f,_20);
+}
+}
+}
+}
+return _17;
+};
+oo.mixin=function(_21,_22){
+var _23,_24,i=1,l=arguments.length;
+for(;i<l;++i){
+_22=arguments[i];
+if(_22 instanceof _2){
+_24=_22.filter;
+_22=_22.bag;
+}else{
+_24=_5;
+}
+if(_22 instanceof _3){
+_23=_22.decorator;
+_22=_22.value;
+}else{
+_23=_7;
+}
+oo.__mixin(_21,_22,_23,_24,_b);
+}
+return _21;
+};
+})();
+}
diff --git a/dojox/lang/oo/rearrange.js b/dojox/lang/oo/rearrange.js
new file mode 100644
index 0000000..9e2f47f
--- /dev/null
+++ b/dojox/lang/oo/rearrange.js
@@ -0,0 +1,25 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.oo.rearrange"]){
+dojo._hasResource["dojox.lang.oo.rearrange"]=true;
+dojo.provide("dojox.lang.oo.rearrange");
+dojox.lang.oo.rearrange=function(_1,_2){
+for(var _3 in _2){
+if(_2.hasOwnProperty(_3)&&_3 in _1){
+var _4=_2[_3],_5=_1[_3];
+if(!(delete _1[_3])){
+_1[_3]=undefined;
+}
+if(_4){
+_1[_4]=_5;
+}
+}
+}
+return _1;
+};
+}
diff --git a/dojox/lang/utils.js b/dojox/lang/utils.js
new file mode 100644
index 0000000..af81f81
--- /dev/null
+++ b/dojox/lang/utils.js
@@ -0,0 +1,59 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.lang.utils"]){
+dojo._hasResource["dojox.lang.utils"]=true;
+dojo.provide("dojox.lang.utils");
+(function(){
+var _1={},du=dojox.lang.utils;
+var _3=function(o){
+if(dojo.isArray(o)){
+return dojo._toArray(o);
+}
+if(!dojo.isObject(o)||dojo.isFunction(o)){
+return o;
+}
+return dojo.delegate(o);
+};
+dojo.mixin(du,{coerceType:function(_5,_6){
+switch(typeof _5){
+case "number":
+return Number(eval("("+_6+")"));
+case "string":
+return String(_6);
+case "boolean":
+return Boolean(eval("("+_6+")"));
+}
+return eval("("+_6+")");
+},updateWithObject:function(_7,_8,_9){
+if(!_8){
+return _7;
+}
+for(var x in _7){
+if(x in _8&&!(x in _1)){
+var t=_7[x];
+if(t&&typeof t=="object"){
+du.updateWithObject(t,_8[x],_9);
+}else{
+_7[x]=_9?du.coerceType(t,_8[x]):_3(_8[x]);
+}
+}
+}
+return _7;
+},updateWithPattern:function(_c,_d,_e,_f){
+if(!_d||!_e){
+return _c;
+}
+for(var x in _e){
+if(x in _d&&!(x in _1)){
+_c[x]=_f?du.coerceType(_e[x],_d[x]):_3(_d[x]);
+}
+}
+return _c;
+}});
+})();
+}
diff --git a/dojox/layout/BorderContainer.js b/dojox/layout/BorderContainer.js
new file mode 100644
index 0000000..d6b67c4
--- /dev/null
+++ b/dojox/layout/BorderContainer.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.layout.BorderContainer"]){
+dojo._hasResource["dojox.layout.BorderContainer"]=true;
+dojo.provide("dojox.layout.BorderContainer");
+console.error("dojox.layout.BorderContainer moved to dijit.layout.BorderContainer");
+}
diff --git a/dojox/layout/ContentPane.js b/dojox/layout/ContentPane.js
new file mode 100644
index 0000000..0c5d5f4
--- /dev/null
+++ b/dojox/layout/ContentPane.js
@@ -0,0 +1,84 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.layout.ContentPane"]){
+dojo._hasResource["dojox.layout.ContentPane"]=true;
+dojo.provide("dojox.layout.ContentPane");
+dojo.require("dijit.layout.ContentPane");
+dojo.require("dojox.html._base");
+(function(){
+dojo.declare("dojox.layout.ContentPane",dijit.layout.ContentPane,{adjustPaths:false,cleanContent:false,renderStyles:false,executeScripts:true,scriptHasHooks:false,constructor:function(){
+this.ioArgs={};
+this.ioMethod=dojo.xhrGet;
+this.onLoadDeferred=new dojo.Deferred();
+this.onUnloadDeferred=new dojo.Deferred();
+},postCreate:function(){
+this._setUpDeferreds();
+dijit.layout.ContentPane.prototype.postCreate.apply(this,arguments);
+},onExecError:function(e){
+},_setContentAttr:function(_2){
+var _3=this._setUpDeferreds();
+this.inherited(arguments);
+return _3;
+},cancel:function(){
+if(this._xhrDfd&&this._xhrDfd.fired==-1){
+this.onUnloadDeferred=null;
+}
+dijit.layout.ContentPane.prototype.cancel.apply(this,arguments);
+},_setUpDeferreds:function(){
+var _t=this,_5=function(){
+_t.cancel();
+};
+var _6=(_t.onLoadDeferred=new dojo.Deferred());
+var _7=(_t._nextUnloadDeferred=new dojo.Deferred());
+return {cancel:_5,addOnLoad:function(_8){
+_6.addCallback(_8);
+},addOnUnload:function(_9){
+_7.addCallback(_9);
+}};
+},_onLoadHandler:function(){
+dijit.layout.ContentPane.prototype._onLoadHandler.apply(this,arguments);
+if(this.onLoadDeferred){
+this.onLoadDeferred.callback(true);
+}
+},_onUnloadHandler:function(){
+this.isLoaded=false;
+this.cancel();
+if(this.onUnloadDeferred){
+this.onUnloadDeferred.callback(true);
+}
+dijit.layout.ContentPane.prototype._onUnloadHandler.apply(this,arguments);
+if(this._nextUnloadDeferred){
+this.onUnloadDeferred=this._nextUnloadDeferred;
+}
+},_onError:function(_a,_b){
+dijit.layout.ContentPane.prototype._onError.apply(this,arguments);
+if(this.onLoadDeferred){
+this.onLoadDeferred.errback(_b);
+}
+},refresh:function(){
+var _c=this._setUpDeferreds();
+this.inherited(arguments);
+return _c;
+},_setContent:function(_d){
+var _e=this._contentSetter;
+if(!(_e&&_e instanceof dojox.html._ContentSetter)){
+_e=this._contentSetter=new dojox.html._ContentSetter({node:this.containerNode,_onError:dojo.hitch(this,this._onError),onContentError:dojo.hitch(this,function(e){
+var _10=this.onContentError(e);
+try{
+this.containerNode.innerHTML=_10;
+}
+catch(e){
+console.error("Fatal "+this.id+" could not change content due to "+e.message,e);
+}
+})});
+}
+this._contentSetterParams={adjustPaths:Boolean(this.adjustPaths&&(this.href||this.referencePath)),referencePath:this.href||this.referencePath,renderStyles:this.renderStyles,executeScripts:this.executeScripts,scriptHasHooks:this.scriptHasHooks,scriptHookReplacement:"dijit.byId('"+this.id+"')"};
+this.inherited("_setContent",arguments);
+}});
+})();
+}
diff --git a/dojox/layout/DragPane.js b/dojox/layout/DragPane.js
new file mode 100644
index 0000000..5687c4c
--- /dev/null
+++ b/dojox/layout/DragPane.js
@@ -0,0 +1,36 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.layout.DragPane"]){
+dojo._hasResource["dojox.layout.DragPane"]=true;
+dojo.provide("dojox.layout.DragPane");
+dojo.require("dijit._Widget");
+dojo.declare("dojox.layout.DragPane",dijit._Widget,{invert:true,postCreate:function(){
+this.inherited(arguments);
+this.connect(this.domNode,"onmousedown","_down");
+this.connect(this.domNode,"onmouseup","_up");
+},_down:function(e){
+var t=this.domNode;
+dojo.style(t,"cursor","move");
+this._x=e.pageX;
+this._y=e.pageY;
+if((this._x<t.offsetLeft+t.clientWidth)&&(this._y<t.offsetTop+t.clientHeight)){
+dojo.setSelectable(t,false);
+this._mover=this.connect(t,"onmousemove","_move");
+}
+},_up:function(e){
+dojo.setSelectable(this.domNode,true);
+dojo.style(this.domNode,"cursor","pointer");
+this.disconnect(this._mover);
+},_move:function(e){
+var _5=this.invert?1:-1;
+this.domNode.scrollTop+=(this._y-e.pageY)*_5;
+this.domNode.scrollLeft+=(this._x-e.pageX)*_5;
+this._x=e.pageX;
+this._y=e.pageY;
+}});
+}
diff --git a/dojox/layout/ExpandoPane.js b/dojox/layout/ExpandoPane.js
new file mode 100644
index 0000000..a60b8fe
--- /dev/null
+++ b/dojox/layout/ExpandoPane.js
@@ -0,0 +1,125 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.layout.ExpandoPane"]){
+dojo._hasResource["dojox.layout.ExpandoPane"]=true;
+dojo.provide("dojox.layout.ExpandoPane");
+dojo.experimental("dojox.layout.ExpandoPane");
+dojo.require("dijit.layout.ContentPane");
+dojo.require("dijit._Templated");
+dojo.require("dijit._Container");
+dojo.declare("dojox.layout.ExpandoPane",[dijit.layout.ContentPane,dijit._Templated,dijit._Contained],{maxHeight:"",maxWidth:"",splitter:"",templateString:"<div class=\"dojoxExpandoPane\" dojoAttachEvent=\"ondblclick:toggle\" >\n\t<div dojoAttachPoint=\"titleWrapper\" class=\"dojoxExpandoTitle\">\n\t\t<div class=\"dojoxExpandoIcon\" dojoAttachPoint=\"iconNode\" dojoAttachEvent=\"onclick:toggle\"><span class=\"a11yNode\">X</span></div>\t\t\t\n\t\t<span class=\"dojoxExpandoTitleNode\" dojoA [...]
+this.inherited(arguments);
+this._animConnects=[];
+this._isHorizontal=true;
+if(dojo.isString(this.easeOut)){
+this.easeOut=dojo.getObject(this.easeOut);
+}
+if(dojo.isString(this.easeIn)){
+this.easeIn=dojo.getObject(this.easeIn);
+}
+var _1="",_2=!this.isLeftToRight();
+if(this.region){
+switch(this.region){
+case "trailing":
+case "right":
+_1=_2?"Left":"Right";
+break;
+case "leading":
+case "left":
+_1=_2?"Right":"Left";
+break;
+case "top":
+_1="Top";
+break;
+case "bottom":
+_1="Bottom";
+break;
+}
+dojo.addClass(this.domNode,"dojoxExpando"+_1);
+this._isHorizontal=/top|bottom/.test(this.region);
+}
+dojo.style(this.domNode,{overflow:"hidden",padding:0});
+},_startupSizes:function(){
+this._container=this.getParent();
+this._closedSize=this._titleHeight=dojo.marginBox(this.titleWrapper).h;
+if(this.splitter){
+var _3=this.id;
+dijit.registry.filter(function(w){
+return w&&w.child&&w.child.id==_3;
+}).forEach(dojo.hitch(this,function(w){
+this.connect(w,"_stopDrag","_afterResize");
+}));
+}
+this._currentSize=dojo.contentBox(this.domNode);
+this._showSize=this._currentSize[(this._isHorizontal?"h":"w")];
+this._setupAnims();
+if(this.startExpanded){
+this._showing=true;
+}else{
+this._showing=false;
+this._hideWrapper();
+this._hideAnim.gotoPercent(99,true);
+}
+this._hasSizes=true;
+},_afterResize:function(e){
+var _7=this._currentSize;
+this._currentSize=dojo.marginBox(this.domNode);
+var n=this._currentSize[(this._isHorizontal?"h":"w")];
+if(n>this._titleHeight){
+if(!this._showing){
+this._showing=!this._showing;
+this._showEnd();
+}
+this._showSize=n;
+this._setupAnims();
+}else{
+this._showSize=_7[(this._isHorizontal?"h":"w")];
+this._showing=false;
+this._hideWrapper();
+this._hideAnim.gotoPercent(89,true);
+}
+},_setupAnims:function(){
+dojo.forEach(this._animConnects,dojo.disconnect);
+var _9={node:this.domNode,duration:this.duration},_a=this._isHorizontal,_b={},_c={},_d=_a?"height":"width";
+_b[_d]={end:this._showSize,unit:"px"};
+_c[_d]={end:this._closedSize,unit:"px"};
+this._showAnim=dojo.animateProperty(dojo.mixin(_9,{easing:this.easeIn,properties:_b}));
+this._hideAnim=dojo.animateProperty(dojo.mixin(_9,{easing:this.easeOut,properties:_c}));
+this._animConnects=[dojo.connect(this._showAnim,"onEnd",this,"_showEnd"),dojo.connect(this._hideAnim,"onEnd",this,"_hideEnd")];
+},toggle:function(){
+if(this._showing){
+this._hideWrapper();
+this._showAnim&&this._showAnim.stop();
+this._hideAnim.play();
+}else{
+this._hideAnim&&this._hideAnim.stop();
+this._showAnim.play();
+}
+this._showing=!this._showing;
+},_hideWrapper:function(){
+dojo.addClass(this.domNode,"dojoxExpandoClosed");
+dojo.style(this.cwrapper,{visibility:"hidden",opacity:"0",overflow:"hidden"});
+},_showEnd:function(){
+dojo.style(this.cwrapper,{opacity:0,visibility:"visible"});
+dojo.fadeIn({node:this.cwrapper,duration:227}).play(1);
+dojo.removeClass(this.domNode,"dojoxExpandoClosed");
+setTimeout(dojo.hitch(this._container,"layout"),15);
+},_hideEnd:function(){
+setTimeout(dojo.hitch(this._container,"layout"),15);
+},resize:function(_e){
+if(!this._hasSizes){
+this._startupSizes(_e);
+}
+var _f=(_e&&_e.h)?_e:dojo.marginBox(this.domNode);
+this._contentBox={w:_f.w||dojo.marginBox(this.domNode).w,h:_f.h-this._titleHeight};
+dojo.style(this.containerNode,"height",this._contentBox.h+"px");
+this._layoutChildren();
+},_trap:function(e){
+dojo.stopEvent(e);
+}});
+}
diff --git a/dojox/layout/FloatingPane.js b/dojox/layout/FloatingPane.js
new file mode 100644
index 0000000..b915068
--- /dev/null
+++ b/dojox/layout/FloatingPane.js
@@ -0,0 +1,222 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.layout.FloatingPane"]){
+dojo._hasResource["dojox.layout.FloatingPane"]=true;
+dojo.provide("dojox.layout.FloatingPane");
+dojo.experimental("dojox.layout.FloatingPane");
+dojo.require("dojox.layout.ContentPane");
+dojo.require("dijit._Templated");
+dojo.require("dijit._Widget");
+dojo.require("dojo.dnd.Moveable");
+dojo.require("dojox.layout.ResizeHandle");
+dojo.declare("dojox.layout.FloatingPane",[dojox.layout.ContentPane,dijit._Templated],{closable:true,dockable:true,resizable:false,maxable:false,resizeAxis:"xy",title:"",dockTo:"",duration:400,contentClass:"dojoxFloatingPaneContent",_showAnim:null,_hideAnim:null,_dockNode:null,_restoreState:{},_allFPs:[],_startZ:100,templateString:null,templateString:"<div class=\"dojoxFloatingPane\" id=\"${id}\">\n\t<div tabindex=\"0\" waiRole=\"button\" class=\"dojoxFloatingPaneTitle\" dojoAttachPoint=\ [...]
+this.setTitle(this.title);
+this.inherited(arguments);
+var _1=new dojo.dnd.Moveable(this.domNode,{handle:this.focusNode});
+if(!this.dockable){
+this.dockNode.style.display="none";
+}
+if(!this.closable){
+this.closeNode.style.display="none";
+}
+if(!this.maxable){
+this.maxNode.style.display="none";
+this.restoreNode.style.display="none";
+}
+if(!this.resizable){
+this.resizeHandle.style.display="none";
+}else{
+var _2=dojo.marginBox(this.domNode);
+this.domNode.style.width=_2.w+"px";
+}
+this._allFPs.push(this);
+this.domNode.style.position="absolute";
+this.bgIframe=new dijit.BackgroundIframe(this.domNode);
+},startup:function(){
+if(this._started){
+return;
+}
+this.inherited(arguments);
+if(this.resizable){
+if(dojo.isIE){
+this.canvas.style.overflow="auto";
+}else{
+this.containerNode.style.overflow="auto";
+}
+this._resizeHandle=new dojox.layout.ResizeHandle({targetId:this.id,resizeAxis:this.resizeAxis},this.resizeHandle);
+}
+if(this.dockable){
+var _3=this.dockTo;
+if(this.dockTo){
+this.dockTo=dijit.byId(this.dockTo);
+}else{
+this.dockTo=dijit.byId("dojoxGlobalFloatingDock");
+}
+if(!this.dockTo){
+var _4;
+var _5;
+if(_3){
+_4=_3;
+_5=dojo.byId(_3);
+}else{
+_5=document.createElement("div");
+dojo.body().appendChild(_5);
+dojo.addClass(_5,"dojoxFloatingDockDefault");
+_4="dojoxGlobalFloatingDock";
+}
+this.dockTo=new dojox.layout.Dock({id:_4,autoPosition:"south"},_5);
+this.dockTo.startup();
+}
+if((this.domNode.style.display=="none")||(this.domNode.style.visibility=="hidden")){
+this.minimize();
+}
+}
+this.connect(this.focusNode,"onmousedown","bringToTop");
+this.connect(this.domNode,"onmousedown","bringToTop");
+this.resize(dojo.coords(this.domNode));
+this._started=true;
+},setTitle:function(_6){
+this.titleNode.innerHTML=_6;
+this.title=_6;
+},close:function(){
+if(!this.closable){
+return;
+}
+dojo.unsubscribe(this._listener);
+this.hide(dojo.hitch(this,function(){
+this.destroyRecursive();
+}));
+},hide:function(_7){
+dojo.fadeOut({node:this.domNode,duration:this.duration,onEnd:dojo.hitch(this,function(){
+this.domNode.style.display="none";
+this.domNode.style.visibility="hidden";
+if(this.dockTo&&this.dockable){
+this.dockTo._positionDock(null);
+}
+if(_7){
+_7();
+}
+})}).play();
+},show:function(_8){
+var _9=dojo.fadeIn({node:this.domNode,duration:this.duration,beforeBegin:dojo.hitch(this,function(){
+this.domNode.style.display="";
+this.domNode.style.visibility="visible";
+if(this.dockTo&&this.dockable){
+this.dockTo._positionDock(null);
+}
+if(typeof _8=="function"){
+_8();
+}
+this._isDocked=false;
+if(this._dockNode){
+this._dockNode.destroy();
+this._dockNode=null;
+}
+})}).play();
+this.resize(dojo.coords(this.domNode));
+},minimize:function(){
+if(!this._isDocked){
+this.hide(dojo.hitch(this,"_dock"));
+}
+},maximize:function(){
+if(this._maximized){
+return;
+}
+this._naturalState=dojo.coords(this.domNode);
+if(this._isDocked){
+this.show();
+setTimeout(dojo.hitch(this,"maximize"),this.duration);
+}
+dojo.addClass(this.focusNode,"floatingPaneMaximized");
+this.resize(dijit.getViewport());
+this._maximized=true;
+},_restore:function(){
+if(this._maximized){
+this.resize(this._naturalState);
+dojo.removeClass(this.focusNode,"floatingPaneMaximized");
+this._maximized=false;
+}
+},_dock:function(){
+if(!this._isDocked&&this.dockable){
+this._dockNode=this.dockTo.addNode(this);
+this._isDocked=true;
+}
+},resize:function(_a){
+this._currentState=_a;
+var _b=this.domNode.style;
+if(_a.t){
+_b.top=_a.t+"px";
+}
+if(_a.l){
+_b.left=_a.l+"px";
+}
+_b.width=_a.w+"px";
+_b.height=_a.h+"px";
+var _c={l:0,t:0,w:_a.w,h:(_a.h-this.focusNode.offsetHeight)};
+dojo.marginBox(this.canvas,_c);
+this._checkIfSingleChild();
+if(this._singleChild&&this._singleChild.resize){
+this._singleChild.resize(_c);
+}
+},bringToTop:function(){
+var _d=dojo.filter(this._allFPs,function(i){
+return i!==this;
+},this);
+_d.sort(function(a,b){
+return a.domNode.style.zIndex-b.domNode.style.zIndex;
+});
+_d.push(this);
+dojo.forEach(_d,function(w,x){
+w.domNode.style.zIndex=this._startZ+(x*2);
+dojo.removeClass(w.domNode,"dojoxFloatingPaneFg");
+},this);
+dojo.addClass(this.domNode,"dojoxFloatingPaneFg");
+},destroy:function(){
+this._allFPs.splice(dojo.indexOf(this._allFPs,this),1);
+if(this._resizeHandle){
+this._resizeHandle.destroy();
+}
+this.inherited(arguments);
+}});
+dojo.declare("dojox.layout.Dock",[dijit._Widget,dijit._Templated],{templateString:"<div class=\"dojoxDock\"><ul dojoAttachPoint=\"containerNode\" class=\"dojoxDockList\"></ul></div>",_docked:[],_inPositioning:false,autoPosition:false,addNode:function(_13){
+var div=document.createElement("li");
+this.containerNode.appendChild(div);
+var _15=new dojox.layout._DockNode({title:_13.title,paneRef:_13},div);
+_15.startup();
+return _15;
+},startup:function(){
+if(this.id=="dojoxGlobalFloatingDock"||this.isFixedDock){
+dojo.connect(window,"onresize",this,"_positionDock");
+dojo.connect(window,"onscroll",this,"_positionDock");
+if(dojo.isIE){
+this.connect(this.domNode,"onresize","_positionDock");
+}
+}
+this._positionDock(null);
+this.inherited(arguments);
+},_positionDock:function(e){
+if(!this._inPositioning){
+if(this.autoPosition=="south"){
+setTimeout(dojo.hitch(this,function(){
+this._inPositiononing=true;
+var _17=dijit.getViewport();
+var s=this.domNode.style;
+s.left=_17.l+"px";
+s.width=(_17.w-2)+"px";
+s.top=(_17.h+_17.t)-this.domNode.offsetHeight+"px";
+this._inPositioning=false;
+}),125);
+}
+}
+}});
+dojo.declare("dojox.layout._DockNode",[dijit._Widget,dijit._Templated],{title:"",paneRef:null,templateString:"<li dojoAttachEvent=\"onclick: restore\" class=\"dojoxDockNode\">"+"<span dojoAttachPoint=\"restoreNode\" class=\"dojoxDockRestoreButton\" dojoAttachEvent=\"onclick: restore\"></span>"+"<span class=\"dojoxDockTitleNode\" dojoAttachPoint=\"titleNode\">${title}</span>"+"</li>",restore:function(){
+this.paneRef.show();
+this.paneRef.bringToTop();
+this.destroy();
+}});
+}
diff --git a/dojox/layout/GridContainer.js b/dojox/layout/GridContainer.js
new file mode 100644
index 0000000..13d62dc
--- /dev/null
+++ b/dojox/layout/GridContainer.js
@@ -0,0 +1,829 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.layout.GridContainer"]){
+dojo._hasResource["dojox.layout.GridContainer"]=true;
+dojo.provide("dojox.layout.GridContainer");
+dojo.experimental("dojox.layout.GridContainer");
+dojo.require("dijit._base.focus");
+dojo.require("dijit._Templated");
+dojo.require("dijit._Container");
+dojo.require("dijit._Contained");
+dojo.require("dojo.dnd.move");
+dojo.require("dojox.layout.dnd.PlottedDnd");
+dojo.requireLocalization("dojox.layout","GridContainer",null,"ROOT,en,fr");
+dojo.declare("dojox.layout.GridContainer",[dijit._Widget,dijit._Templated,dijit._Container,dijit._Contained],{templateString:"<div id=\"${id}\" class=\"gridContainer\" dojoAttachPoint=\"containerNode\" tabIndex=\"0\" dojoAttachEvent=\"onkeypress:_selectFocus\">\n\t<table class=\"gridContainerTable\" dojoAttachPoint=\"gridContainerTable\" cellspacing=\"0\" cellpadding=\"0\">\n\t\t<tbody class=\"gridContainerBody\">\n\t\t\t<tr class=\"gridContainerRow\" dojoAttachPoint=\"gridNode\"></tr>\n [...]
+this.acceptTypes=_1["acceptTypes"]||["dijit.layout.ContentPane"];
+this.dragOffset=_1["dragOffset"]||{x:0,y:0};
+},postMixInProperties:function(){
+this.i18n=dojo.i18n.getLocalization("dojox.layout","GridContainer");
+},_createCells:function(){
+if(this.nbZones===0){
+this.nbZones=1;
+}
+var _3=100/this.nbZones;
+if(dojo.isIE&&dojo.marginBox(this.gridNode).height){
+var _4=document.createTextNode(" ");
+this.gridNode.appendChild(_4);
+}
+var _5=[];
+this.cell=[];
+var i=0;
+while(i<this.nbZones){
+var _7=dojo.doc.createElement("td");
+dojo.addClass(_7,"gridContainerZone");
+_7.id=this.id+"_dz"+i;
+_7.style.width=_3+"%";
+var _8=this.gridNode.appendChild(_7);
+this.cell[i]=_8;
+i++;
+}
+},startup:function(){
+this.inherited(arguments);
+this._createCells();
+if(this.usepref!==true){
+this[(this.isAutoOrganized?"_organizeServices":"_organizeServicesManually")]();
+}else{
+return;
+}
+this.init();
+dojo.forEach(this.getChildren(),function(_9){
+!_9.started&&!_9._started&&_9.startup();
+});
+},init:function(){
+this.grid=this._createGrid();
+this.connect(dojo.global,"onresize","onResized");
+this.connect(this,"onDndDrop","_placeGrips");
+this.dropHandler=dojo.subscribe("/dnd/drop",this,"_placeGrips");
+this._oldwidth=this.domNode.offsetWidth;
+if(this.hasResizableColumns){
+this._initPlaceGrips();
+this._placeGrips();
+}
+},destroy:function(){
+for(var i=0;i<this.handleDndStart;i++){
+dojo.disconnect(this.handleDndStart[i]);
+}
+dojo.unsubscribe(this.dropHandler);
+this.inherited(arguments);
+},onResized:function(){
+if(this.hasResizableColumns){
+this._placeGrips();
+this._oldwidth=this.domNode.offsetWidth;
+this._oldheight=this.domNode.offsetHeight;
+}
+},_organizeServices:function(){
+var _b=this.nbZones;
+var _c=this.getChildren().length;
+var _d=Math.floor(_c/_b);
+var _e=_c%_b;
+var i=0;
+for(var z=0;z<_b;z++){
+for(var r=0;r<_d;r++){
+this._insertService(z,i++,0,true);
+}
+if(_e>0){
+try{
+this._insertService(z,i++,0,true);
+}
+catch(e){
+console.error("Unable to insert service in grid container",e,this.getChildren());
+}
+_e--;
+}else{
+if(_d===0){
+break;
+}
+}
+}
+},_organizeServicesManually:function(){
+var _12=this.getChildren();
+for(var i=0;i<_12.length;i++){
+try{
+this._insertService(_12[i].column-1,i,0,true);
+}
+catch(e){
+console.error("Unable to insert service in grid container",e,_12[i]);
+}
+}
+},_insertService:function(z,p,i,_17){
+var _18=this.cell[z];
+var _19=_18.childNodes.length;
+var _1a=this.getChildren()[(i?i:0)];
+if(typeof (p)=="undefined"||p>_19){
+p=_19;
+}
+var _1b=dojo.place(_1a.domNode,_18,p);
+_1a.domNode.setAttribute("tabIndex",0);
+if(!_1a.dragRestriction){
+dojo.addClass(_1a.domNode,"dojoDndItem");
+}
+if(!_1a.domNode.getAttribute("dndType")){
+_1a.domNode.setAttribute("dndType",_1a.declaredClass);
+}
+dojox.layout.dnd._setGcDndHandle(_1a,this.withHandles,this.handleClasses,_17);
+if(this.hasResizableColumns){
+if(_1a.onLoad){
+this.connect(_1a,"onLoad","_placeGrips");
+}
+if(_1a.onExecError){
+this.connect(_1a,"onExecError","_placeGrips");
+}
+if(_1a.onUnLoad){
+this.connect(_1a,"onUnLoad","_placeGrips");
+}
+}
+this._placeGrips();
+return _1a.id;
+},addService:function(_1c,z,p){
+_1c.domNode.id=_1c.id;
+this.addChild(_1c);
+if(p<=0){
+p=0;
+}
+var _1f=this._insertService(z,p);
+this.grid[z].setItem(_1c.id,{data:_1c.domNode,type:[_1c.domNode.getAttribute("dndType")]});
+return _1f;
+},_createGrid:function(){
+var _20=[];
+var i=0;
+this.tabDZ=[];
+while(i<this.nbZones){
+var _22=this.cell[i];
+this.tabDZ[i]=this._createZone(_22);
+if(this.hasResizableColumns&&i!=(this.nbZones-1)){
+this._createGrip(this.tabDZ[i]);
+}
+_20.push(this.tabDZ[i]);
+i++;
+}
+if(this.hasResizableColumns){
+this.handleDndStart=[];
+for(var j=0;j<this.tabDZ.length;j++){
+var dz=this.tabDZ[j];
+var _25=this;
+this.handleDndStart.push(dojo.connect(dz,"onDndStart",dz,function(_26){
+if(_26==this){
+_25.handleDndInsertNodes=[];
+for(i=0;i<_25.tabDZ.length;i++){
+_25.handleDndInsertNodes.push(dojo.connect(_25.tabDZ[i],"insertNodes",_25,function(){
+_25._disconnectDnd();
+}));
+}
+_25.handleDndInsertNodes.push(dojo.connect(dz,"onDndCancel",_25,_25._disconnectDnd));
+_25.onResized();
+}
+}));
+}
+}
+return _20;
+},_disconnectDnd:function(){
+dojo.forEach(this.handleDndInsertNodes,dojo.disconnect);
+setTimeout(dojo.hitch(this,"onResized"),0);
+},_createZone:function(_27){
+var dz=null;
+dz=new dojox.layout.dnd.PlottedDnd(_27.id,{accept:this.acceptTypes,withHandles:this.withHandles,handleClasses:this.handleClasses,singular:true,hideSource:true,opacity:this.opacity,dom:this.domNode,allowAutoScroll:this.allowAutoScroll,isOffset:this.isOffset,offsetDrag:this.offsetDrag});
+this.connect(dz,"insertDashedZone","_placeGrips");
+this.connect(dz,"deleteDashedZone","_placeGrips");
+return dz;
+},_createGrip:function(dz){
+var _2a=document.createElement("div");
+_2a.className="gridContainerGrip";
+_2a.setAttribute("tabIndex","0");
+var _2b=this;
+this.onMouseOver=this.connect(_2a,"onmouseover",function(e){
+var _2d=false;
+for(var i=0;i<_2b.grid.length-1;i++){
+if(dojo.hasClass(_2b.grid[i].grip,"gridContainerGripShow")){
+_2d=true;
+break;
+}
+}
+if(!_2d){
+dojo.removeClass(e.target,"gridContainerGrip");
+dojo.addClass(e.target,"gridContainerGripShow");
+}
+});
+this.connect(_2a,"onmouseout",function(e){
+if(!_2b._isResized){
+dojo.removeClass(e.target,"gridContainerGripShow");
+dojo.addClass(e.target,"gridContainerGrip");
+}
+});
+this.connect(_2a,"onmousedown",function(e){
+_2b._a11yOn=false;
+_2b._activeGrip=e.target;
+_2b.resizeColumnOn(e);
+});
+this.domNode.appendChild(_2a);
+dz.grip=_2a;
+},_initPlaceGrips:function(){
+var dcs=dojo.getComputedStyle(this.domNode);
+var gcs=dojo.getComputedStyle(this.gridContainerTable);
+this._x=parseInt(dcs.paddingLeft);
+this._topGrip=parseInt(dcs.paddingTop);
+if(dojo.isIE||gcs.borderCollapse!="collapse"){
+var ex=dojo._getBorderExtents(this.gridContainerTable);
+this._x+=ex.l;
+this._topGrip+=ex.t;
+}
+this._topGrip+="px";
+dojo.forEach(this.grid,function(_34){
+if(_34.grip){
+var _35=_34.grip;
+if(!dojo.isIE){
+_34.pad=dojo._getPadBorderExtents(_34.node).w;
+}
+_35.style.top=this._topGrip;
+}
+},this);
+},_placeGrips:function(){
+var _36;
+if(this.allowAutoScroll){
+_36=this.gridNode.scrollHeight;
+}else{
+_36=dojo.contentBox(this.gridNode).h;
+}
+var _37=this._x;
+dojo.forEach(this.grid,function(_38){
+if(_38.grip){
+var _39=_38.grip;
+_37+=dojo[(dojo.isIE?"marginBox":"contentBox")](_38.node).w+(dojo.isIE?0:_38.pad);
+dojo.style(_39,{left:_37+"px",height:_36+"px"});
+}
+},this);
+},_getZoneByIndex:function(n){
+return this.grid[(n>=0&&n<this.grid.length?n:0)];
+},getIndexZone:function(_3b){
+for(var z=0;z<this.grid.length;z++){
+if(this.grid[z].domNode==_3b){
+return z;
+}
+}
+return -1;
+},resizeColumnOn:function(e){
+var k=dojo.keys;
+if(this._a11yOn&&e.keyCode!=k.LEFT_ARROW&&e.keyCode!=k.RIGHT_ARROW){
+return;
+}
+e.preventDefault();
+dojo.body().style.cursor="ew-resize";
+this._isResized=true;
+this.initX=e.pageX;
+var _3f=[];
+for(var i=0;i<this.grid.length;i++){
+_3f[i]=dojo.contentBox(this.grid[i].node).w;
+}
+this.oldTabSize=_3f;
+for(var i=0;i<this.grid.length;i++){
+if(this._activeGrip==this.grid[i].grip){
+this.currentColumn=this.grid[i].node;
+this.currentColumnWidth=_3f[i];
+this.nextColumn=this.currentColumn.nextSibling;
+this.nextColumnWidth=_3f[i+1];
+}
+this.grid[i].node.style.width=_3f[i]+"px";
+}
+var _41=function(_42,_43){
+var _44=0;
+var _45=0;
+dojo.forEach(_42,function(_46){
+if(_46.nodeType==1){
+var _47=dojo.getComputedStyle(_46);
+var _48=(dojo.isIE?_43:parseInt(_47.minWidth));
+_45=_48+parseInt(_47.marginLeft)+parseInt(_47.marginRight);
+if(_44<_45){
+_44=_45;
+}
+}
+});
+return _44;
+};
+var _49=_41(this.currentColumn.childNodes,this.minChildWidth);
+var _4a=_41(this.nextColumn.childNodes,this.minChildWidth);
+var _4b=Math.round((dojo.marginBox(this.gridContainerTable).w*this.minColWidth)/100);
+this.currentMinCol=_49;
+this.nextMinCol=_4a;
+if(_4b>this.currentMinCol){
+this.currentMinCol=_4b;
+}
+if(_4b>this.nextMinCol){
+this.nextMinCol=_4b;
+}
+if(this._a11yOn){
+this.connectResizeColumnMove=this.connect(dojo.doc,"onkeypress","resizeColumnMove");
+}else{
+this.connectResizeColumnMove=this.connect(dojo.doc,"onmousemove","resizeColumnMove");
+this.connectResizeColumnOff=this.connect(document,"onmouseup","resizeColumnOff");
+}
+},resizeColumnMove:function(e){
+var d=0;
+if(this._a11yOn){
+var k=dojo.keys;
+switch(e.keyCode){
+case k.LEFT_ARROW:
+d=-10;
+break;
+case k.RIGHT_ARROW:
+d=10;
+break;
+}
+}else{
+e.preventDefault();
+d=e.pageX-this.initX;
+}
+if(d==0){
+return;
+}
+if(!(this.currentColumnWidth+d<this.currentMinCol||this.nextColumnWidth-d<this.nextMinCol)){
+this.currentColumnWidth+=d;
+this.nextColumnWidth-=d;
+this.initX=e.pageX;
+this.currentColumn.style["width"]=this.currentColumnWidth+"px";
+this.nextColumn.style["width"]=this.nextColumnWidth+"px";
+this._activeGrip.style.left=parseInt(this._activeGrip.style.left)+d+"px";
+this._placeGrips();
+}
+if(this._a11yOn){
+this.resizeColumnOff(e);
+}
+},resizeColumnOff:function(e){
+dojo.body().style.cursor="default";
+if(this._a11yOn){
+this.disconnect(this.connectResizeColumnMove);
+this._a11yOn=false;
+}else{
+this.disconnect(this.connectResizeColumnMove);
+this.disconnect(this.connectResizeColumnOff);
+}
+var _50=[];
+var _51=[];
+var _52=this.gridContainerTable.clientWidth;
+for(var i=0;i<this.grid.length;i++){
+var _cb=dojo.contentBox(this.grid[i].node);
+if(dojo.isIE){
+_50[i]=dojo.marginBox(this.grid[i].node).w;
+_51[i]=_cb.w;
+}else{
+_50[i]=_cb.w;
+_51=_50;
+}
+}
+var _55=false;
+for(var i=0;i<_51.length;i++){
+if(_51[i]!=this.oldTabSize[i]){
+_55=true;
+break;
+}
+}
+if(_55){
+var mul=dojo.isIE?100:10000;
+for(var i=0;i<this.grid.length;i++){
+this.grid[i].node.style.width=Math.round((100*mul*_50[i])/_52)/mul+"%";
+}
+this._placeGrips();
+}
+if(this._activeGrip){
+dojo.removeClass(this._activeGrip,"gridContainerGripShow");
+dojo.addClass(this._activeGrip,"gridContainerGrip");
+}
+this._isResized=false;
+},setColumns:function(_57){
+if(_57>0){
+var _58=this.grid.length-_57;
+if(_58>0){
+var _59=[];
+var _5a,_5b,end;
+if(this.mode=="right"){
+end=(this.isLeftFixed&&this.grid.length>0)?1:0;
+_5b=this.grid.length-(this.isRightFixed?2:1);
+for(var z=_5b;z>=end;z--){
+var _5e=0;
+var _5a=this.grid[z].node;
+for(var j=0;j<_5a.childNodes.length;j++){
+if(_5a.childNodes[j].nodeType==1&&!(_5a.childNodes[j].id=="")){
+_5e++;
+break;
+}
+}
+if(_5e==0){
+_59[_59.length]=z;
+}
+if(_59.length>=_58){
+this._deleteColumn(_59);
+break;
+}
+}
+if(_59.length<_58){
+console.error(this.i18n.err_onSetNbColsRightMode);
+}
+}else{
+if(this.isLeftFixed&&this.grid.length>0){
+_5b=1;
+}else{
+_5b=0;
+}
+if(this.isRightFixed){
+end=this.grid.length-1;
+}else{
+end=this.grid.length;
+}
+for(var z=_5b;z<end;z++){
+var _5e=0;
+var _5a=this.grid[z].node;
+for(var j=0;j<_5a.childNodes.length;j++){
+if(_5a.childNodes[j].nodeType==1&&!(_5a.childNodes[j].id=="")){
+_5e++;
+break;
+}
+}
+if(_5e==0){
+_59[_59.length]=z;
+}
+if(_59.length>=_58){
+this._deleteColumn(_59);
+break;
+}
+}
+if(_59.length<_58){
+alert(this.i18n.err_onSetNbColsLeftMode);
+}
+}
+}else{
+if(_58<0){
+this._addColumn(Math.abs(_58));
+}
+}
+this._initPlaceGrips();
+this._placeGrips();
+}
+},_addColumn:function(_60){
+var _61;
+if(this.hasResizableColumns&&!this.isRightFixed&&this.mode=="right"){
+_61=this.grid[this.grid.length-1];
+this._createGrip(_61);
+}
+for(var i=0;i<_60;i++){
+_61=dojo.doc.createElement("td");
+dojo.addClass(_61,"gridContainerZone");
+_61.id=this.id+"_dz"+this.nbZones;
+var dz;
+if(this.mode=="right"){
+if(this.isRightFixed){
+this.grid[this.grid.length-1].node.parentNode.insertBefore(_61,this.grid[this.grid.length-1].node);
+dz=this._createZone(_61);
+this.tabDZ.splice(this.tabDZ.length-1,0,dz);
+this.grid.splice(this.grid.length-1,0,dz);
+this.cell.splice(this.cell.length-1,0,_61);
+}else{
+var _64=this.gridNode.appendChild(_61);
+dz=this._createZone(_61);
+this.tabDZ.push(dz);
+this.grid.push(dz);
+this.cell.push(_61);
+}
+}else{
+if(this.isLeftFixed){
+(this.grid.length==1)?this.grid[0].node.parentNode.appendChild(_61,this.grid[0].node):this.grid[1].node.parentNode.insertBefore(_61,this.grid[1].node);
+dz=this._createZone(_61);
+this.tabDZ.splice(1,0,dz);
+this.grid.splice(1,0,dz);
+this.cell.splice(1,0,_61);
+}else{
+this.grid[this.grid.length-this.nbZones].node.parentNode.insertBefore(_61,this.grid[this.grid.length-this.nbZones].node);
+dz=this._createZone(_61);
+this.tabDZ.splice(this.tabDZ.length-this.nbZones,0,dz);
+this.grid.splice(this.grid.length-this.nbZones,0,dz);
+this.cell.splice(this.cell.length-this.nbZones,0,_61);
+}
+}
+if(this.hasResizableColumns){
+var _65=this;
+var _66=dojo.connect(dz,"onDndStart",dz,function(_67){
+if(_67==this){
+_65.handleDndInsertNodes=[];
+for(var o=0;o<_65.tabDZ.length;o++){
+_65.handleDndInsertNodes.push(dojo.connect(_65.tabDZ[o],"insertNodes",_65,function(){
+_65._disconnectDnd();
+}));
+}
+_65.handleDndInsertNodes.push(dojo.connect(dz,"onDndCancel",_65,_65._disconnectDnd));
+_65.onResized();
+}
+});
+if(this.mode=="right"){
+if(this.isRightFixed){
+this.handleDndStart.splice(this.handleDndStart.length-1,0,_66);
+}else{
+this.handleDndStart.push(_66);
+}
+}else{
+if(this.isLeftFixed){
+this.handleDndStart.splice(1,0,_66);
+}else{
+this.handleDndStart.splice(this.handleDndStart.length-this.nbZones,0,_66);
+}
+}
+this._createGrip(dz);
+}
+this.nbZones++;
+}
+this._updateColumnsWidth();
+},_deleteColumn:function(_69){
+var _6a,_6b,_6c;
+_6c=0;
+for(var i=0;i<_69.length;i++){
+var idx=_69[i];
+if(this.mode=="right"){
+_6a=this.grid[idx];
+}else{
+_6a=this.grid[idx-_6c];
+}
+for(var j=0;j<_6a.node.childNodes.length;j++){
+if(_6a.node.childNodes[j].nodeType!=1){
+continue;
+}
+_6b=dijit.byId(_6a.node.childNodes[j].id);
+for(var x=0;x<this.getChildren().length;x++){
+if(this.getChildren()[x]===_6b){
+this.getChildren().splice(x,1);
+break;
+}
+}
+}
+_6a.node.parentNode.removeChild(_6a.node);
+if(this.mode=="right"){
+if(this.hasResizableColumns){
+dojo.disconnect(this.handleDndStart[idx]);
+}
+this.grid.splice(idx,1);
+this.tabDZ.splice(idx,1);
+this.cell.splice(idx,1);
+}else{
+if(this.hasResizableColumns){
+dojo.disconnect(this.handleDndStart[idx-_6c]);
+}
+this.grid.splice(idx-_6c,1);
+this.tabDZ.splice(idx-_6c,1);
+this.cell.splice(idx-_6c,1);
+}
+this.nbZones--;
+_6c++;
+if(_6a.grip){
+this.domNode.removeChild(_6a.grip);
+}
+}
+this._updateColumnsWidth();
+},_updateColumnsWidth:function(){
+var _71=100/this.nbZones;
+var _72;
+for(var z=0;z<this.grid.length;z++){
+_72=this.grid[z].node;
+_72.style.width=_71+"%";
+}
+},_selectFocus:function(_74){
+var e=_74.keyCode;
+var _76=null;
+var _77=dijit.getFocus();
+var _78=_77.node;
+var k=dojo.keys;
+var _7a=(e==k.UP_ARROW||e==k.LEFT_ARROW)?"lastChild":"firstChild";
+var pos=(e==k.UP_ARROW||e==k.LEFT_ARROW)?"previousSibling":"nextSibling";
+if(_78==this.containerNode){
+switch(e){
+case k.DOWN_ARROW:
+case k.RIGHT_ARROW:
+for(var i=0;i<this.gridNode.childNodes.length;i++){
+_76=this.gridNode.childNodes[i].firstChild;
+var _7d=false;
+while(!_7d){
+if(_76!=null){
+if(_76.style.display!=="none"){
+dijit.focus(_76);
+dojo.stopEvent(_74);
+_7d=true;
+}else{
+_76=_76[pos];
+}
+}else{
+break;
+}
+}
+if(_7d){
+break;
+}
+}
+break;
+case k.UP_ARROW:
+case k.LEFT_ARROW:
+for(var i=this.gridNode.childNodes.length-1;i>=0;i--){
+_76=this.gridNode.childNodes[i].lastChild;
+var _7d=false;
+while(!_7d){
+if(_76!=null){
+if(_76.style.display!=="none"){
+dijit.focus(_76);
+dojo.stopEvent(_74);
+_7d=true;
+}else{
+_76=_76[pos];
+}
+}else{
+break;
+}
+}
+if(_7d){
+break;
+}
+}
+break;
+}
+}else{
+if(_78.parentNode.parentNode==this.gridNode){
+switch(e){
+case k.UP_ARROW:
+case k.DOWN_ARROW:
+dojo.stopEvent(_74);
+var _7e=0;
+dojo.forEach(_78.parentNode.childNodes,function(_7f){
+if(_7f.style.display!=="none"){
+_7e++;
+}
+});
+if(_7e==1){
+return;
+}
+var _7d=false;
+_76=_78[pos];
+while(!_7d){
+if(_76==null){
+_76=_78.parentNode[_7a];
+if(_76.style.display!=="none"){
+_7d=true;
+}else{
+_76=_76[pos];
+}
+}else{
+if(_76.style.display!=="none"){
+_7d=true;
+}else{
+_76=_76[pos];
+}
+}
+}
+if(_74.shiftKey){
+if(dijit.byNode(_78).dragRestriction){
+return;
+}
+var _80=_78.getAttribute("dndtype");
+var _81=false;
+for(var i=0;i<this.acceptTypes.length;i++){
+if(_80==this.acceptTypes[i]){
+var _81=true;
+break;
+}
+}
+if(_81){
+var _82=_78.parentNode;
+var _83=_82.firstChild;
+var _84=_82.lastChild;
+while(_83.style.display=="none"||_84.style.display=="none"){
+if(_83.style.display=="none"){
+_83=_83.nextSibling;
+}
+if(_84.style.display=="none"){
+_84=_84.previousSibling;
+}
+}
+if(e==k.UP_ARROW){
+var r=_82.removeChild(_78);
+if(r==_83){
+_82.appendChild(r);
+}else{
+_82.insertBefore(r,_76);
+}
+r.setAttribute("tabIndex","0");
+dijit.focus(r);
+}else{
+if(_78==_84){
+var r=_82.removeChild(_78);
+_82.insertBefore(r,_76);
+r.setAttribute("tabIndex","0");
+dijit.focus(r);
+}else{
+var r=_82.removeChild(_76);
+_82.insertBefore(r,_78);
+_78.setAttribute("tabIndex","0");
+dijit.focus(_78);
+}
+}
+}else{
+this._displayPopup();
+}
+}else{
+dijit.focus(_76);
+}
+break;
+case k.RIGHT_ARROW:
+case k.LEFT_ARROW:
+dojo.stopEvent(_74);
+if(_74.shiftKey){
+if(dijit.byNode(_78).dragRestriction){
+return;
+}
+var z=0;
+if(_78.parentNode[pos]==null){
+if(e==k.LEFT_ARROW){
+var z=this.gridNode.childNodes.length-1;
+}
+}else{
+if(_78.parentNode[pos].nodeType==3){
+z=this.gridNode.childNodes.length-2;
+}else{
+for(var i=0;i<this.gridNode.childNodes.length;i++){
+if(_78.parentNode[pos]==this.gridNode.childNodes[i]){
+break;
+}
+z++;
+}
+}
+}
+var _80=_78.getAttribute("dndtype");
+var _81=false;
+for(var i=0;i<this.acceptTypes.length;i++){
+if(_80==this.acceptTypes[i]){
+_81=true;
+break;
+}
+}
+if(_81){
+var _87=_78.parentNode;
+var _88=dijit.byNode(_78);
+var r=_87.removeChild(_78);
+var _89=(e==k.RIGHT_ARROW?0:this.gridNode.childNodes[z].length);
+this.addService(_88,z,_89);
+r.setAttribute("tabIndex","0");
+dijit.focus(r);
+this._placeGrips();
+}else{
+this._displayPopup();
+}
+}else{
+var _8a=_78.parentNode;
+while(_76===null){
+if(_8a[pos]!==null&&_8a[pos].nodeType!==3){
+_8a=_8a[pos];
+}else{
+if(pos==="previousSibling"){
+_8a=_8a.parentNode.childNodes[_8a.parentNode.childNodes.length-1];
+}else{
+_8a=_8a.parentNode.childNodes[0];
+}
+}
+var _7d=false;
+var _8b=_8a[_7a];
+while(!_7d){
+if(_8b!=null){
+if(_8b.style.display!=="none"){
+_76=_8b;
+_7d=true;
+}else{
+_8b=_8b[pos];
+}
+}else{
+break;
+}
+}
+}
+dijit.focus(_76);
+}
+break;
+}
+}else{
+if(dojo.hasClass(_78,"gridContainerGrip")||dojo.hasClass(_78,"gridContainerGripShow")){
+this._activeGrip=_74.target;
+this._a11yOn=true;
+this.resizeColumnOn(_74);
+}
+}
+}
+},_displayPopup:function(){
+if(this._canDisplayPopup){
+var _8c=dojo.doc.createElement("div");
+dojo.addClass(_8c,"gridContainerPopup");
+_8c.innerHTML=this.i18n.alertPopup;
+var _8d=this.containerNode.appendChild(_8c);
+this._canDisplayPopup=false;
+setTimeout(dojo.hitch(this,function(){
+this.containerNode.removeChild(_8d);
+dojo.destroy(_8d);
+this._canDisplayPopup=true;
+}),this.timeDisplayPopup);
+}
+}});
+dojo.extend(dijit._Widget,{dragRestriction:false,column:"1",group:""});
+}
diff --git a/dojox/layout/README b/dojox/layout/README
new file mode 100644
index 0000000..6802bb2
--- /dev/null
+++ b/dojox/layout/README
@@ -0,0 +1,115 @@
+-------------------------------------------------------------------------------
+dojox.layout Experimental and Extended Layout Widgets
+-------------------------------------------------------------------------------
+Version 1.0
+Release date: 10/31/2007
+-------------------------------------------------------------------------------
+Project state:
+
+[BorderContainer] deprecated, use dijit.layout.BorderContainer
+[ContentPane]	beta
+[DragPane]	experimental
+[ExpandoPane] experimental
+[FloatingPane] sub-experimental
+[GridContainer] experimental
+[RadioGroup] experimental
+[RadioGroupFade/Slide] experimental
+[ResizeHandle] experimental
+[RotatorContainer] beta
+[ScrollPane] experimental
+
+-------------------------------------------------------------------------------
+Credits
+
+[BorderContainer] Adam Peller (peller)
+[ContentPane]	Fredrik Johansson (mumme)
+[DragPane]	Peter Higgins (dante)
+[ExpandoPane] Peter Higgins (dante)
+[FloatingPane] Peter Higgins (dante)
+[GridContainer] Juff Cunat (jfcunat), Peter Higgins (dante)
+[RadioGroup/Fade/Slide] Peter Higgins (dante) 
+[ResizeHandle] Peter Higgins (dante)
+[RotatorContainer] Chris Barber (cb1)
+[ScrollPane] Peter Higgins (dante), Shane O'Sullivan (sos)
+
+-------------------------------------------------------------------------------
+Project description
+
+	placeholder for dijit.layout extensions. Currently only:
+
+	dojo.layout.BorderContainer - deprecated, simple replacement at dijit.layout.BorderContainer
+
+	dojox.layout.ContentPane - an extension on dijit ContentPane.
+	Supports inline scripts, inline styles, relative path adjustments
+	and having a table tag as domNode.
+
+	dojox.layout.DragPane - an experimental start of a simple Dragable pane 
+	(drag larger content around inside of a sized pane) Does not support borderContainer
+	LayoutContainer resizing yet. 
+
+	dojox.layout.ExpandoPane - Intended only as a child of BorderContainer, provides an
+	experimental layout region (top/left/right/bottom) that collapses when toggled, hiding
+	the layout children contained within.
+	
+	dojox.layout.FloatingPane - an extension on TitlePane for drag/drop
+	operation, "docking" [minimize/maximize], and resizing. HIGHLY experimental.
+	
+	dojox.layout.GridContainer - displays children in a definable grid-layout,
+	allowing children to optionally be repositioned with DnD
+
+	dojox.layout.RadioGroup - a stack container with sliding or fading transitions
+	(and an internal button set to mimic a tab container, but fires on hover)
+		- RadioGroupFade - fade transitions
+		- RadioGroupSlide - slide transitions
+
+	dojox.layout.ResizeHandle - resize handle to attach to a domNode.
+	works well on normal domNodes, but will require adding a resizeTo(w,h)
+	method to any widget you wish to use it on. [experimental]
+
+	dojox.layout.RotatorContainer - similar to a RadioGroup, but provides advanced button's and
+	control. 
+
+	dojox.layout.ScrollPane - a dynamically scrolling pane. Adjusts naturally sized content
+	to a "viewport" and scrolls based on relative mouse position. 
+	
+-------------------------------------------------------------------------------
+Dependencies
+
+	require Dojo Core, Dojo Base (fx), and Dijit
+
+-------------------------------------------------------------------------------
+Installation:
+
+	checkout:
+
+	http://svn.dojotoolkit.org/src/dojox/trunk/layout/
+	http://svn.dojotoolkit.org/src/dijit/trunk/
+
+	and require via:
+		dojo.require("dojox.layout.FloatingPane");
+	or:
+		dojo.require("dojox.layout.ContentPane");
+	etc ...
+
+	Each component has a required CSS File with a similar name, contained within the
+	/resources folder. Include that file in your page. For instance, if using
+	the dojox.layout.ExpandoPane:
+	
+	<link rel="stylesheet" href="dojo-tree/dojox/layout/resources/ExpandoPane.css" />
+
+-------------------------------------------------------------------------------
+Basic Usage:
+
+	<div dojoType="dojox.layout.FloatingPane" title="my title">
+		Content To be Floated
+	</div>
+
+	<div dojoType="dojox.layout.ContentPane"
+		 adjustPaths="true"
+		 renderStyles="true"
+		 executeScripts="true"
+		 href="my/page/containing/scripts/and/styles/in/a/sub/folder.html"
+	>
+		Initial content, will be replace by href.
+		paths in folder.html will be adjusted to match this page
+	</div>
diff --git a/dojox/layout/RadioGroup.js b/dojox/layout/RadioGroup.js
new file mode 100644
index 0000000..927dce1
--- /dev/null
+++ b/dojox/layout/RadioGroup.js
@@ -0,0 +1,139 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.layout.RadioGroup"]){
+dojo._hasResource["dojox.layout.RadioGroup"]=true;
+dojo.provide("dojox.layout.RadioGroup");
+dojo.experimental("dojox.layout.RadioGroup");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dijit._Contained");
+dojo.require("dijit.layout.StackContainer");
+dojo.require("dojo.fx.easing");
+dojo.declare("dojox.layout.RadioGroup",[dijit.layout.StackContainer,dijit._Templated],{duration:750,hasButtons:false,buttonClass:"dojox.layout._RadioButton",templateString:"<div class=\"dojoxRadioGroup\">"+" \t<div dojoAttachPoint=\"buttonHolder\" style=\"display:none;\">"+"\t\t<table class=\"dojoxRadioButtons\"><tbody><tr class=\"dojoxRadioButtonRow\" dojoAttachPoint=\"buttonNode\"></tr></tbody></table>"+"\t</div>"+"\t<div class=\"dojoxRadioView\" dojoAttachPoint=\"containerNode\"></div [...]
+this.inherited(arguments);
+this._children=this.getChildren();
+this._buttons=this._children.length;
+this._size=dojo.coords(this.containerNode);
+if(this.hasButtons){
+dojo.style(this.buttonHolder,"display","block");
+}
+},_setupChild:function(_1){
+if(this.hasButtons){
+dojo.style(_1.domNode,"position","absolute");
+var _2=this.buttonNode.appendChild(dojo.create("td"));
+var n=dojo.create("div",null,_2),_4=dojo.getObject(this.buttonClass),_5=new _4({label:_1.title,page:_1},n);
+dojo.mixin(_1,{_radioButton:_5});
+_5.startup();
+}
+_1.domNode.style.display="none";
+},removeChild:function(_6){
+if(this.hasButtons&&_6._radioButton){
+_6._radioButton.destroy();
+delete _6._radioButton;
+}
+this.inherited(arguments);
+},_transition:function(_7,_8){
+this._showChild(_7);
+if(_8){
+this._hideChild(_8);
+}
+if(this.doLayout&&_7.resize){
+_7.resize(this._containerContentBox||this._contentBox);
+}
+},_showChild:function(_9){
+var _a=this.getChildren();
+_9.isFirstChild=(_9==_a[0]);
+_9.isLastChild=(_9==_a[_a.length-1]);
+_9.selected=true;
+_9.domNode.style.display="";
+if(_9._onShow){
+_9._onShow();
+}else{
+if(_9.onShow){
+_9.onShow();
+}
+}
+},_hideChild:function(_b){
+_b.selected=false;
+_b.domNode.style.display="none";
+if(_b.onHide){
+_b.onHide();
+}
+}});
+dojo.declare("dojox.layout.RadioGroupFade",dojox.layout.RadioGroup,{_hideChild:function(_c){
+dojo.fadeOut({node:_c.domNode,duration:this.duration,onEnd:dojo.hitch(this,"inherited",arguments)}).play();
+},_showChild:function(_d){
+this.inherited(arguments);
+dojo.style(_d.domNode,"opacity",0);
+dojo.fadeIn({node:_d.domNode,duration:this.duration}).play();
+}});
+dojo.declare("dojox.layout.RadioGroupSlide",dojox.layout.RadioGroup,{easing:"dojo.fx.easing.backOut",zTop:99,constructor:function(){
+if(dojo.isString(this.easing)){
+this.easing=dojo.getObject(this.easing);
+}
+},_positionChild:function(_e){
+if(!this._size){
+return;
+}
+var rA=true,rB=true;
+switch(_e.slideFrom){
+case "bottom":
+rB=!rB;
+break;
+case "right":
+rA=!rA;
+rB=!rB;
+break;
+case "top":
+break;
+case "left":
+rA=!rA;
+break;
+default:
+rA=Math.round(Math.random());
+rB=Math.round(Math.random());
+break;
+}
+var _11=rA?"top":"left",val=(rB?"-":"")+(this._size[rA?"h":"w"]+20)+"px";
+dojo.style(_e.domNode,_11,val);
+},_showChild:function(_13){
+var _14=this.getChildren();
+_13.isFirstChild=(_13==_14[0]);
+_13.isLastChild=(_13==_14[_14.length-1]);
+_13.selected=true;
+dojo.style(_13.domNode,{zIndex:this.zTop,display:""});
+if(this._anim&&this._anim.status()=="playing"){
+this._anim.gotoPercent(100,true);
+}
+this._anim=dojo.animateProperty({node:_13.domNode,properties:{left:0,top:0},duration:this.duration,easing:this.easing,onEnd:dojo.hitch(_13,function(){
+if(this.onShow){
+this.onShow();
+}
+if(this._onShow){
+this._onShow();
+}
+}),beforeBegin:dojo.hitch(this,"_positionChild",_13)});
+this._anim.play();
+},_hideChild:function(_15){
+_15.selected=false;
+_15.domNode.style.zIndex=this.zTop-1;
+if(_15.onHide){
+_15.onHide();
+}
+}});
+dojo.declare("dojox.layout._RadioButton",[dijit._Widget,dijit._Templated,dijit._Contained],{label:"",page:null,templateString:"<div dojoAttachPoint=\"focusNode\" class=\"dojoxRadioButton\"><span dojoAttachPoint=\"titleNode\" class=\"dojoxRadioButtonLabel\">${label}</span></div>",startup:function(){
+this.connect(this.domNode,"onmouseenter","_onMouse");
+},_onMouse:function(e){
+this.getParent().selectChild(this.page);
+this._clearSelected();
+dojo.addClass(this.domNode,"dojoxRadioButtonSelected");
+},_clearSelected:function(){
+dojo.query(".dojoxRadioButtonSelected",this.domNode.parentNode.parentNode).removeClass("dojoxRadioButtonSelected");
+}});
+dojo.extend(dijit._Widget,{slideFrom:"random"});
+}
diff --git a/dojox/layout/ResizeHandle.js b/dojox/layout/ResizeHandle.js
new file mode 100644
index 0000000..5ad4e30
--- /dev/null
+++ b/dojox/layout/ResizeHandle.js
@@ -0,0 +1,173 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.layout.ResizeHandle"]){
+dojo._hasResource["dojox.layout.ResizeHandle"]=true;
+dojo.provide("dojox.layout.ResizeHandle");
+dojo.experimental("dojox.layout.ResizeHandle");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dojo.fx");
+dojo.declare("dojox.layout.ResizeHandle",[dijit._Widget,dijit._Templated],{targetId:"",targetContainer:null,resizeAxis:"xy",activeResize:false,activeResizeClass:"dojoxResizeHandleClone",animateSizing:true,animateMethod:"chain",animateDuration:225,minHeight:100,minWidth:100,constrainMax:false,maxHeight:0,maxWidth:0,fixedAspect:false,intermediateChanges:false,templateString:"<div dojoAttachPoint=\"resizeHandle\" class=\"dojoxResizeHandle\"><div></div></div>",postCreate:function(){
+this.connect(this.resizeHandle,"onmousedown","_beginSizing");
+if(!this.activeResize){
+this._resizeHelper=dijit.byId("dojoxGlobalResizeHelper");
+if(!this._resizeHelper){
+this._resizeHelper=new dojox.layout._ResizeHelper({id:"dojoxGlobalResizeHelper"}).placeAt(dojo.body());
+dojo.addClass(this._resizeHelper.domNode,this.activeResizeClass);
+}
+}else{
+this.animateSizing=false;
+}
+if(!this.minSize){
+this.minSize={w:this.minWidth,h:this.minHeight};
+}
+if(this.constrainMax){
+this.maxSize={w:this.maxWidth,h:this.maxHeight};
+}
+this._resizeX=this._resizeY=false;
+var _1=dojo.partial(dojo.addClass,this.resizeHandle);
+switch(this.resizeAxis.toLowerCase()){
+case "xy":
+this._resizeX=this._resizeY=true;
+_1("dojoxResizeNW");
+break;
+case "x":
+this._resizeX=true;
+_1("dojoxResizeW");
+break;
+case "y":
+this._resizeY=true;
+_1("dojoxResizeN");
+break;
+}
+},_beginSizing:function(e){
+if(this._isSizing){
+return false;
+}
+this.targetWidget=dijit.byId(this.targetId);
+this.targetDomNode=this.targetWidget?this.targetWidget.domNode:dojo.byId(this.targetId);
+if(this.targetContainer){
+this.targetDomNode=this.targetContainer;
+}
+if(!this.targetDomNode){
+return false;
+}
+if(!this.activeResize){
+var c=dojo.coords(this.targetDomNode,true);
+this._resizeHelper.resize({l:c.x,t:c.y,w:c.w,h:c.h});
+this._resizeHelper.show();
+}
+this._isSizing=true;
+this.startPoint={x:e.clientX,y:e.clientY};
+var mb=this.targetWidget?dojo.marginBox(this.targetDomNode):dojo.contentBox(this.targetDomNode);
+this.startSize={w:mb.w,h:mb.h};
+if(this.fixedAspect){
+var _5,_6;
+if(mb.w>mb.h){
+_5="w";
+_6=mb.w/mb.h;
+}else{
+_5="h";
+_6=mb.h/mb.w;
+}
+this._aspect={prop:_5};
+this._aspect[_5]=_6;
+}
+this._pconnects=[];
+this._pconnects.push(dojo.connect(dojo.doc,"onmousemove",this,"_updateSizing"));
+this._pconnects.push(dojo.connect(dojo.doc,"onmouseup",this,"_endSizing"));
+dojo.stopEvent(e);
+},_updateSizing:function(e){
+if(this.activeResize){
+this._changeSizing(e);
+}else{
+var _8=this._getNewCoords(e);
+if(_8===false){
+return;
+}
+this._resizeHelper.resize(_8);
+}
+e.preventDefault();
+},_getNewCoords:function(e){
+try{
+if(!e.clientX||!e.clientY){
+return false;
+}
+}
+catch(e){
+return false;
+}
+this._activeResizeLastEvent=e;
+var dx=this.startPoint.x-e.clientX,dy=this.startPoint.y-e.clientY,_c=this.startSize.w-(this._resizeX?dx:0),_d=this.startSize.h-(this._resizeY?dy:0);
+return this._checkConstraints(_c,_d);
+},_checkConstraints:function(_e,_f){
+if(this.minSize){
+var tm=this.minSize;
+if(_e<tm.w){
+_e=tm.w;
+}
+if(_f<tm.h){
+_f=tm.h;
+}
+}
+if(this.constrainMax&&this.maxSize){
+var ms=this.maxSize;
+if(_e>ms.w){
+_e=ms.w;
+}
+if(_f>ms.h){
+_f=ms.h;
+}
+}
+if(this.fixedAspect){
+var ta=this._aspect[this._aspect.prop];
+if(_e<_f){
+_f=_e*ta;
+}else{
+if(_f<_e){
+_e=_f*ta;
+}
+}
+}
+return {w:_e,h:_f};
+},_changeSizing:function(e){
+var tmp=this._getNewCoords(e);
+if(tmp===false){
+return;
+}
+if(this.targetWidget&&dojo.isFunction(this.targetWidget.resize)){
+this.targetWidget.resize(tmp);
+}else{
+if(this.animateSizing){
+var _15=dojo.fx[this.animateMethod]([dojo.animateProperty({node:this.targetDomNode,properties:{width:{start:this.startSize.w,end:tmp.w,unit:"px"}},duration:this.animateDuration}),dojo.animateProperty({node:this.targetDomNode,properties:{height:{start:this.startSize.h,end:tmp.h,unit:"px"}},duration:this.animateDuration})]);
+_15.play();
+}else{
+dojo.style(this.targetDomNode,{width:tmp.w+"px",height:tmp.h+"px"});
+}
+}
+if(this.intermediateChanges){
+this.onResize(e);
+}
+},_endSizing:function(e){
+dojo.forEach(this._pconnects,dojo.disconnect);
+if(!this.activeResize){
+this._resizeHelper.hide();
+this._changeSizing(e);
+}
+this._isSizing=false;
+this.onResize(e);
+},onResize:function(e){
+}});
+dojo.declare("dojox.layout._ResizeHelper",dijit._Widget,{show:function(){
+dojo.fadeIn({node:this.domNode,duration:120,beforeBegin:dojo.partial(dojo.style,this.domNode,"display","")}).play();
+},hide:function(){
+dojo.fadeOut({node:this.domNode,duration:250,onEnd:dojo.partial(dojo.style,this.domNode,"display","none")}).play();
+},resize:function(dim){
+dojo.marginBox(this.domNode,dim);
+}});
+}
diff --git a/dojox/layout/RotatorContainer.js b/dojox/layout/RotatorContainer.js
new file mode 100644
index 0000000..c8cf0ae
--- /dev/null
+++ b/dojox/layout/RotatorContainer.js
@@ -0,0 +1,207 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.layout.RotatorContainer"]){
+dojo._hasResource["dojox.layout.RotatorContainer"]=true;
+dojo.provide("dojox.layout.RotatorContainer");
+dojo.require("dojo.fx");
+dojo.require("dijit.layout.StackContainer");
+dojo.require("dijit.layout.StackController");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dijit._Contained");
+dojo.declare("dojox.layout.RotatorContainer",[dijit.layout.StackContainer,dijit._Templated],{templateString:"<div class=\"dojoxRotatorContainer\"><div dojoAttachPoint=\"tabNode\"></div><div class=\"dojoxRotatorPager\" dojoAttachPoint=\"pagerNode\"></div><div class=\"dojoxRotatorContent\" dojoAttachPoint=\"containerNode\"></div></div>",showTabs:true,transitionDelay:5000,transition:"fade",transitionDuration:1000,autoStart:true,suspendOnHover:false,pauseOnManualChange:null,reverse:false,pag [...]
+this.inherited(arguments);
+dojo.style(this.domNode,"position","relative");
+if(this.cycles-0==this.cycles&&this.cycles!=-1){
+this.cycles++;
+}else{
+this.cycles=-1;
+}
+if(this.pauseOnManualChange===null){
+this.pauseOnManualChange=!this.suspendOnHover;
+}
+var id=this.id||"rotator"+(new Date()).getTime();
+var sc=new dijit.layout.StackController({containerId:id},this.tabNode);
+this.tabNode=sc.domNode;
+this._stackController=sc;
+dojo.style(this.tabNode,"display",this.showTabs?"":"none");
+this.connect(sc,"onButtonClick","_manualChange");
+this._subscriptions=[dojo.subscribe(this.id+"-cycle",this,"_cycle"),dojo.subscribe(this.id+"-state",this,"_state")];
+var d=Math.round(this.transitionDelay*0.75);
+if(d<this.transitionDuration){
+this.transitionDuration=d;
+}
+if(this.suspendOnHover){
+this.connect(this.domNode,"onmouseover","_onMouseOver");
+this.connect(this.domNode,"onmouseout","_onMouseOut");
+}
+},startup:function(){
+if(this._started){
+return;
+}
+var c=this.getChildren();
+for(var i=0,_6=c.length;i<_6;i++){
+if(c[i].declaredClass==this.pagerClass){
+this.pagerNode.appendChild(c[i].domNode);
+break;
+}
+}
+this.inherited(arguments);
+if(this.autoStart){
+setTimeout(dojo.hitch(this,"_play"),10);
+}else{
+this._updatePager();
+}
+},destroy:function(){
+dojo.forEach(this._subscriptions,dojo.unsubscribe);
+this.inherited(arguments);
+},setAttribute:function(_7,_8){
+this.inherited(arguments);
+switch(_7){
+case "showTabs":
+this.showTabs=_8;
+dojo.style(this.tabNode,"display",_8?"":"none");
+break;
+case "transitionDelay":
+case "transitionDuration":
+case "suspendOnHover":
+case "pauseOnManualChange":
+case "reverse":
+this[_7]=_8;
+}
+},_updatePager:function(){
+var c=this.getChildren();
+dojo.publish(this.id+"-update",[this._playing,dojo.indexOf(c,this.selectedChildWidget)+1,c.length]);
+},_onMouseOver:function(){
+this._resetTimer();
+this._over=true;
+},_onMouseOut:function(){
+this._over=false;
+if(this._playing){
+clearTimeout(this._timer);
+this._timer=setTimeout(dojo.hitch(this,"_play",true),200);
+}
+},_resetTimer:function(){
+clearTimeout(this._timer);
+this._timer=null;
+},_cycle:function(_a){
+if(_a instanceof Boolean||typeof _a=="boolean"){
+this._manualChange();
+}
+var c=this.getChildren();
+var _c=c.length;
+var i=dojo.indexOf(c,this.selectedChildWidget)+(_a===false||(_a!==true&&this.reverse)?-1:1);
+this.selectChild(c[(i<_c?(i<0?_c-1:i):0)]);
+this._updatePager();
+},_manualChange:function(){
+if(this.pauseOnManualChange){
+this._playing=false;
+}
+this.cycles=-1;
+},_play:function(_e){
+this._playing=true;
+this._resetTimer();
+if(_e!==true&&this.cycles>0){
+this.cycles--;
+}
+if(this.cycles==0){
+this._pause();
+}else{
+if((!this.suspendOnHover||!this._over)&&this.transitionDelay){
+this._timer=setTimeout(dojo.hitch(this,"_cycle"),this.selectedChildWidget.domNode.getAttribute("transitionDelay")||this.transitionDelay);
+}
+}
+this._updatePager();
+},_pause:function(){
+this._playing=false;
+this._resetTimer();
+},_state:function(_f){
+if(_f){
+this.cycles=-1;
+this._play();
+}else{
+this._pause();
+}
+},_transition:function(_10,_11){
+this._resetTimer();
+if(_11&&this.transitionDuration){
+switch(this.transition){
+case "fade":
+this._fade(_10,_11);
+return;
+}
+}
+this._transitionEnd();
+this.inherited(arguments);
+},_transitionEnd:function(){
+if(this._playing){
+this._play();
+}else{
+this._updatePager();
+}
+},_fade:function(_12,_13){
+this._styleNode(_13.domNode,1,1);
+this._styleNode(_12.domNode,0,2);
+this._showChild(_12);
+if(this.doLayout&&_12.resize){
+_12.resize(this._containerContentBox||this._contentBox);
+}
+var _14={duration:this.transitionDuration};
+var _15=dojo.fx.combine([dojo["fadeOut"](dojo.mixin({node:_13.domNode},_14)),dojo["fadeIn"](dojo.mixin({node:_12.domNode},_14))]);
+this.connect(_15,"onEnd",dojo.hitch(this,function(){
+this._hideChild(_13);
+this._transitionEnd();
+}));
+_15.play();
+},_styleNode:function(_16,_17,_18){
+
+dojo.style(_16,"opacity",_17);
+dojo.style(_16,"zIndex",_18);
+dojo.style(_16,"position","absolute");
+}});
+dojo.declare("dojox.layout.RotatorPager",[dijit._Widget,dijit._Templated,dijit._Contained],{widgetsInTemplate:true,rotatorId:"",postMixInProperties:function(){
+this.templateString="<div>"+this.srcNodeRef.innerHTML+"</div>";
+},postCreate:function(){
+var p=dijit.byId(this.rotatorId)||this.getParent();
+if(p&&p.declaredClass=="dojox.layout.RotatorContainer"){
+if(this.previous){
+dojo.connect(this.previous,"onClick",function(){
+dojo.publish(p.id+"-cycle",[false]);
+});
+}
+if(this.next){
+dojo.connect(this.next,"onClick",function(){
+dojo.publish(p.id+"-cycle",[true]);
+});
+}
+if(this.playPause){
+dojo.connect(this.playPause,"onClick",function(){
+this.attr("label",this.checked?"Pause":"Play");
+dojo.publish(p.id+"-state",[this.checked]);
+});
+}
+this._subscriptions=[dojo.subscribe(p.id+"-state",this,"_state"),dojo.subscribe(p.id+"-update",this,"_update")];
+}
+},destroy:function(){
+dojo.forEach(this._subscriptions,dojo.unsubscribe);
+this.inherited(arguments);
+},_state:function(_1a){
+if(this.playPause&&this.playPause.checked!=_1a){
+this.playPause.attr("label",_1a?"Pause":"Play");
+this.playPause.setAttribute("checked",_1a);
+}
+},_update:function(_1b,_1c,_1d){
+this._state(_1b);
+if(this.current&&_1c){
+this.current.innerHTML=_1c;
+}
+if(this.total&&_1d){
+this.total.innerHTML=_1d;
+}
+}});
+}
diff --git a/dojox/layout/ScrollPane.js b/dojox/layout/ScrollPane.js
new file mode 100644
index 0000000..b27466a
--- /dev/null
+++ b/dojox/layout/ScrollPane.js
@@ -0,0 +1,82 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.layout.ScrollPane"]){
+dojo._hasResource["dojox.layout.ScrollPane"]=true;
+dojo.provide("dojox.layout.ScrollPane");
+dojo.experimental("dojox.layout.ScrollPane");
+dojo.require("dijit.layout.ContentPane");
+dojo.require("dijit._Templated");
+dojo.declare("dojox.layout.ScrollPane",[dijit.layout.ContentPane,dijit._Templated],{_line:null,_lo:null,_offset:15,orientation:"vertical",autoHide:true,templateString:"<div class=\"dojoxScrollWindow\" dojoAttachEvent=\"onmouseenter: _enter, onmouseleave: _leave\">\n    <div class=\"dojoxScrollWrapper\" style=\"${style}\" dojoAttachPoint=\"wrapper\" dojoAttachEvent=\"onmousemove: _calc\">\n\t<div class=\"dojoxScrollPane\" dojoAttachPoint=\"containerNode\"></div>\n    </div>\n    <div dojo [...]
+if(_1){
+if(_1.h){
+dojo.style(this.domNode,"height",_1.h+"px");
+}
+if(_1.w){
+dojo.style(this.domNode,"width",_1.w+"px");
+}
+}
+var _2=this._dir,_3=this._vertical,_4=this.containerNode[(_3?"scrollHeight":"scrollWidth")];
+dojo.style(this.wrapper,this._dir,this.domNode.style[this._dir]);
+this._lo=dojo.coords(this.wrapper,true);
+this._size=Math.max(0,_4-this._lo[(_3?"h":"w")]);
+if(!this._size){
+this.helper.style.display="none";
+this.wrapper[this._scroll]=0;
+return;
+}else{
+this.helper.style.display="";
+}
+this._line=new dojo._Line(0-this._offset,this._size+(this._offset*2));
+var u=this._lo[(_3?"h":"w")],r=Math.min(1,u/_4),s=u*r,c=Math.floor(u-(u*r));
+this._helpLine=new dojo._Line(0,c);
+dojo.style(this.helper,_2,Math.floor(s)+"px");
+},postCreate:function(){
+this.inherited(arguments);
+if(this.autoHide){
+this._showAnim=dojo._fade({node:this.helper,end:0.5,duration:350});
+this._hideAnim=dojo.fadeOut({node:this.helper,duration:750});
+}
+this._vertical=(this.orientation=="vertical");
+if(!this._vertical){
+dojo.addClass(this.containerNode,"dijitInline");
+this._dir="width";
+this._edge="left";
+this._scroll="scrollLeft";
+}else{
+this._dir="height";
+this._edge="top";
+this._scroll="scrollTop";
+}
+if(this._hideAnim){
+this._hideAnim.play();
+}
+dojo.style(this.wrapper,"overflow","hidden");
+},_set:function(n){
+if(!this._size){
+return;
+}
+this.wrapper[this._scroll]=Math.floor(this._line.getValue(n));
+dojo.style(this.helper,this._edge,Math.floor(this._helpLine.getValue(n))+"px");
+},_calc:function(e){
+if(!this._lo){
+this.resize();
+}
+this._set(this._vertical?((e.pageY-this._lo.y)/this._lo.h):((e.pageX-this._lo.x)/this._lo.w));
+},_enter:function(e){
+if(this._hideAnim){
+if(this._hideAnim.status()=="playing"){
+this._hideAnim.stop();
+}
+this._showAnim.play();
+}
+},_leave:function(e){
+if(this._hideAnim){
+this._hideAnim.play();
+}
+}});
+}
diff --git a/dojox/layout/ToggleSplitter.js b/dojox/layout/ToggleSplitter.js
new file mode 100644
index 0000000..14b0e64
--- /dev/null
+++ b/dojox/layout/ToggleSplitter.js
@@ -0,0 +1,131 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.layout.ToggleSplitter"]){
+dojo._hasResource["dojox.layout.ToggleSplitter"]=true;
+dojo.provide("dojox.layout.ToggleSplitter");
+dojo.experimental("dojox.layout.ToggleSplitter");
+dojo.require("dijit.layout.BorderContainer");
+dojo.declare("dojox.layout.ToggleSplitter",[dijit.layout._Splitter],{open:true,closedThreshold:5,openSize:"",_closedSize:"0",templateString:"<div class=\"dijitSplitter dojoxToggleSplitter\" dojoAttachEvent=\"onkeypress:_onKeyPress,onmousedown:_onMouseDown\" tabIndex=\"0\" waiRole=\"separator\"><div dojoAttachPoint=\"toggleNode\" class=\"dijitSplitterThumb dojoxToggleSplitterIcon\"></div></div>",postCreate:function(){
+this._started=false;
+this.inherited(arguments);
+var _1=this.region;
+dojo.addClass(this.domNode,"dojoxToggleSplitter"+_1.charAt(0).toUpperCase()+_1.substring(1));
+this.connect(this,"onDblClick","_toggleMe");
+},startup:function(){
+this.inherited(arguments);
+var _2=this.child.domNode,_3=dojo.style(_2,(this.horizontal?"height":"width"));
+dojo.forEach(["toggleSplitterOpen","toggleSplitterClosedThreshold","toggleSplitterOpenSize"],function(_4){
+var _5=_4.substring("toggleSplitter".length);
+_5=_5.charAt(0).toLowerCase()+_5.substring(1);
+if(_4 in this.child){
+this[_5]=this.child[_4];
+}
+},this);
+if(!this.openSize){
+this.openSize=(this.open)?_3+"px":"75px";
+}
+this._openStyleProps=this._getStyleProps(_2,true);
+this._started=true;
+this.attr("open",this.open);
+return this;
+},_onMouseUp:function(_6){
+dojo.disconnect(this._onMoveHandle);
+dojo.disconnect(this._onUpHandle);
+delete this._onMoveHandle;
+delete this._onUpHandle;
+delete this._startPosn;
+},_onPrelimMouseMove:function(_7){
+var _8=this._startPosn||0;
+var _9=3;
+var _a=Math.abs(_8-(this.horizontal?_7.clientY:_7.clientX));
+if(_a>=_9){
+dojo.disconnect(this._onMoveHandle);
+this._startDrag(_7);
+}
+},_onMouseDown:function(_b){
+if(!this.open){
+return;
+}
+if(!this._onUpHandle){
+this._onUpHandle=dojo.connect(dojo.body(),"onmouseup",this,"_onMouseUp");
+}
+if(!this._onMoveHandle){
+this._startPosn=this.horizontal?_b.clientY:_b.clientX;
+this._onMoveHandle=dojo.connect(dojo.body(),"onmousemove",this,"_onPrelimMouseMove");
+}
+},_handleOnChange:function(){
+var _c=this.child.domNode,_d,_e=this.horizontal?"height":"width";
+if(this.open){
+var _f=dojo.mixin({display:"block",overflow:"auto",visibility:"visible"},this._openStyleProps);
+_f[_e]=(this._openStyleProps&&this._openStyleProps[_e])?this._openStyleProps[_e]:this.openSize;
+dojo.style(_c,_f);
+this.connect(this.domNode,"onmousedown","_onMouseDown");
+}else{
+var _10=dojo.getComputedStyle(_c);
+_d=this._getStyleProps(_c,true,_10);
+var _11=this._getStyleProps(_c,false,_10);
+this._openStyleProps=_d;
+dojo.style(_c,_11);
+}
+this._setStateClass();
+if(this.container._started){
+this.container._layoutChildren(this.region);
+}
+},_getStyleProps:function(_12,_13,_14){
+if(!_14){
+_14=dojo.getComputedStyle(_12);
+}
+var _15={},dim=this.horizontal?"height":"width";
+_15["overflow"]=(_13)?_14["overflow"]:"hidden";
+_15["visibility"]=(_13)?_14["visibility"]:"hidden";
+_15[dim]=(_13)?_12.style[dim]||_14[dim]:this._closedSize;
+var _17=["Top","Right","Bottom","Left"];
+dojo.forEach(["padding","margin","border"],function(_18){
+for(var i=0;i<_17.length;i++){
+var _1a=_18+_17[i];
+if(_18=="border"){
+_18+="Width";
+}
+if(undefined!==_14[_1a]){
+_15[_1a]=(_13)?_14[_1a]:0;
+}
+}
+});
+return _15;
+},_setStateClass:function(){
+if(this.open){
+dojo.removeClass(this.domNode,"dojoxToggleSplitterClosed");
+dojo.addClass(this.domNode,"dojoxToggleSplitterOpen");
+dojo.removeClass(this.toggleNode,"dojoxToggleSplitterIconClosed");
+dojo.addClass(this.toggleNode,"dojoxToggleSplitterIconOpen");
+}else{
+dojo.addClass(this.domNode,"dojoxToggleSplitterClosed");
+dojo.removeClass(this.domNode,"dojoxToggleSplitterOpen");
+dojo.addClass(this.toggleNode,"dojoxToggleSplitterIconClosed");
+dojo.removeClass(this.toggleNode,"dojoxToggleSplitterIconOpen");
+}
+},_setOpenAttr:function(_1b){
+if(!this._started){
+return;
+}
+this.open=_1b;
+this._handleOnChange(_1b,true);
+var evt=this.open?"onOpen":"onClose";
+this[evt](this.child);
+},onOpen:function(){
+},onClose:function(){
+},_toggleMe:function(evt){
+if(evt){
+dojo.stopEvent(evt);
+}
+this.attr("open",!this.open);
+},_onKeyPress:function(e){
+this.inherited(arguments);
+}});
+dojo.extend(dijit._Widget,{toggleSplitterOpen:true,toggleSplitterClosedThreshold:5,toggleSplitterOpenSize:""});
+}
diff --git a/dojox/layout/dnd/Avatar.js b/dojox/layout/dnd/Avatar.js
new file mode 100644
index 0000000..5cd160c
--- /dev/null
+++ b/dojox/layout/dnd/Avatar.js
@@ -0,0 +1,34 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.layout.dnd.Avatar"]){
+dojo._hasResource["dojox.layout.dnd.Avatar"]=true;
+dojo.provide("dojox.layout.dnd.Avatar");
+dojo.require("dojo.dnd.common");
+dojox.layout.dnd.Avatar=function(_1,_2){
+this.manager=_1;
+this.construct(_2);
+};
+dojo.extend(dojox.layout.dnd.Avatar,{construct:function(_3){
+var _4=this.manager.source;
+var _5=(_4.creator)?_4._normalizedCreator(_4.getItem(this.manager.nodes[0].id).data,"avatar").node:this.manager.nodes[0].cloneNode(true);
+_5.id=dojo.dnd.getUniqueId();
+dojo.addClass(_5,"dojoDndAvatar");
+_5.style.position="absolute";
+_5.style.zIndex=1999;
+_5.style.margin="0px";
+_5.style.width=dojo.marginBox(_4.node).w+"px";
+dojo.style(_5,"opacity",_3);
+this.node=_5;
+},destroy:function(){
+dojo.destroy(this.node);
+this.node=false;
+},update:function(){
+dojo[(this.manager.canDropFlag?"add":"remove")+"Class"](this.node,"dojoDndAvatarCanDrop");
+},_generateText:function(){
+}});
+}
diff --git a/dojox/layout/dnd/PlottedDnd.js b/dojox/layout/dnd/PlottedDnd.js
new file mode 100644
index 0000000..6cd0562
--- /dev/null
+++ b/dojox/layout/dnd/PlottedDnd.js
@@ -0,0 +1,401 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.layout.dnd.PlottedDnd"]){
+dojo._hasResource["dojox.layout.dnd.PlottedDnd"]=true;
+dojo.provide("dojox.layout.dnd.PlottedDnd");
+dojo.require("dojo.dnd.Source");
+dojo.require("dojo.dnd.Manager");
+dojo.require("dojox.layout.dnd.Avatar");
+dojo.declare("dojox.layout.dnd.PlottedDnd",[dojo.dnd.Source],{GC_OFFSET_X:dojo.dnd.manager().OFFSET_X,GC_OFFSET_Y:dojo.dnd.manager().OFFSET_Y,constructor:function(_1,_2){
+this.childBoxes=null;
+this.dropIndicator=new dojox.layout.dnd.DropIndicator("dndDropIndicator","div");
+this.withHandles=_2.withHandles;
+this.handleClasses=_2.handleClasses;
+this.opacity=_2.opacity;
+this.allowAutoScroll=_2.allowAutoScroll;
+this.dom=_2.dom;
+this.singular=true;
+this.skipForm=true;
+this._over=false;
+this.defaultHandleClass="GcDndHandle";
+this.isDropped=false;
+this._timer=null;
+this.isOffset=(_2.isOffset)?true:false;
+this.offsetDrag=(_2.offsetDrag)?_2.offsetDrag:{x:0,y:0};
+this.hideSource=_2.hideSource?_2.hideSource:true;
+this._drop=this.dropIndicator.create();
+},_calculateCoords:function(_3){
+dojo.forEach(this.node.childNodes,function(_4){
+var c=dojo.coords(_4,true);
+_4.coords={xy:c,w:_4.offsetWidth/2,h:_4.offsetHeight/2,mw:c.w};
+if(_3){
+_4.coords.mh=c.h;
+}
+},this);
+},_legalMouseDown:function(e){
+if(!this.withHandles){
+return true;
+}
+for(var _7=(e.target);_7&&_7!=this.node;_7=_7.parentNode){
+if(dojo.hasClass(_7,this.defaultHandleClass)){
+return true;
+}
+}
+return false;
+},setDndItemSelectable:function(_8,_9){
+for(var _a=_8;_a&&_8!=this.node;_a=_a.parentNode){
+if(dojo.hasClass(_a,"dojoDndItem")){
+dojo.setSelectable(_a,_9);
+return;
+}
+}
+},getDraggedWidget:function(_b){
+var _c=_b;
+while(_c&&_c.nodeName.toLowerCase()!="body"&&!dojo.hasClass(_c,"dojoDndItem")){
+_c=_c.parentNode;
+}
+return (_c)?dijit.byNode(_c):null;
+},isAccepted:function(_d){
+var _e=(_d)?_d.getAttribute("dndtype"):null;
+return (_e&&_e in this.accept);
+},onDndStart:function(_f,_10,_11){
+this.firstIndicator=(_f==this);
+this._calculateCoords(true);
+var m=dojo.dnd.manager();
+if(_10[0].coords){
+this._drop.style.height=_10[0].coords.mh+"px";
+dojo.style(m.avatar.node,"width",_10[0].coords.mw+"px");
+}else{
+this._drop.style.height=m.avatar.node.clientHeight+"px";
+}
+this.dndNodes=_10;
+dojox.layout.dnd.PlottedDnd.superclass.onDndStart.call(this,_f,_10,_11);
+if(_f==this&&this.hideSource){
+dojo.forEach(_10,function(n){
+dojo.style(n,"display","none");
+});
+}
+},onDndCancel:function(){
+var m=dojo.dnd.manager();
+if(m.source==this&&this.hideSource){
+var _15=this.getSelectedNodes();
+dojo.forEach(_15,function(n){
+dojo.style(n,"display","");
+});
+}
+dojox.layout.dnd.PlottedDnd.superclass.onDndCancel.call(this);
+this.deleteDashedZone();
+},onDndDrop:function(_17,_18,_19,_1a){
+try{
+if(!this.isAccepted(_18[0])){
+this.onDndCancel();
+}else{
+if(_17==this&&this._over&&this.dropObject){
+this.current=this.dropObject.c;
+}
+dojox.layout.dnd.PlottedDnd.superclass.onDndDrop.call(this,_17,_18,_19,_1a);
+this._calculateCoords(true);
+}
+}
+catch(e){
+console.warn(e);
+}
+},onMouseDown:function(e){
+if(this.current==null){
+this.selection={};
+}else{
+if(this.current==this.anchor){
+this.anchor=null;
+}
+}
+if(this.current!==null){
+var c=dojo.coords(this.current,true);
+this.current.coords={xy:c,w:this.current.offsetWidth/2,h:this.current.offsetHeight/2,mh:c.h,mw:c.w};
+this._drop.style.height=this.current.coords.mh+"px";
+if(this.isOffset){
+if(this.offsetDrag.x==0&&this.offsetDrag.y==0){
+var _1d=true;
+var _1e=dojo.coords(this._getChildByEvent(e));
+this.offsetDrag.x=_1e.x-e.pageX;
+this.offsetDrag.y=_1e.y-e.clientY;
+}
+if(this.offsetDrag.y<16&&this.current!=null){
+this.offsetDrag.y=this.GC_OFFSET_Y;
+}
+var m=dojo.dnd.manager();
+m.OFFSET_X=this.offsetDrag.x;
+m.OFFSET_Y=this.offsetDrag.y;
+if(_1d){
+this.offsetDrag.x=0;
+this.offsetDrag.y=0;
+}
+}
+}
+if(dojo.dnd.isFormElement(e)){
+this.setDndItemSelectable(e.target,true);
+}else{
+this.containerSource=true;
+var _20=this.getDraggedWidget(e.target);
+if(_20&&_20.dragRestriction){
+}else{
+dojox.layout.dnd.PlottedDnd.superclass.onMouseDown.call(this,e);
+}
+}
+},onMouseUp:function(e){
+dojox.layout.dnd.PlottedDnd.superclass.onMouseUp.call(this,e);
+this.containerSource=false;
+if(!dojo.isIE&&this.mouseDown){
+this.setDndItemSelectable(e.target,true);
+}
+var m=dojo.dnd.manager();
+m.OFFSET_X=this.GC_OFFSET_X;
+m.OFFSET_Y=this.GC_OFFSET_Y;
+},onMouseMove:function(e){
+var m=dojo.dnd.manager();
+if(this.isDragging){
+var _25=false;
+if(this.current!=null||(this.current==null&&!this.dropObject)){
+if(this.isAccepted(m.nodes[0])||this.containerSource){
+_25=this.setIndicatorPosition(e);
+}
+}
+if(this.current!=this.targetAnchor||_25!=this.before){
+this._markTargetAnchor(_25);
+m.canDrop(!this.current||m.source!=this||!(this.current.id in this.selection));
+}
+if(this.allowAutoScroll){
+this._checkAutoScroll(e);
+}
+}else{
+if(this.mouseDown&&this.isSource){
+var _26=this.getSelectedNodes();
+if(_26.length){
+m.startDrag(this,_26,this.copyState(dojo.dnd.getCopyKeyState(e)));
+}
+}
+if(this.allowAutoScroll){
+this._stopAutoScroll();
+}
+}
+},_markTargetAnchor:function(_27){
+if(this.current==this.targetAnchor&&this.before==_27){
+return;
+}
+this.targetAnchor=this.current;
+this.targetBox=null;
+this.before=_27;
+},_unmarkTargetAnchor:function(){
+if(!this.targetAnchor){
+return;
+}
+this.targetAnchor=null;
+this.targetBox=null;
+this.before=true;
+},setIndicatorPosition:function(e){
+var _29=false;
+if(this.current){
+if(!this.current.coords||this.allowAutoScroll){
+this.current.coords={xy:dojo.coords(this.current,true),w:this.current.offsetWidth/2,h:this.current.offsetHeight/2};
+}
+_29=this.horizontal?(e.pageX-this.current.coords.xy.x)<this.current.coords.w:(e.pageY-this.current.coords.xy.y)<this.current.coords.h;
+this.insertDashedZone(_29);
+}else{
+if(!this.dropObject){
+this.insertDashedZone(false);
+}
+}
+return _29;
+},onOverEvent:function(){
+this._over=true;
+dojox.layout.dnd.PlottedDnd.superclass.onOverEvent.call(this);
+if(this.isDragging){
+var m=dojo.dnd.manager();
+if(!this.current&&!this.dropObject&&this.getSelectedNodes()[0]&&this.isAccepted(m.nodes[0])){
+this.insertDashedZone(false);
+}
+}
+},onOutEvent:function(){
+this._over=false;
+this.containerSource=false;
+dojox.layout.dnd.PlottedDnd.superclass.onOutEvent.call(this);
+if(this.dropObject){
+this.deleteDashedZone();
+}
+},deleteDashedZone:function(){
+this._drop.style.display="none";
+var _2b=this._drop.nextSibling;
+while(_2b!=null){
+_2b.coords.xy.y-=parseInt(this._drop.style.height);
+_2b=_2b.nextSibling;
+}
+delete this.dropObject;
+},insertDashedZone:function(_2c){
+if(this.dropObject){
+if(_2c==this.dropObject.b&&((this.current&&this.dropObject.c==this.current.id)||(!this.current&&!this.dropObject.c))){
+return;
+}else{
+this.deleteDashedZone();
+}
+}
+this.dropObject={n:this._drop,c:this.current?this.current.id:null,b:_2c};
+if(this.current){
+dojo.place(this._drop,this.current,_2c?"before":"after");
+if(!this.firstIndicator){
+var _2d=this._drop.nextSibling;
+while(_2d!=null){
+_2d.coords.xy.y+=parseInt(this._drop.style.height);
+_2d=_2d.nextSibling;
+}
+}else{
+this.firstIndicator=false;
+}
+}else{
+this.node.appendChild(this._drop);
+}
+this._drop.style.display="";
+},insertNodes:function(_2e,_2f,_30,_31){
+if(this.dropObject){
+dojo.style(this.dropObject.n,"display","none");
+dojox.layout.dnd.PlottedDnd.superclass.insertNodes.call(this,true,_2f,true,this.dropObject.n);
+this.deleteDashedZone();
+}else{
+return dojox.layout.dnd.PlottedDnd.superclass.insertNodes.call(this,_2e,_2f,_30,_31);
+}
+var _32=dijit.byId(_2f[0].getAttribute("widgetId"));
+if(_32){
+dojox.layout.dnd._setGcDndHandle(_32,this.withHandles,this.handleClasses);
+if(this.hideSource){
+dojo.style(_32.domNode,"display","");
+}
+}
+},_checkAutoScroll:function(e){
+if(this._timer){
+clearTimeout(this._timer);
+}
+this._stopAutoScroll();
+var _34=this.dom,y=this._sumAncestorProperties(_34,"offsetTop");
+if((e.pageY-_34.offsetTop+30)>_34.clientHeight){
+this.autoScrollActive=true;
+this._autoScrollDown(_34);
+}else{
+if((_34.scrollTop>0)&&(e.pageY-y)<30){
+this.autoScrollActive=true;
+this._autoScrollUp(_34);
+}
+}
+},_autoScrollUp:function(_36){
+if(this.autoScrollActive&&_36.scrollTop>0){
+_36.scrollTop-=30;
+this._timer=setTimeout(dojo.hitch(this,"_autoScrollUp",_36),100);
+}
+},_autoScrollDown:function(_37){
+if(this.autoScrollActive&&(_37.scrollTop<(_37.scrollHeight-_37.clientHeight))){
+_37.scrollTop+=30;
+this._timer=setTimeout(dojo.hitch(this,"_autoScrollDown",_37),100);
+}
+},_stopAutoScroll:function(){
+this.autoScrollActive=false;
+},_sumAncestorProperties:function(_38,_39){
+_38=dojo.byId(_38);
+if(!_38){
+return 0;
+}
+var _3a=0;
+while(_38){
+var val=_38[_39];
+if(val){
+_3a+=val-0;
+if(_38==dojo.body()){
+break;
+}
+}
+_38=_38.parentNode;
+}
+return _3a;
+}});
+dojox.layout.dnd._setGcDndHandle=function(_3c,_3d,_3e,_3f){
+var cls="GcDndHandle";
+if(!_3f){
+dojo.query(".GcDndHandle",_3c.domNode).removeClass(cls);
+}
+if(!_3d){
+dojo.addClass(_3c.domNode,cls);
+}else{
+var _41=false;
+for(var i=_3e.length-1;i>=0;i--){
+var _43=dojo.query("."+_3e[i],_3c.domNode)[0];
+if(_43){
+_41=true;
+if(_3e[i]!=cls){
+var _44=dojo.query("."+cls,_3c.domNode);
+if(_44.length==0){
+dojo.removeClass(_3c.domNode,cls);
+}else{
+_44.removeClass(cls);
+}
+dojo.addClass(_43,cls);
+}
+}
+}
+if(!_41){
+dojo.addClass(_3c.domNode,cls);
+}
+}
+};
+dojo.declare("dojox.layout.dnd.DropIndicator",null,{constructor:function(cn,tag){
+this.tag=tag||"div";
+this.style=cn||null;
+},isInserted:function(){
+return (this.node.parentNode&&this.node.parentNode.nodeType==1);
+},create:function(){
+if(this.node&&this.isInserted()){
+return this.node;
+}
+var h="90px",el=dojo.doc.createElement(this.tag);
+if(this.style){
+el.className=this.style;
+el.style.height=h;
+}else{
+dojo.style(el,{position:"relative",border:"1px dashed #F60",margin:"2px",height:h});
+}
+this.node=el;
+return el;
+},destroy:function(){
+if(!this.node||!this.isInserted()){
+return;
+}
+this.node.parentNode.removeChild(this.node);
+this.node=null;
+}});
+dojo.extend(dojo.dnd.Manager,{canDrop:function(_49){
+var _4a=this.target&&_49;
+if(this.canDropFlag!=_4a){
+this.canDropFlag=_4a;
+if(this.avatar){
+this.avatar.update();
+}
+}
+},makeAvatar:function(){
+return (this.source.declaredClass=="dojox.layout.dnd.PlottedDnd")?new dojox.layout.dnd.Avatar(this,this.source.opacity):new dojo.dnd.Avatar(this);
+}});
+if(dojo.isIE){
+dojox.layout.dnd.handdleIE=[dojo.subscribe("/dnd/start",null,function(){
+IEonselectstart=document.body.onselectstart;
+document.body.onselectstart=function(){
+return false;
+};
+}),dojo.subscribe("/dnd/cancel",null,function(){
+document.body.onselectstart=IEonselectstart;
+}),dojo.subscribe("/dnd/drop",null,function(){
+document.body.onselectstart=IEonselectstart;
+})];
+dojo.addOnWindowUnload(function(){
+dojo.forEach(dojox.layout.dnd.handdleIE,dojo.unsubscribe);
+});
+}
+}
diff --git a/dojox/layout/ext-dijit/layout/StackContainer-touch.js b/dojox/layout/ext-dijit/layout/StackContainer-touch.js
new file mode 100644
index 0000000..c496df3
--- /dev/null
+++ b/dojox/layout/ext-dijit/layout/StackContainer-touch.js
@@ -0,0 +1,47 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.layout.ext-dijit.layout.StackContainer-touch"]){
+dojo._hasResource["dojox.layout.ext-dijit.layout.StackContainer-touch"]=true;
+dojo.provide("dojox.layout.ext-dijit.layout.StackContainer-touch");
+dojo.experimental("dojox.layout.ext-dijit.layout.StackContainer-touch");
+dojo.require("dijit.layout.StackContainer");
+dojo.connect(dijit.layout.StackContainer.prototype,"postCreate",function(){
+this.axis=(this.baseClass=="dijitAccordionContainer")?"Y":"X";
+dojo.forEach(["touchstart","touchmove","touchend","touchcancel"],function(p){
+this.connect(this.domNode,p,function(e){
+switch(e.type){
+case "touchmove":
+e.preventDefault();
+if(this.touchPosition){
+var _3=e.touches[0]["page"+this.axis]-this.touchPosition;
+if(Math.abs(_3)>100){
+if(this.axis=="Y"){
+_3*=-1;
+}
+delete this.touchPosition;
+if(_3>0){
+!this.selectedChildWidget.isLastChild&&this.forward();
+}else{
+!this.selectedChildWidget.isFirstChild&&this.back();
+}
+}
+}
+break;
+case "touchstart":
+if(e.touches.length==1){
+this.touchPosition=e.touches[0]["page"+this.axis];
+break;
+}
+case "touchend":
+case "touchcancel":
+delete this.touchPosition;
+}
+});
+},this);
+});
+}
diff --git a/dojox/layout/nls/GridContainer.js b/dojox/layout/nls/GridContainer.js
new file mode 100644
index 0000000..7fb53f7
--- /dev/null
+++ b/dojox/layout/nls/GridContainer.js
@@ -0,0 +1 @@
+({"err_onSetNbColsRightMode":"Move boxes in first columns, in all tabs before changing the organization of the page","err_onSetNbColsLeftMode":"Move boxes in last columns, in all tabs before changing the organization of the page","alertPopup":"this widget type is not accepted to be moved !"})
\ No newline at end of file
diff --git a/dojox/layout/nls/en/GridContainer.js b/dojox/layout/nls/en/GridContainer.js
new file mode 100644
index 0000000..7fb53f7
--- /dev/null
+++ b/dojox/layout/nls/en/GridContainer.js
@@ -0,0 +1 @@
+({"err_onSetNbColsRightMode":"Move boxes in first columns, in all tabs before changing the organization of the page","err_onSetNbColsLeftMode":"Move boxes in last columns, in all tabs before changing the organization of the page","alertPopup":"this widget type is not accepted to be moved !"})
\ No newline at end of file
diff --git a/dojox/layout/nls/fr/GridContainer.js b/dojox/layout/nls/fr/GridContainer.js
new file mode 100644
index 0000000..0dd7e7a
--- /dev/null
+++ b/dojox/layout/nls/fr/GridContainer.js
@@ -0,0 +1 @@
+({"err_onSetNbColsRightMode":"Déplacer les boites dans les premières colonnes, dans tous les onglets avant de modifier l'organisation de la page.","err_onSetNbColsLeftMode":"Déplacer les boites dans les dernières colonnes, dans tous les onglets avant de modifier l'organisation de la page","alertPopup":"Ce type de Widget n'est pas autorisé à être déplacé !"})
\ No newline at end of file
diff --git a/dojox/layout/resources/DndGridContainer.css b/dojox/layout/resources/DndGridContainer.css
new file mode 100644
index 0000000..46d8126
--- /dev/null
+++ b/dojox/layout/resources/DndGridContainer.css
@@ -0,0 +1,10 @@
+
+.dojoDndItemOver		{background-color: #feb !important;}
+.dojoDndItemSelected	{background: #ccf; color: #444;}
+.dojoDndItemBefore		{border-top:    3px solid red;}
+.dojoDndItemAfter		{border-bottom: 3px solid red;}
+.dojoDndItemAnchor		{background: #ccf; color: black;}
+.dojoDndItemOver.dojoDndItemSelected	{background: #ec8;}
+.dojoDndItemOver.dojoDndItemAnchor		{background: #feb !important;}
+.dojoDndAvatarItem		{background: #eee;}
+.dndDropIndicator 		{border: 1px dashed #FF6600;cursor: default;}
diff --git a/dojox/layout/resources/ExpandoPane.css b/dojox/layout/resources/ExpandoPane.css
new file mode 100644
index 0000000..87b5290
--- /dev/null
+++ b/dojox/layout/resources/ExpandoPane.css
@@ -0,0 +1,166 @@
+	
+	.dojoxExpandoPane {
+		overflow:hidden;
+		z-index:440 !important;
+	}
+	
+	.dojoxExpandoPane .dojoxExpandoWrapper {
+		overflow:hidden;
+	}
+	.dojoxExpandoClosed .dojoxExpandoTitleNode {
+		display:none;
+	}
+	
+	.dojoxExpandoClosed .dojoxExpandoWrapper * {
+		overflow:hidden !important;
+	}
+	.dojoxExpandoTitleNode {
+		padding-right:6px; 
+		padding-left:6px;
+	}
+	.dojoxExpandoIcon .a11yNode {
+		display:none;
+		visibility:hidden;
+	}
+	.dojoxExpandoBottom .dojoxExpandoIcon,
+	.dojoxExpandoTop .dojoxExpandoIcon,
+	.dojoxExpandoLeft .dojoxExpandoIcon {
+		float:right;
+		margin-right:2px;
+	}
+	.dojoxExpandoRight .dojoxExpandoIcon {
+		float:left;
+		margin-left:2px;
+	}
+	.dojoxExpandoIcon {
+		width:14px;
+		cursor:pointer;
+		background-position:-60px 0px;
+		height:14px;
+	}
+	.dojoxExpandoClosed .dojoxExpandoIcon {
+		background-position: 0px 0px;
+		margin:0 auto;
+	}
+	
+	.dijitBorderContainer-dijitExpandoPane {
+		border: none !important; 
+	}
+	
+	.soria .dojoxExpandoTitle {
+		height:16px;
+		font-size:0.9em;
+		font-weight:bold;
+		padding:3px;
+		padding-top:6px;
+		padding-bottom:5px;
+		background:#F0F4FC url("../../../dijit/themes/soria/images/tabContainerSprite.gif") repeat-x scroll 0pt -50px;
+		border-left: 1px solid #B1BADF;
+		border-right: 1px solid #B1BADF;
+	}
+	
+	.soria .dojoxExpandoClosed .dojoxExpandoTitle {
+		background: none;
+		background-color: #F0F4FC;
+		border: none;
+	}
+	
+	.soria .dojoxExpandoClosed {
+		background: none;
+		background-color: #F0F4FC;
+		border: 1px solid #B1BADF !important;
+	}
+	
+	.soria .dojoxExpandoIcon {
+		background: url('../../../dijit/themes/soria/images/spriteRoundedIconsSmall.png') no-repeat center center;
+		background-position:-60px 0px;
+	}
+	
+	.soria .dojoxExpandoClosed .dojoxExpandoIcon {
+		background-position:0px 0px;
+		margin-right:3px;
+	}
+	
+	
+	.tundra .dojoxExpandoTitle {
+		font-weight: bold;
+		padding: 5px;
+		padding-top: 6px;
+		padding-bottom: 6px;
+		background: #fafafa url("../../../dijit/themes/tundra/images/accordionItemActive.gif") repeat-x scroll left top;
+		border-top: 1px solid #ccc;
+		border-left: 1px solid #ccc;
+		border-right: 1px solid #ccc;
+	}
+		
+	.tundra .dojoxExpandoClosed .dojoxExpandoTitle {
+		background: none;
+		background-color: #fafafa;
+		border: none;
+		padding:3px;
+	}
+	
+	.tundra .dojoxExpandoClosed {
+		background: none;
+		background-color: #fafafa;
+		border: 1px solid #ccc !important;
+	}
+	.tundra .dojoxExpandoRight .dojoxExpandoTitle,
+	.tundra .dojoxExpandoLeft .dojoxExpandoTitle,
+	.tundra .dojoxExpandoClosed .dojoxExpandoTitle,
+	.tundra .dojoxExpandoClosed {
+		background-color: #fafafa;
+	}
+	
+	.tundra .dojoxExpandoIcon {
+		background: url('../../../dijit/themes/tundra/images/minusButton.gif') no-repeat center center;
+		
+	}
+	.tundra .dojoxExpandoClosed .dojoxExpandoIcon {
+		background: url('../../../dijit/themes/tundra/images/plusButton.gif') no-repeat;
+		margin:3px;
+	}
+	
+	
+	.nihilo .dojoxExpandoPane {
+		background: #fafafa;
+	}
+	
+	.nihilo .dojoxExpandoTitle {
+		height:16px;
+		font-size:0.9em;
+		font-weight:bold;
+		padding:3px;
+		padding-top:6px;
+		padding-bottom:5px;
+		background:#fafafa url("../../../dijit/themes/nihilo/images/tabContainerSprite.gif") repeat-x scroll 0pt -50px;
+		border-left: 1px solid #ccc;
+		border-right: 1px solid #ccc;
+	}
+	
+	.nihilo .dojoxExpandoClosed .dojoxExpandoTitle {
+		background: none;
+		background-color: #fafafa;
+		border: none;
+	}
+	
+	.nihilo .dojoxExpandoClosed {
+		background: none;
+		background-color: #fafafa;
+		border: 1px solid #ccc !important;
+	}
+	
+	.nihilo .dojoxExpandoIcon {
+		background: url('../../../dijit/themes/nihilo/images/spriteRoundedIconsSmall.png') no-repeat center center;
+		background-position:-60px 0px;
+	}
+	
+	.nihilo .dojoxExpandoClosed .dojoxExpandoIcon {
+		background-position:0px 0px;
+	}
+	
+	.nihilo .dojoxExpandoTop {
+		border-bottom:1px solid #ccc;
+		border-left:1px solid #ccc;
+		border-right:1px solid #ccc; 
+	}
diff --git a/dojox/layout/resources/ExpandoPane.html b/dojox/layout/resources/ExpandoPane.html
new file mode 100644
index 0000000..d28222e
--- /dev/null
+++ b/dojox/layout/resources/ExpandoPane.html
@@ -0,0 +1,9 @@
+<div class="dojoxExpandoPane" dojoAttachEvent="ondblclick:toggle" >
+	<div dojoAttachPoint="titleWrapper" class="dojoxExpandoTitle">
+		<div class="dojoxExpandoIcon" dojoAttachPoint="iconNode" dojoAttachEvent="onclick:toggle"><span class="a11yNode">X</span></div>			
+		<span class="dojoxExpandoTitleNode" dojoAttachPoint="titleNode">${title}</span>
+	</div>
+	<div class="dojoxExpandoWrapper" dojoAttachPoint="cwrapper" dojoAttachEvent="ondblclick:_trap">
+		<div class="dojoxExpandoContent" dojoAttachPoint="containerNode"></div>
+	</div>
+</div>
\ No newline at end of file
diff --git a/dojox/layout/resources/FloatingPane.css b/dojox/layout/resources/FloatingPane.css
new file mode 100644
index 0000000..18ef1f7
--- /dev/null
+++ b/dojox/layout/resources/FloatingPane.css
@@ -0,0 +1,154 @@
+.dojoxFloatingPane {
+	background-color:#fff;
+	position:relative; 
+	border: 1px solid #dedede; 
+	overflow: hidden;
+	-webkit-box-shadow: 0px 5px 10px #adadad;
+}
+.dojoxFloatingPaneFg {
+	-webkit-box-shadow: 0px 8px 20px #525252;
+}
+.dojoxFloatingPaneTitle {
+	background: #cccccc;
+	background:#fafafa repeat-x bottom left;
+	border:1px solid #bfbfbf;
+	padding:4px 4px 2px 4px;
+	cursor: pointer;
+	white-space: nowrap;
+}
+.soria .dojoxFloatingPaneTitle {
+	background:#fff url("../../../dijit/themes/soria/images/titleBar.png") repeat-x top left;
+	border:1px solid #b1badf;
+	font-size: 0.9em;
+	font-weight: bold;
+	line-height:1.2em;
+}
+.tundra .dojoxFloatingPaneTitle {
+	background:#fafafa url("../../../dijit/themes/tundra/images/titleBarBg.gif") repeat-x bottom left;
+	border:1px solid #bfbfbf;
+	color:#000; 	
+}
+.dojoxFloatingCloseIcon {
+	background:url('../../../dijit/themes/tundra/images/tabClose.png') no-repeat center center; 
+	width:16px;
+	height:16px; 
+	overflow:hidden;
+	float:right; 
+}
+.dojoxFloatingMinimizeIcon {
+	background:url('../../../dijit/themes/tundra/images/spriteArrows.png') no-repeat 0px center; 
+	width:7px;
+	margin: 0px 4px;
+	overflow:hidden;
+	float:right; 
+}
+.soria .dojoxFloatingMinimizeIcon {
+	background:url("../../../dijit/themes/soria/images/spriteRoundedIconsSmallBl.png") no-repeat -15px top;
+	width: 14px;
+	margin: 0px 2px;
+}
+.floatingPaneMaximized .dojoxFloatingMaximizeIcon { display:none; }
+.dojoxFloatingMaximizeIcon {
+	background:url('../../../dijit/themes/tundra/images/spriteArrows.png') no-repeat -21px center;
+	width:7px;
+	margin: 0px 4px;
+	overflow:hidden;
+	float:right;	
+}
+.soria .dojoxFloatingMaximizeIcon {
+	background:url("../../../dijit/themes/soria/images/spriteRoundedIconsSmallBl.png") no-repeat -45px top;
+}
+.floatingPaneMaximized .dojoxFloatingRestoreIcon { display:inline; }
+.dojoxFloatingRestoreIcon {
+	background:url('../../../dijit/themes/tundra/images/spriteArrows.png') no-repeat 0px center; 
+	width:7px;
+	margin: 0px 4px;
+	float:right;
+	display:none;
+}
+.dojoxFloatingResizeHandle {
+	background:url('icons/resize.png') no-repeat bottom right;
+	position:absolute; 
+	right:0; 
+	bottom:0; 	
+	width:16px;
+	height:16px; 
+	cursor:nw-resize;
+}
+.dojoxFloatingCloseIcon {
+	width:15px;
+	height:15px; 
+	overflow:hidden;
+	float:right; 
+	cursor:pointer;
+}
+.soria .dojoxFloatingCloseIcon {
+	background:url("../../../dijit/themes/soria/images/spriteRoundedIconsSmallBl.png") no-repeat -60px top;
+}
+.tundra .dojoxFloatingCloseIcon {
+	background:url('../../../dijit/themes/tundra/images/tabClose.png') no-repeat center center; 	
+}
+.dojoxFloatingDockDefault {
+	position:absolute;
+	bottom:0px;
+	left:0px;
+	overflow:hidden; 
+	margin:0;
+	margin-bottom:3px; 
+	padding:0px; 
+	width:100%;
+	z-index:99; 
+	background:transparent;
+	
+}
+.dojoxDockList {
+	padding: 0px;
+	margin: 0px;
+}
+.dojoxDockRestoreButton {
+	background:url('../../../dijit/themes/tundra/images/arrowUp.png') no-repeat center center;
+	width:16px; height:16px;
+	overflow:hidden; 
+	float:left;
+	margin-top:2px; 
+}
+.soria .dojoxDockRestoreButton {
+	background:url("../../../dijit/themes/soria/images/spriteRoundedIconsSmallBl.png") no-repeat -45px top;
+}
+.dojoxDockTitleNode {
+	overflow:hidden;
+}
+.dojoxDock {
+	display: block;
+	border: 1px solid black;
+	position: absolute;
+	padding:0;
+	margin:0;
+	background:#fcfcfc;
+}
+.dojoxDockNode {
+	border: 1px solid #adadad;
+	border-radius: 2px;
+	-webkit-border-radius: 2px;
+	-moz-border-radius: 3px;
+	cursor:pointer; 
+	list-style: none;
+	padding: 2px;
+	margin: 0px;
+	height: 16px;
+	width: auto;
+	float: left;
+	background: #fafafa url("../../../dijit/themes/tundra/images/titleBarBg.gif") repeat-x bottom left;
+}
+.soria .dojoxDockNode {
+	background:#b7cdee url("../../../dijit/themes/soria/images/titleBar.png") repeat-x;
+}
+.dojoxFloatingPaneContent {
+	overflow: auto;
+	background-color: #fff; 
+	height: 100%; 
+	width:	100%; 
+}
+.dojoxFloatingPaneCanvas {
+	background-color:#fff;
+}
diff --git a/dojox/layout/resources/FloatingPane.html b/dojox/layout/resources/FloatingPane.html
new file mode 100644
index 0000000..d80a4e1
--- /dev/null
+++ b/dojox/layout/resources/FloatingPane.html
@@ -0,0 +1,14 @@
+<div class="dojoxFloatingPane" id="${id}">
+	<div tabindex="0" waiRole="button" class="dojoxFloatingPaneTitle" dojoAttachPoint="focusNode">
+		<span dojoAttachPoint="closeNode" dojoAttachEvent="onclick: close" class="dojoxFloatingCloseIcon"></span>
+		<span dojoAttachPoint="maxNode" dojoAttachEvent="onclick: maximize" class="dojoxFloatingMaximizeIcon"> </span>
+		<span dojoAttachPoint="restoreNode" dojoAttachEvent="onclick: _restore" class="dojoxFloatingRestoreIcon"> </span>	
+		<span dojoAttachPoint="dockNode" dojoAttachEvent="onclick: minimize" class="dojoxFloatingMinimizeIcon"> </span>
+		<span dojoAttachPoint="titleNode" class="dijitInline dijitTitleNode"></span>
+	</div>
+	<div dojoAttachPoint="canvas" class="dojoxFloatingPaneCanvas">
+		<div dojoAttachPoint="containerNode" waiRole="region" tabindex="-1" class="${contentClass}">
+		</div>
+		<span dojoAttachPoint="resizeHandle" class="dojoxFloatingResizeHandle"></span>
+	</div>
+</div>
diff --git a/dojox/layout/resources/GridContainer.css b/dojox/layout/resources/GridContainer.css
new file mode 100644
index 0000000..af0bd55
--- /dev/null
+++ b/dojox/layout/resources/GridContainer.css
@@ -0,0 +1,73 @@
+
+.gridContainer * {
+	zoom:1;
+}
+.oafDndHandle {
+	cursor: move;
+}
+.gridContainer {
+	display:block;	
+	position: relative;
+	background:#FFF;	
+	margin:0px;	
+	padding:10px;
+}
+	
+.gridContainer .dojoDndAvatarHeader	{
+	display:none;
+}
+.gridContainerTable {
+	width:100%;	
+	border:1px solid #F60;
+	height: 100%;
+}
+.gridContainerPopup {
+	position: absolute;
+	top:40%;
+	left:40%;
+	width: 200px;
+	height: auto;	
+	border: 1px solid #F60;
+	background-color: #FFF;
+	text-align: center;
+	padding: 10px;
+}
+.gridContainerTable tbody.gridContainerBody, .gridContainerTable tr.gridContainerRow {
+	height: 100%;
+}
+.gridContainerZone {
+	vertical-align: top;	
+	padding:12px;	
+	background-color: #FDFDFD;	 
+	height: 100%;
+}
+.gridContainerZone .serviceWidgetTitleText h2 {
+	position: relative;
+}
+.gridContainerGrip {
+	cursor:default;
+	position:absolute;	
+	width:5px;	
+	padding: 0px;	
+	margin:0px;
+	background-image: url(images/pixel.gif);
+	background-color: #ededed;
+}
+.tundra .gridContainerGrip {
+	border-left:1px solid #a7a7a7;
+	border-right:1px solid #a7a7a7;
+}
+	
+.gridContainerGripShow, .gridContainerGrip:focus {
+	cursor:e-resize;	
+	position:absolute;	
+	width:5px;	
+	padding:0px;	
+	margin:0px;
+	background-color: #a7a7a7;	
+	background-image: url(images/grip_bg.gif);
+}
+.tundra .gridContainerGripShow, .tundra .gridContainerGrid:focus {
+	border-left:1px solid #aeaeae;
+	border-right:1px solid #aeaeae;
+}
diff --git a/dojox/layout/resources/GridContainer.html b/dojox/layout/resources/GridContainer.html
new file mode 100644
index 0000000..f8a53e8
--- /dev/null
+++ b/dojox/layout/resources/GridContainer.html
@@ -0,0 +1,7 @@
+<div id="${id}" class="gridContainer" dojoAttachPoint="containerNode" tabIndex="0" dojoAttachEvent="onkeypress:_selectFocus">
+	<table class="gridContainerTable" dojoAttachPoint="gridContainerTable" cellspacing="0" cellpadding="0">
+		<tbody class="gridContainerBody">
+			<tr class="gridContainerRow" dojoAttachPoint="gridNode"></tr>
+		</tbody>
+	</table>
+</div>
\ No newline at end of file
diff --git a/dojox/layout/resources/RadioGroup.css b/dojox/layout/resources/RadioGroup.css
new file mode 100644
index 0000000..684fa36
--- /dev/null
+++ b/dojox/layout/resources/RadioGroup.css
@@ -0,0 +1,40 @@
+
+.dojoxRadioButtons {
+	margin:0; padding:4px;
+	width:100%;
+	outline:0;
+}
+.dojoxRadioButtons tbody  {
+	margin:0; padding:0;
+	width:100%;
+}
+.dojoxRadioButton {
+	text-align:center;
+	cursor:pointer;
+	margin:0;
+}
+.dojoxRadioButtonSelected {
+	border:1px solid #ededed;
+}
+.tundra .dojoxRadioButtonSelected {
+	border:1px solid #a0a0a0;
+	background:#b7b7b7;
+}
+.soria .dojoxRadioButtonSelected {
+	background:#b7cdee url('../../../dijit/themes/soria/images/gradientTopBg.png') repeat-x top center;
+}
+.dojoxRadioButtonLabel {
+	padding:8px;
+	text-align:center;
+	display:block;
+}
+.dojoxRadioGroup {
+	overflow:hidden;
+	border:0;
+	margin:0; padding:0;
+}
+.dojoxRadioView {
+	position:relative;
+	overflow:hidden;
+	height:100%;
+}
diff --git a/dojox/layout/resources/ResizeHandle.css b/dojox/layout/resources/ResizeHandle.css
new file mode 100644
index 0000000..b68f2d4
--- /dev/null
+++ b/dojox/layout/resources/ResizeHandle.css
@@ -0,0 +1,28 @@
+.dojoxResizeHandle {
+	float: right;
+	position: absolute;
+	right: 2px;
+	bottom: 2px;
+	width: 13px;
+	height: 13px;
+	z-index: 20;
+	background-image: url('icons/resize.png');
+	line-height: 0px;
+}
+.dojoxResizeNW {
+	cursor: nw-resize;
+}
+.dojoxResizeNE {
+	cursor: ne-resize; 
+}
+.dojoxResizeW {
+	cursor: w-resize; 
+}
+.dojoxResizeN { 
+	cursor: n-resize; 
+}
+.dojoxResizeHandleClone {
+	position:absolute; top:0; left:0; 
+	border:1px dashed #666; 
+	z-index:999; 
+}
diff --git a/dojox/layout/resources/RotatorContainer.css b/dojox/layout/resources/RotatorContainer.css
new file mode 100644
index 0000000..b370ff8
--- /dev/null
+++ b/dojox/layout/resources/RotatorContainer.css
@@ -0,0 +1,82 @@
+.dojoxRotatorContainer .dijitStackController,
+.dojoxRotatorPager {
+	position:absolute;
+	z-index:3;
+}
+.dojoxRotatorContent {
+	position:absolute;
+	z-index:1;
+}
+.dojoxRotatorContainer {
+	border:1px solid #9b9b9b;
+}
+.dojoxRotatorContainer .dijitStackController {
+	right:5px;
+	top:5px;
+}
+.dojoxRotatorContainer .dijitStackController .dijitToggleButtonChecked .dijitButtonNode {
+	background-color:#000;
+	background-image:none;
+	color:#fff;
+}
+.dojoxRotatorContainer .dojoxRotatorPager {
+	bottom:5px;
+	right:5px;
+}
+.tundra .rotatorIcons .dijitButtonText {
+	display:none;
+}
+.tundra .rotatorIcons button,
+.tundra .rotatorIcons .dijitButtonHover button,
+.tundra .rotatorIcons .dijitButtonActive button,
+.tundra .rotatorIcons .dijitToggleButtonHover button,
+.tundra .rotatorIcons .dijitToggleButtonActive button {
+	background:none;
+	border:0;
+}
+.tundra .rotatorIcons .previous,
+.tundra .rotatorIcons .next,
+.tundra .rotatorIcons .playPause,
+.tundra .rotatorIcons .dijitToggleButtonChecked .playPause {
+	background-image:url("icons/rotator.png");
+	background-repeat:no-repeat;
+	display:block;
+	height:16px;
+	width:16px;
+}
+.tundra .rotatorIcons .previous {
+	background-position:0 0;
+}
+.tundra .rotatorIcons .dijitButtonHover .previous { 
+	background-position:0 -16px;
+}
+.tundra .rotatorIcons .dijitButtonActive .previous { 
+	background-position:0 -32px;
+}
+.tundra .rotatorIcons .next{
+	background-position:-16px 0;
+}
+.tundra .rotatorIcons .dijitButtonHover .next{ 
+	background-position:-16px -16px;
+}
+.tundra .rotatorIcons .dijitButtonActive .next{ 
+	background-position:-16px -32px;
+}
+.tundra .rotatorIcons .playPause{
+	background-position:-32px 0;
+}
+.tundra .rotatorIcons .dijitToggleButtonHover .playPause{ 
+	background-position:-32px -16px;
+}
+.tundra .rotatorIcons .dijitToggleButtonActive .playPause {
+	background-position:-32px -32px;
+}
+.tundra .rotatorIcons .dijitToggleButtonChecked .playPause {
+	background-position:-48px 0;
+}
+.tundra .rotatorIcons .dijitToggleButtonCheckedHover .playPause {
+	background-position:-48px -16px;
+}
+.tundra .rotatorIcons .dijitToggleButtonCheckedActive .playPause { 
+	background-position:-48px -32px;
+}
diff --git a/dojox/layout/resources/ScrollPane.css b/dojox/layout/resources/ScrollPane.css
new file mode 100644
index 0000000..6aaa36a
--- /dev/null
+++ b/dojox/layout/resources/ScrollPane.css
@@ -0,0 +1,21 @@
+.dojoxScrollWindow {
+	position:relative;
+	overflow:hidden;
+}
+.dojoxScrollHelper .helperInner {
+	visibility: hidden;
+}
+.dojoxScrollHelper {
+	border:1px solid #b7b7b7;
+	width:4px;
+	background:#ededed;
+	height:4px;
+	position:absolute;
+	top:4px;
+	left:4px;
+	border-radius: 3px;
+	-moz-border-radius: 3px;
+	-webkit-border-radius: 3px;
+}
+.dojoxScrollWrapper {
+}
diff --git a/dojox/layout/resources/ScrollPane.html b/dojox/layout/resources/ScrollPane.html
new file mode 100644
index 0000000..4b3df77
--- /dev/null
+++ b/dojox/layout/resources/ScrollPane.html
@@ -0,0 +1,6 @@
+<div class="dojoxScrollWindow" dojoAttachEvent="onmouseenter: _enter, onmouseleave: _leave">
+    <div class="dojoxScrollWrapper" style="${style}" dojoAttachPoint="wrapper" dojoAttachEvent="onmousemove: _calc">
+	<div class="dojoxScrollPane" dojoAttachPoint="containerNode"></div>
+    </div>
+    <div dojoAttachPoint="helper" class="dojoxScrollHelper"><span class="helperInner">|</span></div>
+</div>
\ No newline at end of file
diff --git a/dojox/layout/resources/ToggleSplitter.css b/dojox/layout/resources/ToggleSplitter.css
new file mode 100644
index 0000000..5a1f32d
--- /dev/null
+++ b/dojox/layout/resources/ToggleSplitter.css
@@ -0,0 +1,80 @@
+.dijitBorderContainer .dojoxToggleSplitterTop,
+.dijitBorderContainer .dojoxToggleSplitterBottom {
+	height:16px;
+}
+.dijitBorderContainer .dojoxToggleSplitterLeft,
+.dijitBorderContainer .dojoxToggleSplitterRight {
+	width:16px;
+}
+.dijitBorderContainer .dijitSplitterH .dojoxToggleSplitterIcon {
+	width:16px;
+	height:16px;
+	top: 0;
+	cursor: pointer;
+}
+.dijitBorderContainer .dijitSplitterV .dojoxToggleSplitterIcon {
+	width:16px;
+	height:16px;
+	left: 0;
+	cursor: pointer;
+}
+.tundra .dojoxToggleSplitterTop .dojoxToggleSplitterIconOpen, 
+.tundra .dojoxToggleSplitterBottom .dojoxToggleSplitterIconClosed 
+ {
+	background: transparent url('../../../dijit/themes/tundra/images/spriteRoundedIconsSmall.png') no-repeat -45px 50%;
+}
+.tundra .dojoxToggleSplitterBottom .dojoxToggleSplitterIconOpen, 
+.tundra .dojoxToggleSplitterTop .dojoxToggleSplitterIconClosed 
+ {
+	background: transparent url('../../../dijit/themes/tundra/images/spriteRoundedIconsSmall.png') no-repeat -15px 50%;
+}
+.tundra .dojoxToggleSplitterLeft .dojoxToggleSplitterIconOpen, 
+.tundra .dojoxToggleSplitterRight .dojoxToggleSplitterIconClosed 
+ {
+	background: transparent url('../../../dijit/themes/tundra/images/spriteRoundedIconsSmall.png') no-repeat 0px 50%;
+}
+.tundra .dojoxToggleSplitterRight .dojoxToggleSplitterIconOpen, 
+.tundra .dojoxToggleSplitterLeft .dojoxToggleSplitterIconClosed 
+ {
+	background: transparent url('../../../dijit/themes/tundra/images/spriteRoundedIconsSmall.png') no-repeat -30px 50%;
+}
+.soria .dojoxToggleSplitterTop .dojoxToggleSplitterIconOpen, 
+.soria .dojoxToggleSplitterBottom .dojoxToggleSplitterIconClosed 
+ {
+	background: transparent url('../../../dijit/themes/soria/images/spriteRoundedIconsSmall.png') no-repeat -45px 50%;
+}
+.soria .dojoxToggleSplitterBottom .dojoxToggleSplitterIconOpen, 
+.soria .dojoxToggleSplitterTop .dojoxToggleSplitterIconClosed 
+ {
+	background: transparent url('../../../dijit/themes/soria/images/spriteRoundedIconsSmall.png') no-repeat -15px 50%;
+}
+.soria .dojoxToggleSplitterLeft .dojoxToggleSplitterIconOpen, 
+.soria .dojoxToggleSplitterRight .dojoxToggleSplitterIconClosed 
+ {
+	background: transparent url('../../../dijit/themes/soria/images/spriteRoundedIconsSmall.png') no-repeat 0px 50%;
+}
+.soria .dojoxToggleSplitterRight .dojoxToggleSplitterIconOpen, 
+.soria .dojoxToggleSplitterLeft .dojoxToggleSplitterIconClosed 
+ {
+	background: transparent url('../../../dijit/themes/soria/images/spriteRoundedIconsSmall.png') no-repeat -30px 50%;
+}
+.nihilo .dojoxToggleSplitterTop .dojoxToggleSplitterIconOpen, 
+.nihilo .dojoxToggleSplitterBottom .dojoxToggleSplitterIconClosed 
+ {
+	background: transparent url('../../../dijit/themes/nihilo/images/spriteRoundedIconsSmall.png') no-repeat -45px 50%;
+}
+.nihilo .dojoxToggleSplitterBottom .dojoxToggleSplitterIconOpen, 
+.nihilo .dojoxToggleSplitterTop .dojoxToggleSplitterIconClosed 
+ {
+	background: transparent url('../../../dijit/themes/nihilo/images/spriteRoundedIconsSmall.png') no-repeat -15px 50%;
+}
+.nihilo .dojoxToggleSplitterLeft .dojoxToggleSplitterIconOpen, 
+.nihilo .dojoxToggleSplitterRight .dojoxToggleSplitterIconClosed 
+ {
+	background: transparent url('../../../dijit/themes/nihilo/images/spriteRoundedIconsSmall.png') no-repeat 0px 50%;
+}
+.nihilo .dojoxToggleSplitterRight .dojoxToggleSplitterIconOpen, 
+.nihilo .dojoxToggleSplitterLeft .dojoxToggleSplitterIconClosed 
+ {
+	background: transparent url('../../../dijit/themes/nihilo/images/spriteRoundedIconsSmall.png') no-repeat -30px 50%;
+}
diff --git a/dojox/layout/resources/icons/grip_bg.gif b/dojox/layout/resources/icons/grip_bg.gif
new file mode 100644
index 0000000..45f76ce
Binary files /dev/null and b/dojox/layout/resources/icons/grip_bg.gif differ
diff --git a/dojox/layout/resources/icons/pixel.gif b/dojox/layout/resources/icons/pixel.gif
new file mode 100644
index 0000000..3be2119
Binary files /dev/null and b/dojox/layout/resources/icons/pixel.gif differ
diff --git a/dojox/layout/resources/icons/resize.png b/dojox/layout/resources/icons/resize.png
new file mode 100644
index 0000000..17f39d0
Binary files /dev/null and b/dojox/layout/resources/icons/resize.png differ
diff --git a/dojox/layout/resources/icons/rotator.png b/dojox/layout/resources/icons/rotator.png
new file mode 100644
index 0000000..ad93ee5
Binary files /dev/null and b/dojox/layout/resources/icons/rotator.png differ
diff --git a/dojox/math.js b/dojox/math.js
new file mode 100644
index 0000000..8bdd2dd
--- /dev/null
+++ b/dojox/math.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.math"]){
+dojo._hasResource["dojox.math"]=true;
+dojo.provide("dojox.math");
+dojo.require("dojox.math._base");
+}
diff --git a/dojox/math/README b/dojox/math/README
new file mode 100644
index 0000000..645e55b
--- /dev/null
+++ b/dojox/math/README
@@ -0,0 +1,38 @@
+-------------------------------------------------------------------------------
+DojoX Math
+-------------------------------------------------------------------------------
+Version 0.9
+Release date: 10/20/2007
+-------------------------------------------------------------------------------
+Project state:
+experimental
+-------------------------------------------------------------------------------
+Credits
+	Cal Henderson
+	Dan Pupius
+	Tom Trenka (ttrenka AT gmail.com)
+-------------------------------------------------------------------------------
+Project description
+
+A port of the main functionality of dojo.math 0.4.  Includes advanced math
+functions, abstract curve definitions, and some point calculations.
+-------------------------------------------------------------------------------
+Dependencies:
+
+Depends on the Dojo Core, v1.0
+-------------------------------------------------------------------------------
+Documentation
+
+See the API documentation.
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/math.js
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/math/*
+
+Install into the following directory structure:
+/dojox/math/
+
+...which should be at the same level as your Dojo checkout.
+-------------------------------------------------------------------------------
diff --git a/dojox/math/_base.js b/dojox/math/_base.js
new file mode 100644
index 0000000..0b56225
--- /dev/null
+++ b/dojox/math/_base.js
@@ -0,0 +1,88 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.math._base"]){
+dojo._hasResource["dojox.math._base"]=true;
+dojo.provide("dojox.math._base");
+dojo.mixin(dojox.math,{degreesToRadians:function(n){
+return (n*Math.PI)/180;
+},radiansToDegrees:function(n){
+return (n*180)/Math.PI;
+},factorial:function(n){
+if(n===0){
+return 1;
+}else{
+if(n<0||Math.floor(n)!=n){
+return NaN;
+}
+}
+var _4=1;
+for(var i=1;i<=n;i++){
+_4*=i;
+}
+return _4;
+},permutations:function(n,k){
+if(n==0||k==0){
+return 1;
+}
+return this.factorial(n)/this.factorial(n-k);
+},combinations:function(n,r){
+if(n==0||r==0){
+return 1;
+}
+return this.factorial(n)/(this.factorial(n-r)*this.factorial(r));
+},bernstein:function(t,n,i){
+return this.combinations(n,i)*Math.pow(t,i)*Math.pow(1-t,n-i);
+},gaussian:function(){
+var k=2;
+do{
+var i=2*Math.random()-1;
+var j=2*Math.random()-1;
+k=i*i+j*j;
+}while(k>=1);
+return i*Math.sqrt((-2*Math.log(k))/k);
+},sd:function(a){
+return Math.sqrt(this.variance(a));
+},variance:function(a){
+var _12=0,_13=0;
+dojo.forEach(a,function(_14){
+_12+=_14;
+_13+=Math.pow(_14,2);
+});
+return (_13/a.length)-Math.pow(_12/a.length,2);
+},range:function(a,b,_17){
+if(arguments.length<2){
+b=a,a=0;
+}
+var _18=[],s=_17||1,i;
+if(s>0){
+for(i=a;i<b;i+=s){
+_18.push(i);
+}
+}else{
+if(s<0){
+for(i=a;i>b;i+=s){
+_18.push(i);
+}
+}else{
+throw new Error("dojox.math.range: step must not be zero.");
+}
+}
+return _18;
+},distance:function(a,b){
+return Math.sqrt(Math.pow(b[0]-a[0],2)+Math.pow(b[1]-a[1],2));
+},midpoint:function(a,b){
+if(a.length!=b.length){
+console.error("dojox.math.midpoint: Points A and B are not the same dimensionally.",a,b);
+}
+var m=[];
+for(var i=0;i<a.length;i++){
+m[i]=(a[i]+b[i])/2;
+}
+return m;
+}});
+}
diff --git a/dojox/math/curves.js b/dojox/math/curves.js
new file mode 100644
index 0000000..d376d5a
--- /dev/null
+++ b/dojox/math/curves.js
@@ -0,0 +1,194 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.math.curves"]){
+dojo._hasResource["dojox.math.curves"]=true;
+dojo.provide("dojox.math.curves");
+dojo.mixin(dojox.math.curves,{Line:function(_1,_2){
+this.start=_1;
+this.end=_2;
+this.dimensions=_1.length;
+for(var i=0;i<_1.length;i++){
+_1[i]=Number(_1[i]);
+}
+for(var i=0;i<_2.length;i++){
+_2[i]=Number(_2[i]);
+}
+this.getValue=function(n){
+var _5=new Array(this.dimensions);
+for(var i=0;i<this.dimensions;i++){
+_5[i]=((this.end[i]-this.start[i])*n)+this.start[i];
+}
+return _5;
+};
+return this;
+},Bezier:function(_7){
+this.getValue=function(_8){
+if(_8>=1){
+return this.p[this.p.length-1];
+}
+if(_8<=0){
+return this.p[0];
+}
+var _9=new Array(this.p[0].length);
+for(var k=0;j<this.p[0].length;k++){
+_9[k]=0;
+}
+for(var j=0;j<this.p[0].length;j++){
+var C=0;
+var D=0;
+for(var i=0;i<this.p.length;i++){
+C+=this.p[i][j]*this.p[this.p.length-1][0]*dojox.math.bernstein(_8,this.p.length,i);
+}
+for(var l=0;l<this.p.length;l++){
+D+=this.p[this.p.length-1][0]*dojox.math.bernstein(_8,this.p.length,l);
+}
+_9[j]=C/D;
+}
+return _9;
+};
+this.p=_7;
+return this;
+},CatmullRom:function(_10,c){
+this.getValue=function(_12){
+var _13=_12*(this.p.length-1);
+var _14=Math.floor(_13);
+var _15=_13-_14;
+var i0=_14-1;
+if(i0<0){
+i0=0;
+}
+var i=_14;
+var i1=_14+1;
+if(i1>=this.p.length){
+i1=this.p.length-1;
+}
+var i2=_14+2;
+if(i2>=this.p.length){
+i2=this.p.length-1;
+}
+var u=_15;
+var u2=_15*_15;
+var u3=_15*_15*_15;
+var _1d=new Array(this.p[0].length);
+for(var k=0;k<this.p[0].length;k++){
+var x1=(-this.c*this.p[i0][k])+((2-this.c)*this.p[i][k])+((this.c-2)*this.p[i1][k])+(this.c*this.p[i2][k]);
+var x2=(2*this.c*this.p[i0][k])+((this.c-3)*this.p[i][k])+((3-2*this.c)*this.p[i1][k])+(-this.c*this.p[i2][k]);
+var x3=(-this.c*this.p[i0][k])+(this.c*this.p[i1][k]);
+var x4=this.p[i][k];
+_1d[k]=x1*u3+x2*u2+x3*u+x4;
+}
+return _1d;
+};
+if(!c){
+this.c=0.7;
+}else{
+this.c=c;
+}
+this.p=_10;
+return this;
+},Arc:function(_23,end,ccw){
+function _26(a,b){
+var c=new Array(a.length);
+for(var i=0;i<a.length;i++){
+c[i]=a[i]+b[i];
+}
+return c;
+};
+function _2b(a){
+var b=new Array(a.length);
+for(var i=0;i<a.length;i++){
+b[i]=-a[i];
+}
+return b;
+};
+var _2f=dojox.math.midpoint(_23,end);
+var _30=_26(_2b(_2f),_23);
+var rad=Math.sqrt(Math.pow(_30[0],2)+Math.pow(_30[1],2));
+var _32=dojox.math.radiansToDegrees(Math.atan(_30[1]/_30[0]));
+if(_30[0]<0){
+_32-=90;
+}else{
+_32+=90;
+}
+dojox.math.curves.CenteredArc.call(this,_2f,rad,_32,_32+(ccw?-180:180));
+},CenteredArc:function(_33,_34,_35,end){
+this.center=_33;
+this.radius=_34;
+this.start=_35||0;
+this.end=end;
+this.getValue=function(n){
+var _38=new Array(2);
+var _39=dojox.math.degreesToRadians(this.start+((this.end-this.start)*n));
+_38[0]=this.center[0]+this.radius*Math.sin(_39);
+_38[1]=this.center[1]-this.radius*Math.cos(_39);
+return _38;
+};
+return this;
+},Circle:function(_3a,_3b){
+dojox.math.curves.CenteredArc.call(this,_3a,_3b,0,360);
+return this;
+},Path:function(){
+var _3c=[];
+var _3d=[];
+var _3e=[];
+var _3f=0;
+this.add=function(_40,_41){
+if(_41<0){
+console.error("dojox.math.curves.Path.add: weight cannot be less than 0");
+}
+_3c.push(_40);
+_3d.push(_41);
+_3f+=_41;
+_42();
+};
+this.remove=function(_43){
+for(var i=0;i<_3c.length;i++){
+if(_3c[i]==_43){
+_3c.splice(i,1);
+_3f-=_3d.splice(i,1)[0];
+break;
+}
+}
+_42();
+};
+this.removeAll=function(){
+_3c=[];
+_3d=[];
+_3f=0;
+};
+this.getValue=function(n){
+var _46=false,_47=0;
+for(var i=0;i<_3e.length;i++){
+var r=_3e[i];
+if(n>=r[0]&&n<r[1]){
+var _4a=(n-r[0])/r[2];
+_47=_3c[i].getValue(_4a);
+_46=true;
+break;
+}
+}
+if(!_46){
+_47=_3c[_3c.length-1].getValue(1);
+}
+for(var j=0;j<i;j++){
+_47=dojox.math.points.translate(_47,_3c[j].getValue(1));
+}
+return _47;
+};
+function _42(){
+var _4c=0;
+for(var i=0;i<_3d.length;i++){
+var end=_4c+_3d[i]/_3f;
+var len=end-_4c;
+_3e[i]=[_4c,end,len];
+_4c=end;
+}
+};
+return this;
+}});
+}
diff --git a/dojox/math/matrix.js b/dojox/math/matrix.js
new file mode 100644
index 0000000..fbb3840
--- /dev/null
+++ b/dojox/math/matrix.js
@@ -0,0 +1,251 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.math.matrix"]){
+dojo._hasResource["dojox.math.matrix"]=true;
+dojo.provide("dojox.math.matrix");
+dojo.mixin(dojox.math.matrix,{iDF:0,ALMOST_ZERO:1e-10,multiply:function(a,b){
+var ay=a.length,ax=a[0].length,by=b.length,bx=b[0].length;
+if(ax!=by){
+console.warn("Can't multiply matricies of sizes "+ax+","+ay+" and "+bx+","+by);
+return [[0]];
+}
+var c=[];
+for(var k=0;k<ay;k++){
+c[k]=[];
+for(var i=0;i<bx;i++){
+c[k][i]=0;
+for(var m=0;m<ax;m++){
+c[k][i]+=a[k][m]*b[m][i];
+}
+}
+}
+return c;
+},product:function(){
+if(arguments.length==0){
+console.warn("can't multiply 0 matrices!");
+return 1;
+}
+var m=arguments[0];
+for(var i=1;i<arguments.length;i++){
+m=this.multiply(m,arguments[i]);
+}
+return m;
+},sum:function(){
+if(arguments.length==0){
+console.warn("can't sum 0 matrices!");
+return 0;
+}
+var m=this.copy(arguments[0]);
+var _e=m.length;
+if(_e==0){
+console.warn("can't deal with matrices of 0 rows!");
+return 0;
+}
+var _f=m[0].length;
+if(_f==0){
+console.warn("can't deal with matrices of 0 cols!");
+return 0;
+}
+for(var i=1;i<arguments.length;++i){
+var arg=arguments[i];
+if(arg.length!=_e||arg[0].length!=_f){
+console.warn("can't add matrices of different dimensions: first dimensions were "+_e+"x"+_f+", current dimensions are "+arg.length+"x"+arg[0].length);
+return 0;
+}
+for(var r=0;r<_e;r++){
+for(var c=0;c<_f;c++){
+m[r][c]+=arg[r][c];
+}
+}
+}
+return m;
+},inverse:function(a){
+if(a.length==1&&a[0].length==1){
+return [[1/a[0][0]]];
+}
+var tms=a.length,m=this.create(tms,tms),mm=this.adjoint(a),det=this.determinant(a),dd=0;
+if(det==0){
+console.warn("Determinant Equals 0, Not Invertible.");
+return [[0]];
+}else{
+dd=1/det;
+}
+for(var i=0;i<tms;i++){
+for(var j=0;j<tms;j++){
+m[i][j]=dd*mm[i][j];
+}
+}
+return m;
+},determinant:function(a){
+if(a.length!=a[0].length){
+console.warn("Can't calculate the determinant of a non-squre matrix!");
+return 0;
+}
+var tms=a.length,det=1,b=this.upperTriangle(a);
+for(var i=0;i<tms;i++){
+var bii=b[i][i];
+if(Math.abs(bii)<this.ALMOST_ZERO){
+return 0;
+}
+det*=bii;
+}
+det*=this.iDF;
+return det;
+},upperTriangle:function(m){
+m=this.copy(m);
+var f1=0,_24=0,tms=m.length,v=1;
+this.iDF=1;
+for(var col=0;col<tms-1;col++){
+if(typeof m[col][col]!="number"){
+console.warn("non-numeric entry found in a numeric matrix: m["+col+"]["+col+"]="+m[col][col]);
+}
+v=1;
+var _28=0;
+while((m[col][col]==0)&&!_28){
+if(col+v>=tms){
+this.iDF=0;
+_28=1;
+}else{
+for(var r=0;r<tms;r++){
+_24=m[col][r];
+m[col][r]=m[col+v][r];
+m[col+v][r]=_24;
+}
+v++;
+this.iDF*=-1;
+}
+}
+for(var row=col+1;row<tms;row++){
+if(typeof m[row][col]!="number"){
+console.warn("non-numeric entry found in a numeric matrix: m["+row+"]["+col+"]="+m[row][col]);
+}
+if(typeof m[col][row]!="number"){
+console.warn("non-numeric entry found in a numeric matrix: m["+col+"]["+row+"]="+m[col][row]);
+}
+if(m[col][col]!=0){
+var f1=(-1)*m[row][col]/m[col][col];
+for(var i=col;i<tms;i++){
+m[row][i]=f1*m[col][i]+m[row][i];
+}
+}
+}
+}
+return m;
+},create:function(a,b,_2e){
+_2e=_2e||0;
+var m=[];
+for(var i=0;i<b;i++){
+m[i]=[];
+for(var j=0;j<a;j++){
+m[i][j]=_2e;
+}
+}
+return m;
+},ones:function(a,b){
+return this.create(a,b,1);
+},zeros:function(a,b){
+return this.create(a,b);
+},identity:function(_36,_37){
+_37=_37||1;
+var m=[];
+for(var i=0;i<_36;i++){
+m[i]=[];
+for(var j=0;j<_36;j++){
+m[i][j]=(i==j?_37:0);
+}
+}
+return m;
+},adjoint:function(a){
+var tms=a.length;
+if(tms<=1){
+console.warn("Can't find the adjoint of a matrix with a dimension less than 2");
+return [[0]];
+}
+if(a.length!=a[0].length){
+console.warn("Can't find the adjoint of a non-square matrix");
+return [[0]];
+}
+var m=this.create(tms,tms),ap=this.create(tms-1,tms-1);
+var ii=0,jj=0,ia=0,ja=0,det=0;
+for(var i=0;i<tms;i++){
+for(var j=0;j<tms;j++){
+ia=0;
+for(ii=0;ii<tms;ii++){
+if(ii==i){
+continue;
+}
+ja=0;
+for(jj=0;jj<tms;jj++){
+if(jj==j){
+continue;
+}
+ap[ia][ja]=a[ii][jj];
+ja++;
+}
+ia++;
+}
+det=this.determinant(ap);
+m[i][j]=Math.pow(-1,(i+j))*det;
+}
+}
+return this.transpose(m);
+},transpose:function(a){
+var m=this.create(a.length,a[0].length);
+for(var i=0;i<a.length;i++){
+for(var j=0;j<a[i].length;j++){
+m[j][i]=a[i][j];
+}
+}
+return m;
+},format:function(a,_4b){
+_4b=_4b||5;
+function _4c(x,dp){
+var fac=Math.pow(10,dp);
+var a=Math.round(x*fac)/fac;
+var b=a.toString();
+if(b.charAt(0)!="-"){
+b=" "+b;
+}
+if(b.indexOf(".")>-1){
+b+=".";
+}
+while(b.length<dp+3){
+b+="0";
+}
+return b;
+};
+var ya=a.length;
+var xa=ya>0?a[0].length:0;
+var _54="";
+for(var y=0;y<ya;y++){
+_54+="| ";
+for(var x=0;x<xa;x++){
+_54+=_4c(a[y][x],_4b)+" ";
+}
+_54+="|\n";
+}
+return _54;
+},copy:function(a){
+var ya=a.length,xa=a[0].length,m=this.create(xa,ya);
+for(var y=0;y<ya;y++){
+for(var x=0;x<xa;x++){
+m[y][x]=a[y][x];
+}
+}
+return m;
+},scale:function(a,_5e){
+a=this.copy(a);
+var ya=a.length,xa=a[0].length;
+for(var y=0;y<ya;y++){
+for(var x=0;x<xa;x++){
+a[y][x]*=_5e;
+}
+}
+return a;
+}});
+}
diff --git a/dojox/math/round.js b/dojox/math/round.js
new file mode 100644
index 0000000..e28ddfb
--- /dev/null
+++ b/dojox/math/round.js
@@ -0,0 +1,30 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.math.round"]){
+dojo._hasResource["dojox.math.round"]=true;
+dojo.provide("dojox.math.round");
+dojo.experimental("dojox.math.round");
+dojox.math.round=function(_1,_2,_3){
+var _4=Math.log(Math.abs(_1))/Math.log(10);
+var _5=10/(_3||10);
+var _6=Math.pow(10,-15+_4);
+return (_5*(+_1+(_1>0?_6:-_6))).toFixed(_2)/_5;
+};
+if((0.9).toFixed()==0){
+(function(){
+var _7=dojox.math.round;
+dojox.math.round=function(v,p,m){
+var d=Math.pow(10,-p||0),a=Math.abs(v);
+if(!v||a>=d||a*Math.pow(10,p+1)<5){
+d=0;
+}
+return _7(v,p,m)+(v>0?d:-d);
+};
+})();
+}
+}
diff --git a/dojox/off.js b/dojox/off.js
new file mode 100644
index 0000000..ebe18cd
--- /dev/null
+++ b/dojox/off.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.off"]){
+dojo._hasResource["dojox.off"]=true;
+dojo.provide("dojox.off");
+dojo.require("dojox.off._common");
+}
diff --git a/dojox/off/README b/dojox/off/README
new file mode 100644
index 0000000..cede939
--- /dev/null
+++ b/dojox/off/README
@@ -0,0 +1,28 @@
+-------------------------------------------------------------------------------
+Dojo Offline
+-------------------------------------------------------------------------------
+Release date: May 2007 (Release date used as version)
+-------------------------------------------------------------------------------
+Project state:
+experimental
+-------------------------------------------------------------------------------
+Credits
+	Brad Neuberg
+	SitePen
+-------------------------------------------------------------------------------
+Project description
+Toolkit to help build offline web applications; uses Google Gears under the covers.
+-------------------------------------------------------------------------------
+Dependencies:
+Dojo Storage, Dojo Crypto, Dojo Core, Google Gears
+-------------------------------------------------------------------------------
+Documentation
+
+See http://docs.google.com/View?docid=dhkhksk4_8gdp9gr for documentation and a t
+utorial on using Dojo Offline.
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+See full documentation at URL given right above.
+-------------------------------------------------------------------------------
diff --git a/dojox/off/_common.js b/dojox/off/_common.js
new file mode 100644
index 0000000..4a279d0
--- /dev/null
+++ b/dojox/off/_common.js
@@ -0,0 +1,178 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.off._common"]){
+dojo._hasResource["dojox.off._common"]=true;
+dojo.provide("dojox.off._common");
+dojo.require("dojo.gears");
+dojo.require("dojox.storage");
+dojo.require("dojox.sql");
+dojo.require("dojox.off.sync");
+dojo.mixin(dojox.off,{isOnline:false,NET_CHECK:5,STORAGE_NAMESPACE:"_dot",enabled:true,availabilityURL:dojo.moduleUrl("dojox","off/network_check.txt"),goingOnline:false,coreOpFailed:false,doNetChecking:true,hasOfflineCache:null,browserRestart:false,_STORAGE_APP_NAME:window.location.href.replace(/[^0-9A-Za-z_]/g,"_"),_initializeCalled:false,_storageLoaded:false,_pageLoaded:false,onLoad:function(){
+},onNetwork:function(_1){
+},initialize:function(){
+this._initializeCalled=true;
+if(this._storageLoaded&&this._pageLoaded){
+this._onLoad();
+}
+},goOffline:function(){
+if((dojox.off.sync.isSyncing)||(this.goingOnline)){
+return;
+}
+this.goingOnline=false;
+this.isOnline=false;
+},goOnline:function(_2){
+if(dojox.off.sync.isSyncing||dojox.off.goingOnline){
+return;
+}
+this.goingOnline=true;
+this.isOnline=false;
+this._isSiteAvailable(_2);
+},onFrameworkEvent:function(_3,_4){
+if(_3=="save"){
+if(_4.isCoreSave&&(_4.status==dojox.storage.FAILED)){
+dojox.off.coreOpFailed=true;
+dojox.off.enabled=false;
+dojox.off.onFrameworkEvent("coreOperationFailed");
+}
+}else{
+if(_3=="coreOperationFailed"){
+dojox.off.coreOpFailed=true;
+dojox.off.enabled=false;
+}
+}
+},_checkOfflineCacheAvailable:function(_5){
+this.hasOfflineCache=dojo.gears.available;
+_5();
+},_onLoad:function(){
+dojox.off.files.cache(dojo.moduleUrl("dojo","dojo.js"));
+this._cacheDojoResources();
+dojox.off.files.cache(dojox.storage.manager.getResourceList());
+dojox.off.files._slurp();
+this._checkOfflineCacheAvailable(dojo.hitch(this,"_onOfflineCacheChecked"));
+},_onOfflineCacheChecked:function(){
+if(this.hasOfflineCache&&this.enabled){
+this._load(dojo.hitch(this,"_finishStartingUp"));
+}else{
+if(this.hasOfflineCache&&!this.enabled){
+this._finishStartingUp();
+}else{
+this._keepCheckingUntilInstalled();
+}
+}
+},_keepCheckingUntilInstalled:function(){
+this._finishStartingUp();
+},_finishStartingUp:function(){
+if(!this.hasOfflineCache){
+this.onLoad();
+}else{
+if(this.enabled){
+this._startNetworkThread();
+this.goOnline(dojo.hitch(this,function(){
+dojox.off.onLoad();
+}));
+}else{
+if(this.coreOpFailed){
+this.onFrameworkEvent("coreOperationFailed");
+}else{
+this.onLoad();
+}
+}
+}
+},_onPageLoad:function(){
+this._pageLoaded=true;
+if(this._storageLoaded&&this._initializeCalled){
+this._onLoad();
+}
+},_onStorageLoad:function(){
+this._storageLoaded=true;
+if(!dojox.storage.manager.isAvailable()&&dojox.storage.manager.isInitialized()){
+this.coreOpFailed=true;
+this.enabled=false;
+}
+if(this._pageLoaded&&this._initializeCalled){
+this._onLoad();
+}
+},_isSiteAvailable:function(_6){
+dojo.xhrGet({url:this._getAvailabilityURL(),handleAs:"text",timeout:this.NET_CHECK*1000,error:dojo.hitch(this,function(_7){
+this.goingOnline=false;
+this.isOnline=false;
+if(_6){
+_6(false);
+}
+}),load:dojo.hitch(this,function(_8){
+this.goingOnline=false;
+this.isOnline=true;
+if(_6){
+_6(true);
+}else{
+this.onNetwork("online");
+}
+})});
+},_startNetworkThread:function(){
+if(!this.doNetChecking){
+return;
+}
+window.setInterval(dojo.hitch(this,function(){
+var d=dojo.xhrGet({url:this._getAvailabilityURL(),handleAs:"text",timeout:this.NET_CHECK*1000,error:dojo.hitch(this,function(_a){
+if(this.isOnline){
+this.isOnline=false;
+try{
+if(typeof d.ioArgs.xhr.abort=="function"){
+d.ioArgs.xhr.abort();
+}
+}
+catch(e){
+}
+dojox.off.sync.isSyncing=false;
+this.onNetwork("offline");
+}
+}),load:dojo.hitch(this,function(_b){
+if(!this.isOnline){
+this.isOnline=true;
+this.onNetwork("online");
+}
+})});
+}),this.NET_CHECK*1000);
+},_getAvailabilityURL:function(){
+var _c=this.availabilityURL.toString();
+if(_c.indexOf("?")==-1){
+_c+="?";
+}else{
+_c+="&";
+}
+_c+="browserbust="+new Date().getTime();
+return _c;
+},_onOfflineCacheInstalled:function(){
+this.onFrameworkEvent("offlineCacheInstalled");
+},_cacheDojoResources:function(){
+var _d=true;
+dojo.forEach(dojo.query("script"),function(i){
+var _f=i.getAttribute("src");
+if(!_f){
+return;
+}
+if(_f.indexOf("_base/_loader/bootstrap.js")!=-1){
+_d=false;
+}
+});
+if(!_d){
+dojox.off.files.cache(dojo.moduleUrl("dojo","_base.js").uri);
+dojox.off.files.cache(dojo.moduleUrl("dojo","_base/_loader/loader.js").uri);
+dojox.off.files.cache(dojo.moduleUrl("dojo","_base/_loader/bootstrap.js").uri);
+dojox.off.files.cache(dojo.moduleUrl("dojo","_base/_loader/hostenv_browser.js").uri);
+}
+for(var i=0;i<dojo._loadedUrls.length;i++){
+dojox.off.files.cache(dojo._loadedUrls[i]);
+}
+},_save:function(){
+},_load:function(_11){
+dojox.off.sync._load(_11);
+}});
+dojox.storage.manager.addOnLoad(dojo.hitch(dojox.off,"_onStorageLoad"));
+dojo.addOnLoad(dojox.off,"_onPageLoad");
+}
diff --git a/dojox/off/docs/bookmarklets.html b/dojox/off/docs/bookmarklets.html
new file mode 100644
index 0000000..c5ece2e
--- /dev/null
+++ b/dojox/off/docs/bookmarklets.html
@@ -0,0 +1,10 @@
+<html>
+<body>
+<h1>Browser Bookmarklets</h1>
+
+<p>Drag the following bookmarklets to your links toolbar and press to clear the Google Gears cache:</p>
+
+<p>Firefox: <a title="Clear Gears Cache" href="javascript:(function(){new GearsFactory().create('beta.localserver', '1.0').removeStore('dot_store_'+window.location.href.replace(/[^0-9A-Za-z_]/g, '_'));dojox.storage.remove('oldVersion', '_dot');}())">Clear Gears Cache</a></p>
+<p>Internet Explorer: <a title="Clear Gears Cache" href="javascript:(function(){new ActiveXObject('Gears.Factory').create('beta.localserver', '1.0').removeStore('dot_store_'+window.location.href.replace(/[^0-9A-Za-z_]/g, '_'));dojox.storage.remove('oldVersion', '_dot');}())">Clear Gears Cache</a></p>
+</body>
+</html>
diff --git a/dojox/off/files.js b/dojox/off/files.js
new file mode 100644
index 0000000..b9a1b47
--- /dev/null
+++ b/dojox/off/files.js
@@ -0,0 +1,238 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.off.files"]){
+dojo._hasResource["dojox.off.files"]=true;
+dojo.provide("dojox.off.files");
+dojox.off.files={versionURL:"version.js",listOfURLs:[],refreshing:false,_cancelID:null,_error:false,_errorMessages:[],_currentFileIndex:0,_store:null,_doSlurp:false,slurp:function(){
+this._doSlurp=true;
+},cache:function(_1){
+if(dojo.isString(_1)){
+var _2=this._trimAnchor(_1+"");
+if(!this.isAvailable(_2)){
+this.listOfURLs.push(_2);
+}
+}else{
+if(_1 instanceof dojo._Url){
+var _2=this._trimAnchor(_1.uri);
+if(!this.isAvailable(_2)){
+this.listOfURLs.push(_2);
+}
+}else{
+dojo.forEach(_1,function(_3){
+_3=this._trimAnchor(_3);
+if(!this.isAvailable(_3)){
+this.listOfURLs.push(_3);
+}
+},this);
+}
+}
+},printURLs:function(){
+
+dojo.forEach(this.listOfURLs,function(i){
+
+});
+},remove:function(_5){
+for(var i=0;i<this.listOfURLs.length;i++){
+if(this.listOfURLs[i]==_5){
+this.listOfURLs=this.listOfURLs.splice(i,1);
+break;
+}
+}
+},isAvailable:function(_7){
+for(var i=0;i<this.listOfURLs.length;i++){
+if(this.listOfURLs[i]==_7){
+return true;
+}
+}
+return false;
+},refresh:function(_9){
+try{
+if(dojo.config.isDebug){
+this.printURLs();
+}
+this.refreshing=true;
+if(this.versionURL){
+this._getVersionInfo(function(_a,_b,_c){
+if(dojo.config.isDebug||!_b||_c||!_a||_a!=_b){
+console.warn("Refreshing offline file list");
+this._doRefresh(_9,_b);
+}else{
+console.warn("No need to refresh offline file list");
+_9(false,[]);
+}
+});
+}else{
+console.warn("Refreshing offline file list");
+this._doRefresh(_9);
+}
+}
+catch(e){
+this.refreshing=false;
+dojox.off.coreOpFailed=true;
+dojox.off.enabled=false;
+dojox.off.onFrameworkEvent("coreOperationFailed");
+}
+},abortRefresh:function(){
+if(!this.refreshing){
+return;
+}
+this._store.abortCapture(this._cancelID);
+this.refreshing=false;
+},_slurp:function(){
+if(!this._doSlurp){
+return;
+}
+var _d=dojo.hitch(this,function(_e){
+if(this._sameLocation(_e)){
+this.cache(_e);
+}
+});
+_d(window.location.href);
+dojo.query("script").forEach(function(i){
+try{
+_d(i.getAttribute("src"));
+}
+catch(exp){
+}
+});
+dojo.query("link").forEach(function(i){
+try{
+if(!i.getAttribute("rel")||i.getAttribute("rel").toLowerCase()!="stylesheet"){
+return;
+}
+_d(i.getAttribute("href"));
+}
+catch(exp){
+}
+});
+dojo.query("img").forEach(function(i){
+try{
+_d(i.getAttribute("src"));
+}
+catch(exp){
+}
+});
+dojo.query("a").forEach(function(i){
+try{
+_d(i.getAttribute("href"));
+}
+catch(exp){
+}
+});
+dojo.forEach(document.styleSheets,function(_13){
+try{
+if(_13.cssRules){
+dojo.forEach(_13.cssRules,function(_14){
+var _15=_14.cssText;
+if(_15){
+var _16=_15.match(/url\(\s*([^\) ]*)\s*\)/i);
+if(!_16){
+return;
+}
+for(var i=1;i<_16.length;i++){
+_d(_16[i]);
+}
+}
+});
+}else{
+if(_13.cssText){
+var _18;
+var _19=_13.cssText.toString();
+var _1a=_19.split(/\f|\r|\n/);
+for(var i=0;i<_1a.length;i++){
+_18=_1a[i].match(/url\(\s*([^\) ]*)\s*\)/i);
+if(_18&&_18.length){
+_d(_18[1]);
+}
+}
+}
+}
+}
+catch(exp){
+}
+});
+},_sameLocation:function(url){
+if(!url){
+return false;
+}
+if(url.length&&url.charAt(0)=="#"){
+return false;
+}
+url=new dojo._Url(url);
+if(!url.scheme&&!url.port&&!url.host){
+return true;
+}
+if(!url.scheme&&url.host&&url.port&&window.location.hostname==url.host&&window.location.port==url.port){
+return true;
+}
+if(!url.scheme&&url.host&&!url.port&&window.location.hostname==url.host&&window.location.port==80){
+return true;
+}
+return window.location.protocol==(url.scheme+":")&&window.location.hostname==url.host&&(window.location.port==url.port||!window.location.port&&!url.port);
+},_trimAnchor:function(url){
+return url.replace(/\#.*$/,"");
+},_doRefresh:function(_1e,_1f){
+var _20;
+try{
+_20=google.gears.factory.create("beta.localserver","1.0");
+}
+catch(exp){
+dojo.setObject("google.gears.denied",true);
+dojox.off.onFrameworkEvent("coreOperationFailed");
+throw "Google Gears must be allowed to run";
+}
+var _21="dot_store_"+window.location.href.replace(/[^0-9A-Za-z_]/g,"_");
+if(_21.length>=64){
+_21=_21.substring(0,63);
+}
+_20.removeStore(_21);
+_20.openStore(_21);
+var _22=_20.createStore(_21);
+this._store=_22;
+var _23=this;
+this._currentFileIndex=0;
+this._cancelID=_22.capture(this.listOfURLs,function(url,_25,_26){
+if(!_25&&_23.refreshing){
+_23._cancelID=null;
+_23.refreshing=false;
+var _27=[];
+_27.push("Unable to capture: "+url);
+_1e(true,_27);
+return;
+}else{
+if(_25){
+_23._currentFileIndex++;
+}
+}
+if(_25&&_23._currentFileIndex>=_23.listOfURLs.length){
+_23._cancelID=null;
+_23.refreshing=false;
+if(_1f){
+dojox.storage.put("oldVersion",_1f,null,dojox.off.STORAGE_NAMESPACE);
+}
+dojox.storage.put("justDebugged",dojo.config.isDebug,null,dojox.off.STORAGE_NAMESPACE);
+_1e(false,[]);
+}
+});
+},_getVersionInfo:function(_28){
+var _29=dojox.storage.get("justDebugged",dojox.off.STORAGE_NAMESPACE);
+var _2a=dojox.storage.get("oldVersion",dojox.off.STORAGE_NAMESPACE);
+var _2b=null;
+_28=dojo.hitch(this,_28);
+dojo.xhrGet({url:this.versionURL+"?browserbust="+new Date().getTime(),timeout:5*1000,handleAs:"javascript",error:function(err){
+dojox.storage.remove("oldVersion",dojox.off.STORAGE_NAMESPACE);
+dojox.storage.remove("justDebugged",dojox.off.STORAGE_NAMESPACE);
+_28(_2a,_2b,_29);
+},load:function(_2d){
+if(_2d){
+_2b=_2d;
+}
+_28(_2a,_2b,_29);
+}});
+}};
+}
diff --git a/dojox/off/network_check.txt b/dojox/off/network_check.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/dojox/off/network_check.txt
@@ -0,0 +1 @@
+1
diff --git a/dojox/off/offline.js b/dojox/off/offline.js
new file mode 100644
index 0000000..2d1b8c8
--- /dev/null
+++ b/dojox/off/offline.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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 a compiled version of Dojo, built for deployment and not for
+	development. To get an editable version, please visit:
+
+		http://dojotoolkit.org
+
+	for documentation and information on getting the source.
+*/
+
+if(!dojo._hasResource["dojox.storage.Provider"]){dojo._hasResource["dojox.storage.Provider"]=true;dojo.provide("dojox.storage.Provider");dojo.declare("dojox.storage.Provider",null,{constructor:function(){},SUCCESS:"success",FAILED:"failed",PENDING:"pending",SIZE_NOT_AVAILABLE:"Size not available",SIZE_NO_LIMIT:"No size limit",DEFAULT_NAMESPACE:"default",onHideSettingsUI:null,initialize:function(){console.warn("dojox.storage.initialize not implemented");},isAvailable:function(){console.wa [...]
diff --git a/dojox/off/offline.js.uncompressed.js b/dojox/off/offline.js.uncompressed.js
new file mode 100644
index 0000000..92f35aa
--- /dev/null
+++ b/dojox/off/offline.js.uncompressed.js
@@ -0,0 +1,6243 @@
+/*
+	Copyright (c) 2004-2009, 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 a compiled version of Dojo, built for deployment and not for
+	development. To get an editable version, please visit:
+
+		http://dojotoolkit.org
+
+	for documentation and information on getting the source.
+*/
+
+if(!dojo._hasResource["dojox.storage.Provider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.storage.Provider"] = true;
+dojo.provide("dojox.storage.Provider");
+
+dojo.declare("dojox.storage.Provider", null, {
+	// summary: A singleton for working with dojox.storage.
+	// description:
+	//		dojox.storage exposes the current available storage provider on this
+	//		platform. It gives you methods such as dojox.storage.put(),
+	//		dojox.storage.get(), etc.
+	//		
+	//		For more details on dojox.storage, see the primary documentation
+	//		page at
+	//			http://manual.dojotoolkit.org/storage.html
+	//		
+	//		Note for storage provider developers who are creating subclasses-
+	//		This is the base class for all storage providers Specific kinds of
+	//		Storage Providers should subclass this and implement these methods.
+	//		You should avoid initialization in storage provider subclass's
+	//		constructor; instead, perform initialization in your initialize()
+	//		method. 
+	constructor: function(){
+	},
+	
+	// SUCCESS: String
+	//	Flag that indicates a put() call to a 
+	//	storage provider was succesful.
+	SUCCESS: "success",
+	
+	// FAILED: String
+	//	Flag that indicates a put() call to 
+	//	a storage provider failed.
+	FAILED: "failed",
+	
+	// PENDING: String
+	//	Flag that indicates a put() call to a 
+	//	storage provider is pending user approval.
+	PENDING: "pending",
+	
+	// SIZE_NOT_AVAILABLE: String
+	//	Returned by getMaximumSize() if this storage provider can not determine
+	//	the maximum amount of data it can support. 
+	SIZE_NOT_AVAILABLE: "Size not available",
+	
+	// SIZE_NO_LIMIT: String
+	//	Returned by getMaximumSize() if this storage provider has no theoretical
+	//	limit on the amount of data it can store. 
+	SIZE_NO_LIMIT: "No size limit",
+
+	// DEFAULT_NAMESPACE: String
+	//	The namespace for all storage operations. This is useful if several
+	//	applications want access to the storage system from the same domain but
+	//	want different storage silos. 
+	DEFAULT_NAMESPACE: "default",
+	
+	// onHideSettingsUI: Function
+	//	If a function is assigned to this property, then when the settings
+	//	provider's UI is closed this function is called. Useful, for example,
+	//	if the user has just cleared out all storage for this provider using
+	//	the settings UI, and you want to update your UI.
+	onHideSettingsUI: null,
+
+	initialize: function(){
+		// summary: 
+		//		Allows this storage provider to initialize itself. This is
+		//		called after the page has finished loading, so you can not do
+		//		document.writes(). Storage Provider subclasses should initialize
+		//		themselves inside of here rather than in their function
+		//		constructor.
+		console.warn("dojox.storage.initialize not implemented");
+	},
+	
+	isAvailable: function(){ /*Boolean*/
+		// summary: 
+		//		Returns whether this storage provider is available on this
+		//		platform. 
+		console.warn("dojox.storage.isAvailable not implemented");
+	},
+
+	put: function(	/*string*/ key,
+					/*object*/ value, 
+					/*function*/ resultsHandler,
+					/*string?*/ namespace){
+		// summary:
+		//		Puts a key and value into this storage system.
+		// description:
+		//		Example-
+		//			var resultsHandler = function(status, key, message, namespace){
+		//			  alert("status="+status+", key="+key+", message="+message);
+		//			};
+		//			dojox.storage.put("test", "hello world", resultsHandler);
+		//
+		//			Arguments:
+		//
+		//			status - The status of the put operation, given by
+		//								dojox.storage.FAILED, dojox.storage.SUCCEEDED, or
+		//								dojox.storage.PENDING
+		//			key - The key that was used for the put
+		//			message - An optional message if there was an error or things failed.
+		//			namespace - The namespace of the key. This comes at the end since
+		//									it was added later.
+		//	
+		//		Important note: if you are using Dojo Storage in conjunction with
+		//		Dojo Offline, then you don't need to provide
+		//		a resultsHandler; this is because for Dojo Offline we 
+		//		use Google Gears to persist data, which has unlimited data
+		//		once the user has given permission. If you are using Dojo
+		//		Storage apart from Dojo Offline, then under the covers hidden
+		//		Flash might be used, which is both asychronous and which might
+		//		get denied; in this case you must provide a resultsHandler.
+		// key:
+		//		A string key to use when retrieving this value in the future.
+		// value:
+		//		A value to store; this can be any JavaScript type.
+		// resultsHandler:
+		//		A callback function that will receive three arguments. The
+		//		first argument is one of three values: dojox.storage.SUCCESS,
+		//		dojox.storage.FAILED, or dojox.storage.PENDING; these values
+		//		determine how the put request went. In some storage systems
+		//		users can deny a storage request, resulting in a
+		//		dojox.storage.FAILED, while in other storage systems a storage
+		//		request must wait for user approval, resulting in a
+		//		dojox.storage.PENDING status until the request is either
+		//		approved or denied, resulting in another call back with
+		//		dojox.storage.SUCCESS. 
+		//		The second argument in the call back is the key name that was being stored.
+		//		The third argument in the call back is an optional message that
+		//		details possible error messages that might have occurred during
+		//		the storage process.
+		//	namespace:
+		//		Optional string namespace that this value will be placed into;
+		//		if left off, the value will be placed into dojox.storage.DEFAULT_NAMESPACE
+		
+		console.warn("dojox.storage.put not implemented");
+	},
+
+	get: function(/*string*/ key, /*string?*/ namespace){ /*Object*/
+		// summary:
+		//		Gets the value with the given key. Returns null if this key is
+		//		not in the storage system.
+		// key:
+		//		A string key to get the value of.
+		//	namespace:
+		//		Optional string namespace that this value will be retrieved from;
+		//		if left off, the value will be retrieved from dojox.storage.DEFAULT_NAMESPACE
+		// return: Returns any JavaScript object type; null if the key is not present
+		console.warn("dojox.storage.get not implemented");
+	},
+
+	hasKey: function(/*string*/ key, /*string?*/ namespace){
+		// summary: Determines whether the storage has the given key. 
+		return !!this.get(key, namespace); // Boolean
+	},
+
+	getKeys: function(/*string?*/ namespace){ /*Array*/
+		// summary: Enumerates all of the available keys in this storage system.
+		// return: Array of available keys
+		console.warn("dojox.storage.getKeys not implemented");
+	},
+	
+	clear: function(/*string?*/ namespace){
+		// summary: 
+		//		Completely clears this storage system of all of it's values and
+		//		keys. If 'namespace' is provided just clears the keys in that
+		//		namespace.
+		console.warn("dojox.storage.clear not implemented");
+	},
+  
+	remove: function(/*string*/ key, /*string?*/ namespace){
+		// summary: Removes the given key from this storage system.
+		console.warn("dojox.storage.remove not implemented");
+	},
+	
+	getNamespaces: function(){ /*string[]*/
+		console.warn("dojox.storage.getNamespaces not implemented");
+	},
+
+	isPermanent: function(){ /*Boolean*/
+		// summary:
+		//		Returns whether this storage provider's values are persisted
+		//		when this platform is shutdown. 
+		console.warn("dojox.storage.isPermanent not implemented");
+	},
+
+	getMaximumSize: function(){ /* mixed */
+		// summary: The maximum storage allowed by this provider
+		// returns: 
+		//	Returns the maximum storage size 
+		//	supported by this provider, in 
+		//	thousands of bytes (i.e., if it 
+		//	returns 60 then this means that 60K 
+		//	of storage is supported).
+		//
+		//	If this provider can not determine 
+		//	it's maximum size, then 
+		//	dojox.storage.SIZE_NOT_AVAILABLE is 
+		//	returned; if there is no theoretical
+		//	limit on the amount of storage 
+		//	this provider can return, then
+		//	dojox.storage.SIZE_NO_LIMIT is 
+		//	returned
+		console.warn("dojox.storage.getMaximumSize not implemented");
+	},
+		
+	putMultiple: function(	/*array*/ keys,
+							/*array*/ values, 
+							/*function*/ resultsHandler,
+							/*string?*/ namespace){
+		// summary:
+		//		Puts multiple keys and values into this storage system.
+		// description:
+		//		Example-
+		//			var resultsHandler = function(status, key, message){
+		//			  alert("status="+status+", key="+key+", message="+message);
+		//			};
+		//			dojox.storage.put(["test"], ["hello world"], resultsHandler);
+		//	
+		//		Important note: if you are using Dojo Storage in conjunction with
+		//		Dojo Offline, then you don't need to provide
+		//		a resultsHandler; this is because for Dojo Offline we 
+		//		use Google Gears to persist data, which has unlimited data
+		//		once the user has given permission. If you are using Dojo
+		//		Storage apart from Dojo Offline, then under the covers hidden
+		//		Flash might be used, which is both asychronous and which might
+		//		get denied; in this case you must provide a resultsHandler.
+		// keys:
+		//		An array of string keys to use when retrieving this value in the future,
+		//		one per value to be stored
+		// values:
+		//		An array of values to store; this can be any JavaScript type, though the
+		//		performance of plain strings is considerably better
+		// resultsHandler:
+		//		A callback function that will receive three arguments. The
+		//		first argument is one of three values: dojox.storage.SUCCESS,
+		//		dojox.storage.FAILED, or dojox.storage.PENDING; these values
+		//		determine how the put request went. In some storage systems
+		//		users can deny a storage request, resulting in a
+		//		dojox.storage.FAILED, while in other storage systems a storage
+		//		request must wait for user approval, resulting in a
+		//		dojox.storage.PENDING status until the request is either
+		//		approved or denied, resulting in another call back with
+		//		dojox.storage.SUCCESS. 
+		//		The second argument in the call back is the key name that was being stored.
+		//		The third argument in the call back is an optional message that
+		//		details possible error messages that might have occurred during
+		//		the storage process.
+		//	namespace:
+		//		Optional string namespace that this value will be placed into;
+		//		if left off, the value will be placed into dojox.storage.DEFAULT_NAMESPACE
+		
+		for(var i = 0; i < keys.length; i++){ 
+			dojox.storage.put(keys[i], values[i], resultsHandler, namespace); 
+		}
+	},
+
+	getMultiple: function(/*array*/ keys, /*string?*/ namespace){ /*Object*/
+		// summary:
+		//		Gets the valuse corresponding to each of the given keys. 
+		//		Returns a null array element for each given key that is
+		//		not in the storage system.
+		// keys:
+		//		An array of string keys to get the value of.
+		//	namespace:
+		//		Optional string namespace that this value will be retrieved from;
+		//		if left off, the value will be retrieved from dojox.storage.DEFAULT_NAMESPACE
+		// return: Returns any JavaScript object type; null if the key is not present
+		
+		var results = []; 
+		for(var i = 0; i < keys.length; i++){ 
+			results.push(dojox.storage.get(keys[i], namespace)); 
+		} 
+		
+		return results;
+	},
+
+	removeMultiple: function(/*array*/ keys, /*string?*/ namespace) {
+		// summary: Removes the given keys from this storage system.
+		
+		for(var i = 0; i < keys.length; i++){ 
+			dojox.storage.remove(keys[i], namespace); 
+		}
+	},
+	
+	isValidKeyArray: function( keys) {
+		if(keys === null || keys === undefined || !dojo.isArray(keys)){
+			return false;
+		}
+
+		//	JAC: This could be optimized by running the key validity test 
+		//  directly over a joined string
+		return !dojo.some(keys, function(key){
+			return !this.isValidKey(key);
+		}, this); // Boolean
+	},
+
+	hasSettingsUI: function(){ /*Boolean*/
+		// summary: Determines whether this provider has a settings UI.
+		return false;
+	},
+
+	showSettingsUI: function(){
+		// summary: If this provider has a settings UI, determined
+		// by calling hasSettingsUI(), it is shown. 
+		console.warn("dojox.storage.showSettingsUI not implemented");
+	},
+
+	hideSettingsUI: function(){
+		// summary: If this provider has a settings UI, hides it.
+		console.warn("dojox.storage.hideSettingsUI not implemented");
+	},
+	
+	isValidKey: function(/*string*/ keyName){ /*Boolean*/
+		// summary:
+		//		Subclasses can call this to ensure that the key given is valid
+		//		in a consistent way across different storage providers. We use
+		//		the lowest common denominator for key values allowed: only
+		//		letters, numbers, and underscores are allowed. No spaces. 
+		if(keyName === null || keyName === undefined){
+			return false;
+		}
+			
+		return /^[0-9A-Za-z_]*$/.test(keyName);
+	},
+	
+	getResourceList: function(){ /* Array[] */
+		// summary:
+		//	Returns a list of URLs that this
+		//	storage provider might depend on.
+		// description:
+		//	This method returns a list of URLs that this
+		//	storage provider depends on to do its work.
+		//	This list is used by the Dojo Offline Toolkit
+		//	to cache these resources to ensure the machinery
+		//	used by this storage provider is available offline.
+		//	What is returned is an array of URLs.
+		//  Note that Dojo Offline uses Gears as its native 
+		//  storage provider, and does not support using other
+		//  kinds of storage providers while offline anymore.
+		
+		return [];
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.storage.manager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.storage.manager"] = true;
+dojo.provide("dojox.storage.manager");
+//
+// FIXME: refactor this to use an AdapterRegistry
+
+dojox.storage.manager = new function(){
+	// summary: A singleton class in charge of the dojox.storage system
+	// description:
+	//		Initializes the storage systems and figures out the best available 
+	//		storage options on this platform.	
+	
+	// currentProvider: Object
+	//	The storage provider that was automagically chosen to do storage
+	//	on this platform, such as dojox.storage.FlashStorageProvider.
+	this.currentProvider = null;
+	
+	// available: Boolean
+	//	Whether storage of some kind is available.
+	this.available = false;
+
+  // providers: Array
+  //  Array of all the static provider instances, useful if you want to
+  //  loop through and see what providers have been registered.
+  this.providers = [];
+	
+	this._initialized = false;
+
+	this._onLoadListeners = [];
+	
+	this.initialize = function(){
+		// summary: 
+		//		Initializes the storage system and autodetects the best storage
+		//		provider we can provide on this platform
+		this.autodetect();
+	};
+	
+	this.register = function(/*string*/ name, /*Object*/ instance){
+		// summary:
+		//		Registers the existence of a new storage provider; used by
+		//		subclasses to inform the manager of their existence. The
+		//		storage manager will select storage providers based on 
+		//		their ordering, so the order in which you call this method
+		//		matters. 
+		// name:
+		//		The full class name of this provider, such as
+		//		"dojox.storage.FlashStorageProvider".
+		// instance:
+		//		An instance of this provider, which we will use to call
+		//		isAvailable() on. 
+		
+		// keep list of providers as a list so that we can know what order
+		// storage providers are preferred; also, store the providers hashed
+		// by name in case someone wants to get a provider that uses
+		// a particular storage backend
+		this.providers.push(instance);
+		this.providers[name] = instance;
+	};
+	
+	this.setProvider = function(storageClass){
+		// summary:
+		//		Instructs the storageManager to use the given storage class for
+		//		all storage requests.
+		// description:
+		//		Example-
+		//			dojox.storage.setProvider(
+		//				dojox.storage.IEStorageProvider)
+	
+	};
+	
+	this.autodetect = function(){
+		// summary:
+		//		Autodetects the best possible persistent storage provider
+		//		available on this platform. 
+		
+		//
+		
+		if(this._initialized){ // already finished
+			return;
+		}
+
+		// a flag to force the storage manager to use a particular 
+		// storage provider type, such as 
+		// djConfig = {forceStorageProvider: "dojox.storage.WhatWGStorageProvider"};
+		var forceProvider = dojo.config["forceStorageProvider"] || false;
+
+		// go through each provider, seeing if it can be used
+		var providerToUse;
+		//FIXME: use dojo.some
+		for(var i = 0; i < this.providers.length; i++){
+			providerToUse = this.providers[i];
+			if(forceProvider && forceProvider == providerToUse.declaredClass){
+				// still call isAvailable for this provider, since this helps some
+				// providers internally figure out if they are available
+				// FIXME: This should be refactored since it is non-intuitive
+				// that isAvailable() would initialize some state
+				providerToUse.isAvailable();
+				break;
+			}else if(!forceProvider && providerToUse.isAvailable()){
+				break;
+			}
+		}
+		
+		if(!providerToUse){ // no provider available
+			this._initialized = true;
+			this.available = false;
+			this.currentProvider = null;
+			console.warn("No storage provider found for this platform");
+			this.loaded();
+			return;
+		}
+			
+		// create this provider and mix in it's properties
+		// so that developers can do dojox.storage.put rather
+		// than dojox.storage.currentProvider.put, for example
+		this.currentProvider = providerToUse;
+		dojo.mixin(dojox.storage, this.currentProvider);
+		
+		// have the provider initialize itself
+		dojox.storage.initialize();
+		
+		this._initialized = true;
+		this.available = true;
+	};
+	
+	this.isAvailable = function(){ /*Boolean*/
+		// summary: Returns whether any storage options are available.
+		return this.available;
+	};
+	
+	this.addOnLoad = function(func){ /* void */
+		// summary:
+		//		Adds an onload listener to know when Dojo Offline can be used.
+		// description:
+		//		Adds a listener to know when Dojo Offline can be used. This
+		//		ensures that the Dojo Offline framework is loaded and that the
+		//		local dojox.storage system is ready to be used. This method is
+		//		useful if you don't want to have a dependency on Dojo Events
+		//		when using dojox.storage.
+		// func: Function
+		//		A function to call when Dojo Offline is ready to go
+		this._onLoadListeners.push(func);
+		
+		if(this.isInitialized()){
+			this._fireLoaded();
+		}
+	};
+	
+	this.removeOnLoad = function(func){ /* void */
+		// summary: Removes the given onLoad listener
+		for(var i = 0; i < this._onLoadListeners.length; i++){
+			if(func == this._onLoadListeners[i]){
+				this._onLoadListeners = this._onLoadListeners.splice(i, 1);
+				break;
+			}
+		}
+	};
+	
+	this.isInitialized = function(){ /*Boolean*/
+	 	// summary:
+		//		Returns whether the storage system is initialized and ready to
+		//		be used. 
+
+		// FIXME: This should REALLY not be in here, but it fixes a tricky
+		// Flash timing bug.
+		// Confirm that this is still needed with the newly refactored Dojo
+		// Flash. Used to be for Internet Explorer. -- Brad Neuberg
+		if(this.currentProvider != null
+			&& this.currentProvider.declaredClass == "dojox.storage.FlashStorageProvider" 
+			&& dojox.flash.ready == false){
+			return false;
+		}else{
+			return this._initialized;
+		}
+	};
+
+	this.supportsProvider = function(/*string*/ storageClass){ /* Boolean */
+		// summary: Determines if this platform supports the given storage provider.
+		// description:
+		//		Example-
+		//			dojox.storage.manager.supportsProvider(
+		//				"dojox.storage.InternetExplorerStorageProvider");
+
+		// construct this class dynamically
+		try{
+			// dynamically call the given providers class level isAvailable()
+			// method
+			var provider = eval("new " + storageClass + "()");
+			var results = provider.isAvailable();
+			if(!results){ return false; }
+			return results;
+		}catch(e){
+			return false;
+		}
+	};
+
+	this.getProvider = function(){ /* Object */
+		// summary: Gets the current provider
+		return this.currentProvider;
+	};
+	
+	this.loaded = function(){
+		// summary:
+		//		The storage provider should call this method when it is loaded
+		//		and ready to be used. Clients who will use the provider will
+		//		connect to this method to know when they can use the storage
+		//		system. You can either use dojo.connect to connect to this
+		//		function, or can use dojox.storage.manager.addOnLoad() to add
+		//		a listener that does not depend on the dojo.event package.
+		// description:
+		//		Example 1-
+		//			if(dojox.storage.manager.isInitialized() == false){ 
+		//				dojo.connect(dojox.storage.manager, "loaded", TestStorage, "initialize");
+		//			}else{
+		//				dojo.connect(dojo, "loaded", TestStorage, "initialize");
+		//			}
+		//		Example 2-
+		//			dojox.storage.manager.addOnLoad(someFunction);
+
+
+		// FIXME: we should just provide a Deferred for this. That way you
+		// don't care when this happens or has happened. Deferreds are in Base
+		this._fireLoaded();
+	};
+	
+	this._fireLoaded = function(){
+		//
+		
+		dojo.forEach(this._onLoadListeners, function(i){ 
+			try{ 
+				i(); 
+			}catch(e){  } 
+		});
+	};
+	
+	this.getResourceList = function(){
+		// summary:
+		//		Returns a list of whatever resources are necessary for storage
+		//		providers to work. 
+		// description:
+		//		This will return all files needed by all storage providers for
+		//		this particular environment type. For example, if we are in the
+		//		browser environment, then this will return the hidden SWF files
+		//		needed by the FlashStorageProvider, even if we don't need them
+		//		for the particular browser we are working within. This is meant
+		//		to faciliate Dojo Offline, which must retrieve all resources we
+		//		need offline into the offline cache -- we retrieve everything
+		//		needed, in case another browser that requires different storage
+		//		mechanisms hits the local offline cache. For example, if we
+		//		were to sync against Dojo Offline on Firefox 2, then we would
+		//		not grab the FlashStorageProvider resources needed for Safari.
+		var results = [];
+		dojo.forEach(dojox.storage.manager.providers, function(currentProvider){
+			results = results.concat(currentProvider.getResourceList());
+		});
+		
+		return results;
+	}
+};
+
+}
+
+if(!dojo._hasResource["dojo.gears"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.gears"] = true;
+dojo.provide("dojo.gears");
+
+dojo.gears._gearsObject = function(){
+	// summary: 
+	//		factory method to get a Google Gears plugin instance to
+	//		expose in the browser runtime environment, if present
+	var factory;
+	var results;
+	
+	var gearsObj = dojo.getObject("google.gears");
+	if(gearsObj){ return gearsObj; } // already defined elsewhere
+	
+	if(typeof GearsFactory != "undefined"){ // Firefox
+		factory = new GearsFactory();
+	}else{
+		if(dojo.isIE){
+			// IE
+			try{
+				factory = new ActiveXObject("Gears.Factory");
+			}catch(e){
+				// ok to squelch; there's no gears factory.  move on.
+			}
+		}else if(navigator.mimeTypes["application/x-googlegears"]){
+			// Safari?
+			factory = document.createElement("object");
+			factory.setAttribute("type", "application/x-googlegears");
+			factory.setAttribute("width", 0);
+			factory.setAttribute("height", 0);
+			factory.style.display = "none";
+			document.documentElement.appendChild(factory);
+		}
+	}
+
+	// still nothing?
+	if(!factory){ return null; }
+	
+	// define the global objects now; don't overwrite them though if they
+	// were somehow set internally by the Gears plugin, which is on their
+	// dev roadmap for the future
+	dojo.setObject("google.gears.factory", factory);
+	return dojo.getObject("google.gears");
+};
+
+/*=====
+dojo.gears.available = {
+	// summary: True if client is using Google Gears
+};
+=====*/
+// see if we have Google Gears installed, and if
+// so, make it available in the runtime environment
+// and in the Google standard 'google.gears' global object
+dojo.gears.available = (!!dojo.gears._gearsObject())||0;
+
+}
+
+if(!dojo._hasResource["dojox.sql._crypto"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.sql._crypto"] = true;
+dojo.provide("dojox.sql._crypto");
+dojo.mixin(dojox.sql._crypto, {
+	// summary: dojox.sql cryptography code
+	// description: 
+	//	Taken from http://www.movable-type.co.uk/scripts/aes.html by
+	// 	Chris Veness (CLA signed); adapted for Dojo and Google Gears Worker Pool
+	// 	by Brad Neuberg, bkn3 at columbia.edu
+	//
+	// _POOL_SIZE:
+	//	Size of worker pool to create to help with crypto
+	_POOL_SIZE: 100,
+
+	encrypt: function(plaintext, password, callback){
+		// summary:
+		//	Use Corrected Block TEA to encrypt plaintext using password
+		//	(note plaintext & password must be strings not string objects).
+		//	Results will be returned to the 'callback' asychronously.	
+		this._initWorkerPool();
+
+		var msg ={plaintext: plaintext, password: password};
+		msg = dojo.toJson(msg);
+		msg = "encr:" + String(msg);
+
+		this._assignWork(msg, callback);
+	},
+
+	decrypt: function(ciphertext, password, callback){
+		// summary:
+		//	Use Corrected Block TEA to decrypt ciphertext using password
+		//	(note ciphertext & password must be strings not string objects).
+		//	Results will be returned to the 'callback' asychronously.
+		this._initWorkerPool();
+
+		var msg = {ciphertext: ciphertext, password: password};
+		msg = dojo.toJson(msg);
+		msg = "decr:" + String(msg);
+
+		this._assignWork(msg, callback);
+	},
+
+	_initWorkerPool: function(){
+		// bugs in Google Gears prevents us from dynamically creating
+		// and destroying workers as we need them -- the worker
+		// pool functionality stops working after a number of crypto
+		// cycles (probably related to a memory leak in Google Gears).
+		// this is too bad, since it results in much simpler code.
+
+		// instead, we have to create a pool of workers and reuse them. we
+		// keep a stack of 'unemployed' Worker IDs that are currently not working.
+		// if a work request comes in, we pop off the 'unemployed' stack
+		// and put them to work, storing them in an 'employed' hashtable,
+		// keyed by their Worker ID with the value being the callback function
+		// that wants the result. when an employed worker is done, we get
+		// a message in our 'manager' which adds this worker back to the 
+		// unemployed stack and routes the result to the callback that
+		// wanted it. if all the workers were employed in the past but
+		// more work needed to be done (i.e. it's a tight labor pool ;) 
+		// then the work messages are pushed onto
+		// a 'handleMessage' queue as an object tuple{msg: msg, callback: callback}
+
+		if(!this._manager){
+			try{
+				this._manager = google.gears.factory.create("beta.workerpool", "1.0");
+				this._unemployed = [];
+				this._employed ={};
+				this._handleMessage = [];
+		
+				var self = this;
+				this._manager.onmessage = function(msg, sender){
+					// get the callback necessary to serve this result
+					var callback = self._employed["_" + sender];
+			
+					// make this worker unemployed
+					self._employed["_" + sender] = undefined;
+					self._unemployed.push("_" + sender);
+			
+					// see if we need to assign new work
+					// that was queued up needing to be done
+					if(self._handleMessage.length){
+						var handleMe = self._handleMessage.shift();
+						self._assignWork(handleMe.msg, handleMe.callback);
+					}
+			
+					// return results
+					callback(msg);
+				}
+			
+				var workerInit = "function _workerInit(){"
+									+ "gearsWorkerPool.onmessage = "
+										+ String(this._workerHandler)
+									+ ";"
+								+ "}";
+		
+				var code = workerInit + " _workerInit();";
+
+				// create our worker pool
+				for(var i = 0; i < this._POOL_SIZE; i++){
+					this._unemployed.push("_" + this._manager.createWorker(code));
+				}
+			}catch(exp){
+				throw exp.message||exp;
+			}
+		}
+	},
+
+	_assignWork: function(msg, callback){
+		// can we immediately assign this work?
+		if(!this._handleMessage.length && this._unemployed.length){
+			// get an unemployed worker
+			var workerID = this._unemployed.shift().substring(1); // remove _
+	
+			// list this worker as employed
+			this._employed["_" + workerID] = callback;
+	
+			// do the worke
+			this._manager.sendMessage(msg, parseInt(workerID,10));
+		}else{
+			// we have to queue it up
+			this._handleMessage ={msg: msg, callback: callback};
+		}
+	},
+
+	_workerHandler: function(msg, sender){
+	
+		/* Begin AES Implementation */
+	
+		/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
+	
+		// Sbox is pre-computed multiplicative inverse in GF(2^8) used in SubBytes and KeyExpansion [§5.1.1]
+		var Sbox =	[0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
+					 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
+					 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
+					 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
+					 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
+					 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
+					 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
+					 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
+					 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
+					 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
+					 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
+					 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
+					 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
+					 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
+					 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
+					 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16];
+
+		// Rcon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [§5.2]
+		var Rcon = [ [0x00, 0x00, 0x00, 0x00],
+					 [0x01, 0x00, 0x00, 0x00],
+					 [0x02, 0x00, 0x00, 0x00],
+					 [0x04, 0x00, 0x00, 0x00],
+					 [0x08, 0x00, 0x00, 0x00],
+					 [0x10, 0x00, 0x00, 0x00],
+					 [0x20, 0x00, 0x00, 0x00],
+					 [0x40, 0x00, 0x00, 0x00],
+					 [0x80, 0x00, 0x00, 0x00],
+					 [0x1b, 0x00, 0x00, 0x00],
+					 [0x36, 0x00, 0x00, 0x00] ]; 
+
+		/*
+		 * AES Cipher function: encrypt 'input' with Rijndael algorithm
+		 *
+		 *	 takes	 byte-array 'input' (16 bytes)
+		 *			 2D byte-array key schedule 'w' (Nr+1 x Nb bytes)
+		 *
+		 *	 applies Nr rounds (10/12/14) using key schedule w for 'add round key' stage
+		 *
+		 *	 returns byte-array encrypted value (16 bytes)
+		 */
+		function Cipher(input, w) {	   // main Cipher function [§5.1]
+		  var Nb = 4;				// block size (in words): no of columns in state (fixed at 4 for AES)
+		  var Nr = w.length/Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys
+
+		  var state = [[],[],[],[]];  // initialise 4xNb byte-array 'state' with input [§3.4]
+		  for (var i=0; i<4*Nb; i++) state[i%4][Math.floor(i/4)] = input[i];
+
+		  state = AddRoundKey(state, w, 0, Nb);
+
+		  for (var round=1; round<Nr; round++) {
+			state = SubBytes(state, Nb);
+			state = ShiftRows(state, Nb);
+			state = MixColumns(state, Nb);
+			state = AddRoundKey(state, w, round, Nb);
+		  }
+
+		  state = SubBytes(state, Nb);
+		  state = ShiftRows(state, Nb);
+		  state = AddRoundKey(state, w, Nr, Nb);
+
+		  var output = new Array(4*Nb);	 // convert state to 1-d array before returning [§3.4]
+		  for (var i=0; i<4*Nb; i++) output[i] = state[i%4][Math.floor(i/4)];
+		  return output;
+		}
+
+
+		function SubBytes(s, Nb) {	  // apply SBox to state S [§5.1.1]
+		  for (var r=0; r<4; r++) {
+			for (var c=0; c<Nb; c++) s[r][c] = Sbox[s[r][c]];
+		  }
+		  return s;
+		}
+
+
+		function ShiftRows(s, Nb) {	   // shift row r of state S left by r bytes [§5.1.2]
+		  var t = new Array(4);
+		  for (var r=1; r<4; r++) {
+			for (var c=0; c<4; c++) t[c] = s[r][(c+r)%Nb];	// shift into temp copy
+			for (var c=0; c<4; c++) s[r][c] = t[c];			// and copy back
+		  }			 // note that this will work for Nb=4,5,6, but not 7,8 (always 4 for AES):
+		  return s;	 // see fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.311.pdf 
+		}
+
+
+		function MixColumns(s, Nb) {   // combine bytes of each col of state S [§5.1.3]
+		  for (var c=0; c<4; c++) {
+			var a = new Array(4);  // 'a' is a copy of the current column from 's'
+			var b = new Array(4);  // 'b' is a•{02} in GF(2^8)
+			for (var i=0; i<4; i++) {
+			  a[i] = s[i][c];
+			  b[i] = s[i][c]&0x80 ? s[i][c]<<1 ^ 0x011b : s[i][c]<<1;
+			}
+			// a[n] ^ b[n] is a•{03} in GF(2^8)
+			s[0][c] = b[0] ^ a[1] ^ b[1] ^ a[2] ^ a[3]; // 2*a0 + 3*a1 + a2 + a3
+			s[1][c] = a[0] ^ b[1] ^ a[2] ^ b[2] ^ a[3]; // a0 * 2*a1 + 3*a2 + a3
+			s[2][c] = a[0] ^ a[1] ^ b[2] ^ a[3] ^ b[3]; // a0 + a1 + 2*a2 + 3*a3
+			s[3][c] = a[0] ^ b[0] ^ a[1] ^ a[2] ^ b[3]; // 3*a0 + a1 + a2 + 2*a3
+		  }
+		  return s;
+		}
+
+
+		function AddRoundKey(state, w, rnd, Nb) {  // xor Round Key into state S [§5.1.4]
+		  for (var r=0; r<4; r++) {
+			for (var c=0; c<Nb; c++) state[r][c] ^= w[rnd*4+c][r];
+		  }
+		  return state;
+		}
+
+
+		function KeyExpansion(key) {  // generate Key Schedule (byte-array Nr+1 x Nb) from Key [§5.2]
+		  var Nb = 4;			 // block size (in words): no of columns in state (fixed at 4 for AES)
+		  var Nk = key.length/4	 // key length (in words): 4/6/8 for 128/192/256-bit keys
+		  var Nr = Nk + 6;		 // no of rounds: 10/12/14 for 128/192/256-bit keys
+
+		  var w = new Array(Nb*(Nr+1));
+		  var temp = new Array(4);
+
+		  for (var i=0; i<Nk; i++) {
+			var r = [key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]];
+			w[i] = r;
+		  }
+
+		  for (var i=Nk; i<(Nb*(Nr+1)); i++) {
+			w[i] = new Array(4);
+			for (var t=0; t<4; t++) temp[t] = w[i-1][t];
+			if (i % Nk == 0) {
+			  temp = SubWord(RotWord(temp));
+			  for (var t=0; t<4; t++) temp[t] ^= Rcon[i/Nk][t];
+			} else if (Nk > 6 && i%Nk == 4) {
+			  temp = SubWord(temp);
+			}
+			for (var t=0; t<4; t++) w[i][t] = w[i-Nk][t] ^ temp[t];
+		  }
+
+		  return w;
+		}
+
+		function SubWord(w) {	 // apply SBox to 4-byte word w
+		  for (var i=0; i<4; i++) w[i] = Sbox[w[i]];
+		  return w;
+		}
+
+		function RotWord(w) {	 // rotate 4-byte word w left by one byte
+		  w[4] = w[0];
+		  for (var i=0; i<4; i++) w[i] = w[i+1];
+		  return w;
+		}
+
+		/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
+
+		/* 
+		 * Use AES to encrypt 'plaintext' with 'password' using 'nBits' key, in 'Counter' mode of operation
+		 *							 - see http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+		 *	 for each block
+		 *	 - outputblock = cipher(counter, key)
+		 *	 - cipherblock = plaintext xor outputblock
+		 */
+		function AESEncryptCtr(plaintext, password, nBits) {
+		  if (!(nBits==128 || nBits==192 || nBits==256)) return '';	 // standard allows 128/192/256 bit keys
+
+		  // for this example script, generate the key by applying Cipher to 1st 16/24/32 chars of password; 
+		  // for real-world applications, a more secure approach would be to hash the password e.g. with SHA-1
+		  var nBytes = nBits/8;	 // no bytes in key
+		  var pwBytes = new Array(nBytes);
+		  for (var i=0; i<nBytes; i++) pwBytes[i] = password.charCodeAt(i) & 0xff;
+
+		  var key = Cipher(pwBytes, KeyExpansion(pwBytes));
+
+		  key = key.concat(key.slice(0, nBytes-16));  // key is now 16/24/32 bytes long
+
+		  // initialise counter block (NIST SP800-38A §B.2): millisecond time-stamp for nonce in 1st 8 bytes,
+		  // block counter in 2nd 8 bytes
+		  var blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
+		  var counterBlock = new Array(blockSize);	// block size fixed at 16 bytes / 128 bits (Nb=4) for AES
+		  var nonce = (new Date()).getTime();  // milliseconds since 1-Jan-1970
+
+		  // encode nonce in two stages to cater for JavaScript 32-bit limit on bitwise ops
+		  for (var i=0; i<4; i++) counterBlock[i] = (nonce >>> i*8) & 0xff;
+		  for (var i=0; i<4; i++) counterBlock[i+4] = (nonce/0x100000000 >>> i*8) & 0xff; 
+
+		  // generate key schedule - an expansion of the key into distinct Key Rounds for each round
+		  var keySchedule = KeyExpansion(key);
+
+		  var blockCount = Math.ceil(plaintext.length/blockSize);
+		  var ciphertext = new Array(blockCount);  // ciphertext as array of strings
+ 
+		  for (var b=0; b<blockCount; b++) {
+			// set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
+			// again done in two stages for 32-bit ops
+			for (var c=0; c<4; c++) counterBlock[15-c] = (b >>> c*8) & 0xff;
+			for (var c=0; c<4; c++) counterBlock[15-c-4] = (b/0x100000000 >>> c*8)
+
+			var cipherCntr = Cipher(counterBlock, keySchedule);	 // -- encrypt counter block --
+
+			// calculate length of final block:
+			var blockLength = b<blockCount-1 ? blockSize : (plaintext.length-1)%blockSize+1;
+
+			var ct = '';
+			for (var i=0; i<blockLength; i++) {	 // -- xor plaintext with ciphered counter byte-by-byte --
+			  var plaintextByte = plaintext.charCodeAt(b*blockSize+i);
+			  var cipherByte = plaintextByte ^ cipherCntr[i];
+			  ct += String.fromCharCode(cipherByte);
+			}
+			// ct is now ciphertext for this block
+
+			ciphertext[b] = escCtrlChars(ct);  // escape troublesome characters in ciphertext
+		  }
+
+		  // convert the nonce to a string to go on the front of the ciphertext
+		  var ctrTxt = '';
+		  for (var i=0; i<8; i++) ctrTxt += String.fromCharCode(counterBlock[i]);
+		  ctrTxt = escCtrlChars(ctrTxt);
+
+		  // use '-' to separate blocks, use Array.join to concatenate arrays of strings for efficiency
+		  return ctrTxt + '-' + ciphertext.join('-');
+		}
+
+
+		/* 
+		 * Use AES to decrypt 'ciphertext' with 'password' using 'nBits' key, in Counter mode of operation
+		 *
+		 *	 for each block
+		 *	 - outputblock = cipher(counter, key)
+		 *	 - cipherblock = plaintext xor outputblock
+		 */
+		function AESDecryptCtr(ciphertext, password, nBits) {
+		  if (!(nBits==128 || nBits==192 || nBits==256)) return '';	 // standard allows 128/192/256 bit keys
+
+		  var nBytes = nBits/8;	 // no bytes in key
+		  var pwBytes = new Array(nBytes);
+		  for (var i=0; i<nBytes; i++) pwBytes[i] = password.charCodeAt(i) & 0xff;
+		  var pwKeySchedule = KeyExpansion(pwBytes);
+		  var key = Cipher(pwBytes, pwKeySchedule);
+		  key = key.concat(key.slice(0, nBytes-16));  // key is now 16/24/32 bytes long
+
+		  var keySchedule = KeyExpansion(key);
+
+		  ciphertext = ciphertext.split('-');  // split ciphertext into array of block-length strings 
+
+		  // recover nonce from 1st element of ciphertext
+		  var blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
+		  var counterBlock = new Array(blockSize);
+		  var ctrTxt = unescCtrlChars(ciphertext[0]);
+		  for (var i=0; i<8; i++) counterBlock[i] = ctrTxt.charCodeAt(i);
+
+		  var plaintext = new Array(ciphertext.length-1);
+
+		  for (var b=1; b<ciphertext.length; b++) {
+			// set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
+			for (var c=0; c<4; c++) counterBlock[15-c] = ((b-1) >>> c*8) & 0xff;
+			for (var c=0; c<4; c++) counterBlock[15-c-4] = ((b/0x100000000-1) >>> c*8) & 0xff;
+
+			var cipherCntr = Cipher(counterBlock, keySchedule);	 // encrypt counter block
+
+			ciphertext[b] = unescCtrlChars(ciphertext[b]);
+
+			var pt = '';
+			for (var i=0; i<ciphertext[b].length; i++) {
+			  // -- xor plaintext with ciphered counter byte-by-byte --
+			  var ciphertextByte = ciphertext[b].charCodeAt(i);
+			  var plaintextByte = ciphertextByte ^ cipherCntr[i];
+			  pt += String.fromCharCode(plaintextByte);
+			}
+			// pt is now plaintext for this block
+
+			plaintext[b-1] = pt;  // b-1 'cos no initial nonce block in plaintext
+		  }
+
+		  return plaintext.join('');
+		}
+
+		/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
+
+		function escCtrlChars(str) {  // escape control chars which might cause problems handling ciphertext
+		  return str.replace(/[\0\t\n\v\f\r\xa0!-]/g, function(c) { return '!' + c.charCodeAt(0) + '!'; });
+		}  // \xa0 to cater for bug in Firefox; include '-' to leave it free for use as a block marker
+
+		function unescCtrlChars(str) {	// unescape potentially problematic control characters
+		  return str.replace(/!\d\d?\d?!/g, function(c) { return String.fromCharCode(c.slice(1,-1)); });
+		}
+
+		/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
+	
+		function encrypt(plaintext, password){
+			return AESEncryptCtr(plaintext, password, 256);
+		}
+
+		function decrypt(ciphertext, password){	
+			return AESDecryptCtr(ciphertext, password, 256);
+		}
+	
+		/* End AES Implementation */
+	
+		var cmd = msg.substr(0,4);
+		var arg = msg.substr(5);
+		if(cmd == "encr"){
+			arg = eval("(" + arg + ")");
+			var plaintext = arg.plaintext;
+			var password = arg.password;
+			var results = encrypt(plaintext, password);
+			gearsWorkerPool.sendMessage(String(results), sender);
+		}else if(cmd == "decr"){
+			arg = eval("(" + arg + ")");
+			var ciphertext = arg.ciphertext;
+			var password = arg.password;
+			var results = decrypt(ciphertext, password);
+			gearsWorkerPool.sendMessage(String(results), sender);
+		}
+	}
+});
+
+}
+
+if(!dojo._hasResource["dojox.sql._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.sql._base"] = true;
+dojo.provide("dojox.sql._base");
+
+
+dojo.mixin(dojox.sql, {
+	// summary:
+	//	Executes a SQL expression.
+	// description:
+	// 	There are four ways to call this:
+	// 	1) Straight SQL: dojox.sql("SELECT * FROM FOOBAR");
+	// 	2) SQL with parameters: dojox.sql("INSERT INTO FOOBAR VALUES (?)", someParam)
+	// 	3) Encrypting particular values: 
+	//			dojox.sql("INSERT INTO FOOBAR VALUES (ENCRYPT(?))", someParam, "somePassword", callback)
+	// 	4) Decrypting particular values:
+	//			dojox.sql("SELECT DECRYPT(SOMECOL1), DECRYPT(SOMECOL2) FROM
+	//					FOOBAR WHERE SOMECOL3 = ?", someParam,
+	//					"somePassword", callback)
+	//
+	// 	For encryption and decryption the last two values should be the the password for
+	// 	encryption/decryption, and the callback function that gets the result set.
+	//
+	// 	Note: We only support ENCRYPT(?) statements, and
+	// 	and DECRYPT(*) statements for now -- you can not have a literal string
+	// 	inside of these, such as ENCRYPT('foobar')
+	//
+	// 	Note: If you have multiple columns to encrypt and decrypt, you can use the following
+	// 	convenience form to not have to type ENCRYPT(?)/DECRYPT(*) many times:
+	//
+	// 	dojox.sql("INSERT INTO FOOBAR VALUES (ENCRYPT(?, ?, ?))", 
+	//					someParam1, someParam2, someParam3, 
+	//					"somePassword", callback)
+	//
+	// 	dojox.sql("SELECT DECRYPT(SOMECOL1, SOMECOL2) FROM
+	//					FOOBAR WHERE SOMECOL3 = ?", someParam,
+	//					"somePassword", callback)
+
+	dbName: null,
+	
+	// summary:
+	//	If true, then we print out any SQL that is executed
+	//	to the debug window
+	debug: (dojo.exists("dojox.sql.debug") ? dojox.sql.debug:false),
+
+	open: function(dbName){
+		if(this._dbOpen && (!dbName || dbName == this.dbName)){
+			return;
+		}
+		
+		if(!this.dbName){
+			this.dbName = "dot_store_" 
+				+ window.location.href.replace(/[^0-9A-Za-z_]/g, "_");
+			// database names in Gears are limited to 64 characters long
+			if(this.dbName.length > 63){
+			  this.dbName = this.dbName.substring(0, 63);
+			}
+		}
+		
+		if(!dbName){
+			dbName = this.dbName;
+		}
+		
+		try{
+			this._initDb();
+			this.db.open(dbName);
+			this._dbOpen = true;
+		}catch(exp){
+			throw exp.message||exp;
+		}
+	},
+
+	close: function(dbName){
+		// on Internet Explorer, Google Gears throws an exception
+		// "Object not a collection", when we try to close the
+		// database -- just don't close it on this platform
+		// since we are running into a Gears bug; the Gears team
+		// said it's ok to not close a database connection
+		if(dojo.isIE){ return; }
+		
+		if(!this._dbOpen && (!dbName || dbName == this.dbName)){
+			return;
+		}
+		
+		if(!dbName){
+			dbName = this.dbName;
+		}
+		
+		try{
+			this.db.close(dbName);
+			this._dbOpen = false;
+		}catch(exp){
+			throw exp.message||exp;
+		}
+	},
+	
+	_exec: function(params){
+		try{	
+			// get the Gears Database object
+			this._initDb();
+		
+			// see if we need to open the db; if programmer
+			// manually called dojox.sql.open() let them handle
+			// it; otherwise we open and close automatically on
+			// each SQL execution
+			if(!this._dbOpen){
+				this.open();
+				this._autoClose = true;
+			}
+		
+			// determine our parameters
+			var sql = null;
+			var callback = null;
+			var password = null;
+
+			var args = dojo._toArray(params);
+
+			sql = args.splice(0, 1)[0];
+
+			// does this SQL statement use the ENCRYPT or DECRYPT
+			// keywords? if so, extract our callback and crypto
+			// password
+			if(this._needsEncrypt(sql) || this._needsDecrypt(sql)){
+				callback = args.splice(args.length - 1, 1)[0];
+				password = args.splice(args.length - 1, 1)[0];
+			}
+
+			// 'args' now just has the SQL parameters
+
+			// print out debug SQL output if the developer wants that
+			if(this.debug){
+				this._printDebugSQL(sql, args);
+			}
+
+			// handle SQL that needs encryption/decryption differently
+			// do we have an ENCRYPT SQL statement? if so, handle that first
+			var crypto;
+			if(this._needsEncrypt(sql)){
+				crypto = new dojox.sql._SQLCrypto("encrypt", sql, 
+													password, args, 
+													callback);
+				return null; // encrypted results will arrive asynchronously
+			}else if(this._needsDecrypt(sql)){ // otherwise we have a DECRYPT statement
+				crypto = new dojox.sql._SQLCrypto("decrypt", sql, 
+													password, args, 
+													callback);
+				return null; // decrypted results will arrive asynchronously
+			}
+
+			// execute the SQL and get the results
+			var rs = this.db.execute(sql, args);
+			
+			// Gears ResultSet object's are ugly -- normalize
+			// these into something JavaScript programmers know
+			// how to work with, basically an array of 
+			// JavaScript objects where each property name is
+			// simply the field name for a column of data
+			rs = this._normalizeResults(rs);
+		
+			if(this._autoClose){
+				this.close();
+			}
+		
+			return rs;
+		}catch(exp){
+			exp = exp.message||exp;
+			
+			
+			
+			if(this._autoClose){
+				try{ 
+					this.close(); 
+				}catch(e){
+					
+				}
+			}
+		
+			throw exp;
+		}
+		
+		return null;
+	},
+
+	_initDb: function(){
+		if(!this.db){
+			try{
+				this.db = google.gears.factory.create('beta.database', '1.0');
+			}catch(exp){
+				dojo.setObject("google.gears.denied", true);
+				if(dojox.off){
+				  dojox.off.onFrameworkEvent("coreOperationFailed");
+				}
+				throw "Google Gears must be allowed to run";
+			}
+		}
+	},
+
+	_printDebugSQL: function(sql, args){
+		var msg = "dojox.sql(\"" + sql + "\"";
+		for(var i = 0; i < args.length; i++){
+			if(typeof args[i] == "string"){
+				msg += ", \"" + args[i] + "\"";
+			}else{
+				msg += ", " + args[i];
+			}
+		}
+		msg += ")";
+	
+		
+	},
+
+	_normalizeResults: function(rs){
+		var results = [];
+		if(!rs){ return []; }
+	
+		while(rs.isValidRow()){
+			var row = {};
+		
+			for(var i = 0; i < rs.fieldCount(); i++){
+				var fieldName = rs.fieldName(i);
+				var fieldValue = rs.field(i);
+				row[fieldName] = fieldValue;
+			}
+		
+			results.push(row);
+		
+			rs.next();
+		}
+	
+		rs.close();
+		
+		return results;
+	},
+
+	_needsEncrypt: function(sql){
+		return /encrypt\([^\)]*\)/i.test(sql);
+	},
+
+	_needsDecrypt: function(sql){
+		return /decrypt\([^\)]*\)/i.test(sql);
+	}
+});
+
+dojo.declare("dojox.sql._SQLCrypto", null, {
+	// summary:
+	//	A private class encapsulating any cryptography that must be done
+	// 	on a SQL statement. We instantiate this class and have it hold
+	//	it's state so that we can potentially have several encryption
+	//	operations happening at the same time by different SQL statements.	
+	constructor: function(action, sql, password, args, callback){
+		if(action == "encrypt"){
+			this._execEncryptSQL(sql, password, args, callback);
+		}else{
+			this._execDecryptSQL(sql, password, args, callback);
+		}		
+	}, 
+	
+	_execEncryptSQL: function(sql, password, args, callback){
+		// strip the ENCRYPT/DECRYPT keywords from the SQL
+		var strippedSQL = this._stripCryptoSQL(sql);
+	
+		// determine what arguments need encryption
+		var encryptColumns = this._flagEncryptedArgs(sql, args);
+	
+		// asynchronously encrypt each argument that needs it
+		var self = this;
+		this._encrypt(strippedSQL, password, args, encryptColumns, function(finalArgs){
+			// execute the SQL
+			var error = false;
+			var resultSet = [];
+			var exp = null;
+			try{
+				resultSet = dojox.sql.db.execute(strippedSQL, finalArgs);
+			}catch(execError){
+				error = true;
+				exp = execError.message||execError;
+			}
+		
+			// was there an error during SQL execution?
+			if(exp != null){
+				if(dojox.sql._autoClose){
+					try{ dojox.sql.close(); }catch(e){}
+				}
+			
+				callback(null, true, exp.toString());
+				return;
+			}
+		
+			// normalize SQL results into a JavaScript object 
+			// we can work with
+			resultSet = dojox.sql._normalizeResults(resultSet);
+		
+			if(dojox.sql._autoClose){
+				dojox.sql.close();
+			}
+				
+			// are any decryptions necessary on the result set?
+			if(dojox.sql._needsDecrypt(sql)){
+				// determine which of the result set columns needs decryption
+	 			var needsDecrypt = self._determineDecryptedColumns(sql);
+
+				// now decrypt columns asynchronously
+				// decrypt columns that need it
+				self._decrypt(resultSet, needsDecrypt, password, function(finalResultSet){
+					callback(finalResultSet, false, null);
+				});
+			}else{
+				callback(resultSet, false, null);
+			}
+		});
+	},
+
+	_execDecryptSQL: function(sql, password, args, callback){
+		// strip the ENCRYPT/DECRYPT keywords from the SQL
+		var strippedSQL = this._stripCryptoSQL(sql);
+	
+		// determine which columns needs decryption; this either
+		// returns the value *, which means all result set columns will
+		// be decrypted, or it will return the column names that need
+		// decryption set on a hashtable so we can quickly test a given
+		// column name; the key is the column name that needs
+		// decryption and the value is 'true' (i.e. needsDecrypt["someColumn"] 
+		// would return 'true' if it needs decryption, and would be 'undefined'
+		// or false otherwise)
+		var needsDecrypt = this._determineDecryptedColumns(sql);
+	
+		// execute the SQL
+		var error = false;
+		var resultSet = [];
+		var exp = null;
+		try{
+			resultSet = dojox.sql.db.execute(strippedSQL, args);
+		}catch(execError){
+			error = true;
+			exp = execError.message||execError;
+		}
+	
+		// was there an error during SQL execution?
+		if(exp != null){
+			if(dojox.sql._autoClose){
+				try{ dojox.sql.close(); }catch(e){}
+			}
+		
+			callback(resultSet, true, exp.toString());
+			return;
+		}
+	
+		// normalize SQL results into a JavaScript object 
+		// we can work with
+		resultSet = dojox.sql._normalizeResults(resultSet);
+	
+		if(dojox.sql._autoClose){
+			dojox.sql.close();
+		}
+	
+		// decrypt columns that need it
+		this._decrypt(resultSet, needsDecrypt, password, function(finalResultSet){
+			callback(finalResultSet, false, null);
+		});
+	},
+
+	_encrypt: function(sql, password, args, encryptColumns, callback){
+		//
+	
+		this._totalCrypto = 0;
+		this._finishedCrypto = 0;
+		this._finishedSpawningCrypto = false;
+		this._finalArgs = args;
+	
+		for(var i = 0; i < args.length; i++){
+			if(encryptColumns[i]){
+				// we have an encrypt() keyword -- get just the value inside
+				// the encrypt() parantheses -- for now this must be a ?
+				var sqlParam = args[i];
+				var paramIndex = i;
+			
+				// update the total number of encryptions we know must be done asynchronously
+				this._totalCrypto++;
+			
+				// FIXME: This currently uses DES as a proof-of-concept since the
+				// DES code used is quite fast and was easy to work with. Modify dojox.sql
+				// to be able to specify a different encryption provider through a 
+				// a SQL-like syntax, such as dojox.sql("SET ENCRYPTION BLOWFISH"),
+				// and modify the dojox.crypto.Blowfish code to be able to work using
+				// a Google Gears Worker Pool
+			
+				// do the actual encryption now, asychronously on a Gears worker thread
+				dojox.sql._crypto.encrypt(sqlParam, password, dojo.hitch(this, function(results){
+					// set the new encrypted value
+					this._finalArgs[paramIndex] = results;
+					this._finishedCrypto++;
+					// are we done with all encryption?
+					if(this._finishedCrypto >= this._totalCrypto
+						&& this._finishedSpawningCrypto){
+						callback(this._finalArgs);
+					}
+				}));
+			}
+		}
+	
+		this._finishedSpawningCrypto = true;
+	},
+
+	_decrypt: function(resultSet, needsDecrypt, password, callback){
+		//
+		
+		this._totalCrypto = 0;
+		this._finishedCrypto = 0;
+		this._finishedSpawningCrypto = false;
+		this._finalResultSet = resultSet;
+	
+		for(var i = 0; i < resultSet.length; i++){
+			var row = resultSet[i];
+		
+			// go through each of the column names in row,
+			// seeing if they need decryption
+			for(var columnName in row){
+				if(needsDecrypt == "*" || needsDecrypt[columnName]){
+					this._totalCrypto++;
+					var columnValue = row[columnName];
+				
+					// forming a closure here can cause issues, with values not cleanly
+					// saved on Firefox/Mac OS X for some of the values above that
+					// are needed in the callback below; call a subroutine that will form 
+					// a closure inside of itself instead
+					this._decryptSingleColumn(columnName, columnValue, password, i,
+												function(finalResultSet){
+						callback(finalResultSet);
+					});
+				}
+			}
+		}
+	
+		this._finishedSpawningCrypto = true;
+	},
+
+	_stripCryptoSQL: function(sql){
+		// replace all DECRYPT(*) occurrences with a *
+		sql = sql.replace(/DECRYPT\(\*\)/ig, "*");
+	
+		// match any ENCRYPT(?, ?, ?, etc) occurrences,
+		// then replace with just the question marks in the
+		// middle
+		var matches = sql.match(/ENCRYPT\([^\)]*\)/ig);
+		if(matches != null){
+			for(var i = 0; i < matches.length; i++){
+				var encryptStatement = matches[i];
+				var encryptValue = encryptStatement.match(/ENCRYPT\(([^\)]*)\)/i)[1];
+				sql = sql.replace(encryptStatement, encryptValue);
+			}
+		}
+	
+		// match any DECRYPT(COL1, COL2, etc) occurrences,
+		// then replace with just the column names
+		// in the middle
+		matches = sql.match(/DECRYPT\([^\)]*\)/ig);
+		if(matches != null){
+			for(i = 0; i < matches.length; i++){
+				var decryptStatement = matches[i];
+				var decryptValue = decryptStatement.match(/DECRYPT\(([^\)]*)\)/i)[1];
+				sql = sql.replace(decryptStatement, decryptValue);
+			}
+		}
+	
+		return sql;
+	},
+
+	_flagEncryptedArgs: function(sql, args){
+		// capture literal strings that have question marks in them,
+		// and also capture question marks that stand alone
+		var tester = new RegExp(/([\"][^\"]*\?[^\"]*[\"])|([\'][^\']*\?[^\']*[\'])|(\?)/ig);
+		var matches;
+		var currentParam = 0;
+		var results = [];
+		while((matches = tester.exec(sql)) != null){
+			var currentMatch = RegExp.lastMatch+"";
+
+			// are we a literal string? then ignore it
+			if(/^[\"\']/.test(currentMatch)){
+				continue;
+			}
+
+			// do we have an encrypt keyword to our left?
+			var needsEncrypt = false;
+			if(/ENCRYPT\([^\)]*$/i.test(RegExp.leftContext)){
+				needsEncrypt = true;
+			}
+
+			// set the encrypted flag
+			results[currentParam] = needsEncrypt;
+
+			currentParam++;
+		}
+	
+		return results;
+	},
+
+	_determineDecryptedColumns: function(sql){
+		var results = {};
+
+		if(/DECRYPT\(\*\)/i.test(sql)){
+			results = "*";
+		}else{
+			var tester = /DECRYPT\((?:\s*\w*\s*\,?)*\)/ig;
+			var matches = tester.exec(sql);
+			while(matches){
+				var lastMatch = new String(RegExp.lastMatch);
+				var columnNames = lastMatch.replace(/DECRYPT\(/i, "");
+				columnNames = columnNames.replace(/\)/, "");
+				columnNames = columnNames.split(/\s*,\s*/);
+				dojo.forEach(columnNames, function(column){
+					if(/\s*\w* AS (\w*)/i.test(column)){
+						column = column.match(/\s*\w* AS (\w*)/i)[1];
+					}
+					results[column] = true;
+				});
+				
+				matches = tester.exec(sql)
+			}
+		}
+
+		return results;
+	},
+
+	_decryptSingleColumn: function(columnName, columnValue, password, currentRowIndex,
+											callback){
+		//
+		dojox.sql._crypto.decrypt(columnValue, password, dojo.hitch(this, function(results){
+			// set the new decrypted value
+			this._finalResultSet[currentRowIndex][columnName] = results;
+			this._finishedCrypto++;
+			
+			// are we done with all encryption?
+			if(this._finishedCrypto >= this._totalCrypto
+				&& this._finishedSpawningCrypto){
+				//
+				callback(this._finalResultSet);
+			}
+		}));
+	}
+});
+
+(function(){
+
+	var orig_sql = dojox.sql;
+	dojox.sql = new Function("return dojox.sql._exec(arguments);");
+	dojo.mixin(dojox.sql, orig_sql);
+	
+})();
+
+}
+
+if(!dojo._hasResource["dojox.sql"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.sql"] = true;
+dojo.provide("dojox.sql"); 
+
+
+}
+
+if(!dojo._hasResource["dojox.storage.GearsStorageProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.storage.GearsStorageProvider"] = true;
+dojo.provide("dojox.storage.GearsStorageProvider");
+
+
+
+
+
+if(dojo.gears.available){
+	
+	(function(){
+		// make sure we don't define the gears provider if we're not gears
+		// enabled
+		
+		dojo.declare("dojox.storage.GearsStorageProvider", dojox.storage.Provider, {
+			// summary:
+			//		Storage provider that uses the features of Google Gears
+			//		to store data (it is saved into the local SQL database
+			//		provided by Gears, using dojox.sql)
+			// description: 
+			//		You can disable this storage provider with the following djConfig
+			//		variable:
+			//		var djConfig = { disableGearsStorage: true };
+			//		
+			//		Authors of this storage provider-	
+			//			Brad Neuberg, bkn3 at columbia.edu 
+			constructor: function(){
+			},
+			// instance methods and properties
+			TABLE_NAME: "__DOJO_STORAGE",
+			initialized: false,
+			
+			_available: null,
+			_storageReady: false,
+			
+			initialize: function(){
+				//
+				if(dojo.config["disableGearsStorage"] == true){
+					return;
+				}
+				
+				// partition our storage data so that multiple apps
+				// on the same host won't collide
+				this.TABLE_NAME = "__DOJO_STORAGE";
+				
+				// we delay creating our internal tables until an operation is
+				// actually called, to avoid having a Gears permission dialog
+				// on page load (bug #7538)
+				
+				// indicate that this storage provider is now loaded
+				this.initialized = true;
+				dojox.storage.manager.loaded();	
+			},
+			
+			isAvailable: function(){
+				// is Google Gears available and defined?
+				return this._available = dojo.gears.available;
+			},
+
+			put: function(key, value, resultsHandler, namespace){
+				this._initStorage();
+				
+				if(!this.isValidKey(key)){
+					throw new Error("Invalid key given: " + key);
+				}
+				
+				namespace = namespace||this.DEFAULT_NAMESPACE;
+				if(!this.isValidKey(namespace)){
+					throw new Error("Invalid namespace given: " + key);
+				}
+				
+				// serialize the value;
+				// handle strings differently so they have better performance
+				if(dojo.isString(value)){
+					value = "string:" + value;
+				}else{
+					value = dojo.toJson(value);
+				}
+				
+				// try to store the value	
+				try{
+					dojox.sql("DELETE FROM " + this.TABLE_NAME
+								+ " WHERE namespace = ? AND key = ?",
+								namespace, key);
+					dojox.sql("INSERT INTO " + this.TABLE_NAME
+								+ " VALUES (?, ?, ?)",
+								namespace, key, value);
+				}catch(e){
+					// indicate we failed
+					
+					resultsHandler(this.FAILED, key, e.toString(), namespace);
+					return;
+				}
+				
+				if(resultsHandler){
+					resultsHandler(dojox.storage.SUCCESS, key, null, namespace);
+				}
+			},
+
+			get: function(key, namespace){
+				this._initStorage();
+				
+				if(!this.isValidKey(key)){
+					throw new Error("Invalid key given: " + key);
+				}
+				
+				namespace = namespace||this.DEFAULT_NAMESPACE;
+				if(!this.isValidKey(namespace)){
+					throw new Error("Invalid namespace given: " + key);
+				}
+				
+				// try to find this key in the database
+				var results = dojox.sql("SELECT * FROM " + this.TABLE_NAME
+											+ " WHERE namespace = ? AND "
+											+ " key = ?",
+											namespace, key);
+				if(!results.length){
+					return null;
+				}else{
+					results = results[0].value;
+				}
+				
+				// destringify the content back into a 
+				// real JavaScript object;
+				// handle strings differently so they have better performance
+				if(dojo.isString(results) && (/^string:/.test(results))){
+					results = results.substring("string:".length);
+				}else{
+					results = dojo.fromJson(results);
+				}
+				
+				return results;
+			},
+			
+			getNamespaces: function(){
+				this._initStorage();
+				
+				var results = [ dojox.storage.DEFAULT_NAMESPACE ];
+				
+				var rs = dojox.sql("SELECT namespace FROM " + this.TABLE_NAME
+									+ " DESC GROUP BY namespace");
+				for(var i = 0; i < rs.length; i++){
+					if(rs[i].namespace != dojox.storage.DEFAULT_NAMESPACE){
+						results.push(rs[i].namespace);
+					}
+				}
+				
+				return results;
+			},
+
+			getKeys: function(namespace){
+				this._initStorage();
+				
+				namespace = namespace||this.DEFAULT_NAMESPACE;
+				if(!this.isValidKey(namespace)){
+					throw new Error("Invalid namespace given: " + namespace);
+				}
+				
+				var rs = dojox.sql("SELECT key FROM " + this.TABLE_NAME
+									+ " WHERE namespace = ?",
+									namespace);
+				
+				var results = [];
+				for(var i = 0; i < rs.length; i++){
+					results.push(rs[i].key);
+				}
+				
+				return results;
+			},
+
+			clear: function(namespace){
+				this._initStorage();
+				
+				namespace = namespace||this.DEFAULT_NAMESPACE;
+				if(!this.isValidKey(namespace)){
+					throw new Error("Invalid namespace given: " + namespace);
+				}
+				
+				dojox.sql("DELETE FROM " + this.TABLE_NAME 
+							+ " WHERE namespace = ?",
+							namespace);
+			},
+			
+			remove: function(key, namespace){
+				this._initStorage();
+				
+				if(!this.isValidKey(key)){
+					throw new Error("Invalid key given: " + key);
+				}
+				
+				namespace = namespace||this.DEFAULT_NAMESPACE;
+				if(!this.isValidKey(namespace)){
+					throw new Error("Invalid namespace given: " + key);
+				}
+				
+				dojox.sql("DELETE FROM " + this.TABLE_NAME 
+							+ " WHERE namespace = ? AND"
+							+ " key = ?",
+							namespace,
+							key);
+			},
+			
+			putMultiple: function(keys, values, resultsHandler, namespace) {
+				this._initStorage();
+				
+ 				if(!this.isValidKeyArray(keys) 
+						|| ! values instanceof Array 
+						|| keys.length != values.length){
+					throw new Error("Invalid arguments: keys = [" 
+									+ keys + "], values = [" + values + "]");
+				}
+				
+				if(namespace == null || typeof namespace == "undefined"){
+					namespace = dojox.storage.DEFAULT_NAMESPACE;		
+				}
+				if(!this.isValidKey(namespace)){
+					throw new Error("Invalid namespace given: " + namespace);
+				}
+	
+				this._statusHandler = resultsHandler;
+
+				// try to store the value	
+				try{
+					dojox.sql.open();
+					dojox.sql.db.execute("BEGIN TRANSACTION");
+					var _stmt = "REPLACE INTO " + this.TABLE_NAME + " VALUES (?, ?, ?)";
+					for(var i=0;i<keys.length;i++) {
+						// serialize the value;
+						// handle strings differently so they have better performance
+						var value = values[i];
+						if(dojo.isString(value)){
+							value = "string:" + value;
+						}else{
+							value = dojo.toJson(value);
+						}
+				
+						dojox.sql.db.execute( _stmt,
+							[namespace, keys[i], value]);
+					}
+					dojox.sql.db.execute("COMMIT TRANSACTION");
+					dojox.sql.close();
+				}catch(e){
+					// indicate we failed
+					
+					if(resultsHandler){
+						resultsHandler(this.FAILED, keys, e.toString(), namespace);
+					}
+					return;
+				}
+				
+				if(resultsHandler){
+					resultsHandler(dojox.storage.SUCCESS, keys, null, namespace);
+				}
+			},
+
+			getMultiple: function(keys, namespace){
+				//	TODO: Maybe use SELECT IN instead
+				this._initStorage();
+
+				if(!this.isValidKeyArray(keys)){
+					throw new ("Invalid key array given: " + keys);
+				}
+				
+				if(namespace == null || typeof namespace == "undefined"){
+					namespace = dojox.storage.DEFAULT_NAMESPACE;		
+				}
+				if(!this.isValidKey(namespace)){
+					throw new Error("Invalid namespace given: " + namespace);
+				}
+		
+				var _stmt = "SELECT * FROM " + this.TABLE_NAME 
+					+ " WHERE namespace = ? AND "	+ " key = ?";
+				
+				var results = [];
+				for(var i=0;i<keys.length;i++){
+					var result = dojox.sql( _stmt, namespace, keys[i]);
+						
+					if( ! result.length){
+						results[i] = null;
+					}else{
+						result = result[0].value;
+						
+						// destringify the content back into a 
+						// real JavaScript object;
+						// handle strings differently so they have better performance
+						if(dojo.isString(result) && (/^string:/.test(result))){
+							results[i] = result.substring("string:".length);
+						}else{
+							results[i] = dojo.fromJson(result);
+						}
+					}
+				}
+				
+				return results;
+			},
+			
+			removeMultiple: function(keys, namespace){
+				this._initStorage();
+				
+				if(!this.isValidKeyArray(keys)){
+					throw new Error("Invalid arguments: keys = [" + keys + "]");
+				}
+				
+				if(namespace == null || typeof namespace == "undefined"){
+					namespace = dojox.storage.DEFAULT_NAMESPACE;		
+				}
+				if(!this.isValidKey(namespace)){
+					throw new Error("Invalid namespace given: " + namespace);
+				}
+				
+				dojox.sql.open();
+				dojox.sql.db.execute("BEGIN TRANSACTION");
+				var _stmt = "DELETE FROM " + this.TABLE_NAME 
+										+ " WHERE namespace = ? AND key = ?";
+
+				for(var i=0;i<keys.length;i++){
+					dojox.sql.db.execute( _stmt,
+						[namespace, keys[i]]);
+				}
+				dojox.sql.db.execute("COMMIT TRANSACTION");
+				dojox.sql.close();
+			}, 				
+			
+			isPermanent: function(){ return true; },
+
+			getMaximumSize: function(){ return this.SIZE_NO_LIMIT; },
+
+			hasSettingsUI: function(){ return false; },
+			
+			showSettingsUI: function(){
+				throw new Error(this.declaredClass 
+									+ " does not support a storage settings user-interface");
+			},
+			
+			hideSettingsUI: function(){
+				throw new Error(this.declaredClass 
+									+ " does not support a storage settings user-interface");
+			},
+			
+			_initStorage: function(){
+				// we delay creating the tables until an operation is actually
+				// called so that we don't give a Gears dialog right on page
+				// load (bug #7538)
+				if (this._storageReady) {
+					return;
+				}
+				
+				if (!google.gears.factory.hasPermission) {
+					var siteName = null;
+					var icon = null;
+					var msg = 'This site would like to use Google Gears to enable '
+										+ 'enhanced functionality.';
+					var allowed = google.gears.factory.getPermission(siteName, icon, msg);
+					if (!allowed) {
+						throw new Error('You must give permission to use Gears in order to '
+														+ 'store data');
+					}
+				}
+				
+				// create the table that holds our data
+				try{
+					dojox.sql("CREATE TABLE IF NOT EXISTS " + this.TABLE_NAME + "( "
+								+ " namespace TEXT, "
+								+ " key TEXT, "
+								+ " value TEXT "
+								+ ")"
+							);
+					dojox.sql("CREATE UNIQUE INDEX IF NOT EXISTS namespace_key_index" 
+								+ " ON " + this.TABLE_NAME
+								+ " (namespace, key)");
+				}catch(e){
+					
+					throw new Error('Unable to create storage tables for Gears in '
+					                + 'Dojo Storage');
+				}
+				
+				this._storageReady = true;
+		  }
+		});
+
+		// register the existence of our storage providers
+		dojox.storage.manager.register("dojox.storage.GearsStorageProvider",
+										new dojox.storage.GearsStorageProvider());
+	})();
+}
+
+}
+
+if(!dojo._hasResource["dojox.storage.WhatWGStorageProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.storage.WhatWGStorageProvider"] = true;
+dojo.provide("dojox.storage.WhatWGStorageProvider");
+
+
+
+dojo.declare("dojox.storage.WhatWGStorageProvider", [ dojox.storage.Provider ], {
+	// summary:
+	//		Storage provider that uses WHAT Working Group features in Firefox 2 
+	//		to achieve permanent storage.
+	// description: 
+	//		The WHAT WG storage API is documented at 
+	//		http://www.whatwg.org/specs/web-apps/current-work/#scs-client-side
+	//
+	//		You can disable this storage provider with the following djConfig
+	//		variable:
+	//		var djConfig = { disableWhatWGStorage: true };
+	//		
+	//		Authors of this storage provider-	
+	//			JB Boisseau, jb.boisseau at eutech-ssii.com
+	//			Brad Neuberg, bkn3 at columbia.edu 
+
+	initialized: false,
+	
+	_domain: null,
+	_available: null,
+	_statusHandler: null,
+	_allNamespaces: null,
+	_storageEventListener: null,
+	
+	initialize: function(){
+		if(dojo.config["disableWhatWGStorage"] == true){
+			return;
+		}
+		
+		// get current domain
+		this._domain = this._getDomain();
+		// 
+		
+		// indicate that this storage provider is now loaded
+		this.initialized = true;
+		dojox.storage.manager.loaded();	
+	},
+	
+	isAvailable: function(){
+		try{
+			var myStorage = globalStorage[this._getDomain()]; 
+		}catch(e){
+			this._available = false;
+			return this._available;
+		}
+		
+		this._available = true;	
+		return this._available;
+	},
+
+	put: function(key, value, resultsHandler, namespace){
+		if(this.isValidKey(key) == false){
+			throw new Error("Invalid key given: " + key);
+		}
+		namespace = namespace||this.DEFAULT_NAMESPACE;
+		
+		// get our full key name, which is namespace + key
+		key = this.getFullKey(key, namespace);	
+		
+		this._statusHandler = resultsHandler;
+		
+		// serialize the value;
+		// handle strings differently so they have better performance
+		if(dojo.isString(value)){
+			value = "string:" + value;
+		}else{
+			value = dojo.toJson(value);
+		}
+		
+		// register for successful storage events.
+		var storageListener = dojo.hitch(this, function(evt){
+			// remove any old storage event listener we might have added
+			// to the window on old put() requests; Firefox has a bug
+			// where it can occassionaly go into infinite loops calling
+			// our storage event listener over and over -- this is a 
+			// workaround
+			// FIXME: Simplify this into a test case and submit it
+			// to Firefox
+			window.removeEventListener("storage", storageListener, false);
+			
+			// indicate we succeeded
+			if(resultsHandler){
+				resultsHandler.call(null, this.SUCCESS, key, null, namespace);
+			}
+		});
+		
+		window.addEventListener("storage", storageListener, false);
+		
+		// try to store the value	
+		try{
+			var myStorage = globalStorage[this._domain];
+			myStorage.setItem(key, value);
+		}catch(e){
+			// indicate we failed
+			this._statusHandler.call(null, this.FAILED, key, e.toString(), namespace);
+		}
+	},
+
+	get: function(key, namespace){
+		if(this.isValidKey(key) == false){
+			throw new Error("Invalid key given: " + key);
+		}
+		namespace = namespace||this.DEFAULT_NAMESPACE;
+		
+		// get our full key name, which is namespace + key
+		key = this.getFullKey(key, namespace);
+		
+		// sometimes, even if a key doesn't exist, Firefox
+		// will return a blank string instead of a null --
+		// this _might_ be due to having underscores in the
+		// keyname, but I am not sure.
+		
+		// FIXME: Simplify this bug into a testcase and
+		// submit it to Firefox
+		var myStorage = globalStorage[this._domain];
+		var results = myStorage.getItem(key);
+		
+		if(results == null || results == ""){
+			return null;
+		}
+		
+		results = results.value;
+		
+		// destringify the content back into a 
+		// real JavaScript object;
+		// handle strings differently so they have better performance
+		if(dojo.isString(results) && (/^string:/.test(results))){
+			results = results.substring("string:".length);
+		}else{
+			results = dojo.fromJson(results);
+		}
+		
+		return results;
+	},
+	
+	getNamespaces: function(){
+		var results = [ this.DEFAULT_NAMESPACE ];
+		
+		// simply enumerate through our array and save any string
+		// that starts with __
+		var found = {};
+		var myStorage = globalStorage[this._domain];
+		var tester = /^__([^_]*)_/;
+		for(var i = 0; i < myStorage.length; i++){
+			var currentKey = myStorage.key(i);
+			if(tester.test(currentKey) == true){
+				var currentNS = currentKey.match(tester)[1];
+				// have we seen this namespace before?
+				if(typeof found[currentNS] == "undefined"){
+					found[currentNS] = true;
+					results.push(currentNS);
+				}
+			}
+		}
+		
+		return results;
+	},
+
+	getKeys: function(namespace){
+		namespace = namespace||this.DEFAULT_NAMESPACE;
+		
+		if(this.isValidKey(namespace) == false){
+			throw new Error("Invalid namespace given: " + namespace);
+		}
+		
+		// create a regular expression to test the beginning
+		// of our key names to see if they match our namespace;
+		// if it is the default namespace then test for the presence
+		// of no namespace for compatibility with older versions
+		// of dojox.storage
+		var namespaceTester;
+		if(namespace == this.DEFAULT_NAMESPACE){
+			namespaceTester = new RegExp("^([^_]{2}.*)$");	
+		}else{
+			namespaceTester = new RegExp("^__" + namespace + "_(.*)$");
+		}
+		
+		var myStorage = globalStorage[this._domain];
+		var keysArray = [];
+		for(var i = 0; i < myStorage.length; i++){
+			var currentKey = myStorage.key(i);
+			if(namespaceTester.test(currentKey) == true){
+				// strip off the namespace portion
+				currentKey = currentKey.match(namespaceTester)[1];
+				keysArray.push(currentKey);
+			}
+		}
+		
+		return keysArray;
+	},
+
+	clear: function(namespace){
+		namespace = namespace||this.DEFAULT_NAMESPACE;
+		
+		if(this.isValidKey(namespace) == false){
+			throw new Error("Invalid namespace given: " + namespace);
+		}
+		
+		// create a regular expression to test the beginning
+		// of our key names to see if they match our namespace;
+		// if it is the default namespace then test for the presence
+		// of no namespace for compatibility with older versions
+		// of dojox.storage
+		var namespaceTester;
+		if(namespace == this.DEFAULT_NAMESPACE){
+			namespaceTester = new RegExp("^[^_]{2}");	
+		}else{
+			namespaceTester = new RegExp("^__" + namespace + "_");
+		}
+		
+		var myStorage = globalStorage[this._domain];
+		var keys = [];
+		for(var i = 0; i < myStorage.length; i++){
+			if(namespaceTester.test(myStorage.key(i)) == true){
+				keys[keys.length] = myStorage.key(i);
+			}
+		}
+		
+		dojo.forEach(keys, dojo.hitch(myStorage, "removeItem"));
+	},
+	
+	remove: function(key, namespace){
+		// get our full key name, which is namespace + key
+		key = this.getFullKey(key, namespace);
+		
+		var myStorage = globalStorage[this._domain];
+		myStorage.removeItem(key);
+	},
+	
+	isPermanent: function(){
+		return true;
+	},
+
+	getMaximumSize: function(){
+		return this.SIZE_NO_LIMIT;
+	},
+
+	hasSettingsUI: function(){
+		return false;
+	},
+	
+	showSettingsUI: function(){
+		throw new Error(this.declaredClass + " does not support a storage settings user-interface");
+	},
+	
+	hideSettingsUI: function(){
+		throw new Error(this.declaredClass + " does not support a storage settings user-interface");
+	},
+	
+	getFullKey: function(key, namespace){
+		namespace = namespace||this.DEFAULT_NAMESPACE;
+		
+		if(this.isValidKey(namespace) == false){
+			throw new Error("Invalid namespace given: " + namespace);
+		}
+		
+		// don't append a namespace string for the default namespace,
+		// for compatibility with older versions of dojox.storage
+		if(namespace == this.DEFAULT_NAMESPACE){
+			return key;
+		}else{
+			return "__" + namespace + "_" + key;
+		}
+	},
+
+	_getDomain: function(){
+		// see: https://bugzilla.mozilla.org/show_bug.cgi?id=357323
+		return ((location.hostname == "localhost" && dojo.isFF && dojo.isFF < 3) ? "localhost.localdomain" : location.hostname);
+	}
+});
+
+dojox.storage.manager.register("dojox.storage.WhatWGStorageProvider", 
+								new dojox.storage.WhatWGStorageProvider());
+
+}
+
+if(!dojo._hasResource["dojo.AdapterRegistry"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.AdapterRegistry"] = true;
+dojo.provide("dojo.AdapterRegistry");
+
+dojo.AdapterRegistry = function(/*Boolean?*/ returnWrappers){
+	//	summary:
+	//		A registry to make contextual calling/searching easier.
+	//	description:
+	//		Objects of this class keep list of arrays in the form [name, check,
+	//		wrap, directReturn] that are used to determine what the contextual
+	//		result of a set of checked arguments is. All check/wrap functions
+	//		in this registry should be of the same arity.
+	//	example:
+	//	|	// create a new registry
+	//	|	var reg = new dojo.AdapterRegistry();
+	//	|	reg.register("handleString",
+	//	|		dojo.isString,
+	//	|		function(str){
+	//	|			// do something with the string here
+	//	|		}
+	//	|	);
+	//	|	reg.register("handleArr",
+	//	|		dojo.isArray,
+	//	|		function(arr){
+	//	|			// do something with the array here
+	//	|		}
+	//	|	);
+	//	|
+	//	|	// now we can pass reg.match() *either* an array or a string and
+	//	|	// the value we pass will get handled by the right function
+	//	|	reg.match("someValue"); // will call the first function
+	//	|	reg.match(["someValue"]); // will call the second
+
+	this.pairs = [];
+	this.returnWrappers = returnWrappers || false; // Boolean
+}
+
+dojo.extend(dojo.AdapterRegistry, {
+	register: function(/*String*/ name, /*Function*/ check, /*Function*/ wrap, /*Boolean?*/ directReturn, /*Boolean?*/ override){
+		//	summary: 
+		//		register a check function to determine if the wrap function or
+		//		object gets selected
+		//	name:
+		//		a way to identify this matcher.
+		//	check:
+		//		a function that arguments are passed to from the adapter's
+		//		match() function.  The check function should return true if the
+		//		given arguments are appropriate for the wrap function.
+		//	directReturn:
+		//		If directReturn is true, the value passed in for wrap will be
+		//		returned instead of being called. Alternately, the
+		//		AdapterRegistry can be set globally to "return not call" using
+		//		the returnWrappers property. Either way, this behavior allows
+		//		the registry to act as a "search" function instead of a
+		//		function interception library.
+		//	override:
+		//		If override is given and true, the check function will be given
+		//		highest priority. Otherwise, it will be the lowest priority
+		//		adapter.
+		this.pairs[((override) ? "unshift" : "push")]([name, check, wrap, directReturn]);
+	},
+
+	match: function(/* ... */){
+		// summary:
+		//		Find an adapter for the given arguments. If no suitable adapter
+		//		is found, throws an exception. match() accepts any number of
+		//		arguments, all of which are passed to all matching functions
+		//		from the registered pairs.
+		for(var i = 0; i < this.pairs.length; i++){
+			var pair = this.pairs[i];
+			if(pair[1].apply(this, arguments)){
+				if((pair[3])||(this.returnWrappers)){
+					return pair[2];
+				}else{
+					return pair[2].apply(this, arguments);
+				}
+			}
+		}
+		throw new Error("No match found");
+	},
+
+	unregister: function(name){
+		// summary: Remove a named adapter from the registry
+
+		// FIXME: this is kind of a dumb way to handle this. On a large
+		// registry this will be slow-ish and we can use the name as a lookup
+		// should we choose to trade memory for speed.
+		for(var i = 0; i < this.pairs.length; i++){
+			var pair = this.pairs[i];
+			if(pair[0] == name){
+				this.pairs.splice(i, 1);
+				return true;
+			}
+		}
+		return false;
+	}
+});
+
+}
+
+if(!dojo._hasResource["dijit._base.place"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.place"] = true;
+dojo.provide("dijit._base.place");
+
+
+
+// ported from dojo.html.util
+
+dijit.getViewport = function(){
+	// summary:
+	//		Returns the dimensions and scroll position of the viewable area of a browser window
+
+	var scrollRoot = (dojo.doc.compatMode == 'BackCompat')? dojo.body() : dojo.doc.documentElement;
+
+	// get scroll position
+	var scroll = dojo._docScroll(); // scrollRoot.scrollTop/Left should work
+	return { w: scrollRoot.clientWidth, h: scrollRoot.clientHeight, l: scroll.x, t: scroll.y };
+};
+
+/*=====
+dijit.__Position = function(){
+	// x: Integer
+	//		horizontal coordinate in pixels, relative to document body
+	// y: Integer
+	//		vertical coordinate in pixels, relative to document body
+
+	thix.x = x;
+	this.y = y;
+}
+=====*/
+
+
+dijit.placeOnScreen = function(
+	/* DomNode */			node,
+	/* dijit.__Position */	pos,
+	/* String[] */			corners,
+	/* dijit.__Position? */	padding){
+	//	summary:
+	//		Positions one of the node's corners at specified position
+	//		such that node is fully visible in viewport.
+	//	description:
+	//		NOTE: node is assumed to be absolutely or relatively positioned.
+	//	pos:
+	//		Object like {x: 10, y: 20}
+	//	corners:
+	//		Array of Strings representing order to try corners in, like ["TR", "BL"].
+	//		Possible values are:
+	//			* "BL" - bottom left
+	//			* "BR" - bottom right
+	//			* "TL" - top left
+	//			* "TR" - top right
+	//	padding:
+	//		set padding to put some buffer around the element you want to position.
+	//	example:	
+	//		Try to place node's top right corner at (10,20).
+	//		If that makes node go (partially) off screen, then try placing
+	//		bottom left corner at (10,20).
+	//	|	placeOnScreen(node, {x: 10, y: 20}, ["TR", "BL"])
+
+	var choices = dojo.map(corners, function(corner){
+		var c = { corner: corner, pos: {x:pos.x,y:pos.y} };
+		if(padding){
+			c.pos.x += corner.charAt(1) == 'L' ? padding.x : -padding.x;
+			c.pos.y += corner.charAt(0) == 'T' ? padding.y : -padding.y;
+		}
+		return c; 
+	});
+
+	return dijit._place(node, choices);
+}
+
+dijit._place = function(/*DomNode*/ node, /* Array */ choices, /* Function */ layoutNode){
+	// summary:
+	//		Given a list of spots to put node, put it at the first spot where it fits,
+	//		of if it doesn't fit anywhere then the place with the least overflow
+	// choices: Array
+	//		Array of elements like: {corner: 'TL', pos: {x: 10, y: 20} }
+	//		Above example says to put the top-left corner of the node at (10,20)
+	// layoutNode: Function(node, aroundNodeCorner, nodeCorner)
+	//		for things like tooltip, they are displayed differently (and have different dimensions)
+	//		based on their orientation relative to the parent.   This adjusts the popup based on orientation.
+
+	// get {x: 10, y: 10, w: 100, h:100} type obj representing position of
+	// viewport over document
+	var view = dijit.getViewport();
+
+	// This won't work if the node is inside a <div style="position: relative">,
+	// so reattach it to dojo.doc.body.   (Otherwise, the positioning will be wrong
+	// and also it might get cutoff)
+	if(!node.parentNode || String(node.parentNode.tagName).toLowerCase() != "body"){
+		dojo.body().appendChild(node);
+	}
+
+	var best = null;
+	dojo.some(choices, function(choice){
+		var corner = choice.corner;
+		var pos = choice.pos;
+
+		// configure node to be displayed in given position relative to button
+		// (need to do this in order to get an accurate size for the node, because
+		// a tooltips size changes based on position, due to triangle)
+		if(layoutNode){
+			layoutNode(node, choice.aroundCorner, corner);
+		}
+
+		// get node's size
+		var style = node.style;
+		var oldDisplay = style.display;
+		var oldVis = style.visibility;
+		style.visibility = "hidden";
+		style.display = "";
+		var mb = dojo.marginBox(node);
+		style.display = oldDisplay;
+		style.visibility = oldVis;
+
+		// coordinates and size of node with specified corner placed at pos,
+		// and clipped by viewport
+		var startX = (corner.charAt(1) == 'L' ? pos.x : Math.max(view.l, pos.x - mb.w)),
+			startY = (corner.charAt(0) == 'T' ? pos.y : Math.max(view.t, pos.y -  mb.h)),
+			endX = (corner.charAt(1) == 'L' ? Math.min(view.l + view.w, startX + mb.w) : pos.x),
+			endY = (corner.charAt(0) == 'T' ? Math.min(view.t + view.h, startY + mb.h) : pos.y),
+			width = endX - startX,
+			height = endY - startY,
+			overflow = (mb.w - width) + (mb.h - height);
+
+		if(best == null || overflow < best.overflow){
+			best = {
+				corner: corner,
+				aroundCorner: choice.aroundCorner,
+				x: startX,
+				y: startY,
+				w: width,
+				h: height,
+				overflow: overflow
+			};
+		}
+		return !overflow;
+	});
+
+	node.style.left = best.x + "px";
+	node.style.top = best.y + "px";
+	if(best.overflow && layoutNode){
+		layoutNode(node, best.aroundCorner, best.corner);
+	}
+	return best;
+}
+
+dijit.placeOnScreenAroundNode = function(
+	/* DomNode */		node,
+	/* DomNode */		aroundNode,
+	/* Object */		aroundCorners,
+	/* Function? */		layoutNode){
+
+	// summary:
+	//		Position node adjacent or kitty-corner to aroundNode
+	//		such that it's fully visible in viewport.
+	//
+	// description:
+	//		Place node such that corner of node touches a corner of
+	//		aroundNode, and that node is fully visible.
+	//
+	// aroundCorners:
+	//		Ordered list of pairs of corners to try matching up.
+	//		Each pair of corners is represented as a key/value in the hash,
+	//		where the key corresponds to the aroundNode's corner, and
+	//		the value corresponds to the node's corner:
+	//
+	//	|	{ aroundNodeCorner1: nodeCorner1, aroundNodeCorner2: nodeCorner2,  ...}
+	//
+	//		The following strings are used to represent the four corners:
+	//			* "BL" - bottom left
+	//			* "BR" - bottom right
+	//			* "TL" - top left
+	//			* "TR" - top right
+	//
+	// layoutNode: Function(node, aroundNodeCorner, nodeCorner)
+	//		For things like tooltip, they are displayed differently (and have different dimensions)
+	//		based on their orientation relative to the parent.   This adjusts the popup based on orientation.
+	//
+	// example:
+	//	|	dijit.placeOnScreenAroundNode(node, aroundNode, {'BL':'TL', 'TR':'BR'}); 
+	//		This will try to position node such that node's top-left corner is at the same position
+	//		as the bottom left corner of the aroundNode (ie, put node below
+	//		aroundNode, with left edges aligned).  If that fails it will try to put
+	// 		the bottom-right corner of node where the top right corner of aroundNode is
+	//		(ie, put node above aroundNode, with right edges aligned)
+	//
+
+	// get coordinates of aroundNode
+	aroundNode = dojo.byId(aroundNode);
+	var oldDisplay = aroundNode.style.display;
+	aroundNode.style.display="";
+	// #3172: use the slightly tighter border box instead of marginBox
+	var aroundNodeW = aroundNode.offsetWidth; //mb.w; 
+	var aroundNodeH = aroundNode.offsetHeight; //mb.h;
+	var aroundNodePos = dojo.coords(aroundNode, true);
+	aroundNode.style.display=oldDisplay;
+
+	// place the node around the calculated rectangle
+	return dijit._placeOnScreenAroundRect(node, 
+		aroundNodePos.x, aroundNodePos.y, aroundNodeW, aroundNodeH,	// rectangle
+		aroundCorners, layoutNode);
+};
+
+/*=====
+dijit.__Rectangle = function(){
+	// x: Integer
+	//		horizontal offset in pixels, relative to document body
+	// y: Integer
+	//		vertical offset in pixels, relative to document body
+	// width: Integer
+	//		width in pixels
+	// height: Integer
+	//		height in pixels
+
+	thix.x = x;
+	this.y = y;
+	thix.width = width;
+	this.height = height;
+}
+=====*/
+
+
+dijit.placeOnScreenAroundRectangle = function(
+	/* DomNode */			node,
+	/* dijit.__Rectangle */	aroundRect,
+	/* Object */			aroundCorners,
+	/* Function */			layoutNode){
+
+	// summary:
+	//		Like dijit.placeOnScreenAroundNode(), except that the "around"
+	//		parameter is an arbitrary rectangle on the screen (x, y, width, height)
+	//		instead of a dom node.
+
+	return dijit._placeOnScreenAroundRect(node, 
+		aroundRect.x, aroundRect.y, aroundRect.width, aroundRect.height,	// rectangle
+		aroundCorners, layoutNode);
+};
+
+dijit._placeOnScreenAroundRect = function(
+	/* DomNode */		node,
+	/* Number */		x,
+	/* Number */		y,
+	/* Number */		width,
+	/* Number */		height,
+	/* Object */		aroundCorners,
+	/* Function */		layoutNode){
+
+	// summary:
+	//		Like dijit.placeOnScreenAroundNode(), except it accepts coordinates
+	//		of a rectangle to place node adjacent to.
+
+	// TODO: combine with placeOnScreenAroundRectangle()
+
+	// Generate list of possible positions for node
+	var choices = [];
+	for(var nodeCorner in aroundCorners){
+		choices.push( {
+			aroundCorner: nodeCorner,
+			corner: aroundCorners[nodeCorner],
+			pos: {
+				x: x + (nodeCorner.charAt(1) == 'L' ? 0 : width),
+				y: y + (nodeCorner.charAt(0) == 'T' ? 0 : height)
+			}
+		});
+	}
+
+	return dijit._place(node, choices, layoutNode);
+};
+
+dijit.placementRegistry = new dojo.AdapterRegistry();
+dijit.placementRegistry.register("node",
+	function(n, x){
+		return typeof x == "object" &&
+			typeof x.offsetWidth != "undefined" && typeof x.offsetHeight != "undefined";
+	},
+	dijit.placeOnScreenAroundNode);
+dijit.placementRegistry.register("rect",
+	function(n, x){
+		return typeof x == "object" &&
+			"x" in x && "y" in x && "width" in x && "height" in x;
+	},
+	dijit.placeOnScreenAroundRectangle);
+
+dijit.placeOnScreenAroundElement = function(
+	/* DomNode */		node,
+	/* Object */		aroundElement,
+	/* Object */		aroundCorners,
+	/* Function */		layoutNode){
+
+	// summary:
+	//		Like dijit.placeOnScreenAroundNode(), except it accepts an arbitrary object
+	//		for the "around" argument and finds a proper processor to place a node.
+
+	return dijit.placementRegistry.match.apply(dijit.placementRegistry, arguments);
+};
+
+}
+
+if(!dojo._hasResource["dojox.flash._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.flash._base"] = true;
+dojo.provide("dojox.flash._base");
+dojo.experimental("dojox.flash");
+
+// for dijit.getViewport(), needed by dojox.flash.Embed.center()
+
+
+dojox.flash = function(){
+	// summary:
+	//	Utilities to embed and communicate with the Flash player from Javascript
+	//
+	// description:
+	//	The goal of dojox.flash is to make it easy to extend Flash's capabilities
+	//	into an Ajax/DHTML environment.
+	//  
+	//	dojox.flash provides an easy object for interacting with the Flash plugin. 
+	//	This object provides methods to determine the current version of the Flash
+	//	plugin (dojox.flash.info); write out the necessary markup to 
+	//	dynamically insert a Flash object into the page (dojox.flash.Embed; and 
+	//	do dynamic installation and upgrading of the current Flash plugin in 
+	//	use (dojox.flash.Install). If you want to call methods on the Flash object
+	//	embedded into the page it is your responsibility to use Flash's ExternalInterface
+	//	API and get a reference to the Flash object yourself.
+	//		
+	//	To use dojox.flash, you must first wait until Flash is finished loading 
+	//	and initializing before you attempt communication or interaction. 
+	//	To know when Flash is finished use dojo.connect:
+	//		
+	//|	dojo.connect(dojox.flash, "loaded", myInstance, "myCallback");
+	//		
+	//	Then, while the page is still loading provide the file name:
+	//		
+	//|	dojox.flash.setSwf(dojo.moduleUrl("dojox", "_storage/storage.swf"));
+	//			
+	//	If no SWF files are specified, then Flash is not initialized.
+	//		
+	//	Your Flash must use Flash's ExternalInterface to expose Flash methods and
+	//	to call JavaScript.
+	//		
+	//	setSwf can take an optional 'visible' attribute to control whether
+	//	the Flash object is visible or not on the page; the default is visible:
+	//		
+	//|	dojox.flash.setSwf(dojo.moduleUrl("dojox", "_storage/storage.swf"),
+	//						false);
+	//		
+	//	Once finished, you can query Flash version information:
+	//		
+	//|	dojox.flash.info.version
+	//		
+	//	Or can communicate with Flash methods that were exposed:	
+	//
+	//|	var f = dojox.flash.get();
+	//|	var results = f.sayHello("Some Message");	
+	// 
+	//	Your Flash files should use DojoExternalInterface.as to register methods;
+	//	this file wraps Flash's normal ExternalInterface but correct various
+	//	serialization bugs that ExternalInterface has.
+	//
+	//	Note that dojox.flash is not meant to be a generic Flash embedding
+	//	mechanism; it is as generic as necessary to make Dojo Storage's
+	//	Flash Storage Provider as clean and modular as possible. If you want 
+	//	a generic Flash embed mechanism see [SWFObject](http://blog.deconcept.com/swfobject/).
+	//
+	// 	Notes:
+	//	Note that dojox.flash can currently only work with one Flash object
+	//	on the page; it does not yet support multiple Flash objects on
+	//	the same page. 
+	//		
+	//	Your code can detect whether the Flash player is installing or having
+	//	its version revved in two ways. First, if dojox.flash detects that
+	//	Flash installation needs to occur, it sets dojox.flash.info.installing
+	//	to true. Second, you can detect if installation is necessary with the
+	//	following callback:
+	//		
+	//|	dojo.connect(dojox.flash, "installing", myInstance, "myCallback");
+	//		
+	//	You can use this callback to delay further actions that might need Flash;
+	//	when installation is finished the full page will be refreshed and the
+	//	user will be placed back on your page with Flash installed.
+	//		
+	//	-------------------
+	//	Todo/Known Issues
+	//	-------------------
+	//
+	//	* On Internet Explorer, after doing a basic install, the page is
+	//	not refreshed or does not detect that Flash is now available. The way
+	//	to fix this is to create a custom small Flash file that is pointed to
+	//	during installation; when it is finished loading, it does a callback
+	//	that says that Flash installation is complete on IE, and we can proceed
+	//	to initialize the dojox.flash subsystem.
+	//	* Things aren't super tested for sending complex objects to Flash
+	//	methods, since Dojo Storage only needs strings
+	//		
+	//	Author- Brad Neuberg, http://codinginparadise.org
+}
+
+dojox.flash = {
+	ready: false,
+	url: null,
+	
+	_visible: true,
+	_loadedListeners: [],
+	_installingListeners: [],
+	
+	setSwf: function(/* String */ url, /* boolean? */ visible){
+		// summary: Sets the SWF files and versions we are using.
+		// url: String
+		//	The URL to this Flash file.
+		// visible: boolean?
+		//	Whether the Flash file is visible or not. If it is not visible we hide 
+		//	it off the screen. This defaults to true (i.e. the Flash file is
+		//	visible).
+		this.url = url;
+		
+		this._visible = true;
+		if(visible !== null && visible !== undefined){
+			this._visible = visible;
+		}
+		
+		// initialize ourselves		
+		this._initialize();
+	},
+	
+	addLoadedListener: function(/* Function */ listener){
+		// summary:
+		//	Adds a listener to know when Flash is finished loading. 
+		//	Useful if you don't want a dependency on dojo.event.
+		// listener: Function
+		//	A function that will be called when Flash is done loading.
+		
+		this._loadedListeners.push(listener);
+	},
+
+	addInstallingListener: function(/* Function */ listener){
+		// summary:
+		//	Adds a listener to know if Flash is being installed. 
+		//	Useful if you don't want a dependency on dojo.event.
+		// listener: Function
+		//	A function that will be called if Flash is being
+		//	installed
+		
+		this._installingListeners.push(listener);
+	},	
+	
+	loaded: function(){
+		// summary: Called back when the Flash subsystem is finished loading.
+		// description:
+		//	A callback when the Flash subsystem is finished loading and can be
+		//	worked with. To be notified when Flash is finished loading, add a
+		//  loaded listener: 
+		//
+		//  dojox.flash.addLoadedListener(loadedListener);
+	
+		dojox.flash.ready = true;
+		if(dojox.flash._loadedListeners.length){ // FIXME: redundant if? use forEach?
+			for(var i = 0;i < dojox.flash._loadedListeners.length; i++){
+				dojox.flash._loadedListeners[i].call(null);
+			}
+		}
+	},
+	
+	installing: function(){
+		// summary: Called if Flash is being installed.
+		// description:
+		//	A callback to know if Flash is currently being installed or
+		//	having its version revved. To be notified if Flash is installing, connect
+		//	your callback to this method using the following:
+		//	
+		//	dojo.event.connect(dojox.flash, "installing", myInstance, "myCallback");
+		
+		if(dojox.flash._installingListeners.length){ // FIXME: redundant if? use forEach?
+			for(var i = 0; i < dojox.flash._installingListeners.length; i++){
+				dojox.flash._installingListeners[i].call(null);
+			}
+		}
+	},
+	
+	// Initializes dojox.flash.
+	_initialize: function(){
+		//
+		// see if we need to rev or install Flash on this platform
+		var installer = new dojox.flash.Install();
+		dojox.flash.installer = installer;
+
+		if(installer.needed()){		
+			installer.install();
+		}else{
+			// write the flash object into the page
+			dojox.flash.obj = new dojox.flash.Embed(this._visible);
+			dojox.flash.obj.write();
+			
+			// setup the communicator
+			dojox.flash.comm = new dojox.flash.Communicator();
+		}
+	}
+};
+
+
+dojox.flash.Info = function(){
+	// summary: A class that helps us determine whether Flash is available.
+	// description:
+	//	A class that helps us determine whether Flash is available,
+	//	it's major and minor versions, and what Flash version features should
+	//	be used for Flash/JavaScript communication. Parts of this code
+	//	are adapted from the automatic Flash plugin detection code autogenerated 
+	//	by the Macromedia Flash 8 authoring environment. 
+	//	
+	//	An instance of this class can be accessed on dojox.flash.info after
+	//	the page is finished loading.
+
+	this._detectVersion();
+}
+
+dojox.flash.Info.prototype = {
+	// version: String
+	//		The full version string, such as "8r22".
+	version: -1,
+	
+	// versionMajor, versionMinor, versionRevision: String
+	//		The major, minor, and revisions of the plugin. For example, if the
+	//		plugin is 8r22, then the major version is 8, the minor version is 0,
+	//		and the revision is 22. 
+	versionMajor: -1,
+	versionMinor: -1,
+	versionRevision: -1,
+	
+	// capable: Boolean
+	//		Whether this platform has Flash already installed.
+	capable: false,
+	
+	// installing: Boolean
+	//	Set if we are in the middle of a Flash installation session.
+	installing: false,
+	
+	isVersionOrAbove: function(
+							/* int */ reqMajorVer, 
+							/* int */ reqMinorVer, 
+							/* int */ reqVer){ /* Boolean */
+		// summary: 
+		//	Asserts that this environment has the given major, minor, and revision
+		//	numbers for the Flash player.
+		// description:
+		//	Asserts that this environment has the given major, minor, and revision
+		//	numbers for the Flash player. 
+		//	
+		//	Example- To test for Flash Player 7r14:
+		//	
+		//	dojox.flash.info.isVersionOrAbove(7, 0, 14)
+		// returns:
+		//	Returns true if the player is equal
+		//	or above the given version, false otherwise.
+		
+		// make the revision a decimal (i.e. transform revision 14 into
+		// 0.14
+		reqVer = parseFloat("." + reqVer);
+		
+		if(this.versionMajor >= reqMajorVer && this.versionMinor >= reqMinorVer
+			 && this.versionRevision >= reqVer){
+			return true;
+		}else{
+			return false;
+		}
+	},
+	
+	_detectVersion: function(){
+		var versionStr;
+		
+		// loop backwards through the versions until we find the newest version	
+		for(var testVersion = 25; testVersion > 0; testVersion--){
+			if(dojo.isIE){
+				var axo;
+				try{
+					if(testVersion > 6){
+						axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash." 
+																		+ testVersion);
+					}else{
+						axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
+					}
+					if(typeof axo == "object"){
+						if(testVersion == 6){
+							axo.AllowScriptAccess = "always";
+						}
+						versionStr = axo.GetVariable("$version");
+					}
+				}catch(e){
+					continue;
+				}
+			}else{
+				versionStr = this._JSFlashInfo(testVersion);		
+			}
+				
+			if(versionStr == -1 ){
+				this.capable = false; 
+				return;
+			}else if(versionStr != 0){
+				var versionArray;
+				if(dojo.isIE){
+					var tempArray = versionStr.split(" ");
+					var tempString = tempArray[1];
+					versionArray = tempString.split(",");
+				}else{
+					versionArray = versionStr.split(".");
+				}
+					
+				this.versionMajor = versionArray[0];
+				this.versionMinor = versionArray[1];
+				this.versionRevision = versionArray[2];
+				
+				// 7.0r24 == 7.24
+				var versionString = this.versionMajor + "." + this.versionRevision;
+				this.version = parseFloat(versionString);
+				
+				this.capable = true;
+				
+				break;
+			}
+		}
+	},
+	 
+	// JavaScript helper required to detect Flash Player PlugIn version 
+	// information. Internet Explorer uses a corresponding Visual Basic
+	// version to interact with the Flash ActiveX control. 
+	_JSFlashInfo: function(testVersion){
+		// NS/Opera version >= 3 check for Flash plugin in plugin array
+		if(navigator.plugins != null && navigator.plugins.length > 0){
+			if(navigator.plugins["Shockwave Flash 2.0"] || 
+				 navigator.plugins["Shockwave Flash"]){
+				var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
+				var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
+				var descArray = flashDescription.split(" ");
+				var tempArrayMajor = descArray[2].split(".");
+				var versionMajor = tempArrayMajor[0];
+				var versionMinor = tempArrayMajor[1];
+				var tempArrayMinor = (descArray[3] || descArray[4]).split("r");
+				var versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0;
+				var version = versionMajor + "." + versionMinor + "." + versionRevision;
+											
+				return version;
+			}
+		}
+		
+		return -1;
+	}
+};
+
+dojox.flash.Embed = function(visible){
+	// summary: A class that is used to write out the Flash object into the page.
+	// description:
+	//	Writes out the necessary tags to embed a Flash file into the page. Note that
+	//	these tags are written out as the page is loaded using document.write, so
+	//	you must call this class before the page has finished loading.
+	
+	this._visible = visible;
+}
+
+dojox.flash.Embed.prototype = {
+	// width: int
+	//	The width of this Flash applet. The default is the minimal width
+	//	necessary to show the Flash settings dialog. Current value is 
+	//  215 pixels.
+	width: 215,
+	
+	// height: int 
+	//	The height of this Flash applet. The default is the minimal height
+	//	necessary to show the Flash settings dialog. Current value is
+	// 138 pixels.
+	height: 138,
+	
+	// id: String
+	// 	The id of the Flash object. Current value is 'flashObject'.
+	id: "flashObject",
+	
+	// Controls whether this is a visible Flash applet or not.
+	_visible: true,
+
+	protocol: function(){
+		switch(window.location.protocol){
+			case "https:":
+				return "https";
+				break;
+			default:
+				return "http";
+				break;
+		}
+	},
+	
+	write: function(/* Boolean? */ doExpressInstall){
+		// summary: Writes the Flash into the page.
+		// description:
+		//	This must be called before the page
+		//	is finished loading. 
+		// doExpressInstall: Boolean
+		//	Whether to write out Express Install
+		//	information. Optional value; defaults to false.
+		
+		// figure out the SWF file to get and how to write out the correct HTML
+		// for this Flash version
+		var objectHTML;
+		var swfloc = dojox.flash.url;
+		var swflocObject = swfloc;
+		var swflocEmbed = swfloc;
+		var dojoUrl = dojo.baseUrl;
+		var xdomainBase = document.location.protocol + '//' + document.location.host;
+		if(doExpressInstall){
+			// the location to redirect to after installing
+			var redirectURL = escape(window.location);
+			document.title = document.title.slice(0, 47) + " - Flash Player Installation";
+			var docTitle = escape(document.title);
+			swflocObject += "?MMredirectURL=" + redirectURL
+			                + "&MMplayerType=ActiveX"
+			                + "&MMdoctitle=" + docTitle
+			                + "&baseUrl=" + escape(dojoUrl)
+			                + "&xdomain=" + escape(xdomainBase);
+			swflocEmbed += "?MMredirectURL=" + redirectURL 
+			                + "&MMplayerType=PlugIn"
+			                + "&baseUrl=" + escape(dojoUrl)
+			                + "&xdomain=" + escape(xdomainBase);
+		}else{
+			// IE/Flash has an evil bug that shows up some time: if we load the
+			// Flash and it isn't in the cache, ExternalInterface works fine --
+			// however, the second time when its loaded from the cache a timing
+			// bug can keep ExternalInterface from working. The trick below 
+			// simply invalidates the Flash object in the cache all the time to
+			// keep it loading fresh. -- Brad Neuberg
+			swflocObject += "?cachebust=" + new Date().getTime();
+			swflocObject += "&baseUrl=" + escape(dojoUrl);
+			swflocObject += "&xdomain=" + escape(xdomainBase);
+		}
+
+		if(swflocEmbed.indexOf("?") == -1){
+			swflocEmbed += '?baseUrl='+escape(dojoUrl);
+		}else{
+		  swflocEmbed += '&baseUrl='+escape(dojoUrl);
+		}
+		swflocEmbed += '&xdomain='+escape(xdomainBase);
+		
+		objectHTML =
+			'<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '
+			  + 'codebase="'
+				+ this.protocol()
+				+ '://fpdownload.macromedia.com/pub/shockwave/cabs/flash/'
+				+ 'swflash.cab#version=8,0,0,0"\n '
+			  + 'width="' + this.width + '"\n '
+			  + 'height="' + this.height + '"\n '
+			  + 'id="' + this.id + '"\n '
+			  + 'name="' + this.id + '"\n '
+			  + 'align="middle">\n '
+			  + '<param name="allowScriptAccess" value="always"></param>\n '
+			  + '<param name="movie" value="' + swflocObject + '"></param>\n '
+			  + '<param name="quality" value="high"></param>\n '
+			  + '<param name="bgcolor" value="#ffffff"></param>\n '
+			  + '<embed src="' + swflocEmbed + '" '
+			  	  + 'quality="high" '
+				  + 'bgcolor="#ffffff" '
+				  + 'width="' + this.width + '" '
+				  + 'height="' + this.height + '" '
+				  + 'id="' + this.id + 'Embed' + '" '
+				  + 'name="' + this.id + '" '
+				  + 'swLiveConnect="true" '
+				  + 'align="middle" '
+				  + 'allowScriptAccess="always" '
+				  + 'type="application/x-shockwave-flash" '
+				  + 'pluginspage="'
+				  + this.protocol()
+				  +'://www.macromedia.com/go/getflashplayer" '
+				  + '></embed>\n'
+			+ '</object>\n';
+					
+		// using same mechanism on all browsers now to write out
+		// Flash object into page
+
+		// document.write no longer works correctly due to Eolas patent workaround
+		// in IE; nothing happens (i.e. object doesn't go into page if we use it)
+		dojo.connect(dojo, "loaded", dojo.hitch(this, function(){
+			// Prevent putting duplicate SWFs onto the page
+			var containerId = this.id + "Container";
+			if(dojo.byId(containerId)){
+				return;
+			}
+			
+			var div = document.createElement("div");
+			div.id = this.id + "Container";
+			
+			div.style.width = this.width + "px";
+			div.style.height = this.height + "px";
+			if(!this._visible){
+				div.style.position = "absolute";
+				div.style.zIndex = "10000";
+				div.style.top = "-1000px";
+			}
+
+			div.innerHTML = objectHTML;
+
+			var body = document.getElementsByTagName("body");
+			if(!body || !body.length){
+				throw new Error("No body tag for this page");
+			}
+			body = body[0];
+			body.appendChild(div);
+		}));
+	},  
+	
+	get: function(){ /* Object */
+		// summary: Gets the Flash object DOM node.
+
+		if(dojo.isIE || dojo.isWebKit){
+			//TODO: should this really be the else?
+			return dojo.byId(this.id);
+		}else{
+			// different IDs on OBJECT and EMBED tags or
+			// else Firefox will return wrong one and
+			// communication won't work; 
+			// also, document.getElementById() returns a
+			// plugin but ExternalInterface calls don't
+			// work on it so we have to use
+			// document[id] instead
+			return document[this.id + "Embed"];
+		}
+	},
+	
+	setVisible: function(/* Boolean */ visible){
+		//
+		
+		// summary: Sets the visibility of this Flash object.		
+		var container = dojo.byId(this.id + "Container");
+		if(visible){
+			container.style.position = "absolute"; // IE -- Brad Neuberg
+			container.style.visibility = "visible";
+		}else{
+			container.style.position = "absolute";
+			container.style.y = "-1000px";
+			container.style.visibility = "hidden";
+		}
+	},
+	
+	center: function(){
+		// summary: Centers the flash applet on the page.
+		
+		var elementWidth = this.width;
+		var elementHeight = this.height;
+
+		var viewport = dijit.getViewport();
+
+		// compute the centered position    
+		var x = viewport.l + (viewport.w - elementWidth) / 2;
+		var y = viewport.t + (viewport.h - elementHeight) / 2; 
+		
+		// set the centered position
+		var container = dojo.byId(this.id + "Container");
+		container.style.top = y + "px";
+		container.style.left = x + "px";
+	}
+};
+
+
+dojox.flash.Communicator = function(){
+	// summary:
+	//	A class that is used to communicate between Flash and JavaScript.
+	// description:
+	//	This class helps mediate Flash and JavaScript communication. Internally
+	//	it uses Flash 8's ExternalInterface API, but adds functionality to fix 
+	//	various encoding bugs that ExternalInterface has.
+}
+
+dojox.flash.Communicator.prototype = {
+	// Registers the existence of a Flash method that we can call with
+	// JavaScript, using Flash 8's ExternalInterface. 
+	_addExternalInterfaceCallback: function(methodName){
+		//
+		var wrapperCall = dojo.hitch(this, function(){
+			// some browsers don't like us changing values in the 'arguments' array, so
+			// make a fresh copy of it
+			var methodArgs = new Array(arguments.length);
+			for(var i = 0; i < arguments.length; i++){
+				methodArgs[i] = this._encodeData(arguments[i]);
+			}
+			
+			var results = this._execFlash(methodName, methodArgs);
+			results = this._decodeData(results);
+			
+			return results;
+		});
+		
+		this[methodName] = wrapperCall;
+	},
+	
+	// Encodes our data to get around ExternalInterface bugs that are still
+	// present even in Flash 9.
+	_encodeData: function(data){
+		//
+		if(!data || typeof data != "string"){
+			return data;
+		}
+		
+		// transforming \ into \\ doesn't work; just use a custom encoding
+		data = data.replace("\\", "&custom_backslash;");
+
+		// also use custom encoding for the null character to avoid problems 
+		data = data.replace(/\0/g, "&custom_null;");
+
+		return data;
+	},
+	
+	// Decodes our data to get around ExternalInterface bugs that are still
+	// present even in Flash 9.
+	_decodeData: function(data){
+		//
+		// wierdly enough, Flash sometimes returns the result as an
+		// 'object' that is actually an array, rather than as a String;
+		// detect this by looking for a length property; for IE
+		// we also make sure that we aren't dealing with a typeof string
+		// since string objects have length property there
+		if(data && data.length && typeof data != "string"){
+			data = data[0];
+		}
+		
+		if(!data || typeof data != "string"){
+			return data;
+		}
+		
+		// needed for IE; \0 is the NULL character 
+		data = data.replace(/\&custom_null\;/g, "\0");
+	
+		// certain XMLish characters break Flash's wire serialization for
+		// ExternalInterface; these are encoded on the 
+		// DojoExternalInterface side into a custom encoding, rather than
+		// the standard entity encoding, because otherwise we won't be able to
+		// differentiate between our own encoding and any entity characters
+		// that are being used in the string itself
+		data = data.replace(/\&custom_lt\;/g, "<")
+			.replace(/\&custom_gt\;/g, ">")
+			.replace(/\&custom_backslash\;/g, '\\');
+		
+		return data;
+	},
+	
+	// Executes a Flash method; called from the JavaScript wrapper proxy we
+	// create on dojox.flash.comm.
+	_execFlash: function(methodName, methodArgs){
+		//
+		var plugin = dojox.flash.obj.get();
+		methodArgs = (methodArgs) ? methodArgs : [];
+		
+		// encode arguments that are strings
+		for(var i = 0; i < methodArgs; i++){
+			if(typeof methodArgs[i] == "string"){
+				methodArgs[i] = this._encodeData(methodArgs[i]);
+			}
+		}
+
+		// we use this gnarly hack below instead of 
+		// plugin[methodName] for two reasons:
+		// 1) plugin[methodName] has no call() method, which
+		// means we can't pass in multiple arguments dynamically
+		// to a Flash method -- we can only have one
+		// 2) On IE plugin[methodName] returns undefined -- 
+		// plugin[methodName] used to work on IE when we
+		// used document.write but doesn't now that
+		// we use dynamic DOM insertion of the Flash object
+		// -- Brad Neuberg
+		var flashExec = function(){ 
+			return eval(plugin.CallFunction(
+						 "<invoke name=\"" + methodName
+						+ "\" returntype=\"javascript\">" 
+						+ __flash__argumentsToXML(methodArgs, 0) 
+						+ "</invoke>")); 
+		};
+		var results = flashExec.call(methodArgs);
+		
+		if(typeof results == "string"){
+			results = this._decodeData(results);
+		}
+			
+		return results;
+	}
+}
+
+// FIXME: dojo.declare()-ify this
+
+// TODO: I did not test the Install code when I refactored Dojo Flash from 0.4 to 
+// 1.0, so am not sure if it works. If Flash is not present I now prefer 
+// that Gears is installed instead of Flash because GearsStorageProvider is
+// much easier to work with than Flash's hacky ExternalInteface. 
+// -- Brad Neuberg
+dojox.flash.Install = function(){
+	// summary: Helps install Flash plugin if needed.
+	// description:
+	//		Figures out the best way to automatically install the Flash plugin
+	//		for this browser and platform. Also determines if installation or
+	//		revving of the current plugin is needed on this platform.
+}
+
+dojox.flash.Install.prototype = {
+	needed: function(){ /* Boolean */
+		// summary:
+		//		Determines if installation or revving of the current plugin is
+		//		needed. 
+	
+		// do we even have flash?
+		if(!dojox.flash.info.capable){
+			return true;
+		}
+
+		// Must have ExternalInterface which came in Flash 8
+		if(!dojox.flash.info.isVersionOrAbove(8, 0, 0)){
+			return true;
+		}
+
+		// otherwise we don't need installation
+		return false;
+	},
+
+	install: function(){
+		// summary: Performs installation or revving of the Flash plugin.
+		var installObj;
+	
+		// indicate that we are installing
+		dojox.flash.info.installing = true;
+		dojox.flash.installing();
+		
+		if(dojox.flash.info.capable == false){ // we have no Flash at all
+			// write out a simple Flash object to force the browser to prompt
+			// the user to install things
+			installObj = new dojox.flash.Embed(false);
+			installObj.write(); // write out HTML for Flash
+		}else if(dojox.flash.info.isVersionOrAbove(6, 0, 65)){ // Express Install
+			installObj = new dojox.flash.Embed(false);
+			installObj.write(true); // write out HTML for Flash 8 version+
+			installObj.setVisible(true);
+			installObj.center();
+		}else{ // older Flash install than version 6r65
+			alert("This content requires a more recent version of the Macromedia "
+						+" Flash Player.");
+			window.location.href = + dojox.flash.Embed.protocol() +
+						"://www.macromedia.com/go/getflashplayer";
+		}
+	},
+	
+	// Called when the Express Install is either finished, failed, or was
+	// rejected by the user.
+	_onInstallStatus: function(msg){
+		if (msg == "Download.Complete"){
+			// Installation is complete.
+			dojox.flash._initialize();
+		}else if(msg == "Download.Cancelled"){
+			alert("This content requires a more recent version of the Macromedia "
+						+" Flash Player.");
+			window.location.href = dojox.flash.Embed.protocol() +
+						"://www.macromedia.com/go/getflashplayer";
+		}else if (msg == "Download.Failed"){
+			// The end user failed to download the installer due to a network failure
+			alert("There was an error downloading the Flash Player update. "
+						+ "Please try again later, or visit macromedia.com to download "
+						+ "the latest version of the Flash plugin.");
+		}	
+	}
+}
+
+// find out if Flash is installed
+dojox.flash.info = new dojox.flash.Info();
+
+// vim:ts=4:noet:tw=0:
+
+}
+
+if(!dojo._hasResource["dojox.flash"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.flash"] = true;
+dojo.provide("dojox.flash");
+
+
+}
+
+if(!dojo._hasResource["dojox.storage.FlashStorageProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.storage.FlashStorageProvider"] = true;
+dojo.provide("dojox.storage.FlashStorageProvider");
+
+
+
+
+
+// summary: 
+//		Storage provider that uses features in Flash to achieve permanent
+//		storage
+// description:
+//		Authors of this storage provider-
+//			Brad Neuberg, bkn3 at columbia.edu	
+dojo.declare("dojox.storage.FlashStorageProvider", dojox.storage.Provider, {
+		initialized: false,
+		
+		_available: null,
+		_statusHandler: null,
+		_flashReady: false,
+		_pageReady: false,
+		
+		initialize: function(){
+		  //
+			if(dojo.config["disableFlashStorage"] == true){
+				return;
+			}
+			
+			// initialize our Flash
+			dojox.flash.addLoadedListener(dojo.hitch(this, function(){
+			  //
+			  // indicate our Flash subsystem is now loaded
+			  this._flashReady = true;
+			  if(this._flashReady && this._pageReady){
+				  this._loaded();
+				}
+			}));
+			var swfLoc = dojo.moduleUrl("dojox", "storage/Storage.swf").toString();
+			dojox.flash.setSwf(swfLoc, false);
+			
+			// wait till page is finished loading
+			dojo.connect(dojo, "loaded", this, function(){
+			  //
+			  this._pageReady = true;
+			  if(this._flashReady && this._pageReady){
+			    this._loaded();
+			  }
+			});
+		},
+		
+		//	Set a new value for the flush delay timer.
+		//	Possible values:
+		//	  0 : Perform the flush synchronously after each "put" request
+		//	> 0 : Wait until 'newDelay' ms have passed without any "put" request to flush
+		//	 -1 : Do not  automatically flush
+		setFlushDelay: function(newDelay){
+			if(newDelay === null || typeof newDelay === "undefined" || isNaN(newDelay)){
+				throw new Error("Invalid argunment: " + newDelay);
+			}
+			
+			dojox.flash.comm.setFlushDelay(String(newDelay));
+		},
+		
+		getFlushDelay: function(){
+			return Number(dojox.flash.comm.getFlushDelay());
+		},
+		
+		flush: function(namespace){
+			//FIXME: is this test necessary?  Just use !namespace
+			if(namespace == null || typeof namespace == "undefined"){
+				namespace = dojox.storage.DEFAULT_NAMESPACE;		
+			}
+			dojox.flash.comm.flush(namespace);
+		},
+
+		isAvailable: function(){
+			return (this._available = !dojo.config["disableFlashStorage"]);
+		},
+
+		put: function(key, value, resultsHandler, namespace){
+			if(!this.isValidKey(key)){
+				throw new Error("Invalid key given: " + key);
+			}
+			
+			if(!namespace){
+				namespace = dojox.storage.DEFAULT_NAMESPACE;		
+			}
+			
+			if(!this.isValidKey(namespace)){
+				throw new Error("Invalid namespace given: " + namespace);
+			}
+				
+			this._statusHandler = resultsHandler;
+			
+			// serialize the value;
+			// handle strings differently so they have better performance
+			if(dojo.isString(value)){
+				value = "string:" + value;
+			}else{
+				value = dojo.toJson(value);
+			}
+			
+			dojox.flash.comm.put(key, value, namespace);
+		},
+
+		putMultiple: function(keys, values, resultsHandler, namespace){
+			if(!this.isValidKeyArray(keys) || ! values instanceof Array 
+			    || keys.length != values.length){
+				throw new Error("Invalid arguments: keys = [" + keys + "], values = [" + values + "]");
+			}
+			
+			if(!namespace){
+				namespace = dojox.storage.DEFAULT_NAMESPACE;		
+			}
+
+			if(!this.isValidKey(namespace)){
+				throw new Error("Invalid namespace given: " + namespace);
+			}
+
+			this._statusHandler = resultsHandler;
+			
+			//	Convert the arguments on strings we can pass along to Flash
+			var metaKey = keys.join(",");
+			var lengths = [];
+			for(var i=0;i<values.length;i++){
+				if(dojo.isString(values[i])){
+					values[i] = "string:" + values[i];
+				}else{
+					values[i] = dojo.toJson(values[i]);
+				}
+				lengths[i] = values[i].length; 
+			}
+			var metaValue = values.join("");
+			var metaLengths = lengths.join(",");
+			
+			dojox.flash.comm.putMultiple(metaKey, metaValue, metaLengths, namespace);
+		},
+
+		get: function(key, namespace){
+			if(!this.isValidKey(key)){
+				throw new Error("Invalid key given: " + key);
+			}
+			
+			if(!namespace){
+				namespace = dojox.storage.DEFAULT_NAMESPACE;		
+			}
+			
+			if(!this.isValidKey(namespace)){
+				throw new Error("Invalid namespace given: " + namespace);
+			}
+			
+			var results = dojox.flash.comm.get(key, namespace);
+
+			if(results == ""){
+				return null;
+			}
+		
+			return this._destringify(results);
+		},
+
+		getMultiple: function(/*array*/ keys, /*string?*/ namespace){ /*Object*/
+			if(!this.isValidKeyArray(keys)){
+				throw new ("Invalid key array given: " + keys);
+			}
+			
+			if(!namespace){
+				namespace = dojox.storage.DEFAULT_NAMESPACE;		
+			}
+			
+			if(!this.isValidKey(namespace)){
+				throw new Error("Invalid namespace given: " + namespace);
+			}
+			
+			var metaKey = keys.join(",");
+			var metaResults = dojox.flash.comm.getMultiple(metaKey, namespace);
+			var results = eval("(" + metaResults + ")");
+			
+			//	destringify each entry back into a real JS object
+			//FIXME: use dojo.map
+			for(var i = 0; i < results.length; i++){
+				results[i] = (results[i] == "") ? null : this._destringify(results[i]);
+			}
+			
+			return results;		
+		},
+
+		_destringify: function(results){
+			// destringify the content back into a 
+			// real JavaScript object;
+			// handle strings differently so they have better performance
+			if(dojo.isString(results) && (/^string:/.test(results))){
+				results = results.substring("string:".length);
+			}else{
+				results = dojo.fromJson(results);
+			}
+		
+			return results;
+		},
+		
+		getKeys: function(namespace){
+			if(!namespace){
+				namespace = dojox.storage.DEFAULT_NAMESPACE;		
+			}
+			
+			if(!this.isValidKey(namespace)){
+				throw new Error("Invalid namespace given: " + namespace);
+			}
+			
+			var results = dojox.flash.comm.getKeys(namespace);
+			
+			// Flash incorrectly returns an empty string as "null"
+			if(results == null || results == "null"){
+			  results = "";
+			}
+			
+			results = results.split(",");
+			results.sort();
+			
+			return results;
+		},
+		
+		getNamespaces: function(){
+			var results = dojox.flash.comm.getNamespaces();
+			
+			// Flash incorrectly returns an empty string as "null"
+			if(results == null || results == "null"){
+			  results = dojox.storage.DEFAULT_NAMESPACE;
+			}
+			
+			results = results.split(",");
+			results.sort();
+			
+			return results;
+		},
+
+		clear: function(namespace){
+			if(!namespace){
+				namespace = dojox.storage.DEFAULT_NAMESPACE;
+			}
+			
+			if(!this.isValidKey(namespace)){
+				throw new Error("Invalid namespace given: " + namespace);
+			}
+			
+			dojox.flash.comm.clear(namespace);
+		},
+		
+		remove: function(key, namespace){
+			if(!namespace){
+				namespace = dojox.storage.DEFAULT_NAMESPACE;		
+			}
+			
+			if(!this.isValidKey(namespace)){
+				throw new Error("Invalid namespace given: " + namespace);
+			}
+			
+			dojox.flash.comm.remove(key, namespace);
+		},
+		
+		removeMultiple: function(/*array*/ keys, /*string?*/ namespace){ /*Object*/
+			if(!this.isValidKeyArray(keys)){
+				dojo.raise("Invalid key array given: " + keys);
+			}
+			if(!namespace){
+				namespace = dojox.storage.DEFAULT_NAMESPACE;		
+			}
+			
+			if(!this.isValidKey(namespace)){
+				throw new Error("Invalid namespace given: " + namespace);
+			}
+			
+			var metaKey = keys.join(",");
+			dojox.flash.comm.removeMultiple(metaKey, namespace);
+		},
+
+		isPermanent: function(){
+			return true;
+		},
+
+		getMaximumSize: function(){
+			return dojox.storage.SIZE_NO_LIMIT;
+		},
+
+		hasSettingsUI: function(){
+			return true;
+		},
+
+		showSettingsUI: function(){
+			dojox.flash.comm.showSettings();
+			dojox.flash.obj.setVisible(true);
+			dojox.flash.obj.center();
+		},
+
+		hideSettingsUI: function(){
+			// hide the dialog
+			dojox.flash.obj.setVisible(false);
+			
+			// call anyone who wants to know the dialog is
+			// now hidden
+			if(dojo.isFunction(dojox.storage.onHideSettingsUI)){
+				dojox.storage.onHideSettingsUI.call(null);	
+			}
+		},
+		
+		getResourceList: function(){ /* Array[] */
+			// Dojo Offline no longer uses the FlashStorageProvider for offline
+			// storage; Gears is now required
+			return [];
+		},
+		
+		/** Called when Flash and the page are finished loading. */
+		_loaded: function(){
+			// get available namespaces
+			this._allNamespaces = this.getNamespaces();
+			
+			this.initialized = true;
+
+			// indicate that this storage provider is now loaded
+			dojox.storage.manager.loaded();
+		},
+		
+		//	Called if the storage system needs to tell us about the status
+		//	of a put() request. 
+		_onStatus: function(statusResult, key, namespace){
+		  //
+			var ds = dojox.storage;
+			var dfo = dojox.flash.obj;
+			
+			if(statusResult == ds.PENDING){
+				dfo.center();
+				dfo.setVisible(true);
+			}else{
+				dfo.setVisible(false);
+			}
+			
+			if(ds._statusHandler){
+				ds._statusHandler.call(null, statusResult, key, null, namespace);		
+			}
+		}
+	}
+);
+
+dojox.storage.manager.register("dojox.storage.FlashStorageProvider",
+								new dojox.storage.FlashStorageProvider());
+
+}
+
+if(!dojo._hasResource["dojox.storage._common"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.storage._common"] = true;
+dojo.provide("dojox.storage._common");
+
+
+
+/*
+  Note: if you are doing Dojo Offline builds you _must_
+  have offlineProfile=true when you run the build script:
+  ./build.sh action=release profile=offline offlineProfile=true
+*/
+
+
+
+
+// now that we are loaded and registered tell the storage manager to
+// initialize itself
+dojox.storage.manager.initialize();
+
+}
+
+if(!dojo._hasResource["dojox.storage"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.storage"] = true;
+dojo.provide("dojox.storage");
+
+
+}
+
+if(!dojo._hasResource["dojox.off.files"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.off.files"] = true;
+dojo.provide("dojox.off.files");
+
+// Author: Brad Neuberg, bkn3 at columbia.edu, http://codinginparadise.org
+
+// summary:
+//	Helps maintain resources that should be
+//	available offline, such as CSS files.
+// description:
+//	dojox.off.files makes it easy to indicate
+//	what resources should be available offline,
+//	such as CSS files, JavaScript, HTML, etc.
+dojox.off.files = {
+	// versionURL: String
+	//	An optional file, that if present, records the version
+	//	of our bundle of files to make available offline. If this
+	//	file is present, and we are not currently debugging,
+	//	then we only refresh our offline files if the version has
+	//	changed. 
+	versionURL: "version.js",
+	
+	// listOfURLs: Array
+	//	For advanced usage; most developers can ignore this.
+	//	Our list of URLs that will be cached and made available
+	//	offline.
+	listOfURLs: [],
+	
+	// refreshing: boolean
+	//	For advanced usage; most developers can ignore this.
+	//	Whether we are currently in the middle
+	//	of refreshing our list of offline files.
+	refreshing: false,
+
+	_cancelID: null,
+	
+	_error: false,
+	_errorMessages: [],
+	_currentFileIndex: 0,
+	_store: null,
+	_doSlurp: false,
+	
+	slurp: function(){
+		// summary:
+		//	Autoscans the page to find all resources to
+		//	cache. This includes scripts, images, CSS, and hyperlinks
+		//	to pages that are in the same scheme/port/host as this
+		//	page. We also scan the embedded CSS of any stylesheets
+		//	to find @import statements and url()'s.
+		//  You should call this method from the top-level, outside of
+		//	any functions and before the page loads:
+		//
+		//	<script>
+		//		
+		//		
+		//		
+		//		
+		//
+		//		// configure how we should work offline
+		//
+		//		// set our application name
+		//		dojox.off.ui.appName = "Moxie";
+		//
+		//		// automatically "slurp" the page and
+		//		// capture the resources we need offline
+		//		dojox.off.files.slurp();
+		//
+		// 		// tell Dojo Offline we are ready for it to initialize itself now
+		//		// that we have finished configuring it for our application
+		//		dojox.off.initialize();
+		//	</script>
+		//
+		//	Note that inline styles on elements are not handled (i.e.
+		//	if you somehow have an inline style that uses a URL);
+		//	object and embed tags are not scanned since their format
+		//	differs based on type; and elements created by JavaScript
+		//	after page load are not found. For these you must manually
+		//	add them with a dojox.off.files.cache() method call.
+		
+		// just schedule the slurp once the page is loaded and
+		// Dojo Offline is ready to slurp; dojox.off will call
+		// our _slurp() method before indicating it is finished
+		// loading
+		this._doSlurp = true;
+	},
+	
+	cache: function(urlOrList){ /* void */
+		// summary:
+		//		Caches a file or list of files to be available offline. This
+		//		can either be a full URL, such as http://foobar.com/index.html,
+		//		or a relative URL, such as ../index.html. This URL is not
+		//		actually cached until dojox.off.sync.synchronize() is called.
+		// urlOrList: String or Array[]
+		//		A URL of a file to cache or an Array of Strings of files to
+		//		cache
+		
+		//
+		
+		if(dojo.isString(urlOrList)){
+			var url = this._trimAnchor(urlOrList+"");
+			if(!this.isAvailable(url)){ 
+				this.listOfURLs.push(url); 
+			}
+		}else if(urlOrList instanceof dojo._Url){
+			var url = this._trimAnchor(urlOrList.uri);
+			if(!this.isAvailable(url)){ 
+				this.listOfURLs.push(url); 
+			}
+		}else{
+			dojo.forEach(urlOrList, function(url){
+				url = this._trimAnchor(url);
+				if(!this.isAvailable(url)){ 
+					this.listOfURLs.push(url); 
+				}
+			}, this);
+		}
+	},
+	
+	printURLs: function(){
+		// summary:
+		//	A helper function that will dump and print out
+		//	all of the URLs that are cached for offline
+		//	availability. This can help with debugging if you
+		//	are trying to make sure that all of your URLs are
+		//	available offline
+		
+		dojo.forEach(this.listOfURLs, function(i){
+			
+		});	
+	},
+	
+	remove: function(url){ /* void */
+		// summary:
+		//		Removes a URL from the list of files to cache.
+		// description:
+		//		Removes a URL from the list of URLs to cache. Note that this
+		//		does not actually remove the file from the offline cache;
+		//		instead, it just prevents us from refreshing this file at a
+		//		later time, so that it will naturally time out and be removed
+		//		from the offline cache
+		// url: String
+		//		The URL to remove
+		for(var i = 0; i < this.listOfURLs.length; i++){
+			if(this.listOfURLs[i] == url){
+				this.listOfURLs = this.listOfURLs.splice(i, 1);
+				break;
+			}
+		}
+	},
+	
+	isAvailable: function(url){ /* boolean */
+		// summary:
+		//		Determines whether the given resource is available offline.
+		// url: String
+		//	The URL to check
+		for(var i = 0; i < this.listOfURLs.length; i++){
+			if(this.listOfURLs[i] == url){
+				return true;
+			}
+		}
+		
+		return false;
+	},
+	
+	refresh: function(callback){ /* void */
+		//
+		// summary:
+		//	For advanced usage; most developers can ignore this.
+		//	Refreshes our list of offline resources,
+		//	making them available offline.
+		// callback: Function
+		//	A callback that receives two arguments: whether an error
+		//	occurred, which is a boolean; and an array of error message strings
+		//	with details on errors encountered. If no error occured then message is
+		//	empty array with length 0.
+		try{
+			if(dojo.config.isDebug){
+				this.printURLs();
+			}
+			
+			this.refreshing = true;
+			
+			if(this.versionURL){
+				this._getVersionInfo(function(oldVersion, newVersion, justDebugged){
+					//console.warn("getVersionInfo, oldVersion="+oldVersion+", newVersion="+newVersion
+					//				+ ", justDebugged="+justDebugged+", isDebug="+dojo.config.isDebug);
+					if(dojo.config.isDebug || !newVersion || justDebugged 
+							|| !oldVersion || oldVersion != newVersion){
+						console.warn("Refreshing offline file list");
+						this._doRefresh(callback, newVersion);
+					}else{
+						console.warn("No need to refresh offline file list");
+						callback(false, []);
+					}
+				});
+			}else{
+				console.warn("Refreshing offline file list");
+				this._doRefresh(callback);
+			}
+		}catch(e){
+			this.refreshing = false;
+                       
+			// can't refresh files -- core operation --
+			// fail fast
+			dojox.off.coreOpFailed = true;
+			dojox.off.enabled = false;
+			dojox.off.onFrameworkEvent("coreOperationFailed");
+		}
+	},
+	
+	abortRefresh: function(){
+		// summary:
+		//	For advanced usage; most developers can ignore this.
+		//	Aborts and cancels a refresh.
+		if(!this.refreshing){
+			return;
+		}
+		
+		this._store.abortCapture(this._cancelID);
+		this.refreshing = false;
+	},
+	
+	_slurp: function(){
+		if(!this._doSlurp){
+			return;
+		}
+		
+		var handleUrl = dojo.hitch(this, function(url){
+			if(this._sameLocation(url)){
+				this.cache(url);
+			}
+		});
+		
+		handleUrl(window.location.href);
+		
+		dojo.query("script").forEach(function(i){
+			try{
+				handleUrl(i.getAttribute("src"));
+			}catch(exp){
+				//
+			}
+		});
+		
+		dojo.query("link").forEach(function(i){
+			try{
+				if(!i.getAttribute("rel")
+					|| i.getAttribute("rel").toLowerCase() != "stylesheet"){
+					return;
+				}
+			
+				handleUrl(i.getAttribute("href"));
+			}catch(exp){
+				//
+			}
+		});
+		
+		dojo.query("img").forEach(function(i){
+			try{
+				handleUrl(i.getAttribute("src"));
+			}catch(exp){
+				//
+			}
+		});
+		
+		dojo.query("a").forEach(function(i){
+			try{
+				handleUrl(i.getAttribute("href"));
+			}catch(exp){
+				//
+			}
+		});
+		
+		// FIXME: handle 'object' and 'embed' tag
+		
+		// parse our style sheets for inline URLs and imports
+		dojo.forEach(document.styleSheets, function(sheet){
+			try{
+				if(sheet.cssRules){ // Firefox
+					dojo.forEach(sheet.cssRules, function(rule){
+						var text = rule.cssText;
+						if(text){
+							var matches = text.match(/url\(\s*([^\) ]*)\s*\)/i);
+							if(!matches){
+								return;
+							}
+							
+							for(var i = 1; i < matches.length; i++){
+								handleUrl(matches[i])
+							}
+						}
+					});
+				}else if(sheet.cssText){ // IE
+					var matches;
+					var text = sheet.cssText.toString();
+					// unfortunately, using RegExp.exec seems to be flakey
+					// for looping across multiple lines on IE using the
+					// global flag, so we have to simulate it
+					var lines = text.split(/\f|\r|\n/);
+					for(var i = 0; i < lines.length; i++){
+						matches = lines[i].match(/url\(\s*([^\) ]*)\s*\)/i);
+						if(matches && matches.length){
+							handleUrl(matches[1]);
+						}
+					}
+				}
+			}catch(exp){
+				//
+			}
+		});
+		
+		//this.printURLs();
+	},
+	
+	_sameLocation: function(url){
+		if(!url){ return false; }
+		
+		// filter out anchors
+		if(url.length && url.charAt(0) == "#"){
+			return false;
+		}
+		
+		// FIXME: dojo._Url should be made public;
+		// it's functionality is very useful for
+		// parsing URLs correctly, which is hard to
+		// do right
+		url = new dojo._Url(url);
+		
+		// totally relative -- ../../someFile.html
+		if(!url.scheme && !url.port && !url.host){ 
+			return true;
+		}
+		
+		// scheme relative with port specified -- brad.com:8080
+		if(!url.scheme && url.host && url.port
+				&& window.location.hostname == url.host
+				&& window.location.port == url.port){
+			return true;
+		}
+		
+		// scheme relative with no-port specified -- brad.com
+		if(!url.scheme && url.host && !url.port
+			&& window.location.hostname == url.host
+			&& window.location.port == 80){
+			return true;
+		}
+		
+		// else we have everything
+		return  window.location.protocol == (url.scheme + ":")
+				&& window.location.hostname == url.host
+				&& (window.location.port == url.port || !window.location.port && !url.port);
+	},
+	
+	_trimAnchor: function(url){
+		return url.replace(/\#.*$/, "");
+	},
+	
+	_doRefresh: function(callback, newVersion){
+		// get our local server
+		var localServer;
+		try{
+			localServer = google.gears.factory.create("beta.localserver", "1.0");
+		}catch(exp){
+			dojo.setObject("google.gears.denied", true);
+			dojox.off.onFrameworkEvent("coreOperationFailed");
+			throw "Google Gears must be allowed to run";
+		}
+		
+		var storeName = "dot_store_" 
+							+ window.location.href.replace(/[^0-9A-Za-z_]/g, "_");
+							
+		// clip at 64 characters, the max length of a resource store name
+		if(storeName.length >= 64){
+		  storeName = storeName.substring(0, 63);
+		}
+			
+		// refresh everything by simply removing
+		// any older stores
+		localServer.removeStore(storeName);
+		
+		// open/create the resource store
+		localServer.openStore(storeName);
+		var store = localServer.createStore(storeName);
+		this._store = store;
+
+		// add our list of files to capture
+		var self = this;
+		this._currentFileIndex = 0;
+		this._cancelID = store.capture(this.listOfURLs, function(url, success, captureId){
+			//
+			if(!success && self.refreshing){
+				self._cancelID = null;
+				self.refreshing = false;
+				var errorMsgs = [];
+				errorMsgs.push("Unable to capture: " + url);
+				callback(true, errorMsgs);
+				return;
+			}else if(success){
+				self._currentFileIndex++;
+			}
+			
+			if(success && self._currentFileIndex >= self.listOfURLs.length){
+				self._cancelID = null;
+				self.refreshing = false;
+				if(newVersion){
+					dojox.storage.put("oldVersion", newVersion, null,
+									dojox.off.STORAGE_NAMESPACE);
+				}
+				dojox.storage.put("justDebugged", dojo.config.isDebug, null,
+									dojox.off.STORAGE_NAMESPACE);
+				callback(false, []);
+			}
+		});
+	},
+	
+	_getVersionInfo: function(callback){
+		var justDebugged = dojox.storage.get("justDebugged", 
+									dojox.off.STORAGE_NAMESPACE);
+		var oldVersion = dojox.storage.get("oldVersion",
+									dojox.off.STORAGE_NAMESPACE);
+		var newVersion = null;
+		
+		callback = dojo.hitch(this, callback);
+		
+		dojo.xhrGet({
+				url: this.versionURL + "?browserbust=" + new Date().getTime(),
+				timeout: 5 * 1000,
+				handleAs: "javascript",
+				error: function(err){
+					//console.warn("dojox.off.files._getVersionInfo, err=",err);
+					dojox.storage.remove("oldVersion", dojox.off.STORAGE_NAMESPACE);
+					dojox.storage.remove("justDebugged", dojox.off.STORAGE_NAMESPACE);
+					callback(oldVersion, newVersion, justDebugged);
+				},
+				load: function(data){
+					//console.warn("dojox.off.files._getVersionInfo, load=",data);
+					
+					// some servers incorrectly return 404's
+					// as a real page
+					if(data){
+						newVersion = data;
+					}
+					
+					callback(oldVersion, newVersion, justDebugged);
+				}
+		});
+	}
+}
+
+}
+
+if(!dojo._hasResource["dojox.off.sync"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.off.sync"] = true;
+dojo.provide("dojox.off.sync");
+
+
+
+
+
+// Author: Brad Neuberg, bkn3 at columbia.edu, http://codinginparadise.org
+
+// summary:
+//		Exposes syncing functionality to offline applications
+dojo.mixin(dojox.off.sync, {
+	// isSyncing: boolean
+	//		Whether we are in the middle of a syncing session.
+	isSyncing: false,
+	
+	// cancelled: boolean
+	//		Whether we were cancelled during our last sync request or not. If
+	//		we are cancelled, then successful will be false.
+	cancelled: false,
+	
+	// successful: boolean
+	//		Whether the last sync was successful or not.  If false, an error
+	//		occurred.
+	successful: true,
+	
+	// details: String[]
+	//		Details on the sync. If the sync was successful, this will carry
+	//		any conflict or merging messages that might be available; if the
+	//		sync was unsuccessful, this will have an error message.  For both
+	//		of these, this should be an array of Strings, where each string
+	//		carries details on the sync. 
+	//	Example: 
+	//		dojox.off.sync.details = ["The document 'foobar' had conflicts - yours one",
+	//						"The document 'hello world' was automatically merged"];
+	details: [],
+	
+	// error: boolean
+	//		Whether an error occurred during the syncing process.
+	error: false,
+	
+	// actions: dojox.off.sync.ActionLog
+	//		Our ActionLog that we store offline actions into for later
+	//		replaying when we go online
+	actions: null,
+	
+	// autoSync: boolean
+	//		For advanced usage; most developers can ignore this.
+	//		Whether we do automatically sync on page load or when we go online.
+	//		If true we do, if false syncing must be manually initiated.
+	//		Defaults to true.
+	autoSync: true,
+	
+	// summary:
+	//	An event handler that is called during the syncing process with
+	//	the state of syncing. It is important that you connect to this
+	//	method and respond to certain sync events, especially the 
+	//	"download" event.
+	// description:
+	//	This event handler is called during the syncing process. You can
+	//	do a dojo.connect to receive sync feedback:
+	//
+	//		dojo.connect(dojox.off.sync, "onSync", someFunc);
+	//
+	//	You will receive one argument, which is the type of the event
+	//	and which can have the following values.
+	//
+	//	The most common two types that you need to care about are "download"
+	//	and "finished", especially if you are using the default
+	//	Dojo Offline UI widget that does the hard work of informing
+	//	the user through the UI about what is occuring during syncing.
+	//
+	//	If you receive the "download" event, you should make a network call
+	//	to retrieve and store your data somehow for offline access. The
+	//	"finished" event indicates that syncing is done. An example:
+	//	
+	//		dojo.connect(dojox.off.sync, "onSync", function(type){
+	//			if(type == "download"){
+	//				// make a network call to download some data
+	//				// for use offline
+	//				dojo.xhrGet({
+	//					url: 		"downloadData.php",
+	//					handleAs:	"javascript",
+	//					error:		function(err){
+	//						dojox.off.sync.finishedDownloading(false, "Can't download data");
+	//					},
+	//					load:		function(data){
+	//						// store our data
+	//						dojox.storage.put("myData", data);
+	//
+	//						// indicate we are finished downloading
+	//						dojox.off.sync.finishedDownloading(true);
+	//					}
+	//				});
+	//			}else if(type == "finished"){
+	//				// update UI somehow to indicate we are finished,
+	//				// such as using the download data to change the 
+	//				// available data
+	//			}
+	//		})
+	//
+	//	Here is the full list of event types if you want to do deep
+	//	customization, such as updating your UI to display the progress
+	//	of syncing (note that the default Dojo Offline UI widget does
+	//	this for you if you choose to pull that in). Most of these
+	//	are only appropriate for advanced usage and can be safely
+	//	ignored:
+	//
+	//		* "start"
+	//				syncing has started
+	//		* "refreshFiles"
+	//				syncing will begin refreshing
+	//				our offline file cache
+	//		* "upload"
+	//				syncing will begin uploading
+	//				any local data changes we have on the client.
+	//				This event is fired before we fire
+	//				the dojox.off.sync.actions.onReplay event for
+	//				each action to replay; use it to completely
+	//				over-ride the replaying behavior and prevent
+	//				it entirely, perhaps rolling your own sync
+	//				protocol if needed.
+	//		* "download"
+	//				syncing will begin downloading any new data that is
+	//				needed into persistent storage. Applications are required to
+	//				implement this themselves, storing the required data into
+	//				persistent local storage using Dojo Storage.
+	//		* "finished"
+	//				syncing is finished; this
+	//				will be called whether an error ocurred or not; check
+	//				dojox.off.sync.successful and dojox.off.sync.error for sync details
+	//		* "cancel"
+	//				Fired when canceling has been initiated; canceling will be
+	//				attempted, followed by the sync event "finished".
+	onSync: function(/* String */ type){},
+	
+	synchronize: function(){ /* void */
+		// summary: Starts synchronizing
+
+		//dojo.debug("synchronize");
+		if(this.isSyncing || dojox.off.goingOnline || (!dojox.off.isOnline)){
+			return;
+		}
+	
+		this.isSyncing = true;
+		this.successful = false;
+		this.details = [];
+		this.cancelled = false;
+		
+		this.start();
+	},
+	
+	cancel: function(){ /* void */
+		// summary:
+		//	Attempts to cancel this sync session
+		
+		if(!this.isSyncing){ return; }
+		
+		this.cancelled = true;
+		if(dojox.off.files.refreshing){
+			dojox.off.files.abortRefresh();
+		}
+		
+		this.onSync("cancel");
+	},
+	
+	finishedDownloading: function(successful /* boolean? */, 
+									errorMessage /* String? */){
+		// summary:
+		//		Applications call this method from their
+		//		after getting a "download" event in
+		//		dojox.off.sync.onSync to signal that
+		//		they are finished downloading any data 
+		//		that should be available offline
+		// successful: boolean?
+		//		Whether our downloading was successful or not.
+		//		If not present, defaults to true.
+		// errorMessage: String?
+		//		If unsuccessful, a message explaining why
+		if(typeof successful == "undefined"){
+			successful = true;
+		}
+		
+		if(!successful){
+			this.successful = false;
+			this.details.push(errorMessage);
+			this.error = true;
+		}
+		
+		this.finished();
+	},
+	
+	start: function(){ /* void */
+		// summary:
+		//	For advanced usage; most developers can ignore this.
+		//	Called at the start of the syncing process. Advanced
+		//	developers can over-ride this method to use their
+		//	own sync mechanism to start syncing.
+		
+		if(this.cancelled){
+			this.finished();
+			return;
+		}
+		this.onSync("start");
+		this.refreshFiles();
+	},
+	
+	refreshFiles: function(){ /* void */
+		// summary:
+		//	For advanced usage; most developers can ignore this.
+		//	Called when we are going to refresh our list
+		//	of offline files during syncing. Advanced developers 
+		//	can over-ride this method to do some advanced magic related to
+		//	refreshing files.
+		
+		//dojo.debug("refreshFiles");
+		if(this.cancelled){
+			this.finished();
+			return;
+		}
+		
+		this.onSync("refreshFiles");
+		
+		dojox.off.files.refresh(dojo.hitch(this, function(error, errorMessages){
+			if(error){
+				this.error = true;
+				this.successful = false;
+				for(var i = 0; i < errorMessages.length; i++){
+					this.details.push(errorMessages[i]);
+				}
+				
+				// even if we get an error while syncing files,
+				// keep syncing so we can upload and download
+				// data
+			}
+			
+			this.upload();
+		}));
+	},
+	
+	upload: function(){ /* void */
+		// summary:
+		//	For advanced usage; most developers can ignore this.
+		//	Called when syncing wants to upload data. Advanced
+		//	developers can over-ride this method to completely
+		//	throw away the Action Log and replaying system
+		//	and roll their own advanced sync mechanism if needed.
+		
+		if(this.cancelled){
+			this.finished();
+			return;
+		}
+		
+		this.onSync("upload");
+		
+		// when we are done uploading start downloading
+		dojo.connect(this.actions, "onReplayFinished", this, this.download);
+		
+		// replay the actions log
+		this.actions.replay();
+	},
+	
+	download: function(){ /* void */
+		// summary:
+		//	For advanced usage; most developers can ignore this.
+		//	Called when syncing wants to download data. Advanced
+		//	developers can over-ride this method to use their
+		//	own sync mechanism.
+		
+		if(this.cancelled){
+			this.finished();
+			return;
+		}
+		
+		// apps should respond to the "download"
+		// event to download their data; when done
+		// they must call dojox.off.sync.finishedDownloading()
+		this.onSync("download");
+	},
+	
+	finished: function(){ /* void */
+		// summary:
+		//	For advanced usage; most developers can ignore this.
+		//	Called when syncing is finished. Advanced
+		//	developers can over-ride this method to clean
+		//	up after finishing their own sync
+		//	mechanism they might have rolled.
+		this.isSyncing = false;
+		
+		this.successful = (!this.cancelled && !this.error);
+		
+		this.onSync("finished");
+	},
+	
+	_save: function(callback){
+		this.actions._save(function(){
+			callback();
+		});
+	},
+	
+	_load: function(callback){
+		this.actions._load(function(){
+			callback();
+		});
+	}
+});
+
+
+// summary:
+//		A class that records actions taken by a user when they are offline,
+//		suitable for replaying when the network reappears. 
+// description:
+//		The basic idea behind this method is to record user actions that would
+//		normally have to contact a server into an action log when we are
+//		offline, so that later when we are online we can simply replay this log
+//		in the order user actions happened so that they can be executed against
+//		the server, causing synchronization to happen. 
+//		
+//		When we replay, for each of the actions that were added, we call a 
+//		method named onReplay that applications should connect to and 
+//		which will be called over and over for each of our actions -- 
+//		applications should take the offline action
+//		information and use it to talk to a server to have this action
+//		actually happen online, 'syncing' themselves with the server. 
+//
+//		For example, if the action was "update" with the item that was updated, we
+//		might call some RESTian server API that exists for updating an item in
+//		our application.  The server could either then do sophisticated merging
+//		and conflict resolution on the server side, for example, allowing you
+//		to pop up a custom merge UI, or could do automatic merging or nothing
+//		of the sort. When you are finished with this particular action, your
+//		application is then required to call continueReplay() on the actionLog object
+//		passed to onReplay() to continue replaying the action log, or haltReplay()
+//		with the reason for halting to completely stop the syncing/replaying
+//		process.
+//
+//		For example, imagine that we have a web application that allows us to add
+//		contacts. If we are offline, and we update a contact, we would add an action;
+//		imagine that the user has to click an Update button after changing the values
+//		for a given contact:
+//	
+//		dojox.off.whenOffline(dojo.byId("updateButton"), "onclick", function(evt){
+//			// get the updated customer values
+//			var customer = getCustomerValues();
+//			
+//			// we are offline -- just record this action
+//			var action = {name: "update", customer: customer};
+//			dojox.off.sync.actions.add(action)
+//			
+//			// persist this customer data into local storage as well
+//			dojox.storage.put(customer.name, customer);
+//		})
+//
+//		Then, when we go back online, the dojox.off.sync.actions.onReplay event
+//		will fire over and over, once for each action that was recorded while offline:
+//
+//		dojo.connect(dojox.off.sync.actions, "onReplay", function(action, actionLog){
+//			// called once for each action we added while offline, in the order
+//			// they were added
+//			if(action.name == "update"){
+//				var customer = action.customer;
+//				
+//				// call some network service to update this customer
+//				dojo.xhrPost({
+//					url: "updateCustomer.php",
+//					content: {customer: dojo.toJson(customer)},
+//					error: function(err){
+//						actionLog.haltReplay(err);
+//					},
+//					load: function(data){
+//						actionLog.continueReplay();
+//					}
+//				})
+//			}
+//		})
+//
+//		Note that the actions log is always automatically persisted locally while using it, so
+//		that if the user closes the browser or it crashes the actions will safely be stored
+//		for later replaying.
+dojo.declare("dojox.off.sync.ActionLog", null, {
+		// entries: Array
+		//		An array of our action entries, where each one is simply a custom
+		//		object literal that were passed to add() when this action entry
+		//		was added.
+		entries: [],
+		
+		// reasonHalted: String
+		//		If we halted, the reason why
+		reasonHalted: null,
+		
+		// isReplaying: boolean
+		//		If true, we are in the middle of replaying a command log; if false,
+		//		then we are not
+		isReplaying: false,
+		
+		// autoSave: boolean
+		//		Whether we automatically save the action log after each call to
+		//		add(); defaults to true. For applications that are rapidly adding
+		//		many action log entries in a short period of time, it can be
+		//		useful to set this to false and simply call save() yourself when
+		//		you are ready to persist your command log -- otherwise performance
+		//		could be slow as the default action is to attempt to persist the
+		//		actions log constantly with calls to add().
+		autoSave: true,
+		
+		add: function(action /* Object */){ /* void */
+			// summary:
+			//	Adds an action to our action log
+			// description:
+			//	This method will add an action to our
+			//	action log, later to be replayed when we
+			//	go from offline to online. 'action'
+			//	will be available when this action is
+			//	replayed and will be passed to onReplay.
+			//
+			//	Example usage:
+			//	
+			//	dojox.off.sync.log.add({actionName: "create", itemType: "document",
+			//					  {title: "Message", content: "Hello World"}});
+			// 
+			//	The object literal is simply a custom object appropriate
+			//	for our application -- it can be anything that preserves the state
+			//	of a user action that will be executed when we go back online
+			//	and replay this log. In the above example,
+			//	"create" is the name of this action; "documents" is the 
+			//	type of item this command is operating on, such as documents, contacts,
+			//	tasks, etc.; and the final argument is the document that was created. 
+			
+			if(this.isReplaying){
+				throw "Programming error: you can not call "
+						+ "dojox.off.sync.actions.add() while "
+						+ "we are replaying an action log";
+			}
+			
+			this.entries.push(action);
+			
+			// save our updated state into persistent
+			// storage
+			if(this.autoSave){
+				this._save();
+			}
+		},
+		
+		onReplay: function(action /* Object */, 
+							actionLog /* dojox.off.sync.ActionLog */){ /* void */
+			// summary:
+			//	Called when we replay our log, for each of our action
+			//	entries.
+			// action: Object
+			//	A custom object literal representing an action for this
+			//	application, such as 
+			//	{actionName: "create", item: {title: "message", content: "hello world"}}
+			// actionLog: dojox.off.sync.ActionLog
+			//	A reference to the dojox.off.sync.actions log so that developers
+			//	can easily call actionLog.continueReplay() or actionLog.haltReplay().
+			// description:
+			//	This callback should be connected to by applications so that
+			//	they can sync themselves when we go back online:
+			//
+			//		dojo.connect(dojox.off.sync.actions, "onReplay", function(action, actionLog){
+			//				// do something
+			//		})
+			//
+			//	When we replay our action log, this callback is called for each
+			//	of our action entries in the order they were added. The 
+			//	'action' entry that was passed to add() for this action will 
+			//	also be passed in to onReplay, so that applications can use this information
+			//	to do their syncing, such as contacting a server web-service
+			//	to create a new item, for example. 
+			// 
+			//	Inside the method you connected to onReplay, you should either call
+			//	actionLog.haltReplay(reason) if an error occurred and you would like to halt
+			//	action replaying or actionLog.continueReplay() to have the action log
+			//	continue replaying its log and proceed to the next action; 
+			//	the reason you must call these is the action you execute inside of 
+			//	onAction will probably be asynchronous, since it will be talking on 
+			//	the network, and you should call one of these two methods based on 
+			//	the result of your network call.
+		},
+		
+		length: function(){ /* Number */
+			// summary:
+			//	Returns the length of this 
+			//	action log
+			return this.entries.length;
+		},
+		
+		haltReplay: function(reason /* String */){ /* void */
+			// summary: Halts replaying this command log.
+			// reason: String
+			//		The reason we halted.
+			// description:
+			//		This method is called as we are replaying an action log; it
+			//		can be called from dojox.off.sync.actions.onReplay, for
+			//		example, for an application to indicate an error occurred
+			//		while replaying this action, halting further processing of
+			//		the action log. Note that any action log entries that
+			//		were processed before have their effects retained (i.e.
+			//		they are not rolled back), while the action entry that was
+			//		halted stays in our list of actions to later be replayed.	
+			if(!this.isReplaying){
+				return;
+			}
+			
+			if(reason){
+				this.reasonHalted = reason.toString();		
+			}
+			
+			// save the state of our action log, then
+			// tell anyone who is interested that we are
+			// done when we are finished saving
+			if(this.autoSave){
+				var self = this;
+				this._save(function(){
+					self.isReplaying = false;
+					self.onReplayFinished();
+				});
+			}else{
+				this.isReplaying = false;
+				this.onReplayFinished();
+			}
+		},
+		
+		continueReplay: function(){ /* void */
+			// summary:
+			//		Indicates that we should continue processing out list of
+			//		actions.
+			// description:
+			//		This method is called by applications that have overridden
+			//		dojox.off.sync.actions.onReplay() to continue replaying our 
+			//		action log after the application has finished handling the 
+			//		current action.
+			if(!this.isReplaying){
+				return;
+			}
+			
+			// shift off the old action we just ran
+			this.entries.shift();
+			
+			// are we done?
+			if(!this.entries.length){
+				// save the state of our action log, then
+				// tell anyone who is interested that we are
+				// done when we are finished saving
+				if(this.autoSave){
+					var self = this;
+					this._save(function(){
+						self.isReplaying = false;
+						self.onReplayFinished();
+					});
+					return;
+				}else{
+					this.isReplaying = false;
+					this.onReplayFinished();
+					return;
+				}
+			}
+			
+			// get the next action
+			var nextAction = this.entries[0];
+			this.onReplay(nextAction, this);
+		},
+		
+		clear: function(){ /* void */
+			// summary:
+			//	Completely clears this action log of its entries
+			
+			if(this.isReplaying){
+				return;
+			}
+			
+			this.entries = [];
+			
+			// save our updated state into persistent
+			// storage
+			if(this.autoSave){
+				this._save();
+			}
+		},
+		
+		replay: function(){ /* void */
+			// summary:
+			//	For advanced usage; most developers can ignore this.
+			//	Replays all of the commands that have been
+			//	cached in this command log when we go back online;
+			//	onCommand will be called for each command we have
+			
+			if(this.isReplaying){
+				return;
+			}
+			
+			this.reasonHalted = null;
+			
+			if(!this.entries.length){
+				this.onReplayFinished();
+				return;
+			}
+			
+			this.isReplaying = true;
+			
+			var nextAction = this.entries[0];
+			this.onReplay(nextAction, this);
+		},
+		
+		// onReplayFinished: Function
+		//	For advanced usage; most developers can ignore this.
+		//	Called when we are finished replaying our commands;
+		//	called if we have successfully exhausted all of our
+		//	commands, or if an error occurred during replaying.
+		//	The default implementation simply continues the
+		//	synchronization process. Connect to this to register
+		//	for the event:
+		//
+		//		dojo.connect(dojox.off.sync.actions, "onReplayFinished", 
+		//					someFunc)
+		onReplayFinished: function(){
+		},
+
+		toString: function(){
+			var results = "";
+			results += "[";
+			
+			for(var i = 0; i < this.entries.length; i++){
+				results += "{";
+				for(var j in this.entries[i]){
+					results += j + ": \"" + this.entries[i][j] + "\"";
+					results += ", ";
+				}
+				results += "}, ";
+			}
+			
+			results += "]";
+			
+			return results;
+		},
+		
+		_save: function(callback){
+			if(!callback){
+				callback = function(){};
+			}
+			
+			try{
+				var self = this;
+				var resultsHandler = function(status, key, message){
+					//
+					if(status == dojox.storage.FAILED){
+						dojox.off.onFrameworkEvent("save", 
+											{status: dojox.storage.FAILED,
+											isCoreSave: true,
+											key: key,
+											value: message,
+											namespace: dojox.off.STORAGE_NAMESPACE});
+						callback();
+					}else if(status == dojox.storage.SUCCESS){
+						callback();
+					}
+				};
+				
+				dojox.storage.put("actionlog", this.entries, resultsHandler,
+									dojox.off.STORAGE_NAMESPACE);
+			}catch(exp){
+				
+				dojox.off.onFrameworkEvent("save",
+							{status: dojox.storage.FAILED,
+							isCoreSave: true,
+							key: "actionlog",
+							value: this.entries,
+							namespace: dojox.off.STORAGE_NAMESPACE});
+				callback();
+			}
+		},
+		
+		_load: function(callback){
+			var entries = dojox.storage.get("actionlog", dojox.off.STORAGE_NAMESPACE);
+			
+			if(!entries){
+				entries = [];
+			}
+			
+			this.entries = entries;
+			
+			callback();
+		}
+	}
+);
+
+dojox.off.sync.actions = new dojox.off.sync.ActionLog();
+
+}
+
+if(!dojo._hasResource["dojox.off._common"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.off._common"] = true;
+dojo.provide("dojox.off._common");
+
+
+
+
+
+
+// Author: Brad Neuberg, bkn3 at columbia.edu, http://codinginparadise.org
+
+// summary:
+//		dojox.off is the main object for offline applications.
+dojo.mixin(dojox.off, {
+	// isOnline: boolean
+	//	true if we are online, false if not
+	isOnline: false,
+	
+	// NET_CHECK: int
+	//		For advanced usage; most developers can ignore this.
+	//		Time in seconds on how often we should check the status of the
+	//		network with an automatic background timer. The current default
+	//		is 5 seconds.
+	NET_CHECK: 5,
+	
+	// STORAGE_NAMESPACE: String
+	//		For advanced usage; most developers can ignore this.
+	//		The namespace we use to save core data into Dojo Storage.
+	STORAGE_NAMESPACE: "_dot",
+	
+	// enabled: boolean
+	//		For advanced usage; most developers can ignore this.
+	//		Whether offline ability is enabled or not. Defaults to true.
+	enabled: true,
+	
+	// availabilityURL: String
+	//		For advanced usage; most developers can ignore this.
+	//		The URL to check for site availability.  We do a GET request on
+	//		this URL to check for site availability.  By default we check for a
+	//		simple text file in src/off/network_check.txt that has one value
+	//		it, the value '1'.
+	availabilityURL: dojo.moduleUrl("dojox", "off/network_check.txt"),
+	
+	// goingOnline: boolean
+	//		For advanced usage; most developers can ignore this.
+	//		True if we are attempting to go online, false otherwise
+	goingOnline: false,
+	
+	// coreOpFailed: boolean
+	//		For advanced usage; most developers can ignore this.
+	//		A flag set by the Dojo Offline framework that indicates that the
+	//		user denied some operation that required the offline cache or an
+	//		operation failed in some critical way that was unrecoverable. For
+	//		example, if the offline cache is Google Gears and we try to get a
+	//		Gears database, a popup window appears asking the user whether they
+	//		will approve or deny this request. If the user denies the request,
+	//		and we are doing some operation that is core to Dojo Offline, then
+	//		we set this flag to 'true'.  This flag causes a 'fail fast'
+	//		condition, turning off offline ability.
+	coreOpFailed: false,
+	
+	// doNetChecking: boolean
+	//		For advanced usage; most developers can ignore this.
+	//		Whether to have a timing interval in the background doing automatic
+	//		network checks at regular intervals; the length of time between
+	//		checks is controlled by dojox.off.NET_CHECK. Defaults to true.
+	doNetChecking: true,
+	
+	// hasOfflineCache: boolean
+	//		For advanced usage; most developers can ignore this.
+	//  	Determines if an offline cache is available or installed; an
+	//  	offline cache is a facility that can truely cache offline
+	//  	resources, such as JavaScript, HTML, etc. in such a way that they
+	//  	won't be removed from the cache inappropriately like a browser
+	//  	cache would. If this is false then an offline cache will be
+	//  	installed. Only Google Gears is currently supported as an offline
+	//  	cache. Future possible offline caches include Firefox 3.
+	hasOfflineCache: null,
+	
+	// browserRestart: boolean
+	//		For advanced usage; most developers can ignore this.
+	//		If true, the browser must be restarted to register the existence of
+	//		a new host added offline (from a call to addHostOffline); if false,
+	//		then nothing is needed.
+	browserRestart: false,
+	
+	_STORAGE_APP_NAME: window.location.href.replace(/[^0-9A-Za-z_]/g, "_"),
+	
+	_initializeCalled: false,
+	_storageLoaded: false,
+	_pageLoaded: false,
+	
+	onLoad: function(){
+		// summary:
+		//	Called when Dojo Offline can be used.
+		// description:
+		//	Do a dojo.connect to this to know when you can
+		//	start using Dojo Offline:
+		//		dojo.connect(dojox.off, "onLoad", myFunc);
+	},
+	
+	onNetwork: function(type){
+		// summary:
+		//	Called when our on- or offline- status changes.
+		// description:
+		//	If we move online, then this method is called with the
+		//	value "online". If we move offline, then this method is
+		//	called with the value "offline". You can connect to this
+		//	method to do add your own behavior:
+		//
+		//		dojo.connect(dojox.off, "onNetwork", someFunc)
+		//
+		//	Note that if you are using the default Dojo Offline UI
+		//	widget that most of the on- and off-line notification
+		//	and syncing is automatically handled and provided to the
+		//	user.
+		// type: String
+		//	Either "online" or "offline".
+	},
+	
+	initialize: function(){ /* void */
+		// summary:
+		//		Called when a Dojo Offline-enabled application is finished
+		//		configuring Dojo Offline, and is ready for Dojo Offline to
+		//		initialize itself.
+		// description:
+		//		When an application has finished filling out the variables Dojo
+		//		Offline needs to work, such as dojox.off.ui.appName, it must
+		//		this method to tell Dojo Offline to initialize itself.
+		
+		//		Note:
+		//		This method is needed for a rare edge case. In some conditions,
+		//		especially if we are dealing with a compressed Dojo build, the
+		//		entire Dojo Offline subsystem might initialize itself and be
+		//		running even before the JavaScript for an application has had a
+		//		chance to run and configure Dojo Offline, causing Dojo Offline
+		//		to have incorrect initialization parameters for a given app,
+		//		such as no value for dojox.off.ui.appName. This method is
+		//		provided to prevent this scenario, to slightly 'slow down' Dojo
+		//		Offline so it can be configured before running off and doing
+		//		its thing.	
+
+		//
+		this._initializeCalled = true;
+		
+		if(this._storageLoaded && this._pageLoaded){
+			this._onLoad();
+		}
+	},
+	
+	goOffline: function(){ /* void */
+		// summary:
+		//		For advanced usage; most developers can ignore this.
+		//		Manually goes offline, away from the network.
+		if((dojox.off.sync.isSyncing)||(this.goingOnline)){ return; }
+		
+		this.goingOnline = false;
+		this.isOnline = false;
+	},
+	
+	goOnline: function(callback){ /* void */
+		// summary: 
+		//		For advanced usage; most developers can ignore this.
+		//		Attempts to go online.
+		// description:
+		//		Attempts to go online, making sure this web application's web
+		//		site is available. 'callback' is called asychronously with the
+		//		result of whether we were able to go online or not.
+		// callback: Function
+		//		An optional callback function that will receive one argument:
+		//		whether the site is available or not and is boolean. If this
+		//		function is not present we call dojo.xoff.onOnline instead if
+		//		we are able to go online.
+		
+		//
+		
+		if(dojox.off.sync.isSyncing || dojox.off.goingOnline){
+			return;
+		}
+		
+		this.goingOnline = true;
+		this.isOnline = false;
+		
+		// see if can reach our web application's web site
+		this._isSiteAvailable(callback);
+	},
+	
+	onFrameworkEvent: function(type /* String */, saveData /* Object? */){
+		//	summary:
+		//		For advanced usage; most developers can ignore this.
+		//		A standard event handler that can be attached to to find out
+		//		about low-level framework events. Most developers will not need to
+		//		attach to this method; it is meant for low-level information
+		//		that can be useful for updating offline user-interfaces in
+		//		exceptional circumstances. The default Dojo Offline UI
+		//		widget takes care of most of these situations.
+		//	type: String
+		//		The type of the event:
+		//
+		//		* "offlineCacheInstalled"
+		//			An event that is fired when a user
+		//			has installed an offline cache after the page has been loaded.
+		//			If a user didn't have an offline cache when the page loaded, a
+		//			UI of some kind might have prompted them to download one. This
+		//			method is called if they have downloaded and installed an
+		//			offline cache so a UI can reinitialize itself to begin using
+		//			this offline cache.
+		//		* "coreOperationFailed"
+		//			Fired when a core operation during interaction with the
+		//			offline cache is denied by the user. Some offline caches, such
+		//			as Google Gears, prompts the user to approve or deny caching
+		//			files, using the database, and more. If the user denies a
+		//			request that is core to Dojo Offline's operation, we set
+		//			dojox.off.coreOpFailed to true and call this method for
+		//			listeners that would like to respond some how to Dojo Offline
+		//			'failing fast'.
+		//		* "save"
+		//			Called whenever the framework saves data into persistent
+		//			storage. This could be useful for providing save feedback
+		//			or providing appropriate error feedback if saving fails 
+		//			due to a user not allowing the save to occur
+		//	saveData: Object?
+		//		If the type was 'save', then a saveData object is provided with
+		//		further save information. This object has the following properties:	
+		//
+		//		* status - dojox.storage.SUCCESS, dojox.storage.PENDING, dojox.storage.FAILED
+		//		Whether the save succeeded, whether it is pending based on a UI
+		//		dialog asking the user for permission, or whether it failed. 	
+		//
+		//		* isCoreSave - boolean
+		//		If true, then this save was for a core piece of data necessary
+		//		for the functioning of Dojo Offline. If false, then it is a
+		//		piece of normal data being saved for offline access. Dojo
+		//		Offline will 'fail fast' if some core piece of data could not
+		//		be saved, automatically setting dojox.off.coreOpFailed to
+		//		'true' and dojox.off.enabled to 'false'.
+		//
+		// 		* key - String
+		//		The key that we are attempting to persist
+		//
+		// 		* value - Object
+		//		The object we are trying to persist
+		//
+		// 		* namespace - String
+		//		The Dojo Storage namespace we are saving this key/value pair
+		//		into, such as "default", "Documents", "Contacts", etc.
+		//		Optional.
+		if(type == "save"){
+			if(saveData.isCoreSave && (saveData.status == dojox.storage.FAILED)){
+				dojox.off.coreOpFailed = true;
+				dojox.off.enabled = false;
+			
+				// FIXME: Stop the background network thread
+				dojox.off.onFrameworkEvent("coreOperationFailed");
+			}
+		}else if(type == "coreOperationFailed"){
+			dojox.off.coreOpFailed = true;
+			dojox.off.enabled = false;
+			// FIXME: Stop the background network thread
+		}
+	},
+	
+	_checkOfflineCacheAvailable: function(callback){
+		// is a true, offline cache running on this machine?
+		this.hasOfflineCache = dojo.gears.available;
+		
+		callback();
+	},
+	
+	_onLoad: function(){
+		//
+		
+		// both local storage and the page are finished loading
+		
+		// cache the Dojo JavaScript -- just use the default dojo.js
+		// name for the most common scenario
+		// FIXME: TEST: Make sure syncing doesn't break if dojo.js
+		// can't be found, or report an error to developer
+		dojox.off.files.cache(dojo.moduleUrl("dojo", "dojo.js"));
+		
+		// pull in the files needed by Dojo
+		this._cacheDojoResources();
+		
+		// FIXME: need to pull in the firebug lite files here!
+		// workaround or else we will get an error on page load
+		// from Dojo that it can't find 'console.debug' for optimized builds
+		// dojox.off.files.cache(dojo.config.baseRelativePath + "src/debug.js");
+		
+		// make sure that resources needed by all of our underlying
+		// Dojo Storage storage providers will be available
+		// offline
+		dojox.off.files.cache(dojox.storage.manager.getResourceList());
+		
+		// slurp the page if the end-developer wants that
+		dojox.off.files._slurp();
+		
+		// see if we have an offline cache; when done, move
+		// on to the rest of our startup tasks
+		this._checkOfflineCacheAvailable(dojo.hitch(this, "_onOfflineCacheChecked"));
+	},
+	
+	_onOfflineCacheChecked: function(){
+		// this method is part of our _onLoad series of startup tasks
+		
+		// if we have an offline cache, see if we have been added to the 
+		// list of available offline web apps yet
+		if(this.hasOfflineCache && this.enabled){
+			// load framework data; when we are finished, continue
+			// initializing ourselves
+			this._load(dojo.hitch(this, "_finishStartingUp"));
+		}else if(this.hasOfflineCache && !this.enabled){
+			// we have an offline cache, but it is disabled for some reason
+			// perhaps due to the user denying a core operation
+			this._finishStartingUp();
+		}else{
+			this._keepCheckingUntilInstalled();
+		}
+	},
+	
+	_keepCheckingUntilInstalled: function(){
+		// this method is part of our _onLoad series of startup tasks
+		
+		// kick off a background interval that keeps
+		// checking to see if an offline cache has been
+		// installed since this page loaded
+			
+		// FIXME: Gears: See if we are installed somehow after the
+		// page has been loaded
+		
+		// now continue starting up
+		this._finishStartingUp();
+	},
+	
+	_finishStartingUp: function(){
+		//
+		
+		// this method is part of our _onLoad series of startup tasks
+		
+		if(!this.hasOfflineCache){
+			this.onLoad();
+		}else if(this.enabled){
+			// kick off a thread to check network status on
+			// a regular basis
+			this._startNetworkThread();
+
+			// try to go online
+			this.goOnline(dojo.hitch(this, function(){
+				//
+				// indicate we are ready to be used
+				dojox.off.onLoad();
+			}));
+		}else{ // we are disabled or a core operation failed
+			if(this.coreOpFailed){
+				this.onFrameworkEvent("coreOperationFailed");
+			}else{
+				this.onLoad();
+			}
+		}
+	},
+	
+	_onPageLoad: function(){
+		//
+		this._pageLoaded = true;
+		
+		if(this._storageLoaded && this._initializeCalled){
+			this._onLoad();
+		}
+	},
+	
+	_onStorageLoad: function(){
+		//
+		this._storageLoaded = true;
+		
+		// were we able to initialize storage? if
+		// not, then this is a core operation, and
+		// let's indicate we will need to fail fast
+		if(!dojox.storage.manager.isAvailable()
+			&& dojox.storage.manager.isInitialized()){
+			this.coreOpFailed = true;
+			this.enabled = false;
+		}
+		
+		if(this._pageLoaded && this._initializeCalled){
+			this._onLoad();		
+		}
+	},
+	
+	_isSiteAvailable: function(callback){
+		// summary:
+		//		Determines if our web application's website is available.
+		// description:
+		//		This method will asychronously determine if our web
+		//		application's web site is available, which is a good proxy for
+		//		network availability. The URL dojox.off.availabilityURL is
+		//		used, which defaults to this site's domain name (ex:
+		//		foobar.com). We check for dojox.off.AVAILABILITY_TIMEOUT (in
+		//		seconds) and abort after that
+		// callback: Function
+		//		An optional callback function that will receive one argument:
+		//		whether the site is available or not and is boolean. If this
+		//		function is not present we call dojox.off.onNetwork instead if we
+		//		are able to go online.
+		dojo.xhrGet({
+			url:		this._getAvailabilityURL(),
+			handleAs:	"text",
+			timeout:	this.NET_CHECK * 1000, 
+			error:		dojo.hitch(this, function(err){
+				//
+				this.goingOnline = false;
+				this.isOnline = false;
+				if(callback){ callback(false); }
+			}),
+			load:		dojo.hitch(this, function(data){
+				//
+				this.goingOnline = false;
+				this.isOnline = true;
+				
+				if(callback){ callback(true);
+				}else{ this.onNetwork("online"); }
+			})
+		});
+	},
+	
+	_startNetworkThread: function(){
+		//
+		
+		// kick off a thread that does periodic
+		// checks on the status of the network
+		if(!this.doNetChecking){
+			return;
+		}
+		
+		window.setInterval(dojo.hitch(this, function(){	
+			var d = dojo.xhrGet({
+				url:	 	this._getAvailabilityURL(),
+				handleAs:	"text",
+				timeout: 	this.NET_CHECK * 1000,
+				error:		dojo.hitch(this, 
+								function(err){
+									if(this.isOnline){
+										this.isOnline = false;
+										
+										// FIXME: xhrGet() is not
+										// correctly calling abort
+										// on the XHR object when
+										// it times out; fix inside
+										// there instead of externally
+										// here
+										try{
+											if(typeof d.ioArgs.xhr.abort == "function"){
+												d.ioArgs.xhr.abort();
+											}
+										}catch(e){}
+					
+										// if things fell in the middle of syncing, 
+										// stop syncing
+										dojox.off.sync.isSyncing = false;
+					
+										this.onNetwork("offline");
+									}
+								}
+							),
+				load:		dojo.hitch(this, 
+								function(data){
+									if(!this.isOnline){
+										this.isOnline = true;
+										this.onNetwork("online");
+									}
+								}
+							)
+			});
+
+		}), this.NET_CHECK * 1000);
+	},
+	
+	_getAvailabilityURL: function(){
+		var url = this.availabilityURL.toString();
+		
+		// bust the browser's cache to make sure we are really talking to
+		// the server
+		if(url.indexOf("?") == -1){
+			url += "?";
+		}else{
+			url += "&";
+		}
+		url += "browserbust=" + new Date().getTime();
+		
+		return url;
+	},
+	
+	_onOfflineCacheInstalled: function(){
+		this.onFrameworkEvent("offlineCacheInstalled");
+	},
+	
+	_cacheDojoResources: function(){
+		// if we are a non-optimized build, then the core Dojo bootstrap
+		// system was loaded as separate JavaScript files;
+		// add these to our offline cache list. these are
+		// loaded before the dojo.require() system exists
+		
+		// FIXME: create a better mechanism in the Dojo core to
+		// expose whether you are dealing with an optimized build;
+		// right now we just scan the SCRIPT tags attached to this
+		// page and see if there is one for _base/_loader/bootstrap.js
+		var isOptimizedBuild = true;
+		dojo.forEach(dojo.query("script"), function(i){
+			var src = i.getAttribute("src");
+			if(!src){ return; }
+			
+			if(src.indexOf("_base/_loader/bootstrap.js") != -1){
+				isOptimizedBuild = false;
+			}
+		});
+		
+		if(!isOptimizedBuild){
+			dojox.off.files.cache(dojo.moduleUrl("dojo", "_base.js").uri);
+			dojox.off.files.cache(dojo.moduleUrl("dojo", "_base/_loader/loader.js").uri);
+			dojox.off.files.cache(dojo.moduleUrl("dojo", "_base/_loader/bootstrap.js").uri);
+			
+			// FIXME: pull in the host environment file in a more generic way
+			// for other host environments
+			dojox.off.files.cache(dojo.moduleUrl("dojo", "_base/_loader/hostenv_browser.js").uri);
+		}
+		
+		// add anything that was brought in with a 
+		// dojo.require() that resulted in a JavaScript
+		// URL being fetched
+		
+		// FIXME: modify dojo/_base/_loader/loader.js to
+		// expose a public API to get this information
+	
+		for(var i = 0; i < dojo._loadedUrls.length; i++){
+			dojox.off.files.cache(dojo._loadedUrls[i]);
+		}
+		
+		// FIXME: add the standard Dojo CSS file
+	},
+	
+	_save: function(){
+		// summary:
+		//		Causes the Dojo Offline framework to save its configuration
+		//		data into local storage.	
+	},
+	
+	_load: function(callback){
+		// summary:
+		//		Causes the Dojo Offline framework to load its configuration
+		//		data from local storage
+		dojox.off.sync._load(callback);
+	}
+});
+
+
+// wait until the storage system is finished loading
+dojox.storage.manager.addOnLoad(dojo.hitch(dojox.off, "_onStorageLoad"));
+
+// wait until the page is finished loading
+dojo.addOnLoad(dojox.off, "_onPageLoad");
+
+}
+
+if(!dojo._hasResource["dojox.off"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.off"] = true;
+dojo.provide("dojox.off");
+
+
+}
+
+if(!dojo._hasResource["dojox.off.ui"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.off.ui"] = true;
+dojo.provide("dojox.off.ui");
+
+
+
+
+
+// Author: Brad Neuberg, bkn3 at columbia.edu, http://codinginparadise.org
+
+// summary:
+//	dojox.off.ui provides a standard,
+//	default user-interface for a 
+//	Dojo Offline Widget that can easily
+//	be dropped into applications that would
+//	like to work offline.
+dojo.mixin(dojox.off.ui, {
+	// appName: String
+	//	This application's name, such as "Foobar". Note that
+	//	this is a string, not HTML, so embedded markup will
+	//	not work, including entities. Only the following
+	//	characters are allowed: numbers, letters, and spaces.
+	//	You must set this property.
+	appName: "setme",
+	
+	// autoEmbed: boolean
+	//	For advanced usage; most developers can ignore this.
+	//	Whether to automatically auto-embed the default Dojo Offline
+	//	widget into this page; default is true. 
+	autoEmbed: true,
+	
+	// autoEmbedID: String
+	//	For advanced usage; most developers can ignore this.
+	//	The ID of the DOM element that will contain our
+	//	Dojo Offline widget; defaults to the ID 'dot-widget'.
+	autoEmbedID: "dot-widget",
+	
+	// runLink: String
+	//	For advanced usage; most developers can ignore this.
+	//	The URL that should be navigated to to run this 
+	//	application offline; this will be placed inside of a
+	//	link that the user can drag to their desktop and double
+	//	click. Note that this URL must exactly match the URL
+	//	of the main page of our resource that is offline for
+	//	it to be retrieved from the offline cache correctly.
+	//	For example, if you have cached your main page as
+	//	http://foobar.com/index.html, and you set this to
+	//	http://www.foobar.com/index.html, the run link will
+	//	not work. By default this value is automatically set to 
+	//	the URL of this page, so it does not need to be set
+	//	manually unless you have unusual needs.
+	runLink: window.location.href,
+	
+	// runLinkTitle: String
+	//	For advanced usage; most developers can ignore this.
+	//	The text that will be inside of the link that a user
+	//	can drag to their desktop to run this application offline.
+	//	By default this is automatically set to "Run " plus your
+	//	application's name.
+	runLinkTitle: "Run Application",
+	
+	// learnHowPath: String
+	//	For advanced usage; most developers can ignore this.
+	//	The path to a web page that has information on 
+	//	how to use this web app offline; defaults to
+	//	src/off/ui-template/learnhow.html, relative to
+	//	your Dojo installation. Make sure to set
+	//	dojo.to.ui.customLearnHowPath to true if you want
+	//	a custom Learn How page.
+	learnHowPath: dojo.moduleUrl("dojox", "off/resources/learnhow.html"),
+	
+	// customLearnHowPath: boolean
+	//	For advanced usage; most developers can ignore this.
+	//	Whether the developer is using their own custom page
+	//	for the Learn How instructional page; defaults to false.
+	//	Use in conjunction with dojox.off.ui.learnHowPath.
+	customLearnHowPath: false,
+	
+	htmlTemplatePath: dojo.moduleUrl("dojox", "off/resources/offline-widget.html").uri,
+	cssTemplatePath: dojo.moduleUrl("dojox", "off/resources/offline-widget.css").uri,
+	onlineImagePath: dojo.moduleUrl("dojox", "off/resources/greenball.png").uri,
+	offlineImagePath: dojo.moduleUrl("dojox", "off/resources/redball.png").uri,
+	rollerImagePath: dojo.moduleUrl("dojox", "off/resources/roller.gif").uri,
+	checkmarkImagePath: dojo.moduleUrl("dojox", "off/resources/checkmark.png").uri,
+	learnHowJSPath: dojo.moduleUrl("dojox", "off/resources/learnhow.js").uri,
+	
+	_initialized: false,
+	
+	onLoad: function(){
+		// summary:
+		//	A function that should be connected to allow your
+		//	application to know when Dojo Offline, the page, and
+		//	the Offline Widget are all initialized and ready to be
+		//	used:
+		//
+		//		dojo.connect(dojox.off.ui, "onLoad", someFunc)
+	},
+
+	_initialize: function(){
+		//
+		
+		// make sure our app name is correct
+		if(this._validateAppName(this.appName) == false){
+			alert("You must set dojox.off.ui.appName; it can only contain "
+					+ "letters, numbers, and spaces; right now it "
+					+ "is incorrectly set to '" + dojox.off.ui.appName + "'");
+			dojox.off.enabled = false;
+			return;
+		}
+		
+		// set our run link text to its default
+		this.runLinkText = "Run " + this.appName;
+		
+		// setup our event listeners for Dojo Offline events
+		// to update our UI
+		dojo.connect(dojox.off, "onNetwork", this, "_onNetwork");
+		dojo.connect(dojox.off.sync, "onSync", this, "_onSync");
+		
+		// cache our default UI resources
+		dojox.off.files.cache([
+							this.htmlTemplatePath,
+							this.cssTemplatePath,
+							this.onlineImagePath,
+							this.offlineImagePath,
+							this.rollerImagePath,
+							this.checkmarkImagePath
+							]);
+		
+		// embed the offline widget UI
+		if(this.autoEmbed){
+			this._doAutoEmbed();
+		}
+	},
+	
+	_doAutoEmbed: function(){
+		// fetch our HTML for the offline widget
+
+		// dispatch the request
+		dojo.xhrGet({
+			url:	 this.htmlTemplatePath,
+			handleAs:	"text",
+			error:		function(err){
+				dojox.off.enabled = false;
+				err = err.message||err;
+				alert("Error loading the Dojo Offline Widget from "
+						+ this.htmlTemplatePath + ": " + err);
+			},
+			load:		dojo.hitch(this, this._templateLoaded)	 
+		});
+	},
+	
+	_templateLoaded: function(data){
+		//
+		// inline our HTML
+		var container = dojo.byId(this.autoEmbedID);
+		if(container){ container.innerHTML = data; }
+		
+		// fill out our image paths
+		this._initImages();
+		
+		// update our network indicator status ball
+		this._updateNetIndicator();
+		
+		// update our 'Learn How' text
+		this._initLearnHow();
+		
+		this._initialized = true;
+		
+		// check offline cache settings
+		if(!dojox.off.hasOfflineCache){
+			this._showNeedsOfflineCache();
+			return;
+		}
+		
+		// check to see if we need a browser restart
+		// to be able to use this web app offline
+		if(dojox.off.hasOfflineCache && dojox.off.browserRestart){
+			this._needsBrowserRestart();
+			return;
+		}else{
+			var browserRestart = dojo.byId("dot-widget-browser-restart");
+			if(browserRestart){ browserRestart.style.display = "none"; }
+		}
+		
+		// update our sync UI
+		this._updateSyncUI();
+		
+		// register our event listeners for our main buttons
+		this._initMainEvtHandlers();
+		
+		// if offline functionality is disabled, disable everything
+		this._setOfflineEnabled(dojox.off.enabled);
+		
+		// update our UI based on the state of the network
+		this._onNetwork(dojox.off.isOnline ? "online" : "offline");
+		
+		// try to go online
+		this._testNet();
+	},
+	
+	_testNet: function(){
+		dojox.off.goOnline(dojo.hitch(this, function(isOnline){
+			//
+			
+			// display our online/offline results
+			this._onNetwork(isOnline ? "online" : "offline");
+			
+			// indicate that our default UI 
+			// and Dojo Offline are now ready to
+			// be used
+			this.onLoad();
+		}));
+	},
+	
+	_updateNetIndicator: function(){
+		var onlineImg = dojo.byId("dot-widget-network-indicator-online");
+		var offlineImg = dojo.byId("dot-widget-network-indicator-offline");
+		var titleText = dojo.byId("dot-widget-title-text");
+		
+		if(onlineImg && offlineImg){
+			if(dojox.off.isOnline == true){
+				onlineImg.style.display = "inline";
+				offlineImg.style.display = "none";
+			}else{
+				onlineImg.style.display = "none";
+				offlineImg.style.display = "inline";
+			}
+		}
+		
+		if(titleText){
+			if(dojox.off.isOnline){
+				titleText.innerHTML = "Online";
+			}else{
+				titleText.innerHTML = "Offline";
+			}
+		}
+	},
+	
+	_initLearnHow: function(){
+		var learnHow = dojo.byId("dot-widget-learn-how-link");
+		
+		if(!learnHow){ return; }
+		
+		if(!this.customLearnHowPath){
+			// add parameters to URL so the Learn How page
+			// can customize itself and display itself
+			// correctly based on framework settings
+			var dojoPath = dojo.config.baseRelativePath;
+			this.learnHowPath += "?appName=" + encodeURIComponent(this.appName)
+									+ "&hasOfflineCache=" + dojox.off.hasOfflineCache
+									+ "&runLink=" + encodeURIComponent(this.runLink)
+									+ "&runLinkText=" + encodeURIComponent(this.runLinkText)
+									+ "&baseRelativePath=" + encodeURIComponent(dojoPath);
+			
+			// cache our Learn How JavaScript page and
+			// the HTML version with full query parameters
+			// so it is available offline without a cache miss					
+			dojox.off.files.cache(this.learnHowJSPath);
+			dojox.off.files.cache(this.learnHowPath);
+		}
+		
+		learnHow.setAttribute("href", this.learnHowPath);
+		
+		var appName = dojo.byId("dot-widget-learn-how-app-name");
+		
+		if(!appName){ return; }
+		
+		appName.innerHTML = "";
+		appName.appendChild(document.createTextNode(this.appName));
+	},
+	
+	_validateAppName: function(appName){
+		if(!appName){ return false; }
+		
+		return (/^[a-z0-9 ]*$/i.test(appName));
+	},
+	
+	_updateSyncUI: function(){
+		var roller = dojo.byId("dot-roller");
+		var checkmark = dojo.byId("dot-success-checkmark");
+		var syncMessages = dojo.byId("dot-sync-messages");
+		var details = dojo.byId("dot-sync-details");
+		var cancel = dojo.byId("dot-sync-cancel");
+		
+		if(dojox.off.sync.isSyncing){
+			this._clearSyncMessage();
+			
+			if(roller){ roller.style.display = "inline"; }
+			
+			if(checkmark){ checkmark.style.display = "none"; }
+			
+			if(syncMessages){
+				dojo.removeClass(syncMessages, "dot-sync-error");
+			}
+			
+			if(details){ details.style.display = "none"; }
+			
+			if(cancel){ cancel.style.display = "inline"; }
+		}else{	
+			if(roller){ roller.style.display = "none"; }
+			
+			if(cancel){ cancel.style.display = "none"; }
+			
+			if(syncMessages){
+				dojo.removeClass(syncMessages, "dot-sync-error");
+			}
+		}
+	},
+	
+	_setSyncMessage: function(message){
+		var syncMessage = dojo.byId("dot-sync-messages");
+		if(syncMessage){
+			// when used with Google Gears pre-release in Firefox/Mac OS X,
+			// the browser would crash when testing in Moxie
+			// if we set the message this way for some reason.
+			// Brad Neuberg, bkn3 at columbia.edu
+			//syncMessage.innerHTML = message;
+			
+			while(syncMessage.firstChild){
+				syncMessage.removeChild(syncMessage.firstChild);
+			}
+			syncMessage.appendChild(document.createTextNode(message));
+		}
+	},
+	
+	_clearSyncMessage: function(){
+		this._setSyncMessage("");
+	},
+	
+	_initImages: function(){	
+		var onlineImg = dojo.byId("dot-widget-network-indicator-online");
+		if(onlineImg){
+			onlineImg.setAttribute("src", this.onlineImagePath);
+		}
+		
+		var offlineImg = dojo.byId("dot-widget-network-indicator-offline");
+		if(offlineImg){
+			offlineImg.setAttribute("src", this.offlineImagePath);
+		}
+		
+		var roller = dojo.byId("dot-roller");
+		if(roller){
+			roller.setAttribute("src", this.rollerImagePath);
+		}
+		
+		var checkmark = dojo.byId("dot-success-checkmark");
+		if(checkmark){
+			checkmark.setAttribute("src", this.checkmarkImagePath);
+		}
+	},
+	
+	_showDetails: function(evt){
+		// cancel the button's default behavior
+		evt.preventDefault();
+		evt.stopPropagation();
+		
+		if(!dojox.off.sync.details.length){
+			return;
+		}
+		
+		// determine our HTML message to display
+		var html = "";
+		html += "<html><head><title>Sync Details</title><head><body>";
+		html += "<h1>Sync Details</h1>\n";
+		html += "<ul>\n";
+		for(var i = 0; i < dojox.off.sync.details.length; i++){
+			html += "<li>";
+			html += dojox.off.sync.details[i];
+			html += "</li>";	
+		}
+		html += "</ul>\n";
+		html += "<a href='javascript:window.close()' "
+				 + "style='text-align: right; padding-right: 2em;'>"
+				 + "Close Window"
+				 + "</a>\n";
+		html += "</body></html>";
+		
+		// open a popup window with this message
+		var windowParams = "height=400,width=600,resizable=true,"
+							+ "scrollbars=true,toolbar=no,menubar=no,"
+							+ "location=no,directories=no,dependent=yes";
+
+		var popup = window.open("", "SyncDetails", windowParams);
+		
+		if(!popup){ // aggressive popup blocker
+			alert("Please allow popup windows for this domain; can't display sync details window");
+			return;
+		}
+		
+		popup.document.open();
+		popup.document.write(html);
+		popup.document.close();
+		
+		// put the focus on the popup window
+		if(popup.focus){
+			popup.focus();
+		}
+	},
+	
+	_cancel: function(evt){
+		// cancel the button's default behavior
+		evt.preventDefault();
+		evt.stopPropagation();
+		
+		dojox.off.sync.cancel();
+	},
+	
+	_needsBrowserRestart: function(){
+		var browserRestart = dojo.byId("dot-widget-browser-restart");
+		if(browserRestart){
+			dojo.addClass(browserRestart, "dot-needs-browser-restart");
+		}
+		
+		var appName = dojo.byId("dot-widget-browser-restart-app-name");
+		if(appName){
+			appName.innerHTML = "";
+			appName.appendChild(document.createTextNode(this.appName));
+		}
+		
+		var status = dojo.byId("dot-sync-status");
+		if(status){
+			status.style.display = "none";
+		}
+	},
+	
+	_showNeedsOfflineCache: function(){
+		var widgetContainer = dojo.byId("dot-widget-container");
+		if(widgetContainer){
+			dojo.addClass(widgetContainer, "dot-needs-offline-cache");
+		}
+	},
+	
+	_hideNeedsOfflineCache: function(){
+		var widgetContainer = dojo.byId("dot-widget-container");
+		if(widgetContainer){
+			dojo.removeClass(widgetContainer, "dot-needs-offline-cache");
+		}
+	},
+	
+	_initMainEvtHandlers: function(){
+		var detailsButton = dojo.byId("dot-sync-details-button");
+		if(detailsButton){
+			dojo.connect(detailsButton, "onclick", this, this._showDetails);
+		}
+		var cancelButton = dojo.byId("dot-sync-cancel-button");
+		if(cancelButton){
+			dojo.connect(cancelButton, "onclick", this, this._cancel);
+		}
+	},
+	
+	_setOfflineEnabled: function(enabled){
+		var elems = [];
+		elems.push(dojo.byId("dot-sync-status"));
+		
+		for(var i = 0; i < elems.length; i++){
+			if(elems[i]){
+				elems[i].style.visibility = 
+							(enabled ? "visible" : "hidden");
+			}
+		}
+	},
+	
+	_syncFinished: function(){
+		this._updateSyncUI();
+		
+		var checkmark = dojo.byId("dot-success-checkmark");
+		var details = dojo.byId("dot-sync-details");
+		
+		if(dojox.off.sync.successful == true){
+			this._setSyncMessage("Sync Successful");
+			if(checkmark){ checkmark.style.display = "inline"; }
+		}else if(dojox.off.sync.cancelled == true){
+			this._setSyncMessage("Sync Cancelled");
+			
+			if(checkmark){ checkmark.style.display = "none"; }
+		}else{
+			this._setSyncMessage("Sync Error");
+			
+			var messages = dojo.byId("dot-sync-messages");
+			if(messages){
+				dojo.addClass(messages, "dot-sync-error");
+			}
+			
+			if(checkmark){ checkmark.style.display = "none"; }
+		}
+		
+		if(dojox.off.sync.details.length && details){
+			details.style.display = "inline";
+		}
+	},
+	
+	_onFrameworkEvent: function(type, saveData){
+		if(type == "save"){
+			if(saveData.status == dojox.storage.FAILED && !saveData.isCoreSave){
+				alert("Please increase the amount of local storage available "
+						+ "to this application");
+				if(dojox.storage.hasSettingsUI()){
+					dojox.storage.showSettingsUI();
+				}		
+			
+				// FIXME: Be able to know if storage size has changed
+				// due to user configuration
+			}
+		}else if(type == "coreOperationFailed"){
+			
+		
+			if(!this._userInformed){
+				alert("This application will not work if Google Gears is not allowed to run");
+				this._userInformed = true;
+			}
+		}else if(type == "offlineCacheInstalled"){
+			// clear out the 'needs offline cache' info
+			this._hideNeedsOfflineCache();
+		
+			// check to see if we need a browser restart
+			// to be able to use this web app offline
+			if(dojox.off.hasOfflineCache == true
+				&& dojox.off.browserRestart == true){
+				this._needsBrowserRestart();
+				return;
+			}else{
+				var browserRestart = dojo.byId("dot-widget-browser-restart");
+				if(browserRestart){
+					browserRestart.style.display = "none";
+				}
+			}
+		
+			// update our sync UI
+			this._updateSyncUI();
+		
+			// register our event listeners for our main buttons
+			this._initMainEvtHandlers();
+		
+			// if offline is disabled, disable everything
+			this._setOfflineEnabled(dojox.off.enabled);
+		
+			// try to go online
+			this._testNet();
+		}
+	},
+	
+	_onSync: function(type){
+		//
+		switch(type){
+			case "start": 
+				this._updateSyncUI();
+				break;
+				
+			case "refreshFiles":
+				this._setSyncMessage("Downloading UI...");
+				break;
+				
+			case "upload":
+				this._setSyncMessage("Uploading new data...");
+				break;
+				
+			case "download":
+				this._setSyncMessage("Downloading new data...");
+				break;
+				
+			case "finished":
+				this._syncFinished();
+				break;
+				
+			case "cancel":
+				this._setSyncMessage("Canceling Sync...");
+				break;
+				
+			default:
+				dojo.warn("Programming error: "
+							+ "Unknown sync type in dojox.off.ui: " + type);
+				break;
+		}
+	},
+	
+	_onNetwork: function(type){
+		// summary:
+		//	Called when we go on- or off-line
+		// description:
+		//	When we go online or offline, this method is called to update
+		//	our UI. Default behavior is to update the Offline
+		//	Widget UI and to attempt a synchronization.
+		// type: String
+		//	"online" if we just moved online, and "offline" if we just
+		//	moved offline.
+		
+		if(!this._initialized){ return; }
+		
+		// update UI
+		this._updateNetIndicator();
+		
+		if(type == "offline"){
+			this._setSyncMessage("You are working offline");
+		
+			// clear old details
+			var details = dojo.byId("dot-sync-details");
+			if(details){ details.style.display = "none"; }
+			
+			// if we fell offline during a sync, hide
+			// the sync info
+			this._updateSyncUI();
+		}else{ // online
+			// synchronize, but pause for a few seconds
+			// so that the user can orient themselves
+			if(dojox.off.sync.autoSync){
+				if(dojo.isAIR){
+					window.setTimeout(function(){dojox.off.sync.synchronize();}, 1000);
+				}else{
+					window.setTimeout(dojox._scopeName + ".off.sync.synchronize()", 1000);
+				}
+			}
+		}
+	}
+});
+
+// register ourselves for low-level framework events
+dojo.connect(dojox.off, "onFrameworkEvent", dojox.off.ui, "_onFrameworkEvent");
+
+// start our magic when the Dojo Offline framework is ready to go
+dojo.connect(dojox.off, "onLoad", dojox.off.ui, dojox.off.ui._initialize);
+
+}
+
+if(!dojo._hasResource["dojox.off.offline"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.off.offline"] = true;
+dojo.provide("dojox.off.offline");
+
+
+
+
+
+
+
+}
+
diff --git a/dojox/off/resources/checkmark.png b/dojox/off/resources/checkmark.png
new file mode 100644
index 0000000..a0ffbb1
Binary files /dev/null and b/dojox/off/resources/checkmark.png differ
diff --git a/dojox/off/resources/greenball.png b/dojox/off/resources/greenball.png
new file mode 100644
index 0000000..520b6a6
Binary files /dev/null and b/dojox/off/resources/greenball.png differ
diff --git a/dojox/off/resources/learnhow.html b/dojox/off/resources/learnhow.html
new file mode 100644
index 0000000..2833fcc
--- /dev/null
+++ b/dojox/off/resources/learnhow.html
@@ -0,0 +1,43 @@
+<html>
+	<head>
+		<link rel="stylesheet" type="text/css" href="offline-widget.css"></link>
+		
+		<script type="text/javascript" src="learnhow.js"></script>
+	</head>
+	
+	<body id="dot-learn-how-body">
+		<div id="dot-learn-how-contents">
+			<h1><b>Want to use <span id="dot-learn-how-app-name">Application</span> offline?</b></h1> 
+			
+			<p id="dot-toolkit-info">It's simple with Dojo Offline! Dojo Offline is a free open source utility that makes it easy 
+			for this web application to work, even if you're offline. Now you can 
+			access your data even when away from the network!</p>
+			
+			<p>Dojo Offline is an open source project brought to you by 
+				<a href="http://dojotoolkit.org">Dojo</a>, <a href="http://sitepen.com">SitePen</a>, 
+				and <a href="http://codinginparadise.org">Brad Neuberg</a>. It incorporates
+				technologies created by <a href="http://google.com">Google</a>.</p>
+				
+			<h2>To get started:</h2>
+			
+			<ol>
+				<li id="dot-download-step">
+					<a target="_new" href="http://gears.google.com">Download Gears</a>, a small, open source utility created by Google that allows this web site 
+					to work offline. This tool is safe and secure for your machine, and only takes
+					a few seconds to download.
+				</li>
+				<li id="dot-install-step">
+					Once downloaded, run the installer. Restart your web browser when finished installing.
+				</li>
+				<li id="dot-drag-link-step">
+					To access this website even when offline, drag the following link to your 
+					desktop or your browser's link toolbar above: <a id="dot-learn-how-run-link" href="#">Run Application</a>.
+				</li>
+				<li id="dot-run-link-step">
+					Double-click the link on your desktop to start this web application, even 
+					if offline.
+				</li>
+			</ol>
+		</div>
+	</body>
+</html>
\ No newline at end of file
diff --git a/dojox/off/resources/learnhow.js b/dojox/off/resources/learnhow.js
new file mode 100644
index 0000000..e81d99c
--- /dev/null
+++ b/dojox/off/resources/learnhow.js
@@ -0,0 +1,39 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+window.onload=function(){
+var _1=window.location.href;
+var _2=_1.match(/appName=([a-z0-9 \%]*)/i);
+var _3="Application";
+if(_2&&_2.length>0){
+_3=decodeURIComponent(_2[1]);
+}
+var _4=document.getElementById("dot-learn-how-app-name");
+_4.innerHTML="";
+_4.appendChild(document.createTextNode(_3));
+_2=_1.match(/hasOfflineCache=(true|false)/);
+var _5=false;
+if(_2&&_2.length>0){
+_5=_2[1];
+_5=(_5=="true")?true:false;
+}
+if(_5==true){
+var _6=document.getElementById("dot-download-step");
+var _7=document.getElementById("dot-install-step");
+_6.parentNode.removeChild(_6);
+_7.parentNode.removeChild(_7);
+}
+_2=_1.match(/runLink=([^\&]*)\&runLinkText=([^\&]*)/);
+if(_2&&_2.length>0){
+var _8=decodeURIComponent(_2[1]);
+var _9=document.getElementById("dot-learn-how-run-link");
+_9.setAttribute("href",_8);
+var _a=decodeURIComponent(_2[2]);
+_9.innerHTML="";
+_9.appendChild(document.createTextNode(_a));
+}
+};
diff --git a/dojox/off/resources/offline-widget.css b/dojox/off/resources/offline-widget.css
new file mode 100644
index 0000000..3d095e9
--- /dev/null
+++ b/dojox/off/resources/offline-widget.css
@@ -0,0 +1,88 @@
+
+#dot-widget-container{
+	
+	width: 13em;
+	height: auto;
+	border: 2px solid #CDDDE9; 
+	position: relative;
+	visibility: visible !important;
+}
+#dot-widget-title-bar{
+	background-color: #CDDDE9; 
+	padding-top: 0.2em;
+	padding-bottom: 0.2em;
+}
+#dot-widget-network-indicator{
+	height: 8px;
+	width: 8px;
+	padding-left: 0.3em;
+}
+#dot-widget-title-text{
+	vertical-align: middle;
+	font-weight: bold;
+	font-size: 14pt;
+	padding-left: 2px;
+}
+#dot-widget-contents{
+	padding: 8px 5px 8px 5px;
+}
+#dot-widget-learn-how{
+	font-size: 11pt;
+}
+#dot-sync-cancel,
+#dot-sync-status{
+	font-size: 11pt;
+}
+#dot-success-checkmark{
+	display: none;
+}
+#dot-roller{
+	display: none;
+	padding-right: 4px;
+}
+.dot-sync-error{
+	color: red;
+}
+#dot-sync-details{
+	display: none;
+	padding-left: 0.2em;
+}
+#dot-sync-status{
+	height: 2em;
+	margin-top: 0.8em;
+	margin-bottom: 0.8em;
+}
+.dot-needs-offline-cache #dot-widget-learn-how,
+.dot-needs-browser-restart{
+	text-align: center;
+	line-height: 1.2;
+	font-size: 16pt !important;
+}
+.dot-needs-offline-cache #dot-sync-status,
+.dot-needs-offline-cache #dot-widget-browser-restart{
+	display: none;
+}
+.dot-needs-browser-restart{
+    font-size: 14pt !important;
+    padding-bottom: 1em;
+    padding-top: 1em;
+}
+#dot-learn-how-body{
+	padding: 3em;
+	background-color: #CDDDE9; 
+}
+#dot-learn-how-contents{
+	border: 1px solid black; 
+	background-color: white; 
+	padding: 0.4em 0.6em 0.4em 0.6em;
+	font-size: 16pt;
+}
+#dot-learn-how-contents h1{
+	font-size: 24pt;
+}
+#dot-learn-how-contents h2{
+	font-size: 18pt;
+}
+#dot-learn-how-contents li{
+	padding-bottom: 0.6em;
+}
diff --git a/dojox/off/resources/offline-widget.html b/dojox/off/resources/offline-widget.html
new file mode 100644
index 0000000..5791644
--- /dev/null
+++ b/dojox/off/resources/offline-widget.html
@@ -0,0 +1,40 @@
+<!-- 
+	Note: The elements in this UI can be broken apart
+	and spread around your page, as long as you keep the
+	IDs intact. Elements can also be dropped without
+	Dojo Offline's default UI breaking.
+-->
+
+<div id="dot-widget-container" style="visibility: hidden;">
+	<div id="dot-widget-title-bar">
+		<span id="dot-widget-network-indicator">
+			<img id="dot-widget-network-indicator-online" />
+			<img id="dot-widget-network-indicator-offline" />
+		</span>
+		<span id="dot-widget-title-text"></span>
+	</div>
+	
+	<div id="dot-widget-contents">
+		<div id="dot-widget-browser-restart">
+			Please restart your browser to 
+			use <span id="dot-widget-browser-restart-app-name"></span> Offline
+		</div>
+		
+		<div id="dot-sync-status">
+			<img id="dot-roller" />
+			<img id="dot-success-checkmark" />
+			<span id="dot-sync-messages"></span>
+			<span id="dot-sync-details">
+				(<a id="dot-sync-details-button" href="#">details</a>)
+			</span>
+			<span id="dot-sync-cancel">
+				(<a id="dot-sync-cancel-button" href="#">cancel</a>)
+			</span>
+		</div>
+		
+		<div id="dot-widget-learn-how">
+			<a id="dot-widget-learn-how-link" target="_blank" href="#">Learn How</a> 
+			to use <span id="dot-widget-learn-how-app-name"></span> Offline!
+		</div>
+	</div>
+</div>
\ No newline at end of file
diff --git a/dojox/off/resources/redball.png b/dojox/off/resources/redball.png
new file mode 100644
index 0000000..cc224c3
Binary files /dev/null and b/dojox/off/resources/redball.png differ
diff --git a/dojox/off/resources/roller.gif b/dojox/off/resources/roller.gif
new file mode 100644
index 0000000..24a3a24
Binary files /dev/null and b/dojox/off/resources/roller.gif differ
diff --git a/dojox/off/sync.js b/dojox/off/sync.js
new file mode 100644
index 0000000..21d3901
--- /dev/null
+++ b/dojox/off/sync.js
@@ -0,0 +1,209 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.off.sync"]){
+dojo._hasResource["dojox.off.sync"]=true;
+dojo.provide("dojox.off.sync");
+dojo.require("dojox.storage.GearsStorageProvider");
+dojo.require("dojox.off._common");
+dojo.require("dojox.off.files");
+dojo.mixin(dojox.off.sync,{isSyncing:false,cancelled:false,successful:true,details:[],error:false,actions:null,autoSync:true,onSync:function(_1){
+},synchronize:function(){
+if(this.isSyncing||dojox.off.goingOnline||(!dojox.off.isOnline)){
+return;
+}
+this.isSyncing=true;
+this.successful=false;
+this.details=[];
+this.cancelled=false;
+this.start();
+},cancel:function(){
+if(!this.isSyncing){
+return;
+}
+this.cancelled=true;
+if(dojox.off.files.refreshing){
+dojox.off.files.abortRefresh();
+}
+this.onSync("cancel");
+},finishedDownloading:function(_2,_3){
+if(typeof _2=="undefined"){
+_2=true;
+}
+if(!_2){
+this.successful=false;
+this.details.push(_3);
+this.error=true;
+}
+this.finished();
+},start:function(){
+if(this.cancelled){
+this.finished();
+return;
+}
+this.onSync("start");
+this.refreshFiles();
+},refreshFiles:function(){
+if(this.cancelled){
+this.finished();
+return;
+}
+this.onSync("refreshFiles");
+dojox.off.files.refresh(dojo.hitch(this,function(_4,_5){
+if(_4){
+this.error=true;
+this.successful=false;
+for(var i=0;i<_5.length;i++){
+this.details.push(_5[i]);
+}
+}
+this.upload();
+}));
+},upload:function(){
+if(this.cancelled){
+this.finished();
+return;
+}
+this.onSync("upload");
+dojo.connect(this.actions,"onReplayFinished",this,this.download);
+this.actions.replay();
+},download:function(){
+if(this.cancelled){
+this.finished();
+return;
+}
+this.onSync("download");
+},finished:function(){
+this.isSyncing=false;
+this.successful=(!this.cancelled&&!this.error);
+this.onSync("finished");
+},_save:function(_7){
+this.actions._save(function(){
+_7();
+});
+},_load:function(_8){
+this.actions._load(function(){
+_8();
+});
+}});
+dojo.declare("dojox.off.sync.ActionLog",null,{entries:[],reasonHalted:null,isReplaying:false,autoSave:true,add:function(_9){
+if(this.isReplaying){
+throw "Programming error: you can not call "+"dojox.off.sync.actions.add() while "+"we are replaying an action log";
+}
+this.entries.push(_9);
+if(this.autoSave){
+this._save();
+}
+},onReplay:function(_a,_b){
+},length:function(){
+return this.entries.length;
+},haltReplay:function(_c){
+if(!this.isReplaying){
+return;
+}
+if(_c){
+this.reasonHalted=_c.toString();
+}
+if(this.autoSave){
+var _d=this;
+this._save(function(){
+_d.isReplaying=false;
+_d.onReplayFinished();
+});
+}else{
+this.isReplaying=false;
+this.onReplayFinished();
+}
+},continueReplay:function(){
+if(!this.isReplaying){
+return;
+}
+this.entries.shift();
+if(!this.entries.length){
+if(this.autoSave){
+var _e=this;
+this._save(function(){
+_e.isReplaying=false;
+_e.onReplayFinished();
+});
+return;
+}else{
+this.isReplaying=false;
+this.onReplayFinished();
+return;
+}
+}
+var _f=this.entries[0];
+this.onReplay(_f,this);
+},clear:function(){
+if(this.isReplaying){
+return;
+}
+this.entries=[];
+if(this.autoSave){
+this._save();
+}
+},replay:function(){
+if(this.isReplaying){
+return;
+}
+this.reasonHalted=null;
+if(!this.entries.length){
+this.onReplayFinished();
+return;
+}
+this.isReplaying=true;
+var _10=this.entries[0];
+this.onReplay(_10,this);
+},onReplayFinished:function(){
+},toString:function(){
+var _11="";
+_11+="[";
+for(var i=0;i<this.entries.length;i++){
+_11+="{";
+for(var j in this.entries[i]){
+_11+=j+": \""+this.entries[i][j]+"\"";
+_11+=", ";
+}
+_11+="}, ";
+}
+_11+="]";
+return _11;
+},_save:function(_14){
+if(!_14){
+_14=function(){
+};
+}
+try{
+var _15=this;
+var _16=function(_17,key,_19){
+if(_17==dojox.storage.FAILED){
+dojox.off.onFrameworkEvent("save",{status:dojox.storage.FAILED,isCoreSave:true,key:key,value:_19,namespace:dojox.off.STORAGE_NAMESPACE});
+_14();
+}else{
+if(_17==dojox.storage.SUCCESS){
+_14();
+}
+}
+};
+dojox.storage.put("actionlog",this.entries,_16,dojox.off.STORAGE_NAMESPACE);
+}
+catch(exp){
+
+dojox.off.onFrameworkEvent("save",{status:dojox.storage.FAILED,isCoreSave:true,key:"actionlog",value:this.entries,namespace:dojox.off.STORAGE_NAMESPACE});
+_14();
+}
+},_load:function(_1a){
+var _1b=dojox.storage.get("actionlog",dojox.off.STORAGE_NAMESPACE);
+if(!_1b){
+_1b=[];
+}
+this.entries=_1b;
+_1a();
+}});
+dojox.off.sync.actions=new dojox.off.sync.ActionLog();
+}
diff --git a/dojox/off/ui.js b/dojox/off/ui.js
new file mode 100644
index 0000000..baf19df
--- /dev/null
+++ b/dojox/off/ui.js
@@ -0,0 +1,358 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.off.ui"]){
+dojo._hasResource["dojox.off.ui"]=true;
+dojo.provide("dojox.off.ui");
+dojo.require("dojox.storage.Provider");
+dojo.require("dojox.storage.manager");
+dojo.require("dojox.storage.GearsStorageProvider");
+dojo.mixin(dojox.off.ui,{appName:"setme",autoEmbed:true,autoEmbedID:"dot-widget",runLink:window.location.href,runLinkTitle:"Run Application",learnHowPath:dojo.moduleUrl("dojox","off/resources/learnhow.html"),customLearnHowPath:false,htmlTemplatePath:dojo.moduleUrl("dojox","off/resources/offline-widget.html").uri,cssTemplatePath:dojo.moduleUrl("dojox","off/resources/offline-widget.css").uri,onlineImagePath:dojo.moduleUrl("dojox","off/resources/greenball.png").uri,offlineImagePath:dojo.mod [...]
+},_initialize:function(){
+if(this._validateAppName(this.appName)==false){
+alert("You must set dojox.off.ui.appName; it can only contain "+"letters, numbers, and spaces; right now it "+"is incorrectly set to '"+dojox.off.ui.appName+"'");
+dojox.off.enabled=false;
+return;
+}
+this.runLinkText="Run "+this.appName;
+dojo.connect(dojox.off,"onNetwork",this,"_onNetwork");
+dojo.connect(dojox.off.sync,"onSync",this,"_onSync");
+dojox.off.files.cache([this.htmlTemplatePath,this.cssTemplatePath,this.onlineImagePath,this.offlineImagePath,this.rollerImagePath,this.checkmarkImagePath]);
+if(this.autoEmbed){
+this._doAutoEmbed();
+}
+},_doAutoEmbed:function(){
+dojo.xhrGet({url:this.htmlTemplatePath,handleAs:"text",error:function(_1){
+dojox.off.enabled=false;
+_1=_1.message||_1;
+alert("Error loading the Dojo Offline Widget from "+this.htmlTemplatePath+": "+_1);
+},load:dojo.hitch(this,this._templateLoaded)});
+},_templateLoaded:function(_2){
+var _3=dojo.byId(this.autoEmbedID);
+if(_3){
+_3.innerHTML=_2;
+}
+this._initImages();
+this._updateNetIndicator();
+this._initLearnHow();
+this._initialized=true;
+if(!dojox.off.hasOfflineCache){
+this._showNeedsOfflineCache();
+return;
+}
+if(dojox.off.hasOfflineCache&&dojox.off.browserRestart){
+this._needsBrowserRestart();
+return;
+}else{
+var _4=dojo.byId("dot-widget-browser-restart");
+if(_4){
+_4.style.display="none";
+}
+}
+this._updateSyncUI();
+this._initMainEvtHandlers();
+this._setOfflineEnabled(dojox.off.enabled);
+this._onNetwork(dojox.off.isOnline?"online":"offline");
+this._testNet();
+},_testNet:function(){
+dojox.off.goOnline(dojo.hitch(this,function(_5){
+this._onNetwork(_5?"online":"offline");
+this.onLoad();
+}));
+},_updateNetIndicator:function(){
+var _6=dojo.byId("dot-widget-network-indicator-online");
+var _7=dojo.byId("dot-widget-network-indicator-offline");
+var _8=dojo.byId("dot-widget-title-text");
+if(_6&&_7){
+if(dojox.off.isOnline==true){
+_6.style.display="inline";
+_7.style.display="none";
+}else{
+_6.style.display="none";
+_7.style.display="inline";
+}
+}
+if(_8){
+if(dojox.off.isOnline){
+_8.innerHTML="Online";
+}else{
+_8.innerHTML="Offline";
+}
+}
+},_initLearnHow:function(){
+var _9=dojo.byId("dot-widget-learn-how-link");
+if(!_9){
+return;
+}
+if(!this.customLearnHowPath){
+var _a=dojo.config.baseRelativePath;
+this.learnHowPath+="?appName="+encodeURIComponent(this.appName)+"&hasOfflineCache="+dojox.off.hasOfflineCache+"&runLink="+encodeURIComponent(this.runLink)+"&runLinkText="+encodeURIComponent(this.runLinkText)+"&baseRelativePath="+encodeURIComponent(_a);
+dojox.off.files.cache(this.learnHowJSPath);
+dojox.off.files.cache(this.learnHowPath);
+}
+_9.setAttribute("href",this.learnHowPath);
+var _b=dojo.byId("dot-widget-learn-how-app-name");
+if(!_b){
+return;
+}
+_b.innerHTML="";
+_b.appendChild(document.createTextNode(this.appName));
+},_validateAppName:function(_c){
+if(!_c){
+return false;
+}
+return (/^[a-z0-9 ]*$/i.test(_c));
+},_updateSyncUI:function(){
+var _d=dojo.byId("dot-roller");
+var _e=dojo.byId("dot-success-checkmark");
+var _f=dojo.byId("dot-sync-messages");
+var _10=dojo.byId("dot-sync-details");
+var _11=dojo.byId("dot-sync-cancel");
+if(dojox.off.sync.isSyncing){
+this._clearSyncMessage();
+if(_d){
+_d.style.display="inline";
+}
+if(_e){
+_e.style.display="none";
+}
+if(_f){
+dojo.removeClass(_f,"dot-sync-error");
+}
+if(_10){
+_10.style.display="none";
+}
+if(_11){
+_11.style.display="inline";
+}
+}else{
+if(_d){
+_d.style.display="none";
+}
+if(_11){
+_11.style.display="none";
+}
+if(_f){
+dojo.removeClass(_f,"dot-sync-error");
+}
+}
+},_setSyncMessage:function(_12){
+var _13=dojo.byId("dot-sync-messages");
+if(_13){
+while(_13.firstChild){
+_13.removeChild(_13.firstChild);
+}
+_13.appendChild(document.createTextNode(_12));
+}
+},_clearSyncMessage:function(){
+this._setSyncMessage("");
+},_initImages:function(){
+var _14=dojo.byId("dot-widget-network-indicator-online");
+if(_14){
+_14.setAttribute("src",this.onlineImagePath);
+}
+var _15=dojo.byId("dot-widget-network-indicator-offline");
+if(_15){
+_15.setAttribute("src",this.offlineImagePath);
+}
+var _16=dojo.byId("dot-roller");
+if(_16){
+_16.setAttribute("src",this.rollerImagePath);
+}
+var _17=dojo.byId("dot-success-checkmark");
+if(_17){
+_17.setAttribute("src",this.checkmarkImagePath);
+}
+},_showDetails:function(evt){
+evt.preventDefault();
+evt.stopPropagation();
+if(!dojox.off.sync.details.length){
+return;
+}
+var _19="";
+_19+="<html><head><title>Sync Details</title><head><body>";
+_19+="<h1>Sync Details</h1>\n";
+_19+="<ul>\n";
+for(var i=0;i<dojox.off.sync.details.length;i++){
+_19+="<li>";
+_19+=dojox.off.sync.details[i];
+_19+="</li>";
+}
+_19+="</ul>\n";
+_19+="<a href='javascript:window.close()' "+"style='text-align: right; padding-right: 2em;'>"+"Close Window"+"</a>\n";
+_19+="</body></html>";
+var _1b="height=400,width=600,resizable=true,"+"scrollbars=true,toolbar=no,menubar=no,"+"location=no,directories=no,dependent=yes";
+var _1c=window.open("","SyncDetails",_1b);
+if(!_1c){
+alert("Please allow popup windows for this domain; can't display sync details window");
+return;
+}
+_1c.document.open();
+_1c.document.write(_19);
+_1c.document.close();
+if(_1c.focus){
+_1c.focus();
+}
+},_cancel:function(evt){
+evt.preventDefault();
+evt.stopPropagation();
+dojox.off.sync.cancel();
+},_needsBrowserRestart:function(){
+var _1e=dojo.byId("dot-widget-browser-restart");
+if(_1e){
+dojo.addClass(_1e,"dot-needs-browser-restart");
+}
+var _1f=dojo.byId("dot-widget-browser-restart-app-name");
+if(_1f){
+_1f.innerHTML="";
+_1f.appendChild(document.createTextNode(this.appName));
+}
+var _20=dojo.byId("dot-sync-status");
+if(_20){
+_20.style.display="none";
+}
+},_showNeedsOfflineCache:function(){
+var _21=dojo.byId("dot-widget-container");
+if(_21){
+dojo.addClass(_21,"dot-needs-offline-cache");
+}
+},_hideNeedsOfflineCache:function(){
+var _22=dojo.byId("dot-widget-container");
+if(_22){
+dojo.removeClass(_22,"dot-needs-offline-cache");
+}
+},_initMainEvtHandlers:function(){
+var _23=dojo.byId("dot-sync-details-button");
+if(_23){
+dojo.connect(_23,"onclick",this,this._showDetails);
+}
+var _24=dojo.byId("dot-sync-cancel-button");
+if(_24){
+dojo.connect(_24,"onclick",this,this._cancel);
+}
+},_setOfflineEnabled:function(_25){
+var _26=[];
+_26.push(dojo.byId("dot-sync-status"));
+for(var i=0;i<_26.length;i++){
+if(_26[i]){
+_26[i].style.visibility=(_25?"visible":"hidden");
+}
+}
+},_syncFinished:function(){
+this._updateSyncUI();
+var _28=dojo.byId("dot-success-checkmark");
+var _29=dojo.byId("dot-sync-details");
+if(dojox.off.sync.successful==true){
+this._setSyncMessage("Sync Successful");
+if(_28){
+_28.style.display="inline";
+}
+}else{
+if(dojox.off.sync.cancelled==true){
+this._setSyncMessage("Sync Cancelled");
+if(_28){
+_28.style.display="none";
+}
+}else{
+this._setSyncMessage("Sync Error");
+var _2a=dojo.byId("dot-sync-messages");
+if(_2a){
+dojo.addClass(_2a,"dot-sync-error");
+}
+if(_28){
+_28.style.display="none";
+}
+}
+}
+if(dojox.off.sync.details.length&&_29){
+_29.style.display="inline";
+}
+},_onFrameworkEvent:function(_2b,_2c){
+if(_2b=="save"){
+if(_2c.status==dojox.storage.FAILED&&!_2c.isCoreSave){
+alert("Please increase the amount of local storage available "+"to this application");
+if(dojox.storage.hasSettingsUI()){
+dojox.storage.showSettingsUI();
+}
+}
+}else{
+if(_2b=="coreOperationFailed"){
+
+if(!this._userInformed){
+alert("This application will not work if Google Gears is not allowed to run");
+this._userInformed=true;
+}
+}else{
+if(_2b=="offlineCacheInstalled"){
+this._hideNeedsOfflineCache();
+if(dojox.off.hasOfflineCache==true&&dojox.off.browserRestart==true){
+this._needsBrowserRestart();
+return;
+}else{
+var _2d=dojo.byId("dot-widget-browser-restart");
+if(_2d){
+_2d.style.display="none";
+}
+}
+this._updateSyncUI();
+this._initMainEvtHandlers();
+this._setOfflineEnabled(dojox.off.enabled);
+this._testNet();
+}
+}
+}
+},_onSync:function(_2e){
+switch(_2e){
+case "start":
+this._updateSyncUI();
+break;
+case "refreshFiles":
+this._setSyncMessage("Downloading UI...");
+break;
+case "upload":
+this._setSyncMessage("Uploading new data...");
+break;
+case "download":
+this._setSyncMessage("Downloading new data...");
+break;
+case "finished":
+this._syncFinished();
+break;
+case "cancel":
+this._setSyncMessage("Canceling Sync...");
+break;
+default:
+dojo.warn("Programming error: "+"Unknown sync type in dojox.off.ui: "+_2e);
+break;
+}
+},_onNetwork:function(_2f){
+if(!this._initialized){
+return;
+}
+this._updateNetIndicator();
+if(_2f=="offline"){
+this._setSyncMessage("You are working offline");
+var _30=dojo.byId("dot-sync-details");
+if(_30){
+_30.style.display="none";
+}
+this._updateSyncUI();
+}else{
+if(dojox.off.sync.autoSync){
+if(dojo.isAIR){
+window.setTimeout(function(){
+dojox.off.sync.synchronize();
+},1000);
+}else{
+window.setTimeout(dojox._scopeName+".off.sync.synchronize()",1000);
+}
+}
+}
+}});
+dojo.connect(dojox.off,"onFrameworkEvent",dojox.off.ui,"_onFrameworkEvent");
+dojo.connect(dojox.off,"onLoad",dojox.off.ui,dojox.off.ui._initialize);
+}
diff --git a/dojox/resources/README.template b/dojox/resources/README.template
new file mode 100644
index 0000000..81dd925
--- /dev/null
+++ b/dojox/resources/README.template
@@ -0,0 +1,42 @@
+-------------------------------------------------------------------------------
+Project Name
+-------------------------------------------------------------------------------
+Version X.XXX
+Release date: MM/DD/YYYY
+-------------------------------------------------------------------------------
+Project state:
+[Object1]:	experimental | alpha | beta | production
+[Object2]:	experimental | alpha | beta | production
+-------------------------------------------------------------------------------
+[   ]	l18n support?
+[   ]	a11y support?
+-------------------------------------------------------------------------------
+Credits
+[Object1]:	Author one (author contact info)
+[Object2]:	Author two (author contact info)
+-------------------------------------------------------------------------------
+Project description
+
+Describe the point of the project here.
+-------------------------------------------------------------------------------
+Dependencies:
+
+List any dependencies here.
+-------------------------------------------------------------------------------
+Documentation
+
+Any notes about documentation--such as a link to a page in the Book of Dojo,
+documentation state, etc.--should go here.
+-------------------------------------------------------------------------------
+Installation instructions
+
+Use this to explain in detail what a person needs to do in order to use this
+project.  Include URLs for grabbing source, URLs for any dependencies, etc.
+Also be sure to include any additional information, such as where to place
+CSS files, images, other media, etc.  The goal is that someone reading this
+file can follow your instructions and be using this project within minutes.
+-------------------------------------------------------------------------------
+Additional Notes
+
+Anything else you think is of interest (for example, object hierarchy) should
+be placed here.
diff --git a/dojox/resources/_modules.js b/dojox/resources/_modules.js
new file mode 100644
index 0000000..0b276e5
--- /dev/null
+++ b/dojox/resources/_modules.js
@@ -0,0 +1,7 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
diff --git a/dojox/resources/explore.php b/dojox/resources/explore.php
new file mode 100644
index 0000000..0644832
--- /dev/null
+++ b/dojox/resources/explore.php
@@ -0,0 +1,149 @@
+<?php // IF you don't have PHP5 installed, you can't use this index! ?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+
+	<link rel="stylesheet" href="../../dijit/tests/css/dijitTests.css">
+	<link rel="stylesheet" href="../../dijit/themes/tundra/tundra.css">
+	<link rel="stylesheet" href="../../dojox/widget/Dialog/Dialog.css">
+	<style type="text/css">
+		.innard {
+			padding:12px;
+			margin-top:0;
+		}
+	</style>
+	<title>Dojo Toolkit - DojoX Demos and Tests by Project</title>
+
+	<script src="../../dojo/dojo.js"></script>
+	<script type="text/javascript">
+		dojo.require('dojox.widget.Dialog');
+		dojo.require("dojo.fx.easing");
+		dojo.addOnLoad(function(){
+			var dialog = new dojox.widget.Dialog({ title: "About", viewportPadding:100, fixedSize:true });
+			dialog.startup();
+			dojo.query("span.projectname + a")
+				.connect("onclick",function(e){
+					e.preventDefault();
+					dojo.xhrGet({
+						url: e.target.href,
+						load: function(data){
+							var content = data.replace(/\</g,"<");
+							dialog.show();
+							dialog.setContent("<pre class='innard'>" + content + "</pre>");
+						}
+					})
+				})
+			;
+		});
+	</script>
+
+</head>
+<body>
+
+	<h1 class="testTitle">DojoX test files overview</h1>
+	
+	<table id="testMatrix">
+		<thead>
+			<tr class="top"><th rowspan="2">Test</th><th colspan="4">Tundra</th><th colspan="4">Nihilo</th><th colspan="4">Soria</th></tr>
+			<tr class="tests"><th>Normal</th><th>a11y</th><th>rtl</th><th>a11y + rtl<th>Normal</th><th>a11y</th><th>rtl</th><th>a11y + rtl<th>Normal</th><th>a11y</th><th>rtl</th><th>a11y + rtl</tr>
+		</thead>
+		<tbody><?php
+
+			foreach(getprojects() as $project){
+				$note = "";
+				if($project['readme']){
+					$note = "<a class='readmeLink' href='".$project['readme']."'>about</a>"; 
+				}
+				if($project['tests'] || $project['demos']){
+					print "<tr class='spacer'><td colspan='13'><span class='projectname'>dojox.". $project['name'] . "</span> ".$note."</td></tr>";
+
+					if($project['tests']){
+						printLinks($project['tests']);					
+					}
+					if($project['demos']){
+						printLinks($project['demos']);
+					}
+
+				}
+				
+			}
+		//	printLinks("./tree","Dijit Tree Tests");
+			
+		?>
+		</tbody>
+	</table>
+
+	<p>* note: All themes and modes included for completeness. Some projects don't even use themes. The "basic" link
+		is the direct link to the file with no enhancements. The test file must include _testCommon from dijit to
+		include theme / rtl / a11y testing capabilities.</p>
+</body>
+</html>
+<?php
+
+function getprojects(){
+	$projects = array();
+	$path = "../../dojox";
+	$handle = opendir($path);
+	while(false !== ($file = readdir($handle))){
+		$README = "";
+		$full = $path."/".$file;
+		if(is_dir($full)){
+			if(file_exists($full."/README")){
+				$README = $full."/README";
+			}
+			$tests = false; $demos = false;
+			if(is_dir($full."/tests")){
+				$tests = $full."/tests";
+			}
+			if(is_dir($full."/demos")){
+				$demos = $full."/demos";
+			}
+			$projects[] = array(
+				"name" => $file,
+				"tests" => $tests,
+				"demos" => $demos,
+				"readme" => $README
+			);
+		}
+	}
+	return $projects;
+}
+
+function printLinks($path){
+	$handle = opendir($path);
+	$i = 0;
+
+	while(false !== ($file = readdir($handle))){
+		if(preg_match("/([a-zA-Z])(.*)\.html/", $file, $matches)){
+			$base = $matches[0];
+			$link = $path."/".$matches[0];
+			print 
+			"<tr class='testRow ". (++$i % 2 ==0 ? "alt" : "")   ."'>" .
+
+				"<td class='label'>" . $base . "</td>" .
+
+			    // standard / tundra:
+				"<td><a href='".$link."'>basic</a></td>" .
+				"<td><a href='".$link."?a11y=true'>a11y</a></td>" .
+				"<td><a href='".$link."?dir=rtl'>rtl</a></td>" .
+				"<td><a href='".$link."?dir=rtl&a11y=true'>both</a></td>" .
+				
+				// nihilo
+				"<td><a href='".$link."?theme=nihilo'>nihilo</a></td>" .
+				"<td><a href='".$link."?theme=nihilo&a11y=true'>a11y</a></td>" .
+				"<td><a href='".$link."?theme=nihilo&dir=rtl'>rtl</a></td>" .
+				"<td><a href='".$link."?theme=nihilo&dir=rtl&a11y=true'>combo</a></td>" .
+
+				// soria
+				"<td><a href='".$link."?theme=soria'>soria</a></td>" .
+				"<td><a href='".$link."?theme=soria&a11y=true'>a11y</a></td>" .
+				"<td><a href='".$link."?theme=soria&dir=rtl'>rtl</a></td>" .
+				"<td><a href='".$link."?theme=soria&dir=rtl&a11y=true'>combo</a></td>" .
+									
+			 "</tr>";
+		}
+	}
+}
+
+?>
diff --git a/dojox/robot/README b/dojox/robot/README
new file mode 100644
index 0000000..46ad353
--- /dev/null
+++ b/dojox/robot/README
@@ -0,0 +1,59 @@
+-------------------------------------------------------------------------------
+dojox.robot.recorder
+-------------------------------------------------------------------------------
+Version 0.1
+Release date: 2008-07-30
+-------------------------------------------------------------------------------
+Project state: experimental
+-------------------------------------------------------------------------------
+Project authors
+	Mark Hays
+-------------------------------------------------------------------------------
+Project description
+
+Writing automated test cases takes time, and DOH is no exception. You have to
+look up element ids, invent dojo.queries for elements with no id,
+figure out exactly how many pixels to move the mouse . . . the list goes on.
+
+This recorder module enables DOH test case writers to create complete DOH test
+scripts directly from their actions and input on a Web page. Simply drop the
+generated code into your test page, set a pass condition, and the test will
+repeat your actions.
+-------------------------------------------------------------------------------
+Dependencies:
+
+dojo
+-------------------------------------------------------------------------------
+Documentation
+
+See installation instructions below to prepare a test page for recording.
+
+To record a test, click in an area of the document with no dojo.stopEvents
+and press CTRL-ALT-ENTER in the main window. You will get a verification alert
+when you successfully start the recorder. Then you can interact with the Web
+page and the recorder will monitor your actions. It's usually good to record one
+test per widget instance per type of interaction (keyboard vs mouse for instance)
+you are testing.
+
+After you finish interacting with the Web page, click out of any dojo.stopEvents
+and press CTRL-ALT-ENTER again. You will see a box containing the generated source 
+code for your recording. Copy this into a dojo.addOnLoad on the same page to register 
+the test with DOH. Replace the /*Your condition here*/ text with a JS condition that
+indicates that the test passed. Again, having multiple small tests will help you
+keep the condition small. Add a doh.run() call after you register all of your tests
+to make them execute when you load the page.
+-------------------------------------------------------------------------------
+Installation instructions
+
+To ready the recorder for a particular page, add this line to your dojo.requires:
+dojo.require("dojox.robot.recorder");
+
+You can safely remove this line after you are finished recording your tests.
+-------------------------------------------------------------------------------
+Additional Notes
+
+Known limitations:
+- Content in an iframe might not report events to the recorder.
+- keyDown/keyUp events are supported by DOH, but not by the recorder.
+	If you hold a key down, it will generate lots of keyPress events instead.
+	Simply change these to one keyDown call yourself.
diff --git a/dojox/robot/recorder.js b/dojox/robot/recorder.js
new file mode 100644
index 0000000..0d04711
--- /dev/null
+++ b/dojox/robot/recorder.js
@@ -0,0 +1,330 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.robot.recorder"]){
+dojo._hasResource["dojox.robot.recorder"]=true;
+dojo.provide("dojox.robot.recorder");
+dojo.experimental("dojox.robot.recorder");
+(function(){
+var _1=1000;
+var _2=500;
+var _3=10000;
+var _4=[];
+var _5=0;
+var _6=null;
+var _7=null;
+var _8=function(){
+alert("Started recording.");
+_4=[];
+_6=new Date();
+_7=new Date();
+};
+var _9=function(_a,_b){
+if(_6==null||_a=="doh.robot.keyPress"&&_b[0]==dojo.keys.ENTER&&eval("("+_b[2]+")").ctrl&&eval("("+_b[2]+")").alt){
+return;
+}
+var dt=Math.max(Math.min(Math.round((new Date()).getTime()-_7.getTime()),_3),1);
+if(_a=="doh.robot.mouseMove"){
+_b[2]=dt;
+}else{
+_b[1]=dt;
+}
+_4.push({name:_a,args:_b});
+_7=new Date();
+};
+var _d=function(){
+var c=_4;
+if(c[0].name=="doh.robot.keyPress"&&(c[0].args[0]==dojo.keys.ENTER||c[0].args[0]==77)){
+c.splice(0,1);
+}
+for(var i=c.length-1;(i>=c.length-2)&&(i>=0);i--){
+if(c[i].name=="doh.robot.keyPress"&&c[i].args[0]==dojo.keys.ALT||c[i].args[0]==dojo.keys.CTRL){
+c.splice(i,1);
+}
+}
+for(i=0;i<c.length;i++){
+var _10,_11;
+if(c[i+1]&&c[i].name=="doh.robot.mouseMove"&&c[i+1].name==c[i].name&&c[i+1].args[2]<_2){
+_10=c[i+1];
+_11=0;
+while(_10&&_10.name==c[i].name&&_10.args[2]<_2){
+c.splice(i+1,1);
+_11+=_10.args[2];
+c[i].args[0]=_10.args[0];
+c[i].args[1]=_10.args[1];
+_10=c[i+1];
+}
+c[i].args[3]=_11;
+}else{
+if(c[i+1]&&c[i].name=="doh.robot.mouseWheel"&&c[i+1].name==c[i].name&&c[i+1].args[1]<_2){
+_10=c[i+1];
+_11=0;
+while(_10&&_10.name==c[i].name&&_10.args[1]<_2){
+c.splice(i+1,1);
+_11+=_10.args[1];
+c[i].args[0]+=_10.args[0];
+_10=c[i+1];
+}
+c[i].args[2]=_11;
+}else{
+if(c[i+2]&&c[i].name=="doh.robot.mouseMoveAt"&&c[i+2].name=="doh.robot.scrollIntoView"){
+var _12=c.splice(i+2,1)[0];
+c.splice(i,0,_12);
+}else{
+if(c[i+1]&&c[i].name=="doh.robot.mousePress"&&c[i+1].name=="doh.robot.mouseRelease"&&c[i].args[0]==c[i+1].args[0]){
+c[i].name="doh.robot.mouseClick";
+c.splice(i+1,1);
+if(c[i+1]&&c[i+1].name=="doh.robot.mouseClick"&&c[i].args[0]==c[i+1].args[0]){
+c.splice(i+1,1);
+}
+}else{
+if(c[i+1]&&c[i-1]&&c[i-1].name=="doh.robot.mouseMoveAt"&&c[i].name=="doh.robot.mousePress"&&c[i+1].name=="doh.robot.mouseMove"){
+var cmd={name:"doh.robot.mouseMoveAt",args:[c[i-1].args[0],1,100,c[i-1].args[3]+1,c[i-1].args[4]]};
+c.splice(i+1,0,cmd);
+}else{
+if(c[i+1]&&((c[i].name=="doh.robot.keyPress"&&typeof c[i].args[0]=="string")||c[i].name=="doh.robot.typeKeys")&&c[i+1].name=="doh.robot.keyPress"&&typeof c[i+1].args[0]=="string"&&c[i+1].args[1]<=_1&&!eval("("+c[i].args[2]+")").ctrl&&!eval("("+c[i].args[2]+")").alt&&!eval("("+c[i+1].args[2]+")").ctrl&&!eval("("+c[i+1].args[2]+")").alt){
+c[i].name="doh.robot.typeKeys";
+c[i].args.splice(3,1);
+_10=c[i+1];
+var _14=0;
+while(_10&&_10.name=="doh.robot.keyPress"&&typeof _10.args[0]=="string"&&_10.args[1]<=_1&&!eval("("+_10.args[2]+")").ctrl&&!eval("("+_10.args[2]+")").alt){
+c.splice(i+1,1);
+c[i].args[0]+=_10.args[0];
+_14+=_10.args[1];
+_10=c[i+1];
+}
+c[i].args[2]=_14;
+c[i].args[0]="'"+c[i].args[0]+"'";
+}else{
+if(c[i].name=="doh.robot.keyPress"){
+if(typeof c[i].args[0]=="string"){
+c[i].args[0]="'"+c[i].args[0]+"'";
+}else{
+if(c[i].args[0]==0){
+c.splice(i,1);
+}else{
+for(var j in dojo.keys){
+if(dojo.keys[j]==c[i].args[0]){
+c[i].args[0]="dojo.keys."+j;
+break;
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+};
+var _16=function(){
+if(!_6){
+_8();
+}else{
+_17();
+}
+};
+var _17=function(){
+var dt=Math.round((new Date()).getTime()-_6.getTime());
+_6=null;
+_d();
+var c=_4;
+
+if(c.length){
+var s="doh.register('dojox.robot.AutoGeneratedTestGroup',{\n";
+s+="     name: 'autotest"+(_5++)+"',\n";
+s+="     timeout: "+(dt+2000)+",\n";
+s+="     runTest: function(){\n";
+s+="          var d = new doh.Deferred();\n";
+for(var i=0;i<c.length;i++){
+s+="          "+c[i].name+"(";
+for(var j=0;j<c[i].args.length;j++){
+var arg=c[i].args[j];
+s+=arg;
+if(j!=c[i].args.length-1){
+s+=", ";
+}
+}
+s+=");\n";
+}
+s+="          doh.robot.sequence(function(){\n";
+s+="               if(/*Your condition here*/){\n";
+s+="                    d.callback(true);\n";
+s+="               }else{\n";
+s+="                    d.errback(new Error('We got a failure'));\n";
+s+="               }\n";
+s+="          }, 1000);\n";
+s+="          return d;\n";
+s+="     }\n";
+s+="});\n";
+var div=document.createElement("div");
+div.id="dojox.robot.recorder";
+div.style.backgroundColor="white";
+div.style.position="absolute";
+var _1f={y:(window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0),x:(window.pageXOffset||(window["dojo"]?dojo._fixIeBiDiScrollLeft(document.documentElement.scrollLeft):undefined)||document.body.scrollLeft||0)};
+div.style.left=_1f.x+"px";
+div.style.top=_1f.y+"px";
+var h1=document.createElement("h1");
+h1.innerHTML="Your code:";
+div.appendChild(h1);
+var pre=document.createElement("pre");
+if(pre.innerText!==undefined){
+pre.innerText=s;
+}else{
+pre.textContent=s;
+}
+div.appendChild(pre);
+var _22=document.createElement("button");
+_22.innerHTML="Close";
+var _23=dojo.connect(_22,"onmouseup",function(e){
+dojo.stopEvent(e);
+document.body.removeChild(div);
+dojo.disconnect(_23);
+});
+div.appendChild(_22);
+document.body.appendChild(div);
+_4=[];
+}
+};
+var _25=function(_26){
+if(typeof _26=="string"){
+return "'"+_26+"'";
+}else{
+if(_26.id){
+return "'"+_26.id+"'";
+}else{
+var _27=document.getElementsByTagName(_26.nodeName);
+var i;
+for(i=0;i<_27.length;i++){
+if(_27[i]==_26){
+break;
+}
+}
+return "function(){ return document.getElementsByTagName('"+_26.nodeName+"')["+i+"]; }";
+}
+}
+};
+var _29=function(b){
+return "{left:"+(b==0)+", middle:"+(b==1)+", right:"+(b==2)+"}";
+};
+var _2b=function(e){
+return "{'shift':"+(e.shiftKey)+", 'ctrl':"+(e.ctrlKey)+", 'alt':"+(e.altKey)+"}";
+};
+dojo.connect(document,"onkeydown",function(e){
+if((e.keyCode==dojo.keys.ENTER||e.keyCode==77)&&e.ctrlKey&&e.altKey){
+dojo.stopEvent(e);
+_16();
+}
+});
+var _2e={type:""};
+var _2f=function(e){
+if(!e||_2e.type==e.type&&_2e.button==e.button){
+return;
+}
+_2e={type:e.type,button:e.button};
+var _31=_25(e.target);
+var _32=dojo.coords(e.target);
+_9("doh.robot.mouseMoveAt",[_31,0,100,e.clientX-_32.x,e.clientY-_32.y]);
+_9("doh.robot.mousePress",[_29(e.button-(dojo.isIE?1:0)),0]);
+};
+var _33=function(e){
+if(!e||_2e.type==e.type&&_2e.button==e.button){
+return;
+}
+_2e={type:e.type,button:e.button};
+var _35=_25(e.target);
+var _36=dojo.coords(e.target);
+_9("doh.robot.mouseClick",[_29(e.button-(dojo.isIE?1:0)),0]);
+};
+var _37=function(e){
+if(!e||_2e.type==e.type&&_2e.button==e.button){
+return;
+}
+_2e={type:e.type,button:e.button};
+var _39=_25(e.target);
+var _3a=dojo.coords(e.target);
+_9("doh.robot.mouseRelease",[_29(e.button-(dojo.isIE?1:0)),0]);
+};
+var _3b=function(e){
+if(!e||_2e.type==e.type&&_2e.pageX==e.pageX&&_2e.pageY==e.pageY){
+return;
+}
+_2e={type:e.type,pageX:e.pageX,pageY:e.pageY};
+_9("doh.robot.mouseMove",[e.pageX,e.pageY,0,100,true]);
+};
+var _3d=function(e){
+if(!e||_2e.type==e.type&&_2e.pageX==e.pageX&&_2e.pageY==e.pageY){
+return;
+}
+_2e={type:e.type,detail:(e.detail?(e.detail):(-e.wheelDelta/120))};
+_9("doh.robot.mouseWheel",[_2e.detail]);
+};
+var _3f=function(e){
+if(!e||_2e.type==e.type&&(_2e.charCode==e.charCode&&_2e.keyCode==e.keyCode)){
+return;
+}
+_2e={type:e.type,charCode:e.charCode,keyCode:e.keyCode};
+_9("doh.robot.keyPress",[e.charOrCode==dojo.keys.SPACE?" ":e.charOrCode,0,_2b(e)]);
+};
+var _41=function(e){
+if(!e||_2e.type==e.type&&(_2e.charCode==e.charCode&&_2e.keyCode==e.keyCode)){
+return;
+}
+_2e={type:e.type,charCode:e.charCode,keyCode:e.keyCode};
+};
+dojo.connect(document,"onmousedown",_2f);
+dojo.connect(document,"onmouseup",_37);
+dojo.connect(document,"onclick",_33);
+dojo.connect(document,"onkeypress",_3f);
+dojo.connect(document,"onkeyup",_41);
+dojo.connect(document,"onmousemove",_3b);
+dojo.connect(document,!dojo.isMozilla?"onmousewheel":"DOMMouseScroll",_3d);
+dojo.addOnLoad(function(){
+if(window["dijit"]&&dijit.scrollIntoView){
+dojo.connect(dijit,"scrollIntoView",function(_43){
+_9("doh.robot.scrollIntoView",[_25(_43)]);
+});
+}
+});
+dojo.connect(dojo,"connect",function(_44,_45,f){
+if(_44&&(!f||!f._mine)){
+var _47=null;
+if(_45.toLowerCase()=="onmousedown"){
+_47=dojo.hitch(this,_2f);
+}else{
+if(_45.toLowerCase()==(!dojo.isMozilla?"onmousewheel":"dommousescroll")){
+_47=dojo.hitch(this,_3d);
+}else{
+if(_45.toLowerCase()=="onclick"){
+_47=dojo.hitch(this,_33);
+}else{
+if(_45.toLowerCase()=="onmouseup"){
+_47=dojo.hitch(this,_37);
+}else{
+if(_45.toLowerCase()=="onkeypress"){
+_47=dojo.hitch(this,_3f);
+}else{
+if(_45.toLowerCase()=="onkeyup"){
+_47=dojo.hitch(this,_41);
+}
+}
+}
+}
+}
+}
+if(_47==null){
+return;
+}
+_47._mine=true;
+dojo.connect(_44,_45,_47);
+}
+});
+})();
+}
diff --git a/dojox/rpc/Client.js b/dojox/rpc/Client.js
new file mode 100644
index 0000000..d544b35
--- /dev/null
+++ b/dojox/rpc/Client.js
@@ -0,0 +1,21 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.rpc.Client"]){
+dojo._hasResource["dojox.rpc.Client"]=true;
+dojo.provide("dojox.rpc.Client");
+(function(){
+dojo._defaultXhr=dojo.xhr;
+dojo.xhr=function(_1,_2){
+var _3=_2.headers=_2.headers||{};
+_3["Client-Id"]=dojox.rpc.Client.clientId;
+_3["Seq-Id"]=dojox._reqSeqId=(dojox._reqSeqId||0)+1;
+return dojo._defaultXhr.apply(dojo,arguments);
+};
+})();
+dojox.rpc.Client.clientId=(Math.random()+"").substring(2,14);
+}
diff --git a/dojox/rpc/JsonRPC.js b/dojox/rpc/JsonRPC.js
new file mode 100644
index 0000000..3a9ecd0
--- /dev/null
+++ b/dojox/rpc/JsonRPC.js
@@ -0,0 +1,39 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.rpc.JsonRPC"]){
+dojo._hasResource["dojox.rpc.JsonRPC"]=true;
+dojo.provide("dojox.rpc.JsonRPC");
+dojo.require("dojox.rpc.Service");
+(function(){
+function _1(_2){
+return {serialize:function(_3,_4,_5,_6){
+var d={id:this._requestId++,method:_4.name,params:_5};
+if(_2){
+d.jsonrpc=_2;
+}
+return {data:dojo.toJson(d),handleAs:"json",contentType:"application/json",transport:"POST"};
+},deserialize:function(_8){
+if("Error"==_8.name){
+_8=dojo.fromJson(_8.responseText);
+}
+if(_8.error){
+var e=new Error(_8.error.message||_8.error);
+e._rpcErrorObject=_8.error;
+return e;
+}
+return _8.result;
+}};
+};
+dojox.rpc.envelopeRegistry.register("JSON-RPC-1.0",function(_a){
+return _a=="JSON-RPC-1.0";
+},dojo.mixin({namedParams:false},_1()));
+dojox.rpc.envelopeRegistry.register("JSON-RPC-2.0",function(_b){
+return _b=="JSON-RPC-2.0";
+},_1("2.0"));
+})();
+}
diff --git a/dojox/rpc/JsonRest.js b/dojox/rpc/JsonRest.js
new file mode 100644
index 0000000..43ac94a
--- /dev/null
+++ b/dojox/rpc/JsonRest.js
@@ -0,0 +1,278 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.rpc.JsonRest"]){
+dojo._hasResource["dojox.rpc.JsonRest"]=true;
+dojo.provide("dojox.rpc.JsonRest");
+dojo.require("dojox.json.ref");
+dojo.require("dojox.rpc.Rest");
+(function(){
+var _1=[];
+var _2=dojox.rpc.Rest;
+var jr;
+function _4(_5,_6,_7,_8){
+var _9=_6.ioArgs&&_6.ioArgs.xhr&&_6.ioArgs.xhr.getResponseHeader("Last-Modified");
+if(_9&&_2._timeStamps){
+_2._timeStamps[_8]=_9;
+}
+return _7&&dojox.json.ref.resolveJson(_7,{defaultId:_8,index:_2._index,timeStamps:_9&&_2._timeStamps,time:_9,idPrefix:_5.servicePath,idAttribute:jr.getIdAttribute(_5),schemas:jr.schemas,loader:jr._loader,assignAbsoluteIds:true});
+};
+jr=dojox.rpc.JsonRest={conflictDateHeader:"If-Unmodified-Since",commit:function(_a){
+_a=_a||{};
+var _b=[];
+var _c={};
+var _d=[];
+for(var i=0;i<_1.length;i++){
+var _f=_1[i];
+var _10=_f.object;
+var old=_f.old;
+var _12=false;
+if(!(_a.service&&(_10||old)&&(_10||old).__id.indexOf(_a.service.servicePath))&&_f.save){
+delete _10.__isDirty;
+if(_10){
+if(old){
+var _13;
+if((_13=_10.__id.match(/(.*)#.*/))){
+_10=_2._index[_13[1]];
+}
+if(!(_10.__id in _c)){
+_c[_10.__id]=_10;
+_b.push({method:"put",target:_10,content:_10});
+}
+}else{
+_b.push({method:"post",target:{__id:jr.getServiceAndId(_10.__id).service.servicePath},content:_10});
+}
+}else{
+if(old){
+_b.push({method:"delete",target:old});
+}
+}
+_d.push(_f);
+_1.splice(i--,1);
+}
+}
+dojo.connect(_a,"onError",function(){
+var _14=_1;
+_1=_d;
+var _15=0;
+jr.revert();
+_1=_14;
+});
+jr.sendToServer(_b,_a);
+return _b;
+},sendToServer:function(_16,_17){
+var _18;
+var _19=dojo.xhr;
+var _1a=_16.length;
+var i,_1c;
+var _1d;
+var _1e=this.conflictDateHeader;
+dojo.xhr=function(_1f,_20){
+_20.headers=_20.headers||{};
+_20.headers["Transaction"]=_16.length-1==i?"commit":"open";
+if(_1e&&_1d){
+_20.headers[_1e]=_1d;
+}
+if(_1c){
+_20.headers["Content-ID"]="<"+_1c+">";
+}
+return _19.apply(dojo,arguments);
+};
+for(i=0;i<_16.length;i++){
+var _21=_16[i];
+dojox.rpc.JsonRest._contentId=_21.content&&_21.content.__id;
+var _22=_21.method=="post";
+_1d=_21.method=="put"&&_2._timeStamps[_21.content.__id];
+if(_1d){
+_2._timeStamps[_21.content.__id]=(new Date())+"";
+}
+_1c=_22&&dojox.rpc.JsonRest._contentId;
+var _23=jr.getServiceAndId(_21.target.__id);
+var _24=_23.service;
+var dfd=_21.deferred=_24[_21.method](_23.id.replace(/#/,""),dojox.json.ref.toJson(_21.content,false,_24.servicePath,true));
+(function(_26,dfd,_28){
+dfd.addCallback(function(_29){
+try{
+var _2a=dfd.ioArgs.xhr&&dfd.ioArgs.xhr.getResponseHeader("Location");
+if(_2a){
+var _2b=_2a.match(/(^\w+:\/\/)/)&&_2a.indexOf(_28.servicePath);
+_2a=_2b>0?_2a.substring(_2b):(_28.servicePath+_2a).replace(/^(.*\/)?(\w+:\/\/)|[^\/\.]+\/\.\.\/|^.*\/(\/)/,"$2$3");
+_26.__id=_2a;
+_2._index[_2a]=_26;
+}
+_29=_4(_28,dfd,_29,_26&&_26.__id);
+}
+catch(e){
+}
+if(!(--_1a)){
+if(_17.onComplete){
+_17.onComplete.call(_17.scope);
+}
+}
+return _29;
+});
+})(_21.content,dfd,_24);
+dfd.addErrback(function(_2c){
+_1a=-1;
+_17.onError.call(_17.scope,_2c);
+});
+}
+dojo.xhr=_19;
+},getDirtyObjects:function(){
+return _1;
+},revert:function(_2d){
+for(var i=_1.length;i>0;){
+i--;
+var _2f=_1[i];
+var _30=_2f.object;
+var old=_2f.old;
+if(!(_2d&&(_30||old)&&(_30||old).__id.indexOf(_2d.servicePath))){
+if(_30&&old){
+for(var j in old){
+if(old.hasOwnProperty(j)){
+_30[j]=old[j];
+}
+}
+for(j in _30){
+if(!old.hasOwnProperty(j)){
+delete _30[j];
+}
+}
+}
+_1.splice(i,1);
+}
+}
+},changing:function(_33,_34){
+if(!_33.__id){
+return;
+}
+_33.__isDirty=true;
+for(var i=0;i<_1.length;i++){
+var _36=_1[i];
+if(_33==_36.object){
+if(_34){
+_36.object=false;
+if(!this._saveNotNeeded){
+_36.save=true;
+}
+}
+return;
+}
+}
+var old=_33 instanceof Array?[]:{};
+for(i in _33){
+if(_33.hasOwnProperty(i)){
+old[i]=_33[i];
+}
+}
+_1.push({object:!_34&&_33,old:old,save:!this._saveNotNeeded});
+},deleteObject:function(_38){
+this.changing(_38,true);
+},getConstructor:function(_39,_3a){
+if(typeof _39=="string"){
+var _3b=_39;
+_39=new dojox.rpc.Rest(_39,true);
+this.registerService(_39,_3b,_3a);
+}
+if(_39._constructor){
+return _39._constructor;
+}
+_39._constructor=function(_3c){
+var _3d=this;
+var _3e=arguments;
+var _3f;
+function _40(_41){
+if(_41){
+_40(_41["extends"]);
+_3f=_41.properties;
+for(var i in _3f){
+var _43=_3f[i];
+if(_43&&(typeof _43=="object")&&("default" in _43)){
+_3d[i]=_43["default"];
+}
+}
+}
+if(_3c){
+dojo.mixin(_3d,_3c);
+}
+if(_41&&_41.prototype&&_41.prototype.initialize){
+_41.prototype.initialize.apply(_3d,_3e);
+}
+};
+_40(_39._schema);
+var _44=jr.getIdAttribute(_39);
+_2._index[this.__id=this.__clientId=_39.servicePath+(this[_44]||Math.random().toString(16).substring(2,14)+"@"+((dojox.rpc.Client&&dojox.rpc.Client.clientId)||"client"))]=this;
+if(dojox.json.schema&&_3f){
+dojox.json.schema.mustBeValid(dojox.json.schema.validate(this,_39._schema));
+}
+_1.push({object:this,save:true});
+};
+return dojo.mixin(_39._constructor,_39._schema,{load:_39});
+},fetch:function(_45){
+var _46=jr.getServiceAndId(_45);
+return this.byId(_46.service,_46.id);
+},getIdAttribute:function(_47){
+var _48=_47._schema;
+var _49;
+if(_48){
+if(!(_49=_48._idAttr)){
+for(var i in _48.properties){
+if(_48.properties[i].identity){
+_48._idAttr=_49=i;
+}
+}
+}
+}
+return _49||"id";
+},getServiceAndId:function(_4b){
+var _4c=_4b.match(/^(.*\/)([^\/]*)$/);
+var svc=jr.services[_4c[1]]||new dojox.rpc.Rest(_4c[1],true);
+return {service:svc,id:_4c[2]};
+},services:{},schemas:{},registerService:function(_4e,_4f,_50){
+_4f=_4f||_4e.servicePath;
+_4f=_4e.servicePath=_4f.match(/\/$/)?_4f:(_4f+"/");
+_4e._schema=jr.schemas[_4f]=_50||_4e._schema||{};
+jr.services[_4f]=_4e;
+},byId:function(_51,id){
+var _53,_54=_2._index[(_51.servicePath||"")+id];
+if(_54&&!_54._loadObject){
+_53=new dojo.Deferred();
+_53.callback(_54);
+return _53;
+}
+return this.query(_51,id);
+},query:function(_55,id,_57){
+var _58=_55(id,_57);
+_58.addCallback(function(_59){
+if(_59.nodeType&&_59.cloneNode){
+return _59;
+}
+return _4(_55,_58,_59,typeof id!="string"||(_57&&(_57.start||_57.count))?undefined:id);
+});
+return _58;
+},_loader:function(_5a){
+var _5b=jr.getServiceAndId(this.__id);
+var _5c=this;
+jr.query(_5b.service,_5b.id).addBoth(function(_5d){
+if(_5d==_5c){
+delete _5d.$ref;
+delete _5d._loadObject;
+}else{
+_5c._loadObject=function(_5e){
+_5e(_5d);
+};
+}
+_5a(_5d);
+});
+},isDirty:function(_5f){
+if(!_5f){
+return !!_1.length;
+}
+return _5f.__isDirty;
+}};
+})();
+}
diff --git a/dojox/rpc/OfflineRest.js b/dojox/rpc/OfflineRest.js
new file mode 100644
index 0000000..0c70b28
--- /dev/null
+++ b/dojox/rpc/OfflineRest.js
@@ -0,0 +1,188 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.rpc.OfflineRest"]){
+dojo._hasResource["dojox.rpc.OfflineRest"]=true;
+dojo.provide("dojox.rpc.OfflineRest");
+dojo.require("dojox.data.ClientFilter");
+dojo.require("dojox.rpc.Rest");
+dojo.require("dojox.storage");
+(function(){
+var _1=dojox.rpc.Rest;
+var _2="dojox_rpc_OfflineRest";
+var _3;
+var _4=_1._index;
+dojox.storage.manager.addOnLoad(function(){
+_3=dojox.storage.manager.available;
+for(var i in _4){
+_6(_4[i],i);
+}
+});
+var _7;
+function _8(_9){
+return _9.replace(/[^0-9A-Za-z_]/g,"_");
+};
+function _6(_a,id){
+if(_3&&!_7&&(id||(_a&&_a.__id))){
+dojox.storage.put(_8(id||_a.__id),typeof _a=="object"?dojox.json.ref.toJson(_a):_a,function(){
+},_2);
+}
+};
+function _c(_d){
+return _d instanceof Error&&(_d.status==503||_d.status>12000||!_d.status);
+};
+function _e(){
+if(_3){
+var _f=dojox.storage.get("dirty",_2);
+if(_f){
+for(var _10 in _f){
+_11(_10,_f);
+}
+}
+}
+};
+var _12;
+function _13(){
+_12.sendChanges();
+_12.downloadChanges();
+};
+var _14=setInterval(_13,15000);
+dojo.connect(document,"ononline",_13);
+_12=dojox.rpc.OfflineRest={turnOffAutoSync:function(){
+clearInterval(_14);
+},sync:_13,sendChanges:_e,downloadChanges:function(){
+},addStore:function(_15,_16){
+_12.stores.push(_15);
+_15.fetch({queryOptions:{cache:true},query:_16,onComplete:function(_17,_18){
+_15._localBaseResults=_17;
+_15._localBaseFetch=_18;
+}});
+}};
+_12.stores=[];
+var _19=_1._get;
+_1._get=function(_1a,id){
+try{
+_e();
+if(window.navigator&&navigator.onLine===false){
+throw new Error();
+}
+var dfd=_19(_1a,id);
+}
+catch(e){
+dfd=new dojo.Deferred();
+dfd.errback(e);
+}
+var _1d=dojox.rpc._sync;
+dfd.addCallback(function(_1e){
+_6(_1e,_1a.servicePath+id);
+return _1e;
+});
+dfd.addErrback(function(_1f){
+if(_3){
+if(_c(_1f)){
+var _20={};
+var _21=function(id,_23){
+if(_20[id]){
+return _23;
+}
+var _24=dojo.fromJson(dojox.storage.get(_8(id),_2))||_23;
+_20[id]=_24;
+for(var i in _24){
+var val=_24[i];
+if(val&&val.$ref){
+_24[i]=_21(val.$ref,val);
+}
+}
+if(_24 instanceof Array){
+for(i=0;i<_24.length;i++){
+if(_24[i]===undefined){
+_24.splice(i--,1);
+}
+}
+}
+return _24;
+};
+_7=true;
+var _27=_21(_1a.servicePath+id);
+if(!_27){
+return _1f;
+}
+_7=false;
+return _27;
+}else{
+return _1f;
+}
+}else{
+if(_1d){
+return new Error("Storage manager not loaded, can not continue");
+}
+dfd=new dojo.Deferred();
+dfd.addCallback(arguments.callee);
+dojox.storage.manager.addOnLoad(function(){
+dfd.callback();
+});
+return dfd;
+}
+});
+return dfd;
+};
+var _28=_1._change;
+_1._change=function(_29,_2a,id,_2c){
+if(!_3){
+return _28.apply(this,arguments);
+}
+var _2d=_2a.servicePath+id;
+if(_29=="delete"){
+dojox.storage.remove(_8(_2d),_2);
+}else{
+dojox.storage.put(_8(dojox.rpc.JsonRest._contentId),_2c,function(){
+},_2);
+}
+var _2e=_2a._store;
+if(_2e){
+_2e.updateResultSet(_2e._localBaseResults,_2e._localBaseFetch);
+dojox.storage.put(_8(_2a.servicePath+_2e._localBaseFetch.query),dojox.json.ref.toJson(_2e._localBaseResults),function(){
+},_2);
+}
+var _2f=dojox.storage.get("dirty",_2)||{};
+if(_29=="put"||_29=="delete"){
+var _30=_2d;
+}else{
+_30=0;
+for(var i in _2f){
+if(!isNaN(parseInt(i))){
+_30=i;
+}
+}
+_30++;
+}
+_2f[_30]={method:_29,id:_2d,content:_2c};
+return _11(_30,_2f);
+};
+function _11(_32,_33){
+var _34=_33[_32];
+var _35=dojox.rpc.JsonRest.getServiceAndId(_34.id);
+var _36=_28(_34.method,_35.service,_35.id,_34.content);
+_33[_32]=_34;
+dojox.storage.put("dirty",_33,function(){
+},_2);
+_36.addBoth(function(_37){
+if(_c(_37)){
+return null;
+}
+var _38=dojox.storage.get("dirty",_2)||{};
+delete _38[_32];
+dojox.storage.put("dirty",_38,function(){
+},_2);
+return _37;
+});
+return _36;
+};
+dojo.connect(_4,"onLoad",_6);
+dojo.connect(_4,"onUpdate",_6);
+})();
+}
diff --git a/dojox/rpc/ProxiedPath.js b/dojox/rpc/ProxiedPath.js
new file mode 100644
index 0000000..bd8e29e
--- /dev/null
+++ b/dojox/rpc/ProxiedPath.js
@@ -0,0 +1,30 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.rpc.ProxiedPath"]){
+dojo._hasResource["dojox.rpc.ProxiedPath"]=true;
+dojo.provide("dojox.rpc.ProxiedPath");
+dojo.require("dojox.rpc.Service");
+dojox.rpc.envelopeRegistry.register("PROXIED-PATH",function(_1){
+return _1=="PROXIED-PATH";
+},{serialize:function(_2,_3,_4){
+var i;
+var _6=dojox.rpc.getTarget(_2,_3);
+if(dojo.isArray(_4)){
+for(i=0;i<_4.length;i++){
+_6+="/"+(_4[i]==null?"":_4[i]);
+}
+}else{
+for(i in _4){
+_6+="/"+i+"/"+_4[i];
+}
+}
+return {data:"",target:(_3.proxyUrl||_2.proxyUrl)+"?url="+encodeURIComponent(_6)};
+},deserialize:function(_7){
+return _7;
+}});
+}
diff --git a/dojox/rpc/README b/dojox/rpc/README
new file mode 100644
index 0000000..e451281
--- /dev/null
+++ b/dojox/rpc/README
@@ -0,0 +1,62 @@
+-------------------------------------------------------------------------------
+DojoX RPC
+-------------------------------------------------------------------------------
+Version 1.0
+Release date: 07/01/2007
+-------------------------------------------------------------------------------
+Project state:
+yahoo.smd: production (but for old dojo.rpc, not the dojox.service.Rpc)
+Service.js: beta - this will become dojo.rpc.Service eventually and replace
+			the existing rpc system
+JsonRPC.js: beta - plugins for json-rpc for the rpc system
+Rest.js: beta - plugin for REST style services for the rpc system
+JsonRest.js: beta - A module for tracking and persisting changes to JSON objects 
+through REST.
+LocalStorageRest.js: alpha - A module for storing REST changes locally as write-
+back cache for offline and intermittent connection situations
+OfflineRest.js: alpha - A module for using LocalStorageRest for a full-fledged
+offline application
+ProxiedPath.js: beta - plugin for the PATH envelope to work with a simple PHP proxy
+Client.js: alpha - A module for maintaining per page/tab client sessions and 
+deterministic message sequencing with a server.
+
+Stores: CouchDBRestStore.js  JsonReferencing.js  PersevereRestStore.js
+These stores are fresh new and alpha. The will likely be moved to dojox.data 
+after they are well tested and documented.
+
+SMDLibrary contains smd files representing external services.
+
+-------------------------------------------------------------------------------
+Project authors
+	Dustin Machi
+	Kris Zyp
+	Revin Guillen
+-------------------------------------------------------------------------------
+Project description
+
+Extra utilities for use with dojo.rpc as well as additional smd descriptions
+for specific services.
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo Core (package loader, dojo.rpc).
+-------------------------------------------------------------------------------
+Documentation
+
+See RPC documentation at http://dojotoolkit.org/
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/rpc/*
+
+Install into the following directory structure:
+/dojox/rpc/
+
+...which should be at the same level as your Dojo checkout.
+
+The use of the actual utilities varies, but typically additional software 
+will be included with dojo.require() and smd files for services can be loaded
+manually with an xhr request or can be provided by url to the service when created
+
diff --git a/dojox/rpc/Rest.js b/dojox/rpc/Rest.js
new file mode 100644
index 0000000..9301c25
--- /dev/null
+++ b/dojox/rpc/Rest.js
@@ -0,0 +1,76 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.rpc.Rest"]){
+dojo._hasResource["dojox.rpc.Rest"]=true;
+dojo.provide("dojox.rpc.Rest");
+(function(){
+if(dojox.rpc&&dojox.rpc.transportRegistry){
+dojox.rpc.transportRegistry.register("REST",function(_1){
+return _1=="REST";
+},{getExecutor:function(_2,_3,_4){
+return new dojox.rpc.Rest(_3.name,(_3.contentType||_4._smd.contentType||"").match(/json|javascript/),null,function(id,_6){
+var _7=_4._getRequest(_3,[id]);
+_7.url=_7.target+(_7.data?"?"+_7.data:"");
+return _7;
+});
+}});
+}
+var _8;
+function _9(_a,_b,_c,id){
+_a.addCallback(function(_e){
+if(_c){
+_c=_a.ioArgs.xhr&&_a.ioArgs.xhr.getResponseHeader("Content-Range");
+_a.fullLength=_c&&(_c=_c.match(/\/(.*)/))&&parseInt(_c[1]);
+}
+return _e;
+});
+return _a;
+};
+_8=dojox.rpc.Rest=function(_f,_10,_11,_12){
+var _13;
+_f=_f.match(/\/$/)?_f:(_f+"/");
+_13=function(id,_15){
+return _8._get(_13,id,_15);
+};
+_13.isJson=_10;
+_13._schema=_11;
+_13.cache={serialize:_10?((dojox.json&&dojox.json.ref)||dojo).toJson:function(_16){
+return _16;
+}};
+_13._getRequest=_12||function(id,_18){
+var _19={url:_f+(dojo.isObject(id)?"?"+dojo.objectToQuery(id):id==null?"":id),handleAs:_10?"json":"text",contentType:_10?"application/json":"text/plain",sync:dojox.rpc._sync,headers:{Accept:_10?"application/json,application/javascript":"*/*"}};
+if(_18&&(_18.start>=0||_18.count>=0)){
+_19.headers.Range="items="+(_18.start||"0")+"-"+((_18.count&&_18.count!=Infinity&&(_18.count+(_18.start||0)-1))||"");
+}
+dojox.rpc._sync=false;
+return _19;
+};
+function _1a(_1b){
+_13[_1b]=function(id,_1d){
+return _8._change(_1b,_13,id,_1d);
+};
+};
+_1a("put");
+_1a("post");
+_1a("delete");
+_13.servicePath=_f;
+return _13;
+};
+_8._index={};
+_8._timeStamps={};
+_8._change=function(_1e,_1f,id,_21){
+var _22=_1f._getRequest(id);
+_22[_1e+"Data"]=_21;
+return _9(dojo.xhr(_1e.toUpperCase(),_22,true),_1f);
+};
+_8._get=function(_23,id,_25){
+_25=_25||{};
+return _9(dojo.xhrGet(_23._getRequest(id,_25)),_23,(_25.start>=0||_25.count>=0),id);
+};
+})();
+}
diff --git a/dojox/rpc/SMDLibrary/dojo-api.smd b/dojox/rpc/SMDLibrary/dojo-api.smd
new file mode 100644
index 0000000..1b2db85
--- /dev/null
+++ b/dojox/rpc/SMDLibrary/dojo-api.smd
@@ -0,0 +1,30 @@
+{
+	envelope: "URL",
+	transport: "JSONP",
+	callbackParamName: "callback",
+	services: {
+		get: {
+			target: "http://api.dojotoolkit.org/jsdoc/jsonp",
+			parameters: [
+				{ name: "name", type: "string", optional: false },
+				{ name: "exact", type: "boolean", optional: true },
+				{ name: "recursion", type: "boolean", optional: true },
+				{ name: "resource", type: "string", optional: true },
+				{ name: "project", type: "string", optional: true },
+				{ name: "version", type: "string", optional: true },
+				{ name: "attributes", type: "array", optional: true }
+			]
+		},
+		batch: {
+			target: "http://api.dojotoolkit.org/jsdoc/jsonp/batch",
+			parameters: [
+				{ name: "names", type: "array", optional: false },
+				{ name: "exact", type: "boolean", optional: true },
+				{ name: "recursion", type: "boolean", optional: true },
+				{ name: "project", type: "string", optional: true },
+				{ name: "version", type: "string", optional: true },
+				{ name: "attributes", type: "array", optional: false }
+			]
+		}
+	}
+}
\ No newline at end of file
diff --git a/dojox/rpc/SMDLibrary/geonames.smd b/dojox/rpc/SMDLibrary/geonames.smd
new file mode 100644
index 0000000..04f04db
--- /dev/null
+++ b/dojox/rpc/SMDLibrary/geonames.smd
@@ -0,0 +1,263 @@
+{
+
+	// JSON REST services provided by geonames.org
+	// adapted from: http://www.geonames.org/export/JSON-webservices.html
+	// http://creativecommons.org/licenses/by/3.0/
+	// INCOMPLETE IMPLEMENTATION
+	
+	"SMDVersion":"2.0",
+	"id":"/geonames",
+	"transport":"JSONP",
+	"envelope":"URL",
+	"target": "http://ws.geonames.org/",
+
+	"parameters" : [ 
+		{name:"type", optional: false, "default":"JSON"}
+	],
+
+	"services":{
+		getCountryInfo:{
+			// Result : returns info about a country such as name, population, etc.
+			// If country parameter is not specified, that information is returned for
+			// every country
+			"target": "countryInfoJSON",
+			"parameters": [
+				{ name: "country", type:"STRING", optional: true },
+				{ name: "lang", type:"STRING"}, // default: "en"
+				{ name: "maxRows", type:"INTEGER", optional: true } // default: 10
+			]	
+		},
+
+		getCities:{
+			// Result : returns a list of cities and placenames in the bounding box,
+			// ordered by relevancy (capital/population). Placenames close together
+			// are filterered out and only the larger name is included in the resulting list.
+			"target": "citiesJSON",
+			"parameters": [
+				{ name: "north", type:"FLOAT"},
+				{ name: "south", type:"FLOAT"},
+				{ name: "east", type:"FLOAT"},
+				{ name: "west", type:"FLOAT"},
+				{ name: "lang", type:"STRING"}, // default: "en"
+				{ name: "maxRows", type:"INTEGER", optional: true } // deault: 10
+			]	
+		},
+
+		"getQuakes":{
+			// Result : returns a list of earthquakes, ordered by magnitude
+			"target" : "earthquakesJSON",
+			"parameters" : [
+				// bounding box coords:
+				{ name: "north", type:"FLOAT" },
+				{ name: "south", type:"FLOAT" },
+				{ name: "east", type:"FLOAT" },
+       				{ name: "west", type:"FLOAT" },
+				{ name: "date", type:"STRING",optional: true }, // yyyy-MM-dd
+				{ name: "minMagniture", type:"INTERGER",optional: true },
+				{ name: "maxRows", type:"INTEGER", optional: true } // deault: 10
+			]
+		},
+
+		"getWeather":{
+			// Weather data is provided in the METAR (METeorological Aerodrome Report) format.
+			// Result : returns a list of weather stations with the most recent weather observation
+			"target" : "weatherJSON",
+			"parameters" : [
+				{ name: "north", type:"FLOAT" },
+				{ name: "south", type:"FLOAT" },
+				{ name: "east", type:"FLOAT" },
+				{ name: "west", type:"FLOAT" },
+				{ name: "maxRows", type:"INTEGER",optional:true } // deault: 10
+			]
+		},
+
+		"getWeatherByICAO":{
+			// Result : returns the weather station and the most recent weather observation for the ICAO code
+			"target": "weatherIcaoJSON",
+			"parameters": [
+				{ name:"ICAO", type:"STRING" }
+			]
+		},
+
+		"getWeatherByCoords":{
+			// Result : returns a weather station with the most recent weather observation
+			"target": "findNearByWeatherJSON",
+			"parameters": [
+				{ name:"lat", type:"FLOAT" },
+				{ name:"lng", type:"FLOAT" }
+			]
+		},
+
+		"getChildren":{
+                        // Returns the children for a given geonameId. The children are the
+                        // administrative divisions within an other administrative division.
+                        // Like the counties (ADM2) in a state (ADM1) or also the countries
+                        // in a continent.
+                        "target": "childrenJSON",
+			"parameters": [
+				{ name:"geonameId", type:"INTEGER" }
+			]
+		},
+
+		"getHierarchy":{
+			// Result : returns a list of GeoName records, ordered by hierarchy 
+			// level. The top hierarchy (continent) is the first element in the list
+			"target": "hierarchyJSON",
+			"parameters": [
+				{ name:"geonameId", type:"INTEGER" }
+			]
+		},
+
+		"getNeighbours":{
+			// The neighbourhood for US cities. Data provided by Zillow under cc-by-sa license.
+			"target":"neighboursJSON",
+			"parameters": [
+				{ name:"geonameId", type:"INTEGER" }
+                                //{ name:"lat", type:"FLOAT" },
+                                //{ name:"long", type:"FLOAT" }
+			]
+		},
+
+		"getNeighbourhood":{
+			// returns the neighbourhood for the given latitude/longitude
+			// Example http://ws.geonames.org/neighbourhood?lat=40.78343&lng=-73.96625
+			"target":"neighbourhoodJSON",
+			"parameters":[
+				{ name:"lat", type:"FLOAT" },
+				{ name:"lng", type:"FLOAT" },
+				{ name:"radius", type:"FLOAT" } 
+			]
+		},
+
+		"getSiblings":{
+			// Result : returns a list of GeoNames records that have the same
+			// administrative level and the same father
+			"target":"siblingsJSON",
+			"parameters": [
+				{ name:"geonameId", type:"INTEGER" }
+			]
+		},
+
+		"getCountryCode":{
+			// returns the iso country code for the given latitude/longitude
+			// With the parameter type=xml this service returns an xml document
+			//      with iso country code and country name. The optional parameter
+			//      lang can be used to specify the language the country name should
+			//      be in. JSON output is produced with type=JSON
+			"target":"countryCode",
+			"parameters": [
+				{ name:"lat", type:"FLOAT" },
+				{ name:"lng", type:"FLOAT" },
+				{ name:"lang", type:"STRING",optional:true }, 
+				{ name:"radius", type:"FLOAT" }
+			]
+		},
+
+		"getCountrySubdivision":{
+			// returns the country and the administrative subdivison (state, province,...) for the given latitude/longitude
+			// Example http://ws.geonames.org/countrySubdivisionJSON?lat=47.03&lng=10.2
+			"target":"countrySubdivisionJSON",
+			"parameters":[
+				{ name:"lat", type:"FLOAT" },
+				{ name:"long", type:"FLOAT" },
+				{ name:"radius", type:"FLOAT" }
+			]
+                }, 
+
+		"getWikipediaBoundingBox":{
+			// returns the wikipedia entries within the bounding box as xml document
+			// Example http://ws.geonames.org/wikipediaBoundingBoxJSON?north=44.1&south=-9.9&east=-22.4&west=55.2
+			"target":"wikipediaBoundingBoxJSON",
+			"parameters":[
+				{ name: "north", type:"FLOAT" },
+				{ name: "south", type:"FLOAT" },
+				{ name: "east", type:"FLOAT" },
+				{ name: "west", type:"FLOAT" },
+				{ name: "lang", type:"STRING",optional:true }, // default: "en"
+				{ name: "maxRows", type:"INTEGER",optional:true } // default: 10
+                        ]
+                },
+
+		"searchWikipedia":{
+			// returns the wikipedia entries found for the searchterm as xml document
+			// Example http://ws.geonames.org/wikipediaSearchJSON?q=london&maxRows=10
+			"target":"wikipediaSearchJSON",
+			"parameters":[
+				{ name: "q", type:"STRING" }, // place name?
+				{ name: "title", type:"STRING" }, // optional
+				{ name: "lang", type:"FLOAT",optional:true }, // de or en
+				{ name: "maxRows", type:"INTEGER",optional:true } // default: 10
+			]
+		},
+
+		"getTimezone":{
+                        // the timezone at the lat/lng with gmt offset (1. January) and dst offset (1. July)
+                        "target":"timezoneJSON",
+			"parameters":[
+				{ name:"lat", type:"FLOAT" },
+				{ name:"lng", type:"FLOAT" }
+			]
+		},
+
+		"search":{
+                        // returns the names found for the searchterm as xml or json document,
+                        // the search is using an AND operator
+                        "target":"searchJSON",
+			"parameters":[
+                                // exhaustive list. see: http://www.geonames.org/export/geonames-search.html
+				{ name:"q", type:"STRING" },
+				{ name:"name", type:"STRING" },
+				{ name:"name_equals", type:"STRING" },
+				// optional:
+				{ name:"maxRows", type:"INTEGER",optional:true }, // def: 100, max:1000
+				{ name:"startRow", type:"INTEGER",optional:true }, // def: 0
+				{ name:"country", type:"STRING",optional:true }, // iso-3166, def: all
+				/* name:"adminCode..." */
+				{ name:"featureClass", type:"STRING",optional:true}, // ? multi, enum(a,h,l,p,r,s,t,u,v)
+				{ name:"featureCode", type:"STRING",optional:true},
+				{ name:"lang", type:"STRING",optional:true}, // iso-636
+				{ name:"type", type:"STRING",optional:true}, // xml | json | rdf, def: xml
+				{ name:"style", type:"STRING",optional:true }, // SHORT,MEDIUM,LONG,FULL def: MEDIUM
+				{ name:"isNamedRequired", type:"BOOLEAN", optional:true }
+			]
+		},
+
+		"postalCodeLookup":{
+			// returns a list of places for the given postalcode in JSON format
+			// Example http://ws.geonames.org/postalCodeLookupJSON?postalcode=6600&country=AT
+			"target":"postalCodeLookupJSON",
+			"parameters":[
+				{ name:"postalcode", type:"STRING" },
+				{ name:"country", type:"STRING",optional:true},
+				{ name:"maxRows", type:"INTEGER", optional:true }, // def: 20
+				{ name:"charset", type:"STRING",optional:true } // def: utf-8
+			]
+		},
+
+                "postalCodeSearch":{
+                        "target":"postalCodeSearchJSON",
+			"parameters":[
+				{ name:"postalcode", type:"STRING",optional:true}, // one or the other
+				{ name:"placename", type:"STRING",optional:true }, // one or the other
+				{ name:"country", type:"STRING",optional:true},
+				{ name:"style", type:"STRING",optional:true}, // def: MEDIUM
+				{ name:"maxRows", type:"INTEGER",optional:true}, // def: 20
+                                { name:"charset", type:"STRING",optional:true} // def: utf-8
+                        ]
+                }
+
+                // TODO: implement:
+                // findNearby,
+                // findNearbyPlaceName
+                // findNearbyPostalCodes,
+                // findNearbyStreets,
+                // findNearByWeather
+                // findNearByWikipedia
+                // findNeareastAddress
+                // findNearestInterestion
+                // get
+                // gtop30
+                // srtm3
+
+	} // end services
+}
diff --git a/dojox/rpc/SMDLibrary/google.smd b/dojox/rpc/SMDLibrary/google.smd
new file mode 100644
index 0000000..82af928
--- /dev/null
+++ b/dojox/rpc/SMDLibrary/google.smd
@@ -0,0 +1,129 @@
+{
+	// Google Ajax API SMD as defined by:
+	// http://code.google.com/apis/ajaxsearch/documentation/reference.html
+	// PLEASE Read the Google Terms of Service:
+	// http://code.google.com/apis/ajaxsearch/terms.html
+	
+	"SMDVersion": "2.0",
+	"id": "http://ajax.googleapis.com/ajax/services/search/", 
+	"description": "Google Ajax API",
+		
+	"transport": "JSONP",
+	"envelope": "URL",
+	"additionalParameters": true,
+	
+	"parameters": [
+		// the most important param, the search query:
+		{ "name": "q", optional: false, "default":"" },
+		
+		// Google doesn't require, but appreciates, you using an API key
+		// see: http://code.google.com/apis/ajaxsearch/signup.html
+		// { "name": "key", optional: true, "default": "[enter your key]" },
+
+		// result size: large | small (8 or 4 per page)
+		{ "name": "rsz", optional:true, "default": "small" },
+
+		// language selection:
+		{ "name": "hl", optional:true, "default": "en" },
+
+		// starting offset
+		{ "name": "start", optional:true, "default": 0 },
+
+		{ "name": "alt", optional:false, "default": "json" },
+
+		// API version: only 1.0 supported 
+		{ "name": "v", optional:false, "default": "1.0" }
+	],
+
+	"services": {
+
+		"webSearch": {
+			"target": "http://ajax.googleapis.com/ajax/services/search/web",
+			"parameters": [
+				{ "name": "cx", "type":"string", "optional":true }, // unique id
+				{ "name": "cref", "type":"string", "optional":true }, // linked custom search engine
+				{ "name": "safe", "type":"string", "optional":true }, // active | moderate | off
+				// lr: see: http://www.google.com/coop/docs/cse/resultsxml.html#languageCollections	
+				{ "name": "lr", "type":"string", "optional":true } // restrict to lang
+			]
+		},
+
+		"localSearch": {
+			"target": "http://ajax.googleapis.com/ajax/services/search/local",
+			"parameters": [
+				// comma separated lat,long value to use for center
+				{ "name": "sll", "type": "string", "optional": true },
+				{ "name": "sspn", "type":"string", "optional": true } // bounding box?
+			]
+		},
+
+		"videoSearch": {
+			"target": "http://ajax.googleapis.com/ajax/services/search/video",
+			"parameters": [
+				// ordering, set "d" to order by date, "default": by relevance
+				{ "name": "scoring", "type": "string", "optional": true }
+			]
+		},
+
+		"blogSearch": {
+			"target": "http://ajax.googleapis.com/ajax/services/search/blogs",
+			"parameters": [
+				// see videoSearch params
+				{ "name": "scoring", "type": "string", "optional": true }
+			]
+		},
+
+		"newsSearch": {
+			"target": "http://ajax.googleapis.com/ajax/services/search/news",
+			"parameters": [
+				{ "name": "scoring", "type": "string", "optional": true },
+				// geo: scope search to location. supply city, state, country, or zipcode
+				// using geo makes "q" param optional
+				{ "name": "geo", "type":"string", optional:true }
+			]
+		},
+
+		"bookSearch": {
+			"target": "http://ajax.googleapis.com/ajax/services/search/books",
+			"parameters": [
+				// set to "1" to only include full books
+				{ "name":"as_brr", "optional": true, "type":"number" },
+				// restrict search to user-defined library
+				{ "name":"as_list", "optional": true, "type":"string" }
+			]
+		},
+
+		"imageSearch": {
+			"target": "http://ajax.googleapis.com/ajax/services/search/images",
+			"parameters": [
+				// safe: active | moderate | off
+				{ "name": "safe", "type":"string", "optional":true }, 
+				// limit image size: one of: icon, small|medium|large|xlarge, xxlarge, huge
+				{ "name": "imgsz", "type":"string", "optional": true },
+				// limit image color: one of: mono|gray|color
+				{ "name": "imgc", "type":"string", "optional": true },
+				// use "face" to limit to mugshots
+				{ "name": "imgtype", "type":"string", "optional": true },
+				// limit to file "type": jpg|png|gif|bmp
+				{ "name": "as_filetype", "type": "string", "optional": true },
+				// limit results to domain:
+				{ "name": "as_sitesearch", "type": "string", "optional": true }
+			]
+		},
+
+		"getFeed": {
+			"target": "http://ajax.googleapis.com/ajax/services/feed/load",
+			// pass a feed URL in the q parameter
+			"parameters": []
+		},
+		
+		"translate" : {
+			"target" : "http://ajax.googleapis.com/ajax/services/language/translate",
+			"parameters": [
+				// A String like "en|es" (for english -> spanish)
+				{ "name":"langpair", "type":"string", optional:false }
+			]
+		}
+		
+	}
+}
diff --git a/dojox/rpc/SMDLibrary/wikipedia.smd b/dojox/rpc/SMDLibrary/wikipedia.smd
new file mode 100644
index 0000000..ffc94a4
--- /dev/null
+++ b/dojox/rpc/SMDLibrary/wikipedia.smd
@@ -0,0 +1,49 @@
+{
+	"SMDVersion": "2.0",
+	"id": "http://en.wikipedia.org/w/api.php",
+	"description": "Wikipedia API",
+
+	transport: "JSONP",
+	envelope: "URL",
+	additionalParameters: true,
+	target: "http://en.wikipedia.org/w/api.php",
+	parameters: [
+		{ name: "format", optional: false, "default": "json" }
+	],
+
+	services: {
+
+		/*
+		 * This is a very very basic spec that just gives us a free-form API
+		 * endpoint to talk to. See http://en.wikipedia.org/w/api.php for
+		 * details on what parameters to supply and what sort of data you
+		 * should expect to see. Note that returned JSON is often somewhat
+		 * ... interesting ...:
+		 *
+		 * {
+		 *     "parse": {
+		 *         "text": {
+		 *             "*": "<table ..."
+		 *         },
+		 *         "langlinks": [
+		 *             {
+		 *                 "lang": "simple",
+		 *                 "*": ""
+		 *             },
+		 *             // etc.
+		 *         ]
+		 *     }
+		 * }
+		 * 
+		 * Not sure why we'd ever want an element to be named "*", but that's
+		 * how it is. So take care.
+		 *
+		 */
+		query: {
+			parameters: [
+				{ name: "action", type: "string", "default": "parse" }
+			]
+		}
+
+	}
+}
diff --git a/dojox/rpc/SMDLibrary/yahoo.smd b/dojox/rpc/SMDLibrary/yahoo.smd
new file mode 100644
index 0000000..20f936f
--- /dev/null
+++ b/dojox/rpc/SMDLibrary/yahoo.smd
@@ -0,0 +1,497 @@
+{
+	"SMDVersion": "2.0",
+	// FIXME: is this the kind of value we're supposed to use here?
+	"id": "http://developer.yahoo.com/search/", 
+	"description": "Yahoo's search API",
+
+	transport: "JSONP",
+	envelope: "URL",
+	additionalParameters: true,
+	parameters: [
+		{ name: "appid", optional: false, "default": "dojotoolkit" },
+		{ name: "output", optional: false, "default": "json" }
+	],
+
+	// FIXME: Quite a few of these APIs can take multiple entries for the same parameter, to behave
+	//        as multi-select options. How should we handle these?
+	
+	// ANSWER: JSON Schema defines this aspect of SMD, enumeration of possible values is handled
+	//	with an "options" attribute. For example:
+	//	{ name: "search_in", type: "string", optional: true, "default": "all", options:["all", "question", "best_answer"]}, // can be "all", "question", "best_answer"
+
+	services: {
+		//
+		// ANSWERS
+		//
+		// FIXME: Some of these API endpoints' names only make sense when you know they're in the
+		//        Yahoo Answers part of the API; just reading a flat listing of methods in this SMD
+		//        likely won't have enough information about what they do. Should we split this up?
+
+		// http://developer.yahoo.com/answers/V1/questionSearch.html
+		questionSearch: {
+			target: "http://answers.yahooapis.com/AnswersService/V1/questionSearch",
+			parameters: [
+				{ name: "query", type: "string", optional: false, "default": "" },
+				{ name: "search_in", type: "string", optional: true, "default": "all" }, // can be "all", "question", "best_answer"
+				{ name: "category_id", type: "integer", optional: true, "default": null }, // one of (category_id, category_name) is required
+				{ name: "category_name", type: "string", optional: true, "default": null },
+				{ name: "region", type: "string", optional: true, "default": "us" }, // can be "us", "uk", "ca", "au", "in", "es", "br", "ar", "mx", "e1", "it", "de", "fr", "sg"
+				{ name: "date_range", type: "string", optional: true, "default": "all" }, // can be "all", "7", "7-30", "30-60", "60-90", "more90"
+				{ name: "sort", type: "string", optional: true, "default": "relevance" }, // can be "relevance", "date_desc", "date_asc"
+				{ name: "type", type: "string", optional: true, "default": "all" }, // can be "all", "resolved", "open", "undecided"
+				{ name: "start", type: "integer", optional: true, "default": 0 },
+				{ name: "results", type: "integer", optional: true, "default": 10 } // max 50
+			]
+		},
+
+		// http://developer.yahoo.com/answers/V1/getByCategory.html
+		getByCategory: {
+			target: "http://answers.yahooapis.com/AnswersService/V1/getByCategory",
+			parameters: [
+				{ name: "category_id", type: "integer", optional: true, "default": null }, // one of (category_id, category_name) is required
+				{ name: "category_name", type: "string", optional: true, "default": null },
+				{ name: "type", type: "string", optional: true, "default": "all" }, // can be "all", "resolved", "open", "undecided"
+				{ name: "region", type: "string", optional: true, "default": "us" }, // can be "us", "uk", "ca", "au", "in", "es", "br", "ar", "mx", "e1", "it", "de", "fr", "sg"
+				{ name: "sort", type: "string", optional: true, "default": "date_desc" }, // can be "date_desc", "date_asc", "ans_count_desc", "ans_count_asc"
+				{ name: "start", type: "integer", optional: true, "default": 0 },
+				{ name: "results", type: "integer", optional: true, "default": 10 } // max 50
+			]
+		},
+
+		// http://developer.yahoo.com/answers/V1/getQuestion.html
+		getQuestion: {
+			target: "http://answers.yahooapis.com/AnswersService/V1/getQuestion",
+			parameters: [
+				{ name: "question_id", type: "string", optional: true, "default": null }
+			]
+		},
+
+		// http://developer.yahoo.com/answers/V1/getByUser.html
+		getByUser: {
+			target: "http://answers.yahooapis.com/AnswersService/V1/getByUser",
+			parameters: [
+				{ name: "user_id", type: "string", optional: false, "default": "" },
+				{ name: "type", type: "string", optional: true, "default": "all" }, // can be "all", "resolved", "open", "undecided"
+				{ name: "filter", type: "string", optional: true, "default": "question" }, // can be "question", "answer", "best_answer"
+				{ name: "sort", type: "string", optional: true, "default": "date_desc" }, // can be "date_desc", "date_asc", "ans_count_desc", "ans_count_asc"
+				{ name: "start", type: "integer", optional: true, "default": 0 },
+				{ name: "results", type: "integer", optional: true, "default": 10 } // max 50
+			]
+		},
+
+		//
+		// AUDIO SEARCH
+		//
+
+		// http://developer.yahoo.com/search/audio/V1/artistSearch.html
+		artistSearch: {
+			target: "http://search.yahooapis.com/AudioSearchService/V1/artistSearch",
+			parameters: [
+				{ name: "artist", type: "string", optional: true, "default": "" }, // one of (artist, artistid) is required
+				{ name: "artistid", type: "string", optional: true, "default": "" },
+				{ name: "type", type: "string", optional: true, "default": "all" }, // can be "all", "any", "phrase"
+				{ name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+				{ name: "start", type: "integer", optional: true, "default": 1 }
+			]
+		},
+
+		// http://developer.yahoo.com/search/audio/V1/albumSearch.html
+		albumSearch: {
+			target: "http://search.yahooapis.com/AudioSearchService/V1/albumSearch",
+			parameters: [
+				{ name: "artist", type: "string", optional: true, "default": "" },
+				{ name: "artistid", type: "string", optional: true, "default": "" },
+				{ name: "album", type: "string", optional: true, "default": "" },
+				{ name: "albumid", type: "string", optional: true, "default": "" },
+				{ name: "type", type: "string", optional: true, "default": "all" }, // can be "all", "any", "phrase"
+				{ name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+				{ name: "start", type: "integer", optional: true, "default": 1 }
+			]
+		},
+
+		// http://developer.yahoo.com/search/audio/V1/songSearch.html
+		songSearch: {
+			// beware, this method has returned many a JSON string containing syntax error(s)
+			target: "http://search.yahooapis.com/AudioSearchService/V1/songSearch",
+			parameters: [
+				{ name: "artist", type: "string", optional: true, "default": "" },
+				{ name: "artistid", type: "string", optional: true, "default": "" },
+				{ name: "album", type: "string", optional: true, "default": "" },
+				{ name: "albumid", type: "string", optional: true, "default": "" },
+				{ name: "song", type: "string", optional: true, "default": "" },
+				{ name: "songid", type: "string", optional: true, "default": "" },
+				{ name: "type", type: "string", optional: true, "default": "all" }, // can be "all", "any", "phrase"
+				{ name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+				{ name: "start", type: "integer", optional: true, "default": 1 }
+			]
+		},
+
+		// http://developer.yahoo.com/search/audio/V1/songDownloadLocation.html
+		songDownloadLocation: {
+			target: "http://search.yahooapis.com/AudioSearchService/V1/songDownloadLocation",
+			parameters: [
+				{ name: "songid", type: "string", optional: false, "default": "" },
+				{ name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+				{ name: "start", type: "integer", optional: true, "default": 1 },
+				{ name: "source", type: "string", optional: true, "default": "" } // can be "audiolunchbox", "artistdirect", "buymusic", "dmusic", "emusic", "epitonic", "garageband", "itunes", "yahoo", "livedownloads", "mp34u", "msn", "musicmatch", "mapster", "passalong", "rhapsody", "soundclick", "theweb"
+			]
+		},
+
+		//
+		// CONTENT ANALYSIS
+		//
+		
+		// http://developer.yahoo.com/search/content/V1/termExtraction.html
+		contextSearch: {
+			// FIXME: the API docs say to submit this as a POST, but we need JSONP for cross-domain, right?
+			// transport: "POST",
+			target: "http://search.yahooapis.com/ContentAnalysisService/V1/termExtraction",
+			parameters: [
+				{ name: "context", type: "string", optional: false, "default": "" },
+				{ name: "query", type: "string", optional: true, "default": "" }
+			]
+		},
+
+		//
+		// IMAGE SEARCH
+		//
+
+		// http://developer.yahoo.com/search/image/V1/imageSearch.html
+		imageSearch: {
+			target: "http://search.yahooapis.com/ImageSearchService/V1/imageSearch",
+			parameters: [
+				{ name: "query", type: "string", optional: false, "default": "" },
+				{ name: "type", type: "string", optional: true, "default": "any" }, // can be "all", "any", "phrase"
+				{ name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+				{ name: "start", type: "integer", optional: true, "default": 1 },
+				{ name: "format", type: "string", optional: true, "default": "any" }, // can be "any", "bmp", "gif", "jpeg", "png"
+				{ name: "adult_ok", type: "boolean", optional: true, "default": null },
+				{ name: "coloration", type: "string", optional: true, "default": "any" }, // can be "any", "color", "bw"
+				{ name: "site", type: "string", optional: true, "default": null }
+			]
+		},
+
+		//
+		// LOCAL SEARCH
+		//
+
+		// http://developer.yahoo.com/search/local/V3/localSearch.html
+		localSearch: {
+			target: "http://local.yahooapis.com/LocalSearchService/V3/localSearch",
+			parameters: [
+				{ name: "query", type: "string", optional: true, "default": "" }, // optional, but one of (query, listing_id) is required
+				{ name: "listing_id", type: "string", optional: true, "default": "" },
+				{ name: "results", type: "integer", optional: true, "default": 10 }, // max 20
+				{ name: "start", type: "integer", optional: true, "default": 1 },
+				{ name: "sort", type: "string", optional: true, "default": "relevance" }, // can be "relevance", "title", "distance", "rating"
+				{ name: "radius", type: "float", optional: true }, // the default varies according to location
+				{ name: "street", type: "string", optional: true, "default": null },
+				{ name: "city", type: "string", optional: true, "default": null },
+				{ name: "state", type: "string", optional: true, "default": null }, // full name or two-letter abbreviation
+				{ name: "zip", type: "any", optional: true, "default": null }, // ddddd or ddddd-dddd format
+				{ name: "location", type: "string", optional: true, "default": null }, // free text, supersedes the street, city, state, zip fields
+				{ name: "latitude", type: "float", optional: true }, // -90 to 90
+				{ name: "longitude", type: "float", optional: true }, // -180 to 180
+				{ name: "category", type: "integer", optional: true },
+				{ name: "omit_category", type: "integer", optional: true },
+				{ name: "minimum_rating", type: "integer", optional: true }
+			]
+		},
+
+		// http://developer.yahoo.com/local/V1/collectionSearch.html
+		collectionSearch: {
+			target: "http://collections.local.yahooapis.com/LocalSearchService/V1/collectionSearch",
+			parameters: [
+				{ name: "query", type: "string", optional: true, "default": "" }, // optional, but at least one of (query, username) is required
+				{ name: "username", type: "string", optional: true, "default": "" },
+				{ name: "city", type: "string", optional: true, "default": null },
+				{ name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+				{ name: "start", type: "integer", optional: true, "default": 1 }
+			]
+		},
+
+		// http://developer.yahoo.com/local/V1/getCollection.html
+		getCollection: {
+			target: "http://collections.local.yahooapis.com/LocalSearchService/V1/getCollection",
+			parameters: [
+				{ name: "collection_id", type: "integer", optional: false, "default": "" }
+			]
+		},
+
+		//
+		// MY WEB 2.0
+		//
+
+		// http://developer.yahoo.com/search/myweb/V1/urlSearch.html
+		urlSearch: {
+			target: "http://search.yahooapis.com/MyWebService/V1/urlSearch",
+			parameters: [
+				{ name: "tag", type: "string", optional: true, "default": "" },
+				{ name: "yahooid", type: "string", optional: true, "default": "" },
+				{ name: "sort", type: "string", optional: true, "default": "date" }, // can be "date", "title", "url"
+				{ name: "reverse_sort", type: "boolean", optional: true, "default": 0 },
+				{ name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+				{ name: "start", type: "integer", optional: true, "default": 1 }
+			]
+		},
+
+		// http://developer.yahoo.com/search/myweb/V1/tagSearch.html
+		tagSearch: {
+			target: "http://search.yahooapis.com/MyWebService/V1/tagSearch",
+			parameters: [
+				{ name: "url", type: "string", optional: true, "default": "" },
+				{ name: "yahooid", type: "string", optional: true, "default": "" },
+				{ name: "sort", type: "string", optional: true, "default": "popularity" }, // can be "popularity", "tag", "date"
+				{ name: "reverse_sort", type: "boolean", optional: true, "default": 0 },
+				{ name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+				{ name: "start", type: "integer", optional: true, "default": 1 }
+			]
+		},
+
+		// http://developer.yahoo.com/search/myweb/V1/relatedTags.html
+		relatedTags: {
+			target: "http://search.yahooapis.com/MyWebService/V1/relatedTags",
+			parameters: [
+				{ name: "tag", type: "string", optional: false, "default": "" },
+				{ name: "yahooid", type: "string", optional: true, "default": "" },
+				{ name: "sort", type: "string", optional: true, "default": "popularity" }, // can be "popularity", "tag", "date"
+				{ name: "reverse_sort", type: "boolean", optional: true, "default": 0 },
+				{ name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+				{ name: "start", type: "integer", optional: true, "default": 1 }
+			]
+		},
+
+		//
+		// NEWS SEARCH
+		//
+
+		// http://developer.yahoo.com/search/news/V1/newsSearch.html
+		newsSearch: {
+			target: "http://search.yahooapis.com/NewsSearchService/V1/newsSearch",
+			parameters: [
+				{ name: "query", type: "string", optional: false, "default": "" },
+				{ name: "type", type: "string", optional: true, "default": "any" }, // can be "all", "any", "phrase"
+				{ name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+				{ name: "start", type: "integer", optional: true, "default": 1 },
+				{ name: "sort", type: "string", optional: true, "default": "rank" }, // can be "rank", "date"
+				{ name: "language", type: "string", optional: true, "default": null },
+				{ name: "site", type: "string", optional: true, "default": null }
+			]
+		},
+
+		//
+		// SHOPPING
+		//
+
+		// http://developer.yahoo.com/shopping/V2/catalogListing.html
+		catalogListing: {
+			target: "http://shopping.yahooapis.com/ShoppingService/V2/catalogListing",
+			parameters: [
+				{ name: "catalogid", type: "integer", optional: true, "default": null }, // required if idtype,idvalue are not specified
+				{ name: "getlisting", type: "boolean", optional: true, "default": 1 },
+				{ name: "getreview", type: "boolean", optional: true, "default": 0 },
+				{ name: "getspec", type: "boolean", optional: true, "default": 0 },
+				{ name: "idtype", type: "string", optional: true, "default": null }, // can be "upc", "brand,model", "brand,partnum"; required if catalogid is not specified
+				{ name: "idvalue", type: "string", optional: true, "default": null }, // required if catalogid is not specified
+				{ name: "onlynew", type: "boolean", optional: true, "default": 1 },
+				{ name: "reviewstart", type: "integer", optional: true, "default": 1 },
+				{ name: "reviewsort", type: "string", optional: true, "default": "mostRecommended_descending" }, // can be "mostRecommended_descending", "mostRecommended_ascending", "latest_descending", "latest_ascending", "highestRated_descending", "highestRated_ascending"
+				{ name: "zip", type: "string", optional: true, "default": null }
+			]
+		},
+
+
+		// http://developer.yahoo.com/shopping/V1/merchantSearch.html
+		merchantSearch: {
+			target: "http://api.shopping.yahoo.com/ShoppingService/V1/merchantSearch",
+			parameters: [
+				{ name: "merchantid", type: "integer", optional: false, "default": null }
+			]
+		},
+
+
+		// http://developer.yahoo.com/shopping/V3/productSearch.html
+		productSearch: {
+			target: "http://shopping.yahooapis.com/ShoppingService/V3/productSearch",
+			parameters: [
+				{ name: "query", type: "string", optional: true, "default": "" }, // required if category is not specified
+				{ name: "category", type: "any", optional: true, "default": "" }, // required if query is not specified
+				{ name: "class", type: "string", optional: true, "default": null }, // can be "catalogs", "freeoffers", "paidoffers"; defaults to all three of these
+				{ name: "department", type: "integer", optional: true, "default": null },
+				{ name: "highestprice", type: "float", optional: true, "default": null },
+				{ name: "lowestprice", type: "float", optional: true, "default": null },
+				{ name: "merchantId", type: "integer", optional: true, "default": null },
+				{ name: "refinement", type: "string", optional: true, "default": null }, // used only if category is specified
+				{ name: "results", type: "integer", optional: true, "default": 10 }, // 1-50
+				{ name: "show_numratings", type: "boolean", optional: true, "default": 0 },
+				{ name: "show_narrowing", type: "boolean", optional: true, "default": 1 },
+				{ name: "sort", type: "string", optional: true }, // can be "price_ascending", "price_descending", "userrating_ascending", "userrating_descending"; omitted, the default is to sort by relevance
+				{ name: "start", type: "integer", optional: true, "default": 1 } // 1-300
+			]
+		},
+
+		//
+		// SITE EXPLORER
+		//
+
+		// http://developer.yahoo.com/search/siteexplorer/V1/inlinkData.html
+		inlinkData: {
+			target: "http://search.yahooapis.com/SiteExplorerService/V1/inlinkData",
+			parameters: [
+				{ name: "query", type: "string", optional: false, "default": "" },
+				{ name: "results", type: "integer", optional: true, "default": 50 }, // max 100
+				{ name: "start", type: "integer", optional: true, "default": 1 },
+				{ name: "entire_site", type: "boolean", optional: true, "default": null },
+				{ name: "omit_inlinks", type: "string", optional: true, "default": "none" } // can be "none", "domain", "subdomain"
+			]
+		},
+
+		// http://developer.yahoo.com/search/siteexplorer/V1/pageData.html
+		pageData: {
+			target: "http://search.yahooapis.com/SiteExplorerService/V1/pageData",
+			parameters: [
+				{ name: "query", type: "string", optional: false, "default": "" },
+				{ name: "results", type: "integer", optional: true, "default": 50 }, // max 100
+				{ name: "start", type: "integer", optional: true, "default": 1 },
+				{ name: "domain_only", type: "boolean", optional: true, "default": null }
+			]
+		},
+
+		// http://developer.yahoo.com/search/siteexplorer/V1/ping.html
+		ping: {
+			target: "http://search.yahooapis.com/SiteExplorerService/V1/ping",
+			parameters: [
+				{ name: "sitemap", type: "string", optional: false, "default": "" }
+			]
+		},
+
+		// http://developer.yahoo.com/search/siteexplorer/V1/updateNotification.html
+		updateNotification: {
+			target: "http://search.yahooapis.com/SiteExplorerService/V1/updateNotification",
+			parameters: [
+				{ name: "url", type: "string", optional: false, "default": "" }
+			]
+		},
+
+		//
+		// TRAFFIC
+		//
+
+		// http://developer.yahoo.com/traffic/rest/V1/index.html
+		trafficData: {
+			target: "http://local.yahooapis.com/MapsService/V1/trafficData",
+			parameters: [
+				{ name: "street", type: "string", optional: true, "default": "" },
+				{ name: "city", type: "string", optional: true, "default": "" },
+				{ name: "state", type: "string", optional: true, "default": null }, // full name or two-letter abbreviation
+				{ name: "zip", type: "any", optional: true, "default": null }, // ddddd or ddddd-dddd format
+				{ name: "location", type: "string", optional: true, "default": null }, // free text, supersedes the street, city, state, zip fields
+				{ name: "latitude", type: "float", optional: true }, // -90 to 90
+				{ name: "longitude", type: "float", optional: true }, // -180 to 180
+				{ name: "severity", type: "integer", optional: true, "default": 1 }, // can be 1-5
+				{ name: "zoom", type: "integer", optional: true, "default": 6 }, // can be 1-12
+				{ name: "radius", type: "float", optional: true }, // in miles, default varies with location; ignored if zoom is specified
+				{ name: "include_map", type: "boolean", optional: true, "default": 0 },
+				{ name: "image_type", type: "string", optional: true, "default": "png" }, // can be "png" or "gif"
+				{ name: "image_height", type: "integer", optional: true, "default": 500 }, // in pixels, can be 10-2000
+				{ name: "image_width", type: "integer", optional: true, "default": 620 } // in pixels, can be 10-2000
+			]
+		},
+
+		//
+		// TRAVEL
+		//
+
+		// http://developer.yahoo.com/travel/tripservice/V1.1/tripSearch.html
+		tripSearch: {
+			target: "http://travel.yahooapis.com/TripService/V1.1/tripSearch",
+			parameters: [
+				{ name: "query", type: "string", optional: true, "default": "" },
+				{ name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+				{ name: "start", type: "integer", optional: true, "default": 1 }
+			]
+		},
+
+		// http://developer.yahoo.com/travel/tripservice/V1.1/getTrip.html
+		getTrip: {
+			target: "http://travel.yahooapis.com/TripService/V1.1/getTrip",
+			parameters: [
+				{ name: "id", type: "integer", optional: false, "default": null }
+			]
+		},
+
+		//
+		// UTILITY SERVICES
+		//
+
+		// http://developer.yahoo.com/util/timeservice/V1/getTime.html
+		/* RGG: commented out because it refuses to return JSON format even when you tell it
+		        to do so (it returns a <script> tag)
+		getTime: {
+			target: "http://developer.yahooapis.com/TimeService/V1/getTime",
+			parameters: [
+				{ name: "format", type: "string", optional: true, "default": "unix" } // can be "unix" for unix timestamp, "ms" for milliseconds
+			]
+		},
+		*/
+
+		//
+		// VIDEO SEARCH
+		//
+
+		// http://developer.yahoo.com/search/video/V1/videoSearch.html
+		videoSearch: {
+			target: "http://search.yahooapis.com/VideoSearchService/V1/videoSearch",
+			parameters: [
+				{ name: "query", type: "string", optional: false, "default": "" },
+				{ name: "type", type: "string", optional: true, "default": "any" }, // can be "all", "any", "phrase"
+				{ name: "results", type: "integer", optional: true, "default": 10 }, // max 50
+				{ name: "start", type: "integer", optional: true, "default": 1 },
+				{ name: "format", type: "string", optional: true, "default": "any" }, // can be "any", "avi", "flash", "mpeg", "msmedia", "quicktime", "realmedia"
+				{ name: "adult_ok", type: "boolean", optional: true, "default": null },
+				{ name: "site", type: "string", optional: true, "default": null }
+			]
+		},
+
+		//
+		// WEB SEARCH
+		//
+
+		// http://developer.yahoo.com/search/web/V1/webSearch.html
+		webSearch: {
+			target: "http://search.yahooapis.com/WebSearchService/V1/webSearch",
+			parameters: [
+				{ name: "query", type: "string", optional: false, "default": "" }, // must be less than 1kb
+				{ name: "region", type: "string", optional: true, "default": "us" },
+				{ name: "type", type: "string", optional: true, "default": "any" }, // can be "all", "any", "phrase"
+				{ name: "results", type: "integer", optional: true, "default": 10 }, // max 100
+				{ name: "start", type: "integer", optional: true, "default": 1 },
+				{ name: "format", type: "string", optional: true, "default": "any" }, // can be "any", "html", "msword", "pdf", "ppt", "rss", "txt", "xls"
+				{ name: "adult_ok", type: "boolean", optional: true, "default": null },
+				{ name: "similar_ok", type: "boolean", optional: true, "default": null },
+				{ name: "language", type: "string", optional: true, "default": null },
+				{ name: "country", type: "string", optional: true, "default": null },
+				{ name: "site", type: "string", optional: true, "default": null },
+				{ name: "subscription", type: "string", optional: true, "default": null },
+				{ name: "license", type: "string", optional: true, "default": "any" } // can be "any", "cc_any", "cc_commercial", "cc_modifiable"
+			]
+		},
+
+		// http://developer.yahoo.com/search/web/V1/spellingSuggestion.html
+		spellingSuggestion: {
+			target: "http://search.yahooapis.com/WebSearchService/V1/spellingSuggestion",
+			parameters: [
+				{ name: "query", type: "string", optional: false, "default": "" }
+			]
+		},
+
+		// http://developer.yahoo.com/search/web/V1/relatedSuggestion.html
+		relatedSuggestion: {
+			target: "http://search.yahooapis.com/WebSearchService/V1/relatedSuggestion",
+			parameters: [
+				{ name: "query", type: "string", optional: false, "default": "" },
+				{ name: "results", type: "integer", optional: true, "default": 10 } // max 50
+			]
+		}
+	}
+}
diff --git a/dojox/rpc/Service.js b/dojox/rpc/Service.js
new file mode 100644
index 0000000..b7ca289
--- /dev/null
+++ b/dojox/rpc/Service.js
@@ -0,0 +1,217 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.rpc.Service"]){
+dojo._hasResource["dojox.rpc.Service"]=true;
+dojo.provide("dojox.rpc.Service");
+dojo.require("dojo.AdapterRegistry");
+dojo.declare("dojox.rpc.Service",null,{constructor:function(_1,_2){
+var _3;
+var _4=this;
+function _5(_6){
+_6._baseUrl=new dojo._Url(location.href,_3||".")+"";
+_4._smd=_6;
+for(var _7 in _4._smd.services){
+var _8=_7.split(".");
+var _9=_4;
+for(var i=0;i<_8.length-1;i++){
+_9=_9[_8[i]]||(_9[_8[i]]={});
+}
+_9[_8[_8.length-1]]=_4._generateService(_7,_4._smd.services[_7]);
+}
+};
+if(_1){
+if((dojo.isString(_1))||(_1 instanceof dojo._Url)){
+if(_1 instanceof dojo._Url){
+_3=_1+"";
+}else{
+_3=_1;
+}
+var _b=dojo._getText(_3);
+if(!_b){
+throw new Error("Unable to load SMD from "+_1);
+}else{
+_5(dojo.fromJson(_b));
+}
+}else{
+_5(_1);
+}
+}
+this._options=(_2?_2:{});
+this._requestId=0;
+},_generateService:function(_c,_d){
+if(this[_d]){
+throw new Error("WARNING: "+_c+" already exists for service. Unable to generate function");
+}
+_d.name=_c;
+var _e=dojo.hitch(this,"_executeMethod",_d);
+var _f=dojox.rpc.transportRegistry.match(_d.transport||this._smd.transport);
+if(_f.getExecutor){
+_e=_f.getExecutor(_e,_d,this);
+}
+var _10=_d.returns||(_d._schema={});
+var _11="/"+_c+"/";
+_10._service=_e;
+_e.servicePath=_11;
+_e._schema=_10;
+_e.id=dojox.rpc.Service._nextId++;
+return _e;
+},_getRequest:function(_12,_13){
+var smd=this._smd;
+var _15=dojox.rpc.envelopeRegistry.match(_12.envelope||smd.envelope||"NONE");
+if(_15.namedParams){
+if((_13.length==1)&&dojo.isObject(_13[0])){
+_13=_13[0];
+}else{
+var _16={};
+for(var i=0;i<_12.parameters.length;i++){
+if(typeof _13[i]!="undefined"||!_12.parameters[i].optional){
+_16[_12.parameters[i].name]=_13[i];
+}
+}
+_13=_16;
+}
+var _18=(_12.parameters||[]).concat(smd.parameters||[]);
+if(_12.strictParameters||smd.strictParameters){
+for(i in _13){
+var _19=false;
+for(var j=0;j<_18.length;j++){
+if(_18[i].name==i){
+_19=true;
+}
+}
+if(!_19){
+delete _13[i];
+}
+}
+}
+for(i=0;i<_18.length;i++){
+var _1b=_18[i];
+if(!_1b.optional&&_1b.name&&!_13[_1b.name]){
+if(_1b["default"]){
+_13[_1b.name]=_1b["default"];
+}else{
+if(!(_1b.name in _13)){
+throw new Error("Required parameter "+_1b.name+" was omitted");
+}
+}
+}
+}
+}else{
+if(_12.parameters&&_12.parameters[0]&&_12.parameters[0].name&&(_13.length==1)&&dojo.isObject(_13[0])){
+if(_15.namedParams===false){
+_13=dojox.rpc.toOrdered(_12,_13);
+}else{
+_13=_13[0];
+}
+}
+}
+if(dojo.isObject(this._options)){
+_13=dojo.mixin(_13,this._options);
+}
+var _1c=_12._schema||_12.returns;
+var _1d=_15.serialize.apply(this,[smd,_12,_13]);
+_1d._envDef=_15;
+var _1e=(_12.contentType||smd.contentType||_1d.contentType);
+return dojo.mixin(_1d,{sync:dojox.rpc._sync,contentType:_1e,headers:{},target:_1d.target||dojox.rpc.getTarget(smd,_12),transport:_12.transport||smd.transport||_1d.transport,envelope:_12.envelope||smd.envelope||_1d.envelope,timeout:_12.timeout||smd.timeout,callbackParamName:_12.callbackParamName||smd.callbackParamName,schema:_1c,handleAs:_1d.handleAs||"auto",preventCache:_12.preventCache||smd.preventCache,frameDoc:this._options.frameDoc||undefined});
+},_executeMethod:function(_1f){
+var _20=[];
+var i;
+for(i=1;i<arguments.length;i++){
+_20.push(arguments[i]);
+}
+var _22=this._getRequest(_1f,_20);
+var _23=dojox.rpc.transportRegistry.match(_22.transport).fire(_22);
+_23.addBoth(function(_24){
+return _22._envDef.deserialize.call(this,_24);
+});
+return _23;
+}});
+dojox.rpc.getTarget=function(smd,_26){
+var _27=smd._baseUrl;
+if(smd.target){
+_27=new dojo._Url(_27,smd.target)+"";
+}
+if(_26.target){
+_27=new dojo._Url(_27,_26.target)+"";
+}
+return _27;
+};
+dojox.rpc.toOrdered=function(_28,_29){
+if(dojo.isArray(_29)){
+return _29;
+}
+var _2a=[];
+for(var i=0;i<_28.parameters.length;i++){
+_2a.push(_29[_28.parameters[i].name]);
+}
+return _2a;
+};
+dojox.rpc.transportRegistry=new dojo.AdapterRegistry(true);
+dojox.rpc.envelopeRegistry=new dojo.AdapterRegistry(true);
+dojox.rpc.envelopeRegistry.register("URL",function(str){
+return str=="URL";
+},{serialize:function(smd,_2e,_2f){
+var d=dojo.objectToQuery(_2f);
+return {data:d,transport:"POST"};
+},deserialize:function(_31){
+return _31;
+},namedParams:true});
+dojox.rpc.envelopeRegistry.register("JSON",function(str){
+return str=="JSON";
+},{serialize:function(smd,_34,_35){
+var d=dojo.toJson(_35);
+return {data:d,handleAs:"json",contentType:"application/json"};
+},deserialize:function(_37){
+return _37;
+}});
+dojox.rpc.envelopeRegistry.register("PATH",function(str){
+return str=="PATH";
+},{serialize:function(smd,_3a,_3b){
+var i;
+var _3d=dojox.rpc.getTarget(smd,_3a);
+if(dojo.isArray(_3b)){
+for(i=0;i<_3b.length;i++){
+_3d+="/"+_3b[i];
+}
+}else{
+for(i in _3b){
+_3d+="/"+i+"/"+_3b[i];
+}
+}
+return {data:"",target:_3d};
+},deserialize:function(_3e){
+return _3e;
+}});
+dojox.rpc.transportRegistry.register("POST",function(str){
+return str=="POST";
+},{fire:function(r){
+r.url=r.target;
+r.postData=r.data;
+return dojo.rawXhrPost(r);
+}});
+dojox.rpc.transportRegistry.register("GET",function(str){
+return str=="GET";
+},{fire:function(r){
+r.url=r.target+(r.data?"?"+r.data:"");
+return dojo.xhrGet(r);
+}});
+dojox.rpc.transportRegistry.register("JSONP",function(str){
+return str=="JSONP";
+},{fire:function(r){
+r.url=r.target+((r.target.indexOf("?")==-1)?"?":"&")+r.data;
+r.callbackParamName=r.callbackParamName||"callback";
+return dojo.io.script.get(r);
+}});
+dojox.rpc.Service._nextId=1;
+dojo._contentHandlers.auto=function(xhr){
+var _46=dojo._contentHandlers;
+var _47=xhr.getResponseHeader("Content-Type");
+var _48=!_47?_46.text(xhr):_47.match(/\/.*json/)?_46.json(xhr):_47.match(/\/javascript/)?_46.javascript(xhr):_47.match(/\/xml/)?_46.xml(xhr):_46.text(xhr);
+return _48;
+};
+}
diff --git a/dojox/rpc/test.txt b/dojox/rpc/test.txt
new file mode 100644
index 0000000..0478a6a
--- /dev/null
+++ b/dojox/rpc/test.txt
@@ -0,0 +1 @@
+this is a test file i'm updating. Again, 11.
diff --git a/dojox/secure/DOM.js b/dojox/secure/DOM.js
new file mode 100644
index 0000000..c09a1bc
--- /dev/null
+++ b/dojox/secure/DOM.js
@@ -0,0 +1,235 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.secure.DOM"]){
+dojo._hasResource["dojox.secure.DOM"]=true;
+dojo.provide("dojox.secure.DOM");
+dojo.require("dojox.lang.observable");
+dojox.secure.DOM=function(_1){
+function _2(_3){
+if(!_3){
+return _3;
+}
+var _4=_3;
+do{
+if(_4==_1){
+return _5(_3);
+}
+}while((_4=_4.parentNode));
+return null;
+};
+function _5(_6){
+if(_6){
+if(_6.nodeType){
+var _7=_8(_6);
+if(_6.nodeType==1&&typeof _7.style=="function"){
+_7.style=_9(_6.style);
+_7.ownerDocument=_a;
+_7.childNodes={__get__:function(i){
+return _5(_6.childNodes[i]);
+},length:0};
+}
+return _7;
+}
+if(_6&&typeof _6=="object"){
+if(_6.__observable){
+return _6.__observable;
+}
+_7=_6 instanceof Array?[]:{};
+_6.__observable=_7;
+for(var i in _6){
+if(i!="__observable"){
+_7[i]=_5(_6[i]);
+}
+}
+_7.data__=_6;
+return _7;
+}
+if(typeof _6=="function"){
+var _d=function(_e){
+if(typeof _e=="function"){
+return function(){
+for(var i=0;i<arguments.length;i++){
+arguments[i]=_5(arguments[i]);
+}
+return _d(_e.apply(_5(this),arguments));
+};
+}
+return dojox.secure.unwrap(_e);
+};
+return function(){
+if(_6.safetyCheck){
+_6.safetyCheck.apply(_d(this),arguments);
+}
+for(var i=0;i<arguments.length;i++){
+arguments[i]=_d(arguments[i]);
+}
+return _5(_6.apply(_d(this),arguments));
+};
+}
+}
+return _6;
+};
+unwrap=dojox.secure.unwrap;
+function _11(css){
+css+="";
+if(css.match(/behavior:|content:|javascript:|binding|expression|\@import/)){
+throw new Error("Illegal CSS");
+}
+var id=_1.id||(_1.id="safe"+(""+Math.random()).substring(2));
+return css.replace(/(\}|^)\s*([^\{]*\{)/g,function(t,a,b){
+return a+" #"+id+" "+b;
+});
+};
+function _17(url){
+if(url.match(/:/)&&!url.match(/^(http|ftp|mailto)/)){
+throw new Error("Unsafe URL "+url);
+}
+};
+function _19(el){
+if(el&&el.nodeType==1){
+if(el.tagName.match(/script/i)){
+var src=el.src;
+if(src&&src!=""){
+el.parentNode.removeChild(el);
+dojo.xhrGet({url:src,secure:true}).addCallback(function(_1c){
+_a.evaluate(_1c);
+});
+}else{
+var _1d=el.innerHTML;
+el.parentNode.removeChild(el);
+_5.evaluate(_1d);
+}
+}
+if(el.tagName.match(/link/i)){
+throw new Error("illegal tag");
+}
+if(el.tagName.match(/style/i)){
+var _1e=function(_1f){
+if(el.styleSheet){
+el.styleSheet.cssText=_1f;
+}else{
+var _20=doc.createTextNode(_1f);
+if(el.childNodes[0]){
+el.replaceChild(_20,el.childNodes[0]);
+}else{
+el.appendChild(_20);
+}
+}
+};
+src=el.src;
+if(src&&src!=""){
+alert("src"+src);
+el.src=null;
+dojo.xhrGet({url:src,secure:true}).addCallback(function(_21){
+_1e(_11(_21));
+});
+}
+_1e(_11(el.innerHTML));
+}
+if(el.style){
+_11(el.style.cssText);
+}
+if(el.href){
+_17(el.href);
+}
+if(el.src){
+_17(el.src);
+}
+var _22,i=0;
+while((_22=el.attributes[i++])){
+if(_22.name.substring(0,2)=="on"&&_22.value!="null"&&_22.value!=""){
+throw new Error("event handlers not allowed in the HTML, they must be set with element.addEventListener");
+}
+}
+var _24=el.childNodes;
+for(var i=0,l=_24.length;i<l;i++){
+_19(_24[i]);
+}
+}
+};
+function _26(_27){
+var div=document.createElement("div");
+if(_27.match(/<object/i)){
+throw new Error("The object tag is not allowed");
+}
+div.innerHTML=_27;
+_19(div);
+return div;
+};
+var doc=_1.ownerDocument;
+var _a={getElementById:function(id){
+return _2(doc.getElementById(id));
+},createElement:function(_2b){
+return _5(doc.createElement(_2b));
+},createTextNode:function(_2c){
+return _5(doc.createTextNode(_2c));
+},write:function(str){
+var div=_26(str);
+while(div.childNodes.length){
+_1.appendChild(div.childNodes[0]);
+}
+}};
+_a.open=_a.close=function(){
+};
+var _2f={innerHTML:function(_30,_31){
+
+_30.innerHTML=_26(_31).innerHTML;
+}};
+_2f.outerHTML=function(_32,_33){
+throw new Error("Can not set this property");
+};
+function _34(_35,_36){
+return function(_37,_38){
+_19(_38[_36]);
+return _37[_35](_38[0]);
+};
+};
+var _39={appendChild:_34("appendChild",0),insertBefore:_34("insertBefore",0),replaceChild:_34("replaceChild",1),cloneNode:function(_3a,_3b){
+return _3a.cloneNode(_3b[0]);
+},addEventListener:function(_3c,_3d){
+dojo.connect(_3c,"on"+_3d[0],this,function(_3e){
+_3e=_8(_3e||window.event);
+_3d[1].call(this,_3e);
+});
+}};
+_39.childNodes=_39.style=_39.ownerDocument=function(){
+};
+function _3f(_40){
+return dojox.lang.makeObservable(function(_41,_42){
+var _43;
+return _41[_42];
+},_40,function(_44,_45,_46,_47){
+for(var i=0;i<_47.length;i++){
+_47[i]=unwrap(_47[i]);
+}
+if(_39[_46]){
+return _5(_39[_46].call(_44,_45,_47));
+}
+return _5(_45[_46].apply(_45,_47));
+},_39);
+};
+var _8=_3f(function(_49,_4a,_4b){
+if(_2f[_4a]){
+_2f[_4a](_49,_4b);
+}
+_49[_4a]=_4b;
+});
+var _4c={behavior:1,MozBinding:1};
+var _9=_3f(function(_4d,_4e,_4f){
+if(!_4c[_4e]){
+_4d[_4e]=_11(_4f);
+}
+});
+_5.safeHTML=_26;
+_5.safeCSS=_11;
+return _5;
+};
+dojox.secure.unwrap=function unwrap(_50){
+return (_50&&_50.data__)||_50;
+};
+}
diff --git a/dojox/secure/README b/dojox/secure/README
new file mode 100644
index 0000000..283c829
--- /dev/null
+++ b/dojox/secure/README
@@ -0,0 +1,50 @@
+-------------------------------------------------------------------------------
+DojoX Secure
+-------------------------------------------------------------------------------
+Version 0.1
+Release date: 07/04/2008
+-------------------------------------------------------------------------------
+Project state:
+alpha
+-------------------------------------------------------------------------------
+Project authors
+	Kris Zyp (kris at sitepen.com)
+-------------------------------------------------------------------------------
+Project description
+
+DojoX Secure is a collection of tools for security, in particular for working with
+untrusted data and code. The following tools are a part of DojoX Secure:
+
+dojox.secure.capability - Object-capability JavaScript validation. This is 
+a validator to run before eval to ensure that a script can't access or modify
+any objects outside of those specifically provided to it.
+
+dojox.secure.sandbox - Provides support for loading web pages, JSON, and scripts 
+from other domains using XHR (and XHR plugins) with a safe subset library and 
+sandboxed access to the DOM.
+
+dojox.secure.DOM - Provides a DOM facade that restricts access to
+a specified subtree of the DOM. The DOM facade uses getters/setters
+and lettables to emulate the DOM API.
+
+dojox.secure.OAuth - Future project to provide an implementation of OAuth.
+
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo Core (package loader).
+-------------------------------------------------------------------------------
+Documentation
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/secure/*
+
+Install into the following directory structure:
+/dojox/secure/
+
+...which should be at the same level as your Dojo checkout.
+
diff --git a/dojox/secure/capability.js b/dojox/secure/capability.js
new file mode 100644
index 0000000..2ec3785
--- /dev/null
+++ b/dojox/secure/capability.js
@@ -0,0 +1,102 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.secure.capability"]){
+dojo._hasResource["dojox.secure.capability"]=true;
+dojo.provide("dojox.secure.capability");
+dojox.secure.badProps=/^__|^(apply|call|callee|caller|constructor|eval|prototype|this|unwatch|valueOf|watch)$|__$/;
+dojox.secure.capability={keywords:["break","case","catch","const","continue","debugger","default","delete","do","else","enum","false","finally","for","function","if","in","instanceof","new","null","yield","return","switch","throw","true","try","typeof","var","void","while"],validate:function(_1,_2,_3){
+var _4=this.keywords;
+for(var i=0;i<_4.length;i++){
+_3[_4[i]]=true;
+}
+var _6="|this| keyword in object literal without a Class call";
+var _7=[];
+if(_1.match(/[\u200c-\u200f\u202a-\u202e\u206a-\u206f\uff00-\uffff]/)){
+throw new Error("Illegal unicode characters detected");
+}
+if(_1.match(/\/\*@cc_on/)){
+throw new Error("Conditional compilation token is not allowed");
+}
+_1=_1.replace(/\\["'\\\/bfnrtu]/g,"@").replace(/\/\/.*|\/\*[\w\W]*?\*\/|\/(\\[\/\\]|[^*\/])(\\.|[^\/\n\\])*\/[gim]*|("[^"]*")|('[^']*')/g,function(t){
+return t.match(/^\/\/|^\/\*/)?" ":"0";
+}).replace(/\.\s*([a-z\$_A-Z][\w\$_]*)|([;,{])\s*([a-z\$_A-Z][\w\$_]*\s*):/g,function(t,_a,_b,_c){
+_a=_a||_c;
+if(/^__|^(apply|call|callee|caller|constructor|eval|prototype|this|unwatch|valueOf|watch)$|__$/.test(_a)){
+throw new Error("Illegal property name "+_a);
+}
+return (_b&&(_b+"0:"))||"~";
+});
+_1.replace(/([^\[][\]\}]\s*=)|((\Wreturn|\S)\s*\[\s*\+?)|([^=!][=!]=[^=])/g,function(_d){
+if(!_d.match(/((\Wreturn|[=\&\|\:\?\,])\s*\[)|\[\s*\+$/)){
+throw new Error("Illegal operator "+_d.substring(1));
+}
+});
+_1=_1.replace(new RegExp("("+_2.join("|")+")[\\s~]*\\(","g"),function(_e){
+return "new(";
+});
+function _f(_10,_11){
+var _12={};
+_10.replace(/#\d/g,function(b){
+var _14=_7[b.substring(1)];
+for(var i in _14){
+if(i==_6){
+throw i;
+}
+if(i=="this"&&_14[":method"]&&_14["this"]==1){
+i=_6;
+}
+if(i!=":method"){
+_12[i]=2;
+}
+}
+});
+_10.replace(/(\W|^)([a-z_\$A-Z][\w_\$]*)/g,function(t,a,_18){
+if(_18.charAt(0)=="_"){
+throw new Error("Names may not start with _");
+}
+_12[_18]=1;
+});
+return _12;
+};
+var _19,_1a;
+function _1b(t,_1d,a,b,_20,_21){
+_21.replace(/(^|,)0:\s*function#(\d)/g,function(t,a,b){
+var _25=_7[b];
+_25[":method"]=1;
+});
+_21=_21.replace(/(^|[^_\w\$])Class\s*\(\s*([_\w\$]+\s*,\s*)*#(\d)/g,function(t,p,a,b){
+var _2a=_7[b];
+delete _2a[_6];
+return (p||"")+(a||"")+"#"+b;
+});
+_1a=_f(_21,_1d);
+function _2b(t,a,b,_2f){
+_2f.replace(/,?([a-z\$A-Z][_\w\$]*)/g,function(t,_31){
+if(_31=="Class"){
+throw new Error("Class is reserved");
+}
+delete _1a[_31];
+});
+};
+if(_1d){
+_2b(t,a,a,_20);
+}
+_21.replace(/(\W|^)(var) ([ \t,_\w\$]+)/g,_2b);
+return (a||"")+(b||"")+"#"+(_7.push(_1a)-1);
+};
+do{
+_19=_1.replace(/((function|catch)(\s+[_\w\$]+)?\s*\(([^\)]*)\)\s*)?{([^{}]*)}/g,_1b);
+}while(_19!=_1&&(_1=_19));
+_1b(0,0,0,0,0,_1);
+for(i in _1a){
+if(!(i in _3)){
+throw new Error("Illegal reference to "+i);
+}
+}
+}};
+}
diff --git a/dojox/secure/sandbox.js b/dojox/secure/sandbox.js
new file mode 100644
index 0000000..1aecaf7
--- /dev/null
+++ b/dojox/secure/sandbox.js
@@ -0,0 +1,231 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.secure.sandbox"]){
+dojo._hasResource["dojox.secure.sandbox"]=true;
+dojo.provide("dojox.secure.sandbox");
+dojo.require("dojox.secure.DOM");
+dojo.require("dojox.secure.capability");
+dojo.require("dojo.NodeList-fx");
+(function(){
+var _1=setTimeout;
+var _2=setInterval;
+if({}.__proto__){
+var _3=function(_4){
+var _5=Array.prototype[_4];
+if(_5&&!_5.fixed){
+(Array.prototype[_4]=function(){
+if(this==window){
+throw new TypeError("Called with wrong this");
+}
+return _5.apply(this,arguments);
+}).fixed=true;
+}
+};
+_3("concat");
+_3("reverse");
+_3("sort");
+_3("slice");
+_3("forEach");
+_3("filter");
+_3("reduce");
+_3("reduceRight");
+_3("every");
+_3("map");
+_3("some");
+}
+var _6=function(){
+return dojo.xhrGet.apply(dojo,arguments);
+};
+dojox.secure.sandbox=function(_7){
+var _8=dojox.secure.DOM(_7);
+_7=_8(_7);
+var _9=_7.ownerDocument;
+var _a,_b=dojox.secure._safeDojoFunctions(_7,_8);
+var _c=[];
+var _d=["isNaN","isFinite","parseInt","parseFloat","escape","unescape","encodeURI","encodeURIComponent","decodeURI","decodeURIComponent","alert","confirm","prompt","Error","EvalError","RangeError","ReferenceError","SyntaxError","TypeError","Date","RegExp","Number","Object","Array","String","Math","setTimeout","setInterval","clearTimeout","clearInterval","dojo","get","set","forEach","load","evaluate"];
+for(var i in _b){
+_d.push(i);
+_c.push("var "+i+"=dojo."+i);
+}
+eval(_c.join(";"));
+function _f(obj,_11){
+_11=""+_11;
+if(dojox.secure.badProps.test(_11)){
+throw new Error("bad property access");
+}
+if(obj.__get__){
+return obj.__get__(_11);
+}
+return obj[_11];
+};
+function set(obj,_14,_15){
+_14=""+_14;
+_f(obj,_14);
+if(obj.__set){
+return obj.__set(_14);
+}
+obj[_14]=_15;
+return _15;
+};
+function _16(obj,fun){
+if(typeof fun!="function"){
+throw new TypeError();
+}
+if("length" in obj){
+if(obj.__get__){
+var len=obj.__get__("length");
+for(var i=0;i<len;i++){
+if(i in obj){
+fun.call(obj,obj.__get__(i),i,obj);
+}
+}
+}else{
+len=obj.length;
+for(i=0;i<len;i++){
+if(i in obj){
+fun.call(obj,obj[i],i,obj);
+}
+}
+}
+}else{
+for(i in obj){
+fun.call(obj,_f(obj,i),i,obj);
+}
+}
+};
+function _1b(_1c,_1d,_1e){
+var _1f,_20,_21;
+var arg;
+for(var i=0,l=arguments.length;typeof (arg=arguments[i])=="function"&&i<l;i++){
+if(_1f){
+_a(_1f,arg.prototype);
+}else{
+_20=arg;
+var F=function(){
+};
+F.prototype=arg.prototype;
+_1f=new F;
+}
+}
+if(arg){
+for(var j in arg){
+var _27=arg[j];
+if(typeof _27=="function"){
+arg[j]=function(){
+if(this instanceof _1b){
+return arguments.callee.__rawMethod__.apply(this,arguments);
+}
+throw new Error("Method called on wrong object");
+};
+arg[j].__rawMethod__=_27;
+}
+}
+if(arg.hasOwnProperty("constructor")){
+_21=arg.constructor;
+}
+}
+_1f=_1f?_a(_1f,arg):arg;
+function _1b(){
+if(_20){
+_20.apply(this,arguments);
+}
+if(_21){
+_21.apply(this,arguments);
+}
+};
+_a(_1b,arguments[i]);
+_1f.constructor=_1b;
+_1b.prototype=_1f;
+return _1b;
+};
+function _28(_29){
+if(typeof _29!="function"){
+throw new Error("String is not allowed in setTimeout/setInterval");
+}
+};
+function _2a(_2b,_2c){
+_28(_2b);
+return _1(_2b,_2c);
+};
+function _2d(_2e,_2f){
+_28(_2e);
+return _2(_2e,_2f);
+};
+function _30(_31){
+return _8.evaluate(_31);
+};
+var _32=_8.load=function(url){
+if(url.match(/^[\w\s]*:/)){
+throw new Error("Access denied to cross-site requests");
+}
+return _6({url:(new _b._Url(_8.rootUrl,url))+"",secure:true});
+};
+_8.evaluate=function(_34){
+dojox.secure.capability.validate(_34,_d,{document:1,element:1});
+if(_34.match(/^\s*[\[\{]/)){
+var _35=eval("("+_34+")");
+}else{
+eval(_34);
+}
+};
+return {loadJS:function(url){
+_8.rootUrl=url;
+return _6({url:url,secure:true}).addCallback(function(_37){
+_30(_37,_7);
+});
+},loadHTML:function(url){
+_8.rootUrl=url;
+return _6({url:url,secure:true}).addCallback(function(_39){
+_7.innerHTML=_39;
+});
+},evaluate:function(_3a){
+return _8.evaluate(_3a);
+}};
+};
+})();
+dojox.secure._safeDojoFunctions=function(_3b,_3c){
+var _3d=["mixin","require","isString","isArray","isFunction","isObject","isArrayLike","isAlien","hitch","delegate","partial","trim","disconnect","subscribe","unsubscribe","Deferred","toJson","style","attr"];
+var doc=_3b.ownerDocument;
+var _3f=dojox.secure.unwrap;
+dojo.NodeList.prototype.addContent.safetyCheck=function(_40){
+_3c.safeHTML(_40);
+};
+dojo.NodeList.prototype.style.safetyCheck=function(_41,_42){
+if(_41=="behavior"){
+throw new Error("Can not set behavior");
+}
+_3c.safeCSS(_42);
+};
+dojo.NodeList.prototype.attr.safetyCheck=function(_43,_44){
+if(_44&&(_43=="src"||_43=="href"||_43=="style")){
+throw new Error("Illegal to set "+_43);
+}
+};
+var _45={query:function(_46,_47){
+return _3c(dojo.query(_46,_3f(_47||_3b)));
+},connect:function(el,_49){
+var obj=el;
+arguments[0]=_3f(el);
+if(obj!=arguments[0]&&_49.substring(0,2)!="on"){
+throw new Error("Invalid event name for element");
+}
+return dojo.connect.apply(dojo,arguments);
+},body:function(){
+return _3b;
+},byId:function(id){
+return _3b.ownerDocument.getElementById(id);
+},fromJson:function(str){
+dojox.secure.capability.validate(str,[],{});
+return dojo.fromJson(str);
+}};
+for(var i=0;i<_3d.length;i++){
+_45[_3d[i]]=dojo[_3d[i]];
+}
+return _45;
+};
+}
diff --git a/dojox/sketch.js b/dojox/sketch.js
new file mode 100644
index 0000000..8fbad1f
--- /dev/null
+++ b/dojox/sketch.js
@@ -0,0 +1,15 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.sketch"]){
+dojo._hasResource["dojox.sketch"]=true;
+dojo.provide("dojox.sketch");
+dojo.require("dojox.xml.DomParser");
+dojo.require("dojox.sketch.UndoStack");
+dojo.require("dojox.sketch.Figure");
+dojo.require("dojox.sketch.Toolbar");
+}
diff --git a/dojox/sketch/Anchor.js b/dojox/sketch/Anchor.js
new file mode 100644
index 0000000..8ab1967
--- /dev/null
+++ b/dojox/sketch/Anchor.js
@@ -0,0 +1,69 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.sketch.Anchor"]){
+dojo._hasResource["dojox.sketch.Anchor"]=true;
+dojo.provide("dojox.sketch.Anchor");
+dojo.require("dojox.gfx");
+(function(){
+var ta=dojox.sketch;
+ta.Anchor=function(an,id,_4){
+var _5=this;
+var _6=4;
+var _7=null;
+this.type=function(){
+return "Anchor";
+};
+this.annotation=an;
+this.id=id;
+this._key="anchor-"+ta.Anchor.count++;
+this.shape=null;
+this.isControl=(_4!=null)?_4:true;
+this.beginEdit=function(){
+this.annotation.beginEdit(ta.CommandTypes.Modify);
+};
+this.endEdit=function(){
+this.annotation.endEdit();
+};
+this.zoom=function(_8){
+if(this.shape){
+var rs=Math.floor(_6/_8);
+var _a=dojox.gfx.renderer=="vml"?1:1/_8;
+this.shape.setShape({x:an[id].x-rs,y:an[id].y-rs,width:rs*2,height:rs*2}).setStroke({color:"black",width:_a});
+}
+};
+this.setBinding=function(pt){
+an[id]={x:an[id].x+pt.dx,y:an[id].y+pt.dy};
+an.draw();
+an.drawBBox();
+};
+this.setUndo=function(){
+an.setUndo();
+};
+this.enable=function(){
+if(!an.shape){
+return;
+}
+an.figure._add(this);
+_7={x:an[id].x-_6,y:an[id].y-_6,width:_6*2,height:_6*2};
+this.shape=an.shape.createRect(_7).setFill([255,255,255,0.35]);
+this.shape.getEventSource().setAttribute("id",_5._key);
+this.shape.getEventSource().setAttribute("shape-rendering","crispEdges");
+this.zoom(an.figure.zoomFactor);
+};
+this.disable=function(){
+an.figure._remove(this);
+if(an.shape){
+an.shape.remove(this.shape);
+}
+this.shape=null;
+_7=null;
+};
+};
+ta.Anchor.count=0;
+})();
+}
diff --git a/dojox/sketch/Annotation.js b/dojox/sketch/Annotation.js
new file mode 100644
index 0000000..cc4c2c0
--- /dev/null
+++ b/dojox/sketch/Annotation.js
@@ -0,0 +1,249 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.sketch.Annotation"]){
+dojo._hasResource["dojox.sketch.Annotation"]=true;
+dojo.provide("dojox.sketch.Annotation");
+dojo.require("dojox.sketch.Anchor");
+dojo.require("dojox.sketch._Plugin");
+(function(){
+var ta=dojox.sketch;
+dojo.declare("dojox.sketch.AnnotationTool",ta._Plugin,{onMouseDown:function(e){
+this._omd=true;
+},onMouseMove:function(e,_4){
+if(!this._omd){
+return;
+}
+if(this._cshape){
+this._cshape.setShape(_4);
+}else{
+this._cshape=this.figure.surface.createRect(_4).setStroke({color:"#999",width:1,style:"ShortDot"}).setFill([255,255,255,0.7]);
+this._cshape.getEventSource().setAttribute("shape-rendering","crispEdges");
+}
+},onMouseUp:function(e){
+if(!this._omd){
+return;
+}
+this._omd=false;
+var f=this.figure;
+if(this._cshape){
+f.surface.remove(this._cshape);
+delete this._cshape;
+}
+if(!(f._startPoint.x==e.pageX&&f._startPoint.y==e.pageY)){
+var _7=10;
+if(Math.max(_7,Math.abs(f._absEnd.x-f._start.x),Math.abs(f._absEnd.y-f._start.y))>_7){
+this._create(f._start,f._end);
+}
+}
+},_create:function(_8,_9){
+var f=this.figure;
+var _=f.nextKey();
+var a=new (this.annotation)(f,_);
+a.transform={dx:_8.x/f.zoomFactor,dy:_8.y/f.zoomFactor};
+a.end={x:_9.x/f.zoomFactor,y:_9.y/f.zoomFactor};
+if(a.control){
+a.control={x:Math.round((_9.x/2)/f.zoomFactor),y:Math.round((_9.y/2)/f.zoomFactor)};
+}
+f.onBeforeCreateShape(a);
+a.initialize();
+f.select(a);
+f.onCreateShape(a);
+f.history.add(ta.CommandTypes.Create,a);
+}});
+ta.Annotation=function(_d,id){
+this.id=this._key=id;
+this.figure=_d;
+this.mode=ta.Annotation.Modes.View;
+this.shape=null;
+this.boundingBox=null;
+this.hasAnchors=true;
+this.anchors={};
+this._properties={"stroke":{color:"blue",width:2},"font":{family:"Arial",size:16,weight:"bold"},"fill":"blue","label":""};
+if(this.figure){
+this.figure.add(this);
+}
+};
+var p=ta.Annotation.prototype;
+p.constructor=ta.Annotation;
+p.type=function(){
+return "";
+};
+p.getType=function(){
+return ta.Annotation;
+};
+p.onRemove=function(_10){
+this.figure.history.add(ta.CommandTypes.Delete,this,this.serialize());
+};
+p.property=function(_11,_12){
+var r;
+_11=_11.toLowerCase();
+if(this._properties[_11]!==undefined){
+r=this._properties[_11];
+}
+if(arguments.length>1){
+this._properties[_11]=_12;
+if(r!=_12){
+this.onPropertyChange(_11,r);
+}
+}
+return r;
+};
+p.onPropertyChange=function(_14,_15){
+};
+p.onCreate=function(){
+this.figure.history.add(ta.CommandTypes.Create,this);
+};
+p.onDblClick=function(e){
+var l=prompt("Set new text:",this.property("label"));
+if(l!==false){
+this.beginEdit(ta.CommandTypes.Modify);
+this.property("label",l);
+this.draw();
+this.endEdit();
+}
+};
+p.initialize=function(){
+};
+p.destroy=function(){
+};
+p.draw=function(){
+};
+p.apply=function(obj){
+};
+p.serialize=function(){
+};
+p.getBBox=function(){
+};
+p.beginEdit=function(_19){
+if(!this._type){
+this._type=_19||ta.CommandTypes.Move;
+this._prevState=this.serialize();
+}
+};
+p.endEdit=function(){
+if(this._prevState!=this.serialize()){
+this.figure.history.add(this._type,this,this._prevState);
+}
+this._type=this._prevState="";
+};
+p.calculate={slope:function(p1,p2){
+if(!(p1.x-p2.x)){
+return 0;
+}
+return ((p1.y-p2.y)/(p1.x-p2.x));
+},dx:function(p1,p2,dy){
+var s=this.slope(p1,p2);
+if(s==0){
+return s;
+}
+return dy/s;
+},dy:function(p1,p2,dx){
+return this.slope(p1,p2)*dx;
+}};
+p.drawBBox=function(){
+var r=this.getBBox();
+if(!this.boundingBox){
+this.boundingBox=this.shape.createRect(r).moveToBack().setStroke({color:"#999",width:1,style:"Dash"}).setFill([238,238,238,0.3]);
+this.boundingBox.getEventSource().setAttribute("id",this.id+"-boundingBox");
+this.boundingBox.getEventSource().setAttribute("shape-rendering","crispEdges");
+this.figure._add(this);
+}else{
+this.boundingBox.setShape(r);
+}
+};
+p.setBinding=function(pt){
+this.transform.dx+=pt.dx;
+this.transform.dy+=pt.dy;
+this.draw();
+};
+p.getTextBox=function(_25){
+var fp=this.property("font");
+var f={fontFamily:fp.family,fontSize:fp.size,fontWeight:fp.weight};
+if(_25){
+f.fontSize=Math.floor(f.fontSize/_25);
+}
+return dojox.gfx._base._getTextBox(this.property("label"),f);
+};
+p.setMode=function(m){
+if(this.mode==m){
+return;
+}
+this.mode=m;
+var _29="disable";
+if(m==ta.Annotation.Modes.Edit){
+_29="enable";
+}
+if(_29=="enable"){
+this.drawBBox();
+this.figure._add(this);
+}else{
+if(this.boundingBox){
+if(this.shape){
+this.shape.remove(this.boundingBox);
+}
+this.boundingBox=null;
+}
+}
+for(var p in this.anchors){
+this.anchors[p][_29]();
+}
+};
+p.zoom=function(pct){
+pct=pct||this.figure.zoomFactor;
+if(this.labelShape){
+var f=dojo.clone(this.property("font"));
+f.size=Math.ceil(f.size/pct)+"px";
+this.labelShape.setFont(f);
+}
+for(var n in this.anchors){
+this.anchors[n].zoom(pct);
+}
+if(dojox.gfx.renderer=="vml"){
+pct=1;
+}
+if(this.pathShape){
+var s=dojo.clone(this.property("stroke"));
+s.width=pct>1?s.width:Math.ceil(s.width/pct)+"px";
+this.pathShape.setStroke(s);
+}
+};
+p.writeCommonAttrs=function(){
+return "id=\""+this.id+"\" dojoxsketch:type=\""+this.type()+"\""+" transform=\"translate("+this.transform.dx+","+this.transform.dy+")\""+(this.data?(" ><![CDATA[data:"+dojo.toJson(this.data)+"]]"):"");
+};
+p.readCommonAttrs=function(obj){
+var i=0,cs=obj.childNodes,c;
+while((c=cs[i++])){
+if(c.nodeType==4){
+if(c.nodeValue.substr(0,11)=="properties:"){
+this._properties=dojo.fromJson(c.nodeValue.substr(11));
+}else{
+if(c.nodeValue.substr(0,5)=="data:"){
+this.data=dojo.fromJson(c.nodeValue.substr(5));
+}else{
+console.error("unknown CDATA node in node ",obj);
+}
+}
+}
+}
+if(obj.getAttribute("transform")){
+var t=obj.getAttribute("transform").replace("translate(","");
+var pt=t.split(",");
+this.transform.dx=parseFloat(pt[0],10);
+this.transform.dy=parseFloat(pt[1],10);
+}
+};
+ta.Annotation.Modes={View:0,Edit:1};
+ta.Annotation.register=function(_35,_36){
+var cls=ta[_35+"Annotation"];
+ta.registerTool(_35,function(p){
+dojo.mixin(p,{shape:_35,annotation:cls});
+return new (_36||ta.AnnotationTool)(p);
+});
+};
+})();
+}
diff --git a/dojox/sketch/DoubleArrowAnnotation.js b/dojox/sketch/DoubleArrowAnnotation.js
new file mode 100644
index 0000000..38e3293
--- /dev/null
+++ b/dojox/sketch/DoubleArrowAnnotation.js
@@ -0,0 +1,178 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.sketch.DoubleArrowAnnotation"]){
+dojo._hasResource["dojox.sketch.DoubleArrowAnnotation"]=true;
+dojo.provide("dojox.sketch.DoubleArrowAnnotation");
+dojo.require("dojox.sketch.Annotation");
+dojo.require("dojox.sketch.Anchor");
+(function(){
+var ta=dojox.sketch;
+ta.DoubleArrowAnnotation=function(_2,id){
+ta.Annotation.call(this,_2,id);
+this.transform={dx:0,dy:0};
+this.start={x:0,y:0};
+this.control={x:100,y:-50};
+this.end={x:200,y:0};
+this.textPosition={x:0,y:0};
+this.textOffset=6;
+this.textYOffset=10;
+this.textAlign="middle";
+this.startRotation=0;
+this.endRotation=0;
+this.labelShape=null;
+this.pathShape=null;
+this.startArrow=null;
+this.startArrowGroup=null;
+this.endArrow=null;
+this.endArrowGroup=null;
+this.anchors.start=new ta.Anchor(this,"start");
+this.anchors.control=new ta.Anchor(this,"control");
+this.anchors.end=new ta.Anchor(this,"end");
+};
+ta.DoubleArrowAnnotation.prototype=new ta.Annotation;
+var p=ta.DoubleArrowAnnotation.prototype;
+p.constructor=ta.DoubleArrowAnnotation;
+p.type=function(){
+return "DoubleArrow";
+};
+p.getType=function(){
+return ta.DoubleArrowAnnotation;
+};
+p._rot=function(){
+var _5=this.control.y-this.start.y;
+var _6=this.control.x-this.start.x;
+this.startRotation=Math.atan2(_5,_6);
+_5=this.end.y-this.control.y;
+_6=this.end.x-this.control.x;
+this.endRotation=Math.atan2(_5,_6);
+};
+p._pos=function(){
+var _7=this.textOffset;
+if(this.control.y<this.end.y){
+_7*=-1;
+}else{
+_7+=this.textYOffset;
+}
+var ab={x:((this.control.x-this.start.x)*0.5)+this.start.x,y:((this.control.y-this.start.y)*0.5)+this.start.y};
+var bc={x:((this.end.x-this.control.x)*0.5)+this.control.x,y:((this.end.y-this.control.y)*0.5)+this.control.y};
+this.textPosition={x:((bc.x-ab.x)*0.5)+ab.x,y:(((bc.y-ab.y)*0.5)+ab.y)+_7};
+};
+p.apply=function(_a){
+if(!_a){
+return;
+}
+if(_a.documentElement){
+_a=_a.documentElement;
+}
+this.readCommonAttrs(_a);
+for(var i=0;i<_a.childNodes.length;i++){
+var c=_a.childNodes[i];
+if(c.localName=="text"){
+this.property("label",c.childNodes.length?c.childNodes[0].nodeValue:"");
+}else{
+if(c.localName=="path"){
+var d=c.getAttribute("d").split(" ");
+var s=d[0].split(",");
+this.start.x=parseFloat(s[0].substr(1),10);
+this.start.y=parseFloat(s[1],10);
+s=d[1].split(",");
+this.control.x=parseFloat(s[0].substr(1),10);
+this.control.y=parseFloat(s[1],10);
+s=d[2].split(",");
+this.end.x=parseFloat(s[0],10);
+this.end.y=parseFloat(s[1],10);
+var _f=this.property("stroke");
+var _10=c.getAttribute("style");
+var m=_10.match(/stroke:([^;]+);/);
+if(m){
+_f.color=m[1];
+this.property("fill",m[1]);
+}
+m=_10.match(/stroke-width:([^;]+);/);
+if(m){
+_f.width=m[1];
+}
+this.property("stroke",_f);
+}
+}
+}
+};
+p.initialize=function(obj){
+var _13=(ta.Annotation.labelFont)?ta.Annotation.labelFont:{family:"Times",size:"16px"};
+this.apply(obj);
+this._rot();
+this._pos();
+var rot=this.startRotation;
+var _15=dojox.gfx.matrix.rotate(rot);
+rot=this.endRotation;
+var _16=dojox.gfx.matrix.rotateAt(rot,this.end.x,this.end.y);
+this.shape=this.figure.group.createGroup();
+this.shape.getEventSource().setAttribute("id",this.id);
+this.pathShape=this.shape.createPath("M"+this.start.x+" "+this.start.y+"Q"+this.control.x+" "+this.control.y+" "+this.end.x+" "+this.end.y+" l0,0");
+this.startArrowGroup=this.shape.createGroup().setTransform({dx:this.start.x,dy:this.start.y});
+this.startArrowGroup.applyTransform(_15);
+this.startArrow=this.startArrowGroup.createPath();
+this.endArrowGroup=this.shape.createGroup().setTransform(_16);
+this.endArrow=this.endArrowGroup.createPath();
+this.labelShape=this.shape.createText({x:this.textPosition.x,y:this.textPosition.y,text:this.property("label"),align:this.textAlign}).setFill(this.property("fill"));
+this.labelShape.getEventSource().setAttribute("id",this.id+"-labelShape");
+this.draw();
+};
+p.destroy=function(){
+if(!this.shape){
+return;
+}
+this.startArrowGroup.remove(this.startArrow);
+this.endArrowGroup.remove(this.endArrow);
+this.shape.remove(this.startArrowGroup);
+this.shape.remove(this.endArrowGroup);
+this.shape.remove(this.pathShape);
+this.shape.remove(this.labelShape);
+this.figure.group.remove(this.shape);
+this.shape=this.pathShape=this.labelShape=this.startArrowGroup=this.startArrow=this.endArrowGroup=this.endArrow=null;
+};
+p.draw=function(obj){
+this.apply(obj);
+this._rot();
+this._pos();
+var rot=this.startRotation;
+var _19=dojox.gfx.matrix.rotate(rot);
+rot=this.endRotation;
+var _1a=dojox.gfx.matrix.rotateAt(rot,this.end.x,this.end.y);
+this.shape.setTransform(this.transform);
+this.pathShape.setShape("M"+this.start.x+" "+this.start.y+" Q"+this.control.x+" "+this.control.y+" "+this.end.x+" "+this.end.y+" l0,0");
+this.startArrowGroup.setTransform({dx:this.start.x,dy:this.start.y}).applyTransform(_19);
+this.startArrow.setFill(this.property("fill"));
+this.endArrowGroup.setTransform(_1a);
+this.endArrow.setFill(this.property("fill"));
+this.labelShape.setShape({x:this.textPosition.x,y:this.textPosition.y,text:this.property("label")}).setFill(this.property("fill"));
+this.zoom();
+};
+p.zoom=function(pct){
+if(this.startArrow){
+pct=pct||this.figure.zoomFactor;
+ta.Annotation.prototype.zoom.call(this,pct);
+var l=pct>1?20:Math.floor(20/pct),w=pct>1?5:Math.floor(5/pct),h=pct>1?3:Math.floor(3/pct);
+this.startArrow.setShape("M0,0 l"+l+",-"+w+" -"+h+","+w+" "+h+","+w+" Z");
+this.endArrow.setShape("M"+this.end.x+","+this.end.y+" l-"+l+",-"+w+" "+h+","+w+" -"+h+","+w+" Z");
+}
+};
+p.getBBox=function(){
+var x=Math.min(this.start.x,this.control.x,this.end.x);
+var y=Math.min(this.start.y,this.control.y,this.end.y);
+var w=Math.max(this.start.x,this.control.x,this.end.x)-x;
+var h=Math.max(this.start.y,this.control.y,this.end.y)-y;
+return {x:x,y:y,width:w,height:h};
+};
+p.serialize=function(){
+var s=this.property("stroke");
+return "<g "+this.writeCommonAttrs()+">"+"<path style=\"stroke:"+s.color+";stroke-width:"+s.width+";fill:none;\" d=\""+"M"+this.start.x+","+this.start.y+" "+"Q"+this.control.x+","+this.control.y+" "+this.end.x+","+this.end.y+"\" />"+"<g transform=\"translate("+this.start.x+","+this.start.y+") "+"rotate("+(Math.round((this.startRotation*(180/Math.PI))*Math.pow(10,4))/Math.pow(10,4))+")\">"+"<path style=\"fill:"+s.color+";\" d=\"M0,0 l20,-5, -3,5, 3,5 Z\" />"+"</g>"+"<g transform=\"rotate( [...]
+};
+ta.Annotation.register("DoubleArrow");
+})();
+}
diff --git a/dojox/sketch/Figure.js b/dojox/sketch/Figure.js
new file mode 100644
index 0000000..0df2c04
--- /dev/null
+++ b/dojox/sketch/Figure.js
@@ -0,0 +1,462 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.sketch.Figure"]){
+dojo._hasResource["dojox.sketch.Figure"]=true;
+dojo.provide("dojox.sketch.Figure");
+dojo.experimental("dojox.sketch");
+dojo.require("dojox.gfx");
+dojo.require("dojox.sketch.UndoStack");
+(function(){
+var ta=dojox.sketch;
+ta.tools={};
+ta.registerTool=function(_2,fn){
+ta.tools[_2]=fn;
+};
+ta.Figure=function(_4){
+var _5=this;
+this.annCounter=1;
+this.shapes=[];
+this.image=null;
+this.imageSrc=null;
+this.size={w:0,h:0};
+this.surface=null;
+this.group=null;
+this.node=null;
+this.zoomFactor=1;
+this.tools=null;
+this.obj={};
+dojo.mixin(this,_4);
+this.selected=[];
+this.hasSelections=function(){
+return this.selected.length>0;
+};
+this.isSelected=function(_6){
+for(var i=0;i<_5.selected.length;i++){
+if(_5.selected[i]==_6){
+return true;
+}
+}
+return false;
+};
+this.select=function(_8){
+if(!_5.isSelected(_8)){
+_5.clearSelections();
+_5.selected=[_8];
+}
+_8.setMode(ta.Annotation.Modes.View);
+_8.setMode(ta.Annotation.Modes.Edit);
+};
+this.deselect=function(_9){
+var _a=-1;
+for(var i=0;i<_5.selected.length;i++){
+if(_5.selected[i]==_9){
+_a=i;
+break;
+}
+}
+if(_a>-1){
+_9.setMode(ta.Annotation.Modes.View);
+_5.selected.splice(_a,1);
+}
+return _9;
+};
+this.clearSelections=function(){
+for(var i=0;i<_5.selected.length;i++){
+_5.selected[i].setMode(ta.Annotation.Modes.View);
+}
+_5.selected=[];
+};
+this.replaceSelection=function(n,o){
+if(!_5.isSelected(o)){
+_5.select(n);
+return;
+}
+var _f=-1;
+for(var i=0;i<_5.selected.length;i++){
+if(_5.selected[i]==o){
+_f=i;
+break;
+}
+}
+if(_f>-1){
+_5.selected.splice(_f,1,n);
+}
+};
+this._c=null;
+this._ctr=null;
+this._lp=null;
+this._action=null;
+this._prevState=null;
+this._startPoint=null;
+this._ctool=null;
+this._start=null;
+this._end=null;
+this._absEnd=null;
+this._cshape=null;
+this._dblclick=function(e){
+var o=_5._fromEvt(e);
+if(o){
+_5.onDblClickShape(o,e);
+}
+};
+this._keydown=function(e){
+var _14=false;
+if(e.ctrlKey){
+if(e.keyCode===90){
+_5.undo();
+_14=true;
+}else{
+if(e.keyCode===89){
+_5.redo();
+_14=true;
+}
+}
+}
+if(e.keyCode===46||e.keyCode===8){
+_5._delete(_5.selected);
+_14=true;
+}
+if(_14){
+dojo.stopEvent(e);
+}
+};
+this._md=function(e){
+var o=_5._fromEvt(e);
+_5._startPoint={x:e.pageX,y:e.pageY};
+_5._ctr=dojo._abs(_5.node);
+_5._ctr={x:_5._ctr.x,y:_5._ctr.y};
+var X=e.clientX-_5._ctr.x,Y=e.clientY-_5._ctr.y;
+_5._lp={x:X,y:Y};
+_5._start={x:X,y:Y};
+_5._end={x:X,y:Y};
+_5._absEnd={x:X,y:Y};
+if(!o){
+_5.clearSelections();
+_5._ctool.onMouseDown(e);
+}else{
+if(o.type&&o.type()!="Anchor"){
+if(!_5.isSelected(o)){
+_5.select(o);
+_5._sameShapeSelected=false;
+}else{
+_5._sameShapeSelected=true;
+}
+}
+o.beginEdit();
+_5._c=o;
+}
+};
+this._mm=function(e){
+if(!_5._ctr){
+return;
+}
+var x=e.clientX-_5._ctr.x;
+var y=e.clientY-_5._ctr.y;
+var dx=x-_5._lp.x;
+var dy=y-_5._lp.y;
+_5._absEnd={x:x,y:y};
+if(_5._c){
+_5._c.setBinding({dx:dx/_5.zoomFactor,dy:dy/_5.zoomFactor});
+_5._lp={x:x,y:y};
+}else{
+_5._end={x:dx,y:dy};
+var _1e={x:Math.min(_5._start.x,_5._absEnd.x),y:Math.min(_5._start.y,_5._absEnd.y),width:Math.abs(_5._start.x-_5._absEnd.x),height:Math.abs(_5._start.y-_5._absEnd.y)};
+if(_1e.width&&_1e.height){
+_5._ctool.onMouseMove(e,_1e);
+}
+}
+};
+this._mu=function(e){
+if(_5._c){
+_5._c.endEdit();
+}else{
+_5._ctool.onMouseUp(e);
+}
+_5._c=_5._ctr=_5._lp=_5._action=_5._prevState=_5._startPoint=null;
+_5._cshape=_5._start=_5._end=_5._absEnd=null;
+};
+this.initUndoStack();
+};
+var p=ta.Figure.prototype;
+p.initUndoStack=function(){
+this.history=new ta.UndoStack(this);
+};
+p.setTool=function(t){
+this._ctool=t;
+};
+p._delete=function(arr,_23){
+for(var i=0;i<arr.length;i++){
+arr[i].setMode(ta.Annotation.Modes.View);
+arr[i].destroy(_23);
+this.remove(arr[i]);
+this._remove(arr[i]);
+if(!_23){
+arr[i].onRemove();
+}
+}
+arr.splice(0,arr.length);
+};
+p.onDblClickShape=function(_25,e){
+if(_25["onDblClick"]){
+_25.onDblClick(e);
+}
+};
+p.onCreateShape=function(_27){
+};
+p.onBeforeCreateShape=function(_28){
+};
+p.initialize=function(_29){
+this.node=_29;
+this.surface=dojox.gfx.createSurface(_29,this.size.w,this.size.h);
+this.group=this.surface.createGroup();
+this._cons=[];
+var es=this.surface.getEventSource();
+this._cons.push(dojo.connect(es,"ondraggesture",dojo.stopEvent),dojo.connect(es,"ondragenter",dojo.stopEvent),dojo.connect(es,"ondragover",dojo.stopEvent),dojo.connect(es,"ondragexit",dojo.stopEvent),dojo.connect(es,"ondragstart",dojo.stopEvent),dojo.connect(es,"onselectstart",dojo.stopEvent),dojo.connect(es,"onmousedown",this._md),dojo.connect(es,"onmousemove",this._mm),dojo.connect(es,"onmouseup",this._mu),dojo.connect(es,"onclick",this,"onClick"),dojo.connect(es,"ondblclick",this._dbl [...]
+this.image=this.group.createImage({width:this.size.w,height:this.size.h,src:this.imageSrc});
+};
+p.destroy=function(_2b){
+if(!this.node){
+return;
+}
+if(!_2b){
+if(this.history){
+this.history.destroy();
+}
+if(this._subscribed){
+dojo.unsubscribe(this._subscribed);
+delete this._subscribed;
+}
+}
+dojo.forEach(this._cons,dojo.disconnect);
+this._cons=[];
+dojo.empty(this.node);
+this.group=this.surface=null;
+this.obj={};
+this.shapes=[];
+};
+p.nextKey=function(){
+return "annotation-"+this.annCounter++;
+};
+p.draw=function(){
+};
+p.zoom=function(pct){
+this.zoomFactor=pct/100;
+var w=this.size.w*this.zoomFactor;
+var h=this.size.h*this.zoomFactor;
+this.surface.setDimensions(w,h);
+this.group.setTransform(dojox.gfx.matrix.scale(this.zoomFactor,this.zoomFactor));
+for(var i=0;i<this.shapes.length;i++){
+this.shapes[i].zoom(this.zoomFactor);
+}
+};
+p.getFit=function(){
+var wF=(this.node.parentNode.clientWidth-5)/this.size.w;
+var hF=(this.node.parentNode.clientHeight-5)/this.size.h;
+return Math.min(wF,hF)*100;
+};
+p.unzoom=function(){
+this.zoomFactor=1;
+this.surface.setDimensions(this.size.w,this.size.h);
+this.group.setTransform();
+};
+p._add=function(obj){
+this.obj[obj._key]=obj;
+};
+p._remove=function(obj){
+if(this.obj[obj._key]){
+delete this.obj[obj._key];
+}
+};
+p._get=function(key){
+if(key&&key.indexOf("bounding")>-1){
+key=key.replace("-boundingBox","");
+}else{
+if(key&&key.indexOf("-labelShape")>-1){
+key=key.replace("-labelShape","");
+}
+}
+return this.obj[key];
+};
+p._keyFromEvt=function(e){
+var key=e.target.id+"";
+if(key.length==0){
+var p=e.target.parentNode;
+var _38=this.surface.getEventSource();
+while(p&&p.id.length==0&&p!=_38){
+p=p.parentNode;
+}
+key=p.id;
+}
+return key;
+};
+p._fromEvt=function(e){
+return this._get(this._keyFromEvt(e));
+};
+p.add=function(_3a){
+for(var i=0;i<this.shapes.length;i++){
+if(this.shapes[i]==_3a){
+return true;
+}
+}
+this.shapes.push(_3a);
+return true;
+};
+p.remove=function(_3c){
+var idx=-1;
+for(var i=0;i<this.shapes.length;i++){
+if(this.shapes[i]==_3c){
+idx=i;
+break;
+}
+}
+if(idx>-1){
+this.shapes.splice(idx,1);
+}
+return _3c;
+};
+p.get=function(id){
+for(var i=0;i<this.shapes.length;i++){
+if(this.shapes[i].id==id){
+return this.shapes[i];
+}
+}
+return null;
+};
+p.convert=function(ann,t){
+var _43=t+"Annotation";
+if(!ta[_43]){
+return;
+}
+var _44=ann.type(),id=ann.id,_46=ann.label,_47=ann.mode,_48=ann.tokenId;
+var _49,end,_4b,_4c;
+switch(_44){
+case "Preexisting":
+case "Lead":
+_4c={dx:ann.transform.dx,dy:ann.transform.dy};
+_49={x:ann.start.x,y:ann.start.y};
+end={x:ann.end.x,y:ann.end.y};
+var cx=end.x-((end.x-_49.x)/2);
+var cy=end.y-((end.y-_49.y)/2);
+_4b={x:cx,y:cy};
+break;
+case "SingleArrow":
+case "DoubleArrow":
+_4c={dx:ann.transform.dx,dy:ann.transform.dy};
+_49={x:ann.start.x,y:ann.start.y};
+end={x:ann.end.x,y:ann.end.y};
+_4b={x:ann.control.x,y:ann.control.y};
+break;
+case "Underline":
+_4c={dx:ann.transform.dx,dy:ann.transform.dy};
+_49={x:ann.start.x,y:ann.start.y};
+_4b={x:_49.x+50,y:_49.y+50};
+end={x:_49.x+100,y:_49.y+100};
+break;
+case "Brace":
+}
+var n=new ta[_43](this,id);
+if(n.type()=="Underline"){
+n.transform={dx:_4c.dx+_49.x,dy:_4c.dy+_49.y};
+}else{
+if(n.transform){
+n.transform=_4c;
+}
+if(n.start){
+n.start=_49;
+}
+}
+if(n.end){
+n.end=end;
+}
+if(n.control){
+n.control=_4b;
+}
+n.label=_46;
+n.token=dojo.lang.shallowCopy(ann.token);
+n.initialize();
+this.replaceSelection(n,ann);
+this._remove(ann);
+this.remove(ann);
+ann.destroy();
+n.setMode(_47);
+};
+p.setValue=function(_50){
+var obj=dojox.xml.DomParser.parse(_50);
+var _52=this.node;
+this.load(obj,_52);
+this.zoom(this.zoomFactor*100);
+};
+p.load=function(obj,n){
+if(this.surface){
+this.destroy(true);
+}
+var _55=obj.documentElement;
+this.size={w:parseFloat(_55.getAttribute("width"),10),h:parseFloat(_55.getAttribute("height"),10)};
+var g=_55.childrenByName("g")[0];
+var img=g.childrenByName("image")[0];
+this.imageSrc=img.getAttribute("xlink:href");
+this.initialize(n);
+var ann=g.childrenByName("g");
+for(var i=0;i<ann.length;i++){
+this._loadAnnotation(ann[i]);
+}
+if(this._loadDeferred){
+this._loadDeferred.callback(this);
+this._loadDeferred=null;
+}
+this.onLoad();
+};
+p.onLoad=function(){
+};
+p.onClick=function(){
+};
+p._loadAnnotation=function(obj){
+var _5b=obj.getAttribute("dojoxsketch:type")+"Annotation";
+if(ta[_5b]){
+var a=new ta[_5b](this,obj.id);
+a.initialize(obj);
+this.nextKey();
+a.setMode(ta.Annotation.Modes.View);
+this._add(a);
+return a;
+}
+return null;
+};
+p.onUndo=function(){
+};
+p.onBeforeUndo=function(){
+};
+p.onRedo=function(){
+};
+p.onBeforeRedo=function(){
+};
+p.undo=function(){
+if(this.history){
+this.onBeforeUndo();
+this.history.undo();
+this.onUndo();
+}
+};
+p.redo=function(){
+if(this.history){
+this.onBeforeRedo();
+this.history.redo();
+this.onRedo();
+}
+};
+p.serialize=function(){
+var s="<svg xmlns=\"http://www.w3.org/2000/svg\" "+"xmlns:xlink=\"http://www.w3.org/1999/xlink\" "+"xmlns:dojoxsketch=\"http://dojotoolkit.org/dojox/sketch\" "+"width=\""+this.size.w+"\" height=\""+this.size.h+"\">"+"<g>"+"<image xlink:href=\""+this.imageSrc+"\" x=\"0\" y=\"0\" width=\""+this.size.w+"\" height=\""+this.size.h+"\" />";
+for(var i=0;i<this.shapes.length;i++){
+s+=this.shapes[i].serialize();
+}
+s+="</g></svg>";
+return s;
+};
+p.getValue=p.serialize;
+})();
+}
diff --git a/dojox/sketch/LeadAnnotation.js b/dojox/sketch/LeadAnnotation.js
new file mode 100644
index 0000000..324c458
--- /dev/null
+++ b/dojox/sketch/LeadAnnotation.js
@@ -0,0 +1,151 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.sketch.LeadAnnotation"]){
+dojo._hasResource["dojox.sketch.LeadAnnotation"]=true;
+dojo.provide("dojox.sketch.LeadAnnotation");
+dojo.require("dojox.sketch.Annotation");
+dojo.require("dojox.sketch.Anchor");
+(function(){
+var ta=dojox.sketch;
+ta.LeadAnnotation=function(_2,id){
+ta.Annotation.call(this,_2,id);
+this.transform={dx:0,dy:0};
+this.start={x:0,y:0};
+this.control={x:100,y:-50};
+this.end={x:200,y:0};
+this.textPosition={x:0,y:0};
+this.textOffset=4;
+this.textAlign="middle";
+this.textYOffset=10;
+this.pathShape=null;
+this.labelShape=null;
+this.anchors.start=new ta.Anchor(this,"start");
+this.anchors.control=new ta.Anchor(this,"control");
+this.anchors.end=new ta.Anchor(this,"end");
+};
+ta.LeadAnnotation.prototype=new ta.Annotation;
+var p=ta.LeadAnnotation.prototype;
+p.constructor=ta.LeadAnnotation;
+p.type=function(){
+return "Lead";
+};
+p.getType=function(){
+return ta.LeadAnnotation;
+};
+p._pos=function(){
+var _5=this.textOffset,x=0,y=0;
+var _8=this.calculate.slope(this.control,this.end);
+if(Math.abs(_8)>=1){
+x=this.end.x+this.calculate.dx(this.control,this.end,_5);
+if(this.control.y>this.end.y){
+y=this.end.y-_5;
+}else{
+y=this.end.y+_5+this.textYOffset;
+}
+}else{
+if(_8==0){
+x=this.end.x+_5;
+y=this.end.y+this.textYOffset;
+}else{
+if(this.start.x>this.end.x){
+x=this.end.x-_5;
+this.textAlign="end";
+}else{
+x=this.end.x+_5;
+this.textAlign="start";
+}
+if(this.start.y<this.end.y){
+y=this.end.y+this.calculate.dy(this.control,this.end,_5)+this.textYOffset;
+}else{
+y=this.end.y+this.calculate.dy(this.control,this.end,-_5);
+}
+}
+}
+this.textPosition={x:x,y:y};
+};
+p.apply=function(_9){
+if(!_9){
+return;
+}
+if(_9.documentElement){
+_9=_9.documentElement;
+}
+this.readCommonAttrs(_9);
+for(var i=0;i<_9.childNodes.length;i++){
+var c=_9.childNodes[i];
+if(c.localName=="text"){
+this.property("label",c.childNodes.length?c.childNodes[0].nodeValue:"");
+}else{
+if(c.localName=="path"){
+var d=c.getAttribute("d").split(" ");
+var s=d[0].split(",");
+this.start.x=parseFloat(s[0].substr(1),10);
+this.start.y=parseFloat(s[1],10);
+s=d[1].split(",");
+this.control.x=parseFloat(s[0].substr(1),10);
+this.control.y=parseFloat(s[1],10);
+s=d[2].split(",");
+this.end.x=parseFloat(s[0],10);
+this.end.y=parseFloat(s[1],10);
+var _e=this.property("stroke");
+var _f=c.getAttribute("style");
+var m=_f.match(/stroke:([^;]+);/);
+if(m){
+_e.color=m[1];
+this.property("fill",m[1]);
+}
+m=_f.match(/stroke-width:([^;]+);/);
+if(m){
+_e.width=m[1];
+}
+this.property("stroke",_e);
+}
+}
+}
+};
+p.initialize=function(obj){
+this.apply(obj);
+this._pos();
+this.shape=this.figure.group.createGroup();
+this.shape.getEventSource().setAttribute("id",this.id);
+this.pathShape=this.shape.createPath("M"+this.start.x+","+this.start.y+" Q"+this.control.x+","+this.control.y+" "+this.end.x+","+this.end.y+" l0,0");
+this.labelShape=this.shape.createText({x:this.textPosition.x,y:this.textPosition.y,text:this.property("label"),align:this.textAlign});
+this.labelShape.getEventSource().setAttribute("id",this.id+"-labelShape");
+this.draw();
+};
+p.destroy=function(){
+if(!this.shape){
+return;
+}
+this.shape.remove(this.pathShape);
+this.shape.remove(this.labelShape);
+this.figure.group.remove(this.shape);
+this.shape=this.pathShape=this.labelShape=null;
+};
+p.getBBox=function(){
+var x=Math.min(this.start.x,this.control.x,this.end.x);
+var y=Math.min(this.start.y,this.control.y,this.end.y);
+var w=Math.max(this.start.x,this.control.x,this.end.x)-x;
+var h=Math.max(this.start.y,this.control.y,this.end.y)-y;
+return {x:x,y:y,width:w,height:h};
+};
+p.draw=function(obj){
+this.apply(obj);
+this._pos();
+this.shape.setTransform(this.transform);
+this.pathShape.setShape("M"+this.start.x+","+this.start.y+" Q"+this.control.x+","+this.control.y+" "+this.end.x+","+this.end.y+" l0,0");
+this.labelShape.setShape({x:this.textPosition.x,y:this.textPosition.y,text:this.property("label")}).setFill(this.property("fill"));
+this.zoom();
+};
+p.serialize=function(){
+var _17=this.property("stroke");
+return "<g "+this.writeCommonAttrs()+">"+"<path style=\"stroke:"+_17.color+";stroke-width:"+_17.width+";fill:none;\" d=\""+"M"+this.start.x+","+this.start.y+" "+"Q"+this.control.x+","+this.control.y+" "+this.end.x+","+this.end.y+"\" />"+"<text style=\"fill:"+_17.color+";text-anchor:"+this.textAlign+"\" font-weight=\"bold\" "+"x=\""+this.textPosition.x+"\" "+"y=\""+this.textPosition.y+"\">"+this.property("label")+"</text>"+"</g>";
+};
+ta.Annotation.register("Lead");
+})();
+}
diff --git a/dojox/sketch/PreexistingAnnotation.js b/dojox/sketch/PreexistingAnnotation.js
new file mode 100644
index 0000000..fddcf4c
--- /dev/null
+++ b/dojox/sketch/PreexistingAnnotation.js
@@ -0,0 +1,141 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.sketch.PreexistingAnnotation"]){
+dojo._hasResource["dojox.sketch.PreexistingAnnotation"]=true;
+dojo.provide("dojox.sketch.PreexistingAnnotation");
+dojo.require("dojox.sketch.Annotation");
+dojo.require("dojox.sketch.Anchor");
+(function(){
+var ta=dojox.sketch;
+ta.PreexistingAnnotation=function(_2,id){
+ta.Annotation.call(this,_2,id);
+this.transform={dx:0,dy:0};
+this.start={x:0,y:0};
+this.end={x:200,y:200};
+this.radius=8;
+this.textPosition={x:196,y:196};
+this.textOffset=4;
+this.textAlign="end";
+this.rectShape=null;
+this.labelShape=null;
+this.anchors.start=new ta.Anchor(this,"start");
+this.anchors.end=new ta.Anchor(this,"end");
+};
+ta.PreexistingAnnotation.prototype=new ta.Annotation;
+var p=ta.PreexistingAnnotation.prototype;
+p.constructor=ta.PreexistingAnnotation;
+p.type=function(){
+return "Preexisting";
+};
+p.getType=function(){
+return ta.PreexistingAnnotation;
+};
+p._pos=function(){
+var x=Math.min(this.start.x,this.end.x);
+var y=Math.min(this.start.y,this.end.y);
+var w=Math.max(this.start.x,this.end.x);
+var h=Math.max(this.start.y,this.end.y);
+this.start={x:x,y:y};
+this.end={x:w,y:h};
+this.textPosition={x:this.end.x-this.textOffset,y:this.end.y-this.textOffset};
+};
+p.apply=function(_9){
+if(!_9){
+return;
+}
+if(_9.documentElement){
+_9=_9.documentElement;
+}
+this.readCommonAttrs(_9);
+for(var i=0;i<_9.childNodes.length;i++){
+var c=_9.childNodes[i];
+if(c.localName=="text"){
+this.property("label",c.childNodes.length?c.childNodes[0].nodeValue:"");
+}else{
+if(c.localName=="rect"){
+if(c.getAttribute("x")!==null){
+this.start.x=parseFloat(c.getAttribute("x"),10);
+}
+if(c.getAttribute("width")!==null){
+this.end.x=parseFloat(c.getAttribute("width"),10)+parseFloat(c.getAttribute("x"),10);
+}
+if(c.getAttribute("y")!==null){
+this.start.y=parseFloat(c.getAttribute("y"),10);
+}
+if(c.getAttribute("height")!==null){
+this.end.y=parseFloat(c.getAttribute("height"),10)+parseFloat(c.getAttribute("y"),10);
+}
+if(c.getAttribute("r")!==null){
+this.radius=parseFloat(c.getAttribute("r"),10);
+}
+var _c=this.property("stroke");
+var _d=c.getAttribute("style");
+var m=_d.match(/stroke:([^;]+);/);
+if(m){
+_c.color=m[1];
+this.property("fill",m[1]);
+}
+m=_d.match(/stroke-width:([^;]+);/);
+if(m){
+_c.width=m[1];
+}
+this.property("stroke",_c);
+}
+}
+}
+};
+p.initialize=function(_f){
+this.apply(_f);
+this._pos();
+this.shape=this.figure.group.createGroup();
+this.shape.getEventSource().setAttribute("id",this.id);
+this.rectShape=this.shape.createRect({x:this.start.x,y:this.start.y,width:this.end.x-this.start.x,height:this.end.y-this.start.y,r:this.radius}).setFill([255,255,255,0.1]);
+this.rectShape.getEventSource().setAttribute("shape-rendering","crispEdges");
+this.labelShape=this.shape.createText({x:this.textPosition.x,y:this.textPosition.y,text:this.property("label"),align:this.textAlign}).setFill(this.property("fill"));
+this.labelShape.getEventSource().setAttribute("id",this.id+"-labelShape");
+this.draw();
+};
+p.destroy=function(){
+if(!this.shape){
+return;
+}
+this.shape.remove(this.rectShape);
+this.shape.remove(this.labelShape);
+this.figure.group.remove(this.shape);
+this.shape=this.rectShape=this.labelShape=null;
+};
+p.getBBox=function(){
+var x=Math.min(this.start.x,this.end.x);
+var y=Math.min(this.start.y,this.end.y);
+var w=Math.max(this.start.x,this.end.x)-x;
+var h=Math.max(this.start.y,this.end.y)-y;
+return {x:x-2,y:y-2,width:w+4,height:h+4};
+};
+p.draw=function(obj){
+this.apply(obj);
+this._pos();
+this.shape.setTransform(this.transform);
+this.rectShape.setShape({x:this.start.x,y:this.start.y,width:this.end.x-this.start.x,height:this.end.y-this.start.y,r:this.radius}).setFill([255,255,255,0.1]);
+this.labelShape.setShape({x:this.textPosition.x,y:this.textPosition.y,text:this.property("label")}).setFill(this.property("fill"));
+this.zoom();
+};
+p.zoom=function(pct){
+if(this.rectShape){
+pct=pct||this.figure.zoomFactor;
+ta.Annotation.prototype.zoom.call(this,pct);
+pct=dojox.gfx.renderer=="vml"?1:pct;
+this.rectShape.setStroke({color:this.property("fill"),width:1/pct});
+}
+};
+p.serialize=function(){
+var s=this.property("stroke");
+return "<g "+this.writeCommonAttrs()+">"+"<rect style=\"stroke:"+s.color+";stroke-width:1;fill:none;\" "+"x=\""+this.start.x+"\" "+"width=\""+(this.end.x-this.start.x)+"\" "+"y=\""+this.start.y+"\" "+"height=\""+(this.end.y-this.start.y)+"\" "+"rx=\""+this.radius+"\" "+"ry=\""+this.radius+"\" "+" />"+"<text style=\"fill:"+s.color+";text-anchor:"+this.textAlign+"\" font-weight=\"bold\" "+"x=\""+this.textPosition.x+"\" "+"y=\""+this.textPosition.y+"\">"+this.property("label")+"</text>"+"</g>";
+};
+ta.Annotation.register("Preexisting");
+})();
+}
diff --git a/dojox/sketch/README b/dojox/sketch/README
new file mode 100644
index 0000000..217d3e9
--- /dev/null
+++ b/dojox/sketch/README
@@ -0,0 +1,58 @@
+-------------------------------------------------------------------------------
+dojox.sketch
+-------------------------------------------------------------------------------
+Version 0.1
+Release date: 28/01/2008
+-------------------------------------------------------------------------------
+Project state:
+experimental
+-------------------------------------------------------------------------------
+Credits
+	Contributed by TeamPatent (supported by National Science Foundation grant 638334)
+  Tom Trenka (ttrenka at gmail.com)
+  Heng Liu/LiuCougar (heng at teampatent.com)
+-------------------------------------------------------------------------------
+Project description
+
+A cross-browser drawing editor based on dojox.gfx.
+-------------------------------------------------------------------------------
+Dependencies:
+
+dijit (Toolbar, Button, Slider)
+dojox.gfx
+dojox.xml
+-------------------------------------------------------------------------------
+Documentation
+
+Currently, 5 shapes are supported: line, single arrow line, double arrow line,
+underline text and text. The first 3 shapes can have optinal text associated.
+
+Shapes can be added, deleted, moved and modified. All of these operations can
+be undo-ed or redo-ed.
+
+TODO:
+ * provide UI to change various properties on shapes (fill, stroke, text) and
+allow changing of background image
+ * serialize/unserialize in dojox.gfx to svg (and maybe vml as well?) (or another
+simplier format? such as a json based one, which is easier to parse, and then
+write a convertor to convert the json format to svg or any other format?)
+ * Move mousedown/up/move to each shape (to prepare for the following)
+ * Add shapes for other primitive shapes (needs to decide which primitive 
+dojox.gfx.shapes are useful), and add in support for user to group any 
+shapes/groups to form a single "compound shape" (need to add support to set 
+fill/stroke properties on the entire compound shape, which shallpropagate to 
+all children shapes)
+-------------------------------------------------------------------------------
+Installation instructions
+
+Install dijit, dojox.gfx and dojox.xml first
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/sketch.js
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/sketch/*
+
+Install into the following directory structure:
+/dojox/sketch/
+
+...which should be at the same level as your Dojo checkout.
+-------------------------------------------------------------------------------
diff --git a/dojox/sketch/SingleArrowAnnotation.js b/dojox/sketch/SingleArrowAnnotation.js
new file mode 100644
index 0000000..4b7114e
--- /dev/null
+++ b/dojox/sketch/SingleArrowAnnotation.js
@@ -0,0 +1,185 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.sketch.SingleArrowAnnotation"]){
+dojo._hasResource["dojox.sketch.SingleArrowAnnotation"]=true;
+dojo.provide("dojox.sketch.SingleArrowAnnotation");
+dojo.require("dojox.sketch.Annotation");
+dojo.require("dojox.sketch.Anchor");
+(function(){
+var ta=dojox.sketch;
+ta.SingleArrowAnnotation=function(_2,id){
+ta.Annotation.call(this,_2,id);
+this.transform={dx:0,dy:0};
+this.start={x:0,y:0};
+this.control={x:100,y:-50};
+this.end={x:200,y:0};
+this.textPosition={x:0,y:0};
+this.textOffset=4;
+this.textAlign="middle";
+this.textYOffset=10;
+this.rotation=0;
+this.pathShape=null;
+this.arrowhead=null;
+this.arrowheadGroup=null;
+this.labelShape=null;
+this.anchors.start=new ta.Anchor(this,"start");
+this.anchors.control=new ta.Anchor(this,"control");
+this.anchors.end=new ta.Anchor(this,"end");
+};
+ta.SingleArrowAnnotation.prototype=new ta.Annotation;
+var p=ta.SingleArrowAnnotation.prototype;
+p.constructor=ta.SingleArrowAnnotation;
+p.type=function(){
+return "SingleArrow";
+};
+p.getType=function(){
+return ta.SingleArrowAnnotation;
+};
+p._rot=function(){
+var _5=this.control.y-this.start.y;
+var _6=this.control.x-this.start.x;
+this.rotation=Math.atan2(_5,_6);
+};
+p._pos=function(){
+var _7=this.textOffset,x=0,y=0;
+var _a=this.calculate.slope(this.control,this.end);
+if(Math.abs(_a)>=1){
+x=this.end.x+this.calculate.dx(this.control,this.end,_7);
+if(this.control.y>this.end.y){
+y=this.end.y-_7;
+}else{
+y=this.end.y+_7+this.textYOffset;
+}
+}else{
+if(_a==0){
+x=this.end.x+_7;
+y=this.end.y+this.textYOffset;
+}else{
+if(this.start.x>this.end.x){
+x=this.end.x-_7;
+this.textAlign="end";
+}else{
+x=this.end.x+_7;
+this.textAlign="start";
+}
+if(this.start.y<this.end.y){
+y=this.end.y+this.calculate.dy(this.control,this.end,_7)+this.textYOffset;
+}else{
+y=this.end.y+this.calculate.dy(this.control,this.end,-_7);
+}
+}
+}
+this.textPosition={x:x,y:y};
+};
+p.apply=function(_b){
+if(!_b){
+return;
+}
+if(_b.documentElement){
+_b=_b.documentElement;
+}
+this.readCommonAttrs(_b);
+for(var i=0;i<_b.childNodes.length;i++){
+var c=_b.childNodes[i];
+if(c.localName=="text"){
+this.property("label",c.childNodes.length?c.childNodes[0].nodeValue:"");
+}else{
+if(c.localName=="path"){
+var d=c.getAttribute("d").split(" ");
+var s=d[0].split(",");
+this.start.x=parseFloat(s[0].substr(1),10);
+this.start.y=parseFloat(s[1],10);
+s=d[1].split(",");
+this.control.x=parseFloat(s[0].substr(1),10);
+this.control.y=parseFloat(s[1],10);
+s=d[2].split(",");
+this.end.x=parseFloat(s[0],10);
+this.end.y=parseFloat(s[1],10);
+var _10=this.property("stroke");
+var _11=c.getAttribute("style");
+var m=_11.match(/stroke:([^;]+);/);
+if(m){
+_10.color=m[1];
+this.property("fill",m[1]);
+}
+m=_11.match(/stroke-width:([^;]+);/);
+if(m){
+_10.width=m[1];
+}
+this.property("stroke",_10);
+}
+}
+}
+};
+p.initialize=function(obj){
+var _14=(ta.Annotation.labelFont)?ta.Annotation.labelFont:{family:"Times",size:"16px"};
+this.apply(obj);
+this._rot();
+this._pos();
+var rot=this.rotation;
+var _16=dojox.gfx.matrix.rotate(rot);
+this.shape=this.figure.group.createGroup();
+this.shape.getEventSource().setAttribute("id",this.id);
+this.pathShape=this.shape.createPath("M"+this.start.x+","+this.start.y+" Q"+this.control.x+","+this.control.y+" "+this.end.x+","+this.end.y+" l0,0");
+this.arrowheadGroup=this.shape.createGroup();
+this.arrowhead=this.arrowheadGroup.createPath();
+this.labelShape=this.shape.createText({x:this.textPosition.x,y:this.textPosition.y,text:this.property("label"),align:this.textAlign});
+this.labelShape.getEventSource().setAttribute("id",this.id+"-labelShape");
+this.draw();
+};
+p.destroy=function(){
+if(!this.shape){
+return;
+}
+this.arrowheadGroup.remove(this.arrowhead);
+this.shape.remove(this.arrowheadGroup);
+this.shape.remove(this.pathShape);
+this.shape.remove(this.labelShape);
+this.figure.group.remove(this.shape);
+this.shape=this.pathShape=this.labelShape=this.arrowheadGroup=this.arrowhead=null;
+};
+p.draw=function(obj){
+this.apply(obj);
+this._rot();
+this._pos();
+var rot=this.rotation;
+var _19=dojox.gfx.matrix.rotate(rot);
+this.shape.setTransform(this.transform);
+this.pathShape.setShape("M"+this.start.x+","+this.start.y+" Q"+this.control.x+","+this.control.y+" "+this.end.x+","+this.end.y+" l0,0");
+this.arrowheadGroup.setTransform({dx:this.start.x,dy:this.start.y}).applyTransform(_19);
+this.arrowhead.setFill(this.property("fill"));
+this.labelShape.setShape({x:this.textPosition.x,y:this.textPosition.y,text:this.property("label"),align:this.textAlign}).setFill(this.property("fill"));
+this.zoom();
+};
+p.zoom=function(pct){
+if(this.arrowhead){
+pct=pct||this.figure.zoomFactor;
+ta.Annotation.prototype.zoom.call(this,pct);
+if(this._curPct!==pct){
+this._curPct=pct;
+var l=pct>1?20:Math.floor(20/pct),w=pct>1?5:Math.floor(5/pct),h=pct>1?3:Math.floor(3/pct);
+this.arrowhead.setShape("M0,0 l"+l+",-"+w+" -"+h+","+w+" "+h+","+w+" Z");
+}
+}
+};
+p.getBBox=function(){
+var x=Math.min(this.start.x,this.control.x,this.end.x);
+var y=Math.min(this.start.y,this.control.y,this.end.y);
+var w=Math.max(this.start.x,this.control.x,this.end.x)-x;
+var h=Math.max(this.start.y,this.control.y,this.end.y)-y;
+return {x:x,y:y,width:w,height:h};
+};
+p.serialize=function(){
+var s=this.property("stroke");
+var r=this.rotation*(180/Math.PI);
+r=Math.round(r*Math.pow(10,4))/Math.pow(10,4);
+return "<g "+this.writeCommonAttrs()+">"+"<path style=\"stroke:"+s.color+";stroke-width:"+s.width+";fill:none;\" d=\""+"M"+this.start.x+","+this.start.y+" "+"Q"+this.control.x+","+this.control.y+" "+this.end.x+","+this.end.y+"\" />"+"<g transform=\"translate("+this.start.x+","+this.start.y+") "+"rotate("+r+")\">"+"<path style=\"fill:"+s.color+";\" d=\"M0,0 l20,-5, -3,5, 3,5 Z\" />"+"</g>"+"<text style=\"fill:"+s.color+";text-anchor:"+this.textAlign+"\" font-weight=\"bold\" "+"x=\""+this. [...]
+};
+ta.Annotation.register("SingleArrow");
+})();
+}
diff --git a/dojox/sketch/Slider.js b/dojox/sketch/Slider.js
new file mode 100644
index 0000000..2e70a33
--- /dev/null
+++ b/dojox/sketch/Slider.js
@@ -0,0 +1,32 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.sketch.Slider"]){
+dojo._hasResource["dojox.sketch.Slider"]=true;
+dojo.provide("dojox.sketch.Slider");
+dojo.require("dijit.form.HorizontalSlider");
+dojo.declare("dojox.sketch.Slider",dojox.sketch._Plugin,{_initButton:function(){
+this.slider=new dijit.form.HorizontalSlider({minimum:20,maximum:200,value:20,style:"width:200px;float:right"});
+this.slider._movable.node.title="Double Click to \"Zoom to Fit\"";
+this.connect(this.slider,"onChange","_setZoom");
+this.connect(this.slider.sliderHandle,"ondblclick","_zoomToFit");
+},_zoomToFit:function(){
+var r=this.figure.getFit();
+this.slider.attr("value",this.slider.maximum<r?this.slider.maximum:(this.slider.minimum>r?this.slider.minimum:r));
+},_setZoom:function(v){
+if(this.figure){
+this.figure.zoom(v);
+}
+},setToolbar:function(t){
+t.addChild(this.slider);
+if(!t._reset2Zoom){
+t._reset2Zoom=true;
+this.connect(t,"reset","_zoomToFit");
+}
+}});
+dojox.sketch.registerTool("Slider",dojox.sketch.Slider);
+}
diff --git a/dojox/sketch/Toolbar.js b/dojox/sketch/Toolbar.js
new file mode 100644
index 0000000..64e15a4
--- /dev/null
+++ b/dojox/sketch/Toolbar.js
@@ -0,0 +1,78 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.sketch.Toolbar"]){
+dojo._hasResource["dojox.sketch.Toolbar"]=true;
+dojo.provide("dojox.sketch.Toolbar");
+dojo.require("dojox.sketch.Annotation");
+dojo.require("dijit.Toolbar");
+dojo.require("dijit.form.Button");
+dojo.declare("dojox.sketch.ButtonGroup",null,{constructor:function(){
+this._childMaps={};
+this._children=[];
+},add:function(_1){
+this._childMaps[_1]=_1.connect(_1,"onActivate",dojo.hitch(this,"_resetGroup",_1));
+this._children.push(_1);
+},_resetGroup:function(p){
+var cs=this._children;
+dojo.forEach(cs,function(c){
+if(p!=c&&c["attr"]){
+c.attr("checked",false);
+}
+});
+}});
+dojo.declare("dojox.sketch.Toolbar",dijit.Toolbar,{figure:null,plugins:null,postCreate:function(){
+this.inherited(arguments);
+this.shapeGroup=new dojox.sketch.ButtonGroup;
+this.connect(this.figure,"onLoad","reset");
+if(!this.plugins){
+this.plugins=["Slider","Lead","SingleArrow","DoubleArrow","Underline","Preexisting"];
+}
+this._plugins=[];
+dojo.forEach(this.plugins,function(_5){
+var _6=dojo.isString(_5)?_5:_5.name;
+var p=new dojox.sketch.tools[_6](_5.args||{});
+this._plugins.push(p);
+p.setFigure(this.figure);
+p.setToolbar(this);
+if(!this._defaultTool&&p.button){
+this._defaultTool=p;
+}
+},this);
+},destroy:function(){
+dojo.forEach(this._plugins,function(p){
+p.destroy();
+});
+this.inherited(arguments);
+delete this._defaultTool;
+delete this._plugins;
+},addGroupItem:function(_9,_a){
+if(_a!="toolsGroup"){
+console.error("not supported group "+_a);
+return;
+}
+this.shapeGroup.add(_9);
+},reset:function(){
+this._defaultTool.activate();
+},_setShape:function(s){
+if(!this.figure.surface){
+return;
+}
+if(this.figure.hasSelections()){
+for(var i=0;i<this.figure.selected.length;i++){
+var _d=this.figure.selected[i].serialize();
+this.figure.convert(this.figure.selected[i],s);
+this.figure.history.add(dojox.sketch.CommandTypes.Convert,this.figure.selected[i],_d);
+}
+}
+}});
+dojox.sketch.makeToolbar=function(_e,_f){
+var _10=new dojox.sketch.Toolbar({"figure":_f});
+_e.appendChild(_10.domNode);
+return _10;
+};
+}
diff --git a/dojox/sketch/UnderlineAnnotation.js b/dojox/sketch/UnderlineAnnotation.js
new file mode 100644
index 0000000..8b823f0
--- /dev/null
+++ b/dojox/sketch/UnderlineAnnotation.js
@@ -0,0 +1,103 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.sketch.UnderlineAnnotation"]){
+dojo._hasResource["dojox.sketch.UnderlineAnnotation"]=true;
+dojo.provide("dojox.sketch.UnderlineAnnotation");
+dojo.require("dojox.sketch.Annotation");
+dojo.require("dojox.sketch.Anchor");
+(function(){
+var ta=dojox.sketch;
+ta.UnderlineAnnotation=function(_2,id){
+ta.Annotation.call(this,_2,id);
+this.transform={dx:0,dy:0};
+this.start={x:0,y:0};
+this.property("label","#");
+this.labelShape=null;
+this.lineShape=null;
+};
+ta.UnderlineAnnotation.prototype=new ta.Annotation;
+var p=ta.UnderlineAnnotation.prototype;
+p.constructor=ta.UnderlineAnnotation;
+p.type=function(){
+return "Underline";
+};
+p.getType=function(){
+return ta.UnderlineAnnotation;
+};
+p.apply=function(_5){
+if(!_5){
+return;
+}
+if(_5.documentElement){
+_5=_5.documentElement;
+}
+this.readCommonAttrs(_5);
+for(var i=0;i<_5.childNodes.length;i++){
+var c=_5.childNodes[i];
+if(c.localName=="text"){
+this.property("label",c.childNodes[0].nodeValue);
+var _8=c.getAttribute("style");
+var m=_8.match(/fill:([^;]+);/);
+if(m){
+var _a=this.property("stroke");
+_a.collor=m[1];
+this.property("stroke",_a);
+this.property("fill",_a.collor);
+}
+}
+}
+};
+p.initialize=function(_b){
+this.apply(_b);
+this.shape=this.figure.group.createGroup();
+this.shape.getEventSource().setAttribute("id",this.id);
+this.labelShape=this.shape.createText({x:0,y:0,text:this.property("label"),decoration:"underline",align:"start"});
+this.labelShape.getEventSource().setAttribute("id",this.id+"-labelShape");
+this.lineShape=this.shape.createLine({x1:1,x2:this.labelShape.getTextWidth(),y1:2,y2:2});
+this.lineShape.getEventSource().setAttribute("shape-rendering","crispEdges");
+this.draw();
+};
+p.destroy=function(){
+if(!this.shape){
+return;
+}
+this.shape.remove(this.labelShape);
+this.shape.remove(this.lineShape);
+this.figure.group.remove(this.shape);
+this.shape=this.lineShape=this.labelShape=null;
+};
+p.getBBox=function(){
+var b=this.getTextBox();
+var z=this.figure.zoomFactor;
+return {x:0,y:(b.h*-1+4)/z,width:(b.w+2)/z,height:b.h/z};
+};
+p.draw=function(_e){
+this.apply(_e);
+this.shape.setTransform(this.transform);
+this.labelShape.setShape({x:0,y:0,text:this.property("label")}).setFill(this.property("fill"));
+this.zoom();
+};
+p.zoom=function(_f){
+if(this.labelShape){
+_f=_f||this.figure.zoomFactor;
+var _10=dojox.gfx.renderer=="vml"?0:2/_f;
+ta.Annotation.prototype.zoom.call(this,_f);
+_f=dojox.gfx.renderer=="vml"?1:_f;
+this.lineShape.setShape({x1:0,x2:this.getBBox().width-_10,y1:2,y2:2}).setStroke({color:this.property("fill"),width:1/_f});
+if(this.mode==ta.Annotation.Modes.Edit){
+this.drawBBox();
+}
+}
+};
+p.serialize=function(){
+var s=this.property("stroke");
+return "<g "+this.writeCommonAttrs()+">"+"<text style=\"fill:"+this.property("fill")+";\" font-weight=\"bold\" text-decoration=\"underline\" "+"x=\"0\" y=\"0\">"+this.property("label")+"</text>"+"</g>";
+};
+ta.Annotation.register("Underline");
+})();
+}
diff --git a/dojox/sketch/UndoStack.js b/dojox/sketch/UndoStack.js
new file mode 100644
index 0000000..ce7faee
--- /dev/null
+++ b/dojox/sketch/UndoStack.js
@@ -0,0 +1,71 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.sketch.UndoStack"]){
+dojo._hasResource["dojox.sketch.UndoStack"]=true;
+dojo.provide("dojox.sketch.UndoStack");
+dojo.require("dojox.xml.DomParser");
+(function(){
+var ta=dojox.sketch;
+ta.CommandTypes={Create:"Create",Move:"Move",Modify:"Modify",Delete:"Delete",Convert:"Convert"};
+dojo.declare("dojox.sketch.UndoStack",null,{constructor:function(_2){
+this.figure=_2;
+this._steps=[];
+this._undoedSteps=[];
+},apply:function(_3,_4,to){
+if(!_4&&!to&&_3.fullText){
+this.figure.setValue(_3.fullText);
+return;
+}
+var _6=_4.shapeText;
+var _7=to.shapeText;
+if(_6.length==0&&_7.length==0){
+return;
+}
+if(_6.length==0){
+var o=dojox.xml.DomParser.parse(_7).documentElement;
+var a=this.figure._loadAnnotation(o);
+if(a){
+this.figure._add(a);
+}
+return;
+}
+if(_7.length==0){
+var _a=this.figure.get(_4.shapeId);
+this.figure._delete([_a],true);
+return;
+}
+var _b=this.figure.get(to.shapeId);
+var no=dojox.xml.DomParser.parse(_7).documentElement;
+_b.draw(no);
+this.figure.select(_b);
+return;
+},add:function(_d,_e,_f){
+var id=_e?_e.id:"";
+var _11=_e?_e.serialize():"";
+if(_d==ta.CommandTypes.Delete){
+_11="";
+}
+var _12={cmdname:_d,before:{shapeId:id,shapeText:_f||""},after:{shapeId:id,shapeText:_11}};
+this._steps.push(_12);
+this._undoedSteps=[];
+},destroy:function(){
+},undo:function(){
+var _13=this._steps.pop();
+if(_13){
+this._undoedSteps.push(_13);
+this.apply(_13,_13.after,_13.before);
+}
+},redo:function(){
+var _14=this._undoedSteps.pop();
+if(_14){
+this._steps.push(_14);
+this.apply(_14,_14.before,_14.after);
+}
+}});
+})();
+}
diff --git a/dojox/sketch/_Plugin.js b/dojox/sketch/_Plugin.js
new file mode 100644
index 0000000..65388b7
--- /dev/null
+++ b/dojox/sketch/_Plugin.js
@@ -0,0 +1,51 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.sketch._Plugin"]){
+dojo._hasResource["dojox.sketch._Plugin"]=true;
+dojo.provide("dojox.sketch._Plugin");
+dojo.require("dijit.form.Button");
+dojo.declare("dojox.sketch._Plugin",null,{constructor:function(_1){
+if(_1){
+dojo.mixin(this,_1);
+}
+this._connects=[];
+},figure:null,iconClassPrefix:"dojoxSketchIcon",itemGroup:"toolsGroup",button:null,queryCommand:null,shape:"",useDefaultCommand:true,buttonClass:dijit.form.ToggleButton,_initButton:function(){
+if(this.shape.length){
+var _2=this.iconClassPrefix+" "+this.iconClassPrefix+this.shape.charAt(0).toUpperCase()+this.shape.substr(1);
+if(!this.button){
+var _3={label:this.shape,showLabel:false,iconClass:_2,dropDown:this.dropDown,tabIndex:"-1"};
+this.button=new this.buttonClass(_3);
+this.connect(this.button,"onClick","activate");
+}
+}
+},attr:function(_4,_5){
+return this.button.attr(_4,_5);
+},onActivate:function(){
+},activate:function(e){
+this.onActivate();
+this.figure.setTool(this);
+this.attr("checked",true);
+},onMouseDown:function(e){
+},onMouseMove:function(e){
+},onMouseUp:function(e){
+},destroy:function(f){
+dojo.forEach(this._connects,dojo.disconnect);
+},connect:function(o,f,tf){
+this._connects.push(dojo.connect(o,f,this,tf));
+},setFigure:function(_e){
+this.figure=_e;
+this._initButton();
+},setToolbar:function(_f){
+if(this.button){
+_f.addChild(this.button);
+}
+if(this.itemGroup){
+_f.addGroupItem(this,this.itemGroup);
+}
+}});
+}
diff --git a/dojox/sketch/resources/images/icons.gif b/dojox/sketch/resources/images/icons.gif
new file mode 100644
index 0000000..ab33b0a
Binary files /dev/null and b/dojox/sketch/resources/images/icons.gif differ
diff --git a/dojox/sketch/resources/sketch.css b/dojox/sketch/resources/sketch.css
new file mode 100644
index 0000000..7451395
--- /dev/null
+++ b/dojox/sketch/resources/sketch.css
@@ -0,0 +1,17 @@
+.dojoxSketchIcon{
+	background-repeat:no-repeat;
+	height:16px;
+	min-width:16px;
+	text-align:center;
+	width:16px;
+}
+.dojoxSketchIcon { background-image:url(images/icons.gif); }
+.ShowCallouts{ background-position:0px 0px; }
+.PreviousCallout{ background-position:0px -16px; }
+.NextCallout{ background-position:0px -32px; }
+.dojoxSketchIconLead{ background-position:0px -48px; }
+.dojoxSketchIconUnderline{ background-position:0px -64px; }
+.dojoxSketchIconSingleArrow{ background-position:0px -80px; }
+.dojoxSketchIconBrace{ background-position:0px -96px; }
+.dojoxSketchIconDoubleArrow{ background-position:0px -112px; }
+.dojoxSketchIconPreexisting{ background-position:0px -128px; }
diff --git a/dojox/sql.js b/dojox/sql.js
new file mode 100644
index 0000000..086b046
--- /dev/null
+++ b/dojox/sql.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.sql"]){
+dojo._hasResource["dojox.sql"]=true;
+dojo.provide("dojox.sql");
+dojo.require("dojox.sql._base");
+}
diff --git a/dojox/sql/LICENSE b/dojox/sql/LICENSE
new file mode 100644
index 0000000..5c277ec
--- /dev/null
+++ b/dojox/sql/LICENSE
@@ -0,0 +1,9 @@
+License Disclaimer:
+
+All contents of this directory are Copyright (c) the Dojo Foundation, with the
+following exceptions:
+-------------------------------------------------------------------------------
+
+_crypto.js - internally uses AES algorithm	
+	* AES algorithm copyright Chris Veness (CLA signed and permission given to use code under BSD license)
+      Taken from http://www.movable-type.co.uk/scripts/aes.html
diff --git a/dojox/sql/README b/dojox/sql/README
new file mode 100644
index 0000000..3a4cc6b
--- /dev/null
+++ b/dojox/sql/README
@@ -0,0 +1,32 @@
+-------------------------------------------------------------------------------
+dojox.sql
+-------------------------------------------------------------------------------
+Version X.XXX
+Release date: MM/DD/YYYY
+-------------------------------------------------------------------------------
+Project state:
+experimental
+-------------------------------------------------------------------------------
+Credits
+	Brad Neuberg
+-------------------------------------------------------------------------------
+Project description
+
+Code to interface with the Google Gears-specific SQL engine, used
+by dojox.storage and dojox.off. 
+-------------------------------------------------------------------------------
+Dependencies:
+
+Google Gears (gears.google.com)
+-------------------------------------------------------------------------------
+Documentation
+
+TBD
+-------------------------------------------------------------------------------
+Installation instructions
+
+TBD
+-------------------------------------------------------------------------------
+Additional Notes
+
+We should consider relocating crypto code to dojox.encoding
diff --git a/dojox/sql/_base.js b/dojox/sql/_base.js
new file mode 100644
index 0000000..9dbd4cf
--- /dev/null
+++ b/dojox/sql/_base.js
@@ -0,0 +1,333 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.sql._base"]){
+dojo._hasResource["dojox.sql._base"]=true;
+dojo.provide("dojox.sql._base");
+dojo.require("dojox.sql._crypto");
+dojo.mixin(dojox.sql,{dbName:null,debug:(dojo.exists("dojox.sql.debug")?dojox.sql.debug:false),open:function(_1){
+if(this._dbOpen&&(!_1||_1==this.dbName)){
+return;
+}
+if(!this.dbName){
+this.dbName="dot_store_"+window.location.href.replace(/[^0-9A-Za-z_]/g,"_");
+if(this.dbName.length>63){
+this.dbName=this.dbName.substring(0,63);
+}
+}
+if(!_1){
+_1=this.dbName;
+}
+try{
+this._initDb();
+this.db.open(_1);
+this._dbOpen=true;
+}
+catch(exp){
+throw exp.message||exp;
+}
+},close:function(_2){
+if(dojo.isIE){
+return;
+}
+if(!this._dbOpen&&(!_2||_2==this.dbName)){
+return;
+}
+if(!_2){
+_2=this.dbName;
+}
+try{
+this.db.close(_2);
+this._dbOpen=false;
+}
+catch(exp){
+throw exp.message||exp;
+}
+},_exec:function(_3){
+try{
+this._initDb();
+if(!this._dbOpen){
+this.open();
+this._autoClose=true;
+}
+var _4=null;
+var _5=null;
+var _6=null;
+var _7=dojo._toArray(_3);
+_4=_7.splice(0,1)[0];
+if(this._needsEncrypt(_4)||this._needsDecrypt(_4)){
+_5=_7.splice(_7.length-1,1)[0];
+_6=_7.splice(_7.length-1,1)[0];
+}
+if(this.debug){
+this._printDebugSQL(_4,_7);
+}
+var _8;
+if(this._needsEncrypt(_4)){
+_8=new dojox.sql._SQLCrypto("encrypt",_4,_6,_7,_5);
+return null;
+}else{
+if(this._needsDecrypt(_4)){
+_8=new dojox.sql._SQLCrypto("decrypt",_4,_6,_7,_5);
+return null;
+}
+}
+var rs=this.db.execute(_4,_7);
+rs=this._normalizeResults(rs);
+if(this._autoClose){
+this.close();
+}
+return rs;
+}
+catch(exp){
+exp=exp.message||exp;
+
+if(this._autoClose){
+try{
+this.close();
+}
+catch(e){
+
+}
+}
+throw exp;
+}
+return null;
+},_initDb:function(){
+if(!this.db){
+try{
+this.db=google.gears.factory.create("beta.database","1.0");
+}
+catch(exp){
+dojo.setObject("google.gears.denied",true);
+if(dojox.off){
+dojox.off.onFrameworkEvent("coreOperationFailed");
+}
+throw "Google Gears must be allowed to run";
+}
+}
+},_printDebugSQL:function(_a,_b){
+var _c="dojox.sql(\""+_a+"\"";
+for(var i=0;i<_b.length;i++){
+if(typeof _b[i]=="string"){
+_c+=", \""+_b[i]+"\"";
+}else{
+_c+=", "+_b[i];
+}
+}
+_c+=")";
+
+},_normalizeResults:function(rs){
+var _f=[];
+if(!rs){
+return [];
+}
+while(rs.isValidRow()){
+var row={};
+for(var i=0;i<rs.fieldCount();i++){
+var _12=rs.fieldName(i);
+var _13=rs.field(i);
+row[_12]=_13;
+}
+_f.push(row);
+rs.next();
+}
+rs.close();
+return _f;
+},_needsEncrypt:function(sql){
+return /encrypt\([^\)]*\)/i.test(sql);
+},_needsDecrypt:function(sql){
+return /decrypt\([^\)]*\)/i.test(sql);
+}});
+dojo.declare("dojox.sql._SQLCrypto",null,{constructor:function(_16,sql,_18,_19,_1a){
+if(_16=="encrypt"){
+this._execEncryptSQL(sql,_18,_19,_1a);
+}else{
+this._execDecryptSQL(sql,_18,_19,_1a);
+}
+},_execEncryptSQL:function(sql,_1c,_1d,_1e){
+var _1f=this._stripCryptoSQL(sql);
+var _20=this._flagEncryptedArgs(sql,_1d);
+var _21=this;
+this._encrypt(_1f,_1c,_1d,_20,function(_22){
+var _23=false;
+var _24=[];
+var exp=null;
+try{
+_24=dojox.sql.db.execute(_1f,_22);
+}
+catch(execError){
+_23=true;
+exp=execError.message||execError;
+}
+if(exp!=null){
+if(dojox.sql._autoClose){
+try{
+dojox.sql.close();
+}
+catch(e){
+}
+}
+_1e(null,true,exp.toString());
+return;
+}
+_24=dojox.sql._normalizeResults(_24);
+if(dojox.sql._autoClose){
+dojox.sql.close();
+}
+if(dojox.sql._needsDecrypt(sql)){
+var _26=_21._determineDecryptedColumns(sql);
+_21._decrypt(_24,_26,_1c,function(_27){
+_1e(_27,false,null);
+});
+}else{
+_1e(_24,false,null);
+}
+});
+},_execDecryptSQL:function(sql,_29,_2a,_2b){
+var _2c=this._stripCryptoSQL(sql);
+var _2d=this._determineDecryptedColumns(sql);
+var _2e=false;
+var _2f=[];
+var exp=null;
+try{
+_2f=dojox.sql.db.execute(_2c,_2a);
+}
+catch(execError){
+_2e=true;
+exp=execError.message||execError;
+}
+if(exp!=null){
+if(dojox.sql._autoClose){
+try{
+dojox.sql.close();
+}
+catch(e){
+}
+}
+_2b(_2f,true,exp.toString());
+return;
+}
+_2f=dojox.sql._normalizeResults(_2f);
+if(dojox.sql._autoClose){
+dojox.sql.close();
+}
+this._decrypt(_2f,_2d,_29,function(_31){
+_2b(_31,false,null);
+});
+},_encrypt:function(sql,_33,_34,_35,_36){
+this._totalCrypto=0;
+this._finishedCrypto=0;
+this._finishedSpawningCrypto=false;
+this._finalArgs=_34;
+for(var i=0;i<_34.length;i++){
+if(_35[i]){
+var _38=_34[i];
+var _39=i;
+this._totalCrypto++;
+dojox.sql._crypto.encrypt(_38,_33,dojo.hitch(this,function(_3a){
+this._finalArgs[_39]=_3a;
+this._finishedCrypto++;
+if(this._finishedCrypto>=this._totalCrypto&&this._finishedSpawningCrypto){
+_36(this._finalArgs);
+}
+}));
+}
+}
+this._finishedSpawningCrypto=true;
+},_decrypt:function(_3b,_3c,_3d,_3e){
+this._totalCrypto=0;
+this._finishedCrypto=0;
+this._finishedSpawningCrypto=false;
+this._finalResultSet=_3b;
+for(var i=0;i<_3b.length;i++){
+var row=_3b[i];
+for(var _41 in row){
+if(_3c=="*"||_3c[_41]){
+this._totalCrypto++;
+var _42=row[_41];
+this._decryptSingleColumn(_41,_42,_3d,i,function(_43){
+_3e(_43);
+});
+}
+}
+}
+this._finishedSpawningCrypto=true;
+},_stripCryptoSQL:function(sql){
+sql=sql.replace(/DECRYPT\(\*\)/ig,"*");
+var _45=sql.match(/ENCRYPT\([^\)]*\)/ig);
+if(_45!=null){
+for(var i=0;i<_45.length;i++){
+var _47=_45[i];
+var _48=_47.match(/ENCRYPT\(([^\)]*)\)/i)[1];
+sql=sql.replace(_47,_48);
+}
+}
+_45=sql.match(/DECRYPT\([^\)]*\)/ig);
+if(_45!=null){
+for(i=0;i<_45.length;i++){
+var _49=_45[i];
+var _4a=_49.match(/DECRYPT\(([^\)]*)\)/i)[1];
+sql=sql.replace(_49,_4a);
+}
+}
+return sql;
+},_flagEncryptedArgs:function(sql,_4c){
+var _4d=new RegExp(/([\"][^\"]*\?[^\"]*[\"])|([\'][^\']*\?[^\']*[\'])|(\?)/ig);
+var _4e;
+var _4f=0;
+var _50=[];
+while((_4e=_4d.exec(sql))!=null){
+var _51=RegExp.lastMatch+"";
+if(/^[\"\']/.test(_51)){
+continue;
+}
+var _52=false;
+if(/ENCRYPT\([^\)]*$/i.test(RegExp.leftContext)){
+_52=true;
+}
+_50[_4f]=_52;
+_4f++;
+}
+return _50;
+},_determineDecryptedColumns:function(sql){
+var _54={};
+if(/DECRYPT\(\*\)/i.test(sql)){
+_54="*";
+}else{
+var _55=/DECRYPT\((?:\s*\w*\s*\,?)*\)/ig;
+var _56=_55.exec(sql);
+while(_56){
+var _57=new String(RegExp.lastMatch);
+var _58=_57.replace(/DECRYPT\(/i,"");
+_58=_58.replace(/\)/,"");
+_58=_58.split(/\s*,\s*/);
+dojo.forEach(_58,function(_59){
+if(/\s*\w* AS (\w*)/i.test(_59)){
+_59=_59.match(/\s*\w* AS (\w*)/i)[1];
+}
+_54[_59]=true;
+});
+_56=_55.exec(sql);
+}
+}
+return _54;
+},_decryptSingleColumn:function(_5a,_5b,_5c,_5d,_5e){
+dojox.sql._crypto.decrypt(_5b,_5c,dojo.hitch(this,function(_5f){
+this._finalResultSet[_5d][_5a]=_5f;
+this._finishedCrypto++;
+if(this._finishedCrypto>=this._totalCrypto&&this._finishedSpawningCrypto){
+_5e(this._finalResultSet);
+}
+}));
+}});
+(function(){
+var _60=dojox.sql;
+dojox.sql=new Function("return dojox.sql._exec(arguments);");
+dojo.mixin(dojox.sql,_60);
+})();
+}
diff --git a/dojox/sql/_crypto.js b/dojox/sql/_crypto.js
new file mode 100644
index 0000000..9b623b1
--- /dev/null
+++ b/dojox/sql/_crypto.js
@@ -0,0 +1,293 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.sql._crypto"]){
+dojo._hasResource["dojox.sql._crypto"]=true;
+dojo.provide("dojox.sql._crypto");
+dojo.mixin(dojox.sql._crypto,{_POOL_SIZE:100,encrypt:function(_1,_2,_3){
+this._initWorkerPool();
+var _4={plaintext:_1,password:_2};
+_4=dojo.toJson(_4);
+_4="encr:"+String(_4);
+this._assignWork(_4,_3);
+},decrypt:function(_5,_6,_7){
+this._initWorkerPool();
+var _8={ciphertext:_5,password:_6};
+_8=dojo.toJson(_8);
+_8="decr:"+String(_8);
+this._assignWork(_8,_7);
+},_initWorkerPool:function(){
+if(!this._manager){
+try{
+this._manager=google.gears.factory.create("beta.workerpool","1.0");
+this._unemployed=[];
+this._employed={};
+this._handleMessage=[];
+var _9=this;
+this._manager.onmessage=function(_a,_b){
+var _c=_9._employed["_"+_b];
+_9._employed["_"+_b]=undefined;
+_9._unemployed.push("_"+_b);
+if(_9._handleMessage.length){
+var _d=_9._handleMessage.shift();
+_9._assignWork(_d.msg,_d.callback);
+}
+_c(_a);
+};
+var _e="function _workerInit(){"+"gearsWorkerPool.onmessage = "+String(this._workerHandler)+";"+"}";
+var _f=_e+" _workerInit();";
+for(var i=0;i<this._POOL_SIZE;i++){
+this._unemployed.push("_"+this._manager.createWorker(_f));
+}
+}
+catch(exp){
+throw exp.message||exp;
+}
+}
+},_assignWork:function(msg,_12){
+if(!this._handleMessage.length&&this._unemployed.length){
+var _13=this._unemployed.shift().substring(1);
+this._employed["_"+_13]=_12;
+this._manager.sendMessage(msg,parseInt(_13,10));
+}else{
+this._handleMessage={msg:msg,callback:_12};
+}
+},_workerHandler:function(msg,_15){
+var _16=[99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253,147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,236,95,151,68,23 [...]
+var _17=[[0,0,0,0],[1,0,0,0],[2,0,0,0],[4,0,0,0],[8,0,0,0],[16,0,0,0],[32,0,0,0],[64,0,0,0],[128,0,0,0],[27,0,0,0],[54,0,0,0]];
+function _18(_19,w){
+var Nb=4;
+var Nr=w.length/Nb-1;
+var _1d=[[],[],[],[]];
+for(var i=0;i<4*Nb;i++){
+_1d[i%4][Math.floor(i/4)]=_19[i];
+}
+_1d=_1f(_1d,w,0,Nb);
+for(var _20=1;_20<Nr;_20++){
+_1d=_21(_1d,Nb);
+_1d=_22(_1d,Nb);
+_1d=_23(_1d,Nb);
+_1d=_1f(_1d,w,_20,Nb);
+}
+_1d=_21(_1d,Nb);
+_1d=_22(_1d,Nb);
+_1d=_1f(_1d,w,Nr,Nb);
+var _24=new Array(4*Nb);
+for(var i=0;i<4*Nb;i++){
+_24[i]=_1d[i%4][Math.floor(i/4)];
+}
+return _24;
+};
+function _21(s,Nb){
+for(var r=0;r<4;r++){
+for(var c=0;c<Nb;c++){
+s[r][c]=_16[s[r][c]];
+}
+}
+return s;
+};
+function _22(s,Nb){
+var t=new Array(4);
+for(var r=1;r<4;r++){
+for(var c=0;c<4;c++){
+t[c]=s[r][(c+r)%Nb];
+}
+for(var c=0;c<4;c++){
+s[r][c]=t[c];
+}
+}
+return s;
+};
+function _23(s,Nb){
+for(var c=0;c<4;c++){
+var a=new Array(4);
+var b=new Array(4);
+for(var i=0;i<4;i++){
+a[i]=s[i][c];
+b[i]=s[i][c]&128?s[i][c]<<1^283:s[i][c]<<1;
+}
+s[0][c]=b[0]^a[1]^b[1]^a[2]^a[3];
+s[1][c]=a[0]^b[1]^a[2]^b[2]^a[3];
+s[2][c]=a[0]^a[1]^b[2]^a[3]^b[3];
+s[3][c]=a[0]^b[0]^a[1]^a[2]^b[3];
+}
+return s;
+};
+function _1f(_34,w,rnd,Nb){
+for(var r=0;r<4;r++){
+for(var c=0;c<Nb;c++){
+_34[r][c]^=w[rnd*4+c][r];
+}
+}
+return _34;
+};
+function _3a(key){
+var Nb=4;
+var Nk=key.length/4;
+var Nr=Nk+6;
+var w=new Array(Nb*(Nr+1));
+var _40=new Array(4);
+for(var i=0;i<Nk;i++){
+var r=[key[4*i],key[4*i+1],key[4*i+2],key[4*i+3]];
+w[i]=r;
+}
+for(var i=Nk;i<(Nb*(Nr+1));i++){
+w[i]=new Array(4);
+for(var t=0;t<4;t++){
+_40[t]=w[i-1][t];
+}
+if(i%Nk==0){
+_40=_44(_45(_40));
+for(var t=0;t<4;t++){
+_40[t]^=_17[i/Nk][t];
+}
+}else{
+if(Nk>6&&i%Nk==4){
+_40=_44(_40);
+}
+}
+for(var t=0;t<4;t++){
+w[i][t]=w[i-Nk][t]^_40[t];
+}
+}
+return w;
+};
+function _44(w){
+for(var i=0;i<4;i++){
+w[i]=_16[w[i]];
+}
+return w;
+};
+function _45(w){
+w[4]=w[0];
+for(var i=0;i<4;i++){
+w[i]=w[i+1];
+}
+return w;
+};
+function _4a(_4b,_4c,_4d){
+if(!(_4d==128||_4d==192||_4d==256)){
+return "";
+}
+var _4e=_4d/8;
+var _4f=new Array(_4e);
+for(var i=0;i<_4e;i++){
+_4f[i]=_4c.charCodeAt(i)&255;
+}
+var key=_18(_4f,_3a(_4f));
+key=key.concat(key.slice(0,_4e-16));
+var _52=16;
+var _53=new Array(_52);
+var _54=(new Date()).getTime();
+for(var i=0;i<4;i++){
+_53[i]=(_54>>>i*8)&255;
+}
+for(var i=0;i<4;i++){
+_53[i+4]=(_54/4294967296>>>i*8)&255;
+}
+var _55=_3a(key);
+var _56=Math.ceil(_4b.length/_52);
+var _57=new Array(_56);
+for(var b=0;b<_56;b++){
+for(var c=0;c<4;c++){
+_53[15-c]=(b>>>c*8)&255;
+}
+for(var c=0;c<4;c++){
+_53[15-c-4]=(b/4294967296>>>c*8);
+}
+var _5a=_18(_53,_55);
+var _5b=b<_56-1?_52:(_4b.length-1)%_52+1;
+var ct="";
+for(var i=0;i<_5b;i++){
+var _5d=_4b.charCodeAt(b*_52+i);
+var _5e=_5d^_5a[i];
+ct+=String.fromCharCode(_5e);
+}
+_57[b]=_5f(ct);
+}
+var _60="";
+for(var i=0;i<8;i++){
+_60+=String.fromCharCode(_53[i]);
+}
+_60=_5f(_60);
+return _60+"-"+_57.join("-");
+};
+function _61(_62,_63,_64){
+if(!(_64==128||_64==192||_64==256)){
+return "";
+}
+var _65=_64/8;
+var _66=new Array(_65);
+for(var i=0;i<_65;i++){
+_66[i]=_63.charCodeAt(i)&255;
+}
+var _68=_3a(_66);
+var key=_18(_66,_68);
+key=key.concat(key.slice(0,_65-16));
+var _6a=_3a(key);
+_62=_62.split("-");
+var _6b=16;
+var _6c=new Array(_6b);
+var _6d=_6e(_62[0]);
+for(var i=0;i<8;i++){
+_6c[i]=_6d.charCodeAt(i);
+}
+var _6f=new Array(_62.length-1);
+for(var b=1;b<_62.length;b++){
+for(var c=0;c<4;c++){
+_6c[15-c]=((b-1)>>>c*8)&255;
+}
+for(var c=0;c<4;c++){
+_6c[15-c-4]=((b/4294967296-1)>>>c*8)&255;
+}
+var _72=_18(_6c,_6a);
+_62[b]=_6e(_62[b]);
+var pt="";
+for(var i=0;i<_62[b].length;i++){
+var _74=_62[b].charCodeAt(i);
+var _75=_74^_72[i];
+pt+=String.fromCharCode(_75);
+}
+_6f[b-1]=pt;
+}
+return _6f.join("");
+};
+function _5f(str){
+return str.replace(/[\0\t\n\v\f\r\xa0!-]/g,function(c){
+return "!"+c.charCodeAt(0)+"!";
+});
+};
+function _6e(str){
+return str.replace(/!\d\d?\d?!/g,function(c){
+return String.fromCharCode(c.slice(1,-1));
+});
+};
+function _7a(_7b,_7c){
+return _4a(_7b,_7c,256);
+};
+function _7d(_7e,_7f){
+return _61(_7e,_7f,256);
+};
+var cmd=msg.substr(0,4);
+var arg=msg.substr(5);
+if(cmd=="encr"){
+arg=eval("("+arg+")");
+var _82=arg.plaintext;
+var _83=arg.password;
+var _84=_7a(_82,_83);
+gearsWorkerPool.sendMessage(String(_84),_15);
+}else{
+if(cmd=="decr"){
+arg=eval("("+arg+")");
+var _85=arg.ciphertext;
+var _83=arg.password;
+var _84=_7d(_85,_83);
+gearsWorkerPool.sendMessage(String(_84),_15);
+}
+}
+}});
+}
diff --git a/dojox/storage.js b/dojox/storage.js
new file mode 100644
index 0000000..4ef6a01
--- /dev/null
+++ b/dojox/storage.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.storage"]){
+dojo._hasResource["dojox.storage"]=true;
+dojo.provide("dojox.storage");
+dojo.require("dojox.storage._common");
+}
diff --git a/dojox/storage/AirDBStorageProvider.js b/dojox/storage/AirDBStorageProvider.js
new file mode 100644
index 0000000..74dd522
--- /dev/null
+++ b/dojox/storage/AirDBStorageProvider.js
@@ -0,0 +1,180 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.storage.AirDBStorageProvider"]){
+dojo._hasResource["dojox.storage.AirDBStorageProvider"]=true;
+dojo.provide("dojox.storage.AirDBStorageProvider");
+dojo.require("dojox.storage.manager");
+dojo.require("dojox.storage.Provider");
+if(dojo.isAIR){
+(function(){
+if(!_1){
+var _1={};
+}
+_1.File=window.runtime.flash.filesystem.File;
+_1.SQLConnection=window.runtime.flash.data.SQLConnection;
+_1.SQLStatement=window.runtime.flash.data.SQLStatement;
+dojo.declare("dojox.storage.AirDBStorageProvider",[dojox.storage.Provider],{DATABASE_FILE:"dojo.db",TABLE_NAME:"__DOJO_STORAGE",initialized:false,_db:null,initialize:function(){
+this.initialized=false;
+try{
+this._db=new _1.SQLConnection();
+this._db.open(_1.File.applicationStorageDirectory.resolvePath(this.DATABASE_FILE));
+this._sql("CREATE TABLE IF NOT EXISTS "+this.TABLE_NAME+"(namespace TEXT, key TEXT, value TEXT)");
+this._sql("CREATE UNIQUE INDEX IF NOT EXISTS namespace_key_index ON "+this.TABLE_NAME+" (namespace, key)");
+this.initialized=true;
+}
+catch(e){
+
+}
+dojox.storage.manager.loaded();
+},_sql:function(_2,_3){
+var _4=new _1.SQLStatement();
+_4.sqlConnection=this._db;
+_4.text=_2;
+if(_3){
+for(var _5 in _3){
+_4.parameters[_5]=_3[_5];
+}
+}
+_4.execute();
+return _4.getResult();
+},_beginTransaction:function(){
+this._db.begin();
+},_commitTransaction:function(){
+this._db.commit();
+},isAvailable:function(){
+return true;
+},put:function(_6,_7,_8,_9){
+if(this.isValidKey(_6)==false){
+throw new Error("Invalid key given: "+_6);
+}
+_9=_9||this.DEFAULT_NAMESPACE;
+if(this.isValidKey(_9)==false){
+throw new Error("Invalid namespace given: "+_9);
+}
+try{
+this._sql("DELETE FROM "+this.TABLE_NAME+" WHERE namespace = :namespace AND key = :key",{":namespace":_9,":key":_6});
+this._sql("INSERT INTO "+this.TABLE_NAME+" VALUES (:namespace, :key, :value)",{":namespace":_9,":key":_6,":value":_7});
+}
+catch(e){
+
+_8(this.FAILED,_6,e.toString());
+return;
+}
+if(_8){
+_8(this.SUCCESS,_6,null,_9);
+}
+},get:function(_a,_b){
+if(this.isValidKey(_a)==false){
+throw new Error("Invalid key given: "+_a);
+}
+_b=_b||this.DEFAULT_NAMESPACE;
+var _c=this._sql("SELECT * FROM "+this.TABLE_NAME+" WHERE namespace = :namespace AND key = :key",{":namespace":_b,":key":_a});
+if(_c.data&&_c.data.length){
+return _c.data[0].value;
+}
+return null;
+},getNamespaces:function(){
+var _d=[this.DEFAULT_NAMESPACE];
+var rs=this._sql("SELECT namespace FROM "+this.TABLE_NAME+" DESC GROUP BY namespace");
+if(rs.data){
+for(var i=0;i<rs.data.length;i++){
+if(rs.data[i].namespace!=this.DEFAULT_NAMESPACE){
+_d.push(rs.data[i].namespace);
+}
+}
+}
+return _d;
+},getKeys:function(_10){
+_10=_10||this.DEFAULT_NAMESPACE;
+if(this.isValidKey(_10)==false){
+throw new Error("Invalid namespace given: "+_10);
+}
+var _11=[];
+var rs=this._sql("SELECT key FROM "+this.TABLE_NAME+" WHERE namespace = :namespace",{":namespace":_10});
+if(rs.data){
+for(var i=0;i<rs.data.length;i++){
+_11.push(rs.data[i].key);
+}
+}
+return _11;
+},clear:function(_14){
+if(this.isValidKey(_14)==false){
+throw new Error("Invalid namespace given: "+_14);
+}
+this._sql("DELETE FROM "+this.TABLE_NAME+" WHERE namespace = :namespace",{":namespace":_14});
+},remove:function(key,_16){
+_16=_16||this.DEFAULT_NAMESPACE;
+this._sql("DELETE FROM "+this.TABLE_NAME+" WHERE namespace = :namespace AND key = :key",{":namespace":_16,":key":key});
+},putMultiple:function(_17,_18,_19,_1a){
+if(this.isValidKeyArray(_17)===false||!_18 instanceof Array||_17.length!=_18.length){
+throw new Error("Invalid arguments: keys = ["+_17+"], values = ["+_18+"]");
+}
+if(_1a==null||typeof _1a=="undefined"){
+_1a=this.DEFAULT_NAMESPACE;
+}
+if(this.isValidKey(_1a)==false){
+throw new Error("Invalid namespace given: "+_1a);
+}
+this._statusHandler=_19;
+try{
+this._beginTransaction();
+for(var i=0;i<_17.length;i++){
+this._sql("DELETE FROM "+this.TABLE_NAME+" WHERE namespace = :namespace AND key = :key",{":namespace":_1a,":key":_17[i]});
+this._sql("INSERT INTO "+this.TABLE_NAME+" VALUES (:namespace, :key, :value)",{":namespace":_1a,":key":_17[i],":value":_18[i]});
+}
+this._commitTransaction();
+}
+catch(e){
+
+if(_19){
+_19(this.FAILED,_17,e.toString(),_1a);
+}
+return;
+}
+if(_19){
+_19(this.SUCCESS,_17,null);
+}
+},getMultiple:function(_1c,_1d){
+if(this.isValidKeyArray(_1c)===false){
+throw new Error("Invalid key array given: "+_1c);
+}
+if(_1d==null||typeof _1d=="undefined"){
+_1d=this.DEFAULT_NAMESPACE;
+}
+if(this.isValidKey(_1d)==false){
+throw new Error("Invalid namespace given: "+_1d);
+}
+var _1e=[];
+for(var i=0;i<_1c.length;i++){
+var _20=this._sql("SELECT * FROM "+this.TABLE_NAME+" WHERE namespace = :namespace AND key = :key",{":namespace":_1d,":key":_1c[i]});
+_1e[i]=_20.data&&_20.data.length?_20.data[0].value:null;
+}
+return _1e;
+},removeMultiple:function(_21,_22){
+_22=_22||this.DEFAULT_NAMESPACE;
+this._beginTransaction();
+for(var i=0;i<_21.length;i++){
+this._sql("DELETE FROM "+this.TABLE_NAME+" WHERE namespace = namespace = :namespace AND key = :key",{":namespace":_22,":key":_21[i]});
+}
+this._commitTransaction();
+},isPermanent:function(){
+return true;
+},getMaximumSize:function(){
+return this.SIZE_NO_LIMIT;
+},hasSettingsUI:function(){
+return false;
+},showSettingsUI:function(){
+throw new Error(this.declaredClass+" does not support a storage settings user-interface");
+},hideSettingsUI:function(){
+throw new Error(this.declaredClass+" does not support a storage settings user-interface");
+}});
+dojox.storage.manager.register("dojox.storage.AirDBStorageProvider",new dojox.storage.AirDBStorageProvider());
+dojox.storage.manager.initialize();
+})();
+}
+}
diff --git a/dojox/storage/AirEncryptedLocalStorageProvider.js b/dojox/storage/AirEncryptedLocalStorageProvider.js
new file mode 100644
index 0000000..a08b709
--- /dev/null
+++ b/dojox/storage/AirEncryptedLocalStorageProvider.js
@@ -0,0 +1,170 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.storage.AirEncryptedLocalStorageProvider"]){
+dojo._hasResource["dojox.storage.AirEncryptedLocalStorageProvider"]=true;
+dojo.provide("dojox.storage.AirEncryptedLocalStorageProvider");
+dojo.require("dojox.storage.manager");
+dojo.require("dojox.storage.Provider");
+if(dojo.isAIR){
+(function(){
+if(!_1){
+var _1={};
+}
+_1.ByteArray=window.runtime.flash.utils.ByteArray;
+_1.EncryptedLocalStore=window.runtime.flash.data.EncryptedLocalStore,dojo.declare("dojox.storage.AirEncryptedLocalStorageProvider",[dojox.storage.Provider],{initialize:function(){
+dojox.storage.manager.loaded();
+},isAvailable:function(){
+return true;
+},_getItem:function(_2){
+var _3=_1.EncryptedLocalStore.getItem("__dojo_"+_2);
+return _3?_3.readUTFBytes(_3.length):"";
+},_setItem:function(_4,_5){
+var _6=new _1.ByteArray();
+_6.writeUTFBytes(_5);
+_1.EncryptedLocalStore.setItem("__dojo_"+_4,_6);
+},_removeItem:function(_7){
+_1.EncryptedLocalStore.removeItem("__dojo_"+_7);
+},put:function(_8,_9,_a,_b){
+if(this.isValidKey(_8)==false){
+throw new Error("Invalid key given: "+_8);
+}
+_b=_b||this.DEFAULT_NAMESPACE;
+if(this.isValidKey(_b)==false){
+throw new Error("Invalid namespace given: "+_b);
+}
+try{
+var _c=this._getItem("namespaces")||"|";
+if(_c.indexOf("|"+_b+"|")==-1){
+this._setItem("namespaces",_c+_b+"|");
+}
+var _d=this._getItem(_b+"_keys")||"|";
+if(_d.indexOf("|"+_8+"|")==-1){
+this._setItem(_b+"_keys",_d+_8+"|");
+}
+this._setItem("_"+_b+"_"+_8,_9);
+}
+catch(e){
+
+_a(this.FAILED,_8,e.toString(),_b);
+return;
+}
+if(_a){
+_a(this.SUCCESS,_8,null,_b);
+}
+},get:function(_e,_f){
+if(this.isValidKey(_e)==false){
+throw new Error("Invalid key given: "+_e);
+}
+_f=_f||this.DEFAULT_NAMESPACE;
+return this._getItem("_"+_f+"_"+_e);
+},getNamespaces:function(){
+var _10=[this.DEFAULT_NAMESPACE];
+var _11=(this._getItem("namespaces")||"|").split("|");
+for(var i=0;i<_11.length;i++){
+if(_11[i].length&&_11[i]!=this.DEFAULT_NAMESPACE){
+_10.push(_11[i]);
+}
+}
+return _10;
+},getKeys:function(_13){
+_13=_13||this.DEFAULT_NAMESPACE;
+if(this.isValidKey(_13)==false){
+throw new Error("Invalid namespace given: "+_13);
+}
+var _14=[];
+var _15=(this._getItem(_13+"_keys")||"|").split("|");
+for(var i=0;i<_15.length;i++){
+if(_15[i].length){
+_14.push(_15[i]);
+}
+}
+return _14;
+},clear:function(_17){
+if(this.isValidKey(_17)==false){
+throw new Error("Invalid namespace given: "+_17);
+}
+var _18=this._getItem("namespaces")||"|";
+if(_18.indexOf("|"+_17+"|")!=-1){
+this._setItem("namespaces",_18.replace("|"+_17+"|","|"));
+}
+var _19=(this._getItem(_17+"_keys")||"|").split("|");
+for(var i=0;i<_19.length;i++){
+if(_19[i].length){
+this._removeItem(_17+"_"+_19[i]);
+}
+}
+this._removeItem(_17+"_keys");
+},remove:function(key,_1c){
+_1c=_1c||this.DEFAULT_NAMESPACE;
+var _1d=this._getItem(_1c+"_keys")||"|";
+if(_1d.indexOf("|"+key+"|")!=-1){
+this._setItem(_1c+"_keys",_1d.replace("|"+key+"|","|"));
+}
+this._removeItem("_"+_1c+"_"+key);
+},putMultiple:function(_1e,_1f,_20,_21){
+if(this.isValidKeyArray(_1e)===false||!_1f instanceof Array||_1e.length!=_1f.length){
+throw new Error("Invalid arguments: keys = ["+_1e+"], values = ["+_1f+"]");
+}
+if(_21==null||typeof _21=="undefined"){
+_21=this.DEFAULT_NAMESPACE;
+}
+if(this.isValidKey(_21)==false){
+throw new Error("Invalid namespace given: "+_21);
+}
+this._statusHandler=_20;
+try{
+for(var i=0;i<_1e.length;i++){
+this.put(_1e[i],_1f[i],null,_21);
+}
+}
+catch(e){
+
+if(_20){
+_20(this.FAILED,_1e,e.toString(),_21);
+}
+return;
+}
+if(_20){
+_20(this.SUCCESS,_1e,null);
+}
+},getMultiple:function(_23,_24){
+if(this.isValidKeyArray(_23)===false){
+throw new Error("Invalid key array given: "+_23);
+}
+if(_24==null||typeof _24=="undefined"){
+_24=this.DEFAULT_NAMESPACE;
+}
+if(this.isValidKey(_24)==false){
+throw new Error("Invalid namespace given: "+_24);
+}
+var _25=[];
+for(var i=0;i<_23.length;i++){
+_25[i]=this.get(_23[i],_24);
+}
+return _25;
+},removeMultiple:function(_27,_28){
+_28=_28||this.DEFAULT_NAMESPACE;
+for(var i=0;i<_27.length;i++){
+this.remove(_27[i],_28);
+}
+},isPermanent:function(){
+return true;
+},getMaximumSize:function(){
+return this.SIZE_NO_LIMIT;
+},hasSettingsUI:function(){
+return false;
+},showSettingsUI:function(){
+throw new Error(this.declaredClass+" does not support a storage settings user-interface");
+},hideSettingsUI:function(){
+throw new Error(this.declaredClass+" does not support a storage settings user-interface");
+}});
+dojox.storage.manager.register("dojox.storage.AirEncryptedLocalStorageProvider",new dojox.storage.AirEncryptedLocalStorageProvider());
+dojox.storage.manager.initialize();
+})();
+}
+}
diff --git a/dojox/storage/AirFileStorageProvider.js b/dojox/storage/AirFileStorageProvider.js
new file mode 100644
index 0000000..6147dc8
--- /dev/null
+++ b/dojox/storage/AirFileStorageProvider.js
@@ -0,0 +1,177 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.storage.AirFileStorageProvider"]){
+dojo._hasResource["dojox.storage.AirFileStorageProvider"]=true;
+dojo.provide("dojox.storage.AirFileStorageProvider");
+dojo.require("dojox.storage.manager");
+dojo.require("dojox.storage.Provider");
+if(dojo.isAIR){
+(function(){
+if(!_1){
+var _1={};
+}
+_1.File=window.runtime.flash.filesystem.File;
+_1.FileStream=window.runtime.flash.filesystem.FileStream;
+_1.FileMode=window.runtime.flash.filesystem.FileMode;
+dojo.declare("dojox.storage.AirFileStorageProvider",[dojox.storage.Provider],{initialized:false,_storagePath:"__DOJO_STORAGE/",initialize:function(){
+this.initialized=false;
+try{
+var _2=_1.File.applicationStorageDirectory.resolvePath(this._storagePath);
+if(!_2.exists){
+_2.createDirectory();
+}
+this.initialized=true;
+}
+catch(e){
+
+}
+dojox.storage.manager.loaded();
+},isAvailable:function(){
+return true;
+},put:function(_3,_4,_5,_6){
+if(this.isValidKey(_3)==false){
+throw new Error("Invalid key given: "+_3);
+}
+_6=_6||this.DEFAULT_NAMESPACE;
+if(this.isValidKey(_6)==false){
+throw new Error("Invalid namespace given: "+_6);
+}
+try{
+this.remove(_3,_6);
+var _7=_1.File.applicationStorageDirectory.resolvePath(this._storagePath+_6);
+if(!_7.exists){
+_7.createDirectory();
+}
+var _8=_7.resolvePath(_3);
+var _9=new _1.FileStream();
+_9.open(_8,_1.FileMode.WRITE);
+_9.writeObject(_4);
+_9.close();
+}
+catch(e){
+
+_5(this.FAILED,_3,e.toString(),_6);
+return;
+}
+if(_5){
+_5(this.SUCCESS,_3,null,_6);
+}
+},get:function(_a,_b){
+if(this.isValidKey(_a)==false){
+throw new Error("Invalid key given: "+_a);
+}
+_b=_b||this.DEFAULT_NAMESPACE;
+var _c=null;
+var _d=_1.File.applicationStorageDirectory.resolvePath(this._storagePath+_b+"/"+_a);
+if(_d.exists&&!_d.isDirectory){
+var _e=new _1.FileStream();
+_e.open(_d,_1.FileMode.READ);
+_c=_e.readObject();
+_e.close();
+}
+return _c;
+},getNamespaces:function(){
+var _f=[this.DEFAULT_NAMESPACE];
+var dir=_1.File.applicationStorageDirectory.resolvePath(this._storagePath);
+var _11=dir.getDirectoryListing(),i;
+for(i=0;i<_11.length;i++){
+if(_11[i].isDirectory&&_11[i].name!=this.DEFAULT_NAMESPACE){
+_f.push(_11[i].name);
+}
+}
+return _f;
+},getKeys:function(_13){
+_13=_13||this.DEFAULT_NAMESPACE;
+if(this.isValidKey(_13)==false){
+throw new Error("Invalid namespace given: "+_13);
+}
+var _14=[];
+var dir=_1.File.applicationStorageDirectory.resolvePath(this._storagePath+_13);
+if(dir.exists&&dir.isDirectory){
+var _16=dir.getDirectoryListing(),i;
+for(i=0;i<_16.length;i++){
+_14.push(_16[i].name);
+}
+}
+return _14;
+},clear:function(_18){
+if(this.isValidKey(_18)==false){
+throw new Error("Invalid namespace given: "+_18);
+}
+var dir=_1.File.applicationStorageDirectory.resolvePath(this._storagePath+_18);
+if(dir.exists&&dir.isDirectory){
+dir.deleteDirectory(true);
+}
+},remove:function(key,_1b){
+_1b=_1b||this.DEFAULT_NAMESPACE;
+var _1c=_1.File.applicationStorageDirectory.resolvePath(this._storagePath+_1b+"/"+key);
+if(_1c.exists&&!_1c.isDirectory){
+_1c.deleteFile();
+}
+},putMultiple:function(_1d,_1e,_1f,_20){
+if(this.isValidKeyArray(_1d)===false||!_1e instanceof Array||_1d.length!=_1e.length){
+throw new Error("Invalid arguments: keys = ["+_1d+"], values = ["+_1e+"]");
+}
+if(_20==null||typeof _20=="undefined"){
+_20=this.DEFAULT_NAMESPACE;
+}
+if(this.isValidKey(_20)==false){
+throw new Error("Invalid namespace given: "+_20);
+}
+this._statusHandler=_1f;
+try{
+for(var i=0;i<_1d.length;i++){
+this.put(_1d[i],_1e[i],null,_20);
+}
+}
+catch(e){
+
+if(_1f){
+_1f(this.FAILED,_1d,e.toString(),_20);
+}
+return;
+}
+if(_1f){
+_1f(this.SUCCESS,_1d,null,_20);
+}
+},getMultiple:function(_22,_23){
+if(this.isValidKeyArray(_22)===false){
+throw new Error("Invalid key array given: "+_22);
+}
+if(_23==null||typeof _23=="undefined"){
+_23=this.DEFAULT_NAMESPACE;
+}
+if(this.isValidKey(_23)==false){
+throw new Error("Invalid namespace given: "+_23);
+}
+var _24=[];
+for(var i=0;i<_22.length;i++){
+_24[i]=this.get(_22[i],_23);
+}
+return _24;
+},removeMultiple:function(_26,_27){
+_27=_27||this.DEFAULT_NAMESPACE;
+for(var i=0;i<_26.length;i++){
+this.remove(_26[i],_27);
+}
+},isPermanent:function(){
+return true;
+},getMaximumSize:function(){
+return this.SIZE_NO_LIMIT;
+},hasSettingsUI:function(){
+return false;
+},showSettingsUI:function(){
+throw new Error(this.declaredClass+" does not support a storage settings user-interface");
+},hideSettingsUI:function(){
+throw new Error(this.declaredClass+" does not support a storage settings user-interface");
+}});
+dojox.storage.manager.register("dojox.storage.AirFileStorageProvider",new dojox.storage.AirFileStorageProvider());
+dojox.storage.manager.initialize();
+})();
+}
+}
diff --git a/dojox/storage/FlashStorageProvider.js b/dojox/storage/FlashStorageProvider.js
new file mode 100644
index 0000000..359b0d1
--- /dev/null
+++ b/dojox/storage/FlashStorageProvider.js
@@ -0,0 +1,211 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.storage.FlashStorageProvider"]){
+dojo._hasResource["dojox.storage.FlashStorageProvider"]=true;
+dojo.provide("dojox.storage.FlashStorageProvider");
+dojo.require("dojox.flash");
+dojo.require("dojox.storage.manager");
+dojo.require("dojox.storage.Provider");
+dojo.declare("dojox.storage.FlashStorageProvider",dojox.storage.Provider,{initialized:false,_available:null,_statusHandler:null,_flashReady:false,_pageReady:false,initialize:function(){
+if(dojo.config["disableFlashStorage"]==true){
+return;
+}
+dojox.flash.addLoadedListener(dojo.hitch(this,function(){
+this._flashReady=true;
+if(this._flashReady&&this._pageReady){
+this._loaded();
+}
+}));
+var _1=dojo.moduleUrl("dojox","storage/Storage.swf").toString();
+dojox.flash.setSwf(_1,false);
+dojo.connect(dojo,"loaded",this,function(){
+this._pageReady=true;
+if(this._flashReady&&this._pageReady){
+this._loaded();
+}
+});
+},setFlushDelay:function(_2){
+if(_2===null||typeof _2==="undefined"||isNaN(_2)){
+throw new Error("Invalid argunment: "+_2);
+}
+dojox.flash.comm.setFlushDelay(String(_2));
+},getFlushDelay:function(){
+return Number(dojox.flash.comm.getFlushDelay());
+},flush:function(_3){
+if(_3==null||typeof _3=="undefined"){
+_3=dojox.storage.DEFAULT_NAMESPACE;
+}
+dojox.flash.comm.flush(_3);
+},isAvailable:function(){
+return (this._available=!dojo.config["disableFlashStorage"]);
+},put:function(_4,_5,_6,_7){
+if(!this.isValidKey(_4)){
+throw new Error("Invalid key given: "+_4);
+}
+if(!_7){
+_7=dojox.storage.DEFAULT_NAMESPACE;
+}
+if(!this.isValidKey(_7)){
+throw new Error("Invalid namespace given: "+_7);
+}
+this._statusHandler=_6;
+if(dojo.isString(_5)){
+_5="string:"+_5;
+}else{
+_5=dojo.toJson(_5);
+}
+dojox.flash.comm.put(_4,_5,_7);
+},putMultiple:function(_8,_9,_a,_b){
+if(!this.isValidKeyArray(_8)||!_9 instanceof Array||_8.length!=_9.length){
+throw new Error("Invalid arguments: keys = ["+_8+"], values = ["+_9+"]");
+}
+if(!_b){
+_b=dojox.storage.DEFAULT_NAMESPACE;
+}
+if(!this.isValidKey(_b)){
+throw new Error("Invalid namespace given: "+_b);
+}
+this._statusHandler=_a;
+var _c=_8.join(",");
+var _d=[];
+for(var i=0;i<_9.length;i++){
+if(dojo.isString(_9[i])){
+_9[i]="string:"+_9[i];
+}else{
+_9[i]=dojo.toJson(_9[i]);
+}
+_d[i]=_9[i].length;
+}
+var _f=_9.join("");
+var _10=_d.join(",");
+dojox.flash.comm.putMultiple(_c,_f,_10,_b);
+},get:function(key,_12){
+if(!this.isValidKey(key)){
+throw new Error("Invalid key given: "+key);
+}
+if(!_12){
+_12=dojox.storage.DEFAULT_NAMESPACE;
+}
+if(!this.isValidKey(_12)){
+throw new Error("Invalid namespace given: "+_12);
+}
+var _13=dojox.flash.comm.get(key,_12);
+if(_13==""){
+return null;
+}
+return this._destringify(_13);
+},getMultiple:function(_14,_15){
+if(!this.isValidKeyArray(_14)){
+throw new ("Invalid key array given: "+_14);
+}
+if(!_15){
+_15=dojox.storage.DEFAULT_NAMESPACE;
+}
+if(!this.isValidKey(_15)){
+throw new Error("Invalid namespace given: "+_15);
+}
+var _16=_14.join(",");
+var _17=dojox.flash.comm.getMultiple(_16,_15);
+var _18=eval("("+_17+")");
+for(var i=0;i<_18.length;i++){
+_18[i]=(_18[i]=="")?null:this._destringify(_18[i]);
+}
+return _18;
+},_destringify:function(_1a){
+if(dojo.isString(_1a)&&(/^string:/.test(_1a))){
+_1a=_1a.substring("string:".length);
+}else{
+_1a=dojo.fromJson(_1a);
+}
+return _1a;
+},getKeys:function(_1b){
+if(!_1b){
+_1b=dojox.storage.DEFAULT_NAMESPACE;
+}
+if(!this.isValidKey(_1b)){
+throw new Error("Invalid namespace given: "+_1b);
+}
+var _1c=dojox.flash.comm.getKeys(_1b);
+if(_1c==null||_1c=="null"){
+_1c="";
+}
+_1c=_1c.split(",");
+_1c.sort();
+return _1c;
+},getNamespaces:function(){
+var _1d=dojox.flash.comm.getNamespaces();
+if(_1d==null||_1d=="null"){
+_1d=dojox.storage.DEFAULT_NAMESPACE;
+}
+_1d=_1d.split(",");
+_1d.sort();
+return _1d;
+},clear:function(_1e){
+if(!_1e){
+_1e=dojox.storage.DEFAULT_NAMESPACE;
+}
+if(!this.isValidKey(_1e)){
+throw new Error("Invalid namespace given: "+_1e);
+}
+dojox.flash.comm.clear(_1e);
+},remove:function(key,_20){
+if(!_20){
+_20=dojox.storage.DEFAULT_NAMESPACE;
+}
+if(!this.isValidKey(_20)){
+throw new Error("Invalid namespace given: "+_20);
+}
+dojox.flash.comm.remove(key,_20);
+},removeMultiple:function(_21,_22){
+if(!this.isValidKeyArray(_21)){
+dojo.raise("Invalid key array given: "+_21);
+}
+if(!_22){
+_22=dojox.storage.DEFAULT_NAMESPACE;
+}
+if(!this.isValidKey(_22)){
+throw new Error("Invalid namespace given: "+_22);
+}
+var _23=_21.join(",");
+dojox.flash.comm.removeMultiple(_23,_22);
+},isPermanent:function(){
+return true;
+},getMaximumSize:function(){
+return dojox.storage.SIZE_NO_LIMIT;
+},hasSettingsUI:function(){
+return true;
+},showSettingsUI:function(){
+dojox.flash.comm.showSettings();
+dojox.flash.obj.setVisible(true);
+dojox.flash.obj.center();
+},hideSettingsUI:function(){
+dojox.flash.obj.setVisible(false);
+if(dojo.isFunction(dojox.storage.onHideSettingsUI)){
+dojox.storage.onHideSettingsUI.call(null);
+}
+},getResourceList:function(){
+return [];
+},_loaded:function(){
+this._allNamespaces=this.getNamespaces();
+this.initialized=true;
+dojox.storage.manager.loaded();
+},_onStatus:function(_24,key,_26){
+var ds=dojox.storage;
+var dfo=dojox.flash.obj;
+if(_24==ds.PENDING){
+dfo.center();
+dfo.setVisible(true);
+}else{
+dfo.setVisible(false);
+}
+if(ds._statusHandler){
+ds._statusHandler.call(null,_24,key,null,_26);
+}
+}});
+dojox.storage.manager.register("dojox.storage.FlashStorageProvider",new dojox.storage.FlashStorageProvider());
+}
diff --git a/dojox/storage/GearsStorageProvider.js b/dojox/storage/GearsStorageProvider.js
new file mode 100644
index 0000000..eb88423
--- /dev/null
+++ b/dojox/storage/GearsStorageProvider.js
@@ -0,0 +1,233 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.storage.GearsStorageProvider"]){
+dojo._hasResource["dojox.storage.GearsStorageProvider"]=true;
+dojo.provide("dojox.storage.GearsStorageProvider");
+dojo.require("dojo.gears");
+dojo.require("dojox.storage.Provider");
+dojo.require("dojox.storage.manager");
+dojo.require("dojox.sql");
+if(dojo.gears.available){
+(function(){
+dojo.declare("dojox.storage.GearsStorageProvider",dojox.storage.Provider,{constructor:function(){
+},TABLE_NAME:"__DOJO_STORAGE",initialized:false,_available:null,_storageReady:false,initialize:function(){
+if(dojo.config["disableGearsStorage"]==true){
+return;
+}
+this.TABLE_NAME="__DOJO_STORAGE";
+this.initialized=true;
+dojox.storage.manager.loaded();
+},isAvailable:function(){
+return this._available=dojo.gears.available;
+},put:function(_1,_2,_3,_4){
+this._initStorage();
+if(!this.isValidKey(_1)){
+throw new Error("Invalid key given: "+_1);
+}
+_4=_4||this.DEFAULT_NAMESPACE;
+if(!this.isValidKey(_4)){
+throw new Error("Invalid namespace given: "+_1);
+}
+if(dojo.isString(_2)){
+_2="string:"+_2;
+}else{
+_2=dojo.toJson(_2);
+}
+try{
+dojox.sql("DELETE FROM "+this.TABLE_NAME+" WHERE namespace = ? AND key = ?",_4,_1);
+dojox.sql("INSERT INTO "+this.TABLE_NAME+" VALUES (?, ?, ?)",_4,_1,_2);
+}
+catch(e){
+
+_3(this.FAILED,_1,e.toString(),_4);
+return;
+}
+if(_3){
+_3(dojox.storage.SUCCESS,_1,null,_4);
+}
+},get:function(_5,_6){
+this._initStorage();
+if(!this.isValidKey(_5)){
+throw new Error("Invalid key given: "+_5);
+}
+_6=_6||this.DEFAULT_NAMESPACE;
+if(!this.isValidKey(_6)){
+throw new Error("Invalid namespace given: "+_5);
+}
+var _7=dojox.sql("SELECT * FROM "+this.TABLE_NAME+" WHERE namespace = ? AND "+" key = ?",_6,_5);
+if(!_7.length){
+return null;
+}else{
+_7=_7[0].value;
+}
+if(dojo.isString(_7)&&(/^string:/.test(_7))){
+_7=_7.substring("string:".length);
+}else{
+_7=dojo.fromJson(_7);
+}
+return _7;
+},getNamespaces:function(){
+this._initStorage();
+var _8=[dojox.storage.DEFAULT_NAMESPACE];
+var rs=dojox.sql("SELECT namespace FROM "+this.TABLE_NAME+" DESC GROUP BY namespace");
+for(var i=0;i<rs.length;i++){
+if(rs[i].namespace!=dojox.storage.DEFAULT_NAMESPACE){
+_8.push(rs[i].namespace);
+}
+}
+return _8;
+},getKeys:function(_b){
+this._initStorage();
+_b=_b||this.DEFAULT_NAMESPACE;
+if(!this.isValidKey(_b)){
+throw new Error("Invalid namespace given: "+_b);
+}
+var rs=dojox.sql("SELECT key FROM "+this.TABLE_NAME+" WHERE namespace = ?",_b);
+var _d=[];
+for(var i=0;i<rs.length;i++){
+_d.push(rs[i].key);
+}
+return _d;
+},clear:function(_f){
+this._initStorage();
+_f=_f||this.DEFAULT_NAMESPACE;
+if(!this.isValidKey(_f)){
+throw new Error("Invalid namespace given: "+_f);
+}
+dojox.sql("DELETE FROM "+this.TABLE_NAME+" WHERE namespace = ?",_f);
+},remove:function(key,_11){
+this._initStorage();
+if(!this.isValidKey(key)){
+throw new Error("Invalid key given: "+key);
+}
+_11=_11||this.DEFAULT_NAMESPACE;
+if(!this.isValidKey(_11)){
+throw new Error("Invalid namespace given: "+key);
+}
+dojox.sql("DELETE FROM "+this.TABLE_NAME+" WHERE namespace = ? AND"+" key = ?",_11,key);
+},putMultiple:function(_12,_13,_14,_15){
+this._initStorage();
+if(!this.isValidKeyArray(_12)||!_13 instanceof Array||_12.length!=_13.length){
+throw new Error("Invalid arguments: keys = ["+_12+"], values = ["+_13+"]");
+}
+if(_15==null||typeof _15=="undefined"){
+_15=dojox.storage.DEFAULT_NAMESPACE;
+}
+if(!this.isValidKey(_15)){
+throw new Error("Invalid namespace given: "+_15);
+}
+this._statusHandler=_14;
+try{
+dojox.sql.open();
+dojox.sql.db.execute("BEGIN TRANSACTION");
+var _16="REPLACE INTO "+this.TABLE_NAME+" VALUES (?, ?, ?)";
+for(var i=0;i<_12.length;i++){
+var _18=_13[i];
+if(dojo.isString(_18)){
+_18="string:"+_18;
+}else{
+_18=dojo.toJson(_18);
+}
+dojox.sql.db.execute(_16,[_15,_12[i],_18]);
+}
+dojox.sql.db.execute("COMMIT TRANSACTION");
+dojox.sql.close();
+}
+catch(e){
+
+if(_14){
+_14(this.FAILED,_12,e.toString(),_15);
+}
+return;
+}
+if(_14){
+_14(dojox.storage.SUCCESS,_12,null,_15);
+}
+},getMultiple:function(_19,_1a){
+this._initStorage();
+if(!this.isValidKeyArray(_19)){
+throw new ("Invalid key array given: "+_19);
+}
+if(_1a==null||typeof _1a=="undefined"){
+_1a=dojox.storage.DEFAULT_NAMESPACE;
+}
+if(!this.isValidKey(_1a)){
+throw new Error("Invalid namespace given: "+_1a);
+}
+var _1b="SELECT * FROM "+this.TABLE_NAME+" WHERE namespace = ? AND "+" key = ?";
+var _1c=[];
+for(var i=0;i<_19.length;i++){
+var _1e=dojox.sql(_1b,_1a,_19[i]);
+if(!_1e.length){
+_1c[i]=null;
+}else{
+_1e=_1e[0].value;
+if(dojo.isString(_1e)&&(/^string:/.test(_1e))){
+_1c[i]=_1e.substring("string:".length);
+}else{
+_1c[i]=dojo.fromJson(_1e);
+}
+}
+}
+return _1c;
+},removeMultiple:function(_1f,_20){
+this._initStorage();
+if(!this.isValidKeyArray(_1f)){
+throw new Error("Invalid arguments: keys = ["+_1f+"]");
+}
+if(_20==null||typeof _20=="undefined"){
+_20=dojox.storage.DEFAULT_NAMESPACE;
+}
+if(!this.isValidKey(_20)){
+throw new Error("Invalid namespace given: "+_20);
+}
+dojox.sql.open();
+dojox.sql.db.execute("BEGIN TRANSACTION");
+var _21="DELETE FROM "+this.TABLE_NAME+" WHERE namespace = ? AND key = ?";
+for(var i=0;i<_1f.length;i++){
+dojox.sql.db.execute(_21,[_20,_1f[i]]);
+}
+dojox.sql.db.execute("COMMIT TRANSACTION");
+dojox.sql.close();
+},isPermanent:function(){
+return true;
+},getMaximumSize:function(){
+return this.SIZE_NO_LIMIT;
+},hasSettingsUI:function(){
+return false;
+},showSettingsUI:function(){
+throw new Error(this.declaredClass+" does not support a storage settings user-interface");
+},hideSettingsUI:function(){
+throw new Error(this.declaredClass+" does not support a storage settings user-interface");
+},_initStorage:function(){
+if(this._storageReady){
+return;
+}
+if(!google.gears.factory.hasPermission){
+var _23=null;
+var _24=null;
+var msg="This site would like to use Google Gears to enable "+"enhanced functionality.";
+var _26=google.gears.factory.getPermission(_23,_24,msg);
+if(!_26){
+throw new Error("You must give permission to use Gears in order to "+"store data");
+}
+}
+try{
+dojox.sql("CREATE TABLE IF NOT EXISTS "+this.TABLE_NAME+"( "+" namespace TEXT, "+" key TEXT, "+" value TEXT "+")");
+dojox.sql("CREATE UNIQUE INDEX IF NOT EXISTS namespace_key_index"+" ON "+this.TABLE_NAME+" (namespace, key)");
+}
+catch(e){
+
+throw new Error("Unable to create storage tables for Gears in "+"Dojo Storage");
+}
+this._storageReady=true;
+}});
+dojox.storage.manager.register("dojox.storage.GearsStorageProvider",new dojox.storage.GearsStorageProvider());
+})();
+}
+}
diff --git a/dojox/storage/Provider.js b/dojox/storage/Provider.js
new file mode 100644
index 0000000..4275672
--- /dev/null
+++ b/dojox/storage/Provider.js
@@ -0,0 +1,69 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.storage.Provider"]){
+dojo._hasResource["dojox.storage.Provider"]=true;
+dojo.provide("dojox.storage.Provider");
+dojo.declare("dojox.storage.Provider",null,{constructor:function(){
+},SUCCESS:"success",FAILED:"failed",PENDING:"pending",SIZE_NOT_AVAILABLE:"Size not available",SIZE_NO_LIMIT:"No size limit",DEFAULT_NAMESPACE:"default",onHideSettingsUI:null,initialize:function(){
+console.warn("dojox.storage.initialize not implemented");
+},isAvailable:function(){
+console.warn("dojox.storage.isAvailable not implemented");
+},put:function(_1,_2,_3,_4){
+console.warn("dojox.storage.put not implemented");
+},get:function(_5,_6){
+console.warn("dojox.storage.get not implemented");
+},hasKey:function(_7,_8){
+return !!this.get(_7,_8);
+},getKeys:function(_9){
+console.warn("dojox.storage.getKeys not implemented");
+},clear:function(_a){
+console.warn("dojox.storage.clear not implemented");
+},remove:function(_b,_c){
+console.warn("dojox.storage.remove not implemented");
+},getNamespaces:function(){
+console.warn("dojox.storage.getNamespaces not implemented");
+},isPermanent:function(){
+console.warn("dojox.storage.isPermanent not implemented");
+},getMaximumSize:function(){
+console.warn("dojox.storage.getMaximumSize not implemented");
+},putMultiple:function(_d,_e,_f,_10){
+for(var i=0;i<_d.length;i++){
+dojox.storage.put(_d[i],_e[i],_f,_10);
+}
+},getMultiple:function(_12,_13){
+var _14=[];
+for(var i=0;i<_12.length;i++){
+_14.push(dojox.storage.get(_12[i],_13));
+}
+return _14;
+},removeMultiple:function(_16,_17){
+for(var i=0;i<_16.length;i++){
+dojox.storage.remove(_16[i],_17);
+}
+},isValidKeyArray:function(_19){
+if(_19===null||_19===undefined||!dojo.isArray(_19)){
+return false;
+}
+return !dojo.some(_19,function(key){
+return !this.isValidKey(key);
+},this);
+},hasSettingsUI:function(){
+return false;
+},showSettingsUI:function(){
+console.warn("dojox.storage.showSettingsUI not implemented");
+},hideSettingsUI:function(){
+console.warn("dojox.storage.hideSettingsUI not implemented");
+},isValidKey:function(_1b){
+if(_1b===null||_1b===undefined){
+return false;
+}
+return /^[0-9A-Za-z_]*$/.test(_1b);
+},getResourceList:function(){
+return [];
+}});
+}
diff --git a/dojox/storage/README b/dojox/storage/README
new file mode 100644
index 0000000..28cd2a9
--- /dev/null
+++ b/dojox/storage/README
@@ -0,0 +1,76 @@
+-------------------------------------------------------------------------------
+Dojo Storage
+-------------------------------------------------------------------------------
+Version X.XXX (does not have separate versioning -- versioned by release date)
+Last Release date: March 2008
+-------------------------------------------------------------------------------
+Project state:
+experimental
+-------------------------------------------------------------------------------
+Credits
+	Brad Neuberg
+	Alex Russell
+-------------------------------------------------------------------------------
+Project description
+
+dojox.storage provides a JavaScript abstraction for persistent storage
+as well as pluggable implementations which typically use native browser extensions
+(e.g. Flash player, Gears)
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+FlashStorageProvider requires the Flash player
+GearsStorageProvider requires the Gears extension
+The various Air*StorageProviders require Adobe's AIR software
+
+The open source mtasc compiler (www.mtasc.org) is needed to build the
+ActionScript into SWF format.  The SWF object is maintained within svn, so
+this step is only necessary if Storage.as is modified.  A sample build script
+is provided (buildFlashStorage.sh)
+
+-------------------------------------------------------------------------------
+Documentation
+
+See http://manual.dojotoolkit.org/WikiHome/DojoDotBook/Book50 for the
+authoritative Dojo Storage docs.
+
+See dojox/storage/demos/helloworld.html for a simple Hello World example
+you can base your code off of.
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+If you want to use Dojo Storage in a web browser:
+
+These installation instructions are to use Dojo Storage in a web browser; at
+runtime, Dojo Storage will autodetect and use the best available storage
+option. This includes:
+
+  * Google Gears
+  * HTML 5 Web Browsers (Firefox 2+)
+  * Hidden Flash
+  
+If you are using a release build (if you downloaded Dojo from the Dojo
+website then this is a release build -- if you checked it out from
+Subversion yourself then you will have to build things yourself), if you 
+only want to grab just the files from Dojo to use Dojo Storage
+in the browser, take the following (but make sure to keep the directory
+layout the same, or else things won't work correctly!):
+
+* dojo/dojo.js
+* dojox/storage/storage-browser.js
+* dojox/storage/Storage.swf
+
+To help with testing and development and to make sure you have everything 
+right, its also useful to grab the following files:
+
+* dojox/storage/README
+* dojox/storage/demos/helloworld.html
+
+If you want to use Dojo Storage with Adobe AIR:
+
+[TBD! Why don't you write this and contribute!]
+
+-------------------------------------------------------------------------------
+Additional Notes
diff --git a/dojox/storage/Storage.as b/dojox/storage/Storage.as
new file mode 100644
index 0000000..89ec67d
--- /dev/null
+++ b/dojox/storage/Storage.as
@@ -0,0 +1,402 @@
+import DojoExternalInterface;
+
+class Storage{
+	public static var SUCCESS = "success";
+	public static var FAILED = "failed";
+	public static var PENDING = "pending";
+	
+	//	Wait the following number of milliseconds before flushing
+	public static var FLUSH_DELAY_DEFAULT = 500;
+	
+	public var flush_delay;
+	public var so;
+	public var timer;
+	
+	private var _NAMESPACE_KEY = "allNamespaces";
+	
+	public function Storage(){
+		flush_delay = Storage.FLUSH_DELAY_DEFAULT;
+	
+		DojoExternalInterface.initialize();
+		DojoExternalInterface.addCallback("put", this, put);
+		DojoExternalInterface.addCallback("putMultiple", this, putMultiple);
+		DojoExternalInterface.addCallback("get", this, get);
+		DojoExternalInterface.addCallback("getMultiple", this, getMultiple);
+		DojoExternalInterface.addCallback("showSettings", this, showSettings);
+		DojoExternalInterface.addCallback("clear", this, clear);
+		DojoExternalInterface.addCallback("getKeys", this, getKeys);
+		DojoExternalInterface.addCallback("getNamespaces", this, getNamespaces);
+		DojoExternalInterface.addCallback("remove", this, remove);
+		DojoExternalInterface.addCallback("removeMultiple", this, removeMultiple);
+		DojoExternalInterface.addCallback("flush", this, flush);
+		DojoExternalInterface.addCallback("setFlushDelay", this, setFlushDelay);
+		DojoExternalInterface.addCallback("getFlushDelay", this, getFlushDelay);
+		DojoExternalInterface.loaded();
+		
+		// preload the System Settings finished button movie for offline
+		// access so it is in the cache
+		_root.createEmptyMovieClip("_settingsBackground", 1);
+		_root._settingsBackground.loadMovie(DojoExternalInterface.dojoPath 
+																				+ "../dojox/storage/storage_dialog.swf");
+	}
+
+  //  FIXME: Whoever added this Flush code did not document why it
+  //  exists. Please also put your name and a bug number so I know 
+  //  who to contact. -- Brad Neuberg
+	
+	//	Set a new value for the flush delay timer.
+	//	Possible values:
+	//	  0 : Perform the flush synchronously after each "put" request
+	//	> 0 : Wait until 'newDelay' ms have passed without any "put" request to flush
+	//	 -1 : Do not automatically flush
+	public function setFlushDelay(newDelay){
+		flush_delay = Number(newDelay);
+	}
+	
+	public function getFlushDelay(){
+		return String(flush_delay);
+	}
+	
+	public function flush(namespace){
+		if(timer){
+			_global.clearTimeout(timer);
+			delete timer;
+		}
+	
+		var so = SharedObject.getLocal(namespace);
+		var flushResults = so.flush();
+
+		// return results of this command to JavaScript
+		var statusResults;
+		if(flushResults == true){
+			statusResults = Storage.SUCCESS;
+		}else if(flushResults == "pending"){
+			statusResults = Storage.PENDING;
+		}else{
+			statusResults = Storage.FAILED;
+		}
+		
+		DojoExternalInterface.call("dojox.storage._onStatus", statusResults, 
+		                            null, namespace);
+	}
+
+	public function put(keyName, keyValue, namespace){
+		// Get the SharedObject for these values and save it
+		so = SharedObject.getLocal(namespace);
+		
+		//  Save the key and value
+		so.data[keyName] = keyValue;
+		
+		// Save the namespace
+		// FIXME: Tie this into the flush/no-flush stuff below; right now
+		// we immediately write out this namespace. -- Brad Neuberg
+    addNamespace(namespace, keyName);
+
+		//	Do all the flush/no-flush stuff
+		var keyNames = new Array(); 
+		keyNames[0] = keyName;
+		postWrite(so, keyNames, namespace);
+	}
+	
+	public function putMultiple(metaKey, metaValue, metaLengths, namespace){
+		// Get the SharedObject for these values and save it
+		so = SharedObject.getLocal(namespace);
+		
+		//	Create array of keys and value lengths
+		var keys = metaKey.split(",");
+		var lengths = metaLengths.split(",");
+		
+		//	Loop through the array and write the values
+		for(var i = 0; i < keys.length; i++){
+			so.data[keys[i]] = metaValue.slice(0,lengths[i]);
+			metaValue = metaValue.slice(lengths[i]);
+		}
+		
+		// Save the namespace
+		// FIXME: Tie this into the flush/no-flush stuff below; right now
+		// we immediately write out this namespace. -- Brad Neuberg
+    addNamespace(namespace, null);
+		
+		//	Do all the flush/no-flush stuff
+		postWrite(so, keys, namespace);
+	}
+
+	public function postWrite(so, keyNames, namespace){
+		//	TODO: Review all this 'handler' stuff. In particular, the flush 
+		//  could now be with keys pending from several different requests, not 
+		//  only the ones passed in this method call
+
+		// prepare a storage status handler
+		var self = this;
+		so.onStatus = function(infoObject:Object){
+			//trace("onStatus, infoObject="+infoObject.code);
+			
+			// delete the data value if the request was denied
+			if(infoObject.code == "SharedObject.Flush.Failed"){
+				for(var i=0;i<keyNames.length;i++){
+					delete self.so.data[keyNames[i]];
+				}
+			}
+			
+			var statusResults;
+			if(infoObject.code == "SharedObject.Flush.Failed"){
+				statusResults = Storage.FAILED;
+			}else if(infoObject.code == "SharedObject.Flush.Pending"){
+				statusResults = Storage.PENDING;
+			}else if(infoObject.code == "SharedObject.Flush.Success"){
+				// if we have succeeded saving our value, see if we
+				// need to update our list of namespaces
+				if(self.hasNamespace(namespace) == true){
+					statusResults = Storage.SUCCESS;
+				}else{
+					// we have a new namespace we must store
+					self.addNamespace(namespace, keyNames[0]);
+					return;
+				}
+			}
+			//trace("onStatus, statusResults="+statusResults);
+			
+			// give the status results to JavaScript
+			DojoExternalInterface.call("dojox.storage._onStatus", statusResults, 
+			                            keyNames[0], namespace);
+		}
+		
+		//	Clear any pending flush timers
+		if(timer){
+			_global.clearTimeout(timer);
+		}
+		
+		//	If we have a flush delay set, set a timer for its execution
+		if(flush_delay > 0){
+			timer = _global.setTimeout(flush, flush_delay, namespace);
+		//	With a flush_delay value of 0, execute the flush request synchronously
+		}else if(flush_delay == 0){
+			flush(namespace);
+		}
+		//	Otherwise just don't flush - will be probably be flushed manually
+	}
+
+	public function get(keyName, namespace){
+		// Get the SharedObject for these values and save it
+		so = SharedObject.getLocal(namespace);
+		var results = so.data[keyName];
+		
+		return results;
+	}
+	
+	//	Returns an array with the contents of each key value on the metaKeys array
+	public function getMultiple(metaKeys, namespace){
+		//	get the storage object
+		so = SharedObject.getLocal(namespace);
+		
+		//	Create array of keys to read
+		var keys = metaKeys.split(",");
+		var results = new Array();
+		
+		//	Read from storage into results array
+		for(var i = 0;i < keys.length;i++){
+			var val = so.data[keys[i]];
+			val = val.split("\\").join("\\\\");
+			val = val.split('"').join('\\"');
+			results.push( val);
+		}
+			
+		//	Make the results array into a string
+		var metaResults = '["' + results.join('","') + '"]';
+		
+		return metaResults;
+	}	
+	
+	public function showSettings(){
+		// Show the configuration options for the Flash player, opened to the
+		// section for local storage controls (pane 1)
+		System.showSettings(1);
+		
+		// there is no way we can intercept when the Close button is pressed, allowing us
+		// to hide the Flash dialog. Instead, we need to load a movie in the
+		// background that we can show a close button on.
+		_root.createEmptyMovieClip("_settingsBackground", 1);
+		_root._settingsBackground.loadMovie(DojoExternalInterface.dojoPath 
+																				+ "../dojox/storage/storage_dialog.swf");
+	}
+	
+	public function clear(namespace){
+		so = SharedObject.getLocal(namespace);
+		so.clear();
+		so.flush();
+		
+		// remove this namespace entry now
+		removeNamespace(namespace);
+	}
+	
+	public function getKeys(namespace) : String{
+		// Returns a list of the available keys in this namespace
+		
+		// get the storage object
+		so = SharedObject.getLocal(namespace);
+		// get all of the keys
+		var results = [];
+		for(var i in so.data){
+			results.push(i);	
+		}
+		
+		// remove our key that records our list of namespaces
+		for(var i = 0; i < results.length; i++){
+			if(results[i] == _NAMESPACE_KEY){
+				results.splice(i, 1);
+				break;
+			}
+		}
+		
+		// a bug in ExternalInterface transforms Arrays into
+		// Strings, so we can't use those here! -- BradNeuberg
+		results = results.join(",");
+		
+		return results;
+	}
+	
+	public function getNamespaces() : String{
+		var allNamespaces = SharedObject.getLocal(_NAMESPACE_KEY);
+		var results = [];
+		
+		for(var i in allNamespaces.data){
+			results.push(i);
+		}
+		
+		// a bug in ExternalInterface transforms Arrays into
+		// Strings, so we can use those here! -- BradNeuberg
+		results = results.join(",");
+		
+		return results;
+	}
+	
+	public function remove(keyName, namespace){
+		// Removes a key
+
+		// get the storage object
+		so = SharedObject.getLocal(namespace);
+		
+		// delete this value
+		delete so.data[keyName];
+		
+		// save the changes
+		so.flush();
+		
+		// see if we are the last entry for this namespace
+		var availableKeys = getKeys(namespace);
+		if(availableKeys == ""){
+			// we are empty
+			removeNamespace(namespace);
+		}
+	}
+	
+	//	Removes all the values for each keys on the metaKeys array
+	public function removeMultiple(metaKeys, namespace){		
+		//	get the storage object
+		so = SharedObject.getLocal(namespace);
+		
+		//	Create array of keys to read
+		var keys = metaKeys.split(",");
+		var results = new Array();
+
+		//	Delete elements
+		for(var i=0;i<keys.length;i++){
+			delete so.data[keys[i]];
+		}
+
+		// see if there are no more entries for this namespace
+		var availableKeys = getKeys(namespace);
+		if(availableKeys == ""){
+			// we are empty
+			removeNamespace(namespace);
+		}
+	}
+	
+	private function hasNamespace(namespace):Boolean{
+		// Get the SharedObject for the namespace list
+		var allNamespaces = SharedObject.getLocal(_NAMESPACE_KEY);
+		
+		var results = false;
+		for(var i in allNamespaces.data){
+			if(i == namespace){
+				results = true;
+				break;
+			}
+		}
+		
+		return results;
+	}
+	
+	// FIXME: This code has gotten ugly -- refactor
+	private function addNamespace(namespace, keyName){
+		if(hasNamespace(namespace) == true){
+			return;
+		}
+		
+		// Get the SharedObject for the namespace list
+		var allNamespaces = SharedObject.getLocal(_NAMESPACE_KEY);
+		
+		// prepare a storage status handler if the keyName is
+		// not null
+		if(keyName != null && typeof keyName != "undefined"){
+			var self = this;
+			allNamespaces.onStatus = function(infoObject:Object){
+				// delete the data value if the request was denied
+				if(infoObject.code == "SharedObject.Flush.Failed"){
+					delete self.so.data[keyName];
+				}
+				
+				var statusResults;
+				if(infoObject.code == "SharedObject.Flush.Failed"){
+					statusResults = Storage.FAILED;
+				}else if(infoObject.code == "SharedObject.Flush.Pending"){
+					statusResults = Storage.PENDING;
+				}else if(infoObject.code == "SharedObject.Flush.Success"){
+					statusResults = Storage.SUCCESS;
+				}
+				
+				// give the status results to JavaScript
+				DojoExternalInterface.call("dojox.storage._onStatus", statusResults, 
+				                            keyName, namespace);
+			}
+		}
+		
+		// save the namespace list
+		allNamespaces.data[namespace] = true;
+		var flushResults = allNamespaces.flush();
+		
+		// return results of this command to JavaScript
+		if(keyName != null && typeof keyName != "undefined"){
+			var statusResults;
+			if(flushResults == true){
+				statusResults = Storage.SUCCESS;
+			}else if(flushResults == "pending"){
+				statusResults = Storage.PENDING;
+			}else{
+				statusResults = Storage.FAILED;
+			}
+			
+			DojoExternalInterface.call("dojox.storage._onStatus", statusResults, 
+			                            keyName, namespace);
+		}
+	}
+	
+	// FIXME: This code has gotten ugly -- refactor
+	private function removeNamespace(namespace){
+		if(hasNamespace(namespace) == false){
+			return;
+		}
+		
+		// try to save the namespace list; don't have a return
+		// callback; if we fail on this, the worst that will happen
+		// is that we have a spurious namespace entry
+		var allNamespaces = SharedObject.getLocal(_NAMESPACE_KEY);
+		delete allNamespaces.data[namespace];
+		allNamespaces.flush();
+	}
+
+	static function main(mc){
+		_root.app = new Storage(); 
+	}
+}
+
diff --git a/dojox/storage/Storage.swf b/dojox/storage/Storage.swf
new file mode 100644
index 0000000..9a09f70
Binary files /dev/null and b/dojox/storage/Storage.swf differ
diff --git a/dojox/storage/WhatWGStorageProvider.js b/dojox/storage/WhatWGStorageProvider.js
new file mode 100644
index 0000000..8c12a83
--- /dev/null
+++ b/dojox/storage/WhatWGStorageProvider.js
@@ -0,0 +1,158 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.storage.WhatWGStorageProvider"]){
+dojo._hasResource["dojox.storage.WhatWGStorageProvider"]=true;
+dojo.provide("dojox.storage.WhatWGStorageProvider");
+dojo.require("dojox.storage.Provider");
+dojo.require("dojox.storage.manager");
+dojo.declare("dojox.storage.WhatWGStorageProvider",[dojox.storage.Provider],{initialized:false,_domain:null,_available:null,_statusHandler:null,_allNamespaces:null,_storageEventListener:null,initialize:function(){
+if(dojo.config["disableWhatWGStorage"]==true){
+return;
+}
+this._domain=this._getDomain();
+this.initialized=true;
+dojox.storage.manager.loaded();
+},isAvailable:function(){
+try{
+var _1=globalStorage[this._getDomain()];
+}
+catch(e){
+this._available=false;
+return this._available;
+}
+this._available=true;
+return this._available;
+},put:function(_2,_3,_4,_5){
+if(this.isValidKey(_2)==false){
+throw new Error("Invalid key given: "+_2);
+}
+_5=_5||this.DEFAULT_NAMESPACE;
+_2=this.getFullKey(_2,_5);
+this._statusHandler=_4;
+if(dojo.isString(_3)){
+_3="string:"+_3;
+}else{
+_3=dojo.toJson(_3);
+}
+var _6=dojo.hitch(this,function(_7){
+window.removeEventListener("storage",_6,false);
+if(_4){
+_4.call(null,this.SUCCESS,_2,null,_5);
+}
+});
+window.addEventListener("storage",_6,false);
+try{
+var _8=globalStorage[this._domain];
+_8.setItem(_2,_3);
+}
+catch(e){
+this._statusHandler.call(null,this.FAILED,_2,e.toString(),_5);
+}
+},get:function(_9,_a){
+if(this.isValidKey(_9)==false){
+throw new Error("Invalid key given: "+_9);
+}
+_a=_a||this.DEFAULT_NAMESPACE;
+_9=this.getFullKey(_9,_a);
+var _b=globalStorage[this._domain];
+var _c=_b.getItem(_9);
+if(_c==null||_c==""){
+return null;
+}
+_c=_c.value;
+if(dojo.isString(_c)&&(/^string:/.test(_c))){
+_c=_c.substring("string:".length);
+}else{
+_c=dojo.fromJson(_c);
+}
+return _c;
+},getNamespaces:function(){
+var _d=[this.DEFAULT_NAMESPACE];
+var _e={};
+var _f=globalStorage[this._domain];
+var _10=/^__([^_]*)_/;
+for(var i=0;i<_f.length;i++){
+var _12=_f.key(i);
+if(_10.test(_12)==true){
+var _13=_12.match(_10)[1];
+if(typeof _e[_13]=="undefined"){
+_e[_13]=true;
+_d.push(_13);
+}
+}
+}
+return _d;
+},getKeys:function(_14){
+_14=_14||this.DEFAULT_NAMESPACE;
+if(this.isValidKey(_14)==false){
+throw new Error("Invalid namespace given: "+_14);
+}
+var _15;
+if(_14==this.DEFAULT_NAMESPACE){
+_15=new RegExp("^([^_]{2}.*)$");
+}else{
+_15=new RegExp("^__"+_14+"_(.*)$");
+}
+var _16=globalStorage[this._domain];
+var _17=[];
+for(var i=0;i<_16.length;i++){
+var _19=_16.key(i);
+if(_15.test(_19)==true){
+_19=_19.match(_15)[1];
+_17.push(_19);
+}
+}
+return _17;
+},clear:function(_1a){
+_1a=_1a||this.DEFAULT_NAMESPACE;
+if(this.isValidKey(_1a)==false){
+throw new Error("Invalid namespace given: "+_1a);
+}
+var _1b;
+if(_1a==this.DEFAULT_NAMESPACE){
+_1b=new RegExp("^[^_]{2}");
+}else{
+_1b=new RegExp("^__"+_1a+"_");
+}
+var _1c=globalStorage[this._domain];
+var _1d=[];
+for(var i=0;i<_1c.length;i++){
+if(_1b.test(_1c.key(i))==true){
+_1d[_1d.length]=_1c.key(i);
+}
+}
+dojo.forEach(_1d,dojo.hitch(_1c,"removeItem"));
+},remove:function(key,_20){
+key=this.getFullKey(key,_20);
+var _21=globalStorage[this._domain];
+_21.removeItem(key);
+},isPermanent:function(){
+return true;
+},getMaximumSize:function(){
+return this.SIZE_NO_LIMIT;
+},hasSettingsUI:function(){
+return false;
+},showSettingsUI:function(){
+throw new Error(this.declaredClass+" does not support a storage settings user-interface");
+},hideSettingsUI:function(){
+throw new Error(this.declaredClass+" does not support a storage settings user-interface");
+},getFullKey:function(key,_23){
+_23=_23||this.DEFAULT_NAMESPACE;
+if(this.isValidKey(_23)==false){
+throw new Error("Invalid namespace given: "+_23);
+}
+if(_23==this.DEFAULT_NAMESPACE){
+return key;
+}else{
+return "__"+_23+"_"+key;
+}
+},_getDomain:function(){
+return ((location.hostname=="localhost"&&dojo.isFF&&dojo.isFF<3)?"localhost.localdomain":location.hostname);
+}});
+dojox.storage.manager.register("dojox.storage.WhatWGStorageProvider",new dojox.storage.WhatWGStorageProvider());
+}
diff --git a/dojox/storage/_common.js b/dojox/storage/_common.js
new file mode 100644
index 0000000..d92bf22
--- /dev/null
+++ b/dojox/storage/_common.js
@@ -0,0 +1,17 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.storage._common"]){
+dojo._hasResource["dojox.storage._common"]=true;
+dojo.provide("dojox.storage._common");
+dojo.require("dojox.storage.Provider");
+dojo.require("dojox.storage.manager");
+dojo.require("dojox.storage.GearsStorageProvider");
+dojo.require("dojox.storage.WhatWGStorageProvider");
+dojo.require("dojox.storage.FlashStorageProvider");
+dojox.storage.manager.initialize();
+}
diff --git a/dojox/storage/buildFlashStorage.sh b/dojox/storage/buildFlashStorage.sh
new file mode 100644
index 0000000..892dca1
--- /dev/null
+++ b/dojox/storage/buildFlashStorage.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+# TODO: FIXME: Get rid of this and hook it into Dojo's general build script
+# You must have mtasc to run this
+mtasc -trace DojoExternalInterface.trace -main -cp ../flash -swf Storage.swf -version 8 -header 215:138:10 Storage.as
diff --git a/dojox/storage/manager.js b/dojox/storage/manager.js
new file mode 100644
index 0000000..e3f8a6f
--- /dev/null
+++ b/dojox/storage/manager.js
@@ -0,0 +1,118 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.storage.manager"]){
+dojo._hasResource["dojox.storage.manager"]=true;
+dojo.provide("dojox.storage.manager");
+dojox.storage.manager=new function(){
+this.currentProvider=null;
+this.available=false;
+this.providers=[];
+this._initialized=false;
+this._onLoadListeners=[];
+this.initialize=function(){
+this.autodetect();
+};
+this.register=function(_1,_2){
+this.providers.push(_2);
+this.providers[_1]=_2;
+};
+this.setProvider=function(_3){
+};
+this.autodetect=function(){
+if(this._initialized){
+return;
+}
+var _4=dojo.config["forceStorageProvider"]||false;
+var _5;
+for(var i=0;i<this.providers.length;i++){
+_5=this.providers[i];
+if(_4&&_4==_5.declaredClass){
+_5.isAvailable();
+break;
+}else{
+if(!_4&&_5.isAvailable()){
+break;
+}
+}
+}
+if(!_5){
+this._initialized=true;
+this.available=false;
+this.currentProvider=null;
+console.warn("No storage provider found for this platform");
+this.loaded();
+return;
+}
+this.currentProvider=_5;
+dojo.mixin(dojox.storage,this.currentProvider);
+dojox.storage.initialize();
+this._initialized=true;
+this.available=true;
+};
+this.isAvailable=function(){
+return this.available;
+};
+this.addOnLoad=function(_7){
+this._onLoadListeners.push(_7);
+if(this.isInitialized()){
+this._fireLoaded();
+}
+};
+this.removeOnLoad=function(_8){
+for(var i=0;i<this._onLoadListeners.length;i++){
+if(_8==this._onLoadListeners[i]){
+this._onLoadListeners=this._onLoadListeners.splice(i,1);
+break;
+}
+}
+};
+this.isInitialized=function(){
+if(this.currentProvider!=null&&this.currentProvider.declaredClass=="dojox.storage.FlashStorageProvider"&&dojox.flash.ready==false){
+return false;
+}else{
+return this._initialized;
+}
+};
+this.supportsProvider=function(_a){
+try{
+var _b=eval("new "+_a+"()");
+var _c=_b.isAvailable();
+if(!_c){
+return false;
+}
+return _c;
+}
+catch(e){
+return false;
+}
+};
+this.getProvider=function(){
+return this.currentProvider;
+};
+this.loaded=function(){
+this._fireLoaded();
+};
+this._fireLoaded=function(){
+dojo.forEach(this._onLoadListeners,function(i){
+try{
+i();
+}
+catch(e){
+
+}
+});
+};
+this.getResourceList=function(){
+var _e=[];
+dojo.forEach(dojox.storage.manager.providers,function(_f){
+_e=_e.concat(_f.getResourceList());
+});
+return _e;
+};
+};
+}
diff --git a/dojox/storage/storage_dialog.fla b/dojox/storage/storage_dialog.fla
new file mode 100644
index 0000000..8e9a093
Binary files /dev/null and b/dojox/storage/storage_dialog.fla differ
diff --git a/dojox/storage/storage_dialog.swf b/dojox/storage/storage_dialog.swf
new file mode 100644
index 0000000..db6b217
Binary files /dev/null and b/dojox/storage/storage_dialog.swf differ
diff --git a/dojox/string/BidiComplex.js b/dojox/string/BidiComplex.js
new file mode 100644
index 0000000..fc8f430
--- /dev/null
+++ b/dojox/string/BidiComplex.js
@@ -0,0 +1,246 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.string.BidiComplex"]){
+dojo._hasResource["dojox.string.BidiComplex"]=true;
+dojo.provide("dojox.string.BidiComplex");
+dojo.experimental("dojox.string.BidiComplex");
+(function(){
+var _1=[];
+dojox.string.BidiComplex.attachInput=function(_2,_3){
+_2.alt=_3;
+dojo.connect(_2,"onkeydown",this,"_ceKeyDown");
+dojo.connect(_2,"onkeyup",this,"_ceKeyUp");
+dojo.connect(_2,"oncut",this,"_ceCutText");
+dojo.connect(_2,"oncopy",this,"_ceCopyText");
+_2.value=dojox.string.BidiComplex.createDisplayString(_2.value,_2.alt);
+};
+dojox.string.BidiComplex.createDisplayString=function(_4,_5){
+_4=dojox.string.BidiComplex.stripSpecialCharacters(_4);
+var _6=dojox.string.BidiComplex._parse(_4,_5);
+var _7="‪"+_4;
+var _8=1;
+dojo.forEach(_6,function(n){
+if(n!=null){
+var _a=_7.substring(0,n+_8);
+var _b=_7.substring(n+_8,_7.length);
+_7=_a+"‎"+_b;
+_8++;
+}
+});
+return _7;
+};
+dojox.string.BidiComplex.stripSpecialCharacters=function(_c){
+return _c.replace(/[\u200E\u200F\u202A-\u202E]/g,"");
+};
+dojox.string.BidiComplex._ceKeyDown=function(_d){
+var _e=dojo.isIE?_d.srcElement:_d.target;
+_1=_e.value;
+};
+dojox.string.BidiComplex._ceKeyUp=function(_f){
+var LRM="‎";
+var _11=dojo.isIE?_f.srcElement:_f.target;
+var _12=_11.value;
+var _13=_f.keyCode;
+if((_13==dojo.keys.HOME)||(_13==dojo.keys.END)||(_13==dojo.keys.SHIFT)){
+return;
+}
+var _14,_15;
+var _16=dojox.string.BidiComplex._getCaretPos(_f,_11);
+if(_16){
+_14=_16[0];
+_15=_16[1];
+}
+if(dojo.isIE){
+var _17=_14,_18=_15;
+if(_13==dojo.keys.LEFT_ARROW){
+if((_12.charAt(_15-1)==LRM)&&(_14==_15)){
+dojox.string.BidiComplex._setSelectedRange(_11,_14-1,_15-1);
+}
+return;
+}
+if(_13==dojo.keys.RIGHT_ARROW){
+if(_12.charAt(_15-1)==LRM){
+_18=_15+1;
+if(_14==_15){
+_17=_14+1;
+}
+}
+dojox.string.BidiComplex._setSelectedRange(_11,_17,_18);
+return;
+}
+}else{
+if(_13==dojo.keys.LEFT_ARROW){
+if(_12.charAt(_15-1)==LRM){
+dojox.string.BidiComplex._setSelectedRange(_11,_14-1,_15-1);
+}
+return;
+}
+if(_13==dojo.keys.RIGHT_ARROW){
+if(_12.charAt(_15-1)==LRM){
+dojox.string.BidiComplex._setSelectedRange(_11,_14+1,_15+1);
+}
+return;
+}
+}
+var _19=dojox.string.BidiComplex.createDisplayString(_12,_11.alt);
+if(_12!=_19){
+window.status=_12+" c="+_15;
+_11.value=_19;
+if((_13==dojo.keys.DELETE)&&(_19.charAt(_15)==LRM)){
+_11.value=_19.substring(0,_15)+_19.substring(_15+2,_19.length);
+}
+if(_13==dojo.keys.DELETE){
+dojox.string.BidiComplex._setSelectedRange(_11,_14,_15);
+}else{
+if(_13==dojo.keys.BACKSPACE){
+if((_1.length>=_15)&&(_1.charAt(_15-1)==LRM)){
+dojox.string.BidiComplex._setSelectedRange(_11,_14-1,_15-1);
+}else{
+dojox.string.BidiComplex._setSelectedRange(_11,_14,_15);
+}
+}else{
+if(_11.value.charAt(_15)!=LRM){
+dojox.string.BidiComplex._setSelectedRange(_11,_14+1,_15+1);
+}
+}
+}
+}
+};
+dojox.string.BidiComplex._processCopy=function(_1a,_1b,_1c){
+if(_1b==null){
+if(dojo.isIE){
+var _1d=document.selection.createRange();
+_1b=_1d.text;
+}else{
+_1b=_1a.value.substring(_1a.selectionStart,_1a.selectionEnd);
+}
+}
+var _1e=dojox.string.BidiComplex.stripSpecialCharacters(_1b);
+if(dojo.isIE){
+window.clipboardData.setData("Text",_1e);
+}
+return true;
+};
+dojox.string.BidiComplex._ceCopyText=function(_1f){
+if(dojo.isIE){
+_1f.returnValue=false;
+}
+return dojox.string.BidiComplex._processCopy(_1f,null,false);
+};
+dojox.string.BidiComplex._ceCutText=function(_20){
+var ret=dojox.string.BidiComplex._processCopy(_20,null,false);
+if(!ret){
+return false;
+}
+if(dojo.isIE){
+document.selection.clear();
+}else{
+var _22=_20.selectionStart;
+_20.value=_20.value.substring(0,_22)+_20.value.substring(_20.selectionEnd);
+_20.setSelectionRange(_22,_22);
+}
+return true;
+};
+dojox.string.BidiComplex._getCaretPos=function(_23,_24){
+if(dojo.isIE){
+var _25=0,_26=document.selection.createRange().duplicate(),_27=_26.duplicate(),_28=_26.text.length;
+if(_24.type=="textarea"){
+_27.moveToElementText(_24);
+}else{
+_27.expand("textedit");
+}
+while(_26.compareEndPoints("StartToStart",_27)>0){
+_26.moveStart("character",-1);
+++_25;
+}
+return [_25,_25+_28];
+}
+return [_23.target.selectionStart,_23.target.selectionEnd];
+};
+dojox.string.BidiComplex._setSelectedRange=function(_29,_2a,_2b){
+if(dojo.isIE){
+var _2c=_29.createTextRange();
+if(_2c){
+if(_29.type=="textarea"){
+_2c.moveToElementText(_29);
+}else{
+_2c.expand("textedit");
+}
+_2c.collapse();
+_2c.moveEnd("character",_2b);
+_2c.moveStart("character",_2a);
+_2c.select();
+}
+}else{
+_29.selectionStart=_2a;
+_29.selectionEnd=_2b;
+}
+};
+var _2d=function(c){
+return (c>="0"&&c<="9")||(c>"ÿ");
+};
+var _2f=function(c){
+return (c>="A"&&c<="Z")||(c>="a"&&c<="z");
+};
+var _31=function(_32,i,_34){
+while(i>0){
+if(i==_34){
+return false;
+}
+i--;
+if(_2d(_32.charAt(i))){
+return true;
+}
+if(_2f(_32.charAt(i))){
+return false;
+}
+}
+return false;
+};
+dojox.string.BidiComplex._parse=function(str,_36){
+var _37=-1,_38=[];
+var _39={FILE_PATH:"/\\:.",URL:"/:.?=&#",XPATH:"/\\:.<>=[]",EMAIL:"<>@.,;"}[_36];
+switch(_36){
+case "FILE_PATH":
+case "URL":
+case "XPATH":
+dojo.forEach(str,function(ch,i){
+if(_39.indexOf(ch)>=0&&_31(str,i,_37)){
+_37=i;
+_38.push(i);
+}
+});
+break;
+case "EMAIL":
+var _3c=false;
+dojo.forEach(str,function(ch,i){
+if(ch=="\""){
+if(_31(str,i,_37)){
+_37=i;
+_38.push(i);
+}
+i++;
+var i1=str.indexOf("\"",i);
+if(i1>=i){
+i=i1;
+}
+if(_31(str,i,_37)){
+_37=i;
+_38.push(i);
+}
+}
+if(_39.indexOf(ch)>=0&&_31(str,i,_37)){
+_37=i;
+_38.push(i);
+}
+});
+}
+return _38;
+};
+})();
+}
diff --git a/dojox/string/Builder.js b/dojox/string/Builder.js
new file mode 100644
index 0000000..363680b
--- /dev/null
+++ b/dojox/string/Builder.js
@@ -0,0 +1,91 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.string.Builder"]){
+dojo._hasResource["dojox.string.Builder"]=true;
+dojo.provide("dojox.string.Builder");
+dojox.string.Builder=function(_1){
+var b="";
+this.length=0;
+this.append=function(s){
+if(arguments.length>1){
+var _4="",l=arguments.length;
+switch(l){
+case 9:
+_4=""+arguments[8]+_4;
+case 8:
+_4=""+arguments[7]+_4;
+case 7:
+_4=""+arguments[6]+_4;
+case 6:
+_4=""+arguments[5]+_4;
+case 5:
+_4=""+arguments[4]+_4;
+case 4:
+_4=""+arguments[3]+_4;
+case 3:
+_4=""+arguments[2]+_4;
+case 2:
+b+=""+arguments[0]+arguments[1]+_4;
+break;
+default:
+var i=0;
+while(i<arguments.length){
+_4+=arguments[i++];
+}
+b+=_4;
+}
+}else{
+b+=s;
+}
+this.length=b.length;
+return this;
+};
+this.concat=function(s){
+return this.append.apply(this,arguments);
+};
+this.appendArray=function(_8){
+return this.append.apply(this,_8);
+};
+this.clear=function(){
+b="";
+this.length=0;
+return this;
+};
+this.replace=function(_9,_a){
+b=b.replace(_9,_a);
+this.length=b.length;
+return this;
+};
+this.remove=function(_b,_c){
+if(_c===undefined){
+_c=b.length;
+}
+if(_c==0){
+return this;
+}
+b=b.substr(0,_b)+b.substr(_b+_c);
+this.length=b.length;
+return this;
+};
+this.insert=function(_d,_e){
+if(_d==0){
+b=_e+b;
+}else{
+b=b.slice(0,_d)+_e+b.slice(_d);
+}
+this.length=b.length;
+return this;
+};
+this.toString=function(){
+return b;
+};
+if(_1){
+this.append(_1);
+}
+};
+}
diff --git a/dojox/string/README b/dojox/string/README
new file mode 100644
index 0000000..c09d59e
--- /dev/null
+++ b/dojox/string/README
@@ -0,0 +1,39 @@
+-------------------------------------------------------------------------------
+DojoX String Utilities
+-------------------------------------------------------------------------------
+Version 0.9
+Release date: 05/08/2007
+-------------------------------------------------------------------------------
+Project state:
+dojox.string.Builder: production
+dojox.string.sprintf: beta
+dojox.string.tokenize: beta
+-------------------------------------------------------------------------------
+Project authors
+	Ben Lowery
+	Tom Trenka (ttrenka at gmail.com)
+	Neil Roberts
+-------------------------------------------------------------------------------
+Project description
+
+The DojoX String utilties project is a placeholder for miscellaneous string
+utility functions.  At the time of writing, only the Builder object has been
+added; but we anticipate other string utilities may end up living here as well.
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo Core (package loader).
+-------------------------------------------------------------------------------
+Documentation
+
+See the Dojo Toolkit API docs (http://dojotookit.org/api), dojo.string.Builder.
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/string/*
+
+Install into the following directory structure:
+/dojox/string/
+
+...which should be at the same level as your Dojo checkout.
diff --git a/dojox/string/sprintf.js b/dojox/string/sprintf.js
new file mode 100644
index 0000000..7c60252
--- /dev/null
+++ b/dojox/string/sprintf.js
@@ -0,0 +1,280 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.string.sprintf"]){
+dojo._hasResource["dojox.string.sprintf"]=true;
+dojo.provide("dojox.string.sprintf");
+dojo.require("dojox.string.tokenize");
+dojox.string.sprintf=function(_1,_2){
+for(var _3=[],i=1;i<arguments.length;i++){
+_3.push(arguments[i]);
+}
+var _5=new dojox.string.sprintf.Formatter(_1);
+return _5.format.apply(_5,_3);
+};
+dojox.string.sprintf.Formatter=function(_6){
+var _7=[];
+this._mapped=false;
+this._format=_6;
+this._tokens=dojox.string.tokenize(_6,this._re,this._parseDelim,this);
+};
+dojo.extend(dojox.string.sprintf.Formatter,{_re:/\%(?:\(([\w_]+)\)|([1-9]\d*)\$)?([0 +\-\#]*)(\*|\d+)?(\.)?(\*|\d+)?[hlL]?([\%scdeEfFgGiouxX])/g,_parseDelim:function(_8,_9,_a,_b,_c,_d,_e){
+if(_8){
+this._mapped=true;
+}
+return {mapping:_8,intmapping:_9,flags:_a,_minWidth:_b,period:_c,_precision:_d,specifier:_e};
+},_specifiers:{b:{base:2,isInt:true},o:{base:8,isInt:true},x:{base:16,isInt:true},X:{extend:["x"],toUpper:true},d:{base:10,isInt:true},i:{extend:["d"]},u:{extend:["d"],isUnsigned:true},c:{setArg:function(_f){
+if(!isNaN(_f.arg)){
+var num=parseInt(_f.arg);
+if(num<0||num>127){
+throw new Error("invalid character code passed to %c in sprintf");
+}
+_f.arg=isNaN(num)?""+num:String.fromCharCode(num);
+}
+}},s:{setMaxWidth:function(_11){
+_11.maxWidth=(_11.period==".")?_11.precision:-1;
+}},e:{isDouble:true,doubleNotation:"e"},E:{extend:["e"],toUpper:true},f:{isDouble:true,doubleNotation:"f"},F:{extend:["f"]},g:{isDouble:true,doubleNotation:"g"},G:{extend:["g"],toUpper:true}},format:function(_12){
+if(this._mapped&&typeof _12!="object"){
+throw new Error("format requires a mapping");
+}
+var str="";
+var _14=0;
+for(var i=0,_16;i<this._tokens.length;i++){
+_16=this._tokens[i];
+if(typeof _16=="string"){
+str+=_16;
+}else{
+if(this._mapped){
+if(typeof _12[_16.mapping]=="undefined"){
+throw new Error("missing key "+_16.mapping);
+}
+_16.arg=_12[_16.mapping];
+}else{
+if(_16.intmapping){
+var _14=parseInt(_16.intmapping)-1;
+}
+if(_14>=arguments.length){
+throw new Error("got "+arguments.length+" printf arguments, insufficient for '"+this._format+"'");
+}
+_16.arg=arguments[_14++];
+}
+if(!_16.compiled){
+_16.compiled=true;
+_16.sign="";
+_16.zeroPad=false;
+_16.rightJustify=false;
+_16.alternative=false;
+var _17={};
+for(var fi=_16.flags.length;fi--;){
+var _19=_16.flags.charAt(fi);
+_17[_19]=true;
+switch(_19){
+case " ":
+_16.sign=" ";
+break;
+case "+":
+_16.sign="+";
+break;
+case "0":
+_16.zeroPad=(_17["-"])?false:true;
+break;
+case "-":
+_16.rightJustify=true;
+_16.zeroPad=false;
+break;
+case "#":
+_16.alternative=true;
+break;
+default:
+throw Error("bad formatting flag '"+_16.flags.charAt(fi)+"'");
+}
+}
+_16.minWidth=(_16._minWidth)?parseInt(_16._minWidth):0;
+_16.maxWidth=-1;
+_16.toUpper=false;
+_16.isUnsigned=false;
+_16.isInt=false;
+_16.isDouble=false;
+_16.precision=1;
+if(_16.period=="."){
+if(_16._precision){
+_16.precision=parseInt(_16._precision);
+}else{
+_16.precision=0;
+}
+}
+var _1a=this._specifiers[_16.specifier];
+if(typeof _1a=="undefined"){
+throw new Error("unexpected specifier '"+_16.specifier+"'");
+}
+if(_1a.extend){
+dojo.mixin(_1a,this._specifiers[_1a.extend]);
+delete _1a.extend;
+}
+dojo.mixin(_16,_1a);
+}
+if(typeof _16.setArg=="function"){
+_16.setArg(_16);
+}
+if(typeof _16.setMaxWidth=="function"){
+_16.setMaxWidth(_16);
+}
+if(_16._minWidth=="*"){
+if(this._mapped){
+throw new Error("* width not supported in mapped formats");
+}
+_16.minWidth=parseInt(arguments[_14++]);
+if(isNaN(_16.minWidth)){
+throw new Error("the argument for * width at position "+_14+" is not a number in "+this._format);
+}
+if(_16.minWidth<0){
+_16.rightJustify=true;
+_16.minWidth=-_16.minWidth;
+}
+}
+if(_16._precision=="*"&&_16.period=="."){
+if(this._mapped){
+throw new Error("* precision not supported in mapped formats");
+}
+_16.precision=parseInt(arguments[_14++]);
+if(isNaN(_16.precision)){
+throw Error("the argument for * precision at position "+_14+" is not a number in "+this._format);
+}
+if(_16.precision<0){
+_16.precision=1;
+_16.period="";
+}
+}
+if(_16.isInt){
+if(_16.period=="."){
+_16.zeroPad=false;
+}
+this.formatInt(_16);
+}else{
+if(_16.isDouble){
+if(_16.period!="."){
+_16.precision=6;
+}
+this.formatDouble(_16);
+}
+}
+this.fitField(_16);
+str+=""+_16.arg;
+}
+}
+return str;
+},_zeros10:"0000000000",_spaces10:"          ",formatInt:function(_1b){
+var i=parseInt(_1b.arg);
+if(!isFinite(i)){
+if(typeof _1b.arg!="number"){
+throw new Error("format argument '"+_1b.arg+"' not an integer; parseInt returned "+i);
+}
+i=0;
+}
+if(i<0&&(_1b.isUnsigned||_1b.base!=10)){
+i=4294967295+i+1;
+}
+if(i<0){
+_1b.arg=(-i).toString(_1b.base);
+this.zeroPad(_1b);
+_1b.arg="-"+_1b.arg;
+}else{
+_1b.arg=i.toString(_1b.base);
+if(!i&&!_1b.precision){
+_1b.arg="";
+}else{
+this.zeroPad(_1b);
+}
+if(_1b.sign){
+_1b.arg=_1b.sign+_1b.arg;
+}
+}
+if(_1b.base==16){
+if(_1b.alternative){
+_1b.arg="0x"+_1b.arg;
+}
+_1b.arg=_1b.toUpper?_1b.arg.toUpperCase():_1b.arg.toLowerCase();
+}
+if(_1b.base==8){
+if(_1b.alternative&&_1b.arg.charAt(0)!="0"){
+_1b.arg="0"+_1b.arg;
+}
+}
+},formatDouble:function(_1d){
+var f=parseFloat(_1d.arg);
+if(!isFinite(f)){
+if(typeof _1d.arg!="number"){
+throw new Error("format argument '"+_1d.arg+"' not a float; parseFloat returned "+f);
+}
+f=0;
+}
+switch(_1d.doubleNotation){
+case "e":
+_1d.arg=f.toExponential(_1d.precision);
+break;
+case "f":
+_1d.arg=f.toFixed(_1d.precision);
+break;
+case "g":
+if(Math.abs(f)<0.0001){
+_1d.arg=f.toExponential(_1d.precision>0?_1d.precision-1:_1d.precision);
+}else{
+_1d.arg=f.toPrecision(_1d.precision);
+}
+if(!_1d.alternative){
+_1d.arg=_1d.arg.replace(/(\..*[^0])0*/,"$1");
+_1d.arg=_1d.arg.replace(/\.0*e/,"e").replace(/\.0$/,"");
+}
+break;
+default:
+throw new Error("unexpected double notation '"+_1d.doubleNotation+"'");
+}
+_1d.arg=_1d.arg.replace(/e\+(\d)$/,"e+0$1").replace(/e\-(\d)$/,"e-0$1");
+if(dojo.isOpera){
+_1d.arg=_1d.arg.replace(/^\./,"0.");
+}
+if(_1d.alternative){
+_1d.arg=_1d.arg.replace(/^(\d+)$/,"$1.");
+_1d.arg=_1d.arg.replace(/^(\d+)e/,"$1.e");
+}
+if(f>=0&&_1d.sign){
+_1d.arg=_1d.sign+_1d.arg;
+}
+_1d.arg=_1d.toUpper?_1d.arg.toUpperCase():_1d.arg.toLowerCase();
+},zeroPad:function(_1f,_20){
+_20=(arguments.length==2)?_20:_1f.precision;
+if(typeof _1f.arg!="string"){
+_1f.arg=""+_1f.arg;
+}
+var _21=_20-10;
+while(_1f.arg.length<_21){
+_1f.arg=(_1f.rightJustify)?_1f.arg+this._zeros10:this._zeros10+_1f.arg;
+}
+var pad=_20-_1f.arg.length;
+_1f.arg=(_1f.rightJustify)?_1f.arg+this._zeros10.substring(0,pad):this._zeros10.substring(0,pad)+_1f.arg;
+},fitField:function(_23){
+if(_23.maxWidth>=0&&_23.arg.length>_23.maxWidth){
+return _23.arg.substring(0,_23.maxWidth);
+}
+if(_23.zeroPad){
+this.zeroPad(_23,_23.minWidth);
+return;
+}
+this.spacePad(_23);
+},spacePad:function(_24,_25){
+_25=(arguments.length==2)?_25:_24.minWidth;
+if(typeof _24.arg!="string"){
+_24.arg=""+_24.arg;
+}
+var _26=_25-10;
+while(_24.arg.length<_26){
+_24.arg=(_24.rightJustify)?_24.arg+this._spaces10:this._spaces10+_24.arg;
+}
+var pad=_25-_24.arg.length;
+_24.arg=(_24.rightJustify)?_24.arg+this._spaces10.substring(0,pad):this._spaces10.substring(0,pad)+_24.arg;
+}});
+}
diff --git a/dojox/string/tokenize.js b/dojox/string/tokenize.js
new file mode 100644
index 0000000..a6052a4
--- /dev/null
+++ b/dojox/string/tokenize.js
@@ -0,0 +1,40 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.string.tokenize"]){
+dojo._hasResource["dojox.string.tokenize"]=true;
+dojo.provide("dojox.string.tokenize");
+dojox.string.tokenize=function(_1,re,_3,_4){
+var _5=[];
+var _6,_7,_8=0;
+while(_6=re.exec(_1)){
+_7=_1.slice(_8,re.lastIndex-_6[0].length);
+if(_7.length){
+_5.push(_7);
+}
+if(_3){
+if(dojo.isOpera){
+var _9=_6.slice(0);
+while(_9.length<_6.length){
+_9.push(null);
+}
+_6=_9;
+}
+var _a=_3.apply(_4,_6.slice(1).concat(_5.length));
+if(typeof _a!="undefined"){
+_5.push(_a);
+}
+}
+_8=re.lastIndex;
+}
+_7=_1.slice(_8);
+if(_7.length){
+_5.push(_7);
+}
+return _5;
+};
+}
diff --git a/dojox/testing/DocTest.js b/dojox/testing/DocTest.js
new file mode 100644
index 0000000..16c5795
--- /dev/null
+++ b/dojox/testing/DocTest.js
@@ -0,0 +1,91 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.testing.DocTest"]){
+dojo._hasResource["dojox.testing.DocTest"]=true;
+dojo.provide("dojox.testing.DocTest");
+dojo.require("dojo.string");
+dojo.declare("dojox.testing.DocTest",null,{errors:[],getTests:function(_1){
+var _2=dojo.moduleUrl(_1).path;
+var _3=_2.substring(0,_2.length-1)+".js";
+var _4=dojo.xhrGet({url:_3,handleAs:"text"});
+var _5=dojo._getText(_3);
+return this._getTestsFromString(_5,true);
+},getTestsFromString:function(_6){
+return this._getTestsFromString(_6,false);
+},_getTestsFromString:function(_7,_8){
+var _9=dojo.hitch(dojo.string,"trim");
+var _a=_7.split("\n");
+var _b=_a.length;
+var _c=[];
+var _d={commands:[],expectedResult:[],line:null};
+for(var i=0;i<_b+1;i++){
+var l=_9(_a[i]||"");
+if((_8&&l.match(/^\/\/\s+>>>\s.*/))||l.match(/^\s*>>>\s.*/)){
+if(!_d.line){
+_d.line=i+1;
+}
+if(_d.expectedResult.length>0){
+_c.push({commands:_d.commands,expectedResult:_d.expectedResult.join("\n"),line:_d.line});
+_d={commands:[],expectedResult:[],line:i+1};
+}
+l=_8?_9(l).substring(2,l.length):l;
+l=_9(l).substring(3,l.length);
+_d.commands.push(_9(l));
+}else{
+if((!_8||l.match(/^\/\/\s+.*/))&&_d.commands.length&&_d.expectedResult.length==0){
+l=_8?_9(l).substring(3,l.length):l;
+_d.expectedResult.push(_9(l));
+}else{
+if(_d.commands.length>0&&_d.expectedResult.length){
+if(!_8||l.match(/^\/\/\s*$/)){
+_c.push({commands:_d.commands,expectedResult:_d.expectedResult.join("\n"),line:_d.line});
+}
+if(_8&&!l.match(/^\/\//)){
+_c.push({commands:_d.commands,expectedResult:_d.expectedResult.join("\n"),line:_d.line});
+}
+_d={commands:[],expectedResult:[],line:0};
+}
+}
+}
+}
+return _c;
+},run:function(_10){
+this.errors=[];
+var _11=this.getTests(_10);
+if(_11){
+this._run(_11);
+}
+},_run:function(_12){
+var len=_12.length;
+this.tests=len;
+var oks=0;
+for(var i=0;i<len;i++){
+var t=_12[i];
+var res=this.runTest(t.commands,t.expectedResult);
+var msg="Test "+(i+1)+": ";
+var _19=t.commands.join(" ");
+_19=(_19.length>50?_19.substr(0,50)+"...":_19);
+if(res.success){
+
+oks+=1;
+}else{
+this.errors.push({commands:t.commands,actual:res.actualResult,expected:t.expectedResult});
+console.error(msg+"Failed: "+_19,{commands:t.commands,actualResult:res.actualResult,expectedResult:t.expectedResult});
+}
+}
+
+},runTest:function(_1a,_1b){
+var ret={success:false,actualResult:null};
+var _1d=_1a.join("\n");
+ret.actualResult=eval(_1d);
+if((String(ret.actualResult)==_1b)||(dojo.toJson(ret.actualResult)==_1b)||((_1b.charAt(0)=="\"")&&(_1b.charAt(_1b.length-1)=="\"")&&(String(ret.actualResult)==_1b.substring(1,_1b.length-1)))){
+ret.success=true;
+}
+return ret;
+}});
+}
diff --git a/dojox/testing/README b/dojox/testing/README
new file mode 100644
index 0000000..7087eb8
--- /dev/null
+++ b/dojox/testing/README
@@ -0,0 +1,41 @@
+-------------------------------------------------------------------------------
+dojox.testing
+-------------------------------------------------------------------------------
+Version 0.1
+Release date: 06/18/08
+-------------------------------------------------------------------------------
+Project state:
+experimental
+-------------------------------------------------------------------------------
+Credits
+	Wolfram Kriesing (wolfram at dojotoolkit.org)
+-------------------------------------------------------------------------------
+Project description 
+
+	A port of Python's DocTests module to Dojo and D.O.H. which is also
+	compatible with Dojo's API documentation system
+ 
+-------------------------------------------------------------------------------
+Dependencies:
+
+	dojo.string, DOH
+
+-------------------------------------------------------------------------------
+Documentation
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+
+	http://svn.dojotoolkit.org/dojo/dojox/trunk/testing/*
+
+Install into the following directory structure:
+
+	/dojox/testing/
+
+...which should be at the same level as your Dojo checkout.
+-------------------------------------------------------------------------------
+Additional Notes
+
+	None.
diff --git a/dojox/timing.js b/dojox/timing.js
new file mode 100644
index 0000000..f2751a6
--- /dev/null
+++ b/dojox/timing.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.timing"]){
+dojo._hasResource["dojox.timing"]=true;
+dojo.provide("dojox.timing");
+dojo.require("dojox.timing._base");
+}
diff --git a/dojox/timing/README b/dojox/timing/README
new file mode 100644
index 0000000..6673d19
--- /dev/null
+++ b/dojox/timing/README
@@ -0,0 +1,63 @@
+-------------------------------------------------------------------------------
+DojoX Timing
+-------------------------------------------------------------------------------
+Version 0.1.0
+Release date: 08/08/2007
+-------------------------------------------------------------------------------
+Project state:
+experimental
+-------------------------------------------------------------------------------
+Credits
+	Tom Trenka (ttrenka AT gmail.com): original Timer, Streamer, Thread and ThreadPool
+	Wolfram Kriesing (http://wolfram.kriesing.de/blog/): Sequence
+	Jonathan Bond-Caron (jbondc AT gmail.com): port of Timer and Streamer
+	Pete Higgins (phiggins AT gmail.com): port of Sequence
+	Mike Wilcox (anm8tr AT yahoo.com): dojo.doLater
+-------------------------------------------------------------------------------
+Project description
+
+DojoX Timing is a project that deals with any kind of advanced use of timing
+constructs.  The central object, dojox.timing.Timer (included by default), is
+a simple object that fires a callback on each tick of the timer, as well as 
+when starting or stopping it.  The interval of each tick is settable, but the
+default is 1 second--useful for driving something such as a clock.
+
+dojox.timing.Streamer is an object designed to facilitate streaming/buffer-type
+scenarios; it takes an input and an output function, will execute the output
+function onTick, and run the input function when the internal buffer gets 
+beneath a certain threshold of items.  This can be useful for something timed--
+such as updating a data plot at every N interval, and getting new data from
+a source when there's less than X data points in the internal buffer (think
+real-time data updating).
+
+dojox.timing.Sequencer is an object, similar to Streamer, that will allow you
+to set up a set of functions to be executed in a specific order, at specific
+intervals.
+
+The DojoX Timing ThreadPool is a port from the original implementation in the
+f(m) library.  It allows a user to feed a set of callback functions (wrapped
+in a Thread constructor) to a pool for background processing.
+
+dojo.doLater() provides a simple mechanism that checks a conditional before allowing
+your function to continue. If the conditional is false, the function is blocked and continually
+re-called, with arguments, until the conditional passes.
+-------------------------------------------------------------------------------
+Dependencies:
+
+DojoX Timing only relies on the Dojo Base.
+-------------------------------------------------------------------------------
+Documentation
+
+TBD.
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/timing.js
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/timing/*
+
+Install into the following directory structure:
+/dojox/timing.js
+/dojox/timing/
+
+...which should be at the same level as your Dojo checkout.
diff --git a/dojox/timing/Sequence.js b/dojox/timing/Sequence.js
new file mode 100644
index 0000000..076314e
--- /dev/null
+++ b/dojox/timing/Sequence.js
@@ -0,0 +1,87 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.timing.Sequence"]){
+dojo._hasResource["dojox.timing.Sequence"]=true;
+dojo.provide("dojox.timing.Sequence");
+dojo.experimental("dojox.timing.Sequence");
+dojo.declare("dojox.timing.Sequence",null,{_goOnPause:0,_running:false,constructor:function(){
+this._defsResolved=[];
+},go:function(_1,_2){
+this._running=true;
+dojo.forEach(_1,function(_3){
+if(_3.repeat>1){
+var _4=_3.repeat;
+for(var j=0;j<_4;j++){
+_3.repeat=1;
+this._defsResolved.push(_3);
+}
+}else{
+this._defsResolved.push(_3);
+}
+},this);
+var _6=_1[_1.length-1];
+if(_2){
+this._defsResolved.push({func:_2});
+}
+this._defsResolved.push({func:[this.stop,this]});
+this._curId=0;
+this._go();
+},_go:function(){
+if(!this._running){
+return;
+}
+var _7=this._defsResolved[this._curId];
+this._curId+=1;
+function _8(_9){
+var _a=null;
+if(dojo.isArray(_9)){
+if(_9.length>2){
+_a=_9[0].apply(_9[1],_9.slice(2));
+}else{
+_a=_9[0].apply(_9[1]);
+}
+}else{
+_a=_9();
+}
+return _a;
+};
+if(this._curId>=this._defsResolved.length){
+_8(_7.func);
+return;
+}
+if(_7.pauseAfter){
+if(_8(_7.func)!==false){
+setTimeout(dojo.hitch(this,"_go"),_7.pauseAfter);
+}else{
+this._goOnPause=_7.pauseAfter;
+}
+}else{
+if(_7.pauseBefore){
+var x=dojo.hitch(this,function(){
+if(_8(_7.func)!==false){
+this._go();
+}
+});
+setTimeout(x,_7.pauseBefore);
+}else{
+if(_8(_7.func)!==false){
+this._go();
+}
+}
+}
+},goOn:function(){
+if(this._goOnPause){
+setTimeout(dojo.hitch(this,"_go"),this._goOnPause);
+this._goOnPause=0;
+}else{
+this._go();
+}
+},stop:function(){
+this._running=false;
+}});
+}
diff --git a/dojox/timing/Streamer.js b/dojox/timing/Streamer.js
new file mode 100644
index 0000000..abb1294
--- /dev/null
+++ b/dojox/timing/Streamer.js
@@ -0,0 +1,64 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.timing.Streamer"]){
+dojo._hasResource["dojox.timing.Streamer"]=true;
+dojo.provide("dojox.timing.Streamer");
+dojo.require("dojox.timing._base");
+dojox.timing.Streamer=function(_1,_2,_3,_4,_5){
+var _6=this;
+var _7=[];
+this.interval=_3||1000;
+this.minimumSize=_4||10;
+this.inputFunction=_1||function(q){
+};
+this.outputFunction=_2||function(_9){
+};
+var _a=new dojox.timing.Timer(this.interval);
+var _b=function(){
+_6.onTick(_6);
+if(_7.length<_6.minimumSize){
+_6.inputFunction(_7);
+}
+var _c=_7.shift();
+while(typeof (_c)=="undefined"&&_7.length>0){
+_c=_7.shift();
+}
+if(typeof (_c)=="undefined"){
+_6.stop();
+return;
+}
+_6.outputFunction(_c);
+};
+this.setInterval=function(ms){
+this.interval=ms;
+_a.setInterval(ms);
+};
+this.onTick=function(_e){
+};
+this.start=function(){
+if(typeof (this.inputFunction)=="function"&&typeof (this.outputFunction)=="function"){
+_a.start();
+return;
+}
+throw new Error("You cannot start a Streamer without an input and an output function.");
+};
+this.onStart=function(){
+};
+this.stop=function(){
+_a.stop();
+};
+this.onStop=function(){
+};
+_a.onTick=this.tick;
+_a.onStart=this.onStart;
+_a.onStop=this.onStop;
+if(_5){
+_7.concat(_5);
+}
+};
+}
diff --git a/dojox/timing/ThreadPool.js b/dojox/timing/ThreadPool.js
new file mode 100644
index 0000000..898ab89
--- /dev/null
+++ b/dojox/timing/ThreadPool.js
@@ -0,0 +1,142 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.timing.ThreadPool"]){
+dojo._hasResource["dojox.timing.ThreadPool"]=true;
+dojo.provide("dojox.timing.ThreadPool");
+dojo.require("dojox.timing");
+dojo.experimental("dojox.timing.ThreadPool");
+(function(){
+var t=dojox.timing;
+t.threadStates={UNSTARTED:"unstarted",STOPPED:"stopped",PENDING:"pending",RUNNING:"running",SUSPENDED:"suspended",WAITING:"waiting",COMPLETE:"complete",ERROR:"error"};
+t.threadPriorities={LOWEST:1,BELOWNORMAL:2,NORMAL:3,ABOVENORMAL:4,HIGHEST:5};
+t.Thread=function(fn,_3){
+var _4=this;
+this.state=t.threadStates.UNSTARTED;
+this.priority=_3||t.threadPriorities.NORMAL;
+this.lastError=null;
+this.func=fn;
+this.invoke=function(){
+_4.state=t.threadStates.RUNNING;
+try{
+fn(this);
+_4.state=t.threadStates.COMPLETE;
+}
+catch(e){
+_4.lastError=e;
+_4.state=t.threadStates.ERROR;
+}
+};
+};
+t.ThreadPool=new (function(_5,_6){
+var _7=this;
+var _8=_5;
+var _9=_8;
+var _a=_6;
+var _b=Math.floor((_a/2)/_8);
+var _c=[];
+var _d=new Array(_8+1);
+var _e=new dojox.timing.Timer();
+var _f=function(){
+var _10=_d[0]={};
+for(var i=0;i<_d.length;i++){
+window.clearTimeout(_d[i]);
+var _12=_c.shift();
+if(typeof (_12)=="undefined"){
+break;
+}
+_10["thread-"+i]=_12;
+_d[i]=window.setTimeout(_12.invoke,(_b*i));
+}
+_9=_8-(i-1);
+};
+this.getMaxThreads=function(){
+return _8;
+};
+this.getAvailableThreads=function(){
+return _9;
+};
+this.getTickInterval=function(){
+return _a;
+};
+this.queueUserWorkItem=function(fn){
+var _14=fn;
+if(_14 instanceof Function){
+_14=new t.Thread(_14);
+}
+var idx=_c.length;
+for(var i=0;i<_c.length;i++){
+if(_c[i].priority<_14.priority){
+idx=i;
+break;
+}
+}
+if(idx<_c.length){
+_c.splice(idx,0,_14);
+}else{
+_c.push(_14);
+}
+return true;
+};
+this.removeQueuedUserWorkItem=function(_17){
+if(_17 instanceof Function){
+var idx=-1;
+for(var i=0;i<_c.length;i++){
+if(_c[i].func==_17){
+idx=i;
+break;
+}
+}
+if(idx>-1){
+_c.splice(idx,1);
+return true;
+}
+return false;
+}
+var idx=-1;
+for(var i=0;i<_c.length;i++){
+if(_c[i]==_17){
+idx=i;
+break;
+}
+}
+if(idx>-1){
+_c.splice(idx,1);
+return true;
+}
+return false;
+};
+this.start=function(){
+_e.start();
+};
+this.stop=function(){
+_e.stop();
+};
+this.abort=function(){
+this.stop();
+for(var i=1;i<_d.length;i++){
+if(_d[i]){
+window.clearTimeout(_d[i]);
+}
+}
+for(var _1b in _d[0]){
+this.queueUserWorkItem(_1b);
+}
+_d[0]={};
+};
+this.reset=function(){
+this.abort();
+_c=[];
+};
+this.sleep=function(_1c){
+_e.stop();
+window.setTimeout(_e.start,_1c);
+};
+_e.onTick=_7.invoke;
+})(16,5000);
+})();
+}
diff --git a/dojox/timing/_base.js b/dojox/timing/_base.js
new file mode 100644
index 0000000..c056c92
--- /dev/null
+++ b/dojox/timing/_base.js
@@ -0,0 +1,41 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.timing._base"]){
+dojo._hasResource["dojox.timing._base"]=true;
+dojo.provide("dojox.timing._base");
+dojo.experimental("dojox.timing");
+dojox.timing.Timer=function(_1){
+this.timer=null;
+this.isRunning=false;
+this.interval=_1;
+this.onStart=null;
+this.onStop=null;
+};
+dojo.extend(dojox.timing.Timer,{onTick:function(){
+},setInterval:function(_2){
+if(this.isRunning){
+window.clearInterval(this.timer);
+}
+this.interval=_2;
+if(this.isRunning){
+this.timer=window.setInterval(dojo.hitch(this,"onTick"),this.interval);
+}
+},start:function(){
+if(typeof this.onStart=="function"){
+this.onStart();
+}
+this.isRunning=true;
+this.timer=window.setInterval(dojo.hitch(this,"onTick"),this.interval);
+},stop:function(){
+if(typeof this.onStop=="function"){
+this.onStop();
+}
+this.isRunning=false;
+window.clearInterval(this.timer);
+}});
+}
diff --git a/dojox/timing/doLater.js b/dojox/timing/doLater.js
new file mode 100644
index 0000000..76d7c8c
--- /dev/null
+++ b/dojox/timing/doLater.js
@@ -0,0 +1,24 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.timing.doLater"]){
+dojo._hasResource["dojox.timing.doLater"]=true;
+dojo.provide("dojox.timing.doLater");
+dojo.experimental("dojox.timing.doLater");
+dojox.timing.doLater=function(_1,_2,_3){
+if(_1){
+return false;
+}
+var _4=dojox.timing.doLater.caller,_5=dojox.timing.doLater.caller.arguments;
+_3=_3||100;
+_2=_2||dojo.global;
+setTimeout(function(){
+_4.apply(_2,_5);
+},_3);
+return true;
+};
+}
diff --git a/dojox/uuid.js b/dojox/uuid.js
new file mode 100644
index 0000000..b8443a4
--- /dev/null
+++ b/dojox/uuid.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.uuid"]){
+dojo._hasResource["dojox.uuid"]=true;
+dojo.provide("dojox.uuid");
+dojo.require("dojox.uuid._base");
+}
diff --git a/dojox/uuid/README b/dojox/uuid/README
new file mode 100644
index 0000000..4cb7c98
--- /dev/null
+++ b/dojox/uuid/README
@@ -0,0 +1,43 @@
+-------------------------------------------------------------------------------
+DojoX UUID
+-------------------------------------------------------------------------------
+Version 0.9
+Release date: 06/21/2007
+-------------------------------------------------------------------------------
+Project state: production
+-------------------------------------------------------------------------------
+Project authors
+	Brian Douglas Skinner (skinner at dojotoolkit.org)
+-------------------------------------------------------------------------------
+Project description
+
+DojoX UUID is the port of the original Dojo 0.4.x UUID classes.  The UUID 
+classes can be used to represent Universally Unique IDentifiers (UUIDs), as
+described in the IETF's RFC 4122: 
+  http://tools.ietf.org/html/rfc4122
+
+The DojoX UUID classes provide support for generating both "time-based" UUIDs
+and lightweight "random" UUIDs.  DojoX UUID does not yet have support for 
+generating new "name-based" UUIDs, but the dojo.uuid.Uuid class can represent
+existing name-based UUIDs, such as UUIDs read from a file or from a server. 
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+DojoX UUID has no dependencies, outside of Dojo Core.
+-------------------------------------------------------------------------------
+Documentation
+
+See the API documentation for Dojo (http://dojotoolkit.org/api).
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/uuid.js
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/uuid/*
+
+Install into the following directory structure:
+/dojox/uuid/
+
+...which should be at the same level as your Dojo checkout.
+-------------------------------------------------------------------------------
diff --git a/dojox/uuid/Uuid.js b/dojox/uuid/Uuid.js
new file mode 100644
index 0000000..02ee540
--- /dev/null
+++ b/dojox/uuid/Uuid.js
@@ -0,0 +1,99 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.uuid.Uuid"]){
+dojo._hasResource["dojox.uuid.Uuid"]=true;
+dojo.provide("dojox.uuid.Uuid");
+dojo.require("dojox.uuid");
+dojox.uuid.Uuid=function(_1){
+this._uuidString=dojox.uuid.NIL_UUID;
+if(_1){
+dojox.uuid.assert(dojo.isString(_1));
+this._uuidString=_1.toLowerCase();
+dojox.uuid.assert(this.isValid());
+}else{
+var _2=dojox.uuid.Uuid.getGenerator();
+if(_2){
+this._uuidString=_2();
+dojox.uuid.assert(this.isValid());
+}
+}
+};
+dojox.uuid.Uuid.compare=function(_3,_4){
+var _5=_3.toString();
+var _6=_4.toString();
+if(_5>_6){
+return 1;
+}
+if(_5<_6){
+return -1;
+}
+return 0;
+};
+dojox.uuid.Uuid.setGenerator=function(_7){
+dojox.uuid.assert(!_7||dojo.isFunction(_7));
+dojox.uuid.Uuid._ourGenerator=_7;
+};
+dojox.uuid.Uuid.getGenerator=function(){
+return dojox.uuid.Uuid._ourGenerator;
+};
+dojox.uuid.Uuid.prototype.toString=function(){
+return this._uuidString;
+};
+dojox.uuid.Uuid.prototype.compare=function(_8){
+return dojox.uuid.Uuid.compare(this,_8);
+};
+dojox.uuid.Uuid.prototype.isEqual=function(_9){
+return (this.compare(_9)==0);
+};
+dojox.uuid.Uuid.prototype.isValid=function(){
+return dojox.uuid.isValid(this);
+};
+dojox.uuid.Uuid.prototype.getVariant=function(){
+return dojox.uuid.getVariant(this);
+};
+dojox.uuid.Uuid.prototype.getVersion=function(){
+if(!this._versionNumber){
+this._versionNumber=dojox.uuid.getVersion(this);
+}
+return this._versionNumber;
+};
+dojox.uuid.Uuid.prototype.getNode=function(){
+if(!this._nodeString){
+this._nodeString=dojox.uuid.getNode(this);
+}
+return this._nodeString;
+};
+dojox.uuid.Uuid.prototype.getTimestamp=function(_a){
+if(!_a){
+_a=null;
+}
+switch(_a){
+case "string":
+case String:
+return this.getTimestamp(Date).toUTCString();
+break;
+case "hex":
+if(!this._timestampAsHexString){
+this._timestampAsHexString=dojox.uuid.getTimestamp(this,"hex");
+}
+return this._timestampAsHexString;
+break;
+case null:
+case "date":
+case Date:
+if(!this._timestampAsDate){
+this._timestampAsDate=dojox.uuid.getTimestamp(this,Date);
+}
+return this._timestampAsDate;
+break;
+default:
+dojox.uuid.assert(false,"The getTimestamp() method dojox.uuid.Uuid was passed a bogus returnType: "+_a);
+break;
+}
+};
+}
diff --git a/dojox/uuid/_base.js b/dojox/uuid/_base.js
new file mode 100644
index 0000000..02a1483
--- /dev/null
+++ b/dojox/uuid/_base.js
@@ -0,0 +1,136 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.uuid._base"]){
+dojo._hasResource["dojox.uuid._base"]=true;
+dojo.provide("dojox.uuid._base");
+dojox.uuid.NIL_UUID="00000000-0000-0000-0000-000000000000";
+dojox.uuid.version={UNKNOWN:0,TIME_BASED:1,DCE_SECURITY:2,NAME_BASED_MD5:3,RANDOM:4,NAME_BASED_SHA1:5};
+dojox.uuid.variant={NCS:"0",DCE:"10",MICROSOFT:"110",UNKNOWN:"111"};
+dojox.uuid.assert=function(_1,_2){
+if(!_1){
+if(!_2){
+_2="An assert statement failed.\n"+"The method dojox.uuid.assert() was called with a 'false' value.\n";
+}
+throw new Error(_2);
+}
+};
+dojox.uuid.generateNilUuid=function(){
+return dojox.uuid.NIL_UUID;
+};
+dojox.uuid.isValid=function(_3){
+_3=_3.toString();
+var _4=(dojo.isString(_3)&&(_3.length==36)&&(_3==_3.toLowerCase()));
+if(_4){
+var _5=_3.split("-");
+_4=((_5.length==5)&&(_5[0].length==8)&&(_5[1].length==4)&&(_5[2].length==4)&&(_5[3].length==4)&&(_5[4].length==12));
+var _6=16;
+for(var i in _5){
+var _8=_5[i];
+var _9=parseInt(_8,_6);
+_4=_4&&isFinite(_9);
+}
+}
+return _4;
+};
+dojox.uuid.getVariant=function(_a){
+if(!dojox.uuid._ourVariantLookupTable){
+var _b=dojox.uuid.variant;
+var _c=[];
+_c[0]=_b.NCS;
+_c[1]=_b.NCS;
+_c[2]=_b.NCS;
+_c[3]=_b.NCS;
+_c[4]=_b.NCS;
+_c[5]=_b.NCS;
+_c[6]=_b.NCS;
+_c[7]=_b.NCS;
+_c[8]=_b.DCE;
+_c[9]=_b.DCE;
+_c[10]=_b.DCE;
+_c[11]=_b.DCE;
+_c[12]=_b.MICROSOFT;
+_c[13]=_b.MICROSOFT;
+_c[14]=_b.UNKNOWN;
+_c[15]=_b.UNKNOWN;
+dojox.uuid._ourVariantLookupTable=_c;
+}
+_a=_a.toString();
+var _d=_a.charAt(19);
+var _e=16;
+var _f=parseInt(_d,_e);
+dojox.uuid.assert((_f>=0)&&(_f<=16));
+return dojox.uuid._ourVariantLookupTable[_f];
+};
+dojox.uuid.getVersion=function(_10){
+var _11="dojox.uuid.getVersion() was not passed a DCE Variant UUID.";
+dojox.uuid.assert(dojox.uuid.getVariant(_10)==dojox.uuid.variant.DCE,_11);
+_10=_10.toString();
+var _12=_10.charAt(14);
+var _13=16;
+var _14=parseInt(_12,_13);
+return _14;
+};
+dojox.uuid.getNode=function(_15){
+var _16="dojox.uuid.getNode() was not passed a TIME_BASED UUID.";
+dojox.uuid.assert(dojox.uuid.getVersion(_15)==dojox.uuid.version.TIME_BASED,_16);
+_15=_15.toString();
+var _17=_15.split("-");
+var _18=_17[4];
+return _18;
+};
+dojox.uuid.getTimestamp=function(_19,_1a){
+var _1b="dojox.uuid.getTimestamp() was not passed a TIME_BASED UUID.";
+dojox.uuid.assert(dojox.uuid.getVersion(_19)==dojox.uuid.version.TIME_BASED,_1b);
+_19=_19.toString();
+if(!_1a){
+_1a=null;
+}
+switch(_1a){
+case "string":
+case String:
+return dojox.uuid.getTimestamp(_19,Date).toUTCString();
+break;
+case "hex":
+var _1c=_19.split("-");
+var _1d=_1c[0];
+var _1e=_1c[1];
+var _1f=_1c[2];
+_1f=_1f.slice(1);
+var _20=_1f+_1e+_1d;
+dojox.uuid.assert(_20.length==15);
+return _20;
+break;
+case null:
+case "date":
+case Date:
+var _21=3394248;
+var _22=16;
+var _23=_19.split("-");
+var _24=parseInt(_23[0],_22);
+var _25=parseInt(_23[1],_22);
+var _26=parseInt(_23[2],_22);
+var _27=_26&4095;
+_27<<=16;
+_27+=_25;
+_27*=4294967296;
+_27+=_24;
+var _28=_27/10000;
+var _29=60*60;
+var _2a=_21;
+var _2b=_2a*_29;
+var _2c=_2b*1000;
+var _2d=_28-_2c;
+var _2e=new Date(_2d);
+return _2e;
+break;
+default:
+dojox.uuid.assert(false,"dojox.uuid.getTimestamp was not passed a valid returnType: "+_1a);
+break;
+}
+};
+}
diff --git a/dojox/uuid/generateRandomUuid.js b/dojox/uuid/generateRandomUuid.js
new file mode 100644
index 0000000..573bcaf
--- /dev/null
+++ b/dojox/uuid/generateRandomUuid.js
@@ -0,0 +1,34 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.uuid.generateRandomUuid"]){
+dojo._hasResource["dojox.uuid.generateRandomUuid"]=true;
+dojo.provide("dojox.uuid.generateRandomUuid");
+dojox.uuid.generateRandomUuid=function(){
+var _1=16;
+function _2(){
+var _3=Math.floor((Math.random()%1)*Math.pow(2,32));
+var _4=_3.toString(_1);
+while(_4.length<8){
+_4="0"+_4;
+}
+return _4;
+};
+var _5="-";
+var _6="4";
+var _7="8";
+var a=_2();
+var b=_2();
+b=b.substring(0,4)+_5+_6+b.substring(5,8);
+var c=_2();
+c=_7+c.substring(1,4)+_5+c.substring(4,8);
+var d=_2();
+var _c=a+_5+b+_5+c+d;
+_c=_c.toLowerCase();
+return _c;
+};
+}
diff --git a/dojox/uuid/generateTimeBasedUuid.js b/dojox/uuid/generateTimeBasedUuid.js
new file mode 100644
index 0000000..c800f77
--- /dev/null
+++ b/dojox/uuid/generateTimeBasedUuid.js
@@ -0,0 +1,197 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.uuid.generateTimeBasedUuid"]){
+dojo._hasResource["dojox.uuid.generateTimeBasedUuid"]=true;
+dojo.provide("dojox.uuid.generateTimeBasedUuid");
+dojox.uuid.generateTimeBasedUuid=function(_1){
+var _2=dojox.uuid.generateTimeBasedUuid._generator.generateUuidString(_1);
+return _2;
+};
+dojox.uuid.generateTimeBasedUuid.isValidNode=function(_3){
+var _4=16;
+var _5=parseInt(_3,_4);
+var _6=dojo.isString(_3)&&_3.length==12&&isFinite(_5);
+return _6;
+};
+dojox.uuid.generateTimeBasedUuid.setNode=function(_7){
+dojox.uuid.assert((_7===null)||this.isValidNode(_7));
+this._uniformNode=_7;
+};
+dojox.uuid.generateTimeBasedUuid.getNode=function(){
+return this._uniformNode;
+};
+dojox.uuid.generateTimeBasedUuid._generator=new function(){
+this.GREGORIAN_CHANGE_OFFSET_IN_HOURS=3394248;
+var _8=null;
+var _9=null;
+var _a=null;
+var _b=0;
+var _c=null;
+var _d=null;
+var _e=16;
+function _f(_10){
+_10[2]+=_10[3]>>>16;
+_10[3]&=65535;
+_10[1]+=_10[2]>>>16;
+_10[2]&=65535;
+_10[0]+=_10[1]>>>16;
+_10[1]&=65535;
+dojox.uuid.assert((_10[0]>>>16)===0);
+};
+function _11(x){
+var _13=new Array(0,0,0,0);
+_13[3]=x%65536;
+x-=_13[3];
+x/=65536;
+_13[2]=x%65536;
+x-=_13[2];
+x/=65536;
+_13[1]=x%65536;
+x-=_13[1];
+x/=65536;
+_13[0]=x;
+return _13;
+};
+function _14(_15,_16){
+dojox.uuid.assert(dojo.isArray(_15));
+dojox.uuid.assert(dojo.isArray(_16));
+dojox.uuid.assert(_15.length==4);
+dojox.uuid.assert(_16.length==4);
+var _17=new Array(0,0,0,0);
+_17[3]=_15[3]+_16[3];
+_17[2]=_15[2]+_16[2];
+_17[1]=_15[1]+_16[1];
+_17[0]=_15[0]+_16[0];
+_f(_17);
+return _17;
+};
+function _18(_19,_1a){
+dojox.uuid.assert(dojo.isArray(_19));
+dojox.uuid.assert(dojo.isArray(_1a));
+dojox.uuid.assert(_19.length==4);
+dojox.uuid.assert(_1a.length==4);
+var _1b=false;
+if(_19[0]*_1a[0]!==0){
+_1b=true;
+}
+if(_19[0]*_1a[1]!==0){
+_1b=true;
+}
+if(_19[0]*_1a[2]!==0){
+_1b=true;
+}
+if(_19[1]*_1a[0]!==0){
+_1b=true;
+}
+if(_19[1]*_1a[1]!==0){
+_1b=true;
+}
+if(_19[2]*_1a[0]!==0){
+_1b=true;
+}
+dojox.uuid.assert(!_1b);
+var _1c=new Array(0,0,0,0);
+_1c[0]+=_19[0]*_1a[3];
+_f(_1c);
+_1c[0]+=_19[1]*_1a[2];
+_f(_1c);
+_1c[0]+=_19[2]*_1a[1];
+_f(_1c);
+_1c[0]+=_19[3]*_1a[0];
+_f(_1c);
+_1c[1]+=_19[1]*_1a[3];
+_f(_1c);
+_1c[1]+=_19[2]*_1a[2];
+_f(_1c);
+_1c[1]+=_19[3]*_1a[1];
+_f(_1c);
+_1c[2]+=_19[2]*_1a[3];
+_f(_1c);
+_1c[2]+=_19[3]*_1a[2];
+_f(_1c);
+_1c[3]+=_19[3]*_1a[3];
+_f(_1c);
+return _1c;
+};
+function _1d(_1e,_1f){
+while(_1e.length<_1f){
+_1e="0"+_1e;
+}
+return _1e;
+};
+function _20(){
+var _21=Math.floor((Math.random()%1)*Math.pow(2,32));
+var _22=_21.toString(_e);
+while(_22.length<8){
+_22="0"+_22;
+}
+return _22;
+};
+this.generateUuidString=function(_23){
+if(_23){
+dojox.uuid.assert(dojox.uuid.generateTimeBasedUuid.isValidNode(_23));
+}else{
+if(dojox.uuid.generateTimeBasedUuid._uniformNode){
+_23=dojox.uuid.generateTimeBasedUuid._uniformNode;
+}else{
+if(!_8){
+var _24=32768;
+var _25=Math.floor((Math.random()%1)*Math.pow(2,15));
+var _26=(_24|_25).toString(_e);
+_8=_26+_20();
+}
+_23=_8;
+}
+}
+if(!_9){
+var _27=32768;
+var _28=Math.floor((Math.random()%1)*Math.pow(2,14));
+_9=(_27|_28).toString(_e);
+}
+var now=new Date();
+var _2a=now.valueOf();
+var _2b=_11(_2a);
+if(!_c){
+var _2c=_11(60*60);
+var _2d=_11(dojox.uuid.generateTimeBasedUuid._generator.GREGORIAN_CHANGE_OFFSET_IN_HOURS);
+var _2e=_18(_2d,_2c);
+var _2f=_11(1000);
+_c=_18(_2e,_2f);
+_d=_11(10000);
+}
+var _30=_2b;
+var _31=_14(_c,_30);
+var _32=_18(_31,_d);
+if(now.valueOf()==_a){
+_32[3]+=_b;
+_f(_32);
+_b+=1;
+if(_b==10000){
+while(now.valueOf()==_a){
+now=new Date();
+}
+}
+}else{
+_a=now.valueOf();
+_b=1;
+}
+var _33=_32[2].toString(_e);
+var _34=_32[3].toString(_e);
+var _35=_1d(_33,4)+_1d(_34,4);
+var _36=_32[1].toString(_e);
+_36=_1d(_36,4);
+var _37=_32[0].toString(_e);
+_37=_1d(_37,3);
+var _38="-";
+var _39="1";
+var _3a=_35+_38+_36+_38+_39+_37+_38+_9+_38+_23;
+_3a=_3a.toLowerCase();
+return _3a;
+};
+}();
+}
diff --git a/dojox/validate.js b/dojox/validate.js
new file mode 100644
index 0000000..98ee537
--- /dev/null
+++ b/dojox/validate.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.validate"]){
+dojo._hasResource["dojox.validate"]=true;
+dojo.provide("dojox.validate");
+dojo.require("dojox.validate._base");
+}
diff --git a/dojox/validate/README b/dojox/validate/README
new file mode 100644
index 0000000..3544c1b
--- /dev/null
+++ b/dojox/validate/README
@@ -0,0 +1,60 @@
+-------------------------------------------------------------------------------
+dojox.validate
+-------------------------------------------------------------------------------
+Version 0.02
+Release date: 07/12/2007
+-------------------------------------------------------------------------------
+Project state: experimental / beta
+-------------------------------------------------------------------------------
+Credits
+	port: Peter Higgins (dante)
+	contributions: Kun Xi (bookstack at gmail com)
+-------------------------------------------------------------------------------
+Project description
+
+	Provides a set of validation functions to match
+	values against known constants for use in form
+	validation, such as email address, TLD, ipAddress,
+	country-specific phone numbers and SSN, among
+	others.. 
+
+	It is broken into many parts. dojox.validate._base
+	is required by most named modules in this project.
+	
+	ca.js provides Canadian specific functionality
+	
+	check.js provides an experimental form-management utility,
+		which will likely be deprecated in favor 
+
+	creditCard.js provides validation functions for most standard
+		credit card types. 
+		
+	isbn.js validates ISBN numbers
+	
+	regexp.js provides a strange place to put regular expressions
+		related to validation. It was formerly polluting namespaces
+		and created in `dojox.regexp`. This is now `dojox.validate.regexp`
+		to confine values to the dojox.validate project.
+		
+	us.js provides US-Specific validation. Zip, Social, etc.
+	
+	web.js provides url and email address validation, as well as a number
+		of web/network related validation functions. 
+		
+-------------------------------------------------------------------------------
+Dependencies:
+
+	Requires Base Dojo and dojo.regexp.
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+
+http://svn.dojotoolkit.org/src/dojox/trunk/validate.js
+http://svn.dojotoolkit.org/src/dojox/trunk/validate
+
+Install into the following directory structure:
+/dojox/validate/
+
+...which should be at the same level as your Dojo checkout.
diff --git a/dojox/validate/_base.js b/dojox/validate/_base.js
new file mode 100644
index 0000000..962ff22
--- /dev/null
+++ b/dojox/validate/_base.js
@@ -0,0 +1,68 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.validate._base"]){
+dojo._hasResource["dojox.validate._base"]=true;
+dojo.provide("dojox.validate._base");
+dojo.experimental("dojox.validate");
+dojo.require("dojo.regexp");
+dojo.require("dojo.number");
+dojo.require("dojox.validate.regexp");
+dojox.validate.isText=function(_1,_2){
+_2=(typeof _2=="object")?_2:{};
+if(/^\s*$/.test(_1)){
+return false;
+}
+if(typeof _2.length=="number"&&_2.length!=_1.length){
+return false;
+}
+if(typeof _2.minlength=="number"&&_2.minlength>_1.length){
+return false;
+}
+if(typeof _2.maxlength=="number"&&_2.maxlength<_1.length){
+return false;
+}
+return true;
+};
+dojox.validate._isInRangeCache={};
+dojox.validate.isInRange=function(_3,_4){
+_3=dojo.number.parse(_3,_4);
+if(isNaN(_3)){
+return false;
+}
+_4=(typeof _4=="object")?_4:{};
+var _5=(typeof _4.max=="number")?_4.max:Infinity,_6=(typeof _4.min=="number")?_4.min:-Infinity,_7=(typeof _4.decimal=="string")?_4.decimal:".",_8=dojox.validate._isInRangeCache,_9=_3+"max"+_5+"min"+_6+"dec"+_7;
+if(typeof _8[_9]!="undefined"){
+return _8[_9];
+}
+_8[_9]=!(_3<_6||_3>_5);
+return _8[_9];
+};
+dojox.validate.isNumberFormat=function(_a,_b){
+var re=new RegExp("^"+dojox.validate.regexp.numberFormat(_b)+"$","i");
+return re.test(_a);
+};
+dojox.validate.isValidLuhn=function(_d){
+var _e=0,_f,_10;
+if(!dojo.isString(_d)){
+_d=String(_d);
+}
+_d=_d.replace(/[- ]/g,"");
+_f=_d.length%2;
+for(var i=0;i<_d.length;i++){
+_10=parseInt(_d.charAt(i));
+if(i%2==_f){
+_10*=2;
+}
+if(_10>9){
+_10-=9;
+}
+_e+=_10;
+}
+return !(_e%10);
+};
+}
diff --git a/dojox/validate/ca.js b/dojox/validate/ca.js
new file mode 100644
index 0000000..20fbb27
--- /dev/null
+++ b/dojox/validate/ca.js
@@ -0,0 +1,24 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.validate.ca"]){
+dojo._hasResource["dojox.validate.ca"]=true;
+dojo.provide("dojox.validate.ca");
+dojo.require("dojox.validate._base");
+dojo.mixin(dojox.validate.ca,{isPhoneNumber:function(_1){
+return dojox.validate.us.isPhoneNumber(_1);
+},isProvince:function(_2){
+var re=new RegExp("^"+dojox.validate.regexp.ca.province()+"$","i");
+return re.test(_2);
+},isSocialInsuranceNumber:function(_4){
+var _5={format:["###-###-###","### ### ###","#########"]};
+return dojox.validate.isNumberFormat(_4,_5);
+},isPostalCode:function(_6){
+var re=new RegExp("^"+dojox.validate.regexp.ca.postalCode()+"$","i");
+return re.test(_6);
+}});
+}
diff --git a/dojox/validate/check.js b/dojox/validate/check.js
new file mode 100644
index 0000000..352fc9c
--- /dev/null
+++ b/dojox/validate/check.js
@@ -0,0 +1,230 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.validate.check"]){
+dojo._hasResource["dojox.validate.check"]=true;
+dojo.provide("dojox.validate.check");
+dojo.experimental;
+dojo.require("dojox.validate._base");
+dojox.validate.check=function(_1,_2){
+var _3=[];
+var _4=[];
+var _5={isSuccessful:function(){
+return (!this.hasInvalid()&&!this.hasMissing());
+},hasMissing:function(){
+return (_3.length>0);
+},getMissing:function(){
+return _3;
+},isMissing:function(_6){
+for(var i=0;i<_3.length;i++){
+if(_6==_3[i]){
+return true;
+}
+}
+return false;
+},hasInvalid:function(){
+return (_4.length>0);
+},getInvalid:function(){
+return _4;
+},isInvalid:function(_8){
+for(var i=0;i<_4.length;i++){
+if(_8==_4[i]){
+return true;
+}
+}
+return false;
+}};
+var _a=function(_b,_c){
+return (typeof _c[_b]=="undefined");
+};
+if(_2.trim instanceof Array){
+for(var i=0;i<_2.trim.length;i++){
+var _e=_1[_2.trim[i]];
+if(_a("type",_e)||_e.type!="text"&&_e.type!="textarea"&&_e.type!="password"){
+continue;
+}
+_e.value=_e.value.replace(/(^\s*|\s*$)/g,"");
+}
+}
+if(_2.uppercase instanceof Array){
+for(var i=0;i<_2.uppercase.length;i++){
+var _e=_1[_2.uppercase[i]];
+if(_a("type",_e)||_e.type!="text"&&_e.type!="textarea"&&_e.type!="password"){
+continue;
+}
+_e.value=_e.value.toUpperCase();
+}
+}
+if(_2.lowercase instanceof Array){
+for(var i=0;i<_2.lowercase.length;i++){
+var _e=_1[_2.lowercase[i]];
+if(_a("type",_e)||_e.type!="text"&&_e.type!="textarea"&&_e.type!="password"){
+continue;
+}
+_e.value=_e.value.toLowerCase();
+}
+}
+if(_2.ucfirst instanceof Array){
+for(var i=0;i<_2.ucfirst.length;i++){
+var _e=_1[_2.ucfirst[i]];
+if(_a("type",_e)||_e.type!="text"&&_e.type!="textarea"&&_e.type!="password"){
+continue;
+}
+_e.value=_e.value.replace(/\b\w+\b/g,function(_f){
+return _f.substring(0,1).toUpperCase()+_f.substring(1).toLowerCase();
+});
+}
+}
+if(_2.digit instanceof Array){
+for(var i=0;i<_2.digit.length;i++){
+var _e=_1[_2.digit[i]];
+if(_a("type",_e)||_e.type!="text"&&_e.type!="textarea"&&_e.type!="password"){
+continue;
+}
+_e.value=_e.value.replace(/\D/g,"");
+}
+}
+if(_2.required instanceof Array){
+for(var i=0;i<_2.required.length;i++){
+if(!dojo.isString(_2.required[i])){
+continue;
+}
+var _e=_1[_2.required[i]];
+if(!_a("type",_e)&&(_e.type=="text"||_e.type=="textarea"||_e.type=="password"||_e.type=="file")&&/^\s*$/.test(_e.value)){
+_3[_3.length]=_e.name;
+}else{
+if(!_a("type",_e)&&(_e.type=="select-one"||_e.type=="select-multiple")&&(_e.selectedIndex==-1||/^\s*$/.test(_e.options[_e.selectedIndex].value))){
+_3[_3.length]=_e.name;
+}else{
+if(_e instanceof Array){
+var _10=false;
+for(var j=0;j<_e.length;j++){
+if(_e[j].checked){
+_10=true;
+}
+}
+if(!_10){
+_3[_3.length]=_e[0].name;
+}
+}
+}
+}
+}
+}
+if(_2.required instanceof Array){
+for(var i=0;i<_2.required.length;i++){
+if(!dojo.isObject(_2.required[i])){
+continue;
+}
+var _e,_12;
+for(var _13 in _2.required[i]){
+_e=_1[_13];
+_12=_2.required[i][_13];
+}
+if(_e instanceof Array){
+var _10=0;
+for(var j=0;j<_e.length;j++){
+if(_e[j].checked){
+_10++;
+}
+}
+if(_10<_12){
+_3[_3.length]=_e[0].name;
+}
+}else{
+if(!_a("type",_e)&&_e.type=="select-multiple"){
+var _14=0;
+for(var j=0;j<_e.options.length;j++){
+if(_e.options[j].selected&&!/^\s*$/.test(_e.options[j].value)){
+_14++;
+}
+}
+if(_14<_12){
+_3[_3.length]=_e.name;
+}
+}
+}
+}
+}
+if(dojo.isObject(_2.dependencies)){
+for(_13 in _2.dependencies){
+var _e=_1[_13];
+if(_a("type",_e)){
+continue;
+}
+if(_e.type!="text"&&_e.type!="textarea"&&_e.type!="password"){
+continue;
+}
+if(/\S+/.test(_e.value)){
+continue;
+}
+if(_5.isMissing(_e.name)){
+continue;
+}
+var _15=_1[_2.dependencies[_13]];
+if(_15.type!="text"&&_15.type!="textarea"&&_15.type!="password"){
+continue;
+}
+if(/^\s*$/.test(_15.value)){
+continue;
+}
+_3[_3.length]=_e.name;
+}
+}
+if(dojo.isObject(_2.constraints)){
+for(_13 in _2.constraints){
+var _e=_1[_13];
+if(!_e){
+continue;
+}
+if(!_a("tagName",_e)&&(_e.tagName.toLowerCase().indexOf("input")>=0||_e.tagName.toLowerCase().indexOf("textarea")>=0)&&/^\s*$/.test(_e.value)){
+continue;
+}
+var _16=true;
+if(dojo.isFunction(_2.constraints[_13])){
+_16=_2.constraints[_13](_e.value);
+}else{
+if(dojo.isArray(_2.constraints[_13])){
+if(dojo.isArray(_2.constraints[_13][0])){
+for(var i=0;i<_2.constraints[_13].length;i++){
+_16=dojox.validate.evaluateConstraint(_2,_2.constraints[_13][i],_13,_e);
+if(!_16){
+break;
+}
+}
+}else{
+_16=dojox.validate.evaluateConstraint(_2,_2.constraints[_13],_13,_e);
+}
+}
+}
+if(!_16){
+_4[_4.length]=_e.name;
+}
+}
+}
+if(dojo.isObject(_2.confirm)){
+for(_13 in _2.confirm){
+var _e=_1[_13];
+var _15=_1[_2.confirm[_13]];
+if(_a("type",_e)||_a("type",_15)||(_e.type!="text"&&_e.type!="textarea"&&_e.type!="password")||(_15.type!=_e.type)||(_15.value==_e.value)||(_5.isInvalid(_e.name))||(/^\s*$/.test(_15.value))){
+continue;
+}
+_4[_4.length]=_e.name;
+}
+}
+return _5;
+};
+dojox.validate.evaluateConstraint=function(_17,_18,_19,_1a){
+var _1b=_18[0];
+var _1c=_18.slice(1);
+_1c.unshift(_1a.value);
+if(typeof _1b!="undefined"){
+return _1b.apply(null,_1c);
+}
+return false;
+};
+}
diff --git a/dojox/validate/creditCard.js b/dojox/validate/creditCard.js
new file mode 100644
index 0000000..c9386ea
--- /dev/null
+++ b/dojox/validate/creditCard.js
@@ -0,0 +1,48 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.validate.creditCard"]){
+dojo._hasResource["dojox.validate.creditCard"]=true;
+dojo.provide("dojox.validate.creditCard");
+dojo.require("dojox.validate._base");
+dojox.validate._cardInfo={"mc":"5[1-5][0-9]{14}","ec":"5[1-5][0-9]{14}","vi":"4(?:[0-9]{12}|[0-9]{15})","ax":"3[47][0-9]{13}","dc":"3(?:0[0-5][0-9]{11}|[68][0-9]{12})","bl":"3(?:0[0-5][0-9]{11}|[68][0-9]{12})","di":"6011[0-9]{12}","jcb":"(?:3[0-9]{15}|(2131|1800)[0-9]{11})","er":"2(?:014|149)[0-9]{11}"};
+dojox.validate.isValidCreditCard=function(_1,_2){
+return ((_2.toLowerCase()=="er"||dojox.validate.isValidLuhn(_1))&&dojox.validate.isValidCreditCardNumber(_1,_2.toLowerCase()));
+};
+dojox.validate.isValidCreditCardNumber=function(_3,_4){
+_3=String(_3).replace(/[- ]/g,"");
+var _5=dojox.validate._cardInfo,_6=[];
+if(_4){
+var _7=_5[_4.toLowerCase()];
+return _7?!!_3.match(_7):false;
+}
+for(var p in _5){
+if(_3.match("^"+_5[p]+"$")){
+_6.push(p);
+}
+}
+return _6.length?_6.join("|"):false;
+};
+dojox.validate.isValidCvv=function(_9,_a){
+if(!dojo.isString(_9)){
+_9=String(_9);
+}
+var _b;
+switch(_a.toLowerCase()){
+case "mc":
+case "ec":
+case "vi":
+case "di":
+_b="###";
+break;
+case "ax":
+_b="####";
+break;
+}
+return !!_b&&_9.length&&dojox.validate.isNumberFormat(_9,{format:_b});
+};
+}
diff --git a/dojox/validate/isbn.js b/dojox/validate/isbn.js
new file mode 100644
index 0000000..3e118f5
--- /dev/null
+++ b/dojox/validate/isbn.js
@@ -0,0 +1,40 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.validate.isbn"]){
+dojo._hasResource["dojox.validate.isbn"]=true;
+dojo.provide("dojox.validate.isbn");
+dojox.validate.isValidIsbn=function(_1){
+var _2,_3=0,_4;
+if(!dojo.isString(_1)){
+_1=String(_1);
+}
+_1=_1.replace(/[- ]/g,"");
+_2=_1.length;
+switch(_2){
+case 10:
+_4=_2;
+for(var i=0;i<9;i++){
+_3+=parseInt(_1.charAt(i))*_4;
+_4--;
+}
+var t=_1.charAt(9).toUpperCase();
+_3+=t=="X"?10:parseInt(t);
+return _3%11==0;
+break;
+case 13:
+_4=-1;
+for(var i=0;i<_2;i++){
+_3+=parseInt(_1.charAt(i))*(2+_4);
+_4*=-1;
+}
+return _3%10==0;
+break;
+}
+return false;
+};
+}
diff --git a/dojox/validate/regexp.js b/dojox/validate/regexp.js
new file mode 100644
index 0000000..945bfb3
--- /dev/null
+++ b/dojox/validate/regexp.js
@@ -0,0 +1,164 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.validate.regexp"]){
+dojo._hasResource["dojox.validate.regexp"]=true;
+dojo.provide("dojox.validate.regexp");
+dojo.require("dojo.regexp");
+dojo.mixin(dojox.validate.regexp,{ipAddress:function(_1){
+_1=(typeof _1=="object")?_1:{};
+if(typeof _1.allowDottedDecimal!="boolean"){
+_1.allowDottedDecimal=true;
+}
+if(typeof _1.allowDottedHex!="boolean"){
+_1.allowDottedHex=true;
+}
+if(typeof _1.allowDottedOctal!="boolean"){
+_1.allowDottedOctal=true;
+}
+if(typeof _1.allowDecimal!="boolean"){
+_1.allowDecimal=true;
+}
+if(typeof _1.allowHex!="boolean"){
+_1.allowHex=true;
+}
+if(typeof _1.allowIPv6!="boolean"){
+_1.allowIPv6=true;
+}
+if(typeof _1.allowHybrid!="boolean"){
+_1.allowHybrid=true;
+}
+var _2="((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])";
+var _3="(0[xX]0*[\\da-fA-F]?[\\da-fA-F]\\.){3}0[xX]0*[\\da-fA-F]?[\\da-fA-F]";
+var _4="(0+[0-3][0-7][0-7]\\.){3}0+[0-3][0-7][0-7]";
+var _5="(0|[1-9]\\d{0,8}|[1-3]\\d{9}|4[01]\\d{8}|42[0-8]\\d{7}|429[0-3]\\d{6}|"+"4294[0-8]\\d{5}|42949[0-5]\\d{4}|429496[0-6]\\d{3}|4294967[01]\\d{2}|42949672[0-8]\\d|429496729[0-5])";
+var _6="0[xX]0*[\\da-fA-F]{1,8}";
+var _7="([\\da-fA-F]{1,4}\\:){7}[\\da-fA-F]{1,4}";
+var _8="([\\da-fA-F]{1,4}\\:){6}"+"((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])";
+var a=[];
+if(_1.allowDottedDecimal){
+a.push(_2);
+}
+if(_1.allowDottedHex){
+a.push(_3);
+}
+if(_1.allowDottedOctal){
+a.push(_4);
+}
+if(_1.allowDecimal){
+a.push(_5);
+}
+if(_1.allowHex){
+a.push(_6);
+}
+if(_1.allowIPv6){
+a.push(_7);
+}
+if(_1.allowHybrid){
+a.push(_8);
+}
+var _a="";
+if(a.length>0){
+_a="("+a.join("|")+")";
+}
+return _a;
+},host:function(_b){
+_b=(typeof _b=="object")?_b:{};
+if(typeof _b.allowIP!="boolean"){
+_b.allowIP=true;
+}
+if(typeof _b.allowLocal!="boolean"){
+_b.allowLocal=false;
+}
+if(typeof _b.allowPort!="boolean"){
+_b.allowPort=true;
+}
+if(typeof _b.allowNamed!="boolean"){
+_b.allowNamed=false;
+}
+var _c="(?:[\\da-zA-Z](?:[-\\da-zA-Z]{0,61}[\\da-zA-Z])?)";
+var _d="(?:[a-zA-Z](?:[-\\da-zA-Z]{0,6}[\\da-zA-Z])?)";
+var _e=_b.allowPort?"(\\:\\d+)?":"";
+var _f="((?:"+_c+"\\.)*"+_d+"\\.?)";
+if(_b.allowIP){
+_f+="|"+dojox.validate.regexp.ipAddress(_b);
+}
+if(_b.allowLocal){
+_f+="|localhost";
+}
+if(_b.allowNamed){
+_f+="|^[^-][a-zA-Z0-9_-]*";
+}
+return "("+_f+")"+_e;
+},url:function(_10){
+_10=(typeof _10=="object")?_10:{};
+if(!("scheme" in _10)){
+_10.scheme=[true,false];
+}
+var _11=dojo.regexp.buildGroupRE(_10.scheme,function(q){
+if(q){
+return "(https?|ftps?)\\://";
+}
+return "";
+});
+var _13="(/(?:[^?#\\s/]+/)*(?:[^?#\\s/]+(?:\\?[^?#\\s/]*)?(?:#[A-Za-z][\\w.:-]*)?)?)?";
+return _11+dojox.validate.regexp.host(_10)+_13;
+},emailAddress:function(_14){
+_14=(typeof _14=="object")?_14:{};
+if(typeof _14.allowCruft!="boolean"){
+_14.allowCruft=false;
+}
+_14.allowPort=false;
+var _15="([\\da-zA-Z]+[-._+&'])*[\\da-zA-Z]+";
+var _16=_15+"@"+dojox.validate.regexp.host(_14);
+if(_14.allowCruft){
+_16="<?(mailto\\:)?"+_16+">?";
+}
+return _16;
+},emailAddressList:function(_17){
+_17=(typeof _17=="object")?_17:{};
+if(typeof _17.listSeparator!="string"){
+_17.listSeparator="\\s;,";
+}
+var _18=dojox.validate.regexp.emailAddress(_17);
+var _19="("+_18+"\\s*["+_17.listSeparator+"]\\s*)*"+_18+"\\s*["+_17.listSeparator+"]?\\s*";
+return _19;
+},numberFormat:function(_1a){
+_1a=(typeof _1a=="object")?_1a:{};
+if(typeof _1a.format=="undefined"){
+_1a.format="###-###-####";
+}
+var _1b=function(_1c){
+return dojo.regexp.escapeString(_1c,"?").replace(/\?/g,"\\d?").replace(/#/g,"\\d");
+};
+return dojo.regexp.buildGroupRE(_1a.format,_1b);
+}});
+dojox.validate.regexp.ca={postalCode:function(){
+return "([A-Z][0-9][A-Z] [0-9][A-Z][0-9])";
+},province:function(){
+return "(AB|BC|MB|NB|NL|NS|NT|NU|ON|PE|QC|SK|YT)";
+}};
+dojox.validate.regexp.us={state:function(_1d){
+_1d=(typeof _1d=="object")?_1d:{};
+if(typeof _1d.allowTerritories!="boolean"){
+_1d.allowTerritories=true;
+}
+if(typeof _1d.allowMilitary!="boolean"){
+_1d.allowMilitary=true;
+}
+var _1e="AL|AK|AZ|AR|CA|CO|CT|DE|DC|FL|GA|HI|ID|IL|IN|IA|KS|KY|LA|ME|MD|MA|MI|MN|MS|MO|MT|"+"NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY";
+var _1f="AS|FM|GU|MH|MP|PW|PR|VI";
+var _20="AA|AE|AP";
+if(_1d.allowTerritories){
+_1e+="|"+_1f;
+}
+if(_1d.allowMilitary){
+_1e+="|"+_20;
+}
+return "("+_1e+")";
+}};
+}
diff --git a/dojox/validate/us.js b/dojox/validate/us.js
new file mode 100644
index 0000000..0fb5c79
--- /dev/null
+++ b/dojox/validate/us.js
@@ -0,0 +1,28 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.validate.us"]){
+dojo._hasResource["dojox.validate.us"]=true;
+dojo.provide("dojox.validate.us");
+dojo.require("dojox.validate._base");
+dojox.validate.us.isState=function(_1,_2){
+var re=new RegExp("^"+dojox.validate.regexp.us.state(_2)+"$","i");
+return re.test(_1);
+};
+dojox.validate.us.isPhoneNumber=function(_4){
+var _5={format:["###-###-####","(###) ###-####","(###) ### ####","###.###.####","###/###-####","### ### ####","###-###-#### x#???","(###) ###-#### x#???","(###) ### #### x#???","###.###.#### x#???","###/###-#### x#???","### ### #### x#???","##########"]};
+return dojox.validate.isNumberFormat(_4,_5);
+};
+dojox.validate.us.isSocialSecurityNumber=function(_6){
+var _7={format:["###-##-####","### ## ####","#########"]};
+return dojox.validate.isNumberFormat(_6,_7);
+};
+dojox.validate.us.isZipCode=function(_8){
+var _9={format:["#####-####","##### ####","#########","#####"]};
+return dojox.validate.isNumberFormat(_8,_9);
+};
+}
diff --git a/dojox/validate/web.js b/dojox/validate/web.js
new file mode 100644
index 0000000..d651288
--- /dev/null
+++ b/dojox/validate/web.js
@@ -0,0 +1,40 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.validate.web"]){
+dojo._hasResource["dojox.validate.web"]=true;
+dojo.provide("dojox.validate.web");
+dojo.require("dojox.validate._base");
+dojox.validate.isIpAddress=function(_1,_2){
+var re=new RegExp("^"+dojox.validate.regexp.ipAddress(_2)+"$","i");
+return re.test(_1);
+};
+dojox.validate.isUrl=function(_4,_5){
+var re=new RegExp("^"+dojox.validate.regexp.url(_5)+"$","i");
+return re.test(_4);
+};
+dojox.validate.isEmailAddress=function(_7,_8){
+var re=new RegExp("^"+dojox.validate.regexp.emailAddress(_8)+"$","i");
+return re.test(_7);
+};
+dojox.validate.isEmailAddressList=function(_a,_b){
+var re=new RegExp("^"+dojox.validate.regexp.emailAddressList(_b)+"$","i");
+return re.test(_a);
+};
+dojox.validate.getEmailAddressList=function(_d,_e){
+if(!_e){
+_e={};
+}
+if(!_e.listSeparator){
+_e.listSeparator="\\s;,";
+}
+if(dojox.validate.isEmailAddressList(_d,_e)){
+return _d.split(new RegExp("\\s*["+_e.listSeparator+"]\\s*"));
+}
+return [];
+};
+}
diff --git a/dojox/widget/AnalogGauge.js b/dojox/widget/AnalogGauge.js
new file mode 100644
index 0000000..3fc899c
--- /dev/null
+++ b/dojox/widget/AnalogGauge.js
@@ -0,0 +1,246 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.AnalogGauge"]){
+dojo._hasResource["dojox.widget.AnalogGauge"]=true;
+dojo.provide("dojox.widget.AnalogGauge");
+dojo.require("dojox.gfx");
+dojo.require("dojox.widget.gauge._Gauge");
+dojo.experimental("dojox.widget.AnalogGauge");
+dojo.declare("dojox.widget.gauge.AnalogLineIndicator",[dojox.widget.gauge._Indicator],{_getShapes:function(){
+var _1=[];
+_1[0]=this._gauge.surface.createLine({x1:0,y1:-this.offset,x2:0,y2:-this.length-this.offset}).setStroke({color:this.color,width:this.width});
+return _1;
+},draw:function(_2){
+if(this.shapes){
+this._move(_2);
+}else{
+if(this.text){
+this._gauge.surface.rawNode.removeChild(this.text);
+this.text=null;
+}
+var v=this.value;
+if(v<this._gauge.min){
+v=this._gauge.min;
+}
+if(v>this._gauge.max){
+v=this._gauge.max;
+}
+var a=this._gauge._getAngle(v);
+this.color=this.color||"#000000";
+this.length=this.length||this._gauge.radius;
+this.width=this.width||1;
+this.offset=this.offset||0;
+this.highlight=this.highlight||"#D0D0D0";
+this.shapes=this._getShapes(this._gauge,this);
+if(this.shapes){
+for(var s=0;s<this.shapes.length;s++){
+this.shapes[s].setTransform([{dx:this._gauge.cx,dy:this._gauge.cy},dojox.gfx.matrix.rotateg(a)]);
+if(this.hover){
+this.shapes[s].getEventSource().setAttribute("hover",this.hover);
+}
+if(this.onDragMove&&!this.noChange){
+this._gauge.connect(this.shapes[s].getEventSource(),"onmousedown",this._gauge.handleMouseDown);
+this.shapes[s].getEventSource().style.cursor="pointer";
+}
+}
+}
+if(this.label){
+var _6=this.length+this.offset;
+var x=this._gauge.cx+(_6+5)*Math.sin(this._gauge._getRadians(a));
+var y=this._gauge.cy-(_6+5)*Math.cos(this._gauge._getRadians(a));
+var _9="start";
+if(a<=-10){
+_9="end";
+}
+if(a>-10&&a<10){
+_9="middle";
+}
+var _a="bottom";
+if((a<-90)||(a>90)){
+_a="top";
+}
+this.text=this._gauge.drawText(""+this.label,x,y,_9,_a,this.color,this.font);
+}
+this.currentValue=this.value;
+}
+},_move:function(_b){
+var v=this.value;
+if(v<this._gauge.min){
+v=this._gauge.min;
+}
+if(v>this._gauge.max){
+v=this._gauge.max;
+}
+var c=this.currentValue;
+if(_b){
+var _e=this._gauge._getAngle(v);
+for(var i in this.shapes){
+this.shapes[i].setTransform([{dx:this._gauge.cx,dy:this._gauge.cy},dojox.gfx.matrix.rotateg(_e)]);
+if(this.hover){
+this.shapes[i].getEventSource().setAttribute("hover",this.hover);
+}
+}
+}else{
+if(c!=v){
+var _10=new dojo._Animation({curve:[c,v],duration:this.duration,easing:this.easing});
+dojo.connect(_10,"onAnimate",dojo.hitch(this,function(_11){
+for(var i in this.shapes){
+this.shapes[i].setTransform([{dx:this._gauge.cx,dy:this._gauge.cy},dojox.gfx.matrix.rotateg(this._gauge._getAngle(_11))]);
+if(this.hover){
+this.shapes[i].getEventSource().setAttribute("hover",this.hover);
+}
+}
+this.currentValue=_11;
+}));
+_10.play();
+}
+}
+}});
+dojo.declare("dojox.widget.AnalogGauge",dojox.widget.gauge._Gauge,{startAngle:-90,endAngle:90,cx:0,cy:0,radius:0,_defaultIndicator:dojox.widget.gauge.AnalogLineIndicator,startup:function(){
+if(this.getChildren){
+dojo.forEach(this.getChildren(),function(_13){
+_13.startup();
+});
+}
+this.startAngle=Number(this.startAngle);
+this.endAngle=Number(this.endAngle);
+this.cx=Number(this.cx);
+if(!this.cx){
+this.cx=this.width/2;
+}
+this.cy=Number(this.cy);
+if(!this.cy){
+this.cy=this.height/2;
+}
+this.radius=Number(this.radius);
+if(!this.radius){
+this.radius=Math.min(this.cx,this.cy)-25;
+}
+this._oppositeMiddle=(this.startAngle+this.endAngle)/2+180;
+this.inherited(arguments);
+},_getAngle:function(_14){
+return (_14-this.min)/(this.max-this.min)*(this.endAngle-this.startAngle)+this.startAngle;
+},_getValueForAngle:function(_15){
+if(_15>this._oppositeMiddle){
+_15-=360;
+}
+return (_15-this.startAngle)*(this.max-this.min)/(this.endAngle-this.startAngle)+this.min;
+},_getRadians:function(_16){
+return _16*Math.PI/180;
+},_getDegrees:function(_17){
+return _17*180/Math.PI;
+},draw:function(){
+var i;
+if(this._rangeData){
+for(i=0;i<this._rangeData.length;i++){
+this.drawRange(this._rangeData[i]);
+}
+if(this._img&&this.image.overlay){
+this._img.moveToFront();
+}
+}
+if(this._indicatorData){
+for(i=0;i<this._indicatorData.length;i++){
+this._indicatorData[i].draw();
+}
+}
+},drawRange:function(_19){
+var _1a;
+if(_19.shape){
+this.surface.remove(_19.shape);
+_19.shape=null;
+}
+var a1;
+var a2;
+if((_19.low==this.min)&&(_19.high==this.max)&&((this.endAngle-this.startAngle)==360)){
+_1a=this.surface.createCircle({cx:this.cx,cy:this.cy,r:this.radius});
+}else{
+a1=this._getRadians(this._getAngle(_19.low));
+a2=this._getRadians(this._getAngle(_19.high));
+var x1=this.cx+this.radius*Math.sin(a1);
+var y1=this.cy-this.radius*Math.cos(a1);
+var x2=this.cx+this.radius*Math.sin(a2);
+var y2=this.cy-this.radius*Math.cos(a2);
+var big=0;
+if((a2-a1)>Math.PI){
+big=1;
+}
+_1a=this.surface.createPath();
+if(_19.size){
+_1a.moveTo(this.cx+(this.radius-_19.size)*Math.sin(a1),this.cy-(this.radius-_19.size)*Math.cos(a1));
+}else{
+_1a.moveTo(this.cx,this.cy);
+}
+_1a.lineTo(x1,y1);
+_1a.arcTo(this.radius,this.radius,0,big,1,x2,y2);
+if(_19.size){
+_1a.lineTo(this.cx+(this.radius-_19.size)*Math.sin(a2),this.cy-(this.radius-_19.size)*Math.cos(a2));
+_1a.arcTo((this.radius-_19.size),(this.radius-_19.size),0,big,0,this.cx+(this.radius-_19.size)*Math.sin(a1),this.cy-(this.radius-_19.size)*Math.cos(a1));
+}
+_1a.closePath();
+}
+if(dojo.isArray(_19.color)||dojo.isString(_19.color)){
+_1a.setStroke({color:_19.color});
+_1a.setFill(_19.color);
+}else{
+if(_19.color.type){
+a1=this._getRadians(this._getAngle(_19.low));
+a2=this._getRadians(this._getAngle(_19.high));
+_19.color.x1=this.cx+(this.radius*Math.sin(a1))/2;
+_19.color.x2=this.cx+(this.radius*Math.sin(a2))/2;
+_19.color.y1=this.cy-(this.radius*Math.cos(a1))/2;
+_19.color.y2=this.cy-(this.radius*Math.cos(a2))/2;
+_1a.setFill(_19.color);
+_1a.setStroke({color:_19.color.colors[0].color});
+}else{
+_1a.setStroke({color:"green"});
+_1a.setFill("green");
+_1a.getEventSource().setAttribute("class",_19.color.style);
+}
+}
+if(_19.hover){
+_1a.getEventSource().setAttribute("hover",_19.hover);
+}
+_19.shape=_1a;
+},getRangeUnderMouse:function(_22){
+var _23=null;
+var pos=dojo.coords(this.gaugeContent);
+var x=_22.clientX-pos.x;
+var y=_22.clientY-pos.y;
+var r=Math.sqrt((y-this.cy)*(y-this.cy)+(x-this.cx)*(x-this.cx));
+if(r<this.radius){
+var _28=this._getDegrees(Math.atan2(y-this.cy,x-this.cx)+Math.PI/2);
+var _29=this._getValueForAngle(_28);
+if(this._rangeData){
+for(var i=0;(i<this._rangeData.length)&&!_23;i++){
+if((Number(this._rangeData[i].low)<=_29)&&(Number(this._rangeData[i].high)>=_29)){
+_23=this._rangeData[i];
+}
+}
+}
+}
+return _23;
+},_dragIndicator:function(_2b,_2c){
+var pos=dojo.coords(_2b.gaugeContent);
+var x=_2c.clientX-pos.x;
+var y=_2c.clientY-pos.y;
+var _30=_2b._getDegrees(Math.atan2(y-_2b.cy,x-_2b.cx)+Math.PI/2);
+var _31=_2b._getValueForAngle(_30);
+if(_31<_2b.min){
+_31=_2b.min;
+}
+if(_31>_2b.max){
+_31=_2b.max;
+}
+_2b._drag.value=_31;
+_2b._drag.currentValue=_31;
+_2b._drag.onDragMove(_2b._drag);
+_2b._drag.draw(true);
+dojo.stopEvent(_2c);
+}});
+}
diff --git a/dojox/widget/BarGauge.js b/dojox/widget/BarGauge.js
new file mode 100644
index 0000000..fca0eb6
--- /dev/null
+++ b/dojox/widget/BarGauge.js
@@ -0,0 +1,194 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.BarGauge"]){
+dojo._hasResource["dojox.widget.BarGauge"]=true;
+dojo.provide("dojox.widget.BarGauge");
+dojo.require("dojox.gfx");
+dojo.require("dojox.widget.gauge._Gauge");
+dojo.experimental("dojox.widget.BarGauge");
+dojo.declare("dojox.widget.gauge.BarLineIndicator",[dojox.widget.gauge._Indicator],{width:1,_getShapes:function(){
+if(!this._gauge){
+return null;
+}
+var v=this.value;
+if(v<this._gauge.min){
+v=this._gauge.min;
+}
+if(v>this._gauge.max){
+v=this._gauge.max;
+}
+var _2=this._gauge._getPosition(v);
+var _3=[];
+if(this.width>1){
+_3[0]=this._gauge.surface.createRect({x:_2,y:this._gauge.dataY+this.offset,width:this.width,height:this.length});
+_3[0].setStroke({color:this.color});
+_3[0].setFill(this.color);
+}else{
+_3[0]=this._gauge.surface.createLine({x1:_2,y1:this._gauge.dataY+this.offset,x2:_2,y2:this._gauge.dataY+this.offset+this.length});
+_3[0].setStroke({color:this.color});
+}
+return _3;
+},draw:function(_4){
+var i;
+if(this.shapes){
+this._move(_4);
+}else{
+if(this.shapes){
+for(i=0;i<this.shapes.length;i++){
+this._gauge.surface.remove(this.shapes[i]);
+}
+this.shapes=null;
+}
+if(this.text){
+this._gauge.surface.rawNode.removeChild(this.text);
+this.text=null;
+}
+this.color=this.color||"#000000";
+this.length=this.length||this._gauge.dataHeight;
+this.width=this.width||3;
+this.offset=this.offset||0;
+this.highlight=this.highlight||"#4D4D4D";
+this.highlight2=this.highlight2||"#A3A3A3";
+this.shapes=this._getShapes(this._gauge,this);
+if(this.label){
+var v=this.value;
+if(v<this._gauge.min){
+v=this._gauge.min;
+}
+if(v>this._gauge.max){
+v=this._gauge.max;
+}
+var _7=this._gauge._getPosition(v);
+this.text=this._gauge.drawText(""+this.label,_7,this._gauge.dataY+this.offset-5,"middle","top",this.color,this.font);
+}
+for(i=0;i<this.shapes.length;i++){
+if(this.hover){
+this.shapes[i].getEventSource().setAttribute("hover",this.hover);
+}
+if(this.onDragMove&&!this.noChange){
+this._gauge.connect(this.shapes[i].getEventSource(),"onmousedown",this._gauge.handleMouseDown);
+this.shapes[i].getEventSource().style.cursor="pointer";
+}
+}
+this.currentValue=this.value;
+}
+},_move:function(_8){
+var v=this.value;
+if(v<this.min){
+v=this.min;
+}
+if(v>this.max){
+v=this.max;
+}
+var c=this._gauge._getPosition(this.currentValue);
+this.currentValue=v;
+v=this._gauge._getPosition(v)-this._gauge.dataX;
+if(_8){
+this.shapes[0].applyTransform(dojox.gfx.matrix.translate(v-(this.shapes[0].matrix?this.shapes[0].matrix.dx:0),0));
+}else{
+var _b=new dojo._Animation({curve:[c,v],duration:this.duration,easing:this.easing});
+dojo.connect(_b,"onAnimate",dojo.hitch(this,function(_c){
+this.shapes[0].applyTransform(dojox.gfx.matrix.translate(_c-(this.shapes[0].matrix?this.shapes[0].matrix.dx:0),0));
+}));
+_b.play();
+}
+}});
+dojo.declare("dojox.widget.BarGauge",dojox.widget.gauge._Gauge,{dataX:5,dataY:5,dataWidth:0,dataHeight:0,_defaultIndicator:dojox.widget.gauge.BarLineIndicator,startup:function(){
+if(this.getChildren){
+dojo.forEach(this.getChildren(),function(_d){
+_d.startup();
+});
+}
+if(!this.dataWidth){
+this.dataWidth=this.gaugeWidth-10;
+}
+if(!this.dataHeight){
+this.dataHeight=this.gaugeHeight-10;
+}
+this.inherited(arguments);
+},_getPosition:function(_e){
+return this.dataX+Math.floor((_e-this.min)/(this.max-this.min)*this.dataWidth);
+},_getValueForPosition:function(_f){
+return (_f-this.dataX)*(this.max-this.min)/this.dataWidth+this.min;
+},draw:function(){
+if(!this.surface){
+this.createSurface();
+}
+var i;
+if(this._rangeData){
+for(i=0;i<this._rangeData.length;i++){
+this.drawRange(this._rangeData[i]);
+}
+if(this._img&&this.image.overlay){
+this._img.moveToFront();
+}
+}
+if(this._indicatorData){
+for(i=0;i<this._indicatorData.length;i++){
+this._indicatorData[i].draw();
+}
+}
+},drawRange:function(_11){
+if(_11.shape){
+this.surface.remove(_11.shape);
+_11.shape=null;
+}
+var x1=this._getPosition(_11.low);
+var x2=this._getPosition(_11.high);
+var _14=this.surface.createRect({x:x1,y:this.dataY,width:x2-x1,height:this.dataHeight});
+if(dojo.isArray(_11.color)||dojo.isString(_11.color)){
+_14.setStroke({color:_11.color});
+_14.setFill(_11.color);
+}else{
+if(_11.color.type){
+var y=this.dataY+this.dataHeight/2;
+_11.color.x1=x1;
+_11.color.x2=x2;
+_11.color.y1=y;
+_11.color.y2=y;
+_14.setFill(_11.color);
+_14.setStroke({color:_11.color.colors[0].color});
+}else{
+_14.setStroke({color:"green"});
+_14.setFill("green");
+_14.getEventSource().setAttribute("class",_11.color.style);
+}
+}
+if(_11.hover){
+_14.getEventSource().setAttribute("hover",_11.hover);
+}
+_11.shape=_14;
+},getRangeUnderMouse:function(_16){
+var _17=null;
+var pos=dojo.coords(this.gaugeContent);
+var x=_16.clientX-pos.x;
+var _1a=this._getValueForPosition(x);
+if(this._rangeData){
+for(var i=0;(i<this._rangeData.length)&&!_17;i++){
+if((Number(this._rangeData[i].low)<=_1a)&&(Number(this._rangeData[i].high)>=_1a)){
+_17=this._rangeData[i];
+}
+}
+}
+return _17;
+},_dragIndicator:function(_1c,_1d){
+var pos=dojo.coords(_1c.gaugeContent);
+var x=_1d.clientX-pos.x;
+var _20=_1c._getValueForPosition(x);
+if(_20<_1c.min){
+_20=_1c.min;
+}
+if(_20>_1c.max){
+_20=_1c.max;
+}
+_1c._drag.value=_20;
+_1c._drag.onDragMove(_1c._drag);
+_1c._drag.draw(true);
+dojo.stopEvent(_1d);
+}});
+}
diff --git a/dojox/widget/Calendar.js b/dojox/widget/Calendar.js
new file mode 100644
index 0000000..f2ccb4c
--- /dev/null
+++ b/dojox/widget/Calendar.js
@@ -0,0 +1,485 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.Calendar"]){
+dojo._hasResource["dojox.widget.Calendar"]=true;
+dojo.provide("dojox.widget.Calendar");
+dojo.experimental("dojox.widget.Calendar");
+dojo.require("dijit._Calendar");
+dojo.require("dijit._Container");
+dojo.declare("dojox.widget._CalendarBase",[dijit._Widget,dijit._Templated,dijit._Container],{templateString:"<div class=\"dojoxCalendar\">\n    <div tabindex=\"0\" class=\"dojoxCalendarContainer\" style=\"visibility: visible; width: 180px; heightL 138px;\" dojoAttachPoint=\"container\">\n\t\t<div style=\"display:none\">\n\t\t\t<div dojoAttachPoint=\"previousYearLabelNode\"></div>\n\t\t\t<div dojoAttachPoint=\"nextYearLabelNode\"></div>\n\t\t\t<div dojoAttachPoint=\"monthLabelSpacer\"></d [...]
+this._views=[];
+},postMixInProperties:function(){
+var c=this.constraints;
+if(c){
+var _2=dojo.date.stamp.fromISOString;
+if(typeof c.min=="string"){
+c.min=_2(c.min);
+}
+if(typeof c.max=="string"){
+c.max=_2(c.max);
+}
+}
+},postCreate:function(){
+this._height=dojo.style(this.containerNode,"height");
+this.displayMonth=new Date(this.attr("value"));
+var _3={parent:this,_getValueAttr:dojo.hitch(this,function(){
+return new Date(this.displayMonth);
+}),_getConstraintsAttr:dojo.hitch(this,function(){
+return this.constraints;
+}),getLang:dojo.hitch(this,function(){
+return this.lang;
+}),isDisabledDate:dojo.hitch(this,this.isDisabledDate),getClassForDate:dojo.hitch(this,this.getClassForDate),addFx:this.useFx?dojo.hitch(this,this.addFx):function(){
+}};
+dojo.forEach(this._views,function(_4){
+var _5=new _4(_3,dojo.create("div"));
+this.addChild(_5);
+var _6=_5.getHeader();
+if(_6){
+this.header.appendChild(_6);
+dojo.style(_6,"display","none");
+}
+dojo.style(_5.domNode,"visibility","hidden");
+dojo.connect(_5,"onValueSelected",this,"_onDateSelected");
+_5.attr("value",this.attr("value"));
+},this);
+if(this._views.length<2){
+dojo.style(this.header,"cursor","auto");
+}
+this.inherited(arguments);
+this._children=this.getChildren();
+this._currentChild=0;
+var _7=new Date();
+this.footer.innerHTML="Today: "+dojo.date.locale.format(_7,{formatLength:this.footerFormat,selector:"date",locale:this.lang});
+dojo.connect(this.footer,"onclick",this,"goToToday");
+var _8=this._children[0];
+dojo.style(_8.domNode,"top","0px");
+dojo.style(_8.domNode,"visibility","visible");
+var _9=_8.getHeader();
+if(_9){
+dojo.style(_8.getHeader(),"display","");
+}
+dojo[_8.useHeader?"removeClass":"addClass"](this.container,"no-header");
+_8.onDisplay();
+var _a=this;
+var _b=function(_c,_d,_e){
+dijit.typematic.addMouseListener(_a[_c],_a,function(_f){
+if(_f>=0){
+_a._adjustDisplay(_d,_e);
+}
+},0.8,500);
+};
+_b("incrementMonth","month",1);
+_b("decrementMonth","month",-1);
+this._updateTitleStyle();
+},addFx:function(_10,_11){
+},_setValueAttr:function(_12){
+if(!_12["getFullYear"]){
+_12=dojo.date.stamp.fromISOString(_12+"");
+}
+if(!this.value||dojo.date.compare(_12,this.value)){
+_12=new Date(_12);
+this.displayMonth=new Date(_12);
+if(!this.isDisabledDate(_12,this.lang)){
+this.value=_12;
+this.onChange(_12);
+}
+this._children[this._currentChild].attr("value",this.value);
+return true;
+}
+return false;
+},isDisabledDate:function(_13,_14){
+var c=this.constraints;
+var _16=dojo.date.compare;
+return c&&(c.min&&(_16(c.min,_13,"date")>0)||(c.max&&_16(c.max,_13,"date")<0));
+},onValueSelected:function(_17){
+},_onDateSelected:function(_18,_19,_1a){
+this.displayMonth=_18;
+this.attr("value",_18);
+if(!this._transitionVert(-1)){
+if(!_19&&_19!==0){
+_19=this.attr("value");
+}
+this.onValueSelected(_19);
+}
+},onChange:function(_1b){
+},onHeaderClick:function(e){
+this._transitionVert(1);
+},goToToday:function(){
+this.attr("value",new Date());
+this.onValueSelected(this.attr("value"));
+},_transitionVert:function(_1d){
+var _1e=this._children[this._currentChild];
+var _1f=this._children[this._currentChild+_1d];
+if(!_1f){
+return false;
+}
+dojo.style(_1f.domNode,"visibility","visible");
+var _20=dojo.style(this.containerNode,"height");
+_1f.attr("value",this.displayMonth);
+if(_1e.header){
+dojo.style(_1e.header,"display","none");
+}
+if(_1f.header){
+dojo.style(_1f.header,"display","");
+}
+dojo.style(_1f.domNode,"top",(_20*-1)+"px");
+dojo.style(_1f.domNode,"visibility","visible");
+this._currentChild+=_1d;
+var _21=_20*_1d;
+var _22=0;
+dojo.style(_1f.domNode,"top",(_21*-1)+"px");
+var _23=dojo.animateProperty({node:_1e.domNode,properties:{top:_21},onEnd:function(){
+dojo.style(_1e.domNode,"visibility","hidden");
+}});
+var _24=dojo.animateProperty({node:_1f.domNode,properties:{top:_22},onEnd:function(){
+_1f.onDisplay();
+}});
+dojo[_1f.useHeader?"removeClass":"addClass"](this.container,"no-header");
+_23.play();
+_24.play();
+_1e.onBeforeUnDisplay();
+_1f.onBeforeDisplay();
+this._updateTitleStyle();
+return true;
+},_updateTitleStyle:function(){
+dojo[this._currentChild<this._children.length-1?"addClass":"removeClass"](this.header,"navToPanel");
+},_slideTable:function(_25,_26,_27){
+var _28=_25.domNode;
+var _29=_28.cloneNode(true);
+var _2a=dojo.style(_28,"width");
+_28.parentNode.appendChild(_29);
+dojo.style(_28,"left",(_2a*_26)+"px");
+_27();
+var _2b=dojo.animateProperty({node:_29,properties:{left:_2a*_26*-1},duration:500,onEnd:function(){
+_29.parentNode.removeChild(_29);
+}});
+var _2c=dojo.animateProperty({node:_28,properties:{left:0},duration:500});
+_2b.play();
+_2c.play();
+},_addView:function(_2d){
+this._views.push(_2d);
+},getClassForDate:function(_2e,_2f){
+},_adjustDisplay:function(_30,_31,_32){
+var _33=this._children[this._currentChild];
+var _34=this.displayMonth=_33.adjustDate(this.displayMonth,_31);
+this._slideTable(_33,_31,function(){
+_33.attr("value",_34);
+});
+}});
+dojo.declare("dojox.widget._CalendarView",dijit._Widget,{headerClass:"",useHeader:true,cloneClass:function(_35,n,_37){
+var _38=dojo.query(_35,this.domNode)[0];
+if(!_37){
+for(var i=0;i<n;i++){
+_38.parentNode.appendChild(_38.cloneNode(true));
+}
+}else{
+var _3a=dojo.query(_35,this.domNode)[0];
+for(var i=0;i<n;i++){
+_38.parentNode.insertBefore(_38.cloneNode(true),_3a);
+}
+}
+},_setText:function(_3b,_3c){
+while(_3b.firstChild){
+_3b.removeChild(_3b.firstChild);
+}
+_3b.appendChild(dojo.doc.createTextNode(_3c));
+},getHeader:function(){
+return this.header||(this.header=this.header=dojo.create("span",{"class":this.headerClass}));
+},onValueSelected:function(_3d){
+},adjustDate:function(_3e,_3f){
+return dojo.date.add(_3e,this.datePart,_3f);
+},onDisplay:function(){
+},onBeforeDisplay:function(){
+},onBeforeUnDisplay:function(){
+}});
+dojo.declare("dojox.widget._CalendarDay",null,{parent:null,constructor:function(){
+this._addView(dojox.widget._CalendarDayView);
+}});
+dojo.declare("dojox.widget._CalendarDayView",[dojox.widget._CalendarView,dijit._Templated],{templateString:"<div class=\"dijitCalendarDayLabels\" style=\"left: 0px;\" dojoAttachPoint=\"dayContainer\">\n\t<div dojoAttachPoint=\"header\">\n\t\t<div dojoAttachPoint=\"monthAndYearHeader\">\n\t\t\t<span dojoAttachPoint=\"monthLabelNode\" class=\"dojoxCalendarMonthLabelNode\"></span>\n\t\t\t<span dojoAttachPoint=\"headerComma\" class=\"dojoxCalendarComma\">,</span>\n\t\t\t<span dojoAttachPoint [...]
+this.cloneClass(".dijitCalendarDayLabelTemplate",6);
+this.cloneClass(".dijitCalendarDateTemplate",6);
+this.cloneClass(".dijitCalendarWeekTemplate",5);
+var _40=dojo.date.locale.getNames("days",this.dayWidth,"standAlone",this.getLang());
+var _41=dojo.cldr.supplemental.getFirstDayOfWeek(this.getLang());
+dojo.query(".dijitCalendarDayLabel",this.domNode).forEach(function(_42,i){
+this._setText(_42,_40[(i+_41)%7]);
+},this);
+},onDisplay:function(){
+if(!this._addedFx){
+this._addedFx=true;
+this.addFx(".dijitCalendarDateTemplate div",this.domNode);
+}
+},_onDayClick:function(e){
+var _45=new Date(this.attr("value"));
+var p=e.target.parentNode;
+var c="dijitCalendar";
+var d=dojo.hasClass(p,c+"PreviousMonth")?-1:(dojo.hasClass(p,c+"NextMonth")?1:0);
+if(d){
+_45=dojo.date.add(_45,"month",d);
+}
+_45.setDate(e.target._date);
+if(this.isDisabledDate(_45)){
+dojo.stopEvent(e);
+return;
+}
+this.attr("value",_45);
+this.parent._onDateSelected(_45);
+},_setValueAttr:function(_49){
+this._populateDays();
+},_populateDays:function(){
+var _4a=this.attr("value");
+_4a.setDate(1);
+var _4b=_4a.getDay();
+var _4c=dojo.date.getDaysInMonth(_4a);
+var _4d=dojo.date.getDaysInMonth(dojo.date.add(_4a,"month",-1));
+var _4e=new Date();
+var _4f=this.attr("value");
+var _50=dojo.cldr.supplemental.getFirstDayOfWeek(this.getLang());
+if(_50>_4b){
+_50-=7;
+}
+dojo.query(".dijitCalendarDateTemplate",this.domNode).forEach(function(_51,i){
+i+=_50;
+var _53=new Date(_4a);
+var _54,_55="dijitCalendar",adj=0;
+if(i<_4b){
+_54=_4d-_4b+i+1;
+adj=-1;
+_55+="Previous";
+}else{
+if(i>=(_4b+_4c)){
+_54=i-_4b-_4c+1;
+adj=1;
+_55+="Next";
+}else{
+_54=i-_4b+1;
+_55+="Current";
+}
+}
+if(adj){
+_53=dojo.date.add(_53,"month",adj);
+}
+_53.setDate(_54);
+if(!dojo.date.compare(_53,_4e,"date")){
+_55="dijitCalendarCurrentDate "+_55;
+}
+if(!dojo.date.compare(_53,_4f,"date")){
+_55="dijitCalendarSelectedDate "+_55;
+}
+if(this.isDisabledDate(_53,this.getLang())){
+_55=" dijitCalendarDisabledDate "+_55;
+}
+var _57=this.getClassForDate(_53,this.getLang());
+if(_57){
+_55+=_57+" "+_55;
+}
+_51.className=_55+"Month dijitCalendarDateTemplate";
+_51.dijitDateValue=_53.valueOf();
+var _58=dojo.query(".dijitCalendarDateLabel",_51)[0];
+this._setText(_58,_53.getDate());
+_58._date=_58.parentNode._date=_53.getDate();
+},this);
+var _59=dojo.date.locale.getNames("months","wide","standAlone",this.getLang());
+this._setText(this.monthLabelNode,_59[_4a.getMonth()]);
+this._setText(this.yearLabelNode,_4a.getFullYear());
+}});
+dojo.declare("dojox.widget._CalendarMonthYear",null,{constructor:function(){
+this._addView(dojox.widget._CalendarMonthYearView);
+}});
+dojo.declare("dojox.widget._CalendarMonthYearView",[dojox.widget._CalendarView,dijit._Templated],{templateString:"<div class=\"dojoxCal-MY-labels\" style=\"left: 0px;\"\t\n\tdojoAttachPoint=\"myContainer\" dojoAttachEvent=\"onclick: onClick\">\n\t\t<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" style=\"margin: auto;\">\n\t\t\t\t<tbody>\n\t\t\t\t\t\t<tr class=\"dojoxCal-MY-G-Template\">\n\t\t\t\t\t\t\t\t<td class=\"dojoxCal-MY-M-Template\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"dojox [...]
+this.cloneClass(".dojoxCal-MY-G-Template",5,".dojoxCal-MY-btns");
+this.monthContainer=this.yearContainer=this.myContainer;
+var _5a="dojoxCalendarYearLabel";
+var _5b="dojoxCalendarDecrease";
+var _5c="dojoxCalendarIncrease";
+dojo.query("."+_5a,this.myContainer).forEach(function(_5d,idx){
+var _5f=_5c;
+switch(idx){
+case 0:
+_5f=_5b;
+case 1:
+dojo.removeClass(_5d,_5a);
+dojo.addClass(_5d,_5f);
+break;
+}
+});
+this._decBtn=dojo.query("."+_5b,this.myContainer)[0];
+this._incBtn=dojo.query("."+_5c,this.myContainer)[0];
+dojo.query(".dojoxCal-MY-M-Template",this.domNode).filter(function(_60){
+return _60.cellIndex==1;
+}).addClass("dojoxCal-MY-M-last");
+dojo.connect(this,"onBeforeDisplay",dojo.hitch(this,function(){
+this._cachedDate=new Date(this.attr("value").getTime());
+this._populateYears(this._cachedDate.getFullYear());
+this._populateMonths();
+this._updateSelectedMonth();
+this._updateSelectedYear();
+}));
+dojo.connect(this,"_populateYears",dojo.hitch(this,function(){
+this._updateSelectedYear();
+}));
+dojo.connect(this,"_populateMonths",dojo.hitch(this,function(){
+this._updateSelectedMonth();
+}));
+this._cachedDate=this.attr("value");
+this._populateYears();
+this._populateMonths();
+this.addFx(".dojoxCalendarMonthLabel,.dojoxCalendarYearLabel ",this.myContainer);
+},_setValueAttr:function(_61){
+this._populateYears(_61.getFullYear());
+},getHeader:function(){
+return null;
+},_getMonthNames:function(_62){
+this._monthNames=this._monthNames||dojo.date.locale.getNames("months",_62,"standAlone",this.getLang());
+return this._monthNames;
+},_populateMonths:function(){
+var _63=this._getMonthNames("abbr");
+dojo.query(".dojoxCalendarMonthLabel",this.monthContainer).forEach(dojo.hitch(this,function(_64,cnt){
+this._setText(_64,_63[cnt]);
+}));
+var _66=this.attr("constraints");
+if(_66){
+var _67=new Date();
+_67.setFullYear(this._year);
+var min=-1,max=12;
+if(_66.min){
+var _6a=_66.min.getFullYear();
+if(_6a>this._year){
+min=12;
+}else{
+if(_6a==this._year){
+min=_66.min.getMonth();
+}
+}
+}
+if(_66.max){
+var _6b=_66.max.getFullYear();
+if(_6b<this._year){
+max=-1;
+}else{
+if(_6b==this._year){
+max=_66.max.getMonth();
+}
+}
+}
+dojo.query(".dojoxCalendarMonthLabel",this.monthContainer).forEach(dojo.hitch(this,function(_6c,cnt){
+dojo[(cnt<min||cnt>max)?"addClass":"removeClass"](_6c,"dijitCalendarDisabledDate");
+}));
+}
+var h=this.getHeader();
+if(h){
+this._setText(this.getHeader(),this.attr("value").getFullYear());
+}
+},_populateYears:function(_6f){
+var _70=this.attr("constraints");
+var _71=_6f||this.attr("value").getFullYear();
+var _72=_71-Math.floor(this.displayedYears/2);
+var min=_70&&_70.min?_70.min.getFullYear():_72-10000;
+_72=Math.max(min,_72);
+this._displayedYear=_71;
+var _74=dojo.query(".dojoxCalendarYearLabel",this.yearContainer);
+var max=_70&&_70.max?_70.max.getFullYear()-_72:_74.length;
+var _76="dijitCalendarDisabledDate";
+_74.forEach(dojo.hitch(this,function(_77,cnt){
+if(cnt<=max){
+this._setText(_77,_72+cnt);
+dojo.removeClass(_77,_76);
+}else{
+dojo.addClass(_77,_76);
+}
+}));
+if(this._incBtn){
+dojo[max<_74.length?"addClass":"removeClass"](this._incBtn,_76);
+}
+if(this._decBtn){
+dojo[min>=_72?"addClass":"removeClass"](this._decBtn,_76);
+}
+var h=this.getHeader();
+if(h){
+this._setText(this.getHeader(),_72+" - "+(_72+11));
+}
+},_updateSelectedYear:function(){
+this._year=String((this._cachedDate||this.attr("value")).getFullYear());
+this._updateSelectedNode(".dojoxCalendarYearLabel",dojo.hitch(this,function(_7a,idx){
+return this._year!==null&&_7a.innerHTML==this._year;
+}));
+},_updateSelectedMonth:function(){
+var _7c=(this._cachedDate||this.attr("value")).getMonth();
+this._month=_7c;
+this._updateSelectedNode(".dojoxCalendarMonthLabel",function(_7d,idx){
+return idx==_7c;
+});
+},_updateSelectedNode:function(_7f,_80){
+var sel="dijitCalendarSelectedDate";
+dojo.query(_7f,this.domNode).forEach(function(_82,idx,_84){
+dojo[_80(_82,idx,_84)?"addClass":"removeClass"](_82.parentNode,sel);
+});
+var _85=dojo.query(".dojoxCal-MY-M-Template div",this.myContainer).filter(function(_86){
+return dojo.hasClass(_86.parentNode,sel);
+})[0];
+if(!_85){
+return;
+}
+var _87=dojo.hasClass(_85,"dijitCalendarDisabledDate");
+dojo[_87?"addClass":"removeClass"](this.okBtn,"dijitDisabled");
+},onClick:function(evt){
+var _89;
+var _8a=this;
+var sel="dijitCalendarSelectedDate";
+function hc(c){
+return dojo.hasClass(evt.target,c);
+};
+if(hc("dijitCalendarDisabledDate")){
+dojo.stopEvent(evt);
+return;
+}
+if(hc("dojoxCalendarMonthLabel")){
+_89="dojoxCal-MY-M-Template";
+this._month=evt.target.parentNode.cellIndex+(evt.target.parentNode.parentNode.rowIndex*2);
+this._cachedDate.setMonth(this._month);
+this._updateSelectedMonth();
+}else{
+if(hc("dojoxCalendarYearLabel")){
+_89="dojoxCal-MY-Y-Template";
+this._year=Number(evt.target.innerHTML);
+this._cachedDate.setYear(this._year);
+this._populateMonths();
+this._updateSelectedYear();
+}else{
+if(hc("dojoxCalendarDecrease")){
+this._populateYears(this._displayedYear-10);
+return;
+}else{
+if(hc("dojoxCalendarIncrease")){
+this._populateYears(this._displayedYear+10);
+return;
+}else{
+return true;
+}
+}
+}
+}
+dojo.stopEvent(evt);
+return false;
+},onOk:function(evt){
+dojo.stopEvent(evt);
+if(dojo.hasClass(this.okBtn,"dijitDisabled")){
+return false;
+}
+this.onValueSelected(this._cachedDate);
+return false;
+},onCancel:function(evt){
+dojo.stopEvent(evt);
+this.onValueSelected(this.attr("value"));
+return false;
+}});
+dojo.declare("dojox.widget.Calendar2Pane",[dojox.widget._CalendarBase,dojox.widget._CalendarDay,dojox.widget._CalendarMonthYear],{});
+dojo.declare("dojox.widget.Calendar",[dojox.widget._CalendarBase,dojox.widget._CalendarDay,dojox.widget._CalendarMonthYear],{});
+dojo.declare("dojox.widget.DailyCalendar",[dojox.widget._CalendarBase,dojox.widget._CalendarDay],{});
+dojo.declare("dojox.widget.MonthAndYearlyCalendar",[dojox.widget._CalendarBase,dojox.widget._CalendarMonthYear],{});
+}
diff --git a/dojox/widget/Calendar/Calendar.css b/dojox/widget/Calendar/Calendar.css
new file mode 100644
index 0000000..f31e1bc
--- /dev/null
+++ b/dojox/widget/Calendar/Calendar.css
@@ -0,0 +1,260 @@
+.dojoxCalendar {
+	width: 182px;
+}
+.dojoxCalendarContainer {
+	cursor: default;
+	font-family: tahoma, verdana, helvetica;
+	font-size: 11px;
+	padding: 0px;
+	text-align: center;
+	width: 180px;
+	overflow: hidden;
+}
+.dojoxCalendarBody {
+	height: 138px;
+	overflow: hidden;
+	position: relative;
+	margin: auto;
+	width: 180px;
+}
+.dojoxCalendar .no-header .dojoxCalendarBody {
+	height: 162px;
+}
+.dojoxCalendar .dijitCalendarDayLabels, .dojoxCalendarMonthLabels, .dojoxCalendarYearLabels, .dojoxCal-MY-labels {
+	width: 180px;
+	height: 138px;
+	top: 0px;
+	position: absolute;
+	left: 0px;
+	margin: auto;
+	text-align: center;
+}
+.dojoxCalendar .dojoxCalendarBody > div {
+	width: 180px;
+}
+.dojoxCalendar .dijitCalendarDateTemplate {
+	padding: 0 1px 0 0 !important;
+}
+.nihilo .dojoxCalendar .dijitCalendarDateTemplate,
+.soria .dojoxCalendar .dijitCalendarDateTemplate {
+	border: 0px none !important; 
+}
+.soria tr.dojoxCal-MY-btns {
+	background:   url(../../../dijit/themes/soria/images/tabBottomHoverC.gif) repeat-x scroll 0px -21px;
+}
+.dojoxCalendar .noPointer, .dojoxCalendar .noPointer * {
+	cursor: auto;
+}
+.dojoxCalendarContainer table {
+	font-size: 11px;
+	border-bottom: 4px solid white;
+}
+.dojoxCalendarHeader {
+	height: 20px;
+	width: 172px;
+	padding: 4px 4px 0;
+}
+.dojoxCalendar .no-header .dojoxCalendarHeader {
+	display: none;
+}
+.soria .dojoxCalendarHeader {
+	background: #BED7F0 url(../../../dijit/themes/soria/images/titleBar.png) repeat-x scroll center top;
+}
+.dojoxCalendarDecrease, .dojoxCalendarIncrease {
+	height: 15px;
+	width: 15px;
+	cursor: pointer;
+}
+.dojoxCalendarDecrease {
+	background: transparent url(../../../dijit/themes/nihilo/images/spriteRoundedIconsSmall.png) no-repeat scroll left top;
+	float: left;
+}
+.dojoxCalendarIncrease {
+	background: transparent url(../../../dijit/themes/nihilo/images/spriteRoundedIconsSmall.png) no-repeat scroll -30px top;
+	float: right;
+}
+.dojoxCalendarMonthLabel {
+	cursor: pointer;
+	height: 35px;
+	width: 41px;
+	overflow: hidden;
+	text-align: center;
+	padding-top: 10px;
+}
+.dojoxCalendarYearLabel {
+	cursor: pointer;
+	height: 35px;
+	width: 41px;
+	overflow: hidden;
+	text-align: center;
+	padding-top: 10px;
+}
+.dojoxCalendarTitle {
+	cursor: pointer;
+	font-weight: bold;
+}
+.dojoxCalendar .navToPanel .dojoxCalendarDayYearLabel,
+.dojoxCalendar .navToPanel .dojoxCalendarYearHeader,
+.dojoxCalendar .navToPanel .dojoxCalendarMonthHeader  {
+	padding-right: 15px;
+	background: url(../../../dijit/themes/tundra/images/comboArrowDown.gif) right no-repeat;
+}
+.dojoxCalendar .dijitCalendarDateLabel {
+	height: 17px;
+	width: 17px;
+	padding: 1px 3px 0px 3px;
+	text-align: center;
+	border: 1px solid white;
+}
+.dojoxCalendar .dijitCalendarDayLabel {
+	cursor: pointer;
+	height: 17px;
+	width: 18px;
+	padding: 0pt 2px;
+	text-align: center;
+}
+.dojoxCalendar .dojoxCalendarContainer {
+	background-color: white;
+	border: 1px solid #656565;
+	color: black;
+}
+.dojoxCalendar .dijitCalendarDisabledDate {
+	text-decoration:line-through !important;
+	cursor:default !important;
+}
+.dojoxCalendar .dojoxCalendarFooter {
+	border-top: 1px solid #F4F4F4;
+	height: 15px;
+	padding-top: 4px;
+	cursor: pointer;
+}
+.soria .dojoxCalendar .dojoxCalendarFooter {
+	border-top: 0px none;
+	padding-top: 5px;
+	background: white url(../../../dijit/themes/soria/images/titleBar.png) repeat-x scroll center top
+}
+.dojoxCalendar .dojoxCalendarMonthLabel {
+	border: 1px solid white;
+}
+.dojoxCalendar .dojoxCalendarYearLabel {
+	border: 1px solid white;
+}
+.dojoxCalendar .dijitCalendarNextMonth .dijitCalendarDateLabel,
+.dojoxCalendar .dijitCalendarPreviousMonth .dijitCalendarDateLabel  {
+	border: 0px;
+  color: #646464;
+	padding-left: 0px;
+	padding-right: 0px;
+}
+.dojoxCalendar .dijitCalendarNextMonth, .dojoxCalendar .dijitCalendarPreviousMonth {
+  background-color: #E4E4E4;
+}
+.dojoxCalendar .dijitCalendarNextMonth .dojoxCalendarYearLabel,
+.dojoxCalendar .dijitCalendarPreviousMonth .dojoxCalendarYearLabel {
+	background-color: white;
+	border-color: white;
+	color: #646464;
+}
+.dojoxCalendar .dijitCalendarSelectedDate,
+.tundra .dojoxCalendar .dijitCalendarSelectedDate,
+.nihilo .dojoxCalendar .dijitCalendarSelectedDate {
+	
+	background-color:#ffe284 !important;
+	color:black !important;
+	border:#f5b93c solid 1px !important;
+}
+.soria .dojoxCalendar td.dijitCalendarSelectedDate {
+	background-color: #B9CBF1 !important;
+	color: black !important;
+	border: 1px solid #4B5AAA !important;
+}
+.soria .dojoxCalendar .dijitCalendarSelectedDate div {
+	
+	background-color: #B9CBF1 !important;
+	border: none  !important;
+}
+.dojoxCalendar .dijitCalendarSelectedDate div {
+	
+	background-color: #FFE284 !important;
+	border: none  !important;
+}
+div.dojoxCalendar tr.dojoxCal-MY-G-Template td.dijitCalendarSelectedDate {
+	background-color: transparent;
+	width: 43px;
+}
+.dojoxCalendar tr.dojoxCal-MY-G-Template td {
+	width: 45px;
+}
+.dojoxCalendar .dijitCalendarSelectedDate div.dijitCalendarDateLabel {
+	padding: 1px 1px 0px 3px;
+}
+.dojoxCalendar .monthOnly .dijitCalendarDayLabels,
+.dojoxCalendar .yearOnly .dijitCalendarDayLabels,
+.dojoxCalendar .monthOnly .dojoxCalendarComma,
+.dojoxCalendar .yearOnly .dojoxCalendarComma,
+.dojoxCalendar .monthOnly .dojoxCalendarFooter,
+.dojoxCalendar .yearOnly .dojoxCalendarFooter,
+.dojoxCalendar .monthOnly .dojoxCalendarYearHeader,
+.dojoxCalendar .monthOnly .dojoxCalendarIncrease,
+.dojoxCalendar .monthOnly .dojoxCalendarDecrease,
+.dojoxCalendar .yearOnly .dojoxCalendarMonthLabelNode {
+	display: none;
+}
+.dojoxCal-MY-labels .dojoxCalendarMonthLabel,
+.dojoxCal-MY-labels .dojoxCalendarYearLabel {
+	height: 13px;
+	padding-top: 4px;
+	padding-bottom: 3px;
+}
+.dojoxCal-MY-labels td.dojoxCal-MY-btns {
+	padding-top: 2px;
+	border-top: 1px solid grey;
+	text-align: center;
+}
+.dojoxCal-MY-labels {
+	background-color: white;
+}
+.dojoxCal-MY-labels .dojoxCalendarIncrease,
+.dojoxCal-MY-labels .dojoxCalendarDecrease {
+	float: none;
+	margin-left: 14px;
+}
+.dojoxCal-MY-btns button {
+	font-size: 8pt;
+}
+.dojoxCalendar .dojoxCal-MY-btns .dijitDisabled button {
+	color: #999;
+}
+.dojoxCal-hidden {
+	visibility: hidden;
+}
+.dojoxCalendar .dojoxCal-MY-labels {
+	height: 164px;
+}
+.dojoxCalendar .dojoxCal-MY-labels .dijitCalendarSelectedDate div {
+	padding-top: 3px;
+	padding-bottom: 2px;
+}
+.soria .dojoxCal-MY-labels .dijitCalendarSelectedDate div {
+	padding-top: 4px;
+	padding-bottom: 3px;
+}
+.dojoxCal-MY-labels .dojoxCalendarMonthLabel {
+	width: 38px;
+}
+.dojoxCal-MY-labels .dojoxCal-MY-M-last {
+	border-right: 1px grey solid;
+}
+.soria .dojoxCal-MY-labels .dojoxCal-MY-M-last {
+	border-right: 1px #B9CBF1 solid;
+} 
+.dojoxCal-MY-labels .dojoxCal-MY-M-last .dojoxCalendarMonthLabel,
+.dojoxCal-MY-labels .dojoxCal-MY-G-Template div.dojoxCalendarYearLabel {
+	width: 42px;
+}
+.dojoxCalendar .cancel-btn {
+	margin-left: 11px;
+}
+.dojoxCalendar .ok-btn {
+	margin-left: 15px;
+}
diff --git a/dojox/widget/Calendar/Calendar.html b/dojox/widget/Calendar/Calendar.html
new file mode 100644
index 0000000..a5ea6c0
--- /dev/null
+++ b/dojox/widget/Calendar/Calendar.html
@@ -0,0 +1,24 @@
+<div class="dojoxCalendar">
+    <div tabindex="0" class="dojoxCalendarContainer" style="visibility: visible; width: 180px; heightL 138px;" dojoAttachPoint="container">
+		<div style="display:none">
+			<div dojoAttachPoint="previousYearLabelNode"></div>
+			<div dojoAttachPoint="nextYearLabelNode"></div>
+			<div dojoAttachPoint="monthLabelSpacer"></div>
+		</div>
+        <div class="dojoxCalendarHeader">
+            <div>
+                <div class="dojoxCalendarDecrease" dojoAttachPoint="decrementMonth"></div>
+            </div>
+            <div class="">
+                <div class="dojoxCalendarIncrease" dojoAttachPoint="incrementMonth"></div>
+            </div>
+            <div class="dojoxCalendarTitle" dojoAttachPoint="header" dojoAttachEvent="onclick: onHeaderClick">
+            </div>
+        </div>
+        <div class="dojoxCalendarBody" dojoAttachPoint="containerNode"></div>
+        <div class="">
+            <div class="dojoxCalendarFooter" dojoAttachPoint="footer">                        
+            </div>
+        </div>
+    </div>
+</div>
diff --git a/dojox/widget/Calendar/CalendarDay.html b/dojox/widget/Calendar/CalendarDay.html
new file mode 100644
index 0000000..1180d6f
--- /dev/null
+++ b/dojox/widget/Calendar/CalendarDay.html
@@ -0,0 +1,23 @@
+<div class="dijitCalendarDayLabels" style="left: 0px;" dojoAttachPoint="dayContainer">
+	<div dojoAttachPoint="header">
+		<div dojoAttachPoint="monthAndYearHeader">
+			<span dojoAttachPoint="monthLabelNode" class="dojoxCalendarMonthLabelNode"></span>
+			<span dojoAttachPoint="headerComma" class="dojoxCalendarComma">,</span>
+			<span dojoAttachPoint="yearLabelNode" class="dojoxCalendarDayYearLabel"></span>
+		</div>
+	</div>
+	<table cellspacing="0" cellpadding="0" border="0" style="margin: auto;">
+		<thead>
+			<tr>
+				<td class="dijitCalendarDayLabelTemplate"><div class="dijitCalendarDayLabel"></div></td>
+			</tr>
+		</thead>
+		<tbody dojoAttachEvent="onclick: _onDayClick">
+			<tr class="dijitCalendarWeekTemplate">
+				<td class="dojoxCalendarNextMonth dijitCalendarDateTemplate">
+					<div class="dijitCalendarDateLabel"></div>
+				</td>
+			</tr>
+		</tbody>
+	</table>
+</div>
diff --git a/dojox/widget/Calendar/CalendarMonth.html b/dojox/widget/Calendar/CalendarMonth.html
new file mode 100644
index 0000000..f0bc3e8
--- /dev/null
+++ b/dojox/widget/Calendar/CalendarMonth.html
@@ -0,0 +1,12 @@
+<div class="dojoxCalendarMonthLabels" style="left: 0px;"  
+	dojoAttachPoint="monthContainer" dojoAttachEvent="onclick: onClick">
+    <table cellspacing="0" cellpadding="0" border="0" style="margin: auto;">
+        <tbody>
+            <tr class="dojoxCalendarMonthGroupTemplate">
+                <td class="dojoxCalendarMonthTemplate">
+                    <div class="dojoxCalendarMonthLabel"></div>
+                </td>
+             </tr>
+        </tbody>
+    </table>
+</div>
diff --git a/dojox/widget/Calendar/CalendarMonthYear.html b/dojox/widget/Calendar/CalendarMonthYear.html
new file mode 100644
index 0000000..f87a09d
--- /dev/null
+++ b/dojox/widget/Calendar/CalendarMonthYear.html
@@ -0,0 +1,31 @@
+<div class="dojoxCal-MY-labels" style="left: 0px;"	
+	dojoAttachPoint="myContainer" dojoAttachEvent="onclick: onClick">
+		<table cellspacing="0" cellpadding="0" border="0" style="margin: auto;">
+				<tbody>
+						<tr class="dojoxCal-MY-G-Template">
+								<td class="dojoxCal-MY-M-Template">
+										<div class="dojoxCalendarMonthLabel"></div>
+								</td>
+								<td class="dojoxCal-MY-M-Template">
+										<div class="dojoxCalendarMonthLabel"></div>
+								</td>
+								<td class="dojoxCal-MY-Y-Template">
+										<div class="dojoxCalendarYearLabel"></div>
+								</td>
+								<td class="dojoxCal-MY-Y-Template">
+										<div class="dojoxCalendarYearLabel"></div>
+								</td>
+						 </tr>
+						 <tr class="dojoxCal-MY-btns">
+						 	 <td class="dojoxCal-MY-btns" colspan="4">
+						 		 <span class="dijitReset dijitInline dijitButtonNode ok-btn" dojoAttachEvent="onclick: onOk" dojoAttachPoint="okBtn">
+						 	 	 	 <button	class="dijitReset dijitStretch dijitButtonContents">OK</button>
+								 </span>
+								 <span class="dijitReset dijitInline dijitButtonNode cancel-btn" dojoAttachEvent="onclick: onCancel" dojoAttachPoint="cancelBtn">
+						 	 		 <button	class="dijitReset dijitStretch dijitButtonContents">Cancel</button>
+								 </span>
+						 	 </td>
+						 </tr>
+				</tbody>
+		</table>
+</div>
diff --git a/dojox/widget/Calendar/CalendarYear.html b/dojox/widget/Calendar/CalendarYear.html
new file mode 100644
index 0000000..08ca429
--- /dev/null
+++ b/dojox/widget/Calendar/CalendarYear.html
@@ -0,0 +1,12 @@
+<div class="dojoxCalendarYearLabels" style="left: 0px;" dojoAttachPoint="yearContainer">
+    <table cellspacing="0" cellpadding="0" border="0" style="margin: auto;" dojoAttachEvent="onclick: onClick">
+        <tbody>
+            <tr class="dojoxCalendarYearGroupTemplate">
+                <td class="dojoxCalendarNextMonth dojoxCalendarYearTemplate">
+                    <div class="dojoxCalendarYearLabel">
+                    </div>
+                </td>
+            </tr>
+        </tbody>
+    </table>
+</div>
diff --git a/dojox/widget/CalendarFx.js b/dojox/widget/CalendarFx.js
new file mode 100644
index 0000000..3814ba7
--- /dev/null
+++ b/dojox/widget/CalendarFx.js
@@ -0,0 +1,18 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.CalendarFx"]){
+dojo._hasResource["dojox.widget.CalendarFx"]=true;
+dojo.provide("dojox.widget.CalendarFx");
+dojo.require("dojox.widget.FisheyeLite");
+dojo.declare("dojox.widget._FisheyeFX",null,{addFx:function(_1,_2){
+dojo.query(_1,_2).forEach(function(_3){
+new dojox.widget.FisheyeLite({properties:{fontSize:1.1}},_3);
+});
+}});
+dojo.declare("dojox.widget.CalendarFisheye",[dojox.widget.Calendar,dojox.widget._FisheyeFX],{});
+}
diff --git a/dojox/widget/CalendarViews.js b/dojox/widget/CalendarViews.js
new file mode 100644
index 0000000..0dc8778
--- /dev/null
+++ b/dojox/widget/CalendarViews.js
@@ -0,0 +1,59 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.CalendarViews"]){
+dojo._hasResource["dojox.widget.CalendarViews"]=true;
+dojo.provide("dojox.widget.CalendarViews");
+dojo.experimental("dojox.widget.CalendarViews");
+dojo.require("dojox.widget.Calendar");
+dojo.declare("dojox.widget._CalendarMonth",null,{constructor:function(){
+this._addView(dojox.widget._CalendarMonthView);
+}});
+dojo.declare("dojox.widget._CalendarMonthView",[dojox.widget._CalendarView,dijit._Templated],{templateString:"<div class=\"dojoxCalendarMonthLabels\" style=\"left: 0px;\"  \n\tdojoAttachPoint=\"monthContainer\" dojoAttachEvent=\"onclick: onClick\">\n    <table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" style=\"margin: auto;\">\n        <tbody>\n            <tr class=\"dojoxCalendarMonthGroupTemplate\">\n                <td class=\"dojoxCalendarMonthTemplate\">\n                     [...]
+this.cloneClass(".dojoxCalendarMonthTemplate",3);
+this.cloneClass(".dojoxCalendarMonthGroupTemplate",2);
+this._populateMonths();
+this.addFx(".dojoxCalendarMonthLabel",this.domNode);
+},_setValueAttr:function(_1){
+
+this.header.innerHTML=_1.getFullYear();
+},_getMonthNames:dojox.widget._CalendarMonthYearView.prototype._getMonthNames,_populateMonths:dojox.widget._CalendarMonthYearView.prototype._populateMonths,onClick:function(_2){
+if(!dojo.hasClass(_2.target,"dojoxCalendarMonthLabel")){
+dojo.stopEvent(_2);
+return;
+}
+var _3=_2.target.parentNode.cellIndex+(_2.target.parentNode.parentNode.rowIndex*4);
+var _4=this.attr("value");
+_4.setMonth(_3);
+this.onValueSelected(_4,_3);
+}});
+dojo.declare("dojox.widget._CalendarYear",null,{parent:null,constructor:function(){
+this._addView(dojox.widget._CalendarYearView);
+}});
+dojo.declare("dojox.widget._CalendarYearView",[dojox.widget._CalendarView,dijit._Templated],{templateString:"<div class=\"dojoxCalendarYearLabels\" style=\"left: 0px;\" dojoAttachPoint=\"yearContainer\">\n    <table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" style=\"margin: auto;\" dojoAttachEvent=\"onclick: onClick\">\n        <tbody>\n            <tr class=\"dojoxCalendarYearGroupTemplate\">\n                <td class=\"dojoxCalendarNextMonth dojoxCalendarYearTemplate\">\n        [...]
+this.cloneClass(".dojoxCalendarYearTemplate",3);
+this.cloneClass(".dojoxCalendarYearGroupTemplate",2);
+this._populateYears();
+this.addFx(".dojoxCalendarYearLabel",this.domNode);
+},_setValueAttr:function(_5){
+this._populateYears(_5.getFullYear());
+},_populateYears:dojox.widget._CalendarMonthYearView.prototype._populateYears,adjustDate:function(_6,_7){
+return dojo.date.add(_6,"year",_7*12);
+},onClick:function(_8){
+if(!dojo.hasClass(_8.target,"dojoxCalendarYearLabel")){
+dojo.stopEvent(_8);
+return;
+}
+var _9=Number(_8.target.innerHTML);
+var _a=this.attr("value");
+_a.setYear(_9);
+this.onValueSelected(_a,_9);
+}});
+dojo.declare("dojox.widget.Calendar3Pane",[dojox.widget._CalendarBase,dojox.widget._CalendarDay,dojox.widget._CalendarMonth,dojox.widget._CalendarYear],{});
+dojo.declare("dojox.widget.MonthlyCalendar",[dojox.widget._CalendarBase,dojox.widget._CalendarMonth],{});
+dojo.declare("dojox.widget.YearlyCalendar",[dojox.widget._CalendarBase,dojox.widget._CalendarYear],{});
+}
diff --git a/dojox/widget/ColorPicker.js b/dojox/widget/ColorPicker.js
new file mode 100644
index 0000000..07dc1b0
--- /dev/null
+++ b/dojox/widget/ColorPicker.js
@@ -0,0 +1,168 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.ColorPicker"]){
+dojo._hasResource["dojox.widget.ColorPicker"]=true;
+dojo.provide("dojox.widget.ColorPicker");
+dojo.experimental("dojox.widget.ColorPicker");
+dojo.require("dijit.form._FormWidget");
+dojo.require("dojo.dnd.move");
+dojo.require("dojo.fx");
+dojo.require("dojox.color");
+(function(d){
+var _2=function(_3){
+return _3;
+};
+dojo.declare("dojox.widget.ColorPicker",dijit.form._FormWidget,{showRgb:true,showHsv:true,showHex:true,webSafe:true,animatePoint:true,slideDuration:250,liveUpdate:false,PICKER_HUE_H:150,PICKER_SAT_VAL_H:150,PICKER_SAT_VAL_W:150,value:"#ffffff",_underlay:d.moduleUrl("dojox.widget","ColorPicker/images/underlay.png"),templateString:"<div class=\"dojoxColorPicker\" dojoAttachEvent=\"onkeypress: _handleKey\">\n\t<div class=\"dojoxColorPickerBox\">\n\t\t<div dojoAttachPoint=\"cursorNode\" tabI [...]
+this.inherited(arguments);
+if(d.isIE<7){
+this.colorUnderlay.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this._underlay+"', sizingMethod='scale')";
+this.colorUnderlay.src=this._blankGif.toString();
+}
+if(!this.showRgb){
+this.rgbNode.style.display="none";
+}
+if(!this.showHsv){
+this.hsvNode.style.display="none";
+}
+if(!this.showHex){
+this.hexNode.style.display="none";
+}
+if(!this.webSafe){
+this.safePreviewNode.style.visibility="hidden";
+}
+this._offset=0;
+var _4=d.marginBox(this.cursorNode);
+var _5=d.marginBox(this.hueCursorNode);
+this._shift={hue:{x:Math.round(_5.w/2)-1,y:Math.round(_5.h/2)-1},picker:{x:Math.floor(_4.w/2),y:Math.floor(_4.h/2)}};
+this.PICKER_HUE_H=d.coords(this.hueNode).h;
+var cu=d.coords(this.colorUnderlay);
+this.PICKER_SAT_VAL_H=cu.h;
+this.PICKER_SAT_VAL_W=cu.w;
+var ox=this._shift.picker.x;
+var oy=this._shift.picker.y;
+this._mover=new d.dnd.move.boxConstrainedMoveable(this.cursorNode,{box:{t:0-oy,l:0-ox,w:this.PICKER_SAT_VAL_W,h:this.PICKER_SAT_VAL_H}});
+this._hueMover=new d.dnd.move.boxConstrainedMoveable(this.hueCursorNode,{box:{t:0-this._shift.hue.y,l:0,w:0,h:this.PICKER_HUE_H}});
+d.subscribe("/dnd/move/stop",d.hitch(this,"_clearTimer"));
+d.subscribe("/dnd/move/start",d.hitch(this,"_setTimer"));
+},startup:function(){
+this._started=true;
+this.attr("value",this.value);
+},_setValueAttr:function(_9){
+if(!this._started){
+return;
+}
+this.setColor(_9,true);
+},setColor:function(_a,_b){
+var _c=dojox.color.fromString(_a);
+this._updatePickerLocations(_c);
+this._updateColorInputs(_c);
+this._updateValue(_c,_b);
+},_setTimer:function(_d){
+dijit.focus(_d.node);
+d.setSelectable(this.domNode,false);
+this._timer=setInterval(d.hitch(this,"_updateColor"),45);
+},_clearTimer:function(_e){
+clearInterval(this._timer);
+this._timer=null;
+this.onChange(this.value);
+d.setSelectable(this.domNode,true);
+},_setHue:function(h){
+d.style(this.colorUnderlay,"backgroundColor",dojox.color.fromHsv(h,100,100).toHex());
+},_updateColor:function(){
+var _10=d.style(this.hueCursorNode,"top")+this._shift.hue.y,_11=d.style(this.cursorNode,"top")+this._shift.picker.y,_12=d.style(this.cursorNode,"left")+this._shift.picker.x,h=Math.round(360-(_10/this.PICKER_HUE_H*360)),col=dojox.color.fromHsv(h,_12/this.PICKER_SAT_VAL_W*100,100-(_11/this.PICKER_SAT_VAL_H*100));
+this._updateColorInputs(col);
+this._updateValue(col,true);
+if(h!=this._hue){
+this._setHue(h);
+}
+},_colorInputChange:function(e){
+var col,_17=false;
+switch(e.target){
+case this.hexCode:
+col=dojox.color.fromString(e.target.value);
+_17=true;
+break;
+case this.Rval:
+case this.Gval:
+case this.Bval:
+col=dojox.color.fromArray([this.Rval.value,this.Gval.value,this.Bval.value]);
+_17=true;
+break;
+case this.Hval:
+case this.Sval:
+case this.Vval:
+col=dojox.color.fromHsv(this.Hval.value,this.Sval.value,this.Vval.value);
+_17=true;
+break;
+}
+if(_17){
+this._updatePickerLocations(col);
+this._updateColorInputs(col);
+this._updateValue(col,true);
+}
+},_updateValue:function(col,_19){
+var hex=col.toHex();
+this.value=this.valueNode.value=hex;
+if(_19&&(!this._timer||this.liveUpdate)){
+this.onChange(hex);
+}
+},_updatePickerLocations:function(col){
+var hsv=col.toHsv(),_1d=Math.round(this.PICKER_HUE_H-hsv.h/360*this.PICKER_HUE_H-this._shift.hue.y),_1e=Math.round(hsv.s/100*this.PICKER_SAT_VAL_W-this._shift.picker.x),_1f=Math.round(this.PICKER_SAT_VAL_H-hsv.v/100*this.PICKER_SAT_VAL_H-this._shift.picker.y);
+if(this.animatePoint){
+d.fx.slideTo({node:this.hueCursorNode,duration:this.slideDuration,top:_1d,left:0}).play();
+d.fx.slideTo({node:this.cursorNode,duration:this.slideDuration,top:_1f,left:_1e}).play();
+}else{
+d.style(this.hueCursorNode,"top",_1d+"px");
+d.style(this.cursorNode,{left:_1e+"px",top:_1f+"px"});
+}
+if(hsv.h!=this._hue){
+this._setHue(hsv.h);
+}
+},_updateColorInputs:function(col){
+var hex=col.toHex();
+if(this.showRgb){
+this.Rval.value=col.r;
+this.Gval.value=col.g;
+this.Bval.value=col.b;
+}
+if(this.showHsv){
+var hsv=col.toHsv();
+this.Hval.value=Math.round((hsv.h));
+this.Sval.value=Math.round(hsv.s);
+this.Vval.value=Math.round(hsv.v);
+}
+if(this.showHex){
+this.hexCode.value=hex;
+}
+this.previewNode.style.backgroundColor=hex;
+if(this.webSafe){
+this.safePreviewNode.style.backgroundColor=_2(hex);
+}
+},_setHuePoint:function(evt){
+var _24=evt.layerY-this._shift.hue.y;
+if(this.animatePoint){
+d.fx.slideTo({node:this.hueCursorNode,duration:this.slideDuration,top:_24,left:0,onEnd:d.hitch(this,"_updateColor",true)}).play();
+}else{
+d.style(this.hueCursorNode,"top",_24+"px");
+this._updateColor(false);
+}
+},_setPoint:function(evt){
+var _26=evt.layerY-this._shift.picker.y,_27=evt.layerX-this._shift.picker.x;
+if(evt){
+dijit.focus(evt.target);
+}
+if(this.animatePoint){
+d.fx.slideTo({node:this.cursorNode,duration:this.slideDuration,top:_26,left:_27,onEnd:d.hitch(this,"_updateColor",true)}).play();
+}else{
+d.style(this.cursorNode,{left:_27+"px",top:_26+"px"});
+this._updateColor(false);
+}
+},_handleKey:function(e){
+}});
+})(dojo);
+}
diff --git a/dojox/widget/ColorPicker/ColorPicker.css b/dojox/widget/ColorPicker/ColorPicker.css
new file mode 100644
index 0000000..56aa4c9
--- /dev/null
+++ b/dojox/widget/ColorPicker/ColorPicker.css
@@ -0,0 +1,93 @@
+.dojoxColorPicker {
+	padding:8px;
+	width:300px;
+	height:150px; 
+	-moz-border-radius:4pt;
+	-webkit-border-radius:5pt;
+	-webkit-drop-shadow:3pt;
+}
+.tundra .dojoxColorPicker {
+	background:#ededed;
+	border:1px solid #ccc;
+}
+.dojoxColorPickerBox {
+	position:relative;
+	width:150px;	
+	height:150px;	
+	margin:0; 
+	padding:0;
+}
+.dojoxColorPickerUnderlay {
+	position:absolute; 
+	top:0; left:0;
+	width:150px; 
+	height:150px;
+	z-index:1;
+}
+.tundra .dojoxColorPickerUnderlay {
+	border:1px solid #a0a0a0;
+}
+.dojoxHuePickerUnderlay {
+	background:url(images/hue.png) no-repeat top center; 
+	position:absolute;
+	top:0; left:0;
+	height:150px;
+	width:20px;
+	z-index:1;
+}
+.dojoxHuePicker { position:relative; top:-150px; left:157px; }
+.dojoxHuePickerPoint {
+	position:absolute;
+	top:0; left:0;
+	width:20px;
+	height:8px;
+	z-index:3; 
+	background-color:#666; 
+	cursor:move;
+	background:url(images/hueHandle.png) no-repeat center center; 
+}
+.dojoxColorPickerPoint {
+	position:absolute;
+	width:10px; 
+	height:10px;
+	background: url(images/pickerPointer.png) no-repeat center center; 
+	border:0;
+	z-index:3; 
+	cursor:move; 
+}
+.dojoxColorPickerPreview {
+	display:block;	
+	width:45px;	
+	height:45px;
+	border:1px solid #333;
+	background-color:#fff; 
+	position:relative;
+	top:-150px;
+	left: 185px; 
+}
+.dojoxColorPickerWebSafePreview {
+	display:block;
+	width:25px; 
+	height:25px; 
+	position:relative;
+	top:-197px;
+	left:240px; 
+	border:1px solid #333; 
+}
+.dojoxColorPickerOptional {
+	position:relative;
+	top:-170px;
+	left:185px;
+}
+.dojoxColorPickerOptional input {
+	border:1px solid #a7a7a7;
+	width:25px;
+	padding:1px 3px 1px 3px;
+	line-height:1.1em;
+}
+.dojoxColorPickerRgb { position:absolute; top:0; left:0;  } 
+.dojoxColorPickerHsv { position:absolute; top:0; left:50px;  } 
+.dojoxColorPickerHex { position:absolute; top:73px; left:2px;  } 
+.dojoxColorPickerHex input {
+	width:55px;	
+}
diff --git a/dojox/widget/ColorPicker/ColorPicker.html b/dojox/widget/ColorPicker/ColorPicker.html
new file mode 100644
index 0000000..7bcf2f0
--- /dev/null
+++ b/dojox/widget/ColorPicker/ColorPicker.html
@@ -0,0 +1,31 @@
+<div class="dojoxColorPicker" dojoAttachEvent="onkeypress: _handleKey">
+	<div class="dojoxColorPickerBox">
+		<div dojoAttachPoint="cursorNode" tabIndex="0" class="dojoxColorPickerPoint"></div>
+		<img dojoAttachPoint="colorUnderlay" dojoAttachEvent="onclick: _setPoint" class="dojoxColorPickerUnderlay" src="${_underlay}">
+	</div>
+	<div class="dojoxHuePicker">
+		<div dojoAttachPoint="hueCursorNode" tabIndex="0" class="dojoxHuePickerPoint"></div>
+		<div dojoAttachPoint="hueNode" class="dojoxHuePickerUnderlay" dojoAttachEvent="onclick: _setHuePoint"></div>
+	</div>
+	<div dojoAttachPoint="previewNode" class="dojoxColorPickerPreview"></div>
+	<div dojoAttachPoint="safePreviewNode" class="dojoxColorPickerWebSafePreview"></div>
+	<div class="dojoxColorPickerOptional" dojoAttachEvent="onchange: _colorInputChange">
+		<div class="dijitInline dojoxColorPickerRgb" dojoAttachPoint="rgbNode">
+			<table>
+			<tr><td>r</td><td><input dojoAttachPoint="Rval" size="1"></td></tr>
+			<tr><td>g</td><td><input dojoAttachPoint="Gval" size="1"></td></tr>
+			<tr><td>b</td><td><input dojoAttachPoint="Bval" size="1"></td></tr>
+			</table>
+		</div>
+		<div class="dijitInline dojoxColorPickerHsv" dojoAttachPoint="hsvNode">
+			<table>
+			<tr><td>h</td><td><input dojoAttachPoint="Hval"size="1"> °</td></tr>
+			<tr><td>s</td><td><input dojoAttachPoint="Sval" size="1"> %</td></tr>
+			<tr><td>v</td><td><input dojoAttachPoint="Vval" size="1"> %</td></tr>
+			</table>
+		</div>
+		<div class="dojoxColorPickerHex" dojoAttachPoint="hexNode">	
+			hex: <input dojoAttachPoint="hexCode, focusNode, valueNode" size="6" class="dojoxColorPickerHexCode">
+		</div>
+	</div>
+</div>
diff --git a/dojox/widget/ColorPicker/images/hue.png b/dojox/widget/ColorPicker/images/hue.png
new file mode 100644
index 0000000..2746235
Binary files /dev/null and b/dojox/widget/ColorPicker/images/hue.png differ
diff --git a/dojox/widget/ColorPicker/images/hueHandle.png b/dojox/widget/ColorPicker/images/hueHandle.png
new file mode 100644
index 0000000..c7b56e8
Binary files /dev/null and b/dojox/widget/ColorPicker/images/hueHandle.png differ
diff --git a/dojox/widget/ColorPicker/images/pickerPointer.png b/dojox/widget/ColorPicker/images/pickerPointer.png
new file mode 100644
index 0000000..28a3c81
Binary files /dev/null and b/dojox/widget/ColorPicker/images/pickerPointer.png differ
diff --git a/dojox/widget/ColorPicker/images/underlay.png b/dojox/widget/ColorPicker/images/underlay.png
new file mode 100644
index 0000000..0f5eb7c
Binary files /dev/null and b/dojox/widget/ColorPicker/images/underlay.png differ
diff --git a/dojox/widget/Dialog.js b/dojox/widget/Dialog.js
new file mode 100644
index 0000000..2c4f3a5
--- /dev/null
+++ b/dojox/widget/Dialog.js
@@ -0,0 +1,81 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.Dialog"]){
+dojo._hasResource["dojox.widget.Dialog"]=true;
+dojo.provide("dojox.widget.Dialog");
+dojo.experimental("dojox.widget.Dialog");
+dojo.require("dijit.Dialog");
+dojo.require("dojox.fx");
+dojo.declare("dojox.widget.Dialog",dijit.Dialog,{templateString:"<div class=\"dojoxDialog\" tabindex=\"-1\" waiRole=\"dialog\" waiState=\"labelledby-${id}_title\">\n\t<div dojoAttachPoint=\"titleBar\" class=\"dojoxDialogTitleBar\">\n\t\t<span dojoAttachPoint=\"titleNode\" class=\"dojoxDialogTitle\" id=\"${id}_title\">${title}</span>\n\t</div>\n\t<div dojoAttachPoint=\"dojoxDialogWrapper\">\n\t\t<div dojoAttachPoint=\"containerNode\" class=\"dojoxDialogPaneContent\"></div>\n\t</div>\n\t<d [...]
+this.easing=_1.easing||dojo._defaultEasing;
+this.dimensions=_1.dimensions||[300,300];
+},_setup:function(){
+this.inherited(arguments);
+if(!this._alreadyInitialized){
+this._navIn=dojo.fadeIn({node:this.closeButtonNode});
+this._navOut=dojo.fadeOut({node:this.closeButtonNode});
+if(!this.showTitle){
+dojo.addClass(this.domNode,"dojoxDialogNoTitle");
+}
+}
+},layout:function(e){
+this._setSize();
+this.inherited(arguments);
+},_setSize:function(){
+this._vp=dijit.getViewport();
+var tc=this.containerNode,_5=this.sizeToViewport;
+return this._displaysize={w:_5?tc.scrollWidth:this.dimensions[0],h:_5?tc.scrollHeight:this.dimensions[1]};
+},show:function(){
+this._setSize();
+dojo.style(this.closeButtonNode,"opacity",0);
+dojo.style(this.domNode,{overflow:"hidden",opacity:0,width:"1px",height:"1px"});
+dojo.style(this.containerNode,{opacity:0,overflow:"hidden"});
+this.inherited(arguments);
+if(this.modal){
+this._modalconnects.push(dojo.connect(dojo.body(),"onkeypress",function(e){
+if(e.charOrCode==dojo.keys.ESCAPE){
+dojo.stopEvent(e);
+}
+}));
+}else{
+this._modalconnects.push(dojo.connect(dijit._underlay.domNode,"onclick",this,"onCancel"));
+}
+this._modalconnects.push(dojo.connect(this.domNode,"onmouseenter",this,"_handleNav"));
+this._modalconnects.push(dojo.connect(this.domNode,"onmouseleave",this,"_handleNav"));
+},_handleNav:function(e){
+var _8="_navOut",_9="_navIn",_a=(e.type=="mouseout"?_9:_8),_b=(e.type=="mouseout"?_8:_9);
+this[_a].stop();
+this[_b].play();
+},_position:function(){
+if(!this._started){
+return;
+}
+if(this._sizing){
+this._sizing.stop();
+this.disconnect(this._sizingConnect);
+delete this._sizing;
+}
+this.inherited(arguments);
+if(!this.open){
+dojo.style(this.containerNode,"opacity",0);
+}
+var _c=this.viewportPadding*2;
+var _d={node:this.domNode,duration:this.sizeDuration||dijit._defaultDuration,easing:this.easing,method:this.sizeMethod};
+var ds=this._displaysize||this._setSize();
+_d["width"]=ds.w=(ds.w+_c>=this._vp.w||this.sizeToViewport)?this._vp.w-_c:ds.w;
+_d["height"]=ds.h=(ds.h+_c>=this._vp.h||this.sizeToViewport)?this._vp.h-_c:ds.h;
+this._sizing=dojox.fx.sizeTo(_d);
+this._sizingConnect=this.connect(this._sizing,"onEnd","_showContent");
+this._sizing.play();
+},_showContent:function(e){
+var _10=this.containerNode;
+dojo.style(this.domNode,"overflow","visible");
+dojo.style(_10,{height:this._displaysize.h+"px",width:this._displaysize.w+"px",overflow:"auto"});
+dojo.anim(_10,{opacity:1});
+}});
+}
diff --git a/dojox/widget/Dialog/Dialog.css b/dojox/widget/Dialog/Dialog.css
new file mode 100644
index 0000000..f4b2c07
--- /dev/null
+++ b/dojox/widget/Dialog/Dialog.css
@@ -0,0 +1,86 @@
+
+.dojoxDialog {
+	position: absolute;
+	z-index: 999;
+	outline:0;
+}
+.dojoxDialog .closeText {
+	display:none;
+	
+	position:absolute;
+}
+.dojoxDialogFixed div.dojoxDialogTitleBar {
+	cursor:default; 
+}
+.dojoxDialogWrapper {
+	left: 0;
+	top: 0;
+}
+.dojoxDialog {
+	background: #fff;
+	-webkit-box-shadow: 0px 5px 10px #adadad;
+	-moz-border-radius:9pt;
+	-webkit-border-radius:8pt;
+	border:1px solid #b7b7b7;
+	padding:1.5em 3px 3px 3px;
+}
+.dojoxDialogFocused {
+	border:1px solid #ccc;
+}
+.dojoxDialog .dojoxDialogPaneContent {
+	border:none;
+	padding:0;
+}
+.dojoxDialogTitleBar {
+	
+	cursor:move;
+	position:absolute;
+	top:0;
+	left:0;
+	right:0;
+	background:#ededed;
+	height:1.5em;
+	outline:0; 
+	-moz-border-radius-topleft:8pt;
+	-moz-border-radius-topright:8pt;
+	-webkik-border-radius-topleft:7pt;
+	-webkit-border-radius-topright:7pt;
+}
+.dj_webkit .dojoxDialogTitleBar {
+	border:1px solid #ccc;
+}
+.dojoxDialogNoTitle .dojoxDialogTitleBar {
+	display:none;
+}
+.dojoxDialogContent {
+	
+	padding: 3px;
+	margin-top:1.2em;
+}
+.dojoxDialogTitle {
+	font-weight: bold;
+	padding: 8px 12px 8px 12px;
+	outline:0;
+	border-bottom:#b7b7b7;
+}
+div.dojoxDialogNoTitle {
+	padding-top:9px;
+}
+.dojoxDialogCloseIcon {
+	background : url("images/dialogCloseButton.png") no-repeat top right;
+	position: absolute;
+	vertical-align: middle;
+	left: -19px;
+	top: -19px;
+	height: 29px;
+	width: 29px;
+	cursor: pointer;
+	z-index: 999;
+}
+.dj_ie6 .dojoxDialogCloseIcon {
+	background-image: url("images/dialogCloseButton.gif");
+}
+.dojoxDialogNoTitle .dojoxDialogCloseIcon {
+	top: -15px;
+	left: -15px;
+}
diff --git a/dojox/widget/Dialog/Dialog.html b/dojox/widget/Dialog/Dialog.html
new file mode 100644
index 0000000..91542c1
--- /dev/null
+++ b/dojox/widget/Dialog/Dialog.html
@@ -0,0 +1,11 @@
+<div class="dojoxDialog" tabindex="-1" waiRole="dialog" waiState="labelledby-${id}_title">
+	<div dojoAttachPoint="titleBar" class="dojoxDialogTitleBar">
+		<span dojoAttachPoint="titleNode" class="dojoxDialogTitle" id="${id}_title">${title}</span>
+	</div>
+	<div dojoAttachPoint="dojoxDialogWrapper">
+		<div dojoAttachPoint="containerNode" class="dojoxDialogPaneContent"></div>
+	</div>
+	<div dojoAttachPoint="closeButtonNode" class="dojoxDialogCloseIcon" dojoAttachEvent="onclick: onCancel">
+			<span dojoAttachPoint="closeText" class="closeText">x</span>
+	</div>
+</div>
diff --git a/dojox/widget/Dialog/images/dialogCloseButton.gif b/dojox/widget/Dialog/images/dialogCloseButton.gif
new file mode 100644
index 0000000..1f45a5c
Binary files /dev/null and b/dojox/widget/Dialog/images/dialogCloseButton.gif differ
diff --git a/dojox/widget/Dialog/images/dialogCloseButton.png b/dojox/widget/Dialog/images/dialogCloseButton.png
new file mode 100644
index 0000000..9d2f423
Binary files /dev/null and b/dojox/widget/Dialog/images/dialogCloseButton.png differ
diff --git a/dojox/widget/DocTester.js b/dojox/widget/DocTester.js
new file mode 100644
index 0000000..d81ddb7
--- /dev/null
+++ b/dojox/widget/DocTester.js
@@ -0,0 +1,70 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.DocTester"]){
+dojo._hasResource["dojox.widget.DocTester"]=true;
+dojo.provide("dojox.widget.DocTester");
+dojo.require("dojo.string");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dojox.form.BusyButton");
+dojo.require("dojox.testing.DocTest");
+dojo.declare("dojox.widget.DocTester",[dijit._Widget,dijit._Templated],{templateString:"<div dojoAttachPoint=\"domNode\" class=\"dojoxDocTester\">\n\t<div dojoAttachPoint=\"containerNode\"></div>\n\t<button dojoType=\"dojox.form.BusyButton\" busyLabel=\"Testing...\" dojoAttachPoint=\"runButtonNode\">Run tests</button>\n\t<button dojoType=\"dijit.form.Button\" dojoAttachPoint=\"resetButtonNode\" style=\"display:none;\">Reset</button>\n\t<span>\n\t\t<span dojoAttachPoint=\"numTestsNode\">0 [...]
+var _2=_1.innerHTML;
+this.doctests=new dojox.testing.DocTest();
+this.tests=this.doctests.getTestsFromString(this._unescapeHtml(_2));
+var _3=dojo.map(this.tests,"return item.line-1");
+var _4=_2.split("\n");
+var _5="<div class=\"actualResult\">FAILED, actual result was: <span class=\"result\"></span></div>";
+var _6="<pre class=\"testCase testNum0 odd\">";
+for(var i=0;i<_4.length;i++){
+var _8=dojo.indexOf(_3,i);
+if(_8>0&&_8!=-1){
+var _9=_8%2?"even":"odd";
+_6+=_5;
+_6+="</pre><pre class=\"testCase testNum"+_8+" "+_9+"\">";
+}
+_6+=_4[i].replace(/^\s+/,"")+"\n";
+}
+_6+=_5+"</pre>";
+this.containerNode.innerHTML=_6;
+},postCreate:function(){
+this.inherited("postCreate",arguments);
+dojo.connect(this.runButtonNode,"onClick",dojo.hitch(this,"runTests"));
+dojo.connect(this.resetButtonNode,"onClick",dojo.hitch(this,"reset"));
+this.numTestsNode.innerHTML=this.tests.length;
+},runTests:function(){
+var _a={ok:0,nok:0};
+for(var i=0;i<this.tests.length;i++){
+var _c=this.doctests.runTest(this.tests[i].commands,this.tests[i].expectedResult);
+dojo.query(".testNum"+i,this.domNode).addClass(_c.success?"resultOk":"resultNok");
+if(!_c.success){
+_a.nok++;
+this.numTestsNokNode.innerHTML=_a.nok;
+var _d=dojo.query(".testNum"+i+" .actualResult",this.domNode)[0];
+dojo.style(_d,"display","inline");
+dojo.query(".result",_d)[0].innerHTML=dojo.toJson(_c.actualResult);
+}else{
+_a.ok++;
+this.numTestsOkNode.innerHTML=_a.ok;
+}
+}
+this.runButtonNode.cancel();
+dojo.style(this.runButtonNode.domNode,"display","none");
+dojo.style(this.resetButtonNode.domNode,"display","");
+},reset:function(){
+dojo.style(this.runButtonNode.domNode,"display","");
+dojo.style(this.resetButtonNode.domNode,"display","none");
+this.numTestsOkNode.innerHTML="0";
+this.numTestsNokNode.innerHTML="0";
+dojo.query(".actualResult",this.domNode).style("display","none");
+dojo.query(".testCase",this.domNode).removeClass("resultOk").removeClass("resultNok");
+},_unescapeHtml:function(_e){
+_e=String(_e).replace(/&/gm,"&").replace(/</gm,"<").replace(/>/gm,">").replace(/"/gm,"\"");
+return _e;
+}});
+}
diff --git a/dojox/widget/DocTester/DocTester.css b/dojox/widget/DocTester/DocTester.css
new file mode 100644
index 0000000..34fbaa5
--- /dev/null
+++ b/dojox/widget/DocTester/DocTester.css
@@ -0,0 +1,30 @@
+.dojoxDocTester pre.testCase{
+	border:0;
+	padding:0.3em;
+	padding-left:2em;
+}
+.dojoxDocTester pre.odd{
+	background-color:#E3E3E3;
+}
+.dojoxDocTester pre.odd.resultOk{
+	background-color:#C3FFC3;
+}
+.dojoxDocTester pre.odd.resultNok{
+	background-color:#FFC3C3;
+}
+.dojoxDocTester pre.even{
+        background-color:#F3F3F3;
+}
+.dojoxDocTester pre.even.resultOk{
+	background-color:#DFFFDF;
+}
+.dojoxDocTester pre.even.resultNok{
+	background-color:#FFCFCF;
+}
+.dojoxDocTester .actualResult{
+	display:none;
+	font-weight:bold;
+}
+.dojoxDocTester .actualResult .result{
+	color:red;
+}
diff --git a/dojox/widget/DocTester/DocTester.html b/dojox/widget/DocTester/DocTester.html
new file mode 100644
index 0000000..fbb7a6b
--- /dev/null
+++ b/dojox/widget/DocTester/DocTester.html
@@ -0,0 +1,10 @@
+<div dojoAttachPoint="domNode" class="dojoxDocTester">
+	<div dojoAttachPoint="containerNode"></div>
+	<button dojoType="dojox.form.BusyButton" busyLabel="Testing..." dojoAttachPoint="runButtonNode">Run tests</button>
+	<button dojoType="dijit.form.Button" dojoAttachPoint="resetButtonNode" style="display:none;">Reset</button>
+	<span>
+		<span dojoAttachPoint="numTestsNode">0</span> tests,
+		<span dojoAttachPoint="numTestsOkNode">0</span> passed,
+		<span dojoAttachPoint="numTestsNokNode">0</span> failed
+	</span>
+</div>
\ No newline at end of file
diff --git a/dojox/widget/FilePicker.js b/dojox/widget/FilePicker.js
new file mode 100644
index 0000000..2603cb2
--- /dev/null
+++ b/dojox/widget/FilePicker.js
@@ -0,0 +1,160 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.FilePicker"]){
+dojo._hasResource["dojox.widget.FilePicker"]=true;
+dojo.provide("dojox.widget.FilePicker");
+dojo.require("dojox.widget.RollingList");
+dojo.require("dojo.i18n");
+dojo.requireLocalization("dojox.widget","FilePicker",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.declare("dojox.widget._FileInfoPane",[dojox.widget._RollingListPane],{templateString:"",templateString:"<div class=\"dojoxFileInfoPane\">\n\t<table>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td class=\"dojoxFileInfoLabel dojoxFileInfoNameLabel\">${_messages.name}</td>\n\t\t\t\t<td class=\"dojoxFileInfoName\" dojoAttachPoint=\"nameNode\"></td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td class=\"dojoxFileInfoLabel dojoxFileInfoPathLabel\">${_messages.path}</td>\n\t\t\t\t<td class=\"dojoxFileInfoPa [...]
+this._messages=dojo.i18n.getLocalization("dojox.widget","FilePicker",this.lang);
+this.inherited(arguments);
+},onItems:function(){
+var _1=this.store,_2=this.items[0];
+if(!_2){
+this._onError("Load",new Error("No item defined"));
+}else{
+this.nameNode.innerHTML=_1.getLabel(_2);
+this.pathNode.innerHTML=_1.getIdentity(_2);
+this.sizeNode.innerHTML=_1.getValue(_2,"size");
+this.parentWidget.scrollIntoView(this);
+this.inherited(arguments);
+}
+}});
+dojo.declare("dojox.widget.FilePicker",dojox.widget.RollingList,{className:"dojoxFilePicker",pathSeparator:"",topDir:"",parentAttr:"parentDir",pathAttr:"path",preloadItems:50,selectDirectories:true,selectFiles:true,_itemsMatch:function(_3,_4){
+if(!_3&&!_4){
+return true;
+}else{
+if(!_3||!_4){
+return false;
+}else{
+if(_3==_4){
+return true;
+}else{
+if(this._isIdentity){
+var _5=[this.store.getIdentity(_3),this.store.getIdentity(_4)];
+dojo.forEach(_5,function(i,_7){
+if(i.lastIndexOf(this.pathSeparator)==(i.length-1)){
+_5[_7]=i.substring(0,i.length-1);
+}else{
+}
+},this);
+return (_5[0]==_5[1]);
+}
+}
+}
+}
+return false;
+},startup:function(){
+if(this._started){
+return;
+}
+this.inherited(arguments);
+var _8,_9=this.getChildren()[0];
+var _a=dojo.hitch(this,function(){
+if(_8){
+this.disconnect(_8);
+}
+delete _8;
+var _b=_9.items[0];
+if(_b){
+var _c=this.store;
+var _d=_c.getValue(_b,this.parentAttr);
+var _e=_c.getValue(_b,this.pathAttr);
+this.pathSeparator=this.pathSeparator||_c.pathSeparator;
+if(!this.pathSeparator){
+this.pathSeparator=_e.substring(_d.length,_d.length+1);
+}
+if(!this.topDir){
+this.topDir=_d;
+if(this.topDir.lastIndexOf(this.pathSeparator)!=(this.topDir.length-1)){
+this.topDir+=this.pathSeparator;
+}
+}
+}
+});
+if(!this.pathSeparator||!this.topDir){
+if(!_9.items){
+_8=this.connect(_9,"onItems",_a);
+}else{
+_a();
+}
+}
+},getChildItems:function(_f){
+var ret=this.inherited(arguments);
+if(!ret&&this.store.getValue(_f,"directory")){
+ret=[];
+}
+return ret;
+},getMenuItemForItem:function(_11,_12,_13){
+var _14={iconClass:"dojoxDirectoryItemIcon"};
+if(!this.store.getValue(_11,"directory")){
+_14.iconClass="dojoxFileItemIcon";
+var l=this.store.getLabel(_11),idx=l.lastIndexOf(".");
+if(idx>=0){
+_14.iconClass+=" dojoxFileItemIcon_"+l.substring(idx+1);
+}
+if(!this.selectFiles){
+_14.disabled=true;
+}
+}
+var ret=new dijit.MenuItem(_14);
+return ret;
+},getPaneForItem:function(_18,_19,_1a){
+var ret=null;
+if(!_18||(this.store.isItem(_18)&&this.store.getValue(_18,"directory"))){
+ret=new dojox.widget._RollingListGroupPane({});
+}else{
+if(this.store.isItem(_18)&&!this.store.getValue(_18,"directory")){
+ret=new dojox.widget._FileInfoPane({});
+}
+}
+return ret;
+},_setPathValueAttr:function(_1c,_1d,_1e){
+if(!_1c){
+this.attr("value",null);
+return;
+}
+if(_1c.lastIndexOf(this.pathSeparator)==(_1c.length-1)){
+_1c=_1c.substring(0,_1c.length-1);
+}
+this.store.fetchItemByIdentity({identity:_1c,onItem:function(v){
+if(_1d){
+this._lastExecutedValue=v;
+}
+this.attr("value",v);
+if(_1e){
+_1e();
+}
+},scope:this});
+},_getPathValueAttr:function(val){
+if(!val){
+val=this.value;
+}
+if(val&&this.store.isItem(val)){
+return this.store.getValue(val,this.pathAttr);
+}else{
+return "";
+}
+},_setValue:function(_21){
+delete this._setInProgress;
+var _22=this.store;
+if(_21&&_22.isItem(_21)){
+var _23=this.store.getValue(_21,"directory");
+if((_23&&!this.selectDirectories)||(!_23&&!this.selectFiles)){
+return;
+}
+}else{
+_21=null;
+}
+if(!this._itemsMatch(this.value,_21)){
+this.value=_21;
+this._onChange(_21);
+}
+}});
+}
diff --git a/dojox/widget/FilePicker/FilePicker.css b/dojox/widget/FilePicker/FilePicker.css
new file mode 100644
index 0000000..d57847a
--- /dev/null
+++ b/dojox/widget/FilePicker/FilePicker.css
@@ -0,0 +1,207 @@
+.dojoxRollingList {
+	border: 1px solid #000;
+	height: 20em;
+	background-color: #FFF;
+	position: relative;
+}
+.dijitPopup .dojoxRollingList {
+	position: static;
+}
+.dojoxRollingListContainer {
+	overflow: scroll;
+	overflow-y: hidden;
+	overflow-x: scroll;
+	white-space: nowrap;
+}
+.dojoxRollingListButtons {
+	position: absolute;
+	right: 5px;
+	padding: 5px 0px;
+}
+.dojoxRollingListButtonsHidden .dojoxRollingListButtons {
+	display: none;
+}
+.dojoxRollingListPane {
+	overflow: scroll;
+	overflow-x: hidden;
+	overflow-y: scroll;
+	display:-moz-inline-box;		
+	display:inline-block;			
+	#zoom: 1; 
+	#display:inline; 
+	border:0;
+	padding:0;
+	vertical-align:middle;
+	#vertical-align: auto;	
+}
+.dojoxRollingListPane .dijitMenuItem td {
+	width: 1px;
+}
+.dojoxRollingListPane .dijitMenuItem td.dijitMenuItemLabel {
+	width: auto;
+}
+.dojoxRollingListPane .dijitMenuItemLabel,
+.dojoxRollingListPane .dijitMenuItemIcon {
+	position: static !important;
+}
+.dj_webkit .dojoxRollingListPane,
+.dj_ie .dojoxRollingListPane {
+	padding-right: 15px; 
+}
+.dojoxRollingListPane .dijitMenu {
+	border: none !important;
+}
+.dojoxRollingListItem {
+	cursor: default;
+}
+.tundra .dojoxRollingList {
+	border-color: #b3b3b3;
+}
+.tundra .dijitPopup .dojoxRollingList {
+	border-color: #406b9b;
+}
+.tundra .dojoxRollingListPane {
+	background-color: #f7f7f7;
+}
+.tundra .dojoxRollingListPane .dojoxRollingListItemHover,
+.tundra .dojoxRollingListPane .dojoxRollingListItemFocus {
+	background-color: #e3e3e3;
+}
+.tundra .dojoxRollingListPane .dojoxRollingListItemSelected {
+	color: #fff;
+	background-color: #999;
+	font-weight: bold;
+}
+.tundra .dojoxRollingListPaneCurrentSelected .dojoxRollingListItemSelected {
+	background-color: #3559ac;
+}
+.tundra .dojoxRollingListPane .dojoxRollingListItemHoverSelected,
+.tundra .dojoxRollingListPane .dojoxRollingListItemFocusSelected {
+	background-color: #9aacd6;
+}
+.tundra .dojoxRollingListItem {
+	font-family: inherit;
+}
+.soria .dojoxRollingList {
+	border-color: #8ba0bd;
+}
+.soria .dijitPopup .dojoxRollingList {
+	border-color: #406b9b;
+}
+.soria .dojoxRollingListPane {
+	background-color: #fff;
+}
+.soria .dojoxRollingListPane .dojoxRollingListItemHover, 
+.soria .dojoxRollingListPane .dojoxRollingListItemFocus {
+	background-color: #e3e3e3;
+}
+.soria .dojoxRollingListPane .dojoxRollingListItemSelected {
+	color: #243C5F;
+	background-color: #ccc;
+	font-weight: bold;
+}
+.soria .dojoxRollingListPaneCurrentSelected .dojoxRollingListItemSelected {
+	background-color: #d9e6f9;
+}
+.soria .dojoxRollingListPane .dojoxRollingListItemHoverSelected,
+.soria .dojoxRollingListPane .dojoxRollingListItemFocusSelected {
+	background-color: #ecf3fc;
+}
+.soria .dojoxRollingListItem {
+	font-family: inherit;
+}
+.nihilo .dojoxRollingList {
+	border-color: #d3d3d3;
+}
+.nihilo .dijitPopup .dojoxRollingList {
+	border-color: #b3b3b3;
+}
+.nihilo .dojoxRollingListPane {
+	background-color: #fff;
+}
+.nihilo .dojoxRollingListPane .dojoxRollingListItemHover,
+.nihilo .dojoxRollingListPane .dojoxRollingListItemFocus {
+	background-color: #e3e3e3;
+}
+.nihilo .dojoxRollingListPane .dojoxRollingListItemSelected {
+	color: #243C5F;
+	background-color: #ccc;
+	font-weight: bold;
+}
+.nihilo .dojoxRollingListPaneCurrentSelected .dojoxRollingListItemSelected {
+	background-color: #ffe284;
+}
+.nihilo .dojoxRollingListPane .dojoxRollingListItemHoverSelected,
+.nihilo .dojoxRollingListPane .dojoxRollingListItemFocusSelected {
+	background-color: #fff1c2;
+}
+.nihilo .dojoxRollingListItem {
+	font-family: inherit;
+}
+.dojoxFileInfoPane *{
+	white-space: normal;
+}
+.dojoxFileInfoLabel {
+	font-weight: bold;
+	white-space: nowrap;
+}
+.dojoxFileInfoPane {
+	width: 20em;
+}
+.tundra .dojoxFilePickerItem .dijitMenuItemIcon {
+	background-image: url("images/tundraFileIcons.gif");
+	background-repeat: no-repeat;
+}
+.tundra .dojoxFilePickerItem .dojoxEmpty {
+	background-image: none;
+}
+.tundra .dojoxFilePickerItem .dojoxDirectoryItemIcon {
+	background-position: 0px;
+}
+.tundra .dojoxFilePickerItemSelected .dojoxDirectoryItemIcon {
+	background-position: -16px;
+}
+.tundra .dojoxFilePickerItem .dojoxFileItemIcon {
+	background-position: -32px;
+}
+.tundra .dojoxFilePickerItemSelected .dojoxFileItemIcon {
+	background-position: -48px;
+}
+.soria .dojoxFilePickerItem .dijitMenuItemIcon {
+	background-image: url("images/soriaFileIcons.gif");
+	background-repeat: no-repeat;
+}
+.soria .dojoxFilePickerItem .dojoxEmpty {
+	background-image: none;
+}
+.soria .dojoxFilePickerItem .dojoxDirectoryItemIcon {
+	background-position: 0px;
+}
+.soria .dojoxFilePickerItemSelected .dojoxDirectoryItemIcon {
+	background-position: -16px;
+}
+.soria .dojoxFilePickerItem .dojoxFileItemIcon {
+	background-position: -32px;
+}
+.soria .dojoxFilePickerItemSelected .dojoxFileItemIcon {
+	background-position: -48px;
+}
+.nihilo .dojoxFilePickerItem .dijitMenuItemIcon {
+	background-image: url("images/nihiloFileIcons.gif");
+	background-repeat: no-repeat;
+}
+.nihilo .dojoxFilePickerItem .dojoxEmpty {
+	background-image: none;
+}
+.nihilo .dojoxFilePickerItem .dojoxDirectoryItemIcon {
+	background-position: 0px;
+}
+.nihilo .dojoxFilePickerItemSelected .dojoxDirectoryItemIcon {
+	background-position: -16px;
+}
+.nihilo .dojoxFilePickerItem .dojoxFileItemIcon {
+	background-position: -32px;
+}
+.nihilo .dojoxFilePickerItemSelected .dojoxFileItemIcon {
+	background-position: -48px;
+}
diff --git a/dojox/widget/FilePicker/_FileInfoPane.html b/dojox/widget/FilePicker/_FileInfoPane.html
new file mode 100644
index 0000000..4a45e61
--- /dev/null
+++ b/dojox/widget/FilePicker/_FileInfoPane.html
@@ -0,0 +1,19 @@
+<div class="dojoxFileInfoPane">
+	<table>
+		<tbody>
+			<tr>
+				<td class="dojoxFileInfoLabel dojoxFileInfoNameLabel">${_messages.name}</td>
+				<td class="dojoxFileInfoName" dojoAttachPoint="nameNode"></td>
+			</tr>
+			<tr>
+				<td class="dojoxFileInfoLabel dojoxFileInfoPathLabel">${_messages.path}</td>
+				<td class="dojoxFileInfoPath" dojoAttachPoint="pathNode"></td>
+			</tr>
+			<tr>
+				<td class="dojoxFileInfoLabel dojoxFileInfoSizeLabel">${_messages.size}</td>
+				<td class="dojoxFileInfoSize" dojoAttachPoint="sizeNode"></td>
+			</tr>
+		</tbody>
+	</table>
+	<div dojoAttachPoint="containerNode" style="display:none;"></div>
+</div>
\ No newline at end of file
diff --git a/dojox/widget/FilePicker/images/nihiloFileIcons.gif b/dojox/widget/FilePicker/images/nihiloFileIcons.gif
new file mode 100644
index 0000000..f029204
Binary files /dev/null and b/dojox/widget/FilePicker/images/nihiloFileIcons.gif differ
diff --git a/dojox/widget/FilePicker/images/soriaFileIcons.gif b/dojox/widget/FilePicker/images/soriaFileIcons.gif
new file mode 100644
index 0000000..8087146
Binary files /dev/null and b/dojox/widget/FilePicker/images/soriaFileIcons.gif differ
diff --git a/dojox/widget/FilePicker/images/tundraFileIcons.gif b/dojox/widget/FilePicker/images/tundraFileIcons.gif
new file mode 100644
index 0000000..744525e
Binary files /dev/null and b/dojox/widget/FilePicker/images/tundraFileIcons.gif differ
diff --git a/dojox/widget/FisheyeList.js b/dojox/widget/FisheyeList.js
new file mode 100644
index 0000000..ed56f8d
--- /dev/null
+++ b/dojox/widget/FisheyeList.js
@@ -0,0 +1,428 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.FisheyeList"]){
+dojo._hasResource["dojox.widget.FisheyeList"]=true;
+dojo.provide("dojox.widget.FisheyeList");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dijit._Container");
+dojo.require("dijit._Contained");
+dojo.declare("dojox.widget.FisheyeList",[dijit._Widget,dijit._Templated,dijit._Container],{constructor:function(){
+this.pos={"x":-1,"y":-1};
+this.timerScale=1;
+},EDGE:{CENTER:0,LEFT:1,RIGHT:2,TOP:3,BOTTOM:4},templateString:"<div class=\"dojoxFisheyeListBar\" dojoAttachPoint=\"containerNode\"></div>",snarfChildDomOutput:true,itemWidth:40,itemHeight:40,itemMaxWidth:150,itemMaxHeight:150,imgNode:null,orientation:"horizontal",isFixed:false,conservativeTrigger:false,effectUnits:2,itemPadding:10,attachEdge:"center",labelEdge:"bottom",postCreate:function(){
+var e=this.EDGE;
+dojo.setSelectable(this.domNode,false);
+var _2=this.isHorizontal=(this.orientation=="horizontal");
+this.selectedNode=-1;
+this.isOver=false;
+this.hitX1=-1;
+this.hitY1=-1;
+this.hitX2=-1;
+this.hitY2=-1;
+this.anchorEdge=this._toEdge(this.attachEdge,e.CENTER);
+this.labelEdge=this._toEdge(this.labelEdge,e.TOP);
+if(this.labelEdge==e.CENTER){
+this.labelEdge=e.TOP;
+}
+if(_2){
+if(this.anchorEdge==e.LEFT){
+this.anchorEdge=e.CENTER;
+}
+if(this.anchorEdge==e.RIGHT){
+this.anchorEdge=e.CENTER;
+}
+if(this.labelEdge==e.LEFT){
+this.labelEdge=e.TOP;
+}
+if(this.labelEdge==e.RIGHT){
+this.labelEdge=e.TOP;
+}
+}else{
+if(this.anchorEdge==e.TOP){
+this.anchorEdge=e.CENTER;
+}
+if(this.anchorEdge==e.BOTTOM){
+this.anchorEdge=e.CENTER;
+}
+if(this.labelEdge==e.TOP){
+this.labelEdge=e.LEFT;
+}
+if(this.labelEdge==e.BOTTOM){
+this.labelEdge=e.LEFT;
+}
+}
+var _3=this.effectUnits;
+this.proximityLeft=this.itemWidth*(_3-0.5);
+this.proximityRight=this.itemWidth*(_3-0.5);
+this.proximityTop=this.itemHeight*(_3-0.5);
+this.proximityBottom=this.itemHeight*(_3-0.5);
+if(this.anchorEdge==e.LEFT){
+this.proximityLeft=0;
+}
+if(this.anchorEdge==e.RIGHT){
+this.proximityRight=0;
+}
+if(this.anchorEdge==e.TOP){
+this.proximityTop=0;
+}
+if(this.anchorEdge==e.BOTTOM){
+this.proximityBottom=0;
+}
+if(this.anchorEdge==e.CENTER){
+this.proximityLeft/=2;
+this.proximityRight/=2;
+this.proximityTop/=2;
+this.proximityBottom/=2;
+}
+},startup:function(){
+this.children=this.getChildren();
+this._initializePositioning();
+if(!this.conservativeTrigger){
+this._onMouseMoveHandle=dojo.connect(document.documentElement,"onmousemove",this,"_onMouseMove");
+}
+if(this.isFixed){
+this._onScrollHandle=dojo.connect(document,"onscroll",this,"_onScroll");
+}
+this._onMouseOutHandle=dojo.connect(document.documentElement,"onmouseout",this,"_onBodyOut");
+this._addChildHandle=dojo.connect(this,"addChild",this,"_initializePositioning");
+this._onResizeHandle=dojo.connect(window,"onresize",this,"_initializePositioning");
+},_initializePositioning:function(){
+this.itemCount=this.children.length;
+this.barWidth=(this.isHorizontal?this.itemCount:1)*this.itemWidth;
+this.barHeight=(this.isHorizontal?1:this.itemCount)*this.itemHeight;
+this.totalWidth=this.proximityLeft+this.proximityRight+this.barWidth;
+this.totalHeight=this.proximityTop+this.proximityBottom+this.barHeight;
+for(var i=0;i<this.children.length;i++){
+this.children[i].posX=this.itemWidth*(this.isHorizontal?i:0);
+this.children[i].posY=this.itemHeight*(this.isHorizontal?0:i);
+this.children[i].cenX=this.children[i].posX+(this.itemWidth/2);
+this.children[i].cenY=this.children[i].posY+(this.itemHeight/2);
+var _5=this.isHorizontal?this.itemWidth:this.itemHeight;
+var r=this.effectUnits*_5;
+var c=this.isHorizontal?this.children[i].cenX:this.children[i].cenY;
+var _8=this.isHorizontal?this.proximityLeft:this.proximityTop;
+var _9=this.isHorizontal?this.proximityRight:this.proximityBottom;
+var _a=this.isHorizontal?this.barWidth:this.barHeight;
+var _b=r;
+var _c=r;
+if(_b>c+_8){
+_b=c+_8;
+}
+if(_c>(_a-c+_9)){
+_c=_a-c+_9;
+}
+this.children[i].effectRangeLeft=_b/_5;
+this.children[i].effectRangeRght=_c/_5;
+}
+this.domNode.style.width=this.barWidth+"px";
+this.domNode.style.height=this.barHeight+"px";
+for(var i=0;i<this.children.length;i++){
+var _d=this.children[i];
+var _e=_d.domNode;
+_e.style.left=_d.posX+"px";
+_e.style.top=_d.posY+"px";
+_e.style.width=this.itemWidth+"px";
+_e.style.height=this.itemHeight+"px";
+_d.imgNode.style.left=this.itemPadding+"%";
+_d.imgNode.style.top=this.itemPadding+"%";
+_d.imgNode.style.width=(100-2*this.itemPadding)+"%";
+_d.imgNode.style.height=(100-2*this.itemPadding)+"%";
+}
+this._calcHitGrid();
+},_overElement:function(_f,e){
+_f=dojo.byId(_f);
+var _11={x:e.pageX,y:e.pageY};
+var bb=dojo._getBorderBox(_f);
+var _13=dojo.coords(_f,true);
+var top=_13.y;
+var _15=top+bb.h;
+var _16=_13.x;
+var _17=_16+bb.w;
+return (_11.x>=_16&&_11.x<=_17&&_11.y>=top&&_11.y<=_15);
+},_onBodyOut:function(e){
+if(this._overElement(dojo.body(),e)){
+return;
+}
+this._setDormant(e);
+},_setDormant:function(e){
+if(!this.isOver){
+return;
+}
+this.isOver=false;
+if(this.conservativeTrigger){
+dojo.disconnect(this._onMouseMoveHandle);
+}
+this._onGridMouseMove(-1,-1);
+},_setActive:function(e){
+if(this.isOver){
+return;
+}
+this.isOver=true;
+if(this.conservativeTrigger){
+this._onMouseMoveHandle=dojo.connect(document.documentElement,"onmousemove",this,"_onMouseMove");
+this.timerScale=0;
+this._onMouseMove(e);
+this._expandSlowly();
+}
+},_onMouseMove:function(e){
+if((e.pageX>=this.hitX1)&&(e.pageX<=this.hitX2)&&(e.pageY>=this.hitY1)&&(e.pageY<=this.hitY2)){
+if(!this.isOver){
+this._setActive(e);
+}
+this._onGridMouseMove(e.pageX-this.hitX1,e.pageY-this.hitY1);
+}else{
+if(this.isOver){
+this._setDormant(e);
+}
+}
+},_onScroll:function(){
+this._calcHitGrid();
+},onResized:function(){
+this._calcHitGrid();
+},_onGridMouseMove:function(x,y){
+this.pos={x:x,y:y};
+this._paint();
+},_paint:function(){
+var x=this.pos.x;
+var y=this.pos.y;
+if(this.itemCount<=0){
+return;
+}
+var pos=this.isHorizontal?x:y;
+var prx=this.isHorizontal?this.proximityLeft:this.proximityTop;
+var siz=this.isHorizontal?this.itemWidth:this.itemHeight;
+var sim=this.isHorizontal?(1-this.timerScale)*this.itemWidth+this.timerScale*this.itemMaxWidth:(1-this.timerScale)*this.itemHeight+this.timerScale*this.itemMaxHeight;
+var cen=((pos-prx)/siz)-0.5;
+var _25=(sim/siz)-0.5;
+if(_25>this.effectUnits){
+_25=this.effectUnits;
+}
+var _26=0;
+if(this.anchorEdge==this.EDGE.BOTTOM){
+var _27=(y-this.proximityTop)/this.itemHeight;
+_26=(_27>0.5)?1:y/(this.proximityTop+(this.itemHeight/2));
+}
+if(this.anchorEdge==this.EDGE.TOP){
+var _27=(y-this.proximityTop)/this.itemHeight;
+_26=(_27<0.5)?1:(this.totalHeight-y)/(this.proximityBottom+(this.itemHeight/2));
+}
+if(this.anchorEdge==this.EDGE.RIGHT){
+var _27=(x-this.proximityLeft)/this.itemWidth;
+_26=(_27>0.5)?1:x/(this.proximityLeft+(this.itemWidth/2));
+}
+if(this.anchorEdge==this.EDGE.LEFT){
+var _27=(x-this.proximityLeft)/this.itemWidth;
+_26=(_27<0.5)?1:(this.totalWidth-x)/(this.proximityRight+(this.itemWidth/2));
+}
+if(this.anchorEdge==this.EDGE.CENTER){
+if(this.isHorizontal){
+_26=y/(this.totalHeight);
+}else{
+_26=x/(this.totalWidth);
+}
+if(_26>0.5){
+_26=1-_26;
+}
+_26*=2;
+}
+for(var i=0;i<this.itemCount;i++){
+var _29=this._weighAt(cen,i);
+if(_29<0){
+_29=0;
+}
+this._setItemSize(i,_29*_26);
+}
+var _2a=Math.round(cen);
+var _2b=0;
+if(cen<0){
+_2a=0;
+}else{
+if(cen>this.itemCount-1){
+_2a=this.itemCount-1;
+}else{
+_2b=(cen-_2a)*((this.isHorizontal?this.itemWidth:this.itemHeight)-this.children[_2a].sizeMain);
+}
+}
+this._positionElementsFrom(_2a,_2b);
+},_weighAt:function(cen,i){
+var _2e=Math.abs(cen-i);
+var _2f=((cen-i)>0)?this.children[i].effectRangeRght:this.children[i].effectRangeLeft;
+return (_2e>_2f)?0:(1-_2e/_2f);
+},_setItemSize:function(p,_31){
+_31*=this.timerScale;
+var w=Math.round(this.itemWidth+((this.itemMaxWidth-this.itemWidth)*_31));
+var h=Math.round(this.itemHeight+((this.itemMaxHeight-this.itemHeight)*_31));
+if(this.isHorizontal){
+this.children[p].sizeW=w;
+this.children[p].sizeH=h;
+this.children[p].sizeMain=w;
+this.children[p].sizeOff=h;
+var y=0;
+if(this.anchorEdge==this.EDGE.TOP){
+y=(this.children[p].cenY-(this.itemHeight/2));
+}else{
+if(this.anchorEdge==this.EDGE.BOTTOM){
+y=(this.children[p].cenY-(h-(this.itemHeight/2)));
+}else{
+y=(this.children[p].cenY-(h/2));
+}
+}
+this.children[p].usualX=Math.round(this.children[p].cenX-(w/2));
+this.children[p].domNode.style.top=y+"px";
+this.children[p].domNode.style.left=this.children[p].usualX+"px";
+}else{
+this.children[p].sizeW=w;
+this.children[p].sizeH=h;
+this.children[p].sizeOff=w;
+this.children[p].sizeMain=h;
+var x=0;
+if(this.anchorEdge==this.EDGE.LEFT){
+x=this.children[p].cenX-(this.itemWidth/2);
+}else{
+if(this.anchorEdge==this.EDGE.RIGHT){
+x=this.children[p].cenX-(w-(this.itemWidth/2));
+}else{
+x=this.children[p].cenX-(w/2);
+}
+}
+this.children[p].domNode.style.left=x+"px";
+this.children[p].usualY=Math.round(this.children[p].cenY-(h/2));
+this.children[p].domNode.style.top=this.children[p].usualY+"px";
+}
+this.children[p].domNode.style.width=w+"px";
+this.children[p].domNode.style.height=h+"px";
+if(this.children[p].svgNode){
+this.children[p].svgNode.setSize(w,h);
+}
+},_positionElementsFrom:function(p,_37){
+var pos=0;
+if(this.isHorizontal){
+pos=Math.round(this.children[p].usualX+_37);
+this.children[p].domNode.style.left=pos+"px";
+}else{
+pos=Math.round(this.children[p].usualY+_37);
+this.children[p].domNode.style.top=pos+"px";
+}
+this._positionLabel(this.children[p]);
+var _39=pos;
+for(var i=p-1;i>=0;i--){
+_39-=this.children[i].sizeMain;
+if(this.isHorizontal){
+this.children[i].domNode.style.left=_39+"px";
+}else{
+this.children[i].domNode.style.top=_39+"px";
+}
+this._positionLabel(this.children[i]);
+}
+var _3b=pos;
+for(var i=p+1;i<this.itemCount;i++){
+_3b+=this.children[i-1].sizeMain;
+if(this.isHorizontal){
+this.children[i].domNode.style.left=_3b+"px";
+}else{
+this.children[i].domNode.style.top=_3b+"px";
+}
+this._positionLabel(this.children[i]);
+}
+},_positionLabel:function(itm){
+var x=0;
+var y=0;
+var mb=dojo.marginBox(itm.lblNode);
+if(this.labelEdge==this.EDGE.TOP){
+x=Math.round((itm.sizeW/2)-(mb.w/2));
+y=-mb.h;
+}
+if(this.labelEdge==this.EDGE.BOTTOM){
+x=Math.round((itm.sizeW/2)-(mb.w/2));
+y=itm.sizeH;
+}
+if(this.labelEdge==this.EDGE.LEFT){
+x=-mb.w;
+y=Math.round((itm.sizeH/2)-(mb.h/2));
+}
+if(this.labelEdge==this.EDGE.RIGHT){
+x=itm.sizeW;
+y=Math.round((itm.sizeH/2)-(mb.h/2));
+}
+itm.lblNode.style.left=x+"px";
+itm.lblNode.style.top=y+"px";
+},_calcHitGrid:function(){
+var pos=dojo.coords(this.domNode,true);
+this.hitX1=pos.x-this.proximityLeft;
+this.hitY1=pos.y-this.proximityTop;
+this.hitX2=this.hitX1+this.totalWidth;
+this.hitY2=this.hitY1+this.totalHeight;
+},_toEdge:function(inp,def){
+return this.EDGE[inp.toUpperCase()]||def;
+},_expandSlowly:function(){
+if(!this.isOver){
+return;
+}
+this.timerScale+=0.2;
+this._paint();
+if(this.timerScale<1){
+setTimeout(dojo.hitch(this,"_expandSlowly"),10);
+}
+},destroyRecursive:function(){
+dojo.disconnect(this._onMouseOutHandle);
+dojo.disconnect(this._onMouseMoveHandle);
+dojo.disconnect(this._addChildHandle);
+if(this.isFixed){
+dojo.disconnect(this._onScrollHandle);
+}
+dojo.disconnect(this._onResizeHandle);
+this.inherited("destroyRecursive",arguments);
+}});
+dojo.declare("dojox.widget.FisheyeListItem",[dijit._Widget,dijit._Templated,dijit._Contained],{iconSrc:"",label:"",id:"",templateString:"<div class=\"dojoxFisheyeListItem\">"+"  <img class=\"dojoxFisheyeListItemImage\" dojoAttachPoint=\"imgNode\" dojoAttachEvent=\"onmouseover:onMouseOver,onmouseout:onMouseOut,onclick:onClick\">"+"  <div class=\"dojoxFisheyeListItemLabel\" dojoAttachPoint=\"lblNode\"></div>"+"</div>",_isNode:function(wh){
+if(typeof Element=="function"){
+try{
+return wh instanceof Element;
+}
+catch(e){
+}
+}else{
+return wh&&!isNaN(wh.nodeType);
+}
+},_hasParent:function(_44){
+return Boolean(_44&&_44.parentNode&&this._isNode(_44.parentNode));
+},postCreate:function(){
+if((this.iconSrc.toLowerCase().substring(this.iconSrc.length-4)==".png")&&dojo.isIE<7){
+if(this._hasParent(this.imgNode)&&this.id!=""){
+var _45=this.imgNode.parentNode;
+_45.setAttribute("id",this.id);
+}
+this.imgNode.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.iconSrc+"', sizingMethod='scale')";
+this.imgNode.src=this._blankGif.toString();
+}else{
+if(this._hasParent(this.imgNode)&&this.id!=""){
+var _45=this.imgNode.parentNode;
+_45.setAttribute("id",this.id);
+}
+this.imgNode.src=this.iconSrc;
+}
+if(this.lblNode){
+this.lblNode.appendChild(document.createTextNode(this.label));
+}
+dojo.setSelectable(this.domNode,false);
+this.startup();
+},startup:function(){
+this.parent=this.getParent();
+},onMouseOver:function(e){
+if(!this.parent.isOver){
+this.parent._setActive(e);
+}
+if(this.label!=""){
+dojo.addClass(this.lblNode,"dojoxFishSelected");
+this.parent._positionLabel(this);
+}
+},onMouseOut:function(e){
+dojo.removeClass(this.lblNode,"dojoxFishSelected");
+},onClick:function(e){
+}});
+}
diff --git a/dojox/widget/FisheyeList/FisheyeList.css b/dojox/widget/FisheyeList/FisheyeList.css
new file mode 100644
index 0000000..c9b78a9
--- /dev/null
+++ b/dojox/widget/FisheyeList/FisheyeList.css
@@ -0,0 +1,24 @@
+.dojoxFisheyeListItemLabel {
+	font-family: Arial, Helvetica, sans-serif;
+	background-color: #eee;
+	border: 2px solid #666;
+	padding: 2px;
+	text-align: center;
+	position: absolute;
+	display: none;
+	white-space:pre; 
+}
+.dojoxFisheyeListItemLabel.dojoxFishSelected {
+	display: block;
+}
+.dojoxFisheyeListItemImage {
+	border: 0px;
+	position: absolute;
+}
+.dojoxFisheyeListItem {
+	position: absolute;
+	z-index: 2;
+}
+.dojoxFisheyeListBar {
+	position: relative;
+}
diff --git a/dojox/widget/FisheyeLite.js b/dojox/widget/FisheyeLite.js
new file mode 100644
index 0000000..cb87798
--- /dev/null
+++ b/dojox/widget/FisheyeLite.js
@@ -0,0 +1,42 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.FisheyeLite"]){
+dojo._hasResource["dojox.widget.FisheyeLite"]=true;
+dojo.provide("dojox.widget.FisheyeLite");
+dojo.experimental("dojox.widget.FisheyeLite");
+dojo.require("dijit._Widget");
+dojo.require("dojo.fx.easing");
+dojo.declare("dojox.widget.FisheyeLite",dijit._Widget,{durationIn:350,easeIn:dojo.fx.easing.backOut,durationOut:1420,easeOut:dojo.fx.easing.elasticOut,properties:null,unit:"px",constructor:function(_1,_2){
+this.properties=_1.properties||{fontSize:2.75};
+},postCreate:function(){
+this.inherited(arguments);
+this._target=dojo.query(".fisheyeTarget",this.domNode)[0]||this.domNode;
+this._makeAnims();
+this.connect(this.domNode,"onmouseover","show");
+this.connect(this.domNode,"onmouseout","hide");
+this.connect(this._target,"onclick","onClick");
+},show:function(){
+this._runningOut.stop();
+this._runningIn.play();
+},hide:function(){
+this._runningIn.stop();
+this._runningOut.play();
+},_makeAnims:function(){
+var _3={},_4={},cs=dojo.getComputedStyle(this._target);
+for(var p in this.properties){
+var _7=this.properties[p],_8=dojo.isObject(_7),v=parseInt(cs[p]);
+_4[p]={end:v,unit:this.unit};
+_3[p]=_8?_7:{end:_7*v,unit:this.unit};
+}
+this._runningIn=dojo.animateProperty({node:this._target,easing:this.easeIn,duration:this.durationIn,properties:_3});
+this._runningOut=dojo.animateProperty({node:this._target,duration:this.durationOut,easing:this.easeOut,properties:_4});
+this.connect(this._runningIn,"onEnd",dojo.hitch(this,"onSelected",this));
+},onClick:function(e){
+},onSelected:function(e){
+}});
+}
diff --git a/dojox/widget/Iterator.js b/dojox/widget/Iterator.js
new file mode 100644
index 0000000..65fc687
--- /dev/null
+++ b/dojox/widget/Iterator.js
@@ -0,0 +1,83 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.Iterator"]){
+dojo._hasResource["dojox.widget.Iterator"]=true;
+dojo.provide("dojox.widget.Iterator");
+dojo.require("dijit.Declaration");
+dojo.experimental("dojox.widget.Iterator");
+dojo.declare("dojox.widget.Iterator",[dijit.Declaration],{constructor:(function(){
+var _1=0;
+return function(){
+this.attrs=[];
+this.children=[];
+this.widgetClass="dojox.widget.Iterator._classes._"+(_1++);
+};
+})(),start:0,fetchMax:1000,query:{name:"*"},attrs:[],defaultValue:"",widgetCtor:null,dataValues:[],data:null,store:null,_srcIndex:0,_srcParent:null,_setSrcIndex:function(s){
+this._srcIndex=0;
+this._srcParent=s.parentNode;
+var ts=s;
+while(ts.previousSibling){
+this._srcIndex++;
+ts=ts.previousSibling;
+}
+},postscript:function(p,s){
+this._setSrcIndex(s);
+this.inherited("postscript",arguments);
+var wc=this.widgetCtor=dojo.getObject(this.widgetClass);
+this.attrs=dojo.map(wc.prototype.templateString.match(/\$\{([^\s\:\}]+)(?:\:([^\s\:\}]+))?\}/g),function(s){
+return s.slice(2,-1);
+});
+dojo.forEach(this.attrs,function(m){
+wc.prototype[m]="";
+});
+this.update();
+},clear:function(){
+if(this.children.length){
+this._setSrcIndex(this.children[0].domNode);
+}
+dojo.forEach(this.children,"item.destroy();");
+this.children=[];
+},update:function(){
+if(this.store){
+this.fetch();
+}else{
+this.onDataAvailable(this.data||this.dataValues);
+}
+},_addItem:function(_9,_a){
+if(dojo.isString(_9)){
+_9={value:_9};
+}
+var _b=new this.widgetCtor(_9);
+this.children.push(_b);
+dojo.place(_b.domNode,this._srcParent,this._srcIndex+_a);
+},getAttrValuesObj:function(_c){
+var _d={};
+if(dojo.isString(_c)){
+dojo.forEach(this.attrs,function(_e){
+_d[_e]=(_e=="value")?_c:this.defaultValue;
+},this);
+}else{
+dojo.forEach(this.attrs,function(_f){
+if(this.store){
+_d[_f]=this.store.getValue(_c,_f)||this.defaultValue;
+}else{
+_d[_f]=_c[_f]||this.defaultValue;
+}
+},this);
+}
+return _d;
+},onDataAvailable:function(_10){
+this.clear();
+dojo.forEach(_10,function(_11,idx){
+this._addItem(this.getAttrValuesObj(_11),idx);
+},this);
+},fetch:function(_13,_14,end){
+this.store.fetch({query:_13||this.query,start:_14||this.start,count:end||this.fetchMax,onComplete:dojo.hitch(this,"onDataAvailable")});
+}});
+dojox.widget.Iterator._classes={};
+}
diff --git a/dojox/widget/Loader.js b/dojox/widget/Loader.js
new file mode 100644
index 0000000..e35c96f
--- /dev/null
+++ b/dojox/widget/Loader.js
@@ -0,0 +1,49 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.Loader"]){
+dojo._hasResource["dojox.widget.Loader"]=true;
+dojo.provide("dojox.widget.Loader");
+dojo.deprecated("dojox.widget.Loader","","2.0");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.declare("dojox.widget.Loader",[dijit._Widget,dijit._Templated],{loadIcon:dojo.moduleUrl("dojox.widget.Loader","icons/loading.gif"),loadMessage:"Loading ...",hasVisuals:true,attachToPointer:true,duration:125,_offset:16,_pointerConnect:null,_xhrStart:null,_xhrEnd:null,templateString:"<div dojoAttachPoint=\"loadNode\" class=\"dojoxLoader\">"+"<img src=\"${loadIcon}\" class=\"dojoxLoaderIcon\"> <span dojoAttachPoint=\"loadMessageNode\" class=\"dojoxLoaderMessage\"></span>"+"</div>",post [...]
+if(!this.hasVisuals){
+this.loadNode.style.display="none";
+}else{
+if(this.attachToPointer){
+dojo.removeClass(this.loadNode,"dojoxLoader");
+dojo.addClass(this.loadNode,"dojoxLoaderPointer");
+}
+this._hide();
+}
+this._setMessage(this.loadMessage);
+this._xhrStart=this.connect(dojo,"_ioSetArgs","_show");
+this._xhrEnd=this.connect(dojo.Deferred.prototype,"_fire","_hide");
+},_setMessage:function(_1){
+this.loadMessageNode.innerHTML=_1;
+},_putLoader:function(e){
+dijit.placeOnScreen(this.loadNode,{x:e.clientX+this._offset,y:e.clientY+this._offset},["TL","BR"]);
+},_show:function(){
+dojo.publish("Loader",[{message:"started"}]);
+if(this.hasVisuals){
+if(this.attachToPointer){
+this._pointerConnect=this.connect(document,"onmousemove","_putLoader");
+}
+dojo.style(this.loadNode,{opacity:0,display:""});
+dojo.fadeIn({node:this.loadNode,duration:this.duration}).play();
+}
+},_hide:function(){
+dojo.publish("Loader",[{message:"ended"}]);
+if(this.hasVisuals){
+if(this.attachToPointer){
+this.disconnect(this._pointerConnect);
+}
+dojo.fadeOut({node:this.loadNode,duration:this.duration,onEnd:dojo.partial(dojo.style,this.loadNode,"display","none")}).play();
+}
+}});
+}
diff --git a/dojox/widget/Loader/Loader.css b/dojox/widget/Loader/Loader.css
new file mode 100644
index 0000000..f209d70
--- /dev/null
+++ b/dojox/widget/Loader/Loader.css
@@ -0,0 +1,24 @@
+.dojoxLoaderPointer {
+	position:absolute; 
+	z-index:999; 
+}
+.dojoxLoader {
+	float:right; 
+	position:fixed; 
+	height:25px;
+	width:100px; 
+	top:0;
+	right:0; 
+	padding:3px; 
+	border:1px solid #ccc;
+	background:#fff;  
+	min-width:42px; 
+}
+.dojoxLoaderIcon {
+	height:22px; width:22px; 
+	vertical-align:middle; 
+}
+.dojoxLoaderMessage {
+	font:8pt Arial,san-serif;
+	color:#666; 
+}
diff --git a/dojox/widget/Loader/icons/loading.gif b/dojox/widget/Loader/icons/loading.gif
new file mode 100644
index 0000000..6e7c8e5
Binary files /dev/null and b/dojox/widget/Loader/icons/loading.gif differ
diff --git a/dojox/widget/Pager.js b/dojox/widget/Pager.js
new file mode 100644
index 0000000..07450d5
--- /dev/null
+++ b/dojox/widget/Pager.js
@@ -0,0 +1,387 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.Pager"]){
+dojo._hasResource["dojox.widget.Pager"]=true;
+dojo.provide("dojox.widget.Pager");
+dojo.experimental("dojox.widget.Pager");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dojo.fx");
+dojo.declare("dojox.widget.Pager",[dijit._Widget,dijit._Templated],{templateString:"<div dojoAttachPoint=\"pagerContainer\" tabIndex=\"0\" dojoAttachEvent=\"onkeypress: _handleKey, onfocus: _a11yStyle, onblur:_a11yStyle\" class=\"${orientation}PagerContainer\">\n    <div class=\"pagerContainer\">\n\t\t<div dojoAttachPoint=\"pagerContainerStatus\" class=\"${orientation}PagerStatus\"></div>\n\t\t<div dojoAttachPoint=\"pagerContainerView\" class=\"${orientation}PagerView\">\n\t\t    <div do [...]
+var h=(this.orientation=="horizontal");
+dojo.mixin(this,{_totalPages:0,_currentPage:1,dirClass:"pager"+(h?"Horizontal":"Vertical"),iconNext:dojo.moduleUrl("dojox.widget","Pager/images/"+(h?"h":"v")+"Next.png"),iconPrevious:dojo.moduleUrl("dojox.widget","Pager/images/"+(h?"h":"v")+"Previous.png")});
+},postCreate:function(){
+this.inherited(arguments);
+this.store.fetch({onComplete:dojo.hitch(this,"_init")});
+},_a11yStyle:function(e){
+dojo[(e.type=="focus"?"addClass":"removeClass")](e.target,"pagerFocus");
+},_handleKey:function(e){
+var dk=dojo.keys;
+var _5=(e.charCode==dk.SPACE?dk.SPACE:e.keyCode);
+switch(_5){
+case dk.UP_ARROW:
+case dk.RIGHT_ARROW:
+case 110:
+case 78:
+e.preventDefault();
+this._pagerNext();
+break;
+case dk.DOWN_ARROW:
+case dk.LEFT_ARROW:
+case 112:
+case 80:
+e.preventDefault();
+this._pagerPrevious();
+break;
+case dk.ENTER:
+switch(e.target){
+case this.pagerNext:
+this._pagerNext();
+break;
+case this.pagerPrevious:
+this._pagerPrevious();
+break;
+}
+break;
+}
+},_init:function(_6){
+this.items=_6;
+this._renderPages();
+this._renderStatus();
+this._renderPager();
+},_renderPages:function(){
+var _7=this.pagerContainerView;
+var _h=(this.orientation=="horizontal");
+var _9=dojo.style;
+if(_h){
+var _a=dojo.marginBox(this.pagerContainerPager).h;
+var _b=dojo.marginBox(this.pagerContainerStatus).h;
+if(this.pagerPos!="center"){
+var _c=_a+_b;
+}else{
+var _c=_b;
+var _d=this.pagerIconNext.width;
+var _e=_9(_7,"width");
+var _f=_e-(2*_d);
+_9(_7,{width:_f+"px",marginLeft:this.pagerIconNext.width+"px",marginRight:this.pagerIconNext.width+"px"});
+}
+var _10=_9(this.pagerContainer,"height")-_c;
+_9(this.pagerContainerView,"height",_10+"px");
+var _11=Math.floor(_9(_7,"width")/this.itemsPage);
+if(this.statusPos=="trailing"){
+if(this.pagerPos!="center"){
+_9(_7,"marginTop",_a+"px");
+}
+_9(_7,"marginBottom",_b+"px");
+}else{
+_9(_7,"marginTop",_b+"px");
+if(this.pagerPos!="center"){
+_9(_7,"marginTop",_a+"px");
+}
+}
+}else{
+var _12=dojo.marginBox(this.pagerContainerPager).w;
+var _13=dojo.marginBox(this.pagerContainerStatus).w;
+var _14=_9(this.pagerContainer,"width");
+if(this.pagerPos!="center"){
+var _15=_12+_13;
+}else{
+var _15=_13;
+var _16=this.pagerIconNext.height;
+var _17=_9(_7,"height");
+var _18=_17-(2*_16);
+_9(_7,{height:_18+"px",marginTop:this.pagerIconNext.height+"px",marginBottom:this.pagerIconNext.height+"px"});
+}
+var _19=_9(this.pagerContainer,"width")-_15;
+_9(_7,"width",_19+"px");
+var _11=Math.floor(_9(_7,"height")/this.itemsPage);
+if(this.statusPos=="trailing"){
+if(this.pagerPos!="center"){
+_9(_7,"marginLeft",_12+"px");
+}
+_9(_7,"marginRight",_13+"px");
+}else{
+_9(_7,"marginLeft",_13+"px");
+if(this.pagerPos!="center"){
+_9(_7,"marginRight",_12+"px");
+}
+}
+}
+var _1a=dojo.getObject(this.itemClass);
+var _1b="padding"+(_h?"Left":"Top");
+var _1c="padding"+(_h?"Right":"Bottom");
+dojo.forEach(this.items,function(_1d,cnt){
+var _1f=dojo.create("div",{innerHTML:_1d.content});
+var _20=new _1a({id:this.id+"-item-"+(cnt+1)},_1f);
+this.pagerItems.appendChild(_20.domNode);
+var _21={};
+_21[(_h?"width":"height")]=(_11-this.itemSpace)+"px";
+var p=(_h?"height":"width");
+_21[p]=_9(_7,p)+"px";
+_9(_20.containerNode,_21);
+if(this.resizeChildren){
+_20.resizeChildren();
+}
+_20.parseChildren();
+_9(_20.domNode,"position","absolute");
+if(cnt<this.itemsPage){
+var pos=(cnt)*_11;
+var _24=(_h?"left":"top");
+var dir=(_h?"top":"left");
+_9(_20.domNode,dir,"0px");
+_9(_20.domNode,_24,pos+"px");
+}else{
+_9(_20.domNode,"top","-1000px");
+_9(_20.domNode,"left","-1000px");
+}
+_9(_20.domNode,_1c,(this.itemSpace/2)+"px");
+_9(_20.domNode,_1b,(this.itemSpace/2)+"px");
+},this);
+},_renderPager:function(){
+var tcp=this.pagerContainerPager;
+var _27="0px";
+var _h=(this.orientation=="horizontal");
+if(_h){
+if(this.statusPos=="center"){
+}else{
+if(this.statusPos=="trailing"){
+dojo.style(tcp,"top",_27);
+}else{
+dojo.style(tcp,"bottom",_27);
+}
+}
+dojo.style(this.pagerNext,"right",_27);
+dojo.style(this.pagerPrevious,"left",_27);
+}else{
+if(this.statusPos=="trailing"){
+dojo.style(tcp,"left",_27);
+}else{
+dojo.style(tcp,"right",_27);
+}
+dojo.style(this.pagerNext,"bottom",_27);
+dojo.style(this.pagerPrevious,"top",_27);
+}
+},_renderStatus:function(){
+this._totalPages=Math.ceil(this.items.length/this.itemsPage);
+this.iconWidth=0;
+this.iconHeight=0;
+this.iconsLoaded=0;
+this._iconConnects=[];
+for(var i=1;i<=this._totalPages;i++){
+var _2a=new Image();
+var _2b=i;
+dojo.connect(_2a,"onclick",dojo.hitch(this,function(_2c){
+this._pagerSkip(_2c);
+},_2b));
+this._iconConnects[_2b]=dojo.connect(_2a,"onload",dojo.hitch(this,function(_2d){
+this.iconWidth+=_2a.width;
+this.iconHeight+=_2a.height;
+this.iconsLoaded++;
+if(this._totalPages==this.iconsLoaded){
+if(this.orientation=="horizontal"){
+if(this.statusPos=="trailing"){
+if(this.pagerPos=="center"){
+var _2e=dojo.style(this.pagerContainer,"height");
+var _2f=dojo.style(this.pagerContainerStatus,"height");
+dojo.style(this.pagerContainerPager,"top",((_2e/2)-(_2f/2))+"px");
+}
+dojo.style(this.pagerContainerStatus,"bottom","0px");
+}else{
+if(this.pagerPos=="center"){
+var _2e=dojo.style(this.pagerContainer,"height");
+var _2f=dojo.style(this.pagerContainerStatus,"height");
+dojo.style(this.pagerContainerPager,"bottom",((_2e/2)-(_2f/2))+"px");
+}
+dojo.style(this.pagerContainerStatus,"top","0px");
+}
+var _30=(dojo.style(this.pagerContainer,"width")/2)-(this.iconWidth/2);
+dojo.style(this.pagerContainerStatus,"paddingLeft",_30+"px");
+}else{
+if(this.statusPos=="trailing"){
+if(this.pagerPos=="center"){
+var _31=dojo.style(this.pagerContainer,"width");
+var _32=dojo.style(this.pagerContainerStatus,"width");
+dojo.style(this.pagerContainerPager,"left",((_31/2)-(_32/2))+"px");
+}
+dojo.style(this.pagerContainerStatus,"right","0px");
+}else{
+if(this.pagerPos=="center"){
+var _31=dojo.style(this.pagerContainer,"width");
+var _32=dojo.style(this.pagerContainerStatus,"width");
+dojo.style(this.pagerContainerPager,"right",((_31/2)-(_32/2))+"px");
+}
+dojo.style(this.pagerContainerStatus,"left","0px");
+}
+var _30=(dojo.style(this.pagerContainer,"height")/2)-(this.iconHeight/2);
+dojo.style(this.pagerContainerStatus,"paddingTop",_30+"px");
+}
+}
+dojo.disconnect(this._iconConnects[_2d]);
+},_2b));
+if(i==this._currentPage){
+_2a.src=this.iconPageActive;
+}else{
+_2a.src=this.iconPage;
+}
+var _2b=i;
+dojo.addClass(_2a,this.orientation+"PagerIcon");
+dojo.attr(_2a,"id",this.id+"-status-"+i);
+this.pagerContainerStatus.appendChild(_2a);
+if(this.orientation=="vertical"){
+dojo.style(_2a,"display","block");
+}
+}
+},_pagerSkip:function(_33){
+if(this._currentPage==_33){
+return;
+}else{
+var _34;
+var _35;
+if(_33<this._currentPage){
+_34=this._currentPage-_33;
+_35=(this._totalPages+_33)-this._currentPage;
+}else{
+_34=(this._totalPages+this._currentPage)-_33;
+_35=_33-this._currentPage;
+}
+var b=(_35>_34);
+this._toScroll=(b?_34:_35);
+var cmd=(b?"_pagerPrevious":"_pagerNext");
+var _38=this.connect(this,"onScrollEnd",function(){
+this._toScroll--;
+if(this._toScroll<1){
+this.disconnect(_38);
+}else{
+this[cmd]();
+}
+});
+this[cmd]();
+}
+},_pagerNext:function(){
+if(this._anim){
+return;
+}
+var _39=[];
+for(var i=this._currentPage*this.itemsPage;i>(this._currentPage-1)*this.itemsPage;i--){
+if(!dojo.byId(this.id+"-item-"+i)){
+continue;
+}
+var _3b=dojo.byId(this.id+"-item-"+i);
+var _3c=dojo.marginBox(_3b);
+if(this.orientation=="horizontal"){
+var _3d=_3c.l-(this.itemsPage*_3c.w);
+_39.push(dojo.fx.slideTo({node:_3b,left:_3d,duration:this.duration}));
+}else{
+var _3d=_3c.t-(this.itemsPage*_3c.h);
+_39.push(dojo.fx.slideTo({node:_3b,top:_3d,duration:this.duration}));
+}
+}
+var _3e=this._currentPage;
+if(this._currentPage==this._totalPages){
+this._currentPage=1;
+}else{
+this._currentPage++;
+}
+var cnt=this.itemsPage;
+for(var i=this._currentPage*this.itemsPage;i>(this._currentPage-1)*this.itemsPage;i--){
+if(dojo.byId(this.id+"-item-"+i)){
+var _3b=dojo.byId(this.id+"-item-"+i);
+var _3c=dojo.marginBox(_3b);
+if(this.orientation=="horizontal"){
+var _40=(dojo.style(this.pagerContainerView,"width")+((cnt-1)*_3c.w))-1;
+dojo.style(_3b,"left",_40+"px");
+dojo.style(_3b,"top","0px");
+var _3d=_40-(this.itemsPage*_3c.w);
+_39.push(dojo.fx.slideTo({node:_3b,left:_3d,duration:this.duration}));
+}else{
+_40=(dojo.style(this.pagerContainerView,"height")+((cnt-1)*_3c.h))-1;
+dojo.style(_3b,"top",_40+"px");
+dojo.style(_3b,"left","0px");
+var _3d=_40-(this.itemsPage*_3c.h);
+_39.push(dojo.fx.slideTo({node:_3b,top:_3d,duration:this.duration}));
+}
+}
+cnt--;
+}
+this._anim=dojo.fx.combine(_39);
+var _41=this.connect(this._anim,"onEnd",function(){
+delete this._anim;
+this.onScrollEnd();
+this.disconnect(_41);
+});
+this._anim.play();
+dojo.byId(this.id+"-status-"+_3e).src=this.iconPage;
+dojo.byId(this.id+"-status-"+this._currentPage).src=this.iconPageActive;
+},_pagerPrevious:function(){
+if(this._anim){
+return;
+}
+var _42=[];
+for(var i=this._currentPage*this.itemsPage;i>(this._currentPage-1)*this.itemsPage;i--){
+if(!dojo.byId(this.id+"-item-"+i)){
+continue;
+}
+var _44=dojo.byId(this.id+"-item-"+i);
+var _45=dojo.marginBox(_44);
+if(this.orientation=="horizontal"){
+var _46=dojo.style(_44,"left")+(this.itemsPage*_45.w);
+_42.push(dojo.fx.slideTo({node:_44,left:_46,duration:this.duration}));
+}else{
+var _46=dojo.style(_44,"top")+(this.itemsPage*_45.h);
+_42.push(dojo.fx.slideTo({node:_44,top:_46,duration:this.duration}));
+}
+}
+var _47=this._currentPage;
+if(this._currentPage==1){
+this._currentPage=this._totalPages;
+}else{
+this._currentPage--;
+}
+var cnt=this.itemsPage;
+var j=1;
+for(var i=this._currentPage*this.itemsPage;i>(this._currentPage-1)*this.itemsPage;i--){
+if(dojo.byId(this.id+"-item-"+i)){
+var _44=dojo.byId(this.id+"-item-"+i);
+var _45=dojo.marginBox(_44);
+if(this.orientation=="horizontal"){
+var _4a=-(j*_45.w)+1;
+dojo.style(_44,"left",_4a+"px");
+dojo.style(_44,"top","0px");
+var _46=((cnt-1)*_45.w);
+_42.push(dojo.fx.slideTo({node:_44,left:_46,duration:this.duration}));
+var _46=_4a+(this.itemsPage*_45.w);
+_42.push(dojo.fx.slideTo({node:_44,left:_46,duration:this.duration}));
+}else{
+_4a=-((j*_45.h)+1);
+dojo.style(_44,"top",_4a+"px");
+dojo.style(_44,"left","0px");
+var _46=((cnt-1)*_45.h);
+_42.push(dojo.fx.slideTo({node:_44,top:_46,duration:this.duration}));
+}
+}
+cnt--;
+j++;
+}
+this._anim=dojo.fx.combine(_42);
+var _4b=dojo.connect(this._anim,"onEnd",dojo.hitch(this,function(){
+delete this._anim;
+this.onScrollEnd();
+dojo.disconnect(_4b);
+}));
+this._anim.play();
+dojo.byId(this.id+"-status-"+_47).src=this.iconPage;
+dojo.byId(this.id+"-status-"+this._currentPage).src=this.iconPageActive;
+},onScrollEnd:function(){
+}});
+dojo.declare("dojox.widget._PagerItem",[dijit._Widget,dijit._Templated],{templateString:"<li class=\"pagerItem\" dojoAttachPoint=\"containerNode\"></li>",resizeChildren:function(){
+var box=dojo.marginBox(this.containerNode);
+dojo.style(this.containerNode.firstChild,{width:box.w+"px",height:box.h+"px"});
+},parseChildren:function(){
+dojo.parser.parse(this.containerNode);
+}});
+}
diff --git a/dojox/widget/Pager/Pager.css b/dojox/widget/Pager/Pager.css
new file mode 100644
index 0000000..df6bc82
--- /dev/null
+++ b/dojox/widget/Pager/Pager.css
@@ -0,0 +1,73 @@
+.pagerContainer {
+	position: relative;
+	height: 100%;
+	width: 100%;
+	overflow: hidden;
+	
+	border:1px solid #ccc;
+	-moz-border-radius:6pt;
+	-webkit-border-radius:7pt;
+}
+.horizontalPagerPager {
+	position: absolute;
+	height: 12px;
+	width: 100%;
+	padding-top: 4px;
+	padding-bottom: 4px;
+}
+.horizontalPagerStatus {
+	position: absolute;
+	height: 10px;
+	padding-top: 5px;
+	padding-bottom: 5px;
+	width: 100%;
+}
+.horizontalPagerView {
+	position: absolute;
+	height: 100%;
+	width: 100%;
+	overflow: hidden;
+}
+.horizontalPagerIcon {
+	cursor: pointer;	
+}
+.verticalPagerPager {
+	position: absolute;
+	width: 12px;
+	height: 100%;
+	padding-left: 4px;
+	padding-right: 4px;
+}
+.verticalPagerStatus {
+	position: absolute;
+	width: 10px;
+	padding-left: 5px;
+	padding-right: 5px;
+	height: 100%;
+}
+.verticalPagerView {
+	position: absolute;
+	height: 100%;
+	width: 100%;
+	overflow: hidden;
+}
+.verticalPagerIcon {
+	cursor: pointer;	
+}
+.pagerIconContainer {
+	position: absolute;	
+}
+.pagerIconContainer img {
+	cursor: pointer;	
+}
+.pagerItems {
+	list-style: none;
+	padding: 0;
+	margin: 0;	
+}
+	
+.pagerItem {
+	overflow: hidden;
+	padding: 0;
+	margin: 0;
+}
diff --git a/dojox/widget/Pager/Pager.html b/dojox/widget/Pager/Pager.html
new file mode 100644
index 0000000..3a7b3c7
--- /dev/null
+++ b/dojox/widget/Pager/Pager.html
@@ -0,0 +1,13 @@
+<div dojoAttachPoint="pagerContainer" tabIndex="0" dojoAttachEvent="onkeypress: _handleKey, onfocus: _a11yStyle, onblur:_a11yStyle" class="${orientation}PagerContainer">
+    <div class="pagerContainer">
+		<div dojoAttachPoint="pagerContainerStatus" class="${orientation}PagerStatus"></div>
+		<div dojoAttachPoint="pagerContainerView" class="${orientation}PagerView">
+		    <div dojoAttachPoint="pagerItemContainer"><ul dojoAttachPoint="pagerItems" class="pagerItems"></ul></div>
+		</div>
+		<div dojoAttachPoint="pagerContainerPager" class="${orientation}PagerPager">
+			<div tabIndex="0" dojoAttachPoint="pagerNext" class="pagerIconContainer" dojoAttachEvent="onclick: _pagerNext"><img dojoAttachPoint="pagerIconNext" src="${iconNext}" alt="Next" /></div>
+			<div tabIndex="0" dojoAttachPoint="pagerPrevious" class="pagerIconContainer" dojoAttachEvent="onclick: _pagerPrevious"><img dojoAttachPoint="pagerIconPrevious" src="${iconPrevious}" alt="Previous" /></div>
+		</div>
+    </div>
+	<div dojoAttachPoint="containerNode" style="display:none"></div>
+</div>
\ No newline at end of file
diff --git a/dojox/widget/Pager/images/hNext.png b/dojox/widget/Pager/images/hNext.png
new file mode 100644
index 0000000..037503f
Binary files /dev/null and b/dojox/widget/Pager/images/hNext.png differ
diff --git a/dojox/widget/Pager/images/hPrevious.png b/dojox/widget/Pager/images/hPrevious.png
new file mode 100644
index 0000000..3d4768a
Binary files /dev/null and b/dojox/widget/Pager/images/hPrevious.png differ
diff --git a/dojox/widget/Pager/images/pageActive.png b/dojox/widget/Pager/images/pageActive.png
new file mode 100644
index 0000000..087d5bc
Binary files /dev/null and b/dojox/widget/Pager/images/pageActive.png differ
diff --git a/dojox/widget/Pager/images/pageInactive.png b/dojox/widget/Pager/images/pageInactive.png
new file mode 100644
index 0000000..66ff3f4
Binary files /dev/null and b/dojox/widget/Pager/images/pageInactive.png differ
diff --git a/dojox/widget/Pager/images/vNext.png b/dojox/widget/Pager/images/vNext.png
new file mode 100644
index 0000000..7a373b8
Binary files /dev/null and b/dojox/widget/Pager/images/vNext.png differ
diff --git a/dojox/widget/Pager/images/vPrevious.png b/dojox/widget/Pager/images/vPrevious.png
new file mode 100644
index 0000000..8c497af
Binary files /dev/null and b/dojox/widget/Pager/images/vPrevious.png differ
diff --git a/dojox/widget/PlaceholderMenuItem.js b/dojox/widget/PlaceholderMenuItem.js
new file mode 100644
index 0000000..8fbd05f
--- /dev/null
+++ b/dojox/widget/PlaceholderMenuItem.js
@@ -0,0 +1,75 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.PlaceholderMenuItem"]){
+dojo._hasResource["dojox.widget.PlaceholderMenuItem"]=true;
+dojo.provide("dojox.widget.PlaceholderMenuItem");
+dojo.require("dijit.Menu");
+dojo.declare("dojox.widget.PlaceholderMenuItem",dijit.MenuItem,{_replaced:false,_replacedWith:null,_isPlaceholder:true,postCreate:function(){
+this.domNode.style.display="none";
+this._replacedWith=[];
+if(!this.label){
+this.label=this.containerNode.innerHTML;
+}
+this.inherited(arguments);
+},replace:function(_1){
+if(this._replaced){
+return false;
+}
+var _2=this.getIndexInParent();
+if(_2<0){
+return false;
+}
+var p=this.getParent();
+dojo.forEach(_1,function(_4){
+p.addChild(_4,_2++);
+});
+this._replacedWith=_1;
+this._replaced=true;
+return true;
+},unReplace:function(_5){
+if(!this._replaced){
+return [];
+}
+var p=this.getParent();
+if(!p){
+return [];
+}
+var r=this._replacedWith;
+dojo.forEach(this._replacedWith,function(_8){
+p.removeChild(_8);
+if(_5){
+_8.destroy();
+}
+});
+this._replacedWith=[];
+this._replaced=false;
+return r;
+}});
+dojo.extend(dijit.Menu,{getPlaceholders:function(_9){
+var r=[];
+var _b=this.getChildren();
+_b.forEach(function(_c){
+if(_c._isPlaceholder&&(!_9||_c.label==_9)){
+r.push(_c);
+}else{
+if(_c._started&&_c.popup&&_c.popup.getPlaceholders){
+r=r.concat(_c.popup.getPlaceholders(_9));
+}else{
+if(!_c._started&&_c.dropDownContainer){
+var _d=dojo.query("[widgetId]",_c.dropDownContainer)[0];
+var _e=dijit.byNode(_d);
+if(_e.getPlaceholders){
+r=r.concat(_e.getPlaceholders(_9));
+}
+}
+}
+}
+},this);
+return r;
+}});
+}
diff --git a/dojox/widget/README b/dojox/widget/README
new file mode 100644
index 0000000..e54122d
--- /dev/null
+++ b/dojox/widget/README
@@ -0,0 +1,168 @@
+-------------------------------------------------------------------------------
+dojox.widget Collection
+-------------------------------------------------------------------------------
+Version 1.0
+Release date: 10/31/2007
+-------------------------------------------------------------------------------
+Project state:
+
+[Calendar]	experimental
+[CalendarFx]	experimental
+[ColorPicker]	beta
+[Dialog]	experimental
+[FilePicker]	experimental
+[FisheyeList]	experimental
+[FisheyeLite]	beta
+[Iterator]	experimental
+[Loader]	experimental
+[Pager]		experimental
+[PlaceholderMenuItem]	experimental
+[Roller]	experimental
+[RollingList]	experimental
+[SortList]	experimental
+[Toaster]	experimental
+[Wizard]	experimental
+[AnalogGauge]   experimental
+[BarGauge]      experimental
+[Standby]	experimental
+-------------------------------------------------------------------------------
+Credits:
+
+[Calendar] Shane O'Sullivan
+[CalendarFx] Shane O'Sullivan
+[ColorPicker] Peter Higgins (dante)
+[Dialog] Peter Higgins (dante)
+[FilePicker] Nathan Toone (toonetown)
+[FisheyeList] Karl Tiedt (kteidt)
+[FisheyeLite] Peter Higgins (dante)
+[Iterator] Alex Russell (slightlyoff)
+[Loader] Peter Higgins (dante)
+[Pager] Nikolai Onken (nonken), Peter Higgins (dante);
+[PlaceholderMenuItem] Nathan Toone (toonetown)
+[Roller] Peter Higgins (dante)
+[RollingList] Nathan Toone (toonetown)
+[SortList] Peter Higgins (dante)
+[Toaster] Adam Peller (peller)
+[Wizard] Peter Higgins (dante)
+[AnalogGauge] Benjamin Schell (bmschell) CCLA
+[BarGauge] Benjamin Schell (bmschell) CCLA 
+[Standby] Jared Jurkiewicz (jaredj) CCLA 
+
+-------------------------------------------------------------------------------
+Project description
+
+	This is a collection of standalone widgets for use in
+	your website.  Each individual widget is independent
+	of the others.
+	
+-------------------------------------------------------------------------------
+Dependencies:
+
+	Each widget has it's own requirements and dependencies.
+	Most inherit from dijit base-classes such as dijit._Widget,
+	dijit._Templated, etc ... So we will assume the availablility
+	of dojo (core), and dijit packages.
+	
+	Each individual component stores resources in a folder that shares 
+	a name with the Widget. For instance:
+	
+	the Dialog lives in 
+	dojox/widget/Dialog.js ... 
+
+	and the folder:
+	dojox/widget/Dialog/ 	contains a 'Dialog.css', the required 
+	styles for that particular widget. All required templates and 
+	images reside in the folder. 
+	
+	This differs slightly from the rest of DojoX in that each other
+	project uses a shared resources/ folder in the project folder,
+	though uses the same naming convention for stylesheets and templates.
+
+	eg:
+	dojox/layout/resources/ExpandoPane.css
+	dojox.layout.ExpandoPane
+	
+-------------------------------------------------------------------------------
+Documentation
+
+	Please refer to the API-tool, or in-line documentation. All of these
+	widgets are of varying use, quality, and documentation completion.
+	
+-------------------------------------------------------------------------------
+Installation instructions
+
+	These are standalone Widgets, so putting the [widget].js file 
+	in your dojox/widget folder, and copying any files in the
+	/dojox/widget/[widget]/ folder as supplements/templates/etc
+	should be all you need to do.
+
+	eg: FisheyeList:
+	/dojox/widget/FisheyeList.js
+	/dojox/widget/FisheyeList/FisheyeList.css
+
+	should be all you need to use the Fisheye widget.	
+	
+	you can safely import the whole widget project into your 
+	dojox/ root directory from the following SVN url:
+
+	http://svn.dojotoolkit.org/src/dojox/trunk/widget
+
+-------------------------------------------------------------------------------
+Other Notes (Brief widget list):
+
+    * ColorPicker - An HSV ColorPicker intended to be a drop down
+
+	* Calendar - An extension on the dijit._Calendar providing a different UI
+	* CalendarFx - additional mixable FX for transitions in dojox.widget.Calendar
+
+	* Dialog - An extended version of dijit.Dialog with man options and transition.
+
+	* FilePicker - a widget for browsing server-side file systems (can use
+		dojox.data.FileStore as backend store)
+
+	* FisheyeList - the classic FishEye Picker (abandoned)
+
+	* FisheyeLite - A partial replacement for the FisheyeList - serious performance
+		gains, and entirely more extensible in that it simply animates defined
+		properties, relying on the natural styling as a foundation.
+
+	* Iterator - Basic array and data store iterator class
+	
+	* Loader - an experimental Class that listens to XHR 
+		connections in the background, and displays 
+		a loading indicator. Loader will be removed in 1.3, and is (abandoned).
+
+	* PlaceholderMenuItem - a menu item that can be used to inject other menu
+		items at a given location. Extends dijit.Menu directly. 
+
+	* Roller - A component to show many lines of text in a single area, rotating
+		through the options available. Also provides RollerSlide, an extension
+		to the stock fading roller to add a slide animation to the transition.
+
+	* RollingList - A component of the FilePicker widget
+
+	* SortList - a degradable UL with a fixed header, scrolling,
+		and sorting. Can be the direct descendant of a
+		LayoutContainer and will size to fit.
+
+	* Toaster - a messaging system to display unobtrusive 
+		alerts on screen.
+
+	* Wizard - a StackContainer with built-in navigation to
+		ease in the creation of 'step-based' content.
+		Requires dojo >= 1.1 
+                
+	* AnalogGauge - an analog style customizable gauge for displaying values in an
+		animated fashion and with multiple indicators.  Supports easings for 
+		indicator animations, transparent overlays, etc.  Very flexible.
+		Requires dojo >= 1.3
+	
+	* BarGauge - a bar style gauge for displaying values in an animated fashion 
+		and with multiple indicators.  Supports easings for indicator animations,
+		etc.  Very flexible.
+		Requires dojo >= 1.3
+
+	* Standby - a 'blocker' style widget to overlay a translucent div + image over a DOM node/widget to indicate busy.
+		Overlay color, image, and alt text can all be customized.
+		Requires dojo >= 1.3
+
diff --git a/dojox/widget/Roller.js b/dojox/widget/Roller.js
new file mode 100644
index 0000000..9bb5e02
--- /dev/null
+++ b/dojox/widget/Roller.js
@@ -0,0 +1,84 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.Roller"]){
+dojo._hasResource["dojox.widget.Roller"]=true;
+dojo.provide("dojox.widget.Roller");
+dojo.require("dijit._Widget");
+dojo.declare("dojox.widget.Roller",dijit._Widget,{delay:2000,autoStart:true,itemSelector:"> li",durationIn:400,durationOut:275,_idx:-1,postCreate:function(){
+if(!this["items"]){
+this.items=[];
+}
+dojo.addClass(this.domNode,"dojoxRoller");
+dojo.query(this.itemSelector,this.domNode).forEach(function(_1,i){
+this.items.push(_1.innerHTML);
+if(i==0){
+this._roller=_1;
+this._idx=0;
+}else{
+dojo.destroy(_1);
+}
+},this);
+if(!this._roller){
+this._roller=dojo.create("li",null,this.domNode);
+}
+this.makeAnims();
+if(this.autoStart){
+this.start();
+}
+},makeAnims:function(){
+var n=this.domNode;
+dojo.mixin(this,{_anim:{"in":dojo.fadeIn({node:n,duration:this.durationIn}),"out":dojo.fadeOut({node:n,duration:this.durationOut})}});
+this._setupConnects();
+},_setupConnects:function(){
+var _4=this._anim;
+this.connect(_4["out"],"onEnd",function(){
+this._set(this._idx+1);
+_4["in"].play(15);
+});
+this.connect(_4["in"],"onEnd",function(){
+this._timeout=setTimeout(dojo.hitch(this,"_run"),this.delay);
+});
+},start:function(){
+if(!this.rolling){
+this.rolling=true;
+this._run();
+}
+},_run:function(){
+this._anim["out"].gotoPercent(0,true);
+},stop:function(){
+this.rolling=false;
+var m=this._anim,t=this._timeout;
+if(t){
+clearTimeout(t);
+}
+m["in"].stop();
+m["out"].stop();
+},_set:function(i){
+var l=this.items.length-1;
+if(i<0){
+i=l;
+}
+if(i>l){
+i=0;
+}
+this._roller.innerHTML=this.items[i]||"error!";
+this._idx=i;
+}});
+dojo.declare("dojox.widget.RollerSlide",dojox.widget.Roller,{durationOut:175,makeAnims:function(){
+var n=this.domNode,_a="position",_b={top:{end:0,start:25},opacity:1};
+dojo.style(n,_a,"relative");
+dojo.style(this._roller,_a,"absolute");
+dojo.mixin(this,{_anim:{"in":dojo.animateProperty({node:n,duration:this.durationIn,properties:_b}),"out":dojo.fadeOut({node:n,duration:this.durationOut})}});
+this._setupConnects();
+}});
+dojo.declare("dojox.widget._RollerHover",null,{postCreate:function(){
+this.inherited(arguments);
+this.connect(this.domNode,"onmouseenter","stop");
+this.connect(this.domNode,"onmouseleave","start");
+}});
+}
diff --git a/dojox/widget/RollingList.js b/dojox/widget/RollingList.js
new file mode 100644
index 0000000..196f40d
--- /dev/null
+++ b/dojox/widget/RollingList.js
@@ -0,0 +1,914 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.RollingList"]){
+dojo._hasResource["dojox.widget.RollingList"]=true;
+dojo.provide("dojox.widget.RollingList");
+dojo.experimental("dojox.widget.RollingList");
+dojo.require("dijit._Templated");
+dojo.require("dijit.layout.ContentPane");
+dojo.require("dijit.layout._LayoutWidget");
+dojo.require("dijit.Menu");
+dojo.require("dojox.html.metrics");
+dojo.require("dijit.form.Button");
+dojo.require("dojo.i18n");
+dojo.requireLocalization("dojox.widget","RollingList",null,"ROOT,ca,sk,sl,th");
+dojo.requireLocalization("dijit","common",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.declare("dojox.widget._RollingListPane",[dijit.layout.ContentPane,dijit._Templated,dijit._Contained],{templateString:"<div class=\"dojoxRollingListPane\"><table><tbody><tr><td dojoAttachPoint=\"containerNode\"></td></tr></tbody></div>",parentWidget:null,parentPane:null,store:null,items:null,query:null,queryOptions:null,_focusByNode:true,minWidth:0,_setContentAndScroll:function(_1,_2){
+this._setContent(_1,_2);
+this.parentWidget.scrollIntoView(this);
+},_updateNodeWidth:function(n,_4){
+n.style.width="";
+var _5=dojo.marginBox(n).w;
+if(_5<_4){
+dojo.marginBox(n,{w:_4});
+}
+},_onMinWidthChange:function(v){
+this._updateNodeWidth(this.domNode,v);
+},_setMinWidthAttr:function(v){
+if(v!==this.minWidth){
+this.minWidth=v;
+this._onMinWidthChange(v);
+}
+},startup:function(){
+if(this._started){
+return;
+}
+if(this.store&&this.store.getFeatures()["dojo.data.api.Notification"]){
+window.setTimeout(dojo.hitch(this,function(){
+this.connect(this.store,"onSet","_onSetItem");
+this.connect(this.store,"onNew","_onNewItem");
+this.connect(this.store,"onDelete","_onDeleteItem");
+}),1);
+}
+this.connect(this.focusNode||this.domNode,"onkeypress","_focusKey");
+this.parentWidget._updateClass(this.domNode,"Pane");
+this.inherited(arguments);
+this._onMinWidthChange(this.minWidth);
+},_focusKey:function(e){
+if(e.charOrCode==dojo.keys.BACKSPACE){
+dojo.stopEvent(e);
+return;
+}else{
+if(e.charOrCode==dojo.keys.LEFT_ARROW&&this.parentPane){
+this.parentPane.focus();
+this.parentWidget.scrollIntoView(this.parentPane);
+}else{
+if(e.charOrCode==dojo.keys.ENTER){
+this.parentWidget._onExecute();
+}
+}
+}
+},focus:function(_9){
+if(this.parentWidget._focusedPane!=this){
+this.parentWidget._focusedPane=this;
+this.parentWidget.scrollIntoView(this);
+if(this._focusByNode&&(!this.parentWidget._savedFocus||_9)){
+try{
+(this.focusNode||this.domNode).focus();
+}
+catch(e){
+}
+}
+}
+},_loadCheck:function(){
+if(!this._started){
+var c=this.connect(this,"startup",function(){
+this.disconnect(c);
+this._loadCheck();
+});
+}
+var _b=this.domNode&&this._isShown();
+if((this.store||this.items)&&((this.refreshOnShow&&_b)||(!this.isLoaded&&_b))){
+this._loadQuery();
+}
+},_loadQuery:function(){
+this.isLoaded=false;
+if(this.items){
+this._setContentAndScroll(this.onLoadStart(),true);
+window.setTimeout(dojo.hitch(this,"_doQuery"),1);
+}else{
+this._doQuery();
+}
+},_doLoadItems:function(_c,_d){
+var _e=0,_f=this.store;
+dojo.forEach(_c,function(_10){
+if(!_f.isItemLoaded(_10)){
+_e++;
+}
+});
+if(_e===0){
+_d();
+}else{
+var _11=function(_12){
+_e--;
+if((_e)===0){
+_d();
+}
+};
+dojo.forEach(_c,function(_13){
+if(!_f.isItemLoaded(_13)){
+_f.loadItem({item:_13,onItem:_11});
+}
+});
+}
+},_doQuery:function(){
+var _14=this.parentWidget.preloadItems;
+_14=(_14===true||(this.items&&this.items.length<=Number(_14)));
+if(this.items&&_14){
+this._doLoadItems(this.items,dojo.hitch(this,"onItems"));
+}else{
+if(this.items){
+this.onItems();
+}else{
+this._setContentAndScroll(this.onFetchStart(),true);
+this.store.fetch({query:this.query,onComplete:function(_15){
+this.items=_15;
+this.onItems();
+},onError:function(e){
+this._onError("Fetch",e);
+},scope:this});
+}
+}
+},_hasItem:function(_17){
+var _18=this.items||[];
+for(var i=0,_1a;(_1a=_18[i]);i++){
+if(this.parentWidget._itemsMatch(_1a,_17)){
+return true;
+}
+}
+return false;
+},_onSetItem:function(_1b,_1c,_1d,_1e){
+if(this._hasItem(_1b)){
+this._loadCheck(true);
+}
+},_onNewItem:function(_1f,_20){
+var sel;
+if((!_20&&!this.parentPane)||(_20&&this.parentPane&&this.parentPane._hasItem(_20.item)&&(sel=this.parentPane._getSelected())&&this.parentWidget._itemsMatch(sel.item,_20.item))){
+this.items.push(_1f);
+this._loadCheck(true);
+}else{
+if(_20&&this.parentPane&&this._hasItem(_20.item)){
+this._loadCheck(true);
+}
+}
+},_onDeleteItem:function(_22){
+if(this._hasItem(_22)){
+this.items=dojo.filter(this.items,function(i){
+return (i!=_22);
+});
+this._loadCheck(true);
+}
+},onFetchStart:function(){
+return this.loadingMessage;
+},onFetchError:function(_24){
+return this.errorMessage;
+},onLoadStart:function(){
+return this.loadingMessage;
+},onLoadError:function(_25){
+return this.errorMessage;
+},onItems:function(){
+this._onLoadHandler();
+}});
+dojo.declare("dojox.widget._RollingListGroupPane",[dojox.widget._RollingListPane],{templateString:"<div><div dojoAttachPoint=\"containerNode\"></div>"+"<div dojoAttachPoint=\"menuContainer\">"+"<div dojoAttachPoint=\"menuNode\"></div>"+"</div></div>",_menu:null,_loadCheck:function(){
+var _26=this._isShown();
+if((this.store||this.items)&&((this.refreshOnShow&&_26)||(!this.isLoaded&&_26))){
+this._loadQuery();
+}
+},_setContent:function(_27){
+if(!this._menu){
+this.inherited(arguments);
+}
+},_onMinWidthChange:function(v){
+if(!this._menu){
+return;
+}
+var _29=dojo.marginBox(this.domNode).w;
+var _2a=dojo.marginBox(this._menu.domNode).w;
+this._updateNodeWidth(this._menu.domNode,v-(_29-_2a));
+},onItems:function(){
+var _2b,_2c=false;
+if(this._menu){
+_2b=this._getSelected();
+this._menu.destroyRecursive();
+}
+this._menu=this._getMenu();
+var _2d,_2e;
+if(this.items.length){
+dojo.forEach(this.items,function(_2f){
+_2d=this.parentWidget._getMenuItemForItem(_2f,this);
+if(_2d){
+if(_2b&&this.parentWidget._itemsMatch(_2d.item,_2b.item)){
+_2e=_2d;
+}
+this._menu.addChild(_2d);
+}
+},this);
+}else{
+_2d=this.parentWidget._getMenuItemForItem(null,this);
+if(_2d){
+this._menu.addChild(_2d);
+}
+}
+if(_2e){
+this._setSelected(_2e);
+if((_2b&&!_2b.children&&_2e.children)||(_2b&&_2b.children&&!_2e.children)){
+var _30=this.parentWidget._getPaneForItem(_2e.item,this,_2e.children);
+if(_30){
+this.parentWidget.addChild(_30,this.getIndexInParent()+1);
+}else{
+this.parentWidget._removeAfter(this);
+this.parentWidget._onItemClick(null,this,_2e.item,_2e.children);
+}
+}
+}else{
+if(_2b){
+this.parentWidget._removeAfter(this);
+}
+}
+this.containerNode.innerHTML="";
+this.containerNode.appendChild(this._menu.domNode);
+this.parentWidget.scrollIntoView(this);
+this._checkScrollConnection(true);
+this.inherited(arguments);
+this._onMinWidthChange(this.minWidth);
+},_checkScrollConnection:function(_31){
+var _32=this.store;
+if(this._scrollConn){
+this.disconnect(this._scrollConn);
+}
+delete this._scrollConn;
+if(!dojo.every(this.items,function(i){
+return _32.isItemLoaded(i);
+})){
+if(_31){
+this._loadVisibleItems();
+}
+this._scrollConn=this.connect(this.domNode,"onscroll","_onScrollPane");
+}
+},startup:function(){
+this.inherited(arguments);
+this.parentWidget._updateClass(this.domNode,"GroupPane");
+},focus:function(_34){
+if(this._menu){
+if(this._pendingFocus){
+this.disconnect(this._pendingFocus);
+}
+delete this._pendingFocus;
+var _35=this._menu.focusedChild;
+if(!_35){
+var _36=dojo.query(".dojoxRollingListItemSelected",this.domNode)[0];
+if(_36){
+_35=dijit.byNode(_36);
+}
+}
+if(!_35){
+_35=this._menu.getChildren()[0]||this._menu;
+}
+this._focusByNode=false;
+if(_35.focusNode){
+if(!this.parentWidget._savedFocus||_34){
+try{
+_35.focusNode.focus();
+}
+catch(e){
+}
+}
+window.setTimeout(function(){
+try{
+dijit.scrollIntoView(_35.focusNode);
+}
+catch(e){
+}
+},1);
+}else{
+if(_35.focus){
+if(!this.parentWidget._savedFocus||_34){
+_35.focus();
+}
+}else{
+this._focusByNode=true;
+}
+}
+this.inherited(arguments);
+}else{
+if(!this._pendingFocus){
+this._pendingFocus=this.connect(this,"onItems","focus");
+}
+}
+},_getMenu:function(){
+var _37=this;
+var _38=new dijit.Menu({parentMenu:this.parentPane?this.parentPane._menu:null,onCancel:function(_39){
+if(_37.parentPane){
+_37.parentPane.focus(true);
+}
+},_moveToPopup:function(evt){
+if(this.focusedChild&&!this.focusedChild.disabled){
+this.focusedChild._onClick(evt);
+}
+}},this.menuNode);
+this.connect(_38,"onItemClick",function(_3b,evt){
+if(_3b.disabled){
+return;
+}
+evt.alreadySelected=dojo.hasClass(_3b.domNode,"dojoxRollingListItemSelected");
+if(evt.alreadySelected&&((evt.type=="keypress"&&evt.charOrCode!=dojo.keys.ENTER)||(evt.type=="internal"))){
+var p=this.parentWidget.getChildren()[this.getIndexInParent()+1];
+if(p){
+p.focus(true);
+this.parentWidget.scrollIntoView(p);
+}
+}else{
+this._setSelected(_3b,_38);
+this.parentWidget._onItemClick(evt,this,_3b.item,_3b.children);
+if(evt.type=="keypress"&&evt.charOrCode==dojo.keys.ENTER){
+this.parentWidget._onExecute();
+}
+}
+});
+if(!_38._started){
+_38.startup();
+}
+return _38;
+},_onScrollPane:function(){
+if(this._visibleLoadPending){
+window.clearTimeout(this._visibleLoadPending);
+}
+this._visibleLoadPending=window.setTimeout(dojo.hitch(this,"_loadVisibleItems"),500);
+},_layoutHack:function(){
+if(dojo.isFF==2&&!this._layoutHackHandle){
+var _3e=this.domNode;
+var old=_3e.style.opacity;
+_3e.style.opacity="0.999";
+this._layoutHackHandle=setTimeout(dojo.hitch(this,function(){
+this._layoutHackHandle=null;
+_3e.style.opacity=old;
+}),0);
+}
+},_loadVisibleItems:function(){
+delete this._visibleLoadPending;
+var _40=this._menu;
+if(!_40){
+return;
+}
+var _41=_40.getChildren();
+if(!_41||!_41.length){
+return;
+}
+var _42=function(n,m,pb){
+var s=dojo.getComputedStyle(n);
+var r=0;
+if(m){
+r+=dojo._getMarginExtents(n,s).t;
+}
+if(pb){
+r+=dojo._getPadBorderExtents(n,s).t;
+}
+return r;
+};
+var _48=_42(this.domNode,false,true)+_42(this.containerNode,true,true)+_42(_40.domNode,true,true)+_42(_41[0].domNode,true,false);
+var h=dojo.contentBox(this.domNode).h;
+var _4a=this.domNode.scrollTop-_48-(h/2);
+var _4b=_4a+(3*h/2);
+var _4c=dojo.filter(_41,function(c){
+var cnt=c.domNode.offsetTop;
+var s=c.store;
+var i=c.item;
+return (cnt>=_4a&&cnt<=_4b&&!s.isItemLoaded(i));
+});
+var _51=dojo.map(_4c,function(c){
+return c.item;
+});
+var _53=dojo.hitch(this,function(){
+var _54=this._getSelected();
+var _55;
+dojo.forEach(_51,function(_56,idx){
+var _58=this.parentWidget._getMenuItemForItem(_56,this);
+var _59=_4c[idx];
+var _5a=_59.getIndexInParent();
+_40.removeChild(_59);
+if(_58){
+if(_54&&this.parentWidget._itemsMatch(_58.item,_54.item)){
+_55=_58;
+}
+_40.addChild(_58,_5a);
+if(_40.focusedChild==_59){
+_40.focusChild(_58);
+}
+}
+_59.destroy();
+},this);
+this._checkScrollConnection(false);
+this._layoutHack();
+});
+this._doLoadItems(_51,_53);
+},_getSelected:function(_5b){
+if(!_5b){
+_5b=this._menu;
+}
+if(_5b){
+var _5c=this._menu.getChildren();
+for(var i=0,_5e;(_5e=_5c[i]);i++){
+if(dojo.hasClass(_5e.domNode,"dojoxRollingListItemSelected")){
+return _5e;
+}
+}
+}
+return null;
+},_setSelected:function(_5f,_60){
+if(!_60){
+_60=this._menu;
+}
+if(_60){
+dojo.forEach(_60.getChildren(),function(i){
+this.parentWidget._updateClass(i.domNode,"Item",{"Selected":(_5f&&(i==_5f&&!i.disabled))});
+},this);
+}
+},destroy:function(){
+if(this._layoutHackHandle){
+clearTimeout(this._layoutHackHandle);
+}
+this.inherited(arguments);
+}});
+dojo.declare("dojox.widget.RollingList",[dijit._Widget,dijit._Templated,dijit._Container],{templateString:"<div class=\"dojoxRollingList ${className}\"\n\t><div class=\"dojoxRollingListContainer\" dojoAttachPoint=\"containerNode\" dojoAttachEvent=\"onkeypress:_onKey\"\n\t></div\n\t><div class=\"dojoxRollingListButtons\" dojoAttachPoint=\"buttonsNode\"\n        ><button dojoType=\"dijit.form.Button\" dojoAttachPoint=\"okButton\"\n\t\t\t\tdojoAttachEvent=\"onClick:_onExecute\">${okButtonLa [...]
+this.inherited(arguments);
+var loc=dojo.i18n.getLocalization("dijit","common");
+this.okButtonLabel=this.okButtonLabel||loc.buttonOk;
+this.cancelButtonLabel=this.cancelButtonLabel||loc.buttonCancel;
+},_setShowButtonsAttr:function(_63){
+var _64=false;
+if((this.showButtons!=_63&&this._started)||(this.showButtons==_63&&!this.started)){
+_64=true;
+}
+dojo.toggleClass(this.domNode,"dojoxRollingListButtonsHidden",!_63);
+this.showButtons=_63;
+if(_64){
+if(this._started){
+this.layout();
+}else{
+window.setTimeout(dojo.hitch(this,"layout"),0);
+}
+}
+},_itemsMatch:function(_65,_66){
+if(!_65&&!_66){
+return true;
+}else{
+if(!_65||!_66){
+return false;
+}
+}
+return (_65==_66||(this._isIdentity&&this.store.getIdentity(_65)==this.store.getIdentity(_66)));
+},_removeAfter:function(idx){
+if(typeof idx!="number"){
+idx=this.getIndexOfChild(idx);
+}
+if(idx>=0){
+dojo.forEach(this.getChildren(),function(c,i){
+if(i>idx){
+this.removeChild(c);
+c.destroyRecursive();
+}
+},this);
+}
+var _6a=this.getChildren(),_6b=_6a[_6a.length-1];
+var _6c=null;
+while(_6b&&!_6c){
+var val=_6b._getSelected?_6b._getSelected():null;
+if(val){
+_6c=val.item;
+}
+_6b=_6b.parentPane;
+}
+if(!this._setInProgress){
+this._setValue(_6c);
+}
+},addChild:function(_6e,_6f){
+if(_6f>0){
+this._removeAfter(_6f-1);
+}
+this.inherited(arguments);
+if(!_6e._started){
+_6e.startup();
+}
+_6e.attr("minWidth",this.minPaneWidth);
+this.layout();
+if(!this._savedFocus){
+_6e.focus();
+}
+},_setMinPaneWidthAttr:function(_70){
+if(_70!==this.minPaneWidth){
+this.minPaneWidth=_70;
+dojo.forEach(this.getChildren(),function(c){
+c.attr("minWidth",_70);
+});
+}
+},_updateClass:function(_72,_73,_74){
+if(!this._declaredClasses){
+this._declaredClasses=("dojoxRollingList "+this.className).split(" ");
+}
+dojo.forEach(this._declaredClasses,function(c){
+if(c){
+dojo.addClass(_72,c+_73);
+for(var k in _74||{}){
+dojo.toggleClass(_72,c+_73+k,_74[k]);
+}
+dojo.toggleClass(_72,c+_73+"FocusSelected",(dojo.hasClass(_72,c+_73+"Focus")&&dojo.hasClass(_72,c+_73+"Selected")));
+dojo.toggleClass(_72,c+_73+"HoverSelected",(dojo.hasClass(_72,c+_73+"Hover")&&dojo.hasClass(_72,c+_73+"Selected")));
+}
+});
+},scrollIntoView:function(_77){
+if(this._scrollingTimeout){
+window.clearTimeout(this._scrollingTimeout);
+}
+delete this._scrollingTimeout;
+this._scrollingTimeout=window.setTimeout(dojo.hitch(this,function(){
+if(_77.domNode){
+dijit.scrollIntoView(_77.domNode);
+}
+delete this._scrollingTimeout;
+return;
+}),1);
+},resize:function(_78){
+dijit.layout._LayoutWidget.prototype.resize.call(this,_78);
+},layout:function(){
+var _79=this.getChildren();
+if(this._contentBox){
+var bn=this.buttonsNode;
+var _7b=this._contentBox.h-dojo.marginBox(bn).h-dojox.html.metrics.getScrollbar().h;
+dojo.forEach(_79,function(c){
+dojo.marginBox(c.domNode,{h:_7b});
+});
+}
+if(this._focusedPane){
+var foc=this._focusedPane;
+delete this._focusedPane;
+if(!this._savedFocus){
+foc.focus();
+}
+}else{
+if(_79&&_79.length){
+if(!this._savedFocus){
+_79[0].focus();
+}
+}
+}
+},_onChange:function(_7e){
+this.onChange(_7e);
+},_setValue:function(_7f){
+delete this._setInProgress;
+if(!this._itemsMatch(this.value,_7f)){
+this.value=_7f;
+this._onChange(_7f);
+}
+},_setValueAttr:function(_80){
+if(this._itemsMatch(this.value,_80)&&!_80){
+return;
+}
+if(this._setInProgress&&this._setInProgress===_80){
+return;
+}
+this._setInProgress=_80;
+if(!_80||!this.store.isItem(_80)){
+var _81=this.getChildren()[0];
+_81._setSelected(null);
+this._onItemClick(null,_81,null,null);
+return;
+}
+var _82=dojo.hitch(this,function(_83,_84){
+var _85=this.store,id;
+if(this.parentAttr&&_85.getFeatures()["dojo.data.api.Identity"]&&((id=this.store.getValue(_83,this.parentAttr))||id==="")){
+var cb=function(i){
+if(_85.getIdentity(i)==_85.getIdentity(_83)){
+_84(null);
+}else{
+_84([i]);
+}
+};
+if(id===""){
+_84(null);
+}else{
+if(typeof id=="string"){
+_85.fetchItemByIdentity({identity:id,onItem:cb});
+}else{
+if(_85.isItem(id)){
+cb(id);
+}
+}
+}
+}else{
+var _89=this.childrenAttrs.length;
+var _8a=[];
+dojo.forEach(this.childrenAttrs,function(_8b){
+var q={};
+q[_8b]=_83;
+_85.fetch({query:q,scope:this,onComplete:function(_8d){
+if(this._setInProgress!==_80){
+return;
+}
+_8a=_8a.concat(_8d);
+_89--;
+if(_89===0){
+_84(_8a);
+}
+}});
+},this);
+}
+});
+var _8e=dojo.hitch(this,function(_8f,idx){
+var set=_8f[idx];
+var _92=this.getChildren()[idx];
+var _93;
+if(set&&_92){
+var fx=dojo.hitch(this,function(){
+if(_93){
+this.disconnect(_93);
+}
+delete _93;
+if(this._setInProgress!==_80){
+return;
+}
+var _95=dojo.filter(_92._menu.getChildren(),function(i){
+return this._itemsMatch(i.item,set);
+},this)[0];
+if(_95){
+idx++;
+_92._menu.onItemClick(_95,{type:"internal",stopPropagation:function(){
+},preventDefault:function(){
+}});
+if(_8f[idx]){
+_8e(_8f,idx);
+}else{
+this._setValue(set);
+this.onItemClick(set,_92,this.getChildItems(set));
+}
+}
+});
+if(!_92.isLoaded){
+_93=this.connect(_92,"onLoad",fx);
+}else{
+fx();
+}
+}else{
+if(idx===0){
+this.attr("value",null);
+}
+}
+});
+var _97=[];
+var _98=dojo.hitch(this,function(_99){
+if(_99&&_99.length){
+_97.push(_99[0]);
+_82(_99[0],_98);
+}else{
+if(!_99){
+_97.pop();
+}
+_97.reverse();
+_8e(_97,0);
+}
+});
+var ns=this.domNode.style;
+if(ns.display=="none"||ns.visibility=="hidden"){
+this._setValue(_80);
+}else{
+if(!this._itemsMatch(_80,this._visibleItem)){
+_98([_80]);
+}
+}
+},_onItemClick:function(evt,_9c,_9d,_9e){
+if(evt){
+var _9f=this._getPaneForItem(_9d,_9c,_9e);
+var _a0=(evt.type=="click"&&evt.alreadySelected);
+if(_a0&&_9f){
+this._removeAfter(_9c.getIndexInParent()+1);
+var _a1=_9c.getNextSibling();
+if(_a1&&_a1._setSelected){
+_a1._setSelected(null);
+}
+this.scrollIntoView(_a1);
+}else{
+if(_9f){
+this.addChild(_9f,_9c.getIndexInParent()+1);
+if(this._savedFocus){
+_9f.focus(true);
+}
+}else{
+this._removeAfter(_9c);
+this.scrollIntoView(_9c);
+}
+}
+}else{
+if(_9c){
+this._removeAfter(_9c);
+this.scrollIntoView(_9c);
+}
+}
+if(!evt||evt.type!="internal"){
+this._setValue(_9d);
+this.onItemClick(_9d,_9c,_9e);
+}
+this._visibleItem=_9d;
+},_getPaneForItem:function(_a2,_a3,_a4){
+var ret=this.getPaneForItem(_a2,_a3,_a4);
+ret.store=this.store;
+ret.parentWidget=this;
+ret.parentPane=_a3||null;
+if(!_a2){
+ret.query=this.query;
+ret.queryOptions=this.queryOptions;
+}else{
+if(_a4){
+ret.items=_a4;
+}else{
+ret.items=[_a2];
+}
+}
+return ret;
+},_getMenuItemForItem:function(_a6,_a7){
+var _a8=this.store;
+if(!_a6||!_a8||!_a8.isItem(_a6)){
+var i=new dijit.MenuItem({label:dojo.i18n.getLocalization("dojox.widget","RollingList",this.lang).empty,disabled:true,iconClass:"dojoxEmpty",focus:function(){
+}});
+this._updateClass(i.domNode,"Item");
+return i;
+}else{
+var _aa=_a8.isItemLoaded(_a6);
+var _ab=_aa?this.getChildItems(_a6):undefined;
+var _ac;
+if(_ab){
+_ac=this.getMenuItemForItem(_a6,_a7,_ab);
+_ac.children=_ab;
+this._updateClass(_ac.domNode,"Item",{"Expanding":true});
+if(!_ac._started){
+var c=_ac.connect(_ac,"startup",function(){
+this.disconnect(c);
+dojo.style(this.arrowWrapper,"display","");
+});
+}else{
+dojo.style(_ac.arrowWrapper,"display","");
+}
+}else{
+_ac=this.getMenuItemForItem(_a6,_a7,null);
+if(_aa){
+this._updateClass(_ac.domNode,"Item",{"Single":true});
+}else{
+this._updateClass(_ac.domNode,"Item",{"Unloaded":true});
+_ac.attr("disabled",true);
+}
+}
+_ac.store=this.store;
+_ac.item=_a6;
+if(!_ac.label){
+_ac.attr("label",this.store.getLabel(_a6).replace(/</,"<"));
+}
+if(_ac.focusNode){
+var _ae=this;
+_ac.focus=function(){
+if(!this.disabled){
+try{
+this.focusNode.focus();
+}
+catch(e){
+}
+}
+};
+_ac.connect(_ac.focusNode,"onmouseenter",function(){
+if(!this.disabled){
+_ae._updateClass(this.domNode,"Item",{"Hover":true});
+}
+});
+_ac.connect(_ac.focusNode,"onmouseleave",function(){
+if(!this.disabled){
+_ae._updateClass(this.domNode,"Item",{"Hover":false});
+}
+});
+_ac.connect(_ac.focusNode,"blur",function(){
+_ae._updateClass(this.domNode,"Item",{"Focus":false,"Hover":false});
+});
+_ac.connect(_ac.focusNode,"focus",function(){
+_ae._updateClass(this.domNode,"Item",{"Focus":true});
+_ae._focusedPane=_a7;
+});
+if(this.executeOnDblClick){
+_ac.connect(_ac.focusNode,"ondblclick",function(){
+_ae._onExecute();
+});
+}
+}
+return _ac;
+}
+},_setStore:function(_af){
+if(_af===this.store&&this._started){
+return;
+}
+this.store=_af;
+this._isIdentity=_af.getFeatures()["dojo.data.api.Identity"];
+var _b0=this._getPaneForItem();
+this.addChild(_b0,0);
+},_onKey:function(e){
+if(e.charOrCode==dojo.keys.BACKSPACE){
+dojo.stopEvent(e);
+return;
+}else{
+if(e.charOrCode==dojo.keys.ESCAPE&&this._savedFocus){
+try{
+dijit.focus(this._savedFocus);
+}
+catch(e){
+}
+dojo.stopEvent(e);
+return;
+}else{
+if(e.charOrCode==dojo.keys.LEFT_ARROW||e.charOrCode==dojo.keys.RIGHT_ARROW){
+dojo.stopEvent(e);
+return;
+}
+}
+}
+},_resetValue:function(){
+this.attr("value",this._lastExecutedValue);
+},_onCancel:function(){
+this._resetValue();
+this.onCancel();
+},_onExecute:function(){
+this._lastExecutedValue=this.attr("value");
+this.onExecute();
+},focus:function(){
+var _b2=this._savedFocus;
+this._savedFocus=dijit.getFocus(this);
+if(!this._savedFocus.node){
+delete this._savedFocus;
+}
+if(!this._focusedPane){
+var _b3=this.getChildren()[0];
+if(_b3&&!_b2){
+_b3.focus(true);
+}
+}else{
+this._savedFocus=dijit.getFocus(this);
+var foc=this._focusedPane;
+delete this._focusedPane;
+if(!_b2){
+foc.focus(true);
+}
+}
+},handleKey:function(e){
+if(e.charOrCode==dojo.keys.DOWN_ARROW){
+delete this._savedFocus;
+this.focus();
+return false;
+}else{
+if(e.charOrCode==dojo.keys.ESCAPE){
+this._onCancel();
+return false;
+}
+}
+return true;
+},_updateChildClasses:function(){
+var _b6=this.getChildren();
+var _b7=_b6.length;
+dojo.forEach(_b6,function(c,idx){
+dojo.toggleClass(c.domNode,"dojoxRollingListPaneCurrentChild",(idx==(_b7-1)));
+dojo.toggleClass(c.domNode,"dojoxRollingListPaneCurrentSelected",(idx==(_b7-2)));
+});
+},startup:function(){
+if(this._started){
+return;
+}
+if(!this.getParent||!this.getParent()){
+this.resize();
+this.connect(dojo.global,"onresize","resize");
+}
+this.connect(this,"addChild","_updateChildClasses");
+this.connect(this,"removeChild","_updateChildClasses");
+this._setStore(this.store);
+this.attr("showButtons",this.showButtons);
+this.inherited(arguments);
+this._lastExecutedValue=this.attr("value");
+},getChildItems:function(_ba){
+var _bb,_bc=this.store;
+dojo.forEach(this.childrenAttrs,function(_bd){
+var _be=_bc.getValues(_ba,_bd);
+if(_be&&_be.length){
+_bb=(_bb||[]).concat(_be);
+}
+});
+return _bb;
+},getMenuItemForItem:function(_bf,_c0,_c1){
+return new dijit.MenuItem({});
+},getPaneForItem:function(_c2,_c3,_c4){
+if(!_c2||_c4){
+return new dojox.widget._RollingListGroupPane({});
+}else{
+return null;
+}
+},onItemClick:function(_c5,_c6,_c7){
+},onExecute:function(){
+},onCancel:function(){
+},onChange:function(_c8){
+}});
+}
diff --git a/dojox/widget/RollingList/RollingList.css b/dojox/widget/RollingList/RollingList.css
new file mode 100644
index 0000000..6334510
--- /dev/null
+++ b/dojox/widget/RollingList/RollingList.css
@@ -0,0 +1,140 @@
+.dojoxRollingList {
+	border: 1px solid #000;
+	height: 20em;
+	background-color: #FFF;
+	position: relative;
+}
+.dijitPopup .dojoxRollingList {
+	position: static;
+}
+.dojoxRollingListContainer {
+	overflow: scroll;
+	overflow-y: hidden;
+	overflow-x: scroll;
+	white-space: nowrap;
+}
+.dojoxRollingListButtons {
+	position: absolute;
+	right: 5px;
+	padding: 5px 0px;
+}
+.dojoxRollingListButtonsHidden .dojoxRollingListButtons {
+	display: none;
+}
+.dojoxRollingListPane {
+	overflow: scroll;
+	overflow-x: hidden;
+	overflow-y: scroll;
+	display:-moz-inline-box;		
+	display:inline-block;			
+	#zoom: 1; 
+	#display:inline; 
+	border:0;
+	padding:0;
+	vertical-align:middle;
+	#vertical-align: auto;	
+}
+.dojoxRollingListPane .dijitMenuItem td {
+	width: 1px;
+}
+.dojoxRollingListPane .dijitMenuItem td.dijitMenuItemLabel {
+	width: auto;
+}
+.dojoxRollingListPane .dijitMenuItemLabel,
+.dojoxRollingListPane .dijitMenuItemIcon {
+	position: static !important;
+}
+.dj_webkit .dojoxRollingListPane,
+.dj_ie .dojoxRollingListPane {
+	padding-right: 15px; 
+}
+.dojoxRollingListPane .dijitMenu {
+	border: none !important;
+}
+.dojoxRollingListItem {
+	cursor: default;
+}
+.tundra .dojoxRollingList {
+	border-color: #b3b3b3;
+}
+.tundra .dijitPopup .dojoxRollingList {
+	border-color: #406b9b;
+}
+.tundra .dojoxRollingListPane {
+	background-color: #f7f7f7;
+}
+.tundra .dojoxRollingListPane .dojoxRollingListItemHover,
+.tundra .dojoxRollingListPane .dojoxRollingListItemFocus {
+	background-color: #e3e3e3;
+}
+.tundra .dojoxRollingListPane .dojoxRollingListItemSelected {
+	color: #fff;
+	background-color: #999;
+	font-weight: bold;
+}
+.tundra .dojoxRollingListPaneCurrentSelected .dojoxRollingListItemSelected {
+	background-color: #3559ac;
+}
+.tundra .dojoxRollingListPane .dojoxRollingListItemHoverSelected,
+.tundra .dojoxRollingListPane .dojoxRollingListItemFocusSelected {
+	background-color: #9aacd6;
+}
+.tundra .dojoxRollingListItem {
+	font-family: inherit;
+}
+.soria .dojoxRollingList {
+	border-color: #8ba0bd;
+}
+.soria .dijitPopup .dojoxRollingList {
+	border-color: #406b9b;
+}
+.soria .dojoxRollingListPane {
+	background-color: #fff;
+}
+.soria .dojoxRollingListPane .dojoxRollingListItemHover, 
+.soria .dojoxRollingListPane .dojoxRollingListItemFocus {
+	background-color: #e3e3e3;
+}
+.soria .dojoxRollingListPane .dojoxRollingListItemSelected {
+	color: #243C5F;
+	background-color: #ccc;
+	font-weight: bold;
+}
+.soria .dojoxRollingListPaneCurrentSelected .dojoxRollingListItemSelected {
+	background-color: #d9e6f9;
+}
+.soria .dojoxRollingListPane .dojoxRollingListItemHoverSelected,
+.soria .dojoxRollingListPane .dojoxRollingListItemFocusSelected {
+	background-color: #ecf3fc;
+}
+.soria .dojoxRollingListItem {
+	font-family: inherit;
+}
+.nihilo .dojoxRollingList {
+	border-color: #d3d3d3;
+}
+.nihilo .dijitPopup .dojoxRollingList {
+	border-color: #b3b3b3;
+}
+.nihilo .dojoxRollingListPane {
+	background-color: #fff;
+}
+.nihilo .dojoxRollingListPane .dojoxRollingListItemHover,
+.nihilo .dojoxRollingListPane .dojoxRollingListItemFocus {
+	background-color: #e3e3e3;
+}
+.nihilo .dojoxRollingListPane .dojoxRollingListItemSelected {
+	color: #243C5F;
+	background-color: #ccc;
+	font-weight: bold;
+}
+.nihilo .dojoxRollingListPaneCurrentSelected .dojoxRollingListItemSelected {
+	background-color: #ffe284;
+}
+.nihilo .dojoxRollingListPane .dojoxRollingListItemHoverSelected,
+.nihilo .dojoxRollingListPane .dojoxRollingListItemFocusSelected {
+	background-color: #fff1c2;
+}
+.nihilo .dojoxRollingListItem {
+	font-family: inherit;
+}
diff --git a/dojox/widget/RollingList/RollingList.html b/dojox/widget/RollingList/RollingList.html
new file mode 100644
index 0000000..ec26ebb
--- /dev/null
+++ b/dojox/widget/RollingList/RollingList.html
@@ -0,0 +1,10 @@
+<div class="dojoxRollingList ${className}"
+	><div class="dojoxRollingListContainer" dojoAttachPoint="containerNode" dojoAttachEvent="onkeypress:_onKey"
+	></div
+	><div class="dojoxRollingListButtons" dojoAttachPoint="buttonsNode"
+        ><button dojoType="dijit.form.Button" dojoAttachPoint="okButton"
+				dojoAttachEvent="onClick:_onExecute">${okButtonLabel}</button
+        ><button dojoType="dijit.form.Button" dojoAttachPoint="cancelButton"
+				dojoAttachEvent="onClick:_onCancel">${cancelButtonLabel}</button
+	></div
+></div>
diff --git a/dojox/widget/SortList.js b/dojox/widget/SortList.js
new file mode 100644
index 0000000..75b5ea5
--- /dev/null
+++ b/dojox/widget/SortList.js
@@ -0,0 +1,86 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.SortList"]){
+dojo._hasResource["dojox.widget.SortList"]=true;
+dojo.provide("dojox.widget.SortList");
+dojo.experimental("dojox.widget.SortList");
+dojo.require("dijit.layout._LayoutWidget");
+dojo.require("dijit._Templated");
+dojo.declare("dojox.widget.SortList",[dijit.layout._LayoutWidget,dijit._Templated],{title:"",heading:"",descending:true,selected:null,sortable:true,store:"",key:"name",baseClass:"dojoxSortList",templateString:"<div class=\"sortList\" id=\"${id}\">\n\t\t<div class=\"sortListTitle\" dojoAttachPoint=\"titleNode\">\n\t\t<div class=\"dijitInline sortListIcon\"> </div>\n\t\t<span dojoAttachPoint=\"focusNode\">${title}</span>\n\t\t</div>\n\t\t<div class=\"sortListBodyWrapper\" dojoAttach [...]
+dojo.create("li",{innerHTML:this.store.getValue(_1,this.key).replace(/</g,"<")},this.containerNode);
+},postCreate:function(){
+if(this.store){
+this.store=dojo.getObject(this.store);
+var _2={onItem:dojo.hitch(this,"_addItem"),onComplete:dojo.hitch(this,"onSort")};
+this.store.fetch(_2);
+}else{
+this.onSort();
+}
+this.inherited(arguments);
+},startup:function(){
+this.inherited(arguments);
+if(this.heading){
+this.setTitle(this.heading);
+this.title=this.heading;
+}
+setTimeout(dojo.hitch(this,"resize"),5);
+if(this.sortable){
+this.connect(this.titleNode,"onclick","onSort");
+}
+},resize:function(){
+this.inherited(arguments);
+var _3=((this._contentBox.h)-(dojo.style(this.titleNode,"height")))-10;
+this.bodyWrapper.style.height=Math.abs(_3)+"px";
+},onSort:function(e){
+var _5=dojo.query("li",this.domNode);
+if(this.sortable){
+this.descending=!this.descending;
+dojo.addClass(this.titleNode,((this.descending)?"sortListDesc":"sortListAsc"));
+dojo.removeClass(this.titleNode,((this.descending)?"sortListAsc":"sortListDesc"));
+_5.sort(this._sorter);
+if(this.descending){
+_5.reverse();
+}
+}
+var i=0;
+dojo.forEach(_5,function(_7){
+dojo[(i++)%2===0?"addClass":"removeClass"](_7,"sortListItemOdd");
+this.containerNode.appendChild(_7);
+},this);
+},_set:function(e){
+if(e.target!==this.bodyWrapper){
+dojo.addClass(e.target,"sortListItemHover");
+}
+},_unset:function(e){
+dojo.removeClass(e.target,"sortListItemHover");
+},_handleClick:function(e){
+dojo.toggleClass(e.target,"sortListItemSelected");
+e.target.focus();
+this._updateValues(e.target.innerHTML);
+},_updateValues:function(){
+this._selected=dojo.query("li.sortListItemSelected",this.containerNode);
+this.selected=[];
+dojo.forEach(this._selected,function(_b){
+this.selected.push(_b.innerHTML);
+},this);
+this.onChanged(arguments);
+},_sorter:function(a,b){
+var _e=a.innerHTML;
+var _f=b.innerHTML;
+if(_e>_f){
+return 1;
+}
+if(_e<_f){
+return -1;
+}
+return 0;
+},setTitle:function(_10){
+this.focusNode.innerHTML=this.title=_10;
+},onChanged:function(){
+}});
+}
diff --git a/dojox/widget/SortList/SortList.css b/dojox/widget/SortList/SortList.css
new file mode 100644
index 0000000..e15d52a
--- /dev/null
+++ b/dojox/widget/SortList/SortList.css
@@ -0,0 +1,57 @@
+.sortListBody { margin:0; padding:0; background:#fff; }
+.soria .sortListBody li,
+.tundra .sortListBody li {
+	border-bottom:1px solid #b7b7b7;
+	padding:2px 2px 2px 5px;	
+}
+.sortListTitle {
+	cursor:pointer; 
+	padding:4px 4px 3px 4px;
+}
+.sortList { height:100%; width:100%; }
+.dijitBorderContainer .dojoxSortList { width: auto; height: auto;}
+.sortListBodyWrapper { 
+	border:1px solid #b7b7b7; 
+	overflow:auto; 
+	height:100%; 
+	cursor:pointer;
+} 
+.soria .sortListBodyWrapper {
+	border:1px solid #333; 
+}
+.soria .sortListItemOdd,
+.tundra .sortListItemOdd { background:#f2f5f9; }
+.tundra .sortListTitle {
+	background:#fafafa url('../../../dijit/themes/tundra/images/titleBarBg.gif') repeat-x top left; 
+	border:1px solid #bfbfbf;
+	border-bottom:0;
+}
+.soria .sortListTitle {
+	background:#4f8ce5 url('../../../dijit/themes/soria/images/titleBar.png') repeat-x top left;
+	background-position:0px -1px; 
+	border:1px solid #333; 
+	border-bottom:0;
+	font-weight:bold;
+	color:#fff; 
+}
+.sortListItemSelected { background:#b7cdee !important; }
+.sortListItemHover { background:#ff6 !important; }
+.soria .sortListIcon,
+.tundra .sortListIcon { 
+	float:right;
+	background:url('../../../dijit/themes/tundra/images/spriteArrows.png') no-repeat;
+	width: 7px;
+}
+.tundra .sortListDesc .sortListIcon {
+	background-position: 0px center;
+}
+.tundra .sortListAsc .sortListIcon {
+	background-position: -21px center;
+}
+.soria .sortListDesc .sortListIcon,
+.soria .sortListAsc .sortListIcon {
+	background:url('../../../dijit/themes/soria/images/spriteRoundedIconsSmall.png') no-repeat -15px top;
+}
+.soria .sortListDesc .sortListIcon {
+	background-position:-45px 0px; 
+}
diff --git a/dojox/widget/SortList/SortList.html b/dojox/widget/SortList/SortList.html
new file mode 100644
index 0000000..2cc16eb
--- /dev/null
+++ b/dojox/widget/SortList/SortList.html
@@ -0,0 +1,9 @@
+<div class="sortList" id="${id}">
+		<div class="sortListTitle" dojoAttachPoint="titleNode">
+		<div class="dijitInline sortListIcon"> </div>
+		<span dojoAttachPoint="focusNode">${title}</span>
+		</div>
+		<div class="sortListBodyWrapper" dojoAttachEvent="onmouseover: _set, onmouseout: _unset, onclick:_handleClick" dojoAttachPoint="bodyWrapper">
+		<ul dojoAttachPoint="containerNode" class="sortListBody"></ul>
+	</div>
+</div>
\ No newline at end of file
diff --git a/dojox/widget/Standby.js b/dojox/widget/Standby.js
new file mode 100644
index 0000000..ff07214
--- /dev/null
+++ b/dojox/widget/Standby.js
@@ -0,0 +1,138 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.Standby"]){
+dojo._hasResource["dojox.widget.Standby"]=true;
+dojo.provide("dojox.widget.Standby");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dojo.fx");
+dojo.experimental("dojox.widget.Standby");
+dojo.declare("dojox.widget.Standby",[dijit._Widget,dijit._Templated],{templateString:"<div>\n\t<div class=\"standbyUnderlayNode\" dojoAttachPoint=\"_underlayNode\">\n\t</div>\n\t<img src=\"${image}\" class=\"standbyImageNode\" dojoAttachPoint=\"_imageNode\">\n</div>\n\n",_underlayNode:null,_imageNode:null,image:dojo.moduleUrl("dojox","widget/Standby/images/loading.gif").toString(),imageText:"Please Wait...",_displayed:false,_resizeCheck:null,target:"",color:"#C0C0C0",startup:function(_1){
+if(typeof this.target==="string"){
+var w=dijit.byId(this.target);
+if(w){
+this.target=w.domNode;
+}else{
+this.target=dojo.byId(this.target);
+}
+}
+dojo.style(this._underlayNode,"display","none");
+dojo.style(this._imageNode,"display","none");
+dojo.style(this._underlayNode,"backgroundColor",this.color);
+dojo.attr(this._imageNode,"src",this.image);
+dojo.attr(this._imageNode,"alt",this.imageText);
+this.connect(this._underlayNode,"onclick","_ignore");
+if(this.domNode.parentNode&&this.domNode.parentNode!=dojo.body()){
+dojo.body().appendChild(this.domNode);
+}
+},show:function(){
+if(!this._displayed){
+this._displayed=true;
+this._size();
+this._fadeIn();
+}
+},hide:function(){
+if(this._displayed){
+this._size();
+this._fadeOut();
+this._displayed=false;
+if(this._resizeCheck!==null){
+clearInterval(this._resizeCheck);
+this._resizeCheck=null;
+}
+}
+},_size:function(){
+if(this._displayed){
+var _3=dojo.style(this._imageNode,"display");
+dojo.style(this._imageNode,"display","block");
+var _4=dojo.coords(this.target);
+var _5=dojo.marginBox(this._imageNode);
+dojo.style(this._imageNode,"display",_3);
+dojo.style(this._imageNode,"zIndex","10000");
+var _6=dojo._docScroll();
+if(!_6){
+_6={x:0,y:0};
+}
+var _7=dojo.style(this.target,"marginLeft");
+if(dojo.isWebKit&&_7){
+_7=_7*2;
+}
+if(_7){
+_4.w=_4.w-_7;
+}
+if(!dojo.isWebKit){
+var _8=dojo.style(this.target,"marginRight");
+if(_8){
+_4.w=_4.w-_8;
+}
+}
+var _9=dojo.style(this.target,"marginTop");
+if(_9){
+_4.h=_4.h-_9;
+}
+var _a=dojo.style(this.target,"marginBottom");
+if(_a){
+_4.h=_4.h-_a;
+}
+if(_4.h>0&&_4.w>0){
+dojo.style(this._underlayNode,"width",_4.w+"px");
+dojo.style(this._underlayNode,"height",_4.h+"px");
+dojo.style(this._underlayNode,"top",(_4.y+_6.y)+"px");
+dojo.style(this._underlayNode,"left",(_4.x+_6.x)+"px");
+var _b=function(_c,_d){
+dojo.forEach(_c,function(_e){
+dojo.style(this._underlayNode,_e,dojo.style(this.target,_e));
+},_d);
+};
+var _f=["borderRadius","borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius"];
+_b(_f,this);
+if(!dojo.isIE){
+_f=["MozBorderRadius","MozBorderRadiusTopleft","MozBorderRadiusTopright","MozBorderRadiusBottomleft","MozBorderRadiusBottomright","WebkitBorderRadius","WebkitBorderTopLeftRadius","WebkitBorderTopRightRadius","WebkitBorderBottomLeftRadius","WebkitBorderBottomRightRadius"];
+_b(_f,this);
+}
+var _10=(_4.h/2)-(_5.h/2);
+var _11=(_4.w/2)-(_5.w/2);
+dojo.style(this._imageNode,"top",(_10+_4.y+_6.y)+"px");
+dojo.style(this._imageNode,"left",(_11+_4.x+_6.x)+"px");
+dojo.style(this._underlayNode,"display","block");
+dojo.style(this._imageNode,"display","block");
+}else{
+dojo.style(this._underlayNode,"display","none");
+dojo.style(this._imageNode,"display","none");
+}
+if(this._resizeCheck===null){
+var _12=this;
+this._resizeCheck=setInterval(function(){
+_12._size();
+},100);
+}
+}
+},_fadeIn:function(){
+var _13=dojo.animateProperty({node:this._underlayNode,properties:{opacity:{start:0,end:0.75}}});
+var _14=dojo.animateProperty({node:this._imageNode,properties:{opacity:{start:0,end:1}}});
+var _15=dojo.fx.combine([_13,_14]);
+_15.play();
+},_fadeOut:function(){
+var _16=this;
+var _17=dojo.animateProperty({node:this._underlayNode,properties:{opacity:{start:0.75,end:0}},onEnd:function(){
+dojo.style(_16._underlayNode,"display","none");
+}});
+var _18=dojo.animateProperty({node:this._imageNode,properties:{opacity:{start:1,end:0}},onEnd:function(){
+dojo.style(_16._imageNode,"display","none");
+}});
+var _19=dojo.fx.combine([_17,_18]);
+_19.play();
+},_ignore:function(_1a){
+if(_1a){
+_1a.preventDefault();
+_1a.stopPropagation();
+}
+},uninitialize:function(){
+this.hide();
+}});
+}
diff --git a/dojox/widget/Standby/Standby.css b/dojox/widget/Standby/Standby.css
new file mode 100644
index 0000000..f83d2e5
--- /dev/null
+++ b/dojox/widget/Standby/Standby.css
@@ -0,0 +1,16 @@
+.standbyUnderlayNode {
+	display: none;
+	opacity: 0;
+	z-index: 9999;
+	position: absolute;
+	cursor:wait;
+}
+.standbyImageNode {
+	opacity: 0;
+        display: none;
+	z-index: -10000;
+	position: absolute;
+	top: 0px;
+	left: 0px;
+	cursor:wait;
+}
diff --git a/dojox/widget/Standby/Standby.html b/dojox/widget/Standby/Standby.html
new file mode 100644
index 0000000..8d4a2ad
--- /dev/null
+++ b/dojox/widget/Standby/Standby.html
@@ -0,0 +1,6 @@
+<div>
+	<div class="standbyUnderlayNode" dojoAttachPoint="_underlayNode">
+	</div>
+	<img src="${image}" class="standbyImageNode" dojoAttachPoint="_imageNode">
+</div>
+
diff --git a/dojox/widget/Standby/images/loading.gif b/dojox/widget/Standby/images/loading.gif
new file mode 100644
index 0000000..e4ab783
Binary files /dev/null and b/dojox/widget/Standby/images/loading.gif differ
diff --git a/dojox/widget/Toaster.js b/dojox/widget/Toaster.js
new file mode 100644
index 0000000..06342b5
--- /dev/null
+++ b/dojox/widget/Toaster.js
@@ -0,0 +1,176 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.Toaster"]){
+dojo._hasResource["dojox.widget.Toaster"]=true;
+dojo.provide("dojox.widget.Toaster");
+dojo.require("dojo.fx");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.declare("dojox.widget.Toaster",[dijit._Widget,dijit._Templated],{templateString:"<div dojoAttachPoint=\"clipNode\"><div dojoAttachPoint=\"containerNode\" dojoAttachEvent=\"onclick:onSelect\"><div dojoAttachPoint=\"contentNode\"></div></div></div>",messageTopic:"",messageTypes:{MESSAGE:"message",WARNING:"warning",ERROR:"error",FATAL:"fatal"},defaultType:"message",positionDirection:"br-up",positionDirectionTypes:["br-up","br-left","bl-up","bl-right","tr-down","tr-left","tl-down","tl-r [...]
+this.inherited(arguments);
+this.hide();
+dojo.body().appendChild(this.domNode);
+this.clipNode.className="dijitToasterClip";
+this.containerNode.className+=" dijitToasterContainer";
+this.contentNode.className="dijitToasterContent";
+if(this.messageTopic){
+dojo.subscribe(this.messageTopic,this,"_handleMessage");
+}
+},_handleMessage:function(_1){
+if(dojo.isString(_1)){
+this.setContent(_1);
+}else{
+this.setContent(_1.message,_1.type,_1.duration);
+}
+},_capitalize:function(w){
+return w.substring(0,1).toUpperCase()+w.substring(1);
+},setContent:function(_3,_4,_5){
+_5=_5||this.duration;
+if(this.slideAnim){
+if(this.slideAnim.status()!="playing"){
+this.slideAnim.stop();
+}
+if(this.slideAnim.status()=="playing"||(this.fadeAnim&&this.fadeAnim.status()=="playing")){
+setTimeout(dojo.hitch(this,function(){
+this.setContent(_3,_4,_5);
+}),50);
+return;
+}
+}
+for(var _6 in this.messageTypes){
+dojo.removeClass(this.containerNode,"dijitToaster"+this._capitalize(this.messageTypes[_6]));
+}
+dojo.style(this.containerNode,"opacity",1);
+this._setContent(_3);
+dojo.addClass(this.containerNode,"dijitToaster"+this._capitalize(_4||this.defaultType));
+this.show();
+var _7=dojo.marginBox(this.containerNode);
+this._cancelHideTimer();
+if(this.isVisible){
+this._placeClip();
+if(!this._stickyMessage){
+this._setHideTimer(_5);
+}
+}else{
+var _8=this.containerNode.style;
+var pd=this.positionDirection;
+if(pd.indexOf("-up")>=0){
+_8.left=0+"px";
+_8.top=_7.h+10+"px";
+}else{
+if(pd.indexOf("-left")>=0){
+_8.left=_7.w+10+"px";
+_8.top=0+"px";
+}else{
+if(pd.indexOf("-right")>=0){
+_8.left=0-_7.w-10+"px";
+_8.top=0+"px";
+}else{
+if(pd.indexOf("-down")>=0){
+_8.left=0+"px";
+_8.top=0-_7.h-10+"px";
+}else{
+throw new Error(this.id+".positionDirection is invalid: "+pd);
+}
+}
+}
+}
+this.slideAnim=dojo.fx.slideTo({node:this.containerNode,top:0,left:0,duration:this.slideDuration});
+this.connect(this.slideAnim,"onEnd",function(_a,_b){
+this.fadeAnim=dojo.fadeOut({node:this.containerNode,duration:1000});
+this.connect(this.fadeAnim,"onEnd",function(_c){
+this.isVisible=false;
+this.hide();
+});
+this._setHideTimer(_5);
+this.connect(this,"onSelect",function(_d){
+this._cancelHideTimer();
+this._stickyMessage=false;
+this.fadeAnim.play();
+});
+this.isVisible=true;
+});
+this.slideAnim.play();
+}
+},_setContent:function(_e){
+if(dojo.isFunction(_e)){
+_e(this);
+return;
+}
+if(_e&&this.isVisible){
+_e=this.contentNode.innerHTML+this.separator+_e;
+}
+this.contentNode.innerHTML=_e;
+},_cancelHideTimer:function(){
+if(this._hideTimer){
+clearTimeout(this._hideTimer);
+this._hideTimer=null;
+}
+},_setHideTimer:function(_f){
+this._cancelHideTimer();
+if(_f>0){
+this._cancelHideTimer();
+this._hideTimer=setTimeout(dojo.hitch(this,function(evt){
+if(this.bgIframe&&this.bgIframe.iframe){
+this.bgIframe.iframe.style.display="none";
+}
+this._hideTimer=null;
+this._stickyMessage=false;
+this.fadeAnim.play();
+}),_f);
+}else{
+this._stickyMessage=true;
+}
+},_placeClip:function(){
+var _11=dijit.getViewport();
+var _12=dojo.marginBox(this.containerNode);
+var _13=this.clipNode.style;
+_13.height=_12.h+"px";
+_13.width=_12.w+"px";
+var pd=this.positionDirection;
+if(pd.match(/^t/)){
+_13.top=_11.t+"px";
+}else{
+if(pd.match(/^b/)){
+_13.top=(_11.h-_12.h-2+_11.t)+"px";
+}
+}
+if(pd.match(/^[tb]r-/)){
+_13.left=(_11.w-_12.w-1-_11.l)+"px";
+}else{
+if(pd.match(/^[tb]l-/)){
+_13.left=0+"px";
+}
+}
+_13.clip="rect(0px, "+_12.w+"px, "+_12.h+"px, 0px)";
+if(dojo.isIE){
+if(!this.bgIframe){
+this.clipNode.id=dijit.getUniqueId("dojox_widget_Toaster_clipNode");
+this.bgIframe=new dijit.BackgroundIframe(this.clipNode);
+}
+var _15=this.bgIframe.iframe;
+if(_15){
+_15.style.display="block";
+}
+}
+},onSelect:function(e){
+},show:function(){
+dojo.style(this.domNode,"display","block");
+this._placeClip();
+if(!this._scrollConnected){
+this._scrollConnected=dojo.connect(window,"onscroll",this,this._placeClip);
+}
+},hide:function(){
+dojo.style(this.domNode,"display","none");
+if(this._scrollConnected){
+dojo.disconnect(this._scrollConnected);
+this._scrollConnected=false;
+}
+dojo.style(this.containerNode,"opacity",1);
+}});
+}
diff --git a/dojox/widget/Toaster/Toaster.css b/dojox/widget/Toaster/Toaster.css
new file mode 100644
index 0000000..b898452
--- /dev/null
+++ b/dojox/widget/Toaster/Toaster.css
@@ -0,0 +1,39 @@
+
+.dijitToasterContent {
+	padding:1em;
+	padding-top:0.25em;
+	background:#73c74a;
+}
+.dijitToasterMessage{ 
+	color:#fff;
+}
+.dijitToasterWarning{ }
+.dijitToasterError,
+.dijitToasterFatal{
+	font-weight:bold;
+	color:#fff;
+}
+.dijitToasterWarning .dijitToasterContent{
+	padding:1em;
+	padding-top:0.25em;
+	background:#d4d943;
+} 
+.dijitToasterError .dijitToasterContent{
+	padding:1em;
+	padding-top:0.25em;
+	background:#c46600;
+}
+ 
+.dijitToasterClip {
+	position: absolute;
+	z-index: 5000;
+	overflow: hidden;
+}
+.dijitToasterContainer {
+	display: block;
+	position: absolute;
+	width: 17.5em;
+	margin: 0px;
+	font:0.75em Tahoma, Helvetica, Verdana, Arial;
+}
+ 
diff --git a/dojox/widget/Wizard.js b/dojox/widget/Wizard.js
new file mode 100644
index 0000000..44b2ff6
--- /dev/null
+++ b/dojox/widget/Wizard.js
@@ -0,0 +1,108 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.Wizard"]){
+dojo._hasResource["dojox.widget.Wizard"]=true;
+dojo.provide("dojox.widget.Wizard");
+dojo.require("dijit.layout.StackContainer");
+dojo.require("dijit.layout.ContentPane");
+dojo.require("dijit.form.Button");
+dojo.require("dojo.i18n");
+dojo.requireLocalization("dijit","common",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.requireLocalization("dojox.widget","Wizard",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.declare("dojox.widget.Wizard",[dijit.layout.StackContainer,dijit._Templated],{widgetsInTemplate:true,templateString:"<div class=\"dojoxWizard\" dojoAttachPoint=\"wizardNode\">\n    <div class=\"dojoxWizardContainer\" dojoAttachPoint=\"containerNode\"></div>\n    <div class=\"dojoxWizardButtons\" dojoAttachPoint=\"wizardNav\">\n        <button dojoType=\"dijit.form.Button\" dojoAttachPoint=\"previousButton\">${previousButtonLabel}</button>\n        <button dojoType=\"dijit.form.Butto [...]
+this.inherited(arguments);
+var _1=dojo.mixin({cancel:dojo.i18n.getLocalization("dijit","common",this.lang).buttonCancel},dojo.i18n.getLocalization("dojox.widget","Wizard",this.lang));
+var _2;
+for(_2 in _1){
+if(!this[_2+"ButtonLabel"]){
+this[_2+"ButtonLabel"]=_1[_2];
+}
+}
+},startup:function(){
+if(this._started){
+return;
+}
+this.inherited(arguments);
+this.connect(this.nextButton,"onClick","_forward");
+this.connect(this.previousButton,"onClick","back");
+if(this.cancelFunction){
+if(dojo.isString(this.cancelFunction)){
+this.cancelFunction=dojo.getObject(this.cancelFunction);
+}
+this.connect(this.cancelButton,"onClick",this.cancelFunction);
+}else{
+this.cancelButton.domNode.style.display="none";
+}
+this.connect(this.doneButton,"onClick","done");
+this._subscription=dojo.subscribe(this.id+"-selectChild",dojo.hitch(this,"_checkButtons"));
+this._checkButtons();
+this._started=true;
+},_checkButtons:function(){
+var sw=this.selectedChildWidget;
+var _4=sw.isLastChild;
+this.nextButton.attr("disabled",_4);
+this._setButtonClass(this.nextButton);
+if(sw.doneFunction){
+this.doneButton.domNode.style.display="";
+if(_4){
+this.nextButton.domNode.style.display="none";
+}
+}else{
+this.doneButton.domNode.style.display="none";
+}
+this.previousButton.attr("disabled",!this.selectedChildWidget.canGoBack);
+this._setButtonClass(this.previousButton);
+},_setButtonClass:function(_5){
+_5.domNode.style.display=(this.hideDisabled&&_5.disabled)?"none":"";
+},_forward:function(){
+if(this.selectedChildWidget._checkPass()){
+this.forward();
+}
+},done:function(){
+this.selectedChildWidget.done();
+},destroy:function(){
+dojo.unsubscribe(this._subscription);
+this.inherited(arguments);
+}});
+dojo.declare("dojox.widget.WizardPane",dijit.layout.ContentPane,{canGoBack:true,passFunction:null,doneFunction:null,startup:function(){
+this.inherited(arguments);
+if(this.isFirstChild){
+this.canGoBack=false;
+}
+if(dojo.isString(this.passFunction)){
+this.passFunction=dojo.getObject(this.passFunction);
+}
+if(dojo.isString(this.doneFunction)&&this.doneFunction){
+this.doneFunction=dojo.getObject(this.doneFunction);
+}
+},_onShow:function(){
+if(this.isFirstChild){
+this.canGoBack=false;
+}
+this.inherited(arguments);
+},_checkPass:function(){
+var r=true;
+if(this.passFunction&&dojo.isFunction(this.passFunction)){
+var _7=this.passFunction();
+switch(typeof _7){
+case "boolean":
+r=_7;
+break;
+case "string":
+alert(_7);
+r=false;
+break;
+}
+}
+return r;
+},done:function(){
+if(this.doneFunction&&dojo.isFunction(this.doneFunction)){
+this.doneFunction();
+}
+}});
+}
diff --git a/dojox/widget/Wizard/Wizard.css b/dojox/widget/Wizard/Wizard.css
new file mode 100644
index 0000000..f1a9177
--- /dev/null
+++ b/dojox/widget/Wizard/Wizard.css
@@ -0,0 +1,19 @@
+.dojoxWizard {
+	position:relative; 
+}
+.dojoxWizardButtons {
+	position:absolute;
+	bottom:5px;
+	right:5px;	
+}
+.tundra .dojoxWizard {
+	background: #eeeeee;
+	border: #b7b7b7 1px solid;
+	padding: 2px;
+	-moz-border-radius:3pt;
+	-webkit-border-radius:4pt;
+}
+.soria .dojoxWizard {
+	border:1px solid #b7b7b7;
+	padding:2px;
+}
diff --git a/dojox/widget/Wizard/Wizard.html b/dojox/widget/Wizard/Wizard.html
new file mode 100644
index 0000000..1ae6a1e
--- /dev/null
+++ b/dojox/widget/Wizard/Wizard.html
@@ -0,0 +1,9 @@
+<div class="dojoxWizard" dojoAttachPoint="wizardNode">
+    <div class="dojoxWizardContainer" dojoAttachPoint="containerNode"></div>
+    <div class="dojoxWizardButtons" dojoAttachPoint="wizardNav">
+        <button dojoType="dijit.form.Button" dojoAttachPoint="previousButton">${previousButtonLabel}</button>
+        <button dojoType="dijit.form.Button" dojoAttachPoint="nextButton">${nextButtonLabel}</button>
+        <button dojoType="dijit.form.Button" dojoAttachPoint="doneButton" style="display:none">${doneButtonLabel}</button>
+        <button dojoType="dijit.form.Button" dojoAttachPoint="cancelButton">${cancelButtonLabel}</button>
+    </div>
+</div>
diff --git a/dojox/widget/gauge/AnalogArcIndicator.js b/dojox/widget/gauge/AnalogArcIndicator.js
new file mode 100644
index 0000000..8cc605b
--- /dev/null
+++ b/dojox/widget/gauge/AnalogArcIndicator.js
@@ -0,0 +1,69 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.gauge.AnalogArcIndicator"]){
+dojo._hasResource["dojox.widget.gauge.AnalogArcIndicator"]=true;
+dojo.provide("dojox.widget.gauge.AnalogArcIndicator");
+dojo.require("dojox.widget.AnalogGauge");
+dojo.experimental("dojox.widget.gauge.AnalogArcIndicator");
+dojo.declare("dojox.widget.gauge.AnalogArcIndicator",[dojox.widget.gauge.AnalogLineIndicator],{_createArc:function(_1){
+if(this.shapes[0]){
+var a=this._gauge._getRadians(this._gauge._getAngle(_1));
+var _3=Math.cos(a);
+var _4=Math.sin(a);
+var sa=this._gauge._getRadians(this._gauge.startAngle);
+var _6=Math.cos(sa);
+var _7=Math.sin(sa);
+var _8=this.offset+this.width;
+var p=["M"];
+p.push(this._gauge.cx+this.offset*_7);
+p.push(this._gauge.cy-this.offset*_6);
+p.push("A",this.offset,this.offset,0,((a-sa)>Math.PI)?1:0,1);
+p.push(this._gauge.cx+this.offset*_4);
+p.push(this._gauge.cy-this.offset*_3);
+p.push("L");
+p.push(this._gauge.cx+_8*_4);
+p.push(this._gauge.cy-_8*_3);
+p.push("A",_8,_8,0,((a-sa)>Math.PI)?1:0,0);
+p.push(this._gauge.cx+_8*_7);
+p.push(this._gauge.cy-_8*_6);
+this.shapes[0].setShape(p.join(" "));
+this.currentValue=_1;
+}
+},draw:function(_a){
+var v=this.value;
+if(v<this._gauge.min){
+v=this._gauge.min;
+}
+if(v>this._gauge.max){
+v=this._gauge.max;
+}
+if(this.shapes){
+if(_a){
+this._createArc(v);
+}else{
+var _c=new dojo._Animation({curve:[this.currentValue,v],duration:this.duration,easing:this.easing});
+dojo.connect(_c,"onAnimate",dojo.hitch(this,this._createArc));
+_c.play();
+}
+}else{
+var _d={color:this.color,width:1};
+if(this.color.type){
+_d.color=this.color.colors[0].color;
+}
+this.shapes=[this._gauge.surface.createPath().setStroke(_d).setFill(this.color)];
+this._createArc(v);
+if(this.hover){
+this.shapes[0].getEventSource().setAttribute("hover",this.hover);
+}
+if(this.onDragMove&&!this.noChange){
+this._gauge.connect(this.shapes[0].getEventSource(),"onmousedown",this._gauge.handleMouseDown);
+this.shapes[0].getEventSource().style.cursor="pointer";
+}
+}
+}});
+}
diff --git a/dojox/widget/gauge/AnalogArrowIndicator.js b/dojox/widget/gauge/AnalogArrowIndicator.js
new file mode 100644
index 0000000..fb64af1
--- /dev/null
+++ b/dojox/widget/gauge/AnalogArrowIndicator.js
@@ -0,0 +1,28 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.gauge.AnalogArrowIndicator"]){
+dojo._hasResource["dojox.widget.gauge.AnalogArrowIndicator"]=true;
+dojo.provide("dojox.widget.gauge.AnalogArrowIndicator");
+dojo.require("dojox.widget.AnalogGauge");
+dojo.experimental("dojox.widget.gauge.AnalogArrowIndicator");
+dojo.declare("dojox.widget.gauge.AnalogArrowIndicator",[dojox.widget.gauge.AnalogLineIndicator],{_getShapes:function(){
+if(!this._gauge){
+return null;
+}
+var x=Math.floor(this.width/2);
+var _2=this.width*5;
+var _3=(this.width&1);
+var _4=[];
+var _5=[{x:-x,y:0},{x:-x,y:-this.length+_2},{x:-2*x,y:-this.length+_2},{x:0,y:-this.length},{x:2*x+_3,y:-this.length+_2},{x:x+_3,y:-this.length+_2},{x:x+_3,y:0},{x:-x,y:0}];
+_4[0]=this._gauge.surface.createPolyline(_5).setStroke({color:this.color}).setFill(this.color);
+_4[1]=this._gauge.surface.createLine({x1:-x,y1:0,x2:-x,y2:-this.length+_2}).setStroke({color:this.highlight});
+_4[2]=this._gauge.surface.createLine({x1:-x-3,y1:-this.length+_2,x2:0,y2:-this.length}).setStroke({color:this.highlight});
+_4[3]=this._gauge.surface.createCircle({cx:0,cy:0,r:this.width}).setStroke({color:this.color}).setFill(this.color);
+return _4;
+}});
+}
diff --git a/dojox/widget/gauge/AnalogNeedleIndicator.js b/dojox/widget/gauge/AnalogNeedleIndicator.js
new file mode 100644
index 0000000..522901d
--- /dev/null
+++ b/dojox/widget/gauge/AnalogNeedleIndicator.js
@@ -0,0 +1,30 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.gauge.AnalogNeedleIndicator"]){
+dojo._hasResource["dojox.widget.gauge.AnalogNeedleIndicator"]=true;
+dojo.provide("dojox.widget.gauge.AnalogNeedleIndicator");
+dojo.require("dojox.widget.AnalogGauge");
+dojo.experimental("dojox.widget.gauge.AnalogNeedleIndicator");
+dojo.declare("dojox.widget.gauge.AnalogNeedleIndicator",[dojox.widget.gauge.AnalogLineIndicator],{_getShapes:function(){
+if(!this._gauge){
+return null;
+}
+var x=Math.floor(this.width/2);
+var _2=this.width*5;
+var _3=(this.width&1);
+var _4=[];
+var _5={color:this.color,width:1};
+if(this.color.type){
+_5.color=this.color.colors[0].color;
+}
+var xy=(Math.sqrt(2)*(x));
+_4[0]=this._gauge.surface.createPath().setStroke(_5).setFill(this.color).moveTo(xy,-xy).arcTo((2*x),(2*x),0,0,0,-xy,-xy).lineTo(0,-this.length).closePath();
+_4[1]=this._gauge.surface.createCircle({cx:0,cy:0,r:this.width}).setStroke({color:this.color}).setFill(this.color);
+return _4;
+}});
+}
diff --git a/dojox/widget/gauge/BarIndicator.js b/dojox/widget/gauge/BarIndicator.js
new file mode 100644
index 0000000..9784a4d
--- /dev/null
+++ b/dojox/widget/gauge/BarIndicator.js
@@ -0,0 +1,80 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.gauge.BarIndicator"]){
+dojo._hasResource["dojox.widget.gauge.BarIndicator"]=true;
+dojo.provide("dojox.widget.gauge.BarIndicator");
+dojo.require("dojox.widget.BarGauge");
+dojo.experimental("dojox.widget.gauge.BarIndicator");
+dojo.declare("dojox.widget.gauge.BarIndicator",[dojox.widget.gauge.BarLineIndicator],{_getShapes:function(){
+if(!this._gauge){
+return null;
+}
+var v=this.value;
+if(v<this._gauge.min){
+v=this._gauge.min;
+}
+if(v>this._gauge.max){
+v=this._gauge.max;
+}
+var _2=this._gauge._getPosition(v);
+if(_2==this.dataX){
+_2=this.dataX+1;
+}
+var y=this._gauge.dataY+Math.floor((this._gauge.dataHeight-this.width)/2)+this.offset;
+var _4=[];
+_4[0]=this._gauge.surface.createRect({x:this._gauge.dataX,y:y,width:_2-this._gauge.dataX,height:this.width});
+_4[0].setStroke({color:this.color});
+_4[0].setFill(this.color);
+_4[1]=this._gauge.surface.createLine({x1:this._gauge.dataX,y1:y,x2:_2,y2:y});
+_4[1].setStroke({color:this.highlight});
+if(this.highlight2){
+y--;
+_4[2]=this._gauge.surface.createLine({x1:this._gauge.dataX,y1:y,x2:_2,y2:y});
+_4[2].setStroke({color:this.highlight2});
+}
+return _4;
+},_createShapes:function(_5){
+for(var i in this.shapes){
+i=this.shapes[i];
+var _7={};
+for(var j in i){
+_7[j]=i[j];
+}
+if(i.shape.type=="line"){
+_7.shape.x2=_5+_7.shape.x1;
+}else{
+if(i.shape.type=="rect"){
+_7.width=_5;
+}
+}
+i.setShape(_7);
+}
+},_move:function(_9){
+var _a=false;
+var c;
+var v=this.value;
+if(v<this.min){
+v=this.min;
+}
+if(v>this.max){
+v=this.max;
+}
+c=this._gauge._getPosition(this.currentValue);
+this.currentValue=v;
+v=this._gauge._getPosition(v)-this._gauge.dataX;
+if(_9){
+this._createShapes(v);
+}else{
+if(c!=v){
+var _d=new dojo._Animation({curve:[c,v],duration:this.duration,easing:this.easing});
+dojo.connect(_d,"onAnimate",dojo.hitch(this,this._createShapes));
+_d.play();
+}
+}
+}});
+}
diff --git a/dojox/widget/gauge/_Gauge.css b/dojox/widget/gauge/_Gauge.css
new file mode 100644
index 0000000..d2001a7
--- /dev/null
+++ b/dojox/widget/gauge/_Gauge.css
@@ -0,0 +1,51 @@
+ at CHARSET "ISO-8859-1";
+.dojoxGaugeContent {
+	font-family: Verdana;
+	border-width: 1px;
+	border-style: solid;
+	border-color: #CCCCCC;
+}
+.dojoxGaugeRange1 {
+	fill: #606060 ;
+	stroke: #606060 ;
+}
+.dojoxGaugeRange2 {
+	fill: #707070 ;
+	stroke: #707070 ;
+}
+.dojoxGaugeRange3 {
+	fill: #808080 ;
+	stroke: #808080 ;
+}
+.dojoxGaugeRange4 {
+	fill: #909090 ;
+	stroke: #909090 ;
+}
+.dojoxGaugeRange5 {
+	fill: #A0A0A0;
+	stroke: #A0A0A0;
+}
+.dojoxGaugeRange6 {
+	fill: #B0B0B0;
+	stroke: #B0B0B0;
+}
+.dojoxGaugeRange7 {
+	fill: #C0C0C0;
+	stroke: #C0C0C0;
+}
+.dojoxGaugeRange8 {
+	fill: #D0D0D0;
+	stroke: #D0D0D0;
+}
+.dojoxGaugeRange9 {
+	fill: #E0E0E0;
+	stroke: #E0E0E0;
+}
+.dojoxGaugeRange10 {
+	fill: #F0F0F0;
+	stroke: #F0F0F0;
+}
+.testing {
+	fill: blue;
+	stroke: blue;
+}
diff --git a/dojox/widget/gauge/_Gauge.html b/dojox/widget/gauge/_Gauge.html
new file mode 100644
index 0000000..3c4bdf9
--- /dev/null
+++ b/dojox/widget/gauge/_Gauge.html
@@ -0,0 +1,5 @@
+<div>
+	<div class="dojoxGaugeContent" dojoAttachPoint="gaugeContent"></div>
+	<div dojoAttachPoint="containerNode"></div>
+	<div dojoAttachPoint="mouseNode"></div>
+</div>
\ No newline at end of file
diff --git a/dojox/widget/gauge/_Gauge.js b/dojox/widget/gauge/_Gauge.js
new file mode 100644
index 0000000..a7f968b
--- /dev/null
+++ b/dojox/widget/gauge/_Gauge.js
@@ -0,0 +1,304 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.widget.gauge._Gauge"]){
+dojo._hasResource["dojox.widget.gauge._Gauge"]=true;
+dojo.provide("dojox.widget.gauge._Gauge");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dijit._Container");
+dojo.require("dijit._Contained");
+dojo.require("dijit.Tooltip");
+dojo.require("dojo.fx.easing");
+dojo.require("dojox.gfx");
+dojo.experimental("dojox.widget.gauge._Gauge");
+dojo.declare("dojox.widget.gauge._Gauge",[dijit._Widget,dijit._Templated,dijit._Container],{width:0,height:0,background:null,min:0,max:0,image:null,useRangeStyles:0,useTooltip:true,majorTicks:null,minorTicks:null,_defaultIndicator:null,defaultColors:[[0,84,170,1],[68,119,187,1],[102,153,204,1],[153,187,238,1],[153,204,255,1],[204,238,255,1],[221,238,255,1]],min:null,max:null,surface:null,hideValues:false,gaugeContent:undefined,templateString:"<div>\n\t<div class=\"dojoxGaugeContent\" doj [...]
+if(this.image===null){
+this.image={};
+}
+this.connect(this.gaugeContent,"onmousemove",this.handleMouseMove);
+this.connect(this.gaugeContent,"onmouseover",this.handleMouseOver);
+this.connect(this.gaugeContent,"onmouseout",this.handleMouseOut);
+this.connect(this.gaugeContent,"onmouseup",this.handleMouseUp);
+if(!dojo.isArray(this.ranges)){
+this.ranges=[];
+}
+if(!dojo.isArray(this.indicators)){
+this.indicators=[];
+}
+var _1=[],_2=[];
+var i;
+if(this.hasChildren()){
+var _4=this.getChildren();
+for(i=0;i<_4.length;i++){
+if(/dojox\.widget\..*Indicator/.test(_4[i].declaredClass)){
+_2.push(_4[i]);
+continue;
+}
+switch(_4[i].declaredClass){
+case "dojox.widget.gauge.Range":
+_1.push(_4[i]);
+break;
+}
+}
+this.ranges=this.ranges.concat(_1);
+this.indicators=this.indicators.concat(_2);
+}
+if(!this.background){
+this.background=this._backgroundDefault;
+}
+this.background=this.background.color||this.background;
+if(!this.surface){
+this.createSurface();
+}
+this.addRanges(this.ranges);
+if(this.minorTicks&&this.minorTicks.interval){
+this.setMinorTicks(this.minorTicks);
+}
+if(this.majorTicks&&this.majorTicks.interval){
+this.setMajorTicks(this.majorTicks);
+}
+for(i=0;i<this.indicators.length;i++){
+this.addIndicator(this.indicators[i]);
+}
+},_setTicks:function(_5,_6,_7){
+var i;
+if(_5&&dojo.isArray(_5._ticks)){
+for(i=0;i<_5._ticks.length;i++){
+this.removeIndicator(_5._ticks[i]);
+}
+}
+var t={length:_6.length,offset:_6.offset,noChange:true};
+if(_6.color){
+t.color=_6.color;
+}
+if(_6.font){
+t.font=_6.font;
+}
+_6._ticks=[];
+for(i=this.min;i<=this.max;i+=_6.interval){
+t.value=i;
+if(_7){
+t.label=""+i;
+}
+_6._ticks.push(this.addIndicator(t));
+}
+return _6;
+},setMinorTicks:function(_a){
+this.minorTicks=this._setTicks(this.minorTicks,_a,false);
+},setMajorTicks:function(_b){
+this.majorTicks=this._setTicks(this.majorTicks,_b,true);
+},postCreate:function(){
+if(this.hideValues){
+dojo.style(this.containerNode,"display","none");
+}
+dojo.style(this.mouseNode,"width","0");
+dojo.style(this.mouseNode,"height","0");
+dojo.style(this.mouseNode,"position","absolute");
+dojo.style(this.mouseNode,"z-index","100");
+if(this.useTooltip){
+dijit.showTooltip("test",this.mouseNode);
+dijit.hideTooltip(this.mouseNode);
+}
+},createSurface:function(){
+this.gaugeContent.style.width=this.width+"px";
+this.gaugeContent.style.height=this.height+"px";
+this.surface=dojox.gfx.createSurface(this.gaugeContent,this.width,this.height);
+this._background=this.surface.createRect({x:0,y:0,width:this.width,height:this.height});
+this._background.setFill(this.background);
+if(this.image.url){
+this._img=this.surface.createImage({width:this.image.width||this.width,height:this.image.height||this.height,src:this.image.url});
+if(this.image.overlay){
+this._img.getEventSource().setAttribute("overlay",true);
+}
+if(this.image.x||this.image.y){
+this._img.setTransform({dx:this.image.x||0,dy:this.image.y||0});
+}
+}
+},setBackground:function(_c){
+if(!_c){
+_c=this._backgroundDefault;
+}
+this.background=_c.color||_c;
+this._background.setFill(this.background);
+},addRange:function(_d){
+this.addRanges([_d]);
+},addRanges:function(_e){
+if(!this._rangeData){
+this._rangeData=[];
+}
+var _f;
+for(var i=0;i<_e.length;i++){
+_f=_e[i];
+if((this.min===null)||(_f.low<this.min)){
+this.min=_f.low;
+}
+if((this.max===null)||(_f.high>this.max)){
+this.max=_f.high;
+}
+if(!_f.color){
+var _11=this._rangeData.length%this.defaultColors.length;
+if(dojox.gfx.svg&&this.useRangeStyles>0){
+_11=(this._rangeData.length%this.useRangeStyles)+1;
+_f.color={style:"dojoxGaugeRange"+_11};
+}else{
+_11=this._rangeData.length%this.defaultColors.length;
+_f.color=this.defaultColors[_11];
+}
+}
+this._rangeData[this._rangeData.length]=_f;
+}
+this.draw();
+},addIndicator:function(_12){
+_12._gauge=this;
+if(!_12.declaredClass){
+_12=new this._defaultIndicator(_12);
+}
+if(!_12.hideValue){
+this.containerNode.appendChild(_12.domNode);
+}
+if(!this._indicatorData){
+this._indicatorData=[];
+}
+this._indicatorData[this._indicatorData.length]=_12;
+_12.draw();
+return _12;
+},removeIndicator:function(_13){
+for(var i=0;i<this._indicatorData.length;i++){
+if(this._indicatorData[i]===_13){
+this._indicatorData.splice(i,1);
+_13.remove();
+break;
+}
+}
+},moveIndicatorToFront:function(_15){
+if(_15.shapes){
+for(var i=0;i<_15.shapes.length;i++){
+_15.shapes[i].moveToFront();
+}
+}
+},drawText:function(txt,x,y,_1a,_1b,_1c,_1d){
+var t=this.surface.createText({x:x,y:y,text:txt,align:_1a});
+t.setFill(_1c);
+t.setFont(_1d);
+return t;
+},removeText:function(t){
+this.surface.rawNode.removeChild(t);
+},updateTooltip:function(txt,e){
+if(this._lastHover!=txt){
+if(txt!==""){
+dijit.hideTooltip(this.mouseNode);
+dijit.showTooltip(txt,this.mouseNode);
+}else{
+dijit.hideTooltip(this.mouseNode);
+}
+this._lastHover=txt;
+}
+},handleMouseOver:function(_22){
+var _23=_22.target.getAttribute("hover");
+if(_22.target.getAttribute("overlay")){
+this._overOverlay=true;
+var r=this.getRangeUnderMouse(_22);
+if(r&&r.hover){
+_23=r.hover;
+}
+}
+if(this.useTooltip&&!this._drag){
+if(_23){
+this.updateTooltip(_23,_22);
+}else{
+this.updateTooltip("",_22);
+}
+}
+},handleMouseOut:function(_25){
+if(_25.target.getAttribute("overlay")){
+this._overOverlay=false;
+}
+if(this.useTooltip&&this.mouseNode){
+dijit.hideTooltip(this.mouseNode);
+}
+},handleMouseDown:function(_26){
+for(var i=0;i<this._indicatorData.length;i++){
+var _28=this._indicatorData[i].shapes;
+for(var s=0;s<_28.length;s++){
+if(_28[s].getEventSource()==_26.target){
+this._drag=this._indicatorData[i];
+s=_28.length;
+i=this._indicatorData.length;
+}
+}
+}
+dojo.stopEvent(_26);
+},handleMouseUp:function(_2a){
+this._drag=null;
+dojo.stopEvent(_2a);
+},handleMouseMove:function(_2b){
+if(_2b){
+dojo.style(this.mouseNode,"left",_2b.pageX+1+"px");
+dojo.style(this.mouseNode,"top",_2b.pageY+1+"px");
+}
+if(this._drag){
+this._dragIndicator(this,_2b);
+}else{
+if(this.useTooltip&&this._overOverlay){
+var r=this.getRangeUnderMouse(_2b);
+if(r&&r.hover){
+this.updateTooltip(r.hover,_2b);
+}else{
+this.updateTooltip("",_2b);
+}
+}
+}
+}});
+dojo.declare("dojox.widget.gauge.Range",[dijit._Widget,dijit._Contained],{low:0,high:0,hover:"",color:null,size:0,startup:function(){
+this.color=this.color.color||this.color;
+}});
+dojo.declare("dojox.widget.gauge._Indicator",[dijit._Widget,dijit._Contained,dijit._Templated],{value:0,type:"",color:"black",label:"",font:{family:"sans-serif",size:"12px"},length:0,width:0,offset:0,hover:"",front:false,easing:dojo._defaultEasing,duration:1000,hideValue:false,noChange:false,_gauge:null,title:"",templateString:"<div class=\"dojoxGaugeIndicatorDiv\">\n\t<label class=\"dojoxGaugeIndicatorLabel\" for=\"${title}\">${title}:</label>\n\t<input class=\"dojoxGaugeIndicatorInput\ [...]
+if(this.onDragMove){
+this.onDragMove=dojo.hitch(this.onDragMove);
+}
+},postCreate:function(){
+if(this.title===""){
+dojo.style(this.domNode,"display","none");
+}
+if(dojo.isString(this.easing)){
+this.easing=dojo.getObject(this.easing);
+}
+},_update:function(_2d){
+var _2e=this.valueNode.value;
+if(_2e===""){
+this.value=null;
+}else{
+this.value=Number(_2e);
+this.hover=this.title+": "+_2e;
+}
+if(this._gauge){
+this.draw();
+this.valueNode.value=this.value;
+if((this.title=="Target"||this.front)&&this._gauge.moveIndicator){
+this._gauge.moveIndicatorToFront(this);
+}
+}
+},update:function(_2f){
+if(!this.noChange){
+this.valueNode.value=_2f;
+this._update();
+}
+},onDragMove:function(){
+this.value=Math.floor(this.value);
+this.valueNode.value=this.value;
+this.hover=this.title+": "+this.value;
+},draw:function(_30){
+},remove:function(){
+for(var i=0;i<this.shapes.length;i++){
+this._gauge.surface.remove(this.shapes[i]);
+}
+if(this.text){
+this._gauge.surface.remove(this.text);
+}
+}});
+}
diff --git a/dojox/widget/gauge/_Indicator.html b/dojox/widget/gauge/_Indicator.html
new file mode 100644
index 0000000..2942996
--- /dev/null
+++ b/dojox/widget/gauge/_Indicator.html
@@ -0,0 +1,4 @@
+<div class="dojoxGaugeIndicatorDiv">
+	<label class="dojoxGaugeIndicatorLabel" for="${title}">${title}:</label>
+	<input class="dojoxGaugeIndicatorInput" name="${title}" size="5" value="${value}" dojoAttachPoint="valueNode" dojoAttachEvent="onchange:_update"></input>
+</div>
\ No newline at end of file
diff --git a/dojox/widget/nls/FilePicker.js b/dojox/widget/nls/FilePicker.js
new file mode 100644
index 0000000..542f043
--- /dev/null
+++ b/dojox/widget/nls/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Name","size":"Size (in bytes)","path":"Path"})
\ No newline at end of file
diff --git a/dojox/widget/nls/RollingList.js b/dojox/widget/nls/RollingList.js
new file mode 100644
index 0000000..2c1f566
--- /dev/null
+++ b/dojox/widget/nls/RollingList.js
@@ -0,0 +1 @@
+({"empty":"<EMPTY>"})
\ No newline at end of file
diff --git a/dojox/widget/nls/Wizard.js b/dojox/widget/nls/Wizard.js
new file mode 100644
index 0000000..ec10f3f
--- /dev/null
+++ b/dojox/widget/nls/Wizard.js
@@ -0,0 +1 @@
+({"next":"Next","done":"Done","previous":"Previous"})
\ No newline at end of file
diff --git a/dojox/widget/nls/ar/FilePicker.js b/dojox/widget/nls/ar/FilePicker.js
new file mode 100644
index 0000000..01d76ae
--- /dev/null
+++ b/dojox/widget/nls/ar/FilePicker.js
@@ -0,0 +1 @@
+({"name":"الاسم","size":"الحجم (بالبايت) ","path":"‏المسار‏"})
\ No newline at end of file
diff --git a/dojox/widget/nls/ar/Wizard.js b/dojox/widget/nls/ar/Wizard.js
new file mode 100644
index 0000000..c8acda0
--- /dev/null
+++ b/dojox/widget/nls/ar/Wizard.js
@@ -0,0 +1 @@
+({"next":"تالي","done":"اتمام","previous":"‏سابق‏"})
\ No newline at end of file
diff --git a/dojox/widget/nls/ca/FilePicker.js b/dojox/widget/nls/ca/FilePicker.js
new file mode 100644
index 0000000..5902820
--- /dev/null
+++ b/dojox/widget/nls/ca/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Nom","size":"Mida (en bytes)","path":"Camí d'accés"})
\ No newline at end of file
diff --git a/dojox/widget/nls/ca/RollingList.js b/dojox/widget/nls/ca/RollingList.js
new file mode 100644
index 0000000..bc0296e
--- /dev/null
+++ b/dojox/widget/nls/ca/RollingList.js
@@ -0,0 +1 @@
+({"empty":"<BUIT>"})
\ No newline at end of file
diff --git a/dojox/widget/nls/ca/Wizard.js b/dojox/widget/nls/ca/Wizard.js
new file mode 100644
index 0000000..da85941
--- /dev/null
+++ b/dojox/widget/nls/ca/Wizard.js
@@ -0,0 +1 @@
+({"next":"Següent","done":"Fet","previous":"Anterior"})
\ No newline at end of file
diff --git a/dojox/widget/nls/cs/FilePicker.js b/dojox/widget/nls/cs/FilePicker.js
new file mode 100644
index 0000000..54f7366
--- /dev/null
+++ b/dojox/widget/nls/cs/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Název","size":"Velikost (v bajtech)","path":"Cesta"})
\ No newline at end of file
diff --git a/dojox/widget/nls/cs/Wizard.js b/dojox/widget/nls/cs/Wizard.js
new file mode 100644
index 0000000..4075772
--- /dev/null
+++ b/dojox/widget/nls/cs/Wizard.js
@@ -0,0 +1 @@
+({"next":"Další","done":"Hotovo","previous":"Předchozí"})
\ No newline at end of file
diff --git a/dojox/widget/nls/da/FilePicker.js b/dojox/widget/nls/da/FilePicker.js
new file mode 100644
index 0000000..35cc924
--- /dev/null
+++ b/dojox/widget/nls/da/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Navn","size":"Størrelse (i byte)","path":"Sti"})
\ No newline at end of file
diff --git a/dojox/widget/nls/da/Wizard.js b/dojox/widget/nls/da/Wizard.js
new file mode 100644
index 0000000..e447f70
--- /dev/null
+++ b/dojox/widget/nls/da/Wizard.js
@@ -0,0 +1 @@
+({"next":"Næste","done":"Udført","previous":"Forrige"})
\ No newline at end of file
diff --git a/dojox/widget/nls/de/FilePicker.js b/dojox/widget/nls/de/FilePicker.js
new file mode 100644
index 0000000..b33ec5d
--- /dev/null
+++ b/dojox/widget/nls/de/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Name","size":"Größe (in Byte)","path":"Pfad"})
\ No newline at end of file
diff --git a/dojox/widget/nls/de/Wizard.js b/dojox/widget/nls/de/Wizard.js
new file mode 100644
index 0000000..a7f2164
--- /dev/null
+++ b/dojox/widget/nls/de/Wizard.js
@@ -0,0 +1 @@
+({"next":"Weiter","done":"Fertig","previous":"Zurück"})
\ No newline at end of file
diff --git a/dojox/widget/nls/el/FilePicker.js b/dojox/widget/nls/el/FilePicker.js
new file mode 100644
index 0000000..e6d8b24
--- /dev/null
+++ b/dojox/widget/nls/el/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Όνομα","size":"Μέγεθος (σε bytes)","path":"Διαδρομή"})
\ No newline at end of file
diff --git a/dojox/widget/nls/el/Wizard.js b/dojox/widget/nls/el/Wizard.js
new file mode 100644
index 0000000..6a25346
--- /dev/null
+++ b/dojox/widget/nls/el/Wizard.js
@@ -0,0 +1 @@
+({"next":"Επόμενο","done":"Ολοκλήρωση","previous":"Προηγούμενο"})
\ No newline at end of file
diff --git a/dojox/widget/nls/es/FilePicker.js b/dojox/widget/nls/es/FilePicker.js
new file mode 100644
index 0000000..b926640
--- /dev/null
+++ b/dojox/widget/nls/es/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Nombre","size":"Tamaño (en bytes)","path":"Vía de acceso"})
\ No newline at end of file
diff --git a/dojox/widget/nls/es/Wizard.js b/dojox/widget/nls/es/Wizard.js
new file mode 100644
index 0000000..aab5661
--- /dev/null
+++ b/dojox/widget/nls/es/Wizard.js
@@ -0,0 +1 @@
+({"next":"Siguiente","done":"Terminado","previous":"Anterior"})
\ No newline at end of file
diff --git a/dojox/widget/nls/fi/FilePicker.js b/dojox/widget/nls/fi/FilePicker.js
new file mode 100644
index 0000000..df2efcf
--- /dev/null
+++ b/dojox/widget/nls/fi/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Nimi","size":"Koko (tavuina)","path":"Polku"})
\ No newline at end of file
diff --git a/dojox/widget/nls/fi/Wizard.js b/dojox/widget/nls/fi/Wizard.js
new file mode 100644
index 0000000..ea6a9db
--- /dev/null
+++ b/dojox/widget/nls/fi/Wizard.js
@@ -0,0 +1 @@
+({"next":"Seuraava","done":"Valmis","previous":"Edellinen"})
\ No newline at end of file
diff --git a/dojox/widget/nls/fr/FilePicker.js b/dojox/widget/nls/fr/FilePicker.js
new file mode 100644
index 0000000..8b1045f
--- /dev/null
+++ b/dojox/widget/nls/fr/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Nom","size":"Taille (en octets)","path":"Chemin"})
\ No newline at end of file
diff --git a/dojox/widget/nls/fr/Wizard.js b/dojox/widget/nls/fr/Wizard.js
new file mode 100644
index 0000000..779919e
--- /dev/null
+++ b/dojox/widget/nls/fr/Wizard.js
@@ -0,0 +1 @@
+({"next":"Suivant","done":"Terminé","previous":"Précédent"})
\ No newline at end of file
diff --git a/dojox/widget/nls/he/FilePicker.js b/dojox/widget/nls/he/FilePicker.js
new file mode 100644
index 0000000..7b4e52a
--- /dev/null
+++ b/dojox/widget/nls/he/FilePicker.js
@@ -0,0 +1 @@
+({"name":"שם","size":"גודל (בבתים)","path":"נתיב"})
\ No newline at end of file
diff --git a/dojox/widget/nls/he/Wizard.js b/dojox/widget/nls/he/Wizard.js
new file mode 100644
index 0000000..e5ee2ee
--- /dev/null
+++ b/dojox/widget/nls/he/Wizard.js
@@ -0,0 +1 @@
+({"next":"הבא","done":"סיום","previous":"הקודם"})
\ No newline at end of file
diff --git a/dojox/widget/nls/hu/FilePicker.js b/dojox/widget/nls/hu/FilePicker.js
new file mode 100644
index 0000000..8323b89
--- /dev/null
+++ b/dojox/widget/nls/hu/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Név","size":"Méret (byte)","path":"Elérési út"})
\ No newline at end of file
diff --git a/dojox/widget/nls/hu/Wizard.js b/dojox/widget/nls/hu/Wizard.js
new file mode 100644
index 0000000..6ad86c7
--- /dev/null
+++ b/dojox/widget/nls/hu/Wizard.js
@@ -0,0 +1 @@
+({"next":"Következő","done":"Kész","previous":"Előző"})
\ No newline at end of file
diff --git a/dojox/widget/nls/it/FilePicker.js b/dojox/widget/nls/it/FilePicker.js
new file mode 100644
index 0000000..77801d2
--- /dev/null
+++ b/dojox/widget/nls/it/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Nome","size":"Dimensione (in byte)","path":"Percorso"})
\ No newline at end of file
diff --git a/dojox/widget/nls/it/Wizard.js b/dojox/widget/nls/it/Wizard.js
new file mode 100644
index 0000000..78ea64b
--- /dev/null
+++ b/dojox/widget/nls/it/Wizard.js
@@ -0,0 +1 @@
+({"next":"Successivo","done":"Eseguito","previous":"Precedente"})
\ No newline at end of file
diff --git a/dojox/widget/nls/ja/FilePicker.js b/dojox/widget/nls/ja/FilePicker.js
new file mode 100644
index 0000000..61068a9
--- /dev/null
+++ b/dojox/widget/nls/ja/FilePicker.js
@@ -0,0 +1 @@
+({"name":"名前","size":"サイズ (バイト単位)","path":"パス"})
\ No newline at end of file
diff --git a/dojox/widget/nls/ja/Wizard.js b/dojox/widget/nls/ja/Wizard.js
new file mode 100644
index 0000000..6394cb3
--- /dev/null
+++ b/dojox/widget/nls/ja/Wizard.js
@@ -0,0 +1 @@
+({"next":"次へ","done":"完了","previous":"前へ"})
\ No newline at end of file
diff --git a/dojox/widget/nls/ko/FilePicker.js b/dojox/widget/nls/ko/FilePicker.js
new file mode 100644
index 0000000..fd59903
--- /dev/null
+++ b/dojox/widget/nls/ko/FilePicker.js
@@ -0,0 +1 @@
+({"name":"이름","size":"크기(바이트)","path":"경로"})
\ No newline at end of file
diff --git a/dojox/widget/nls/ko/Wizard.js b/dojox/widget/nls/ko/Wizard.js
new file mode 100644
index 0000000..dec3546
--- /dev/null
+++ b/dojox/widget/nls/ko/Wizard.js
@@ -0,0 +1 @@
+({"next":"다음","done":"완료","previous":"이전"})
\ No newline at end of file
diff --git a/dojox/widget/nls/nb/FilePicker.js b/dojox/widget/nls/nb/FilePicker.js
new file mode 100644
index 0000000..ef78320
--- /dev/null
+++ b/dojox/widget/nls/nb/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Navn","size":"Størrelse (i byte)","path":"Bane"})
\ No newline at end of file
diff --git a/dojox/widget/nls/nb/Wizard.js b/dojox/widget/nls/nb/Wizard.js
new file mode 100644
index 0000000..0cbe813
--- /dev/null
+++ b/dojox/widget/nls/nb/Wizard.js
@@ -0,0 +1 @@
+({"next":"Neste","done":"Ferdig","previous":"Forrige"})
\ No newline at end of file
diff --git a/dojox/widget/nls/nl/FilePicker.js b/dojox/widget/nls/nl/FilePicker.js
new file mode 100644
index 0000000..a841a1d
--- /dev/null
+++ b/dojox/widget/nls/nl/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Naam","size":"Grootte (in bytes)","path":"Pad"})
\ No newline at end of file
diff --git a/dojox/widget/nls/nl/Wizard.js b/dojox/widget/nls/nl/Wizard.js
new file mode 100644
index 0000000..d5e680f
--- /dev/null
+++ b/dojox/widget/nls/nl/Wizard.js
@@ -0,0 +1 @@
+({"next":"Volgende","done":"Klaar","previous":"Vorige"})
\ No newline at end of file
diff --git a/dojox/widget/nls/pl/FilePicker.js b/dojox/widget/nls/pl/FilePicker.js
new file mode 100644
index 0000000..5afd4b7
--- /dev/null
+++ b/dojox/widget/nls/pl/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Nazwa","size":"Wielkość (w bajtach)","path":"Ścieżka"})
\ No newline at end of file
diff --git a/dojox/widget/nls/pl/Wizard.js b/dojox/widget/nls/pl/Wizard.js
new file mode 100644
index 0000000..3bcfb9c
--- /dev/null
+++ b/dojox/widget/nls/pl/Wizard.js
@@ -0,0 +1 @@
+({"next":"Następna","done":"Gotowe","previous":"Poprzednia"})
\ No newline at end of file
diff --git a/dojox/widget/nls/pt-pt/FilePicker.js b/dojox/widget/nls/pt-pt/FilePicker.js
new file mode 100644
index 0000000..22e342e
--- /dev/null
+++ b/dojox/widget/nls/pt-pt/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Nome","size":"Tamanho (em bytes)","path":"Caminho"})
\ No newline at end of file
diff --git a/dojox/widget/nls/pt-pt/Wizard.js b/dojox/widget/nls/pt-pt/Wizard.js
new file mode 100644
index 0000000..2b6bb1e
--- /dev/null
+++ b/dojox/widget/nls/pt-pt/Wizard.js
@@ -0,0 +1 @@
+({"next":"Seguinte","done":"Concluído","previous":"Anterior"})
\ No newline at end of file
diff --git a/dojox/widget/nls/pt/FilePicker.js b/dojox/widget/nls/pt/FilePicker.js
new file mode 100644
index 0000000..22e342e
--- /dev/null
+++ b/dojox/widget/nls/pt/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Nome","size":"Tamanho (em bytes)","path":"Caminho"})
\ No newline at end of file
diff --git a/dojox/widget/nls/pt/Wizard.js b/dojox/widget/nls/pt/Wizard.js
new file mode 100644
index 0000000..8f7aa7c
--- /dev/null
+++ b/dojox/widget/nls/pt/Wizard.js
@@ -0,0 +1 @@
+({"next":"Próximo","done":"Concluído","previous":"Anterior"})
\ No newline at end of file
diff --git a/dojox/widget/nls/ru/FilePicker.js b/dojox/widget/nls/ru/FilePicker.js
new file mode 100644
index 0000000..af2d596
--- /dev/null
+++ b/dojox/widget/nls/ru/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Имя","size":"Размер (байт)","path":"Путь"})
\ No newline at end of file
diff --git a/dojox/widget/nls/ru/Wizard.js b/dojox/widget/nls/ru/Wizard.js
new file mode 100644
index 0000000..bbc1b51
--- /dev/null
+++ b/dojox/widget/nls/ru/Wizard.js
@@ -0,0 +1 @@
+({"next":"Далее","done":"Готово","previous":"Назад"})
\ No newline at end of file
diff --git a/dojox/widget/nls/sk/FilePicker.js b/dojox/widget/nls/sk/FilePicker.js
new file mode 100644
index 0000000..c165416
--- /dev/null
+++ b/dojox/widget/nls/sk/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Názov","size":"Veľkosť (v bajtoch)","path":"Cesta"})
\ No newline at end of file
diff --git a/dojox/widget/nls/sk/RollingList.js b/dojox/widget/nls/sk/RollingList.js
new file mode 100644
index 0000000..bcfe692
--- /dev/null
+++ b/dojox/widget/nls/sk/RollingList.js
@@ -0,0 +1 @@
+({"empty":"<PRÁZDNY>"})
\ No newline at end of file
diff --git a/dojox/widget/nls/sk/Wizard.js b/dojox/widget/nls/sk/Wizard.js
new file mode 100644
index 0000000..d740aa4
--- /dev/null
+++ b/dojox/widget/nls/sk/Wizard.js
@@ -0,0 +1 @@
+({"next":"Ďalej","done":"Hotovo","previous":"Späť"})
\ No newline at end of file
diff --git a/dojox/widget/nls/sl/FilePicker.js b/dojox/widget/nls/sl/FilePicker.js
new file mode 100644
index 0000000..f977154
--- /dev/null
+++ b/dojox/widget/nls/sl/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Ime","size":"Velikost (v bajtih)","path":"Pot"})
\ No newline at end of file
diff --git a/dojox/widget/nls/sl/RollingList.js b/dojox/widget/nls/sl/RollingList.js
new file mode 100644
index 0000000..37d408f
--- /dev/null
+++ b/dojox/widget/nls/sl/RollingList.js
@@ -0,0 +1 @@
+({"empty":"<PRAZNO>"})
\ No newline at end of file
diff --git a/dojox/widget/nls/sl/Wizard.js b/dojox/widget/nls/sl/Wizard.js
new file mode 100644
index 0000000..a89a23c
--- /dev/null
+++ b/dojox/widget/nls/sl/Wizard.js
@@ -0,0 +1 @@
+({"next":"Naprej","done":"Opravljeno","previous":"Nazaj"})
\ No newline at end of file
diff --git a/dojox/widget/nls/sv/FilePicker.js b/dojox/widget/nls/sv/FilePicker.js
new file mode 100644
index 0000000..1c66552
--- /dev/null
+++ b/dojox/widget/nls/sv/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Namn","size":"Storlek (byte)","path":"Sökväg"})
\ No newline at end of file
diff --git a/dojox/widget/nls/sv/Wizard.js b/dojox/widget/nls/sv/Wizard.js
new file mode 100644
index 0000000..ae75b03
--- /dev/null
+++ b/dojox/widget/nls/sv/Wizard.js
@@ -0,0 +1 @@
+({"next":"Nästa","done":"Stäng","previous":"Föregående"})
\ No newline at end of file
diff --git a/dojox/widget/nls/th/FilePicker.js b/dojox/widget/nls/th/FilePicker.js
new file mode 100644
index 0000000..362f1c1
--- /dev/null
+++ b/dojox/widget/nls/th/FilePicker.js
@@ -0,0 +1 @@
+({"name":"ชื่อ","size":"ขนาด (ไบต์)","path":"พาธ"})
\ No newline at end of file
diff --git a/dojox/widget/nls/th/RollingList.js b/dojox/widget/nls/th/RollingList.js
new file mode 100644
index 0000000..fb5711f
--- /dev/null
+++ b/dojox/widget/nls/th/RollingList.js
@@ -0,0 +1 @@
+({"empty":"<ว่าง>"})
\ No newline at end of file
diff --git a/dojox/widget/nls/th/Wizard.js b/dojox/widget/nls/th/Wizard.js
new file mode 100644
index 0000000..d9b793a
--- /dev/null
+++ b/dojox/widget/nls/th/Wizard.js
@@ -0,0 +1 @@
+({"next":"ถัดไป","done":"เสร็จสิ้น","previous":"ก่อนหน้า"})
\ No newline at end of file
diff --git a/dojox/widget/nls/tr/FilePicker.js b/dojox/widget/nls/tr/FilePicker.js
new file mode 100644
index 0000000..2c0d44c
--- /dev/null
+++ b/dojox/widget/nls/tr/FilePicker.js
@@ -0,0 +1 @@
+({"name":"Ad","size":"Boyut (bayt cinsinden)","path":"Yol"})
\ No newline at end of file
diff --git a/dojox/widget/nls/tr/Wizard.js b/dojox/widget/nls/tr/Wizard.js
new file mode 100644
index 0000000..752b8ac
--- /dev/null
+++ b/dojox/widget/nls/tr/Wizard.js
@@ -0,0 +1 @@
+({"next":"İleri","done":"Bitti","previous":"Geri"})
\ No newline at end of file
diff --git a/dojox/widget/nls/zh-tw/FilePicker.js b/dojox/widget/nls/zh-tw/FilePicker.js
new file mode 100644
index 0000000..9053ece
--- /dev/null
+++ b/dojox/widget/nls/zh-tw/FilePicker.js
@@ -0,0 +1 @@
+({"name":"名稱","size":"大小 (以位元組為單位)","path":"路徑"})
\ No newline at end of file
diff --git a/dojox/widget/nls/zh-tw/Wizard.js b/dojox/widget/nls/zh-tw/Wizard.js
new file mode 100644
index 0000000..fe45203
--- /dev/null
+++ b/dojox/widget/nls/zh-tw/Wizard.js
@@ -0,0 +1 @@
+({"next":"下一步","done":"完成","previous":"上一步"})
\ No newline at end of file
diff --git a/dojox/widget/nls/zh/FilePicker.js b/dojox/widget/nls/zh/FilePicker.js
new file mode 100644
index 0000000..3efdbc4
--- /dev/null
+++ b/dojox/widget/nls/zh/FilePicker.js
@@ -0,0 +1 @@
+({"name":"名称","size":"大小(字节","path":"路径"})
\ No newline at end of file
diff --git a/dojox/widget/nls/zh/Wizard.js b/dojox/widget/nls/zh/Wizard.js
new file mode 100644
index 0000000..fe45203
--- /dev/null
+++ b/dojox/widget/nls/zh/Wizard.js
@@ -0,0 +1 @@
+({"next":"下一步","done":"完成","previous":"上一步"})
\ No newline at end of file
diff --git a/dojox/wire.js b/dojox/wire.js
new file mode 100644
index 0000000..b4886f1
--- /dev/null
+++ b/dojox/wire.js
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.wire"]){
+dojo._hasResource["dojox.wire"]=true;
+dojo.provide("dojox.wire");
+dojo.require("dojox.wire._base");
+}
diff --git a/dojox/wire/CompositeWire.js b/dojox/wire/CompositeWire.js
new file mode 100644
index 0000000..1790d94
--- /dev/null
+++ b/dojox/wire/CompositeWire.js
@@ -0,0 +1,44 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.wire.CompositeWire"]){
+dojo._hasResource["dojox.wire.CompositeWire"]=true;
+dojo.provide("dojox.wire.CompositeWire");
+dojo.require("dojox.wire._base");
+dojo.require("dojox.wire.Wire");
+dojo.declare("dojox.wire.CompositeWire",dojox.wire.Wire,{_wireClass:"dojox.wire.CompositeWire",constructor:function(_1){
+this._initializeChildren(this.children);
+},_getValue:function(_2){
+if(!_2||!this.children){
+return _2;
+}
+var _3=(dojo.isArray(this.children)?[]:{});
+for(var c in this.children){
+_3[c]=this.children[c].getValue(_2);
+}
+return _3;
+},_setValue:function(_5,_6){
+if(!_5||!this.children){
+return _5;
+}
+for(var c in this.children){
+this.children[c].setValue(_6[c],_5);
+}
+return _5;
+},_initializeChildren:function(_8){
+if(!_8){
+return;
+}
+for(var c in _8){
+var _a=_8[c];
+_a.parent=this;
+if(!dojox.wire.isWire(_a)){
+_8[c]=dojox.wire.create(_a);
+}
+}
+}});
+}
diff --git a/dojox/wire/DataWire.js b/dojox/wire/DataWire.js
new file mode 100644
index 0000000..6f3ef7f
--- /dev/null
+++ b/dojox/wire/DataWire.js
@@ -0,0 +1,84 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.wire.DataWire"]){
+dojo._hasResource["dojox.wire.DataWire"]=true;
+dojo.provide("dojox.wire.DataWire");
+dojo.require("dojox.wire.Wire");
+dojo.declare("dojox.wire.DataWire",dojox.wire.Wire,{_wireClass:"dojox.wire.DataWire",constructor:function(_1){
+if(!this.dataStore&&this.parent){
+this.dataStore=this.parent.dataStore;
+}
+},_getValue:function(_2){
+if(!_2||!this.attribute||!this.dataStore){
+return _2;
+}
+var _3=_2;
+var _4=this.attribute.split(".");
+for(var i in _4){
+_3=this._getAttributeValue(_3,_4[i]);
+if(!_3){
+return undefined;
+}
+}
+return _3;
+},_setValue:function(_6,_7){
+if(!_6||!this.attribute||!this.dataStore){
+return _6;
+}
+var _8=_6;
+var _9=this.attribute.split(".");
+var _a=_9.length-1;
+for(var i=0;i<_a;i++){
+_8=this._getAttributeValue(_8,_9[i]);
+if(!_8){
+return undefined;
+}
+}
+this._setAttributeValue(_8,_9[_a],_7);
+return _6;
+},_getAttributeValue:function(_c,_d){
+var _e=undefined;
+var i1=_d.indexOf("[");
+if(i1>=0){
+var i2=_d.indexOf("]");
+var _11=_d.substring(i1+1,i2);
+_d=_d.substring(0,i1);
+var _12=this.dataStore.getValues(_c,_d);
+if(_12){
+if(!_11){
+_e=_12;
+}else{
+_e=_12[_11];
+}
+}
+}else{
+_e=this.dataStore.getValue(_c,_d);
+}
+return _e;
+},_setAttributeValue:function(_13,_14,_15){
+var i1=_14.indexOf("[");
+if(i1>=0){
+var i2=_14.indexOf("]");
+var _18=_14.substring(i1+1,i2);
+_14=_14.substring(0,i1);
+var _19=null;
+if(!_18){
+_19=_15;
+}else{
+_19=this.dataStore.getValues(_13,_14);
+if(!_19){
+_19=[];
+}
+_19[_18]=_15;
+}
+this.dataStore.setValues(_13,_14,_19);
+}else{
+this.dataStore.setValue(_13,_14,_15);
+}
+}});
+}
diff --git a/dojox/wire/README b/dojox/wire/README
new file mode 100644
index 0000000..d33edee
--- /dev/null
+++ b/dojox/wire/README
@@ -0,0 +1,54 @@
+-------------------------------------------------------------------------------
+DojoX Wire
+-------------------------------------------------------------------------------
+Version 1.0
+Release date: 05/29/2007
+-------------------------------------------------------------------------------
+Project state: production
+-------------------------------------------------------------------------------
+Project authors
+	Jared Jurkiewicz (jared.jurkiewicz at gmail.com)
+-------------------------------------------------------------------------------
+Project description
+
+The DojoX Wire project is a set of functions that build a generic data binding
+and service invocation library to simplify how data values across a wide
+variety of widget and non-widget JavaScript constructs are accessed, updated,
+and passed to and from services.  It also provides a set of widgets 
+within the dojox.wire.ml package to allow for declarative data binding 
+definitions in addition to the programmatic APIs.
+
+In essense, this project is an API to provide a simplified way of doing MVC
+patterns in the client.
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+DojoX Wire has dependencies on core dojo, the dijit widget system (for classes 
+in the dojox.wire.ml package), dojox.data, dojox.xml, and the D.O.H. unit test 
+framework.
+-------------------------------------------------------------------------------
+Documentation:
+
+See the Dojo API tool (http://dojotoolkit.org/api)
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/wire.js
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/wire/*
+
+Install into the following directory structure:
+/dojox/wire/
+
+...which should be at the same level as your Dojo checkout.
+
+It should look like:
+/dojox/wire.js
+/dojox/wire/*
+
+Require in dojox.wire for all baseline functions (dojox.wire.connect, 
+dojox.wire.register, etc).  For specific Wire classes,
+require in the appropriate dojox.wire.<Class>.
+-------------------------------------------------------------------------------
+
diff --git a/dojox/wire/TableAdapter.js b/dojox/wire/TableAdapter.js
new file mode 100644
index 0000000..18632ec
--- /dev/null
+++ b/dojox/wire/TableAdapter.js
@@ -0,0 +1,37 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.wire.TableAdapter"]){
+dojo._hasResource["dojox.wire.TableAdapter"]=true;
+dojo.provide("dojox.wire.TableAdapter");
+dojo.require("dojox.wire.CompositeWire");
+dojo.declare("dojox.wire.TableAdapter",dojox.wire.CompositeWire,{_wireClass:"dojox.wire.TableAdapter",constructor:function(_1){
+this._initializeChildren(this.columns);
+},_getValue:function(_2){
+if(!_2||!this.columns){
+return _2;
+}
+var _3=_2;
+if(!dojo.isArray(_3)){
+_3=[_3];
+}
+var _4=[];
+for(var i in _3){
+var _6=this._getRow(_3[i]);
+_4.push(_6);
+}
+return _4;
+},_setValue:function(_7,_8){
+throw new Error("Unsupported API: "+this._wireClass+"._setValue");
+},_getRow:function(_9){
+var _a=(dojo.isArray(this.columns)?[]:{});
+for(var c in this.columns){
+_a[c]=this.columns[c].getValue(_9);
+}
+return _a;
+}});
+}
diff --git a/dojox/wire/TextAdapter.js b/dojox/wire/TextAdapter.js
new file mode 100644
index 0000000..54466fc
--- /dev/null
+++ b/dojox/wire/TextAdapter.js
@@ -0,0 +1,40 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.wire.TextAdapter"]){
+dojo._hasResource["dojox.wire.TextAdapter"]=true;
+dojo.provide("dojox.wire.TextAdapter");
+dojo.require("dojox.wire.CompositeWire");
+dojo.declare("dojox.wire.TextAdapter",dojox.wire.CompositeWire,{_wireClass:"dojox.wire.TextAdapter",constructor:function(_1){
+this._initializeChildren(this.segments);
+if(!this.delimiter){
+this.delimiter="";
+}
+},_getValue:function(_2){
+if(!_2||!this.segments){
+return _2;
+}
+var _3="";
+for(var i in this.segments){
+var _5=this.segments[i].getValue(_2);
+_3=this._addSegment(_3,_5);
+}
+return _3;
+},_setValue:function(_6,_7){
+throw new Error("Unsupported API: "+this._wireClass+"._setValue");
+},_addSegment:function(_8,_9){
+if(!_9){
+return _8;
+}else{
+if(!_8){
+return _9;
+}else{
+return _8+this.delimiter+_9;
+}
+}
+}});
+}
diff --git a/dojox/wire/TreeAdapter.js b/dojox/wire/TreeAdapter.js
new file mode 100644
index 0000000..3c96a41
--- /dev/null
+++ b/dojox/wire/TreeAdapter.js
@@ -0,0 +1,88 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.wire.TreeAdapter"]){
+dojo._hasResource["dojox.wire.TreeAdapter"]=true;
+dojo.provide("dojox.wire.TreeAdapter");
+dojo.require("dojox.wire.CompositeWire");
+dojo.declare("dojox.wire.TreeAdapter",dojox.wire.CompositeWire,{_wireClass:"dojox.wire.TreeAdapter",constructor:function(_1){
+this._initializeChildren(this.nodes);
+},_getValue:function(_2){
+if(!_2||!this.nodes){
+return _2;
+}
+var _3=_2;
+if(!dojo.isArray(_3)){
+_3=[_3];
+}
+var _4=[];
+for(var i in _3){
+for(var i2 in this.nodes){
+_4=_4.concat(this._getNodes(_3[i],this.nodes[i2]));
+}
+}
+return _4;
+},_setValue:function(_7,_8){
+throw new Error("Unsupported API: "+this._wireClass+"._setValue");
+},_initializeChildren:function(_9){
+if(!_9){
+return;
+}
+for(var i in _9){
+var _b=_9[i];
+if(_b.node){
+_b.node.parent=this;
+if(!dojox.wire.isWire(_b.node)){
+_b.node=dojox.wire.create(_b.node);
+}
+}
+if(_b.title){
+_b.title.parent=this;
+if(!dojox.wire.isWire(_b.title)){
+_b.title=dojox.wire.create(_b.title);
+}
+}
+if(_b.children){
+this._initializeChildren(_b.children);
+}
+}
+},_getNodes:function(_c,_d){
+var _e=null;
+if(_d.node){
+_e=_d.node.getValue(_c);
+if(!_e){
+return [];
+}
+if(!dojo.isArray(_e)){
+_e=[_e];
+}
+}else{
+_e=[_c];
+}
+var _f=[];
+for(var i in _e){
+_c=_e[i];
+var _11={};
+if(_d.title){
+_11.title=_d.title.getValue(_c);
+}else{
+_11.title=_c;
+}
+if(_d.children){
+var _12=[];
+for(var i2 in _d.children){
+_12=_12.concat(this._getNodes(_c,_d.children[i2]));
+}
+if(_12.length>0){
+_11.children=_12;
+}
+}
+_f.push(_11);
+}
+return _f;
+}});
+}
diff --git a/dojox/wire/Wire.js b/dojox/wire/Wire.js
new file mode 100644
index 0000000..22a6fc9
--- /dev/null
+++ b/dojox/wire/Wire.js
@@ -0,0 +1,231 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.wire.Wire"]){
+dojo._hasResource["dojox.wire.Wire"]=true;
+dojo.provide("dojox.wire.Wire");
+dojo.require("dojox.wire._base");
+dojo.declare("dojox.wire.Wire",null,{_wireClass:"dojox.wire.Wire",constructor:function(_1){
+dojo.mixin(this,_1);
+if(this.converter){
+if(dojo.isString(this.converter)){
+var _2=dojo.getObject(this.converter);
+if(dojo.isFunction(_2)){
+try{
+var _3=new _2();
+if(_3&&!dojo.isFunction(_3["convert"])){
+this.converter={convert:_2};
+}else{
+this.converter=_3;
+}
+}
+catch(e){
+}
+}else{
+if(dojo.isObject(_2)){
+if(dojo.isFunction(_2["convert"])){
+this.converter=_2;
+}
+}
+}
+if(dojo.isString(this.converter)){
+var _4=dojox.wire._getClass(this.converter);
+if(_4){
+this.converter=new _4();
+}else{
+this.converter=undefined;
+}
+}
+}else{
+if(dojo.isFunction(this.converter)){
+this.converter={convert:this.converter};
+}
+}
+}
+},getValue:function(_5){
+var _6=undefined;
+if(dojox.wire.isWire(this.object)){
+_6=this.object.getValue(_5);
+}else{
+_6=(this.object||_5);
+}
+if(this.property){
+var _7=this.property.split(".");
+for(var i in _7){
+if(!_6){
+return _6;
+}
+_6=this._getPropertyValue(_6,_7[i]);
+}
+}
+var _9=undefined;
+if(this._getValue){
+_9=this._getValue(_6);
+}else{
+_9=_6;
+}
+if(_9){
+if(this.type){
+if(this.type=="string"){
+_9=_9.toString();
+}else{
+if(this.type=="number"){
+_9=parseInt(_9,10);
+}else{
+if(this.type=="boolean"){
+_9=(_9!="false");
+}else{
+if(this.type=="array"){
+if(!dojo.isArray(_9)){
+_9=[_9];
+}
+}
+}
+}
+}
+}
+if(this.converter&&this.converter.convert){
+_9=this.converter.convert(_9,this);
+}
+}
+return _9;
+},setValue:function(_a,_b){
+var _c=undefined;
+if(dojox.wire.isWire(this.object)){
+_c=this.object.getValue(_b);
+}else{
+_c=(this.object||_b);
+}
+var _d=undefined;
+var o;
+if(this.property){
+if(!_c){
+if(dojox.wire.isWire(this.object)){
+_c={};
+this.object.setValue(_c,_b);
+}else{
+throw new Error(this._wireClass+".setValue(): invalid object");
+}
+}
+var _f=this.property.split(".");
+var _10=_f.length-1;
+for(var i=0;i<_10;i++){
+var p=_f[i];
+o=this._getPropertyValue(_c,p);
+if(!o){
+o={};
+this._setPropertyValue(_c,p,o);
+}
+_c=o;
+}
+_d=_f[_10];
+}
+if(this._setValue){
+if(_d){
+o=this._getPropertyValue(_c,_d);
+if(!o){
+o={};
+this._setPropertyValue(_c,_d,o);
+}
+_c=o;
+}
+var _13=this._setValue(_c,_a);
+if(!_c&&_13){
+if(dojox.wire.isWire(this.object)){
+this.object.setValue(_13,_b);
+}else{
+throw new Error(this._wireClass+".setValue(): invalid object");
+}
+}
+}else{
+if(_d){
+this._setPropertyValue(_c,_d,_a);
+}else{
+if(dojox.wire.isWire(this.object)){
+this.object.setValue(_a,_b);
+}else{
+throw new Error(this._wireClass+".setValue(): invalid property");
+}
+}
+}
+},_getPropertyValue:function(_14,_15){
+var _16=undefined;
+var i1=_15.indexOf("[");
+if(i1>=0){
+var i2=_15.indexOf("]");
+var _19=_15.substring(i1+1,i2);
+var _1a=null;
+if(i1===0){
+_1a=_14;
+}else{
+_15=_15.substring(0,i1);
+_1a=this._getPropertyValue(_14,_15);
+if(_1a&&!dojo.isArray(_1a)){
+_1a=[_1a];
+}
+}
+if(_1a){
+_16=_1a[_19];
+}
+}else{
+if(_14.getPropertyValue){
+_16=_14.getPropertyValue(_15);
+}else{
+var _1b="get"+_15.charAt(0).toUpperCase()+_15.substring(1);
+if(this._useAttr(_14)){
+_16=_14.attr(_15);
+}else{
+if(_14[_1b]){
+_16=_14[_1b]();
+}else{
+_16=_14[_15];
+}
+}
+}
+}
+return _16;
+},_setPropertyValue:function(_1c,_1d,_1e){
+var i1=_1d.indexOf("[");
+if(i1>=0){
+var i2=_1d.indexOf("]");
+var _21=_1d.substring(i1+1,i2);
+var _22=null;
+if(i1===0){
+_22=_1c;
+}else{
+_1d=_1d.substring(0,i1);
+_22=this._getPropertyValue(_1c,_1d);
+if(!_22){
+_22=[];
+this._setPropertyValue(_1c,_1d,_22);
+}
+}
+_22[_21]=_1e;
+}else{
+if(_1c.setPropertyValue){
+_1c.setPropertyValue(_1d,_1e);
+}else{
+var _23="set"+_1d.charAt(0).toUpperCase()+_1d.substring(1);
+if(this._useAttr(_1c)){
+_1c.attr(_1d,_1e);
+}else{
+if(_1c[_23]){
+_1c[_23](_1e);
+}else{
+_1c[_1d]=_1e;
+}
+}
+}
+}
+},_useAttr:function(_24){
+var _25=false;
+if(dojo.isFunction(_24.attr)){
+_25=true;
+}
+return _25;
+}});
+}
diff --git a/dojox/wire/XmlWire.js b/dojox/wire/XmlWire.js
new file mode 100644
index 0000000..e3defd5
--- /dev/null
+++ b/dojox/wire/XmlWire.js
@@ -0,0 +1,135 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.wire.XmlWire"]){
+dojo._hasResource["dojox.wire.XmlWire"]=true;
+dojo.provide("dojox.wire.XmlWire");
+dojo.require("dojox.xml.parser");
+dojo.require("dojox.wire.Wire");
+dojo.declare("dojox.wire.XmlWire",dojox.wire.Wire,{_wireClass:"dojox.wire.XmlWire",constructor:function(_1){
+},_getValue:function(_2){
+if(!_2||!this.path){
+return _2;
+}
+var _3=_2;
+var _4=this.path;
+var i;
+if(_4.charAt(0)=="/"){
+i=_4.indexOf("/",1);
+_4=_4.substring(i+1);
+}
+var _6=_4.split("/");
+var _7=_6.length-1;
+for(i=0;i<_7;i++){
+_3=this._getChildNode(_3,_6[i]);
+if(!_3){
+return undefined;
+}
+}
+var _8=this._getNodeValue(_3,_6[_7]);
+return _8;
+},_setValue:function(_9,_a){
+if(!this.path){
+return _9;
+}
+var _b=_9;
+var _c=this._getDocument(_b);
+var _d=this.path;
+var i;
+if(_d.charAt(0)=="/"){
+i=_d.indexOf("/",1);
+if(!_b){
+var _f=_d.substring(1,i);
+_b=_c.createElement(_f);
+_9=_b;
+}
+_d=_d.substring(i+1);
+}else{
+if(!_b){
+return undefined;
+}
+}
+var _10=_d.split("/");
+var _11=_10.length-1;
+for(i=0;i<_11;i++){
+var _12=this._getChildNode(_b,_10[i]);
+if(!_12){
+_12=_c.createElement(_10[i]);
+_b.appendChild(_12);
+}
+_b=_12;
+}
+this._setNodeValue(_b,_10[_11],_a);
+return _9;
+},_getNodeValue:function(_13,exp){
+var _15=undefined;
+if(exp.charAt(0)=="@"){
+var _16=exp.substring(1);
+_15=_13.getAttribute(_16);
+}else{
+if(exp=="text()"){
+var _17=_13.firstChild;
+if(_17){
+_15=_17.nodeValue;
+}
+}else{
+_15=[];
+for(var i=0;i<_13.childNodes.length;i++){
+var _19=_13.childNodes[i];
+if(_19.nodeType===1&&_19.nodeName==exp){
+_15.push(_19);
+}
+}
+}
+}
+return _15;
+},_setNodeValue:function(_1a,exp,_1c){
+if(exp.charAt(0)=="@"){
+var _1d=exp.substring(1);
+if(_1c){
+_1a.setAttribute(_1d,_1c);
+}else{
+_1a.removeAttribute(_1d);
+}
+}else{
+if(exp=="text()"){
+while(_1a.firstChild){
+_1a.removeChild(_1a.firstChild);
+}
+if(_1c){
+var _1e=this._getDocument(_1a).createTextNode(_1c);
+_1a.appendChild(_1e);
+}
+}
+}
+},_getChildNode:function(_1f,_20){
+var _21=1;
+var i1=_20.indexOf("[");
+if(i1>=0){
+var i2=_20.indexOf("]");
+_21=_20.substring(i1+1,i2);
+_20=_20.substring(0,i1);
+}
+var _24=1;
+for(var i=0;i<_1f.childNodes.length;i++){
+var _26=_1f.childNodes[i];
+if(_26.nodeType===1&&_26.nodeName==_20){
+if(_24==_21){
+return _26;
+}
+_24++;
+}
+}
+return null;
+},_getDocument:function(_27){
+if(_27){
+return (_27.nodeType==9?_27:_27.ownerDocument);
+}else{
+return dojox.xml.parser.parse();
+}
+}});
+}
diff --git a/dojox/wire/_base.js b/dojox/wire/_base.js
new file mode 100644
index 0000000..bc50dad
--- /dev/null
+++ b/dojox/wire/_base.js
@@ -0,0 +1,102 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.wire._base"]){
+dojo._hasResource["dojox.wire._base"]=true;
+dojo.provide("dojox.wire._base");
+dojox.wire._defaultWireClass="dojox.wire.Wire";
+dojox.wire._wireClasses={"attribute":"dojox.wire.DataWire","path":"dojox.wire.XmlWire","children":"dojox.wire.CompositeWire","columns":"dojox.wire.TableAdapter","nodes":"dojox.wire.TreeAdapter","segments":"dojox.wire.TextAdapter"};
+dojox.wire.register=function(_1,_2){
+if(!_1||!_2){
+return;
+}
+if(dojox.wire._wireClasses[_2]){
+return;
+}
+dojox.wire._wireClasses[_2]=_1;
+};
+dojox.wire._getClass=function(_3){
+dojo["require"](_3);
+return dojo.getObject(_3);
+};
+dojox.wire.create=function(_4){
+if(!_4){
+_4={};
+}
+var _5=_4.wireClass;
+if(_5){
+if(dojo.isString(_5)){
+_5=dojox.wire._getClass(_5);
+}
+}else{
+for(var _6 in _4){
+if(!_4[_6]){
+continue;
+}
+_5=dojox.wire._wireClasses[_6];
+if(_5){
+if(dojo.isString(_5)){
+_5=dojox.wire._getClass(_5);
+dojox.wire._wireClasses[_6]=_5;
+}
+break;
+}
+}
+}
+if(!_5){
+if(dojo.isString(dojox.wire._defaultWireClass)){
+dojox.wire._defaultWireClass=dojox.wire._getClass(dojox.wire._defaultWireClass);
+}
+_5=dojox.wire._defaultWireClass;
+}
+return new _5(_4);
+};
+dojox.wire.isWire=function(_7){
+return (_7&&_7._wireClass);
+};
+dojox.wire.transfer=function(_8,_9,_a,_b){
+if(!_8||!_9){
+return;
+}
+if(!dojox.wire.isWire(_8)){
+_8=dojox.wire.create(_8);
+}
+if(!dojox.wire.isWire(_9)){
+_9=dojox.wire.create(_9);
+}
+var _c=_8.getValue(_a);
+_9.setValue(_c,(_b||_a));
+};
+dojox.wire.connect=function(_d,_e,_f){
+if(!_d||!_e||!_f){
+return;
+}
+var _10={topic:_d.topic};
+if(_d.topic){
+_10.handle=dojo.subscribe(_d.topic,function(){
+dojox.wire.transfer(_e,_f,arguments);
+});
+}else{
+if(_d.event){
+_10.handle=dojo.connect(_d.scope,_d.event,function(){
+dojox.wire.transfer(_e,_f,arguments);
+});
+}
+}
+return _10;
+};
+dojox.wire.disconnect=function(_11){
+if(!_11||!_11.handle){
+return;
+}
+if(_11.topic){
+dojo.unsubscribe(_11.handle);
+}else{
+dojo.disconnect(_11.handle);
+}
+};
+}
diff --git a/dojox/wire/ml/Action.js b/dojox/wire/ml/Action.js
new file mode 100644
index 0000000..8bed3f7
--- /dev/null
+++ b/dojox/wire/ml/Action.js
@@ -0,0 +1,113 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.wire.ml.Action"]){
+dojo._hasResource["dojox.wire.ml.Action"]=true;
+dojo.provide("dojox.wire.ml.Action");
+dojo.provide("dojox.wire.ml.ActionFilter");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Container");
+dojo.require("dojox.wire.Wire");
+dojo.require("dojox.wire.ml.util");
+dojo.declare("dojox.wire.ml.Action",[dijit._Widget,dijit._Container],{trigger:"",triggerEvent:"",triggerTopic:"",postCreate:function(){
+this._connect();
+},_connect:function(){
+if(this.triggerEvent){
+if(this.trigger){
+var _1=dojox.wire.ml._getValue(this.trigger);
+if(_1){
+if(!_1[this.triggerEvent]){
+_1[this.triggerEvent]=function(){
+};
+}
+this._triggerHandle=dojo.connect(_1,this.triggerEvent,this,"run");
+}
+}else{
+var _2=this.triggerEvent.toLowerCase();
+if(_2=="onload"){
+var _3=this;
+dojo.addOnLoad(function(){
+_3._run.apply(_3,arguments);
+});
+}
+}
+}else{
+if(this.triggerTopic){
+this._triggerHandle=dojo.subscribe(this.triggerTopic,this,"run");
+}
+}
+},_disconnect:function(){
+if(this._triggerHandle){
+if(this.triggerTopic){
+dojo.unsubscribe(this.triggerTopic,this._triggerHandle);
+}else{
+dojo.disconnect(this._triggerHandle);
+}
+}
+},run:function(){
+var _4=this.getChildren();
+for(var i in _4){
+var _6=_4[i];
+if(_6 instanceof dojox.wire.ml.ActionFilter){
+if(!_6.filter.apply(_6,arguments)){
+return;
+}
+}
+}
+this._run.apply(this,arguments);
+},_run:function(){
+var _7=this.getChildren();
+for(var i in _7){
+var _9=_7[i];
+if(_9 instanceof dojox.wire.ml.Action){
+_9.run.apply(_9,arguments);
+}
+}
+},uninitialize:function(){
+this._disconnect();
+return true;
+}});
+dojo.declare("dojox.wire.ml.ActionFilter",dijit._Widget,{required:"",requiredValue:"",type:"",message:"",error:"",filter:function(){
+if(this.required===""){
+return true;
+}else{
+var _a=dojox.wire.ml._getValue(this.required,arguments);
+if(this.requiredValue===""){
+if(_a){
+return true;
+}
+}else{
+var _b=this.requiredValue;
+if(this.type!==""){
+var _c=this.type.toLowerCase();
+if(_c==="boolean"){
+if(_b.toLowerCase()==="false"){
+_b=false;
+}else{
+_b=true;
+}
+}else{
+if(_c==="number"){
+_b=parseInt(_b,10);
+}
+}
+}
+if(_a===_b){
+return true;
+}
+}
+}
+if(this.message){
+if(this.error){
+dojox.wire.ml._setValue(this.error,this.message);
+}else{
+alert(this.message);
+}
+}
+return false;
+}});
+}
diff --git a/dojox/wire/ml/Data.js b/dojox/wire/ml/Data.js
new file mode 100644
index 0000000..12d794d
--- /dev/null
+++ b/dojox/wire/ml/Data.js
@@ -0,0 +1,81 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.wire.ml.Data"]){
+dojo._hasResource["dojox.wire.ml.Data"]=true;
+dojo.provide("dojox.wire.ml.Data");
+dojo.provide("dojox.wire.ml.DataProperty");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Container");
+dojo.require("dojox.wire.ml.util");
+dojo.declare("dojox.wire.ml.Data",[dijit._Widget,dijit._Container],{startup:function(){
+this._initializeProperties();
+},_initializeProperties:function(_1){
+if(!this._properties||_1){
+this._properties={};
+}
+var _2=this.getChildren();
+for(var i in _2){
+var _4=_2[i];
+if((_4 instanceof dojox.wire.ml.DataProperty)&&_4.name){
+this.setPropertyValue(_4.name,_4.getValue());
+}
+}
+},getPropertyValue:function(_5){
+return this._properties[_5];
+},setPropertyValue:function(_6,_7){
+this._properties[_6]=_7;
+}});
+dojo.declare("dojox.wire.ml.DataProperty",[dijit._Widget,dijit._Container],{name:"",type:"",value:"",_getValueAttr:function(){
+return this.getValue();
+},getValue:function(){
+var _8=this.value;
+if(this.type){
+if(this.type=="number"){
+_8=parseInt(_8);
+}else{
+if(this.type=="boolean"){
+_8=(_8=="true");
+}else{
+if(this.type=="array"){
+_8=[];
+var _9=this.getChildren();
+for(var i in _9){
+var _b=_9[i];
+if(_b instanceof dojox.wire.ml.DataProperty){
+_8.push(_b.getValue());
+}
+}
+}else{
+if(this.type=="object"){
+_8={};
+var _9=this.getChildren();
+for(var i in _9){
+var _b=_9[i];
+if((_b instanceof dojox.wire.ml.DataProperty)&&_b.name){
+_8[_b.name]=_b.getValue();
+}
+}
+}else{
+if(this.type=="element"){
+_8=new dojox.wire.ml.XmlElement(_8);
+var _9=this.getChildren();
+for(var i in _9){
+var _b=_9[i];
+if((_b instanceof dojox.wire.ml.DataProperty)&&_b.name){
+_8.setPropertyValue(_b.name,_b.getValue());
+}
+}
+}
+}
+}
+}
+}
+}
+return _8;
+}});
+}
diff --git a/dojox/wire/ml/DataStore.js b/dojox/wire/ml/DataStore.js
new file mode 100644
index 0000000..e9fe89d
--- /dev/null
+++ b/dojox/wire/ml/DataStore.js
@@ -0,0 +1,45 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.wire.ml.DataStore"]){
+dojo._hasResource["dojox.wire.ml.DataStore"]=true;
+dojo.provide("dojox.wire.ml.DataStore");
+dojo.require("dijit._Widget");
+dojo.require("dojox.wire._base");
+dojo.declare("dojox.wire.ml.DataStore",dijit._Widget,{storeClass:"",postCreate:function(){
+this.store=this._createStore();
+},_createStore:function(){
+if(!this.storeClass){
+return null;
+}
+var _1=dojox.wire._getClass(this.storeClass);
+if(!_1){
+return null;
+}
+var _2={};
+var _3=this.domNode.attributes;
+for(var i=0;i<_3.length;i++){
+var a=_3.item(i);
+if(a.specified&&!this[a.nodeName]){
+_2[a.nodeName]=a.nodeValue;
+}
+}
+return new _1(_2);
+},getFeatures:function(){
+return this.store.getFeatures();
+},fetch:function(_6){
+return this.store.fetch(_6);
+},save:function(_7){
+this.store.save(_7);
+},newItem:function(_8){
+return this.store.newItem(_8);
+},deleteItem:function(_9){
+return this.store.deleteItem(_9);
+},revert:function(){
+return this.store.revert();
+}});
+}
diff --git a/dojox/wire/ml/Invocation.js b/dojox/wire/ml/Invocation.js
new file mode 100644
index 0000000..2ff35fd
--- /dev/null
+++ b/dojox/wire/ml/Invocation.js
@@ -0,0 +1,109 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.wire.ml.Invocation"]){
+dojo._hasResource["dojox.wire.ml.Invocation"]=true;
+dojo.provide("dojox.wire.ml.Invocation");
+dojo.require("dojox.wire.ml.Action");
+dojo.declare("dojox.wire.ml.Invocation",dojox.wire.ml.Action,{object:"",method:"",topic:"",parameters:"",result:"",error:"",_run:function(){
+if(this.topic){
+var _1=this._getParameters(arguments);
+try{
+dojo.publish(this.topic,_1);
+this.onComplete();
+}
+catch(e){
+this.onError(e);
+}
+}else{
+if(this.method){
+var _2=(this.object?dojox.wire.ml._getValue(this.object):dojo.global);
+if(!_2){
+return;
+}
+var _1=this._getParameters(arguments);
+var _3=_2[this.method];
+if(!_3){
+_3=_2.callMethod;
+if(!_3){
+return;
+}
+_1=[this.method,_1];
+}
+try{
+var _4=false;
+if(_2.getFeatures){
+var _5=_2.getFeatures();
+if((this.method=="fetch"&&_5["dojo.data.api.Read"])||(this.method=="save"&&_5["dojo.data.api.Write"])){
+var _6=_1[0];
+if(!_6.onComplete){
+_6.onComplete=function(){
+};
+}
+this.connect(_6,"onComplete","onComplete");
+if(!_6.onError){
+_6.onError=function(){
+};
+}
+this.connect(_6,"onError","onError");
+_4=true;
+}
+}
+var r=_3.apply(_2,_1);
+if(!_4){
+if(r&&(r instanceof dojo.Deferred)){
+var _8=this;
+r.addCallbacks(function(_9){
+_8.onComplete(_9);
+},function(_a){
+_8.onError(_a);
+});
+}else{
+this.onComplete(r);
+}
+}
+}
+catch(e){
+this.onError(e);
+}
+}
+}
+},onComplete:function(_b){
+if(this.result){
+dojox.wire.ml._setValue(this.result,_b);
+}
+if(this.error){
+dojox.wire.ml._setValue(this.error,"");
+}
+},onError:function(_c){
+if(this.error){
+if(_c&&_c.message){
+_c=_c.message;
+}
+dojox.wire.ml._setValue(this.error,_c);
+}
+},_getParameters:function(_d){
+if(!this.parameters){
+return _d;
+}
+var _e=[];
+var _f=this.parameters.split(",");
+if(_f.length==1){
+var _10=dojox.wire.ml._getValue(dojo.trim(_f[0]),_d);
+if(dojo.isArray(_10)){
+_e=_10;
+}else{
+_e.push(_10);
+}
+}else{
+for(var i in _f){
+_e.push(dojox.wire.ml._getValue(dojo.trim(_f[i]),_d));
+}
+}
+return _e;
+}});
+}
diff --git a/dojox/wire/ml/Service.js b/dojox/wire/ml/Service.js
new file mode 100644
index 0000000..b0757a3
--- /dev/null
+++ b/dojox/wire/ml/Service.js
@@ -0,0 +1,170 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.wire.ml.Service"]){
+dojo._hasResource["dojox.wire.ml.Service"]=true;
+dojo.provide("dojox.wire.ml.Service");
+dojo.provide("dojox.wire.ml.RestHandler");
+dojo.provide("dojox.wire.ml.XmlHandler");
+dojo.provide("dojox.wire.ml.JsonHandler");
+dojo.require("dijit._Widget");
+dojo.require("dojox.xml.parser");
+dojo.require("dojox.wire._base");
+dojo.require("dojox.wire.ml.util");
+dojo.declare("dojox.wire.ml.Service",dijit._Widget,{url:"",serviceUrl:"",serviceType:"",handlerClass:"",preventCache:true,postCreate:function(){
+this.handler=this._createHandler();
+},_handlerClasses:{"TEXT":"dojox.wire.ml.RestHandler","XML":"dojox.wire.ml.XmlHandler","JSON":"dojox.wire.ml.JsonHandler","JSON-RPC":"dojo.rpc.JsonService"},_createHandler:function(){
+if(this.url){
+var _1=this;
+var d=dojo.xhrGet({url:this.url,handleAs:"json",sync:true});
+d.addCallback(function(_3){
+_1.smd=_3;
+});
+if(this.smd&&!this.serviceUrl){
+this.serviceUrl=(this.smd.serviceUrl||this.smd.serviceURL);
+}
+}
+var _4=undefined;
+if(this.handlerClass){
+_4=dojox.wire._getClass(this.handlerClass);
+}else{
+if(this.serviceType){
+_4=this._handlerClasses[this.serviceType];
+if(_4&&dojo.isString(_4)){
+_4=dojox.wire._getClass(_4);
+this._handlerClasses[this.serviceType]=_4;
+}
+}else{
+if(this.smd&&this.smd.serviceType){
+_4=this._handlerClasses[this.smd.serviceType];
+if(_4&&dojo.isString(_4)){
+_4=dojox.wire._getClass(_4);
+this._handlerClasses[this.smd.serviceType]=_4;
+}
+}
+}
+}
+if(!_4){
+return null;
+}
+return new _4();
+},callMethod:function(_5,_6){
+var _7=new dojo.Deferred();
+this.handler.bind(_5,_6,_7,this.serviceUrl);
+return _7;
+}});
+dojo.declare("dojox.wire.ml.RestHandler",null,{contentType:"text/plain",handleAs:"text",bind:function(_8,_9,_a,_b){
+_8=_8.toUpperCase();
+var _c=this;
+var _d={url:this._getUrl(_8,_9,_b),contentType:this.contentType,handleAs:this.handleAs,headers:this.headers,preventCache:this.preventCache};
+var d=null;
+if(_8=="POST"){
+_d.postData=this._getContent(_8,_9);
+d=dojo.rawXhrPost(_d);
+}else{
+if(_8=="PUT"){
+_d.putData=this._getContent(_8,_9);
+d=dojo.rawXhrPut(_d);
+}else{
+if(_8=="DELETE"){
+d=dojo.xhrDelete(_d);
+}else{
+d=dojo.xhrGet(_d);
+}
+}
+}
+d.addCallbacks(function(_f){
+_a.callback(_c._getResult(_f));
+},function(_10){
+_a.errback(_10);
+});
+},_getUrl:function(_11,_12,url){
+var _14;
+if(_11=="GET"||_11=="DELETE"){
+if(_12.length>0){
+_14=_12[0];
+}
+}else{
+if(_12.length>1){
+_14=_12[1];
+}
+}
+if(_14){
+var _15="";
+for(var _16 in _14){
+var _17=_14[_16];
+if(_17){
+_17=encodeURIComponent(_17);
+var _18="{"+_16+"}";
+var _19=url.indexOf(_18);
+if(_19>=0){
+url=url.substring(0,_19)+_17+url.substring(_19+_18.length);
+}else{
+if(_15){
+_15+="&";
+}
+_15+=(_16+"="+_17);
+}
+}
+}
+if(_15){
+url+="?"+_15;
+}
+}
+return url;
+},_getContent:function(_1a,_1b){
+if(_1a=="POST"||_1a=="PUT"){
+return (_1b?_1b[0]:null);
+}else{
+return null;
+}
+},_getResult:function(_1c){
+return _1c;
+}});
+dojo.declare("dojox.wire.ml.XmlHandler",dojox.wire.ml.RestHandler,{contentType:"text/xml",handleAs:"xml",_getContent:function(_1d,_1e){
+var _1f=null;
+if(_1d=="POST"||_1d=="PUT"){
+var p=_1e[0];
+if(p){
+if(dojo.isString(p)){
+_1f=p;
+}else{
+var _21=p;
+if(_21 instanceof dojox.wire.ml.XmlElement){
+_21=_21.element;
+}else{
+if(_21.nodeType===9){
+_21=_21.documentElement;
+}
+}
+var _22="<?xml version=\"1.0\"?>";
+_1f=_22+dojox.xml.parser.innerXML(_21);
+}
+}
+}
+return _1f;
+},_getResult:function(_23){
+if(_23){
+_23=new dojox.wire.ml.XmlElement(_23);
+}
+return _23;
+}});
+dojo.declare("dojox.wire.ml.JsonHandler",dojox.wire.ml.RestHandler,{contentType:"text/json",handleAs:"json",headers:{"Accept":"*/json"},_getContent:function(_24,_25){
+var _26=null;
+if(_24=="POST"||_24=="PUT"){
+var p=(_25?_25[0]:undefined);
+if(p){
+if(dojo.isString(p)){
+_26=p;
+}else{
+_26=dojo.toJson(p);
+}
+}
+}
+return _26;
+}});
+}
diff --git a/dojox/wire/ml/Transfer.js b/dojox/wire/ml/Transfer.js
new file mode 100644
index 0000000..0748fe0
--- /dev/null
+++ b/dojox/wire/ml/Transfer.js
@@ -0,0 +1,122 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.wire.ml.Transfer"]){
+dojo._hasResource["dojox.wire.ml.Transfer"]=true;
+dojo.provide("dojox.wire.ml.Transfer");
+dojo.provide("dojox.wire.ml.ChildWire");
+dojo.provide("dojox.wire.ml.ColumnWire");
+dojo.provide("dojox.wire.ml.NodeWire");
+dojo.provide("dojox.wire.ml.SegmentWire");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Container");
+dojo.require("dojox.wire._base");
+dojo.require("dojox.wire.ml.Action");
+dojo.declare("dojox.wire.ml.Transfer",dojox.wire.ml.Action,{source:"",sourceStore:"",sourceAttribute:"",sourcePath:"",type:"",converter:"",delimiter:"",target:"",targetStore:"",targetAttribute:"",targetPath:"",_run:function(){
+var _1=this._getWire("source");
+var _2=this._getWire("target");
+dojox.wire.transfer(_1,_2,arguments);
+},_getWire:function(_3){
+var _4=undefined;
+if(_3=="source"){
+_4={object:this.source,dataStore:this.sourceStore,attribute:this.sourceAttribute,path:this.sourcePath,type:this.type,converter:this.converter};
+}else{
+_4={object:this.target,dataStore:this.targetStore,attribute:this.targetAttribute,path:this.targetPath};
+}
+if(_4.object){
+if(_4.object.length>=9&&_4.object.substring(0,9)=="arguments"){
+_4.property=_4.object.substring(9);
+_4.object=null;
+}else{
+var i=_4.object.indexOf(".");
+if(i<0){
+_4.object=dojox.wire.ml._getValue(_4.object);
+}else{
+_4.property=_4.object.substring(i+1);
+_4.object=dojox.wire.ml._getValue(_4.object.substring(0,i));
+}
+}
+}
+if(_4.dataStore){
+_4.dataStore=dojox.wire.ml._getValue(_4.dataStore);
+}
+var _6=undefined;
+var _7=this.getChildren();
+for(var i in _7){
+var _8=_7[i];
+if(_8 instanceof dojox.wire.ml.ChildWire&&_8.which==_3){
+if(!_6){
+_6={};
+}
+_8._addWire(this,_6);
+}
+}
+if(_6){
+_6.object=dojox.wire.create(_4);
+_6.dataStore=_4.dataStore;
+_4=_6;
+}
+return _4;
+}});
+dojo.declare("dojox.wire.ml.ChildWire",dijit._Widget,{which:"source",object:"",property:"",type:"",converter:"",attribute:"",path:"",name:"",_addWire:function(_9,_a){
+if(this.name){
+if(!_a.children){
+_a.children={};
+}
+_a.children[this.name]=this._getWire(_9);
+}else{
+if(!_a.children){
+_a.children=[];
+}
+_a.children.push(this._getWire(_9));
+}
+},_getWire:function(_b){
+return {object:(this.object?dojox.wire.ml._getValue(this.object):undefined),property:this.property,type:this.type,converter:this.converter,attribute:this.attribute,path:this.path};
+}});
+dojo.declare("dojox.wire.ml.ColumnWire",dojox.wire.ml.ChildWire,{column:"",_addWire:function(_c,_d){
+if(this.column){
+if(!_d.columns){
+_d.columns={};
+}
+_d.columns[this.column]=this._getWire(_c);
+}else{
+if(!_d.columns){
+_d.columns=[];
+}
+_d.columns.push(this._getWire(_c));
+}
+}});
+dojo.declare("dojox.wire.ml.NodeWire",[dojox.wire.ml.ChildWire,dijit._Container],{titleProperty:"",titleAttribute:"",titlePath:"",_addWire:function(_e,_f){
+if(!_f.nodes){
+_f.nodes=[];
+}
+_f.nodes.push(this._getWires(_e));
+},_getWires:function(_10){
+var _11={node:this._getWire(_10),title:{type:"string",property:this.titleProperty,attribute:this.titleAttribute,path:this.titlePath}};
+var _12=[];
+var _13=this.getChildren();
+for(var i in _13){
+var _15=_13[i];
+if(_15 instanceof dojox.wire.ml.NodeWire){
+_12.push(_15._getWires(_10));
+}
+}
+if(_12.length>0){
+_11.children=_12;
+}
+return _11;
+}});
+dojo.declare("dojox.wire.ml.SegmentWire",dojox.wire.ml.ChildWire,{_addWire:function(_16,_17){
+if(!_17.segments){
+_17.segments=[];
+}
+_17.segments.push(this._getWire(_16));
+if(_16.delimiter&&!_17.delimiter){
+_17.delimiter=_16.delimiter;
+}
+}});
+}
diff --git a/dojox/wire/ml/util.js b/dojox/wire/ml/util.js
new file mode 100644
index 0000000..c52bf7d
--- /dev/null
+++ b/dojox/wire/ml/util.js
@@ -0,0 +1,213 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.wire.ml.util"]){
+dojo._hasResource["dojox.wire.ml.util"]=true;
+dojo.provide("dojox.wire.ml.util");
+dojo.require("dojox.xml.parser");
+dojo.require("dojox.wire.Wire");
+dojox.wire.ml._getValue=function(_1,_2){
+if(!_1){
+return undefined;
+}
+var _3=undefined;
+if(_2&&_1.length>=9&&_1.substring(0,9)=="arguments"){
+_3=_1.substring(9);
+return new dojox.wire.Wire({property:_3}).getValue(_2);
+}
+var i=_1.indexOf(".");
+if(i>=0){
+_3=_1.substring(i+1);
+_1=_1.substring(0,i);
+}
+var _5=(dijit.byId(_1)||dojo.byId(_1)||dojo.getObject(_1));
+if(!_5){
+return undefined;
+}
+if(!_3){
+return _5;
+}else{
+return new dojox.wire.Wire({object:_5,property:_3}).getValue();
+}
+};
+dojox.wire.ml._setValue=function(_6,_7){
+if(!_6){
+return;
+}
+var i=_6.indexOf(".");
+if(i<0){
+return;
+}
+var _9=this._getValue(_6.substring(0,i));
+if(!_9){
+return;
+}
+var _a=_6.substring(i+1);
+var _b=new dojox.wire.Wire({object:_9,property:_a}).setValue(_7);
+};
+dojo.declare("dojox.wire.ml.XmlElement",null,{constructor:function(_c){
+if(dojo.isString(_c)){
+_c=this._getDocument().createElement(_c);
+}
+this.element=_c;
+},getPropertyValue:function(_d){
+var _e=undefined;
+if(!this.element){
+return _e;
+}
+if(!_d){
+return _e;
+}
+if(_d.charAt(0)=="@"){
+var _f=_d.substring(1);
+_e=this.element.getAttribute(_f);
+}else{
+if(_d=="text()"){
+var _10=this.element.firstChild;
+if(_10){
+_e=_10.nodeValue;
+}
+}else{
+var _11=[];
+for(var i=0;i<this.element.childNodes.length;i++){
+var _13=this.element.childNodes[i];
+if(_13.nodeType===1&&_13.nodeName==_d){
+_11.push(new dojox.wire.ml.XmlElement(_13));
+}
+}
+if(_11.length>0){
+if(_11.length===1){
+_e=_11[0];
+}else{
+_e=_11;
+}
+}
+}
+}
+return _e;
+},setPropertyValue:function(_14,_15){
+var i;
+var _17;
+if(!this.element){
+return;
+}
+if(!_14){
+return;
+}
+if(_14.charAt(0)=="@"){
+var _18=_14.substring(1);
+if(_15){
+this.element.setAttribute(_18,_15);
+}else{
+this.element.removeAttribute(_18);
+}
+}else{
+if(_14=="text()"){
+while(this.element.firstChild){
+this.element.removeChild(this.element.firstChild);
+}
+if(_15){
+_17=this._getDocument().createTextNode(_15);
+this.element.appendChild(_17);
+}
+}else{
+var _19=null;
+var _1a;
+for(i=this.element.childNodes.length-1;i>=0;i--){
+_1a=this.element.childNodes[i];
+if(_1a.nodeType===1&&_1a.nodeName==_14){
+if(!_19){
+_19=_1a.nextSibling;
+}
+this.element.removeChild(_1a);
+}
+}
+if(_15){
+if(dojo.isArray(_15)){
+for(i in _15){
+var e=_15[i];
+if(e.element){
+this.element.insertBefore(e.element,_19);
+}
+}
+}else{
+if(_15 instanceof dojox.wire.ml.XmlElement){
+if(_15.element){
+this.element.insertBefore(_15.element,_19);
+}
+}else{
+_1a=this._getDocument().createElement(_14);
+_17=this._getDocument().createTextNode(_15);
+_1a.appendChild(_17);
+this.element.insertBefore(_1a,_19);
+}
+}
+}
+}
+}
+},toString:function(){
+var s="";
+if(this.element){
+var _1d=this.element.firstChild;
+if(_1d){
+s=_1d.nodeValue;
+}
+}
+return s;
+},toObject:function(){
+if(!this.element){
+return null;
+}
+var _1e="";
+var obj={};
+var _20=0;
+var i;
+for(i=0;i<this.element.childNodes.length;i++){
+var _22=this.element.childNodes[i];
+if(_22.nodeType===1){
+_20++;
+var o=new dojox.wire.ml.XmlElement(_22).toObject();
+var _24=_22.nodeName;
+var p=obj[_24];
+if(!p){
+obj[_24]=o;
+}else{
+if(dojo.isArray(p)){
+p.push(o);
+}else{
+obj[_24]=[p,o];
+}
+}
+}else{
+if(_22.nodeType===3||_22.nodeType===4){
+_1e+=_22.nodeValue;
+}
+}
+}
+var _26=0;
+if(this.element.nodeType===1){
+_26=this.element.attributes.length;
+for(i=0;i<_26;i++){
+var _27=this.element.attributes[i];
+obj["@"+_27.nodeName]=_27.nodeValue;
+}
+}
+if(_20===0){
+if(_26===0){
+return _1e;
+}
+obj["text()"]=_1e;
+}
+return obj;
+},_getDocument:function(){
+if(this.element){
+return (this.element.nodeType==9?this.element:this.element.ownerDocument);
+}else{
+return dojox.xml.parser.parse();
+}
+}});
+}
diff --git a/dojox/xml/DomParser.js b/dojox/xml/DomParser.js
new file mode 100644
index 0000000..ed2c7aa
--- /dev/null
+++ b/dojox/xml/DomParser.js
@@ -0,0 +1,325 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.xml.DomParser"]){
+dojo._hasResource["dojox.xml.DomParser"]=true;
+dojo.provide("dojox.xml.DomParser");
+dojox.xml.DomParser=new (function(){
+var _1={ELEMENT:1,ATTRIBUTE:2,TEXT:3,CDATA_SECTION:4,PROCESSING_INSTRUCTION:7,COMMENT:8,DOCUMENT:9};
+var _2=/<([^>\/\s+]*)([^>]*)>([^<]*)/g;
+var _3=/([^=]*)=(("([^"]*)")|('([^']*)'))/g;
+var _4=/<!ENTITY\s+([^"]*)\s+"([^"]*)">/g;
+var _5=/<!\[CDATA\[([\u0001-\uFFFF]*?)\]\]>/g;
+var _6=/<!--([\u0001-\uFFFF]*?)-->/g;
+var _7=/^\s+|\s+$/g;
+var _8=/\s+/g;
+var _9=/\>/g;
+var _a=/\</g;
+var _b=/\"/g;
+var _c=/\'/g;
+var _d=/\&/g;
+var _e="_def_";
+function _f(){
+return new (function(){
+var all={};
+this.nodeType=_1.DOCUMENT;
+this.nodeName="#document";
+this.namespaces={};
+this._nsPaths={};
+this.childNodes=[];
+this.documentElement=null;
+this._add=function(obj){
+if(typeof (obj.id)!="undefined"){
+all[obj.id]=obj;
+}
+};
+this._remove=function(id){
+if(all[id]){
+delete all[id];
+}
+};
+this.byId=this.getElementById=function(id){
+return all[id];
+};
+this.byName=this.getElementsByTagName=_14;
+this.byNameNS=this.getElementsByTagNameNS=_15;
+this.childrenByName=_16;
+this.childrenByNameNS=_17;
+})();
+};
+function _14(_18){
+function __(_1a,_1b,arr){
+dojo.forEach(_1a.childNodes,function(c){
+if(c.nodeType==_1.ELEMENT){
+if(_1b=="*"){
+arr.push(c);
+}else{
+if(c.nodeName==_1b){
+arr.push(c);
+}
+}
+__(c,_1b,arr);
+}
+});
+};
+var a=[];
+__(this,_18,a);
+return a;
+};
+function _15(_1f,ns){
+function __(_22,_23,ns,arr){
+dojo.forEach(_22.childNodes,function(c){
+if(c.nodeType==_1.ELEMENT){
+if(_23=="*"&&c.ownerDocument._nsPaths[ns]==c.namespace){
+arr.push(c);
+}else{
+if(c.localName==_23&&c.ownerDocument._nsPaths[ns]==c.namespace){
+arr.push(c);
+}
+}
+__(c,_23,ns,arr);
+}
+});
+};
+if(!ns){
+ns=_e;
+}
+var a=[];
+__(this,_1f,ns,a);
+return a;
+};
+function _16(_28){
+var a=[];
+dojo.forEach(this.childNodes,function(c){
+if(c.nodeType==_1.ELEMENT){
+if(_28=="*"){
+a.push(c);
+}else{
+if(c.nodeName==_28){
+a.push(c);
+}
+}
+}
+});
+return a;
+};
+function _17(_2b,ns){
+var a=[];
+dojo.forEach(this.childNodes,function(c){
+if(c.nodeType==_1.ELEMENT){
+if(_2b=="*"&&c.ownerDocument._nsPaths[ns]==c.namespace){
+a.push(c);
+}else{
+if(c.localName==_2b&&c.ownerDocument._nsPaths[ns]==c.namespace){
+a.push(c);
+}
+}
+}
+});
+return a;
+};
+function _2f(v){
+return {nodeType:_1.TEXT,nodeName:"#text",nodeValue:v.replace(_8," ").replace(_9,">").replace(_a,"<").replace(_c,"'").replace(_b,"\"").replace(_d,"&")};
+};
+function _31(_32){
+for(var i=0;i<this.attributes.length;i++){
+if(this.attributes[i].nodeName==_32){
+return this.attributes[i].nodeValue;
+}
+}
+return null;
+};
+function _34(_35,ns){
+for(var i=0;i<this.attributes.length;i++){
+if(this.ownerDocument._nsPaths[ns]==this.attributes[i].namespace&&this.attributes[i].localName==_35){
+return this.attributes[i].nodeValue;
+}
+}
+return null;
+};
+function _38(_39,val){
+var old=null;
+for(var i=0;i<this.attributes.length;i++){
+if(this.attributes[i].nodeName==_39){
+old=this.attributes[i].nodeValue;
+this.attributes[i].nodeValue=val;
+break;
+}
+}
+if(_39=="id"){
+if(old!=null){
+this.ownerDocument._remove(old);
+}
+this.ownerDocument._add(this);
+}
+};
+function _3d(_3e,val,ns){
+for(var i=0;i<this.attributes.length;i++){
+if(this.ownerDocument._nsPaths[ns]==this.attributes[i].namespace&&this.attributes[i].localName==_3e){
+this.attributes[i].nodeValue=val;
+return;
+}
+}
+};
+function _42(){
+var p=this.parentNode;
+if(p){
+for(var i=0;i<p.childNodes.length;i++){
+if(p.childNodes[i]==this&&i>0){
+return p.childNodes[i-1];
+}
+}
+}
+return null;
+};
+function _45(){
+var p=this.parentNode;
+if(p){
+for(var i=0;i<p.childNodes.length;i++){
+if(p.childNodes[i]==this&&(i+1)<p.childNodes.length){
+return p.childNodes[i+1];
+}
+}
+}
+return null;
+};
+this.parse=function(str){
+var _49=_f();
+if(str==null){
+return _49;
+}
+if(str.length==0){
+return _49;
+}
+if(str.indexOf("<!ENTITY")>0){
+var _4a,eRe=[];
+if(_4.test(str)){
+_4.lastIndex=0;
+while((_4a=_4.exec(str))!=null){
+eRe.push({entity:"&"+_4a[1].replace(_7,"")+";",expression:_4a[2]});
+}
+for(var i=0;i<eRe.length;i++){
+str=str.replace(new RegExp(eRe[i].entity,"g"),eRe[i].expression);
+}
+}
+}
+var _4d=[],_4e;
+while((_4e=_5.exec(str))!=null){
+_4d.push(_4e[1]);
+}
+for(var i=0;i<_4d.length;i++){
+str=str.replace(_4d[i],i);
+}
+var _4f=[],_50;
+while((_50=_6.exec(str))!=null){
+_4f.push(_50[1]);
+}
+for(i=0;i<_4f.length;i++){
+str=str.replace(_4f[i],i);
+}
+var res,obj=_49;
+while((res=_2.exec(str))!=null){
+if(res[2].charAt(0)=="/"&&res[2].replace(_7,"").length>1){
+if(obj.parentNode){
+obj=obj.parentNode;
+}
+var _53=(res[3]||"").replace(_7,"");
+if(_53.length>0){
+obj.childNodes.push(_2f(_53));
+}
+}else{
+if(res[1].length>0){
+if(res[1].charAt(0)=="?"){
+var _54=res[1].substr(1);
+var _55=res[2].substr(0,res[2].length-2);
+obj.childNodes.push({nodeType:_1.PROCESSING_INSTRUCTION,nodeName:_54,nodeValue:_55});
+}else{
+if(res[1].charAt(0)=="!"){
+if(res[1].indexOf("![CDATA[")==0){
+var val=parseInt(res[1].replace("![CDATA[","").replace("]]",""));
+obj.childNodes.push({nodeType:_1.CDATA_SECTION,nodeName:"#cdata-section",nodeValue:_4d[val]});
+}else{
+if(res[1].substr(0,3)=="!--"){
+var val=parseInt(res[1].replace("!--","").replace("--",""));
+obj.childNodes.push({nodeType:_1.COMMENT,nodeName:"#comment",nodeValue:_4f[val]});
+}
+}
+}else{
+var _54=res[1].replace(_7,"");
+var o={nodeType:_1.ELEMENT,nodeName:_54,localName:_54,namespace:_e,ownerDocument:_49,attributes:[],parentNode:null,childNodes:[]};
+if(_54.indexOf(":")>-1){
+var t=_54.split(":");
+o.namespace=t[0];
+o.localName=t[1];
+}
+o.byName=o.getElementsByTagName=_14;
+o.byNameNS=o.getElementsByTagNameNS=_15;
+o.childrenByName=_16;
+o.childrenByNameNS=_17;
+o.getAttribute=_31;
+o.getAttributeNS=_34;
+o.setAttribute=_38;
+o.setAttributeNS=_3d;
+o.previous=o.previousSibling=_42;
+o.next=o.nextSibling=_45;
+var _59;
+while((_59=_3.exec(res[2]))!=null){
+if(_59.length>0){
+var _54=_59[1].replace(_7,"");
+var val=(_59[4]||_59[6]||"").replace(_8," ").replace(_9,">").replace(_a,"<").replace(_c,"'").replace(_b,"\"").replace(_d,"&");
+if(_54.indexOf("xmlns")==0){
+if(_54.indexOf(":")>0){
+var ns=_54.split(":");
+_49.namespaces[ns[1]]=val;
+_49._nsPaths[val]=ns[1];
+}else{
+_49.namespaces[_e]=val;
+_49._nsPaths[val]=_e;
+}
+}else{
+var ln=_54;
+var ns=_e;
+if(_54.indexOf(":")>0){
+var t=_54.split(":");
+ln=t[1];
+ns=t[0];
+}
+o.attributes.push({nodeType:_1.ATTRIBUTE,nodeName:_54,localName:ln,namespace:ns,nodeValue:val});
+if(ln=="id"){
+o.id=val;
+}
+}
+}
+}
+_49._add(o);
+if(obj){
+obj.childNodes.push(o);
+o.parentNode=obj;
+if(res[2].charAt(res[2].length-1)!="/"){
+obj=o;
+}
+}
+var _53=res[3];
+if(_53.length>0){
+obj.childNodes.push(_2f(_53));
+}
+}
+}
+}
+}
+}
+for(var i=0;i<_49.childNodes.length;i++){
+var e=_49.childNodes[i];
+if(e.nodeType==_1.ELEMENT){
+_49.documentElement=e;
+break;
+}
+}
+return _49;
+};
+})();
+}
diff --git a/dojox/xml/README b/dojox/xml/README
new file mode 100644
index 0000000..c00122a
--- /dev/null
+++ b/dojox/xml/README
@@ -0,0 +1,40 @@
+-------------------------------------------------------------------------------
+DojoX XML Utilities
+-------------------------------------------------------------------------------
+Version 0.1
+Release date: 05/30/2007	
+-------------------------------------------------------------------------------
+Project state:
+experimental
+-------------------------------------------------------------------------------
+Credits 
+	Tom Trenka (ttrenka at gmail.com): DomParser
+	
+-------------------------------------------------------------------------------
+Project description
+
+The goal of DojoX XML Utilities is provide differing XML utilities for use
+in various places.  Currently this includes a native JS DomParser, but will
+most likely be expanded to include things as dealing with x-browser forks
+(like the Sarissa project), various DOM utilites, and more.
+-------------------------------------------------------------------------------
+Dependencies:
+
+DojoX XML relies only on the Dojo Base package system.
+-------------------------------------------------------------------------------
+Documentation
+
+None at the time of writing.  The only object is dojox.xml.DomParser (a singleton),
+which has one method: parse:
+
+dojox.xml.DomParser.parse(xmlString)
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/xml/*
+
+Install into the following directory structure:
+/dojox/xml/
+
+...which should be at the same level as your Dojo checkout.
diff --git a/dojox/xml/Script.js b/dojox/xml/Script.js
new file mode 100644
index 0000000..07acb09
--- /dev/null
+++ b/dojox/xml/Script.js
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.xml.Script"]){
+dojo._hasResource["dojox.xml.Script"]=true;
+dojo.provide("dojox.xml.Script");
+dojo.require("dojo.parser");
+dojo.require("dojox.xml.widgetParser");
+dojo.declare("dojox.xml.Script",null,{constructor:function(_1,_2){
+dojo.parser.instantiate(dojox.xml.widgetParser._processScript(_2));
+}});
+}
diff --git a/dojox/xml/parser.js b/dojox/xml/parser.js
new file mode 100644
index 0000000..5627240
--- /dev/null
+++ b/dojox/xml/parser.js
@@ -0,0 +1,137 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.xml.parser"]){
+dojo._hasResource["dojox.xml.parser"]=true;
+dojo.provide("dojox.xml.parser");
+dojox.xml.parser.parse=function(_1,_2){
+var _3=dojo.doc;
+var _4;
+_2=_2||"text/xml";
+if(_1&&dojo.trim(_1)&&"DOMParser" in dojo.global){
+var _5=new DOMParser();
+_4=_5.parseFromString(_1,_2);
+var de=_4.documentElement;
+var _7="http://www.mozilla.org/newlayout/xml/parsererror.xml";
+if(de.nodeName=="parsererror"&&de.namespaceURI==_7){
+var _8=de.getElementsByTagNameNS(_7,"sourcetext")[0];
+if(!_8){
+_8=_8.firstChild.data;
+}
+throw new Error("Error parsing text "+nativeDoc.documentElement.firstChild.data+" \n"+_8);
+}
+return _4;
+}else{
+if("ActiveXObject" in dojo.global){
+var ms=function(n){
+return "MSXML"+n+".DOMDocument";
+};
+var dp=["Microsoft.XMLDOM",ms(6),ms(4),ms(3),ms(2)];
+dojo.some(dp,function(p){
+try{
+_4=new ActiveXObject(p);
+}
+catch(e){
+return false;
+}
+return true;
+});
+if(_1&&_4){
+_4.async=false;
+_4.loadXML(_1);
+var pe=_4.parseError;
+if(pe.errorCode!==0){
+throw new Error("Line: "+pe.line+"\n"+"Col: "+pe.linepos+"\n"+"Reason: "+pe.reason+"\n"+"Error Code: "+pe.errorCode+"\n"+"Source: "+pe.srcText);
+}
+}
+if(_4){
+return _4;
+}
+}else{
+if(_3.implementation&&_3.implementation.createDocument){
+if(_1&&dojo.trim(_1)&&_3.createElement){
+var _e=_3.createElement("xml");
+_e.innerHTML=_1;
+var _f=_3.implementation.createDocument("foo","",null);
+dojo.forEach(_e.childNodes,function(_10){
+_f.importNode(_10,true);
+});
+return _f;
+}else{
+return _3.implementation.createDocument("","",null);
+}
+}
+}
+}
+return null;
+};
+dojox.xml.parser.textContent=function(_11,_12){
+if(arguments.length>1){
+var _13=_11.ownerDocument||dojo.doc;
+dojox.xml.parser.replaceChildren(_11,_13.createTextNode(_12));
+return _12;
+}else{
+if(_11.textContent!==undefined){
+return _11.textContent;
+}
+var _14="";
+if(_11){
+dojo.forEach(_11.childNodes,function(_15){
+switch(_15.nodeType){
+case 1:
+case 5:
+_14+=dojox.xml.parser.textContent(_15);
+break;
+case 3:
+case 2:
+case 4:
+_14+=_15.nodeValue;
+}
+});
+}
+return _14;
+}
+};
+dojox.xml.parser.replaceChildren=function(_16,_17){
+var _18=[];
+if(dojo.isIE){
+dojo.forEach(_16.childNodes,function(_19){
+_18.push(_19);
+});
+}
+dojox.xml.parser.removeChildren(_16);
+dojo.forEach(_18,dojo.destroy);
+if(!dojo.isArray(_17)){
+_16.appendChild(_17);
+}else{
+dojo.forEach(_17,function(_1a){
+_16.appendChild(_1a);
+});
+}
+};
+dojox.xml.parser.removeChildren=function(_1b){
+var _1c=_1b.childNodes.length;
+while(_1b.hasChildNodes()){
+_1b.removeChild(_1b.firstChild);
+}
+return _1c;
+};
+dojox.xml.parser.innerXML=function(_1d){
+if(_1d.innerXML){
+return _1d.innerXML;
+}else{
+if(_1d.xml){
+return _1d.xml;
+}else{
+if(typeof XMLSerializer!="undefined"){
+return (new XMLSerializer()).serializeToString(_1d);
+}
+}
+}
+return null;
+};
+}
diff --git a/dojox/xml/widgetParser.js b/dojox/xml/widgetParser.js
new file mode 100644
index 0000000..c070514
--- /dev/null
+++ b/dojox/xml/widgetParser.js
@@ -0,0 +1,69 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.xml.widgetParser"]){
+dojo._hasResource["dojox.xml.widgetParser"]=true;
+dojo.provide("dojox.xml.widgetParser");
+dojo.require("dojox.xml.parser");
+dojo.require("dojo.parser");
+dojox.xml.widgetParser=new function(){
+var d=dojo;
+this.parseNode=function(_2){
+var _3=[];
+d.query("script[type='text/xml']",_2).forEach(function(_4){
+_3.push.apply(_3,this._processScript(_4));
+},this).orphan();
+return d.parser.instantiate(_3);
+};
+this._processScript=function(_5){
+var _6=_5.src?d._getText(_5.src):_5.innerHTML||_5.firstChild.nodeValue;
+var _7=this.toHTML(dojox.xml.parser.parse(_6).firstChild);
+var _8=d.query("[dojoType]",_7);
+dojo.query(">",_7).place(_5,"before");
+_5.parentNode.removeChild(_5);
+return _8;
+};
+this.toHTML=function(_9){
+var _a;
+var _b=_9.nodeName;
+var dd=dojo.doc;
+var _d=_9.nodeType;
+if(_d>=3){
+return dd.createTextNode((_d==3||_d==4)?_9.nodeValue:"");
+}
+var _e=_9.localName||_b.split(":").pop();
+var _f=_9.namespaceURI||(_9.getNamespaceUri?_9.getNamespaceUri():"");
+if(_f=="html"){
+_a=dd.createElement(_e);
+}else{
+var _10=_f+"."+_e;
+_a=_a||dd.createElement((_10=="dijit.form.ComboBox")?"select":"div");
+_a.setAttribute("dojoType",_10);
+}
+d.forEach(_9.attributes,function(_11){
+var _12=_11.name||_11.nodeName;
+var _13=_11.value||_11.nodeValue;
+if(_12.indexOf("xmlns")!=0){
+if(dojo.isIE&&_12=="style"){
+_a.style.setAttribute("cssText",_13);
+}else{
+_a.setAttribute(_12,_13);
+}
+}
+});
+d.forEach(_9.childNodes,function(cn){
+var _15=this.toHTML(cn);
+if(_e=="script"){
+_a.text+=_15.nodeValue;
+}else{
+_a.appendChild(_15);
+}
+},this);
+return _a;
+};
+}();
+}
diff --git a/dojox/xmpp/ChatService.js b/dojox/xmpp/ChatService.js
new file mode 100644
index 0000000..9090ca7
--- /dev/null
+++ b/dojox/xmpp/ChatService.js
@@ -0,0 +1,90 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.xmpp.ChatService"]){
+dojo._hasResource["dojox.xmpp.ChatService"]=true;
+dojo.provide("dojox.xmpp.ChatService");
+dojox.xmpp.chat={CHAT_STATE_NS:"http://jabber.org/protocol/chatstates",ACTIVE_STATE:"active",COMPOSING_STATE:"composing",INACTIVE_STATE:"inactive",PAUSED_STATE:"paused",GONE_STATE:"gone"};
+dojo.declare("dojox.xmpp.ChatService",null,{state:"",constructor:function(){
+this.state="";
+this.chatid=Math.round(Math.random()*1000000000000000);
+},recieveMessage:function(_1,_2){
+if(_1&&!_2){
+this.onNewMessage(_1);
+}
+},setSession:function(_3){
+this.session=_3;
+},setState:function(_4){
+if(this.state!=_4){
+this.state=_4;
+}
+},invite:function(_5){
+if(this.uid){
+return;
+}
+if(!_5||_5==""){
+throw new Error("ChatService::invite() contact is NULL");
+}
+this.uid=_5;
+var _6={xmlns:"jabber:client",to:this.uid,from:this.session.jid+"/"+this.session.resource,type:"chat"};
+var _7=new dojox.string.Builder(dojox.xmpp.util.createElement("message",_6,false));
+_7.append(dojox.xmpp.util.createElement("thread",{},false));
+_7.append(this.chatid);
+_7.append("</thread>");
+_7.append(dojox.xmpp.util.createElement("active",{xmlns:dojox.xmpp.chat.CHAT_STATE_NS},true));
+_7.append("</message>");
+this.session.dispatchPacket(_7.toString());
+this.onInvite(_5);
+this.setState(dojox.xmpp.chat.CHAT_STATE_NS);
+},sendMessage:function(_8){
+if(!this.uid){
+return;
+}
+if((!_8.body||_8.body=="")&&!_8.xhtml){
+return;
+}
+var _9={xmlns:"jabber:client",to:this.uid,from:this.session.jid+"/"+this.session.resource,type:"chat"};
+var _a=new dojox.string.Builder(dojox.xmpp.util.createElement("message",_9,false));
+var _b=dojox.xmpp.util.createElement("html",{"xmlns":dojox.xmpp.xmpp.XHTML_IM_NS},false);
+var _c=dojox.xmpp.util.createElement("body",{"xml:lang":this.session.lang,"xmlns":dojox.xmpp.xmpp.XHTML_BODY_NS},false)+_8.body+"</body>";
+var _d=dojox.xmpp.util.createElement("body",{},false)+dojox.xmpp.util.stripHtml(_8.body)+"</body>";
+if(_a.subject&&_a.subject!=""){
+_a.append(dojox.xmpp.util.createElement("subject",{},false));
+_a.append(_a.subject);
+_a.append("</subject>");
+}
+_a.append(_d);
+_a.append(_b);
+_a.append(_c);
+_a.append("</html>");
+_a.append(dojox.xmpp.util.createElement("thread",{},false));
+_a.append(this.chatid);
+_a.append("</thread>");
+if(this.useChatStates){
+_a.append(dojox.xmpp.util.createElement("active",{xmlns:dojox.xmpp.chat.CHAT_STATE_NS},true));
+}
+_a.append("</message>");
+this.session.dispatchPacket(_a.toString());
+},sendChatState:function(_e){
+if(!this.useChatState||this.firstMessage){
+return;
+}
+if(_e==this._currentState){
+return;
+}
+var _f={xmlns:"jabber:client",to:this.uid,from:this.session.jid+"/"+this.session.resource,type:"chat"};
+var _10=new dojox.string.Builder(dojox.xmpp.util.createElement("message",_f,false));
+_10.append(dojox.xmpp.util.createElement(_e,{xmlns:dojox.xmpp.chat.CHAT_STATE_NS},true));
+this._currentState=_e;
+_10.append("<thread>");
+_10.append(this.chatid);
+_10.append("</thread></message>");
+this.session.dispatchPacket(_10.toString());
+},onNewMessage:function(msg){
+},onInvite:function(_12){
+}});
+}
diff --git a/dojox/xmpp/PresenceService.js b/dojox/xmpp/PresenceService.js
new file mode 100644
index 0000000..ebb909d
--- /dev/null
+++ b/dojox/xmpp/PresenceService.js
@@ -0,0 +1,163 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.xmpp.PresenceService"]){
+dojo._hasResource["dojox.xmpp.PresenceService"]=true;
+dojo.provide("dojox.xmpp.PresenceService");
+dojox.xmpp.presence={UPDATE:201,SUBSCRIPTION_REQUEST:202,SUBSCRIPTION_SUBSTATUS_NONE:204,SUBSCRIPTION_NONE:"none",SUBSCRIPTION_FROM:"from",SUBSCRIPTION_TO:"to",SUBSCRIPTION_BOTH:"both",SUBSCRIPTION_REQUEST_PENDING:"pending",STATUS_ONLINE:"online",STATUS_AWAY:"away",STATUS_CHAT:"chat",STATUS_DND:"dnd",STATUS_EXTENDED_AWAY:"xa",STATUS_OFFLINE:"offline",STATUS_INVISIBLE:"invisible"};
+dojo.declare("dojox.xmpp.PresenceService",null,{constructor:function(_1){
+this.session=_1;
+this.isInvisible=false;
+this.avatarHash=null;
+this.presence=null;
+this.restrictedContactjids={};
+},publish:function(_2){
+this.presence=_2;
+this._setPresence();
+},sendAvatarHash:function(_3){
+this.avatarHash=_3;
+this._setPresence();
+},_setPresence:function(){
+var _4=this.presence;
+var p={xmlns:"jabber:client"};
+if(_4&&_4.to){
+p.to=_4.to;
+}
+if(_4.show&&_4.show==dojox.xmpp.presence.STATUS_OFFLINE){
+p.type="unavailable";
+}
+if(_4.show&&_4.show==dojox.xmpp.presence.STATUS_INVISIBLE){
+this._setInvisible();
+this.isInvisible=true;
+return;
+}
+if(this.isInvisible){
+this._setVisible();
+}
+var _6=new dojox.string.Builder(dojox.xmpp.util.createElement("presence",p,false));
+if(_4.show&&_4.show!=dojox.xmpp.presence.STATUS_OFFLINE){
+_6.append(dojox.xmpp.util.createElement("show",{},false));
+_6.append(_4.show);
+_6.append("</show>");
+}
+if(_4.status){
+_6.append(dojox.xmpp.util.createElement("status",{},false));
+_6.append(_4.status);
+_6.append("</status>");
+}
+if(this.avatarHash){
+_6.append(dojox.xmpp.util.createElement("x",{xmlns:"vcard-temp:x:update"},false));
+_6.append(dojox.xmpp.util.createElement("photo",{},false));
+_6.append(this.avatarHash);
+_6.append("</photo>");
+_6.append("</x>");
+}
+if(_4.priority&&_4.show!=dojox.xmpp.presence.STATUS_OFFLINE){
+if(_4.priority>127||_4.priority<-128){
+_4.priority=5;
+}
+_6.append(dojox.xmpp.util.createElement("priority",{},false));
+_6.append(_4.priority);
+_6.append("</priority>");
+}
+_6.append("</presence>");
+this.session.dispatchPacket(_6.toString());
+},toggleBlockContact:function(_7){
+if(!this.restrictedContactjids[_7]){
+this.restrictedContactjids[_7]=this._createRestrictedJid();
+}
+this.restrictedContactjids[_7].blocked=!this.restrictedContactjids[_7].blocked;
+this._updateRestricted();
+return this.restrictedContactjids;
+},toggleContactInvisiblity:function(_8){
+if(!this.restrictedContactjids[_8]){
+this.restrictedContactjids[_8]=this._createRestrictedJid();
+}
+this.restrictedContactjids[_8].invisible=!this.restrictedContactjids[_8].invisible;
+this._updateRestricted();
+return this.restrictedContactjids;
+},_createRestrictedJid:function(){
+return {invisible:false,blocked:false};
+},_updateRestricted:function(){
+var _9={id:this.session.getNextIqId(),from:this.session.jid+"/"+this.session.resource,type:"set"};
+var _a=new dojox.string.Builder(dojox.xmpp.util.createElement("iq",_9,false));
+_a.append(dojox.xmpp.util.createElement("query",{xmlns:"jabber:iq:privacy"},false));
+_a.append(dojox.xmpp.util.createElement("list",{name:"iwcRestrictedContacts"},false));
+var _b=1;
+for(var _c in this.restrictedContactjids){
+var _d=this.restrictedContactjids[_c];
+if(_d.blocked||_d.invisible){
+_a.append(dojox.xmpp.util.createElement("item",{value:dojox.xmpp.util.encodeJid(_c),action:"deny",order:_b++},false));
+if(_d.blocked){
+_a.append(dojox.xmpp.util.createElement("message",{},true));
+}
+if(_d.invisible){
+_a.append(dojox.xmpp.util.createElement("presence-out",{},true));
+}
+_a.append("</item>");
+}else{
+delete this.restrictedContactjids[_c];
+}
+}
+_a.append("</list>");
+_a.append("</query>");
+_a.append("</iq>");
+var _e=new dojox.string.Builder(dojox.xmpp.util.createElement("iq",_9,false));
+_e.append(dojox.xmpp.util.createElement("query",{xmlns:"jabber:iq:privacy"},false));
+_e.append(dojox.xmpp.util.createElement("active",{name:"iwcRestrictedContacts"},true));
+_e.append("</query>");
+_e.append("</iq>");
+this.session.dispatchPacket(_a.toString());
+this.session.dispatchPacket(_e.toString());
+},_setVisible:function(){
+var _f={id:this.session.getNextIqId(),from:this.session.jid+"/"+this.session.resource,type:"set"};
+var req=new dojox.string.Builder(dojox.xmpp.util.createElement("iq",_f,false));
+req.append(dojox.xmpp.util.createElement("query",{xmlns:"jabber:iq:privacy"},false));
+req.append(dojox.xmpp.util.createElement("active",{},true));
+req.append("</query>");
+req.append("</iq>");
+this.session.dispatchPacket(req.toString());
+},_setInvisible:function(){
+var _11={id:this.session.getNextIqId(),from:this.session.jid+"/"+this.session.resource,type:"set"};
+var req=new dojox.string.Builder(dojox.xmpp.util.createElement("iq",_11,false));
+req.append(dojox.xmpp.util.createElement("query",{xmlns:"jabber:iq:privacy"},false));
+req.append(dojox.xmpp.util.createElement("list",{name:"invisible"},false));
+req.append(dojox.xmpp.util.createElement("item",{action:"deny",order:"1"},false));
+req.append(dojox.xmpp.util.createElement("presence-out",{},true));
+req.append("</item>");
+req.append("</list>");
+req.append("</query>");
+req.append("</iq>");
+_11={id:this.session.getNextIqId(),from:this.session.jid+"/"+this.session.resource,type:"set"};
+var _13=new dojox.string.Builder(dojox.xmpp.util.createElement("iq",_11,false));
+_13.append(dojox.xmpp.util.createElement("query",{xmlns:"jabber:iq:privacy"},false));
+_13.append(dojox.xmpp.util.createElement("active",{name:"invisible"},true));
+_13.append("</query>");
+_13.append("</iq>");
+this.session.dispatchPacket(req.toString());
+this.session.dispatchPacket(_13.toString());
+},_manageSubscriptions:function(_14,_15){
+if(!_14){
+return;
+}
+if(_14.indexOf("@")==-1){
+_14+="@"+this.session.domain;
+}
+var req=dojox.xmpp.util.createElement("presence",{to:_14,type:_15},true);
+this.session.dispatchPacket(req);
+},subscribe:function(_17){
+this._manageSubscriptions(_17,"subscribe");
+},approveSubscription:function(_18){
+this._manageSubscriptions(_18,"subscribed");
+},unsubscribe:function(_19){
+this._manageSubscriptions(_19,"unsubscribe");
+},declineSubscription:function(_1a){
+this._manageSubscriptions(_1a,"unsubscribed");
+},cancelSubscription:function(_1b){
+this._manageSubscriptions(_1b,"unsubscribed");
+}});
+}
diff --git a/dojox/xmpp/README b/dojox/xmpp/README
new file mode 100644
index 0000000..322cce2
--- /dev/null
+++ b/dojox/xmpp/README
@@ -0,0 +1,32 @@
+-------------------------------------------------------------------------------
+DojoX XMPP (Jabber Client)
+-------------------------------------------------------------------------------
+Version .9
+Release date: 07/05/2008
+-------------------------------------------------------------------------------
+Project state:	experimental
+-------------------------------------------------------------------------------
+[   ]	l18n support?
+[   ]	a11y support?
+-------------------------------------------------------------------------------
+Credits
+	Dustin Machi
+	Jason Cline
+	Revin Guillen
+-------------------------------------------------------------------------------
+Project description
+
+XMPP Service implementation in pure javascript. Uses BOSH and works cross
+domain.
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo Core 
+-------------------------------------------------------------------------------
+Documentation
+
+FIXME
+-------------------------------------------------------------------------------
+Installation instructions
+
+FIXME
diff --git a/dojox/xmpp/RosterService.js b/dojox/xmpp/RosterService.js
new file mode 100644
index 0000000..3b61c95
--- /dev/null
+++ b/dojox/xmpp/RosterService.js
@@ -0,0 +1,210 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.xmpp.RosterService"]){
+dojo._hasResource["dojox.xmpp.RosterService"]=true;
+dojo.provide("dojox.xmpp.RosterService");
+dojox.xmpp.roster={ADDED:101,CHANGED:102,REMOVED:103};
+dojo.declare("dojox.xmpp.RosterService",null,{constructor:function(_1){
+this.session=_1;
+},addRosterItem:function(_2,_3,_4){
+if(!_2){
+throw new Error("Roster::addRosterItem() - User ID is null");
+}
+var _5=this.session.getNextIqId();
+var _6={id:_5,from:this.session.jid+"/"+this.session.resource,type:"set"};
+var _7=new dojox.string.Builder(dojox.xmpp.util.createElement("iq",_6,false));
+_7.append(dojox.xmpp.util.createElement("query",{xmlns:"jabber:iq:roster"},false));
+_2=dojox.xmpp.util.encodeJid(_2);
+if(_2.indexOf("@")==-1){
+_2=_2+"@"+this.session.domain;
+}
+_7.append(dojox.xmpp.util.createElement("item",{jid:_2,name:dojox.xmpp.util.xmlEncode(_3)},false));
+if(_4){
+for(var i=0;i<_4.length;i++){
+_7.append("<group>");
+_7.append(_4[i]);
+_7.append("</group>");
+}
+}
+_7.append("</item></query></iq>");
+var _9=this.session.dispatchPacket(_7.toString(),"iq",_6.id);
+_9.addCallback(this,"verifyRoster");
+return _9;
+},updateRosterItem:function(_a,_b,_c){
+if(_a.indexOf("@")==-1){
+_a+=_a+"@"+this.session.domain;
+}
+var _d={id:this.session.getNextIqId(),from:this.session.jid+"/"+this.session.resource,type:"set"};
+var _e=new dojox.string.Builder(dojox.xmpp.util.createElement("iq",_d,false));
+_e.append(dojox.xmpp.util.createElement("query",{xmlns:"jabber:iq:roster"},false));
+var i=this.session.getRosterIndex(_a);
+if(i==-1){
+return;
+}
+var _10={jid:_a};
+if(_b){
+_10.name=_b;
+}else{
+if(this.session.roster[i].name){
+_10.name=this.session.roster[i].name;
+}
+}
+if(_10.name){
+_10.name=dojox.xmpp.util.xmlEncode(_10.name);
+}
+_e.append(dojox.xmpp.util.createElement("item",_10,false));
+var _11=_c?_c:this.session.roster[i].groups;
+if(_11){
+for(var x=0;x<_11.length;x++){
+_e.append("<group>");
+_e.append(_11[x]);
+_e.append("</group>");
+}
+}
+_e.append("</item></query></iq>");
+var def=this.session.dispatchPacket(_e.toString(),"iq",_d.id);
+def.addCallback(this,"verifyRoster");
+return def;
+},verifyRoster:function(res){
+if(res.getAttribute("type")=="result"){
+}else{
+var err=this.session.processXmppError(res);
+this.onAddRosterItemFailed(err);
+}
+return res;
+},addRosterItemToGroup:function(jid,_17){
+if(!jid){
+throw new Error("Roster::addRosterItemToGroup() JID is null or undefined");
+}
+if(!_17){
+throw new Error("Roster::addRosterItemToGroup() group is null or undefined");
+}
+var _18=this.session.getRosterIndex(jid);
+if(_18==-1){
+return;
+}
+var _19=this.session.roster[_18];
+var _1a=[];
+var _1b=false;
+for(var i=0;((_19<_19.groups.length)&&(!_1b));i++){
+if(_19.groups[i]!=_17){
+continue;
+}
+_1b=true;
+}
+if(!_1b){
+return this.updateRosterItem(jid,_19.name,_19.groups.concat(_17),_18);
+}
+return dojox.xmpp.xmpp.INVALID_ID;
+},removeRosterGroup:function(_1d){
+var _1e=this.session.roster;
+for(var i=0;i<_1e.length;i++){
+var _20=_1e[i];
+if(_20.groups.length>0){
+for(var j=0;j<_20.groups.length;j++){
+if(_20.groups[j]==_1d){
+_20.groups.splice(j,1);
+this.updateRosterItem(_20.jid,_20.name,_20.groups);
+}
+}
+}
+}
+},renameRosterGroup:function(_22,_23){
+var _24=this.session.roster;
+for(var i=0;i<_24.length;i++){
+var _26=_24[i];
+if(_26.groups.length>0){
+for(var j=0;j<_26.groups.length;j++){
+if(_26.groups[j]==_22){
+_26.groups[j]=_23;
+this.updateRosterItem(_26.jid,_26.name,_26.groups);
+}
+}
+}
+}
+},removeRosterItemFromGroup:function(jid,_29){
+if(!jid){
+throw new Error("Roster::addRosterItemToGroup() JID is null or undefined");
+}
+if(!_29){
+throw new Error("Roster::addRosterItemToGroup() group is null or undefined");
+}
+var _2a=this.session.getRosterIndex(jid);
+if(_2a==-1){
+return;
+}
+var _2b=this.session.roster[_2a];
+var _2c=false;
+for(var i=0;((i<_2b.groups.length)&&(!_2c));i++){
+if(_2b.groups[i]!=_29){
+continue;
+}
+_2c=true;
+_2a=i;
+}
+if(_2c==true){
+_2b.groups.splice(_2a,1);
+return this.updateRosterItem(jid,_2b.name,_2b.groups);
+}
+return dojox.xmpp.xmpp.INVALID_ID;
+},rosterItemRenameGroup:function(jid,_2f,_30){
+if(!jid){
+throw new Error("Roster::rosterItemRenameGroup() JID is null or undefined");
+}
+if(!_30){
+throw new Error("Roster::rosterItemRenameGroup() group is null or undefined");
+}
+var _31=this.session.getRosterIndex(jid);
+if(_31==-1){
+return;
+}
+var _32=this.session.roster[_31];
+var _33=false;
+for(var i=0;((i<_32.groups.length)&&(!_33));i++){
+if(_32.groups[i]==_2f){
+_32.groups[i]=_30;
+_33=true;
+}
+}
+if(_33==true){
+return this.updateRosterItem(jid,_32.name,_32.groups);
+}
+return dojox.xmpp.xmpp.INVALID_ID;
+},renameRosterItem:function(jid,_36){
+if(!jid){
+throw new Error("Roster::addRosterItemToGroup() JID is null or undefined");
+}
+if(!_36){
+throw new Error("Roster::addRosterItemToGroup() New Name is null or undefined");
+}
+var _37=this.session.getRosterIndex(jid);
+if(_37==-1){
+return;
+}
+return this.updateRosterItem(jid,_36,this.session.roster.groups,_37);
+},removeRosterItem:function(jid){
+if(!jid){
+throw new Error("Roster::addRosterItemToGroup() JID is null or undefined");
+}
+var req={id:this.session.getNextIqId(),from:this.session.jid+"/"+this.session.resource,type:"set"};
+var _3a=new dojox.string.Builder(dojox.xmpp.util.createElement("iq",req,false));
+_3a.append(dojox.xmpp.util.createElement("query",{xmlns:"jabber:iq:roster"},false));
+if(jid.indexOf("@")==-1){
+jid+=jid+"@"+this.session.domain;
+}
+_3a.append(dojox.xmpp.util.createElement("item",{jid:jid,subscription:"remove"},true));
+_3a.append("</query></iq>");
+var def=this.session.dispatchPacket(_3a.toString(),"iq",req.id);
+def.addCallback(this,"verifyRoster");
+return def;
+},getAvatar:function(jid){
+},publishAvatar:function(_3d,_3e){
+},onVerifyRoster:function(id){
+},onVerifyRosterFailed:function(err){
+}});
+}
diff --git a/dojox/xmpp/TransportSession.js b/dojox/xmpp/TransportSession.js
new file mode 100644
index 0000000..77c0256
--- /dev/null
+++ b/dojox/xmpp/TransportSession.js
@@ -0,0 +1,308 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.xmpp.TransportSession"]){
+dojo._hasResource["dojox.xmpp.TransportSession"]=true;
+dojo.provide("dojox.xmpp.TransportSession");
+dojo.require("dojox.xmpp.util");
+dojo.require("dojo.io.script");
+dojo.require("dojo.io.iframe");
+dojo.require("dojox.data.dom");
+dojox.xmpp.TransportSession=function(_1){
+if(_1&&dojo.isObject(_1)){
+dojo.mixin(this,_1);
+if(this.useScriptSrcTransport){
+this.transportIframes=[];
+}
+}
+};
+dojox.xmpp.TransportSession._iframeOnload=function(_2){
+var _3=dojo.io.iframe.doc(dojo.byId("xmpp-transport-"+_2));
+_3.write("<script>var isLoaded=true; var rid=0; var transmiting=false; function _BOSH_(msg) { transmiting=false; parent.dojox.xmpp.TransportSession.handleBOSH(msg, rid); } </script>");
+};
+dojox.xmpp.TransportSession.handleBOSH=function(_4,_5){
+};
+dojo.extend(dojox.xmpp.TransportSession,{rid:0,hold:1,polling:1000,secure:false,wait:60,lang:"en",submitContentType:"text/xml; charset=utf=8",serviceUrl:"/httpbind",defaultResource:"dojoIm",domain:"imserver.com",sendTimeout:(this.wait+20)*1000,useScriptSrcTransport:false,keepAliveTimer:null,state:"NotReady",transmitState:"Idle",protocolPacketQueue:[],outboundQueue:[],outboundRequests:{},inboundQueue:[],deferredRequests:{},matchTypeIdAttribute:{},open:function(){
+this.status="notReady";
+this.rid=Math.round(Math.random()*1000000000);
+this.protocolPacketQueue=[];
+this.outboundQueue=[];
+this.outboundRequests={};
+this.inboundQueue=[];
+this.deferredRequests={};
+this.matchTypeIdAttribute={};
+this.keepAliveTimer=setTimeout(dojo.hitch(this,"_keepAlive"),10000);
+if(this.useScriptSrcTransport){
+dojo.connect(dojox.xmpp.TransportSession,"handleBOSH",this,"processScriptSrc");
+this.transportIframes=[];
+for(var i=0;i<=this.hold;i++){
+var _7=dojo.io.iframe.create("xmpp-transport-"+i,dojox._scopeName+".xmpp.TransportSession._iframeOnload("+i+");");
+this.transportIframes.push(_7);
+if(i==0){
+dojo.connect(_7,"onload",this,"_sendLogin");
+}
+}
+}else{
+this._sendLogin();
+}
+},_sendLogin:function(){
+var _8=this.rid++;
+var _9={content:this.submitContentType,hold:this.hold,rid:_8,to:this.domain,secure:this.secure,wait:this.wait,"xml:lang":this.lang,xmlns:dojox.xmpp.xmpp.BODY_NS};
+var _a=dojox.xmpp.util.createElement("body",_9,true);
+this.addToOutboundQueue(_a,_8);
+},processScriptSrc:function(_b,_c){
+var _d=dojox.data.dom.createDocument(_b,"text/xml");
+if(_d){
+this.processDocument(_d,_c);
+}else{
+}
+},_keepAlive:function(){
+if(this.state=="wait"||this.isTerminated()){
+return;
+}
+this._dispatchPacket();
+this.keepAliveTimer=setTimeout(dojo.hitch(this,"_keepAlive"),10000);
+},close:function(_e){
+var _f=this.rid++;
+var req={sid:this.sid,rid:_f,type:"terminate"};
+var _11=null;
+if(_e){
+_11=new dojox.string.Builder(dojox.xmpp.util.createElement("body",req,false));
+_11.append(_e);
+_11.append("</body>");
+}else{
+_11=new dojox.string.Builder(dojox.xmpp.util.createElement("body",req,false));
+}
+this.addToOutboundQueue(_11.toString(),_f);
+this.state=="Terminate";
+},dispatchPacket:function(msg,_13,_14,_15){
+if(msg){
+this.protocolPacketQueue.push(msg);
+}
+var def=new dojo.Deferred();
+if(_13&&_14){
+def.protocolMatchType=_13;
+def.matchId=_14;
+def.matchProperty=_15||"id";
+if(def.matchProperty!="id"){
+this.matchTypeIdAttribute[_13]=def.matchProperty;
+}
+}
+this.deferredRequests[def.protocolMatchType+"-"+def.matchId]=def;
+if(!this.dispatchTimer){
+this.dispatchTimer=setTimeout(dojo.hitch(this,"_dispatchPacket"),600);
+}
+return def;
+},_dispatchPacket:function(){
+clearTimeout(this.dispatchTimer);
+delete this.dispatchTimer;
+if(!this.sid){
+
+return;
+}
+if(!this.authId){
+
+return;
+}
+if(this.transmitState!="error"&&(this.protocolPacketQueue.length==0)&&(this.outboundQueue.length>0)){
+return;
+}
+if(this.state=="wait"||this.isTerminated()){
+return;
+}
+var req={sid:this.sid};
+if(this.protocolPacketQueue.length>0){
+req.rid=this.rid++;
+var _18=new dojox.string.Builder(dojox.xmpp.util.createElement("body",req,false));
+_18.append(this.processProtocolPacketQueue());
+_18.append("</body>");
+delete this.lastPollTime;
+}else{
+if(this.lastPollTime){
+var now=new Date().getTime();
+if(now-this.lastPollTime<this.polling){
+this.dispatchTimer=setTimeout(dojo.hitch(this,"_dispatchPacket"),this.polling-(now-this.lastPollTime)+10);
+return;
+}
+}
+req.rid=this.rid++;
+this.lastPollTime=new Date().getTime();
+var _18=new dojox.string.Builder(dojox.xmpp.util.createElement("body",req,true));
+}
+this.addToOutboundQueue(_18.toString(),req.rid);
+},redispatchPacket:function(rid){
+var env=this.outboundRequests[rid];
+this.sendXml(env,rid);
+},addToOutboundQueue:function(msg,rid){
+this.outboundQueue.push({msg:msg,rid:rid});
+this.outboundRequests[rid]=msg;
+this.sendXml(msg,rid);
+},removeFromOutboundQueue:function(rid){
+for(var i=0;i<this.outboundQueue.length;i++){
+if(rid==this.outboundQueue[i]["rid"]){
+this.outboundQueue.splice(i,1);
+break;
+}
+}
+delete this.outboundRequests[rid];
+},processProtocolPacketQueue:function(){
+var _20=new dojox.string.Builder();
+for(var i=0;i<this.protocolPacketQueue.length;i++){
+_20.append(this.protocolPacketQueue[i]);
+}
+this.protocolPacketQueue=[];
+return _20.toString();
+},findOpenIframe:function(){
+for(var i=0;i<this.transportIframes.length;i++){
+var _23=this.transportIframes[i];
+var win=_23.contentWindow;
+if(win.isLoaded&&!win.transmiting){
+return _23;
+}
+}
+},sendXml:function(_25,rid){
+if(this.isTerminated()){
+return;
+}
+this.transmitState="transmitting";
+if(this.useScriptSrcTransport){
+var _27=this.findOpenIframe();
+var _28=dojo.io.iframe.doc(_27);
+_27.contentWindow.rid=rid;
+_27.contentWindow.transmiting=true;
+dojo.io.script.attach("rid-"+rid,this.serviceUrl+"?"+encodeURIComponent(_25),_28);
+}else{
+var def=dojo.rawXhrPost({contentType:"text/xml",url:this.serviceUrl,postData:_25,handleAs:"xml",error:dojo.hitch(this,function(res,io){
+return this.processError(io.xhr.responseXML,io.xhr.status,rid);
+}),timeout:this.sendTimeout});
+def.addCallback(this,function(res){
+return this.processDocument(res,rid);
+});
+return def;
+}
+},processDocument:function(doc,rid){
+if(this.isTerminated()){
+return;
+}
+this.transmitState="idle";
+var _2f=doc.firstChild;
+if(_2f.nodeName!="body"){
+}
+if(this.outboundQueue.length<1){
+return;
+}
+var _30=this.outboundQueue[0]["rid"];
+if(rid==_30){
+this.removeFromOutboundQueue(rid);
+this.processResponse(_2f,rid);
+this.processInboundQueue();
+}else{
+var gap=rid-_30;
+if(gap<this.hold+2){
+this.addToInboundQueue(doc,rid);
+}else{
+}
+}
+return doc;
+},processInboundQueue:function(){
+while(this.inboundQueue.length>0){
+var _32=this.inboundQueue.shift();
+this.processDocument(_32["doc"],_32["rid"]);
+}
+},addToInboundQueue:function(doc,rid){
+for(var i=0;i<this.inboundQueue.length;i++){
+if(rid<this.inboundQueue[i]["rid"]){
+continue;
+}
+this.inboundQueue.splice(i,0,{doc:doc,rid:rid});
+}
+},processResponse:function(_36,rid){
+if(_36.getAttribute("type")=="terminate"){
+var _38=_36.firstChild.firstChild;
+var _39="";
+if(_38.nodeName=="conflict"){
+_39="conflict";
+}
+this.setState("Terminate",_39);
+return;
+}
+if((this.state!="Ready")&&(this.state!="Terminate")){
+var sid=_36.getAttribute("sid");
+if(sid){
+this.sid=sid;
+}else{
+throw new Error("No sid returned during xmpp session startup");
+}
+this.authId=_36.getAttribute("authid");
+if(this.authId==""){
+if(this.authRetries--<1){
+console.error("Unable to obtain Authorization ID");
+this.terminateSession();
+}
+}
+this.wait=_36.getAttribute("wait");
+if(_36.getAttribute("polling")){
+this.polling=parseInt(_36.getAttribute("polling"))*1000;
+}
+this.inactivity=_36.getAttribute("inactivity");
+this.setState("Ready");
+}
+dojo.forEach(_36.childNodes,function(_3b){
+this.processProtocolResponse(_3b,rid);
+},this);
+if(this.transmitState=="idle"){
+this.dispatchPacket();
+}
+},processProtocolResponse:function(msg,rid){
+this.onProcessProtocolResponse(msg);
+var key=msg.nodeName+"-"+msg.getAttribute("id");
+var def=this.deferredRequests[key];
+if(def){
+def.callback(msg);
+delete this.deferredRequests[key];
+}
+},setState:function(_40,_41){
+if(this.state!=_40){
+if(this["on"+_40]){
+this["on"+_40](_40,this.state,_41);
+}
+this.state=_40;
+}
+},isTerminated:function(){
+return this.state=="Terminate";
+},processError:function(err,_43,rid){
+if(this.isTerminated()){
+return;
+}
+if(_43!=200){
+this.setState("Terminate",_45);
+return;
+}
+if(err&&err.dojoType&&err.dojoType=="timeout"){
+}
+this.removeFromOutboundQueue(rid);
+if(err&&err.firstChild){
+if(err.firstChild.getAttribute("type")=="terminate"){
+var _46=err.firstChild.firstChild;
+var _45="";
+if(_46&&_46.nodeName=="conflict"){
+_45="conflict";
+}
+this.setState("Terminate",_45);
+return;
+}
+}
+this.transmitState="error";
+setTimeout(dojo.hitch(this,function(){
+this.dispatchPacket();
+}),200);
+return true;
+},onTerminate:function(_47,_48,_49){
+},onProcessProtocolResponse:function(msg){
+},onReady:function(_4b,_4c){
+}});
+}
diff --git a/dojox/xmpp/UserService.js b/dojox/xmpp/UserService.js
new file mode 100644
index 0000000..2f8bd05
--- /dev/null
+++ b/dojox/xmpp/UserService.js
@@ -0,0 +1,76 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.xmpp.UserService"]){
+dojo._hasResource["dojox.xmpp.UserService"]=true;
+dojo.provide("dojox.xmpp.UserService");
+dojo.declare("dojox.xmpp.UserService",null,{constructor:function(_1){
+this.session=_1;
+},getPersonalProfile:function(){
+var _2={id:this.session.getNextIqId(),type:"get"};
+var _3=new dojox.string.Builder(dojox.xmpp.util.createElement("iq",_2,false));
+_3.append(dojox.xmpp.util.createElement("query",{xmlns:"jabber:iq:private"},false));
+_3.append(dojox.xmpp.util.createElement("sunmsgr",{xmlsns:"sun:xmpp:properties"},true));
+_3.append("</query></iq>");
+var _4=this.session.dispatchPacket(_3.toString(),"iq",_2.id);
+_4.addCallback(this,"_onGetPersonalProfile");
+},setPersonalProfile:function(_5){
+var _6={id:this.session.getNextIqId(),type:"set"};
+var _7=new dojox.string.Builder(dojox.xmpp.util.createElement("iq",_6,false));
+_7.append(dojox.xmpp.util.createElement("query",{xmlns:"jabber:iq:private"},false));
+_7.append(dojox.xmpp.util.createElement("sunmsgr",{xmlsns:"sun:xmpp:properties"},false));
+for(var _8 in _5){
+_7.append(dojox.xmpp.util.createElement("property",{name:_8},false));
+_7.append(dojox.xmpp.util.createElement("value",{},false));
+_7.append(_5[_8]);
+_7.append("</value></props>");
+}
+_7.append("</sunmsgr></query></iq>");
+var _9=this.session.dispatchPacket(_7.toString(),"iq",_6.id);
+_9.addCallback(this,"_onSetPersonalProfile");
+},_onSetPersonalProfile:function(_a){
+if(_a.getAttribute("type")=="result"){
+this.onSetPersonalProfile(_a.getAttribute("id"));
+}else{
+if(_a.getAttribute("type")=="error"){
+var _b=this.session.processXmppError(_a);
+this.onSetPersonalProfileFailure(_b);
+}
+}
+},onSetPersonalProfile:function(id){
+},onSetPersonalProfileFailure:function(_d){
+},_onGetPersonalProfile:function(_e){
+if(_e.getAttribute("type")=="result"){
+var _f={};
+if(_e.hasChildNodes()){
+var _10=_e.firstChild;
+if((_10.nodeName=="query")&&(_10.getAttribute("xmlns")=="jabber:iq:private")){
+var _11=_10.firstChild;
+if((_11.nodeName=="query")&&(_11.getAttributes("xmlns")=="sun:xmpp:properties")){
+for(var i=0;i<_11.childNodes.length;i++){
+var n=_11.childNodes[i];
+if(n.nodeName=="property"){
+var _14=n.getAttribute("name");
+var val=n.firstChild||"";
+_f[_14]=val;
+}
+}
+}
+}
+this.onGetPersonalProfile(_f);
+}
+}else{
+if(_e.getAttribute("type")=="error"){
+var err=this.session.processXmppError(_e);
+this.onGetPersonalProfileFailure(err);
+}
+}
+return _e;
+},onGetPersonalProfile:function(_17){
+},onGetPersonalProfileFailure:function(err){
+}});
+}
diff --git a/dojox/xmpp/sasl.js b/dojox/xmpp/sasl.js
new file mode 100644
index 0000000..4ab235c
--- /dev/null
+++ b/dojox/xmpp/sasl.js
@@ -0,0 +1,32 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.xmpp.sasl"]){
+dojo._hasResource["dojox.xmpp.sasl"]=true;
+dojo.provide("dojox.xmpp.sasl");
+dojo.require("dojox.xmpp.util");
+dojox.xmpp.sasl.saslNS="urn:ietf:params:xml:ns:xmpp-sasl";
+dojox.xmpp.sasl.SunWebClientAuth=function(_1){
+var _2={xmlns:dojox.xmpp.sasl.saslNS,mechanism:"SUN-COMMS-CLIENT-PROXY-AUTH"};
+var _3=dojox.xmpp.util.createElement("auth",_2,true);
+_1.dispatchPacket(_3);
+};
+dojox.xmpp.sasl.SaslPlain=function(_4){
+var _5={xmlns:dojox.xmpp.sasl.saslNS,mechanism:"PLAIN"};
+var _6=new dojox.string.Builder(dojox.xmpp.util.createElement("auth",_5,false));
+var id=_4.jid;
+var _8=_4.jid.indexOf("@");
+if(_8!=-1){
+id=_4.jid.substring(0,_8);
+}
+var _9="\x00"+id+"\x00"+_4.password;
+_9=dojox.xmpp.util.Base64.encode(_9);
+_6.append(_9);
+_6.append("</auth>");
+_4.dispatchPacket(_6.toString());
+};
+}
diff --git a/dojox/xmpp/util.js b/dojox/xmpp/util.js
new file mode 100644
index 0000000..3e3b317
--- /dev/null
+++ b/dojox/xmpp/util.js
@@ -0,0 +1,167 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.xmpp.util"]){
+dojo._hasResource["dojox.xmpp.util"]=true;
+dojo.provide("dojox.xmpp.util");
+dojo.require("dojox.string.Builder");
+dojox.xmpp.util.xmlEncode=function(_1){
+if(_1){
+_1=_1.replace("&","&").replace(">",">").replace("<","<").replace("'","'").replace("\"",""");
+}
+return _1;
+};
+dojox.xmpp.util.encodeJid=function(_2){
+var _3=new dojox.string.Builder();
+for(var i=0;i<_2.length;i++){
+var ch=_2.charAt(i);
+var _6=ch;
+switch(ch){
+case " ":
+_6="\\20";
+break;
+case "\"":
+_6="\\22";
+break;
+case "#":
+_6="\\23";
+break;
+case "&":
+_6="\\26";
+break;
+case "'":
+_6="\\27";
+break;
+case "/":
+_6="\\2f";
+break;
+case ":":
+_6="\\3a";
+break;
+case "<":
+_6="\\3c";
+break;
+case ">":
+_6="\\3e";
+break;
+}
+_3.append(_6);
+}
+return _3.toString();
+};
+dojox.xmpp.util.decodeJid=function(_7){
+_7=_7.replace(/\\([23][02367acef])/g,function(_8){
+switch(_8){
+case "\\20":
+return " ";
+case "\\22":
+return "\"";
+case "\\23":
+return "#";
+case "\\26":
+return "&";
+case "\\27":
+return "'";
+case "\\2f":
+return "/";
+case "\\3a":
+return ":";
+case "\\3c":
+return "<";
+case "\\3e":
+return ">";
+}
+return "ARG";
+});
+return _7;
+};
+dojox.xmpp.util.createElement=function(_9,_a,_b){
+var _c=new dojox.string.Builder("<");
+_c.append(_9+" ");
+for(var _d in _a){
+_c.append(_d+"=\"");
+_c.append(_a[_d]);
+_c.append("\" ");
+}
+if(_b){
+_c.append("/>");
+}else{
+_c.append(">");
+}
+return _c.toString();
+};
+dojox.xmpp.util.stripHtml=function(_e){
+var re=/<[^>]*?>/gi;
+for(var i=0;i<arguments.length;i++){
+}
+return _e.replace(re,"");
+};
+dojox.xmpp.util.decodeHtmlEntities=function(str){
+var ta=dojo.doc.createElement("textarea");
+ta.innerHTML=str.replace(/</g,"<").replace(/>/g,">");
+return ta.value;
+};
+dojox.xmpp.util.htmlToPlain=function(str){
+str=dojox.xmpp.util.decodeHtmlEntities(str);
+str=str.replace(/<br\s*[i\/]{0,1}>/gi,"\n");
+str=dojox.xmpp.util.stripHtml(str);
+return str;
+};
+dojox.xmpp.util.Base64={};
+dojox.xmpp.util.Base64.keylist="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+dojox.xmpp.util.Base64.encode=function(_14){
+var _15="";
+var c1,c2,c3;
+var _19,_1a,_1b,_1c;
+var i=0;
+do{
+c1=c2=c3="";
+_19=_1a=_1b=_1c="";
+c1=_14.charCodeAt(i++);
+c2=_14.charCodeAt(i++);
+c3=_14.charCodeAt(i++);
+_19=c1>>2;
+_1a=((c1&3)<<4)|(c2>>4);
+_1b=((c2&15)<<2)|(c3>>6);
+_1c=c3&63;
+if(isNaN(c2)){
+_1b=_1c=64;
+}else{
+if(isNaN(c3)){
+_1c=64;
+}
+}
+_15=_15+dojox.xmpp.util.Base64.keylist.charAt(_19)+dojox.xmpp.util.Base64.keylist.charAt(_1a)+dojox.xmpp.util.Base64.keylist.charAt(_1b)+dojox.xmpp.util.Base64.keylist.charAt(_1c);
+}while(i<_14.length);
+return _15;
+};
+dojox.xmpp.util.Base64.decode=function(_1e){
+var _1f="";
+var c1,c2,c3;
+var _23,_24,_25,_26="";
+var i=0;
+do{
+c1=c2=c3="";
+_23=_24=_25=_26="";
+_23=dojox.xmpp.util.Base64.keylist.indexOf(_1e.charAt(i++));
+_24=dojox.xmpp.util.Base64.keylist.indexOf(_1e.charAt(i++));
+_25=dojox.xmpp.util.Base64.keylist.indexOf(_1e.charAt(i++));
+_26=dojox.xmpp.util.Base64.keylist.indexOf(_1e.charAt(i++));
+c1=(_23<<2)|(_24>>4);
+c2=((_24&15)<<4)|(_25>>2);
+c3=((_25&3)<<6)|_26;
+_1f=_1f+String.fromCharCode(c1);
+if(_25!=64){
+_1f=_1f+String.fromCharCode(c2);
+}
+if(_26!=64){
+_1f=_1f+String.fromCharCode(c3);
+}
+}while(i<_1e.length);
+return _1f;
+};
+}
diff --git a/dojox/xmpp/widget/ChatSession.js b/dojox/xmpp/widget/ChatSession.js
new file mode 100644
index 0000000..384c5a1
--- /dev/null
+++ b/dojox/xmpp/widget/ChatSession.js
@@ -0,0 +1,28 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.xmpp.widget.ChatSession"]){
+dojo._hasResource["dojox.xmpp.widget.ChatSession"]=true;
+dojo.provide("dojox.xmpp.widget.ChatSession");
+dojo.declare("dojox.xmpp.widget.ChatSession",[dijit.layout.LayoutContainer,dijit._Templated],{templateString:"<div>\n<div dojoAttachPoint=\"messages\" dojoType=\"dijit.layout.ContentPane\" layoutAlign=\"client\" style=\"overflow:auto\">\n</div>\n<div dojoType=\"dijit.layout.ContentPane\" layoutAlign=\"bottom\" style=\"border-top: 2px solid #333333; height: 35px;\"><input dojoAttachPoint=\"chatInput\" dojoAttachEvent=\"onkeypress: onKeyPress\" style=\"width: 100%;height: 35px;\" /></div>\ [...]
+},displayMessage:function(_1,_2){
+if(_1){
+var _3=_1.from?this.chatWith:"me";
+this.messages.domNode.innerHTML+="<b>"+_3+":</b> "+_1.body+"<br/>";
+this.goToLastMessage();
+}
+},goToLastMessage:function(){
+this.messages.domNode.scrollTop=this.messages.domNode.scrollHeight;
+},onKeyPress:function(e){
+var _5=e.keyCode||e.charCode;
+if((_5==dojo.keys.ENTER)&&(this.chatInput.value!="")){
+this.instance.sendMessage({body:this.chatInput.value});
+this.displayMessage({body:this.chatInput.value},"out");
+this.chatInput.value="";
+}
+}});
+}
diff --git a/dojox/xmpp/widget/templates/ChatSession.html b/dojox/xmpp/widget/templates/ChatSession.html
new file mode 100644
index 0000000..0a94d8c
--- /dev/null
+++ b/dojox/xmpp/widget/templates/ChatSession.html
@@ -0,0 +1,5 @@
+<div>
+<div dojoAttachPoint="messages" dojoType="dijit.layout.ContentPane" layoutAlign="client" style="overflow:auto">
+</div>
+<div dojoType="dijit.layout.ContentPane" layoutAlign="bottom" style="border-top: 2px solid #333333; height: 35px;"><input dojoAttachPoint="chatInput" dojoAttachEvent="onkeypress: onKeyPress" style="width: 100%;height: 35px;" /></div>
+</div>
\ No newline at end of file
diff --git a/dojox/xmpp/xmppSession.js b/dojox/xmpp/xmppSession.js
new file mode 100644
index 0000000..d8bdee2
--- /dev/null
+++ b/dojox/xmpp/xmppSession.js
@@ -0,0 +1,525 @@
+/*
+	Copyright (c) 2004-2009, 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
+*/
+
+
+if(!dojo._hasResource["dojox.xmpp.xmppSession"]){
+dojo._hasResource["dojox.xmpp.xmppSession"]=true;
+dojo.provide("dojox.xmpp.xmppSession");
+dojo.require("dojox.xmpp.TransportSession");
+dojo.require("dojox.xmpp.RosterService");
+dojo.require("dojox.xmpp.PresenceService");
+dojo.require("dojox.xmpp.UserService");
+dojo.require("dojox.xmpp.ChatService");
+dojo.require("dojox.xmpp.sasl");
+dojox.xmpp.xmpp={STREAM_NS:"http://etherx.jabber.org/streams",CLIENT_NS:"jabber:client",STANZA_NS:"urn:ietf:params:xml:ns:xmpp-stanzas",SASL_NS:"urn:ietf:params:xml:ns:xmpp-sasl",BIND_NS:"urn:ietf:params:xml:ns:xmpp-bind",BODY_NS:"http://jabber.org/protocol/httpbind",XHTML_BODY_NS:"http://www.w3.org/1999/xhtml",XHTML_IM_NS:"http://jabber.org/protocol/xhtml-im",INACTIVE:"Inactive",CONNECTED:"Connected",ACTIVE:"Active",TERMINATE:"Terminate",LOGIN_FAILURE:"LoginFailure",INVALID_ID:-1,NO_ID: [...]
+dojox.xmpp.xmppSession=function(_1){
+if(_1&&dojo.isObject(_1)){
+dojo.mixin(this,_1);
+}
+this.session=new dojox.xmpp.TransportSession(_1);
+dojo.connect(this.session,"onReady",this,"onTransportReady");
+dojo.connect(this.session,"onTerminate",this,"onTransportTerminate");
+dojo.connect(this.session,"onProcessProtocolResponse",this,"processProtocolResponse");
+};
+dojo.extend(dojox.xmpp.xmppSession,{roster:[],chatRegister:[],_iqId:Math.round(Math.random()*1000000000),open:function(_2,_3,_4){
+if(!_2){
+throw new Error("User id cannot be null");
+}else{
+this.jid=_2;
+if(_2.indexOf("@")==-1){
+this.jid=this.jid+"@"+this.domain;
+}
+}
+if(_3){
+this.password=_3;
+}
+if(_4){
+this.resource=_4;
+}
+this.session.open();
+},close:function(){
+this.state=dojox.xmpp.xmpp.TERMINATE;
+this.session.close(dojox.xmpp.util.createElement("presence",{type:"unavailable",xmlns:dojox.xmpp.xmpp.CLIENT_NS},true));
+},processProtocolResponse:function(_5){
+var _6=_5.nodeName;
+var _7=_6.indexOf(":");
+if(_7>0){
+_6=_6.substring(_7+1);
+}
+switch(_6){
+case "iq":
+case "presence":
+case "message":
+case "features":
+this[_6+"Handler"](_5);
+break;
+default:
+if(_5.getAttribute("xmlns")==dojox.xmpp.xmpp.SASL_NS){
+this.saslHandler(_5);
+}
+}
+},messageHandler:function(_8){
+switch(_8.getAttribute("type")){
+case "chat":
+this.chatHandler(_8);
+break;
+case "normal":
+default:
+this.simpleMessageHandler(_8);
+}
+},iqHandler:function(_9){
+if(_9.getAttribute("type")=="set"){
+this.iqSetHandler(_9);
+return;
+}else{
+if(_9.getAttribute("type")=="get"){
+return;
+}
+}
+},presenceHandler:function(_a){
+switch(_a.getAttribute("type")){
+case "subscribe":
+this.presenceSubscriptionRequest(_a.getAttribute("from"));
+break;
+case "subscribed":
+case "unsubscribed":
+break;
+case "error":
+this.processXmppError(_a);
+break;
+default:
+this.presenceUpdate(_a);
+break;
+}
+},featuresHandler:function(_b){
+var _c=[];
+var _d=false;
+if(_b.hasChildNodes()){
+for(var i=0;i<_b.childNodes.length;i++){
+var n=_b.childNodes[i];
+switch(n.nodeName){
+case "mechanisms":
+for(var x=0;x<n.childNodes.length;x++){
+_c.push(n.childNodes[x].firstChild.nodeValue);
+}
+break;
+case "bind":
+_d=true;
+break;
+}
+}
+}
+if(this.state==dojox.xmpp.xmpp.CONNECTED&&_d){
+for(var i=0;i<_c.length;i++){
+if(_c[i]=="SUN-COMMS-CLIENT-PROXY-AUTH"){
+dojox.xmpp.sasl.SunWebClientAuth(this);
+break;
+}else{
+if(_c[i]=="PLAIN"){
+dojox.xmpp.sasl.SaslPlain(this);
+break;
+}else{
+console.error("No suitable auth mechanism found for: ",_c[i]);
+}
+}
+}
+delete this.password;
+}
+},saslHandler:function(msg){
+if(msg.nodeName=="success"){
+this.bindResource();
+return;
+}
+if(msg.hasChildNodes()){
+this.onLoginFailure(msg.firstChild.nodeName);
+}
+},chatHandler:function(msg){
+var _13={from:msg.getAttribute("from"),to:msg.getAttribute("to")};
+var _14=null;
+for(var i=0;i<msg.childNodes.length;i++){
+var n=msg.childNodes[i];
+if(n.hasChildNodes()){
+switch(n.nodeName){
+case "thread":
+_13.chatid=n.firstChild.nodeValue;
+break;
+case "body":
+if(!n.getAttribute("xmlns")||(n.getAttribute("xmlns")=="")){
+_13.body=n.firstChild.nodeValue;
+}
+break;
+case "subject":
+_13.subject=n.firstChild.nodeValue;
+case "html":
+if(n.getAttribute("xmlns")==dojox.xmpp.xmpp.XHTML_IM_NS){
+_13.xhtml=n.getElementsByTagName("body")[0];
+}
+break;
+case "x":
+break;
+default:
+}
+}
+}
+var _17=-1;
+if(_13.chatid){
+for(var i=0;i<this.chatRegister.length;i++){
+var ci=this.chatRegister[i];
+if(ci&&ci.chatid==_13.chatid){
+_17=i;
+break;
+}
+}
+}else{
+for(var i=0;i<this.chatRegister.length;i++){
+var ci=this.chatRegister[i];
+if(ci){
+if(ci.uid==this.getBareJid(_13.from)){
+_17=i;
+}
+}
+}
+}
+if(_17>-1&&_14){
+var _19=this.chatRegister[_17];
+_19.setState(_14);
+if(_19.firstMessage){
+if(_14==dojox.xmpp.chat.ACTIVE_STATE){
+_19.useChatState=(_14!=null)?true:false;
+_19.firstMessage=false;
+}
+}
+}
+if((!_13.body||_13.body=="")&&!_13.xhtml){
+return;
+}
+if(_17>-1){
+var _19=this.chatRegister[_17];
+_19.recieveMessage(_13);
+}else{
+var _1a=new dojox.xmpp.ChatService();
+_1a.uid=this.getBareJid(_13.from);
+_1a.chatid=_13.chatid;
+_1a.firstMessage=true;
+if(!_14||_14!=dojox.xmpp.chat.ACTIVE_STATE){
+this.useChatState=false;
+}
+this.registerChatInstance(_1a,_13);
+}
+},simpleMessageHandler:function(msg){
+},registerChatInstance:function(_1c,_1d){
+_1c.setSession(this);
+this.chatRegister.push(_1c);
+this.onRegisterChatInstance(_1c,_1d);
+_1c.recieveMessage(_1d,true);
+},iqSetHandler:function(msg){
+if(msg.hasChildNodes()){
+var fn=msg.firstChild;
+switch(fn.nodeName){
+case "query":
+if(fn.getAttribute("xmlns")=="jabber:iq:roster"){
+this.rosterSetHandler(fn);
+this.sendIqResult(msg.getAttribute("id"),msg.getAttribute("from"));
+}
+break;
+default:
+break;
+}
+}
+},sendIqResult:function(_20,to){
+var req={id:_20,to:to||this.domain,type:"result",from:this.jid+"/"+this.resource};
+this.dispatchPacket(dojox.xmpp.util.createElement("iq",req,true));
+},rosterSetHandler:function(_23){
+for(var i=0;i<_23.childNodes.length;i++){
+var n=_23.childNodes[i];
+if(n.nodeName=="item"){
+var _26=false;
+var _27=-1;
+var _28=null;
+var _29=null;
+for(var x=0;x<this.roster.length;x++){
+var r=this.roster[x];
+if(n.getAttribute("jid")==r.jid){
+_26=true;
+if(n.getAttribute("subscription")=="remove"){
+_28={id:r.jid,name:r.name,groups:[]};
+for(var y=0;y<r.groups.length;y++){
+_28.groups.push(r.groups[y]);
+}
+this.roster.splice(x,1);
+_27=dojox.xmpp.roster.REMOVED;
+}else{
+_29=dojo.clone(r);
+var _2d=n.getAttribute("name");
+if(_2d){
+this.roster[x].name=_2d;
+}
+r.groups=[];
+if(n.getAttribute("subscription")){
+r.status=n.getAttribute("subscription");
+}
+r.substatus=dojox.xmpp.presence.SUBSCRIPTION_SUBSTATUS_NONE;
+if(n.getAttribute("ask")=="subscribe"){
+r.substatus=dojox.xmpp.presence.SUBSCRIPTION_REQUEST_PENDING;
+}
+for(var y=0;y<n.childNodes.length;y++){
+var _2e=n.childNodes[y];
+if((_2e.nodeName=="group")&&(_2e.hasChildNodes())){
+var _2f=_2e.firstChild.nodeValue;
+r.groups.push(_2f);
+}
+}
+_28=r;
+_27=dojox.xmpp.roster.CHANGED;
+}
+break;
+}
+}
+if(!_26&&(n.getAttribute("subscription")!="remove")){
+r=this.createRosterEntry(n);
+_28=r;
+_27=dojox.xmpp.roster.ADDED;
+}
+switch(_27){
+case dojox.xmpp.roster.ADDED:
+this.onRosterAdded(_28);
+break;
+case dojox.xmpp.roster.REMOVED:
+this.onRosterRemoved(_28);
+break;
+case dojox.xmpp.roster.CHANGED:
+this.onRosterChanged(_28,_29);
+break;
+}
+}
+}
+},presenceUpdate:function(msg){
+if(msg.getAttribute("to")){
+var jid=this.getBareJid(msg.getAttribute("to"));
+if(jid!=this.jid){
+return;
+}
+}
+var _32=this.getResourceFromJid(msg.getAttribute("from"));
+if(!_32){
+return;
+}
+var p={from:this.getBareJid(msg.getAttribute("from")),resource:_32,show:dojox.xmpp.presence.STATUS_ONLINE,priority:5,hasAvatar:false};
+if(msg.getAttribute("type")=="unavailable"){
+p.show=dojox.xmpp.presence.STATUS_OFFLINE;
+}
+for(var i=0;i<msg.childNodes.length;i++){
+var n=msg.childNodes[i];
+if(n.hasChildNodes()){
+switch(n.nodeName){
+case "status":
+case "show":
+p[n.nodeName]=n.firstChild.nodeValue;
+break;
+case "status":
+p.priority=parseInt(n.firstChild.nodeValue);
+break;
+case "x":
+if(n.firstChild&&n.firstChild.firstChild&&n.firstChild.firstChild.nodeValue!=""){
+p.avatarHash=n.firstChild.firstChild.nodeValue;
+p.hasAvatar=true;
+}
+break;
+}
+}
+}
+this.onPresenceUpdate(p);
+},retrieveRoster:function(){
+var _36={id:this.getNextIqId(),from:this.jid+"/"+this.resource,type:"get"};
+var req=new dojox.string.Builder(dojox.xmpp.util.createElement("iq",_36,false));
+req.append(dojox.xmpp.util.createElement("query",{xmlns:"jabber:iq:roster"},true));
+req.append("</iq>");
+var def=this.dispatchPacket(req,"iq",_36.id);
+def.addCallback(this,"onRetrieveRoster");
+},getRosterIndex:function(jid){
+if(jid.indexOf("@")==-1){
+jid+="@"+this.domain;
+}
+for(var i=0;i<this.roster.length;i++){
+if(jid==this.roster[i].jid){
+return i;
+}
+}
+return -1;
+},createRosterEntry:function(_3b){
+var re={name:_3b.getAttribute("name"),jid:_3b.getAttribute("jid"),groups:[],status:dojox.xmpp.presence.SUBSCRIPTION_NONE,substatus:dojox.xmpp.presence.SUBSCRIPTION_SUBSTATUS_NONE};
+if(!re.name){
+re.name=re.id;
+}
+for(var i=0;i<_3b.childNodes.length;i++){
+var n=_3b.childNodes[i];
+if(n.nodeName=="group"&&n.hasChildNodes()){
+re.groups.push(n.firstChild.nodeValue);
+}
+}
+if(_3b.getAttribute("subscription")){
+re.status=_3b.getAttribute("subscription");
+}
+if(_3b.getAttribute("ask")=="subscribe"){
+re.substatus=dojox.xmpp.presence.SUBSCRIPTION_REQUEST_PENDING;
+}
+return re;
+},bindResource:function(){
+var _3f={xmlns:"jabber:client",id:this.getNextIqId(),type:"set"};
+var _40=new dojox.string.Builder(dojox.xmpp.util.createElement("iq",_3f,false));
+_40.append(dojox.xmpp.util.createElement("bind",{xmlns:dojox.xmpp.xmpp.BIND_NS},false));
+if(this.resource){
+_40.append(dojox.xmpp.util.createElement("resource"));
+_40.append(this.resource);
+_40.append("</resource>");
+}
+_40.append("</bind></iq>");
+var def=this.dispatchPacket(_40,"iq",_3f.id);
+def.addCallback(this,"onBindResource");
+},getNextIqId:function(){
+return "im_"+this._iqId++;
+},presenceSubscriptionRequest:function(msg){
+this.onSubscriptionRequest(msg);
+},dispatchPacket:function(msg,_44,_45){
+if(this.state!="Terminate"){
+return this.session.dispatchPacket(msg,_44,_45);
+}else{
+}
+},setState:function(_46,_47){
+if(this.state!=_46){
+if(this["on"+_46]){
+this["on"+_46](_46,this.state,_47);
+}
+this.state=_46;
+}
+},search:function(_48,_49,_4a){
+var req={id:this.getNextIqId(),"xml:lang":this.lang,type:"set",from:this.jid+"/"+this.resource,to:_49};
+var _4c=new dojox.string.Builder(dojox.xmpp.util.createElement("iq",req,false));
+_4c.append(dojox.xmpp.util.createElement("query",{xmlns:"jabber:iq:search"},false));
+_4c.append(dojox.xmpp.util.createElement(_4a,{},false));
+_4c.append(_48);
+_4c.append("</").append(_4a).append(">");
+_4c.append("</query></iq>");
+var def=this.dispatchPacket(_4c.toString,"iq",req.id);
+def.addCallback(this,"_onSearchResults");
+},_onSearchResults:function(msg){
+if((msg.getAttribute("type")=="result")&&(msg.hasChildNodes())){
+this.onSearchResults([]);
+}
+},onLogin:function(){
+this.retrieveRoster();
+},onLoginFailure:function(msg){
+},onBindResource:function(msg){
+if(msg.getAttribute("type")=="result"){
+if((msg.hasChildNodes())&&(msg.firstChild.nodeName=="bind")){
+var _51=msg.firstChild;
+if((_51.hasChildNodes())&&(_51.firstChild.nodeName=="jid")){
+if(_51.firstChild.hasChildNodes()){
+var _52=_51.firstChild.firstChild.nodeValue;
+this.jid=this.getBareJid(_52);
+this.resource=this.getResourceFromJid(_52);
+}
+}
+}else{
+}
+this.onLogin();
+}else{
+if(msg.getAttribute("type")=="error"){
+var err=this.processXmppError(msg);
+this.onLoginFailure(err);
+}
+}
+return msg;
+},onSearchResults:function(_54){
+},onRetrieveRoster:function(msg){
+if((msg.getAttribute("type")=="result")&&msg.hasChildNodes()){
+var _56=msg.getElementsByTagName("query")[0];
+if(_56.getAttribute("xmlns")=="jabber:iq:roster"){
+for(var i=0;i<_56.childNodes.length;i++){
+if(_56.childNodes[i].nodeName=="item"){
+this.roster[i]=this.createRosterEntry(_56.childNodes[i]);
+}
+}
+}
+}else{
+if(msg.getAttribute("type")=="error"){
+}
+}
+this.setState(dojox.xmpp.xmpp.ACTIVE);
+this.onRosterUpdated();
+return msg;
+},onRosterUpdated:function(){
+},onSubscriptionRequest:function(req){
+},onPresenceUpdate:function(p){
+},onTransportReady:function(){
+this.setState(dojox.xmpp.xmpp.CONNECTED);
+this.rosterService=new dojox.xmpp.RosterService(this);
+this.presenceService=new dojox.xmpp.PresenceService(this);
+this.userService=new dojox.xmpp.UserService(this);
+},onTransportTerminate:function(_5a,_5b,_5c){
+this.setState(dojox.xmpp.xmpp.TERMINATE,_5c);
+},onConnected:function(){
+},onTerminate:function(_5d,_5e,_5f){
+},onActive:function(){
+},onRegisterChatInstance:function(_60,_61){
+},onRosterAdded:function(ri){
+},onRosterRemoved:function(ri){
+},onRosterChanged:function(ri,_65){
+},processXmppError:function(msg){
+var err={stanzaType:msg.nodeName,id:msg.getAttribute("id")};
+for(var i=0;i<msg.childNodes.length;i++){
+var n=msg.childNodes[i];
+switch(n.nodeName){
+case "error":
+err.errorType=n.getAttribute("type");
+for(var x=0;x<n.childNodes.length;x++){
+var cn=n.childNodes[x];
+if((cn.nodeName=="text")&&(cn.getAttribute("xmlns")==dojox.xmpp.xmpp.STANZA_NS)&&cn.hasChildNodes()){
+err.message=cn.firstChild.nodeValue;
+}else{
+if((cn.getAttribute("xmlns")==dojox.xmpp.xmpp.STANZA_NS)&&(!cn.hasChildNodes())){
+err.condition=cn.nodeName;
+}
+}
+}
+break;
+default:
+break;
+}
+}
+return err;
+},sendStanzaError:function(_6c,to,id,_6f,_70,_71){
+var req={type:"error"};
+if(to){
+req.to=to;
+}
+if(id){
+req.id=id;
+}
+var _73=new dojox.string.Builder(dojox.xmpp.util.createElement(_6c,req,false));
+_73.append(dojox.xmpp.util.createElement("error",{type:_6f},false));
+_73.append(dojox.xmpp.util.createElement("condition",{xmlns:dojox.xmpp.xmpp.STANZA_NS},true));
+if(_71){
+var _74={xmlns:dojox.xmpp.xmpp.STANZA_NS,"xml:lang":this.lang};
+_73.append(dojox.xmpp.util.createElement("text",_74,false));
+_73.append(_71).append("</text>");
+}
+_73.append("</error></").append(_6c).append(">");
+this.dispatchPacket(_73.toString());
+},getBareJid:function(jid){
+var i=jid.indexOf("/");
+if(i!=-1){
+return jid.substring(0,i);
+}
+return jid;
+},getResourceFromJid:function(jid){
+var i=jid.indexOf("/");
+if(i!=-1){
+return jid.substring((i+1),jid.length);
+}
+return "";
+}});
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/dojo.git



More information about the Pkg-javascript-commits mailing list