/**
* This module contains some color dictionaries and algorithms to
* parse a string into a hex RGB color value.s
* @summary Parsing of color strings.
* @module color
* @private
*/
define([], function() {
/*
{\color{apricot}\blacksquare}{\color{aquamarine}\blacksquare}{\color{bittersweet}\blacksquare}{\color{black}\blacksquare}{\color{blue}\blacksquare}{\color{blueGreen}\blacksquare}{\color{blueviolet}\blacksquare}{\color{brickred}\blacksquare}{\color{brown}\blacksquare}{\color{burntorange}\blacksquare}{\color{cadetblue}\blacksquare}{\color{carnationpink}\blacksquare}{\color{cerulean}\blacksquare}{\color{cornflowerblue}\blacksquare}{\color{cyan}\blacksquare}{\color{dandelion}\blacksquare}{\color{darkorchid}\blacksquare}{\color{emerald}\blacksquare}{\color{forestgreen}\blacksquare}{\color{fuchsia}\blacksquare}{\color{goldenrod}\blacksquare}{\color{gray}\blacksquare}{\color{green}\blacksquare}{\color{greenyellow}\blacksquare}{\color{junglegreen}\blacksquare}{\color{lavender}\blacksquare}{\color{limegreen}\blacksquare}{\color{magenta}\blacksquare}{\color{mahogany}\blacksquare}{\color{maroon}\blacksquare}{\color{melon}\blacksquare}{\color{midnightblue}\blacksquare}{\color{mulberry}\blacksquare}{\color{navyblue}\blacksquare}{\color{olivegreen}\blacksquare}{\color{orange}\blacksquare}{\color{orangered}\blacksquare}{\color{orchid}\blacksquare}{\color{peach}\blacksquare}{\color{periwinkle}\blacksquare}{\color{pinegreen}\blacksquare}{\color{plum}\blacksquare}{\color{processblue}\blacksquare}{\color{purple}\blacksquare}{\color{rawsienna}\blacksquare}{\color{red}\blacksquare}{\color{redorange}\blacksquare}{\color{redviolet}\blacksquare}{\color{rhodamine}\blacksquare}{\color{royalblue}\blacksquare}{\color{royalpurple}\blacksquare}{\color{rubinered}\blacksquare}{\color{salmon}\blacksquare}{\color{seagreen}\blacksquare}{\color{sepia}\blacksquare}{\color{skyblue}\blacksquare}{\color{springgreen}\blacksquare}{\color{tan}\blacksquare}{\color{tealblue}\blacksquare}{\color{thistle}\blacksquare}{\color{turquoise}\blacksquare}{\color{violet}\blacksquare}{\color{violetred}\blacksquare}{\color{white}\blacksquare}{\color{wildstrawberry}\blacksquare}{\color{yellow}\blacksquare}{\color{yellowgreen}\blacksquare}{\color{yelloworange}\blacksquare}
*/
/**
* First 10 predefined colors used for plotting by Mathematica.
*
* Also known as _indexed color scheme #97_.
* @constant
* @type {Object.<string, string>}
* @memberof module:color
*/
const MATHEMATICA_COLORS = {
'm0': '#3f3d99', // strong blue
'm1': '#993d71', // strong cerise
'm2': '#998b3d', // strong gold
'm3': '#3d9956', // malachite green
'm4': '#3d5a99', // strong cobalt blue
'm5': '#993d90', // strong orchid
'm6': '#996d3d', // strong orange
'm7': '#43993d', // strong sap green
'm8': '#3d7999', // cornflower blue
'm9': '#843d99' // mulberry
}
/* Area colors are most appropriate to color a large aread */
const AREA_COLORS = [
'#d35d60', // red
'#7293cb', // cobalt blue
'#e1974d', // orange
'#84bb5d', // pistachio
'#9066a7', // purple
'#aD6a58', // vermilion
'#f5a4ce', // pale rose
'#fff590', // pale gold
'#212121', // Black
'#818787', // dark grey
'#d4d5d2', // light grey
'#ffffff' // white
]
/* Line colors are most appropriate to color as a stroke color */
const LINE_COLORS = [
'#cc2428', // red
'#3769b1', // cobalt blue
'#da7e30', // orange
'#409852', // malachite green
'#6b4c9a', // blue violet
'#922426', // red
'#e7298a', // brilliant rose
'#ffe907', // vivid gold
'#000000',
'#525055',
'#adafaa',
'#ffffff',
]
/**
* 68 colors (+ white) known to dvips used in LaTeX.
*
* The color names are based on the names of the _Crayola Crayon_ box of
* 64 crayons.
*
* See:
* - {@link http://mirror.jmu.edu/pub/CTAN/systems/knuth/local/lib/colordvi.tex|ColorDVI.tex}
* - {@link https://en.wikibooks.org/w/index.php?title=LaTeX/Colors|Wikibooks:LaTeX/Colors}
* @constant NAMED_COLORS
* @memberof module:color
* @type {Object.<string, string>}
*/
const NAMED_COLORS = {
'apricot': '#FBB982',
'aquamarine': '#00B5BE',
'bittersweet': '#C04F17',
'black': '#221E1F', // Indeed.
'blue': '#2D2F92',
'bluegreen': '#00B3B8',
'blueviolet': '#473992',
'brickred': '#B6321C',
'brown': '#792500',
'burntorange': '#F7921D',
'cadetblue': '#74729A',
'carnationpink': '#F282B4',
'cerulean': '#00A2E3',
'cornflowerblue': '#41B0E4',
'cyan': '#00AEEF',
'dandelion': '#FDBC42',
'darkorchid': '#A4538A',
'emerald': '#00A99D',
'forestgreen': '#009B55',
'fuchsia': '#8C368C',
'goldenrod': '#FFDF42',
'gray': '#949698',
'green': '#00A64F',
'greenyellow': '#DFE674',
'junglegreen': '#00A99A',
'lavender': '#F49EC4',
'limegreen': '#8DC73E',
'magenta': '#EC008C',
'mahogany': '#A9341F',
'maroon': '#AF3235',
'melon': '#F89E7B',
'midnightblue': '#006795',
'mulberry': '#A93C93',
'navyblue': '#006EB8',
'olivegreen': '#3C8031',
'orange': '#F58137',
'orangered': '#ED135A',
'orchid': '#AF72B0',
'peach': '#F7965A',
'periwinkle': '#7977B8',
'pinegreen': '#008B72',
'plum': '#92268F',
'processblue': '#00B0F0',
'purple': '#99479B',
'rawsienna': '#974006',
'red': '#ED1B23',
'redorange': '#F26035',
'redviolet': '#A1246B',
'rhodamine': '#EF559F',
'royalblue': '#0071BC',
'royalpurple': '#613F99',
'rubinered': '#ED017D',
'salmon': '#F69289',
'seagreen': '#3FBC9D',
'sepia': '#671800',
'skyblue': '#46C5DD',
'springgreen': '#C6DC67',
'tan': '#DA9D76',
'tealblue': '#00AEB3',
'thistle': '#D883B7',
'turquoise': '#00B4CE',
'violet': '#58429B',
'violetred': '#EF58A0',
'white': '#FFFFFF',
'wildstrawberry': '#EE2967',
'yellow': '#FFF200',
'yellowgreen': '#98CC70',
'yelloworange': '#FAA21A',
};
// Other color lists: SVG colors, x11 colors
/*
aliceblue rgb(240, 248, 255)
antiquewhite rgb(250, 235, 215)
aqua rgb( 0, 255, 255)
aquamarine rgb(127, 255, 212)
azure rgb(240, 255, 255)
beige rgb(245, 245, 220)
bisque rgb(255, 228, 196)
black rgb( 0, 0, 0)
blanchedalmond rgb(255, 235, 205)
blue rgb( 0, 0, 255)
blueviolet rgb(138, 43, 226)
brown rgb(165, 42, 42)
burlywood rgb(222, 184, 135)
cadetblue rgb( 95, 158, 160)
chartreuse rgb(127, 255, 0)
chocolate rgb(210, 105, 30)
coral rgb(255, 127, 80)
cornflowerblue rgb(100, 149, 237)
cornsilk rgb(255, 248, 220)
crimson rgb(220, 20, 60)
cyan rgb( 0, 255, 255)
darkblue rgb( 0, 0, 139)
darkcyan rgb( 0, 139, 139)
darkgoldenrod rgb(184, 134, 11)
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)
darkorange rgb(255, 140, 0)
darkorchid rgb(153, 50, 204)
darkred rgb(139, 0, 0)
darksalmon rgb(233, 150, 122)
darkseagreen rgb(143, 188, 143)
darkslateblue rgb( 72, 61, 139)
darkslategray rgb( 47, 79, 79)
darkslategrey rgb( 47, 79, 79)
darkturquoise rgb( 0, 206, 209)
darkviolet rgb(148, 0, 211)
deeppink rgb(255, 20, 147)
deepskyblue rgb( 0, 191, 255)
dimgray rgb(105, 105, 105)
dimgrey rgb(105, 105, 105)
dodgerblue rgb( 30, 144, 255)
firebrick rgb(178, 34, 34)
floralwhite rgb(255, 250, 240)
forestgreen rgb( 34, 139, 34)
fuchsia rgb(255, 0, 255)
gainsboro rgb(220, 220, 220)
ghostwhite rgb(248, 248, 255)
gold rgb(255, 215, 0)
goldenrod rgb(218, 165, 32)
gray rgb(128, 128, 128)
grey rgb(128, 128, 128)
green rgb( 0, 128, 0)
greenyellow rgb(173, 255, 47)
honeydew rgb(240, 255, 240)
hotpink rgb(255, 105, 180)
indianred rgb(205, 92, 92)
indigo rgb( 75, 0, 130)
ivory rgb(255, 255, 240)
khaki rgb(240, 230, 140)
lavender rgb(230, 230, 250)
lavenderblush rgb(255, 240, 245)
lawngreen rgb(124, 252, 0)
lemonchiffon rgb(255, 250, 205)
lightblue rgb(173, 216, 230)
lightcoral rgb(240, 128, 128)
lightcyan rgb(224, 255, 255)
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)
lightsalmon rgb(255, 160, 122)
lightseagreen rgb( 32, 178, 170)
lightskyblue rgb(135, 206, 250)
lightslategray rgb(119, 136, 153)
lightslategrey rgb(119, 136, 153)
lightsteelblue rgb(176, 196, 222)
lightyellow rgb(255, 255, 224)
lime rgb( 0, 255, 0)
limegreen rgb( 50, 205, 50)
linen rgb(250, 240, 230)
magenta rgb(255, 0, 255)
maroon rgb(128, 0, 0)
mediumaquamarine rgb(102, 205, 170)
mediumblue rgb( 0, 0, 205)
mediumorchid rgb(186, 85, 211)
mediumpurple rgb(147, 112, 219)
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)
moccasin rgb(255, 228, 181)
navajowhite rgb(255, 222, 173)
navy rgb( 0, 0, 128)
oldlace rgb(253, 245, 230)
olive rgb(128, 128, 0)
olivedrab rgb(107, 142, 35)
orange rgb(255, 165, 0)
orangered rgb(255, 69, 0)
orchid rgb(218, 112, 214)
palegoldenrod rgb(238, 232, 170)
palegreen rgb(152, 251, 152)
paleturquoise rgb(175, 238, 238)
palevioletred rgb(219, 112, 147)
papayawhip rgb(255, 239, 213)
peachpuff rgb(255, 218, 185)
peru rgb(205, 133, 63)
pink rgb(255, 192, 203)
plum rgb(221, 160, 221)
powderblue rgb(176, 224, 230)
purple rgb(128, 0, 128)
red rgb(255, 0, 0)
rosybrown rgb(188, 143, 143)
royalblue rgb( 65, 105, 225)
saddlebrown rgb(139, 69, 19)
salmon rgb(250, 128, 114)
sandybrown rgb(244, 164, 96)
seagreen rgb( 46, 139, 87)
seashell rgb(255, 245, 238)
sienna rgb(160, 82, 45)
silver rgb(192, 192, 192)
skyblue rgb(135, 206, 235)
slateblue rgb(106, 90, 205)
slategray rgb(112, 128, 144)
slategrey rgb(112, 128, 144)
snow rgb(255, 250, 250)
springgreen rgb( 0, 255, 127)
steelblue rgb( 70, 130, 180)
tan rgb(210, 180, 140)
teal rgb( 0, 128, 128)
thistle rgb(216, 191, 216)
tomato rgb(255, 99, 71)
turquoise rgb( 64, 224, 208)
violet rgb(238, 130, 238)
wheat rgb(245, 222, 179)
white rgb(255, 255, 255)
whitesmoke rgb(245, 245, 245)
yellow rgb(255, 255, 0)
yellowgreen rgb(154, 205, 50)
*/
/**
* Return a CSS color (#rrggbb) from a string.
*
* Possible formats include:
* - named colors from the DVI color set: 'Yellow', 'red'... Case insensitive.
* - colors from the Mathematica set: 'm1'...'m9'
* - 3-digit hex: `'#d50'`
* - 6-digit hex: `'#dd5500'`
* - RGB functional: `'rgb(240, 20, 10)'`
*
* In addition, colors can be mixed using the following syntax:
* `<mix> = <color>![<value>][!<mix>]`
* For example:
* - `'blue!20'` = 20% blue + 80% white
* - `'blue!20!black'` = 20% + 80% black
* - `'blue!20!black!30!green'` = (20% + 80% black) * 30 % + 70% green
*
* If the input string is prefixed with a dash, the complementary color
* of the expression is returned.
*
* This creative syntax is defined by the {@link http://mirror.jmu.edu/pub/CTAN/macros/latex/contrib/xcolor/xcolor.pdf|`xcolor` LaTeX package}.
*
* @param {string} s - An expression representing a color value
* @return {string} An RGB color expressed as a hex-triplet preceded by `#`
* @memberof module:color
* @private
*/
function stringToColor(s) {
const colorSpec = s.toLowerCase().split('!');
let baseRed;
let baseGreen;
let baseBlue;
let red = 255;
let green = 255;
let blue = 255;
let mix = -1;
// If the string is prefixed with a '-', use the complementary color
const complementary = colorSpec.length > 0 && colorSpec[0].charAt(0) === '-';
if (complementary) colorSpec[0] = colorSpec[0].slice(1);
for (let i = 0; i < colorSpec.length; i++) {
baseRed = red;
baseGreen = green;
baseBlue = blue;
let colorName = colorSpec[i].match(/([a-z0-9]*)/);
if (colorName) colorName = colorName[1];
let color = NAMED_COLORS[colorName] || MATHEMATICA_COLORS[colorName];
if (!color) color = colorSpec[i];
let m = color.match(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i);
if (m && m[1] && m[2] && m[3]) {
// It's a six-digit hex number
red = Math.max(0, Math.min(255, parseInt(m[1], 16)));
green = Math.max(0, Math.min(255, parseInt(m[2], 16)));
blue = Math.max(0, Math.min(255, parseInt(m[3], 16)));
} else {
m = color.match(/^#([0-9a-f]{3})$/i)
if (m && m[1]) {
// It's a three-digit hex number
const r1 = parseInt(m[1][0], 16);
const g1 = parseInt(m[1][1], 16);
const b1 = parseInt(m[1][2], 16)
red = Math.max(0, Math.min(255, r1 * 16 + r1));
green = Math.max(0, Math.min(255, g1 * 16 + g1));
blue = Math.max(0, Math.min(255, b1 * 16 + b1));
} else {
// It's a rgb functional
m = color.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i);
if (m && m[1] && m[2] && m[3]) {
red = Math.max(0, Math.min(255, parseInt(m[1])));
green = Math.max(0, Math.min(255, parseInt(m[2])));
blue = Math.max(0, Math.min(255, parseInt(m[3])));
} else {
return null;
}
}
}
if (mix >= 0) {
red = (1.0 - mix) * red + mix * baseRed;
green = (1.0 - mix) * green + mix * baseGreen;
blue = (1.0 - mix) * blue + mix * baseBlue;
mix = -1;
}
if (i + 1 < colorSpec.length) {
mix = Math.max(0, Math.min(100, parseInt(colorSpec[++i]))) / 100.0;
}
}
if (mix >= 0) {
red = mix * red + (1.0 - mix) * baseRed;
green = mix * green + (1.0 - mix) * baseGreen;
blue = mix * blue + (1.0 - mix) * baseBlue;
}
if (complementary) {
red = 255 - red;
green = 255 - green;
blue = 255 - blue;
}
return '#' +
('00' + Math.round(red).toString(16)).slice(-2) +
('00' + Math.round(green).toString(16)).slice(-2) +
('00' + Math.round(blue).toString(16)).slice(-2);
}
// Export the public interface for this module
return {
stringToColor,
AREA_COLORS,
LINE_COLORS,
// NAMED_COLORS,
// MATHEMATICA_COLORS
}
})