text: YUI.add('button-core', function (Y, NAME) {
  
  /**
   * Provides an interface for working with button-like DOM nodes
   *
   * @module button-core
   * @since 3.5.0
   */
  var getClassName = Y.ClassNameManager.getClassName,
      AttributeCore = Y.AttributeCore;
  
  /**
   * Creates a button
   *
   * @class ButtonCore
   * @uses AttributeCore
   * @param config {Object} Configuration object
   * @constructor
   */
  function ButtonCore(config) {
      this.initializer(config);
  }
  
  ButtonCore.prototype = {
  
      /**
       *
       * @property TEMPLATE
       * @type {String}
       * @default <button/>
       */
      TEMPLATE: '<button/>',
  
      /**
       *
       * @property constructor
       * @type {Object}
       * @default ButtonCore
       * @private
       */
      constructor: ButtonCore,
  
      /**
       * @method initializer
       * @description Internal init() handler.
       * @param config {Object} Config object.
       * @private
       */
      initializer: function(config) {
          this._initNode(config);
          this._initAttributes(config);
          this._renderUI(config);
      },
  
      /**
       * @method _initNode
       * @description Node initializer
       * @param config {Object} Config object.
       * @private
       */
      _initNode: function(config) {
          if (config.host) {
              this._host = Y.one(config.host);
          } else {
              this._host = Y.Node.create(this.TEMPLATE);
          }
      },
  
      /**
       * @method _initAttributes
       * @description  Attribute initializer
       * @param config {Object} Config object.
       * @private
       */
      _initAttributes: function(config) {
          AttributeCore.call(this, ButtonCore.ATTRS, config);
      },
  
      /**
       * @method renderUI
       * @description Renders any UI/DOM elements for Button instances
       * @param config {Object} Config object.
       * @private
       */
      _renderUI: function() {
          var node = this.getNode(),
              nodeName = node.get('nodeName').toLowerCase();
  
          // Set some default node attributes
          node.addClass(ButtonCore.CLASS_NAMES.BUTTON);
  
          if (nodeName !== 'button' && nodeName !== 'input') {
              node.set('role', 'button');
          }
      },
  
      /**
       * @method enable
       * @description Sets the button's `disabled` DOM attribute to `false`
       * @public
       */
      enable: function() {
          this.set('disabled', false);
      },
  
      /**
       * @method disable
       * @description Sets the button's `disabled` DOM attribute to `true`
       * @public
       */
      disable: function() {
          this.set('disabled', true);
      },
  
      /**
       * @method getNode
       * @description Gets the button's host node
       * @return {Node} The host node instance
       * @public
       */
      getNode: function() {
          if (!this._host) {
              // If this._host doesn't exist, that means this._initNode
              // was never executed, meaning this is likely a Widget and
              // the host node should point to the boundingBox.
              this._host = this.get('boundingBox');
          }
  
          return this._host;
      },
  
      /**
       * @method _getLabel
       * @description Getter for a button's `label` ATTR
       * @return {String} The text label of the button
       * @private
       */
      _getLabel: function () {
          var node = this.getNode(),
              label = ButtonCore._getTextLabelFromNode(node);
  
          return label;
      },
  
      /**
       * @method _getLabelHTML
       * @description Getter for a button's `labelHTML` ATTR
       * @return {String} The HTML label of the button
       * @private
       */
      _getLabelHTML: function () {
          var node = this.getNode(),
              labelHTML = ButtonCore._getHTMLFromNode(node);
  
          return labelHTML;
      },
  
      /**
       * @method _setLabel
       * @description Setter for a button's `label` ATTR
       * @param value {String} The value to set for `label`
       * @param name {String} The name of this ATTR (`label`)
       * @param opts {Object} Additional options
       *    @param opts.src {String} A string identifying the callee.
       *        `internal` will not sync this value with the `labelHTML` ATTR
       * @return {String} The text label for the given node
       * @private
       */
      _setLabel: function (value, name, opts) {
          var label = Y.Escape.html(value);
  
          if (!opts || opts.src !== 'internal') {
              this.set('labelHTML', label, {src: 'internal'});
          }
  
          return label;
      },
  
      /**
       * @method _setLabelHTML
       * @description Setter for a button's `labelHTML` ATTR
       * @param value {String} The value to set for `labelHTML`
       * @param name {String} The name of this ATTR (`labelHTML`)
       * @param opts {Object} Additional options
       *    @param opts.src {String} A string identifying the callee.
       *        `internal` will not sync this value with the `label` ATTR
       * @return {String} The HTML label for the given node
       * @private
       */
      _setLabelHTML: function (value, name, opts) {
          var node = this.getNode(),
              labelNode = ButtonCore._getLabelNodeFromParent(node),
              nodeName = node.get('nodeName').toLowerCase();
  
          if (nodeName === 'input') {
              labelNode.set('value', value);
          }
          else {
              labelNode.setHTML(value);
          }
  
          if (!opts || opts.src !== 'internal') {
              this.set('label', value, {src: 'internal'});
          }
  
          return value;
      },
  
      /**
       * @method _setDisabled
       * @description Setter for the `disabled` ATTR
       * @param value {boolean}
       * @private
       */
      _setDisabled: function(value) {
          var node = this.getNode();
  
          node.getDOMNode().disabled = value; // avoid rerunning setter when this === node
          node.toggleClass(ButtonCore.CLASS_NAMES.DISABLED, value);
  
          return value;
      }
  };
  
  // ButtonCore inherits from AttributeCore
  Y.mix(ButtonCore.prototype, AttributeCore.prototype);
  
  /**
   * Attribute configuration.
   *
   * @property ATTRS
   * @type {Object}
   * @protected
   * @static
   */
  ButtonCore.ATTRS = {
  
      /**
       * The text of the button's label
       *
       * @config label
       * @type String
       */
      label: {
          setter: '_setLabel',
          getter: '_getLabel',
          lazyAdd: false
      },
  
      /**
       * The HTML of the button's label
       *
       * This attribute accepts HTML and inserts it into the DOM **without**
       * sanitization.  This attribute should only be used with HTML that has
       * either been escaped (using `Y.Escape.html`), or sanitized according to
       * the requirements of your application.
       *
       * If all you need is support for text labels, please use the `label`
       * attribute instead.
       *
       * @config labelHTML
       * @type HTML
       */
      labelHTML: {
          setter: '_setLabelHTML',
          getter: '_getLabelHTML',
          lazyAdd: false
      },
  
      /**
       * The button's enabled/disabled state
       *
       * @config disabled
       * @type Boolean
       */
      disabled: {
          value: false,
          setter: '_setDisabled',
          lazyAdd: false
      }
  };
  
  /**
   * Name of this component.
   *
   * @property NAME
   * @type String
   * @static
   */
  ButtonCore.NAME = "button";
  
  /**
   * Array of static constants used to identify the classnames applied to DOM nodes
   *
   * @property CLASS_NAMES
   * @type {Object}
   * @public
   * @static
   */
  ButtonCore.CLASS_NAMES = {
      BUTTON  : getClassName('button'),
      DISABLED: getClassName('button', 'disabled'),
      SELECTED: getClassName('button', 'selected'),
      LABEL   : getClassName('button', 'label')
  };
  
  /**
   * Array of static constants used to for applying ARIA states
   *
   * @property ARIA_STATES
   * @type {Object}
   * @private
   * @static
   */
  ButtonCore.ARIA_STATES = {
      PRESSED : 'aria-pressed',
      CHECKED : 'aria-checked'
  };
  
  /**
   * Array of static constants used to for applying ARIA roles
   *
   * @property ARIA_ROLES
   * @type {Object}
   * @private
   * @static
   */
  ButtonCore.ARIA_ROLES = {
      BUTTON  : 'button',
      CHECKBOX: 'checkbox',
      TOGGLE  : 'toggle'
  };
  
  /**
   * Finds the label node within a button
   *
   * @method _getLabelNodeFromParent
   * @param node {Node} The parent node
   * @return {Node} The label node
   * @private
   * @static
   */
  ButtonCore._getLabelNodeFromParent = function (node) {
      var labelNode = (node.one('.' + ButtonCore.CLASS_NAMES.LABEL) || node);
  
      return labelNode;
  };
  
  /**
   * Gets a text label from a node
   *
   * @method _getTextLabelFromNode
   * @param node {Node} The parent node
   * @return {String} The text label for a given node
   * @private
   * @static
   */
  ButtonCore._getTextLabelFromNode = function (node) {
      var labelNode = ButtonCore._getLabelNodeFromParent(node),
          nodeName = labelNode.get('nodeName').toLowerCase(),
          label = labelNode.get(nodeName === 'input' ? 'value' : 'text');
  
      return label;
  };
  
  /**
   * A utility method that gets an HTML label from a given node
   *
   * @method _getHTMLFromNode
   * @param node {Node} The parent node
   * @return {String} The HTML label for a given node
   * @private
   * @static
   */
  ButtonCore._getHTMLFromNode = function (node) {
      var labelNode = ButtonCore._getLabelNodeFromParent(node),
          label = labelNode.getHTML();
  
      return label;
  };
  
  /**
   * Gets the disabled attribute from a node
   *
   * @method _getDisabledFromNode
   * @param node {Node} The parent node
   * @return {boolean} The disabled state for a given node
   * @private
   * @static
   */
  ButtonCore._getDisabledFromNode = function (node) {
      return node.get('disabled');
  };
  
  // Export ButtonCore
  Y.ButtonCore = ButtonCore;
  
  
  }, '3.18.0', {"requires": ["attribute-core", "classnamemanager", "node-base", "escape"]});
  