text: YUI.add('dom-base', function(Y) {
  
  var documentElement = Y.config.doc.documentElement,
      Y_DOM = Y.DOM,
      TAG_NAME = 'tagName',
      OWNER_DOCUMENT = 'ownerDocument',
      EMPTY_STRING = '',
      addFeature = Y.Features.add,
      testFeature = Y.Features.test;
  
  Y.mix(Y_DOM, {
      /**
       * Returns the text content of the HTMLElement. 
       * @method getText         
       * @param {HTMLElement} element The html element. 
       * @return {String} The text content of the element (includes text of any descending elements).
       */
      getText: (documentElement.textContent !== undefined) ?
          function(element) {
              var ret = '';
              if (element) {
                  ret = element.textContent;
              }
              return ret || '';
          } : function(element) {
              var ret = '';
              if (element) {
                  ret = element.innerText || element.nodeValue; // might be a textNode
              }
              return ret || '';
          },
  
      /**
       * Sets the text content of the HTMLElement. 
       * @method setText         
       * @param {HTMLElement} element The html element. 
       * @param {String} content The content to add. 
       */
      setText: (documentElement.textContent !== undefined) ?
          function(element, content) {
              if (element) {
                  element.textContent = content;
              }
          } : function(element, content) {
              if ('innerText' in element) {
                  element.innerText = content;
              } else if ('nodeValue' in element) {
                  element.nodeValue = content;
              }
      },
  
      CUSTOM_ATTRIBUTES: (!documentElement.hasAttribute) ? { // IE < 8
          'for': 'htmlFor',
          'class': 'className'
      } : { // w3c
          'htmlFor': 'for',
          'className': 'class'
      },
  
      /**
       * Provides a normalized attribute interface. 
       * @method setAttribute
       * @param {HTMLElement} el The target element for the attribute.
       * @param {String} attr The attribute to set.
       * @param {String} val The value of the attribute.
       */
      setAttribute: function(el, attr, val, ieAttr) {
          if (el && attr && el.setAttribute) {
              attr = Y_DOM.CUSTOM_ATTRIBUTES[attr] || attr;
              el.setAttribute(attr, val, ieAttr);
          }
          else { Y.log('bad input to setAttribute', 'warn', 'dom'); }
      },
  
  
      /**
       * Provides a normalized attribute interface. 
       * @method getAttibute
       * @param {HTMLElement} el The target element for the attribute.
       * @param {String} attr The attribute to get.
       * @return {String} The current value of the attribute. 
       */
      getAttribute: function(el, attr, ieAttr) {
          ieAttr = (ieAttr !== undefined) ? ieAttr : 2;
          var ret = '';
          if (el && attr && el.getAttribute) {
              attr = Y_DOM.CUSTOM_ATTRIBUTES[attr] || attr;
              ret = el.getAttribute(attr, ieAttr);
  
              if (ret === null) {
                  ret = ''; // per DOM spec
              }
          }
          else { Y.log('bad input to getAttribute', 'warn', 'dom'); }
          return ret;
      },
  
      VALUE_SETTERS: {},
  
      VALUE_GETTERS: {},
  
      getValue: function(node) {
          var ret = '', // TODO: return null?
              getter;
  
          if (node && node[TAG_NAME]) {
              getter = Y_DOM.VALUE_GETTERS[node[TAG_NAME].toLowerCase()];
  
              if (getter) {
                  ret = getter(node);
              } else {
                  ret = node.value;
              }
          }
  
          // workaround for IE8 JSON stringify bug
          // which converts empty string values to null
          if (ret === EMPTY_STRING) {
              ret = EMPTY_STRING; // for real
          }
  
          return (typeof ret === 'string') ? ret : '';
      },
  
      setValue: function(node, val) {
          var setter;
  
          if (node && node[TAG_NAME]) {
              setter = Y_DOM.VALUE_SETTERS[node[TAG_NAME].toLowerCase()];
  
              if (setter) {
                  setter(node, val);
              } else {
                  node.value = val;
              }
          }
      },
  
      creators: {}
  });
  
  addFeature('value-set', 'select', {
      test: function() {
          var node = Y.config.doc.createElement('select');
          node.innerHTML = '<option>1</option><option>2</option>';
          node.value = '2';
          return (node.value && node.value === '2');
      }
  });
  
  if (!testFeature('value-set', 'select')) {
      Y_DOM.VALUE_SETTERS.select = function(node, val) {
          for (var i = 0, options = node.getElementsByTagName('option'), option;
                  option = options[i++];) {
              if (Y_DOM.getValue(option) === val) {
                  option.selected = true;
                  //Y_DOM.setAttribute(option, 'selected', 'selected');
                  break;
              }
          }
      }
  }
  
  Y.mix(Y_DOM.VALUE_GETTERS, {
      button: function(node) {
          return (node.attributes && node.attributes.value) ? node.attributes.value.value : '';
      }
  });
  
  Y.mix(Y_DOM.VALUE_SETTERS, {
      // IE: node.value changes the button text, which should be handled via innerHTML
      button: function(node, val) {
          var attr = node.attributes.value;
          if (!attr) {
              attr = node[OWNER_DOCUMENT].createAttribute('value');
              node.setAttributeNode(attr);
          }
  
          attr.value = val;
      }
  });
  
  
  Y.mix(Y_DOM.VALUE_GETTERS, {
      option: function(node) {
          var attrs = node.attributes;
          return (attrs.value && attrs.value.specified) ? node.value : node.text;
      },
  
      select: function(node) {
          var val = node.value,
              options = node.options;
  
          if (options && options.length) {
              // TODO: implement multipe select
              if (node.multiple) {
                  Y.log('multiple select normalization not implemented', 'warn', 'DOM');
              } else {
                  val = Y_DOM.getValue(options[node.selectedIndex]);
              }
          }
  
          return val;
      }
  });
  var addClass, hasClass, removeClass;
  
  Y.mix(Y.DOM, {
      /**
       * Determines whether a DOM element has the given className.
       * @method hasClass
       * @for DOM
       * @param {HTMLElement} element The DOM element. 
       * @param {String} className the class name to search for
       * @return {Boolean} Whether or not the element has the given class. 
       */
      hasClass: function(node, className) {
          var re = Y.DOM._getRegExp('(?:^|\\s+)' + className + '(?:\\s+|$)');
          return re.test(node.className);
      },
  
      /**
       * Adds a class name to a given DOM element.
       * @method addClass         
       * @for DOM
       * @param {HTMLElement} element The DOM element. 
       * @param {String} className the class name to add to the class attribute
       */
      addClass: function(node, className) {
          if (!Y.DOM.hasClass(node, className)) { // skip if already present 
              node.className = Y.Lang.trim([node.className, className].join(' '));
          }
      },
  
      /**
       * Removes a class name from a given element.
       * @method removeClass         
       * @for DOM
       * @param {HTMLElement} element The DOM element. 
       * @param {String} className the class name to remove from the class attribute
       */
      removeClass: function(node, className) {
          if (className && hasClass(node, className)) {
              node.className = Y.Lang.trim(node.className.replace(Y.DOM._getRegExp('(?:^|\\s+)' +
                              className + '(?:\\s+|$)'), ' '));
  
              if ( hasClass(node, className) ) { // in case of multiple adjacent
                  removeClass(node, className);
              }
          }                 
      },
  
      /**
       * Replace a class with another class for a given element.
       * If no oldClassName is present, the newClassName is simply added.
       * @method replaceClass  
       * @for DOM
       * @param {HTMLElement} element The DOM element 
       * @param {String} oldClassName the class name to be replaced
       * @param {String} newClassName the class name that will be replacing the old class name
       */
      replaceClass: function(node, oldC, newC) {
          //Y.log('replaceClass replacing ' + oldC + ' with ' + newC, 'info', 'Node');
          removeClass(node, oldC); // remove first in case oldC === newC
          addClass(node, newC);
      },
  
      /**
       * If the className exists on the node it is removed, if it doesn't exist it is added.
       * @method toggleClass  
       * @for DOM
       * @param {HTMLElement} element The DOM element
       * @param {String} className the class name to be toggled
       * @param {Boolean} addClass optional boolean to indicate whether class
       * should be added or removed regardless of current state
       */
      toggleClass: function(node, className, force) {
          var add = (force !== undefined) ? force :
                  !(hasClass(node, className));
  
          if (add) {
              addClass(node, className);
          } else {
              removeClass(node, className);
          }
      }
  });
  
  hasClass = Y.DOM.hasClass;
  removeClass = Y.DOM.removeClass;
  addClass = Y.DOM.addClass;
  
  var re_tag = /<([a-z]+)/i,
  
      Y_DOM = Y.DOM,
  
      addFeature = Y.Features.add,
      testFeature = Y.Features.test,
  
      creators = {},
  
      createFromDIV = function(html, tag) {
          var div = Y.config.doc.createElement('div'),
              ret = true;
  
          div.innerHTML = html;
          if (!div.firstChild || div.firstChild.tagName !== tag.toUpperCase()) {
              ret = false;
          }
  
          return ret;
      },
  
      re_tbody = /(?:\/(?:thead|tfoot|tbody|caption|col|colgroup)>)+\s*<tbody/,
  
      TABLE_OPEN = '<table>',
      TABLE_CLOSE = '</table>';
  
  Y.mix(Y.DOM, {
      _fragClones: {},
  
      _create: function(html, doc, tag) {
          tag = tag || 'div';
  
          var frag = Y_DOM._fragClones[tag];
          if (frag) {
              frag = frag.cloneNode(false);
          } else {
              frag = Y_DOM._fragClones[tag] = doc.createElement(tag);
          }
          frag.innerHTML = html;
          return frag;
      },
  
      /**
       * Creates a new dom node using the provided markup string. 
       * @method create
       * @param {String} html The markup used to create the element
       * @param {HTMLDocument} doc An optional document context 
       * @return {HTMLElement|DocumentFragment} returns a single HTMLElement 
       * when creating one node, and a documentFragment when creating
       * multiple nodes.
       */
      create: function(html, doc) {
          if (typeof html === 'string') {
              html = Y.Lang.trim(html); // match IE which trims whitespace from innerHTML
  
          }
  
          doc = doc || Y.config.doc;
          var m = re_tag.exec(html),
              create = Y_DOM._create,
              custom = creators,
              ret = null,
              creator,
              tag, nodes;
  
          if (html != undefined) { // not undefined or null
              if (m && m[1]) {
                  creator = custom[m[1].toLowerCase()];
                  if (typeof creator === 'function') {
                      create = creator; 
                  } else {
                      tag = creator;
                  }
              }
  
              nodes = create(html, doc, tag).childNodes;
  
              if (nodes.length === 1) { // return single node, breaking parentNode ref from "fragment"
                  ret = nodes[0].parentNode.removeChild(nodes[0]);
              } else if (nodes[0] && nodes[0].className === 'yui3-big-dummy') { // using dummy node to preserve some attributes (e.g. OPTION not selected)
                  if (nodes.length === 2) {
                      ret = nodes[0].nextSibling;
                  } else {
                      nodes[0].parentNode.removeChild(nodes[0]); 
                       ret = Y_DOM._nl2frag(nodes, doc);
                  }
              } else { // return multiple nodes as a fragment
                   ret = Y_DOM._nl2frag(nodes, doc);
              }
          }
  
          return ret;
      },
  
      _nl2frag: function(nodes, doc) {
          var ret = null,
              i, len;
  
          if (nodes && (nodes.push || nodes.item) && nodes[0]) {
              doc = doc || nodes[0].ownerDocument; 
              ret = doc.createDocumentFragment();
  
              if (nodes.item) { // convert live list to static array
                  nodes = Y.Array(nodes, 0, true);
              }
  
              for (i = 0, len = nodes.length; i < len; i++) {
                  ret.appendChild(nodes[i]); 
              }
          } // else inline with log for minification
          else { Y.log('unable to convert ' + nodes + ' to fragment', 'warn', 'dom'); }
          return ret;
      },
  
      /**
       * Inserts content in a node at the given location 
       * @method addHTML
       * @param {HTMLElement} node The node to insert into
       * @param {HTMLElement | Array | HTMLCollection} content The content to be inserted 
       * @param {HTMLElement} where Where to insert the content
       * If no "where" is given, content is appended to the node
       * Possible values for "where"
       * <dl>
       * <dt>HTMLElement</dt>
       * <dd>The element to insert before</dd>
       * <dt>"replace"</dt>
       * <dd>Replaces the existing HTML</dd>
       * <dt>"before"</dt>
       * <dd>Inserts before the existing HTML</dd>
       * <dt>"before"</dt>
       * <dd>Inserts content before the node</dd>
       * <dt>"after"</dt>
       * <dd>Inserts content after the node</dd>
       * </dl>
       */
      addHTML: function(node, content, where) {
          var nodeParent = node.parentNode,
              i = 0,
              item,
              ret = content,
              newNode;
              
  
          if (content != undefined) { // not null or undefined (maybe 0)
              if (content.nodeType) { // DOM node, just add it
                  newNode = content;
              } else if (typeof content == 'string' || typeof content == 'number') {
                  ret = newNode = Y_DOM.create(content);
              } else if (content[0] && content[0].nodeType) { // array or collection 
                  newNode = Y.config.doc.createDocumentFragment();
                  while ((item = content[i++])) {
                      newNode.appendChild(item); // append to fragment for insertion
                  }
              }
          }
  
          if (where) {
              if (where.nodeType) { // insert regardless of relationship to node
                  where.parentNode.insertBefore(newNode, where);
              } else {
                  switch (where) {
                      case 'replace':
                          while (node.firstChild) {
                              node.removeChild(node.firstChild);
                          }
                          if (newNode) { // allow empty content to clear node
                              node.appendChild(newNode);
                          }
                          break;
                      case 'before':
                          nodeParent.insertBefore(newNode, node);
                          break;
                      case 'after':
                          if (node.nextSibling) { // IE errors if refNode is null
                              nodeParent.insertBefore(newNode, node.nextSibling);
                          } else {
                              nodeParent.appendChild(newNode);
                          }
                          break;
                      default:
                          node.appendChild(newNode);
                  }
              }
          } else if (newNode) {
              node.appendChild(newNode);
          }
  
          return ret;
      }
  });
  
  addFeature('innerhtml', 'table', {
      test: function() {
          var node = Y.config.doc.createElement('table');
          try {
              node.innerHTML = '<tbody></tbody>';
          } catch(e) {
              return false;
          }
          return (node.firstChild && node.firstChild.nodeName === 'TBODY');
      }
  });
  
  addFeature('innerhtml-div', 'tr', {
      test: function() {
          return createFromDIV('<tr></tr>', 'tr');
      }
  });
  
  addFeature('innerhtml-div', 'script', {
      test: function() {
          return createFromDIV('<script></script>', 'script');
      }
  });
  
  if (!testFeature('innerhtml', 'table')) {
      // TODO: thead/tfoot with nested tbody
          // IE adds TBODY when creating TABLE elements (which may share this impl)
      creators.tbody = function(html, doc) {
          var frag = Y_DOM.create(TABLE_OPEN + html + TABLE_CLOSE, doc),
              tb = frag.children.tags('tbody')[0];
  
          if (frag.children.length > 1 && tb && !re_tbody.test(html)) {
              tb.parentNode.removeChild(tb); // strip extraneous tbody
          }
          return frag;
      };
  }
  
  if (!testFeature('innerhtml-div', 'script')) {
      creators.script = function(html, doc) {
          var frag = doc.createElement('div');
  
          frag.innerHTML = '-' + html;
          frag.removeChild(frag.firstChild);
          return frag;
      }
  
      creators.link = creators.style = creators.script;
  }
  
  if (!testFeature('innerhtml-div', 'tr')) {
      Y.mix(creators, {
          option: function(html, doc) {
              return Y_DOM.create('<select><option class="yui3-big-dummy" selected></option>' + html + '</select>', doc);
          },
  
          tr: function(html, doc) {
              return Y_DOM.create('<tbody>' + html + '</tbody>', doc);
          },
  
          td: function(html, doc) {
              return Y_DOM.create('<tr>' + html + '</tr>', doc);
          }, 
  
          col: function(html, doc) {
              return Y_DOM.create('<colgroup>' + html + '</colgroup>', doc);
          }, 
  
          tbody: 'table'
      });
  
      Y.mix(creators, {
          legend: 'fieldset',
          th: creators.td,
          thead: creators.tbody,
          tfoot: creators.tbody,
          caption: creators.tbody,
          colgroup: creators.tbody,
          optgroup: creators.option
      });
  }
  
  Y_DOM.creators = creators;
  Y.mix(Y.DOM, {
      /**
       * Sets the width of the element to the given size, regardless
       * of box model, border, padding, etc.
       * @method setWidth
       * @param {HTMLElement} element The DOM element. 
       * @param {String|Int} size The pixel height to size to
       */
  
      setWidth: function(node, size) {
          Y.DOM._setSize(node, 'width', size);
      },
  
      /**
       * Sets the height of the element to the given size, regardless
       * of box model, border, padding, etc.
       * @method setHeight
       * @param {HTMLElement} element The DOM element. 
       * @param {String|Int} size The pixel height to size to
       */
  
      setHeight: function(node, size) {
          Y.DOM._setSize(node, 'height', size);
      },
  
      _setSize: function(node, prop, val) {
          val = (val > 0) ? val : 0;
          var size = 0;
  
          node.style[prop] = val + 'px';
          size = (prop === 'height') ? node.offsetHeight : node.offsetWidth;
  
          if (size > val) {
              val = val - (size - val);
  
              if (val < 0) {
                  val = 0;
              }
  
              node.style[prop] = val + 'px';
          }
      }
  });
  
  
  }, '@VERSION@' ,{requires:['dom-core']});
  YUI.add('dom-style', function(Y) {
  
  (function(Y) {
  /** 
   * Add style management functionality to DOM.
   * @module dom
   * @submodule dom-style
   * @for DOM
   */
  
  var DOCUMENT_ELEMENT = 'documentElement',
      DEFAULT_VIEW = 'defaultView',
      OWNER_DOCUMENT = 'ownerDocument',
      STYLE = 'style',
      FLOAT = 'float',
      CSS_FLOAT = 'cssFloat',
      STYLE_FLOAT = 'styleFloat',
      TRANSPARENT = 'transparent',
      GET_COMPUTED_STYLE = 'getComputedStyle',
      GET_BOUNDING_CLIENT_RECT = 'getBoundingClientRect',
  
      WINDOW = Y.config.win,
      DOCUMENT = Y.config.doc,
      UNDEFINED = undefined,
  
      Y_DOM = Y.DOM,
  
      TRANSFORM = 'transform',
      VENDOR_TRANSFORM = [
          'WebkitTransform',
          'MozTransform',
          'OTransform'
      ],
  
      re_color = /color$/i,
      re_unit = /width|height|top|left|right|bottom|margin|padding/i;
  
  Y.Array.each(VENDOR_TRANSFORM, function(val) {
      if (val in DOCUMENT[DOCUMENT_ELEMENT].style) {
          TRANSFORM = val;
      }
  });
  
  Y.mix(Y_DOM, {
      DEFAULT_UNIT: 'px',
  
      CUSTOM_STYLES: {
      },
  
  
      /**
       * Sets a style property for a given element.
       * @method setStyle
       * @param {HTMLElement} An HTMLElement to apply the style to.
       * @param {String} att The style property to set. 
       * @param {String|Number} val The value. 
       */
      setStyle: function(node, att, val, style) {
          style = style || node.style;
          var CUSTOM_STYLES = Y_DOM.CUSTOM_STYLES;
  
          if (style) {
              if (val === null || val === '') { // normalize unsetting
                  val = '';
              } else if (!isNaN(new Number(val)) && re_unit.test(att)) { // number values may need a unit
                  val += Y_DOM.DEFAULT_UNIT;
              }
  
              if (att in CUSTOM_STYLES) {
                  if (CUSTOM_STYLES[att].set) {
                      CUSTOM_STYLES[att].set(node, val, style);
                      return; // NOTE: return
                  } else if (typeof CUSTOM_STYLES[att] === 'string') {
                      att = CUSTOM_STYLES[att];
                  }
              } else if (att === '') { // unset inline styles
                  att = 'cssText';
                  val = '';
              }
              style[att] = val; 
          }
      },
  
      /**
       * Returns the current style value for the given property.
       * @method getStyle
       * @param {HTMLElement} An HTMLElement to get the style from.
       * @param {String} att The style property to get. 
       */
      getStyle: function(node, att, style) {
          style = style || node.style;
          var CUSTOM_STYLES = Y_DOM.CUSTOM_STYLES,
              val = '';
  
          if (style) {
              if (att in CUSTOM_STYLES) {
                  if (CUSTOM_STYLES[att].get) {
                      return CUSTOM_STYLES[att].get(node, att, style); // NOTE: return
                  } else if (typeof CUSTOM_STYLES[att] === 'string') {
                      att = CUSTOM_STYLES[att];
                  }
              }
              val = style[att];
              if (val === '') { // TODO: is empty string sufficient?
                  val = Y_DOM[GET_COMPUTED_STYLE](node, att);
              }
          }
  
          return val;
      },
  
      /**
       * Sets multiple style properties.
       * @method setStyles
       * @param {HTMLElement} node An HTMLElement to apply the styles to. 
       * @param {Object} hash An object literal of property:value pairs. 
       */
      setStyles: function(node, hash) {
          var style = node.style;
          Y.each(hash, function(v, n) {
              Y_DOM.setStyle(node, n, v, style);
          }, Y_DOM);
      },
  
      /**
       * Returns the computed style for the given node.
       * @method getComputedStyle
       * @param {HTMLElement} An HTMLElement to get the style from.
       * @param {String} att The style property to get. 
       * @return {String} The computed value of the style property. 
       */
      getComputedStyle: function(node, att) {
          var val = '',
              doc = node[OWNER_DOCUMENT];
  
          if (node[STYLE] && doc[DEFAULT_VIEW] && doc[DEFAULT_VIEW][GET_COMPUTED_STYLE]) {
              val = doc[DEFAULT_VIEW][GET_COMPUTED_STYLE](node, null)[att];
          }
          return val;
      }
  });
  
  // normalize reserved word float alternatives ("cssFloat" or "styleFloat")
  if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][CSS_FLOAT] !== UNDEFINED) {
      Y_DOM.CUSTOM_STYLES[FLOAT] = CSS_FLOAT;
  } else if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][STYLE_FLOAT] !== UNDEFINED) {
      Y_DOM.CUSTOM_STYLES[FLOAT] = STYLE_FLOAT;
  }
  
  // fix opera computedStyle default color unit (convert to rgb)
  if (Y.UA.opera) {
      Y_DOM[GET_COMPUTED_STYLE] = function(node, att) {
          var view = node[OWNER_DOCUMENT][DEFAULT_VIEW],
              val = view[GET_COMPUTED_STYLE](node, '')[att];
  
          if (re_color.test(att)) {
              val = Y.Color.toRGB(val);
          }
  
          return val;
      };
  
  }
  
  // safari converts transparent to rgba(), others use "transparent"
  if (Y.UA.webkit) {
      Y_DOM[GET_COMPUTED_STYLE] = function(node, att) {
          var view = node[OWNER_DOCUMENT][DEFAULT_VIEW],
              val = view[GET_COMPUTED_STYLE](node, '')[att];
  
          if (val === 'rgba(0, 0, 0, 0)') {
              val = TRANSPARENT; 
          }
  
          return val;
      };
  
  }
  
  Y.DOM._getAttrOffset = function(node, attr) {
      var val = Y.DOM[GET_COMPUTED_STYLE](node, attr),
          offsetParent = node.offsetParent,
          position,
          parentOffset,
          offset;
  
      if (val === 'auto') {
          position = Y.DOM.getStyle(node, 'position');
          if (position === 'static' || position === 'relative') {
              val = 0;    
          } else if (offsetParent && offsetParent[GET_BOUNDING_CLIENT_RECT]) {
              parentOffset = offsetParent[GET_BOUNDING_CLIENT_RECT]()[attr];
              offset = node[GET_BOUNDING_CLIENT_RECT]()[attr];
              if (attr === 'left' || attr === 'top') {
                  val = offset - parentOffset;
              } else {
                  val = parentOffset - node[GET_BOUNDING_CLIENT_RECT]()[attr];
              }
          }
      }
  
      return val;
  };
  
  Y.DOM._getOffset = function(node) {
      var pos,
          xy = null;
  
      if (node) {
          pos = Y_DOM.getStyle(node, 'position');
          xy = [
              parseInt(Y_DOM[GET_COMPUTED_STYLE](node, 'left'), 10),
              parseInt(Y_DOM[GET_COMPUTED_STYLE](node, 'top'), 10)
          ];
  
          if ( isNaN(xy[0]) ) { // in case of 'auto'
              xy[0] = parseInt(Y_DOM.getStyle(node, 'left'), 10); // try inline
              if ( isNaN(xy[0]) ) { // default to offset value
                  xy[0] = (pos === 'relative') ? 0 : node.offsetLeft || 0;
              }
          } 
  
          if ( isNaN(xy[1]) ) { // in case of 'auto'
              xy[1] = parseInt(Y_DOM.getStyle(node, 'top'), 10); // try inline
              if ( isNaN(xy[1]) ) { // default to offset value
                  xy[1] = (pos === 'relative') ? 0 : node.offsetTop || 0;
              }
          } 
      }
  
      return xy;
  
  };
  
  Y_DOM.CUSTOM_STYLES.transform = {
      set: function(node, val, style) {
          style[TRANSFORM] = val;
      },
  
      get: function(node, style) {
          return Y_DOM[GET_COMPUTED_STYLE](node, TRANSFORM);
      }
  };
  
  
  })(Y);
  (function(Y) {
  var PARSE_INT = parseInt,
      RE = RegExp;
  
  Y.Color = {
      KEYWORDS: {
          black: '000',
          silver: 'c0c0c0',
          gray: '808080',
          white: 'fff',
          maroon: '800000',
          red: 'f00',
          purple: '800080',
          fuchsia: 'f0f',
          green: '008000',
          lime: '0f0',
          olive: '808000',
          yellow: 'ff0',
          navy: '000080',
          blue: '00f',
          teal: '008080',
          aqua: '0ff'
      },
  
      re_RGB: /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i,
      re_hex: /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i,
      re_hex3: /([0-9A-F])/gi,
  
      toRGB: function(val) {
          if (!Y.Color.re_RGB.test(val)) {
              val = Y.Color.toHex(val);
          }
  
          if(Y.Color.re_hex.exec(val)) {
              val = 'rgb(' + [
                  PARSE_INT(RE.$1, 16),
                  PARSE_INT(RE.$2, 16),
                  PARSE_INT(RE.$3, 16)
              ].join(', ') + ')';
          }
          return val;
      },
  
      toHex: function(val) {
          val = Y.Color.KEYWORDS[val] || val;
          if (Y.Color.re_RGB.exec(val)) {
              val = [
                  Number(RE.$1).toString(16),
                  Number(RE.$2).toString(16),
                  Number(RE.$3).toString(16)
              ];
  
              for (var i = 0; i < val.length; i++) {
                  if (val[i].length < 2) {
                      val[i] = '0' + val[i];
                  }
              }
  
              val = val.join('');
          }
  
          if (val.length < 6) {
              val = val.replace(Y.Color.re_hex3, '$1$1');
          }
  
          if (val !== 'transparent' && val.indexOf('#') < 0) {
              val = '#' + val;
          }
  
          return val.toUpperCase();
      }
  };
  })(Y);
  
  
  
  }, '@VERSION@' ,{requires:['dom-base']});
  YUI.add('dom-screen', function(Y) {
  
  (function(Y) {
  
  /**
   * Adds position and region management functionality to DOM.
   * @module dom
   * @submodule dom-screen
   * @for DOM
   */
  
  var DOCUMENT_ELEMENT = 'documentElement',
      COMPAT_MODE = 'compatMode',
      POSITION = 'position',
      FIXED = 'fixed',
      RELATIVE = 'relative',
      LEFT = 'left',
      TOP = 'top',
      _BACK_COMPAT = 'BackCompat',
      MEDIUM = 'medium',
      BORDER_LEFT_WIDTH = 'borderLeftWidth',
      BORDER_TOP_WIDTH = 'borderTopWidth',
      GET_BOUNDING_CLIENT_RECT = 'getBoundingClientRect',
      GET_COMPUTED_STYLE = 'getComputedStyle',
  
      Y_DOM = Y.DOM,
  
      // TODO: how about thead/tbody/tfoot/tr?
      // TODO: does caption matter?
      RE_TABLE = /^t(?:able|d|h)$/i,
  
      SCROLL_NODE;
  
  if (Y.UA.ie) {
      if (Y.config.doc[COMPAT_MODE] !== 'BackCompat') {
          SCROLL_NODE = DOCUMENT_ELEMENT; 
      } else {
          SCROLL_NODE = 'body';
      }
  }
  
  Y.mix(Y_DOM, {
      /**
       * Returns the inner height of the viewport (exludes scrollbar). 
       * @method winHeight
       * @return {Number} The current height of the viewport.
       */
      winHeight: function(node) {
          var h = Y_DOM._getWinSize(node).height;
          Y.log('winHeight returning ' + h, 'info', 'dom-screen');
          return h;
      },
  
      /**
       * Returns the inner width of the viewport (exludes scrollbar). 
       * @method winWidth
       * @return {Number} The current width of the viewport.
       */
      winWidth: function(node) {
          var w = Y_DOM._getWinSize(node).width;
          Y.log('winWidth returning ' + w, 'info', 'dom-screen');
          return w;
      },
  
      /**
       * Document height 
       * @method docHeight
       * @return {Number} The current height of the document.
       */
      docHeight:  function(node) {
          var h = Y_DOM._getDocSize(node).height;
          Y.log('docHeight returning ' + h, 'info', 'dom-screen');
          return Math.max(h, Y_DOM._getWinSize(node).height);
      },
  
      /**
       * Document width 
       * @method docWidth
       * @return {Number} The current width of the document.
       */
      docWidth:  function(node) {
          var w = Y_DOM._getDocSize(node).width;
          Y.log('docWidth returning ' + w, 'info', 'dom-screen');
          return Math.max(w, Y_DOM._getWinSize(node).width);
      },
  
      /**
       * Amount page has been scroll horizontally 
       * @method docScrollX
       * @return {Number} The current amount the screen is scrolled horizontally.
       */
      docScrollX: function(node, doc) {
          doc = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc; // perf optimization
          var dv = doc.defaultView,
              pageOffset = (dv) ? dv.pageXOffset : 0;
          return Math.max(doc[DOCUMENT_ELEMENT].scrollLeft, doc.body.scrollLeft, pageOffset);
      },
  
      /**
       * Amount page has been scroll vertically 
       * @method docScrollY
       * @return {Number} The current amount the screen is scrolled vertically.
       */
      docScrollY:  function(node, doc) {
          doc = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc; // perf optimization
          var dv = doc.defaultView,
              pageOffset = (dv) ? dv.pageYOffset : 0;
          return Math.max(doc[DOCUMENT_ELEMENT].scrollTop, doc.body.scrollTop, pageOffset);
      },
  
      /**
       * Gets the current position of an element based on page coordinates. 
       * Element must be part of the DOM tree to have page coordinates
       * (display:none or elements not appended return false).
       * @method getXY
       * @param element The target element
       * @return {Array} The XY position of the element
  
       TODO: test inDocument/display?
       */
      getXY: function() {
          if (Y.config.doc[DOCUMENT_ELEMENT][GET_BOUNDING_CLIENT_RECT]) {
              return function(node) {
                  var xy = null,
                      scrollLeft,
                      scrollTop,
                      box,
                      off1, off2,
                      bLeft, bTop,
                      mode,
                      doc,
                      inDoc,
                      rootNode;
  
                  if (node && node.tagName) {
                      doc = node.ownerDocument;
                      rootNode = doc[DOCUMENT_ELEMENT];
  
                      // inline inDoc check for perf
                      if (rootNode.contains) {
                          inDoc = rootNode.contains(node); 
                      } else {
                          inDoc = Y.DOM.contains(rootNode, node);
                      }
  
                      if (inDoc) {
                          scrollLeft = (SCROLL_NODE) ? doc[SCROLL_NODE].scrollLeft : Y_DOM.docScrollX(node, doc);
                          scrollTop = (SCROLL_NODE) ? doc[SCROLL_NODE].scrollTop : Y_DOM.docScrollY(node, doc);
                          box = node[GET_BOUNDING_CLIENT_RECT]();
                          xy = [box.left, box.top];
  
                              if (Y.UA.ie) {
                                  off1 = 2;
                                  off2 = 2;
                                  mode = doc[COMPAT_MODE];
                                  bLeft = Y_DOM[GET_COMPUTED_STYLE](doc[DOCUMENT_ELEMENT], BORDER_LEFT_WIDTH);
                                  bTop = Y_DOM[GET_COMPUTED_STYLE](doc[DOCUMENT_ELEMENT], BORDER_TOP_WIDTH);
  
                                  if (Y.UA.ie === 6) {
                                      if (mode !== _BACK_COMPAT) {
                                          off1 = 0;
                                          off2 = 0;
                                      }
                                  }
                                  
                                  if ((mode == _BACK_COMPAT)) {
                                      if (bLeft !== MEDIUM) {
                                          off1 = parseInt(bLeft, 10);
                                      }
                                      if (bTop !== MEDIUM) {
                                          off2 = parseInt(bTop, 10);
                                      }
                                  }
                                  
                                  xy[0] -= off1;
                                  xy[1] -= off2;
  
                              }
  
                          if ((scrollTop || scrollLeft)) {
                              if (!Y.UA.ios || (Y.UA.ios >= 4.2)) {
                                  xy[0] += scrollLeft;
                                  xy[1] += scrollTop;
                              }
                              
                          }
                      } else {
                          xy = Y_DOM._getOffset(node);       
                      }
                  }
                  return xy;                   
              }
          } else {
              return function(node) { // manually calculate by crawling up offsetParents
                  //Calculate the Top and Left border sizes (assumes pixels)
                  var xy = null,
                      doc,
                      parentNode,
                      bCheck,
                      scrollTop,
                      scrollLeft;
  
                  if (node) {
                      if (Y_DOM.inDoc(node)) {
                          xy = [node.offsetLeft, node.offsetTop];
                          doc = node.ownerDocument;
                          parentNode = node;
                          // TODO: refactor with !! or just falsey
                          bCheck = ((Y.UA.gecko || Y.UA.webkit > 519) ? true : false);
  
                          // TODO: worth refactoring for TOP/LEFT only?
                          while ((parentNode = parentNode.offsetParent)) {
                              xy[0] += parentNode.offsetLeft;
                              xy[1] += parentNode.offsetTop;
                              if (bCheck) {
                                  xy = Y_DOM._calcBorders(parentNode, xy);
                              }
                          }
  
                          // account for any scrolled ancestors
                          if (Y_DOM.getStyle(node, POSITION) != FIXED) {
                              parentNode = node;
  
                              while ((parentNode = parentNode.parentNode)) {
                                  scrollTop = parentNode.scrollTop;
                                  scrollLeft = parentNode.scrollLeft;
  
                                  //Firefox does something funky with borders when overflow is not visible.
                                  if (Y.UA.gecko && (Y_DOM.getStyle(parentNode, 'overflow') !== 'visible')) {
                                          xy = Y_DOM._calcBorders(parentNode, xy);
                                  }
                                  
  
                                  if (scrollTop || scrollLeft) {
                                      xy[0] -= scrollLeft;
                                      xy[1] -= scrollTop;
                                  }
                              }
                              xy[0] += Y_DOM.docScrollX(node, doc);
                              xy[1] += Y_DOM.docScrollY(node, doc);
  
                          } else {
                              //Fix FIXED position -- add scrollbars
                              xy[0] += Y_DOM.docScrollX(node, doc);
                              xy[1] += Y_DOM.docScrollY(node, doc);
                          }
                      } else {
                          xy = Y_DOM._getOffset(node);
                      }
                  }
  
                  return xy;                
              };
          }
      }(),// NOTE: Executing for loadtime branching
  
      /**
       * Gets the current X position of an element based on page coordinates. 
       * Element must be part of the DOM tree to have page coordinates
       * (display:none or elements not appended return false).
       * @method getX
       * @param element The target element
       * @return {Int} The X position of the element
       */
  
      getX: function(node) {
          return Y_DOM.getXY(node)[0];
      },
  
      /**
       * Gets the current Y position of an element based on page coordinates. 
       * Element must be part of the DOM tree to have page coordinates
       * (display:none or elements not appended return false).
       * @method getY
       * @param element The target element
       * @return {Int} The Y position of the element
       */
  
      getY: function(node) {
          return Y_DOM.getXY(node)[1];
      },
  
      /**
       * Set the position of an html element in page coordinates.
       * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
       * @method setXY
       * @param element The target element
       * @param {Array} xy Contains X & Y values for new position (coordinates are page-based)
       * @param {Boolean} noRetry By default we try and set the position a second time if the first fails
       */
      setXY: function(node, xy, noRetry) {
          var setStyle = Y_DOM.setStyle,
              pos,
              delta,
              newXY,
              currentXY;
  
          if (node && xy) {
              pos = Y_DOM.getStyle(node, POSITION);
  
              delta = Y_DOM._getOffset(node);       
              if (pos == 'static') { // default to relative
                  pos = RELATIVE;
                  setStyle(node, POSITION, pos);
              }
              currentXY = Y_DOM.getXY(node);
  
              if (xy[0] !== null) {
                  setStyle(node, LEFT, xy[0] - currentXY[0] + delta[0] + 'px');
              }
  
              if (xy[1] !== null) {
                  setStyle(node, TOP, xy[1] - currentXY[1] + delta[1] + 'px');
              }
  
              if (!noRetry) {
                  newXY = Y_DOM.getXY(node);
                  if (newXY[0] !== xy[0] || newXY[1] !== xy[1]) {
                      Y_DOM.setXY(node, xy, true); 
                  }
              }
            
              Y.log('setXY setting position to ' + xy, 'info', 'dom-screen');
          } else {
              Y.log('setXY failed to set ' + node + ' to ' + xy, 'info', 'dom-screen');
          }
      },
  
      /**
       * Set the X position of an html element in page coordinates, regardless of how the element is positioned.
       * The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
       * @method setX
       * @param element The target element
       * @param {Int} x The X values for new position (coordinates are page-based)
       */
      setX: function(node, x) {
          return Y_DOM.setXY(node, [x, null]);
      },
  
      /**
       * Set the Y position of an html element in page coordinates, regardless of how the element is positioned.
       * The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
       * @method setY
       * @param element The target element
       * @param {Int} y The Y values for new position (coordinates are page-based)
       */
      setY: function(node, y) {
          return Y_DOM.setXY(node, [null, y]);
      },
  
      /**
       * @method swapXY
       * @description Swap the xy position with another node
       * @param {Node} node The node to swap with
       * @param {Node} otherNode The other node to swap with
       * @return {Node}
       */
      swapXY: function(node, otherNode) {
          var xy = Y_DOM.getXY(node);
          Y_DOM.setXY(node, Y_DOM.getXY(otherNode));
          Y_DOM.setXY(otherNode, xy);
      },
  
      _calcBorders: function(node, xy2) {
          var t = parseInt(Y_DOM[GET_COMPUTED_STYLE](node, BORDER_TOP_WIDTH), 10) || 0,
              l = parseInt(Y_DOM[GET_COMPUTED_STYLE](node, BORDER_LEFT_WIDTH), 10) || 0;
          if (Y.UA.gecko) {
              if (RE_TABLE.test(node.tagName)) {
                  t = 0;
                  l = 0;
              }
          }
          xy2[0] += l;
          xy2[1] += t;
          return xy2;
      },
  
      _getWinSize: function(node, doc) {
          doc  = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc;
          var win = doc.defaultView || doc.parentWindow,
              mode = doc[COMPAT_MODE],
              h = win.innerHeight,
              w = win.innerWidth,
              root = doc[DOCUMENT_ELEMENT];
  
          if ( mode && !Y.UA.opera ) { // IE, Gecko
              if (mode != 'CSS1Compat') { // Quirks
                  root = doc.body; 
              }
              h = root.clientHeight;
              w = root.clientWidth;
          }
          return { height: h, width: w };
      },
  
      _getDocSize: function(node) {
          var doc = (node) ? Y_DOM._getDoc(node) : Y.config.doc,
              root = doc[DOCUMENT_ELEMENT];
  
          if (doc[COMPAT_MODE] != 'CSS1Compat') {
              root = doc.body;
          }
  
          return { height: root.scrollHeight, width: root.scrollWidth };
      }
  });
  
  })(Y);
  (function(Y) {
  var TOP = 'top',
      RIGHT = 'right',
      BOTTOM = 'bottom',
      LEFT = 'left',
  
      getOffsets = function(r1, r2) {
          var t = Math.max(r1[TOP], r2[TOP]),
              r = Math.min(r1[RIGHT], r2[RIGHT]),
              b = Math.min(r1[BOTTOM], r2[BOTTOM]),
              l = Math.max(r1[LEFT], r2[LEFT]),
              ret = {};
          
          ret[TOP] = t;
          ret[RIGHT] = r;
          ret[BOTTOM] = b;
          ret[LEFT] = l;
          return ret;
      },
  
      DOM = Y.DOM;
  
  Y.mix(DOM, {
      /**
       * Returns an Object literal containing the following about this element: (top, right, bottom, left)
       * @for DOM
       * @method region
       * @param {HTMLElement} element The DOM element. 
       * @return {Object} Object literal containing the following about this element: (top, right, bottom, left)
       */
      region: function(node) {
          var xy = DOM.getXY(node),
              ret = false;
          
          if (node && xy) {
              ret = DOM._getRegion(
                  xy[1], // top
                  xy[0] + node.offsetWidth, // right
                  xy[1] + node.offsetHeight, // bottom
                  xy[0] // left
              );
          }
  
          return ret;
      },
  
      /**
       * Find the intersect information for the passes nodes.
       * @method intersect
       * @for DOM
       * @param {HTMLElement} element The first element 
       * @param {HTMLElement | Object} element2 The element or region to check the interect with
       * @param {Object} altRegion An object literal containing the region for the first element if we already have the data (for performance i.e. DragDrop)
       * @return {Object} Object literal containing the following intersection data: (top, right, bottom, left, area, yoff, xoff, inRegion)
       */
      intersect: function(node, node2, altRegion) {
          var r = altRegion || DOM.region(node), region = {},
              n = node2,
              off;
  
          if (n.tagName) {
              region = DOM.region(n);
          } else if (Y.Lang.isObject(node2)) {
              region = node2;
          } else {
              return false;
          }
          
          off = getOffsets(region, r);
          return {
              top: off[TOP],
              right: off[RIGHT],
              bottom: off[BOTTOM],
              left: off[LEFT],
              area: ((off[BOTTOM] - off[TOP]) * (off[RIGHT] - off[LEFT])),
              yoff: ((off[BOTTOM] - off[TOP])),
              xoff: (off[RIGHT] - off[LEFT]),
              inRegion: DOM.inRegion(node, node2, false, altRegion)
          };
          
      },
      /**
       * Check if any part of this node is in the passed region
       * @method inRegion
       * @for DOM
       * @param {Object} node2 The node to get the region from or an Object literal of the region
       * $param {Boolean} all Should all of the node be inside the region
       * @param {Object} altRegion An object literal containing the region for this node if we already have the data (for performance i.e. DragDrop)
       * @return {Boolean} True if in region, false if not.
       */
      inRegion: function(node, node2, all, altRegion) {
          var region = {},
              r = altRegion || DOM.region(node),
              n = node2,
              off;
  
          if (n.tagName) {
              region = DOM.region(n);
          } else if (Y.Lang.isObject(node2)) {
              region = node2;
          } else {
              return false;
          }
              
          if (all) {
              return (
                  r[LEFT]   >= region[LEFT]   &&
                  r[RIGHT]  <= region[RIGHT]  && 
                  r[TOP]    >= region[TOP]    && 
                  r[BOTTOM] <= region[BOTTOM]  );
          } else {
              off = getOffsets(region, r);
              if (off[BOTTOM] >= off[TOP] && off[RIGHT] >= off[LEFT]) {
                  return true;
              } else {
                  return false;
              }
              
          }
      },
  
      /**
       * Check if any part of this element is in the viewport
       * @method inViewportRegion
       * @for DOM
       * @param {HTMLElement} element The DOM element. 
       * @param {Boolean} all Should all of the node be inside the region
       * @param {Object} altRegion An object literal containing the region for this node if we already have the data (for performance i.e. DragDrop)
       * @return {Boolean} True if in region, false if not.
       */
      inViewportRegion: function(node, all, altRegion) {
          return DOM.inRegion(node, DOM.viewportRegion(node), all, altRegion);
              
      },
  
      _getRegion: function(t, r, b, l) {
          var region = {};
  
          region[TOP] = region[1] = t;
          region[LEFT] = region[0] = l;
          region[BOTTOM] = b;
          region[RIGHT] = r;
          region.width = region[RIGHT] - region[LEFT];
          region.height = region[BOTTOM] - region[TOP];
  
          return region;
      },
  
      /**
       * Returns an Object literal containing the following about the visible region of viewport: (top, right, bottom, left)
       * @method viewportRegion
       * @for DOM
       * @return {Object} Object literal containing the following about the visible region of the viewport: (top, right, bottom, left)
       */
      viewportRegion: function(node) {
          node = node || Y.config.doc.documentElement;
          var ret = false,
              scrollX,
              scrollY;
  
          if (node) {
              scrollX = DOM.docScrollX(node);
              scrollY = DOM.docScrollY(node);
  
              ret = DOM._getRegion(scrollY, // top
                  DOM.winWidth(node) + scrollX, // right
                  scrollY + DOM.winHeight(node), // bottom
                  scrollX); // left
          }
  
          return ret;
      }
  });
  })(Y);
  
  
  }, '@VERSION@' ,{requires:['dom-base', 'dom-style']});
  YUI.add('selector-native', function(Y) {
  
  (function(Y) {
  /**
   * The selector-native module provides support for native querySelector
   * @module dom
   * @submodule selector-native
   * @for Selector
   */
  
  /**
   * Provides support for using CSS selectors to query the DOM 
   * @class Selector 
   * @static
   * @for Selector
   */
  
  Y.namespace('Selector'); // allow native module to standalone
  
  var COMPARE_DOCUMENT_POSITION = 'compareDocumentPosition',
      OWNER_DOCUMENT = 'ownerDocument';
  
  var Selector = {
      _foundCache: [],
  
      useNative: true,
  
      _compare: ('sourceIndex' in Y.config.doc.documentElement) ?
          function(nodeA, nodeB) {
              var a = nodeA.sourceIndex,
                  b = nodeB.sourceIndex;
  
              if (a === b) {
                  return 0;
              } else if (a > b) {
                  return 1;
              }
  
              return -1;
  
          } : (Y.config.doc.documentElement[COMPARE_DOCUMENT_POSITION] ?
          function(nodeA, nodeB) {
              if (nodeA[COMPARE_DOCUMENT_POSITION](nodeB) & 4) {
                  return -1;
              } else {
                  return 1;
              }
          } :
          function(nodeA, nodeB) {
              var rangeA, rangeB, compare;
              if (nodeA && nodeB) {
                  rangeA = nodeA[OWNER_DOCUMENT].createRange();
                  rangeA.setStart(nodeA, 0);
                  rangeB = nodeB[OWNER_DOCUMENT].createRange();
                  rangeB.setStart(nodeB, 0);
                  compare = rangeA.compareBoundaryPoints(1, rangeB); // 1 === Range.START_TO_END
              }
  
              return compare;
          
      }),
  
      _sort: function(nodes) {
          if (nodes) {
              nodes = Y.Array(nodes, 0, true);
              if (nodes.sort) {
                  nodes.sort(Selector._compare);
              }
          }
  
          return nodes;
      },
  
      _deDupe: function(nodes) {
          var ret = [],
              i, node;
  
          for (i = 0; (node = nodes[i++]);) {
              if (!node._found) {
                  ret[ret.length] = node;
                  node._found = true;
              }
          }
  
          for (i = 0; (node = ret[i++]);) {
              node._found = null;
              node.removeAttribute('_found');
          }
  
          return ret;
      },
  
      /**
       * Retrieves a set of nodes based on a given CSS selector. 
       * @method query
       *
       * @param {string} selector The CSS Selector to test the node against.
       * @param {HTMLElement} root optional An HTMLElement to start the query from. Defaults to Y.config.doc
       * @param {Boolean} firstOnly optional Whether or not to return only the first match.
       * @return {Array} An array of nodes that match the given selector.
       * @static
       */
      query: function(selector, root, firstOnly, skipNative) {
          root = root || Y.config.doc;
          var ret = [],
              useNative = (Y.Selector.useNative && Y.config.doc.querySelector && !skipNative),
              queries = [[selector, root]],
              query,
              result,
              i,
              fn = (useNative) ? Y.Selector._nativeQuery : Y.Selector._bruteQuery;
  
          if (selector && fn) {
              // split group into seperate queries
              if (!skipNative && // already done if skipping
                      (!useNative || root.tagName)) { // split native when element scoping is needed
                  queries = Selector._splitQueries(selector, root);
              }
  
              for (i = 0; (query = queries[i++]);) {
                  result = fn(query[0], query[1], firstOnly);
                  if (!firstOnly) { // coerce DOM Collection to Array
                      result = Y.Array(result, 0, true);
                  }
                  if (result) {
                      ret = ret.concat(result);
                  }
              }
  
              if (queries.length > 1) { // remove dupes and sort by doc order 
                  ret = Selector._sort(Selector._deDupe(ret));
              }
          }
  
          Y.log('query: ' + selector + ' returning: ' + ret.length, 'info', 'Selector');
          return (firstOnly) ? (ret[0] || null) : ret;
  
      },
  
      // allows element scoped queries to begin with combinator
      // e.g. query('> p', document.body) === query('body > p')
      _splitQueries: function(selector, node) {
          var groups = selector.split(','),
              queries = [],
              prefix = '',
              i, len;
  
          if (node) {
              // enforce for element scoping
              if (node.tagName) {
                  node.id = node.id || Y.guid();
                  prefix = '[id="' + node.id + '"] ';
              }
  
              for (i = 0, len = groups.length; i < len; ++i) {
                  selector =  prefix + groups[i];
                  queries.push([selector, node]);
              }
          }
  
          return queries;
      },
  
      _nativeQuery: function(selector, root, one) {
          if (Y.UA.webkit && selector.indexOf(':checked') > -1 &&
                  (Y.Selector.pseudos && Y.Selector.pseudos.checked)) { // webkit (chrome, safari) fails to pick up "selected"  with "checked"
              return Y.Selector.query(selector, root, one, true); // redo with skipNative true to try brute query
          }
          try {
              //Y.log('trying native query with: ' + selector, 'info', 'selector-native');
              return root['querySelector' + (one ? '' : 'All')](selector);
          } catch(e) { // fallback to brute if available
              //Y.log('native query error; reverting to brute query with: ' + selector, 'info', 'selector-native');
              return Y.Selector.query(selector, root, one, true); // redo with skipNative true
          }
      },
  
      filter: function(nodes, selector) {
          var ret = [],
              i, node;
  
          if (nodes && selector) {
              for (i = 0; (node = nodes[i++]);) {
                  if (Y.Selector.test(node, selector)) {
                      ret[ret.length] = node;
                  }
              }
          } else {
              Y.log('invalid filter input (nodes: ' + nodes +
                      ', selector: ' + selector + ')', 'warn', 'Selector');
          }
  
          return ret;
      },
  
      test: function(node, selector, root) {
          var ret = false,
              useFrag = false,
              groups,
              parent,
              item,
              items,
              frag,
              i, j, group;
  
          if (node && node.tagName) { // only test HTMLElements
  
              if (typeof selector == 'function') { // test with function
                  ret = selector.call(node, node);
              } else { // test with query
                  // we need a root if off-doc
                  groups = selector.split(',');
                  if (!root && !Y.DOM.inDoc(node)) {
                      parent = node.parentNode;
                      if (parent) { 
                          root = parent;
                      } else { // only use frag when no parent to query
                          frag = node[OWNER_DOCUMENT].createDocumentFragment();
                          frag.appendChild(node);
                          root = frag;
                          useFrag = true;
                      }
                  }
                  root = root || node[OWNER_DOCUMENT];
  
                  if (!node.id) {
                      node.id = Y.guid();
                  }
                  for (i = 0; (group = groups[i++]);) { // TODO: off-dom test
                      group += '[id="' + node.id + '"]';
                      items = Y.Selector.query(group, root);
  
                      for (j = 0; item = items[j++];) {
                          if (item === node) {
                              ret = true;
                              break;
                          }
                      }
                      if (ret) {
                          break;
                      }
                  }
  
                  if (useFrag) { // cleanup
                      frag.removeChild(node);
                  }
              };
          }
  
          return ret;
      },
  
      /**
       * A convenience function to emulate Y.Node's aNode.ancestor(selector).
       * @param {HTMLElement} element An HTMLElement to start the query from.
       * @param {String} selector The CSS selector to test the node against.
       * @return {HTMLElement} The ancestor node matching the selector, or null.
       * @param {Boolean} testSelf optional Whether or not to include the element in the scan 
       * @static
       * @method ancestor
       */
      ancestor: function (element, selector, testSelf) {
          return Y.DOM.ancestor(element, function(n) {
              return Y.Selector.test(n, selector);
          }, testSelf);
      }
  };
  
  Y.mix(Y.Selector, Selector, true);
  
  })(Y);
  
  
  }, '@VERSION@' ,{requires:['dom-base']});
  YUI.add('selector', function(Y) {
  
  
  
  
  }, '@VERSION@' ,{requires:['selector-native']});
  
  
  YUI.add('dom', function(Y){}, '@VERSION@' ,{use:['dom-base', 'dom-style', 'dom-screen', 'selector-native', 'selector']});
  
  