From 6b7702ce01f1bfab16bdaf5943b4bb06106199d8 Mon Sep 17 00:00:00 2001 From: Romain Menke Date: Sat, 11 Apr 2026 22:25:25 +0200 Subject: [PATCH] css-color-parser: add support for analogous set in color interpolations --- packages/css-color-parser/CHANGELOG.md | 4 ++ packages/css-color-parser/dist/index.mjs | 2 +- packages/css-color-parser/src/color-data.ts | 53 +++++++++++++------ .../test/basic/color-mix-function-oklch.mjs | 5 ++ .../test/basic/color-mix-function.mjs | 5 ++ 5 files changed, 52 insertions(+), 17 deletions(-) diff --git a/packages/css-color-parser/CHANGELOG.md b/packages/css-color-parser/CHANGELOG.md index d3e8d38771..b87b6a1a0c 100644 --- a/packages/css-color-parser/CHANGELOG.md +++ b/packages/css-color-parser/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to CSS Color Parser +### Unreleased (minor) + +- Add support for analogous set in color interpolations + ### 4.0.2 _February 21, 2026_ diff --git a/packages/css-color-parser/dist/index.mjs b/packages/css-color-parser/dist/index.mjs index b7be61cbf6..95a76b1a76 100644 --- a/packages/css-color-parser/dist/index.mjs +++ b/packages/css-color-parser/dist/index.mjs @@ -1 +1 @@ -import{TokenType as e,NumberType as a,isTokenIdent as n,isTokenPercentage as r,isTokenNumber as o,isTokenDelim as t,isTokenNumeric as l,isTokenComma as s,isTokenDimension as u,isTokenHash as i}from"@csstools/css-tokenizer";import{XYZ_D50_to_XYZ_D65 as c,XYZ_D50_to_XYZ_D50 as h,XYZ_D50_to_OKLab as m,XYZ_D50_to_OKLCH as p,XYZ_D50_to_LCH as N,XYZ_D50_to_Lab as b,XYZ_D50_to_HWB as v,XYZ_D50_to_HSL as g,XYZ_D50_to_a98_RGB as f,XYZ_D50_to_ProPhoto as d,XYZ_D50_to_rec_2020 as y,XYZ_D50_to_lin_P3 as _,XYZ_D50_to_P3 as C,XYZ_D50_to_lin_sRGB as w,XYZ_D50_to_sRGB as x,XYZ_D65_to_XYZ_D50 as L,OKLCH_to_XYZ_D50 as H,LCH_to_XYZ_D50 as P,OKLab_to_XYZ_D50 as k,Lab_to_XYZ_D50 as S,HWB_to_XYZ_D50 as D,HSL_to_XYZ_D50 as M,ProPhoto_RGB_to_XYZ_D50 as F,a98_RGB_to_XYZ_D50 as z,rec_2020_to_XYZ_D50 as Z,lin_P3_to_XYZ_D50 as R,P3_to_XYZ_D50 as B,lin_sRGB_to_XYZ_D50 as V,sRGB_to_XYZ_D50 as T,namedColors as G,inGamut as A,clip as X,gam_sRGB as K,mapGamutRayTrace as Y,OKLCH_to_OKLab as I,OKLab_to_XYZ as O,XYZ_to_lin_sRGB as W,lin_sRGB_to_XYZ as E,XYZ_to_OKLab as U,OKLab_to_OKLCH as $,contrast_ratio_wcag_2_1 as j,gam_P3 as q,XYZ_to_lin_P3 as J,lin_P3_to_XYZ as Q}from"@csstools/color-helpers";import{isWhitespaceNode as ee,isCommentNode as ae,isTokenNode as ne,isFunctionNode as re,TokenNode as oe,isWhiteSpaceOrCommentNode as te,replaceComponentValues as le,FunctionNode as se,WhitespaceNode as ue}from"@csstools/css-parser-algorithms";import{mathFunctionNames as ie,calcFromComponentValues as ce}from"@csstools/css-calc";var he,me;function convertNaNToZero(e){return[Number.isNaN(e[0])?0:e[0],Number.isNaN(e[1])?0:e[1],Number.isNaN(e[2])?0:e[2]]}function colorData_to_XYZ_D50(e){switch(e.colorNotation){case he.HEX:case he.RGB:case he.sRGB:return{...e,colorNotation:he.XYZ_D50,channels:T(convertNaNToZero(e.channels))};case he.Linear_sRGB:return{...e,colorNotation:he.XYZ_D50,channels:V(convertNaNToZero(e.channels))};case he.Display_P3:return{...e,colorNotation:he.XYZ_D50,channels:B(convertNaNToZero(e.channels))};case he.Linear_Display_P3:return{...e,colorNotation:he.XYZ_D50,channels:R(convertNaNToZero(e.channels))};case he.Rec2020:return{...e,colorNotation:he.XYZ_D50,channels:Z(convertNaNToZero(e.channels))};case he.A98_RGB:return{...e,colorNotation:he.XYZ_D50,channels:z(convertNaNToZero(e.channels))};case he.ProPhoto_RGB:return{...e,colorNotation:he.XYZ_D50,channels:F(convertNaNToZero(e.channels))};case he.HSL:return{...e,colorNotation:he.XYZ_D50,channels:M(convertNaNToZero(e.channels))};case he.HWB:return{...e,colorNotation:he.XYZ_D50,channels:D(convertNaNToZero(e.channels))};case he.Lab:return{...e,colorNotation:he.XYZ_D50,channels:S(convertNaNToZero(e.channels))};case he.OKLab:return{...e,colorNotation:he.XYZ_D50,channels:k(convertNaNToZero(e.channels))};case he.LCH:return{...e,colorNotation:he.XYZ_D50,channels:P(convertNaNToZero(e.channels))};case he.OKLCH:return{...e,colorNotation:he.XYZ_D50,channels:H(convertNaNToZero(e.channels))};case he.XYZ_D50:return{...e,colorNotation:he.XYZ_D50,channels:h(convertNaNToZero(e.channels))};case he.XYZ_D65:return{...e,colorNotation:he.XYZ_D50,channels:L(convertNaNToZero(e.channels))};default:throw new Error("Unsupported color notation")}}!function(e){e.A98_RGB="a98-rgb",e.Display_P3="display-p3",e.Linear_Display_P3="display-p3-linear",e.HEX="hex",e.HSL="hsl",e.HWB="hwb",e.LCH="lch",e.Lab="lab",e.Linear_sRGB="srgb-linear",e.OKLCH="oklch",e.OKLab="oklab",e.ProPhoto_RGB="prophoto-rgb",e.RGB="rgb",e.sRGB="srgb",e.Rec2020="rec2020",e.XYZ_D50="xyz-d50",e.XYZ_D65="xyz-d65"}(he||(he={})),function(e){e.ColorKeyword="color-keyword",e.HasAlpha="has-alpha",e.HasDimensionValues="has-dimension-values",e.HasNoneKeywords="has-none-keywords",e.HasNumberValues="has-number-values",e.HasPercentageAlpha="has-percentage-alpha",e.HasPercentageValues="has-percentage-values",e.HasVariableAlpha="has-variable-alpha",e.Hex="hex",e.LegacyHSL="legacy-hsl",e.LegacyRGB="legacy-rgb",e.NamedColor="named-color",e.RelativeColorSyntax="relative-color-syntax",e.ColorMix="color-mix",e.ColorMixVariadic="color-mix-variadic",e.ContrastColor="contrast-color",e.RelativeAlphaSyntax="relative-alpha-syntax",e.Experimental="experimental"}(me||(me={}));const pe=new Set([he.A98_RGB,he.Display_P3,he.Linear_Display_P3,he.HEX,he.Linear_sRGB,he.ProPhoto_RGB,he.RGB,he.sRGB,he.Rec2020,he.XYZ_D50,he.XYZ_D65]);function colorDataTo(e,a){const n={...e};if(e.colorNotation!==a){const e=colorData_to_XYZ_D50(n);switch(a){case he.HEX:case he.RGB:n.colorNotation=he.RGB,n.channels=x(e.channels);break;case he.sRGB:n.colorNotation=he.sRGB,n.channels=x(e.channels);break;case he.Linear_sRGB:n.colorNotation=he.Linear_sRGB,n.channels=w(e.channels);break;case he.Display_P3:n.colorNotation=he.Display_P3,n.channels=C(e.channels);break;case he.Linear_Display_P3:n.colorNotation=he.Linear_Display_P3,n.channels=_(e.channels);break;case he.Rec2020:n.colorNotation=he.Rec2020,n.channels=y(e.channels);break;case he.ProPhoto_RGB:n.colorNotation=he.ProPhoto_RGB,n.channels=d(e.channels);break;case he.A98_RGB:n.colorNotation=he.A98_RGB,n.channels=f(e.channels);break;case he.HSL:n.colorNotation=he.HSL,n.channels=g(e.channels);break;case he.HWB:n.colorNotation=he.HWB,n.channels=v(e.channels);break;case he.Lab:n.colorNotation=he.Lab,n.channels=b(e.channels);break;case he.LCH:n.colorNotation=he.LCH,n.channels=N(e.channels);break;case he.OKLCH:n.colorNotation=he.OKLCH,n.channels=p(e.channels);break;case he.OKLab:n.colorNotation=he.OKLab,n.channels=m(e.channels);break;case he.XYZ_D50:n.colorNotation=he.XYZ_D50,n.channels=h(e.channels);break;case he.XYZ_D65:n.colorNotation=he.XYZ_D65,n.channels=c(e.channels);break;default:throw new Error("Unsupported color notation")}}else n.channels=convertNaNToZero(e.channels);if(a===e.colorNotation)n.channels=carryForwardMissingComponents(e.channels,[0,1,2],n.channels,[0,1,2]);else if(pe.has(a)&&pe.has(e.colorNotation))n.channels=carryForwardMissingComponents(e.channels,[0,1,2],n.channels,[0,1,2]);else switch(a){case he.HSL:switch(e.colorNotation){case he.HWB:n.channels=carryForwardMissingComponents(e.channels,[0],n.channels,[0]);break;case he.Lab:case he.OKLab:n.channels=carryForwardMissingComponents(e.channels,[2],n.channels,[0]);break;case he.LCH:case he.OKLCH:n.channels=carryForwardMissingComponents(e.channels,[0,1,2],n.channels,[2,1,0])}break;case he.HWB:switch(e.colorNotation){case he.HSL:n.channels=carryForwardMissingComponents(e.channels,[0],n.channels,[0]);break;case he.LCH:case he.OKLCH:n.channels=carryForwardMissingComponents(e.channels,[0],n.channels,[2])}break;case he.Lab:case he.OKLab:switch(e.colorNotation){case he.HSL:n.channels=carryForwardMissingComponents(e.channels,[0],n.channels,[2]);break;case he.Lab:case he.OKLab:n.channels=carryForwardMissingComponents(e.channels,[0,1,2],n.channels,[0,1,2]);break;case he.LCH:case he.OKLCH:n.channels=carryForwardMissingComponents(e.channels,[0],n.channels,[0])}break;case he.LCH:case he.OKLCH:switch(e.colorNotation){case he.HSL:n.channels=carryForwardMissingComponents(e.channels,[0,1,2],n.channels,[2,1,0]);break;case he.HWB:n.channels=carryForwardMissingComponents(e.channels,[0],n.channels,[2]);break;case he.Lab:case he.OKLab:n.channels=carryForwardMissingComponents(e.channels,[0],n.channels,[0]);break;case he.LCH:case he.OKLCH:n.channels=carryForwardMissingComponents(e.channels,[0,1,2],n.channels,[0,1,2])}}return n.channels=convertPowerlessComponentsToMissingComponents(n.channels,a),n}function convertPowerlessComponentsToMissingComponents(e,a){const n=[...e];switch(a){case he.HSL:!Number.isNaN(n[1])&&reducePrecision(n[1],4)<=0&&(n[0]=Number.NaN);break;case he.HWB:Math.max(0,reducePrecision(n[1],4))+Math.max(0,reducePrecision(n[2],4))>=100&&(n[0]=Number.NaN);break;case he.LCH:!Number.isNaN(n[1])&&reducePrecision(n[1],4)<=0&&(n[2]=Number.NaN);break;case he.OKLCH:!Number.isNaN(n[1])&&reducePrecision(n[1],6)<=0&&(n[2]=Number.NaN)}return n}function convertPowerlessComponentsToZeroValuesForDisplay(e,a){const n=[...e];switch(a){case he.HSL:(reducePrecision(n[2])<=0||reducePrecision(n[2])>=100)&&(n[0]=Number.NaN,n[1]=Number.NaN),reducePrecision(n[1])<=0&&(n[0]=Number.NaN);break;case he.HWB:Math.max(0,reducePrecision(n[1]))+Math.max(0,reducePrecision(n[2]))>=100&&(n[0]=Number.NaN);break;case he.Lab:(reducePrecision(n[0])<=0||reducePrecision(n[0])>=100)&&(n[1]=Number.NaN,n[2]=Number.NaN);break;case he.LCH:reducePrecision(n[1])<=0&&(n[2]=Number.NaN),(reducePrecision(n[0])<=0||reducePrecision(n[0])>=100)&&(n[1]=Number.NaN,n[2]=Number.NaN);break;case he.OKLab:(reducePrecision(n[0])<=0||reducePrecision(n[0])>=1)&&(n[1]=Number.NaN,n[2]=Number.NaN);break;case he.OKLCH:reducePrecision(n[1])<=0&&(n[2]=Number.NaN),(reducePrecision(n[0])<=0||reducePrecision(n[0])>=1)&&(n[1]=Number.NaN,n[2]=Number.NaN)}return n}function carryForwardMissingComponents(e,a,n,r){const o=[...n];for(const n of a)Number.isNaN(e[a[n]])&&(o[r[n]]=Number.NaN);return o}function normalizeRelativeColorDataChannels(e){const a=new Map;switch(e.colorNotation){case he.RGB:case he.HEX:a.set("r",dummyNumberToken(255*e.channels[0])),a.set("g",dummyNumberToken(255*e.channels[1])),a.set("b",dummyNumberToken(255*e.channels[2])),"number"==typeof e.alpha&&a.set("alpha",dummyNumberToken(e.alpha));break;case he.HSL:a.set("h",dummyNumberToken(e.channels[0])),a.set("s",dummyNumberToken(e.channels[1])),a.set("l",dummyNumberToken(e.channels[2])),"number"==typeof e.alpha&&a.set("alpha",dummyNumberToken(e.alpha));break;case he.HWB:a.set("h",dummyNumberToken(e.channels[0])),a.set("w",dummyNumberToken(e.channels[1])),a.set("b",dummyNumberToken(e.channels[2])),"number"==typeof e.alpha&&a.set("alpha",dummyNumberToken(e.alpha));break;case he.Lab:case he.OKLab:a.set("l",dummyNumberToken(e.channels[0])),a.set("a",dummyNumberToken(e.channels[1])),a.set("b",dummyNumberToken(e.channels[2])),"number"==typeof e.alpha&&a.set("alpha",dummyNumberToken(e.alpha));break;case he.LCH:case he.OKLCH:a.set("l",dummyNumberToken(e.channels[0])),a.set("c",dummyNumberToken(e.channels[1])),a.set("h",dummyNumberToken(e.channels[2])),"number"==typeof e.alpha&&a.set("alpha",dummyNumberToken(e.alpha));break;case he.sRGB:case he.A98_RGB:case he.Display_P3:case he.Linear_Display_P3:case he.Rec2020:case he.Linear_sRGB:case he.ProPhoto_RGB:a.set("r",dummyNumberToken(e.channels[0])),a.set("g",dummyNumberToken(e.channels[1])),a.set("b",dummyNumberToken(e.channels[2])),"number"==typeof e.alpha&&a.set("alpha",dummyNumberToken(e.alpha));break;case he.XYZ_D50:case he.XYZ_D65:a.set("x",dummyNumberToken(e.channels[0])),a.set("y",dummyNumberToken(e.channels[1])),a.set("z",dummyNumberToken(e.channels[2])),"number"==typeof e.alpha&&a.set("alpha",dummyNumberToken(e.alpha))}return a}function noneToZeroInRelativeColorDataChannels(e){const a=new Map(e);for(const[n,r]of e)Number.isNaN(r[4].value)&&a.set(n,dummyNumberToken(0));return a}function dummyNumberToken(n){return Number.isNaN(n)?[e.Number,"none",-1,-1,{value:Number.NaN,type:a.Number}]:[e.Number,n.toString(),-1,-1,{value:n,type:a.Number}]}function reducePrecision(e,a=7){if(Number.isNaN(e))return 0;const n=Math.pow(10,a);return Math.round(e*n)/n}function colorDataFitsRGB_Gamut(e){const a={...e,channels:[...e.channels]};a.channels=convertPowerlessComponentsToZeroValuesForDisplay(a.channels,a.colorNotation);return!colorDataTo(a,he.RGB).channels.find(e=>e<-1e-5||e>1.00001)}function colorDataFitsDisplayP3_Gamut(e){const a={...e,channels:[...e.channels]};a.channels=convertPowerlessComponentsToZeroValuesForDisplay(a.channels,a.colorNotation);return!colorDataTo(a,he.Display_P3).channels.find(e=>e<-1e-5||e>1.00001)}function normalize(e,a,n,r){return Math.min(Math.max(e/a,n),r)}const Ne=/[A-Z]/g;function toLowerCaseAZ(e){return e.replace(Ne,e=>String.fromCharCode(e.charCodeAt(0)+32))}function normalize_Color_ChannelValues(t,l,s){if(n(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:a.Number}];if(r(t)){3!==l&&s.syntaxFlags.add(me.HasPercentageValues);let n=normalize(t[4].value,100,-2147483647,2147483647);return 3===l&&(n=normalize(t[4].value,100,0,1)),[e.Number,n.toString(),t[2],t[3],{value:n,type:a.Number}]}if(o(t)){3!==l&&s.syntaxFlags.add(me.HasNumberValues);let n=normalize(t[4].value,1,-2147483647,2147483647);return 3===l&&(n=normalize(t[4].value,1,0,1)),[e.Number,n.toString(),t[2],t[3],{value:n,type:a.Number}]}return!1}const be=new Set(["srgb","srgb-linear","display-p3","display-p3-linear","a98-rgb","prophoto-rgb","rec2020","xyz","xyz-d50","xyz-d65"]);function color$1(e,a){const r=[],s=[],u=[],i=[];let c,h,m=!1,p=!1;const N={colorNotation:he.sRGB,channels:[0,0,0],alpha:1,syntaxFlags:new Set([])};let b=r;for(let o=0;o=0){u=i.value[4].value;continue}}return!1}if(!t)return!1;n.push({color:t,percentage:u}),t=!1,u=!1}}if(!t)return!1;n.push({color:t,percentage:u});let i=0,c=0;for(let e=0;e100)return!1;i+=a}else c++}const h=Math.max(0,100-i);i=0;for(let e=0;e100)for(let e=0;e=2;){const e=n.pop(),a=n.pop();if(!e||!a)return!1;const o=colorMixRectangularPair(r,e.color,e.percentage,a.color,a.percentage);if(!o)return!1;n.push({color:o,percentage:e.percentage+a.percentage})}const o=n[0]?.color;return!!o&&(a.colors.some(e=>e.color.syntaxFlags.has(me.Experimental))&&o.syntaxFlags.add(me.Experimental),"number"==typeof o.alpha&&(o.alpha=o.alpha*a.alphaMultiplier,2!==a.colors.length&&o.syntaxFlags.add(me.ColorMixVariadic),o))}function colorMixRectangularPair(e,a,n,r,o){const t=n/(n+o);let l=a.alpha;if("number"!=typeof l)return!1;let s=r.alpha;if("number"!=typeof s)return!1;l=Number.isNaN(l)?s:l,s=Number.isNaN(s)?l:s;const u=colorDataTo(a,e).channels,i=colorDataTo(r,e).channels;u[0]=fillInMissingComponent(u[0],i[0]),i[0]=fillInMissingComponent(i[0],u[0]),u[1]=fillInMissingComponent(u[1],i[1]),i[1]=fillInMissingComponent(i[1],u[1]),u[2]=fillInMissingComponent(u[2],i[2]),i[2]=fillInMissingComponent(i[2],u[2]),u[0]=premultiply(u[0],l),u[1]=premultiply(u[1],l),u[2]=premultiply(u[2],l),i[0]=premultiply(i[0],s),i[1]=premultiply(i[1],s),i[2]=premultiply(i[2],s);const c=interpolate(l,s,t);return{colorNotation:e,channels:[un_premultiply(interpolate(u[0],i[0],t),c),un_premultiply(interpolate(u[1],i[1],t),c),un_premultiply(interpolate(u[2],i[2],t),c)],alpha:c,syntaxFlags:new Set([me.ColorMix])}}function colorMixPolar(e,a,n){if(!n||!n.colors.length)return!1;const r=n.colors.slice();let o;switch(r.reverse(),e){case"hsl":o=he.HSL;break;case"hwb":o=he.HWB;break;case"lch":o=he.LCH;break;case"oklch":o=he.OKLCH;break;default:return!1}if(1===r.length){const e=colorDataTo(r[0].color,o);return e.colorNotation=o,e.syntaxFlags.add(me.ColorMixVariadic),"number"!=typeof e.alpha?!1:(e.alpha=e.alpha*n.alphaMultiplier,e)}for(;r.length>=2;){const e=r.pop(),n=r.pop();if(!e||!n)return!1;const t=colorMixPolarPair(o,a,e.color,e.percentage,n.color,n.percentage);if(!t)return!1;r.push({color:t,percentage:e.percentage+n.percentage})}const t=r[0]?.color;return!!t&&(n.colors.some(e=>e.color.syntaxFlags.has(me.Experimental))&&t.syntaxFlags.add(me.Experimental),"number"==typeof t.alpha&&(t.alpha=t.alpha*n.alphaMultiplier,2!==n.colors.length&&t.syntaxFlags.add(me.ColorMixVariadic),t))}function colorMixPolarPair(e,a,n,r,o,t){const l=r/(r+t);let s=0,u=0,i=0,c=0,h=0,m=0,p=n.alpha;if("number"!=typeof p)return!1;let N=o.alpha;if("number"!=typeof N)return!1;p=Number.isNaN(p)?N:p,N=Number.isNaN(N)?p:N;const b=colorDataTo(n,e).channels,v=colorDataTo(o,e).channels;switch(e){case he.HSL:case he.HWB:s=b[0],u=v[0],i=b[1],c=v[1],h=b[2],m=v[2];break;case he.LCH:case he.OKLCH:i=b[0],c=v[0],h=b[1],m=v[1],s=b[2],u=v[2]}s=fillInMissingComponent(s,u),Number.isNaN(s)&&(s=0),u=fillInMissingComponent(u,s),Number.isNaN(u)&&(u=0),i=fillInMissingComponent(i,c),c=fillInMissingComponent(c,i),h=fillInMissingComponent(h,m),m=fillInMissingComponent(m,h);const g=u-s;switch(a){case"shorter":g>180?s+=360:g<-180&&(u+=360);break;case"longer":-1800?s+=360:u+=360);break;case"increasing":g<0&&(u+=360);break;case"decreasing":g>0&&(s+=360);break;default:throw new Error("Unknown hue interpolation method")}i=premultiply(i,p),h=premultiply(h,p),c=premultiply(c,N),m=premultiply(m,N);let f=[0,0,0];const d=interpolate(p,N,l);switch(e){case he.HSL:case he.HWB:f=[interpolate(s,u,l),un_premultiply(interpolate(i,c,l),d),un_premultiply(interpolate(h,m,l),d)];break;case he.LCH:case he.OKLCH:f=[un_premultiply(interpolate(i,c,l),d),un_premultiply(interpolate(h,m,l),d),interpolate(s,u,l)]}return{colorNotation:e,channels:f,alpha:d,syntaxFlags:new Set([me.ColorMix])}}function fillInMissingComponent(e,a){return Number.isNaN(e)?a:e}function interpolate(e,a,n){return e*n+a*(1-n)}function premultiply(e,a){return Number.isNaN(a)?e:Number.isNaN(e)?Number.NaN:e*a}function un_premultiply(e,a){return 0===a||Number.isNaN(a)?e:Number.isNaN(e)?Number.NaN:e/a}function hex(e){const a=toLowerCaseAZ(e[4].value);if(a.match(/[^a-f0-9]/))return!1;const n={colorNotation:he.HEX,channels:[0,0,0],alpha:1,syntaxFlags:new Set([me.Hex])},r=a.length;if(3===r){const e=a[0],r=a[1],o=a[2];return n.channels=[parseInt(e+e,16)/255,parseInt(r+r,16)/255,parseInt(o+o,16)/255],n}if(6===r){const e=a[0]+a[1],r=a[2]+a[3],o=a[4]+a[5];return n.channels=[parseInt(e,16)/255,parseInt(r,16)/255,parseInt(o,16)/255],n}if(4===r){const e=a[0],r=a[1],o=a[2],t=a[3];return n.channels=[parseInt(e+e,16)/255,parseInt(r+r,16)/255,parseInt(o+o,16)/255],n.alpha=parseInt(t+t,16)/255,n.syntaxFlags.add(me.HasAlpha),n}if(8===r){const e=a[0]+a[1],r=a[2]+a[3],o=a[4]+a[5],t=a[6]+a[7];return n.channels=[parseInt(e,16)/255,parseInt(r,16)/255,parseInt(o,16)/255],n.alpha=parseInt(t,16)/255,n.syntaxFlags.add(me.HasAlpha),n}return!1}function normalizeHue(n){if(o(n))return n[4].value=n[4].value%360,n[1]=n[4].value.toString(),n;if(u(n)){let r=n[4].value;switch(toLowerCaseAZ(n[4].unit)){case"deg":break;case"rad":r=180*n[4].value/Math.PI;break;case"grad":r=.9*n[4].value;break;case"turn":r=360*n[4].value;break;default:return!1}return r%=360,[e.Number,r.toString(),n[2],n[3],{value:r,type:a.Number}]}return!1}function normalize_legacy_HSL_ChannelValues(n,t,l){if(0===t){const e=normalizeHue(n);return!1!==e&&(u(n)&&l.syntaxFlags.add(me.HasDimensionValues),e)}if(r(n)){3===t?l.syntaxFlags.add(me.HasPercentageAlpha):l.syntaxFlags.add(me.HasPercentageValues);let r=normalize(n[4].value,1,0,100);return 3===t&&(r=normalize(n[4].value,100,0,1)),[e.Number,r.toString(),n[2],n[3],{value:r,type:a.Number}]}if(o(n)){if(3!==t)return!1;let r=normalize(n[4].value,1,0,100);return 3===t&&(r=normalize(n[4].value,1,0,1)),[e.Number,r.toString(),n[2],n[3],{value:r,type:a.Number}]}return!1}function normalize_modern_HSL_ChannelValues(t,l,s){if(n(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:a.Number}];if(0===l){const e=normalizeHue(t);return!1!==e&&(u(t)&&s.syntaxFlags.add(me.HasDimensionValues),e)}if(r(t)){3===l?s.syntaxFlags.add(me.HasPercentageAlpha):s.syntaxFlags.add(me.HasPercentageValues);let n=t[4].value;return 3===l?n=normalize(t[4].value,100,0,1):1===l&&(n=normalize(t[4].value,1,0,2147483647)),[e.Number,n.toString(),t[2],t[3],{value:n,type:a.Number}]}if(o(t)){3!==l&&s.syntaxFlags.add(me.HasNumberValues);let n=t[4].value;return 3===l?n=normalize(t[4].value,1,0,1):1===l&&(n=normalize(t[4].value,1,0,2147483647)),[e.Number,n.toString(),t[2],t[3],{value:n,type:a.Number}]}return!1}function threeChannelLegacySyntax(e,a,n,r){const t=[],u=[],i=[],c=[],h={colorNotation:n,channels:[0,0,0],alpha:1,syntaxFlags:new Set(r)};let m=t;for(let a=0;ane(e)&&s(e.value))){const a=hslCommaSeparated(e);if(!1!==a)return a}{const n=hslSpaceSeparated(e,a);if(!1!==n)return n}return!1}function hslCommaSeparated(e){return threeChannelLegacySyntax(e,normalize_legacy_HSL_ChannelValues,he.HSL,[me.LegacyHSL])}function hslSpaceSeparated(e,a){return threeChannelSpaceSeparated(e,normalize_modern_HSL_ChannelValues,he.HSL,[],a)}function normalize_HWB_ChannelValues(t,l,s){if(n(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:a.Number}];if(0===l){const e=normalizeHue(t);return!1!==e&&(u(t)&&s.syntaxFlags.add(me.HasDimensionValues),e)}if(r(t)){3===l?s.syntaxFlags.add(me.HasPercentageAlpha):s.syntaxFlags.add(me.HasPercentageValues);let n=t[4].value;return 3===l&&(n=normalize(t[4].value,100,0,1)),[e.Number,n.toString(),t[2],t[3],{value:n,type:a.Number}]}if(o(t)){3!==l&&s.syntaxFlags.add(me.HasNumberValues);let n=t[4].value;return 3===l&&(n=normalize(t[4].value,1,0,1)),[e.Number,n.toString(),t[2],t[3],{value:n,type:a.Number}]}return!1}function normalize_Lab_ChannelValues(t,l,s){if(n(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:a.Number}];if(r(t)){3!==l&&s.syntaxFlags.add(me.HasPercentageValues);let n=normalize(t[4].value,1,0,100);return 1===l||2===l?n=normalize(t[4].value,.8,-2147483647,2147483647):3===l&&(n=normalize(t[4].value,100,0,1)),[e.Number,n.toString(),t[2],t[3],{value:n,type:a.Number}]}if(o(t)){3!==l&&s.syntaxFlags.add(me.HasNumberValues);let n=normalize(t[4].value,1,0,100);return 1===l||2===l?n=normalize(t[4].value,1,-2147483647,2147483647):3===l&&(n=normalize(t[4].value,1,0,1)),[e.Number,n.toString(),t[2],t[3],{value:n,type:a.Number}]}return!1}function lab(e,a){return threeChannelSpaceSeparated(e,normalize_Lab_ChannelValues,he.Lab,[],a)}function normalize_LCH_ChannelValues(t,l,s){if(n(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:a.Number}];if(2===l){const e=normalizeHue(t);return!1!==e&&(u(t)&&s.syntaxFlags.add(me.HasDimensionValues),e)}if(r(t)){3!==l&&s.syntaxFlags.add(me.HasPercentageValues);let n=normalize(t[4].value,1,0,100);return 1===l?n=normalize(t[4].value,100/150,0,2147483647):3===l&&(n=normalize(t[4].value,100,0,1)),[e.Number,n.toString(),t[2],t[3],{value:n,type:a.Number}]}if(o(t)){3!==l&&s.syntaxFlags.add(me.HasNumberValues);let n=normalize(t[4].value,1,0,100);return 1===l?n=normalize(t[4].value,1,0,2147483647):3===l&&(n=normalize(t[4].value,1,0,1)),[e.Number,n.toString(),t[2],t[3],{value:n,type:a.Number}]}return!1}function lch(e,a){return threeChannelSpaceSeparated(e,normalize_LCH_ChannelValues,he.LCH,[],a)}const de=new Map;for(const[e,a]of Object.entries(G))de.set(e,a);function namedColor(e){const a=de.get(toLowerCaseAZ(e));return!!a&&{colorNotation:he.RGB,channels:[a[0]/255,a[1]/255,a[2]/255],alpha:1,syntaxFlags:new Set([me.ColorKeyword,me.NamedColor])}}function normalize_OKLab_ChannelValues(t,l,s){if(n(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:a.Number}];if(r(t)){3!==l&&s.syntaxFlags.add(me.HasPercentageValues);let n=normalize(t[4].value,100,0,1);return 1===l||2===l?n=normalize(t[4].value,250,-2147483647,2147483647):3===l&&(n=normalize(t[4].value,100,0,1)),[e.Number,n.toString(),t[2],t[3],{value:n,type:a.Number}]}if(o(t)){3!==l&&s.syntaxFlags.add(me.HasNumberValues);let n=normalize(t[4].value,1,0,1);return 1===l||2===l?n=normalize(t[4].value,1,-2147483647,2147483647):3===l&&(n=normalize(t[4].value,1,0,1)),[e.Number,n.toString(),t[2],t[3],{value:n,type:a.Number}]}return!1}function oklab(e,a){return threeChannelSpaceSeparated(e,normalize_OKLab_ChannelValues,he.OKLab,[],a)}function normalize_OKLCH_ChannelValues(t,l,s){if(n(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:a.Number}];if(2===l){const e=normalizeHue(t);return!1!==e&&(u(t)&&s.syntaxFlags.add(me.HasDimensionValues),e)}if(r(t)){3!==l&&s.syntaxFlags.add(me.HasPercentageValues);let n=normalize(t[4].value,100,0,1);return 1===l?n=normalize(t[4].value,250,0,2147483647):3===l&&(n=normalize(t[4].value,100,0,1)),[e.Number,n.toString(),t[2],t[3],{value:n,type:a.Number}]}if(o(t)){3!==l&&s.syntaxFlags.add(me.HasNumberValues);let n=normalize(t[4].value,1,0,1);return 1===l?n=normalize(t[4].value,1,0,2147483647):3===l&&(n=normalize(t[4].value,1,0,1)),[e.Number,n.toString(),t[2],t[3],{value:n,type:a.Number}]}return!1}function oklch(e,a){return threeChannelSpaceSeparated(e,normalize_OKLCH_ChannelValues,he.OKLCH,[],a)}function normalize_legacy_sRGB_ChannelValues(n,t,l){if(r(n)){3===t?l.syntaxFlags.add(me.HasPercentageAlpha):l.syntaxFlags.add(me.HasPercentageValues);const r=normalize(n[4].value,100,0,1);return[e.Number,r.toString(),n[2],n[3],{value:r,type:a.Number}]}if(o(n)){3!==t&&l.syntaxFlags.add(me.HasNumberValues);let r=normalize(n[4].value,255,0,1);return 3===t&&(r=normalize(n[4].value,1,0,1)),[e.Number,r.toString(),n[2],n[3],{value:r,type:a.Number}]}return!1}function normalize_modern_sRGB_ChannelValues(t,l,s){if(n(t)&&"none"===t[4].value.toLowerCase())return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:a.Number}];if(r(t)){3!==l&&s.syntaxFlags.add(me.HasPercentageValues);let n=normalize(t[4].value,100,-2147483647,2147483647);return 3===l&&(n=normalize(t[4].value,100,0,1)),[e.Number,n.toString(),t[2],t[3],{value:n,type:a.Number}]}if(o(t)){3!==l&&s.syntaxFlags.add(me.HasNumberValues);let n=normalize(t[4].value,255,-2147483647,2147483647);return 3===l&&(n=normalize(t[4].value,1,0,1)),[e.Number,n.toString(),t[2],t[3],{value:n,type:a.Number}]}return!1}function rgb(e,a){if(e.value.some(e=>ne(e)&&s(e.value))){const a=rgbCommaSeparated(e);if(!1!==a)return(!a.syntaxFlags.has(me.HasNumberValues)||!a.syntaxFlags.has(me.HasPercentageValues))&&a}else{const n=rgbSpaceSeparated(e,a);if(!1!==n)return n}return!1}function rgbCommaSeparated(e){return threeChannelLegacySyntax(e,normalize_legacy_sRGB_ChannelValues,he.RGB,[me.LegacyRGB])}function rgbSpaceSeparated(e,a){return threeChannelSpaceSeparated(e,normalize_modern_sRGB_ChannelValues,he.RGB,[],a)}function XYZ_D50_to_sRGB_Gamut(e){const a=x(e);if(A(a))return X(a);let n=e;return n=p(n),n[0]<1e-6&&(n=[0,0,0]),n[0]>.999999&&(n=[1,0,0]),K(Y(n,oklch_to_lin_srgb,lin_srgb_to_oklch))}function oklch_to_lin_srgb(e){return e=I(e),e=O(e),W(e)}function lin_srgb_to_oklch(e){return e=E(e),e=U(e),$(e)}function contrastColor(e,a){let n=!1;for(let r=0;rt?[1,1,1]:[0,0,0],r}function alpha(e,a){let r,s,u=!1,i=!1,c=!1;const h={colorNotation:he.sRGB,channels:[0,0,0],alpha:1,syntaxFlags:new Set([])};for(let m=0;m{if(ne(e)&&n(e.value)&&"alpha"===toLowerCaseAZ(e.value[4].value)&&r&&r.has("alpha"))return new oe(r.get("alpha"))});h.alpha=e[0][0],i=!0;continue}return!1}if(c)return!1;for(;ee(e.value[m+1])||ae(e.value[m+1]);)m++;if(m++,p=e.value[m],c=a(p),!1===c)return!1;r=normalizeRelativeColorDataChannels(c),s=noneToZeroInRelativeColorDataChannels(r),h.syntaxFlags=new Set(c.syntaxFlags),h.syntaxFlags.add(me.RelativeAlphaSyntax),h.channels=[...c.channels],h.colorNotation=c.colorNotation,h.alpha=c.alpha}}return!!r&&h}function XYZ_D50_to_P3_Gamut(e){const a=C(e);if(A(a))return X(a);let n=e;return n=p(n),n[0]<1e-6&&(n=[0,0,0]),n[0]>.999999&&(n=[1,0,0]),q(Y(n,oklch_to_lin_p3,lin_p3_to_oklch))}function oklch_to_lin_p3(e){return e=I(e),e=O(e),J(e)}function lin_p3_to_oklch(e){return e=Q(e),e=U(e),$(e)}function toPrecision(e,a=7){e=+e,a=+a;const n=(Math.floor(Math.abs(e))+"").length;if(a>n)return+e.toFixed(a-n);{const r=10**(n-a);return Math.round(e/r)*r}}function serializeWithAlpha(n,r,o,t){const l=[e.CloseParen,")",-1,-1,void 0];if("number"==typeof n.alpha){const s=Math.min(1,Math.max(0,toPrecision(Number.isNaN(n.alpha)?0:n.alpha)));return 1===toPrecision(s,4)?new se(r,l,t):new se(r,l,[...t,new ue([o]),new oe([e.Delim,"/",-1,-1,{value:"/"}]),new ue([o]),new oe([e.Number,toPrecision(s,4).toString(),-1,-1,{value:n.alpha,type:a.Integer}])])}return new se(r,l,[...t,new ue([o]),new oe([e.Delim,"/",-1,-1,{value:"/"}]),new ue([o]),n.alpha])}function serializeP3(n,r=!0){n.channels=convertPowerlessComponentsToZeroValuesForDisplay(n.channels,n.colorNotation);let o=n.channels.map(e=>Number.isNaN(e)?0:e);r?o=XYZ_D50_to_P3_Gamut(colorData_to_XYZ_D50(n).channels):n.colorNotation!==he.Display_P3&&(o=C(colorData_to_XYZ_D50(n).channels));const t=r?Math.min(1,Math.max(0,toPrecision(o[0],6))):toPrecision(o[0],6),l=r?Math.min(1,Math.max(0,toPrecision(o[1],6))):toPrecision(o[1],6),s=r?Math.min(1,Math.max(0,toPrecision(o[2],6))):toPrecision(o[2],6),u=[e.Function,"color(",-1,-1,{value:"color"}],i=[e.Whitespace," ",-1,-1,void 0];return serializeWithAlpha(n,u,i,[new oe([e.Ident,"display-p3",-1,-1,{value:"display-p3"}]),new ue([i]),new oe([e.Number,t.toString(),-1,-1,{value:o[0],type:a.Number}]),new ue([i]),new oe([e.Number,l.toString(),-1,-1,{value:o[1],type:a.Number}]),new ue([i]),new oe([e.Number,s.toString(),-1,-1,{value:o[2],type:a.Number}])])}function serializeRGB(n,r=!0){let o;n.channels=convertPowerlessComponentsToZeroValuesForDisplay(n.channels,n.colorNotation),o=r?XYZ_D50_to_sRGB_Gamut(colorData_to_XYZ_D50(n).channels):x(colorData_to_XYZ_D50(n).channels);const t=Math.min(255,Math.max(0,Math.round(255*toPrecision(o[0])))),l=Math.min(255,Math.max(0,Math.round(255*toPrecision(o[1])))),s=Math.min(255,Math.max(0,Math.round(255*toPrecision(o[2])))),u=[e.CloseParen,")",-1,-1,void 0],i=[e.Whitespace," ",-1,-1,void 0],c=[e.Comma,",",-1,-1,void 0],h=[new oe([e.Number,t.toString(),-1,-1,{value:Math.min(255,255*Math.max(0,o[0])),type:a.Integer}]),new oe(c),new ue([i]),new oe([e.Number,l.toString(),-1,-1,{value:Math.min(255,255*Math.max(0,o[1])),type:a.Integer}]),new oe(c),new ue([i]),new oe([e.Number,s.toString(),-1,-1,{value:Math.min(255,255*Math.max(0,o[2])),type:a.Integer}])];if("number"==typeof n.alpha){const r=Math.min(1,Math.max(0,toPrecision(Number.isNaN(n.alpha)?0:n.alpha)));return 1===toPrecision(r,4)?new se([e.Function,"rgb(",-1,-1,{value:"rgb"}],u,h):new se([e.Function,"rgba(",-1,-1,{value:"rgba"}],u,[...h,new oe(c),new ue([i]),new oe([e.Number,toPrecision(r,4).toString(),-1,-1,{value:n.alpha,type:a.Number}])])}return new se([e.Function,"rgba(",-1,-1,{value:"rgba"}],u,[...h,new oe(c),new ue([i]),n.alpha])}function serializeHSL(n,r=!0){let o;n.channels=convertPowerlessComponentsToZeroValuesForDisplay(n.channels,n.colorNotation),o=g(r?T(XYZ_D50_to_sRGB_Gamut(colorData_to_XYZ_D50(n).channels)):colorData_to_XYZ_D50(n).channels),o=o.map(e=>Number.isNaN(e)?0:e);const t=Math.min(360,Math.max(0,Math.round(toPrecision(o[0])))),l=Math.min(100,Math.max(0,Math.round(toPrecision(o[1])))),s=Math.min(100,Math.max(0,Math.round(toPrecision(o[2])))),u=[e.CloseParen,")",-1,-1,void 0],i=[e.Whitespace," ",-1,-1,void 0],c=[e.Comma,",",-1,-1,void 0],h=[new oe([e.Number,t.toString(),-1,-1,{value:o[0],type:a.Integer}]),new oe(c),new ue([i]),new oe([e.Percentage,l.toString()+"%",-1,-1,{value:o[1]}]),new oe(c),new ue([i]),new oe([e.Percentage,s.toString()+"%",-1,-1,{value:o[2]}])];if("number"==typeof n.alpha){const r=Math.min(1,Math.max(0,toPrecision(Number.isNaN(n.alpha)?0:n.alpha)));return 1===toPrecision(r,4)?new se([e.Function,"hsl(",-1,-1,{value:"hsl"}],u,h):new se([e.Function,"hsla(",-1,-1,{value:"hsla"}],u,[...h,new oe(c),new ue([i]),new oe([e.Number,toPrecision(r,4).toString(),-1,-1,{value:n.alpha,type:a.Number}])])}return new se([e.Function,"hsla(",-1,-1,{value:"hsla"}],u,[...h,new oe(c),new ue([i]),n.alpha])}function serializeOKLCH(n){n.channels=convertPowerlessComponentsToZeroValuesForDisplay(n.channels,n.colorNotation);let r=n.channels.map(e=>Number.isNaN(e)?0:e);n.colorNotation!==he.OKLCH&&(r=p(colorData_to_XYZ_D50(n).channels));const o=toPrecision(r[0],6),t=toPrecision(r[1],6),l=toPrecision(r[2],6),s=[e.Function,"oklch(",-1,-1,{value:"oklch"}],u=[e.Whitespace," ",-1,-1,void 0];return serializeWithAlpha(n,s,u,[new oe([e.Number,o.toString(),-1,-1,{value:r[0],type:a.Number}]),new ue([u]),new oe([e.Number,t.toString(),-1,-1,{value:r[1],type:a.Number}]),new ue([u]),new oe([e.Number,l.toString(),-1,-1,{value:r[2],type:a.Number}])])}function color(e){if(re(e)){switch(toLowerCaseAZ(e.getName())){case"rgb":case"rgba":return rgb(e,color);case"hsl":case"hsla":return hsl(e,color);case"hwb":return a=color,threeChannelSpaceSeparated(e,normalize_HWB_ChannelValues,he.HWB,[],a);case"lab":return lab(e,color);case"lch":return lch(e,color);case"oklab":return oklab(e,color);case"oklch":return oklch(e,color);case"color":return color$1(e,color);case"color-mix":return colorMix(e,color);case"contrast-color":return contrastColor(e,color);case"alpha":return alpha(e,color)}}var a;if(ne(e)){if(i(e.value))return hex(e.value);if(n(e.value)){const a=namedColor(e.value[4].value);return!1!==a?a:"transparent"===toLowerCaseAZ(e.value[4].value)&&{colorNotation:he.RGB,channels:[0,0,0],alpha:0,syntaxFlags:new Set([me.ColorKeyword])}}}return!1}export{he as ColorNotation,me as SyntaxFlag,color,colorDataFitsDisplayP3_Gamut,colorDataFitsRGB_Gamut,serializeHSL,serializeOKLCH,serializeP3,serializeRGB}; +import{TokenType as e,NumberType as a,isTokenIdent as n,isTokenPercentage as r,isTokenNumber as o,isTokenDelim as l,isTokenNumeric as t,isTokenComma as s,isTokenDimension as u,isTokenHash as i}from"@csstools/css-tokenizer";import{XYZ_D50_to_XYZ_D65 as c,XYZ_D50_to_XYZ_D50 as h,XYZ_D50_to_OKLab as m,XYZ_D50_to_OKLCH as p,XYZ_D50_to_LCH as N,XYZ_D50_to_Lab as b,XYZ_D50_to_HWB as g,XYZ_D50_to_HSL as v,XYZ_D50_to_a98_RGB as f,XYZ_D50_to_ProPhoto as d,XYZ_D50_to_rec_2020 as y,XYZ_D50_to_lin_P3 as _,XYZ_D50_to_P3 as C,XYZ_D50_to_lin_sRGB as w,XYZ_D50_to_sRGB as x,XYZ_D65_to_XYZ_D50 as L,OKLCH_to_XYZ_D50 as H,LCH_to_XYZ_D50 as P,OKLab_to_XYZ_D50 as k,Lab_to_XYZ_D50 as S,HWB_to_XYZ_D50 as M,HSL_to_XYZ_D50 as D,ProPhoto_RGB_to_XYZ_D50 as F,a98_RGB_to_XYZ_D50 as z,rec_2020_to_XYZ_D50 as Z,lin_P3_to_XYZ_D50 as R,P3_to_XYZ_D50 as B,lin_sRGB_to_XYZ_D50 as V,sRGB_to_XYZ_D50 as T,namedColors as G,inGamut as A,clip as X,gam_sRGB as K,mapGamutRayTrace as Y,OKLCH_to_OKLab as I,OKLab_to_XYZ as O,XYZ_to_lin_sRGB as W,lin_sRGB_to_XYZ as E,XYZ_to_OKLab as U,OKLab_to_OKLCH as $,contrast_ratio_wcag_2_1 as j,gam_P3 as q,XYZ_to_lin_P3 as J,lin_P3_to_XYZ as Q}from"@csstools/color-helpers";import{isWhitespaceNode as ee,isCommentNode as ae,isTokenNode as ne,isFunctionNode as re,TokenNode as oe,isWhiteSpaceOrCommentNode as le,replaceComponentValues as te,FunctionNode as se,WhitespaceNode as ue}from"@csstools/css-parser-algorithms";import{mathFunctionNames as ie,calcFromComponentValues as ce}from"@csstools/css-calc";var he,me;function convertNaNToZero(e){return[Number.isNaN(e[0])?0:e[0],Number.isNaN(e[1])?0:e[1],Number.isNaN(e[2])?0:e[2]]}function colorData_to_XYZ_D50(e){switch(e.colorNotation){case he.HEX:case he.RGB:case he.sRGB:return{...e,colorNotation:he.XYZ_D50,channels:T(convertNaNToZero(e.channels))};case he.Linear_sRGB:return{...e,colorNotation:he.XYZ_D50,channels:V(convertNaNToZero(e.channels))};case he.Display_P3:return{...e,colorNotation:he.XYZ_D50,channels:B(convertNaNToZero(e.channels))};case he.Linear_Display_P3:return{...e,colorNotation:he.XYZ_D50,channels:R(convertNaNToZero(e.channels))};case he.Rec2020:return{...e,colorNotation:he.XYZ_D50,channels:Z(convertNaNToZero(e.channels))};case he.A98_RGB:return{...e,colorNotation:he.XYZ_D50,channels:z(convertNaNToZero(e.channels))};case he.ProPhoto_RGB:return{...e,colorNotation:he.XYZ_D50,channels:F(convertNaNToZero(e.channels))};case he.HSL:return{...e,colorNotation:he.XYZ_D50,channels:D(convertNaNToZero(e.channels))};case he.HWB:return{...e,colorNotation:he.XYZ_D50,channels:M(convertNaNToZero(e.channels))};case he.Lab:return{...e,colorNotation:he.XYZ_D50,channels:S(convertNaNToZero(e.channels))};case he.OKLab:return{...e,colorNotation:he.XYZ_D50,channels:k(convertNaNToZero(e.channels))};case he.LCH:return{...e,colorNotation:he.XYZ_D50,channels:P(convertNaNToZero(e.channels))};case he.OKLCH:return{...e,colorNotation:he.XYZ_D50,channels:H(convertNaNToZero(e.channels))};case he.XYZ_D50:return{...e,colorNotation:he.XYZ_D50,channels:h(convertNaNToZero(e.channels))};case he.XYZ_D65:return{...e,colorNotation:he.XYZ_D50,channels:L(convertNaNToZero(e.channels))};default:throw new Error("Unsupported color notation")}}!function(e){e.A98_RGB="a98-rgb",e.Display_P3="display-p3",e.Linear_Display_P3="display-p3-linear",e.HEX="hex",e.HSL="hsl",e.HWB="hwb",e.LCH="lch",e.Lab="lab",e.Linear_sRGB="srgb-linear",e.OKLCH="oklch",e.OKLab="oklab",e.ProPhoto_RGB="prophoto-rgb",e.RGB="rgb",e.sRGB="srgb",e.Rec2020="rec2020",e.XYZ_D50="xyz-d50",e.XYZ_D65="xyz-d65"}(he||(he={})),function(e){e.ColorKeyword="color-keyword",e.HasAlpha="has-alpha",e.HasDimensionValues="has-dimension-values",e.HasNoneKeywords="has-none-keywords",e.HasNumberValues="has-number-values",e.HasPercentageAlpha="has-percentage-alpha",e.HasPercentageValues="has-percentage-values",e.HasVariableAlpha="has-variable-alpha",e.Hex="hex",e.LegacyHSL="legacy-hsl",e.LegacyRGB="legacy-rgb",e.NamedColor="named-color",e.RelativeColorSyntax="relative-color-syntax",e.ColorMix="color-mix",e.ColorMixVariadic="color-mix-variadic",e.ContrastColor="contrast-color",e.RelativeAlphaSyntax="relative-alpha-syntax",e.Experimental="experimental"}(me||(me={}));const pe=new Set([he.A98_RGB,he.Display_P3,he.Linear_Display_P3,he.HEX,he.Linear_sRGB,he.ProPhoto_RGB,he.RGB,he.sRGB,he.Rec2020,he.XYZ_D50,he.XYZ_D65]);function colorDataTo(e,a){const n={...e};if(e.colorNotation!==a){const e=colorData_to_XYZ_D50(n);switch(a){case he.HEX:case he.RGB:n.colorNotation=he.RGB,n.channels=x(e.channels);break;case he.sRGB:n.colorNotation=he.sRGB,n.channels=x(e.channels);break;case he.Linear_sRGB:n.colorNotation=he.Linear_sRGB,n.channels=w(e.channels);break;case he.Display_P3:n.colorNotation=he.Display_P3,n.channels=C(e.channels);break;case he.Linear_Display_P3:n.colorNotation=he.Linear_Display_P3,n.channels=_(e.channels);break;case he.Rec2020:n.colorNotation=he.Rec2020,n.channels=y(e.channels);break;case he.ProPhoto_RGB:n.colorNotation=he.ProPhoto_RGB,n.channels=d(e.channels);break;case he.A98_RGB:n.colorNotation=he.A98_RGB,n.channels=f(e.channels);break;case he.HSL:n.colorNotation=he.HSL,n.channels=v(e.channels);break;case he.HWB:n.colorNotation=he.HWB,n.channels=g(e.channels);break;case he.Lab:n.colorNotation=he.Lab,n.channels=b(e.channels);break;case he.LCH:n.colorNotation=he.LCH,n.channels=N(e.channels);break;case he.OKLCH:n.colorNotation=he.OKLCH,n.channels=p(e.channels);break;case he.OKLab:n.colorNotation=he.OKLab,n.channels=m(e.channels);break;case he.XYZ_D50:n.colorNotation=he.XYZ_D50,n.channels=h(e.channels);break;case he.XYZ_D65:n.colorNotation=he.XYZ_D65,n.channels=c(e.channels);break;default:throw new Error("Unsupported color notation")}}else n.channels=convertNaNToZero(e.channels);if(a===e.colorNotation)n.channels=carryForwardMissingComponents(e.channels,[0,1,2],[],n.channels,[0,1,2],[]);else if(pe.has(a)&&pe.has(e.colorNotation))n.channels=carryForwardMissingComponents(e.channels,[0,1,2],[],n.channels,[0,1,2],[]);else switch(a){case he.HSL:switch(e.colorNotation){case he.HWB:n.channels=carryForwardMissingComponents(e.channels,[0],[1,2],n.channels,[0],[1,2]);break;case he.Lab:case he.OKLab:n.channels=carryForwardMissingComponents(e.channels,[2],[0,1],n.channels,[0],[1,2]);break;case he.LCH:case he.OKLCH:n.channels=carryForwardMissingComponents(e.channels,[0,1,2],[],n.channels,[2,1,0],[]);break;default:n.channels=carryForwardMissingComponents(e.channels,[],[],n.channels,[],[])}break;case he.HWB:switch(e.colorNotation){case he.HSL:n.channels=carryForwardMissingComponents(e.channels,[0],[1,2],n.channels,[0],[1,2]);break;case he.LCH:case he.OKLCH:n.channels=carryForwardMissingComponents(e.channels,[0],[1,2],n.channels,[2],[0,1]);break;default:n.channels=carryForwardMissingComponents(e.channels,[],[],n.channels,[],[])}break;case he.Lab:case he.OKLab:switch(e.colorNotation){case he.HSL:n.channels=carryForwardMissingComponents(e.channels,[0],[1,2],n.channels,[2],[0,1]);break;case he.Lab:case he.OKLab:n.channels=carryForwardMissingComponents(e.channels,[0,1,2],[],n.channels,[0,1,2],[]);break;case he.LCH:case he.OKLCH:n.channels=carryForwardMissingComponents(e.channels,[0],[1,2],n.channels,[0],[1,2]);break;default:n.channels=carryForwardMissingComponents(e.channels,[],[],n.channels,[],[])}break;case he.LCH:case he.OKLCH:switch(e.colorNotation){case he.HSL:n.channels=carryForwardMissingComponents(e.channels,[0,1,2],[],n.channels,[2,1,0],[]);break;case he.HWB:n.channels=carryForwardMissingComponents(e.channels,[0],[1,2],n.channels,[2],[0,1]);break;case he.Lab:case he.OKLab:n.channels=carryForwardMissingComponents(e.channels,[0],[1,2],n.channels,[0],[1,2]);break;case he.LCH:case he.OKLCH:n.channels=carryForwardMissingComponents(e.channels,[0,1,2],[],n.channels,[0,1,2],[]);break;default:n.channels=carryForwardMissingComponents(e.channels,[],[],n.channels,[],[])}break;default:n.channels=carryForwardMissingComponents(e.channels,[],[],n.channels,[],[])}return n.channels=convertPowerlessComponentsToMissingComponents(n.channels,a),n}function convertPowerlessComponentsToMissingComponents(e,a){const n=[...e];switch(a){case he.HSL:!Number.isNaN(n[1])&&reducePrecision(n[1],4)<=0&&(n[0]=Number.NaN);break;case he.HWB:Math.max(0,reducePrecision(n[1],4))+Math.max(0,reducePrecision(n[2],4))>=100&&(n[0]=Number.NaN);break;case he.LCH:!Number.isNaN(n[1])&&reducePrecision(n[1],4)<=0&&(n[2]=Number.NaN);break;case he.OKLCH:!Number.isNaN(n[1])&&reducePrecision(n[1],6)<=0&&(n[2]=Number.NaN)}return n}function convertPowerlessComponentsToZeroValuesForDisplay(e,a){const n=[...e];switch(a){case he.HSL:(reducePrecision(n[2])<=0||reducePrecision(n[2])>=100)&&(n[0]=Number.NaN,n[1]=Number.NaN),reducePrecision(n[1])<=0&&(n[0]=Number.NaN);break;case he.HWB:Math.max(0,reducePrecision(n[1]))+Math.max(0,reducePrecision(n[2]))>=100&&(n[0]=Number.NaN);break;case he.Lab:(reducePrecision(n[0])<=0||reducePrecision(n[0])>=100)&&(n[1]=Number.NaN,n[2]=Number.NaN);break;case he.LCH:reducePrecision(n[1])<=0&&(n[2]=Number.NaN),(reducePrecision(n[0])<=0||reducePrecision(n[0])>=100)&&(n[1]=Number.NaN,n[2]=Number.NaN);break;case he.OKLab:(reducePrecision(n[0])<=0||reducePrecision(n[0])>=1)&&(n[1]=Number.NaN,n[2]=Number.NaN);break;case he.OKLCH:reducePrecision(n[1])<=0&&(n[2]=Number.NaN),(reducePrecision(n[0])<=0||reducePrecision(n[0])>=1)&&(n[1]=Number.NaN,n[2]=Number.NaN)}return n}function carryForwardMissingComponents(e,a,n,r,o,l){if(a.length<3&&e.every(Number.isNaN))return[Number.NaN,Number.NaN,Number.NaN];const t=[...r];for(let n=0;nNumber.isNaN(e[a])))for(let e=0;ee<-1e-5||e>1.00001)}function colorDataFitsDisplayP3_Gamut(e){const a={...e,channels:[...e.channels]};a.channels=convertPowerlessComponentsToZeroValuesForDisplay(a.channels,a.colorNotation);return!colorDataTo(a,he.Display_P3).channels.find(e=>e<-1e-5||e>1.00001)}function normalize(e,a,n,r){return Math.min(Math.max(e/a,n),r)}const Ne=/[A-Z]/g;function toLowerCaseAZ(e){return e.replace(Ne,e=>String.fromCharCode(e.charCodeAt(0)+32))}function normalize_Color_ChannelValues(l,t,s){if(n(l)&&"none"===toLowerCaseAZ(l[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",l[2],l[3],{value:Number.NaN,type:a.Number}];if(r(l)){3!==t&&s.syntaxFlags.add(me.HasPercentageValues);let n=normalize(l[4].value,100,-2147483647,2147483647);return 3===t&&(n=normalize(l[4].value,100,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}if(o(l)){3!==t&&s.syntaxFlags.add(me.HasNumberValues);let n=normalize(l[4].value,1,-2147483647,2147483647);return 3===t&&(n=normalize(l[4].value,1,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}return!1}const be=new Set(["srgb","srgb-linear","display-p3","display-p3-linear","a98-rgb","prophoto-rgb","rec2020","xyz","xyz-d50","xyz-d65"]);function color$1(e,a){const r=[],s=[],u=[],i=[];let c,h,m=!1,p=!1;const N={colorNotation:he.sRGB,channels:[0,0,0],alpha:1,syntaxFlags:new Set([])};let b=r;for(let o=0;o=0){u=i.value[4].value;continue}}return!1}if(!l)return!1;n.push({color:l,percentage:u}),l=!1,u=!1}}if(!l)return!1;n.push({color:l,percentage:u});let i=0,c=0;for(let e=0;e100)return!1;i+=a}else c++}const h=Math.max(0,100-i);i=0;for(let e=0;e100)for(let e=0;e=2;){const e=n.pop(),a=n.pop();if(!e||!a)return!1;const o=colorMixRectangularPair(r,e.color,e.percentage,a.color,a.percentage);if(!o)return!1;n.push({color:o,percentage:e.percentage+a.percentage})}const o=n[0]?.color;return!!o&&(a.colors.some(e=>e.color.syntaxFlags.has(me.Experimental))&&o.syntaxFlags.add(me.Experimental),"number"==typeof o.alpha&&(o.alpha=o.alpha*a.alphaMultiplier,2!==a.colors.length&&o.syntaxFlags.add(me.ColorMixVariadic),o))}function colorMixRectangularPair(e,a,n,r,o){const l=n/(n+o);let t=a.alpha;if("number"!=typeof t)return!1;let s=r.alpha;if("number"!=typeof s)return!1;t=Number.isNaN(t)?s:t,s=Number.isNaN(s)?t:s;const u=colorDataTo(a,e).channels,i=colorDataTo(r,e).channels;u[0]=fillInMissingComponent(u[0],i[0]),i[0]=fillInMissingComponent(i[0],u[0]),u[1]=fillInMissingComponent(u[1],i[1]),i[1]=fillInMissingComponent(i[1],u[1]),u[2]=fillInMissingComponent(u[2],i[2]),i[2]=fillInMissingComponent(i[2],u[2]),u[0]=premultiply(u[0],t),u[1]=premultiply(u[1],t),u[2]=premultiply(u[2],t),i[0]=premultiply(i[0],s),i[1]=premultiply(i[1],s),i[2]=premultiply(i[2],s);const c=interpolate(t,s,l);return{colorNotation:e,channels:[un_premultiply(interpolate(u[0],i[0],l),c),un_premultiply(interpolate(u[1],i[1],l),c),un_premultiply(interpolate(u[2],i[2],l),c)],alpha:c,syntaxFlags:new Set([me.ColorMix])}}function colorMixPolar(e,a,n){if(!n||!n.colors.length)return!1;const r=n.colors.slice();let o;switch(r.reverse(),e){case"hsl":o=he.HSL;break;case"hwb":o=he.HWB;break;case"lch":o=he.LCH;break;case"oklch":o=he.OKLCH;break;default:return!1}if(1===r.length){const e=colorDataTo(r[0].color,o);return e.colorNotation=o,e.syntaxFlags.add(me.ColorMixVariadic),"number"!=typeof e.alpha?!1:(e.alpha=e.alpha*n.alphaMultiplier,e)}for(;r.length>=2;){const e=r.pop(),n=r.pop();if(!e||!n)return!1;const l=colorMixPolarPair(o,a,e.color,e.percentage,n.color,n.percentage);if(!l)return!1;r.push({color:l,percentage:e.percentage+n.percentage})}const l=r[0]?.color;return!!l&&(n.colors.some(e=>e.color.syntaxFlags.has(me.Experimental))&&l.syntaxFlags.add(me.Experimental),"number"==typeof l.alpha&&(l.alpha=l.alpha*n.alphaMultiplier,2!==n.colors.length&&l.syntaxFlags.add(me.ColorMixVariadic),l))}function colorMixPolarPair(e,a,n,r,o,l){const t=r/(r+l);let s=0,u=0,i=0,c=0,h=0,m=0,p=n.alpha;if("number"!=typeof p)return!1;let N=o.alpha;if("number"!=typeof N)return!1;p=Number.isNaN(p)?N:p,N=Number.isNaN(N)?p:N;const b=colorDataTo(n,e).channels,g=colorDataTo(o,e).channels;switch(e){case he.HSL:case he.HWB:s=b[0],u=g[0],i=b[1],c=g[1],h=b[2],m=g[2];break;case he.LCH:case he.OKLCH:i=b[0],c=g[0],h=b[1],m=g[1],s=b[2],u=g[2]}s=fillInMissingComponent(s,u),Number.isNaN(s)&&(s=0),u=fillInMissingComponent(u,s),Number.isNaN(u)&&(u=0),i=fillInMissingComponent(i,c),c=fillInMissingComponent(c,i),h=fillInMissingComponent(h,m),m=fillInMissingComponent(m,h);const v=u-s;switch(a){case"shorter":v>180?s+=360:v<-180&&(u+=360);break;case"longer":-1800?s+=360:u+=360);break;case"increasing":v<0&&(u+=360);break;case"decreasing":v>0&&(s+=360);break;default:throw new Error("Unknown hue interpolation method")}i=premultiply(i,p),h=premultiply(h,p),c=premultiply(c,N),m=premultiply(m,N);let f=[0,0,0];const d=interpolate(p,N,t);switch(e){case he.HSL:case he.HWB:f=[interpolate(s,u,t),un_premultiply(interpolate(i,c,t),d),un_premultiply(interpolate(h,m,t),d)];break;case he.LCH:case he.OKLCH:f=[un_premultiply(interpolate(i,c,t),d),un_premultiply(interpolate(h,m,t),d),interpolate(s,u,t)]}return{colorNotation:e,channels:f,alpha:d,syntaxFlags:new Set([me.ColorMix])}}function fillInMissingComponent(e,a){return Number.isNaN(e)?a:e}function interpolate(e,a,n){return e*n+a*(1-n)}function premultiply(e,a){return Number.isNaN(a)?e:Number.isNaN(e)?Number.NaN:e*a}function un_premultiply(e,a){return 0===a||Number.isNaN(a)?e:Number.isNaN(e)?Number.NaN:e/a}function hex(e){const a=toLowerCaseAZ(e[4].value);if(a.match(/[^a-f0-9]/))return!1;const n={colorNotation:he.HEX,channels:[0,0,0],alpha:1,syntaxFlags:new Set([me.Hex])},r=a.length;if(3===r){const e=a[0],r=a[1],o=a[2];return n.channels=[parseInt(e+e,16)/255,parseInt(r+r,16)/255,parseInt(o+o,16)/255],n}if(6===r){const e=a[0]+a[1],r=a[2]+a[3],o=a[4]+a[5];return n.channels=[parseInt(e,16)/255,parseInt(r,16)/255,parseInt(o,16)/255],n}if(4===r){const e=a[0],r=a[1],o=a[2],l=a[3];return n.channels=[parseInt(e+e,16)/255,parseInt(r+r,16)/255,parseInt(o+o,16)/255],n.alpha=parseInt(l+l,16)/255,n.syntaxFlags.add(me.HasAlpha),n}if(8===r){const e=a[0]+a[1],r=a[2]+a[3],o=a[4]+a[5],l=a[6]+a[7];return n.channels=[parseInt(e,16)/255,parseInt(r,16)/255,parseInt(o,16)/255],n.alpha=parseInt(l,16)/255,n.syntaxFlags.add(me.HasAlpha),n}return!1}function normalizeHue(n){if(o(n))return n[4].value=n[4].value%360,n[1]=n[4].value.toString(),n;if(u(n)){let r=n[4].value;switch(toLowerCaseAZ(n[4].unit)){case"deg":break;case"rad":r=180*n[4].value/Math.PI;break;case"grad":r=.9*n[4].value;break;case"turn":r=360*n[4].value;break;default:return!1}return r%=360,[e.Number,r.toString(),n[2],n[3],{value:r,type:a.Number}]}return!1}function normalize_legacy_HSL_ChannelValues(n,l,t){if(0===l){const e=normalizeHue(n);return!1!==e&&(u(n)&&t.syntaxFlags.add(me.HasDimensionValues),e)}if(r(n)){3===l?t.syntaxFlags.add(me.HasPercentageAlpha):t.syntaxFlags.add(me.HasPercentageValues);let r=normalize(n[4].value,1,0,100);return 3===l&&(r=normalize(n[4].value,100,0,1)),[e.Number,r.toString(),n[2],n[3],{value:r,type:a.Number}]}if(o(n)){if(3!==l)return!1;let r=normalize(n[4].value,1,0,100);return 3===l&&(r=normalize(n[4].value,1,0,1)),[e.Number,r.toString(),n[2],n[3],{value:r,type:a.Number}]}return!1}function normalize_modern_HSL_ChannelValues(l,t,s){if(n(l)&&"none"===toLowerCaseAZ(l[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",l[2],l[3],{value:Number.NaN,type:a.Number}];if(0===t){const e=normalizeHue(l);return!1!==e&&(u(l)&&s.syntaxFlags.add(me.HasDimensionValues),e)}if(r(l)){3===t?s.syntaxFlags.add(me.HasPercentageAlpha):s.syntaxFlags.add(me.HasPercentageValues);let n=l[4].value;return 3===t?n=normalize(l[4].value,100,0,1):1===t&&(n=normalize(l[4].value,1,0,2147483647)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}if(o(l)){3!==t&&s.syntaxFlags.add(me.HasNumberValues);let n=l[4].value;return 3===t?n=normalize(l[4].value,1,0,1):1===t&&(n=normalize(l[4].value,1,0,2147483647)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}return!1}function threeChannelLegacySyntax(e,a,n,r){const l=[],u=[],i=[],c=[],h={colorNotation:n,channels:[0,0,0],alpha:1,syntaxFlags:new Set(r)};let m=l;for(let a=0;ane(e)&&s(e.value))){const a=hslCommaSeparated(e);if(!1!==a)return a}{const n=hslSpaceSeparated(e,a);if(!1!==n)return n}return!1}function hslCommaSeparated(e){return threeChannelLegacySyntax(e,normalize_legacy_HSL_ChannelValues,he.HSL,[me.LegacyHSL])}function hslSpaceSeparated(e,a){return threeChannelSpaceSeparated(e,normalize_modern_HSL_ChannelValues,he.HSL,[],a)}function normalize_HWB_ChannelValues(l,t,s){if(n(l)&&"none"===toLowerCaseAZ(l[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",l[2],l[3],{value:Number.NaN,type:a.Number}];if(0===t){const e=normalizeHue(l);return!1!==e&&(u(l)&&s.syntaxFlags.add(me.HasDimensionValues),e)}if(r(l)){3===t?s.syntaxFlags.add(me.HasPercentageAlpha):s.syntaxFlags.add(me.HasPercentageValues);let n=l[4].value;return 3===t&&(n=normalize(l[4].value,100,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}if(o(l)){3!==t&&s.syntaxFlags.add(me.HasNumberValues);let n=l[4].value;return 3===t&&(n=normalize(l[4].value,1,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}return!1}function normalize_Lab_ChannelValues(l,t,s){if(n(l)&&"none"===toLowerCaseAZ(l[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",l[2],l[3],{value:Number.NaN,type:a.Number}];if(r(l)){3!==t&&s.syntaxFlags.add(me.HasPercentageValues);let n=normalize(l[4].value,1,0,100);return 1===t||2===t?n=normalize(l[4].value,.8,-2147483647,2147483647):3===t&&(n=normalize(l[4].value,100,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}if(o(l)){3!==t&&s.syntaxFlags.add(me.HasNumberValues);let n=normalize(l[4].value,1,0,100);return 1===t||2===t?n=normalize(l[4].value,1,-2147483647,2147483647):3===t&&(n=normalize(l[4].value,1,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}return!1}function lab(e,a){return threeChannelSpaceSeparated(e,normalize_Lab_ChannelValues,he.Lab,[],a)}function normalize_LCH_ChannelValues(l,t,s){if(n(l)&&"none"===toLowerCaseAZ(l[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",l[2],l[3],{value:Number.NaN,type:a.Number}];if(2===t){const e=normalizeHue(l);return!1!==e&&(u(l)&&s.syntaxFlags.add(me.HasDimensionValues),e)}if(r(l)){3!==t&&s.syntaxFlags.add(me.HasPercentageValues);let n=normalize(l[4].value,1,0,100);return 1===t?n=normalize(l[4].value,100/150,0,2147483647):3===t&&(n=normalize(l[4].value,100,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}if(o(l)){3!==t&&s.syntaxFlags.add(me.HasNumberValues);let n=normalize(l[4].value,1,0,100);return 1===t?n=normalize(l[4].value,1,0,2147483647):3===t&&(n=normalize(l[4].value,1,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}return!1}function lch(e,a){return threeChannelSpaceSeparated(e,normalize_LCH_ChannelValues,he.LCH,[],a)}const de=new Map;for(const[e,a]of Object.entries(G))de.set(e,a);function namedColor(e){const a=de.get(toLowerCaseAZ(e));return!!a&&{colorNotation:he.RGB,channels:[a[0]/255,a[1]/255,a[2]/255],alpha:1,syntaxFlags:new Set([me.ColorKeyword,me.NamedColor])}}function normalize_OKLab_ChannelValues(l,t,s){if(n(l)&&"none"===toLowerCaseAZ(l[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",l[2],l[3],{value:Number.NaN,type:a.Number}];if(r(l)){3!==t&&s.syntaxFlags.add(me.HasPercentageValues);let n=normalize(l[4].value,100,0,1);return 1===t||2===t?n=normalize(l[4].value,250,-2147483647,2147483647):3===t&&(n=normalize(l[4].value,100,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}if(o(l)){3!==t&&s.syntaxFlags.add(me.HasNumberValues);let n=normalize(l[4].value,1,0,1);return 1===t||2===t?n=normalize(l[4].value,1,-2147483647,2147483647):3===t&&(n=normalize(l[4].value,1,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}return!1}function oklab(e,a){return threeChannelSpaceSeparated(e,normalize_OKLab_ChannelValues,he.OKLab,[],a)}function normalize_OKLCH_ChannelValues(l,t,s){if(n(l)&&"none"===toLowerCaseAZ(l[4].value))return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",l[2],l[3],{value:Number.NaN,type:a.Number}];if(2===t){const e=normalizeHue(l);return!1!==e&&(u(l)&&s.syntaxFlags.add(me.HasDimensionValues),e)}if(r(l)){3!==t&&s.syntaxFlags.add(me.HasPercentageValues);let n=normalize(l[4].value,100,0,1);return 1===t?n=normalize(l[4].value,250,0,2147483647):3===t&&(n=normalize(l[4].value,100,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}if(o(l)){3!==t&&s.syntaxFlags.add(me.HasNumberValues);let n=normalize(l[4].value,1,0,1);return 1===t?n=normalize(l[4].value,1,0,2147483647):3===t&&(n=normalize(l[4].value,1,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}return!1}function oklch(e,a){return threeChannelSpaceSeparated(e,normalize_OKLCH_ChannelValues,he.OKLCH,[],a)}function normalize_legacy_sRGB_ChannelValues(n,l,t){if(r(n)){3===l?t.syntaxFlags.add(me.HasPercentageAlpha):t.syntaxFlags.add(me.HasPercentageValues);const r=normalize(n[4].value,100,0,1);return[e.Number,r.toString(),n[2],n[3],{value:r,type:a.Number}]}if(o(n)){3!==l&&t.syntaxFlags.add(me.HasNumberValues);let r=normalize(n[4].value,255,0,1);return 3===l&&(r=normalize(n[4].value,1,0,1)),[e.Number,r.toString(),n[2],n[3],{value:r,type:a.Number}]}return!1}function normalize_modern_sRGB_ChannelValues(l,t,s){if(n(l)&&"none"===l[4].value.toLowerCase())return s.syntaxFlags.add(me.HasNoneKeywords),[e.Number,"none",l[2],l[3],{value:Number.NaN,type:a.Number}];if(r(l)){3!==t&&s.syntaxFlags.add(me.HasPercentageValues);let n=normalize(l[4].value,100,-2147483647,2147483647);return 3===t&&(n=normalize(l[4].value,100,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}if(o(l)){3!==t&&s.syntaxFlags.add(me.HasNumberValues);let n=normalize(l[4].value,255,-2147483647,2147483647);return 3===t&&(n=normalize(l[4].value,1,0,1)),[e.Number,n.toString(),l[2],l[3],{value:n,type:a.Number}]}return!1}function rgb(e,a){if(e.value.some(e=>ne(e)&&s(e.value))){const a=rgbCommaSeparated(e);if(!1!==a)return(!a.syntaxFlags.has(me.HasNumberValues)||!a.syntaxFlags.has(me.HasPercentageValues))&&a}else{const n=rgbSpaceSeparated(e,a);if(!1!==n)return n}return!1}function rgbCommaSeparated(e){return threeChannelLegacySyntax(e,normalize_legacy_sRGB_ChannelValues,he.RGB,[me.LegacyRGB])}function rgbSpaceSeparated(e,a){return threeChannelSpaceSeparated(e,normalize_modern_sRGB_ChannelValues,he.RGB,[],a)}function XYZ_D50_to_sRGB_Gamut(e){const a=x(e);if(A(a))return X(a);let n=e;return n=p(n),n[0]<1e-6&&(n=[0,0,0]),n[0]>.999999&&(n=[1,0,0]),K(Y(n,oklch_to_lin_srgb,lin_srgb_to_oklch))}function oklch_to_lin_srgb(e){return e=I(e),e=O(e),W(e)}function lin_srgb_to_oklch(e){return e=E(e),e=U(e),$(e)}function contrastColor(e,a){let n=!1;for(let r=0;rl?[1,1,1]:[0,0,0],r}function alpha(e,a){let r,s,u=!1,i=!1,c=!1;const h={colorNotation:he.sRGB,channels:[0,0,0],alpha:1,syntaxFlags:new Set([])};for(let m=0;m{if(ne(e)&&n(e.value)&&"alpha"===toLowerCaseAZ(e.value[4].value)&&r&&r.has("alpha"))return new oe(r.get("alpha"))});h.alpha=e[0][0],i=!0;continue}return!1}if(c)return!1;for(;ee(e.value[m+1])||ae(e.value[m+1]);)m++;if(m++,p=e.value[m],c=a(p),!1===c)return!1;r=normalizeRelativeColorDataChannels(c),s=noneToZeroInRelativeColorDataChannels(r),h.syntaxFlags=new Set(c.syntaxFlags),h.syntaxFlags.add(me.RelativeAlphaSyntax),h.channels=[...c.channels],h.colorNotation=c.colorNotation,h.alpha=c.alpha}}return!!r&&h}function XYZ_D50_to_P3_Gamut(e){const a=C(e);if(A(a))return X(a);let n=e;return n=p(n),n[0]<1e-6&&(n=[0,0,0]),n[0]>.999999&&(n=[1,0,0]),q(Y(n,oklch_to_lin_p3,lin_p3_to_oklch))}function oklch_to_lin_p3(e){return e=I(e),e=O(e),J(e)}function lin_p3_to_oklch(e){return e=Q(e),e=U(e),$(e)}function toPrecision(e,a=7){e=+e,a=+a;const n=(Math.floor(Math.abs(e))+"").length;if(a>n)return+e.toFixed(a-n);{const r=10**(n-a);return Math.round(e/r)*r}}function serializeWithAlpha(n,r,o,l){const t=[e.CloseParen,")",-1,-1,void 0];if("number"==typeof n.alpha){const s=Math.min(1,Math.max(0,toPrecision(Number.isNaN(n.alpha)?0:n.alpha)));return 1===toPrecision(s,4)?new se(r,t,l):new se(r,t,[...l,new ue([o]),new oe([e.Delim,"/",-1,-1,{value:"/"}]),new ue([o]),new oe([e.Number,toPrecision(s,4).toString(),-1,-1,{value:n.alpha,type:a.Integer}])])}return new se(r,t,[...l,new ue([o]),new oe([e.Delim,"/",-1,-1,{value:"/"}]),new ue([o]),n.alpha])}function serializeP3(n,r=!0){n.channels=convertPowerlessComponentsToZeroValuesForDisplay(n.channels,n.colorNotation);let o=n.channels.map(e=>Number.isNaN(e)?0:e);r?o=XYZ_D50_to_P3_Gamut(colorData_to_XYZ_D50(n).channels):n.colorNotation!==he.Display_P3&&(o=C(colorData_to_XYZ_D50(n).channels));const l=r?Math.min(1,Math.max(0,toPrecision(o[0],6))):toPrecision(o[0],6),t=r?Math.min(1,Math.max(0,toPrecision(o[1],6))):toPrecision(o[1],6),s=r?Math.min(1,Math.max(0,toPrecision(o[2],6))):toPrecision(o[2],6),u=[e.Function,"color(",-1,-1,{value:"color"}],i=[e.Whitespace," ",-1,-1,void 0];return serializeWithAlpha(n,u,i,[new oe([e.Ident,"display-p3",-1,-1,{value:"display-p3"}]),new ue([i]),new oe([e.Number,l.toString(),-1,-1,{value:o[0],type:a.Number}]),new ue([i]),new oe([e.Number,t.toString(),-1,-1,{value:o[1],type:a.Number}]),new ue([i]),new oe([e.Number,s.toString(),-1,-1,{value:o[2],type:a.Number}])])}function serializeRGB(n,r=!0){let o;n.channels=convertPowerlessComponentsToZeroValuesForDisplay(n.channels,n.colorNotation),o=r?XYZ_D50_to_sRGB_Gamut(colorData_to_XYZ_D50(n).channels):x(colorData_to_XYZ_D50(n).channels);const l=Math.min(255,Math.max(0,Math.round(255*toPrecision(o[0])))),t=Math.min(255,Math.max(0,Math.round(255*toPrecision(o[1])))),s=Math.min(255,Math.max(0,Math.round(255*toPrecision(o[2])))),u=[e.CloseParen,")",-1,-1,void 0],i=[e.Whitespace," ",-1,-1,void 0],c=[e.Comma,",",-1,-1,void 0],h=[new oe([e.Number,l.toString(),-1,-1,{value:Math.min(255,255*Math.max(0,o[0])),type:a.Integer}]),new oe(c),new ue([i]),new oe([e.Number,t.toString(),-1,-1,{value:Math.min(255,255*Math.max(0,o[1])),type:a.Integer}]),new oe(c),new ue([i]),new oe([e.Number,s.toString(),-1,-1,{value:Math.min(255,255*Math.max(0,o[2])),type:a.Integer}])];if("number"==typeof n.alpha){const r=Math.min(1,Math.max(0,toPrecision(Number.isNaN(n.alpha)?0:n.alpha)));return 1===toPrecision(r,4)?new se([e.Function,"rgb(",-1,-1,{value:"rgb"}],u,h):new se([e.Function,"rgba(",-1,-1,{value:"rgba"}],u,[...h,new oe(c),new ue([i]),new oe([e.Number,toPrecision(r,4).toString(),-1,-1,{value:n.alpha,type:a.Number}])])}return new se([e.Function,"rgba(",-1,-1,{value:"rgba"}],u,[...h,new oe(c),new ue([i]),n.alpha])}function serializeHSL(n,r=!0){let o;n.channels=convertPowerlessComponentsToZeroValuesForDisplay(n.channels,n.colorNotation),o=v(r?T(XYZ_D50_to_sRGB_Gamut(colorData_to_XYZ_D50(n).channels)):colorData_to_XYZ_D50(n).channels),o=o.map(e=>Number.isNaN(e)?0:e);const l=Math.min(360,Math.max(0,Math.round(toPrecision(o[0])))),t=Math.min(100,Math.max(0,Math.round(toPrecision(o[1])))),s=Math.min(100,Math.max(0,Math.round(toPrecision(o[2])))),u=[e.CloseParen,")",-1,-1,void 0],i=[e.Whitespace," ",-1,-1,void 0],c=[e.Comma,",",-1,-1,void 0],h=[new oe([e.Number,l.toString(),-1,-1,{value:o[0],type:a.Integer}]),new oe(c),new ue([i]),new oe([e.Percentage,t.toString()+"%",-1,-1,{value:o[1]}]),new oe(c),new ue([i]),new oe([e.Percentage,s.toString()+"%",-1,-1,{value:o[2]}])];if("number"==typeof n.alpha){const r=Math.min(1,Math.max(0,toPrecision(Number.isNaN(n.alpha)?0:n.alpha)));return 1===toPrecision(r,4)?new se([e.Function,"hsl(",-1,-1,{value:"hsl"}],u,h):new se([e.Function,"hsla(",-1,-1,{value:"hsla"}],u,[...h,new oe(c),new ue([i]),new oe([e.Number,toPrecision(r,4).toString(),-1,-1,{value:n.alpha,type:a.Number}])])}return new se([e.Function,"hsla(",-1,-1,{value:"hsla"}],u,[...h,new oe(c),new ue([i]),n.alpha])}function serializeOKLCH(n){n.channels=convertPowerlessComponentsToZeroValuesForDisplay(n.channels,n.colorNotation);let r=n.channels.map(e=>Number.isNaN(e)?0:e);n.colorNotation!==he.OKLCH&&(r=p(colorData_to_XYZ_D50(n).channels));const o=toPrecision(r[0],6),l=toPrecision(r[1],6),t=toPrecision(r[2],6),s=[e.Function,"oklch(",-1,-1,{value:"oklch"}],u=[e.Whitespace," ",-1,-1,void 0];return serializeWithAlpha(n,s,u,[new oe([e.Number,o.toString(),-1,-1,{value:r[0],type:a.Number}]),new ue([u]),new oe([e.Number,l.toString(),-1,-1,{value:r[1],type:a.Number}]),new ue([u]),new oe([e.Number,t.toString(),-1,-1,{value:r[2],type:a.Number}])])}function color(e){if(re(e)){switch(toLowerCaseAZ(e.getName())){case"rgb":case"rgba":return rgb(e,color);case"hsl":case"hsla":return hsl(e,color);case"hwb":return a=color,threeChannelSpaceSeparated(e,normalize_HWB_ChannelValues,he.HWB,[],a);case"lab":return lab(e,color);case"lch":return lch(e,color);case"oklab":return oklab(e,color);case"oklch":return oklch(e,color);case"color":return color$1(e,color);case"color-mix":return colorMix(e,color);case"contrast-color":return contrastColor(e,color);case"alpha":return alpha(e,color)}}var a;if(ne(e)){if(i(e.value))return hex(e.value);if(n(e.value)){const a=namedColor(e.value[4].value);return!1!==a?a:"transparent"===toLowerCaseAZ(e.value[4].value)&&{colorNotation:he.RGB,channels:[0,0,0],alpha:0,syntaxFlags:new Set([me.ColorKeyword])}}}return!1}export{he as ColorNotation,me as SyntaxFlag,color,colorDataFitsDisplayP3_Gamut,colorDataFitsRGB_Gamut,serializeHSL,serializeOKLCH,serializeP3,serializeRGB}; diff --git a/packages/css-color-parser/src/color-data.ts b/packages/css-color-parser/src/color-data.ts index f99a7abb9f..b9a96472ec 100644 --- a/packages/css-color-parser/src/color-data.ts +++ b/packages/css-color-parser/src/color-data.ts @@ -281,39 +281,43 @@ export function colorDataTo(colorData: ColorData, toNotation: ColorNotation): Co // 2. Carry forward missing components if (toNotation === colorData.colorNotation) { - outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0, 1, 2], outputColorData.channels, [0, 1, 2]); + outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0, 1, 2], [], outputColorData.channels, [0, 1, 2], []); } else if ( predefinedRGB_or_XYZ_Spaces.has(toNotation) && predefinedRGB_or_XYZ_Spaces.has(colorData.colorNotation) ) { - outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0, 1, 2], outputColorData.channels, [0, 1, 2]); + outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0, 1, 2], [], outputColorData.channels, [0, 1, 2], []); } else { switch (toNotation) { case ColorNotation.HSL: switch (colorData.colorNotation) { case ColorNotation.HWB: - outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0], outputColorData.channels, [0]); + outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0], [1, 2], outputColorData.channels, [0], [1, 2]); break; case ColorNotation.Lab: case ColorNotation.OKLab: - outputColorData.channels = carryForwardMissingComponents(colorData.channels, [2], outputColorData.channels, [0]); + outputColorData.channels = carryForwardMissingComponents(colorData.channels, [2], [0, 1], outputColorData.channels, [0], [1, 2]); break; case ColorNotation.LCH: case ColorNotation.OKLCH: - outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0, 1, 2], outputColorData.channels, [2, 1, 0]); + outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0, 1, 2], [], outputColorData.channels, [2, 1, 0], []); break; + default: + outputColorData.channels = carryForwardMissingComponents(colorData.channels, [], [], outputColorData.channels, [], []); } break; case ColorNotation.HWB: switch (colorData.colorNotation) { case ColorNotation.HSL: - outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0], outputColorData.channels, [0]); + outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0], [1, 2], outputColorData.channels, [0], [1, 2]); break; case ColorNotation.LCH: case ColorNotation.OKLCH: - outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0], outputColorData.channels, [2]); + outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0], [1, 2], outputColorData.channels, [2], [0, 1]); break; + default: + outputColorData.channels = carryForwardMissingComponents(colorData.channels, [], [], outputColorData.channels, [], []); } break; @@ -321,16 +325,18 @@ export function colorDataTo(colorData: ColorData, toNotation: ColorNotation): Co case ColorNotation.OKLab: switch (colorData.colorNotation) { case ColorNotation.HSL: - outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0], outputColorData.channels, [2]); + outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0], [1, 2], outputColorData.channels, [2], [0, 1]); break; case ColorNotation.Lab: case ColorNotation.OKLab: - outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0, 1, 2], outputColorData.channels, [0, 1, 2]); + outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0, 1, 2], [], outputColorData.channels, [0, 1, 2], []); break; case ColorNotation.LCH: case ColorNotation.OKLCH: - outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0], outputColorData.channels, [0]); + outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0], [1, 2], outputColorData.channels, [0], [1, 2]); break; + default: + outputColorData.channels = carryForwardMissingComponents(colorData.channels, [], [], outputColorData.channels, [], []); } break; @@ -338,22 +344,27 @@ export function colorDataTo(colorData: ColorData, toNotation: ColorNotation): Co case ColorNotation.OKLCH: switch (colorData.colorNotation) { case ColorNotation.HSL: - outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0, 1, 2], outputColorData.channels, [2, 1, 0]); + outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0, 1, 2], [], outputColorData.channels, [2, 1, 0], []); break; case ColorNotation.HWB: - outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0], outputColorData.channels, [2]); + outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0], [1, 2], outputColorData.channels, [2], [0, 1]); break; case ColorNotation.Lab: case ColorNotation.OKLab: - outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0], outputColorData.channels, [0]); + outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0], [1, 2], outputColorData.channels, [0], [1, 2]); break; case ColorNotation.LCH: case ColorNotation.OKLCH: - outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0, 1, 2], outputColorData.channels, [0, 1, 2]); + outputColorData.channels = carryForwardMissingComponents(colorData.channels, [0, 1, 2], [], outputColorData.channels, [0, 1, 2], []); break; + default: + outputColorData.channels = carryForwardMissingComponents(colorData.channels, [], [], outputColorData.channels, [], []); } break; + + default: + outputColorData.channels = carryForwardMissingComponents(colorData.channels, [], [], outputColorData.channels, [], []); } } @@ -452,15 +463,25 @@ export function convertPowerlessComponentsToZeroValuesForDisplay(a: Color, color return out; } -function carryForwardMissingComponents(a: Color, aIndices: Array, b: Color, bIndices: Array): Color { +function carryForwardMissingComponents(a: Color, aIndices: Array, aSet: Array, b: Color, bIndices: Array, bSet: Array): Color { + if (aIndices.length < 3 && a.every(Number.isNaN)) { + return [Number.NaN, Number.NaN, Number.NaN]; + } + const output: Color = [...b]; - for (const i of aIndices) { + for (let i = 0; i < aIndices.length; i++) { if (Number.isNaN(a[aIndices[i]])) { output[bIndices[i]] = Number.NaN; } } + if (aSet.length && aSet.every((i) => Number.isNaN(a[i]))) { + for (let i = 0; i < bSet.length; i++) { + output[bSet[i]] = Number.NaN; + } + } + return output; } diff --git a/packages/css-color-parser/test/basic/color-mix-function-oklch.mjs b/packages/css-color-parser/test/basic/color-mix-function-oklch.mjs index 2f16eee018..3fd02f60ea 100644 --- a/packages/css-color-parser/test/basic/color-mix-function-oklch.mjs +++ b/packages/css-color-parser/test/basic/color-mix-function-oklch.mjs @@ -9,6 +9,11 @@ const tests = [ ['color-mix(in lch, oklch(75% 0% 60deg), oklch(75% 50% 0deg))', 'oklch(0.74979 0.09824 0.10588)'], ['color-mix(in oklch, oklch(100% 0% none), oklch(50% 50% 0deg))', 'oklch(0.75 0.1 0)'], ['color-mix(in oklch, oklch(100% none 60deg), oklch(50% 50% 0deg))', 'oklch(0.75 0.2 30)'], + + // Analogous sets + ['color-mix(in oklch, rgb(none none none), oklch(0.5 0.2 50))', 'oklch(0.5 0.2 50)'], + ['color-mix(in oklch, hwb(100deg none none), oklch(0.5 0.2 50deg))', 'oklch(0.5 0.2 94.8876)'], + ['color-mix(in oklch, lab(100 none none), oklch(0.5 0.2 50deg))', 'oklch(0.75 0.2 50)'], ]; for (const test of tests) { diff --git a/packages/css-color-parser/test/basic/color-mix-function.mjs b/packages/css-color-parser/test/basic/color-mix-function.mjs index cfbf770e1b..f01c50a3ba 100644 --- a/packages/css-color-parser/test/basic/color-mix-function.mjs +++ b/packages/css-color-parser/test/basic/color-mix-function.mjs @@ -135,6 +135,11 @@ const tests = [ ['color-mix(in oklab, red 5%,)', ''], ['color-mix(in oklab, red, blue, green,)', ''], ['color-mix(in oklab, red, , green)', ''], + + // Analogous sets + ['color-mix(in oklch, rgb(200, 100, 50), oklch(none none none))', 'rgb(200, 100, 50)'], + ['color-mix(in oklch, rgb(200, 100, 50), lab(none none none))', 'rgb(200, 100, 50)'], + ['color-mix(in oklch, lab(40% 20% 10%), lab(40% 20% 10%))', 'rgb(136, 77, 75)'], ]; for (const test of tests) {