diff -r 322d0feea350 -r 89ef5ed3c48b src/cm/media/js/lib/yui/yui_3.10.3/build/yui-nodejs/yui-nodejs.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cm/media/js/lib/yui/yui_3.10.3/build/yui-nodejs/yui-nodejs.js Tue Jul 16 14:29:46 2013 +0200 @@ -0,0 +1,10455 @@ +/* +YUI 3.10.3 (build 2fb5187) +Copyright 2013 Yahoo! Inc. All rights reserved. +Licensed under the BSD License. +http://yuilibrary.com/license/ +*/ + +/** +The YUI module contains the components required for building the YUI seed file. +This includes the script loading mechanism, a simple queue, and the core +utilities for the library. + +@module yui +@main yui +@submodule yui-base +**/ + +/*jshint eqeqeq: false*/ +if (typeof YUI != 'undefined') { + YUI._YUI = YUI; +} + +/** +The YUI global namespace object. This is the constructor for all YUI instances. + +This is a self-instantiable factory function, meaning you don't need to precede +it with the `new` operator. You can invoke it directly like this: + + YUI().use('*', function (Y) { + // Y is a new YUI instance. + }); + +But it also works like this: + + var Y = YUI(); + +The `YUI` constructor accepts an optional config object, like this: + + YUI({ + debug: true, + combine: false + }).use('node', function (Y) { + // Y.Node is ready to use. + }); + +See the API docs for the Config class for the complete +list of supported configuration properties accepted by the YUI constuctor. + +If a global `YUI` object is already defined, the existing YUI object will not be +overwritten, to ensure that defined namespaces are preserved. + +Each YUI instance has full custom event support, but only if the event system is +available. + +@class YUI +@uses EventTarget +@constructor +@global +@param {Object} [config]* Zero or more optional configuration objects. Config + values are stored in the `Y.config` property. See the + Config docs for the list of supported properties. +**/ + + /*global YUI*/ + /*global YUI_config*/ + var YUI = function() { + var i = 0, + Y = this, + args = arguments, + l = args.length, + instanceOf = function(o, type) { + return (o && o.hasOwnProperty && (o instanceof type)); + }, + gconf = (typeof YUI_config !== 'undefined') && YUI_config; + + if (!(instanceOf(Y, YUI))) { + Y = new YUI(); + } else { + // set up the core environment + Y._init(); + + /** + Master configuration that might span multiple contexts in a non- + browser environment. It is applied first to all instances in all + contexts. + + @example + + YUI.GlobalConfig = { + filter: 'debug' + }; + + YUI().use('node', function (Y) { + // debug files used here + }); + + YUI({ + filter: 'min' + }).use('node', function (Y) { + // min files used here + }); + + @property {Object} GlobalConfig + @global + @static + **/ + if (YUI.GlobalConfig) { + Y.applyConfig(YUI.GlobalConfig); + } + + /** + Page-level config applied to all YUI instances created on the + current page. This is applied after `YUI.GlobalConfig` and before + any instance-level configuration. + + @example + + // Single global var to include before YUI seed file + YUI_config = { + filter: 'debug' + }; + + YUI().use('node', function (Y) { + // debug files used here + }); + + YUI({ + filter: 'min' + }).use('node', function (Y) { + // min files used here + }); + + @property {Object} YUI_config + @global + **/ + if (gconf) { + Y.applyConfig(gconf); + } + + // bind the specified additional modules for this instance + if (!l) { + Y._setup(); + } + } + + if (l) { + // Each instance can accept one or more configuration objects. + // These are applied after YUI.GlobalConfig and YUI_Config, + // overriding values set in those config files if there is a + // matching property. + for (; i < l; i++) { + Y.applyConfig(args[i]); + } + + Y._setup(); + } + + Y.instanceOf = instanceOf; + + return Y; + }; + +(function() { + + var proto, prop, + VERSION = '3.10.3', + PERIOD = '.', + BASE = 'http://yui.yahooapis.com/', + /* + These CSS class names can't be generated by + getClassName since it is not available at the + time they are being used. + */ + DOC_LABEL = 'yui3-js-enabled', + CSS_STAMP_EL = 'yui3-css-stamp', + NOOP = function() {}, + SLICE = Array.prototype.slice, + APPLY_TO_AUTH = { 'io.xdrReady': 1, // the functions applyTo + 'io.xdrResponse': 1, // can call. this should + 'SWF.eventHandler': 1 }, // be done at build time + hasWin = (typeof window != 'undefined'), + win = (hasWin) ? window : null, + doc = (hasWin) ? win.document : null, + docEl = doc && doc.documentElement, + docClass = docEl && docEl.className, + instances = {}, + time = new Date().getTime(), + add = function(el, type, fn, capture) { + if (el && el.addEventListener) { + el.addEventListener(type, fn, capture); + } else if (el && el.attachEvent) { + el.attachEvent('on' + type, fn); + } + }, + remove = function(el, type, fn, capture) { + if (el && el.removeEventListener) { + // this can throw an uncaught exception in FF + try { + el.removeEventListener(type, fn, capture); + } catch (ex) {} + } else if (el && el.detachEvent) { + el.detachEvent('on' + type, fn); + } + }, + handleLoad = function() { + YUI.Env.windowLoaded = true; + YUI.Env.DOMReady = true; + if (hasWin) { + remove(window, 'load', handleLoad); + } + }, + getLoader = function(Y, o) { + var loader = Y.Env._loader, + lCore = [ 'loader-base' ], + G_ENV = YUI.Env, + mods = G_ENV.mods; + + if (loader) { + //loader._config(Y.config); + loader.ignoreRegistered = false; + loader.onEnd = null; + loader.data = null; + loader.required = []; + loader.loadType = null; + } else { + loader = new Y.Loader(Y.config); + Y.Env._loader = loader; + } + if (mods && mods.loader) { + lCore = [].concat(lCore, YUI.Env.loaderExtras); + } + YUI.Env.core = Y.Array.dedupe([].concat(YUI.Env.core, lCore)); + + return loader; + }, + + clobber = function(r, s) { + for (var i in s) { + if (s.hasOwnProperty(i)) { + r[i] = s[i]; + } + } + }, + + ALREADY_DONE = { success: true }; + +// Stamp the documentElement (HTML) with a class of "yui-loaded" to +// enable styles that need to key off of JS being enabled. +if (docEl && docClass.indexOf(DOC_LABEL) == -1) { + if (docClass) { + docClass += ' '; + } + docClass += DOC_LABEL; + docEl.className = docClass; +} + +if (VERSION.indexOf('@') > -1) { + VERSION = '3.5.0'; // dev time hack for cdn test +} + +proto = { + /** + Applies a new configuration object to the config of this YUI instance. This + will merge new group/module definitions, and will also update the loader + cache if necessary. Updating `Y.config` directly will not update the cache. + + @method applyConfig + @param {Object} o the configuration object. + @since 3.2.0 + **/ + applyConfig: function(o) { + + o = o || NOOP; + + var attr, + name, + // detail, + config = this.config, + mods = config.modules, + groups = config.groups, + aliases = config.aliases, + loader = this.Env._loader; + + for (name in o) { + if (o.hasOwnProperty(name)) { + attr = o[name]; + if (mods && name == 'modules') { + clobber(mods, attr); + } else if (aliases && name == 'aliases') { + clobber(aliases, attr); + } else if (groups && name == 'groups') { + clobber(groups, attr); + } else if (name == 'win') { + config[name] = (attr && attr.contentWindow) || attr; + config.doc = config[name] ? config[name].document : null; + } else if (name == '_yuid') { + // preserve the guid + } else { + config[name] = attr; + } + } + } + + if (loader) { + loader._config(o); + } + + }, + + /** + Old way to apply a config to this instance (calls `applyConfig` under the + hood). + + @private + @method _config + @param {Object} o The config to apply + **/ + _config: function(o) { + this.applyConfig(o); + }, + + /** + Initializes this YUI instance. + + @private + @method _init + **/ + _init: function() { + var filter, el, + Y = this, + G_ENV = YUI.Env, + Env = Y.Env, + prop; + + /** + The version number of this YUI instance. + + This value is typically updated by a script when a YUI release is built, + so it may not reflect the correct version number when YUI is run from + the development source tree. + + @property {String} version + **/ + Y.version = VERSION; + + if (!Env) { + Y.Env = { + core: ['get', 'features', 'intl-base', 'yui-log', 'yui-log-nodejs', 'yui-later', 'loader-base', 'loader-rollup', 'loader-yui3'], + loaderExtras: ['loader-rollup', 'loader-yui3'], + mods: {}, // flat module map + versions: {}, // version module map + base: BASE, + cdn: BASE + VERSION + '/build/', + // bootstrapped: false, + _idx: 0, + _used: {}, + _attached: {}, + _missed: [], + _yidx: 0, + _uidx: 0, + _guidp: 'y', + _loaded: {}, + // serviced: {}, + // Regex in English: + // I'll start at the \b(simpleyui). + // 1. Look in the test string for "simpleyui" or "yui" or + // "yui-base" or "yui-davglass" or "yui-foobar" that comes after a word break. That is, it + // can't match "foyui" or "i_heart_simpleyui". This can be anywhere in the string. + // 2. After #1 must come a forward slash followed by the string matched in #1, so + // "yui-base/yui-base" or "simpleyui/simpleyui" or "yui-pants/yui-pants". + // 3. The second occurence of the #1 token can optionally be followed by "-debug" or "-min", + // so "yui/yui-min", "yui/yui-debug", "yui-base/yui-base-debug". NOT "yui/yui-tshirt". + // 4. This is followed by ".js", so "yui/yui.js", "simpleyui/simpleyui-min.js" + // 0. Going back to the beginning, now. If all that stuff in 1-4 comes after a "?" in the string, + // then capture the junk between the LAST "&" and the string in 1-4. So + // "blah?foo/yui/yui.js" will capture "foo/" and "blah?some/thing.js&3.3.0/build/yui-davglass/yui-davglass.js" + // will capture "3.3.0/build/" + // + // Regex Exploded: + // (?:\? Find a ? + // (?:[^&]*&) followed by 0..n characters followed by an & + // * in fact, find as many sets of characters followed by a & as you can + // ([^&]*) capture the stuff after the last & in \1 + // )? but it's ok if all this ?junk&more_junk stuff isn't even there + // \b(simpleyui| after a word break find either the string "simpleyui" or + // yui(?:-\w+)? the string "yui" optionally followed by a -, then more characters + // ) and store the simpleyui or yui-* string in \2 + // \/\2 then comes a / followed by the simpleyui or yui-* string in \2 + // (?:-(min|debug))? optionally followed by "-min" or "-debug" + // .js and ending in ".js" + _BASE_RE: /(?:\?(?:[^&]*&)*([^&]*))?\b(simpleyui|yui(?:-\w+)?)\/\2(?:-(min|debug))?\.js/, + parseBasePath: function(src, pattern) { + var match = src.match(pattern), + path, filter; + + if (match) { + path = RegExp.leftContext || src.slice(0, src.indexOf(match[0])); + + // this is to set up the path to the loader. The file + // filter for loader should match the yui include. + filter = match[3]; + + // extract correct path for mixed combo urls + // http://yuilibrary.com/projects/yui3/ticket/2528423 + if (match[1]) { + path += '?' + match[1]; + } + path = { + filter: filter, + path: path + }; + } + return path; + }, + getBase: G_ENV && G_ENV.getBase || + function(pattern) { + var nodes = (doc && doc.getElementsByTagName('script')) || [], + path = Env.cdn, parsed, + i, len, src; + + for (i = 0, len = nodes.length; i < len; ++i) { + src = nodes[i].src; + if (src) { + parsed = Y.Env.parseBasePath(src, pattern); + if (parsed) { + filter = parsed.filter; + path = parsed.path; + break; + } + } + } + + // use CDN default + return path; + } + + }; + + Env = Y.Env; + + Env._loaded[VERSION] = {}; + + if (G_ENV && Y !== YUI) { + Env._yidx = ++G_ENV._yidx; + Env._guidp = ('yui_' + VERSION + '_' + + Env._yidx + '_' + time).replace(/[^a-z0-9_]+/g, '_'); + } else if (YUI._YUI) { + + G_ENV = YUI._YUI.Env; + Env._yidx += G_ENV._yidx; + Env._uidx += G_ENV._uidx; + + for (prop in G_ENV) { + if (!(prop in Env)) { + Env[prop] = G_ENV[prop]; + } + } + + delete YUI._YUI; + } + + Y.id = Y.stamp(Y); + instances[Y.id] = Y; + + } + + Y.constructor = YUI; + + // configuration defaults + Y.config = Y.config || { + bootstrap: true, + cacheUse: true, + debug: true, + doc: doc, + fetchCSS: true, + throwFail: true, + useBrowserConsole: true, + useNativeES5: true, + win: win, + global: Function('return this')() + }; + + //Register the CSS stamp element + if (doc && !doc.getElementById(CSS_STAMP_EL)) { + el = doc.createElement('div'); + el.innerHTML = '
'; + YUI.Env.cssStampEl = el.firstChild; + if (doc.body) { + doc.body.appendChild(YUI.Env.cssStampEl); + } else { + docEl.insertBefore(YUI.Env.cssStampEl, docEl.firstChild); + } + } else if (doc && doc.getElementById(CSS_STAMP_EL) && !YUI.Env.cssStampEl) { + YUI.Env.cssStampEl = doc.getElementById(CSS_STAMP_EL); + } + + Y.config.lang = Y.config.lang || 'en-US'; + + Y.config.base = YUI.config.base || Y.Env.getBase(Y.Env._BASE_RE); + + if (!filter || (!('mindebug').indexOf(filter))) { + filter = 'min'; + } + filter = (filter) ? '-' + filter : filter; + Y.config.loaderPath = YUI.config.loaderPath || 'loader/loader' + filter + '.js'; + + }, + + /** + Finishes the instance setup. Attaches whatever YUI modules were defined + at the time that this instance was created. + + @method _setup + @private + **/ + _setup: function() { + var i, Y = this, + core = [], + mods = YUI.Env.mods, + extras = Y.config.core || [].concat(YUI.Env.core); //Clone it.. + + for (i = 0; i < extras.length; i++) { + if (mods[extras[i]]) { + core.push(extras[i]); + } + } + + Y._attach(['yui-base']); + Y._attach(core); + + if (Y.Loader) { + getLoader(Y); + } + + }, + + /** + Executes the named method on the specified YUI instance if that method is + whitelisted. + + @method applyTo + @param {String} id YUI instance id. + @param {String} method Name of the method to execute. For example: + 'Object.keys'. + @param {Array} args Arguments to apply to the method. + @return {Mixed} Return value from the applied method, or `null` if the + specified instance was not found or the method was not whitelisted. + **/ + applyTo: function(id, method, args) { + if (!(method in APPLY_TO_AUTH)) { + this.log(method + ': applyTo not allowed', 'warn', 'yui'); + return null; + } + + var instance = instances[id], nest, m, i; + if (instance) { + nest = method.split('.'); + m = instance; + for (i = 0; i < nest.length; i = i + 1) { + m = m[nest[i]]; + if (!m) { + this.log('applyTo not found: ' + method, 'warn', 'yui'); + } + } + return m && m.apply(instance, args); + } + + return null; + }, + +/** +Registers a YUI module and makes it available for use in a `YUI().use()` call or +as a dependency for other modules. + +The easiest way to create a first-class YUI module is to use +Shifter, the YUI component build +tool. + +Shifter will automatically wrap your module code in a `YUI.add()` call along +with any configuration info required for the module. + +@example + + YUI.add('davglass', function (Y) { + Y.davglass = function () { + }; + }, '3.4.0', { + requires: ['harley-davidson', 'mt-dew'] + }); + +@method add +@param {String} name Module name. +@param {Function} fn Function containing module code. This function will be + executed whenever the module is attached to a specific YUI instance. + + @param {YUI} fn.Y The YUI instance to which this module is attached. + @param {String} fn.name Name of the module + +@param {String} version Module version number. This is currently used only for + informational purposes, and is not used internally by YUI. + +@param {Object} [config] Module config. + @param {Array} [config.requires] Array of other module names that must be + attached before this module can be attached. + @param {Array} [config.optional] Array of optional module names that should + be attached before this module is attached if they've already been + loaded. If the `loadOptional` YUI option is `true`, optional modules + that have not yet been loaded will be loaded just as if they were hard + requirements. + @param {Array} [config.use] Array of module names that are included within + or otherwise provided by this module, and which should be attached + automatically when this module is attached. This makes it possible to + create "virtual rollup" modules that simply attach a collection of other + modules or submodules. + +@return {YUI} This YUI instance. +**/ + add: function(name, fn, version, details) { + details = details || {}; + var env = YUI.Env, + mod = { + name: name, + fn: fn, + version: version, + details: details + }, + //Instance hash so we don't apply it to the same instance twice + applied = {}, + loader, inst, + i, versions = env.versions; + + env.mods[name] = mod; + versions[version] = versions[version] || {}; + versions[version][name] = mod; + + for (i in instances) { + if (instances.hasOwnProperty(i)) { + inst = instances[i]; + if (!applied[inst.id]) { + applied[inst.id] = true; + loader = inst.Env._loader; + if (loader) { + if (!loader.moduleInfo[name] || loader.moduleInfo[name].temp) { + loader.addModule(details, name); + } + } + } + } + } + + return this; + }, + + /** + Executes the callback function associated with each required module, + attaching the module to this YUI instance. + + @method _attach + @param {Array} r The array of modules to attach + @param {Boolean} [moot=false] If `true`, don't throw a warning if the module + is not attached. + @private + **/ + _attach: function(r, moot) { + var i, name, mod, details, req, use, after, + mods = YUI.Env.mods, + aliases = YUI.Env.aliases, + Y = this, j, + cache = YUI.Env._renderedMods, + loader = Y.Env._loader, + done = Y.Env._attached, + len = r.length, loader, def, go, + c = []; + + //Check for conditional modules (in a second+ instance) and add their requirements + //TODO I hate this entire method, it needs to be fixed ASAP (3.5.0) ^davglass + for (i = 0; i < len; i++) { + name = r[i]; + mod = mods[name]; + c.push(name); + if (loader && loader.conditions[name]) { + for (j in loader.conditions[name]) { + if (loader.conditions[name].hasOwnProperty(j)) { + def = loader.conditions[name][j]; + go = def && ((def.ua && Y.UA[def.ua]) || (def.test && def.test(Y))); + if (go) { + c.push(def.name); + } + } + } + } + } + r = c; + len = r.length; + + for (i = 0; i < len; i++) { + if (!done[r[i]]) { + name = r[i]; + mod = mods[name]; + + if (aliases && aliases[name] && !mod) { + Y._attach(aliases[name]); + continue; + } + if (!mod) { + if (loader && loader.moduleInfo[name]) { + mod = loader.moduleInfo[name]; + moot = true; + } + + + //if (!loader || !loader.moduleInfo[name]) { + //if ((!loader || !loader.moduleInfo[name]) && !moot) { + if (!moot && name) { + if ((name.indexOf('skin-') === -1) && (name.indexOf('css') === -1)) { + Y.Env._missed.push(name); + Y.Env._missed = Y.Array.dedupe(Y.Env._missed); + Y.message('NOT loaded: ' + name, 'warn', 'yui'); + } + } + } else { + done[name] = true; + //Don't like this, but in case a mod was asked for once, then we fetch it + //We need to remove it from the missed list ^davglass + for (j = 0; j < Y.Env._missed.length; j++) { + if (Y.Env._missed[j] === name) { + Y.message('Found: ' + name + ' (was reported as missing earlier)', 'warn', 'yui'); + Y.Env._missed.splice(j, 1); + } + } + /* + If it's a temp module, we need to redo it's requirements if it's already loaded + since it may have been loaded by another instance and it's dependencies might + have been redefined inside the fetched file. + */ + if (loader && cache && cache[name] && cache[name].temp) { + loader.getRequires(cache[name]); + req = []; + for (j in loader.moduleInfo[name].expanded_map) { + if (loader.moduleInfo[name].expanded_map.hasOwnProperty(j)) { + req.push(j); + } + } + Y._attach(req); + } + + details = mod.details; + req = details.requires; + use = details.use; + after = details.after; + //Force Intl load if there is a language (Loader logic) @todo fix this shit + if (details.lang) { + req = req || []; + req.unshift('intl'); + } + + if (req) { + for (j = 0; j < req.length; j++) { + if (!done[req[j]]) { + if (!Y._attach(req)) { + return false; + } + break; + } + } + } + + if (after) { + for (j = 0; j < after.length; j++) { + if (!done[after[j]]) { + if (!Y._attach(after, true)) { + return false; + } + break; + } + } + } + + if (mod.fn) { + if (Y.config.throwFail) { + mod.fn(Y, name); + } else { + try { + mod.fn(Y, name); + } catch (e) { + Y.error('Attach error: ' + name, e, name); + return false; + } + } + } + + if (use) { + for (j = 0; j < use.length; j++) { + if (!done[use[j]]) { + if (!Y._attach(use)) { + return false; + } + break; + } + } + } + + + + } + } + } + + return true; + }, + + /** + Delays the `use` callback until another event has taken place such as + `window.onload`, `domready`, `contentready`, or `available`. + + @private + @method _delayCallback + @param {Function} cb The original `use` callback. + @param {String|Object} until Either an event name ('load', 'domready', etc.) + or an object containing event/args keys for contentready/available. + @return {Function} + **/ + _delayCallback: function(cb, until) { + + var Y = this, + mod = ['event-base']; + + until = (Y.Lang.isObject(until) ? until : { event: until }); + + if (until.event === 'load') { + mod.push('event-synthetic'); + } + + return function() { + var args = arguments; + Y._use(mod, function() { + Y.on(until.event, function() { + args[1].delayUntil = until.event; + cb.apply(Y, args); + }, until.args); + }); + }; + }, + + /** + Attaches one or more modules to this YUI instance. When this is executed, + the requirements of the desired modules are analyzed, and one of several + things can happen: + + + * All required modules have already been loaded, and just need to be + attached to this YUI instance. In this case, the `use()` callback will + be executed synchronously after the modules are attached. + + * One or more modules have not yet been loaded, or the Get utility is not + available, or the `bootstrap` config option is `false`. In this case, + a warning is issued indicating that modules are missing, but all + available modules will still be attached and the `use()` callback will + be executed synchronously. + + * One or more modules are missing and the Loader is not available but the + Get utility is, and `bootstrap` is not `false`. In this case, the Get + utility will be used to load the Loader, and we will then proceed to + the following state: + + * One or more modules are missing and the Loader is available. In this + case, the Loader will be used to resolve the dependency tree for the + missing modules and load them and their dependencies. When the Loader is + finished loading modules, the `use()` callback will be executed + asynchronously. + + @example + + // Loads and attaches dd and its dependencies. + YUI().use('dd', function (Y) { + // ... + }); + + // Loads and attaches dd and node as well as all of their dependencies. + YUI().use(['dd', 'node'], function (Y) { + // ... + }); + + // Attaches all modules that have already been loaded. + YUI().use('*', function (Y) { + // ... + }); + + // Attaches a gallery module. + YUI().use('gallery-yql', function (Y) { + // ... + }); + + // Attaches a YUI 2in3 module. + YUI().use('yui2-datatable', function (Y) { + // ... + }); + + @method use + @param {String|Array} modules* One or more module names to attach. + @param {Function} [callback] Callback function to be executed once all + specified modules and their dependencies have been attached. + @param {YUI} callback.Y The YUI instance created for this sandbox. + @param {Object} callback.status Object containing `success`, `msg` and + `data` properties. + @chainable + **/ + use: function() { + var args = SLICE.call(arguments, 0), + callback = args[args.length - 1], + Y = this, + i = 0, + name, + Env = Y.Env, + provisioned = true; + + // The last argument supplied to use can be a load complete callback + if (Y.Lang.isFunction(callback)) { + args.pop(); + if (Y.config.delayUntil) { + callback = Y._delayCallback(callback, Y.config.delayUntil); + } + } else { + callback = null; + } + if (Y.Lang.isArray(args[0])) { + args = args[0]; + } + + if (Y.config.cacheUse) { + while ((name = args[i++])) { + if (!Env._attached[name]) { + provisioned = false; + break; + } + } + + if (provisioned) { + if (args.length) { + } + Y._notify(callback, ALREADY_DONE, args); + return Y; + } + } + + if (Y._loading) { + Y._useQueue = Y._useQueue || new Y.Queue(); + Y._useQueue.add([args, callback]); + } else { + Y._use(args, function(Y, response) { + Y._notify(callback, response, args); + }); + } + + return Y; + }, + + /** + Handles Loader notifications about attachment/load errors. + + @method _notify + @param {Function} callback Callback to pass to `Y.config.loadErrorFn`. + @param {Object} response Response returned from Loader. + @param {Array} args Arguments passed from Loader. + @private + **/ + _notify: function(callback, response, args) { + if (!response.success && this.config.loadErrorFn) { + this.config.loadErrorFn.call(this, this, callback, response, args); + } else if (callback) { + if (this.Env._missed && this.Env._missed.length) { + response.msg = 'Missing modules: ' + this.Env._missed.join(); + response.success = false; + } + if (this.config.throwFail) { + callback(this, response); + } else { + try { + callback(this, response); + } catch (e) { + this.error('use callback error', e, args); + } + } + } + }, + + /** + Called from the `use` method queue to ensure that only one set of loading + logic is performed at a time. + + @method _use + @param {String} args* One or more modules to attach. + @param {Function} [callback] Function to call once all required modules have + been attached. + @private + **/ + _use: function(args, callback) { + + if (!this.Array) { + this._attach(['yui-base']); + } + + var len, loader, handleBoot, + Y = this, + G_ENV = YUI.Env, + mods = G_ENV.mods, + Env = Y.Env, + used = Env._used, + aliases = G_ENV.aliases, + queue = G_ENV._loaderQueue, + firstArg = args[0], + YArray = Y.Array, + config = Y.config, + boot = config.bootstrap, + missing = [], + i, + r = [], + ret = true, + fetchCSS = config.fetchCSS, + process = function(names, skip) { + + var i = 0, a = [], name, len, m, req, use; + + if (!names.length) { + return; + } + + if (aliases) { + len = names.length; + for (i = 0; i < len; i++) { + if (aliases[names[i]] && !mods[names[i]]) { + a = [].concat(a, aliases[names[i]]); + } else { + a.push(names[i]); + } + } + names = a; + } + + len = names.length; + + for (i = 0; i < len; i++) { + name = names[i]; + if (!skip) { + r.push(name); + } + + // only attach a module once + if (used[name]) { + continue; + } + + m = mods[name]; + req = null; + use = null; + + if (m) { + used[name] = true; + req = m.details.requires; + use = m.details.use; + } else { + // CSS files don't register themselves, see if it has + // been loaded + if (!G_ENV._loaded[VERSION][name]) { + missing.push(name); + } else { + used[name] = true; // probably css + } + } + + // make sure requirements are attached + if (req && req.length) { + process(req); + } + + // make sure we grab the submodule dependencies too + if (use && use.length) { + process(use, 1); + } + } + + }, + + handleLoader = function(fromLoader) { + var response = fromLoader || { + success: true, + msg: 'not dynamic' + }, + redo, origMissing, + ret = true, + data = response.data; + + Y._loading = false; + + if (data) { + origMissing = missing; + missing = []; + r = []; + process(data); + redo = missing.length; + if (redo) { + if ([].concat(missing).sort().join() == + origMissing.sort().join()) { + redo = false; + } + } + } + + if (redo && data) { + Y._loading = true; + Y._use(missing, function() { + if (Y._attach(data)) { + Y._notify(callback, response, data); + } + }); + } else { + if (data) { + ret = Y._attach(data); + } + if (ret) { + Y._notify(callback, response, args); + } + } + + if (Y._useQueue && Y._useQueue.size() && !Y._loading) { + Y._use.apply(Y, Y._useQueue.next()); + } + + }; + + + // YUI().use('*'); // bind everything available + if (firstArg === '*') { + args = []; + for (i in mods) { + if (mods.hasOwnProperty(i)) { + args.push(i); + } + } + ret = Y._attach(args); + if (ret) { + handleLoader(); + } + return Y; + } + + if ((mods.loader || mods['loader-base']) && !Y.Loader) { + Y._attach(['loader' + ((!mods.loader) ? '-base' : '')]); + } + + + // use loader to expand dependencies and sort the + // requirements if it is available. + if (boot && Y.Loader && args.length) { + loader = getLoader(Y); + loader.require(args); + loader.ignoreRegistered = true; + loader._boot = true; + loader.calculate(null, (fetchCSS) ? null : 'js'); + args = loader.sorted; + loader._boot = false; + } + + process(args); + + len = missing.length; + + + if (len) { + missing = YArray.dedupe(missing); + len = missing.length; + } + + + // dynamic load + if (boot && len && Y.Loader) { + Y._loading = true; + loader = getLoader(Y); + loader.onEnd = handleLoader; + loader.context = Y; + loader.data = args; + loader.ignoreRegistered = false; + loader.require(missing); + loader.insert(null, (fetchCSS) ? null : 'js'); + + } else if (boot && len && Y.Get && !Env.bootstrapped) { + + Y._loading = true; + + handleBoot = function() { + Y._loading = false; + queue.running = false; + Env.bootstrapped = true; + G_ENV._bootstrapping = false; + if (Y._attach(['loader'])) { + Y._use(args, callback); + } + }; + + if (G_ENV._bootstrapping) { + queue.add(handleBoot); + } else { + G_ENV._bootstrapping = true; + Y.Get.script(config.base + config.loaderPath, { + onEnd: handleBoot + }); + } + + } else { + ret = Y._attach(args); + if (ret) { + handleLoader(); + } + } + + return Y; + }, + + + /** + Utility method for safely creating namespaces if they don't already exist. + May be called statically on the YUI global object or as a method on a YUI + instance. + + When called statically, a namespace will be created on the YUI global + object: + + // Create `YUI.your.namespace.here` as nested objects, preserving any + // objects that already exist instead of overwriting them. + YUI.namespace('your.namespace.here'); + + When called as a method on a YUI instance, a namespace will be created on + that instance: + + // Creates `Y.property.package`. + Y.namespace('property.package'); + + Dots in the input string cause `namespace` to create nested objects for each + token. If any part of the requested namespace already exists, the current + object will be left in place and will not be overwritten. This allows + multiple calls to `namespace` to preserve existing namespaced properties. + + If the first token in the namespace string is "YAHOO", that token is + discarded. This is legacy behavior for backwards compatibility with YUI 2. + + Be careful with namespace tokens. Reserved words may work in some browsers + and not others. For instance, the following will fail in some browsers + because the supported version of JavaScript reserves the word "long": + + Y.namespace('really.long.nested.namespace'); + + Note: If you pass multiple arguments to create multiple namespaces, only the + last one created is returned from this function. + + @method namespace + @param {String} namespace* One or more namespaces to create. + @return {Object} Reference to the last namespace object created. + **/ + namespace: function() { + var a = arguments, o, i = 0, j, d, arg; + + for (; i < a.length; i++) { + o = this; //Reset base object per argument or it will get reused from the last + arg = a[i]; + if (arg.indexOf(PERIOD) > -1) { //Skip this if no "." is present + d = arg.split(PERIOD); + for (j = (d[0] == 'YAHOO') ? 1 : 0; j < d.length; j++) { + o[d[j]] = o[d[j]] || {}; + o = o[d[j]]; + } + } else { + o[arg] = o[arg] || {}; + o = o[arg]; //Reset base object to the new object so it's returned + } + } + return o; + }, + + // this is replaced if the log module is included + log: NOOP, + message: NOOP, + // this is replaced if the dump module is included + dump: function (o) { return ''+o; }, + + /** + Reports an error. + + The reporting mechanism is controlled by the `throwFail` configuration + attribute. If `throwFail` is falsy, the message is logged. If `throwFail` is + truthy, a JS exception is thrown. + + If an `errorFn` is specified in the config it must return `true` to indicate + that the exception was handled and keep it from being thrown. + + @method error + @param {String} msg Error message. + @param {Error|String} [e] JavaScript error object or an error string. + @param {String} [src] Source of the error (such as the name of the module in + which the error occurred). + @chainable + **/ + error: function(msg, e, src) { + //TODO Add check for window.onerror here + + var Y = this, ret; + + if (Y.config.errorFn) { + ret = Y.config.errorFn.apply(Y, arguments); + } + + if (!ret) { + throw (e || new Error(msg)); + } else { + Y.message(msg, 'error', ''+src); // don't scrub this one + } + + return Y; + }, + + /** + Generates an id string that is unique among all YUI instances in this + execution context. + + @method guid + @param {String} [pre] Prefix. + @return {String} Unique id. + **/ + guid: function(pre) { + var id = this.Env._guidp + '_' + (++this.Env._uidx); + return (pre) ? (pre + id) : id; + }, + + /** + Returns a unique id associated with the given object and (if *readOnly* is + falsy) stamps the object with that id so it can be identified in the future. + + Stamping an object involves adding a `_yuid` property to it that contains + the object's id. One exception to this is that in Internet Explorer, DOM + nodes have a `uniqueID` property that contains a browser-generated unique + id, which will be used instead of a YUI-generated id when available. + + @method stamp + @param {Object} o Object to stamp. + @param {Boolean} readOnly If truthy and the given object has not already + been stamped, the object will not be modified and `null` will be + returned. + @return {String} Object's unique id, or `null` if *readOnly* was truthy and + the given object was not already stamped. + **/ + stamp: function(o, readOnly) { + var uid; + if (!o) { + return o; + } + + // IE generates its own unique ID for dom nodes + // The uniqueID property of a document node returns a new ID + if (o.uniqueID && o.nodeType && o.nodeType !== 9) { + uid = o.uniqueID; + } else { + uid = (typeof o === 'string') ? o : o._yuid; + } + + if (!uid) { + uid = this.guid(); + if (!readOnly) { + try { + o._yuid = uid; + } catch (e) { + uid = null; + } + } + } + return uid; + }, + + /** + Destroys this YUI instance. + + @method destroy + @since 3.3.0 + **/ + destroy: function() { + var Y = this; + if (Y.Event) { + Y.Event._unload(); + } + delete instances[Y.id]; + delete Y.Env; + delete Y.config; + } + + /** + Safe `instanceof` wrapper that works around a memory leak in IE when the + object being tested is `window` or `document`. + + Unless you are testing objects that may be `window` or `document`, you + should use the native `instanceof` operator instead of this method. + + @method instanceOf + @param {Object} o Object to check. + @param {Object} type Class to check against. + @since 3.3.0 + **/ +}; + + YUI.prototype = proto; + + // inheritance utilities are not available yet + for (prop in proto) { + if (proto.hasOwnProperty(prop)) { + YUI[prop] = proto[prop]; + } + } + + /** + Applies a configuration to all YUI instances in this execution context. + + The main use case for this method is in "mashups" where several third-party + scripts need to write to a global YUI config, but cannot share a single + centrally-managed config object. This way they can all call + `YUI.applyConfig({})` instead of overwriting the single global config. + + @example + + YUI.applyConfig({ + modules: { + davglass: { + fullpath: './davglass.js' + } + } + }); + + YUI.applyConfig({ + modules: { + foo: { + fullpath: './foo.js' + } + } + }); + + YUI().use('davglass', function (Y) { + // Module davglass will be available here. + }); + + @method applyConfig + @param {Object} o Configuration object to apply. + @static + @since 3.5.0 + **/ + YUI.applyConfig = function(o) { + if (!o) { + return; + } + //If there is a GlobalConfig, apply it first to set the defaults + if (YUI.GlobalConfig) { + this.prototype.applyConfig.call(this, YUI.GlobalConfig); + } + //Apply this config to it + this.prototype.applyConfig.call(this, o); + //Reset GlobalConfig to the combined config + YUI.GlobalConfig = this.config; + }; + + // set up the environment + YUI._init(); + + if (hasWin) { + // add a window load event at load time so we can capture + // the case where it fires before dynamic loading is + // complete. + add(window, 'load', handleLoad); + } else { + handleLoad(); + } + + YUI.Env.add = add; + YUI.Env.remove = remove; + + /*global exports*/ + // Support the CommonJS method for exporting our single global + if (typeof exports == 'object') { + exports.YUI = YUI; + /** + * Set a method to be called when `Get.script` is called in Node.js + * `Get` will open the file, then pass it's content and it's path + * to this method before attaching it. Commonly used for code coverage + * instrumentation. Calling this multiple times will only + * attach the last hook method. This method is only + * available in Node.js. + * @method setLoadHook + * @static + * @param {Function} fn The function to set + * @param {String} fn.data The content of the file + * @param {String} fn.path The file path of the file + */ + YUI.setLoadHook = function(fn) { + YUI._getLoadHook = fn; + }; + /** + * Load hook for `Y.Get.script` in Node.js, see `YUI.setLoadHook` + * @method _getLoadHook + * @private + * @param {String} data The content of the file + * @param {String} path The file path of the file + */ + YUI._getLoadHook = null; + } + +}()); + + +/** +Config object that contains all of the configuration options for +this `YUI` instance. + +This object is supplied by the implementer when instantiating YUI. Some +properties have default values if they are not supplied by the implementer. + +This object should not be updated directly because some values are cached. Use +`applyConfig()` to update the config object on a YUI instance that has already +been configured. + +@class config +@static +**/ + +/** +If `true` (the default), YUI will "bootstrap" the YUI Loader and module metadata +if they're needed to load additional dependencies and aren't already available. + +Setting this to `false` will prevent YUI from automatically loading the Loader +and module metadata, so you will need to manually ensure that they're available +or handle dependency resolution yourself. + +@property {Boolean} bootstrap +@default true +**/ + +/** + +@property {Object} aliases +**/ + +/** +A hash of module group definitions. + +For each group you can specify a list of modules and the base path and +combo spec to use when dynamically loading the modules. + +@example + + groups: { + yui2: { + // specify whether or not this group has a combo service + combine: true, + + // The comboSeperator to use with this group's combo handler + comboSep: ';', + + // The maxURLLength for this server + maxURLLength: 500, + + // the base path for non-combo paths + base: 'http://yui.yahooapis.com/2.8.0r4/build/', + + // the path to the combo service + comboBase: 'http://yui.yahooapis.com/combo?', + + // a fragment to prepend to the path attribute when + // when building combo urls + root: '2.8.0r4/build/', + + // the module definitions + modules: { + yui2_yde: { + path: "yahoo-dom-event/yahoo-dom-event.js" + }, + yui2_anim: { + path: "animation/animation.js", + requires: ['yui2_yde'] + } + } + } + } + +@property {Object} groups +**/ + +/** +Path to the Loader JS file, relative to the `base` path. + +This is used to dynamically bootstrap the Loader when it's needed and isn't yet +available. + +@property {String} loaderPath +@default "loader/loader-min.js" +**/ + +/** +If `true`, YUI will attempt to load CSS dependencies and skins. Set this to +`false` to prevent YUI from loading any CSS, or set it to the string `"force"` +to force CSS dependencies to be loaded even if their associated JS modules are +already loaded. + +@property {Boolean|String} fetchCSS +@default true +**/ + +/** +Default gallery version used to build gallery module urls. + +@property {String} gallery +@since 3.1.0 +**/ + +/** +Default YUI 2 version used to build YUI 2 module urls. + +This is used for intrinsic YUI 2 support via the 2in3 project. Also see the +`2in3` config for pulling different revisions of the wrapped YUI 2 modules. + +@property {String} yui2 +@default "2.9.0" +@since 3.1.0 +**/ + +/** +Revision number of YUI 2in3 modules that should be used when loading YUI 2in3. + +@property {String} 2in3 +@default "4" +@since 3.1.0 +**/ + +/** +Alternate console log function that should be used in environments without a +supported native console. This function is executed with the YUI instance as its +`this` object. + +@property {Function} logFn +@since 3.1.0 +**/ + +/** +The minimum log level to log messages for. Log levels are defined +incrementally. Messages greater than or equal to the level specified will +be shown. All others will be discarded. The order of log levels in +increasing priority is: + + debug + info + warn + error + +@property {String} logLevel +@default 'debug' +@since 3.10.0 +**/ + +/** +Callback to execute when `Y.error()` is called. It receives the error message +and a JavaScript error object if one was provided. + +This function is executed with the YUI instance as its `this` object. + +Returning `true` from this function will prevent an exception from being thrown. + +@property {Function} errorFn +@param {String} errorFn.msg Error message +@param {Object} [errorFn.err] Error object (if one was provided). +@since 3.2.0 +**/ + +/** +A callback to execute when Loader fails to load one or more resources. + +This could be because of a script load failure. It could also be because a +module fails to register itself when the `requireRegistration` config is `true`. + +If this function is defined, the `use()` callback will only be called when the +loader succeeds. Otherwise, `use()` will always executes unless there was a +JavaScript error when attaching a module. + +@property {Function} loadErrorFn +@since 3.3.0 +**/ + +/** +If `true`, Loader will expect all loaded scripts to be first-class YUI modules +that register themselves with the YUI global, and will trigger a failure if a +loaded script does not register a YUI module. + +@property {Boolean} requireRegistration +@default false +@since 3.3.0 +**/ + +/** +Cache serviced use() requests. + +@property {Boolean} cacheUse +@default true +@since 3.3.0 +@deprecated No longer used. +**/ + +/** +Whether or not YUI should use native ES5 functionality when available for +features like `Y.Array.each()`, `Y.Object()`, etc. + +When `false`, YUI will always use its own fallback implementations instead of +relying on ES5 functionality, even when ES5 functionality is available. + +@property {Boolean} useNativeES5 +@default true +@since 3.5.0 +**/ + +/** + * Leverage native JSON stringify if the browser has a native + * implementation. In general, this is a good idea. See the Known Issues + * section in the JSON user guide for caveats. The default value is true + * for browsers with native JSON support. + * + * @property useNativeJSONStringify + * @type Boolean + * @default true + * @since 3.8.0 + */ + + /** + * Leverage native JSON parse if the browser has a native implementation. + * In general, this is a good idea. See the Known Issues section in the + * JSON user guide for caveats. The default value is true for browsers with + * native JSON support. + * + * @property useNativeJSONParse + * @type Boolean + * @default true + * @since 3.8.0 + */ + +/** +Delay the `use` callback until a specific event has passed (`load`, `domready`, `contentready` or `available`) + +@property {Object|String} delayUntil +@since 3.6.0 +@example + +You can use `load` or `domready` strings by default: + + YUI({ + delayUntil: 'domready' + }, function (Y) { + // This will not execute until 'domeready' occurs. + }); + +Or you can delay until a node is available (with `available` or `contentready`): + + YUI({ + delayUntil: { + event: 'available', + args : '#foo' + } + }, function (Y) { + // This will not execute until a node matching the selector "#foo" is + // available in the DOM. + }); + +**/ +YUI.add('yui-base', function (Y, NAME) { + +/* + * YUI stub + * @module yui + * @submodule yui-base + */ +/** + * The YUI module contains the components required for building the YUI + * seed file. This includes the script loading mechanism, a simple queue, + * and the core utilities for the library. + * @module yui + * @submodule yui-base + */ + +/** + * Provides core language utilites and extensions used throughout YUI. + * + * @class Lang + * @static + */ + +var L = Y.Lang || (Y.Lang = {}), + +STRING_PROTO = String.prototype, +TOSTRING = Object.prototype.toString, + +TYPES = { + 'undefined' : 'undefined', + 'number' : 'number', + 'boolean' : 'boolean', + 'string' : 'string', + '[object Function]': 'function', + '[object RegExp]' : 'regexp', + '[object Array]' : 'array', + '[object Date]' : 'date', + '[object Error]' : 'error' +}, + +SUBREGEX = /\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g, +TRIMREGEX = /^\s+|\s+$/g, +NATIVE_FN_REGEX = /\{\s*\[(?:native code|function)\]\s*\}/i; + +// -- Protected Methods -------------------------------------------------------- + +/** +Returns `true` if the given function appears to be implemented in native code, +`false` otherwise. Will always return `false` -- even in ES5-capable browsers -- +if the `useNativeES5` YUI config option is set to `false`. + +This isn't guaranteed to be 100% accurate and won't work for anything other than +functions, but it can be useful for determining whether a function like +`Array.prototype.forEach` is native or a JS shim provided by another library. + +There's a great article by @kangax discussing certain flaws with this technique: + + +While his points are valid, it's still possible to benefit from this function +as long as it's used carefully and sparingly, and in such a way that false +negatives have minimal consequences. It's used internally to avoid using +potentially broken non-native ES5 shims that have been added to the page by +other libraries. + +@method _isNative +@param {Function} fn Function to test. +@return {Boolean} `true` if _fn_ appears to be native, `false` otherwise. +@static +@protected +@since 3.5.0 +**/ +L._isNative = function (fn) { + return !!(Y.config.useNativeES5 && fn && NATIVE_FN_REGEX.test(fn)); +}; + +// -- Public Methods ----------------------------------------------------------- + +/** + * Determines whether or not the provided item is an array. + * + * Returns `false` for array-like collections such as the function `arguments` + * collection or `HTMLElement` collections. Use `Y.Array.test()` if you want to + * test for an array-like collection. + * + * @method isArray + * @param o The object to test. + * @return {boolean} true if o is an array. + * @static + */ +L.isArray = L._isNative(Array.isArray) ? Array.isArray : function (o) { + return L.type(o) === 'array'; +}; + +/** + * Determines whether or not the provided item is a boolean. + * @method isBoolean + * @static + * @param o The object to test. + * @return {boolean} true if o is a boolean. + */ +L.isBoolean = function(o) { + return typeof o === 'boolean'; +}; + +/** + * Determines whether or not the supplied item is a date instance. + * @method isDate + * @static + * @param o The object to test. + * @return {boolean} true if o is a date. + */ +L.isDate = function(o) { + return L.type(o) === 'date' && o.toString() !== 'Invalid Date' && !isNaN(o); +}; + +/** + *

+ * Determines whether or not the provided item is a function. + * Note: Internet Explorer thinks certain functions are objects: + *

+ * + *
+ * var obj = document.createElement("object");
+ * Y.Lang.isFunction(obj.getAttribute) // reports false in IE
+ *  
+ * var input = document.createElement("input"); // append to body
+ * Y.Lang.isFunction(input.focus) // reports false in IE
+ * 
+ * + *

+ * You will have to implement additional tests if these functions + * matter to you. + *

+ * + * @method isFunction + * @static + * @param o The object to test. + * @return {boolean} true if o is a function. + */ +L.isFunction = function(o) { + return L.type(o) === 'function'; +}; + +/** + * Determines whether or not the provided item is null. + * @method isNull + * @static + * @param o The object to test. + * @return {boolean} true if o is null. + */ +L.isNull = function(o) { + return o === null; +}; + +/** + * Determines whether or not the provided item is a legal number. + * @method isNumber + * @static + * @param o The object to test. + * @return {boolean} true if o is a number. + */ +L.isNumber = function(o) { + return typeof o === 'number' && isFinite(o); +}; + +/** + * Determines whether or not the provided item is of type object + * or function. Note that arrays are also objects, so + * Y.Lang.isObject([]) === true. + * @method isObject + * @static + * @param o The object to test. + * @param failfn {boolean} fail if the input is a function. + * @return {boolean} true if o is an object. + * @see isPlainObject + */ +L.isObject = function(o, failfn) { + var t = typeof o; + return (o && (t === 'object' || + (!failfn && (t === 'function' || L.isFunction(o))))) || false; +}; + +/** + * Determines whether or not the provided item is a string. + * @method isString + * @static + * @param o The object to test. + * @return {boolean} true if o is a string. + */ +L.isString = function(o) { + return typeof o === 'string'; +}; + +/** + * Determines whether or not the provided item is undefined. + * @method isUndefined + * @static + * @param o The object to test. + * @return {boolean} true if o is undefined. + */ +L.isUndefined = function(o) { + return typeof o === 'undefined'; +}; + +/** + * A convenience method for detecting a legitimate non-null value. + * Returns false for null/undefined/NaN, true for other values, + * including 0/false/'' + * @method isValue + * @static + * @param o The item to test. + * @return {boolean} true if it is not null/undefined/NaN || false. + */ +L.isValue = function(o) { + var t = L.type(o); + + switch (t) { + case 'number': + return isFinite(o); + + case 'null': // fallthru + case 'undefined': + return false; + + default: + return !!t; + } +}; + +/** + * Returns the current time in milliseconds. + * + * @method now + * @return {Number} Current time in milliseconds. + * @static + * @since 3.3.0 + */ +L.now = Date.now || function () { + return new Date().getTime(); +}; + +/** + * Lightweight version of Y.substitute. Uses the same template + * structure as Y.substitute, but doesn't support recursion, + * auto-object coersion, or formats. + * @method sub + * @param {string} s String to be modified. + * @param {object} o Object containing replacement values. + * @return {string} the substitute result. + * @static + * @since 3.2.0 + */ +L.sub = function(s, o) { + return s.replace ? s.replace(SUBREGEX, function (match, key) { + return L.isUndefined(o[key]) ? match : o[key]; + }) : s; +}; + +/** + * Returns a string without any leading or trailing whitespace. If + * the input is not a string, the input will be returned untouched. + * @method trim + * @static + * @param s {string} the string to trim. + * @return {string} the trimmed string. + */ +L.trim = STRING_PROTO.trim ? function(s) { + return s && s.trim ? s.trim() : s; +} : function (s) { + try { + return s.replace(TRIMREGEX, ''); + } catch (e) { + return s; + } +}; + +/** + * Returns a string without any leading whitespace. + * @method trimLeft + * @static + * @param s {string} the string to trim. + * @return {string} the trimmed string. + */ +L.trimLeft = STRING_PROTO.trimLeft ? function (s) { + return s.trimLeft(); +} : function (s) { + return s.replace(/^\s+/, ''); +}; + +/** + * Returns a string without any trailing whitespace. + * @method trimRight + * @static + * @param s {string} the string to trim. + * @return {string} the trimmed string. + */ +L.trimRight = STRING_PROTO.trimRight ? function (s) { + return s.trimRight(); +} : function (s) { + return s.replace(/\s+$/, ''); +}; + +/** +Returns one of the following strings, representing the type of the item passed +in: + + * "array" + * "boolean" + * "date" + * "error" + * "function" + * "null" + * "number" + * "object" + * "regexp" + * "string" + * "undefined" + +Known issues: + + * `typeof HTMLElementCollection` returns function in Safari, but + `Y.Lang.type()` reports "object", which could be a good thing -- + but it actually caused the logic in Y.Lang.isObject to fail. + +@method type +@param o the item to test. +@return {string} the detected type. +@static +**/ +L.type = function(o) { + return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null'); +}; +/** +@module yui +@submodule yui-base +*/ + +var Lang = Y.Lang, + Native = Array.prototype, + + hasOwn = Object.prototype.hasOwnProperty; + +/** +Provides utility methods for working with arrays. Additional array helpers can +be found in the `collection` and `array-extras` modules. + +`Y.Array(thing)` returns a native array created from _thing_. Depending on +_thing_'s type, one of the following will happen: + + * Arrays are returned unmodified unless a non-zero _startIndex_ is + specified. + * Array-like collections (see `Array.test()`) are converted to arrays. + * For everything else, a new array is created with _thing_ as the sole + item. + +Note: elements that are also collections, such as `
` and ``, to be array-like. + +@method test +@param {Object} obj Object to test. +@return {Number} A number indicating the results of the test: + + * 0: Neither an array nor an array-like collection. + * 1: Real array. + * 2: Array-like collection. + +@static +**/ +YArray.test = function (obj) { + var result = 0; + + if (Lang.isArray(obj)) { + result = 1; + } else if (Lang.isObject(obj)) { + try { + // indexed, but no tagName (element) or scrollTo/document (window. From DOM.isWindow test which we can't use here), + // or functions without apply/call (Safari + // HTMLElementCollection bug). + if ('length' in obj && !obj.tagName && !(obj.scrollTo && obj.document) && !obj.apply) { + result = 2; + } + } catch (ex) {} + } + + return result; +}; +/** + * The YUI module contains the components required for building the YUI + * seed file. This includes the script loading mechanism, a simple queue, + * and the core utilities for the library. + * @module yui + * @submodule yui-base + */ + +/** + * A simple FIFO queue. Items are added to the Queue with add(1..n items) and + * removed using next(). + * + * @class Queue + * @constructor + * @param {MIXED} item* 0..n items to seed the queue. + */ +function Queue() { + this._init(); + this.add.apply(this, arguments); +} + +Queue.prototype = { + /** + * Initialize the queue + * + * @method _init + * @protected + */ + _init: function() { + /** + * The collection of enqueued items + * + * @property _q + * @type Array + * @protected + */ + this._q = []; + }, + + /** + * Get the next item in the queue. FIFO support + * + * @method next + * @return {MIXED} the next item in the queue. + */ + next: function() { + return this._q.shift(); + }, + + /** + * Get the last in the queue. LIFO support. + * + * @method last + * @return {MIXED} the last item in the queue. + */ + last: function() { + return this._q.pop(); + }, + + /** + * Add 0..n items to the end of the queue. + * + * @method add + * @param {MIXED} item* 0..n items. + * @return {object} this queue. + */ + add: function() { + this._q.push.apply(this._q, arguments); + + return this; + }, + + /** + * Returns the current number of queued items. + * + * @method size + * @return {Number} The size. + */ + size: function() { + return this._q.length; + } +}; + +Y.Queue = Queue; + +YUI.Env._loaderQueue = YUI.Env._loaderQueue || new Queue(); + +/** +The YUI module contains the components required for building the YUI seed file. +This includes the script loading mechanism, a simple queue, and the core +utilities for the library. + +@module yui +@submodule yui-base +**/ + +var CACHED_DELIMITER = '__', + + hasOwn = Object.prototype.hasOwnProperty, + isObject = Y.Lang.isObject; + +/** +Returns a wrapper for a function which caches the return value of that function, +keyed off of the combined string representation of the argument values provided +when the wrapper is called. + +Calling this function again with the same arguments will return the cached value +rather than executing the wrapped function. + +Note that since the cache is keyed off of the string representation of arguments +passed to the wrapper function, arguments that aren't strings and don't provide +a meaningful `toString()` method may result in unexpected caching behavior. For +example, the objects `{}` and `{foo: 'bar'}` would both be converted to the +string `[object Object]` when used as a cache key. + +@method cached +@param {Function} source The function to memoize. +@param {Object} [cache={}] Object in which to store cached values. You may seed + this object with pre-existing cached values if desired. +@param {any} [refetch] If supplied, this value is compared with the cached value + using a `==` comparison. If the values are equal, the wrapped function is + executed again even though a cached value exists. +@return {Function} Wrapped function. +@for YUI +**/ +Y.cached = function (source, cache, refetch) { + /*jshint expr: true*/ + cache || (cache = {}); + + return function (arg) { + var key = arguments.length > 1 ? + Array.prototype.join.call(arguments, CACHED_DELIMITER) : + String(arg); + + /*jshint eqeqeq: false*/ + if (!(key in cache) || (refetch && cache[key] == refetch)) { + cache[key] = source.apply(source, arguments); + } + + return cache[key]; + }; +}; + +/** +Returns the `location` object from the window/frame in which this YUI instance +operates, or `undefined` when executing in a non-browser environment +(e.g. Node.js). + +It is _not_ recommended to hold references to the `window.location` object +outside of the scope of a function in which its properties are being accessed or +its methods are being called. This is because of a nasty bug/issue that exists +in both Safari and MobileSafari browsers: +[WebKit Bug 34679](https://bugs.webkit.org/show_bug.cgi?id=34679). + +@method getLocation +@return {location} The `location` object from the window/frame in which this YUI + instance operates. +@since 3.5.0 +**/ +Y.getLocation = function () { + // It is safer to look this up every time because yui-base is attached to a + // YUI instance before a user's config is applied; i.e. `Y.config.win` does + // not point the correct window object when this file is loaded. + var win = Y.config.win; + + // It is not safe to hold a reference to the `location` object outside the + // scope in which it is being used. The WebKit engine used in Safari and + // MobileSafari will "disconnect" the `location` object from the `window` + // when a page is restored from back/forward history cache. + return win && win.location; +}; + +/** +Returns a new object containing all of the properties of all the supplied +objects. The properties from later objects will overwrite those in earlier +objects. + +Passing in a single object will create a shallow copy of it. For a deep copy, +use `clone()`. + +@method merge +@param {Object} objects* One or more objects to merge. +@return {Object} A new merged object. +**/ +Y.merge = function () { + var i = 0, + len = arguments.length, + result = {}, + key, + obj; + + for (; i < len; ++i) { + obj = arguments[i]; + + for (key in obj) { + if (hasOwn.call(obj, key)) { + result[key] = obj[key]; + } + } + } + + return result; +}; + +/** +Mixes _supplier_'s properties into _receiver_. + +Properties on _receiver_ or _receiver_'s prototype will not be overwritten or +shadowed unless the _overwrite_ parameter is `true`, and will not be merged +unless the _merge_ parameter is `true`. + +In the default mode (0), only properties the supplier owns are copied (prototype +properties are not copied). The following copying modes are available: + + * `0`: _Default_. Object to object. + * `1`: Prototype to prototype. + * `2`: Prototype to prototype and object to object. + * `3`: Prototype to object. + * `4`: Object to prototype. + +@method mix +@param {Function|Object} receiver The object or function to receive the mixed + properties. +@param {Function|Object} supplier The object or function supplying the + properties to be mixed. +@param {Boolean} [overwrite=false] If `true`, properties that already exist + on the receiver will be overwritten with properties from the supplier. +@param {String[]} [whitelist] An array of property names to copy. If + specified, only the whitelisted properties will be copied, and all others + will be ignored. +@param {Number} [mode=0] Mix mode to use. See above for available modes. +@param {Boolean} [merge=false] If `true`, objects and arrays that already + exist on the receiver will have the corresponding object/array from the + supplier merged into them, rather than being skipped or overwritten. When + both _overwrite_ and _merge_ are `true`, _merge_ takes precedence. +@return {Function|Object|YUI} The receiver, or the YUI instance if the + specified receiver is falsy. +**/ +Y.mix = function(receiver, supplier, overwrite, whitelist, mode, merge) { + var alwaysOverwrite, exists, from, i, key, len, to; + + // If no supplier is given, we return the receiver. If no receiver is given, + // we return Y. Returning Y doesn't make much sense to me, but it's + // grandfathered in for backcompat reasons. + if (!receiver || !supplier) { + return receiver || Y; + } + + if (mode) { + // In mode 2 (prototype to prototype and object to object), we recurse + // once to do the proto to proto mix. The object to object mix will be + // handled later on. + if (mode === 2) { + Y.mix(receiver.prototype, supplier.prototype, overwrite, + whitelist, 0, merge); + } + + // Depending on which mode is specified, we may be copying from or to + // the prototypes of the supplier and receiver. + from = mode === 1 || mode === 3 ? supplier.prototype : supplier; + to = mode === 1 || mode === 4 ? receiver.prototype : receiver; + + // If either the supplier or receiver doesn't actually have a + // prototype property, then we could end up with an undefined `from` + // or `to`. If that happens, we abort and return the receiver. + if (!from || !to) { + return receiver; + } + } else { + from = supplier; + to = receiver; + } + + // If `overwrite` is truthy and `merge` is falsy, then we can skip a + // property existence check on each iteration and save some time. + alwaysOverwrite = overwrite && !merge; + + if (whitelist) { + for (i = 0, len = whitelist.length; i < len; ++i) { + key = whitelist[i]; + + // We call `Object.prototype.hasOwnProperty` instead of calling + // `hasOwnProperty` on the object itself, since the object's + // `hasOwnProperty` method may have been overridden or removed. + // Also, some native objects don't implement a `hasOwnProperty` + // method. + if (!hasOwn.call(from, key)) { + continue; + } + + // The `key in to` check here is (sadly) intentional for backwards + // compatibility reasons. It prevents undesired shadowing of + // prototype members on `to`. + exists = alwaysOverwrite ? false : key in to; + + if (merge && exists && isObject(to[key], true) + && isObject(from[key], true)) { + // If we're in merge mode, and the key is present on both + // objects, and the value on both objects is either an object or + // an array (but not a function), then we recurse to merge the + // `from` value into the `to` value instead of overwriting it. + // + // Note: It's intentional that the whitelist isn't passed to the + // recursive call here. This is legacy behavior that lots of + // code still depends on. + Y.mix(to[key], from[key], overwrite, null, 0, merge); + } else if (overwrite || !exists) { + // We're not in merge mode, so we'll only copy the `from` value + // to the `to` value if we're in overwrite mode or if the + // current key doesn't exist on the `to` object. + to[key] = from[key]; + } + } + } else { + for (key in from) { + // The code duplication here is for runtime performance reasons. + // Combining whitelist and non-whitelist operations into a single + // loop or breaking the shared logic out into a function both result + // in worse performance, and Y.mix is critical enough that the byte + // tradeoff is worth it. + if (!hasOwn.call(from, key)) { + continue; + } + + // The `key in to` check here is (sadly) intentional for backwards + // compatibility reasons. It prevents undesired shadowing of + // prototype members on `to`. + exists = alwaysOverwrite ? false : key in to; + + if (merge && exists && isObject(to[key], true) + && isObject(from[key], true)) { + Y.mix(to[key], from[key], overwrite, null, 0, merge); + } else if (overwrite || !exists) { + to[key] = from[key]; + } + } + + // If this is an IE browser with the JScript enumeration bug, force + // enumeration of the buggy properties by making a recursive call with + // the buggy properties as the whitelist. + if (Y.Object._hasEnumBug) { + Y.mix(to, from, overwrite, Y.Object._forceEnum, mode, merge); + } + } + + return receiver; +}; +/** + * The YUI module contains the components required for building the YUI + * seed file. This includes the script loading mechanism, a simple queue, + * and the core utilities for the library. + * @module yui + * @submodule yui-base + */ + +/** + * Adds utilities to the YUI instance for working with objects. + * + * @class Object + */ + +var Lang = Y.Lang, + hasOwn = Object.prototype.hasOwnProperty, + + UNDEFINED, // <-- Note the comma. We're still declaring vars. + +/** + * Returns a new object that uses _obj_ as its prototype. This method wraps the + * native ES5 `Object.create()` method if available, but doesn't currently + * pass through `Object.create()`'s second argument (properties) in order to + * ensure compatibility with older browsers. + * + * @method () + * @param {Object} obj Prototype object. + * @return {Object} New object using _obj_ as its prototype. + * @static + */ +O = Y.Object = Lang._isNative(Object.create) ? function (obj) { + // We currently wrap the native Object.create instead of simply aliasing it + // to ensure consistency with our fallback shim, which currently doesn't + // support Object.create()'s second argument (properties). Once we have a + // safe fallback for the properties arg, we can stop wrapping + // Object.create(). + return Object.create(obj); +} : (function () { + // Reusable constructor function for the Object.create() shim. + function F() {} + + // The actual shim. + return function (obj) { + F.prototype = obj; + return new F(); + }; +}()), + +/** + * Property names that IE doesn't enumerate in for..in loops, even when they + * should be enumerable. When `_hasEnumBug` is `true`, it's necessary to + * manually enumerate these properties. + * + * @property _forceEnum + * @type String[] + * @protected + * @static + */ +forceEnum = O._forceEnum = [ + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'toString', + 'toLocaleString', + 'valueOf' +], + +/** + * `true` if this browser has the JScript enumeration bug that prevents + * enumeration of the properties named in the `_forceEnum` array, `false` + * otherwise. + * + * See: + * - + * - + * + * @property _hasEnumBug + * @type Boolean + * @protected + * @static + */ +hasEnumBug = O._hasEnumBug = !{valueOf: 0}.propertyIsEnumerable('valueOf'), + +/** + * `true` if this browser incorrectly considers the `prototype` property of + * functions to be enumerable. Currently known to affect Opera 11.50. + * + * @property _hasProtoEnumBug + * @type Boolean + * @protected + * @static + */ +hasProtoEnumBug = O._hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'), + +/** + * Returns `true` if _key_ exists on _obj_, `false` if _key_ doesn't exist or + * exists only on _obj_'s prototype. This is essentially a safer version of + * `obj.hasOwnProperty()`. + * + * @method owns + * @param {Object} obj Object to test. + * @param {String} key Property name to look for. + * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise. + * @static + */ +owns = O.owns = function (obj, key) { + return !!obj && hasOwn.call(obj, key); +}; // <-- End of var declarations. + +/** + * Alias for `owns()`. + * + * @method hasKey + * @param {Object} obj Object to test. + * @param {String} key Property name to look for. + * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise. + * @static + */ +O.hasKey = owns; + +/** + * Returns an array containing the object's enumerable keys. Does not include + * prototype keys or non-enumerable keys. + * + * Note that keys are returned in enumeration order (that is, in the same order + * that they would be enumerated by a `for-in` loop), which may not be the same + * as the order in which they were defined. + * + * This method is an alias for the native ES5 `Object.keys()` method if + * available. + * + * @example + * + * Y.Object.keys({a: 'foo', b: 'bar', c: 'baz'}); + * // => ['a', 'b', 'c'] + * + * @method keys + * @param {Object} obj An object. + * @return {String[]} Array of keys. + * @static + */ +O.keys = Lang._isNative(Object.keys) ? Object.keys : function (obj) { + if (!Lang.isObject(obj)) { + throw new TypeError('Object.keys called on a non-object'); + } + + var keys = [], + i, key, len; + + if (hasProtoEnumBug && typeof obj === 'function') { + for (key in obj) { + if (owns(obj, key) && key !== 'prototype') { + keys.push(key); + } + } + } else { + for (key in obj) { + if (owns(obj, key)) { + keys.push(key); + } + } + } + + if (hasEnumBug) { + for (i = 0, len = forceEnum.length; i < len; ++i) { + key = forceEnum[i]; + + if (owns(obj, key)) { + keys.push(key); + } + } + } + + return keys; +}; + +/** + * Returns an array containing the values of the object's enumerable keys. + * + * Note that values are returned in enumeration order (that is, in the same + * order that they would be enumerated by a `for-in` loop), which may not be the + * same as the order in which they were defined. + * + * @example + * + * Y.Object.values({a: 'foo', b: 'bar', c: 'baz'}); + * // => ['foo', 'bar', 'baz'] + * + * @method values + * @param {Object} obj An object. + * @return {Array} Array of values. + * @static + */ +O.values = function (obj) { + var keys = O.keys(obj), + i = 0, + len = keys.length, + values = []; + + for (; i < len; ++i) { + values.push(obj[keys[i]]); + } + + return values; +}; + +/** + * Returns the number of enumerable keys owned by an object. + * + * @method size + * @param {Object} obj An object. + * @return {Number} The object's size. + * @static + */ +O.size = function (obj) { + try { + return O.keys(obj).length; + } catch (ex) { + return 0; // Legacy behavior for non-objects. + } +}; + +/** + * Returns `true` if the object owns an enumerable property with the specified + * value. + * + * @method hasValue + * @param {Object} obj An object. + * @param {any} value The value to search for. + * @return {Boolean} `true` if _obj_ contains _value_, `false` otherwise. + * @static + */ +O.hasValue = function (obj, value) { + return Y.Array.indexOf(O.values(obj), value) > -1; +}; + +/** + * Executes a function on each enumerable property in _obj_. The function + * receives the value, the key, and the object itself as parameters (in that + * order). + * + * By default, only properties owned by _obj_ are enumerated. To include + * prototype properties, set the _proto_ parameter to `true`. + * + * @method each + * @param {Object} obj Object to enumerate. + * @param {Function} fn Function to execute on each enumerable property. + * @param {mixed} fn.value Value of the current property. + * @param {String} fn.key Key of the current property. + * @param {Object} fn.obj Object being enumerated. + * @param {Object} [thisObj] `this` object to use when calling _fn_. + * @param {Boolean} [proto=false] Include prototype properties. + * @return {YUI} the YUI instance. + * @chainable + * @static + */ +O.each = function (obj, fn, thisObj, proto) { + var key; + + for (key in obj) { + if (proto || owns(obj, key)) { + fn.call(thisObj || Y, obj[key], key, obj); + } + } + + return Y; +}; + +/** + * Executes a function on each enumerable property in _obj_, but halts if the + * function returns a truthy value. The function receives the value, the key, + * and the object itself as paramters (in that order). + * + * By default, only properties owned by _obj_ are enumerated. To include + * prototype properties, set the _proto_ parameter to `true`. + * + * @method some + * @param {Object} obj Object to enumerate. + * @param {Function} fn Function to execute on each enumerable property. + * @param {mixed} fn.value Value of the current property. + * @param {String} fn.key Key of the current property. + * @param {Object} fn.obj Object being enumerated. + * @param {Object} [thisObj] `this` object to use when calling _fn_. + * @param {Boolean} [proto=false] Include prototype properties. + * @return {Boolean} `true` if any execution of _fn_ returns a truthy value, + * `false` otherwise. + * @static + */ +O.some = function (obj, fn, thisObj, proto) { + var key; + + for (key in obj) { + if (proto || owns(obj, key)) { + if (fn.call(thisObj || Y, obj[key], key, obj)) { + return true; + } + } + } + + return false; +}; + +/** + * Retrieves the sub value at the provided path, + * from the value object provided. + * + * @method getValue + * @static + * @param o The object from which to extract the property value. + * @param path {Array} A path array, specifying the object traversal path + * from which to obtain the sub value. + * @return {Any} The value stored in the path, undefined if not found, + * undefined if the source is not an object. Returns the source object + * if an empty path is provided. + */ +O.getValue = function(o, path) { + if (!Lang.isObject(o)) { + return UNDEFINED; + } + + var i, + p = Y.Array(path), + l = p.length; + + for (i = 0; o !== UNDEFINED && i < l; i++) { + o = o[p[i]]; + } + + return o; +}; + +/** + * Sets the sub-attribute value at the provided path on the + * value object. Returns the modified value object, or + * undefined if the path is invalid. + * + * @method setValue + * @static + * @param o The object on which to set the sub value. + * @param path {Array} A path array, specifying the object traversal path + * at which to set the sub value. + * @param val {Any} The new value for the sub-attribute. + * @return {Object} The modified object, with the new sub value set, or + * undefined, if the path was invalid. + */ +O.setValue = function(o, path, val) { + var i, + p = Y.Array(path), + leafIdx = p.length - 1, + ref = o; + + if (leafIdx >= 0) { + for (i = 0; ref !== UNDEFINED && i < leafIdx; i++) { + ref = ref[p[i]]; + } + + if (ref !== UNDEFINED) { + ref[p[i]] = val; + } else { + return UNDEFINED; + } + } + + return o; +}; + +/** + * Returns `true` if the object has no enumerable properties of its own. + * + * @method isEmpty + * @param {Object} obj An object. + * @return {Boolean} `true` if the object is empty. + * @static + * @since 3.2.0 + */ +O.isEmpty = function (obj) { + return !O.keys(Object(obj)).length; +}; +/** + * The YUI module contains the components required for building the YUI seed + * file. This includes the script loading mechanism, a simple queue, and the + * core utilities for the library. + * @module yui + * @submodule yui-base + */ + +/** + * YUI user agent detection. + * Do not fork for a browser if it can be avoided. Use feature detection when + * you can. Use the user agent as a last resort. For all fields listed + * as @type float, UA stores a version number for the browser engine, + * 0 otherwise. This value may or may not map to the version number of + * the browser using the engine. The value is presented as a float so + * that it can easily be used for boolean evaluation as well as for + * looking for a particular range of versions. Because of this, + * some of the granularity of the version info may be lost. The fields that + * are @type string default to null. The API docs list the values that + * these fields can have. + * @class UA + * @static + */ + +/** +* Static method on `YUI.Env` for parsing a UA string. Called at instantiation +* to populate `Y.UA`. +* +* @static +* @method parseUA +* @param {String} [subUA=navigator.userAgent] UA string to parse +* @return {Object} The Y.UA object +*/ +YUI.Env.parseUA = function(subUA) { + + var numberify = function(s) { + var c = 0; + return parseFloat(s.replace(/\./g, function() { + return (c++ === 1) ? '' : '.'; + })); + }, + + win = Y.config.win, + + nav = win && win.navigator, + + o = { + + /** + * Internet Explorer version number or 0. Example: 6 + * @property ie + * @type float + * @static + */ + ie: 0, + + /** + * Opera version number or 0. Example: 9.2 + * @property opera + * @type float + * @static + */ + opera: 0, + + /** + * Gecko engine revision number. Will evaluate to 1 if Gecko + * is detected but the revision could not be found. Other browsers + * will be 0. Example: 1.8 + *
+         * Firefox 1.0.0.4: 1.7.8   <-- Reports 1.7
+         * Firefox 1.5.0.9: 1.8.0.9 <-- 1.8
+         * Firefox 2.0.0.3: 1.8.1.3 <-- 1.81
+         * Firefox 3.0   <-- 1.9
+         * Firefox 3.5   <-- 1.91
+         * 
+ * @property gecko + * @type float + * @static + */ + gecko: 0, + + /** + * AppleWebKit version. KHTML browsers that are not WebKit browsers + * will evaluate to 1, other browsers 0. Example: 418.9 + *
+         * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the
+         *                                   latest available for Mac OSX 10.3.
+         * Safari 2.0.2:         416     <-- hasOwnProperty introduced
+         * Safari 2.0.4:         418     <-- preventDefault fixed
+         * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
+         *                                   different versions of webkit
+         * Safari 2.0.4 (419.3): 419     <-- Tiger installations that have been
+         *                                   updated, but not updated
+         *                                   to the latest patch.
+         * Webkit 212 nightly:   522+    <-- Safari 3.0 precursor (with native
+         * SVG and many major issues fixed).
+         * Safari 3.0.4 (523.12) 523.12  <-- First Tiger release - automatic
+         * update from 2.x via the 10.4.11 OS patch.
+         * Webkit nightly 1/2008:525+    <-- Supports DOMContentLoaded event.
+         *                                   yahoo.com user agent hack removed.
+         * 
+ * http://en.wikipedia.org/wiki/Safari_version_history + * @property webkit + * @type float + * @static + */ + webkit: 0, + + /** + * Safari will be detected as webkit, but this property will also + * be populated with the Safari version number + * @property safari + * @type float + * @static + */ + safari: 0, + + /** + * Chrome will be detected as webkit, but this property will also + * be populated with the Chrome version number + * @property chrome + * @type float + * @static + */ + chrome: 0, + + /** + * The mobile property will be set to a string containing any relevant + * user agent information when a modern mobile browser is detected. + * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series + * devices with the WebKit-based browser, and Opera Mini. + * @property mobile + * @type string + * @default null + * @static + */ + mobile: null, + + /** + * Adobe AIR version number or 0. Only populated if webkit is detected. + * Example: 1.0 + * @property air + * @type float + */ + air: 0, + /** + * PhantomJS version number or 0. Only populated if webkit is detected. + * Example: 1.0 + * @property phantomjs + * @type float + */ + phantomjs: 0, + /** + * Detects Apple iPad's OS version + * @property ipad + * @type float + * @static + */ + ipad: 0, + /** + * Detects Apple iPhone's OS version + * @property iphone + * @type float + * @static + */ + iphone: 0, + /** + * Detects Apples iPod's OS version + * @property ipod + * @type float + * @static + */ + ipod: 0, + /** + * General truthy check for iPad, iPhone or iPod + * @property ios + * @type Boolean + * @default null + * @static + */ + ios: null, + /** + * Detects Googles Android OS version + * @property android + * @type float + * @static + */ + android: 0, + /** + * Detects Kindle Silk + * @property silk + * @type float + * @static + */ + silk: 0, + /** + * Detects Kindle Silk Acceleration + * @property accel + * @type Boolean + * @static + */ + accel: false, + /** + * Detects Palms WebOS version + * @property webos + * @type float + * @static + */ + webos: 0, + + /** + * Google Caja version number or 0. + * @property caja + * @type float + */ + caja: nav && nav.cajaVersion, + + /** + * Set to true if the page appears to be in SSL + * @property secure + * @type boolean + * @static + */ + secure: false, + + /** + * The operating system. Currently only detecting windows or macintosh + * @property os + * @type string + * @default null + * @static + */ + os: null, + + /** + * The Nodejs Version + * @property nodejs + * @type float + * @default 0 + * @static + */ + nodejs: 0, + /** + * Window8/IE10 Application host environment + * @property winjs + * @type Boolean + * @static + */ + winjs: !!((typeof Windows !== "undefined") && Windows.System), + /** + * Are touch/msPointer events available on this device + * @property touchEnabled + * @type Boolean + * @static + */ + touchEnabled: false + }, + + ua = subUA || nav && nav.userAgent, + + loc = win && win.location, + + href = loc && loc.href, + + m; + + /** + * The User Agent string that was parsed + * @property userAgent + * @type String + * @static + */ + o.userAgent = ua; + + + o.secure = href && (href.toLowerCase().indexOf('https') === 0); + + if (ua) { + + if ((/windows|win32/i).test(ua)) { + o.os = 'windows'; + } else if ((/macintosh|mac_powerpc/i).test(ua)) { + o.os = 'macintosh'; + } else if ((/android/i).test(ua)) { + o.os = 'android'; + } else if ((/symbos/i).test(ua)) { + o.os = 'symbos'; + } else if ((/linux/i).test(ua)) { + o.os = 'linux'; + } else if ((/rhino/i).test(ua)) { + o.os = 'rhino'; + } + + // Modern KHTML browsers should qualify as Safari X-Grade + if ((/KHTML/).test(ua)) { + o.webkit = 1; + } + if ((/IEMobile|XBLWP7/).test(ua)) { + o.mobile = 'windows'; + } + if ((/Fennec/).test(ua)) { + o.mobile = 'gecko'; + } + // Modern WebKit browsers are at least X-Grade + m = ua.match(/AppleWebKit\/([^\s]*)/); + if (m && m[1]) { + o.webkit = numberify(m[1]); + o.safari = o.webkit; + + if (/PhantomJS/.test(ua)) { + m = ua.match(/PhantomJS\/([^\s]*)/); + if (m && m[1]) { + o.phantomjs = numberify(m[1]); + } + } + + // Mobile browser check + if (/ Mobile\//.test(ua) || (/iPad|iPod|iPhone/).test(ua)) { + o.mobile = 'Apple'; // iPhone or iPod Touch + + m = ua.match(/OS ([^\s]*)/); + if (m && m[1]) { + m = numberify(m[1].replace('_', '.')); + } + o.ios = m; + o.os = 'ios'; + o.ipad = o.ipod = o.iphone = 0; + + m = ua.match(/iPad|iPod|iPhone/); + if (m && m[0]) { + o[m[0].toLowerCase()] = o.ios; + } + } else { + m = ua.match(/NokiaN[^\/]*|webOS\/\d\.\d/); + if (m) { + // Nokia N-series, webOS, ex: NokiaN95 + o.mobile = m[0]; + } + if (/webOS/.test(ua)) { + o.mobile = 'WebOS'; + m = ua.match(/webOS\/([^\s]*);/); + if (m && m[1]) { + o.webos = numberify(m[1]); + } + } + if (/ Android/.test(ua)) { + if (/Mobile/.test(ua)) { + o.mobile = 'Android'; + } + m = ua.match(/Android ([^\s]*);/); + if (m && m[1]) { + o.android = numberify(m[1]); + } + + } + if (/Silk/.test(ua)) { + m = ua.match(/Silk\/([^\s]*)\)/); + if (m && m[1]) { + o.silk = numberify(m[1]); + } + if (!o.android) { + o.android = 2.34; //Hack for desktop mode in Kindle + o.os = 'Android'; + } + if (/Accelerated=true/.test(ua)) { + o.accel = true; + } + } + } + + m = ua.match(/(Chrome|CrMo|CriOS)\/([^\s]*)/); + if (m && m[1] && m[2]) { + o.chrome = numberify(m[2]); // Chrome + o.safari = 0; //Reset safari back to 0 + if (m[1] === 'CrMo') { + o.mobile = 'chrome'; + } + } else { + m = ua.match(/AdobeAIR\/([^\s]*)/); + if (m) { + o.air = m[0]; // Adobe AIR 1.0 or better + } + } + } + + if (!o.webkit) { // not webkit +// @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr) + if (/Opera/.test(ua)) { + m = ua.match(/Opera[\s\/]([^\s]*)/); + if (m && m[1]) { + o.opera = numberify(m[1]); + } + m = ua.match(/Version\/([^\s]*)/); + if (m && m[1]) { + o.opera = numberify(m[1]); // opera 10+ + } + + if (/Opera Mobi/.test(ua)) { + o.mobile = 'opera'; + m = ua.replace('Opera Mobi', '').match(/Opera ([^\s]*)/); + if (m && m[1]) { + o.opera = numberify(m[1]); + } + } + m = ua.match(/Opera Mini[^;]*/); + + if (m) { + o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316 + } + } else { // not opera or webkit + m = ua.match(/MSIE\s([^;]*)/); + if (m && m[1]) { + o.ie = numberify(m[1]); + } else { // not opera, webkit, or ie + m = ua.match(/Gecko\/([^\s]*)/); + if (m) { + o.gecko = 1; // Gecko detected, look for revision + m = ua.match(/rv:([^\s\)]*)/); + if (m && m[1]) { + o.gecko = numberify(m[1]); + if (/Mobile|Tablet/.test(ua)) { + o.mobile = "ffos"; + } + } + } + } + } + } + } + + //Check for known properties to tell if touch events are enabled on this device or if + //the number of MSPointer touchpoints on this device is greater than 0. + if (win && nav && !(o.chrome && o.chrome < 6)) { + o.touchEnabled = (("ontouchstart" in win) || (("msMaxTouchPoints" in nav) && (nav.msMaxTouchPoints > 0))); + } + + //It was a parsed UA, do not assign the global value. + if (!subUA) { + + if (typeof process === 'object') { + + if (process.versions && process.versions.node) { + //NodeJS + o.os = process.platform; + o.nodejs = numberify(process.versions.node); + } + } + + YUI.Env.UA = o; + + } + + return o; +}; + + +Y.UA = YUI.Env.UA || YUI.Env.parseUA(); + +/** +Performs a simple comparison between two version numbers, accounting for +standard versioning logic such as the fact that "535.8" is a lower version than +"535.24", even though a simple numerical comparison would indicate that it's +greater. Also accounts for cases such as "1.1" vs. "1.1.0", which are +considered equivalent. + +Returns -1 if version _a_ is lower than version _b_, 0 if they're equivalent, +1 if _a_ is higher than _b_. + +Versions may be numbers or strings containing numbers and dots. For example, +both `535` and `"535.8.10"` are acceptable. A version string containing +non-numeric characters, like `"535.8.beta"`, may produce unexpected results. + +@method compareVersions +@param {Number|String} a First version number to compare. +@param {Number|String} b Second version number to compare. +@return -1 if _a_ is lower than _b_, 0 if they're equivalent, 1 if _a_ is + higher than _b_. +**/ +Y.UA.compareVersions = function (a, b) { + var aPart, aParts, bPart, bParts, i, len; + + if (a === b) { + return 0; + } + + aParts = (a + '').split('.'); + bParts = (b + '').split('.'); + + for (i = 0, len = Math.max(aParts.length, bParts.length); i < len; ++i) { + aPart = parseInt(aParts[i], 10); + bPart = parseInt(bParts[i], 10); + + /*jshint expr: true*/ + isNaN(aPart) && (aPart = 0); + isNaN(bPart) && (bPart = 0); + + if (aPart < bPart) { + return -1; + } + + if (aPart > bPart) { + return 1; + } + } + + return 0; +}; +YUI.Env.aliases = { + "anim": ["anim-base","anim-color","anim-curve","anim-easing","anim-node-plugin","anim-scroll","anim-xy"], + "anim-shape-transform": ["anim-shape"], + "app": ["app-base","app-content","app-transitions","lazy-model-list","model","model-list","model-sync-rest","router","view","view-node-map"], + "attribute": ["attribute-base","attribute-complex"], + "attribute-events": ["attribute-observable"], + "autocomplete": ["autocomplete-base","autocomplete-sources","autocomplete-list","autocomplete-plugin"], + "axes": ["axis-numeric","axis-category","axis-time","axis-stacked"], + "axes-base": ["axis-numeric-base","axis-category-base","axis-time-base","axis-stacked-base"], + "base": ["base-base","base-pluginhost","base-build"], + "cache": ["cache-base","cache-offline","cache-plugin"], + "charts": ["charts-base"], + "collection": ["array-extras","arraylist","arraylist-add","arraylist-filter","array-invoke"], + "color": ["color-base","color-hsl","color-harmony"], + "controller": ["router"], + "dataschema": ["dataschema-base","dataschema-json","dataschema-xml","dataschema-array","dataschema-text"], + "datasource": ["datasource-local","datasource-io","datasource-get","datasource-function","datasource-cache","datasource-jsonschema","datasource-xmlschema","datasource-arrayschema","datasource-textschema","datasource-polling"], + "datatable": ["datatable-core","datatable-table","datatable-head","datatable-body","datatable-base","datatable-column-widths","datatable-message","datatable-mutable","datatable-sort","datatable-datasource"], + "datatype": ["datatype-date","datatype-number","datatype-xml"], + "datatype-date": ["datatype-date-parse","datatype-date-format","datatype-date-math"], + "datatype-number": ["datatype-number-parse","datatype-number-format"], + "datatype-xml": ["datatype-xml-parse","datatype-xml-format"], + "dd": ["dd-ddm-base","dd-ddm","dd-ddm-drop","dd-drag","dd-proxy","dd-constrain","dd-drop","dd-scroll","dd-delegate"], + "dom": ["dom-base","dom-screen","dom-style","selector-native","selector"], + "editor": ["frame","editor-selection","exec-command","editor-base","editor-para","editor-br","editor-bidi","editor-tab","createlink-base"], + "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"], + "event-custom": ["event-custom-base","event-custom-complex"], + "event-gestures": ["event-flick","event-move"], + "handlebars": ["handlebars-compiler"], + "highlight": ["highlight-base","highlight-accentfold"], + "history": ["history-base","history-hash","history-hash-ie","history-html5"], + "io": ["io-base","io-xdr","io-form","io-upload-iframe","io-queue"], + "json": ["json-parse","json-stringify"], + "loader": ["loader-base","loader-rollup","loader-yui3"], + "node": ["node-base","node-event-delegate","node-pluginhost","node-screen","node-style"], + "pluginhost": ["pluginhost-base","pluginhost-config"], + "querystring": ["querystring-parse","querystring-stringify"], + "recordset": ["recordset-base","recordset-sort","recordset-filter","recordset-indexer"], + "resize": ["resize-base","resize-proxy","resize-constrain"], + "slider": ["slider-base","slider-value-range","clickable-rail","range-slider"], + "template": ["template-base","template-micro"], + "text": ["text-accentfold","text-wordbreak"], + "widget": ["widget-base","widget-htmlparser","widget-skin","widget-uievents"] +}; + + +}, '3.10.3', { + "use": [ + "yui-base", + "get", + "features", + "intl-base", + "yui-log", + "yui-log-nodejs", + "yui-later", + "loader-base", + "loader-rollup", + "loader-yui3" + ] +}); +YUI.add('get', function (Y, NAME) { + + /** + * NodeJS specific Get module used to load remote resources. + * It contains the same signature as the default Get module so there is no code change needed. + * @module get-nodejs + * @class GetNodeJS + */ + + var Module = require('module'), + + path = require('path'), + fs = require('fs'), + request = require('request'), + end = function(cb, msg, result) { + if (Y.Lang.isFunction(cb.onEnd)) { + cb.onEnd.call(Y, msg, result); + } + }, pass = function(cb) { + if (Y.Lang.isFunction(cb.onSuccess)) { + cb.onSuccess.call(Y, cb); + } + end(cb, 'success', 'success'); + }, fail = function(cb, er) { + er.errors = [er]; + if (Y.Lang.isFunction(cb.onFailure)) { + cb.onFailure.call(Y, er, cb); + } + end(cb, er, 'fail'); + }; + + + Y.Get = function() { + }; + + //Setup the default config base path + Y.config.base = path.join(__dirname, '../'); + + YUI.require = require; + YUI.process = process; + + /** + * Takes the raw JS files and wraps them to be executed in the YUI context so they can be loaded + * into the YUI object + * @method _exec + * @private + * @param {String} data The JS to execute + * @param {String} url The path to the file that was parsed + * @param {Callback} cb The callback to execute when this is completed + * @param {Error} cb.err=null Error object + * @param {String} cb.url The URL that was just parsed + */ + + Y.Get._exec = function(data, url, cb) { + if (data.charCodeAt(0) === 0xFEFF) { + data = data.slice(1); + } + + var mod = new Module(url, module); + mod.filename = url; + mod.paths = Module._nodeModulePaths(path.dirname(url)); + if (typeof YUI._getLoadHook === 'function') { + data = YUI._getLoadHook(data, url); + } + mod._compile('module.exports = function (YUI) {' + data + '\n;return YUI;};', url); + + /*global YUI:true */ + YUI = mod.exports(YUI); + + mod.loaded = true; + + cb(null, url); + }; + + /** + * Fetches the content from a remote URL or a file from disc and passes the content + * off to `_exec` for parsing + * @method _include + * @private + * @param {String} url The URL/File path to fetch the content from + * @param {Callback} cb The callback to fire once the content has been executed via `_exec` + */ + Y.Get._include = function (url, cb) { + var cfg, + mod, + self = this; + + if (url.match(/^https?:\/\//)) { + cfg = { + url: url, + timeout: self.timeout + }; + request(cfg, function (err, response, body) { + if (err) { + cb(err, url); + } else { + Y.Get._exec(body, url, cb); + } + }); + } else { + try { + // Try to resolve paths relative to the module that required yui. + url = Module._findPath(url, Module._resolveLookupPaths(url, module.parent.parent)[1]); + + if (Y.config.useSync) { + //Needs to be in useSync + mod = fs.readFileSync(url,'utf8'); + } else { + fs.readFile(url, 'utf8', function (err, mod) { + if (err) { + cb(err, url); + } else { + Y.Get._exec(mod, url, cb); + } + }); + return; + } + } catch (err) { + cb(err, url); + return; + } + + Y.Get._exec(mod, url, cb); + } + }; + + + /** + * Override for Get.script for loading local or remote YUI modules. + * @method js + * @param {Array|String} s The URL's to load into this context + * @param {Object} options Transaction options + */ + Y.Get.js = function(s, options) { + var urls = Y.Array(s), url, i, l = urls.length, c= 0, + check = function() { + if (c === l) { + pass(options); + } + }; + + + /*jshint loopfunc: true */ + for (i=0; i 0) { + result = scan(language); + if (result) { + return result; + } else { + index = language.lastIndexOf('-'); + if (index >= 0) { + language = language.substring(0, index); + // one-character subtags get cut along with the + // following subtag + if (index >= 2 && language.charAt(index - 2) === '-') { + language = language.substring(0, index - 2); + } + } else { + // nothing available for this language + break; + } + } + } + } + + return ''; + } +}); + + +}, '3.10.3', {"requires": ["yui-base"]}); +YUI.add('yui-log', function (Y, NAME) { + +/** + * Provides console log capability and exposes a custom event for + * console implementations. This module is a `core` YUI module, + * it's documentation is located under the YUI class. + * + * @module yui + * @submodule yui-log + */ + +var INSTANCE = Y, + LOGEVENT = 'yui:log', + UNDEFINED = 'undefined', + LEVELS = { debug: 1, + info: 2, + warn: 4, + error: 8 }; + +/** + * If the 'debug' config is true, a 'yui:log' event will be + * dispatched, which the Console widget and anything else + * can consume. If the 'useBrowserConsole' config is true, it will + * write to the browser console if available. YUI-specific log + * messages will only be present in the -debug versions of the + * JS files. The build system is supposed to remove log statements + * from the raw and minified versions of the files. + * + * @method log + * @for YUI + * @param {String} msg The message to log. + * @param {String} cat The log category for the message. Default + * categories are "info", "warn", "error", time". + * Custom categories can be used as well. (opt). + * @param {String} src The source of the the message (opt). + * @param {boolean} silent If true, the log event won't fire. + * @return {YUI} YUI instance. + */ +INSTANCE.log = function(msg, cat, src, silent) { + var bail, excl, incl, m, f, minlevel, + Y = INSTANCE, + c = Y.config, + publisher = (Y.fire) ? Y : YUI.Env.globalEvents; + // suppress log message if the config is off or the event stack + // or the event call stack contains a consumer of the yui:log event + if (c.debug) { + // apply source filters + src = src || ""; + if (typeof src !== "undefined") { + excl = c.logExclude; + incl = c.logInclude; + if (incl && !(src in incl)) { + bail = 1; + } else if (incl && (src in incl)) { + bail = !incl[src]; + } else if (excl && (src in excl)) { + bail = excl[src]; + } + + // Determine the current minlevel as defined in configuration + Y.config.logLevel = Y.config.logLevel || 'debug'; + minlevel = LEVELS[Y.config.logLevel.toLowerCase()]; + + if (cat in LEVELS && LEVELS[cat] < minlevel) { + // Skip this message if the we don't meet the defined minlevel + bail = 1; + } + } + if (!bail) { + if (c.useBrowserConsole) { + m = (src) ? src + ': ' + msg : msg; + if (Y.Lang.isFunction(c.logFn)) { + c.logFn.call(Y, msg, cat, src); + } else if (typeof console !== UNDEFINED && console.log) { + f = (cat && console[cat] && (cat in LEVELS)) ? cat : 'log'; + console[f](m); + } else if (typeof opera !== UNDEFINED) { + opera.postError(m); + } + } + + if (publisher && !silent) { + + if (publisher === Y && (!publisher.getEvent(LOGEVENT))) { + publisher.publish(LOGEVENT, { + broadcast: 2 + }); + } + + publisher.fire(LOGEVENT, { + msg: msg, + cat: cat, + src: src + }); + } + } + } + + return Y; +}; + +/** + * Write a system message. This message will be preserved in the + * minified and raw versions of the YUI files, unlike log statements. + * @method message + * @for YUI + * @param {String} msg The message to log. + * @param {String} cat The log category for the message. Default + * categories are "info", "warn", "error", time". + * Custom categories can be used as well. (opt). + * @param {String} src The source of the the message (opt). + * @param {boolean} silent If true, the log event won't fire. + * @return {YUI} YUI instance. + */ +INSTANCE.message = function() { + return INSTANCE.log.apply(INSTANCE, arguments); +}; + + +}, '3.10.3', {"requires": ["yui-base"]}); +YUI.add('yui-log-nodejs', function (Y, NAME) { + +var sys = require(process.binding('natives').util ? 'util' : 'sys'), + hasColor = false; + +try { + var stdio = require("stdio"); + hasColor = stdio.isStderrATTY(); +} catch (ex) { + hasColor = true; +} + +Y.config.useColor = hasColor; + +Y.consoleColor = function(str, num) { + if (!this.config.useColor) { + return str; + } + if (!num) { + num = '32'; + } + return "\u001b[" + num +"m" + str + "\u001b[0m"; +}; + + +var logFn = function(str, t, m) { + var id = '', lvl, mLvl; + if (this.id) { + id = '[' + this.id + ']:'; + } + t = t || 'info'; + m = (m) ? this.consoleColor(' (' + m.toLowerCase() + '):', 35) : ''; + + if (str === null) { + str = 'null'; + } + + if ((typeof str === 'object') || str instanceof Array) { + try { + //Should we use this? + if (str.tagName || str._yuid || str._query) { + str = str.toString(); + } else { + str = sys.inspect(str); + } + } catch (e) { + //Fail catcher + } + } + + lvl = '37;40'; + mLvl = ((str) ? '' : 31); + t = t+''; //Force to a string.. + switch (t.toLowerCase()) { + case 'error': + lvl = mLvl = 31; + break; + case 'warn': + lvl = 33; + break; + case 'debug': + lvl = 34; + break; + } + if (typeof str === 'string') { + if (str && str.indexOf("\n") !== -1) { + str = "\n" + str; + } + } + + // output log messages to stderr + sys.error(this.consoleColor(t.toLowerCase() + ':', lvl) + m + ' ' + this.consoleColor(str, mLvl)); +}; + +if (!Y.config.logFn) { + Y.config.logFn = logFn; +} + + + +}, '3.10.3'); +YUI.add('yui-later', function (Y, NAME) { + +/** + * Provides a setTimeout/setInterval wrapper. This module is a `core` YUI module, + * it's documentation is located under the YUI class. + * + * @module yui + * @submodule yui-later + */ + +var NO_ARGS = []; + +/** + * Executes the supplied function in the context of the supplied + * object 'when' milliseconds later. Executes the function a + * single time unless periodic is set to true. + * @for YUI + * @method later + * @param when {int} the number of milliseconds to wait until the fn + * is executed. + * @param o the context object. + * @param fn {Function|String} the function to execute or the name of + * the method in the 'o' object to execute. + * @param data [Array] data that is provided to the function. This + * accepts either a single item or an array. If an array is provided, + * the function is executed with one parameter for each array item. + * If you need to pass a single array parameter, it needs to be wrapped + * in an array [myarray]. + * + * Note: native methods in IE may not have the call and apply methods. + * In this case, it will work, but you are limited to four arguments. + * + * @param periodic {boolean} if true, executes continuously at supplied + * interval until canceled. + * @return {object} a timer object. Call the cancel() method on this + * object to stop the timer. + */ +Y.later = function(when, o, fn, data, periodic) { + when = when || 0; + data = (!Y.Lang.isUndefined(data)) ? Y.Array(data) : NO_ARGS; + o = o || Y.config.win || Y; + + var cancelled = false, + method = (o && Y.Lang.isString(fn)) ? o[fn] : fn, + wrapper = function() { + // IE 8- may execute a setInterval callback one last time + // after clearInterval was called, so in order to preserve + // the cancel() === no more runny-run, we have to jump through + // an extra hoop. + if (!cancelled) { + if (!method.apply) { + method(data[0], data[1], data[2], data[3]); + } else { + method.apply(o, data || NO_ARGS); + } + } + }, + id = (periodic) ? setInterval(wrapper, when) : setTimeout(wrapper, when); + + return { + id: id, + interval: periodic, + cancel: function() { + cancelled = true; + if (this.interval) { + clearInterval(id); + } else { + clearTimeout(id); + } + } + }; +}; + +Y.Lang.later = Y.later; + + + +}, '3.10.3', {"requires": ["yui-base"]}); +YUI.add('loader-base', function (Y, NAME) { + +/** + * The YUI loader core + * @module loader + * @submodule loader-base + */ + +if (!YUI.Env[Y.version]) { + + (function() { + var VERSION = Y.version, + BUILD = '/build/', + ROOT = VERSION + '/', + CDN_BASE = Y.Env.base, + GALLERY_VERSION = 'gallery-2013.06.05-22-14', + TNT = '2in3', + TNT_VERSION = '4', + YUI2_VERSION = '2.9.0', + COMBO_BASE = CDN_BASE + 'combo?', + META = { version: VERSION, + root: ROOT, + base: Y.Env.base, + comboBase: COMBO_BASE, + skin: { defaultSkin: 'sam', + base: 'assets/skins/', + path: 'skin.css', + after: ['cssreset', + 'cssfonts', + 'cssgrids', + 'cssbase', + 'cssreset-context', + 'cssfonts-context']}, + groups: {}, + patterns: {} }, + groups = META.groups, + yui2Update = function(tnt, yui2, config) { + + var root = TNT + '.' + + (tnt || TNT_VERSION) + '/' + + (yui2 || YUI2_VERSION) + BUILD, + base = (config && config.base) ? config.base : CDN_BASE, + combo = (config && config.comboBase) ? config.comboBase : COMBO_BASE; + + groups.yui2.base = base + root; + groups.yui2.root = root; + groups.yui2.comboBase = combo; + }, + galleryUpdate = function(tag, config) { + var root = (tag || GALLERY_VERSION) + BUILD, + base = (config && config.base) ? config.base : CDN_BASE, + combo = (config && config.comboBase) ? config.comboBase : COMBO_BASE; + + groups.gallery.base = base + root; + groups.gallery.root = root; + groups.gallery.comboBase = combo; + }; + + + groups[VERSION] = {}; + + groups.gallery = { + ext: false, + combine: true, + comboBase: COMBO_BASE, + update: galleryUpdate, + patterns: { 'gallery-': { }, + 'lang/gallery-': {}, + 'gallerycss-': { type: 'css' } } + }; + + groups.yui2 = { + combine: true, + ext: false, + comboBase: COMBO_BASE, + update: yui2Update, + patterns: { + 'yui2-': { + configFn: function(me) { + if (/-skin|reset|fonts|grids|base/.test(me.name)) { + me.type = 'css'; + me.path = me.path.replace(/\.js/, '.css'); + // this makes skins in builds earlier than + // 2.6.0 work as long as combine is false + me.path = me.path.replace(/\/yui2-skin/, + '/assets/skins/sam/yui2-skin'); + } + } + } + } + }; + + galleryUpdate(); + yui2Update(); + + YUI.Env[VERSION] = META; + }()); +} + + +/*jslint forin: true, maxlen: 350 */ + +/** + * Loader dynamically loads script and css files. It includes the dependency + * information for the version of the library in use, and will automatically pull in + * dependencies for the modules requested. It can also load the + * files from the Yahoo! CDN, and it can utilize the combo service provided on + * this network to reduce the number of http connections required to download + * YUI files. + * + * @module loader + * @main loader + * @submodule loader-base + */ + +var NOT_FOUND = {}, + NO_REQUIREMENTS = [], + MAX_URL_LENGTH = 1024, + GLOBAL_ENV = YUI.Env, + GLOBAL_LOADED = GLOBAL_ENV._loaded, + CSS = 'css', + JS = 'js', + INTL = 'intl', + DEFAULT_SKIN = 'sam', + VERSION = Y.version, + ROOT_LANG = '', + YObject = Y.Object, + oeach = YObject.each, + yArray = Y.Array, + _queue = GLOBAL_ENV._loaderQueue, + META = GLOBAL_ENV[VERSION], + SKIN_PREFIX = 'skin-', + L = Y.Lang, + ON_PAGE = GLOBAL_ENV.mods, + modulekey, + _path = function(dir, file, type, nomin) { + var path = dir + '/' + file; + if (!nomin) { + path += '-min'; + } + path += '.' + (type || CSS); + + return path; + }; + + + if (!YUI.Env._cssLoaded) { + YUI.Env._cssLoaded = {}; + } + + +/** + * The component metadata is stored in Y.Env.meta. + * Part of the loader module. + * @property meta + * @for YUI + */ +Y.Env.meta = META; + +/** + * Loader dynamically loads script and css files. It includes the dependency + * info for the version of the library in use, and will automatically pull in + * dependencies for the modules requested. It can load the + * files from the Yahoo! CDN, and it can utilize the combo service provided on + * this network to reduce the number of http connections required to download + * YUI files. You can also specify an external, custom combo service to host + * your modules as well. + + var Y = YUI(); + var loader = new Y.Loader({ + filter: 'debug', + base: '../../', + root: 'build/', + combine: true, + require: ['node', 'dd', 'console'] + }); + var out = loader.resolve(true); + + * @constructor + * @class Loader + * @param {Object} config an optional set of configuration options. + * @param {String} config.base The base dir which to fetch this module from + * @param {String} config.comboBase The Combo service base path. Ex: `http://yui.yahooapis.com/combo?` + * @param {String} config.root The root path to prepend to module names for the combo service. Ex: `2.5.2/build/` + * @param {String|Object} config.filter A filter to apply to result urls. See filter property + * @param {Object} config.filters Per-component filter specification. If specified for a given component, this overrides the filter config. + * @param {Boolean} config.combine Use a combo service to reduce the number of http connections required to load your dependencies + * @param {Boolean} [config.async=true] Fetch files in async + * @param {Array} config.ignore: A list of modules that should never be dynamically loaded + * @param {Array} config.force A list of modules that should always be loaded when required, even if already present on the page + * @param {HTMLElement|String} config.insertBefore Node or id for a node that should be used as the insertion point for new nodes + * @param {Object} config.jsAttributes Object literal containing attributes to add to script nodes + * @param {Object} config.cssAttributes Object literal containing attributes to add to link nodes + * @param {Number} config.timeout The number of milliseconds before a timeout occurs when dynamically loading nodes. If not set, there is no timeout + * @param {Object} config.context Execution context for all callbacks + * @param {Function} config.onSuccess Callback for the 'success' event + * @param {Function} config.onFailure Callback for the 'failure' event + * @param {Function} config.onCSS Callback for the 'CSSComplete' event. When loading YUI components with CSS the CSS is loaded first, then the script. This provides a moment you can tie into to improve the presentation of the page while the script is loading. + * @param {Function} config.onTimeout Callback for the 'timeout' event + * @param {Function} config.onProgress Callback executed each time a script or css file is loaded + * @param {Object} config.modules A list of module definitions. See Loader.addModule for the supported module metadata + * @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`. + * @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. + * @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. + */ +Y.Loader = function(o) { + + var self = this; + + //Catch no config passed. + o = o || {}; + + modulekey = META.md5; + + /** + * Internal callback to handle multiple internal insert() calls + * so that css is inserted prior to js + * @property _internalCallback + * @private + */ + // self._internalCallback = null; + + /** + * Callback that will be executed when the loader is finished + * with an insert + * @method onSuccess + * @type function + */ + // self.onSuccess = null; + + /** + * Callback that will be executed if there is a failure + * @method onFailure + * @type function + */ + // self.onFailure = null; + + /** + * Callback for the 'CSSComplete' event. When loading YUI components + * with CSS the CSS is loaded first, then the script. This provides + * a moment you can tie into to improve the presentation of the page + * while the script is loading. + * @method onCSS + * @type function + */ + // self.onCSS = null; + + /** + * Callback executed each time a script or css file is loaded + * @method onProgress + * @type function + */ + // self.onProgress = null; + + /** + * Callback that will be executed if a timeout occurs + * @method onTimeout + * @type function + */ + // self.onTimeout = null; + + /** + * The execution context for all callbacks + * @property context + * @default {YUI} the YUI instance + */ + self.context = Y; + + /** + * Data that is passed to all callbacks + * @property data + */ + // self.data = null; + + /** + * Node reference or id where new nodes should be inserted before + * @property insertBefore + * @type string|HTMLElement + */ + // self.insertBefore = null; + + /** + * The charset attribute for inserted nodes + * @property charset + * @type string + * @deprecated , use cssAttributes or jsAttributes. + */ + // self.charset = null; + + /** + * An object literal containing attributes to add to link nodes + * @property cssAttributes + * @type object + */ + // self.cssAttributes = null; + + /** + * An object literal containing attributes to add to script nodes + * @property jsAttributes + * @type object + */ + // self.jsAttributes = null; + + /** + * The base directory. + * @property base + * @type string + * @default http://yui.yahooapis.com/[YUI VERSION]/build/ + */ + self.base = Y.Env.meta.base + Y.Env.meta.root; + + /** + * Base path for the combo service + * @property comboBase + * @type string + * @default http://yui.yahooapis.com/combo? + */ + self.comboBase = Y.Env.meta.comboBase; + + /* + * Base path for language packs. + */ + // self.langBase = Y.Env.meta.langBase; + // self.lang = ""; + + /** + * If configured, the loader will attempt to use the combo + * service for YUI resources and configured external resources. + * @property combine + * @type boolean + * @default true if a base dir isn't in the config + */ + self.combine = o.base && + (o.base.indexOf(self.comboBase.substr(0, 20)) > -1); + + /** + * The default seperator to use between files in a combo URL + * @property comboSep + * @type {String} + * @default Ampersand + */ + self.comboSep = '&'; + /** + * Max url length for combo urls. The default is 1024. This is the URL + * limit for the Yahoo! hosted combo servers. If consuming + * a different combo service that has a different URL limit + * it is possible to override this default by supplying + * the maxURLLength config option. The config option will + * only take effect if lower than the default. + * + * @property maxURLLength + * @type int + */ + self.maxURLLength = MAX_URL_LENGTH; + + /** + * Ignore modules registered on the YUI global + * @property ignoreRegistered + * @default false + */ + self.ignoreRegistered = o.ignoreRegistered; + + /** + * Root path to prepend to module path for the combo + * service + * @property root + * @type string + * @default [YUI VERSION]/build/ + */ + self.root = Y.Env.meta.root; + + /** + * Timeout value in milliseconds. If set, self value will be used by + * the get utility. the timeout event will fire if + * a timeout occurs. + * @property timeout + * @type int + */ + self.timeout = 0; + + /** + * A list of modules that should not be loaded, even if + * they turn up in the dependency tree + * @property ignore + * @type string[] + */ + // self.ignore = null; + + /** + * A list of modules that should always be loaded, even + * if they have already been inserted into the page. + * @property force + * @type string[] + */ + // self.force = null; + + self.forceMap = {}; + + /** + * Should we allow rollups + * @property allowRollup + * @type boolean + * @default false + */ + self.allowRollup = false; + + /** + * A filter to apply to result urls. This filter will modify the default + * path for all modules. The default path for the YUI library is the + * minified version of the files (e.g., event-min.js). The filter property + * can be a predefined filter or a custom filter. The valid predefined + * filters are: + *
+ *
DEBUG
+ *
Selects the debug versions of the library (e.g., event-debug.js). + * This option will automatically include the Logger widget
+ *
RAW
+ *
Selects the non-minified version of the library (e.g., event.js). + *
+ *
+ * You can also define a custom filter, which must be an object literal + * containing a search expression and a replace string: + * + * myFilter: { + * 'searchExp': "-min\\.js", + * 'replaceStr': "-debug.js" + * } + * + * @property filter + * @type string| {searchExp: string, replaceStr: string} + */ + // self.filter = null; + + /** + * per-component filter specification. If specified for a given + * component, this overrides the filter config. + * @property filters + * @type object + */ + self.filters = {}; + + /** + * The list of requested modules + * @property required + * @type {string: boolean} + */ + self.required = {}; + + /** + * If a module name is predefined when requested, it is checked againsts + * the patterns provided in this property. If there is a match, the + * module is added with the default configuration. + * + * At the moment only supporting module prefixes, but anticipate + * supporting at least regular expressions. + * @property patterns + * @type Object + */ + // self.patterns = Y.merge(Y.Env.meta.patterns); + self.patterns = {}; + + /** + * The library metadata + * @property moduleInfo + */ + // self.moduleInfo = Y.merge(Y.Env.meta.moduleInfo); + self.moduleInfo = {}; + + self.groups = Y.merge(Y.Env.meta.groups); + + /** + * Provides the information used to skin the skinnable components. + * The following skin definition would result in 'skin1' and 'skin2' + * being loaded for calendar (if calendar was requested), and + * 'sam' for all other skinnable components: + * + * skin: { + * // The default skin, which is automatically applied if not + * // overriden by a component-specific skin definition. + * // Change this in to apply a different skin globally + * defaultSkin: 'sam', + * + * // This is combined with the loader base property to get + * // the default root directory for a skin. ex: + * // http://yui.yahooapis.com/2.3.0/build/assets/skins/sam/ + * base: 'assets/skins/', + * + * // Any component-specific overrides can be specified here, + * // making it possible to load different skins for different + * // components. It is possible to load more than one skin + * // for a given component as well. + * overrides: { + * calendar: ['skin1', 'skin2'] + * } + * } + * @property skin + * @type {Object} + */ + self.skin = Y.merge(Y.Env.meta.skin); + + /* + * Map of conditional modules + * @since 3.2.0 + */ + self.conditions = {}; + + // map of modules with a hash of modules that meet the requirement + // self.provides = {}; + + self.config = o; + self._internal = true; + + self._populateCache(); + + /** + * Set when beginning to compute the dependency tree. + * Composed of what YUI reports to be loaded combined + * with what has been loaded by any instance on the page + * with the version number specified in the metadata. + * @property loaded + * @type {string: boolean} + */ + self.loaded = GLOBAL_LOADED[VERSION]; + + + /** + * Should Loader fetch scripts in `async`, defaults to `true` + * @property async + */ + + self.async = true; + + self._inspectPage(); + + self._internal = false; + + self._config(o); + + self.forceMap = (self.force) ? Y.Array.hash(self.force) : {}; + + self.testresults = null; + + if (Y.config.tests) { + self.testresults = Y.config.tests; + } + + /** + * List of rollup files found in the library metadata + * @property rollups + */ + // self.rollups = null; + + /** + * Whether or not to load optional dependencies for + * the requested modules + * @property loadOptional + * @type boolean + * @default false + */ + // self.loadOptional = false; + + /** + * All of the derived dependencies in sorted order, which + * will be populated when either calculate() or insert() + * is called + * @property sorted + * @type string[] + */ + self.sorted = []; + + /* + * A list of modules to attach to the YUI instance when complete. + * If not supplied, the sorted list of dependencies are applied. + * @property attaching + */ + // self.attaching = null; + + /** + * Flag to indicate the dependency tree needs to be recomputed + * if insert is called again. + * @property dirty + * @type boolean + * @default true + */ + self.dirty = true; + + /** + * List of modules inserted by the utility + * @property inserted + * @type {string: boolean} + */ + self.inserted = {}; + + /** + * List of skipped modules during insert() because the module + * was not defined + * @property skipped + */ + self.skipped = {}; + + // Y.on('yui:load', self.loadNext, self); + + self.tested = {}; + + /* + * Cached sorted calculate results + * @property results + * @since 3.2.0 + */ + //self.results = {}; + + if (self.ignoreRegistered) { + //Clear inpage already processed modules. + self._resetModules(); + } + +}; + +Y.Loader.prototype = { + /** + * Checks the cache for modules and conditions, if they do not exist + * process the default metadata and populate the local moduleInfo hash. + * @method _populateCache + * @private + */ + _populateCache: function() { + var self = this, + defaults = META.modules, + cache = GLOBAL_ENV._renderedMods, + i; + + if (cache && !self.ignoreRegistered) { + for (i in cache) { + if (cache.hasOwnProperty(i)) { + self.moduleInfo[i] = Y.merge(cache[i]); + } + } + + cache = GLOBAL_ENV._conditions; + for (i in cache) { + if (cache.hasOwnProperty(i)) { + self.conditions[i] = Y.merge(cache[i]); + } + } + + } else { + for (i in defaults) { + if (defaults.hasOwnProperty(i)) { + self.addModule(defaults[i], i); + } + } + } + + }, + /** + * Reset modules in the module cache to a pre-processed state so additional + * computations with a different skin or language will work as expected. + * @method _resetModules + * @private + */ + _resetModules: function() { + var self = this, i, o, + mod, name, details; + for (i in self.moduleInfo) { + if (self.moduleInfo.hasOwnProperty(i)) { + mod = self.moduleInfo[i]; + name = mod.name; + details = (YUI.Env.mods[name] ? YUI.Env.mods[name].details : null); + + if (details) { + self.moduleInfo[name]._reset = true; + self.moduleInfo[name].requires = details.requires || []; + self.moduleInfo[name].optional = details.optional || []; + self.moduleInfo[name].supersedes = details.supercedes || []; + } + + if (mod.defaults) { + for (o in mod.defaults) { + if (mod.defaults.hasOwnProperty(o)) { + if (mod[o]) { + mod[o] = mod.defaults[o]; + } + } + } + } + delete mod.langCache; + delete mod.skinCache; + if (mod.skinnable) { + self._addSkin(self.skin.defaultSkin, mod.name); + } + } + } + }, + /** + Regex that matches a CSS URL. Used to guess the file type when it's not + specified. + + @property REGEX_CSS + @type RegExp + @final + @protected + @since 3.5.0 + **/ + REGEX_CSS: /\.css(?:[?;].*)?$/i, + + /** + * Default filters for raw and debug + * @property FILTER_DEFS + * @type Object + * @final + * @protected + */ + FILTER_DEFS: { + RAW: { + 'searchExp': '-min\\.js', + 'replaceStr': '.js' + }, + DEBUG: { + 'searchExp': '-min\\.js', + 'replaceStr': '-debug.js' + }, + COVERAGE: { + 'searchExp': '-min\\.js', + 'replaceStr': '-coverage.js' + } + }, + /* + * Check the pages meta-data and cache the result. + * @method _inspectPage + * @private + */ + _inspectPage: function() { + var self = this, v, m, req, mr, i; + + //Inspect the page for CSS only modules and mark them as loaded. + for (i in self.moduleInfo) { + if (self.moduleInfo.hasOwnProperty(i)) { + v = self.moduleInfo[i]; + if (v.type && v.type === CSS) { + if (self.isCSSLoaded(v.name)) { + self.loaded[i] = true; + } + } + } + } + for (i in ON_PAGE) { + if (ON_PAGE.hasOwnProperty(i)) { + v = ON_PAGE[i]; + if (v.details) { + m = self.moduleInfo[v.name]; + req = v.details.requires; + mr = m && m.requires; + + if (m) { + if (!m._inspected && req && mr.length !== req.length) { + // console.log('deleting ' + m.name); + delete m.expanded; + } + } else { + m = self.addModule(v.details, i); + } + m._inspected = true; + } + } + } + }, + /* + * returns true if b is not loaded, and is required directly or by means of modules it supersedes. + * @private + * @method _requires + * @param {String} mod1 The first module to compare + * @param {String} mod2 The second module to compare + */ + _requires: function(mod1, mod2) { + + var i, rm, after_map, s, + info = this.moduleInfo, + m = info[mod1], + other = info[mod2]; + + if (!m || !other) { + return false; + } + + rm = m.expanded_map; + after_map = m.after_map; + + // check if this module should be sorted after the other + // do this first to short circut circular deps + if (after_map && (mod2 in after_map)) { + return true; + } + + after_map = other.after_map; + + // and vis-versa + if (after_map && (mod1 in after_map)) { + return false; + } + + // check if this module requires one the other supersedes + s = info[mod2] && info[mod2].supersedes; + if (s) { + for (i = 0; i < s.length; i++) { + if (this._requires(mod1, s[i])) { + return true; + } + } + } + + s = info[mod1] && info[mod1].supersedes; + if (s) { + for (i = 0; i < s.length; i++) { + if (this._requires(mod2, s[i])) { + return false; + } + } + } + + // check if this module requires the other directly + // if (r && yArray.indexOf(r, mod2) > -1) { + if (rm && (mod2 in rm)) { + return true; + } + + // external css files should be sorted below yui css + if (m.ext && m.type === CSS && !other.ext && other.type === CSS) { + return true; + } + + return false; + }, + /** + * Apply a new config to the Loader instance + * @method _config + * @private + * @param {Object} o The new configuration + */ + _config: function(o) { + var i, j, val, a, f, group, groupName, self = this, + mods = [], mod; + // apply config values + if (o) { + for (i in o) { + if (o.hasOwnProperty(i)) { + val = o[i]; + //TODO This should be a case + if (i === 'require') { + self.require(val); + } else if (i === 'skin') { + //If the config.skin is a string, format to the expected object + if (typeof val === 'string') { + self.skin.defaultSkin = o.skin; + val = { + defaultSkin: val + }; + } + + Y.mix(self.skin, val, true); + } else if (i === 'groups') { + for (j in val) { + if (val.hasOwnProperty(j)) { + groupName = j; + group = val[j]; + self.addGroup(group, groupName); + if (group.aliases) { + for (a in group.aliases) { + if (group.aliases.hasOwnProperty(a)) { + self.addAlias(group.aliases[a], a); + } + } + } + } + } + + } else if (i === 'modules') { + // add a hash of module definitions + for (j in val) { + if (val.hasOwnProperty(j)) { + self.addModule(val[j], j); + } + } + } else if (i === 'aliases') { + for (j in val) { + if (val.hasOwnProperty(j)) { + self.addAlias(val[j], j); + } + } + } else if (i === 'gallery') { + if (this.groups.gallery.update) { + this.groups.gallery.update(val, o); + } + } else if (i === 'yui2' || i === '2in3') { + if (this.groups.yui2.update) { + this.groups.yui2.update(o['2in3'], o.yui2, o); + } + } else { + self[i] = val; + } + } + } + } + + // fix filter + f = self.filter; + + if (L.isString(f)) { + f = f.toUpperCase(); + self.filterName = f; + self.filter = self.FILTER_DEFS[f]; + if (f === 'DEBUG') { + self.require('yui-log', 'dump'); + } + } + + if (self.filterName && self.coverage) { + if (self.filterName === 'COVERAGE' && L.isArray(self.coverage) && self.coverage.length) { + for (i = 0; i < self.coverage.length; i++) { + mod = self.coverage[i]; + if (self.moduleInfo[mod] && self.moduleInfo[mod].use) { + mods = [].concat(mods, self.moduleInfo[mod].use); + } else { + mods.push(mod); + } + } + self.filters = self.filters || {}; + Y.Array.each(mods, function(mod) { + self.filters[mod] = self.FILTER_DEFS.COVERAGE; + }); + self.filterName = 'RAW'; + self.filter = self.FILTER_DEFS[self.filterName]; + } + } + + }, + + /** + * Returns the skin module name for the specified skin name. If a + * module name is supplied, the returned skin module name is + * specific to the module passed in. + * @method formatSkin + * @param {string} skin the name of the skin. + * @param {string} mod optional: the name of a module to skin. + * @return {string} the full skin module name. + */ + formatSkin: function(skin, mod) { + var s = SKIN_PREFIX + skin; + if (mod) { + s = s + '-' + mod; + } + + return s; + }, + + /** + * Adds the skin def to the module info + * @method _addSkin + * @param {string} skin the name of the skin. + * @param {string} mod the name of the module. + * @param {string} parent parent module if this is a skin of a + * submodule or plugin. + * @return {string} the module name for the skin. + * @private + */ + _addSkin: function(skin, mod, parent) { + var mdef, pkg, name, nmod, + info = this.moduleInfo, + sinf = this.skin, + ext = info[mod] && info[mod].ext; + + // Add a module definition for the module-specific skin css + if (mod) { + name = this.formatSkin(skin, mod); + if (!info[name]) { + mdef = info[mod]; + pkg = mdef.pkg || mod; + nmod = { + skin: true, + name: name, + group: mdef.group, + type: 'css', + after: sinf.after, + path: (parent || pkg) + '/' + sinf.base + skin + + '/' + mod + '.css', + ext: ext + }; + if (mdef.base) { + nmod.base = mdef.base; + } + if (mdef.configFn) { + nmod.configFn = mdef.configFn; + } + this.addModule(nmod, name); + + } + } + + return name; + }, + /** + * Adds an alias module to the system + * @method addAlias + * @param {Array} use An array of modules that makes up this alias + * @param {String} name The name of the alias + * @example + * var loader = new Y.Loader({}); + * loader.addAlias([ 'node', 'yql' ], 'davglass'); + * loader.require(['davglass']); + * var out = loader.resolve(true); + * + * //out.js will contain Node and YQL modules + */ + addAlias: function(use, name) { + YUI.Env.aliases[name] = use; + this.addModule({ + name: name, + use: use + }); + }, + /** + * Add a new module group + * @method addGroup + * @param {Object} config An object containing the group configuration data + * @param {String} config.name required, the group name + * @param {String} config.base The base directory for this module group + * @param {String} config.root The root path to add to each combo resource path + * @param {Boolean} config.combine Should the request be combined + * @param {String} config.comboBase Combo service base path + * @param {Object} config.modules The group of modules + * @param {String} name the group name. + * @example + * var loader = new Y.Loader({}); + * loader.addGroup({ + * name: 'davglass', + * combine: true, + * comboBase: '/combo?', + * root: '', + * modules: { + * //Module List here + * } + * }, 'davglass'); + */ + addGroup: function(o, name) { + var mods = o.modules, + self = this, i, v; + + name = name || o.name; + o.name = name; + self.groups[name] = o; + + if (o.patterns) { + for (i in o.patterns) { + if (o.patterns.hasOwnProperty(i)) { + o.patterns[i].group = name; + self.patterns[i] = o.patterns[i]; + } + } + } + + if (mods) { + for (i in mods) { + if (mods.hasOwnProperty(i)) { + v = mods[i]; + if (typeof v === 'string') { + v = { name: i, fullpath: v }; + } + v.group = name; + self.addModule(v, i); + } + } + } + }, + + /** + * Add a new module to the component metadata. + * @method addModule + * @param {Object} config An object containing the module data. + * @param {String} config.name Required, the component name + * @param {String} config.type Required, the component type (js or css) + * @param {String} config.path Required, the path to the script from `base` + * @param {Array} config.requires Array of modules required by this component + * @param {Array} [config.optional] Array of optional modules for this component + * @param {Array} [config.supersedes] Array of the modules this component replaces + * @param {Array} [config.after] Array of modules the components which, if present, should be sorted above this one + * @param {Object} [config.after_map] Faster alternative to 'after' -- supply a hash instead of an array + * @param {Number} [config.rollup] The number of superseded modules required for automatic rollup + * @param {String} [config.fullpath] If `fullpath` is specified, this is used instead of the configured `base + path` + * @param {Boolean} [config.skinnable] Flag to determine if skin assets should automatically be pulled in + * @param {Object} [config.submodules] Hash of submodules + * @param {String} [config.group] The group the module belongs to -- this is set automatically when it is added as part of a group configuration. + * @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"]` + * @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: + * @param {String} [config.condition.trigger] The name of a module that can trigger the auto-load + * @param {Function} [config.condition.test] A function that returns true when the module is to be loaded. + * @param {String} [config.condition.ua] The UA name of Y.UA object that returns true when the module is to be loaded. e.g., `"ie"`, `"nodejs"`. + * @param {String} [config.condition.when] Specifies the load order of the conditional module + * with regard to the position of the trigger module. + * This should be one of three values: `before`, `after`, or `instead`. The default is `after`. + * @param {Object} [config.testresults] A hash of test results from `Y.Features.all()` + * @param {Function} [config.configFn] A function to exectute when configuring this module + * @param {Object} config.configFn.mod The module config, modifying this object will modify it's config. Returning false will delete the module's config. + * @param {String} [name] The module name, required if not in the module data. + * @return {Object} the module definition or null if the object passed in did not provide all required attributes. + */ + addModule: function(o, name) { + name = name || o.name; + + if (typeof o === 'string') { + o = { name: name, fullpath: o }; + } + + + var subs, i, l, t, sup, s, smod, plugins, plug, + j, langs, packName, supName, flatSup, flatLang, lang, ret, + overrides, skinname, when, g, p, + conditions = this.conditions, trigger; + + //Only merge this data if the temp flag is set + //from an earlier pass from a pattern or else + //an override module (YUI_config) can not be used to + //replace a default module. + if (this.moduleInfo[name] && this.moduleInfo[name].temp) { + //This catches temp modules loaded via a pattern + // The module will be added twice, once from the pattern and + // Once from the actual add call, this ensures that properties + // that were added to the module the first time around (group: gallery) + // are also added the second time around too. + o = Y.merge(this.moduleInfo[name], o); + } + + o.name = name; + + if (!o || !o.name) { + return null; + } + + if (!o.type) { + //Always assume it's javascript unless the CSS pattern is matched. + o.type = JS; + p = o.path || o.fullpath; + if (p && this.REGEX_CSS.test(p)) { + o.type = CSS; + } + } + + if (!o.path && !o.fullpath) { + o.path = _path(name, name, o.type); + } + o.supersedes = o.supersedes || o.use; + + o.ext = ('ext' in o) ? o.ext : (this._internal) ? false : true; + + // Handle submodule logic + subs = o.submodules; + + this.moduleInfo[name] = o; + + o.requires = o.requires || []; + + /* + Only allowing the cascade of requires information, since + optional and supersedes are far more fine grained than + a blanket requires is. + */ + if (this.requires) { + for (i = 0; i < this.requires.length; i++) { + o.requires.push(this.requires[i]); + } + } + if (o.group && this.groups && this.groups[o.group]) { + g = this.groups[o.group]; + if (g.requires) { + for (i = 0; i < g.requires.length; i++) { + o.requires.push(g.requires[i]); + } + } + } + + + if (!o.defaults) { + o.defaults = { + requires: o.requires ? [].concat(o.requires) : null, + supersedes: o.supersedes ? [].concat(o.supersedes) : null, + optional: o.optional ? [].concat(o.optional) : null + }; + } + + if (o.skinnable && o.ext && o.temp) { + skinname = this._addSkin(this.skin.defaultSkin, name); + o.requires.unshift(skinname); + } + + if (o.requires.length) { + o.requires = this.filterRequires(o.requires) || []; + } + + if (!o.langPack && o.lang) { + langs = yArray(o.lang); + for (j = 0; j < langs.length; j++) { + lang = langs[j]; + packName = this.getLangPackName(lang, name); + smod = this.moduleInfo[packName]; + if (!smod) { + smod = this._addLangPack(lang, o, packName); + } + } + } + + + if (subs) { + sup = o.supersedes || []; + l = 0; + + for (i in subs) { + if (subs.hasOwnProperty(i)) { + s = subs[i]; + + s.path = s.path || _path(name, i, o.type); + s.pkg = name; + s.group = o.group; + + if (s.supersedes) { + sup = sup.concat(s.supersedes); + } + + smod = this.addModule(s, i); + sup.push(i); + + if (smod.skinnable) { + o.skinnable = true; + overrides = this.skin.overrides; + if (overrides && overrides[i]) { + for (j = 0; j < overrides[i].length; j++) { + skinname = this._addSkin(overrides[i][j], + i, name); + sup.push(skinname); + } + } + skinname = this._addSkin(this.skin.defaultSkin, + i, name); + sup.push(skinname); + } + + // looks like we are expected to work out the metadata + // for the parent module language packs from what is + // specified in the child modules. + if (s.lang && s.lang.length) { + + langs = yArray(s.lang); + for (j = 0; j < langs.length; j++) { + lang = langs[j]; + packName = this.getLangPackName(lang, name); + supName = this.getLangPackName(lang, i); + smod = this.moduleInfo[packName]; + + if (!smod) { + smod = this._addLangPack(lang, o, packName); + } + + flatSup = flatSup || yArray.hash(smod.supersedes); + + if (!(supName in flatSup)) { + smod.supersedes.push(supName); + } + + o.lang = o.lang || []; + + flatLang = flatLang || yArray.hash(o.lang); + + if (!(lang in flatLang)) { + o.lang.push(lang); + } + +// Add rollup file, need to add to supersedes list too + + // default packages + packName = this.getLangPackName(ROOT_LANG, name); + supName = this.getLangPackName(ROOT_LANG, i); + + smod = this.moduleInfo[packName]; + + if (!smod) { + smod = this._addLangPack(lang, o, packName); + } + + if (!(supName in flatSup)) { + smod.supersedes.push(supName); + } + +// Add rollup file, need to add to supersedes list too + + } + } + + l++; + } + } + //o.supersedes = YObject.keys(yArray.hash(sup)); + o.supersedes = yArray.dedupe(sup); + if (this.allowRollup) { + o.rollup = (l < 4) ? l : Math.min(l - 1, 4); + } + } + + plugins = o.plugins; + if (plugins) { + for (i in plugins) { + if (plugins.hasOwnProperty(i)) { + plug = plugins[i]; + plug.pkg = name; + plug.path = plug.path || _path(name, i, o.type); + plug.requires = plug.requires || []; + plug.group = o.group; + this.addModule(plug, i); + if (o.skinnable) { + this._addSkin(this.skin.defaultSkin, i, name); + } + + } + } + } + + if (o.condition) { + t = o.condition.trigger; + if (YUI.Env.aliases[t]) { + t = YUI.Env.aliases[t]; + } + if (!Y.Lang.isArray(t)) { + t = [t]; + } + + for (i = 0; i < t.length; i++) { + trigger = t[i]; + when = o.condition.when; + conditions[trigger] = conditions[trigger] || {}; + conditions[trigger][name] = o.condition; + // the 'when' attribute can be 'before', 'after', or 'instead' + // the default is after. + if (when && when !== 'after') { + if (when === 'instead') { // replace the trigger + o.supersedes = o.supersedes || []; + o.supersedes.push(trigger); + } + // before the trigger + // the trigger requires the conditional mod, + // so it should appear before the conditional + // mod if we do not intersede. + } else { // after the trigger + o.after = o.after || []; + o.after.push(trigger); + } + } + } + + if (o.supersedes) { + o.supersedes = this.filterRequires(o.supersedes); + } + + if (o.after) { + o.after = this.filterRequires(o.after); + o.after_map = yArray.hash(o.after); + } + + // this.dirty = true; + + if (o.configFn) { + ret = o.configFn(o); + if (ret === false) { + delete this.moduleInfo[name]; + delete GLOBAL_ENV._renderedMods[name]; + o = null; + } + } + //Add to global cache + if (o) { + if (!GLOBAL_ENV._renderedMods) { + GLOBAL_ENV._renderedMods = {}; + } + GLOBAL_ENV._renderedMods[name] = Y.mix(GLOBAL_ENV._renderedMods[name] || {}, o); + GLOBAL_ENV._conditions = conditions; + } + + return o; + }, + + /** + * Add a requirement for one or more module + * @method require + * @param {string[] | string*} what the modules to load. + */ + require: function(what) { + var a = (typeof what === 'string') ? yArray(arguments) : what; + this.dirty = true; + this.required = Y.merge(this.required, yArray.hash(this.filterRequires(a))); + + this._explodeRollups(); + }, + /** + * Grab all the items that were asked for, check to see if the Loader + * meta-data contains a "use" array. If it doesm remove the asked item and replace it with + * the content of the "use". + * This will make asking for: "dd" + * Actually ask for: "dd-ddm-base,dd-ddm,dd-ddm-drop,dd-drag,dd-proxy,dd-constrain,dd-drop,dd-scroll,dd-drop-plugin" + * @private + * @method _explodeRollups + */ + _explodeRollups: function() { + var self = this, m, m2, i, a, v, len, len2, + r = self.required; + + if (!self.allowRollup) { + for (i in r) { + if (r.hasOwnProperty(i)) { + m = self.getModule(i); + if (m && m.use) { + len = m.use.length; + for (a = 0; a < len; a++) { + m2 = self.getModule(m.use[a]); + if (m2 && m2.use) { + len2 = m2.use.length; + for (v = 0; v < len2; v++) { + r[m2.use[v]] = true; + } + } else { + r[m.use[a]] = true; + } + } + } + } + } + self.required = r; + } + + }, + /** + * Explodes the required array to remove aliases and replace them with real modules + * @method filterRequires + * @param {Array} r The original requires array + * @return {Array} The new array of exploded requirements + */ + filterRequires: function(r) { + if (r) { + if (!Y.Lang.isArray(r)) { + r = [r]; + } + r = Y.Array(r); + var c = [], i, mod, o, m; + + for (i = 0; i < r.length; i++) { + mod = this.getModule(r[i]); + if (mod && mod.use) { + for (o = 0; o < mod.use.length; o++) { + //Must walk the other modules in case a module is a rollup of rollups (datatype) + m = this.getModule(mod.use[o]); + if (m && m.use && (m.name !== mod.name)) { + c = Y.Array.dedupe([].concat(c, this.filterRequires(m.use))); + } else { + c.push(mod.use[o]); + } + } + } else { + c.push(r[i]); + } + } + r = c; + } + return r; + }, + /** + * Returns an object containing properties for all modules required + * in order to load the requested module + * @method getRequires + * @param {object} mod The module definition from moduleInfo. + * @return {array} the expanded requirement list. + */ + getRequires: function(mod) { + + if (!mod) { + //console.log('returning no reqs for ' + mod.name); + return NO_REQUIREMENTS; + } + + if (mod._parsed) { + //console.log('returning requires for ' + mod.name, mod.requires); + return mod.expanded || NO_REQUIREMENTS; + } + + //TODO add modue cache here out of scope.. + + var i, m, j, add, packName, lang, testresults = this.testresults, + name = mod.name, cond, + adddef = ON_PAGE[name] && ON_PAGE[name].details, + d, go, def, + r, old_mod, + o, skinmod, skindef, skinpar, skinname, + intl = mod.lang || mod.intl, + info = this.moduleInfo, + ftests = Y.Features && Y.Features.tests.load, + hash, reparse; + + // console.log(name); + + // pattern match leaves module stub that needs to be filled out + if (mod.temp && adddef) { + old_mod = mod; + mod = this.addModule(adddef, name); + mod.group = old_mod.group; + mod.pkg = old_mod.pkg; + delete mod.expanded; + } + + // console.log('cache: ' + mod.langCache + ' == ' + this.lang); + + //If a skin or a lang is different, reparse.. + reparse = !((!this.lang || mod.langCache === this.lang) && (mod.skinCache === this.skin.defaultSkin)); + + if (mod.expanded && !reparse) { + return mod.expanded; + } + + + d = []; + hash = {}; + r = this.filterRequires(mod.requires); + if (mod.lang) { + //If a module has a lang attribute, auto add the intl requirement. + d.unshift('intl'); + r.unshift('intl'); + intl = true; + } + o = this.filterRequires(mod.optional); + + + mod._parsed = true; + mod.langCache = this.lang; + mod.skinCache = this.skin.defaultSkin; + + for (i = 0; i < r.length; i++) { + if (!hash[r[i]]) { + d.push(r[i]); + hash[r[i]] = true; + m = this.getModule(r[i]); + if (m) { + add = this.getRequires(m); + intl = intl || (m.expanded_map && + (INTL in m.expanded_map)); + for (j = 0; j < add.length; j++) { + d.push(add[j]); + } + } + } + } + + // get the requirements from superseded modules, if any + r = this.filterRequires(mod.supersedes); + if (r) { + for (i = 0; i < r.length; i++) { + if (!hash[r[i]]) { + // if this module has submodules, the requirements list is + // expanded to include the submodules. This is so we can + // prevent dups when a submodule is already loaded and the + // parent is requested. + if (mod.submodules) { + d.push(r[i]); + } + + hash[r[i]] = true; + m = this.getModule(r[i]); + + if (m) { + add = this.getRequires(m); + intl = intl || (m.expanded_map && + (INTL in m.expanded_map)); + for (j = 0; j < add.length; j++) { + d.push(add[j]); + } + } + } + } + } + + if (o && this.loadOptional) { + for (i = 0; i < o.length; i++) { + if (!hash[o[i]]) { + d.push(o[i]); + hash[o[i]] = true; + m = info[o[i]]; + if (m) { + add = this.getRequires(m); + intl = intl || (m.expanded_map && + (INTL in m.expanded_map)); + for (j = 0; j < add.length; j++) { + d.push(add[j]); + } + } + } + } + } + + cond = this.conditions[name]; + + if (cond) { + //Set the module to not parsed since we have conditionals and this could change the dependency tree. + mod._parsed = false; + if (testresults && ftests) { + oeach(testresults, function(result, id) { + var condmod = ftests[id].name; + if (!hash[condmod] && ftests[id].trigger === name) { + if (result && ftests[id]) { + hash[condmod] = true; + d.push(condmod); + } + } + }); + } else { + for (i in cond) { + if (cond.hasOwnProperty(i)) { + if (!hash[i]) { + def = cond[i]; + //first see if they've specfied a ua check + //then see if they've got a test fn & if it returns true + //otherwise just having a condition block is enough + go = def && ((!def.ua && !def.test) || (def.ua && Y.UA[def.ua]) || + (def.test && def.test(Y, r))); + + if (go) { + hash[i] = true; + d.push(i); + m = this.getModule(i); + if (m) { + add = this.getRequires(m); + for (j = 0; j < add.length; j++) { + d.push(add[j]); + } + + } + } + } + } + } + } + } + + // Create skin modules + if (mod.skinnable) { + skindef = this.skin.overrides; + for (i in YUI.Env.aliases) { + if (YUI.Env.aliases.hasOwnProperty(i)) { + if (Y.Array.indexOf(YUI.Env.aliases[i], name) > -1) { + skinpar = i; + } + } + } + if (skindef && (skindef[name] || (skinpar && skindef[skinpar]))) { + skinname = name; + if (skindef[skinpar]) { + skinname = skinpar; + } + for (i = 0; i < skindef[skinname].length; i++) { + skinmod = this._addSkin(skindef[skinname][i], name); + if (!this.isCSSLoaded(skinmod, this._boot)) { + d.push(skinmod); + } + } + } else { + skinmod = this._addSkin(this.skin.defaultSkin, name); + if (!this.isCSSLoaded(skinmod, this._boot)) { + d.push(skinmod); + } + } + } + + mod._parsed = false; + + if (intl) { + + if (mod.lang && !mod.langPack && Y.Intl) { + lang = Y.Intl.lookupBestLang(this.lang || ROOT_LANG, mod.lang); + packName = this.getLangPackName(lang, name); + if (packName) { + d.unshift(packName); + } + } + d.unshift(INTL); + } + + mod.expanded_map = yArray.hash(d); + + mod.expanded = YObject.keys(mod.expanded_map); + + return mod.expanded; + }, + /** + * Check to see if named css module is already loaded on the page + * @method isCSSLoaded + * @param {String} name The name of the css file + * @return Boolean + */ + isCSSLoaded: function(name, skip) { + //TODO - Make this call a batching call with name being an array + if (!name || !YUI.Env.cssStampEl || (!skip && this.ignoreRegistered)) { + return false; + } + var el = YUI.Env.cssStampEl, + ret = false, + mod = YUI.Env._cssLoaded[name], + style = el.currentStyle; //IE + + + if (mod !== undefined) { + return mod; + } + + //Add the classname to the element + el.className = name; + + if (!style) { + style = Y.config.doc.defaultView.getComputedStyle(el, null); + } + + if (style && style.display === 'none') { + ret = true; + } + + + el.className = ''; //Reset the classname to '' + + YUI.Env._cssLoaded[name] = ret; + + return ret; + }, + + /** + * Returns a hash of module names the supplied module satisfies. + * @method getProvides + * @param {string} name The name of the module. + * @return {object} what this module provides. + */ + getProvides: function(name) { + var m = this.getModule(name), o, s; + // supmap = this.provides; + + if (!m) { + return NOT_FOUND; + } + + if (m && !m.provides) { + o = {}; + s = m.supersedes; + + if (s) { + yArray.each(s, function(v) { + Y.mix(o, this.getProvides(v)); + }, this); + } + + o[name] = true; + m.provides = o; + + } + + return m.provides; + }, + + /** + * Calculates the dependency tree, the result is stored in the sorted + * property. + * @method calculate + * @param {object} o optional options object. + * @param {string} type optional argument to prune modules. + */ + calculate: function(o, type) { + if (o || type || this.dirty) { + + if (o) { + this._config(o); + } + + if (!this._init) { + this._setup(); + } + + this._explode(); + + if (this.allowRollup) { + this._rollup(); + } else { + this._explodeRollups(); + } + this._reduce(); + this._sort(); + } + }, + /** + * Creates a "psuedo" package for languages provided in the lang array + * @method _addLangPack + * @private + * @param {String} lang The language to create + * @param {Object} m The module definition to create the language pack around + * @param {String} packName The name of the package (e.g: lang/datatype-date-en-US) + * @return {Object} The module definition + */ + _addLangPack: function(lang, m, packName) { + var name = m.name, + packPath, conf, + existing = this.moduleInfo[packName]; + + if (!existing) { + + packPath = _path((m.pkg || name), packName, JS, true); + + conf = { + path: packPath, + intl: true, + langPack: true, + ext: m.ext, + group: m.group, + supersedes: [] + }; + if (m.root) { + conf.root = m.root; + } + if (m.base) { + conf.base = m.base; + } + + if (m.configFn) { + conf.configFn = m.configFn; + } + + this.addModule(conf, packName); + + if (lang) { + Y.Env.lang = Y.Env.lang || {}; + Y.Env.lang[lang] = Y.Env.lang[lang] || {}; + Y.Env.lang[lang][name] = true; + } + } + + return this.moduleInfo[packName]; + }, + + /** + * Investigates the current YUI configuration on the page. By default, + * modules already detected will not be loaded again unless a force + * option is encountered. Called by calculate() + * @method _setup + * @private + */ + _setup: function() { + var info = this.moduleInfo, name, i, j, m, l, + packName; + + for (name in info) { + if (info.hasOwnProperty(name)) { + m = info[name]; + if (m) { + + // remove dups + //m.requires = YObject.keys(yArray.hash(m.requires)); + m.requires = yArray.dedupe(m.requires); + + // Create lang pack modules + //if (m.lang && m.lang.length) { + if (m.lang) { + // Setup root package if the module has lang defined, + // it needs to provide a root language pack + packName = this.getLangPackName(ROOT_LANG, name); + this._addLangPack(null, m, packName); + } + + } + } + } + + + //l = Y.merge(this.inserted); + l = {}; + + // available modules + if (!this.ignoreRegistered) { + Y.mix(l, GLOBAL_ENV.mods); + } + + // add the ignore list to the list of loaded packages + if (this.ignore) { + Y.mix(l, yArray.hash(this.ignore)); + } + + // expand the list to include superseded modules + for (j in l) { + if (l.hasOwnProperty(j)) { + Y.mix(l, this.getProvides(j)); + } + } + + // remove modules on the force list from the loaded list + if (this.force) { + for (i = 0; i < this.force.length; i++) { + if (this.force[i] in l) { + delete l[this.force[i]]; + } + } + } + + Y.mix(this.loaded, l); + + this._init = true; + }, + + /** + * Builds a module name for a language pack + * @method getLangPackName + * @param {string} lang the language code. + * @param {string} mname the module to build it for. + * @return {string} the language pack module name. + */ + getLangPackName: function(lang, mname) { + return ('lang/' + mname + ((lang) ? '_' + lang : '')); + }, + /** + * Inspects the required modules list looking for additional + * dependencies. Expands the required list to include all + * required modules. Called by calculate() + * @method _explode + * @private + */ + _explode: function() { + //TODO Move done out of scope + var r = this.required, m, reqs, done = {}, + self = this, name, expound; + + // the setup phase is over, all modules have been created + self.dirty = false; + + self._explodeRollups(); + r = self.required; + + for (name in r) { + if (r.hasOwnProperty(name)) { + if (!done[name]) { + done[name] = true; + m = self.getModule(name); + if (m) { + expound = m.expound; + + if (expound) { + r[expound] = self.getModule(expound); + reqs = self.getRequires(r[expound]); + Y.mix(r, yArray.hash(reqs)); + } + + reqs = self.getRequires(m); + Y.mix(r, yArray.hash(reqs)); + } + } + } + } + + }, + /** + * The default method used to test a module against a pattern + * @method _patternTest + * @private + * @param {String} mname The module being tested + * @param {String} pname The pattern to match + */ + _patternTest: function(mname, pname) { + return (mname.indexOf(pname) > -1); + }, + /** + * Get's the loader meta data for the requested module + * @method getModule + * @param {String} mname The module name to get + * @return {Object} The module metadata + */ + getModule: function(mname) { + //TODO: Remove name check - it's a quick hack to fix pattern WIP + if (!mname) { + return null; + } + + var p, found, pname, + m = this.moduleInfo[mname], + patterns = this.patterns; + + // check the patterns library to see if we should automatically add + // the module with defaults + if (!m || (m && m.ext)) { + for (pname in patterns) { + if (patterns.hasOwnProperty(pname)) { + p = patterns[pname]; + + //There is no test method, create a default one that tests + // the pattern against the mod name + if (!p.test) { + p.test = this._patternTest; + } + + if (p.test(mname, pname)) { + // use the metadata supplied for the pattern + // as the module definition. + found = p; + break; + } + } + } + } + + if (!m) { + if (found) { + if (p.action) { + p.action.call(this, mname, pname); + } else { + // ext true or false? + m = this.addModule(Y.merge(found), mname); + if (found.configFn) { + m.configFn = found.configFn; + } + m.temp = true; + } + } + } else { + if (found && m && found.configFn && !m.configFn) { + m.configFn = found.configFn; + m.configFn(m); + } + } + + return m; + }, + + // impl in rollup submodule + _rollup: function() { }, + + /** + * Remove superceded modules and loaded modules. Called by + * calculate() after we have the mega list of all dependencies + * @method _reduce + * @return {object} the reduced dependency hash. + * @private + */ + _reduce: function(r) { + + r = r || this.required; + + var i, j, s, m, type = this.loadType, + ignore = this.ignore ? yArray.hash(this.ignore) : false; + + for (i in r) { + if (r.hasOwnProperty(i)) { + m = this.getModule(i); + // remove if already loaded + if (((this.loaded[i] || ON_PAGE[i]) && + !this.forceMap[i] && !this.ignoreRegistered) || + (type && m && m.type !== type)) { + delete r[i]; + } + if (ignore && ignore[i]) { + delete r[i]; + } + // remove anything this module supersedes + s = m && m.supersedes; + if (s) { + for (j = 0; j < s.length; j++) { + if (s[j] in r) { + delete r[s[j]]; + } + } + } + } + } + + return r; + }, + /** + * Handles the queue when a module has been loaded for all cases + * @method _finish + * @private + * @param {String} msg The message from Loader + * @param {Boolean} success A boolean denoting success or failure + */ + _finish: function(msg, success) { + + _queue.running = false; + + var onEnd = this.onEnd; + if (onEnd) { + onEnd.call(this.context, { + msg: msg, + data: this.data, + success: success + }); + } + this._continue(); + }, + /** + * The default Loader onSuccess handler, calls this.onSuccess with a payload + * @method _onSuccess + * @private + */ + _onSuccess: function() { + var self = this, skipped = Y.merge(self.skipped), fn, + failed = [], rreg = self.requireRegistration, + success, msg, i, mod; + + for (i in skipped) { + if (skipped.hasOwnProperty(i)) { + delete self.inserted[i]; + } + } + + self.skipped = {}; + + for (i in self.inserted) { + if (self.inserted.hasOwnProperty(i)) { + mod = self.getModule(i); + if (mod && rreg && mod.type === JS && !(i in YUI.Env.mods)) { + failed.push(i); + } else { + Y.mix(self.loaded, self.getProvides(i)); + } + } + } + + fn = self.onSuccess; + msg = (failed.length) ? 'notregistered' : 'success'; + success = !(failed.length); + if (fn) { + fn.call(self.context, { + msg: msg, + data: self.data, + success: success, + failed: failed, + skipped: skipped + }); + } + self._finish(msg, success); + }, + /** + * The default Loader onProgress handler, calls this.onProgress with a payload + * @method _onProgress + * @private + */ + _onProgress: function(e) { + var self = this, i; + //set the internal cache to what just came in. + if (e.data && e.data.length) { + for (i = 0; i < e.data.length; i++) { + e.data[i] = self.getModule(e.data[i].name); + } + } + if (self.onProgress) { + self.onProgress.call(self.context, { + name: e.url, + data: e.data + }); + } + }, + /** + * The default Loader onFailure handler, calls this.onFailure with a payload + * @method _onFailure + * @private + */ + _onFailure: function(o) { + var f = this.onFailure, msg = [], i = 0, len = o.errors.length; + + for (i; i < len; i++) { + msg.push(o.errors[i].error); + } + + msg = msg.join(','); + + + if (f) { + f.call(this.context, { + msg: msg, + data: this.data, + success: false + }); + } + + this._finish(msg, false); + + }, + + /** + * The default Loader onTimeout handler, calls this.onTimeout with a payload + * @method _onTimeout + * @param {Get.Transaction} transaction The Transaction object from `Y.Get` + * @private + */ + _onTimeout: function(transaction) { + var f = this.onTimeout; + if (f) { + f.call(this.context, { + msg: 'timeout', + data: this.data, + success: false, + transaction: transaction + }); + } + }, + + /** + * Sorts the dependency tree. The last step of calculate() + * @method _sort + * @private + */ + _sort: function() { + + // create an indexed list + var s = YObject.keys(this.required), + // loaded = this.loaded, + //TODO Move this out of scope + done = {}, + p = 0, l, a, b, j, k, moved, doneKey; + + // keep going until we make a pass without moving anything + for (;;) { + + l = s.length; + moved = false; + + // start the loop after items that are already sorted + for (j = p; j < l; j++) { + + // check the next module on the list to see if its + // dependencies have been met + a = s[j]; + + // check everything below current item and move if we + // find a requirement for the current item + for (k = j + 1; k < l; k++) { + doneKey = a + s[k]; + + if (!done[doneKey] && this._requires(a, s[k])) { + + // extract the dependency so we can move it up + b = s.splice(k, 1); + + // insert the dependency above the item that + // requires it + s.splice(j, 0, b[0]); + + // only swap two dependencies once to short circut + // circular dependencies + done[doneKey] = true; + + // keep working + moved = true; + + break; + } + } + + // jump out of loop if we moved something + if (moved) { + break; + // this item is sorted, move our pointer and keep going + } else { + p++; + } + } + + // when we make it here and moved is false, we are + // finished sorting + if (!moved) { + break; + } + + } + + this.sorted = s; + }, + + /** + * Handles the actual insertion of script/link tags + * @method _insert + * @private + * @param {Object} source The YUI instance the request came from + * @param {Object} o The metadata to include + * @param {String} type JS or CSS + * @param {Boolean} [skipcalc=false] Do a Loader.calculate on the meta + */ + _insert: function(source, o, type, skipcalc) { + + + // restore the state at the time of the request + if (source) { + this._config(source); + } + + // build the dependency list + // don't include type so we can process CSS and script in + // one pass when the type is not specified. + + var modules = this.resolve(!skipcalc), + self = this, comp = 0, actions = 0, + mods = {}, deps, complete; + + self._refetch = []; + + if (type) { + //Filter out the opposite type and reset the array so the checks later work + modules[((type === JS) ? CSS : JS)] = []; + } + if (!self.fetchCSS) { + modules.css = []; + } + if (modules.js.length) { + comp++; + } + if (modules.css.length) { + comp++; + } + + //console.log('Resolved Modules: ', modules); + + complete = function(d) { + actions++; + var errs = {}, i = 0, o = 0, u = '', fn, + modName, resMods; + + if (d && d.errors) { + for (i = 0; i < d.errors.length; i++) { + if (d.errors[i].request) { + u = d.errors[i].request.url; + } else { + u = d.errors[i]; + } + errs[u] = u; + } + } + + if (d && d.data && d.data.length && (d.type === 'success')) { + for (i = 0; i < d.data.length; i++) { + self.inserted[d.data[i].name] = true; + //If the external module has a skin or a lang, reprocess it + if (d.data[i].lang || d.data[i].skinnable) { + delete self.inserted[d.data[i].name]; + self._refetch.push(d.data[i].name); + } + } + } + + if (actions === comp) { + self._loading = null; + if (self._refetch.length) { + //Get the deps for the new meta-data and reprocess + for (i = 0; i < self._refetch.length; i++) { + deps = self.getRequires(self.getModule(self._refetch[i])); + for (o = 0; o < deps.length; o++) { + if (!self.inserted[deps[o]]) { + //We wouldn't be to this point without the module being here + mods[deps[o]] = deps[o]; + } + } + } + mods = Y.Object.keys(mods); + if (mods.length) { + self.require(mods); + resMods = self.resolve(true); + if (resMods.cssMods.length) { + for (i=0; i < resMods.cssMods.length; i++) { + modName = resMods.cssMods[i].name; + delete YUI.Env._cssLoaded[modName]; + if (self.isCSSLoaded(modName)) { + self.inserted[modName] = true; + delete self.required[modName]; + } + } + self.sorted = []; + self._sort(); + } + d = null; //bail + self._insert(); //insert the new deps + } + } + if (d && d.fn) { + fn = d.fn; + delete d.fn; + fn.call(self, d); + } + } + }; + + this._loading = true; + + if (!modules.js.length && !modules.css.length) { + actions = -1; + complete({ + fn: self._onSuccess + }); + return; + } + + + if (modules.css.length) { //Load CSS first + Y.Get.css(modules.css, { + data: modules.cssMods, + attributes: self.cssAttributes, + insertBefore: self.insertBefore, + charset: self.charset, + timeout: self.timeout, + context: self, + onProgress: function(e) { + self._onProgress.call(self, e); + }, + onTimeout: function(d) { + self._onTimeout.call(self, d); + }, + onSuccess: function(d) { + d.type = 'success'; + d.fn = self._onSuccess; + complete.call(self, d); + }, + onFailure: function(d) { + d.type = 'failure'; + d.fn = self._onFailure; + complete.call(self, d); + } + }); + } + + if (modules.js.length) { + Y.Get.js(modules.js, { + data: modules.jsMods, + insertBefore: self.insertBefore, + attributes: self.jsAttributes, + charset: self.charset, + timeout: self.timeout, + autopurge: false, + context: self, + async: self.async, + onProgress: function(e) { + self._onProgress.call(self, e); + }, + onTimeout: function(d) { + self._onTimeout.call(self, d); + }, + onSuccess: function(d) { + d.type = 'success'; + d.fn = self._onSuccess; + complete.call(self, d); + }, + onFailure: function(d) { + d.type = 'failure'; + d.fn = self._onFailure; + complete.call(self, d); + } + }); + } + }, + /** + * Once a loader operation is completely finished, process any additional queued items. + * @method _continue + * @private + */ + _continue: function() { + if (!(_queue.running) && _queue.size() > 0) { + _queue.running = true; + _queue.next()(); + } + }, + + /** + * inserts the requested modules and their dependencies. + * type can be "js" or "css". Both script and + * css are inserted if type is not provided. + * @method insert + * @param {object} o optional options object. + * @param {string} type the type of dependency to insert. + */ + insert: function(o, type, skipsort) { + var self = this, copy = Y.merge(this); + delete copy.require; + delete copy.dirty; + _queue.add(function() { + self._insert(copy, o, type, skipsort); + }); + this._continue(); + }, + + /** + * Executed every time a module is loaded, and if we are in a load + * cycle, we attempt to load the next script. Public so that it + * is possible to call this if using a method other than + * Y.register to determine when scripts are fully loaded + * @method loadNext + * @deprecated + * @param {string} mname optional the name of the module that has + * been loaded (which is usually why it is time to load the next + * one). + */ + loadNext: function() { + return; + }, + + /** + * Apply filter defined for this instance to a url/path + * @method _filter + * @param {string} u the string to filter. + * @param {string} name the name of the module, if we are processing + * a single module as opposed to a combined url. + * @return {string} the filtered string. + * @private + */ + _filter: function(u, name, group) { + var f = this.filter, + hasFilter = name && (name in this.filters), + modFilter = hasFilter && this.filters[name], + groupName = group || (this.moduleInfo[name] ? this.moduleInfo[name].group : null); + + if (groupName && this.groups[groupName] && this.groups[groupName].filter) { + modFilter = this.groups[groupName].filter; + hasFilter = true; + } + + if (u) { + if (hasFilter) { + f = (L.isString(modFilter)) ? this.FILTER_DEFS[modFilter.toUpperCase()] || null : modFilter; + } + if (f) { + u = u.replace(new RegExp(f.searchExp, 'g'), f.replaceStr); + } + } + return u; + }, + + /** + * Generates the full url for a module + * @method _url + * @param {string} path the path fragment. + * @param {String} name The name of the module + * @param {String} [base=self.base] The base url to use + * @return {string} the full url. + * @private + */ + _url: function(path, name, base) { + return this._filter((base || this.base || '') + path, name); + }, + /** + * Returns an Object hash of file arrays built from `loader.sorted` or from an arbitrary list of sorted modules. + * @method resolve + * @param {Boolean} [calc=false] Perform a loader.calculate() before anything else + * @param {Array} [s=loader.sorted] An override for the loader.sorted array + * @return {Object} Object hash (js and css) of two arrays of file lists + * @example This method can be used as an off-line dep calculator + * + * var Y = YUI(); + * var loader = new Y.Loader({ + * filter: 'debug', + * base: '../../', + * root: 'build/', + * combine: true, + * require: ['node', 'dd', 'console'] + * }); + * var out = loader.resolve(true); + * + */ + resolve: function(calc, s) { + + var len, i, m, url, group, groupName, j, frag, + comboSource, comboSources, mods, comboBase, + base, urls, u = [], tmpBase, baseLen, resCombos = {}, + self = this, comboSep, maxURLLength, + inserted = (self.ignoreRegistered) ? {} : self.inserted, + resolved = { js: [], jsMods: [], css: [], cssMods: [] }, + type = self.loadType || 'js', addSingle; + + if (self.skin.overrides || self.skin.defaultSkin !== DEFAULT_SKIN || self.ignoreRegistered) { + self._resetModules(); + } + + if (calc) { + self.calculate(); + } + s = s || self.sorted; + + addSingle = function(m) { + + if (m) { + group = (m.group && self.groups[m.group]) || NOT_FOUND; + + //Always assume it's async + if (group.async === false) { + m.async = group.async; + } + + url = (m.fullpath) ? self._filter(m.fullpath, s[i]) : + self._url(m.path, s[i], group.base || m.base); + + if (m.attributes || m.async === false) { + url = { + url: url, + async: m.async + }; + if (m.attributes) { + url.attributes = m.attributes; + } + } + resolved[m.type].push(url); + resolved[m.type + 'Mods'].push(m); + } else { + } + + }; + + len = s.length; + + // the default combo base + comboBase = self.comboBase; + + url = comboBase; + + comboSources = {}; + + for (i = 0; i < len; i++) { + comboSource = comboBase; + m = self.getModule(s[i]); + groupName = m && m.group; + group = self.groups[groupName]; + if (groupName && group) { + + if (!group.combine || m.fullpath) { + //This is not a combo module, skip it and load it singly later. + addSingle(m); + continue; + } + m.combine = true; + if (group.comboBase) { + comboSource = group.comboBase; + } + + if ("root" in group && L.isValue(group.root)) { + m.root = group.root; + } + m.comboSep = group.comboSep || self.comboSep; + m.maxURLLength = group.maxURLLength || self.maxURLLength; + } else { + if (!self.combine) { + //This is not a combo module, skip it and load it singly later. + addSingle(m); + continue; + } + } + + comboSources[comboSource] = comboSources[comboSource] || []; + comboSources[comboSource].push(m); + } + + for (j in comboSources) { + if (comboSources.hasOwnProperty(j)) { + resCombos[j] = resCombos[j] || { js: [], jsMods: [], css: [], cssMods: [] }; + url = j; + mods = comboSources[j]; + len = mods.length; + + if (len) { + for (i = 0; i < len; i++) { + if (inserted[mods[i]]) { + continue; + } + m = mods[i]; + // Do not try to combine non-yui JS unless combo def + // is found + if (m && (m.combine || !m.ext)) { + resCombos[j].comboSep = m.comboSep; + resCombos[j].group = m.group; + resCombos[j].maxURLLength = m.maxURLLength; + frag = ((L.isValue(m.root)) ? m.root : self.root) + (m.path || m.fullpath); + frag = self._filter(frag, m.name); + resCombos[j][m.type].push(frag); + resCombos[j][m.type + 'Mods'].push(m); + } else { + //Add them to the next process.. + if (mods[i]) { + addSingle(mods[i]); + } + } + + } + } + } + } + + + for (j in resCombos) { + if (resCombos.hasOwnProperty(j)) { + base = j; + comboSep = resCombos[base].comboSep || self.comboSep; + maxURLLength = resCombos[base].maxURLLength || self.maxURLLength; + for (type in resCombos[base]) { + if (type === JS || type === CSS) { + urls = resCombos[base][type]; + mods = resCombos[base][type + 'Mods']; + len = urls.length; + tmpBase = base + urls.join(comboSep); + baseLen = tmpBase.length; + if (maxURLLength <= base.length) { + maxURLLength = MAX_URL_LENGTH; + } + + if (len) { + if (baseLen > maxURLLength) { + u = []; + for (s = 0; s < len; s++) { + u.push(urls[s]); + tmpBase = base + u.join(comboSep); + + if (tmpBase.length > maxURLLength) { + m = u.pop(); + tmpBase = base + u.join(comboSep); + resolved[type].push(self._filter(tmpBase, null, resCombos[base].group)); + u = []; + if (m) { + u.push(m); + } + } + } + if (u.length) { + tmpBase = base + u.join(comboSep); + resolved[type].push(self._filter(tmpBase, null, resCombos[base].group)); + } + } else { + resolved[type].push(self._filter(tmpBase, null, resCombos[base].group)); + } + } + resolved[type + 'Mods'] = resolved[type + 'Mods'].concat(mods); + } + } + } + } + + resCombos = null; + + return resolved; + }, + /** + Shortcut to calculate, resolve and load all modules. + + var loader = new Y.Loader({ + ignoreRegistered: true, + modules: { + mod: { + path: 'mod.js' + } + }, + requires: [ 'mod' ] + }); + loader.load(function() { + console.log('All modules have loaded..'); + }); + + + @method load + @param {Callback} cb Executed after all load operations are complete + */ + load: function(cb) { + if (!cb) { + return; + } + var self = this, + out = self.resolve(true); + + self.data = out; + + self.onEnd = function() { + cb.apply(self.context || self, arguments); + }; + + self.insert(); + } +}; + + + +}, '3.10.3', {"requires": ["get", "features"]}); +YUI.add('loader-rollup', function (Y, NAME) { + +/** + * Optional automatic rollup logic for reducing http connections + * when not using a combo service. + * @module loader + * @submodule rollup + */ + +/** + * Look for rollup packages to determine if all of the modules a + * rollup supersedes are required. If so, include the rollup to + * help reduce the total number of connections required. Called + * by calculate(). This is an optional feature, and requires the + * appropriate submodule to function. + * @method _rollup + * @for Loader + * @private + */ +Y.Loader.prototype._rollup = function() { + var i, j, m, s, r = this.required, roll, + info = this.moduleInfo, rolled, c, smod; + + // find and cache rollup modules + if (this.dirty || !this.rollups) { + this.rollups = {}; + for (i in info) { + if (info.hasOwnProperty(i)) { + m = this.getModule(i); + // if (m && m.rollup && m.supersedes) { + if (m && m.rollup) { + this.rollups[i] = m; + } + } + } + } + + // make as many passes as needed to pick up rollup rollups + for (;;) { + rolled = false; + + // go through the rollup candidates + for (i in this.rollups) { + if (this.rollups.hasOwnProperty(i)) { + // there can be only one, unless forced + if (!r[i] && ((!this.loaded[i]) || this.forceMap[i])) { + m = this.getModule(i); + s = m.supersedes || []; + roll = false; + + // @TODO remove continue + if (!m.rollup) { + continue; + } + + c = 0; + + // check the threshold + for (j = 0; j < s.length; j++) { + smod = info[s[j]]; + + // if the superseded module is loaded, we can't + // load the rollup unless it has been forced. + if (this.loaded[s[j]] && !this.forceMap[s[j]]) { + roll = false; + break; + // increment the counter if this module is required. + // if we are beyond the rollup threshold, we will + // use the rollup module + } else if (r[s[j]] && m.type === smod.type) { + c++; + roll = (c >= m.rollup); + if (roll) { + break; + } + } + } + + if (roll) { + // add the rollup + r[i] = true; + rolled = true; + + // expand the rollup's dependencies + this.getRequires(m); + } + } + } + } + + // if we made it here w/o rolling up something, we are done + if (!rolled) { + break; + } + } +}; + + +}, '3.10.3', {"requires": ["loader-base"]}); +YUI.add('loader-yui3', function (Y, NAME) { + +/* This file is auto-generated by (yogi loader --yes --mix --start ../) */ + +/*jshint maxlen:900, eqeqeq: false */ + +/** + * YUI 3 module metadata + * @module loader + * @submodule loader-yui3 + */ +YUI.Env[Y.version].modules = YUI.Env[Y.version].modules || {}; +Y.mix(YUI.Env[Y.version].modules, { + "align-plugin": { + "requires": [ + "node-screen", + "node-pluginhost" + ] + }, + "anim": { + "use": [ + "anim-base", + "anim-color", + "anim-curve", + "anim-easing", + "anim-node-plugin", + "anim-scroll", + "anim-xy" + ] + }, + "anim-base": { + "requires": [ + "base-base", + "node-style" + ] + }, + "anim-color": { + "requires": [ + "anim-base" + ] + }, + "anim-curve": { + "requires": [ + "anim-xy" + ] + }, + "anim-easing": { + "requires": [ + "anim-base" + ] + }, + "anim-node-plugin": { + "requires": [ + "node-pluginhost", + "anim-base" + ] + }, + "anim-scroll": { + "requires": [ + "anim-base" + ] + }, + "anim-shape": { + "requires": [ + "anim-base", + "anim-easing", + "anim-color", + "matrix" + ] + }, + "anim-shape-transform": { + "use": [ + "anim-shape" + ] + }, + "anim-xy": { + "requires": [ + "anim-base", + "node-screen" + ] + }, + "app": { + "use": [ + "app-base", + "app-content", + "app-transitions", + "lazy-model-list", + "model", + "model-list", + "model-sync-rest", + "router", + "view", + "view-node-map" + ] + }, + "app-base": { + "requires": [ + "classnamemanager", + "pjax-base", + "router", + "view" + ] + }, + "app-content": { + "requires": [ + "app-base", + "pjax-content" + ] + }, + "app-transitions": { + "requires": [ + "app-base" + ] + }, + "app-transitions-css": { + "type": "css" + }, + "app-transitions-native": { + "condition": { + "name": "app-transitions-native", + "test": function (Y) { + var doc = Y.config.doc, + node = doc ? doc.documentElement : null; + + if (node && node.style) { + return ('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style); + } + + return false; +}, + "trigger": "app-transitions" + }, + "requires": [ + "app-transitions", + "app-transitions-css", + "parallel", + "transition" + ] + }, + "array-extras": { + "requires": [ + "yui-base" + ] + }, + "array-invoke": { + "requires": [ + "yui-base" + ] + }, + "arraylist": { + "requires": [ + "yui-base" + ] + }, + "arraylist-add": { + "requires": [ + "arraylist" + ] + }, + "arraylist-filter": { + "requires": [ + "arraylist" + ] + }, + "arraysort": { + "requires": [ + "yui-base" + ] + }, + "async-queue": { + "requires": [ + "event-custom" + ] + }, + "attribute": { + "use": [ + "attribute-base", + "attribute-complex" + ] + }, + "attribute-base": { + "requires": [ + "attribute-core", + "attribute-observable", + "attribute-extras" + ] + }, + "attribute-complex": { + "requires": [ + "attribute-base" + ] + }, + "attribute-core": { + "requires": [ + "oop" + ] + }, + "attribute-events": { + "use": [ + "attribute-observable" + ] + }, + "attribute-extras": { + "requires": [ + "oop" + ] + }, + "attribute-observable": { + "requires": [ + "event-custom" + ] + }, + "autocomplete": { + "use": [ + "autocomplete-base", + "autocomplete-sources", + "autocomplete-list", + "autocomplete-plugin" + ] + }, + "autocomplete-base": { + "optional": [ + "autocomplete-sources" + ], + "requires": [ + "array-extras", + "base-build", + "escape", + "event-valuechange", + "node-base" + ] + }, + "autocomplete-filters": { + "requires": [ + "array-extras", + "text-wordbreak" + ] + }, + "autocomplete-filters-accentfold": { + "requires": [ + "array-extras", + "text-accentfold", + "text-wordbreak" + ] + }, + "autocomplete-highlighters": { + "requires": [ + "array-extras", + "highlight-base" + ] + }, + "autocomplete-highlighters-accentfold": { + "requires": [ + "array-extras", + "highlight-accentfold" + ] + }, + "autocomplete-list": { + "after": [ + "autocomplete-sources" + ], + "lang": [ + "en", + "es", + "it" + ], + "requires": [ + "autocomplete-base", + "event-resize", + "node-screen", + "selector-css3", + "shim-plugin", + "widget", + "widget-position", + "widget-position-align" + ], + "skinnable": true + }, + "autocomplete-list-keys": { + "condition": { + "name": "autocomplete-list-keys", + "test": function (Y) { + // Only add keyboard support to autocomplete-list if this doesn't appear to + // be an iOS or Android-based mobile device. + // + // There's currently no feasible way to actually detect whether a device has + // a hardware keyboard, so this sniff will have to do. It can easily be + // overridden by manually loading the autocomplete-list-keys module. + // + // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari + // doesn't fire the keyboard events used by AutoCompleteList, so there's + // no point loading the -keys module even when a bluetooth keyboard may be + // available. + return !(Y.UA.ios || Y.UA.android); +}, + "trigger": "autocomplete-list" + }, + "requires": [ + "autocomplete-list", + "base-build" + ] + }, + "autocomplete-plugin": { + "requires": [ + "autocomplete-list", + "node-pluginhost" + ] + }, + "autocomplete-sources": { + "optional": [ + "io-base", + "json-parse", + "jsonp", + "yql" + ], + "requires": [ + "autocomplete-base" + ] + }, + "axes": { + "use": [ + "axis-numeric", + "axis-category", + "axis-time", + "axis-stacked" + ] + }, + "axes-base": { + "use": [ + "axis-numeric-base", + "axis-category-base", + "axis-time-base", + "axis-stacked-base" + ] + }, + "axis": { + "requires": [ + "dom", + "widget", + "widget-position", + "widget-stack", + "graphics", + "axis-base" + ] + }, + "axis-base": { + "requires": [ + "classnamemanager", + "datatype-number", + "datatype-date", + "base", + "event-custom" + ] + }, + "axis-category": { + "requires": [ + "axis", + "axis-category-base" + ] + }, + "axis-category-base": { + "requires": [ + "axis-base" + ] + }, + "axis-numeric": { + "requires": [ + "axis", + "axis-numeric-base" + ] + }, + "axis-numeric-base": { + "requires": [ + "axis-base" + ] + }, + "axis-stacked": { + "requires": [ + "axis-numeric", + "axis-stacked-base" + ] + }, + "axis-stacked-base": { + "requires": [ + "axis-numeric-base" + ] + }, + "axis-time": { + "requires": [ + "axis", + "axis-time-base" + ] + }, + "axis-time-base": { + "requires": [ + "axis-base" + ] + }, + "base": { + "use": [ + "base-base", + "base-pluginhost", + "base-build" + ] + }, + "base-base": { + "requires": [ + "attribute-base", + "base-core", + "base-observable" + ] + }, + "base-build": { + "requires": [ + "base-base" + ] + }, + "base-core": { + "requires": [ + "attribute-core" + ] + }, + "base-observable": { + "requires": [ + "attribute-observable" + ] + }, + "base-pluginhost": { + "requires": [ + "base-base", + "pluginhost" + ] + }, + "button": { + "requires": [ + "button-core", + "cssbutton", + "widget" + ] + }, + "button-core": { + "requires": [ + "attribute-core", + "classnamemanager", + "node-base" + ] + }, + "button-group": { + "requires": [ + "button-plugin", + "cssbutton", + "widget" + ] + }, + "button-plugin": { + "requires": [ + "button-core", + "cssbutton", + "node-pluginhost" + ] + }, + "cache": { + "use": [ + "cache-base", + "cache-offline", + "cache-plugin" + ] + }, + "cache-base": { + "requires": [ + "base" + ] + }, + "cache-offline": { + "requires": [ + "cache-base", + "json" + ] + }, + "cache-plugin": { + "requires": [ + "plugin", + "cache-base" + ] + }, + "calendar": { + "lang": [ + "de", + "en", + "es", + "es-AR", + "fr", + "it", + "ja", + "nb-NO", + "nl", + "pt-BR", + "ru", + "zh-HANT-TW" + ], + "requires": [ + "calendar-base", + "calendarnavigator" + ], + "skinnable": true + }, + "calendar-base": { + "lang": [ + "de", + "en", + "es", + "es-AR", + "fr", + "it", + "ja", + "nb-NO", + "nl", + "pt-BR", + "ru", + "zh-HANT-TW" + ], + "requires": [ + "widget", + "datatype-date", + "datatype-date-math", + "cssgrids" + ], + "skinnable": true + }, + "calendarnavigator": { + "requires": [ + "plugin", + "classnamemanager", + "datatype-date", + "node" + ], + "skinnable": true + }, + "charts": { + "use": [ + "charts-base" + ] + }, + "charts-base": { + "requires": [ + "dom", + "event-mouseenter", + "event-touch", + "graphics-group", + "axes", + "series-pie", + "series-line", + "series-marker", + "series-area", + "series-spline", + "series-column", + "series-bar", + "series-areaspline", + "series-combo", + "series-combospline", + "series-line-stacked", + "series-marker-stacked", + "series-area-stacked", + "series-spline-stacked", + "series-column-stacked", + "series-bar-stacked", + "series-areaspline-stacked", + "series-combo-stacked", + "series-combospline-stacked" + ] + }, + "charts-legend": { + "requires": [ + "charts-base" + ] + }, + "classnamemanager": { + "requires": [ + "yui-base" + ] + }, + "clickable-rail": { + "requires": [ + "slider-base" + ] + }, + "collection": { + "use": [ + "array-extras", + "arraylist", + "arraylist-add", + "arraylist-filter", + "array-invoke" + ] + }, + "color": { + "use": [ + "color-base", + "color-hsl", + "color-harmony" + ] + }, + "color-base": { + "requires": [ + "yui-base" + ] + }, + "color-harmony": { + "requires": [ + "color-hsl" + ] + }, + "color-hsl": { + "requires": [ + "color-base" + ] + }, + "color-hsv": { + "requires": [ + "color-base" + ] + }, + "console": { + "lang": [ + "en", + "es", + "it", + "ja" + ], + "requires": [ + "yui-log", + "widget" + ], + "skinnable": true + }, + "console-filters": { + "requires": [ + "plugin", + "console" + ], + "skinnable": true + }, + "controller": { + "use": [ + "router" + ] + }, + "cookie": { + "requires": [ + "yui-base" + ] + }, + "createlink-base": { + "requires": [ + "editor-base" + ] + }, + "cssbase": { + "after": [ + "cssreset", + "cssfonts", + "cssgrids", + "cssreset-context", + "cssfonts-context", + "cssgrids-context" + ], + "type": "css" + }, + "cssbase-context": { + "after": [ + "cssreset", + "cssfonts", + "cssgrids", + "cssreset-context", + "cssfonts-context", + "cssgrids-context" + ], + "type": "css" + }, + "cssbutton": { + "type": "css" + }, + "cssfonts": { + "type": "css" + }, + "cssfonts-context": { + "type": "css" + }, + "cssgrids": { + "optional": [ + "cssreset", + "cssfonts" + ], + "type": "css" + }, + "cssgrids-base": { + "optional": [ + "cssreset", + "cssfonts" + ], + "type": "css" + }, + "cssgrids-responsive": { + "optional": [ + "cssreset", + "cssfonts" + ], + "requires": [ + "cssgrids", + "cssgrids-responsive-base" + ], + "type": "css" + }, + "cssgrids-units": { + "optional": [ + "cssreset", + "cssfonts" + ], + "requires": [ + "cssgrids-base" + ], + "type": "css" + }, + "cssnormalize": { + "type": "css" + }, + "cssnormalize-context": { + "type": "css" + }, + "cssreset": { + "type": "css" + }, + "cssreset-context": { + "type": "css" + }, + "dataschema": { + "use": [ + "dataschema-base", + "dataschema-json", + "dataschema-xml", + "dataschema-array", + "dataschema-text" + ] + }, + "dataschema-array": { + "requires": [ + "dataschema-base" + ] + }, + "dataschema-base": { + "requires": [ + "base" + ] + }, + "dataschema-json": { + "requires": [ + "dataschema-base", + "json" + ] + }, + "dataschema-text": { + "requires": [ + "dataschema-base" + ] + }, + "dataschema-xml": { + "requires": [ + "dataschema-base" + ] + }, + "datasource": { + "use": [ + "datasource-local", + "datasource-io", + "datasource-get", + "datasource-function", + "datasource-cache", + "datasource-jsonschema", + "datasource-xmlschema", + "datasource-arrayschema", + "datasource-textschema", + "datasource-polling" + ] + }, + "datasource-arrayschema": { + "requires": [ + "datasource-local", + "plugin", + "dataschema-array" + ] + }, + "datasource-cache": { + "requires": [ + "datasource-local", + "plugin", + "cache-base" + ] + }, + "datasource-function": { + "requires": [ + "datasource-local" + ] + }, + "datasource-get": { + "requires": [ + "datasource-local", + "get" + ] + }, + "datasource-io": { + "requires": [ + "datasource-local", + "io-base" + ] + }, + "datasource-jsonschema": { + "requires": [ + "datasource-local", + "plugin", + "dataschema-json" + ] + }, + "datasource-local": { + "requires": [ + "base" + ] + }, + "datasource-polling": { + "requires": [ + "datasource-local" + ] + }, + "datasource-textschema": { + "requires": [ + "datasource-local", + "plugin", + "dataschema-text" + ] + }, + "datasource-xmlschema": { + "requires": [ + "datasource-local", + "plugin", + "datatype-xml", + "dataschema-xml" + ] + }, + "datatable": { + "use": [ + "datatable-core", + "datatable-table", + "datatable-head", + "datatable-body", + "datatable-base", + "datatable-column-widths", + "datatable-message", + "datatable-mutable", + "datatable-sort", + "datatable-datasource" + ] + }, + "datatable-base": { + "requires": [ + "datatable-core", + "datatable-table", + "datatable-head", + "datatable-body", + "base-build", + "widget" + ], + "skinnable": true + }, + "datatable-body": { + "requires": [ + "datatable-core", + "view", + "classnamemanager" + ] + }, + "datatable-column-widths": { + "requires": [ + "datatable-base" + ] + }, + "datatable-core": { + "requires": [ + "escape", + "model-list", + "node-event-delegate" + ] + }, + "datatable-datasource": { + "requires": [ + "datatable-base", + "plugin", + "datasource-local" + ] + }, + "datatable-formatters": { + "requires": [ + "datatable-body", + "datatype-number-format", + "datatype-date-format", + "escape" + ] + }, + "datatable-head": { + "requires": [ + "datatable-core", + "view", + "classnamemanager" + ] + }, + "datatable-message": { + "lang": [ + "en", + "fr", + "es", + "it" + ], + "requires": [ + "datatable-base" + ], + "skinnable": true + }, + "datatable-mutable": { + "requires": [ + "datatable-base" + ] + }, + "datatable-scroll": { + "requires": [ + "datatable-base", + "datatable-column-widths", + "dom-screen" + ], + "skinnable": true + }, + "datatable-sort": { + "lang": [ + "en", + "fr", + "es" + ], + "requires": [ + "datatable-base" + ], + "skinnable": true + }, + "datatable-table": { + "requires": [ + "datatable-core", + "datatable-head", + "datatable-body", + "view", + "classnamemanager" + ] + }, + "datatype": { + "use": [ + "datatype-date", + "datatype-number", + "datatype-xml" + ] + }, + "datatype-date": { + "use": [ + "datatype-date-parse", + "datatype-date-format", + "datatype-date-math" + ] + }, + "datatype-date-format": { + "lang": [ + "ar", + "ar-JO", + "ca", + "ca-ES", + "da", + "da-DK", + "de", + "de-AT", + "de-DE", + "el", + "el-GR", + "en", + "en-AU", + "en-CA", + "en-GB", + "en-IE", + "en-IN", + "en-JO", + "en-MY", + "en-NZ", + "en-PH", + "en-SG", + "en-US", + "es", + "es-AR", + "es-BO", + "es-CL", + "es-CO", + "es-EC", + "es-ES", + "es-MX", + "es-PE", + "es-PY", + "es-US", + "es-UY", + "es-VE", + "fi", + "fi-FI", + "fr", + "fr-BE", + "fr-CA", + "fr-FR", + "hi", + "hi-IN", + "id", + "id-ID", + "it", + "it-IT", + "ja", + "ja-JP", + "ko", + "ko-KR", + "ms", + "ms-MY", + "nb", + "nb-NO", + "nl", + "nl-BE", + "nl-NL", + "pl", + "pl-PL", + "pt", + "pt-BR", + "ro", + "ro-RO", + "ru", + "ru-RU", + "sv", + "sv-SE", + "th", + "th-TH", + "tr", + "tr-TR", + "vi", + "vi-VN", + "zh-Hans", + "zh-Hans-CN", + "zh-Hant", + "zh-Hant-HK", + "zh-Hant-TW" + ] + }, + "datatype-date-math": { + "requires": [ + "yui-base" + ] + }, + "datatype-date-parse": {}, + "datatype-number": { + "use": [ + "datatype-number-parse", + "datatype-number-format" + ] + }, + "datatype-number-format": {}, + "datatype-number-parse": {}, + "datatype-xml": { + "use": [ + "datatype-xml-parse", + "datatype-xml-format" + ] + }, + "datatype-xml-format": {}, + "datatype-xml-parse": {}, + "dd": { + "use": [ + "dd-ddm-base", + "dd-ddm", + "dd-ddm-drop", + "dd-drag", + "dd-proxy", + "dd-constrain", + "dd-drop", + "dd-scroll", + "dd-delegate" + ] + }, + "dd-constrain": { + "requires": [ + "dd-drag" + ] + }, + "dd-ddm": { + "requires": [ + "dd-ddm-base", + "event-resize" + ] + }, + "dd-ddm-base": { + "requires": [ + "node", + "base", + "yui-throttle", + "classnamemanager" + ] + }, + "dd-ddm-drop": { + "requires": [ + "dd-ddm" + ] + }, + "dd-delegate": { + "requires": [ + "dd-drag", + "dd-drop-plugin", + "event-mouseenter" + ] + }, + "dd-drag": { + "requires": [ + "dd-ddm-base" + ] + }, + "dd-drop": { + "requires": [ + "dd-drag", + "dd-ddm-drop" + ] + }, + "dd-drop-plugin": { + "requires": [ + "dd-drop" + ] + }, + "dd-gestures": { + "condition": { + "name": "dd-gestures", + "trigger": "dd-drag", + "ua": "touchEnabled" + }, + "requires": [ + "dd-drag", + "event-synthetic", + "event-gestures" + ] + }, + "dd-plugin": { + "optional": [ + "dd-constrain", + "dd-proxy" + ], + "requires": [ + "dd-drag" + ] + }, + "dd-proxy": { + "requires": [ + "dd-drag" + ] + }, + "dd-scroll": { + "requires": [ + "dd-drag" + ] + }, + "dial": { + "lang": [ + "en", + "es" + ], + "requires": [ + "widget", + "dd-drag", + "event-mouseenter", + "event-move", + "event-key", + "transition", + "intl" + ], + "skinnable": true + }, + "dom": { + "use": [ + "dom-base", + "dom-screen", + "dom-style", + "selector-native", + "selector" + ] + }, + "dom-base": { + "requires": [ + "dom-core" + ] + }, + "dom-core": { + "requires": [ + "oop", + "features" + ] + }, + "dom-deprecated": { + "requires": [ + "dom-base" + ] + }, + "dom-screen": { + "requires": [ + "dom-base", + "dom-style" + ] + }, + "dom-style": { + "requires": [ + "dom-base", + "color-base" + ] + }, + "dom-style-ie": { + "condition": { + "name": "dom-style-ie", + "test": function (Y) { + + var testFeature = Y.Features.test, + addFeature = Y.Features.add, + WINDOW = Y.config.win, + DOCUMENT = Y.config.doc, + DOCUMENT_ELEMENT = 'documentElement', + ret = false; + + addFeature('style', 'computedStyle', { + test: function() { + return WINDOW && 'getComputedStyle' in WINDOW; + } + }); + + addFeature('style', 'opacity', { + test: function() { + return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style; + } + }); + + ret = (!testFeature('style', 'opacity') && + !testFeature('style', 'computedStyle')); + + return ret; +}, + "trigger": "dom-style" + }, + "requires": [ + "dom-style" + ] + }, + "dump": { + "requires": [ + "yui-base" + ] + }, + "editor": { + "use": [ + "frame", + "editor-selection", + "exec-command", + "editor-base", + "editor-para", + "editor-br", + "editor-bidi", + "editor-tab", + "createlink-base" + ] + }, + "editor-base": { + "requires": [ + "base", + "frame", + "node", + "exec-command", + "editor-selection" + ] + }, + "editor-bidi": { + "requires": [ + "editor-base" + ] + }, + "editor-br": { + "requires": [ + "editor-base" + ] + }, + "editor-lists": { + "requires": [ + "editor-base" + ] + }, + "editor-para": { + "requires": [ + "editor-para-base" + ] + }, + "editor-para-base": { + "requires": [ + "editor-base" + ] + }, + "editor-para-ie": { + "condition": { + "name": "editor-para-ie", + "trigger": "editor-para", + "ua": "ie", + "when": "instead" + }, + "requires": [ + "editor-para-base" + ] + }, + "editor-selection": { + "requires": [ + "node" + ] + }, + "editor-tab": { + "requires": [ + "editor-base" + ] + }, + "escape": { + "requires": [ + "yui-base" + ] + }, + "event": { + "after": [ + "node-base" + ], + "use": [ + "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" + ] + }, + "event-base": { + "after": [ + "node-base" + ], + "requires": [ + "event-custom-base" + ] + }, + "event-base-ie": { + "after": [ + "event-base" + ], + "condition": { + "name": "event-base-ie", + "test": function(Y) { + var imp = Y.config.doc && Y.config.doc.implementation; + return (imp && (!imp.hasFeature('Events', '2.0'))); +}, + "trigger": "node-base" + }, + "requires": [ + "node-base" + ] + }, + "event-contextmenu": { + "requires": [ + "event-synthetic", + "dom-screen" + ] + }, + "event-custom": { + "use": [ + "event-custom-base", + "event-custom-complex" + ] + }, + "event-custom-base": { + "requires": [ + "oop" + ] + }, + "event-custom-complex": { + "requires": [ + "event-custom-base" + ] + }, + "event-delegate": { + "requires": [ + "node-base" + ] + }, + "event-flick": { + "requires": [ + "node-base", + "event-touch", + "event-synthetic" + ] + }, + "event-focus": { + "requires": [ + "event-synthetic" + ] + }, + "event-gestures": { + "use": [ + "event-flick", + "event-move" + ] + }, + "event-hover": { + "requires": [ + "event-mouseenter" + ] + }, + "event-key": { + "requires": [ + "event-synthetic" + ] + }, + "event-mouseenter": { + "requires": [ + "event-synthetic" + ] + }, + "event-mousewheel": { + "requires": [ + "node-base" + ] + }, + "event-move": { + "requires": [ + "node-base", + "event-touch", + "event-synthetic" + ] + }, + "event-outside": { + "requires": [ + "event-synthetic" + ] + }, + "event-resize": { + "requires": [ + "node-base", + "event-synthetic" + ] + }, + "event-simulate": { + "requires": [ + "event-base" + ] + }, + "event-synthetic": { + "requires": [ + "node-base", + "event-custom-complex" + ] + }, + "event-tap": { + "requires": [ + "node-base", + "event-base", + "event-touch", + "event-synthetic" + ] + }, + "event-touch": { + "requires": [ + "node-base" + ] + }, + "event-valuechange": { + "requires": [ + "event-focus", + "event-synthetic" + ] + }, + "exec-command": { + "requires": [ + "frame" + ] + }, + "features": { + "requires": [ + "yui-base" + ] + }, + "file": { + "requires": [ + "file-flash", + "file-html5" + ] + }, + "file-flash": { + "requires": [ + "base" + ] + }, + "file-html5": { + "requires": [ + "base" + ] + }, + "frame": { + "requires": [ + "base", + "node", + "selector-css3", + "yui-throttle" + ] + }, + "gesture-simulate": { + "requires": [ + "async-queue", + "event-simulate", + "node-screen" + ] + }, + "get": { + "requires": [ + "yui-base" + ] + }, + "graphics": { + "requires": [ + "node", + "event-custom", + "pluginhost", + "matrix", + "classnamemanager" + ] + }, + "graphics-canvas": { + "condition": { + "name": "graphics-canvas", + "test": function(Y) { + var DOCUMENT = Y.config.doc, + useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas", + canvas = DOCUMENT && DOCUMENT.createElement("canvas"), + svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); + return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d")); +}, + "trigger": "graphics" + }, + "requires": [ + "graphics" + ] + }, + "graphics-canvas-default": { + "condition": { + "name": "graphics-canvas-default", + "test": function(Y) { + var DOCUMENT = Y.config.doc, + useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas", + canvas = DOCUMENT && DOCUMENT.createElement("canvas"), + svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); + return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d")); +}, + "trigger": "graphics" + } + }, + "graphics-group": { + "requires": [ + "graphics" + ] + }, + "graphics-svg": { + "condition": { + "name": "graphics-svg", + "test": function(Y) { + var DOCUMENT = Y.config.doc, + useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas", + canvas = DOCUMENT && DOCUMENT.createElement("canvas"), + svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); + + return svg && (useSVG || !canvas); +}, + "trigger": "graphics" + }, + "requires": [ + "graphics" + ] + }, + "graphics-svg-default": { + "condition": { + "name": "graphics-svg-default", + "test": function(Y) { + var DOCUMENT = Y.config.doc, + useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas", + canvas = DOCUMENT && DOCUMENT.createElement("canvas"), + svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); + + return svg && (useSVG || !canvas); +}, + "trigger": "graphics" + } + }, + "graphics-vml": { + "condition": { + "name": "graphics-vml", + "test": function(Y) { + var DOCUMENT = Y.config.doc, + canvas = DOCUMENT && DOCUMENT.createElement("canvas"); + return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d"))); +}, + "trigger": "graphics" + }, + "requires": [ + "graphics" + ] + }, + "graphics-vml-default": { + "condition": { + "name": "graphics-vml-default", + "test": function(Y) { + var DOCUMENT = Y.config.doc, + canvas = DOCUMENT && DOCUMENT.createElement("canvas"); + return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d"))); +}, + "trigger": "graphics" + } + }, + "handlebars": { + "use": [ + "handlebars-compiler" + ] + }, + "handlebars-base": { + "requires": [] + }, + "handlebars-compiler": { + "requires": [ + "handlebars-base" + ] + }, + "highlight": { + "use": [ + "highlight-base", + "highlight-accentfold" + ] + }, + "highlight-accentfold": { + "requires": [ + "highlight-base", + "text-accentfold" + ] + }, + "highlight-base": { + "requires": [ + "array-extras", + "classnamemanager", + "escape", + "text-wordbreak" + ] + }, + "history": { + "use": [ + "history-base", + "history-hash", + "history-hash-ie", + "history-html5" + ] + }, + "history-base": { + "requires": [ + "event-custom-complex" + ] + }, + "history-hash": { + "after": [ + "history-html5" + ], + "requires": [ + "event-synthetic", + "history-base", + "yui-later" + ] + }, + "history-hash-ie": { + "condition": { + "name": "history-hash-ie", + "test": function (Y) { + var docMode = Y.config.doc && Y.config.doc.documentMode; + + return Y.UA.ie && (!('onhashchange' in Y.config.win) || + !docMode || docMode < 8); +}, + "trigger": "history-hash" + }, + "requires": [ + "history-hash", + "node-base" + ] + }, + "history-html5": { + "optional": [ + "json" + ], + "requires": [ + "event-base", + "history-base", + "node-base" + ] + }, + "imageloader": { + "requires": [ + "base-base", + "node-style", + "node-screen" + ] + }, + "intl": { + "requires": [ + "intl-base", + "event-custom" + ] + }, + "intl-base": { + "requires": [ + "yui-base" + ] + }, + "io": { + "use": [ + "io-base", + "io-xdr", + "io-form", + "io-upload-iframe", + "io-queue" + ] + }, + "io-base": { + "requires": [ + "event-custom-base", + "querystring-stringify-simple" + ] + }, + "io-form": { + "requires": [ + "io-base", + "node-base" + ] + }, + "io-nodejs": { + "condition": { + "name": "io-nodejs", + "trigger": "io-base", + "ua": "nodejs" + }, + "requires": [ + "io-base" + ] + }, + "io-queue": { + "requires": [ + "io-base", + "queue-promote" + ] + }, + "io-upload-iframe": { + "requires": [ + "io-base", + "node-base" + ] + }, + "io-xdr": { + "requires": [ + "io-base", + "datatype-xml-parse" + ] + }, + "json": { + "use": [ + "json-parse", + "json-stringify" + ] + }, + "json-parse": { + "requires": [ + "yui-base" + ] + }, + "json-parse-shim": { + "condition": { + "name": "json-parse-shim", + "test": function (Y) { + var _JSON = Y.config.global.JSON, + Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON, + nativeSupport = Y.config.useNativeJSONParse !== false && !!Native; + + function workingNative( k, v ) { + return k === "ok" ? true : v; + } + + // Double check basic functionality. This is mainly to catch early broken + // implementations of the JSON API in Firefox 3.1 beta1 and beta2 + if ( nativeSupport ) { + try { + nativeSupport = ( Native.parse( '{"ok":false}', workingNative ) ).ok; + } + catch ( e ) { + nativeSupport = false; + } + } + + return !nativeSupport; +}, + "trigger": "json-parse" + }, + "requires": [ + "json-parse" + ] + }, + "json-stringify": { + "requires": [ + "yui-base" + ] + }, + "json-stringify-shim": { + "condition": { + "name": "json-stringify-shim", + "test": function (Y) { + var _JSON = Y.config.global.JSON, + Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON, + nativeSupport = Y.config.useNativeJSONStringify !== false && !!Native; + + // Double check basic native functionality. This is primarily to catch broken + // early JSON API implementations in Firefox 3.1 beta1 and beta2. + if ( nativeSupport ) { + try { + nativeSupport = ( '0' === Native.stringify(0) ); + } catch ( e ) { + nativeSupport = false; + } + } + + + return !nativeSupport; +}, + "trigger": "json-stringify" + }, + "requires": [ + "json-stringify" + ] + }, + "jsonp": { + "requires": [ + "get", + "oop" + ] + }, + "jsonp-url": { + "requires": [ + "jsonp" + ] + }, + "lazy-model-list": { + "requires": [ + "model-list" + ] + }, + "loader": { + "use": [ + "loader-base", + "loader-rollup", + "loader-yui3" + ] + }, + "loader-base": { + "requires": [ + "get", + "features" + ] + }, + "loader-rollup": { + "requires": [ + "loader-base" + ] + }, + "loader-yui3": { + "requires": [ + "loader-base" + ] + }, + "matrix": { + "requires": [ + "yui-base" + ] + }, + "model": { + "requires": [ + "base-build", + "escape", + "json-parse" + ] + }, + "model-list": { + "requires": [ + "array-extras", + "array-invoke", + "arraylist", + "base-build", + "escape", + "json-parse", + "model" + ] + }, + "model-sync-rest": { + "requires": [ + "model", + "io-base", + "json-stringify" + ] + }, + "node": { + "use": [ + "node-base", + "node-event-delegate", + "node-pluginhost", + "node-screen", + "node-style" + ] + }, + "node-base": { + "requires": [ + "event-base", + "node-core", + "dom-base" + ] + }, + "node-core": { + "requires": [ + "dom-core", + "selector" + ] + }, + "node-deprecated": { + "requires": [ + "node-base" + ] + }, + "node-event-delegate": { + "requires": [ + "node-base", + "event-delegate" + ] + }, + "node-event-html5": { + "requires": [ + "node-base" + ] + }, + "node-event-simulate": { + "requires": [ + "node-base", + "event-simulate", + "gesture-simulate" + ] + }, + "node-flick": { + "requires": [ + "classnamemanager", + "transition", + "event-flick", + "plugin" + ], + "skinnable": true + }, + "node-focusmanager": { + "requires": [ + "attribute", + "node", + "plugin", + "node-event-simulate", + "event-key", + "event-focus" + ] + }, + "node-load": { + "requires": [ + "node-base", + "io-base" + ] + }, + "node-menunav": { + "requires": [ + "node", + "classnamemanager", + "plugin", + "node-focusmanager" + ], + "skinnable": true + }, + "node-pluginhost": { + "requires": [ + "node-base", + "pluginhost" + ] + }, + "node-screen": { + "requires": [ + "dom-screen", + "node-base" + ] + }, + "node-scroll-info": { + "requires": [ + "base-build", + "dom-screen", + "event-resize", + "node-pluginhost", + "plugin" + ] + }, + "node-style": { + "requires": [ + "dom-style", + "node-base" + ] + }, + "oop": { + "requires": [ + "yui-base" + ] + }, + "overlay": { + "requires": [ + "widget", + "widget-stdmod", + "widget-position", + "widget-position-align", + "widget-stack", + "widget-position-constrain" + ], + "skinnable": true + }, + "panel": { + "requires": [ + "widget", + "widget-autohide", + "widget-buttons", + "widget-modality", + "widget-position", + "widget-position-align", + "widget-position-constrain", + "widget-stack", + "widget-stdmod" + ], + "skinnable": true + }, + "parallel": { + "requires": [ + "yui-base" + ] + }, + "pjax": { + "requires": [ + "pjax-base", + "pjax-content" + ] + }, + "pjax-base": { + "requires": [ + "classnamemanager", + "node-event-delegate", + "router" + ] + }, + "pjax-content": { + "requires": [ + "io-base", + "node-base", + "router" + ] + }, + "pjax-plugin": { + "requires": [ + "node-pluginhost", + "pjax", + "plugin" + ] + }, + "plugin": { + "requires": [ + "base-base" + ] + }, + "pluginhost": { + "use": [ + "pluginhost-base", + "pluginhost-config" + ] + }, + "pluginhost-base": { + "requires": [ + "yui-base" + ] + }, + "pluginhost-config": { + "requires": [ + "pluginhost-base" + ] + }, + "promise": { + "requires": [ + "timers" + ] + }, + "querystring": { + "use": [ + "querystring-parse", + "querystring-stringify" + ] + }, + "querystring-parse": { + "requires": [ + "yui-base", + "array-extras" + ] + }, + "querystring-parse-simple": { + "requires": [ + "yui-base" + ] + }, + "querystring-stringify": { + "requires": [ + "yui-base" + ] + }, + "querystring-stringify-simple": { + "requires": [ + "yui-base" + ] + }, + "queue-promote": { + "requires": [ + "yui-base" + ] + }, + "range-slider": { + "requires": [ + "slider-base", + "slider-value-range", + "clickable-rail" + ] + }, + "recordset": { + "use": [ + "recordset-base", + "recordset-sort", + "recordset-filter", + "recordset-indexer" + ] + }, + "recordset-base": { + "requires": [ + "base", + "arraylist" + ] + }, + "recordset-filter": { + "requires": [ + "recordset-base", + "array-extras", + "plugin" + ] + }, + "recordset-indexer": { + "requires": [ + "recordset-base", + "plugin" + ] + }, + "recordset-sort": { + "requires": [ + "arraysort", + "recordset-base", + "plugin" + ] + }, + "resize": { + "use": [ + "resize-base", + "resize-proxy", + "resize-constrain" + ] + }, + "resize-base": { + "requires": [ + "base", + "widget", + "event", + "oop", + "dd-drag", + "dd-delegate", + "dd-drop" + ], + "skinnable": true + }, + "resize-constrain": { + "requires": [ + "plugin", + "resize-base" + ] + }, + "resize-plugin": { + "optional": [ + "resize-constrain" + ], + "requires": [ + "resize-base", + "plugin" + ] + }, + "resize-proxy": { + "requires": [ + "plugin", + "resize-base" + ] + }, + "router": { + "optional": [ + "querystring-parse" + ], + "requires": [ + "array-extras", + "base-build", + "history" + ] + }, + "scrollview": { + "requires": [ + "scrollview-base", + "scrollview-scrollbars" + ] + }, + "scrollview-base": { + "requires": [ + "widget", + "event-gestures", + "event-mousewheel", + "transition" + ], + "skinnable": true + }, + "scrollview-base-ie": { + "condition": { + "name": "scrollview-base-ie", + "trigger": "scrollview-base", + "ua": "ie" + }, + "requires": [ + "scrollview-base" + ] + }, + "scrollview-list": { + "requires": [ + "plugin", + "classnamemanager" + ], + "skinnable": true + }, + "scrollview-paginator": { + "requires": [ + "plugin", + "classnamemanager" + ] + }, + "scrollview-scrollbars": { + "requires": [ + "classnamemanager", + "transition", + "plugin" + ], + "skinnable": true + }, + "selector": { + "requires": [ + "selector-native" + ] + }, + "selector-css2": { + "condition": { + "name": "selector-css2", + "test": function (Y) { + var DOCUMENT = Y.config.doc, + ret = DOCUMENT && !('querySelectorAll' in DOCUMENT); + + return ret; +}, + "trigger": "selector" + }, + "requires": [ + "selector-native" + ] + }, + "selector-css3": { + "requires": [ + "selector-native", + "selector-css2" + ] + }, + "selector-native": { + "requires": [ + "dom-base" + ] + }, + "series-area": { + "requires": [ + "series-cartesian", + "series-fill-util" + ] + }, + "series-area-stacked": { + "requires": [ + "series-stacked", + "series-area" + ] + }, + "series-areaspline": { + "requires": [ + "series-area", + "series-curve-util" + ] + }, + "series-areaspline-stacked": { + "requires": [ + "series-stacked", + "series-areaspline" + ] + }, + "series-bar": { + "requires": [ + "series-marker", + "series-histogram-base" + ] + }, + "series-bar-stacked": { + "requires": [ + "series-stacked", + "series-bar" + ] + }, + "series-base": { + "requires": [ + "graphics", + "axis-base" + ] + }, + "series-candlestick": { + "requires": [ + "series-range" + ] + }, + "series-cartesian": { + "requires": [ + "series-base" + ] + }, + "series-column": { + "requires": [ + "series-marker", + "series-histogram-base" + ] + }, + "series-column-stacked": { + "requires": [ + "series-stacked", + "series-column" + ] + }, + "series-combo": { + "requires": [ + "series-cartesian", + "series-line-util", + "series-plot-util", + "series-fill-util" + ] + }, + "series-combo-stacked": { + "requires": [ + "series-stacked", + "series-combo" + ] + }, + "series-combospline": { + "requires": [ + "series-combo", + "series-curve-util" + ] + }, + "series-combospline-stacked": { + "requires": [ + "series-combo-stacked", + "series-curve-util" + ] + }, + "series-curve-util": {}, + "series-fill-util": {}, + "series-histogram-base": { + "requires": [ + "series-cartesian", + "series-plot-util" + ] + }, + "series-line": { + "requires": [ + "series-cartesian", + "series-line-util" + ] + }, + "series-line-stacked": { + "requires": [ + "series-stacked", + "series-line" + ] + }, + "series-line-util": {}, + "series-marker": { + "requires": [ + "series-cartesian", + "series-plot-util" + ] + }, + "series-marker-stacked": { + "requires": [ + "series-stacked", + "series-marker" + ] + }, + "series-ohlc": { + "requires": [ + "series-range" + ] + }, + "series-pie": { + "requires": [ + "series-base", + "series-plot-util" + ] + }, + "series-plot-util": {}, + "series-range": { + "requires": [ + "series-cartesian" + ] + }, + "series-spline": { + "requires": [ + "series-line", + "series-curve-util" + ] + }, + "series-spline-stacked": { + "requires": [ + "series-stacked", + "series-spline" + ] + }, + "series-stacked": { + "requires": [ + "axis-stacked" + ] + }, + "shim-plugin": { + "requires": [ + "node-style", + "node-pluginhost" + ] + }, + "slider": { + "use": [ + "slider-base", + "slider-value-range", + "clickable-rail", + "range-slider" + ] + }, + "slider-base": { + "requires": [ + "widget", + "dd-constrain", + "event-key" + ], + "skinnable": true + }, + "slider-value-range": { + "requires": [ + "slider-base" + ] + }, + "sortable": { + "requires": [ + "dd-delegate", + "dd-drop-plugin", + "dd-proxy" + ] + }, + "sortable-scroll": { + "requires": [ + "dd-scroll", + "sortable" + ] + }, + "stylesheet": { + "requires": [ + "yui-base" + ] + }, + "substitute": { + "optional": [ + "dump" + ], + "requires": [ + "yui-base" + ] + }, + "swf": { + "requires": [ + "event-custom", + "node", + "swfdetect", + "escape" + ] + }, + "swfdetect": { + "requires": [ + "yui-base" + ] + }, + "tabview": { + "requires": [ + "widget", + "widget-parent", + "widget-child", + "tabview-base", + "node-pluginhost", + "node-focusmanager" + ], + "skinnable": true + }, + "tabview-base": { + "requires": [ + "node-event-delegate", + "classnamemanager" + ] + }, + "tabview-plugin": { + "requires": [ + "tabview-base" + ] + }, + "template": { + "use": [ + "template-base", + "template-micro" + ] + }, + "template-base": { + "requires": [ + "yui-base" + ] + }, + "template-micro": { + "requires": [ + "escape" + ] + }, + "test": { + "requires": [ + "event-simulate", + "event-custom", + "json-stringify" + ] + }, + "test-console": { + "requires": [ + "console-filters", + "test", + "array-extras" + ], + "skinnable": true + }, + "text": { + "use": [ + "text-accentfold", + "text-wordbreak" + ] + }, + "text-accentfold": { + "requires": [ + "array-extras", + "text-data-accentfold" + ] + }, + "text-data-accentfold": { + "requires": [ + "yui-base" + ] + }, + "text-data-wordbreak": { + "requires": [ + "yui-base" + ] + }, + "text-wordbreak": { + "requires": [ + "array-extras", + "text-data-wordbreak" + ] + }, + "timers": { + "requires": [ + "yui-base" + ] + }, + "transition": { + "requires": [ + "node-style" + ] + }, + "transition-timer": { + "condition": { + "name": "transition-timer", + "test": function (Y) { + var DOCUMENT = Y.config.doc, + node = (DOCUMENT) ? DOCUMENT.documentElement: null, + ret = true; + + if (node && node.style) { + ret = !('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style); + } + + return ret; +}, + "trigger": "transition" + }, + "requires": [ + "transition" + ] + }, + "tree": { + "requires": [ + "base-build", + "tree-node" + ] + }, + "tree-labelable": { + "requires": [ + "tree" + ] + }, + "tree-lazy": { + "requires": [ + "base-pluginhost", + "plugin", + "tree" + ] + }, + "tree-node": {}, + "tree-openable": { + "requires": [ + "tree" + ] + }, + "tree-selectable": { + "requires": [ + "tree" + ] + }, + "tree-sortable": { + "requires": [ + "tree" + ] + }, + "uploader": { + "requires": [ + "uploader-html5", + "uploader-flash" + ] + }, + "uploader-flash": { + "requires": [ + "swf", + "widget", + "base", + "cssbutton", + "node", + "event-custom", + "file-flash", + "uploader-queue" + ] + }, + "uploader-html5": { + "requires": [ + "widget", + "node-event-simulate", + "file-html5", + "uploader-queue" + ] + }, + "uploader-queue": { + "requires": [ + "base" + ] + }, + "view": { + "requires": [ + "base-build", + "node-event-delegate" + ] + }, + "view-node-map": { + "requires": [ + "view" + ] + }, + "widget": { + "use": [ + "widget-base", + "widget-htmlparser", + "widget-skin", + "widget-uievents" + ] + }, + "widget-anim": { + "requires": [ + "anim-base", + "plugin", + "widget" + ] + }, + "widget-autohide": { + "requires": [ + "base-build", + "event-key", + "event-outside", + "widget" + ] + }, + "widget-base": { + "requires": [ + "attribute", + "base-base", + "base-pluginhost", + "classnamemanager", + "event-focus", + "node-base", + "node-style" + ], + "skinnable": true + }, + "widget-base-ie": { + "condition": { + "name": "widget-base-ie", + "trigger": "widget-base", + "ua": "ie" + }, + "requires": [ + "widget-base" + ] + }, + "widget-buttons": { + "requires": [ + "button-plugin", + "cssbutton", + "widget-stdmod" + ] + }, + "widget-child": { + "requires": [ + "base-build", + "widget" + ] + }, + "widget-htmlparser": { + "requires": [ + "widget-base" + ] + }, + "widget-locale": { + "requires": [ + "widget-base" + ] + }, + "widget-modality": { + "requires": [ + "base-build", + "event-outside", + "widget" + ], + "skinnable": true + }, + "widget-parent": { + "requires": [ + "arraylist", + "base-build", + "widget" + ] + }, + "widget-position": { + "requires": [ + "base-build", + "node-screen", + "widget" + ] + }, + "widget-position-align": { + "requires": [ + "widget-position" + ] + }, + "widget-position-constrain": { + "requires": [ + "widget-position" + ] + }, + "widget-skin": { + "requires": [ + "widget-base" + ] + }, + "widget-stack": { + "requires": [ + "base-build", + "widget" + ], + "skinnable": true + }, + "widget-stdmod": { + "requires": [ + "base-build", + "widget" + ] + }, + "widget-uievents": { + "requires": [ + "node-event-delegate", + "widget-base" + ] + }, + "yql": { + "requires": [ + "oop" + ] + }, + "yql-jsonp": { + "condition": { + "name": "yql-jsonp", + "test": function (Y) { + /* Only load the JSONP module when not in nodejs or winjs + TODO Make the winjs module a CORS module + */ + return (!Y.UA.nodejs && !Y.UA.winjs); +}, + "trigger": "yql", + "when": "after" + }, + "requires": [ + "jsonp", + "jsonp-url" + ] + }, + "yql-nodejs": { + "condition": { + "name": "yql-nodejs", + "trigger": "yql", + "ua": "nodejs", + "when": "after" + } + }, + "yql-winjs": { + "condition": { + "name": "yql-winjs", + "trigger": "yql", + "ua": "winjs", + "when": "after" + } + }, + "yui": {}, + "yui-base": {}, + "yui-later": { + "requires": [ + "yui-base" + ] + }, + "yui-log": { + "requires": [ + "yui-base" + ] + }, + "yui-throttle": { + "requires": [ + "yui-base" + ] + } +}); +YUI.Env[Y.version].md5 = 'd7ced98e3907d3c3c0655a93c6ac6867'; + + +}, '3.10.3', {"requires": ["loader-base"]}); +YUI.add('yui', function (Y, NAME) {}, '3.10.3', { + "use": [ + "get", + "features", + "intl-base", + "yui-log", + "yui-log-nodejs", + "yui-later", + "loader-base", + "loader-rollup", + "loader-yui3" + ] +});