/**
 * This module contains some color dictionaries and algorithms to
 * parse a string into a hex RGB color value.s
 */ /**
 * First 10 predefined colors used for plotting by Mathematica.
 *
 * Also known as _indexed color scheme #97_.
 */ const MATHEMATICA_COLORS = { m0 : '#3F3D99' , m1 : '#993D71' , m2 : '#998B3D' , m3 : '#3D9956' , m4 : '#3D5A99' , m5 : '#993D90' , m6 : '#996D3D' , m7 : '#43993D' , m8 : '#3D7999' , m9 : '#843D99' , } ; /**
 *  Matlab colors
 */ export const MATLAB_COLORS = { blue : '#0072BD' , orange : '#D95319' , yellow : '#EDB120' , purple : '#7E2F8E' , green : '#77AC30' , cyan : '#4DBEEE' , red : '#A2142F' , } ; export const BACKGROUND_COLORS = { 'red' : '#fbbbb6' , 'orange' : '#ffe0c2' , 'yellow' : '#fff1c2' , 'lime' : '#d0e8b9' , 'green' : '#bceac4' , 'teal' : '#b9f1f1' , 'blue' : '#b6d9fb' , 'indigo' : '#d1c2f0' , 'purple' : '#e3baf8' , 'magenta' : '#f9c8e0' , 'black' : '#353535' , 'dark-grey' : '#8C8C8C' , 'grey' : '#D0D0D0' , 'light-grey' : '#F0F0F0' , 'white' : '#ffffff' , } ; export const FOREGROUND_COLORS = { 'red' : '#d7170b' , 'orange' : '#fe8a2b' , 'yellow' : '#ffc02b' , 'lime' : '#63b215' , 'green' : '#21ba3a' , 'teal' : '#17cfcf' , 'blue' : '#0d80f2' , 'indigo' : '#63c' , 'purple' : '#a219e6' , 'magenta' : '#eb4799' , 'black' : '#000' , 'dark-grey' : '#666' , 'grey' : '#A6A6A6' , 'light-grey' : '#d4d5d2' , 'white' : '#ffffff' , } ; const DVIPS_TO_CHROMATIC = { Red : 'red' , Orange : 'orange' , Yellow : 'yellow' , LimeGreen : 'lime' , Green : 'green' , TealBlue : 'teal' , Blue : 'blue' , Violet : 'indigo' , Purple : 'purple' , Magenta : 'magenta' , Black : 'black' , Gray : 'grey' , White : 'white' , } ; /**
 * 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:
 * -  https * -  https *
 * We use the Matlab colors for common colors by default.
 *
  const DVIPS_COLORS = { Apricot : '#FBB982' , Aquamarine : '#00B5BE' , Bittersweet : '#C04F17' , Black : '#221E1F' , 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' , } ; /**
 * Return a CSS color (#rrggbb) from a string.
 *
 * Possible formats include:
 * - named colors from the DVI color set: 'Yellow', 'red'... Case sensitive.
 * - 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  http .
 *
 *  param s return export function defaultColorMap ( s ) { const colorSpec = s . split ( '!' ) ; let baseRed ; let baseGreen ; let baseBlue ; let red = 255 ; let green = 255 ; let blue = 255 ; let mix = - 1 ; const complementary = colorSpec . length > 0 && colorSpec [ 0 ] . startsWith ( '-' ) ; if ( complementary ) colorSpec [ 0 ] = colorSpec [ 0 ] . slice ( 1 ) ; for ( let i = 0 ; i < colorSpec . length ; i ++ ) { baseRed = red ; baseGreen = green ; baseBlue = blue ; const colorName = colorSpec [ i ] . trim ( ) . match ( /^([A-Za-z\d]+)/ ) ?. [ 1 ] ; const lcColorName = colorName ?. toLowerCase ( ) ; const color = ! colorName ? colorSpec [ i ] . trim ( ) : FOREGROUND_COLORS [ lcColorName ! ] ?? FOREGROUND_COLORS [ DVIPS_TO_CHROMATIC [ colorName ] ] ?? MATLAB_COLORS [ colorName ] ?? DVIPS_COLORS [ colorName ] ?? MATHEMATICA_COLORS [ colorName ] ?? colorSpec [ i ] . trim ( ) ; let m = color . match ( /^#([\da-f]{2})([\da-f]{2})([\da-f]{2})$/i ) ; if ( m ?. [ 1 ] && m [ 2 ] && m [ 3 ] ) { red = Math . max ( 0 , Math . min ( 255 , Number . parseInt ( m [ 1 ] , 16 ) ) ) ; green = Math . max ( 0 , Math . min ( 255 , Number . parseInt ( m [ 2 ] , 16 ) ) ) ; blue = Math . max ( 0 , Math . min ( 255 , Number . parseInt ( m [ 3 ] , 16 ) ) ) ; } else { m = color . match ( /^#([\da-f]{3})$/i ) ; if ( m ?. [ 1 ] ) { const r1 = Number . parseInt ( m [ 1 ] [ 0 ] , 16 ) ; const g1 = Number . parseInt ( m [ 1 ] [ 1 ] , 16 ) ; const b1 = Number . 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 { m = color . match ( /^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i ) ; if ( m ?. [ 1 ] && m [ 2 ] && m [ 3 ] ) { red = Math . max ( 0 , Math . min ( 255 , Number . parseInt ( m [ 1 ] ) ) ) ; green = Math . max ( 0 , Math . min ( 255 , Number . parseInt ( m [ 2 ] ) ) ) ; blue = Math . max ( 0 , Math . min ( 255 , Number . parseInt ( m [ 3 ] ) ) ) ; } else { return undefined ; } } } if ( mix >= 0 ) { red = ( 1 - mix ) * red + mix * baseRed ; green = ( 1 - mix ) * green + mix * baseGreen ; blue = ( 1 - mix ) * blue + mix * baseBlue ; mix = - 1 ; } if ( i + 1 < colorSpec . length ) { mix = Math . max ( 0 , Math . min ( 100 , Number . parseInt ( colorSpec [ ++ i ] ) ) ) / 100 ; } } if ( mix >= 0 ) { red = mix * red + ( 1 - mix ) * baseRed ! ; green = mix * green + ( 1 - mix ) * baseGreen ! ; blue = mix * blue + ( 1 - 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 function defaultBackgroundColorMap ( s ) { s = s . trim ( ) ; return ( BACKGROUND_COLORS [ s . toLowerCase ( ) ] ?? BACKGROUND_COLORS [ DVIPS_TO_CHROMATIC [ s ] ] ?? defaultColorMap ( s ) ) ; } function parseHex ( hex ) { if ( ! hex ) return undefined ; if ( hex [ 0 ] !== '#' ) return undefined ; hex = hex . slice ( 1 ) ; let result ; if ( hex . length <= 4 ) { result = { r : parseInt ( hex [ 0 ] + hex [ 0 ] , 16 ) , g : parseInt ( hex [ 1 ] + hex [ 1 ] , 16 ) , b : parseInt ( hex [ 2 ] + hex [ 2 ] , 16 ) , } ; if ( hex . length === 4 ) { result . a = parseInt ( hex [ 3 ] + hex [ 3 ] , 16 ) / 255 ; } } else { result = { r : parseInt ( hex [ 0 ] + hex [ 1 ] , 16 ) , g : parseInt ( hex [ 2 ] + hex [ 3 ] , 16 ) , b : parseInt ( hex [ 4 ] + hex [ 5 ] , 16 ) , } ; if ( hex . length === 8 ) { result . a = parseInt ( hex [ 6 ] + hex [ 7 ] , 16 ) / 255 ; } } if ( result && result . a === undefined ) result . a = 1.0 ; return result ; } function hueToRgbChannel ( 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 ; return t1 ; } function hslToRgb ( hsl ) { let [ hue , sat , light ] = [ hsl . h , hsl . s , hsl . l ] ; hue = ( ( hue + 360 ) % 360 ) / 60.0 ; light = Math . max ( 0 , Math . min ( light , 1.0 ) ) ; sat = Math . max ( 0 , Math . min ( sat , 1.0 ) ) ; const t2 = light <= 0.5 ? light * ( sat + 1 ) : light + sat - light * sat ; const t1 = light * 2 - t2 ; return { r : Math . round ( 255 * hueToRgbChannel ( t1 , t2 , hue + 2 ) ) , g : Math . round ( 255 * hueToRgbChannel ( t1 , t2 , hue ) ) , b : Math . round ( 255 * hueToRgbChannel ( t1 , t2 , hue - 2 ) ) , } ; } function clampByte ( v ) { if ( v < 0 ) return 0 ; if ( v > 255 ) return 255 ; return Math . round ( v ) ; } function rgbToHexstring ( rgb ) { const { r , g , b } = rgb ; let hexString = ( ( 1 << 24 ) + ( clampByte ( r ) << 16 ) + ( clampByte ( g ) << 8 ) + clampByte ( b ) ) . toString ( 16 ) . slice ( 1 ) ; if ( hexString [ 0 ] === hexString [ 1 ] && hexString [ 2 ] === hexString [ 3 ] && hexString [ 4 ] === hexString [ 5 ] && hexString [ 6 ] === hexString [ 7 ] ) { hexString = hexString [ 0 ] + hexString [ 2 ] + hexString [ 4 ] ; } return '#' + hexString ; } function rgbToHsl ( rgb ) { let { r , g , b } = rgb ; r = r / 255 ; g = g / 255 ; b = b / 255 ; const min = Math . min ( r , g , b ) ; const max = Math . max ( r , g , b ) ; const delta = max - min ; let h ; let s ; if ( max === min ) { h = 0 ; } else if ( r === max ) { h = ( g - b ) / delta ; } else if ( g === max ) { h = 2 + ( b - r ) / delta ; } else if ( b === max ) { h = 4 + ( r - g ) / delta ; } h = Math . min ( h * 60 , 360 ) ; if ( h < 0 ) { h += 360 ; } const l = ( min + max ) / 2 ; if ( max === min ) { s = 0 ; } else if ( l <= 0.5 ) { s = delta / ( max + min ) ; } else { s = delta / ( 2 - max - min ) ; } return { h : h , s : s , l : l } ; } export function highlight ( color ) { let rgb = parseHex ( color ) ; if ( ! rgb ) return color ; let { h , s , l } = rgbToHsl ( rgb ) ; s += 0.1 ; l -= 0.1 ; return rgbToHexstring ( hslToRgb ( { h , s , l } ) ) ; }