text: /**
   * Color For KISSY.
   * @ignore
   * @author yiminghe@gmail.com
   */
  
  var util = require('util');
  var rgbaRe = /\s*rgba?\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*(?:,\s*([\d\.]+))?\)\s*/,
      hexRe = /\s*#([0-9a-fA-F][0-9a-fA-F]?)([0-9a-fA-F][0-9a-fA-F]?)([0-9a-fA-F][0-9a-fA-F]?)\s*/;
  
  var Attribute = require('attribute');
  
  /**
   * Color for KISSY to normalize HSL, HSV, RGB and HEX.
   * @class KISSY.Color
   */
  var Color = module.exports = Attribute.extend({
      /**
       * To hsl string format
       * @return {String}
       */
      toHSL: function () {
          var hsl = this.getHSL();
          return 'hsl(' + (Math.round(hsl.h || 0)) + ', ' + percentage(hsl.s) + ', ' + percentage(hsl.l) + ')';
      },
      /**
       * To hsla string format
       * @return {String}
       */
      toHSLA: function () {
          var hsl = this.getHSL();
          return 'hsla(' + (Math.round(hsl.h || 0)) + ', ' + percentage(hsl.s) + ', ' +
              percentage(hsl.l) + ', ' + this.get('a') + ')';
      },
  
      /**
       * To rgb string format
       * @return {String}
       */
      toRGB: function () {
          var self = this;
          return 'rgb(' + self.get('r') + ', ' + self.get('g') + ', ' + self.get('b') + ')';
      },
      /**
       * To rgba string format
       * @return {String}
       */
      toRGBA: function () {
          var self = this;
          return 'rgba(' + self.get('r') + ', ' + self.get('g') +
              ', ' + self.get('b') + ', ' + self.get('a') + ')';
      },
      /**
       * To hex string format
       * @return {String}
       */
      toHex: function () {
          var self = this;
          return '#' + padding2(Number(self.get('r')).toString(16)) +
              padding2(Number(self.get('g')).toString(16)) + padding2(Number(self.get('b')).toString(16));
      },
      /**
       * Return the color in the rgba format.
       * @return {String}
       */
      toString: function () {
          return this.toRGBA();
      },
      /**
       * Return the color in the hsl format.
       * @return {Object}
       */
      getHSL: function () {
          var self = this,
              r = self.get('r') / 255,
              g = self.get('g') / 255,
              b = self.get('b') / 255,
              max = Math.max(r, g, b),
              min = Math.min(r, g, b),
              delta = max - min,
              h,
              s = 0,
              l = 0.5 * (max + min);
  
          // min==max means achromatic (hue is undefined)
          if (min !== max) {
              s = (l < 0.5) ? delta / (max + min) : delta / (2 - max - min);
              if (r === max) {
                  h = 60 * (g - b) / delta;
              } else if (g === max) {
                  h = 120 + 60 * (b - r) / delta;
              } else {
                  h = 240 + 60 * (r - g) / delta;
              }
  
              h = (h + 360) % 360;
          }
          return {
              h: h,
              s: s,
              l: l
          };
      },
  
      /**
       * Return the color in the hsv format.
       * @return {Object}
       */
      getHSV: function () {
          return rgb2hsv({
              r: this.get('r'),
              g: this.get('g'),
              b: this.get('b')
          });
      },
  
      /**
       * Set value by hsv
       * @param cfg
       * @param cfg.h
       * @param cfg.s
       * @param cfg.v
       */
      setHSV: function (cfg) {
          var self = this,
              current;
          if (!('h' in cfg && 's' in cfg && 'v' in cfg)) {
              current = self.getHSV();
              util.each(['h', 's', 'v'], function (x) {
                  if (x in cfg) {
                      current[x] = cfg[x];
                  }
              });
              cfg = current;
          }
          self.set(hsv2rgb(cfg));
      },
  
      /**
       * Set value by hsl
       * @param cfg
       * @param cfg.h
       * @param cfg.s
       * @param cfg.l
       */
      setHSL: function (cfg) {
          var self = this,
              current;
          if (!('h' in cfg && 's' in cfg && 'l' in cfg)) {
              current = self.getHSL();
              util.each(['h', 's', 'l'], function (x) {
                  if (x in cfg) {
                      current[x] = cfg[x];
                  }
              });
              cfg = current;
          }
          self.set(hsl2rgb(cfg));
      }
  });
  
  util.mix(Color, {
      ATTRS: {
          /**
           * Red.
           * @type {Number}
           * @property r
           */
          /**
           * Red.
           * @cfg {Number} r
           */
          /**
           * @ignore
           */
          r: {
              getter: function (v) {
                  return Math.round(v);
              },
              setter: function (v) {
                  return constrain255(v);
              }
          },
          /**
           * Green.
           * @type {Number}
           * @property g
           */
          /**
           * Green.
           * @cfg {Number} g
           */
          /**
           * @ignore
           */
          g: {
              getter: function (v) {
                  return Math.round(v);
              },
              setter: function (v) {
                  return constrain255(v);
              }
          },
          /**
           * Blue.
           * @type {Number}
           * @property b
           */
          /**
           * Blue.
           * @cfg {Number} b
           */
          /**
           * @ignore
           */
          b: {
              getter: function (v) {
                  return Math.round(v);
              },
              setter: function (v) {
                  return constrain255(v);
              }
          },
          /**
           * Alpha.
           * @type {Number}
           * @property a
           */
          /**
           * Alpha.
           * Defaults to: 1
           * @cfg {Number} a
           */
          /**
           * @ignore
           */
          a: {
              value: 1,
              setter: function (v) {
                  return constrain1(v);
              }
          }
      },
  
      /**
       * Construct color object from String.
       * @static
       * @param {String} str string format color( '#rrggbb'  '#rgb' or 'rgb(r,g,b)'  'rgba(r,g,b,a)' )
       */
      parse: function (str) {
          var values, r,
              g,
              b,
              a = 1;
  
          if ((str.length === 4 || str.length === 7) && str.substr(0, 1) === '#') {
              values = str.match(hexRe);
              if (values) {
                  r = parseHex(values[1]);
                  g = parseHex(values[2]);
                  b = parseHex(values[3]);
                  if (str.length === 4) {
                      r = paddingHex(r);
                      g = paddingHex(g);
                      b = paddingHex(b);
                  }
              }
          } else {
              values = str.match(rgbaRe);
              if (values) {
                  r = parseInt(values[1], 10);
                  g = parseInt(values[2], 10);
                  b = parseInt(values[3], 10);
                  a = parseFloat(values[4]) || 1;
              }
          }
  
          return (typeof r === 'undefined') ? undefined : new Color({
              r: r,
              g: g,
              b: b,
              a: a
          });
      },
  
      /**
       * Construct color object from hsl.
       * @static
       * @param {Object} cfg
       * @param {Number} cfg.h Hue
       * @param {Number} cfg.s Saturation
       * @param {Number} cfg.l lightness
       * @param {Number} cfg.a alpha
       */
      fromHSL: function (cfg) {
          var rgb = hsl2rgb(cfg);
          rgb.a = cfg.a;
          return new Color(rgb);
      },
      /**
       * Construct color object from hsv.
       * @static
       * @param {Object} cfg
       * @param {Number} cfg.h Hue
       * @param {Number} cfg.s Saturation
       * @param {Number} cfg.v value
       * @param {Number} cfg.a alpha
       */
      fromHSV: function (cfg) {
          var rgb = hsv2rgb(cfg);
          rgb.a = cfg.a;
          return new Color(rgb);
      }
  });
  
  // #---------------------------- private start
  
  function to255(v) {
      return v * 255;
  }
  
  function hsv2rgb(cfg) {
      var h = Math.min(Math.round(cfg.h), 359),
          s = Math.max(0, Math.min(1, cfg.s)),
          v = Math.max(0, Math.min(1, cfg.v)),
          r, g, b,
          i = Math.floor((h / 60) % 6),
          f = (h / 60) - i,
          p = v * (1 - s),
          q = v * (1 - f * s),
          t = v * (1 - (1 - f) * s);
  
      switch (i) {
          case 0:
              r = v;
              g = t;
              b = p;
              break;
          case 1:
              r = q;
              g = v;
              b = p;
              break;
          case 2:
              r = p;
              g = v;
              b = t;
              break;
          case 3:
              r = p;
              g = q;
              b = v;
              break;
          case 4:
              r = t;
              g = p;
              b = v;
              break;
          case 5:
              r = v;
              g = p;
              b = q;
              break;
      }
  
      return {r: constrain255(to255(r)), g: constrain255(to255(g)), b: constrain255(to255(b))};
  }
  
  function rgb2hsv(cfg) {
      var r = cfg.r / 255,
          g = cfg.g / 255,
          b = cfg.b / 255;
  
      var h, s,
          min = Math.min(Math.min(r, g), b),
          max = Math.max(Math.max(r, g), b),
          delta = max - min,
          hsv;
  
      switch (max) {
          case min:
              h = 0;
              break;
          case r:
              h = 60 * (g - b) / delta;
              if (g < b) {
                  h += 360;
              }
              break;
          case g:
              h = (60 * (b - r) / delta) + 120;
              break;
          case b:
              h = (60 * (r - g) / delta) + 240;
              break;
      }
  
      s = (max === 0) ? 0 : 1 - (min / max);
  
      hsv = {
          h: Math.round(h),
          s: s,
          v: max
      };
  
      return hsv;
  }
  
  function hsl2rgb(cfg) {
      var h = Math.min(Math.round(cfg.h), 359),
          s = Math.max(0, Math.min(1, cfg.s)),
          l = Math.max(0, Math.min(1, cfg.l)),
          C, X, m, rgb = [],
          abs = Math.abs,
          floor = Math.floor;
  
      if (s === 0 || h == null) {
          // achromatic
          rgb = [l, l, l];
      } else {
          // http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSL
          // C is the chroma
          // X is the second largest component
          // m is the lightness adjustment
          h /= 60;
          C = s * (1 - abs(2 * l - 1));
          X = C * (1 - abs(h - 2 * floor(h / 2) - 1));
          m = l - C / 2;
          switch (floor(h)) {
              case 0:
                  rgb = [C, X, 0];
                  break;
              case 1:
                  rgb = [X, C, 0];
                  break;
              case 2:
                  rgb = [0, C, X];
                  break;
              case 3:
                  rgb = [0, X, C];
                  break;
              case 4:
                  rgb = [X, 0, C];
                  break;
              case 5:
                  rgb = [C, 0, X];
                  break;
          }
          rgb = [rgb[0] + m, rgb[1] + m, rgb[2] + m];
      }
      util.each(rgb, function (v, index) {
          rgb[index] = to255(v);
      });
      return {
          r: rgb[0],
          g: rgb[1],
          b: rgb[2]
      };
  }
  
  function parseHex(v) {
      return parseInt(v, 16);
  }
  
  function paddingHex(v) {
      return v + v * 16;
  }
  
  function padding2(v) {
      if (v.length !== 2) {
          v = '0' + v;
      }
      return v;
  }
  
  function percentage(v) {
      return Math.round(v * 100) + '%';
  }
  
  function constrain255(v) {
      return Math.max(0, Math.min(v, 255));
  }
  
  function constrain1(v) {
      return Math.max(0, Math.min(v, 1));
  }
  
  // #---------------------------- private end
  
  /**
   * @ignore
   * Refer:
   *  - 支持 http://en.wikipedia.org/wiki/HSL_and_HSV
   */
  