text: var colors = {
  	maroon: '#800000', red: '#ff0000', orange: '#ffA500', yellow: '#ffff00', olive: '#808000',
  	purple: '#800080', fuchsia: "#ff00ff", white: '#ffffff', lime: '#00ff00', green: '#008000',
  	navy: '#000080', blue: '#0000ff', aqua: '#00ffff', teal: '#008080',
  	black: '#000000', silver: '#c0c0c0', gray: '#808080'
  };
  
  var map = function(array, fn){
  	var results = [];
  	for (var i = 0, l = array.length; i < l; i++)
  		results[i] = fn(array[i], i);
  	return results;
  };
  
  var Color = function(color, type){
  	
  	if (color.isColor){
  		
  		this.red = color.red;
  		this.green = color.green;
  		this.blue = color.blue;
  		this.alpha = color.alpha;
  
  	} else {
  		
  		var namedColor = colors[color];
  		if (namedColor){
  			color = namedColor;
  			type = 'hex';
  		}
  
  		switch (typeof color){
  			case 'string': if (!type) type = (type = color.match(/^rgb|^hsb|^hsl/)) ? type[0] : 'hex'; break;
  			case 'object': type = type || 'rgb'; color = color.toString(); break;
  			case 'number': type = 'hex'; color = color.toString(16); break;
  		}
  
  		color = Color['parse' + type.toUpperCase()](color);
  		this.red = color[0];
  		this.green = color[1];
  		this.blue = color[2];
  		this.alpha = color[3];
  	}
  	
  	this.isColor = true;
  
  };
  
  var limit = function(number, min, max){
  	return Math.min(max, Math.max(min, number));
  };
  
  var listMatch = /([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,?\s*([-.\d]*\%?)/;
  var hexMatch = /^#?([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{0,2})$/i;
  
  Color.parseRGB = function(color){
  	return map(color.match(listMatch).slice(1), function(bit, i){
  		if (bit) bit = parseFloat(bit) * (bit[bit.length - 1] == '%' ? 2.55 : 1);
  		return (i < 3) ? Math.round(((bit %= 256) < 0) ? bit + 256 : bit) : limit(((bit === '') ? 1 : Number(bit)), 0, 1);
  	});
  };
  	
  Color.parseHEX = function(color){
  	if (color.length == 1) color = color + color + color;
  	return map(color.match(hexMatch).slice(1), function(bit, i){
  		if (i == 3) return (bit) ? parseInt(bit, 16) / 255 : 1;
  		return parseInt((bit.length == 1) ? bit + bit : bit, 16);
  	});
  };
  	
  Color.parseHSB = function(color){
  	var hsb = map(color.match(listMatch).slice(1), function(bit, i){
  		if (bit) bit = parseFloat(bit);
  		if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
  		else if (i < 3) return limit(Math.round(bit), 0, 100);
  		else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
  	});
  	
  	var a = hsb[3];
  	var br = Math.round(hsb[2] / 100 * 255);
  	if (hsb[1] == 0) return [br, br, br, a];
  		
  	var hue = hsb[0];
  	var f = hue % 60;
  	var p = Math.round((hsb[2] * (100 - hsb[1])) / 10000 * 255);
  	var q = Math.round((hsb[2] * (6000 - hsb[1] * f)) / 600000 * 255);
  	var t = Math.round((hsb[2] * (6000 - hsb[1] * (60 - f))) / 600000 * 255);
  
  	switch (Math.floor(hue / 60)){
  		case 0: return [br, t, p, a];
  		case 1: return [q, br, p, a];
  		case 2: return [p, br, t, a];
  		case 3: return [p, q, br, a];
  		case 4: return [t, p, br, a];
  		default: return [br, p, q, a];
  	}
  };
  
  Color.parseHSL = function(color){
  	var hsb = map(color.match(listMatch).slice(1), function(bit, i){
  		if (bit) bit = parseFloat(bit);
  		if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
  		else if (i < 3) return limit(Math.round(bit), 0, 100);
  		else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
  	});
  
  	var h = hsb[0] / 60;
  	var s = hsb[1] / 100;
  	var l = hsb[2] / 100;
  	var a = hsb[3];
  	
  	var c = (1 - Math.abs(2 * l - 1)) * s;
  	var x = c * (1 - Math.abs(h % 2 - 1));
  	var m = l - c / 2;
  	
  	var p = Math.round((c + m) * 255);
  	var q = Math.round((x + m) * 255);
  	var t = Math.round((m) * 255);
  
  	switch (Math.floor(h)){
  		case 0: return [p, q, t, a];
  		case 1: return [q, p, t, a];
  		case 2: return [t, p, q, a];
  		case 3: return [t, q, p, a];
  		case 4: return [q, t, p, a];
  		default: return [p, t, q, a];
  	}
  };
  
  var toString = function(type, array){
  	if (array[3] != 1) type += 'a';
  	else array.pop();
  	return type + '(' + array.join(', ') + ')';
  };
  
  Color.prototype = {
  
  	toHSB: function(array){
  		var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
  
  		var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
  		var hue = 0, saturation = (delta != 0) ? delta / max : 0, brightness = max / 255;
  		if (saturation){
  			var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
  			hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
  			if ((hue /= 6) < 0) hue++;
  		}
  
  		var hsb = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100), alpha];
  
  		return (array) ? hsb : toString('hsb', hsb);
  	},
  
  	toHSL: function(array){
  		var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
  
  		var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
  		var hue = 0, saturation = (delta != 0) ? delta / (255 - Math.abs((max + min) - 255)) : 0, lightness = (max + min) / 512;
  		if (saturation){
  			var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
  			hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
  			if ((hue /= 6) < 0) hue++;
  		}
  
  		var hsl = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(lightness * 100), alpha];
  
  		return (array) ? hsl : toString('hsl', hsl);
  	},
  
  	toHEX: function(array){
  
  		var a = this.alpha;
  		var alpha = ((a = Math.round((a * 255)).toString(16)).length == 1) ? a + a : a;
  		
  		var hex = map([this.red, this.green, this.blue], function(bit){
  			bit = bit.toString(16);
  			return (bit.length == 1) ? '0' + bit : bit;
  		});
  		
  		return (array) ? hex.concat(alpha) : '#' + hex.join('') + ((alpha == 'ff') ? '' : alpha);
  	},
  	
  	toRGB: function(array){
  		var rgb = [this.red, this.green, this.blue, this.alpha];
  		return (array) ? rgb : toString('rgb', rgb);
  	}
  
  };
  
  Color.prototype.toString = Color.prototype.toRGB;
  
  Color.hex = function(hex){
  	return new Color(hex, 'hex');
  };
  
  if (this && this.hex == null) this.hex = Color.hex;
  
  Color.hsb = function(h, s, b, a){
  	return new Color([h || 0, s || 0, b || 0, (a == null) ? 1 : a], 'hsb');
  };
  
  if (this && this.hsb == null) this.hsb = Color.hsb;
  
  Color.hsl = function(h, s, l, a){
  	return new Color([h || 0, s || 0, l || 0, (a == null) ? 1 : a], 'hsl');
  };
  
  if (this && this.hsl == null) this.hsl = Color.hsl;
  
  Color.rgb = function(r, g, b, a){
  	return new Color([r || 0, g || 0, b || 0, (a == null) ? 1 : a], 'rgb');
  };
  
  if (this && this.rgb == null) this.rgb = Color.rgb;
  
  Color.detach = function(color){
  	color = new Color(color);
  	return [Color.rgb(color.red, color.green, color.blue).toString(), color.alpha];
  };
  
  module.exports = Color;
  