/*
        Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
        Available via Academic Free License >= 2.1 OR the modified BSD license.
        see: http://dojotoolkit.org/license for details
*/

/*
        This is an optimized version of Dojo, built for deployment and not for
        development. To get sources and documentation, please visit:

                http://dojotoolkit.org
*/

;(function(){

        /*
        dojo, dijit, and dojox must always be the first three, and in that order.
        djConfig.scopeMap = [
                ["dojo", "fojo"],
                ["dijit", "fijit"],
                ["dojox", "fojox"]
        
        ]
        */

        /**Build will replace this comment with a scoped djConfig **/

        //The null below can be relaced by a build-time value used instead of djConfig.scopeMap.
        var sMap = null;

        //See if new scopes need to be defined.
        if((sMap || (typeof djConfig != "undefined" && djConfig.scopeMap)) && (typeof window != "undefined")){
                var scopeDef = "", scopePrefix = "", scopeSuffix = "", scopeMap = {}, scopeMapRev = {};
                sMap = sMap || djConfig.scopeMap;
                for(var i = 0; i < sMap.length; i++){
                        //Make local variables, then global variables that use the locals.
                        var newScope = sMap[i];
                        scopeDef += "var " + newScope[0] + " = {}; " + newScope[1] + " = " + newScope[0] + ";" + newScope[1] + "._scopeName = '" + newScope[1] + "';";
                        scopePrefix += (i == 0 ? "" : ",") + newScope[0];
                        scopeSuffix += (i == 0 ? "" : ",") + newScope[1];
                        scopeMap[newScope[0]] = newScope[1];
                        scopeMapRev[newScope[1]] = newScope[0];
                }

                eval(scopeDef + "dojo._scopeArgs = [" + scopeSuffix + "];");

                dojo._scopePrefixArgs = scopePrefix;
                dojo._scopePrefix = "(function(" + scopePrefix + "){";
                dojo._scopeSuffix = "})(" + scopeSuffix + ")";
                dojo._scopeMap = scopeMap;
                dojo._scopeMapRev = scopeMapRev;
        }

/*=====
// note:
//              'djConfig' does not exist under 'dojo.*' so that it can be set before the
//              'dojo' variable exists.
// note:
//              Setting any of these variables *after* the library has loaded does
//              nothing at all.

djConfig = {
        // summary:
        //              Application code can set the global 'djConfig' prior to loading
        //              the library to override certain global settings for how dojo works.
        //
        // isDebug: Boolean
        //              Defaults to `false`. If set to `true`, ensures that Dojo provides
        //              extended debugging feedback via Firebug. If Firebug is not available
        //              on your platform, setting `isDebug` to `true` will force Dojo to
        //              pull in (and display) the version of Firebug Lite which is
        //              integrated into the Dojo distribution, thereby always providing a
        //              debugging/logging console when `isDebug` is enabled. Note that
        //              Firebug's `console.*` methods are ALWAYS defined by Dojo. If
        //              `isDebug` is false and you are on a platform without Firebug, these
        //              methods will be defined as no-ops.
        isDebug: false,
        // debugAtAllCosts: Boolean
        //              Defaults to `false`. If set to `true`, this triggers an alternate
        //              mode of the package system in which dependencies are detected and
        //              only then are resources evaluated in dependency order via
        //              `<script>` tag inclusion. This may double-request resources and
        //              cause problems with scripts which expect `dojo.require()` to
        //              preform synchronously. `debugAtAllCosts` can be an invaluable
        //              debugging aid, but when using it, ensure that all code which
        //              depends on Dojo modules is wrapped in `dojo.addOnLoad()` handlers.
        //              Due to the somewhat unpredictable side-effects of using
        //              `debugAtAllCosts`, it is strongly recommended that you enable this
        //              flag as a last resort. `debugAtAllCosts` has no effect when loading
        //              resources across domains. For usage information, see the
        //              [Dojo Book](http://dojotoolkit.org/book/book-dojo/part-4-meta-dojo-making-your-dojo-code-run-faster-and-better/debugging-facilities/deb)
        debugAtAllCosts: false,
        // locale: String
        //              The locale to assume for loading localized resources in this page,
        //              specified according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt).
        //              Must be specified entirely in lowercase, e.g. `en-us` and `zh-cn`.
        //              See the documentation for `dojo.i18n` and `dojo.requireLocalization`
        //              for details on loading localized resources. If no locale is specified,
        //              Dojo assumes the locale of the user agent, according to `navigator.userLanguage`
        //              or `navigator.language` properties.
        locale: undefined,
        // extraLocale: Array
        //              No default value. Specifies additional locales whose
        //              resources should also be loaded alongside the default locale when
        //              calls to `dojo.requireLocalization()` are processed.
        extraLocale: undefined,
        // baseUrl: String
        //              The directory in which `dojo.js` is located. Under normal
        //              conditions, Dojo auto-detects the correct location from which it
        //              was loaded. You may need to manually configure `baseUrl` in cases
        //              where you have renamed `dojo.js` or in which `<base>` tags confuse
        //              some browsers (e.g. IE 6). The variable `dojo.baseUrl` is assigned
        //              either the value of `djConfig.baseUrl` if one is provided or the
        //              auto-detected root if not. Other modules are located relative to
        //              this path. The path should end in a slash.
        baseUrl: undefined,
        // modulePaths: Object
        //              A map of module names to paths relative to `dojo.baseUrl`. The
        //              key/value pairs correspond directly to the arguments which
        //              `dojo.registerModulePath` accepts. Specifiying
        //              `djConfig.modulePaths = { "foo": "../../bar" }` is the equivalent
        //              of calling `dojo.registerModulePath("foo", "../../bar");`. Multiple
        //              modules may be configured via `djConfig.modulePaths`.
        modulePaths: {},
        // afterOnLoad: Boolean
        //              Indicates Dojo was added to the page after the page load. In this case
        //              Dojo will not wait for the page DOMContentLoad/load events and fire
        //              its dojo.addOnLoad callbacks after making sure all outstanding
        //              dojo.required modules have loaded. Only works with a built dojo.js,
        //              it does not work the dojo.js directly from source control.
        afterOnLoad: false,
        // addOnLoad: Function or Array
        //              Adds a callback via dojo.addOnLoad. Useful when Dojo is added after
        //              the page loads and djConfig.afterOnLoad is true. Supports the same
        //              arguments as dojo.addOnLoad. When using a function reference, use
        //              `djConfig.addOnLoad = function(){};`. For object with function name use
        //              `djConfig.addOnLoad = [myObject, "functionName"];` and for object with
        //              function reference use
        //              `djConfig.addOnLoad = [myObject, function(){}];`
        addOnLoad: null,
        // require: Array
        //              An array of module names to be loaded immediately after dojo.js has been included
        //              in a page.
        require: [],
        // defaultDuration: Array
        //              Default duration, in milliseconds, for wipe and fade animations within dijits.
        //              Assigned to dijit.defaultDuration.
        defaultDuration: 200,
        // dojoBlankHtmlUrl: String
        //              Used by some modules to configure an empty iframe. Used by dojo.io.iframe and
        //              dojo.back, and dijit popup support in IE where an iframe is needed to make sure native
        //              controls do not bleed through the popups. Normally this configuration variable
        //              does not need to be set, except when using cross-domain/CDN Dojo builds.
        //              Save dojo/resources/blank.html to your domain and set `djConfig.dojoBlankHtmlUrl`
        //              to the path on your domain your copy of blank.html.
        dojoBlankHtmlUrl: undefined,
        //      ioPublish: Boolean?
        //              Set this to true to enable publishing of topics for the different phases of
        //              IO operations. Publishing is done via dojo.publish. See dojo.__IoPublish for a list
        //              of topics that are published.
        ioPublish: false,
        //  useCustomLogger: Anything?
        //              If set to a value that evaluates to true such as a string or array and
        //              isDebug is true and Firebug is not available or running, then it bypasses
        //              the creation of Firebug Lite allowing you to define your own console object.
        useCustomLogger: undefined,
        // transparentColor: Array
        //              Array containing the r, g, b components used as transparent color in dojo.Color;
        //              if undefined, [255,255,255] (white) will be used.
        transparentColor: undefined,
        // skipIeDomLoaded: Boolean
        //              For IE only, skip the DOMContentLoaded hack used. Sometimes it can cause an Operation
        //              Aborted error if the rest of the page triggers script defers before the DOM is ready.
        //              If this is config value is set to true, then dojo.addOnLoad callbacks will not be
        //              triggered until the page load event, which is after images and iframes load. If you
        //              want to trigger the callbacks sooner, you can put a script block in the bottom of
        //              your HTML that calls dojo._loadInit();. If you are using multiversion support, change
        //              "dojo." to the appropriate scope name for dojo.
        skipIeDomLoaded: false
}
=====*/

(function(){
        // firebug stubs

        if(typeof this["loadFirebugConsole"] == "function"){
                // for Firebug 1.2
                this["loadFirebugConsole"]();
        }else{
                this.console = this.console || {};

                //      Be careful to leave 'log' always at the end
                var cn = [
                        "assert", "count", "debug", "dir", "dirxml", "error", "group",
                        "groupEnd", "info", "profile", "profileEnd", "time", "timeEnd",
                        "trace", "warn", "log"
                ];
                var i = 0, tn;
                while((tn=cn[i++])){
                        if(!console[tn]){
                                (function(){
                                        var tcn = tn+"";
                                        console[tcn] = ('log' in console) ? function(){
                                                var a = Array.apply({}, arguments);
                                                a.unshift(tcn+":");
                                                console["log"](a.join(" "));
                                        } : function(){}
                                        console[tcn]._fake = true;
                                })();
                        }
                }
        }

        //TODOC:  HOW TO DOC THIS?
        // dojo is the root variable of (almost all) our public symbols -- make sure it is defined.
        if(typeof dojo == "undefined"){
                dojo = {
                        _scopeName: "dojo",
                        _scopePrefix: "",
                        _scopePrefixArgs: "",
                        _scopeSuffix: "",
                        _scopeMap: {},
                        _scopeMapRev: {}
                };
        }

        var d = dojo;

        //Need placeholders for dijit and dojox for scoping code.
        if(typeof dijit == "undefined"){
                dijit = {_scopeName: "dijit"};
        }
        if(typeof dojox == "undefined"){
                dojox = {_scopeName: "dojox"};
        }

        if(!d._scopeArgs){
                d._scopeArgs = [dojo, dijit, dojox];
        }

/*=====
dojo.global = {
        //      summary:
        //              Alias for the global scope
        //              (e.g. the window object in a browser).
        //      description:
        //              Refer to 'dojo.global' rather than referring to window to ensure your
        //              code runs correctly in contexts other than web browsers (e.g. Rhino on a server).
}
=====*/
        d.global = this;

        d.config =/*===== djConfig = =====*/{
                isDebug: false,
                debugAtAllCosts: false
        };

        // FIXME: 2.0, drop djConfig support. Use dojoConfig exclusively for global config.
        var cfg = typeof djConfig != "undefined" ? djConfig :
                typeof dojoConfig != "undefined" ? dojoConfig : null;
                
        if(cfg){
                for(var c in cfg){
                        d.config[c] = cfg[c];
                }
        }

/*=====
        // Override locale setting, if specified
        dojo.locale = {
                // summary: the locale as defined by Dojo (read-only)
        };
=====*/
        dojo.locale = d.config.locale;

        var rev = "$Rev: 24595 $".match(/\d+/);

/*=====
        dojo.version = function(){
                // summary:
                //              Version number of the Dojo Toolkit
                // major: Integer
                //              Major version. If total version is "1.2.0beta1", will be 1
                // minor: Integer
                //              Minor version. If total version is "1.2.0beta1", will be 2
                // patch: Integer
                //              Patch version. If total version is "1.2.0beta1", will be 0
                // flag: String
                //              Descriptor flag. If total version is "1.2.0beta1", will be "beta1"
                // revision: Number
                //              The SVN rev from which dojo was pulled
                this.major = 0;
                this.minor = 0;
                this.patch = 0;
                this.flag = "";
                this.revision = 0;
        }
=====*/
        dojo.version = {
                major: 1, minor: 6, patch: 1, flag: "",
                revision: rev ? +rev[0] : NaN,
                toString: function(){
                        with(d.version){
                                return major + "." + minor + "." + patch + flag + " (" + revision + ")";        // String
                        }
                }
        }

                // Register with the OpenAjax hub
        if(typeof OpenAjax != "undefined"){
                OpenAjax.hub.registerLibrary(dojo._scopeName, "http://dojotoolkit.org", d.version.toString());
        }
        
        var extraNames, extraLen, empty = {};
        for(var i in {toString: 1}){ extraNames = []; break; }
        dojo._extraNames = extraNames = extraNames || ["hasOwnProperty", "valueOf", "isPrototypeOf",
                "propertyIsEnumerable", "toLocaleString", "toString", "constructor"];
        extraLen = extraNames.length;

        dojo._mixin = function(/*Object*/ target, /*Object*/ source){
                // summary:
                //              Adds all properties and methods of source to target. This addition
                //              is "prototype extension safe", so that instances of objects
                //              will not pass along prototype defaults.
                var name, s, i;
                for(name in source){
                        // the "tobj" condition avoid copying properties in "source"
                        // inherited from Object.prototype.  For example, if target has a custom
                        // toString() method, don't overwrite it with the toString() method
                        // that source inherited from Object.prototype
                        s = source[name];
                        if(!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))){
                                target[name] = s;
                        }
                }
                                // IE doesn't recognize some custom functions in for..in
                if(extraLen && source){
                        for(i = 0; i < extraLen; ++i){
                                name = extraNames[i];
                                s = source[name];
                                if(!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))){
                                        target[name] = s;
                                }
                        }
                }
                                return target; // Object
        }

        dojo.mixin = function(/*Object*/obj, /*Object...*/props){
                // summary:
                //              Adds all properties and methods of props to obj and returns the
                //              (now modified) obj.
                //      description:
                //              `dojo.mixin` can mix multiple source objects into a
                //              destination object which is then returned. Unlike regular
                //              `for...in` iteration, `dojo.mixin` is also smart about avoiding
                //              extensions which other toolkits may unwisely add to the root
                //              object prototype
                //      obj:
                //              The object to mix properties into. Also the return value.
                //      props:
                //              One or more objects whose values are successively copied into
                //              obj. If more than one of these objects contain the same value,
                //              the one specified last in the function call will "win".
                //      example:
                //              make a shallow copy of an object
                //      |       var copy = dojo.mixin({}, source);
                //      example:
                //              many class constructors often take an object which specifies
                //              values to be configured on the object. In this case, it is
                //              often simplest to call `dojo.mixin` on the `this` object:
                //      |       dojo.declare("acme.Base", null, {
                //      |               constructor: function(properties){
                //      |                       // property configuration:
                //      |                       dojo.mixin(this, properties);
                //      |
                //      |                       console.log(this.quip);
                //      |                       //  ...
                //      |               },
                //      |               quip: "I wasn't born yesterday, you know - I've seen movies.",
                //      |               // ...
                //      |       });
                //      |
                //      |       // create an instance of the class and configure it
                //      |       var b = new acme.Base({quip: "That's what it does!" });
                //      example:
                //              copy in properties from multiple objects
                //      |       var flattened = dojo.mixin(
                //      |               {
                //      |                       name: "Frylock",
                //      |                       braces: true
                //      |               },
                //      |               {
                //      |                       name: "Carl Brutanananadilewski"
                //      |               }
                //      |       );
                //      |
                //      |       // will print "Carl Brutanananadilewski"
                //      |       console.log(flattened.name);
                //      |       // will print "true"
                //      |       console.log(flattened.braces);
                if(!obj){ obj = {}; }
                for(var i=1, l=arguments.length; i<l; i++){
                        d._mixin(obj, arguments[i]);
                }
                return obj; // Object
        }

        dojo._getProp = function(/*Array*/parts, /*Boolean*/create, /*Object*/context){
                var obj=context || d.global;
                for(var i=0, p; obj && (p=parts[i]); i++){
                        if(i == 0 && d._scopeMap[p]){
                                p = d._scopeMap[p];
                        }
                        obj = (p in obj ? obj[p] : (create ? obj[p]={} : undefined));
                }
                return obj; // mixed
        }

        dojo.setObject = function(/*String*/name, /*Object*/value, /*Object?*/context){
                // summary:
                //              Set a property from a dot-separated string, such as "A.B.C"
                //      description:
                //              Useful for longer api chains where you have to test each object in
                //              the chain, or when you have an object reference in string format.
                //              Objects are created as needed along `path`. Returns the passed
                //              value if setting is successful or `undefined` if not.
                //      name:
                //              Path to a property, in the form "A.B.C".
                //      context:
                //              Optional. Object to use as root of path. Defaults to
                //              `dojo.global`.
                //      example:
                //              set the value of `foo.bar.baz`, regardless of whether
                //              intermediate objects already exist:
                //      |       dojo.setObject("foo.bar.baz", value);
                //      example:
                //              without `dojo.setObject`, we often see code like this:
                //      |       // ensure that intermediate objects are available
                //      |       if(!obj["parent"]){ obj.parent = {}; }
                //      |       if(!obj.parent["child"]){ obj.parent.child= {}; }
                //      |       // now we can safely set the property
                //      |       obj.parent.child.prop = "some value";
                //              wheras with `dojo.setObject`, we can shorten that to:
                //      |       dojo.setObject("parent.child.prop", "some value", obj);
                var parts=name.split("."), p=parts.pop(), obj=d._getProp(parts, true, context);
                return obj && p ? (obj[p]=value) : undefined; // Object
        }

        dojo.getObject = function(/*String*/name, /*Boolean?*/create, /*Object?*/context){
                // summary:
                //              Get a property from a dot-separated string, such as "A.B.C"
                //      description:
                //              Useful for longer api chains where you have to test each object in
                //              the chain, or when you have an object reference in string format.
                //      name:
                //              Path to an property, in the form "A.B.C".
                //      create:
                //              Optional. Defaults to `false`. If `true`, Objects will be
                //              created at any point along the 'path' that is undefined.
                //      context:
                //              Optional. Object to use as root of path. Defaults to
                //              'dojo.global'. Null may be passed.
                return d._getProp(name.split("."), create, context); // Object
        }

        dojo.exists = function(/*String*/name, /*Object?*/obj){
                //      summary:
                //              determine if an object supports a given method
                //      description:
                //              useful for longer api chains where you have to test each object in
                //              the chain. Useful for object and method detection.
                //      name:
                //              Path to an object, in the form "A.B.C".
                //      obj:
                //              Object to use as root of path. Defaults to
                //              'dojo.global'. Null may be passed.
                //      example:
                //      |       // define an object
                //      |       var foo = {
                //      |               bar: { }
                //      |       };
                //      |
                //      |       // search the global scope
                //      |       dojo.exists("foo.bar"); // true
                //      |       dojo.exists("foo.bar.baz"); // false
                //      |
                //      |       // search from a particular scope
                //      |       dojo.exists("bar", foo); // true
                //      |       dojo.exists("bar.baz", foo); // false
                return d.getObject(name, false, obj) !== undefined; // Boolean
        }

        dojo["eval"] = function(/*String*/ scriptFragment){
                //      summary:
                //              A legacy method created for use exclusively by internal Dojo methods. Do not use
                //              this method directly, the behavior of this eval will differ from the normal
                //              browser eval.
                //      description:
                //              Placed in a separate function to minimize size of trapped
                //              exceptions. Calling eval() directly from some other scope may
                //              complicate tracebacks on some platforms.
                //      returns:
                //              The result of the evaluation. Often `undefined`
                return d.global.eval ? d.global.eval(scriptFragment) : eval(scriptFragment);    // Object
        }

        /*=====
                dojo.deprecated = function(behaviour, extra, removal){
                        //      summary:
                        //              Log a debug message to indicate that a behavior has been
                        //              deprecated.
                        //      behaviour: String
                        //              The API or behavior being deprecated. Usually in the form
                        //              of "myApp.someFunction()".
                        //      extra: String?
                        //              Text to append to the message. Often provides advice on a
                        //              new function or facility to achieve the same goal during
                        //              the deprecation period.
                        //      removal: String?
                        //              Text to indicate when in the future the behavior will be
                        //              removed. Usually a version number.
                        //      example:
                        //      |       dojo.deprecated("myApp.getTemp()", "use myApp.getLocaleTemp() instead", "1.0");
                }

                dojo.experimental = function(moduleName, extra){
                        //      summary: Marks code as experimental.
                        //      description:
                        //              This can be used to mark a function, file, or module as
                        //              experimental.  Experimental code is not ready to be used, and the
                        //              APIs are subject to change without notice.  Experimental code may be
                        //              completed deleted without going through the normal deprecation
                        //              process.
                        //      moduleName: String
                        //              The name of a module, or the name of a module file or a specific
                        //              function
                        //      extra: String?
                        //              some additional message for the user
                        //      example:
                        //      |       dojo.experimental("dojo.data.Result");
                        //      example:
                        //      |       dojo.experimental("dojo.weather.toKelvin()", "PENDING approval from NOAA");
                }
        =====*/

        //Real functions declared in dojo._firebug.firebug.
        d.deprecated = d.experimental = function(){};

})();
// vim:ai:ts=4:noet

/*
 * loader.js - A bootstrap module.  Runs before the hostenv_*.js file. Contains
 * all of the package loading methods.
 */
