]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/javascript/yui3/build/yui-base/yui-base.js
Release 6.2.1
[Github/sugarcrm.git] / jssource / src_files / include / javascript / yui3 / build / yui-base / yui-base.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 (function() {
9
10     var _instances = {}, 
11         _startTime = new Date().getTime(), 
12         p, 
13         i,
14
15         add = function () {
16             if (window.addEventListener) {
17                 return function(el, type, fn, capture) {
18                     el.addEventListener(type, fn, (!!capture));
19                 };
20             } else if (window.attachEvent) {
21                 return function(el, type, fn) {
22                     el.attachEvent("on" + type, fn);
23                 };
24             } else {
25                 return function(){};
26             }
27         }(),
28
29         remove = function() {
30             if (window.removeEventListener) {
31                 return function (el, type, fn, capture) {
32                     el.removeEventListener(type, fn, !!capture);
33                 };
34             } else if (window.detachEvent) {
35                 return function (el, type, fn) {
36                     el.detachEvent("on" + type, fn);
37                 };
38             } else {
39                 return function(){};
40             }
41         }(),
42
43         globalListener = function() {
44             YUI.Env.windowLoaded = true;
45             YUI.Env.DOMReady = true;
46             remove(window, 'load', globalListener);
47         },
48
49 // @TODO: this needs to be created at build time from module metadata
50
51         _APPLY_TO_WHITE_LIST = {
52             'io.xdrReady': 1,
53             'io.start': 1,
54             'io.success': 1,
55             'io.failure': 1
56         },
57
58         SLICE = Array.prototype.slice;
59         
60 // reduce to one or the other
61 if (typeof YUI === 'undefined' || !YUI) {
62
63     /**
64      * The YUI global namespace object.  If YUI is already defined, the
65      * existing YUI object will not be overwritten so that defined
66      * namespaces are preserved.  
67      *
68      * @class YUI
69      * @constructor
70      * @global
71      * @uses EventTarget
72      * @param o* Up to five optional configuration objects.  This object is stored
73      * in YUI.config.  See config for the list of supported properties.
74      */
75
76     /*global YUI*/
77     // Make a function, disallow direct instantiation
78     YUI = function(o1, o2, o3, o4, o5) {
79
80         var Y = this, a = arguments, i, l = a.length;
81
82         // Allow instantiation without the new operator
83         if (!(Y instanceof YUI)) {
84             return new YUI(o1, o2, o3, o4, o5);
85         } else {
86             // set up the core environment
87             Y._init();
88
89             for (i=0; i<l; i++) {
90                 Y._config(a[i]);
91             }
92
93             // bind the specified additional modules for this instance
94             Y._setup();
95
96             return Y;
97         }
98     };
99 }
100
101 // The prototype contains the functions that are required to allow the external
102 // modules to be registered and for the instance to be initialized.
103 YUI.prototype = {
104
105     _config: function(o) {
106
107         o = o || {};
108
109         var c = this.config, i, j, m, mods;
110
111         mods = c.modules;
112         for (i in o) {
113             if (mods && i == 'modules') {
114                 m = o[i];
115                 for (j in m) {
116                     if (m.hasOwnProperty(j)) {
117                         mods[j] = m[j];
118                     }
119                 }
120             } else if (i == 'win') {
121                 c[i] = o[i].contentWindow || o[i];
122                 c.doc = c[i].document;
123             } else {
124                 c[i] = o[i];
125             }
126         }
127     },
128
129     /**
130      * Initialize this YUI instance
131      * @param o config options
132      * @private
133      */
134     _init: function(o) {
135
136         // find targeted window/frame
137         // @TODO create facades
138         var v = '3.0.0', Y = this;
139
140         if (v.indexOf('@') > -1) {
141             v = 'test';
142         }
143
144         Y.version = v;
145
146         Y.Env = {
147             // @todo expand the new module metadata
148             mods: {},
149             cdn: 'http://yui.yahooapis.com/' + v + '/build/',
150             bootstrapped: false,
151             _idx: 0,
152             _used: {},
153             _attached: {},
154             _yidx: 0,
155             _uidx: 0,
156             _loaded: {}
157         };
158
159         Y.Env._loaded[v] = {};
160
161         if (YUI.Env) {
162             Y.Env._yidx = (++YUI.Env._yidx);
163             Y.Env._guidp = ('yui_' + v + '-' + Y.Env._yidx + '-' + _startTime).replace(/\./g, '_');
164             Y.id = Y.stamp(Y);
165             _instances[Y.id] = Y;
166         }
167
168         Y.constructor = YUI;
169
170         // configuration defaults
171         Y.config = {
172
173             win: window || {},
174             doc: document,
175             debug: true,
176             useBrowserConsole: true,
177             throwFail: true,
178         
179             base: function() {
180                 var b, nodes, i, match;
181
182                 // get from querystring
183                 nodes = document.getElementsByTagName('script');
184
185                 for (i=0; i<nodes.length; i=i+1) {
186                     match = nodes[i].src.match(/^(.*)yui\/yui[\.\-].*js(\?.*)?$/);
187                     b = match && match[1];
188                     if (b) {
189                         break;
190                     }
191                 }
192
193                 // use CDN default
194                 return b || this.Env.cdn;
195
196             }(),
197
198             loaderPath: 'loader/loader-min.js'
199         };
200
201     },
202     
203     /**
204      * Finishes the instance setup. Attaches whatever modules were defined
205      * when the yui modules was registered.
206      * @method _setup
207      * @private
208      */
209     _setup: function(o) {
210         this.use("yui-base");
211     },
212
213     /**
214      * Executes a method on a YUI instance with
215      * the specified id if the specified method is whitelisted.
216      * @method applyTo
217      * @param id {string} the YUI instance id
218      * @param method {string} the name of the method to exectute.
219      * Ex: 'Object.keys'
220      * @param args {Array} the arguments to apply to the method
221      * @return {object} the return value from the applied method or null
222      */
223     applyTo: function(id, method, args) {
224
225         if (!(method in _APPLY_TO_WHITE_LIST)) {
226             this.error(method + ': applyTo not allowed');
227             return null;
228         }
229
230         var instance = _instances[id], nest, m, i;
231
232         if (instance) {
233
234             nest = method.split('.'); 
235             m = instance;
236
237             for (i=0; i<nest.length; i=i+1) {
238
239                 m = m[nest[i]];
240
241                 if (!m) {
242                     this.error('applyTo not found: ' + method);
243                 }
244             }
245
246             return m.apply(instance, args);
247         }
248
249         return null;
250     }, 
251
252     /**
253      * Register a module
254      * @method add
255      * @param name {string} module name
256      * @param fn {Function} entry point into the module that
257      * is used to bind module to the YUI instance
258      * @param version {string} version string
259      * @param details optional config data: 
260      * requires   - features that should be present before loading
261      * optional   - optional features that should be present if load optional defined
262      * use  - features that should be attached automatically
263      * skinnable  -
264      * rollup
265      * omit - features that should not be loaded if this module is present
266      * @return {YUI} the YUI instance
267      *
268      */
269     add: function(name, fn, version, details) {
270         // this.log('Adding a new component ' + name);
271         // @todo expand this to include version mapping
272         // @todo may want to restore the build property
273         // @todo fire moduleAvailable event
274         
275         YUI.Env.mods[name] = {
276             name: name, 
277             fn: fn,
278             version: version,
279             details: details || {}
280         };
281
282         return this; // chain support
283     },
284
285     _attach: function(r, fromLoader) {
286
287         var mods = YUI.Env.mods,
288             attached = this.Env._attached,
289             i, l = r.length, name, m, d, req, use;
290
291         for (i=0; i<l; i=i+1) {
292
293             name = r[i]; 
294             m    = mods[name];
295
296             if (!attached[name] && m) {
297
298                 attached[name] = true;
299
300                 d   = m.details; 
301                 req = d.requires; 
302                 use = d.use;
303
304                 if (req) {
305                     this._attach(this.Array(req));
306                 }
307
308                 // this.log('attaching ' + name, 'info', 'yui');
309
310                 if (m.fn) {
311                     m.fn(this);
312                 }
313
314                 if (use) {
315                     this._attach(this.Array(use));
316                 }
317             }
318         }
319
320     },
321
322     /**
323      * Bind a module to a YUI instance
324      * @param modules* {string} 1-n modules to bind (uses arguments array)
325      * @param *callback {function} callback function executed when 
326      * the instance has the required functionality.  If included, it
327      * must be the last parameter.
328      *
329      * @TODO 
330      * Implement versioning?  loader can load different versions?
331      * Should sub-modules/plugins be normal modules, or do
332      * we add syntax for specifying these?
333      *
334      * YUI().use('dragdrop')
335      * YUI().use('dragdrop:2.4.0'); // specific version
336      * YUI().use('dragdrop:2.4.0-'); // at least this version
337      * YUI().use('dragdrop:2.4.0-2.9999.9999'); // version range
338      * YUI().use('*'); // use all available modules
339      * YUI().use('lang+dump+substitute'); // use lang and some plugins
340      * YUI().use('lang+*'); // use lang and all known plugins
341      *
342      *
343      * @return {YUI} the YUI instance
344      */
345     use: function() {
346
347         if (this._loading) {
348             this._useQueue = this._useQueue || new this.Queue();
349             this._useQueue.add(SLICE.call(arguments, 0));
350             return this;
351         }
352
353         var Y = this, 
354             a=SLICE.call(arguments, 0), 
355             mods = YUI.Env.mods, 
356             used = Y.Env._used,
357             loader, 
358             firstArg = a[0], 
359             dynamic = false,
360             callback = a[a.length-1],
361             k, i, l, missing = [], 
362             r = [], 
363             f = function(name) {
364
365                 // only attach a module once
366                 if (used[name]) {
367                     return;
368                 }
369
370                 var m = mods[name], j, req, use;
371
372                 if (m) {
373
374
375                     used[name] = true;
376
377                     req = m.details.requires;
378                     use = m.details.use;
379                 } else {
380
381                     // CSS files don't register themselves, see if it has been loaded
382                     if (!YUI.Env._loaded[Y.version][name]) {
383                         missing.push(name);
384                     } else {
385                         // probably css
386                         used[name] = true;
387                     }
388                 }
389
390                 // make sure requirements are attached
391                 if (req) {
392                     if (Y.Lang.isString(req)) {
393                         f(req);
394                     } else {
395                         for (j = 0; j < req.length; j = j + 1) {
396                             f(req[j]);
397                         }
398                     }
399                 }
400
401                 // add this module to full list of things to attach
402                 r.push(name);
403
404             },
405
406             onComplete = function(fromLoader) {
407
408
409                 fromLoader = fromLoader || {
410                     success: true,
411                     msg: 'not dynamic'
412                 };
413
414                 if (Y.Env._callback) {
415
416                     var cb = Y.Env._callback;
417                     Y.Env._callback = null;
418                     cb(Y, fromLoader);
419                 }
420
421                 if (Y.fire) {
422                     Y.fire('yui:load', Y, fromLoader);
423                 }
424
425                 // process queued use requests as long until done 
426                 // or dynamic load happens again.
427                 Y._loading = false;
428                 while (Y._useQueue && Y._useQueue.size() && !Y._loading) {
429                     Y.use.apply(Y, Y._useQueue.next());
430                 }
431             };
432
433
434         // The last argument supplied to use can be a load complete callback
435         if (typeof callback === 'function') {
436             a.pop();
437             Y.Env._callback = callback;
438         } else {
439             callback = null;
440         }
441
442         // YUI().use('*'); // bind everything available
443         if (firstArg === "*") {
444             a = [];
445             for (k in mods) {
446                 if (mods.hasOwnProperty(k)) {
447                     a.push(k);
448                 }
449             }
450
451             return Y.use.apply(Y, a);
452         }
453         
454
455         // use loader to expand dependencies and sort the 
456         // requirements if it is available.
457         if (Y.Loader) {
458             dynamic = true;
459             loader = new Y.Loader(Y.config);
460             loader.require(a);
461             loader.ignoreRegistered = true;
462             loader.allowRollup = false;
463             loader.calculate();
464             a = loader.sorted;
465         }
466
467
468         l = a.length;
469
470         // process each requirement and any additional requirements 
471         // the module metadata specifies
472         for (i=0; i<l; i=i+1) {
473             f(a[i]);
474         }
475
476
477         // dynamic load
478         if (Y.Loader && missing.length) {
479             Y._loading = true;
480             loader = new Y.Loader(Y.config);
481             loader.onSuccess = onComplete;
482             loader.onFailure = onComplete;
483             loader.onTimeout = onComplete;
484             loader.context = Y;
485             loader.attaching = a;
486             loader.require(missing);
487             loader.insert();
488         } else if (Y.Get && missing.length && !Y.Env.bootstrapped) {
489             Y._loading = true;
490
491             a = Y.Array(arguments, 0, true);
492             // a.unshift('loader');
493
494             Y.Get.script(Y.config.base + Y.config.loaderPath, {
495                 onEnd: function() {
496                     Y._loading = false;
497                     Y.Env.bootstrapped = true;
498                     Y._attach(['loader']);
499                     Y.use.apply(Y, a);
500                 }
501             });
502
503             return Y;
504
505         } else {
506             Y._attach(r);
507             onComplete();
508         }
509
510         return Y; // chain support var yui = YUI().use('dragdrop');
511     },
512
513
514     /**
515      * Returns the namespace specified and creates it if it doesn't exist
516      * <pre>
517      * YUI.namespace("property.package");
518      * YUI.namespace("YAHOO.property.package");
519      * </pre>
520      * Either of the above would create YUI.property, then
521      * YUI.property.package (YAHOO is scrubbed out, this is
522      * to remain compatible with YUI2)
523      *
524      * Be careful when naming packages. Reserved words may work in some browsers
525      * and not others. For instance, the following will fail in Safari:
526      * <pre>
527      * YUI.namespace("really.long.nested.namespace");
528      * </pre>
529      * This fails because "long" is a future reserved word in ECMAScript
530      *
531      * @method namespace
532      * @param  {string*} arguments 1-n namespaces to create 
533      * @return {object}  A reference to the last namespace object created
534      */
535     namespace: function() {
536         var a=arguments, o=null, i, j, d;
537         for (i=0; i<a.length; i=i+1) {
538             d = ("" + a[i]).split(".");
539             o = this;
540             for (j=(d[0] == "YAHOO") ? 1 : 0; j<d.length; j=j+1) {
541                 o[d[j]] = o[d[j]] || {};
542                 o = o[d[j]];
543             }
544         }
545         return o;
546     },
547
548     // this is replaced if the log module is included
549     log: function() {
550
551     },
552
553     /**
554      * Report an error.  The reporting mechanism is controled by
555      * the 'throwFail' configuration attribute.  If throwFail is
556      * not specified, the message is written to the Logger, otherwise
557      * a JS error is thrown
558      * @method error
559      * @param msg {string} the error message
560      * @param e {Error} Optional JS error that was caught.  If supplied
561      * and throwFail is specified, this error will be re-thrown.
562      * @return {YUI} this YUI instance
563      */
564     error: function(msg, e) {
565         if (this.config.throwFail) {
566             throw (e || new Error(msg)); 
567         } else {
568             this.message(msg, "error"); // don't scrub this one
569         }
570
571         return this;
572     },
573
574     /**
575      * Generate an id that is unique among all YUI instances
576      * @method guid
577      * @param pre {string} optional guid prefix
578      * @return {string} the guid
579      */
580     guid: function(pre) {
581         var id =  this.Env._guidp + (++this.Env._uidx);
582         return (pre) ? (pre + id) : id;
583     },
584
585     /**
586      * Returns a guid associated with an object.  If the object
587      * does not have one, a new one is created unless readOnly
588      * is specified.
589      * @method stamp
590      * @param o The object to stamp
591      * @param readOnly {boolean} if true, a valid guid will only
592      * be returned if the object has one assigned to it.
593      * @return {string} The object's guid or null
594      */
595     stamp: function(o, readOnly) {
596
597         if (!o) {
598             return o;
599         }
600
601         var uid = (typeof o === 'string') ? o : o._yuid;
602
603         if (!uid) {
604             uid = this.guid();
605             if (!readOnly) {
606                 try {
607                     o._yuid = uid;
608                 } catch(e) {
609                     uid = null;
610                 }
611             }
612         }
613
614         return uid;
615     }
616 };
617
618 // Give the YUI global the same properties as an instance.
619 // This makes it so that the YUI global can be used like the YAHOO
620 // global was used prior to 3.x.  More importantly, the YUI global
621 // provides global metadata, so env needs to be configured.
622 // @TODO review
623
624     p = YUI.prototype;
625
626     // inheritance utilities are not available yet
627     for (i in p) {
628         // if (1) { // intenionally ignoring hasOwnProperty check
629         YUI[i] = p[i];
630         // }
631     }
632
633     // set up the environment
634     YUI._init();
635
636     // add a window load event at load time so we can capture
637     // the case where it fires before dynamic loading is
638     // complete.
639     add(window, 'load', globalListener);
640
641     YUI.Env.add = add;
642     YUI.Env.remove = remove;
643
644     /*
645      * Subscribe to an event.  The signature differs depending on the
646      * type of event you are attaching to.
647      * @method on 
648      * @param type {string|function|object} The type of the event.  If
649      * this is a function, this is dispatched to the aop system.  If an
650      * object, it is parsed for multiple subsription definitions
651      * @param fn {Function} The callback
652      * @param elspec {any} DOM element(s), selector string(s), and or
653      * Node ref(s) to attach DOM related events to (only applies to
654      * DOM events).
655      * @param
656      * @return the event target or a detach handle per 'chain' config
657      */
658
659 })();
660
661 /**
662  * The config object contains all of the configuration options for
663  * the YUI instance.  This object is supplied by the implementer 
664  * when instantiating a YUI instance.  Some properties have default
665  * values if they are not supplied by the implementer.
666  *
667  * @class config
668  * @static
669  */
670
671 /**
672  * Turn debug statements on or off.
673  *
674  * @property debug
675  * @type boolean
676  * @default true
677  */
678
679 /**
680  * Log to the browser console if debug is on and the browser has a
681  * supported console.
682  *
683  * @property useBrowserConsole
684  * @type boolean
685  * @default true
686  */
687
688 /**
689  * A hash of log sources that should be logged.  If specified, only log messages from these sources will be logged.
690  *
691  * @property logInclude
692  * @type object
693  */
694
695 /**
696  * A hash of log sources that should be not be logged.  If specified, all sources are logged if not on this list.
697  *
698  * @property logExclude
699  * @type object
700  */
701
702 /**
703  * Set to true if the yui seed file was dynamically loaded in 
704  * order to bootstrap components relying on the window load event 
705  * and the 'domready' custom event.
706  *
707  * @property injected
708  * @type object
709  */
710
711 /**
712  * If throwFail is set, Y.fail will generate or re-throw a JS Error.  Otherwise the failure is logged.
713  *
714  * @property throwFail
715  * @type boolean
716  * @default true
717  */
718
719 /**
720  * The window/frame that this instance should operate in.
721  *
722  * @property win
723  * @type Window
724  * @default the window hosting YUI
725  */
726
727 /**
728  * The document associated with the 'win' configuration.
729  *
730  * @property doc
731  * @type Document
732  * @default the document hosting YUI
733  */
734
735 /**
736  * A list of modules that defines the YUI core (overrides the default).
737  *
738  * @property core
739  * @type string[]
740  */
741
742 /**
743  * The default date format
744  *
745  * @property dateFormat
746  * @type string
747  */
748
749 /**
750  * The default locale
751  *
752  * @property locale
753  * @type string
754  */
755
756 /**
757  * The default interval when polling in milliseconds.
758  *
759  * @property pollInterval
760  * @type int
761  * @default 20
762  */
763
764 /**
765  * The number of dynamic nodes to insert by default before
766  * automatically removing them.  This applies to script nodes
767  * because remove the node will not make the evaluated script
768  * unavailable.  Dynamic CSS is not auto purged, because removing
769  * a linked style sheet will also remove the style definitions.
770  *
771  * @property purgethreshold
772  * @type int
773  * @default 20
774  */
775
776 /**
777  * The default interval when polling in milliseconds.
778  *
779  * @property windowResizeDelay
780  * @type int
781  * @default 40
782  */
783
784 /**
785  * Base directory for dynamic loading
786  *
787  * @property base
788  * @type string
789  */
790
791 /**
792  * The secure base dir (not implemented)
793  *
794  * For dynamic loading.
795  *
796  * @property secureBase
797  * @type string
798  */
799
800 /**
801  * The YUI combo service base dir. Ex: http://yui.yahooapis.com/combo?
802  *
803  * For dynamic loading.
804  *
805  * @property comboBase
806  * @type string
807  */
808
809 /**
810  * The root path to prepend to module names for the combo service. Ex: 3.0.0b1/build/
811  *
812  * For dynamic loading.
813  *
814  * @property root
815  * @type string
816  */
817
818 /**
819  * A filter to apply to result urls.  This filter will modify the default
820  * path for all modules.  The default path for the YUI library is the
821  * minified version of the files (e.g., event-min.js).  The filter property
822  * can be a predefined filter or a custom filter.  The valid predefined 
823  * filters are:
824  * <dl>
825  *  <dt>DEBUG</dt>
826  *  <dd>Selects the debug versions of the library (e.g., event-debug.js).
827  *      This option will automatically include the Logger widget</dd>
828  *  <dt>RAW</dt>
829  *  <dd>Selects the non-minified version of the library (e.g., event.js).</dd>
830  * </dl>
831  * You can also define a custom filter, which must be an object literal 
832  * containing a search expression and a replace string:
833  * <pre>
834  *  myFilter: &#123; 
835  *      'searchExp': "-min\\.js", 
836  *      'replaceStr': "-debug.js"
837  *  &#125;
838  * </pre>
839  *
840  * For dynamic loading.
841  *
842  * @property filter
843  * @type string|object
844  */
845
846 /**
847  * Hash of per-component filter specification.  If specified for a given component, 
848  * this overrides the filter config
849  *
850  * For dynamic loading.
851  *
852  * @property filters
853  * @type object
854  */
855
856 /**
857  * Use the YUI combo service to reduce the number of http connections 
858  * required to load your dependencies.
859  *
860  * For dynamic loading.
861  *
862  * @property combine
863  * @type boolean
864  * @default true if 'base' is not supplied, false if it is.
865  */
866
867 /**
868  * A list of modules that should never be dynamically loaded
869  *
870  * @property ignore
871  * @type string[]
872  */
873
874 /**
875  * A list of modules that should always be loaded when required, even if already 
876  * present on the page.
877  *
878  * @property force
879  * @type string[]
880  */
881
882 /**
883  * Node or id for a node that should be used as the insertion point for new nodes
884  * For dynamic loading.
885  *
886  * @property insertBefore
887  * @type string
888  */
889
890 /**
891  * charset for dynamic nodes
892  *
893  * @property charset
894  * @type string
895  * @deprecated use jsAttributes cssAttributes
896  */
897
898 /**
899  * Object literal containing attributes to add to dynamically loaded script nodes.
900  *
901  * @property jsAttributes
902  * @type string
903  */
904
905 /**
906  * Object literal containing attributes to add to dynamically loaded link nodes.
907  *
908  * @property cssAttributes
909  * @type string
910  */
911
912 /**
913  * Number of milliseconds before a timeout occurs when dynamically 
914  * loading nodes. If not set, there is no timeout.
915  *
916  * @property timeout
917  * @type int
918  */
919
920 /**
921  * Callback for the 'CSSComplete' event.  When dynamically loading YUI 
922  * components with CSS, this property fires when the CSS is finished
923  * loading but script loading is still ongoing.  This provides an
924  * opportunity to enhance the presentation of a loading page a little
925  * bit before the entire loading process is done.
926  *
927  * @property onCSS
928  * @type function
929  */
930
931 /**
932  * A list of module definitions to add to the list of YUI components.  
933  * These components can then be dynamically loaded side by side with
934  * YUI via the use() method.See Loader.addModule for the supported
935  * module metadata.
936  *
937  * @property modules
938  * @type function
939  */
940  
941 /**
942  * The loader 'path' attribute to the loader itself.  This is combined
943  * with the 'base' attribute to dynamically load the loader component
944  * when boostrapping with the get utility alone.
945  *
946  * @property loaderPath
947  * @default loader/loader-min.js
948  */
949 YUI.add('yui-base', function(Y) {
950
951 /*
952  * YUI stub
953  * @module yui
954  * @submodule yui-base
955  */
956 (function() {
957
958 var INSTANCE = Y,
959     LOGEVENT = 'yui:log',
960     UNDEFINED = 'undefined',
961     LEVELS = { debug: 1, info: 1, warn: 1, error: 1 },
962     _published;
963
964 /**
965  * If the 'debug' config is true, a 'yui:log' event will be
966  * dispatched, which the Console widget and anything else
967  * can consume.  If the 'useBrowserConsole' config is true, it will
968  * write to the browser console if available.  YUI-specific log
969  * messages will only be present in the -debug versions of the
970  * JS files.  The build system is supposed to remove log statements
971  * from the raw and minified versions of the files.
972  *
973  * @method log
974  * @for YUI
975  * @param  {String}  msg  The message to log.
976  * @param  {String}  cat  The log category for the message.  Default
977  *                        categories are "info", "warn", "error", time".
978  *                        Custom categories can be used as well. (opt)
979  * @param  {String}  src  The source of the the message (opt)
980  * @param  {boolean} silent If true, the log event won't fire
981  * @return {YUI}      YUI instance
982  */
983 INSTANCE.log = function(msg, cat, src, silent) {
984     var Y = INSTANCE, c = Y.config, bail = false, excl, incl, m, f;
985     // suppress log message if the config is off or the event stack
986     // or the event call stack contains a consumer of the yui:log event
987     if (c.debug) {
988         // apply source filters
989         if (src) {
990
991             excl = c.logExclude; 
992             incl = c.logInclude;
993
994             if (incl && !(src in incl)) {
995                 bail = 1;
996             } else if (excl && (src in excl)) {
997                 bail = 1;
998             }
999         }
1000
1001         if (!bail) {
1002
1003             if (c.useBrowserConsole) {
1004                 m = (src) ? src + ': ' + msg : msg;
1005                 if (typeof console != UNDEFINED && console.log) {
1006                     f = (cat && console[cat] && (cat in LEVELS)) ? cat : 'log';
1007                     console[f](m);
1008                 } else if (typeof opera != UNDEFINED) {
1009                     opera.postError(m);
1010                 }
1011             }
1012
1013             if (Y.fire && !bail && !silent) {
1014                 if (!_published) {
1015                     Y.publish(LOGEVENT, {
1016                         broadcast: 2,
1017                         emitFacade: 1
1018                     });
1019
1020                     _published = 1;
1021
1022                 }
1023                 Y.fire(LOGEVENT, {
1024                     msg: msg, 
1025                     cat: cat, 
1026                     src: src
1027                 });
1028             }
1029         }
1030     }
1031
1032     return Y;
1033 };
1034
1035 /**
1036  * Write a system message.  This message will be preserved in the
1037  * minified and raw versions of the YUI files, unlike log statements.
1038  * @method message
1039  * @for YUI
1040  * @param  {String}  msg  The message to log.
1041  * @param  {String}  cat  The log category for the message.  Default
1042  *                        categories are "info", "warn", "error", time".
1043  *                        Custom categories can be used as well. (opt)
1044  * @param  {String}  src  The source of the the message (opt)
1045  * @param  {boolean} silent If true, the log event won't fire
1046  * @return {YUI}      YUI instance
1047  */
1048 INSTANCE.message = function() {
1049     return INSTANCE.log.apply(INSTANCE, arguments);
1050 };
1051
1052 })();
1053 (function() {
1054 /**
1055  * Provides the language utilites and extensions used by the library
1056  * @class Lang
1057  * @static
1058  */
1059 Y.Lang    = Y.Lang || {};
1060
1061 var L     = Y.Lang, 
1062
1063 ARRAY     = 'array',
1064 BOOLEAN   = 'boolean',
1065 DATE      = 'date',
1066 ERROR     = 'error',
1067 FUNCTION  = 'function',
1068 NUMBER    = 'number',
1069 NULL      = 'null',
1070 OBJECT    = 'object',
1071 REGEX     = 'regexp',
1072 STRING    = 'string',
1073 TOSTRING  = Object.prototype.toString,
1074 UNDEFINED = 'undefined',
1075
1076 TYPES     = {
1077     'undefined'         : UNDEFINED,
1078     'number'            : NUMBER,
1079     'boolean'           : BOOLEAN,
1080     'string'            : STRING,
1081     '[object Function]' : FUNCTION,
1082     '[object RegExp]'   : REGEX,
1083     '[object Array]'    : ARRAY,
1084     '[object Date]'     : DATE,
1085     '[object Error]'    : ERROR 
1086 },
1087
1088 TRIMREGEX = /^\s+|\s+$/g,
1089 EMPTYSTRING = '';
1090
1091 /**
1092  * Determines whether or not the provided item is an array.
1093  * Returns false for array-like collections such as the
1094  * function arguments collection or HTMLElement collection
1095  * will return false.  You can use @see Array.test if you 
1096  * want to
1097  * @method isArray
1098  * @static
1099  * @param o The object to test
1100  * @return {boolean} true if o is an array
1101  */
1102 L.isArray = function(o) { 
1103     return L.type(o) === ARRAY;
1104 };
1105
1106 /**
1107  * Determines whether or not the provided item is a boolean
1108  * @method isBoolean
1109  * @static
1110  * @param o The object to test
1111  * @return {boolean} true if o is a boolean
1112  */
1113 L.isBoolean = function(o) {
1114     return typeof o === BOOLEAN;
1115 };
1116
1117 /**
1118  * Determines whether or not the provided item is a function
1119  * Note: Internet Explorer thinks certain functions are objects:
1120  *
1121  * var obj = document.createElement("object");
1122  * Y.Lang.isFunction(obj.getAttribute) // reports false in IE
1123  *
1124  * var input = document.createElement("input"); // append to body
1125  * Y.Lang.isFunction(input.focus) // reports false in IE
1126  *
1127  * You will have to implement additional tests if these functions
1128  * matter to you.
1129  *
1130  * @method isFunction
1131  * @static
1132  * @param o The object to test
1133  * @return {boolean} true if o is a function
1134  */
1135 L.isFunction = function(o) {
1136     return L.type(o) === FUNCTION;
1137 };
1138     
1139 /**
1140  * Determines whether or not the supplied item is a date instance
1141  * @method isDate
1142  * @static
1143  * @param o The object to test
1144  * @return {boolean} true if o is a date
1145  */
1146 L.isDate = function(o) {
1147     // return o instanceof Date;
1148     return L.type(o) === DATE;
1149 };
1150
1151 /**
1152  * Determines whether or not the provided item is null
1153  * @method isNull
1154  * @static
1155  * @param o The object to test
1156  * @return {boolean} true if o is null
1157  */
1158 L.isNull = function(o) {
1159     return o === null;
1160 };
1161     
1162 /**
1163  * Determines whether or not the provided item is a legal number
1164  * @method isNumber
1165  * @static
1166  * @param o The object to test
1167  * @return {boolean} true if o is a number
1168  */
1169 L.isNumber = function(o) {
1170     return typeof o === NUMBER && isFinite(o);
1171 };
1172   
1173 /**
1174  * Determines whether or not the provided item is of type object
1175  * or function
1176  * @method isObject
1177  * @static
1178  * @param o The object to test
1179  * @param failfn {boolean} fail if the input is a function
1180  * @return {boolean} true if o is an object
1181  */  
1182 L.isObject = function(o, failfn) {
1183 return (o && (typeof o === OBJECT || (!failfn && L.isFunction(o)))) || false;
1184 };
1185     
1186 /**
1187  * Determines whether or not the provided item is a string
1188  * @method isString
1189  * @static
1190  * @param o The object to test
1191  * @return {boolean} true if o is a string
1192  */
1193 L.isString = function(o) {
1194     return typeof o === STRING;
1195 };
1196     
1197 /**
1198  * Determines whether or not the provided item is undefined
1199  * @method isUndefined
1200  * @static
1201  * @param o The object to test
1202  * @return {boolean} true if o is undefined
1203  */
1204 L.isUndefined = function(o) {
1205     return typeof o === UNDEFINED;
1206 };
1207
1208 /**
1209  * Returns a string without any leading or trailing whitespace.  If 
1210  * the input is not a string, the input will be returned untouched.
1211  * @method trim
1212  * @static
1213  * @param s {string} the string to trim
1214  * @return {string} the trimmed string
1215  */
1216 L.trim = function(s){
1217     try {
1218         return s.replace(TRIMREGEX, EMPTYSTRING);
1219     } catch(e) {
1220         return s;
1221     }
1222 };
1223
1224 /**
1225  * A convenience method for detecting a legitimate non-null value.
1226  * Returns false for null/undefined/NaN, true for other values, 
1227  * including 0/false/''
1228  * @method isValue
1229  * @static
1230  * @param o The item to test
1231  * @return {boolean} true if it is not null/undefined/NaN || false
1232  */
1233 L.isValue = function(o) {
1234     var t = L.type(o);
1235     switch (t) {
1236         case NUMBER:
1237             return isFinite(o);
1238         case NULL:
1239         case UNDEFINED:
1240             return false;
1241         default:
1242             return !!(t);
1243     }
1244 };
1245
1246 /**
1247  * Returns a string representing the type of the item passed in.
1248  * @method type
1249  * @param o the item to test
1250  * @return {string} the detected type
1251  */
1252 L.type = function (o) {
1253     return  TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? OBJECT : NULL);
1254 };
1255
1256 })();
1257
1258 /*
1259  * Provides information about the environment hosting YUI
1260  * @module yui
1261  * @submodule Array
1262  */
1263
1264 (function() {
1265
1266 var L = Y.Lang, Native = Array.prototype,
1267
1268 /**
1269  * Adds the following array utilities to the YUI instance.  Additional
1270  * array helpers can be found in the collection component.
1271  * @class Array
1272  */
1273
1274 /** 
1275  * Y.Array(o) returns an array:
1276  * - Arrays are return unmodified unless the start position is specified.
1277  * - "Array-like" collections (@see Array.test) are converted to arrays
1278  * - For everything else, a new array is created with the input as the sole item
1279  * - The start position is used if the input is or is like an array to return
1280  *   a subset of the collection.
1281  *
1282  *   @TODO this will not automatically convert elements that are also collections
1283  *   such as forms and selects.  Passing true as the third param will
1284  *   force a conversion.
1285  *
1286  * @method ()
1287  * @static
1288  *   @param o the item to arrayify
1289  *   @param i {int} if an array or array-like, this is the start index
1290  *   @param al {boolean} if true, it forces the array-like fork.  This
1291  *   can be used to avoid multiple array.test calls.
1292  *   @return {Array} the resulting array
1293  */
1294 YArray = function(o, startIdx, al) {
1295     var t = (al) ? 2 : Y.Array.test(o), i, l, a;
1296
1297     // switch (t) {
1298     //     case 1:
1299     //         // return (startIdx) ? o.slice(startIdx) : o;
1300     //     case 2:
1301     //         return Native.slice.call(o, startIdx || 0);
1302     //     default:
1303     //         return [o];
1304     // }
1305
1306     if (t) {
1307         try {
1308             return Native.slice.call(o, startIdx || 0);
1309         // IE errors when trying to slice element collections
1310         } catch(e) {
1311             a=[];
1312             for (i=0, l=o.length; i<l; i=i+1) {
1313                 a.push(o[i]);
1314             }
1315             return a;
1316         }
1317     } else {
1318         return [o];
1319     }
1320
1321 };
1322
1323 Y.Array = YArray;
1324
1325 /** 
1326  * Evaluates the input to determine if it is an array, array-like, or 
1327  * something else.  This is used to handle the arguments collection 
1328  * available within functions, and HTMLElement collections
1329  *
1330  * @method test
1331  * @static
1332  *
1333  * @todo current implementation (intenionally) will not implicitly 
1334  * handle html elements that are array-like (forms, selects, etc).  
1335  *
1336  * @return {int} a number indicating the results:
1337  * 0: Not an array or an array-like collection
1338  * 1: A real array. 
1339  * 2: array-like collection.
1340  */
1341 YArray.test = function(o) {
1342     var r = 0;
1343     if (L.isObject(o)) {
1344         if (L.isArray(o)) {
1345             r = 1; 
1346         } else {
1347             try {
1348                 // indexed, but no tagName (element) or alert (window)
1349                 if ("length" in o && !("tagName" in o) && !("alert" in o) && 
1350                     (!Y.Lang.isFunction(o.size) || o.size() > 1)) {
1351                     r = 2;
1352                 }
1353                     
1354             } catch(e) {}
1355         }
1356     }
1357     return r;
1358 };
1359
1360 /**
1361  * Executes the supplied function on each item in the array.
1362  * @method each
1363  * @param a {Array} the array to iterate
1364  * @param f {Function} the function to execute on each item
1365  * @param o Optional context object
1366  * @static
1367  * @return {YUI} the YUI instance
1368  */
1369 YArray.each = (Native.forEach) ?
1370     function (a, f, o) { 
1371         Native.forEach.call(a || [], f, o || Y);
1372         return Y;
1373     } :
1374     function (a, f, o) { 
1375         var l = (a && a.length) || 0, i;
1376         for (i = 0; i < l; i=i+1) {
1377             f.call(o || Y, a[i], i, a);
1378         }
1379         return Y;
1380     };
1381
1382 /**
1383  * Returns an object using the first array as keys, and
1384  * the second as values.  If the second array is not
1385  * provided the value is set to true for each.
1386  * @method hash
1387  * @static
1388  * @param k {Array} keyset
1389  * @param v {Array} optional valueset
1390  * @return {object} the hash
1391  */
1392 YArray.hash = function(k, v) {
1393     var o = {}, l = k.length, vl = v && v.length, i;
1394     for (i=0; i<l; i=i+1) {
1395         o[k[i]] = (vl && vl > i) ? v[i] : true;
1396     }
1397
1398     return o;
1399 };
1400
1401 /**
1402  * Returns the index of the first item in the array
1403  * that contains the specified value, -1 if the
1404  * value isn't found.
1405  * @method indexOf
1406  * @static
1407  * @param a {Array} the array to search
1408  * @param val the value to search for
1409  * @return {int} the index of the item that contains the value or -1
1410  */
1411 YArray.indexOf = (Native.indexOf) ?
1412     function(a, val) {
1413         return Native.indexOf.call(a, val);
1414     } :
1415     function(a, val) {
1416         for (var i=0; i<a.length; i=i+1) {
1417             if (a[i] === val) {
1418                 return i;
1419             }
1420         }
1421
1422         return -1;
1423     };
1424
1425 /**
1426  * Numeric sort convenience function.
1427  * Y.ArrayAssert.itemsAreEqual([1, 2, 3], [3, 1, 2].sort(Y.Array.numericSort));
1428  * @method numericSort
1429  */
1430 YArray.numericSort = function(a, b) { 
1431     return (a - b); 
1432 };
1433
1434 /**
1435  * Executes the supplied function on each item in the array.
1436  * Returning true from the processing function will stop the 
1437  * processing of the remaining
1438  * items.
1439  * @method some
1440  * @param a {Array} the array to iterate
1441  * @param f {Function} the function to execute on each item
1442  * @param o Optional context object
1443  * @static
1444  * @return {boolean} true if the function returns true on
1445  * any of the items in the array
1446  */
1447  YArray.some = (Native.some) ?
1448     function (a, f, o) { 
1449         return Native.some.call(a, f, o);
1450     } :
1451     function (a, f, o) {
1452         var l = a.length, i;
1453         for (i=0; i<l; i=i+1) {
1454             if (f.call(o, a[i], i, a)) {
1455                 return true;
1456             }
1457         }
1458         return false;
1459     };
1460
1461 })();
1462 (function() {
1463
1464 var L = Y.Lang, 
1465 DELIMITER = '__',
1466 // FROZEN = {
1467 //     'prototype': 1,
1468 //     '_yuid': 1
1469 // },
1470
1471 /*
1472  * IE will not enumerate native functions in a derived object even if the
1473  * function was overridden.  This is a workaround for specific functions 
1474  * we care about on the Object prototype. 
1475  * @property _iefix
1476  * @for YUI
1477  * @param {Function} r  the object to receive the augmentation
1478  * @param {Function} s  the object that supplies the properties to augment
1479  * @private
1480  */
1481 _iefix = function(r, s) {
1482     var fn = s.toString;
1483     if (L.isFunction(fn) && fn != Object.prototype.toString) {
1484         r.toString = fn;
1485     }
1486 };
1487
1488
1489 /**
1490  * Returns a new object containing all of the properties of
1491  * all the supplied objects.  The properties from later objects
1492  * will overwrite those in earlier objects.  Passing in a
1493  * single object will create a shallow copy of it.  For a deep
1494  * copy, use clone.
1495  * @method merge
1496  * @for YUI
1497  * @param arguments {Object*} the objects to merge
1498  * @return {object} the new merged object
1499  */
1500 Y.merge = function() {
1501     var a = arguments, o = {}, i, l = a.length;
1502     for (i=0; i<l; i=i+1) {
1503         Y.mix(o, a[i], true);
1504     }
1505     return o;
1506 };
1507    
1508 /**
1509  * Applies the supplier's properties to the receiver.  By default
1510  * all prototype and static propertes on the supplier are applied
1511  * to the corresponding spot on the receiver.  By default all
1512  * properties are applied, and a property that is already on the
1513  * reciever will not be overwritten.  The default behavior can
1514  * be modified by supplying the appropriate parameters.
1515  *
1516  * @TODO add constants for the modes
1517  *
1518  * @method mix
1519  * @param {Function} r  the object to receive the augmentation
1520  * @param {Function} s  the object that supplies the properties to augment
1521  * @param ov {boolean} if true, properties already on the receiver
1522  * will be overwritten if found on the supplier.
1523  * @param wl {string[]} a whitelist.  If supplied, only properties in 
1524  * this list will be applied to the receiver.
1525  * @param {int} mode what should be copies, and to where
1526  *        default(0): object to object
1527  *        1: prototype to prototype (old augment)
1528  *        2: prototype to prototype and object props (new augment)
1529  *        3: prototype to object
1530  *        4: object to prototype
1531  * @param merge {boolean} merge objects instead of overwriting/ignoring
1532  * Used by Y.aggregate
1533  * @return {object} the augmented object
1534  */
1535 Y.mix = function(r, s, ov, wl, mode, merge) {
1536
1537     if (!s||!r) {
1538         return r || Y;
1539     }
1540
1541     if (mode) {
1542         switch (mode) {
1543             case 1: // proto to proto
1544                 return Y.mix(r.prototype, s.prototype, ov, wl, 0, merge);
1545             case 2: // object to object and proto to proto
1546                 Y.mix(r.prototype, s.prototype, ov, wl, 0, merge);
1547                 break; // pass through 
1548             case 3: // proto to static
1549                 return Y.mix(r, s.prototype, ov, wl, 0, merge);
1550             case 4: // static to proto
1551                 return Y.mix(r.prototype, s, ov, wl, 0, merge);
1552             default:  // object to object is what happens below
1553         }
1554     }
1555
1556     // Maybe don't even need this wl && wl.length check anymore??
1557     var arr = merge && L.isArray(r), i, l, p;
1558
1559     if (wl && wl.length) {
1560         for (i = 0, l = wl.length; i < l; ++i) {
1561             p = wl[i];
1562             if (p in s) {
1563                 if (merge && L.isObject(r[p], true)) {
1564                     Y.mix(r[p], s[p]);
1565                 } else if (!arr && (ov || !(p in r))) {
1566                     r[p] = s[p];
1567                 } else if (arr) {
1568                     r.push(s[p]);
1569                 }
1570             }
1571         }
1572     } else {
1573         for (i in s) { 
1574             // if (s.hasOwnProperty(i) && !(i in FROZEN)) {
1575                 // check white list if it was supplied
1576                 // if the receiver has this property, it is an object,
1577                 // and merge is specified, merge the two objects.
1578                 if (merge && L.isObject(r[i], true)) {
1579                     Y.mix(r[i], s[i]); // recursive
1580                 // otherwise apply the property only if overwrite
1581                 // is specified or the receiver doesn't have one.
1582                 } else if (!arr && (ov || !(i in r))) {
1583                     r[i] = s[i];
1584                 // if merge is specified and the receiver is an array,
1585                 // append the array item
1586                 } else if (arr) {
1587                     r.push(s[i]);
1588                 }
1589             // }
1590         }
1591     
1592         if (Y.UA.ie) {
1593             _iefix(r, s);
1594         }
1595     }
1596
1597     return r;
1598 };
1599
1600 /**
1601  * Returns a wrapper for a function which caches the
1602  * return value of that function, keyed off of the combined 
1603  * argument values.
1604  * @function cached
1605  * @param source {function} the function to memoize
1606  * @param cache an optional cache seed
1607  * @param refetch if supplied, this value is tested against the cached
1608  * value.  If the values are equal, the wrapped function is executed again.
1609  * @return {Function} the wrapped function
1610  */
1611 Y.cached = function(source, cache, refetch){
1612     cache = cache || {};
1613
1614     return function(arg1, arg2) {
1615
1616         var k = (arg2) ? Array.prototype.join.call(arguments, DELIMITER) : arg1,
1617             v = cache[k];
1618
1619         if (!(k in cache) || (refetch && cache[k] == refetch)) {
1620             cache[k] = source.apply(source, arguments);
1621         }
1622
1623         return cache[k];
1624     };
1625
1626 };
1627
1628 })();
1629
1630 (function() {
1631
1632 /**
1633  * Adds the following Object utilities to the YUI instance
1634  * @class Object
1635  */
1636
1637 /**
1638  * Y.Object(o) returns a new object based upon the supplied object.  
1639  * @TODO Use native Object.create() when available
1640  * @method ()
1641  * @static
1642  * @param o the supplier object
1643  * @return {Object} the new object
1644  */
1645 Y.Object = function(o) {
1646     var F = function() {};
1647     F.prototype = o;
1648     return new F();
1649 }; 
1650
1651 var O = Y.Object,
1652
1653 UNDEFINED = undefined,
1654
1655 /**
1656  * Extracts the keys, values, or size from an object
1657  * 
1658  * @method _extract
1659  * @param o the object
1660  * @param what what to extract (0: keys, 1: values, 2: size)
1661  * @return {boolean|Array} the extracted info
1662  * @static
1663  * @private
1664  */
1665 _extract = function(o, what) {
1666     var count = (what === 2), out = (count) ? 0 : [], i;
1667
1668     for (i in o) {
1669         if (count) {
1670             out++;
1671         } else {
1672             if (o.hasOwnProperty(i)) {
1673                 out.push((what) ? o[i] : i);
1674             }
1675         }
1676     }
1677
1678     return out;
1679 };
1680
1681 /**
1682  * Returns an array containing the object's keys
1683  * @TODO use native Object.keys() if available
1684  * @method keys
1685  * @static
1686  * @param o an object
1687  * @return {string[]} the keys
1688  */
1689 O.keys = function(o) {
1690     return _extract(o);
1691 };
1692
1693 /**
1694  * Returns an array containing the object's values
1695  * @TODO use native Object.values() if available
1696  * @method values
1697  * @static
1698  * @param o an object
1699  * @return {Array} the values
1700  */
1701 O.values = function(o) {
1702     return _extract(o, 1);
1703 };
1704
1705 /**
1706  * Returns the size of an object
1707  * @TODO use native Object.size() if available
1708  * @method size
1709  * @static
1710  * @param o an object
1711  * @return {int} the size
1712  */
1713 O.size = function(o) {
1714     return _extract(o, 2);
1715 };
1716
1717 /**
1718  * Returns true if the object contains a given key
1719  * @method hasKey
1720  * @static
1721  * @param o an object
1722  * @param k the key to query
1723  * @return {boolean} true if the object contains the key
1724  */
1725 O.hasKey = function(o, k) {
1726     // return (o.hasOwnProperty(k));
1727     return (k in o);
1728 };
1729
1730 /**
1731  * Returns true if the object contains a given value
1732  * @method hasValue
1733  * @static
1734  * @param o an object
1735  * @param v the value to query
1736  * @return {boolean} true if the object contains the value
1737  */
1738 O.hasValue = function(o, v) {
1739     return (Y.Array.indexOf(O.values(o), v) > -1);
1740 };
1741
1742 /**
1743  * Determines whether or not the property was added
1744  * to the object instance.  Returns false if the property is not present
1745  * in the object, or was inherited from the prototype.
1746  *
1747  * @deprecated Safari 1.x support has been removed, so this is simply a 
1748  * wrapper for the native implementation.  Use the native implementation
1749  * directly instead.
1750  *
1751  * @TODO Remove in B1
1752  *
1753  * @method owns
1754  * @static
1755  * @param o {any} The object being testing
1756  * @param p {string} the property to look for
1757  * @return {boolean} true if the object has the property on the instance
1758  */
1759 O.owns = function(o, k) {
1760     return (o.hasOwnProperty(k));
1761 };
1762
1763 /**
1764  * Executes a function on each item. The function
1765  * receives the value, the key, and the object
1766  * as paramters (in that order).
1767  * @method each
1768  * @static
1769  * @param o the object to iterate
1770  * @param f {function} the function to execute
1771  * @param c the execution context
1772  * @param proto {boolean} include proto
1773  * @return {YUI} the YUI instance
1774  */
1775 O.each = function (o, f, c, proto) {
1776     var s = c || Y, i;
1777
1778     for (i in o) {
1779         if (proto || o.hasOwnProperty(i)) {
1780             f.call(s, o[i], i, o);
1781         }
1782     }
1783     return Y;
1784 };
1785
1786 /**
1787  * Retrieves the sub value at the provided path,
1788  * from the value object provided.
1789  *
1790  * @method getValue
1791  * @param o The object from which to extract the property value
1792  * @param path {Array} A path array, specifying the object traversal path
1793  * from which to obtain the sub value.
1794  * @return {Any} The value stored in the path, undefined if not found.
1795  * Returns the source object if an empty path is provided.
1796  */
1797 O.getValue = function (o, path) {
1798     var p=Y.Array(path), l=p.length, i;
1799
1800     for (i=0; o !== UNDEFINED && i < l; i=i+1) {
1801         o = o[p[i]];
1802     }
1803
1804     return o;
1805 };
1806
1807 /**
1808  * Sets the sub-attribute value at the provided path on the 
1809  * value object.  Returns the modified value object, or 
1810  * undefined if the path is invalid.
1811  *
1812  * @method setValue
1813  * @param o             The object on which to set the sub value.
1814  * @param path {Array}  A path array, specifying the object traversal path
1815  *                      at which to set the sub value.
1816  * @param val {Any}     The new value for the sub-attribute.
1817  * @return {Object}     The modified object, with the new sub value set, or 
1818  *                      undefined, if the path was invalid.
1819  */
1820 O.setValue = function(o, path, val) {
1821
1822     var p=Y.Array(path), leafIdx=p.length-1, i, ref=o;
1823
1824     if (leafIdx >= 0) {
1825         for (i=0; ref !== UNDEFINED && i < leafIdx; i=i+1) {
1826             ref = ref[p[i]];
1827         }
1828
1829         if (ref !== UNDEFINED) {
1830             ref[p[i]] = val;
1831         } else {
1832             return UNDEFINED;
1833         }
1834     }
1835
1836     return o;
1837 };
1838
1839
1840 })();
1841
1842 /*
1843  * Provides information about the environment hosting YUI
1844  * @module yui
1845  * @submodule UA
1846  */
1847 /**
1848  * YUI user agent detection.
1849  * Do not fork for a browser if it can be avoided.  Use feature detection when
1850  * you can.  Use the user agent as a last resort.  UA stores a version
1851  * number for the browser engine, 0 otherwise.  This value may or may not map
1852  * to the version number of the browser using the engine.  The value is 
1853  * presented as a float so that it can easily be used for boolean evaluation 
1854  * as well as for looking for a particular range of versions.  Because of this, 
1855  * some of the granularity of the version info may be lost (e.g., Gecko 1.8.0.9 
1856  * reports 1.8).
1857  * @class UA
1858  * @static
1859  */
1860 Y.UA = function() {
1861
1862     var numberfy = function(s) {
1863             var c = 0;
1864             return parseFloat(s.replace(/\./g, function() {
1865                 return (c++ == 1) ? '' : '.';
1866             }));
1867         },
1868     
1869         nav = navigator,
1870
1871         o = {
1872
1873         /**
1874          * Internet Explorer version number or 0.  Example: 6
1875          * @property ie
1876          * @type float
1877          * @static
1878          */
1879         ie: 0,
1880
1881         /**
1882          * Opera version number or 0.  Example: 9.2
1883          * @property opera
1884          * @type float
1885          * @static
1886          */
1887         opera: 0,
1888
1889         /**
1890          * Gecko engine revision number.  Will evaluate to 1 if Gecko 
1891          * is detected but the revision could not be found. Other browsers
1892          * will be 0.  Example: 1.8
1893          * <pre>
1894          * Firefox 1.0.0.4: 1.7.8   <-- Reports 1.7
1895          * Firefox 1.5.0.9: 1.8.0.9 <-- Reports 1.8
1896          * Firefox 2.0.0.3: 1.8.1.3 <-- Reports 1.8
1897          * Firefox 3 alpha: 1.9a4   <-- Reports 1.9
1898          * </pre>
1899          * @property gecko
1900          * @type float
1901          * @static
1902          */
1903         gecko: 0,
1904
1905         /**
1906          * AppleWebKit version.  KHTML browsers that are not WebKit browsers 
1907          * will evaluate to 1, other browsers 0.  Example: 418.9
1908          * <pre>
1909          * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the 
1910          *                                   latest available for Mac OSX 10.3.
1911          * Safari 2.0.2:         416     <-- hasOwnProperty introduced
1912          * Safari 2.0.4:         418     <-- preventDefault fixed
1913          * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
1914          *                                   different versions of webkit
1915          * Safari 2.0.4 (419.3): 419     <-- Tiger installations that have been
1916          *                                   updated, but not updated
1917          *                                   to the latest patch.
1918          * Webkit 212 nightly:   522+    <-- Safari 3.0 precursor (with native SVG
1919          *                                   and many major issues fixed).
1920          * Safari 3.0.4 (523.12) 523.12  <-- First Tiger release - automatic update
1921          *                                   from 2.x via the 10.4.11 OS patch
1922          * Webkit nightly 1/2008:525+    <-- Supports DOMContentLoaded event.
1923          *                                   yahoo.com user agent hack removed.
1924          * </pre>
1925          * http://en.wikipedia.org/wiki/Safari_(web_browser)#Version_history
1926          * @property webkit
1927          * @type float
1928          * @static
1929          */
1930         webkit: 0,
1931
1932         /**
1933          * The mobile property will be set to a string containing any relevant
1934          * user agent information when a modern mobile browser is detected.
1935          * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
1936          * devices with the WebKit-based browser, and Opera Mini.  
1937          * @property mobile 
1938          * @type string
1939          * @static
1940          */
1941         mobile: null,
1942
1943         /**
1944          * Adobe AIR version number or 0.  Only populated if webkit is detected.
1945          * Example: 1.0
1946          * @property air
1947          * @type float
1948          */
1949         air: 0,
1950
1951         /**
1952          * Google Caja version number or 0.
1953          * @property caja
1954          * @type float
1955          */
1956         caja: nav.cajaVersion,
1957
1958         /**
1959          * Set to true if the page appears to be in SSL
1960          * @property secure
1961          * @type boolean
1962          * @static
1963          */
1964         secure: false,
1965
1966         /**
1967          * The operating system.  Currently only detecting windows or macintosh
1968          * @property os
1969          * @type string
1970          * @static
1971          */
1972         os: null
1973         
1974     },
1975
1976     ua = nav && nav.userAgent, 
1977
1978     loc = Y.config.win.location,
1979
1980     href = loc && loc.href,
1981     
1982     m;
1983
1984     o.secure = href && (href.toLowerCase().indexOf("https") === 0);
1985
1986     if (ua) {
1987
1988         if ((/windows|win32/i).test(ua)) {
1989             o.os = 'windows';
1990         } else if ((/macintosh/i).test(ua)) {
1991             o.os = 'macintosh';
1992         }
1993
1994         // Modern KHTML browsers should qualify as Safari X-Grade
1995         if ((/KHTML/).test(ua)) {
1996             o.webkit=1;
1997         }
1998         // Modern WebKit browsers are at least X-Grade
1999         m=ua.match(/AppleWebKit\/([^\s]*)/);
2000         if (m&&m[1]) {
2001             o.webkit=numberfy(m[1]);
2002
2003             // Mobile browser check
2004             if (/ Mobile\//.test(ua)) {
2005                 o.mobile = "Apple"; // iPhone or iPod Touch
2006             } else {
2007                 m=ua.match(/NokiaN[^\/]*|Android \d\.\d|webOS\/\d\.\d/);
2008                 if (m) {
2009                     o.mobile = m[0]; // Nokia N-series, Android, webOS, ex: NokiaN95
2010                 }
2011             }
2012
2013             m=ua.match(/AdobeAIR\/([^\s]*)/);
2014             if (m) {
2015                 o.air = m[0]; // Adobe AIR 1.0 or better
2016             }
2017
2018         }
2019
2020         if (!o.webkit) { // not webkit
2021             // @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
2022             m=ua.match(/Opera[\s\/]([^\s]*)/);
2023             if (m&&m[1]) {
2024                 o.opera=numberfy(m[1]);
2025                 m=ua.match(/Opera Mini[^;]*/);
2026                 if (m) {
2027                     o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
2028                 }
2029             } else { // not opera or webkit
2030                 m=ua.match(/MSIE\s([^;]*)/);
2031                 if (m&&m[1]) {
2032                     o.ie=numberfy(m[1]);
2033                 } else { // not opera, webkit, or ie
2034                     m=ua.match(/Gecko\/([^\s]*)/);
2035                     if (m) {
2036                         o.gecko=1; // Gecko detected, look for revision
2037                         m=ua.match(/rv:([^\s\)]*)/);
2038                         if (m&&m[1]) {
2039                             o.gecko=numberfy(m[1]);
2040                         }
2041                     }
2042                 }
2043             }
2044         }
2045     }
2046     
2047     return o;
2048 }();
2049 (function() {
2050     var L = Y.Lang,
2051
2052     /**
2053      * Executes the supplied function in the context of the supplied 
2054      * object 'when' milliseconds later.  Executes the function a 
2055      * single time unless periodic is set to true.
2056      * @method later
2057      * @for YUI
2058      * @param when {int} the number of milliseconds to wait until the fn 
2059      * is executed.
2060      * @param o the context object.
2061      * @param fn {Function|String} the function to execute or the name of 
2062      * the method in the 'o' object to execute.
2063      * @param data [Array] data that is provided to the function.  This accepts
2064      * either a single item or an array.  If an array is provided, the
2065      * function is executed with one parameter for each array item.  If
2066      * you need to pass a single array parameter, it needs to be wrapped in
2067      * an array [myarray].
2068      * @param periodic {boolean} if true, executes continuously at supplied 
2069      * interval until canceled.
2070      * @return {object} a timer object. Call the cancel() method on this object to 
2071      * stop the timer.
2072      */
2073     later = function(when, o, fn, data, periodic) {
2074         when = when || 0; 
2075         o = o || {};
2076         var m=fn, d=data, f, r;
2077
2078         if (L.isString(fn)) {
2079             m = o[fn];
2080         }
2081
2082         if (!m) {
2083             Y.error("method undefined");
2084         }
2085
2086         if (!L.isArray(d)) {
2087             d = [data];
2088         }
2089
2090         f = function() {
2091             m.apply(o, d);
2092         };
2093
2094         r = (periodic) ? setInterval(f, when) : setTimeout(f, when);
2095
2096         return {
2097             id: r,
2098             interval: periodic,
2099             cancel: function() {
2100                 if (this.interval) {
2101                     clearInterval(r);
2102                 } else {
2103                     clearTimeout(r);
2104                 }
2105             }
2106         };
2107     };
2108
2109     Y.later = later;
2110     L.later = later;
2111
2112 })();
2113 (function() {
2114
2115     var min = ['yui-base'], core, C = Y.config, LOADER='loader';
2116
2117     // apply the minimal required functionality
2118     Y.use.apply(Y, min);
2119
2120
2121     if (C.core) {
2122         core = C.core;
2123     } else {
2124         core = ['queue-base', 'get'];
2125         if (YUI.Env.mods[LOADER]) {
2126             core.push(LOADER);
2127         }
2128     }
2129
2130     Y.use.apply(Y, core);
2131      
2132 })();
2133
2134
2135
2136 }, '3.0.0' );