[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/yui/ -> yui-debug.js (source)

   1  /*
   2  YUI 3.17.2 (build 9c3c78e)
   3  Copyright 2014 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.17.2',
 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          handleReady = function() {
 206              YUI.Env.DOMReady = true;
 207              if (hasWin) {
 208                  remove(doc, 'DOMContentLoaded', handleReady);
 209              }        
 210          },
 211          handleLoad = function() {
 212              YUI.Env.windowLoaded = true;
 213              YUI.Env.DOMReady = true;
 214              if (hasWin) {
 215                  remove(window, 'load', handleLoad);
 216              }
 217          },
 218          getLoader = function(Y, o) {
 219              var loader = Y.Env._loader,
 220                  lCore = [ 'loader-base' ],
 221                  G_ENV = YUI.Env,
 222                  mods = G_ENV.mods;
 223  
 224              if (loader) {
 225                  //loader._config(Y.config);
 226                  loader.ignoreRegistered = false;
 227                  loader.onEnd = null;
 228                  loader.data = null;
 229                  loader.required = [];
 230                  loader.loadType = null;
 231              } else {
 232                  loader = new Y.Loader(Y.config);
 233                  Y.Env._loader = loader;
 234              }
 235              if (mods && mods.loader) {
 236                  lCore = [].concat(lCore, YUI.Env.loaderExtras);
 237              }
 238              YUI.Env.core = Y.Array.dedupe([].concat(YUI.Env.core, lCore));
 239  
 240              return loader;
 241          },
 242  
 243          clobber = function(r, s) {
 244              for (var i in s) {
 245                  if (s.hasOwnProperty(i)) {
 246                      r[i] = s[i];
 247                  }
 248              }
 249          },
 250  
 251          ALREADY_DONE = { success: true };
 252  
 253  //  Stamp the documentElement (HTML) with a class of "yui-loaded" to
 254  //  enable styles that need to key off of JS being enabled.
 255  if (docEl && docClass.indexOf(DOC_LABEL) == -1) {
 256      if (docClass) {
 257          docClass += ' ';
 258      }
 259      docClass += DOC_LABEL;
 260      docEl.className = docClass;
 261  }
 262  
 263  if (VERSION.indexOf('@') > -1) {
 264      VERSION = '3.5.0'; // dev time hack for cdn test
 265  }
 266  
 267  proto = {
 268      /**
 269      Applies a new configuration object to the config of this YUI instance. This
 270      will merge new group/module definitions, and will also update the loader
 271      cache if necessary. Updating `Y.config` directly will not update the cache.
 272  
 273      @method applyConfig
 274      @param {Object} o the configuration object.
 275      @since 3.2.0
 276      **/
 277      applyConfig: function(o) {
 278  
 279          o = o || NOOP;
 280  
 281          var attr,
 282              name,
 283              // detail,
 284              config = this.config,
 285              mods = config.modules,
 286              groups = config.groups,
 287              aliases = config.aliases,
 288              loader = this.Env._loader;
 289  
 290          for (name in o) {
 291              if (o.hasOwnProperty(name)) {
 292                  attr = o[name];
 293                  if (mods && name == 'modules') {
 294                      clobber(mods, attr);
 295                  } else if (aliases && name == 'aliases') {
 296                      clobber(aliases, attr);
 297                  } else if (groups && name == 'groups') {
 298                      clobber(groups, attr);
 299                  } else if (name == 'win') {
 300                      config[name] = (attr && attr.contentWindow) || attr;
 301                      config.doc = config[name] ? config[name].document : null;
 302                  } else if (name == '_yuid') {
 303                      // preserve the guid
 304                  } else {
 305                      config[name] = attr;
 306                  }
 307              }
 308          }
 309  
 310          if (loader) {
 311              loader._config(o);
 312          }
 313  
 314      },
 315  
 316      /**
 317      Old way to apply a config to this instance (calls `applyConfig` under the
 318      hood).
 319  
 320      @private
 321      @method _config
 322      @param {Object} o The config to apply
 323      **/
 324      _config: function(o) {
 325          this.applyConfig(o);
 326      },
 327  
 328      /**
 329      Initializes this YUI instance.
 330  
 331      @private
 332      @method _init
 333      **/
 334      _init: function() {
 335          var filter, el,
 336              Y = this,
 337              G_ENV = YUI.Env,
 338              Env = Y.Env,
 339              prop;
 340  
 341          /**
 342          The version number of this YUI instance.
 343  
 344          This value is typically updated by a script when a YUI release is built,
 345          so it may not reflect the correct version number when YUI is run from
 346          the development source tree.
 347  
 348          @property {String} version
 349          **/
 350          Y.version = VERSION;
 351  
 352          if (!Env) {
 353              Y.Env = {
 354                  core: ['get', 'features', 'intl-base', 'yui-log', 'yui-later', 'loader-base', 'loader-rollup', 'loader-yui3'],
 355                  loaderExtras: ['loader-rollup', 'loader-yui3'],
 356                  mods: {}, // flat module map
 357                  versions: {}, // version module map
 358                  base: BASE,
 359                  cdn: BASE + VERSION + '/build/',
 360                  // bootstrapped: false,
 361                  _idx: 0,
 362                  _used: {},
 363                  _attached: {},
 364                  _exported: {},
 365                  _missed: [],
 366                  _yidx: 0,
 367                  _uidx: 0,
 368                  _guidp: 'y',
 369                  _loaded: {},
 370                  // serviced: {},
 371                  // Regex in English:
 372                  // I'll start at the \b(yui).
 373                  // 1. Look in the test string for "yui" or
 374                  //    "yui-base" or "yui-davglass" or "yui-foobar" that comes after a word break.  That is, it
 375                  //    can't match "foyui" or "i_heart_yui". This can be anywhere in the string.
 376                  // 2. After #1 must come a forward slash followed by the string matched in #1, so
 377                  //    "yui-base/yui-base" or "yui-pants/yui-pants".
 378                  // 3. The second occurence of the #1 token can optionally be followed by "-debug" or "-min",
 379                  //    so "yui/yui-min", "yui/yui-debug", "yui-base/yui-base-debug". NOT "yui/yui-tshirt".
 380                  // 4. This is followed by ".js", so "yui/yui.js".
 381                  // 0. Going back to the beginning, now. If all that stuff in 1-4 comes after a "?" in the string,
 382                  //    then capture the junk between the LAST "&" and the string in 1-4.  So
 383                  //    "blah?foo/yui/yui.js" will capture "foo/" and "blah?some/thing.js&3.3.0/build/yui-davglass/yui-davglass.js"
 384                  //    will capture "3.3.0/build/"
 385                  //
 386                  // Regex Exploded:
 387                  // (?:\?             Find a ?
 388                  //   (?:[^&]*&)      followed by 0..n characters followed by an &
 389                  //   *               in fact, find as many sets of characters followed by a & as you can
 390                  //   ([^&]*)         capture the stuff after the last & in \1
 391                  // )?                but it's ok if all this ?junk&more_junk stuff isn't even there
 392                  // \b(               after a word break find either the string
 393                  //    yui(?:-\w+)?   "yui" optionally followed by a -, then more characters
 394                  // )                 and store the yui-* string in \2
 395                  // \/\2              then comes a / followed by the yui-* string in \2
 396                  // (?:-(min|debug))? optionally followed by "-min" or "-debug"
 397                  // .js               and ending in ".js"
 398                  _BASE_RE: /(?:\?(?:[^&]*&)*([^&]*))?\b(yui(?:-\w+)?)\/\2(?:-(min|debug))?\.js/,
 399                  parseBasePath: function(src, pattern) {
 400                      var match = src.match(pattern),
 401                          path, filter;
 402  
 403                      if (match) {
 404                          path = RegExp.leftContext || src.slice(0, src.indexOf(match[0]));
 405  
 406                          // this is to set up the path to the loader.  The file
 407                          // filter for loader should match the yui include.
 408                          filter = match[3];
 409  
 410                          // extract correct path for mixed combo urls
 411                          // http://yuilibrary.com/projects/yui3/ticket/2528423
 412                          if (match[1]) {
 413                              path += '?' + match[1];
 414                          }
 415                          path = {
 416                              filter: filter,
 417                              path: path
 418                          };
 419                      }
 420                      return path;
 421                  },
 422                  getBase: G_ENV && G_ENV.getBase ||
 423                          function(pattern) {
 424                              var nodes = (doc && doc.getElementsByTagName('script')) || [],
 425                                  path = Env.cdn, parsed,
 426                                  i, len, src;
 427  
 428                              for (i = 0, len = nodes.length; i < len; ++i) {
 429                                  src = nodes[i].src;
 430                                  if (src) {
 431                                      parsed = Y.Env.parseBasePath(src, pattern);
 432                                      if (parsed) {
 433                                          filter = parsed.filter;
 434                                          path = parsed.path;
 435                                          break;
 436                                      }
 437                                  }
 438                              }
 439  
 440                              // use CDN default
 441                              return path;
 442                          }
 443  
 444              };
 445  
 446              Env = Y.Env;
 447  
 448              Env._loaded[VERSION] = {};
 449  
 450              if (G_ENV && Y !== YUI) {
 451                  Env._yidx = ++G_ENV._yidx;
 452                  Env._guidp = ('yui_' + VERSION + '_' +
 453                               Env._yidx + '_' + time).replace(/[^a-z0-9_]+/g, '_');
 454              } else if (YUI._YUI) {
 455  
 456                  G_ENV = YUI._YUI.Env;
 457                  Env._yidx += G_ENV._yidx;
 458                  Env._uidx += G_ENV._uidx;
 459  
 460                  for (prop in G_ENV) {
 461                      if (!(prop in Env)) {
 462                          Env[prop] = G_ENV[prop];
 463                      }
 464                  }
 465  
 466                  delete YUI._YUI;
 467              }
 468  
 469              Y.id = Y.stamp(Y);
 470              instances[Y.id] = Y;
 471  
 472          }
 473  
 474          Y.constructor = YUI;
 475  
 476          // configuration defaults
 477          Y.config = Y.config || {
 478              bootstrap: true,
 479              cacheUse: true,
 480              debug: true,
 481              doc: doc,
 482              fetchCSS: true,
 483              throwFail: true,
 484              useBrowserConsole: true,
 485              useNativeES5: true,
 486              win: win,
 487              global: Function('return this')()
 488          };
 489  
 490          //Register the CSS stamp element
 491          if (doc && !doc.getElementById(CSS_STAMP_EL)) {
 492              el = doc.createElement('div');
 493              el.innerHTML = '<div id="' + CSS_STAMP_EL + '" style="position: absolute !important; visibility: hidden !important"></div>';
 494              YUI.Env.cssStampEl = el.firstChild;
 495              if (doc.body) {
 496                  doc.body.appendChild(YUI.Env.cssStampEl);
 497              } else {
 498                  docEl.insertBefore(YUI.Env.cssStampEl, docEl.firstChild);
 499              }
 500          } else if (doc && doc.getElementById(CSS_STAMP_EL) && !YUI.Env.cssStampEl) {
 501              YUI.Env.cssStampEl = doc.getElementById(CSS_STAMP_EL);
 502          }
 503  
 504          Y.config.lang = Y.config.lang || 'en-US';
 505  
 506          Y.config.base = YUI.config.base || Y.Env.getBase(Y.Env._BASE_RE);
 507  
 508          if (!filter || (!('mindebug').indexOf(filter))) {
 509              filter = 'min';
 510          }
 511          filter = (filter) ? '-' + filter : filter;
 512          Y.config.loaderPath = YUI.config.loaderPath || 'loader/loader' + filter + '.js';
 513  
 514      },
 515  
 516      /**
 517      Finishes the instance setup. Attaches whatever YUI modules were defined
 518      at the time that this instance was created.
 519  
 520      @method _setup
 521      @private
 522      **/
 523      _setup: function() {
 524          var i, Y = this,
 525              core = [],
 526              mods = YUI.Env.mods,
 527              extras = Y.config.core || [].concat(YUI.Env.core); //Clone it..
 528  
 529          for (i = 0; i < extras.length; i++) {
 530              if (mods[extras[i]]) {
 531                  core.push(extras[i]);
 532              }
 533          }
 534  
 535          Y._attach(['yui-base']);
 536          Y._attach(core);
 537  
 538          if (Y.Loader) {
 539              getLoader(Y);
 540          }
 541  
 542          // Y.log(Y.id + ' initialized', 'info', 'yui');
 543      },
 544  
 545      /**
 546      Executes the named method on the specified YUI instance if that method is
 547      whitelisted.
 548  
 549      @method applyTo
 550      @param {String} id YUI instance id.
 551      @param {String} method Name of the method to execute. For example:
 552          'Object.keys'.
 553      @param {Array} args Arguments to apply to the method.
 554      @return {Mixed} Return value from the applied method, or `null` if the
 555          specified instance was not found or the method was not whitelisted.
 556      **/
 557      applyTo: function(id, method, args) {
 558          if (!(method in APPLY_TO_AUTH)) {
 559              this.log(method + ': applyTo not allowed', 'warn', 'yui');
 560              return null;
 561          }
 562  
 563          var instance = instances[id], nest, m, i;
 564          if (instance) {
 565              nest = method.split('.');
 566              m = instance;
 567              for (i = 0; i < nest.length; i = i + 1) {
 568                  m = m[nest[i]];
 569                  if (!m) {
 570                      this.log('applyTo not found: ' + method, 'warn', 'yui');
 571                  }
 572              }
 573              return m && m.apply(instance, args);
 574          }
 575  
 576          return null;
 577      },
 578  
 579  /**
 580  Registers a YUI module and makes it available for use in a `YUI().use()` call or
 581  as a dependency for other modules.
 582  
 583  The easiest way to create a first-class YUI module is to use
 584  <a href="http://yui.github.com/shifter/">Shifter</a>, the YUI component build
 585  tool.
 586  
 587  Shifter will automatically wrap your module code in a `YUI.add()` call along
 588  with any configuration info required for the module.
 589  
 590  @example
 591  
 592      YUI.add('davglass', function (Y) {
 593          Y.davglass = function () {
 594              Y.log('Dav was here!');
 595          };
 596      }, '3.4.0', {
 597          requires: ['harley-davidson', 'mt-dew']
 598      });
 599  
 600  @method add
 601  @param {String} name Module name.
 602  @param {Function} fn Function containing module code. This function will be
 603      executed whenever the module is attached to a specific YUI instance.
 604  
 605      @param {YUI} fn.Y The YUI instance to which this module is attached.
 606      @param {String} fn.name Name of the module
 607  
 608  @param {String} version Module version number. This is currently used only for
 609      informational purposes, and is not used internally by YUI.
 610  
 611  @param {Object} [details] Module config.
 612      @param {Array} [details.requires] Array of other module names that must be
 613          attached before this module can be attached.
 614      @param {Array} [details.optional] Array of optional module names that should
 615          be attached before this module is attached if they've already been
 616          loaded. If the `loadOptional` YUI option is `true`, optional modules
 617          that have not yet been loaded will be loaded just as if they were hard
 618          requirements.
 619      @param {Array} [details.use] Array of module names that are included within
 620          or otherwise provided by this module, and which should be attached
 621          automatically when this module is attached. This makes it possible to
 622          create "virtual rollup" modules that simply attach a collection of other
 623          modules or submodules.
 624  
 625  @return {YUI} This YUI instance.
 626  **/
 627      add: function(name, fn, version, details) {
 628          details = details || {};
 629          var env = YUI.Env,
 630              mod = {
 631                  name: name,
 632                  fn: fn,
 633                  version: version,
 634                  details: details
 635              },
 636              //Instance hash so we don't apply it to the same instance twice
 637              applied = {},
 638              loader, inst, modInfo,
 639              i, versions = env.versions;
 640  
 641          env.mods[name] = mod;
 642          versions[version] = versions[version] || {};
 643          versions[version][name] = mod;
 644  
 645          for (i in instances) {
 646              if (instances.hasOwnProperty(i)) {
 647                  inst = instances[i];
 648                  if (!applied[inst.id]) {
 649                      applied[inst.id] = true;
 650                      loader = inst.Env._loader;
 651                      if (loader) {
 652                          modInfo = loader.getModuleInfo(name);
 653                          if (!modInfo || modInfo.temp) {
 654                              loader.addModule(details, name);
 655                          }
 656                      }
 657                  }
 658              }
 659          }
 660  
 661          return this;
 662      },
 663  
 664      /**
 665      Executes the callback function associated with each required module,
 666      attaching the module to this YUI instance.
 667  
 668      @method _attach
 669      @param {Array} r The array of modules to attach
 670      @param {Boolean} [moot=false] If `true`, don't throw a warning if the module
 671          is not attached.
 672      @private
 673      **/
 674      _attach: function(r, moot) {
 675          var i, name, mod, details, req, use, after,
 676              mods = YUI.Env.mods,
 677              aliases = YUI.Env.aliases,
 678              Y = this, j,
 679              cache = YUI.Env._renderedMods,
 680              loader = Y.Env._loader,
 681              done = Y.Env._attached,
 682              exported = Y.Env._exported,
 683              len = r.length, loader, def, go,
 684              c = [],
 685              modArgs, esCompat, reqlen, modInfo,
 686              condition,
 687              __exports__, __imports__;
 688  
 689          //Check for conditional modules (in a second+ instance) and add their requirements
 690          //TODO I hate this entire method, it needs to be fixed ASAP (3.5.0) ^davglass
 691          for (i = 0; i < len; i++) {
 692              name = r[i];
 693              mod = mods[name];
 694              c.push(name);
 695              if (loader && loader.conditions[name]) {
 696                  for (j in loader.conditions[name]) {
 697                      if (loader.conditions[name].hasOwnProperty(j)) {
 698                          def = loader.conditions[name][j];
 699                          go = def && ((def.ua && Y.UA[def.ua]) || (def.test && def.test(Y)));
 700                          if (go) {
 701                              c.push(def.name);
 702                          }
 703                      }
 704                  }
 705              }
 706          }
 707          r = c;
 708          len = r.length;
 709  
 710          for (i = 0; i < len; i++) {
 711              if (!done[r[i]]) {
 712                  name = r[i];
 713                  mod = mods[name];
 714  
 715                  if (aliases && aliases[name] && !mod) {
 716                      Y._attach(aliases[name]);
 717                      continue;
 718                  }
 719                  if (!mod) {
 720                      modInfo = loader && loader.getModuleInfo(name);
 721                      if (modInfo) {
 722                          mod = modInfo;
 723                          moot = true;
 724                      }
 725  
 726                      // Y.log('no js def for: ' + name, 'info', 'yui');
 727  
 728                      //if (!loader || !loader.moduleInfo[name]) {
 729                      //if ((!loader || !loader.moduleInfo[name]) && !moot) {
 730                      if (!moot && name) {
 731                          if ((name.indexOf('skin-') === -1) && (name.indexOf('css') === -1)) {
 732                              Y.Env._missed.push(name);
 733                              Y.Env._missed = Y.Array.dedupe(Y.Env._missed);
 734                              Y.message('NOT loaded: ' + name, 'warn', 'yui');
 735                          }
 736                      }
 737                  } else {
 738                      done[name] = true;
 739                      //Don't like this, but in case a mod was asked for once, then we fetch it
 740                      //We need to remove it from the missed list ^davglass
 741                      for (j = 0; j < Y.Env._missed.length; j++) {
 742                          if (Y.Env._missed[j] === name) {
 743                              Y.message('Found: ' + name + ' (was reported as missing earlier)', 'warn', 'yui');
 744                              Y.Env._missed.splice(j, 1);
 745                          }
 746                      }
 747  
 748                      // Optional dependencies normally work by modifying the
 749                      // dependency list of a module. If the dependency's test
 750                      // passes it is added to the list. If not, it's not loaded.
 751                      // This following check ensures that optional dependencies
 752                      // are not attached when they were already loaded into the
 753                      // page (when bundling for example)
 754                      if (loader && !loader._canBeAttached(name)) {
 755                          Y.log('Failed to attach module ' + name, 'warn', 'yui');
 756                          return true;
 757                      }
 758  
 759                      /*
 760                          If it's a temp module, we need to redo it's requirements if it's already loaded
 761                          since it may have been loaded by another instance and it's dependencies might
 762                          have been redefined inside the fetched file.
 763                      */
 764                      if (loader && cache && cache[name] && cache[name].temp) {
 765                          loader.getRequires(cache[name]);
 766                          req = [];
 767                          modInfo = loader.getModuleInfo(name);
 768                          for (j in modInfo.expanded_map) {
 769                              if (modInfo.expanded_map.hasOwnProperty(j)) {
 770                                  req.push(j);
 771                              }
 772                          }
 773                          Y._attach(req);
 774                      }
 775  
 776                      details = mod.details;
 777                      req = details.requires;
 778                      esCompat = details.es;
 779                      use = details.use;
 780                      after = details.after;
 781                      //Force Intl load if there is a language (Loader logic) @todo fix this shit
 782                      if (details.lang) {
 783                          req = req || [];
 784                          req.unshift('intl');
 785                      }
 786  
 787                      if (req) {
 788                          reqlen = req.length;
 789                          for (j = 0; j < reqlen; j++) {
 790                              if (!done[req[j]]) {
 791                                  if (!Y._attach(req)) {
 792                                      return false;
 793                                  }
 794                                  break;
 795                              }
 796                          }
 797                      }
 798  
 799                      if (after) {
 800                          for (j = 0; j < after.length; j++) {
 801                              if (!done[after[j]]) {
 802                                  if (!Y._attach(after, true)) {
 803                                      return false;
 804                                  }
 805                                  break;
 806                              }
 807                          }
 808                      }
 809  
 810                      if (mod.fn) {
 811                          modArgs = [Y, name];
 812                          if (esCompat) {
 813                              __imports__ = {};
 814                              __exports__ = {};
 815                              // passing `exports` and `imports` onto the module function
 816                              modArgs.push(__imports__, __exports__);
 817                              if (req) {
 818                                  reqlen = req.length;
 819                                  for (j = 0; j < reqlen; j++) {
 820                                      __imports__[req[j]] = exported.hasOwnProperty(req[j]) ? exported[req[j]] : Y;
 821                                  }
 822                              }
 823                          }
 824                          if (Y.config.throwFail) {
 825                              __exports__ = mod.fn.apply(esCompat ? undefined : mod, modArgs);
 826                          } else {
 827                              try {
 828                                  __exports__ = mod.fn.apply(esCompat ? undefined : mod, modArgs);
 829                              } catch (e) {
 830                                  Y.error('Attach error: ' + name, e, name);
 831                                  return false;
 832                              }
 833                          }
 834                          if (esCompat) {
 835                              // store the `exports` in case others `es` modules requires it
 836                              exported[name] = __exports__;
 837  
 838                              // If an ES module is conditionally loaded and set
 839                              // to be used "instead" another module, replace the
 840                              // trigger module's content with the conditionally
 841                              // loaded one so the values returned by require()
 842                              // still makes sense
 843                              condition = mod.details.condition;
 844                              if (condition && condition.when === 'instead') {
 845                                  exported[condition.trigger] = __exports__;
 846                              }
 847                          }
 848                      }
 849  
 850                      if (use) {
 851                          for (j = 0; j < use.length; j++) {
 852                              if (!done[use[j]]) {
 853                                  if (!Y._attach(use)) {
 854                                      return false;
 855                                  }
 856                                  break;
 857                              }
 858                          }
 859                      }
 860  
 861  
 862  
 863                  }
 864              }
 865          }
 866  
 867          return true;
 868      },
 869  
 870      /**
 871      Delays the `use` callback until another event has taken place such as
 872      `window.onload`, `domready`, `contentready`, or `available`.
 873  
 874      @private
 875      @method _delayCallback
 876      @param {Function} cb The original `use` callback.
 877      @param {String|Object} until Either an event name ('load', 'domready', etc.)
 878          or an object containing event/args keys for contentready/available.
 879      @return {Function}
 880      **/
 881      _delayCallback: function(cb, until) {
 882  
 883          var Y = this,
 884              mod = ['event-base'];
 885  
 886          until = (Y.Lang.isObject(until) ? until : { event: until });
 887  
 888          if (until.event === 'load') {
 889              mod.push('event-synthetic');
 890          }
 891  
 892          Y.log('Delaying use callback until: ' + until.event, 'info', 'yui');
 893          return function() {
 894              Y.log('Use callback fired, waiting on delay', 'info', 'yui');
 895              var args = arguments;
 896              Y._use(mod, function() {
 897                  Y.log('Delayed use wrapper callback after dependencies', 'info', 'yui');
 898                  Y.on(until.event, function() {
 899                      args[1].delayUntil = until.event;
 900                      Y.log('Delayed use callback done after ' + until.event, 'info', 'yui');
 901                      cb.apply(Y, args);
 902                  }, until.args);
 903              });
 904          };
 905      },
 906  
 907      /**
 908      Attaches one or more modules to this YUI instance. When this is executed,
 909      the requirements of the desired modules are analyzed, and one of several
 910      things can happen:
 911  
 912  
 913        * All required modules have already been loaded, and just need to be
 914          attached to this YUI instance. In this case, the `use()` callback will
 915          be executed synchronously after the modules are attached.
 916  
 917        * One or more modules have not yet been loaded, or the Get utility is not
 918          available, or the `bootstrap` config option is `false`. In this case,
 919          a warning is issued indicating that modules are missing, but all
 920          available modules will still be attached and the `use()` callback will
 921          be executed synchronously.
 922  
 923        * One or more modules are missing and the Loader is not available but the
 924          Get utility is, and `bootstrap` is not `false`. In this case, the Get
 925          utility will be used to load the Loader, and we will then proceed to
 926          the following state:
 927  
 928        * One or more modules are missing and the Loader is available. In this
 929          case, the Loader will be used to resolve the dependency tree for the
 930          missing modules and load them and their dependencies. When the Loader is
 931          finished loading modules, the `use()` callback will be executed
 932          asynchronously.
 933  
 934      @example
 935  
 936          // Loads and attaches dd and its dependencies.
 937          YUI().use('dd', function (Y) {
 938              // ...
 939          });
 940  
 941          // Loads and attaches dd and node as well as all of their dependencies.
 942          YUI().use(['dd', 'node'], function (Y) {
 943              // ...
 944          });
 945  
 946          // Attaches all modules that have already been loaded.
 947          YUI().use('*', function (Y) {
 948              // ...
 949          });
 950  
 951          // Attaches a gallery module.
 952          YUI().use('gallery-yql', function (Y) {
 953              // ...
 954          });
 955  
 956          // Attaches a YUI 2in3 module.
 957          YUI().use('yui2-datatable', function (Y) {
 958              // ...
 959          });
 960  
 961      @method use
 962      @param {String|Array} modules* One or more module names to attach.
 963      @param {Function} [callback] Callback function to be executed once all
 964          specified modules and their dependencies have been attached.
 965      @param {YUI} callback.Y The YUI instance created for this sandbox.
 966      @param {Object} callback.status Object containing `success`, `msg` and
 967          `data` properties.
 968      @chainable
 969      **/
 970      use: function() {
 971          var args = SLICE.call(arguments, 0),
 972              callback = args[args.length - 1],
 973              Y = this,
 974              i = 0,
 975              name,
 976              Env = Y.Env,
 977              provisioned = true;
 978  
 979          // The last argument supplied to use can be a load complete callback
 980          if (Y.Lang.isFunction(callback)) {
 981              args.pop();
 982              if (Y.config.delayUntil) {
 983                  callback = Y._delayCallback(callback, Y.config.delayUntil);
 984              }
 985          } else {
 986              callback = null;
 987          }
 988          if (Y.Lang.isArray(args[0])) {
 989              args = args[0];
 990          }
 991  
 992          if (Y.config.cacheUse) {
 993              while ((name = args[i++])) {
 994                  if (!Env._attached[name]) {
 995                      provisioned = false;
 996                      break;
 997                  }
 998              }
 999  
1000              if (provisioned) {
1001                  if (args.length) {
1002                      Y.log('already provisioned: ' + args, 'info', 'yui');
1003                  }
1004                  Y._notify(callback, ALREADY_DONE, args);
1005                  return Y;
1006              }
1007          }
1008  
1009          if (Y._loading) {
1010              Y._useQueue = Y._useQueue || new Y.Queue();
1011              Y._useQueue.add([args, callback]);
1012          } else {
1013              Y._use(args, function(Y, response) {
1014                  Y._notify(callback, response, args);
1015              });
1016          }
1017  
1018          return Y;
1019      },
1020  
1021      /**
1022      Sugar for loading both legacy and ES6-based YUI modules.
1023  
1024      @method require
1025      @param {String} [modules*] List of module names to import or a single
1026          module name.
1027      @param {Function} callback Callback that gets called once all the modules
1028          were loaded. Each parameter of the callback is the export value of the
1029          corresponding module in the list. If the module is a legacy YUI module,
1030          the YUI instance is used instead of the module exports.
1031      @example
1032      ```
1033      YUI().require(['es6-set'], function (Y, imports) {
1034          var Set = imports.Set,
1035              set = new Set();
1036      });
1037      ```
1038      **/
1039      require: function () {
1040          var args = SLICE.call(arguments),
1041              callback;
1042  
1043          if (typeof args[args.length - 1] === 'function') {
1044              callback = args.pop();
1045  
1046              // only add the callback if one was provided
1047              // YUI().require('foo'); is valid
1048              args.push(function (Y) {
1049                  var i, length = args.length,
1050                      exported = Y.Env._exported,
1051                      __imports__ = {};
1052  
1053                  // Get only the imports requested as arguments
1054                  for (i = 0; i < length; i++) {
1055                      if (exported.hasOwnProperty(args[i])) {
1056                          __imports__[args[i]] = exported[args[i]];
1057                      }
1058                  }
1059  
1060                  // Using `undefined` because:
1061                  // - Using `Y.config.global` would force the value of `this` to be
1062                  //   the global object even in strict mode
1063                  // - Using `Y` goes against the goal of moving away from a shared
1064                  //   object and start thinking in terms of imported and exported
1065                  //   objects
1066                  callback.call(undefined, Y, __imports__);
1067              });
1068          }
1069          // Do not return the Y object. This makes it hard to follow this
1070          // traditional pattern:
1071          //   var Y = YUI().use(...);
1072          // This is a good idea in the light of ES6 modules, to avoid working
1073          // in the global scope.
1074          // This also leaves the door open for returning a promise, once the
1075          // YUI loader is based on the ES6 loader which uses
1076          // loader.import(...).then(...)
1077          this.use.apply(this, args);
1078      },
1079  
1080      /**
1081      Handles Loader notifications about attachment/load errors.
1082  
1083      @method _notify
1084      @param {Function} callback Callback to pass to `Y.config.loadErrorFn`.
1085      @param {Object} response Response returned from Loader.
1086      @param {Array} args Arguments passed from Loader.
1087      @private
1088      **/
1089      _notify: function(callback, response, args) {
1090          if (!response.success && this.config.loadErrorFn) {
1091              this.config.loadErrorFn.call(this, this, callback, response, args);
1092          } else if (callback) {
1093              if (this.Env._missed && this.Env._missed.length) {
1094                  response.msg = 'Missing modules: ' + this.Env._missed.join();
1095                  response.success = false;
1096              }
1097              if (this.config.throwFail) {
1098                  callback(this, response);
1099              } else {
1100                  try {
1101                      callback(this, response);
1102                  } catch (e) {
1103                      this.error('use callback error', e, args);
1104                  }
1105              }
1106          }
1107      },
1108  
1109      /**
1110      Called from the `use` method queue to ensure that only one set of loading
1111      logic is performed at a time.
1112  
1113      @method _use
1114      @param {String} args* One or more modules to attach.
1115      @param {Function} [callback] Function to call once all required modules have
1116          been attached.
1117      @private
1118      **/
1119      _use: function(args, callback) {
1120  
1121          if (!this.Array) {
1122              this._attach(['yui-base']);
1123          }
1124  
1125          var len, loader, handleBoot,
1126              Y = this,
1127              G_ENV = YUI.Env,
1128              mods = G_ENV.mods,
1129              Env = Y.Env,
1130              used = Env._used,
1131              aliases = G_ENV.aliases,
1132              queue = G_ENV._loaderQueue,
1133              firstArg = args[0],
1134              YArray = Y.Array,
1135              config = Y.config,
1136              boot = config.bootstrap,
1137              missing = [],
1138              i,
1139              r = [],
1140              ret = true,
1141              fetchCSS = config.fetchCSS,
1142              process = function(names, skip) {
1143  
1144                  var i = 0, a = [], name, len, m, req, use;
1145  
1146                  if (!names.length) {
1147                      return;
1148                  }
1149  
1150                  if (aliases) {
1151                      len = names.length;
1152                      for (i = 0; i < len; i++) {
1153                          if (aliases[names[i]] && !mods[names[i]]) {
1154                              a = [].concat(a, aliases[names[i]]);
1155                          } else {
1156                              a.push(names[i]);
1157                          }
1158                      }
1159                      names = a;
1160                  }
1161  
1162                  len = names.length;
1163  
1164                  for (i = 0; i < len; i++) {
1165                      name = names[i];
1166                      if (!skip) {
1167                          r.push(name);
1168                      }
1169  
1170                      // only attach a module once
1171                      if (used[name]) {
1172                          continue;
1173                      }
1174  
1175                      m = mods[name];
1176                      req = null;
1177                      use = null;
1178  
1179                      if (m) {
1180                          used[name] = true;
1181                          req = m.details.requires;
1182                          use = m.details.use;
1183                      } else {
1184                          // CSS files don't register themselves, see if it has
1185                          // been loaded
1186                          if (!G_ENV._loaded[VERSION][name]) {
1187                              missing.push(name);
1188                          } else {
1189                              used[name] = true; // probably css
1190                          }
1191                      }
1192  
1193                      // make sure requirements are attached
1194                      if (req && req.length) {
1195                          process(req);
1196                      }
1197  
1198                      // make sure we grab the submodule dependencies too
1199                      if (use && use.length) {
1200                          process(use, 1);
1201                      }
1202                  }
1203  
1204              },
1205  
1206              handleLoader = function(fromLoader) {
1207                  var response = fromLoader || {
1208                          success: true,
1209                          msg: 'not dynamic'
1210                      },
1211                      redo, origMissing,
1212                      ret = true,
1213                      data = response.data;
1214  
1215                  Y._loading = false;
1216  
1217                  if (data) {
1218                      origMissing = missing;
1219                      missing = [];
1220                      r = [];
1221                      process(data);
1222                      redo = missing.length;
1223                      if (redo) {
1224                          if ([].concat(missing).sort().join() ==
1225                                  origMissing.sort().join()) {
1226                              redo = false;
1227                          }
1228                      }
1229                  }
1230  
1231                  if (redo && data) {
1232                      Y._loading = true;
1233                      Y._use(missing, function() {
1234                          Y.log('Nested use callback: ' + data, 'info', 'yui');
1235                          if (Y._attach(data)) {
1236                              Y._notify(callback, response, data);
1237                          }
1238                      });
1239                  } else {
1240                      if (data) {
1241                          // Y.log('attaching from loader: ' + data, 'info', 'yui');
1242                          ret = Y._attach(data);
1243                      }
1244                      if (ret) {
1245                          Y._notify(callback, response, args);
1246                      }
1247                  }
1248  
1249                  if (Y._useQueue && Y._useQueue.size() && !Y._loading) {
1250                      Y._use.apply(Y, Y._useQueue.next());
1251                  }
1252  
1253              };
1254  
1255  // Y.log(Y.id + ': use called: ' + a + ' :: ' + callback, 'info', 'yui');
1256  
1257          // YUI().use('*'); // bind everything available
1258          if (firstArg === '*') {
1259              args = [];
1260              for (i in mods) {
1261                  if (mods.hasOwnProperty(i)) {
1262                      args.push(i);
1263                  }
1264              }
1265              ret = Y._attach(args);
1266              if (ret) {
1267                  handleLoader();
1268              }
1269              return Y;
1270          }
1271  
1272          if ((mods.loader || mods['loader-base']) && !Y.Loader) {
1273              Y.log('Loader was found in meta, but it is not attached. Attaching..', 'info', 'yui');
1274              Y._attach(['loader' + ((!mods.loader) ? '-base' : '')]);
1275          }
1276  
1277          // Y.log('before loader requirements: ' + args, 'info', 'yui');
1278  
1279          // use loader to expand dependencies and sort the
1280          // requirements if it is available.
1281          if (boot && Y.Loader && args.length) {
1282              Y.log('Using loader to expand dependencies', 'info', 'yui');
1283              loader = getLoader(Y);
1284              loader.require(args);
1285              loader.ignoreRegistered = true;
1286              loader._boot = true;
1287              loader.calculate(null, (fetchCSS) ? null : 'js');
1288              args = loader.sorted;
1289              loader._boot = false;
1290          }
1291  
1292          process(args);
1293  
1294          len = missing.length;
1295  
1296  
1297          if (len) {
1298              missing = YArray.dedupe(missing);
1299              len = missing.length;
1300  Y.log('Modules missing: ' + missing + ', ' + missing.length, 'info', 'yui');
1301          }
1302  
1303  
1304          // dynamic load
1305          if (boot && len && Y.Loader) {
1306  // Y.log('Using loader to fetch missing deps: ' + missing, 'info', 'yui');
1307              Y.log('Using Loader', 'info', 'yui');
1308              Y._loading = true;
1309              loader = getLoader(Y);
1310              loader.onEnd = handleLoader;
1311              loader.context = Y;
1312              loader.data = args;
1313              loader.ignoreRegistered = false;
1314              loader.require(missing);
1315              loader.insert(null, (fetchCSS) ? null : 'js');
1316  
1317          } else if (boot && len && Y.Get && !Env.bootstrapped) {
1318  
1319              Y._loading = true;
1320  
1321              handleBoot = function() {
1322                  Y._loading = false;
1323                  queue.running = false;
1324                  Env.bootstrapped = true;
1325                  G_ENV._bootstrapping = false;
1326                  if (Y._attach(['loader'])) {
1327                      Y._use(args, callback);
1328                  }
1329              };
1330  
1331              if (G_ENV._bootstrapping) {
1332  Y.log('Waiting for loader', 'info', 'yui');
1333                  queue.add(handleBoot);
1334              } else {
1335                  G_ENV._bootstrapping = true;
1336  Y.log('Fetching loader: ' + config.base + config.loaderPath, 'info', 'yui');
1337                  Y.Get.script(config.base + config.loaderPath, {
1338                      onEnd: handleBoot
1339                  });
1340              }
1341  
1342          } else {
1343              Y.log('Attaching available dependencies: ' + args, 'info', 'yui');
1344              ret = Y._attach(args);
1345              if (ret) {
1346                  handleLoader();
1347              }
1348          }
1349  
1350          return Y;
1351      },
1352  
1353  
1354      /**
1355      Utility method for safely creating namespaces if they don't already exist.
1356      May be called statically on the YUI global object or as a method on a YUI
1357      instance.
1358  
1359      When called statically, a namespace will be created on the YUI global
1360      object:
1361  
1362          // Create `YUI.your.namespace.here` as nested objects, preserving any
1363          // objects that already exist instead of overwriting them.
1364          YUI.namespace('your.namespace.here');
1365  
1366      When called as a method on a YUI instance, a namespace will be created on
1367      that instance:
1368  
1369          // Creates `Y.property.package`.
1370          Y.namespace('property.package');
1371  
1372      Dots in the input string cause `namespace` to create nested objects for each
1373      token. If any part of the requested namespace already exists, the current
1374      object will be left in place and will not be overwritten. This allows
1375      multiple calls to `namespace` to preserve existing namespaced properties.
1376  
1377      If the first token in the namespace string is "YAHOO", that token is
1378      discarded. This is legacy behavior for backwards compatibility with YUI 2.
1379  
1380      Be careful with namespace tokens. Reserved words may work in some browsers
1381      and not others. For instance, the following will fail in some browsers
1382      because the supported version of JavaScript reserves the word "long":
1383  
1384          Y.namespace('really.long.nested.namespace');
1385  
1386      Note: If you pass multiple arguments to create multiple namespaces, only the
1387      last one created is returned from this function.
1388  
1389      @method namespace
1390      @param {String} namespace* One or more namespaces to create.
1391      @return {Object} Reference to the last namespace object created.
1392      **/
1393      namespace: function() {
1394          var a = arguments, o, i = 0, j, d, arg;
1395  
1396          for (; i < a.length; i++) {
1397              o = this; //Reset base object per argument or it will get reused from the last
1398              arg = a[i];
1399              if (arg.indexOf(PERIOD) > -1) { //Skip this if no "." is present
1400                  d = arg.split(PERIOD);
1401                  for (j = (d[0] == 'YAHOO') ? 1 : 0; j < d.length; j++) {
1402                      o[d[j]] = o[d[j]] || {};
1403                      o = o[d[j]];
1404                  }
1405              } else {
1406                  o[arg] = o[arg] || {};
1407                  o = o[arg]; //Reset base object to the new object so it's returned
1408              }
1409          }
1410          return o;
1411      },
1412  
1413      // this is replaced if the log module is included
1414      log: NOOP,
1415      message: NOOP,
1416      // this is replaced if the dump module is included
1417      dump: function (o) { return ''+o; },
1418  
1419      /**
1420      Reports an error.
1421  
1422      The reporting mechanism is controlled by the `throwFail` configuration
1423      attribute. If `throwFail` is falsy, the message is logged. If `throwFail` is
1424      truthy, a JS exception is thrown.
1425  
1426      If an `errorFn` is specified in the config it must return `true` to indicate
1427      that the exception was handled and keep it from being thrown.
1428  
1429      @method error
1430      @param {String} msg Error message.
1431      @param {Error|String} [e] JavaScript error object or an error string.
1432      @param {String} [src] Source of the error (such as the name of the module in
1433          which the error occurred).
1434      @chainable
1435      **/
1436      error: function(msg, e, src) {
1437          //TODO Add check for window.onerror here
1438  
1439          var Y = this, ret;
1440  
1441          if (Y.config.errorFn) {
1442              ret = Y.config.errorFn.apply(Y, arguments);
1443          }
1444  
1445          if (!ret) {
1446              throw (e || new Error(msg));
1447          } else {
1448              Y.message(msg, 'error', ''+src); // don't scrub this one
1449          }
1450  
1451          return Y;
1452      },
1453  
1454      /**
1455      Generates an id string that is unique among all YUI instances in this
1456      execution context.
1457  
1458      @method guid
1459      @param {String} [pre] Prefix.
1460      @return {String} Unique id.
1461      **/
1462      guid: function(pre) {
1463          var id = this.Env._guidp + '_' + (++this.Env._uidx);
1464          return (pre) ? (pre + id) : id;
1465      },
1466  
1467      /**
1468      Returns a unique id associated with the given object and (if *readOnly* is
1469      falsy) stamps the object with that id so it can be identified in the future.
1470  
1471      Stamping an object involves adding a `_yuid` property to it that contains
1472      the object's id. One exception to this is that in Internet Explorer, DOM
1473      nodes have a `uniqueID` property that contains a browser-generated unique
1474      id, which will be used instead of a YUI-generated id when available.
1475  
1476      @method stamp
1477      @param {Object} o Object to stamp.
1478      @param {Boolean} readOnly If truthy and the given object has not already
1479          been stamped, the object will not be modified and `null` will be
1480          returned.
1481      @return {String} Object's unique id, or `null` if *readOnly* was truthy and
1482          the given object was not already stamped.
1483      **/
1484      stamp: function(o, readOnly) {
1485          var uid;
1486          if (!o) {
1487              return o;
1488          }
1489  
1490          // IE generates its own unique ID for dom nodes
1491          // The uniqueID property of a document node returns a new ID
1492          if (o.uniqueID && o.nodeType && o.nodeType !== 9) {
1493              uid = o.uniqueID;
1494          } else {
1495              uid = (typeof o === 'string') ? o : o._yuid;
1496          }
1497  
1498          if (!uid) {
1499              uid = this.guid();
1500              if (!readOnly) {
1501                  try {
1502                      o._yuid = uid;
1503                  } catch (e) {
1504                      uid = null;
1505                  }
1506              }
1507          }
1508          return uid;
1509      },
1510  
1511      /**
1512      Destroys this YUI instance.
1513  
1514      @method destroy
1515      @since 3.3.0
1516      **/
1517      destroy: function() {
1518          var Y = this;
1519          if (Y.Event) {
1520              Y.Event._unload();
1521          }
1522          delete instances[Y.id];
1523          delete Y.Env;
1524          delete Y.config;
1525      }
1526  
1527      /**
1528      Safe `instanceof` wrapper that works around a memory leak in IE when the
1529      object being tested is `window` or `document`.
1530  
1531      Unless you are testing objects that may be `window` or `document`, you
1532      should use the native `instanceof` operator instead of this method.
1533  
1534      @method instanceOf
1535      @param {Object} o Object to check.
1536      @param {Object} type Class to check against.
1537      @since 3.3.0
1538      **/
1539  };
1540  
1541      YUI.prototype = proto;
1542  
1543      // inheritance utilities are not available yet
1544      for (prop in proto) {
1545          if (proto.hasOwnProperty(prop)) {
1546              YUI[prop] = proto[prop];
1547          }
1548      }
1549  
1550      /**
1551      Applies a configuration to all YUI instances in this execution context.
1552  
1553      The main use case for this method is in "mashups" where several third-party
1554      scripts need to write to a global YUI config, but cannot share a single
1555      centrally-managed config object. This way they can all call
1556      `YUI.applyConfig({})` instead of overwriting the single global config.
1557  
1558      @example
1559  
1560          YUI.applyConfig({
1561              modules: {
1562                  davglass: {
1563                      fullpath: './davglass.js'
1564                  }
1565              }
1566          });
1567  
1568          YUI.applyConfig({
1569              modules: {
1570                  foo: {
1571                      fullpath: './foo.js'
1572                  }
1573              }
1574          });
1575  
1576          YUI().use('davglass', function (Y) {
1577              // Module davglass will be available here.
1578          });
1579  
1580      @method applyConfig
1581      @param {Object} o Configuration object to apply.
1582      @static
1583      @since 3.5.0
1584      **/
1585      YUI.applyConfig = function(o) {
1586          if (!o) {
1587              return;
1588          }
1589          //If there is a GlobalConfig, apply it first to set the defaults
1590          if (YUI.GlobalConfig) {
1591              this.prototype.applyConfig.call(this, YUI.GlobalConfig);
1592          }
1593          //Apply this config to it
1594          this.prototype.applyConfig.call(this, o);
1595          //Reset GlobalConfig to the combined config
1596          YUI.GlobalConfig = this.config;
1597      };
1598  
1599      // set up the environment
1600      YUI._init();
1601  
1602      if (hasWin) {
1603          add(doc, 'DOMContentLoaded', handleReady);
1604  
1605          // add a window load event at load time so we can capture
1606          // the case where it fires before dynamic loading is
1607          // complete.
1608          add(window, 'load', handleLoad);
1609      } else {
1610          handleReady();
1611          handleLoad();
1612      }
1613  
1614      YUI.Env.add = add;
1615      YUI.Env.remove = remove;
1616  
1617      /*global exports*/
1618      // Support the CommonJS method for exporting our single global
1619      if (typeof exports == 'object') {
1620          exports.YUI = YUI;
1621          /**
1622          * Set a method to be called when `Get.script` is called in Node.js
1623          * `Get` will open the file, then pass it's content and it's path
1624          * to this method before attaching it. Commonly used for code coverage
1625          * instrumentation. <strong>Calling this multiple times will only
1626          * attach the last hook method</strong>. This method is only
1627          * available in Node.js.
1628          * @method setLoadHook
1629          * @static
1630          * @param {Function} fn The function to set
1631          * @param {String} fn.data The content of the file
1632          * @param {String} fn.path The file path of the file
1633          */
1634          YUI.setLoadHook = function(fn) {
1635              YUI._getLoadHook = fn;
1636          };
1637          /**
1638          * Load hook for `Y.Get.script` in Node.js, see `YUI.setLoadHook`
1639          * @method _getLoadHook
1640          * @private
1641          * @param {String} data The content of the file
1642          * @param {String} path The file path of the file
1643          */
1644          YUI._getLoadHook = null;
1645      }
1646  
1647      YUI.Env[VERSION] = {};
1648  }());
1649  
1650  
1651  /**
1652  Config object that contains all of the configuration options for
1653  this `YUI` instance.
1654  
1655  This object is supplied by the implementer when instantiating YUI. Some
1656  properties have default values if they are not supplied by the implementer.
1657  
1658  This object should not be updated directly because some values are cached. Use
1659  `applyConfig()` to update the config object on a YUI instance that has already
1660  been configured.
1661  
1662  @class config
1663  @static
1664  **/
1665  
1666  /**
1667  If `true` (the default), YUI will "bootstrap" the YUI Loader and module metadata
1668  if they're needed to load additional dependencies and aren't already available.
1669  
1670  Setting this to `false` will prevent YUI from automatically loading the Loader
1671  and module metadata, so you will need to manually ensure that they're available
1672  or handle dependency resolution yourself.
1673  
1674  @property {Boolean} bootstrap
1675  @default true
1676  **/
1677  
1678  /**
1679  If `true`, `Y.log()` messages will be written to the browser's debug console
1680  when available and when `useBrowserConsole` is also `true`.
1681  
1682  @property {Boolean} debug
1683  @default true
1684  **/
1685  
1686  /**
1687  Log messages to the browser console if `debug` is `true` and the browser has a
1688  supported console.
1689  
1690  @property {Boolean} useBrowserConsole
1691  @default true
1692  **/
1693  
1694  /**
1695  A hash of log sources that should be logged. If specified, only messages from
1696  these sources will be logged. Others will be discarded.
1697  
1698  @property {Object} logInclude
1699  @type object
1700  **/
1701  
1702  /**
1703  A hash of log sources that should be not be logged. If specified, all sources
1704  will be logged *except* those on this list.
1705  
1706  @property {Object} logExclude
1707  **/
1708  
1709  /**
1710  When the YUI seed file is dynamically loaded after the `window.onload` event has
1711  fired, set this to `true` to tell YUI that it shouldn't wait for `window.onload`
1712  to occur.
1713  
1714  This ensures that components that rely on `window.onload` and the `domready`
1715  custom event will work as expected even when YUI is dynamically injected.
1716  
1717  @property {Boolean} injected
1718  @default false
1719  **/
1720  
1721  /**
1722  If `true`, `Y.error()` will generate or re-throw a JavaScript error. Otherwise,
1723  errors are merely logged silently.
1724  
1725  @property {Boolean} throwFail
1726  @default true
1727  **/
1728  
1729  /**
1730  Reference to the global object for this execution context.
1731  
1732  In a browser, this is the current `window` object. In Node.js, this is the
1733  Node.js `global` object.
1734  
1735  @property {Object} global
1736  **/
1737  
1738  /**
1739  The browser window or frame that this YUI instance should operate in.
1740  
1741  When running in Node.js, this property is `undefined`, since there is no
1742  `window` object. Use `global` to get a reference to the global object that will
1743  work in both browsers and Node.js.
1744  
1745  @property {Window} win
1746  **/
1747  
1748  /**
1749  The browser `document` object associated with this YUI instance's `win` object.
1750  
1751  When running in Node.js, this property is `undefined`, since there is no
1752  `document` object.
1753  
1754  @property {Document} doc
1755  **/
1756  
1757  /**
1758  A list of modules that defines the YUI core (overrides the default list).
1759  
1760  @property {Array} core
1761  @type Array
1762  @default ['get', 'features', 'intl-base', 'yui-log', 'yui-later', 'loader-base', 'loader-rollup', 'loader-yui3']
1763  **/
1764  
1765  /**
1766  A list of languages to use in order of preference.
1767  
1768  This list is matched against the list of available languages in modules that the
1769  YUI instance uses to determine the best possible localization of language
1770  sensitive modules.
1771  
1772  Languages are represented using BCP 47 language tags, such as "en-GB" for
1773  English as used in the United Kingdom, or "zh-Hans-CN" for simplified Chinese as
1774  used in China. The list may be provided as a comma-separated string or as an
1775  array.
1776  
1777  @property {String|String[]} lang
1778  **/
1779  
1780  /**
1781  Default date format.
1782  
1783  @property {String} dateFormat
1784  @deprecated Use configuration in `DataType.Date.format()` instead.
1785  **/
1786  
1787  /**
1788  Default locale.
1789  
1790  @property {String} locale
1791  @deprecated Use `config.lang` instead.
1792  **/
1793  
1794  /**
1795  Default generic polling interval in milliseconds.
1796  
1797  @property {Number} pollInterval
1798  @default 20
1799  **/
1800  
1801  /**
1802  The number of dynamic `<script>` nodes to insert by default before automatically
1803  removing them when loading scripts.
1804  
1805  This applies only to script nodes because removing the node will not make the
1806  evaluated script unavailable. Dynamic CSS nodes are not auto purged, because
1807  removing a linked style sheet will also remove the style definitions.
1808  
1809  @property {Number} purgethreshold
1810  @default 20
1811  **/
1812  
1813  /**
1814  Delay in milliseconds to wait after a window `resize` event before firing the
1815  event. If another `resize` event occurs before this delay has elapsed, the
1816  delay will start over to ensure that `resize` events are throttled.
1817  
1818  @property {Number} windowResizeDelay
1819  @default 40
1820  **/
1821  
1822  /**
1823  Base directory for dynamic loading.
1824  
1825  @property {String} base
1826  **/
1827  
1828  /**
1829  Base URL for a dynamic combo handler. This will be used to make combo-handled
1830  module requests if `combine` is set to `true.
1831  
1832  @property {String} comboBase
1833  @default "http://yui.yahooapis.com/combo?"
1834  **/
1835  
1836  /**
1837  Root path to prepend to each module path when creating a combo-handled request.
1838  
1839  This is updated for each YUI release to point to a specific version of the
1840  library; for example: "3.8.0/build/".
1841  
1842  @property {String} root
1843  **/
1844  
1845  /**
1846  Filter to apply to module urls. This filter will modify the default path for all
1847  modules.
1848  
1849  The default path for the YUI library is the minified version of the files (e.g.,
1850  event-min.js). The filter property can be a predefined filter or a custom
1851  filter. The valid predefined filters are:
1852  
1853    - **debug**: Loads debug versions of modules (e.g., event-debug.js).
1854    - **raw**: Loads raw, non-minified versions of modules without debug logging
1855      (e.g., event.js).
1856  
1857  You can also define a custom filter, which must be an object literal containing
1858  a search regular expression and a replacement string:
1859  
1860      myFilter: {
1861          searchExp : "-min\\.js",
1862          replaceStr: "-debug.js"
1863      }
1864  
1865  @property {Object|String} filter
1866  **/
1867  
1868  /**
1869  Skin configuration and customizations.
1870  
1871  @property {Object} skin
1872  @param {String} [skin.defaultSkin='sam'] Default skin name. This skin will be
1873      applied automatically to skinnable components if not overridden by a
1874      component-specific skin name.
1875  @param {String} [skin.base='assets/skins/'] Default base path for a skin,
1876      relative to Loader's `base` path.
1877  @param {Object} [skin.overrides] Component-specific skin name overrides. Specify
1878      a component name as the key and, as the value, a string or array of strings
1879      for a skin or skins that should be loaded for that component instead of the
1880      `defaultSkin`.
1881  **/
1882  
1883  /**
1884  Hash of per-component filter specifications. If specified for a given component,
1885  this overrides the global `filter` config.
1886  
1887  @example
1888      YUI({
1889          modules: {
1890              'foo': './foo.js',
1891              'bar': './bar.js',
1892              'baz': './baz.js'
1893          },
1894          filters: {
1895              'foo': {
1896                  searchExp: '.js',
1897                  replaceStr: '-coverage.js'
1898              }
1899          }
1900      }).use('foo', 'bar', 'baz', function (Y) {
1901          // foo-coverage.js is loaded
1902          // bar.js is loaded
1903          // baz.js is loaded
1904      });
1905  
1906  @property {Object} filters
1907  **/
1908  
1909  /**
1910  If `true`, YUI will use a combo handler to load multiple modules in as few
1911  requests as possible.
1912  
1913  The YUI CDN (which YUI uses by default) supports combo handling, but other
1914  servers may not. If the server from which you're loading YUI does not support
1915  combo handling, set this to `false`.
1916  
1917  Providing a value for the `base` config property will cause `combine` to default
1918  to `false` instead of `true`.
1919  
1920  @property {Boolean} combine
1921  @default true
1922  */
1923  
1924  /**
1925  Array of module names that should never be dynamically loaded.
1926  
1927  @property {String[]} ignore
1928  **/
1929  
1930  /**
1931  Array of module names that should always be loaded when required, even if
1932  already present on the page.
1933  
1934  @property {String[]} force
1935  **/
1936  
1937  /**
1938  DOM element or id that should be used as the insertion point for dynamically
1939  added `<script>` and `<link>` nodes.
1940  
1941  @property {HTMLElement|String} insertBefore
1942  **/
1943  
1944  /**
1945  Object hash containing attributes to add to dynamically added `<script>` nodes.
1946  
1947  @property {Object} jsAttributes
1948  **/
1949  
1950  /**
1951  Object hash containing attributes to add to dynamically added `<link>` nodes.
1952  
1953  @property {Object} cssAttributes
1954  **/
1955  
1956  /**
1957  Timeout in milliseconds before a dynamic JS or CSS request will be considered a
1958  failure. If not set, no timeout will be enforced.
1959  
1960  @property {Number} timeout
1961  **/
1962  
1963  /**
1964  A hash of module definitions to add to the list of available YUI modules. These
1965  modules can then be dynamically loaded via the `use()` method.
1966  
1967  This is a hash in which keys are module names and values are objects containing
1968  module metadata.
1969  
1970  See `Loader.addModule()` for the supported module metadata fields. Also see
1971  `groups`, which provides a way to configure the base and combo spec for a set of
1972  modules.
1973  
1974  @example
1975  
1976      modules: {
1977          mymod1: {
1978              requires: ['node'],
1979              fullpath: '/mymod1/mymod1.js'
1980          },
1981  
1982          mymod2: {
1983              requires: ['mymod1'],
1984              fullpath: '/mymod2/mymod2.js'
1985          },
1986  
1987          mymod3: '/js/mymod3.js',
1988          mycssmod: '/css/mycssmod.css'
1989      }
1990  
1991  @property {Object} modules
1992  **/
1993  
1994  /**
1995  Aliases are dynamic groups of modules that can be used as shortcuts.
1996  
1997  @example
1998  
1999      YUI({
2000          aliases: {
2001              davglass: [ 'node', 'yql', 'dd' ],
2002              mine: [ 'davglass', 'autocomplete']
2003          }
2004      }).use('mine', function (Y) {
2005          // Node, YQL, DD & AutoComplete available here.
2006      });
2007  
2008  @property {Object} aliases
2009  **/
2010  
2011  /**
2012  A hash of module group definitions.
2013  
2014  For each group you can specify a list of modules and the base path and
2015  combo spec to use when dynamically loading the modules.
2016  
2017  @example
2018  
2019      groups: {
2020          yui2: {
2021              // specify whether or not this group has a combo service
2022              combine: true,
2023  
2024              // The comboSeperator to use with this group's combo handler
2025              comboSep: ';',
2026  
2027              // The maxURLLength for this server
2028              maxURLLength: 500,
2029  
2030              // the base path for non-combo paths
2031              base: 'http://yui.yahooapis.com/2.8.0r4/build/',
2032  
2033              // the path to the combo service
2034              comboBase: 'http://yui.yahooapis.com/combo?',
2035  
2036              // a fragment to prepend to the path attribute when
2037              // when building combo urls
2038              root: '2.8.0r4/build/',
2039  
2040              // the module definitions
2041              modules:  {
2042                  yui2_yde: {
2043                      path: "yahoo-dom-event/yahoo-dom-event.js"
2044                  },
2045                  yui2_anim: {
2046                      path: "animation/animation.js",
2047                      requires: ['yui2_yde']
2048                  }
2049              }
2050          }
2051      }
2052  
2053  @property {Object} groups
2054  **/
2055  
2056  /**
2057  Path to the Loader JS file, relative to the `base` path.
2058  
2059  This is used to dynamically bootstrap the Loader when it's needed and isn't yet
2060  available.
2061  
2062  @property {String} loaderPath
2063  @default "loader/loader-min.js"
2064  **/
2065  
2066  /**
2067  If `true`, YUI will attempt to load CSS dependencies and skins. Set this to
2068  `false` to prevent YUI from loading any CSS, or set it to the string `"force"`
2069  to force CSS dependencies to be loaded even if their associated JS modules are
2070  already loaded.
2071  
2072  @property {Boolean|String} fetchCSS
2073  @default true
2074  **/
2075  
2076  /**
2077  Default gallery version used to build gallery module urls.
2078  
2079  @property {String} gallery
2080  @since 3.1.0
2081  **/
2082  
2083  /**
2084  Default YUI 2 version used to build YUI 2 module urls.
2085  
2086  This is used for intrinsic YUI 2 support via the 2in3 project. Also see the
2087  `2in3` config for pulling different revisions of the wrapped YUI 2 modules.
2088  
2089  @property {String} yui2
2090  @default "2.9.0"
2091  @since 3.1.0
2092  **/
2093  
2094  /**
2095  Revision number of YUI 2in3 modules that should be used when loading YUI 2in3.
2096  
2097  @property {String} 2in3
2098  @default "4"
2099  @since 3.1.0
2100  **/
2101  
2102  /**
2103  Alternate console log function that should be used in environments without a
2104  supported native console. This function is executed with the YUI instance as its
2105  `this` object.
2106  
2107  @property {Function} logFn
2108  @since 3.1.0
2109  **/
2110  
2111  /**
2112  The minimum log level to log messages for. Log levels are defined
2113  incrementally. Messages greater than or equal to the level specified will
2114  be shown. All others will be discarded. The order of log levels in
2115  increasing priority is:
2116  
2117      debug
2118      info
2119      warn
2120      error
2121  
2122  @property {String} logLevel
2123  @default 'debug'
2124  @since 3.10.0
2125  **/
2126  
2127  /**
2128  Callback to execute when `Y.error()` is called. It receives the error message
2129  and a JavaScript error object if one was provided.
2130  
2131  This function is executed with the YUI instance as its `this` object.
2132  
2133  Returning `true` from this function will prevent an exception from being thrown.
2134  
2135  @property {Function} errorFn
2136  @param {String} errorFn.msg Error message
2137  @param {Object} [errorFn.err] Error object (if one was provided).
2138  @since 3.2.0
2139  **/
2140  
2141  /**
2142  A callback to execute when Loader fails to load one or more resources.
2143  
2144  This could be because of a script load failure. It could also be because a
2145  module fails to register itself when the `requireRegistration` config is `true`.
2146  
2147  If this function is defined, the `use()` callback will only be called when the
2148  loader succeeds. Otherwise, `use()` will always executes unless there was a
2149  JavaScript error when attaching a module.
2150  
2151  @property {Function} loadErrorFn
2152  @since 3.3.0
2153  **/
2154  
2155  /**
2156  If `true`, Loader will expect all loaded scripts to be first-class YUI modules
2157  that register themselves with the YUI global, and will trigger a failure if a
2158  loaded script does not register a YUI module.
2159  
2160  @property {Boolean} requireRegistration
2161  @default false
2162  @since 3.3.0
2163  **/
2164  
2165  /**
2166  Cache serviced use() requests.
2167  
2168  @property {Boolean} cacheUse
2169  @default true
2170  @since 3.3.0
2171  @deprecated No longer used.
2172  **/
2173  
2174  /**
2175  Whether or not YUI should use native ES5 functionality when available for
2176  features like `Y.Array.each()`, `Y.Object()`, etc.
2177  
2178  When `false`, YUI will always use its own fallback implementations instead of
2179  relying on ES5 functionality, even when ES5 functionality is available.
2180  
2181  @property {Boolean} useNativeES5
2182  @default true
2183  @since 3.5.0
2184  **/
2185  
2186  /**
2187   * Leverage native JSON stringify if the browser has a native
2188   * implementation.  In general, this is a good idea.  See the Known Issues
2189   * section in the JSON user guide for caveats.  The default value is true
2190   * for browsers with native JSON support.
2191   *
2192   * @property useNativeJSONStringify
2193   * @type Boolean
2194   * @default true
2195   * @since 3.8.0
2196   */
2197  
2198   /**
2199   * Leverage native JSON parse if the browser has a native implementation.
2200   * In general, this is a good idea.  See the Known Issues section in the
2201   * JSON user guide for caveats.  The default value is true for browsers with
2202   * native JSON support.
2203   *
2204   * @property useNativeJSONParse
2205   * @type Boolean
2206   * @default true
2207   * @since 3.8.0
2208   */
2209  
2210  /**
2211  Delay the `use` callback until a specific event has passed (`load`, `domready`, `contentready` or `available`)
2212  
2213  @property {Object|String} delayUntil
2214  @since 3.6.0
2215  @example
2216  
2217  You can use `load` or `domready` strings by default:
2218  
2219      YUI({
2220          delayUntil: 'domready'
2221      }, function (Y) {
2222          // This will not execute until 'domeready' occurs.
2223      });
2224  
2225  Or you can delay until a node is available (with `available` or `contentready`):
2226  
2227      YUI({
2228          delayUntil: {
2229              event: 'available',
2230              args : '#foo'
2231          }
2232      }, function (Y) {
2233          // This will not execute until a node matching the selector "#foo" is
2234          // available in the DOM.
2235      });
2236  
2237  **/
2238  YUI.add('yui-base', function (Y, NAME) {
2239  
2240  /*
2241   * YUI stub
2242   * @module yui
2243   * @submodule yui-base
2244   */
2245  /**
2246   * The YUI module contains the components required for building the YUI
2247   * seed file.  This includes the script loading mechanism, a simple queue,
2248   * and the core utilities for the library.
2249   * @module yui
2250   * @submodule yui-base
2251   */
2252  
2253  /**
2254   * Provides core language utilites and extensions used throughout YUI.
2255   *
2256   * @class Lang
2257   * @static
2258   */
2259  
2260  var L = Y.Lang || (Y.Lang = {}),
2261  
2262  STRING_PROTO = String.prototype,
2263  TOSTRING     = Object.prototype.toString,
2264  
2265  TYPES = {
2266      'undefined'        : 'undefined',
2267      'number'           : 'number',
2268      'boolean'          : 'boolean',
2269      'string'           : 'string',
2270      '[object Function]': 'function',
2271      '[object RegExp]'  : 'regexp',
2272      '[object Array]'   : 'array',
2273      '[object Date]'    : 'date',
2274      '[object Error]'   : 'error'
2275  },
2276  
2277  SUBREGEX         = /\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g,
2278  
2279  WHITESPACE       = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF",
2280  WHITESPACE_CLASS = "[\x09-\x0D\x20\xA0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]+",
2281  TRIM_LEFT_REGEX  = new RegExp("^" + WHITESPACE_CLASS),
2282  TRIM_RIGHT_REGEX = new RegExp(WHITESPACE_CLASS + "$"),
2283  TRIMREGEX        = new RegExp(TRIM_LEFT_REGEX.source + "|" + TRIM_RIGHT_REGEX.source, "g"),
2284  
2285  NATIVE_FN_REGEX  = /\{\s*\[(?:native code|function)\]\s*\}/i;
2286  
2287  // -- Protected Methods --------------------------------------------------------
2288  
2289  /**
2290  Returns `true` if the given function appears to be implemented in native code,
2291  `false` otherwise. Will always return `false` -- even in ES5-capable browsers --
2292  if the `useNativeES5` YUI config option is set to `false`.
2293  
2294  This isn't guaranteed to be 100% accurate and won't work for anything other than
2295  functions, but it can be useful for determining whether a function like
2296  `Array.prototype.forEach` is native or a JS shim provided by another library.
2297  
2298  There's a great article by @kangax discussing certain flaws with this technique:
2299  <http://perfectionkills.com/detecting-built-in-host-methods/>
2300  
2301  While his points are valid, it's still possible to benefit from this function
2302  as long as it's used carefully and sparingly, and in such a way that false
2303  negatives have minimal consequences. It's used internally to avoid using
2304  potentially broken non-native ES5 shims that have been added to the page by
2305  other libraries.
2306  
2307  @method _isNative
2308  @param {Function} fn Function to test.
2309  @return {Boolean} `true` if _fn_ appears to be native, `false` otherwise.
2310  @static
2311  @protected
2312  @since 3.5.0
2313  **/
2314  L._isNative = function (fn) {
2315      return !!(Y.config.useNativeES5 && fn && NATIVE_FN_REGEX.test(fn));
2316  };
2317  
2318  // -- Public Methods -----------------------------------------------------------
2319  
2320  /**
2321   * Determines whether or not the provided item is an array.
2322   *
2323   * Returns `false` for array-like collections such as the function `arguments`
2324   * collection or `HTMLElement` collections. Use `Y.Array.test()` if you want to
2325   * test for an array-like collection.
2326   *
2327   * @method isArray
2328   * @param o The object to test.
2329   * @return {boolean} true if o is an array.
2330   * @static
2331   */
2332  L.isArray = L._isNative(Array.isArray) ? Array.isArray : function (o) {
2333      return L.type(o) === 'array';
2334  };
2335  
2336  /**
2337   * Determines whether or not the provided item is a boolean.
2338   * @method isBoolean
2339   * @static
2340   * @param o The object to test.
2341   * @return {boolean} true if o is a boolean.
2342   */
2343  L.isBoolean = function(o) {
2344      return typeof o === 'boolean';
2345  };
2346  
2347  /**
2348   * Determines whether or not the supplied item is a date instance.
2349   * @method isDate
2350   * @static
2351   * @param o The object to test.
2352   * @return {boolean} true if o is a date.
2353   */
2354  L.isDate = function(o) {
2355      return L.type(o) === 'date' && o.toString() !== 'Invalid Date' && !isNaN(o);
2356  };
2357  
2358  /**
2359   * <p>
2360   * Determines whether or not the provided item is a function.
2361   * Note: Internet Explorer thinks certain functions are objects:
2362   * </p>
2363   *
2364   * <pre>
2365   * var obj = document.createElement("object");
2366   * Y.Lang.isFunction(obj.getAttribute) // reports false in IE
2367   * &nbsp;
2368   * var input = document.createElement("input"); // append to body
2369   * Y.Lang.isFunction(input.focus) // reports false in IE
2370   * </pre>
2371   *
2372   * <p>
2373   * You will have to implement additional tests if these functions
2374   * matter to you.
2375   * </p>
2376   *
2377   * @method isFunction
2378   * @static
2379   * @param o The object to test.
2380   * @return {boolean} true if o is a function.
2381   */
2382  L.isFunction = function(o) {
2383      return L.type(o) === 'function';
2384  };
2385  
2386  /**
2387   * Determines whether or not the provided item is null.
2388   * @method isNull
2389   * @static
2390   * @param o The object to test.
2391   * @return {boolean} true if o is null.
2392   */
2393  L.isNull = function(o) {
2394      return o === null;
2395  };
2396  
2397  /**
2398   * Determines whether or not the provided item is a legal number.
2399   * @method isNumber
2400   * @static
2401   * @param o The object to test.
2402   * @return {boolean} true if o is a number.
2403   */
2404  L.isNumber = function(o) {
2405      return typeof o === 'number' && isFinite(o);
2406  };
2407  
2408  /**
2409   * Determines whether or not the provided item is of type object
2410   * or function. Note that arrays are also objects, so
2411   * <code>Y.Lang.isObject([]) === true</code>.
2412   * @method isObject
2413   * @static
2414   * @param o The object to test.
2415   * @param failfn {boolean} fail if the input is a function.
2416   * @return {boolean} true if o is an object.
2417   * @see isPlainObject
2418   */
2419  L.isObject = function(o, failfn) {
2420      var t = typeof o;
2421      return (o && (t === 'object' ||
2422          (!failfn && (t === 'function' || L.isFunction(o))))) || false;
2423  };
2424  
2425  /**
2426   * Determines whether or not the provided value is a regexp.
2427   * @method isRegExp
2428   * @static
2429   * @param value The value or object to test.
2430   * @return {boolean} true if value is a regexp.
2431   */
2432  L.isRegExp = function(value) {
2433      return L.type(value) === 'regexp';
2434  };
2435  
2436  /**
2437   * Determines whether or not the provided item is a string.
2438   * @method isString
2439   * @static
2440   * @param o The object to test.
2441   * @return {boolean} true if o is a string.
2442   */
2443  L.isString = function(o) {
2444      return typeof o === 'string';
2445  };
2446  
2447  /**
2448   * Determines whether or not the provided item is undefined.
2449   * @method isUndefined
2450   * @static
2451   * @param o The object to test.
2452   * @return {boolean} true if o is undefined.
2453   */
2454  L.isUndefined = function(o) {
2455      return typeof o === 'undefined';
2456  };
2457  
2458  /**
2459   * A convenience method for detecting a legitimate non-null value.
2460   * Returns false for null/undefined/NaN, true for other values,
2461   * including 0/false/''
2462   * @method isValue
2463   * @static
2464   * @param o The item to test.
2465   * @return {boolean} true if it is not null/undefined/NaN || false.
2466   */
2467  L.isValue = function(o) {
2468      var t = L.type(o);
2469  
2470      switch (t) {
2471          case 'number':
2472              return isFinite(o);
2473  
2474          case 'null': // fallthru
2475          case 'undefined':
2476              return false;
2477  
2478          default:
2479              return !!t;
2480      }
2481  };
2482  
2483  /**
2484   * Returns the current time in milliseconds.
2485   *
2486   * @method now
2487   * @return {Number} Current time in milliseconds.
2488   * @static
2489   * @since 3.3.0
2490   */
2491  L.now = Date.now || function () {
2492      return new Date().getTime();
2493  };
2494  
2495  /**
2496   * Performs `{placeholder}` substitution on a string. The object passed as the 
2497   * second parameter provides values to replace the `{placeholder}`s.
2498   * `{placeholder}` token names must match property names of the object. For example,
2499   * 
2500   *`var greeting = Y.Lang.sub("Hello, {who}!", { who: "World" });`
2501   *
2502   * `{placeholder}` tokens that are undefined on the object map will be left 
2503   * in tact (leaving unsightly `{placeholder}`'s in the output string). 
2504   *
2505   * @method sub
2506   * @param {string} s String to be modified.
2507   * @param {object} o Object containing replacement values.
2508   * @return {string} the substitute result.
2509   * @static
2510   * @since 3.2.0
2511   */
2512  L.sub = function(s, o) {
2513      return s.replace ? s.replace(SUBREGEX, function (match, key) {
2514          return L.isUndefined(o[key]) ? match : o[key];
2515      }) : s;
2516  };
2517  
2518  /**
2519   * Returns a string without any leading or trailing whitespace.  If
2520   * the input is not a string, the input will be returned untouched.
2521   * @method trim
2522   * @static
2523   * @param s {string} the string to trim.
2524   * @return {string} the trimmed string.
2525   */
2526  L.trim = L._isNative(STRING_PROTO.trim) && !WHITESPACE.trim() ? function(s) {
2527      return s && s.trim ? s.trim() : s;
2528  } : function (s) {
2529      try {
2530          return s.replace(TRIMREGEX, '');
2531      } catch (e) {
2532          return s;
2533      }
2534  };
2535  
2536  /**
2537   * Returns a string without any leading whitespace.
2538   * @method trimLeft
2539   * @static
2540   * @param s {string} the string to trim.
2541   * @return {string} the trimmed string.
2542   */
2543  L.trimLeft = L._isNative(STRING_PROTO.trimLeft) && !WHITESPACE.trimLeft() ? function (s) {
2544      return s.trimLeft();
2545  } : function (s) {
2546      return s.replace(TRIM_LEFT_REGEX, '');
2547  };
2548  
2549  /**
2550   * Returns a string without any trailing whitespace.
2551   * @method trimRight
2552   * @static
2553   * @param s {string} the string to trim.
2554   * @return {string} the trimmed string.
2555   */
2556  L.trimRight = L._isNative(STRING_PROTO.trimRight) && !WHITESPACE.trimRight() ? function (s) {
2557      return s.trimRight();
2558  } : function (s) {
2559      return s.replace(TRIM_RIGHT_REGEX, '');
2560  };
2561  
2562  /**
2563  Returns one of the following strings, representing the type of the item passed
2564  in:
2565  
2566   * "array"
2567   * "boolean"
2568   * "date"
2569   * "error"
2570   * "function"
2571   * "null"
2572   * "number"
2573   * "object"
2574   * "regexp"
2575   * "string"
2576   * "undefined"
2577  
2578  Known issues:
2579  
2580   * `typeof HTMLElementCollection` returns function in Safari, but
2581      `Y.Lang.type()` reports "object", which could be a good thing --
2582      but it actually caused the logic in <code>Y.Lang.isObject</code> to fail.
2583  
2584  @method type
2585  @param o the item to test.
2586  @return {string} the detected type.
2587  @static
2588  **/
2589  L.type = function(o) {
2590      return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null');
2591  };
2592  /**
2593  @module yui
2594  @submodule yui-base
2595  */
2596  
2597  var Lang   = Y.Lang,
2598      Native = Array.prototype,
2599  
2600      hasOwn = Object.prototype.hasOwnProperty;
2601  
2602  /**
2603  Provides utility methods for working with arrays. Additional array helpers can
2604  be found in the `collection` and `array-extras` modules.
2605  
2606  `Y.Array(thing)` returns a native array created from _thing_. Depending on
2607  _thing_'s type, one of the following will happen:
2608  
2609    * Arrays are returned unmodified unless a non-zero _startIndex_ is
2610      specified.
2611    * Array-like collections (see `Array.test()`) are converted to arrays.
2612    * For everything else, a new array is created with _thing_ as the sole
2613      item.
2614  
2615  Note: elements that are also collections, such as `<form>` and `<select>`
2616  elements, are not automatically converted to arrays. To force a conversion,
2617  pass `true` as the value of the _force_ parameter.
2618  
2619  @class Array
2620  @constructor
2621  @param {Any} thing The thing to arrayify.
2622  @param {Number} [startIndex=0] If non-zero and _thing_ is an array or array-like
2623    collection, a subset of items starting at the specified index will be
2624    returned.
2625  @param {Boolean} [force=false] If `true`, _thing_ will be treated as an
2626    array-like collection no matter what.
2627  @return {Array} A native array created from _thing_, according to the rules
2628    described above.
2629  **/
2630  function YArray(thing, startIndex, force) {
2631      var len, result;
2632  
2633      /*jshint expr: true*/
2634      startIndex || (startIndex = 0);
2635  
2636      if (force || YArray.test(thing)) {
2637          // IE throws when trying to slice HTMLElement collections.
2638          try {
2639              return Native.slice.call(thing, startIndex);
2640          } catch (ex) {
2641              result = [];
2642  
2643              for (len = thing.length; startIndex < len; ++startIndex) {
2644                  result.push(thing[startIndex]);
2645              }
2646  
2647              return result;
2648          }
2649      }
2650  
2651      return [thing];
2652  }
2653  
2654  Y.Array = YArray;
2655  
2656  /**
2657  Dedupes an array of strings, returning an array that's guaranteed to contain
2658  only one copy of a given string.
2659  
2660  This method differs from `Array.unique()` in that it's optimized for use only
2661  with arrays consisting entirely of strings or entirely of numbers, whereas
2662  `unique` may be used with other value types (but is slower).
2663  
2664  Using `dedupe()` with values other than strings or numbers, or with arrays
2665  containing a mix of strings and numbers, may result in unexpected behavior.
2666  
2667  @method dedupe
2668  @param {String[]|Number[]} array Array of strings or numbers to dedupe.
2669  @return {Array} Copy of _array_ containing no duplicate values.
2670  @static
2671  @since 3.4.0
2672  **/
2673  YArray.dedupe = Lang._isNative(Object.create) ? function (array) {
2674      var hash    = Object.create(null),
2675          results = [],
2676          i, item, len;
2677  
2678      for (i = 0, len = array.length; i < len; ++i) {
2679          item = array[i];
2680  
2681          if (!hash[item]) {
2682              hash[item] = 1;
2683              results.push(item);
2684          }
2685      }
2686  
2687      return results;
2688  } : function (array) {
2689      var hash    = {},
2690          results = [],
2691          i, item, len;
2692  
2693      for (i = 0, len = array.length; i < len; ++i) {
2694          item = array[i];
2695  
2696          if (!hasOwn.call(hash, item)) {
2697              hash[item] = 1;
2698              results.push(item);
2699          }
2700      }
2701  
2702      return results;
2703  };
2704  
2705  /**
2706  Executes the supplied function on each item in the array. This method wraps
2707  the native ES5 `Array.forEach()` method if available.
2708  
2709  @method each
2710  @param {Array} array Array to iterate.
2711  @param {Function} fn Function to execute on each item in the array. The function
2712    will receive the following arguments:
2713      @param {Any} fn.item Current array item.
2714      @param {Number} fn.index Current array index.
2715      @param {Array} fn.array Array being iterated.
2716  @param {Object} [thisObj] `this` object to use when calling _fn_.
2717  @return {YUI} The YUI instance.
2718  @static
2719  **/
2720  YArray.each = YArray.forEach = Lang._isNative(Native.forEach) ? function (array, fn, thisObj) {
2721      Native.forEach.call(array || [], fn, thisObj || Y);
2722      return Y;
2723  } : function (array, fn, thisObj) {
2724      for (var i = 0, len = (array && array.length) || 0; i < len; ++i) {
2725          if (i in array) {
2726              fn.call(thisObj || Y, array[i], i, array);
2727          }
2728      }
2729  
2730      return Y;
2731  };
2732  
2733  /**
2734  Alias for `each()`.
2735  
2736  @method forEach
2737  @static
2738  **/
2739  
2740  /**
2741  Returns an object using the first array as keys and the second as values. If
2742  the second array is not provided, or if it doesn't contain the same number of
2743  values as the first array, then `true` will be used in place of the missing
2744  values.
2745  
2746  @example
2747  
2748      Y.Array.hash(['a', 'b', 'c'], ['foo', 'bar']);
2749      // => {a: 'foo', b: 'bar', c: true}
2750  
2751  @method hash
2752  @param {String[]} keys Array of strings to use as keys.
2753  @param {Array} [values] Array to use as values.
2754  @return {Object} Hash using the first array as keys and the second as values.
2755  @static
2756  **/
2757  YArray.hash = function (keys, values) {
2758      var hash = {},
2759          vlen = (values && values.length) || 0,
2760          i, len;
2761  
2762      for (i = 0, len = keys.length; i < len; ++i) {
2763          if (i in keys) {
2764              hash[keys[i]] = vlen > i && i in values ? values[i] : true;
2765          }
2766      }
2767  
2768      return hash;
2769  };
2770  
2771  /**
2772  Returns the index of the first item in the array that's equal (using a strict
2773  equality check) to the specified _value_, or `-1` if the value isn't found.
2774  
2775  This method wraps the native ES5 `Array.indexOf()` method if available.
2776  
2777  @method indexOf
2778  @param {Array} array Array to search.
2779  @param {Any} value Value to search for.
2780  @param {Number} [from=0] The index at which to begin the search.
2781  @return {Number} Index of the item strictly equal to _value_, or `-1` if not
2782      found.
2783  @static
2784  **/
2785  YArray.indexOf = Lang._isNative(Native.indexOf) ? function (array, value, from) {
2786      return Native.indexOf.call(array, value, from);
2787  } : function (array, value, from) {
2788      // http://es5.github.com/#x15.4.4.14
2789      var len = array.length;
2790  
2791      from = +from || 0;
2792      from = (from > 0 || -1) * Math.floor(Math.abs(from));
2793  
2794      if (from < 0) {
2795          from += len;
2796  
2797          if (from < 0) {
2798              from = 0;
2799          }
2800      }
2801  
2802      for (; from < len; ++from) {
2803          if (from in array && array[from] === value) {
2804              return from;
2805          }
2806      }
2807  
2808      return -1;
2809  };
2810  
2811  /**
2812  Numeric sort convenience function.
2813  
2814  The native `Array.prototype.sort()` function converts values to strings and
2815  sorts them in lexicographic order, which is unsuitable for sorting numeric
2816  values. Provide `Array.numericSort` as a custom sort function when you want
2817  to sort values in numeric order.
2818  
2819  @example
2820  
2821      [42, 23, 8, 16, 4, 15].sort(Y.Array.numericSort);
2822      // => [4, 8, 15, 16, 23, 42]
2823  
2824  @method numericSort
2825  @param {Number} a First value to compare.
2826  @param {Number} b Second value to compare.
2827  @return {Number} Difference between _a_ and _b_.
2828  @static
2829  **/
2830  YArray.numericSort = function (a, b) {
2831      return a - b;
2832  };
2833  
2834  /**
2835  Executes the supplied function on each item in the array. Returning a truthy
2836  value from the function will stop the processing of remaining items.
2837  
2838  @method some
2839  @param {Array} array Array to iterate over.
2840  @param {Function} fn Function to execute on each item. The function will receive
2841    the following arguments:
2842      @param {Any} fn.value Current array item.
2843      @param {Number} fn.index Current array index.
2844      @param {Array} fn.array Array being iterated over.
2845  @param {Object} [thisObj] `this` object to use when calling _fn_.
2846  @return {Boolean} `true` if the function returns a truthy value on any of the
2847    items in the array; `false` otherwise.
2848  @static
2849  **/
2850  YArray.some = Lang._isNative(Native.some) ? function (array, fn, thisObj) {
2851      return Native.some.call(array, fn, thisObj);
2852  } : function (array, fn, thisObj) {
2853      for (var i = 0, len = array.length; i < len; ++i) {
2854          if (i in array && fn.call(thisObj, array[i], i, array)) {
2855              return true;
2856          }
2857      }
2858  
2859      return false;
2860  };
2861  
2862  /**
2863  Evaluates _obj_ to determine if it's an array, an array-like collection, or
2864  something else. This is useful when working with the function `arguments`
2865  collection and `HTMLElement` collections.
2866  
2867  Note: This implementation doesn't consider elements that are also
2868  collections, such as `<form>` and `<select>`, to be array-like.
2869  
2870  @method test
2871  @param {Object} obj Object to test.
2872  @return {Number} A number indicating the results of the test:
2873  
2874    * 0: Neither an array nor an array-like collection.
2875    * 1: Real array.
2876    * 2: Array-like collection.
2877  
2878  @static
2879  **/
2880  YArray.test = function (obj) {
2881      var result = 0;
2882  
2883      if (Lang.isArray(obj)) {
2884          result = 1;
2885      } else if (Lang.isObject(obj)) {
2886          try {
2887              // indexed, but no tagName (element) or scrollTo/document (window. From DOM.isWindow test which we can't use here),
2888              // or functions without apply/call (Safari
2889              // HTMLElementCollection bug).
2890              if ('length' in obj && !obj.tagName && !(obj.scrollTo && obj.document) && !obj.apply) {
2891                  result = 2;
2892              }
2893          } catch (ex) {}
2894      }
2895  
2896      return result;
2897  };
2898  /**
2899   * The YUI module contains the components required for building the YUI
2900   * seed file.  This includes the script loading mechanism, a simple queue,
2901   * and the core utilities for the library.
2902   * @module yui
2903   * @submodule yui-base
2904   */
2905  
2906  /**
2907   * A simple FIFO queue.  Items are added to the Queue with add(1..n items) and
2908   * removed using next().
2909   *
2910   * @class Queue
2911   * @constructor
2912   * @param {MIXED} item* 0..n items to seed the queue.
2913   */
2914  function Queue() {
2915      this._init();
2916      this.add.apply(this, arguments);
2917  }
2918  
2919  Queue.prototype = {
2920      /**
2921       * Initialize the queue
2922       *
2923       * @method _init
2924       * @protected
2925       */
2926      _init: function() {
2927          /**
2928           * The collection of enqueued items
2929           *
2930           * @property _q
2931           * @type Array
2932           * @protected
2933           */
2934          this._q = [];
2935      },
2936  
2937      /**
2938       * Get the next item in the queue. FIFO support
2939       *
2940       * @method next
2941       * @return {MIXED} the next item in the queue.
2942       */
2943      next: function() {
2944          return this._q.shift();
2945      },
2946  
2947      /**
2948       * Get the last in the queue. LIFO support.
2949       *
2950       * @method last
2951       * @return {MIXED} the last item in the queue.
2952       */
2953      last: function() {
2954          return this._q.pop();
2955      },
2956  
2957      /**
2958       * Add 0..n items to the end of the queue.
2959       *
2960       * @method add
2961       * @param {MIXED} item* 0..n items.
2962       * @return {object} this queue.
2963       */
2964      add: function() {
2965          this._q.push.apply(this._q, arguments);
2966  
2967          return this;
2968      },
2969  
2970      /**
2971       * Returns the current number of queued items.
2972       *
2973       * @method size
2974       * @return {Number} The size.
2975       */
2976      size: function() {
2977          return this._q.length;
2978      }
2979  };
2980  
2981  Y.Queue = Queue;
2982  
2983  YUI.Env._loaderQueue = YUI.Env._loaderQueue || new Queue();
2984  
2985  /**
2986  The YUI module contains the components required for building the YUI seed file.
2987  This includes the script loading mechanism, a simple queue, and the core
2988  utilities for the library.
2989  
2990  @module yui
2991  @submodule yui-base
2992  **/
2993  
2994  var CACHED_DELIMITER = '__',
2995  
2996      hasOwn   = Object.prototype.hasOwnProperty,
2997      isObject = Y.Lang.isObject;
2998  
2999  /**
3000  Returns a wrapper for a function which caches the return value of that function,
3001  keyed off of the combined string representation of the argument values provided
3002  when the wrapper is called.
3003  
3004  Calling this function again with the same arguments will return the cached value
3005  rather than executing the wrapped function.
3006  
3007  Note that since the cache is keyed off of the string representation of arguments
3008  passed to the wrapper function, arguments that aren't strings and don't provide
3009  a meaningful `toString()` method may result in unexpected caching behavior. For
3010  example, the objects `{}` and `{foo: 'bar'}` would both be converted to the
3011  string `[object Object]` when used as a cache key.
3012  
3013  @method cached
3014  @param {Function} source The function to memoize.
3015  @param {Object} [cache={}] Object in which to store cached values. You may seed
3016    this object with pre-existing cached values if desired.
3017  @param {any} [refetch] If supplied, this value is compared with the cached value
3018    using a `==` comparison. If the values are equal, the wrapped function is
3019    executed again even though a cached value exists.
3020  @return {Function} Wrapped function.
3021  @for YUI
3022  **/
3023  Y.cached = function (source, cache, refetch) {
3024      /*jshint expr: true*/
3025      cache || (cache = {});
3026  
3027      return function (arg) {
3028          var key = arguments.length > 1 ?
3029                  Array.prototype.join.call(arguments, CACHED_DELIMITER) :
3030                  String(arg);
3031  
3032          /*jshint eqeqeq: false*/
3033          if (!(key in cache) || (refetch && cache[key] == refetch)) {
3034              cache[key] = source.apply(source, arguments);
3035          }
3036  
3037          return cache[key];
3038      };
3039  };
3040  
3041  /**
3042  Returns the `location` object from the window/frame in which this YUI instance
3043  operates, or `undefined` when executing in a non-browser environment
3044  (e.g. Node.js).
3045  
3046  It is _not_ recommended to hold references to the `window.location` object
3047  outside of the scope of a function in which its properties are being accessed or
3048  its methods are being called. This is because of a nasty bug/issue that exists
3049  in both Safari and MobileSafari browsers:
3050  [WebKit Bug 34679](https://bugs.webkit.org/show_bug.cgi?id=34679).
3051  
3052  @method getLocation
3053  @return {location} The `location` object from the window/frame in which this YUI
3054      instance operates.
3055  @since 3.5.0
3056  **/
3057  Y.getLocation = function () {
3058      // It is safer to look this up every time because yui-base is attached to a
3059      // YUI instance before a user's config is applied; i.e. `Y.config.win` does
3060      // not point the correct window object when this file is loaded.
3061      var win = Y.config.win;
3062  
3063      // It is not safe to hold a reference to the `location` object outside the
3064      // scope in which it is being used. The WebKit engine used in Safari and
3065      // MobileSafari will "disconnect" the `location` object from the `window`
3066      // when a page is restored from back/forward history cache.
3067      return win && win.location;
3068  };
3069  
3070  /**
3071  Returns a new object containing all of the properties of all the supplied
3072  objects. The properties from later objects will overwrite those in earlier
3073  objects.
3074  
3075  Passing in a single object will create a shallow copy of it. For a deep copy,
3076  use `clone()`.
3077  
3078  @method merge
3079  @param {Object} objects* One or more objects to merge.
3080  @return {Object} A new merged object.
3081  **/
3082  Y.merge = function () {
3083      var i      = 0,
3084          len    = arguments.length,
3085          result = {},
3086          key,
3087          obj;
3088  
3089      for (; i < len; ++i) {
3090          obj = arguments[i];
3091  
3092          for (key in obj) {
3093              if (hasOwn.call(obj, key)) {
3094                  result[key] = obj[key];
3095              }
3096          }
3097      }
3098  
3099      return result;
3100  };
3101  
3102  /**
3103  Mixes _supplier_'s properties into _receiver_.
3104  
3105  Properties on _receiver_ or _receiver_'s prototype will not be overwritten or
3106  shadowed unless the _overwrite_ parameter is `true`, and will not be merged
3107  unless the _merge_ parameter is `true`.
3108  
3109  In the default mode (0), only properties the supplier owns are copied (prototype
3110  properties are not copied). The following copying modes are available:
3111  
3112    * `0`: _Default_. Object to object.
3113    * `1`: Prototype to prototype.
3114    * `2`: Prototype to prototype and object to object.
3115    * `3`: Prototype to object.
3116    * `4`: Object to prototype.
3117  
3118  @method mix
3119  @param {Function|Object} receiver The object or function to receive the mixed
3120    properties.
3121  @param {Function|Object} supplier The object or function supplying the
3122    properties to be mixed.
3123  @param {Boolean} [overwrite=false] If `true`, properties that already exist
3124    on the receiver will be overwritten with properties from the supplier.
3125  @param {String[]} [whitelist] An array of property names to copy. If
3126    specified, only the whitelisted properties will be copied, and all others
3127    will be ignored.
3128  @param {Number} [mode=0] Mix mode to use. See above for available modes.
3129  @param {Boolean} [merge=false] If `true`, objects and arrays that already
3130    exist on the receiver will have the corresponding object/array from the
3131    supplier merged into them, rather than being skipped or overwritten. When
3132    both _overwrite_ and _merge_ are `true`, _merge_ takes precedence.
3133  @return {Function|Object|YUI} The receiver, or the YUI instance if the
3134    specified receiver is falsy.
3135  **/
3136  Y.mix = function(receiver, supplier, overwrite, whitelist, mode, merge) {
3137      var alwaysOverwrite, exists, from, i, key, len, to;
3138  
3139      // If no supplier is given, we return the receiver. If no receiver is given,
3140      // we return Y. Returning Y doesn't make much sense to me, but it's
3141      // grandfathered in for backcompat reasons.
3142      if (!receiver || !supplier) {
3143          return receiver || Y;
3144      }
3145  
3146      if (mode) {
3147          // In mode 2 (prototype to prototype and object to object), we recurse
3148          // once to do the proto to proto mix. The object to object mix will be
3149          // handled later on.
3150          if (mode === 2) {
3151              Y.mix(receiver.prototype, supplier.prototype, overwrite,
3152                      whitelist, 0, merge);
3153          }
3154  
3155          // Depending on which mode is specified, we may be copying from or to
3156          // the prototypes of the supplier and receiver.
3157          from = mode === 1 || mode === 3 ? supplier.prototype : supplier;
3158          to   = mode === 1 || mode === 4 ? receiver.prototype : receiver;
3159  
3160          // If either the supplier or receiver doesn't actually have a
3161          // prototype property, then we could end up with an undefined `from`
3162          // or `to`. If that happens, we abort and return the receiver.
3163          if (!from || !to) {
3164              return receiver;
3165          }
3166      } else {
3167          from = supplier;
3168          to   = receiver;
3169      }
3170  
3171      // If `overwrite` is truthy and `merge` is falsy, then we can skip a
3172      // property existence check on each iteration and save some time.
3173      alwaysOverwrite = overwrite && !merge;
3174  
3175      if (whitelist) {
3176          for (i = 0, len = whitelist.length; i < len; ++i) {
3177              key = whitelist[i];
3178  
3179              // We call `Object.prototype.hasOwnProperty` instead of calling
3180              // `hasOwnProperty` on the object itself, since the object's
3181              // `hasOwnProperty` method may have been overridden or removed.
3182              // Also, some native objects don't implement a `hasOwnProperty`
3183              // method.
3184              if (!hasOwn.call(from, key)) {
3185                  continue;
3186              }
3187  
3188              // The `key in to` check here is (sadly) intentional for backwards
3189              // compatibility reasons. It prevents undesired shadowing of
3190              // prototype members on `to`.
3191              exists = alwaysOverwrite ? false : key in to;
3192  
3193              if (merge && exists && isObject(to[key], true)
3194                      && isObject(from[key], true)) {
3195                  // If we're in merge mode, and the key is present on both
3196                  // objects, and the value on both objects is either an object or
3197                  // an array (but not a function), then we recurse to merge the
3198                  // `from` value into the `to` value instead of overwriting it.
3199                  //
3200                  // Note: It's intentional that the whitelist isn't passed to the
3201                  // recursive call here. This is legacy behavior that lots of
3202                  // code still depends on.
3203                  Y.mix(to[key], from[key], overwrite, null, 0, merge);
3204              } else if (overwrite || !exists) {
3205                  // We're not in merge mode, so we'll only copy the `from` value
3206                  // to the `to` value if we're in overwrite mode or if the
3207                  // current key doesn't exist on the `to` object.
3208                  to[key] = from[key];
3209              }
3210          }
3211      } else {
3212          for (key in from) {
3213              // The code duplication here is for runtime performance reasons.
3214              // Combining whitelist and non-whitelist operations into a single
3215              // loop or breaking the shared logic out into a function both result
3216              // in worse performance, and Y.mix is critical enough that the byte
3217              // tradeoff is worth it.
3218              if (!hasOwn.call(from, key)) {
3219                  continue;
3220              }
3221  
3222              // The `key in to` check here is (sadly) intentional for backwards
3223              // compatibility reasons. It prevents undesired shadowing of
3224              // prototype members on `to`.
3225              exists = alwaysOverwrite ? false : key in to;
3226  
3227              if (merge && exists && isObject(to[key], true)
3228                      && isObject(from[key], true)) {
3229                  Y.mix(to[key], from[key], overwrite, null, 0, merge);
3230              } else if (overwrite || !exists) {
3231                  to[key] = from[key];
3232              }
3233          }
3234  
3235          // If this is an IE browser with the JScript enumeration bug, force
3236          // enumeration of the buggy properties by making a recursive call with
3237          // the buggy properties as the whitelist.
3238          if (Y.Object._hasEnumBug) {
3239              Y.mix(to, from, overwrite, Y.Object._forceEnum, mode, merge);
3240          }
3241      }
3242  
3243      return receiver;
3244  };
3245  /**
3246   * The YUI module contains the components required for building the YUI
3247   * seed file.  This includes the script loading mechanism, a simple queue,
3248   * and the core utilities for the library.
3249   * @module yui
3250   * @submodule yui-base
3251   */
3252  
3253  /**
3254   * Adds utilities to the YUI instance for working with objects.
3255   *
3256   * @class Object
3257   */
3258  
3259  var Lang   = Y.Lang,
3260      hasOwn = Object.prototype.hasOwnProperty,
3261  
3262      UNDEFINED, // <-- Note the comma. We're still declaring vars.
3263  
3264  /**
3265   * Returns a new object that uses _obj_ as its prototype. This method wraps the
3266   * native ES5 `Object.create()` method if available, but doesn't currently
3267   * pass through `Object.create()`'s second argument (properties) in order to
3268   * ensure compatibility with older browsers.
3269   *
3270   * @method ()
3271   * @param {Object} obj Prototype object.
3272   * @return {Object} New object using _obj_ as its prototype.
3273   * @static
3274   */
3275  O = Y.Object = Lang._isNative(Object.create) ? function (obj) {
3276      // We currently wrap the native Object.create instead of simply aliasing it
3277      // to ensure consistency with our fallback shim, which currently doesn't
3278      // support Object.create()'s second argument (properties). Once we have a
3279      // safe fallback for the properties arg, we can stop wrapping
3280      // Object.create().
3281      return Object.create(obj);
3282  } : (function () {
3283      // Reusable constructor function for the Object.create() shim.
3284      function F() {}
3285  
3286      // The actual shim.
3287      return function (obj) {
3288          F.prototype = obj;
3289          return new F();
3290      };
3291  }()),
3292  
3293  /**
3294   * Property names that IE doesn't enumerate in for..in loops, even when they
3295   * should be enumerable. When `_hasEnumBug` is `true`, it's necessary to
3296   * manually enumerate these properties.
3297   *
3298   * @property _forceEnum
3299   * @type String[]
3300   * @protected
3301   * @static
3302   */
3303  forceEnum = O._forceEnum = [
3304      'hasOwnProperty',
3305      'isPrototypeOf',
3306      'propertyIsEnumerable',
3307      'toString',
3308      'toLocaleString',
3309      'valueOf'
3310  ],
3311  
3312  /**
3313   * `true` if this browser has the JScript enumeration bug that prevents
3314   * enumeration of the properties named in the `_forceEnum` array, `false`
3315   * otherwise.
3316   *
3317   * See:
3318   *   - <https://developer.mozilla.org/en/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug>
3319   *   - <http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation>
3320   *
3321   * @property _hasEnumBug
3322   * @type Boolean
3323   * @protected
3324   * @static
3325   */
3326  hasEnumBug = O._hasEnumBug = !{valueOf: 0}.propertyIsEnumerable('valueOf'),
3327  
3328  /**
3329   * `true` if this browser incorrectly considers the `prototype` property of
3330   * functions to be enumerable. Currently known to affect Opera 11.50 and Android 2.3.x.
3331   *
3332   * @property _hasProtoEnumBug
3333   * @type Boolean
3334   * @protected
3335   * @static
3336   */
3337  hasProtoEnumBug = O._hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'),
3338  
3339  /**
3340   * Returns `true` if _key_ exists on _obj_, `false` if _key_ doesn't exist or
3341   * exists only on _obj_'s prototype. This is essentially a safer version of
3342   * `obj.hasOwnProperty()`.
3343   *
3344   * @method owns
3345   * @param {Object} obj Object to test.
3346   * @param {String} key Property name to look for.
3347   * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
3348   * @static
3349   */
3350  owns = O.owns = function (obj, key) {
3351      return !!obj && hasOwn.call(obj, key);
3352  }; // <-- End of var declarations.
3353  
3354  /**
3355   * Alias for `owns()`.
3356   *
3357   * @method hasKey
3358   * @param {Object} obj Object to test.
3359   * @param {String} key Property name to look for.
3360   * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
3361   * @static
3362   */
3363  O.hasKey = owns;
3364  
3365  /**
3366   * Returns an array containing the object's enumerable keys. Does not include
3367   * prototype keys or non-enumerable keys.
3368   *
3369   * Note that keys are returned in enumeration order (that is, in the same order
3370   * that they would be enumerated by a `for-in` loop), which may not be the same
3371   * as the order in which they were defined.
3372   *
3373   * This method is an alias for the native ES5 `Object.keys()` method if
3374   * available and non-buggy. The Opera 11.50 and Android 2.3.x versions of
3375   * `Object.keys()` have an inconsistency as they consider `prototype` to be
3376   * enumerable, so a non-native shim is used to rectify the difference.
3377   *
3378   * @example
3379   *
3380   *     Y.Object.keys({a: 'foo', b: 'bar', c: 'baz'});
3381   *     // => ['a', 'b', 'c']
3382   *
3383   * @method keys
3384   * @param {Object} obj An object.
3385   * @return {String[]} Array of keys.
3386   * @static
3387   */
3388  O.keys = Lang._isNative(Object.keys) && !hasProtoEnumBug ? Object.keys : function (obj) {
3389      if (!Lang.isObject(obj)) {
3390          throw new TypeError('Object.keys called on a non-object');
3391      }
3392  
3393      var keys = [],
3394          i, key, len;
3395  
3396      if (hasProtoEnumBug && typeof obj === 'function') {
3397          for (key in obj) {
3398              if (owns(obj, key) && key !== 'prototype') {
3399                  keys.push(key);
3400              }
3401          }
3402      } else {
3403          for (key in obj) {
3404              if (owns(obj, key)) {
3405                  keys.push(key);
3406              }
3407          }
3408      }
3409  
3410      if (hasEnumBug) {
3411          for (i = 0, len = forceEnum.length; i < len; ++i) {
3412              key = forceEnum[i];
3413  
3414              if (owns(obj, key)) {
3415                  keys.push(key);
3416              }
3417          }
3418      }
3419  
3420      return keys;
3421  };
3422  
3423  /**
3424   * Returns an array containing the values of the object's enumerable keys.
3425   *
3426   * Note that values are returned in enumeration order (that is, in the same
3427   * order that they would be enumerated by a `for-in` loop), which may not be the
3428   * same as the order in which they were defined.
3429   *
3430   * @example
3431   *
3432   *     Y.Object.values({a: 'foo', b: 'bar', c: 'baz'});
3433   *     // => ['foo', 'bar', 'baz']
3434   *
3435   * @method values
3436   * @param {Object} obj An object.
3437   * @return {Array} Array of values.
3438   * @static
3439   */
3440  O.values = function (obj) {
3441      var keys   = O.keys(obj),
3442          i      = 0,
3443          len    = keys.length,
3444          values = [];
3445  
3446      for (; i < len; ++i) {
3447          values.push(obj[keys[i]]);
3448      }
3449  
3450      return values;
3451  };
3452  
3453  /**
3454   * Returns the number of enumerable keys owned by an object.
3455   *
3456   * @method size
3457   * @param {Object} obj An object.
3458   * @return {Number} The object's size.
3459   * @static
3460   */
3461  O.size = function (obj) {
3462      try {
3463          return O.keys(obj).length;
3464      } catch (ex) {
3465          return 0; // Legacy behavior for non-objects.
3466      }
3467  };
3468  
3469  /**
3470   * Returns `true` if the object owns an enumerable property with the specified
3471   * value.
3472   *
3473   * @method hasValue
3474   * @param {Object} obj An object.
3475   * @param {any} value The value to search for.
3476   * @return {Boolean} `true` if _obj_ contains _value_, `false` otherwise.
3477   * @static
3478   */
3479  O.hasValue = function (obj, value) {
3480      return Y.Array.indexOf(O.values(obj), value) > -1;
3481  };
3482  
3483  /**
3484   * Executes a function on each enumerable property in _obj_. The function
3485   * receives the value, the key, and the object itself as parameters (in that
3486   * order).
3487   *
3488   * By default, only properties owned by _obj_ are enumerated. To include
3489   * prototype properties, set the _proto_ parameter to `true`.
3490   *
3491   * @method each
3492   * @param {Object} obj Object to enumerate.
3493   * @param {Function} fn Function to execute on each enumerable property.
3494   *   @param {mixed} fn.value Value of the current property.
3495   *   @param {String} fn.key Key of the current property.
3496   *   @param {Object} fn.obj Object being enumerated.
3497   * @param {Object} [thisObj] `this` object to use when calling _fn_.
3498   * @param {Boolean} [proto=false] Include prototype properties.
3499   * @return {YUI} the YUI instance.
3500   * @chainable
3501   * @static
3502   */
3503  O.each = function (obj, fn, thisObj, proto) {
3504      var key;
3505  
3506      for (key in obj) {
3507          if (proto || owns(obj, key)) {
3508              fn.call(thisObj || Y, obj[key], key, obj);
3509          }
3510      }
3511  
3512      return Y;
3513  };
3514  
3515  /**
3516   * Executes a function on each enumerable property in _obj_, but halts if the
3517   * function returns a truthy value. The function receives the value, the key,
3518   * and the object itself as paramters (in that order).
3519   *
3520   * By default, only properties owned by _obj_ are enumerated. To include
3521   * prototype properties, set the _proto_ parameter to `true`.
3522   *
3523   * @method some
3524   * @param {Object} obj Object to enumerate.
3525   * @param {Function} fn Function to execute on each enumerable property.
3526   *   @param {mixed} fn.value Value of the current property.
3527   *   @param {String} fn.key Key of the current property.
3528   *   @param {Object} fn.obj Object being enumerated.
3529   * @param {Object} [thisObj] `this` object to use when calling _fn_.
3530   * @param {Boolean} [proto=false] Include prototype properties.
3531   * @return {Boolean} `true` if any execution of _fn_ returns a truthy value,
3532   *   `false` otherwise.
3533   * @static
3534   */
3535  O.some = function (obj, fn, thisObj, proto) {
3536      var key;
3537  
3538      for (key in obj) {
3539          if (proto || owns(obj, key)) {
3540              if (fn.call(thisObj || Y, obj[key], key, obj)) {
3541                  return true;
3542              }
3543          }
3544      }
3545  
3546      return false;
3547  };
3548  
3549  /**
3550   * Retrieves the sub value at the provided path,
3551   * from the value object provided.
3552   *
3553   * @method getValue
3554   * @static
3555   * @param o The object from which to extract the property value.
3556   * @param path {Array} A path array, specifying the object traversal path
3557   * from which to obtain the sub value.
3558   * @return {Any} The value stored in the path, undefined if not found,
3559   * undefined if the source is not an object.  Returns the source object
3560   * if an empty path is provided.
3561   */
3562  O.getValue = function(o, path) {
3563      if (!Lang.isObject(o)) {
3564          return UNDEFINED;
3565      }
3566  
3567      var i,
3568          p = Y.Array(path),
3569          l = p.length;
3570  
3571      for (i = 0; o !== UNDEFINED && i < l; i++) {
3572          o = o[p[i]];
3573      }
3574  
3575      return o;
3576  };
3577  
3578  /**
3579   * Sets the sub-attribute value at the provided path on the
3580   * value object.  Returns the modified value object, or
3581   * undefined if the path is invalid.
3582   *
3583   * @method setValue
3584   * @static
3585   * @param o             The object on which to set the sub value.
3586   * @param path {Array}  A path array, specifying the object traversal path
3587   *                      at which to set the sub value.
3588   * @param val {Any}     The new value for the sub-attribute.
3589   * @return {Object}     The modified object, with the new sub value set, or
3590   *                      undefined, if the path was invalid.
3591   */
3592  O.setValue = function(o, path, val) {
3593      var i,
3594          p = Y.Array(path),
3595          leafIdx = p.length - 1,
3596          ref = o;
3597  
3598      if (leafIdx >= 0) {
3599          for (i = 0; ref !== UNDEFINED && i < leafIdx; i++) {
3600              ref = ref[p[i]];
3601          }
3602  
3603          if (ref !== UNDEFINED) {
3604              ref[p[i]] = val;
3605          } else {
3606              return UNDEFINED;
3607          }
3608      }
3609  
3610      return o;
3611  };
3612  
3613  /**
3614   * Returns `true` if the object has no enumerable properties of its own.
3615   *
3616   * @method isEmpty
3617   * @param {Object} obj An object.
3618   * @return {Boolean} `true` if the object is empty.
3619   * @static
3620   * @since 3.2.0
3621   */
3622  O.isEmpty = function (obj) {
3623      return !O.keys(Object(obj)).length;
3624  };
3625  /**
3626   * The YUI module contains the components required for building the YUI seed
3627   * file.  This includes the script loading mechanism, a simple queue, and the
3628   * core utilities for the library.
3629   * @module yui
3630   * @submodule yui-base
3631   */
3632  
3633  /**
3634   * YUI user agent detection.
3635   * Do not fork for a browser if it can be avoided.  Use feature detection when
3636   * you can.  Use the user agent as a last resort.  For all fields listed
3637   * as @type float, UA stores a version number for the browser engine,
3638   * 0 otherwise.  This value may or may not map to the version number of
3639   * the browser using the engine.  The value is presented as a float so
3640   * that it can easily be used for boolean evaluation as well as for
3641   * looking for a particular range of versions.  Because of this,
3642   * some of the granularity of the version info may be lost.  The fields that
3643   * are @type string default to null.  The API docs list the values that
3644   * these fields can have.
3645   * @class UA
3646   * @static
3647   */
3648  
3649  /**
3650  * Static method on `YUI.Env` for parsing a UA string.  Called at instantiation
3651  * to populate `Y.UA`.
3652  *
3653  * @static
3654  * @method parseUA
3655  * @param {String} [subUA=navigator.userAgent] UA string to parse
3656  * @return {Object} The Y.UA object
3657  */
3658  YUI.Env.parseUA = function(subUA) {
3659  
3660      var numberify = function(s) {
3661              var c = 0;
3662              return parseFloat(s.replace(/\./g, function() {
3663                  return (c++ === 1) ? '' : '.';
3664              }));
3665          },
3666  
3667          win = Y.config.win,
3668  
3669          nav = win && win.navigator,
3670  
3671          o = {
3672  
3673          /**
3674           * Internet Explorer version number or 0.  Example: 6
3675           * @property ie
3676           * @type float
3677           * @static
3678           */
3679          ie: 0,
3680  
3681          /**
3682           * Opera version number or 0.  Example: 9.2
3683           * @property opera
3684           * @type float
3685           * @static
3686           */
3687          opera: 0,
3688  
3689          /**
3690           * Gecko engine revision number.  Will evaluate to 1 if Gecko
3691           * is detected but the revision could not be found. Other browsers
3692           * will be 0.  Example: 1.8
3693           * <pre>
3694           * Firefox 1.0.0.4: 1.7.8   <-- Reports 1.7
3695           * Firefox 1.5.0.9: 1.8.0.9 <-- 1.8
3696           * Firefox 2.0.0.3: 1.8.1.3 <-- 1.81
3697           * Firefox 3.0   <-- 1.9
3698           * Firefox 3.5   <-- 1.91
3699           * </pre>
3700           * @property gecko
3701           * @type float
3702           * @static
3703           */
3704          gecko: 0,
3705  
3706          /**
3707           * AppleWebKit version.  KHTML browsers that are not WebKit browsers
3708           * will evaluate to 1, other browsers 0.  Example: 418.9
3709           * <pre>
3710           * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the
3711           *                                   latest available for Mac OSX 10.3.
3712           * Safari 2.0.2:         416     <-- hasOwnProperty introduced
3713           * Safari 2.0.4:         418     <-- preventDefault fixed
3714           * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
3715           *                                   different versions of webkit
3716           * Safari 2.0.4 (419.3): 419     <-- Tiger installations that have been
3717           *                                   updated, but not updated
3718           *                                   to the latest patch.
3719           * Webkit 212 nightly:   522+    <-- Safari 3.0 precursor (with native
3720           * SVG and many major issues fixed).
3721           * Safari 3.0.4 (523.12) 523.12  <-- First Tiger release - automatic
3722           * update from 2.x via the 10.4.11 OS patch.
3723           * Webkit nightly 1/2008:525+    <-- Supports DOMContentLoaded event.
3724           *                                   yahoo.com user agent hack removed.
3725           * </pre>
3726           * http://en.wikipedia.org/wiki/Safari_version_history
3727           * @property webkit
3728           * @type float
3729           * @static
3730           */
3731          webkit: 0,
3732  
3733          /**
3734           * Safari will be detected as webkit, but this property will also
3735           * be populated with the Safari version number
3736           * @property safari
3737           * @type float
3738           * @static
3739           */
3740          safari: 0,
3741  
3742          /**
3743           * Chrome will be detected as webkit, but this property will also
3744           * be populated with the Chrome version number
3745           * @property chrome
3746           * @type float
3747           * @static
3748           */
3749          chrome: 0,
3750  
3751          /**
3752           * The mobile property will be set to a string containing any relevant
3753           * user agent information when a modern mobile browser is detected.
3754           * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
3755           * devices with the WebKit-based browser, and Opera Mini.
3756           * @property mobile
3757           * @type string
3758           * @default null
3759           * @static
3760           */
3761          mobile: null,
3762  
3763          /**
3764           * Adobe AIR version number or 0.  Only populated if webkit is detected.
3765           * Example: 1.0
3766           * @property air
3767           * @type float
3768           */
3769          air: 0,
3770          /**
3771           * PhantomJS version number or 0.  Only populated if webkit is detected.
3772           * Example: 1.0
3773           * @property phantomjs
3774           * @type float
3775           */
3776          phantomjs: 0,
3777          /**
3778           * Detects Apple iPad's OS version
3779           * @property ipad
3780           * @type float
3781           * @static
3782           */
3783          ipad: 0,
3784          /**
3785           * Detects Apple iPhone's OS version
3786           * @property iphone
3787           * @type float
3788           * @static
3789           */
3790          iphone: 0,
3791          /**
3792           * Detects Apples iPod's OS version
3793           * @property ipod
3794           * @type float
3795           * @static
3796           */
3797          ipod: 0,
3798          /**
3799           * General truthy check for iPad, iPhone or iPod
3800           * @property ios
3801           * @type Boolean
3802           * @default null
3803           * @static
3804           */
3805          ios: null,
3806          /**
3807           * Detects Googles Android OS version
3808           * @property android
3809           * @type float
3810           * @static
3811           */
3812          android: 0,
3813          /**
3814           * Detects Kindle Silk
3815           * @property silk
3816           * @type float
3817           * @static
3818           */
3819          silk: 0,
3820          /**
3821           * Detects Ubuntu version
3822           * @property ubuntu
3823           * @type float
3824           * @static
3825           */
3826          ubuntu: 0,
3827          /**
3828           * Detects Kindle Silk Acceleration
3829           * @property accel
3830           * @type Boolean
3831           * @static
3832           */
3833          accel: false,
3834          /**
3835           * Detects Palms WebOS version
3836           * @property webos
3837           * @type float
3838           * @static
3839           */
3840          webos: 0,
3841  
3842          /**
3843           * Google Caja version number or 0.
3844           * @property caja
3845           * @type float
3846           */
3847          caja: nav && nav.cajaVersion,
3848  
3849          /**
3850           * Set to true if the page appears to be in SSL
3851           * @property secure
3852           * @type boolean
3853           * @static
3854           */
3855          secure: false,
3856  
3857          /**
3858           * The operating system.  Currently only detecting windows or macintosh
3859           * @property os
3860           * @type string
3861           * @default null
3862           * @static
3863           */
3864          os: null,
3865  
3866          /**
3867           * The Nodejs Version
3868           * @property nodejs
3869           * @type float
3870           * @default 0
3871           * @static
3872           */
3873          nodejs: 0,
3874          /**
3875          * Window8/IE10 Application host environment
3876          * @property winjs
3877          * @type Boolean
3878          * @static
3879          */
3880          winjs: !!((typeof Windows !== "undefined") && Windows.System),
3881          /**
3882          * Are touch/msPointer events available on this device
3883          * @property touchEnabled
3884          * @type Boolean
3885          * @static
3886          */
3887          touchEnabled: false
3888      },
3889  
3890      ua = subUA || nav && nav.userAgent,
3891  
3892      loc = win && win.location,
3893  
3894      href = loc && loc.href,
3895  
3896      m;
3897  
3898      /**
3899      * The User Agent string that was parsed
3900      * @property userAgent
3901      * @type String
3902      * @static
3903      */
3904      o.userAgent = ua;
3905  
3906  
3907      o.secure = href && (href.toLowerCase().indexOf('https') === 0);
3908  
3909      if (ua) {
3910  
3911          if ((/windows|win32/i).test(ua)) {
3912              o.os = 'windows';
3913          } else if ((/macintosh|mac_powerpc/i).test(ua)) {
3914              o.os = 'macintosh';
3915          } else if ((/android/i).test(ua)) {
3916              o.os = 'android';
3917          } else if ((/symbos/i).test(ua)) {
3918              o.os = 'symbos';
3919          } else if ((/linux/i).test(ua)) {
3920              o.os = 'linux';
3921          } else if ((/rhino/i).test(ua)) {
3922              o.os = 'rhino';
3923          }
3924  
3925          // Modern KHTML browsers should qualify as Safari X-Grade
3926          if ((/KHTML/).test(ua)) {
3927              o.webkit = 1;
3928          }
3929          if ((/IEMobile|XBLWP7/).test(ua)) {
3930              o.mobile = 'windows';
3931          }
3932          if ((/Fennec/).test(ua)) {
3933              o.mobile = 'gecko';
3934          }
3935          // Modern WebKit browsers are at least X-Grade
3936          m = ua.match(/AppleWebKit\/([^\s]*)/);
3937          if (m && m[1]) {
3938              o.webkit = numberify(m[1]);
3939              o.safari = o.webkit;
3940  
3941              if (/PhantomJS/.test(ua)) {
3942                  m = ua.match(/PhantomJS\/([^\s]*)/);
3943                  if (m && m[1]) {
3944                      o.phantomjs = numberify(m[1]);
3945                  }
3946              }
3947  
3948              // Mobile browser check
3949              if (/ Mobile\//.test(ua) || (/iPad|iPod|iPhone/).test(ua)) {
3950                  o.mobile = 'Apple'; // iPhone or iPod Touch
3951  
3952                  m = ua.match(/OS ([^\s]*)/);
3953                  if (m && m[1]) {
3954                      m = numberify(m[1].replace('_', '.'));
3955                  }
3956                  o.ios = m;
3957                  o.os = 'ios';
3958                  o.ipad = o.ipod = o.iphone = 0;
3959  
3960                  m = ua.match(/iPad|iPod|iPhone/);
3961                  if (m && m[0]) {
3962                      o[m[0].toLowerCase()] = o.ios;
3963                  }
3964              } else {
3965                  m = ua.match(/NokiaN[^\/]*|webOS\/\d\.\d/);
3966                  if (m) {
3967                      // Nokia N-series, webOS, ex: NokiaN95
3968                      o.mobile = m[0];
3969                  }
3970                  if (/webOS/.test(ua)) {
3971                      o.mobile = 'WebOS';
3972                      m = ua.match(/webOS\/([^\s]*);/);
3973                      if (m && m[1]) {
3974                          o.webos = numberify(m[1]);
3975                      }
3976                  }
3977                  if (/ Android/.test(ua)) {
3978                      if (/Mobile/.test(ua)) {
3979                          o.mobile = 'Android';
3980                      }
3981                      m = ua.match(/Android ([^\s]*);/);
3982                      if (m && m[1]) {
3983                          o.android = numberify(m[1]);
3984                      }
3985  
3986                  }
3987                  if (/Silk/.test(ua)) {
3988                      m = ua.match(/Silk\/([^\s]*)/);
3989                      if (m && m[1]) {
3990                          o.silk = numberify(m[1]);
3991                      }
3992                      if (!o.android) {
3993                          o.android = 2.34; //Hack for desktop mode in Kindle
3994                          o.os = 'Android';
3995                      }
3996                      if (/Accelerated=true/.test(ua)) {
3997                          o.accel = true;
3998                      }
3999                  }
4000              }
4001  
4002              m = ua.match(/OPR\/(\d+\.\d+)/);
4003  
4004              if (m && m[1]) {
4005                  // Opera 15+ with Blink (pretends to be both Chrome and Safari)
4006                  o.opera = numberify(m[1]);
4007              } else {
4008                  m = ua.match(/(Chrome|CrMo|CriOS)\/([^\s]*)/);
4009  
4010                  if (m && m[1] && m[2]) {
4011                      o.chrome = numberify(m[2]); // Chrome
4012                      o.safari = 0; //Reset safari back to 0
4013                      if (m[1] === 'CrMo') {
4014                          o.mobile = 'chrome';
4015                      }
4016                  } else {
4017                      m = ua.match(/AdobeAIR\/([^\s]*)/);
4018                      if (m) {
4019                          o.air = m[0]; // Adobe AIR 1.0 or better
4020                      }
4021                  }
4022              }
4023          }
4024  
4025          m = ua.match(/Ubuntu\ (\d+\.\d+)/);
4026          if (m && m[1]) {
4027  
4028              o.os = 'linux';
4029              o.ubuntu = numberify(m[1]);
4030  
4031              m = ua.match(/\ WebKit\/([^\s]*)/);
4032              if (m && m[1]) {
4033                  o.webkit = numberify(m[1]);
4034              }
4035              m = ua.match(/\ Chromium\/([^\s]*)/);
4036              if (m && m[1]) {
4037                  o.chrome = numberify(m[1]);
4038              }
4039              if (/ Mobile$/.test(ua)) {
4040                  o.mobile = 'Ubuntu';
4041              }
4042          }
4043  
4044          if (!o.webkit) { // not webkit
4045  // @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
4046              if (/Opera/.test(ua)) {
4047                  m = ua.match(/Opera[\s\/]([^\s]*)/);
4048                  if (m && m[1]) {
4049                      o.opera = numberify(m[1]);
4050                  }
4051                  m = ua.match(/Version\/([^\s]*)/);
4052                  if (m && m[1]) {
4053                      o.opera = numberify(m[1]); // opera 10+
4054                  }
4055  
4056                  if (/Opera Mobi/.test(ua)) {
4057                      o.mobile = 'opera';
4058                      m = ua.replace('Opera Mobi', '').match(/Opera ([^\s]*)/);
4059                      if (m && m[1]) {
4060                          o.opera = numberify(m[1]);
4061                      }
4062                  }
4063                  m = ua.match(/Opera Mini[^;]*/);
4064  
4065                  if (m) {
4066                      o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
4067                  }
4068              } else { // not opera or webkit
4069                  m = ua.match(/MSIE ([^;]*)|Trident.*; rv:([0-9.]+)/);
4070  
4071                  if (m && (m[1] || m[2])) {
4072                      o.ie = numberify(m[1] || m[2]);
4073                  } else { // not opera, webkit, or ie
4074                      m = ua.match(/Gecko\/([^\s]*)/);
4075  
4076                      if (m) {
4077                          o.gecko = 1; // Gecko detected, look for revision
4078                          m = ua.match(/rv:([^\s\)]*)/);
4079                          if (m && m[1]) {
4080                              o.gecko = numberify(m[1]);
4081                              if (/Mobile|Tablet/.test(ua)) {
4082                                  o.mobile = "ffos";
4083                              }
4084                          }
4085                      }
4086                  }
4087              }
4088          }
4089      }
4090  
4091      //Check for known properties to tell if touch events are enabled on this device or if
4092      //the number of MSPointer touchpoints on this device is greater than 0.
4093      if (win && nav && !(o.chrome && o.chrome < 6)) {
4094          o.touchEnabled = (("ontouchstart" in win) || (("msMaxTouchPoints" in nav) && (nav.msMaxTouchPoints > 0)));
4095      }
4096  
4097      //It was a parsed UA, do not assign the global value.
4098      if (!subUA) {
4099  
4100          if (typeof process === 'object') {
4101  
4102              if (process.versions && process.versions.node) {
4103                  //NodeJS
4104                  o.os = process.platform;
4105                  o.nodejs = numberify(process.versions.node);
4106              }
4107          }
4108  
4109          YUI.Env.UA = o;
4110  
4111      }
4112  
4113      return o;
4114  };
4115  
4116  
4117  Y.UA = YUI.Env.UA || YUI.Env.parseUA();
4118  
4119  /**
4120  Performs a simple comparison between two version numbers, accounting for
4121  standard versioning logic such as the fact that "535.8" is a lower version than
4122  "535.24", even though a simple numerical comparison would indicate that it's
4123  greater. Also accounts for cases such as "1.1" vs. "1.1.0", which are
4124  considered equivalent.
4125  
4126  Returns -1 if version _a_ is lower than version _b_, 0 if they're equivalent,
4127  1 if _a_ is higher than _b_.
4128  
4129  Versions may be numbers or strings containing numbers and dots. For example,
4130  both `535` and `"535.8.10"` are acceptable. A version string containing
4131  non-numeric characters, like `"535.8.beta"`, may produce unexpected results.
4132  
4133  @method compareVersions
4134  @param {Number|String} a First version number to compare.
4135  @param {Number|String} b Second version number to compare.
4136  @return -1 if _a_ is lower than _b_, 0 if they're equivalent, 1 if _a_ is
4137      higher than _b_.
4138  **/
4139  Y.UA.compareVersions = function (a, b) {
4140      var aPart, aParts, bPart, bParts, i, len;
4141  
4142      if (a === b) {
4143          return 0;
4144      }
4145  
4146      aParts = (a + '').split('.');
4147      bParts = (b + '').split('.');
4148  
4149      for (i = 0, len = Math.max(aParts.length, bParts.length); i < len; ++i) {
4150          aPart = parseInt(aParts[i], 10);
4151          bPart = parseInt(bParts[i], 10);
4152  
4153          /*jshint expr: true*/
4154          isNaN(aPart) && (aPart = 0);
4155          isNaN(bPart) && (bPart = 0);
4156  
4157          if (aPart < bPart) {
4158              return -1;
4159          }
4160  
4161          if (aPart > bPart) {
4162              return 1;
4163          }
4164      }
4165  
4166      return 0;
4167  };
4168  YUI.Env.aliases = {
4169      "anim": ["anim-base","anim-color","anim-curve","anim-easing","anim-node-plugin","anim-scroll","anim-xy"],
4170      "anim-shape-transform": ["anim-shape"],
4171      "app": ["app-base","app-content","app-transitions","lazy-model-list","model","model-list","model-sync-rest","model-sync-local","router","view","view-node-map"],
4172      "attribute": ["attribute-base","attribute-complex"],
4173      "attribute-events": ["attribute-observable"],
4174      "autocomplete": ["autocomplete-base","autocomplete-sources","autocomplete-list","autocomplete-plugin"],
4175      "axes": ["axis-numeric","axis-category","axis-time","axis-stacked"],
4176      "axes-base": ["axis-numeric-base","axis-category-base","axis-time-base","axis-stacked-base"],
4177      "base": ["base-base","base-pluginhost","base-build"],
4178      "cache": ["cache-base","cache-offline","cache-plugin"],
4179      "charts": ["charts-base"],
4180      "collection": ["array-extras","arraylist","arraylist-add","arraylist-filter","array-invoke"],
4181      "color": ["color-base","color-hsl","color-harmony"],
4182      "controller": ["router"],
4183      "dataschema": ["dataschema-base","dataschema-json","dataschema-xml","dataschema-array","dataschema-text"],
4184      "datasource": ["datasource-local","datasource-io","datasource-get","datasource-function","datasource-cache","datasource-jsonschema","datasource-xmlschema","datasource-arrayschema","datasource-textschema","datasource-polling"],
4185      "datatable": ["datatable-core","datatable-table","datatable-head","datatable-body","datatable-base","datatable-column-widths","datatable-message","datatable-mutable","datatable-sort","datatable-datasource"],
4186      "datatype": ["datatype-date","datatype-number","datatype-xml"],
4187      "datatype-date": ["datatype-date-parse","datatype-date-format","datatype-date-math"],
4188      "datatype-number": ["datatype-number-parse","datatype-number-format"],
4189      "datatype-xml": ["datatype-xml-parse","datatype-xml-format"],
4190      "dd": ["dd-ddm-base","dd-ddm","dd-ddm-drop","dd-drag","dd-proxy","dd-constrain","dd-drop","dd-scroll","dd-delegate"],
4191      "dom": ["dom-base","dom-screen","dom-style","selector-native","selector"],
4192      "editor": ["frame","editor-selection","exec-command","editor-base","editor-para","editor-br","editor-bidi","editor-tab","createlink-base"],
4193      "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"],
4194      "event-custom": ["event-custom-base","event-custom-complex"],
4195      "event-gestures": ["event-flick","event-move"],
4196      "handlebars": ["handlebars-compiler"],
4197      "highlight": ["highlight-base","highlight-accentfold"],
4198      "history": ["history-base","history-hash","history-html5"],
4199      "io": ["io-base","io-xdr","io-form","io-upload-iframe","io-queue"],
4200      "json": ["json-parse","json-stringify"],
4201      "loader": ["loader-base","loader-rollup","loader-yui3"],
4202      "node": ["node-base","node-event-delegate","node-pluginhost","node-screen","node-style"],
4203      "pluginhost": ["pluginhost-base","pluginhost-config"],
4204      "querystring": ["querystring-parse","querystring-stringify"],
4205      "recordset": ["recordset-base","recordset-sort","recordset-filter","recordset-indexer"],
4206      "resize": ["resize-base","resize-proxy","resize-constrain"],
4207      "slider": ["slider-base","slider-value-range","clickable-rail","range-slider"],
4208      "template": ["template-base","template-micro"],
4209      "text": ["text-accentfold","text-wordbreak"],
4210      "widget": ["widget-base","widget-htmlparser","widget-skin","widget-uievents"]
4211  };
4212  
4213  
4214  }, '3.17.2', {
4215      "use": [
4216          "yui-base",
4217          "get",
4218          "features",
4219          "intl-base",
4220          "yui-log",
4221          "yui-later",
4222          "loader-base",
4223          "loader-rollup",
4224          "loader-yui3"
4225      ]
4226  });
4227  YUI.add('get', function (Y, NAME) {
4228  
4229  /*jslint boss:true, expr:true, laxbreak: true */
4230  
4231  /**
4232  Provides dynamic loading of remote JavaScript and CSS resources.
4233  
4234  @module get
4235  @class Get
4236  @static
4237  **/
4238  
4239  var Lang = Y.Lang,
4240  
4241      CUSTOM_ATTRS, // defined lazily in Y.Get.Transaction._createNode()
4242  
4243      Get, Transaction;
4244  
4245  Y.Get = Get = {
4246      // -- Public Properties ----------------------------------------------------
4247  
4248      /**
4249      Default options for CSS requests. Options specified here will override
4250      global defaults for CSS requests.
4251  
4252      See the `options` property for all available options.
4253  
4254      @property cssOptions
4255      @type Object
4256      @static
4257      @since 3.5.0
4258      **/
4259      cssOptions: {
4260          attributes: {
4261              rel: 'stylesheet'
4262          },
4263  
4264          doc         : Y.config.linkDoc || Y.config.doc,
4265          pollInterval: 50
4266      },
4267  
4268      /**
4269      Default options for JS requests. Options specified here will override global
4270      defaults for JS requests.
4271  
4272      See the `options` property for all available options.
4273  
4274      @property jsOptions
4275      @type Object
4276      @static
4277      @since 3.5.0
4278      **/
4279      jsOptions: {
4280          autopurge: true,
4281          doc      : Y.config.scriptDoc || Y.config.doc
4282      },
4283  
4284      /**
4285      Default options to use for all requests.
4286  
4287      Note that while all available options are documented here for ease of
4288      discovery, some options (like callback functions) only make sense at the
4289      transaction level.
4290  
4291      Callback functions specified via the options object or the `options`
4292      parameter of the `css()`, `js()`, or `load()` methods will receive the
4293      transaction object as a parameter. See `Y.Get.Transaction` for details on
4294      the properties and methods available on transactions.
4295  
4296      @static
4297      @since 3.5.0
4298      @property {Object} options
4299  
4300      @property {Boolean} [options.async=false] Whether or not to load scripts
4301          asynchronously, meaning they're requested in parallel and execution
4302          order is not guaranteed. Has no effect on CSS, since CSS is always
4303          loaded asynchronously.
4304  
4305      @property {Object} [options.attributes] HTML attribute name/value pairs that
4306          should be added to inserted nodes. By default, the `charset` attribute
4307          will be set to "utf-8" and nodes will be given an auto-generated `id`
4308          attribute, but you can override these with your own values if desired.
4309  
4310      @property {Boolean} [options.autopurge] Whether or not to automatically
4311          purge inserted nodes after the purge threshold is reached. This is
4312          `true` by default for JavaScript, but `false` for CSS since purging a
4313          CSS node will also remove any styling applied by the referenced file.
4314  
4315      @property {Object} [options.context] `this` object to use when calling
4316          callback functions. Defaults to the transaction object.
4317  
4318      @property {Mixed} [options.data] Arbitrary data object to pass to "on*"
4319          callbacks.
4320  
4321      @property {Document} [options.doc] Document into which nodes should be
4322          inserted. By default, the current document is used.
4323  
4324      @property {HTMLElement|String} [options.insertBefore] HTML element or id
4325          string of an element before which all generated nodes should be
4326          inserted. If not specified, Get will automatically determine the best
4327          place to insert nodes for maximum compatibility.
4328  
4329      @property {Function} [options.onEnd] Callback to execute after a transaction
4330          is complete, regardless of whether it succeeded or failed.
4331  
4332      @property {Function} [options.onFailure] Callback to execute after a
4333          transaction fails, times out, or is aborted.
4334  
4335      @property {Function} [options.onProgress] Callback to execute after each
4336          individual request in a transaction either succeeds or fails.
4337  
4338      @property {Function} [options.onSuccess] Callback to execute after a
4339          transaction completes successfully with no errors. Note that in browsers
4340          that don't support the `error` event on CSS `<link>` nodes, a failed CSS
4341          request may still be reported as a success because in these browsers
4342          it can be difficult or impossible to distinguish between success and
4343          failure for CSS resources.
4344  
4345      @property {Function} [options.onTimeout] Callback to execute after a
4346          transaction times out.
4347  
4348      @property {Number} [options.pollInterval=50] Polling interval (in
4349          milliseconds) for detecting CSS load completion in browsers that don't
4350          support the `load` event on `<link>` nodes. This isn't used for
4351          JavaScript.
4352  
4353      @property {Number} [options.purgethreshold=20] Number of nodes to insert
4354          before triggering an automatic purge when `autopurge` is `true`.
4355  
4356      @property {Number} [options.timeout] Number of milliseconds to wait before
4357          aborting a transaction. When a timeout occurs, the `onTimeout` callback
4358          is called, followed by `onFailure` and finally `onEnd`. By default,
4359          there is no timeout.
4360  
4361      @property {String} [options.type] Resource type ("css" or "js"). This option
4362          is set automatically by the `css()` and `js()` functions and will be
4363          ignored there, but may be useful when using the `load()` function. If
4364          not specified, the type will be inferred from the URL, defaulting to
4365          "js" if the URL doesn't contain a recognizable file extension.
4366      **/
4367      options: {
4368          attributes: {
4369              charset: 'utf-8'
4370          },
4371  
4372          purgethreshold: 20
4373      },
4374  
4375      // -- Protected Properties -------------------------------------------------
4376  
4377      /**
4378      Regex that matches a CSS URL. Used to guess the file type when it's not
4379      specified.
4380  
4381      @property REGEX_CSS
4382      @type RegExp
4383      @final
4384      @protected
4385      @static
4386      @since 3.5.0
4387      **/
4388      REGEX_CSS: /\.css(?:[?;].*)?$/i,
4389  
4390      /**
4391      Regex that matches a JS URL. Used to guess the file type when it's not
4392      specified.
4393  
4394      @property REGEX_JS
4395      @type RegExp
4396      @final
4397      @protected
4398      @static
4399      @since 3.5.0
4400      **/
4401      REGEX_JS : /\.js(?:[?;].*)?$/i,
4402  
4403      /**
4404      Contains information about the current environment, such as what script and
4405      link injection features it supports.
4406  
4407      This object is created and populated the first time the `_getEnv()` method
4408      is called.
4409  
4410      @property _env
4411      @type Object
4412      @protected
4413      @static
4414      @since 3.5.0
4415      **/
4416  
4417      /**
4418      Mapping of document _yuid strings to <head> or <base> node references so we
4419      don't have to look the node up each time we want to insert a request node.
4420  
4421      @property _insertCache
4422      @type Object
4423      @protected
4424      @static
4425      @since 3.5.0
4426      **/
4427      _insertCache: {},
4428  
4429      /**
4430      Information about the currently pending transaction, if any.
4431  
4432      This is actually an object with two properties: `callback`, containing the
4433      optional callback passed to `css()`, `load()`, or `js()`; and `transaction`,
4434      containing the actual transaction instance.
4435  
4436      @property _pending
4437      @type Object
4438      @protected
4439      @static
4440      @since 3.5.0
4441      **/
4442      _pending: null,
4443  
4444      /**
4445      HTML nodes eligible to be purged next time autopurge is triggered.
4446  
4447      @property _purgeNodes
4448      @type HTMLElement[]
4449      @protected
4450      @static
4451      @since 3.5.0
4452      **/
4453      _purgeNodes: [],
4454  
4455      /**
4456      Queued transactions and associated callbacks.
4457  
4458      @property _queue
4459      @type Object[]
4460      @protected
4461      @static
4462      @since 3.5.0
4463      **/
4464      _queue: [],
4465  
4466      // -- Public Methods -------------------------------------------------------
4467  
4468      /**
4469      Aborts the specified transaction.
4470  
4471      This will cause the transaction's `onFailure` callback to be called and
4472      will prevent any new script and link nodes from being added to the document,
4473      but any resources that have already been requested will continue loading
4474      (there's no safe way to prevent this, unfortunately).
4475  
4476      *Note:* This method is deprecated as of 3.5.0, and will be removed in a
4477      future version of YUI. Use the transaction-level `abort()` method instead.
4478  
4479      @method abort
4480      @param {Get.Transaction} transaction Transaction to abort.
4481      @deprecated Use the `abort()` method on the transaction instead.
4482      @static
4483      **/
4484      abort: function (transaction) {
4485          var i, id, item, len, pending;
4486  
4487          Y.log('`Y.Get.abort()` is deprecated as of 3.5.0. Use the `abort()` method on the transaction instead.', 'warn', 'get');
4488  
4489          if (!transaction.abort) {
4490              id          = transaction;
4491              pending     = this._pending;
4492              transaction = null;
4493  
4494              if (pending && pending.transaction.id === id) {
4495                  transaction   = pending.transaction;
4496                  this._pending = null;
4497              } else {
4498                  for (i = 0, len = this._queue.length; i < len; ++i) {
4499                      item = this._queue[i].transaction;
4500  
4501                      if (item.id === id) {
4502                          transaction = item;
4503                          this._queue.splice(i, 1);
4504                          break;
4505                      }
4506                  }
4507              }
4508          }
4509  
4510          transaction && transaction.abort();
4511      },
4512  
4513      /**
4514      Loads one or more CSS files.
4515  
4516      The _urls_ parameter may be provided as a URL string, a request object,
4517      or an array of URL strings and/or request objects.
4518  
4519      A request object is just an object that contains a `url` property and zero
4520      or more options that should apply specifically to that request.
4521      Request-specific options take priority over transaction-level options and
4522      default options.
4523  
4524      URLs may be relative or absolute, and do not have to have the same origin
4525      as the current page.
4526  
4527      The `options` parameter may be omitted completely and a callback passed in
4528      its place, if desired.
4529  
4530      @example
4531  
4532          // Load a single CSS file and log a message on completion.
4533          Y.Get.css('foo.css', function (err) {
4534              if (err) {
4535                  Y.log('foo.css failed to load!');
4536              } else {
4537                  Y.log('foo.css was loaded successfully');
4538              }
4539          });
4540  
4541          // Load multiple CSS files and log a message when all have finished
4542          // loading.
4543          var urls = ['foo.css', 'http://example.com/bar.css', 'baz/quux.css'];
4544  
4545          Y.Get.css(urls, function (err) {
4546              if (err) {
4547                  Y.log('one or more files failed to load!');
4548              } else {
4549                  Y.log('all files loaded successfully');
4550              }
4551          });
4552  
4553          // Specify transaction-level options, which will apply to all requests
4554          // within the transaction.
4555          Y.Get.css(urls, {
4556              attributes: {'class': 'my-css'},
4557              timeout   : 5000
4558          });
4559  
4560          // Specify per-request options, which override transaction-level and
4561          // default options.
4562          Y.Get.css([
4563              {url: 'foo.css', attributes: {id: 'foo'}},
4564              {url: 'bar.css', attributes: {id: 'bar', charset: 'iso-8859-1'}}
4565          ]);
4566  
4567      @method css
4568      @param {String|Object|Array} urls URL string, request object, or array
4569          of URLs and/or request objects to load.
4570      @param {Object} [options] Options for this transaction. See the
4571          `Y.Get.options` property for a complete list of available options.
4572      @param {Function} [callback] Callback function to be called on completion.
4573          This is a general callback and will be called before any more granular
4574          callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
4575          object.
4576  
4577          @param {Array|null} callback.err Array of errors that occurred during
4578              the transaction, or `null` on success.
4579          @param {Get.Transaction} callback.transaction Transaction object.
4580  
4581      @return {Get.Transaction} Transaction object.
4582      @static
4583      **/
4584      css: function (urls, options, callback) {
4585          return this._load('css', urls, options, callback);
4586      },
4587  
4588      /**
4589      Loads one or more JavaScript resources.
4590  
4591      The _urls_ parameter may be provided as a URL string, a request object,
4592      or an array of URL strings and/or request objects.
4593  
4594      A request object is just an object that contains a `url` property and zero
4595      or more options that should apply specifically to that request.
4596      Request-specific options take priority over transaction-level options and
4597      default options.
4598  
4599      URLs may be relative or absolute, and do not have to have the same origin
4600      as the current page.
4601  
4602      The `options` parameter may be omitted completely and a callback passed in
4603      its place, if desired.
4604  
4605      Scripts will be executed in the order they're specified unless the `async`
4606      option is `true`, in which case they'll be loaded in parallel and executed
4607      in whatever order they finish loading.
4608  
4609      @example
4610  
4611          // Load a single JS file and log a message on completion.
4612          Y.Get.js('foo.js', function (err) {
4613              if (err) {
4614                  Y.log('foo.js failed to load!');
4615              } else {
4616                  Y.log('foo.js was loaded successfully');
4617              }
4618          });
4619  
4620          // Load multiple JS files, execute them in order, and log a message when
4621          // all have finished loading.
4622          var urls = ['foo.js', 'http://example.com/bar.js', 'baz/quux.js'];
4623  
4624          Y.Get.js(urls, function (err) {
4625              if (err) {
4626                  Y.log('one or more files failed to load!');
4627              } else {
4628                  Y.log('all files loaded successfully');
4629              }
4630          });
4631  
4632          // Specify transaction-level options, which will apply to all requests
4633          // within the transaction.
4634          Y.Get.js(urls, {
4635              attributes: {'class': 'my-js'},
4636              timeout   : 5000
4637          });
4638  
4639          // Specify per-request options, which override transaction-level and
4640          // default options.
4641          Y.Get.js([
4642              {url: 'foo.js', attributes: {id: 'foo'}},
4643              {url: 'bar.js', attributes: {id: 'bar', charset: 'iso-8859-1'}}
4644          ]);
4645  
4646      @method js
4647      @param {String|Object|Array} urls URL string, request object, or array
4648          of URLs and/or request objects to load.
4649      @param {Object} [options] Options for this transaction. See the
4650          `Y.Get.options` property for a complete list of available options.
4651      @param {Function} [callback] Callback function to be called on completion.
4652          This is a general callback and will be called before any more granular
4653          callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
4654          object.
4655  
4656          @param {Array|null} callback.err Array of errors that occurred during
4657              the transaction, or `null` on success.
4658          @param {Get.Transaction} callback.transaction Transaction object.
4659  
4660      @return {Get.Transaction} Transaction object.
4661      @since 3.5.0
4662      @static
4663      **/
4664      js: function (urls, options, callback) {
4665          return this._load('js', urls, options, callback);
4666      },
4667  
4668      /**
4669      Loads one or more CSS and/or JavaScript resources in the same transaction.
4670  
4671      Use this method when you want to load both CSS and JavaScript in a single
4672      transaction and be notified when all requested URLs have finished loading,
4673      regardless of type.
4674  
4675      Behavior and options are the same as for the `css()` and `js()` methods. If
4676      a resource type isn't specified in per-request options or transaction-level
4677      options, Get will guess the file type based on the URL's extension (`.css`
4678      or `.js`, with or without a following query string). If the file type can't
4679      be guessed from the URL, a warning will be logged and Get will assume the
4680      URL is a JavaScript resource.
4681  
4682      @example
4683  
4684          // Load both CSS and JS files in a single transaction, and log a message
4685          // when all files have finished loading.
4686          Y.Get.load(['foo.css', 'bar.js', 'baz.css'], function (err) {
4687              if (err) {
4688                  Y.log('one or more files failed to load!');
4689              } else {
4690                  Y.log('all files loaded successfully');
4691              }
4692          });
4693  
4694      @method load
4695      @param {String|Object|Array} urls URL string, request object, or array
4696          of URLs and/or request objects to load.
4697      @param {Object} [options] Options for this transaction. See the
4698          `Y.Get.options` property for a complete list of available options.
4699      @param {Function} [callback] Callback function to be called on completion.
4700          This is a general callback and will be called before any more granular
4701          callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
4702          object.
4703  
4704          @param {Array|null} err Array of errors that occurred during the
4705              transaction, or `null` on success.
4706          @param {Get.Transaction} Transaction object.
4707  
4708      @return {Get.Transaction} Transaction object.
4709      @since 3.5.0
4710      @static
4711      **/
4712      load: function (urls, options, callback) {
4713          return this._load(null, urls, options, callback);
4714      },
4715  
4716      // -- Protected Methods ----------------------------------------------------
4717  
4718      /**
4719      Triggers an automatic purge if the purge threshold has been reached.
4720  
4721      @method _autoPurge
4722      @param {Number} threshold Purge threshold to use, in milliseconds.
4723      @protected
4724      @since 3.5.0
4725      @static
4726      **/
4727      _autoPurge: function (threshold) {
4728          if (threshold && this._purgeNodes.length >= threshold) {
4729              Y.log('autopurge triggered after ' + this._purgeNodes.length + ' nodes', 'info', 'get');
4730              this._purge(this._purgeNodes);
4731          }
4732      },
4733  
4734      /**
4735      Populates the `_env` property with information about the current
4736      environment.
4737  
4738      @method _getEnv
4739      @return {Object} Environment information.
4740      @protected
4741      @since 3.5.0
4742      @static
4743      **/
4744      _getEnv: function () {
4745          var doc = Y.config.doc,
4746              ua  = Y.UA;
4747  
4748          // Note: some of these checks require browser sniffs since it's not
4749          // feasible to load test files on every pageview just to perform a
4750          // feature test. I'm sorry if this makes you sad.
4751          return (this._env = {
4752  
4753              // True if this is a browser that supports disabling async mode on
4754              // dynamically created script nodes. See
4755              // https://developer.mozilla.org/En/HTML/Element/Script#Attributes
4756  
4757              // IE10 doesn't return true for the MDN feature test, so setting it explicitly,
4758              // because it is async by default, and allows you to disable async by setting it to false
4759              async: (doc && doc.createElement('script').async === true) || (ua.ie >= 10),
4760  
4761              // True if this browser fires an event when a dynamically injected
4762              // link node fails to load. This is currently true for Firefox 9+
4763              // and WebKit 535.24+
4764              cssFail: ua.gecko >= 9 || ua.compareVersions(ua.webkit, 535.24) >= 0,
4765  
4766              // True if this browser fires an event when a dynamically injected
4767              // link node finishes loading. This is currently true for IE, Opera,
4768              // Firefox 9+, and WebKit 535.24+. Note that IE versions <9 fire the
4769              // DOM 0 "onload" event, but not "load". All versions of IE fire
4770              // "onload".
4771              // davglass: Seems that Chrome on Android needs this to be false.
4772              cssLoad: (
4773                      (!ua.gecko && !ua.webkit) || ua.gecko >= 9 ||
4774                      ua.compareVersions(ua.webkit, 535.24) >= 0
4775                  ) && !(ua.chrome && ua.chrome <= 18),
4776  
4777              // True if this browser preserves script execution order while
4778              // loading scripts in parallel as long as the script node's `async`
4779              // attribute is set to false to explicitly disable async execution.
4780              preservesScriptOrder: !!(ua.gecko || ua.opera || (ua.ie && ua.ie >= 10))
4781          });
4782      },
4783  
4784      _getTransaction: function (urls, options) {
4785          var requests = [],
4786              i, len, req, url;
4787  
4788          if (!Lang.isArray(urls)) {
4789              urls = [urls];
4790          }
4791  
4792          options = Y.merge(this.options, options);
4793  
4794          // Clone the attributes object so we don't end up modifying it by ref.
4795          options.attributes = Y.merge(this.options.attributes,
4796                  options.attributes);
4797  
4798          for (i = 0, len = urls.length; i < len; ++i) {
4799              url = urls[i];
4800              req = {attributes: {}};
4801  
4802              // If `url` is a string, we create a URL object for it, then mix in
4803              // global options and request-specific options. If it's an object
4804              // with a "url" property, we assume it's a request object containing
4805              // URL-specific options.
4806              if (typeof url === 'string') {
4807                  req.url = url;
4808              } else if (url.url) {
4809                  // URL-specific options override both global defaults and
4810                  // request-specific options.
4811                  Y.mix(req, url, false, null, 0, true);
4812                  url = url.url; // Make url a string so we can use it later.
4813              } else {
4814                  Y.log('URL must be a string or an object with a `url` property.', 'error', 'get');
4815                  continue;
4816              }
4817  
4818              Y.mix(req, options, false, null, 0, true);
4819  
4820              // If we didn't get an explicit type for this URL either in the
4821              // request options or the URL-specific options, try to determine
4822              // one from the file extension.
4823              if (!req.type) {
4824                  if (this.REGEX_CSS.test(url)) {
4825                      req.type = 'css';
4826                  } else {
4827                      if (!this.REGEX_JS.test(url)) {
4828                          Y.log("Can't guess file type from URL. Assuming JS: " + url, 'warn', 'get');
4829                      }
4830  
4831                      req.type = 'js';
4832                  }
4833              }
4834  
4835              // Mix in type-specific default options, but don't overwrite any
4836              // options that have already been set.
4837              Y.mix(req, req.type === 'js' ? this.jsOptions : this.cssOptions,
4838                  false, null, 0, true);
4839  
4840              // Give the node an id attribute if it doesn't already have one.
4841              req.attributes.id || (req.attributes.id = Y.guid());
4842  
4843              // Backcompat for <3.5.0 behavior.
4844              if (req.win) {
4845                  Y.log('The `win` option is deprecated as of 3.5.0. Use `doc` instead.', 'warn', 'get');
4846                  req.doc = req.win.document;
4847              } else {
4848                  req.win = req.doc.defaultView || req.doc.parentWindow;
4849              }
4850  
4851              if (req.charset) {
4852                  Y.log('The `charset` option is deprecated as of 3.5.0. Set `attributes.charset` instead.', 'warn', 'get');
4853                  req.attributes.charset = req.charset;
4854              }
4855  
4856              requests.push(req);
4857          }
4858  
4859          return new Transaction(requests, options);
4860      },
4861  
4862      _load: function (type, urls, options, callback) {
4863          var transaction;
4864  
4865          // Allow callback as third param.
4866          if (typeof options === 'function') {
4867              callback = options;
4868              options  = {};
4869          }
4870  
4871          options || (options = {});
4872          options.type = type;
4873  
4874          options._onFinish = Get._onTransactionFinish;
4875  
4876          if (!this._env) {
4877              this._getEnv();
4878          }
4879  
4880          transaction = this._getTransaction(urls, options);
4881  
4882          this._queue.push({
4883              callback   : callback,
4884              transaction: transaction
4885          });
4886  
4887          this._next();
4888  
4889          return transaction;
4890      },
4891  
4892      _onTransactionFinish : function() {
4893          Get._pending = null;
4894          Get._next();
4895      },
4896  
4897      _next: function () {
4898          var item;
4899  
4900          if (this._pending) {
4901              return;
4902          }
4903  
4904          item = this._queue.shift();
4905  
4906          if (item) {
4907              this._pending = item;
4908              item.transaction.execute(item.callback);
4909          }
4910      },
4911  
4912      _purge: function (nodes) {
4913          var purgeNodes    = this._purgeNodes,
4914              isTransaction = nodes !== purgeNodes,
4915              index, node;
4916  
4917          while (node = nodes.pop()) { // assignment
4918              // Don't purge nodes that haven't finished loading (or errored out),
4919              // since this can hang the transaction.
4920              if (!node._yuiget_finished) {
4921                  continue;
4922              }
4923  
4924              node.parentNode && node.parentNode.removeChild(node);
4925  
4926              // If this is a transaction-level purge and this node also exists in
4927              // the Get-level _purgeNodes array, we need to remove it from
4928              // _purgeNodes to avoid creating a memory leak. The indexOf lookup
4929              // sucks, but until we get WeakMaps, this is the least troublesome
4930              // way to do this (we can't just hold onto node ids because they may
4931              // not be in the same document).
4932              if (isTransaction) {
4933                  index = Y.Array.indexOf(purgeNodes, node);
4934  
4935                  if (index > -1) {
4936                      purgeNodes.splice(index, 1);
4937                  }
4938              }
4939          }
4940      }
4941  };
4942  
4943  /**
4944  Alias for `js()`.
4945  
4946  @method script
4947  @static
4948  **/
4949  Get.script = Get.js;
4950  
4951  /**
4952  Represents a Get transaction, which may contain requests for one or more JS or
4953  CSS files.
4954  
4955  This class should not be instantiated manually. Instances will be created and
4956  returned as needed by Y.Get's `css()`, `js()`, and `load()` methods.
4957  
4958  @class Get.Transaction
4959  @constructor
4960  @since 3.5.0
4961  **/
4962  Get.Transaction = Transaction = function (requests, options) {
4963      var self = this;
4964  
4965      self.id       = Transaction._lastId += 1;
4966      self.data     = options.data;
4967      self.errors   = [];
4968      self.nodes    = [];
4969      self.options  = options;
4970      self.requests = requests;
4971  
4972      self._callbacks = []; // callbacks to call after execution finishes
4973      self._queue     = [];
4974      self._reqsWaiting   = 0;
4975  
4976      // Deprecated pre-3.5.0 properties.
4977      self.tId = self.id; // Use `id` instead.
4978      self.win = options.win || Y.config.win;
4979  };
4980  
4981  /**
4982  Arbitrary data object associated with this transaction.
4983  
4984  This object comes from the options passed to `Get.css()`, `Get.js()`, or
4985  `Get.load()`, and will be `undefined` if no data object was specified.
4986  
4987  @property {Object} data
4988  **/
4989  
4990  /**
4991  Array of errors that have occurred during this transaction, if any. Each error
4992  object has the following properties:
4993  `errors.error`: Error message.
4994  `errors.request`: Request object related to the error.
4995  
4996  @since 3.5.0
4997  @property {Object[]} errors
4998  **/
4999  
5000  /**
5001  Numeric id for this transaction, unique among all transactions within the same
5002  YUI sandbox in the current pageview.
5003  
5004  @property {Number} id
5005  @since 3.5.0
5006  **/
5007  
5008  /**
5009  HTMLElement nodes (native ones, not YUI Node instances) that have been inserted
5010  during the current transaction.
5011  
5012  @property {HTMLElement[]} nodes
5013  **/
5014  
5015  /**
5016  Options associated with this transaction.
5017  
5018  See `Get.options` for the full list of available options.
5019  
5020  @property {Object} options
5021  @since 3.5.0
5022  **/
5023  
5024  /**
5025  Request objects contained in this transaction. Each request object represents
5026  one CSS or JS URL that will be (or has been) requested and loaded into the page.
5027  
5028  @property {Object} requests
5029  @since 3.5.0
5030  **/
5031  
5032  /**
5033  Id of the most recent transaction.
5034  
5035  @property _lastId
5036  @type Number
5037  @protected
5038  @static
5039  **/
5040  Transaction._lastId = 0;
5041  
5042  Transaction.prototype = {
5043      // -- Public Properties ----------------------------------------------------
5044  
5045      /**
5046      Current state of this transaction. One of "new", "executing", or "done".
5047  
5048      @property _state
5049      @type String
5050      @protected
5051      **/
5052      _state: 'new', // "new", "executing", or "done"
5053  
5054      // -- Public Methods -------------------------------------------------------
5055  
5056      /**
5057      Aborts this transaction.
5058  
5059      This will cause the transaction's `onFailure` callback to be called and
5060      will prevent any new script and link nodes from being added to the document,
5061      but any resources that have already been requested will continue loading
5062      (there's no safe way to prevent this, unfortunately).
5063  
5064      @method abort
5065      @param {String} [msg="Aborted."] Optional message to use in the `errors`
5066          array describing why the transaction was aborted.
5067      **/
5068      abort: function (msg) {
5069          this._pending    = null;
5070          this._pendingCSS = null;
5071          this._pollTimer  = clearTimeout(this._pollTimer);
5072          this._queue      = [];
5073          this._reqsWaiting    = 0;
5074  
5075          this.errors.push({error: msg || 'Aborted'});
5076          this._finish();
5077      },
5078  
5079      /**
5080      Begins execting the transaction.
5081  
5082      There's usually no reason to call this manually, since Get will call it
5083      automatically when other pending transactions have finished. If you really
5084      want to execute your transaction before Get does, you can, but be aware that
5085      this transaction's scripts may end up executing before the scripts in other
5086      pending transactions.
5087  
5088      If the transaction is already executing, the specified callback (if any)
5089      will be queued and called after execution finishes. If the transaction has
5090      already finished, the callback will be called immediately (the transaction
5091      will not be executed again).
5092  
5093      @method execute
5094      @param {Function} callback Callback function to execute after all requests
5095          in the transaction are complete, or after the transaction is aborted.
5096      **/
5097      execute: function (callback) {
5098          var self     = this,
5099              requests = self.requests,
5100              state    = self._state,
5101              i, len, queue, req;
5102  
5103          if (state === 'done') {
5104              callback && callback(self.errors.length ? self.errors : null, self);
5105              return;
5106          } else {
5107              callback && self._callbacks.push(callback);
5108  
5109              if (state === 'executing') {
5110                  return;
5111              }
5112          }
5113  
5114          self._state = 'executing';
5115          self._queue = queue = [];
5116  
5117          if (self.options.timeout) {
5118              self._timeout = setTimeout(function () {
5119                  self.abort('Timeout');
5120              }, self.options.timeout);
5121          }
5122  
5123          self._reqsWaiting = requests.length;
5124  
5125          for (i = 0, len = requests.length; i < len; ++i) {
5126              req = requests[i];
5127  
5128              if (req.async || req.type === 'css') {
5129                  // No need to queue CSS or fully async JS.
5130                  self._insert(req);
5131              } else {
5132                  queue.push(req);
5133              }
5134          }
5135  
5136          self._next();
5137      },
5138  
5139      /**
5140      Manually purges any `<script>` or `<link>` nodes this transaction has
5141      created.
5142  
5143      Be careful when purging a transaction that contains CSS requests, since
5144      removing `<link>` nodes will also remove any styles they applied.
5145  
5146      @method purge
5147      **/
5148      purge: function () {
5149          Get._purge(this.nodes);
5150      },
5151  
5152      // -- Protected Methods ----------------------------------------------------
5153      _createNode: function (name, attrs, doc) {
5154          var node = doc.createElement(name),
5155              attr, testEl;
5156  
5157          if (!CUSTOM_ATTRS) {
5158              // IE6 and IE7 expect property names rather than attribute names for
5159              // certain attributes. Rather than sniffing, we do a quick feature
5160              // test the first time _createNode() runs to determine whether we
5161              // need to provide a workaround.
5162              testEl = doc.createElement('div');
5163              testEl.setAttribute('class', 'a');
5164  
5165              CUSTOM_ATTRS = testEl.className === 'a' ? {} : {
5166                  'for'  : 'htmlFor',
5167                  'class': 'className'
5168              };
5169          }
5170  
5171          for (attr in attrs) {
5172              if (attrs.hasOwnProperty(attr)) {
5173                  node.setAttribute(CUSTOM_ATTRS[attr] || attr, attrs[attr]);
5174              }
5175          }
5176  
5177          return node;
5178      },
5179  
5180      _finish: function () {
5181          var errors  = this.errors.length ? this.errors : null,
5182              options = this.options,
5183              thisObj = options.context || this,
5184              data, i, len;
5185  
5186          if (this._state === 'done') {
5187              return;
5188          }
5189  
5190          this._state = 'done';
5191  
5192          for (i = 0, len = this._callbacks.length; i < len; ++i) {
5193              this._callbacks[i].call(thisObj, errors, this);
5194          }
5195  
5196          data = this._getEventData();
5197  
5198          if (errors) {
5199              if (options.onTimeout && errors[errors.length - 1].error === 'Timeout') {
5200                  options.onTimeout.call(thisObj, data);
5201              }
5202  
5203              if (options.onFailure) {
5204                  options.onFailure.call(thisObj, data);
5205              }
5206          } else if (options.onSuccess) {
5207              options.onSuccess.call(thisObj, data);
5208          }
5209  
5210          if (options.onEnd) {
5211              options.onEnd.call(thisObj, data);
5212          }
5213  
5214          if (options._onFinish) {
5215              options._onFinish();
5216          }
5217      },
5218  
5219      _getEventData: function (req) {
5220          if (req) {
5221              // This merge is necessary for backcompat. I hate it.
5222              return Y.merge(this, {
5223                  abort  : this.abort, // have to copy these because the prototype isn't preserved
5224                  purge  : this.purge,
5225                  request: req,
5226                  url    : req.url,
5227                  win    : req.win
5228              });
5229          } else {
5230              return this;
5231          }
5232      },
5233  
5234      _getInsertBefore: function (req) {
5235          var doc = req.doc,
5236              el  = req.insertBefore,
5237              cache, docStamp;
5238  
5239          if (el) {
5240              return typeof el === 'string' ? doc.getElementById(el) : el;
5241          }
5242  
5243          cache    = Get._insertCache;
5244          docStamp = Y.stamp(doc);
5245  
5246          if ((el = cache[docStamp])) { // assignment
5247              return el;
5248          }
5249  
5250          // Inserting before a <base> tag apparently works around an IE bug
5251          // (according to a comment from pre-3.5.0 Y.Get), but I'm not sure what
5252          // bug that is, exactly. Better safe than sorry?
5253          if ((el = doc.getElementsByTagName('base')[0])) { // assignment
5254              return (cache[docStamp] = el);
5255          }
5256  
5257          // Look for a <head> element.
5258          el = doc.head || doc.getElementsByTagName('head')[0];
5259  
5260          if (el) {
5261              // Create a marker node at the end of <head> to use as an insertion
5262              // point. Inserting before this node will ensure that all our CSS
5263              // gets inserted in the correct order, to maintain style precedence.
5264              el.appendChild(doc.createTextNode(''));
5265              return (cache[docStamp] = el.lastChild);
5266          }
5267  
5268          // If all else fails, just insert before the first script node on the
5269          // page, which is virtually guaranteed to exist.
5270          return (cache[docStamp] = doc.getElementsByTagName('script')[0]);
5271      },
5272  
5273      _insert: function (req) {
5274          var env          = Get._env,
5275              insertBefore = this._getInsertBefore(req),
5276              isScript     = req.type === 'js',
5277              node         = req.node,
5278              self         = this,
5279              ua           = Y.UA,
5280              cssTimeout, nodeType;
5281  
5282          if (!node) {
5283              if (isScript) {
5284                  nodeType = 'script';
5285              } else if (!env.cssLoad && ua.gecko) {
5286                  nodeType = 'style';
5287              } else {
5288                  nodeType = 'link';
5289              }
5290  
5291              node = req.node = this._createNode(nodeType, req.attributes,
5292                  req.doc);
5293          }
5294  
5295          function onError() {
5296              self._progress('Failed to load ' + req.url, req);
5297          }
5298  
5299          function onLoad() {
5300              if (cssTimeout) {
5301                  clearTimeout(cssTimeout);
5302              }
5303  
5304              self._progress(null, req);
5305          }
5306  
5307          // Deal with script asynchronicity.
5308          if (isScript) {
5309              node.setAttribute('src', req.url);
5310  
5311              if (req.async) {
5312                  // Explicitly indicate that we want the browser to execute this
5313                  // script asynchronously. This is necessary for older browsers
5314                  // like Firefox <4.
5315                  node.async = true;
5316              } else {
5317                  if (env.async) {
5318                      // This browser treats injected scripts as async by default
5319                      // (standard HTML5 behavior) but asynchronous loading isn't
5320                      // desired, so tell the browser not to mark this script as
5321                      // async.
5322                      node.async = false;
5323                  }
5324  
5325                  // If this browser doesn't preserve script execution order based
5326                  // on insertion order, we'll need to avoid inserting other
5327                  // scripts until this one finishes loading.
5328                  if (!env.preservesScriptOrder) {
5329                      this._pending = req;
5330                  }
5331              }
5332          } else {
5333              if (!env.cssLoad && ua.gecko) {
5334                  // In Firefox <9, we can import the requested URL into a <style>
5335                  // node and poll for the existence of node.sheet.cssRules. This
5336                  // gives us a reliable way to determine CSS load completion that
5337                  // also works for cross-domain stylesheets.
5338                  //
5339                  // Props to Zach Leatherman for calling my attention to this
5340                  // technique.
5341                  node.innerHTML = (req.attributes.charset ?
5342                      '@charset "' + req.attributes.charset + '";' : '') +
5343                      '@import "' + req.url + '";';
5344              } else {
5345                  node.setAttribute('href', req.url);
5346              }
5347          }
5348  
5349          // Inject the node.
5350          if (isScript && ua.ie && (ua.ie < 9 || (document.documentMode && document.documentMode < 9))) {
5351              // Script on IE < 9, and IE 9+ when in IE 8 or older modes, including quirks mode.
5352              node.onreadystatechange = function () {
5353                  if (/loaded|complete/.test(node.readyState)) {
5354                      node.onreadystatechange = null;
5355                      onLoad();
5356                  }
5357              };
5358          } else if (!isScript && !env.cssLoad) {
5359              // CSS on Firefox <9 or WebKit.
5360              this._poll(req);
5361          } else {
5362              // Script or CSS on everything else. Using DOM 0 events because that
5363              // evens the playing field with older IEs.
5364  
5365              if (ua.ie >= 10) {
5366  
5367                  // We currently need to introduce a timeout for IE10, since it
5368                  // calls onerror/onload synchronously for 304s - messing up existing
5369                  // program flow.
5370  
5371                  // Remove this block if the following bug gets fixed by GA
5372                  /*jshint maxlen: 1500 */
5373                  // https://connect.microsoft.com/IE/feedback/details/763871/dynamically-loaded-scripts-with-304s-responses-interrupt-the-currently-executing-js-thread-onload
5374                  node.onerror = function() { setTimeout(onError, 0); };
5375                  node.onload  = function() { setTimeout(onLoad, 0); };
5376              } else {
5377                  node.onerror = onError;
5378                  node.onload  = onLoad;
5379              }
5380  
5381              // If this browser doesn't fire an event when CSS fails to load,
5382              // fail after a timeout to avoid blocking the transaction queue.
5383              if (!env.cssFail && !isScript) {
5384                  cssTimeout = setTimeout(onError, req.timeout || 3000);
5385              }
5386          }
5387  
5388          this.nodes.push(node);
5389          insertBefore.parentNode.insertBefore(node, insertBefore);
5390      },
5391  
5392      _next: function () {
5393          if (this._pending) {
5394              return;
5395          }
5396  
5397          // If there are requests in the queue, insert the next queued request.
5398          // Otherwise, if we're waiting on already-inserted requests to finish,
5399          // wait longer. If there are no queued requests and we're not waiting
5400          // for anything to load, then we're done!
5401          if (this._queue.length) {
5402              this._insert(this._queue.shift());
5403          } else if (!this._reqsWaiting) {
5404              this._finish();
5405          }
5406      },
5407  
5408      _poll: function (newReq) {
5409          var self       = this,
5410              pendingCSS = self._pendingCSS,
5411              isWebKit   = Y.UA.webkit,
5412              i, hasRules, j, nodeHref, req, sheets;
5413  
5414          if (newReq) {
5415              pendingCSS || (pendingCSS = self._pendingCSS = []);
5416              pendingCSS.push(newReq);
5417  
5418              if (self._pollTimer) {
5419                  // A poll timeout is already pending, so no need to create a
5420                  // new one.
5421                  return;
5422              }
5423          }
5424  
5425          self._pollTimer = null;
5426  
5427          // Note: in both the WebKit and Gecko hacks below, a CSS URL that 404s
5428          // will still be treated as a success. There's no good workaround for
5429          // this.
5430  
5431          for (i = 0; i < pendingCSS.length; ++i) {
5432              req = pendingCSS[i];
5433  
5434              if (isWebKit) {
5435                  // Look for a stylesheet matching the pending URL.
5436                  sheets   = req.doc.styleSheets;
5437                  j        = sheets.length;
5438                  nodeHref = req.node.href;
5439  
5440                  while (--j >= 0) {
5441                      if (sheets[j].href === nodeHref) {
5442                          pendingCSS.splice(i, 1);
5443                          i -= 1;
5444                          self._progress(null, req);
5445                          break;
5446                      }
5447                  }
5448              } else {
5449                  // Many thanks to Zach Leatherman for calling my attention to
5450                  // the @import-based cross-domain technique used here, and to
5451                  // Oleg Slobodskoi for an earlier same-domain implementation.
5452                  //
5453                  // See Zach's blog for more details:
5454                  // http://www.zachleat.com/web/2010/07/29/load-css-dynamically/
5455                  try {
5456                      // We don't really need to store this value since we never
5457                      // use it again, but if we don't store it, Closure Compiler
5458                      // assumes the code is useless and removes it.
5459                      hasRules = !!req.node.sheet.cssRules;
5460  
5461                      // If we get here, the stylesheet has loaded.
5462                      pendingCSS.splice(i, 1);
5463                      i -= 1;
5464                      self._progress(null, req);
5465                  } catch (ex) {
5466                      // An exception means the stylesheet is still loading.
5467                  }
5468              }
5469          }
5470  
5471          if (pendingCSS.length) {
5472              self._pollTimer = setTimeout(function () {
5473                  self._poll.call(self);
5474              }, self.options.pollInterval);
5475          }
5476      },
5477  
5478      _progress: function (err, req) {
5479          var options = this.options;
5480  
5481          if (err) {
5482              req.error = err;
5483  
5484              this.errors.push({
5485                  error  : err,
5486                  request: req
5487              });
5488  
5489              Y.log(err, 'error', 'get');
5490          }
5491  
5492          req.node._yuiget_finished = req.finished = true;
5493  
5494          if (options.onProgress) {
5495              options.onProgress.call(options.context || this,
5496                  this._getEventData(req));
5497          }
5498  
5499          if (req.autopurge) {
5500              // Pre-3.5.0 Get always excludes the most recent node from an
5501              // autopurge. I find this odd, but I'm keeping that behavior for
5502              // the sake of backcompat.
5503              Get._autoPurge(this.options.purgethreshold);
5504              Get._purgeNodes.push(req.node);
5505          }
5506  
5507          if (this._pending === req) {
5508              this._pending = null;
5509          }
5510  
5511          this._reqsWaiting -= 1;
5512  
5513          this._next();
5514      }
5515  };
5516  
5517  
5518  }, '3.17.2', {"requires": ["yui-base"]});
5519  YUI.add('features', function (Y, NAME) {
5520  
5521  var feature_tests = {};
5522  
5523  /**
5524  Contains the core of YUI's feature test architecture.
5525  @module features
5526  */
5527  
5528  /**
5529  * Feature detection
5530  * @class Features
5531  * @static
5532  */
5533  
5534  Y.mix(Y.namespace('Features'), {
5535  
5536      /**
5537      * Object hash of all registered feature tests
5538      * @property tests
5539      * @type Object
5540      */
5541      tests: feature_tests,
5542  
5543      /**
5544      * Add a test to the system
5545      *
5546      *   ```
5547      *   Y.Features.add("load", "1", {});
5548      *   ```
5549      *
5550      * @method add
5551      * @param {String} cat The category, right now only 'load' is supported
5552      * @param {String} name The number sequence of the test, how it's reported in the URL or config: 1, 2, 3
5553      * @param {Object} o Object containing test properties
5554      * @param {String} o.name The name of the test
5555      * @param {Function} o.test The test function to execute, the only argument to the function is the `Y` instance
5556      * @param {String} o.trigger The module that triggers this test.
5557      */
5558      add: function(cat, name, o) {
5559          feature_tests[cat] = feature_tests[cat] || {};
5560          feature_tests[cat][name] = o;
5561      },
5562      /**
5563      * Execute all tests of a given category and return the serialized results
5564      *
5565      *   ```
5566      *   caps=1:1;2:1;3:0
5567      *   ```
5568      * @method all
5569      * @param {String} cat The category to execute
5570      * @param {Array} args The arguments to pass to the test function
5571      * @return {String} A semi-colon separated string of tests and their success/failure: 1:1;2:1;3:0
5572      */
5573      all: function(cat, args) {
5574          var cat_o = feature_tests[cat],
5575              // results = {};
5576              result = [];
5577          if (cat_o) {
5578              Y.Object.each(cat_o, function(v, k) {
5579                  result.push(k + ':' + (Y.Features.test(cat, k, args) ? 1 : 0));
5580              });
5581          }
5582  
5583          return (result.length) ? result.join(';') : '';
5584      },
5585      /**
5586      * Run a specific test and return a Boolean response.
5587      *
5588      *   ```
5589      *   Y.Features.test("load", "1");
5590      *   ```
5591      *
5592      * @method test
5593      * @param {String} cat The category of the test to run
5594      * @param {String} name The name of the test to run
5595      * @param {Array} args The arguments to pass to the test function
5596      * @return {Boolean} True or false if the test passed/failed.
5597      */
5598      test: function(cat, name, args) {
5599          args = args || [];
5600          var result, ua, test,
5601              cat_o = feature_tests[cat],
5602              feature = cat_o && cat_o[name];
5603  
5604          if (!feature) {
5605              Y.log('Feature test ' + cat + ', ' + name + ' not found');
5606          } else {
5607  
5608              result = feature.result;
5609  
5610              if (Y.Lang.isUndefined(result)) {
5611  
5612                  ua = feature.ua;
5613                  if (ua) {
5614                      result = (Y.UA[ua]);
5615                  }
5616  
5617                  test = feature.test;
5618                  if (test && ((!ua) || result)) {
5619                      result = test.apply(Y, args);
5620                  }
5621  
5622                  feature.result = result;
5623              }
5624          }
5625  
5626          return result;
5627      }
5628  });
5629  
5630  // Y.Features.add("load", "1", {});
5631  // Y.Features.test("load", "1");
5632  // caps=1:1;2:0;3:1;
5633  
5634  /* This file is auto-generated by (yogi.js loader --mix --yes) */
5635  /*jshint maxlen:900, eqeqeq: false */
5636  var add = Y.Features.add;
5637  // app-transitions-native
5638  add('load', '0', {
5639      "name": "app-transitions-native",
5640      "test": function (Y) {
5641      var doc  = Y.config.doc,
5642          node = doc ? doc.documentElement : null;
5643  
5644      if (node && node.style) {
5645          return ('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
5646      }
5647  
5648      return false;
5649  },
5650      "trigger": "app-transitions"
5651  });
5652  // autocomplete-list-keys
5653  add('load', '1', {
5654      "name": "autocomplete-list-keys",
5655      "test": function (Y) {
5656      // Only add keyboard support to autocomplete-list if this doesn't appear to
5657      // be an iOS or Android-based mobile device.
5658      //
5659      // There's currently no feasible way to actually detect whether a device has
5660      // a hardware keyboard, so this sniff will have to do. It can easily be
5661      // overridden by manually loading the autocomplete-list-keys module.
5662      //
5663      // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari
5664      // doesn't fire the keyboard events used by AutoCompleteList, so there's
5665      // no point loading the -keys module even when a bluetooth keyboard may be
5666      // available.
5667      return !(Y.UA.ios || Y.UA.android);
5668  },
5669      "trigger": "autocomplete-list"
5670  });
5671  // dd-gestures
5672  add('load', '2', {
5673      "name": "dd-gestures",
5674      "trigger": "dd-drag",
5675      "ua": "touchEnabled"
5676  });
5677  // dom-style-ie
5678  add('load', '3', {
5679      "name": "dom-style-ie",
5680      "test": function (Y) {
5681  
5682      var testFeature = Y.Features.test,
5683          addFeature = Y.Features.add,
5684          WINDOW = Y.config.win,
5685          DOCUMENT = Y.config.doc,
5686          DOCUMENT_ELEMENT = 'documentElement',
5687          ret = false;
5688  
5689      addFeature('style', 'computedStyle', {
5690          test: function() {
5691              return WINDOW && 'getComputedStyle' in WINDOW;
5692          }
5693      });
5694  
5695      addFeature('style', 'opacity', {
5696          test: function() {
5697              return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style;
5698          }
5699      });
5700  
5701      ret =  (!testFeature('style', 'opacity') &&
5702              !testFeature('style', 'computedStyle'));
5703  
5704      return ret;
5705  },
5706      "trigger": "dom-style"
5707  });
5708  // editor-para-ie
5709  add('load', '4', {
5710      "name": "editor-para-ie",
5711      "trigger": "editor-para",
5712      "ua": "ie",
5713      "when": "instead"
5714  });
5715  // event-base-ie
5716  add('load', '5', {
5717      "name": "event-base-ie",
5718      "test": function(Y) {
5719      var imp = Y.config.doc && Y.config.doc.implementation;
5720      return (imp && (!imp.hasFeature('Events', '2.0')));
5721  },
5722      "trigger": "node-base"
5723  });
5724  // graphics-canvas
5725  add('load', '6', {
5726      "name": "graphics-canvas",
5727      "test": function(Y) {
5728      var DOCUMENT = Y.config.doc,
5729          useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
5730          canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5731          svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5732      return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
5733  },
5734      "trigger": "graphics"
5735  });
5736  // graphics-canvas-default
5737  add('load', '7', {
5738      "name": "graphics-canvas-default",
5739      "test": function(Y) {
5740      var DOCUMENT = Y.config.doc,
5741          useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
5742          canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5743          svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5744      return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
5745  },
5746      "trigger": "graphics"
5747  });
5748  // graphics-svg
5749  add('load', '8', {
5750      "name": "graphics-svg",
5751      "test": function(Y) {
5752      var DOCUMENT = Y.config.doc,
5753          useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
5754          canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5755          svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5756      
5757      return svg && (useSVG || !canvas);
5758  },
5759      "trigger": "graphics"
5760  });
5761  // graphics-svg-default
5762  add('load', '9', {
5763      "name": "graphics-svg-default",
5764      "test": function(Y) {
5765      var DOCUMENT = Y.config.doc,
5766          useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
5767          canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5768          svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5769      
5770      return svg && (useSVG || !canvas);
5771  },
5772      "trigger": "graphics"
5773  });
5774  // graphics-vml
5775  add('load', '10', {
5776      "name": "graphics-vml",
5777      "test": function(Y) {
5778      var DOCUMENT = Y.config.doc,
5779          canvas = DOCUMENT && DOCUMENT.createElement("canvas");
5780      return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
5781  },
5782      "trigger": "graphics"
5783  });
5784  // graphics-vml-default
5785  add('load', '11', {
5786      "name": "graphics-vml-default",
5787      "test": function(Y) {
5788      var DOCUMENT = Y.config.doc,
5789          canvas = DOCUMENT && DOCUMENT.createElement("canvas");
5790      return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
5791  },
5792      "trigger": "graphics"
5793  });
5794  // history-hash-ie
5795  add('load', '12', {
5796      "name": "history-hash-ie",
5797      "test": function (Y) {
5798      var docMode = Y.config.doc && Y.config.doc.documentMode;
5799  
5800      return Y.UA.ie && (!('onhashchange' in Y.config.win) ||
5801              !docMode || docMode < 8);
5802  },
5803      "trigger": "history-hash"
5804  });
5805  // io-nodejs
5806  add('load', '13', {
5807      "name": "io-nodejs",
5808      "trigger": "io-base",
5809      "ua": "nodejs"
5810  });
5811  // json-parse-shim
5812  add('load', '14', {
5813      "name": "json-parse-shim",
5814      "test": function (Y) {
5815      var _JSON = Y.config.global.JSON,
5816          Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
5817          nativeSupport = Y.config.useNativeJSONParse !== false && !!Native;
5818  
5819      function workingNative( k, v ) {
5820          return k === "ok" ? true : v;
5821      }
5822      
5823      // Double check basic functionality.  This is mainly to catch early broken
5824      // implementations of the JSON API in Firefox 3.1 beta1 and beta2
5825      if ( nativeSupport ) {
5826          try {
5827              nativeSupport = ( Native.parse( '{"ok":false}', workingNative ) ).ok;
5828          }
5829          catch ( e ) {
5830              nativeSupport = false;
5831          }
5832      }
5833  
5834      return !nativeSupport;
5835  },
5836      "trigger": "json-parse"
5837  });
5838  // json-stringify-shim
5839  add('load', '15', {
5840      "name": "json-stringify-shim",
5841      "test": function (Y) {
5842      var _JSON = Y.config.global.JSON,
5843          Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
5844          nativeSupport = Y.config.useNativeJSONStringify !== false && !!Native;
5845  
5846      // Double check basic native functionality.  This is primarily to catch broken
5847      // early JSON API implementations in Firefox 3.1 beta1 and beta2.
5848      if ( nativeSupport ) {
5849          try {
5850              nativeSupport = ( '0' === Native.stringify(0) );
5851          } catch ( e ) {
5852              nativeSupport = false;
5853          }
5854      }
5855  
5856  
5857      return !nativeSupport;
5858  },
5859      "trigger": "json-stringify"
5860  });
5861  // scrollview-base-ie
5862  add('load', '16', {
5863      "name": "scrollview-base-ie",
5864      "trigger": "scrollview-base",
5865      "ua": "ie"
5866  });
5867  // selector-css2
5868  add('load', '17', {
5869      "name": "selector-css2",
5870      "test": function (Y) {
5871      var DOCUMENT = Y.config.doc,
5872          ret = DOCUMENT && !('querySelectorAll' in DOCUMENT);
5873  
5874      return ret;
5875  },
5876      "trigger": "selector"
5877  });
5878  // transition-timer
5879  add('load', '18', {
5880      "name": "transition-timer",
5881      "test": function (Y) {
5882      var DOCUMENT = Y.config.doc,
5883          node = (DOCUMENT) ? DOCUMENT.documentElement: null,
5884          ret = true;
5885  
5886      if (node && node.style) {
5887          ret = !('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
5888      }
5889  
5890      return ret;
5891  },
5892      "trigger": "transition"
5893  });
5894  // widget-base-ie
5895  add('load', '19', {
5896      "name": "widget-base-ie",
5897      "trigger": "widget-base",
5898      "ua": "ie"
5899  });
5900  // yql-jsonp
5901  add('load', '20', {
5902      "name": "yql-jsonp",
5903      "test": function (Y) {
5904      /* Only load the JSONP module when not in nodejs or winjs
5905      TODO Make the winjs module a CORS module
5906      */
5907      return (!Y.UA.nodejs && !Y.UA.winjs);
5908  },
5909      "trigger": "yql"
5910  });
5911  // yql-nodejs
5912  add('load', '21', {
5913      "name": "yql-nodejs",
5914      "trigger": "yql",
5915      "ua": "nodejs"
5916  });
5917  // yql-winjs
5918  add('load', '22', {
5919      "name": "yql-winjs",
5920      "trigger": "yql",
5921      "ua": "winjs"
5922  });
5923  
5924  }, '3.17.2', {"requires": ["yui-base"]});
5925  YUI.add('intl-base', function (Y, NAME) {
5926  
5927  /**
5928   * The Intl utility provides a central location for managing sets of
5929   * localized resources (strings and formatting patterns).
5930   *
5931   * @class Intl
5932   * @uses EventTarget
5933   * @static
5934   */
5935  
5936  var SPLIT_REGEX = /[, ]/;
5937  
5938  Y.mix(Y.namespace('Intl'), {
5939  
5940   /**
5941      * Returns the language among those available that
5942      * best matches the preferred language list, using the Lookup
5943      * algorithm of BCP 47.
5944      * If none of the available languages meets the user's preferences,
5945      * then "" is returned.
5946      * Extended language ranges are not supported.
5947      *
5948      * @method lookupBestLang
5949      * @param {String[] | String} preferredLanguages The list of preferred
5950      * languages in descending preference order, represented as BCP 47
5951      * language tags. A string array or a comma-separated list.
5952      * @param {String[]} availableLanguages The list of languages
5953      * that the application supports, represented as BCP 47 language
5954      * tags.
5955      *
5956      * @return {String} The available language that best matches the
5957      * preferred language list, or "".
5958      * @since 3.1.0
5959      */
5960      lookupBestLang: function(preferredLanguages, availableLanguages) {
5961  
5962          var i, language, result, index;
5963  
5964          // check whether the list of available languages contains language;
5965          // if so return it
5966          function scan(language) {
5967              var i;
5968              for (i = 0; i < availableLanguages.length; i += 1) {
5969                  if (language.toLowerCase() ===
5970                              availableLanguages[i].toLowerCase()) {
5971                      return availableLanguages[i];
5972                  }
5973              }
5974          }
5975  
5976          if (Y.Lang.isString(preferredLanguages)) {
5977              preferredLanguages = preferredLanguages.split(SPLIT_REGEX);
5978          }
5979  
5980          for (i = 0; i < preferredLanguages.length; i += 1) {
5981              language = preferredLanguages[i];
5982              if (!language || language === '*') {
5983                  continue;
5984              }
5985              // check the fallback sequence for one language
5986              while (language.length > 0) {
5987                  result = scan(language);
5988                  if (result) {
5989                      return result;
5990                  } else {
5991                      index = language.lastIndexOf('-');
5992                      if (index >= 0) {
5993                          language = language.substring(0, index);
5994                          // one-character subtags get cut along with the
5995                          // following subtag
5996                          if (index >= 2 && language.charAt(index - 2) === '-') {
5997                              language = language.substring(0, index - 2);
5998                          }
5999                      } else {
6000                          // nothing available for this language
6001                          break;
6002                      }
6003                  }
6004              }
6005          }
6006  
6007          return '';
6008      }
6009  });
6010  
6011  
6012  }, '3.17.2', {"requires": ["yui-base"]});
6013  YUI.add('yui-log', function (Y, NAME) {
6014  
6015  /**
6016   * Provides console log capability and exposes a custom event for
6017   * console implementations. This module is a `core` YUI module,
6018   * <a href="../classes/YUI.html#method_log">it's documentation is located under the YUI class</a>.
6019   *
6020   * @module yui
6021   * @submodule yui-log
6022   */
6023  
6024  var INSTANCE = Y,
6025      LOGEVENT = 'yui:log',
6026      UNDEFINED = 'undefined',
6027      LEVELS = { debug: 1,
6028                 info: 2,
6029                 warn: 4,
6030                 error: 8 };
6031  
6032  /**
6033   * If the 'debug' config is true, a 'yui:log' event will be
6034   * dispatched, which the Console widget and anything else
6035   * can consume.  If the 'useBrowserConsole' config is true, it will
6036   * write to the browser console if available.  YUI-specific log
6037   * messages will only be present in the -debug versions of the
6038   * JS files.  The build system is supposed to remove log statements
6039   * from the raw and minified versions of the files.
6040   *
6041   * @method log
6042   * @for YUI
6043   * @param  {String}  msg  The message to log.
6044   * @param  {String}  cat  The log category for the message.  Default
6045   *                        categories are "info", "warn", "error", "debug".
6046   *                        Custom categories can be used as well. (opt).
6047   * @param  {String}  src  The source of the the message (opt).
6048   * @param  {boolean} silent If true, the log event won't fire.
6049   * @return {YUI}      YUI instance.
6050   */
6051  INSTANCE.log = function(msg, cat, src, silent) {
6052      var bail, excl, incl, m, f, minlevel,
6053          Y = INSTANCE,
6054          c = Y.config,
6055          publisher = (Y.fire) ? Y : YUI.Env.globalEvents;
6056      // suppress log message if the config is off or the event stack
6057      // or the event call stack contains a consumer of the yui:log event
6058      if (c.debug) {
6059          // apply source filters
6060          src = src || "";
6061          if (typeof src !== "undefined") {
6062              excl = c.logExclude;
6063              incl = c.logInclude;
6064              if (incl && !(src in incl)) {
6065                  bail = 1;
6066              } else if (incl && (src in incl)) {
6067                  bail = !incl[src];
6068              } else if (excl && (src in excl)) {
6069                  bail = excl[src];
6070              }
6071  
6072              // Set a default category of info if the category was not defined.
6073              if ((typeof cat === 'undefined')) {
6074                  cat = 'info';
6075              }
6076  
6077              // Determine the current minlevel as defined in configuration
6078              Y.config.logLevel = Y.config.logLevel || 'debug';
6079              minlevel = LEVELS[Y.config.logLevel.toLowerCase()];
6080  
6081              if (cat in LEVELS && LEVELS[cat] < minlevel) {
6082                  // Skip this message if the we don't meet the defined minlevel
6083                  bail = 1;
6084              }
6085          }
6086          if (!bail) {
6087              if (c.useBrowserConsole) {
6088                  m = (src) ? src + ': ' + msg : msg;
6089                  if (Y.Lang.isFunction(c.logFn)) {
6090                      c.logFn.call(Y, msg, cat, src);
6091                  } else if (typeof console !== UNDEFINED && console.log) {
6092                      f = (cat && console[cat] && (cat in LEVELS)) ? cat : 'log';
6093                      console[f](m);
6094                  } else if (typeof opera !== UNDEFINED) {
6095                      opera.postError(m);
6096                  }
6097              }
6098  
6099              if (publisher && !silent) {
6100  
6101                  if (publisher === Y && (!publisher.getEvent(LOGEVENT))) {
6102                      publisher.publish(LOGEVENT, {
6103                          broadcast: 2
6104                      });
6105                  }
6106  
6107                  publisher.fire(LOGEVENT, {
6108                      msg: msg,
6109                      cat: cat,
6110                      src: src
6111                  });
6112              }
6113          }
6114      }
6115  
6116      return Y;
6117  };
6118  
6119  /**
6120   * Write a system message.  This message will be preserved in the
6121   * minified and raw versions of the YUI files, unlike log statements.
6122   * @method message
6123   * @for YUI
6124   * @param  {String}  msg  The message to log.
6125   * @param  {String}  cat  The log category for the message.  Default
6126   *                        categories are "info", "warn", "error", "debug".
6127   *                        Custom categories can be used as well. (opt).
6128   * @param  {String}  src  The source of the the message (opt).
6129   * @param  {boolean} silent If true, the log event won't fire.
6130   * @return {YUI}      YUI instance.
6131   */
6132  INSTANCE.message = function() {
6133      return INSTANCE.log.apply(INSTANCE, arguments);
6134  };
6135  
6136  
6137  }, '3.17.2', {"requires": ["yui-base"]});
6138  YUI.add('yui-later', function (Y, NAME) {
6139  
6140  /**
6141   * Provides a setTimeout/setInterval wrapper. This module is a `core` YUI module,
6142   * <a href="../classes/YUI.html#method_later">it's documentation is located under the YUI class</a>.
6143   *
6144   * @module yui
6145   * @submodule yui-later
6146   */
6147  
6148  var NO_ARGS = [];
6149  
6150  /**
6151   * Executes the supplied function in the context of the supplied
6152   * object 'when' milliseconds later.  Executes the function a
6153   * single time unless periodic is set to true.
6154   * @for YUI
6155   * @method later
6156   * @param when {Number} the number of milliseconds to wait until the fn
6157   * is executed.
6158   * @param o the context object.
6159   * @param fn {Function|String} the function to execute or the name of
6160   * the method in the 'o' object to execute.
6161   * @param data [Array] data that is provided to the function.  This
6162   * accepts either a single item or an array.  If an array is provided,
6163   * the function is executed with one parameter for each array item.
6164   * If you need to pass a single array parameter, it needs to be wrapped
6165   * in an array [myarray].
6166   *
6167   * Note: native methods in IE may not have the call and apply methods.
6168   * In this case, it will work, but you are limited to four arguments.
6169   *
6170   * @param periodic {boolean} if true, executes continuously at supplied
6171   * interval until canceled.
6172   * @return {object} a timer object. Call the cancel() method on this
6173   * object to stop the timer.
6174   */
6175  Y.later = function(when, o, fn, data, periodic) {
6176      when = when || 0;
6177      data = (!Y.Lang.isUndefined(data)) ? Y.Array(data) : NO_ARGS;
6178      o = o || Y.config.win || Y;
6179  
6180      var cancelled = false,
6181          method = (o && Y.Lang.isString(fn)) ? o[fn] : fn,
6182          wrapper = function() {
6183              // IE 8- may execute a setInterval callback one last time
6184              // after clearInterval was called, so in order to preserve
6185              // the cancel() === no more runny-run, we have to jump through
6186              // an extra hoop.
6187              if (!cancelled) {
6188                  if (!method.apply) {
6189                      method(data[0], data[1], data[2], data[3]);
6190                  } else {
6191                      method.apply(o, data || NO_ARGS);
6192                  }
6193              }
6194          },
6195          id = (periodic) ? setInterval(wrapper, when) : setTimeout(wrapper, when);
6196  
6197      return {
6198          id: id,
6199          interval: periodic,
6200          cancel: function() {
6201              cancelled = true;
6202              if (this.interval) {
6203                  clearInterval(id);
6204              } else {
6205                  clearTimeout(id);
6206              }
6207          }
6208      };
6209  };
6210  
6211  Y.Lang.later = Y.later;
6212  
6213  
6214  
6215  }, '3.17.2', {"requires": ["yui-base"]});
6216  YUI.add('loader-base', function (Y, NAME) {
6217  
6218  /**
6219   * The YUI loader core
6220   * @module loader
6221   * @submodule loader-base
6222   */
6223  
6224  (function() {
6225      var VERSION = Y.version,
6226          BUILD = '/build/',
6227          ROOT = VERSION + '/',
6228          CDN_BASE = Y.Env.base,
6229          GALLERY_VERSION = 'gallery-2014.05.29-15-46',
6230          TNT = '2in3',
6231          TNT_VERSION = '4',
6232          YUI2_VERSION = '2.9.0',
6233          COMBO_BASE = CDN_BASE + 'combo?',
6234          META = {
6235              version: VERSION,
6236              root: ROOT,
6237              base: Y.Env.base,
6238              comboBase: COMBO_BASE,
6239              skin: {
6240                  defaultSkin: 'sam',
6241                  base: 'assets/skins/',
6242                  path: 'skin.css',
6243                  after: [
6244                      'cssreset',
6245                      'cssfonts',
6246                      'cssgrids',
6247                      'cssbase',
6248                      'cssreset-context',
6249                      'cssfonts-context'
6250                  ]
6251              },
6252              groups: {},
6253              patterns: {}
6254          },
6255          groups = META.groups,
6256          yui2Update = function(tnt, yui2, config) {
6257              var root = TNT + '.' +
6258                      (tnt || TNT_VERSION) + '/' +
6259                      (yui2 || YUI2_VERSION) + BUILD,
6260                  base = (config && config.base) ? config.base : CDN_BASE,
6261                  combo = (config && config.comboBase) ? config.comboBase : COMBO_BASE;
6262  
6263              groups.yui2.base = base + root;
6264              groups.yui2.root = root;
6265              groups.yui2.comboBase = combo;
6266          },
6267          galleryUpdate = function(tag, config) {
6268              var root = (tag || GALLERY_VERSION) + BUILD,
6269                  base = (config && config.base) ? config.base : CDN_BASE,
6270                  combo = (config && config.comboBase) ? config.comboBase : COMBO_BASE;
6271  
6272              groups.gallery.base = base + root;
6273              groups.gallery.root = root;
6274              groups.gallery.comboBase = combo;
6275          };
6276  
6277  
6278      groups[VERSION] = {};
6279  
6280      groups.gallery = {
6281          ext: false,
6282          combine: true,
6283          comboBase: COMBO_BASE,
6284          update: galleryUpdate,
6285          patterns: {
6286              'gallery-': {},
6287              'lang/gallery-': {},
6288              'gallerycss-': {
6289                  type: 'css'
6290              }
6291          }
6292      };
6293  
6294      groups.yui2 = {
6295          combine: true,
6296          ext: false,
6297          comboBase: COMBO_BASE,
6298          update: yui2Update,
6299          patterns: {
6300              'yui2-': {
6301                  configFn: function(me) {
6302                      if (/-skin|reset|fonts|grids|base/.test(me.name)) {
6303                          me.type = 'css';
6304                          me.path = me.path.replace(/\.js/, '.css');
6305                          // this makes skins in builds earlier than
6306                          // 2.6.0 work as long as combine is false
6307                          me.path = me.path.replace(/\/yui2-skin/,
6308                                              '/assets/skins/sam/yui2-skin');
6309                      }
6310                  }
6311              }
6312          }
6313      };
6314  
6315      galleryUpdate();
6316      yui2Update();
6317  
6318      if (YUI.Env[VERSION]) {
6319          Y.mix(META, YUI.Env[VERSION], false, [
6320              'modules',
6321              'groups',
6322              'skin'
6323          ], 0, true);
6324      }
6325  
6326      YUI.Env[VERSION] = META;
6327  }());
6328  /*jslint forin: true, maxlen: 350 */
6329  
6330  /**
6331   * Loader dynamically loads script and css files.  It includes the dependency
6332   * information for the version of the library in use, and will automatically pull in
6333   * dependencies for the modules requested. It can also load the
6334   * files from the Yahoo! CDN, and it can utilize the combo service provided on
6335   * this network to reduce the number of http connections required to download
6336   * YUI files.
6337   *
6338   * @module loader
6339   * @main loader
6340   * @submodule loader-base
6341   */
6342  
6343  var NOT_FOUND = {},
6344      NO_REQUIREMENTS = [],
6345      MAX_URL_LENGTH = 1024,
6346      GLOBAL_ENV = YUI.Env,
6347      GLOBAL_LOADED = GLOBAL_ENV._loaded,
6348      CSS = 'css',
6349      JS = 'js',
6350      INTL = 'intl',
6351      DEFAULT_SKIN = 'sam',
6352      VERSION = Y.version,
6353      ROOT_LANG = '',
6354      YObject = Y.Object,
6355      oeach = YObject.each,
6356      yArray = Y.Array,
6357      _queue = GLOBAL_ENV._loaderQueue,
6358      META = GLOBAL_ENV[VERSION],
6359      SKIN_PREFIX = 'skin-',
6360      L = Y.Lang,
6361      ON_PAGE = GLOBAL_ENV.mods,
6362      modulekey,
6363      _path = function(dir, file, type, nomin) {
6364          var path = dir + '/' + file;
6365          if (!nomin) {
6366              path += '-min';
6367          }
6368          path += '.' + (type || CSS);
6369  
6370          return path;
6371      };
6372  
6373  
6374      if (!YUI.Env._cssLoaded) {
6375          YUI.Env._cssLoaded = {};
6376      }
6377  
6378  
6379  /**
6380   * The component metadata is stored in Y.Env.meta.
6381   * Part of the loader module.
6382   * @property meta
6383   * @for YUI
6384   */
6385  Y.Env.meta = META;
6386  
6387  /**
6388   * Loader dynamically loads script and css files.  It includes the dependency
6389   * info for the version of the library in use, and will automatically pull in
6390   * dependencies for the modules requested. It can load the
6391   * files from the Yahoo! CDN, and it can utilize the combo service provided on
6392   * this network to reduce the number of http connections required to download
6393   * YUI files. You can also specify an external, custom combo service to host
6394   * your modules as well.
6395  
6396          var Y = YUI();
6397          var loader = new Y.Loader({
6398              filter: 'debug',
6399              base: '../../',
6400              root: 'build/',
6401              combine: true,
6402              require: ['node', 'dd', 'console']
6403          });
6404          var out = loader.resolve(true);
6405  
6406   * If the Loader needs to be patched before it is used for the first time, it
6407   * should be done through the `doBeforeLoader` hook. Simply make the patch
6408   * available via configuration before YUI is loaded:
6409  
6410          YUI_config = YUI_config || {};
6411          YUI_config.doBeforeLoader = function (config) {
6412              var resolve = this.context.Loader.prototype.resolve;
6413              this.context.Loader.prototype.resolve = function () {
6414                  // do something here
6415                  return resolve.apply(this, arguments);
6416              };
6417          };
6418  
6419   * @constructor
6420   * @class Loader
6421   * @param {Object} config an optional set of configuration options.
6422   * @param {String} config.base The base dir which to fetch this module from
6423   * @param {String} config.comboBase The Combo service base path. Ex: `http://yui.yahooapis.com/combo?`
6424   * @param {String} config.root The root path to prepend to module names for the combo service. Ex: `2.5.2/build/`
6425   * @param {String|Object} config.filter A filter to apply to result urls. <a href="#property_filter">See filter property</a>
6426   * @param {Object} config.filters Per-component filter specification.  If specified for a given component, this overrides the filter config.
6427   * @param {Boolean} config.combine Use a combo service to reduce the number of http connections required to load your dependencies
6428   * @param {Boolean} [config.async=true] Fetch files in async
6429   * @param {Array} config.ignore: A list of modules that should never be dynamically loaded
6430   * @param {Array} config.force A list of modules that should always be loaded when required, even if already present on the page
6431   * @param {HTMLElement|String} config.insertBefore Node or id for a node that should be used as the insertion point for new nodes
6432   * @param {Object} config.jsAttributes Object literal containing attributes to add to script nodes
6433   * @param {Object} config.cssAttributes Object literal containing attributes to add to link nodes
6434   * @param {Number} config.timeout The number of milliseconds before a timeout occurs when dynamically loading nodes.  If not set, there is no timeout
6435   * @param {Object} config.context Execution context for all callbacks
6436   * @param {Function} config.onSuccess Callback for the 'success' event
6437   * @param {Function} config.onFailure Callback for the 'failure' event
6438   * @param {Function} config.onTimeout Callback for the 'timeout' event
6439   * @param {Function} config.onProgress Callback executed each time a script or css file is loaded
6440   * @param {Object} config.modules A list of module definitions.  See <a href="#method_addModule">Loader.addModule</a> for the supported module metadata
6441   * @param {Object} config.groups A list of group definitions.  Each group can contain specific definitions for `base`, `comboBase`, `combine`, and accepts a list of `modules`.
6442   * @param {String} config.2in3 The version of the YUI 2 in 3 wrapper to use.  The intrinsic support for YUI 2 modules in YUI 3 relies on versions of the YUI 2 components inside YUI 3 module wrappers.  These wrappers change over time to accomodate the issues that arise from running YUI 2 in a YUI 3 sandbox.
6443   * @param {String} config.yui2 When using the 2in3 project, you can select the version of YUI 2 to use.  Valid values are `2.2.2`, `2.3.1`, `2.4.1`, `2.5.2`, `2.6.0`, `2.7.0`, `2.8.0`, `2.8.1` and `2.9.0` [default] -- plus all versions of YUI 2 going forward.
6444   * @param {Function} config.doBeforeLoader An optional hook that allows for the patching of the loader instance. The `Y` instance is available as `this.context` and the only argument to the function is the Loader configuration object.
6445   */
6446  Y.Loader = function(o) {
6447  
6448      var self = this;
6449  
6450      //Catch no config passed.
6451      o = o || {};
6452  
6453      modulekey = META.md5;
6454  
6455      /**
6456       * Internal callback to handle multiple internal insert() calls
6457       * so that css is inserted prior to js
6458       * @property _internalCallback
6459       * @private
6460       */
6461      // self._internalCallback = null;
6462  
6463      /**
6464       * Callback that will be executed when the loader is finished
6465       * with an insert
6466       * @method onSuccess
6467       * @type function
6468       */
6469      // self.onSuccess = null;
6470  
6471      /**
6472       * Callback that will be executed if there is a failure
6473       * @method onFailure
6474       * @type function
6475       */
6476      // self.onFailure = null;
6477  
6478      /**
6479       * Callback executed each time a script or css file is loaded
6480       * @method onProgress
6481       * @type function
6482       */
6483      // self.onProgress = null;
6484  
6485      /**
6486       * Callback that will be executed if a timeout occurs
6487       * @method onTimeout
6488       * @type function
6489       */
6490      // self.onTimeout = null;
6491  
6492      /**
6493       * The execution context for all callbacks
6494       * @property context
6495       * @default {YUI} the YUI instance
6496       */
6497      self.context = Y;
6498  
6499      // Hook that allows the patching of loader
6500      if (o.doBeforeLoader) {
6501          o.doBeforeLoader.apply(self, arguments);
6502      }
6503  
6504      /**
6505       * Data that is passed to all callbacks
6506       * @property data
6507       */
6508      // self.data = null;
6509  
6510      /**
6511       * Node reference or id where new nodes should be inserted before
6512       * @property insertBefore
6513       * @type string|HTMLElement
6514       */
6515      // self.insertBefore = null;
6516  
6517      /**
6518       * The charset attribute for inserted nodes
6519       * @property charset
6520       * @type string
6521       * @deprecated , use cssAttributes or jsAttributes.
6522       */
6523      // self.charset = null;
6524  
6525      /**
6526       * An object literal containing attributes to add to link nodes
6527       * @property cssAttributes
6528       * @type object
6529       */
6530      // self.cssAttributes = null;
6531  
6532      /**
6533       * An object literal containing attributes to add to script nodes
6534       * @property jsAttributes
6535       * @type object
6536       */
6537      // self.jsAttributes = null;
6538  
6539      /**
6540       * The base directory.
6541       * @property base
6542       * @type string
6543       * @default http://yui.yahooapis.com/[YUI VERSION]/build/
6544       */
6545      self.base = Y.Env.meta.base + Y.Env.meta.root;
6546  
6547      /**
6548       * Base path for the combo service
6549       * @property comboBase
6550       * @type string
6551       * @default http://yui.yahooapis.com/combo?
6552       */
6553      self.comboBase = Y.Env.meta.comboBase;
6554  
6555      /*
6556       * Base path for language packs.
6557       */
6558      // self.langBase = Y.Env.meta.langBase;
6559      // self.lang = "";
6560  
6561      /**
6562       * If configured, the loader will attempt to use the combo
6563       * service for YUI resources and configured external resources.
6564       * @property combine
6565       * @type boolean
6566       * @default true if a base dir isn't in the config
6567       */
6568      self.combine = o.base &&
6569          (o.base.indexOf(self.comboBase.substr(0, 20)) > -1);
6570  
6571      /**
6572      * The default seperator to use between files in a combo URL
6573      * @property comboSep
6574      * @type {String}
6575      * @default Ampersand
6576      */
6577      self.comboSep = '&';
6578      /**
6579       * Max url length for combo urls.  The default is 1024. This is the URL
6580       * limit for the Yahoo! hosted combo servers.  If consuming
6581       * a different combo service that has a different URL limit
6582       * it is possible to override this default by supplying
6583       * the maxURLLength config option.  The config option will
6584       * only take effect if lower than the default.
6585       *
6586       * @property maxURLLength
6587       * @type int
6588       */
6589      self.maxURLLength = MAX_URL_LENGTH;
6590  
6591      /**
6592       * Ignore modules registered on the YUI global
6593       * @property ignoreRegistered
6594       * @default false
6595       */
6596      self.ignoreRegistered = o.ignoreRegistered;
6597  
6598      /**
6599       * Root path to prepend to module path for the combo
6600       * service
6601       * @property root
6602       * @type string
6603       * @default [YUI VERSION]/build/
6604       */
6605      self.root = Y.Env.meta.root;
6606  
6607      /**
6608       * Timeout value in milliseconds.  If set, self value will be used by
6609       * the get utility.  the timeout event will fire if
6610       * a timeout occurs.
6611       * @property timeout
6612       * @type int
6613       */
6614      self.timeout = 0;
6615  
6616      /**
6617       * A list of modules that should not be loaded, even if
6618       * they turn up in the dependency tree
6619       * @property ignore
6620       * @type string[]
6621       */
6622      // self.ignore = null;
6623  
6624      /**
6625       * A list of modules that should always be loaded, even
6626       * if they have already been inserted into the page.
6627       * @property force
6628       * @type string[]
6629       */
6630      // self.force = null;
6631  
6632      self.forceMap = {};
6633  
6634      /**
6635       * Should we allow rollups
6636       * @property allowRollup
6637       * @type boolean
6638       * @default false
6639       */
6640      self.allowRollup = false;
6641  
6642      /**
6643       * A filter to apply to result urls.  This filter will modify the default
6644       * path for all modules.  The default path for the YUI library is the
6645       * minified version of the files (e.g., event-min.js).  The filter property
6646       * can be a predefined filter or a custom filter.  The valid predefined
6647       * filters are:
6648       * <dl>
6649       *  <dt>DEBUG</dt>
6650       *  <dd>Selects the debug versions of the library (e.g., event-debug.js).
6651       *      This option will automatically include the Logger widget</dd>
6652       *  <dt>RAW</dt>
6653       *  <dd>Selects the non-minified version of the library (e.g., event.js).
6654       *  </dd>
6655       * </dl>
6656       * You can also define a custom filter, which must be an object literal
6657       * containing a search expression and a replace string:
6658       *
6659       *      myFilter: {
6660       *          'searchExp': "-min\\.js",
6661       *          'replaceStr': "-debug.js"
6662       *      }
6663       *
6664       * @property filter
6665       * @type string| {searchExp: string, replaceStr: string}
6666       */
6667      // self.filter = null;
6668  
6669      /**
6670       * per-component filter specification.  If specified for a given
6671       * component, this overrides the filter config.
6672       * @property filters
6673       * @type object
6674       */
6675      self.filters = {};
6676  
6677      /**
6678       * The list of requested modules
6679       * @property required
6680       * @type {string: boolean}
6681       */
6682      self.required = {};
6683  
6684      /**
6685       * If a module name is predefined when requested, it is checked againsts
6686       * the patterns provided in this property.  If there is a match, the
6687       * module is added with the default configuration.
6688       *
6689       * At the moment only supporting module prefixes, but anticipate
6690       * supporting at least regular expressions.
6691       * @property patterns
6692       * @type Object
6693       */
6694      // self.patterns = Y.merge(Y.Env.meta.patterns);
6695      self.patterns = {};
6696  
6697      /**
6698       * Internal loader instance metadata. Use accessor `getModuleInfo()` instead.
6699       */
6700      self.moduleInfo = {};
6701  
6702      self.groups = Y.merge(Y.Env.meta.groups);
6703  
6704      /**
6705       * Provides the information used to skin the skinnable components.
6706       * The following skin definition would result in 'skin1' and 'skin2'
6707       * being loaded for calendar (if calendar was requested), and
6708       * 'sam' for all other skinnable components:
6709       *
6710       *      skin: {
6711       *          // The default skin, which is automatically applied if not
6712       *          // overriden by a component-specific skin definition.
6713       *          // Change this in to apply a different skin globally
6714       *          defaultSkin: 'sam',
6715       *
6716       *          // This is combined with the loader base property to get
6717       *          // the default root directory for a skin. ex:
6718       *          // http://yui.yahooapis.com/2.3.0/build/assets/skins/sam/
6719       *          base: 'assets/skins/',
6720       *
6721       *          // Any component-specific overrides can be specified here,
6722       *          // making it possible to load different skins for different
6723       *          // components.  It is possible to load more than one skin
6724       *          // for a given component as well.
6725       *          overrides: {
6726       *              calendar: ['skin1', 'skin2']
6727       *          }
6728       *      }
6729       * @property skin
6730       * @type {Object}
6731       */
6732      self.skin = Y.merge(Y.Env.meta.skin);
6733  
6734      /*
6735       * Map of conditional modules
6736       * @since 3.2.0
6737       */
6738      self.conditions = {};
6739  
6740      // map of modules with a hash of modules that meet the requirement
6741      // self.provides = {};
6742  
6743      self.config = o;
6744      self._internal = true;
6745  
6746      self._populateConditionsCache();
6747  
6748      /**
6749       * Set when beginning to compute the dependency tree.
6750       * Composed of what YUI reports to be loaded combined
6751       * with what has been loaded by any instance on the page
6752       * with the version number specified in the metadata.
6753       * @property loaded
6754       * @type {string: boolean}
6755       */
6756      self.loaded = GLOBAL_LOADED[VERSION];
6757  
6758  
6759      /**
6760      * Should Loader fetch scripts in `async`, defaults to `true`
6761      * @property async
6762      */
6763  
6764      self.async = true;
6765  
6766      self._inspectPage();
6767  
6768      self._internal = false;
6769  
6770      self._config(o);
6771  
6772      self.forceMap = (self.force) ? Y.Array.hash(self.force) : {};
6773  
6774      self.testresults = null;
6775  
6776      if (Y.config.tests) {
6777          self.testresults = Y.config.tests;
6778      }
6779  
6780      /**
6781       * List of rollup files found in the library metadata
6782       * @property rollups
6783       */
6784      // self.rollups = null;
6785  
6786      /**
6787       * Whether or not to load optional dependencies for
6788       * the requested modules
6789       * @property loadOptional
6790       * @type boolean
6791       * @default false
6792       */
6793      // self.loadOptional = false;
6794  
6795      /**
6796       * All of the derived dependencies in sorted order, which
6797       * will be populated when either calculate() or insert()
6798       * is called
6799       * @property sorted
6800       * @type string[]
6801       */
6802      self.sorted = [];
6803  
6804      /*
6805       * A list of modules to attach to the YUI instance when complete.
6806       * If not supplied, the sorted list of dependencies are applied.
6807       * @property attaching
6808       */
6809      // self.attaching = null;
6810  
6811      /**
6812       * Flag to indicate the dependency tree needs to be recomputed
6813       * if insert is called again.
6814       * @property dirty
6815       * @type boolean
6816       * @default true
6817       */
6818      self.dirty = true;
6819  
6820      /**
6821       * List of modules inserted by the utility
6822       * @property inserted
6823       * @type {string: boolean}
6824       */
6825      self.inserted = {};
6826  
6827      /**
6828       * List of skipped modules during insert() because the module
6829       * was not defined
6830       * @property skipped
6831       */
6832      self.skipped = {};
6833  
6834      // Y.on('yui:load', self.loadNext, self);
6835  
6836      self.tested = {};
6837  
6838      /*
6839       * Cached sorted calculate results
6840       * @property results
6841       * @since 3.2.0
6842       */
6843      //self.results = {};
6844  
6845      if (self.ignoreRegistered) {
6846          //Clear inpage already processed modules.
6847          self._resetModules();
6848      }
6849  
6850  };
6851  
6852  Y.Loader.prototype = {
6853      /**
6854      * Gets the module info from the local moduleInfo hash, or from the
6855      * default metadata and populate the local moduleInfo hash.
6856      * @method getModuleInfo
6857      * @param {string} name of the module
6858      * @public
6859      */
6860      getModuleInfo: function(name) {
6861  
6862          var m = this.moduleInfo[name],
6863              rawMetaModules, globalRenderedMods, internal, v;
6864  
6865          if (m) {
6866              return m;
6867          }
6868  
6869          rawMetaModules = META.modules;
6870          globalRenderedMods = GLOBAL_ENV._renderedMods;
6871          internal = this._internal;
6872  
6873          /*
6874          The logic here is:
6875  
6876          - if the `moduleInfo[name]` is avilable,
6877            then short circuit
6878          - otherwise, if the module is in the globalCache (cross Y instance),
6879            then port it from the global registry into `moduleInfo[name]`
6880          - otherwise, if the module has raw metadata (from meta modules)
6881            then add it to the global registry and to `moduleInfo[name]`
6882  
6883          */
6884          if (globalRenderedMods && globalRenderedMods.hasOwnProperty(name) && !this.ignoreRegistered) {
6885              this.moduleInfo[name] = Y.merge(globalRenderedMods[name]);
6886          } else {
6887              if (rawMetaModules.hasOwnProperty(name)) {
6888                  this._internal = true; // making sure that modules from raw data are marked as internal
6889                  v = this.addModule(rawMetaModules[name], name);
6890                  // Inspect the page for the CSS module and mark it as loaded.
6891                  if (v && v.type === CSS) {
6892                      if (this.isCSSLoaded(v.name, true)) {
6893                          Y.log('Found CSS module on page: ' + v.name, 'info', 'loader');
6894                          this.loaded[v.name] = true;
6895                      }
6896                  }
6897                  this._internal = internal;
6898              }
6899          }
6900          return this.moduleInfo[name];
6901      },
6902      /**
6903      * Expand the names that are aliases to other modules.
6904      * @method _expandAliases
6905      * @param {string[]} list a module name or a list of names to be expanded
6906      * @private
6907      * @return {array}
6908      */
6909      _expandAliases: function(list) {
6910          var expanded = [],
6911              aliases = YUI.Env.aliases,
6912              i, name;
6913          list = Y.Array(list);
6914          for (i = 0; i < list.length; i += 1) {
6915              name = list[i];
6916              expanded.push.apply(expanded, aliases[name] ? aliases[name] : [name]);
6917          }
6918          return expanded;
6919      },
6920      /**
6921      * Populate the conditions cache from raw modules, this is necessary
6922      * because no other module will require a conditional module, instead
6923      * the condition has to be executed and then the module is analyzed
6924      * to be included in the final requirement list. Without this cache
6925      * conditional modules will be simply ignored.
6926      * @method _populateConditionsCache
6927      * @private
6928      */
6929      _populateConditionsCache: function() {
6930          var rawMetaModules = META.modules,
6931              cache = GLOBAL_ENV._conditions,
6932              i, j, t, trigger;
6933  
6934          // if we have conditions in cache and cache is enabled
6935          // we should port them to this loader instance
6936          if (cache && !this.ignoreRegistered) {
6937              for (i in cache) {
6938                  if (cache.hasOwnProperty(i)) {
6939                      this.conditions[i] = Y.merge(cache[i]);
6940                  }
6941              }
6942          } else {
6943              for (i in rawMetaModules) {
6944                  if (rawMetaModules.hasOwnProperty(i) && rawMetaModules[i].condition) {
6945                      t = this._expandAliases(rawMetaModules[i].condition.trigger);
6946                      for (j = 0; j < t.length; j += 1) {
6947                          trigger = t[j];
6948                          this.conditions[trigger] = this.conditions[trigger] || {};
6949                          this.conditions[trigger][rawMetaModules[i].name || i] = rawMetaModules[i].condition;
6950                      }
6951                  }
6952              }
6953              GLOBAL_ENV._conditions = this.conditions;
6954          }
6955      },
6956      /**
6957      * Reset modules in the module cache to a pre-processed state so additional
6958      * computations with a different skin or language will work as expected.
6959      * @method _resetModules
6960      * @private
6961      */
6962      _resetModules: function() {
6963          var self = this, i, o,
6964              mod, name, details;
6965          for (i in self.moduleInfo) {
6966              if (self.moduleInfo.hasOwnProperty(i) && self.moduleInfo[i]) {
6967                  mod = self.moduleInfo[i];
6968                  name = mod.name;
6969                  details  = (YUI.Env.mods[name] ? YUI.Env.mods[name].details : null);
6970  
6971                  if (details) {
6972                      self.moduleInfo[name]._reset = true;
6973                      self.moduleInfo[name].requires = details.requires || [];
6974                      self.moduleInfo[name].optional = details.optional || [];
6975                      self.moduleInfo[name].supersedes = details.supercedes || [];
6976                  }
6977  
6978                  if (mod.defaults) {
6979                      for (o in mod.defaults) {
6980                          if (mod.defaults.hasOwnProperty(o)) {
6981                              if (mod[o]) {
6982                                  mod[o] = mod.defaults[o];
6983                              }
6984                          }
6985                      }
6986                  }
6987                  mod.langCache = undefined;
6988                  mod.skinCache = undefined;
6989                  if (mod.skinnable) {
6990                      self._addSkin(self.skin.defaultSkin, mod.name);
6991                  }
6992              }
6993          }
6994      },
6995      /**
6996      Regex that matches a CSS URL. Used to guess the file type when it's not
6997      specified.
6998  
6999      @property REGEX_CSS
7000      @type RegExp
7001      @final
7002      @protected
7003      @since 3.5.0
7004      **/
7005      REGEX_CSS: /\.css(?:[?;].*)?$/i,
7006  
7007      /**
7008      * Default filters for raw and debug
7009      * @property FILTER_DEFS
7010      * @type Object
7011      * @final
7012      * @protected
7013      */
7014      FILTER_DEFS: {
7015          RAW: {
7016              'searchExp': '-min\\.js',
7017              'replaceStr': '.js'
7018          },
7019          DEBUG: {
7020              'searchExp': '-min\\.js',
7021              'replaceStr': '-debug.js'
7022          },
7023          COVERAGE: {
7024              'searchExp': '-min\\.js',
7025              'replaceStr': '-coverage.js'
7026          }
7027      },
7028      /*
7029      * Check the pages meta-data and cache the result.
7030      * @method _inspectPage
7031      * @private
7032      */
7033      _inspectPage: function() {
7034          var self = this, v, m, req, mr, i;
7035  
7036          for (i in ON_PAGE) {
7037              if (ON_PAGE.hasOwnProperty(i)) {
7038                  v = ON_PAGE[i];
7039                  if (v.details) {
7040                      m = self.getModuleInfo(v.name);
7041                      req = v.details.requires;
7042                      mr = m && m.requires;
7043  
7044                     if (m) {
7045                         if (!m._inspected && req && mr.length !== req.length) {
7046                             // console.log('deleting ' + m.name);
7047                             delete m.expanded;
7048                         }
7049                     } else {
7050                         m = self.addModule(v.details, i);
7051                     }
7052                     m._inspected = true;
7053                 }
7054              }
7055          }
7056      },
7057      /*
7058      * returns true if b is not loaded, and is required directly or by means of modules it supersedes.
7059      * @private
7060      * @method _requires
7061      * @param {String} mod1 The first module to compare
7062      * @param {String} mod2 The second module to compare
7063      */
7064     _requires: function(mod1, mod2) {
7065  
7066          var i, rm, after_map, s,
7067              m = this.getModuleInfo(mod1),
7068              other = this.getModuleInfo(mod2);
7069  
7070          if (!m || !other) {
7071              return false;
7072          }
7073  
7074          rm = m.expanded_map;
7075          after_map = m.after_map;
7076  
7077          // check if this module should be sorted after the other
7078          // do this first to short circut circular deps
7079          if (after_map && (mod2 in after_map)) {
7080              return true;
7081          }
7082  
7083          after_map = other.after_map;
7084  
7085          // and vis-versa
7086          if (after_map && (mod1 in after_map)) {
7087              return false;
7088          }
7089  
7090          // check if this module requires one the other supersedes
7091          s = other.supersedes;
7092          if (s) {
7093              for (i = 0; i < s.length; i++) {
7094                  if (this._requires(mod1, s[i])) {
7095                      return true;
7096                  }
7097              }
7098          }
7099  
7100          s = m.supersedes;
7101          if (s) {
7102              for (i = 0; i < s.length; i++) {
7103                  if (this._requires(mod2, s[i])) {
7104                      return false;
7105                  }
7106              }
7107          }
7108  
7109          // check if this module requires the other directly
7110          // if (r && yArray.indexOf(r, mod2) > -1) {
7111          if (rm && (mod2 in rm)) {
7112              return true;
7113          }
7114  
7115          // external css files should be sorted below yui css
7116          if (m.ext && m.type === CSS && !other.ext && other.type === CSS) {
7117              return true;
7118          }
7119  
7120          return false;
7121      },
7122      /**
7123      * Apply a new config to the Loader instance
7124      * @method _config
7125      * @private
7126      * @param {Object} o The new configuration
7127      */
7128      _config: function(o) {
7129          var i, j, val, a, f, group, groupName, self = this,
7130              mods = [], mod, modInfo;
7131          // apply config values
7132          if (o) {
7133              for (i in o) {
7134                  if (o.hasOwnProperty(i)) {
7135                      val = o[i];
7136                      //TODO This should be a case
7137                      if (i === 'require') {
7138                          self.require(val);
7139                      } else if (i === 'skin') {
7140                          //If the config.skin is a string, format to the expected object
7141                          if (typeof val === 'string') {
7142                              self.skin.defaultSkin = o.skin;
7143                              val = {
7144                                  defaultSkin: val
7145                              };
7146                          }
7147  
7148                          Y.mix(self.skin, val, true);
7149                      } else if (i === 'groups') {
7150                          for (j in val) {
7151                              if (val.hasOwnProperty(j)) {
7152                                  // Y.log('group: ' + j);
7153                                  groupName = j;
7154                                  group = val[j];
7155                                  self.addGroup(group, groupName);
7156                                  if (group.aliases) {
7157                                      for (a in group.aliases) {
7158                                          if (group.aliases.hasOwnProperty(a)) {
7159                                              self.addAlias(group.aliases[a], a);
7160                                          }
7161                                      }
7162                                  }
7163                              }
7164                          }
7165  
7166                      } else if (i === 'modules') {
7167                          // add a hash of module definitions
7168                          for (j in val) {
7169                              if (val.hasOwnProperty(j)) {
7170                                  self.addModule(val[j], j);
7171                              }
7172                          }
7173                      } else if (i === 'aliases') {
7174                          for (j in val) {
7175                              if (val.hasOwnProperty(j)) {
7176                                  self.addAlias(val[j], j);
7177                              }
7178                          }
7179                      } else if (i === 'gallery') {
7180                          if (this.groups.gallery.update) {
7181                              this.groups.gallery.update(val, o);
7182                          }
7183                      } else if (i === 'yui2' || i === '2in3') {
7184                          if (this.groups.yui2.update) {
7185                              this.groups.yui2.update(o['2in3'], o.yui2, o);
7186                          }
7187                      } else {
7188                          self[i] = val;
7189                      }
7190                  }
7191              }
7192          }
7193  
7194          // fix filter
7195          f = self.filter;
7196  
7197          if (L.isString(f)) {
7198              f = f.toUpperCase();
7199              self.filterName = f;
7200              self.filter = self.FILTER_DEFS[f];
7201              if (f === 'DEBUG') {
7202                  self.require('yui-log', 'dump');
7203              }
7204          }
7205  
7206          if (self.filterName && self.coverage) {
7207              if (self.filterName === 'COVERAGE' && L.isArray(self.coverage) && self.coverage.length) {
7208                  for (i = 0; i < self.coverage.length; i++) {
7209                      mod = self.coverage[i];
7210                      modInfo = self.getModuleInfo(mod);
7211                      if (modInfo && modInfo.use) {
7212                          mods = mods.concat(modInfo.use);
7213                      } else {
7214                          mods.push(mod);
7215                      }
7216                  }
7217                  self.filters = self.filters || {};
7218                  Y.Array.each(mods, function(mod) {
7219                      self.filters[mod] = self.FILTER_DEFS.COVERAGE;
7220                  });
7221                  self.filterName = 'RAW';
7222                  self.filter = self.FILTER_DEFS[self.filterName];
7223              }
7224          }
7225  
7226      },
7227  
7228      /**
7229       * Returns the skin module name for the specified skin name.  If a
7230       * module name is supplied, the returned skin module name is
7231       * specific to the module passed in.
7232       * @method formatSkin
7233       * @param {string} skin the name of the skin.
7234       * @param {string} mod optional: the name of a module to skin.
7235       * @return {string} the full skin module name.
7236       */
7237      formatSkin: function(skin, mod) {
7238          var s = SKIN_PREFIX + skin;
7239          if (mod) {
7240              s = s + '-' + mod;
7241          }
7242  
7243          return s;
7244      },
7245  
7246      /**
7247       * Adds the skin def to the module info
7248       * @method _addSkin
7249       * @param {string} skin the name of the skin.
7250       * @param {string} mod the name of the module.
7251       * @param {string} parent parent module if this is a skin of a
7252       * submodule or plugin.
7253       * @return {string} the module name for the skin.
7254       * @private
7255       */
7256      _addSkin: function(skin, mod, parent) {
7257          var pkg, name, nmod,
7258              sinf = this.skin,
7259              mdef = mod && this.getModuleInfo(mod),
7260              ext = mdef && mdef.ext;
7261  
7262          // Add a module definition for the module-specific skin css
7263          if (mod) {
7264              name = this.formatSkin(skin, mod);
7265              if (!this.getModuleInfo(name)) {
7266                  pkg = mdef.pkg || mod;
7267                  nmod = {
7268                      skin: true,
7269                      name: name,
7270                      group: mdef.group,
7271                      type: 'css',
7272                      after: sinf.after,
7273                      path: (parent || pkg) + '/' + sinf.base + skin +
7274                            '/' + mod + '.css',
7275                      ext: ext
7276                  };
7277                  if (mdef.base) {
7278                      nmod.base = mdef.base;
7279                  }
7280                  if (mdef.configFn) {
7281                      nmod.configFn = mdef.configFn;
7282                  }
7283                  this.addModule(nmod, name);
7284  
7285                  Y.log('Adding skin (' + name + '), ' + parent + ', ' + pkg + ', ' + nmod.path, 'info', 'loader');
7286              }
7287          }
7288  
7289          return name;
7290      },
7291      /**
7292      * Adds an alias module to the system
7293      * @method addAlias
7294      * @param {Array} use An array of modules that makes up this alias
7295      * @param {String} name The name of the alias
7296      * @example
7297      *       var loader = new Y.Loader({});
7298      *       loader.addAlias([ 'node', 'yql' ], 'davglass');
7299      *       loader.require(['davglass']);
7300      *       var out = loader.resolve(true);
7301      *
7302      *       //out.js will contain Node and YQL modules
7303      */
7304      addAlias: function(use, name) {
7305          YUI.Env.aliases[name] = use;
7306          this.addModule({
7307              name: name,
7308              use: use
7309          });
7310      },
7311      /**
7312       * Add a new module group
7313       * @method addGroup
7314       * @param {Object} config An object containing the group configuration data
7315       * @param {String} config.name required, the group name
7316       * @param {String} config.base The base directory for this module group
7317       * @param {String} config.root The root path to add to each combo resource path
7318       * @param {Boolean} config.combine Should the request be combined
7319       * @param {String} config.comboBase Combo service base path
7320       * @param {Object} config.modules The group of modules
7321       * @param {String} name the group name.
7322       * @example
7323       *      var loader = new Y.Loader({});
7324       *      loader.addGroup({
7325       *          name: 'davglass',
7326       *          combine: true,
7327       *          comboBase: '/combo?',
7328       *          root: '',
7329       *          modules: {
7330       *              //Module List here
7331       *          }
7332       *      }, 'davglass');
7333       */
7334      addGroup: function(o, name) {
7335          var mods = o.modules,
7336              self = this, i, v;
7337  
7338          name = name || o.name;
7339          o.name = name;
7340          self.groups[name] = o;
7341  
7342          if (o.patterns) {
7343              for (i in o.patterns) {
7344                  if (o.patterns.hasOwnProperty(i)) {
7345                      o.patterns[i].group = name;
7346                      self.patterns[i] = o.patterns[i];
7347                  }
7348              }
7349          }
7350  
7351          if (mods) {
7352              for (i in mods) {
7353                  if (mods.hasOwnProperty(i)) {
7354                      v = mods[i];
7355                      if (typeof v === 'string') {
7356                          v = { name: i, fullpath: v };
7357                      }
7358                      v.group = name;
7359                      self.addModule(v, i);
7360                  }
7361              }
7362          }
7363      },
7364  
7365      /**
7366       * Add a new module to the component metadata.
7367       * @method addModule
7368       * @param {Object} config An object containing the module data.
7369       * @param {String} config.name Required, the component name
7370       * @param {String} config.type Required, the component type (js or css)
7371       * @param {String} config.path Required, the path to the script from `base`
7372       * @param {Array} config.requires Array of modules required by this component
7373       * @param {Array} [config.optional] Array of optional modules for this component
7374       * @param {Array} [config.supersedes] Array of the modules this component replaces
7375       * @param {Array} [config.after] Array of modules the components which, if present, should be sorted above this one
7376       * @param {Object} [config.after_map] Faster alternative to 'after' -- supply a hash instead of an array
7377       * @param {Number} [config.rollup] The number of superseded modules required for automatic rollup
7378       * @param {String} [config.fullpath] If `fullpath` is specified, this is used instead of the configured `base + path`
7379       * @param {Boolean} [config.skinnable] Flag to determine if skin assets should automatically be pulled in
7380       * @param {Object} [config.submodules] Hash of submodules
7381       * @param {String} [config.group] The group the module belongs to -- this is set automatically when it is added as part of a group configuration.
7382       * @param {Array} [config.lang] Array of BCP 47 language tags of languages for which this module has localized resource bundles, e.g., `["en-GB", "zh-Hans-CN"]`
7383       * @param {Object} [config.condition] Specifies that the module should be loaded automatically if a condition is met. This is an object with up to four fields:
7384       * @param {String} [config.condition.trigger] The name of a module that can trigger the auto-load
7385       * @param {Function} [config.condition.test] A function that returns true when the module is to be loaded.
7386       * @param {String} [config.condition.ua] The UA name of <a href="UA.html">Y.UA</a> object that returns true when the module is to be loaded. e.g., `"ie"`, `"nodejs"`.
7387       * @param {String} [config.condition.when] Specifies the load order of the conditional module
7388       *  with regard to the position of the trigger module.
7389       *  This should be one of three values: `before`, `after`, or `instead`.  The default is `after`.
7390       * @param {Object} [config.testresults] A hash of test results from `Y.Features.all()`
7391       * @param {Function} [config.configFn] A function to exectute when configuring this module
7392       * @param {Object} config.configFn.mod The module config, modifying this object will modify it's config. Returning false will delete the module's config.
7393       * @param {String[]} [config.optionalRequires] List of dependencies that
7394          may optionally be loaded by this loader. This is targeted mostly at
7395          polyfills, since they should not be in the list of requires because
7396          polyfills are assumed to be available in the global scope.
7397       * @param {Function} [config.test] Test to be called when this module is
7398          added as an optional dependency of another module. If the test function
7399          returns `false`, the module will be ignored and will not be attached to
7400          this YUI instance.
7401       * @param {String} [name] The module name, required if not in the module data.
7402       * @return {Object} the module definition or null if the object passed in did not provide all required attributes.
7403       */
7404      addModule: function(o, name) {
7405          name = name || o.name;
7406  
7407          if (typeof o === 'string') {
7408              o = { name: name, fullpath: o };
7409          }
7410  
7411  
7412          var subs, i, l, t, sup, s, smod, plugins, plug,
7413              j, langs, packName, supName, flatSup, flatLang, lang, ret,
7414              overrides, skinname, when, g, p,
7415              modInfo = this.moduleInfo[name],
7416              conditions = this.conditions, trigger;
7417  
7418          //Only merge this data if the temp flag is set
7419          //from an earlier pass from a pattern or else
7420          //an override module (YUI_config) can not be used to
7421          //replace a default module.
7422          if (modInfo && modInfo.temp) {
7423              //This catches temp modules loaded via a pattern
7424              // The module will be added twice, once from the pattern and
7425              // Once from the actual add call, this ensures that properties
7426              // that were added to the module the first time around (group: gallery)
7427              // are also added the second time around too.
7428              o = Y.merge(modInfo, o);
7429          }
7430  
7431          o.name = name;
7432  
7433          if (!o || !o.name) {
7434              return null;
7435          }
7436  
7437          if (!o.type) {
7438              //Always assume it's javascript unless the CSS pattern is matched.
7439              o.type = JS;
7440              p = o.path || o.fullpath;
7441              if (p && this.REGEX_CSS.test(p)) {
7442                  Y.log('Auto determined module type as CSS', 'warn', 'loader');
7443                  o.type = CSS;
7444              }
7445          }
7446  
7447          if (!o.path && !o.fullpath) {
7448              o.path = _path(name, name, o.type);
7449          }
7450          o.supersedes = o.supersedes || o.use;
7451  
7452          o.ext = ('ext' in o) ? o.ext : (this._internal) ? false : true;
7453  
7454          // Handle submodule logic
7455          subs = o.submodules;
7456  
7457          this.moduleInfo[name] = o;
7458  
7459          o.requires = o.requires || [];
7460  
7461          /*
7462          Only allowing the cascade of requires information, since
7463          optional and supersedes are far more fine grained than
7464          a blanket requires is.
7465          */
7466          if (this.requires) {
7467              for (i = 0; i < this.requires.length; i++) {
7468                  o.requires.push(this.requires[i]);
7469              }
7470          }
7471          if (o.group && this.groups && this.groups[o.group]) {
7472              g = this.groups[o.group];
7473              if (g.requires) {
7474                  for (i = 0; i < g.requires.length; i++) {
7475                      o.requires.push(g.requires[i]);
7476                  }
7477              }
7478          }
7479  
7480  
7481          if (!o.defaults) {
7482              o.defaults = {
7483                  requires: o.requires ? [].concat(o.requires) : null,
7484                  supersedes: o.supersedes ? [].concat(o.supersedes) : null,
7485                  optional: o.optional ? [].concat(o.optional) : null
7486              };
7487          }
7488  
7489          if (o.skinnable && o.ext && o.temp) {
7490              skinname = this._addSkin(this.skin.defaultSkin, name);
7491              o.requires.unshift(skinname);
7492          }
7493  
7494          if (o.requires.length) {
7495              o.requires = this.filterRequires(o.requires) || [];
7496          }
7497  
7498          if (!o.langPack && o.lang) {
7499              langs = yArray(o.lang);
7500              for (j = 0; j < langs.length; j++) {
7501                  lang = langs[j];
7502                  packName = this.getLangPackName(lang, name);
7503                  smod = this.getModuleInfo(packName);
7504                  if (!smod) {
7505                      smod = this._addLangPack(lang, o, packName);
7506                  }
7507              }
7508          }
7509  
7510  
7511          if (subs) {
7512              sup = o.supersedes || [];
7513              l = 0;
7514  
7515              for (i in subs) {
7516                  if (subs.hasOwnProperty(i)) {
7517                      s = subs[i];
7518  
7519                      s.path = s.path || _path(name, i, o.type);
7520                      s.pkg = name;
7521                      s.group = o.group;
7522  
7523                      if (s.supersedes) {
7524                          sup = sup.concat(s.supersedes);
7525                      }
7526  
7527                      smod = this.addModule(s, i);
7528                      sup.push(i);
7529  
7530                      if (smod.skinnable) {
7531                          o.skinnable = true;
7532                          overrides = this.skin.overrides;
7533                          if (overrides && overrides[i]) {
7534                              for (j = 0; j < overrides[i].length; j++) {
7535                                  skinname = this._addSkin(overrides[i][j],
7536                                           i, name);
7537                                  sup.push(skinname);
7538                              }
7539                          }
7540                          skinname = this._addSkin(this.skin.defaultSkin,
7541                                          i, name);
7542                          sup.push(skinname);
7543                      }
7544  
7545                      // looks like we are expected to work out the metadata
7546                      // for the parent module language packs from what is
7547                      // specified in the child modules.
7548                      if (s.lang && s.lang.length) {
7549  
7550                          langs = yArray(s.lang);
7551                          for (j = 0; j < langs.length; j++) {
7552                              lang = langs[j];
7553                              packName = this.getLangPackName(lang, name);
7554                              supName = this.getLangPackName(lang, i);
7555                              smod = this.getModuleInfo(packName);
7556  
7557                              if (!smod) {
7558                                  smod = this._addLangPack(lang, o, packName);
7559                              }
7560  
7561                              flatSup = flatSup || yArray.hash(smod.supersedes);
7562  
7563                              if (!(supName in flatSup)) {
7564                                  smod.supersedes.push(supName);
7565                              }
7566  
7567                              o.lang = o.lang || [];
7568  
7569                              flatLang = flatLang || yArray.hash(o.lang);
7570  
7571                              if (!(lang in flatLang)) {
7572                                  o.lang.push(lang);
7573                              }
7574  
7575  // Y.log('pack ' + packName + ' should supersede ' + supName);
7576  // Add rollup file, need to add to supersedes list too
7577  
7578                              // default packages
7579                              packName = this.getLangPackName(ROOT_LANG, name);
7580                              supName = this.getLangPackName(ROOT_LANG, i);
7581  
7582                              smod = this.getModuleInfo(packName);
7583  
7584                              if (!smod) {
7585                                  smod = this._addLangPack(lang, o, packName);
7586                              }
7587  
7588                              if (!(supName in flatSup)) {
7589                                  smod.supersedes.push(supName);
7590                              }
7591  
7592  // Y.log('pack ' + packName + ' should supersede ' + supName);
7593  // Add rollup file, need to add to supersedes list too
7594  
7595                          }
7596                      }
7597  
7598                      l++;
7599                  }
7600              }
7601              //o.supersedes = YObject.keys(yArray.hash(sup));
7602              o.supersedes = yArray.dedupe(sup);
7603              if (this.allowRollup) {
7604                  o.rollup = (l < 4) ? l : Math.min(l - 1, 4);
7605              }
7606          }
7607  
7608          plugins = o.plugins;
7609          if (plugins) {
7610              for (i in plugins) {
7611                  if (plugins.hasOwnProperty(i)) {
7612                      plug = plugins[i];
7613                      plug.pkg = name;
7614                      plug.path = plug.path || _path(name, i, o.type);
7615                      plug.requires = plug.requires || [];
7616                      plug.group = o.group;
7617                      this.addModule(plug, i);
7618                      if (o.skinnable) {
7619                          this._addSkin(this.skin.defaultSkin, i, name);
7620                      }
7621  
7622                  }
7623              }
7624          }
7625  
7626          if (o.condition) {
7627              t = this._expandAliases(o.condition.trigger);
7628              for (i = 0; i < t.length; i++) {
7629                  trigger = t[i];
7630                  when = o.condition.when;
7631                  conditions[trigger] = conditions[trigger] || {};
7632                  conditions[trigger][name] = o.condition;
7633                  // the 'when' attribute can be 'before', 'after', or 'instead'
7634                  // the default is after.
7635                  if (when && when !== 'after') {
7636                      if (when === 'instead') { // replace the trigger
7637                          o.supersedes = o.supersedes || [];
7638                          o.supersedes.push(trigger);
7639                      }
7640                      // before the trigger
7641                          // the trigger requires the conditional mod,
7642                          // so it should appear before the conditional
7643                          // mod if we do not intersede.
7644                  } else { // after the trigger
7645                      o.after = o.after || [];
7646                      o.after.push(trigger);
7647                  }
7648              }
7649          }
7650  
7651          if (o.supersedes) {
7652              o.supersedes = this.filterRequires(o.supersedes);
7653          }
7654  
7655          if (o.after) {
7656              o.after = this.filterRequires(o.after);
7657              o.after_map = yArray.hash(o.after);
7658          }
7659  
7660          // this.dirty = true;
7661  
7662          if (o.configFn) {
7663              ret = o.configFn(o);
7664              if (ret === false) {
7665                  Y.log('Config function returned false for ' + name + ', skipping.', 'info', 'loader');
7666                  delete this.moduleInfo[name];
7667                  delete GLOBAL_ENV._renderedMods[name];
7668                  o = null;
7669              }
7670          }
7671          //Add to global cache
7672          if (o) {
7673              if (!GLOBAL_ENV._renderedMods) {
7674                  GLOBAL_ENV._renderedMods = {};
7675              }
7676              GLOBAL_ENV._renderedMods[name] = Y.mix(GLOBAL_ENV._renderedMods[name] || {}, o);
7677              GLOBAL_ENV._conditions = conditions;
7678          }
7679  
7680          return o;
7681      },
7682  
7683      /**
7684       * Add a requirement for one or more module
7685       * @method require
7686       * @param {string[] | string*} what the modules to load.
7687       */
7688      require: function(what) {
7689          var a = (typeof what === 'string') ? yArray(arguments) : what;
7690          this.dirty = true;
7691          this.required = Y.merge(this.required, yArray.hash(this.filterRequires(a)));
7692  
7693          this._explodeRollups();
7694      },
7695      /**
7696      * Grab all the items that were asked for, check to see if the Loader
7697      * meta-data contains a "use" array. If it doesm remove the asked item and replace it with
7698      * the content of the "use".
7699      * This will make asking for: "dd"
7700      * Actually ask for: "dd-ddm-base,dd-ddm,dd-ddm-drop,dd-drag,dd-proxy,dd-constrain,dd-drop,dd-scroll,dd-drop-plugin"
7701      * @private
7702      * @method _explodeRollups
7703      */
7704      _explodeRollups: function() {
7705          var self = this, m, m2, i, a, v, len, len2,
7706          r = self.required;
7707  
7708          if (!self.allowRollup) {
7709              for (i in r) {
7710                  if (r.hasOwnProperty(i)) {
7711                      m = self.getModule(i);
7712                      if (m && m.use) {
7713                          len = m.use.length;
7714                          for (a = 0; a < len; a++) {
7715                              m2 = self.getModule(m.use[a]);
7716                              if (m2 && m2.use) {
7717                                  len2 = m2.use.length;
7718                                  for (v = 0; v < len2; v++) {
7719                                      r[m2.use[v]] = true;
7720                                  }
7721                              } else {
7722                                  r[m.use[a]] = true;
7723                              }
7724                          }
7725                      }
7726                  }
7727              }
7728              self.required = r;
7729          }
7730  
7731      },
7732      /**
7733      * Explodes the required array to remove aliases and replace them with real modules
7734      * @method filterRequires
7735      * @param {Array} r The original requires array
7736      * @return {Array} The new array of exploded requirements
7737      */
7738      filterRequires: function(r) {
7739          if (r) {
7740              if (!Y.Lang.isArray(r)) {
7741                  r = [r];
7742              }
7743              r = Y.Array(r);
7744              var c = [], i, mod, o, m;
7745  
7746              for (i = 0; i < r.length; i++) {
7747                  mod = this.getModule(r[i]);
7748                  if (mod && mod.use) {
7749                      for (o = 0; o < mod.use.length; o++) {
7750                          //Must walk the other modules in case a module is a rollup of rollups (datatype)
7751                          m = this.getModule(mod.use[o]);
7752                          if (m && m.use && (m.name !== mod.name)) {
7753                              c = Y.Array.dedupe([].concat(c, this.filterRequires(m.use)));
7754                          } else {
7755                              c.push(mod.use[o]);
7756                          }
7757                      }
7758                  } else {
7759                      c.push(r[i]);
7760                  }
7761              }
7762              r = c;
7763          }
7764          return r;
7765      },
7766  
7767      /**
7768      Returns `true` if the module can be attached to the YUI instance. Runs
7769      the module's test if there is one and caches its result.
7770  
7771      @method _canBeAttached
7772      @param {String} module Name of the module to check.
7773      @return {Boolean} Result of the module's test if it has one, or `true`.
7774      **/
7775      _canBeAttached: function (m) {
7776          m = this.getModule(m);
7777          if (m && m.test) {
7778              if (!m.hasOwnProperty('_testResult')) {
7779                  m._testResult = m.test(Y);
7780              }
7781              return m._testResult;
7782          }
7783          // return `true` for modules not registered as Loader will know what
7784          // to do with them later on
7785          return true;
7786      },
7787  
7788      /**
7789       * Returns an object containing properties for all modules required
7790       * in order to load the requested module
7791       * @method getRequires
7792       * @param {object}  mod The module definition from moduleInfo.
7793       * @return {array} the expanded requirement list.
7794       */
7795      getRequires: function(mod) {
7796  
7797          if (!mod) {
7798              //console.log('returning no reqs for ' + mod.name);
7799              return NO_REQUIREMENTS;
7800          }
7801  
7802          if (mod._parsed) {
7803              //console.log('returning requires for ' + mod.name, mod.requires);
7804              return mod.expanded || NO_REQUIREMENTS;
7805          }
7806  
7807          //TODO add modue cache here out of scope..
7808  
7809          var i, m, j, length, add, packName, lang, testresults = this.testresults,
7810              name = mod.name, cond,
7811              adddef = ON_PAGE[name] && ON_PAGE[name].details,
7812              optReqs = mod.optionalRequires,
7813              d, go, def,
7814              r, old_mod,
7815              o, skinmod, skindef, skinpar, skinname,
7816              intl = mod.lang || mod.intl,
7817              ftests = Y.Features && Y.Features.tests.load,
7818              hash, reparse;
7819  
7820          // console.log(name);
7821  
7822          // pattern match leaves module stub that needs to be filled out
7823          if (mod.temp && adddef) {
7824              old_mod = mod;
7825              mod = this.addModule(adddef, name);
7826              mod.group = old_mod.group;
7827              mod.pkg = old_mod.pkg;
7828              delete mod.expanded;
7829          }
7830  
7831          // console.log('cache: ' + mod.langCache + ' == ' + this.lang);
7832  
7833          //If a skin or a lang is different, reparse..
7834          reparse = !((!this.lang || mod.langCache === this.lang) && (mod.skinCache === this.skin.defaultSkin));
7835  
7836          if (mod.expanded && !reparse) {
7837              //Y.log('Already expanded ' + name + ', ' + mod.expanded);
7838              return mod.expanded;
7839          }
7840  
7841          // Optional dependencies are dependencies that may or may not be
7842          // available.
7843          // This feature was designed specifically to be used when transpiling
7844          // ES6 modules, in order to use polyfills and regular scripts that define
7845          // global variables without having to import them since they should be
7846          // available in the global scope.
7847          if (optReqs) {
7848              for (i = 0, length = optReqs.length; i < length; i++) {
7849                  if (this._canBeAttached(optReqs[i])) {
7850                      mod.requires.push(optReqs[i]);
7851                  }
7852              }
7853          }
7854  
7855          d = [];
7856          hash = {};
7857          r = this.filterRequires(mod.requires);
7858          if (mod.lang) {
7859              //If a module has a lang attribute, auto add the intl requirement.
7860              d.unshift('intl');
7861              r.unshift('intl');
7862              intl = true;
7863          }
7864          o = this.filterRequires(mod.optional);
7865  
7866          // Y.log("getRequires: " + name + " (dirty:" + this.dirty +
7867          // ", expanded:" + mod.expanded + ")");
7868  
7869          mod._parsed = true;
7870          mod.langCache = this.lang;
7871          mod.skinCache = this.skin.defaultSkin;
7872  
7873          for (i = 0; i < r.length; i++) {
7874              //Y.log(name + ' requiring ' + r[i], 'info', 'loader');
7875              if (!hash[r[i]]) {
7876                  d.push(r[i]);
7877                  hash[r[i]] = true;
7878                  m = this.getModule(r[i]);
7879                  if (m) {
7880                      add = this.getRequires(m);
7881                      intl = intl || (m.expanded_map &&
7882                          (INTL in m.expanded_map));
7883                      for (j = 0; j < add.length; j++) {
7884                          d.push(add[j]);
7885                      }
7886                  }
7887              }
7888          }
7889  
7890          // get the requirements from superseded modules, if any
7891          r = this.filterRequires(mod.supersedes);
7892          if (r) {
7893              for (i = 0; i < r.length; i++) {
7894                  if (!hash[r[i]]) {
7895                      // if this module has submodules, the requirements list is
7896                      // expanded to include the submodules.  This is so we can
7897                      // prevent dups when a submodule is already loaded and the
7898                      // parent is requested.
7899                      if (mod.submodules) {
7900                          d.push(r[i]);
7901                      }
7902  
7903                      hash[r[i]] = true;
7904                      m = this.getModule(r[i]);
7905  
7906                      if (m) {
7907                          add = this.getRequires(m);
7908                          intl = intl || (m.expanded_map &&
7909                              (INTL in m.expanded_map));
7910                          for (j = 0; j < add.length; j++) {
7911                              d.push(add[j]);
7912                          }
7913                      }
7914                  }
7915              }
7916          }
7917  
7918          if (o && this.loadOptional) {
7919              for (i = 0; i < o.length; i++) {
7920                  if (!hash[o[i]]) {
7921                      d.push(o[i]);
7922                      hash[o[i]] = true;
7923                      m = this.getModuleInfo(o[i]);
7924                      if (m) {
7925                          add = this.getRequires(m);
7926                          intl = intl || (m.expanded_map &&
7927                              (INTL in m.expanded_map));
7928                          for (j = 0; j < add.length; j++) {
7929                              d.push(add[j]);
7930                          }
7931                      }
7932                  }
7933              }
7934          }
7935  
7936          cond = this.conditions[name];
7937  
7938          if (cond) {
7939              //Set the module to not parsed since we have conditionals and this could change the dependency tree.
7940              mod._parsed = false;
7941              if (testresults && ftests) {
7942                  oeach(testresults, function(result, id) {
7943                      var condmod = ftests[id].name;
7944                      if (!hash[condmod] && ftests[id].trigger === name) {
7945                          if (result && ftests[id]) {
7946                              hash[condmod] = true;
7947                              d.push(condmod);
7948                          }
7949                      }
7950                  });
7951              } else {
7952                  for (i in cond) {
7953                      if (cond.hasOwnProperty(i)) {
7954                          if (!hash[i]) {
7955                              def = cond[i];
7956                              //first see if they've specfied a ua check
7957                              //then see if they've got a test fn & if it returns true
7958                              //otherwise just having a condition block is enough
7959                              go = def && ((!def.ua && !def.test) || (def.ua && Y.UA[def.ua]) ||
7960                                          (def.test && def.test(Y, r)));
7961  
7962                              if (go) {
7963                                  hash[i] = true;
7964                                  d.push(i);
7965                                  m = this.getModule(i);
7966                                  if (m) {
7967                                      add = this.getRequires(m);
7968                                      for (j = 0; j < add.length; j++) {
7969                                          d.push(add[j]);
7970                                      }
7971  
7972                                  }
7973                              }
7974                          }
7975                      }
7976                  }
7977              }
7978          }
7979  
7980          // Create skin modules
7981          if (mod.skinnable) {
7982              skindef = this.skin.overrides;
7983              for (i in YUI.Env.aliases) {
7984                  if (YUI.Env.aliases.hasOwnProperty(i)) {
7985                      if (Y.Array.indexOf(YUI.Env.aliases[i], name) > -1) {
7986                          skinpar = i;
7987                      }
7988                  }
7989              }
7990              if (skindef && (skindef[name] || (skinpar && skindef[skinpar]))) {
7991                  skinname = name;
7992                  if (skindef[skinpar]) {
7993                      skinname = skinpar;
7994                  }
7995                  for (i = 0; i < skindef[skinname].length; i++) {
7996                      skinmod = this._addSkin(skindef[skinname][i], name);
7997                      if (!this.isCSSLoaded(skinmod, this._boot)) {
7998                          d.push(skinmod);
7999                      }
8000                  }
8001              } else {
8002                  skinmod = this._addSkin(this.skin.defaultSkin, name);
8003                  if (!this.isCSSLoaded(skinmod, this._boot)) {
8004                      d.push(skinmod);
8005                  }
8006              }
8007          }
8008  
8009          mod._parsed = false;
8010  
8011          if (intl) {
8012  
8013              if (mod.lang && !mod.langPack && Y.Intl) {
8014                  lang = Y.Intl.lookupBestLang(this.lang || ROOT_LANG, mod.lang);
8015                  //Y.log('Best lang: ' + lang + ', this.lang: ' + this.lang + ', mod.lang: ' + mod.lang);
8016                  packName = this.getLangPackName(lang, name);
8017                  if (packName) {
8018                      d.unshift(packName);
8019                  }
8020              }
8021              d.unshift(INTL);
8022          }
8023  
8024          mod.expanded_map = yArray.hash(d);
8025  
8026          mod.expanded = YObject.keys(mod.expanded_map);
8027  
8028          return mod.expanded;
8029      },
8030      /**
8031      * Check to see if named css module is already loaded on the page
8032      * @method isCSSLoaded
8033      * @param {String} name The name of the css file
8034      * @param {Boolean} skip To skip the short-circuit for ignoreRegister
8035      * @return Boolean
8036      */
8037      isCSSLoaded: function(name, skip) {
8038          //TODO - Make this call a batching call with name being an array
8039          if (!name || !YUI.Env.cssStampEl || (!skip && this.ignoreRegistered)) {
8040              Y.log('isCSSLoaded was skipped for ' + name, 'warn', 'loader');
8041              return false;
8042          }
8043          var el = YUI.Env.cssStampEl,
8044              ret = false,
8045              mod = YUI.Env._cssLoaded[name],
8046              style = el.currentStyle; //IE
8047  
8048  
8049          if (mod !== undefined) {
8050              //Y.log('isCSSLoaded was cached for ' + name, 'warn', 'loader');
8051              return mod;
8052          }
8053  
8054          //Add the classname to the element
8055          el.className = name;
8056  
8057          if (!style) {
8058              style = Y.config.doc.defaultView.getComputedStyle(el, null);
8059          }
8060  
8061          if (style && style.display === 'none') {
8062              ret = true;
8063          }
8064  
8065          Y.log('Has Skin? ' + name + ' : ' + ret, 'info', 'loader');
8066  
8067          el.className = ''; //Reset the classname to ''
8068  
8069          YUI.Env._cssLoaded[name] = ret;
8070  
8071          return ret;
8072      },
8073  
8074      /**
8075       * Returns a hash of module names the supplied module satisfies.
8076       * @method getProvides
8077       * @param {string} name The name of the module.
8078       * @return {object} what this module provides.
8079       */
8080      getProvides: function(name) {
8081          var m = this.getModule(name), o, s;
8082              // supmap = this.provides;
8083  
8084          if (!m) {
8085              return NOT_FOUND;
8086          }
8087  
8088          if (m && !m.provides) {
8089              o = {};
8090              s = m.supersedes;
8091  
8092              if (s) {
8093                  yArray.each(s, function(v) {
8094                      Y.mix(o, this.getProvides(v));
8095                  }, this);
8096              }
8097  
8098              o[name] = true;
8099              m.provides = o;
8100  
8101          }
8102  
8103          return m.provides;
8104      },
8105  
8106      /**
8107       * Calculates the dependency tree, the result is stored in the sorted
8108       * property.
8109       * @method calculate
8110       * @param {object} o optional options object.
8111       * @param {string} type optional argument to prune modules.
8112       */
8113      calculate: function(o, type) {
8114          if (o || type || this.dirty) {
8115  
8116              if (o) {
8117                  this._config(o);
8118              }
8119  
8120              if (!this._init) {
8121                  this._setup();
8122              }
8123  
8124              this._explode();
8125  
8126              if (this.allowRollup) {
8127                  this._rollup();
8128              } else {
8129                  this._explodeRollups();
8130              }
8131              this._reduce();
8132              this._sort();
8133          }
8134      },
8135      /**
8136      * Creates a "psuedo" package for languages provided in the lang array
8137      * @method _addLangPack
8138      * @private
8139      * @param {String} lang The language to create
8140      * @param {Object} m The module definition to create the language pack around
8141      * @param {String} packName The name of the package (e.g: lang/datatype-date-en-US)
8142      * @return {Object} The module definition
8143      */
8144      _addLangPack: function(lang, m, packName) {
8145          var name = m.name,
8146              packPath, conf,
8147              existing = this.getModuleInfo(packName);
8148  
8149          if (!existing) {
8150  
8151              packPath = _path((m.pkg || name), packName, JS, true);
8152  
8153              conf = {
8154                  path: packPath,
8155                  intl: true,
8156                  langPack: true,
8157                  ext: m.ext,
8158                  group: m.group,
8159                  supersedes: []
8160              };
8161              if (m.root) {
8162                  conf.root = m.root;
8163              }
8164              if (m.base) {
8165                  conf.base = m.base;
8166              }
8167  
8168              if (m.configFn) {
8169                  conf.configFn = m.configFn;
8170              }
8171  
8172              this.addModule(conf, packName);
8173  
8174              if (lang) {
8175                  Y.Env.lang = Y.Env.lang || {};
8176                  Y.Env.lang[lang] = Y.Env.lang[lang] || {};
8177                  Y.Env.lang[lang][name] = true;
8178              }
8179          }
8180  
8181          return this.getModuleInfo(packName);
8182      },
8183  
8184      /**
8185       * Investigates the current YUI configuration on the page.  By default,
8186       * modules already detected will not be loaded again unless a force
8187       * option is encountered.  Called by calculate()
8188       * @method _setup
8189       * @private
8190       */
8191      _setup: function() {
8192          var info = this.moduleInfo, name, i, j, m, l,
8193              packName;
8194  
8195          for (name in info) {
8196              if (info.hasOwnProperty(name)) {
8197                  m = info[name];
8198                  if (m) {
8199  
8200                      // remove dups
8201                      //m.requires = YObject.keys(yArray.hash(m.requires));
8202                      m.requires = yArray.dedupe(m.requires);
8203  
8204                      // Create lang pack modules
8205                      //if (m.lang && m.lang.length) {
8206                      if (m.lang) {
8207                          // Setup root package if the module has lang defined,
8208                          // it needs to provide a root language pack
8209                          packName = this.getLangPackName(ROOT_LANG, name);
8210                          this._addLangPack(null, m, packName);
8211                      }
8212  
8213                  }
8214              }
8215          }
8216  
8217  
8218          //l = Y.merge(this.inserted);
8219          l = {};
8220  
8221          // available modules
8222          if (!this.ignoreRegistered) {
8223              Y.mix(l, GLOBAL_ENV.mods);
8224          }
8225  
8226          // add the ignore list to the list of loaded packages
8227          if (this.ignore) {
8228              Y.mix(l, yArray.hash(this.ignore));
8229          }
8230  
8231          // expand the list to include superseded modules
8232          for (j in l) {
8233              if (l.hasOwnProperty(j)) {
8234                  Y.mix(l, this.getProvides(j));
8235              }
8236          }
8237  
8238          // remove modules on the force list from the loaded list
8239          if (this.force) {
8240              for (i = 0; i < this.force.length; i++) {
8241                  if (this.force[i] in l) {
8242                      delete l[this.force[i]];
8243                  }
8244              }
8245          }
8246  
8247          Y.mix(this.loaded, l);
8248  
8249          this._init = true;
8250      },
8251  
8252      /**
8253       * Builds a module name for a language pack
8254       * @method getLangPackName
8255       * @param {string} lang the language code.
8256       * @param {string} mname the module to build it for.
8257       * @return {string} the language pack module name.
8258       */
8259      getLangPackName: function(lang, mname) {
8260          return ('lang/' + mname + ((lang) ? '_' + lang : ''));
8261      },
8262      /**
8263       * Inspects the required modules list looking for additional
8264       * dependencies.  Expands the required list to include all
8265       * required modules.  Called by calculate()
8266       * @method _explode
8267       * @private
8268       */
8269      _explode: function() {
8270          //TODO Move done out of scope
8271          var r = this.required, m, reqs, done = {},
8272              self = this, name, expound;
8273  
8274          // the setup phase is over, all modules have been created
8275          self.dirty = false;
8276  
8277          self._explodeRollups();
8278          r = self.required;
8279  
8280          for (name in r) {
8281              if (r.hasOwnProperty(name)) {
8282                  if (!done[name]) {
8283                      done[name] = true;
8284                      m = self.getModule(name);
8285                      if (m) {
8286                          expound = m.expound;
8287  
8288                          if (expound) {
8289                              r[expound] = self.getModule(expound);
8290                              reqs = self.getRequires(r[expound]);
8291                              Y.mix(r, yArray.hash(reqs));
8292                          }
8293  
8294                          reqs = self.getRequires(m);
8295                          Y.mix(r, yArray.hash(reqs));
8296                      }
8297                  }
8298              }
8299          }
8300  
8301          // Y.log('After explode: ' + YObject.keys(r));
8302      },
8303      /**
8304      * The default method used to test a module against a pattern
8305      * @method _patternTest
8306      * @private
8307      * @param {String} mname The module being tested
8308      * @param {String} pname The pattern to match
8309      */
8310      _patternTest: function(mname, pname) {
8311          return (mname.indexOf(pname) > -1);
8312      },
8313      /**
8314      * Get's the loader meta data for the requested module
8315      * @method getModule
8316      * @param {String} mname The module name to get
8317      * @return {Object} The module metadata
8318      */
8319      getModule: function(mname) {
8320          //TODO: Remove name check - it's a quick hack to fix pattern WIP
8321          if (!mname) {
8322              return null;
8323          }
8324  
8325          var p, found, pname,
8326              m = this.getModuleInfo(mname),
8327              patterns = this.patterns;
8328  
8329          // check the patterns library to see if we should automatically add
8330          // the module with defaults
8331          if (!m || (m && m.ext)) {
8332             // Y.log('testing patterns ' + YObject.keys(patterns));
8333              for (pname in patterns) {
8334                  if (patterns.hasOwnProperty(pname)) {
8335                      // Y.log('testing pattern ' + i);
8336                      p = patterns[pname];
8337  
8338                      //There is no test method, create a default one that tests
8339                      // the pattern against the mod name
8340                      if (!p.test) {
8341                          p.test = this._patternTest;
8342                      }
8343  
8344                      if (p.test(mname, pname)) {
8345                          // use the metadata supplied for the pattern
8346                          // as the module definition.
8347                          found = p;
8348                          break;
8349                      }
8350                  }
8351              }
8352          }
8353  
8354          if (!m) {
8355              if (found) {
8356                  if (p.action) {
8357                      // Y.log('executing pattern action: ' + pname);
8358                      p.action.call(this, mname, pname);
8359                  } else {
8360  Y.log('Undefined module: ' + mname + ', matched a pattern: ' +
8361      pname, 'info', 'loader');
8362                      // ext true or false?
8363                      m = this.addModule(Y.merge(found, {
8364                          test: void 0,
8365                          temp: true
8366                      }), mname);
8367                      if (found.configFn) {
8368                          m.configFn = found.configFn;
8369                      }
8370                  }
8371              }
8372          } else {
8373              if (found && m && found.configFn && !m.configFn) {
8374                  m.configFn = found.configFn;
8375                  m.configFn(m);
8376              }
8377          }
8378  
8379          return m;
8380      },
8381  
8382      // impl in rollup submodule
8383      _rollup: function() { },
8384  
8385      /**
8386       * Remove superceded modules and loaded modules.  Called by
8387       * calculate() after we have the mega list of all dependencies
8388       * @method _reduce
8389       * @return {object} the reduced dependency hash.
8390       * @private
8391       */
8392      _reduce: function(r) {
8393  
8394          r = r || this.required;
8395  
8396          var i, j, s, m, type = this.loadType,
8397          ignore = this.ignore ? yArray.hash(this.ignore) : false;
8398  
8399          for (i in r) {
8400              if (r.hasOwnProperty(i)) {
8401                  m = this.getModule(i);
8402                  // remove if already loaded
8403                  if (((this.loaded[i] || ON_PAGE[i]) &&
8404                          !this.forceMap[i] && !this.ignoreRegistered) ||
8405                          (type && m && m.type !== type)) {
8406                      delete r[i];
8407                  }
8408                  if (ignore && ignore[i]) {
8409                      delete r[i];
8410                  }
8411                  // remove anything this module supersedes
8412                  s = m && m.supersedes;
8413                  if (s) {
8414                      for (j = 0; j < s.length; j++) {
8415                          if (s[j] in r) {
8416                              delete r[s[j]];
8417                          }
8418                      }
8419                  }
8420              }
8421          }
8422  
8423          return r;
8424      },
8425      /**
8426      * Handles the queue when a module has been loaded for all cases
8427      * @method _finish
8428      * @private
8429      * @param {String} msg The message from Loader
8430      * @param {Boolean} success A boolean denoting success or failure
8431      */
8432      _finish: function(msg, success) {
8433          Y.log('loader finishing: ' + msg + ', ' + Y.id + ', ' +
8434              this.data, 'info', 'loader');
8435  
8436          _queue.running = false;
8437  
8438          var onEnd = this.onEnd;
8439          if (onEnd) {
8440              onEnd.call(this.context, {
8441                  msg: msg,
8442                  data: this.data,
8443                  success: success
8444              });
8445          }
8446          this._continue();
8447      },
8448      /**
8449      * The default Loader onSuccess handler, calls this.onSuccess with a payload
8450      * @method _onSuccess
8451      * @private
8452      */
8453      _onSuccess: function() {
8454          var self = this, skipped = Y.merge(self.skipped), fn,
8455              failed = [], rreg = self.requireRegistration,
8456              success, msg, i, mod;
8457  
8458          for (i in skipped) {
8459              if (skipped.hasOwnProperty(i)) {
8460                  delete self.inserted[i];
8461              }
8462          }
8463  
8464          self.skipped = {};
8465  
8466          for (i in self.inserted) {
8467              if (self.inserted.hasOwnProperty(i)) {
8468                  mod = self.getModule(i);
8469                  if (mod && rreg && mod.type === JS && !(i in YUI.Env.mods)) {
8470                      failed.push(i);
8471                  } else {
8472                      Y.mix(self.loaded, self.getProvides(i));
8473                  }
8474              }
8475          }
8476  
8477          fn = self.onSuccess;
8478          msg = (failed.length) ? 'notregistered' : 'success';
8479          success = !(failed.length);
8480          if (fn) {
8481              fn.call(self.context, {
8482                  msg: msg,
8483                  data: self.data,
8484                  success: success,
8485                  failed: failed,
8486                  skipped: skipped
8487              });
8488          }
8489          self._finish(msg, success);
8490      },
8491      /**
8492      * The default Loader onProgress handler, calls this.onProgress with a payload
8493      * @method _onProgress
8494      * @private
8495      */
8496      _onProgress: function(e) {
8497          var self = this, i;
8498          //set the internal cache to what just came in.
8499          if (e.data && e.data.length) {
8500              for (i = 0; i < e.data.length; i++) {
8501                  e.data[i] = self.getModule(e.data[i].name);
8502              }
8503          }
8504          if (self.onProgress) {
8505              self.onProgress.call(self.context, {
8506                  name: e.url,
8507                  data: e.data
8508              });
8509          }
8510      },
8511      /**
8512      * The default Loader onFailure handler, calls this.onFailure with a payload
8513      * @method _onFailure
8514      * @private
8515      */
8516      _onFailure: function(o) {
8517          var f = this.onFailure, msg = [], i = 0, len = o.errors.length;
8518  
8519          for (i; i < len; i++) {
8520              msg.push(o.errors[i].error);
8521          }
8522  
8523          msg = msg.join(',');
8524  
8525          Y.log('load error: ' + msg + ', ' + Y.id, 'error', 'loader');
8526  
8527          if (f) {
8528              f.call(this.context, {
8529                  msg: msg,
8530                  data: this.data,
8531                  success: false
8532              });
8533          }
8534  
8535          this._finish(msg, false);
8536  
8537      },
8538  
8539      /**
8540      * The default Loader onTimeout handler, calls this.onTimeout with a payload
8541      * @method _onTimeout
8542      * @param {Get.Transaction} transaction The Transaction object from `Y.Get`
8543      * @private
8544      */
8545      _onTimeout: function(transaction) {
8546          Y.log('loader timeout: ' + Y.id, 'error', 'loader');
8547          var f = this.onTimeout;
8548          if (f) {
8549              f.call(this.context, {
8550                  msg: 'timeout',
8551                  data: this.data,
8552                  success: false,
8553                  transaction: transaction
8554              });
8555          }
8556      },
8557  
8558      /**
8559       * Sorts the dependency tree.  The last step of calculate()
8560       * @method _sort
8561       * @private
8562       */
8563      _sort: function() {
8564          var name,
8565  
8566              // Object containing module names.
8567              required = this.required,
8568  
8569              // Keep track of whether we've visited a module.
8570              visited = {};
8571  
8572          // Will contain modules names, in the correct order,
8573          // according to dependencies.
8574          this.sorted = [];
8575  
8576          for (name in required) {
8577              if (!visited[name] && required.hasOwnProperty(name)) {
8578                  this._visit(name, visited);
8579              }
8580          }
8581      },
8582  
8583      /**
8584       * Recursively visits the dependencies of the module name
8585       * passed in, and appends each module name to the `sorted` property.
8586       * @param {String} name The name of a module.
8587       * @param {Object} visited Keeps track of whether a module was visited.
8588       * @method _visit
8589       * @private
8590       */
8591      _visit: function (name, visited) {
8592          var required, condition, moduleInfo, dependency, dependencies,
8593              trigger, isAfter, i, l;
8594  
8595          visited[name] = true;
8596          required = this.required;
8597          moduleInfo = this.moduleInfo[name];
8598          condition = this.conditions[name] || {};
8599  
8600          if (moduleInfo) {
8601              // Recurse on each dependency of this module,
8602              // figuring out its dependencies, and so on.
8603              dependencies = moduleInfo.expanded || moduleInfo.requires;
8604  
8605              for (i = 0, l = dependencies.length; i < l; ++i) {
8606                  dependency = dependencies[i];
8607                  trigger = condition[dependency];
8608  
8609                  // We cannot process this dependency yet if it must
8610                  // appear after our current module.
8611                  isAfter = trigger && (!trigger.when || trigger.when === "after");
8612  
8613                  // Is this module name in the required list of modules,
8614                  // and have we not already visited it?
8615                  if (required[dependency] && !visited[dependency] && !isAfter) {
8616                      this._visit(dependency, visited);
8617                  }
8618              }
8619          }
8620  
8621          this.sorted.push(name);
8622      },
8623  
8624      /**
8625      * Handles the actual insertion of script/link tags
8626      * @method _insert
8627      * @private
8628      * @param {Object} source The YUI instance the request came from
8629      * @param {Object} o The metadata to include
8630      * @param {String} type JS or CSS
8631      * @param {Boolean} [skipcalc=false] Do a Loader.calculate on the meta
8632      */
8633      _insert: function(source, o, type, skipcalc) {
8634  
8635          Y.log('private _insert() ' + (type || '') + ', ' + Y.id, "info", "loader");
8636  
8637          // restore the state at the time of the request
8638          if (source) {
8639              this._config(source);
8640          }
8641  
8642          // build the dependency list
8643          // don't include type so we can process CSS and script in
8644          // one pass when the type is not specified.
8645  
8646          var modules = this.resolve(!skipcalc),
8647              self = this, comp = 0, actions = 0,
8648              mods = {}, deps, complete;
8649  
8650          self._refetch = [];
8651  
8652          if (type) {
8653              //Filter out the opposite type and reset the array so the checks later work
8654              modules[((type === JS) ? CSS : JS)] = [];
8655          }
8656          if (!self.fetchCSS) {
8657              modules.css = [];
8658          }
8659          if (modules.js.length) {
8660              comp++;
8661          }
8662          if (modules.css.length) {
8663              comp++;
8664          }
8665  
8666          //console.log('Resolved Modules: ', modules);
8667  
8668          complete = function(d) {
8669              actions++;
8670              var errs = {}, i = 0, o = 0, u = '', fn,
8671                  modName, resMods;
8672  
8673              if (d && d.errors) {
8674                  for (i = 0; i < d.errors.length; i++) {
8675                      if (d.errors[i].request) {
8676                          u = d.errors[i].request.url;
8677                      } else {
8678                          u = d.errors[i];
8679                      }
8680                      errs[u] = u;
8681                  }
8682              }
8683  
8684              if (d && d.data && d.data.length && (d.type === 'success')) {
8685                  for (i = 0; i < d.data.length; i++) {
8686                      self.inserted[d.data[i].name] = true;
8687                      //If the external module has a skin or a lang, reprocess it
8688                      if (d.data[i].lang || d.data[i].skinnable) {
8689                          delete self.inserted[d.data[i].name];
8690                          self._refetch.push(d.data[i].name);
8691                      }
8692                  }
8693              }
8694  
8695              if (actions === comp) {
8696                  self._loading = null;
8697                  Y.log('Loader actions complete!', 'info', 'loader');
8698                  if (self._refetch.length) {
8699                      //Get the deps for the new meta-data and reprocess
8700                      Y.log('Found potential modules to refetch', 'info', 'loader');
8701                      for (i = 0; i < self._refetch.length; i++) {
8702                          deps = self.getRequires(self.getModule(self._refetch[i]));
8703                          for (o = 0; o < deps.length; o++) {
8704                              if (!self.inserted[deps[o]]) {
8705                                  //We wouldn't be to this point without the module being here
8706                                  mods[deps[o]] = deps[o];
8707                              }
8708                          }
8709                      }
8710                      mods = Y.Object.keys(mods);
8711                      if (mods.length) {
8712                          Y.log('Refetching modules with new meta-data', 'info', 'loader');
8713                          self.require(mods);
8714                          resMods = self.resolve(true);
8715                          if (resMods.cssMods.length) {
8716                              for (i=0; i <  resMods.cssMods.length; i++) {
8717                                  modName = resMods.cssMods[i].name;
8718                                  delete YUI.Env._cssLoaded[modName];
8719                                  if (self.isCSSLoaded(modName)) {
8720                                      self.inserted[modName] = true;
8721                                      delete self.required[modName];
8722                                  }
8723                              }
8724                              self.sorted = [];
8725                              self._sort();
8726                          }
8727                          d = null; //bail
8728                          self._insert(); //insert the new deps
8729                      }
8730                  }
8731                  if (d && d.fn) {
8732                      Y.log('Firing final Loader callback!', 'info', 'loader');
8733                      fn = d.fn;
8734                      delete d.fn;
8735                      fn.call(self, d);
8736                  }
8737              }
8738          };
8739  
8740          this._loading = true;
8741  
8742          if (!modules.js.length && !modules.css.length) {
8743              Y.log('No modules resolved..', 'warn', 'loader');
8744              actions = -1;
8745              complete({
8746                  fn: self._onSuccess
8747              });
8748              return;
8749          }
8750  
8751  
8752          if (modules.css.length) { //Load CSS first
8753              Y.log('Loading CSS modules', 'info', 'loader');
8754              Y.Get.css(modules.css, {
8755                  data: modules.cssMods,
8756                  attributes: self.cssAttributes,
8757                  insertBefore: self.insertBefore,
8758                  charset: self.charset,
8759                  timeout: self.timeout,
8760                  context: self,
8761                  onProgress: function(e) {
8762                      self._onProgress.call(self, e);
8763                  },
8764                  onTimeout: function(d) {
8765                      self._onTimeout.call(self, d);
8766                  },
8767                  onSuccess: function(d) {
8768                      d.type = 'success';
8769                      d.fn = self._onSuccess;
8770                      complete.call(self, d);
8771                  },
8772                  onFailure: function(d) {
8773                      d.type = 'failure';
8774                      d.fn = self._onFailure;
8775                      complete.call(self, d);
8776                  }
8777              });
8778          }
8779  
8780          if (modules.js.length) {
8781              Y.log('Loading JS modules', 'info', 'loader');
8782              Y.Get.js(modules.js, {
8783                  data: modules.jsMods,
8784                  insertBefore: self.insertBefore,
8785                  attributes: self.jsAttributes,
8786                  charset: self.charset,
8787                  timeout: self.timeout,
8788                  autopurge: false,
8789                  context: self,
8790                  async: self.async,
8791                  onProgress: function(e) {
8792                      self._onProgress.call(self, e);
8793                  },
8794                  onTimeout: function(d) {
8795                      self._onTimeout.call(self, d);
8796                  },
8797                  onSuccess: function(d) {
8798                      d.type = 'success';
8799                      d.fn = self._onSuccess;
8800                      complete.call(self, d);
8801                  },
8802                  onFailure: function(d) {
8803                      d.type = 'failure';
8804                      d.fn = self._onFailure;
8805                      complete.call(self, d);
8806                  }
8807              });
8808          }
8809      },
8810      /**
8811      * Once a loader operation is completely finished, process any additional queued items.
8812      * @method _continue
8813      * @private
8814      */
8815      _continue: function() {
8816          if (!(_queue.running) && _queue.size() > 0) {
8817              _queue.running = true;
8818              _queue.next()();
8819          }
8820      },
8821  
8822      /**
8823       * inserts the requested modules and their dependencies.
8824       * <code>type</code> can be "js" or "css".  Both script and
8825       * css are inserted if type is not provided.
8826       * @method insert
8827       * @param {object} o optional options object.
8828       * @param {string} type the type of dependency to insert.
8829       */
8830      insert: function(o, type, skipsort) {
8831          Y.log('public insert() ' + (type || '') + ', ' + Y.Object.keys(this.required), "info", "loader");
8832          var self = this, copy = Y.merge(this);
8833          delete copy.require;
8834          delete copy.dirty;
8835          _queue.add(function() {
8836              self._insert(copy, o, type, skipsort);
8837          });
8838          this._continue();
8839      },
8840  
8841      /**
8842       * Executed every time a module is loaded, and if we are in a load
8843       * cycle, we attempt to load the next script.  Public so that it
8844       * is possible to call this if using a method other than
8845       * Y.register to determine when scripts are fully loaded
8846       * @method loadNext
8847       * @deprecated
8848       * @param {string} mname optional the name of the module that has
8849       * been loaded (which is usually why it is time to load the next
8850       * one).
8851       */
8852      loadNext: function() {
8853          Y.log('loadNext was called..', 'error', 'loader');
8854          return;
8855      },
8856  
8857      /**
8858       * Apply filter defined for this instance to a url/path
8859       * @method _filter
8860       * @param {string} u the string to filter.
8861       * @param {string} name the name of the module, if we are processing
8862       * a single module as opposed to a combined url.
8863       * @return {string} the filtered string.
8864       * @private
8865       */
8866      _filter: function(u, name, group) {
8867          var f = this.filter,
8868              hasFilter = name && (name in this.filters),
8869              modFilter = hasFilter && this.filters[name],
8870              groupName = group || (this.getModuleInfo(name) || {}).group || null;
8871  
8872          if (groupName && this.groups[groupName] && this.groups[groupName].filter) {
8873              modFilter = this.groups[groupName].filter;
8874              hasFilter = true;
8875          }
8876  
8877          if (u) {
8878              if (hasFilter) {
8879                  f = (L.isString(modFilter)) ? this.FILTER_DEFS[modFilter.toUpperCase()] || null : modFilter;
8880              }
8881              if (f) {
8882                  u = u.replace(new RegExp(f.searchExp, 'g'), f.replaceStr);
8883              }
8884          }
8885          return u;
8886      },
8887  
8888      /**
8889       * Generates the full url for a module
8890       * @method _url
8891       * @param {string} path the path fragment.
8892       * @param {String} name The name of the module
8893       * @param {String} [base] The base url to use. Defaults to self.base
8894       * @return {string} the full url.
8895       * @private
8896       */
8897      _url: function(path, name, base) {
8898          return this._filter((base || this.base || '') + path, name);
8899      },
8900      /**
8901      * Returns an Object hash of file arrays built from `loader.sorted` or from an arbitrary list of sorted modules.
8902      * @method resolve
8903      * @param {Boolean} [calc=false] Perform a loader.calculate() before anything else
8904      * @param {Array} [sorted=loader.sorted] An override for the loader.sorted array
8905      * @return {Object} Object hash (js and css) of two arrays of file lists
8906      * @example This method can be used as an off-line dep calculator
8907      *
8908      *        var Y = YUI();
8909      *        var loader = new Y.Loader({
8910      *            filter: 'debug',
8911      *            base: '../../',
8912      *            root: 'build/',
8913      *            combine: true,
8914      *            require: ['node', 'dd', 'console']
8915      *        });
8916      *        var out = loader.resolve(true);
8917      *
8918      */
8919      resolve: function(calc, sorted) {
8920          var self     = this,
8921              resolved = { js: [], jsMods: [], css: [], cssMods: [] },
8922              addSingle;
8923  
8924          if (self.skin.overrides || self.skin.defaultSkin !== DEFAULT_SKIN || self.ignoreRegistered) {
8925              self._resetModules();
8926          }
8927  
8928          if (calc) {
8929              self.calculate();
8930          }
8931          sorted = sorted || self.sorted;
8932  
8933          addSingle = function(mod) {
8934              if (mod) {
8935                  var group = (mod.group && self.groups[mod.group]) || NOT_FOUND,
8936                      url;
8937  
8938                  //Always assume it's async
8939                  if (group.async === false) {
8940                      mod.async = group.async;
8941                  }
8942  
8943                  url = (mod.fullpath) ? self._filter(mod.fullpath, mod.name) :
8944                        self._url(mod.path, mod.name, group.base || mod.base);
8945  
8946                  if (mod.attributes || mod.async === false) {
8947                      url = {
8948                          url: url,
8949                          async: mod.async
8950                      };
8951                      if (mod.attributes) {
8952                          url.attributes = mod.attributes;
8953                      }
8954                  }
8955                  resolved[mod.type].push(url);
8956                  resolved[mod.type + 'Mods'].push(mod);
8957              } else {
8958                  Y.log('Undefined Module', 'warn', 'loader');
8959              }
8960  
8961          };
8962  
8963          /*jslint vars: true */
8964          var inserted     = (self.ignoreRegistered) ? {} : self.inserted,
8965              comboSources = {},
8966              maxURLLength,
8967              comboMeta,
8968              comboBase,
8969              comboSep,
8970              group,
8971              mod,
8972              len,
8973              i;
8974          /*jslint vars: false */
8975  
8976          for (i = 0, len = sorted.length; i < len; i++) {
8977              mod = self.getModule(sorted[i]);
8978              if (!mod || inserted[mod.name]) {
8979                  continue;
8980              }
8981  
8982              group = self.groups[mod.group];
8983  
8984              comboBase = self.comboBase;
8985  
8986              if (group) {
8987                  if (!group.combine || mod.fullpath) {
8988                      //This is not a combo module, skip it and load it singly later.
8989                      addSingle(mod);
8990                      continue;
8991                  }
8992                  mod.combine = true;
8993  
8994                  if (typeof group.root === 'string') {
8995                      mod.root = group.root;
8996                  }
8997  
8998                  comboBase    = group.comboBase || comboBase;
8999                  comboSep     = group.comboSep;
9000                  maxURLLength = group.maxURLLength;
9001              } else {
9002                  if (!self.combine) {
9003                      //This is not a combo module, skip it and load it singly later.
9004                      addSingle(mod);
9005                      continue;
9006                  }
9007              }
9008  
9009              if (!mod.combine && mod.ext) {
9010                  addSingle(mod);
9011                  continue;
9012              }
9013  
9014              comboSources[comboBase] = comboSources[comboBase] ||
9015                  { js: [], jsMods: [], css: [], cssMods: [] };
9016  
9017              comboMeta               = comboSources[comboBase];
9018              comboMeta.group         = mod.group;
9019              comboMeta.comboSep      = comboSep || self.comboSep;
9020              comboMeta.maxURLLength  = maxURLLength || self.maxURLLength;
9021  
9022              comboMeta[mod.type + 'Mods'].push(mod);
9023          }
9024  
9025          // TODO: Refactor the encoding logic below into its own method.
9026  
9027          /*jslint vars: true */
9028          var fragSubset,
9029              modules,
9030              tmpBase,
9031              baseLen,
9032              frags,
9033              frag,
9034              type;
9035          /*jslint vars: false */
9036  
9037          for (comboBase in comboSources) {
9038              if (comboSources.hasOwnProperty(comboBase)) {
9039                  comboMeta    = comboSources[comboBase];
9040                  comboSep     = comboMeta.comboSep;
9041                  maxURLLength = comboMeta.maxURLLength;
9042                  Y.log('Using maxURLLength of ' + maxURLLength, 'info', 'loader');
9043                  for (type in comboMeta) {
9044                      if (type === JS || type === CSS) {
9045                          modules = comboMeta[type + 'Mods'];
9046                          frags = [];
9047                          for (i = 0, len = modules.length; i < len; i += 1) {
9048                              mod = modules[i];
9049                              frag = ((typeof mod.root === 'string') ? mod.root : self.root) + (mod.path || mod.fullpath);
9050                              frags.push(
9051                                  self._filter(frag, mod.name)
9052                              );
9053                          }
9054                          tmpBase = comboBase + frags.join(comboSep);
9055                          baseLen = tmpBase.length;
9056                          if (maxURLLength <= comboBase.length) {
9057                              Y.log('maxURLLength (' + maxURLLength + ') is lower than the comboBase length (' + comboBase.length + '), resetting to default (' + MAX_URL_LENGTH + ')', 'error', 'loader');
9058                              maxURLLength = MAX_URL_LENGTH;
9059                          }
9060  
9061                          if (frags.length) {
9062                              if (baseLen > maxURLLength) {
9063                                  Y.log('Exceeded maxURLLength (' + maxURLLength + ') for ' + type + ', splitting', 'info', 'loader');
9064                                  fragSubset = [];
9065                                  for (i = 0, len = frags.length; i < len; i++) {
9066                                      fragSubset.push(frags[i]);
9067                                      tmpBase = comboBase + fragSubset.join(comboSep);
9068  
9069                                      if (tmpBase.length > maxURLLength) {
9070                                          frag = fragSubset.pop();
9071                                          tmpBase = comboBase + fragSubset.join(comboSep);
9072                                          resolved[type].push(self._filter(tmpBase, null, comboMeta.group));
9073                                          fragSubset = [];
9074                                          if (frag) {
9075                                              fragSubset.push(frag);
9076                                          }
9077                                      }
9078                                  }
9079                                  if (fragSubset.length) {
9080                                      tmpBase = comboBase + fragSubset.join(comboSep);
9081                                      resolved[type].push(self._filter(tmpBase, null, comboMeta.group));
9082                                  }
9083                              } else {
9084                                  resolved[type].push(self._filter(tmpBase, null, comboMeta.group));
9085                              }
9086                          }
9087                          resolved[type + 'Mods'] = resolved[type + 'Mods'].concat(modules);
9088                      }
9089                  }
9090              }
9091          }
9092  
9093          return resolved;
9094      },
9095  
9096      /**
9097      Shortcut to calculate, resolve and load all modules.
9098  
9099          var loader = new Y.Loader({
9100              ignoreRegistered: true,
9101              modules: {
9102                  mod: {
9103                      path: 'mod.js'
9104                  }
9105              },
9106              requires: [ 'mod' ]
9107          });
9108          loader.load(function() {
9109              console.log('All modules have loaded..');
9110          });
9111  
9112  
9113      @method load
9114      @param {Function} cb Executed after all load operations are complete
9115      */
9116      load: function(cb) {
9117          if (!cb) {
9118              Y.log('No callback supplied to load()', 'error', 'loader');
9119              return;
9120          }
9121          var self = this,
9122              out = self.resolve(true);
9123  
9124          self.data = out;
9125  
9126          self.onEnd = function() {
9127              cb.apply(self.context || self, arguments);
9128          };
9129  
9130          self.insert();
9131      }
9132  };
9133  
9134  
9135  
9136  }, '3.17.2', {"requires": ["get", "features"]});
9137  YUI.add('loader-rollup', function (Y, NAME) {
9138  
9139  /**
9140   * Optional automatic rollup logic for reducing http connections
9141   * when not using a combo service.
9142   * @module loader
9143   * @submodule rollup
9144   */
9145  
9146  /**
9147   * Look for rollup packages to determine if all of the modules a
9148   * rollup supersedes are required.  If so, include the rollup to
9149   * help reduce the total number of connections required.  Called
9150   * by calculate().  This is an optional feature, and requires the
9151   * appropriate submodule to function.
9152   * @method _rollup
9153   * @for Loader
9154   * @private
9155   */
9156  Y.Loader.prototype._rollup = function() {
9157      var i, j, m, s, r = this.required, roll,
9158          info = this.moduleInfo, rolled, c, smod;
9159  
9160      // find and cache rollup modules
9161      if (this.dirty || !this.rollups) {
9162          this.rollups = {};
9163          for (i in info) {
9164              if (info.hasOwnProperty(i)) {
9165                  m = this.getModule(i);
9166                  // if (m && m.rollup && m.supersedes) {
9167                  if (m && m.rollup) {
9168                      this.rollups[i] = m;
9169                  }
9170              }
9171          }
9172      }
9173  
9174      // make as many passes as needed to pick up rollup rollups
9175      for (;;) {
9176          rolled = false;
9177  
9178          // go through the rollup candidates
9179          for (i in this.rollups) {
9180              if (this.rollups.hasOwnProperty(i)) {
9181                  // there can be only one, unless forced
9182                  if (!r[i] && ((!this.loaded[i]) || this.forceMap[i])) {
9183                      m = this.getModule(i);
9184                      s = m.supersedes || [];
9185                      roll = false;
9186  
9187                      // @TODO remove continue
9188                      if (!m.rollup) {
9189                          continue;
9190                      }
9191  
9192                      c = 0;
9193  
9194                      // check the threshold
9195                      for (j = 0; j < s.length; j++) {
9196                          smod = info[s[j]];
9197  
9198                          // if the superseded module is loaded, we can't
9199                          // load the rollup unless it has been forced.
9200                          if (this.loaded[s[j]] && !this.forceMap[s[j]]) {
9201                              roll = false;
9202                              break;
9203                          // increment the counter if this module is required.
9204                          // if we are beyond the rollup threshold, we will
9205                          // use the rollup module
9206                          } else if (r[s[j]] && m.type === smod.type) {
9207                              c++;
9208                              // Y.log("adding to thresh: " + c + ", " + s[j]);
9209                              roll = (c >= m.rollup);
9210                              if (roll) {
9211                                  // Y.log("over thresh " + c + ", " + s[j]);
9212                                  break;
9213                              }
9214                          }
9215                      }
9216  
9217                      if (roll) {
9218                          // Y.log("adding rollup: " +  i);
9219                          // add the rollup
9220                          r[i] = true;
9221                          rolled = true;
9222  
9223                          // expand the rollup's dependencies
9224                          this.getRequires(m);
9225                      }
9226                  }
9227              }
9228          }
9229  
9230          // if we made it here w/o rolling up something, we are done
9231          if (!rolled) {
9232              break;
9233          }
9234      }
9235  };
9236  
9237  
9238  }, '3.17.2', {"requires": ["loader-base"]});
9239  YUI.add('loader-yui3', function (Y, NAME) {
9240  
9241  /* This file is auto-generated by (yogi.js loader --mix --yes) */
9242  
9243  /*jshint maxlen:900, eqeqeq: false */
9244  
9245  /**
9246   * YUI 3 module metadata
9247   * @module loader
9248   * @submodule loader-yui3
9249   */
9250  YUI.Env[Y.version].modules = YUI.Env[Y.version].modules || {};
9251  Y.mix(YUI.Env[Y.version].modules, {
9252      "align-plugin": {
9253          "requires": [
9254              "node-screen",
9255              "node-pluginhost"
9256          ]
9257      },
9258      "anim": {
9259          "use": [
9260              "anim-base",
9261              "anim-color",
9262              "anim-curve",
9263              "anim-easing",
9264              "anim-node-plugin",
9265              "anim-scroll",
9266              "anim-xy"
9267          ]
9268      },
9269      "anim-base": {
9270          "requires": [
9271              "base-base",
9272              "node-style",
9273              "color-base"
9274          ]
9275      },
9276      "anim-color": {
9277          "requires": [
9278              "anim-base"
9279          ]
9280      },
9281      "anim-curve": {
9282          "requires": [
9283              "anim-xy"
9284          ]
9285      },
9286      "anim-easing": {
9287          "requires": [
9288              "anim-base"
9289          ]
9290      },
9291      "anim-node-plugin": {
9292          "requires": [
9293              "node-pluginhost",
9294              "anim-base"
9295          ]
9296      },
9297      "anim-scroll": {
9298          "requires": [
9299              "anim-base"
9300          ]
9301      },
9302      "anim-shape": {
9303          "requires": [
9304              "anim-base",
9305              "anim-easing",
9306              "anim-color",
9307              "matrix"
9308          ]
9309      },
9310      "anim-shape-transform": {
9311          "use": [
9312              "anim-shape"
9313          ]
9314      },
9315      "anim-xy": {
9316          "requires": [
9317              "anim-base",
9318              "node-screen"
9319          ]
9320      },
9321      "app": {
9322          "use": [
9323              "app-base",
9324              "app-content",
9325              "app-transitions",
9326              "lazy-model-list",
9327              "model",
9328              "model-list",
9329              "model-sync-rest",
9330              "model-sync-local",
9331              "router",
9332              "view",
9333              "view-node-map"
9334          ]
9335      },
9336      "app-base": {
9337          "requires": [
9338              "classnamemanager",
9339              "pjax-base",
9340              "router",
9341              "view"
9342          ]
9343      },
9344      "app-content": {
9345          "requires": [
9346              "app-base",
9347              "pjax-content"
9348          ]
9349      },
9350      "app-transitions": {
9351          "requires": [
9352              "app-base"
9353          ]
9354      },
9355      "app-transitions-css": {
9356          "type": "css"
9357      },
9358      "app-transitions-native": {
9359          "condition": {
9360              "name": "app-transitions-native",
9361              "test": function (Y) {
9362      var doc  = Y.config.doc,
9363          node = doc ? doc.documentElement : null;
9364  
9365      if (node && node.style) {
9366          return ('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
9367      }
9368  
9369      return false;
9370  },
9371              "trigger": "app-transitions"
9372          },
9373          "requires": [
9374              "app-transitions",
9375              "app-transitions-css",
9376              "parallel",
9377              "transition"
9378          ]
9379      },
9380      "array-extras": {
9381          "requires": [
9382              "yui-base"
9383          ]
9384      },
9385      "array-invoke": {
9386          "requires": [
9387              "yui-base"
9388          ]
9389      },
9390      "arraylist": {
9391          "requires": [
9392              "yui-base"
9393          ]
9394      },
9395      "arraylist-add": {
9396          "requires": [
9397              "arraylist"
9398          ]
9399      },
9400      "arraylist-filter": {
9401          "requires": [
9402              "arraylist"
9403          ]
9404      },
9405      "arraysort": {
9406          "requires": [
9407              "yui-base"
9408          ]
9409      },
9410      "async-queue": {
9411          "requires": [
9412              "event-custom"
9413          ]
9414      },
9415      "attribute": {
9416          "use": [
9417              "attribute-base",
9418              "attribute-complex"
9419          ]
9420      },
9421      "attribute-base": {
9422          "requires": [
9423              "attribute-core",
9424              "attribute-observable",
9425              "attribute-extras"
9426          ]
9427      },
9428      "attribute-complex": {
9429          "requires": [
9430              "attribute-base"
9431          ]
9432      },
9433      "attribute-core": {
9434          "requires": [
9435              "oop"
9436          ]
9437      },
9438      "attribute-events": {
9439          "use": [
9440              "attribute-observable"
9441          ]
9442      },
9443      "attribute-extras": {
9444          "requires": [
9445              "oop"
9446          ]
9447      },
9448      "attribute-observable": {
9449          "requires": [
9450              "event-custom"
9451          ]
9452      },
9453      "autocomplete": {
9454          "use": [
9455              "autocomplete-base",
9456              "autocomplete-sources",
9457              "autocomplete-list",
9458              "autocomplete-plugin"
9459          ]
9460      },
9461      "autocomplete-base": {
9462          "optional": [
9463              "autocomplete-sources"
9464          ],
9465          "requires": [
9466              "array-extras",
9467              "base-build",
9468              "escape",
9469              "event-valuechange",
9470              "node-base"
9471          ]
9472      },
9473      "autocomplete-filters": {
9474          "requires": [
9475              "array-extras",
9476              "text-wordbreak"
9477          ]
9478      },
9479      "autocomplete-filters-accentfold": {
9480          "requires": [
9481              "array-extras",
9482              "text-accentfold",
9483              "text-wordbreak"
9484          ]
9485      },
9486      "autocomplete-highlighters": {
9487          "requires": [
9488              "array-extras",
9489              "highlight-base"
9490          ]
9491      },
9492      "autocomplete-highlighters-accentfold": {
9493          "requires": [
9494              "array-extras",
9495              "highlight-accentfold"
9496          ]
9497      },
9498      "autocomplete-list": {
9499          "after": [
9500              "autocomplete-sources"
9501          ],
9502          "lang": [
9503              "en",
9504              "es",
9505              "hu",
9506              "it"
9507          ],
9508          "requires": [
9509              "autocomplete-base",
9510              "event-resize",
9511              "node-screen",
9512              "selector-css3",
9513              "shim-plugin",
9514              "widget",
9515              "widget-position",
9516              "widget-position-align"
9517          ],
9518          "skinnable": true
9519      },
9520      "autocomplete-list-keys": {
9521          "condition": {
9522              "name": "autocomplete-list-keys",
9523              "test": function (Y) {
9524      // Only add keyboard support to autocomplete-list if this doesn't appear to
9525      // be an iOS or Android-based mobile device.
9526      //
9527      // There's currently no feasible way to actually detect whether a device has
9528      // a hardware keyboard, so this sniff will have to do. It can easily be
9529      // overridden by manually loading the autocomplete-list-keys module.
9530      //
9531      // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari
9532      // doesn't fire the keyboard events used by AutoCompleteList, so there's
9533      // no point loading the -keys module even when a bluetooth keyboard may be
9534      // available.
9535      return !(Y.UA.ios || Y.UA.android);
9536  },
9537              "trigger": "autocomplete-list"
9538          },
9539          "requires": [
9540              "autocomplete-list",
9541              "base-build"
9542          ]
9543      },
9544      "autocomplete-plugin": {
9545          "requires": [
9546              "autocomplete-list",
9547              "node-pluginhost"
9548          ]
9549      },
9550      "autocomplete-sources": {
9551          "optional": [
9552              "io-base",
9553              "json-parse",
9554              "jsonp",
9555              "yql"
9556          ],
9557          "requires": [
9558              "autocomplete-base"
9559          ]
9560      },
9561      "axes": {
9562          "use": [
9563              "axis-numeric",
9564              "axis-category",
9565              "axis-time",
9566              "axis-stacked"
9567          ]
9568      },
9569      "axes-base": {
9570          "use": [
9571              "axis-numeric-base",
9572              "axis-category-base",
9573              "axis-time-base",
9574              "axis-stacked-base"
9575          ]
9576      },
9577      "axis": {
9578          "requires": [
9579              "dom",
9580              "widget",
9581              "widget-position",
9582              "widget-stack",
9583              "graphics",
9584              "axis-base"
9585          ]
9586      },
9587      "axis-base": {
9588          "requires": [
9589              "classnamemanager",
9590              "datatype-number",
9591              "datatype-date",
9592              "base",
9593              "event-custom"
9594          ]
9595      },
9596      "axis-category": {
9597          "requires": [
9598              "axis",
9599              "axis-category-base"
9600          ]
9601      },
9602      "axis-category-base": {
9603          "requires": [
9604              "axis-base"
9605          ]
9606      },
9607      "axis-numeric": {
9608          "requires": [
9609              "axis",
9610              "axis-numeric-base"
9611          ]
9612      },
9613      "axis-numeric-base": {
9614          "requires": [
9615              "axis-base"
9616          ]
9617      },
9618      "axis-stacked": {
9619          "requires": [
9620              "axis-numeric",
9621              "axis-stacked-base"
9622          ]
9623      },
9624      "axis-stacked-base": {
9625          "requires": [
9626              "axis-numeric-base"
9627          ]
9628      },
9629      "axis-time": {
9630          "requires": [
9631              "axis",
9632              "axis-time-base"
9633          ]
9634      },
9635      "axis-time-base": {
9636          "requires": [
9637              "axis-base"
9638          ]
9639      },
9640      "base": {
9641          "use": [
9642              "base-base",
9643              "base-pluginhost",
9644              "base-build"
9645          ]
9646      },
9647      "base-base": {
9648          "requires": [
9649              "attribute-base",
9650              "base-core",
9651              "base-observable"
9652          ]
9653      },
9654      "base-build": {
9655          "requires": [
9656              "base-base"
9657          ]
9658      },
9659      "base-core": {
9660          "requires": [
9661              "attribute-core"
9662          ]
9663      },
9664      "base-observable": {
9665          "requires": [
9666              "attribute-observable",
9667              "base-core"
9668          ]
9669      },
9670      "base-pluginhost": {
9671          "requires": [
9672              "base-base",
9673              "pluginhost"
9674          ]
9675      },
9676      "button": {
9677          "requires": [
9678              "button-core",
9679              "cssbutton",
9680              "widget"
9681          ]
9682      },
9683      "button-core": {
9684          "requires": [
9685              "attribute-core",
9686              "classnamemanager",
9687              "node-base",
9688              "escape"
9689          ]
9690      },
9691      "button-group": {
9692          "requires": [
9693              "button-plugin",
9694              "cssbutton",
9695              "widget"
9696          ]
9697      },
9698      "button-plugin": {
9699          "requires": [
9700              "button-core",
9701              "cssbutton",
9702              "node-pluginhost"
9703          ]
9704      },
9705      "cache": {
9706          "use": [
9707              "cache-base",
9708              "cache-offline",
9709              "cache-plugin"
9710          ]
9711      },
9712      "cache-base": {
9713          "requires": [
9714              "base"
9715          ]
9716      },
9717      "cache-offline": {
9718          "requires": [
9719              "cache-base",
9720              "json"
9721          ]
9722      },
9723      "cache-plugin": {
9724          "requires": [
9725              "plugin",
9726              "cache-base"
9727          ]
9728      },
9729      "calendar": {
9730          "requires": [
9731              "calendar-base",
9732              "calendarnavigator"
9733          ],
9734          "skinnable": true
9735      },
9736      "calendar-base": {
9737          "lang": [
9738              "de",
9739              "en",
9740              "es",
9741              "es-AR",
9742              "fr",
9743              "hu",
9744              "it",
9745              "ja",
9746              "nb-NO",
9747              "nl",
9748              "pt-BR",
9749              "ru",
9750              "zh-Hans",
9751              "zh-Hans-CN",
9752              "zh-Hant",
9753              "zh-Hant-HK",
9754              "zh-HANT-TW"
9755          ],
9756          "requires": [
9757              "widget",
9758              "datatype-date",
9759              "datatype-date-math",
9760              "cssgrids"
9761          ],
9762          "skinnable": true
9763      },
9764      "calendarnavigator": {
9765          "requires": [
9766              "plugin",
9767              "classnamemanager",
9768              "datatype-date",
9769              "node"
9770          ],
9771          "skinnable": true
9772      },
9773      "charts": {
9774          "use": [
9775              "charts-base"
9776          ]
9777      },
9778      "charts-base": {
9779          "requires": [
9780              "dom",
9781              "event-mouseenter",
9782              "event-touch",
9783              "graphics-group",
9784              "axes",
9785              "series-pie",
9786              "series-line",
9787              "series-marker",
9788              "series-area",
9789              "series-spline",
9790              "series-column",
9791              "series-bar",
9792              "series-areaspline",
9793              "series-combo",
9794              "series-combospline",
9795              "series-line-stacked",
9796              "series-marker-stacked",
9797              "series-area-stacked",
9798              "series-spline-stacked",
9799              "series-column-stacked",
9800              "series-bar-stacked",
9801              "series-areaspline-stacked",
9802              "series-combo-stacked",
9803              "series-combospline-stacked"
9804          ]
9805      },
9806      "charts-legend": {
9807          "requires": [
9808              "charts-base"
9809          ]
9810      },
9811      "classnamemanager": {
9812          "requires": [
9813              "yui-base"
9814          ]
9815      },
9816      "clickable-rail": {
9817          "requires": [
9818              "slider-base"
9819          ]
9820      },
9821      "collection": {
9822          "use": [
9823              "array-extras",
9824              "arraylist",
9825              "arraylist-add",
9826              "arraylist-filter",
9827              "array-invoke"
9828          ]
9829      },
9830      "color": {
9831          "use": [
9832              "color-base",
9833              "color-hsl",
9834              "color-harmony"
9835          ]
9836      },
9837      "color-base": {
9838          "requires": [
9839              "yui-base"
9840          ]
9841      },
9842      "color-harmony": {
9843          "requires": [
9844              "color-hsl"
9845          ]
9846      },
9847      "color-hsl": {
9848          "requires": [
9849              "color-base"
9850          ]
9851      },
9852      "color-hsv": {
9853          "requires": [
9854              "color-base"
9855          ]
9856      },
9857      "console": {
9858          "lang": [
9859              "en",
9860              "es",
9861              "hu",
9862              "it",
9863              "ja"
9864          ],
9865          "requires": [
9866              "yui-log",
9867              "widget"
9868          ],
9869          "skinnable": true
9870      },
9871      "console-filters": {
9872          "requires": [
9873              "plugin",
9874              "console"
9875          ],
9876          "skinnable": true
9877      },
9878      "content-editable": {
9879          "requires": [
9880              "node-base",
9881              "editor-selection",
9882              "stylesheet",
9883              "plugin"
9884          ]
9885      },
9886      "controller": {
9887          "use": [
9888              "router"
9889          ]
9890      },
9891      "cookie": {
9892          "requires": [
9893              "yui-base"
9894          ]
9895      },
9896      "createlink-base": {
9897          "requires": [
9898              "editor-base"
9899          ]
9900      },
9901      "cssbase": {
9902          "after": [
9903              "cssreset",
9904              "cssfonts",
9905              "cssgrids",
9906              "cssreset-context",
9907              "cssfonts-context",
9908              "cssgrids-context"
9909          ],
9910          "type": "css"
9911      },
9912      "cssbase-context": {
9913          "after": [
9914              "cssreset",
9915              "cssfonts",
9916              "cssgrids",
9917              "cssreset-context",
9918              "cssfonts-context",
9919              "cssgrids-context"
9920          ],
9921          "type": "css"
9922      },
9923      "cssbutton": {
9924          "type": "css"
9925      },
9926      "cssfonts": {
9927          "type": "css"
9928      },
9929      "cssfonts-context": {
9930          "type": "css"
9931      },
9932      "cssgrids": {
9933          "optional": [
9934              "cssnormalize"
9935          ],
9936          "type": "css"
9937      },
9938      "cssgrids-base": {
9939          "optional": [
9940              "cssnormalize"
9941          ],
9942          "type": "css"
9943      },
9944      "cssgrids-responsive": {
9945          "optional": [
9946              "cssnormalize"
9947          ],
9948          "requires": [
9949              "cssgrids",
9950              "cssgrids-responsive-base"
9951          ],
9952          "type": "css"
9953      },
9954      "cssgrids-units": {
9955          "optional": [
9956              "cssnormalize"
9957          ],
9958          "requires": [
9959              "cssgrids-base"
9960          ],
9961          "type": "css"
9962      },
9963      "cssnormalize": {
9964          "type": "css"
9965      },
9966      "cssnormalize-context": {
9967          "type": "css"
9968      },
9969      "cssreset": {
9970          "type": "css"
9971      },
9972      "cssreset-context": {
9973          "type": "css"
9974      },
9975      "dataschema": {
9976          "use": [
9977              "dataschema-base",
9978              "dataschema-json",
9979              "dataschema-xml",
9980              "dataschema-array",
9981              "dataschema-text"
9982          ]
9983      },
9984      "dataschema-array": {
9985          "requires": [
9986              "dataschema-base"
9987          ]
9988      },
9989      "dataschema-base": {
9990          "requires": [
9991              "base"
9992          ]
9993      },
9994      "dataschema-json": {
9995          "requires": [
9996              "dataschema-base",
9997              "json"
9998          ]
9999      },
10000      "dataschema-text": {
10001          "requires": [
10002              "dataschema-base"
10003          ]
10004      },
10005      "dataschema-xml": {
10006          "requires": [
10007              "dataschema-base"
10008          ]
10009      },
10010      "datasource": {
10011          "use": [
10012              "datasource-local",
10013              "datasource-io",
10014              "datasource-get",
10015              "datasource-function",
10016              "datasource-cache",
10017              "datasource-jsonschema",
10018              "datasource-xmlschema",
10019              "datasource-arrayschema",
10020              "datasource-textschema",
10021              "datasource-polling"
10022          ]
10023      },
10024      "datasource-arrayschema": {
10025          "requires": [
10026              "datasource-local",
10027              "plugin",
10028              "dataschema-array"
10029          ]
10030      },
10031      "datasource-cache": {
10032          "requires": [
10033              "datasource-local",
10034              "plugin",
10035              "cache-base"
10036          ]
10037      },
10038      "datasource-function": {
10039          "requires": [
10040              "datasource-local"
10041          ]
10042      },
10043      "datasource-get": {
10044          "requires": [
10045              "datasource-local",
10046              "get"
10047          ]
10048      },
10049      "datasource-io": {
10050          "requires": [
10051              "datasource-local",
10052              "io-base"
10053          ]
10054      },
10055      "datasource-jsonschema": {
10056          "requires": [
10057              "datasource-local",
10058              "plugin",
10059              "dataschema-json"
10060          ]
10061      },
10062      "datasource-local": {
10063          "requires": [
10064              "base"
10065          ]
10066      },
10067      "datasource-polling": {
10068          "requires": [
10069              "datasource-local"
10070          ]
10071      },
10072      "datasource-textschema": {
10073          "requires": [
10074              "datasource-local",
10075              "plugin",
10076              "dataschema-text"
10077          ]
10078      },
10079      "datasource-xmlschema": {
10080          "requires": [
10081              "datasource-local",
10082              "plugin",
10083              "datatype-xml",
10084              "dataschema-xml"
10085          ]
10086      },
10087      "datatable": {
10088          "use": [
10089              "datatable-core",
10090              "datatable-table",
10091              "datatable-head",
10092              "datatable-body",
10093              "datatable-base",
10094              "datatable-column-widths",
10095              "datatable-message",
10096              "datatable-mutable",
10097              "datatable-sort",
10098              "datatable-datasource"
10099          ]
10100      },
10101      "datatable-base": {
10102          "requires": [
10103              "datatable-core",
10104              "datatable-table",
10105              "datatable-head",
10106              "datatable-body",
10107              "base-build",
10108              "widget"
10109          ],
10110          "skinnable": true
10111      },
10112      "datatable-body": {
10113          "requires": [
10114              "datatable-core",
10115              "view",
10116              "classnamemanager"
10117          ]
10118      },
10119      "datatable-column-widths": {
10120          "requires": [
10121              "datatable-base"
10122          ]
10123      },
10124      "datatable-core": {
10125          "requires": [
10126              "escape",
10127              "model-list",
10128              "node-event-delegate"
10129          ]
10130      },
10131      "datatable-datasource": {
10132          "requires": [
10133              "datatable-base",
10134              "plugin",
10135              "datasource-local"
10136          ]
10137      },
10138      "datatable-foot": {
10139          "requires": [
10140              "datatable-core",
10141              "view"
10142          ]
10143      },
10144      "datatable-formatters": {
10145          "requires": [
10146              "datatable-body",
10147              "datatype-number-format",
10148              "datatype-date-format",
10149              "escape"
10150          ]
10151      },
10152      "datatable-head": {
10153          "requires": [
10154              "datatable-core",
10155              "view",
10156              "classnamemanager"
10157          ]
10158      },
10159      "datatable-highlight": {
10160          "requires": [
10161              "datatable-base",
10162              "event-hover"
10163          ],
10164          "skinnable": true
10165      },
10166      "datatable-keynav": {
10167          "requires": [
10168              "datatable-base"
10169          ]
10170      },
10171      "datatable-message": {
10172          "lang": [
10173              "en",
10174              "fr",
10175              "es",
10176              "hu",
10177              "it"
10178          ],
10179          "requires": [
10180              "datatable-base"
10181          ],
10182          "skinnable": true
10183      },
10184      "datatable-mutable": {
10185          "requires": [
10186              "datatable-base"
10187          ]
10188      },
10189      "datatable-paginator": {
10190          "lang": [
10191              "en",
10192              "fr"
10193          ],
10194          "requires": [
10195              "model",
10196              "view",
10197              "paginator-core",
10198              "datatable-foot",
10199              "datatable-paginator-templates"
10200          ],
10201          "skinnable": true
10202      },
10203      "datatable-paginator-templates": {
10204          "requires": [
10205              "template"
10206          ]
10207      },
10208      "datatable-scroll": {
10209          "requires": [
10210              "datatable-base",
10211              "datatable-column-widths",
10212              "dom-screen"
10213          ],
10214          "skinnable": true
10215      },
10216      "datatable-sort": {
10217          "lang": [
10218              "en",
10219              "fr",
10220              "es",
10221              "hu"
10222          ],
10223          "requires": [
10224              "datatable-base"
10225          ],
10226          "skinnable": true
10227      },
10228      "datatable-table": {
10229          "requires": [
10230              "datatable-core",
10231              "datatable-head",
10232              "datatable-body",
10233              "view",
10234              "classnamemanager"
10235          ]
10236      },
10237      "datatype": {
10238          "use": [
10239              "datatype-date",
10240              "datatype-number",
10241              "datatype-xml"
10242          ]
10243      },
10244      "datatype-date": {
10245          "use": [
10246              "datatype-date-parse",
10247              "datatype-date-format",
10248              "datatype-date-math"
10249          ]
10250      },
10251      "datatype-date-format": {
10252          "lang": [
10253              "ar",
10254              "ar-JO",
10255              "ca",
10256              "ca-ES",
10257              "da",
10258              "da-DK",
10259              "de",
10260              "de-AT",
10261              "de-DE",
10262              "el",
10263              "el-GR",
10264              "en",
10265              "en-AU",
10266              "en-CA",
10267              "en-GB",
10268              "en-IE",
10269              "en-IN",
10270              "en-JO",
10271              "en-MY",
10272              "en-NZ",
10273              "en-PH",
10274              "en-SG",
10275              "en-US",
10276              "es",
10277              "es-AR",
10278              "es-BO",
10279              "es-CL",
10280              "es-CO",
10281              "es-EC",
10282              "es-ES",
10283              "es-MX",
10284              "es-PE",
10285              "es-PY",
10286              "es-US",
10287              "es-UY",
10288              "es-VE",
10289              "fi",
10290              "fi-FI",
10291              "fr",
10292              "fr-BE",
10293              "fr-CA",
10294              "fr-FR",
10295              "hi",
10296              "hi-IN",
10297              "hu",
10298              "id",
10299              "id-ID",
10300              "it",
10301              "it-IT",
10302              "ja",
10303              "ja-JP",
10304              "ko",
10305              "ko-KR",
10306              "ms",
10307              "ms-MY",
10308              "nb",
10309              "nb-NO",
10310              "nl",
10311              "nl-BE",
10312              "nl-NL",
10313              "pl",
10314              "pl-PL",
10315              "pt",
10316              "pt-BR",
10317              "ro",
10318              "ro-RO",
10319              "ru",
10320              "ru-RU",
10321              "sv",
10322              "sv-SE",
10323              "th",
10324              "th-TH",
10325              "tr",
10326              "tr-TR",
10327              "vi",
10328              "vi-VN",
10329              "zh-Hans",
10330              "zh-Hans-CN",
10331              "zh-Hant",
10332              "zh-Hant-HK",
10333              "zh-Hant-TW"
10334          ]
10335      },
10336      "datatype-date-math": {
10337          "requires": [
10338              "yui-base"
10339          ]
10340      },
10341      "datatype-date-parse": {},
10342      "datatype-number": {
10343          "use": [
10344              "datatype-number-parse",
10345              "datatype-number-format"
10346          ]
10347      },
10348      "datatype-number-format": {},
10349      "datatype-number-parse": {
10350          "requires": [
10351              "escape"
10352          ]
10353      },
10354      "datatype-xml": {
10355          "use": [
10356              "datatype-xml-parse",
10357              "datatype-xml-format"
10358          ]
10359      },
10360      "datatype-xml-format": {},
10361      "datatype-xml-parse": {},
10362      "dd": {
10363          "use": [
10364              "dd-ddm-base",
10365              "dd-ddm",
10366              "dd-ddm-drop",
10367              "dd-drag",
10368              "dd-proxy",
10369              "dd-constrain",
10370              "dd-drop",
10371              "dd-scroll",
10372              "dd-delegate"
10373          ]
10374      },
10375      "dd-constrain": {
10376          "requires": [
10377              "dd-drag"
10378          ]
10379      },
10380      "dd-ddm": {
10381          "requires": [
10382              "dd-ddm-base",
10383              "event-resize"
10384          ]
10385      },
10386      "dd-ddm-base": {
10387          "requires": [
10388              "node",
10389              "base",
10390              "yui-throttle",
10391              "classnamemanager"
10392          ]
10393      },
10394      "dd-ddm-drop": {
10395          "requires": [
10396              "dd-ddm"
10397          ]
10398      },
10399      "dd-delegate": {
10400          "requires": [
10401              "dd-drag",
10402              "dd-drop-plugin",
10403              "event-mouseenter"
10404          ]
10405      },
10406      "dd-drag": {
10407          "requires": [
10408              "dd-ddm-base"
10409          ]
10410      },
10411      "dd-drop": {
10412          "requires": [
10413              "dd-drag",
10414              "dd-ddm-drop"
10415          ]
10416      },
10417      "dd-drop-plugin": {
10418          "requires": [
10419              "dd-drop"
10420          ]
10421      },
10422      "dd-gestures": {
10423          "condition": {
10424              "name": "dd-gestures",
10425              "trigger": "dd-drag",
10426              "ua": "touchEnabled"
10427          },
10428          "requires": [
10429              "dd-drag",
10430              "event-synthetic",
10431              "event-gestures"
10432          ]
10433      },
10434      "dd-plugin": {
10435          "optional": [
10436              "dd-constrain",
10437              "dd-proxy"
10438          ],
10439          "requires": [
10440              "dd-drag"
10441          ]
10442      },
10443      "dd-proxy": {
10444          "requires": [
10445              "dd-drag"
10446          ]
10447      },
10448      "dd-scroll": {
10449          "requires": [
10450              "dd-drag"
10451          ]
10452      },
10453      "dial": {
10454          "lang": [
10455              "en",
10456              "es",
10457              "hu"
10458          ],
10459          "requires": [
10460              "widget",
10461              "dd-drag",
10462              "event-mouseenter",
10463              "event-move",
10464              "event-key",
10465              "transition",
10466              "intl"
10467          ],
10468          "skinnable": true
10469      },
10470      "dom": {
10471          "use": [
10472              "dom-base",
10473              "dom-screen",
10474              "dom-style",
10475              "selector-native",
10476              "selector"
10477          ]
10478      },
10479      "dom-base": {
10480          "requires": [
10481              "dom-core"
10482          ]
10483      },
10484      "dom-core": {
10485          "requires": [
10486              "oop",
10487              "features"
10488          ]
10489      },
10490      "dom-screen": {
10491          "requires": [
10492              "dom-base",
10493              "dom-style"
10494          ]
10495      },
10496      "dom-style": {
10497          "requires": [
10498              "dom-base"
10499          ]
10500      },
10501      "dom-style-ie": {
10502          "condition": {
10503              "name": "dom-style-ie",
10504              "test": function (Y) {
10505  
10506      var testFeature = Y.Features.test,
10507          addFeature = Y.Features.add,
10508          WINDOW = Y.config.win,
10509          DOCUMENT = Y.config.doc,
10510          DOCUMENT_ELEMENT = 'documentElement',
10511          ret = false;
10512  
10513      addFeature('style', 'computedStyle', {
10514          test: function() {
10515              return WINDOW && 'getComputedStyle' in WINDOW;
10516          }
10517      });
10518  
10519      addFeature('style', 'opacity', {
10520          test: function() {
10521              return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style;
10522          }
10523      });
10524  
10525      ret =  (!testFeature('style', 'opacity') &&
10526              !testFeature('style', 'computedStyle'));
10527  
10528      return ret;
10529  },
10530              "trigger": "dom-style"
10531          },
10532          "requires": [
10533              "dom-style",
10534              "color-base"
10535          ]
10536      },
10537      "dump": {
10538          "requires": [
10539              "yui-base"
10540          ]
10541      },
10542      "editor": {
10543          "use": [
10544              "frame",
10545              "editor-selection",
10546              "exec-command",
10547              "editor-base",
10548              "editor-para",
10549              "editor-br",
10550              "editor-bidi",
10551              "editor-tab",
10552              "createlink-base"
10553          ]
10554      },
10555      "editor-base": {
10556          "requires": [
10557              "base",
10558              "frame",
10559              "node",
10560              "exec-command",
10561              "editor-selection"
10562          ]
10563      },
10564      "editor-bidi": {
10565          "requires": [
10566              "editor-base"
10567          ]
10568      },
10569      "editor-br": {
10570          "requires": [
10571              "editor-base"
10572          ]
10573      },
10574      "editor-inline": {
10575          "requires": [
10576              "editor-base",
10577              "content-editable"
10578          ]
10579      },
10580      "editor-lists": {
10581          "requires": [
10582              "editor-base"
10583          ]
10584      },
10585      "editor-para": {
10586          "requires": [
10587              "editor-para-base"
10588          ]
10589      },
10590      "editor-para-base": {
10591          "requires": [
10592              "editor-base"
10593          ]
10594      },
10595      "editor-para-ie": {
10596          "condition": {
10597              "name": "editor-para-ie",
10598              "trigger": "editor-para",
10599              "ua": "ie",
10600              "when": "instead"
10601          },
10602          "requires": [
10603              "editor-para-base"
10604          ]
10605      },
10606      "editor-selection": {
10607          "requires": [
10608              "node"
10609          ]
10610      },
10611      "editor-tab": {
10612          "requires": [
10613              "editor-base"
10614          ]
10615      },
10616      "escape": {
10617          "requires": [
10618              "yui-base"
10619          ]
10620      },
10621      "event": {
10622          "after": [
10623              "node-base"
10624          ],
10625          "use": [
10626              "event-base",
10627              "event-delegate",
10628              "event-synthetic",
10629              "event-mousewheel",
10630              "event-mouseenter",
10631              "event-key",
10632              "event-focus",
10633              "event-resize",
10634              "event-hover",
10635              "event-outside",
10636              "event-touch",
10637              "event-move",
10638              "event-flick",
10639              "event-valuechange",
10640              "event-tap"
10641          ]
10642      },
10643      "event-base": {
10644          "after": [
10645              "node-base"
10646          ],
10647          "requires": [
10648              "event-custom-base"
10649          ]
10650      },
10651      "event-base-ie": {
10652          "after": [
10653              "event-base"
10654          ],
10655          "condition": {
10656              "name": "event-base-ie",
10657              "test": function(Y) {
10658      var imp = Y.config.doc && Y.config.doc.implementation;
10659      return (imp && (!imp.hasFeature('Events', '2.0')));
10660  },
10661              "trigger": "node-base"
10662          },
10663          "requires": [
10664              "node-base"
10665          ]
10666      },
10667      "event-contextmenu": {
10668          "requires": [
10669              "event-synthetic",
10670              "dom-screen"
10671          ]
10672      },
10673      "event-custom": {
10674          "use": [
10675              "event-custom-base",
10676              "event-custom-complex"
10677          ]
10678      },
10679      "event-custom-base": {
10680          "requires": [
10681              "oop"
10682          ]
10683      },
10684      "event-custom-complex": {
10685          "requires": [
10686              "event-custom-base"
10687          ]
10688      },
10689      "event-delegate": {
10690          "requires": [
10691              "node-base"
10692          ]
10693      },
10694      "event-flick": {
10695          "requires": [
10696              "node-base",
10697              "event-touch",
10698              "event-synthetic"
10699          ]
10700      },
10701      "event-focus": {
10702          "requires": [
10703              "event-synthetic"
10704          ]
10705      },
10706      "event-gestures": {
10707          "use": [
10708              "event-flick",
10709              "event-move"
10710          ]
10711      },
10712      "event-hover": {
10713          "requires": [
10714              "event-mouseenter"
10715          ]
10716      },
10717      "event-key": {
10718          "requires": [
10719              "event-synthetic"
10720          ]
10721      },
10722      "event-mouseenter": {
10723          "requires": [
10724              "event-synthetic"
10725          ]
10726      },
10727      "event-mousewheel": {
10728          "requires": [
10729              "node-base"
10730          ]
10731      },
10732      "event-move": {
10733          "requires": [
10734              "node-base",
10735              "event-touch",
10736              "event-synthetic"
10737          ]
10738      },
10739      "event-outside": {
10740          "requires": [
10741              "event-synthetic"
10742          ]
10743      },
10744      "event-resize": {
10745          "requires": [
10746              "node-base",
10747              "event-synthetic"
10748          ]
10749      },
10750      "event-simulate": {
10751          "requires": [
10752              "event-base"
10753          ]
10754      },
10755      "event-synthetic": {
10756          "requires": [
10757              "node-base",
10758              "event-custom-complex"
10759          ]
10760      },
10761      "event-tap": {
10762          "requires": [
10763              "node-base",
10764              "event-base",
10765              "event-touch",
10766              "event-synthetic"
10767          ]
10768      },
10769      "event-touch": {
10770          "requires": [
10771              "node-base"
10772          ]
10773      },
10774      "event-valuechange": {
10775          "requires": [
10776              "event-focus",
10777              "event-synthetic"
10778          ]
10779      },
10780      "exec-command": {
10781          "requires": [
10782              "frame"
10783          ]
10784      },
10785      "features": {
10786          "requires": [
10787              "yui-base"
10788          ]
10789      },
10790      "file": {
10791          "requires": [
10792              "file-flash",
10793              "file-html5"
10794          ]
10795      },
10796      "file-flash": {
10797          "requires": [
10798              "base"
10799          ]
10800      },
10801      "file-html5": {
10802          "requires": [
10803              "base"
10804          ]
10805      },
10806      "frame": {
10807          "requires": [
10808              "base",
10809              "node",
10810              "plugin",
10811              "selector-css3",
10812              "yui-throttle"
10813          ]
10814      },
10815      "gesture-simulate": {
10816          "requires": [
10817              "async-queue",
10818              "event-simulate",
10819              "node-screen"
10820          ]
10821      },
10822      "get": {
10823          "requires": [
10824              "yui-base"
10825          ]
10826      },
10827      "graphics": {
10828          "requires": [
10829              "node",
10830              "event-custom",
10831              "pluginhost",
10832              "matrix",
10833              "classnamemanager"
10834          ]
10835      },
10836      "graphics-canvas": {
10837          "condition": {
10838              "name": "graphics-canvas",
10839              "test": function(Y) {
10840      var DOCUMENT = Y.config.doc,
10841          useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
10842          canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
10843          svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
10844      return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
10845  },
10846              "trigger": "graphics"
10847          },
10848          "requires": [
10849              "graphics",
10850              "color-base"
10851          ]
10852      },
10853      "graphics-canvas-default": {
10854          "condition": {
10855              "name": "graphics-canvas-default",
10856              "test": function(Y) {
10857      var DOCUMENT = Y.config.doc,
10858          useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
10859          canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
10860          svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
10861      return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
10862  },
10863              "trigger": "graphics"
10864          }
10865      },
10866      "graphics-group": {
10867          "requires": [
10868              "graphics"
10869          ]
10870      },
10871      "graphics-svg": {
10872          "condition": {
10873              "name": "graphics-svg",
10874              "test": function(Y) {
10875      var DOCUMENT = Y.config.doc,
10876          useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
10877          canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
10878          svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
10879      
10880      return svg && (useSVG || !canvas);
10881  },
10882              "trigger": "graphics"
10883          },
10884          "requires": [
10885              "graphics"
10886          ]
10887      },
10888      "graphics-svg-default": {
10889          "condition": {
10890              "name": "graphics-svg-default",
10891              "test": function(Y) {
10892      var DOCUMENT = Y.config.doc,
10893          useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
10894          canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
10895          svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
10896      
10897      return svg && (useSVG || !canvas);
10898  },
10899              "trigger": "graphics"
10900          }
10901      },
10902      "graphics-vml": {
10903          "condition": {
10904              "name": "graphics-vml",
10905              "test": function(Y) {
10906      var DOCUMENT = Y.config.doc,
10907          canvas = DOCUMENT && DOCUMENT.createElement("canvas");
10908      return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
10909  },
10910              "trigger": "graphics"
10911          },
10912          "requires": [
10913              "graphics",
10914              "color-base"
10915          ]
10916      },
10917      "graphics-vml-default": {
10918          "condition": {
10919              "name": "graphics-vml-default",
10920              "test": function(Y) {
10921      var DOCUMENT = Y.config.doc,
10922          canvas = DOCUMENT && DOCUMENT.createElement("canvas");
10923      return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
10924  },
10925              "trigger": "graphics"
10926          }
10927      },
10928      "handlebars": {
10929          "use": [
10930              "handlebars-compiler"
10931          ]
10932      },
10933      "handlebars-base": {
10934          "requires": []
10935      },
10936      "handlebars-compiler": {
10937          "requires": [
10938              "handlebars-base"
10939          ]
10940      },
10941      "highlight": {
10942          "use": [
10943              "highlight-base",
10944              "highlight-accentfold"
10945          ]
10946      },
10947      "highlight-accentfold": {
10948          "requires": [
10949              "highlight-base",
10950              "text-accentfold"
10951          ]
10952      },
10953      "highlight-base": {
10954          "requires": [
10955              "array-extras",
10956              "classnamemanager",
10957              "escape",
10958              "text-wordbreak"
10959          ]
10960      },
10961      "history": {
10962          "use": [
10963              "history-base",
10964              "history-hash",
10965              "history-html5"
10966          ]
10967      },
10968      "history-base": {
10969          "requires": [
10970              "event-custom-complex"
10971          ]
10972      },
10973      "history-hash": {
10974          "after": [
10975              "history-html5"
10976          ],
10977          "requires": [
10978              "event-synthetic",
10979              "history-base",
10980              "yui-later"
10981          ]
10982      },
10983      "history-hash-ie": {
10984          "condition": {
10985              "name": "history-hash-ie",
10986              "test": function (Y) {
10987      var docMode = Y.config.doc && Y.config.doc.documentMode;
10988  
10989      return Y.UA.ie && (!('onhashchange' in Y.config.win) ||
10990              !docMode || docMode < 8);
10991  },
10992              "trigger": "history-hash"
10993          },
10994          "requires": [
10995              "history-hash",
10996              "node-base"
10997          ]
10998      },
10999      "history-html5": {
11000          "optional": [
11001              "json"
11002          ],
11003          "requires": [
11004              "event-base",
11005              "history-base",
11006              "node-base"
11007          ]
11008      },
11009      "imageloader": {
11010          "requires": [
11011              "base-base",
11012              "node-style",
11013              "node-screen"
11014          ]
11015      },
11016      "intl": {
11017          "requires": [
11018              "intl-base",
11019              "event-custom"
11020          ]
11021      },
11022      "intl-base": {
11023          "requires": [
11024              "yui-base"
11025          ]
11026      },
11027      "io": {
11028          "use": [
11029              "io-base",
11030              "io-xdr",
11031              "io-form",
11032              "io-upload-iframe",
11033              "io-queue"
11034          ]
11035      },
11036      "io-base": {
11037          "requires": [
11038              "event-custom-base",
11039              "querystring-stringify-simple"
11040          ]
11041      },
11042      "io-form": {
11043          "requires": [
11044              "io-base",
11045              "node-base"
11046          ]
11047      },
11048      "io-nodejs": {
11049          "condition": {
11050              "name": "io-nodejs",
11051              "trigger": "io-base",
11052              "ua": "nodejs"
11053          },
11054          "requires": [
11055              "io-base"
11056          ]
11057      },
11058      "io-queue": {
11059          "requires": [
11060              "io-base",
11061              "queue-promote"
11062          ]
11063      },
11064      "io-upload-iframe": {
11065          "requires": [
11066              "io-base",
11067              "node-base"
11068          ]
11069      },
11070      "io-xdr": {
11071          "requires": [
11072              "io-base",
11073              "datatype-xml-parse"
11074          ]
11075      },
11076      "json": {
11077          "use": [
11078              "json-parse",
11079              "json-stringify"
11080          ]
11081      },
11082      "json-parse": {
11083          "requires": [
11084              "yui-base"
11085          ]
11086      },
11087      "json-parse-shim": {
11088          "condition": {
11089              "name": "json-parse-shim",
11090              "test": function (Y) {
11091      var _JSON = Y.config.global.JSON,
11092          Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
11093          nativeSupport = Y.config.useNativeJSONParse !== false && !!Native;
11094  
11095      function workingNative( k, v ) {
11096          return k === "ok" ? true : v;
11097      }
11098      
11099      // Double check basic functionality.  This is mainly to catch early broken
11100      // implementations of the JSON API in Firefox 3.1 beta1 and beta2
11101      if ( nativeSupport ) {
11102          try {
11103              nativeSupport = ( Native.parse( '{"ok":false}', workingNative ) ).ok;
11104          }
11105          catch ( e ) {
11106              nativeSupport = false;
11107          }
11108      }
11109  
11110      return !nativeSupport;
11111  },
11112              "trigger": "json-parse"
11113          },
11114          "requires": [
11115              "json-parse"
11116          ]
11117      },
11118      "json-stringify": {
11119          "requires": [
11120              "yui-base"
11121          ]
11122      },
11123      "json-stringify-shim": {
11124          "condition": {
11125              "name": "json-stringify-shim",
11126              "test": function (Y) {
11127      var _JSON = Y.config.global.JSON,
11128          Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
11129          nativeSupport = Y.config.useNativeJSONStringify !== false && !!Native;
11130  
11131      // Double check basic native functionality.  This is primarily to catch broken
11132      // early JSON API implementations in Firefox 3.1 beta1 and beta2.
11133      if ( nativeSupport ) {
11134          try {
11135              nativeSupport = ( '0' === Native.stringify(0) );
11136          } catch ( e ) {
11137              nativeSupport = false;
11138          }
11139      }
11140  
11141  
11142      return !nativeSupport;
11143  },
11144              "trigger": "json-stringify"
11145          },
11146          "requires": [
11147              "json-stringify"
11148          ]
11149      },
11150      "jsonp": {
11151          "requires": [
11152              "get",
11153              "oop"
11154          ]
11155      },
11156      "jsonp-url": {
11157          "requires": [
11158              "jsonp"
11159          ]
11160      },
11161      "lazy-model-list": {
11162          "requires": [
11163              "model-list"
11164          ]
11165      },
11166      "loader": {
11167          "use": [
11168              "loader-base",
11169              "loader-rollup",
11170              "loader-yui3"
11171          ]
11172      },
11173      "loader-base": {
11174          "requires": [
11175              "get",
11176              "features"
11177          ]
11178      },
11179      "loader-rollup": {
11180          "requires": [
11181              "loader-base"
11182          ]
11183      },
11184      "loader-yui3": {
11185          "requires": [
11186              "loader-base"
11187          ]
11188      },
11189      "matrix": {
11190          "requires": [
11191              "yui-base"
11192          ]
11193      },
11194      "model": {
11195          "requires": [
11196              "base-build",
11197              "escape",
11198              "json-parse"
11199          ]
11200      },
11201      "model-list": {
11202          "requires": [
11203              "array-extras",
11204              "array-invoke",
11205              "arraylist",
11206              "base-build",
11207              "escape",
11208              "json-parse",
11209              "model"
11210          ]
11211      },
11212      "model-sync-local": {
11213          "requires": [
11214              "model",
11215              "json-stringify"
11216          ]
11217      },
11218      "model-sync-rest": {
11219          "requires": [
11220              "model",
11221              "io-base",
11222              "json-stringify"
11223          ]
11224      },
11225      "node": {
11226          "use": [
11227              "node-base",
11228              "node-event-delegate",
11229              "node-pluginhost",
11230              "node-screen",
11231              "node-style"
11232          ]
11233      },
11234      "node-base": {
11235          "requires": [
11236              "event-base",
11237              "node-core",
11238              "dom-base",
11239              "dom-style"
11240          ]
11241      },
11242      "node-core": {
11243          "requires": [
11244              "dom-core",
11245              "selector"
11246          ]
11247      },
11248      "node-event-delegate": {
11249          "requires": [
11250              "node-base",
11251              "event-delegate"
11252          ]
11253      },
11254      "node-event-html5": {
11255          "requires": [
11256              "node-base"
11257          ]
11258      },
11259      "node-event-simulate": {
11260          "requires": [
11261              "node-base",
11262              "event-simulate",
11263              "gesture-simulate"
11264          ]
11265      },
11266      "node-flick": {
11267          "requires": [
11268              "classnamemanager",
11269              "transition",
11270              "event-flick",
11271              "plugin"
11272          ],
11273          "skinnable": true
11274      },
11275      "node-focusmanager": {
11276          "requires": [
11277              "attribute",
11278              "node",
11279              "plugin",
11280              "node-event-simulate",
11281              "event-key",
11282              "event-focus"
11283          ]
11284      },
11285      "node-load": {
11286          "requires": [
11287              "node-base",
11288              "io-base"
11289          ]
11290      },
11291      "node-menunav": {
11292          "requires": [
11293              "node",
11294              "classnamemanager",
11295              "plugin",
11296              "node-focusmanager"
11297          ],
11298          "skinnable": true
11299      },
11300      "node-pluginhost": {
11301          "requires": [
11302              "node-base",
11303              "pluginhost"
11304          ]
11305      },
11306      "node-screen": {
11307          "requires": [
11308              "dom-screen",
11309              "node-base"
11310          ]
11311      },
11312      "node-scroll-info": {
11313          "requires": [
11314              "array-extras",
11315              "base-build",
11316              "event-resize",
11317              "node-pluginhost",
11318              "plugin",
11319              "selector"
11320          ]
11321      },
11322      "node-style": {
11323          "requires": [
11324              "dom-style",
11325              "node-base"
11326          ]
11327      },
11328      "oop": {
11329          "requires": [
11330              "yui-base"
11331          ]
11332      },
11333      "overlay": {
11334          "requires": [
11335              "widget",
11336              "widget-stdmod",
11337              "widget-position",
11338              "widget-position-align",
11339              "widget-stack",
11340              "widget-position-constrain"
11341          ],
11342          "skinnable": true
11343      },
11344      "paginator": {
11345          "requires": [
11346              "paginator-core"
11347          ]
11348      },
11349      "paginator-core": {
11350          "requires": [
11351              "base"
11352          ]
11353      },
11354      "paginator-url": {
11355          "requires": [
11356              "paginator"
11357          ]
11358      },
11359      "panel": {
11360          "requires": [
11361              "widget",
11362              "widget-autohide",
11363              "widget-buttons",
11364              "widget-modality",
11365              "widget-position",
11366              "widget-position-align",
11367              "widget-position-constrain",
11368              "widget-stack",
11369              "widget-stdmod"
11370          ],
11371          "skinnable": true
11372      },
11373      "parallel": {
11374          "requires": [
11375              "yui-base"
11376          ]
11377      },
11378      "pjax": {
11379          "requires": [
11380              "pjax-base",
11381              "pjax-content"
11382          ]
11383      },
11384      "pjax-base": {
11385          "requires": [
11386              "classnamemanager",
11387              "node-event-delegate",
11388              "router"
11389          ]
11390      },
11391      "pjax-content": {
11392          "requires": [
11393              "io-base",
11394              "node-base",
11395              "router"
11396          ]
11397      },
11398      "pjax-plugin": {
11399          "requires": [
11400              "node-pluginhost",
11401              "pjax",
11402              "plugin"
11403          ]
11404      },
11405      "plugin": {
11406          "requires": [
11407              "base-base"
11408          ]
11409      },
11410      "pluginhost": {
11411          "use": [
11412              "pluginhost-base",
11413              "pluginhost-config"
11414          ]
11415      },
11416      "pluginhost-base": {
11417          "requires": [
11418              "yui-base"
11419          ]
11420      },
11421      "pluginhost-config": {
11422          "requires": [
11423              "pluginhost-base"
11424          ]
11425      },
11426      "promise": {
11427          "requires": [
11428              "timers"
11429          ]
11430      },
11431      "querystring": {
11432          "use": [
11433              "querystring-parse",
11434              "querystring-stringify"
11435          ]
11436      },
11437      "querystring-parse": {
11438          "requires": [
11439              "yui-base",
11440              "array-extras"
11441          ]
11442      },
11443      "querystring-parse-simple": {
11444          "requires": [
11445              "yui-base"
11446          ]
11447      },
11448      "querystring-stringify": {
11449          "requires": [
11450              "yui-base"
11451          ]
11452      },
11453      "querystring-stringify-simple": {
11454          "requires": [
11455              "yui-base"
11456          ]
11457      },
11458      "queue-promote": {
11459          "requires": [
11460              "yui-base"
11461          ]
11462      },
11463      "range-slider": {
11464          "requires": [
11465              "slider-base",
11466              "slider-value-range",
11467              "clickable-rail"
11468          ]
11469      },
11470      "recordset": {
11471          "use": [
11472              "recordset-base",
11473              "recordset-sort",
11474              "recordset-filter",
11475              "recordset-indexer"
11476          ]
11477      },
11478      "recordset-base": {
11479          "requires": [
11480              "base",
11481              "arraylist"
11482          ]
11483      },
11484      "recordset-filter": {
11485          "requires": [
11486              "recordset-base",
11487              "array-extras",
11488              "plugin"
11489          ]
11490      },
11491      "recordset-indexer": {
11492          "requires": [
11493              "recordset-base",
11494              "plugin"
11495          ]
11496      },
11497      "recordset-sort": {
11498          "requires": [
11499              "arraysort",
11500              "recordset-base",
11501              "plugin"
11502          ]
11503      },
11504      "resize": {
11505          "use": [
11506              "resize-base",
11507              "resize-proxy",
11508              "resize-constrain"
11509          ]
11510      },
11511      "resize-base": {
11512          "requires": [
11513              "base",
11514              "widget",
11515              "event",
11516              "oop",
11517              "dd-drag",
11518              "dd-delegate",
11519              "dd-drop"
11520          ],
11521          "skinnable": true
11522      },
11523      "resize-constrain": {
11524          "requires": [
11525              "plugin",
11526              "resize-base"
11527          ]
11528      },
11529      "resize-plugin": {
11530          "optional": [
11531              "resize-constrain"
11532          ],
11533          "requires": [
11534              "resize-base",
11535              "plugin"
11536          ]
11537      },
11538      "resize-proxy": {
11539          "requires": [
11540              "plugin",
11541              "resize-base"
11542          ]
11543      },
11544      "router": {
11545          "optional": [
11546              "querystring-parse"
11547          ],
11548          "requires": [
11549              "array-extras",
11550              "base-build",
11551              "history"
11552          ]
11553      },
11554      "scrollview": {
11555          "requires": [
11556              "scrollview-base",
11557              "scrollview-scrollbars"
11558          ]
11559      },
11560      "scrollview-base": {
11561          "requires": [
11562              "widget",
11563              "event-gestures",
11564              "event-mousewheel",
11565              "transition"
11566          ],
11567          "skinnable": true
11568      },
11569      "scrollview-base-ie": {
11570          "condition": {
11571              "name": "scrollview-base-ie",
11572              "trigger": "scrollview-base",
11573              "ua": "ie"
11574          },
11575          "requires": [
11576              "scrollview-base"
11577          ]
11578      },
11579      "scrollview-list": {
11580          "requires": [
11581              "plugin",
11582              "classnamemanager"
11583          ],
11584          "skinnable": true
11585      },
11586      "scrollview-paginator": {
11587          "requires": [
11588              "plugin",
11589              "classnamemanager"
11590          ]
11591      },
11592      "scrollview-scrollbars": {
11593          "requires": [
11594              "classnamemanager",
11595              "transition",
11596              "plugin"
11597          ],
11598          "skinnable": true
11599      },
11600      "selector": {
11601          "requires": [
11602              "selector-native"
11603          ]
11604      },
11605      "selector-css2": {
11606          "condition": {
11607              "name": "selector-css2",
11608              "test": function (Y) {
11609      var DOCUMENT = Y.config.doc,
11610          ret = DOCUMENT && !('querySelectorAll' in DOCUMENT);
11611  
11612      return ret;
11613  },
11614              "trigger": "selector"
11615          },
11616          "requires": [
11617              "selector-native"
11618          ]
11619      },
11620      "selector-css3": {
11621          "requires": [
11622              "selector-native",
11623              "selector-css2"
11624          ]
11625      },
11626      "selector-native": {
11627          "requires": [
11628              "dom-base"
11629          ]
11630      },
11631      "series-area": {
11632          "requires": [
11633              "series-cartesian",
11634              "series-fill-util"
11635          ]
11636      },
11637      "series-area-stacked": {
11638          "requires": [
11639              "series-stacked",
11640              "series-area"
11641          ]
11642      },
11643      "series-areaspline": {
11644          "requires": [
11645              "series-area",
11646              "series-curve-util"
11647          ]
11648      },
11649      "series-areaspline-stacked": {
11650          "requires": [
11651              "series-stacked",
11652              "series-areaspline"
11653          ]
11654      },
11655      "series-bar": {
11656          "requires": [
11657              "series-marker",
11658              "series-histogram-base"
11659          ]
11660      },
11661      "series-bar-stacked": {
11662          "requires": [
11663              "series-stacked",
11664              "series-bar"
11665          ]
11666      },
11667      "series-base": {
11668          "requires": [
11669              "graphics",
11670              "axis-base"
11671          ]
11672      },
11673      "series-candlestick": {
11674          "requires": [
11675              "series-range"
11676          ]
11677      },
11678      "series-cartesian": {
11679          "requires": [
11680              "series-base"
11681          ]
11682      },
11683      "series-column": {
11684          "requires": [
11685              "series-marker",
11686              "series-histogram-base"
11687          ]
11688      },
11689      "series-column-stacked": {
11690          "requires": [
11691              "series-stacked",
11692              "series-column"
11693          ]
11694      },
11695      "series-combo": {
11696          "requires": [
11697              "series-cartesian",
11698              "series-line-util",
11699              "series-plot-util",
11700              "series-fill-util"
11701          ]
11702      },
11703      "series-combo-stacked": {
11704          "requires": [
11705              "series-stacked",
11706              "series-combo"
11707          ]
11708      },
11709      "series-combospline": {
11710          "requires": [
11711              "series-combo",
11712              "series-curve-util"
11713          ]
11714      },
11715      "series-combospline-stacked": {
11716          "requires": [
11717              "series-combo-stacked",
11718              "series-curve-util"
11719          ]
11720      },
11721      "series-curve-util": {},
11722      "series-fill-util": {},
11723      "series-histogram-base": {
11724          "requires": [
11725              "series-cartesian",
11726              "series-plot-util"
11727          ]
11728      },
11729      "series-line": {
11730          "requires": [
11731              "series-cartesian",
11732              "series-line-util"
11733          ]
11734      },
11735      "series-line-stacked": {
11736          "requires": [
11737              "series-stacked",
11738              "series-line"
11739          ]
11740      },
11741      "series-line-util": {},
11742      "series-marker": {
11743          "requires": [
11744              "series-cartesian",
11745              "series-plot-util"
11746          ]
11747      },
11748      "series-marker-stacked": {
11749          "requires": [
11750              "series-stacked",
11751              "series-marker"
11752          ]
11753      },
11754      "series-ohlc": {
11755          "requires": [
11756              "series-range"
11757          ]
11758      },
11759      "series-pie": {
11760          "requires": [
11761              "series-base",
11762              "series-plot-util"
11763          ]
11764      },
11765      "series-plot-util": {},
11766      "series-range": {
11767          "requires": [
11768              "series-cartesian"
11769          ]
11770      },
11771      "series-spline": {
11772          "requires": [
11773              "series-line",
11774              "series-curve-util"
11775          ]
11776      },
11777      "series-spline-stacked": {
11778          "requires": [
11779              "series-stacked",
11780              "series-spline"
11781          ]
11782      },
11783      "series-stacked": {
11784          "requires": [
11785              "axis-stacked"
11786          ]
11787      },
11788      "shim-plugin": {
11789          "requires": [
11790              "node-style",
11791              "node-pluginhost"
11792          ]
11793      },
11794      "slider": {
11795          "use": [
11796              "slider-base",
11797              "slider-value-range",
11798              "clickable-rail",
11799              "range-slider"
11800          ]
11801      },
11802      "slider-base": {
11803          "requires": [
11804              "widget",
11805              "dd-constrain",
11806              "event-key"
11807          ],
11808          "skinnable": true
11809      },
11810      "slider-value-range": {
11811          "requires": [
11812              "slider-base"
11813          ]
11814      },
11815      "sortable": {
11816          "requires": [
11817              "dd-delegate",
11818              "dd-drop-plugin",
11819              "dd-proxy"
11820          ]
11821      },
11822      "sortable-scroll": {
11823          "requires": [
11824              "dd-scroll",
11825              "sortable"
11826          ]
11827      },
11828      "stylesheet": {
11829          "requires": [
11830              "yui-base"
11831          ]
11832      },
11833      "substitute": {
11834          "optional": [
11835              "dump"
11836          ],
11837          "requires": [
11838              "yui-base"
11839          ]
11840      },
11841      "swf": {
11842          "requires": [
11843              "event-custom",
11844              "node",
11845              "swfdetect",
11846              "escape"
11847          ]
11848      },
11849      "swfdetect": {
11850          "requires": [
11851              "yui-base"
11852          ]
11853      },
11854      "tabview": {
11855          "requires": [
11856              "widget",
11857              "widget-parent",
11858              "widget-child",
11859              "tabview-base",
11860              "node-pluginhost",
11861              "node-focusmanager"
11862          ],
11863          "skinnable": true
11864      },
11865      "tabview-base": {
11866          "requires": [
11867              "node-event-delegate",
11868              "classnamemanager"
11869          ]
11870      },
11871      "tabview-plugin": {
11872          "requires": [
11873              "tabview-base"
11874          ]
11875      },
11876      "template": {
11877          "use": [
11878              "template-base",
11879              "template-micro"
11880          ]
11881      },
11882      "template-base": {
11883          "requires": [
11884              "yui-base"
11885          ]
11886      },
11887      "template-micro": {
11888          "requires": [
11889              "escape"
11890          ]
11891      },
11892      "test": {
11893          "requires": [
11894              "event-simulate",
11895              "event-custom",
11896              "json-stringify"
11897          ]
11898      },
11899      "test-console": {
11900          "requires": [
11901              "console-filters",
11902              "test",
11903              "array-extras"
11904          ],
11905          "skinnable": true
11906      },
11907      "text": {
11908          "use": [
11909              "text-accentfold",
11910              "text-wordbreak"
11911          ]
11912      },
11913      "text-accentfold": {
11914          "requires": [
11915              "array-extras",
11916              "text-data-accentfold"
11917          ]
11918      },
11919      "text-data-accentfold": {
11920          "requires": [
11921              "yui-base"
11922          ]
11923      },
11924      "text-data-wordbreak": {
11925          "requires": [
11926              "yui-base"
11927          ]
11928      },
11929      "text-wordbreak": {
11930          "requires": [
11931              "array-extras",
11932              "text-data-wordbreak"
11933          ]
11934      },
11935      "timers": {
11936          "requires": [
11937              "yui-base"
11938          ]
11939      },
11940      "transition": {
11941          "requires": [
11942              "node-style"
11943          ]
11944      },
11945      "transition-timer": {
11946          "condition": {
11947              "name": "transition-timer",
11948              "test": function (Y) {
11949      var DOCUMENT = Y.config.doc,
11950          node = (DOCUMENT) ? DOCUMENT.documentElement: null,
11951          ret = true;
11952  
11953      if (node && node.style) {
11954          ret = !('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
11955      }
11956  
11957      return ret;
11958  },
11959              "trigger": "transition"
11960          },
11961          "requires": [
11962              "transition"
11963          ]
11964      },
11965      "tree": {
11966          "requires": [
11967              "base-build",
11968              "tree-node"
11969          ]
11970      },
11971      "tree-labelable": {
11972          "requires": [
11973              "tree"
11974          ]
11975      },
11976      "tree-lazy": {
11977          "requires": [
11978              "base-pluginhost",
11979              "plugin",
11980              "tree"
11981          ]
11982      },
11983      "tree-node": {},
11984      "tree-openable": {
11985          "requires": [
11986              "tree"
11987          ]
11988      },
11989      "tree-selectable": {
11990          "requires": [
11991              "tree"
11992          ]
11993      },
11994      "tree-sortable": {
11995          "requires": [
11996              "tree"
11997          ]
11998      },
11999      "uploader": {
12000          "requires": [
12001              "uploader-html5",
12002              "uploader-flash"
12003          ]
12004      },
12005      "uploader-flash": {
12006          "requires": [
12007              "swfdetect",
12008              "escape",
12009              "widget",
12010              "base",
12011              "cssbutton",
12012              "node",
12013              "event-custom",
12014              "uploader-queue"
12015          ]
12016      },
12017      "uploader-html5": {
12018          "requires": [
12019              "widget",
12020              "node-event-simulate",
12021              "file-html5",
12022              "uploader-queue"
12023          ]
12024      },
12025      "uploader-queue": {
12026          "requires": [
12027              "base"
12028          ]
12029      },
12030      "view": {
12031          "requires": [
12032              "base-build",
12033              "node-event-delegate"
12034          ]
12035      },
12036      "view-node-map": {
12037          "requires": [
12038              "view"
12039          ]
12040      },
12041      "widget": {
12042          "use": [
12043              "widget-base",
12044              "widget-htmlparser",
12045              "widget-skin",
12046              "widget-uievents"
12047          ]
12048      },
12049      "widget-anim": {
12050          "requires": [
12051              "anim-base",
12052              "plugin",
12053              "widget"
12054          ]
12055      },
12056      "widget-autohide": {
12057          "requires": [
12058              "base-build",
12059              "event-key",
12060              "event-outside",
12061              "widget"
12062          ]
12063      },
12064      "widget-base": {
12065          "requires": [
12066              "attribute",
12067              "base-base",
12068              "base-pluginhost",
12069              "classnamemanager",
12070              "event-focus",
12071              "node-base",
12072              "node-style"
12073          ],
12074          "skinnable": true
12075      },
12076      "widget-base-ie": {
12077          "condition": {
12078              "name": "widget-base-ie",
12079              "trigger": "widget-base",
12080              "ua": "ie"
12081          },
12082          "requires": [
12083              "widget-base"
12084          ]
12085      },
12086      "widget-buttons": {
12087          "requires": [
12088              "button-plugin",
12089              "cssbutton",
12090              "widget-stdmod"
12091          ]
12092      },
12093      "widget-child": {
12094          "requires": [
12095              "base-build",
12096              "widget"
12097          ]
12098      },
12099      "widget-htmlparser": {
12100          "requires": [
12101              "widget-base"
12102          ]
12103      },
12104      "widget-modality": {
12105          "requires": [
12106              "base-build",
12107              "event-outside",
12108              "widget"
12109          ],
12110          "skinnable": true
12111      },
12112      "widget-parent": {
12113          "requires": [
12114              "arraylist",
12115              "base-build",
12116              "widget"
12117          ]
12118      },
12119      "widget-position": {
12120          "requires": [
12121              "base-build",
12122              "node-screen",
12123              "widget"
12124          ]
12125      },
12126      "widget-position-align": {
12127          "requires": [
12128              "widget-position"
12129          ]
12130      },
12131      "widget-position-constrain": {
12132          "requires": [
12133              "widget-position"
12134          ]
12135      },
12136      "widget-skin": {
12137          "requires": [
12138              "widget-base"
12139          ]
12140      },
12141      "widget-stack": {
12142          "requires": [
12143              "base-build",
12144              "widget"
12145          ],
12146          "skinnable": true
12147      },
12148      "widget-stdmod": {
12149          "requires": [
12150              "base-build",
12151              "widget"
12152          ]
12153      },
12154      "widget-uievents": {
12155          "requires": [
12156              "node-event-delegate",
12157              "widget-base"
12158          ]
12159      },
12160      "yql": {
12161          "requires": [
12162              "oop"
12163          ]
12164      },
12165      "yql-jsonp": {
12166          "condition": {
12167              "name": "yql-jsonp",
12168              "test": function (Y) {
12169      /* Only load the JSONP module when not in nodejs or winjs
12170      TODO Make the winjs module a CORS module
12171      */
12172      return (!Y.UA.nodejs && !Y.UA.winjs);
12173  },
12174              "trigger": "yql"
12175          },
12176          "requires": [
12177              "yql",
12178              "jsonp",
12179              "jsonp-url"
12180          ]
12181      },
12182      "yql-nodejs": {
12183          "condition": {
12184              "name": "yql-nodejs",
12185              "trigger": "yql",
12186              "ua": "nodejs"
12187          },
12188          "requires": [
12189              "yql"
12190          ]
12191      },
12192      "yql-winjs": {
12193          "condition": {
12194              "name": "yql-winjs",
12195              "trigger": "yql",
12196              "ua": "winjs"
12197          },
12198          "requires": [
12199              "yql"
12200          ]
12201      },
12202      "yui": {},
12203      "yui-base": {},
12204      "yui-later": {
12205          "requires": [
12206              "yui-base"
12207          ]
12208      },
12209      "yui-log": {
12210          "requires": [
12211              "yui-base"
12212          ]
12213      },
12214      "yui-throttle": {
12215          "requires": [
12216              "yui-base"
12217          ]
12218      }
12219  });
12220  YUI.Env[Y.version].md5 = '45357bb11eddf7fd0a89c0b756599df2';
12221  
12222  
12223  }, '3.17.2', {"requires": ["loader-base"]});
12224  YUI.add('yui', function (Y, NAME) {}, '3.17.2', {
12225      "use": [
12226          "yui-base",
12227          "get",
12228          "features",
12229          "intl-base",
12230          "yui-log",
12231          "yui-later",
12232          "loader-base",
12233          "loader-rollup",
12234          "loader-yui3"
12235      ]
12236  });


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1