(function(){
        var d = dojo, currentModule;

        d.mixin(d, {
                _loadedModules: {},
                _inFlightCount: 0,
                _hasResource: {},

                _modulePrefixes: {
                        dojo:   {       name: "dojo", value: "." },
                        // dojox:       {       name: "dojox", value: "../dojox" },
                        // dijit:       {       name: "dijit", value: "../dijit" },
                        doh:    {       name: "doh", value: "../util/doh" },
                        tests:  {       name: "tests", value: "tests" }
                },

                _moduleHasPrefix: function(/*String*/module){
                        // summary: checks to see if module has been established
                        var mp = d._modulePrefixes;
                        return !!(mp[module] && mp[module].value); // Boolean
                },

                _getModulePrefix: function(/*String*/module){
                        // summary: gets the prefix associated with module
                        var mp = d._modulePrefixes;
                        if(d._moduleHasPrefix(module)){
                                return mp[module].value; // String
                        }
                        return module; // String
                },

                _loadedUrls: [],

                //WARNING:
                //              This variable is referenced by packages outside of bootstrap:
                //              FloatingPane.js and undo/browser.js
                _postLoad: false,

                //Egad! Lots of test files push on this directly instead of using dojo.addOnLoad.
                _loaders: [],
                _unloaders: [],
                _loadNotifying: false
        });


                dojo._loadPath = function(/*String*/relpath, /*String?*/module, /*Function?*/cb){
                //      summary:
                //              Load a Javascript module given a relative path
                //
                //      description:
                //              Loads and interprets the script located at relpath, which is
                //              relative to the script root directory.  If the script is found but
                //              its interpretation causes a runtime exception, that exception is
                //              not caught by us, so the caller will see it.  We return a true
                //              value if and only if the script is found.
                //
                // relpath:
                //              A relative path to a script (no leading '/', and typically ending
                //              in '.js').
                // module:
                //              A module whose existance to check for after loading a path.  Can be
                //              used to determine success or failure of the load.
                // cb:
                //              a callback function to pass the result of evaluating the script

                var uri = ((relpath.charAt(0) == '/' || relpath.match(/^\w+:/)) ? "" : d.baseUrl) + relpath;
                try{
                        currentModule = module;
                        return !module ? d._loadUri(uri, cb) : d._loadUriAndCheck(uri, module, cb); // Boolean
                }catch(e){
                        console.error(e);
                        return false; // Boolean
                }finally{
                        currentModule = null;
                }
        }

        dojo._loadUri = function(/*String*/uri, /*Function?*/cb){
                //      summary:
                //              Loads JavaScript from a URI
                //      description:
                //              Reads the contents of the URI, and evaluates the contents.  This is
                //              used to load modules as well as resource bundles. Returns true if
                //              it succeeded. Returns false if the URI reading failed.  Throws if
                //              the evaluation throws.
                //      uri: a uri which points at the script to be loaded
                //      cb:
                //              a callback function to process the result of evaluating the script
                //              as an expression, typically used by the resource bundle loader to
                //              load JSON-style resources

                if(d._loadedUrls[uri]){
                        return true; // Boolean
                }
                d._inFlightCount++; // block addOnLoad calls that arrive while we're busy downloading
                var contents = d._getText(uri, true);
                if(contents){ // not 404, et al
                        d._loadedUrls[uri] = true;
                        d._loadedUrls.push(uri);
                        if(cb){
                                //conditional to support script-inject i18n bundle format
                                contents = /^define\(/.test(contents) ? contents : '('+contents+')';
                        }else{
                                //Only do the scoping if no callback. If a callback is specified,
                                //it is most likely the i18n bundle stuff.
                                contents = d._scopePrefix + contents + d._scopeSuffix;
                        }
                        if(!d.isIE){ contents += "\r\n//@ sourceURL=" + uri; } // debugging assist for Firebug
                        var value = d["eval"](contents);
                        if(cb){ cb(value); }
                }
                // Check to see if we need to call _callLoaded() due to an addOnLoad() that arrived while we were busy downloading
                if(--d._inFlightCount == 0 && d._postLoad && d._loaders.length){
                        // We shouldn't be allowed to get here but Firefox allows an event
                        // (mouse, keybd, async xhrGet) to interrupt a synchronous xhrGet.
                        // If the current script block contains multiple require() statements, then after each
                        // require() returns, inFlightCount == 0, but we want to hold the _callLoaded() until
                        // all require()s are done since the out-of-sequence addOnLoad() presumably needs them all.
                        // setTimeout allows the next require() to start (if needed), and then we check this again.
                        setTimeout(function(){
                                // If inFlightCount > 0, then multiple require()s are running sequentially and
                                // the next require() started after setTimeout() was executed but before we got here.
                                if(d._inFlightCount == 0){
                                        d._callLoaded();
                                }
                        }, 0);
                }
                return !!contents; // Boolean: contents? true : false
        }
        
        // FIXME: probably need to add logging to this method
        dojo._loadUriAndCheck = function(/*String*/uri, /*String*/moduleName, /*Function?*/cb){
                // summary: calls loadUri then findModule and returns true if both succeed
                var ok = false;
                try{
                        ok = d._loadUri(uri, cb);
                }catch(e){
                        console.error("failed loading " + uri + " with error: " + e);
                }
                return !!(ok && d._loadedModules[moduleName]); // Boolean
        }

        dojo.loaded = function(){
                // summary:
                //              signal fired when initial environment and package loading is
                //              complete. You should use dojo.addOnLoad() instead of doing a
                //              direct dojo.connect() to this method in order to handle
                //              initialization tasks that require the environment to be
                //              initialized. In a browser host, declarative widgets will
                //              be constructed when this function finishes runing.
                d._loadNotifying = true;
                d._postLoad = true;
                var mll = d._loaders;

                //Clear listeners so new ones can be added
                //For other xdomain package loads after the initial load.
                d._loaders = [];

                for(var x = 0; x < mll.length; x++){
                        mll[x]();
                }

                d._loadNotifying = false;
                
                //Make sure nothing else got added to the onload queue
                //after this first run. If something did, and we are not waiting for any
                //more inflight resources, run again.
                if(d._postLoad && d._inFlightCount == 0 && mll.length){
                        d._callLoaded();
                }
        }

        dojo.unloaded = function(){
                // summary:
                //              signal fired by impending environment destruction. You should use
                //              dojo.addOnUnload() instead of doing a direct dojo.connect() to this
                //              method to perform page/application cleanup methods. See
                //              dojo.addOnUnload for more info.
                var mll = d._unloaders;
                while(mll.length){
                        (mll.pop())();
                }
        }

        d._onto = function(arr, obj, fn){
                if(!fn){
                        arr.push(obj);
                }else if(fn){
                        var func = (typeof fn == "string") ? obj[fn] : fn;
                        arr.push(function(){ func.call(obj); });
                }
        }

        dojo.ready = dojo.addOnLoad = function(/*Object*/obj, /*String|Function?*/functionName){
                // summary:
                //              Registers a function to be triggered after the DOM and dojo.require() calls
                //              have finished loading.
                //
                // description:
                //              Registers a function to be triggered after the DOM has finished
                //              loading and `dojo.require` modules have loaded. Widgets declared in markup
                //              have been instantiated if `djConfig.parseOnLoad` is true when this fires.
                //
                //              Images and CSS files may or may not have finished downloading when
                //              the specified function is called.  (Note that widgets' CSS and HTML
                //              code is guaranteed to be downloaded before said widgets are
                //              instantiated, though including css resouces BEFORE any script elements
                //              is highly recommended).
                //
                // example:
                //      Register an anonymous function to run when everything is ready
                //      |       dojo.addOnLoad(function(){ doStuff(); });
                //
                // example:
                //      Register a function to run when everything is ready by pointer:
                //      |       var init = function(){ doStuff(); }
                //      |       dojo.addOnLoad(init);
                //
                // example:
                //      Register a function to run scoped to `object`, either by name or anonymously:
                //      |       dojo.addOnLoad(object, "functionName");
                //      |       dojo.addOnLoad(object, function(){ doStuff(); });

                d._onto(d._loaders, obj, functionName);

                //Added for xdomain loading. dojo.addOnLoad is used to
                //indicate callbacks after doing some dojo.require() statements.
                //In the xdomain case, if all the requires are loaded (after initial
                //page load), then immediately call any listeners.
                if(d._postLoad && d._inFlightCount == 0 && !d._loadNotifying){
                        d._callLoaded();
                }
        }

        //Support calling dojo.addOnLoad via djConfig.addOnLoad. Support all the
        //call permutations of dojo.addOnLoad. Mainly useful when dojo is added
        //to the page after the page has loaded.
        var dca = d.config.addOnLoad;
        if(dca){
                d.addOnLoad[(dca instanceof Array ? "apply" : "call")](d, dca);
        }

        dojo._modulesLoaded = function(){
                if(d._postLoad){ return; }
                if(d._inFlightCount > 0){
                        console.warn("files still in flight!");
                        return;
                }
                d._callLoaded();
        }

        dojo._callLoaded = function(){

                // The "object" check is for IE, and the other opera check fixes an
                // issue in Opera where it could not find the body element in some
                // widget test cases.  For 0.9, maybe route all browsers through the
                // setTimeout (need protection still for non-browser environments
                // though). This might also help the issue with FF 2.0 and freezing
                // issues where we try to do sync xhr while background css images are
                // being loaded (trac #2572)? Consider for 0.9.
                if(typeof setTimeout == "object" || (d.config.useXDomain && d.isOpera)){
                        setTimeout(
                                d.isAIR ? function(){ d.loaded(); } : d._scopeName + ".loaded();",
                                0);
                }else{
                        d.loaded();
                }
        }

        dojo._getModuleSymbols = function(/*String*/modulename){
                // summary:
                //              Converts a module name in dotted JS notation to an array
                //              representing the path in the source tree
                var syms = modulename.split(".");
                for(var i = syms.length; i>0; i--){
                        var parentModule = syms.slice(0, i).join(".");
                        if(i == 1 && !d._moduleHasPrefix(parentModule)){
                                // Support default module directory (sibling of dojo) for top-level modules
                                syms[0] = "../" + syms[0];
                        }else{
                                var parentModulePath = d._getModulePrefix(parentModule);
                                if(parentModulePath != parentModule){
                                        syms.splice(0, i, parentModulePath);
                                        break;
                                }
                        }
                }
                return syms; // Array
        }

        dojo._global_omit_module_check = false;

        dojo.loadInit = function(/*Function*/init){
                //      summary:
                //              Executes a function that needs to be executed for the loader's dojo.requireIf
                //              resolutions to work. This is needed mostly for the xdomain loader case where
                //              a function needs to be executed to set up the possible values for a dojo.requireIf
                //              call.
                //      init:
                //              a function reference. Executed immediately.
                //      description: This function is mainly a marker for the xdomain loader to know parts of
                //              code that needs be executed outside the function wrappper that is placed around modules.
                //              The init function could be executed more than once, and it should make no assumptions
                //              on what is loaded, or what modules are available. Only the functionality in Dojo Base
                //              is allowed to be used. Avoid using this method. For a valid use case,
                //              see the source for dojox.gfx.
                init();
        }

        dojo._loadModule = dojo.require = function(/*String*/moduleName, /*Boolean?*/omitModuleCheck){
                //      summary:
                //              loads a Javascript module from the appropriate URI
                //
                //      moduleName: String
                //              module name to load, using periods for separators,
                //               e.g. "dojo.date.locale".  Module paths are de-referenced by dojo's
                //              internal mapping of locations to names and are disambiguated by
                //              longest prefix. See `dojo.registerModulePath()` for details on
                //              registering new modules.
                //
                //      omitModuleCheck: Boolean?
                //              if `true`, omitModuleCheck skips the step of ensuring that the
                //              loaded file actually defines the symbol it is referenced by.
                //              For example if it called as `dojo.require("a.b.c")` and the
                //              file located at `a/b/c.js` does not define an object `a.b.c`,
                //              and exception will be throws whereas no exception is raised
                //              when called as `dojo.require("a.b.c", true)`
                //
                //      description:
                //              Modules are loaded via dojo.require by using one of two loaders: the normal loader
                //              and the xdomain loader. The xdomain loader is used when dojo was built with a
                //              custom build that specified loader=xdomain and the module lives on a modulePath
                //              that is a whole URL, with protocol and a domain. The versions of Dojo that are on
                //              the Google and AOL CDNs use the xdomain loader.
                //
                //              If the module is loaded via the xdomain loader, it is an asynchronous load, since
                //              the module is added via a dynamically created script tag. This
                //              means that dojo.require() can return before the module has loaded. However, this
                //              should only happen in the case where you do dojo.require calls in the top-level
                //              HTML page, or if you purposely avoid the loader checking for dojo.require
                //              dependencies in your module by using a syntax like dojo["require"] to load the module.
                //
                //              Sometimes it is useful to not have the loader detect the dojo.require calls in the
                //              module so that you can dynamically load the modules as a result of an action on the
                //              page, instead of right at module load time.
                //
                //              Also, for script blocks in an HTML page, the loader does not pre-process them, so
                //              it does not know to download the modules before the dojo.require calls occur.
                //
                //              So, in those two cases, when you want on-the-fly module loading or for script blocks
                //              in the HTML page, special care must be taken if the dojo.required code is loaded
                //              asynchronously. To make sure you can execute code that depends on the dojo.required
                //              modules, be sure to add the code that depends on the modules in a dojo.addOnLoad()
                //              callback. dojo.addOnLoad waits for all outstanding modules to finish loading before
                //              executing.
                //
                //              This type of syntax works with both xdomain and normal loaders, so it is good
                //              practice to always use this idiom for on-the-fly code loading and in HTML script
                //              blocks. If at some point you change loaders and where the code is loaded from,
                //              it will all still work.
                //
                //              More on how dojo.require
                //              `dojo.require("A.B")` first checks to see if symbol A.B is
                //              defined. If it is, it is simply returned (nothing to do).
                //
                //              If it is not defined, it will look for `A/B.js` in the script root
                //              directory.
                //
                //              `dojo.require` throws an exception if it cannot find a file
                //              to load, or if the symbol `A.B` is not defined after loading.
                //
                //              It returns the object `A.B`, but note the caveats above about on-the-fly loading and
                //              HTML script blocks when the xdomain loader is loading a module.
                //
                //              `dojo.require()` does nothing about importing symbols into
                //              the current namespace.  It is presumed that the caller will
                //              take care of that.
                //
                //      example:
                //              To use dojo.require in conjunction with dojo.ready:
                //
                //              |       dojo.require("foo");
                //              |       dojo.require("bar");
                //              |       dojo.addOnLoad(function(){
                //              |               //you can now safely do something with foo and bar
                //              |       });
                //
                //      example:
                //              For example, to import all symbols into a local block, you might write:
                //
                //              |       with (dojo.require("A.B")) {
                //              |               ...
                //              |       }
                //
                //              And to import just the leaf symbol to a local variable:
                //
                //              |       var B = dojo.require("A.B");
                //              |       ...
                //
                //      returns:
                //              the required namespace object
                omitModuleCheck = d._global_omit_module_check || omitModuleCheck;

                //Check if it is already loaded.
                var module = d._loadedModules[moduleName];
                if(module){
                        return module;
                }

                // convert periods to slashes
                var relpath = d._getModuleSymbols(moduleName).join("/") + '.js';
                var modArg = !omitModuleCheck ? moduleName : null;
                var ok = d._loadPath(relpath, modArg);
                if(!ok && !omitModuleCheck){
                        throw new Error("Could not load '" + moduleName + "'; last tried '" + relpath + "'");
                }

                // check that the symbol was defined
                // Don't bother if we're doing xdomain (asynchronous) loading.
                if(!omitModuleCheck && !d._isXDomain){
                        // pass in false so we can give better error
                        module = d._loadedModules[moduleName];
                        if(!module){
                                throw new Error("symbol '" + moduleName + "' is not defined after loading '" + relpath + "'");
                        }
                }

                return module;
        }

        dojo.provide = function(/*String*/ resourceName){
                //      summary:
                //              Register a resource with the package system. Works in conjunction with `dojo.require`
                //
                //      description:
                //              Each javascript source file is called a resource.  When a
                //              resource is loaded by the browser, `dojo.provide()` registers
                //              that it has been loaded.
                //
                //              Each javascript source file must have at least one
                //              `dojo.provide()` call at the top of the file, corresponding to
                //              the file name.  For example, `js/dojo/foo.js` must have
                //              `dojo.provide("dojo.foo");` before any calls to
                //              `dojo.require()` are made.
                //
                //              For backwards compatibility reasons, in addition to registering
                //              the resource, `dojo.provide()` also ensures that the javascript
                //              object for the module exists.  For example,
                //              `dojo.provide("dojox.data.FlickrStore")`, in addition to
                //              registering that `FlickrStore.js` is a resource for the
                //              `dojox.data` module, will ensure that the `dojox.data`
                //              javascript object exists, so that calls like
                //              `dojo.data.foo = function(){ ... }` don't fail.
                //
                //              In the case of a build where multiple javascript source files
                //              are combined into one bigger file (similar to a .lib or .jar
                //              file), that file may contain multiple dojo.provide() calls, to
                //              note that it includes multiple resources.
                //
                // resourceName: String
                //              A dot-sperated string identifying a resource.
                //
                // example:
                //      Safely create a `my` object, and make dojo.require("my.CustomModule") work
                //      |       dojo.provide("my.CustomModule");

                //Make sure we have a string.
                resourceName = resourceName + "";
                return (d._loadedModules[resourceName] = d.getObject(resourceName, true)); // Object
        }

        //Start of old bootstrap2:

        dojo.platformRequire = function(/*Object*/modMap){
                //      summary:
                //              require one or more modules based on which host environment
                //              Dojo is currently operating in
                //      description:
                //              This method takes a "map" of arrays which one can use to
                //              optionally load dojo modules. The map is indexed by the
                //              possible dojo.name_ values, with two additional values:
                //              "default" and "common". The items in the "default" array will
                //              be loaded if none of the other items have been choosen based on
                //              dojo.name_, set by your host environment. The items in the
                //              "common" array will *always* be loaded, regardless of which
                //              list is chosen.
                //      example:
                //              |       dojo.platformRequire({
                //              |               browser: [
                //              |                       "foo.sample", // simple module
                //              |                       "foo.test",
                //              |                       ["foo.bar.baz", true] // skip object check in _loadModule (dojo.require)
                //              |               ],
                //              |               default: [ "foo.sample._base" ],
                //              |               common: [ "important.module.common" ]
                //              |       });

                var common = modMap.common || [];
                var result = common.concat(modMap[d._name] || modMap["default"] || []);

                for(var x=0; x<result.length; x++){
                        var curr = result[x];
                        if(curr.constructor == Array){
                                d._loadModule.apply(d, curr);
                        }else{
                                d._loadModule(curr);
                        }
                }
        }

        dojo.requireIf = function(/*Boolean*/ condition, /*String*/ resourceName){
                // summary:
                //              If the condition is true then call `dojo.require()` for the specified
                //              resource
                //
                // example:
                //      |       dojo.requireIf(dojo.isBrowser, "my.special.Module");
                
                if(condition === true){
                        // FIXME: why do we support chained require()'s here? does the build system?
                        var args = [];
                        for(var i = 1; i < arguments.length; i++){
                                args.push(arguments[i]);
                        }
                        d.require.apply(d, args);
                }
        }

        dojo.requireAfterIf = d.requireIf;

        dojo.registerModulePath = function(/*String*/module, /*String*/prefix){
                //      summary:
                //              Maps a module name to a path
                //      description:
                //              An unregistered module is given the default path of ../[module],
                //              relative to Dojo root. For example, module acme is mapped to
                //              ../acme.  If you want to use a different module name, use
                //              dojo.registerModulePath.
                //      example:
                //              If your dojo.js is located at this location in the web root:
                //      |       /myapp/js/dojo/dojo/dojo.js
                //              and your modules are located at:
                //      |       /myapp/js/foo/bar.js
                //      |       /myapp/js/foo/baz.js
                //      |       /myapp/js/foo/thud/xyzzy.js
                //              Your application can tell Dojo to locate the "foo" namespace by calling:
                //      |       dojo.registerModulePath("foo", "../../foo");
                //              At which point you can then use dojo.require() to load the
                //              modules (assuming they provide() the same things which are
                //              required). The full code might be:
                //      |       <script type="text/javascript"
                //      |               src="/myapp/js/dojo/dojo/dojo.js"></script>
                //      |       <script type="text/javascript">
                //      |               dojo.registerModulePath("foo", "../../foo");
                //      |               dojo.require("foo.bar");
                //      |               dojo.require("foo.baz");
                //      |               dojo.require("foo.thud.xyzzy");
                //      |       </script>
                d._modulePrefixes[module] = { name: module, value: prefix };
        };
        
        dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String?*/availableFlatLocales){
                // summary:
                //              Declares translated resources and loads them if necessary, in the
                //              same style as dojo.require.  Contents of the resource bundle are
                //              typically strings, but may be any name/value pair, represented in
                //              JSON format.  See also `dojo.i18n.getLocalization`.
                //
                // description:
                //              Load translated resource bundles provided underneath the "nls"
                //              directory within a package.  Translated resources may be located in
                //              different packages throughout the source tree.
                //
                //              Each directory is named for a locale as specified by RFC 3066,
                //              (http://www.ietf.org/rfc/rfc3066.txt), normalized in lowercase.
                //              Note that the two bundles in the example do not define all the
                //              same variants.  For a given locale, bundles will be loaded for
                //              that locale and all more general locales above it, including a
                //              fallback at the root directory.  For example, a declaration for
                //              the "de-at" locale will first load `nls/de-at/bundleone.js`,
                //              then `nls/de/bundleone.js` and finally `nls/bundleone.js`.  The
                //              data will be flattened into a single Object so that lookups
                //              will follow this cascading pattern.  An optional build step can
                //              preload the bundles to avoid data redundancy and the multiple
                //              network hits normally required to load these resources.
                //
                // moduleName:
                //              name of the package containing the "nls" directory in which the
                //              bundle is found
                //
                // bundleName:
                //              bundle name, i.e. the filename without the '.js' suffix. Using "nls" as a
                //              a bundle name is not supported, since "nls" is the name of the folder
                //              that holds bundles. Using "nls" as the bundle name will cause problems
                //              with the custom build.
                //
                // locale:
                //              the locale to load (optional)  By default, the browser's user
                //              locale as defined by dojo.locale
                //
                // availableFlatLocales:
                //              A comma-separated list of the available, flattened locales for this
                //              bundle. This argument should only be set by the build process.
                //
                //      example:
                //              A particular widget may define one or more resource bundles,
                //              structured in a program as follows, where moduleName is
                //              mycode.mywidget and bundleNames available include bundleone and
                //              bundletwo:
                //      |               ...
                //      |       mycode/
                //      |               mywidget/
                //      |                       nls/
                //      |                               bundleone.js (the fallback translation, English in this example)
                //      |                               bundletwo.js (also a fallback translation)
                //      |                               de/
                //      |                                       bundleone.js
                //      |                                       bundletwo.js
                //      |                               de-at/
                //      |                                       bundleone.js
                //      |                               en/
                //      |                                       (empty; use the fallback translation)
                //      |                               en-us/
                //      |                                       bundleone.js
                //      |                               en-gb/
                //      |                                       bundleone.js
                //      |                               es/
                //      |                                       bundleone.js
                //      |                                       bundletwo.js
                //      |                                 ...etc
                //      |                               ...
                //

                d.require("dojo.i18n");
                d.i18n._requireLocalization.apply(d.hostenv, arguments);
        };


        var ore = new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"),
                ire = new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$");

        dojo._Url = function(/*dojo._Url|String...*/){
                // summary:
                //              Constructor to create an object representing a URL.
                //              It is marked as private, since we might consider removing
                //              or simplifying it.
                // description:
                //              Each argument is evaluated in order relative to the next until
                //              a canonical uri is produced. To get an absolute Uri relative to
                //              the current document use:
                //              new dojo._Url(document.baseURI, url)

                var n = null,
                        _a = arguments,
                        uri = [_a[0]];
                // resolve uri components relative to each other
                for(var i = 1; i<_a.length; i++){
                        if(!_a[i]){ continue; }

                        // Safari doesn't support this.constructor so we have to be explicit
                        // FIXME: Tracked (and fixed) in Webkit bug 3537.
                        //              http://bugs.webkit.org/show_bug.cgi?id=3537
                        var relobj = new d._Url(_a[i]+""),
                                uriobj = new d._Url(uri[0]+"");

                        if(
                                relobj.path == "" &&
                                !relobj.scheme &&
                                !relobj.authority &&
                                !relobj.query
                        ){
                                if(relobj.fragment != n){
                                        uriobj.fragment = relobj.fragment;
                                }
                                relobj = uriobj;
                        }else if(!relobj.scheme){
                                relobj.scheme = uriobj.scheme;

                                if(!relobj.authority){
                                        relobj.authority = uriobj.authority;

                                        if(relobj.path.charAt(0) != "/"){
                                                var path = uriobj.path.substring(0,
                                                        uriobj.path.lastIndexOf("/") + 1) + relobj.path;

                                                var segs = path.split("/");
                                                for(var j = 0; j < segs.length; j++){
                                                        if(segs[j] == "."){
                                                                // flatten "./" references
                                                                if(j == segs.length - 1){
                                                                        segs[j] = "";
                                                                }else{
                                                                        segs.splice(j, 1);
                                                                        j--;
                                                                }
                                                        }else if(j > 0 && !(j == 1 && segs[0] == "") &&
                                                                segs[j] == ".." && segs[j-1] != ".."){
                                                                // flatten "../" references
                                                                if(j == (segs.length - 1)){
                                                                        segs.splice(j, 1);
                                                                        segs[j - 1] = "";
                                                                }else{
                                                                        segs.splice(j - 1, 2);
                                                                        j -= 2;
                                                                }
                                                        }
                                                }
                                                relobj.path = segs.join("/");
                                        }
                                }
                        }

                        uri = [];
                        if(relobj.scheme){
                                uri.push(relobj.scheme, ":");
                        }
                        if(relobj.authority){
                                uri.push("//", relobj.authority);
                        }
                        uri.push(relobj.path);
                        if(relobj.query){
                                uri.push("?", relobj.query);
                        }
                        if(relobj.fragment){
                                uri.push("#", relobj.fragment);
                        }
                }

                this.uri = uri.join("");

                // break the uri into its main components
                var r = this.uri.match(ore);

                this.scheme = r[2] || (r[1] ? "" : n);
                this.authority = r[4] || (r[3] ? "" : n);
                this.path = r[5]; // can never be undefined
                this.query = r[7] || (r[6] ? "" : n);
                this.fragment  = r[9] || (r[8] ? "" : n);

                if(this.authority != n){
                        // server based naming authority
                        r = this.authority.match(ire);

                        this.user = r[3] || n;
                        this.password = r[4] || n;
                        this.host = r[6] || r[7]; // ipv6 || ipv4
                        this.port = r[9] || n;
                }
        }

        dojo._Url.prototype.toString = function(){ return this.uri; };

        dojo.moduleUrl = function(/*String*/module, /*dojo._Url||String*/url){
                //      summary:
                //              Returns a `dojo._Url` object relative to a module.
                //      example:
                //      |       var pngPath = dojo.moduleUrl("acme","images/small.png");
                //      |       console.dir(pngPath); // list the object properties
                //      |       // create an image and set it's source to pngPath's value:
                //      |       var img = document.createElement("img");
                //      |       // NOTE: we assign the string representation of the url object
                //      |       img.src = pngPath.toString();
                //      |       // add our image to the document
                //      |       dojo.body().appendChild(img);
                //      example:
                //              you may de-reference as far as you like down the package
                //              hierarchy.  This is sometimes handy to avoid lenghty relative
                //              urls or for building portable sub-packages. In this example,
                //              the `acme.widget` and `acme.util` directories may be located
                //              under different roots (see `dojo.registerModulePath`) but the
                //              the modules which reference them can be unaware of their
                //              relative locations on the filesystem:
                //      |       // somewhere in a configuration block
                //      |       dojo.registerModulePath("acme.widget", "../../acme/widget");
                //      |       dojo.registerModulePath("acme.util", "../../util");
                //      |
                //      |       // ...
                //      |
                //      |       // code in a module using acme resources
                //      |       var tmpltPath = dojo.moduleUrl("acme.widget","templates/template.html");
                //      |       var dataPath = dojo.moduleUrl("acme.util","resources/data.json");

                var loc = d._getModuleSymbols(module).join('/');
                if(!loc){ return null; }
                if(loc.lastIndexOf("/") != loc.length-1){
                        loc += "/";
                }
                
                //If the path is an absolute path (starts with a / or is on another
                //domain/xdomain) then don't add the baseUrl.
                var colonIndex = loc.indexOf(":");
                if(loc.charAt(0) != "/" && (colonIndex == -1 || colonIndex > loc.indexOf("/"))){
                        loc = d.baseUrl + loc;
                }

                return new d._Url(loc, url); // dojo._Url
        };



})();

/*=====
dojo.isBrowser = {
        //      example:
        //      |       if(dojo.isBrowser){ ... }
};

dojo.isFF = {
        //      example:
        //      |       if(dojo.isFF > 1){ ... }
};

dojo.isIE = {
        // example:
        //      |       if(dojo.isIE > 6){
        //      |               // we are IE7
        //      |       }
};

dojo.isSafari = {
        //      example:
        //      |       if(dojo.isSafari){ ... }
        //      example:
        //              Detect iPhone:
        //      |       if(dojo.isSafari && navigator.userAgent.indexOf("iPhone") != -1){
        //      |               // we are iPhone. Note, iPod touch reports "iPod" above and fails this test.
        //      |       }
};

dojo = {
        // isBrowser: Boolean
        //              True if the client is a web-browser
        isBrowser: true,
        //      isFF: Number | undefined
        //              Version as a Number if client is FireFox. undefined otherwise. Corresponds to
        //              major detected FireFox version (1.5, 2, 3, etc.)
        isFF: 2,
        //      isIE: Number | undefined
        //              Version as a Number if client is MSIE(PC). undefined otherwise. Corresponds to
        //              major detected IE version (6, 7, 8, etc.)
        isIE: 6,
        //      isKhtml: Number | undefined
        //              Version as a Number if client is a KHTML browser. undefined otherwise. Corresponds to major
        //              detected version.
        isKhtml: 0,
        //      isWebKit: Number | undefined
        //              Version as a Number if client is a WebKit-derived browser (Konqueror,
        //              Safari, Chrome, etc.). undefined otherwise.
        isWebKit: 0,
        //      isMozilla: Number | undefined
        //              Version as a Number if client is a Mozilla-based browser (Firefox,
        //              SeaMonkey). undefined otherwise. Corresponds to major detected version.
        isMozilla: 0,
        //      isOpera: Number | undefined
        //              Version as a Number if client is Opera. undefined otherwise. Corresponds to
        //              major detected version.
        isOpera: 0,
        //      isSafari: Number | undefined
        //              Version as a Number if client is Safari or iPhone. undefined otherwise.
        isSafari: 0,
        //      isChrome: Number | undefined
        //              Version as a Number if client is Chrome browser. undefined otherwise.
        isChrome: 0
        //      isMac: Boolean
        //              True if the client runs on Mac
}
=====*/
if(typeof window != 'undefined'){
        dojo.isBrowser = true;
        dojo._name = "browser";


        // attempt to figure out the path to dojo if it isn't set in the config
        (function(){
                var d = dojo;

                // this is a scope protection closure. We set browser versions and grab
                // the URL we were loaded from here.

                // grab the node we were loaded from
                if(document && document.getElementsByTagName){
                        var scripts = document.getElementsByTagName("script");
                        var rePkg = /dojo(\.xd)?\.js(\W|$)/i;
                        for(var i = 0; i < scripts.length; i++){
                                var src = scripts[i].getAttribute("src");
                                if(!src){ continue; }
                                var m = src.match(rePkg);
                                if(m){
                                        // find out where we came from
                                        if(!d.config.baseUrl){
                                                d.config.baseUrl = src.substring(0, m.index);
                                        }
                                        // and find out if we need to modify our behavior
                                        var cfg = (scripts[i].getAttribute("djConfig") || scripts[i].getAttribute("data-dojo-config"));
                                        if(cfg){
                                                var cfgo = eval("({ "+cfg+" })");
                                                for(var x in cfgo){
                                                        dojo.config[x] = cfgo[x];
                                                }
                                        }
                                        break; // "first Dojo wins"
                                }
                        }
                }
                d.baseUrl = d.config.baseUrl;

                // fill in the rendering support information in dojo.render.*
                var n = navigator;
                var dua = n.userAgent,
                        dav = n.appVersion,
                        tv = parseFloat(dav);

                if(dua.indexOf("Opera") >= 0){ d.isOpera = tv; }
                if(dua.indexOf("AdobeAIR") >= 0){ d.isAIR = 1; }
                d.isKhtml = (dav.indexOf("Konqueror") >= 0) ? tv : 0;
                d.isWebKit = parseFloat(dua.split("WebKit/")[1]) || undefined;
                d.isChrome = parseFloat(dua.split("Chrome/")[1]) || undefined;
                d.isMac = dav.indexOf("Macintosh") >= 0;

                // safari detection derived from:
                //              http://developer.apple.com/internet/safari/faq.html#anchor2
                //              http://developer.apple.com/internet/safari/uamatrix.html
                var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);
                if(index && !dojo.isChrome){
                        // try to grab the explicit Safari version first. If we don't get
                        // one, look for less than 419.3 as the indication that we're on something
                        // "Safari 2-ish".
                        d.isSafari = parseFloat(dav.split("Version/")[1]);
                        if(!d.isSafari || parseFloat(dav.substr(index + 7)) <= 419.3){
                                d.isSafari = 2;
                        }
                }

                                if(dua.indexOf("Gecko") >= 0 && !d.isKhtml && !d.isWebKit){ d.isMozilla = d.isMoz = tv; }
                if(d.isMoz){
                        //We really need to get away from this. Consider a sane isGecko approach for the future.
                        d.isFF = parseFloat(dua.split("Firefox/")[1] || dua.split("Minefield/")[1]) || undefined;
                }
                if(document.all && !d.isOpera){
                        d.isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
                        //In cases where the page has an HTTP header or META tag with
                        //X-UA-Compatible, then it is in emulation mode.
                        //Make sure isIE reflects the desired version.
                        //document.documentMode of 5 means quirks mode.
                        //Only switch the value if documentMode's major version
                        //is different from isIE's major version.
                        var mode = document.documentMode;
                        if(mode && mode != 5 && Math.floor(d.isIE) != mode){
                                d.isIE = mode;
                        }
                }

                //Workaround to get local file loads of dojo to work on IE 7
                //by forcing to not use native xhr.
                if(dojo.isIE && window.location.protocol === "file:"){
                        dojo.config.ieForceActiveXXhr=true;
                }
                
                d.isQuirks = document.compatMode == "BackCompat";

                // TODO: is the HTML LANG attribute relevant?
                d.locale = dojo.config.locale || (d.isIE ? n.userLanguage : n.language).toLowerCase();

                // These are in order of decreasing likelihood; this will change in time.
                                d._XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'];
                
                d._xhrObj = function(){
                        // summary:
                        //              does the work of portably generating a new XMLHTTPRequest object.
                        var http, last_e;
                                                if(!dojo.isIE || !dojo.config.ieForceActiveXXhr){
                                                        try{ http = new XMLHttpRequest(); }catch(e){}
                                                }
                        if(!http){
                                for(var i=0; i<3; ++i){
                                        var progid = d._XMLHTTP_PROGIDS[i];
                                        try{
                                                http = new ActiveXObject(progid);
                                        }catch(e){
                                                last_e = e;
                                        }

                                        if(http){
                                                d._XMLHTTP_PROGIDS = [progid];  // so faster next time
                                                break;
                                        }
                                }
                        }
                        
                        if(!http){
                                throw new Error("XMLHTTP not available: "+last_e);
                        }

                        return http; // XMLHTTPRequest instance
                }

                d._isDocumentOk = function(http){
                        var stat = http.status || 0,
                                lp = location.protocol;
                        return (stat >= 200 && stat < 300) ||   // Boolean
                                stat == 304 ||                  // allow any 2XX response code
                                stat == 1223 ||                 // get it out of the cache
                                                                // Internet Explorer mangled the status code
                                // Internet Explorer mangled the status code OR we're Titanium/browser chrome/chrome extension requesting a local file
                                (!stat && (lp == "file:" || lp == "chrome:" || lp == "chrome-extension:" || lp == "app:"));
                }

                //See if base tag is in use.
                //This is to fix http://trac.dojotoolkit.org/ticket/3973,
                //but really, we need to find out how to get rid of the dojo._Url reference
                //below and still have DOH work with the dojo.i18n test following some other
                //test that uses the test frame to load a document (trac #2757).
                //Opera still has problems, but perhaps a larger issue of base tag support
                //with XHR requests (hasBase is true, but the request is still made to document
                //path, not base path).
                var owloc = window.location+"";
                var base = document.getElementsByTagName("base");
                var hasBase = (base && base.length > 0);

                d._getText = function(/*URI*/ uri, /*Boolean*/ fail_ok){
                        // summary: Read the contents of the specified uri and return those contents.
                        // uri:
                        //              A relative or absolute uri. If absolute, it still must be in
                        //              the same "domain" as we are.
                        // fail_ok:
                        //              Default false. If fail_ok and loading fails, return null
                        //              instead of throwing.
                        // returns: The response text. null is returned when there is a
                        //              failure and failure is okay (an exception otherwise)

                        // NOTE: must be declared before scope switches ie. this._xhrObj()
                        var http = d._xhrObj();

                        if(!hasBase && dojo._Url){
                                uri = (new dojo._Url(owloc, uri)).toString();
                        }

                        if(d.config.cacheBust){
                                //Make sure we have a string before string methods are used on uri
                                uri += "";
                                uri += (uri.indexOf("?") == -1 ? "?" : "&") + String(d.config.cacheBust).replace(/\W+/g,"");
                        }

                        http.open('GET', uri, false);
                        try{
                                http.send(null);
                                if(!d._isDocumentOk(http)){
                                        var err = Error("Unable to load "+uri+" status:"+ http.status);
                                        err.status = http.status;
                                        err.responseText = http.responseText;
                                        throw err;
                                }
                        }catch(e){
                                if(fail_ok){ return null; } // null
                                // rethrow the exception
                                throw e;
                        }
                        return http.responseText; // String
                }
                

                var _w = window;
                var _handleNodeEvent = function(/*String*/evtName, /*Function*/fp){
                        // summary:
                        //              non-destructively adds the specified function to the node's
                        //              evtName handler.
                        // evtName: should be in the form "onclick" for "onclick" handlers.
                        // Make sure you pass in the "on" part.
                        var _a = _w.attachEvent || _w.addEventListener;
                        evtName = _w.attachEvent ? evtName : evtName.substring(2);
                        _a(evtName, function(){
                                fp.apply(_w, arguments);
                        }, false);
                };


                d._windowUnloaders = [];
                
                d.windowUnloaded = function(){
                        // summary:
                        //              signal fired by impending window destruction. You may use
                        //              dojo.addOnWindowUnload() to register a listener for this
                        //              event. NOTE: if you wish to dojo.connect() to this method
                        //              to perform page/application cleanup, be aware that this
                        //              event WILL NOT fire if no handler has been registered with
                        //              dojo.addOnWindowUnload. This behavior started in Dojo 1.3.
                        //              Previous versions always triggered dojo.windowUnloaded. See
                        //              dojo.addOnWindowUnload for more info.
                        var mll = d._windowUnloaders;
                        while(mll.length){
                                (mll.pop())();
                        }
                        d = null;
                };

                var _onWindowUnloadAttached = 0;
                d.addOnWindowUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
                        // summary:
                        //              registers a function to be triggered when window.onunload
                        //              fires.
                        //      description:
                        //              The first time that addOnWindowUnload is called Dojo
                        //              will register a page listener to trigger your unload
                        //              handler with. Note that registering these handlers may
                        //              destory "fastback" page caching in browsers that support
                        //              it. Be careful trying to modify the DOM or access
                        //              JavaScript properties during this phase of page unloading:
                        //              they may not always be available. Consider
                        //              dojo.addOnUnload() if you need to modify the DOM or do
                        //              heavy JavaScript work since it fires at the eqivalent of
                        //              the page's "onbeforeunload" event.
                        // example:
                        //      |       dojo.addOnWindowUnload(functionPointer)
                        //      |       dojo.addOnWindowUnload(object, "functionName");
                        //      |       dojo.addOnWindowUnload(object, function(){ /* ... */});

                        d._onto(d._windowUnloaders, obj, functionName);
                        if(!_onWindowUnloadAttached){
                                _onWindowUnloadAttached = 1;
                                _handleNodeEvent("onunload", d.windowUnloaded);
                        }
                };

                var _onUnloadAttached = 0;
                d.addOnUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
                        // summary:
                        //              registers a function to be triggered when the page unloads.
                        //      description:
                        //              The first time that addOnUnload is called Dojo will
                        //              register a page listener to trigger your unload handler
                        //              with.
                        //
                        //              In a browser enviroment, the functions will be triggered
                        //              during the window.onbeforeunload event. Be careful of doing
                        //              too much work in an unload handler. onbeforeunload can be
                        //              triggered if a link to download a file is clicked, or if
                        //              the link is a javascript: link. In these cases, the
                        //              onbeforeunload event fires, but the document is not
                        //              actually destroyed. So be careful about doing destructive
                        //              operations in a dojo.addOnUnload callback.
                        //
                        //              Further note that calling dojo.addOnUnload will prevent
                        //              browsers from using a "fast back" cache to make page
                        //              loading via back button instantaneous.
                        // example:
                        //      |       dojo.addOnUnload(functionPointer)
                        //      |       dojo.addOnUnload(object, "functionName")
                        //      |       dojo.addOnUnload(object, function(){ /* ... */});

                        d._onto(d._unloaders, obj, functionName);
                        if(!_onUnloadAttached){
                                _onUnloadAttached = 1;
                                _handleNodeEvent("onbeforeunload", dojo.unloaded);
                        }
                };

        })();

        //START DOMContentLoaded
        dojo._initFired = false;
        dojo._loadInit = function(e){
                if(dojo._scrollIntervalId){
                        clearInterval(dojo._scrollIntervalId);
                        dojo._scrollIntervalId = 0;
                }

                if(!dojo._initFired){
                        dojo._initFired = true;

                        //Help out IE to avoid memory leak.
                        if(!dojo.config.afterOnLoad && window.detachEvent){
                                window.detachEvent("onload", dojo._loadInit);
                        }

                        if(dojo._inFlightCount == 0){
                                dojo._modulesLoaded();
                        }
                }
        }

        if(!dojo.config.afterOnLoad){
                if(document.addEventListener){
                        //Standards. Hooray! Assumption here that if standards based,
                        //it knows about DOMContentLoaded. It is OK if it does not, the fall through
                        //to window onload should be good enough.
                        document.addEventListener("DOMContentLoaded", dojo._loadInit, false);
                        window.addEventListener("load", dojo._loadInit, false);
                }else if(window.attachEvent){
                        window.attachEvent("onload", dojo._loadInit);

                        //DOMContentLoaded approximation. Diego Perini found this MSDN article
                        //that indicates doScroll is available after DOM ready, so do a setTimeout
                        //to check when it is available.
                        //http://msdn.microsoft.com/en-us/library/ms531426.aspx
                        if(!dojo.config.skipIeDomLoaded && self === self.top){
                                dojo._scrollIntervalId = setInterval(function (){
                                        try{
                                                //When dojo is loaded into an iframe in an IE HTML Application
                                                //(HTA), such as in a selenium test, javascript in the iframe
                                                //can't see anything outside of it, so self===self.top is true,
                                                //but the iframe is not the top window and doScroll will be
                                                //available before document.body is set. Test document.body
                                                //before trying the doScroll trick
                                                if(document.body){
                                                        document.documentElement.doScroll("left");
                                                        dojo._loadInit();
                                                }
                                        }catch (e){}
                                }, 30);
                        }
                }
        }

                if(dojo.isIE){
                try{
                        (function(){
                                document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
                                var vmlElems = ["*", "group", "roundrect", "oval", "shape", "rect", "imagedata", "path", "textpath", "text"],
                                        i = 0, l = 1, s = document.createStyleSheet();
                                if(dojo.isIE >= 8){
                                        i = 1;
                                        l = vmlElems.length;
                                }
                                for(; i < l; ++i){
                                        s.addRule("v\\:" + vmlElems[i], "behavior:url(#default#VML); display:inline-block");
                                }
                        })();
                }catch(e){}
        }
                //END DOMContentLoaded


        /*
        OpenAjax.subscribe("OpenAjax", "onload", function(){
                if(dojo._inFlightCount == 0){
                        dojo._modulesLoaded();
                }
        });

        OpenAjax.subscribe("OpenAjax", "onunload", function(){
                dojo.unloaded();
        });
        */
} //if (typeof window != 'undefined')

//Register any module paths set up in djConfig. Need to do this
//in the hostenvs since hostenv_browser can read djConfig from a
//script tag's attribute.
(function(){
        var mp = dojo.config["modulePaths"];
        if(mp){
                for(var param in mp){
                        dojo.registerModulePath(param, mp[param]);
                }
        }
})();

//Load debug code if necessary.
if(dojo.config.isDebug){
        dojo.require("dojo._firebug.firebug");
}

if(dojo.config.debugAtAllCosts){
        // this breaks the new AMD based module loader. The XDomain won't be necessary
        // anyway if you switch to the asynchronous loader
        //dojo.config.useXDomain = true;
        //dojo.require("dojo._base._loader.loader_xd");
        dojo.require("dojo._base._loader.loader_debug");
        dojo.require("dojo.i18n");
}


