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