UNPKG

@johnny95731/color-utils

Version:

High-performance color utilities that including conversions, harmonies, mix, and sort.

708 lines (687 loc) 24.9 kB
type DeepReadonly<T> = Readonly<{ [K in keyof T]: T[K] extends (number | string | symbol) ? Readonly<T[K]> : T[K] extends Array<infer A> ? Readonly<Array<DeepReadonly<A>>> : DeepReadonly<T[K]>; }>; type DeepWriteable<T> = { -readonly [P in keyof T]: DeepWriteable<T[P]>; }; declare const cloneDeep: <T>(obj: T) => DeepWriteable<T>; type map = { /** * Generate an array with specific length. */ <R>(len: number, callback: (i: number) => R): R[]; /** * Similar to Array.prototype.map but this can control the length of output array . */ <R, T extends readonly unknown[]>(arr: T, callback: (val: T[number], i: number) => R, len?: number): R[]; }; declare const map: map; /** * An alias of x**y. About 25%~30% faster than x**y = Math.pow(x,y) for non-integer `y`. */ declare const pow: (x: number, y: number) => number; /** * Generate a random (positive) integer between [0, max]. */ declare const randInt: (max: number) => number; /** * Rounding a number to specific place value. * @param num A number. * @param place Default: `0`. Rounding to specific place value. Positive means decimal places * and negative means whole number places. */ declare const round: (num: number, place?: number) => number; /** * Limit the number in the interval [`min`, `max`]. * @param num Number to clip. * @param min Minimum value. * @param max Maximum value. * @returns Clipped number. */ declare const clip: (num: number, min?: number, max?: number) => number; /** * Linear mapping a number from a range to another range. * @param val The value that be transform. * @param min Minimum of original range. * @param max Maximum of original range. * @param newMin Minimum of new range. * @param newMax Maximum of new range. * @param place Rounding to specific place value. Positive means decimal places * and negative means whole number places. */ declare const rangeMapping: (val: number, min: number, max: number, newMin: number, newMax: number, place?: number) => number; declare const deg2rad: (deg: number) => number; declare const rad2deg: (rad: number) => number; /** * Dot product of two arrays with lenght=3. */ declare const dot3: (arr1: readonly number[], arr2: readonly number[]) => number; /** * Return the summation of square of numbers. */ declare const squareSum4: (a: number, b: number, c?: number, d?: number) => number; declare const l2Norm3: (a: number, b: number, c?: number) => number; /** * Square of L2-distance (not take square root yet) of two array. * This function is present for comparing. * @param color1 Array with length = 3. * @param color2 Array with length = 3. * @returns The mean value of arr1 and arr2. */ declare const l2Dist3: (color1: readonly number[], color2: readonly number[]) => number; /** * Evaluates elementwise mean of two arrays, that is, returns an array that * each value is the mean of input arrays at same index. * @param arr1 Array 1. * @param arr2 Array 2. * @returns The mean value of arr1 and arr2. */ declare const elementwiseMean: (arr1: readonly number[], arr2: readonly number[]) => number[]; type Array3<T = number> = [T, T, T]; type Mat3x3<T = number> = Array3<Array3<T>>; /** * @deprecated * Matrix-vector product. * Multiply a 3x3 matrix by a 3 vector */ declare const matVecProduct3: <Mat extends number[][] | Mat3x3, Vec extends number[] | Array3>(mat: DeepReadonly<Mat>, vec: DeepReadonly<Vec>) => number[]; type ColorSpace = { /** * Name of the color space. */ name_: string; /** * Browser support. */ isSupported_: boolean; /** * Label of channels */ labels_: string[]; /** * Range of each channel of a color spaces. * * The type of values: * - `[number, number][]`: the minimum and maximum of each channel. * * The most common digits are `255`, `100`, and `360`. * - `255`: Maximum of uint8. * - `100`: The value is a percentage. * - `360`: The unit is a degree. * - others: Usually see this in CIE spaces. The value eather follows the CSS * rules (CIELAB) or represents the extreme value when transform from RGB * to the space. */ max_: readonly (readonly [number, number])[]; /** * Convert RGB to specified color space. * @param x RGB values. * @returns specified color space values. */ fromRgb_: (x: readonly number[]) => number[]; /** * Convert specified color space to RGB space. * @param x specified color space values. * @returns RGB values. */ toRgb_: (x: readonly number[]) => number[]; /** * White point. The property only exists in XYZ space. */ white_?: 'd65' | 'd50'; }; /** * Support color spaces. */ declare const COLOR_SPACES: ColorSpace[]; /** * Return an item in `COLOR_SPACES`. * @param space Item in `COLOR_SPACES` or `COLOR_SPACES[number].name_` */ declare const getColorSpace: (space?: ColorSpace | string) => ColorSpace; /** * @deprecated. * Return the range of a space. */ declare const getSpaceRange: (space: ColorSpace | string) => [number, number][]; /** * Convert the color to specific space. * @param color */ declare const toSpace: (color: readonly number[], space: ColorSpace | string, to: ColorSpace | string) => number[]; type CssColorOptions = { /** * Check the browser support or not. If browser does not support the format, * return string in RGB space. * @default false */ checkSupport_?: boolean; /** * Seperator of values. If `checkSupport_` is `true`, the seperator will * always be `' '`. * @default ' ' */ sep_?: string; /** * Convert all values to percent except degree. * @default true */ percent_?: boolean; /** * Argument for rounding values. Set `false` to disable rounding. `true` equials * default value. * @default 2 */ place_?: number | boolean; }; /** * Return CSS `<color>` value format: `space(val val val)`. * If `checkSupport === true` and the brwoser does not support, then return * RGB format. * In node enviroment, the `ColorSpace.isSupport_` based on <color-function> * value (not include theese spaces that only support by`color()`) * MDN <color>: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value * @param color Color. * @param space Color space of color. * @param options * @returns */ declare const getCssColor: (color: readonly number[], space?: ColorSpace | string, options?: CssColorOptions) => string; /** * If input a hex, convert to array and return it. * If input an array, return it. */ declare const rgbArraylize: (rgb: readonly number[] | string) => readonly number[]; /** * Calculate hue (H channel of HSL/HSB) from rgb. Also, returns minimum and * maximum of rgb. * @param rgb RGB array. */ declare const rgb2hue: (rgb: readonly number[] | string) => number; /** * Linearlize a sRGB channel. * Maps [0, 255] into [0, 1] */ declare const srgb2linearRgb: (val: number) => number; /** * Gamma correction a sRGB-linear channel * Maps [0, 255] into [0, 1] */ declare const linearRgb2srgb: (val: number) => number; /** * Conver RGB to grayscale. The value is the same as the Y channel of YIQ space. * @param rgb Array of RGB color. * @return Grayscale [0, 255] */ declare const rgb2gray: (rgb: string | readonly number[]) => number; /** * The rgb is light if the grayscale >= 127.5. */ declare const isLight: (rgb: readonly number[] | string) => boolean; /** * Evaluate relative luminance from RGB. * @returns Relative luminance, between [0, 1]. */ declare const getRelativeLuminance: (rgb: string | readonly number[]) => number; /** * Returns the contrast ratio which is defined by WCAG 2.1. */ declare const getContrastRatio: (rgb1: string | readonly number[], rgb2: string | readonly number[]) => number; /** * WCAG 2.2 requirements about contrast ratio of text. * https://www.w3.org/TR/WCAG/#contrast-minimum */ type ReadbleOptions = { /** * Text size is large scale (`true`) or normal scale (`false`). * * Large scale: text with at least 18 point or 14 point bold or font size * that would yield equivalent size for Chinese, Japanese and Korean (CJK) fonts. * @default false */ isLarge?: boolean; /** * Required to satisfy WCAG level AAA (`true`) or level AA (`false`). * * WCAG has three levels of conformance: * - Level A is the minimum level. * - Level AA includes all Level A and AA requirements. Many organizations strive to meet Level AA. * - Level AAA includes all Level A, AA, and AAA requirements. * * Text contrast ratio has no level A. * @default false */ levelAAA?: boolean; }; declare const isReadable: (rgb1: string | readonly number[], rgb2: string | readonly number[], options?: ReadbleOptions) => boolean; /** * Generate an RGB color. * @return [R, G, B] */ declare const randRgbGen: () => number[]; /** * Support mix modes. */ declare const MIXING_MODES: readonly ["mean", "brighter", "deeper", "soft light", "additive", "weighted"]; /** * Support mix modes. */ type Mixing = typeof MIXING_MODES[number]; type MixOp = ((c1: readonly number[], c2: readonly number[]) => number[]) | ((c1: readonly number[], c2: readonly number[], formula: string) => number[]) | ((c1: readonly number[], c2: readonly number[], ...args: number[]) => number[]); /** * Mixing two colors by evaluate their elementwise weighted sum. * @param color1 Color array. * @param color2 Color array. * @param weight1 Default: `0.5`. Weight of `color1`. Should be in range [0, 1]. */ declare const mix: (color1: readonly number[], color2: readonly number[], weight1?: number, weight2?: number) => number[]; /** * Mixing two colors by evaluate their elementwise average. * @param color1 Color array. * @param color2 Color array. */ declare const meanMix: (arr1: readonly number[], arr2: readonly number[]) => number[]; /** * Take the mean mix of color1 and color2 and do gamma correction to adjust * saturation and luminance. * @param rgb1 RGB color. * @param rgb2 RGB color. * @param gamma Gamma-corection coefficient. The color is deeper if gamma > 1. * The color is brighter if gamma < 1. * @returns RGB color. */ declare const gammaMix: (rgb1: readonly number[], rgb2: readonly number[], gamma?: number) => number[]; /** * * @param rgb1 RGB color. * @param rgb2 RGB color. * @returns Color in `space` */ declare const brighterMix: (rgb1: readonly number[], rgb2: readonly number[]) => number[]; declare const deeperMix: (rgb1: readonly number[], rgb2: readonly number[]) => number[]; /** * Blending two colors by soft light. * @param rgb1 Color 1. * @param rgb2 Color 2. * @param formula Default: 'w3c'. The softlight formula. * @returns RGB color. */ declare const softLightBlend: (rgb1: readonly number[], rgb2: readonly number[], formula?: "photoshop" | "pegtop" | "illusions.hu" | "w3c") => number[]; /** * Mixing two colors by evaluate their RGB sum. * @param rgb1 Color array. * @param rgb2 Color array. * @returns RGB color. */ declare const additive: (rgb1: readonly number[], rgb2: readonly number[]) => number[]; /** * Mix or blend array of RGB colors. Return a RGB color. * @param rgbs Array of RGB colors. * @param method Mix method. If not spcified, incorrect string, or number is * out of range, default to use 'mean'. * @returns RGB color. */ declare const mixColors: (rgbs: readonly number[][], method?: Mixing | number, ...args: unknown[]) => number[]; /** * Methods of adjusting contrast. */ declare const HARMONY_METHODS: readonly ["shades", "tints", "tones", "analogous", "triadic", "square", "complementary", "split complementary", "tetradic1", "tetradic2", "tetradic3"]; /** * Support harmony adjusting methods. */ type Harmony = typeof HARMONY_METHODS[number]; /** * Harmony methods which by changing the hue. */ type HueHarmony = Exclude<Harmony, 'shades' | 'tints' | 'tones'>; type HarmonyOp = (((primaryHsb: readonly number[]) => number[][]) | ((primaryHsb: readonly number[], num?: number) => number[][])); /** * Generate a harmony palette from a primary color (in HSB). * * The hues of palette are [ * primary + degs[0], primary + degs[1], ... * ] * @param primary Primary color. Should be HSB, HSL, HWB color, or color * space that first channel represents hue. * @param degs Shift degrees. * @returns HSL/HSB/HWB color (same as input). */ declare const shiftHue: (primary: readonly number[], degs: number[]) => number[][]; /** * Generate gradient that decreasing in brightness. */ declare const shades: (hsb: readonly number[], num?: number) => number[][]; /** * Generate gradient that decreasing in saturation. */ declare const tints: (hsb: readonly number[], num?: number) => number[][]; /** * Generate gradient that decreasing in both saturation and brightness. */ declare const tones: (hsb: readonly number[], num?: number) => number[][]; /** * Generate harmony colors. Returns RGB colors. * @param hsb Primary color in HSB space. Calculate other colors base on this color. * @param method Harmony method. * @param args Argument `num` for `shades`, `tints`, and `tones`. * @returns RGB colors. */ declare const harmonize: (hsb: readonly number[], method: Harmony | number, args?: number) => number[][]; /** * Methods of adjusting contrast. */ declare const CONTRAST_METHODS: readonly ["linear", "gamma", "auto enhancement", "auto brightness"]; /** * Support contrast adjusting methods. */ type ContrastMethod = typeof CONTRAST_METHODS[number]; type ContrastFunction = (rgbs: readonly number[][], ...arg: number[]) => number[][]; /** * Scale ths values of RGB. * @param rgbs RGB arrays. * @param c Scaling coefficient. * @returns RGB arrays. */ declare const scaling: (rgbs: readonly number[][], c?: number) => number[][]; /** * Gamma correction to RGB array(s). * @param rgbs RGB array(s). * @param gamma Gamma coefficient. * @returns RGB arrays. */ declare const gammaCorrection: (rgbs: readonly number[][], gamma?: number) => number[][]; /** * Enhance the contrast by scaling their luminance channel of CIELAB space. * @param rgbs * @returns RGB arrays. */ declare const autoEnhancement: ContrastFunction; /** * Adjust the luminance channel of CIELAB space by gamma correction that gamma * satisfies `((mean of luminance) / 100) ** gamma = coeff` * * Darker when coeff -> 0 and brighter when coeff -> 1 * * Modify from the paper: * BABAKHANI, Pedram; ZAREI, Parham. Automatic gamma correction based on average of brightness. Advances in Computer Science : an International Journal, [S.l.], p. 156-159, nov. 2015. ISSN 2322-5157. Available at: <https://www.acsij.org/index.php/acsij/article/view/390>. Date accessed: 22 May. 2025. * @param rgbs * @param coeff * @returns RGB arrays. */ declare const autoBrightness: ContrastFunction; declare const getAdjuster: (method: ContrastMethod) => ContrastFunction; /** * Adjust the contrast of array of RGB colors. * @param rgbs RGB colors. * @param method Adjust method. * @param space Default: 'RGB'. Color space of input and output colors. * @param args * @returns RGB colors. */ declare const adjContrast: (rgbs: number[][], method: ContrastMethod | number, ...args: number[]) => number[][]; /** * Actions for sorting palette colors. */ declare const SORTING_ACTIONS: readonly ["luminance", "random", "reversion", "CIE76", "CIE94", "CIEDE2000"]; type Sort = typeof SORTING_ACTIONS[number]; type SortOp = (rgb1: readonly number[], rgb2: readonly number[]) => number; type CIEDifferenceFn = (lab1: readonly number[], lab2: readonly number[]) => number; /** * Luminance difference of first and second colors. * @param rgb1 First RGB color. * @param rgb2 Second RGB color. */ declare const diffLuminance: SortOp; /** * Color difference of two LAB colors with CIE 1976 formula. */ declare const distE76: CIEDifferenceFn; /** * Color difference of two CIELAB colors with CIE 1994 formula. * Note that CIE 1976 formula is "not" symmetry, that is, `diffE94(hex1, hex2)` * and `diffE94(hex2, hex1)` may be different. * @param lab1 CIELAB color 1 * @param lab2 CIELAB color 2 * @returns */ declare const distE94: CIEDifferenceFn; /** * Color difference of two CIELAB colors with CIEDE2000 formula. * @param lab1 CIELAB color 1 * @param lab2 CIELAB color 2 */ declare const distE00: CIEDifferenceFn; /** * In-place shuffle an array by Fisher-Yates shuffle. * @param arr The array to be shuffled. */ declare const shuffle: <T>(arr: T[]) => T[] | DeepWriteable<T[]>; type tspGreedy = { <T>(arr: readonly T[], rgbGetter: (color: T | DeepWriteable<T>) => number[], diffOp: CIEDifferenceFn, copy: true): DeepWriteable<T[]>; <T>(arr: T[], rgbGetter: (color: T | DeepWriteable<T>) => number[], diffOp: CIEDifferenceFn, copy?: false): T[]; }; /** * Travelling salesman problem by greedy algorithm. * The first point is fixed. * @param items Array of points. * @param diffOp Distance function. */ declare const tspGreedy: tspGreedy; /** * Sort array of colors. * @param colors Colors to be sorted. Can be array of colors or object with * some key to get RGB. * @param method Sort method. * @param rgbGetter To get RGB from input color. */ declare const sortColors: <T>(colors: readonly T[], method: Sort | number, rgbGetter: (color: T | DeepWriteable<T>) => number[]) => DeepWriteable<T[]>; /** * Sort array of RGB colors. * @param rgbs Sort RGB colors. * @param method Sort method. */ declare const sortRgbs: (rgbs: readonly number[][], method: Sort | number) => number[][]; /** * Change the transformation matrix between CIEXYZ and RGB by changing the * reference white. * @param white Reference white: D65 or D50. */ declare const setReferenceWhite: (white: "D65" | "D50") => void; /** * Function that be used in the transformation from CIE XYZ to CIE LAB and to CIE LUV. * The function maps [0, 1] into [4/29, 1] and is continuous. */ type cieTrans = (xyz: number) => number; declare const cieTrans: cieTransInv; /** * Function that be used in the transformation from CIE LAB to CIE XYZ and * from CIE LUV to CIE XYZ. * The function maps [4/29, 1] into [0, 1] */ type cieTransInv = (lab: number) => number; declare const cieTransInv: cieTransInv; /** * Convert RGB to CIE Lab. * @param rgb RGB color array. * @return CIE Lab color array. */ declare const rgb2lab: (rgb: readonly number[]) => number[]; /** * Convert CIE LAB to RGB. * @param lab CIE LAB color array. * @return RGB color array. */ declare const lab2rgb: (lab: readonly number[]) => number[]; /** * Convert RGB to CIE LCh(ab). * @param rgb RGB color array. * @return CIE LCh(ab) color array. */ declare const rgb2lchab: (rgb: readonly number[]) => number[]; /** * Convert CIE LCh(ab) to RGB. * @param lch CIE LCh(ab) color array. * @return RGB color array. */ declare const lchab2rgb: (lch: readonly number[]) => number[]; /** * Convert RGB to CIE LUV. * @param rgb RGB color array. * @return CIE LUV color array. */ type rgb2luv = (xyz: readonly number[]) => number[]; declare const rgb2luv: rgb2luv; /** * Convert CIE LUV to RGB. * Note that the change of luminance may be non-intutive. * For example, luv2rgb([14, -70, -90]) is [255, 0, 0], but * luv2rgb([15, -70, -90]) is [0, 255, 255]. * @param luv CIE LUV color array. * @return RGB color array. */ type luv2rgb = (luv: readonly number[]) => number[]; declare const luv2rgb: luv2rgb; /** * Convert RGB to CIE LCh(uv). * @param rgb RGB color array. * @return CIE LCh(uv) color array. */ declare const rgb2lchuv: (rgb: readonly number[]) => number[]; /** * Convert CIE LCh(uv) to RGB. * @param lch CIE LCh(uv) color array. * @return RGB color array. */ declare const lchuv2rgb: (lch: readonly number[]) => number[]; /** * Convert RGB to CIE XYZ. * @param rgb RGB color array. * @return CIE XYZ color array. */ declare const rgb2xyz: (rgb: readonly number[]) => number[]; /** * Convert CIE XYZ to RGB. * @param xyz RGB color array. * @return RGB color array. */ declare const xyz2rgb: (xyz: readonly number[]) => number[]; /** * Convert RGB to CMYK. * @param rgb RGB color array. * @return CMYK color array. */ declare const rgb2cmyk: (rgb: readonly number[]) => number[]; /** * Convert CMYK to RGB. * @param cmyk CMYK color array. * @return RGB color array. */ declare const cmyk2rgb: (cmyk: readonly number[]) => number[]; /** * Verify the string whether is a (3 channel, no alpha channel) Hex color. * @param str String that need to be verified. * @return Validity of string. */ declare const isValidHex: (str: string) => boolean; /** * Convert RGB to Hex. * @param rgb RGB color array. * @return Hex color. */ declare const rgb2hex: (rgb: readonly number[]) => string; /** * Convert Hex color to RGB color. * @param hex Hex color string. Note that this function will not hex hex is valid or not. * @return rgb */ declare const hex2rgb: (hex: string) => number[]; /** * Calculate hue (H channel of HSL/HSB) from rgb. Also, returns minimum and * maximum of rgb. * @param rgb RGB array. * @return [hue, min = min(r,g,b), max = max(r,g,b), max - min]. */ declare const hsbHelper: (rgb: readonly number[]) => number[]; /** * Convert RGB to HSB. * @param rgb RGB color array. * @return [hue, sat, brightness]. */ declare const rgb2hsb: (rgb: readonly number[]) => number[]; /** * Convert HSB to RGB. * @param hsb HSB color array. * @return RGB color array. */ declare const hsb2rgb: (hsb: readonly number[]) => number[]; /** * Convert RGB to HSL. * @param rgb RGB color array. * @return [hue, sat, lum] */ declare const rgb2hsl: (rgb: readonly number[]) => number[]; /** * Convert HSL to RGB. * @param hsl HSL array. * @return RGB color array. */ declare const hsl2rgb: (hsl: readonly number[]) => number[]; /** * Convert RGB to HWB. * @param rgb RGB color array. * @return [hue, whiteness, blackness]. */ declare const rgb2hwb: (rgb: readonly number[]) => number[]; /** * Convert HWB to RGB. * @param hwb HWB color array. * @return RGB color array. */ declare const hwb2rgb: (hwb: readonly number[]) => number[]; /** * Convert Luminance-Chroma-Chroma model to LCh Luminance-Chroma-Hue model. * * @param lcc Color model that is [luminance, chroma1, chroma2] * @returns Corresponding Luminance-Chroma-Chroma model */ type lcc2lch = (lcc: readonly number[]) => number[]; declare const lcc2lch: lcc2lch; /** * Convert LCh Luminance-Chroma-Hue model to Luminance-Chroma-Chroma model. * @param lch Luminance-Chroma-Chroma model. * @returns [luminance, chroma1, chroma2] color model. */ type lch2lcc = (lch: readonly number[]) => number[]; declare const lch2lcc: lch2lcc; declare const namedColor: Map<string, number[]>; /** * Find the closet named-color. */ declare const rgb2named: (rgb: number[]) => string; declare const named2rgb: (name: string) => number[]; /** * Convert RGB to Oklab. * @param rgb RGB color array. * @return Oklab color array. */ declare const rgb2oklab: (rgb: readonly number[]) => number[]; /** * Convert Oklab to RGB. * @param oklab Oklab color array. * @return RGB color array. */ declare const oklab2rgb: (oklab: readonly number[]) => number[]; /** * Convert RGB to Oklch. * @param rgb RGB color array. * @return Oklch color array. */ declare const rgb2oklch: (rgb: readonly number[]) => number[]; /** * Convert Oklch to RGB. * @param oklch Oklch color array. * @return RGB color array. */ declare const oklch2rgb: (oklch: readonly number[]) => number[]; export { COLOR_SPACES, CONTRAST_METHODS, HARMONY_METHODS, MIXING_MODES, SORTING_ACTIONS, additive, adjContrast, autoBrightness, autoEnhancement, brighterMix, cieTrans, cieTransInv, clip, cloneDeep, cmyk2rgb, deeperMix, deg2rad, diffLuminance, distE00, distE76, distE94, dot3, elementwiseMean, gammaCorrection, gammaMix, getAdjuster, getColorSpace, getContrastRatio, getCssColor, getRelativeLuminance, getSpaceRange, harmonize, hex2rgb, hsb2rgb, hsbHelper, hsl2rgb, hwb2rgb, isLight, isReadable, isValidHex, l2Dist3, l2Norm3, lab2rgb, lcc2lch, lch2lcc, lchab2rgb, lchuv2rgb, linearRgb2srgb, luv2rgb, map, matVecProduct3, meanMix, mix, mixColors, named2rgb, namedColor, oklab2rgb, oklch2rgb, pow, rad2deg, randInt, randRgbGen, rangeMapping, rgb2cmyk, rgb2gray, rgb2hex, rgb2hsb, rgb2hsl, rgb2hue, rgb2hwb, rgb2lab, rgb2lchab, rgb2lchuv, rgb2luv, rgb2named, rgb2oklab, rgb2oklch, rgb2xyz, rgbArraylize, round, scaling, setReferenceWhite, shades, shiftHue, shuffle, softLightBlend, sortColors, sortRgbs, squareSum4, srgb2linearRgb, tints, toSpace, tones, tspGreedy, xyz2rgb }; export type { Array3, ColorSpace, ContrastFunction, ContrastMethod, CssColorOptions, DeepReadonly, DeepWriteable, Harmony, HarmonyOp, HueHarmony, Mat3x3, MixOp, Mixing, ReadbleOptions, Sort };