blob: 2fd401bea68294403846186da3735f34e085764c [file]
// Copyright 2012 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview Color utilities.
*/
import {lib} from './lib.js';
/** @const */
lib.colors = {};
/**
* First, some canned regular expressions we're going to use in this file.
*
*
* BRACE YOURSELF
*
* ,~~~~.
* |>_< ~~
* 3`---'-/.
* 3:::::\v\
* =o=:::::\,\
* | :::::\,,\
*
* THE REGULAR EXPRESSIONS
* ARE COMING.
*
* There's no way to break long RE literals in JavaScript. Fix that why don't
* you? Oh, and also there's no way to write a string that doesn't interpret
* escapes.
*
* Instead, we stoop to this .replace() trick.
*/
const re_ = {
// CSS hex color, #RGB or #RGBA.
hex16: /^#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?$/i,
// CSS hex color, #RRGGBB or #RRGGBBAA.
hex24: /^#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?$/i,
// CSS rgb color, rgb(rrr,ggg,bbb[,aaa]).
// rgba() is an alias for rgb().
// https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/color_value/rgb
rgb: new RegExp(
('^/s*rgba?/s*' +
'/(/s*(/d{1,3})/s*,/s*(/d{1,3})/s*,/s*(/d{1,3})/s*' +
'(?:,/s*(/d+(?:/./d+)?)/s*)?/)/s*$'
).replace(/\//g, '\\'), 'i'),
// CSS hsl color, hsl(hhh,sss%,lll%[,aaa]).
// hsla() is an alias for hsl().
// https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/color_value/hsl
hsl: new RegExp(
('^/s*hsla?/s*' +
'/(/s*(/d{1,3})/s*,/s*(/d{1,3})/s*%/s*,/s*(/d{1,3})/s*%/s*' +
'(?:,/s*(/d+(?:/./d+)?)/s*)?/)/s*$'
).replace(/\//g, '\\'), 'i'),
// An X11 "rgb:dddd/dddd/dddd" value.
x11rgb: /^\s*rgb:([a-f0-9]{1,4})\/([a-f0-9]{1,4})\/([a-f0-9]{1,4})\s*$/i,
// English color name.
name: /[a-z][a-z0-9\s]+/,
};
/**
* Convert a CSS rgb(ddd,ddd,ddd) color value into an X11 color value.
*
* Other CSS color values are ignored to ensure sanitary data handling.
*
* Each 'ddd' component is a one byte value specified in decimal.
*
* @param {string} value The CSS color value to convert.
* @return {?string} The X11 color value or null if the value could not be
* converted.
*/
lib.colors.rgbToX11 = function(value) {
function scale(v) {
v = (Math.min(v, 255) * 257).toString(16);
return lib.f.zpad(v, 4);
}
const ary = value.match(re_.rgb);
if (!ary) {
return null;
}
return 'rgb:' + scale(ary[1]) + '/' + scale(ary[2]) + '/' + scale(ary[3]);
};
/**
* Convert a legacy X11 color value into an CSS rgb(...) color value.
*
* They take the form:
* 12 bit: #RGB -> #R000G000B000
* 24 bit: #RRGGBB -> #RR00GG00BB00
* 36 bit: #RRRGGGBBB -> #RRR0GGG0BBB0
* 48 bit: #RRRRGGGGBBBB
* These are the most significant bits.
*
* Truncate values back down to 24 bit since that's all CSS supports.
*
* @param {string} v The X11 hex color value to convert.
* @return {?string} The CSS color value or null if the value could not be
* converted.
*/
lib.colors.x11HexToCSS = function(v) {
if (!v.startsWith('#')) {
return null;
}
// Strip the leading # off.
v = v.substr(1);
// Reject unknown sizes.
if ([3, 6, 9, 12].indexOf(v.length) == -1) {
return null;
}
// Reject non-hex values.
if (v.match(/[^a-f0-9]/i)) {
return null;
}
// Split the colors out.
const size = v.length / 3;
const r = v.substr(0, size);
const g = v.substr(size, size);
const b = v.substr(size + size, size);
// Normalize to 16 bits.
function norm16(v) {
v = parseInt(v, 16);
return size == 2 ? v : // 16 bit
size == 1 ? v << 4 : // 8 bit
v >> (4 * (size - 2)); // 24 or 32 bit
}
return lib.colors.arrayToRGB([r, g, b].map(norm16));
};
/**
* Convert an X11 color value into an CSS rgb(...) color value.
*
* The X11 value may be an X11 color name, or an RGB value of the form
* rgb:hhhh/hhhh/hhhh. If a component value is less than 4 digits it is
* padded out to 4, then scaled down to fit in a single byte.
*
* @param {string} v The X11 color value to convert.
* @return {?string} The CSS color value or null if the value could not be
* converted.
*/
lib.colors.x11ToCSS = function(v) {
function scale(v) {
// Pad out values with less than four digits. This padding (probably)
// matches xterm. It's difficult to say for sure since xterm seems to
// arrive at a padded value and then perform some combination of
// gamma correction, color space transformation, and quantization.
if (v.length == 1) {
// Single digits pad out to four by repeating the character. "f" becomes
// "ffff". Scaling down a hex value of this pattern by 257 is the same
// as cutting off one byte. We skip the middle step and just double
// the character.
return parseInt(v + v, 16);
}
if (v.length == 2) {
// Similar deal here. X11 pads two digit values by repeating the
// byte (or scale up by 257). Since we're going to scale it back
// down anyway, we can just return the original value.
return parseInt(v, 16);
}
if (v.length == 3) {
// Three digit values seem to be padded by repeating the final digit.
// e.g. 10f becomes 10ff.
v = v + v.substr(2);
}
// Scale down the 2 byte value.
return Math.round(parseInt(v, 16) / 257);
}
const ary = v.match(re_.x11rgb);
if (!ary) {
// Handle the legacy format.
if (v.startsWith('#')) {
return lib.colors.x11HexToCSS(v);
} else {
return lib.colors.nameToRGB(v);
}
}
ary.splice(0, 1);
return lib.colors.arrayToRGB(ary.map(scale));
};
/**
* Converts a CSS '#RRGGBB' or '#RRGGBBAA' color values into the rgb(...) form.
*
* @param {string} hex A single RGB or RGBA value to convert.
* @return {?string} The converted value.
*/
lib.colors.hexToRGB = function(hex) {
const hex16 = re_.hex16;
const hex24 = re_.hex24;
if (hex16.test(hex)) {
// Convert from RGB to RRGGBB and from RGBA to RRGGBBAA.
hex = `#${hex.match(/[a-f0-9]/gi).map((x) => `${x}${x}`).join('')}`;
}
const ary = hex.match(hex24);
if (!ary) {
return null;
}
const val = (index) => parseInt(ary[index + 1], 16);
ary[4] ??= 'ff';
return val(3) === 255
? `rgb(${val(0)}, ${val(1)}, ${val(2)})`
: `rgb(${val(0)}, ${val(1)}, ${val(2)}, ${val(3) / 255})`;
};
/**
* Converts CSS rgb(...) forms into their '#RRGGBB' or '#RRGGBBAA' color values.
*
* @param {string} rgb A single rgb(...) value to convert.
* @return {?string} The converted value.
*/
lib.colors.rgbToHex = function(rgb) {
const ary = lib.colors.crackRGB(rgb);
if (!ary) {
return null;
}
const hex = '#' + lib.f.zpad((
(parseInt(ary[0], 10) << 16) |
(parseInt(ary[1], 10) << 8) |
(parseInt(ary[2], 10) << 0)).toString(16), 6);
if (ary[3] === undefined || ary[3] === '1') {
return hex;
} else {
const alpha = Math.round(255 * parseFloat(ary[3])).toString(16);
return `${hex}${lib.f.zpad(alpha, 2)}`;
}
};
/**
* Split an HSL color into an array of its components.
*
* On success, a 4 element array will be returned. For hsl values, the alpha
* will be set to 1.
*
* @param {string} color The HSL CSS color spec.
* @return {?Array<string>} The HSL values split out.
*/
lib.colors.crackHSL = function(color) {
const ary = color.match(re_.hsl);
if (ary) {
ary.shift();
ary[3] ??= '1';
return Array.from(ary);
}
console.error(`Couldn't crack: ${color}`);
return null;
};
/**
* Wrapper to normalize user strings or numbers inputs to numbers.
*
* The parseInt function only accepts strings, so return numbers directly.
*
* @param {string|number} v
* @return {number}
*/
function maybeParseInt(v) {
return typeof v === 'number' ? v : parseInt(v, 10);
}
/**
* Converts HSL array to RGB array.
*
* The returned alpha component defaults to 1 if it isn't present in the input.
*
* The returned values are not rounded to preserve precision for computations,
* so should be rounded before they are used in CSS strings.
*
* @param {?Array<string|number>} hsl The HSL elements to convert.
* @return {!Array<number>} The RGB values.
*/
lib.colors.hslArrayToRgbArray = function(hsl) {
const hue = maybeParseInt(hsl[0]) / 60;
const sat = maybeParseInt(hsl[1]) / 100;
const light = maybeParseInt(hsl[2]) / 100;
// The following algorithm has been adapted from:
// https://www.w3.org/TR/css-color-4/#hsl-to-rgb
const hueToRgb = (t1, t2, hue) => {
if (hue < 0) {
hue += 6;
}
if (hue >= 6) {
hue -= 6;
}
if (hue < 1) {
return (t2 - t1) * hue + t1;
} else if (hue < 3) {
return t2;
} else if (hue < 4) {
return (t2 - t1) * (4 - hue) + t1;
} else {
return t1;
}
};
const t2 = light <= 0.5 ? light * (sat + 1) : light + sat - (light * sat);
const t1 = light * 2 - t2;
return [
255 * hueToRgb(t1, t2, hue + 2),
255 * hueToRgb(t1, t2, hue),
255 * hueToRgb(t1, t2, hue - 2),
hsl[3] !== undefined ? +hsl[3] : 1,
];
};
/**
* Converts a hsvx array to a HSL array. The hsvx array is an array of [hue
* (>=0, <=360), saturation (>=0, <=100), value (>=0, <=100), alpha] (alpha can
* be missing).
*
* The returned alpha component defaults to 1 if it isn't present in the input.
*
* The returned values are not rounded to preserve precision for computations,
* so should be rounded before they are used in CSS strings.
*
* @param {?Array<string|number>} hsvx The hsv or hsva array.
* @return {!Array<number>} The HSL array.
*/
lib.colors.hsvxArrayToHslArray = function(hsvx) {
const clamp = (x) => lib.f.clamp(x, 0, 100);
const [hue, saturation, value] = hsvx.map(parseFloat);
const hslLightness = clamp(value * (100 - saturation / 2) / 100);
let hslSaturation = 0;
if (hslLightness !== 0 && hslLightness !== 100) {
hslSaturation = clamp((value - hslLightness) /
Math.min(hslLightness, 100 - hslLightness) * 100);
}
return [
hue,
hslSaturation,
hslLightness,
hsvx.length === 4 ? +hsvx[3] : 1,
];
};
/**
* Converts a HSL array to a hsva array. The hsva array is an array of [hue
* (>=0, <=360), saturation (>=0, <=100), value (>=0, <=100), alpha].
*
* The returned alpha component defaults to 1 if it isn't present in the input.
*
* @param {?Array<string|number>} hsl The HSL array.
* @return {!Array<number>} The hsva array.
*/
lib.colors.hslArrayToHsvaArray = function(hsl) {
const clamp = (x) => lib.f.clamp(x, 0, 100);
const [hue, saturation, lightness] = hsl.map(parseFloat);
const hsvValue = clamp(
lightness + saturation * Math.min(lightness, 100 - lightness) / 100);
let hsvSaturation = 0;
if (hsvValue !== 0) {
hsvSaturation = clamp(200 * (1 - lightness / hsvValue));
}
return [hue, hsvSaturation, hsvValue, hsl.length === 4 ? +hsl[3] : 1];
};
/**
* Converts a CSS hsl(...) form into its rgb(...) color values.
*
* @param {string} hsl A single hsl(...) value to convert.
* @return {?string} The converted value.
*/
lib.colors.hslToRGB = function(hsl) {
const ary = lib.colors.crackHSL(hsl);
if (!ary) {
return null;
}
const [r, g, b, a] = lib.colors.hslArrayToRgbArray(ary);
const rgb = [r, g, b].map(Math.round).join(', ');
return a === 1 ? `rgb(${rgb})` : `rgb(${rgb}, ${a})`;
};
/**
* Converts rgb array to hsl array.
*
* The returned alpha component defaults to 1 if it isn't present in the input.
*
* The returned values are not rounded to preserve precision for computations,
* so should be rounded before they are used in CSS strings.
*
* @param {?Array<string|number>} rgb The RGB elements to convert.
* @return {!Array<number>} The HSL values.
*/
lib.colors.rgbArrayToHslArray = function(rgb) {
const r = maybeParseInt(rgb[0]) / 255;
const g = maybeParseInt(rgb[1]) / 255;
const b = maybeParseInt(rgb[2]) / 255;
const min = Math.min(r, g, b);
const max = Math.max(r, g, b);
const spread = max - min;
/* eslint-disable id-denylist */
const l = (max + min) / 2;
if (spread == 0) {
return [0, 0, 100 * l, rgb[3] !== undefined ? +rgb[3] : 1];
}
let h = (() => {
switch (max) {
case r: return ((g - b) / spread) % 6;
case g: return (b - r) / spread + 2;
case b: return (r - g) / spread + 4;
}
})();
h *= 60;
if (h < 0) {
h += 360;
}
const s = spread / (1 - Math.abs(2 * l - 1));
return [h, 100 * s, 100 * l, rgb[3] !== undefined ? +rgb[3] : 1];
/* eslint-enable id-denylist */
};
/**
* Converts a CSS rgb(...) form into their hsl(...) color values.
*
* @param {string} rgb A single rgb(...) value to convert.
* @return {?string} The converted value.
*/
lib.colors.rgbToHsl = function(rgb) {
const ary = lib.colors.crackRGB(rgb);
if (!ary) {
return null;
}
/* eslint-disable id-denylist */
// eslint-disable-next-line prefer-const
let [h, s, l, a] = lib.colors.rgbArrayToHslArray(ary);
h = Math.round(h);
s = Math.round(s);
l = Math.round(l);
return a === 1 ? `hsl(${h}, ${s}%, ${l}%)` : `hsl(${h}, ${s}%, ${l}%, ${a})`;
/* eslint-enable id-denylist */
};
/**
* Take any valid CSS color definition and turn it into an rgb value.
*
* @param {string} def The CSS color spec to normalize.
* @return {?string} The converted value.
*/
lib.colors.normalizeCSS = function(def) {
if (def.startsWith('#')) {
return lib.colors.hexToRGB(def);
}
if (re_.rgb.test(def)) {
return def;
}
if (re_.hsl.test(def)) {
return lib.colors.hslToRGB(def);
}
return lib.colors.nameToRGB(def);
};
/**
* Take any valid CSS color definition and turn it into an HSL value.
*
* @param {string} def The CSS color spec to normalize.
* @return {?string} The converted value.
*/
lib.colors.normalizeCSSToHSL = function(def) {
if (re_.hsl.test(def)) {
return def;
}
const rgb = lib.colors.normalizeCSS(def);
if (!rgb) {
return rgb;
}
return lib.colors.rgbToHsl(rgb);
};
/**
* Convert a 3 or 4 element array into an rgb(...) string.
*
* @param {?Array<string|number>} ary The RGB elements to convert.
* @return {string} The normalized CSS color spec.
*/
lib.colors.arrayToRGB = function(ary) {
if (maybeParseInt(ary[3] ?? 1) === 1) {
return `rgb(${ary[0]}, ${ary[1]}, ${ary[2]})`;
}
return `rgb(${ary[0]}, ${ary[1]}, ${ary[2]}, ${ary[3]})`;
};
/**
* Convert a 3 or 4 element array into an hsl(...) string.
*
* @param {?Array<number>} ary The HSL elements to convert.
* @return {string} The normalized CSS color spec.
*/
lib.colors.arrayToHSL = function(ary) {
const alpha = (ary.length > 3) ? ary[3] : 1;
return `hsl(${Math.round(ary[0])}, ${Math.round(ary[1])}%, ` +
`${Math.round(ary[2])}%, ${alpha})`;
};
/**
* Overwrite the alpha channel of an rgb color.
*
* @param {string} rgb The normalized CSS color spec.
* @param {string|number} alpha The alpha channel.
* @return {string} The normalized CSS color spec with updated alpha channel.
*/
lib.colors.setAlpha = function(rgb, alpha) {
const ary = lib.colors.crackRGB(rgb).slice(0, 3);
alpha = alpha.toString();
if (alpha !== '1') {
ary[3] = alpha;
}
return lib.colors.arrayToRGB(ary);
};
/**
* Split an rgb color into an array of its components.
*
* On success, a 4 element array will be returned. For rgb values, the alpha
* will be set to 1.
*
* @param {string} color The RGB CSS color spec.
* @return {?Array<string>} The RGB values split out.
*/
lib.colors.crackRGB = function(color) {
const ary = color.match(re_.rgb);
if (ary) {
ary.shift();
ary[3] ??= '1';
return Array.from(ary);
}
console.error('Couldn\'t crack: ' + color);
return null;
};
/**
* Convert an X11 color name into a CSS rgb(...) value.
*
* Names are stripped of spaces and converted to lowercase. If the name is
* unknown, null is returned.
*
* This list of color name to RGB mapping is derived from the stock X11
* rgb.txt file.
*
* @param {string} name The color name to convert.
* @return {?string} The corresponding CSS rgb(...) value.
*/
lib.colors.nameToRGB = function(name) {
if (name in x11ColorNames) {
return x11ColorNames[name];
}
name = name.toLowerCase();
if (name in x11ColorNames) {
return x11ColorNames[name];
}
name = name.replace(/\s+/g, '');
if (name in x11ColorNames) {
return x11ColorNames[name];
}
return null;
};
/**
* Calculate the relative luminance as per
* https://www.w3.org/TR/WCAG20/#relativeluminancedef
*
* @param {number} r The value (>=0 and <= 255) of the rgb component.
* @param {number} g The value (>=0 and <= 255) of the rgb component.
* @param {number} b The value (>=0 and <= 255) of the rgb component.
* @return {number} The relative luminance.
*/
lib.colors.luminance = function(r, g, b) {
const [rr, gg, bb] = [r, g, b].map((value) => {
value /= 255;
if (value <= 0.03928) {
return value / 12.92;
} else {
return Math.pow((value + 0.055) / 1.055, 2.4);
}
});
return 0.2126 * rr + 0.7152 * gg + 0.0722 * bb;
};
/**
* Calculate the contrast ratio of two relative luminance values as per
* https://www.w3.org/TR/WCAG20/#contrast-ratiodef
*
* @param {number} l1 Relative luminance value.
* @param {number} l2 Relative luminance value.
* @return {number} The contrast ratio.
*/
lib.colors.contrastRatio = function(l1, l2) {
return (Math.max(l1, l2) + 0.05) / (Math.min(l1, l2) + 0.05);
};
/**
* The stock color palette.
*
* @type {!Array<string>}
*/
lib.colors.stockPalette = [
// The "ANSI 16"...
'#000000', '#CC0000', '#4E9A06', '#C4A000',
'#3465A4', '#75507B', '#06989A', '#D3D7CF',
'#555753', '#EF2929', '#00BA13', '#FCE94F',
'#729FCF', '#F200CB', '#00B5BD', '#EEEEEC',
// The 6x6 color cubes...
'#000000', '#00005F', '#000087', '#0000AF', '#0000D7', '#0000FF',
'#005F00', '#005F5F', '#005F87', '#005FAF', '#005FD7', '#005FFF',
'#008700', '#00875F', '#008787', '#0087AF', '#0087D7', '#0087FF',
'#00AF00', '#00AF5F', '#00AF87', '#00AFAF', '#00AFD7', '#00AFFF',
'#00D700', '#00D75F', '#00D787', '#00D7AF', '#00D7D7', '#00D7FF',
'#00FF00', '#00FF5F', '#00FF87', '#00FFAF', '#00FFD7', '#00FFFF',
'#5F0000', '#5F005F', '#5F0087', '#5F00AF', '#5F00D7', '#5F00FF',
'#5F5F00', '#5F5F5F', '#5F5F87', '#5F5FAF', '#5F5FD7', '#5F5FFF',
'#5F8700', '#5F875F', '#5F8787', '#5F87AF', '#5F87D7', '#5F87FF',
'#5FAF00', '#5FAF5F', '#5FAF87', '#5FAFAF', '#5FAFD7', '#5FAFFF',
'#5FD700', '#5FD75F', '#5FD787', '#5FD7AF', '#5FD7D7', '#5FD7FF',
'#5FFF00', '#5FFF5F', '#5FFF87', '#5FFFAF', '#5FFFD7', '#5FFFFF',
'#870000', '#87005F', '#870087', '#8700AF', '#8700D7', '#8700FF',
'#875F00', '#875F5F', '#875F87', '#875FAF', '#875FD7', '#875FFF',
'#878700', '#87875F', '#878787', '#8787AF', '#8787D7', '#8787FF',
'#87AF00', '#87AF5F', '#87AF87', '#87AFAF', '#87AFD7', '#87AFFF',
'#87D700', '#87D75F', '#87D787', '#87D7AF', '#87D7D7', '#87D7FF',
'#87FF00', '#87FF5F', '#87FF87', '#87FFAF', '#87FFD7', '#87FFFF',
'#AF0000', '#AF005F', '#AF0087', '#AF00AF', '#AF00D7', '#AF00FF',
'#AF5F00', '#AF5F5F', '#AF5F87', '#AF5FAF', '#AF5FD7', '#AF5FFF',
'#AF8700', '#AF875F', '#AF8787', '#AF87AF', '#AF87D7', '#AF87FF',
'#AFAF00', '#AFAF5F', '#AFAF87', '#AFAFAF', '#AFAFD7', '#AFAFFF',
'#AFD700', '#AFD75F', '#AFD787', '#AFD7AF', '#AFD7D7', '#AFD7FF',
'#AFFF00', '#AFFF5F', '#AFFF87', '#AFFFAF', '#AFFFD7', '#AFFFFF',
'#D70000', '#D7005F', '#D70087', '#D700AF', '#D700D7', '#D700FF',
'#D75F00', '#D75F5F', '#D75F87', '#D75FAF', '#D75FD7', '#D75FFF',
'#D78700', '#D7875F', '#D78787', '#D787AF', '#D787D7', '#D787FF',
'#D7AF00', '#D7AF5F', '#D7AF87', '#D7AFAF', '#D7AFD7', '#D7AFFF',
'#D7D700', '#D7D75F', '#D7D787', '#D7D7AF', '#D7D7D7', '#D7D7FF',
'#D7FF00', '#D7FF5F', '#D7FF87', '#D7FFAF', '#D7FFD7', '#D7FFFF',
'#FF0000', '#FF005F', '#FF0087', '#FF00AF', '#FF00D7', '#FF00FF',
'#FF5F00', '#FF5F5F', '#FF5F87', '#FF5FAF', '#FF5FD7', '#FF5FFF',
'#FF8700', '#FF875F', '#FF8787', '#FF87AF', '#FF87D7', '#FF87FF',
'#FFAF00', '#FFAF5F', '#FFAF87', '#FFAFAF', '#FFAFD7', '#FFAFFF',
'#FFD700', '#FFD75F', '#FFD787', '#FFD7AF', '#FFD7D7', '#FFD7FF',
'#FFFF00', '#FFFF5F', '#FFFF87', '#FFFFAF', '#FFFFD7', '#FFFFFF',
// The greyscale ramp...
'#080808', '#121212', '#1C1C1C', '#262626', '#303030', '#3A3A3A',
'#444444', '#4E4E4E', '#585858', '#626262', '#6C6C6C', '#767676',
'#808080', '#8A8A8A', '#949494', '#9E9E9E', '#A8A8A8', '#B2B2B2',
'#BCBCBC', '#C6C6C6', '#D0D0D0', '#DADADA', '#E4E4E4', '#EEEEEE',
].map(lib.colors.hexToRGB);
/**
* Named colors according to the stock X11 rgb.txt file.
*/
const x11ColorNames = {
'aliceblue': 'rgb(240, 248, 255)',
'antiquewhite': 'rgb(250, 235, 215)',
'antiquewhite1': 'rgb(255, 239, 219)',
'antiquewhite2': 'rgb(238, 223, 204)',
'antiquewhite3': 'rgb(205, 192, 176)',
'antiquewhite4': 'rgb(139, 131, 120)',
'aquamarine': 'rgb(127, 255, 212)',
'aquamarine1': 'rgb(127, 255, 212)',
'aquamarine2': 'rgb(118, 238, 198)',
'aquamarine3': 'rgb(102, 205, 170)',
'aquamarine4': 'rgb(69, 139, 116)',
'azure': 'rgb(240, 255, 255)',
'azure1': 'rgb(240, 255, 255)',
'azure2': 'rgb(224, 238, 238)',
'azure3': 'rgb(193, 205, 205)',
'azure4': 'rgb(131, 139, 139)',
'beige': 'rgb(245, 245, 220)',
'bisque': 'rgb(255, 228, 196)',
'bisque1': 'rgb(255, 228, 196)',
'bisque2': 'rgb(238, 213, 183)',
'bisque3': 'rgb(205, 183, 158)',
'bisque4': 'rgb(139, 125, 107)',
'black': 'rgb(0, 0, 0)',
'blanchedalmond': 'rgb(255, 235, 205)',
'blue': 'rgb(0, 0, 255)',
'blue1': 'rgb(0, 0, 255)',
'blue2': 'rgb(0, 0, 238)',
'blue3': 'rgb(0, 0, 205)',
'blue4': 'rgb(0, 0, 139)',
'blueviolet': 'rgb(138, 43, 226)',
'brown': 'rgb(165, 42, 42)',
'brown1': 'rgb(255, 64, 64)',
'brown2': 'rgb(238, 59, 59)',
'brown3': 'rgb(205, 51, 51)',
'brown4': 'rgb(139, 35, 35)',
'burlywood': 'rgb(222, 184, 135)',
'burlywood1': 'rgb(255, 211, 155)',
'burlywood2': 'rgb(238, 197, 145)',
'burlywood3': 'rgb(205, 170, 125)',
'burlywood4': 'rgb(139, 115, 85)',
'cadetblue': 'rgb(95, 158, 160)',
'cadetblue1': 'rgb(152, 245, 255)',
'cadetblue2': 'rgb(142, 229, 238)',
'cadetblue3': 'rgb(122, 197, 205)',
'cadetblue4': 'rgb(83, 134, 139)',
'chartreuse': 'rgb(127, 255, 0)',
'chartreuse1': 'rgb(127, 255, 0)',
'chartreuse2': 'rgb(118, 238, 0)',
'chartreuse3': 'rgb(102, 205, 0)',
'chartreuse4': 'rgb(69, 139, 0)',
'chocolate': 'rgb(210, 105, 30)',
'chocolate1': 'rgb(255, 127, 36)',
'chocolate2': 'rgb(238, 118, 33)',
'chocolate3': 'rgb(205, 102, 29)',
'chocolate4': 'rgb(139, 69, 19)',
'coral': 'rgb(255, 127, 80)',
'coral1': 'rgb(255, 114, 86)',
'coral2': 'rgb(238, 106, 80)',
'coral3': 'rgb(205, 91, 69)',
'coral4': 'rgb(139, 62, 47)',
'cornflowerblue': 'rgb(100, 149, 237)',
'cornsilk': 'rgb(255, 248, 220)',
'cornsilk1': 'rgb(255, 248, 220)',
'cornsilk2': 'rgb(238, 232, 205)',
'cornsilk3': 'rgb(205, 200, 177)',
'cornsilk4': 'rgb(139, 136, 120)',
'cyan': 'rgb(0, 255, 255)',
'cyan1': 'rgb(0, 255, 255)',
'cyan2': 'rgb(0, 238, 238)',
'cyan3': 'rgb(0, 205, 205)',
'cyan4': 'rgb(0, 139, 139)',
'darkblue': 'rgb(0, 0, 139)',
'darkcyan': 'rgb(0, 139, 139)',
'darkgoldenrod': 'rgb(184, 134, 11)',
'darkgoldenrod1': 'rgb(255, 185, 15)',
'darkgoldenrod2': 'rgb(238, 173, 14)',
'darkgoldenrod3': 'rgb(205, 149, 12)',
'darkgoldenrod4': 'rgb(139, 101, 8)',
'darkgray': 'rgb(169, 169, 169)',
'darkgreen': 'rgb(0, 100, 0)',
'darkgrey': 'rgb(169, 169, 169)',
'darkkhaki': 'rgb(189, 183, 107)',
'darkmagenta': 'rgb(139, 0, 139)',
'darkolivegreen': 'rgb(85, 107, 47)',
'darkolivegreen1': 'rgb(202, 255, 112)',
'darkolivegreen2': 'rgb(188, 238, 104)',
'darkolivegreen3': 'rgb(162, 205, 90)',
'darkolivegreen4': 'rgb(110, 139, 61)',
'darkorange': 'rgb(255, 140, 0)',
'darkorange1': 'rgb(255, 127, 0)',
'darkorange2': 'rgb(238, 118, 0)',
'darkorange3': 'rgb(205, 102, 0)',
'darkorange4': 'rgb(139, 69, 0)',
'darkorchid': 'rgb(153, 50, 204)',
'darkorchid1': 'rgb(191, 62, 255)',
'darkorchid2': 'rgb(178, 58, 238)',
'darkorchid3': 'rgb(154, 50, 205)',
'darkorchid4': 'rgb(104, 34, 139)',
'darkred': 'rgb(139, 0, 0)',
'darksalmon': 'rgb(233, 150, 122)',
'darkseagreen': 'rgb(143, 188, 143)',
'darkseagreen1': 'rgb(193, 255, 193)',
'darkseagreen2': 'rgb(180, 238, 180)',
'darkseagreen3': 'rgb(155, 205, 155)',
'darkseagreen4': 'rgb(105, 139, 105)',
'darkslateblue': 'rgb(72, 61, 139)',
'darkslategray': 'rgb(47, 79, 79)',
'darkslategray1': 'rgb(151, 255, 255)',
'darkslategray2': 'rgb(141, 238, 238)',
'darkslategray3': 'rgb(121, 205, 205)',
'darkslategray4': 'rgb(82, 139, 139)',
'darkslategrey': 'rgb(47, 79, 79)',
'darkturquoise': 'rgb(0, 206, 209)',
'darkviolet': 'rgb(148, 0, 211)',
'debianred': 'rgb(215, 7, 81)',
'deeppink': 'rgb(255, 20, 147)',
'deeppink1': 'rgb(255, 20, 147)',
'deeppink2': 'rgb(238, 18, 137)',
'deeppink3': 'rgb(205, 16, 118)',
'deeppink4': 'rgb(139, 10, 80)',
'deepskyblue': 'rgb(0, 191, 255)',
'deepskyblue1': 'rgb(0, 191, 255)',
'deepskyblue2': 'rgb(0, 178, 238)',
'deepskyblue3': 'rgb(0, 154, 205)',
'deepskyblue4': 'rgb(0, 104, 139)',
'dimgray': 'rgb(105, 105, 105)',
'dimgrey': 'rgb(105, 105, 105)',
'dodgerblue': 'rgb(30, 144, 255)',
'dodgerblue1': 'rgb(30, 144, 255)',
'dodgerblue2': 'rgb(28, 134, 238)',
'dodgerblue3': 'rgb(24, 116, 205)',
'dodgerblue4': 'rgb(16, 78, 139)',
'firebrick': 'rgb(178, 34, 34)',
'firebrick1': 'rgb(255, 48, 48)',
'firebrick2': 'rgb(238, 44, 44)',
'firebrick3': 'rgb(205, 38, 38)',
'firebrick4': 'rgb(139, 26, 26)',
'floralwhite': 'rgb(255, 250, 240)',
'forestgreen': 'rgb(34, 139, 34)',
'gainsboro': 'rgb(220, 220, 220)',
'ghostwhite': 'rgb(248, 248, 255)',
'gold': 'rgb(255, 215, 0)',
'gold1': 'rgb(255, 215, 0)',
'gold2': 'rgb(238, 201, 0)',
'gold3': 'rgb(205, 173, 0)',
'gold4': 'rgb(139, 117, 0)',
'goldenrod': 'rgb(218, 165, 32)',
'goldenrod1': 'rgb(255, 193, 37)',
'goldenrod2': 'rgb(238, 180, 34)',
'goldenrod3': 'rgb(205, 155, 29)',
'goldenrod4': 'rgb(139, 105, 20)',
'gray': 'rgb(190, 190, 190)',
'gray0': 'rgb(0, 0, 0)',
'gray1': 'rgb(3, 3, 3)',
'gray10': 'rgb(26, 26, 26)',
'gray100': 'rgb(255, 255, 255)',
'gray11': 'rgb(28, 28, 28)',
'gray12': 'rgb(31, 31, 31)',
'gray13': 'rgb(33, 33, 33)',
'gray14': 'rgb(36, 36, 36)',
'gray15': 'rgb(38, 38, 38)',
'gray16': 'rgb(41, 41, 41)',
'gray17': 'rgb(43, 43, 43)',
'gray18': 'rgb(46, 46, 46)',
'gray19': 'rgb(48, 48, 48)',
'gray2': 'rgb(5, 5, 5)',
'gray20': 'rgb(51, 51, 51)',
'gray21': 'rgb(54, 54, 54)',
'gray22': 'rgb(56, 56, 56)',
'gray23': 'rgb(59, 59, 59)',
'gray24': 'rgb(61, 61, 61)',
'gray25': 'rgb(64, 64, 64)',
'gray26': 'rgb(66, 66, 66)',
'gray27': 'rgb(69, 69, 69)',
'gray28': 'rgb(71, 71, 71)',
'gray29': 'rgb(74, 74, 74)',
'gray3': 'rgb(8, 8, 8)',
'gray30': 'rgb(77, 77, 77)',
'gray31': 'rgb(79, 79, 79)',
'gray32': 'rgb(82, 82, 82)',
'gray33': 'rgb(84, 84, 84)',
'gray34': 'rgb(87, 87, 87)',
'gray35': 'rgb(89, 89, 89)',
'gray36': 'rgb(92, 92, 92)',
'gray37': 'rgb(94, 94, 94)',
'gray38': 'rgb(97, 97, 97)',
'gray39': 'rgb(99, 99, 99)',
'gray4': 'rgb(10, 10, 10)',
'gray40': 'rgb(102, 102, 102)',
'gray41': 'rgb(105, 105, 105)',
'gray42': 'rgb(107, 107, 107)',
'gray43': 'rgb(110, 110, 110)',
'gray44': 'rgb(112, 112, 112)',
'gray45': 'rgb(115, 115, 115)',
'gray46': 'rgb(117, 117, 117)',
'gray47': 'rgb(120, 120, 120)',
'gray48': 'rgb(122, 122, 122)',
'gray49': 'rgb(125, 125, 125)',
'gray5': 'rgb(13, 13, 13)',
'gray50': 'rgb(127, 127, 127)',
'gray51': 'rgb(130, 130, 130)',
'gray52': 'rgb(133, 133, 133)',
'gray53': 'rgb(135, 135, 135)',
'gray54': 'rgb(138, 138, 138)',
'gray55': 'rgb(140, 140, 140)',
'gray56': 'rgb(143, 143, 143)',
'gray57': 'rgb(145, 145, 145)',
'gray58': 'rgb(148, 148, 148)',
'gray59': 'rgb(150, 150, 150)',
'gray6': 'rgb(15, 15, 15)',
'gray60': 'rgb(153, 153, 153)',
'gray61': 'rgb(156, 156, 156)',
'gray62': 'rgb(158, 158, 158)',
'gray63': 'rgb(161, 161, 161)',
'gray64': 'rgb(163, 163, 163)',
'gray65': 'rgb(166, 166, 166)',
'gray66': 'rgb(168, 168, 168)',
'gray67': 'rgb(171, 171, 171)',
'gray68': 'rgb(173, 173, 173)',
'gray69': 'rgb(176, 176, 176)',
'gray7': 'rgb(18, 18, 18)',
'gray70': 'rgb(179, 179, 179)',
'gray71': 'rgb(181, 181, 181)',
'gray72': 'rgb(184, 184, 184)',
'gray73': 'rgb(186, 186, 186)',
'gray74': 'rgb(189, 189, 189)',
'gray75': 'rgb(191, 191, 191)',
'gray76': 'rgb(194, 194, 194)',
'gray77': 'rgb(196, 196, 196)',
'gray78': 'rgb(199, 199, 199)',
'gray79': 'rgb(201, 201, 201)',
'gray8': 'rgb(20, 20, 20)',
'gray80': 'rgb(204, 204, 204)',
'gray81': 'rgb(207, 207, 207)',
'gray82': 'rgb(209, 209, 209)',
'gray83': 'rgb(212, 212, 212)',
'gray84': 'rgb(214, 214, 214)',
'gray85': 'rgb(217, 217, 217)',
'gray86': 'rgb(219, 219, 219)',
'gray87': 'rgb(222, 222, 222)',
'gray88': 'rgb(224, 224, 224)',
'gray89': 'rgb(227, 227, 227)',
'gray9': 'rgb(23, 23, 23)',
'gray90': 'rgb(229, 229, 229)',
'gray91': 'rgb(232, 232, 232)',
'gray92': 'rgb(235, 235, 235)',
'gray93': 'rgb(237, 237, 237)',
'gray94': 'rgb(240, 240, 240)',
'gray95': 'rgb(242, 242, 242)',
'gray96': 'rgb(245, 245, 245)',
'gray97': 'rgb(247, 247, 247)',
'gray98': 'rgb(250, 250, 250)',
'gray99': 'rgb(252, 252, 252)',
'green': 'rgb(0, 255, 0)',
'green1': 'rgb(0, 255, 0)',
'green2': 'rgb(0, 238, 0)',
'green3': 'rgb(0, 205, 0)',
'green4': 'rgb(0, 139, 0)',
'greenyellow': 'rgb(173, 255, 47)',
'grey': 'rgb(190, 190, 190)',
'grey0': 'rgb(0, 0, 0)',
'grey1': 'rgb(3, 3, 3)',
'grey10': 'rgb(26, 26, 26)',
'grey100': 'rgb(255, 255, 255)',
'grey11': 'rgb(28, 28, 28)',
'grey12': 'rgb(31, 31, 31)',
'grey13': 'rgb(33, 33, 33)',
'grey14': 'rgb(36, 36, 36)',
'grey15': 'rgb(38, 38, 38)',
'grey16': 'rgb(41, 41, 41)',
'grey17': 'rgb(43, 43, 43)',
'grey18': 'rgb(46, 46, 46)',
'grey19': 'rgb(48, 48, 48)',
'grey2': 'rgb(5, 5, 5)',
'grey20': 'rgb(51, 51, 51)',
'grey21': 'rgb(54, 54, 54)',
'grey22': 'rgb(56, 56, 56)',
'grey23': 'rgb(59, 59, 59)',
'grey24': 'rgb(61, 61, 61)',
'grey25': 'rgb(64, 64, 64)',
'grey26': 'rgb(66, 66, 66)',
'grey27': 'rgb(69, 69, 69)',
'grey28': 'rgb(71, 71, 71)',
'grey29': 'rgb(74, 74, 74)',
'grey3': 'rgb(8, 8, 8)',
'grey30': 'rgb(77, 77, 77)',
'grey31': 'rgb(79, 79, 79)',
'grey32': 'rgb(82, 82, 82)',
'grey33': 'rgb(84, 84, 84)',
'grey34': 'rgb(87, 87, 87)',
'grey35': 'rgb(89, 89, 89)',
'grey36': 'rgb(92, 92, 92)',
'grey37': 'rgb(94, 94, 94)',
'grey38': 'rgb(97, 97, 97)',
'grey39': 'rgb(99, 99, 99)',
'grey4': 'rgb(10, 10, 10)',
'grey40': 'rgb(102, 102, 102)',
'grey41': 'rgb(105, 105, 105)',
'grey42': 'rgb(107, 107, 107)',
'grey43': 'rgb(110, 110, 110)',
'grey44': 'rgb(112, 112, 112)',
'grey45': 'rgb(115, 115, 115)',
'grey46': 'rgb(117, 117, 117)',
'grey47': 'rgb(120, 120, 120)',
'grey48': 'rgb(122, 122, 122)',
'grey49': 'rgb(125, 125, 125)',
'grey5': 'rgb(13, 13, 13)',
'grey50': 'rgb(127, 127, 127)',
'grey51': 'rgb(130, 130, 130)',
'grey52': 'rgb(133, 133, 133)',
'grey53': 'rgb(135, 135, 135)',
'grey54': 'rgb(138, 138, 138)',
'grey55': 'rgb(140, 140, 140)',
'grey56': 'rgb(143, 143, 143)',
'grey57': 'rgb(145, 145, 145)',
'grey58': 'rgb(148, 148, 148)',
'grey59': 'rgb(150, 150, 150)',
'grey6': 'rgb(15, 15, 15)',
'grey60': 'rgb(153, 153, 153)',
'grey61': 'rgb(156, 156, 156)',
'grey62': 'rgb(158, 158, 158)',
'grey63': 'rgb(161, 161, 161)',
'grey64': 'rgb(163, 163, 163)',
'grey65': 'rgb(166, 166, 166)',
'grey66': 'rgb(168, 168, 168)',
'grey67': 'rgb(171, 171, 171)',
'grey68': 'rgb(173, 173, 173)',
'grey69': 'rgb(176, 176, 176)',
'grey7': 'rgb(18, 18, 18)',
'grey70': 'rgb(179, 179, 179)',
'grey71': 'rgb(181, 181, 181)',
'grey72': 'rgb(184, 184, 184)',
'grey73': 'rgb(186, 186, 186)',
'grey74': 'rgb(189, 189, 189)',
'grey75': 'rgb(191, 191, 191)',
'grey76': 'rgb(194, 194, 194)',
'grey77': 'rgb(196, 196, 196)',
'grey78': 'rgb(199, 199, 199)',
'grey79': 'rgb(201, 201, 201)',
'grey8': 'rgb(20, 20, 20)',
'grey80': 'rgb(204, 204, 204)',
'grey81': 'rgb(207, 207, 207)',
'grey82': 'rgb(209, 209, 209)',
'grey83': 'rgb(212, 212, 212)',
'grey84': 'rgb(214, 214, 214)',
'grey85': 'rgb(217, 217, 217)',
'grey86': 'rgb(219, 219, 219)',
'grey87': 'rgb(222, 222, 222)',
'grey88': 'rgb(224, 224, 224)',
'grey89': 'rgb(227, 227, 227)',
'grey9': 'rgb(23, 23, 23)',
'grey90': 'rgb(229, 229, 229)',
'grey91': 'rgb(232, 232, 232)',
'grey92': 'rgb(235, 235, 235)',
'grey93': 'rgb(237, 237, 237)',
'grey94': 'rgb(240, 240, 240)',
'grey95': 'rgb(242, 242, 242)',
'grey96': 'rgb(245, 245, 245)',
'grey97': 'rgb(247, 247, 247)',
'grey98': 'rgb(250, 250, 250)',
'grey99': 'rgb(252, 252, 252)',
'honeydew': 'rgb(240, 255, 240)',
'honeydew1': 'rgb(240, 255, 240)',
'honeydew2': 'rgb(224, 238, 224)',
'honeydew3': 'rgb(193, 205, 193)',
'honeydew4': 'rgb(131, 139, 131)',
'hotpink': 'rgb(255, 105, 180)',
'hotpink1': 'rgb(255, 110, 180)',
'hotpink2': 'rgb(238, 106, 167)',
'hotpink3': 'rgb(205, 96, 144)',
'hotpink4': 'rgb(139, 58, 98)',
'indianred': 'rgb(205, 92, 92)',
'indianred1': 'rgb(255, 106, 106)',
'indianred2': 'rgb(238, 99, 99)',
'indianred3': 'rgb(205, 85, 85)',
'indianred4': 'rgb(139, 58, 58)',
'ivory': 'rgb(255, 255, 240)',
'ivory1': 'rgb(255, 255, 240)',
'ivory2': 'rgb(238, 238, 224)',
'ivory3': 'rgb(205, 205, 193)',
'ivory4': 'rgb(139, 139, 131)',
'khaki': 'rgb(240, 230, 140)',
'khaki1': 'rgb(255, 246, 143)',
'khaki2': 'rgb(238, 230, 133)',
'khaki3': 'rgb(205, 198, 115)',
'khaki4': 'rgb(139, 134, 78)',
'lavender': 'rgb(230, 230, 250)',
'lavenderblush': 'rgb(255, 240, 245)',
'lavenderblush1': 'rgb(255, 240, 245)',
'lavenderblush2': 'rgb(238, 224, 229)',
'lavenderblush3': 'rgb(205, 193, 197)',
'lavenderblush4': 'rgb(139, 131, 134)',
'lawngreen': 'rgb(124, 252, 0)',
'lemonchiffon': 'rgb(255, 250, 205)',
'lemonchiffon1': 'rgb(255, 250, 205)',
'lemonchiffon2': 'rgb(238, 233, 191)',
'lemonchiffon3': 'rgb(205, 201, 165)',
'lemonchiffon4': 'rgb(139, 137, 112)',
'lightblue': 'rgb(173, 216, 230)',
'lightblue1': 'rgb(191, 239, 255)',
'lightblue2': 'rgb(178, 223, 238)',
'lightblue3': 'rgb(154, 192, 205)',
'lightblue4': 'rgb(104, 131, 139)',
'lightcoral': 'rgb(240, 128, 128)',
'lightcyan': 'rgb(224, 255, 255)',
'lightcyan1': 'rgb(224, 255, 255)',
'lightcyan2': 'rgb(209, 238, 238)',
'lightcyan3': 'rgb(180, 205, 205)',
'lightcyan4': 'rgb(122, 139, 139)',
'lightgoldenrod': 'rgb(238, 221, 130)',
'lightgoldenrod1': 'rgb(255, 236, 139)',
'lightgoldenrod2': 'rgb(238, 220, 130)',
'lightgoldenrod3': 'rgb(205, 190, 112)',
'lightgoldenrod4': 'rgb(139, 129, 76)',
'lightgoldenrodyellow': 'rgb(250, 250, 210)',
'lightgray': 'rgb(211, 211, 211)',
'lightgreen': 'rgb(144, 238, 144)',
'lightgrey': 'rgb(211, 211, 211)',
'lightpink': 'rgb(255, 182, 193)',
'lightpink1': 'rgb(255, 174, 185)',
'lightpink2': 'rgb(238, 162, 173)',
'lightpink3': 'rgb(205, 140, 149)',
'lightpink4': 'rgb(139, 95, 101)',
'lightsalmon': 'rgb(255, 160, 122)',
'lightsalmon1': 'rgb(255, 160, 122)',
'lightsalmon2': 'rgb(238, 149, 114)',
'lightsalmon3': 'rgb(205, 129, 98)',
'lightsalmon4': 'rgb(139, 87, 66)',
'lightseagreen': 'rgb(32, 178, 170)',
'lightskyblue': 'rgb(135, 206, 250)',
'lightskyblue1': 'rgb(176, 226, 255)',
'lightskyblue2': 'rgb(164, 211, 238)',
'lightskyblue3': 'rgb(141, 182, 205)',
'lightskyblue4': 'rgb(96, 123, 139)',
'lightslateblue': 'rgb(132, 112, 255)',
'lightslategray': 'rgb(119, 136, 153)',
'lightslategrey': 'rgb(119, 136, 153)',
'lightsteelblue': 'rgb(176, 196, 222)',
'lightsteelblue1': 'rgb(202, 225, 255)',
'lightsteelblue2': 'rgb(188, 210, 238)',
'lightsteelblue3': 'rgb(162, 181, 205)',
'lightsteelblue4': 'rgb(110, 123, 139)',
'lightyellow': 'rgb(255, 255, 224)',
'lightyellow1': 'rgb(255, 255, 224)',
'lightyellow2': 'rgb(238, 238, 209)',
'lightyellow3': 'rgb(205, 205, 180)',
'lightyellow4': 'rgb(139, 139, 122)',
'limegreen': 'rgb(50, 205, 50)',
'linen': 'rgb(250, 240, 230)',
'magenta': 'rgb(255, 0, 255)',
'magenta1': 'rgb(255, 0, 255)',
'magenta2': 'rgb(238, 0, 238)',
'magenta3': 'rgb(205, 0, 205)',
'magenta4': 'rgb(139, 0, 139)',
'maroon': 'rgb(176, 48, 96)',
'maroon1': 'rgb(255, 52, 179)',
'maroon2': 'rgb(238, 48, 167)',
'maroon3': 'rgb(205, 41, 144)',
'maroon4': 'rgb(139, 28, 98)',
'mediumaquamarine': 'rgb(102, 205, 170)',
'mediumblue': 'rgb(0, 0, 205)',
'mediumorchid': 'rgb(186, 85, 211)',
'mediumorchid1': 'rgb(224, 102, 255)',
'mediumorchid2': 'rgb(209, 95, 238)',
'mediumorchid3': 'rgb(180, 82, 205)',
'mediumorchid4': 'rgb(122, 55, 139)',
'mediumpurple': 'rgb(147, 112, 219)',
'mediumpurple1': 'rgb(171, 130, 255)',
'mediumpurple2': 'rgb(159, 121, 238)',
'mediumpurple3': 'rgb(137, 104, 205)',
'mediumpurple4': 'rgb(93, 71, 139)',
'mediumseagreen': 'rgb(60, 179, 113)',
'mediumslateblue': 'rgb(123, 104, 238)',
'mediumspringgreen': 'rgb(0, 250, 154)',
'mediumturquoise': 'rgb(72, 209, 204)',
'mediumvioletred': 'rgb(199, 21, 133)',
'midnightblue': 'rgb(25, 25, 112)',
'mintcream': 'rgb(245, 255, 250)',
'mistyrose': 'rgb(255, 228, 225)',
'mistyrose1': 'rgb(255, 228, 225)',
'mistyrose2': 'rgb(238, 213, 210)',
'mistyrose3': 'rgb(205, 183, 181)',
'mistyrose4': 'rgb(139, 125, 123)',
'moccasin': 'rgb(255, 228, 181)',
'navajowhite': 'rgb(255, 222, 173)',
'navajowhite1': 'rgb(255, 222, 173)',
'navajowhite2': 'rgb(238, 207, 161)',
'navajowhite3': 'rgb(205, 179, 139)',
'navajowhite4': 'rgb(139, 121, 94)',
'navy': 'rgb(0, 0, 128)',
'navyblue': 'rgb(0, 0, 128)',
'oldlace': 'rgb(253, 245, 230)',
'olivedrab': 'rgb(107, 142, 35)',
'olivedrab1': 'rgb(192, 255, 62)',
'olivedrab2': 'rgb(179, 238, 58)',
'olivedrab3': 'rgb(154, 205, 50)',
'olivedrab4': 'rgb(105, 139, 34)',
'orange': 'rgb(255, 165, 0)',
'orange1': 'rgb(255, 165, 0)',
'orange2': 'rgb(238, 154, 0)',
'orange3': 'rgb(205, 133, 0)',
'orange4': 'rgb(139, 90, 0)',
'orangered': 'rgb(255, 69, 0)',
'orangered1': 'rgb(255, 69, 0)',
'orangered2': 'rgb(238, 64, 0)',
'orangered3': 'rgb(205, 55, 0)',
'orangered4': 'rgb(139, 37, 0)',
'orchid': 'rgb(218, 112, 214)',
'orchid1': 'rgb(255, 131, 250)',
'orchid2': 'rgb(238, 122, 233)',
'orchid3': 'rgb(205, 105, 201)',
'orchid4': 'rgb(139, 71, 137)',
'palegoldenrod': 'rgb(238, 232, 170)',
'palegreen': 'rgb(152, 251, 152)',
'palegreen1': 'rgb(154, 255, 154)',
'palegreen2': 'rgb(144, 238, 144)',
'palegreen3': 'rgb(124, 205, 124)',
'palegreen4': 'rgb(84, 139, 84)',
'paleturquoise': 'rgb(175, 238, 238)',
'paleturquoise1': 'rgb(187, 255, 255)',
'paleturquoise2': 'rgb(174, 238, 238)',
'paleturquoise3': 'rgb(150, 205, 205)',
'paleturquoise4': 'rgb(102, 139, 139)',
'palevioletred': 'rgb(219, 112, 147)',
'palevioletred1': 'rgb(255, 130, 171)',
'palevioletred2': 'rgb(238, 121, 159)',
'palevioletred3': 'rgb(205, 104, 137)',
'palevioletred4': 'rgb(139, 71, 93)',
'papayawhip': 'rgb(255, 239, 213)',
'peachpuff': 'rgb(255, 218, 185)',
'peachpuff1': 'rgb(255, 218, 185)',
'peachpuff2': 'rgb(238, 203, 173)',
'peachpuff3': 'rgb(205, 175, 149)',
'peachpuff4': 'rgb(139, 119, 101)',
'peru': 'rgb(205, 133, 63)',
'pink': 'rgb(255, 192, 203)',
'pink1': 'rgb(255, 181, 197)',
'pink2': 'rgb(238, 169, 184)',
'pink3': 'rgb(205, 145, 158)',
'pink4': 'rgb(139, 99, 108)',
'plum': 'rgb(221, 160, 221)',
'plum1': 'rgb(255, 187, 255)',
'plum2': 'rgb(238, 174, 238)',
'plum3': 'rgb(205, 150, 205)',
'plum4': 'rgb(139, 102, 139)',
'powderblue': 'rgb(176, 224, 230)',
'purple': 'rgb(160, 32, 240)',
'purple1': 'rgb(155, 48, 255)',
'purple2': 'rgb(145, 44, 238)',
'purple3': 'rgb(125, 38, 205)',
'purple4': 'rgb(85, 26, 139)',
'red': 'rgb(255, 0, 0)',
'red1': 'rgb(255, 0, 0)',
'red2': 'rgb(238, 0, 0)',
'red3': 'rgb(205, 0, 0)',
'red4': 'rgb(139, 0, 0)',
'rosybrown': 'rgb(188, 143, 143)',
'rosybrown1': 'rgb(255, 193, 193)',
'rosybrown2': 'rgb(238, 180, 180)',
'rosybrown3': 'rgb(205, 155, 155)',
'rosybrown4': 'rgb(139, 105, 105)',
'royalblue': 'rgb(65, 105, 225)',
'royalblue1': 'rgb(72, 118, 255)',
'royalblue2': 'rgb(67, 110, 238)',
'royalblue3': 'rgb(58, 95, 205)',
'royalblue4': 'rgb(39, 64, 139)',
'saddlebrown': 'rgb(139, 69, 19)',
'salmon': 'rgb(250, 128, 114)',
'salmon1': 'rgb(255, 140, 105)',
'salmon2': 'rgb(238, 130, 98)',
'salmon3': 'rgb(205, 112, 84)',
'salmon4': 'rgb(139, 76, 57)',
'sandybrown': 'rgb(244, 164, 96)',
'seagreen': 'rgb(46, 139, 87)',
'seagreen1': 'rgb(84, 255, 159)',
'seagreen2': 'rgb(78, 238, 148)',
'seagreen3': 'rgb(67, 205, 128)',
'seagreen4': 'rgb(46, 139, 87)',
'seashell': 'rgb(255, 245, 238)',
'seashell1': 'rgb(255, 245, 238)',
'seashell2': 'rgb(238, 229, 222)',
'seashell3': 'rgb(205, 197, 191)',
'seashell4': 'rgb(139, 134, 130)',
'sienna': 'rgb(160, 82, 45)',
'sienna1': 'rgb(255, 130, 71)',
'sienna2': 'rgb(238, 121, 66)',
'sienna3': 'rgb(205, 104, 57)',
'sienna4': 'rgb(139, 71, 38)',
'skyblue': 'rgb(135, 206, 235)',
'skyblue1': 'rgb(135, 206, 255)',
'skyblue2': 'rgb(126, 192, 238)',
'skyblue3': 'rgb(108, 166, 205)',
'skyblue4': 'rgb(74, 112, 139)',
'slateblue': 'rgb(106, 90, 205)',
'slateblue1': 'rgb(131, 111, 255)',
'slateblue2': 'rgb(122, 103, 238)',
'slateblue3': 'rgb(105, 89, 205)',
'slateblue4': 'rgb(71, 60, 139)',
'slategray': 'rgb(112, 128, 144)',
'slategray1': 'rgb(198, 226, 255)',
'slategray2': 'rgb(185, 211, 238)',
'slategray3': 'rgb(159, 182, 205)',
'slategray4': 'rgb(108, 123, 139)',
'slategrey': 'rgb(112, 128, 144)',
'snow': 'rgb(255, 250, 250)',
'snow1': 'rgb(255, 250, 250)',
'snow2': 'rgb(238, 233, 233)',
'snow3': 'rgb(205, 201, 201)',
'snow4': 'rgb(139, 137, 137)',
'springgreen': 'rgb(0, 255, 127)',
'springgreen1': 'rgb(0, 255, 127)',
'springgreen2': 'rgb(0, 238, 118)',
'springgreen3': 'rgb(0, 205, 102)',
'springgreen4': 'rgb(0, 139, 69)',
'steelblue': 'rgb(70, 130, 180)',
'steelblue1': 'rgb(99, 184, 255)',
'steelblue2': 'rgb(92, 172, 238)',
'steelblue3': 'rgb(79, 148, 205)',
'steelblue4': 'rgb(54, 100, 139)',
'tan': 'rgb(210, 180, 140)',
'tan1': 'rgb(255, 165, 79)',
'tan2': 'rgb(238, 154, 73)',
'tan3': 'rgb(205, 133, 63)',
'tan4': 'rgb(139, 90, 43)',
'thistle': 'rgb(216, 191, 216)',
'thistle1': 'rgb(255, 225, 255)',
'thistle2': 'rgb(238, 210, 238)',
'thistle3': 'rgb(205, 181, 205)',
'thistle4': 'rgb(139, 123, 139)',
'tomato': 'rgb(255, 99, 71)',
'tomato1': 'rgb(255, 99, 71)',
'tomato2': 'rgb(238, 92, 66)',
'tomato3': 'rgb(205, 79, 57)',
'tomato4': 'rgb(139, 54, 38)',
'turquoise': 'rgb(64, 224, 208)',
'turquoise1': 'rgb(0, 245, 255)',
'turquoise2': 'rgb(0, 229, 238)',
'turquoise3': 'rgb(0, 197, 205)',
'turquoise4': 'rgb(0, 134, 139)',
'violet': 'rgb(238, 130, 238)',
'violetred': 'rgb(208, 32, 144)',
'violetred1': 'rgb(255, 62, 150)',
'violetred2': 'rgb(238, 58, 140)',
'violetred3': 'rgb(205, 50, 120)',
'violetred4': 'rgb(139, 34, 82)',
'wheat': 'rgb(245, 222, 179)',
'wheat1': 'rgb(255, 231, 186)',
'wheat2': 'rgb(238, 216, 174)',
'wheat3': 'rgb(205, 186, 150)',
'wheat4': 'rgb(139, 126, 102)',
'white': 'rgb(255, 255, 255)',
'whitesmoke': 'rgb(245, 245, 245)',
'yellow': 'rgb(255, 255, 0)',
'yellow1': 'rgb(255, 255, 0)',
'yellow2': 'rgb(238, 238, 0)',
'yellow3': 'rgb(205, 205, 0)',
'yellow4': 'rgb(139, 139, 0)',
'yellowgreen': 'rgb(154, 205, 50)',
};