src/cm/media/js/lib/yui/yui3-3.15.0/build/yui-base/yui-base-debug.js
changeset 602 e16a97fb364a
equal deleted inserted replaced
601:d334a616c023 602:e16a97fb364a
       
     1 /**
       
     2 The YUI module contains the components required for building the YUI seed file.
       
     3 This includes the script loading mechanism, a simple queue, and the core
       
     4 utilities for the library.
       
     5 
       
     6 @module yui
       
     7 @main yui
       
     8 @submodule yui-base
       
     9 **/
       
    10 
       
    11 /*jshint eqeqeq: false*/
       
    12 if (typeof YUI != 'undefined') {
       
    13     YUI._YUI = YUI;
       
    14 }
       
    15 
       
    16 /**
       
    17 The YUI global namespace object. This is the constructor for all YUI instances.
       
    18 
       
    19 This is a self-instantiable factory function, meaning you don't need to precede
       
    20 it with the `new` operator. You can invoke it directly like this:
       
    21 
       
    22     YUI().use('*', function (Y) {
       
    23         // Y is a new YUI instance.
       
    24     });
       
    25 
       
    26 But it also works like this:
       
    27 
       
    28     var Y = YUI();
       
    29 
       
    30 The `YUI` constructor accepts an optional config object, like this:
       
    31 
       
    32     YUI({
       
    33         debug: true,
       
    34         combine: false
       
    35     }).use('node', function (Y) {
       
    36         // Y.Node is ready to use.
       
    37     });
       
    38 
       
    39 See the API docs for the <a href="config.html">Config</a> class for the complete
       
    40 list of supported configuration properties accepted by the YUI constuctor.
       
    41 
       
    42 If a global `YUI` object is already defined, the existing YUI object will not be
       
    43 overwritten, to ensure that defined namespaces are preserved.
       
    44 
       
    45 Each YUI instance has full custom event support, but only if the event system is
       
    46 available.
       
    47 
       
    48 @class YUI
       
    49 @uses EventTarget
       
    50 @constructor
       
    51 @global
       
    52 @param {Object} [config]* Zero or more optional configuration objects. Config
       
    53     values are stored in the `Y.config` property. See the
       
    54     <a href="config.html">Config</a> docs for the list of supported properties.
       
    55 **/
       
    56 
       
    57     /*global YUI*/
       
    58     /*global YUI_config*/
       
    59     var YUI = function() {
       
    60         var i = 0,
       
    61             Y = this,
       
    62             args = arguments,
       
    63             l = args.length,
       
    64             instanceOf = function(o, type) {
       
    65                 return (o && o.hasOwnProperty && (o instanceof type));
       
    66             },
       
    67             gconf = (typeof YUI_config !== 'undefined') && YUI_config;
       
    68 
       
    69         if (!(instanceOf(Y, YUI))) {
       
    70             Y = new YUI();
       
    71         } else {
       
    72             // set up the core environment
       
    73             Y._init();
       
    74 
       
    75             /**
       
    76             Master configuration that might span multiple contexts in a non-
       
    77             browser environment. It is applied first to all instances in all
       
    78             contexts.
       
    79 
       
    80             @example
       
    81 
       
    82                 YUI.GlobalConfig = {
       
    83                     filter: 'debug'
       
    84                 };
       
    85 
       
    86                 YUI().use('node', function (Y) {
       
    87                     // debug files used here
       
    88                 });
       
    89 
       
    90                 YUI({
       
    91                     filter: 'min'
       
    92                 }).use('node', function (Y) {
       
    93                     // min files used here
       
    94                 });
       
    95 
       
    96             @property {Object} GlobalConfig
       
    97             @global
       
    98             @static
       
    99             **/
       
   100             if (YUI.GlobalConfig) {
       
   101                 Y.applyConfig(YUI.GlobalConfig);
       
   102             }
       
   103 
       
   104             /**
       
   105             Page-level config applied to all YUI instances created on the
       
   106             current page. This is applied after `YUI.GlobalConfig` and before
       
   107             any instance-level configuration.
       
   108 
       
   109             @example
       
   110 
       
   111                 // Single global var to include before YUI seed file
       
   112                 YUI_config = {
       
   113                     filter: 'debug'
       
   114                 };
       
   115 
       
   116                 YUI().use('node', function (Y) {
       
   117                     // debug files used here
       
   118                 });
       
   119 
       
   120                 YUI({
       
   121                     filter: 'min'
       
   122                 }).use('node', function (Y) {
       
   123                     // min files used here
       
   124                 });
       
   125 
       
   126             @property {Object} YUI_config
       
   127             @global
       
   128             **/
       
   129             if (gconf) {
       
   130                 Y.applyConfig(gconf);
       
   131             }
       
   132 
       
   133             // bind the specified additional modules for this instance
       
   134             if (!l) {
       
   135                 Y._setup();
       
   136             }
       
   137         }
       
   138 
       
   139         if (l) {
       
   140             // Each instance can accept one or more configuration objects.
       
   141             // These are applied after YUI.GlobalConfig and YUI_Config,
       
   142             // overriding values set in those config files if there is a
       
   143             // matching property.
       
   144             for (; i < l; i++) {
       
   145                 Y.applyConfig(args[i]);
       
   146             }
       
   147 
       
   148             Y._setup();
       
   149         }
       
   150 
       
   151         Y.instanceOf = instanceOf;
       
   152 
       
   153         return Y;
       
   154     };
       
   155 
       
   156 (function() {
       
   157 
       
   158     var proto, prop,
       
   159         VERSION = '@VERSION@',
       
   160         PERIOD = '.',
       
   161         BASE = 'http://yui.yahooapis.com/',
       
   162         /*
       
   163             These CSS class names can't be generated by
       
   164             getClassName since it is not available at the
       
   165             time they are being used.
       
   166         */
       
   167         DOC_LABEL = 'yui3-js-enabled',
       
   168         CSS_STAMP_EL = 'yui3-css-stamp',
       
   169         NOOP = function() {},
       
   170         SLICE = Array.prototype.slice,
       
   171         APPLY_TO_AUTH = { 'io.xdrReady': 1,   // the functions applyTo
       
   172                           'io.xdrResponse': 1,   // can call. this should
       
   173                           'SWF.eventHandler': 1 }, // be done at build time
       
   174         hasWin = (typeof window != 'undefined'),
       
   175         win = (hasWin) ? window : null,
       
   176         doc = (hasWin) ? win.document : null,
       
   177         docEl = doc && doc.documentElement,
       
   178         docClass = docEl && docEl.className,
       
   179         instances = {},
       
   180         time = new Date().getTime(),
       
   181         add = function(el, type, fn, capture) {
       
   182             if (el && el.addEventListener) {
       
   183                 el.addEventListener(type, fn, capture);
       
   184             } else if (el && el.attachEvent) {
       
   185                 el.attachEvent('on' + type, fn);
       
   186             }
       
   187         },
       
   188         remove = function(el, type, fn, capture) {
       
   189             if (el && el.removeEventListener) {
       
   190                 // this can throw an uncaught exception in FF
       
   191                 try {
       
   192                     el.removeEventListener(type, fn, capture);
       
   193                 } catch (ex) {}
       
   194             } else if (el && el.detachEvent) {
       
   195                 el.detachEvent('on' + type, fn);
       
   196             }
       
   197         },
       
   198         handleReady = function() {
       
   199             YUI.Env.DOMReady = true;
       
   200             if (hasWin) {
       
   201                 remove(doc, 'DOMContentLoaded', handleReady);
       
   202             }        
       
   203         },
       
   204         handleLoad = function() {
       
   205             YUI.Env.windowLoaded = true;
       
   206             YUI.Env.DOMReady = true;
       
   207             if (hasWin) {
       
   208                 remove(window, 'load', handleLoad);
       
   209             }
       
   210         },
       
   211         getLoader = function(Y, o) {
       
   212             var loader = Y.Env._loader,
       
   213                 lCore = [ 'loader-base' ],
       
   214                 G_ENV = YUI.Env,
       
   215                 mods = G_ENV.mods;
       
   216 
       
   217             if (loader) {
       
   218                 //loader._config(Y.config);
       
   219                 loader.ignoreRegistered = false;
       
   220                 loader.onEnd = null;
       
   221                 loader.data = null;
       
   222                 loader.required = [];
       
   223                 loader.loadType = null;
       
   224             } else {
       
   225                 loader = new Y.Loader(Y.config);
       
   226                 Y.Env._loader = loader;
       
   227             }
       
   228             if (mods && mods.loader) {
       
   229                 lCore = [].concat(lCore, YUI.Env.loaderExtras);
       
   230             }
       
   231             YUI.Env.core = Y.Array.dedupe([].concat(YUI.Env.core, lCore));
       
   232 
       
   233             return loader;
       
   234         },
       
   235 
       
   236         clobber = function(r, s) {
       
   237             for (var i in s) {
       
   238                 if (s.hasOwnProperty(i)) {
       
   239                     r[i] = s[i];
       
   240                 }
       
   241             }
       
   242         },
       
   243 
       
   244         ALREADY_DONE = { success: true };
       
   245 
       
   246 //  Stamp the documentElement (HTML) with a class of "yui-loaded" to
       
   247 //  enable styles that need to key off of JS being enabled.
       
   248 if (docEl && docClass.indexOf(DOC_LABEL) == -1) {
       
   249     if (docClass) {
       
   250         docClass += ' ';
       
   251     }
       
   252     docClass += DOC_LABEL;
       
   253     docEl.className = docClass;
       
   254 }
       
   255 
       
   256 if (VERSION.indexOf('@') > -1) {
       
   257     VERSION = '3.5.0'; // dev time hack for cdn test
       
   258 }
       
   259 
       
   260 proto = {
       
   261     /**
       
   262     Applies a new configuration object to the config of this YUI instance. This
       
   263     will merge new group/module definitions, and will also update the loader
       
   264     cache if necessary. Updating `Y.config` directly will not update the cache.
       
   265 
       
   266     @method applyConfig
       
   267     @param {Object} o the configuration object.
       
   268     @since 3.2.0
       
   269     **/
       
   270     applyConfig: function(o) {
       
   271 
       
   272         o = o || NOOP;
       
   273 
       
   274         var attr,
       
   275             name,
       
   276             // detail,
       
   277             config = this.config,
       
   278             mods = config.modules,
       
   279             groups = config.groups,
       
   280             aliases = config.aliases,
       
   281             loader = this.Env._loader;
       
   282 
       
   283         for (name in o) {
       
   284             if (o.hasOwnProperty(name)) {
       
   285                 attr = o[name];
       
   286                 if (mods && name == 'modules') {
       
   287                     clobber(mods, attr);
       
   288                 } else if (aliases && name == 'aliases') {
       
   289                     clobber(aliases, attr);
       
   290                 } else if (groups && name == 'groups') {
       
   291                     clobber(groups, attr);
       
   292                 } else if (name == 'win') {
       
   293                     config[name] = (attr && attr.contentWindow) || attr;
       
   294                     config.doc = config[name] ? config[name].document : null;
       
   295                 } else if (name == '_yuid') {
       
   296                     // preserve the guid
       
   297                 } else {
       
   298                     config[name] = attr;
       
   299                 }
       
   300             }
       
   301         }
       
   302 
       
   303         if (loader) {
       
   304             loader._config(o);
       
   305         }
       
   306 
       
   307     },
       
   308 
       
   309     /**
       
   310     Old way to apply a config to this instance (calls `applyConfig` under the
       
   311     hood).
       
   312 
       
   313     @private
       
   314     @method _config
       
   315     @param {Object} o The config to apply
       
   316     **/
       
   317     _config: function(o) {
       
   318         this.applyConfig(o);
       
   319     },
       
   320 
       
   321     /**
       
   322     Initializes this YUI instance.
       
   323 
       
   324     @private
       
   325     @method _init
       
   326     **/
       
   327     _init: function() {
       
   328         var filter, el,
       
   329             Y = this,
       
   330             G_ENV = YUI.Env,
       
   331             Env = Y.Env,
       
   332             prop;
       
   333 
       
   334         /**
       
   335         The version number of this YUI instance.
       
   336 
       
   337         This value is typically updated by a script when a YUI release is built,
       
   338         so it may not reflect the correct version number when YUI is run from
       
   339         the development source tree.
       
   340 
       
   341         @property {String} version
       
   342         **/
       
   343         Y.version = VERSION;
       
   344 
       
   345         if (!Env) {
       
   346             Y.Env = {
       
   347                 core: ['get', 'features', 'intl-base', 'yui-log', 'yui-later'],
       
   348                 loaderExtras: ['loader-rollup', 'loader-yui3'],
       
   349                 mods: {}, // flat module map
       
   350                 versions: {}, // version module map
       
   351                 base: BASE,
       
   352                 cdn: BASE + VERSION + '/build/',
       
   353                 // bootstrapped: false,
       
   354                 _idx: 0,
       
   355                 _used: {},
       
   356                 _attached: {},
       
   357                 _exported: {},
       
   358                 _missed: [],
       
   359                 _yidx: 0,
       
   360                 _uidx: 0,
       
   361                 _guidp: 'y',
       
   362                 _loaded: {},
       
   363                 // serviced: {},
       
   364                 // Regex in English:
       
   365                 // I'll start at the \b(yui).
       
   366                 // 1. Look in the test string for "yui" or
       
   367                 //    "yui-base" or "yui-davglass" or "yui-foobar" that comes after a word break.  That is, it
       
   368                 //    can't match "foyui" or "i_heart_yui". This can be anywhere in the string.
       
   369                 // 2. After #1 must come a forward slash followed by the string matched in #1, so
       
   370                 //    "yui-base/yui-base" or "yui-pants/yui-pants".
       
   371                 // 3. The second occurence of the #1 token can optionally be followed by "-debug" or "-min",
       
   372                 //    so "yui/yui-min", "yui/yui-debug", "yui-base/yui-base-debug". NOT "yui/yui-tshirt".
       
   373                 // 4. This is followed by ".js", so "yui/yui.js".
       
   374                 // 0. Going back to the beginning, now. If all that stuff in 1-4 comes after a "?" in the string,
       
   375                 //    then capture the junk between the LAST "&" and the string in 1-4.  So
       
   376                 //    "blah?foo/yui/yui.js" will capture "foo/" and "blah?some/thing.js&3.3.0/build/yui-davglass/yui-davglass.js"
       
   377                 //    will capture "3.3.0/build/"
       
   378                 //
       
   379                 // Regex Exploded:
       
   380                 // (?:\?             Find a ?
       
   381                 //   (?:[^&]*&)      followed by 0..n characters followed by an &
       
   382                 //   *               in fact, find as many sets of characters followed by a & as you can
       
   383                 //   ([^&]*)         capture the stuff after the last & in \1
       
   384                 // )?                but it's ok if all this ?junk&more_junk stuff isn't even there
       
   385                 // \b(               after a word break find either the string
       
   386                 //    yui(?:-\w+)?   "yui" optionally followed by a -, then more characters
       
   387                 // )                 and store the yui-* string in \2
       
   388                 // \/\2              then comes a / followed by the yui-* string in \2
       
   389                 // (?:-(min|debug))? optionally followed by "-min" or "-debug"
       
   390                 // .js               and ending in ".js"
       
   391                 _BASE_RE: /(?:\?(?:[^&]*&)*([^&]*))?\b(yui(?:-\w+)?)\/\2(?:-(min|debug))?\.js/,
       
   392                 parseBasePath: function(src, pattern) {
       
   393                     var match = src.match(pattern),
       
   394                         path, filter;
       
   395 
       
   396                     if (match) {
       
   397                         path = RegExp.leftContext || src.slice(0, src.indexOf(match[0]));
       
   398 
       
   399                         // this is to set up the path to the loader.  The file
       
   400                         // filter for loader should match the yui include.
       
   401                         filter = match[3];
       
   402 
       
   403                         // extract correct path for mixed combo urls
       
   404                         // http://yuilibrary.com/projects/yui3/ticket/2528423
       
   405                         if (match[1]) {
       
   406                             path += '?' + match[1];
       
   407                         }
       
   408                         path = {
       
   409                             filter: filter,
       
   410                             path: path
       
   411                         };
       
   412                     }
       
   413                     return path;
       
   414                 },
       
   415                 getBase: G_ENV && G_ENV.getBase ||
       
   416                         function(pattern) {
       
   417                             var nodes = (doc && doc.getElementsByTagName('script')) || [],
       
   418                                 path = Env.cdn, parsed,
       
   419                                 i, len, src;
       
   420 
       
   421                             for (i = 0, len = nodes.length; i < len; ++i) {
       
   422                                 src = nodes[i].src;
       
   423                                 if (src) {
       
   424                                     parsed = Y.Env.parseBasePath(src, pattern);
       
   425                                     if (parsed) {
       
   426                                         filter = parsed.filter;
       
   427                                         path = parsed.path;
       
   428                                         break;
       
   429                                     }
       
   430                                 }
       
   431                             }
       
   432 
       
   433                             // use CDN default
       
   434                             return path;
       
   435                         }
       
   436 
       
   437             };
       
   438 
       
   439             Env = Y.Env;
       
   440 
       
   441             Env._loaded[VERSION] = {};
       
   442 
       
   443             if (G_ENV && Y !== YUI) {
       
   444                 Env._yidx = ++G_ENV._yidx;
       
   445                 Env._guidp = ('yui_' + VERSION + '_' +
       
   446                              Env._yidx + '_' + time).replace(/[^a-z0-9_]+/g, '_');
       
   447             } else if (YUI._YUI) {
       
   448 
       
   449                 G_ENV = YUI._YUI.Env;
       
   450                 Env._yidx += G_ENV._yidx;
       
   451                 Env._uidx += G_ENV._uidx;
       
   452 
       
   453                 for (prop in G_ENV) {
       
   454                     if (!(prop in Env)) {
       
   455                         Env[prop] = G_ENV[prop];
       
   456                     }
       
   457                 }
       
   458 
       
   459                 delete YUI._YUI;
       
   460             }
       
   461 
       
   462             Y.id = Y.stamp(Y);
       
   463             instances[Y.id] = Y;
       
   464 
       
   465         }
       
   466 
       
   467         Y.constructor = YUI;
       
   468 
       
   469         // configuration defaults
       
   470         Y.config = Y.config || {
       
   471             bootstrap: true,
       
   472             cacheUse: true,
       
   473             debug: true,
       
   474             doc: doc,
       
   475             fetchCSS: true,
       
   476             throwFail: true,
       
   477             useBrowserConsole: true,
       
   478             useNativeES5: true,
       
   479             win: win,
       
   480             global: Function('return this')()
       
   481         };
       
   482 
       
   483         //Register the CSS stamp element
       
   484         if (doc && !doc.getElementById(CSS_STAMP_EL)) {
       
   485             el = doc.createElement('div');
       
   486             el.innerHTML = '<div id="' + CSS_STAMP_EL + '" style="position: absolute !important; visibility: hidden !important"></div>';
       
   487             YUI.Env.cssStampEl = el.firstChild;
       
   488             if (doc.body) {
       
   489                 doc.body.appendChild(YUI.Env.cssStampEl);
       
   490             } else {
       
   491                 docEl.insertBefore(YUI.Env.cssStampEl, docEl.firstChild);
       
   492             }
       
   493         } else if (doc && doc.getElementById(CSS_STAMP_EL) && !YUI.Env.cssStampEl) {
       
   494             YUI.Env.cssStampEl = doc.getElementById(CSS_STAMP_EL);
       
   495         }
       
   496 
       
   497         Y.config.lang = Y.config.lang || 'en-US';
       
   498 
       
   499         Y.config.base = YUI.config.base || Y.Env.getBase(Y.Env._BASE_RE);
       
   500 
       
   501         if (!filter || (!('mindebug').indexOf(filter))) {
       
   502             filter = 'min';
       
   503         }
       
   504         filter = (filter) ? '-' + filter : filter;
       
   505         Y.config.loaderPath = YUI.config.loaderPath || 'loader/loader' + filter + '.js';
       
   506 
       
   507     },
       
   508 
       
   509     /**
       
   510     Finishes the instance setup. Attaches whatever YUI modules were defined
       
   511     at the time that this instance was created.
       
   512 
       
   513     @method _setup
       
   514     @private
       
   515     **/
       
   516     _setup: function() {
       
   517         var i, Y = this,
       
   518             core = [],
       
   519             mods = YUI.Env.mods,
       
   520             extras = Y.config.core || [].concat(YUI.Env.core); //Clone it..
       
   521 
       
   522         for (i = 0; i < extras.length; i++) {
       
   523             if (mods[extras[i]]) {
       
   524                 core.push(extras[i]);
       
   525             }
       
   526         }
       
   527 
       
   528         Y._attach(['yui-base']);
       
   529         Y._attach(core);
       
   530 
       
   531         if (Y.Loader) {
       
   532             getLoader(Y);
       
   533         }
       
   534 
       
   535         // Y.log(Y.id + ' initialized', 'info', 'yui');
       
   536     },
       
   537 
       
   538     /**
       
   539     Executes the named method on the specified YUI instance if that method is
       
   540     whitelisted.
       
   541 
       
   542     @method applyTo
       
   543     @param {String} id YUI instance id.
       
   544     @param {String} method Name of the method to execute. For example:
       
   545         'Object.keys'.
       
   546     @param {Array} args Arguments to apply to the method.
       
   547     @return {Mixed} Return value from the applied method, or `null` if the
       
   548         specified instance was not found or the method was not whitelisted.
       
   549     **/
       
   550     applyTo: function(id, method, args) {
       
   551         if (!(method in APPLY_TO_AUTH)) {
       
   552             this.log(method + ': applyTo not allowed', 'warn', 'yui');
       
   553             return null;
       
   554         }
       
   555 
       
   556         var instance = instances[id], nest, m, i;
       
   557         if (instance) {
       
   558             nest = method.split('.');
       
   559             m = instance;
       
   560             for (i = 0; i < nest.length; i = i + 1) {
       
   561                 m = m[nest[i]];
       
   562                 if (!m) {
       
   563                     this.log('applyTo not found: ' + method, 'warn', 'yui');
       
   564                 }
       
   565             }
       
   566             return m && m.apply(instance, args);
       
   567         }
       
   568 
       
   569         return null;
       
   570     },
       
   571 
       
   572 /**
       
   573 Registers a YUI module and makes it available for use in a `YUI().use()` call or
       
   574 as a dependency for other modules.
       
   575 
       
   576 The easiest way to create a first-class YUI module is to use
       
   577 <a href="http://yui.github.com/shifter/">Shifter</a>, the YUI component build
       
   578 tool.
       
   579 
       
   580 Shifter will automatically wrap your module code in a `YUI.add()` call along
       
   581 with any configuration info required for the module.
       
   582 
       
   583 @example
       
   584 
       
   585     YUI.add('davglass', function (Y) {
       
   586         Y.davglass = function () {
       
   587             Y.log('Dav was here!');
       
   588         };
       
   589     }, '3.4.0', {
       
   590         requires: ['harley-davidson', 'mt-dew']
       
   591     });
       
   592 
       
   593 @method add
       
   594 @param {String} name Module name.
       
   595 @param {Function} fn Function containing module code. This function will be
       
   596     executed whenever the module is attached to a specific YUI instance.
       
   597 
       
   598     @param {YUI} fn.Y The YUI instance to which this module is attached.
       
   599     @param {String} fn.name Name of the module
       
   600 
       
   601 @param {String} version Module version number. This is currently used only for
       
   602     informational purposes, and is not used internally by YUI.
       
   603 
       
   604 @param {Object} [config] Module config.
       
   605     @param {Array} [config.requires] Array of other module names that must be
       
   606         attached before this module can be attached.
       
   607     @param {Array} [config.optional] Array of optional module names that should
       
   608         be attached before this module is attached if they've already been
       
   609         loaded. If the `loadOptional` YUI option is `true`, optional modules
       
   610         that have not yet been loaded will be loaded just as if they were hard
       
   611         requirements.
       
   612     @param {Array} [config.use] Array of module names that are included within
       
   613         or otherwise provided by this module, and which should be attached
       
   614         automatically when this module is attached. This makes it possible to
       
   615         create "virtual rollup" modules that simply attach a collection of other
       
   616         modules or submodules.
       
   617 
       
   618 @return {YUI} This YUI instance.
       
   619 **/
       
   620     add: function(name, fn, version, details) {
       
   621         details = details || {};
       
   622         var env = YUI.Env,
       
   623             mod = {
       
   624                 name: name,
       
   625                 fn: fn,
       
   626                 version: version,
       
   627                 details: details
       
   628             },
       
   629             //Instance hash so we don't apply it to the same instance twice
       
   630             applied = {},
       
   631             loader, inst,
       
   632             i, versions = env.versions;
       
   633 
       
   634         env.mods[name] = mod;
       
   635         versions[version] = versions[version] || {};
       
   636         versions[version][name] = mod;
       
   637 
       
   638         for (i in instances) {
       
   639             if (instances.hasOwnProperty(i)) {
       
   640                 inst = instances[i];
       
   641                 if (!applied[inst.id]) {
       
   642                     applied[inst.id] = true;
       
   643                     loader = inst.Env._loader;
       
   644                     if (loader) {
       
   645                         if (!loader.moduleInfo[name] || loader.moduleInfo[name].temp) {
       
   646                             loader.addModule(details, name);
       
   647                         }
       
   648                     }
       
   649                 }
       
   650             }
       
   651         }
       
   652 
       
   653         return this;
       
   654     },
       
   655 
       
   656     /**
       
   657     Executes the callback function associated with each required module,
       
   658     attaching the module to this YUI instance.
       
   659 
       
   660     @method _attach
       
   661     @param {Array} r The array of modules to attach
       
   662     @param {Boolean} [moot=false] If `true`, don't throw a warning if the module
       
   663         is not attached.
       
   664     @private
       
   665     **/
       
   666     _attach: function(r, moot) {
       
   667         var i, name, mod, details, req, use, after,
       
   668             mods = YUI.Env.mods,
       
   669             aliases = YUI.Env.aliases,
       
   670             Y = this, j,
       
   671             cache = YUI.Env._renderedMods,
       
   672             loader = Y.Env._loader,
       
   673             done = Y.Env._attached,
       
   674             exported = Y.Env._exported,
       
   675             len = r.length, loader, def, go,
       
   676             c = [],
       
   677             modArgs, esCompat, reqlen,
       
   678             condition,
       
   679             __exports__, __imports__;
       
   680 
       
   681         //Check for conditional modules (in a second+ instance) and add their requirements
       
   682         //TODO I hate this entire method, it needs to be fixed ASAP (3.5.0) ^davglass
       
   683         for (i = 0; i < len; i++) {
       
   684             name = r[i];
       
   685             mod = mods[name];
       
   686             c.push(name);
       
   687             if (loader && loader.conditions[name]) {
       
   688                 for (j in loader.conditions[name]) {
       
   689                     if (loader.conditions[name].hasOwnProperty(j)) {
       
   690                         def = loader.conditions[name][j];
       
   691                         go = def && ((def.ua && Y.UA[def.ua]) || (def.test && def.test(Y)));
       
   692                         if (go) {
       
   693                             c.push(def.name);
       
   694                         }
       
   695                     }
       
   696                 }
       
   697             }
       
   698         }
       
   699         r = c;
       
   700         len = r.length;
       
   701 
       
   702         for (i = 0; i < len; i++) {
       
   703             if (!done[r[i]]) {
       
   704                 name = r[i];
       
   705                 mod = mods[name];
       
   706 
       
   707                 if (aliases && aliases[name] && !mod) {
       
   708                     Y._attach(aliases[name]);
       
   709                     continue;
       
   710                 }
       
   711                 if (!mod) {
       
   712                     if (loader && loader.moduleInfo[name]) {
       
   713                         mod = loader.moduleInfo[name];
       
   714                         moot = true;
       
   715                     }
       
   716 
       
   717                     // Y.log('no js def for: ' + name, 'info', 'yui');
       
   718 
       
   719                     //if (!loader || !loader.moduleInfo[name]) {
       
   720                     //if ((!loader || !loader.moduleInfo[name]) && !moot) {
       
   721                     if (!moot && name) {
       
   722                         if ((name.indexOf('skin-') === -1) && (name.indexOf('css') === -1)) {
       
   723                             Y.Env._missed.push(name);
       
   724                             Y.Env._missed = Y.Array.dedupe(Y.Env._missed);
       
   725                             Y.message('NOT loaded: ' + name, 'warn', 'yui');
       
   726                         }
       
   727                     }
       
   728                 } else {
       
   729                     done[name] = true;
       
   730                     //Don't like this, but in case a mod was asked for once, then we fetch it
       
   731                     //We need to remove it from the missed list ^davglass
       
   732                     for (j = 0; j < Y.Env._missed.length; j++) {
       
   733                         if (Y.Env._missed[j] === name) {
       
   734                             Y.message('Found: ' + name + ' (was reported as missing earlier)', 'warn', 'yui');
       
   735                             Y.Env._missed.splice(j, 1);
       
   736                         }
       
   737                     }
       
   738                     /*
       
   739                         If it's a temp module, we need to redo it's requirements if it's already loaded
       
   740                         since it may have been loaded by another instance and it's dependencies might
       
   741                         have been redefined inside the fetched file.
       
   742                     */
       
   743                     if (loader && cache && cache[name] && cache[name].temp) {
       
   744                         loader.getRequires(cache[name]);
       
   745                         req = [];
       
   746                         for (j in loader.moduleInfo[name].expanded_map) {
       
   747                             if (loader.moduleInfo[name].expanded_map.hasOwnProperty(j)) {
       
   748                                 req.push(j);
       
   749                             }
       
   750                         }
       
   751                         Y._attach(req);
       
   752                     }
       
   753 
       
   754                     details = mod.details;
       
   755                     req = details.requires;
       
   756                     esCompat = details.es;
       
   757                     use = details.use;
       
   758                     after = details.after;
       
   759                     //Force Intl load if there is a language (Loader logic) @todo fix this shit
       
   760                     if (details.lang) {
       
   761                         req = req || [];
       
   762                         req.unshift('intl');
       
   763                     }
       
   764 
       
   765                     if (req) {
       
   766                         reqlen = req.length;
       
   767                         for (j = 0; j < reqlen; j++) {
       
   768                             if (!done[req[j]]) {
       
   769                                 if (!Y._attach(req)) {
       
   770                                     return false;
       
   771                                 }
       
   772                                 break;
       
   773                             }
       
   774                         }
       
   775                     }
       
   776 
       
   777                     if (after) {
       
   778                         for (j = 0; j < after.length; j++) {
       
   779                             if (!done[after[j]]) {
       
   780                                 if (!Y._attach(after, true)) {
       
   781                                     return false;
       
   782                                 }
       
   783                                 break;
       
   784                             }
       
   785                         }
       
   786                     }
       
   787 
       
   788                     if (mod.fn) {
       
   789                         modArgs = [Y, name];
       
   790                         if (esCompat) {
       
   791                             __imports__ = {};
       
   792                             __exports__ = {};
       
   793                             // passing `exports` and `imports` onto the module function
       
   794                             modArgs.push(__imports__, __exports__);
       
   795                             if (req) {
       
   796                                 reqlen = req.length;
       
   797                                 for (j = 0; j < reqlen; j++) {
       
   798                                     __imports__[req[j]] = exported.hasOwnProperty(req[j]) ? exported[req[j]] : Y;
       
   799                                 }
       
   800                             }
       
   801                         }
       
   802                         if (Y.config.throwFail) {
       
   803                             __exports__ = mod.fn.apply(esCompat ? undefined : mod, modArgs);
       
   804                         } else {
       
   805                             try {
       
   806                                 __exports__ = mod.fn.apply(esCompat ? undefined : mod, modArgs);
       
   807                             } catch (e) {
       
   808                                 Y.error('Attach error: ' + name, e, name);
       
   809                                 return false;
       
   810                             }
       
   811                         }
       
   812                         if (esCompat) {
       
   813                             // store the `exports` in case others `es` modules requires it
       
   814                             exported[name] = __exports__;
       
   815 
       
   816                             // If an ES module is conditionally loaded and set
       
   817                             // to be used "instead" another module, replace the
       
   818                             // trigger module's content with the conditionally
       
   819                             // loaded one so the values returned by require()
       
   820                             // still makes sense
       
   821                             condition = mod.details.condition;
       
   822                             if (condition && condition.when === 'instead') {
       
   823                                 exported[condition.trigger] = __exports__;
       
   824                             }
       
   825                         }
       
   826                     }
       
   827 
       
   828                     if (use) {
       
   829                         for (j = 0; j < use.length; j++) {
       
   830                             if (!done[use[j]]) {
       
   831                                 if (!Y._attach(use)) {
       
   832                                     return false;
       
   833                                 }
       
   834                                 break;
       
   835                             }
       
   836                         }
       
   837                     }
       
   838 
       
   839 
       
   840 
       
   841                 }
       
   842             }
       
   843         }
       
   844 
       
   845         return true;
       
   846     },
       
   847 
       
   848     /**
       
   849     Delays the `use` callback until another event has taken place such as
       
   850     `window.onload`, `domready`, `contentready`, or `available`.
       
   851 
       
   852     @private
       
   853     @method _delayCallback
       
   854     @param {Function} cb The original `use` callback.
       
   855     @param {String|Object} until Either an event name ('load', 'domready', etc.)
       
   856         or an object containing event/args keys for contentready/available.
       
   857     @return {Function}
       
   858     **/
       
   859     _delayCallback: function(cb, until) {
       
   860 
       
   861         var Y = this,
       
   862             mod = ['event-base'];
       
   863 
       
   864         until = (Y.Lang.isObject(until) ? until : { event: until });
       
   865 
       
   866         if (until.event === 'load') {
       
   867             mod.push('event-synthetic');
       
   868         }
       
   869 
       
   870         Y.log('Delaying use callback until: ' + until.event, 'info', 'yui');
       
   871         return function() {
       
   872             Y.log('Use callback fired, waiting on delay', 'info', 'yui');
       
   873             var args = arguments;
       
   874             Y._use(mod, function() {
       
   875                 Y.log('Delayed use wrapper callback after dependencies', 'info', 'yui');
       
   876                 Y.on(until.event, function() {
       
   877                     args[1].delayUntil = until.event;
       
   878                     Y.log('Delayed use callback done after ' + until.event, 'info', 'yui');
       
   879                     cb.apply(Y, args);
       
   880                 }, until.args);
       
   881             });
       
   882         };
       
   883     },
       
   884 
       
   885     /**
       
   886     Attaches one or more modules to this YUI instance. When this is executed,
       
   887     the requirements of the desired modules are analyzed, and one of several
       
   888     things can happen:
       
   889 
       
   890 
       
   891       * All required modules have already been loaded, and just need to be
       
   892         attached to this YUI instance. In this case, the `use()` callback will
       
   893         be executed synchronously after the modules are attached.
       
   894 
       
   895       * One or more modules have not yet been loaded, or the Get utility is not
       
   896         available, or the `bootstrap` config option is `false`. In this case,
       
   897         a warning is issued indicating that modules are missing, but all
       
   898         available modules will still be attached and the `use()` callback will
       
   899         be executed synchronously.
       
   900 
       
   901       * One or more modules are missing and the Loader is not available but the
       
   902         Get utility is, and `bootstrap` is not `false`. In this case, the Get
       
   903         utility will be used to load the Loader, and we will then proceed to
       
   904         the following state:
       
   905 
       
   906       * One or more modules are missing and the Loader is available. In this
       
   907         case, the Loader will be used to resolve the dependency tree for the
       
   908         missing modules and load them and their dependencies. When the Loader is
       
   909         finished loading modules, the `use()` callback will be executed
       
   910         asynchronously.
       
   911 
       
   912     @example
       
   913 
       
   914         // Loads and attaches dd and its dependencies.
       
   915         YUI().use('dd', function (Y) {
       
   916             // ...
       
   917         });
       
   918 
       
   919         // Loads and attaches dd and node as well as all of their dependencies.
       
   920         YUI().use(['dd', 'node'], function (Y) {
       
   921             // ...
       
   922         });
       
   923 
       
   924         // Attaches all modules that have already been loaded.
       
   925         YUI().use('*', function (Y) {
       
   926             // ...
       
   927         });
       
   928 
       
   929         // Attaches a gallery module.
       
   930         YUI().use('gallery-yql', function (Y) {
       
   931             // ...
       
   932         });
       
   933 
       
   934         // Attaches a YUI 2in3 module.
       
   935         YUI().use('yui2-datatable', function (Y) {
       
   936             // ...
       
   937         });
       
   938 
       
   939     @method use
       
   940     @param {String|Array} modules* One or more module names to attach.
       
   941     @param {Function} [callback] Callback function to be executed once all
       
   942         specified modules and their dependencies have been attached.
       
   943     @param {YUI} callback.Y The YUI instance created for this sandbox.
       
   944     @param {Object} callback.status Object containing `success`, `msg` and
       
   945         `data` properties.
       
   946     @chainable
       
   947     **/
       
   948     use: function() {
       
   949         var args = SLICE.call(arguments, 0),
       
   950             callback = args[args.length - 1],
       
   951             Y = this,
       
   952             i = 0,
       
   953             name,
       
   954             Env = Y.Env,
       
   955             provisioned = true;
       
   956 
       
   957         // The last argument supplied to use can be a load complete callback
       
   958         if (Y.Lang.isFunction(callback)) {
       
   959             args.pop();
       
   960             if (Y.config.delayUntil) {
       
   961                 callback = Y._delayCallback(callback, Y.config.delayUntil);
       
   962             }
       
   963         } else {
       
   964             callback = null;
       
   965         }
       
   966         if (Y.Lang.isArray(args[0])) {
       
   967             args = args[0];
       
   968         }
       
   969 
       
   970         if (Y.config.cacheUse) {
       
   971             while ((name = args[i++])) {
       
   972                 if (!Env._attached[name]) {
       
   973                     provisioned = false;
       
   974                     break;
       
   975                 }
       
   976             }
       
   977 
       
   978             if (provisioned) {
       
   979                 if (args.length) {
       
   980                     Y.log('already provisioned: ' + args, 'info', 'yui');
       
   981                 }
       
   982                 Y._notify(callback, ALREADY_DONE, args);
       
   983                 return Y;
       
   984             }
       
   985         }
       
   986 
       
   987         if (Y._loading) {
       
   988             Y._useQueue = Y._useQueue || new Y.Queue();
       
   989             Y._useQueue.add([args, callback]);
       
   990         } else {
       
   991             Y._use(args, function(Y, response) {
       
   992                 Y._notify(callback, response, args);
       
   993             });
       
   994         }
       
   995 
       
   996         return Y;
       
   997     },
       
   998 
       
   999     /**
       
  1000     Sugar for loading both legacy and ES6-based YUI modules.
       
  1001 
       
  1002     @method require
       
  1003     @param {String} [modules*] List of module names to import or a single
       
  1004         module name.
       
  1005     @param {Function} callback Callback that gets called once all the modules
       
  1006         were loaded. Each parameter of the callback is the export value of the
       
  1007         corresponding module in the list. If the module is a legacy YUI module,
       
  1008         the YUI instance is used instead of the module exports.
       
  1009     @example
       
  1010     ```
       
  1011     YUI().require(['es6-set'], function (Y, imports) {
       
  1012         var Set = imports.Set,
       
  1013             set = new Set();
       
  1014     });
       
  1015     ```
       
  1016     **/
       
  1017     require: function () {
       
  1018         var args = SLICE.call(arguments),
       
  1019             callback;
       
  1020 
       
  1021         if (typeof args[args.length - 1] === 'function') {
       
  1022             callback = args.pop();
       
  1023 
       
  1024             // only add the callback if one was provided
       
  1025             // YUI().require('foo'); is valid
       
  1026             args.push(function (Y) {
       
  1027                 var i, length = args.length,
       
  1028                     exported = Y.Env._exported,
       
  1029                     __imports__ = {};
       
  1030 
       
  1031                 // Get only the imports requested as arguments
       
  1032                 for (i = 0; i < length; i++) {
       
  1033                     if (exported.hasOwnProperty(args[i])) {
       
  1034                         __imports__[args[i]] = exported[args[i]];
       
  1035                     }
       
  1036                 }
       
  1037 
       
  1038                 // Using `undefined` because:
       
  1039                 // - Using `Y.config.global` would force the value of `this` to be
       
  1040                 //   the global object even in strict mode
       
  1041                 // - Using `Y` goes against the goal of moving away from a shared
       
  1042                 //   object and start thinking in terms of imported and exported
       
  1043                 //   objects
       
  1044                 callback.call(undefined, Y, __imports__);
       
  1045             });
       
  1046         }
       
  1047         // Do not return the Y object. This makes it hard to follow this
       
  1048         // traditional pattern:
       
  1049         //   var Y = YUI().use(...);
       
  1050         // This is a good idea in the light of ES6 modules, to avoid working
       
  1051         // in the global scope.
       
  1052         // This also leaves the door open for returning a promise, once the
       
  1053         // YUI loader is based on the ES6 loader which uses
       
  1054         // loader.import(...).then(...)
       
  1055         this.use.apply(this, args);
       
  1056     },
       
  1057 
       
  1058     /**
       
  1059     Handles Loader notifications about attachment/load errors.
       
  1060 
       
  1061     @method _notify
       
  1062     @param {Function} callback Callback to pass to `Y.config.loadErrorFn`.
       
  1063     @param {Object} response Response returned from Loader.
       
  1064     @param {Array} args Arguments passed from Loader.
       
  1065     @private
       
  1066     **/
       
  1067     _notify: function(callback, response, args) {
       
  1068         if (!response.success && this.config.loadErrorFn) {
       
  1069             this.config.loadErrorFn.call(this, this, callback, response, args);
       
  1070         } else if (callback) {
       
  1071             if (this.Env._missed && this.Env._missed.length) {
       
  1072                 response.msg = 'Missing modules: ' + this.Env._missed.join();
       
  1073                 response.success = false;
       
  1074             }
       
  1075             if (this.config.throwFail) {
       
  1076                 callback(this, response);
       
  1077             } else {
       
  1078                 try {
       
  1079                     callback(this, response);
       
  1080                 } catch (e) {
       
  1081                     this.error('use callback error', e, args);
       
  1082                 }
       
  1083             }
       
  1084         }
       
  1085     },
       
  1086 
       
  1087     /**
       
  1088     Called from the `use` method queue to ensure that only one set of loading
       
  1089     logic is performed at a time.
       
  1090 
       
  1091     @method _use
       
  1092     @param {String} args* One or more modules to attach.
       
  1093     @param {Function} [callback] Function to call once all required modules have
       
  1094         been attached.
       
  1095     @private
       
  1096     **/
       
  1097     _use: function(args, callback) {
       
  1098 
       
  1099         if (!this.Array) {
       
  1100             this._attach(['yui-base']);
       
  1101         }
       
  1102 
       
  1103         var len, loader, handleBoot,
       
  1104             Y = this,
       
  1105             G_ENV = YUI.Env,
       
  1106             mods = G_ENV.mods,
       
  1107             Env = Y.Env,
       
  1108             used = Env._used,
       
  1109             aliases = G_ENV.aliases,
       
  1110             queue = G_ENV._loaderQueue,
       
  1111             firstArg = args[0],
       
  1112             YArray = Y.Array,
       
  1113             config = Y.config,
       
  1114             boot = config.bootstrap,
       
  1115             missing = [],
       
  1116             i,
       
  1117             r = [],
       
  1118             ret = true,
       
  1119             fetchCSS = config.fetchCSS,
       
  1120             process = function(names, skip) {
       
  1121 
       
  1122                 var i = 0, a = [], name, len, m, req, use;
       
  1123 
       
  1124                 if (!names.length) {
       
  1125                     return;
       
  1126                 }
       
  1127 
       
  1128                 if (aliases) {
       
  1129                     len = names.length;
       
  1130                     for (i = 0; i < len; i++) {
       
  1131                         if (aliases[names[i]] && !mods[names[i]]) {
       
  1132                             a = [].concat(a, aliases[names[i]]);
       
  1133                         } else {
       
  1134                             a.push(names[i]);
       
  1135                         }
       
  1136                     }
       
  1137                     names = a;
       
  1138                 }
       
  1139 
       
  1140                 len = names.length;
       
  1141 
       
  1142                 for (i = 0; i < len; i++) {
       
  1143                     name = names[i];
       
  1144                     if (!skip) {
       
  1145                         r.push(name);
       
  1146                     }
       
  1147 
       
  1148                     // only attach a module once
       
  1149                     if (used[name]) {
       
  1150                         continue;
       
  1151                     }
       
  1152 
       
  1153                     m = mods[name];
       
  1154                     req = null;
       
  1155                     use = null;
       
  1156 
       
  1157                     if (m) {
       
  1158                         used[name] = true;
       
  1159                         req = m.details.requires;
       
  1160                         use = m.details.use;
       
  1161                     } else {
       
  1162                         // CSS files don't register themselves, see if it has
       
  1163                         // been loaded
       
  1164                         if (!G_ENV._loaded[VERSION][name]) {
       
  1165                             missing.push(name);
       
  1166                         } else {
       
  1167                             used[name] = true; // probably css
       
  1168                         }
       
  1169                     }
       
  1170 
       
  1171                     // make sure requirements are attached
       
  1172                     if (req && req.length) {
       
  1173                         process(req);
       
  1174                     }
       
  1175 
       
  1176                     // make sure we grab the submodule dependencies too
       
  1177                     if (use && use.length) {
       
  1178                         process(use, 1);
       
  1179                     }
       
  1180                 }
       
  1181 
       
  1182             },
       
  1183 
       
  1184             handleLoader = function(fromLoader) {
       
  1185                 var response = fromLoader || {
       
  1186                         success: true,
       
  1187                         msg: 'not dynamic'
       
  1188                     },
       
  1189                     redo, origMissing,
       
  1190                     ret = true,
       
  1191                     data = response.data;
       
  1192 
       
  1193                 Y._loading = false;
       
  1194 
       
  1195                 if (data) {
       
  1196                     origMissing = missing;
       
  1197                     missing = [];
       
  1198                     r = [];
       
  1199                     process(data);
       
  1200                     redo = missing.length;
       
  1201                     if (redo) {
       
  1202                         if ([].concat(missing).sort().join() ==
       
  1203                                 origMissing.sort().join()) {
       
  1204                             redo = false;
       
  1205                         }
       
  1206                     }
       
  1207                 }
       
  1208 
       
  1209                 if (redo && data) {
       
  1210                     Y._loading = true;
       
  1211                     Y._use(missing, function() {
       
  1212                         Y.log('Nested use callback: ' + data, 'info', 'yui');
       
  1213                         if (Y._attach(data)) {
       
  1214                             Y._notify(callback, response, data);
       
  1215                         }
       
  1216                     });
       
  1217                 } else {
       
  1218                     if (data) {
       
  1219                         // Y.log('attaching from loader: ' + data, 'info', 'yui');
       
  1220                         ret = Y._attach(data);
       
  1221                     }
       
  1222                     if (ret) {
       
  1223                         Y._notify(callback, response, args);
       
  1224                     }
       
  1225                 }
       
  1226 
       
  1227                 if (Y._useQueue && Y._useQueue.size() && !Y._loading) {
       
  1228                     Y._use.apply(Y, Y._useQueue.next());
       
  1229                 }
       
  1230 
       
  1231             };
       
  1232 
       
  1233 // Y.log(Y.id + ': use called: ' + a + ' :: ' + callback, 'info', 'yui');
       
  1234 
       
  1235         // YUI().use('*'); // bind everything available
       
  1236         if (firstArg === '*') {
       
  1237             args = [];
       
  1238             for (i in mods) {
       
  1239                 if (mods.hasOwnProperty(i)) {
       
  1240                     args.push(i);
       
  1241                 }
       
  1242             }
       
  1243             ret = Y._attach(args);
       
  1244             if (ret) {
       
  1245                 handleLoader();
       
  1246             }
       
  1247             return Y;
       
  1248         }
       
  1249 
       
  1250         if ((mods.loader || mods['loader-base']) && !Y.Loader) {
       
  1251             Y.log('Loader was found in meta, but it is not attached. Attaching..', 'info', 'yui');
       
  1252             Y._attach(['loader' + ((!mods.loader) ? '-base' : '')]);
       
  1253         }
       
  1254 
       
  1255         // Y.log('before loader requirements: ' + args, 'info', 'yui');
       
  1256 
       
  1257         // use loader to expand dependencies and sort the
       
  1258         // requirements if it is available.
       
  1259         if (boot && Y.Loader && args.length) {
       
  1260             Y.log('Using loader to expand dependencies', 'info', 'yui');
       
  1261             loader = getLoader(Y);
       
  1262             loader.require(args);
       
  1263             loader.ignoreRegistered = true;
       
  1264             loader._boot = true;
       
  1265             loader.calculate(null, (fetchCSS) ? null : 'js');
       
  1266             args = loader.sorted;
       
  1267             loader._boot = false;
       
  1268         }
       
  1269 
       
  1270         process(args);
       
  1271 
       
  1272         len = missing.length;
       
  1273 
       
  1274 
       
  1275         if (len) {
       
  1276             missing = YArray.dedupe(missing);
       
  1277             len = missing.length;
       
  1278 Y.log('Modules missing: ' + missing + ', ' + missing.length, 'info', 'yui');
       
  1279         }
       
  1280 
       
  1281 
       
  1282         // dynamic load
       
  1283         if (boot && len && Y.Loader) {
       
  1284 // Y.log('Using loader to fetch missing deps: ' + missing, 'info', 'yui');
       
  1285             Y.log('Using Loader', 'info', 'yui');
       
  1286             Y._loading = true;
       
  1287             loader = getLoader(Y);
       
  1288             loader.onEnd = handleLoader;
       
  1289             loader.context = Y;
       
  1290             loader.data = args;
       
  1291             loader.ignoreRegistered = false;
       
  1292             loader.require(missing);
       
  1293             loader.insert(null, (fetchCSS) ? null : 'js');
       
  1294 
       
  1295         } else if (boot && len && Y.Get && !Env.bootstrapped) {
       
  1296 
       
  1297             Y._loading = true;
       
  1298 
       
  1299             handleBoot = function() {
       
  1300                 Y._loading = false;
       
  1301                 queue.running = false;
       
  1302                 Env.bootstrapped = true;
       
  1303                 G_ENV._bootstrapping = false;
       
  1304                 if (Y._attach(['loader'])) {
       
  1305                     Y._use(args, callback);
       
  1306                 }
       
  1307             };
       
  1308 
       
  1309             if (G_ENV._bootstrapping) {
       
  1310 Y.log('Waiting for loader', 'info', 'yui');
       
  1311                 queue.add(handleBoot);
       
  1312             } else {
       
  1313                 G_ENV._bootstrapping = true;
       
  1314 Y.log('Fetching loader: ' + config.base + config.loaderPath, 'info', 'yui');
       
  1315                 Y.Get.script(config.base + config.loaderPath, {
       
  1316                     onEnd: handleBoot
       
  1317                 });
       
  1318             }
       
  1319 
       
  1320         } else {
       
  1321             Y.log('Attaching available dependencies: ' + args, 'info', 'yui');
       
  1322             ret = Y._attach(args);
       
  1323             if (ret) {
       
  1324                 handleLoader();
       
  1325             }
       
  1326         }
       
  1327 
       
  1328         return Y;
       
  1329     },
       
  1330 
       
  1331 
       
  1332     /**
       
  1333     Utility method for safely creating namespaces if they don't already exist.
       
  1334     May be called statically on the YUI global object or as a method on a YUI
       
  1335     instance.
       
  1336 
       
  1337     When called statically, a namespace will be created on the YUI global
       
  1338     object:
       
  1339 
       
  1340         // Create `YUI.your.namespace.here` as nested objects, preserving any
       
  1341         // objects that already exist instead of overwriting them.
       
  1342         YUI.namespace('your.namespace.here');
       
  1343 
       
  1344     When called as a method on a YUI instance, a namespace will be created on
       
  1345     that instance:
       
  1346 
       
  1347         // Creates `Y.property.package`.
       
  1348         Y.namespace('property.package');
       
  1349 
       
  1350     Dots in the input string cause `namespace` to create nested objects for each
       
  1351     token. If any part of the requested namespace already exists, the current
       
  1352     object will be left in place and will not be overwritten. This allows
       
  1353     multiple calls to `namespace` to preserve existing namespaced properties.
       
  1354 
       
  1355     If the first token in the namespace string is "YAHOO", that token is
       
  1356     discarded. This is legacy behavior for backwards compatibility with YUI 2.
       
  1357 
       
  1358     Be careful with namespace tokens. Reserved words may work in some browsers
       
  1359     and not others. For instance, the following will fail in some browsers
       
  1360     because the supported version of JavaScript reserves the word "long":
       
  1361 
       
  1362         Y.namespace('really.long.nested.namespace');
       
  1363 
       
  1364     Note: If you pass multiple arguments to create multiple namespaces, only the
       
  1365     last one created is returned from this function.
       
  1366 
       
  1367     @method namespace
       
  1368     @param {String} namespace* One or more namespaces to create.
       
  1369     @return {Object} Reference to the last namespace object created.
       
  1370     **/
       
  1371     namespace: function() {
       
  1372         var a = arguments, o, i = 0, j, d, arg;
       
  1373 
       
  1374         for (; i < a.length; i++) {
       
  1375             o = this; //Reset base object per argument or it will get reused from the last
       
  1376             arg = a[i];
       
  1377             if (arg.indexOf(PERIOD) > -1) { //Skip this if no "." is present
       
  1378                 d = arg.split(PERIOD);
       
  1379                 for (j = (d[0] == 'YAHOO') ? 1 : 0; j < d.length; j++) {
       
  1380                     o[d[j]] = o[d[j]] || {};
       
  1381                     o = o[d[j]];
       
  1382                 }
       
  1383             } else {
       
  1384                 o[arg] = o[arg] || {};
       
  1385                 o = o[arg]; //Reset base object to the new object so it's returned
       
  1386             }
       
  1387         }
       
  1388         return o;
       
  1389     },
       
  1390 
       
  1391     // this is replaced if the log module is included
       
  1392     log: NOOP,
       
  1393     message: NOOP,
       
  1394     // this is replaced if the dump module is included
       
  1395     dump: function (o) { return ''+o; },
       
  1396 
       
  1397     /**
       
  1398     Reports an error.
       
  1399 
       
  1400     The reporting mechanism is controlled by the `throwFail` configuration
       
  1401     attribute. If `throwFail` is falsy, the message is logged. If `throwFail` is
       
  1402     truthy, a JS exception is thrown.
       
  1403 
       
  1404     If an `errorFn` is specified in the config it must return `true` to indicate
       
  1405     that the exception was handled and keep it from being thrown.
       
  1406 
       
  1407     @method error
       
  1408     @param {String} msg Error message.
       
  1409     @param {Error|String} [e] JavaScript error object or an error string.
       
  1410     @param {String} [src] Source of the error (such as the name of the module in
       
  1411         which the error occurred).
       
  1412     @chainable
       
  1413     **/
       
  1414     error: function(msg, e, src) {
       
  1415         //TODO Add check for window.onerror here
       
  1416 
       
  1417         var Y = this, ret;
       
  1418 
       
  1419         if (Y.config.errorFn) {
       
  1420             ret = Y.config.errorFn.apply(Y, arguments);
       
  1421         }
       
  1422 
       
  1423         if (!ret) {
       
  1424             throw (e || new Error(msg));
       
  1425         } else {
       
  1426             Y.message(msg, 'error', ''+src); // don't scrub this one
       
  1427         }
       
  1428 
       
  1429         return Y;
       
  1430     },
       
  1431 
       
  1432     /**
       
  1433     Generates an id string that is unique among all YUI instances in this
       
  1434     execution context.
       
  1435 
       
  1436     @method guid
       
  1437     @param {String} [pre] Prefix.
       
  1438     @return {String} Unique id.
       
  1439     **/
       
  1440     guid: function(pre) {
       
  1441         var id = this.Env._guidp + '_' + (++this.Env._uidx);
       
  1442         return (pre) ? (pre + id) : id;
       
  1443     },
       
  1444 
       
  1445     /**
       
  1446     Returns a unique id associated with the given object and (if *readOnly* is
       
  1447     falsy) stamps the object with that id so it can be identified in the future.
       
  1448 
       
  1449     Stamping an object involves adding a `_yuid` property to it that contains
       
  1450     the object's id. One exception to this is that in Internet Explorer, DOM
       
  1451     nodes have a `uniqueID` property that contains a browser-generated unique
       
  1452     id, which will be used instead of a YUI-generated id when available.
       
  1453 
       
  1454     @method stamp
       
  1455     @param {Object} o Object to stamp.
       
  1456     @param {Boolean} readOnly If truthy and the given object has not already
       
  1457         been stamped, the object will not be modified and `null` will be
       
  1458         returned.
       
  1459     @return {String} Object's unique id, or `null` if *readOnly* was truthy and
       
  1460         the given object was not already stamped.
       
  1461     **/
       
  1462     stamp: function(o, readOnly) {
       
  1463         var uid;
       
  1464         if (!o) {
       
  1465             return o;
       
  1466         }
       
  1467 
       
  1468         // IE generates its own unique ID for dom nodes
       
  1469         // The uniqueID property of a document node returns a new ID
       
  1470         if (o.uniqueID && o.nodeType && o.nodeType !== 9) {
       
  1471             uid = o.uniqueID;
       
  1472         } else {
       
  1473             uid = (typeof o === 'string') ? o : o._yuid;
       
  1474         }
       
  1475 
       
  1476         if (!uid) {
       
  1477             uid = this.guid();
       
  1478             if (!readOnly) {
       
  1479                 try {
       
  1480                     o._yuid = uid;
       
  1481                 } catch (e) {
       
  1482                     uid = null;
       
  1483                 }
       
  1484             }
       
  1485         }
       
  1486         return uid;
       
  1487     },
       
  1488 
       
  1489     /**
       
  1490     Destroys this YUI instance.
       
  1491 
       
  1492     @method destroy
       
  1493     @since 3.3.0
       
  1494     **/
       
  1495     destroy: function() {
       
  1496         var Y = this;
       
  1497         if (Y.Event) {
       
  1498             Y.Event._unload();
       
  1499         }
       
  1500         delete instances[Y.id];
       
  1501         delete Y.Env;
       
  1502         delete Y.config;
       
  1503     }
       
  1504 
       
  1505     /**
       
  1506     Safe `instanceof` wrapper that works around a memory leak in IE when the
       
  1507     object being tested is `window` or `document`.
       
  1508 
       
  1509     Unless you are testing objects that may be `window` or `document`, you
       
  1510     should use the native `instanceof` operator instead of this method.
       
  1511 
       
  1512     @method instanceOf
       
  1513     @param {Object} o Object to check.
       
  1514     @param {Object} type Class to check against.
       
  1515     @since 3.3.0
       
  1516     **/
       
  1517 };
       
  1518 
       
  1519     YUI.prototype = proto;
       
  1520 
       
  1521     // inheritance utilities are not available yet
       
  1522     for (prop in proto) {
       
  1523         if (proto.hasOwnProperty(prop)) {
       
  1524             YUI[prop] = proto[prop];
       
  1525         }
       
  1526     }
       
  1527 
       
  1528     /**
       
  1529     Applies a configuration to all YUI instances in this execution context.
       
  1530 
       
  1531     The main use case for this method is in "mashups" where several third-party
       
  1532     scripts need to write to a global YUI config, but cannot share a single
       
  1533     centrally-managed config object. This way they can all call
       
  1534     `YUI.applyConfig({})` instead of overwriting the single global config.
       
  1535 
       
  1536     @example
       
  1537 
       
  1538         YUI.applyConfig({
       
  1539             modules: {
       
  1540                 davglass: {
       
  1541                     fullpath: './davglass.js'
       
  1542                 }
       
  1543             }
       
  1544         });
       
  1545 
       
  1546         YUI.applyConfig({
       
  1547             modules: {
       
  1548                 foo: {
       
  1549                     fullpath: './foo.js'
       
  1550                 }
       
  1551             }
       
  1552         });
       
  1553 
       
  1554         YUI().use('davglass', function (Y) {
       
  1555             // Module davglass will be available here.
       
  1556         });
       
  1557 
       
  1558     @method applyConfig
       
  1559     @param {Object} o Configuration object to apply.
       
  1560     @static
       
  1561     @since 3.5.0
       
  1562     **/
       
  1563     YUI.applyConfig = function(o) {
       
  1564         if (!o) {
       
  1565             return;
       
  1566         }
       
  1567         //If there is a GlobalConfig, apply it first to set the defaults
       
  1568         if (YUI.GlobalConfig) {
       
  1569             this.prototype.applyConfig.call(this, YUI.GlobalConfig);
       
  1570         }
       
  1571         //Apply this config to it
       
  1572         this.prototype.applyConfig.call(this, o);
       
  1573         //Reset GlobalConfig to the combined config
       
  1574         YUI.GlobalConfig = this.config;
       
  1575     };
       
  1576 
       
  1577     // set up the environment
       
  1578     YUI._init();
       
  1579 
       
  1580     if (hasWin) {
       
  1581         add(doc, 'DOMContentLoaded', handleReady);
       
  1582 
       
  1583         // add a window load event at load time so we can capture
       
  1584         // the case where it fires before dynamic loading is
       
  1585         // complete.
       
  1586         add(window, 'load', handleLoad);
       
  1587     } else {
       
  1588         handleReady();
       
  1589         handleLoad();
       
  1590     }
       
  1591 
       
  1592     YUI.Env.add = add;
       
  1593     YUI.Env.remove = remove;
       
  1594 
       
  1595     /*global exports*/
       
  1596     // Support the CommonJS method for exporting our single global
       
  1597     if (typeof exports == 'object') {
       
  1598         exports.YUI = YUI;
       
  1599         /**
       
  1600         * Set a method to be called when `Get.script` is called in Node.js
       
  1601         * `Get` will open the file, then pass it's content and it's path
       
  1602         * to this method before attaching it. Commonly used for code coverage
       
  1603         * instrumentation. <strong>Calling this multiple times will only
       
  1604         * attach the last hook method</strong>. This method is only
       
  1605         * available in Node.js.
       
  1606         * @method setLoadHook
       
  1607         * @static
       
  1608         * @param {Function} fn The function to set
       
  1609         * @param {String} fn.data The content of the file
       
  1610         * @param {String} fn.path The file path of the file
       
  1611         */
       
  1612         YUI.setLoadHook = function(fn) {
       
  1613             YUI._getLoadHook = fn;
       
  1614         };
       
  1615         /**
       
  1616         * Load hook for `Y.Get.script` in Node.js, see `YUI.setLoadHook`
       
  1617         * @method _getLoadHook
       
  1618         * @private
       
  1619         * @param {String} data The content of the file
       
  1620         * @param {String} path The file path of the file
       
  1621         */
       
  1622         YUI._getLoadHook = null;
       
  1623     }
       
  1624 
       
  1625     YUI.Env[VERSION] = {};
       
  1626 }());
       
  1627 
       
  1628 
       
  1629 /**
       
  1630 Config object that contains all of the configuration options for
       
  1631 this `YUI` instance.
       
  1632 
       
  1633 This object is supplied by the implementer when instantiating YUI. Some
       
  1634 properties have default values if they are not supplied by the implementer.
       
  1635 
       
  1636 This object should not be updated directly because some values are cached. Use
       
  1637 `applyConfig()` to update the config object on a YUI instance that has already
       
  1638 been configured.
       
  1639 
       
  1640 @class config
       
  1641 @static
       
  1642 **/
       
  1643 
       
  1644 /**
       
  1645 If `true` (the default), YUI will "bootstrap" the YUI Loader and module metadata
       
  1646 if they're needed to load additional dependencies and aren't already available.
       
  1647 
       
  1648 Setting this to `false` will prevent YUI from automatically loading the Loader
       
  1649 and module metadata, so you will need to manually ensure that they're available
       
  1650 or handle dependency resolution yourself.
       
  1651 
       
  1652 @property {Boolean} bootstrap
       
  1653 @default true
       
  1654 **/
       
  1655 
       
  1656 /**
       
  1657 If `true`, `Y.log()` messages will be written to the browser's debug console
       
  1658 when available and when `useBrowserConsole` is also `true`.
       
  1659 
       
  1660 @property {Boolean} debug
       
  1661 @default true
       
  1662 **/
       
  1663 
       
  1664 /**
       
  1665 Log messages to the browser console if `debug` is `true` and the browser has a
       
  1666 supported console.
       
  1667 
       
  1668 @property {Boolean} useBrowserConsole
       
  1669 @default true
       
  1670 **/
       
  1671 
       
  1672 /**
       
  1673 A hash of log sources that should be logged. If specified, only messages from
       
  1674 these sources will be logged. Others will be discarded.
       
  1675 
       
  1676 @property {Object} logInclude
       
  1677 @type object
       
  1678 **/
       
  1679 
       
  1680 /**
       
  1681 A hash of log sources that should be not be logged. If specified, all sources
       
  1682 will be logged *except* those on this list.
       
  1683 
       
  1684 @property {Object} logExclude
       
  1685 **/
       
  1686 
       
  1687 /**
       
  1688 When the YUI seed file is dynamically loaded after the `window.onload` event has
       
  1689 fired, set this to `true` to tell YUI that it shouldn't wait for `window.onload`
       
  1690 to occur.
       
  1691 
       
  1692 This ensures that components that rely on `window.onload` and the `domready`
       
  1693 custom event will work as expected even when YUI is dynamically injected.
       
  1694 
       
  1695 @property {Boolean} injected
       
  1696 @default false
       
  1697 **/
       
  1698 
       
  1699 /**
       
  1700 If `true`, `Y.error()` will generate or re-throw a JavaScript error. Otherwise,
       
  1701 errors are merely logged silently.
       
  1702 
       
  1703 @property {Boolean} throwFail
       
  1704 @default true
       
  1705 **/
       
  1706 
       
  1707 /**
       
  1708 Reference to the global object for this execution context.
       
  1709 
       
  1710 In a browser, this is the current `window` object. In Node.js, this is the
       
  1711 Node.js `global` object.
       
  1712 
       
  1713 @property {Object} global
       
  1714 **/
       
  1715 
       
  1716 /**
       
  1717 The browser window or frame that this YUI instance should operate in.
       
  1718 
       
  1719 When running in Node.js, this property is `undefined`, since there is no
       
  1720 `window` object. Use `global` to get a reference to the global object that will
       
  1721 work in both browsers and Node.js.
       
  1722 
       
  1723 @property {Window} win
       
  1724 **/
       
  1725 
       
  1726 /**
       
  1727 The browser `document` object associated with this YUI instance's `win` object.
       
  1728 
       
  1729 When running in Node.js, this property is `undefined`, since there is no
       
  1730 `document` object.
       
  1731 
       
  1732 @property {Document} doc
       
  1733 **/
       
  1734 
       
  1735 /**
       
  1736 A list of modules that defines the YUI core (overrides the default list).
       
  1737 
       
  1738 @property {Array} core
       
  1739 @type Array
       
  1740 @default ['get', 'features', 'intl-base', 'yui-log', 'yui-later', 'loader-base', 'loader-rollup', 'loader-yui3']
       
  1741 **/
       
  1742 
       
  1743 /**
       
  1744 A list of languages to use in order of preference.
       
  1745 
       
  1746 This list is matched against the list of available languages in modules that the
       
  1747 YUI instance uses to determine the best possible localization of language
       
  1748 sensitive modules.
       
  1749 
       
  1750 Languages are represented using BCP 47 language tags, such as "en-GB" for
       
  1751 English as used in the United Kingdom, or "zh-Hans-CN" for simplified Chinese as
       
  1752 used in China. The list may be provided as a comma-separated string or as an
       
  1753 array.
       
  1754 
       
  1755 @property {String|String[]} lang
       
  1756 **/
       
  1757 
       
  1758 /**
       
  1759 Default date format.
       
  1760 
       
  1761 @property {String} dateFormat
       
  1762 @deprecated Use configuration in `DataType.Date.format()` instead.
       
  1763 **/
       
  1764 
       
  1765 /**
       
  1766 Default locale.
       
  1767 
       
  1768 @property {String} locale
       
  1769 @deprecated Use `config.lang` instead.
       
  1770 **/
       
  1771 
       
  1772 /**
       
  1773 Default generic polling interval in milliseconds.
       
  1774 
       
  1775 @property {Number} pollInterval
       
  1776 @default 20
       
  1777 **/
       
  1778 
       
  1779 /**
       
  1780 The number of dynamic `<script>` nodes to insert by default before automatically
       
  1781 removing them when loading scripts.
       
  1782 
       
  1783 This applies only to script nodes because removing the node will not make the
       
  1784 evaluated script unavailable. Dynamic CSS nodes are not auto purged, because
       
  1785 removing a linked style sheet will also remove the style definitions.
       
  1786 
       
  1787 @property {Number} purgethreshold
       
  1788 @default 20
       
  1789 **/
       
  1790 
       
  1791 /**
       
  1792 Delay in milliseconds to wait after a window `resize` event before firing the
       
  1793 event. If another `resize` event occurs before this delay has elapsed, the
       
  1794 delay will start over to ensure that `resize` events are throttled.
       
  1795 
       
  1796 @property {Number} windowResizeDelay
       
  1797 @default 40
       
  1798 **/
       
  1799 
       
  1800 /**
       
  1801 Base directory for dynamic loading.
       
  1802 
       
  1803 @property {String} base
       
  1804 **/
       
  1805 
       
  1806 /**
       
  1807 Base URL for a dynamic combo handler. This will be used to make combo-handled
       
  1808 module requests if `combine` is set to `true.
       
  1809 
       
  1810 @property {String} comboBase
       
  1811 @default "http://yui.yahooapis.com/combo?"
       
  1812 **/
       
  1813 
       
  1814 /**
       
  1815 Root path to prepend to each module path when creating a combo-handled request.
       
  1816 
       
  1817 This is updated for each YUI release to point to a specific version of the
       
  1818 library; for example: "3.8.0/build/".
       
  1819 
       
  1820 @property {String} root
       
  1821 **/
       
  1822 
       
  1823 /**
       
  1824 Filter to apply to module urls. This filter will modify the default path for all
       
  1825 modules.
       
  1826 
       
  1827 The default path for the YUI library is the minified version of the files (e.g.,
       
  1828 event-min.js). The filter property can be a predefined filter or a custom
       
  1829 filter. The valid predefined filters are:
       
  1830 
       
  1831   - **debug**: Loads debug versions of modules (e.g., event-debug.js).
       
  1832   - **raw**: Loads raw, non-minified versions of modules without debug logging
       
  1833     (e.g., event.js).
       
  1834 
       
  1835 You can also define a custom filter, which must be an object literal containing
       
  1836 a search regular expression and a replacement string:
       
  1837 
       
  1838     myFilter: {
       
  1839         searchExp : "-min\\.js",
       
  1840         replaceStr: "-debug.js"
       
  1841     }
       
  1842 
       
  1843 @property {Object|String} filter
       
  1844 **/
       
  1845 
       
  1846 /**
       
  1847 Skin configuration and customizations.
       
  1848 
       
  1849 @property {Object} skin
       
  1850 @param {String} [skin.defaultSkin='sam'] Default skin name. This skin will be
       
  1851     applied automatically to skinnable components if not overridden by a
       
  1852     component-specific skin name.
       
  1853 @param {String} [skin.base='assets/skins/'] Default base path for a skin,
       
  1854     relative to Loader's `base` path.
       
  1855 @param {Object} [skin.overrides] Component-specific skin name overrides. Specify
       
  1856     a component name as the key and, as the value, a string or array of strings
       
  1857     for a skin or skins that should be loaded for that component instead of the
       
  1858     `defaultSkin`.
       
  1859 **/
       
  1860 
       
  1861 /**
       
  1862 Hash of per-component filter specifications. If specified for a given component,
       
  1863 this overrides the global `filter` config.
       
  1864 
       
  1865 @example
       
  1866     YUI({
       
  1867         modules: {
       
  1868             'foo': './foo.js',
       
  1869             'bar': './bar.js',
       
  1870             'baz': './baz.js'
       
  1871         },
       
  1872         filters: {
       
  1873             'foo': {
       
  1874                 searchExp: '.js',
       
  1875                 replaceStr: '-coverage.js'
       
  1876             }
       
  1877         }
       
  1878     }).use('foo', 'bar', 'baz', function (Y) {
       
  1879         // foo-coverage.js is loaded
       
  1880         // bar.js is loaded
       
  1881         // baz.js is loaded
       
  1882     });
       
  1883 
       
  1884 @property {Object} filters
       
  1885 **/
       
  1886 
       
  1887 /**
       
  1888 If `true`, YUI will use a combo handler to load multiple modules in as few
       
  1889 requests as possible.
       
  1890 
       
  1891 The YUI CDN (which YUI uses by default) supports combo handling, but other
       
  1892 servers may not. If the server from which you're loading YUI does not support
       
  1893 combo handling, set this to `false`.
       
  1894 
       
  1895 Providing a value for the `base` config property will cause `combine` to default
       
  1896 to `false` instead of `true`.
       
  1897 
       
  1898 @property {Boolean} combine
       
  1899 @default true
       
  1900 */
       
  1901 
       
  1902 /**
       
  1903 Array of module names that should never be dynamically loaded.
       
  1904 
       
  1905 @property {String[]} ignore
       
  1906 **/
       
  1907 
       
  1908 /**
       
  1909 Array of module names that should always be loaded when required, even if
       
  1910 already present on the page.
       
  1911 
       
  1912 @property {String[]} force
       
  1913 **/
       
  1914 
       
  1915 /**
       
  1916 DOM element or id that should be used as the insertion point for dynamically
       
  1917 added `<script>` and `<link>` nodes.
       
  1918 
       
  1919 @property {HTMLElement|String} insertBefore
       
  1920 **/
       
  1921 
       
  1922 /**
       
  1923 Object hash containing attributes to add to dynamically added `<script>` nodes.
       
  1924 
       
  1925 @property {Object} jsAttributes
       
  1926 **/
       
  1927 
       
  1928 /**
       
  1929 Object hash containing attributes to add to dynamically added `<link>` nodes.
       
  1930 
       
  1931 @property {Object} cssAttributes
       
  1932 **/
       
  1933 
       
  1934 /**
       
  1935 Timeout in milliseconds before a dynamic JS or CSS request will be considered a
       
  1936 failure. If not set, no timeout will be enforced.
       
  1937 
       
  1938 @property {Number} timeout
       
  1939 **/
       
  1940 
       
  1941 /**
       
  1942 Callback for the 'CSSComplete' event. When dynamically loading YUI components
       
  1943 with CSS, this property fires when the CSS is finished loading.
       
  1944 
       
  1945 This provides an opportunity to enhance the presentation of a loading page a
       
  1946 little bit before the entire loading process is done.
       
  1947 
       
  1948 @property {Function} onCSS
       
  1949 **/
       
  1950 
       
  1951 /**
       
  1952 A hash of module definitions to add to the list of available YUI modules. These
       
  1953 modules can then be dynamically loaded via the `use()` method.
       
  1954 
       
  1955 This is a hash in which keys are module names and values are objects containing
       
  1956 module metadata.
       
  1957 
       
  1958 See `Loader.addModule()` for the supported module metadata fields. Also see
       
  1959 `groups`, which provides a way to configure the base and combo spec for a set of
       
  1960 modules.
       
  1961 
       
  1962 @example
       
  1963 
       
  1964     modules: {
       
  1965         mymod1: {
       
  1966             requires: ['node'],
       
  1967             fullpath: '/mymod1/mymod1.js'
       
  1968         },
       
  1969 
       
  1970         mymod2: {
       
  1971             requires: ['mymod1'],
       
  1972             fullpath: '/mymod2/mymod2.js'
       
  1973         },
       
  1974 
       
  1975         mymod3: '/js/mymod3.js',
       
  1976         mycssmod: '/css/mycssmod.css'
       
  1977     }
       
  1978 
       
  1979 @property {Object} modules
       
  1980 **/
       
  1981 
       
  1982 /**
       
  1983 Aliases are dynamic groups of modules that can be used as shortcuts.
       
  1984 
       
  1985 @example
       
  1986 
       
  1987     YUI({
       
  1988         aliases: {
       
  1989             davglass: [ 'node', 'yql', 'dd' ],
       
  1990             mine: [ 'davglass', 'autocomplete']
       
  1991         }
       
  1992     }).use('mine', function (Y) {
       
  1993         // Node, YQL, DD & AutoComplete available here.
       
  1994     });
       
  1995 
       
  1996 @property {Object} aliases
       
  1997 **/
       
  1998 
       
  1999 /**
       
  2000 A hash of module group definitions.
       
  2001 
       
  2002 For each group you can specify a list of modules and the base path and
       
  2003 combo spec to use when dynamically loading the modules.
       
  2004 
       
  2005 @example
       
  2006 
       
  2007     groups: {
       
  2008         yui2: {
       
  2009             // specify whether or not this group has a combo service
       
  2010             combine: true,
       
  2011 
       
  2012             // The comboSeperator to use with this group's combo handler
       
  2013             comboSep: ';',
       
  2014 
       
  2015             // The maxURLLength for this server
       
  2016             maxURLLength: 500,
       
  2017 
       
  2018             // the base path for non-combo paths
       
  2019             base: 'http://yui.yahooapis.com/2.8.0r4/build/',
       
  2020 
       
  2021             // the path to the combo service
       
  2022             comboBase: 'http://yui.yahooapis.com/combo?',
       
  2023 
       
  2024             // a fragment to prepend to the path attribute when
       
  2025             // when building combo urls
       
  2026             root: '2.8.0r4/build/',
       
  2027 
       
  2028             // the module definitions
       
  2029             modules:  {
       
  2030                 yui2_yde: {
       
  2031                     path: "yahoo-dom-event/yahoo-dom-event.js"
       
  2032                 },
       
  2033                 yui2_anim: {
       
  2034                     path: "animation/animation.js",
       
  2035                     requires: ['yui2_yde']
       
  2036                 }
       
  2037             }
       
  2038         }
       
  2039     }
       
  2040 
       
  2041 @property {Object} groups
       
  2042 **/
       
  2043 
       
  2044 /**
       
  2045 Path to the Loader JS file, relative to the `base` path.
       
  2046 
       
  2047 This is used to dynamically bootstrap the Loader when it's needed and isn't yet
       
  2048 available.
       
  2049 
       
  2050 @property {String} loaderPath
       
  2051 @default "loader/loader-min.js"
       
  2052 **/
       
  2053 
       
  2054 /**
       
  2055 If `true`, YUI will attempt to load CSS dependencies and skins. Set this to
       
  2056 `false` to prevent YUI from loading any CSS, or set it to the string `"force"`
       
  2057 to force CSS dependencies to be loaded even if their associated JS modules are
       
  2058 already loaded.
       
  2059 
       
  2060 @property {Boolean|String} fetchCSS
       
  2061 @default true
       
  2062 **/
       
  2063 
       
  2064 /**
       
  2065 Default gallery version used to build gallery module urls.
       
  2066 
       
  2067 @property {String} gallery
       
  2068 @since 3.1.0
       
  2069 **/
       
  2070 
       
  2071 /**
       
  2072 Default YUI 2 version used to build YUI 2 module urls.
       
  2073 
       
  2074 This is used for intrinsic YUI 2 support via the 2in3 project. Also see the
       
  2075 `2in3` config for pulling different revisions of the wrapped YUI 2 modules.
       
  2076 
       
  2077 @property {String} yui2
       
  2078 @default "2.9.0"
       
  2079 @since 3.1.0
       
  2080 **/
       
  2081 
       
  2082 /**
       
  2083 Revision number of YUI 2in3 modules that should be used when loading YUI 2in3.
       
  2084 
       
  2085 @property {String} 2in3
       
  2086 @default "4"
       
  2087 @since 3.1.0
       
  2088 **/
       
  2089 
       
  2090 /**
       
  2091 Alternate console log function that should be used in environments without a
       
  2092 supported native console. This function is executed with the YUI instance as its
       
  2093 `this` object.
       
  2094 
       
  2095 @property {Function} logFn
       
  2096 @since 3.1.0
       
  2097 **/
       
  2098 
       
  2099 /**
       
  2100 The minimum log level to log messages for. Log levels are defined
       
  2101 incrementally. Messages greater than or equal to the level specified will
       
  2102 be shown. All others will be discarded. The order of log levels in
       
  2103 increasing priority is:
       
  2104 
       
  2105     debug
       
  2106     info
       
  2107     warn
       
  2108     error
       
  2109 
       
  2110 @property {String} logLevel
       
  2111 @default 'debug'
       
  2112 @since 3.10.0
       
  2113 **/
       
  2114 
       
  2115 /**
       
  2116 Callback to execute when `Y.error()` is called. It receives the error message
       
  2117 and a JavaScript error object if one was provided.
       
  2118 
       
  2119 This function is executed with the YUI instance as its `this` object.
       
  2120 
       
  2121 Returning `true` from this function will prevent an exception from being thrown.
       
  2122 
       
  2123 @property {Function} errorFn
       
  2124 @param {String} errorFn.msg Error message
       
  2125 @param {Object} [errorFn.err] Error object (if one was provided).
       
  2126 @since 3.2.0
       
  2127 **/
       
  2128 
       
  2129 /**
       
  2130 A callback to execute when Loader fails to load one or more resources.
       
  2131 
       
  2132 This could be because of a script load failure. It could also be because a
       
  2133 module fails to register itself when the `requireRegistration` config is `true`.
       
  2134 
       
  2135 If this function is defined, the `use()` callback will only be called when the
       
  2136 loader succeeds. Otherwise, `use()` will always executes unless there was a
       
  2137 JavaScript error when attaching a module.
       
  2138 
       
  2139 @property {Function} loadErrorFn
       
  2140 @since 3.3.0
       
  2141 **/
       
  2142 
       
  2143 /**
       
  2144 If `true`, Loader will expect all loaded scripts to be first-class YUI modules
       
  2145 that register themselves with the YUI global, and will trigger a failure if a
       
  2146 loaded script does not register a YUI module.
       
  2147 
       
  2148 @property {Boolean} requireRegistration
       
  2149 @default false
       
  2150 @since 3.3.0
       
  2151 **/
       
  2152 
       
  2153 /**
       
  2154 Cache serviced use() requests.
       
  2155 
       
  2156 @property {Boolean} cacheUse
       
  2157 @default true
       
  2158 @since 3.3.0
       
  2159 @deprecated No longer used.
       
  2160 **/
       
  2161 
       
  2162 /**
       
  2163 Whether or not YUI should use native ES5 functionality when available for
       
  2164 features like `Y.Array.each()`, `Y.Object()`, etc.
       
  2165 
       
  2166 When `false`, YUI will always use its own fallback implementations instead of
       
  2167 relying on ES5 functionality, even when ES5 functionality is available.
       
  2168 
       
  2169 @property {Boolean} useNativeES5
       
  2170 @default true
       
  2171 @since 3.5.0
       
  2172 **/
       
  2173 
       
  2174 /**
       
  2175  * Leverage native JSON stringify if the browser has a native
       
  2176  * implementation.  In general, this is a good idea.  See the Known Issues
       
  2177  * section in the JSON user guide for caveats.  The default value is true
       
  2178  * for browsers with native JSON support.
       
  2179  *
       
  2180  * @property useNativeJSONStringify
       
  2181  * @type Boolean
       
  2182  * @default true
       
  2183  * @since 3.8.0
       
  2184  */
       
  2185 
       
  2186  /**
       
  2187  * Leverage native JSON parse if the browser has a native implementation.
       
  2188  * In general, this is a good idea.  See the Known Issues section in the
       
  2189  * JSON user guide for caveats.  The default value is true for browsers with
       
  2190  * native JSON support.
       
  2191  *
       
  2192  * @property useNativeJSONParse
       
  2193  * @type Boolean
       
  2194  * @default true
       
  2195  * @since 3.8.0
       
  2196  */
       
  2197 
       
  2198 /**
       
  2199 Delay the `use` callback until a specific event has passed (`load`, `domready`, `contentready` or `available`)
       
  2200 
       
  2201 @property {Object|String} delayUntil
       
  2202 @since 3.6.0
       
  2203 @example
       
  2204 
       
  2205 You can use `load` or `domready` strings by default:
       
  2206 
       
  2207     YUI({
       
  2208         delayUntil: 'domready'
       
  2209     }, function (Y) {
       
  2210         // This will not execute until 'domeready' occurs.
       
  2211     });
       
  2212 
       
  2213 Or you can delay until a node is available (with `available` or `contentready`):
       
  2214 
       
  2215     YUI({
       
  2216         delayUntil: {
       
  2217             event: 'available',
       
  2218             args : '#foo'
       
  2219         }
       
  2220     }, function (Y) {
       
  2221         // This will not execute until a node matching the selector "#foo" is
       
  2222         // available in the DOM.
       
  2223     });
       
  2224 
       
  2225 **/
       
  2226 YUI.add('yui-base', function (Y, NAME) {
       
  2227 
       
  2228 /*
       
  2229  * YUI stub
       
  2230  * @module yui
       
  2231  * @submodule yui-base
       
  2232  */
       
  2233 /**
       
  2234  * The YUI module contains the components required for building the YUI
       
  2235  * seed file.  This includes the script loading mechanism, a simple queue,
       
  2236  * and the core utilities for the library.
       
  2237  * @module yui
       
  2238  * @submodule yui-base
       
  2239  */
       
  2240 
       
  2241 /**
       
  2242  * Provides core language utilites and extensions used throughout YUI.
       
  2243  *
       
  2244  * @class Lang
       
  2245  * @static
       
  2246  */
       
  2247 
       
  2248 var L = Y.Lang || (Y.Lang = {}),
       
  2249 
       
  2250 STRING_PROTO = String.prototype,
       
  2251 TOSTRING     = Object.prototype.toString,
       
  2252 
       
  2253 TYPES = {
       
  2254     'undefined'        : 'undefined',
       
  2255     'number'           : 'number',
       
  2256     'boolean'          : 'boolean',
       
  2257     'string'           : 'string',
       
  2258     '[object Function]': 'function',
       
  2259     '[object RegExp]'  : 'regexp',
       
  2260     '[object Array]'   : 'array',
       
  2261     '[object Date]'    : 'date',
       
  2262     '[object Error]'   : 'error'
       
  2263 },
       
  2264 
       
  2265 SUBREGEX         = /\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g,
       
  2266 
       
  2267 WHITESPACE       = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF",
       
  2268 WHITESPACE_CLASS = "[\x09-\x0D\x20\xA0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]+",
       
  2269 TRIM_LEFT_REGEX  = new RegExp("^" + WHITESPACE_CLASS),
       
  2270 TRIM_RIGHT_REGEX = new RegExp(WHITESPACE_CLASS + "$"),
       
  2271 TRIMREGEX        = new RegExp(TRIM_LEFT_REGEX.source + "|" + TRIM_RIGHT_REGEX.source, "g"),
       
  2272 
       
  2273 NATIVE_FN_REGEX  = /\{\s*\[(?:native code|function)\]\s*\}/i;
       
  2274 
       
  2275 // -- Protected Methods --------------------------------------------------------
       
  2276 
       
  2277 /**
       
  2278 Returns `true` if the given function appears to be implemented in native code,
       
  2279 `false` otherwise. Will always return `false` -- even in ES5-capable browsers --
       
  2280 if the `useNativeES5` YUI config option is set to `false`.
       
  2281 
       
  2282 This isn't guaranteed to be 100% accurate and won't work for anything other than
       
  2283 functions, but it can be useful for determining whether a function like
       
  2284 `Array.prototype.forEach` is native or a JS shim provided by another library.
       
  2285 
       
  2286 There's a great article by @kangax discussing certain flaws with this technique:
       
  2287 <http://perfectionkills.com/detecting-built-in-host-methods/>
       
  2288 
       
  2289 While his points are valid, it's still possible to benefit from this function
       
  2290 as long as it's used carefully and sparingly, and in such a way that false
       
  2291 negatives have minimal consequences. It's used internally to avoid using
       
  2292 potentially broken non-native ES5 shims that have been added to the page by
       
  2293 other libraries.
       
  2294 
       
  2295 @method _isNative
       
  2296 @param {Function} fn Function to test.
       
  2297 @return {Boolean} `true` if _fn_ appears to be native, `false` otherwise.
       
  2298 @static
       
  2299 @protected
       
  2300 @since 3.5.0
       
  2301 **/
       
  2302 L._isNative = function (fn) {
       
  2303     return !!(Y.config.useNativeES5 && fn && NATIVE_FN_REGEX.test(fn));
       
  2304 };
       
  2305 
       
  2306 // -- Public Methods -----------------------------------------------------------
       
  2307 
       
  2308 /**
       
  2309  * Determines whether or not the provided item is an array.
       
  2310  *
       
  2311  * Returns `false` for array-like collections such as the function `arguments`
       
  2312  * collection or `HTMLElement` collections. Use `Y.Array.test()` if you want to
       
  2313  * test for an array-like collection.
       
  2314  *
       
  2315  * @method isArray
       
  2316  * @param o The object to test.
       
  2317  * @return {boolean} true if o is an array.
       
  2318  * @static
       
  2319  */
       
  2320 L.isArray = L._isNative(Array.isArray) ? Array.isArray : function (o) {
       
  2321     return L.type(o) === 'array';
       
  2322 };
       
  2323 
       
  2324 /**
       
  2325  * Determines whether or not the provided item is a boolean.
       
  2326  * @method isBoolean
       
  2327  * @static
       
  2328  * @param o The object to test.
       
  2329  * @return {boolean} true if o is a boolean.
       
  2330  */
       
  2331 L.isBoolean = function(o) {
       
  2332     return typeof o === 'boolean';
       
  2333 };
       
  2334 
       
  2335 /**
       
  2336  * Determines whether or not the supplied item is a date instance.
       
  2337  * @method isDate
       
  2338  * @static
       
  2339  * @param o The object to test.
       
  2340  * @return {boolean} true if o is a date.
       
  2341  */
       
  2342 L.isDate = function(o) {
       
  2343     return L.type(o) === 'date' && o.toString() !== 'Invalid Date' && !isNaN(o);
       
  2344 };
       
  2345 
       
  2346 /**
       
  2347  * <p>
       
  2348  * Determines whether or not the provided item is a function.
       
  2349  * Note: Internet Explorer thinks certain functions are objects:
       
  2350  * </p>
       
  2351  *
       
  2352  * <pre>
       
  2353  * var obj = document.createElement("object");
       
  2354  * Y.Lang.isFunction(obj.getAttribute) // reports false in IE
       
  2355  * &nbsp;
       
  2356  * var input = document.createElement("input"); // append to body
       
  2357  * Y.Lang.isFunction(input.focus) // reports false in IE
       
  2358  * </pre>
       
  2359  *
       
  2360  * <p>
       
  2361  * You will have to implement additional tests if these functions
       
  2362  * matter to you.
       
  2363  * </p>
       
  2364  *
       
  2365  * @method isFunction
       
  2366  * @static
       
  2367  * @param o The object to test.
       
  2368  * @return {boolean} true if o is a function.
       
  2369  */
       
  2370 L.isFunction = function(o) {
       
  2371     return L.type(o) === 'function';
       
  2372 };
       
  2373 
       
  2374 /**
       
  2375  * Determines whether or not the provided item is null.
       
  2376  * @method isNull
       
  2377  * @static
       
  2378  * @param o The object to test.
       
  2379  * @return {boolean} true if o is null.
       
  2380  */
       
  2381 L.isNull = function(o) {
       
  2382     return o === null;
       
  2383 };
       
  2384 
       
  2385 /**
       
  2386  * Determines whether or not the provided item is a legal number.
       
  2387  * @method isNumber
       
  2388  * @static
       
  2389  * @param o The object to test.
       
  2390  * @return {boolean} true if o is a number.
       
  2391  */
       
  2392 L.isNumber = function(o) {
       
  2393     return typeof o === 'number' && isFinite(o);
       
  2394 };
       
  2395 
       
  2396 /**
       
  2397  * Determines whether or not the provided item is of type object
       
  2398  * or function. Note that arrays are also objects, so
       
  2399  * <code>Y.Lang.isObject([]) === true</code>.
       
  2400  * @method isObject
       
  2401  * @static
       
  2402  * @param o The object to test.
       
  2403  * @param failfn {boolean} fail if the input is a function.
       
  2404  * @return {boolean} true if o is an object.
       
  2405  * @see isPlainObject
       
  2406  */
       
  2407 L.isObject = function(o, failfn) {
       
  2408     var t = typeof o;
       
  2409     return (o && (t === 'object' ||
       
  2410         (!failfn && (t === 'function' || L.isFunction(o))))) || false;
       
  2411 };
       
  2412 
       
  2413 /**
       
  2414  * Determines whether or not the provided value is a regexp.
       
  2415  * @method isRegExp
       
  2416  * @static
       
  2417  * @param value The value or object to test.
       
  2418  * @return {boolean} true if value is a regexp.
       
  2419  */
       
  2420 L.isRegExp = function(value) {
       
  2421     return L.type(value) === 'regexp';
       
  2422 };
       
  2423 
       
  2424 /**
       
  2425  * Determines whether or not the provided item is a string.
       
  2426  * @method isString
       
  2427  * @static
       
  2428  * @param o The object to test.
       
  2429  * @return {boolean} true if o is a string.
       
  2430  */
       
  2431 L.isString = function(o) {
       
  2432     return typeof o === 'string';
       
  2433 };
       
  2434 
       
  2435 /**
       
  2436  * Determines whether or not the provided item is undefined.
       
  2437  * @method isUndefined
       
  2438  * @static
       
  2439  * @param o The object to test.
       
  2440  * @return {boolean} true if o is undefined.
       
  2441  */
       
  2442 L.isUndefined = function(o) {
       
  2443     return typeof o === 'undefined';
       
  2444 };
       
  2445 
       
  2446 /**
       
  2447  * A convenience method for detecting a legitimate non-null value.
       
  2448  * Returns false for null/undefined/NaN, true for other values,
       
  2449  * including 0/false/''
       
  2450  * @method isValue
       
  2451  * @static
       
  2452  * @param o The item to test.
       
  2453  * @return {boolean} true if it is not null/undefined/NaN || false.
       
  2454  */
       
  2455 L.isValue = function(o) {
       
  2456     var t = L.type(o);
       
  2457 
       
  2458     switch (t) {
       
  2459         case 'number':
       
  2460             return isFinite(o);
       
  2461 
       
  2462         case 'null': // fallthru
       
  2463         case 'undefined':
       
  2464             return false;
       
  2465 
       
  2466         default:
       
  2467             return !!t;
       
  2468     }
       
  2469 };
       
  2470 
       
  2471 /**
       
  2472  * Returns the current time in milliseconds.
       
  2473  *
       
  2474  * @method now
       
  2475  * @return {Number} Current time in milliseconds.
       
  2476  * @static
       
  2477  * @since 3.3.0
       
  2478  */
       
  2479 L.now = Date.now || function () {
       
  2480     return new Date().getTime();
       
  2481 };
       
  2482 
       
  2483 /**
       
  2484  * Performs `{placeholder}` substitution on a string. The object passed as the 
       
  2485  * second parameter provides values to replace the `{placeholder}`s.
       
  2486  * `{placeholder}` token names must match property names of the object. For example,
       
  2487  * 
       
  2488  *`var greeting = Y.Lang.sub("Hello, {who}!", { who: "World" });`
       
  2489  *
       
  2490  * `{placeholder}` tokens that are undefined on the object map will be left 
       
  2491  * in tact (leaving unsightly `{placeholder}`'s in the output string). 
       
  2492  *
       
  2493  * @method sub
       
  2494  * @param {string} s String to be modified.
       
  2495  * @param {object} o Object containing replacement values.
       
  2496  * @return {string} the substitute result.
       
  2497  * @static
       
  2498  * @since 3.2.0
       
  2499  */
       
  2500 L.sub = function(s, o) {
       
  2501     return s.replace ? s.replace(SUBREGEX, function (match, key) {
       
  2502         return L.isUndefined(o[key]) ? match : o[key];
       
  2503     }) : s;
       
  2504 };
       
  2505 
       
  2506 /**
       
  2507  * Returns a string without any leading or trailing whitespace.  If
       
  2508  * the input is not a string, the input will be returned untouched.
       
  2509  * @method trim
       
  2510  * @static
       
  2511  * @param s {string} the string to trim.
       
  2512  * @return {string} the trimmed string.
       
  2513  */
       
  2514 L.trim = L._isNative(STRING_PROTO.trim) && !WHITESPACE.trim() ? function(s) {
       
  2515     return s && s.trim ? s.trim() : s;
       
  2516 } : function (s) {
       
  2517     try {
       
  2518         return s.replace(TRIMREGEX, '');
       
  2519     } catch (e) {
       
  2520         return s;
       
  2521     }
       
  2522 };
       
  2523 
       
  2524 /**
       
  2525  * Returns a string without any leading whitespace.
       
  2526  * @method trimLeft
       
  2527  * @static
       
  2528  * @param s {string} the string to trim.
       
  2529  * @return {string} the trimmed string.
       
  2530  */
       
  2531 L.trimLeft = L._isNative(STRING_PROTO.trimLeft) && !WHITESPACE.trimLeft() ? function (s) {
       
  2532     return s.trimLeft();
       
  2533 } : function (s) {
       
  2534     return s.replace(TRIM_LEFT_REGEX, '');
       
  2535 };
       
  2536 
       
  2537 /**
       
  2538  * Returns a string without any trailing whitespace.
       
  2539  * @method trimRight
       
  2540  * @static
       
  2541  * @param s {string} the string to trim.
       
  2542  * @return {string} the trimmed string.
       
  2543  */
       
  2544 L.trimRight = L._isNative(STRING_PROTO.trimRight) && !WHITESPACE.trimRight() ? function (s) {
       
  2545     return s.trimRight();
       
  2546 } : function (s) {
       
  2547     return s.replace(TRIM_RIGHT_REGEX, '');
       
  2548 };
       
  2549 
       
  2550 /**
       
  2551 Returns one of the following strings, representing the type of the item passed
       
  2552 in:
       
  2553 
       
  2554  * "array"
       
  2555  * "boolean"
       
  2556  * "date"
       
  2557  * "error"
       
  2558  * "function"
       
  2559  * "null"
       
  2560  * "number"
       
  2561  * "object"
       
  2562  * "regexp"
       
  2563  * "string"
       
  2564  * "undefined"
       
  2565 
       
  2566 Known issues:
       
  2567 
       
  2568  * `typeof HTMLElementCollection` returns function in Safari, but
       
  2569     `Y.Lang.type()` reports "object", which could be a good thing --
       
  2570     but it actually caused the logic in <code>Y.Lang.isObject</code> to fail.
       
  2571 
       
  2572 @method type
       
  2573 @param o the item to test.
       
  2574 @return {string} the detected type.
       
  2575 @static
       
  2576 **/
       
  2577 L.type = function(o) {
       
  2578     return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null');
       
  2579 };
       
  2580 /**
       
  2581 @module yui
       
  2582 @submodule yui-base
       
  2583 */
       
  2584 
       
  2585 var Lang   = Y.Lang,
       
  2586     Native = Array.prototype,
       
  2587 
       
  2588     hasOwn = Object.prototype.hasOwnProperty;
       
  2589 
       
  2590 /**
       
  2591 Provides utility methods for working with arrays. Additional array helpers can
       
  2592 be found in the `collection` and `array-extras` modules.
       
  2593 
       
  2594 `Y.Array(thing)` returns a native array created from _thing_. Depending on
       
  2595 _thing_'s type, one of the following will happen:
       
  2596 
       
  2597   * Arrays are returned unmodified unless a non-zero _startIndex_ is
       
  2598     specified.
       
  2599   * Array-like collections (see `Array.test()`) are converted to arrays.
       
  2600   * For everything else, a new array is created with _thing_ as the sole
       
  2601     item.
       
  2602 
       
  2603 Note: elements that are also collections, such as `<form>` and `<select>`
       
  2604 elements, are not automatically converted to arrays. To force a conversion,
       
  2605 pass `true` as the value of the _force_ parameter.
       
  2606 
       
  2607 @class Array
       
  2608 @constructor
       
  2609 @param {Any} thing The thing to arrayify.
       
  2610 @param {Number} [startIndex=0] If non-zero and _thing_ is an array or array-like
       
  2611   collection, a subset of items starting at the specified index will be
       
  2612   returned.
       
  2613 @param {Boolean} [force=false] If `true`, _thing_ will be treated as an
       
  2614   array-like collection no matter what.
       
  2615 @return {Array} A native array created from _thing_, according to the rules
       
  2616   described above.
       
  2617 **/
       
  2618 function YArray(thing, startIndex, force) {
       
  2619     var len, result;
       
  2620 
       
  2621     /*jshint expr: true*/
       
  2622     startIndex || (startIndex = 0);
       
  2623 
       
  2624     if (force || YArray.test(thing)) {
       
  2625         // IE throws when trying to slice HTMLElement collections.
       
  2626         try {
       
  2627             return Native.slice.call(thing, startIndex);
       
  2628         } catch (ex) {
       
  2629             result = [];
       
  2630 
       
  2631             for (len = thing.length; startIndex < len; ++startIndex) {
       
  2632                 result.push(thing[startIndex]);
       
  2633             }
       
  2634 
       
  2635             return result;
       
  2636         }
       
  2637     }
       
  2638 
       
  2639     return [thing];
       
  2640 }
       
  2641 
       
  2642 Y.Array = YArray;
       
  2643 
       
  2644 /**
       
  2645 Dedupes an array of strings, returning an array that's guaranteed to contain
       
  2646 only one copy of a given string.
       
  2647 
       
  2648 This method differs from `Array.unique()` in that it's optimized for use only
       
  2649 with arrays consisting entirely of strings or entirely of numbers, whereas
       
  2650 `unique` may be used with other value types (but is slower).
       
  2651 
       
  2652 Using `dedupe()` with values other than strings or numbers, or with arrays
       
  2653 containing a mix of strings and numbers, may result in unexpected behavior.
       
  2654 
       
  2655 @method dedupe
       
  2656 @param {String[]|Number[]} array Array of strings or numbers to dedupe.
       
  2657 @return {Array} Copy of _array_ containing no duplicate values.
       
  2658 @static
       
  2659 @since 3.4.0
       
  2660 **/
       
  2661 YArray.dedupe = Lang._isNative(Object.create) ? function (array) {
       
  2662     var hash    = Object.create(null),
       
  2663         results = [],
       
  2664         i, item, len;
       
  2665 
       
  2666     for (i = 0, len = array.length; i < len; ++i) {
       
  2667         item = array[i];
       
  2668 
       
  2669         if (!hash[item]) {
       
  2670             hash[item] = 1;
       
  2671             results.push(item);
       
  2672         }
       
  2673     }
       
  2674 
       
  2675     return results;
       
  2676 } : function (array) {
       
  2677     var hash    = {},
       
  2678         results = [],
       
  2679         i, item, len;
       
  2680 
       
  2681     for (i = 0, len = array.length; i < len; ++i) {
       
  2682         item = array[i];
       
  2683 
       
  2684         if (!hasOwn.call(hash, item)) {
       
  2685             hash[item] = 1;
       
  2686             results.push(item);
       
  2687         }
       
  2688     }
       
  2689 
       
  2690     return results;
       
  2691 };
       
  2692 
       
  2693 /**
       
  2694 Executes the supplied function on each item in the array. This method wraps
       
  2695 the native ES5 `Array.forEach()` method if available.
       
  2696 
       
  2697 @method each
       
  2698 @param {Array} array Array to iterate.
       
  2699 @param {Function} fn Function to execute on each item in the array. The function
       
  2700   will receive the following arguments:
       
  2701     @param {Any} fn.item Current array item.
       
  2702     @param {Number} fn.index Current array index.
       
  2703     @param {Array} fn.array Array being iterated.
       
  2704 @param {Object} [thisObj] `this` object to use when calling _fn_.
       
  2705 @return {YUI} The YUI instance.
       
  2706 @static
       
  2707 **/
       
  2708 YArray.each = YArray.forEach = Lang._isNative(Native.forEach) ? function (array, fn, thisObj) {
       
  2709     Native.forEach.call(array || [], fn, thisObj || Y);
       
  2710     return Y;
       
  2711 } : function (array, fn, thisObj) {
       
  2712     for (var i = 0, len = (array && array.length) || 0; i < len; ++i) {
       
  2713         if (i in array) {
       
  2714             fn.call(thisObj || Y, array[i], i, array);
       
  2715         }
       
  2716     }
       
  2717 
       
  2718     return Y;
       
  2719 };
       
  2720 
       
  2721 /**
       
  2722 Alias for `each()`.
       
  2723 
       
  2724 @method forEach
       
  2725 @static
       
  2726 **/
       
  2727 
       
  2728 /**
       
  2729 Returns an object using the first array as keys and the second as values. If
       
  2730 the second array is not provided, or if it doesn't contain the same number of
       
  2731 values as the first array, then `true` will be used in place of the missing
       
  2732 values.
       
  2733 
       
  2734 @example
       
  2735 
       
  2736     Y.Array.hash(['a', 'b', 'c'], ['foo', 'bar']);
       
  2737     // => {a: 'foo', b: 'bar', c: true}
       
  2738 
       
  2739 @method hash
       
  2740 @param {String[]} keys Array of strings to use as keys.
       
  2741 @param {Array} [values] Array to use as values.
       
  2742 @return {Object} Hash using the first array as keys and the second as values.
       
  2743 @static
       
  2744 **/
       
  2745 YArray.hash = function (keys, values) {
       
  2746     var hash = {},
       
  2747         vlen = (values && values.length) || 0,
       
  2748         i, len;
       
  2749 
       
  2750     for (i = 0, len = keys.length; i < len; ++i) {
       
  2751         if (i in keys) {
       
  2752             hash[keys[i]] = vlen > i && i in values ? values[i] : true;
       
  2753         }
       
  2754     }
       
  2755 
       
  2756     return hash;
       
  2757 };
       
  2758 
       
  2759 /**
       
  2760 Returns the index of the first item in the array that's equal (using a strict
       
  2761 equality check) to the specified _value_, or `-1` if the value isn't found.
       
  2762 
       
  2763 This method wraps the native ES5 `Array.indexOf()` method if available.
       
  2764 
       
  2765 @method indexOf
       
  2766 @param {Array} array Array to search.
       
  2767 @param {Any} value Value to search for.
       
  2768 @param {Number} [from=0] The index at which to begin the search.
       
  2769 @return {Number} Index of the item strictly equal to _value_, or `-1` if not
       
  2770     found.
       
  2771 @static
       
  2772 **/
       
  2773 YArray.indexOf = Lang._isNative(Native.indexOf) ? function (array, value, from) {
       
  2774     return Native.indexOf.call(array, value, from);
       
  2775 } : function (array, value, from) {
       
  2776     // http://es5.github.com/#x15.4.4.14
       
  2777     var len = array.length;
       
  2778 
       
  2779     from = +from || 0;
       
  2780     from = (from > 0 || -1) * Math.floor(Math.abs(from));
       
  2781 
       
  2782     if (from < 0) {
       
  2783         from += len;
       
  2784 
       
  2785         if (from < 0) {
       
  2786             from = 0;
       
  2787         }
       
  2788     }
       
  2789 
       
  2790     for (; from < len; ++from) {
       
  2791         if (from in array && array[from] === value) {
       
  2792             return from;
       
  2793         }
       
  2794     }
       
  2795 
       
  2796     return -1;
       
  2797 };
       
  2798 
       
  2799 /**
       
  2800 Numeric sort convenience function.
       
  2801 
       
  2802 The native `Array.prototype.sort()` function converts values to strings and
       
  2803 sorts them in lexicographic order, which is unsuitable for sorting numeric
       
  2804 values. Provide `Array.numericSort` as a custom sort function when you want
       
  2805 to sort values in numeric order.
       
  2806 
       
  2807 @example
       
  2808 
       
  2809     [42, 23, 8, 16, 4, 15].sort(Y.Array.numericSort);
       
  2810     // => [4, 8, 15, 16, 23, 42]
       
  2811 
       
  2812 @method numericSort
       
  2813 @param {Number} a First value to compare.
       
  2814 @param {Number} b Second value to compare.
       
  2815 @return {Number} Difference between _a_ and _b_.
       
  2816 @static
       
  2817 **/
       
  2818 YArray.numericSort = function (a, b) {
       
  2819     return a - b;
       
  2820 };
       
  2821 
       
  2822 /**
       
  2823 Executes the supplied function on each item in the array. Returning a truthy
       
  2824 value from the function will stop the processing of remaining items.
       
  2825 
       
  2826 @method some
       
  2827 @param {Array} array Array to iterate over.
       
  2828 @param {Function} fn Function to execute on each item. The function will receive
       
  2829   the following arguments:
       
  2830     @param {Any} fn.value Current array item.
       
  2831     @param {Number} fn.index Current array index.
       
  2832     @param {Array} fn.array Array being iterated over.
       
  2833 @param {Object} [thisObj] `this` object to use when calling _fn_.
       
  2834 @return {Boolean} `true` if the function returns a truthy value on any of the
       
  2835   items in the array; `false` otherwise.
       
  2836 @static
       
  2837 **/
       
  2838 YArray.some = Lang._isNative(Native.some) ? function (array, fn, thisObj) {
       
  2839     return Native.some.call(array, fn, thisObj);
       
  2840 } : function (array, fn, thisObj) {
       
  2841     for (var i = 0, len = array.length; i < len; ++i) {
       
  2842         if (i in array && fn.call(thisObj, array[i], i, array)) {
       
  2843             return true;
       
  2844         }
       
  2845     }
       
  2846 
       
  2847     return false;
       
  2848 };
       
  2849 
       
  2850 /**
       
  2851 Evaluates _obj_ to determine if it's an array, an array-like collection, or
       
  2852 something else. This is useful when working with the function `arguments`
       
  2853 collection and `HTMLElement` collections.
       
  2854 
       
  2855 Note: This implementation doesn't consider elements that are also
       
  2856 collections, such as `<form>` and `<select>`, to be array-like.
       
  2857 
       
  2858 @method test
       
  2859 @param {Object} obj Object to test.
       
  2860 @return {Number} A number indicating the results of the test:
       
  2861 
       
  2862   * 0: Neither an array nor an array-like collection.
       
  2863   * 1: Real array.
       
  2864   * 2: Array-like collection.
       
  2865 
       
  2866 @static
       
  2867 **/
       
  2868 YArray.test = function (obj) {
       
  2869     var result = 0;
       
  2870 
       
  2871     if (Lang.isArray(obj)) {
       
  2872         result = 1;
       
  2873     } else if (Lang.isObject(obj)) {
       
  2874         try {
       
  2875             // indexed, but no tagName (element) or scrollTo/document (window. From DOM.isWindow test which we can't use here),
       
  2876             // or functions without apply/call (Safari
       
  2877             // HTMLElementCollection bug).
       
  2878             if ('length' in obj && !obj.tagName && !(obj.scrollTo && obj.document) && !obj.apply) {
       
  2879                 result = 2;
       
  2880             }
       
  2881         } catch (ex) {}
       
  2882     }
       
  2883 
       
  2884     return result;
       
  2885 };
       
  2886 /**
       
  2887  * The YUI module contains the components required for building the YUI
       
  2888  * seed file.  This includes the script loading mechanism, a simple queue,
       
  2889  * and the core utilities for the library.
       
  2890  * @module yui
       
  2891  * @submodule yui-base
       
  2892  */
       
  2893 
       
  2894 /**
       
  2895  * A simple FIFO queue.  Items are added to the Queue with add(1..n items) and
       
  2896  * removed using next().
       
  2897  *
       
  2898  * @class Queue
       
  2899  * @constructor
       
  2900  * @param {MIXED} item* 0..n items to seed the queue.
       
  2901  */
       
  2902 function Queue() {
       
  2903     this._init();
       
  2904     this.add.apply(this, arguments);
       
  2905 }
       
  2906 
       
  2907 Queue.prototype = {
       
  2908     /**
       
  2909      * Initialize the queue
       
  2910      *
       
  2911      * @method _init
       
  2912      * @protected
       
  2913      */
       
  2914     _init: function() {
       
  2915         /**
       
  2916          * The collection of enqueued items
       
  2917          *
       
  2918          * @property _q
       
  2919          * @type Array
       
  2920          * @protected
       
  2921          */
       
  2922         this._q = [];
       
  2923     },
       
  2924 
       
  2925     /**
       
  2926      * Get the next item in the queue. FIFO support
       
  2927      *
       
  2928      * @method next
       
  2929      * @return {MIXED} the next item in the queue.
       
  2930      */
       
  2931     next: function() {
       
  2932         return this._q.shift();
       
  2933     },
       
  2934 
       
  2935     /**
       
  2936      * Get the last in the queue. LIFO support.
       
  2937      *
       
  2938      * @method last
       
  2939      * @return {MIXED} the last item in the queue.
       
  2940      */
       
  2941     last: function() {
       
  2942         return this._q.pop();
       
  2943     },
       
  2944 
       
  2945     /**
       
  2946      * Add 0..n items to the end of the queue.
       
  2947      *
       
  2948      * @method add
       
  2949      * @param {MIXED} item* 0..n items.
       
  2950      * @return {object} this queue.
       
  2951      */
       
  2952     add: function() {
       
  2953         this._q.push.apply(this._q, arguments);
       
  2954 
       
  2955         return this;
       
  2956     },
       
  2957 
       
  2958     /**
       
  2959      * Returns the current number of queued items.
       
  2960      *
       
  2961      * @method size
       
  2962      * @return {Number} The size.
       
  2963      */
       
  2964     size: function() {
       
  2965         return this._q.length;
       
  2966     }
       
  2967 };
       
  2968 
       
  2969 Y.Queue = Queue;
       
  2970 
       
  2971 YUI.Env._loaderQueue = YUI.Env._loaderQueue || new Queue();
       
  2972 
       
  2973 /**
       
  2974 The YUI module contains the components required for building the YUI seed file.
       
  2975 This includes the script loading mechanism, a simple queue, and the core
       
  2976 utilities for the library.
       
  2977 
       
  2978 @module yui
       
  2979 @submodule yui-base
       
  2980 **/
       
  2981 
       
  2982 var CACHED_DELIMITER = '__',
       
  2983 
       
  2984     hasOwn   = Object.prototype.hasOwnProperty,
       
  2985     isObject = Y.Lang.isObject;
       
  2986 
       
  2987 /**
       
  2988 Returns a wrapper for a function which caches the return value of that function,
       
  2989 keyed off of the combined string representation of the argument values provided
       
  2990 when the wrapper is called.
       
  2991 
       
  2992 Calling this function again with the same arguments will return the cached value
       
  2993 rather than executing the wrapped function.
       
  2994 
       
  2995 Note that since the cache is keyed off of the string representation of arguments
       
  2996 passed to the wrapper function, arguments that aren't strings and don't provide
       
  2997 a meaningful `toString()` method may result in unexpected caching behavior. For
       
  2998 example, the objects `{}` and `{foo: 'bar'}` would both be converted to the
       
  2999 string `[object Object]` when used as a cache key.
       
  3000 
       
  3001 @method cached
       
  3002 @param {Function} source The function to memoize.
       
  3003 @param {Object} [cache={}] Object in which to store cached values. You may seed
       
  3004   this object with pre-existing cached values if desired.
       
  3005 @param {any} [refetch] If supplied, this value is compared with the cached value
       
  3006   using a `==` comparison. If the values are equal, the wrapped function is
       
  3007   executed again even though a cached value exists.
       
  3008 @return {Function} Wrapped function.
       
  3009 @for YUI
       
  3010 **/
       
  3011 Y.cached = function (source, cache, refetch) {
       
  3012     /*jshint expr: true*/
       
  3013     cache || (cache = {});
       
  3014 
       
  3015     return function (arg) {
       
  3016         var key = arguments.length > 1 ?
       
  3017                 Array.prototype.join.call(arguments, CACHED_DELIMITER) :
       
  3018                 String(arg);
       
  3019 
       
  3020         /*jshint eqeqeq: false*/
       
  3021         if (!(key in cache) || (refetch && cache[key] == refetch)) {
       
  3022             cache[key] = source.apply(source, arguments);
       
  3023         }
       
  3024 
       
  3025         return cache[key];
       
  3026     };
       
  3027 };
       
  3028 
       
  3029 /**
       
  3030 Returns the `location` object from the window/frame in which this YUI instance
       
  3031 operates, or `undefined` when executing in a non-browser environment
       
  3032 (e.g. Node.js).
       
  3033 
       
  3034 It is _not_ recommended to hold references to the `window.location` object
       
  3035 outside of the scope of a function in which its properties are being accessed or
       
  3036 its methods are being called. This is because of a nasty bug/issue that exists
       
  3037 in both Safari and MobileSafari browsers:
       
  3038 [WebKit Bug 34679](https://bugs.webkit.org/show_bug.cgi?id=34679).
       
  3039 
       
  3040 @method getLocation
       
  3041 @return {location} The `location` object from the window/frame in which this YUI
       
  3042     instance operates.
       
  3043 @since 3.5.0
       
  3044 **/
       
  3045 Y.getLocation = function () {
       
  3046     // It is safer to look this up every time because yui-base is attached to a
       
  3047     // YUI instance before a user's config is applied; i.e. `Y.config.win` does
       
  3048     // not point the correct window object when this file is loaded.
       
  3049     var win = Y.config.win;
       
  3050 
       
  3051     // It is not safe to hold a reference to the `location` object outside the
       
  3052     // scope in which it is being used. The WebKit engine used in Safari and
       
  3053     // MobileSafari will "disconnect" the `location` object from the `window`
       
  3054     // when a page is restored from back/forward history cache.
       
  3055     return win && win.location;
       
  3056 };
       
  3057 
       
  3058 /**
       
  3059 Returns a new object containing all of the properties of all the supplied
       
  3060 objects. The properties from later objects will overwrite those in earlier
       
  3061 objects.
       
  3062 
       
  3063 Passing in a single object will create a shallow copy of it. For a deep copy,
       
  3064 use `clone()`.
       
  3065 
       
  3066 @method merge
       
  3067 @param {Object} objects* One or more objects to merge.
       
  3068 @return {Object} A new merged object.
       
  3069 **/
       
  3070 Y.merge = function () {
       
  3071     var i      = 0,
       
  3072         len    = arguments.length,
       
  3073         result = {},
       
  3074         key,
       
  3075         obj;
       
  3076 
       
  3077     for (; i < len; ++i) {
       
  3078         obj = arguments[i];
       
  3079 
       
  3080         for (key in obj) {
       
  3081             if (hasOwn.call(obj, key)) {
       
  3082                 result[key] = obj[key];
       
  3083             }
       
  3084         }
       
  3085     }
       
  3086 
       
  3087     return result;
       
  3088 };
       
  3089 
       
  3090 /**
       
  3091 Mixes _supplier_'s properties into _receiver_.
       
  3092 
       
  3093 Properties on _receiver_ or _receiver_'s prototype will not be overwritten or
       
  3094 shadowed unless the _overwrite_ parameter is `true`, and will not be merged
       
  3095 unless the _merge_ parameter is `true`.
       
  3096 
       
  3097 In the default mode (0), only properties the supplier owns are copied (prototype
       
  3098 properties are not copied). The following copying modes are available:
       
  3099 
       
  3100   * `0`: _Default_. Object to object.
       
  3101   * `1`: Prototype to prototype.
       
  3102   * `2`: Prototype to prototype and object to object.
       
  3103   * `3`: Prototype to object.
       
  3104   * `4`: Object to prototype.
       
  3105 
       
  3106 @method mix
       
  3107 @param {Function|Object} receiver The object or function to receive the mixed
       
  3108   properties.
       
  3109 @param {Function|Object} supplier The object or function supplying the
       
  3110   properties to be mixed.
       
  3111 @param {Boolean} [overwrite=false] If `true`, properties that already exist
       
  3112   on the receiver will be overwritten with properties from the supplier.
       
  3113 @param {String[]} [whitelist] An array of property names to copy. If
       
  3114   specified, only the whitelisted properties will be copied, and all others
       
  3115   will be ignored.
       
  3116 @param {Number} [mode=0] Mix mode to use. See above for available modes.
       
  3117 @param {Boolean} [merge=false] If `true`, objects and arrays that already
       
  3118   exist on the receiver will have the corresponding object/array from the
       
  3119   supplier merged into them, rather than being skipped or overwritten. When
       
  3120   both _overwrite_ and _merge_ are `true`, _merge_ takes precedence.
       
  3121 @return {Function|Object|YUI} The receiver, or the YUI instance if the
       
  3122   specified receiver is falsy.
       
  3123 **/
       
  3124 Y.mix = function(receiver, supplier, overwrite, whitelist, mode, merge) {
       
  3125     var alwaysOverwrite, exists, from, i, key, len, to;
       
  3126 
       
  3127     // If no supplier is given, we return the receiver. If no receiver is given,
       
  3128     // we return Y. Returning Y doesn't make much sense to me, but it's
       
  3129     // grandfathered in for backcompat reasons.
       
  3130     if (!receiver || !supplier) {
       
  3131         return receiver || Y;
       
  3132     }
       
  3133 
       
  3134     if (mode) {
       
  3135         // In mode 2 (prototype to prototype and object to object), we recurse
       
  3136         // once to do the proto to proto mix. The object to object mix will be
       
  3137         // handled later on.
       
  3138         if (mode === 2) {
       
  3139             Y.mix(receiver.prototype, supplier.prototype, overwrite,
       
  3140                     whitelist, 0, merge);
       
  3141         }
       
  3142 
       
  3143         // Depending on which mode is specified, we may be copying from or to
       
  3144         // the prototypes of the supplier and receiver.
       
  3145         from = mode === 1 || mode === 3 ? supplier.prototype : supplier;
       
  3146         to   = mode === 1 || mode === 4 ? receiver.prototype : receiver;
       
  3147 
       
  3148         // If either the supplier or receiver doesn't actually have a
       
  3149         // prototype property, then we could end up with an undefined `from`
       
  3150         // or `to`. If that happens, we abort and return the receiver.
       
  3151         if (!from || !to) {
       
  3152             return receiver;
       
  3153         }
       
  3154     } else {
       
  3155         from = supplier;
       
  3156         to   = receiver;
       
  3157     }
       
  3158 
       
  3159     // If `overwrite` is truthy and `merge` is falsy, then we can skip a
       
  3160     // property existence check on each iteration and save some time.
       
  3161     alwaysOverwrite = overwrite && !merge;
       
  3162 
       
  3163     if (whitelist) {
       
  3164         for (i = 0, len = whitelist.length; i < len; ++i) {
       
  3165             key = whitelist[i];
       
  3166 
       
  3167             // We call `Object.prototype.hasOwnProperty` instead of calling
       
  3168             // `hasOwnProperty` on the object itself, since the object's
       
  3169             // `hasOwnProperty` method may have been overridden or removed.
       
  3170             // Also, some native objects don't implement a `hasOwnProperty`
       
  3171             // method.
       
  3172             if (!hasOwn.call(from, key)) {
       
  3173                 continue;
       
  3174             }
       
  3175 
       
  3176             // The `key in to` check here is (sadly) intentional for backwards
       
  3177             // compatibility reasons. It prevents undesired shadowing of
       
  3178             // prototype members on `to`.
       
  3179             exists = alwaysOverwrite ? false : key in to;
       
  3180 
       
  3181             if (merge && exists && isObject(to[key], true)
       
  3182                     && isObject(from[key], true)) {
       
  3183                 // If we're in merge mode, and the key is present on both
       
  3184                 // objects, and the value on both objects is either an object or
       
  3185                 // an array (but not a function), then we recurse to merge the
       
  3186                 // `from` value into the `to` value instead of overwriting it.
       
  3187                 //
       
  3188                 // Note: It's intentional that the whitelist isn't passed to the
       
  3189                 // recursive call here. This is legacy behavior that lots of
       
  3190                 // code still depends on.
       
  3191                 Y.mix(to[key], from[key], overwrite, null, 0, merge);
       
  3192             } else if (overwrite || !exists) {
       
  3193                 // We're not in merge mode, so we'll only copy the `from` value
       
  3194                 // to the `to` value if we're in overwrite mode or if the
       
  3195                 // current key doesn't exist on the `to` object.
       
  3196                 to[key] = from[key];
       
  3197             }
       
  3198         }
       
  3199     } else {
       
  3200         for (key in from) {
       
  3201             // The code duplication here is for runtime performance reasons.
       
  3202             // Combining whitelist and non-whitelist operations into a single
       
  3203             // loop or breaking the shared logic out into a function both result
       
  3204             // in worse performance, and Y.mix is critical enough that the byte
       
  3205             // tradeoff is worth it.
       
  3206             if (!hasOwn.call(from, key)) {
       
  3207                 continue;
       
  3208             }
       
  3209 
       
  3210             // The `key in to` check here is (sadly) intentional for backwards
       
  3211             // compatibility reasons. It prevents undesired shadowing of
       
  3212             // prototype members on `to`.
       
  3213             exists = alwaysOverwrite ? false : key in to;
       
  3214 
       
  3215             if (merge && exists && isObject(to[key], true)
       
  3216                     && isObject(from[key], true)) {
       
  3217                 Y.mix(to[key], from[key], overwrite, null, 0, merge);
       
  3218             } else if (overwrite || !exists) {
       
  3219                 to[key] = from[key];
       
  3220             }
       
  3221         }
       
  3222 
       
  3223         // If this is an IE browser with the JScript enumeration bug, force
       
  3224         // enumeration of the buggy properties by making a recursive call with
       
  3225         // the buggy properties as the whitelist.
       
  3226         if (Y.Object._hasEnumBug) {
       
  3227             Y.mix(to, from, overwrite, Y.Object._forceEnum, mode, merge);
       
  3228         }
       
  3229     }
       
  3230 
       
  3231     return receiver;
       
  3232 };
       
  3233 /**
       
  3234  * The YUI module contains the components required for building the YUI
       
  3235  * seed file.  This includes the script loading mechanism, a simple queue,
       
  3236  * and the core utilities for the library.
       
  3237  * @module yui
       
  3238  * @submodule yui-base
       
  3239  */
       
  3240 
       
  3241 /**
       
  3242  * Adds utilities to the YUI instance for working with objects.
       
  3243  *
       
  3244  * @class Object
       
  3245  */
       
  3246 
       
  3247 var Lang   = Y.Lang,
       
  3248     hasOwn = Object.prototype.hasOwnProperty,
       
  3249 
       
  3250     UNDEFINED, // <-- Note the comma. We're still declaring vars.
       
  3251 
       
  3252 /**
       
  3253  * Returns a new object that uses _obj_ as its prototype. This method wraps the
       
  3254  * native ES5 `Object.create()` method if available, but doesn't currently
       
  3255  * pass through `Object.create()`'s second argument (properties) in order to
       
  3256  * ensure compatibility with older browsers.
       
  3257  *
       
  3258  * @method ()
       
  3259  * @param {Object} obj Prototype object.
       
  3260  * @return {Object} New object using _obj_ as its prototype.
       
  3261  * @static
       
  3262  */
       
  3263 O = Y.Object = Lang._isNative(Object.create) ? function (obj) {
       
  3264     // We currently wrap the native Object.create instead of simply aliasing it
       
  3265     // to ensure consistency with our fallback shim, which currently doesn't
       
  3266     // support Object.create()'s second argument (properties). Once we have a
       
  3267     // safe fallback for the properties arg, we can stop wrapping
       
  3268     // Object.create().
       
  3269     return Object.create(obj);
       
  3270 } : (function () {
       
  3271     // Reusable constructor function for the Object.create() shim.
       
  3272     function F() {}
       
  3273 
       
  3274     // The actual shim.
       
  3275     return function (obj) {
       
  3276         F.prototype = obj;
       
  3277         return new F();
       
  3278     };
       
  3279 }()),
       
  3280 
       
  3281 /**
       
  3282  * Property names that IE doesn't enumerate in for..in loops, even when they
       
  3283  * should be enumerable. When `_hasEnumBug` is `true`, it's necessary to
       
  3284  * manually enumerate these properties.
       
  3285  *
       
  3286  * @property _forceEnum
       
  3287  * @type String[]
       
  3288  * @protected
       
  3289  * @static
       
  3290  */
       
  3291 forceEnum = O._forceEnum = [
       
  3292     'hasOwnProperty',
       
  3293     'isPrototypeOf',
       
  3294     'propertyIsEnumerable',
       
  3295     'toString',
       
  3296     'toLocaleString',
       
  3297     'valueOf'
       
  3298 ],
       
  3299 
       
  3300 /**
       
  3301  * `true` if this browser has the JScript enumeration bug that prevents
       
  3302  * enumeration of the properties named in the `_forceEnum` array, `false`
       
  3303  * otherwise.
       
  3304  *
       
  3305  * See:
       
  3306  *   - <https://developer.mozilla.org/en/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug>
       
  3307  *   - <http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation>
       
  3308  *
       
  3309  * @property _hasEnumBug
       
  3310  * @type Boolean
       
  3311  * @protected
       
  3312  * @static
       
  3313  */
       
  3314 hasEnumBug = O._hasEnumBug = !{valueOf: 0}.propertyIsEnumerable('valueOf'),
       
  3315 
       
  3316 /**
       
  3317  * `true` if this browser incorrectly considers the `prototype` property of
       
  3318  * functions to be enumerable. Currently known to affect Opera 11.50 and Android 2.3.x.
       
  3319  *
       
  3320  * @property _hasProtoEnumBug
       
  3321  * @type Boolean
       
  3322  * @protected
       
  3323  * @static
       
  3324  */
       
  3325 hasProtoEnumBug = O._hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'),
       
  3326 
       
  3327 /**
       
  3328  * Returns `true` if _key_ exists on _obj_, `false` if _key_ doesn't exist or
       
  3329  * exists only on _obj_'s prototype. This is essentially a safer version of
       
  3330  * `obj.hasOwnProperty()`.
       
  3331  *
       
  3332  * @method owns
       
  3333  * @param {Object} obj Object to test.
       
  3334  * @param {String} key Property name to look for.
       
  3335  * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
       
  3336  * @static
       
  3337  */
       
  3338 owns = O.owns = function (obj, key) {
       
  3339     return !!obj && hasOwn.call(obj, key);
       
  3340 }; // <-- End of var declarations.
       
  3341 
       
  3342 /**
       
  3343  * Alias for `owns()`.
       
  3344  *
       
  3345  * @method hasKey
       
  3346  * @param {Object} obj Object to test.
       
  3347  * @param {String} key Property name to look for.
       
  3348  * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
       
  3349  * @static
       
  3350  */
       
  3351 O.hasKey = owns;
       
  3352 
       
  3353 /**
       
  3354  * Returns an array containing the object's enumerable keys. Does not include
       
  3355  * prototype keys or non-enumerable keys.
       
  3356  *
       
  3357  * Note that keys are returned in enumeration order (that is, in the same order
       
  3358  * that they would be enumerated by a `for-in` loop), which may not be the same
       
  3359  * as the order in which they were defined.
       
  3360  *
       
  3361  * This method is an alias for the native ES5 `Object.keys()` method if
       
  3362  * available and non-buggy. The Opera 11.50 and Android 2.3.x versions of
       
  3363  * `Object.keys()` have an inconsistency as they consider `prototype` to be
       
  3364  * enumerable, so a non-native shim is used to rectify the difference.
       
  3365  *
       
  3366  * @example
       
  3367  *
       
  3368  *     Y.Object.keys({a: 'foo', b: 'bar', c: 'baz'});
       
  3369  *     // => ['a', 'b', 'c']
       
  3370  *
       
  3371  * @method keys
       
  3372  * @param {Object} obj An object.
       
  3373  * @return {String[]} Array of keys.
       
  3374  * @static
       
  3375  */
       
  3376 O.keys = Lang._isNative(Object.keys) && !hasProtoEnumBug ? Object.keys : function (obj) {
       
  3377     if (!Lang.isObject(obj)) {
       
  3378         throw new TypeError('Object.keys called on a non-object');
       
  3379     }
       
  3380 
       
  3381     var keys = [],
       
  3382         i, key, len;
       
  3383 
       
  3384     if (hasProtoEnumBug && typeof obj === 'function') {
       
  3385         for (key in obj) {
       
  3386             if (owns(obj, key) && key !== 'prototype') {
       
  3387                 keys.push(key);
       
  3388             }
       
  3389         }
       
  3390     } else {
       
  3391         for (key in obj) {
       
  3392             if (owns(obj, key)) {
       
  3393                 keys.push(key);
       
  3394             }
       
  3395         }
       
  3396     }
       
  3397 
       
  3398     if (hasEnumBug) {
       
  3399         for (i = 0, len = forceEnum.length; i < len; ++i) {
       
  3400             key = forceEnum[i];
       
  3401 
       
  3402             if (owns(obj, key)) {
       
  3403                 keys.push(key);
       
  3404             }
       
  3405         }
       
  3406     }
       
  3407 
       
  3408     return keys;
       
  3409 };
       
  3410 
       
  3411 /**
       
  3412  * Returns an array containing the values of the object's enumerable keys.
       
  3413  *
       
  3414  * Note that values are returned in enumeration order (that is, in the same
       
  3415  * order that they would be enumerated by a `for-in` loop), which may not be the
       
  3416  * same as the order in which they were defined.
       
  3417  *
       
  3418  * @example
       
  3419  *
       
  3420  *     Y.Object.values({a: 'foo', b: 'bar', c: 'baz'});
       
  3421  *     // => ['foo', 'bar', 'baz']
       
  3422  *
       
  3423  * @method values
       
  3424  * @param {Object} obj An object.
       
  3425  * @return {Array} Array of values.
       
  3426  * @static
       
  3427  */
       
  3428 O.values = function (obj) {
       
  3429     var keys   = O.keys(obj),
       
  3430         i      = 0,
       
  3431         len    = keys.length,
       
  3432         values = [];
       
  3433 
       
  3434     for (; i < len; ++i) {
       
  3435         values.push(obj[keys[i]]);
       
  3436     }
       
  3437 
       
  3438     return values;
       
  3439 };
       
  3440 
       
  3441 /**
       
  3442  * Returns the number of enumerable keys owned by an object.
       
  3443  *
       
  3444  * @method size
       
  3445  * @param {Object} obj An object.
       
  3446  * @return {Number} The object's size.
       
  3447  * @static
       
  3448  */
       
  3449 O.size = function (obj) {
       
  3450     try {
       
  3451         return O.keys(obj).length;
       
  3452     } catch (ex) {
       
  3453         return 0; // Legacy behavior for non-objects.
       
  3454     }
       
  3455 };
       
  3456 
       
  3457 /**
       
  3458  * Returns `true` if the object owns an enumerable property with the specified
       
  3459  * value.
       
  3460  *
       
  3461  * @method hasValue
       
  3462  * @param {Object} obj An object.
       
  3463  * @param {any} value The value to search for.
       
  3464  * @return {Boolean} `true` if _obj_ contains _value_, `false` otherwise.
       
  3465  * @static
       
  3466  */
       
  3467 O.hasValue = function (obj, value) {
       
  3468     return Y.Array.indexOf(O.values(obj), value) > -1;
       
  3469 };
       
  3470 
       
  3471 /**
       
  3472  * Executes a function on each enumerable property in _obj_. The function
       
  3473  * receives the value, the key, and the object itself as parameters (in that
       
  3474  * order).
       
  3475  *
       
  3476  * By default, only properties owned by _obj_ are enumerated. To include
       
  3477  * prototype properties, set the _proto_ parameter to `true`.
       
  3478  *
       
  3479  * @method each
       
  3480  * @param {Object} obj Object to enumerate.
       
  3481  * @param {Function} fn Function to execute on each enumerable property.
       
  3482  *   @param {mixed} fn.value Value of the current property.
       
  3483  *   @param {String} fn.key Key of the current property.
       
  3484  *   @param {Object} fn.obj Object being enumerated.
       
  3485  * @param {Object} [thisObj] `this` object to use when calling _fn_.
       
  3486  * @param {Boolean} [proto=false] Include prototype properties.
       
  3487  * @return {YUI} the YUI instance.
       
  3488  * @chainable
       
  3489  * @static
       
  3490  */
       
  3491 O.each = function (obj, fn, thisObj, proto) {
       
  3492     var key;
       
  3493 
       
  3494     for (key in obj) {
       
  3495         if (proto || owns(obj, key)) {
       
  3496             fn.call(thisObj || Y, obj[key], key, obj);
       
  3497         }
       
  3498     }
       
  3499 
       
  3500     return Y;
       
  3501 };
       
  3502 
       
  3503 /**
       
  3504  * Executes a function on each enumerable property in _obj_, but halts if the
       
  3505  * function returns a truthy value. The function receives the value, the key,
       
  3506  * and the object itself as paramters (in that order).
       
  3507  *
       
  3508  * By default, only properties owned by _obj_ are enumerated. To include
       
  3509  * prototype properties, set the _proto_ parameter to `true`.
       
  3510  *
       
  3511  * @method some
       
  3512  * @param {Object} obj Object to enumerate.
       
  3513  * @param {Function} fn Function to execute on each enumerable property.
       
  3514  *   @param {mixed} fn.value Value of the current property.
       
  3515  *   @param {String} fn.key Key of the current property.
       
  3516  *   @param {Object} fn.obj Object being enumerated.
       
  3517  * @param {Object} [thisObj] `this` object to use when calling _fn_.
       
  3518  * @param {Boolean} [proto=false] Include prototype properties.
       
  3519  * @return {Boolean} `true` if any execution of _fn_ returns a truthy value,
       
  3520  *   `false` otherwise.
       
  3521  * @static
       
  3522  */
       
  3523 O.some = function (obj, fn, thisObj, proto) {
       
  3524     var key;
       
  3525 
       
  3526     for (key in obj) {
       
  3527         if (proto || owns(obj, key)) {
       
  3528             if (fn.call(thisObj || Y, obj[key], key, obj)) {
       
  3529                 return true;
       
  3530             }
       
  3531         }
       
  3532     }
       
  3533 
       
  3534     return false;
       
  3535 };
       
  3536 
       
  3537 /**
       
  3538  * Retrieves the sub value at the provided path,
       
  3539  * from the value object provided.
       
  3540  *
       
  3541  * @method getValue
       
  3542  * @static
       
  3543  * @param o The object from which to extract the property value.
       
  3544  * @param path {Array} A path array, specifying the object traversal path
       
  3545  * from which to obtain the sub value.
       
  3546  * @return {Any} The value stored in the path, undefined if not found,
       
  3547  * undefined if the source is not an object.  Returns the source object
       
  3548  * if an empty path is provided.
       
  3549  */
       
  3550 O.getValue = function(o, path) {
       
  3551     if (!Lang.isObject(o)) {
       
  3552         return UNDEFINED;
       
  3553     }
       
  3554 
       
  3555     var i,
       
  3556         p = Y.Array(path),
       
  3557         l = p.length;
       
  3558 
       
  3559     for (i = 0; o !== UNDEFINED && i < l; i++) {
       
  3560         o = o[p[i]];
       
  3561     }
       
  3562 
       
  3563     return o;
       
  3564 };
       
  3565 
       
  3566 /**
       
  3567  * Sets the sub-attribute value at the provided path on the
       
  3568  * value object.  Returns the modified value object, or
       
  3569  * undefined if the path is invalid.
       
  3570  *
       
  3571  * @method setValue
       
  3572  * @static
       
  3573  * @param o             The object on which to set the sub value.
       
  3574  * @param path {Array}  A path array, specifying the object traversal path
       
  3575  *                      at which to set the sub value.
       
  3576  * @param val {Any}     The new value for the sub-attribute.
       
  3577  * @return {Object}     The modified object, with the new sub value set, or
       
  3578  *                      undefined, if the path was invalid.
       
  3579  */
       
  3580 O.setValue = function(o, path, val) {
       
  3581     var i,
       
  3582         p = Y.Array(path),
       
  3583         leafIdx = p.length - 1,
       
  3584         ref = o;
       
  3585 
       
  3586     if (leafIdx >= 0) {
       
  3587         for (i = 0; ref !== UNDEFINED && i < leafIdx; i++) {
       
  3588             ref = ref[p[i]];
       
  3589         }
       
  3590 
       
  3591         if (ref !== UNDEFINED) {
       
  3592             ref[p[i]] = val;
       
  3593         } else {
       
  3594             return UNDEFINED;
       
  3595         }
       
  3596     }
       
  3597 
       
  3598     return o;
       
  3599 };
       
  3600 
       
  3601 /**
       
  3602  * Returns `true` if the object has no enumerable properties of its own.
       
  3603  *
       
  3604  * @method isEmpty
       
  3605  * @param {Object} obj An object.
       
  3606  * @return {Boolean} `true` if the object is empty.
       
  3607  * @static
       
  3608  * @since 3.2.0
       
  3609  */
       
  3610 O.isEmpty = function (obj) {
       
  3611     return !O.keys(Object(obj)).length;
       
  3612 };
       
  3613 /**
       
  3614  * The YUI module contains the components required for building the YUI seed
       
  3615  * file.  This includes the script loading mechanism, a simple queue, and the
       
  3616  * core utilities for the library.
       
  3617  * @module yui
       
  3618  * @submodule yui-base
       
  3619  */
       
  3620 
       
  3621 /**
       
  3622  * YUI user agent detection.
       
  3623  * Do not fork for a browser if it can be avoided.  Use feature detection when
       
  3624  * you can.  Use the user agent as a last resort.  For all fields listed
       
  3625  * as @type float, UA stores a version number for the browser engine,
       
  3626  * 0 otherwise.  This value may or may not map to the version number of
       
  3627  * the browser using the engine.  The value is presented as a float so
       
  3628  * that it can easily be used for boolean evaluation as well as for
       
  3629  * looking for a particular range of versions.  Because of this,
       
  3630  * some of the granularity of the version info may be lost.  The fields that
       
  3631  * are @type string default to null.  The API docs list the values that
       
  3632  * these fields can have.
       
  3633  * @class UA
       
  3634  * @static
       
  3635  */
       
  3636 
       
  3637 /**
       
  3638 * Static method on `YUI.Env` for parsing a UA string.  Called at instantiation
       
  3639 * to populate `Y.UA`.
       
  3640 *
       
  3641 * @static
       
  3642 * @method parseUA
       
  3643 * @param {String} [subUA=navigator.userAgent] UA string to parse
       
  3644 * @return {Object} The Y.UA object
       
  3645 */
       
  3646 YUI.Env.parseUA = function(subUA) {
       
  3647 
       
  3648     var numberify = function(s) {
       
  3649             var c = 0;
       
  3650             return parseFloat(s.replace(/\./g, function() {
       
  3651                 return (c++ === 1) ? '' : '.';
       
  3652             }));
       
  3653         },
       
  3654 
       
  3655         win = Y.config.win,
       
  3656 
       
  3657         nav = win && win.navigator,
       
  3658 
       
  3659         o = {
       
  3660 
       
  3661         /**
       
  3662          * Internet Explorer version number or 0.  Example: 6
       
  3663          * @property ie
       
  3664          * @type float
       
  3665          * @static
       
  3666          */
       
  3667         ie: 0,
       
  3668 
       
  3669         /**
       
  3670          * Opera version number or 0.  Example: 9.2
       
  3671          * @property opera
       
  3672          * @type float
       
  3673          * @static
       
  3674          */
       
  3675         opera: 0,
       
  3676 
       
  3677         /**
       
  3678          * Gecko engine revision number.  Will evaluate to 1 if Gecko
       
  3679          * is detected but the revision could not be found. Other browsers
       
  3680          * will be 0.  Example: 1.8
       
  3681          * <pre>
       
  3682          * Firefox 1.0.0.4: 1.7.8   <-- Reports 1.7
       
  3683          * Firefox 1.5.0.9: 1.8.0.9 <-- 1.8
       
  3684          * Firefox 2.0.0.3: 1.8.1.3 <-- 1.81
       
  3685          * Firefox 3.0   <-- 1.9
       
  3686          * Firefox 3.5   <-- 1.91
       
  3687          * </pre>
       
  3688          * @property gecko
       
  3689          * @type float
       
  3690          * @static
       
  3691          */
       
  3692         gecko: 0,
       
  3693 
       
  3694         /**
       
  3695          * AppleWebKit version.  KHTML browsers that are not WebKit browsers
       
  3696          * will evaluate to 1, other browsers 0.  Example: 418.9
       
  3697          * <pre>
       
  3698          * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the
       
  3699          *                                   latest available for Mac OSX 10.3.
       
  3700          * Safari 2.0.2:         416     <-- hasOwnProperty introduced
       
  3701          * Safari 2.0.4:         418     <-- preventDefault fixed
       
  3702          * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
       
  3703          *                                   different versions of webkit
       
  3704          * Safari 2.0.4 (419.3): 419     <-- Tiger installations that have been
       
  3705          *                                   updated, but not updated
       
  3706          *                                   to the latest patch.
       
  3707          * Webkit 212 nightly:   522+    <-- Safari 3.0 precursor (with native
       
  3708          * SVG and many major issues fixed).
       
  3709          * Safari 3.0.4 (523.12) 523.12  <-- First Tiger release - automatic
       
  3710          * update from 2.x via the 10.4.11 OS patch.
       
  3711          * Webkit nightly 1/2008:525+    <-- Supports DOMContentLoaded event.
       
  3712          *                                   yahoo.com user agent hack removed.
       
  3713          * </pre>
       
  3714          * http://en.wikipedia.org/wiki/Safari_version_history
       
  3715          * @property webkit
       
  3716          * @type float
       
  3717          * @static
       
  3718          */
       
  3719         webkit: 0,
       
  3720 
       
  3721         /**
       
  3722          * Safari will be detected as webkit, but this property will also
       
  3723          * be populated with the Safari version number
       
  3724          * @property safari
       
  3725          * @type float
       
  3726          * @static
       
  3727          */
       
  3728         safari: 0,
       
  3729 
       
  3730         /**
       
  3731          * Chrome will be detected as webkit, but this property will also
       
  3732          * be populated with the Chrome version number
       
  3733          * @property chrome
       
  3734          * @type float
       
  3735          * @static
       
  3736          */
       
  3737         chrome: 0,
       
  3738 
       
  3739         /**
       
  3740          * The mobile property will be set to a string containing any relevant
       
  3741          * user agent information when a modern mobile browser is detected.
       
  3742          * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
       
  3743          * devices with the WebKit-based browser, and Opera Mini.
       
  3744          * @property mobile
       
  3745          * @type string
       
  3746          * @default null
       
  3747          * @static
       
  3748          */
       
  3749         mobile: null,
       
  3750 
       
  3751         /**
       
  3752          * Adobe AIR version number or 0.  Only populated if webkit is detected.
       
  3753          * Example: 1.0
       
  3754          * @property air
       
  3755          * @type float
       
  3756          */
       
  3757         air: 0,
       
  3758         /**
       
  3759          * PhantomJS version number or 0.  Only populated if webkit is detected.
       
  3760          * Example: 1.0
       
  3761          * @property phantomjs
       
  3762          * @type float
       
  3763          */
       
  3764         phantomjs: 0,
       
  3765         /**
       
  3766          * Detects Apple iPad's OS version
       
  3767          * @property ipad
       
  3768          * @type float
       
  3769          * @static
       
  3770          */
       
  3771         ipad: 0,
       
  3772         /**
       
  3773          * Detects Apple iPhone's OS version
       
  3774          * @property iphone
       
  3775          * @type float
       
  3776          * @static
       
  3777          */
       
  3778         iphone: 0,
       
  3779         /**
       
  3780          * Detects Apples iPod's OS version
       
  3781          * @property ipod
       
  3782          * @type float
       
  3783          * @static
       
  3784          */
       
  3785         ipod: 0,
       
  3786         /**
       
  3787          * General truthy check for iPad, iPhone or iPod
       
  3788          * @property ios
       
  3789          * @type Boolean
       
  3790          * @default null
       
  3791          * @static
       
  3792          */
       
  3793         ios: null,
       
  3794         /**
       
  3795          * Detects Googles Android OS version
       
  3796          * @property android
       
  3797          * @type float
       
  3798          * @static
       
  3799          */
       
  3800         android: 0,
       
  3801         /**
       
  3802          * Detects Kindle Silk
       
  3803          * @property silk
       
  3804          * @type float
       
  3805          * @static
       
  3806          */
       
  3807         silk: 0,
       
  3808         /**
       
  3809          * Detects Kindle Silk Acceleration
       
  3810          * @property accel
       
  3811          * @type Boolean
       
  3812          * @static
       
  3813          */
       
  3814         accel: false,
       
  3815         /**
       
  3816          * Detects Palms WebOS version
       
  3817          * @property webos
       
  3818          * @type float
       
  3819          * @static
       
  3820          */
       
  3821         webos: 0,
       
  3822 
       
  3823         /**
       
  3824          * Google Caja version number or 0.
       
  3825          * @property caja
       
  3826          * @type float
       
  3827          */
       
  3828         caja: nav && nav.cajaVersion,
       
  3829 
       
  3830         /**
       
  3831          * Set to true if the page appears to be in SSL
       
  3832          * @property secure
       
  3833          * @type boolean
       
  3834          * @static
       
  3835          */
       
  3836         secure: false,
       
  3837 
       
  3838         /**
       
  3839          * The operating system.  Currently only detecting windows or macintosh
       
  3840          * @property os
       
  3841          * @type string
       
  3842          * @default null
       
  3843          * @static
       
  3844          */
       
  3845         os: null,
       
  3846 
       
  3847         /**
       
  3848          * The Nodejs Version
       
  3849          * @property nodejs
       
  3850          * @type float
       
  3851          * @default 0
       
  3852          * @static
       
  3853          */
       
  3854         nodejs: 0,
       
  3855         /**
       
  3856         * Window8/IE10 Application host environment
       
  3857         * @property winjs
       
  3858         * @type Boolean
       
  3859         * @static
       
  3860         */
       
  3861         winjs: !!((typeof Windows !== "undefined") && Windows.System),
       
  3862         /**
       
  3863         * Are touch/msPointer events available on this device
       
  3864         * @property touchEnabled
       
  3865         * @type Boolean
       
  3866         * @static
       
  3867         */
       
  3868         touchEnabled: false
       
  3869     },
       
  3870 
       
  3871     ua = subUA || nav && nav.userAgent,
       
  3872 
       
  3873     loc = win && win.location,
       
  3874 
       
  3875     href = loc && loc.href,
       
  3876 
       
  3877     m;
       
  3878 
       
  3879     /**
       
  3880     * The User Agent string that was parsed
       
  3881     * @property userAgent
       
  3882     * @type String
       
  3883     * @static
       
  3884     */
       
  3885     o.userAgent = ua;
       
  3886 
       
  3887 
       
  3888     o.secure = href && (href.toLowerCase().indexOf('https') === 0);
       
  3889 
       
  3890     if (ua) {
       
  3891 
       
  3892         if ((/windows|win32/i).test(ua)) {
       
  3893             o.os = 'windows';
       
  3894         } else if ((/macintosh|mac_powerpc/i).test(ua)) {
       
  3895             o.os = 'macintosh';
       
  3896         } else if ((/android/i).test(ua)) {
       
  3897             o.os = 'android';
       
  3898         } else if ((/symbos/i).test(ua)) {
       
  3899             o.os = 'symbos';
       
  3900         } else if ((/linux/i).test(ua)) {
       
  3901             o.os = 'linux';
       
  3902         } else if ((/rhino/i).test(ua)) {
       
  3903             o.os = 'rhino';
       
  3904         }
       
  3905 
       
  3906         // Modern KHTML browsers should qualify as Safari X-Grade
       
  3907         if ((/KHTML/).test(ua)) {
       
  3908             o.webkit = 1;
       
  3909         }
       
  3910         if ((/IEMobile|XBLWP7/).test(ua)) {
       
  3911             o.mobile = 'windows';
       
  3912         }
       
  3913         if ((/Fennec/).test(ua)) {
       
  3914             o.mobile = 'gecko';
       
  3915         }
       
  3916         // Modern WebKit browsers are at least X-Grade
       
  3917         m = ua.match(/AppleWebKit\/([^\s]*)/);
       
  3918         if (m && m[1]) {
       
  3919             o.webkit = numberify(m[1]);
       
  3920             o.safari = o.webkit;
       
  3921 
       
  3922             if (/PhantomJS/.test(ua)) {
       
  3923                 m = ua.match(/PhantomJS\/([^\s]*)/);
       
  3924                 if (m && m[1]) {
       
  3925                     o.phantomjs = numberify(m[1]);
       
  3926                 }
       
  3927             }
       
  3928 
       
  3929             // Mobile browser check
       
  3930             if (/ Mobile\//.test(ua) || (/iPad|iPod|iPhone/).test(ua)) {
       
  3931                 o.mobile = 'Apple'; // iPhone or iPod Touch
       
  3932 
       
  3933                 m = ua.match(/OS ([^\s]*)/);
       
  3934                 if (m && m[1]) {
       
  3935                     m = numberify(m[1].replace('_', '.'));
       
  3936                 }
       
  3937                 o.ios = m;
       
  3938                 o.os = 'ios';
       
  3939                 o.ipad = o.ipod = o.iphone = 0;
       
  3940 
       
  3941                 m = ua.match(/iPad|iPod|iPhone/);
       
  3942                 if (m && m[0]) {
       
  3943                     o[m[0].toLowerCase()] = o.ios;
       
  3944                 }
       
  3945             } else {
       
  3946                 m = ua.match(/NokiaN[^\/]*|webOS\/\d\.\d/);
       
  3947                 if (m) {
       
  3948                     // Nokia N-series, webOS, ex: NokiaN95
       
  3949                     o.mobile = m[0];
       
  3950                 }
       
  3951                 if (/webOS/.test(ua)) {
       
  3952                     o.mobile = 'WebOS';
       
  3953                     m = ua.match(/webOS\/([^\s]*);/);
       
  3954                     if (m && m[1]) {
       
  3955                         o.webos = numberify(m[1]);
       
  3956                     }
       
  3957                 }
       
  3958                 if (/ Android/.test(ua)) {
       
  3959                     if (/Mobile/.test(ua)) {
       
  3960                         o.mobile = 'Android';
       
  3961                     }
       
  3962                     m = ua.match(/Android ([^\s]*);/);
       
  3963                     if (m && m[1]) {
       
  3964                         o.android = numberify(m[1]);
       
  3965                     }
       
  3966 
       
  3967                 }
       
  3968                 if (/Silk/.test(ua)) {
       
  3969                     m = ua.match(/Silk\/([^\s]*)/);
       
  3970                     if (m && m[1]) {
       
  3971                         o.silk = numberify(m[1]);
       
  3972                     }
       
  3973                     if (!o.android) {
       
  3974                         o.android = 2.34; //Hack for desktop mode in Kindle
       
  3975                         o.os = 'Android';
       
  3976                     }
       
  3977                     if (/Accelerated=true/.test(ua)) {
       
  3978                         o.accel = true;
       
  3979                     }
       
  3980                 }
       
  3981             }
       
  3982 
       
  3983             m = ua.match(/OPR\/(\d+\.\d+)/);
       
  3984 
       
  3985             if (m && m[1]) {
       
  3986                 // Opera 15+ with Blink (pretends to be both Chrome and Safari)
       
  3987                 o.opera = numberify(m[1]);
       
  3988             } else {
       
  3989                 m = ua.match(/(Chrome|CrMo|CriOS)\/([^\s]*)/);
       
  3990 
       
  3991                 if (m && m[1] && m[2]) {
       
  3992                     o.chrome = numberify(m[2]); // Chrome
       
  3993                     o.safari = 0; //Reset safari back to 0
       
  3994                     if (m[1] === 'CrMo') {
       
  3995                         o.mobile = 'chrome';
       
  3996                     }
       
  3997                 } else {
       
  3998                     m = ua.match(/AdobeAIR\/([^\s]*)/);
       
  3999                     if (m) {
       
  4000                         o.air = m[0]; // Adobe AIR 1.0 or better
       
  4001                     }
       
  4002                 }
       
  4003             }
       
  4004         }
       
  4005 
       
  4006         if (!o.webkit) { // not webkit
       
  4007 // @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
       
  4008             if (/Opera/.test(ua)) {
       
  4009                 m = ua.match(/Opera[\s\/]([^\s]*)/);
       
  4010                 if (m && m[1]) {
       
  4011                     o.opera = numberify(m[1]);
       
  4012                 }
       
  4013                 m = ua.match(/Version\/([^\s]*)/);
       
  4014                 if (m && m[1]) {
       
  4015                     o.opera = numberify(m[1]); // opera 10+
       
  4016                 }
       
  4017 
       
  4018                 if (/Opera Mobi/.test(ua)) {
       
  4019                     o.mobile = 'opera';
       
  4020                     m = ua.replace('Opera Mobi', '').match(/Opera ([^\s]*)/);
       
  4021                     if (m && m[1]) {
       
  4022                         o.opera = numberify(m[1]);
       
  4023                     }
       
  4024                 }
       
  4025                 m = ua.match(/Opera Mini[^;]*/);
       
  4026 
       
  4027                 if (m) {
       
  4028                     o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
       
  4029                 }
       
  4030             } else { // not opera or webkit
       
  4031                 m = ua.match(/MSIE ([^;]*)|Trident.*; rv:([0-9.]+)/);
       
  4032 
       
  4033                 if (m && (m[1] || m[2])) {
       
  4034                     o.ie = numberify(m[1] || m[2]);
       
  4035                 } else { // not opera, webkit, or ie
       
  4036                     m = ua.match(/Gecko\/([^\s]*)/);
       
  4037 
       
  4038                     if (m) {
       
  4039                         o.gecko = 1; // Gecko detected, look for revision
       
  4040                         m = ua.match(/rv:([^\s\)]*)/);
       
  4041                         if (m && m[1]) {
       
  4042                             o.gecko = numberify(m[1]);
       
  4043                             if (/Mobile|Tablet/.test(ua)) {
       
  4044                                 o.mobile = "ffos";
       
  4045                             }
       
  4046                         }
       
  4047                     }
       
  4048                 }
       
  4049             }
       
  4050         }
       
  4051     }
       
  4052 
       
  4053     //Check for known properties to tell if touch events are enabled on this device or if
       
  4054     //the number of MSPointer touchpoints on this device is greater than 0.
       
  4055     if (win && nav && !(o.chrome && o.chrome < 6)) {
       
  4056         o.touchEnabled = (("ontouchstart" in win) || (("msMaxTouchPoints" in nav) && (nav.msMaxTouchPoints > 0)));
       
  4057     }
       
  4058 
       
  4059     //It was a parsed UA, do not assign the global value.
       
  4060     if (!subUA) {
       
  4061 
       
  4062         if (typeof process === 'object') {
       
  4063 
       
  4064             if (process.versions && process.versions.node) {
       
  4065                 //NodeJS
       
  4066                 o.os = process.platform;
       
  4067                 o.nodejs = numberify(process.versions.node);
       
  4068             }
       
  4069         }
       
  4070 
       
  4071         YUI.Env.UA = o;
       
  4072 
       
  4073     }
       
  4074 
       
  4075     return o;
       
  4076 };
       
  4077 
       
  4078 
       
  4079 Y.UA = YUI.Env.UA || YUI.Env.parseUA();
       
  4080 
       
  4081 /**
       
  4082 Performs a simple comparison between two version numbers, accounting for
       
  4083 standard versioning logic such as the fact that "535.8" is a lower version than
       
  4084 "535.24", even though a simple numerical comparison would indicate that it's
       
  4085 greater. Also accounts for cases such as "1.1" vs. "1.1.0", which are
       
  4086 considered equivalent.
       
  4087 
       
  4088 Returns -1 if version _a_ is lower than version _b_, 0 if they're equivalent,
       
  4089 1 if _a_ is higher than _b_.
       
  4090 
       
  4091 Versions may be numbers or strings containing numbers and dots. For example,
       
  4092 both `535` and `"535.8.10"` are acceptable. A version string containing
       
  4093 non-numeric characters, like `"535.8.beta"`, may produce unexpected results.
       
  4094 
       
  4095 @method compareVersions
       
  4096 @param {Number|String} a First version number to compare.
       
  4097 @param {Number|String} b Second version number to compare.
       
  4098 @return -1 if _a_ is lower than _b_, 0 if they're equivalent, 1 if _a_ is
       
  4099     higher than _b_.
       
  4100 **/
       
  4101 Y.UA.compareVersions = function (a, b) {
       
  4102     var aPart, aParts, bPart, bParts, i, len;
       
  4103 
       
  4104     if (a === b) {
       
  4105         return 0;
       
  4106     }
       
  4107 
       
  4108     aParts = (a + '').split('.');
       
  4109     bParts = (b + '').split('.');
       
  4110 
       
  4111     for (i = 0, len = Math.max(aParts.length, bParts.length); i < len; ++i) {
       
  4112         aPart = parseInt(aParts[i], 10);
       
  4113         bPart = parseInt(bParts[i], 10);
       
  4114 
       
  4115         /*jshint expr: true*/
       
  4116         isNaN(aPart) && (aPart = 0);
       
  4117         isNaN(bPart) && (bPart = 0);
       
  4118 
       
  4119         if (aPart < bPart) {
       
  4120             return -1;
       
  4121         }
       
  4122 
       
  4123         if (aPart > bPart) {
       
  4124             return 1;
       
  4125         }
       
  4126     }
       
  4127 
       
  4128     return 0;
       
  4129 };
       
  4130 YUI.Env.aliases = {
       
  4131     "anim": ["anim-base","anim-color","anim-curve","anim-easing","anim-node-plugin","anim-scroll","anim-xy"],
       
  4132     "anim-shape-transform": ["anim-shape"],
       
  4133     "app": ["app-base","app-content","app-transitions","lazy-model-list","model","model-list","model-sync-rest","model-sync-local","router","view","view-node-map"],
       
  4134     "attribute": ["attribute-base","attribute-complex"],
       
  4135     "attribute-events": ["attribute-observable"],
       
  4136     "autocomplete": ["autocomplete-base","autocomplete-sources","autocomplete-list","autocomplete-plugin"],
       
  4137     "axes": ["axis-numeric","axis-category","axis-time","axis-stacked"],
       
  4138     "axes-base": ["axis-numeric-base","axis-category-base","axis-time-base","axis-stacked-base"],
       
  4139     "base": ["base-base","base-pluginhost","base-build"],
       
  4140     "cache": ["cache-base","cache-offline","cache-plugin"],
       
  4141     "charts": ["charts-base"],
       
  4142     "collection": ["array-extras","arraylist","arraylist-add","arraylist-filter","array-invoke"],
       
  4143     "color": ["color-base","color-hsl","color-harmony"],
       
  4144     "controller": ["router"],
       
  4145     "dataschema": ["dataschema-base","dataschema-json","dataschema-xml","dataschema-array","dataschema-text"],
       
  4146     "datasource": ["datasource-local","datasource-io","datasource-get","datasource-function","datasource-cache","datasource-jsonschema","datasource-xmlschema","datasource-arrayschema","datasource-textschema","datasource-polling"],
       
  4147     "datatable": ["datatable-core","datatable-table","datatable-head","datatable-body","datatable-base","datatable-column-widths","datatable-message","datatable-mutable","datatable-sort","datatable-datasource"],
       
  4148     "datatype": ["datatype-date","datatype-number","datatype-xml"],
       
  4149     "datatype-date": ["datatype-date-parse","datatype-date-format","datatype-date-math"],
       
  4150     "datatype-number": ["datatype-number-parse","datatype-number-format"],
       
  4151     "datatype-xml": ["datatype-xml-parse","datatype-xml-format"],
       
  4152     "dd": ["dd-ddm-base","dd-ddm","dd-ddm-drop","dd-drag","dd-proxy","dd-constrain","dd-drop","dd-scroll","dd-delegate"],
       
  4153     "dom": ["dom-base","dom-screen","dom-style","selector-native","selector"],
       
  4154     "editor": ["frame","editor-selection","exec-command","editor-base","editor-para","editor-br","editor-bidi","editor-tab","createlink-base"],
       
  4155     "event": ["event-base","event-delegate","event-synthetic","event-mousewheel","event-mouseenter","event-key","event-focus","event-resize","event-hover","event-outside","event-touch","event-move","event-flick","event-valuechange","event-tap"],
       
  4156     "event-custom": ["event-custom-base","event-custom-complex"],
       
  4157     "event-gestures": ["event-flick","event-move"],
       
  4158     "handlebars": ["handlebars-compiler"],
       
  4159     "highlight": ["highlight-base","highlight-accentfold"],
       
  4160     "history": ["history-base","history-hash","history-html5"],
       
  4161     "io": ["io-base","io-xdr","io-form","io-upload-iframe","io-queue"],
       
  4162     "json": ["json-parse","json-stringify"],
       
  4163     "loader": ["loader-base","loader-rollup","loader-yui3"],
       
  4164     "node": ["node-base","node-event-delegate","node-pluginhost","node-screen","node-style"],
       
  4165     "pluginhost": ["pluginhost-base","pluginhost-config"],
       
  4166     "querystring": ["querystring-parse","querystring-stringify"],
       
  4167     "recordset": ["recordset-base","recordset-sort","recordset-filter","recordset-indexer"],
       
  4168     "resize": ["resize-base","resize-proxy","resize-constrain"],
       
  4169     "slider": ["slider-base","slider-value-range","clickable-rail","range-slider"],
       
  4170     "template": ["template-base","template-micro"],
       
  4171     "text": ["text-accentfold","text-wordbreak"],
       
  4172     "widget": ["widget-base","widget-htmlparser","widget-skin","widget-uievents"]
       
  4173 };
       
  4174 
       
  4175 
       
  4176 }, '@VERSION@', {"use": ["get", "features", "intl-base", "yui-log", "yui-later"]});
       
  4177 YUI.add('get', function (Y, NAME) {
       
  4178 
       
  4179 /*jslint boss:true, expr:true, laxbreak: true */
       
  4180 
       
  4181 /**
       
  4182 Provides dynamic loading of remote JavaScript and CSS resources.
       
  4183 
       
  4184 @module get
       
  4185 @class Get
       
  4186 @static
       
  4187 **/
       
  4188 
       
  4189 var Lang = Y.Lang,
       
  4190 
       
  4191     CUSTOM_ATTRS, // defined lazily in Y.Get.Transaction._createNode()
       
  4192 
       
  4193     Get, Transaction;
       
  4194 
       
  4195 Y.Get = Get = {
       
  4196     // -- Public Properties ----------------------------------------------------
       
  4197 
       
  4198     /**
       
  4199     Default options for CSS requests. Options specified here will override
       
  4200     global defaults for CSS requests.
       
  4201 
       
  4202     See the `options` property for all available options.
       
  4203 
       
  4204     @property cssOptions
       
  4205     @type Object
       
  4206     @static
       
  4207     @since 3.5.0
       
  4208     **/
       
  4209     cssOptions: {
       
  4210         attributes: {
       
  4211             rel: 'stylesheet'
       
  4212         },
       
  4213 
       
  4214         doc         : Y.config.linkDoc || Y.config.doc,
       
  4215         pollInterval: 50
       
  4216     },
       
  4217 
       
  4218     /**
       
  4219     Default options for JS requests. Options specified here will override global
       
  4220     defaults for JS requests.
       
  4221 
       
  4222     See the `options` property for all available options.
       
  4223 
       
  4224     @property jsOptions
       
  4225     @type Object
       
  4226     @static
       
  4227     @since 3.5.0
       
  4228     **/
       
  4229     jsOptions: {
       
  4230         autopurge: true,
       
  4231         doc      : Y.config.scriptDoc || Y.config.doc
       
  4232     },
       
  4233 
       
  4234     /**
       
  4235     Default options to use for all requests.
       
  4236 
       
  4237     Note that while all available options are documented here for ease of
       
  4238     discovery, some options (like callback functions) only make sense at the
       
  4239     transaction level.
       
  4240 
       
  4241     Callback functions specified via the options object or the `options`
       
  4242     parameter of the `css()`, `js()`, or `load()` methods will receive the
       
  4243     transaction object as a parameter. See `Y.Get.Transaction` for details on
       
  4244     the properties and methods available on transactions.
       
  4245 
       
  4246     @static
       
  4247     @since 3.5.0
       
  4248     @property {Object} options
       
  4249 
       
  4250     @property {Boolean} [options.async=false] Whether or not to load scripts
       
  4251         asynchronously, meaning they're requested in parallel and execution
       
  4252         order is not guaranteed. Has no effect on CSS, since CSS is always
       
  4253         loaded asynchronously.
       
  4254 
       
  4255     @property {Object} [options.attributes] HTML attribute name/value pairs that
       
  4256         should be added to inserted nodes. By default, the `charset` attribute
       
  4257         will be set to "utf-8" and nodes will be given an auto-generated `id`
       
  4258         attribute, but you can override these with your own values if desired.
       
  4259 
       
  4260     @property {Boolean} [options.autopurge] Whether or not to automatically
       
  4261         purge inserted nodes after the purge threshold is reached. This is
       
  4262         `true` by default for JavaScript, but `false` for CSS since purging a
       
  4263         CSS node will also remove any styling applied by the referenced file.
       
  4264 
       
  4265     @property {Object} [options.context] `this` object to use when calling
       
  4266         callback functions. Defaults to the transaction object.
       
  4267 
       
  4268     @property {Mixed} [options.data] Arbitrary data object to pass to "on*"
       
  4269         callbacks.
       
  4270 
       
  4271     @property {Document} [options.doc] Document into which nodes should be
       
  4272         inserted. By default, the current document is used.
       
  4273 
       
  4274     @property {HTMLElement|String} [options.insertBefore] HTML element or id
       
  4275         string of an element before which all generated nodes should be
       
  4276         inserted. If not specified, Get will automatically determine the best
       
  4277         place to insert nodes for maximum compatibility.
       
  4278 
       
  4279     @property {Function} [options.onEnd] Callback to execute after a transaction
       
  4280         is complete, regardless of whether it succeeded or failed.
       
  4281 
       
  4282     @property {Function} [options.onFailure] Callback to execute after a
       
  4283         transaction fails, times out, or is aborted.
       
  4284 
       
  4285     @property {Function} [options.onProgress] Callback to execute after each
       
  4286         individual request in a transaction either succeeds or fails.
       
  4287 
       
  4288     @property {Function} [options.onSuccess] Callback to execute after a
       
  4289         transaction completes successfully with no errors. Note that in browsers
       
  4290         that don't support the `error` event on CSS `<link>` nodes, a failed CSS
       
  4291         request may still be reported as a success because in these browsers
       
  4292         it can be difficult or impossible to distinguish between success and
       
  4293         failure for CSS resources.
       
  4294 
       
  4295     @property {Function} [options.onTimeout] Callback to execute after a
       
  4296         transaction times out.
       
  4297 
       
  4298     @property {Number} [options.pollInterval=50] Polling interval (in
       
  4299         milliseconds) for detecting CSS load completion in browsers that don't
       
  4300         support the `load` event on `<link>` nodes. This isn't used for
       
  4301         JavaScript.
       
  4302 
       
  4303     @property {Number} [options.purgethreshold=20] Number of nodes to insert
       
  4304         before triggering an automatic purge when `autopurge` is `true`.
       
  4305 
       
  4306     @property {Number} [options.timeout] Number of milliseconds to wait before
       
  4307         aborting a transaction. When a timeout occurs, the `onTimeout` callback
       
  4308         is called, followed by `onFailure` and finally `onEnd`. By default,
       
  4309         there is no timeout.
       
  4310 
       
  4311     @property {String} [options.type] Resource type ("css" or "js"). This option
       
  4312         is set automatically by the `css()` and `js()` functions and will be
       
  4313         ignored there, but may be useful when using the `load()` function. If
       
  4314         not specified, the type will be inferred from the URL, defaulting to
       
  4315         "js" if the URL doesn't contain a recognizable file extension.
       
  4316     **/
       
  4317     options: {
       
  4318         attributes: {
       
  4319             charset: 'utf-8'
       
  4320         },
       
  4321 
       
  4322         purgethreshold: 20
       
  4323     },
       
  4324 
       
  4325     // -- Protected Properties -------------------------------------------------
       
  4326 
       
  4327     /**
       
  4328     Regex that matches a CSS URL. Used to guess the file type when it's not
       
  4329     specified.
       
  4330 
       
  4331     @property REGEX_CSS
       
  4332     @type RegExp
       
  4333     @final
       
  4334     @protected
       
  4335     @static
       
  4336     @since 3.5.0
       
  4337     **/
       
  4338     REGEX_CSS: /\.css(?:[?;].*)?$/i,
       
  4339 
       
  4340     /**
       
  4341     Regex that matches a JS URL. Used to guess the file type when it's not
       
  4342     specified.
       
  4343 
       
  4344     @property REGEX_JS
       
  4345     @type RegExp
       
  4346     @final
       
  4347     @protected
       
  4348     @static
       
  4349     @since 3.5.0
       
  4350     **/
       
  4351     REGEX_JS : /\.js(?:[?;].*)?$/i,
       
  4352 
       
  4353     /**
       
  4354     Contains information about the current environment, such as what script and
       
  4355     link injection features it supports.
       
  4356 
       
  4357     This object is created and populated the first time the `_getEnv()` method
       
  4358     is called.
       
  4359 
       
  4360     @property _env
       
  4361     @type Object
       
  4362     @protected
       
  4363     @static
       
  4364     @since 3.5.0
       
  4365     **/
       
  4366 
       
  4367     /**
       
  4368     Mapping of document _yuid strings to <head> or <base> node references so we
       
  4369     don't have to look the node up each time we want to insert a request node.
       
  4370 
       
  4371     @property _insertCache
       
  4372     @type Object
       
  4373     @protected
       
  4374     @static
       
  4375     @since 3.5.0
       
  4376     **/
       
  4377     _insertCache: {},
       
  4378 
       
  4379     /**
       
  4380     Information about the currently pending transaction, if any.
       
  4381 
       
  4382     This is actually an object with two properties: `callback`, containing the
       
  4383     optional callback passed to `css()`, `load()`, or `js()`; and `transaction`,
       
  4384     containing the actual transaction instance.
       
  4385 
       
  4386     @property _pending
       
  4387     @type Object
       
  4388     @protected
       
  4389     @static
       
  4390     @since 3.5.0
       
  4391     **/
       
  4392     _pending: null,
       
  4393 
       
  4394     /**
       
  4395     HTML nodes eligible to be purged next time autopurge is triggered.
       
  4396 
       
  4397     @property _purgeNodes
       
  4398     @type HTMLElement[]
       
  4399     @protected
       
  4400     @static
       
  4401     @since 3.5.0
       
  4402     **/
       
  4403     _purgeNodes: [],
       
  4404 
       
  4405     /**
       
  4406     Queued transactions and associated callbacks.
       
  4407 
       
  4408     @property _queue
       
  4409     @type Object[]
       
  4410     @protected
       
  4411     @static
       
  4412     @since 3.5.0
       
  4413     **/
       
  4414     _queue: [],
       
  4415 
       
  4416     // -- Public Methods -------------------------------------------------------
       
  4417 
       
  4418     /**
       
  4419     Aborts the specified transaction.
       
  4420 
       
  4421     This will cause the transaction's `onFailure` callback to be called and
       
  4422     will prevent any new script and link nodes from being added to the document,
       
  4423     but any resources that have already been requested will continue loading
       
  4424     (there's no safe way to prevent this, unfortunately).
       
  4425 
       
  4426     *Note:* This method is deprecated as of 3.5.0, and will be removed in a
       
  4427     future version of YUI. Use the transaction-level `abort()` method instead.
       
  4428 
       
  4429     @method abort
       
  4430     @param {Get.Transaction} transaction Transaction to abort.
       
  4431     @deprecated Use the `abort()` method on the transaction instead.
       
  4432     @static
       
  4433     **/
       
  4434     abort: function (transaction) {
       
  4435         var i, id, item, len, pending;
       
  4436 
       
  4437         Y.log('`Y.Get.abort()` is deprecated as of 3.5.0. Use the `abort()` method on the transaction instead.', 'warn', 'get');
       
  4438 
       
  4439         if (!transaction.abort) {
       
  4440             id          = transaction;
       
  4441             pending     = this._pending;
       
  4442             transaction = null;
       
  4443 
       
  4444             if (pending && pending.transaction.id === id) {
       
  4445                 transaction   = pending.transaction;
       
  4446                 this._pending = null;
       
  4447             } else {
       
  4448                 for (i = 0, len = this._queue.length; i < len; ++i) {
       
  4449                     item = this._queue[i].transaction;
       
  4450 
       
  4451                     if (item.id === id) {
       
  4452                         transaction = item;
       
  4453                         this._queue.splice(i, 1);
       
  4454                         break;
       
  4455                     }
       
  4456                 }
       
  4457             }
       
  4458         }
       
  4459 
       
  4460         transaction && transaction.abort();
       
  4461     },
       
  4462 
       
  4463     /**
       
  4464     Loads one or more CSS files.
       
  4465 
       
  4466     The _urls_ parameter may be provided as a URL string, a request object,
       
  4467     or an array of URL strings and/or request objects.
       
  4468 
       
  4469     A request object is just an object that contains a `url` property and zero
       
  4470     or more options that should apply specifically to that request.
       
  4471     Request-specific options take priority over transaction-level options and
       
  4472     default options.
       
  4473 
       
  4474     URLs may be relative or absolute, and do not have to have the same origin
       
  4475     as the current page.
       
  4476 
       
  4477     The `options` parameter may be omitted completely and a callback passed in
       
  4478     its place, if desired.
       
  4479 
       
  4480     @example
       
  4481 
       
  4482         // Load a single CSS file and log a message on completion.
       
  4483         Y.Get.css('foo.css', function (err) {
       
  4484             if (err) {
       
  4485                 Y.log('foo.css failed to load!');
       
  4486             } else {
       
  4487                 Y.log('foo.css was loaded successfully');
       
  4488             }
       
  4489         });
       
  4490 
       
  4491         // Load multiple CSS files and log a message when all have finished
       
  4492         // loading.
       
  4493         var urls = ['foo.css', 'http://example.com/bar.css', 'baz/quux.css'];
       
  4494 
       
  4495         Y.Get.css(urls, function (err) {
       
  4496             if (err) {
       
  4497                 Y.log('one or more files failed to load!');
       
  4498             } else {
       
  4499                 Y.log('all files loaded successfully');
       
  4500             }
       
  4501         });
       
  4502 
       
  4503         // Specify transaction-level options, which will apply to all requests
       
  4504         // within the transaction.
       
  4505         Y.Get.css(urls, {
       
  4506             attributes: {'class': 'my-css'},
       
  4507             timeout   : 5000
       
  4508         });
       
  4509 
       
  4510         // Specify per-request options, which override transaction-level and
       
  4511         // default options.
       
  4512         Y.Get.css([
       
  4513             {url: 'foo.css', attributes: {id: 'foo'}},
       
  4514             {url: 'bar.css', attributes: {id: 'bar', charset: 'iso-8859-1'}}
       
  4515         ]);
       
  4516 
       
  4517     @method css
       
  4518     @param {String|Object|Array} urls URL string, request object, or array
       
  4519         of URLs and/or request objects to load.
       
  4520     @param {Object} [options] Options for this transaction. See the
       
  4521         `Y.Get.options` property for a complete list of available options.
       
  4522     @param {Function} [callback] Callback function to be called on completion.
       
  4523         This is a general callback and will be called before any more granular
       
  4524         callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
       
  4525         object.
       
  4526 
       
  4527         @param {Array|null} callback.err Array of errors that occurred during
       
  4528             the transaction, or `null` on success.
       
  4529         @param {Get.Transaction} callback.transaction Transaction object.
       
  4530 
       
  4531     @return {Get.Transaction} Transaction object.
       
  4532     @static
       
  4533     **/
       
  4534     css: function (urls, options, callback) {
       
  4535         return this._load('css', urls, options, callback);
       
  4536     },
       
  4537 
       
  4538     /**
       
  4539     Loads one or more JavaScript resources.
       
  4540 
       
  4541     The _urls_ parameter may be provided as a URL string, a request object,
       
  4542     or an array of URL strings and/or request objects.
       
  4543 
       
  4544     A request object is just an object that contains a `url` property and zero
       
  4545     or more options that should apply specifically to that request.
       
  4546     Request-specific options take priority over transaction-level options and
       
  4547     default options.
       
  4548 
       
  4549     URLs may be relative or absolute, and do not have to have the same origin
       
  4550     as the current page.
       
  4551 
       
  4552     The `options` parameter may be omitted completely and a callback passed in
       
  4553     its place, if desired.
       
  4554 
       
  4555     Scripts will be executed in the order they're specified unless the `async`
       
  4556     option is `true`, in which case they'll be loaded in parallel and executed
       
  4557     in whatever order they finish loading.
       
  4558 
       
  4559     @example
       
  4560 
       
  4561         // Load a single JS file and log a message on completion.
       
  4562         Y.Get.js('foo.js', function (err) {
       
  4563             if (err) {
       
  4564                 Y.log('foo.js failed to load!');
       
  4565             } else {
       
  4566                 Y.log('foo.js was loaded successfully');
       
  4567             }
       
  4568         });
       
  4569 
       
  4570         // Load multiple JS files, execute them in order, and log a message when
       
  4571         // all have finished loading.
       
  4572         var urls = ['foo.js', 'http://example.com/bar.js', 'baz/quux.js'];
       
  4573 
       
  4574         Y.Get.js(urls, function (err) {
       
  4575             if (err) {
       
  4576                 Y.log('one or more files failed to load!');
       
  4577             } else {
       
  4578                 Y.log('all files loaded successfully');
       
  4579             }
       
  4580         });
       
  4581 
       
  4582         // Specify transaction-level options, which will apply to all requests
       
  4583         // within the transaction.
       
  4584         Y.Get.js(urls, {
       
  4585             attributes: {'class': 'my-js'},
       
  4586             timeout   : 5000
       
  4587         });
       
  4588 
       
  4589         // Specify per-request options, which override transaction-level and
       
  4590         // default options.
       
  4591         Y.Get.js([
       
  4592             {url: 'foo.js', attributes: {id: 'foo'}},
       
  4593             {url: 'bar.js', attributes: {id: 'bar', charset: 'iso-8859-1'}}
       
  4594         ]);
       
  4595 
       
  4596     @method js
       
  4597     @param {String|Object|Array} urls URL string, request object, or array
       
  4598         of URLs and/or request objects to load.
       
  4599     @param {Object} [options] Options for this transaction. See the
       
  4600         `Y.Get.options` property for a complete list of available options.
       
  4601     @param {Function} [callback] Callback function to be called on completion.
       
  4602         This is a general callback and will be called before any more granular
       
  4603         callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
       
  4604         object.
       
  4605 
       
  4606         @param {Array|null} callback.err Array of errors that occurred during
       
  4607             the transaction, or `null` on success.
       
  4608         @param {Get.Transaction} callback.transaction Transaction object.
       
  4609 
       
  4610     @return {Get.Transaction} Transaction object.
       
  4611     @since 3.5.0
       
  4612     @static
       
  4613     **/
       
  4614     js: function (urls, options, callback) {
       
  4615         return this._load('js', urls, options, callback);
       
  4616     },
       
  4617 
       
  4618     /**
       
  4619     Loads one or more CSS and/or JavaScript resources in the same transaction.
       
  4620 
       
  4621     Use this method when you want to load both CSS and JavaScript in a single
       
  4622     transaction and be notified when all requested URLs have finished loading,
       
  4623     regardless of type.
       
  4624 
       
  4625     Behavior and options are the same as for the `css()` and `js()` methods. If
       
  4626     a resource type isn't specified in per-request options or transaction-level
       
  4627     options, Get will guess the file type based on the URL's extension (`.css`
       
  4628     or `.js`, with or without a following query string). If the file type can't
       
  4629     be guessed from the URL, a warning will be logged and Get will assume the
       
  4630     URL is a JavaScript resource.
       
  4631 
       
  4632     @example
       
  4633 
       
  4634         // Load both CSS and JS files in a single transaction, and log a message
       
  4635         // when all files have finished loading.
       
  4636         Y.Get.load(['foo.css', 'bar.js', 'baz.css'], function (err) {
       
  4637             if (err) {
       
  4638                 Y.log('one or more files failed to load!');
       
  4639             } else {
       
  4640                 Y.log('all files loaded successfully');
       
  4641             }
       
  4642         });
       
  4643 
       
  4644     @method load
       
  4645     @param {String|Object|Array} urls URL string, request object, or array
       
  4646         of URLs and/or request objects to load.
       
  4647     @param {Object} [options] Options for this transaction. See the
       
  4648         `Y.Get.options` property for a complete list of available options.
       
  4649     @param {Function} [callback] Callback function to be called on completion.
       
  4650         This is a general callback and will be called before any more granular
       
  4651         callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
       
  4652         object.
       
  4653 
       
  4654         @param {Array|null} err Array of errors that occurred during the
       
  4655             transaction, or `null` on success.
       
  4656         @param {Get.Transaction} Transaction object.
       
  4657 
       
  4658     @return {Get.Transaction} Transaction object.
       
  4659     @since 3.5.0
       
  4660     @static
       
  4661     **/
       
  4662     load: function (urls, options, callback) {
       
  4663         return this._load(null, urls, options, callback);
       
  4664     },
       
  4665 
       
  4666     // -- Protected Methods ----------------------------------------------------
       
  4667 
       
  4668     /**
       
  4669     Triggers an automatic purge if the purge threshold has been reached.
       
  4670 
       
  4671     @method _autoPurge
       
  4672     @param {Number} threshold Purge threshold to use, in milliseconds.
       
  4673     @protected
       
  4674     @since 3.5.0
       
  4675     @static
       
  4676     **/
       
  4677     _autoPurge: function (threshold) {
       
  4678         if (threshold && this._purgeNodes.length >= threshold) {
       
  4679             Y.log('autopurge triggered after ' + this._purgeNodes.length + ' nodes', 'info', 'get');
       
  4680             this._purge(this._purgeNodes);
       
  4681         }
       
  4682     },
       
  4683 
       
  4684     /**
       
  4685     Populates the `_env` property with information about the current
       
  4686     environment.
       
  4687 
       
  4688     @method _getEnv
       
  4689     @return {Object} Environment information.
       
  4690     @protected
       
  4691     @since 3.5.0
       
  4692     @static
       
  4693     **/
       
  4694     _getEnv: function () {
       
  4695         var doc = Y.config.doc,
       
  4696             ua  = Y.UA;
       
  4697 
       
  4698         // Note: some of these checks require browser sniffs since it's not
       
  4699         // feasible to load test files on every pageview just to perform a
       
  4700         // feature test. I'm sorry if this makes you sad.
       
  4701         return (this._env = {
       
  4702 
       
  4703             // True if this is a browser that supports disabling async mode on
       
  4704             // dynamically created script nodes. See
       
  4705             // https://developer.mozilla.org/En/HTML/Element/Script#Attributes
       
  4706 
       
  4707             // IE10 doesn't return true for the MDN feature test, so setting it explicitly,
       
  4708             // because it is async by default, and allows you to disable async by setting it to false
       
  4709             async: (doc && doc.createElement('script').async === true) || (ua.ie >= 10),
       
  4710 
       
  4711             // True if this browser fires an event when a dynamically injected
       
  4712             // link node fails to load. This is currently true for Firefox 9+
       
  4713             // and WebKit 535.24+
       
  4714             cssFail: ua.gecko >= 9 || ua.compareVersions(ua.webkit, 535.24) >= 0,
       
  4715 
       
  4716             // True if this browser fires an event when a dynamically injected
       
  4717             // link node finishes loading. This is currently true for IE, Opera,
       
  4718             // Firefox 9+, and WebKit 535.24+. Note that IE versions <9 fire the
       
  4719             // DOM 0 "onload" event, but not "load". All versions of IE fire
       
  4720             // "onload".
       
  4721             // davglass: Seems that Chrome on Android needs this to be false.
       
  4722             cssLoad: (
       
  4723                     (!ua.gecko && !ua.webkit) || ua.gecko >= 9 ||
       
  4724                     ua.compareVersions(ua.webkit, 535.24) >= 0
       
  4725                 ) && !(ua.chrome && ua.chrome <= 18),
       
  4726 
       
  4727             // True if this browser preserves script execution order while
       
  4728             // loading scripts in parallel as long as the script node's `async`
       
  4729             // attribute is set to false to explicitly disable async execution.
       
  4730             preservesScriptOrder: !!(ua.gecko || ua.opera || (ua.ie && ua.ie >= 10))
       
  4731         });
       
  4732     },
       
  4733 
       
  4734     _getTransaction: function (urls, options) {
       
  4735         var requests = [],
       
  4736             i, len, req, url;
       
  4737 
       
  4738         if (!Lang.isArray(urls)) {
       
  4739             urls = [urls];
       
  4740         }
       
  4741 
       
  4742         options = Y.merge(this.options, options);
       
  4743 
       
  4744         // Clone the attributes object so we don't end up modifying it by ref.
       
  4745         options.attributes = Y.merge(this.options.attributes,
       
  4746                 options.attributes);
       
  4747 
       
  4748         for (i = 0, len = urls.length; i < len; ++i) {
       
  4749             url = urls[i];
       
  4750             req = {attributes: {}};
       
  4751 
       
  4752             // If `url` is a string, we create a URL object for it, then mix in
       
  4753             // global options and request-specific options. If it's an object
       
  4754             // with a "url" property, we assume it's a request object containing
       
  4755             // URL-specific options.
       
  4756             if (typeof url === 'string') {
       
  4757                 req.url = url;
       
  4758             } else if (url.url) {
       
  4759                 // URL-specific options override both global defaults and
       
  4760                 // request-specific options.
       
  4761                 Y.mix(req, url, false, null, 0, true);
       
  4762                 url = url.url; // Make url a string so we can use it later.
       
  4763             } else {
       
  4764                 Y.log('URL must be a string or an object with a `url` property.', 'error', 'get');
       
  4765                 continue;
       
  4766             }
       
  4767 
       
  4768             Y.mix(req, options, false, null, 0, true);
       
  4769 
       
  4770             // If we didn't get an explicit type for this URL either in the
       
  4771             // request options or the URL-specific options, try to determine
       
  4772             // one from the file extension.
       
  4773             if (!req.type) {
       
  4774                 if (this.REGEX_CSS.test(url)) {
       
  4775                     req.type = 'css';
       
  4776                 } else {
       
  4777                     if (!this.REGEX_JS.test(url)) {
       
  4778                         Y.log("Can't guess file type from URL. Assuming JS: " + url, 'warn', 'get');
       
  4779                     }
       
  4780 
       
  4781                     req.type = 'js';
       
  4782                 }
       
  4783             }
       
  4784 
       
  4785             // Mix in type-specific default options, but don't overwrite any
       
  4786             // options that have already been set.
       
  4787             Y.mix(req, req.type === 'js' ? this.jsOptions : this.cssOptions,
       
  4788                 false, null, 0, true);
       
  4789 
       
  4790             // Give the node an id attribute if it doesn't already have one.
       
  4791             req.attributes.id || (req.attributes.id = Y.guid());
       
  4792 
       
  4793             // Backcompat for <3.5.0 behavior.
       
  4794             if (req.win) {
       
  4795                 Y.log('The `win` option is deprecated as of 3.5.0. Use `doc` instead.', 'warn', 'get');
       
  4796                 req.doc = req.win.document;
       
  4797             } else {
       
  4798                 req.win = req.doc.defaultView || req.doc.parentWindow;
       
  4799             }
       
  4800 
       
  4801             if (req.charset) {
       
  4802                 Y.log('The `charset` option is deprecated as of 3.5.0. Set `attributes.charset` instead.', 'warn', 'get');
       
  4803                 req.attributes.charset = req.charset;
       
  4804             }
       
  4805 
       
  4806             requests.push(req);
       
  4807         }
       
  4808 
       
  4809         return new Transaction(requests, options);
       
  4810     },
       
  4811 
       
  4812     _load: function (type, urls, options, callback) {
       
  4813         var transaction;
       
  4814 
       
  4815         // Allow callback as third param.
       
  4816         if (typeof options === 'function') {
       
  4817             callback = options;
       
  4818             options  = {};
       
  4819         }
       
  4820 
       
  4821         options || (options = {});
       
  4822         options.type = type;
       
  4823 
       
  4824         options._onFinish = Get._onTransactionFinish;
       
  4825 
       
  4826         if (!this._env) {
       
  4827             this._getEnv();
       
  4828         }
       
  4829 
       
  4830         transaction = this._getTransaction(urls, options);
       
  4831 
       
  4832         this._queue.push({
       
  4833             callback   : callback,
       
  4834             transaction: transaction
       
  4835         });
       
  4836 
       
  4837         this._next();
       
  4838 
       
  4839         return transaction;
       
  4840     },
       
  4841 
       
  4842     _onTransactionFinish : function() {
       
  4843         Get._pending = null;
       
  4844         Get._next();
       
  4845     },
       
  4846 
       
  4847     _next: function () {
       
  4848         var item;
       
  4849 
       
  4850         if (this._pending) {
       
  4851             return;
       
  4852         }
       
  4853 
       
  4854         item = this._queue.shift();
       
  4855 
       
  4856         if (item) {
       
  4857             this._pending = item;
       
  4858             item.transaction.execute(item.callback);
       
  4859         }
       
  4860     },
       
  4861 
       
  4862     _purge: function (nodes) {
       
  4863         var purgeNodes    = this._purgeNodes,
       
  4864             isTransaction = nodes !== purgeNodes,
       
  4865             index, node;
       
  4866 
       
  4867         while (node = nodes.pop()) { // assignment
       
  4868             // Don't purge nodes that haven't finished loading (or errored out),
       
  4869             // since this can hang the transaction.
       
  4870             if (!node._yuiget_finished) {
       
  4871                 continue;
       
  4872             }
       
  4873 
       
  4874             node.parentNode && node.parentNode.removeChild(node);
       
  4875 
       
  4876             // If this is a transaction-level purge and this node also exists in
       
  4877             // the Get-level _purgeNodes array, we need to remove it from
       
  4878             // _purgeNodes to avoid creating a memory leak. The indexOf lookup
       
  4879             // sucks, but until we get WeakMaps, this is the least troublesome
       
  4880             // way to do this (we can't just hold onto node ids because they may
       
  4881             // not be in the same document).
       
  4882             if (isTransaction) {
       
  4883                 index = Y.Array.indexOf(purgeNodes, node);
       
  4884 
       
  4885                 if (index > -1) {
       
  4886                     purgeNodes.splice(index, 1);
       
  4887                 }
       
  4888             }
       
  4889         }
       
  4890     }
       
  4891 };
       
  4892 
       
  4893 /**
       
  4894 Alias for `js()`.
       
  4895 
       
  4896 @method script
       
  4897 @static
       
  4898 **/
       
  4899 Get.script = Get.js;
       
  4900 
       
  4901 /**
       
  4902 Represents a Get transaction, which may contain requests for one or more JS or
       
  4903 CSS files.
       
  4904 
       
  4905 This class should not be instantiated manually. Instances will be created and
       
  4906 returned as needed by Y.Get's `css()`, `js()`, and `load()` methods.
       
  4907 
       
  4908 @class Get.Transaction
       
  4909 @constructor
       
  4910 @since 3.5.0
       
  4911 **/
       
  4912 Get.Transaction = Transaction = function (requests, options) {
       
  4913     var self = this;
       
  4914 
       
  4915     self.id       = Transaction._lastId += 1;
       
  4916     self.data     = options.data;
       
  4917     self.errors   = [];
       
  4918     self.nodes    = [];
       
  4919     self.options  = options;
       
  4920     self.requests = requests;
       
  4921 
       
  4922     self._callbacks = []; // callbacks to call after execution finishes
       
  4923     self._queue     = [];
       
  4924     self._reqsWaiting   = 0;
       
  4925 
       
  4926     // Deprecated pre-3.5.0 properties.
       
  4927     self.tId = self.id; // Use `id` instead.
       
  4928     self.win = options.win || Y.config.win;
       
  4929 };
       
  4930 
       
  4931 /**
       
  4932 Arbitrary data object associated with this transaction.
       
  4933 
       
  4934 This object comes from the options passed to `Get.css()`, `Get.js()`, or
       
  4935 `Get.load()`, and will be `undefined` if no data object was specified.
       
  4936 
       
  4937 @property {Object} data
       
  4938 **/
       
  4939 
       
  4940 /**
       
  4941 Array of errors that have occurred during this transaction, if any. Each error
       
  4942 object has the following properties:
       
  4943 `errors.error`: Error message.
       
  4944 `errors.request`: Request object related to the error.
       
  4945 
       
  4946 @since 3.5.0
       
  4947 @property {Object[]} errors
       
  4948 **/
       
  4949 
       
  4950 /**
       
  4951 Numeric id for this transaction, unique among all transactions within the same
       
  4952 YUI sandbox in the current pageview.
       
  4953 
       
  4954 @property {Number} id
       
  4955 @since 3.5.0
       
  4956 **/
       
  4957 
       
  4958 /**
       
  4959 HTMLElement nodes (native ones, not YUI Node instances) that have been inserted
       
  4960 during the current transaction.
       
  4961 
       
  4962 @property {HTMLElement[]} nodes
       
  4963 **/
       
  4964 
       
  4965 /**
       
  4966 Options associated with this transaction.
       
  4967 
       
  4968 See `Get.options` for the full list of available options.
       
  4969 
       
  4970 @property {Object} options
       
  4971 @since 3.5.0
       
  4972 **/
       
  4973 
       
  4974 /**
       
  4975 Request objects contained in this transaction. Each request object represents
       
  4976 one CSS or JS URL that will be (or has been) requested and loaded into the page.
       
  4977 
       
  4978 @property {Object} requests
       
  4979 @since 3.5.0
       
  4980 **/
       
  4981 
       
  4982 /**
       
  4983 Id of the most recent transaction.
       
  4984 
       
  4985 @property _lastId
       
  4986 @type Number
       
  4987 @protected
       
  4988 @static
       
  4989 **/
       
  4990 Transaction._lastId = 0;
       
  4991 
       
  4992 Transaction.prototype = {
       
  4993     // -- Public Properties ----------------------------------------------------
       
  4994 
       
  4995     /**
       
  4996     Current state of this transaction. One of "new", "executing", or "done".
       
  4997 
       
  4998     @property _state
       
  4999     @type String
       
  5000     @protected
       
  5001     **/
       
  5002     _state: 'new', // "new", "executing", or "done"
       
  5003 
       
  5004     // -- Public Methods -------------------------------------------------------
       
  5005 
       
  5006     /**
       
  5007     Aborts this transaction.
       
  5008 
       
  5009     This will cause the transaction's `onFailure` callback to be called and
       
  5010     will prevent any new script and link nodes from being added to the document,
       
  5011     but any resources that have already been requested will continue loading
       
  5012     (there's no safe way to prevent this, unfortunately).
       
  5013 
       
  5014     @method abort
       
  5015     @param {String} [msg="Aborted."] Optional message to use in the `errors`
       
  5016         array describing why the transaction was aborted.
       
  5017     **/
       
  5018     abort: function (msg) {
       
  5019         this._pending    = null;
       
  5020         this._pendingCSS = null;
       
  5021         this._pollTimer  = clearTimeout(this._pollTimer);
       
  5022         this._queue      = [];
       
  5023         this._reqsWaiting    = 0;
       
  5024 
       
  5025         this.errors.push({error: msg || 'Aborted'});
       
  5026         this._finish();
       
  5027     },
       
  5028 
       
  5029     /**
       
  5030     Begins execting the transaction.
       
  5031 
       
  5032     There's usually no reason to call this manually, since Get will call it
       
  5033     automatically when other pending transactions have finished. If you really
       
  5034     want to execute your transaction before Get does, you can, but be aware that
       
  5035     this transaction's scripts may end up executing before the scripts in other
       
  5036     pending transactions.
       
  5037 
       
  5038     If the transaction is already executing, the specified callback (if any)
       
  5039     will be queued and called after execution finishes. If the transaction has
       
  5040     already finished, the callback will be called immediately (the transaction
       
  5041     will not be executed again).
       
  5042 
       
  5043     @method execute
       
  5044     @param {Function} callback Callback function to execute after all requests
       
  5045         in the transaction are complete, or after the transaction is aborted.
       
  5046     **/
       
  5047     execute: function (callback) {
       
  5048         var self     = this,
       
  5049             requests = self.requests,
       
  5050             state    = self._state,
       
  5051             i, len, queue, req;
       
  5052 
       
  5053         if (state === 'done') {
       
  5054             callback && callback(self.errors.length ? self.errors : null, self);
       
  5055             return;
       
  5056         } else {
       
  5057             callback && self._callbacks.push(callback);
       
  5058 
       
  5059             if (state === 'executing') {
       
  5060                 return;
       
  5061             }
       
  5062         }
       
  5063 
       
  5064         self._state = 'executing';
       
  5065         self._queue = queue = [];
       
  5066 
       
  5067         if (self.options.timeout) {
       
  5068             self._timeout = setTimeout(function () {
       
  5069                 self.abort('Timeout');
       
  5070             }, self.options.timeout);
       
  5071         }
       
  5072 
       
  5073         self._reqsWaiting = requests.length;
       
  5074 
       
  5075         for (i = 0, len = requests.length; i < len; ++i) {
       
  5076             req = requests[i];
       
  5077 
       
  5078             if (req.async || req.type === 'css') {
       
  5079                 // No need to queue CSS or fully async JS.
       
  5080                 self._insert(req);
       
  5081             } else {
       
  5082                 queue.push(req);
       
  5083             }
       
  5084         }
       
  5085 
       
  5086         self._next();
       
  5087     },
       
  5088 
       
  5089     /**
       
  5090     Manually purges any `<script>` or `<link>` nodes this transaction has
       
  5091     created.
       
  5092 
       
  5093     Be careful when purging a transaction that contains CSS requests, since
       
  5094     removing `<link>` nodes will also remove any styles they applied.
       
  5095 
       
  5096     @method purge
       
  5097     **/
       
  5098     purge: function () {
       
  5099         Get._purge(this.nodes);
       
  5100     },
       
  5101 
       
  5102     // -- Protected Methods ----------------------------------------------------
       
  5103     _createNode: function (name, attrs, doc) {
       
  5104         var node = doc.createElement(name),
       
  5105             attr, testEl;
       
  5106 
       
  5107         if (!CUSTOM_ATTRS) {
       
  5108             // IE6 and IE7 expect property names rather than attribute names for
       
  5109             // certain attributes. Rather than sniffing, we do a quick feature
       
  5110             // test the first time _createNode() runs to determine whether we
       
  5111             // need to provide a workaround.
       
  5112             testEl = doc.createElement('div');
       
  5113             testEl.setAttribute('class', 'a');
       
  5114 
       
  5115             CUSTOM_ATTRS = testEl.className === 'a' ? {} : {
       
  5116                 'for'  : 'htmlFor',
       
  5117                 'class': 'className'
       
  5118             };
       
  5119         }
       
  5120 
       
  5121         for (attr in attrs) {
       
  5122             if (attrs.hasOwnProperty(attr)) {
       
  5123                 node.setAttribute(CUSTOM_ATTRS[attr] || attr, attrs[attr]);
       
  5124             }
       
  5125         }
       
  5126 
       
  5127         return node;
       
  5128     },
       
  5129 
       
  5130     _finish: function () {
       
  5131         var errors  = this.errors.length ? this.errors : null,
       
  5132             options = this.options,
       
  5133             thisObj = options.context || this,
       
  5134             data, i, len;
       
  5135 
       
  5136         if (this._state === 'done') {
       
  5137             return;
       
  5138         }
       
  5139 
       
  5140         this._state = 'done';
       
  5141 
       
  5142         for (i = 0, len = this._callbacks.length; i < len; ++i) {
       
  5143             this._callbacks[i].call(thisObj, errors, this);
       
  5144         }
       
  5145 
       
  5146         data = this._getEventData();
       
  5147 
       
  5148         if (errors) {
       
  5149             if (options.onTimeout && errors[errors.length - 1].error === 'Timeout') {
       
  5150                 options.onTimeout.call(thisObj, data);
       
  5151             }
       
  5152 
       
  5153             if (options.onFailure) {
       
  5154                 options.onFailure.call(thisObj, data);
       
  5155             }
       
  5156         } else if (options.onSuccess) {
       
  5157             options.onSuccess.call(thisObj, data);
       
  5158         }
       
  5159 
       
  5160         if (options.onEnd) {
       
  5161             options.onEnd.call(thisObj, data);
       
  5162         }
       
  5163 
       
  5164         if (options._onFinish) {
       
  5165             options._onFinish();
       
  5166         }
       
  5167     },
       
  5168 
       
  5169     _getEventData: function (req) {
       
  5170         if (req) {
       
  5171             // This merge is necessary for backcompat. I hate it.
       
  5172             return Y.merge(this, {
       
  5173                 abort  : this.abort, // have to copy these because the prototype isn't preserved
       
  5174                 purge  : this.purge,
       
  5175                 request: req,
       
  5176                 url    : req.url,
       
  5177                 win    : req.win
       
  5178             });
       
  5179         } else {
       
  5180             return this;
       
  5181         }
       
  5182     },
       
  5183 
       
  5184     _getInsertBefore: function (req) {
       
  5185         var doc = req.doc,
       
  5186             el  = req.insertBefore,
       
  5187             cache, docStamp;
       
  5188 
       
  5189         if (el) {
       
  5190             return typeof el === 'string' ? doc.getElementById(el) : el;
       
  5191         }
       
  5192 
       
  5193         cache    = Get._insertCache;
       
  5194         docStamp = Y.stamp(doc);
       
  5195 
       
  5196         if ((el = cache[docStamp])) { // assignment
       
  5197             return el;
       
  5198         }
       
  5199 
       
  5200         // Inserting before a <base> tag apparently works around an IE bug
       
  5201         // (according to a comment from pre-3.5.0 Y.Get), but I'm not sure what
       
  5202         // bug that is, exactly. Better safe than sorry?
       
  5203         if ((el = doc.getElementsByTagName('base')[0])) { // assignment
       
  5204             return (cache[docStamp] = el);
       
  5205         }
       
  5206 
       
  5207         // Look for a <head> element.
       
  5208         el = doc.head || doc.getElementsByTagName('head')[0];
       
  5209 
       
  5210         if (el) {
       
  5211             // Create a marker node at the end of <head> to use as an insertion
       
  5212             // point. Inserting before this node will ensure that all our CSS
       
  5213             // gets inserted in the correct order, to maintain style precedence.
       
  5214             el.appendChild(doc.createTextNode(''));
       
  5215             return (cache[docStamp] = el.lastChild);
       
  5216         }
       
  5217 
       
  5218         // If all else fails, just insert before the first script node on the
       
  5219         // page, which is virtually guaranteed to exist.
       
  5220         return (cache[docStamp] = doc.getElementsByTagName('script')[0]);
       
  5221     },
       
  5222 
       
  5223     _insert: function (req) {
       
  5224         var env          = Get._env,
       
  5225             insertBefore = this._getInsertBefore(req),
       
  5226             isScript     = req.type === 'js',
       
  5227             node         = req.node,
       
  5228             self         = this,
       
  5229             ua           = Y.UA,
       
  5230             cssTimeout, nodeType;
       
  5231 
       
  5232         if (!node) {
       
  5233             if (isScript) {
       
  5234                 nodeType = 'script';
       
  5235             } else if (!env.cssLoad && ua.gecko) {
       
  5236                 nodeType = 'style';
       
  5237             } else {
       
  5238                 nodeType = 'link';
       
  5239             }
       
  5240 
       
  5241             node = req.node = this._createNode(nodeType, req.attributes,
       
  5242                 req.doc);
       
  5243         }
       
  5244 
       
  5245         function onError() {
       
  5246             self._progress('Failed to load ' + req.url, req);
       
  5247         }
       
  5248 
       
  5249         function onLoad() {
       
  5250             if (cssTimeout) {
       
  5251                 clearTimeout(cssTimeout);
       
  5252             }
       
  5253 
       
  5254             self._progress(null, req);
       
  5255         }
       
  5256 
       
  5257         // Deal with script asynchronicity.
       
  5258         if (isScript) {
       
  5259             node.setAttribute('src', req.url);
       
  5260 
       
  5261             if (req.async) {
       
  5262                 // Explicitly indicate that we want the browser to execute this
       
  5263                 // script asynchronously. This is necessary for older browsers
       
  5264                 // like Firefox <4.
       
  5265                 node.async = true;
       
  5266             } else {
       
  5267                 if (env.async) {
       
  5268                     // This browser treats injected scripts as async by default
       
  5269                     // (standard HTML5 behavior) but asynchronous loading isn't
       
  5270                     // desired, so tell the browser not to mark this script as
       
  5271                     // async.
       
  5272                     node.async = false;
       
  5273                 }
       
  5274 
       
  5275                 // If this browser doesn't preserve script execution order based
       
  5276                 // on insertion order, we'll need to avoid inserting other
       
  5277                 // scripts until this one finishes loading.
       
  5278                 if (!env.preservesScriptOrder) {
       
  5279                     this._pending = req;
       
  5280                 }
       
  5281             }
       
  5282         } else {
       
  5283             if (!env.cssLoad && ua.gecko) {
       
  5284                 // In Firefox <9, we can import the requested URL into a <style>
       
  5285                 // node and poll for the existence of node.sheet.cssRules. This
       
  5286                 // gives us a reliable way to determine CSS load completion that
       
  5287                 // also works for cross-domain stylesheets.
       
  5288                 //
       
  5289                 // Props to Zach Leatherman for calling my attention to this
       
  5290                 // technique.
       
  5291                 node.innerHTML = (req.attributes.charset ?
       
  5292                     '@charset "' + req.attributes.charset + '";' : '') +
       
  5293                     '@import "' + req.url + '";';
       
  5294             } else {
       
  5295                 node.setAttribute('href', req.url);
       
  5296             }
       
  5297         }
       
  5298 
       
  5299         // Inject the node.
       
  5300         if (isScript && ua.ie && (ua.ie < 9 || (document.documentMode && document.documentMode < 9))) {
       
  5301             // Script on IE < 9, and IE 9+ when in IE 8 or older modes, including quirks mode.
       
  5302             node.onreadystatechange = function () {
       
  5303                 if (/loaded|complete/.test(node.readyState)) {
       
  5304                     node.onreadystatechange = null;
       
  5305                     onLoad();
       
  5306                 }
       
  5307             };
       
  5308         } else if (!isScript && !env.cssLoad) {
       
  5309             // CSS on Firefox <9 or WebKit.
       
  5310             this._poll(req);
       
  5311         } else {
       
  5312             // Script or CSS on everything else. Using DOM 0 events because that
       
  5313             // evens the playing field with older IEs.
       
  5314 
       
  5315             if (ua.ie >= 10) {
       
  5316 
       
  5317                 // We currently need to introduce a timeout for IE10, since it
       
  5318                 // calls onerror/onload synchronously for 304s - messing up existing
       
  5319                 // program flow.
       
  5320 
       
  5321                 // Remove this block if the following bug gets fixed by GA
       
  5322                 /*jshint maxlen: 1500 */
       
  5323                 // https://connect.microsoft.com/IE/feedback/details/763871/dynamically-loaded-scripts-with-304s-responses-interrupt-the-currently-executing-js-thread-onload
       
  5324                 node.onerror = function() { setTimeout(onError, 0); };
       
  5325                 node.onload  = function() { setTimeout(onLoad, 0); };
       
  5326             } else {
       
  5327                 node.onerror = onError;
       
  5328                 node.onload  = onLoad;
       
  5329             }
       
  5330 
       
  5331             // If this browser doesn't fire an event when CSS fails to load,
       
  5332             // fail after a timeout to avoid blocking the transaction queue.
       
  5333             if (!env.cssFail && !isScript) {
       
  5334                 cssTimeout = setTimeout(onError, req.timeout || 3000);
       
  5335             }
       
  5336         }
       
  5337 
       
  5338         this.nodes.push(node);
       
  5339         insertBefore.parentNode.insertBefore(node, insertBefore);
       
  5340     },
       
  5341 
       
  5342     _next: function () {
       
  5343         if (this._pending) {
       
  5344             return;
       
  5345         }
       
  5346 
       
  5347         // If there are requests in the queue, insert the next queued request.
       
  5348         // Otherwise, if we're waiting on already-inserted requests to finish,
       
  5349         // wait longer. If there are no queued requests and we're not waiting
       
  5350         // for anything to load, then we're done!
       
  5351         if (this._queue.length) {
       
  5352             this._insert(this._queue.shift());
       
  5353         } else if (!this._reqsWaiting) {
       
  5354             this._finish();
       
  5355         }
       
  5356     },
       
  5357 
       
  5358     _poll: function (newReq) {
       
  5359         var self       = this,
       
  5360             pendingCSS = self._pendingCSS,
       
  5361             isWebKit   = Y.UA.webkit,
       
  5362             i, hasRules, j, nodeHref, req, sheets;
       
  5363 
       
  5364         if (newReq) {
       
  5365             pendingCSS || (pendingCSS = self._pendingCSS = []);
       
  5366             pendingCSS.push(newReq);
       
  5367 
       
  5368             if (self._pollTimer) {
       
  5369                 // A poll timeout is already pending, so no need to create a
       
  5370                 // new one.
       
  5371                 return;
       
  5372             }
       
  5373         }
       
  5374 
       
  5375         self._pollTimer = null;
       
  5376 
       
  5377         // Note: in both the WebKit and Gecko hacks below, a CSS URL that 404s
       
  5378         // will still be treated as a success. There's no good workaround for
       
  5379         // this.
       
  5380 
       
  5381         for (i = 0; i < pendingCSS.length; ++i) {
       
  5382             req = pendingCSS[i];
       
  5383 
       
  5384             if (isWebKit) {
       
  5385                 // Look for a stylesheet matching the pending URL.
       
  5386                 sheets   = req.doc.styleSheets;
       
  5387                 j        = sheets.length;
       
  5388                 nodeHref = req.node.href;
       
  5389 
       
  5390                 while (--j >= 0) {
       
  5391                     if (sheets[j].href === nodeHref) {
       
  5392                         pendingCSS.splice(i, 1);
       
  5393                         i -= 1;
       
  5394                         self._progress(null, req);
       
  5395                         break;
       
  5396                     }
       
  5397                 }
       
  5398             } else {
       
  5399                 // Many thanks to Zach Leatherman for calling my attention to
       
  5400                 // the @import-based cross-domain technique used here, and to
       
  5401                 // Oleg Slobodskoi for an earlier same-domain implementation.
       
  5402                 //
       
  5403                 // See Zach's blog for more details:
       
  5404                 // http://www.zachleat.com/web/2010/07/29/load-css-dynamically/
       
  5405                 try {
       
  5406                     // We don't really need to store this value since we never
       
  5407                     // use it again, but if we don't store it, Closure Compiler
       
  5408                     // assumes the code is useless and removes it.
       
  5409                     hasRules = !!req.node.sheet.cssRules;
       
  5410 
       
  5411                     // If we get here, the stylesheet has loaded.
       
  5412                     pendingCSS.splice(i, 1);
       
  5413                     i -= 1;
       
  5414                     self._progress(null, req);
       
  5415                 } catch (ex) {
       
  5416                     // An exception means the stylesheet is still loading.
       
  5417                 }
       
  5418             }
       
  5419         }
       
  5420 
       
  5421         if (pendingCSS.length) {
       
  5422             self._pollTimer = setTimeout(function () {
       
  5423                 self._poll.call(self);
       
  5424             }, self.options.pollInterval);
       
  5425         }
       
  5426     },
       
  5427 
       
  5428     _progress: function (err, req) {
       
  5429         var options = this.options;
       
  5430 
       
  5431         if (err) {
       
  5432             req.error = err;
       
  5433 
       
  5434             this.errors.push({
       
  5435                 error  : err,
       
  5436                 request: req
       
  5437             });
       
  5438 
       
  5439             Y.log(err, 'error', 'get');
       
  5440         }
       
  5441 
       
  5442         req.node._yuiget_finished = req.finished = true;
       
  5443 
       
  5444         if (options.onProgress) {
       
  5445             options.onProgress.call(options.context || this,
       
  5446                 this._getEventData(req));
       
  5447         }
       
  5448 
       
  5449         if (req.autopurge) {
       
  5450             // Pre-3.5.0 Get always excludes the most recent node from an
       
  5451             // autopurge. I find this odd, but I'm keeping that behavior for
       
  5452             // the sake of backcompat.
       
  5453             Get._autoPurge(this.options.purgethreshold);
       
  5454             Get._purgeNodes.push(req.node);
       
  5455         }
       
  5456 
       
  5457         if (this._pending === req) {
       
  5458             this._pending = null;
       
  5459         }
       
  5460 
       
  5461         this._reqsWaiting -= 1;
       
  5462 
       
  5463         this._next();
       
  5464     }
       
  5465 };
       
  5466 
       
  5467 
       
  5468 }, '@VERSION@', {"requires": ["yui-base"]});
       
  5469 YUI.add('features', function (Y, NAME) {
       
  5470 
       
  5471 var feature_tests = {};
       
  5472 
       
  5473 /**
       
  5474 Contains the core of YUI's feature test architecture.
       
  5475 @module features
       
  5476 */
       
  5477 
       
  5478 /**
       
  5479 * Feature detection
       
  5480 * @class Features
       
  5481 * @static
       
  5482 */
       
  5483 
       
  5484 Y.mix(Y.namespace('Features'), {
       
  5485 
       
  5486     /**
       
  5487     * Object hash of all registered feature tests
       
  5488     * @property tests
       
  5489     * @type Object
       
  5490     */
       
  5491     tests: feature_tests,
       
  5492 
       
  5493     /**
       
  5494     * Add a test to the system
       
  5495     *
       
  5496     *   ```
       
  5497     *   Y.Features.add("load", "1", {});
       
  5498     *   ```
       
  5499     *
       
  5500     * @method add
       
  5501     * @param {String} cat The category, right now only 'load' is supported
       
  5502     * @param {String} name The number sequence of the test, how it's reported in the URL or config: 1, 2, 3
       
  5503     * @param {Object} o Object containing test properties
       
  5504     * @param {String} o.name The name of the test
       
  5505     * @param {Function} o.test The test function to execute, the only argument to the function is the `Y` instance
       
  5506     * @param {String} o.trigger The module that triggers this test.
       
  5507     */
       
  5508     add: function(cat, name, o) {
       
  5509         feature_tests[cat] = feature_tests[cat] || {};
       
  5510         feature_tests[cat][name] = o;
       
  5511     },
       
  5512     /**
       
  5513     * Execute all tests of a given category and return the serialized results
       
  5514     *
       
  5515     *   ```
       
  5516     *   caps=1:1;2:1;3:0
       
  5517     *   ```
       
  5518     * @method all
       
  5519     * @param {String} cat The category to execute
       
  5520     * @param {Array} args The arguments to pass to the test function
       
  5521     * @return {String} A semi-colon separated string of tests and their success/failure: 1:1;2:1;3:0
       
  5522     */
       
  5523     all: function(cat, args) {
       
  5524         var cat_o = feature_tests[cat],
       
  5525             // results = {};
       
  5526             result = [];
       
  5527         if (cat_o) {
       
  5528             Y.Object.each(cat_o, function(v, k) {
       
  5529                 result.push(k + ':' + (Y.Features.test(cat, k, args) ? 1 : 0));
       
  5530             });
       
  5531         }
       
  5532 
       
  5533         return (result.length) ? result.join(';') : '';
       
  5534     },
       
  5535     /**
       
  5536     * Run a sepecific test and return a Boolean response.
       
  5537     *
       
  5538     *   ```
       
  5539     *   Y.Features.test("load", "1");
       
  5540     *   ```
       
  5541     *
       
  5542     * @method test
       
  5543     * @param {String} cat The category of the test to run
       
  5544     * @param {String} name The name of the test to run
       
  5545     * @param {Array} args The arguments to pass to the test function
       
  5546     * @return {Boolean} True or false if the test passed/failed.
       
  5547     */
       
  5548     test: function(cat, name, args) {
       
  5549         args = args || [];
       
  5550         var result, ua, test,
       
  5551             cat_o = feature_tests[cat],
       
  5552             feature = cat_o && cat_o[name];
       
  5553 
       
  5554         if (!feature) {
       
  5555             Y.log('Feature test ' + cat + ', ' + name + ' not found');
       
  5556         } else {
       
  5557 
       
  5558             result = feature.result;
       
  5559 
       
  5560             if (Y.Lang.isUndefined(result)) {
       
  5561 
       
  5562                 ua = feature.ua;
       
  5563                 if (ua) {
       
  5564                     result = (Y.UA[ua]);
       
  5565                 }
       
  5566 
       
  5567                 test = feature.test;
       
  5568                 if (test && ((!ua) || result)) {
       
  5569                     result = test.apply(Y, args);
       
  5570                 }
       
  5571 
       
  5572                 feature.result = result;
       
  5573             }
       
  5574         }
       
  5575 
       
  5576         return result;
       
  5577     }
       
  5578 });
       
  5579 
       
  5580 // Y.Features.add("load", "1", {});
       
  5581 // Y.Features.test("load", "1");
       
  5582 // caps=1:1;2:0;3:1;
       
  5583 
       
  5584 /* This file is auto-generated by (yogi loader --yes --mix --start ../) */
       
  5585 /*jshint maxlen:900, eqeqeq: false */
       
  5586 var add = Y.Features.add;
       
  5587 // app-transitions-native
       
  5588 add('load', '0', {
       
  5589     "name": "app-transitions-native",
       
  5590     "test": function (Y) {
       
  5591     var doc  = Y.config.doc,
       
  5592         node = doc ? doc.documentElement : null;
       
  5593 
       
  5594     if (node && node.style) {
       
  5595         return ('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
       
  5596     }
       
  5597 
       
  5598     return false;
       
  5599 },
       
  5600     "trigger": "app-transitions"
       
  5601 });
       
  5602 // autocomplete-list-keys
       
  5603 add('load', '1', {
       
  5604     "name": "autocomplete-list-keys",
       
  5605     "test": function (Y) {
       
  5606     // Only add keyboard support to autocomplete-list if this doesn't appear to
       
  5607     // be an iOS or Android-based mobile device.
       
  5608     //
       
  5609     // There's currently no feasible way to actually detect whether a device has
       
  5610     // a hardware keyboard, so this sniff will have to do. It can easily be
       
  5611     // overridden by manually loading the autocomplete-list-keys module.
       
  5612     //
       
  5613     // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari
       
  5614     // doesn't fire the keyboard events used by AutoCompleteList, so there's
       
  5615     // no point loading the -keys module even when a bluetooth keyboard may be
       
  5616     // available.
       
  5617     return !(Y.UA.ios || Y.UA.android);
       
  5618 },
       
  5619     "trigger": "autocomplete-list"
       
  5620 });
       
  5621 // dd-gestures
       
  5622 add('load', '2', {
       
  5623     "name": "dd-gestures",
       
  5624     "trigger": "dd-drag",
       
  5625     "ua": "touchEnabled"
       
  5626 });
       
  5627 // dom-style-ie
       
  5628 add('load', '3', {
       
  5629     "name": "dom-style-ie",
       
  5630     "test": function (Y) {
       
  5631 
       
  5632     var testFeature = Y.Features.test,
       
  5633         addFeature = Y.Features.add,
       
  5634         WINDOW = Y.config.win,
       
  5635         DOCUMENT = Y.config.doc,
       
  5636         DOCUMENT_ELEMENT = 'documentElement',
       
  5637         ret = false;
       
  5638 
       
  5639     addFeature('style', 'computedStyle', {
       
  5640         test: function() {
       
  5641             return WINDOW && 'getComputedStyle' in WINDOW;
       
  5642         }
       
  5643     });
       
  5644 
       
  5645     addFeature('style', 'opacity', {
       
  5646         test: function() {
       
  5647             return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style;
       
  5648         }
       
  5649     });
       
  5650 
       
  5651     ret =  (!testFeature('style', 'opacity') &&
       
  5652             !testFeature('style', 'computedStyle'));
       
  5653 
       
  5654     return ret;
       
  5655 },
       
  5656     "trigger": "dom-style"
       
  5657 });
       
  5658 // editor-para-ie
       
  5659 add('load', '4', {
       
  5660     "name": "editor-para-ie",
       
  5661     "trigger": "editor-para",
       
  5662     "ua": "ie",
       
  5663     "when": "instead"
       
  5664 });
       
  5665 // event-base-ie
       
  5666 add('load', '5', {
       
  5667     "name": "event-base-ie",
       
  5668     "test": function(Y) {
       
  5669     var imp = Y.config.doc && Y.config.doc.implementation;
       
  5670     return (imp && (!imp.hasFeature('Events', '2.0')));
       
  5671 },
       
  5672     "trigger": "node-base"
       
  5673 });
       
  5674 // graphics-canvas
       
  5675 add('load', '6', {
       
  5676     "name": "graphics-canvas",
       
  5677     "test": function(Y) {
       
  5678     var DOCUMENT = Y.config.doc,
       
  5679         useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
       
  5680 		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
       
  5681         svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
       
  5682     return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
       
  5683 },
       
  5684     "trigger": "graphics"
       
  5685 });
       
  5686 // graphics-canvas-default
       
  5687 add('load', '7', {
       
  5688     "name": "graphics-canvas-default",
       
  5689     "test": function(Y) {
       
  5690     var DOCUMENT = Y.config.doc,
       
  5691         useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
       
  5692 		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
       
  5693         svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
       
  5694     return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
       
  5695 },
       
  5696     "trigger": "graphics"
       
  5697 });
       
  5698 // graphics-svg
       
  5699 add('load', '8', {
       
  5700     "name": "graphics-svg",
       
  5701     "test": function(Y) {
       
  5702     var DOCUMENT = Y.config.doc,
       
  5703         useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
       
  5704 		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
       
  5705         svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
       
  5706     
       
  5707     return svg && (useSVG || !canvas);
       
  5708 },
       
  5709     "trigger": "graphics"
       
  5710 });
       
  5711 // graphics-svg-default
       
  5712 add('load', '9', {
       
  5713     "name": "graphics-svg-default",
       
  5714     "test": function(Y) {
       
  5715     var DOCUMENT = Y.config.doc,
       
  5716         useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
       
  5717 		canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
       
  5718         svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
       
  5719     
       
  5720     return svg && (useSVG || !canvas);
       
  5721 },
       
  5722     "trigger": "graphics"
       
  5723 });
       
  5724 // graphics-vml
       
  5725 add('load', '10', {
       
  5726     "name": "graphics-vml",
       
  5727     "test": function(Y) {
       
  5728     var DOCUMENT = Y.config.doc,
       
  5729 		canvas = DOCUMENT && DOCUMENT.createElement("canvas");
       
  5730     return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
       
  5731 },
       
  5732     "trigger": "graphics"
       
  5733 });
       
  5734 // graphics-vml-default
       
  5735 add('load', '11', {
       
  5736     "name": "graphics-vml-default",
       
  5737     "test": function(Y) {
       
  5738     var DOCUMENT = Y.config.doc,
       
  5739 		canvas = DOCUMENT && DOCUMENT.createElement("canvas");
       
  5740     return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
       
  5741 },
       
  5742     "trigger": "graphics"
       
  5743 });
       
  5744 // history-hash-ie
       
  5745 add('load', '12', {
       
  5746     "name": "history-hash-ie",
       
  5747     "test": function (Y) {
       
  5748     var docMode = Y.config.doc && Y.config.doc.documentMode;
       
  5749 
       
  5750     return Y.UA.ie && (!('onhashchange' in Y.config.win) ||
       
  5751             !docMode || docMode < 8);
       
  5752 },
       
  5753     "trigger": "history-hash"
       
  5754 });
       
  5755 // io-nodejs
       
  5756 add('load', '13', {
       
  5757     "name": "io-nodejs",
       
  5758     "trigger": "io-base",
       
  5759     "ua": "nodejs"
       
  5760 });
       
  5761 // json-parse-shim
       
  5762 add('load', '14', {
       
  5763     "name": "json-parse-shim",
       
  5764     "test": function (Y) {
       
  5765     var _JSON = Y.config.global.JSON,
       
  5766         Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
       
  5767         nativeSupport = Y.config.useNativeJSONParse !== false && !!Native;
       
  5768 
       
  5769     function workingNative( k, v ) {
       
  5770         return k === "ok" ? true : v;
       
  5771     }
       
  5772     
       
  5773     // Double check basic functionality.  This is mainly to catch early broken
       
  5774     // implementations of the JSON API in Firefox 3.1 beta1 and beta2
       
  5775     if ( nativeSupport ) {
       
  5776         try {
       
  5777             nativeSupport = ( Native.parse( '{"ok":false}', workingNative ) ).ok;
       
  5778         }
       
  5779         catch ( e ) {
       
  5780             nativeSupport = false;
       
  5781         }
       
  5782     }
       
  5783 
       
  5784     return !nativeSupport;
       
  5785 },
       
  5786     "trigger": "json-parse"
       
  5787 });
       
  5788 // json-stringify-shim
       
  5789 add('load', '15', {
       
  5790     "name": "json-stringify-shim",
       
  5791     "test": function (Y) {
       
  5792     var _JSON = Y.config.global.JSON,
       
  5793         Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
       
  5794         nativeSupport = Y.config.useNativeJSONStringify !== false && !!Native;
       
  5795 
       
  5796     // Double check basic native functionality.  This is primarily to catch broken
       
  5797     // early JSON API implementations in Firefox 3.1 beta1 and beta2.
       
  5798     if ( nativeSupport ) {
       
  5799         try {
       
  5800             nativeSupport = ( '0' === Native.stringify(0) );
       
  5801         } catch ( e ) {
       
  5802             nativeSupport = false;
       
  5803         }
       
  5804     }
       
  5805 
       
  5806 
       
  5807     return !nativeSupport;
       
  5808 },
       
  5809     "trigger": "json-stringify"
       
  5810 });
       
  5811 // scrollview-base-ie
       
  5812 add('load', '16', {
       
  5813     "name": "scrollview-base-ie",
       
  5814     "trigger": "scrollview-base",
       
  5815     "ua": "ie"
       
  5816 });
       
  5817 // selector-css2
       
  5818 add('load', '17', {
       
  5819     "name": "selector-css2",
       
  5820     "test": function (Y) {
       
  5821     var DOCUMENT = Y.config.doc,
       
  5822         ret = DOCUMENT && !('querySelectorAll' in DOCUMENT);
       
  5823 
       
  5824     return ret;
       
  5825 },
       
  5826     "trigger": "selector"
       
  5827 });
       
  5828 // transition-timer
       
  5829 add('load', '18', {
       
  5830     "name": "transition-timer",
       
  5831     "test": function (Y) {
       
  5832     var DOCUMENT = Y.config.doc,
       
  5833         node = (DOCUMENT) ? DOCUMENT.documentElement: null,
       
  5834         ret = true;
       
  5835 
       
  5836     if (node && node.style) {
       
  5837         ret = !('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
       
  5838     }
       
  5839 
       
  5840     return ret;
       
  5841 },
       
  5842     "trigger": "transition"
       
  5843 });
       
  5844 // widget-base-ie
       
  5845 add('load', '19', {
       
  5846     "name": "widget-base-ie",
       
  5847     "trigger": "widget-base",
       
  5848     "ua": "ie"
       
  5849 });
       
  5850 // yql-jsonp
       
  5851 add('load', '20', {
       
  5852     "name": "yql-jsonp",
       
  5853     "test": function (Y) {
       
  5854     /* Only load the JSONP module when not in nodejs or winjs
       
  5855     TODO Make the winjs module a CORS module
       
  5856     */
       
  5857     return (!Y.UA.nodejs && !Y.UA.winjs);
       
  5858 },
       
  5859     "trigger": "yql",
       
  5860     "when": "after"
       
  5861 });
       
  5862 // yql-nodejs
       
  5863 add('load', '21', {
       
  5864     "name": "yql-nodejs",
       
  5865     "trigger": "yql",
       
  5866     "ua": "nodejs",
       
  5867     "when": "after"
       
  5868 });
       
  5869 // yql-winjs
       
  5870 add('load', '22', {
       
  5871     "name": "yql-winjs",
       
  5872     "trigger": "yql",
       
  5873     "ua": "winjs",
       
  5874     "when": "after"
       
  5875 });
       
  5876 
       
  5877 }, '@VERSION@', {"requires": ["yui-base"]});
       
  5878 YUI.add('intl-base', function (Y, NAME) {
       
  5879 
       
  5880 /**
       
  5881  * The Intl utility provides a central location for managing sets of
       
  5882  * localized resources (strings and formatting patterns).
       
  5883  *
       
  5884  * @class Intl
       
  5885  * @uses EventTarget
       
  5886  * @static
       
  5887  */
       
  5888 
       
  5889 var SPLIT_REGEX = /[, ]/;
       
  5890 
       
  5891 Y.mix(Y.namespace('Intl'), {
       
  5892 
       
  5893  /**
       
  5894     * Returns the language among those available that
       
  5895     * best matches the preferred language list, using the Lookup
       
  5896     * algorithm of BCP 47.
       
  5897     * If none of the available languages meets the user's preferences,
       
  5898     * then "" is returned.
       
  5899     * Extended language ranges are not supported.
       
  5900     *
       
  5901     * @method lookupBestLang
       
  5902     * @param {String[] | String} preferredLanguages The list of preferred
       
  5903     * languages in descending preference order, represented as BCP 47
       
  5904     * language tags. A string array or a comma-separated list.
       
  5905     * @param {String[]} availableLanguages The list of languages
       
  5906     * that the application supports, represented as BCP 47 language
       
  5907     * tags.
       
  5908     *
       
  5909     * @return {String} The available language that best matches the
       
  5910     * preferred language list, or "".
       
  5911     * @since 3.1.0
       
  5912     */
       
  5913     lookupBestLang: function(preferredLanguages, availableLanguages) {
       
  5914 
       
  5915         var i, language, result, index;
       
  5916 
       
  5917         // check whether the list of available languages contains language;
       
  5918         // if so return it
       
  5919         function scan(language) {
       
  5920             var i;
       
  5921             for (i = 0; i < availableLanguages.length; i += 1) {
       
  5922                 if (language.toLowerCase() ===
       
  5923                             availableLanguages[i].toLowerCase()) {
       
  5924                     return availableLanguages[i];
       
  5925                 }
       
  5926             }
       
  5927         }
       
  5928 
       
  5929         if (Y.Lang.isString(preferredLanguages)) {
       
  5930             preferredLanguages = preferredLanguages.split(SPLIT_REGEX);
       
  5931         }
       
  5932 
       
  5933         for (i = 0; i < preferredLanguages.length; i += 1) {
       
  5934             language = preferredLanguages[i];
       
  5935             if (!language || language === '*') {
       
  5936                 continue;
       
  5937             }
       
  5938             // check the fallback sequence for one language
       
  5939             while (language.length > 0) {
       
  5940                 result = scan(language);
       
  5941                 if (result) {
       
  5942                     return result;
       
  5943                 } else {
       
  5944                     index = language.lastIndexOf('-');
       
  5945                     if (index >= 0) {
       
  5946                         language = language.substring(0, index);
       
  5947                         // one-character subtags get cut along with the
       
  5948                         // following subtag
       
  5949                         if (index >= 2 && language.charAt(index - 2) === '-') {
       
  5950                             language = language.substring(0, index - 2);
       
  5951                         }
       
  5952                     } else {
       
  5953                         // nothing available for this language
       
  5954                         break;
       
  5955                     }
       
  5956                 }
       
  5957             }
       
  5958         }
       
  5959 
       
  5960         return '';
       
  5961     }
       
  5962 });
       
  5963 
       
  5964 
       
  5965 }, '@VERSION@', {"requires": ["yui-base"]});
       
  5966 YUI.add('yui-log', function (Y, NAME) {
       
  5967 
       
  5968 /**
       
  5969  * Provides console log capability and exposes a custom event for
       
  5970  * console implementations. This module is a `core` YUI module,
       
  5971  * <a href="../classes/YUI.html#method_log">it's documentation is located under the YUI class</a>.
       
  5972  *
       
  5973  * @module yui
       
  5974  * @submodule yui-log
       
  5975  */
       
  5976 
       
  5977 var INSTANCE = Y,
       
  5978     LOGEVENT = 'yui:log',
       
  5979     UNDEFINED = 'undefined',
       
  5980     LEVELS = { debug: 1,
       
  5981                info: 2,
       
  5982                warn: 4,
       
  5983                error: 8 };
       
  5984 
       
  5985 /**
       
  5986  * If the 'debug' config is true, a 'yui:log' event will be
       
  5987  * dispatched, which the Console widget and anything else
       
  5988  * can consume.  If the 'useBrowserConsole' config is true, it will
       
  5989  * write to the browser console if available.  YUI-specific log
       
  5990  * messages will only be present in the -debug versions of the
       
  5991  * JS files.  The build system is supposed to remove log statements
       
  5992  * from the raw and minified versions of the files.
       
  5993  *
       
  5994  * @method log
       
  5995  * @for YUI
       
  5996  * @param  {String}  msg  The message to log.
       
  5997  * @param  {String}  cat  The log category for the message.  Default
       
  5998  *                        categories are "info", "warn", "error", "debug".
       
  5999  *                        Custom categories can be used as well. (opt).
       
  6000  * @param  {String}  src  The source of the the message (opt).
       
  6001  * @param  {boolean} silent If true, the log event won't fire.
       
  6002  * @return {YUI}      YUI instance.
       
  6003  */
       
  6004 INSTANCE.log = function(msg, cat, src, silent) {
       
  6005     var bail, excl, incl, m, f, minlevel,
       
  6006         Y = INSTANCE,
       
  6007         c = Y.config,
       
  6008         publisher = (Y.fire) ? Y : YUI.Env.globalEvents;
       
  6009     // suppress log message if the config is off or the event stack
       
  6010     // or the event call stack contains a consumer of the yui:log event
       
  6011     if (c.debug) {
       
  6012         // apply source filters
       
  6013         src = src || "";
       
  6014         if (typeof src !== "undefined") {
       
  6015             excl = c.logExclude;
       
  6016             incl = c.logInclude;
       
  6017             if (incl && !(src in incl)) {
       
  6018                 bail = 1;
       
  6019             } else if (incl && (src in incl)) {
       
  6020                 bail = !incl[src];
       
  6021             } else if (excl && (src in excl)) {
       
  6022                 bail = excl[src];
       
  6023             }
       
  6024 
       
  6025             // Set a default category of info if the category was not defined or was not
       
  6026             // a real category.
       
  6027             if ((typeof cat === 'undefined') || !(cat in LEVELS)) {
       
  6028                 cat = 'info';
       
  6029             }
       
  6030 
       
  6031             // Determine the current minlevel as defined in configuration
       
  6032             Y.config.logLevel = Y.config.logLevel || 'debug';
       
  6033             minlevel = LEVELS[Y.config.logLevel.toLowerCase()];
       
  6034 
       
  6035             if (cat in LEVELS && LEVELS[cat] < minlevel) {
       
  6036                 // Skip this message if the we don't meet the defined minlevel
       
  6037                 bail = 1;
       
  6038             }
       
  6039         }
       
  6040         if (!bail) {
       
  6041             if (c.useBrowserConsole) {
       
  6042                 m = (src) ? src + ': ' + msg : msg;
       
  6043                 if (Y.Lang.isFunction(c.logFn)) {
       
  6044                     c.logFn.call(Y, msg, cat, src);
       
  6045                 } else if (typeof console !== UNDEFINED && console.log) {
       
  6046                     f = (cat && console[cat] && (cat in LEVELS)) ? cat : 'log';
       
  6047                     console[f](m);
       
  6048                 } else if (typeof opera !== UNDEFINED) {
       
  6049                     opera.postError(m);
       
  6050                 }
       
  6051             }
       
  6052 
       
  6053             if (publisher && !silent) {
       
  6054 
       
  6055                 if (publisher === Y && (!publisher.getEvent(LOGEVENT))) {
       
  6056                     publisher.publish(LOGEVENT, {
       
  6057                         broadcast: 2
       
  6058                     });
       
  6059                 }
       
  6060 
       
  6061                 publisher.fire(LOGEVENT, {
       
  6062                     msg: msg,
       
  6063                     cat: cat,
       
  6064                     src: src
       
  6065                 });
       
  6066             }
       
  6067         }
       
  6068     }
       
  6069 
       
  6070     return Y;
       
  6071 };
       
  6072 
       
  6073 /**
       
  6074  * Write a system message.  This message will be preserved in the
       
  6075  * minified and raw versions of the YUI files, unlike log statements.
       
  6076  * @method message
       
  6077  * @for YUI
       
  6078  * @param  {String}  msg  The message to log.
       
  6079  * @param  {String}  cat  The log category for the message.  Default
       
  6080  *                        categories are "info", "warn", "error", "debug".
       
  6081  *                        Custom categories can be used as well. (opt).
       
  6082  * @param  {String}  src  The source of the the message (opt).
       
  6083  * @param  {boolean} silent If true, the log event won't fire.
       
  6084  * @return {YUI}      YUI instance.
       
  6085  */
       
  6086 INSTANCE.message = function() {
       
  6087     return INSTANCE.log.apply(INSTANCE, arguments);
       
  6088 };
       
  6089 
       
  6090 
       
  6091 }, '@VERSION@', {"requires": ["yui-base"]});
       
  6092 YUI.add('yui-later', function (Y, NAME) {
       
  6093 
       
  6094 /**
       
  6095  * Provides a setTimeout/setInterval wrapper. This module is a `core` YUI module,
       
  6096  * <a href="../classes/YUI.html#method_later">it's documentation is located under the YUI class</a>.
       
  6097  *
       
  6098  * @module yui
       
  6099  * @submodule yui-later
       
  6100  */
       
  6101 
       
  6102 var NO_ARGS = [];
       
  6103 
       
  6104 /**
       
  6105  * Executes the supplied function in the context of the supplied
       
  6106  * object 'when' milliseconds later.  Executes the function a
       
  6107  * single time unless periodic is set to true.
       
  6108  * @for YUI
       
  6109  * @method later
       
  6110  * @param when {Number} the number of milliseconds to wait until the fn
       
  6111  * is executed.
       
  6112  * @param o the context object.
       
  6113  * @param fn {Function|String} the function to execute or the name of
       
  6114  * the method in the 'o' object to execute.
       
  6115  * @param data [Array] data that is provided to the function.  This
       
  6116  * accepts either a single item or an array.  If an array is provided,
       
  6117  * the function is executed with one parameter for each array item.
       
  6118  * If you need to pass a single array parameter, it needs to be wrapped
       
  6119  * in an array [myarray].
       
  6120  *
       
  6121  * Note: native methods in IE may not have the call and apply methods.
       
  6122  * In this case, it will work, but you are limited to four arguments.
       
  6123  *
       
  6124  * @param periodic {boolean} if true, executes continuously at supplied
       
  6125  * interval until canceled.
       
  6126  * @return {object} a timer object. Call the cancel() method on this
       
  6127  * object to stop the timer.
       
  6128  */
       
  6129 Y.later = function(when, o, fn, data, periodic) {
       
  6130     when = when || 0;
       
  6131     data = (!Y.Lang.isUndefined(data)) ? Y.Array(data) : NO_ARGS;
       
  6132     o = o || Y.config.win || Y;
       
  6133 
       
  6134     var cancelled = false,
       
  6135         method = (o && Y.Lang.isString(fn)) ? o[fn] : fn,
       
  6136         wrapper = function() {
       
  6137             // IE 8- may execute a setInterval callback one last time
       
  6138             // after clearInterval was called, so in order to preserve
       
  6139             // the cancel() === no more runny-run, we have to jump through
       
  6140             // an extra hoop.
       
  6141             if (!cancelled) {
       
  6142                 if (!method.apply) {
       
  6143                     method(data[0], data[1], data[2], data[3]);
       
  6144                 } else {
       
  6145                     method.apply(o, data || NO_ARGS);
       
  6146                 }
       
  6147             }
       
  6148         },
       
  6149         id = (periodic) ? setInterval(wrapper, when) : setTimeout(wrapper, when);
       
  6150 
       
  6151     return {
       
  6152         id: id,
       
  6153         interval: periodic,
       
  6154         cancel: function() {
       
  6155             cancelled = true;
       
  6156             if (this.interval) {
       
  6157                 clearInterval(id);
       
  6158             } else {
       
  6159                 clearTimeout(id);
       
  6160             }
       
  6161         }
       
  6162     };
       
  6163 };
       
  6164 
       
  6165 Y.Lang.later = Y.later;
       
  6166 
       
  6167 
       
  6168 
       
  6169 }, '@VERSION@', {"requires": ["yui-base"]});
       
  6170 YUI.add('yui', function (Y, NAME) {}, '@VERSION@', {"use": ["get", "features", "intl-base", "yui-log", "yui-later"]});