keep removing MochiKit dependencies
[dygraphs.git] / mochikit_v14 / MochiKit / Color.js
1 /***
2
3 MochiKit.Color 1.4
4
5 See <http://mochikit.com/> for documentation, downloads, license, etc.
6
7 (c) 2005 Bob Ippolito and others. All rights Reserved.
8
9 ***/
10
11 if (typeof(dojo) != 'undefined') {
12 dojo.provide('MochiKit.Color');
13 dojo.require('MochiKit.Base');
14 }
15
16 if (typeof(JSAN) != 'undefined') {
17 JSAN.use("MochiKit.Base", []);
18 }
19
20 try {
21 if (typeof(MochiKit.Base) == 'undefined') {
22 throw "";
23 }
24 } catch (e) {
25 throw "MochiKit.Color depends on MochiKit.Base";
26 }
27
28 if (typeof(MochiKit.Color) == "undefined") {
29 MochiKit.Color = {};
30 }
31
32 MochiKit.Color.NAME = "MochiKit.Color";
33 MochiKit.Color.VERSION = "1.4";
34
35 MochiKit.Color.__repr__ = function () {
36 return "[" + this.NAME + " " + this.VERSION + "]";
37 };
38
39 MochiKit.Color.toString = function () {
40 return this.__repr__();
41 };
42
43
44 /** @id MochiKit.Color.Color */
45 MochiKit.Color.Color = function (red, green, blue, alpha) {
46 if (typeof(alpha) == 'undefined' || alpha === null) {
47 alpha = 1.0;
48 }
49 this.rgb = {
50 r: red,
51 g: green,
52 b: blue,
53 a: alpha
54 };
55 };
56
57
58 // Prototype methods
59
60 MochiKit.Color.Color.prototype = {
61
62 __class__: MochiKit.Color.Color,
63
64 /** @id MochiKit.Color.Color.prototype.colorWithAlpha */
65 colorWithAlpha: function (alpha) {
66 var rgb = this.rgb;
67 var m = MochiKit.Color;
68 return m.Color.fromRGB(rgb.r, rgb.g, rgb.b, alpha);
69 },
70
71 /** @id MochiKit.Color.Color.prototype.colorWithHue */
72 colorWithHue: function (hue) {
73 // get an HSL model, and set the new hue...
74 var hsl = this.asHSL();
75 hsl.h = hue;
76 var m = MochiKit.Color;
77 // convert back to RGB...
78 return m.Color.fromHSL(hsl);
79 },
80
81 /** @id MochiKit.Color.Color.prototype.colorWithSaturation */
82 colorWithSaturation: function (saturation) {
83 // get an HSL model, and set the new hue...
84 var hsl = this.asHSL();
85 hsl.s = saturation;
86 var m = MochiKit.Color;
87 // convert back to RGB...
88 return m.Color.fromHSL(hsl);
89 },
90
91 /** @id MochiKit.Color.Color.prototype.colorWithLightness */
92 colorWithLightness: function (lightness) {
93 // get an HSL model, and set the new hue...
94 var hsl = this.asHSL();
95 hsl.l = lightness;
96 var m = MochiKit.Color;
97 // convert back to RGB...
98 return m.Color.fromHSL(hsl);
99 },
100
101 /** @id MochiKit.Color.Color.prototype.darkerColorWithLevel */
102 darkerColorWithLevel: function (level) {
103 var hsl = this.asHSL();
104 hsl.l = Math.max(hsl.l - level, 0);
105 var m = MochiKit.Color;
106 return m.Color.fromHSL(hsl);
107 },
108
109 /** @id MochiKit.Color.Color.prototype.lighterColorWithLevel */
110 lighterColorWithLevel: function (level) {
111 var hsl = this.asHSL();
112 hsl.l = Math.min(hsl.l + level, 1);
113 var m = MochiKit.Color;
114 return m.Color.fromHSL(hsl);
115 },
116
117 /** @id MochiKit.Color.Color.prototype.blendedColor */
118 blendedColor: function (other, /* optional */ fraction) {
119 if (typeof(fraction) == 'undefined' || fraction === null) {
120 fraction = 0.5;
121 }
122 var sf = 1.0 - fraction;
123 var s = this.rgb;
124 var d = other.rgb;
125 var df = fraction;
126 return MochiKit.Color.Color.fromRGB(
127 (s.r * sf) + (d.r * df),
128 (s.g * sf) + (d.g * df),
129 (s.b * sf) + (d.b * df),
130 (s.a * sf) + (d.a * df)
131 );
132 },
133
134 /** @id MochiKit.Color.Color.prototype.compareRGB */
135 compareRGB: function (other) {
136 var a = this.asRGB();
137 var b = other.asRGB();
138 return MochiKit.Base.compare(
139 [a.r, a.g, a.b, a.a],
140 [b.r, b.g, b.b, b.a]
141 );
142 },
143
144 /** @id MochiKit.Color.Color.prototype.isLight */
145 isLight: function () {
146 return this.asHSL().b > 0.5;
147 },
148
149 /** @id MochiKit.Color.Color.prototype.isDark */
150 isDark: function () {
151 return (!this.isLight());
152 },
153
154 /** @id MochiKit.Color.Color.prototype.toHSLString */
155 toHSLString: function () {
156 var c = this.asHSL();
157 var ccc = MochiKit.Color.clampColorComponent;
158 var rval = this._hslString;
159 if (!rval) {
160 var mid = (
161 ccc(c.h, 360).toFixed(0)
162 + "," + ccc(c.s, 100).toPrecision(4) + "%"
163 + "," + ccc(c.l, 100).toPrecision(4) + "%"
164 );
165 var a = c.a;
166 if (a >= 1) {
167 a = 1;
168 rval = "hsl(" + mid + ")";
169 } else {
170 if (a <= 0) {
171 a = 0;
172 }
173 rval = "hsla(" + mid + "," + a + ")";
174 }
175 this._hslString = rval;
176 }
177 return rval;
178 },
179
180 /** @id MochiKit.Color.Color.prototype.toRGBString */
181 toRGBString: function () {
182 var c = this.rgb;
183 var ccc = MochiKit.Color.clampColorComponent;
184 var rval = this._rgbString;
185 if (!rval) {
186 var mid = (
187 ccc(c.r, 255).toFixed(0)
188 + "," + ccc(c.g, 255).toFixed(0)
189 + "," + ccc(c.b, 255).toFixed(0)
190 );
191 if (c.a != 1) {
192 rval = "rgba(" + mid + "," + c.a + ")";
193 } else {
194 rval = "rgb(" + mid + ")";
195 }
196 this._rgbString = rval;
197 }
198 return rval;
199 },
200
201 /** @id MochiKit.Color.Color.prototype.asRGB */
202 asRGB: function () {
203 return MochiKit.Base.clone(this.rgb);
204 },
205
206 /** @id MochiKit.Color.Color.prototype.toHexString */
207 toHexString: function () {
208 var m = MochiKit.Color;
209 var c = this.rgb;
210 var ccc = MochiKit.Color.clampColorComponent;
211 var rval = this._hexString;
212 if (!rval) {
213 rval = ("#" +
214 m.toColorPart(ccc(c.r, 255)) +
215 m.toColorPart(ccc(c.g, 255)) +
216 m.toColorPart(ccc(c.b, 255))
217 );
218 this._hexString = rval;
219 }
220 return rval;
221 },
222
223 /** @id MochiKit.Color.Color.prototype.asHSV */
224 asHSV: function () {
225 var hsv = this.hsv;
226 var c = this.rgb;
227 if (typeof(hsv) == 'undefined' || hsv === null) {
228 hsv = MochiKit.Color.rgbToHSV(this.rgb);
229 this.hsv = hsv;
230 }
231 return MochiKit.Base.clone(hsv);
232 },
233
234 /** @id MochiKit.Color.Color.prototype.asHSL */
235 asHSL: function () {
236 var hsl = this.hsl;
237 var c = this.rgb;
238 if (typeof(hsl) == 'undefined' || hsl === null) {
239 hsl = MochiKit.Color.rgbToHSL(this.rgb);
240 this.hsl = hsl;
241 }
242 return MochiKit.Base.clone(hsl);
243 },
244
245 /** @id MochiKit.Color.Color.prototype.toString */
246 toString: function () {
247 return this.toRGBString();
248 },
249
250 /** @id MochiKit.Color.Color.prototype.repr */
251 repr: function () {
252 var c = this.rgb;
253 var col = [c.r, c.g, c.b, c.a];
254 return this.__class__.NAME + "(" + col.join(", ") + ")";
255 }
256
257 };
258
259 // Constructor methods
260
261 MochiKit.Base.update(MochiKit.Color.Color, {
262 /** @id MochiKit.Color.Color.fromRGB */
263 fromRGB: function (red, green, blue, alpha) {
264 // designated initializer
265 var Color = MochiKit.Color.Color;
266 if (arguments.length == 1) {
267 var rgb = red;
268 red = rgb.r;
269 green = rgb.g;
270 blue = rgb.b;
271 if (typeof(rgb.a) == 'undefined') {
272 alpha = undefined;
273 } else {
274 alpha = rgb.a;
275 }
276 }
277 return new Color(red, green, blue, alpha);
278 },
279
280 /** @id MochiKit.Color.Color.fromHSL */
281 fromHSL: function (hue, saturation, lightness, alpha) {
282 var m = MochiKit.Color;
283 return m.Color.fromRGB(m.hslToRGB.apply(m, arguments));
284 },
285
286 /** @id MochiKit.Color.Color.fromHSV */
287 fromHSV: function (hue, saturation, value, alpha) {
288 var m = MochiKit.Color;
289 return m.Color.fromRGB(m.hsvToRGB.apply(m, arguments));
290 },
291
292 /** @id MochiKit.Color.Color.fromName */
293 fromName: function (name) {
294 var Color = MochiKit.Color.Color;
295 // Opera 9 seems to "quote" named colors(?!)
296 if (name.charAt(0) == '"') {
297 name = name.substr(1, name.length - 2);
298 }
299 var htmlColor = Color._namedColors[name.toLowerCase()];
300 if (typeof(htmlColor) == 'string') {
301 return Color.fromHexString(htmlColor);
302 } else if (name == "transparent") {
303 return Color.transparentColor();
304 }
305 return null;
306 },
307
308 /** @id MochiKit.Color.Color.fromString */
309 fromString: function (colorString) {
310 var self = MochiKit.Color.Color;
311 var three = colorString.substr(0, 3);
312 if (three == "rgb") {
313 return self.fromRGBString(colorString);
314 } else if (three == "hsl") {
315 return self.fromHSLString(colorString);
316 } else if (colorString.charAt(0) == "#") {
317 return self.fromHexString(colorString);
318 }
319 return self.fromName(colorString);
320 },
321
322
323 /** @id MochiKit.Color.Color.fromHexString */
324 fromHexString: function (hexCode) {
325 if (hexCode.charAt(0) == '#') {
326 hexCode = hexCode.substring(1);
327 }
328 var components = [];
329 var i, hex;
330 if (hexCode.length == 3) {
331 for (i = 0; i < 3; i++) {
332 hex = hexCode.substr(i, 1);
333 components.push(parseInt(hex + hex, 16) / 255.0);
334 }
335 } else {
336 for (i = 0; i < 6; i += 2) {
337 hex = hexCode.substr(i, 2);
338 components.push(parseInt(hex, 16) / 255.0);
339 }
340 }
341 var Color = MochiKit.Color.Color;
342 return Color.fromRGB.apply(Color, components);
343 },
344
345
346 _fromColorString: function (pre, method, scales, colorCode) {
347 // parses either HSL or RGB
348 if (colorCode.indexOf(pre) === 0) {
349 colorCode = colorCode.substring(colorCode.indexOf("(", 3) + 1, colorCode.length - 1);
350 }
351 var colorChunks = colorCode.split(/\s*,\s*/);
352 var colorFloats = [];
353 for (var i = 0; i < colorChunks.length; i++) {
354 var c = colorChunks[i];
355 var val;
356 var three = c.substring(c.length - 3);
357 if (c.charAt(c.length - 1) == '%') {
358 val = 0.01 * parseFloat(c.substring(0, c.length - 1));
359 } else if (three == "deg") {
360 val = parseFloat(c) / 360.0;
361 } else if (three == "rad") {
362 val = parseFloat(c) / (Math.PI * 2);
363 } else {
364 val = scales[i] * parseFloat(c);
365 }
366 colorFloats.push(val);
367 }
368 return this[method].apply(this, colorFloats);
369 },
370
371 /** @id MochiKit.Color.Color.fromBackground */
372 fromBackground: function (elem) {
373 var cls = MochiKit.Color.Color;
374 return cls.fromComputedStyle(
375 elem, "backgroundColor", "background-color") || cls.whiteColor();
376 },
377
378 /** @id MochiKit.Color.Color.fromText */
379 fromText: function (elem) {
380 var cls = MochiKit.Color.Color;
381 return cls.fromComputedStyle(
382 elem, "color", "color") || cls.blackColor();
383 },
384
385 /** @id MochiKit.Color.Color.namedColors */
386 namedColors: function () {
387 return MochiKit.Base.clone(MochiKit.Color.Color._namedColors);
388 }
389 });
390
391
392 // Module level functions
393
394 MochiKit.Base.update(MochiKit.Color, {
395 /** @id MochiKit.Color.clampColorComponent */
396 clampColorComponent: function (v, scale) {
397 v *= scale;
398 if (v < 0) {
399 return 0;
400 } else if (v > scale) {
401 return scale;
402 } else {
403 return v;
404 }
405 },
406
407 _hslValue: function (n1, n2, hue) {
408 if (hue > 6.0) {
409 hue -= 6.0;
410 } else if (hue < 0.0) {
411 hue += 6.0;
412 }
413 var val;
414 if (hue < 1.0) {
415 val = n1 + (n2 - n1) * hue;
416 } else if (hue < 3.0) {
417 val = n2;
418 } else if (hue < 4.0) {
419 val = n1 + (n2 - n1) * (4.0 - hue);
420 } else {
421 val = n1;
422 }
423 return val;
424 },
425
426 /** @id MochiKit.Color.hsvToRGB */
427 hsvToRGB: function (hue, saturation, value, alpha) {
428 if (arguments.length == 1) {
429 var hsv = hue;
430 hue = hsv.h;
431 saturation = hsv.s;
432 value = hsv.v;
433 alpha = hsv.a;
434 }
435 var red;
436 var green;
437 var blue;
438 if (saturation === 0) {
439 red = value;
440 green = value;
441 blue = value;
442 } else {
443 var i = Math.floor(hue * 6);
444 var f = (hue * 6) - i;
445 var p = value * (1 - saturation);
446 var q = value * (1 - (saturation * f));
447 var t = value * (1 - (saturation * (1 - f)));
448 switch (i) {
449 case 1: red = q; green = value; blue = p; break;
450 case 2: red = p; green = value; blue = t; break;
451 case 3: red = p; green = q; blue = value; break;
452 case 4: red = t; green = p; blue = value; break;
453 case 5: red = value; green = p; blue = q; break;
454 case 6: // fall through
455 case 0: red = value; green = t; blue = p; break;
456 }
457 }
458 return {
459 r: red,
460 g: green,
461 b: blue,
462 a: alpha
463 };
464 },
465
466 /** @id MochiKit.Color.hslToRGB */
467 hslToRGB: function (hue, saturation, lightness, alpha) {
468 if (arguments.length == 1) {
469 var hsl = hue;
470 hue = hsl.h;
471 saturation = hsl.s;
472 lightness = hsl.l;
473 alpha = hsl.a;
474 }
475 var red;
476 var green;
477 var blue;
478 if (saturation === 0) {
479 red = lightness;
480 green = lightness;
481 blue = lightness;
482 } else {
483 var m2;
484 if (lightness <= 0.5) {
485 m2 = lightness * (1.0 + saturation);
486 } else {
487 m2 = lightness + saturation - (lightness * saturation);
488 }
489 var m1 = (2.0 * lightness) - m2;
490 var f = MochiKit.Color._hslValue;
491 var h6 = hue * 6.0;
492 red = f(m1, m2, h6 + 2);
493 green = f(m1, m2, h6);
494 blue = f(m1, m2, h6 - 2);
495 }
496 return {
497 r: red,
498 g: green,
499 b: blue,
500 a: alpha
501 };
502 },
503
504 /** @id MochiKit.Color.rgbToHSV */
505 rgbToHSV: function (red, green, blue, alpha) {
506 if (arguments.length == 1) {
507 var rgb = red;
508 red = rgb.r;
509 green = rgb.g;
510 blue = rgb.b;
511 alpha = rgb.a;
512 }
513 var max = Math.max(Math.max(red, green), blue);
514 var min = Math.min(Math.min(red, green), blue);
515 var hue;
516 var saturation;
517 var value = max;
518 if (min == max) {
519 hue = 0;
520 saturation = 0;
521 } else {
522 var delta = (max - min);
523 saturation = delta / max;
524
525 if (red == max) {
526 hue = (green - blue) / delta;
527 } else if (green == max) {
528 hue = 2 + ((blue - red) / delta);
529 } else {
530 hue = 4 + ((red - green) / delta);
531 }
532 hue /= 6;
533 if (hue < 0) {
534 hue += 1;
535 }
536 if (hue > 1) {
537 hue -= 1;
538 }
539 }
540 return {
541 h: hue,
542 s: saturation,
543 v: value,
544 a: alpha
545 };
546 },
547
548 /** @id MochiKit.Color.rgbToHSL */
549 rgbToHSL: function (red, green, blue, alpha) {
550 if (arguments.length == 1) {
551 var rgb = red;
552 red = rgb.r;
553 green = rgb.g;
554 blue = rgb.b;
555 alpha = rgb.a;
556 }
557 var max = Math.max(red, Math.max(green, blue));
558 var min = Math.min(red, Math.min(green, blue));
559 var hue;
560 var saturation;
561 var lightness = (max + min) / 2.0;
562 var delta = max - min;
563 if (delta === 0) {
564 hue = 0;
565 saturation = 0;
566 } else {
567 if (lightness <= 0.5) {
568 saturation = delta / (max + min);
569 } else {
570 saturation = delta / (2 - max - min);
571 }
572 if (red == max) {
573 hue = (green - blue) / delta;
574 } else if (green == max) {
575 hue = 2 + ((blue - red) / delta);
576 } else {
577 hue = 4 + ((red - green) / delta);
578 }
579 hue /= 6;
580 if (hue < 0) {
581 hue += 1;
582 }
583 if (hue > 1) {
584 hue -= 1;
585 }
586
587 }
588 return {
589 h: hue,
590 s: saturation,
591 l: lightness,
592 a: alpha
593 };
594 },
595
596 /** @id MochiKit.Color.toColorPart */
597 toColorPart: function (num) {
598 num = Math.round(num);
599 var digits = num.toString(16);
600 if (num < 16) {
601 return '0' + digits;
602 }
603 return digits;
604 },
605
606 __new__: function () {
607 var m = MochiKit.Base;
608 /** @id MochiKit.Color.fromRGBString */
609 this.Color.fromRGBString = m.bind(
610 this.Color._fromColorString, this.Color, "rgb", "fromRGB",
611 [1.0/255.0, 1.0/255.0, 1.0/255.0, 1]
612 );
613 /** @id MochiKit.Color.fromHSLString */
614 this.Color.fromHSLString = m.bind(
615 this.Color._fromColorString, this.Color, "hsl", "fromHSL",
616 [1.0/360.0, 0.01, 0.01, 1]
617 );
618
619 var third = 1.0 / 3.0;
620 /** @id MochiKit.Color.colors */
621 var colors = {
622 // NSColor colors plus transparent
623 /** @id MochiKit.Color.blackColor */
624 black: [0, 0, 0],
625 /** @id MochiKit.Color.blueColor */
626 blue: [0, 0, 1],
627 /** @id MochiKit.Color.brownColor */
628 brown: [0.6, 0.4, 0.2],
629 /** @id MochiKit.Color.cyanColor */
630 cyan: [0, 1, 1],
631 /** @id MochiKit.Color.darkGrayColor */
632 darkGray: [third, third, third],
633 /** @id MochiKit.Color.grayColor */
634 gray: [0.5, 0.5, 0.5],
635 /** @id MochiKit.Color.greenColor */
636 green: [0, 1, 0],
637 /** @id MochiKit.Color.lightGrayColor */
638 lightGray: [2 * third, 2 * third, 2 * third],
639 /** @id MochiKit.Color.magentaColor */
640 magenta: [1, 0, 1],
641 /** @id MochiKit.Color.orangeColor */
642 orange: [1, 0.5, 0],
643 /** @id MochiKit.Color.purpleColor */
644 purple: [0.5, 0, 0.5],
645 /** @id MochiKit.Color.redColor */
646 red: [1, 0, 0],
647 /** @id MochiKit.Color.transparentColor */
648 transparent: [0, 0, 0, 0],
649 /** @id MochiKit.Color.whiteColor */
650 white: [1, 1, 1],
651 /** @id MochiKit.Color.yellowColor */
652 yellow: [1, 1, 0]
653 };
654
655 var makeColor = function (name, r, g, b, a) {
656 var rval = this.fromRGB(r, g, b, a);
657 this[name] = function () { return rval; };
658 return rval;
659 };
660
661 for (var k in colors) {
662 var name = k + "Color";
663 var bindArgs = m.concat(
664 [makeColor, this.Color, name],
665 colors[k]
666 );
667 this.Color[name] = m.bind.apply(null, bindArgs);
668 }
669
670 var isColor = function () {
671 for (var i = 0; i < arguments.length; i++) {
672 if (!(arguments[i] instanceof Color)) {
673 return false;
674 }
675 }
676 return true;
677 };
678
679 var compareColor = function (a, b) {
680 return a.compareRGB(b);
681 };
682
683 m.nameFunctions(this);
684
685 m.registerComparator(this.Color.NAME, isColor, compareColor);
686
687 this.EXPORT_TAGS = {
688 ":common": this.EXPORT,
689 ":all": m.concat(this.EXPORT, this.EXPORT_OK)
690 };
691
692 }
693 });
694
695 MochiKit.Color.EXPORT = [
696 "Color"
697 ];
698
699 MochiKit.Color.EXPORT_OK = [
700 "clampColorComponent",
701 "rgbToHSL",
702 "hslToRGB",
703 "rgbToHSV",
704 "hsvToRGB",
705 "toColorPart"
706 ];
707
708 MochiKit.Color.__new__();
709
710 MochiKit.Base._exportSymbols(this, MochiKit.Color);
711
712 // Full table of css3 X11 colors <http://www.w3.org/TR/css3-color/#X11COLORS>
713
714 MochiKit.Color.Color._namedColors = {
715 aliceblue: "#f0f8ff",
716 antiquewhite: "#faebd7",
717 aqua: "#00ffff",
718 aquamarine: "#7fffd4",
719 azure: "#f0ffff",
720 beige: "#f5f5dc",
721 bisque: "#ffe4c4",
722 black: "#000000",
723 blanchedalmond: "#ffebcd",
724 blue: "#0000ff",
725 blueviolet: "#8a2be2",
726 brown: "#a52a2a",
727 burlywood: "#deb887",
728 cadetblue: "#5f9ea0",
729 chartreuse: "#7fff00",
730 chocolate: "#d2691e",
731 coral: "#ff7f50",
732 cornflowerblue: "#6495ed",
733 cornsilk: "#fff8dc",
734 crimson: "#dc143c",
735 cyan: "#00ffff",
736 darkblue: "#00008b",
737 darkcyan: "#008b8b",
738 darkgoldenrod: "#b8860b",
739 darkgray: "#a9a9a9",
740 darkgreen: "#006400",
741 darkgrey: "#a9a9a9",
742 darkkhaki: "#bdb76b",
743 darkmagenta: "#8b008b",
744 darkolivegreen: "#556b2f",
745 darkorange: "#ff8c00",
746 darkorchid: "#9932cc",
747 darkred: "#8b0000",
748 darksalmon: "#e9967a",
749 darkseagreen: "#8fbc8f",
750 darkslateblue: "#483d8b",
751 darkslategray: "#2f4f4f",
752 darkslategrey: "#2f4f4f",
753 darkturquoise: "#00ced1",
754 darkviolet: "#9400d3",
755 deeppink: "#ff1493",
756 deepskyblue: "#00bfff",
757 dimgray: "#696969",
758 dimgrey: "#696969",
759 dodgerblue: "#1e90ff",
760 firebrick: "#b22222",
761 floralwhite: "#fffaf0",
762 forestgreen: "#228b22",
763 fuchsia: "#ff00ff",
764 gainsboro: "#dcdcdc",
765 ghostwhite: "#f8f8ff",
766 gold: "#ffd700",
767 goldenrod: "#daa520",
768 gray: "#808080",
769 green: "#008000",
770 greenyellow: "#adff2f",
771 grey: "#808080",
772 honeydew: "#f0fff0",
773 hotpink: "#ff69b4",
774 indianred: "#cd5c5c",
775 indigo: "#4b0082",
776 ivory: "#fffff0",
777 khaki: "#f0e68c",
778 lavender: "#e6e6fa",
779 lavenderblush: "#fff0f5",
780 lawngreen: "#7cfc00",
781 lemonchiffon: "#fffacd",
782 lightblue: "#add8e6",
783 lightcoral: "#f08080",
784 lightcyan: "#e0ffff",
785 lightgoldenrodyellow: "#fafad2",
786 lightgray: "#d3d3d3",
787 lightgreen: "#90ee90",
788 lightgrey: "#d3d3d3",
789 lightpink: "#ffb6c1",
790 lightsalmon: "#ffa07a",
791 lightseagreen: "#20b2aa",
792 lightskyblue: "#87cefa",
793 lightslategray: "#778899",
794 lightslategrey: "#778899",
795 lightsteelblue: "#b0c4de",
796 lightyellow: "#ffffe0",
797 lime: "#00ff00",
798 limegreen: "#32cd32",
799 linen: "#faf0e6",
800 magenta: "#ff00ff",
801 maroon: "#800000",
802 mediumaquamarine: "#66cdaa",
803 mediumblue: "#0000cd",
804 mediumorchid: "#ba55d3",
805 mediumpurple: "#9370db",
806 mediumseagreen: "#3cb371",
807 mediumslateblue: "#7b68ee",
808 mediumspringgreen: "#00fa9a",
809 mediumturquoise: "#48d1cc",
810 mediumvioletred: "#c71585",
811 midnightblue: "#191970",
812 mintcream: "#f5fffa",
813 mistyrose: "#ffe4e1",
814 moccasin: "#ffe4b5",
815 navajowhite: "#ffdead",
816 navy: "#000080",
817 oldlace: "#fdf5e6",
818 olive: "#808000",
819 olivedrab: "#6b8e23",
820 orange: "#ffa500",
821 orangered: "#ff4500",
822 orchid: "#da70d6",
823 palegoldenrod: "#eee8aa",
824 palegreen: "#98fb98",
825 paleturquoise: "#afeeee",
826 palevioletred: "#db7093",
827 papayawhip: "#ffefd5",
828 peachpuff: "#ffdab9",
829 peru: "#cd853f",
830 pink: "#ffc0cb",
831 plum: "#dda0dd",
832 powderblue: "#b0e0e6",
833 purple: "#800080",
834 red: "#ff0000",
835 rosybrown: "#bc8f8f",
836 royalblue: "#4169e1",
837 saddlebrown: "#8b4513",
838 salmon: "#fa8072",
839 sandybrown: "#f4a460",
840 seagreen: "#2e8b57",
841 seashell: "#fff5ee",
842 sienna: "#a0522d",
843 silver: "#c0c0c0",
844 skyblue: "#87ceeb",
845 slateblue: "#6a5acd",
846 slategray: "#708090",
847 slategrey: "#708090",
848 snow: "#fffafa",
849 springgreen: "#00ff7f",
850 steelblue: "#4682b4",
851 tan: "#d2b48c",
852 teal: "#008080",
853 thistle: "#d8bfd8",
854 tomato: "#ff6347",
855 turquoise: "#40e0d0",
856 violet: "#ee82ee",
857 wheat: "#f5deb3",
858 white: "#ffffff",
859 whitesmoke: "#f5f5f5",
860 yellow: "#ffff00",
861 yellowgreen: "#9acd32"
862 };