Actually commit the new simplified dojo directory. Did not see it due to .hgignore.
authorJames Burke <jrburke@mozillamessaging.com>
Mon, 29 Mar 2010 19:57:41 -0700
changeset 1517 39d50efcfc688ce2984b88d9b5d2cb84885e95a3
parent 1516 0d7f895b06b8bd1b3f3b7891613db39e4390e349
child 1518 e14e5d03cf7099d0c565e657adf9a5bde8c3fafb
push id806
push userjrburke@gmail.com
push dateTue, 30 Mar 2010 02:57:55 +0000
Actually commit the new simplified dojo directory. Did not see it due to .hgignore.
.hgignore
client/dojo/dijit/themes/dijit.css
client/dojo/dojo.js
client/dojo/dojo/resources/blank.gif
client/dojo/raindrop.build.js
client/dojo/raindrop.sh
--- a/.hgignore
+++ b/.hgignore
@@ -3,10 +3,9 @@ syntax:regexp
 \.egg-info
 \.pyc
 \.swp
 \.DS_Store
 \.min
 ^server/python/build/
 ^nbproject/
 ^pipeline.svg$
-^client/dojo/
 ^tools/clientbuild/
new file mode 100644
--- /dev/null
+++ b/client/dojo/dijit/themes/dijit.css
@@ -0,0 +1,1866 @@
+/*
+	Essential styles that themes can inherit.
+	In other words, works but doesn't look great.
+*/
+
+
+
+/****
+		GENERIC PIECES
+ ****/
+
+.dijitReset {
+	/* Use this style to null out padding, margin, border in your template elements
+		so that page specific styles don't break them.
+		- Use in all TABLE, TR and TD tags.
+	*/
+	margin:0;
+	border:0;
+	padding:0;
+	line-height:normal;
+	font: inherit;
+	color: inherit;
+}
+
+.dijitInline {
+	/*  To inline block elements.
+		Similar to InlineBox below, but this has fewer side-effects in Moz.
+		Also, apparently works on a DIV as well as a FIELDSET.
+	*/
+	display:inline-block;			/* webkit and FF3 */
+	#zoom: 1; /* set hasLayout:true to mimic inline-block */
+	#display:inline; /* don't use .dj_ie since that increases the priority */
+	border:0;
+	padding:0;
+	vertical-align:middle;
+	#vertical-align: auto;	/* makes TextBox,Button line up w/native counterparts on IE6 */
+}
+
+.dijitHidden {
+	/* To hide unselected panes in StackContainer etc. */
+	display: none !important;
+}
+
+.dijitVisible {
+	/* To show selected pane in StackContainer etc. */
+	display: block !important;	/* override user's display:none setting via style setting or indirectly via class */
+	position: relative;			/* to support setting width/height, see #2033 */
+}
+
+
+.dj_ie INPUT.dijitTextBox,
+.dj_ie .dijitInputField INPUT {
+	font-size: 100%;
+}
+
+.dj_ie .dijitInputField INPUT { /* try to get rid of IE implicit margin around INPUT */
+	margin: -1px 0 !important;
+}
+
+.dijitInlineTable {
+	/* To inline tables with a given width set (otherwise, use dijitInline above) */
+	display:inline-table;
+	display:inline-block;		/* webkit and FF3 */
+	#zoom: 1; /* set hasLayout:true to mimic inline-block */
+	#display:inline; /* don't use .dj_ie since that increases the priority */
+	box-sizing: content-box; -moz-box-sizing: content-box;
+	border:0;
+	padding:0;
+}
+
+.dijitTeeny {
+	font-size:1px;
+	line-height:1px;
+}
+
+/*
+ * Popup items have a wrapper div (dijitPopup)
+ * with the real popup inside, and maybe an iframe too
+ */
+.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 {
+	/* Null out all position-related properties */
+	padding: 0 !important;
+	border: 0 !important;
+	background-color: transparent !important;
+	background-image: none !important;
+	height: auto !important;
+	width: auto !important;
+}
+
+.dijitNonPositionOnly {
+	/* Null position-related properties */
+	float: none !important;
+	position: static !important;
+	margin: 0 0 0 0 !important;
+	vertical-align: middle !important;
+}
+
+.dijitBackgroundIframe {
+	/* iframe used to prevent problems with PDF or other applets overlaying menus etc */
+	position: absolute;
+	left: 0;
+	top: 0;
+	width: 100%;
+	height: 100%;
+	z-index: -1;
+	border: 0;
+	padding: 0;
+	margin: 0;
+}
+
+.dijitClickableRegion {
+	/* An InlineEditBox in view mode (click this to edit the text) */
+	background-color: #e2ebf2;
+	cursor: text;
+}
+
+
+.dijitDisplayNone {
+	/* hide something.  Use this as a class rather than element.style so another class can override */
+	display:none !important;
+}
+
+.dijitContainer {
+	/* for all layout containers */
+	overflow: hidden;	/* need on IE so something can be reduced in size, and so scrollbars aren't temporarily displayed when resizing */
+}
+
+/****
+		A11Y
+ ****/
+.dijit_a11y * {
+	background-image:none !important;
+}
+
+.dijit_a11y .dijitCalendarIncrementControl {
+	display: none;	/* don't display icon */
+}
+.dijit_a11y .dijitA11ySideArrow {
+	display: inline !important; /* display text instead */
+	cursor: pointer;
+}
+
+/*
+ * Since we can't use shading in a11y mode, and since the underline indicates today's date,
+ * use a border to show the selected date.
+ * Avoid screen jitter when switching selected date by compensating for the selected node's
+ * border w/padding on other nodes.
+ */
+.dijit_a11y .dijitCalendarDateLabel {
+	padding: 1px;
+}
+.dijit_a11y .dijitCalendarSelectedDate .dijitCalendarDateLabel {
+	border: solid 1px black;
+	padding: 0px;
+}
+.dijit_a11y .dijitCalendarDateTemplate {
+	padding-bottom: 0.1em !important;	/* otherwise bottom border doesn't appear on IE */
+}
+
+.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 .dijitComboBoxReadOnly .dijitInputField,
+.dijit_a11y .dijitComboBoxReadOnly .dijitButtonNode,
+.dijit_a11y .dijitSpinnerReadOnly .dijitButtonNode,
+.dijit_a11y .dijitSpinnerReadOnly .dijitInputField,
+.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;
+}
+
+/* button inner contents - labels, icons etc. */
+.dijitButtonNode * {
+	vertical-align: middle;
+}
+.dijit_a11y .dijitArrowButtonInner {
+	width: 1em;
+	display: none !important;
+}
+.dijitButtonNode .dijitArrowButtonInner {
+	background:no-repeat center;
+	width: 16px;
+}
+.dijitComboBox .dijitArrowButtonInner {
+	display: block;
+}
+
+/* In high contrast mode, display the check symbol */
+.dijit_a11y .dijitToggleButtonChecked .dijitToggleButtonIconChar {
+	display: inline !important;
+}
+
+
+/****
+		3-element borders:  ( dijitLeft + dijitStretch + dijitRight )
+ ****/
+
+.dijitLeft {
+	/* Left part of a 3-element border */
+	background-position:left top;
+	background-repeat:no-repeat;
+}
+
+.dijitStretch {
+	/* Middle (stretchy) part of a 3-element border */
+	white-space:nowrap;			/* MOW: move somewhere else */
+	background-repeat:repeat-x;
+}
+
+.dijitRight {
+	/* Right part of a 3-element border */
+	#display:inline;				/* IE7 sizes to outer size w/o this */
+	background-position:right top;
+	background-repeat:no-repeat;
+}
+
+.dijitToggleButton,
+.dijitButton,
+.dijitDropDownButton,
+.dijitComboButton {
+	/* outside of button */
+	margin: 0.2em;
+}
+
+.dijitToolbar .dijitToggleButton,
+.dijitToolbar .dijitButton,
+.dijitToolbar .dijitDropDownButton,
+.dijitToolbar .dijitComboButton {
+	margin: 0;
+}
+
+.dj_ie8 .dijitToolbar button,
+.dj_webkit .dijitToolbar button {
+	/* FF and IE<8 adds implicit padding to buttons, so make other browsers follow suit,
+	 * to avoid a bunch of browse specific rules in theme files
+	 */
+	padding: 1px 2px;
+}
+
+.dj_ie .dijitToolbar .dijitComboBox{
+	/* make combobox buttons align porperly with other buttons in a toolbar */
+	vertical-align: middle;
+}
+
+.dj_ie .dijitComboButton {
+	/* hack to get inline-table to vertically align w/other buttons */
+	margin-bottom: -3px;
+}
+
+.dj_webkit .dijitToolbar .dijitDropDownButton {
+	padding-left: 0.3em;
+}
+.dj_gecko .dijitToolbar .dijitButtonNode::-moz-focus-inner {
+	padding:0;
+}
+
+.dijitButtonNode {
+	/* Node that is acting as a button -- may or may not be a BUTTON element */
+	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;
+}
+
+/**** Disabled cursor *****/
+.dijitReadOnly *,
+.dijitDisabled *,
+.dijitReadOnly,
+.dijitDisabled,
+.dijitDisabledClickableRegion {	/* a region the user would be able to click on, but it's disabled */
+	cursor: not-allowed !important;
+}
+
+.dj_ie .dijitButtonNode {
+	/* ensure hasLayout */
+	zoom: 1;
+}
+
+.dj_ie .dijitButtonNode button {
+	/*
+		disgusting hack to get rid of spurious padding around button elements
+		on IE. MSIE is truly the web's boat anchor.
+	*/
+	overflow: visible;
+}
+
+.dijitArrowButton {
+	/* Node that is acting as a arrow button -- drop down (spinner has its own treatment).  Also gets dijitButtonNode */
+	/* place AFTER dijitButtonNode so it overrides */
+	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 {
+	/* In ComboButton, borders are on each cell rather than on <table> itself */
+	border-collapse: collapse;
+	border:0;
+	padding:0;
+	margin:0;
+}
+.dijitToolbar .dijitComboButton {
+	/* because Toolbar only draws a border around the hovered thing */
+	border-collapse: separate;
+}
+
+.dj_ie BUTTON.dijitButtonNode {
+	overflow: visible; /* eliminates arbitrary left and right padding on buttons */
+}
+
+table .dijitButton .dijitButtonNode,
+table .dijitComboButton .dijitButtonNode {
+	#overflow:hidden; /* visible messes up if the button is inside a table on IE */
+}
+
+
+
+.dijitButtonNode IMG {
+	/* make text and images line up cleanly */
+	vertical-align:middle;
+	/*margin-bottom:.2em;*/
+}
+
+/******
+	TextBox related.
+	Everything that has an <input>
+*******/
+
+.dijitTextBox,
+.dijitComboBox,
+.dijitSpinner {
+	border: solid black 1px;
+	#overflow: hidden; /* #6027, #6067 */
+	width: 15em;	/* need to set default size on outer node since inner nodes say <input style="width:100%"> and <td width=100%>.  user can override */
+	vertical-align: middle;
+	#vertical-align: auto;
+}
+
+.dijitTimeTextBox {
+	width: 8em;
+}
+
+/* rules for safari to deal with fuzzy blue focus border */
+.dijitTextBox input:focus,
+.dijitComboBox input:focus,
+.dijitSpinner input:focus {
+	outline: none;	/* blue fuzzy line looks wrong on combobox or something w/validation icon showing */
+}
+.dijitTextBoxFocused,
+.dijitComboBoxFocused,
+.dijitSpinnerFocused, .dijitSpinnerUpArrowActive, .dijitSpinnerDownArrowActive,
+.dijitTextAreaFocused {
+	/* should we display focus like we do on other browsers, or use the safari standard focus indicator?? */
+	outline: auto 5px -webkit-focus-ring-color;
+}
+
+.dijitTextBox INPUT,
+.dijitComboBox INPUT,
+.dijitSpinner INPUT {
+	border-left: solid black 1px;	/* TODO: for RTL mode should be border-right */
+	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;
+}
+
+/* Display an "X" for invalid input. Themes will override these rules to display an icon instead.
+*/
+.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 {
+	/* this is for a combo box with no arrow displayed; we set baseClass=TextBox */
+	display:none;
+}
+
+/****
+		dijit.form.CheckBox
+ 	 &
+  		dijit.form.RadioButton
+ ****/
+
+.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 {
+	/* place the actual input on top, but all-but-invisible */
+	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;
+}
+
+
+/****
+		dijit.ProgressBar
+ ****/
+
+.dijitProgressBarEmpty{
+	/* outer container and background of the bar that's not finished yet*/
+	position:relative;overflow:hidden;
+	border:1px solid black; 	/* a11y: border necessary for high-contrast mode */
+	z-index:0;			/* establish a stacking context for this progress bar */
+}
+
+.dijitProgressBarFull {
+	/* outer container for background of bar that is finished */
+	position:absolute;
+	overflow:hidden;
+	z-index:-1;
+	top:0;
+	width:100%;
+}
+.dj_ie6 .dijitProgressBarFull {
+	height:1.6em;
+}
+
+.dijitProgressBarTile {
+	/* inner container for finished portion */
+	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{
+	/* a11y:  The border provides visibility in high-contrast mode */
+	border-width:4px;
+	border-style:solid;
+	background-color:transparent !important;
+}
+
+.dj_ie6 .dijitProgressBarTile {
+	/* width:auto works in IE6 with position:static but not position:absolute */
+	position:static;
+	/* height:auto or 100% does not work in IE6 */
+	height:1.6em;
+}
+
+.dijitProgressBarIndeterminate .dijitProgressBarLabel {
+	visibility:hidden;
+}
+
+.dijitProgressBarIndeterminate .dijitProgressBarTile {
+	/* animated gif for 'indeterminate' mode */
+}
+
+.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;
+}
+
+/****
+		dijit.Tooltip
+ ****/
+
+.dijitTooltip {
+	position: absolute;
+	z-index: 2000;
+	display: block;
+	/* make visible but off screen */
+	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;
+}
+/* MOW: using actual images at this time ??? close???
+/* draw an arrow with CSS only * /
+.dijitTooltipConnector {
+	/* the border on the triangle * /
+	font-size: 0; line-height: 0%; width: 0;
+	border-top: none;
+	border-bottom: 14px solid black;
+	border-left: 7px solid transparent;
+	border-right: 7px solid transparent;
+	top: -14px;
+	left: 3px;
+	z-index: 2;
+}
+
+.dijitTooltipConnector div {
+	/* the background of the triangle * /
+	font-size: 0; line-height: 0%; width: 0;
+	position: absolute;
+	border-bottom: 10px solid #b8b5b5;
+	border-left: 5px solid transparent;
+	border-right: 5px solid transparent;
+	top: 6px;
+	left: -5px;
+	z-index: 3;
+}
+
+*/
+
+
+
+/* Layout widgets. This is essential CSS to make layout work (it isn't "styling" CSS)
+   make sure that the position:absolute in dijitAlign* overrides other classes */
+
+.dijitLayoutContainer{
+	position: relative;
+	display: block;
+	overflow: hidden;
+}
+
+body .dijitAlignTop,
+body .dijitAlignBottom,
+body .dijitAlignLeft,
+body .dijitAlignRight {
+	position: absolute;
+	overflow: hidden;
+}
+
+body .dijitAlignClient { position: absolute; }
+
+/*
+ * BorderContaienr
+ *
+ * .dijitBorderContainer is a stylized layout where panes have border and margin.
+ * .dijitBorderContainerNoGutter is a raw layout.
+ */
+.dijitBorderContainer, .dijitBorderContainerNoGutter {
+	position:relative;
+	overflow: hidden;
+}
+
+.dijitBorderContainerPane,
+.dijitBorderContainerNoGutterPane {
+	position: absolute !important;	/* !important to override position:relative in dijitTabContainer etc. */
+	z-index: 2;		/* above the splitters so that off-by-one browser errors don't cover up border of pane */
+}
+
+.dijitBorderContainer > .dijitTextArea {
+	/* On Safari, for SimpleTextArea inside a BorderContainer,
+		don't want to display the grip to resize */
+	resize: none;
+}
+
+.dijitGutter {
+	/* gutter is just a place holder for empty space between panes in BorderContainer */
+	position: absolute;
+	font-size: 1px;		/* needed by IE6 even though div is empty, otherwise goes to 15px */
+}
+
+/* SplitContainer
+
+	'V' == container that splits vertically (up/down)
+	'H' = horizontal (left/right)
+*/
+
+.dijitSplitter {
+	position: absolute;
+	overflow: hidden;
+	z-index: 10;		/* above the panes so that splitter focus is visible on FF, see #7583*/
+	background-color: #fff;
+	border-color: gray;
+	border-style: solid;
+	border-width: 0;
+}
+.dj_ie .dijitSplitter {
+	z-index: 1;	/* behind the panes so that pane borders aren't obscured see test_Gui.html/[14392] */
+}
+
+.dijitSplitterActive {
+	z-index: 11 !important;
+}
+
+.dijitSplitterCover{
+	position:absolute;
+	z-index:-1;
+	top:0;
+	left:0;
+	width:100%;
+	height:100%;
+}
+
+.dijitSplitterCoverActive{
+	z-index:3 !important;
+}
+
+/* #6945: stop mouse events */
+.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;
+}
+
+/* ContentPane */
+
+.dijitContentPane {
+	display: block;
+	overflow: auto;	/* if we don't have this (or overflow:hidden), then Widget.resizeTo() doesn't make sense for ContentPane */
+}
+
+.dijitContentPaneSingleChild {
+	/*
+	 * if the ContentPane holds a single layout widget child which is being sized to match the content pane,
+	 * then the ContentPane should never get a scrollbar (but it does due to browser bugs, see #9449
+	 */
+	overflow: hidden;
+}
+
+/* TitlePane */
+.dijitTitlePane {
+	display: block;
+	overflow: hidden;
+}
+
+/* Color Palette */
+
+.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; /*This is the width of one color in the provided palettes. */
+	height: 14px; /* Height of one color in the provided palettes. */
+	position: absolute;
+	top: 1px;
+	left: 1px;
+	overflow: hidden;
+	cursor: default;
+	border:1px solid #999;
+	/* -moz-border-radius:2pt; */
+}
+
+.dijitPaletteCellHighlight img {
+	width: 14px; /*This is the width of one color in the provided palettes. */
+	height: 12px; /* Height of one color in the provided palettes. */
+	position: absolute;
+	top: 1px;
+	left: 1px;
+	overflow: hidden;
+	cursor: default;
+	border:2px solid #000;
+	outline:1px solid #dedede;
+	/* -moz-border-radius:0; */
+}
+
+.dijit_a11y .dijitPaletteCell {
+	background-color:transparent !important;
+}
+.dijit_a11y .dijitPaletteImg {
+	background-color:transparent !important;
+}
+
+.dijitAccordionContainer {
+	border:1px solid #b7b7b7;
+	border-top:0 !important;
+}
+/* prevent partial, ugly focus border on FF and Safari */
+.dj_webkit .dijitAccordionContainer  div:focus {
+	outline:none;
+}
+.dj_ff3 .dijitAccordionContainer  div:focus {
+	outline:none;
+}
+.dijitAccordionTitle {
+	cursor: pointer;
+}
+.dijitAccordionFocused  {
+	text-decoration: underline;
+}
+
+/* images off, high-contrast mode styles */
+.dijitAccordionTitle .arrowTextUp,
+.dijitAccordionTitle .arrowTextDown {
+	display: none;
+	font-size: 0.65em;
+	font-weight: normal !important;
+}
+
+.dijit_a11y .dijitAccordionTitle .arrowTextUp,
+.dijit_a11y .dijitAccordionTitle-selected .arrowTextDown {
+	display: inline;
+}
+
+.dijit_a11y .dijitAccordionTitle-selected .arrowTextUp {
+	display: none;
+}
+
+/* Calendar */
+
+.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 {
+	vertical-align: middle;
+}
+
+.dijitCalendarDisabledDate {
+	color:gray !important;
+}
+
+.dijitCalendarPreviousMonthDisabled,
+.dijitCalendarCurrentMonthDisabled,
+.dijitCalendarNextMonthDisabled {
+	cursor:default !important
+}
+
+.dijitCalendarIncrementControl,
+.dijitCalendarBodyContainer tbody tr td,
+.dijitCalendarDateTemplate,
+.dijitCalendarContainer .dijitInline {
+	cursor:pointer;
+}
+
+.dijitSpacer {
+	/* don't display it, but make it affect the width */
+  	position: relative;
+  	height: 1px;
+  	overflow: hidden;
+  	visibility: hidden;
+}
+
+
+/* Menu */
+
+.dijitMenu {
+	border:1px solid black;
+	background-color:white;
+}
+.dijitMenuTable {
+	margin:1px 0;
+	border-collapse:collapse;
+	border-width:0;
+	background-color:white;
+}
+
+/* workaround for webkit bug #8427, remove this when it is fixed upstream */
+.dj_webkit .dijitMenuTable td[colspan="2"]{
+	border-right:hidden;
+}
+
+.dijitMenuItem{
+	text-align: left;
+	white-space: nowrap;
+	padding:.1em .2em;
+	cursor:pointer;
+}
+
+.dijitMenuPassive .dijitMenuItemHover,
+.dijitMenuItemSelected {
+	/*
+	 * dijitMenuItemHover refers to actual mouse over
+	 * dijitMenuItemSelected is used after a menu has been "activated" by
+	 * clicking it, tabbing into it, or being opened from a parent menu,
+	 * and denotes that the menu item has focus or that focus is on a child
+	 * menu
+	 */
+	background-color:black;
+	color:white;
+}
+
+.dijitMenuItemIcon, .dijitMenuExpand {
+	background-repeat: no-repeat;
+}
+
+.dijitMenuItemDisabled * {
+	/* for a disabled menu item, just set it to mostly transparent */
+	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 {
+	border: 1px #fff dotted !important;
+}
+.dj_ff3 .dijit_a11y .dijitMenuItem td {
+	padding: none !important;
+	background:none ! important;
+}
+.dijit_a11y .dijitMenuItemSelected .dijitMenuItemLabel {
+	border-width: 1px;
+	border-style: solid;
+}
+.dj_ie8 .dijit_a11y .dijitMenuItemLabel {
+	position:static;
+}
+
+.dijitMenuExpandA11y {
+	display: none;
+}
+.dijit_a11y .dijitMenuExpandA11y {
+	display: inline;
+}
+
+.dijitMenuSeparator td {
+	border: 0;
+	padding: 0;
+}
+
+/* separator can be two pixels -- set border of either one to 0 to have only one */
+.dijitMenuSeparatorTop {
+	height: 50%;
+	margin: 0;
+	margin-top:3px;
+	font-size: 1px;
+}
+
+.dijitMenuSeparatorBottom {
+	height: 50%;
+	margin: 0;
+	margin-bottom:3px;
+	font-size: 1px;
+}
+
+/* the checked menu item */
+.dijitCheckedMenuItemIconChar {
+	vertical-align: middle;
+	visibility:hidden;
+}
+.dijitCheckedMenuItemChecked .dijitCheckedMenuItemIconChar {
+	visibility: visible;
+}
+.dijit_a11y .dijitCheckedMenuItemIconChar {
+	display:inline !important;
+}
+.dijit_a11y .dijitCheckedMenuItemIcon {
+	display: none;
+}
+
+
+/* StackContainer */
+
+.dijitStackController .dijitToggleButtonChecked * {
+	cursor: default;	/* because pressing it has no effect */
+}
+
+/* TabContainer */
+
+.dijitTabContainerNoLayout {
+	width: 100%;	/* otherwise ScrollingTabController goes to 50K pixels wide */
+}
+
+.dijitTabContainerBottom-tabs,
+.dijitTabContainerTop-tabs,
+.dijitTabContainerLeft-tabs,
+.dijitTabContainerRight-tabs {
+	overflow: visible !important;  /* so tabs can cover up border adjacent to container */
+}
+
+.dijitTabContainerBottom-container,
+.dijitTabContainerTop-container,
+.dijitTabContainerLeft-container,
+.dijitTabContainerRight-container {
+	z-index:0;
+	overflow: hidden;
+	border: 1px solid black;
+}
+.dijitTabContainer .nowrapTabStrip {
+	width: 50000px;
+	display: block;
+	position: relative;
+}
+.dijitTabContainer .dijitTabListWrapper {
+	overflow: hidden;
+}
+
+.dijit_a11y .dijitTabContainer .tabStripButton img {
+	/* hide the icons (or rather the empty space where they normally appear) because text will appear instead */
+	display: none;
+}
+
+.dijitTabContainerTop-tabs {
+	border-bottom: 1px solid black;
+}
+.dijitTabContainerTop-container {
+	border-top: 0px;
+}
+
+.dijitTabContainerLeft-tabs {
+	border-right: 1px solid black;
+	float: left;
+}
+.dijitTabContainerLeft-container {
+	border-left: 0px;
+}
+
+.dijitTabContainerBottom-tabs {
+	border-top: 1px solid black;
+}
+.dijitTabContainerBottom-container {
+	border-bottom: 0px;
+}
+
+.dijitTabContainerRight-tabs {
+	border-left: 1px solid black;
+	float: left;
+}
+.dijitTabContainerRight-container {
+	border-right: 0px;
+}
+
+div.dijitTabBtnDisabled, .dj_ie div.dijitTabBtnDisabled {
+	cursor: auto;
+}
+/*
+div.dijitTabBtnDisabled img {
+	opacity: 0.3;
+}
+
+
+.dj_ie div.dijitTabBtnDisabled img {
+	filter: gray() alpha(opacity=30);
+}
+*/
+.dijitTab {
+	position:relative;
+	cursor:pointer;
+	white-space:nowrap;
+	z-index:3;
+}
+.dijitTab * {
+	/* make tab icons and close icon line up w/text */
+	vertical-align: middle;
+}
+.dijitTabChecked {
+	cursor: default;	/* because clicking will have no effect */
+}
+
+.dijitTabButtonIcon {
+	height: 18px;
+}
+
+.dijitTabContainerTop-tabs .dijitTab {
+	top: 1px;	/* to overlap border on .dijitTabContainerTop-tabs */
+}
+.dijitTabContainerBottom-tabs .dijitTab {
+	top: -1px;	/* to overlap border on .dijitTabContainerBottom-tabs */
+}
+.dijitTabContainerLeft-tabs .dijitTab {
+	left: 1px;	/* to overlap border on .dijitTabContainerLeft-tabs */
+}
+.dijitTabContainerRight-tabs .dijitTab {
+	left: -1px;	/* to overlap border on .dijitTabContainerRight-tabs */
+}
+
+
+.dijitTabContainerTop-tabs .dijitTab,
+.dijitTabContainerBottom-tabs .dijitTab {
+	/* Inline-block */
+	display:inline-block;			/* webkit and FF3 */
+	#zoom: 1; /* set hasLayout:true to mimic inline-block */
+	#display:inline; /* don't use .dj_ie since that increases the priority */
+}
+
+.dijitTabInnerDiv {
+	position:relative;
+}
+
+
+.tabStripButton {
+	z-index: 12;
+}
+
+.dijitTabButtonDisabled .tabStripButton {
+	display: none;
+}
+
+
+.dijitTab .closeButton {
+	margin-left: 1em;
+}
+
+/* images off, high-contrast mode styles */
+.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 {
+	/* children of TabContainer, StackContainer, and AccordionContainer shouldn't have borders
+	 * b/c a border is already there from the TabContainer/StackContainer/AccordionContainer itself.
+	 */
+    border: none !important;
+}
+
+.dijitInlineEditor {
+	/* span around an inline-editable value when in edit mode */
+	position:relative;
+	vertical-align:bottom;
+}
+.dj_ie .dijitInlineEditor {
+	vertical-align:middle;
+}
+
+.dijitInlineValue {
+	/* span around an inline-editable value when NOT in edit mode */
+}
+
+.dijitInlineEditor .dijitButtonContainer {
+	/* div around the buttons -- makes them float below the field */
+	position:absolute;
+	right:0;
+	overflow:visible;
+}
+
+.dijitInlineEditor .saveButton,
+.dijitInlineEditor .cancelButton {
+}
+
+/* Tree */
+
+.dijitTreeIndent {
+	/* amount to indent each tree node (relative to parent node) */
+	width: 19px;
+}
+
+.dijitTreeRow, .dijitTreeContent {
+	white-space: nowrap;
+}
+
+.dijitTreeRow img {
+	/* make the expando and folder icons line up with the label */
+	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;
+}
+
+/* Dialog */
+
+.dijitDialog {
+	position: absolute;
+	z-index: 999;
+	padding: 1px;
+	overflow: hidden;       /* override overflow: auto; from ContentPane to make dragging smoother */
+}
+
+.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);
+}
+
+/* images off, high-contrast mode styles */
+.dijit_a11y .dijitInputLayoutContainer,
+.dijit_a11y .dijitDialog {
+	opacity: 1 !important;
+	background-color: white !important;
+}
+
+.dijitDialog .closeText {
+	display:none;
+	/* for the onhover border in high contrast on IE: */
+	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;
+}
+
+/* the slider bumper is the space consumed by the slider handle when it hangs over an edge */
+.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; /* mozilla bug workaround for float:left,height:100% block elements */
+}
+
+.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;
+}
+
+/* Icon-only buttons (often in toolbars) still display the text in high-contrast mode */
+.dijit_a11y .dijitButtonContents .dijitButtonText,
+.dijit_a11y .dijitTab .tabLabel {
+	display: inline !important;
+}
+.dj_ie7 .dijitButtonNode > BUTTON.dijitButtonContents > * {
+	position: relative; /* workaround for IE7 distorted text on scroll */
+}
+
+.dijitTextArea {
+	width:100%;
+	overflow-y: auto;	/* w/out this IE's SimpleTextArea goes to overflow: scroll */
+}
+.dijitTextArea[cols] {
+	width:auto; /* SimpleTextArea cols */
+}
+.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;
+}
+
+/* Editor */
+.dijitIEFixedToolbar {
+	position:absolute;
+	/* top:0; */
+	top: expression(eval((document.documentElement||document.body).scrollTop));
+}
+
+.RichTextEditable {
+	display: block;	/* prevents glitch on FF with InlineEditBox, see #8404 */
+}
+
+/* TimePicker */
+
+.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;
+}
+
+
+/* Disable the high contrast character */
+.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;
+}
+
+/* Select */
+.dijitSelect {
+	margin: 0.2em;
+}
+.dj_ie .dijitSelect,
+.dj_ie7 .dijitSelect,
+.dj_iequirks .dijitSelect {
+	vertical-align: middle; /* Set this back for what we hack in dijit inline */
+}
+.dj_ie8 .dijitSelect .dijitButtonText {
+	vertical-align: top;
+}
+.dijitSelect .dijitButtonNode {
+	text-align: left;
+}
+.dijitRtl .dijitSelect .dijitButtonNode {
+	text-align: right;
+}
+.dijitToolbar .dijitSelect {
+	margin: 0;
+}
+.dj_webkit .dijitToolbar .dijitSelect {
+	padding-left: 0.3em;
+}
+.dijit_a11y .dijitSelectDisabled .dijitButtonNode {
+	border-style: outset!important;
+	border-width: medium!important;
+	border-color: #999 !important;
+	color:#999 !important;
+}
+.dijitSelect .dijitButtonContents {
+	padding: 0px;
+	background: transparent none;
+}
+.dijitSelectFixedWidth .dijitButtonContents {
+	width: 100%;
+}
+.dijitSelect .dijitArrowButton {
+	width: 16px;
+}
+
+.dj_ie6 .dijitSelectMenu .dijitMenuItemLabel,
+.dj_ie7 .dijitSelectMenu .dijitMenuItemLabel {
+	/* Set back to static due to bug in ie6/ie7 - See Bug #9651 */
+	position: static;
+}
+
+/* Fix the baseline of our label (for multi-size font elements) */
+.dijitSelectLabel *
+{
+	vertical-align: baseline;
+}
+
+/* Styling for the currently-selected option (rich text can mess this up) */
+.dijitSelectSelectedOption * {
+	font-weight: bold;
+}
+
+/* Fix the styling of the dropdown menu to be more combobox-like */
+.dijitSelectMenu {
+	border-width: 1px;
+}
+
+/* Style the different areas of the button to look like a "real" dropdown */
+.dijitSelect .dijitButtonContents {
+	white-space: nowrap;
+}
+
+/* Remove margins on the sub-table */
+.dijitSelectMenu .dijitMenuTable {
+	margin: 0px;
+	background-color: transparent;
+}
+
+/* basic readonly/disabled text color rules for form widgets */
+.dijitTextBoxReadOnly,
+.dijitComboBoxReadOnly,
+.dijitSpinnerReadOnly,
+.dijitTextAreaReadOnly,
+.dijitTextBoxDisabled,
+.dijitComboBoxDisabled,
+.dijitSpinnerDisabled,
+.dijitTextAreaDisabled {
+	color: gray;
+}
+.dj_webkit .dijitTextBoxDisabled INPUT,
+.dj_webkit .dijitComboBoxDisabled INPUT,
+.dj_webkit .dijitSpinnerDisabled INPUT {
+	color: #eee;
+}
+.dj_webkit INPUT.dijitTextBoxDisabled,
+.dj_webkit TEXTAREA.dijitTextAreaDisabled {
+	color: #333; /* because WebKit lightens disabled input/textarea no matter what color you specify */
+}
+
+.dijit_a11y .dijitSliderReadOnly,
+.dijit_a11y .dijitSliderDisabled {
+	opacity:0.6;
+}
+.dj_ie .dijit_a11y .dijitSliderReadOnly .dijitSliderBar,
+.dj_ie .dijit_a11y .dijitSliderDisabled .dijitSliderBar {
+	filter: alpha(opacity=40);
+}
+
+/* + and - Slider buttons: undo themed image values */
+.dijit_a11y .dijitSlider .dijitSliderButtonContainer DIV {
+	font-family: monospace; /* hypen is larger and more vertically centered */
+	font-size: 1em;
+	line-height: 1em;
+	height: auto;
+	width: auto;
+	margin: 0px 4px;
+}
+
+
+.dijitForceStatic {
+    position: static !important;
+}
+
new file mode 100644
--- /dev/null
+++ b/client/dojo/dojo.js
@@ -0,0 +1,30707 @@
+/**
+ * @license RequireJS Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT, GPL or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+//laxbreak is true to allow build pragmas to change some statements.
+/*jslint plusplus: false, laxbreak: true */
+/*global window: false, document: false, navigator: false,
+setTimeout: false, traceDeps: true, clearInterval: false, self: false,
+setInterval: false */
+
+
+var require;
+(function () {
+    //Change this version number for each release.
+    var version = "0.8.0",
+            empty = {}, s,
+            i, defContextName = "_", contextLoads = [],
+            scripts, script, rePkg, src, m, cfg, setReadyState,
+            readyRegExp = /^(complete|loaded)$/,
+            isBrowser = !!(typeof window !== "undefined" && navigator && document),
+            ostring = Object.prototype.toString, scrollIntervalId;
+
+    function isFunction(it) {
+        return ostring.call(it) === "[object Function]";
+    }
+
+    //Check for an existing version of require. If so, then exit out. Only allow
+    //one version of require to be active in a page. However, allow for a require
+    //config object, just exit quickly if require is an actual function.
+    if (typeof require !== "undefined") {
+        if (isFunction(require)) {
+            return;
+        } else {
+            //assume it is a config object.
+            cfg = require;
+        }
+    }
+
+        function makeContextFunc(name, contextName, force) {
+        return function () {
+            //A version of a require function that uses the current context.
+            //If last arg is a string, then it is a context.
+            //If last arg is not a string, then add context to it.
+            var args = [].concat(Array.prototype.slice.call(arguments, 0));
+            if (force || typeof arguments[arguments.length - 1] !== "string") {
+                args.push(contextName);
+            }
+            return (name ? require[name] : require).apply(null, args);
+        };
+    }
+        
+        /**
+     * Calls a method on a plugin. The obj object should have two property,
+     * name: the name of the method to call on the plugin
+     * args: the arguments to pass to the plugin method.
+     */
+    function callPlugin(prefix, context, obj) {
+        //Call the plugin, or load it.
+        var plugin = s.plugins.defined[prefix], waiting;
+        if (plugin) {
+            plugin[obj.name].apply(null, obj.args);
+        } else {
+            //Put the call in the waiting call BEFORE requiring the module,
+            //since the require could be synchronous in some environments,
+            //like builds
+            waiting = s.plugins.waiting[prefix] || (s.plugins.waiting[prefix] = []);
+            waiting.push(obj);
+
+            //Load the module
+            context.defined.require(["require/" + prefix]);
+        }
+    }
+    
+    /**
+     * Main entry point.
+     *
+     * If the only argument to require is a string, then the module that
+     * is represented by that string is fetched for the appropriate context.
+     *
+     * If the first argument is an array, then it will be treated as an array
+     * of dependency string names to fetch. An optional function callback can
+     * be specified to execute when all of those dependencies are available.
+     */
+    require = function (deps, callback, contextName) {
+        if (typeof deps === "string" && !isFunction(callback)) {
+            //Just return the module wanted. In this scenario, the
+            //second arg (if passed) is just the contextName.
+            return require.get(deps, callback);
+        }
+
+        //Do more work, either 
+        return require.def.apply(require, arguments);
+    };
+
+    /**
+     * The function that handles definitions of modules. Differs from
+     * require() in that a string for the module should be the first argument,
+     * and the function to execute after dependencies are loaded should
+     * return a value to define the module corresponding to the first argument's
+     * name.
+     */
+    require.def = function (name, deps, callback, contextName) {
+        var config = null, context, newContext, contextRequire, loaded,
+            canSetContext, prop, newLength,
+            mods, pluginPrefix, paths, index;
+
+        //Normalize the arguments.
+        if (typeof name === "string") {
+            //Defining a module. First, pull off any plugin prefix.
+            index = name.indexOf("!");
+            if (index !== -1) {
+                pluginPrefix = name.substring(0, index);
+                name = name.substring(index + 1, name.length);
+            }
+
+            //Check if there are no dependencies, and adjust args.
+            if (!require.isArray(deps)) {
+                contextName = callback;
+                callback = deps;
+                deps = [];
+            }
+
+            contextName = contextName || s.ctxName;
+
+            //If module already defined for context, or already waiting to be
+            //evaluated, leave.
+            context = s.contexts[contextName];
+            if (context && (context.defined[name] || context.waiting[name])) {
+                return require;
+            }
+        } else if (require.isArray(name)) {
+            //Just some code that has dependencies. Adjust args accordingly.
+            contextName = callback;
+            callback = deps;
+            deps = name;
+            name = null;
+        } else if (require.isFunction(name)) {
+            //Just a function that does not define a module and
+            //does not have dependencies. Useful if just want to wait
+            //for whatever modules are in flight and execute some code after
+            //those modules load.
+            callback = name;
+            contextName = deps;
+            name = null;
+            deps = [];
+        } else {
+            //name is a config object.
+            config = name;
+            name = null;
+            //Adjust args if no dependencies.
+            if (require.isFunction(deps)) {
+                contextName = callback;
+                callback = deps;
+                deps = [];
+            }
+
+            contextName = contextName || config.context;
+        }
+
+        contextName = contextName || s.ctxName;
+
+                if (contextName !== s.ctxName) {
+            //If nothing is waiting on being loaded in the current context,
+            //then switch s.ctxName to current contextName.
+            loaded = (s.contexts[s.ctxName] && s.contexts[s.ctxName].loaded);
+            canSetContext = true;
+            if (loaded) {
+                for (prop in loaded) {
+                    if (!(prop in empty)) {
+                        if (!loaded[prop]) {
+                            canSetContext = false;
+                            break;
+                        }
+                    }
+                }
+            }
+            if (canSetContext) {
+                s.ctxName = contextName;
+            }
+        }
+        
+        //Grab the context, or create a new one for the given context name.
+        context = s.contexts[contextName];
+        if (!context) {
+            newContext = {
+                contextName: contextName,
+                config: {
+                    waitSeconds: 7,
+                    baseUrl: s.baseUrl || "./",
+                    paths: {}
+                },
+                waiting: [],
+                specified: {
+                    "require": true,
+                    "exports": true,
+                    "module": true
+                },
+                loaded: {
+                    "require": true
+                },
+                defined: {},
+                modifiers: {}
+            };
+
+            //Define require for this context.
+                                    newContext.defined.require = contextRequire = makeContextFunc(null, contextName);
+            require.mixin(contextRequire, {
+                                modify: makeContextFunc("modify", contextName),
+                def: makeContextFunc("def", contextName),
+                                get: makeContextFunc("get", contextName, true),
+                nameToUrl: makeContextFunc("nameToUrl", contextName, true),
+                ready: require.ready,
+                context: newContext,
+                config: newContext.config,
+                isBrowser: s.isBrowser
+            });
+            
+                        if (s.plugins.newContext) {
+                s.plugins.newContext(newContext);
+            }
+            
+            context = s.contexts[contextName] = newContext;
+        }
+
+        //If have a config object, update the context's config object with
+        //the config values.
+        if (config) {
+            //Make sure the baseUrl ends in a slash.
+            if (config.baseUrl) {
+                if (config.baseUrl.charAt(config.baseUrl.length - 1) !== "/") {
+                    config.baseUrl += "/";
+                }
+            }
+
+            //Save off the paths since they require special processing,
+            //they are additive.
+            paths = context.config.paths;
+
+            //Mix in the config values, favoring the new values over
+            //existing ones in context.config.
+            require.mixin(context.config, config, true);
+
+            //Adjust paths if necessary.
+            if (config.paths) {
+                for (prop in config.paths) {
+                    if (!(prop in empty)) {
+                        paths[prop] = config.paths[prop];
+                    }
+                }
+                context.config.paths = paths;
+            }
+
+            //If a deps array or a config callback is specified, then call
+            //require with those args. This is useful when require is defined as a
+            //config object before require.js is loaded.
+            if (config.deps || config.callback) {
+                require(config.deps || [], config.callback);
+            }
+
+                        //Set up ready callback, if asked. Useful when require is defined as a
+            //config object before require.js is loaded.
+            if (config.ready) {
+                require.ready(config.ready);
+            }
+            
+            //If it is just a config block, nothing else,
+            //then return.
+            if (!deps) {
+                return require;
+            }
+        }
+
+        //Store the module for later evaluation
+        newLength = context.waiting.push({
+            name: name,
+            deps: deps,
+            callback: callback
+        });
+
+        if (name) {
+            //Store index of insertion for quick lookup
+            context.waiting[name] = newLength - 1;
+
+            //Mark the module as specified: not loaded yet, but in the process,
+            //so no need to fetch it again. Important to do it here for the
+            //pause/resume case where there are multiple modules in a file.
+            context.specified[name] = true;
+
+                        //Load any modifiers for the module.
+            mods = context.modifiers[name];
+            if (mods) {
+                require(mods, contextName);
+            }
+                    }
+
+        //If the callback is not an actual function, it means it already
+        //has the definition of the module as a literal value.
+        if (name && callback && !require.isFunction(callback)) {
+            context.defined[name] = callback;
+        }
+
+        //If a pluginPrefix is available, call the plugin, or load it.
+                if (pluginPrefix) {
+            callPlugin(pluginPrefix, context, {
+                name: "require",
+                args: [name, deps, callback, context]
+            });
+        }
+        
+        //See if all is loaded. If paused, then do not check the dependencies
+        //of the module yet.
+        if (s.paused) {
+            s.paused.push([pluginPrefix, name, deps, context]);
+        } else {
+            require.checkDeps(pluginPrefix, name, deps, context);
+            require.checkLoaded(contextName);
+        }
+
+        return require;
+    };
+
+    /**
+     * Simple function to mix in properties from source into target,
+     * but only if target does not already have a property of the same name.
+     */
+    require.mixin = function (target, source, override) {
+        for (var prop in source) {
+            if (!(prop in empty) && (!(prop in target) || override)) {
+                target[prop] = source[prop];
+            }
+        }
+        return require;
+    };
+
+    require.version = version;
+
+    //Set up page state.
+    s = require.s = {
+        ctxName: defContextName,
+        contexts: {},
+                plugins: {
+            defined: {},
+            callbacks: {},
+            waiting: {}
+        },
+                isBrowser: isBrowser,
+        isPageLoaded: !isBrowser,
+        readyCalls: [],
+        doc: isBrowser ? document : null
+    };
+
+    require.isBrowser = s.isBrowser;
+    s.head = isBrowser ? document.getElementsByTagName("head")[0] : null;
+
+        /**
+     * Sets up a plugin callback name. Want to make it easy to test if a plugin
+     * needs to be called for a certain lifecycle event by testing for
+     * if (s.plugins.onLifeCyleEvent) so only define the lifecycle event
+     * if there is a real plugin that registers for it.
+     */
+    function makePluginCallback(name, returnOnTrue) {
+        var cbs = s.plugins.callbacks[name] = [];
+        s.plugins[name] = function () {
+            for (var i = 0, cb; (cb = cbs[i]); i++) {
+                if (cb.apply(null, arguments) === true && returnOnTrue) {
+                    return true;
+                }
+            }
+            return false;
+        };
+    }
+
+    /**
+     * Registers a new plugin for require.
+     */
+    require.plugin = function (obj) {
+        var i, prop, call, prefix = obj.prefix, cbs = s.plugins.callbacks,
+            waiting = s.plugins.waiting[prefix], generics,
+            defined = s.plugins.defined, contexts = s.contexts, context;
+
+        //Do not allow redefinition of a plugin, there may be internal
+        //state in the plugin that could be lost.
+        if (defined[prefix]) {
+            return require;
+        }
+
+        //Save the plugin.
+        defined[prefix] = obj;
+
+        //Set up plugin callbacks for methods that need to be generic to
+        //require, for lifecycle cases where it does not care about a particular
+        //plugin, but just that some plugin work needs to be done.
+        generics = ["newContext", "isWaiting", "orderDeps"];
+        for (i = 0; (prop = generics[i]); i++) {
+            if (!s.plugins[prop]) {
+                makePluginCallback(prop, prop === "isWaiting");
+            }
+            cbs[prop].push(obj[prop]);
+        }
+
+        //Call newContext for any contexts that were already created.
+        if (obj.newContext) {
+            for (prop in contexts) {
+                if (!(prop in empty)) {
+                    context = contexts[prop];
+                    obj.newContext(context);
+                }
+            }
+        }
+
+        //If there are waiting requests for a plugin, execute them now.
+        if (waiting) {
+            for (i = 0; (call = waiting[i]); i++) {
+                if (obj[call.name]) {
+                    obj[call.name].apply(null, call.args);
+                }
+            }
+            delete s.plugins.waiting[prefix];
+        }
+
+        return require;
+    };
+    
+    /**
+     * Pauses the tracing of dependencies. Useful in a build scenario when
+     * multiple modules are bundled into one file, and they all need to be
+     * require before figuring out what is left still to load.
+     */
+    require.pause = function () {
+        if (!s.paused) {
+            s.paused = [];
+        }
+    };
+
+    /**
+     * Resumes the tracing of dependencies. Useful in a build scenario when
+     * multiple modules are bundled into one file. This method is related
+     * to require.pause() and should only be called if require.pause() was called first.
+     */
+    require.resume = function () {
+        var i, args, paused;
+        if (s.paused) {
+            paused = s.paused;
+            delete s.paused;
+            for (i = 0; (args = paused[i]); i++) {
+                require.checkDeps.apply(require, args);
+            }
+        }
+        require.checkLoaded(s.ctxName);
+    };
+
+    /**
+     * Trace down the dependencies to see if they are loaded. If not, trigger
+     * the load.
+     * @param {String} pluginPrefix the plugin prefix, if any associated with the name.
+     *
+     * @param {String} name: the name of the module that has the dependencies.
+     *
+     * @param {Array} deps array of dependencies.
+     *
+     * @param {Object} context: the loading context.
+     *
+     * @private
+     */
+    require.checkDeps = function (pluginPrefix, name, deps, context) {
+        //Figure out if all the modules are loaded. If the module is not
+        //being loaded or already loaded, add it to the "to load" list,
+        //and request it to be loaded.
+        var i, dep, index, depPrefix;
+
+        if (pluginPrefix) {
+                        callPlugin(pluginPrefix, context, {
+                name: "checkDeps",
+                args: [name, deps, context]
+            });
+                    } else {
+            for (i = 0; (dep = deps[i]); i++) {
+                //If it is a string, then a plain dependency
+                if (typeof dep === "string") {
+                    if (!context.specified[dep]) {
+                        context.specified[dep] = true;
+
+                        //If a plugin, call its load method.
+                        index = dep.indexOf("!");
+                        if (index !== -1) {
+                                                        depPrefix = dep.substring(0, index);
+                            dep = dep.substring(index + 1, dep.length);
+
+                            callPlugin(depPrefix, context, {
+                                name: "load",
+                                args: [dep, context.contextName]
+                            });
+                                                    } else {
+                            require.load(dep, context.contextName);
+                        }
+                    }
+                } else {
+                    throw new Error("Unsupported non-string dependency: " + dep);
+                }
+            }
+        }
+    };
+
+        /**
+     * Register a module that modifies another module. The modifier will
+     * only be called once the target module has been loaded.
+     *
+     * First syntax:
+     *
+     * require.modify({
+     *     "some/target1": "my/modifier1",
+     *     "some/target2": "my/modifier2",
+     * });
+     *
+     * With this syntax, the my/modifier1 will only be loaded when
+     * "some/target1" is loaded.
+     *
+     * Second syntax, defining a modifier.
+     *
+     * require.modify("some/target1", "my/modifier",
+     *                        ["some/target1", "some/other"],
+     *                        function (target, other) {
+     *                            //Modify properties of target here.
+     *                            Only properties of target can be modified, but
+     *                            target cannot be replaced.
+     *                        }
+     * );
+     */
+    require.modify = function (target, name, deps, callback, contextName) {
+        var prop, modifier, list,
+                cName = (typeof target === "string" ? contextName : name) || s.ctxName,
+                context = s.contexts[cName],
+                mods = context.modifiers;
+
+        if (typeof target === "string") {
+            //A modifier module.
+            //First store that it is a modifier.
+            list = mods[target] || (mods[target] = []);
+            if (!list[name]) {
+                list.push(name);
+                list[name] = true;
+            }
+
+            //Trigger the normal module definition logic.
+            require.def(name, deps, callback, contextName);
+        } else {
+            //A list of modifiers. Save them for future reference.
+            for (prop in target) {
+                if (!(prop in empty)) {
+                    //Store the modifier for future use.
+                    modifier = target[prop];
+                    list = context.modifiers[prop] || (context.modifiers[prop] = []);
+                    if (!list[modifier]) {
+                        list.push(modifier);
+                        list[modifier] = true;
+
+                        if (context.specified[prop]) {
+                            //Load the modifier right away.
+                            require([modifier], cName);
+                        }
+                    }
+                }
+            }
+        }
+    };
+    
+    require.isArray = function (it) {
+        return ostring.call(it) === "[object Array]";
+    };
+
+    require.isFunction = isFunction;
+
+    /**
+     * Gets one module's exported value. This method is used by require().
+     * It is broken out as a separate function to allow a host environment
+     * shim to overwrite this function with something appropriate for that
+     * environment.
+     *
+     * @param {String} moduleName the name of the module.
+     * @param {String} [contextName] the name of the context to use. Uses
+     * default context if no contextName is provided.
+     *
+     * @returns {Object} the exported module value.
+     */
+    require.get = function (moduleName, contextName) {
+        if (moduleName === "exports" || moduleName === "module") {
+            throw new Error("require of " + moduleName + " is not allowed.");
+        }
+        contextName = contextName || s.ctxName;
+        var ret = s.contexts[contextName].defined[moduleName];
+        if (ret === undefined) {
+            throw new Error("require: module name '" +
+                            moduleName +
+                            "' has not been loaded yet for context: " +
+                            contextName);
+        }
+        return ret;
+    };
+
+    /**
+     * Makes the request to load a module. May be an async load depending on
+     * the environment and the circumstance of the load call. Override this
+     * method in a host environment shim to do something specific for that
+     * environment.
+     *
+     * @param {String} moduleName the name of the module.
+     * @param {String} contextName the name of the context to use.
+     */
+    require.load = function (moduleName, contextName) {
+        var context = s.contexts[contextName], url;
+        s.isDone = false;
+        context.loaded[moduleName] = false;
+                if (contextName !== s.ctxName) {
+            //Not in the right context now, hold on to it until
+            //the current context finishes all its loading.
+            contextLoads.push(arguments);
+        } else {
+                    //First derive the path name for the module.
+            url = require.nameToUrl(moduleName, null, contextName);
+            require.attach(url, contextName, moduleName);
+            context.startTime = (new Date()).getTime();
+                }
+            };
+
+    require.jsExtRegExp = /\.js$/;
+
+    /**
+     * Converts a module name to a file path.
+     */
+    require.nameToUrl = function (moduleName, ext, contextName) {
+        var paths, syms, i, parentModule, url,
+            config = s.contexts[contextName].config;
+
+        //If a colon is in the URL, it indicates a protocol is used and it is just
+        //an URL to a file, or if it starts with a slash or ends with .js, it is just a plain file.
+        //The slash is important for protocol-less URLs as well as full paths.
+        if (moduleName.indexOf(":") !== -1 || moduleName.charAt(0) === '/' || require.jsExtRegExp.test(moduleName)) {
+            //Just a plain path, not module name lookup, so just return it.
+            return moduleName;
+        } else {
+            //A module that needs to be converted to a path.
+            paths = config.paths;
+
+            syms = moduleName.split("/");
+            //For each module name segment, see if there is a path
+            //registered for it. Start with most specific name
+            //and work up from it.
+            for (i = syms.length; i > 0; i--) {
+                parentModule = syms.slice(0, i).join("/");
+                if (paths[parentModule]) {
+                    syms.splice(0, i, paths[parentModule]);
+                    break;
+                }
+            }
+
+            //Join the path parts together, then figure out if baseUrl is needed.
+            url = syms.join("/") + (ext || ".js");
+            return ((url.charAt(0) === '/' || url.match(/^\w+:/)) ? "" : config.baseUrl) + url;
+        }
+    };
+
+    /**
+     * Checks if all modules for a context are loaded, and if so, evaluates the
+     * new ones in right dependency order.
+     *
+     * @private
+     */
+    require.checkLoaded = function (contextName) {
+        var context = s.contexts[contextName || s.ctxName],
+                waitInterval = context.config.waitSeconds * 1000,
+                //It is possible to disable the wait interval by using waitSeconds of 0.
+                expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(),
+                loaded = context.loaded, defined = context.defined,
+                modifiers = context.modifiers, waiting = context.waiting, noLoads = "",
+                hasLoadedProp = false, stillLoading = false, prop,
+
+                                pIsWaiting = s.plugins.isWaiting, pOrderDeps = s.plugins.orderDeps,
+                
+                i, module, allDone, loads, loadArgs,
+                traced = {};
+
+        //If already doing a checkLoaded call,
+        //then do not bother checking loaded state.
+        if (context.isCheckLoaded) {
+            return;
+        }
+
+        //Signal that checkLoaded is being require, so other calls that could be triggered
+        //by calling a waiting callback that then calls require and then this function
+        //should not proceed. At the end of this function, if there are still things
+        //waiting, then checkLoaded will be called again.
+        context.isCheckLoaded = true;
+
+        //See if anything is still in flight.
+        for (prop in loaded) {
+            if (!(prop in empty)) {
+                hasLoadedProp = true;
+                if (!loaded[prop]) {
+                    if (expired) {
+                        noLoads += prop + " ";
+                    } else {
+                        stillLoading = true;
+                        break;
+                    }
+                }
+            }
+        }
+
+        //Check for exit conditions.
+        if (!hasLoadedProp && !waiting.length
+                        && (!pIsWaiting || !pIsWaiting(context))
+                       ) {
+            //If the loaded object had no items, then the rest of
+            //the work below does not need to be done.
+            context.isCheckLoaded = false;
+            return;
+        }
+        if (expired && noLoads) {
+            //If wait time expired, throw error of unloaded modules.
+            throw new Error("require.js load timeout for modules: " + noLoads);
+        }
+        if (stillLoading) {
+            //Something is still waiting to load. Wait for it.
+            context.isCheckLoaded = false;
+            if (require.isBrowser) {
+                setTimeout(function () {
+                    require.checkLoaded(contextName);
+                }, 50);
+            }
+            return;
+        }
+
+        //Order the dependencies. Also clean up state because the evaluation
+        //of modules might create new loading tasks, so need to reset.
+        //Be sure to call plugins too.
+        context.waiting = [];
+        context.loaded = {};
+
+                //Call plugins to order their dependencies, do their
+        //module definitions.
+        if (pOrderDeps) {
+            pOrderDeps(context);
+        }
+        
+                //Before defining the modules, give priority treatment to any modifiers
+        //for modules that are already defined.
+        for (prop in modifiers) {
+            if (!(prop in empty)) {
+                if (defined[prop]) {
+                    require.execModifiers(prop, traced, waiting, context);
+                }
+            }
+        }
+        
+        //Define the modules, doing a depth first search.
+        for (i = 0; (module = waiting[i]); i++) {
+            require.exec(module, traced, waiting, context);
+        }
+
+        //Indicate checkLoaded is now done.
+        context.isCheckLoaded = false;
+
+        if (context.waiting.length
+                        || (pIsWaiting && pIsWaiting(context))
+                       ) {
+            //More things in this context are waiting to load. They were probably
+            //added while doing the work above in checkLoaded, calling module
+            //callbacks that triggered other require calls.
+            require.checkLoaded(contextName);
+        } else if (contextLoads.length) {
+                        //Check for other contexts that need to load things.
+            //First, make sure current context has no more things to
+            //load. After defining the modules above, new require calls
+            //could have been made.
+            loaded = context.loaded;
+            allDone = true;
+            for (prop in loaded) {
+                if (!(prop in empty)) {
+                    if (!loaded[prop]) {
+                        allDone = false;
+                        break;
+                    }
+                }
+            }
+
+            if (allDone) {
+                s.ctxName = contextLoads[0][1];
+                loads = contextLoads;
+                //Reset contextLoads in case some of the waiting loads
+                //are for yet another context.
+                contextLoads = [];
+                for (i = 0; (loadArgs = loads[i]); i++) {
+                    require.load.apply(require, loadArgs);
+                }
+            }
+                    } else {
+            //Make sure we reset to default context.
+            s.ctxName = defContextName;
+            s.isDone = true;
+            if (require.callReady) {
+                require.callReady();
+            }
+        }
+    };
+
+    /**
+     * Executes the modules in the correct order.
+     * 
+     * @private
+     */
+    require.exec = function (module, traced, waiting, context) {
+        //Some modules are just plain script files, abddo not have a formal
+        //module definition, 
+        if (!module) {
+            return undefined;
+        }
+
+        var name = module.name, cb = module.callback, deps = module.deps, j, dep,
+            defined = context.defined, ret, args = [], prefix, depModule,
+            usingExports = false;
+
+        //If already traced or defined, do not bother a second time.
+        if (name) {
+            if (traced[name] || defined[name]) {
+                return defined[name];
+            }
+    
+            //Mark this module as being traced, so that it is not retraced (as in a circular
+            //dependency)
+            traced[name] = true;
+        }
+
+        if (deps) {
+            for (j = 0; (dep = deps[j]); j++) {
+                //Adjust dependency for plugins.
+                prefix = dep.indexOf("!");
+                if (prefix !== -1) {
+                    dep = dep.substring(prefix + 1, dep.length);
+                }
+
+                if (dep === "exports") {
+                    //CommonJS module spec 1.1
+                    depModule = defined[name] = {};
+                    usingExports = true;
+                } else if (dep === "module") {
+                    //CommonJS module spec 1.1
+                    depModule = {
+                        id: name,
+                        uri: name ? require.nameToUrl(name, null, context.contextName) : undefined
+                    };
+                } else {
+                    //Get dependent module. It could not exist, for a circular
+                    //dependency or if the loaded dependency does not actually call
+                    //require. Favor not throwing an error here if undefined because
+                    //we want to allow code that does not use require as a module
+                    //definition framework to still work -- allow a web site to
+                    //gradually update to contained modules. That is seen as more
+                    //important than forcing a throw for the circular dependency case.
+                    depModule = dep in defined ? defined[dep] : (traced[dep] ? undefined : require.exec(waiting[waiting[dep]], traced, waiting, context));
+                }
+
+                args.push(depModule);
+            }
+        }
+
+        //Call the callback to define the module, if necessary.
+        cb = module.callback;
+        if (cb && require.isFunction(cb)) {
+            ret = require.execCb(name, cb, args);
+            if (name) {
+                if (usingExports) {
+                    ret = defined[name];
+                } else {
+                    if (name in defined) {
+                        throw new Error(name + " has already been defined");
+                    } else {
+                        defined[name] = ret;
+                    }
+                }
+            }
+        }
+
+                //Execute modifiers, if they exist.
+        require.execModifiers(name, traced, waiting, context);
+        
+        return ret;
+    };
+
+    /**
+     * Executes a module callack function. Broken out as a separate function
+     * solely to allow the build system to sequence the files in the built
+     * layer in the right sequence.
+     * @param {String} name the module name.
+     * @param {Function} cb the module callback/definition function.
+     * @param {Array} args The arguments (dependent modules) to pass to callback.
+     *
+     * @private
+     */
+    require.execCb = function (name, cb, args) {
+        return cb.apply(null, args);
+    };
+
+        /**
+     * Executes modifiers for the given module name.
+     * @param {String} target
+     * @param {Object} traced
+     * @param {Object} context
+     *
+     * @private
+     */
+    require.execModifiers = function (target, traced, waiting, context) {
+        var modifiers = context.modifiers, mods = modifiers[target], mod, i;
+        if (mods) {
+            for (i = 0; i < mods.length; i++) {
+                mod = mods[i];
+                //Not all modifiers define a module, they might collect other modules.
+                //If it is just a collection it will not be in waiting.
+                if (mod in waiting) {
+                    require.exec(waiting[waiting[mod]], traced, waiting, context);
+                }
+            }
+            delete modifiers[target];
+        }
+    };
+    
+    /**
+     * callback for script loads, used to check status of loading.
+     *
+     * @param {Event} evt the event from the browser for the script
+     * that was loaded.
+     *
+     * @private
+     */
+    require.onScriptLoad = function (evt) {
+        var node = evt.target || evt.srcElement, contextName, moduleName;
+        if (evt.type === "load" || readyRegExp.test(node.readyState)) {
+            //Pull out the name of the module and the context.
+            contextName = node.getAttribute("data-requirecontext");
+            moduleName = node.getAttribute("data-requiremodule");
+
+            //Mark the module loaded.
+            s.contexts[contextName].loaded[moduleName] = true;
+
+            require.checkLoaded(contextName);
+
+            //Clean up script binding.
+            if (node.removeEventListener) {
+                node.removeEventListener("load", require.onScriptLoad, false);
+            } else {
+                //Probably IE.
+                node.detachEvent("onreadystatechange", require.onScriptLoad);
+            }
+        }
+    };
+
+    /**
+     * Attaches the script represented by the URL to the current
+     * environment. Right now only supports browser loading,
+     * but can be redefined in other environments to do the right thing.
+     */
+    require.attach = function (url, contextName, moduleName) {
+        if (require.isBrowser) {
+            var node = document.createElement("script");
+            node.type = "text/javascript";
+            node.charset = "utf-8";
+            node.setAttribute("data-requirecontext", contextName);
+            node.setAttribute("data-requiremodule", moduleName);
+    
+            //Set up load listener.
+            if (node.addEventListener) {
+                node.addEventListener("load", require.onScriptLoad, false);
+            } else {
+                //Probably IE.
+                node.attachEvent("onreadystatechange", require.onScriptLoad);
+            }
+            node.src = url;
+
+            return s.head.appendChild(node);
+        }
+        return null;
+    };
+
+    //Determine what baseUrl should be if not already defined via a require config object
+    s.baseUrl = cfg && cfg.baseUrl;
+    if (require.isBrowser && (!s.baseUrl || !s.head)) {
+        //Figure out baseUrl. Get it from the script tag with require.js in it.
+        scripts = document.getElementsByTagName("script");
+        if (cfg && cfg.baseUrlMatch) {
+            rePkg = cfg.baseUrlMatch;
+        } else {
+            
+                        rePkg = /dojo\.js(\W|$)/i;
+            
+                    }
+
+        for (i = scripts.length - 1; i > -1 && (script = scripts[i]); i--) {
+            //Set the "head" where we can append children by
+            //using the script's parent.
+            if (!s.head) {
+                s.head = script.parentNode;
+            }
+            //Using .src instead of getAttribute to get an absolute URL.
+            //While using a relative URL will be fine for script tags, other
+            //URLs used for text! resources that use XHR calls might benefit
+            //from an absolute URL.
+            src = script.src;
+            if (src) {
+                m = src.match(rePkg);
+                if (m) {
+                    s.baseUrl = src.substring(0, m.index);
+                    break;
+                }
+            }
+        }
+    }
+
+        //****** START page load functionality ****************
+    /**
+     * Sets the page as loaded and triggers check for all modules loaded.
+     */
+    require.pageLoaded = function () {
+        if (!s.isPageLoaded) {
+            s.isPageLoaded = true;
+            if (scrollIntervalId) {
+                clearInterval(scrollIntervalId);
+            }
+
+            //Part of a fix for FF < 3.6 where readyState was not set to
+            //complete so libraries like jQuery that check for readyState
+            //after page load where not getting initialized correctly.
+            //Original approach suggested by Andrea Giammarchi:
+            //http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html
+            //see other setReadyState reference for the rest of the fix.
+            if (setReadyState) {
+                document.readyState = "complete";
+            }
+
+            require.callReady();
+        }
+    };
+
+    /**
+     * Internal function that calls back any ready functions. If you are
+     * integrating RequireJS with another library without require.ready support,
+     * you can define this method to call your page ready code instead.
+     */
+    require.callReady = function () {
+        var callbacks = s.readyCalls, i, callback;
+
+        if (s.isPageLoaded && s.isDone && callbacks.length) {
+            s.readyCalls = [];
+            for (i = 0; (callback = callbacks[i]); i++) {
+                callback();
+            }
+        }
+    };
+
+    /**
+     * Registers functions to call when the page is loaded
+     */
+    require.ready = function (callback) {
+        if (s.isPageLoaded && s.isDone) {
+            callback();
+        } else {
+            s.readyCalls.push(callback);
+        }
+        return require;
+    };
+
+    if (require.isBrowser) {
+        if (document.addEventListener) {
+            //Standards. Hooray! Assumption here that if standards based,
+            //it knows about DOMContentLoaded.
+            document.addEventListener("DOMContentLoaded", require.pageLoaded, false);
+            window.addEventListener("load", require.pageLoaded, false);
+            //Part of FF < 3.6 readystate fix (see setReadyState refs for more info)
+            if (!document.readyState) {
+                setReadyState = true;
+                document.readyState = "loading";
+            }
+        } else if (window.attachEvent) {
+            window.attachEvent("onload", require.pageLoaded);
+
+            //DOMContentLoaded approximation, as found by Diego Perini:
+            //http://javascript.nwbox.com/IEContentLoaded/
+            if (self === self.top) {
+                scrollIntervalId = setInterval(function () {
+                    try {
+                        document.documentElement.doScroll("left");
+                        require.pageLoaded();
+                    } catch (e) {}
+                }, 30);
+            }
+        }
+
+        //Check if document already complete, and if so, just trigger page load
+        //listeners. NOTE: does not work with Firefox before 3.6. To support
+        //those browsers, manually call require.pageLoaded().
+        if (document.readyState === "complete") {
+            require.pageLoaded();
+        }
+    }
+    //****** END page load functionality ****************
+    
+    //Set up default context. If require was a configuration object, use that as base config.
+    if (cfg) {
+        require(cfg);
+    }
+}());
+require.pause();
+
+/**
+ * @license RequireJS text Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT, GPL or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+/*jslint regexp: false, nomen: false, plusplus: false */
+/*global require: false, XMLHttpRequest: false, ActiveXObject: false */
+
+
+(function () {
+    var progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'],
+        xmlRegExp = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,
+        bodyRegExp = /<body[^>]*>\s*([\s\S]+)\s*<\/body>/im;
+
+    if (!require.textStrip) {
+        require.textStrip = function (text) {
+            //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 (text) {
+                text = text.replace(xmlRegExp, "");
+                var matches = text.match(bodyRegExp);
+                if (matches) {
+                    text = matches[1];
+                }
+            } else {
+                text = "";
+            }
+            return text;
+        };
+    }
+
+    //Upgrade require to add some methods for XHR handling. But it could be that
+    //this require is used in a non-browser env, so detect for existing method
+    //before attaching one.
+    if (!require.getXhr) {
+        require.getXhr = function () {
+            //Would love to dump the ActiveX crap in here. Need IE 6 to die first.
+            var xhr, i, progId;
+            if (typeof XMLHttpRequest !== "undefined") {
+                return new XMLHttpRequest();
+            } else {
+                for (i = 0; i < 3; i++) {
+                    progId = progIds[i];
+                    try {
+                        xhr = new ActiveXObject(progId);
+                    } catch (e) {}
+
+                    if (xhr) {
+                        progIds = [progId];  // so faster next time
+                        break;
+                    }
+                }   
+            }
+
+            if (!xhr) {
+                throw new Error("require.getXhr(): XMLHttpRequest not available");
+            }
+
+            return xhr;
+        };
+    }
+    
+    if (!require.fetchText) {
+        require.fetchText = function (url, callback) {
+            var xhr = require.getXhr();
+            xhr.open('GET', url, true);
+            xhr.onreadystatechange = function (evt) {
+                //Do not explicitly handle errors, those should be
+                //visible via console output in the browser.
+                if (xhr.readyState === 4) {
+                    callback(xhr.responseText);
+                }
+            };
+            xhr.send(null);
+        };
+    }
+
+    require.plugin({
+        prefix: "text",
+
+        /**
+         * This callback is prefix-specific, only gets called for this prefix
+         */
+        require: function (name, deps, callback, context) {
+            //No-op, require never gets these text items, they are always
+            //a dependency, see load for the action.
+        },
+
+        /**
+         * Called when a new context is defined. Use this to store
+         * context-specific info on it.
+         */
+        newContext: function (context) {
+            require.mixin(context, {
+                text: {},
+                textWaiting: []
+            });
+        },
+
+        /**
+         * Called when a dependency needs to be loaded.
+         */
+        load: function (name, contextName) {
+            //Name has format: some.module!filext!strip!text
+            //The strip and text parts are optional.
+            //if strip is present, then that means only get the string contents
+            //inside a body tag in an HTML string. For XML/SVG content it means
+            //removing the <?xml ...?> declarations so the content can be inserted
+            //into the current doc without problems.
+            //If text is present, it is the actual text of the file.
+            var strip = false, text = null, key, url, index = name.indexOf("!"),
+                modName = name.substring(0, index), fullKey,
+                ext = name.substring(index + 1, name.length),
+                context = require.s.contexts[contextName],
+                tWaitAry = context.textWaiting;
+
+            index = ext.indexOf("!");
+            if (index !== -1) {
+                //Pull off the strip arg.
+                strip = ext.substring(index + 1, ext.length);
+                ext = ext.substring(0, index);
+                index = strip.indexOf("!");
+                if (index !== -1 && strip.substring(0, index) === "strip") {
+                    //Pul off the text.
+                    text = strip.substring(index + 1, strip.length);
+                    strip = "strip";
+                } else if (strip !== "strip") {
+                    //strip is actually the inlined text.
+                    text = strip;
+                    strip = null;
+                }
+            }
+            key = modName + "!" + ext;
+            fullKey = strip ? key + "!" + strip : key;
+
+            //Store off text if it is available for the given key and be done.
+            if (text !== null && !context.text[key]) {
+                context.defined[name] = context.text[key] = text;
+                return;
+            }
+
+            //If text is not available, load it.
+            if (!context.text[key] && !context.textWaiting[key] && !context.textWaiting[fullKey]) {
+                //Keep track that the fullKey needs to be resolved, during the
+                //orderDeps stage.
+                if (!tWaitAry[fullKey]) {
+                    tWaitAry[fullKey] = tWaitAry[(tWaitAry.push({
+                        name: name,
+                        key: key,
+                        fullKey: fullKey,
+                        strip: !!strip
+                    }) - 1)];
+                }
+
+                //Load the text.
+                url = require.nameToUrl(modName, "." + ext, contextName);
+                context.loaded[name] = false;
+                require.fetchText(url, function (text) {
+                    context.text[key] = text;
+                    context.loaded[name] = true;
+                    require.checkLoaded(contextName);                    
+                });
+            }
+        },
+
+        /**
+         * Called when the dependencies of a module are checked.
+         */
+        checkDeps: function (name, deps, context) {
+            //No-op, checkDeps never gets these text items, they are always
+            //a dependency, see load for the action.
+        },
+
+        /**
+         * Called to determine if a module is waiting to load.
+         */
+        isWaiting: function (context) {
+            return !!context.textWaiting.length;
+        },
+
+        /**
+         * Called when all modules have been loaded.
+         */
+        orderDeps: function (context) {
+            //Clear up state since further processing could
+            //add more things to fetch.
+            var i, dep, text, tWaitAry = context.textWaiting;
+            context.textWaiting = [];
+            for (i = 0; (dep = tWaitAry[i]); i++) {
+                text = context.text[dep.key];
+                context.defined[dep.name] = dep.strip ? require.textStrip(text) : text;
+            }
+        }
+    });
+}());
+/**
+ * @license RequireJS i18n Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT, GPL or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+/*jslint regexp: false, nomen: false, plusplus: false */
+/*global require: false, navigator: false */
+
+
+/**
+ * This plugin handles i18n! prefixed modules. It does the following:
+ *
+ * 1) A regular module can have a dependency on an i18n bundle, but the regular
+ * module does not want to specify what locale to load. So it just specifies
+ * the top-level bundle, like "i18n!nls/colors".
+ *
+ * This plugin will load the i18n bundle at nls/colors, see that it is a root/master
+ * bundle since it does not have a locale in its name. It will then try to find
+ * the best match locale available in that master bundle, then request all the
+ * locale pieces for that best match locale. For instance, if the locale is "en-us",
+ * then the plugin will ask for the "en-us", "en" and "root" bundles to be loaded
+ * (but only if they are specified on the master bundle).
+ *
+ * Once all the bundles for the locale pieces load, then it mixes in all those
+ * locale pieces into each other, then finally sets the context.defined value
+ * for the nls/colors bundle to be that mixed in locale.
+ *
+ * 2) A regular module specifies a specific locale to load. For instance,
+ * i18n!nls/fr-fr/colors. In this case, the plugin needs to load the master bundle
+ * first, at nls/colors, then figure out what the best match locale is for fr-fr,
+ * since maybe only fr or just root is defined for that locale. Once that best
+ * fit is found, all of its locale pieces need to have their bundles loaded.
+ *
+ * Once all the bundles for the locale pieces load, then it mixes in all those
+ * locale pieces into each other, then finally sets the context.defined value
+ * for the nls/fr-fr/colors bundle to be that mixed in locale.
+ */
+(function () {
+    //regexp for reconstructing the master bundle name from parts of the regexp match
+    //nlsRegExp.exec("foo/bar/baz/nls/en-ca/foo") gives:
+    //["foo/bar/baz/nls/en-ca/foo", "foo/bar/baz/nls/", "/", "/", "en-ca", "foo"]
+    //nlsRegExp.exec("foo/bar/baz/nls/foo") gives:
+    //["foo/bar/baz/nls/foo", "foo/bar/baz/nls/", "/", "/", "foo", ""]
+    //so, if match[5] is blank, it means this is the top bundle definition.
+    var nlsRegExp = /(^.*(^|\/)nls(\/|$))([^\/]*)\/?([^\/]*)/,
+        empty = {};
+
+    function getWaiting(name, context) {
+        var nlswAry = context.nlsWaiting;
+        return nlswAry[name] ||
+               //Push a new waiting object on the nlsWaiting array, but also put
+               //a shortcut lookup by name to the object on the array.
+               (nlswAry[name] = nlswAry[(nlswAry.push({ _name: name}) - 1)]);
+    }
+
+    /**
+     * Makes sure all the locale pieces are loaded, and finds the best match
+     * for the requested locale.
+     */
+    function resolveLocale(masterName, bundle, locale, context) {
+        //Break apart the locale to get the parts.
+        var i, parts, toLoad, nlsw, loc, val, bestLoc = "root";
+
+        parts = locale.split("-");
+
+        //Now see what bundles exist for each country/locale.
+        //Want to walk up the chain, so if locale is en-us-foo,
+        //look for en-us-foo, en-us, en, then root.
+        toLoad = [];
+
+        nlsw = getWaiting(masterName, context);
+
+        for (i = parts.length; i > -1; i--) {
+            loc = i ? parts.slice(0, i).join("-") : "root";
+            val = bundle[loc];
+            if (val) {
+                //Store which bundle to use for the default bundle definition.
+                if (locale === context.config.locale && !nlsw._match) {
+                    nlsw._match = loc;
+                }
+
+                //Store the best match for the target locale
+                if (bestLoc === "root") {
+                    bestLoc = loc;
+                }
+
+                //Track that the locale needs to be resolved with its parts.
+                //Mark what locale should be used when resolving.
+                nlsw[loc] = loc;
+
+                //If locale value is true, it means it is a resource that
+                //needs to be loaded. Track it to load if it has not already
+                //been asked for.
+                if (val === true) {
+                    //split off the bundl name from master name and insert the
+                    //locale before the bundle name. So, if masterName is
+                    //some/path/nls/colors, then the locale fr-fr's bundle name should
+                    //be some/path/nls/fr-fr/colors
+                    val = masterName.split("/");
+                    val.splice(-1, 0, loc);
+                    val = val.join("/");
+
+                    if (!context.specified[val] && !(val in context.loaded) && !context.defined[val]) {
+                        toLoad.push(val);
+                    }
+                }
+            }
+        }
+
+        //If locale was not an exact match, store the closest match for it.
+        if (bestLoc !== locale) {
+            if (context.defined[bestLoc]) {
+                //Already got it. Easy peasy lemon squeezy.
+                context.defined[locale] = context.defined[bestLoc];
+            } else {
+                //Need to wait for things to load then define it.
+                nlsw[locale] = bestLoc;
+            }
+        }
+
+        //Load any bundles that are still needed.
+        if (toLoad.length) {
+            context.defined.require(toLoad);
+        }
+    }
+
+    require.plugin({
+        prefix: "i18n",
+
+        /**
+         * This callback is prefix-specific, only gets called for this prefix
+         */
+        require: function (name, deps, callback, context) {
+            var i, match, nlsw, bundle, master, toLoad, obj = context.defined[name];
+
+            //All i18n modules must match the nls module name structure.
+            match = nlsRegExp.exec(name);
+            //If match[5] is blank, it means this is the top bundle definition,
+            //so it does not have to be handled. Only deal with ones that have a locale
+            //(a match[4] value but no match[5])
+            if (match[5]) {
+                master = match[1] + match[5];
+
+                //Track what locale bundle need to be generated once all the modules load.
+                nlsw = getWaiting(master, context);
+                nlsw[match[4]] = match[4];
+
+                bundle = context.nls[master];
+                if (!bundle) {
+                    //No master bundle yet, ask for it.
+                    context.defined.require([master]);
+                    bundle = context.nls[master] = {};
+                }
+                //For nls modules, the callback is just a regular object,
+                //so save it off in the bundle now.
+                bundle[match[4]] = callback;
+            } else {
+                //Integrate bundle into the nls area.
+                bundle = context.nls[name];
+                if (bundle) {
+                    //A specific locale already started the bundle object.
+                    //Do a mixin (which will not overwrite the locale property
+                    //on the bundle that has the previously loaded locale's info)
+                    require.mixin(bundle, obj);
+                } else {
+                    bundle = context.nls[name] = obj;
+                }
+                context.nlsRootLoaded[name] = true;
+
+                //Make sure there are no locales waiting to be resolved.
+                toLoad = context.nlsToLoad[name];
+                if (toLoad) {
+                    delete context.nlsToLoad[name];
+                    for (i = 0; i < toLoad.length; i++) {
+                        resolveLocale(name, bundle, toLoad[i], context);
+                    }
+                }
+
+                resolveLocale(name, bundle, context.config.locale, context);
+            }
+        },
+
+        /**
+         * Called when a new context is defined. Use this to store
+         * context-specific info on it.
+         */
+        newContext: function (context) {
+            require.mixin(context, {
+                nlsWaiting: [],
+                nls: {},
+                nlsRootLoaded: {},
+                nlsToLoad: {}
+            });
+            if (!context.config.locale) {
+                context.config.locale = typeof navigator === "undefined" ? "root" :
+                        (navigator.language || navigator.userLanguage || "root").toLowerCase();
+            }
+        },
+
+        /**
+         * Called when a dependency needs to be loaded.
+         */
+        load: function (name, contextName) {
+            //Make sure the root bundle is loaded, to check if we can support
+            //loading the requested locale, or if a different one needs
+            //to be chosen.
+            var masterName, context = require.s.contexts[contextName], bundle,
+                match = nlsRegExp.exec(name), locale = match[4];
+
+            //If match[5] is blank, it means this is the top bundle definition,
+            //so it does not have to be handled. Only deal with ones that have a locale
+            //(a match[4] value but no match[5])
+            if (match[5]) {
+                //locale-specific bundle
+                masterName = match[1] + match[5];
+                bundle = context.nls[masterName];
+                if (context.nlsRootLoaded[masterName] && bundle) {
+                    resolveLocale(masterName, bundle, locale, context);
+                } else {
+                    //Store this locale to figure out after masterName is loaded and load masterName.
+                    (context.nlsToLoad[masterName] || (context.nlsToLoad[masterName] = [])).push(locale);
+                    context.defined.require([masterName]);
+                }
+            } else {
+                //Top-level bundle. Just call regular load, if not already loaded
+                if (!context.nlsRootLoaded[name]) {
+                    require.load(name, contextName);
+                }
+            }
+        },
+
+        /**
+         * Called when the dependencies of a module are checked.
+         */
+        checkDeps: function (name, deps, context) {
+            //i18n bundles are always defined as objects for their "dependencies",
+            //and that object is already processed in the require method, no need to
+            //do work in here.
+        },
+
+        /**
+         * Called to determine if a module is waiting to load.
+         */
+        isWaiting: function (context) {
+            return !!context.nlsWaiting.length;
+        },
+
+        /**
+         * Called when all modules have been loaded.
+         */
+        orderDeps: function (context) {
+            //Clear up state since further processing could
+            //add more things to fetch.
+            var i, j, master, msWaiting, bundle, parts, moduleSuffix, mixed,
+                modulePrefix, loc, defLoc, locPart, nlsWaiting = context.nlsWaiting,
+                bestFit;
+            context.nlsWaiting = [];
+            context.nlsToLoad = {};
+
+            //First, properly mix in any nls bundles waiting to happen.
+            for (i = 0; (msWaiting = nlsWaiting[i]); i++) {
+                //Each property is a master bundle name.
+                master = msWaiting._name;
+                bundle = context.nls[master];
+                defLoc = null;
+
+                //Create the module name parts from the master name. So, if master
+                //is foo/nls/bar, then the parts should be prefix: "foo/nls",
+                // suffix: "bar", and the final locale's module name will be foo/nls/locale/bar
+                parts = master.split("/");
+                modulePrefix = parts.slice(0, parts.length - 1).join("/");
+                moduleSuffix = parts[parts.length - 1];
+                //Cycle through the locale props on the waiting object and combine
+                //the locales together.
+                for (loc in msWaiting) {
+                    if (loc !== "_name" && !(loc in empty)) {
+                        if (loc === "_match") {
+                            //Found default locale to use for the top-level bundle name.
+                            defLoc = msWaiting[loc];
+                        
+                        } else if (msWaiting[loc] !== loc) {
+                            //A "best fit" locale, store it off to the end and handle
+                            //it at the end by just assigning the best fit value, since
+                            //after this for loop, the best fit locale will be defined.
+                            (bestFit || (bestFit = {}))[loc] = msWaiting[loc];
+                        } else {
+                            //Mix in the properties of this locale together.
+                            //Split the locale into pieces.
+                            mixed = {};
+                            parts = loc.split("-");
+                            for (j = parts.length; j > 0; j--) {
+                                locPart = parts.slice(0, j).join("-");
+                                if (locPart !== "root" && bundle[locPart]) {
+                                    require.mixin(mixed, bundle[locPart]);
+                                }
+                            }
+                            if (bundle.root) {
+                                require.mixin(mixed, bundle.root);
+                            }
+
+                            context.defined[modulePrefix + "/" + loc + "/" + moduleSuffix] = mixed;
+                        }
+                    }
+                }
+
+                //Finally define the default locale. Wait to the end of the property
+                //loop above so that the default locale bundle has been properly mixed
+                //together.
+                context.defined[master] = context.defined[modulePrefix + "/" + defLoc + "/" + moduleSuffix];
+                
+                //Handle any best fit locale definitions.
+                if (bestFit) {
+                    for (loc in bestFit) {
+                        if (!(loc in empty)) {
+                            context.defined[modulePrefix + "/" + loc + "/" + moduleSuffix] = context.defined[modulePrefix + "/" + bestFit[loc] + "/" + moduleSuffix];
+                        }
+                    }
+                }
+            }
+        }
+    });
+}());
+
+require.baseUrlRegExp = /dojo(\.xd)?\.js(\W|$)/i;
+(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 tcn = tn + "";
+                    console[tcn] = ("log" in console) ? function () {
+                        var a = Array.apply({}, arguments);
+                        a.unshift(tcn + ":");
+                        console["log"](a.join(" "));
+                    } : function () {
+                    };
+                    console[tcn]._fake = true;
+                })();
+            }
+        }
+    }
+    if (typeof dojo == "undefined") {
+        dojo = {_scopeName:"dojo", _scopePrefix:"", _scopePrefixArgs:"", _scopeSuffix:"", _scopeMap:{}, _scopeMapRev:{}};
+    }
+    var d = dojo;
+    if (typeof dijit == "undefined") {
+        dijit = {_scopeName:"dijit"};
+    }
+    if (typeof dojox == "undefined") {
+        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 opt in djConfig) {
+            d.config[opt] = djConfig[opt];
+        }
+    }
+    dojo.locale = d.config.locale;
+    var rev = "$Rev: 20734 $".match(/\d+/);
+    dojo.version = {major:1, minor:4, patch:0, flag:"dev", revision:rev ? +rev[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 extraNames, extraLen, empty = {};
+    for (var i in {toString:1}) {
+        extraNames = [];
+        break;
+    }
+    dojo._extraNames = extraNames = extraNames || ["hasOwnProperty", "valueOf", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString", "constructor"];
+    extraLen = extraNames.length;
+    dojo._mixin = function (target, source) {
+        var name, s, i;
+        for (name in source) {
+            s = source[name];
+            if (!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))) {
+                target[name] = s;
+            }
+        }
+        if (extraLen && source) {
+            for (i = 0; i < extraLen; ++i) {
+                name = extraNames[i];
+                s = source[name];
+                if (!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))) {
+                    target[name] = s;
+                }
+            }
+        }
+        return target;
+    };
+    dojo.mixin = function (obj, props) {
+        if (!obj) {
+            obj = {};
+        }
+        for (var i = 1, l = arguments.length; i < l; i++) {
+            d._mixin(obj, arguments[i]);
+        }
+        return obj;
+    };
+    dojo._getProp = function (parts, create, context) {
+        var obj = context || d.global;
+        for (var i = 0, p; obj && (p = parts[i]); i++) {
+            if (i == 0 && d._scopeMap[p]) {
+                p = d._scopeMap[p];
+            }
+            obj = (p in obj ? obj[p] : (create ? obj[p] = {} : undefined));
+        }
+        return obj;
+    };
+    dojo.setObject = function (name, value, context) {
+        var parts = name.split("."), p = parts.pop(), obj = d._getProp(parts, true, context);
+        return obj && p ? (obj[p] = value) : undefined;
+    };
+    dojo.getObject = function (name, create, context) {
+        return d._getProp(name.split("."), create, context);
+    };
+    dojo.exists = function (name, obj) {
+        return !!d.getObject(name, false, obj);
+    };
+    dojo["eval"] = function (scriptFragment) {
+        return d.global.eval ? d.global.eval(scriptFragment) : eval(scriptFragment);
+    };
+    d.deprecated = d.experimental = function () {
+    };
+})();
+
+
+(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 (module) {
+        var mp = d._modulePrefixes;
+        return !!(mp[module] && mp[module].value);
+    }, _getModulePrefix:function (module) {
+        var mp = d._modulePrefixes;
+        if (d._moduleHasPrefix(module)) {
+            return mp[module].value;
+        }
+        return module;
+    }, _loadedUrls:[], _postLoad:false, _loaders:[], _unloaders:[], _loadNotifying:false});
+    dojo._loadPath = function (relpath, module, cb) {
+        var uri = ((relpath.charAt(0) == "/" || relpath.match(/^\w+:/)) ? "" : d.baseUrl) + relpath;
+        try {
+            return !module ? d._loadUri(uri, cb) : d._loadUriAndCheck(uri, module, cb);
+        }
+        catch (e) {
+            console.error(e);
+            return false;
+        }
+    };
+    dojo._loadUri = function (uri, cb) {
+        if (d._loadedUrls[uri]) {
+            return true;
+        }
+        d._inFlightCount++;
+        var contents = d._getText(uri, true);
+        if (contents) {
+            d._loadedUrls[uri] = true;
+            d._loadedUrls.push(uri);
+            if (cb) {
+                contents = "(" + contents + ")";
+            } else {
+                contents = d._scopePrefix + contents + d._scopeSuffix;
+            }
+            if (!d.isIE) {
+                contents += "\r\n//@ sourceURL=" + uri;
+            }
+            var value = d["eval"](contents);
+            if (cb) {
+                cb(value);
+            }
+        }
+        if (--d._inFlightCount == 0 && d._postLoad && d._loaders.length) {
+            setTimeout(function () {
+                if (d._inFlightCount == 0) {
+                    d._callLoaded();
+                }
+            }, 0);
+        }
+        return !!contents;
+    };
+    dojo._loadUriAndCheck = function (uri, moduleName, cb) {
+        var ok = false;
+        try {
+            ok = d._loadUri(uri, cb);
+        }
+        catch (e) {
+            console.error("failed loading " + uri + " with error: " + e);
+        }
+        return !!(ok && d._loadedModules[moduleName]);
+    };
+    dojo.loaded = function () {
+        d._loadNotifying = true;
+        d._postLoad = true;
+        var mll = d._loaders;
+        d._loaders = [];
+        for (var x = 0; x < mll.length; x++) {
+            mll[x]();
+        }
+        d._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 func = (typeof fn == "string") ? obj[fn] : fn;
+                arr.push(function () {
+                    func.call(obj);
+                });
+            }
+        }
+    };
+    dojo.ready = dojo.addOnLoad = function (obj, functionName) {
+        d._onto(d._loaders, obj, functionName);
+        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" || (d.config.useXDomain && d.isOpera)) {
+            setTimeout(d.isAIR ? function () {
+                d.loaded();
+            } : d._scopeName + ".loaded();", 0);
+        } else {
+            d.loaded();
+        }
+    };
+    dojo._getModuleSymbols = function (modulename) {
+        var syms = modulename.split(".");
+        for (var i = syms.length; i > 0; i--) {
+            var parentModule = syms.slice(0, i).join(".");
+            if (i == 1 && !d._moduleHasPrefix(parentModule)) {
+                syms[0] = "../" + syms[0];
+            } else {
+                var parentModulePath = d._getModulePrefix(parentModule);
+                if (parentModulePath != parentModule) {
+                    syms.splice(0, i, parentModulePath);
+                    break;
+                }
+            }
+        }
+        return syms;
+    };
+    dojo._global_omit_module_check = false;
+    dojo.loadInit = function (init) {
+        init();
+    };
+    dojo._loadModule = dojo.require = function (moduleName, omitModuleCheck) {
+        omitModuleCheck = d._global_omit_module_check || omitModuleCheck;
+        var module = d._loadedModules[moduleName];
+        if (module) {
+            return module;
+        }
+        var relpath = d._getModuleSymbols(moduleName).join("/") + ".js";
+        var modArg = !omitModuleCheck ? moduleName : null;
+        var ok = d._loadPath(relpath, modArg);
+        if (!ok && !omitModuleCheck) {
+            throw new Error("Could not load '" + moduleName + "'; last tried '" + relpath + "'");
+        }
+        if (!omitModuleCheck && !d._isXDomain) {
+            module = d._loadedModules[moduleName];
+            if (!module) {
+                throw new Error("symbol '" + moduleName + "' is not defined after loading '" + relpath + "'");
+            }
+        }
+        return module;
+    };
+    dojo.provide = function (resourceName) {
+        resourceName = resourceName + "";
+        return (d._loadedModules[resourceName] = d.getObject(resourceName, true));
+    };
+    dojo.platformRequire = function (modMap) {
+        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 (condition, resourceName) {
+        if (condition === true) {
+            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 (module, prefix) {
+        d._modulePrefixes[module] = {name:module, value:prefix};
+    };
+    dojo.requireLocalization = function (moduleName, bundleName, locale, availableFlatLocales) {
+        d.require("dojo.i18n");
+        d.i18n._requireLocalization.apply(d.hostenv, arguments);
+    };
+    var ore = new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"), ire = new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$");
+    dojo._Url = function () {
+        var n = null, _a = arguments, uri = [_a[0]];
+        for (var i = 1; i < _a.length; i++) {
+            if (!_a[i]) {
+                continue;
+            }
+            var relobj = new d._Url(_a[i] + ""), uriobj = new d._Url(uri[0] + "");
+            if (relobj.path == "" && !relobj.scheme && !relobj.authority && !relobj.query) {
+                if (relobj.fragment != n) {
+                    uriobj.fragment = relobj.fragment;
+                }
+                relobj = uriobj;
+            } else {
+                if (!relobj.scheme) {
+                    relobj.scheme = uriobj.scheme;
+                    if (!relobj.authority) {
+                        relobj.authority = uriobj.authority;
+                        if (relobj.path.charAt(0) != "/") {
+                            var path = uriobj.path.substring(0, uriobj.path.lastIndexOf("/") + 1) + relobj.path;
+                            var segs = path.split("/");
+                            for (var j = 0; j < segs.length; j++) {
+                                if (segs[j] == ".") {
+                                    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] != "..") {
+                                        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("");
+        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 (module, url) {
+        var loc = d._getModuleSymbols(module).join("/");
+        if (!loc) {
+            return null;
+        }
+        if (loc.lastIndexOf("/") != loc.length - 1) {
+            loc += "/";
+        }
+        var colonIndex = loc.indexOf(":");
+        if (loc.charAt(0) != "/" && (colonIndex == -1 || colonIndex > loc.indexOf("/"))) {
+            loc = d.baseUrl + loc;
+        }
+        return new d._Url(loc, url);
+    };
+})();
+
+
+if (typeof window != "undefined") {
+    dojo.isBrowser = true;
+    dojo._name = "browser";
+    (function () {
+        var d = dojo;
+        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) {
+                    if (!d.config.baseUrl) {
+                        d.config.baseUrl = src.substring(0, m.index);
+                    }
+                    var cfg = scripts[i].getAttribute("djConfig");
+                    if (cfg) {
+                        var cfgo = eval("({ " + cfg + " })");
+                        for (var x in cfgo) {
+                            dojo.config[x] = cfgo[x];
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+        d.baseUrl = d.config.baseUrl;
+        var n = navigator;
+        var dua = n.userAgent, dav = n.appVersion, tv = parseFloat(dav);
+        if (dua.indexOf("Opera") >= 0) {
+            d.isOpera = tv;
+        }
+        if (dua.indexOf("AdobeAIR") >= 0) {
+            d.isAIR = 1;
+        }
+        d.isKhtml = (dav.indexOf("Konqueror") >= 0) ? tv : 0;
+        d.isWebKit = parseFloat(dua.split("WebKit/")[1]) || undefined;
+        d.isChrome = parseFloat(dua.split("Chrome/")[1]) || undefined;
+        d.isMac = dav.indexOf("Macintosh") >= 0;
+        var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);
+        if (index && !dojo.isChrome) {
+            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) {
+            d.isFF = parseFloat(dua.split("Firefox/")[1] || dua.split("Minefield/")[1]) || undefined;
+        }
+        if (document.all && !d.isOpera) {
+            d.isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
+            var mode = document.documentMode;
+            if (mode && mode != 5 && Math.floor(d.isIE) != mode) {
+                d.isIE = mode;
+            }
+        }
+        if (dojo.isIE && window.location.protocol === "file:") {
+            dojo.config.ieForceActiveXXhr = true;
+        }
+        d.isQuirks = document.compatMode == "BackCompat";
+        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 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];
+                        break;
+                    }
+                }
+            }
+            if (!http) {
+                throw new Error("XMLHTTP not available: " + last_e);
+            }
+            return http;
+        };
+        d._isDocumentOk = function (http) {
+            var stat = http.status || 0, lp = location.protocol;
+            return (stat >= 200 && stat < 300) || stat == 304 || stat == 1223 || (!stat && (lp == "file:" || lp == "chrome:" || lp == "app:"));
+        };
+        var owloc = window.location + "";
+        var base = document.getElementsByTagName("base");
+        var hasBase = (base && base.length > 0);
+        d._getText = function (uri, fail_ok) {
+            var http = d._xhrObj();
+            if (!hasBase && dojo._Url) {
+                uri = (new dojo._Url(owloc, uri)).toString();
+            }
+            if (d.config.cacheBust) {
+                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;
+                }
+                throw e;
+            }
+            return http.responseText;
+        };
+        var _w = window;
+        var _handleNodeEvent = function (evtName, fp) {
+            var _a = _w.attachEvent || _w.addEventListener;
+            evtName = _w.attachEvent ? evtName : evtName.substring(2);
+            _a(evtName, function () {
+                fp.apply(_w, arguments);
+            }, false);
+        };
+        d._windowUnloaders = [];
+        d.windowUnloaded = function () {
+            var mll = d._windowUnloaders;
+            while (mll.length) {
+                (mll.pop())();
+            }
+        };
+        var _onWindowUnloadAttached = 0;
+        d.addOnWindowUnload = function (obj, functionName) {
+            d._onto(d._windowUnloaders, obj, functionName);
+            if (!_onWindowUnloadAttached) {
+                _onWindowUnloadAttached = 1;
+                _handleNodeEvent("onunload", d.windowUnloaded);
+            }
+        };
+        var _onUnloadAttached = 0;
+        d.addOnUnload = function (obj, functionName) {
+            d._onto(d._unloaders, obj, functionName);
+            if (!_onUnloadAttached) {
+                _onUnloadAttached = 1;
+                _handleNodeEvent("onbeforeunload", dojo.unloaded);
+            }
+        };
+    })();
+    dojo._initFired = false;
+    dojo._loadInit = function (e) {
+        if (!dojo._initFired) {
+            dojo._initFired = true;
+            if (!dojo.config.afterOnLoad && window.detachEvent) {
+                window.detachEvent("onload", dojo._loadInit);
+            }
+            if (dojo._inFlightCount == 0) {
+                dojo._modulesLoaded();
+            }
+        }
+    };
+    if (!dojo.config.afterOnLoad) {
+        if (document.addEventListener) {
+            document.addEventListener("DOMContentLoaded", dojo._loadInit, false);
+            window.addEventListener("load", dojo._loadInit, false);
+        } else {
+            if (window.attachEvent) {
+                window.attachEvent("onload", dojo._loadInit);
+            }
+        }
+    }
+    if (dojo.isIE) {
+        if (!dojo.config.afterOnLoad && !dojo.config.skipIeDomLoaded) {
+            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");
+            var vmlElems = ["*", "group", "roundrect", "oval", "shape", "rect", "imagedata"], i = 0, l = 1, s = document.createStyleSheet();
+            if (dojo.isIE >= 8) {
+                i = 1;
+                l = vmlElems.length;
+            }
+            for (; i < l; ++i) {
+                s.addRule("v\\:" + vmlElems[i], "behavior:url(#default#VML); display:inline-block");
+            }
+        }
+        catch (e) {
+        }
+    }
+}
+(function () {
+    var mp = dojo.config["modulePaths"];
+    if (mp) {
+        for (var param in mp) {
+            dojo.registerModulePath(param, mp[param]);
+        }
+    }
+})();
+
+require.def("dojo", function() {return dojo;});require.def("dijit", function() {return dijit;});require.def("dojox", function() {return dojox;});require.modify("dojo", "dojo-base", ["dojo", "dojo/_base"], function(){});
+require.def("dojo/_base/lang", ["require", "dojo", "dijit", "dojox"], function(require, dojo, dijit, dojox) {
+dojo.provide("dojo._base.lang");
+
+(function(){
+	var d = dojo, opts = Object.prototype.toString;
+
+	// Crockford (ish) functions
+
+	dojo.isString = function(/*anything*/ it){
+		//	summary:
+		//		Return true if it is a String
+		return (typeof it == "string" || it instanceof String); // Boolean
+	}
+
+	dojo.isArray = function(/*anything*/ it){
+		//	summary:
+		//		Return true if it is an Array.
+		//		Does not work on Arrays created in other windows.
+		return it && (it instanceof Array || typeof it == "array"); // Boolean
+	}
+
+	dojo.isFunction = function(/*anything*/ it){
+		// summary:
+		//		Return true if it is a Function
+		return opts.call(it) === "[object Function]";
+	};
+
+	dojo.isObject = function(/*anything*/ it){
+		// summary:
+		//		Returns true if it is a JavaScript object (or an Array, a Function
+		//		or null)
+		return it !== undefined &&
+			(it === null || typeof it == "object" || d.isArray(it) || d.isFunction(it)); // Boolean
+	}
+
+	dojo.isArrayLike = function(/*anything*/ it){
+		//	summary:
+		//		similar to dojo.isArray() but more permissive
+		//	description:
+		//		Doesn't strongly test for "arrayness".  Instead, settles for "isn't
+		//		a string or number and has a length property". Arguments objects
+		//		and DOM collections will return true when passed to
+		//		dojo.isArrayLike(), but will return false when passed to
+		//		dojo.isArray().
+		//	returns:
+		//		If it walks like a duck and quacks like a duck, return `true`
+		return it && it !== undefined && // Boolean
+			// keep out built-in constructors (Number, String, ...) which have length
+			// properties
+			!d.isString(it) && !d.isFunction(it) &&
+			!(it.tagName && it.tagName.toLowerCase() == 'form') &&
+			(d.isArray(it) || isFinite(it.length));
+	}
+
+	dojo.isAlien = function(/*anything*/ it){
+		// summary:
+		//		Returns true if it is a built-in function or some other kind of
+		//		oddball that *should* report as a function but doesn't
+		return it && !d.isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean
+	}
+
+	dojo.extend = function(/*Object*/ constructor, /*Object...*/ props){
+		// summary:
+		//		Adds all properties and methods of props to constructor's
+		//		prototype, making them available to all instances created with
+		//		constructor.
+		for(var i=1, l=arguments.length; i<l; i++){
+			d._mixin(constructor.prototype, arguments[i]);
+		}
+		return constructor; // Object
+	}
+
+	dojo._hitchArgs = function(scope, method /*,...*/){
+		var pre = d._toArray(arguments, 2);
+		var named = d.isString(method);
+		return function(){
+			// arrayify arguments
+			var args = d._toArray(arguments);
+			// locate our method
+			var f = named ? (scope||d.global)[method] : method;
+			// invoke with collected args
+			return f && f.apply(scope || this, pre.concat(args)); // mixed
+		} // Function
+	}
+
+	dojo.hitch = function(/*Object*/scope, /*Function|String*/method /*,...*/){
+		//	summary:
+		//		Returns a function that will only ever execute in the a given scope.
+		//		This allows for easy use of object member functions
+		//		in callbacks and other places in which the "this" keyword may
+		//		otherwise not reference the expected scope.
+		//		Any number of default positional arguments may be passed as parameters 
+		//		beyond "method".
+		//		Each of these values will be used to "placehold" (similar to curry)
+		//		for the hitched function.
+		//	scope:
+		//		The scope to use when method executes. If method is a string,
+		//		scope is also the object containing method.
+		//	method:
+		//		A function to be hitched to scope, or the name of the method in
+		//		scope to be hitched.
+		//	example:
+		//	|	dojo.hitch(foo, "bar")();
+		//		runs foo.bar() in the scope of foo
+		//	example:
+		//	|	dojo.hitch(foo, myFunction);
+		//		returns a function that runs myFunction in the scope of foo
+		//	example:
+		//		Expansion on the default positional arguments passed along from
+		//		hitch. Passed args are mixed first, additional args after.
+		//	|	var foo = { bar: function(a, b, c){ console.log(a, b, c); } };
+		//	|	var fn = dojo.hitch(foo, "bar", 1, 2);
+		//	|	fn(3); // logs "1, 2, 3"
+		//	example:
+		//	|	var foo = { bar: 2 };
+		//	|	dojo.hitch(foo, function(){ this.bar = 10; })();
+		//		execute an anonymous function in scope of foo
+		
+		if(arguments.length > 2){
+			return d._hitchArgs.apply(d, arguments); // Function
+		}
+		if(!method){
+			method = scope;
+			scope = null;
+		}
+		if(d.isString(method)){
+			scope = scope || d.global;
+			if(!scope[method]){ throw(['dojo.hitch: scope["', method, '"] is null (scope="', scope, '")'].join('')); }
+			return function(){ return scope[method].apply(scope, arguments || []); }; // Function
+		}
+		return !scope ? method : function(){ return method.apply(scope, arguments || []); }; // Function
+	}
+
+	/*=====
+	dojo.delegate = function(obj, props){
+		//	summary:
+		//		Returns a new object which "looks" to obj for properties which it
+		//		does not have a value for. Optionally takes a bag of properties to
+		//		seed the returned object with initially.
+		//	description:
+		//		This is a small implementaton of the Boodman/Crockford delegation
+		//		pattern in JavaScript. An intermediate object constructor mediates
+		//		the prototype chain for the returned object, using it to delegate
+		//		down to obj for property lookup when object-local lookup fails.
+		//		This can be thought of similarly to ES4's "wrap", save that it does
+		//		not act on types but rather on pure objects.
+		//	obj:
+		//		The object to delegate to for properties not found directly on the
+		//		return object or in props.
+		//	props:
+		//		an object containing properties to assign to the returned object
+		//	returns:
+		//		an Object of anonymous type
+		//	example:
+		//	|	var foo = { bar: "baz" };
+		//	|	var thinger = dojo.delegate(foo, { thud: "xyzzy"});
+		//	|	thinger.bar == "baz"; // delegated to foo
+		//	|	foo.thud == undefined; // by definition
+		//	|	thinger.thud == "xyzzy"; // mixed in from props
+		//	|	foo.bar = "thonk";
+		//	|	thinger.bar == "thonk"; // still delegated to foo's bar
+	}
+	=====*/
+
+	dojo.delegate = dojo._delegate = (function(){
+		// boodman/crockford delegation w/ cornford optimization
+		function TMP(){}
+		return function(obj, props){
+			TMP.prototype = obj;
+			var tmp = new TMP();
+			TMP.prototype = null;
+			if(props){
+				d._mixin(tmp, props);
+			}
+			return tmp; // Object
+		}
+	})();
+
+	/*=====
+	dojo._toArray = function(obj, offset, startWith){
+		//	summary:
+		//		Converts an array-like object (i.e. arguments, DOMCollection) to an
+		//		array. Returns a new Array with the elements of obj.
+		//	obj: Object
+		//		the object to "arrayify". We expect the object to have, at a
+		//		minimum, a length property which corresponds to integer-indexed
+		//		properties.
+		//	offset: Number?
+		//		the location in obj to start iterating from. Defaults to 0.
+		//		Optional.
+		//	startWith: Array?
+		//		An array to pack with the properties of obj. If provided,
+		//		properties in obj are appended at the end of startWith and
+		//		startWith is the returned array.
+	}
+	=====*/
+
+	var efficient = function(obj, offset, startWith){
+		return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0));
+	};
+
+		var slow = function(obj, offset, startWith){
+		var arr = startWith||[];
+		for(var x = offset || 0; x < obj.length; x++){
+			arr.push(obj[x]);
+		}
+		return arr;
+	};
+	
+	dojo._toArray =
+				d.isIE ?  function(obj){
+			return ((obj.item) ? slow : efficient).apply(this, arguments);
+		} :
+				efficient;
+
+	dojo.partial = function(/*Function|String*/method /*, ...*/){
+		//	summary:
+		//		similar to hitch() except that the scope object is left to be
+		//		whatever the execution context eventually becomes.
+		//	description:
+		//		Calling dojo.partial is the functional equivalent of calling:
+		//		|	dojo.hitch(null, funcName, ...);
+		var arr = [ null ];
+		return d.hitch.apply(d, arr.concat(d._toArray(arguments))); // Function
+	}
+
+	var extraNames = d._extraNames, extraLen = extraNames.length, empty = {};
+
+	dojo.clone = function(/*anything*/ o){
+		// summary:
+		//		Clones objects (including DOM nodes) and all children.
+		//		Warning: do not clone cyclic structures.
+		if(!o || typeof o != "object" || d.isFunction(o)){
+			// null, undefined, any non-object, or function
+			return o;	// anything
+		}
+		if(o.nodeType && "cloneNode" in o){
+			// DOM Node
+			return o.cloneNode(true); // Node
+		}
+		if(o instanceof Date){
+			// Date
+			return new Date(o.getTime());	// Date
+		}
+		var r, i, l, s, name;
+		if(d.isArray(o)){
+			// array
+			r = [];
+			for(i = 0, l = o.length; i < l; ++i){
+				if(i in o){
+					r.push(d.clone(o[i]));
+				}
+			}
+// we don't clone functions for performance reasons
+//		}else if(d.isFunction(o)){
+//			// function
+//			r = function(){ return o.apply(this, arguments); };
+		}else{
+			// generic objects
+			r = o.constructor ? new o.constructor() : {};
+		}
+		for(name in o){
+			// the "tobj" condition avoid copying properties in "source"
+			// inherited from Object.prototype.  For example, if target has a custom
+			// toString() method, don't overwrite it with the toString() method
+			// that source inherited from Object.prototype
+			s = o[name];
+			if(!(name in r) || (r[name] !== s && (!(name in empty) || empty[name] !== s))){
+				r[name] = d.clone(s);
+			}
+		}
+				// IE doesn't recognize some custom functions in for..in
+		if(extraLen){
+			for(i = 0; i < extraLen; ++i){
+				name = extraNames[i];
+				s = o[name];
+				if(!(name in r) || (r[name] !== s && (!(name in empty) || empty[name] !== s))){
+					r[name] = s; // functions only, we don't clone them
+				}
+			}
+		}
+				return r; // Object
+	}
+
+	/*=====
+	dojo.trim = function(str){
+		//	summary:
+		//		Trims whitespace from both sides of the string
+		//	str: String
+		//		String to be trimmed
+		//	returns: String
+		//		Returns the trimmed string
+		//	description:
+		//		This version of trim() was selected for inclusion into the base due
+		//		to its compact size and relatively good performance
+		//		(see [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript)
+		//		Uses String.prototype.trim instead, if available.
+		//		The fastest but longest version of this function is located at
+		//		dojo.string.trim()
+		return "";	// String
+	}
+	=====*/
+
+	dojo.trim = String.prototype.trim ?
+		function(str){ return str.trim(); } :
+		function(str){ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); };
+
+	/*=====
+	dojo.replace = function(tmpl, map, pattern){
+		//	summary:
+		//		Performs parameterized substitutions on a string. Throws an
+		//		exception if any parameter is unmatched. 
+		//	tmpl: String
+		//		String to be used as a template.
+		//	map: Object|Function
+		//		If an object, it is used as a dictionary to look up substitutions.
+		//		If a function, it is called for every substitution with following
+		//		parameters: a whole match, a name, an offset, and the whole template
+		//		string (see https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/replace
+		//		for more details).
+		//	pattern: RegEx?
+		//		Optional regular expression objects that overrides the default pattern.
+		//		Must be global and match one item. The default is: /\{([^\}]+)\}/g,
+		//		which matches patterns like that: "{xxx}", where "xxx" is any sequence
+		//		of characters, which doesn't include "}".
+		//	returns: String
+		//		Returns the substituted string.
+		//	example:
+		//	|	// uses a dictionary for substitutions:
+		//	|	dojo.replace("Hello, {name.first} {name.last} AKA {nick}!",
+		//	|	  {
+		//	|	    nick: "Bob",
+		//	|	    name: {
+		//	|	      first:  "Robert",
+		//	|	      middle: "X",
+		//	|	      last:   "Cringely"
+		//	|	    }
+		//	|	  });
+		//	|	// returns: Hello, Robert Cringely AKA Bob!
+		//	example:
+		//	|	// uses an array for substitutions:
+		//	|	dojo.replace("Hello, {0} {2}!",
+		//	|	  ["Robert", "X", "Cringely"]);
+		//	|	// returns: Hello, Robert Cringely!
+		//	example:
+		//	|	// uses a function for substitutions:
+		//	|	function sum(a){
+		//	|	  var t = 0;
+		//	|	  dojo.forEach(a, function(x){ t += x; });
+		//	|	  return t;
+		//	|	}
+		//	|	dojo.replace(
+		//	|	  "{count} payments averaging {avg} USD per payment.",
+		//	|	  dojo.hitch(
+		//	|	    { payments: [11, 16, 12] },
+		//	|	    function(_, key){
+		//	|	      switch(key){
+		//	|	        case "count": return this.payments.length;
+		//	|	        case "min":   return Math.min.apply(Math, this.payments);
+		//	|	        case "max":   return Math.max.apply(Math, this.payments);
+		//	|	        case "sum":   return sum(this.payments);
+		//	|	        case "avg":   return sum(this.payments) / this.payments.length;
+		//	|	      }
+		//	|	    }
+		//	|	  )
+		//	|	);
+		//	|	// prints: 3 payments averaging 13 USD per payment.
+		//	example:
+		//	|	// uses an alternative PHP-like pattern for substitutions:
+		//	|	dojo.replace("Hello, ${0} ${2}!",
+		//	|	  ["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g);
+		//	|	// returns: Hello, Robert Cringely!
+		return "";	// String
+	}
+	=====*/
+
+	var _pattern = /\{([^\}]+)\}/g;
+	dojo.replace = function(tmpl, map, pattern){
+		return tmpl.replace(pattern || _pattern, d.isFunction(map) ?
+			map : function(_, k){ return d.getObject(k, false, map); });
+	};
+})();
+
+return dojo._base.lang; });
+;
+require.def("dojo/_base/array", ["require", "dojo", "dijit", "dojox"], function(require, dojo, dijit, dojox) {
+dojo.provide("dojo._base.array");
+
+(function(){
+	var _getParts = function(arr, obj, cb){
+		return [ 
+			(typeof arr == "string") ? arr.split("") : arr, 
+			obj || dojo.global,
+			// FIXME: cache the anonymous functions we create here?
+			(typeof cb == "string") ? new Function("item", "index", "array", cb) : cb
+		];
+	};
+
+	var everyOrSome = function(/*Boolean*/every, /*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
+		var _p = _getParts(arr, thisObject, callback); arr = _p[0];
+		for(var i=0,l=arr.length; i<l; ++i){
+			var result = !!_p[2].call(_p[1], arr[i], i, arr);
+			if(every ^ result){
+				return result; // Boolean
+			}
+		}
+		return every; // Boolean
+	};
+
+	dojo.mixin(dojo, {
+		indexOf: function(	/*Array*/		array, 
+							/*Object*/		value,
+							/*Integer?*/	fromIndex,
+							/*Boolean?*/	findLast){
+			// summary:
+			//		locates the first index of the provided value in the
+			//		passed array. If the value is not found, -1 is returned.
+			// description:
+			//		This method corresponds to the JavaScript 1.6 Array.indexOf method, with one difference: when
+			//		run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript 
+			//		1.6's indexOf skips the holes in the sparse array.
+			//		For details on this method, see:
+			//			https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf
+
+			var step = 1, end = array.length || 0, i = 0;
+			if(findLast){
+				i = end - 1;
+				step = end = -1;
+			}
+			if(fromIndex != undefined){ i = fromIndex; }
+			if((findLast && i > end) || i < end){
+				for(; i != end; i += step){
+					if(array[i] == value){ return i; }
+				}
+			}
+			return -1;	// Number
+		},
+
+		lastIndexOf: function(/*Array*/array, /*Object*/value, /*Integer?*/fromIndex){
+			// summary:
+			//		locates the last index of the provided value in the passed
+			//		array. If the value is not found, -1 is returned.
+			// description:
+			//		This method corresponds to the JavaScript 1.6 Array.lastIndexOf method, with one difference: when
+			//		run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript 
+			//		1.6's lastIndexOf skips the holes in the sparse array.
+			//		For details on this method, see:
+			// 			https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/lastIndexOf
+			return dojo.indexOf(array, value, fromIndex, true); // Number
+		},
+
+		forEach: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
+			//	summary:
+			//		for every item in arr, callback is invoked. Return values are ignored.
+			//		If you want to break out of the loop, consider using dojo.every() or dojo.some().
+			//		forEach does not allow breaking out of the loop over the items in arr.
+			//	arr:
+			//		the array to iterate over. If a string, operates on individual characters.
+			//	callback:
+			//		a function is invoked with three arguments: item, index, and array
+			//	thisObject:
+			//		may be used to scope the call to callback
+			//	description:
+			//		This function corresponds to the JavaScript 1.6 Array.forEach() method, with one difference: when 
+			//		run over sparse arrays, this implemenation passes the "holes" in the sparse array to
+			//		the callback function with a value of undefined. JavaScript 1.6's forEach skips the holes in the sparse array.
+			//		For more details, see:
+			//			https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach
+			//	example:
+			//	|	// log out all members of the array:
+			//	|	dojo.forEach(
+			//	|		[ "thinger", "blah", "howdy", 10 ],
+			//	|		function(item){
+			//	|			console.log(item);
+			//	|		}
+			//	|	);
+			//	example:
+			//	|	// log out the members and their indexes
+			//	|	dojo.forEach(
+			//	|		[ "thinger", "blah", "howdy", 10 ],
+			//	|		function(item, idx, arr){
+			//	|			console.log(item, "at index:", idx);
+			//	|		}
+			//	|	);
+			//	example:
+			//	|	// use a scoped object member as the callback
+			//	|	
+			//	|	var obj = {
+			//	|		prefix: "logged via obj.callback:", 
+			//	|		callback: function(item){
+			//	|			console.log(this.prefix, item);
+			//	|		}
+			//	|	};
+			//	|	
+			//	|	// specifying the scope function executes the callback in that scope
+			//	|	dojo.forEach(
+			//	|		[ "thinger", "blah", "howdy", 10 ],
+			//	|		obj.callback,
+			//	|		obj
+			//	|	);
+			//	|	
+			//	|	// alternately, we can accomplish the same thing with dojo.hitch()
+			//	|	dojo.forEach(
+			//	|		[ "thinger", "blah", "howdy", 10 ],
+			//	|		dojo.hitch(obj, "callback")
+			//	|	);
+
+			// match the behavior of the built-in forEach WRT empty arrs
+			if(!arr || !arr.length){ return; }
+
+			// FIXME: there are several ways of handilng thisObject. Is
+			// dojo.global always the default context?
+			var _p = _getParts(arr, thisObject, callback); arr = _p[0];
+			for(var i=0,l=arr.length; i<l; ++i){ 
+				_p[2].call(_p[1], arr[i], i, arr);
+			}
+		},
+
+		every: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
+			// summary:
+			//		Determines whether or not every item in arr satisfies the
+			//		condition implemented by callback.
+			// arr:
+			//		the array to iterate on. If a string, operates on individual characters.
+			// callback:
+			//		a function is invoked with three arguments: item, index,
+			//		and array and returns true if the condition is met.
+			// thisObject:
+			//		may be used to scope the call to callback
+			// description:
+			//		This function corresponds to the JavaScript 1.6 Array.every() method, with one difference: when 
+			//		run over sparse arrays, this implemenation passes the "holes" in the sparse array to
+			//		the callback function with a value of undefined. JavaScript 1.6's every skips the holes in the sparse array.
+			//		For more details, see:
+			//			https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/every
+			// example:
+			//	|	// returns false
+			//	|	dojo.every([1, 2, 3, 4], function(item){ return item>1; });
+			// example:
+			//	|	// returns true 
+			//	|	dojo.every([1, 2, 3, 4], function(item){ return item>0; });
+			return everyOrSome(true, arr, callback, thisObject); // Boolean
+		},
+
+		some: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
+			// summary:
+			//		Determines whether or not any item in arr satisfies the
+			//		condition implemented by callback.
+			// arr:
+			//		the array to iterate over. If a string, operates on individual characters.
+			// callback:
+			//		a function is invoked with three arguments: item, index,
+			//		and array and returns true if the condition is met.
+			// thisObject:
+			//		may be used to scope the call to callback
+			// description:
+			//		This function corresponds to the JavaScript 1.6 Array.some() method, with one difference: when 
+			//		run over sparse arrays, this implemenation passes the "holes" in the sparse array to
+			//		the callback function with a value of undefined. JavaScript 1.6's some skips the holes in the sparse array.
+			//		For more details, see:
+			//			https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/some
+			// example:
+			//	|	// is true
+			//	|	dojo.some([1, 2, 3, 4], function(item){ return item>1; });
+			// example:
+			//	|	// is false
+			//	|	dojo.some([1, 2, 3, 4], function(item){ return item<1; });
+			return everyOrSome(false, arr, callback, thisObject); // Boolean
+		},
+
+		map: function(/*Array|String*/arr, /*Function|String*/callback, /*Function?*/thisObject){
+			// summary:
+			//		applies callback to each element of arr and returns
+			//		an Array with the results
+			// arr:
+			//		the array to iterate on. If a string, operates on
+			//		individual characters.
+			// callback:
+			//		a function is invoked with three arguments, (item, index,
+			//		array),  and returns a value
+			// thisObject:
+			//		may be used to scope the call to callback
+			// description:
+			//		This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when 
+			//		run over sparse arrays, this implemenation passes the "holes" in the sparse array to
+			//		the callback function with a value of undefined. JavaScript 1.6's map skips the holes in the sparse array.
+			//		For more details, see:
+			//			https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
+			// example:
+			//	|	// returns [2, 3, 4, 5]
+			//	|	dojo.map([1, 2, 3, 4], function(item){ return item+1 });
+
+			var _p = _getParts(arr, thisObject, callback); arr = _p[0];
+			var outArr = (arguments[3] ? (new arguments[3]()) : []);
+			for(var i=0,l=arr.length; i<l; ++i){
+				outArr.push(_p[2].call(_p[1], arr[i], i, arr));
+			}
+			return outArr; // Array
+		},
+
+		filter: function(/*Array*/arr, /*Function|String*/callback, /*Object?*/thisObject){
+			// summary:
+			//		Returns a new Array with those items from arr that match the
+			//		condition implemented by callback.
+			// arr:
+			//		the array to iterate over.
+			// callback:
+			//		a function that is invoked with three arguments (item,
+			//		index, array). The return of this function is expected to
+			//		be a boolean which determines whether the passed-in item
+			//		will be included in the returned array.
+			// thisObject:
+			//		may be used to scope the call to callback
+			// description:
+			//		This function corresponds to the JavaScript 1.6 Array.filter() method, with one difference: when 
+			//		run over sparse arrays, this implemenation passes the "holes" in the sparse array to
+			//		the callback function with a value of undefined. JavaScript 1.6's filter skips the holes in the sparse array. 
+			//		For more details, see:
+			//			https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
+			// example:
+			//	|	// returns [2, 3, 4]
+			//	|	dojo.filter([1, 2, 3, 4], function(item){ return item>1; });
+
+			var _p = _getParts(arr, thisObject, callback); arr = _p[0];
+			var outArr = [];
+			for(var i=0,l=arr.length; i<l; ++i){
+				if(_p[2].call(_p[1], arr[i], i, arr)){
+					outArr.push(arr[i]);
+				}
+			}
+			return outArr; // Array
+		}
+	});
+})();
+/*
+*/
+
+return dojo._base.array; });
+require.def("dojo/_base/declare", ["require", "dojo", "dijit", "dojox", "dojo/_base/lang", "dojo/_base/array"], function(require, dojo, dijit, dojox, _R0, _R1) {
+dojo.provide("dojo._base.declare");
+
+;
+;
+
+(function(){
+	var d = dojo, mix = d._mixin, op = Object.prototype, opts = op.toString,
+		xtor = new Function, counter = 0, cname = "constructor";
+
+	function err(msg){ throw new Error("declare: " + msg); }
+
+	// C3 Method Resolution Order (see http://www.python.org/download/releases/2.3/mro/)
+	function c3mro(bases){
+		var result = [], roots = [{cls: 0, refs: []}], nameMap = {}, clsCount = 1,
+			l = bases.length, i = 0, j, lin, base, top, proto, rec, name, refs;
+
+		// build a list of bases naming them if needed
+		for(; i < l; ++i){
+			base = bases[i];
+			if(!base){
+				err("mixin #" + i + " is null");
+			}
+			lin = base._meta ? base._meta.bases : [base];
+			top = 0;
+			// add bases to the name map
+			for(j = lin.length - 1; j >= 0; --j){
+				proto = lin[j].prototype;
+				if(!proto.hasOwnProperty("declaredClass")){
+					proto.declaredClass = "uniqName_" + (counter++);
+				}
+				name = proto.declaredClass;
+				if(!nameMap.hasOwnProperty(name)){
+					nameMap[name] = {count: 0, refs: [], cls: lin[j]};
+					++clsCount;
+				}
+				rec = nameMap[name];
+				if(top && top !== rec){
+					rec.refs.push(top);
+					++top.count;
+				}
+				top = rec;
+			}
+			++top.count;
+			roots[0].refs.push(top);
+		}
+
+		// remove classes without external references recursively
+		while(roots.length){
+			top = roots.pop();
+			result.push(top.cls);
+			--clsCount;
+			// optimization: follow a single-linked chain
+			while(refs = top.refs, refs.length == 1){
+				top = refs[0];
+				if(!top || --top.count){
+					// branch or end of chain => do not end to roots
+					top = 0;
+					break;
+				}
+				result.push(top.cls);
+				--clsCount;
+			}
+			if(top){
+				// branch
+				for(i = 0, l = refs.length; i < l; ++i){
+					top = refs[i];
+					if(!--top.count){
+						roots.push(top);
+					}
+				}
+			}
+		}
+		if(clsCount){
+			err("can't build consistent linearization");
+		}
+
+		// calculate the superclass offset
+		base = bases[0];
+		result[0] = base ?
+			base._meta && base === result[result.length - base._meta.bases.length] ?
+				base._meta.bases.length : 1 : 0;
+
+		return result;
+	}
+
+	function inherited(args, a, f){
+		var name, chains, bases, caller, meta, base, proto, opf, pos,
+			cache = this._inherited = this._inherited || {};
+
+		// crack arguments
+		if(typeof args == "string"){
+			name = args;
+			args = a;
+			a = f;
+		}
+		f = 0;
+
+		caller = args.callee;
+		name = name || caller.nom;
+		if(!name){
+			err("can't deduce a name to call inherited()");
+		}
+
+		meta = this.constructor._meta;
+		bases = meta.bases;
+
+		pos = cache.p;
+		if(name != cname){
+			// method
+			if(cache.c !== caller){
+				// cache bust
+				pos = 0;
+				base = bases[0];
+				meta = base._meta;
+				if(meta.hidden[name] !== caller){
+					// error detection
+					chains = meta.chains;
+					if(chains && typeof chains[name] == "string"){
+						err("calling chained method with inherited: " + name);
+					}
+					// find caller
+					do{
+						meta = base._meta;
+						proto = base.prototype;
+						if(meta && (proto[name] === caller && proto.hasOwnProperty(name) || meta.hidden[name] === caller)){
+							break;
+						}
+					}while(base = bases[++pos]); // intentional assignment
+					pos = base ? pos : -1;
+				}
+			}
+			// find next
+			base = bases[++pos];
+			if(base){
+				proto = base.prototype;
+				if(base._meta && proto.hasOwnProperty(name)){
+					f = proto[name];
+				}else{
+					opf = op[name];
+					do{
+						proto = base.prototype;
+						f = proto[name];
+						if(f && (base._meta ? proto.hasOwnProperty(name) : f !== opf)){
+							break;
+						}
+					}while(base = bases[++pos]); // intentional assignment
+				}
+			}
+			f = base && f || op[name];
+		}else{
+			// constructor
+			if(cache.c !== caller){
+				// cache bust
+				pos = 0;
+				meta = bases[0]._meta;
+				if(meta && meta.ctor !== caller){
+					// error detection
+					chains = meta.chains;
+					if(!chains || chains.constructor !== "manual"){
+						err("calling chained constructor with inherited");
+					}
+					// find caller
+					while(base = bases[++pos]){ // intentional assignment
+						meta = base._meta;
+						if(meta && meta.ctor === caller){
+							break;
+						}
+					};
+					pos = base ? pos : -1;
+				}
+			}
+			// find next
+			while(base = bases[++pos]){	// intentional assignment
+				meta = base._meta;
+				f = meta ? meta.ctor : base;
+				if(f){
+					break;
+				}
+			}
+			f = base && f;
+		}
+
+		// cache the found super method
+		cache.c = f;
+		cache.p = pos;
+
+		// now we have the result
+		if(f){
+			return a === true ? f : f.apply(this, a || args);
+		}
+		// intentionally if a super method was not found
+	}
+
+	function getInherited(name, args){
+		if(typeof name == "string"){
+			return this.inherited(name, args, true);
+		}
+		return this.inherited(name, true);
+	}
+
+	// emulation of "instanceof"
+	function isInstanceOf(cls){
+		var bases = this.constructor._meta.bases;
+		for(var i = 0, l = bases.length; i < l; ++i){
+			if(bases[i] === cls){
+				return true;
+			}
+		}
+		return this instanceof cls;
+	}
+
+	// imlementation of safe mixin function
+	function safeMixin(target, source){
+		var name, t, i = 0, l = d._extraNames.length;
+		// add props adding metadata for incoming functions skipping a constructor
+		for(name in source){
+			t = source[name];
+			if((t !== op[name] || !(name in op)) && name != cname){
+				if(opts.call(t) == "[object Function]"){
+					// non-trivial function method => attach its name
+					t.nom = name;
+				}
+				target[name] = t;
+			}
+		}
+		// process unenumerable methods on IE
+		for(; i < l; ++i){
+			name = d._extraNames[i];
+			t = source[name];
+			if((t !== op[name] || !(name in op)) && name != cname){
+				if(opts.call(t) == "[object Function]"){
+					// non-trivial function method => attach its name
+					t.nom = name;
+				}
+				target[name] = t;
+			}
+		}
+		return target;
+	}
+
+	function extend(source){
+		safeMixin(this.prototype, source);
+		return this;
+	}
+
+	// chained constructor compatible with the legacy dojo.declare()
+	function chainedConstructor(bases, ctorSpecial){
+		return function(){
+			var a = arguments, args = a, a0 = a[0], f, i, m,
+				l = bases.length, preArgs;
+			//this._inherited = {};
+			// perform the shaman's rituals of the original dojo.declare()
+			// 1) call two types of the preamble
+			if(ctorSpecial && (a0 && a0.preamble || this.preamble)){
+				// full blown ritual
+				preArgs = new Array(bases.length);
+				// prepare parameters
+				preArgs[0] = a;
+				for(i = 0;;){
+					// process the preamble of the 1st argument
+					a0 = a[0];
+					if(a0){
+						f = a0.preamble;
+						if(f){
+							a = f.apply(this, a) || a;
+						}
+					}
+					// process the preamble of this class
+					f = bases[i].prototype;
+					f = f.hasOwnProperty("preamble") && f.preamble;
+					if(f){
+						a = f.apply(this, a) || a;
+					}
+					// one pecularity of the preamble:
+					// it is called if it is not needed,
+					// e.g., there is no constructor to call
+					// let's watch for the last constructor
+					// (see ticket #9795)
+					if(++i == l){
+						break;
+					}
+					preArgs[i] = a;
+				}
+			}
+			// 2) call all non-trivial constructors using prepared arguments
+			for(i = l - 1; i >= 0; --i){
+				f = bases[i];
+				m = f._meta;
+				f = m ? m.ctor : f;
+				if(f){
+					f.apply(this, preArgs ? preArgs[i] : a);
+				}
+			}
+			// 3) continue the original ritual: call the postscript
+			f = this.postscript;
+			if(f){
+				f.apply(this, args);
+			}
+		};
+	}
+
+
+	// chained constructor compatible with the legacy dojo.declare()
+	function singleConstructor(ctor, ctorSpecial){
+		return function(){
+			var a = arguments, t = a, a0 = a[0], f;
+			//this._inherited = {};
+			// perform the shaman's rituals of the original dojo.declare()
+			// 1) call two types of the preamble
+			if(ctorSpecial){
+				// full blown ritual
+				if(a0){
+					// process the preamble of the 1st argument
+					f = a0.preamble;
+					if(f){
+						t = f.apply(this, t) || t;
+					}
+				}
+				f = this.preamble;
+				if(f){
+					// process the preamble of this class
+					f.apply(this, t);
+					// one pecularity of the preamble:
+					// it is called even if it is not needed,
+					// e.g., there is no constructor to call
+					// let's watch for the last constructor
+					// (see ticket #9795)
+				}
+			}
+			// 2) call a constructor
+			if(ctor){
+				ctor.apply(this, a);
+			}
+			// 3) continue the original ritual: call the postscript
+			f = this.postscript;
+			if(f){
+				f.apply(this, a);
+			}
+		};
+	}
+
+	// plain vanilla constructor (can use inherited() to call its base constructor)
+	function simpleConstructor(bases){
+		return function(){
+			var a = arguments, i = 0, f;
+			//this._inherited = {};
+			// perform the shaman's rituals of the original dojo.declare()
+			// 1) do not call the preamble
+			// 2) call the top constructor (it can use this.inherited())
+			for(; f = bases[i]; ++i){ // intentional assignment
+				m = f._meta;
+				f = m ? m.ctor : f;
+				if(f){
+					f.apply(this, a);
+					break;
+				}
+			}
+			// 3) call the postscript
+			f = this.postscript;
+			if(f){
+				f.apply(this, a);
+			}
+		};
+	}
+
+	function chain(name, bases, reversed){
+		return function(){
+			var b, m, f, i = 0, step = 1;
+			if(reversed){
+				i = bases.length - 1;
+				step = -1;
+			}
+			for(; b = bases[i]; i += step){ // intentional assignment
+				m = b._meta;
+				f = (m ? m.hidden : b.prototype)[name];
+				if(f){
+					f.apply(this, arguments);
+				}
+			}
+		};
+	}
+
+	d.declare = function(className, superclass, props){
+		var proto, i, t, ctor, name, bases, chains, mixins = 1, parents = superclass;
+
+		// crack parameters
+		if(typeof className != "string"){
+			props = superclass;
+			superclass = className;
+			className = "";
+		}
+		props = props || {};
+
+		// build a prototype
+		if(opts.call(superclass) == "[object Array]"){
+			// C3 MRO
+			bases = c3mro(superclass);
+			t = bases[0];
+			mixins = bases.length - t;
+			superclass = bases[mixins];
+		}else{
+			bases = [0];
+			if(superclass){
+				t = superclass._meta;
+				bases = bases.concat(t ? t.bases : superclass);
+			}
+		}
+		if(superclass){
+			for(i = mixins - 1;; --i){
+				// delegation
+				xtor.prototype = superclass.prototype;
+				proto = new xtor;
+				if(!i){
+					// stop if nothing to add (the last base)
+					break;
+				}
+				// mix in properties
+				t = bases[i];
+				mix(proto, t._meta ? t._meta.hidden : t.prototype);
+				// chain in new constructor
+				ctor = new Function;
+				ctor.superclass = superclass;
+				ctor.prototype = proto;
+				superclass = proto.constructor = ctor;
+			}
+		}else{
+			proto = {};
+		}
+		// add all properties
+		safeMixin(proto, props);
+		// add constructor
+		t = props.constructor;
+		if(t !== op.constructor){
+			t.nom = cname;
+			proto.constructor = t;
+		}
+		xtor.prototype = 0;	// cleanup
+
+		// collect chains and flags
+		for(i = mixins - 1; i; --i){ // intentional assignment
+			t = bases[i]._meta;
+			if(t && t.chains){
+				chains = mix(chains || {}, t.chains);
+			}
+		}
+		if(proto["-chains-"]){
+			chains = mix(chains || {}, proto["-chains-"]);
+		}
+
+		// build ctor
+		t = !chains || !chains.hasOwnProperty(cname);
+		bases[0] = ctor = (chains && chains.constructor === "manual") ? simpleConstructor(bases) :
+			(bases.length == 1 ? singleConstructor(props.constructor, t) : chainedConstructor(bases, t));
+
+		// add meta information to the constructor
+		ctor._meta  = {bases: bases, hidden: props, chains: chains,
+			parents: parents, ctor: props.constructor};
+		ctor.superclass = superclass && superclass.prototype;
+		ctor.extend = extend;
+		ctor.prototype = proto;
+		proto.constructor = ctor;
+
+		// add "standard" methods to the ptototype
+		proto.getInherited = getInherited;
+		proto.inherited = inherited;
+		proto.isInstanceOf = isInstanceOf;
+
+		// add name if specified
+		if(className){
+			proto.declaredClass = className;
+			d.setObject(className, ctor);
+		}
+
+		// build chains and add them to the prototype
+		if(chains){
+			for(name in chains){
+				if(proto[name] && typeof chains[name] == "string" && name != cname){
+					t = proto[name] = chain(name, bases, chains[name] === "after");
+					t.nom = name;
+				}
+			}
+		}
+		// chained methods do not return values
+		// no need to chain "invisible" functions
+
+		return ctor;	// Function
+	};
+
+	d.safeMixin = safeMixin;
+
+	/*=====
+	dojo.declare = function(className, superclass, props){
+		//	summary:
+		//		Create a feature-rich constructor from compact notation.
+		//	className: String?:
+		//		The optional name of the constructor (loosely, a "class")
+		//		stored in the "declaredClass" property in the created prototype.
+		//		It will be used as a global name for a created constructor.
+		//	superclass: Function|Function[]:
+		//		May be null, a Function, or an Array of Functions. This argument
+		//		specifies a list of bases (the left-most one is the most deepest
+		//		base).
+		//	props: Object:
+		//		An object whose properties are copied to the created prototype.
+		//		Add an instance-initialization function by making it a property
+		//		named "constructor".
+		//	returns:
+		//		New constructor function.
+		//	description:
+		//		Create a constructor using a compact notation for inheritance and
+		//		prototype extension.
+		//
+		//		Mixin ancestors provide a type of multiple inheritance.
+		//		Prototypes of mixin ancestors are copied to the new class:
+		//		changes to mixin prototypes will not affect classes to which
+		//		they have been mixed in.
+		//
+		//		Ancestors can be compound classes created by this version of
+		//		dojo.declare. In complex cases all base classes are going to be
+		//		linearized according to C3 MRO algorithm
+		//		(see http://www.python.org/download/releases/2.3/mro/ for more
+		//		details).
+		//
+		//		"className" is cached in "declaredClass" property of the new class,
+		//		if it was supplied. The immediate super class will be cached in
+		//		"superclass" property of the new class.
+		//
+		//		Methods in "props" will be copied and modified: "nom" property
+		//		(the declared name of the method) will be added to all copied
+		//		functions to help identify them for the internal machinery. Be
+		//		very careful, while reusing methods: if you use the same
+		//		function under different names, it can produce errors in some
+		//		cases.
+		//
+		//		It is possible to use constructors created "manually" (without
+		//		dojo.declare) as bases. They will be called as usual during the
+		//		creation of an instance, their methods will be chained, and even
+		//		called by "this.inherited()".
+		//
+		//		Special property "-chains-" governs how to chain methods. It is
+		//		a dictionary, which uses method names as keys, and hint strings
+		//		as values. If a hint string is "after", this method will be
+		//		called after methods of its base classes. If a hint string is
+		//		"before", this method will be called before methods of its base
+		//		classes.
+		//
+		//		If "constructor" is not mentioned in "-chains-" property, it will
+		//		be chained using the legacy mode: using "after" chaining,
+		//		calling preamble() method before each constructor, if available,
+		//		and calling postscript() after all constructors were executed.
+		//		If the hint is "after", it is chained as a regular method, but
+		//		postscript() will be called after the chain of constructors.
+		//		"constructor" cannot be chained "before", but it allows
+		//		a special hint string: "manual", which means that constructors
+		//		are not going to be chained in any way, and programmer will call
+		//		them manually using this.inherited(). In the latter case
+		//		postscript() will be called after the construction.
+		//
+		//		All chaining hints are "inherited" from base classes and
+		//		potentially can be overridden. Be very careful when overriding
+		//		hints! Make sure that all chained methods can work in a proposed
+		//		manner of chaining.
+		//
+		//		Once a method was chained, it is impossible to unchain it. The
+		//		only exception is "constructor". You don't need to define a
+		//		method in order to supply a chaining hint.
+		//
+		//		If a method is chained, it cannot use this.inherited() because
+		//		all other methods in the hierarchy will be called automatically.
+		//
+		//		Usually constructors and initializers of any kind are chained
+		//		using "after" and destructors of any kind are chained as
+		//		"before". Note that chaining assumes that chained methods do not
+		//		return any value: any returned value will be discarded.
+		//
+		//	example:
+		//	|	dojo.declare("my.classes.bar", my.classes.foo, {
+		//	|		// properties to be added to the class prototype
+		//	|		someValue: 2,
+		//	|		// initialization function
+		//	|		constructor: function(){
+		//	|			this.myComplicatedObject = new ReallyComplicatedObject();
+		//	|		},
+		//	|		// other functions
+		//	|		someMethod: function(){
+		//	|			doStuff();
+		//	|		}
+		//	|	});
+		//
+		//	example:
+		//	|	var MyBase = dojo.declare(null, {
+		//	|		// constructor, properties, and methods go here
+		//	|		// ...
+		//	|	});
+		//	|	var MyClass1 = dojo.declare(MyBase, {
+		//	|		// constructor, properties, and methods go here
+		//	|		// ...
+		//	|	});
+		//	|	var MyClass2 = dojo.declare(MyBase, {
+		//	|		// constructor, properties, and methods go here
+		//	|		// ...
+		//	|	});
+		//	|	var MyDiamond = dojo.declare([MyClass1, MyClass2], {
+		//	|		// constructor, properties, and methods go here
+		//	|		// ...
+		//	|	});
+		//
+		//	example:
+		//	|	var F = function(){ console.log("raw constructor"); };
+		//	|	F.prototype.method = function(){
+		//	|		console.log("raw method");
+		//	|	};
+		//	|	var A = dojo.declare(F, {
+		//	|		constructor: function(){
+		//	|			console.log("A.constructor");
+		//	|		},
+		//	|		method: function(){
+		//	|			console.log("before calling F.method...");
+		//	|			this.inherited(arguments);
+		//	|			console.log("...back in A");
+		//	|		}
+		//	|	});
+		//	|	new A().method();
+		//	|	// will print:
+		//	|	// raw constructor
+		//	|	// A.constructor
+		//	|	// before calling F.method...
+		//	|	// raw method
+		//	|	// ...back in A
+		//
+		//	example:
+		//	|	var A = dojo.declare(null, {
+		//	|		"-chains-": {
+		//	|			destroy: "before"
+		//	|		}
+		//	|	});
+		//	|	var B = dojo.declare(A, {
+		//	|		constructor: function(){
+		//	|			console.log("B.constructor");
+		//	|		},
+		//	|		destroy: function(){
+		//	|			console.log("B.destroy");
+		//	|		}
+		//	|	});
+		//	|	var C = dojo.declare(B, {
+		//	|		constructor: function(){
+		//	|			console.log("C.constructor");
+		//	|		},
+		//	|		destroy: function(){
+		//	|			console.log("C.destroy");
+		//	|		}
+		//	|	});
+		//	|	new C().destroy();
+		//	|	// prints:
+		//	|	// B.constructor
+		//	|	// C.constructor
+		//	|	// C.destroy
+		//	|	// B.destroy
+		//
+		//	example:
+		//	|	var A = dojo.declare(null, {
+		//	|		"-chains-": {
+		//	|			constructor: "manual"
+		//	|		}
+		//	|	});
+		//	|	var B = dojo.declare(A, {
+		//	|		constructor: function(){
+		//	|			// ...
+		//	|			// call the base constructor with new parameters
+		//	|			this.inherited(arguments, [1, 2, 3]);
+		//	|			// ...
+		//	|		}
+		//	|	});
+		//
+		//	example:
+		//	|	var A = dojo.declare(null, {
+		//	|		"-chains-": {
+		//	|			m1: "before"
+		//	|		},
+		//	|		m1: function(){
+		//	|			console.log("A.m1");
+		//	|		},
+		//	|		m2: function(){
+		//	|			console.log("A.m2");
+		//	|		}
+		//	|	});
+		//	|	var B = dojo.declare(A, {
+		//	|		"-chains-": {
+		//	|			m2: "after"
+		//	|		},
+		//	|		m1: function(){
+		//	|			console.log("B.m1");
+		//	|		},
+		//	|		m2: function(){
+		//	|			console.log("B.m2");
+		//	|		}
+		//	|	});
+		//	|	var x = new B();
+		//	|	x.m1();
+		//	|	// prints:
+		//	|	// B.m1
+		//	|	// A.m1
+		//	|	x.m2();
+		//	|	// prints:
+		//	|	// A.m2
+		//	|	// B.m2
+		return new Function(); // Function
+	};
+	=====*/
+
+	/*=====
+	dojo.safeMixin = function(target, source){
+		//	summary:
+		//		Mix in properties skipping a constructor and decorating functions
+		//		like it is done by dojo.declare.
+		//	target: Object
+		//		Target object to accept new properties.
+		//	source: Object
+		//		Source object for new properties.
+		//	description:
+		//		This function is used to mix in properties like dojo._mixin does,
+		//		but it skips a constructor property and decorates functions like
+		//		dojo.declare does.
+		//
+		//		It is meant to be used with classes and objects produced with
+		//		dojo.declare. Functions mixed in with dojo.safeMixin can use
+		//		this.inherited() like normal methods.
+		//
+		//		This function is used to implement extend() method of a constructor
+		//		produced with dojo.declare().
+		//
+		//	example:
+		//	|	var A = dojo.declare(null, {
+		//	|		m1: function(){
+		//	|			console.log("A.m1");
+		//	|		},
+		//	|		m2: function(){
+		//	|			console.log("A.m2");
+		//	|		}
+		//	|	});
+		//	|	var B = dojo.declare(A, {
+		//	|		m1: function(){
+		//	|			this.inherited(arguments);
+		//	|			console.log("B.m1");
+		//	|		}
+		//	|	});
+		//	|	B.extend({
+		//	|		m2: function(){
+		//	|			this.inherited(arguments);
+		//	|			console.log("B.m2");
+		//	|		}
+		//	|	});
+		//	|	var x = new B();
+		//	|	dojo.safeMixin(x, {
+		//	|		m1: function(){
+		//	|			this.inherited(arguments);
+		//	|			console.log("X.m1");
+		//	|		},
+		//	|		m2: function(){
+		//	|			this.inherited(arguments);
+		//	|			console.log("X.m2");
+		//	|		}
+		//	|	});
+		//	|	x.m2();
+		//	|	// prints:
+		//	|	// A.m1
+		//	|	// B.m1
+		//	|	// X.m1
+	};
+	=====*/
+
+	/*=====
+	Object.inherited = function(name, args, newArgs){
+		//	summary:
+		//		Calls a super method.
+		//	name: String?
+		//		The optional method name. Should be the same as the caller's
+		//		name. Usually "name" is specified in complex dynamic cases, when
+		//		the calling method was dynamically added, undecorated by
+		//		dojo.declare, and it cannot be determined.
+		//	args: Arguments
+		//		The caller supply this argument, which should be the original
+		//		"arguments".
+		//	newArgs: Object?
+		//		If "true", the found function will be returned without
+		//		executing it.
+		//		If Array, it will be used to call a super method. Otherwise
+		//		"args" will be used.
+		//	returns:
+		//		Whatever is returned by a super method, or a super method itself,
+		//		if "true" was specified as newArgs.
+		//	description:
+		//		This method is used inside method of classes produced with
+		//		dojo.declare to call a super method (next in the chain). It is
+		//		used for manually controlled chaining. Consider using the regular
+		//		chaining, because it is faster. Use "this.inherited()" only in
+		//		complex cases.
+		//
+		//		This method cannot me called from automatically chained
+		//		constructors including the case of a special (legacy)
+		//		constructor chaining. It cannot be called from chained methods.
+		//
+		//		If "this.inherited()" cannot find the next-in-chain method, it
+		//		does nothing and returns "undefined". The last method in chain
+		//		can be a default method implemented in Object, which will be
+		//		called last.
+		//
+		//		If "name" is specified, it is assumed that the method that
+		//		received "args" is the parent method for this call. It is looked
+		//		up in the chain list and if it is found the next-in-chain method
+		//		is called. If it is not found, the first-in-chain method is
+		//		called.
+		//
+		//		If "name" is not specified, it will be derived from the calling
+		//		method (using a methoid property "nom").
+		//
+		//	example:
+		//	|	var B = dojo.declare(A, {
+		//	|		method1: function(a, b, c){
+		//	|			this.inherited(arguments);
+		//	|		},
+		//	|		method2: function(a, b){
+		//	|			return this.inherited(arguments, [a + b]);
+		//	|		}
+		//	|	});
+		//	|	// next method is not in the chain list because it is added
+		//	|	// manually after the class was created.
+		//	|	B.prototype.method3 = function(){
+		//	|		console.log("This is a dynamically-added method.");
+		//	|		this.inherited("method3", arguments);
+		//	|	};
+		//	example:
+		//	|	var B = dojo.declare(A, {
+		//	|		method: function(a, b){
+		//	|			var super = this.inherited(arguments, true);
+		//	|			// ...
+		//	|			if(!super){
+		//	|				console.log("there is no super method");
+		//	|				return 0;
+		//	|			}
+		//	|			return super.apply(this, arguments);
+		//	|		}
+		//	|	});
+		return	{};	// Object
+	}
+	=====*/
+
+	/*=====
+	Object.getInherited = function(name, args){
+		//	summary:
+		//		Returns a super method.
+		//	name: String?
+		//		The optional method name. Should be the same as the caller's
+		//		name. Usually "name" is specified in complex dynamic cases, when
+		//		the calling method was dynamically added, undecorated by
+		//		dojo.declare, and it cannot be determined.
+		//	args: Arguments
+		//		The caller supply this argument, which should be the original
+		//		"arguments".
+		//	returns:
+		//		Returns a super method (Function) or "undefined".
+		//	description:
+		//		This method is a convenience method for "this.inherited()".
+		//		It uses the same algorithm but instead of executing a super
+		//		method, it returns it, or "undefined" if not found.
+		//
+		//	example:
+		//	|	var B = dojo.declare(A, {
+		//	|		method: function(a, b){
+		//	|			var super = this.getInherited(arguments);
+		//	|			// ...
+		//	|			if(!super){
+		//	|				console.log("there is no super method");
+		//	|				return 0;
+		//	|			}
+		//	|			return super.apply(this, arguments);
+		//	|		}
+		//	|	});
+		return	{};	// Object
+	}
+	=====*/
+
+	/*=====
+	Object.isInstanceOf = function(cls){
+		//	summary:
+		//		Checks the inheritance cahin to see if it is inherited from this
+		//		class.
+		//	cls: Function
+		//		Class constructor.
+		//	returns:
+		//		"true", if this object is inherited from this class, "false"
+		//		otherwise.
+		//	description:
+		//		This method is used with instances of classes produced with
+		//		dojo.declare to determine of they support a certain interface or
+		//		not. It models "instanceof" operator.
+		//
+		//	example:
+		//	|	var A = dojo.declare(null, {
+		//	|		// constructor, properties, and methods go here
+		//	|		// ...
+		//	|	});
+		//	|	var B = dojo.declare(null, {
+		//	|		// constructor, properties, and methods go here
+		//	|		// ...
+		//	|	});
+		//	|	var C = dojo.declare([A, B], {
+		//	|		// constructor, properties, and methods go here
+		//	|		// ...
+		//	|	});
+		//	|	var D = dojo.declare(A, {
+		//	|		// constructor, properties, and methods go here
+		//	|		// ...
+		//	|	});
+		//	|
+		//	|	var a = new A(), b = new B(), c = new C(), d = new D();
+		//	|
+		//	|	console.log(a.isInstanceOf(A)); // true
+		//	|	console.log(b.isInstanceOf(A)); // false
+		//	|	console.log(c.isInstanceOf(A)); // true
+		//	|	console.log(d.isInstanceOf(A)); // true
+		//	|
+		//	|	console.log(a.isInstanceOf(B)); // false
+		//	|	console.log(b.isInstanceOf(B)); // true
+		//	|	console.log(c.isInstanceOf(B)); // true
+		//	|	console.log(d.isInstanceOf(B)); // false
+		//	|
+		//	|	console.log(a.isInstanceOf(C)); // false
+		//	|	console.log(b.isInstanceOf(C)); // false
+		//	|	console.log(c.isInstanceOf(C)); // true
+		//	|	console.log(d.isInstanceOf(C)); // false
+		//	|
+		//	|	console.log(a.isInstanceOf(D)); // false
+		//	|	console.log(b.isInstanceOf(D)); // false
+		//	|	console.log(c.isInstanceOf(D)); // false
+		//	|	console.log(d.isInstanceOf(D)); // true
+		return	{};	// Object
+	}
+	=====*/
+
+	/*=====
+	Object.extend = function(source){
+		//	summary:
+		//		Adds all properties and methods of source to constructor's
+		//		prototype, making them available to all instances created with
+		//		constructor. This method is specific to constructors created with
+		//		dojo.declare.
+		//	source: Object
+		//		Source object which properties are going to be copied to the
+		//		constructor's prototype.
+		//	description:
+		//		Adds source properties to the constructor's prototype. It can
+		//		override existing properties.
+		//
+		//		This method is similar to dojo.extend function, but it is specific
+		//		to constructors produced by dojo.declare. It is implemented
+		//		using dojo.safeMixin, and it skips a constructor property,
+		//		and properly decorates copied functions.
+		//
+		//	example:
+		//	|	var A = dojo.declare(null, {
+		//	|		m1: function(){},
+		//	|		s1: "Popokatepetl"
+		//	|	});
+		//	|	A.extend({
+		//	|		m1: function(){},
+		//	|		m2: function(){},
+		//	|		f1: true,
+		//	|		d1: 42
+		//	|	});
+	};
+	=====*/
+})();
+
+return dojo._base.declare; });
+require.def("dojo/_base/connect", ["require", "dojo", "dijit", "dojox", "dojo/_base/lang"], function(require, dojo, dijit, dojox, _R0) {
+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:
+	//		`dojo.connect` is the core event handling and delegation method in
+	//		Dojo. It allows one function to "listen in" on the execution of
+	//		any other, triggering the second whenever the first is called. Many
+	//		listeners may be attached to a function, and source functions may
+	//		be either regular function calls or DOM events.
+	//
+	// description:
+	//		Connects listeners to actions, so that after event fires, a
+	//		listener is called with the same arguments passed to the orginal
+	//		function.
+	//
+	//		Since `dojo.connect` allows the source of events to be either a
+	//		"regular" JavaScript function or a DOM event, it provides a uniform
+	//		interface for listening to all the types of events that an
+	//		application is likely to deal with though a single, unified
+	//		interface. DOM programmers may want to think of it as
+	//		"addEventListener for everything and anything".
+	//
+	//		When setting up a connection, the `event` parameter must be a
+	//		string that is the name of the method/event to be listened for. If
+	//		`obj` is null, `dojo.global` is assumed, meaning that connections
+	//		to global methods are supported but also that you may inadvertantly
+	//		connect to a global by passing an incorrect object name or invalid
+	//		reference.
+	//
+	//		`dojo.connect` generally is forgiving. If you pass the name of a
+	//		function or method that does not yet exist on `obj`, connect will
+	//		not fail, but will instead set up a stub method. Similarly, null
+	//		arguments may simply be omitted such that fewer than 4 arguments
+	//		may be required to set up a connection See the examples for deails.
+	//
+	//		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
+};
+
+return dojo._base.connect; });
+require.def("dojo/_base/Deferred", ["require", "dojo", "dijit", "dojox", "dojo/_base/lang"], function(require, dojo, dijit, dojox, _R0) {
+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;
+	this.isFiring = 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.isFiring){
+			this._fire();
+		}
+		return this; // dojo.Deferred
+	},
+
+	_fire: function(){
+		// summary: 
+		//		Used internally to exhaust the callback sequence when a result
+		//		is available.
+		this.isFiring = true;
+		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;
+		this.isFiring = false;
+		if((cb)&&(this.paused)){
+			// this is for "tail recursion" in case the dependent
+			// deferred is already fired
+			res.addBoth(cb);
+		}
+	}
+});
+
+return dojo._base.Deferred; });
+require.def("dojo/_base/json", ["require", "dojo", "dijit", "dojox"], function(require, dojo, dijit, dojox) {
+dojo.provide("dojo._base.json");
+
+dojo.fromJson = function(/*String*/ json){
+	// summary:
+	// 		Parses a [JSON](http://json.org) string to return a JavaScript object.
+	// description:
+	// 		Throws for invalid JSON strings, but it does not use a strict JSON parser. It
+	// 		delegates to eval().
+	// 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.
+	//	example:
+	//		simple serialization of a trivial object
+	//		|	var jsonStr = dojo.toJson({ howdy: "stranger!", isStrange: true });
+	//		|	doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr);
+	//	example:
+	//		a custom serializer for an objects of a particular class:
+	//		|	dojo.declare("Furby", null, {
+	//		|		furbies: "are strange",
+	//		|		furbyCount: 10,
+	//		|		__json__: function(){
+	//		|		},
+	//		|	});
+
+	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){
+		// console.log(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
+}
+
+return dojo._base.json; });
+require.def("dojo/_base/Color", ["require", "dojo", "dijit", "dojox", "dojo/_base/array", "dojo/_base/lang"], function(require, dojo, dijit, dojox, _R0, _R1) {
+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;
+		//	 | console.log(n.toString()); // 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],
+		transparent: d.config.transparentColor || [255,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:
+			//		Ensures the object has correct attributes
+			// description:
+			//		the default implementation does nothing, include dojo.colors to
+			//		augment it with real checks
+			return this;	// dojo.Color
+		},
+		toRgb: function(){
+			// summary:
+			//		Returns 3 component array of rgb values
+			// example:
+			//	|	var c = new dojo.Color("#000000");
+			//	| 	console.log(c.toRgb()); // [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 from the color
+			//		represented by this object.
+			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:
+			//	| 	console.log(new dojo.Color([0,0,0]).toHex()); // #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();
+			//	|	console.log(c); // 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:
+		//		Returns a `dojo.Color` instance from a string of the form
+		//		"rgb(...)" or "rgba(...)". Optionally accepts a `dojo.Color`
+		//		object to update with the parsed value and return instead of
+		//		creating a new object.
+		// returns:
+		//		A dojo.Color object. If obj is passed, it will be the return value.
+		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. Optionally accepts a
+		//		`dojo.Color` object to update with the parsed value.
+		//
+		// returns:
+		//		A dojo.Color object. If obj is passed, it will be the return value.
+		//
+		// 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 `dojo.Color` from a 3 or 4 element array, mapping each
+		//		element in sequence to the rgb(a) values of the color.
+		// example:
+		//		| var myColor = dojo.colorFromArray([237,237,237,0.5]); // grey, 50% alpha 
+		// returns:
+		//		A dojo.Color object. If obj is passed, it will be the return value.
+		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. Accepts hex, rgb, and rgba
+		//		style color values.
+		// 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);
+	};
+})();
+
+return dojo._base.Color; });
+require.def("dojo/_base/window", ["require", "dojo", "dijit", "dojox"], function(require, dojo, dijit, dojox) {
+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,
+		oldQ = dojo.isQuirks;
+
+	try{
+		dojo.doc = documentObject;
+		delete dojo._bodyLtr; // uncache
+		dojo.isQuirks = dojo.doc.compatMode == "BackCompat"; // no need to check for QuirksMode which was Opera 7 only
+
+		if(thisObject && typeof callback == "string"){
+			callback = thisObject[callback];
+		}
+
+		return callback.apply(thisObject, cbArguments || []);
+	}finally{
+		dojo.doc = oldDoc;
+		delete dojo._bodyLtr; // in case it was undefined originally, and set to true/false by the alternate document
+		if(oldLtr !== undefined){ dojo._bodyLtr = oldLtr; }
+		dojo.isQuirks = oldQ;
+	}
+};
+	
+
+return dojo._base.window; });
+require.def("dojo/_base/event", ["require", "dojo", "dijit", "dojox", "dojo/_base/connect"], function(require, dojo, dijit, dojox, _R0) {
+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.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,
+		META: dojo.isSafari ? 91 : 224,		// the apple key on macs
+		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,
+		// virtual key mapping
+		copyKey: dojo.isMac && !dojo.isAIR ? (dojo.isSafari ? 91 : 224 ) : 17
+	};
+	
+	var evtCopyKey = dojo.isMac ? "metaKey" : "ctrlKey";
+	
+	dojo.isCopyKey = function(e){
+		// summary:
+		//		Checks an event for the copy key (meta on Mac, and ctrl anywhere else)
+		// e: Event
+		//		Event object to examine
+		return e[evtCopyKey];	// Boolean
+	};
+
+	// Public: decoding mouse buttons from events
+
+/*=====
+	dojo.mouseButtons = {
+		// LEFT: Number
+		//		Numeric value of the left mouse button for the platform.
+		LEFT:   0,
+		// MIDDLE: Number
+		//		Numeric value of the middle mouse button for the platform.
+		MIDDLE: 1,
+		// RIGHT: Number
+		//		Numeric value of the right mouse button for the platform.
+		RIGHT:  2,
+	
+		isButton: function(e, button){
+			// summary:
+			//		Checks an event object for a pressed button
+			// e: Event
+			//		Event object to examine
+			// button: Number
+			//		The button value (example: dojo.mouseButton.LEFT)
+			return e.button == button; // Boolean
+		},
+		isLeft: function(e){
+			// summary:
+			//		Checks an event object for the pressed left button
+			// e: Event
+			//		Event object to examine
+			return e.button == 0; // Boolean
+		},
+		isMiddle: function(e){
+			// summary:
+			//		Checks an event object for the pressed middle button
+			// e: Event
+			//		Event object to examine
+			return e.button == 1; // Boolean
+		},
+		isRight: function(e){
+			// summary:
+			//		Checks an event object for the pressed right button
+			// e: Event
+			//		Event object to examine
+			return e.button == 2; // Boolean
+		}
+	};
+=====*/
+
+		if(dojo.isIE){
+		dojo.mouseButtons = {
+			LEFT:   1,
+			MIDDLE: 4,
+			RIGHT:  2,
+			// helper functions
+			isButton: function(e, button){ return e.button & button; },
+			isLeft:   function(e){ return e.button & 1; },
+			isMiddle: function(e){ return e.button & 4; },
+			isRight:  function(e){ return e.button & 2; }
+		};
+	}else{
+			dojo.mouseButtons = {
+			LEFT:   0,
+			MIDDLE: 1,
+			RIGHT:  2,
+			// helper functions
+			isButton: function(e, button){ return e.button == button; },
+			isLeft:   function(e){ return e.button == 0; },
+			isMiddle: function(e){ return e.button == 1; },
+			isRight:  function(e){ return e.button == 2; }
+		};
+		}
+	
+		// 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<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)); };
+	}
+}
+
+return dojo._base.event; });
+;
+require.def("dojo/_base/html", ["require", "dojo", "dijit", "dojox"], function(require, dojo, dijit, dojox) {
+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. 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, and use it.
+	//	|	var n = dojo.byId("bar");
+	//	|	if(n){ doStuff() ... }
+	//
+	//	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(typeof id != "string"){
+			return id;
+		}
+		var _d = doc || dojo.doc, 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{
+	dojo.byId = function(id, doc){
+		// inline'd type check
+		return (typeof id == "string") ? (doc || dojo.doc).getElementById(id) : id; // DomNode
+	};
+}
+/*=====
+};
+=====*/
+
+(function(){
+	var d = dojo;
+	var byId = d.byId;
+
+	var _destroyContainer = null,
+		_destroyDoc;
+		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 = byId(node);
+		try{
+			var doc = node.ownerDocument;
+			// cannot use _destroyContainer.ownerDocument since this can throw an exception on IE
+			if(!_destroyContainer || _destroyDoc != doc){
+				_destroyContainer = doc.createElement("div");
+				_destroyDoc = doc;
+			}
+			_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
+		//
+		// example:
+		//	Test is node id="bar" is a descendant of node id="foo"
+		//	|	if(dojo.isDescendant("bar", "foo")){ ... }
+		try{
+			node = byId(node);
+			ancestor = 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.
+		//	example:
+		//	Make the node id="bar" unselectable
+		//	|	dojo.setSelectable("bar"); 
+		//	example:
+		//	Make the node id="bar" selectable
+		//	|	dojo.setSelectable("bar", true);
+		node = 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 the first argument resolved to a DOM node.
+		//
+		//	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("<div></div>", dojo.body());
+		//
+		// example:
+		//		Put a new LI as the first child of a list by id:
+		//	|	dojo.place("<li></li>", "someUl", "first");
+
+		refNode = byId(refNode);
+		if(typeof node == "string"){ // inline'd type check
+			node = node.charAt(0) == "<" ? d._toDom(node, refNode.ownerDocument) : byId(node);
+		}
+		if(typeof position == "number"){ // inline'd type check
+			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*/){
+		// client code may have to adjust if compatMode varies across iframes
+		d.boxModel = document.compatMode == "BackCompat" ? "border-box" : "content-box";
+	}
+	
+	// =============================
+	// 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()`, 
+		//		`dojo.contentBox()` or `dojo.position()`.
+		//	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 = 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 && typeof style != "string"){ // inline'd type check
+			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.
+		//	description:
+		//		Returns an object with `w`, `h`, `l`, `t` properties:
+		//	|		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.
+		//	description:
+		// 		* 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.
+		// description:
+		//		* 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:
+		//		left offset from parent.
+		//	t:
+		//		top offset from parent.
+		//	w:
+		//		width in current box model.
+		//	h:
+		//		width in current box model.
+		//	u:
+		//		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:
+		//		Getter/setter for the margin-box of node.
+		//		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.
+		//	example:
+		//	Retrieve the marginbox of a passed node
+		//	|	var box = dojo.marginBox("someNodeId");
+		//	|	console.dir(box);
+		//
+		//	example:
+		//	Set a node's marginbox to the size of another node
+		//	|	var box = dojo.marginBox("someNodeId");
+		//	|	dojo.marginBox("someOtherNode", box);
+		
+		var n = 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 = 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 n = d.global;
+		return "pageXOffset" in n? { x:n.pageXOffset, y:n.pageYOffset } :
+			(n=d.doc.documentElement, n.clientHeight? { x:d._fixIeBiDiScrollLeft(n.scrollLeft), y:n.scrollTop } :
+			(n=d.body(), { x:n.scrollLeft||0, y:n.scrollTop||0 }));
+	};
+
+	dojo._isBodyLtr = function(){
+		return "_bodyLtr" in d? d._bodyLtr :
+			d._bodyLtr = (d.body().dir || d.doc.documentElement.dir || "ltr").toLowerCase() == "ltr"; // Boolean 
+	}
+
+		dojo._getIeDocumentElementOffset = function(){
+		//	summary:
+		//		returns the offset in x and y from the document body to the
+		//		visual edge of the page
+		//	description:
+		// 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; // only deal with HTML element here, _abs handles body/quirks 
+
+		if(d.isIE < 8){
+			var r = de.getBoundingClientRect(); // works well for IE6+
+			//console.debug('rect left,top = ' + r.left+','+r.top + ', html client left/top = ' + de.clientLeft+','+de.clientTop + ', rtl = ' + (!d._isBodyLtr()) + ', quirks = ' + d.isQuirks);
+			var l = r.left,
+			    t = r.top;
+			if(d.isIE < 7){
+				l += de.clientLeft;	// scrollbar size in strict/RTL, or,
+				t += de.clientTop;	// HTML border size in strict
+			}
+			return {
+				x: l < 0? 0 : l, // FRAME element border size can lead to inaccurate negative values
+				y: t < 0? 0 : t
+			};
+		}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 = d.isQuirks ? dd.body : dd.documentElement;
+			return scrollLeft + de.clientWidth - de.scrollWidth; // Integer
+		}
+				return scrollLeft; // Integer
+	}
+
+	// FIXME: need a setter for coords or a moveTo!!
+	dojo._abs = dojo.position = function(/*DomNode*/node, /*Boolean?*/includeScroll){
+		//	summary:
+		//		Gets the position and size of the passed element relative to
+		//		the viewport (if includeScroll==false), or relative to the
+		//		document root (if includeScroll==true).
+		//
+		//	description:
+		//		Returns an object of the form:
+		//			{ x: 100, y: 300, w: 20, h: 15 }
+		//		If includeScroll==true, the x and y values will include any
+		//		document offsets that may affect the position relative to the
+		//		viewport.
+		//		Uses the border-box model (inclusive of border and padding but
+		//		not margin).  Does not act as a setter.
+
+		var db = d.body(), dh = db.parentNode, ret;
+		node = byId(node);
+		if(node["getBoundingClientRect"]){
+			// IE6+, FF3+, super-modern WebKit, and Opera 9.6+ all take this branch
+			ret = node.getBoundingClientRect();
+			ret = { x: ret.left, y: ret.top, w: ret.right - ret.left, h: ret.bottom - ret.top };
+					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+db.offsetLeft : 0);
+				ret.y -= offset.y + (d.isQuirks ? db.clientTop+db.offsetTop : 0);
+			}else if(d.isFF == 3){
+				// In FF3 you have to subtract the document element margins.
+				// Fixed in FF3.5 though.
+				var cs = gcs(dh);
+				ret.x -= px(dh, cs.marginLeft) + px(dh, cs.borderLeftWidth);
+				ret.y -= px(dh, cs.marginTop) + px(dh, cs.borderTopWidth);
+			}
+				}else{
+			// FF2 and older WebKit
+			ret = {
+				x: 0,
+				y: 0,
+				w: node.offsetWidth,
+				h: node.offsetHeight
+			};
+			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.isMoz){
+							// 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.isMoz && 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
+	}
+
+	dojo.coords = function(/*DomNode|String*/node, /*Boolean?*/includeScroll){
+		//	summary:
+		//		Deprecated: Use position() for border-box x/y/w/h
+		//		or marginBox() for margin-box w/h/l/t.
+		//		Returns an object representing a node's size and position.
+		//
+		//	description:
+		//		Returns an object that measures margin-box (w)idth/(h)eight
+		//		and absolute position x/y of the border-box. Also returned
+		//		is computed (l)eft and (t)op values in pixels from the
+		//		node's offsetParent as returned from marginBox().
+		//		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.position().
+		var n = byId(node), s = gcs(n), mb = d._getMarginBox(n, s);
+		var abs = d.position(n, includeScroll);
+		mb.x = abs.x;
+		mb.y = abs.y;
+		return mb;
+	}
+
+	// =============================
+	// Element attribute Functions
+	// =============================
+
+	// dojo.attr() should conform to http://www.w3.org/TR/DOM-Level-2-Core/
+
+	var _propNames = {
+			// properties renamed to avoid clashes with reserved words
+			"class":   "className",
+			"for":     "htmlFor",
+			// properties written as camelCase
+			tabindex:  "tabIndex",
+			readonly:  "readOnly",
+			colspan:   "colSpan",
+			frameborder: "frameBorder",
+			rowspan:   "rowSpan",
+			valuetype: "valueType"
+		},
+		_attrNames = {
+			// original attribute names
+			classname: "class",
+			htmlfor:   "for",
+			// for IE
+			tabindex:  "tabIndex",
+			readonly:  "readOnly"
+		},
+		_forcePropNames = {
+			innerHTML: 1,
+			className: 1,
+			htmlFor:   d.isIE,
+			value:     1
+		};
+
+	var _fixAttrName = function(/*String*/ name){
+		return _attrNames[name.toLowerCase()] || name;
+	};
+
+	var _hasAttr = function(node, name){
+		var attr = node.getAttributeNode && node.getAttributeNode(name);
+		return attr && attr.specified; // Boolean
+	};
+
+	// There is a difference in the presence of certain properties and their default values
+	// between browsers. For example, on IE "disabled" is present on all elements,
+	// but it is value is "false"; "tabIndex" of <div> returns 0 by default on IE, yet other browsers
+	// can return -1.
+
+	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
+		var lc = name.toLowerCase();
+		return _forcePropNames[_propNames[lc] || name] || _hasAttr(byId(node), _attrNames[lc] || name);	// 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 argument 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, the DOM node
+		//
+		//	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 = byId(node);
+		var args = arguments.length, prop;
+		if(args == 2 && typeof name != "string"){ // inline'd type check
+			// the object form of setter: the 2nd argument is a dictionary
+			for(var x in name){
+				d.attr(node, x, name[x]);
+			}
+			return node; // DomNode
+		}
+		var lc = name.toLowerCase(),
+			propName = _propNames[lc] || name,
+			forceProp = _forcePropNames[propName],
+			attrName = _attrNames[lc] || name;
+		if(args == 3){
+			// setter
+			do{
+				if(propName == "style" && typeof value != "string"){ // inline'd type check
+					// special case: setting a style
+					d.style(node, value);
+					break;
+				}
+				if(propName == "innerHTML"){
+					// special case: assigning HTML
+										if(d.isIE && node.tagName.toLowerCase() in _roInnerHtml){
+						d.empty(node);
+						node.appendChild(d._toDom(value, node.ownerDocument));
+					}else{
+											node[propName] = value;
+										}
+										break;
+				}
+				if(d.isFunction(value)){
+					// special case: assigning an event handler
+					// 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][propName];
+					if(h){
+						d.disconnect(h);
+					}else{
+						try{
+							delete node[propName];
+						}catch(e){}
+					}
+					// ensure that event objects are normalized, etc.
+					_evtHdlrMap[attrId][propName] = d.connect(node, propName, value);
+					break;
+				}
+				if(forceProp || typeof value == "boolean"){
+					// special case: forcing assignment to the property
+					// special case: setting boolean to a property instead of attribute
+					node[propName] = value;
+					break;
+				}
+				// node's attribute
+				node.setAttribute(attrName, value);
+			}while(false);
+			return node; // DomNode
+		}
+		// getter
+		// should we access this attribute via a property or
+		// via getAttribute()?
+		value = node[propName];
+		if(forceProp && typeof value != "undefined"){
+			// node's property
+			return value;	// Anything
+		}
+		if(propName != "href" && (typeof value == "boolean" || d.isFunction(value))){
+			// node's property
+			return value;	// Anything
+		}
+		// node's attribute
+		// we need _hasAttr() here to guard against IE returning a default value
+		return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
+	}
+
+	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
+		byId(node).removeAttribute(_fixAttrName(name));
+	}
+
+	dojo.getNodeProp = function(/*DomNode|String*/ node, /*String*/ name){
+		//	summary:
+		//		Returns an effective value of a property or an attribute.
+		//	node:
+		//		id or reference to the element to remove the attribute from
+		//	name:
+		//		the name of the attribute
+		node = byId(node);
+		var lc = name.toLowerCase(),
+			propName = _propNames[lc] || name;
+		if((propName in node) && propName != "href"){
+			// node's property
+			return node[propName];	// Anything
+		}
+		// node's attribute
+		var attrName = _attrNames[lc] || name;
+		return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
+	}
+
+	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){ console.log('clicked', e.target) })
+		//	|		.place("#someNode"); // redundant, but cleaner.
+
+		var doc = d.doc;
+		if(refNode){
+			refNode = byId(refNode);
+			doc = refNode.ownerDocument;
+		}
+		if(typeof tag == "string"){ // inline'd type check
+			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 = byId(node);
+			for(var c; c = node.lastChild;){ // intentional assignment
+				d.destroy(c);
+			}
+		} :
+				function(node){
+			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:
+		//	Do something if a node with id="someNode" has class="aSillyClassName" present
+		//	|	if(dojo.hasClass("someNode","aSillyClassName")){ ... }
+
+		return ((" "+ byId(node)[_className] +" ").indexOf(" " + classStr + " ") >= 0);  // Boolean
+	};
+
+	var spaces = /\s+/, a1 = [""],
+		str2array = function(s){
+			if(typeof s == "string" || s instanceof String){
+				if(s.indexOf(" ") < 0){
+					a1[0] = s;
+					return a1;
+				}else{
+					return s.split(spaces);
+				}
+			}
+			// assumed to be an array
+			return s;
+		};
+
+	dojo.addClass = function(/*DomNode|String*/node, /*String|Array*/classStr){
+		//	summary:
+		//		Adds the specified classes to the end of the class list on the
+		//		passed node. Will not re-apply duplicate classes.
+		//
+		//	node:
+		//		String ID or DomNode reference to add a class string too
+		//
+		//	classStr:
+		//		A String class name to add, or several space-separated class names,
+		//		or an array of class names.
+		//
+		// example:
+		//	Add a class to some node:
+		//	|	dojo.addClass("someNode", "anewClass");
+		//
+		// example:
+		//	Add two classes at once:
+		//	|	dojo.addClass("someNode", "firstClass secondClass");
+		//
+		// example:
+		//	Add two classes at once (using array):
+		//	|	dojo.addClass("someNode", ["firstClass", "secondClass"]);
+		//
+		// example:
+		//	Available in `dojo.NodeList` for multiple additions
+		//	|	dojo.query("ul > li").addClass("firstLevel");
+
+		node = byId(node);
+		classStr = str2array(classStr);
+		var cls = " " + node[_className] + " ";
+		for(var i = 0, len = classStr.length, c; i < len; ++i){
+			c = classStr[i];
+			if(c && cls.indexOf(" " + c + " ") < 0){
+				cls += c + " ";
+			}
+		}
+		node[_className] = d.trim(cls);
+	};
+
+	dojo.removeClass = function(/*DomNode|String*/node, /*String|Array?*/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.
+		//
+		// classStr:
+		//		An optional String class name to remove, or several space-separated
+		//		class names, or an array of class names. If omitted, all class names
+		//		will be deleted.
+		//
+		// example:
+		//	Remove a class from some node:
+		//	|	dojo.removeClass("someNode", "firstClass");
+		//
+		// example:
+		//	Remove two classes from some node:
+		//	|	dojo.removeClass("someNode", "firstClass secondClass");
+		//
+		// example:
+		//	Remove two classes from some node (using array):
+		//	|	dojo.removeClass("someNode", ["firstClass", "secondClass"]);
+		//
+		// example:
+		//	Remove all classes from some node:
+		//	|	dojo.removeClass("someNode");
+		//
+		// example:
+		//	Available in `dojo.NodeList()` for multiple removal
+		//	|	dojo.query(".foo").removeClass("foo");
+
+		node = byId(node);
+		var cls;
+		if(classStr !== undefined){
+			classStr = str2array(classStr);
+			cls = " " + node[_className] + " ";
+			for(var i = 0, len = classStr.length; i < len; ++i){
+				cls = cls.replace(" " + classStr[i] + " ", " ");
+			}
+			cls = d.trim(cls);
+		}else{
+			cls = "";
+		}
+		if(node[_className] != cls){ node[_className] = cls; }
+	};
+
+	dojo.toggleClass = function(/*DomNode|String*/node, /*String|Array*/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);
+	};
+
+})();
+
+return dojo._base.html; });
+require.def("dojo/_base/NodeList", ["require", "dojo", "dijit", "dojox", "dojo/_base/lang", "dojo/_base/array"], function(require, dojo, dijit, dojox, _R0, _R1) {
+dojo.provide("dojo._base.NodeList");
+;
+;
+
+(function(){
+
+	var d = dojo;
+
+	var ap = Array.prototype, aps = ap.slice, apc = ap.concat;
+
+	var tnl = function(/*Array*/ a, /*dojo.NodeList?*/ parent, /*Function?*/ NodeListCtor){
+		// summary:
+		// 		decorate an array to make it look like a `dojo.NodeList`.
+		// a:
+		// 		Array of nodes to decorate.
+		// parent:
+		// 		An optional parent NodeList that generated the current
+		// 		list of nodes. Used to call _stash() so the parent NodeList
+		// 		can be accessed via end() later.
+		// NodeListCtor:
+		// 		An optional constructor function to use for any
+		// 		new NodeList calls. This allows a certain chain of
+		// 		NodeList calls to use a different object than dojo.NodeList.
+		if(!a.sort){
+			// make sure it's a real array before we pass it on to be wrapped
+			a = aps.call(a, 0);
+		}
+		var ctor = NodeListCtor || this._NodeListCtor || d._NodeListCtor;
+		a.constructor = ctor;
+		dojo._mixin(a, ctor.prototype);
+		a._NodeListCtor = ctor;
+		return parent ? a._stash(parent) : a;
+	};
+
+	var loopBody = function(f, a, o){
+		a = [0].concat(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 && (typeof a[0] == "string"); // inline'd type check
+	};
+
+	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){
+		//		|		console.log(index, node.innerHTML);
+		//		|	});
+		//	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
+		//		|	console.log(l.length);
+		//		|	l.push(dojo.create("span"));
+		//		|
+		//		|	// dojo's normalized array methods work too:
+		//		|	console.log( l.indexOf(dojo.byId("foo")) );
+		//		|	// ...including the special "function as string" shorthand
+		//		|	console.log( l.every("item.nodeType == 1") );
+		//		|
+		//		|	// 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));
+	};
+
+	//Allow things that new up a NodeList to use a delegated or alternate NodeList implementation.
+	d._NodeListCtor = d.NodeList;
+
+	var nl = d.NodeList, nlp = nl.prototype;
+
+	// expose adapters and the wrapper as private functions
+
+	nl._wrap = nlp._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];
+		//Use a copy of the this array via this.slice() to allow .end() to work right in the splice case.
+		// CANNOT apply ._stash()/end() to splice since it currently modifies
+		// the existing this array -- it would break backward compatibility if we copy the array before
+		// the splice so that we can use .end(). So only doing the stash option to this._wrap for slice.
+		nlp[name] = function(){ return this._wrap(f.apply(this, arguments), name == "slice" ? this : null); };
+	});
+	// 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", "removeAttr"], function(name){
+		nlp[name] = adaptAsForEach(d[name]);
+	});
+
+	dojo.extend(dojo.NodeList, {
+		_normalize: function(/*String||Element||Object||NodeList*/content, /*DOMNode?*/refNode){
+			// summary:
+			// 		normalizes data to an array of items to insert.
+			// description:
+			// 		If content is an object, it can have special properties "template" and
+			// 		"parse". If "template" is defined, then the template value is run through
+			// 		dojo.string.substitute (if dojo.string.substitute has been dojo.required elsewhere),
+			// 		or if templateFunc is a function on the content, that function will be used to
+			// 		transform the template into a final string to be used for for passing to dojo._toDom.
+			// 		If content.parse is true, then it is remembered for later, for when the content
+			// 		nodes are inserted into the DOM. At that point, the nodes will be parsed for widgets
+			// 		(if dojo.parser has been dojo.required elsewhere).
+
+			//Wanted to just use a DocumentFragment, but for the array/NodeList
+			//case that meant  using cloneNode, but we may not want that.
+			//Cloning should only happen if the node operations span
+			//multiple refNodes. Also, need a real array, not a NodeList from the
+			//DOM since the node movements could change those NodeLists.
+
+			var parse = content.parse === true ? true : false;
+
+			//Do we have an object that needs to be run through a template?
+			if(typeof content.template == "string"){
+				var templateFunc = content.templateFunc || (dojo.string && dojo.string.substitute);
+				content = templateFunc ? templateFunc(content.template, content) : content;
+			}
+
+			var type = (typeof content);
+			if(type == "string" || type == "number"){
+				content = dojo._toDom(content, (refNode && refNode.ownerDocument));
+				if(content.nodeType == 11){
+					//DocumentFragment. It cannot handle cloneNode calls, so pull out the children.
+					content = dojo._toArray(content.childNodes);
+				}else{
+					content = [content];
+				}
+			}else if(!dojo.isArrayLike(content)){
+				content = [content];
+			}else if(!dojo.isArray(content)){
+				//To get to this point, content is array-like, but
+				//not an array, which likely means a DOM NodeList. Convert it now.
+				content = dojo._toArray(content);
+			}
+
+			//Pass around the parse info
+			if(parse){
+				content._runParse = true;
+			}
+			return content; //Array
+		},
+
+		_cloneNode: function(/*DOMNode*/ node){
+			// summary:
+			// 		private utiltity to clone a node. Not very interesting in the vanilla
+			// 		dojo.NodeList case, but delegates could do interesting things like
+			// 		clone event handlers if that is derivable from the node.
+			return node.cloneNode(true);
+		},
+
+		_place: function(/*Array*/ary, /*DOMNode*/refNode, /*String*/position, /*Boolean*/useClone){
+			// summary:
+			// 		private utility to handle placing an array of nodes relative to another node.
+			// description:
+			// 		Allows for cloning the nodes in the array, and for
+			// 		optionally parsing widgets, if ary._runParse is true.
+
+			//Avoid a disallowed operation if trying to do an innerHTML on a non-element node.
+			if(refNode.nodeType != 1 && position == "only"){
+				return;
+			}
+			var rNode = refNode, tempNode;
+
+			//Always cycle backwards in case the array is really a
+			//DOM NodeList and the DOM operations take it out of the live collection.
+			var length = ary.length;
+			for(var i = length - 1; i >= 0; i--){
+				var node = (useClone ? this._cloneNode(ary[i]) : ary[i]);
+
+				//If need widget parsing, use a temp node, instead of waiting after inserting into
+				//real DOM because we need to start widget parsing at one node up from current node,
+				//which could cause some already parsed widgets to be parsed again.
+				if(ary._runParse && dojo.parser && dojo.parser.parse){
+					if(!tempNode){
+						tempNode = rNode.ownerDocument.createElement("div");
+					}
+					tempNode.appendChild(node);
+					dojo.parser.parse(tempNode);
+					node = tempNode.firstChild;
+					while(tempNode.firstChild){
+						tempNode.removeChild(tempNode.firstChild);
+					}
+				}
+
+				if(i == length - 1){
+					dojo.place(node, rNode, position);
+				}else{
+					rNode.parentNode.insertBefore(node, rNode);
+				}
+				rNode = node;
+			}
+		},
+
+		_stash: function(parent){
+			// summary:
+			// 		private function to hold to a parent NodeList. end() to return the parent NodeList.
+			//
+			// example:
+			// How to make a `dojo.NodeList` method that only returns the third node in
+			// the dojo.NodeList but allows access to the original NodeList by using this._stash:
+			//	|	dojo.extend(dojo.NodeList, {
+			//	|		third: function(){
+			//  |			var newNodeList = dojo.NodeList(this[2]);
+			//	|			return newNodeList._stash(this);
+			//	|		}
+			//	|	});
+			//	|	// then see how _stash applies a sub-list, to be .end()'ed out of
+			//	|	dojo.query(".foo")
+			//	|		.third()
+			//	|			.addClass("thirdFoo")
+			//	|		.end()
+			//	|		// access to the orig .foo list
+			//	|		.removeClass("foo")
+			//	|
+			//
+			this._parent = parent;
+			return this; //dojo.NodeList
+		},
+
+		end: function(){
+			// summary:
+			// 		Ends use of the current `dojo.NodeList` by returning the previous dojo.NodeList
+			// 		that generated the current dojo.NodeList.
+			// description:
+			// 		Returns the `dojo.NodeList` that generated the current `dojo.NodeList`. If there
+			// 		is no parent dojo.NodeList, an empty dojo.NodeList is returned.
+			// example:
+			//	|	dojo.query("a")
+			//	|		.filter(".disabled")
+			//	|			// operate on the anchors that only have a disabled class
+			//	|			.style("color", "grey")
+			//	|		.end()
+			//	|		// jump back to the list of anchors
+			//	|		.style(...)
+			//
+			if(this._parent){
+				return this._parent;
+			}else{
+				//Just return empy list.
+				return new this._NodeListCtor();
+			}
+		},
+
+		// 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 this._wrap(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]
+			// 		For backwards compatibility, calling .end() on the spliced NodeList
+			// 		does not return the original NodeList -- splice alters the NodeList in place.
+			// 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 this._wrap(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 this._wrap(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) &&
+						(typeof NodeList != "undefined" && a.constructor === NodeList || a.constructor === this._NodeListCtor) ?
+							aps.call(a, 0) : a;
+				});
+			return this._wrap(apc.apply(t, m), this);	// 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 this._wrap(d.map(this, func, obj), this); // dojo.NodeList
+		},
+
+		forEach: function(callback, thisObj){
+			//	summary:
+			//		see `dojo.forEach()`. The primary difference is that the acted-on 
+			//		array is implicitly this NodeList. If you want the option to break out
+			//		of the forEach loop, use every() or some() instead.
+			d.forEach(this, callback, thisObj);
+			// non-standard return to allow easier chaining
+			return this; // dojo.NodeList 
+		},
+
+		/*=====
+		coords: function(){
+			//	summary:
+			//		Returns the box objects of all elements in a node list as
+			//		an Array (*not* a NodeList). Acts like `dojo.coords`, though assumes
+			//		the node passed is each node in this list.
+
+			return d.map(this, d.coords); // Array
+		},
+
+		position: function(){
+			//	summary:
+			//		Returns border-box objects (x/y/w/h) of all elements in a node list
+			//		as an Array (*not* a NodeList). Acts like `dojo.position`, though
+			//		assumes the node passed is each node in this list. 
+
+			return d.map(this, d.position); // Array
+		},
+
+		attr: function(property, value){
+			//	summary:
+			//		gets or sets the DOM attribute for every element in the
+			//		NodeList. See also `dojo.attr`
+			//	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
+			//	example:
+			//		Make all nodes with a particular class focusabl:
+			//	|	dojo.query(".focusable").attr("tabIndex", -1);
+			//	example:
+			//		Disable a group of buttons:
+			//	|	dojo.query("button.group").attr("disalbed", true);
+			//	example:
+			//		innerHTML can be assigned or retreived as well:
+			//	|	// get the innerHTML (as an array) for each list item
+			//	|	var ih = dojo.query("li.replaceable").attr("innerHTML");<