color-swatch
Version:
A web component for displaying color swatches.
1,603 lines • 115 kB
JavaScript
function _e(t, e) {
let r = t.length, n, a, s = !1, o = !1;
Array.isArray(t[0]) ? n = /** @type {number[][]} */
t : (n = [
/** @type {number[]} */
t
], r = n.length, s = !0), Array.isArray(e[0]) ? a = /** @type {number[][]} */
e : (a = e.length > 0 ? e.map((h) => [h]) : [[]], o = !0);
let i = a[0].length, l = a[0].map((h, u) => a.map((f) => f[u])), c = n.map((h) => l.map((u) => {
let f = 0;
if (!Array.isArray(h)) {
for (let d of u)
f += h * d;
return f;
}
for (let d = 0; d < h.length; d++)
f += h[d] * (u[d] || 0);
return f;
}));
return r === 1 && s && (c = c[0]), i === 1 && o ? r === 1 && s ? c[0] : c.map((h) => h[0]) : c;
}
function ct(t, e) {
return t[0] * e[0] + t[1] * e[1] + t[2] * e[2];
}
function k(t, e, r = [0, 0, 0]) {
const n = ct(t, e[0]), a = ct(t, e[1]), s = ct(t, e[2]);
return r[0] = n, r[1] = a, r[2] = s, r;
}
function ye(t) {
return U(t) === "string";
}
function U(t) {
return (Object.prototype.toString.call(t).match(/^\[object\s+(.*?)\]$/)[1] || "").toLowerCase();
}
function zt(t, { precision: e = 16, unit: r }) {
return _(t) ? "none" : (t = +$t(t, e), t + (r ?? ""));
}
function _(t) {
return t === null;
}
function B(t) {
return _(t) ? 0 : t;
}
function $t(t, e) {
if (t === 0)
return 0;
let r = ~~t, n = 0;
r && e && (n = ~~Math.log10(Math.abs(r)) + 1);
const a = 10 ** (e - n);
return Math.floor(t * a + 0.5) / a;
}
function Be(t, e, r) {
return isNaN(t) ? e : isNaN(e) ? t : t + (e - t) * r;
}
function Zr(t, e, r) {
return (r - t) / (e - t);
}
function xt(t, e, r) {
return !t || !e || t === e || t[0] === e[0] && t[1] === e[1] || isNaN(r) || r === null ? r : Be(e[0], e[1], Zr(t[0], t[1], r));
}
function tt(t, e, r) {
return Math.max(Math.min(r, e), t);
}
function rt(t, e) {
return Math.sign(t) === Math.sign(e) ? t : -t;
}
function A(t, e) {
return rt(Math.abs(t) ** e, t);
}
function Et(t, e) {
return e === 0 ? 0 : t / e;
}
function Fr(t, e, r = 0, n = t.length) {
for (; r < n; ) {
const a = r + n >> 1;
t[a] < e ? r = a + 1 : n = a;
}
return r;
}
function pe(t, e) {
if (t instanceof e)
return !0;
const r = e.name;
for (; t; ) {
const n = Object.getPrototypeOf(t), a = n?.constructor?.name;
if (a === r)
return !0;
if (!a || a === "Object")
return !1;
t = n;
}
return !1;
}
var T0 = /* @__PURE__ */ Object.freeze({
__proto__: null,
bisectLeft: Fr,
clamp: tt,
copySign: rt,
interpolate: Be,
interpolateInv: Zr,
isInstance: pe,
isNone: _,
isString: ye,
mapRange: xt,
multiplyMatrices: _e,
multiply_v3_m3x3: k,
serializeNumber: zt,
skipNone: B,
spow: A,
toPrecision: $t,
type: U,
zdiv: Et
});
class z0 {
add(e, r, n) {
if (typeof arguments[0] != "string") {
for (var e in arguments[0])
this.add(e, arguments[0][e], arguments[1]);
return;
}
(Array.isArray(e) ? e : [e]).forEach(function(a) {
this[a] = this[a] || [], r && this[a][n ? "unshift" : "push"](r);
}, this);
}
run(e, r) {
this[e] = this[e] || [], this[e].forEach(function(n) {
n.call(r && r.context ? r.context : r, r);
});
}
}
const te = new z0();
var q = {
gamut_mapping: "css",
precision: 5,
deltaE: "76",
// Default deltaE method
verbose: globalThis?.process?.env?.NODE_ENV?.toLowerCase() !== "test",
warn: function(e) {
this.verbose && globalThis?.console?.warn?.(e);
}
};
class Zt {
// Class properties - declared here so that type inference works
type;
coordMeta;
coordRange;
/** @type {[number, number]} */
range;
/**
* @param {any} type
* @param {import("./types.js").CoordMeta} coordMeta
*/
constructor(e, r) {
if (typeof e == "object" && (this.coordMeta = e), r && (this.coordMeta = r, this.coordRange = r.range ?? r.refRange), typeof e == "string") {
let n = e.trim().match(/^(?<type><[a-z]+>)(\[(?<min>-?[.\d]+),\s*(?<max>-?[.\d]+)\])?$/);
if (!n)
throw new TypeError(`Cannot parse ${e} as a type definition.`);
this.type = n.groups.type;
let { min: a, max: s } = n.groups;
(a || s) && (this.range = [+a, +s]);
}
}
/** @returns {[number, number]} */
get computedRange() {
return this.range ? this.range : this.type === "<percentage>" ? this.percentageRange() : this.type === "<angle>" ? [0, 360] : null;
}
get unit() {
return this.type === "<percentage>" ? "%" : this.type === "<angle>" ? "deg" : "";
}
/**
* Map a number to the internal representation
* @param {number} number
*/
resolve(e) {
if (this.type === "<angle>")
return e;
let r = this.computedRange, n = this.coordRange;
return this.type === "<percentage>" && (n ??= this.percentageRange()), xt(r, n, e);
}
/**
* Serialize a number from the internal representation to a string
* @param {number} number
* @param {number} [precision]
*/
serialize(e, r) {
let n = this.type === "<percentage>" ? this.percentageRange(100) : this.computedRange, a = this.unit;
return e = xt(this.coordRange, n, e), zt(e, { unit: a, precision: r });
}
toString() {
let e = this.type;
if (this.range) {
let [r = "", n = ""] = this.range;
e += `[${r},${n}]`;
}
return e;
}
/**
* Returns a percentage range for values of this type
* @param {number} scale
* @returns {[number, number]}
*/
percentageRange(e = 1) {
let r;
return this.coordMeta && this.coordMeta.range || this.coordRange && this.coordRange[0] >= 0 ? r = [0, 1] : r = [-1, 1], [r[0] * e, r[1] * e];
}
static get(e, r) {
return pe(e, this) ? e : new this(e, r);
}
}
const ut = /* @__PURE__ */ Symbol("instance");
class Je {
// Class properties - declared here so that type inference works
type;
name;
spaceCoords;
/** @type {Type[][]} */
coords;
/** @type {string | undefined} */
id;
/** @type {boolean | undefined} */
alpha;
/**
* @param {FormatInterface} format
* @param {ColorSpace} space
*/
constructor(e, r = e.space) {
e[ut] = this, this.type = "function", this.name = "color", Object.assign(this, e), this.space = r, this.type !== "custom" && (this.spaceCoords = Object.values(r.coords), this.coords || (this.coords = this.spaceCoords.map((n) => {
let a = ["<number>", "<percentage>"];
return n.type === "angle" && a.push("<angle>"), a;
})), this.coords = this.coords.map(
/** @param {string | string[] | Type[]} types */
(n, a) => {
let s = this.spaceCoords[a];
return typeof n == "string" && (n = n.trim().split(/\s*\|\s*/)), n.map((o) => Zt.get(o, s));
}
));
}
/**
* @param {Coords} coords
* @param {number} precision
* @param {Type[]} types
*/
serializeCoords(e, r, n) {
return n = e.map((a, s) => Zt.get(n?.[s] ?? this.coords[s][0], this.spaceCoords[s])), e.map((a, s) => n[s].serialize(a, r));
}
/**
* Validates the coordinates of a color against a format's coord grammar and
* maps the coordinates to the range or refRange of the coordinates.
* @param {Coords} coords
* @param {[string, string, string]} types
*/
coerceCoords(e, r) {
return Object.entries(this.space.coords).map(([n, a], s) => {
let o = e[s];
if (_(o) || isNaN(o))
return o;
let i = r[s], l = this.coords[s].find((c) => c.type == i);
if (!l) {
let c = a.name || n;
throw new TypeError(
`${i ?? /** @type {any} */
o?.raw ?? o} not allowed for ${c} in ${this.name}()`
);
}
return o = l.resolve(o), l.range && (r[s] = l.toString()), o;
});
}
/**
* @returns {boolean | Required<FormatInterface>["serialize"]}
*/
canSerialize() {
return this.type === "function" || /** @type {any} */
this.serialize;
}
/**
* @param {string} str
* @returns {(import("./types.js").ColorConstructor) | undefined | null}
*/
parse(e) {
return null;
}
/**
* @param {Format | FormatInterface} format
* @param {RemoveFirstElement<ConstructorParameters<typeof Format>>} args
* @returns {Format}
*/
static get(e, ...r) {
return !e || pe(e, this) ? (
/** @type {Format} */
e
) : e[ut] ? e[ut] : new Je(e, ...r);
}
}
const I = {
// for compatibility, the four-digit chromaticity-derived ones everyone else uses
D50: [0.3457 / 0.3585, 1, (1 - 0.3457 - 0.3585) / 0.3585],
D65: [0.3127 / 0.329, 1, (1 - 0.3127 - 0.329) / 0.329]
};
function _t(t) {
return Array.isArray(t) ? t : I[t];
}
function We(t, e, r, n = {}) {
if (t = _t(t), e = _t(e), !t || !e)
throw new TypeError(
`Missing white point to convert ${t ? "" : "from"}${!t && !e ? "/" : ""}${e ? "" : "to"}`
);
if (t === e)
return r;
let a = { W1: t, W2: e, XYZ: r, options: n };
if (te.run("chromatic-adaptation-start", a), a.M || (a.W1 === I.D65 && a.W2 === I.D50 ? a.M = [
[1.0479297925449969, 0.022946870601609652, -0.05019226628920524],
[0.02962780877005599, 0.9904344267538799, -0.017073799063418826],
[-0.009243040646204504, 0.015055191490298152, 0.7518742814281371]
] : a.W1 === I.D50 && a.W2 === I.D65 && (a.M = [
[0.955473421488075, -0.02309845494876471, 0.06325924320057072],
[-0.0283697093338637, 1.0099953980813041, 0.021041441191917323],
[0.012314014864481998, -0.020507649298898964, 1.330365926242124]
])), te.run("chromatic-adaptation-end", a), a.M)
return k(a.XYZ, a.M);
throw new TypeError("Only Bradford CAT with white points D50 and D65 supported for now.");
}
function Jr(t, e) {
let r = {
str: String(t)?.trim(),
options: e
};
if (te.run("parse-start", r), r.color)
return r.color;
r.parsed = E0(r.str);
let n, a = r.options ? r.options.parseMeta ?? r.options.meta : null;
if (r.parsed) {
let s = r.parsed.name, o, i, l = r.parsed.args, c = l.map((f, d) => r.parsed.argMeta[d]?.type);
if (s === "color") {
let f = l.shift();
c.shift();
let d = f.startsWith("--") ? f.substring(2) : `--${f}`, m = [f, d];
if (o = g.findFormat({ name: s, id: m, type: "function" }), !o) {
let M, p = f in g.registry ? f : d;
if (p in g.registry) {
let y = g.registry[p].formats?.color?.id;
y && (M = `Did you mean ${t.replace("color(" + f, "color(" + y)}?`);
}
throw new TypeError(
`Cannot parse ${r.str}. ` + (M ?? "Missing a plugin?")
);
}
i = o.space, o.id.startsWith("--") && !f.startsWith("--") && q.warn(
`${i.name} is a non-standard space and not currently supported in the CSS spec. Use prefixed color(${o.id}) instead of color(${f}).`
), f.startsWith("--") && !o.id.startsWith("--") && q.warn(
`${i.name} is a standard space and supported in the CSS spec. Use color(${o.id}) instead of prefixed color(${f}).`
);
} else
o = g.findFormat({ name: s, type: "function" }), i = o.space;
a && Object.assign(a, {
format: o,
formatId: o.name,
types: c,
commas: r.parsed.commas
});
let h = 1;
r.parsed.lastAlpha && (h = r.parsed.args.pop(), a && (a.alphaType = c.pop()));
let u = o.coords.length;
if (l.length !== u)
throw new TypeError(
`Expected ${u} coordinates for ${i.id} in ${r.str}), got ${l.length}`
);
l = o.coerceCoords(l, c), n = { spaceId: i.id, coords: l, alpha: h };
} else
e: for (let s of g.all)
for (let o in s.formats) {
let i = s.formats[o];
if (i.type !== "custom" || i.test && !i.test(r.str))
continue;
let l = s.getFormat(i), c = l.parse(r.str);
if (c) {
a && Object.assign(a, { format: l, formatId: o }), n = c;
break e;
}
}
if (!n)
throw new TypeError(`Could not parse ${t} as a color. Missing a plugin?`);
return n.alpha = _(n.alpha) ? n.alpha : n.alpha === void 0 ? 1 : tt(0, n.alpha, 1), n;
}
const Wr = {
"%": 0.01,
deg: 1,
grad: 0.9,
rad: 180 / Math.PI,
turn: 360
}, Ve = {
// Need to list calc(NaN) explicitly as otherwise its ending paren would terminate the function call
function: /^([a-z]+)\(((?:calc\(NaN\)|.)+?)\)$/i,
number: /^([-+]?(?:[0-9]*\.)?[0-9]+(e[-+]?[0-9]+)?)$/i,
unitValue: RegExp(`(${Object.keys(Wr).join("|")})$`),
// NOTE The -+ are not just for prefix, but also for idents, and e+N notation!
singleArgument: /\/?\s*(none|NaN|calc\(NaN\)|[-+\w.]+(?:%|deg|g?rad|turn)?)/g
};
function $0(t) {
let e = {}, r = t.match(Ve.unitValue)?.[0], n = e.raw = t;
return r ? (e.type = r === "%" ? "<percentage>" : "<angle>", e.unit = r, e.unitless = Number(n.slice(0, -r.length)), n = e.unitless * Wr[r]) : Ve.number.test(n) ? (n = Number(n), e.type = "<number>") : n === "none" ? n = null : n === "NaN" || n === "calc(NaN)" ? (n = NaN, e.type = "<number>") : e.type = "<ident>", { value: (
/** @type {number} */
n
), meta: (
/** @type {ArgumentMeta} */
e
) };
}
function E0(t) {
if (!t)
return;
t = t.trim();
let e = t.match(Ve.function);
if (e) {
let r = [], n = [], a = !1, s = e[1].toLowerCase(), o = e[2].replace(Ve.singleArgument, (i, l) => {
let { value: c, meta: h } = $0(l);
return (
// If there's a slash here, it's modern syntax
(i.startsWith("/") || // If there's still elements to process after there's already 3 in `args` (and the we're not dealing with "color()"), it's likely to be a legacy color like "hsl(0, 0%, 0%, 0.5)"
s !== "color" && r.length === 3) && (a = !0), r.push(c), n.push(h), ""
);
});
return {
name: s,
args: r,
argMeta: n,
lastAlpha: a,
commas: o.includes(","),
rawName: e[1],
rawArgs: e[2]
};
}
}
function C(t, e) {
if (Array.isArray(t))
return t.map((n) => C(n, e));
if (!t)
throw new TypeError("Empty color reference");
ye(t) && (t = Jr(t, e));
let r = t.space || t.spaceId;
return typeof r == "string" && (t.space = g.get(r)), t.alpha === void 0 && (t.alpha = 1), t;
}
const I0 = 75e-6;
class g {
constructor(e) {
this.id = e.id, this.name = e.name, this.base = e.base ? g.get(e.base) : null, this.aliases = e.aliases, this.base && (this.fromBase = e.fromBase, this.toBase = e.toBase);
let r = e.coords ?? this.base.coords;
for (let a in r)
"name" in r[a] || (r[a].name = a);
this.coords = r;
let n = e.white ?? this.base.white ?? "D65";
this.white = _t(n), this.formats = e.formats ?? {};
for (let a in this.formats) {
let s = this.formats[a];
s.type ||= "function", s.name ||= a;
}
this.formats.color?.id || (this.formats.color = {
...this.formats.color ?? {},
id: e.cssId || this.id
}), e.gamutSpace ? this.gamutSpace = e.gamutSpace === "self" ? this : g.get(e.gamutSpace) : this.isPolar ? this.gamutSpace = this.base : this.gamutSpace = this, this.gamutSpace.isUnbounded && (this.inGamut = (a, s) => !0), this.referred = e.referred, Object.defineProperty(this, "path", {
value: O0(this).reverse(),
writable: !1,
enumerable: !0,
configurable: !0
}), te.run("colorspace-init-end", this);
}
inGamut(e, { epsilon: r = I0 } = {}) {
if (!this.equals(this.gamutSpace))
return e = this.to(this.gamutSpace, e), this.gamutSpace.inGamut(e, { epsilon: r });
let n = Object.values(this.coords);
return e.every((a, s) => {
let o = n[s];
if (o.type !== "angle" && o.range) {
if (_(a))
return !0;
let [i, l] = o.range;
return (i === void 0 || a >= i - r) && (l === void 0 || a <= l + r);
}
return !0;
});
}
get isUnbounded() {
return Object.values(this.coords).every((e) => !("range" in e));
}
get cssId() {
return this.formats?.color?.id || this.id;
}
get isPolar() {
for (let e in this.coords)
if (this.coords[e].type === "angle")
return !0;
return !1;
}
/**
* Lookup a format in this color space
* @param {string | object | Format} format - Format id if string. If object, it's converted to a `Format` object and returned.
* @returns {Format}
*/
getFormat(e) {
if (!e)
return null;
e === "default" ? e = Object.values(this.formats)[0] : typeof e == "string" && (e = this.formats[e]);
let r = Je.get(e, this);
return r !== e && e.name in this.formats && (this.formats[e.name] = r), r;
}
/**
* Check if this color space is the same as another color space reference.
* Allows proxying color space objects and comparing color spaces with ids.
* @param {string | ColorSpace} space ColorSpace object or id to compare to
* @returns {boolean}
*/
equals(e) {
return e ? this === e || this.id === e || this.id === e.id : !1;
}
to(e, r) {
if (arguments.length === 1) {
const i = C(e);
[e, r] = [i.space, i.coords];
}
if (e = g.get(e), this.equals(e))
return r;
r = r.map((i) => _(i) ? 0 : i);
let n = this.path, a = e.path, s, o;
for (let i = 0; i < n.length && n[i].equals(a[i]); i++)
s = n[i], o = i;
if (!s)
throw new Error(
`Cannot convert between color spaces ${this} and ${e}: no connection space was found`
);
for (let i = n.length - 1; i > o; i--)
r = n[i].toBase(r);
for (let i = o + 1; i < a.length; i++)
r = a[i].fromBase(r);
return r;
}
from(e, r) {
if (arguments.length === 1) {
const n = C(e);
[e, r] = [n.space, n.coords];
}
return e = g.get(e), e.to(this, r);
}
toString() {
return `${this.name} (${this.id})`;
}
getMinCoords() {
let e = [];
for (let r in this.coords) {
let n = this.coords[r], a = n.range || n.refRange;
e.push(a?.min ?? 0);
}
return e;
}
static registry = {};
// Returns array of unique color spaces
static get all() {
return [...new Set(Object.values(g.registry))];
}
static register(e, r) {
if (arguments.length === 1 && (r = arguments[0], e = r.id), r = this.get(r), this.registry[e] && this.registry[e] !== r)
throw new Error(`Duplicate color space registration: '${e}'`);
if (this.registry[e] = r, arguments.length === 1 && r.aliases)
for (let n of r.aliases)
this.register(n, r);
return r;
}
/**
* Lookup ColorSpace object by name
* @param {ColorSpace | string} name
*/
static get(e, ...r) {
if (!e || pe(e, this))
return e;
if (U(e) === "string") {
let a = g.registry[e.toLowerCase()];
if (!a)
throw new TypeError(`No color space found with id = "${e}"`);
return a;
}
if (r.length)
return g.get(...r);
throw new TypeError(`${e} is not a valid color space`);
}
/**
* Look up all color spaces for a format that matches certain criteria
* @param {object | string} filters
* @param {Array<ColorSpace>} [spaces=ColorSpace.all]
* @returns {Format | null}
*/
static findFormat(e, r = g.all) {
if (!e)
return null;
typeof e == "string" && (e = { name: e });
for (let n of r)
for (let [a, s] of Object.entries(n.formats)) {
s.name ??= a, s.type ??= "function";
let o = (!e.name || s.name === e.name) && (!e.type || s.type === e.type);
if (e.id) {
let i = s.ids || [s.id], l = Array.isArray(e.id) ? e.id : [e.id];
o &&= l.some((c) => i.includes(c));
}
if (o) {
let i = Je.get(s, n);
return i !== s && (n.formats[s.name] = i), i;
}
}
return null;
}
/**
* Get metadata about a coordinate of a color space
*
* @static
* @param {Array | string} ref
* @param {ColorSpace | string} [workingSpace]
* @return {Object}
*/
static resolveCoord(e, r) {
let n = U(e), a, s;
if (n === "string" ? e.includes(".") ? [a, s] = e.split(".") : [a, s] = [, e] : Array.isArray(e) ? [a, s] = e : (a = e.space, s = e.coordId), a = g.get(a), a || (a = r), !a)
throw new TypeError(
`Cannot resolve coordinate reference ${e}: No color space specified and relative references are not allowed here`
);
if (n = U(s), n === "number" || n === "string" && s >= 0) {
let l = Object.entries(a.coords)[s];
if (l)
return { space: a, id: l[0], index: s, ...l[1] };
}
a = g.get(a);
let o = s.toLowerCase(), i = 0;
for (let l in a.coords) {
let c = a.coords[l];
if (l.toLowerCase() === o || c.name?.toLowerCase() === o)
return { space: a, id: l, index: i, ...c };
i++;
}
throw new TypeError(
`No "${s}" coordinate found in ${a.name}. Its coordinates are: ${Object.keys(a.coords).join(", ")}`
);
}
static DEFAULT_FORMAT = {
type: "functions",
name: "color"
};
}
function O0(t) {
let e = [t];
for (let r = t; r = r.base; )
e.push(r);
return e;
}
var $ = new g({
id: "xyz-d65",
name: "XYZ D65",
coords: {
x: {
refRange: [0, 1],
name: "X"
},
y: {
refRange: [0, 1],
name: "Y"
},
z: {
refRange: [0, 1],
name: "Z"
}
},
white: "D65",
formats: {
color: {
ids: ["xyz-d65", "xyz"]
}
},
aliases: ["xyz"]
});
class E extends g {
/**
* Creates a new RGB ColorSpace.
* If coords are not specified, they will use the default RGB coords.
* Instead of `fromBase()` and `toBase()` functions,
* you can specify to/from XYZ matrices and have `toBase()` and `fromBase()` automatically generated.
* @param {RGBOptions} options
*/
constructor(e) {
e.coords || (e.coords = {
r: {
range: [0, 1],
name: "Red"
},
g: {
range: [0, 1],
name: "Green"
},
b: {
range: [0, 1],
name: "Blue"
}
}), e.base || (e.base = $), e.toXYZ_M && e.fromXYZ_M && (e.toBase ??= (r) => {
let n = k(r, e.toXYZ_M);
return this.white !== this.base.white && (n = We(this.white, this.base.white, n)), n;
}, e.fromBase ??= (r) => (r = We(this.base.white, this.white, r), k(r, e.fromXYZ_M))), e.referred ??= "display", super(e);
}
}
function Vr(t, e = {}) {
if (Array.isArray(t))
return t.map((l) => Vr(l, e));
let { cssProperty: r = "background-color", element: n, ...a } = e, s = null;
try {
return C(t, a);
} catch (l) {
s = l;
}
let { CSS: o, getComputedStyle: i } = globalThis;
if (ye(t) && n && o && i && o.supports(r, t)) {
let l = n.style[r];
t !== l && (n.style[r] = t);
let c = i(n).getPropertyValue(r);
if (t !== l && (n.style[r] = l), c !== t)
try {
return C(c, a);
} catch (h) {
s = h;
}
else
s = {
message: "Color value is a valid CSS color, but it could not be resolved :("
};
}
return e.errorMeta && (e.errorMeta.error = s), null;
}
function ze(t, e) {
t = C(t);
let r = g.get(e, e?.space), n = e?.precision, a;
return !r || t.space.equals(r) ? a = t.coords.slice() : a = r.from(t), n === void 0 ? a : a.map((s) => $t(s, n));
}
function N(t, e) {
if (t = C(t), e === "alpha")
return t.alpha ?? 1;
let { space: r, index: n } = g.resolveCoord(e, t.space);
return ze(t, r)[n];
}
function It(t, e, r, n) {
return t = C(t), Array.isArray(e) && ([e, r, n] = [t.space, e, r]), e = g.get(e), t.coords = e === t.space ? r.slice() : e.to(t.space, r), n !== void 0 && (t.alpha = n), t;
}
It.returns = "color";
function W(t, e, r) {
if (t = C(t), arguments.length === 2 && U(arguments[1]) === "object") {
let n = arguments[1];
for (let a in n)
W(t, a, n[a]);
} else if (typeof r == "function" && (r = r(N(t, e))), e === "alpha")
t.alpha = r;
else {
let { space: n, index: a } = g.resolveCoord(e, t.space), s = ze(t, n);
s[a] = r, It(t, n, s);
}
return t;
}
W.returns = "color";
var Ot = new g({
id: "xyz-d50",
name: "XYZ D50",
white: "D50",
base: $,
fromBase: (t) => We($.white, "D50", t),
toBase: (t) => We("D50", $.white, t)
});
const P0 = 216 / 24389, Ft = 24 / 116, Pe = 24389 / 27;
let ht = I.D50;
var D = new g({
id: "lab",
name: "Lab",
coords: {
l: {
refRange: [0, 100],
name: "Lightness"
},
a: {
refRange: [-125, 125]
},
b: {
refRange: [-125, 125]
}
},
// Assuming XYZ is relative to D50, convert to CIE Lab
// from CIE standard, which now defines these as a rational fraction
white: ht,
base: Ot,
// Convert D50-adapted XYX to Lab
// CIE 15.3:2004 section 8.2.1.1
fromBase(t) {
let r = t.map((o, i) => o / ht[i]).map((o) => o > P0 ? Math.cbrt(o) : (Pe * o + 16) / 116), n = 116 * r[1] - 16, a = 500 * (r[0] - r[1]), s = 200 * (r[1] - r[2]);
return [n, a, s];
},
// Convert Lab to D50-adapted XYZ
// Same result as CIE 15.3:2004 Appendix D although the derivation is different
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
toBase(t) {
let [e, r, n] = t, a = [];
return a[1] = (e + 16) / 116, a[0] = r / 500 + a[1], a[2] = a[1] - n / 200, [
a[0] > Ft ? Math.pow(a[0], 3) : (116 * a[0] - 16) / Pe,
t[0] > 8 ? Math.pow((t[0] + 16) / 116, 3) : t[0] / Pe,
a[2] > Ft ? Math.pow(a[2], 3) : (116 * a[2] - 16) / Pe
].map((o, i) => o * ht[i]);
},
formats: {
lab: {
coords: [
"<percentage> | <number>",
"<number> | <percentage>",
"<number> | <percentage>"
]
}
}
});
function X(t) {
return typeof t != "number" ? t : (t % 360 + 360) % 360;
}
function Qr(t, e) {
let [r, n] = e, a = _(r), s = _(n);
if (a && s)
return [r, n];
if (a ? r = n : s && (n = r), t === "raw")
return e;
r = X(r), n = X(n);
let o = n - r;
return t === "increasing" ? o < 0 && (n += 360) : t === "decreasing" ? o > 0 && (r += 360) : t === "longer" ? -180 < o && o < 180 && (o > 0 ? r += 360 : n += 360) : t === "shorter" && (o > 180 ? r += 360 : o < -180 && (n += 360)), [r, n];
}
var Y = new g({
id: "lch",
name: "LCH",
coords: {
l: {
refRange: [0, 100],
name: "Lightness"
},
c: {
refRange: [0, 150],
name: "Chroma"
},
h: {
refRange: [0, 360],
type: "angle",
name: "Hue"
}
},
base: D,
fromBase(t) {
if (this.ε === void 0) {
let i = Object.values(this.base.coords)[1].refRange, l = i[1] - i[0];
this.ε = l / 1e5;
}
let [e, r, n] = t, a = Math.abs(r) < this.ε && Math.abs(n) < this.ε, s = a ? null : X(Math.atan2(n, r) * 180 / Math.PI), o = a ? 0 : Math.sqrt(r ** 2 + n ** 2);
return [e, o, s];
},
toBase(t) {
let [e, r, n] = t, a = null, s = null;
return _(n) || (r = r < 0 ? 0 : r, a = r * Math.cos(n * Math.PI / 180), s = r * Math.sin(n * Math.PI / 180)), [e, a, s];
},
formats: {
lch: {
coords: ["<percentage> | <number>", "<number> | <percentage>", "<number> | <angle>"]
}
}
});
const Jt = 25 ** 7, Qe = Math.PI, Wt = 180 / Qe, ue = Qe / 180;
function Vt(t) {
const e = t * t;
return e * e * e * t;
}
function Kr(t, e, { kL: r = 1, kC: n = 1, kH: a = 1 } = {}) {
[t, e] = C([t, e]);
let [s, o, i] = D.from(t), l = Y.from(D, [s, o, i])[1], [c, h, u] = D.from(e), f = Y.from(D, [c, h, u])[1];
l < 0 && (l = 0), f < 0 && (f = 0);
let d = (l + f) / 2, m = Vt(d), M = 0.5 * (1 - Math.sqrt(m / (m + Jt))), p = (1 + M) * o, y = (1 + M) * h, b = Math.sqrt(p ** 2 + i ** 2), w = Math.sqrt(y ** 2 + u ** 2), x = p === 0 && i === 0 ? 0 : Math.atan2(i, p), S = y === 0 && u === 0 ? 0 : Math.atan2(u, y);
x < 0 && (x += 2 * Qe), S < 0 && (S += 2 * Qe), x *= Wt, S *= Wt;
let O = c - s, P = w - b, R = S - x, H = x + S, V = Math.abs(R), G;
b * w === 0 ? G = 0 : V <= 180 ? G = R : R > 180 ? G = R - 360 : R < -180 ? G = R + 360 : q.warn("the unthinkable has happened");
let F = 2 * Math.sqrt(w * b) * Math.sin(G * ue / 2), Q = (s + c) / 2, J = (b + w) / 2, Ce = Vt(J), j;
b * w === 0 ? j = H : V <= 180 ? j = H / 2 : H < 360 ? j = (H + 360) / 2 : j = (H - 360) / 2;
let Ee = (Q - 50) ** 2, Ie = 1 + 0.015 * Ee / Math.sqrt(20 + Ee), le = 1 + 0.045 * J, K = 1;
K -= 0.17 * Math.cos((j - 30) * ue), K += 0.24 * Math.cos(2 * j * ue), K += 0.32 * Math.cos((3 * j + 6) * ue), K -= 0.2 * Math.cos((4 * j - 63) * ue);
let ce = 1 + 0.015 * J * K, ot = 30 * Math.exp(-1 * ((j - 275) / 25) ** 2), Oe = 2 * Math.sqrt(Ce / (Ce + Jt)), xe = -1 * Math.sin(2 * ot * ue) * Oe, ae = (O / (r * Ie)) ** 2;
return ae += (P / (n * le)) ** 2, ae += (F / (a * ce)) ** 2, ae += xe * (P / (n * le)) * (F / (a * ce)), Math.sqrt(ae);
}
const H0 = [
[0.819022437996703, 0.3619062600528904, -0.1288737815209879],
[0.0329836539323885, 0.9292868615863434, 0.0361446663506424],
[0.0481771893596242, 0.2642395317527308, 0.6335478284694309]
], j0 = [
[1.2268798758459243, -0.5578149944602171, 0.2813910456659647],
[-0.0405757452148008, 1.112286803280317, -0.0717110580655164],
[-0.0763729366746601, -0.4214933324022432, 1.5869240198367816]
], N0 = [
[0.210454268309314, 0.7936177747023054, -0.0040720430116193],
[1.9779985324311684, -2.42859224204858, 0.450593709617411],
[0.0259040424655478, 0.7827717124575296, -0.8086757549230774]
], ee = [
[1, 0.3963377773761749, 0.2158037573099136],
[1, -0.1055613458156586, -0.0638541728258133],
[1, -0.0894841775298119, -1.2914855480194092]
];
var Z = new g({
id: "oklab",
name: "Oklab",
coords: {
l: {
refRange: [0, 1],
name: "Lightness"
},
a: {
refRange: [-0.4, 0.4]
},
b: {
refRange: [-0.4, 0.4]
}
},
// Note that XYZ is relative to D65
white: "D65",
base: $,
fromBase(t) {
let e = k(t, H0);
return e[0] = Math.cbrt(e[0]), e[1] = Math.cbrt(e[1]), e[2] = Math.cbrt(e[2]), k(e, N0, e);
},
toBase(t) {
let e = k(t, ee);
return e[0] = e[0] ** 3, e[1] = e[1] ** 3, e[2] = e[2] ** 3, k(e, j0, e);
},
formats: {
oklab: {
coords: [
"<percentage> | <number>",
"<number> | <percentage>",
"<number> | <percentage>"
]
}
}
});
function Lt(t, e) {
[t, e] = C([t, e]);
let [r, n, a] = Z.from(t), [s, o, i] = Z.from(e), l = r - s, c = n - o, h = a - i;
return Math.sqrt(l ** 2 + c ** 2 + h ** 2);
}
const D0 = 75e-6;
function oe(t, e, { epsilon: r = D0 } = {}) {
t = C(t), e || (e = t.space), e = g.get(e);
let n = t.coords;
return e !== t.space && (n = e.from(t)), e.inGamut(n, { epsilon: r });
}
function be(t) {
return {
space: t.space,
coords: (
/** @type {Coords} */
t.coords.slice()
),
alpha: t.alpha
};
}
function Ur(t, e, r = "lab") {
r = g.get(r);
let n = r.from(t), a = r.from(e);
return Math.sqrt(
n.reduce((s, o, i) => {
let l = a[i];
return _(o) || _(l) ? s : s + (l - o) ** 2;
}, 0)
);
}
function q0(t, e) {
return Ur(t, e, "lab");
}
const Y0 = Math.PI, Qt = Y0 / 180;
function X0(t, e, { l: r = 2, c: n = 1 } = {}) {
[t, e] = C([t, e]);
let [a, s, o] = D.from(t), [, i, l] = Y.from(D, [a, s, o]), [c, h, u] = D.from(e), f = Y.from(D, [c, h, u])[1];
i < 0 && (i = 0), f < 0 && (f = 0);
let d = a - c, m = i - f, M = s - h, p = o - u, y = M ** 2 + p ** 2 - m ** 2, b = 0.511;
a >= 16 && (b = 0.040975 * a / (1 + 0.01765 * a));
let w = 0.0638 * i / (1 + 0.0131 * i) + 0.638, x;
_(l) && (l = 0), l >= 164 && l <= 345 ? x = 0.56 + Math.abs(0.2 * Math.cos((l + 168) * Qt)) : x = 0.36 + Math.abs(0.4 * Math.cos((l + 35) * Qt));
let S = Math.pow(i, 4), O = Math.sqrt(S / (S + 1900)), P = w * (O * x + 1 - O), R = (d / (r * b)) ** 2;
return R += (m / (n * w)) ** 2, R += y / P ** 2, Math.sqrt(R);
}
const Kt = 203;
var Pt = new g({
// Absolute CIE XYZ, with a D65 whitepoint,
// as used in most HDR colorspaces as a starting point.
// SDR spaces are converted per BT.2048
// so that diffuse, media white is 203 cd/m²
id: "xyz-abs-d65",
cssId: "--xyz-abs-d65",
name: "Absolute XYZ D65",
coords: {
x: {
refRange: [0, 9504.7],
name: "Xa"
},
y: {
refRange: [0, 1e4],
name: "Ya"
},
z: {
refRange: [0, 10888.3],
name: "Za"
}
},
base: $,
fromBase(t) {
return t.map((e) => e * Kt);
},
toBase(t) {
return t.map((e) => e / Kt);
}
});
const He = 1.15, je = 0.66, Ut = 2610 / 2 ** 14, G0 = 2 ** 14 / 2610, er = 3424 / 2 ** 12, tr = 2413 / 2 ** 7, rr = 2392 / 2 ** 7, Z0 = 1.7 * 2523 / 2 ** 5, nr = 2 ** 5 / (1.7 * 2523), Ne = -0.56, ft = 16295499532821565e-27, F0 = [
[0.41478972, 0.579999, 0.014648],
[-0.20151, 1.120649, 0.0531008],
[-0.0166008, 0.2648, 0.6684799]
], J0 = [
[1.9242264357876067, -1.0047923125953657, 0.037651404030618],
[0.35031676209499907, 0.7264811939316552, -0.06538442294808501],
[-0.09098281098284752, -0.3127282905230739, 1.5227665613052603]
], W0 = [
[0.5, 0.5, 0],
[3.524, -4.066708, 0.542708],
[0.199076, 1.096799, -1.295875]
], V0 = [
[1, 0.13860504327153927, 0.05804731615611883],
[1, -0.1386050432715393, -0.058047316156118904],
[1, -0.09601924202631895, -0.811891896056039]
];
var e0 = new g({
id: "jzazbz",
name: "Jzazbz",
coords: {
jz: {
refRange: [0, 1],
name: "Jz"
},
az: {
refRange: [-0.21, 0.21]
},
bz: {
refRange: [-0.21, 0.21]
}
},
base: Pt,
fromBase(t) {
let [e, r, n] = t, a = He * e - (He - 1) * n, s = je * r - (je - 1) * e, i = (
/** @type {Vector3} } */
k([a, s, n], F0).map(function(f) {
let d = er + tr * A(f / 1e4, Ut), m = 1 + rr * A(f / 1e4, Ut);
return A(d / m, Z0);
})
), [l, c, h] = k(i, W0);
return [(1 + Ne) * l / (1 + Ne * l) - ft, c, h];
},
toBase(t) {
let [e, r, n] = t, a = (e + ft) / (1 + Ne - Ne * (e + ft)), o = (
/** @type {Vector3} } */
k([a, r, n], V0).map(function(f) {
let d = er - A(f, nr), m = rr * A(f, nr) - tr;
return 1e4 * A(d / m, G0);
})
), [i, l, c] = k(o, J0), h = (i + (He - 1) * c) / He, u = (l + (je - 1) * h) / je;
return [h, u, c];
},
formats: {
// https://drafts.csswg.org/css-color-hdr/#Jzazbz
jzazbz: {
coords: [
"<percentage> | <number>",
"<number> | <percentage>",
"<number> | <percentage>"
]
}
}
}), vt = new g({
id: "jzczhz",
name: "JzCzHz",
coords: {
jz: {
refRange: [0, 1],
name: "Jz"
},
cz: {
refRange: [0, 0.26],
name: "Chroma"
},
hz: {
refRange: [0, 360],
type: "angle",
name: "Hue"
}
},
base: e0,
fromBase: Y.fromBase,
toBase: Y.toBase,
formats: {
// https://drafts.csswg.org/css-color-hdr/#JzCzhz
jzczhz: {
coords: ["<percentage> | <number>", "<number> | <percentage>", "<number> | <angle>"]
}
}
});
function Q0(t, e) {
[t, e] = C([t, e]);
let [r, n, a] = vt.from(t), [s, o, i] = vt.from(e), l = r - s, c = n - o;
_(a) && _(i) ? (a = 0, i = 0) : _(a) ? a = i : _(i) && (i = a);
let h = a - i, u = 2 * Math.sqrt(n * o) * Math.sin(h / 2 * (Math.PI / 180));
return Math.sqrt(l ** 2 + c ** 2 + u ** 2);
}
const t0 = 3424 / 4096, r0 = 2413 / 128, n0 = 2392 / 128, ar = 2610 / 16384, K0 = 2523 / 32, U0 = 16384 / 2610, sr = 32 / 2523, en = [
[0.3592832590121217, 0.6976051147779502, -0.035891593232029],
[-0.1920808463704993, 1.100476797037432, 0.0753748658519118],
[0.0070797844607479, 0.0748396662186362, 0.8433265453898765]
], tn = [
[2048 / 4096, 2048 / 4096, 0],
[6610 / 4096, -13613 / 4096, 7003 / 4096],
[17933 / 4096, -17390 / 4096, -543 / 4096]
], rn = [
[0.9999999999999998, 0.0086090370379328, 0.111029625003026],
[0.9999999999999998, -0.0086090370379328, -0.1110296250030259],
[0.9999999999999998, 0.5600313357106791, -0.3206271749873188]
], nn = [
[2.0701522183894223, -1.3263473389671563, 0.2066510476294053],
[0.3647385209748072, 0.6805660249472273, -0.0453045459220347],
[-0.0497472075358123, -0.0492609666966131, 1.1880659249923042]
];
var St = new g({
id: "ictcp",
name: "ICTCP",
// From BT.2100-2 page 7:
// During production, signal values are expected to exceed the
// range E′ = [0.0 : 1.0]. This provides processing headroom and avoids
// signal degradation during cascaded processing. Such values of E′,
// below 0.0 or exceeding 1.0, should not be clipped during production
// and exchange.
// Values below 0.0 should not be clipped in reference displays (even
// though they represent “negative” light) to allow the black level of
// the signal (LB) to be properly set using test signals known as “PLUGE”
coords: {
i: {
refRange: [0, 1],
// Constant luminance,
name: "I"
},
ct: {
refRange: [-0.5, 0.5],
// Full BT.2020 gamut in range [-0.5, 0.5]
name: "CT"
},
cp: {
refRange: [-0.5, 0.5],
name: "CP"
}
},
base: Pt,
fromBase(t) {
let e = k(t, en);
return an(e);
},
toBase(t) {
let e = sn(t);
return k(e, nn);
},
formats: {
ictcp: {
coords: [
"<percentage> | <number>",
"<number> | <percentage>",
"<number> | <percentage>"
]
}
}
});
function an(t) {
let e = (
/** @type {Vector3} */
t.map(function(r) {
let n = t0 + r0 * (r / 1e4) ** ar, a = 1 + n0 * (r / 1e4) ** ar;
return (n / a) ** K0;
})
);
return k(e, tn);
}
function sn(t) {
return (
/** @type {Vector3} */
k(t, rn).map(function(n) {
let a = Math.max(n ** sr - t0, 0), s = r0 - n0 * n ** sr;
return 1e4 * (a / s) ** U0;
})
);
}
function on(t, e) {
[t, e] = C([t, e]);
let [r, n, a] = St.from(t), [s, o, i] = St.from(e);
return 720 * Math.sqrt((r - s) ** 2 + 0.25 * (n - o) ** 2 + (a - i) ** 2);
}
function ln(t, e) {
[t, e] = C([t, e]);
let r = 2, [n, a, s] = Z.from(t), [o, i, l] = Z.from(e), c = n - o, h = r * (a - i), u = r * (s - l);
return Math.sqrt(c ** 2 + h ** 2 + u ** 2);
}
const cn = I.D65, a0 = 0.42, or = 1 / a0, dt = 2 * Math.PI, s0 = [
[0.401288, 0.650173, -0.051461],
[-0.250268, 1.204414, 0.045854],
[-2079e-6, 0.048952, 0.953127]
], un = [
[1.8620678550872327, -1.0112546305316843, 0.14918677544445175],
[0.38752654323613717, 0.6214474419314753, -0.008973985167612518],
[-0.015841498849333856, -0.03412293802851557, 1.0499644368778496]
], hn = [
[460, 451, 288],
[460, -891, -261],
[460, -220, -6300]
], fn = {
dark: [0.8, 0.525, 0.8],
dim: [0.9, 0.59, 0.9],
average: [1, 0.69, 1]
}, se = {
// Red, Yellow, Green, Blue, Red
h: [20.14, 90, 164.25, 237.53, 380.14],
e: [0.8, 0.7, 1, 1.2, 0.8],
H: [0, 100, 200, 300, 400]
}, dn = 180 / Math.PI, ir = Math.PI / 180;
function o0(t, e) {
return (
/** @type {[number, number, number]} */
t.map((n) => {
const a = A(e * Math.abs(n) * 0.01, a0);
return 400 * rt(a, n) / (a + 27.13);
})
);
}
function mn(t, e) {
const r = 100 / e * 27.13 ** or;
return (
/** @type {[number, number, number]} */
t.map((n) => {
const a = Math.abs(n);
return rt(r * A(a / (400 - a), or), n);
})
);
}
function gn(t) {
let e = X(t);
e <= se.h[0] && (e += 360);
const r = Fr(se.h, e) - 1, [n, a] = se.h.slice(r, r + 2), [s, o] = se.e.slice(r, r + 2), i = se.H[r], l = (e - n) / s;
return i + 100 * l / (l + (a - e) / o);
}
function pn(t) {
let e = (t % 400 + 400) % 400;
const r = Math.floor(0.01 * e);
e = e % 100;
const [n, a] = se.h.slice(r, r + 2), [s, o] = se.e.slice(r, r + 2);
return X((e * (o * n - s * a) - 100 * n * o) / (e * (o - s) - 100 * o));
}
function i0(t, e, r, n, a) {
const s = {};
s.discounting = a, s.refWhite = t, s.surround = n;
const o = (
/** @type {Vector3} */
t.map((p) => p * 100)
);
s.la = e, s.yb = r;
const i = o[1], l = k(o, s0);
let c = fn[s.surround];
const h = c[0];
s.c = c[1], s.nc = c[2];
const f = (1 / (5 * s.la + 1)) ** 4;
s.fl = f * s.la + 0.1 * (1 - f) * (1 - f) * Math.cbrt(5 * s.la), s.flRoot = s.fl ** 0.25, s.n = s.yb / i, s.z = 1.48 + Math.sqrt(s.n), s.nbb = 0.725 * s.n ** -0.2, s.ncb = s.nbb;
const d = Math.max(Math.min(h * (1 - 1 / 3.6 * Math.exp((-s.la - 42) / 92)), 1), 0);
s.dRgb = /** @type {[number, number, number]} */
l.map((p) => Be(1, i / p, d)), s.dRgbInv = /** @type {[number, number, number]} */
s.dRgb.map((p) => 1 / p);
const m = (
/** @type {[number, number, number]} */
l.map((p, y) => p * s.dRgb[y])
), M = o0(m, s.fl);
return s.aW = s.nbb * (2 * M[0] + M[1] + 0.05 * M[2]), s;
}
const lr = i0(cn, 64 / Math.PI * 0.2, 20, "average", !1);
function kt(t, e) {
if (!(t.J !== void 0 ^ t.Q !== void 0))
throw new Error("Conversion requires one and only one: 'J' or 'Q'");
if (!(t.C !== void 0 ^ t.M !== void 0 ^ t.s !== void 0))
throw new Error("Conversion requires one and only one: 'C', 'M' or 's'");
if (!(t.h !== void 0 ^ t.H !== void 0))
throw new Error("Conversion requires one and only one: 'h' or 'H'");
if (t.J === 0 || t.Q === 0)
return [0, 0, 0];
let r = 0;
t.h !== void 0 ? r = X(t.h) * ir : r = pn(t.H) * ir;
const n = Math.cos(r), a = Math.sin(r);
let s = 0;
t.J !== void 0 ? s = A(t.J, 1 / 2) * 0.1 : t.Q !== void 0 && (s = 0.25 * e.c * t.Q / ((e.aW + 4) * e.flRoot));
let o = 0;
t.C !== void 0 ? o = t.C / s : t.M !== void 0 ? o = t.M / e.flRoot / s : t.s !== void 0 && (o = 4e-4 * t.s ** 2 * (e.aW + 4) / e.c);
const i = A(o * Math.pow(1.64 - Math.pow(0.29, e.n), -0.73), 10 / 9), l = 0.25 * (Math.cos(r + 2) + 3.8), c = e.aW * A(s, 2 / e.c / e.z), h = 5e4 / 13 * e.nc * e.ncb * l, u = c / e.nbb, f = 23 * (u + 0.305) * Et(i, 23 * h + i * (11 * n + 108 * a)), d = f * n, m = f * a, M = mn(
/** @type {Vector3} */
k([u, d, m], hn).map((p) => p * 1 / 1403),
e.fl
);
return (
/** @type {Vector3} */
k(
/** @type {Vector3} */
M.map((p, y) => p * e.dRgbInv[y]),
un
).map((p) => p / 100)
);
}
function l0(t, e) {
const r = (
/** @type {Vector3} */
t.map((w) => w * 100)
), n = o0(
/** @type {[number, number, number]} */
k(r, s0).map((w, x) => w * e.dRgb[x]),
e.fl
), a = n[0] + (-12 * n[1] + n[2]) / 11, s = (n[0] + n[1] - 2 * n[2]) / 9, o = (Math.atan2(s, a) % dt + dt) % dt, i = 0.25 * (Math.cos(o + 2) + 3.8), l = 5e4 / 13 * e.nc * e.ncb * Et(i * Math.sqrt(a ** 2 + s ** 2), n[0] + n[1] + 1.05 * n[2] + 0.305), c = A(l, 0.9) * Math.pow(1.64 - Math.pow(0.29, e.n), 0.73), h = e.nbb * (2 * n[0] + n[1] + 0.05 * n[2]), u = A(h / e.aW, 0.5 * e.c * e.z), f = 100 * A(u, 2), d = 4 / e.c * u * (e.aW + 4) * e.flRoot, m = c * u, M = m * e.flRoot, p = X(o * dn), y = gn(p), b = 50 * A(e.c * c / (e.aW + 4), 1 / 2);
return { J: f, C: m, h: p, s: b, Q: d, M, H: y };
}
var bn = new g({
id: "cam16-jmh",
cssId: "--cam16-jmh",
name: "CAM16-JMh",
coords: {
j: {
refRange: [0, 100],
name: "J"
},
m: {
refRange: [0, 105],
name: "Colorfulness"
},
h: {
refRange: [0, 360],
type: "angle",
name: "Hue"
}
},
base: $,
fromBase(t) {
this.ε === void 0 && (this.ε = Object.values(this.coords)[1].refRange[1] / 1e5);
const e = l0(t, lr), r = Math.abs(e.M) < this.ε;
return [e.J, r ? 0 : e.M, r ? null : e.h];
},
toBase(t) {
return kt({ J: t[0], M: t[1], h: t[2] }, lr);
}
});
const Mn = I.D65, wn = 216 / 24389, c0 = 24389 / 27;
function yn(t) {
return 116 * (t > wn ? Math.cbrt(t) : (c0 * t + 16) / 116) - 16;
}
function Rt(t) {
return t > 8 ? Math.pow((t + 16) / 116, 3) : t / c0;
}
function Cn(t, e) {
let [r, n, a] = t, s = [], o = 0;
if (a === 0)
return [0, 0, 0];
let i = Rt(a);
a > 0 ? o = 0.00379058511492914 * a ** 2 + 0.608983189401032 * a + 0.9155088574762233 : o = 9514440756550361e-21 * a ** 2 + 0.08693057439788597 * a - 21.928975842194614;
const l = 2e-12, c = 15;
let h = 0, u = 1 / 0;
for (; h <= c; ) {
s = kt({ J: o, C: n, h: r }, e);
const f = Math.abs(s[1] - i);
if (f < u) {
if (f <= l)
return s;
u = f;
}
o = o - (s[1] - i) * o / (2 * s[1]), h += 1;
}
return kt({ J: o, C: n, h: r }, e);
}
function xn(t, e) {
const r = yn(t[1]);
if (r === 0)
return [0, 0, 0];
const n = l0(t, Ht);
return [X(n.h), n.C, r];
}
const Ht = i0(
Mn,
200 / Math.PI * Rt(50),
Rt(50) * 100,
"average",
!1
);
var Ae = new g({
id: "hct",
name: "HCT",
coords: {
h: {
refRange: [0, 360],
type: "angle",
name: "Hue"
},
c: {
refRange: [0, 145],
name: "Colorfulness"
},
t: {
refRange: [0, 100],
name: "Tone"
}
},
base: $,
fromBase(t) {
this.ε === void 0 && (this.ε = Object.values(this.coords)[1].refRange[1] / 1e5);
let e = xn(t);
return e[1] < this.ε && (e[1] = 0, e[0] = null), e;
},
toBase(t) {
return Cn(t, Ht);
},
formats: {
color: {
id: "--hct",
coords: ["<number> | <angle>", "<percentage> | <number>", "<percentage> | <number>"]
}
}
});
const _n = Math.PI / 180, cr = [1, 7e-3, 0.0228];
function ur(t) {
t[1] < 0 && (t = Ae.fromBase(Ae.toBase(t)));
const e = Math.log(Math.max(1 + cr[2] * t[1] * Ht.flRoot, 1)) / cr[2], r = t[0] * _n, n = e * Math.cos(r), a = e * Math.sin(r);
return [t[2], n, a];
}
function Ln(t, e) {
[t, e] = C([t, e]);
let [r, n, a] = ur(Ae.from(t)), [s, o, i] = ur(Ae.from(e));
return Math.sqrt((r - s) ** 2 + (n - o) ** 2 + (a - i) ** 2);
}
var Me = {
deltaE76: q0,
deltaECMC: X0,
deltaE2000: Kr,
deltaEJz: Q0,
deltaEITP: on,
deltaEOK: Lt,
deltaEOK2: ln,
deltaEHCT: Ln
};
function vn(t) {
const e = t ? Math.floor(Math.log10(Math.abs(t))) : 0;
return Math.max(parseFloat(`1e${e - 2}`), 1e-6);
}
const hr = {
hct: {
method: "hct.c",
jnd: 2,
deltaEMethod: "hct",
blackWhiteClamp: {}
},
"hct-tonal": {
method: "hct.c",
jnd: 0,
deltaEMethod: "hct",
blackWhiteClamp: { channel: "hct.t", min: 0, max: 100 }
}
};
function re(t, {
method: e = q.gamut_mapping,
space: r = void 0,
deltaEMethod: n = "",
jnd: a = 2,
blackWhiteClamp: s = void 0
} = {}) {
if (t = C(t), ye(arguments[1]) ? r = arguments[1] : r || (r = t.space), r = g.get(r), oe(t, r, { epsilon: 0 }))
return (
/** @type {PlainColorObject} */
t
);
let o;
if (e === "css")
o = Sn(t, { space: r });
else {
if (e !== "clip" && !oe(t, r)) {
Object.prototype.hasOwnProperty.call(hr, e) && ({ method: e, jnd: a, deltaEMethod: n, blackWhiteClamp: s } = hr[e]);
let i = Kr;
if (n !== "") {
for (let c in Me)
if ("deltae" + n.toLowerCase() === c.toLowerCase()) {
i = Me[c];
break;
}
}
a === 0 && (a = 1e-16);
let l = re(v(t, r), { method: "clip", space: r });
if (i(t, l) > a) {
if (s && Object.keys(s).length === 3) {
let b = g.resolveCoord(s.channel), w = N(v(t, b.space), b.id);
if (_(w) && (w = 0), w >= s.max)
return v({ space: "xyz-d65", coords: I.D65 }, t.space);
if (w <= s.min)
return v({ space: "xyz-d65", coords: [0, 0, 0] }, t.space);
}
let c = g.resolveCoord(e), h = c.space, u = c.id, f = v(t, h);
f.coords.forEach((b, w) => {
_(b) && (f.coords[w] = 0);
});
let m = (c.range || c.refRange)[0], M = vn(a), p = m, y = N(f, u);
for (; y - p > M; ) {
let b = be(f);
b = re(b, { space: r, method: "clip" }), i(f, b) - a < M ? p = N(f, u) : y = N(f, u), W(f, u, (p + y) / 2);
}
o = v(f, r);
} else
o = l;
} else
o = v(t, r);
if (e === "clip" || // Dumb coord clipping
// finish off smarter gamut mapping with clip to get rid of ε, see #17
!oe(o, r, { epsilon: 0 })) {
let i = Object.values(r.coords).map((l) => l.range || []);
o.coords = /** @type {[number, number, number]} */
o.coords.map((l, c) => {
let [h, u] = i[c];
return h !== void 0 && (l = Math.max(h, l)), u !== void 0 && (l = Math.min(l, u)), l;
});
}
}
return r !== t.space && (o = v(o, t.space)), t.coords = o.coords, /** @type {PlainColorObject} */
t;
}
re.returns = "color";
const fr = {
WHITE: { space: Z, coords: [1, 0, 0], alpha: 1 },
BLACK: { space: Z, coords: [0, 0, 0], alpha: 1 }
};
function Sn(t, { space: e } = {}) {
t = C(t), e || (e = t.space), e = g.get(e);
const a = g.get("oklch");
if (e.isUnbounded)
return v(t, e);
const s = v(t, a);
let o = s.coords[0];
if (o >= 1) {
const m = v(fr.WHITE, e);
return m.alpha = t.alpha, v(m, e);
}
if (o <= 0) {
const m = v(fr.BLACK, e);
return m.alpha = t.alpha, v(m, e);
}
if (oe(s, e, { epsilon: 0 }))
return v(s, e);
function i(m) {
const M = v(m, e), p = Object.values(
/** @type {ColorSpace} */
e.coords
);
return M.coords = /** @type {[number, number, number]} */
M.coords.map((y, b) => {
if ("range" in p[b]) {
const [w, x] = p[b].range;
return tt(w, y, x);
}
return y;
}), M;
}
let l = 0, c = s.coords[1], h = !0, u = be(s), f = i(u), d = Lt(f, u);
if (d < 0.02)
return f;
for (; c - l > 1e-4; ) {
const m = (l + c) / 2;
if (u.coords[1] = m, h && oe(u, e, { epsilon: 0 }))
l = m;
else if (f = i(u), d = Lt(f, u), d < 0.02) {
if (0.02 - d < 1e-4)
break;
h = !1, l = m;
} else
c = m;
}
return f;
}
function v(t, e, { inGamut: r } = {}) {
t = C(t), e = g.get(e);
let n = e.from(t), a = { space: e, coords: n, alpha: t.alpha };
return r && (a = re(a, r === !0 ? void 0 : r)), a;
}
v.returns = "color";
function Se(t, e = {}) {
let {
precision: r = q.precision,
format: n,
inGamut: a = !0,
coords: s,
alpha: o,
commas: i
} = e, l, c = (
/** @type {PlainColorObject & ParseOptions} */
C(t)
), h = n, u = c.parseMeta;
u && !n && (u.format.canSerialize() && (n = u.format, h = u.formatId), s ??= u.types, o ??= u.alphaType, i ??= u.commas), h && (n = c.space.getFormat(n) ?? g.findFormat(h)), n || (n = c.