text: /**
   * @private
   * @class Ext.draw.sprite.AttributeParser
   *
   * Parsers used for sprite attributes if they are {@link Ext.draw.sprite.AttributeDefinition#normalize normalized}
   * (default) when being {@link Ext.draw.sprite.Sprite#setAttributes set}.
   *
   * Methods of the singleton correpond either to the processor functions themselves or processor factories.
   */
  Ext.define('Ext.draw.sprite.AttributeParser', {
      singleton: true,
      attributeRe: /^url\(#([a-zA-Z\-]+)\)$/,
      requires: [
          'Ext.draw.Color',
          'Ext.draw.gradient.GradientDefinition'
      ],
  
      "default": function (n) {
          return n;
      },
      
      string: function (n) {
          return String(n);
      },
      
      number: function (n) {
          if (!isNaN(n)) {
              return n;
          }
      },
      
      angle: function (n) {
          if (!isNaN(n)) {
              n %= Math.PI * 2;
              if (n < -Math.PI) {
                  n += Math.PI * 2;
              }
              if (n > Math.PI) {
                  n -= Math.PI * 2;
              }
              return n;
          }
      },
      
      data: function (n) {
          if (Ext.isArray(n)) {
              return n.slice();
          } else if (n instanceof Float32Array) {
              return new Float32Array(n);
          }
      },
      
      bool: function (n) {
          return !!n;
      },
      
      color: function (n) {
          if (n instanceof Ext.draw.Color) {
              return n.toString();
          } else if (n instanceof Ext.draw.gradient.Gradient) {
              return n;
          } else if (!n) {
              return Ext.draw.Color.NONE;
          } else if (Ext.isString(n)) {
              if (n.substr(0, 3) === 'url') {
                  n = Ext.draw.gradient.GradientDefinition.get(n);
                  if (Ext.isString(n)) {
                      return n;
                  }
              } else {
                  return Ext.draw.Color.fly(n).toString();
              }
          }
          if (n.type === 'linear') {
              return Ext.create('Ext.draw.gradient.Linear', n);
          } else if (n.type === 'radial') {
              return Ext.create('Ext.draw.gradient.Radial', n);
          } else if (n.type === 'pattern') {
              return Ext.create('Ext.draw.gradient.Pattern', n);
          } else {
              return Ext.draw.Color.NONE;
          }
      },
  
      limited: function (low, hi) {
          return function (n) {
              return isNaN(n) ? undefined : Math.min(Math.max(+n, low), hi);
          };
      },
      
      limited01: function (n) {
          return isNaN(n) ? undefined : Math.min(Math.max(+n, 0), 1);
      },
  
      /**
       * Generates a function that checks if a value matches
       * one of the given attributes.
       * @returns {Function}
       */
      enums: function () {
          var enums = {},
              args = Array.prototype.slice.call(arguments, 0),
              i, ln;
  
          for (i = 0, ln = args.length; i < ln; i++) {
              enums[args[i]] = true;
          }
          return function (n) {
              return n in enums ? n : undefined;
          };
      }
  });