if(!dojo._hasResource["dojo._base.lang"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.lang"] = true;
dojo.provide("dojo._base.lang");


(function(){
        var d = dojo, opts = Object.prototype.toString;

        // Crockford (ish) functions

        dojo.isString = function(/*anything*/ it){
                //      summary:
                //              Return true if it is a String
                return (typeof it == "string" || it instanceof String); // Boolean
        };

        dojo.isArray = function(/*anything*/ it){
                //      summary:
                //              Return true if it is an Array.
                //              Does not work on Arrays created in other windows.
                return it && (it instanceof Array || typeof it == "array"); // Boolean
        };

        dojo.isFunction = function(/*anything*/ it){
                // summary:
                //              Return true if it is a Function
                return opts.call(it) === "[object Function]";
        };

        dojo.isObject = function(/*anything*/ it){
                // summary:
                //              Returns true if it is a JavaScript object (or an Array, a Function
                //              or null)
                return it !== undefined &&
                        (it === null || typeof it == "object" || d.isArray(it) || d.isFunction(it)); // Boolean
        };

        dojo.isArrayLike = function(/*anything*/ it){
                //      summary:
                //              similar to dojo.isArray() but more permissive
                //      description:
                //              Doesn't strongly test for "arrayness".  Instead, settles for "isn't
                //              a string or number and has a length property". Arguments objects
                //              and DOM collections will return true when passed to
                //              dojo.isArrayLike(), but will return false when passed to
                //              dojo.isArray().
                //      returns:
                //              If it walks like a duck and quacks like a duck, return `true`
                return it && it !== undefined && // Boolean
                        // keep out built-in constructors (Number, String, ...) which have length
                        // properties
                        !d.isString(it) && !d.isFunction(it) &&
                        !(it.tagName && it.tagName.toLowerCase() == 'form') &&
                        (d.isArray(it) || isFinite(it.length));
        };

        dojo.isAlien = function(/*anything*/ it){
                // summary:
                //              Returns true if it is a built-in function or some other kind of
                //              oddball that *should* report as a function but doesn't
                return it && !d.isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean
        };

        dojo.extend = function(/*Object*/ constructor, /*Object...*/ props){
                // summary:
                //              Adds all properties and methods of props to constructor's
                //              prototype, making them available to all instances created with
                //              constructor.
                for(var i=1, l=arguments.length; i<l; i++){
                        d._mixin(constructor.prototype, arguments[i]);
                }
                return constructor; // Object
        };

        dojo._hitchArgs = function(scope, method /*,...*/){
                var pre = d._toArray(arguments, 2);
                var named = d.isString(method);
                return function(){
                        // arrayify arguments
                        var args = d._toArray(arguments);
                        // locate our method
                        var f = named ? (scope||d.global)[method] : method;
                        // invoke with collected args
                        return f && f.apply(scope || this, pre.concat(args)); // mixed
                }; // Function
        };

        dojo.hitch = function(/*Object*/scope, /*Function|String*/method /*,...*/){
                //      summary:
                //              Returns a function that will only ever execute in the a given scope.
                //              This allows for easy use of object member functions
                //              in callbacks and other places in which the "this" keyword may
                //              otherwise not reference the expected scope.
                //              Any number of default positional arguments may be passed as parameters
                //              beyond "method".
                //              Each of these values will be used to "placehold" (similar to curry)
                //              for the hitched function.
                //      scope:
                //              The scope to use when method executes. If method is a string,
                //              scope is also the object containing method.
                //      method:
                //              A function to be hitched to scope, or the name of the method in
                //              scope to be hitched.
                //      example:
                //      |       dojo.hitch(foo, "bar")();
                //              runs foo.bar() in the scope of foo
                //      example:
                //      |       dojo.hitch(foo, myFunction);
                //              returns a function that runs myFunction in the scope of foo
                //      example:
                //              Expansion on the default positional arguments passed along from
                //              hitch. Passed args are mixed first, additional args after.
                //      |       var foo = { bar: function(a, b, c){ console.log(a, b, c); } };
                //      |       var fn = dojo.hitch(foo, "bar", 1, 2);
                //      |       fn(3); // logs "1, 2, 3"
                //      example:
                //      |       var foo = { bar: 2 };
                //      |       dojo.hitch(foo, function(){ this.bar = 10; })();
                //              execute an anonymous function in scope of foo
                
                if(arguments.length > 2){
                        return d._hitchArgs.apply(d, arguments); // Function
                }
                if(!method){
                        method = scope;
                        scope = null;
                }
                if(d.isString(method)){
                        scope = scope || d.global;
                        if(!scope[method]){ throw(['dojo.hitch: scope["', method, '"] is null (scope="', scope, '")'].join('')); }
                        return function(){ return scope[method].apply(scope, arguments || []); }; // Function
                }
                return !scope ? method : function(){ return method.apply(scope, arguments || []); }; // Function
        };

        /*=====
        dojo.delegate = function(obj, props){
                //      summary:
                //              Returns a new object which "looks" to obj for properties which it
                //              does not have a value for. Optionally takes a bag of properties to
                //              seed the returned object with initially.
                //      description:
                //              This is a small implementaton of the Boodman/Crockford delegation
                //              pattern in JavaScript. An intermediate object constructor mediates
                //              the prototype chain for the returned object, using it to delegate
                //              down to obj for property lookup when object-local lookup fails.
                //              This can be thought of similarly to ES4's "wrap", save that it does
                //              not act on types but rather on pure objects.
                //      obj:
                //              The object to delegate to for properties not found directly on the
                //              return object or in props.
                //      props:
                //              an object containing properties to assign to the returned object
                //      returns:
                //              an Object of anonymous type
                //      example:
                //      |       var foo = { bar: "baz" };
                //      |       var thinger = dojo.delegate(foo, { thud: "xyzzy"});
                //      |       thinger.bar == "baz"; // delegated to foo
                //      |       foo.thud == undefined; // by definition
                //      |       thinger.thud == "xyzzy"; // mixed in from props
                //      |       foo.bar = "thonk";
                //      |       thinger.bar == "thonk"; // still delegated to foo's bar
        }
        =====*/

        dojo.delegate = dojo._delegate = (function(){
                // boodman/crockford delegation w/ cornford optimization
                function TMP(){}
                return function(obj, props){
                        TMP.prototype = obj;
                        var tmp = new TMP();
                        TMP.prototype = null;
                        if(props){
                                d._mixin(tmp, props);
                        }
                        return tmp; // Object
                };
        })();

        /*=====
        dojo._toArray = function(obj, offset, startWith){
                //      summary:
                //              Converts an array-like object (i.e. arguments, DOMCollection) to an
                //              array. Returns a new Array with the elements of obj.
                //      obj: Object
                //              the object to "arrayify". We expect the object to have, at a
                //              minimum, a length property which corresponds to integer-indexed
                //              properties.
                //      offset: Number?
                //              the location in obj to start iterating from. Defaults to 0.
                //              Optional.
                //      startWith: Array?
                //              An array to pack with the properties of obj. If provided,
                //              properties in obj are appended at the end of startWith and
                //              startWith is the returned array.
        }
        =====*/

        var efficient = function(obj, offset, startWith){
                return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0));
        };

                var slow = function(obj, offset, startWith){
                var arr = startWith||[];
                for(var x = offset || 0; x < obj.length; x++){
                        arr.push(obj[x]);
                }
                return arr;
        };
        
        dojo._toArray =
                                d.isIE ?  function(obj){
                        return ((obj.item) ? slow : efficient).apply(this, arguments);
                } :
                                efficient;

        dojo.partial = function(/*Function|String*/method /*, ...*/){
                //      summary:
                //              similar to hitch() except that the scope object is left to be
                //              whatever the execution context eventually becomes.
                //      description:
                //              Calling dojo.partial is the functional equivalent of calling:
                //              |       dojo.hitch(null, funcName, ...);
                var arr = [ null ];
                return d.hitch.apply(d, arr.concat(d._toArray(arguments))); // Function
        };

        var extraNames = d._extraNames, extraLen = extraNames.length, empty = {};

        dojo.clone = function(/*anything*/ o){
                // summary:
                //              Clones objects (including DOM nodes) and all children.
                //              Warning: do not clone cyclic structures.
                if(!o || typeof o != "object" || d.isFunction(o)){
                        // null, undefined, any non-object, or function
                        return o;       // anything
                }
                if(o.nodeType && "cloneNode" in o){
                        // DOM Node
                        return o.cloneNode(true); // Node
                }
                if(o instanceof Date){
                        // Date
                        return new Date(o.getTime());   // Date
                }
                if(o instanceof RegExp){
                        // RegExp
                        return new RegExp(o);   // RegExp
                }
                var r, i, l, s, name;
                if(d.isArray(o)){
                        // array
                        r = [];
                        for(i = 0, l = o.length; i < l; ++i){
                                if(i in o){
                                        r.push(d.clone(o[i]));
                                }
                        }
// we don't clone functions for performance reasons
//              }else if(d.isFunction(o)){
//                      // function
//                      r = function(){ return o.apply(this, arguments); };
                }else{
                        // generic objects
                        r = o.constructor ? new o.constructor() : {};
                }
                for(name in o){
                        // the "tobj" condition avoid copying properties in "source"
                        // inherited from Object.prototype.  For example, if target has a custom
                        // toString() method, don't overwrite it with the toString() method
                        // that source inherited from Object.prototype
                        s = o[name];
                        if(!(name in r) || (r[name] !== s && (!(name in empty) || empty[name] !== s))){
                                r[name] = d.clone(s);
                        }
                }
                                // IE doesn't recognize some custom functions in for..in
                if(extraLen){
                        for(i = 0; i < extraLen; ++i){
                                name = extraNames[i];
                                s = o[name];
                                if(!(name in r) || (r[name] !== s && (!(name in empty) || empty[name] !== s))){
                                        r[name] = s; // functions only, we don't clone them
                                }
                        }
                }
                                return r; // Object
        };

        /*=====
        dojo.trim = function(str){
                //      summary:
                //              Trims whitespace from both sides of the string
                //      str: String
                //              String to be trimmed
                //      returns: String
                //              Returns the trimmed string
                //      description:
                //              This version of trim() was selected for inclusion into the base due
                //              to its compact size and relatively good performance
                //              (see [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript)
                //              Uses String.prototype.trim instead, if available.
                //              The fastest but longest version of this function is located at
                //              dojo.string.trim()
                return "";      // String
        }
        =====*/

        dojo.trim = String.prototype.trim ?
                function(str){ return str.trim(); } :
                function(str){ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); };

        /*=====
        dojo.replace = function(tmpl, map, pattern){
                //      summary:
                //              Performs parameterized substitutions on a string. Throws an
                //              exception if any parameter is unmatched.
                //      tmpl: String
                //              String to be used as a template.
                //      map: Object|Function
                //              If an object, it is used as a dictionary to look up substitutions.
                //              If a function, it is called for every substitution with following
                //              parameters: a whole match, a name, an offset, and the whole template
                //              string (see https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/replace
                //              for more details).
                //      pattern: RegEx?
                //              Optional regular expression objects that overrides the default pattern.
                //              Must be global and match one item. The default is: /\{([^\}]+)\}/g,
                //              which matches patterns like that: "{xxx}", where "xxx" is any sequence
                //              of characters, which doesn't include "}".
                //      returns: String
                //              Returns the substituted string.
                //      example:
                //      |       // uses a dictionary for substitutions:
                //      |       dojo.replace("Hello, {name.first} {name.last} AKA {nick}!",
                //      |         {
                //      |           nick: "Bob",
                //      |           name: {
                //      |             first:  "Robert",
                //      |             middle: "X",
                //      |             last:   "Cringely"
                //      |           }
                //      |         });
                //      |       // returns: Hello, Robert Cringely AKA Bob!
                //      example:
                //      |       // uses an array for substitutions:
                //      |       dojo.replace("Hello, {0} {2}!",
                //      |         ["Robert", "X", "Cringely"]);
                //      |       // returns: Hello, Robert Cringely!
                //      example:
                //      |       // uses a function for substitutions:
                //      |       function sum(a){
                //      |         var t = 0;
                //      |         dojo.forEach(a, function(x){ t += x; });
                //      |         return t;
                //      |       }
                //      |       dojo.replace(
                //      |         "{count} payments averaging {avg} USD per payment.",
                //      |         dojo.hitch(
                //      |           { payments: [11, 16, 12] },
                //      |           function(_, key){
                //      |             switch(key){
                //      |               case "count": return this.payments.length;
                //      |               case "min":   return Math.min.apply(Math, this.payments);
                //      |               case "max":   return Math.max.apply(Math, this.payments);
                //      |               case "sum":   return sum(this.payments);
                //      |               case "avg":   return sum(this.payments) / this.payments.length;
                //      |             }
                //      |           }
                //      |         )
                //      |       );
                //      |       // prints: 3 payments averaging 13 USD per payment.
                //      example:
                //      |       // uses an alternative PHP-like pattern for substitutions:
                //      |       dojo.replace("Hello, ${0} ${2}!",
                //      |         ["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g);
                //      |       // returns: Hello, Robert Cringely!
                return "";      // String
        }
        =====*/

        var _pattern = /\{([^\}]+)\}/g;
        dojo.replace = function(tmpl, map, pattern){
                return tmpl.replace(pattern || _pattern, d.isFunction(map) ?
                        map : function(_, k){ return d.getObject(k, false, map); });
        };
})();

}

if(!dojo._hasResource["dojo._base.array"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.array"] = true;
dojo.provide("dojo._base.array");



(function(){
        var _getParts = function(arr, obj, cb){
                return [
                        (typeof arr == "string") ? arr.split("") : arr,
                        obj || dojo.global,
                        // FIXME: cache the anonymous functions we create here?
                        (typeof cb == "string") ? new Function("item", "index", "array", cb) : cb
                ];
        };

        var everyOrSome = function(/*Boolean*/every, /*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
                var _p = _getParts(arr, thisObject, callback); arr = _p[0];
                for(var i=0,l=arr.length; i<l; ++i){
                        var result = !!_p[2].call(_p[1], arr[i], i, arr);
                        if(every ^ result){
                                return result; // Boolean
                        }
                }
                return every; // Boolean
        };

        dojo.mixin(dojo, {
                indexOf: function(      /*Array*/               array,
                                                        /*Object*/              value,
                                                        /*Integer?*/    fromIndex,
                                                        /*Boolean?*/    findLast){
                        // summary:
                        //              locates the first index of the provided value in the
                        //              passed array. If the value is not found, -1 is returned.
                        // description:
                        //              This method corresponds to the JavaScript 1.6 Array.indexOf method, with one difference: when
                        //              run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
                        //              1.6's indexOf skips the holes in the sparse array.
                        //              For details on this method, see:
                        //                      https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf

                        var step = 1, end = array.length || 0, i = 0;
                        if(findLast){
                                i = end - 1;
                                step = end = -1;
                        }
                        if(fromIndex != undefined){ i = fromIndex; }
                        if((findLast && i > end) || i < end){
                                for(; i != end; i += step){
                                        if(array[i] == value){ return i; }
                                }
                        }
                        return -1;      // Number
                },

                lastIndexOf: function(/*Array*/array, /*Object*/value, /*Integer?*/fromIndex){
                        // summary:
                        //              locates the last index of the provided value in the passed
                        //              array. If the value is not found, -1 is returned.
                        // description:
                        //              This method corresponds to the JavaScript 1.6 Array.lastIndexOf method, with one difference: when
                        //              run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
                        //              1.6's lastIndexOf skips the holes in the sparse array.
                        //              For details on this method, see:
                        //                      https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/lastIndexOf
                        return dojo.indexOf(array, value, fromIndex, true); // Number
                },

                forEach: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
                        //      summary:
                        //              for every item in arr, callback is invoked. Return values are ignored.
                        //              If you want to break out of the loop, consider using dojo.every() or dojo.some().
                        //              forEach does not allow breaking out of the loop over the items in arr.
                        //      arr:
                        //              the array to iterate over. If a string, operates on individual characters.
                        //      callback:
                        //              a function is invoked with three arguments: item, index, and array
                        //      thisObject:
                        //              may be used to scope the call to callback
                        //      description:
                        //              This function corresponds to the JavaScript 1.6 Array.forEach() method, with one difference: when
                        //              run over sparse arrays, this implemenation passes the "holes" in the sparse array to
                        //              the callback function with a value of undefined. JavaScript 1.6's forEach skips the holes in the sparse array.
                        //              For more details, see:
                        //                      https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach
                        //      example:
                        //      |       // log out all members of the array:
                        //      |       dojo.forEach(
                        //      |               [ "thinger", "blah", "howdy", 10 ],
                        //      |               function(item){
                        //      |                       console.log(item);
                        //      |               }
                        //      |       );
                        //      example:
                        //      |       // log out the members and their indexes
                        //      |       dojo.forEach(
                        //      |               [ "thinger", "blah", "howdy", 10 ],
                        //      |               function(item, idx, arr){
                        //      |                       console.log(item, "at index:", idx);
                        //      |               }
                        //      |       );
                        //      example:
                        //      |       // use a scoped object member as the callback
                        //      |
                        //      |       var obj = {
                        //      |               prefix: "logged via obj.callback:",
                        //      |               callback: function(item){
                        //      |                       console.log(this.prefix, item);
                        //      |               }
                        //      |       };
                        //      |
                        //      |       // specifying the scope function executes the callback in that scope
                        //      |       dojo.forEach(
                        //      |               [ "thinger", "blah", "howdy", 10 ],
                        //      |               obj.callback,
                        //      |               obj
                        //      |       );
                        //      |
                        //      |       // alternately, we can accomplish the same thing with dojo.hitch()
                        //      |       dojo.forEach(
                        //      |               [ "thinger", "blah", "howdy", 10 ],
                        //      |               dojo.hitch(obj, "callback")
                        //      |       );

                        // match the behavior of the built-in forEach WRT empty arrs
                        if(!arr || !arr.length){ return; }

                        // FIXME: there are several ways of handilng thisObject. Is
                        // dojo.global always the default context?
                        var _p = _getParts(arr, thisObject, callback); arr = _p[0];
                        for(var i=0,l=arr.length; i<l; ++i){
                                _p[2].call(_p[1], arr[i], i, arr);
                        }
                },

                every: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
                        // summary:
                        //              Determines whether or not every item in arr satisfies the
                        //              condition implemented by callback.
                        // arr:
                        //              the array to iterate on. If a string, operates on individual characters.
                        // callback:
                        //              a function is invoked with three arguments: item, index,
                        //              and array and returns true if the condition is met.
                        // thisObject:
                        //              may be used to scope the call to callback
                        // description:
                        //              This function corresponds to the JavaScript 1.6 Array.every() method, with one difference: when
                        //              run over sparse arrays, this implemenation passes the "holes" in the sparse array to
                        //              the callback function with a value of undefined. JavaScript 1.6's every skips the holes in the sparse array.
                        //              For more details, see:
                        //                      https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/every
                        // example:
                        //      |       // returns false
                        //      |       dojo.every([1, 2, 3, 4], function(item){ return item>1; });
                        // example:
                        //      |       // returns true
                        //      |       dojo.every([1, 2, 3, 4], function(item){ return item>0; });
                        return everyOrSome(true, arr, callback, thisObject); // Boolean
                },

                some: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
                        // summary:
                        //              Determines whether or not any item in arr satisfies the
                        //              condition implemented by callback.
                        // arr:
                        //              the array to iterate over. If a string, operates on individual characters.
                        // callback:
                        //              a function is invoked with three arguments: item, index,
                        //              and array and returns true if the condition is met.
                        // thisObject:
                        //              may be used to scope the call to callback
                        // description:
                        //              This function corresponds to the JavaScript 1.6 Array.some() method, with one difference: when
                        //              run over sparse arrays, this implemenation passes the "holes" in the sparse array to
                        //              the callback function with a value of undefined. JavaScript 1.6's some skips the holes in the sparse array.
                        //              For more details, see:
                        //                      https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/some
                        // example:
                        //      |       // is true
                        //      |       dojo.some([1, 2, 3, 4], function(item){ return item>1; });
                        // example:
                        //      |       // is false
                        //      |       dojo.some([1, 2, 3, 4], function(item){ return item<1; });
                        return everyOrSome(false, arr, callback, thisObject); // Boolean
                },

                map: function(/*Array|String*/arr, /*Function|String*/callback, /*Function?*/thisObject){
                        // summary:
                        //              applies callback to each element of arr and returns
                        //              an Array with the results
                        // arr:
                        //              the array to iterate on. If a string, operates on
                        //              individual characters.
                        // callback:
                        //              a function is invoked with three arguments, (item, index,
                        //              array),  and returns a value
                        // thisObject:
                        //              may be used to scope the call to callback
                        // description:
                        //              This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when
                        //              run over sparse arrays, this implemenation passes the "holes" in the sparse array to
                        //              the callback function with a value of undefined. JavaScript 1.6's map skips the holes in the sparse array.
                        //              For more details, see:
                        //                      https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
                        // example:
                        //      |       // returns [2, 3, 4, 5]
                        //      |       dojo.map([1, 2, 3, 4], function(item){ return item+1 });

                        var _p = _getParts(arr, thisObject, callback); arr = _p[0];
                        var outArr = (arguments[3] ? (new arguments[3]()) : []);
                        for(var i=0,l=arr.length; i<l; ++i){
                                outArr.push(_p[2].call(_p[1], arr[i], i, arr));
                        }
                        return outArr; // Array
                },

                filter: function(/*Array*/arr, /*Function|String*/callback, /*Object?*/thisObject){
                        // summary:
                        //              Returns a new Array with those items from arr that match the
                        //              condition implemented by callback.
                        // arr:
                        //              the array to iterate over.
                        // callback:
                        //              a function that is invoked with three arguments (item,
                        //              index, array). The return of this function is expected to
                        //              be a boolean which determines whether the passed-in item
                        //              will be included in the returned array.
                        // thisObject:
                        //              may be used to scope the call to callback
                        // description:
                        //              This function corresponds to the JavaScript 1.6 Array.filter() method, with one difference: when
                        //              run over sparse arrays, this implemenation passes the "holes" in the sparse array to
                        //              the callback function with a value of undefined. JavaScript 1.6's filter skips the holes in the sparse array.
                        //              For more details, see:
                        //                      https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
                        // example:
                        //      |       // returns [2, 3, 4]
                        //      |       dojo.filter([1, 2, 3, 4], function(item){ return item>1; });

                        var _p = _getParts(arr, thisObject, callback); arr = _p[0];
                        var outArr = [];
                        for(var i=0,l=arr.length; i<l; ++i){
                                if(_p[2].call(_p[1], arr[i], i, arr)){
                                        outArr.push(arr[i]);
                                }
                        }
                        return outArr; // Array
                }
        });
})();
/*
*/

}

