]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/javascript/yui3/build/yui/yui.js
Release 6.2.0beta4
[Github/sugarcrm.git] / jssource / src_files / include / javascript / yui3 / build / yui / yui.js
1 /*
2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
5 version: 3.0.0
6 build: 1549
7 */
8 /**
9  * The YUI module contains the components required for building the YUI seed file.
10  * This includes the script loading mechanism, a simple queue, and the core utilities for the library.
11  * @module yui
12  * @submodule yui-base
13  */
14
15 (function() {
16
17     var _instances = {}, 
18         _startTime = new Date().getTime(), 
19         p, 
20         i,
21
22         add = function () {
23             if (window.addEventListener) {
24                 return function(el, type, fn, capture) {
25                     el.addEventListener(type, fn, (!!capture));
26                 };
27             } else if (window.attachEvent) {
28                 return function(el, type, fn) {
29                     el.attachEvent("on" + type, fn);
30                 };
31             } else {
32                 return function(){};
33             }
34         }(),
35
36         remove = function() {
37             if (window.removeEventListener) {
38                 return function (el, type, fn, capture) {
39                     el.removeEventListener(type, fn, !!capture);
40                 };
41             } else if (window.detachEvent) {
42                 return function (el, type, fn) {
43                     el.detachEvent("on" + type, fn);
44                 };
45             } else {
46                 return function(){};
47             }
48         }(),
49
50         globalListener = function() {
51             YUI.Env.windowLoaded = true;
52             YUI.Env.DOMReady = true;
53             remove(window, 'load', globalListener);
54         },
55
56 // @TODO: this needs to be created at build time from module metadata
57
58         _APPLY_TO_WHITE_LIST = {
59           'io.xdrReady': 1,
60           'io.xdrResponse':1
61         },
62
63         SLICE = Array.prototype.slice;
64         
65 // reduce to one or the other
66 if (typeof YUI === 'undefined' || !YUI) {
67
68     /**
69      * The YUI global namespace object.  If YUI is already defined, the
70      * existing YUI object will not be overwritten so that defined
71      * namespaces are preserved.  
72      *
73      * @class YUI
74      * @constructor
75      * @global
76      * @uses EventTarget
77      * @param o* Up to five optional configuration objects.  This object is stored
78      * in YUI.config.  See config for the list of supported properties.
79      */
80
81     /*global YUI*/
82     // Make a function, disallow direct instantiation
83     YUI = function(o1, o2, o3, o4, o5) {
84
85         var Y = this, a = arguments, i, l = a.length;
86
87         // Allow instantiation without the new operator
88         if (!(Y instanceof YUI)) {
89             return new YUI(o1, o2, o3, o4, o5);
90         } else {
91             // set up the core environment
92             Y._init();
93
94             for (i=0; i<l; i++) {
95                 Y._config(a[i]);
96             }
97
98             // bind the specified additional modules for this instance
99             Y._setup();
100
101             return Y;
102         }
103     };
104 }
105
106 // The prototype contains the functions that are required to allow the external
107 // modules to be registered and for the instance to be initialized.
108 YUI.prototype = {
109
110     _config: function(o) {
111
112         o = o || {};
113
114         var c = this.config, i, j, m, mods;
115
116         mods = c.modules;
117         for (i in o) {
118             if (mods && i == 'modules') {
119                 m = o[i];
120                 for (j in m) {
121                     if (m.hasOwnProperty(j)) {
122                         mods[j] = m[j];
123                     }
124                 }
125             } else if (i == 'win') {
126                 c[i] = o[i].contentWindow || o[i];
127                 c.doc = c[i].document;
128             } else {
129                 c[i] = o[i];
130             }
131         }
132     },
133
134     /**
135      * Initialize this YUI instance
136      * @private
137      */
138     _init: function() {
139
140         // find targeted window/frame
141         // @TODO create facades
142         var v = '3.0.0', Y = this;
143
144         if (v.indexOf('@') > -1) {
145             v = 'test';
146         }
147
148         Y.version = v;
149
150         Y.Env = {
151             // @todo expand the new module metadata
152             mods: {},
153             cdn: 'http://yui.yahooapis.com/' + v + '/build/',
154             bootstrapped: false,
155             _idx: 0,
156             _used: {},
157             _attached: {},
158             _yidx: 0,
159             _uidx: 0,
160             _loaded: {}
161         };
162
163         Y.Env._loaded[v] = {};
164
165         if (YUI.Env) {
166             Y.Env._yidx = (++YUI.Env._yidx);
167             Y.Env._guidp = ('yui_' + v + '-' + Y.Env._yidx + '-' + _startTime).replace(/\./g, '_');
168             Y.id = Y.stamp(Y);
169             _instances[Y.id] = Y;
170         }
171
172         Y.constructor = YUI;
173
174         // configuration defaults
175         Y.config = {
176
177             win: window || {},
178             doc: document,
179             debug: true,
180             useBrowserConsole: true,
181             throwFail: true,
182             bootstrap: true,
183             fetchCSS: true,
184         
185             base: function() {
186                 var b, nodes, i, match;
187
188                 // get from querystring
189                 nodes = document.getElementsByTagName('script');
190
191                 for (i=0; i<nodes.length; i=i+1) {
192                     match = nodes[i].src.match(/^(.*)yui\/yui[\.\-].*js(\?.*)?$/);
193                     b = match && match[1];
194                     if (b) {
195                         break;
196                     }
197                 }
198
199                 // use CDN default
200                 return b || Y.Env.cdn;
201
202             }(),
203
204             loaderPath: 'loader/loader-min.js'
205         };
206
207     },
208     
209     /**
210      * Finishes the instance setup. Attaches whatever modules were defined
211      * when the yui modules was registered.
212      * @method _setup
213      * @private
214      */
215     _setup: function(o) {
216         this.use("yui-base");
217     },
218
219     /**
220      * Executes a method on a YUI instance with
221      * the specified id if the specified method is whitelisted.
222      * @method applyTo
223      * @param id {string} the YUI instance id
224      * @param method {string} the name of the method to exectute.
225      * Ex: 'Object.keys'
226      * @param args {Array} the arguments to apply to the method
227      * @return {object} the return value from the applied method or null
228      */
229     applyTo: function(id, method, args) {
230
231         if (!(method in _APPLY_TO_WHITE_LIST)) {
232             this.log(method + ': applyTo not allowed', 'warn', 'yui');
233             return null;
234         }
235
236         var instance = _instances[id], nest, m, i;
237
238         if (instance) {
239
240             nest = method.split('.'); 
241             m = instance;
242
243             for (i=0; i<nest.length; i=i+1) {
244
245                 m = m[nest[i]];
246
247                 if (!m) {
248                     this.log('applyTo not found: ' + method, 'warn', 'yui');
249                 }
250             }
251
252             return m.apply(instance, args);
253         }
254
255         return null;
256     }, 
257
258     /**
259      * Register a module
260      * @method add
261      * @param name {string} module name
262      * @param fn {Function} entry point into the module that
263      * is used to bind module to the YUI instance
264      * @param version {string} version string
265      * @param details optional config data: 
266      * requires   - features that should be present before loading
267      * optional   - optional features that should be present if load optional defined
268      * use  - features that should be attached automatically
269      * skinnable  -
270      * rollup
271      * omit - features that should not be loaded if this module is present
272      * @return {YUI} the YUI instance
273      *
274      */
275     add: function(name, fn, version, details) {
276         // this.log('Adding a new component ' + name);
277         // @todo expand this to include version mapping
278         // @todo may want to restore the build property
279         // @todo fire moduleAvailable event
280         
281         YUI.Env.mods[name] = {
282             name: name, 
283             fn: fn,
284             version: version,
285             details: details || {}
286         };
287
288         return this; // chain support
289     },
290
291     _attach: function(r, fromLoader) {
292
293         var mods = YUI.Env.mods,
294             attached = this.Env._attached,
295             i, l = r.length, name, m, d, req, use;
296
297         for (i=0; i<l; i=i+1) {
298
299             name = r[i]; 
300             m    = mods[name];
301
302             if (!attached[name] && m) {
303
304                 attached[name] = true;
305
306                 d   = m.details; 
307                 req = d.requires; 
308                 use = d.use;
309
310                 if (req) {
311                     this._attach(this.Array(req));
312                 }
313
314                 // this.log('attaching ' + name, 'info', 'yui');
315
316                 if (m.fn) {
317                     m.fn(this);
318                 }
319
320                 if (use) {
321                     this._attach(this.Array(use));
322                 }
323             }
324         }
325
326     },
327
328     /**
329      * Bind a module to a YUI instance
330      * @param modules* {string} 1-n modules to bind (uses arguments array)
331      * @param *callback {function} callback function executed when 
332      * the instance has the required functionality.  If included, it
333      * must be the last parameter.
334      *
335      * @TODO 
336      * Implement versioning?  loader can load different versions?
337      * Should sub-modules/plugins be normal modules, or do
338      * we add syntax for specifying these?
339      *
340      * YUI().use('dragdrop')
341      * YUI().use('dragdrop:2.4.0'); // specific version
342      * YUI().use('dragdrop:2.4.0-'); // at least this version
343      * YUI().use('dragdrop:2.4.0-2.9999.9999'); // version range
344      * YUI().use('*'); // use all available modules
345      * YUI().use('lang+dump+substitute'); // use lang and some plugins
346      * YUI().use('lang+*'); // use lang and all known plugins
347      *
348      *
349      * @return {YUI} the YUI instance
350      */
351     use: function() {
352
353         if (this._loading) {
354             this._useQueue = this._useQueue || new this.Queue();
355             this._useQueue.add(SLICE.call(arguments, 0));
356             return this;
357         }
358
359         var Y = this, 
360             a=SLICE.call(arguments, 0), 
361             mods = YUI.Env.mods, 
362             used = Y.Env._used,
363             loader, 
364             firstArg = a[0], 
365             dynamic = false,
366             callback = a[a.length-1],
367             boot = Y.config.bootstrap,
368             k, i, l, missing = [], 
369             r = [], 
370             css = Y.config.fetchCSS,
371             f = function(name) {
372
373                 // only attach a module once
374                 if (used[name]) {
375                     return;
376                 }
377
378                 var m = mods[name], j, req, use;
379
380                 if (m) {
381
382
383                     used[name] = true;
384
385                     req = m.details.requires;
386                     use = m.details.use;
387                 } else {
388
389                     // CSS files don't register themselves, see if it has been loaded
390                     if (!YUI.Env._loaded[Y.version][name]) {
391                         missing.push(name);
392                     } else {
393                         // probably css
394                         used[name] = true;
395                     }
396                 }
397
398                 // make sure requirements are attached
399                 if (req) {
400                     if (Y.Lang.isString(req)) {
401                         f(req);
402                     } else {
403                         for (j = 0; j < req.length; j = j + 1) {
404                             f(req[j]);
405                         }
406                     }
407                 }
408
409                 // add this module to full list of things to attach
410                 r.push(name);
411
412             },
413
414             onComplete;
415
416
417         // The last argument supplied to use can be a load complete callback
418         if (typeof callback === 'function') {
419             a.pop();
420         } else {
421             callback = null;
422         }
423
424         onComplete = function(fromLoader) {
425
426
427             fromLoader = fromLoader || {
428                 success: true,
429                 msg: 'not dynamic'
430             };
431
432             if (callback) {
433                 callback(Y, fromLoader);
434             }
435
436             if (Y.fire) {
437                 Y.fire('yui:load', Y, fromLoader);
438             }
439
440             // process queued use requests as long until done 
441             // or dynamic load happens again.
442             Y._loading = false;
443
444             if (Y._useQueue && Y._useQueue.size() && !Y._loading) {
445                 Y.use.apply(Y, Y._useQueue.next());
446             }
447         };
448  
449
450         // YUI().use('*'); // bind everything available
451         if (firstArg === "*") {
452             a = [];
453             for (k in mods) {
454                 if (mods.hasOwnProperty(k)) {
455                     a.push(k);
456                 }
457             }
458             
459             if (callback) {
460                 a.push(callback);
461             }
462
463             return Y.use.apply(Y, a);
464         }
465         
466
467         // use loader to expand dependencies and sort the 
468         // requirements if it is available.
469         if (Y.Loader) {
470             dynamic = true;
471             loader = new Y.Loader(Y.config);
472             loader.require(a);
473             loader.ignoreRegistered = true;
474             loader.allowRollup = false;
475             // loader.calculate(null, (css && css == 'force') ? null : 'js');
476             // loader.calculate();
477             loader.calculate(null, (css) ? null : 'js');
478             a = loader.sorted;
479         }
480
481
482         l = a.length;
483
484         // process each requirement and any additional requirements 
485         // the module metadata specifies
486         for (i=0; i<l; i=i+1) {
487             f(a[i]);
488         }
489
490         l = missing.length;
491
492
493         if (l) {
494             missing = Y.Object.keys(Y.Array.hash(missing));
495         }
496
497         // dynamic load
498         if (boot && l && Y.Loader) {
499             Y._loading = true;
500             loader = new Y.Loader(Y.config);
501             loader.onSuccess = onComplete;
502             loader.onFailure = onComplete;
503             loader.onTimeout = onComplete;
504             loader.context = Y;
505             loader.attaching = a;
506             // loader.require(missing);
507             loader.require((css) ? missing : a);
508             loader.insert(null, (css) ? null : 'js');
509         } else if (boot && l && Y.Get && !Y.Env.bootstrapped) {
510             Y._loading = true;
511
512             a = Y.Array(arguments, 0, true);
513             // a.unshift('loader');
514
515             Y.Get.script(Y.config.base + Y.config.loaderPath, {
516                 onEnd: function() {
517                     Y._loading = false;
518                     Y.Env.bootstrapped = true;
519                     Y._attach(['loader']);
520                     Y.use.apply(Y, a);
521                 }
522             });
523
524             return Y;
525
526         } else {
527             if (l) {
528             }
529             Y._attach(r);
530             onComplete();
531         }
532
533         return Y; // chain support var yui = YUI().use('dragdrop');
534     },
535
536
537     /**
538      * Returns the namespace specified and creates it if it doesn't exist
539      * <pre>
540      * YUI.namespace("property.package");
541      * YUI.namespace("YAHOO.property.package");
542      * </pre>
543      * Either of the above would create YUI.property, then
544      * YUI.property.package (YAHOO is scrubbed out, this is
545      * to remain compatible with YUI2)
546      *
547      * Be careful when naming packages. Reserved words may work in some browsers
548      * and not others. For instance, the following will fail in Safari:
549      * <pre>
550      * YUI.namespace("really.long.nested.namespace");
551      * </pre>
552      * This fails because "long" is a future reserved word in ECMAScript
553      *
554      * @method namespace
555      * @param  {string*} arguments 1-n namespaces to create 
556      * @return {object}  A reference to the last namespace object created
557      */
558     namespace: function() {
559         var a=arguments, o=null, i, j, d;
560         for (i=0; i<a.length; i=i+1) {
561             d = ("" + a[i]).split(".");
562             o = this;
563             for (j=(d[0] == "YAHOO") ? 1 : 0; j<d.length; j=j+1) {
564                 o[d[j]] = o[d[j]] || {};
565                 o = o[d[j]];
566             }
567         }
568         return o;
569     },
570
571     // this is replaced if the log module is included
572     log: function() {
573
574     },
575
576     /**
577      * Report an error.  The reporting mechanism is controled by
578      * the 'throwFail' configuration attribute.  If throwFail is
579      * not specified, the message is written to the Logger, otherwise
580      * a JS error is thrown
581      * @method error
582      * @param msg {string} the error message
583      * @param e {Error} Optional JS error that was caught.  If supplied
584      * and throwFail is specified, this error will be re-thrown.
585      * @return {YUI} this YUI instance
586      */
587     error: function(msg, e) {
588         if (this.config.throwFail) {
589             throw (e || new Error(msg)); 
590         } else {
591             this.message(msg, "error"); // don't scrub this one
592         }
593
594         return this;
595     },
596
597     /**
598      * Generate an id that is unique among all YUI instances
599      * @method guid
600      * @param pre {string} optional guid prefix
601      * @return {string} the guid
602      */
603     guid: function(pre) {
604         var id =  this.Env._guidp + (++this.Env._uidx);
605         return (pre) ? (pre + id) : id;
606     },
607
608     /**
609      * Returns a guid associated with an object.  If the object
610      * does not have one, a new one is created unless readOnly
611      * is specified.
612      * @method stamp
613      * @param o The object to stamp
614      * @param readOnly {boolean} if true, a valid guid will only
615      * be returned if the object has one assigned to it.
616      * @return {string} The object's guid or null
617      */
618     stamp: function(o, readOnly) {
619
620         if (!o) {
621             return o;
622         }
623
624         var uid = (typeof o === 'string') ? o : o._yuid;
625
626         if (!uid) {
627             uid = this.guid();
628             if (!readOnly) {
629                 try {
630                     o._yuid = uid;
631                 } catch(e) {
632                     uid = null;
633                 }
634             }
635         }
636
637         return uid;
638     }
639 };
640
641 // Give the YUI global the same properties as an instance.
642 // This makes it so that the YUI global can be used like the YAHOO
643 // global was used prior to 3.x.  More importantly, the YUI global
644 // provides global metadata, so env needs to be configured.
645 // @TODO review
646
647     p = YUI.prototype;
648
649     // inheritance utilities are not available yet
650     for (i in p) {
651         // if (1) { // intenionally ignoring hasOwnProperty check
652         YUI[i] = p[i];
653         // }
654     }
655
656     // set up the environment
657     YUI._init();
658
659     // add a window load event at load time so we can capture
660     // the case where it fires before dynamic loading is
661     // complete.
662     add(window, 'load', globalListener);
663
664     YUI.Env.add = add;
665     YUI.Env.remove = remove;
666
667     /*
668      * Subscribe to an event.  The signature differs depending on the
669      * type of event you are attaching to.
670      * @method on 
671      * @param type {string|function|object} The type of the event.  If
672      * this is a function, this is dispatched to the aop system.  If an
673      * object, it is parsed for multiple subsription definitions
674      * @param fn {Function} The callback
675      * @param elspec {any} DOM element(s), selector string(s), and or
676      * Node ref(s) to attach DOM related events to (only applies to
677      * DOM events).
678      * @param
679      * @return the event target or a detach handle per 'chain' config
680      */
681
682 })();
683
684 /**
685  * The config object contains all of the configuration options for
686  * the YUI instance.  This object is supplied by the implementer 
687  * when instantiating a YUI instance.  Some properties have default
688  * values if they are not supplied by the implementer.
689  *
690  * @class config
691  * @static
692  */
693
694 /**
695  * Allows the YUI seed file to fetch the loader component and library
696  * metadata to dynamically load additional dependencies.
697  *
698  * @property bootstrap
699  * @type boolean
700  * @default true
701  */
702
703 /**
704  * Log to the browser console if debug is on and the browser has a
705  * supported console.
706  *
707  * @property useBrowserConsole
708  * @type boolean
709  * @default true
710  */
711
712 /**
713  * A hash of log sources that should be logged.  If specified, only log messages from these sources will be logged.
714  *
715  * @property logInclude
716  * @type object
717  */
718
719 /**
720  * A hash of log sources that should be not be logged.  If specified, all sources are logged if not on this list.
721  *
722  * @property logExclude
723  * @type object
724  */
725
726 /**
727  * Set to true if the yui seed file was dynamically loaded in 
728  * order to bootstrap components relying on the window load event 
729  * and the 'domready' custom event.
730  *
731  * @property injected
732  * @type object
733  */
734
735 /**
736  * If throwFail is set, Y.fail will generate or re-throw a JS Error.  Otherwise the failure is logged.
737  *
738  * @property throwFail
739  * @type boolean
740  * @default true
741  */
742
743 /**
744  * The window/frame that this instance should operate in.
745  *
746  * @property win
747  * @type Window
748  * @default the window hosting YUI
749  */
750
751 /**
752  * The document associated with the 'win' configuration.
753  *
754  * @property doc
755  * @type Document
756  * @default the document hosting YUI
757  */
758
759 /**
760  * A list of modules that defines the YUI core (overrides the default).
761  *
762  * @property core
763  * @type string[]
764  */
765
766 /**
767  * The default date format
768  *
769  * @property dateFormat
770  * @type string
771  */
772
773 /**
774  * The default locale
775  *
776  * @property locale
777  * @type string
778  */
779
780 /**
781  * The default interval when polling in milliseconds.
782  *
783  * @property pollInterval
784  * @type int
785  * @default 20
786  */
787
788 /**
789  * The number of dynamic nodes to insert by default before
790  * automatically removing them.  This applies to script nodes
791  * because remove the node will not make the evaluated script
792  * unavailable.  Dynamic CSS is not auto purged, because removing
793  * a linked style sheet will also remove the style definitions.
794  *
795  * @property purgethreshold
796  * @type int
797  * @default 20
798  */
799
800 /**
801  * The default interval when polling in milliseconds.
802  *
803  * @property windowResizeDelay
804  * @type int
805  * @default 40
806  */
807
808 /**
809  * Base directory for dynamic loading
810  *
811  * @property base
812  * @type string
813  */
814
815 /**
816  * The secure base dir (not implemented)
817  *
818  * For dynamic loading.
819  *
820  * @property secureBase
821  * @type string
822  */
823
824 /**
825  * The YUI combo service base dir. Ex: http://yui.yahooapis.com/combo?
826  *
827  * For dynamic loading.
828  *
829  * @property comboBase
830  * @type string
831  */
832
833 /**
834  * The root path to prepend to module names for the combo service. Ex: 3.0.0b1/build/
835  *
836  * For dynamic loading.
837  *
838  * @property root
839  * @type string
840  */
841
842 /**
843  * A filter to apply to result urls.  This filter will modify the default
844  * path for all modules.  The default path for the YUI library is the
845  * minified version of the files (e.g., event-min.js).  The filter property
846  * can be a predefined filter or a custom filter.  The valid predefined 
847  * filters are:
848  * <dl>
849  *  <dt>DEBUG</dt>
850  *  <dd>Selects the debug versions of the library (e.g., event-debug.js).
851  *      This option will automatically include the Logger widget</dd>
852  *  <dt>RAW</dt>
853  *  <dd>Selects the non-minified version of the library (e.g., event.js).</dd>
854  * </dl>
855  * You can also define a custom filter, which must be an object literal 
856  * containing a search expression and a replace string:
857  * <pre>
858  *  myFilter: &#123; 
859  *      'searchExp': "-min\\.js", 
860  *      'replaceStr': "-debug.js"
861  *  &#125;
862  * </pre>
863  *
864  * For dynamic loading.
865  *
866  * @property filter
867  * @type string|object
868  */
869
870 /**
871  * Hash of per-component filter specification.  If specified for a given component, 
872  * this overrides the filter config
873  *
874  * For dynamic loading.
875  *
876  * @property filters
877  * @type object
878  */
879
880 /**
881  * Use the YUI combo service to reduce the number of http connections 
882  * required to load your dependencies.
883  *
884  * For dynamic loading.
885  *
886  * @property combine
887  * @type boolean
888  * @default true if 'base' is not supplied, false if it is.
889  */
890
891 /**
892  * A list of modules that should never be dynamically loaded
893  *
894  * @property ignore
895  * @type string[]
896  */
897
898 /**
899  * A list of modules that should always be loaded when required, even if already 
900  * present on the page.
901  *
902  * @property force
903  * @type string[]
904  */
905
906 /**
907  * Node or id for a node that should be used as the insertion point for new nodes
908  * For dynamic loading.
909  *
910  * @property insertBefore
911  * @type string
912  */
913
914 /**
915  * charset for dynamic nodes
916  *
917  * @property charset
918  * @type string
919  * @deprecated use jsAttributes cssAttributes
920  */
921
922 /**
923  * Object literal containing attributes to add to dynamically loaded script nodes.
924  *
925  * @property jsAttributes
926  * @type string
927  */
928
929 /**
930  * Object literal containing attributes to add to dynamically loaded link nodes.
931  *
932  * @property cssAttributes
933  * @type string
934  */
935
936 /**
937  * Number of milliseconds before a timeout occurs when dynamically 
938  * loading nodes. If not set, there is no timeout.
939  *
940  * @property timeout
941  * @type int
942  */
943
944 /**
945  * Callback for the 'CSSComplete' event.  When dynamically loading YUI 
946  * components with CSS, this property fires when the CSS is finished
947  * loading but script loading is still ongoing.  This provides an
948  * opportunity to enhance the presentation of a loading page a little
949  * bit before the entire loading process is done.
950  *
951  * @property onCSS
952  * @type function
953  */
954
955 /**
956  * A list of module definitions to add to the list of YUI components.  
957  * These components can then be dynamically loaded side by side with
958  * YUI via the use() method.See Loader.addModule for the supported
959  * module metadata.
960  *
961  * @property modules
962  * @type function
963  */
964  
965 /**
966  * The loader 'path' attribute to the loader itself.  This is combined
967  * with the 'base' attribute to dynamically load the loader component
968  * when boostrapping with the get utility alone.
969  *
970  * @property loaderPath
971  * @default loader/loader-min.js
972  */
973
974 /**
975  * 
976  * Specifies whether or not YUI().use(...) will attempt to load CSS
977  * resources at all.  Any truthy value will cause CSS dependencies
978  * to load when fetching script.  The special value 'force' will 
979  * cause CSS dependencies to be loaded even if no script is needed.
980  *
981  * @property fetchCSS
982  * @default true
983  */
984 YUI.add('yui-base', function(Y) {
985
986 /*
987  * YUI stub
988  * @module yui
989  * @submodule yui-base
990  */
991 /**
992  * The YUI module contains the components required for building the YUI seed file.
993  * This includes the script loading mechanism, a simple queue, and the core utilities for the library.
994  * @module yui
995  * @submodule yui-base
996  */
997
998 /**
999  * A simple FIFO queue.  Items are added to the Queue with add(1..n items) and
1000  * removed using next().
1001  *
1002  * @class Queue
1003  * @param item* {MIXED} 0..n items to seed the queue
1004  */
1005 function Queue() {
1006     this._init();
1007     this.add.apply(this, arguments);
1008 }
1009
1010 Queue.prototype = {
1011     /**
1012      * Initialize the queue
1013      *
1014      * @method _init
1015      * @protected
1016      */
1017     _init : function () {
1018         /**
1019          * The collection of enqueued items
1020          *
1021          * @property _q
1022          * @type {Array}
1023          * @protected
1024          */
1025         this._q = [];
1026     },
1027
1028     /**
1029      * Get the next item in the queue.
1030      *
1031      * @method next
1032      * @return {MIXED} the next item in the queue
1033      */
1034     next : function () {
1035         return this._q.shift();
1036     },
1037
1038     /**
1039      * Add 0..n items to the end of the queue
1040      *
1041      * @method add
1042      * @param item* {MIXED} 0..n items
1043      */
1044     add : function () {
1045         Y.Array.each(Y.Array(arguments,0,true),function (fn) {
1046             this._q.push(fn);
1047         },this);
1048
1049         return this;
1050     },
1051
1052     /**
1053      * Returns the current number of queued items
1054      *
1055      * @method size
1056      * @return {Number}
1057      */
1058     size : function () {
1059         return this._q.length;
1060     }
1061 };
1062
1063 Y.Queue = Queue;
1064 /**
1065  * The YUI module contains the components required for building the YUI seed file.
1066  * This includes the script loading mechanism, a simple queue, and the core utilities for the library.
1067  * @module yui
1068  * @submodule yui-base
1069  */
1070 (function() {
1071 /**
1072  * Provides the language utilites and extensions used by the library
1073  * @class Lang
1074  * @static
1075  */
1076 Y.Lang    = Y.Lang || {};
1077
1078 var L     = Y.Lang, 
1079
1080 ARRAY     = 'array',
1081 BOOLEAN   = 'boolean',
1082 DATE      = 'date',
1083 ERROR     = 'error',
1084 FUNCTION  = 'function',
1085 NUMBER    = 'number',
1086 NULL      = 'null',
1087 OBJECT    = 'object',
1088 REGEX     = 'regexp',
1089 STRING    = 'string',
1090 TOSTRING  = Object.prototype.toString,
1091 UNDEFINED = 'undefined',
1092
1093 TYPES     = {
1094     'undefined'         : UNDEFINED,
1095     'number'            : NUMBER,
1096     'boolean'           : BOOLEAN,
1097     'string'            : STRING,
1098     '[object Function]' : FUNCTION,
1099     '[object RegExp]'   : REGEX,
1100     '[object Array]'    : ARRAY,
1101     '[object Date]'     : DATE,
1102     '[object Error]'    : ERROR 
1103 },
1104
1105 TRIMREGEX = /^\s+|\s+$/g,
1106 EMPTYSTRING = '';
1107
1108 /**
1109  * Determines whether or not the provided item is an array.
1110  * Returns false for array-like collections such as the
1111  * function arguments collection or HTMLElement collection
1112  * will return false.  You can use @see Array.test if you 
1113  * want to
1114  * @method isArray
1115  * @static
1116  * @param o The object to test
1117  * @return {boolean} true if o is an array
1118  */
1119 L.isArray = function(o) { 
1120     return L.type(o) === ARRAY;
1121 };
1122
1123 /**
1124  * Determines whether or not the provided item is a boolean
1125  * @method isBoolean
1126  * @static
1127  * @param o The object to test
1128  * @return {boolean} true if o is a boolean
1129  */
1130 L.isBoolean = function(o) {
1131     return typeof o === BOOLEAN;
1132 };
1133
1134 /**
1135  * Determines whether or not the provided item is a function
1136  * Note: Internet Explorer thinks certain functions are objects:
1137  *
1138  * var obj = document.createElement("object");
1139  * Y.Lang.isFunction(obj.getAttribute) // reports false in IE
1140  *
1141  * var input = document.createElement("input"); // append to body
1142  * Y.Lang.isFunction(input.focus) // reports false in IE
1143  *
1144  * You will have to implement additional tests if these functions
1145  * matter to you.
1146  *
1147  * @method isFunction
1148  * @static
1149  * @param o The object to test
1150  * @return {boolean} true if o is a function
1151  */
1152 L.isFunction = function(o) {
1153     return L.type(o) === FUNCTION;
1154 };
1155     
1156 /**
1157  * Determines whether or not the supplied item is a date instance
1158  * @method isDate
1159  * @static
1160  * @param o The object to test
1161  * @return {boolean} true if o is a date
1162  */
1163 L.isDate = function(o) {
1164     // return o instanceof Date;
1165     return L.type(o) === DATE;
1166 };
1167
1168 /**
1169  * Determines whether or not the provided item is null
1170  * @method isNull
1171  * @static
1172  * @param o The object to test
1173  * @return {boolean} true if o is null
1174  */
1175 L.isNull = function(o) {
1176     return o === null;
1177 };
1178     
1179 /**
1180  * Determines whether or not the provided item is a legal number
1181  * @method isNumber
1182  * @static
1183  * @param o The object to test
1184  * @return {boolean} true if o is a number
1185  */
1186 L.isNumber = function(o) {
1187     return typeof o === NUMBER && isFinite(o);
1188 };
1189   
1190 /**
1191  * Determines whether or not the provided item is of type object
1192  * or function
1193  * @method isObject
1194  * @static
1195  * @param o The object to test
1196  * @param failfn {boolean} fail if the input is a function
1197  * @return {boolean} true if o is an object
1198  */  
1199 L.isObject = function(o, failfn) {
1200 return (o && (typeof o === OBJECT || (!failfn && L.isFunction(o)))) || false;
1201 };
1202     
1203 /**
1204  * Determines whether or not the provided item is a string
1205  * @method isString
1206  * @static
1207  * @param o The object to test
1208  * @return {boolean} true if o is a string
1209  */
1210 L.isString = function(o) {
1211     return typeof o === STRING;
1212 };
1213     
1214 /**
1215  * Determines whether or not the provided item is undefined
1216  * @method isUndefined
1217  * @static
1218  * @param o The object to test
1219  * @return {boolean} true if o is undefined
1220  */
1221 L.isUndefined = function(o) {
1222     return typeof o === UNDEFINED;
1223 };
1224
1225 /**
1226  * Returns a string without any leading or trailing whitespace.  If 
1227  * the input is not a string, the input will be returned untouched.
1228  * @method trim
1229  * @static
1230  * @param s {string} the string to trim
1231  * @return {string} the trimmed string
1232  */
1233 L.trim = function(s){
1234     try {
1235         return s.replace(TRIMREGEX, EMPTYSTRING);
1236     } catch(e) {
1237         return s;
1238     }
1239 };
1240
1241 /**
1242  * A convenience method for detecting a legitimate non-null value.
1243  * Returns false for null/undefined/NaN, true for other values, 
1244  * including 0/false/''
1245  * @method isValue
1246  * @static
1247  * @param o The item to test
1248  * @return {boolean} true if it is not null/undefined/NaN || false
1249  */
1250 L.isValue = function(o) {
1251     var t = L.type(o);
1252     switch (t) {
1253         case NUMBER:
1254             return isFinite(o);
1255         case NULL:
1256         case UNDEFINED:
1257             return false;
1258         default:
1259             return !!(t);
1260     }
1261 };
1262
1263 /**
1264  * Returns a string representing the type of the item passed in.
1265  * @method type
1266  * @param o the item to test
1267  * @return {string} the detected type
1268  */
1269 L.type = function (o) {
1270     return  TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? OBJECT : NULL);
1271 };
1272
1273 })();
1274
1275 /**
1276  * The YUI module contains the components required for building the YUI seed file.
1277  * This includes the script loading mechanism, a simple queue, and the core utilities for the library.
1278  * @module yui
1279  * @submodule yui-base
1280  */
1281
1282 (function() {
1283
1284 var L = Y.Lang, Native = Array.prototype,
1285
1286 /**
1287  * Adds the following array utilities to the YUI instance.  Additional
1288  * array helpers can be found in the collection component.
1289  * @class Array
1290  */
1291
1292 /** 
1293  * Y.Array(o) returns an array:
1294  * - Arrays are return unmodified unless the start position is specified.
1295  * - "Array-like" collections (@see Array.test) are converted to arrays
1296  * - For everything else, a new array is created with the input as the sole item
1297  * - The start position is used if the input is or is like an array to return
1298  *   a subset of the collection.
1299  *
1300  *   @TODO this will not automatically convert elements that are also collections
1301  *   such as forms and selects.  Passing true as the third param will
1302  *   force a conversion.
1303  *
1304  * @method ()
1305  * @static
1306  *   @param o the item to arrayify
1307  *   @param i {int} if an array or array-like, this is the start index
1308  *   @param al {boolean} if true, it forces the array-like fork.  This
1309  *   can be used to avoid multiple array.test calls.
1310  *   @return {Array} the resulting array
1311  */
1312 YArray = function(o, startIdx, al) {
1313     var t = (al) ? 2 : Y.Array.test(o), i, l, a;
1314
1315     // switch (t) {
1316     //     case 1:
1317     //         // return (startIdx) ? o.slice(startIdx) : o;
1318     //     case 2:
1319     //         return Native.slice.call(o, startIdx || 0);
1320     //     default:
1321     //         return [o];
1322     // }
1323
1324     if (t) {
1325         try {
1326             return Native.slice.call(o, startIdx || 0);
1327         // IE errors when trying to slice element collections
1328         } catch(e) {
1329             a=[];
1330             for (i=0, l=o.length; i<l; i=i+1) {
1331                 a.push(o[i]);
1332             }
1333             return a;
1334         }
1335     } else {
1336         return [o];
1337     }
1338
1339 };
1340
1341 Y.Array = YArray;
1342
1343 /** 
1344  * Evaluates the input to determine if it is an array, array-like, or 
1345  * something else.  This is used to handle the arguments collection 
1346  * available within functions, and HTMLElement collections
1347  *
1348  * @method test
1349  * @static
1350  *
1351  * @todo current implementation (intenionally) will not implicitly 
1352  * handle html elements that are array-like (forms, selects, etc).  
1353  *
1354  * @return {int} a number indicating the results:
1355  * 0: Not an array or an array-like collection
1356  * 1: A real array. 
1357  * 2: array-like collection.
1358  */
1359 YArray.test = function(o) {
1360     var r = 0;
1361     if (L.isObject(o)) {
1362         if (L.isArray(o)) {
1363             r = 1; 
1364         } else {
1365             try {
1366                 // indexed, but no tagName (element) or alert (window)
1367                 if ("length" in o && !("tagName" in o) && !("alert" in o) && 
1368                     (!Y.Lang.isFunction(o.size) || o.size() > 1)) {
1369                     r = 2;
1370                 }
1371                     
1372             } catch(e) {}
1373         }
1374     }
1375     return r;
1376 };
1377
1378 /**
1379  * Executes the supplied function on each item in the array.
1380  * @method each
1381  * @param a {Array} the array to iterate
1382  * @param f {Function} the function to execute on each item.  The 
1383  * function receives three arguments: the value, the index, the full array.
1384  * @param o Optional context object
1385  * @static
1386  * @return {YUI} the YUI instance
1387  */
1388 YArray.each = (Native.forEach) ?
1389     function (a, f, o) { 
1390         Native.forEach.call(a || [], f, o || Y);
1391         return Y;
1392     } :
1393     function (a, f, o) { 
1394         var l = (a && a.length) || 0, i;
1395         for (i = 0; i < l; i=i+1) {
1396             f.call(o || Y, a[i], i, a);
1397         }
1398         return Y;
1399     };
1400
1401 /**
1402  * Returns an object using the first array as keys, and
1403  * the second as values.  If the second array is not
1404  * provided the value is set to true for each.
1405  * @method hash
1406  * @static
1407  * @param k {Array} keyset
1408  * @param v {Array} optional valueset
1409  * @return {object} the hash
1410  */
1411 YArray.hash = function(k, v) {
1412     var o = {}, l = k.length, vl = v && v.length, i;
1413     for (i=0; i<l; i=i+1) {
1414         o[k[i]] = (vl && vl > i) ? v[i] : true;
1415     }
1416
1417     return o;
1418 };
1419
1420 /**
1421  * Returns the index of the first item in the array
1422  * that contains the specified value, -1 if the
1423  * value isn't found.
1424  * @method indexOf
1425  * @static
1426  * @param a {Array} the array to search
1427  * @param val the value to search for
1428  * @return {int} the index of the item that contains the value or -1
1429  */
1430 YArray.indexOf = (Native.indexOf) ?
1431     function(a, val) {
1432         return Native.indexOf.call(a, val);
1433     } :
1434     function(a, val) {
1435         for (var i=0; i<a.length; i=i+1) {
1436             if (a[i] === val) {
1437                 return i;
1438             }
1439         }
1440
1441         return -1;
1442     };
1443
1444 /**
1445  * Numeric sort convenience function.
1446  * Y.ArrayAssert.itemsAreEqual([1, 2, 3], [3, 1, 2].sort(Y.Array.numericSort));
1447  * @method numericSort
1448  */
1449 YArray.numericSort = function(a, b) { 
1450     return (a - b); 
1451 };
1452
1453 /**
1454  * Executes the supplied function on each item in the array.
1455  * Returning true from the processing function will stop the 
1456  * processing of the remaining
1457  * items.
1458  * @method some
1459  * @param a {Array} the array to iterate
1460  * @param f {Function} the function to execute on each item. The function 
1461  * receives three arguments: the value, the index, the full array.
1462  * @param o Optional context object
1463  * @static
1464  * @return {boolean} true if the function returns true on
1465  * any of the items in the array
1466  */
1467  YArray.some = (Native.some) ?
1468     function (a, f, o) { 
1469         return Native.some.call(a, f, o);
1470     } :
1471     function (a, f, o) {
1472         var l = a.length, i;
1473         for (i=0; i<l; i=i+1) {
1474             if (f.call(o, a[i], i, a)) {
1475                 return true;
1476             }
1477         }
1478         return false;
1479     };
1480
1481 })();
1482
1483
1484 /**
1485  * The YUI module contains the components required for building the YUI seed file.
1486  * This includes the script loading mechanism, a simple queue, and the core utilities for the library.
1487  * @module yui
1488  * @submodule yui-base
1489  */
1490
1491 (function() {
1492
1493 var L = Y.Lang, 
1494 DELIMITER = '__',
1495 // FROZEN = {
1496 //     'prototype': 1,
1497 //     '_yuid': 1
1498 // },
1499
1500 /*
1501  * IE will not enumerate native functions in a derived object even if the
1502  * function was overridden.  This is a workaround for specific functions 
1503  * we care about on the Object prototype. 
1504  * @property _iefix
1505  * @for YUI
1506  * @param {Function} r  the object to receive the augmentation
1507  * @param {Function} s  the object that supplies the properties to augment
1508  * @private
1509  */
1510 _iefix = function(r, s) {
1511     var fn = s.toString;
1512     if (L.isFunction(fn) && fn != Object.prototype.toString) {
1513         r.toString = fn;
1514     }
1515 };
1516
1517
1518 /**
1519  * Returns a new object containing all of the properties of
1520  * all the supplied objects.  The properties from later objects
1521  * will overwrite those in earlier objects.  Passing in a
1522  * single object will create a shallow copy of it.  For a deep
1523  * copy, use clone.
1524  * @method merge
1525  * @for YUI
1526  * @param arguments {Object*} the objects to merge
1527  * @return {object} the new merged object
1528  */
1529 Y.merge = function() {
1530     var a = arguments, o = {}, i, l = a.length;
1531     for (i=0; i<l; i=i+1) {
1532         Y.mix(o, a[i], true);
1533     }
1534     return o;
1535 };
1536    
1537 /**
1538  * Applies the supplier's properties to the receiver.  By default
1539  * all prototype and static propertes on the supplier are applied
1540  * to the corresponding spot on the receiver.  By default all
1541  * properties are applied, and a property that is already on the
1542  * reciever will not be overwritten.  The default behavior can
1543  * be modified by supplying the appropriate parameters.
1544  *
1545  * @TODO add constants for the modes
1546  *
1547  * @method mix
1548  * @param {Function} r  the object to receive the augmentation
1549  * @param {Function} s  the object that supplies the properties to augment
1550  * @param ov {boolean} if true, properties already on the receiver
1551  * will be overwritten if found on the supplier.
1552  * @param wl {string[]} a whitelist.  If supplied, only properties in 
1553  * this list will be applied to the receiver.
1554  * @param {int} mode what should be copies, and to where
1555  *        default(0): object to object
1556  *        1: prototype to prototype (old augment)
1557  *        2: prototype to prototype and object props (new augment)
1558  *        3: prototype to object
1559  *        4: object to prototype
1560  * @param merge {boolean} merge objects instead of overwriting/ignoring
1561  * Used by Y.aggregate
1562  * @return {object} the augmented object
1563  */
1564 Y.mix = function(r, s, ov, wl, mode, merge) {
1565
1566     if (!s||!r) {
1567         return r || Y;
1568     }
1569
1570     if (mode) {
1571         switch (mode) {
1572             case 1: // proto to proto
1573                 return Y.mix(r.prototype, s.prototype, ov, wl, 0, merge);
1574             case 2: // object to object and proto to proto
1575                 Y.mix(r.prototype, s.prototype, ov, wl, 0, merge);
1576                 break; // pass through 
1577             case 3: // proto to static
1578                 return Y.mix(r, s.prototype, ov, wl, 0, merge);
1579             case 4: // static to proto
1580                 return Y.mix(r.prototype, s, ov, wl, 0, merge);
1581             default:  // object to object is what happens below
1582         }
1583     }
1584
1585     // Maybe don't even need this wl && wl.length check anymore??
1586     var arr = merge && L.isArray(r), i, l, p;
1587
1588     if (wl && wl.length) {
1589         for (i = 0, l = wl.length; i < l; ++i) {
1590             p = wl[i];
1591             if (p in s) {
1592                 if (merge && L.isObject(r[p], true)) {
1593                     Y.mix(r[p], s[p]);
1594                 } else if (!arr && (ov || !(p in r))) {
1595                     r[p] = s[p];
1596                 } else if (arr) {
1597                     r.push(s[p]);
1598                 }
1599             }
1600         }
1601     } else {
1602         for (i in s) { 
1603             // if (s.hasOwnProperty(i) && !(i in FROZEN)) {
1604                 // check white list if it was supplied
1605                 // if the receiver has this property, it is an object,
1606                 // and merge is specified, merge the two objects.
1607                 if (merge && L.isObject(r[i], true)) {
1608                     Y.mix(r[i], s[i]); // recursive
1609                 // otherwise apply the property only if overwrite
1610                 // is specified or the receiver doesn't have one.
1611                 } else if (!arr && (ov || !(i in r))) {
1612                     r[i] = s[i];
1613                 // if merge is specified and the receiver is an array,
1614                 // append the array item
1615                 } else if (arr) {
1616                     r.push(s[i]);
1617                 }
1618             // }
1619         }
1620     
1621         if (Y.UA.ie) {
1622             _iefix(r, s);
1623         }
1624     }
1625
1626     return r;
1627 };
1628
1629 /**
1630  * Returns a wrapper for a function which caches the
1631  * return value of that function, keyed off of the combined 
1632  * argument values.
1633  * @function cached
1634  * @param source {function} the function to memoize
1635  * @param cache an optional cache seed
1636  * @param refetch if supplied, this value is tested against the cached
1637  * value.  If the values are equal, the wrapped function is executed again.
1638  * @return {Function} the wrapped function
1639  */
1640 Y.cached = function(source, cache, refetch){
1641     cache = cache || {};
1642
1643     return function(arg1, arg2) {
1644
1645         var k = (arg2) ? Array.prototype.join.call(arguments, DELIMITER) : arg1,
1646             v = cache[k];
1647
1648         if (!(k in cache) || (refetch && cache[k] == refetch)) {
1649             cache[k] = source.apply(source, arguments);
1650         }
1651
1652         return cache[k];
1653     };
1654
1655 };
1656
1657 })();
1658
1659 /**
1660  * The YUI module contains the components required for building the YUI seed file.
1661  * This includes the script loading mechanism, a simple queue, and the core utilities for the library.
1662  * @module yui
1663  * @submodule yui-base
1664  */
1665 (function() {
1666
1667 /**
1668  * Adds the following Object utilities to the YUI instance
1669  * @class Object
1670  */
1671
1672 /**
1673  * Y.Object(o) returns a new object based upon the supplied object.  
1674  * @TODO Use native Object.create() when available
1675  * @method ()
1676  * @static
1677  * @param o the supplier object
1678  * @return {Object} the new object
1679  */
1680 Y.Object = function(o) {
1681     var F = function() {};
1682     F.prototype = o;
1683     return new F();
1684 }; 
1685
1686 var O = Y.Object,
1687
1688 UNDEFINED = undefined,
1689
1690 /**
1691  * Extracts the keys, values, or size from an object
1692  * 
1693  * @method _extract
1694  * @param o the object
1695  * @param what what to extract (0: keys, 1: values, 2: size)
1696  * @return {boolean|Array} the extracted info
1697  * @static
1698  * @private
1699  */
1700 _extract = function(o, what) {
1701     var count = (what === 2), out = (count) ? 0 : [], i;
1702
1703     for (i in o) {
1704         if (count) {
1705             out++;
1706         } else {
1707             if (o.hasOwnProperty(i)) {
1708                 out.push((what) ? o[i] : i);
1709             }
1710         }
1711     }
1712
1713     return out;
1714 };
1715
1716 /**
1717  * Returns an array containing the object's keys
1718  * @TODO use native Object.keys() if available
1719  * @method keys
1720  * @static
1721  * @param o an object
1722  * @return {string[]} the keys
1723  */
1724 O.keys = function(o) {
1725     return _extract(o);
1726 };
1727
1728 /**
1729  * Returns an array containing the object's values
1730  * @TODO use native Object.values() if available
1731  * @method values
1732  * @static
1733  * @param o an object
1734  * @return {Array} the values
1735  */
1736 O.values = function(o) {
1737     return _extract(o, 1);
1738 };
1739
1740 /**
1741  * Returns the size of an object
1742  * @TODO use native Object.size() if available
1743  * @method size
1744  * @static
1745  * @param o an object
1746  * @return {int} the size
1747  */
1748 O.size = function(o) {
1749     return _extract(o, 2);
1750 };
1751
1752 /**
1753  * Returns true if the object contains a given key
1754  * @method hasKey
1755  * @static
1756  * @param o an object
1757  * @param k the key to query
1758  * @return {boolean} true if the object contains the key
1759  */
1760 O.hasKey = function(o, k) {
1761     // return (o.hasOwnProperty(k));
1762     return (k in o);
1763 };
1764
1765 /**
1766  * Returns true if the object contains a given value
1767  * @method hasValue
1768  * @static
1769  * @param o an object
1770  * @param v the value to query
1771  * @return {boolean} true if the object contains the value
1772  */
1773 O.hasValue = function(o, v) {
1774     return (Y.Array.indexOf(O.values(o), v) > -1);
1775 };
1776
1777 /**
1778  * Determines whether or not the property was added
1779  * to the object instance.  Returns false if the property is not present
1780  * in the object, or was inherited from the prototype.
1781  *
1782  * @deprecated Safari 1.x support has been removed, so this is simply a 
1783  * wrapper for the native implementation.  Use the native implementation
1784  * directly instead.
1785  *
1786  * @TODO Remove in B1
1787  *
1788  * @method owns
1789  * @static
1790  * @param o {any} The object being testing
1791  * @param p {string} the property to look for
1792  * @return {boolean} true if the object has the property on the instance
1793  */
1794 O.owns = function(o, k) {
1795     return (o.hasOwnProperty(k));
1796 };
1797
1798 /**
1799  * Executes a function on each item. The function
1800  * receives the value, the key, and the object
1801  * as paramters (in that order).
1802  * @method each
1803  * @static
1804  * @param o the object to iterate
1805  * @param f {Function} the function to execute on each item. The function 
1806  * receives three arguments: the value, the the key, the full object.
1807  * @param c the execution context
1808  * @param proto {boolean} include proto
1809  * @return {YUI} the YUI instance
1810  */
1811 O.each = function (o, f, c, proto) {
1812     var s = c || Y, i;
1813
1814     for (i in o) {
1815         if (proto || o.hasOwnProperty(i)) {
1816             f.call(s, o[i], i, o);
1817         }
1818     }
1819     return Y;
1820 };
1821
1822 /*
1823  * Executes a function on each item, but halts if the
1824  * function returns true.  The function
1825  * receives the value, the key, and the object
1826  * as paramters (in that order).
1827  * @method some
1828  * @static
1829  * @param o the object to iterate
1830  * @param f {Function} the function to execute on each item. The function 
1831  * receives three arguments: the value, the the key, the full object.
1832  * @param c the execution context
1833  * @param proto {boolean} include proto
1834  * @return {boolean} true if any execution of the function returns true, false otherwise
1835  */
1836 // O.some = function (o, f, c, proto) {
1837 //     var s = c || Y, i;
1838 // 
1839 //     for (i in o) {
1840 //         if (proto || o.hasOwnProperty(i)) {
1841 //             if (f.call(s, o[i], i, o)) {
1842 //                 return true;
1843 //             }
1844 //         }
1845 //     }
1846 //     return false;
1847 // };
1848
1849 /**
1850  * Retrieves the sub value at the provided path,
1851  * from the value object provided.
1852  *
1853  * @method getValue
1854  * @param o The object from which to extract the property value
1855  * @param path {Array} A path array, specifying the object traversal path
1856  * from which to obtain the sub value.
1857  * @return {Any} The value stored in the path, undefined if not found.
1858  * Returns the source object if an empty path is provided.
1859  */
1860 O.getValue = function (o, path) {
1861     var p=Y.Array(path), l=p.length, i;
1862
1863     for (i=0; o !== UNDEFINED && i < l; i=i+1) {
1864         o = o[p[i]];
1865     }
1866
1867     return o;
1868 };
1869
1870 /**
1871  * Sets the sub-attribute value at the provided path on the 
1872  * value object.  Returns the modified value object, or 
1873  * undefined if the path is invalid.
1874  *
1875  * @method setValue
1876  * @param o             The object on which to set the sub value.
1877  * @param path {Array}  A path array, specifying the object traversal path
1878  *                      at which to set the sub value.
1879  * @param val {Any}     The new value for the sub-attribute.
1880  * @return {Object}     The modified object, with the new sub value set, or 
1881  *                      undefined, if the path was invalid.
1882  */
1883 O.setValue = function(o, path, val) {
1884
1885     var p=Y.Array(path), leafIdx=p.length-1, i, ref=o;
1886
1887     if (leafIdx >= 0) {
1888         for (i=0; ref !== UNDEFINED && i < leafIdx; i=i+1) {
1889             ref = ref[p[i]];
1890         }
1891
1892         if (ref !== UNDEFINED) {
1893             ref[p[i]] = val;
1894         } else {
1895             return UNDEFINED;
1896         }
1897     }
1898
1899     return o;
1900 };
1901
1902
1903 })();
1904
1905 /**
1906  * The YUI module contains the components required for building the YUI seed file.
1907  * This includes the script loading mechanism, a simple queue, and the core utilities for the library.
1908  * @module yui
1909  * @submodule yui-base
1910  */
1911
1912 /**
1913  * YUI user agent detection.
1914  * Do not fork for a browser if it can be avoided.  Use feature detection when
1915  * you can.  Use the user agent as a last resort.  UA stores a version
1916  * number for the browser engine, 0 otherwise.  This value may or may not map
1917  * to the version number of the browser using the engine.  The value is 
1918  * presented as a float so that it can easily be used for boolean evaluation 
1919  * as well as for looking for a particular range of versions.  Because of this, 
1920  * some of the granularity of the version info may be lost (e.g., Gecko 1.8.0.9 
1921  * reports 1.8).
1922  * @class UA
1923  * @static
1924  */
1925 Y.UA = function() {
1926
1927     var numberfy = function(s) {
1928             var c = 0;
1929             return parseFloat(s.replace(/\./g, function() {
1930                 return (c++ == 1) ? '' : '.';
1931             }));
1932         },
1933     
1934         nav = navigator,
1935
1936         o = {
1937
1938         /**
1939          * Internet Explorer version number or 0.  Example: 6
1940          * @property ie
1941          * @type float
1942          * @static
1943          */
1944         ie: 0,
1945
1946         /**
1947          * Opera version number or 0.  Example: 9.2
1948          * @property opera
1949          * @type float
1950          * @static
1951          */
1952         opera: 0,
1953
1954         /**
1955          * Gecko engine revision number.  Will evaluate to 1 if Gecko 
1956          * is detected but the revision could not be found. Other browsers
1957          * will be 0.  Example: 1.8
1958          * <pre>
1959          * Firefox 1.0.0.4: 1.7.8   <-- Reports 1.7
1960          * Firefox 1.5.0.9: 1.8.0.9 <-- Reports 1.8
1961          * Firefox 2.0.0.3: 1.8.1.3 <-- Reports 1.8
1962          * Firefox 3 alpha: 1.9a4   <-- Reports 1.9
1963          * </pre>
1964          * @property gecko
1965          * @type float
1966          * @static
1967          */
1968         gecko: 0,
1969
1970         /**
1971          * AppleWebKit version.  KHTML browsers that are not WebKit browsers 
1972          * will evaluate to 1, other browsers 0.  Example: 418.9
1973          * <pre>
1974          * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the 
1975          *                                   latest available for Mac OSX 10.3.
1976          * Safari 2.0.2:         416     <-- hasOwnProperty introduced
1977          * Safari 2.0.4:         418     <-- preventDefault fixed
1978          * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
1979          *                                   different versions of webkit
1980          * Safari 2.0.4 (419.3): 419     <-- Tiger installations that have been
1981          *                                   updated, but not updated
1982          *                                   to the latest patch.
1983          * Webkit 212 nightly:   522+    <-- Safari 3.0 precursor (with native SVG
1984          *                                   and many major issues fixed).
1985          * Safari 3.0.4 (523.12) 523.12  <-- First Tiger release - automatic update
1986          *                                   from 2.x via the 10.4.11 OS patch
1987          * Webkit nightly 1/2008:525+    <-- Supports DOMContentLoaded event.
1988          *                                   yahoo.com user agent hack removed.
1989          * </pre>
1990          * http://en.wikipedia.org/wiki/Safari_(web_browser)#Version_history
1991          * @property webkit
1992          * @type float
1993          * @static
1994          */
1995         webkit: 0,
1996
1997         /**
1998          * The mobile property will be set to a string containing any relevant
1999          * user agent information when a modern mobile browser is detected.
2000          * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
2001          * devices with the WebKit-based browser, and Opera Mini.  
2002          * @property mobile 
2003          * @type string
2004          * @static
2005          */
2006         mobile: null,
2007
2008         /**
2009          * Adobe AIR version number or 0.  Only populated if webkit is detected.
2010          * Example: 1.0
2011          * @property air
2012          * @type float
2013          */
2014         air: 0,
2015
2016         /**
2017          * Google Caja version number or 0.
2018          * @property caja
2019          * @type float
2020          */
2021         caja: nav.cajaVersion,
2022
2023         /**
2024          * Set to true if the page appears to be in SSL
2025          * @property secure
2026          * @type boolean
2027          * @static
2028          */
2029         secure: false,
2030
2031         /**
2032          * The operating system.  Currently only detecting windows or macintosh
2033          * @property os
2034          * @type string
2035          * @static
2036          */
2037         os: null
2038         
2039     },
2040
2041     ua = nav && nav.userAgent, 
2042
2043     loc = Y.config.win.location,
2044
2045     href = loc && loc.href,
2046     
2047     m;
2048
2049     o.secure = href && (href.toLowerCase().indexOf("https") === 0);
2050
2051     if (ua) {
2052
2053         if ((/windows|win32/i).test(ua)) {
2054             o.os = 'windows';
2055         } else if ((/macintosh/i).test(ua)) {
2056             o.os = 'macintosh';
2057         }
2058
2059         // Modern KHTML browsers should qualify as Safari X-Grade
2060         if ((/KHTML/).test(ua)) {
2061             o.webkit=1;
2062         }
2063         // Modern WebKit browsers are at least X-Grade
2064         m=ua.match(/AppleWebKit\/([^\s]*)/);
2065         if (m&&m[1]) {
2066             o.webkit=numberfy(m[1]);
2067
2068             // Mobile browser check
2069             if (/ Mobile\//.test(ua)) {
2070                 o.mobile = "Apple"; // iPhone or iPod Touch
2071             } else {
2072                 m=ua.match(/NokiaN[^\/]*|Android \d\.\d|webOS\/\d\.\d/);
2073                 if (m) {
2074                     o.mobile = m[0]; // Nokia N-series, Android, webOS, ex: NokiaN95
2075                 }
2076             }
2077
2078             m=ua.match(/AdobeAIR\/([^\s]*)/);
2079             if (m) {
2080                 o.air = m[0]; // Adobe AIR 1.0 or better
2081             }
2082
2083         }
2084
2085         if (!o.webkit) { // not webkit
2086             // @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
2087             m=ua.match(/Opera[\s\/]([^\s]*)/);
2088             if (m&&m[1]) {
2089                 o.opera=numberfy(m[1]);
2090                 m=ua.match(/Opera Mini[^;]*/);
2091                 if (m) {
2092                     o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
2093                 }
2094             } else { // not opera or webkit
2095                 m=ua.match(/MSIE\s([^;]*)/);
2096                 if (m&&m[1]) {
2097                     o.ie=numberfy(m[1]);
2098                 } else { // not opera, webkit, or ie
2099                     m=ua.match(/Gecko\/([^\s]*)/);
2100                     if (m) {
2101                         o.gecko=1; // Gecko detected, look for revision
2102                         m=ua.match(/rv:([^\s\)]*)/);
2103                         if (m&&m[1]) {
2104                             o.gecko=numberfy(m[1]);
2105                         }
2106                     }
2107                 }
2108             }
2109         }
2110     }
2111     
2112     return o;
2113 }();
2114 /**
2115  * The YUI module contains the components required for building the YUI seed file.
2116  * This includes the script loading mechanism, a simple queue, and the core utilities for the library.
2117  * @module yui
2118  * @submodule yui-base
2119  */
2120
2121 (function() {
2122
2123     var min = ['yui-base'], core, C = Y.config, mods = YUI.Env.mods,
2124         extras, i;
2125
2126     // apply the minimal required functionality
2127     Y.use.apply(Y, min);
2128
2129
2130     if (C.core) {
2131         core = C.core;
2132     } else {
2133         core = [];
2134         extras = ['get', 'loader', 'yui-log', 'yui-later'];
2135
2136         for (i=0; i<extras.length; i++) {
2137             if (mods[extras[i]]) {
2138                 core.push(extras[i]);
2139             }
2140         }
2141     }
2142
2143     Y.use.apply(Y, core);
2144      
2145 })();
2146
2147
2148
2149 }, '3.0.0' );
2150 YUI.add('get', function(Y) {
2151
2152 (function() {
2153
2154 /**
2155  * Provides a mechanism to fetch remote resources and
2156  * insert them into a document.
2157  * @module yui
2158  * @submodule get
2159  */
2160
2161 var ua         = Y.UA, 
2162     L          = Y.Lang,
2163     // PREFIX     = Y.guid(),
2164     TYPE_JS    = "text/javascript",
2165     TYPE_CSS   = "text/css",
2166     STYLESHEET = "stylesheet";
2167
2168 /**
2169  * Fetches and inserts one or more script or link nodes into the document 
2170  * @class Get
2171  * @static
2172  */
2173 Y.Get = function() {
2174
2175     /**
2176      * hash of queues to manage multiple requests
2177      * @property queues
2178      * @private
2179      */
2180     var queues={}, 
2181         
2182     /**
2183      * queue index used to generate transaction ids
2184      * @property qidx
2185      * @type int
2186      * @private
2187      */
2188         qidx=0, 
2189         
2190     /**
2191      * interal property used to prevent multiple simultaneous purge 
2192      * processes
2193      * @property purging
2194      * @type boolean
2195      * @private
2196      */
2197         purging=false,
2198
2199     
2200     /** 
2201      * Generates an HTML element, this is not appended to a document
2202      * @method _node
2203      * @param type {string} the type of element
2204      * @param attr {string} the attributes
2205      * @param win {Window} optional window to create the element in
2206      * @return {HTMLElement} the generated node
2207      * @private
2208      */
2209     _node = function(type, attr, win) {
2210         var w = win || Y.config.win, d=w.document, n=d.createElement(type),
2211             i;
2212
2213         for (i in attr) {
2214             if (attr[i] && attr.hasOwnProperty(i)) {
2215                 n.setAttribute(i, attr[i]);
2216             }
2217         }
2218
2219         return n;
2220     },
2221
2222     /**
2223      * Generates a link node
2224      * @method _linkNode
2225      * @param url {string} the url for the css file
2226      * @param win {Window} optional window to create the node in
2227      * @param attributes optional attributes collection to apply to the new node
2228      * @return {HTMLElement} the generated node
2229      * @private
2230      */
2231     _linkNode = function(url, win, attributes) {
2232         var o = {
2233             id:   Y.guid(),
2234             type: TYPE_CSS,
2235             rel:  STYLESHEET,
2236             href: url
2237         };
2238         if (attributes) {
2239             Y.mix(o, attributes);
2240         }
2241         return _node("link", o, win);
2242     },
2243
2244     /**
2245      * Generates a script node
2246      * @method _scriptNode
2247      * @param url {string} the url for the script file
2248      * @param win {Window} optional window to create the node in
2249      * @param attributes optional attributes collection to apply to the new node
2250      * @return {HTMLElement} the generated node
2251      * @private
2252      */
2253     _scriptNode = function(url, win, attributes) {
2254         var o = {
2255             id:   Y.guid(),
2256             type: TYPE_JS,
2257             src:  url
2258         };
2259
2260         if (attributes) {
2261             Y.mix(o, attributes);
2262         }
2263
2264         return _node("script", o, win);
2265     },
2266
2267     /**
2268      * Removes the nodes for the specified queue
2269      * @method _purge
2270      * @private
2271      */
2272     _purge = function(tId) {
2273         var q=queues[tId], n, l, d, h, s, i, node, attr;
2274         if (q) {
2275             n = q.nodes; 
2276             l = n.length;
2277             d = q.win.document;
2278             h = d.getElementsByTagName("head")[0];
2279
2280             if (q.insertBefore) {
2281                 s = _get(q.insertBefore, tId);
2282                 if (s) {
2283                     h = s.parentNode;
2284                 }
2285             }
2286
2287             for (i=0; i<l; i=i+1) {
2288                 node = n[i];
2289                 if (node.clearAttributes) {
2290                     node.clearAttributes();
2291                 } else {
2292                     // This is a hostile delete
2293                     // operation attempting to improve
2294                     // memory performance.  As such, the
2295                     // hasOwnProperty check is intentionally
2296                     // ommitted.
2297                     for (attr in node) {
2298                         delete node[attr];
2299                     }
2300                 }
2301
2302                 h.removeChild(node);
2303             }
2304         }
2305         q.nodes = [];
2306     },
2307
2308     /**
2309      * Returns the data payload for callback functions
2310      * @method _returnData
2311      * @private
2312      */
2313     _returnData = function(q, msg, result) {
2314         return {
2315                 tId: q.tId,
2316                 win: q.win,
2317                 data: q.data,
2318                 nodes: q.nodes,
2319                 msg: msg,
2320                 statusText: result,
2321                 purge: function() {
2322                     _purge(this.tId);
2323                 }
2324             };
2325     },
2326
2327     /**
2328      * The transaction is finished
2329      * @method _end
2330      * @param id {string} the id of the request
2331      * @private
2332      */
2333     _end = function(id, msg, result) {
2334         var q = queues[id], sc;
2335         if (q && q.onEnd) {
2336             sc = q.context || q;
2337             q.onEnd.call(sc, _returnData(q, msg, result));
2338         }
2339     },
2340
2341     /*
2342      * The request failed, execute fail handler with whatever
2343      * was accomplished.  There isn't a failure case at the
2344      * moment unless you count aborted transactions
2345      * @method _fail
2346      * @param id {string} the id of the request
2347      * @private
2348      */
2349     _fail = function(id, msg) {
2350
2351
2352         var q = queues[id], sc;
2353         if (q.timer) {
2354             // q.timer.cancel();
2355             clearTimeout(q.timer);
2356         }
2357
2358         // execute failure callback
2359         if (q.onFailure) {
2360             sc = q.context || q;
2361             q.onFailure.call(sc, _returnData(q, msg));
2362         }
2363
2364         _end(id, msg, 'failure');
2365     },
2366
2367     _get = function(nId, tId) {
2368         var q = queues[tId],
2369             n = (L.isString(nId)) ? q.win.document.getElementById(nId) : nId;
2370         if (!n) {
2371             _fail(tId, "target node not found: " + nId);
2372         }
2373
2374         return n;
2375     },
2376
2377     /**
2378      * The request is complete, so executing the requester's callback
2379      * @method _finish
2380      * @param id {string} the id of the request
2381      * @private
2382      */
2383     _finish = function(id) {
2384         var q = queues[id], msg, sc;
2385         if (q.timer) {
2386             // q.timer.cancel();
2387             clearTimeout(q.timer);
2388         }
2389         q.finished = true;
2390
2391         if (q.aborted) {
2392             msg = "transaction " + id + " was aborted";
2393             _fail(id, msg);
2394             return;
2395         }
2396
2397         // execute success callback
2398         if (q.onSuccess) {
2399             sc = q.context || q;
2400             q.onSuccess.call(sc, _returnData(q));
2401         }
2402
2403         _end(id, msg, 'OK');
2404     },
2405
2406     /**
2407      * Timeout detected
2408      * @method _timeout
2409      * @param id {string} the id of the request
2410      * @private
2411      */
2412     _timeout = function(id) {
2413         var q = queues[id], sc;
2414         if (q.onTimeout) {
2415             sc = q.context || q;
2416             q.onTimeout.call(sc, _returnData(q));
2417         }
2418
2419         _end(id, 'timeout', 'timeout');
2420     },
2421     
2422
2423     /**
2424      * Loads the next item for a given request
2425      * @method _next
2426      * @param id {string} the id of the request
2427      * @param loaded {string} the url that was just loaded, if any
2428      * @private
2429      */
2430     _next = function(id, loaded) {
2431
2432
2433         var q = queues[id], msg, w, d, h, n, url, s;
2434
2435         if (q.timer) {
2436             // q.timer.cancel();
2437             clearTimeout(q.timer);
2438         }
2439
2440         if (q.aborted) {
2441             msg = "transaction " + id + " was aborted";
2442             _fail(id, msg);
2443             return;
2444         }
2445
2446         if (loaded) {
2447             q.url.shift(); 
2448             if (q.varName) {
2449                 q.varName.shift(); 
2450             }
2451         } else {
2452             // This is the first pass: make sure the url is an array
2453             q.url = (L.isString(q.url)) ? [q.url] : q.url;
2454             if (q.varName) {
2455                 q.varName = (L.isString(q.varName)) ? [q.varName] : q.varName;
2456             }
2457         }
2458
2459         w = q.win; 
2460         d = w.document; 
2461         h = d.getElementsByTagName("head")[0];
2462
2463         if (q.url.length === 0) {
2464             _finish(id);
2465             return;
2466         } 
2467
2468         url = q.url[0];
2469
2470         // if the url is undefined, this is probably a trailing comma problem in IE
2471         if (!url) {
2472             q.url.shift(); 
2473             return _next(id);
2474         }
2475
2476
2477         if (q.timeout) {
2478             // q.timer = L.later(q.timeout, q, _timeout, id);
2479             q.timer = setTimeout(function() { 
2480                 _timeout(id);
2481             }, q.timeout);
2482         }
2483
2484         if (q.type === "script") {
2485             n = _scriptNode(url, w, q.attributes);
2486         } else {
2487             n = _linkNode(url, w, q.attributes);
2488         }
2489
2490         // track this node's load progress
2491         _track(q.type, n, id, url, w, q.url.length);
2492
2493         // add the node to the queue so we can return it to the user supplied callback
2494         q.nodes.push(n);
2495
2496         // add it to the head or insert it before 'insertBefore'
2497         if (q.insertBefore) {
2498             s = _get(q.insertBefore, id);
2499             if (s) {
2500                 s.parentNode.insertBefore(n, s);
2501             }
2502         } else {
2503             h.appendChild(n);
2504         }
2505         
2506
2507         // FireFox does not support the onload event for link nodes, so there is
2508         // no way to make the css requests synchronous. This means that the css 
2509         // rules in multiple files could be applied out of order in this browser
2510         // if a later request returns before an earlier one.  Safari too.
2511         if ((ua.webkit || ua.gecko) && q.type === "css") {
2512             _next(id, url);
2513         }
2514     },
2515
2516     /**
2517      * Removes processed queues and corresponding nodes
2518      * @method _autoPurge
2519      * @private
2520      */
2521     _autoPurge = function() {
2522
2523         if (purging) {
2524             return;
2525         }
2526
2527         purging = true;
2528
2529         var i, q;
2530
2531         for (i in queues) {
2532             if (queues.hasOwnProperty(i)) {
2533                 q = queues[i];
2534                 if (q.autopurge && q.finished) {
2535                     _purge(q.tId);
2536                     delete queues[i];
2537                 }
2538             }
2539         }
2540
2541         purging = false;
2542     },
2543
2544     /**
2545      * Saves the state for the request and begins loading
2546      * the requested urls
2547      * @method queue
2548      * @param type {string} the type of node to insert
2549      * @param url {string} the url to load
2550      * @param opts the hash of options for this request
2551      * @private
2552      */
2553     _queue = function(type, url, opts) {
2554
2555         opts = opts || {};
2556
2557         var id = "q" + (qidx++), q,
2558             thresh = opts.purgethreshold || Y.Get.PURGE_THRESH;
2559
2560         if (qidx % thresh === 0) {
2561             _autoPurge();
2562         }
2563
2564         queues[id] = Y.merge(opts, {
2565             tId: id,
2566             type: type,
2567             url: url,
2568             finished: false,
2569             nodes: []
2570         });
2571
2572         q           = queues[id];
2573         q.win       = q.win || Y.config.win;
2574         q.context   = q.context || q;
2575         q.autopurge = ("autopurge" in q) ? q.autopurge : 
2576                       (type === "script") ? true : false;
2577
2578         if (opts.charset) {
2579             q.attributes = q.attributes || {};
2580             q.attributes.charset = opts.charset;
2581         }
2582
2583         // L.later(0, q, _next, id);
2584         setTimeout(function() {
2585             _next(id);
2586         }, 0);
2587
2588         return {
2589             tId: id
2590         };
2591     },
2592
2593     /**
2594      * Detects when a node has been loaded.  In the case of
2595      * script nodes, this does not guarantee that contained
2596      * script is ready to use.
2597      * @method _track
2598      * @param type {string} the type of node to track
2599      * @param n {HTMLElement} the node to track
2600      * @param id {string} the id of the request
2601      * @param url {string} the url that is being loaded
2602      * @param win {Window} the targeted window
2603      * @param qlength the number of remaining items in the queue,
2604      * including this one
2605      * @param trackfn {Function} function to execute when finished
2606      * the default is _next
2607      * @private
2608      */
2609     _track = function(type, n, id, url, win, qlength, trackfn) {
2610         var f = trackfn || _next;
2611
2612         // IE supports the readystatechange event for script and css nodes
2613         // Opera only for script nodes.  Opera support onload for script
2614         // nodes, but this doesn't fire when there is a load failure.
2615         // The onreadystatechange appears to be a better way to respond
2616         // to both success and failure.
2617         if (ua.ie) {
2618             n.onreadystatechange = function() {
2619                 var rs = this.readyState;
2620                 if ("loaded" === rs || "complete" === rs) {
2621                     n.onreadystatechange = null;
2622                     f(id, url);
2623                 }
2624             };
2625
2626         // webkit prior to 3.x is no longer supported
2627         } else if (ua.webkit) {
2628
2629             if (type === "script") {
2630                 // Safari 3.x supports the load event for script nodes (DOM2)
2631                 n.addEventListener("load", function() {
2632                     f(id, url);
2633                 });
2634             } 
2635
2636         // FireFox and Opera support onload (but not DOM2 in FF) handlers for
2637         // script nodes.  Opera, but not FF, supports the onload event for link
2638         // nodes.
2639         } else { 
2640
2641             n.onload = function() {
2642                 f(id, url);
2643             };
2644
2645             n.onerror = function(e) {
2646                 _fail(id, e + ": " + url);
2647             };
2648         }
2649     };
2650
2651     return {
2652
2653         /**
2654          * The number of request required before an automatic purge.
2655          * Can be configured via the 'purgethreshold' config
2656          * property PURGE_THRESH
2657          * @static
2658          * @type int
2659          * @default 20
2660          * @private
2661          */
2662         PURGE_THRESH: 20,
2663
2664         /**
2665          * Called by the the helper for detecting script load in Safari
2666          * @method _finalize
2667          * @static
2668          * @param id {string} the transaction id
2669          * @private
2670          */
2671         _finalize: function(id) {
2672             // L.later(0, null, _finish, id);
2673             setTimeout(function() {
2674                 _finish(id);
2675             }, 0);
2676         },
2677
2678         /**
2679          * Abort a transaction
2680          * @method abort
2681          * @static
2682          * @param o {string|object} Either the tId or the object returned from
2683          * script() or css()
2684          */
2685         abort: function(o) {
2686             var id = (L.isString(o)) ? o : o.tId,
2687                 q = queues[id];
2688             if (q) {
2689                 q.aborted = true;
2690             }
2691         }, 
2692
2693         /**
2694          * Fetches and inserts one or more script nodes into the head
2695          * of the current document or the document in a specified window.
2696          *
2697          * @method script
2698          * @static
2699          * @param url {string|string[]} the url or urls to the script(s)
2700          * @param opts {object} Options: 
2701          * <dl>
2702          * <dt>onSuccess</dt>
2703          * <dd>
2704          * callback to execute when the script(s) are finished loading
2705          * The callback receives an object back with the following
2706          * data:
2707          * <dl>
2708          * <dt>win</dt>
2709          * <dd>the window the script(s) were inserted into</dd>
2710          * <dt>data</dt>
2711          * <dd>the data object passed in when the request was made</dd>
2712          * <dt>nodes</dt>
2713          * <dd>An array containing references to the nodes that were
2714          * inserted</dd>
2715          * <dt>purge</dt>
2716          * <dd>A function that, when executed, will remove the nodes
2717          * that were inserted</dd>
2718          * <dt>
2719          * </dl>
2720          * </dd>
2721          * <dt>onTimeout</dt>
2722          * <dd>
2723          * callback to execute when a timeout occurs.
2724          * The callback receives an object back with the following
2725          * data:
2726          * <dl>
2727          * <dt>win</dt>
2728          * <dd>the window the script(s) were inserted into</dd>
2729          * <dt>data</dt>
2730          * <dd>the data object passed in when the request was made</dd>
2731          * <dt>nodes</dt>
2732          * <dd>An array containing references to the nodes that were
2733          * inserted</dd>
2734          * <dt>purge</dt>
2735          * <dd>A function that, when executed, will remove the nodes
2736          * that were inserted</dd>
2737          * <dt>
2738          * </dl>
2739          * </dd>
2740          * <dt>onEnd</dt>
2741          * <dd>a function that executes when the transaction finishes, regardless of the exit path</dd>
2742          * <dt>onFailure</dt>
2743          * <dd>
2744          * callback to execute when the script load operation fails
2745          * The callback receives an object back with the following
2746          * data:
2747          * <dl>
2748          * <dt>win</dt>
2749          * <dd>the window the script(s) were inserted into</dd>
2750          * <dt>data</dt>
2751          * <dd>the data object passed in when the request was made</dd>
2752          * <dt>nodes</dt>
2753          * <dd>An array containing references to the nodes that were
2754          * inserted successfully</dd>
2755          * <dt>purge</dt>
2756          * <dd>A function that, when executed, will remove any nodes
2757          * that were inserted</dd>
2758          * <dt>
2759          * </dl>
2760          * </dd>
2761          * <dt>context</dt>
2762          * <dd>the execution context for the callbacks</dd>
2763          * <dt>win</dt>
2764          * <dd>a window other than the one the utility occupies</dd>
2765          * <dt>autopurge</dt>
2766          * <dd>
2767          * setting to true will let the utilities cleanup routine purge 
2768          * the script once loaded
2769          * </dd>
2770          * <dt>purgethreshold</dt>
2771          * <dd>
2772          * The number of transaction before autopurge should be initiated
2773          * </dd>
2774          * <dt>data</dt>
2775          * <dd>
2776          * data that is supplied to the callback when the script(s) are
2777          * loaded.
2778          * </dd>
2779          * <dt>insertBefore</dt>
2780          * <dd>node or node id that will become the new node's nextSibling</dd>
2781          * </dl>
2782          * <dt>charset</dt>
2783          * <dd>Node charset, default utf-8 (deprecated, use the attributes config)</dd>
2784          * <dt>attributes</dt>
2785          * <dd>An object literal containing additional attributes to add to the link tags</dd>
2786          * <dt>timeout</dt>
2787          * <dd>Number of milliseconds to wait before aborting and firing the timeout event</dd>
2788          * <pre>
2789          * &nbsp;&nbsp;Y.Get.script(
2790          * &nbsp;&nbsp;["http://yui.yahooapis.com/2.5.2/build/yahoo/yahoo-min.js",
2791          * &nbsp;&nbsp;&nbsp;"http://yui.yahooapis.com/2.5.2/build/event/event-min.js"], &#123;
2792          * &nbsp;&nbsp;&nbsp;&nbsp;onSuccess: function(o) &#123;
2793          * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.log("won't cause error because Y is the context");
2794          * &nbsp;&nbsp;&nbsp;&nbsp;&#125;,
2795          * &nbsp;&nbsp;&nbsp;&nbsp;onFailure: function(o) &#123;
2796          * &nbsp;&nbsp;&nbsp;&nbsp;&#125;,
2797          * &nbsp;&nbsp;&nbsp;&nbsp;onTimeout: function(o) &#123;
2798          * &nbsp;&nbsp;&nbsp;&nbsp;&#125;,
2799          * &nbsp;&nbsp;&nbsp;&nbsp;data: "foo",
2800          * &nbsp;&nbsp;&nbsp;&nbsp;timeout: 10000, // 10 second timeout
2801          * &nbsp;&nbsp;&nbsp;&nbsp;context: Y, // make the YUI instance
2802          * &nbsp;&nbsp;&nbsp;&nbsp;// win: otherframe // target another window/frame
2803          * &nbsp;&nbsp;&nbsp;&nbsp;autopurge: true // allow the utility to choose when to remove the nodes
2804          * &nbsp;&nbsp;&nbsp;&nbsp;purgetheshold: 1 // purge previous transaction before next transaction
2805          * &nbsp;&nbsp;&#125;);
2806          * </pre>
2807          * @return {tId: string} an object containing info about the transaction
2808          */
2809         script: function(url, opts) { 
2810             return _queue("script", url, opts); 
2811         },
2812
2813         /**
2814          * Fetches and inserts one or more css link nodes into the 
2815          * head of the current document or the document in a specified
2816          * window.
2817          * @method css
2818          * @static
2819          * @param url {string} the url or urls to the css file(s)
2820          * @param opts Options: 
2821          * <dl>
2822          * <dt>onSuccess</dt>
2823          * <dd>
2824          * callback to execute when the css file(s) are finished loading
2825          * The callback receives an object back with the following
2826          * data:
2827          * <dl>win</dl>
2828          * <dd>the window the link nodes(s) were inserted into</dd>
2829          * <dt>data</dt>
2830          * <dd>the data object passed in when the request was made</dd>
2831          * <dt>nodes</dt>
2832          * <dd>An array containing references to the nodes that were
2833          * inserted</dd>
2834          * <dt>purge</dt>
2835          * <dd>A function that, when executed, will remove the nodes
2836          * that were inserted</dd>
2837          * <dt>
2838          * </dl>
2839          * </dd>
2840          * <dt>context</dt>
2841          * <dd>the execution context for the callbacks</dd>
2842          * <dt>win</dt>
2843          * <dd>a window other than the one the utility occupies</dd>
2844          * <dt>data</dt>
2845          * <dd>
2846          * data that is supplied to the callbacks when the nodes(s) are
2847          * loaded.
2848          * </dd>
2849          * <dt>insertBefore</dt>
2850          * <dd>node or node id that will become the new node's nextSibling</dd>
2851          * <dt>charset</dt>
2852          * <dd>Node charset, default utf-8 (deprecated, use the attributes config)</dd>
2853          * <dt>attributes</dt>
2854          * <dd>An object literal containing additional attributes to add to the link tags</dd>
2855          * </dl>
2856          * <pre>
2857          *      Y.Get.css("http://yui.yahooapis.com/2.3.1/build/menu/assets/skins/sam/menu.css");
2858          * </pre>
2859          * <pre>
2860          * &nbsp;&nbsp;Y.Get.css(
2861          * &nbsp;&nbsp;["http://yui.yahooapis.com/2.3.1/build/menu/assets/skins/sam/menu.css",
2862          * &nbsp;&nbsp;&nbsp;&nbsp;insertBefore: 'custom-styles' // nodes will be inserted before the specified node
2863          * &nbsp;&nbsp;&#125;);
2864          * </pre>
2865          * @return {tId: string} an object containing info about the transaction
2866          */
2867         css: function(url, opts) {
2868             return _queue("css", url, opts); 
2869         }
2870     };
2871 }();
2872
2873 })();
2874
2875
2876 }, '3.0.0' );
2877 YUI.add('yui-log', function(Y) {
2878
2879 /**
2880  * Provides console log capability and exposes a custom event for
2881  * console implementations.
2882  * @module yui
2883  * @submodule yui-log
2884  */
2885 (function() {
2886
2887 var INSTANCE = Y,
2888     LOGEVENT = 'yui:log',
2889     UNDEFINED = 'undefined',
2890     LEVELS = { debug: 1, info: 1, warn: 1, error: 1 },
2891     _published;
2892
2893 /**
2894  * If the 'debug' config is true, a 'yui:log' event will be
2895  * dispatched, which the Console widget and anything else
2896  * can consume.  If the 'useBrowserConsole' config is true, it will
2897  * write to the browser console if available.  YUI-specific log
2898  * messages will only be present in the -debug versions of the
2899  * JS files.  The build system is supposed to remove log statements
2900  * from the raw and minified versions of the files.
2901  *
2902  * @method log
2903  * @for YUI
2904  * @param  {String}  msg  The message to log.
2905  * @param  {String}  cat  The log category for the message.  Default
2906  *                        categories are "info", "warn", "error", time".
2907  *                        Custom categories can be used as well. (opt)
2908  * @param  {String}  src  The source of the the message (opt)
2909  * @param  {boolean} silent If true, the log event won't fire
2910  * @return {YUI}      YUI instance
2911  */
2912 INSTANCE.log = function(msg, cat, src, silent) {
2913     var Y = INSTANCE, c = Y.config, bail = false, excl, incl, m, f;
2914     // suppress log message if the config is off or the event stack
2915     // or the event call stack contains a consumer of the yui:log event
2916     if (c.debug) {
2917         // apply source filters
2918         if (src) {
2919             excl = c.logExclude; 
2920             incl = c.logInclude;
2921
2922             if (incl && !(src in incl)) {
2923                 bail = 1;
2924             } else if (excl && (src in excl)) {
2925                 bail = 1;
2926             }
2927         }
2928
2929         if (!bail) {
2930
2931             if (c.useBrowserConsole) {
2932                 m = (src) ? src + ': ' + msg : msg;
2933                 if (typeof console != UNDEFINED && console.log) {
2934                     f = (cat && console[cat] && (cat in LEVELS)) ? cat : 'log';
2935                     console[f](m);
2936                 } else if (typeof opera != UNDEFINED) {
2937                     opera.postError(m);
2938                 }
2939             }
2940
2941             if (Y.fire && !silent) {
2942                 if (!_published) {
2943                     Y.publish(LOGEVENT, {
2944                         broadcast: 2,
2945                         emitFacade: 1
2946                     });
2947
2948                     _published = 1;
2949
2950                 }
2951                 Y.fire(LOGEVENT, {
2952                     msg: msg, 
2953                     cat: cat, 
2954                     src: src
2955                 });
2956             }
2957         }
2958     }
2959
2960     return Y;
2961 };
2962
2963 /**
2964  * Write a system message.  This message will be preserved in the
2965  * minified and raw versions of the YUI files, unlike log statements.
2966  * @method message
2967  * @for YUI
2968  * @param  {String}  msg  The message to log.
2969  * @param  {String}  cat  The log category for the message.  Default
2970  *                        categories are "info", "warn", "error", time".
2971  *                        Custom categories can be used as well. (opt)
2972  * @param  {String}  src  The source of the the message (opt)
2973  * @param  {boolean} silent If true, the log event won't fire
2974  * @return {YUI}      YUI instance
2975  */
2976 INSTANCE.message = function() {
2977     return INSTANCE.log.apply(INSTANCE, arguments);
2978 };
2979
2980 })();
2981
2982
2983 }, '3.0.0' ,{requires:['yui-base']});
2984 YUI.add('yui-later', function(Y) {
2985
2986 /**
2987  * Provides a setTimeout/setInterval wrapper
2988  * @module yui
2989  * @submodule yui-later
2990  */
2991 (function() {
2992     var L = Y.Lang,
2993
2994     /**
2995      * Executes the supplied function in the context of the supplied 
2996      * object 'when' milliseconds later.  Executes the function a 
2997      * single time unless periodic is set to true.
2998      * @method later
2999      * @for YUI
3000      * @param when {int} the number of milliseconds to wait until the fn 
3001      * is executed.
3002      * @param o the context object.
3003      * @param fn {Function|String} the function to execute or the name of 
3004      * the method in the 'o' object to execute.
3005      * @param data [Array] data that is provided to the function.  This accepts
3006      * either a single item or an array.  If an array is provided, the
3007      * function is executed with one parameter for each array item.  If
3008      * you need to pass a single array parameter, it needs to be wrapped in
3009      * an array [myarray].
3010      * @param periodic {boolean} if true, executes continuously at supplied 
3011      * interval until canceled.
3012      * @return {object} a timer object. Call the cancel() method on this object to 
3013      * stop the timer.
3014      */
3015     later = function(when, o, fn, data, periodic) {
3016         when = when || 0; 
3017         o = o || {};
3018         var m=fn, d=Y.Array(data), f, r;
3019
3020         if (L.isString(fn)) {
3021             m = o[fn];
3022         }
3023
3024         if (!m) {
3025         }
3026
3027         f = function() {
3028             m.apply(o, d);
3029         };
3030
3031         r = (periodic) ? setInterval(f, when) : setTimeout(f, when);
3032
3033         return {
3034             id: r,
3035             interval: periodic,
3036             cancel: function() {
3037                 if (this.interval) {
3038                     clearInterval(r);
3039                 } else {
3040                     clearTimeout(r);
3041                 }
3042             }
3043         };
3044     };
3045
3046     Y.later = later;
3047     L.later = later;
3048
3049 })();
3050
3051
3052 }, '3.0.0' ,{requires:['yui-base']});
3053
3054
3055 YUI.add('yui', function(Y){}, '3.0.0' ,{use:['yui-base','get','yui-log','yui-later']});
3056