[PerformanceTests] Each Dromaeo test needs its landing html.
[WebKit-https.git] / PerformanceTests / Dromaeo / resources / dromaeo / web / lib / dojo-1.6.1.js
1 /*
2         Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
3         Available via Academic Free License >= 2.1 OR the modified BSD license.
4         see: http://dojotoolkit.org/license for details
5 */
6
7 /*
8         This is an optimized version of Dojo, built for deployment and not for
9         development. To get sources and documentation, please visit:
10
11                 http://dojotoolkit.org
12 */
13
14 ;(function(){
15
16         /*
17         dojo, dijit, and dojox must always be the first three, and in that order.
18         djConfig.scopeMap = [
19                 ["dojo", "fojo"],
20                 ["dijit", "fijit"],
21                 ["dojox", "fojox"]
22         
23         ]
24         */
25
26         /**Build will replace this comment with a scoped djConfig **/
27
28         //The null below can be relaced by a build-time value used instead of djConfig.scopeMap.
29         var sMap = null;
30
31         //See if new scopes need to be defined.
32         if((sMap || (typeof djConfig != "undefined" && djConfig.scopeMap)) && (typeof window != "undefined")){
33                 var scopeDef = "", scopePrefix = "", scopeSuffix = "", scopeMap = {}, scopeMapRev = {};
34                 sMap = sMap || djConfig.scopeMap;
35                 for(var i = 0; i < sMap.length; i++){
36                         //Make local variables, then global variables that use the locals.
37                         var newScope = sMap[i];
38                         scopeDef += "var " + newScope[0] + " = {}; " + newScope[1] + " = " + newScope[0] + ";" + newScope[1] + "._scopeName = '" + newScope[1] + "';";
39                         scopePrefix += (i == 0 ? "" : ",") + newScope[0];
40                         scopeSuffix += (i == 0 ? "" : ",") + newScope[1];
41                         scopeMap[newScope[0]] = newScope[1];
42                         scopeMapRev[newScope[1]] = newScope[0];
43                 }
44
45                 eval(scopeDef + "dojo._scopeArgs = [" + scopeSuffix + "];");
46
47                 dojo._scopePrefixArgs = scopePrefix;
48                 dojo._scopePrefix = "(function(" + scopePrefix + "){";
49                 dojo._scopeSuffix = "})(" + scopeSuffix + ")";
50                 dojo._scopeMap = scopeMap;
51                 dojo._scopeMapRev = scopeMapRev;
52         }
53
54 /*=====
55 // note:
56 //              'djConfig' does not exist under 'dojo.*' so that it can be set before the
57 //              'dojo' variable exists.
58 // note:
59 //              Setting any of these variables *after* the library has loaded does
60 //              nothing at all.
61
62 djConfig = {
63         // summary:
64         //              Application code can set the global 'djConfig' prior to loading
65         //              the library to override certain global settings for how dojo works.
66         //
67         // isDebug: Boolean
68         //              Defaults to `false`. If set to `true`, ensures that Dojo provides
69         //              extended debugging feedback via Firebug. If Firebug is not available
70         //              on your platform, setting `isDebug` to `true` will force Dojo to
71         //              pull in (and display) the version of Firebug Lite which is
72         //              integrated into the Dojo distribution, thereby always providing a
73         //              debugging/logging console when `isDebug` is enabled. Note that
74         //              Firebug's `console.*` methods are ALWAYS defined by Dojo. If
75         //              `isDebug` is false and you are on a platform without Firebug, these
76         //              methods will be defined as no-ops.
77         isDebug: false,
78         // debugAtAllCosts: Boolean
79         //              Defaults to `false`. If set to `true`, this triggers an alternate
80         //              mode of the package system in which dependencies are detected and
81         //              only then are resources evaluated in dependency order via
82         //              `<script>` tag inclusion. This may double-request resources and
83         //              cause problems with scripts which expect `dojo.require()` to
84         //              preform synchronously. `debugAtAllCosts` can be an invaluable
85         //              debugging aid, but when using it, ensure that all code which
86         //              depends on Dojo modules is wrapped in `dojo.addOnLoad()` handlers.
87         //              Due to the somewhat unpredictable side-effects of using
88         //              `debugAtAllCosts`, it is strongly recommended that you enable this
89         //              flag as a last resort. `debugAtAllCosts` has no effect when loading
90         //              resources across domains. For usage information, see the
91         //              [Dojo Book](http://dojotoolkit.org/book/book-dojo/part-4-meta-dojo-making-your-dojo-code-run-faster-and-better/debugging-facilities/deb)
92         debugAtAllCosts: false,
93         // locale: String
94         //              The locale to assume for loading localized resources in this page,
95         //              specified according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt).
96         //              Must be specified entirely in lowercase, e.g. `en-us` and `zh-cn`.
97         //              See the documentation for `dojo.i18n` and `dojo.requireLocalization`
98         //              for details on loading localized resources. If no locale is specified,
99         //              Dojo assumes the locale of the user agent, according to `navigator.userLanguage`
100         //              or `navigator.language` properties.
101         locale: undefined,
102         // extraLocale: Array
103         //              No default value. Specifies additional locales whose
104         //              resources should also be loaded alongside the default locale when
105         //              calls to `dojo.requireLocalization()` are processed.
106         extraLocale: undefined,
107         // baseUrl: String
108         //              The directory in which `dojo.js` is located. Under normal
109         //              conditions, Dojo auto-detects the correct location from which it
110         //              was loaded. You may need to manually configure `baseUrl` in cases
111         //              where you have renamed `dojo.js` or in which `<base>` tags confuse
112         //              some browsers (e.g. IE 6). The variable `dojo.baseUrl` is assigned
113         //              either the value of `djConfig.baseUrl` if one is provided or the
114         //              auto-detected root if not. Other modules are located relative to
115         //              this path. The path should end in a slash.
116         baseUrl: undefined,
117         // modulePaths: Object
118         //              A map of module names to paths relative to `dojo.baseUrl`. The
119         //              key/value pairs correspond directly to the arguments which
120         //              `dojo.registerModulePath` accepts. Specifiying
121         //              `djConfig.modulePaths = { "foo": "../../bar" }` is the equivalent
122         //              of calling `dojo.registerModulePath("foo", "../../bar");`. Multiple
123         //              modules may be configured via `djConfig.modulePaths`.
124         modulePaths: {},
125         // afterOnLoad: Boolean
126         //              Indicates Dojo was added to the page after the page load. In this case
127         //              Dojo will not wait for the page DOMContentLoad/load events and fire
128         //              its dojo.addOnLoad callbacks after making sure all outstanding
129         //              dojo.required modules have loaded. Only works with a built dojo.js,
130         //              it does not work the dojo.js directly from source control.
131         afterOnLoad: false,
132         // addOnLoad: Function or Array
133         //              Adds a callback via dojo.addOnLoad. Useful when Dojo is added after
134         //              the page loads and djConfig.afterOnLoad is true. Supports the same
135         //              arguments as dojo.addOnLoad. When using a function reference, use
136         //              `djConfig.addOnLoad = function(){};`. For object with function name use
137         //              `djConfig.addOnLoad = [myObject, "functionName"];` and for object with
138         //              function reference use
139         //              `djConfig.addOnLoad = [myObject, function(){}];`
140         addOnLoad: null,
141         // require: Array
142         //              An array of module names to be loaded immediately after dojo.js has been included
143         //              in a page.
144         require: [],
145         // defaultDuration: Array
146         //              Default duration, in milliseconds, for wipe and fade animations within dijits.
147         //              Assigned to dijit.defaultDuration.
148         defaultDuration: 200,
149         // dojoBlankHtmlUrl: String
150         //              Used by some modules to configure an empty iframe. Used by dojo.io.iframe and
151         //              dojo.back, and dijit popup support in IE where an iframe is needed to make sure native
152         //              controls do not bleed through the popups. Normally this configuration variable
153         //              does not need to be set, except when using cross-domain/CDN Dojo builds.
154         //              Save dojo/resources/blank.html to your domain and set `djConfig.dojoBlankHtmlUrl`
155         //              to the path on your domain your copy of blank.html.
156         dojoBlankHtmlUrl: undefined,
157         //      ioPublish: Boolean?
158         //              Set this to true to enable publishing of topics for the different phases of
159         //              IO operations. Publishing is done via dojo.publish. See dojo.__IoPublish for a list
160         //              of topics that are published.
161         ioPublish: false,
162         //  useCustomLogger: Anything?
163         //              If set to a value that evaluates to true such as a string or array and
164         //              isDebug is true and Firebug is not available or running, then it bypasses
165         //              the creation of Firebug Lite allowing you to define your own console object.
166         useCustomLogger: undefined,
167         // transparentColor: Array
168         //              Array containing the r, g, b components used as transparent color in dojo.Color;
169         //              if undefined, [255,255,255] (white) will be used.
170         transparentColor: undefined,
171         // skipIeDomLoaded: Boolean
172         //              For IE only, skip the DOMContentLoaded hack used. Sometimes it can cause an Operation
173         //              Aborted error if the rest of the page triggers script defers before the DOM is ready.
174         //              If this is config value is set to true, then dojo.addOnLoad callbacks will not be
175         //              triggered until the page load event, which is after images and iframes load. If you
176         //              want to trigger the callbacks sooner, you can put a script block in the bottom of
177         //              your HTML that calls dojo._loadInit();. If you are using multiversion support, change
178         //              "dojo." to the appropriate scope name for dojo.
179         skipIeDomLoaded: false
180 }
181 =====*/
182
183 (function(){
184         // firebug stubs
185
186         if(typeof this["loadFirebugConsole"] == "function"){
187                 // for Firebug 1.2
188                 this["loadFirebugConsole"]();
189         }else{
190                 this.console = this.console || {};
191
192                 //      Be careful to leave 'log' always at the end
193                 var cn = [
194                         "assert", "count", "debug", "dir", "dirxml", "error", "group",
195                         "groupEnd", "info", "profile", "profileEnd", "time", "timeEnd",
196                         "trace", "warn", "log"
197                 ];
198                 var i = 0, tn;
199                 while((tn=cn[i++])){
200                         if(!console[tn]){
201                                 (function(){
202                                         var tcn = tn+"";
203                                         console[tcn] = ('log' in console) ? function(){
204                                                 var a = Array.apply({}, arguments);
205                                                 a.unshift(tcn+":");
206                                                 console["log"](a.join(" "));
207                                         } : function(){}
208                                         console[tcn]._fake = true;
209                                 })();
210                         }
211                 }
212         }
213
214         //TODOC:  HOW TO DOC THIS?
215         // dojo is the root variable of (almost all) our public symbols -- make sure it is defined.
216         if(typeof dojo == "undefined"){
217                 dojo = {
218                         _scopeName: "dojo",
219                         _scopePrefix: "",
220                         _scopePrefixArgs: "",
221                         _scopeSuffix: "",
222                         _scopeMap: {},
223                         _scopeMapRev: {}
224                 };
225         }
226
227         var d = dojo;
228
229         //Need placeholders for dijit and dojox for scoping code.
230         if(typeof dijit == "undefined"){
231                 dijit = {_scopeName: "dijit"};
232         }
233         if(typeof dojox == "undefined"){
234                 dojox = {_scopeName: "dojox"};
235         }
236
237         if(!d._scopeArgs){
238                 d._scopeArgs = [dojo, dijit, dojox];
239         }
240
241 /*=====
242 dojo.global = {
243         //      summary:
244         //              Alias for the global scope
245         //              (e.g. the window object in a browser).
246         //      description:
247         //              Refer to 'dojo.global' rather than referring to window to ensure your
248         //              code runs correctly in contexts other than web browsers (e.g. Rhino on a server).
249 }
250 =====*/
251         d.global = this;
252
253         d.config =/*===== djConfig = =====*/{
254                 isDebug: false,
255                 debugAtAllCosts: false
256         };
257
258         // FIXME: 2.0, drop djConfig support. Use dojoConfig exclusively for global config.
259         var cfg = typeof djConfig != "undefined" ? djConfig :
260                 typeof dojoConfig != "undefined" ? dojoConfig : null;
261                 
262         if(cfg){
263                 for(var c in cfg){
264                         d.config[c] = cfg[c];
265                 }
266         }
267
268 /*=====
269         // Override locale setting, if specified
270         dojo.locale = {
271                 // summary: the locale as defined by Dojo (read-only)
272         };
273 =====*/
274         dojo.locale = d.config.locale;
275
276         var rev = "$Rev: 24595 $".match(/\d+/);
277
278 /*=====
279         dojo.version = function(){
280                 // summary:
281                 //              Version number of the Dojo Toolkit
282                 // major: Integer
283                 //              Major version. If total version is "1.2.0beta1", will be 1
284                 // minor: Integer
285                 //              Minor version. If total version is "1.2.0beta1", will be 2
286                 // patch: Integer
287                 //              Patch version. If total version is "1.2.0beta1", will be 0
288                 // flag: String
289                 //              Descriptor flag. If total version is "1.2.0beta1", will be "beta1"
290                 // revision: Number
291                 //              The SVN rev from which dojo was pulled
292                 this.major = 0;
293                 this.minor = 0;
294                 this.patch = 0;
295                 this.flag = "";
296                 this.revision = 0;
297         }
298 =====*/
299         dojo.version = {
300                 major: 1, minor: 6, patch: 1, flag: "",
301                 revision: rev ? +rev[0] : NaN,
302                 toString: function(){
303                         with(d.version){
304                                 return major + "." + minor + "." + patch + flag + " (" + revision + ")";        // String
305                         }
306                 }
307         }
308
309                 // Register with the OpenAjax hub
310         if(typeof OpenAjax != "undefined"){
311                 OpenAjax.hub.registerLibrary(dojo._scopeName, "http://dojotoolkit.org", d.version.toString());
312         }
313         
314         var extraNames, extraLen, empty = {};
315         for(var i in {toString: 1}){ extraNames = []; break; }
316         dojo._extraNames = extraNames = extraNames || ["hasOwnProperty", "valueOf", "isPrototypeOf",
317                 "propertyIsEnumerable", "toLocaleString", "toString", "constructor"];
318         extraLen = extraNames.length;
319
320         dojo._mixin = function(/*Object*/ target, /*Object*/ source){
321                 // summary:
322                 //              Adds all properties and methods of source to target. This addition
323                 //              is "prototype extension safe", so that instances of objects
324                 //              will not pass along prototype defaults.
325                 var name, s, i;
326                 for(name in source){
327                         // the "tobj" condition avoid copying properties in "source"
328                         // inherited from Object.prototype.  For example, if target has a custom
329                         // toString() method, don't overwrite it with the toString() method
330                         // that source inherited from Object.prototype
331                         s = source[name];
332                         if(!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))){
333                                 target[name] = s;
334                         }
335                 }
336                                 // IE doesn't recognize some custom functions in for..in
337                 if(extraLen && source){
338                         for(i = 0; i < extraLen; ++i){
339                                 name = extraNames[i];
340                                 s = source[name];
341                                 if(!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))){
342                                         target[name] = s;
343                                 }
344                         }
345                 }
346                                 return target; // Object
347         }
348
349         dojo.mixin = function(/*Object*/obj, /*Object...*/props){
350                 // summary:
351                 //              Adds all properties and methods of props to obj and returns the
352                 //              (now modified) obj.
353                 //      description:
354                 //              `dojo.mixin` can mix multiple source objects into a
355                 //              destination object which is then returned. Unlike regular
356                 //              `for...in` iteration, `dojo.mixin` is also smart about avoiding
357                 //              extensions which other toolkits may unwisely add to the root
358                 //              object prototype
359                 //      obj:
360                 //              The object to mix properties into. Also the return value.
361                 //      props:
362                 //              One or more objects whose values are successively copied into
363                 //              obj. If more than one of these objects contain the same value,
364                 //              the one specified last in the function call will "win".
365                 //      example:
366                 //              make a shallow copy of an object
367                 //      |       var copy = dojo.mixin({}, source);
368                 //      example:
369                 //              many class constructors often take an object which specifies
370                 //              values to be configured on the object. In this case, it is
371                 //              often simplest to call `dojo.mixin` on the `this` object:
372                 //      |       dojo.declare("acme.Base", null, {
373                 //      |               constructor: function(properties){
374                 //      |                       // property configuration:
375                 //      |                       dojo.mixin(this, properties);
376                 //      |
377                 //      |                       console.log(this.quip);
378                 //      |                       //  ...
379                 //      |               },
380                 //      |               quip: "I wasn't born yesterday, you know - I've seen movies.",
381                 //      |               // ...
382                 //      |       });
383                 //      |
384                 //      |       // create an instance of the class and configure it
385                 //      |       var b = new acme.Base({quip: "That's what it does!" });
386                 //      example:
387                 //              copy in properties from multiple objects
388                 //      |       var flattened = dojo.mixin(
389                 //      |               {
390                 //      |                       name: "Frylock",
391                 //      |                       braces: true
392                 //      |               },
393                 //      |               {
394                 //      |                       name: "Carl Brutanananadilewski"
395                 //      |               }
396                 //      |       );
397                 //      |
398                 //      |       // will print "Carl Brutanananadilewski"
399                 //      |       console.log(flattened.name);
400                 //      |       // will print "true"
401                 //      |       console.log(flattened.braces);
402                 if(!obj){ obj = {}; }
403                 for(var i=1, l=arguments.length; i<l; i++){
404                         d._mixin(obj, arguments[i]);
405                 }
406                 return obj; // Object
407         }
408
409         dojo._getProp = function(/*Array*/parts, /*Boolean*/create, /*Object*/context){
410                 var obj=context || d.global;
411                 for(var i=0, p; obj && (p=parts[i]); i++){
412                         if(i == 0 && d._scopeMap[p]){
413                                 p = d._scopeMap[p];
414                         }
415                         obj = (p in obj ? obj[p] : (create ? obj[p]={} : undefined));
416                 }
417                 return obj; // mixed
418         }
419
420         dojo.setObject = function(/*String*/name, /*Object*/value, /*Object?*/context){
421                 // summary:
422                 //              Set a property from a dot-separated string, such as "A.B.C"
423                 //      description:
424                 //              Useful for longer api chains where you have to test each object in
425                 //              the chain, or when you have an object reference in string format.
426                 //              Objects are created as needed along `path`. Returns the passed
427                 //              value if setting is successful or `undefined` if not.
428                 //      name:
429                 //              Path to a property, in the form "A.B.C".
430                 //      context:
431                 //              Optional. Object to use as root of path. Defaults to
432                 //              `dojo.global`.
433                 //      example:
434                 //              set the value of `foo.bar.baz`, regardless of whether
435                 //              intermediate objects already exist:
436                 //      |       dojo.setObject("foo.bar.baz", value);
437                 //      example:
438                 //              without `dojo.setObject`, we often see code like this:
439                 //      |       // ensure that intermediate objects are available
440                 //      |       if(!obj["parent"]){ obj.parent = {}; }
441                 //      |       if(!obj.parent["child"]){ obj.parent.child= {}; }
442                 //      |       // now we can safely set the property
443                 //      |       obj.parent.child.prop = "some value";
444                 //              wheras with `dojo.setObject`, we can shorten that to:
445                 //      |       dojo.setObject("parent.child.prop", "some value", obj);
446                 var parts=name.split("."), p=parts.pop(), obj=d._getProp(parts, true, context);
447                 return obj && p ? (obj[p]=value) : undefined; // Object
448         }
449
450         dojo.getObject = function(/*String*/name, /*Boolean?*/create, /*Object?*/context){
451                 // summary:
452                 //              Get a property from a dot-separated string, such as "A.B.C"
453                 //      description:
454                 //              Useful for longer api chains where you have to test each object in
455                 //              the chain, or when you have an object reference in string format.
456                 //      name:
457                 //              Path to an property, in the form "A.B.C".
458                 //      create:
459                 //              Optional. Defaults to `false`. If `true`, Objects will be
460                 //              created at any point along the 'path' that is undefined.
461                 //      context:
462                 //              Optional. Object to use as root of path. Defaults to
463                 //              'dojo.global'. Null may be passed.
464                 return d._getProp(name.split("."), create, context); // Object
465         }
466
467         dojo.exists = function(/*String*/name, /*Object?*/obj){
468                 //      summary:
469                 //              determine if an object supports a given method
470                 //      description:
471                 //              useful for longer api chains where you have to test each object in
472                 //              the chain. Useful for object and method detection.
473                 //      name:
474                 //              Path to an object, in the form "A.B.C".
475                 //      obj:
476                 //              Object to use as root of path. Defaults to
477                 //              'dojo.global'. Null may be passed.
478                 //      example:
479                 //      |       // define an object
480                 //      |       var foo = {
481                 //      |               bar: { }
482                 //      |       };
483                 //      |
484                 //      |       // search the global scope
485                 //      |       dojo.exists("foo.bar"); // true
486                 //      |       dojo.exists("foo.bar.baz"); // false
487                 //      |
488                 //      |       // search from a particular scope
489                 //      |       dojo.exists("bar", foo); // true
490                 //      |       dojo.exists("bar.baz", foo); // false
491                 return d.getObject(name, false, obj) !== undefined; // Boolean
492         }
493
494         dojo["eval"] = function(/*String*/ scriptFragment){
495                 //      summary:
496                 //              A legacy method created for use exclusively by internal Dojo methods. Do not use
497                 //              this method directly, the behavior of this eval will differ from the normal
498                 //              browser eval.
499                 //      description:
500                 //              Placed in a separate function to minimize size of trapped
501                 //              exceptions. Calling eval() directly from some other scope may
502                 //              complicate tracebacks on some platforms.
503                 //      returns:
504                 //              The result of the evaluation. Often `undefined`
505                 return d.global.eval ? d.global.eval(scriptFragment) : eval(scriptFragment);    // Object
506         }
507
508         /*=====
509                 dojo.deprecated = function(behaviour, extra, removal){
510                         //      summary:
511                         //              Log a debug message to indicate that a behavior has been
512                         //              deprecated.
513                         //      behaviour: String
514                         //              The API or behavior being deprecated. Usually in the form
515                         //              of "myApp.someFunction()".
516                         //      extra: String?
517                         //              Text to append to the message. Often provides advice on a
518                         //              new function or facility to achieve the same goal during
519                         //              the deprecation period.
520                         //      removal: String?
521                         //              Text to indicate when in the future the behavior will be
522                         //              removed. Usually a version number.
523                         //      example:
524                         //      |       dojo.deprecated("myApp.getTemp()", "use myApp.getLocaleTemp() instead", "1.0");
525                 }
526
527                 dojo.experimental = function(moduleName, extra){
528                         //      summary: Marks code as experimental.
529                         //      description:
530                         //              This can be used to mark a function, file, or module as
531                         //              experimental.  Experimental code is not ready to be used, and the
532                         //              APIs are subject to change without notice.  Experimental code may be
533                         //              completed deleted without going through the normal deprecation
534                         //              process.
535                         //      moduleName: String
536                         //              The name of a module, or the name of a module file or a specific
537                         //              function
538                         //      extra: String?
539                         //              some additional message for the user
540                         //      example:
541                         //      |       dojo.experimental("dojo.data.Result");
542                         //      example:
543                         //      |       dojo.experimental("dojo.weather.toKelvin()", "PENDING approval from NOAA");
544                 }
545         =====*/
546
547         //Real functions declared in dojo._firebug.firebug.
548         d.deprecated = d.experimental = function(){};
549
550 })();
551 // vim:ai:ts=4:noet
552
553 /*
554  * loader.js - A bootstrap module.  Runs before the hostenv_*.js file. Contains
555  * all of the package loading methods.
556  */
557 (function(){
558         var d = dojo, currentModule;
559
560         d.mixin(d, {
561                 _loadedModules: {},
562                 _inFlightCount: 0,
563                 _hasResource: {},
564
565                 _modulePrefixes: {
566                         dojo:   {       name: "dojo", value: "." },
567                         // dojox:       {       name: "dojox", value: "../dojox" },
568                         // dijit:       {       name: "dijit", value: "../dijit" },
569                         doh:    {       name: "doh", value: "../util/doh" },
570                         tests:  {       name: "tests", value: "tests" }
571                 },
572
573                 _moduleHasPrefix: function(/*String*/module){
574                         // summary: checks to see if module has been established
575                         var mp = d._modulePrefixes;
576                         return !!(mp[module] && mp[module].value); // Boolean
577                 },
578
579                 _getModulePrefix: function(/*String*/module){
580                         // summary: gets the prefix associated with module
581                         var mp = d._modulePrefixes;
582                         if(d._moduleHasPrefix(module)){
583                                 return mp[module].value; // String
584                         }
585                         return module; // String
586                 },
587
588                 _loadedUrls: [],
589
590                 //WARNING:
591                 //              This variable is referenced by packages outside of bootstrap:
592                 //              FloatingPane.js and undo/browser.js
593                 _postLoad: false,
594
595                 //Egad! Lots of test files push on this directly instead of using dojo.addOnLoad.
596                 _loaders: [],
597                 _unloaders: [],
598                 _loadNotifying: false
599         });
600
601
602                 dojo._loadPath = function(/*String*/relpath, /*String?*/module, /*Function?*/cb){
603                 //      summary:
604                 //              Load a Javascript module given a relative path
605                 //
606                 //      description:
607                 //              Loads and interprets the script located at relpath, which is
608                 //              relative to the script root directory.  If the script is found but
609                 //              its interpretation causes a runtime exception, that exception is
610                 //              not caught by us, so the caller will see it.  We return a true
611                 //              value if and only if the script is found.
612                 //
613                 // relpath:
614                 //              A relative path to a script (no leading '/', and typically ending
615                 //              in '.js').
616                 // module:
617                 //              A module whose existance to check for after loading a path.  Can be
618                 //              used to determine success or failure of the load.
619                 // cb:
620                 //              a callback function to pass the result of evaluating the script
621
622                 var uri = ((relpath.charAt(0) == '/' || relpath.match(/^\w+:/)) ? "" : d.baseUrl) + relpath;
623                 try{
624                         currentModule = module;
625                         return !module ? d._loadUri(uri, cb) : d._loadUriAndCheck(uri, module, cb); // Boolean
626                 }catch(e){
627                         console.error(e);
628                         return false; // Boolean
629                 }finally{
630                         currentModule = null;
631                 }
632         }
633
634         dojo._loadUri = function(/*String*/uri, /*Function?*/cb){
635                 //      summary:
636                 //              Loads JavaScript from a URI
637                 //      description:
638                 //              Reads the contents of the URI, and evaluates the contents.  This is
639                 //              used to load modules as well as resource bundles. Returns true if
640                 //              it succeeded. Returns false if the URI reading failed.  Throws if
641                 //              the evaluation throws.
642                 //      uri: a uri which points at the script to be loaded
643                 //      cb:
644                 //              a callback function to process the result of evaluating the script
645                 //              as an expression, typically used by the resource bundle loader to
646                 //              load JSON-style resources
647
648                 if(d._loadedUrls[uri]){
649                         return true; // Boolean
650                 }
651                 d._inFlightCount++; // block addOnLoad calls that arrive while we're busy downloading
652                 var contents = d._getText(uri, true);
653                 if(contents){ // not 404, et al
654                         d._loadedUrls[uri] = true;
655                         d._loadedUrls.push(uri);
656                         if(cb){
657                                 //conditional to support script-inject i18n bundle format
658                                 contents = /^define\(/.test(contents) ? contents : '('+contents+')';
659                         }else{
660                                 //Only do the scoping if no callback. If a callback is specified,
661                                 //it is most likely the i18n bundle stuff.
662                                 contents = d._scopePrefix + contents + d._scopeSuffix;
663                         }
664                         if(!d.isIE){ contents += "\r\n//@ sourceURL=" + uri; } // debugging assist for Firebug
665                         var value = d["eval"](contents);
666                         if(cb){ cb(value); }
667                 }
668                 // Check to see if we need to call _callLoaded() due to an addOnLoad() that arrived while we were busy downloading
669                 if(--d._inFlightCount == 0 && d._postLoad && d._loaders.length){
670                         // We shouldn't be allowed to get here but Firefox allows an event
671                         // (mouse, keybd, async xhrGet) to interrupt a synchronous xhrGet.
672                         // If the current script block contains multiple require() statements, then after each
673                         // require() returns, inFlightCount == 0, but we want to hold the _callLoaded() until
674                         // all require()s are done since the out-of-sequence addOnLoad() presumably needs them all.
675                         // setTimeout allows the next require() to start (if needed), and then we check this again.
676                         setTimeout(function(){
677                                 // If inFlightCount > 0, then multiple require()s are running sequentially and
678                                 // the next require() started after setTimeout() was executed but before we got here.
679                                 if(d._inFlightCount == 0){
680                                         d._callLoaded();
681                                 }
682                         }, 0);
683                 }
684                 return !!contents; // Boolean: contents? true : false
685         }
686         
687         // FIXME: probably need to add logging to this method
688         dojo._loadUriAndCheck = function(/*String*/uri, /*String*/moduleName, /*Function?*/cb){
689                 // summary: calls loadUri then findModule and returns true if both succeed
690                 var ok = false;
691                 try{
692                         ok = d._loadUri(uri, cb);
693                 }catch(e){
694                         console.error("failed loading " + uri + " with error: " + e);
695                 }
696                 return !!(ok && d._loadedModules[moduleName]); // Boolean
697         }
698
699         dojo.loaded = function(){
700                 // summary:
701                 //              signal fired when initial environment and package loading is
702                 //              complete. You should use dojo.addOnLoad() instead of doing a
703                 //              direct dojo.connect() to this method in order to handle
704                 //              initialization tasks that require the environment to be
705                 //              initialized. In a browser host, declarative widgets will
706                 //              be constructed when this function finishes runing.
707                 d._loadNotifying = true;
708                 d._postLoad = true;
709                 var mll = d._loaders;
710
711                 //Clear listeners so new ones can be added
712                 //For other xdomain package loads after the initial load.
713                 d._loaders = [];
714
715                 for(var x = 0; x < mll.length; x++){
716                         mll[x]();
717                 }
718
719                 d._loadNotifying = false;
720                 
721                 //Make sure nothing else got added to the onload queue
722                 //after this first run. If something did, and we are not waiting for any
723                 //more inflight resources, run again.
724                 if(d._postLoad && d._inFlightCount == 0 && mll.length){
725                         d._callLoaded();
726                 }
727         }
728
729         dojo.unloaded = function(){
730                 // summary:
731                 //              signal fired by impending environment destruction. You should use
732                 //              dojo.addOnUnload() instead of doing a direct dojo.connect() to this
733                 //              method to perform page/application cleanup methods. See
734                 //              dojo.addOnUnload for more info.
735                 var mll = d._unloaders;
736                 while(mll.length){
737                         (mll.pop())();
738                 }
739         }
740
741         d._onto = function(arr, obj, fn){
742                 if(!fn){
743                         arr.push(obj);
744                 }else if(fn){
745                         var func = (typeof fn == "string") ? obj[fn] : fn;
746                         arr.push(function(){ func.call(obj); });
747                 }
748         }
749
750         dojo.ready = dojo.addOnLoad = function(/*Object*/obj, /*String|Function?*/functionName){
751                 // summary:
752                 //              Registers a function to be triggered after the DOM and dojo.require() calls
753                 //              have finished loading.
754                 //
755                 // description:
756                 //              Registers a function to be triggered after the DOM has finished
757                 //              loading and `dojo.require` modules have loaded. Widgets declared in markup
758                 //              have been instantiated if `djConfig.parseOnLoad` is true when this fires.
759                 //
760                 //              Images and CSS files may or may not have finished downloading when
761                 //              the specified function is called.  (Note that widgets' CSS and HTML
762                 //              code is guaranteed to be downloaded before said widgets are
763                 //              instantiated, though including css resouces BEFORE any script elements
764                 //              is highly recommended).
765                 //
766                 // example:
767                 //      Register an anonymous function to run when everything is ready
768                 //      |       dojo.addOnLoad(function(){ doStuff(); });
769                 //
770                 // example:
771                 //      Register a function to run when everything is ready by pointer:
772                 //      |       var init = function(){ doStuff(); }
773                 //      |       dojo.addOnLoad(init);
774                 //
775                 // example:
776                 //      Register a function to run scoped to `object`, either by name or anonymously:
777                 //      |       dojo.addOnLoad(object, "functionName");
778                 //      |       dojo.addOnLoad(object, function(){ doStuff(); });
779
780                 d._onto(d._loaders, obj, functionName);
781
782                 //Added for xdomain loading. dojo.addOnLoad is used to
783                 //indicate callbacks after doing some dojo.require() statements.
784                 //In the xdomain case, if all the requires are loaded (after initial
785                 //page load), then immediately call any listeners.
786                 if(d._postLoad && d._inFlightCount == 0 && !d._loadNotifying){
787                         d._callLoaded();
788                 }
789         }
790
791         //Support calling dojo.addOnLoad via djConfig.addOnLoad. Support all the
792         //call permutations of dojo.addOnLoad. Mainly useful when dojo is added
793         //to the page after the page has loaded.
794         var dca = d.config.addOnLoad;
795         if(dca){
796                 d.addOnLoad[(dca instanceof Array ? "apply" : "call")](d, dca);
797         }
798
799         dojo._modulesLoaded = function(){
800                 if(d._postLoad){ return; }
801                 if(d._inFlightCount > 0){
802                         console.warn("files still in flight!");
803                         return;
804                 }
805                 d._callLoaded();
806         }
807
808         dojo._callLoaded = function(){
809
810                 // The "object" check is for IE, and the other opera check fixes an
811                 // issue in Opera where it could not find the body element in some
812                 // widget test cases.  For 0.9, maybe route all browsers through the
813                 // setTimeout (need protection still for non-browser environments
814                 // though). This might also help the issue with FF 2.0 and freezing
815                 // issues where we try to do sync xhr while background css images are
816                 // being loaded (trac #2572)? Consider for 0.9.
817                 if(typeof setTimeout == "object" || (d.config.useXDomain && d.isOpera)){
818                         setTimeout(
819                                 d.isAIR ? function(){ d.loaded(); } : d._scopeName + ".loaded();",
820                                 0);
821                 }else{
822                         d.loaded();
823                 }
824         }
825
826         dojo._getModuleSymbols = function(/*String*/modulename){
827                 // summary:
828                 //              Converts a module name in dotted JS notation to an array
829                 //              representing the path in the source tree
830                 var syms = modulename.split(".");
831                 for(var i = syms.length; i>0; i--){
832                         var parentModule = syms.slice(0, i).join(".");
833                         if(i == 1 && !d._moduleHasPrefix(parentModule)){
834                                 // Support default module directory (sibling of dojo) for top-level modules
835                                 syms[0] = "../" + syms[0];
836                         }else{
837                                 var parentModulePath = d._getModulePrefix(parentModule);
838                                 if(parentModulePath != parentModule){
839                                         syms.splice(0, i, parentModulePath);
840                                         break;
841                                 }
842                         }
843                 }
844                 return syms; // Array
845         }
846
847         dojo._global_omit_module_check = false;
848
849         dojo.loadInit = function(/*Function*/init){
850                 //      summary:
851                 //              Executes a function that needs to be executed for the loader's dojo.requireIf
852                 //              resolutions to work. This is needed mostly for the xdomain loader case where
853                 //              a function needs to be executed to set up the possible values for a dojo.requireIf
854                 //              call.
855                 //      init:
856                 //              a function reference. Executed immediately.
857                 //      description: This function is mainly a marker for the xdomain loader to know parts of
858                 //              code that needs be executed outside the function wrappper that is placed around modules.
859                 //              The init function could be executed more than once, and it should make no assumptions
860                 //              on what is loaded, or what modules are available. Only the functionality in Dojo Base
861                 //              is allowed to be used. Avoid using this method. For a valid use case,
862                 //              see the source for dojox.gfx.
863                 init();
864         }
865
866         dojo._loadModule = dojo.require = function(/*String*/moduleName, /*Boolean?*/omitModuleCheck){
867                 //      summary:
868                 //              loads a Javascript module from the appropriate URI
869                 //
870                 //      moduleName: String
871                 //              module name to load, using periods for separators,
872                 //               e.g. "dojo.date.locale".  Module paths are de-referenced by dojo's
873                 //              internal mapping of locations to names and are disambiguated by
874                 //              longest prefix. See `dojo.registerModulePath()` for details on
875                 //              registering new modules.
876                 //
877                 //      omitModuleCheck: Boolean?
878                 //              if `true`, omitModuleCheck skips the step of ensuring that the
879                 //              loaded file actually defines the symbol it is referenced by.
880                 //              For example if it called as `dojo.require("a.b.c")` and the
881                 //              file located at `a/b/c.js` does not define an object `a.b.c`,
882                 //              and exception will be throws whereas no exception is raised
883                 //              when called as `dojo.require("a.b.c", true)`
884                 //
885                 //      description:
886                 //              Modules are loaded via dojo.require by using one of two loaders: the normal loader
887                 //              and the xdomain loader. The xdomain loader is used when dojo was built with a
888                 //              custom build that specified loader=xdomain and the module lives on a modulePath
889                 //              that is a whole URL, with protocol and a domain. The versions of Dojo that are on
890                 //              the Google and AOL CDNs use the xdomain loader.
891                 //
892                 //              If the module is loaded via the xdomain loader, it is an asynchronous load, since
893                 //              the module is added via a dynamically created script tag. This
894                 //              means that dojo.require() can return before the module has loaded. However, this
895                 //              should only happen in the case where you do dojo.require calls in the top-level
896                 //              HTML page, or if you purposely avoid the loader checking for dojo.require
897                 //              dependencies in your module by using a syntax like dojo["require"] to load the module.
898                 //
899                 //              Sometimes it is useful to not have the loader detect the dojo.require calls in the
900                 //              module so that you can dynamically load the modules as a result of an action on the
901                 //              page, instead of right at module load time.
902                 //
903                 //              Also, for script blocks in an HTML page, the loader does not pre-process them, so
904                 //              it does not know to download the modules before the dojo.require calls occur.
905                 //
906                 //              So, in those two cases, when you want on-the-fly module loading or for script blocks
907                 //              in the HTML page, special care must be taken if the dojo.required code is loaded
908                 //              asynchronously. To make sure you can execute code that depends on the dojo.required
909                 //              modules, be sure to add the code that depends on the modules in a dojo.addOnLoad()
910                 //              callback. dojo.addOnLoad waits for all outstanding modules to finish loading before
911                 //              executing.
912                 //
913                 //              This type of syntax works with both xdomain and normal loaders, so it is good
914                 //              practice to always use this idiom for on-the-fly code loading and in HTML script
915                 //              blocks. If at some point you change loaders and where the code is loaded from,
916                 //              it will all still work.
917                 //
918                 //              More on how dojo.require
919                 //              `dojo.require("A.B")` first checks to see if symbol A.B is
920                 //              defined. If it is, it is simply returned (nothing to do).
921                 //
922                 //              If it is not defined, it will look for `A/B.js` in the script root
923                 //              directory.
924                 //
925                 //              `dojo.require` throws an exception if it cannot find a file
926                 //              to load, or if the symbol `A.B` is not defined after loading.
927                 //
928                 //              It returns the object `A.B`, but note the caveats above about on-the-fly loading and
929                 //              HTML script blocks when the xdomain loader is loading a module.
930                 //
931                 //              `dojo.require()` does nothing about importing symbols into
932                 //              the current namespace.  It is presumed that the caller will
933                 //              take care of that.
934                 //
935                 //      example:
936                 //              To use dojo.require in conjunction with dojo.ready:
937                 //
938                 //              |       dojo.require("foo");
939                 //              |       dojo.require("bar");
940                 //              |       dojo.addOnLoad(function(){
941                 //              |               //you can now safely do something with foo and bar
942                 //              |       });
943                 //
944                 //      example:
945                 //              For example, to import all symbols into a local block, you might write:
946                 //
947                 //              |       with (dojo.require("A.B")) {
948                 //              |               ...
949                 //              |       }
950                 //
951                 //              And to import just the leaf symbol to a local variable:
952                 //
953                 //              |       var B = dojo.require("A.B");
954                 //              |       ...
955                 //
956                 //      returns:
957                 //              the required namespace object
958                 omitModuleCheck = d._global_omit_module_check || omitModuleCheck;
959
960                 //Check if it is already loaded.
961                 var module = d._loadedModules[moduleName];
962                 if(module){
963                         return module;
964                 }
965
966                 // convert periods to slashes
967                 var relpath = d._getModuleSymbols(moduleName).join("/") + '.js';
968                 var modArg = !omitModuleCheck ? moduleName : null;
969                 var ok = d._loadPath(relpath, modArg);
970                 if(!ok && !omitModuleCheck){
971                         throw new Error("Could not load '" + moduleName + "'; last tried '" + relpath + "'");
972                 }
973
974                 // check that the symbol was defined
975                 // Don't bother if we're doing xdomain (asynchronous) loading.
976                 if(!omitModuleCheck && !d._isXDomain){
977                         // pass in false so we can give better error
978                         module = d._loadedModules[moduleName];
979                         if(!module){
980                                 throw new Error("symbol '" + moduleName + "' is not defined after loading '" + relpath + "'");
981                         }
982                 }
983
984                 return module;
985         }
986
987         dojo.provide = function(/*String*/ resourceName){
988                 //      summary:
989                 //              Register a resource with the package system. Works in conjunction with `dojo.require`
990                 //
991                 //      description:
992                 //              Each javascript source file is called a resource.  When a
993                 //              resource is loaded by the browser, `dojo.provide()` registers
994                 //              that it has been loaded.
995                 //
996                 //              Each javascript source file must have at least one
997                 //              `dojo.provide()` call at the top of the file, corresponding to
998                 //              the file name.  For example, `js/dojo/foo.js` must have
999                 //              `dojo.provide("dojo.foo");` before any calls to
1000                 //              `dojo.require()` are made.
1001                 //
1002                 //              For backwards compatibility reasons, in addition to registering
1003                 //              the resource, `dojo.provide()` also ensures that the javascript
1004                 //              object for the module exists.  For example,
1005                 //              `dojo.provide("dojox.data.FlickrStore")`, in addition to
1006                 //              registering that `FlickrStore.js` is a resource for the
1007                 //              `dojox.data` module, will ensure that the `dojox.data`
1008                 //              javascript object exists, so that calls like
1009                 //              `dojo.data.foo = function(){ ... }` don't fail.
1010                 //
1011                 //              In the case of a build where multiple javascript source files
1012                 //              are combined into one bigger file (similar to a .lib or .jar
1013                 //              file), that file may contain multiple dojo.provide() calls, to
1014                 //              note that it includes multiple resources.
1015                 //
1016                 // resourceName: String
1017                 //              A dot-sperated string identifying a resource.
1018                 //
1019                 // example:
1020                 //      Safely create a `my` object, and make dojo.require("my.CustomModule") work
1021                 //      |       dojo.provide("my.CustomModule");
1022
1023                 //Make sure we have a string.
1024                 resourceName = resourceName + "";
1025                 return (d._loadedModules[resourceName] = d.getObject(resourceName, true)); // Object
1026         }
1027
1028         //Start of old bootstrap2:
1029
1030         dojo.platformRequire = function(/*Object*/modMap){
1031                 //      summary:
1032                 //              require one or more modules based on which host environment
1033                 //              Dojo is currently operating in
1034                 //      description:
1035                 //              This method takes a "map" of arrays which one can use to
1036                 //              optionally load dojo modules. The map is indexed by the
1037                 //              possible dojo.name_ values, with two additional values:
1038                 //              "default" and "common". The items in the "default" array will
1039                 //              be loaded if none of the other items have been choosen based on
1040                 //              dojo.name_, set by your host environment. The items in the
1041                 //              "common" array will *always* be loaded, regardless of which
1042                 //              list is chosen.
1043                 //      example:
1044                 //              |       dojo.platformRequire({
1045                 //              |               browser: [
1046                 //              |                       "foo.sample", // simple module
1047                 //              |                       "foo.test",
1048                 //              |                       ["foo.bar.baz", true] // skip object check in _loadModule (dojo.require)
1049                 //              |               ],
1050                 //              |               default: [ "foo.sample._base" ],
1051                 //              |               common: [ "important.module.common" ]
1052                 //              |       });
1053
1054                 var common = modMap.common || [];
1055                 var result = common.concat(modMap[d._name] || modMap["default"] || []);
1056
1057                 for(var x=0; x<result.length; x++){
1058                         var curr = result[x];
1059                         if(curr.constructor == Array){
1060                                 d._loadModule.apply(d, curr);
1061                         }else{
1062                                 d._loadModule(curr);
1063                         }
1064                 }
1065         }
1066
1067         dojo.requireIf = function(/*Boolean*/ condition, /*String*/ resourceName){
1068                 // summary:
1069                 //              If the condition is true then call `dojo.require()` for the specified
1070                 //              resource
1071                 //
1072                 // example:
1073                 //      |       dojo.requireIf(dojo.isBrowser, "my.special.Module");
1074                 
1075                 if(condition === true){
1076                         // FIXME: why do we support chained require()'s here? does the build system?
1077                         var args = [];
1078                         for(var i = 1; i < arguments.length; i++){
1079                                 args.push(arguments[i]);
1080                         }
1081                         d.require.apply(d, args);
1082                 }
1083         }
1084
1085         dojo.requireAfterIf = d.requireIf;
1086
1087         dojo.registerModulePath = function(/*String*/module, /*String*/prefix){
1088                 //      summary:
1089                 //              Maps a module name to a path
1090                 //      description:
1091                 //              An unregistered module is given the default path of ../[module],
1092                 //              relative to Dojo root. For example, module acme is mapped to
1093                 //              ../acme.  If you want to use a different module name, use
1094                 //              dojo.registerModulePath.
1095                 //      example:
1096                 //              If your dojo.js is located at this location in the web root:
1097                 //      |       /myapp/js/dojo/dojo/dojo.js
1098                 //              and your modules are located at:
1099                 //      |       /myapp/js/foo/bar.js
1100                 //      |       /myapp/js/foo/baz.js
1101                 //      |       /myapp/js/foo/thud/xyzzy.js
1102                 //              Your application can tell Dojo to locate the "foo" namespace by calling:
1103                 //      |       dojo.registerModulePath("foo", "../../foo");
1104                 //              At which point you can then use dojo.require() to load the
1105                 //              modules (assuming they provide() the same things which are
1106                 //              required). The full code might be:
1107                 //      |       <script type="text/javascript"
1108                 //      |               src="/myapp/js/dojo/dojo/dojo.js"></script>
1109                 //      |       <script type="text/javascript">
1110                 //      |               dojo.registerModulePath("foo", "../../foo");
1111                 //      |               dojo.require("foo.bar");
1112                 //      |               dojo.require("foo.baz");
1113                 //      |               dojo.require("foo.thud.xyzzy");
1114                 //      |       </script>
1115                 d._modulePrefixes[module] = { name: module, value: prefix };
1116         };
1117         
1118         dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String?*/availableFlatLocales){
1119                 // summary:
1120                 //              Declares translated resources and loads them if necessary, in the
1121                 //              same style as dojo.require.  Contents of the resource bundle are
1122                 //              typically strings, but may be any name/value pair, represented in
1123                 //              JSON format.  See also `dojo.i18n.getLocalization`.
1124                 //
1125                 // description:
1126                 //              Load translated resource bundles provided underneath the "nls"
1127                 //              directory within a package.  Translated resources may be located in
1128                 //              different packages throughout the source tree.
1129                 //
1130                 //              Each directory is named for a locale as specified by RFC 3066,
1131                 //              (http://www.ietf.org/rfc/rfc3066.txt), normalized in lowercase.
1132                 //              Note that the two bundles in the example do not define all the
1133                 //              same variants.  For a given locale, bundles will be loaded for
1134                 //              that locale and all more general locales above it, including a
1135                 //              fallback at the root directory.  For example, a declaration for
1136                 //              the "de-at" locale will first load `nls/de-at/bundleone.js`,
1137                 //              then `nls/de/bundleone.js` and finally `nls/bundleone.js`.  The
1138                 //              data will be flattened into a single Object so that lookups
1139                 //              will follow this cascading pattern.  An optional build step can
1140                 //              preload the bundles to avoid data redundancy and the multiple
1141                 //              network hits normally required to load these resources.
1142                 //
1143                 // moduleName:
1144                 //              name of the package containing the "nls" directory in which the
1145                 //              bundle is found
1146                 //
1147                 // bundleName:
1148                 //              bundle name, i.e. the filename without the '.js' suffix. Using "nls" as a
1149                 //              a bundle name is not supported, since "nls" is the name of the folder
1150                 //              that holds bundles. Using "nls" as the bundle name will cause problems
1151                 //              with the custom build.
1152                 //
1153                 // locale:
1154                 //              the locale to load (optional)  By default, the browser's user
1155                 //              locale as defined by dojo.locale
1156                 //
1157                 // availableFlatLocales:
1158                 //              A comma-separated list of the available, flattened locales for this
1159                 //              bundle. This argument should only be set by the build process.
1160                 //
1161                 //      example:
1162                 //              A particular widget may define one or more resource bundles,
1163                 //              structured in a program as follows, where moduleName is
1164                 //              mycode.mywidget and bundleNames available include bundleone and
1165                 //              bundletwo:
1166                 //      |               ...
1167                 //      |       mycode/
1168                 //      |               mywidget/
1169                 //      |                       nls/
1170                 //      |                               bundleone.js (the fallback translation, English in this example)
1171                 //      |                               bundletwo.js (also a fallback translation)
1172                 //      |                               de/
1173                 //      |                                       bundleone.js
1174                 //      |                                       bundletwo.js
1175                 //      |                               de-at/
1176                 //      |                                       bundleone.js
1177                 //      |                               en/
1178                 //      |                                       (empty; use the fallback translation)
1179                 //      |                               en-us/
1180                 //      |                                       bundleone.js
1181                 //      |                               en-gb/
1182                 //      |                                       bundleone.js
1183                 //      |                               es/
1184                 //      |                                       bundleone.js
1185                 //      |                                       bundletwo.js
1186                 //      |                                 ...etc
1187                 //      |                               ...
1188                 //
1189
1190                 d.require("dojo.i18n");
1191                 d.i18n._requireLocalization.apply(d.hostenv, arguments);
1192         };
1193
1194
1195         var ore = new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"),
1196                 ire = new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$");
1197
1198         dojo._Url = function(/*dojo._Url|String...*/){
1199                 // summary:
1200                 //              Constructor to create an object representing a URL.
1201                 //              It is marked as private, since we might consider removing
1202                 //              or simplifying it.
1203                 // description:
1204                 //              Each argument is evaluated in order relative to the next until
1205                 //              a canonical uri is produced. To get an absolute Uri relative to
1206                 //              the current document use:
1207                 //              new dojo._Url(document.baseURI, url)
1208
1209                 var n = null,
1210                         _a = arguments,
1211                         uri = [_a[0]];
1212                 // resolve uri components relative to each other
1213                 for(var i = 1; i<_a.length; i++){
1214                         if(!_a[i]){ continue; }
1215
1216                         // Safari doesn't support this.constructor so we have to be explicit
1217                         // FIXME: Tracked (and fixed) in Webkit bug 3537.
1218                         //              http://bugs.webkit.org/show_bug.cgi?id=3537
1219                         var relobj = new d._Url(_a[i]+""),
1220                                 uriobj = new d._Url(uri[0]+"");
1221
1222                         if(
1223                                 relobj.path == "" &&
1224                                 !relobj.scheme &&
1225                                 !relobj.authority &&
1226                                 !relobj.query
1227                         ){
1228                                 if(relobj.fragment != n){
1229                                         uriobj.fragment = relobj.fragment;
1230                                 }
1231                                 relobj = uriobj;
1232                         }else if(!relobj.scheme){
1233                                 relobj.scheme = uriobj.scheme;
1234
1235                                 if(!relobj.authority){
1236                                         relobj.authority = uriobj.authority;
1237
1238                                         if(relobj.path.charAt(0) != "/"){
1239                                                 var path = uriobj.path.substring(0,
1240                                                         uriobj.path.lastIndexOf("/") + 1) + relobj.path;
1241
1242                                                 var segs = path.split("/");
1243                                                 for(var j = 0; j < segs.length; j++){
1244                                                         if(segs[j] == "."){
1245                                                                 // flatten "./" references
1246                                                                 if(j == segs.length - 1){
1247                                                                         segs[j] = "";
1248                                                                 }else{
1249                                                                         segs.splice(j, 1);
1250                                                                         j--;
1251                                                                 }
1252                                                         }else if(j > 0 && !(j == 1 && segs[0] == "") &&
1253                                                                 segs[j] == ".." && segs[j-1] != ".."){
1254                                                                 // flatten "../" references
1255                                                                 if(j == (segs.length - 1)){
1256                                                                         segs.splice(j, 1);
1257                                                                         segs[j - 1] = "";
1258                                                                 }else{
1259                                                                         segs.splice(j - 1, 2);
1260                                                                         j -= 2;
1261                                                                 }
1262                                                         }
1263                                                 }
1264                                                 relobj.path = segs.join("/");
1265                                         }
1266                                 }
1267                         }
1268
1269                         uri = [];
1270                         if(relobj.scheme){
1271                                 uri.push(relobj.scheme, ":");
1272                         }
1273                         if(relobj.authority){
1274                                 uri.push("//", relobj.authority);
1275                         }
1276                         uri.push(relobj.path);
1277                         if(relobj.query){
1278                                 uri.push("?", relobj.query);
1279                         }
1280                         if(relobj.fragment){
1281                                 uri.push("#", relobj.fragment);
1282                         }
1283                 }
1284
1285                 this.uri = uri.join("");
1286
1287                 // break the uri into its main components
1288                 var r = this.uri.match(ore);
1289
1290                 this.scheme = r[2] || (r[1] ? "" : n);
1291                 this.authority = r[4] || (r[3] ? "" : n);
1292                 this.path = r[5]; // can never be undefined
1293                 this.query = r[7] || (r[6] ? "" : n);
1294                 this.fragment  = r[9] || (r[8] ? "" : n);
1295
1296                 if(this.authority != n){
1297                         // server based naming authority
1298                         r = this.authority.match(ire);
1299
1300                         this.user = r[3] || n;
1301                         this.password = r[4] || n;
1302                         this.host = r[6] || r[7]; // ipv6 || ipv4
1303                         this.port = r[9] || n;
1304                 }
1305         }
1306
1307         dojo._Url.prototype.toString = function(){ return this.uri; };
1308
1309         dojo.moduleUrl = function(/*String*/module, /*dojo._Url||String*/url){
1310                 //      summary:
1311                 //              Returns a `dojo._Url` object relative to a module.
1312                 //      example:
1313                 //      |       var pngPath = dojo.moduleUrl("acme","images/small.png");
1314                 //      |       console.dir(pngPath); // list the object properties
1315                 //      |       // create an image and set it's source to pngPath's value:
1316                 //      |       var img = document.createElement("img");
1317                 //      |       // NOTE: we assign the string representation of the url object
1318                 //      |       img.src = pngPath.toString();
1319                 //      |       // add our image to the document
1320                 //      |       dojo.body().appendChild(img);
1321                 //      example:
1322                 //              you may de-reference as far as you like down the package
1323                 //              hierarchy.  This is sometimes handy to avoid lenghty relative
1324                 //              urls or for building portable sub-packages. In this example,
1325                 //              the `acme.widget` and `acme.util` directories may be located
1326                 //              under different roots (see `dojo.registerModulePath`) but the
1327                 //              the modules which reference them can be unaware of their
1328                 //              relative locations on the filesystem:
1329                 //      |       // somewhere in a configuration block
1330                 //      |       dojo.registerModulePath("acme.widget", "../../acme/widget");
1331                 //      |       dojo.registerModulePath("acme.util", "../../util");
1332                 //      |
1333                 //      |       // ...
1334                 //      |
1335                 //      |       // code in a module using acme resources
1336                 //      |       var tmpltPath = dojo.moduleUrl("acme.widget","templates/template.html");
1337                 //      |       var dataPath = dojo.moduleUrl("acme.util","resources/data.json");
1338
1339                 var loc = d._getModuleSymbols(module).join('/');
1340                 if(!loc){ return null; }
1341                 if(loc.lastIndexOf("/") != loc.length-1){
1342                         loc += "/";
1343                 }
1344                 
1345                 //If the path is an absolute path (starts with a / or is on another
1346                 //domain/xdomain) then don't add the baseUrl.
1347                 var colonIndex = loc.indexOf(":");
1348                 if(loc.charAt(0) != "/" && (colonIndex == -1 || colonIndex > loc.indexOf("/"))){
1349                         loc = d.baseUrl + loc;
1350                 }
1351
1352                 return new d._Url(loc, url); // dojo._Url
1353         };
1354
1355
1356
1357 })();
1358
1359 /*=====
1360 dojo.isBrowser = {
1361         //      example:
1362         //      |       if(dojo.isBrowser){ ... }
1363 };
1364
1365 dojo.isFF = {
1366         //      example:
1367         //      |       if(dojo.isFF > 1){ ... }
1368 };
1369
1370 dojo.isIE = {
1371         // example:
1372         //      |       if(dojo.isIE > 6){
1373         //      |               // we are IE7
1374         //      |       }
1375 };
1376
1377 dojo.isSafari = {
1378         //      example:
1379         //      |       if(dojo.isSafari){ ... }
1380         //      example:
1381         //              Detect iPhone:
1382         //      |       if(dojo.isSafari && navigator.userAgent.indexOf("iPhone") != -1){
1383         //      |               // we are iPhone. Note, iPod touch reports "iPod" above and fails this test.
1384         //      |       }
1385 };
1386
1387 dojo = {
1388         // isBrowser: Boolean
1389         //              True if the client is a web-browser
1390         isBrowser: true,
1391         //      isFF: Number | undefined
1392         //              Version as a Number if client is FireFox. undefined otherwise. Corresponds to
1393         //              major detected FireFox version (1.5, 2, 3, etc.)
1394         isFF: 2,
1395         //      isIE: Number | undefined
1396         //              Version as a Number if client is MSIE(PC). undefined otherwise. Corresponds to
1397         //              major detected IE version (6, 7, 8, etc.)
1398         isIE: 6,
1399         //      isKhtml: Number | undefined
1400         //              Version as a Number if client is a KHTML browser. undefined otherwise. Corresponds to major
1401         //              detected version.
1402         isKhtml: 0,
1403         //      isWebKit: Number | undefined
1404         //              Version as a Number if client is a WebKit-derived browser (Konqueror,
1405         //              Safari, Chrome, etc.). undefined otherwise.
1406         isWebKit: 0,
1407         //      isMozilla: Number | undefined
1408         //              Version as a Number if client is a Mozilla-based browser (Firefox,
1409         //              SeaMonkey). undefined otherwise. Corresponds to major detected version.
1410         isMozilla: 0,
1411         //      isOpera: Number | undefined
1412         //              Version as a Number if client is Opera. undefined otherwise. Corresponds to
1413         //              major detected version.
1414         isOpera: 0,
1415         //      isSafari: Number | undefined
1416         //              Version as a Number if client is Safari or iPhone. undefined otherwise.
1417         isSafari: 0,
1418         //      isChrome: Number | undefined
1419         //              Version as a Number if client is Chrome browser. undefined otherwise.
1420         isChrome: 0
1421         //      isMac: Boolean
1422         //              True if the client runs on Mac
1423 }
1424 =====*/
1425 if(typeof window != 'undefined'){
1426         dojo.isBrowser = true;
1427         dojo._name = "browser";
1428
1429
1430         // attempt to figure out the path to dojo if it isn't set in the config
1431         (function(){
1432                 var d = dojo;
1433
1434                 // this is a scope protection closure. We set browser versions and grab
1435                 // the URL we were loaded from here.
1436
1437                 // grab the node we were loaded from
1438                 if(document && document.getElementsByTagName){
1439                         var scripts = document.getElementsByTagName("script");
1440                         var rePkg = /dojo(\.xd)?\.js(\W|$)/i;
1441                         for(var i = 0; i < scripts.length; i++){
1442                                 var src = scripts[i].getAttribute("src");
1443                                 if(!src){ continue; }
1444                                 var m = src.match(rePkg);
1445                                 if(m){
1446                                         // find out where we came from
1447                                         if(!d.config.baseUrl){
1448                                                 d.config.baseUrl = src.substring(0, m.index);
1449                                         }
1450                                         // and find out if we need to modify our behavior
1451                                         var cfg = (scripts[i].getAttribute("djConfig") || scripts[i].getAttribute("data-dojo-config"));
1452                                         if(cfg){
1453                                                 var cfgo = eval("({ "+cfg+" })");
1454                                                 for(var x in cfgo){
1455                                                         dojo.config[x] = cfgo[x];
1456                                                 }
1457                                         }
1458                                         break; // "first Dojo wins"
1459                                 }
1460                         }
1461                 }
1462                 d.baseUrl = d.config.baseUrl;
1463
1464                 // fill in the rendering support information in dojo.render.*
1465                 var n = navigator;
1466                 var dua = n.userAgent,
1467                         dav = n.appVersion,
1468                         tv = parseFloat(dav);
1469
1470                 if(dua.indexOf("Opera") >= 0){ d.isOpera = tv; }
1471                 if(dua.indexOf("AdobeAIR") >= 0){ d.isAIR = 1; }
1472                 d.isKhtml = (dav.indexOf("Konqueror") >= 0) ? tv : 0;
1473                 d.isWebKit = parseFloat(dua.split("WebKit/")[1]) || undefined;
1474                 d.isChrome = parseFloat(dua.split("Chrome/")[1]) || undefined;
1475                 d.isMac = dav.indexOf("Macintosh") >= 0;
1476
1477                 // safari detection derived from:
1478                 //              http://developer.apple.com/internet/safari/faq.html#anchor2
1479                 //              http://developer.apple.com/internet/safari/uamatrix.html
1480                 var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);
1481                 if(index && !dojo.isChrome){
1482                         // try to grab the explicit Safari version first. If we don't get
1483                         // one, look for less than 419.3 as the indication that we're on something
1484                         // "Safari 2-ish".
1485                         d.isSafari = parseFloat(dav.split("Version/")[1]);
1486                         if(!d.isSafari || parseFloat(dav.substr(index + 7)) <= 419.3){
1487                                 d.isSafari = 2;
1488                         }
1489                 }
1490
1491                                 if(dua.indexOf("Gecko") >= 0 && !d.isKhtml && !d.isWebKit){ d.isMozilla = d.isMoz = tv; }
1492                 if(d.isMoz){
1493                         //We really need to get away from this. Consider a sane isGecko approach for the future.
1494                         d.isFF = parseFloat(dua.split("Firefox/")[1] || dua.split("Minefield/")[1]) || undefined;
1495                 }
1496                 if(document.all && !d.isOpera){
1497                         d.isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
1498                         //In cases where the page has an HTTP header or META tag with
1499                         //X-UA-Compatible, then it is in emulation mode.
1500                         //Make sure isIE reflects the desired version.
1501                         //document.documentMode of 5 means quirks mode.
1502                         //Only switch the value if documentMode's major version
1503                         //is different from isIE's major version.
1504                         var mode = document.documentMode;
1505                         if(mode && mode != 5 && Math.floor(d.isIE) != mode){
1506                                 d.isIE = mode;
1507                         }
1508                 }
1509
1510                 //Workaround to get local file loads of dojo to work on IE 7
1511                 //by forcing to not use native xhr.
1512                 if(dojo.isIE && window.location.protocol === "file:"){
1513                         dojo.config.ieForceActiveXXhr=true;
1514                 }
1515                 
1516                 d.isQuirks = document.compatMode == "BackCompat";
1517
1518                 // TODO: is the HTML LANG attribute relevant?
1519                 d.locale = dojo.config.locale || (d.isIE ? n.userLanguage : n.language).toLowerCase();
1520
1521                 // These are in order of decreasing likelihood; this will change in time.
1522                                 d._XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'];
1523                 
1524                 d._xhrObj = function(){
1525                         // summary:
1526                         //              does the work of portably generating a new XMLHTTPRequest object.
1527                         var http, last_e;
1528                                                 if(!dojo.isIE || !dojo.config.ieForceActiveXXhr){
1529                                                         try{ http = new XMLHttpRequest(); }catch(e){}
1530                                                 }
1531                         if(!http){
1532                                 for(var i=0; i<3; ++i){
1533                                         var progid = d._XMLHTTP_PROGIDS[i];
1534                                         try{
1535                                                 http = new ActiveXObject(progid);
1536                                         }catch(e){
1537                                                 last_e = e;
1538                                         }
1539
1540                                         if(http){
1541                                                 d._XMLHTTP_PROGIDS = [progid];  // so faster next time
1542                                                 break;
1543                                         }
1544                                 }
1545                         }
1546                         
1547                         if(!http){
1548                                 throw new Error("XMLHTTP not available: "+last_e);
1549                         }
1550
1551                         return http; // XMLHTTPRequest instance
1552                 }
1553
1554                 d._isDocumentOk = function(http){
1555                         var stat = http.status || 0,
1556                                 lp = location.protocol;
1557                         return (stat >= 200 && stat < 300) ||   // Boolean
1558                                 stat == 304 ||                  // allow any 2XX response code
1559                                 stat == 1223 ||                 // get it out of the cache
1560                                                                 // Internet Explorer mangled the status code
1561                                 // Internet Explorer mangled the status code OR we're Titanium/browser chrome/chrome extension requesting a local file
1562                                 (!stat && (lp == "file:" || lp == "chrome:" || lp == "chrome-extension:" || lp == "app:"));
1563                 }
1564
1565                 //See if base tag is in use.
1566                 //This is to fix http://trac.dojotoolkit.org/ticket/3973,
1567                 //but really, we need to find out how to get rid of the dojo._Url reference
1568                 //below and still have DOH work with the dojo.i18n test following some other
1569                 //test that uses the test frame to load a document (trac #2757).
1570                 //Opera still has problems, but perhaps a larger issue of base tag support
1571                 //with XHR requests (hasBase is true, but the request is still made to document
1572                 //path, not base path).
1573                 var owloc = window.location+"";
1574                 var base = document.getElementsByTagName("base");
1575                 var hasBase = (base && base.length > 0);
1576
1577                 d._getText = function(/*URI*/ uri, /*Boolean*/ fail_ok){
1578                         // summary: Read the contents of the specified uri and return those contents.
1579                         // uri:
1580                         //              A relative or absolute uri. If absolute, it still must be in
1581                         //              the same "domain" as we are.
1582                         // fail_ok:
1583                         //              Default false. If fail_ok and loading fails, return null
1584                         //              instead of throwing.
1585                         // returns: The response text. null is returned when there is a
1586                         //              failure and failure is okay (an exception otherwise)
1587
1588                         // NOTE: must be declared before scope switches ie. this._xhrObj()
1589                         var http = d._xhrObj();
1590
1591                         if(!hasBase && dojo._Url){
1592                                 uri = (new dojo._Url(owloc, uri)).toString();
1593                         }
1594
1595                         if(d.config.cacheBust){
1596                                 //Make sure we have a string before string methods are used on uri
1597                                 uri += "";
1598                                 uri += (uri.indexOf("?") == -1 ? "?" : "&") + String(d.config.cacheBust).replace(/\W+/g,"");
1599                         }
1600
1601                         http.open('GET', uri, false);
1602                         try{
1603                                 http.send(null);
1604                                 if(!d._isDocumentOk(http)){
1605                                         var err = Error("Unable to load "+uri+" status:"+ http.status);
1606                                         err.status = http.status;
1607                                         err.responseText = http.responseText;
1608                                         throw err;
1609                                 }
1610                         }catch(e){
1611                                 if(fail_ok){ return null; } // null
1612                                 // rethrow the exception
1613                                 throw e;
1614                         }
1615                         return http.responseText; // String
1616                 }
1617                 
1618
1619                 var _w = window;
1620                 var _handleNodeEvent = function(/*String*/evtName, /*Function*/fp){
1621                         // summary:
1622                         //              non-destructively adds the specified function to the node's
1623                         //              evtName handler.
1624                         // evtName: should be in the form "onclick" for "onclick" handlers.
1625                         // Make sure you pass in the "on" part.
1626                         var _a = _w.attachEvent || _w.addEventListener;
1627                         evtName = _w.attachEvent ? evtName : evtName.substring(2);
1628                         _a(evtName, function(){
1629                                 fp.apply(_w, arguments);
1630                         }, false);
1631                 };
1632
1633
1634                 d._windowUnloaders = [];
1635                 
1636                 d.windowUnloaded = function(){
1637                         // summary:
1638                         //              signal fired by impending window destruction. You may use
1639                         //              dojo.addOnWindowUnload() to register a listener for this
1640                         //              event. NOTE: if you wish to dojo.connect() to this method
1641                         //              to perform page/application cleanup, be aware that this
1642                         //              event WILL NOT fire if no handler has been registered with
1643                         //              dojo.addOnWindowUnload. This behavior started in Dojo 1.3.
1644                         //              Previous versions always triggered dojo.windowUnloaded. See
1645                         //              dojo.addOnWindowUnload for more info.
1646                         var mll = d._windowUnloaders;
1647                         while(mll.length){
1648                                 (mll.pop())();
1649                         }
1650                         d = null;
1651                 };
1652
1653                 var _onWindowUnloadAttached = 0;
1654                 d.addOnWindowUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
1655                         // summary:
1656                         //              registers a function to be triggered when window.onunload
1657                         //              fires.
1658                         //      description:
1659                         //              The first time that addOnWindowUnload is called Dojo
1660                         //              will register a page listener to trigger your unload
1661                         //              handler with. Note that registering these handlers may
1662                         //              destory "fastback" page caching in browsers that support
1663                         //              it. Be careful trying to modify the DOM or access
1664                         //              JavaScript properties during this phase of page unloading:
1665                         //              they may not always be available. Consider
1666                         //              dojo.addOnUnload() if you need to modify the DOM or do
1667                         //              heavy JavaScript work since it fires at the eqivalent of
1668                         //              the page's "onbeforeunload" event.
1669                         // example:
1670                         //      |       dojo.addOnWindowUnload(functionPointer)
1671                         //      |       dojo.addOnWindowUnload(object, "functionName");
1672                         //      |       dojo.addOnWindowUnload(object, function(){ /* ... */});
1673
1674                         d._onto(d._windowUnloaders, obj, functionName);
1675                         if(!_onWindowUnloadAttached){
1676                                 _onWindowUnloadAttached = 1;
1677                                 _handleNodeEvent("onunload", d.windowUnloaded);
1678                         }
1679                 };
1680
1681                 var _onUnloadAttached = 0;
1682                 d.addOnUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
1683                         // summary:
1684                         //              registers a function to be triggered when the page unloads.
1685                         //      description:
1686                         //              The first time that addOnUnload is called Dojo will
1687                         //              register a page listener to trigger your unload handler
1688                         //              with.
1689                         //
1690                         //              In a browser enviroment, the functions will be triggered
1691                         //              during the window.onbeforeunload event. Be careful of doing
1692                         //              too much work in an unload handler. onbeforeunload can be
1693                         //              triggered if a link to download a file is clicked, or if
1694                         //              the link is a javascript: link. In these cases, the
1695                         //              onbeforeunload event fires, but the document is not
1696                         //              actually destroyed. So be careful about doing destructive
1697                         //              operations in a dojo.addOnUnload callback.
1698                         //
1699                         //              Further note that calling dojo.addOnUnload will prevent
1700                         //              browsers from using a "fast back" cache to make page
1701                         //              loading via back button instantaneous.
1702                         // example:
1703                         //      |       dojo.addOnUnload(functionPointer)
1704                         //      |       dojo.addOnUnload(object, "functionName")
1705                         //      |       dojo.addOnUnload(object, function(){ /* ... */});
1706
1707                         d._onto(d._unloaders, obj, functionName);
1708                         if(!_onUnloadAttached){
1709                                 _onUnloadAttached = 1;
1710                                 _handleNodeEvent("onbeforeunload", dojo.unloaded);
1711                         }
1712                 };
1713
1714         })();
1715
1716         //START DOMContentLoaded
1717         dojo._initFired = false;
1718         dojo._loadInit = function(e){
1719                 if(dojo._scrollIntervalId){
1720                         clearInterval(dojo._scrollIntervalId);
1721                         dojo._scrollIntervalId = 0;
1722                 }
1723
1724                 if(!dojo._initFired){
1725                         dojo._initFired = true;
1726
1727                         //Help out IE to avoid memory leak.
1728                         if(!dojo.config.afterOnLoad && window.detachEvent){
1729                                 window.detachEvent("onload", dojo._loadInit);
1730                         }
1731
1732                         if(dojo._inFlightCount == 0){
1733                                 dojo._modulesLoaded();
1734                         }
1735                 }
1736         }
1737
1738         if(!dojo.config.afterOnLoad){
1739                 if(document.addEventListener){
1740                         //Standards. Hooray! Assumption here that if standards based,
1741                         //it knows about DOMContentLoaded. It is OK if it does not, the fall through
1742                         //to window onload should be good enough.
1743                         document.addEventListener("DOMContentLoaded", dojo._loadInit, false);
1744                         window.addEventListener("load", dojo._loadInit, false);
1745                 }else if(window.attachEvent){
1746                         window.attachEvent("onload", dojo._loadInit);
1747
1748                         //DOMContentLoaded approximation. Diego Perini found this MSDN article
1749                         //that indicates doScroll is available after DOM ready, so do a setTimeout
1750                         //to check when it is available.
1751                         //http://msdn.microsoft.com/en-us/library/ms531426.aspx
1752                         if(!dojo.config.skipIeDomLoaded && self === self.top){
1753                                 dojo._scrollIntervalId = setInterval(function (){
1754                                         try{
1755                                                 //When dojo is loaded into an iframe in an IE HTML Application
1756                                                 //(HTA), such as in a selenium test, javascript in the iframe
1757                                                 //can't see anything outside of it, so self===self.top is true,
1758                                                 //but the iframe is not the top window and doScroll will be
1759                                                 //available before document.body is set. Test document.body
1760                                                 //before trying the doScroll trick
1761                                                 if(document.body){
1762                                                         document.documentElement.doScroll("left");
1763                                                         dojo._loadInit();
1764                                                 }
1765                                         }catch (e){}
1766                                 }, 30);
1767                         }
1768                 }
1769         }
1770
1771                 if(dojo.isIE){
1772                 try{
1773                         (function(){
1774                                 document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
1775                                 var vmlElems = ["*", "group", "roundrect", "oval", "shape", "rect", "imagedata", "path", "textpath", "text"],
1776                                         i = 0, l = 1, s = document.createStyleSheet();
1777                                 if(dojo.isIE >= 8){
1778                                         i = 1;
1779                                         l = vmlElems.length;
1780                                 }
1781                                 for(; i < l; ++i){
1782                                         s.addRule("v\\:" + vmlElems[i], "behavior:url(#default#VML); display:inline-block");
1783                                 }
1784                         })();
1785                 }catch(e){}
1786         }
1787                 //END DOMContentLoaded
1788
1789
1790         /*
1791         OpenAjax.subscribe("OpenAjax", "onload", function(){
1792                 if(dojo._inFlightCount == 0){
1793                         dojo._modulesLoaded();
1794                 }
1795         });
1796
1797         OpenAjax.subscribe("OpenAjax", "onunload", function(){
1798                 dojo.unloaded();
1799         });
1800         */
1801 } //if (typeof window != 'undefined')
1802
1803 //Register any module paths set up in djConfig. Need to do this
1804 //in the hostenvs since hostenv_browser can read djConfig from a
1805 //script tag's attribute.
1806 (function(){
1807         var mp = dojo.config["modulePaths"];
1808         if(mp){
1809                 for(var param in mp){
1810                         dojo.registerModulePath(param, mp[param]);
1811                 }
1812         }
1813 })();
1814
1815 //Load debug code if necessary.
1816 if(dojo.config.isDebug){
1817         dojo.require("dojo._firebug.firebug");
1818 }
1819
1820 if(dojo.config.debugAtAllCosts){
1821         // this breaks the new AMD based module loader. The XDomain won't be necessary
1822         // anyway if you switch to the asynchronous loader
1823         //dojo.config.useXDomain = true;
1824         //dojo.require("dojo._base._loader.loader_xd");
1825         dojo.require("dojo._base._loader.loader_debug");
1826         dojo.require("dojo.i18n");
1827 }
1828
1829
1830 if(!dojo._hasResource["dojo._base.lang"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
1831 dojo._hasResource["dojo._base.lang"] = true;
1832 dojo.provide("dojo._base.lang");
1833
1834
1835 (function(){
1836         var d = dojo, opts = Object.prototype.toString;
1837
1838         // Crockford (ish) functions
1839
1840         dojo.isString = function(/*anything*/ it){
1841                 //      summary:
1842                 //              Return true if it is a String
1843                 return (typeof it == "string" || it instanceof String); // Boolean
1844         };
1845
1846         dojo.isArray = function(/*anything*/ it){
1847                 //      summary:
1848                 //              Return true if it is an Array.
1849                 //              Does not work on Arrays created in other windows.
1850                 return it && (it instanceof Array || typeof it == "array"); // Boolean
1851         };
1852
1853         dojo.isFunction = function(/*anything*/ it){
1854                 // summary:
1855                 //              Return true if it is a Function
1856                 return opts.call(it) === "[object Function]";
1857         };
1858
1859         dojo.isObject = function(/*anything*/ it){
1860                 // summary:
1861                 //              Returns true if it is a JavaScript object (or an Array, a Function
1862                 //              or null)
1863                 return it !== undefined &&
1864                         (it === null || typeof it == "object" || d.isArray(it) || d.isFunction(it)); // Boolean
1865         };
1866
1867         dojo.isArrayLike = function(/*anything*/ it){
1868                 //      summary:
1869                 //              similar to dojo.isArray() but more permissive
1870                 //      description:
1871                 //              Doesn't strongly test for "arrayness".  Instead, settles for "isn't
1872                 //              a string or number and has a length property". Arguments objects
1873                 //              and DOM collections will return true when passed to
1874                 //              dojo.isArrayLike(), but will return false when passed to
1875                 //              dojo.isArray().
1876                 //      returns:
1877                 //              If it walks like a duck and quacks like a duck, return `true`
1878                 return it && it !== undefined && // Boolean
1879                         // keep out built-in constructors (Number, String, ...) which have length
1880                         // properties
1881                         !d.isString(it) && !d.isFunction(it) &&
1882                         !(it.tagName && it.tagName.toLowerCase() == 'form') &&
1883                         (d.isArray(it) || isFinite(it.length));
1884         };
1885
1886         dojo.isAlien = function(/*anything*/ it){
1887                 // summary:
1888                 //              Returns true if it is a built-in function or some other kind of
1889                 //              oddball that *should* report as a function but doesn't
1890                 return it && !d.isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean
1891         };
1892
1893         dojo.extend = function(/*Object*/ constructor, /*Object...*/ props){
1894                 // summary:
1895                 //              Adds all properties and methods of props to constructor's
1896                 //              prototype, making them available to all instances created with
1897                 //              constructor.
1898                 for(var i=1, l=arguments.length; i<l; i++){
1899                         d._mixin(constructor.prototype, arguments[i]);
1900                 }
1901                 return constructor; // Object
1902         };
1903
1904         dojo._hitchArgs = function(scope, method /*,...*/){
1905                 var pre = d._toArray(arguments, 2);
1906                 var named = d.isString(method);
1907                 return function(){
1908                         // arrayify arguments
1909                         var args = d._toArray(arguments);
1910                         // locate our method
1911                         var f = named ? (scope||d.global)[method] : method;
1912                         // invoke with collected args
1913                         return f && f.apply(scope || this, pre.concat(args)); // mixed
1914                 }; // Function
1915         };
1916
1917         dojo.hitch = function(/*Object*/scope, /*Function|String*/method /*,...*/){
1918                 //      summary:
1919                 //              Returns a function that will only ever execute in the a given scope.
1920                 //              This allows for easy use of object member functions
1921                 //              in callbacks and other places in which the "this" keyword may
1922                 //              otherwise not reference the expected scope.
1923                 //              Any number of default positional arguments may be passed as parameters
1924                 //              beyond "method".
1925                 //              Each of these values will be used to "placehold" (similar to curry)
1926                 //              for the hitched function.
1927                 //      scope:
1928                 //              The scope to use when method executes. If method is a string,
1929                 //              scope is also the object containing method.
1930                 //      method:
1931                 //              A function to be hitched to scope, or the name of the method in
1932                 //              scope to be hitched.
1933                 //      example:
1934                 //      |       dojo.hitch(foo, "bar")();
1935                 //              runs foo.bar() in the scope of foo
1936                 //      example:
1937                 //      |       dojo.hitch(foo, myFunction);
1938                 //              returns a function that runs myFunction in the scope of foo
1939                 //      example:
1940                 //              Expansion on the default positional arguments passed along from
1941                 //              hitch. Passed args are mixed first, additional args after.
1942                 //      |       var foo = { bar: function(a, b, c){ console.log(a, b, c); } };
1943                 //      |       var fn = dojo.hitch(foo, "bar", 1, 2);
1944                 //      |       fn(3); // logs "1, 2, 3"
1945                 //      example:
1946                 //      |       var foo = { bar: 2 };
1947                 //      |       dojo.hitch(foo, function(){ this.bar = 10; })();
1948                 //              execute an anonymous function in scope of foo
1949                 
1950                 if(arguments.length > 2){
1951                         return d._hitchArgs.apply(d, arguments); // Function
1952                 }
1953                 if(!method){
1954                         method = scope;
1955                         scope = null;
1956                 }
1957                 if(d.isString(method)){
1958                         scope = scope || d.global;
1959                         if(!scope[method]){ throw(['dojo.hitch: scope["', method, '"] is null (scope="', scope, '")'].join('')); }
1960                         return function(){ return scope[method].apply(scope, arguments || []); }; // Function
1961                 }
1962                 return !scope ? method : function(){ return method.apply(scope, arguments || []); }; // Function
1963         };
1964
1965         /*=====
1966         dojo.delegate = function(obj, props){
1967                 //      summary:
1968                 //              Returns a new object which "looks" to obj for properties which it
1969                 //              does not have a value for. Optionally takes a bag of properties to
1970                 //              seed the returned object with initially.
1971                 //      description:
1972                 //              This is a small implementaton of the Boodman/Crockford delegation
1973                 //              pattern in JavaScript. An intermediate object constructor mediates
1974                 //              the prototype chain for the returned object, using it to delegate
1975                 //              down to obj for property lookup when object-local lookup fails.
1976                 //              This can be thought of similarly to ES4's "wrap", save that it does
1977                 //              not act on types but rather on pure objects.
1978                 //      obj:
1979                 //              The object to delegate to for properties not found directly on the
1980                 //              return object or in props.
1981                 //      props:
1982                 //              an object containing properties to assign to the returned object
1983                 //      returns:
1984                 //              an Object of anonymous type
1985                 //      example:
1986                 //      |       var foo = { bar: "baz" };
1987                 //      |       var thinger = dojo.delegate(foo, { thud: "xyzzy"});
1988                 //      |       thinger.bar == "baz"; // delegated to foo
1989                 //      |       foo.thud == undefined; // by definition
1990                 //      |       thinger.thud == "xyzzy"; // mixed in from props
1991                 //      |       foo.bar = "thonk";
1992                 //      |       thinger.bar == "thonk"; // still delegated to foo's bar
1993         }
1994         =====*/
1995
1996         dojo.delegate = dojo._delegate = (function(){
1997                 // boodman/crockford delegation w/ cornford optimization
1998                 function TMP(){}
1999                 return function(obj, props){
2000                         TMP.prototype = obj;
2001                         var tmp = new TMP();
2002                         TMP.prototype = null;
2003                         if(props){
2004                                 d._mixin(tmp, props);
2005                         }
2006                         return tmp; // Object
2007                 };
2008         })();
2009
2010         /*=====
2011         dojo._toArray = function(obj, offset, startWith){
2012                 //      summary:
2013                 //              Converts an array-like object (i.e. arguments, DOMCollection) to an
2014                 //              array. Returns a new Array with the elements of obj.
2015                 //      obj: Object
2016                 //              the object to "arrayify". We expect the object to have, at a
2017                 //              minimum, a length property which corresponds to integer-indexed
2018                 //              properties.
2019                 //      offset: Number?
2020                 //              the location in obj to start iterating from. Defaults to 0.
2021                 //              Optional.
2022                 //      startWith: Array?
2023                 //              An array to pack with the properties of obj. If provided,
2024                 //              properties in obj are appended at the end of startWith and
2025                 //              startWith is the returned array.
2026         }
2027         =====*/
2028
2029         var efficient = function(obj, offset, startWith){
2030                 return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0));
2031         };
2032
2033                 var slow = function(obj, offset, startWith){
2034                 var arr = startWith||[];
2035                 for(var x = offset || 0; x < obj.length; x++){
2036                         arr.push(obj[x]);
2037                 }
2038                 return arr;
2039         };
2040         
2041         dojo._toArray =
2042                                 d.isIE ?  function(obj){
2043                         return ((obj.item) ? slow : efficient).apply(this, arguments);
2044                 } :
2045                                 efficient;
2046
2047         dojo.partial = function(/*Function|String*/method /*, ...*/){
2048                 //      summary:
2049                 //              similar to hitch() except that the scope object is left to be
2050                 //              whatever the execution context eventually becomes.
2051                 //      description:
2052                 //              Calling dojo.partial is the functional equivalent of calling:
2053                 //              |       dojo.hitch(null, funcName, ...);
2054                 var arr = [ null ];
2055                 return d.hitch.apply(d, arr.concat(d._toArray(arguments))); // Function
2056         };
2057
2058         var extraNames = d._extraNames, extraLen = extraNames.length, empty = {};
2059
2060         dojo.clone = function(/*anything*/ o){
2061                 // summary:
2062                 //              Clones objects (including DOM nodes) and all children.
2063                 //              Warning: do not clone cyclic structures.
2064                 if(!o || typeof o != "object" || d.isFunction(o)){
2065                         // null, undefined, any non-object, or function
2066                         return o;       // anything
2067                 }
2068                 if(o.nodeType && "cloneNode" in o){
2069                         // DOM Node
2070                         return o.cloneNode(true); // Node
2071                 }
2072                 if(o instanceof Date){
2073                         // Date
2074                         return new Date(o.getTime());   // Date
2075                 }
2076                 if(o instanceof RegExp){
2077                         // RegExp
2078                         return new RegExp(o);   // RegExp
2079                 }
2080                 var r, i, l, s, name;
2081                 if(d.isArray(o)){
2082                         // array
2083                         r = [];
2084                         for(i = 0, l = o.length; i < l; ++i){
2085                                 if(i in o){
2086                                         r.push(d.clone(o[i]));
2087                                 }
2088                         }
2089 // we don't clone functions for performance reasons
2090 //              }else if(d.isFunction(o)){
2091 //                      // function
2092 //                      r = function(){ return o.apply(this, arguments); };
2093                 }else{
2094                         // generic objects
2095                         r = o.constructor ? new o.constructor() : {};
2096                 }
2097                 for(name in o){
2098                         // the "tobj" condition avoid copying properties in "source"
2099                         // inherited from Object.prototype.  For example, if target has a custom
2100                         // toString() method, don't overwrite it with the toString() method
2101                         // that source inherited from Object.prototype
2102                         s = o[name];
2103                         if(!(name in r) || (r[name] !== s && (!(name in empty) || empty[name] !== s))){
2104                                 r[name] = d.clone(s);
2105                         }
2106                 }
2107                                 // IE doesn't recognize some custom functions in for..in
2108                 if(extraLen){
2109                         for(i = 0; i < extraLen; ++i){
2110                                 name = extraNames[i];
2111                                 s = o[name];
2112                                 if(!(name in r) || (r[name] !== s && (!(name in empty) || empty[name] !== s))){
2113                                         r[name] = s; // functions only, we don't clone them
2114                                 }
2115                         }
2116                 }
2117                                 return r; // Object
2118         };
2119
2120         /*=====
2121         dojo.trim = function(str){
2122                 //      summary:
2123                 //              Trims whitespace from both sides of the string
2124                 //      str: String
2125                 //              String to be trimmed
2126                 //      returns: String
2127                 //              Returns the trimmed string
2128                 //      description:
2129                 //              This version of trim() was selected for inclusion into the base due
2130                 //              to its compact size and relatively good performance
2131                 //              (see [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript)
2132                 //              Uses String.prototype.trim instead, if available.
2133                 //              The fastest but longest version of this function is located at
2134                 //              dojo.string.trim()
2135                 return "";      // String
2136         }
2137         =====*/
2138
2139         dojo.trim = String.prototype.trim ?
2140                 function(str){ return str.trim(); } :
2141                 function(str){ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); };
2142
2143         /*=====
2144         dojo.replace = function(tmpl, map, pattern){
2145                 //      summary:
2146                 //              Performs parameterized substitutions on a string. Throws an
2147                 //              exception if any parameter is unmatched.
2148                 //      tmpl: String
2149                 //              String to be used as a template.
2150                 //      map: Object|Function
2151                 //              If an object, it is used as a dictionary to look up substitutions.
2152                 //              If a function, it is called for every substitution with following
2153                 //              parameters: a whole match, a name, an offset, and the whole template
2154                 //              string (see https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/replace
2155                 //              for more details).
2156                 //      pattern: RegEx?
2157                 //              Optional regular expression objects that overrides the default pattern.
2158                 //              Must be global and match one item. The default is: /\{([^\}]+)\}/g,
2159                 //              which matches patterns like that: "{xxx}", where "xxx" is any sequence
2160                 //              of characters, which doesn't include "}".
2161                 //      returns: String
2162                 //              Returns the substituted string.
2163                 //      example:
2164                 //      |       // uses a dictionary for substitutions:
2165                 //      |       dojo.replace("Hello, {name.first} {name.last} AKA {nick}!",
2166                 //      |         {
2167                 //      |           nick: "Bob",
2168                 //      |           name: {
2169                 //      |             first:  "Robert",
2170                 //      |             middle: "X",
2171                 //      |             last:   "Cringely"
2172                 //      |           }
2173                 //      |         });
2174                 //      |       // returns: Hello, Robert Cringely AKA Bob!
2175                 //      example:
2176                 //      |       // uses an array for substitutions:
2177                 //      |       dojo.replace("Hello, {0} {2}!",
2178                 //      |         ["Robert", "X", "Cringely"]);
2179                 //      |       // returns: Hello, Robert Cringely!
2180                 //      example:
2181                 //      |       // uses a function for substitutions:
2182                 //      |       function sum(a){
2183                 //      |         var t = 0;
2184                 //      |         dojo.forEach(a, function(x){ t += x; });
2185                 //      |         return t;
2186                 //      |       }
2187                 //      |       dojo.replace(
2188                 //      |         "{count} payments averaging {avg} USD per payment.",
2189                 //      |         dojo.hitch(
2190                 //      |           { payments: [11, 16, 12] },
2191                 //      |           function(_, key){
2192                 //      |             switch(key){
2193                 //      |               case "count": return this.payments.length;
2194                 //      |               case "min":   return Math.min.apply(Math, this.payments);
2195                 //      |               case "max":   return Math.max.apply(Math, this.payments);
2196                 //      |               case "sum":   return sum(this.payments);
2197                 //      |               case "avg":   return sum(this.payments) / this.payments.length;
2198                 //      |             }
2199                 //      |           }
2200                 //      |         )
2201                 //      |       );
2202                 //      |       // prints: 3 payments averaging 13 USD per payment.
2203                 //      example:
2204                 //      |       // uses an alternative PHP-like pattern for substitutions:
2205                 //      |       dojo.replace("Hello, ${0} ${2}!",
2206                 //      |         ["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g);
2207                 //      |       // returns: Hello, Robert Cringely!
2208                 return "";      // String
2209         }
2210         =====*/
2211
2212         var _pattern = /\{([^\}]+)\}/g;
2213         dojo.replace = function(tmpl, map, pattern){
2214                 return tmpl.replace(pattern || _pattern, d.isFunction(map) ?
2215                         map : function(_, k){ return d.getObject(k, false, map); });
2216         };
2217 })();
2218
2219 }
2220
2221 if(!dojo._hasResource["dojo._base.array"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2222 dojo._hasResource["dojo._base.array"] = true;
2223 dojo.provide("dojo._base.array");
2224
2225
2226
2227 (function(){
2228         var _getParts = function(arr, obj, cb){
2229                 return [
2230                         (typeof arr == "string") ? arr.split("") : arr,
2231                         obj || dojo.global,
2232                         // FIXME: cache the anonymous functions we create here?
2233                         (typeof cb == "string") ? new Function("item", "index", "array", cb) : cb
2234                 ];
2235         };
2236
2237         var everyOrSome = function(/*Boolean*/every, /*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
2238                 var _p = _getParts(arr, thisObject, callback); arr = _p[0];
2239                 for(var i=0,l=arr.length; i<l; ++i){
2240                         var result = !!_p[2].call(_p[1], arr[i], i, arr);
2241                         if(every ^ result){
2242                                 return result; // Boolean
2243                         }
2244                 }
2245                 return every; // Boolean
2246         };
2247
2248         dojo.mixin(dojo, {
2249                 indexOf: function(      /*Array*/               array,
2250                                                         /*Object*/              value,
2251                                                         /*Integer?*/    fromIndex,
2252                                                         /*Boolean?*/    findLast){
2253                         // summary:
2254                         //              locates the first index of the provided value in the
2255                         //              passed array. If the value is not found, -1 is returned.
2256                         // description:
2257                         //              This method corresponds to the JavaScript 1.6 Array.indexOf method, with one difference: when
2258                         //              run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
2259                         //              1.6's indexOf skips the holes in the sparse array.
2260                         //              For details on this method, see:
2261                         //                      https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf
2262
2263                         var step = 1, end = array.length || 0, i = 0;
2264                         if(findLast){
2265                                 i = end - 1;
2266                                 step = end = -1;
2267                         }
2268                         if(fromIndex != undefined){ i = fromIndex; }
2269                         if((findLast && i > end) || i < end){
2270                                 for(; i != end; i += step){
2271                                         if(array[i] == value){ return i; }
2272                                 }
2273                         }
2274                         return -1;      // Number
2275                 },
2276
2277                 lastIndexOf: function(/*Array*/array, /*Object*/value, /*Integer?*/fromIndex){
2278                         // summary:
2279                         //              locates the last index of the provided value in the passed
2280                         //              array. If the value is not found, -1 is returned.
2281                         // description:
2282                         //              This method corresponds to the JavaScript 1.6 Array.lastIndexOf method, with one difference: when
2283                         //              run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
2284                         //              1.6's lastIndexOf skips the holes in the sparse array.
2285                         //              For details on this method, see:
2286                         //                      https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/lastIndexOf
2287                         return dojo.indexOf(array, value, fromIndex, true); // Number
2288                 },
2289
2290                 forEach: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
2291                         //      summary:
2292                         //              for every item in arr, callback is invoked. Return values are ignored.
2293                         //              If you want to break out of the loop, consider using dojo.every() or dojo.some().
2294                         //              forEach does not allow breaking out of the loop over the items in arr.
2295                         //      arr:
2296                         //              the array to iterate over. If a string, operates on individual characters.
2297                         //      callback:
2298                         //              a function is invoked with three arguments: item, index, and array
2299                         //      thisObject:
2300                         //              may be used to scope the call to callback
2301                         //      description:
2302                         //              This function corresponds to the JavaScript 1.6 Array.forEach() method, with one difference: when
2303                         //              run over sparse arrays, this implemenation passes the "holes" in the sparse array to
2304                         //              the callback function with a value of undefined. JavaScript 1.6's forEach skips the holes in the sparse array.
2305                         //              For more details, see:
2306                         //                      https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach
2307                         //      example:
2308                         //      |       // log out all members of the array:
2309                         //      |       dojo.forEach(
2310                         //      |               [ "thinger", "blah", "howdy", 10 ],
2311                         //      |               function(item){
2312                         //      |                       console.log(item);
2313                         //      |               }
2314                         //      |       );
2315                         //      example:
2316                         //      |       // log out the members and their indexes
2317                         //      |       dojo.forEach(
2318                         //      |               [ "thinger", "blah", "howdy", 10 ],
2319                         //      |               function(item, idx, arr){
2320                         //      |                       console.log(item, "at index:", idx);
2321                         //      |               }
2322                         //      |       );
2323                         //      example:
2324                         //      |       // use a scoped object member as the callback
2325                         //      |
2326                         //      |       var obj = {
2327                         //      |               prefix: "logged via obj.callback:",
2328                         //      |               callback: function(item){
2329                         //      |                       console.log(this.prefix, item);
2330                         //      |               }
2331                         //      |       };
2332                         //      |
2333                         //      |       // specifying the scope function executes the callback in that scope
2334                         //      |       dojo.forEach(
2335                         //      |               [ "thinger", "blah", "howdy", 10 ],
2336                         //      |               obj.callback,
2337                         //      |               obj
2338                         //      |       );
2339                         //      |
2340                         //      |       // alternately, we can accomplish the same thing with dojo.hitch()
2341                         //      |       dojo.forEach(
2342                         //      |               [ "thinger", "blah", "howdy", 10 ],
2343                         //      |               dojo.hitch(obj, "callback")
2344                         //      |       );
2345
2346                         // match the behavior of the built-in forEach WRT empty arrs
2347                         if(!arr || !arr.length){ return; }
2348
2349                         // FIXME: there are several ways of handilng thisObject. Is
2350                         // dojo.global always the default context?
2351                         var _p = _getParts(arr, thisObject, callback); arr = _p[0];
2352                         for(var i=0,l=arr.length; i<l; ++i){
2353                                 _p[2].call(_p[1], arr[i], i, arr);
2354                         }
2355                 },
2356
2357                 every: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
2358                         // summary:
2359                         //              Determines whether or not every item in arr satisfies the
2360                         //              condition implemented by callback.
2361                         // arr:
2362                         //              the array to iterate on. If a string, operates on individual characters.
2363                         // callback:
2364                         //              a function is invoked with three arguments: item, index,
2365                         //              and array and returns true if the condition is met.
2366                         // thisObject:
2367                         //              may b