if(!dojo._hasResource["dojo._base.declare"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.declare"] = true;
dojo.provide("dojo._base.declare");




(function(){
        var d = dojo, mix = d._mixin, op = Object.prototype, opts = op.toString,
                xtor = new Function, counter = 0, cname = "constructor";

        function err(msg, cls){ throw new Error("declare" + (cls ? " " + cls : "") + ": " + msg); }

        // C3 Method Resolution Order (see http://www.python.org/download/releases/2.3/mro/)
        function c3mro(bases, className){
                var result = [], roots = [{cls: 0, refs: []}], nameMap = {}, clsCount = 1,
                        l = bases.length, i = 0, j, lin, base, top, proto, rec, name, refs;

                // build a list of bases naming them if needed
                for(; i < l; ++i){
                        base = bases[i];
                        if(!base){
                                err("mixin #" + i + " is unknown. Did you use dojo.require to pull it in?", className);
                        }else if(opts.call(base) != "[object Function]"){
                                err("mixin #" + i + " is not a callable constructor.", className);
                        }
                        lin = base._meta ? base._meta.bases : [base];
                        top = 0;
                        // add bases to the name map
                        for(j = lin.length - 1; j >= 0; --j){
                                proto = lin[j].prototype;
                                if(!proto.hasOwnProperty("declaredClass")){
                                        proto.declaredClass = "uniqName_" + (counter++);
                                }
                                name = proto.declaredClass;
                                if(!nameMap.hasOwnProperty(name)){
                                        nameMap[name] = {count: 0, refs: [], cls: lin[j]};
                                        ++clsCount;
                                }
                                rec = nameMap[name];
                                if(top && top !== rec){
                                        rec.refs.push(top);
                                        ++top.count;
                                }
                                top = rec;
                        }
                        ++top.count;
                        roots[0].refs.push(top);
                }

                // remove classes without external references recursively
                while(roots.length){
                        top = roots.pop();
                        result.push(top.cls);
                        --clsCount;
                        // optimization: follow a single-linked chain
                        while(refs = top.refs, refs.length == 1){
                                top = refs[0];
                                if(!top || --top.count){
                                        // branch or end of chain => do not end to roots
                                        top = 0;
                                        break;
                                }
                                result.push(top.cls);
                                --clsCount;
                        }
                        if(top){
                                // branch
                                for(i = 0, l = refs.length; i < l; ++i){
                                        top = refs[i];
                                        if(!--top.count){
                                                roots.push(top);
                                        }
                                }
                        }
                }
                if(clsCount){
                        err("can't build consistent linearization", className);
                }

                // calculate the superclass offset
                base = bases[0];
                result[0] = base ?
                        base._meta && base === result[result.length - base._meta.bases.length] ?
                                base._meta.bases.length : 1 : 0;

                return result;
        }

        function inherited(args, a, f){
                var name, chains, bases, caller, meta, base, proto, opf, pos,
                        cache = this._inherited = this._inherited || {};

                // crack arguments
                if(typeof args == "string"){
                        name = args;
                        args = a;
                        a = f;
                }
                f = 0;

                caller = args.callee;
                name = name || caller.nom;
                if(!name){
                        err("can't deduce a name to call inherited()", this.declaredClass);
                }

                meta = this.constructor._meta;
                bases = meta.bases;

                pos = cache.p;
                if(name != cname){
                        // method
                        if(cache.c !== caller){
                                // cache bust
                                pos = 0;
                                base = bases[0];
                                meta = base._meta;
                                if(meta.hidden[name] !== caller){
                                        // error detection
                                        chains = meta.chains;
                                        if(chains && typeof chains[name] == "string"){
                                                err("calling chained method with inherited: " + name, this.declaredClass);
                                        }
                                        // find caller
                                        do{
                                                meta = base._meta;
                                                proto = base.prototype;
                                                if(meta && (proto[name] === caller && proto.hasOwnProperty(name) || meta.hidden[name] === caller)){
                                                        break;
                                                }
                                        }while(base = bases[++pos]); // intentional assignment
                                        pos = base ? pos : -1;
                                }
                        }
                        // find next
                        base = bases[++pos];
                        if(base){
                                proto = base.prototype;
                                if(base._meta && proto.hasOwnProperty(name)){
                                        f = proto[name];
                                }else{
                                        opf = op[name];
                                        do{
                                                proto = base.prototype;
                                                f = proto[name];
                                                if(f && (base._meta ? proto.hasOwnProperty(name) : f !== opf)){
                                                        break;
                                                }
                                        }while(base = bases[++pos]); // intentional assignment
                                }
                        }
                        f = base && f || op[name];
                }else{
                        // constructor
                        if(cache.c !== caller){
                                // cache bust
                                pos = 0;
                                meta = bases[0]._meta;
                                if(meta && meta.ctor !== caller){
                                        // error detection
                                        chains = meta.chains;
                                        if(!chains || chains.constructor !== "manual"){
                                                err("calling chained constructor with inherited", this.declaredClass);
                                        }
                                        // find caller
                                        while(base = bases[++pos]){ // intentional assignment
                                                meta = base._meta;
                                                if(meta && meta.ctor === caller){
                                                        break;
                                                }
                                        }
                                        pos = base ? pos : -1;
                                }
                        }
                        // find next
                        while(base = bases[++pos]){     // intentional assignment
                                meta = base._meta;
                                f = meta ? meta.ctor : base;
                                if(f){
                                        break;
                                }
                        }
                        f = base && f;
                }

                // cache the found super method
                cache.c = f;
                cache.p = pos;

                // now we have the result
                if(f){
                        return a === true ? f : f.apply(this, a || args);
                }
                // intentionally if a super method was not found
        }

        function getInherited(name, args){
                if(typeof name == "string"){
                        return this.inherited(name, args, true);
                }
                return this.inherited(name, true);
        }

        // emulation of "instanceof"
        function isInstanceOf(cls){
                var bases = this.constructor._meta.bases;
                for(var i = 0, l = bases.length; i < l; ++i){
                        if(bases[i] === cls){
                                return true;
                        }
                }
                return this instanceof cls;
        }

        function mixOwn(target, source){
                var name, i = 0, l = d._extraNames.length;
                // add props adding metadata for incoming functions skipping a constructor
                for(name in source){
                        if(name != cname && source.hasOwnProperty(name)){
                                target[name] = source[name];
                        }
                }
                // process unenumerable methods on IE
                for(; i < l; ++i){
                        name = d._extraNames[i];
                        if(name != cname && source.hasOwnProperty(name)){
                                target[name] = source[name];
                        }
                }
        }

        // implementation of safe mixin function
        function safeMixin(target, source){
                var name, t, i = 0, l = d._extraNames.length;
                // add props adding metadata for incoming functions skipping a constructor
                for(name in source){
                        t = source[name];
                        if((t !== op[name] || !(name in op)) && name != cname){
                                if(opts.call(t) == "[object Function]"){
                                        // non-trivial function method => attach its name
                                        t.nom = name;
                                }
                                target[name] = t;
                        }
                }
                // process unenumerable methods on IE
                for(; i < l; ++i){
                        name = d._extraNames[i];
                        t = source[name];
                        if((t !== op[name] || !(name in op)) && name != cname){
                                if(opts.call(t) == "[object Function]"){
                                        // non-trivial function method => attach its name
                                        t.nom = name;
                                }
                                target[name] = t;
                        }
                }
                return target;
        }

        function extend(source){
                safeMixin(this.prototype, source);
                return this;
        }

        // chained constructor compatible with the legacy dojo.declare()
        function chainedConstructor(bases, ctorSpecial){
                return function(){
                        var a = arguments, args = a, a0 = a[0], f, i, m,
                                l = bases.length, preArgs;

                        if(!(this instanceof a.callee)){
                                // not called via new, so force it
                                return applyNew(a);
                        }

                        //this._inherited = {};
                        // perform the shaman's rituals of the original dojo.declare()
                        // 1) call two types of the preamble
                        if(ctorSpecial && (a0 && a0.preamble || this.preamble)){
                                // full blown ritual
                                preArgs = new Array(bases.length);
                                // prepare parameters
                                preArgs[0] = a;
                                for(i = 0;;){
                                        // process the preamble of the 1st argument
                                        a0 = a[0];
                                        if(a0){
                                                f = a0.preamble;
                                                if(f){
                                                        a = f.apply(this, a) || a;
                                                }
                                        }
                                        // process the preamble of this class
                                        f = bases[i].prototype;
                                        f = f.hasOwnProperty("preamble") && f.preamble;
                                        if(f){
                                                a = f.apply(this, a) || a;
                                        }
                                        // one peculiarity of the preamble:
                                        // it is called if it is not needed,
                                        // e.g., there is no constructor to call
                                        // let's watch for the last constructor
                                        // (see ticket #9795)
                                        if(++i == l){
                                                break;
                                        }
                                        preArgs[i] = a;
                                }
                        }
                        // 2) call all non-trivial constructors using prepared arguments
                        for(i = l - 1; i >= 0; --i){
                                f = bases[i];
                                m = f._meta;
                                f = m ? m.ctor : f;
                                if(f){
                                        f.apply(this, preArgs ? preArgs[i] : a);
                                }
                        }
                        // 3) continue the original ritual: call the postscript
                        f = this.postscript;
                        if(f){
                                f.apply(this, args);
                        }
                };
        }


        // chained constructor compatible with the legacy dojo.declare()
        function singleConstructor(ctor, ctorSpecial){
                return function(){
                        var a = arguments, t = a, a0 = a[0], f;

                        if(!(this instanceof a.callee)){
                                // not called via new, so force it
                                return applyNew(a);
                        }

                        //this._inherited = {};
                        // perform the shaman's rituals of the original dojo.declare()
                        // 1) call two types of the preamble
                        if(ctorSpecial){
                                // full blown ritual
                                if(a0){
                                        // process the preamble of the 1st argument
                                        f = a0.preamble;
                                        if(f){
                                                t = f.apply(this, t) || t;
                                        }
                                }
                                f = this.preamble;
                                if(f){
                                        // process the preamble of this class
                                        f.apply(this, t);
                                        // one peculiarity of the preamble:
                                        // it is called even if it is not needed,
                                        // e.g., there is no constructor to call
                                        // let's watch for the last constructor
                                        // (see ticket #9795)
                                }
                        }
                        // 2) call a constructor
                        if(ctor){
                                ctor.apply(this, a);
                        }
                        // 3) continue the original ritual: call the postscript
                        f = this.postscript;
                        if(f){
                                f.apply(this, a);
                        }
                };
        }

        // plain vanilla constructor (can use inherited() to call its base constructor)
        function simpleConstructor(bases){
                return function(){
                        var a = arguments, i = 0, f, m;

                        if(!(this instanceof a.callee)){
                                // not called via new, so force it
                                return applyNew(a);
                        }

                        //this._inherited = {};
                        // perform the shaman's rituals of the original dojo.declare()
                        // 1) do not call the preamble
                        // 2) call the top constructor (it can use this.inherited())
                        for(; f = bases[i]; ++i){ // intentional assignment
                                m = f._meta;
                                f = m ? m.ctor : f;
                                if(f){
                                        f.apply(this, a);
                                        break;
                                }
                        }
                        // 3) call the postscript
                        f = this.postscript;
                        if(f){
                                f.apply(this, a);
                        }
                };
        }

        function chain(name, bases, reversed){
                return function(){
                        var b, m, f, i = 0, step = 1;
                        if(reversed){
                                i = bases.length - 1;
                                step = -1;
                        }
                        for(; b = bases[i]; i += step){ // intentional assignment
                                m = b._meta;
                                f = (m ? m.hidden : b.prototype)[name];
                                if(f){
                                        f.apply(this, arguments);
                                }
                        }
                };
        }

        // forceNew(ctor)
        // return a new object that inherits from ctor.prototype but
        // without actually running ctor on the object.
        function forceNew(ctor){
                // create object with correct prototype using a do-nothing
                // constructor
                xtor.prototype = ctor.prototype;
                var t = new xtor;
                xtor.prototype = null;  // clean up
                return t;
        }

        // applyNew(args)
        // just like 'new ctor()' except that the constructor and its arguments come
        // from args, which must be an array or an arguments object
        function applyNew(args){
                // create an object with ctor's prototype but without
                // calling ctor on it.
                var ctor = args.callee, t = forceNew(ctor);
                // execute the real constructor on the new object
                ctor.apply(t, args);
                return t;
        }

        d.declare = function(className, superclass, props){
                // crack parameters
                if(typeof className != "string"){
                        props = superclass;
                        superclass = className;
                        className = "";
                }
                props = props || {};

                var proto, i, t, ctor, name, bases, chains, mixins = 1, parents = superclass;

                // build a prototype
                if(opts.call(superclass) == "[object Array]"){
                        // C3 MRO
                        bases = c3mro(superclass, className);
                        t = bases[0];
                        mixins = bases.length - t;
                        superclass = bases[mixins];
                }else{
                        bases = [0];
                        if(superclass){
                                if(opts.call(superclass) == "[object Function]"){
                                        t = superclass._meta;
                                        bases = bases.concat(t ? t.bases : superclass);
                                }else{
                                        err("base class is not a callable constructor.", className);
                                }
                        }else if(superclass !== null){
                                err("unknown base class. Did you use dojo.require to pull it in?", className);
                        }
                }
                if(superclass){
                        for(i = mixins - 1;; --i){
                                proto = forceNew(superclass);
                                if(!i){
                                        // stop if nothing to add (the last base)
                                        break;
                                }
                                // mix in properties
                                t = bases[i];
                                (t._meta ? mixOwn : mix)(proto, t.prototype);
                                // chain in new constructor
                                ctor = new Function;
                                ctor.superclass = superclass;
                                ctor.prototype = proto;
                                superclass = proto.constructor = ctor;
                        }
                }else{
                        proto = {};
                }
                // add all properties
                safeMixin(proto, props);
                // add constructor
                t = props.constructor;
                if(t !== op.constructor){
                        t.nom = cname;
                        proto.constructor = t;
                }

                // collect chains and flags
                for(i = mixins - 1; i; --i){ // intentional assignment
                        t = bases[i]._meta;
                        if(t && t.chains){
                                chains = mix(chains || {}, t.chains);
                        }
                }
                if(proto["-chains-"]){
                        chains = mix(chains || {}, proto["-chains-"]);
                }

                // build ctor
                t = !chains || !chains.hasOwnProperty(cname);
                bases[0] = ctor = (chains && chains.constructor === "manual") ? simpleConstructor(bases) :
                        (bases.length == 1 ? singleConstructor(props.constructor, t) : chainedConstructor(bases, t));

                // add meta information to the constructor
                ctor._meta  = {bases: bases, hidden: props, chains: chains,
                        parents: parents, ctor: props.constructor};
                ctor.superclass = superclass && superclass.prototype;
                ctor.extend = extend;
                ctor.prototype = proto;
                proto.constructor = ctor;

                // add "standard" methods to the prototype
                proto.getInherited = getInherited;
                proto.inherited = inherited;
                proto.isInstanceOf = isInstanceOf;

                // add name if specified
                if(className){
                        proto.declaredClass = className;
                        d.setObject(className, ctor);
                }

                // build chains and add them to the prototype
                if(chains){
                        for(name in chains){
                                if(proto[name] && typeof chains[name] == "string" && name != cname){
                                        t = proto[name] = chain(name, bases, chains[name] === "after");
                                        t.nom = name;
                                }
                        }
                }
                // chained methods do not return values
                // no need to chain "invisible" functions

                return ctor;    // Function
        };

        d.safeMixin = safeMixin;

        /*=====
        dojo.declare = function(className, superclass, props){
                //      summary:
                //              Create a feature-rich constructor from compact notation.
                //      className: String?:
                //              The optional name of the constructor (loosely, a "class")
                //              stored in the "declaredClass" property in the created prototype.
                //              It will be used as a global name for a created constructor.
                //      superclass: Function|Function[]:
                //              May be null, a Function, or an Array of Functions. This argument
                //              specifies a list of bases (the left-most one is the most deepest
                //              base).
                //      props: Object:
                //              An object whose properties are copied to the created prototype.
                //              Add an instance-initialization function by making it a property
                //              named "constructor".
                //      returns:
                //              New constructor function.
                //      description:
                //              Create a constructor using a compact notation for inheritance and
                //              prototype extension.
                //
                //              Mixin ancestors provide a type of multiple inheritance.
                //              Prototypes of mixin ancestors are copied to the new class:
                //              changes to mixin prototypes will not affect classes to which
                //              they have been mixed in.
                //
                //              Ancestors can be compound classes created by this version of
                //              dojo.declare. In complex cases all base classes are going to be
                //              linearized according to C3 MRO algorithm
                //              (see http://www.python.org/download/releases/2.3/mro/ for more
                //              details).
                //
                //              "className" is cached in "declaredClass" property of the new class,
                //              if it was supplied. The immediate super class will be cached in
                //              "superclass" property of the new class.
                //
                //              Methods in "props" will be copied and modified: "nom" property
                //              (the declared name of the method) will be added to all copied
                //              functions to help identify them for the internal machinery. Be
                //              very careful, while reusing methods: if you use the same
                //              function under different names, it can produce errors in some
                //              cases.
                //
                //              It is possible to use constructors created "manually" (without
                //              dojo.declare) as bases. They will be called as usual during the
                //              creation of an instance, their methods will be chained, and even
                //              called by "this.inherited()".
                //
                //              Special property "-chains-" governs how to chain methods. It is
                //              a dictionary, which uses method names as keys, and hint strings
                //              as values. If a hint string is "after", this method will be
                //              called after methods of its base classes. If a hint string is
                //              "before", this method will be called before methods of its base
                //              classes.
                //
                //              If "constructor" is not mentioned in "-chains-" property, it will
                //              be chained using the legacy mode: using "after" chaining,
                //              calling preamble() method before each constructor, if available,
                //              and calling postscript() after all constructors were executed.
                //              If the hint is "after", it is chained as a regular method, but
                //              postscript() will be called after the chain of constructors.
                //              "constructor" cannot be chained "before", but it allows
                //              a special hint string: "manual", which means that constructors
                //              are not going to be chained in any way, and programmer will call
                //              them manually using this.inherited(). In the latter case
                //              postscript() will be called after the construction.
                //
                //              All chaining hints are "inherited" from base classes and
                //              potentially can be overridden. Be very careful when overriding
                //              hints! Make sure that all chained methods can work in a proposed
                //              manner of chaining.
                //
                //              Once a method was chained, it is impossible to unchain it. The
                //              only exception is "constructor". You don't need to define a
                //              method in order to supply a chaining hint.
                //
                //              If a method is chained, it cannot use this.inherited() because
                //              all other methods in the hierarchy will be called automatically.
                //
                //              Usually constructors and initializers of any kind are chained
                //              using "after" and destructors of any kind are chained as
                //              "before". Note that chaining assumes that chained methods do not
                //              return any value: any returned value will be discarded.
                //
                //      example:
                //      |       dojo.declare("my.classes.bar", my.classes.foo, {
                //      |               // properties to be added to the class prototype
                //      |               someValue: 2,
                //      |               // initialization function
                //      |               constructor: function(){
                //      |                       this.myComplicatedObject = new ReallyComplicatedObject();
                //      |               },
                //      |               // other functions
                //      |               someMethod: function(){
                //      |                       doStuff();
                //      |               }
                //      |       });
                //
                //      example:
                //      |       var MyBase = dojo.declare(null, {
                //      |               // constructor, properties, and methods go here
                //      |               // ...
                //      |       });
                //      |       var MyClass1 = dojo.declare(MyBase, {
                //      |               // constructor, properties, and methods go here
                //      |               // ...
                //      |       });
                //      |       var MyClass2 = dojo.declare(MyBase, {
                //      |               // constructor, properties, and methods go here
                //      |               // ...
                //      |       });
                //      |       var MyDiamond = dojo.declare([MyClass1, MyClass2], {
                //      |               // constructor, properties, and methods go here
                //      |               // ...
                //      |       });
                //
                //      example:
                //      |       var F = function(){ console.log("raw constructor"); };
                //      |       F.prototype.method = function(){
                //      |               console.log("raw method");
                //      |       };
                //      |       var A = dojo.declare(F, {
                //      |               constructor: function(){
                //      |                       console.log("A.constructor");
                //      |               },
                //      |               method: function(){
                //      |                       console.log("before calling F.method...");
                //      |                       this.inherited(arguments);
                //      |                       console.log("...back in A");
                //      |               }
                //      |       });
                //      |       new A().method();
                //      |       // will print:
                //      |       // raw constructor
                //      |       // A.constructor
                //      |       // before calling F.method...
                //      |       // raw method
                //      |       // ...back in A
                //
                //      example:
                //      |       var A = dojo.declare(null, {
                //      |               "-chains-": {
                //      |                       destroy: "before"
                //      |               }
                //      |       });
                //      |       var B = dojo.declare(A, {
                //      |               constructor: function(){
                //      |                       console.log("B.constructor");
                //      |               },
                //      |               destroy: function(){
                //      |                       console.log("B.destroy");
                //      |               }
                //      |       });
                //      |       var C = dojo.declare(B, {
                //      |               constructor: function(){
                //      |                       console.log("C.constructor");
                //      |               },
                //      |               destroy: function(){
                //      |                       console.log("C.destroy");
                //      |               }
                //      |       });
                //      |       new C().destroy();
                //      |       // prints:
                //      |       // B.constructor
                //      |       // C.constructor
                //      |       // C.destroy
                //      |       // B.destroy
                //
                //      example:
                //      |       var A = dojo.declare(null, {
                //      |               "-chains-": {
                //      |                       constructor: "manual"
                //      |               }
                //      |       });
                //      |       var B = dojo.declare(A, {
                //      |               constructor: function(){
                //      |                       // ...
                //      |                       // call the base constructor with new parameters
                //      |                       this.inherited(arguments, [1, 2, 3]);
                //      |                       // ...
                //      |               }
                //      |       });
                //
                //      example:
                //      |       var A = dojo.declare(null, {
                //      |               "-chains-": {
                //      |                       m1: "before"
                //      |               },
                //      |               m1: function(){
                //      |                       console.log("A.m1");
                //      |               },
                //      |               m2: function(){
                //      |                       console.log("A.m2");
                //      |               }
                //      |       });
                //      |       var B = dojo.declare(A, {
                //      |               "-chains-": {
                //      |                       m2: "after"
                //      |               },
                //      |               m1: function(){
                //      |                       console.log("B.m1");
                //      |               },
                //      |               m2: function(){
                //      |                       console.log("B.m2");
                //      |               }
                //      |       });
                //      |       var x = new B();
                //      |       x.m1();
                //      |       // prints:
                //      |       // B.m1
                //      |       // A.m1
                //      |       x.m2();
                //      |       // prints:
                //      |       // A.m2
                //      |       // B.m2
                return new Function(); // Function
        };
        =====*/

        /*=====
        dojo.safeMixin = function(target, source){
                //      summary:
                //              Mix in properties skipping a constructor and decorating functions
                //              like it is done by dojo.declare.
                //      target: Object
                //              Target object to accept new properties.
                //      source: Object
                //              Source object for new properties.
                //      description:
                //              This function is used to mix in properties like dojo._mixin does,
                //              but it skips a constructor property and decorates functions like
                //              dojo.declare does.
                //
                //              It is meant to be used with classes and objects produced with
                //              dojo.declare. Functions mixed in with dojo.safeMixin can use
                //              this.inherited() like normal methods.
                //
                //              This function is used to implement extend() method of a constructor
                //              produced with dojo.declare().
                //
                //      example:
                //      |       var A = dojo.declare(null, {
                //      |               m1: function(){
                //      |                       console.log("A.m1");
                //      |               },
                //      |               m2: function(){
                //      |                       console.log("A.m2");
                //      |               }
                //      |       });
                //      |       var B = dojo.declare(A, {
                //      |               m1: function(){
                //      |                       this.inherited(arguments);
                //      |                       console.log("B.m1");
                //      |               }
                //      |       });
                //      |       B.extend({
                //      |               m2: function(){
                //      |                       this.inherited(arguments);
                //      |                       console.log("B.m2");
                //      |               }
                //      |       });
                //      |       var x = new B();
                //      |       dojo.safeMixin(x, {
                //      |               m1: function(){
                //      |                       this.inherited(arguments);
                //      |                       console.log("X.m1");
                //      |               },
                //      |               m2: function(){
                //      |                       this.inherited(arguments);
                //      |                       console.log("X.m2");
                //      |               }
                //      |       });
                //      |       x.m2();
                //      |       // prints:
                //      |       // A.m1
                //      |       // B.m1
                //      |       // X.m1
        };
        =====*/

        /*=====
        Object.inherited = function(name, args, newArgs){
                //      summary:
                //              Calls a super method.
                //      name: String?
                //              The optional method name. Should be the same as the caller's
                //              name. Usually "name" is specified in complex dynamic cases, when
                //              the calling method was dynamically added, undecorated by
                //              dojo.declare, and it cannot be determined.
                //      args: Arguments
                //              The caller supply this argument, which should be the original
                //              "arguments".
                //      newArgs: Object?
                //              If "true", the found function will be returned without
                //              executing it.
                //              If Array, it will be used to call a super method. Otherwise
                //              "args" will be used.
                //      returns:
                //              Whatever is returned by a super method, or a super method itself,
                //              if "true" was specified as newArgs.
                //      description:
                //              This method is used inside method of classes produced with
                //              dojo.declare to call a super method (next in the chain). It is
                //              used for manually controlled chaining. Consider using the regular
                //              chaining, because it is faster. Use "this.inherited()" only in
                //              complex cases.
                //
                //              This method cannot me called from automatically chained
                //              constructors including the case of a special (legacy)
                //              constructor chaining. It cannot be called from chained methods.
                //
                //              If "this.inherited()" cannot find the next-in-chain method, it
                //              does nothing and returns "undefined". The last method in chain
                //              can be a default method implemented in Object, which will be
                //              called last.
                //
                //              If "name" is specified, it is assumed that the method that
                //              received "args" is the parent method for this call. It is looked
                //              up in the chain list and if it is found the next-in-chain method
                //              is called. If it is not found, the first-in-chain method is
                //              called.
                //
                //              If "name" is not specified, it will be derived from the calling
                //              method (using a methoid property "nom").
                //
                //      example:
                //      |       var B = dojo.declare(A, {
                //      |               method1: function(a, b, c){
                //      |                       this.inherited(arguments);
                //      |               },
                //      |               method2: function(a, b){
                //      |                       return this.inherited(arguments, [a + b]);
                //      |               }
                //      |       });
                //      |       // next method is not in the chain list because it is added
                //      |       // manually after the class was created.
                //      |       B.prototype.method3 = function(){
                //      |               console.log("This is a dynamically-added method.");
                //      |               this.inherited("method3", arguments);
                //      |       };
                //      example:
                //      |       var B = dojo.declare(A, {
                //      |               method: function(a, b){
                //      |                       var super = this.inherited(arguments, true);
                //      |                       // ...
                //      |                       if(!super){
                //      |                               console.log("there is no super method");
                //      |                               return 0;
                //      |                       }
                //      |                       return super.apply(this, arguments);
                //      |               }
                //      |       });
                return  {};     // Object
        }
        =====*/

        /*=====
        Object.getInherited = function(name, args){
                //      summary:
                //              Returns a super method.
                //      name: String?
                //              The optional method name. Should be the same as the caller's
                //              name. Usually "name" is specified in complex dynamic cases, when
                //              the calling method was dynamically added, undecorated by
                //              dojo.declare, and it cannot be determined.
                //      args: Arguments
                //              The caller supply this argument, which should be the original
                //              "arguments".
                //      returns:
                //              Returns a super method (Function) or "undefined".
                //      description:
                //              This method is a convenience method for "this.inherited()".
                //              It uses the same algorithm but instead of executing a super
                //              method, it returns it, or "undefined" if not found.
                //
                //      example:
                //      |       var B = dojo.declare(A, {
                //      |               method: function(a, b){
                //      |                       var super = this.getInherited(arguments);
                //      |                       // ...
                //      |                       if(!super){
                //      |                               console.log("there is no super method");
                //      |                               return 0;
                //      |                       }
                //      |                       return super.apply(this, arguments);
                //      |               }
                //      |       });
                return  {};     // Object
        }
        =====*/

        /*=====
        Object.isInstanceOf = function(cls){
                //      summary:
                //              Checks the inheritance chain to see if it is inherited from this
                //              class.
                //      cls: Function
                //              Class constructor.
                //      returns:
                //              "true", if this object is inherited from this class, "false"
                //              otherwise.
                //      description:
                //              This method is used with instances of classes produced with
                //              dojo.declare to determine of they support a certain interface or
                //              not. It models "instanceof" operator.
                //
                //      example:
                //      |       var A = dojo.declare(null, {
                //      |               // constructor, properties, and methods go here
                //      |               // ...
                //      |       });
                //      |       var B = dojo.declare(null, {
                //      |               // constructor, properties, and methods go here
                //      |               // ...
                //      |       });
                //      |       var C = dojo.declare([A, B], {
                //      |               // constructor, properties, and methods go here
                //      |               // ...
                //      |       });
                //      |       var D = dojo.declare(A, {
                //      |               // constructor, properties, and methods go here
                //      |               // ...
                //      |       });
                //      |
                //      |       var a = new A(), b = new B(), c = new C(), d = new D();
                //      |
                //      |       console.log(a.isInstanceOf(A)); // true
                //      |       console.log(b.isInstanceOf(A)); // false
                //      |       console.log(c.isInstanceOf(A)); // true
                //      |       console.log(d.isInstanceOf(A)); // true
                //      |
                //      |       console.log(a.isInstanceOf(B)); // false
                //      |       console.log(b.isInstanceOf(B)); // true
                //      |       console.log(c.isInstanceOf(B)); // true
                //      |       console.log(d.isInstanceOf(B)); // false
                //      |
                //      |       console.log(a.isInstanceOf(C)); // false
                //      |       console.log(b.isInstanceOf(C)); // false
                //      |       console.log(c.isInstanceOf(C)); // true
                //      |       console.log(d.isInstanceOf(C)); // false
                //      |
                //      |       console.log(a.isInstanceOf(D)); // false
                //      |       console.log(b.isInstanceOf(D)); // false
                //      |       console.log(c.isInstanceOf(D)); // false
                //      |       console.log(d.isInstanceOf(D)); // true
                return  {};     // Object
        }
        =====*/

        /*=====
        Object.extend = function(source){
                //      summary:
                //              Adds all properties and methods of source to constructor's
                //              prototype, making them available to all instances created with
                //              constructor. This method is specific to constructors created with
                //              dojo.declare.
                //      source: Object
                //              Source object which properties are going to be copied to the
                //              constructor's prototype.
                //      description:
                //              Adds source properties to the constructor's prototype. It can
                //              override existing properties.
                //
                //              This method is similar to dojo.extend function, but it is specific
                //              to constructors produced by dojo.declare. It is implemented
                //              using dojo.safeMixin, and it skips a constructor property,
                //              and properly decorates copied functions.
                //
                //      example:
                //      |       var A = dojo.declare(null, {
                //      |               m1: function(){},
                //      |               s1: "Popokatepetl"
                //      |       });
                //      |       A.extend({
                //      |               m1: function(){},
                //      |               m2: function(){},
                //      |               f1: true,
                //      |               d1: 42
                //      |       });
        };
        =====*/
})();

}

if(!dojo._hasResource["dojo._base.connect"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.connect"] = true;
dojo.provide("dojo._base.connect");



// this file courtesy of the TurboAjax Group, licensed under a Dojo CLA

// low-level delegation machinery
dojo._listener = {
        // create a dispatcher function
        getDispatcher: function(){
                // following comments pulled out-of-line to prevent cloning them
                // in the returned function.
                // - indices (i) that are really in the array of listeners (ls) will
                //   not be in Array.prototype. This is the 'sparse array' trick
                //   that keeps us safe from libs that take liberties with built-in
                //   objects
                // - listener is invoked with current scope (this)
                return function(){
                        var ap = Array.prototype, c = arguments.callee, ls = c._listeners, t = c.target,
                        // return value comes from original target function
                                r = t && t.apply(this, arguments),
                        // make local copy of listener array so it is immutable during processing
                                i, lls = [].concat(ls)
                        ;

                        // invoke listeners after target function
                        for(i in lls){
                                if(!(i in ap)){
                                        lls[i].apply(this, arguments);
                                }
                        }
                        // return value comes from original target function
                        return r;
                };
        },
        // add a listener to an object
        add: function(/*Object*/ source, /*String*/ method, /*Function*/ listener){
                // Whenever 'method' is invoked, 'listener' will have the same scope.
                // Trying to supporting a context object for the listener led to
                // complexity.
                // Non trivial to provide 'once' functionality here
                // because listener could be the result of a dojo.hitch call,
                // in which case two references to the same hitch target would not
                // be equivalent.
                source = source || dojo.global;
                // The source method is either null, a dispatcher, or some other function
                var f = source[method];
                // Ensure a dispatcher
                if(!f || !f._listeners){
                        var d = dojo._listener.getDispatcher();
                        // original target function is special
                        d.target = f;
                        // dispatcher holds a list of listeners
                        d._listeners = [];
                        // redirect source to dispatcher
                        f = source[method] = d;
                }
                // The contract is that a handle is returned that can
                // identify this listener for disconnect.
                //
                // The type of the handle is private. Here is it implemented as Integer.
                // DOM event code has this same contract but handle is Function
                // in non-IE browsers.
                //
                // We could have separate lists of before and after listeners.
                return f._listeners.push(listener); /*Handle*/
        },
        // remove a listener from an object
        remove: function(/*Object*/ source, /*String*/ method, /*Handle*/ handle){
                var f = (source || dojo.global)[method];
                // remember that handle is the index+1 (0 is not a valid handle)
                if(f && f._listeners && handle--){
                        delete f._listeners[handle];
                }
        }
};

// Multiple delegation for arbitrary methods.

// This unit knows nothing about DOM, but we include DOM aware documentation
// and dontFix argument here to help the autodocs. Actual DOM aware code is in
// event.js.

dojo.connect = function(/*Object|null*/ obj,
                                                /*String*/ event,
                                                /*Object|null*/ context,
                                                /*String|Function*/ method,
                                                /*Boolean?*/ dontFix){
        // summary:
        //              `dojo.connect` is the core event handling and delegation method in
        //              Dojo. It allows one function to "listen in" on the execution of
        //              any other, triggering the second whenever the first is called. Many
        //              listeners may be attached to a function, and source functions may
        //              be either regular function calls or DOM events.
        //
        // description:
        //              Connects listeners to actions, so that after event fires, a
        //              listener is called with the same arguments passed to the original
        //              function.
        //
        //              Since `dojo.connect` allows the source of events to be either a
        //              "regular" JavaScript function or a DOM event, it provides a uniform
        //              interface for listening to all the types of events that an
        //              application is likely to deal with though a single, unified
        //              interface. DOM programmers may want to think of it as
        //              "addEventListener for everything and anything".
        //
        //              When setting up a connection, the `event` parameter must be a
        //              string that is the name of the method/event to be listened for. If
        //              `obj` is null, `dojo.global` is assumed, meaning that connections
        //              to global methods are supported but also that you may inadvertently
        //              connect to a global by passing an incorrect object name or invalid
        //              reference.
        //
        //              `dojo.connect` generally is forgiving. If you pass the name of a
        //              function or method that does not yet exist on `obj`, connect will
        //              not fail, but will instead set up a stub method. Similarly, null
        //              arguments may simply be omitted such that fewer than 4 arguments
        //              may be required to set up a connection See the examples for details.
        //
        //              The return value is a handle that is needed to
        //              remove this connection with `dojo.disconnect`.
        //
        // obj:
        //              The source object for the event function.
        //              Defaults to `dojo.global` if null.
        //              If obj is a DOM node, the connection is delegated
        //              to the DOM event manager (unless dontFix is true).
        //
        // event:
        //              String name of the event function in obj.
        //              I.e. identifies a property `obj[event]`.
        //
        // context:
        //              The object that method will receive as "this".
        //
        //              If context is null and method is a function, then method
        //              inherits the context of event.
        //
        //              If method is a string then context must be the source
        //              object object for method (context[method]). If context is null,
        //              dojo.global is used.
        //
        // method:
        //              A function reference, or name of a function in context.
        //              The function identified by method fires after event does.
        //              method receives the same arguments as the event.
        //              See context argument comments for information on method's scope.
        //
        // dontFix:
        //              If obj is a DOM node, set dontFix to true to prevent delegation
        //              of this connection to the DOM event manager.
        //
        // example:
        //              When obj.onchange(), do ui.update():
        //      |       dojo.connect(obj, "onchange", ui, "update");
        //      |       dojo.connect(obj, "onchange", ui, ui.update); // same
        //
        // example:
        //              Using return value for disconnect:
        //      |       var link = dojo.connect(obj, "onchange", ui, "update");
        //      |       ...
        //      |       dojo.disconnect(link);
        //
        // example:
        //              When onglobalevent executes, watcher.handler is invoked:
        //      |       dojo.connect(null, "onglobalevent", watcher, "handler");
        //
        // example:
        //              When ob.onCustomEvent executes, customEventHandler is invoked:
        //      |       dojo.connect(ob, "onCustomEvent", null, "customEventHandler");
        //      |       dojo.connect(ob, "onCustomEvent", "customEventHandler"); // same
        //
        // example:
        //              When ob.onCustomEvent executes, customEventHandler is invoked
        //              with the same scope (this):
        //      |       dojo.connect(ob, "onCustomEvent", null, customEventHandler);
        //      |       dojo.connect(ob, "onCustomEvent", customEventHandler); // same
        //
        // example:
        //              When globalEvent executes, globalHandler is invoked
        //              with the same scope (this):
        //      |       dojo.connect(null, "globalEvent", null, globalHandler);
        //      |       dojo.connect("globalEvent", globalHandler); // same

        // normalize arguments
        var a=arguments, args=[], i=0;
        // if a[0] is a String, obj was omitted
        args.push(dojo.isString(a[0]) ? null : a[i++], a[i++]);
        // if the arg-after-next is a String or Function, context was NOT omitted
        var a1 = a[i+1];
        args.push(dojo.isString(a1)||dojo.isFunction(a1) ? a[i++] : null, a[i++]);
        // absorb any additional arguments
        for(var l=a.length; i<l; i++){  args.push(a[i]); }
        // do the actual work
        return dojo._connect.apply(this, args); /*Handle*/
}

// used by non-browser hostenvs. always overriden by event.js
dojo._connect = function(obj, event, context, method){
        var l=dojo._listener, h=l.add(obj, event, dojo.hitch(context, method));
        return [obj, event, h, l]; // Handle
};

dojo.disconnect = function(/*Handle*/ handle){
        // summary:
        //              Remove a link created by dojo.connect.
        // description:
        //              Removes the connection between event and the method referenced by handle.
        // handle:
        //              the return value of the dojo.connect call that created the connection.
        if(handle && handle[0] !== undefined){
                dojo._disconnect.apply(this, handle);
                // let's not keep this reference
                delete handle[0];
        }
};

dojo._disconnect = function(obj, event, handle, listener){
        listener.remove(obj, event, handle);
};

// topic publish/subscribe

dojo._topics = {};

dojo.subscribe = function(/*String*/ topic, /*Object|null*/ context, /*String|Function*/ method){
        //      summary:
        //              Attach a listener to a named topic. The listener function is invoked whenever the
        //              named topic is published (see: dojo.publish).
        //              Returns a handle which is needed to unsubscribe this listener.
        //      context:
        //              Scope in which method will be invoked, or null for default scope.
        //      method:
        //              The name of a function in context, or a function reference. This is the function that
        //              is invoked when topic is published.
        //      example:
        //      |       dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); });
        //      |       dojo.publish("alerts", [ "read this", "hello world" ]);

        // support for 2 argument invocation (omitting context) depends on hitch
        return [topic, dojo._listener.add(dojo._topics, topic, dojo.hitch(context, method))]; /*Handle*/
};

dojo.unsubscribe = function(/*Handle*/ handle){
        //      summary:
        //              Remove a topic listener.
        //      handle:
        //              The handle returned from a call to subscribe.
        //      example:
        //      |       var alerter = dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
        //      |       ...
        //      |       dojo.unsubscribe(alerter);
        if(handle){
                dojo._listener.remove(dojo._topics, handle[0], handle[1]);
        }
};

dojo.publish = function(/*String*/ topic, /*Array*/ args){
        //      summary:
        //              Invoke all listener method subscribed to topic.
        //      topic:
        //              The name of the topic to publish.
        //      args:
        //              An array of arguments. The arguments will be applied
        //              to each topic subscriber (as first class parameters, via apply).
        //      example:
        //      |       dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
        //      |       dojo.publish("alerts", [ "read this", "hello world" ]);

        // Note that args is an array, which is more efficient vs variable length
        // argument list.  Ideally, var args would be implemented via Array
        // throughout the APIs.
        var f = dojo._topics[topic];
        if(f){
                f.apply(this, args||[]);
        }
};

dojo.connectPublisher = function(       /*String*/ topic,
                                                                        /*Object|null*/ obj,
                                                                        /*String*/ event){
        //      summary:
        //              Ensure that every time obj.event() is called, a message is published
        //              on the topic. Returns a handle which can be passed to
        //              dojo.disconnect() to disable subsequent automatic publication on
        //              the topic.
        //      topic:
        //              The name of the topic to publish.
        //      obj:
        //              The source object for the event function. Defaults to dojo.global
        //              if null.
        //      event:
        //              The name of the event function in obj.
        //              I.e. identifies a property obj[event].
        //      example:
        //      |       dojo.connectPublisher("/ajax/start", dojo, "xhrGet");
        var pf = function(){ dojo.publish(topic, arguments); }
        return event ? dojo.connect(obj, event, pf) : dojo.connect(obj, pf); //Handle
};

}

if(!dojo._hasResource["dojo._base.Deferred"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.Deferred"] = true;
dojo.provide("dojo._base.Deferred");



(function(){
        var mutator = function(){};
        var freeze = Object.freeze || function(){};
        // A deferred provides an API for creating and resolving a promise.
        dojo.Deferred = function(/*Function?*/canceller){
        // summary:
        //              Deferreds provide a generic means for encapsulating an asynchronous
        //              operation and notifying users of the completion and result of the operation.
        // description:
        //              The dojo.Deferred API is based on the concept of promises that provide a
        //              generic interface into the eventual completion of an asynchronous action.
        //              The motivation for promises fundamentally is about creating a
        //              separation of concerns that allows one to achieve the same type of
        //              call patterns and logical data flow in asynchronous code as can be
        //              achieved in synchronous code. Promises allows one
        //              to be able to call a function purely with arguments needed for
        //              execution, without conflating the call with concerns of whether it is
        //              sync or async. One shouldn't need to alter a call's arguments if the
        //              implementation switches from sync to async (or vice versa). By having
        //              async functions return promises, the concerns of making the call are
        //              separated from the concerns of asynchronous interaction (which are
        //              handled by the promise).
        //
        //      The dojo.Deferred is a type of promise that provides methods for fulfilling the
        //              promise with a successful result or an error. The most important method for
        //              working with Dojo's promises is the then() method, which follows the
        //              CommonJS proposed promise API. An example of using a Dojo promise:
        //
        //              |       var resultingPromise = someAsyncOperation.then(function(result){
        //              |               ... handle result ...
        //              |       },
        //              |       function(error){
        //              |               ... handle error ...
        //              |       });
        //
        //              The .then() call returns a new promise that represents the result of the
        //              execution of the callback. The callbacks will never affect the original promises value.
        //
        //              The dojo.Deferred instances also provide the following functions for backwards compatibility:
        //
        //                      * addCallback(handler)
        //                      * addErrback(handler)
        //                      * callback(result)
        //                      * errback(result)
        //
        //              Callbacks are allowed to return promises themselves, so
        //              you can build complicated sequences of events with ease.
        //
        //              The creator of the Deferred may specify a canceller.  The canceller
        //              is a function that will be called if Deferred.cancel is called
        //              before the Deferred fires. You can use this to implement clean
        //              aborting of an XMLHttpRequest, etc. Note that cancel will fire the
        //              deferred with a CancelledError (unless your canceller returns
        //              another kind of error), so the errbacks should be prepared to
        //              handle that error for cancellable Deferreds.
        // example:
        //      |       var deferred = new dojo.Deferred();
        //      |       setTimeout(function(){ deferred.callback({success: true}); }, 1000);
        //      |       return deferred;
        // example:
        //              Deferred objects are often used when making code asynchronous. It
        //              may be easiest to write functions in a synchronous manner and then
        //              split code using a deferred to trigger a response to a long-lived
        //              operation. For example, instead of register a callback function to
        //              denote when a rendering operation completes, the function can
        //              simply return a deferred:
        //
        //              |       // callback style:
        //              |       function renderLotsOfData(data, callback){
        //              |               var success = false
        //              |               try{
        //              |                       for(var x in data){
        //              |                               renderDataitem(data[x]);
        //              |                       }
        //              |                       success = true;
        //              |               }catch(e){ }
        //              |               if(callback){
        //              |                       callback(success);
        //              |               }
        //              |       }
        //
        //              |       // using callback style
        //              |       renderLotsOfData(someDataObj, function(success){
        //              |               // handles success or failure
        //              |               if(!success){
        //              |                       promptUserToRecover();
        //              |               }
        //              |       });
        //              |       // NOTE: no way to add another callback here!!
        // example:
        //              Using a Deferred doesn't simplify the sending code any, but it
        //              provides a standard interface for callers and senders alike,
        //              providing both with a simple way to service multiple callbacks for
        //              an operation and freeing both sides from worrying about details
        //              such as "did this get called already?". With Deferreds, new
        //              callbacks can be added at any time.
        //
        //              |       // Deferred style:
        //              |       function renderLotsOfData(data){
        //              |               var d = new dojo.Deferred();
        //              |               try{
        //              |                       for(var x in data){
        //              |                               renderDataitem(data[x]);
        //              |                       }
        //              |                       d.callback(true);
        //              |               }catch(e){
        //              |                       d.errback(new Error("rendering failed"));
        //              |               }
        //              |               return d;
        //              |       }
        //
        //              |       // using Deferred style
        //              |       renderLotsOfData(someDataObj).then(null, function(){
        //              |               promptUserToRecover();
        //              |       });
        //              |       // NOTE: addErrback and addCallback both return the Deferred
        //              |       // again, so we could chain adding callbacks or save the
        //              |       // deferred for later should we need to be notified again.
        // example:
        //              In this example, renderLotsOfData is synchronous and so both
        //              versions are pretty artificial. Putting the data display on a
        //              timeout helps show why Deferreds rock:
        //
        //              |       // Deferred style and async func
        //              |       function renderLotsOfData(data){
        //              |               var d = new dojo.Deferred();
        //              |               setTimeout(function(){
        //              |                       try{
        //              |                               for(var x in data){
        //              |                                       renderDataitem(data[x]);
        //              |                               }
        //              |                               d.callback(true);
        //              |                       }catch(e){
        //              |                               d.errback(new Error("rendering failed"));
        //              |                       }
        //              |               }, 100);
        //              |               return d;
        //              |       }
        //
        //              |       // using Deferred style
        //              |       renderLotsOfData(someDataObj).then(null, function(){
        //              |               promptUserToRecover();
        //              |       });
        //
        //              Note that the caller doesn't have to change his code at all to
        //              handle the asynchronous case.
                var result, finished, isError, head, nextListener;
                var promise = (this.promise = {});
                
                function complete(value){
                        if(finished){
                                throw new Error("This deferred has already been resolved");
                        }
                        result = value;
                        finished = true;
                        notify();
                }
                function notify(){
                        var mutated;
                        while(!mutated && nextListener){
                                var listener = nextListener;
                                nextListener = nextListener.next;
                                if((mutated = (listener.progress == mutator))){ // assignment and check
                                        finished = false;
                                }
                                var func = (isError ? listener.error : listener.resolved);
                                if (func) {
                                        try {
                                                var newResult = func(result);
                                                if (newResult && typeof newResult.then === "function") {
                                                        newResult.then(dojo.hitch(listener.deferred, "resolve"), dojo.hitch(listener.deferred, "reject"));
                                                        continue;
                                                }
                                                var unchanged = mutated && newResult === undefined;
                                                if(mutated && !unchanged){
                                                        isError = newResult instanceof Error;
                                                }
                                                listener.deferred[unchanged && isError ? "reject" : "resolve"](unchanged ? result : newResult);
                                        }
                                        catch (e) {
                                                listener.deferred.reject(e);
                                        }
                                }else {
                                        if(isError){
                                                listener.deferred.reject(result);
                                        }else{
                                                listener.deferred.resolve(result);
                                        }
                                }
                        }
                }
                // calling resolve will resolve the promise
                this.resolve = this.callback = function(value){
                        // summary:
                        //              Fulfills the Deferred instance successfully with the provide value
                        this.fired = 0;
                        this.results = [value, null];
                        complete(value);
                };
                
                
                // calling error will indicate that the promise failed
                this.reject = this.errback = function(error){
                        // summary:
                        //              Fulfills the Deferred instance as an error with the provided error
                        isError = true;
                        this.fired = 1;
                        complete(error);
                        this.results = [null, error];
                        if(!error || error.log !== false){
                                (dojo.config.deferredOnError || function(x){ console.error(x); })(error);
                        }
                };
                // call progress to provide updates on the progress on the completion of the promise
                this.progress = function(update){
                        // summary
                        //              Send progress events to all listeners
                        var listener = nextListener;
                        while(listener){
                                var progress = listener.progress;
                                progress && progress(update);
                                listener = listener.next;
                        }
                };
                this.addCallbacks = function(/*Function?*/callback, /*Function?*/errback){
                        this.then(callback, errback, mutator);
                        return this;
                };
                // provide the implementation of the promise
                this.then = promise.then = function(/*Function?*/resolvedCallback, /*Function?*/errorCallback, /*Function?*/progressCallback){
                        // summary:
                        //              Adds a fulfilledHandler, errorHandler, and progressHandler to be called for
                        //              completion of a promise. The fulfilledHandler is called when the promise
                        //              is fulfilled. The errorHandler is called when a promise fails. The
                        //              progressHandler is called for progress events. All arguments are optional
                        //              and non-function values are ignored. The progressHandler is not only an
                        //              optional argument, but progress events are purely optional. Promise
                        //              providers are not required to ever create progress events.
                        //
                        //              This function will return a new promise that is fulfilled when the given
                        //              fulfilledHandler or errorHandler callback is finished. This allows promise
                        //              operations to be chained together. The value returned from the callback
                        //              handler is the fulfillment value for the returned promise. If the callback
                        //              throws an error, the returned promise will be moved to failed state.
                        //
                        // example:
                        //              An example of using a CommonJS compliant promise:
                        //              |       asyncComputeTheAnswerToEverything().
                        //              |               then(addTwo).
                        //              |               then(printResult, onError);
                        //              |       >44
                        //
                        var returnDeferred = progressCallback == mutator ? this : new dojo.Deferred(promise.cancel);
                        var listener = {
                                resolved: resolvedCallback,
                                error: errorCallback,
                                progress: progressCallback,
                                deferred: returnDeferred
                        };
                        if(nextListener){
                                head = head.next = listener;
                        }
                        else{
                                nextListener = head = listener;
                        }
                        if(finished){
                                notify();
                        }
                        return returnDeferred.promise;
                };
                var deferred = this;
                this.cancel = promise.cancel = function () {
                        // summary:
                        //              Cancels the asynchronous operation
                        if(!finished){
                                var error = canceller && canceller(deferred);
                                if(!finished){
                                        if (!(error instanceof Error)) {
                                                error = new Error(error);
                                        }
                                        error.log = false;
                                        deferred.reject(error);
                                }
                        }
                };
                freeze(promise);
        };
        dojo.extend(dojo.Deferred, {
                addCallback: function (/*Function*/callback) {
                        return this.addCallbacks(dojo.hitch.apply(dojo, arguments));
                },
        
                addErrback: function (/*Function*/errback) {
                        return this.addCallbacks(null, dojo.hitch.apply(dojo, arguments));
                },
        
                addBoth: function (/*Function*/callback) {
                        var enclosed = dojo.hitch.apply(dojo, arguments);
                        return this.addCallbacks(enclosed, enclosed);
                },
                fired: -1
        });
})();
dojo.when = function(promiseOrValue, /*Function?*/callback, /*Function?*/errback, /*Function?*/progressHandler){
        // summary:
        //              This provides normalization between normal synchronous values and
        //              asynchronous promises, so you can interact with them in a common way
        //      example:
        //              |       function printFirstAndList(items){
        //              |               dojo.when(findFirst(items), console.log);
        //              |               dojo.when(findLast(items), console.log);
        //              |       }
        //              |       function findFirst(items){
        //              |               return dojo.when(items, function(items){
        //              |                       return items[0];
        //              |               });
        //              |       }
        //              |       function findLast(items){
        //              |               return dojo.when(items, function(items){
        //              |                       return items[items.length];
        //              |               });
        //              |       }
        //              And now all three of his functions can be used sync or async.
        //              |       printFirstAndLast([1,2,3,4]) will work just as well as
        //              |       printFirstAndLast(dojo.xhrGet(...));
        
        if(promiseOrValue && typeof promiseOrValue.then === "function"){
                return promiseOrValue.then(callback, errback, progressHandler);
        }
        return callback(promiseOrValue);
};

}

if(!dojo._hasResource["dojo._base.json"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.json"] = true;
dojo.provide("dojo._base.json");


dojo.fromJson = function(/*String*/ json){
        // summary:
        //              Parses a [JSON](http://json.org) string to return a JavaScript object.
        // description:
        //              Throws for invalid JSON strings, but it does not use a strict JSON parser. It
        //              delegates to eval().  The content passed to this method must therefore come
        //              from a trusted source.
        // json:
        //              a string literal of a JSON item, for instance:
        //                      `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`

        return eval("(" + json + ")"); // Object
};

dojo._escapeString = function(/*String*/str){
        //summary:
        //              Adds escape sequences for non-visual characters, double quote and
        //              backslash and surrounds with double quotes to form a valid string
        //              literal.
        return ('"' + str.replace(/(["\\])/g, '\\$1') + '"').
                replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n").
                replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r"); // string
};

dojo.toJsonIndentStr = "\t";
dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint, /*String?*/ _indentStr){
        //      summary:
        //              Returns a [JSON](http://json.org) serialization of an object.
        //      description:
        //              Returns a [JSON](http://json.org) serialization of an object.
        //              Note that this doesn't check for infinite recursion, so don't do that!
        //      it:
        //              an object to be serialized. Objects may define their own
        //              serialization via a special "__json__" or "json" function
        //              property. If a specialized serializer has been defined, it will
        //              be used as a fallback.
        //      prettyPrint:
        //              if true, we indent objects and arrays to make the output prettier.
        //              The variable `dojo.toJsonIndentStr` is used as the indent string --
        //              to use something other than the default (tab), change that variable
        //              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
};

}

if(!dojo._hasResource["dojo._base.Color"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.Color"] = true;
dojo.provide("dojo._base.Color");




(function(){

        var d = dojo;

        dojo.Color = function(/*Array|String|Object*/ color){
                // summary:
                //              Takes a named string, hex string, array of rgb or rgba values,
                //              an object with r, g, b, and a properties, or another `dojo.Color` object
                //              and creates a new Color instance to work from.
                //
                // example:
                //              Work with a Color instance:
                //       | var c = new dojo.Color();
                //       | c.setColor([0,0,0]); // black
                //       | var hex = c.toHex(); // #000000
                //
                // example:
                //              Work with a node's color:
                //       | var color = dojo.style("someNode", "backgroundColor");
                //       | var n = new dojo.Color(color);
                //       | // adjust the color some
                //       | n.r *= .5;
                //       | 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);
        };
})();

}

if(!dojo._hasResource["dojo._base.window"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.window"] = true;
dojo.provide("dojo._base.window");


/*=====
dojo.doc = {
        // summary:
        //              Alias for the current document. 'dojo.doc' can be modified
        //              for temporary context shifting. Also see dojo.withDoc().
        // description:
        //    Refer to dojo.doc rather
        //    than referring to 'window.document' to ensure your code runs
        //    correctly in managed contexts.
        // example:
        //      |       n.appendChild(dojo.doc.createElement('div'));
}
=====*/
dojo.doc = window["document"] || null;

dojo.body = function(){
        // summary:
        //              Return the body element of the document
        //              return the body object associated with dojo.doc
        // example:
        //      |       dojo.body().appendChild(dojo.doc.createElement('div'));

        // Note: document.body is not defined for a strict xhtml document
        // Would like to memoize this, but dojo.doc can change vi dojo.withDoc().
        return dojo.doc.body || dojo.doc.getElementsByTagName("body")[0]; // Node
};

dojo.setContext = function(/*Object*/globalObject, /*DocumentElement*/globalDocument){
        // summary:
        //              changes the behavior of many core Dojo functions that deal with
        //              namespace and DOM lookup, changing them to work in a new global
        //              context (e.g., an iframe). The varibles dojo.global and dojo.doc
        //              are modified as a result of calling this function and the result of
        //              `dojo.body()` likewise differs.
        dojo.global = globalObject;
        dojo.doc = globalDocument;
};

dojo.withGlobal = function(     /*Object*/globalObject,
                                                        /*Function*/callback,
                                                        /*Object?*/thisObject,
                                                        /*Array?*/cbArguments){
        // summary:
        //              Invoke callback with globalObject as dojo.global and
        //              globalObject.document as dojo.doc.
        // description:
        //              Invoke callback with globalObject as dojo.global and
        //              globalObject.document as dojo.doc. If provided, globalObject
        //              will be executed in the context of object thisObject
        //              When callback() returns or throws an error, the dojo.global
        //              and dojo.doc will be restored to its previous state.

        var oldGlob = dojo.global;
        try{
                dojo.global = globalObject;
                return dojo.withDoc.call(null, globalObject.document, callback, thisObject, cbArguments);
        }finally{
                dojo.global = oldGlob;
        }
};

dojo.withDoc = function(        /*DocumentElement*/documentObject,
                                                        /*Function*/callback,
                                                        /*Object?*/thisObject,
                                                        /*Array?*/cbArguments){
        // summary:
        //              Invoke callback with documentObject as dojo.doc.
        // description:
        //              Invoke callback with documentObject as dojo.doc. If provided,
        //              callback will be executed in the context of object thisObject
        //              When callback() returns or throws an error, the dojo.doc will
        //              be restored to its previous state.

        var oldDoc = dojo.doc,
                oldLtr = dojo._bodyLtr,
                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;
        }
};

}

if(!dojo._hasResource["dojo._base.event"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.event"] = true;
dojo.provide("dojo._base.event");



// this file courtesy of the TurboAjax Group, licensed under a Dojo CLA

(function(){
        // DOM event listener machinery
        var del = (dojo._event_listener = {
                add: function(/*DOMNode*/ node, /*String*/ name, /*Function*/ fp){
                        if(!node){return;}
                        name = del._normalizeEventName(name);
                        fp = del._fixCallback(name, fp);
                        if(
                                                                !dojo.isIE &&
                                                                (name == "mouseenter" || name == "mouseleave")
                        ){
                                var ofp = fp;
                                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 >= 32 ? 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 < 9 || (dojo.isIE && dojo.isQuirks)){
                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;
                                }
                                if (dojo.isIE < 9 || dojo.isQuirks) {
                                        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 || (dojo.isIE >= 9 && !dojo.isQuirks)) && 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);
                                        if(dojo.isIE < 9 || (dojo.isIE && dojo.isQuirks)){
                                                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 = (dojo.isIE < 9 || dojo.isQuirks) ? function(evt){
                        evt = evt || window.event;
                        del._stopPropagation.call(evt);
                        del._preventDefault.call(evt);
                } : dojo.stopEvent;
        }
        
        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)); };
        };
}

}

if(!dojo._hasResource["dojo._base.html"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.html"] = true;
dojo.provide("dojo._base.html");



// FIXME: need to add unit tests for all the semi-public methods

try{
        document.execCommand("BackgroundImageCache", false, true);
}catch(e){
        // sane browsers don't have cache "issues"
}

// =============================
// DOM Functions
// =============================

/*=====
dojo.byId = function(id, doc){
        //      summary:
        //              Returns DOM node with matching `id` attribute or `null`
        //              if not found. 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.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.
                // be sure to return null per documentation, to match IE branch.
                return ((typeof id == "string") ? (doc || dojo.doc).getElementById(id) : id) || null; // 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 = /^\s*</.test(node) ? 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 < 9 ? 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 < 9 ? function(/*DomNode*/node, /*Number*/opacity){
                        var ov = opacity * 100, opaque = opacity == 1;
                        node.style.zoom = opaque ? "" : 1;

                        if(!af(node)){
                                if(opaque){
                                        return opacity;
                                }
                                node.style.filter += " progid:" + astr + "(Opacity=" + ov + ")";
                        }else{
                                af(node, 1).Opacity = ov;
                        }

                        // 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 = !opaque;

                        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._getMarginSize = function(/*DomNode*/node, /*Object*/computedStyle){
                // summary:
                //      returns an object that encodes the width and height of
                //      the node's margin box
                node = byId(node);
                var me = d._getMarginExtents(node, computedStyle || gcs(node));

                var size = node.getBoundingClientRect();
                return {
                        w: (size.right - size.left) + me.w,
                        h: (size.bottom - size.top) + 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.
                //              While the getter will return top and left values, the
                //              setter only accepts setting the width and height.
                //      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, but only w (width) and h (height) are supported.
                //              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.isQuirks? d.doc.body : d.doc.documentElement, { x:d._fixIeBiDiScrollLeft(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
                // 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 ie = d.isIE;
                if(ie && !d._isBodyLtr()){
                        var qk = d.isQuirks,
                                de = qk ? d.doc.body : d.doc.documentElement;
                        if(ie == 6 && !qk && d.global.frameElement && de.scrollHeight > de.clientHeight){
                                scrollLeft += de.clientLeft; // workaround ie6+strict+rtl+iframe+vertical-scrollbar bug where clientWidth is too small by clientLeft pixels
                        }
                        return (ie < 8 || qk) ? (scrollLeft + de.clientWidth - de.scrollWidth) : -scrollLeft; // 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.

                node = byId(node);
                var     db = d.body(),
                        dh = db.parentNode,
                        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);
                        }
                                // account for document scrolling
                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){
                if(tagWrap.hasOwnProperty(param)){
                        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 = [""],
                fakeNode = {},
                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], oldLen;
                cls = cls ? " " + cls + " " : " ";
                oldLen = cls.length;
                for(var i = 0, len = classStr.length, c; i < len; ++i){
                        c = classStr[i];
                        if(c && cls.indexOf(" " + c + " ") < 0){
                                cls += c + " ";
                        }
                }
                if(oldLen < cls.length){
                        node[_className] = cls.substr(1, cls.length - 2);
                }
        };

        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.replaceClass = function(/*DomNode|String*/node, /*String|Array*/addClassStr, /*String|Array?*/removeClassStr){
                // summary:
                //              Replaces one or more classes on a node if not present.
                //              Operates more quickly than calling dojo.removeClass and dojo.addClass
                // node:
                //              String ID or DomNode reference to remove the class from.
                // addClassStr:
                //              A String class name to add, or several space-separated class names,
                //              or an array of class names.
                // removeClassStr:
                //              A String class name to remove, or several space-separated class names,
                //              or an array of class names.
                //
                // example:
                //      |       dojo.replaceClass("someNode", "add1 add2", "remove1 remove2");
                //
                // example:
                //      Replace all classes with addMe
                //      |       dojo.replaceClass("someNode", "addMe");
                //
                // example:
                //      Available in `dojo.NodeList()` for multiple toggles
                //      |       dojo.query(".findMe").replaceClass("addMe", "removeMe");

        node = byId(node);
                fakeNode.className = node.className;
                dojo.removeClass(fakeNode, removeClassStr);
                dojo.addClass(fakeNode, addClassStr);
                if(node.className !== fakeNode.className){
                        node.className = fakeNode.className;
                }
        };

        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);
        };

})();

}

if(!dojo._hasResource["dojo._base.NodeList"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.NodeList"] = true;
dojo.provide("dojo._base.NodeList");






(function(){

        var d = dojo;

        var ap = Array.prototype, aps = ap.slice, apc = ap.concat;

        var tnl = function(/*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", "replaceClass", "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 utility 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 empty 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 location 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 location 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 focusable:
                        //      |       dojo.query(".focusable").attr("tabIndex", -1);
                        //      example:
                        //              Disable a group of buttons:
                        //      |       dojo.query("button.group").attr("disabled", true);
                        //      example:
                        //              innerHTML can be assigned or retrieved as well:
                        //      |       // get the innerHTML (as an array) for each list item
                        //      |       var ih = dojo.query("li.replaceable").attr("innerHTML");
                        return; // dojo.NodeList
                        return; // Array
                },

                style: function(property, value){
                        //      summary:
                        //              gets or sets the CSS property for every element in the NodeList
                        //      property: String
                        //              the CSS property to get/set, in JavaScript notation
                        //              ("lineHieght" instead of "line-height")
                        //      value: String?
                        //              optional. The value to set the property to
                        //      returns:
                        //              if no value is passed, the result is an array of strings.
                        //              If a value is passed, the return is this NodeList
                        return; // dojo.NodeList
                        return; // Array
                },

                addClass: function(className){
                        //      summary:
                        //              adds the specified class to every node in the list
                        //      className: String|Array
                        //              A String class name to add, or several space-separated class names,
                        //              or an array of class names.
                        return; // dojo.NodeList
                },

                removeClass: function(className){
                        //      summary:
                        //              removes the specified class from every node in the list
                        //      className: String|Array?
                        //              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.
                        //      returns:
                        //              dojo.NodeList, this list
                        return; // dojo.NodeList
                },

                toggleClass: function(className, condition){
                        //      summary:
                        //              Adds a class to node if not present, or removes if present.
                        //              Pass a boolean condition if you want to explicitly add or remove.
                        //      condition: Boolean?
                        //              If passed, true means to add the class, false means to remove.
                        //      className: String
                        //              the CSS class to add
                        return; // dojo.NodeList
                },

                connect: function(methodName, objOrFunc, funcName){
                        //      summary:
                        //              attach event handlers to every item of the NodeList. Uses dojo.connect()
                        //              so event properties are normalized
                        //      methodName: String
                        //              the name of the method to attach to. For DOM events, this should be
                        //              the lower-case name of the event
                        //      objOrFunc: Object|Function|String
                        //              if 2 arguments are passed (methodName, objOrFunc), objOrFunc should
                        //              reference a function or be the name of the function in the global
                        //              namespace to attach. If 3 arguments are provided
                        //              (methodName, objOrFunc, funcName), objOrFunc must be the scope to
                        //              locate the bound function in
                        //      funcName: String?
                        //              optional. A string naming the function in objOrFunc to bind to the
                        //              event. May also be a function reference.
                        //      example:
                        //              add an onclick handler to every button on the page
                        //              |       dojo.query("div:nth-child(odd)").connect("onclick", function(e){
                        //              |               console.log("clicked!");
                        //              |       });
                        // example:
                        //              attach foo.bar() to every odd div's onmouseover
                        //              |       dojo.query("div:nth-child(odd)").connect("onmouseover", foo, "bar");
                },

                empty: function(){
                        //      summary:
                        //              clears all content from each node in the list. Effectively
                        //              equivalent to removing all child nodes from every item in
                        //              the list.
                        return this.forEach("item.innerHTML='';"); // dojo.NodeList
                        // FIXME: should we be checking for and/or disposing of widgets below these nodes?
                },
                =====*/

                // useful html methods
                coords: adaptAsMap(d.coords),
                position: adaptAsMap(d.position),

                // FIXME: connectPublisher()? connectRunOnce()?

                /*
                destroy: function(){
                        //      summary:
                        //              destroys every item in  the list.
                        this.forEach(d.destroy);
                        // FIXME: should we be checking for and/or disposing of widgets below these nodes?
                },
                */

                place: function(/*String||Node*/ queryOrNode, /*String*/ position){
                        //      summary:
                        //              places elements of this node list relative to the first element matched
                        //              by queryOrNode. Returns the original NodeList. See: `dojo.place`
                        //      queryOrNode:
                        //              may be a string representing any valid CSS3 selector or a DOM node.
                        //              In the selector case, only the first matching element will be used
                        //              for relative positioning.
                        //      position:
                        //              can be one of:
                        //              |       "last" (default)
                        //              |       "first"
                        //              |       "before"
                        //              |       "after"
                        //              |       "only"
                        //              |       "replace"
                        //              or an offset in the childNodes property
                        var item = d.query(queryOrNode)[0];
                        return this.forEach(function(node){ d.place(node, item, position); }); // dojo.NodeList
                },

                orphan: function(/*String?*/ filter){
                        //      summary:
                        //              removes elements in this list that match the filter
                        //              from their parents and returns them as a new NodeList.
                        //      filter:
                        //              CSS selector like ".foo" or "div > span"
                        //      returns:
                        //              `dojo.NodeList` containing the orphaned elements
                        return (filter ? d._filterQueryResult(this, filter) : this).forEach(orphan); // dojo.NodeList
                },

                adopt: function(/*String||Array||DomNode*/ queryOrListOrNode, /*String?*/ position){
                        //      summary:
                        //              places any/all elements in queryOrListOrNode at a
                        //              position relative to the first element in this list.
                        //              Returns a dojo.NodeList of the adopted elements.
                        //      queryOrListOrNode:
                        //              a DOM node or a query string or a query result.
                        //              Represents the nodes to be adopted relative to the
                        //              first element of this NodeList.
                        //      position:
                        //              can be one of:
                        //              |       "last" (default)
                        //              |       "first"
                        //              |       "before"
                        //              |       "after"
                        //              |       "only"
                        //              |       "replace"
                        //              or an offset in the childNodes property
                        return d.query(queryOrListOrNode).place(this[0], position)._stash(this);        // dojo.NodeList
                },

                // FIXME: do we need this?
                query: function(/*String*/ queryStr){
                        //      summary:
                        //              Returns a new list whose members match the passed query,
                        //              assuming elements of the current NodeList as the root for
                        //              each search.
                        //      example:
                        //              assume a DOM created by this markup:
                        //      |       <div id="foo">
                        //      |               <p>
                        //      |                       bacon is tasty, <span>dontcha think?</span>
                        //      |               </p>
                        //      |       </div>
                        //      |       <div id="bar">
                        //      |               <p>great comedians may not be funny <span>in person</span></p>
                        //      |       </div>
                        //              If we are presented with the following definition for a NodeList:
                        //      |       var l = new dojo.NodeList(dojo.byId("foo"), dojo.byId("bar"));
                        //              it's possible to find all span elements under paragraphs
                        //              contained by these elements with this sub-query:
                        //      |       var spans = l.query("p span");

                        // FIXME: probably slow
                        if(!queryStr){ return this; }
                        var ret = this.map(function(node){
                                // FIXME: why would we ever get undefined here?
                                return d.query(queryStr, node).filter(function(subNode){ return subNode !== undefined; });
                        });
                        return this._wrap(apc.apply([], ret), this);    // dojo.NodeList
                },

                filter: function(/*String|Function*/ filter){
                        //      summary:
                        //              "masks" the built-in javascript filter() method (supported
                        //              in Dojo via `dojo.filter`) to support passing a simple
                        //              string filter in addition to supporting filtering function
                        //              objects.
                        //      filter:
                        //              If a string, a CSS rule like ".thinger" or "div > span".
                        //      example:
                        //              "regular" JS filter syntax as exposed in dojo.filter:
                        //              |       dojo.query("*").filter(function(item){
                        //              |               // highlight every paragraph
                        //              |               return (item.nodeName == "p");
                        //              |       }).style("backgroundColor", "yellow");
                        // example:
                        //              the same filtering using a CSS selector
                        //              |       dojo.query("*").filter("p").styles("backgroundColor", "yellow");

                        var a = arguments, items = this, start = 0;
                        if(typeof filter == "string"){ // inline'd type check
                                items = d._filterQueryResult(this, a[0]);
                                if(a.length == 1){
                                        // if we only got a string query, pass back the filtered results
                                        return items._stash(this); // dojo.NodeList
                                }
                                // if we got a callback, run it over the filtered items
                                start = 1;
                        }
                        return this._wrap(d.filter(items, a[start], a[start + 1]), this);       // dojo.NodeList
                },

                /*
                // FIXME: should this be "copyTo" and include parenting info?
                clone: function(){
                        // summary:
                        //              creates node clones of each element of this list
                        //              and returns a new list containing the clones
                },
                */

                addContent: function(/*String||DomNode||Object||dojo.NodeList*/ content, /*String||Integer?*/ position){
                        //      summary:
                        //              add a node, NodeList or some HTML as a string to every item in the
                        //              list.  Returns the original list.
                        //      description:
                        //              a copy of the HTML content is added to each item in the
                        //              list, with an optional position argument. If no position
                        //              argument is provided, the content is appended to the end of
                        //              each item.
                        //      content:
                        //              DOM node, HTML in string format, a NodeList or an Object. If a DOM node or
                        //              NodeList, the content will be cloned if the current NodeList has more than one
                        //              element. Only the DOM nodes are cloned, no event handlers. If it is an Object,
                        //              it should be an object with at "template" String property that has the HTML string
                        //              to insert. If dojo.string has already been dojo.required, then dojo.string.substitute
                        //              will be used on the "template" to generate the final HTML string. Other allowed
                        //              properties on the object are: "parse" if the HTML
                        //              string should be parsed for widgets (dojo.require("dojo.parser") to get that
                        //              option to work), and "templateFunc" if a template function besides dojo.string.substitute
                        //              should be used to transform the "template".
                        //      position:
                        //              can be one of:
                        //              |       "last"||"end" (default)
                        //              |       "first||"start"
                        //              |       "before"
                        //              |       "after"
                        //              |       "replace" (replaces nodes in this NodeList with new content)
                        //              |       "only" (removes other children of the nodes so new content is the only child)
                        //              or an offset in the childNodes property
                        //      example:
                        //              appends content to the end if the position is omitted
                        //      |       dojo.query("h3 > p").addContent("hey there!");
                        //      example:
                        //              add something to the front of each element that has a
                        //              "thinger" property:
                        //      |       dojo.query("[thinger]").addContent("...", "first");
                        //      example:
                        //              adds a header before each element of the list
                        //      |       dojo.query(".note").addContent("<h4>NOTE:</h4>", "before");
                        //      example:
                        //              add a clone of a DOM node to the end of every element in
                        //              the list, removing it from its existing parent.
                        //      |       dojo.query(".note").addContent(dojo.byId("foo"));
                        //  example:
                        //      Append nodes from a templatized string.
                        //              dojo.require("dojo.string");
                        //              dojo.query(".note").addContent({
                        //              template: '<b>${id}: </b><span>${name}</span>',
                        //                      id: "user332",
                        //              name: "Mr. Anderson"
                        //      });
                        //  example:
                        //      Append nodes from a templatized string that also has widgets parsed.
                        //      dojo.require("dojo.string");
                        //      dojo.require("dojo.parser");
                        //      var notes = dojo.query(".note").addContent({
                        //              template: '<button dojoType="dijit.form.Button">${text}</button>',
                        //              parse: true,
                        //              text: "Send"
                        //      });
                        content = this._normalize(content, this[0]);
                        for(var i = 0, node; (node = this[i]); i++){
                                this._place(content, node, position, i > 0);
                        }
                        return this; //dojo.NodeList
                },

                instantiate: function(/*String|Object*/ declaredClass, /*Object?*/ properties){
                        //      summary:
                        //              Create a new instance of a specified class, using the
                        //              specified properties and each node in the nodeList as a
                        //              srcNodeRef.
                        //      example:
                        //              Grabs all buttons in the page and converts them to diji.form.Buttons.
                        //      |       var buttons = dojo.query("button").instantiate("dijit.form.Button", {showLabel: true});
                        var c = d.isFunction(declaredClass) ? declaredClass : d.getObject(declaredClass);
                        properties = properties || {};
                        return this.forEach(function(node){
                                new c(properties, node);
                        });     // dojo.NodeList
                },

                at: function(/*===== index =====*/){
                        //      summary:
                        //              Returns a new NodeList comprised of items in this NodeList
                        //              at the given index or indices.
                        //
                        //      index: Integer...
                        //              One or more 0-based indices of items in the current
                        //              NodeList. A negative index will start at the end of the
                        //              list and go backwards.
                        //
                        //      example:
                        //      Shorten the list to the first, second, and third elements
                        //      |       dojo.query("a").at(0, 1, 2).forEach(fn);
                        //
                        //      example:
                        //      Retrieve the first and last elements of a unordered list:
                        //      |       dojo.query("ul > li").at(0, -1).forEach(cb);
                        //
                        //      example:
                        //      Do something for the first element only, but end() out back to
                        //      the original list and continue chaining:
                        //      |       dojo.query("a").at(0).onclick(fn).end().forEach(function(n){
                        //      |               console.log(n); // all anchors on the page.
                        //      |       })
                        //
                        //      returns:
                        //              dojo.NodeList
                        var t = new this._NodeListCtor();
                        d.forEach(arguments, function(i){
                                if(i < 0){ i = this.length + i }
                                if(this[i]){ t.push(this[i]); }
                        }, this);
                        return t._stash(this); // dojo.NodeList
                }

        });

        nl.events = [
                // summary:
                //              list of all DOM events used in NodeList
                "blur", "focus", "change", "click", "error", "keydown", "keypress",
                "keyup", "load", "mousedown", "mouseenter", "mouseleave", "mousemove",
                "mouseout", "mouseover", "mouseup", "submit"
        ];
        
        // FIXME: pseudo-doc the above automatically generated on-event functions

        // syntactic sugar for DOM events
        d.forEach(nl.events, function(evt){
                        var _oe = "on" + evt;
                        nlp[_oe] = function(a, b){
                                return this.connect(_oe, a, b);
                        };
                                // FIXME: should these events trigger publishes?
                                /*
                                return (a ? this.connect(_oe, a, b) :
                                                        this.forEach(function(n){
                                                                // FIXME:
                                                                //              listeners get buried by
                                                                //              addEventListener and can't be dug back
                                                                //              out to be triggered externally.
                                                                // see:
                                                                //              http://developer.mozilla.org/en/docs/DOM:element

                                                                console.log(n, evt, _oe);

                                                                // FIXME: need synthetic event support!
                                                                var _e = { target: n, faux: true, type: evt };
                                                                // dojo._event_listener._synthesizeEvent({}, { target: n, faux: true, type: evt });
                                                                try{ n[evt](_e); }catch(e){ console.log(e); }
                                                                try{ n[_oe](_e); }catch(e){ console.log(e); }
                                                        })
                                );
                                */
                }
        );

})();

}

if(!dojo._hasResource["dojo._base.query"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.query"] = true;
(function(){

/*
        dojo.query() architectural overview:

                dojo.query is a relatively full-featured CSS3 query library. It is
                designed to take any valid CSS3 selector and return the nodes matching
                the selector. To do this quickly, it processes queries in several
                steps, applying caching where profitable.
                
                The steps (roughly in reverse order of the way they appear in the code):
                        1.) check to see if we already have a "query dispatcher"
                                - if so, use that with the given parameterization. Skip to step 4.
                        2.) attempt to determine which branch to dispatch the query to:
                                - JS (optimized DOM iteration)
                                - native (FF3.1+, Safari 3.1+, IE 8+)
                        3.) tokenize and convert to executable "query dispatcher"
                                - this is where the lion's share of the complexity in the
                                  system lies. In the DOM version, the query dispatcher is
                                  assembled as a chain of "yes/no" test functions pertaining to
                                  a section of a simple query statement (".blah:nth-child(odd)"
                                  but not "div div", which is 2 simple statements). Individual
                                  statement dispatchers are cached (to prevent re-definition)
                                  as are entire dispatch chains (to make re-execution of the
                                  same query fast)
                        4.) the resulting query dispatcher is called in the passed scope
                            (by default the top-level document)
                                - for DOM queries, this results in a recursive, top-down
                                  evaluation of nodes based on each simple query section
                                - for native implementations, this may mean working around spec
                                  bugs. So be it.
                        5.) matched nodes are pruned to ensure they are unique (if necessary)
*/

var defineQuery= function(d){
        // define everything in a closure for compressability reasons. "d" is an
        // alias to "dojo" (or the toolkit alias object, e.g., "acme").

        ////////////////////////////////////////////////////////////////////////
        // Toolkit aliases
        ////////////////////////////////////////////////////////////////////////

        // if you are extracting dojo.query for use in your own system, you will
        // need to provide these methods and properties. No other porting should be
        // necessary, save for configuring the system to use a class other than
        // dojo.NodeList as the return instance instantiator
        var trim =                      d.trim;
        var each =                      d.forEach;
        //                                      d.isIE; // float
        //                                      d.isSafari; // float
        //                                      d.isOpera; // float
        //                                      d.isWebKit; // float
        //                                      d.doc ; // document element
        var qlc = (d._NodeListCtor =            d.NodeList);

        var getDoc = function(){ return d.doc; };
        // NOTE(alex): the spec is idiotic. CSS queries should ALWAYS be case-sensitive, but nooooooo
        var cssCaseBug = ((d.isWebKit||d.isMozilla) && ((getDoc().compatMode) == "BackCompat"));

        ////////////////////////////////////////////////////////////////////////
        // Global utilities
        ////////////////////////////////////////////////////////////////////////


        // on browsers that support the "children" collection we can avoid a lot of
        // iteration on chaff (non-element) nodes.
        // why.
        var childNodesName = !!getDoc().firstChild["children"] ? "children" : "childNodes";

        var specials = ">~+";

        // global thunk to determine whether we should treat the current query as
        // case sensitive or not. This switch is flipped by the query evaluator
        // based on the document passed as the context to search.
        var caseSensitive = false;

        // how high?
        var yesman = function(){ return true; };

        ////////////////////////////////////////////////////////////////////////
        // Tokenizer
        ////////////////////////////////////////////////////////////////////////

        var getQueryParts = function(query){
                //      summary:
                //              state machine for query tokenization
                //      description:
                //              instead of using a brittle and slow regex-based CSS parser,
                //              dojo.query implements an AST-style query representation. This
                //              representation is only generated once per query. For example,
                //              the same query run multiple times or under different root nodes
                //              does not re-parse the selector expression but instead uses the
                //              cached data structure. The state machine implemented here
                //              terminates on the last " " (space) character and returns an
                //              ordered array of query component structures (or "parts"). Each
                //              part represents an operator or a simple CSS filtering
                //              expression. The structure for parts is documented in the code
                //              below.


                // NOTE:
                //              this code is designed to run fast and compress well. Sacrifices
                //              to readability and maintainability have been made.  Your best
                //              bet when hacking the tokenizer is to put The Donnas on *really*
                //              loud (may we recommend their "Spend The Night" release?) and
                //              just assume you're gonna make mistakes. Keep the unit tests
                //              open and run them frequently. Knowing is half the battle ;-)
                if(specials.indexOf(query.slice(-1)) >= 0){
                        // if we end with a ">", "+", or "~", that means we're implicitly
                        // searching all children, so make it explicit
                        query += " * "
                }else{
                        // if you have not provided a terminator, one will be provided for
                        // you...
                        query += " ";
                }

                var ts = function(/*Integer*/ s, /*Integer*/ e){
                        // trim and slice.

                        // take an index to start a string slice from and an end position
                        // and return a trimmed copy of that sub-string
                        return trim(query.slice(s, e));
                }

                // the overall data graph of the full query, as represented by queryPart objects
                var queryParts = [];


                // state keeping vars
                var inBrackets = -1, inParens = -1, inMatchFor = -1,
                        inPseudo = -1, inClass = -1, inId = -1, inTag = -1,
                        lc = "", cc = "", pStart;

                // iteration vars
                var x = 0, // index in the query
                        ql = query.length,
                        currentPart = null, // data structure representing the entire clause
                        _cp = null; // the current pseudo or attr matcher

                // several temporary variables are assigned to this structure during a
                // potential sub-expression match:
                //              attr:
                //                      a string representing the current full attribute match in a
                //                      bracket expression
                //              type:
                //                      if there's an operator in a bracket expression, this is
                //                      used to keep track of it
                //              value:
                //                      the internals of parenthetical expression for a pseudo. for
                //                      :nth-child(2n+1), value might be "2n+1"

                var endTag = function(){
                        // called when the tokenizer hits the end of a particular tag name.
                        // Re-sets state variables for tag matching and sets up the matcher
                        // to handle the next type of token (tag or operator).
                        if(inTag >= 0){
                                var tv = (inTag == x) ? null : ts(inTag, x); // .toLowerCase();
                                currentPart[ (specials.indexOf(tv) < 0) ? "tag" : "oper" ] = tv;
                                inTag = -1;
                        }
                }

                var endId = function(){
                        // called when the tokenizer might be at the end of an ID portion of a match
                        if(inId >= 0){
                                currentPart.id = ts(inId, x).replace(/\\/g, "");
                                inId = -1;
                        }
                }

                var endClass = function(){
                        // called when the tokenizer might be at the end of a class name
                        // match. CSS allows for multiple classes, so we augment the
                        // current item with another class in its list
                        if(inClass >= 0){
                                currentPart.classes.push(ts(inClass+1, x).replace(/\\/g, ""));
                                inClass = -1;
                        }
                }

                var endAll = function(){
                        // at the end of a simple fragment, so wall off the matches
                        endId(); endTag(); endClass();
                }

                var endPart = function(){
                        endAll();
                        if(inPseudo >= 0){
                                currentPart.pseudos.push({ name: ts(inPseudo+1, x) });
                        }
                        // hint to the selector engine to tell it whether or not it
                        // needs to do any iteration. Many simple selectors don't, and
                        // we can avoid significant construction-time work by advising
                        // the system to skip them
                        currentPart.loops = (
                                        currentPart.pseudos.length ||
                                        currentPart.attrs.length ||
                                        currentPart.classes.length      );

                        currentPart.oquery = currentPart.query = ts(pStart, x); // save the full expression as a string


                        // otag/tag are hints to suggest to the system whether or not
                        // it's an operator or a tag. We save a copy of otag since the
                        // tag name is cast to upper-case in regular HTML matches. The
                        // system has a global switch to figure out if the current
                        // expression needs to be case sensitive or not and it will use
                        // otag or tag accordingly
                        currentPart.otag = currentPart.tag = (currentPart["oper"]) ? null : (currentPart.tag || "*");

                        if(currentPart.tag){
                                // if we're in a case-insensitive HTML doc, we likely want
                                // the toUpperCase when matching on element.tagName. If we
                                // do it here, we can skip the string op per node
                                // comparison
                                currentPart.tag = currentPart.tag.toUpperCase();
                        }

                        // add the part to the list
                        if(queryParts.length && (queryParts[queryParts.length-1].oper)){
                                // operators are always infix, so we remove them from the
                                // list and attach them to the next match. The evaluator is
                                // responsible for sorting out how to handle them.
                                currentPart.infixOper = queryParts.pop();
                                currentPart.query = currentPart.infixOper.query + " " + currentPart.query;
                                /*
                                console.debug(  "swapping out the infix",
                                                                currentPart.infixOper,
                                                                "and attaching it to",
                                                                currentPart);
                                */
                        }
                        queryParts.push(currentPart);

                        currentPart = null;
                }

                // iterate over the query, character by character, building up a
                // list of query part objects
                for(; lc=cc, cc=query.charAt(x), x < ql; x++){
                        //              cc: the current character in the match
                        //              lc: the last character (if any)

                        // someone is trying to escape something, so don't try to match any
                        // fragments. We assume we're inside a literal.
                        if(lc == "\\"){ continue; }
                        if(!currentPart){ // a part was just ended or none has yet been created
                                // NOTE: I hate all this alloc, but it's shorter than writing tons of if's
                                pStart = x;
                                //      rules describe full CSS sub-expressions, like:
                                //              #someId
                                //              .className:first-child
                                //      but not:
                                //              thinger > div.howdy[type=thinger]
                                //      the indidual components of the previous query would be
                                //      split into 3 parts that would be represented a structure
                                //      like:
                                //              [
                                //                      {
                                //                              query: "thinger",
                                //                              tag: "thinger",
                                //                      },
                                //                      {
                                //                              query: "div.howdy[type=thinger]",
                                //                              classes: ["howdy"],
                                //                              infixOper: {
                                //                                      query: ">",
                                //                                      oper: ">",
                                //                              }
                                //                      },
                                //              ]
                                currentPart = {
                                        query: null, // the full text of the part's rule
                                        pseudos: [], // CSS supports multiple pseud-class matches in a single rule
                                        attrs: [],      // CSS supports multi-attribute match, so we need an array
                                        classes: [], // class matches may be additive, e.g.: .thinger.blah.howdy
                                        tag: null,      // only one tag...
                                        oper: null, // ...or operator per component. Note that these wind up being exclusive.
                                        id: null,       // the id component of a rule
                                        getTag: function(){
                                                return (caseSensitive) ? this.otag : this.tag;
                                        }
                                };

                                // if we don't have a part, we assume we're going to start at
                                // the beginning of a match, which should be a tag name. This
                                // might fault a little later on, but we detect that and this
                                // iteration will still be fine.
                                inTag = x;
                        }

                        if(inBrackets >= 0){
                                // look for a the close first
                                if(cc == "]"){ // if we're in a [...] clause and we end, do assignment
                                        if(!_cp.attr){
                                                // no attribute match was previously begun, so we
                                                // assume this is an attribute existence match in the
                                                // form of [someAttributeName]
                                                _cp.attr = ts(inBrackets+1, x);
                                        }else{
                                                // we had an attribute already, so we know that we're
                                                // matching some sort of value, as in [attrName=howdy]
                                                _cp.matchFor = ts((inMatchFor||inBrackets+1), x);
                                        }
                                        var cmf = _cp.matchFor;
                                        if(cmf){
                                                // try to strip quotes from the matchFor value. We want
                                                // [attrName=howdy] to match the same
                                                //      as [attrName = 'howdy' ]
                                                if(     (cmf.charAt(0) == '"') || (cmf.charAt(0)  == "'") ){
                                                        _cp.matchFor = cmf.slice(1, -1);
                                                }
                                        }
                                        // end the attribute by adding it to the list of attributes.
                                        currentPart.attrs.push(_cp);
                                        _cp = null; // necessary?
                                        inBrackets = inMatchFor = -1;
                                }else if(cc == "="){
                                        // if the last char was an operator prefix, make sure we
                                        // record it along with the "=" operator.
                                        var addToCc = ("|~^$*".indexOf(lc) >=0 ) ? lc : "";
                                        _cp.type = addToCc+cc;
                                        _cp.attr = ts(inBrackets+1, x-addToCc.length);
                                        inMatchFor = x+1;
                                }
                                // now look for other clause parts
                        }else if(inParens >= 0){
                                // if we're in a parenthetical expression, we need to figure
                                // out if it's attached to a pseudo-selector rule like
                                // :nth-child(1)
                                if(cc == ")"){
                                        if(inPseudo >= 0){
                                                _cp.value = ts(inParens+1, x);
                                        }
                                        inPseudo = inParens = -1;
                                }
                        }else if(cc == "#"){
                                // start of an ID match
                                endAll();
                                inId = x+1;
                        }else if(cc == "."){
                                // start of a class match
                                endAll();
                                inClass = x;
                        }else if(cc == ":"){
                                // start of a pseudo-selector match
                                endAll();
                                inPseudo = x;
                        }else if(cc == "["){
                                // start of an attribute match.
                                endAll();
                                inBrackets = x;
                                // provide a new structure for the attribute match to fill-in
                                _cp = {
                                        /*=====
                                        attr: null, type: null, matchFor: null
                                        =====*/
                                };
                        }else if(cc == "("){
                                // we really only care if we've entered a parenthetical
                                // expression if we're already inside a pseudo-selector match
                                if(inPseudo >= 0){
                                        // provide a new structure for the pseudo match to fill-in
                                        _cp = {
                                                name: ts(inPseudo+1, x),
                                                value: null
                                        }
                                        currentPart.pseudos.push(_cp);
                                }
                                inParens = x;
                        }else if(
                                (cc == " ") &&
                                // if it's a space char and the last char is too, consume the
                                // current one without doing more work
                                (lc != cc)
                        ){
                                endPart();
                        }
                }
                return queryParts;
        };
        

        ////////////////////////////////////////////////////////////////////////
        // DOM query infrastructure
        ////////////////////////////////////////////////////////////////////////

        var agree = function(first, second){
                // the basic building block of the yes/no chaining system. agree(f1,
                // f2) generates a new function which returns the boolean results of
                // both of the passed functions to a single logical-anded result. If
                // either are not passed, the other is used exclusively.
                if(!first){ return second; }
                if(!second){ return first; }

                return function(){
                        return first.apply(window, arguments) && second.apply(window, arguments);
                }
        };

        var getArr = function(i, arr){
                // helps us avoid array alloc when we don't need it
                var r = arr||[]; // FIXME: should this be 'new d._NodeListCtor()' ?
                if(i){ r.push(i); }
                return r;
        };

        var _isElement = function(n){ return (1 == n.nodeType); };

        // FIXME: need to coalesce _getAttr with defaultGetter
        var blank = "";
        var _getAttr = function(elem, attr){
                if(!elem){ return blank; }
                if(attr == "class"){
                        return elem.className || blank;
                }
                if(attr == "for"){
                        return elem.htmlFor || blank;
                }
                if(attr == "style"){
                        return elem.style.cssText || blank;
                }
                return (caseSensitive ? elem.getAttribute(attr) : elem.getAttribute(attr, 2)) || blank;
        };

        var attrs = {
                "*=": function(attr, value){
                        return function(elem){
                                // E[foo*="bar"]
                                //              an E element whose "foo" attribute value contains
                                //              the substring "bar"
                                return (_getAttr(elem, attr).indexOf(value)>=0);
                        }
                },
                "^=": function(attr, value){
                        // E[foo^="bar"]
                        //              an E element whose "foo" attribute value begins exactly
                        //              with the string "bar"
                        return function(elem){
                                return (_getAttr(elem, attr).indexOf(value)==0);
                        }
                },
                "$=": function(attr, value){
                        // E[foo$="bar"]
                        //              an E element whose "foo" attribute value ends exactly
                        //              with the string "bar"
                        var tval = " "+value;
                        return function(elem){
                                var ea = " "+_getAttr(elem, attr);
                                return (ea.lastIndexOf(value)==(ea.length-value.length));
                        }
                },
                "~=": function(attr, value){
                        // E[foo~="bar"]
                        //              an E element whose "foo" attribute value is a list of
                        //              space-separated values, one of which is exactly equal
                        //              to "bar"

                        // return "[contains(concat(' ',@"+attr+",' '), ' "+ value +" ')]";
                        var tval = " "+value+" ";
                        return function(elem){
                                var ea = " "+_getAttr(elem, attr)+" ";
                                return (ea.indexOf(tval)>=0);
                        }
                },
                "|=": function(attr, value){
                        // E[hreflang|="en"]
                        //              an E element whose "hreflang" attribute has a
                        //              hyphen-separated list of values beginning (from the
                        //              left) with "en"
                        var valueDash = " "+value+"-";
                        return function(elem){
                                var ea = " "+_getAttr(elem, attr);
                                return (
                                        (ea == value) ||
                                        (ea.indexOf(valueDash)==0)
                                );
                        }
                },
                "=": function(attr, value){
                        return function(elem){
                                return (_getAttr(elem, attr) == value);
                        }
                }
        };

        // avoid testing for node type if we can. Defining this in the negative
        // here to avoid negation in the fast path.
        var _noNES = (typeof getDoc().firstChild.nextElementSibling == "undefined");
        var _ns = !_noNES ? "nextElementSibling" : "nextSibling";
        var _ps = !_noNES ? "previousElementSibling" : "previousSibling";
        var _simpleNodeTest = (_noNES ? _isElement : yesman);

        var _lookLeft = function(node){
                // look left
                while(node = node[_ps]){
                        if(_simpleNodeTest(node)){ return false; }
                }
                return true;
        };

        var _lookRight = function(node){
                // look right
                while(node = node[_ns]){
                        if(_simpleNodeTest(node)){ return false; }
                }
                return true;
        };

        var getNodeIndex = function(node){
                var root = node.parentNode;
                var i = 0,
                        tret = root[childNodesName],
                        ci = (node["_i"]||-1),
                        cl = (root["_l"]||-1);

                if(!tret){ return -1; }
                var l = tret.length;

                // we calculate the parent length as a cheap way to invalidate the
                // cache. It's not 100% accurate, but it's much more honest than what
                // other libraries do
                if( cl == l && ci >= 0 && cl >= 0 ){
                        // if it's legit, tag and release
                        return ci;
                }

                // else re-key things
                root["_l"] = l;
                ci = -1;
                for(var te = root["firstElementChild"]||root["firstChild"]; te; te = te[_ns]){
                        if(_simpleNodeTest(te)){
                                te["_i"] = ++i;
                                if(node === te){
                                        // NOTE:
                                        //      shortcutting the return at this step in indexing works
                                        //      very well for benchmarking but we avoid it here since
                                        //      it leads to potential O(n^2) behavior in sequential
                                        //      getNodexIndex operations on a previously un-indexed
                                        //      parent. We may revisit this at a later time, but for
                                        //      now we just want to get the right answer more often
                                        //      than not.
                                        ci = i;
                                }
                        }
                }
                return ci;
        };

        var isEven = function(elem){
                return !((getNodeIndex(elem)) % 2);
        };

        var isOdd = function(elem){
                return ((getNodeIndex(elem)) % 2);
        };

        var pseudos = {
                "checked": function(name, condition){
                        return function(elem){
                                return !!("checked" in elem ? elem.checked : elem.selected);
                        }
                },
                "first-child": function(){ return _lookLeft; },
                "last-child": function(){ return _lookRight; },
                "only-child": function(name, condition){
                        return function(node){
                                if(!_lookLeft(node)){ return false; }
                                if(!_lookRight(node)){ return false; }
                                return true;
                        };
                },
                "empty": function(name, condition){
                        return function(elem){
                                // DomQuery and jQuery get this wrong, oddly enough.
                                // The CSS 3 selectors spec is pretty explicit about it, too.
                                var cn = elem.childNodes;
                                var cnl = elem.childNodes.length;
                                // if(!cnl){ return true; }
                                for(var x=cnl-1; x >= 0; x--){
                                        var nt = cn[x].nodeType;
                                        if((nt === 1)||(nt == 3)){ return false; }
                                }
                                return true;
                        }
                },
                "contains": function(name, condition){
                        var cz = condition.charAt(0);
                        if( cz == '"' || cz == "'" ){ //remove quote
                                condition = condition.slice(1, -1);
                        }
                        return function(elem){
                                return (elem.innerHTML.indexOf(condition) >= 0);
                        }
                },
                "not": function(name, condition){
                        var p = getQueryParts(condition)[0];
                        var ignores = { el: 1 };
                        if(p.tag != "*"){
                                ignores.tag = 1;
                        }
                        if(!p.classes.length){
                                ignores.classes = 1;
                        }
                        var ntf = getSimpleFilterFunc(p, ignores);
                        return function(elem){
                                return (!ntf(elem));
                        }
                },
                "nth-child": function(name, condition){
                        var pi = parseInt;
                        // avoid re-defining function objects if we can
                        if(condition == "odd"){
                                return isOdd;
                        }else if(condition == "even"){
                                return isEven;
                        }
                        // FIXME: can we shorten this?
                        if(condition.indexOf("n") != -1){
                                var tparts = condition.split("n", 2);
                                var pred = tparts[0] ? ((tparts[0] == '-') ? -1 : pi(tparts[0])) : 1;
                                var idx = tparts[1] ? pi(tparts[1]) : 0;
                                var lb = 0, ub = -1;
                                if(pred > 0){
                                        if(idx < 0){
                                                idx = (idx % pred) && (pred + (idx % pred));
                                        }else if(idx>0){
                                                if(idx >= pred){
                                                        lb = idx - idx % pred;
                                                }
                                                idx = idx % pred;
                                        }
                                }else if(pred<0){
                                        pred *= -1;
                                        // idx has to be greater than 0 when pred is negative;
                                        // shall we throw an error here?
                                        if(idx > 0){
                                                ub = idx;
                                                idx = idx % pred;
                                        }
                                }
                                if(pred > 0){
                                        return function(elem){
                                                var i = getNodeIndex(elem);
                                                return (i>=lb) && (ub<0 || i<=ub) && ((i % pred) == idx);
                                        }
                                }else{
                                        condition = idx;
                                }
                        }
                        var ncount = pi(condition);
                        return function(elem){
                                return (getNodeIndex(elem) == ncount);
                        }
                }
        };

        var defaultGetter = (d.isIE < 9 || (dojo.isIE && dojo.isQuirks)) ? function(cond){
                var clc = cond.toLowerCase();
                if(clc == "class"){ cond = "className"; }
                return function(elem){
                        return (caseSensitive ? elem.getAttribute(cond) : elem[cond]||elem[clc]);
                }
        } : function(cond){
                return function(elem){
                        return (elem && elem.getAttribute && elem.hasAttribute(cond));
                }
        };

        var getSimpleFilterFunc = function(query, ignores){
                // generates a node tester function based on the passed query part. The
                // query part is one of the structures generated by the query parser
                // when it creates the query AST. The "ignores" object specifies which
                // (if any) tests to skip, allowing the system to avoid duplicating
                // work where it may have already been taken into account by other
                // factors such as how the nodes to test were fetched in the first
                // place
                if(!query){ return yesman; }
                ignores = ignores||{};

                var ff = null;

                if(!("el" in ignores)){
                        ff = agree(ff, _isElement);
                }

                if(!("tag" in ignores)){
                        if(query.tag != "*"){
                                ff = agree(ff, function(elem){
                                        return (elem && (elem.tagName == query.getTag()));
                                });
                        }
                }

                if(!("classes" in ignores)){
                        each(query.classes, function(cname, idx, arr){
                                // get the class name
                                /*
                                var isWildcard = cname.charAt(cname.length-1) == "*";
                                if(isWildcard){
                                        cname = cname.substr(0, cname.length-1);
                                }
                                // I dislike the regex thing, even if memoized in a cache, but it's VERY short
                                var re = new RegExp("(?:^|\\s)" + cname + (isWildcard ? ".*" : "") + "(?:\\s|$)");
                                */
                                var re = new RegExp("(?:^|\\s)" + cname + "(?:\\s|$)");
                                ff = agree(ff, function(elem){
                                        return re.test(elem.className);
                                });
                                ff.count = idx;
                        });
                }

                if(!("pseudos" in ignores)){
                        each(query.pseudos, function(pseudo){
                                var pn = pseudo.name;
                                if(pseudos[pn]){
                                        ff = agree(ff, pseudos[pn](pn, pseudo.value));
                                }
                        });
                }

                if(!("attrs" in ignores)){
                        each(query.attrs, function(attr){
                                var matcher;
                                var a = attr.attr;
                                // type, attr, matchFor
                                if(attr.type && attrs[attr.type]){
                                        matcher = attrs[attr.type](a, attr.matchFor);
                                }else if(a.length){
                                        matcher = defaultGetter(a);
                                }
                                if(matcher){
                                        ff = agree(ff, matcher);
                                }
                        });
                }

                if(!("id" in ignores)){
                        if(query.id){
                                ff = agree(ff, function(elem){
                                        return (!!elem && (elem.id == query.id));
                                });
                        }
                }

                if(!ff){
                        if(!("default" in ignores)){
                                ff = yesman;
                        }
                }
                return ff;
        };

        var _nextSibling = function(filterFunc){
                return function(node, ret, bag){
                        while(node = node[_ns]){
                                if(_noNES && (!_isElement(node))){ continue; }
                                if(
                                        (!bag || _isUnique(node, bag)) &&
                                        filterFunc(node)
                                ){
                                        ret.push(node);
                                }
                                break;
                        }
                        return ret;
                }
        };

        var _nextSiblings = function(filterFunc){
                return function(root, ret, bag){
                        var te = root[_ns];
                        while(te){
                                if(_simpleNodeTest(te)){
                                        if(bag && !_isUnique(te, bag)){
                                                break;
                                        }
                                        if(filterFunc(te)){
                                                ret.push(te);
                                        }
                                }
                                te = te[_ns];
                        }
                        return ret;
                }
        };

        // get an array of child *elements*, skipping text and comment nodes
        var _childElements = function(filterFunc){
                filterFunc = filterFunc||yesman;
                return function(root, ret, bag){
                        // get an array of child elements, skipping text and comment nodes
                        var te, x = 0, tret = root[childNodesName];
                        while(te = tret[x++]){
                                if(
                                        _simpleNodeTest(te) &&
                                        (!bag || _isUnique(te, bag)) &&
                                        (filterFunc(te, x))
                                ){
                                        ret.push(te);
                                }
                        }
                        return ret;
                };
        };
        
        /*
        // thanks, Dean!
        var itemIsAfterRoot = d.isIE ? function(item, root){
                return (item.sourceIndex > root.sourceIndex);
        } : function(item, root){
                return (item.compareDocumentPosition(root) == 2);
        };
        */

        // test to see if node is below root
        var _isDescendant = function(node, root){
                var pn = node.parentNode;
                while(pn){
                        if(pn == root){
                                break;
                        }
                        pn = pn.parentNode;
                }
                return !!pn;
        };

        var _getElementsFuncCache = {};

        var getElementsFunc = function(query){
                var retFunc = _getElementsFuncCache[query.query];
                // if we've got a cached dispatcher, just use that
                if(retFunc){ return retFunc; }
                // else, generate a new on

                // NOTE:
                //              this function returns a function that searches for nodes and
                //              filters them.  The search may be specialized by infix operators
                //              (">", "~", or "+") else it will default to searching all
                //              descendants (the " " selector). Once a group of children is
                //              found, a test function is applied to weed out the ones we
                //              don't want. Many common cases can be fast-pathed. We spend a
                //              lot of cycles to create a dispatcher that doesn't do more work
                //              than necessary at any point since, unlike this function, the
                //              dispatchers will be called every time. The logic of generating
                //              efficient dispatchers looks like this in pseudo code:
                //
                //              # if it's a purely descendant query (no ">", "+", or "~" modifiers)
                //              if infixOperator == " ":
                //                      if only(id):
                //                              return def(root):
                //                                      return d.byId(id, root);
                //
                //                      elif id:
                //                              return def(root):
                //                                      return filter(d.byId(id, root));
                //
                //                      elif cssClass && getElementsByClassName:
                //                              return def(root):
                //                                      return filter(root.getElementsByClassName(cssClass));
                //
                //                      elif only(tag):
                //                              return def(root):
                //                                      return root.getElementsByTagName(tagName);
                //
                //                      else:
                //                              # search by tag name, then filter
                //                              return def(root):
                //                                      return filter(root.getElementsByTagName(tagName||"*"));
                //
                //              elif infixOperator == ">":
                //                      # search direct children
                //                      return def(root):
                //                              return filter(root.children);
                //
                //              elif infixOperator == "+":
                //                      # search next sibling
                //                      return def(root):
                //                              return filter(root.nextElementSibling);
                //
                //              elif infixOperator == "~":
                //                      # search rightward siblings
                //                      return def(root):
                //                              return filter(nextSiblings(root));

                var io = query.infixOper;
                var oper = (io ? io.oper : "");
                // the default filter func which tests for all conditions in the query
                // part. This is potentially inefficient, so some optimized paths may
                // re-define it to test fewer things.
                var filterFunc = getSimpleFilterFunc(query, { el: 1 });
                var qt = query.tag;
                var wildcardTag = ("*" == qt);
                var ecs = getDoc()["getElementsByClassName"];

                if(!oper){
                        // if there's no infix operator, then it's a descendant query. ID
                        // and "elements by class name" variants can be accelerated so we
                        // call them out explicitly:
                        if(query.id){
                                // testing shows that the overhead of yesman() is acceptable
                                // and can save us some bytes vs. re-defining the function
                                // everywhere.
                                filterFunc = (!query.loops && wildcardTag) ?
                                        yesman :
                                        getSimpleFilterFunc(query, { el: 1, id: 1 });

                                retFunc = function(root, arr){
                                        var te = d.byId(query.id, (root.ownerDocument||root));
                                        if(!te || !filterFunc(te)){ return; }
                                        if(9 == root.nodeType){ // if root's a doc, we just return directly
                                                return getArr(te, arr);
                                        }else{ // otherwise check ancestry
                                                if(_isDescendant(te, root)){
                                                        return getArr(te, arr);
                                                }
                                        }
                                }
                        }else if(
                                ecs &&
                                // isAlien check. Workaround for Prototype.js being totally evil/dumb.
                                /\{\s*\[native code\]\s*\}/.test(String(ecs)) &&
                                query.classes.length &&
                                !cssCaseBug
                        ){
                                // it's a class-based query and we've got a fast way to run it.

                                // ignore class and ID filters since we will have handled both
                                filterFunc = getSimpleFilterFunc(query, { el: 1, classes: 1, id: 1 });
                                var classesString = query.classes.join(" ");
                                retFunc = function(root, arr, bag){
                                        var ret = getArr(0, arr), te, x=0;
                                        var tret = root.getElementsByClassName(classesString);
                                        while((te = tret[x++])){
                                                if(filterFunc(te, root) && _isUnique(te, bag)){
                                                        ret.push(te);
                                                }
                                        }
                                        return ret;
                                };

                        }else if(!wildcardTag && !query.loops){
                                // it's tag only. Fast-path it.
                                retFunc = function(root, arr, bag){
                                        var ret = getArr(0, arr), te, x=0;
                                        var tret = root.getElementsByTagName(query.getTag());
                                        while((te = tret[x++])){
                                                if(_isUnique(te, bag)){
                                                        ret.push(te);
                                                }
                                        }
                                        return ret;
                                };
                        }else{
                                // the common case:
                                //              a descendant selector without a fast path. By now it's got
                                //              to have a tag selector, even if it's just "*" so we query
                                //              by that and filter
                                filterFunc = getSimpleFilterFunc(query, { el: 1, tag: 1, id: 1 });
                                retFunc = function(root, arr, bag){
                                        var ret = getArr(0, arr), te, x=0;
                                        // we use getTag() to avoid case sensitivity issues
                                        var tret = root.getElementsByTagName(query.getTag());
                                        while((te = tret[x++])){
                                                if(filterFunc(te, root) && _isUnique(te, bag)){
                                                        ret.push(te);
                                                }
                                        }
                                        return ret;
                                };
                        }
                }else{
                        // the query is scoped in some way. Instead of querying by tag we
                        // use some other collection to find candidate nodes
                        var skipFilters = { el: 1 };
                        if(wildcardTag){
                                skipFilters.tag = 1;
                        }
                        filterFunc = getSimpleFilterFunc(query, skipFilters);
                        if("+" == oper){
                                retFunc = _nextSibling(filterFunc);
                        }else if("~" == oper){
                                retFunc = _nextSiblings(filterFunc);
                        }else if(">" == oper){
                                retFunc = _childElements(filterFunc);
                        }
                }
                // cache it and return
                return _getElementsFuncCache[query.query] = retFunc;
        };

        var filterDown = function(root, queryParts){
                // NOTE:
                //              this is the guts of the DOM query system. It takes a list of
                //              parsed query parts and a root and finds children which match
                //              the selector represented by the parts
                var candidates = getArr(root), qp, x, te, qpl = queryParts.length, bag, ret;

                for(var i = 0; i < qpl; i++){
                        ret = [];
                        qp = queryParts[i];
                        x = candidates.length - 1;
                        if(x > 0){
                                // if we have more than one root at this level, provide a new
                                // hash to use for checking group membership but tell the
                                // system not to post-filter us since we will already have been
                                // gauranteed to be unique
                                bag = {};
                                ret.nozip = true;
                        }
                        var gef = getElementsFunc(qp);
                        for(var j = 0; (te = candidates[j]); j++){
                                // for every root, get the elements that match the descendant
                                // selector, adding them to the "ret" array and filtering them
                                // via membership in this level's bag. If there are more query
                                // parts, then this level's return will be used as the next
                                // level's candidates
                                gef(te, ret, bag);
                        }
                        if(!ret.length){ break; }
                        candidates = ret;
                }
                return ret;
        };

        ////////////////////////////////////////////////////////////////////////
        // the query runner
        ////////////////////////////////////////////////////////////////////////

        // these are the primary caches for full-query results. The query
        // dispatcher functions are generated then stored here for hash lookup in
        // the future
        var _queryFuncCacheDOM = {},
                _queryFuncCacheQSA = {};

        // this is the second level of spliting, from full-length queries (e.g.,
        // "div.foo .bar") into simple query expressions (e.g., ["div.foo",
        // ".bar"])
        var getStepQueryFunc = function(query){
                var qparts = getQueryParts(trim(query));

                // if it's trivial, avoid iteration and zipping costs
                if(qparts.length == 1){
                        // we optimize this case here to prevent dispatch further down the
                        // chain, potentially slowing things down. We could more elegantly
                        // handle this in filterDown(), but it's slower for simple things
                        // that need to be fast (e.g., "#someId").
                        var tef = getElementsFunc(qparts[0]);
                        return function(root){
                                var r = tef(root, new qlc());
                                if(r){ r.nozip = true; }
                                return r;
                        }
                }

                // otherwise, break it up and return a runner that iterates over the parts recursively
                return function(root){
                        return filterDown(root, qparts);
                }
        };

        // NOTES:
        //      * we can't trust QSA for anything but document-rooted queries, so
        //        caching is split into DOM query evaluators and QSA query evaluators
        //      * caching query results is dirty and leak-prone (or, at a minimum,
        //        prone to unbounded growth). Other toolkits may go this route, but
        //        they totally destroy their own ability to manage their memory
        //        footprint. If we implement it, it should only ever be with a fixed
        //        total element reference # limit and an LRU-style algorithm since JS
        //        has no weakref support. Caching compiled query evaluators is also
        //        potentially problematic, but even on large documents the size of the
        //        query evaluators is often < 100 function objects per evaluator (and
        //        LRU can be applied if it's ever shown to be an issue).
        //      * since IE's QSA support is currently only for HTML documents and even
        //        then only in IE 8's "standards mode", we have to detect our dispatch
        //        route at query time and keep 2 separate caches. Ugg.

        // we need to determine if we think we can run a given query via
        // querySelectorAll or if we'll need to fall back on DOM queries to get
        // there. We need a lot of information about the environment and the query
        // to make the determiniation (e.g. does it support QSA, does the query in
        // question work in the native QSA impl, etc.).
        var nua = navigator.userAgent;
        // some versions of Safari provided QSA, but it was buggy and crash-prone.
        // We need te detect the right "internal" webkit version to make this work.
        var wk = "WebKit/";
        var is525 = (
                d.isWebKit &&
                (nua.indexOf(wk) > 0) &&
                (parseFloat(nua.split(wk)[1]) > 528)
        );

        // IE QSA queries may incorrectly include comment nodes, so we throw the
        // zipping function into "remove" comments mode instead of the normal "skip
        // it" which every other QSA-clued browser enjoys
        var noZip = d.isIE ? "commentStrip" : "nozip";

        var qsa = "querySelectorAll";
        var qsaAvail = (
                !!getDoc()[qsa] &&
                // see #5832
                (!d.isSafari || (d.isSafari > 3.1) || is525 )
        );

        //Don't bother with n+3 type of matches, IE complains if we modify those.
        var infixSpaceRe = /n\+\d|([^ ])?([>~+])([^ =])?/g;
        var infixSpaceFunc = function(match, pre, ch, post) {
                return ch ? (pre ? pre + " " : "") + ch + (post ? " " + post : "") : /*n+3*/ match;
        };

        var getQueryFunc = function(query, forceDOM){
                //Normalize query. The CSS3 selectors spec allows for omitting spaces around
                //infix operators, >, ~ and +
                //Do the work here since detection for spaces is used as a simple "not use QSA"
                //test below.
                query = query.replace(infixSpaceRe, infixSpaceFunc);

                if(qsaAvail){
                        // if we've got a cached variant and we think we can do it, run it!
                        var qsaCached = _queryFuncCacheQSA[query];
                        if(qsaCached && !forceDOM){ return qsaCached; }
                }

                // else if we've got a DOM cached variant, assume that we already know
                // all we need to and use it
                var domCached = _queryFuncCacheDOM[query];
                if(domCached){ return domCached; }

                // TODO:
                //              today we're caching DOM and QSA branches separately so we
                //              recalc useQSA every time. If we had a way to tag root+query
                //              efficiently, we'd be in good shape to do a global cache.

                var qcz = query.charAt(0);
                var nospace = (-1 == query.indexOf(" "));

                // byId searches are wicked fast compared to QSA, even when filtering
                // is required
                if( (query.indexOf("#") >= 0) && (nospace) ){
                        forceDOM = true;
                }

                var useQSA = (
                        qsaAvail && (!forceDOM) &&
                        // as per CSS 3, we can't currently start w/ combinator:
                        //              http://www.w3.org/TR/css3-selectors/#w3cselgrammar
                        (specials.indexOf(qcz) == -1) &&
                        // IE's QSA impl sucks on pseudos
                        (!d.isIE || (query.indexOf(":") == -1)) &&

                        (!(cssCaseBug && (query.indexOf(".") >= 0))) &&

                        // FIXME:
                        //              need to tighten up browser rules on ":contains" and "|=" to
                        //              figure out which aren't good
                        //              Latest webkit (around 531.21.8) does not seem to do well with :checked on option
                        //              elements, even though according to spec, selected options should
                        //              match :checked. So go nonQSA for it:
                        //              http://bugs.dojotoolkit.org/ticket/5179
                        (query.indexOf(":contains") == -1) && (query.indexOf(":checked") == -1) &&
                        (query.indexOf("|=") == -1) // some browsers don't grok it
                );

                // TODO:
                //              if we've got a descendant query (e.g., "> .thinger" instead of
                //              just ".thinger") in a QSA-able doc, but are passed a child as a
                //              root, it should be possible to give the item a synthetic ID and
                //              trivially rewrite the query to the form "#synid > .thinger" to
                //              use the QSA branch


                if(useQSA){
                        var tq = (specials.indexOf(query.charAt(query.length-1)) >= 0) ?
                                                (query + " *") : query;
                        return _queryFuncCacheQSA[query] = function(root){
                                try{
                                        // the QSA system contains an egregious spec bug which
                                        // limits us, effectively, to only running QSA queries over
                                        // entire documents.  See:
                                        //              http://ejohn.org/blog/thoughts-on-queryselectorall/
                                        //      despite this, we can also handle QSA runs on simple
                                        //      selectors, but we don't want detection to be expensive
                                        //      so we're just checking for the presence of a space char
                                        //      right now. Not elegant, but it's cheaper than running
                                        //      the query parser when we might not need to
                                        if(!((9 == root.nodeType) || nospace)){ throw ""; }
                                        var r = root[qsa](tq);
                                        // skip expensive duplication checks and just wrap in a NodeList
                                        r[noZip] = true;
                                        return r;
                                }catch(e){
                                        // else run the DOM branch on this query, ensuring that we
                                        // default that way in the future
                                        return getQueryFunc(query, true)(root);
                                }
                        }
                }else{
                        // DOM branch
                        var parts = query.split(/\s*,\s*/);
                        return _queryFuncCacheDOM[query] = ((parts.length < 2) ?
                                // if not a compound query (e.g., ".foo, .bar"), cache and return a dispatcher
                                getStepQueryFunc(query) :
                                // if it *is* a complex query, break it up into its
                                // constituent parts and return a dispatcher that will
                                // merge the parts when run
                                function(root){
                                        var pindex = 0, // avoid array alloc for every invocation
                                                ret = [],
                                                tp;
                                        while((tp = parts[pindex++])){
                                                ret = ret.concat(getStepQueryFunc(tp)(root));
                                        }
                                        return ret;
                                }
                        );
                }
        };

        var _zipIdx = 0;

        // NOTE:
        //              this function is Moo inspired, but our own impl to deal correctly
        //              with XML in IE
        var _nodeUID = d.isIE ? function(node){
                if(caseSensitive){
                        // XML docs don't have uniqueID on their nodes
                        return (node.getAttribute("_uid") || node.setAttribute("_uid", ++_zipIdx) || _zipIdx);

                }else{
                        return node.uniqueID;
                }
        } :
        function(node){
                return (node._uid || (node._uid = ++_zipIdx));
        };

        // determine if a node in is unique in a "bag". In this case we don't want
        // to flatten a list of unique items, but rather just tell if the item in
        // question is already in the bag. Normally we'd just use hash lookup to do
        // this for us but IE's DOM is busted so we can't really count on that. On
        // the upside, it gives us a built in unique ID function.
        var _isUnique = function(node, bag){
                if(!bag){ return 1; }
                var id = _nodeUID(node);
                if(!bag[id]){ return bag[id] = 1; }
                return 0;
        };

        // attempt to efficiently determine if an item in a list is a dupe,
        // returning a list of "uniques", hopefully in doucment order
        var _zipIdxName = "_zipIdx";
        var _zip = function(arr){
                if(arr && arr.nozip){
                        return (qlc._wrap) ? qlc._wrap(arr) : arr;
                }
                // var ret = new d._NodeListCtor();
                var ret = new qlc();
                if(!arr || !arr.length){ return ret; }
                if(arr[0]){
                        ret.push(arr[0]);
                }
                if(arr.length < 2){ return ret; }

                _zipIdx++;
                
                // we have to fork here for IE and XML docs because we can't set
                // expandos on their nodes (apparently). *sigh*
                if(d.isIE && caseSensitive){
                        var szidx = _zipIdx+"";
                        arr[0].setAttribute(_zipIdxName, szidx);
                        for(var x = 1, te; te = arr[x]; x++){
                                if(arr[x].getAttribute(_zipIdxName) != szidx){
                                        ret.push(te);
                                }
                                te.setAttribute(_zipIdxName, szidx);
                        }
                }else if(d.isIE && arr.commentStrip){
                        try{
                                for(var x = 1, te; te = arr[x]; x++){
                                        if(_isElement(te)){
                                                ret.push(te);
                                        }
                                }
                        }catch(e){ /* squelch */ }
                }else{
                        if(arr[0]){ arr[0][_zipIdxName] = _zipIdx; }
                        for(var x = 1, te; te = arr[x]; x++){
                                if(arr[x][_zipIdxName] != _zipIdx){
                                        ret.push(te);
                                }
                                te[_zipIdxName] = _zipIdx;
                        }
                }
                return ret;
        };

        // the main executor
        d.query = function(/*String*/ query, /*String|DOMNode?*/ root){
                //      summary:
                //              Returns nodes which match the given CSS3 selector, searching the
                //              entire document by default but optionally taking a node to scope
                //              the search by. Returns an instance of dojo.NodeList.
                //      description:
                //              dojo.query() is the swiss army knife of DOM node manipulation in
                //              Dojo. Much like Prototype's "$$" (bling-bling) function or JQuery's
                //              "$" function, dojo.query provides robust, high-performance
                //              CSS-based node selector support with the option of scoping searches
                //              to a particular sub-tree of a document.
                //
                //              Supported Selectors:
                //              --------------------
                //
                //              dojo.query() supports a rich set of CSS3 selectors, including:
                //
                //                      * class selectors (e.g., `.foo`)
                //                      * node type selectors like `span`
                //                      * ` ` descendant selectors
                //                      * `>` child element selectors
                //                      * `#foo` style ID selectors
                //                      * `*` universal selector
                //                      * `~`, the preceded-by sibling selector
                //                      * `+`, the immediately preceded-by sibling selector
                //                      * attribute queries:
                //                      |       * `[foo]` attribute presence selector
                //                      |       * `[foo='bar']` attribute value exact match
                //                      |       * `[foo~='bar']` attribute value list item match
                //                      |       * `[foo^='bar']` attribute start match
                //                      |       * `[foo$='bar']` attribute end match
                //                      |       * `[foo*='bar']` attribute substring match
                //                      * `:first-child`, `:last-child`, and `:only-child` positional selectors
                //                      * `:empty` content emtpy selector
                //                      * `:checked` pseudo selector
                //                      * `:nth-child(n)`, `:nth-child(2n+1)` style positional calculations
                //                      * `:nth-child(even)`, `:nth-child(odd)` positional selectors
                //                      * `:not(...)` negation pseudo selectors
                //
                //              Any legal combination of these selectors will work with
                //              `dojo.query()`, including compound selectors ("," delimited).
                //              Very complex and useful searches can be constructed with this
                //              palette of selectors and when combined with functions for
                //              manipulation presented by dojo.NodeList, many types of DOM
                //              manipulation operations become very straightforward.
                //
                //              Unsupported Selectors:
                //              ----------------------
                //
                //              While dojo.query handles many CSS3 selectors, some fall outside of
                //              what's reasonable for a programmatic node querying engine to
                //              handle. Currently unsupported selectors include:
                //
                //                      * namespace-differentiated selectors of any form
                //                      * all `::` pseduo-element selectors
                //                      * certain pseduo-selectors which don't get a lot of day-to-day use:
                //                      |       * `:root`, `:lang()`, `:target`, `:focus`
                //                      * all visual and state selectors:
                //                      |       * `:root`, `:active`, `:hover`, `:visisted`, `:link`,
                //                                `:enabled`, `:disabled`
                //                      * `:*-of-type` pseudo selectors
                //
                //              dojo.query and XML Documents:
                //              -----------------------------
                //
                //              `dojo.query` (as of dojo 1.2) supports searching XML documents
                //              in a case-sensitive manner. If an HTML document is served with
                //              a doctype that forces case-sensitivity (e.g., XHTML 1.1
                //              Strict), dojo.query() will detect this and "do the right
                //              thing". Case sensitivity is dependent upon the document being
                //              searched and not the query used. It is therefore possible to
                //              use case-sensitive queries on strict sub-documents (iframes,
                //              etc.) or XML documents while still assuming case-insensitivity
                //              for a host/root document.
                //
                //              Non-selector Queries:
                //              ---------------------
                //
                //              If something other than a String is passed for the query,
                //              `dojo.query` will return a new `dojo.NodeList` instance
                //              constructed from that parameter alone and all further
                //              processing will stop. This means that if you have a reference
                //              to a node or NodeList, you can quickly construct a new NodeList
                //              from the original by calling `dojo.query(node)` or
                //              `dojo.query(list)`.
                //
                //      query:
                //              The CSS3 expression to match against. For details on the syntax of
                //              CSS3 selectors, see <http://www.w3.org/TR/css3-selectors/#selectors>
                //      root:
                //              A DOMNode (or node id) to scope the search from. Optional.
                //      returns: dojo.NodeList
                //              An instance of `dojo.NodeList`. Many methods are available on
                //              NodeLists for searching, iterating, manipulating, and handling
                //              events on the matched nodes in the returned list.
                //      example:
                //              search the entire document for elements with the class "foo":
                //      |       dojo.query(".foo");
                //              these elements will match:
                //      |       <span class="foo"></span>
                //      |       <span class="foo bar"></span>
                //      |       <p class="thud foo"></p>
                //      example:
                //              search the entire document for elements with the classes "foo" *and* "bar":
                //      |       dojo.query(".foo.bar");
                //              these elements will match:
                //      |       <span class="foo bar"></span>
                //              while these will not:
                //      |       <span class="foo"></span>
                //      |       <p class="thud foo"></p>
                //      example:
                //              find `<span>` elements which are descendants of paragraphs and
                //              which have a "highlighted" class:
                //      |       dojo.query("p span.highlighted");
                //              the innermost span in this fragment matches:
                //      |       <p class="foo">
                //      |               <span>...
                //      |                       <span class="highlighted foo bar">...</span>
                //      |               </span>
                //      |       </p>
                //      example:
                //              set an "odd" class on all odd table rows inside of the table
                //              `#tabular_data`, using the `>` (direct child) selector to avoid
                //              affecting any nested tables:
                //      |       dojo.query("#tabular_data > tbody > tr:nth-child(odd)").addClass("odd");
                //      example:
                //              remove all elements with the class "error" from the document
                //              and store them in a list:
                //      |       var errors = dojo.query(".error").orphan();
                //      example:
                //              add an onclick handler to every submit button in the document
                //              which causes the form to be sent via Ajax instead:
                //      |       dojo.query("input[type='submit']").onclick(function(e){
                //      |               dojo.stopEvent(e); // prevent sending the form
                //      |               var btn = e.target;
                //      |               dojo.xhrPost({
                //      |                       form: btn.form,
                //      |                       load: function(data){
                //      |                               // replace the form with the response
                //      |                               var div = dojo.doc.createElement("div");
                //      |                               dojo.place(div, btn.form, "after");
                //      |                               div.innerHTML = data;
                //      |                               dojo.style(btn.form, "display", "none");
                //      |                       }
                //      |               });
                //      |       });

                //Set list constructor to desired value. This can change
                //between calls, so always re-assign here.
                qlc = d._NodeListCtor;

                if(!query){
                        return new qlc();
                }

                if(query.constructor == qlc){
                        return query;
                }
                if(typeof query != "string"){ // inline'd type check
                        return new qlc(query); // dojo.NodeList
                }
                if(typeof root == "string"){ // inline'd type check
                        root = d.byId(root);
                        if(!root){ return new qlc(); }
                }

                root = root||getDoc();
                var od = root.ownerDocument||root.documentElement;

                // throw the big case sensitivity switch

                // NOTE:
                //              Opera in XHTML mode doesn't detect case-sensitivity correctly
                //              and it's not clear that there's any way to test for it
                caseSensitive = (root.contentType && root.contentType=="application/xml") ||
                                                (d.isOpera && (root.doctype || od.toString() == "[object XMLDocument]")) ||
                                                (!!od) &&
                                                (d.isIE ? od.xml : (root.xmlVersion||od.xmlVersion));

                // NOTE:
                //              adding "true" as the 2nd argument to getQueryFunc is useful for
                //              testing the DOM branch without worrying about the
                //              behavior/performance of the QSA branch.
                var r = getQueryFunc(query)(root);

                // FIXME:
                //              need to investigate this branch WRT #8074 and #8075
                if(r && r.nozip && !qlc._wrap){
                        return r;
                }
                return _zip(r); // dojo.NodeList
        }

        // FIXME: need to add infrastructure for post-filtering pseudos, ala :last
        d.query.pseudos = pseudos;

        // function for filtering a NodeList based on a selector, optimized for simple selectors
        d._filterQueryResult = function(/*NodeList*/ nodeList, /*String*/ filter, /*String|DOMNode?*/ root){
                var tmpNodeList = new d._NodeListCtor(),
                        parts = getQueryParts(filter),
                        filterFunc =
                                (parts.length == 1 && !/[^\w#\.]/.test(filter)) ?
                                getSimpleFilterFunc(parts[0]) :
                                function(node) {
                                        return dojo.query(filter, root).indexOf(node) != -1;
                                };
                for(var x = 0, te; te = nodeList[x]; x++){
                        if(filterFunc(te)){ tmpNodeList.push(te); }
                }
                return tmpNodeList;
        }
};//end defineQuery

var defineAcme= function(){
        // a self-sufficient query impl
        acme = {
                trim: function(/*String*/ str){
                        // summary:
                        //              trims whitespaces from both sides of the string
                        str = str.replace(/^\s+/, '');
                        for(var i = str.length - 1; i >= 0; i--){
                                if(/\S/.test(str.charAt(i))){
                                        str = str.substring(0, i + 1);
                                        break;
                                }
                        }
                        return str;     // String
                },
                forEach: function(/*String*/ arr, /*Function*/ callback, /*Object?*/ thisObject){
                        //      summary:
                        //              an iterator function that passes items, indexes,
                        //              and the array to a callback
                        if(!arr || !arr.length){ return; }
                        for(var i=0,l=arr.length; i<l; ++i){
                                callback.call(thisObject||window, arr[i], i, arr);
                        }
                },
                byId: function(id, doc){
                        //      summary:
                        //              a function that return an element by ID, but also
                        //              accepts nodes safely
                        if(typeof id == "string"){
                                return (doc||document).getElementById(id); // DomNode
                        }else{
                                return id; // DomNode
                        }
                },
                // the default document to search
                doc: document,
                // the constructor for node list objects returned from query()
                NodeList: Array
        };

        // define acme.isIE, acme.isSafari, acme.isOpera, etc.
        var n = navigator;
        var dua = n.userAgent;
        var dav = n.appVersion;
        var tv = parseFloat(dav);
        acme.isOpera = (dua.indexOf("Opera") >= 0) ? tv: undefined;
        acme.isKhtml = (dav.indexOf("Konqueror") >= 0) ? tv : undefined;
        acme.isWebKit = parseFloat(dua.split("WebKit/")[1]) || undefined;
        acme.isChrome = parseFloat(dua.split("Chrome/")[1]) || undefined;
        var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);
        if(index && !acme.isChrome){
                acme.isSafari = parseFloat(dav.split("Version/")[1]);
                if(!acme.isSafari || parseFloat(dav.substr(index + 7)) <= 419.3){
                        acme.isSafari = 2;
                }
        }
        if(document.all && !acme.isOpera){
                acme.isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
        }

        Array._wrap = function(arr){ return arr; };
  return acme;
};

        //prefers queryPortability, then acme, then dojo
        if(this["dojo"]){
                dojo.provide("dojo._base.query");
                
                
                defineQuery(this["queryPortability"]||this["acme"]||dojo);
        }else{
                defineQuery(this["queryPortability"]||this["acme"]||defineAcme());
        }

})();

/*
*/

}

if(!dojo._hasResource["dojo._base.xhr"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.xhr"] = true;
dojo.provide("dojo._base.xhr");






(function(){
        var _d = dojo, cfg = _d.config;

        function setValue(/*Object*/obj, /*String*/name, /*String*/value){
                //summary:
                //              For the named property in object, set the value. If a value
                //              already exists and it is a string, convert the value to be an
                //              array of values.

                //Skip it if there is no value
                if(value === null){
                        return;
                }

                var val = obj[name];
                if(typeof val == "string"){ // inline'd type check
                        obj[name] = [val, value];
                }else if(_d.isArray(val)){
                        val.push(value);
                }else{
                        obj[name] = value;
                }
        }
        
        dojo.fieldToObject = function(/*DOMNode||String*/ inputNode){
                // summary:
                //              Serialize a form field to a JavaScript object.
                //
                // description:
                //              Returns the value encoded in a form field as
                //              as a string or an array of strings. Disabled form elements
                //              and unchecked radio and checkboxes are skipped. Multi-select
                //              elements are returned as an array of string values.
                var ret = null;
                var item = _d.byId(inputNode);
                if(item){
                        var _in = item.name;
                        var type = (item.type||"").toLowerCase();
                        if(_in && type && !item.disabled){
                                if(type == "radio" || type == "checkbox"){
                                        if(item.checked){ ret = item.value; }
                                }else if(item.multiple){
                                        ret = [];
                                        _d.query("option", item).forEach(function(opt){
                                                if(opt.selected){
                                                        ret.push(opt.value);
                                                }
                                        });
                                }else{
                                        ret = item.value;
                                }
                        }
                }
                return ret; // Object
        };

        dojo.formToObject = function(/*DOMNode||String*/ formNode){
                // summary:
                //              Serialize a form node to a JavaScript object.
                // description:
                //              Returns the values encoded in an HTML form as
                //              string properties in an object which it then returns. Disabled form
                //              elements, buttons, and other non-value form elements are skipped.
                //              Multi-select elements are returned as an array of string values.
                //
                // example:
                //              This form:
                //              |       <form id="test_form">
                //              |               <input type="text" name="blah" value="blah">
                //              |               <input type="text" name="no_value" value="blah" disabled>
                //              |               <input type="button" name="no_value2" value="blah">
                //              |               <select type="select" multiple name="multi" size="5">
                //              |                       <option value="blah">blah</option>
                //              |                       <option value="thud" selected>thud</option>
                //              |                       <option value="thonk" selected>thonk</option>
                //              |               </select>
                //              |       </form>
                //
                //              yields this object structure as the result of a call to
                //              formToObject():
                //
                //              |       {
                //              |               blah: "blah",
                //              |               multi: [
                //              |                       "thud",
                //              |                       "thonk"
                //              |               ]
                //              |       };

                var ret = {};
                var exclude = "file|submit|image|reset|button|";
                _d.forEach(dojo.byId(formNode).elements, function(item){
                        var _in = item.name;
                        var type = (item.type||"").toLowerCase();
                        if(_in && type && exclude.indexOf(type) == -1 && !item.disabled){
                                setValue(ret, _in, _d.fieldToObject(item));
                                if(type == "image"){
                                        ret[_in+".x"] = ret[_in+".y"] = ret[_in].x = ret[_in].y = 0;
                                }
                        }
                });
                return ret; // Object
        };

        dojo.objectToQuery = function(/*Object*/ map){
                //      summary:
                //              takes a name/value mapping object and returns a string representing
                //              a URL-encoded version of that object.
                //      example:
                //              this object:
                //
                //              |       {
                //              |               blah: "blah",
                //              |               multi: [
                //              |                       "thud",
                //              |                       "thonk"
                //              |               ]
                //              |       };
                //
                //      yields the following query string:
                //
                //      |       "blah=blah&multi=thud&multi=thonk"

                // FIXME: need to implement encodeAscii!!
                var enc = encodeURIComponent;
                var pairs = [];
                var backstop = {};
                for(var name in map){
                        var value = map[name];
                        if(value != backstop[name]){
                                var assign = enc(name) + "=";
                                if(_d.isArray(value)){
                                        for(var i=0; i < value.length; i++){
                                                pairs.push(assign + enc(value[i]));
                                        }
                                }else{
                                        pairs.push(assign + enc(value));
                                }
                        }
                }
                return pairs.join("&"); // String
        };

        dojo.formToQuery = function(/*DOMNode||String*/ formNode){
                // summary:
                //              Returns a URL-encoded string representing the form passed as either a
                //              node or string ID identifying the form to serialize
                return _d.objectToQuery(_d.formToObject(formNode)); // String
        };

        dojo.formToJson = function(/*DOMNode||String*/ formNode, /*Boolean?*/prettyPrint){
                // summary:
                //              Create a serialized JSON string from a form node or string
                //              ID identifying the form to serialize
                return _d.toJson(_d.formToObject(formNode), prettyPrint); // String
        };

        dojo.queryToObject = function(/*String*/ str){
                // summary:
                //              Create an object representing a de-serialized query section of a
                //              URL. Query keys with multiple values are returned in an array.
                //
                // example:
                //              This string:
                //
                //      |               "foo=bar&foo=baz&thinger=%20spaces%20=blah&zonk=blarg&"
                //
                //              results in this object structure:
                //
                //      |               {
                //      |                       foo: [ "bar", "baz" ],
                //      |                       thinger: " spaces =blah",
                //      |                       zonk: "blarg"
                //      |               }
                //
                //              Note that spaces and other urlencoded entities are correctly
                //              handled.

                // FIXME: should we grab the URL string if we're not passed one?
                var ret = {};
                var qp = str.split("&");
                var dec = decodeURIComponent;
                _d.forEach(qp, function(item){
                        if(item.length){
                                var parts = item.split("=");
                                var name = dec(parts.shift());
                                var val = dec(parts.join("="));
                                if(typeof ret[name] == "string"){ // inline'd type check
                                        ret[name] = [ret[name]];
                                }

                                if(_d.isArray(ret[name])){
                                        ret[name].push(val);
                                }else{
                                        ret[name] = val;
                                }
                        }
                });
                return ret; // Object
        };

        // need to block async callbacks from snatching this thread as the result
        // of an async callback might call another sync XHR, this hangs khtml forever
        // must checked by watchInFlight()

        dojo._blockAsync = false;

        // MOW: remove dojo._contentHandlers alias in 2.0
        var handlers = _d._contentHandlers = dojo.contentHandlers = {
                // summary:
                //              A map of availble XHR transport handle types. Name matches the
                //              `handleAs` attribute passed to XHR calls.
                //
                // description:
                //              A map of availble XHR transport handle types. Name matches the
                //              `handleAs` attribute passed to XHR calls. Each contentHandler is
                //              called, passing the xhr object for manipulation. The return value
                //              from the contentHandler will be passed to the `load` or `handle`
                //              functions defined in the original xhr call.
                //
                // example:
                //              Creating a custom content-handler:
                //      |       dojo.contentHandlers.makeCaps = function(xhr){
                //      |               return xhr.responseText.toUpperCase();
                //      |       }
                //      |       // and later:
                //      |       dojo.xhrGet({
                //      |               url:"foo.txt",
                //      |               handleAs:"makeCaps",
                //      |               load: function(data){ /* data is a toUpper version of foo.txt */ }
                //      |       });

                text: function(xhr){
                        // summary: A contentHandler which simply returns the plaintext response data
                        return xhr.responseText;
                },
                json: function(xhr){
                        // summary: A contentHandler which returns a JavaScript object created from the response data
                        return _d.fromJson(xhr.responseText || null);
                },
                "json-comment-filtered": function(xhr){
                        // summary: A contentHandler which expects comment-filtered JSON.
                        // description:
                        //              A contentHandler which expects comment-filtered JSON.
                        //              the json-comment-filtered option was implemented to prevent
                        //              "JavaScript Hijacking", but it is less secure than standard JSON. Use
                        //              standard JSON instead. JSON prefixing can be used to subvert hijacking.
                        //
                        //              Will throw a notice suggesting to use application/json mimetype, as
                        //              json-commenting can introduce security issues. To decrease the chances of hijacking,
                        //              use the standard `json` contentHandler, and prefix your "JSON" with: {}&&
                        //
                        //              use djConfig.useCommentedJson = true to turn off the notice
                        if(!dojo.config.useCommentedJson){
                                console.warn("Consider using the standard mimetype:application/json."
                                        + " json-commenting can introduce security issues. To"
                                        + " decrease the chances of hijacking, use the standard the 'json' handler and"
                                        + " prefix your json with: {}&&\n"
                                        + "Use djConfig.useCommentedJson=true to turn off this message.");
                        }

                        var value = xhr.responseText;
                        var cStartIdx = value.indexOf("\/*");
                        var cEndIdx = value.lastIndexOf("*\/");
                        if(cStartIdx == -1 || cEndIdx == -1){
                                throw new Error("JSON was not comment filtered");
                        }
                        return _d.fromJson(value.substring(cStartIdx+2, cEndIdx));
                },
                javascript: function(xhr){
                        // summary: A contentHandler which evaluates the response data, expecting it to be valid JavaScript

                        // FIXME: try Moz and IE specific eval variants?
                        return _d.eval(xhr.responseText);
                },
                xml: function(xhr){
                        // summary: A contentHandler returning an XML Document parsed from the response data
                        var result = xhr.responseXML;
                                                if(_d.isIE && (!result || !result.documentElement)){
                                //WARNING: this branch used by the xml handling in dojo.io.iframe,
                                //so be sure to test dojo.io.iframe if making changes below.
                                var ms = function(n){ return "MSXML" + n + ".DOMDocument"; };
                                var dp = ["Microsoft.XMLDOM", ms(6), ms(4), ms(3), ms(2)];
                                _d.some(dp, function(p){
                                        try{
                                                var dom = new ActiveXObject(p);
                                                dom.async = false;
                                                dom.loadXML(xhr.responseText);
                                                result = dom;
                                        }catch(e){ return false; }
                                        return true;
                                });
                        }
                                                return result; // DOMDocument
                },
                "json-comment-optional": function(xhr){
                        // summary: A contentHandler which checks the presence of comment-filtered JSON and
                        //              alternates between the `json` and `json-comment-filtered` contentHandlers.
                        if(xhr.responseText && /^[^{\[]*\/\*/.test(xhr.responseText)){
                                return handlers["json-comment-filtered"](xhr);
                        }else{
                                return handlers["json"](xhr);
                        }
                }
        };

        /*=====
        dojo.__IoArgs = function(){
                //      url: String
                //              URL to server endpoint.
                //      content: Object?
                //              Contains properties with string values. These
                //              properties will be serialized as name1=value2 and
                //              passed in the request.
                //      timeout: Integer?
                //              Milliseconds to wait for the response. If this time
                //              passes, the then error callbacks are called.
                //      form: DOMNode?
                //              DOM node for a form. Used to extract the form values
                //              and send to the server.
                //      preventCache: Boolean?
                //              Default is false. If true, then a
                //              "dojo.preventCache" parameter is sent in the request
                //              with a value that changes with each request
                //              (timestamp). Useful only with GET-type requests.
                //      handleAs: String?
                //              Acceptable values depend on the type of IO
                //              transport (see specific IO calls for more information).
                //      rawBody: String?
                //              Sets the raw body for an HTTP request. If this is used, then the content
                //              property is ignored. This is mostly useful for HTTP methods that have
                //              a body to their requests, like PUT or POST. This property can be used instead
                //              of postData and putData for dojo.rawXhrPost and dojo.rawXhrPut respectively.
                //      ioPublish: Boolean?
                //              Set this explicitly to false to prevent publishing of topics related to
                //              IO operations. Otherwise, if djConfig.ioPublish is set to true, topics
                //              will be published via dojo.publish for different phases of an IO operation.
                //              See dojo.__IoPublish for a list of topics that are published.
                //      load: Function?
                //              This function will be
                //              called on a successful HTTP response code.
                //      error: Function?
                //              This function will
                //              be called when the request fails due to a network or server error, the url
                //              is invalid, etc. It will also be called if the load or handle callback throws an
                //              exception, unless djConfig.debugAtAllCosts is true.  This allows deployed applications
                //              to continue to run even when a logic error happens in the callback, while making
                //              it easier to troubleshoot while in debug mode.
                //      handle: Function?
                //              This function will
                //              be called at the end of every request, whether or not an error occurs.
                this.url = url;
                this.content = content;
                this.timeout = timeout;
                this.form = form;
                this.preventCache = preventCache;
                this.handleAs = handleAs;
                this.ioPublish = ioPublish;
                this.load = function(response, ioArgs){
                        // ioArgs: dojo.__IoCallbackArgs
                        //              Provides additional information about the request.
                        // response: Object
                        //              The response in the format as defined with handleAs.
                }
                this.error = function(response, ioArgs){
                        // ioArgs: dojo.__IoCallbackArgs
                        //              Provides additional information about the request.
                        // response: Object
                        //              The response in the format as defined with handleAs.
                }
                this.handle = function(loadOrError, response, ioArgs){
                        // loadOrError: String
                        //              Provides a string that tells you whether this function
                        //              was called because of success (load) or failure (error).
                        // response: Object
                        //              The response in the format as defined with handleAs.
                        // ioArgs: dojo.__IoCallbackArgs
                        //              Provides additional information about the request.
                }
        }
        =====*/

        /*=====
        dojo.__IoCallbackArgs = function(args, xhr, url, query, handleAs, id, canDelete, json){
                //      args: Object
                //              the original object argument to the IO call.
                //      xhr: XMLHttpRequest
                //              For XMLHttpRequest calls only, the
                //              XMLHttpRequest object that was used for the
                //              request.
                //      url: String
                //              The final URL used for the call. Many times it
                //              will be different than the original args.url
                //              value.
                //      query: String
                //              For non-GET requests, the
                //              name1=value1&name2=value2 parameters sent up in
                //              the request.
                //      handleAs: String
                //              The final indicator on how the response will be
                //              handled.
                //      id: String
                //              For dojo.io.script calls only, the internal
                //              script ID used for the request.
                //      canDelete: Boolean
                //              For dojo.io.script calls only, indicates
                //              whether the script tag that represents the
                //              request can be deleted after callbacks have
                //              been called. Used internally to know when
                //              cleanup can happen on JSONP-type requests.
                //      json: Object
                //              For dojo.io.script calls only: holds the JSON
                //              response for JSONP-type requests. Used
                //              internally to hold on to the JSON responses.
                //              You should not need to access it directly --
                //              the same object should be passed to the success
                //              callbacks directly.
                this.args = args;
                this.xhr = xhr;
                this.url = url;
                this.query = query;
                this.handleAs = handleAs;
                this.id = id;
                this.canDelete = canDelete;
                this.json = json;
        }
        =====*/


        /*=====
        dojo.__IoPublish = function(){
                //      summary:
                //              This is a list of IO topics that can be published
                //              if djConfig.ioPublish is set to true. IO topics can be
                //              published for any Input/Output, network operation. So,
                //              dojo.xhr, dojo.io.script and dojo.io.iframe can all
                //              trigger these topics to be published.
                //      start: String
                //              "/dojo/io/start" is sent when there are no outstanding IO
                //              requests, and a new IO request is started. No arguments
                //              are passed with this topic.
                //      send: String
                //              "/dojo/io/send" is sent whenever a new IO request is started.
                //              It passes the dojo.Deferred for the request with the topic.
                //      load: String
                //              "/dojo/io/load" is sent whenever an IO request has loaded
                //              successfully. It passes the response and the dojo.Deferred
                //              for the request with the topic.
                //      error: String
                //              "/dojo/io/error" is sent whenever an IO request has errored.
                //              It passes the error and the dojo.Deferred
                //              for the request with the topic.
                //      done: String
                //              "/dojo/io/done" is sent whenever an IO request has completed,
                //              either by loading or by erroring. It passes the error and
                //              the dojo.Deferred for the request with the topic.
                //      stop: String
                //              "/dojo/io/stop" is sent when all outstanding IO requests have
                //              finished. No arguments are passed with this topic.
                this.start = "/dojo/io/start";
                this.send = "/dojo/io/send";
                this.load = "/dojo/io/load";
                this.error = "/dojo/io/error";
                this.done = "/dojo/io/done";
                this.stop = "/dojo/io/stop";
        }
        =====*/


        dojo._ioSetArgs = function(/*dojo.__IoArgs*/args,
                        /*Function*/canceller,
                        /*Function*/okHandler,
                        /*Function*/errHandler){
                //      summary:
                //              sets up the Deferred and ioArgs property on the Deferred so it
                //              can be used in an io call.
                //      args:
                //              The args object passed into the public io call. Recognized properties on
                //              the args object are:
                //      canceller:
                //              The canceller function used for the Deferred object. The function
                //              will receive one argument, the Deferred object that is related to the
                //              canceller.
                //      okHandler:
                //              The first OK callback to be registered with Deferred. It has the opportunity
                //              to transform the OK response. It will receive one argument -- the Deferred
                //              object returned from this function.
                //      errHandler:
                //              The first error callback to be registered with Deferred. It has the opportunity
                //              to do cleanup on an error. It will receive two arguments: error (the
                //              Error object) and dfd, the Deferred object returned from this function.

                var ioArgs = {args: args, url: args.url};

                //Get values from form if requestd.
                var formObject = null;
                if(args.form){
                        var form = _d.byId(args.form);
                        //IE requires going through getAttributeNode instead of just getAttribute in some form cases,
                        //so use it for all.  See #2844
                        var actnNode = form.getAttributeNode("action");
                        ioArgs.url = ioArgs.url || (actnNode ? actnNode.value : null);
                        formObject = _d.formToObject(form);
                }

                // set up the query params
                var miArgs = [{}];
        
                if(formObject){
                        // potentially over-ride url-provided params w/ form values
                        miArgs.push(formObject);
                }
                if(args.content){
                        // stuff in content over-rides what's set by form
                        miArgs.push(args.content);
                }
                if(args.preventCache){
                        miArgs.push({"dojo.preventCache": new Date().valueOf()});
                }
                ioArgs.query = _d.objectToQuery(_d.mixin.apply(null, miArgs));
        
                // .. and the real work of getting the deferred in order, etc.
                ioArgs.handleAs = args.handleAs || "text";
                var d = new _d.Deferred(canceller);
                d.addCallbacks(okHandler, function(error){
                        return errHandler(error, d);
                });

                //Support specifying load, error and handle callback functions from the args.
                //For those callbacks, the "this" object will be the args object.
                //The callbacks will get the deferred result value as the
                //first argument and the ioArgs object as the second argument.
                var ld = args.load;
                if(ld && _d.isFunction(ld)){
                        d.addCallback(function(value){
                                return ld.call(args, value, ioArgs);
                        });
                }
                var err = args.error;
                if(err && _d.isFunction(err)){
                        d.addErrback(function(value){
                                return err.call(args, value, ioArgs);
                        });
                }
                var handle = args.handle;
                if(handle && _d.isFunction(handle)){
                        d.addBoth(function(value){
                                return handle.call(args, value, ioArgs);
                        });
                }

                //Plug in topic publishing, if dojo.publish is loaded.
                if(cfg.ioPublish && _d.publish && ioArgs.args.ioPublish !== false){
                        d.addCallbacks(
                                function(res){
                                        _d.publish("/dojo/io/load", [d, res]);
                                        return res;
                                },
                                function(res){
                                        _d.publish("/dojo/io/error", [d, res]);
                                        return res;
                                }
                        );
                        d.addBoth(function(res){
                                _d.publish("/dojo/io/done", [d, res]);
                                return res;
                        });
                }

                d.ioArgs = ioArgs;
        
                // FIXME: need to wire up the xhr object's abort method to something
                // analagous in the Deferred
                return d;
        };

        var _deferredCancel = function(/*Deferred*/dfd){
                // summary: canceller function for dojo._ioSetArgs call.
                
                dfd.canceled = true;
                var xhr = dfd.ioArgs.xhr;
                var _at = typeof xhr.abort;
                if(_at == "function" || _at == "object" || _at == "unknown"){
                        xhr.abort();
                }
                var err = dfd.ioArgs.error;
                if(!err){
                        err = new Error("xhr cancelled");
                        err.dojoType="cancel";
                }
                return err;
        };
        var _deferredOk = function(/*Deferred*/dfd){
                // summary: okHandler function for dojo._ioSetArgs call.

                var ret = handlers[dfd.ioArgs.handleAs](dfd.ioArgs.xhr);
                return ret === undefined ? null : ret;
        };
        var _deferError = function(/*Error*/error, /*Deferred*/dfd){
                // summary: errHandler function for dojo._ioSetArgs call.

                if(!dfd.ioArgs.args.failOk){
                        console.error(error);
                }
                return error;
        };

        // avoid setting a timer per request. It degrades performance on IE
        // something fierece if we don't use unified loops.
        var _inFlightIntvl = null;
        var _inFlight = [];
        
        
        //Use a separate count for knowing if we are starting/stopping io calls.
        //Cannot use _inFlight.length since it can change at a different time than
        //when we want to do this kind of test. We only want to decrement the count
        //after a callback/errback has finished, since the callback/errback should be
        //considered as part of finishing a request.
        var _pubCount = 0;
        var _checkPubCount = function(dfd){
                if(_pubCount <= 0){
                        _pubCount = 0;
                        if(cfg.ioPublish && _d.publish && (!dfd || dfd && dfd.ioArgs.args.ioPublish !== false)){
                                _d.publish("/dojo/io/stop");
                        }
                }
        };

        var _watchInFlight = function(){
                //summary:
                //              internal method that checks each inflight XMLHttpRequest to see
                //              if it has completed or if the timeout situation applies.
                
                var now = (new Date()).getTime();
                // make sure sync calls stay thread safe, if this callback is called
                // during a sync call and this results in another sync call before the
                // first sync call ends the browser hangs
                if(!_d._blockAsync){
                        // we need manual loop because we often modify _inFlight (and therefore 'i') while iterating
                        // note: the second clause is an assigment on purpose, lint may complain
                        for(var i = 0, tif; i < _inFlight.length && (tif = _inFlight[i]); i++){
                                var dfd = tif.dfd;
                                var func = function(){
                                        if(!dfd || dfd.canceled || !tif.validCheck(dfd)){
                                                _inFlight.splice(i--, 1);
                                                _pubCount -= 1;
                                        }else if(tif.ioCheck(dfd)){
                                                _inFlight.splice(i--, 1);
                                                tif.resHandle(dfd);
                                                _pubCount -= 1;
                                        }else if(dfd.startTime){
                                                //did we timeout?
                                                if(dfd.startTime + (dfd.ioArgs.args.timeout || 0) < now){
                                                        _inFlight.splice(i--, 1);
                                                        var err = new Error("timeout exceeded");
                                                        err.dojoType = "timeout";
                                                        dfd.errback(err);
                                                        //Cancel the request so the io module can do appropriate cleanup.
                                                        dfd.cancel();
                                                        _pubCount -= 1;
                                                }
                                        }
                                };
                                if(dojo.config.debugAtAllCosts){
                                        func.call(this);
                                }else{
                                        try{
                                                func.call(this);
                                        }catch(e){
                                                dfd.errback(e);
                                        }
                                }
                        }
                }

                _checkPubCount(dfd);

                if(!_inFlight.length){
                        clearInterval(_inFlightIntvl);
                        _inFlightIntvl = null;
                        return;
                }
        };

        dojo._ioCancelAll = function(){
                //summary: Cancels all pending IO requests, regardless of IO type
                //(xhr, script, iframe).
                try{
                        _d.forEach(_inFlight, function(i){
                                try{
                                        i.dfd.cancel();
                                }catch(e){/*squelch*/}
                        });
                }catch(e){/*squelch*/}
        };

        //Automatically call cancel all io calls on unload
        //in IE for trac issue #2357.
                if(_d.isIE){
                _d.addOnWindowUnload(_d._ioCancelAll);
        }
        
        _d._ioNotifyStart = function(/*Deferred*/dfd){
                // summary:
                //              If dojo.publish is available, publish topics
                //              about the start of a request queue and/or the
                //              the beginning of request.
                // description:
                //              Used by IO transports. An IO transport should
                //              call this method before making the network connection.
                if(cfg.ioPublish && _d.publish && dfd.ioArgs.args.ioPublish !== false){
                        if(!_pubCount){
                                _d.publish("/dojo/io/start");
                        }
                        _pubCount += 1;
                        _d.publish("/dojo/io/send", [dfd]);
                }
        };

        _d._ioWatch = function(dfd, validCheck, ioCheck, resHandle){
                // summary:
                //              Watches the io request represented by dfd to see if it completes.
                // dfd: Deferred
                //              The Deferred object to watch.
                // validCheck: Function
                //              Function used to check if the IO request is still valid. Gets the dfd
                //              object as its only argument.
                // ioCheck: Function
                //              Function used to check if basic IO call worked. Gets the dfd
                //              object as its only argument.
                // resHandle: Function
                //              Function used to process response. Gets the dfd
                //              object as its only argument.
                var args = dfd.ioArgs.args;
                if(args.timeout){
                        dfd.startTime = (new Date()).getTime();
                }
                
                _inFlight.push({dfd: dfd, validCheck: validCheck, ioCheck: ioCheck, resHandle: resHandle});
                if(!_inFlightIntvl){
                        _inFlightIntvl = setInterval(_watchInFlight, 50);
                }
                // handle sync requests
                //A weakness: async calls in flight
                //could have their handlers called as part of the
                //_watchInFlight call, before the sync's callbacks
                // are called.
                if(args.sync){
                        _watchInFlight();
                }
        };

        var _defaultContentType = "application/x-www-form-urlencoded";

        var _validCheck = function(/*Deferred*/dfd){
                return dfd.ioArgs.xhr.readyState; //boolean
        };
        var _ioCheck = function(/*Deferred*/dfd){
                return 4 == dfd.ioArgs.xhr.readyState; //boolean
        };
        var _resHandle = function(/*Deferred*/dfd){
                var xhr = dfd.ioArgs.xhr;
                if(_d._isDocumentOk(xhr)){
                        dfd.callback(dfd);
                }else{
                        var err = new Error("Unable to load " + dfd.ioArgs.url + " status:" + xhr.status);
                        err.status = xhr.status;
                        err.responseText = xhr.responseText;
                        dfd.errback(err);
                }
        };

        dojo._ioAddQueryToUrl = function(/*dojo.__IoCallbackArgs*/ioArgs){
                //summary: Adds query params discovered by the io deferred construction to the URL.
                //Only use this for operations which are fundamentally GET-type operations.
                if(ioArgs.query.length){
                        ioArgs.url += (ioArgs.url.indexOf("?") == -1 ? "?" : "&") + ioArgs.query;
                        ioArgs.query = null;
                }
        };

        /*=====
        dojo.declare("dojo.__XhrArgs", dojo.__IoArgs, {
                constructor: function(){
                        //      summary:
                        //              In addition to the properties listed for the dojo._IoArgs type,
                        //              the following properties are allowed for dojo.xhr* methods.
                        //      handleAs: String?
                        //              Acceptable values are: text (default), json, json-comment-optional,
                        //              json-comment-filtered, javascript, xml. See `dojo.contentHandlers`
                        //      sync: Boolean?
                        //              false is default. Indicates whether the request should
                        //              be a synchronous (blocking) request.
                        //      headers: Object?
                        //              Additional HTTP headers to send in the request.
                        //      failOk: Boolean?
                        //              false is default. Indicates whether a request should be
                        //              allowed to fail (and therefore no console error message in
                        //              the event of a failure)
                        this.handleAs = handleAs;
                        this.sync = sync;
                        this.headers = headers;
                        this.failOk = failOk;
                }
        });
        =====*/

        dojo.xhr = function(/*String*/ method, /*dojo.__XhrArgs*/ args, /*Boolean?*/ hasBody){
                //      summary:
                //              Sends an HTTP request with the given method.
                //      description:
                //              Sends an HTTP request with the given method.
                //              See also dojo.xhrGet(), xhrPost(), xhrPut() and dojo.xhrDelete() for shortcuts
                //              for those HTTP methods. There are also methods for "raw" PUT and POST methods
                //              via dojo.rawXhrPut() and dojo.rawXhrPost() respectively.
                //      method:
                //              HTTP method to be used, such as GET, POST, PUT, DELETE.  Should be uppercase.
                //      hasBody:
                //              If the request has an HTTP body, then pass true for hasBody.

                //Make the Deferred object for this xhr request.
                var dfd = _d._ioSetArgs(args, _deferredCancel, _deferredOk, _deferError);
                var ioArgs = dfd.ioArgs;

                //Pass the args to _xhrObj, to allow alternate XHR calls based specific calls, like
                //the one used for iframe proxies.
                var xhr = ioArgs.xhr = _d._xhrObj(ioArgs.args);
                //If XHR factory fails, cancel the deferred.
                if(!xhr){
                        dfd.cancel();
                        return dfd;
                }

                //Allow for specifying the HTTP body completely.
                if("postData" in args){
                        ioArgs.query = args.postData;
                }else if("putData" in args){
                        ioArgs.query = args.putData;
                }else if("rawBody" in args){
                        ioArgs.query = args.rawBody;
                }else if((arguments.length > 2 && !hasBody) || "POST|PUT".indexOf(method.toUpperCase()) == -1){
                        //Check for hasBody being passed. If no hasBody,
                        //then only append query string if not a POST or PUT request.
                        _d._ioAddQueryToUrl(ioArgs);
                }

                // IE 6 is a steaming pile. It won't let you call apply() on the native function (xhr.open).
                // workaround for IE6's apply() "issues"
                xhr.open(method, ioArgs.url, args.sync !== true, args.user || undefined, args.password || undefined);
                if(args.headers){
                        for(var hdr in args.headers){
                                if(hdr.toLowerCase() === "content-type" && !args.contentType){
                                        args.contentType = args.headers[hdr];
                                }else if(args.headers[hdr]){
                                        //Only add header if it has a value. This allows for instnace, skipping
                                        //insertion of X-Requested-With by specifying empty value.
                                        xhr.setRequestHeader(hdr, args.headers[hdr]);
                                }
                        }
                }
                // FIXME: is this appropriate for all content types?
                xhr.setRequestHeader("Content-Type", args.contentType || _defaultContentType);
                if(!args.headers || !("X-Requested-With" in args.headers)){
                        xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
                }
                // FIXME: set other headers here!
                _d._ioNotifyStart(dfd);
                if(dojo.config.debugAtAllCosts){
                        xhr.send(ioArgs.query);
                }else{
                        try{
                                xhr.send(ioArgs.query);
                        }catch(e){
                                ioArgs.error = e;
                                dfd.cancel();
                        }
                }
                _d._ioWatch(dfd, _validCheck, _ioCheck, _resHandle);
                xhr = null;
                return dfd; // dojo.Deferred
        };

        dojo.xhrGet = function(/*dojo.__XhrArgs*/ args){
                //      summary:
                //              Sends an HTTP GET request to the server.
                return _d.xhr("GET", args); // dojo.Deferred
        };

        dojo.rawXhrPost = dojo.xhrPost = function(/*dojo.__XhrArgs*/ args){
                //      summary:
                //              Sends an HTTP POST request to the server. In addtion to the properties
                //              listed for the dojo.__XhrArgs type, the following property is allowed:
                //      postData:
                //              String. Send raw data in the body of the POST request.
                return _d.xhr("POST", args, true); // dojo.Deferred
        };

        dojo.rawXhrPut = dojo.xhrPut = function(/*dojo.__XhrArgs*/ args){
                //      summary:
                //              Sends an HTTP PUT request to the server. In addtion to the properties
                //              listed for the dojo.__XhrArgs type, the following property is allowed:
                //      putData:
                //              String. Send raw data in the body of the PUT request.
                return _d.xhr("PUT", args, true); // dojo.Deferred
        };

        dojo.xhrDelete = function(/*dojo.__XhrArgs*/ args){
                //      summary:
                //              Sends an HTTP DELETE request to the server.
                return _d.xhr("DELETE", args); //dojo.Deferred
        };

        /*
        dojo.wrapForm = function(formNode){
                //summary:
                //              A replacement for FormBind, but not implemented yet.

                // FIXME: need to think harder about what extensions to this we might
                // want. What should we allow folks to do w/ this? What events to
                // set/send?
                throw new Error("dojo.wrapForm not yet implemented");
        }
        */
})();

}

if(!dojo._hasResource["dojo._base.fx"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.fx"] = true;
dojo.provide("dojo._base.fx");






/*
        Animation loosely package based on Dan Pupius' work, contributed under CLA:
                http://pupius.co.uk/js/Toolkit.Drawing.js
*/
(function(){
        var d = dojo;
        var _mixin = d._mixin;

        dojo._Line = function(/*int*/ start, /*int*/ end){
                //      summary:
                //              dojo._Line is the object used to generate values from a start value
                //              to an end value
                //      start: int
                //              Beginning value for range
                //      end: int
                //              Ending value for range
                this.start = start;
                this.end = end;
        };

        dojo._Line.prototype.getValue = function(/*float*/ n){
                //      summary: Returns the point on the line
                //      n: a floating point number greater than 0 and less than 1
                return ((this.end - this.start) * n) + this.start; // Decimal
        };

        dojo.Animation = function(args){
                //      summary:
                //              A generic animation class that fires callbacks into its handlers
                //              object at various states.
                //      description:
                //              A generic animation class that fires callbacks into its handlers
                //              object at various states. Nearly all dojo animation functions
                //              return an instance of this method, usually without calling the
                //              .play() method beforehand. Therefore, you will likely need to
                //              call .play() on instances of `dojo.Animation` when one is
                //              returned.
                // args: Object
                //              The 'magic argument', mixing all the properties into this
                //              animation instance.

                _mixin(this, args);
                if(d.isArray(this.curve)){
                        this.curve = new d._Line(this.curve[0], this.curve[1]);
                }

        };

        // Alias to drop come 2.0:
        d._Animation = d.Animation;

        d.extend(dojo.Animation, {
                // duration: Integer
                //              The time in milliseonds the animation will take to run
                duration: 350,

        /*=====
                // curve: dojo._Line|Array
                //              A two element array of start and end values, or a `dojo._Line` instance to be
                //              used in the Animation.
                curve: null,

                // easing: Function?
                //              A Function to adjust the acceleration (or deceleration) of the progress
                //              across a dojo._Line
                easing: null,
        =====*/

                // repeat: Integer?
                //              The number of times to loop the animation
                repeat: 0,

                // rate: Integer?
                //              the time in milliseconds to wait before advancing to next frame
                //              (used as a fps timer: 1000/rate = fps)
                rate: 20 /* 50 fps */,

        /*=====
                // delay: Integer?
                //              The time in milliseconds to wait before starting animation after it
                //              has been .play()'ed
                delay: null,

                // beforeBegin: Event?
                //              Synthetic event fired before a dojo.Animation begins playing (synchronous)
                beforeBegin: null,

                // onBegin: Event?
                //              Synthetic event fired as a dojo.Animation begins playing (useful?)
                onBegin: null,

                // onAnimate: Event?
                //              Synthetic event fired at each interval of a `dojo.Animation`
                onAnimate: null,

                // onEnd: Event?
                //              Synthetic event fired after the final frame of a `dojo.Animation`
                onEnd: null,

                // onPlay: Event?
                //              Synthetic event fired any time a `dojo.Animation` is play()'ed
                onPlay: null,

                // onPause: Event?
                //              Synthetic event fired when a `dojo.Animation` is paused
                onPause: null,

                // onStop: Event
                //              Synthetic event fires when a `dojo.Animation` is stopped
                onStop: null,

        =====*/

                _percent: 0,
                _startRepeatCount: 0,

                _getStep: function(){
                        var _p = this._percent,
                                _e = this.easing
                        ;
                        return _e ? _e(_p) : _p;
                },
                _fire: function(/*Event*/ evt, /*Array?*/ args){
                        //      summary:
                        //              Convenience function.  Fire event "evt" and pass it the
                        //              arguments specified in "args".
                        //      description:
                        //              Convenience function.  Fire event "evt" and pass it the
                        //              arguments specified in "args".
                        //              Fires the callback in the scope of the `dojo.Animation`
                        //              instance.
                        //      evt:
                        //              The event to fire.
                        //      args:
                        //              The arguments to pass to the event.
                        var a = args||[];
                        if(this[evt]){
                                if(d.config.debugAtAllCosts){
                                        this[evt].apply(this, a);
                                }else{
                                        try{
                                                this[evt].apply(this, a);
                                        }catch(e){
                                                // squelch and log because we shouldn't allow exceptions in
                                                // synthetic event handlers to cause the internal timer to run
                                                // amuck, potentially pegging the CPU. I'm not a fan of this
                                                // squelch, but hopefully logging will make it clear what's
                                                // going on
                                                console.error("exception in animation handler for:", evt);
                                                console.error(e);
                                        }
                                }
                        }
                        return this; // dojo.Animation
                },

                play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
                        // summary:
                        //              Start the animation.
                        // delay:
                        //              How many milliseconds to delay before starting.
                        // gotoStart:
                        //              If true, starts the animation from the beginning; otherwise,
                        //              starts it from its current position.
                        // returns: dojo.Animation
                        //              The instance to allow chaining.

                        var _t = this;
                        if(_t._delayTimer){ _t._clearTimer(); }
                        if(gotoStart){
                                _t._stopTimer();
                                _t._active = _t._paused = false;
                                _t._percent = 0;
                        }else if(_t._active && !_t._paused){
                                return _t;
                        }

                        _t._fire("beforeBegin", [_t.node]);

                        var de = delay || _t.delay,
                                _p = dojo.hitch(_t, "_play", gotoStart);

                        if(de > 0){
                                _t._delayTimer = setTimeout(_p, de);
                                return _t;
                        }
                        _p();
                        return _t;
                },

                _play: function(gotoStart){
                        var _t = this;
                        if(_t._delayTimer){ _t._clearTimer(); }
                        _t._startTime = new Date().valueOf();
                        if(_t._paused){
                                _t._startTime -= _t.duration * _t._percent;
                        }

                        _t._active = true;
                        _t._paused = false;
                        var value = _t.curve.getValue(_t._getStep());
                        if(!_t._percent){
                                if(!_t._startRepeatCount){
                                        _t._startRepeatCount = _t.repeat;
                                }
                                _t._fire("onBegin", [value]);
                        }

                        _t._fire("onPlay", [value]);

                        _t._cycle();
                        return _t; // dojo.Animation
                },

                pause: function(){
                        // summary: Pauses a running animation.
                        var _t = this;
                        if(_t._delayTimer){ _t._clearTimer(); }
                        _t._stopTimer();
                        if(!_t._active){ return _t; /*dojo.Animation*/ }
                        _t._paused = true;
                        _t._fire("onPause", [_t.curve.getValue(_t._getStep())]);
                        return _t; // dojo.Animation
                },

                gotoPercent: function(/*Decimal*/ percent, /*Boolean?*/ andPlay){
                        //      summary:
                        //              Sets the progress of the animation.
                        //      percent:
                        //              A percentage in decimal notation (between and including 0.0 and 1.0).
                        //      andPlay:
                        //              If true, play the animation after setting the progress.
                        var _t = this;
                        _t._stopTimer();
                        _t._active = _t._paused = true;
                        _t._percent = percent;
                        if(andPlay){ _t.play(); }
                        return _t; // dojo.Animation
                },

                stop: function(/*boolean?*/ gotoEnd){
                        // summary: Stops a running animation.
                        // gotoEnd: If true, the animation will end.
                        var _t = this;
                        if(_t._delayTimer){ _t._clearTimer(); }
                        if(!_t._timer){ return _t; /* dojo.Animation */ }
                        _t._stopTimer();
                        if(gotoEnd){
                                _t._percent = 1;
                        }
                        _t._fire("onStop", [_t.curve.getValue(_t._getStep())]);
                        _t._active = _t._paused = false;
                        return _t; // dojo.Animation
                },

                status: function(){
                        // summary:
                        //              Returns a string token representation of the status of
                        //              the animation, one of: "paused", "playing", "stopped"
                        if(this._active){
                                return this._paused ? "paused" : "playing"; // String
                        }
                        return "stopped"; // String
                },

                _cycle: function(){
                        var _t = this;
                        if(_t._active){
                                var curr = new Date().valueOf();
                                var step = (curr - _t._startTime) / (_t.duration);

                                if(step >= 1){
                                        step = 1;
                                }
                                _t._percent = step;

                                // Perform easing
                                if(_t.easing){
                                        step = _t.easing(step);
                                }

                                _t._fire("onAnimate", [_t.curve.getValue(step)]);

                                if(_t._percent < 1){
                                        _t._startTimer();
                                }else{
                                        _t._active = false;

                                        if(_t.repeat > 0){
                                                _t.repeat--;
                                                _t.play(null, true);
                                        }else if(_t.repeat == -1){
                                                _t.play(null, true);
                                        }else{
                                                if(_t._startRepeatCount){
                                                        _t.repeat = _t._startRepeatCount;
                                                        _t._startRepeatCount = 0;
                                                }
                                        }
                                        _t._percent = 0;
                                        _t._fire("onEnd", [_t.node]);
                                        !_t.repeat && _t._stopTimer();
                                }
                        }
                        return _t; // dojo.Animation
                },

                _clearTimer: function(){
                        // summary: Clear the play delay timer
                        clearTimeout(this._delayTimer);
                        delete this._delayTimer;
                }

        });

        // the local timer, stubbed into all Animation instances
        var ctr = 0,
                timer = null,
                runner = {
                        run: function(){}
                };

        d.extend(d.Animation, {

                _startTimer: function(){
                        if(!this._timer){
                                this._timer = d.connect(runner, "run", this, "_cycle");
                                ctr++;
                        }
                        if(!timer){
                                timer = setInterval(d.hitch(runner, "run"), this.rate);
                        }
                },

                _stopTimer: function(){
                        if(this._timer){
                                d.disconnect(this._timer);
                                this._timer = null;
                                ctr--;
                        }
                        if(ctr <= 0){
                                clearInterval(timer);
                                timer = null;
                                ctr = 0;
                        }
                }

        });

        var _makeFadeable =
                                d.isIE ? function(node){
                        // only set the zoom if the "tickle" value would be the same as the
                        // default
                        var ns = node.style;
                        // don't set the width to auto if it didn't already cascade that way.
                        // We don't want to f anyones designs
                        if(!ns.width.length && d.style(node, "width") == "auto"){
                                ns.width = "auto";
                        }
                } :
                                function(){};

        dojo._fade = function(/*Object*/ args){
                //      summary:
                //              Returns an animation that will fade the node defined by
                //              args.node from the start to end values passed (args.start
                //              args.end) (end is mandatory, start is optional)

                args.node = d.byId(args.node);
                var fArgs = _mixin({ properties: {} }, args),
                        props = (fArgs.properties.opacity = {});

                props.start = !("start" in fArgs) ?
                        function(){
                                return +d.style(fArgs.node, "opacity")||0;
                        } : fArgs.start;
                props.end = fArgs.end;

                var anim = d.animateProperty(fArgs);
                d.connect(anim, "beforeBegin", d.partial(_makeFadeable, fArgs.node));

                return anim; // dojo.Animation
        };

        /*=====
        dojo.__FadeArgs = function(node, duration, easing){
                //      node: DOMNode|String
                //              The node referenced in the animation
                //      duration: Integer?
                //              Duration of the animation in milliseconds.
                //      easing: Function?
                //              An easing function.
                this.node = node;
                this.duration = duration;
                this.easing = easing;
        }
        =====*/

        dojo.fadeIn = function(/*dojo.__FadeArgs*/ args){
                // summary:
                //              Returns an animation that will fade node defined in 'args' from
                //              its current opacity to fully opaque.
                return d._fade(_mixin({ end: 1 }, args)); // dojo.Animation
        };

        dojo.fadeOut = function(/*dojo.__FadeArgs*/  args){
                // summary:
                //              Returns an animation that will fade node defined in 'args'
                //              from its current opacity to fully transparent.
                return d._fade(_mixin({ end: 0 }, args)); // dojo.Animation
        };

        dojo._defaultEasing = function(/*Decimal?*/ n){
                // summary: The default easing function for dojo.Animation(s)
                return 0.5 + ((Math.sin((n + 1.5) * Math.PI)) / 2);
        };

        var PropLine = function(properties){
                // PropLine is an internal class which is used to model the values of
                // an a group of CSS properties across an animation lifecycle. In
                // particular, the "getValue" function handles getting interpolated
                // values between start and end for a particular CSS value.
                this._properties = properties;
                for(var p in properties){
                        var prop = properties[p];
                        if(prop.start instanceof d.Color){
                                // create a reusable temp color object to keep intermediate results
                                prop.tempColor = new d.Color();
                        }
                }
        };

        PropLine.prototype.getValue = function(r){
                var ret = {};
                for(var p in this._properties){
                        var prop = this._properties[p],
                                start = prop.start;
                        if(start instanceof d.Color){
                                ret[p] = d.blendColors(start, prop.end, r, prop.tempColor).toCss();
                        }else if(!d.isArray(start)){
                                ret[p] = ((prop.end - start) * r) + start + (p != "opacity" ? prop.units || "px" : 0);
                        }
                }
                return ret;
        };

        /*=====
        dojo.declare("dojo.__AnimArgs", [dojo.__FadeArgs], {
                // Properties: Object?
                //      A hash map of style properties to Objects describing the transition,
                //      such as the properties of dojo._Line with an additional 'units' property
                properties: {}

                //TODOC: add event callbacks
        });
        =====*/

        dojo.animateProperty = function(/*dojo.__AnimArgs*/ args){
                // summary:
                //              Returns an animation that will transition the properties of
                //              node defined in `args` depending how they are defined in
                //              `args.properties`
                //
                // description:
                //              `dojo.animateProperty` is the foundation of most `dojo.fx`
                //              animations. It takes an object of "properties" corresponding to
                //              style properties, and animates them in parallel over a set
                //              duration.
                //
                // example:
                //              A simple animation that changes the width of the specified node.
                //      |       dojo.animateProperty({
                //      |               node: "nodeId",
                //      |               properties: { width: 400 },
                //      |       }).play();
                //              Dojo figures out the start value for the width and converts the
                //              integer specified for the width to the more expressive but
                //              verbose form `{ width: { end: '400', units: 'px' } }` which you
                //              can also specify directly. Defaults to 'px' if ommitted.
                //
                // example:
                //              Animate width, height, and padding over 2 seconds... the
                //              pedantic way:
                //      |       dojo.animateProperty({ node: node, duration:2000,
                //      |               properties: {
                //      |                       width: { start: '200', end: '400', units:"px" },
                //      |                       height: { start:'200', end: '400', units:"px" },
                //      |                       paddingTop: { start:'5', end:'50', units:"px" }
                //      |               }
                //      |       }).play();
                //              Note 'paddingTop' is used over 'padding-top'. Multi-name CSS properties
                //              are written using "mixed case", as the hyphen is illegal as an object key.
                //
                // example:
                //              Plug in a different easing function and register a callback for
                //              when the animation ends. Easing functions accept values between
                //              zero and one and return a value on that basis. In this case, an
                //              exponential-in curve.
                //      |       dojo.animateProperty({
                //      |               node: "nodeId",
                //      |               // dojo figures out the start value
                //      |               properties: { width: { end: 400 } },
                //      |               easing: function(n){
                //      |                       return (n==0) ? 0 : Math.pow(2, 10 * (n - 1));
                //      |               },
                //      |               onEnd: function(node){
                //      |                       // called when the animation finishes. The animation
                //      |                       // target is passed to this function
                //      |               }
                //      |       }).play(500); // delay playing half a second
                //
                // example:
                //              Like all `dojo.Animation`s, animateProperty returns a handle to the
                //              Animation instance, which fires the events common to Dojo FX. Use `dojo.connect`
                //              to access these events outside of the Animation definiton:
                //      |       var anim = dojo.animateProperty({
                //      |               node:"someId",
                //      |               properties:{
                //      |                       width:400, height:500
                //      |               }
                //      |       });
                //      |       dojo.connect(anim,"onEnd", function(){
                //      |               console.log("animation ended");
                //      |       });
                //      |       // play the animation now:
                //      |       anim.play();
                //
                // example:
                //              Each property can be a function whose return value is substituted along.
                //              Additionally, each measurement (eg: start, end) can be a function. The node
                //              reference is passed direcly to callbacks.
                //      |       dojo.animateProperty({
                //      |               node:"mine",
                //      |               properties:{
                //      |                       height:function(node){
                //      |                               // shrink this node by 50%
                //      |                               return dojo.position(node).h / 2
                //      |                       },
                //      |                       width:{
                //      |                               start:function(node){ return 100; },
                //      |                               end:function(node){ return 200; }
                //      |                       }
                //      |               }
                //      |       }).play();
                //

                var n = args.node = d.byId(args.node);
                if(!args.easing){ args.easing = d._defaultEasing; }

                var anim = new d.Animation(args);
                d.connect(anim, "beforeBegin", anim, function(){
                        var pm = {};
                        for(var p in this.properties){
                                // Make shallow copy of properties into pm because we overwrite
                                // some values below. In particular if start/end are functions
                                // we don't want to overwrite them or the functions won't be
                                // called if the animation is reused.
                                if(p == "width" || p == "height"){
                                        this.node.display = "block";
                                }
                                var prop = this.properties[p];
                                if(d.isFunction(prop)){
                                        prop = prop(n);
                                }
                                prop = pm[p] = _mixin({}, (d.isObject(prop) ? prop: { end: prop }));

                                if(d.isFunction(prop.start)){
                                        prop.start = prop.start(n);
                                }
                                if(d.isFunction(prop.end)){
                                        prop.end = prop.end(n);
                                }
                                var isColor = (p.toLowerCase().indexOf("color") >= 0);
                                function getStyle(node, p){
                                        // dojo.style(node, "height") can return "auto" or "" on IE; this is more reliable:
                                        var v = { height: node.offsetHeight, width: node.offsetWidth }[p];
                                        if(v !== undefined){ return v; }
                                        v = d.style(node, p);
                                        return (p == "opacity") ? +v : (isColor ? v : parseFloat(v));
                                }
                                if(!("end" in prop)){
                                        prop.end = getStyle(n, p);
                                }else if(!("start" in prop)){
                                        prop.start = getStyle(n, p);
                                }

                                if(isColor){
                                        prop.start = new d.Color(prop.start);
                                        prop.end = new d.Color(prop.end);
                                }else{
                                        prop.start = (p == "opacity") ? +prop.start : parseFloat(prop.start);
                                }
                        }
                        this.curve = new PropLine(pm);
                });
                d.connect(anim, "onAnimate", d.hitch(d, "style", anim.node));
                return anim; // dojo.Animation
        };

        dojo.anim = function(   /*DOMNode|String*/      node,
                                                        /*Object*/                      properties,
                                                        /*Integer?*/            duration,
                                                        /*Function?*/           easing,
                                                        /*Function?*/           onEnd,
                                                        /*Integer?*/            delay){
                //      summary:
                //              A simpler interface to `dojo.animateProperty()`, also returns
                //              an instance of `dojo.Animation` but begins the animation
                //              immediately, unlike nearly every other Dojo animation API.
                //      description:
                //              `dojo.anim` is a simpler (but somewhat less powerful) version
                //              of `dojo.animateProperty`.  It uses defaults for many basic properties
                //              and allows for positional parameters to be used in place of the
                //              packed "property bag" which is used for other Dojo animation
                //              methods.
                //
                //              The `dojo.Animation` object returned from `dojo.anim` will be
                //              already playing when it is returned from this function, so
                //              calling play() on it again is (usually) a no-op.
                //      node:
                //              a DOM node or the id of a node to animate CSS properties on
                //      duration:
                //              The number of milliseconds over which the animation
                //              should run. Defaults to the global animation default duration
                //              (350ms).
                //      easing:
                //              An easing function over which to calculate acceleration
                //              and deceleration of the animation through its duration.
                //              A default easing algorithm is provided, but you may
                //              plug in any you wish. A large selection of easing algorithms
                //              are available in `dojo.fx.easing`.
                //      onEnd:
                //              A function to be called when the animation finishes
                //              running.
                //      delay:
                //              The number of milliseconds to delay beginning the
                //              animation by. The default is 0.
                //      example:
                //              Fade out a node
                //      |       dojo.anim("id", { opacity: 0 });
                //      example:
                //              Fade out a node over a full second
                //      |       dojo.anim("id", { opacity: 0 }, 1000);
                return d.animateProperty({ // dojo.Animation
                        node: node,
                        duration: duration || d.Animation.prototype.duration,
                        properties: properties,
                        easing: easing,
                        onEnd: onEnd
                }).play(delay || 0);
        };
})();

}

if(!dojo._hasResource["dojo._base.browser"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.browser"] = true;
dojo.provide("dojo._base.browser");









        //Need this to be the last code segment in base, so do not place any
        //dojo/requireIf calls in this file/ Otherwise, due to how the build system
        //puts all requireIf dependencies after the current file, the require calls
        //could be called before all of base is defined/
        dojo.forEach(dojo.config.require, function(i){
                dojo["require"](i);
        });

}

if(!dojo._hasResource["dojo._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base"] = true;
dojo.provide("dojo._base");











}

        //INSERT dojo.i18n._preloadLocalizations HERE

        //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, set djConfig.afterOnLoad = true when you know Dojo is added
        //after page load. Using a timeout so the rest of this
        //script gets evaluated properly. This work needs to happen after the
        //dojo.config.require work done in dojo._base.
        if(dojo.isBrowser && (document.readyState === "complete" || dojo.config.afterOnLoad)){
                window.setTimeout(dojo._loadInit, 100);
        }
})();

