Custom Web Software Development

JavaScript, HTML 5, CSS 4, & PHP 8: Innovative Enterprise level Scripting for interactive sites, SaaS, & cross-platform desktop apps
  • Home
  • Automotive Dealer Website Development
  • Free desktop apps
  • Rainbow-Maker
  • MasterColorPicker
  • Free libraries: JavaScript and PHP
  • <input type="picker">
  • RGB_Calc color-space converter
  • FormFieldGenie fieldset multiplier
  • UniDOM.js x-browser solution +
  • eMail address validation scripts
  • PHP Utility Functions
  • SoftMoon Humane Use License
  • ActiveState Komodo Edit support
  • RGB_Calc color-space conversion calculator

    and

    ColorFactory color-space interpreter & conversion calculator

    The RGB_Calc Class was born of the need for speed, yet also the need to accommodate flexible input & output formats.  In testing, I found using Arrays to pass data in & out provided the fastest execution times by far.  The predecessor of this class passed back only (custom) “color-Objects,” and (if memory serves) it “processed” all input before actually converting any colors, and when I replaced that previous class with this new RGB_Calc Class in my “MasterColorPicker” project and configured this new Class to pass back simple Arrays instead (using the same conversion functions internally with about the same extraneous overhead), maximum palette draw-time went from about 8.5 seconds to about 1.5 seconds (timed by eye/ear using the clicks on my analog wall-clock).  I was shocked (but happy☺) at the dramatic increase; I expected maybe 25%-100% faster times, but 700% faster is even better!

    The RGB_Calc Class focuses on converting the sRGB (standard Red-Green-Blue) color space model to & from various other color space models.  In the (hopefully near) future, it will evolve into handling other RGB color-spaces with wider gamuts as well.  It also has utility functions for calculating ►Luminance and Color-Contrast.  Included with this package is also the ColorFactory Class, which can: interpret a (user-input) string and return the properly interpreted values; copy a color-object (with universal but somewhat defined properties) to another color-object; and convert one color space model to another in the most direct way, skipping the RGB color space when possible.  Color-object support is supplied with somewhat universal “color-Array” classes (collectively, we call them …A_Arrays, the “A” signifying that they also carry an alpha-channel value), one for each color space model.  Finally, …A_Arrays also have extended versions (…A_Colors) that can filter (user-)input for proper values.

    Note a “color-space” is a conceptual, imaginary construct, that defines a specific range of (usually visible) colors.  A “color-model” is a mathematical way of describing a color-space, and often has defined limits to values — the sRGB color space model limits each value to integers ranging from 0—255.  In reality, colors could be more intense (have more chroma by allowing greater values), or be more densely packed throughout the range of intensity (have a greater bit-depth), but integers from 0 to 255 is the limit that computers use (at least for now… coming soon: universal UHD support!).  (By the way … chroma, or color-intensity, should not be confused with saturation, brightness, or luminance; it is a mix of them.)  So we generally define sRGB color-space-model-values like this: (64, 128, 255), but any color-model (including an RGB model) can generally also use percent values like this (25%, 50%, 100%); or some use hue-angles which correlate to a percentage of distance around the circumference of a circle (90deg, 50%, 100%).  The mathematical color space model is then applied to the monitor, and every monitor has its own gamut; that is the actual range of colors that the monitor will show, related to its contrast-ratio, where generally speaking, the higher the contrast, the darker the black is, and the more bright and pure and less washed-out the colors appear.  This all gets more confusing as we try to compare computer monitors with real-life and different wavelengths of light bouncing off different objects that reflect that wave in different ways, and how the eye perceives color and vision in general, and that is where this discussion leads…but not here.

    To use the package, you must first create a couple of namespaces for it.  Typically, these namespaces are JavaScript constants, and are used by many of SoftMoon-WebWare’s various different library packages, so they can’t all create the constant.  The SoftMoon namespace is our root, and it holds simple “universal” data that different libraries may need.  The SoftMoon.WebWare namespace holds executable code.  Also, you need to create an Array for named-color-palette files to load themselves into if you are hard-loading them with <script> tags (▼more on that in the Palettes section below).  If you are only loading palettes from a server (using “ajax” via SoftMoon.WebWare.loadPalettes()), or not at all, you don’t need the SoftMoon.loaded_palettes property.  If you are not loading palettes from a server (using “ajax”), you do not need the HTTP.js file.  Don’t confuse the fact that you can load the palettes using <script> tags from a server — but that is not using “ajax.”  The following HTML code will create the proper namespace Objects and then load the code files and the CSS palette file:

    <script type='text/javascript'> const SoftMoon=Object.defineProperties({}, { WebWare: {value: {}, enumerable: true}, loaded_palettes: {value: [], enumerable: true} }); </script> <script type='text/javascript' src='JS_toolbucket/+++JS/+++.js' defer></script> <script type='text/javascript' src='JS_toolbucket/+++JS/+++Math.js' defer></script> <script type='text/javascript' src='JS_toolbucket/SoftMoon-WebWare/HTTP.js' defer></script> <script type='text/javascript' src='JS_toolbucket/Alexei_Boronine.HSLᵤᵥ_color_space_model.js' defer></script> <script type='text/javascript' src='JS_toolbucket/Björn_Ottosson.OK_color_space_models.js' defer></script> <script type='text/javascript' src='JS_toolbucket/SoftMoon-WebWare/RGB_Calc.js' defer></script> <script type='text/javascript' src='color_palettes/desktop_palettes/CSS4.palette.js' defer onload='SoftMoon.WebWare.addPalette(SoftMoon.loaded_palettes.pop())'></script>

    Once loaded, the RGB_Calc Class is already set up to give you access to all of the individual conversion functions and the luminance and contrast-ratio functions.  These “quick” functions are tuned for maximum speed, and are members of RGB_Calc so they depend being called as such to access the configuration options: RGB_Calc.config.  They all require passing in an Array of “proper” values (see each function); that is, converting from sRGB (→to→ any color-model) requires passing in values from 0—255, converting from other color-models typically (but not by all) requires passing in factor-values from 0.0—1.0, and “improper” input values yield undefined results; they are not checked for “improper” values, as this slows the calculator.

    const RGB_Calc=SoftMoon.WebWare.RGB_Calc; const c1=RGB_Calc.from.hsl([0.3, 0.5, 0.84]); // By default, the returned value is a simple Array object console.log(c1); const c2=RGB_Calc.to.hsl([202, 235, 194]); // By default, the returned value is a simple Array object; console.log(c2); // We can also get conversion values returned in: // • a “color-Array” (a.k.a. an …A_Array), // • a “Color-Object” (a.k.a. an …A_Color), // • or YOUR custom Class object. // To temporarily change a configuration value: RGB_Calc.config.stack({RGBA_Factory: {value:SoftMoon.WebWare.RGBA_Array}}); // ↑ with .stack(), the passed value must be a properties descriptor const c3=RGB_Calc.from.hsl([0.3, 0.5, 0.84]); // now the returned value is a custom RGBA_Array object; // its .toString('css') method yields: "RGB(202, 235, 194)" console.log(c3); // Note the slight difference in conversion values; // this is because RGBA_Array objects’ .toString() method has rounded the resulting RGB values to integers. // To find the precision RGB values // **when the calculator’s configuration options do NOT round the RGB result**: console.log(...c3) // ←the precision values console.log(c3.red, c3.green, c3.blue) // ←the precision values c3.red=128; console.log(c3[0]); // ← now is 128, because .red is a getter/setter c3[1]=64; console.log(c3.green) // ← now is 64, because .green is a getter/setter console.log(c3.rgba) // ←yields a simple Array that you can manipulate & mutilate without affecting the original // (note we can also directly change config values without having first .stack()ed if we want them to be more permanent) RGB_Calc.config.RGBA_Factory=MyCustomColorClass; // this should point to YOUR constructor function const c4=RGB_Calc.from.hsl([0.3, 0.5, 0.84]); // ←c4 is an instance of MyCustomColorClass RGB_Calc.config.OKHCGA_Factory=SoftMoon.WebWare.OKHCGA_Array; const c5=RGB_Calc.to.okhcg([128,23,226]); // ↑ c5 is an instance of SoftMoon.WebWare.OKHCGA_Array, not the original default simple Array const c6=RGB_Calc.to.okhcg([128,23,226], MyCustom_OKHCG_Class); // ↑ c6 is an instance of MyCustom_OKHCG_Class, overriding the new default SoftMoon.WebWare.OKHCGA_Array // ↑ Only RGB_Calc.to. methods accept a “factory” parameter. RGB_Calc.from methods do NOT! RGB_Calc.config.cull(); // now the RGBA_Factory & the OKHCGA_Factory are whatever they were before we .stack()ed

    For all calculators, both “quick” and “auditing” types, values returned (in whatever Object) are always in the “byte” range of 0-255 for the sRGB color-space-model (they may be numeric-floats if .config.roundRGB==false, so we can’t exactly call them “bytes” or call this the sRGB color-model); and factors from 0.0–1.0 for most other color-models, excepting “-axis” and “Chroma” values (¡not “Chroma∝”! That is a factor!).

    Introducing … Color-Arrays (…A_Arrays) & Color-Objects (…A_Colors)

    Before we continue describing the RGB_Calc class, we need to take a fast look at SoftMoon-WebWare’s “color-Arrays” (a.k.a. …A_Arrays) and “Color-Objects” (a.k.a. …A_Colors).  The …A_Arrays construct quickly like normal simple Arrays, as they are extensions of the Array class, but they have prototyped getters & setters that allow you to access a color-model’s dimensional values through named properties like: clr.b, clr.blu, clr.blue, clr.alpha, etc.  For many color-spaces, they also have prototyped conversion functions to related color space models.  These …A_Arrays also have nice custom .toString() prototyped methods that allow you to easily specify the output format.  They filter out any undefined alpha (opacity) values you may pass in upon construction, so the undefined value does not become a member of the resulting array (keeping its length value trimmed), and therefore they construct just a tad bit slower than a simple Array.  For the RGBA_Array class, the constructor also takes an optional profile argument; at this time, only "sRGB" is valid for profile, but eventually other RGB color spaces will be supported (Wide-Gamut RGB (UHD), pro-Photo RGB, Adobe RGB, etc.).  For the XYZA_Array class, the constructor also takes optional illuminant & observer arguments; the list of illuminants can be found below, but for now the only observer supported is the standard "2°".  If you don’t supply these illuminant & observer arguments, they default to "D65" & "2°".  The …A_Colors construct a little slower, so they are not recommended for (graphics creation) algorithmic loops; but they offer “audited” input once constructed, if you need such.  Unlike their parent …A_Arrays, they do not simply “ignore” an undefined alpha (opacity) value if you pass one in: they fall back on the .config.defaultAlpha value.  They are extensions of their corresponding …A_Arrays, so they have all those properties and methods, also.  There are ▼more details about …A_Arrays & …A_Colors which can be found below.

    Constructing new Calculators

    Besides being a simple stand-alone static-functional class, RGB_Calc is also a Class constructor to create new “calculators” with their own set of options.  But the calculators you can construct can offer greater input flexibility, specifically, but not limited to, the ability to “audit” (interpret) a String similar to a CSS color-definition; except it can interpret any color-model that RGB_Calc is set-up to convert (you can plug-in your own and extend it), as well as ▼“named-colors” from any of the “palettes” that are loaded.  The individual “audit” conversion/luminance/contrast-ratio functions can accept a single String with the values separated by commas and/or spaces, or an Array of values in either String or numeric (Number) format.  They generally (except see special option RGB_Calc.config.inputAsFactor) accept values with limits that a CSS definition would impose: i.e. 0255 for sRGB, and 0%100% for others, or for hue-angles, any value is accepted and automatically transformed into a standard angle (since angles are circular, 45° = 405° = −335°).  Any value outside the limits will not be accepted, and may throw an Error if you choose (see RGB_Calc.config.onError). Besides the individual conversion functions, a newly constructed “audit” RGB_Calc Class object offers a “general input” interpreter that interprets just about any format you throw at it and returns the RGBA values in the Object of your choice; an explanation of the String values it can interpret follows below:

    const myCalc=new SoftMoon.WebWare.RGB_Calc; const c1=myCalc( "HSL(0.3turn, 50%, 84%)" ); // By default, the returned value is a custom RGBA_Color object; // its .toString('css') method yields: "RGB(202, 235, 194)" console.log(c1); const c2=myCalc.to.hsl( "CMYK(14.0255%, 0%, 17.44681%, 7.84314%)" ); // Here, the CMYK color is converted to RGB internally, and then to HSL. // RGB values may be rounded if myCalc.config.roundRGB=true // and this can affect the final HSL conversion values slightly. // Note that rounding the RGB values makes the // final HSL values a true representation of the sRGB color-space. // By default, the returned value is a custom HSLA_Color object; // its .toString('css') method yields: "HSL(108.29deg, 50.61728%, 84.11765%)" console.log(c2); const c3=myCalc.from.hsl("108.29deg, 50.61728%, 84.11765%"); // By default, the returned value is a custom RGBA_Color object; // its .toString('css') method yields: "RGB(202, 235, 194)" console.log(c3); // you can even leave out the units: // “audit” calculators by default use percents not factors (except for RGB uses bytes!) // except for hue-angles use the unit in myCalc.config.hueAngleUnit ("deg" by default) // UNLESS myCalc.config.inputAsFactor=true ←then (almost) ALL values are considered factors (0.0–0.1) // ↑↑↑ except .config.inputAsNumeric applies for some color-models const c4=myCalc.from.hsl("108.29, 50.61728, 84.11765"); console.log(c4); myCalc.config.inputAsFactor=true; // we can also use .config.stack(…) const c5=myCalc.from.hsl("0.3, 0.5, 84%") //←all values are factors, except 84% because it has a qualifier! const c6=myCalc.from.hsl([0.3, 0.5, "84%"]) //←we can even pass an array of numeric and/or string values // Just like the “quick-calc” examples above, we can also get conversion values // returned in a simple Array, a “color-Array” (…A_Array), or YOUR custom Class object, // using myCalc.config.stack() // or by changing myCalc.config. values directly.

    “audit”, “quick”, & “mini” calculators

    When you create your own new calculator, it can be either an “audit” or “quick” type.  This is controlled by passing true for a ▲“quick” calculator, or false (the default) for an ▲“auditing” calculator, as the 2nd parameter to the constructor.  You can even make your own custom “mini” calculators that only have the conversion function(s) you specifically need.  The “mini” calculator descriptor Object (passed into the constructor as the 3rd parameter) can have “to” and/or “from” options (property keys), and their values should be an Array listing the conversion functions as individual String values.  You can have any combination of these options, such as a “quick-mini” calculator that returns native Arrays.

    // This is the calculator that the “Rigden-colorblind_websafe-table_interpolator” // plug-in for this RGB_Calc class uses in its own internal workings. // It is a “quick” calculator that only has RGB to HCG functionality, and it returns an Array. const rgb_calc=new SoftMoon.WebWare.RGB_Calc( {HCGA_Factory: Array, defaultAlpha: undefined}, true, {to:['hcg']} );

    Valid String values for colors include:

    You may specify opacity (the opposite of transparency) in any of the color space models by adding an additional factor (0.0—1.0) or percent (0%—100% ← you must use the percent % sign).  This is called the “alpha” (Greek α) channel in technical terms.  The color-space model names may or may not end with an additional “A” (for example, RGB vs. RGBA). Per CSS4 specifications, the opacity value may also be separated with a / symbol that is itself preceded and followed by a space; for example RGBA(0, 153, 255 / 62%)  Note the “loose” interpretation of CSS specs allows commas with the / alpha separator. Hex-RGB values may have an additional 2 hex digits to specify the alpha; for example #ADDCAD80  Named colors may use the same alpha specification for color space models described above, but it must end with either a semicolon ; or a space followed by opacity;  For examples:

    Note that named colors may already have an alpha value, and if you “add on” another alpha value as shown above, it will be multiplied by the color’s existing one.  For example, if a named-color already has an alpha value of 50%, and you add on another 50% alpha, the final alpha value is 25%.  You can forbid this action using myCalc.config.forbidAddOnAlpha=true; (or by using myCalc.config.stack({forbidAddOnAlpha:{value:true}});).  You can modify this process through the multiplyAddOnAlpha(α1, α2) method of your calculator.

    Examples:

    The properties & methods of the RGB_Calc object, and its class instances

    RGB_Calc

    .config
    holds this calculator’s configuration options.  It is an instance of an extension of the ▼ConfigStack Class.  “Quick” calculators use the RGB_Calc.definer.quick.ConfigStack Class, and “auditing” calculators use the RGB_Calc.definer.audit.ConfigStack Class.
    .to
    holds functions converting sRGB to other color-models.
    .from
    holds functions converting from other color-models to sRGB.
    .luminance(color)
    This non-conversion function takes the color you input and calculates its “average perceived relative Luminance” — the luminance perceived by the average person viewing the average monitor, relative to “pure white” as displayed by the same monitor.  See the W3C’s formula for luminance except that RGB_Calc also factors in the alpha (opacity) value: if the color is partially transparent, its luminance is correspondingly partially reduced.  Luminance is used internally by the .contrastRatio() and .to.contrast() methods.
    .contrastRatio(foreground, background)
    This non-conversion function calculates the contrast ratio between two colors based on their “average perceived relative Luminance” (as defined above).  See the W3C’s formula for contrast except that RGB_Calc also factors in the alpha (opacity) value of the foreground: if the foreground color is partially transparent, its luminance is correspondingly partially reduced and some of the luminance of the background color is correspondingly added in.  This result will of course ultimately be skewed if the background color is partially transparent also, based on the (third) color behind it, unless said third color is fully opaque black.
    .install()
    Used to install different conversion functions “on the fly,” such as when there are two different color-blind filters available, etc.
    .γCorrect_linear_RGB()
    Used internally to gamma-correct RGB values from various conversion functions, and then outputs the values through .ouput_clampedRGB()
    .linearize_γCorrected_RGB()
    Used internally to prepare standardized (gamma-corrected) RGB values for conversion calculations.
    .output_sRGB()
    filters all sRGB output, according to this calculator’s .config.roundRGB flag and returns the output using the object-constructor defined by this calculator’s .config.RGBA_Factory
    .output_RGB()
    for now, the same as .output_sRGB; eventually it will handle P3-RGB, Adobe RGB, ProPhoto RGB, Wide-Gamut RGB (UHD), etc.
    .output_clampedRGB()
    filters all RGB (factors from 0.0—1.0) output by first adjusting the bit-depth, then verifies that the values are in the gamut of the current RGB profile, and returns the output through the object-constructor defined by this calculator’s .config.RGBA_Factory, or if out-of-gamut, passes the color to .config.clamp_sRGB() for customized clamping.
    .getByte()
    filters sRGB input and guarantees results from 0—255
    .getFactor()
    filters input and returns a factor from 0—1, or false if the value is out-of-range.  Input may be a string or number, and may be a percent (0-100), or already a factor if .config.inputAsFactor is true; but strings with a % qualifier at the end are always considered percents.
    .getHueFactor()
    filters input and returns a factor from 0—1; note hue-angles are circular, so no value is out-of-range.  The conversion factor is determined by .config.hueAngleUnit or the value may already be a factor if .config.inputAsFactor is true; but strings with a hue-angle-unit qualifier at the end respect that conversion factor.  If the hue-angle-unit is not recognized, this function returns false.  Note that RGB_Calc uses the hue 360° (2πrad, 400grad, 1turn, 100%, etc.) to specify that the “color” is a gray-tone (i.e. “all the colors at once”) when it makes a conversion, whereas usually 360° normalizes to 0° (the “red” hue when using “standard RGB hues”).  When calculating the hue-factor, it therefore will not normalize this specific hue value; however, 720° (etc.) normalizes to 0° as usual.  You will only notice this result when using the ColorFactory.createColor() method.  This is useful when creating gradients through hue-based color-spaces, when a color in the gradient is a gray-scale tone: you may want to grade the adjacent color straight to the gray tone without changing the hue (use hue 360°), or you may want to grade to the gray tone while also grading through hues (use any hue except 360°).

    Note that hue-values for different color space models are not all the same.  “Standard RGB” hues are based on an RGB color space, with red mapped at 0°, green (CSS: lime) at 120°, and blue at 240°, and with yellow mixing at 60°, cyan mixing at 180°, and magenta mixing at 300°.  The CIE LCh (based on CIE Lab), CIE LChᵤᵥ & HSLᵤᵥ (based on CIE Luv), and OKLCh OKHSL OKHSV OKHWB & OKHCG (based on OKLab) color models use three different hue-mappings, depending on the color space they are based on.

    .getAxis()
    filters input and returns an axis value (or a chroma value), or false if the value is out-of-range.  Input may be a string or number, and may be an axis-value or chroma-value number (value limits depends on the color-model’s input), or already a factor if .config.inputAsFactor is true and .config.inputAsNumeric is false; but strings with a % qualifier at the end are always considered percents.
    .getAlpha()
    filters input and returns a factor from 0—1, or false if the value is out-of-range.  Input may be a string or number.  Input values are considered factors from 0.01.0 unless they have % qualifiers.
    .factorize()
    filters an Array of values using this.getFactor(), this.getHueFactor(), and this.getAlpha(), and returns either:
    • a new Array (with the factorized values) when .config.preserveInputArrays=true
    • the same Array (with the modified values) when .config.preserveInputArrays=false
    • false if this.getFactor() or this.getHueFactor() or this.getAlpha() returns false
    .applyAlpha()
    This function applies an alpha value to a given color-object.  The two alpha values are multiplied according to the formula in multiplyAddOnAlpha() (see below).  It is used when you pass a “named-color” to an “auditing” calculator, and you specify an “add-on” alpha value to a color that already has an alpha value.  For example: skyPalette: clouds / 84% opacity;  Suppose this color (skyPalette: clouds) is a partly transparent blueish-graytone: RGB(50%, 55%, 70%, 80%)  Then the final alpha result is (by the default formula): 80% × 84% = 67.2%
    If you use your own custom color-objects for RGB calculator output, you may need to update or replace this function to work with them, if they don’t have an .alpha property, and they are not an Array or a child-class of Array.
    .multiplyAddOnAlpha()
    This function takes two alpha values and multiples them according to a specific formula.  You may modify the formula to suit your needs by replacing this function.
    .convertColor()
    used by ▲“auditing” .to functions to interpret the given color using the “catch-all” function (see .$() below) and convert it to sRGB before further converting to the final format.
    .$()
    This is only found on ▲“auditing” instances of the RGB_Calc class and is a mirror of the “catch-all” function that is the central to that class.  In other words: var rgb, myCalc = new SoftMoon.WebWare.RGB_Calc(); rgb=myCalc('red') //the easy preferred way rgb=mycalc.$('red') //the long way This allows methods of an “audit” RGB_Calc.to Class instance to access the “catch-all.”
    .definer
    data-Object (static property of RGB_Calc only).  This is where all the stuff is stored to create a new calculator instance.  Within this Object, you can find goodies such as the RGB_Calc.definer.quick.ConfigStack and RGB_Calc.definer.audit.ConfigStack constructors and their prototypes.
    .hueAngleUnitFactors
    data table (static property of RGB_Calc only)
    .colorblindProviders
    table of color-blind filter-functions and their meta-data. (static property of RGB_Calc only, and only present when an external color-blind filter provider file is present)

    In general, only the first 6 listed properties (methods) of RGB_Calc (above) are used, and in common use, only the first 5 listed.  There are 2 different color-blind filters currently available for the RGB_Calc Class library.  Both install themselves as RGB_Calc.to.colorblind() methods; but only one can work at a time.  They also install their meta-data in the static RGB_Calc.colorblindProviders property.  You can use RGB_Calc.install('colorblind', 'Rigden') or RGB_Calc.install('colorblind', 'Wickline'), and the filter you choose will become the one that is active, not only in RGB_Calc.to but in all future calculators constructed (using for example myCalc = new RGB_Calc();). If you use, for example myCalc.install('colorblind', 'Rigden') then the colorblind filter you install will only take effect on that individual instance of the RGB_Calc Class.

    The RGB_Calc.to and RGB_Calc.from methods are all lowercase, and the RGB_Calc.from methods must be for the “catch-all” String filtering function to recognize them.  You may add to them as you wish.  The format makes programming with them simple & easy to de-localize, allowing, for examples: RGB_Calc.from[model] or myCalc.to[model].  There are also RGB_Calc.to.contrast() and RGB_Calc.to.shade() methods, but of course not similar “from” methods.  “Contrast” returns either “black” or “white”, while “shade” either lightens or darkens a given color in contrast to the given color.

    The RGB_Calc.to and RGB_Calc.from objects have as their prototype the calculator they are attached to.  That means that the prototype of RGB_Calc.to or RGB_Calc.from is itself RGB_Calc.  Likewise, when you construct a custom calculator: const myCalc = new RGB_Calc() the objects myCalc.to and myCalc.from have as their prototypes myCalc.  Therefore, any of the methods of RGB_Calc.to or RGB_Calc.from (or similar to newly constructed calculators) can refer to this.config and assess the ConfigStack instance for the given calculator.

    The other RGB_Calc methods are all hooks to functions that are used internally.  These hooks are for plug-ins to the RGB_Calc Class to access.  You may use these hooks or hack them as you wish, but generally you need not worry about them.

    Finally, the last 3 properties listed above of RGB_Calc are static properties and are not included with class instances.  They are also available for your hacking or other use, but the ConfigStack constructors and their .prototypes need special attention. 

    Introducing … ConfigStacks

    Every “calculator,” as well as every ColorFactory instance, gets its own instance of a ConfigStack constructed object for its .config property, and every ConfigStack instance is “attached” to its calculator or ColorFactory instance.  ▲“Quick calculators” use the SoftMoon.WebWare.RGB_Calc.definer.quick.ConfigStack constructor, and its prototyped “factories” are all Arrays.  ▲“Auditing calculators” use the SoftMoon.WebWare.RGB_Calc.definer.audit.ConfigStack constructor, and its prototyped “factories” are all …A_Colors; and ColorFactory instances extend the SoftMoon.WebWare.RGB_Calc.definer.audit.ConfigStack even further, and use A_Arrays.  Also, every custom “Color Object” (a.k.a. …A_Colors) (RGBA_Colors, HSLA_Colors, & CMYKA_Colors, etc., etc.) gets its own ConfigStack, and those stacks each may have different “factory” defaults for each type of custom Color Object and their conversion methods: …A_Color conversions output an …A_Color by default.  “Color-Arrays” (a.k.a …A_Arrays, the parents to …A_Colors) have a shared config-stack in their prototype for each color-model, and those stacks each may have different “factory” defaults for each type of custom …A_Array Object and their conversion methods: and …A_Array conversions output an …A_Array by default.  The “ConfigStack” has in its prototype all the default configuration values and special methods.  You can easily change the values in any individual “calculator,” ColorFactory instance, or Color Object without affecting the others, for example RGB_Calc.config.roundRGB=true;; but if you change a config value in an …A_Array, it affects all of the same Class of …A_Array instances:

    my_HSL1=new HSLA_Array([0.2167, 1, 0.4]); my_HSL2=new HSLA_Array([0.55, 1, 0.7]); console.log(my_HSL1.toString()); // .config.stringFormat === "self" by default: HSLA_Array(… … …) my_HSL2.config.stringFormat='CSS'; // ← affects ALL instances of HSLA_Array console.log(my_HSL1.toString()); // .config.stringFormat === "CSS" now: HSL(… … …) my_HSL1.config.stack({stringFormat:{value:"self"}}); // still affects ALL instances of HSLA_Array console.log(my_HSL2.toString()); // .config.stringFormat === "self" now: HSLA_Array(… … …) my_HSL1.config.cull(); // still affects ALL instances of HSLA_Array //my_HSL2.config.cull(); // we could do this instead and it still affects ALL instances of HSLA_Array console.log(my_HSL2.toString()); // .config.stringFormat === back to "CSS" now: HSL(… … …)

    The “ConfigStack” is a 2-dimentional Object-prototype-stack with methods to add to and remove from the stack: specifically RGB_Calc.config.stack() and RGB_Calc.config.cull().  When you .stack(), the “Stack” adds another new Object to its own top-level making itself the prototype of this new Object, and re-points its calculator’s .config property to this new Object.  (Remember, when JavaScript looks for a property of an object and doesn’t find it there, it looks in that object’s prototype and then recursively the prototype’s prototype until it finds the property; this makes native JavaScript Objects an ideal container for configuration values!)  Then you can change the configuration values as you like to temporarily suit your needs, then use .config.cull() to return to the previous configuration values.  To make it even easier, .config.stack() accepts a parameter that is a JavaScript Object-Properties-Definer (see a good ►JavaScript reference): for example myCalc.config.stack({roundRGB:{value:false}, RGBA_Factory:{value:Array}});.  In this way, you can temporarily modify individual configuration value(s) for an individual calculator and then restore the original value(s), quickly and easily without having to keep track of said original value(s).  You can use .config.stack() multiple times and build the “ConfigStack” to as many levels as you need; the .config.reset() method will remove all the Objects stacked for the given calculator’s configuration and bring it back to its given default values when it was originally constructed.

    For any calculator, you don't need to .stack() the .config to temporarily change the config values if you only use defaults in your calculator instance, as the defaults are in the prototype. However, if you pass a .config descriptor object to the RGB_Calc constructor, those values are stored in the top level of your ConfigStack, and modifying the .config directly modifies them.  Using delete as shown below is faster and convenient if you only want to temporarily change one or maybe two values.  Using it with many values may be slower and clutters your codespace — that’s why .stack() and .cull() were included.

    const myCalc=new SoftMoon.WebWare.RGB_Calc({hueAngleUnit:'grad'}); myCalc.from.hsv("34, 95, 45"); // input as gradians & percents by this calc’s current default myCalc.config.inputAsFactor=true; myCalc.from.hsv("34grad, .95, .45"); // input as gradians & factors by this calc’s current default delete myCalc.config.inputAsFactor; // now the .config value goes back to the old default, faster than .stack() & .cull() myCalc.config.hueAngleUnit='rad'; // we can never go back to "grad" - if we delete this value, the prototype value is used myCalc.config.stack(); // if we did this first (after we created the calculator) all values could be preserved using delete

    There is also a flag to .config.resetConfigStackOnThrownError when using the standard .config.onError() handler. However, now-a-days it is considered best practice to use a try {…} finally {…} code-block (this config option was developed for legacy dinosaur browsers, but it still may simplify your complex coding schemes).  Note using try {…} finally {…} also covers your script’s butt if a native JavaScript Error occurs (none now known to exist) in the RGB_Calc code itself.

    const myCalc=new SoftMoon.WebWare.RGB_Calc; document.querySelector('input#userColor').attachEventListener('change', function() { myCalc.config.stack({throwErrors: {value:true}}); try {doItAgainAndAgain(this.value);} // if the user-input is in error, an Error is thrown and console outputs once here … catch(e) {console.error('we had an error with the color:',e);} // … … … and a second time here //we ALWAYS want to clean up the stack, but since any Errors are caught above, we really don’t need “finally” below finally {myCalc.config.cull();} } ); function doItAgainAndAgain(userInput) { const c1=myCalc.to.hsl('RGB: 234,127,35'); console.log(c1); //outputs from the standard HSLA_Color object: HSL(27.74deg, 82.57261%, 52.7451%) myCalc.config.stack({HSLA_Factory: {value:Array}}); try { const c2=myCalc.to.hsl(userInput); console.log(c2); //outputs from the Array object, or “null.” (“red” is): Array(3) [ 0, 0.5, 1 ] } //we ALWAYS want to clean up the stack, or if an error is thrown in the above calculator, //the stack will still have the HSLA_Factory as an Array next time we use this function or this calculator. finally {myCalc.config.cull();} } doItAgainAndAgain('red'); // no errors here - console outputs twice doItAgainAndAgain('foo-bar'); // an error but it is not thrown - console outputs twice, second is "null"

    There is no reason you can’t also change the ConfigStack.prototypes themselves.  They are numerous, but there is the root ConfigStack.prototype which is the parent Class to all the other ConfigStack Class extentions.  As is with JavaScript, this will modify the default configuration values for all calculators: the basic static RGB_Calc itself, as well any constructed, ▲“quick” or “auditing,” in the past or future.  The same goes for all …A_Arrays, …A_Colors, and all ColorFactorys you create.  However, all these Classes extend the root class, and modify some of the properties specific to their individual needs.  Mostly, these modifications are for “factories” specific to the Class, but some other mods exist.  These are subject to change, and are not listed here; see the code for each Class; but generally, the root has Array for “factories,” …A_Arrays have …A_Array “factories,” …A_Colors have …A_Color “factories,” ▲“quick calculators” use the root default “factories,” ▲“auditing calculators” have …A_Color “factories,” and ▼ColorFactorys further extends the same Audit_ConfigStack (see: SoftMoon.WebWare.RGB_Calc.definer.audit.ConfigStack) that “auditing calculators” use, but it uses …A_Array “factories”.  Any of these ConfigStack extensions may have their prototypes modified to your needs…

    Recognized properties & methods of a ConfigStack instance:

    Note these properties are not all present for every config-stack instance, depending on the class using said config-stack.

    ConfigStack

    .reflect
    For the RGB color model, depending on this Boolean flag, values passed in outside the range of 0—255 are either “reflected” or “clamped” back into the correct range.
    .roundRGB
    For the RGB color model, depending on this Boolean flag, values may be rounded to integers or left as floating-points.
    .inputShortHex
    When true, “audit” functions can recognize 3- or 4-digit hex values as valid colors.  When false, only 6- and 8-digit hex values are valid colors
    .inputAsFactor
    When true, all “audit” functions interpret input values as factors from 0—1; except for XYZ values, and except for -axis and Chroma (¡not Chroma∝!) values when .config.inputAsNumeric===true; and except string based values with unit qualifiers (i.e. a percent sign % or a Hue-Angle-Unit); and also except Number object instances with a .unit property that qualifies another unit: class Hue extends Number {} Hue.prototype.unit="deg"; const h=new Hue(78); const s=new Number(50); s.unit="%"; const red=new Number(0.37); red.unit='factor'; // did you know Number instances work exactly like primitive numbers // except they can carry meta-data: console.log(h.unit); //deg console.log(s.unit); //% console.log(h*s); //3900 console.log((h-4)*(h+4)); //6068 console.log(red.unit); //factor const foo=3; foo.bar='baz'; //not an error but… console.log(foo.bar) //undefined When false, all “audit” functions take by default (float)bytes for RGB, and percents, -axis/Chroma values, & whatever .config.hueAngleUnit is for the other color-models.  Remember, all “quick” calculator functions always take inputs as (float)bytes or factors or -axis/Chroma values or XYZ values, depending of course on the color space model; there is no other option.
    .inputAsNumeric
    When true, this overrides .config.inputAsFactor and all “audit” functions interpret input -axis and Chroma (¡not Chroma∝!) values as a corresponding numeric value, if the value is not a string with a percent % qualifier or an instance of a Number Object with a .unit property ==="%"
    .hueAngleUnit
    Default input unit when none is specified in “audit” functions and ColorWheel_Color Objects; also default output unit for ColorWheel_Array Objects and their child ColorWheel_Color Objects (HSL, HSV, HSB, HCG, & HWB, and variations of these from other color space models).  Valid units are listed as the property keys of RGB_Calc.hueAngleUnitFactors.  The .hueAngleUnit default is overridden by .inputAsfactor (see above) when input values have undeclared units.
    .useHexSymbol
    When outputting RGB Hex values, this Boolean flag determines the format.  For example: A1B2C3 vs. #A1B2C3
    .preserveInputArrays
    When you pass an Array into an “audit” calculator, it will interpret the values and may convert them into factors from 0–1.  You may want to have access to those converted values, or you may want to preserve the original values: your choice.  RGB Arrays are always preserved.
    .defaultAlpha
    When a calculator’s method, or a “color-Object” (an …A_Color) gets passed an undefined alpha value, this value is used instead.  It may be anything, including undefined also.  Note that “color Arrays’” (…A-Arrays) .toString() methods, when told to force an alpha output, will output a default Alpha value of 100% if both their alpha values and their .config.defaultAlpha are not numeric.  Note that when a calculator outputs, it will not output undefined alpha values; when using simple Arrays or …A_Arrays as an output object (see the “Factory” pointers below) its .length value will reflect that omission.
    .forbidAddOnAlpha
    For named (palette) colors we can forbid (or allow) an add-on alpha or not according to this Boolean value (true / false).  If a named color’s value is RGBA(50%, 55%, 70%, 80%) and it is in the “Sky” palette and its name is “clouds” auditing calculators can use the following spec: Sky: clouds / 84% opacity;  Using the default alpha-multiplier function (RGB_Calc.multiplyAddOnAlpha()) the final alpha value will be 80% × 84% = 67.2%
    .RGBA_Factory
    .HSLA_Factory
    .HSBA_Factory
    .HSVA_Factory
    .HCGA_Factory
    .HWBA_Factory
    .CMYKA_Factory
    .LabA_Factory
    .LChA_Factory
    .LuvA_Factory
    .LChᵤᵥA_Factory
    .HSLᵤᵥA_Factory
    .OKLabA_Factory
    .OKLChA_Factory
    .OKHSLA_Factory
    .OKHSVA_Factory
    .OKHCGA_Factory
    .OKHWBA_Factory
    .JᶻaᶻbᶻA_Factory
    .JᶻCᶻhᶻA_Factory
    .ICᵀCᴾA_Factory
    .ICHᵀᴾA_Factory
    .XYZA_Factory
    These are pointers to the constructors for the output Object holding color-conversion values.  You may want to use a simple Array (nice ’n’ fast); or any of the supplied “color Arrays” (the …A_Array classes); or any of the supplied “color Objects” (the …A_Color classes); or create your own Class constructor, or a factory-function that accepts the values and creates your custom color-object, or even a simple callback-function that accepts the values and simply acts on them (now we’re talkin’ ¡fast performance!), for any of these Factories.
    .clamp_sRGB()
    For now, this only returns null, signifying the “to RGB” conversion was “out of gamut”.  It may evolve to “clamp_RGB()” for all RGB profiles.  It is intended to evolve to allow clamping an RGB value to its maximum chroma for a given lightness and hue within the gamut.
    .RGB_bitDepth
    For now, only “sRGB” is supported, and therefore only a bit-depth-per-channel of “255” is valid.  Should any RGB color space model in the future support a specified bit-depth-per-channel (e.g. 10-bits or “1023”, 16-bits or “65535”, etc.) this will be needed… My understanding is that for now at least, when using CSS only percent values are valid for other RGB color space models, and the bit-depth for them might then be “1” (because they are float factor values, not integers).  We would like to do our calculations using the bit depth so we can “round RGB” values, even if we then convert back to percents for a CSS specification; so we will use window.screen.pixelDepth to get our bit-depth-per-channel value.  Without knowing the bit-depth of the monitor you are using, we can’t “round RGB” values in the color-conversion process as we do for sRGB
    .illuminant
    Default value for XYZ conversions.  See the ▲list of illuminants above.
    .colorProfile
    Default value for XYZ conversions.  For now, only the string "sRGB" is valid.  This will identify the RGB color space that the current monitor is using, or that you want to convert to/from.
    .onError()
    This is the standard input value error handler filter function for “auditing” calculators, ColorFactorys, and …A_Colors.  (Remember, “quick” calculators and …A_Arrays never check input values, and therefore don’t use this function.)  Replace it as necessary.
    .throwErrors
    Boolean flag used by the standard .OnError() function (above).  Change to true for debugging, etc…  If errors are not thrown, the config.errorResult is returned instead.
    .logErrors
    Boolean flag used by the standard .OnError() function (above).  Change to true for debugging, etc…
    .errorResult
    The value returned by the standard .OnError() function (above) when input values are in error and config.throwErrors is false.
    .resetConfigStackOnThrownError
    If you throw errors, you may need to clean up your .config stack, lest you create a bug or memory leak in your code’s functioning.  Set this Boolean flag to true to do so automatically when using the standard .onError() function (above).  See also the notes and code example above on using try {} finally {} code blocks instead.
    .stack()
    Add another layer to the “top” of this ConfigStack’s prototype-based stack.  Pass in an optional Object properties descriptor to quickly set new configuration values.  Then make any temporary changes you like to the configuration values; they will be valid until you .cull() or .reset() this stack (see below).
    .cull()
    Removes the “top” layer of this ConfigStack’s prototype-based stack.  Configuration values revert to previous settings before the last .stack() (see above).
    .reset()
    Removes all layers .stack()ed onto this ConfigStack’s prototype-based stack.  Configuration values revert to the “bottom” layer of settings (just above the default .prototype) — i.e. values revert to the given default values when the ConfigStack was created.
    .owner
    Private property: do not over-write this value in the ConfigStack instance.  This refers back to the calculator instance or the custom Color Object instance that this ConfigStack instance is “attached” to.
    .useAngleUnitSymbol
    Not when the output formatting style (see directly below) is csscss5html (they always prevent using symbols): depending on this Boolean flag (true / false), the .toString() method may output hues with either: ▪ a symbol: (example: 78°);  ▪ or a textual suffix: (example: 78deg) ← when applicable for the hue-angle-unit.  Typically, the hue-angle-unit used for output is defined by: ▪ .config.hueAngleUnit or ▪ .config.formatString or ▪ by passing a “formatString” directly to the .toString() method itself, and may already be a symbol or not, but this flag, when Boolean, will override the final result.  This flag is ignored when its value is not Boolean, such as null or undefined or 0 or 1.
    .stringFormat
    For all supplied “color Arrays” (the …A_Arrays) (and their “Color Object” children – the …A_Colors), this String value may define a custom output format used by the default .toString() method of the …A_Arrays (and their children).  Note you may also pass a format-string that follows these same rules directly to the .toString() method and it will take precedence over the rules found in this default format.  These format-String values have no formatting rules themselves other than values found in the beginning of the format-string override conflicting values later in the format-string.  The format-string may contain anything, but the values shown below have meaning.  Note the formatting style examples are shown for the RGB color-space, others are similar:
    output formatting style:
    # #rrggbbaa
    rrggbbaa
    !#
    hex
    color color(sRGB r g b α)
    css RGBA(r, g, b, a)
    css5
    html
    wrap
    function
    prefix RGBA: r, g, b, a
    commas r, g, b, a
    csv
    plain r g b a
    tabbed rTabgTabbTaba
    self RGBA_Color(r, g, b, a)
    All formats may not include the alpha value if it is undefined.
    ‡ hex formats are only for the RGB color-space and may or may not have the # symbol, depending on the Boolean value of .config.useHexSymbol and/or the presence of # in the format string itself.  !# closer to the beginning of the format-string negates # later in the string, and visa-verse.  In all cases, the format-string overrides .config.useHexSymbol.
    ♣ The CSS “color” function format only works for color-models that CSS supports.
    css & html formatting styles prevent (most of) the numeric output format from being a factor (see the next table), and prevent hue-angle units from being “symbols” — they convert to the “textual” equivalent (see the following table) except for % which is not a true CSS unit for hue-angles, but word on the street is that all browsers support it.  Also, for the “newer” color models, the output is de-standardized to suit the weird non-standard spec format, and commas , are removed, and the alpha separator / is used, and…(read on)…
    ☼ The “A” in “RGBA” and other “old-school” color-models will not be included if the alpha value is undefined.  Also for some “newer” color-models, the “A” will always be dropped when the output style is csshtml; the other “newer” color-models always drop their “A”.  When the output style is css5, the “A” will always be dropped for all color-models.
    ❇ Besides being an output format in-and-of themselves, these specifiers control whether commas are used or not at all, regardless of the overall format.  Many newer color space model formats do not use commas at all (by CSS standards), whereas older color models do.  Note CSS5 standards do not require any commas, and by specifying CSS5 as the output format, no commas will be used.
    Numeric values output format:
    byte for the sRGB color-space only, values are shown as integer-bytes (0–255)
    percent values are shown as percents (0%–100%)
    factor values are shown as factors (0.0–1.0) (not for csshtml formatting styles, except for hue & alpha values)
    numeric for -axis and Chroma (¡not Chroma∝!) values, this overrides “percent” & “factor” if they are found later in the formatting string.
    alpha always show an alpha value, even if one is not defined.  If it is not defined, it becomes defined in the RGBA_Color object as the .config.defaultAlpha value, or 100% if the default is not defined.
    precision: For some color-space models, you may define the number of significant digits that are shown for some of the models’ values.  (Note that precision below the default will result in some colors not converting back properly.)  JavaScript™ limits the maximum precision internally.  For example:
    precision: 10
    Hue-angle-unit output format:
    deg values are shown as degrees (0°–360°)
    °
    rad values are shown as radians (0ᴿ–2πᴿ≈6.2831853ᴿ)
    ᴿ
    grad values are shown as gradians (0ᵍ–400ᵍ)
    % values are shown as percent of a turn (0%–100%)
    turn values are shown as turns of a circle (0.0●–1.0●)
    “factor” is not actually a valid unit for hue-angles — it gets converted to “turn”
    factor

    The 19 “Factory” pointers of a ConfigStack instance (above) control the output of the functions of RGB_Calc and its instances.  You can set any the default configuration values for your new calculator by passing an Object with corresponding key/value pairs to the constructor as the 1st parameter.  You can also set default configuration values for the custom Color Objects (RGBA_Color, etc.) by passing to their constructors the configuration options object as the final (5th or 6th) value.  Note that unlike using the .config.stack() method, this configuration Object is not a JavaScript “properties descriptor.”

    /* * this example provides a calculator that returns * RGB output as a simple array of values, * instead of the default RGBA_Color object instance: */ myCalc=new SoftMoon.WebWare.RGB_Calc({RGBA_Factory:Array}); /* * this example provides a calculator that returns * an RGBA_Color object instance that outputs * hex using the # symbol, regardless of the universal default: */ myCalc=new SoftMoon.WebWare.RGB_Calc; myCalc.config.RGBA_Factory=function(r,g,b,a) { return new SoftMoon.WebWare.RGBA_Color(r,g,b,a,{useHexSymbol:true}); };

    using the named-color palettes

    The RGB_Calc Class can interpret named colors, as well as color-models, when using an “auditing” calculator.  It comes packaged with nine named-color database files included: ANSI, Brewer, CorelD, Crayola, CSS, Material Design, OpenOffice, universal, & X11; plus a Pantonic database file generator for Pantone® colors support (git the source data from GitHub).  The palette file format can come in two formatting flavors: JavaScript & JSON. The JavaScript-formatted palette-files can be hard-loaded using an HTML <script> tag in your web-page; while the JSON-formatted palette-files can be loaded from a server using HTTP.  The RGB_Calc package comes with a basic JavaScript function (SoftMoon.WebWare.loadPalettes()) to load JSON palettes from a server as well as a basic PHP file for the server’s color_palettes/ folder “index” that are designed to work together.  (Note that the name of this folder can be changed but it must end with a folder-separator / — see: SoftMoon.colorPalettes_defaultPath)  (Note also that the PHP “index” file may be replaced with one in any programming language, or even a static text file!) You can simply add/remove palette files (they must have the extension: .palette.json) from the server’s color_palettes/ folder without having to modify any HTML, JavaScript, or PHP code (if you use a static text file for the “index”, you will have to keep it manually updated); the “qualifying” palette files in the folder will be loaded.  Without a server, the palette files must be loaded via HTML <script> tags in the JavaScript flavor.

    You can also create your own named-color palettes, and an instructional file to do so is included in the color_palettes/ folder.  As a special note, your palettes can have their own .config values for the calculator that interprets them, and this should be a simple object containing the properties and their settings you desire, the same as you pass into the calculator or custom-color-objects constructors (not an object-properties-descriptor formatted for .config.stack()).  You may want to pay attention to them if you use a “non-standard” configuration.  All palettes use inputAsFactor=false and hueAngleUnit='deg' by default, regardless of whatever the current calculator’s .config values are.  Remember, simply using unit-qualifiers in your palette’s color specs may alleviate the need for any .config values.  In particular, your individual palettes may want to control the default Hue-angle-unit, input-as-factors, input-as-short-hex, default Alpha values, or whether to allow add-on Alpha values.  Configuration values for palettes are by default limited to the above list of properties, since normally the other calculator configuration settings are not Palette-specific, but your implementation may add (or remove) properties from this list.  There is no reason you couldn’t, for example, create a system that uses your own custom Color-objects as return-data from the calculator, and your individual Palettes may want to specify which “Factory” to choose.  You can control which .config properties are allowed in a Palette through the array at SoftMoon.WebWare.Palette.configProps by adding/removing string-names of the specific properties.

    Palette files may have extraneous meta-data in them.  The supplied files come with meta-data that the ►MasterColorPicker project uses.  You may also put any meta-data in the palettes you create, but when they are loaded and processed, the final SoftMoon.WebWare.Palette object that gets saved in SoftMoon.palettes will not, by default, include said meta-data.  If you want your meta-data included in the processed palette, you need to tell the SoftMoon.WebWare.Palette constructor to include it.  To do so, add string values for the meta-data property names to the SoftMoon.WebWare.Palette.properties array.  If your custom palette uses the meta-data property “foobar,” then use the code: SoftMoon.WebWare.Palette.properties.push('foobar');

    Palette files are supplied in the JavaScript flavor.  Your implementation may load them from a local file (via the file:// protocol) or a local/remote server (via the http:// or https:// protocols) using HTML <script> elements.  To load them from a server via “ajax” using SoftMoon.WebWare.loadPalettes() requires that they are converted to the JSON flavor.  This is simple and easy; there is an instructional file to do so manually, as well as a PHP file to do so automatically.  Find both in the color_palettes/ folder.

    To use a JavaScript flavored palette, you must first create a property of the SoftMoon namespace: SoftMoon.loaded_palettes=new Array; then load the file using a <script> tag.  The palette will place itself in the SoftMoon.loaded_palettes array.  You must then use a JavaScript Event-handler to add the palette to the “processed” palettes (found in SoftMoon.palettes).  You use the function SoftMoon.WebWare.addPalette() to process the palette.  You can use an “onload” property of the <script> tag as shown in the ▲example at the top of this page, or wait until all palettes are loaded and use an “onload” event on the window and then add all palettes found in the SoftMoon.loaded_palettes array.

    To use a JSON flavored palette, the SoftMoon.WebWare.loadPalettes() function contacts the server, requesting the index for the palette files.  The index returned contains the names of all palette files in the color_palettes/ folder & its sub-folders.  Once the loadPalettes() function gets the index, it “qualifies” each file for loading.  Any file in a “trash” folder or its sub-folders is ignored.  Any file in a “users” folder or its sub-folders is ignored, unless it is in an “autoload” folder or its sub-folders.  The names of these folders (“trash”, “users”, “autoload”) can be modified, but it is a bit trickier and requires knowing how to use JavaScript Regular Expressions; see the loadPalettes() function code in the RGB_Calc.js file for more details.  Once a palette file is deemed “qualified” for loading, it is loaded, processed, and added to SoftMoon.palettes

    The SoftMoon.WebWare.loadPalettes() function requires no parameters to work, but it can take many, to customize the palette loading process.  These are no light-duty customizations.  The details of these customizing options are beyond this text, require that you fully understand JavaScript and asynchronous communications, and are fairly self-explanatory if you read the loadPalettes() function code in the RGB_Calc.js file.  The loadPalettes() function relies on the external file HTTP.js to handle communications, and some of the parameters you pass are for customizing that Class’ functionality so see its file also.

    Palettes may also be loaded from a browser’s internal database.  The SoftMoon.WebWare.loadDBPalettes() function handles this.  However, no functionality is supplied to store a palette in the database; this may change in the future.  (The ►MasterColorPicker project can create them, if you are interested; but remember: browser databases only work with the website domain (when using a server) or the individual HTML file (when working from your home filesystem) that created the database.) Palettes in the database should be JSON formatted.  You can also customize the functionality of the loading process as you can when loading from a server — see the code.

    Color-Arrays (…A_Arrays) & Color-Objects (…A_Color)s

    The RGB_Calc package comes with constructors for custom color Arrays (known collectively as the …A_Arrays), and their child class custom color Objects (known collectively as the …A_Colorss); the former are the default output Objects for ColorFactorys, and the latter are used as the default output from conversion functions of “auditing” calculators.  They are meant to be relatively “universal” in usage with other software packages.  They are designed internally so if you change one value in the color-object, it reflects throughout the entire object.  For example, in an RGBA_Array object, if you change the property of .red, the other properties (array-index)[0] .r & .hex all change in accordance.  In an RGBA_Array object, there is also .rgba[0] that changes accordingly when you read it; other …A_Array also have the corresponding array. However, these getter/setter properties return a “free” simple Array that you can modify & mutilate without modifying the …A_Array or A_Color, and once you read the whole simple Array, the Array’s values are unattached from the …A_Array.  You can not “set” these simple Arrays on an …A_Array’s property, but you can on an …A_Color’s property thus changing the whole …A_ColorRGBA_Color objects also have a unique .rgb property, that works just like the .rgba property but without the alpha-value; this facilitates Array.map() etc., for functions such as “lighten” or “darken”, whereas other color models do not have channels/coordinates that are orthogonal to each-other, so no need.  The …A_Arrays are not much more than a simple Array with extra properties, but the …A_Colors can “audit” the input once constructed (they do not audit input upon creation).

    All …A_Arrays (and correspondingly all …A_Colors) are extensions of the root ColorA_Array (¡which is meant to be only a parent class, not a stand-alone constructor!) so you can check them using instanceof, and it provides generic .copy($factory, $config) and .convertTo($dSpace, $factory, $config) methods.  These methods mirror the .copyColor() and .convertColor() methods of a ColorFactory in the parameters they take, except the …A_Arrays are the first parameter of the ColorFactory’s methods.  Many specific …A_Arrays also have specific direct conversion methods to other corresponding color space models.  The RGBA_Color objects also have within themselves direct conversion properties to all other color-models, as well as properties that provide “contrast” and “shade.”  These other custom Color Objects have within them a conversion property to RGB, and HSBA_Color & HSVA_Color objects also provide a conversion property to CMYK, since this is a near-parallel mapping.  You can also find this latter conversion service as a static function at: SoftMoon.WebWare.HSVA_Color.to_CMYK()

    const myRGB=new SoftMoon.WebWare.RGBA_Color(245, 191, 46); console.log(myRGB.to.hcg); //this is a property, not a method. console.log(myRGB.to.cmyk); //this is a property, not a method. console.log(myRGB.to.xyz); //this is a property, not a method. console.log(myRGB.to_xyz(SoftMoon.WebWare.XYZA_Array)); //this is a method inherited from RGBA_Array, and it takes an optional factory specifier console.log(myRGB.contrast); //this is a property, not a method. const myHSV=new SoftMoon.WebWare.HSVA_Color(0.4, 0.9, 0.67); console.log(myHSV.to.rgb); //this is a property, not a method. console.log(myHSV.to.cmyk); //this is a property, not a method. const myHSV_array=[0.4, 0.9, 0.67]; console.log(SoftMoon.WebWare.HSVA_Color.to_CMYK(myHSV_array)); // this is a simple function, not a method.

    These custom color Arrays also provide .toString() methods that provide user-friendly reading.  These methods are highly customizable with ease, on-the-fly as necessary.  To control their output, you use the ConfigStack configuration object of the custom color Object (e.g. myColor.config.stringFormat) or pass in the formatting info directly to the .toString() method.  For ColorWheel_Arrays, the .config.useAngleUnitSymbol option is valid also.  See the ▲details in the section on ConfigStacks above.

    You should note that the HSB and HSV color-models are actually one-in-the-same.  RGB_Calc’s custom underlying Color-Array is therefore the just about same: HSBA_Array is an extension of HSVA_Array.  You can access “.brightness” from an HSVA_Array instance, and “.value” from an HSBA_Array instance.  The only difference is in the constructor and model values:

    const hsv=new SoftMoon.WebWare.HSVA_Color(0.3, 0.5, 0.7); const hsb=new SoftMoon.WebWare.HSBA_Color(0.3, 0.5, 0.7); console.log(hsv instanceof HSBA_Color); //false console.log(hsb instanceof HSVA_Color); //true console.log(hsv instanceof ColorWheel_Array); //true console.log(hsb instanceof ColorWheel_Array); //true console.log(hsv.model) //HSV console.log(hsb.model) //HSB console.log(hsv.brightness) //0.7 console.log(hsb.value) //0.7

    Using the ColorFactory class

    If you’ve made it this far and read this whole preceding instructional document,
    Ⓐ you deserve a Skoobie Snack, &
    Ⓑ understanding how to use the ColorFactory class should be simple. 
    Like calculators and color Objects, a ColorFactory instance has its own ConfigStack instance.  Unlike RGB_Calc, you must create an instance of a ColorFactory to use its features.  When you create an instance of ColorFactory, you can pass in a $config value to the constructor, and this $config determines how the ColorFactory instance interprets color-data-strings, as well as defining the specific default “Factories” to use for each color model you create, copy to, or convert to.  Don’t confuse the $config value for the class constructor with the $config values you can pass into this class’ methods, the latter of which is for the color-object you create (typically …A_Colors).  ColorFactory instances have three methods:

    .createColor($color, $config, $dSpace)
    This method interprets a (user-input) string and returns the value through the factory you desire.  Use the .config property of you ColorFactory to control which factory to return the color-data through (…A_Arrays by default).  If you pass an optional $config value as well as a $color-definition-string, it will be passed into the factory constructor for your returned color-object.  Typically, using $config is only for creating …A_Colors, but you can use it for your own color class constructor as well.  Oddly, if you use the optional $dSpace argument, $config is used for both the final destination color space model Object, as well as the intermediary “interpreted” color Object.  If you pass in an optional $dSpace string, the interpreted color will then be converted to that color space model using the ColorFactory instance’s .convertColor() method (see below for more info on $dSpace…)
    .copyColor($color, $model, $factory, $config)
    This method simply copies the array of color-data you pass in ⇨ to the factory (constructor) of your choice.  You only need to specify the $model if your color-data array does not have a .model property (note that …A_Arrays and their child-classes …A_Colors have the .model property).  If you don’t pass in an optional $factory, it uses the factory specified in the ColorFactory instance’s .config property.  If you pass an optional $config value, it will be passed into the factory constructor for your returned color-object.  Typically, using $config is only for creating …A_Colors, but you can use it for your own color class constructor as well.
    .convertColor($color, $dSpace, $factory, $config)
    This method converts the …A_Array or child class of color model data ($color) you pass in ⇨ to another color space model ($dSpace).  Remember that $dSpace is a ¡case-sensitive! string in able to specify the type of factory within this method, even if you supply an optional $factory.  If you don’t pass in an optional $factory, it uses the factory specified in the ColorFactory instance’s .config property.  If you pass an optional $config value, it will be applied to the newly created color-object’s .config property after the color-object is created (¡not passed into the factory constructor as other ColorFactory methods do!).  Typically, using $config is only for creating …A_Colors.

    ¡You’re almost done learning!

    Now you have the overall perspective of what this library package can do.  You’re about ready to use the features in your own projects … … … except you still can learn more about the details of each aspect of this package by reading the source-code to make the most out of its features.  Slackers and hackees (those who get hacked) just pick a library and use it without understanding all of it.  So many details about …A_Arrays and their children are too numerous to list here … see the codebase to find what they offer.  There are even more goodies for your package to consume like a plethora of RegExps that can do heavy lifting for you.  ¡¡☻Happy programming☻!!