chromametry 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -46
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +4 -29
- package/dist/index.d.ts +4 -29
- package/dist/index.global.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -68,7 +68,7 @@ npm install chromametry
|
|
|
68
68
|
|
|
69
69
|
### Usage
|
|
70
70
|
```ts
|
|
71
|
-
import {
|
|
71
|
+
import { Ramp, Swatch } from "chromametry";
|
|
72
72
|
|
|
73
73
|
const blue = new Ramp([
|
|
74
74
|
"#ffffff",
|
|
@@ -89,39 +89,18 @@ console.log(blue.baseColor);
|
|
|
89
89
|
console.log(blue.wcag[45].span);
|
|
90
90
|
console.log(blue.metrics);
|
|
91
91
|
console.log(blue.score);
|
|
92
|
+
console.log(blue.direction);
|
|
92
93
|
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
"#ffffff",
|
|
97
|
-
"#fff2e8",
|
|
98
|
-
"#ffd9be",
|
|
99
|
-
"#ffb784",
|
|
100
|
-
"#ff832b",
|
|
101
|
-
"#eb6200",
|
|
102
|
-
"#ba4e00",
|
|
103
|
-
"#8a3800",
|
|
104
|
-
"#5e2900",
|
|
105
|
-
"#3e1a00",
|
|
106
|
-
"#231000",
|
|
107
|
-
"#000000",
|
|
108
|
-
],
|
|
109
|
-
}, "My Brand");
|
|
110
|
-
|
|
111
|
-
console.log(brand.metrics);
|
|
112
|
-
console.log(brand.wcag[45]);
|
|
113
|
-
console.log(brand.score);
|
|
114
|
-
|
|
115
|
-
const shade = new Shade("#2378c3");
|
|
116
|
-
console.log(shade.lab);
|
|
117
|
-
console.log(shade.chroma);
|
|
94
|
+
const swatch = new Swatch("#2378c3");
|
|
95
|
+
console.log(swatch.lab);
|
|
96
|
+
console.log(swatch.chroma);
|
|
118
97
|
```
|
|
119
98
|
|
|
120
99
|
### Browser
|
|
121
100
|
**ESM**
|
|
122
101
|
```html
|
|
123
102
|
<script type="module">
|
|
124
|
-
import {
|
|
103
|
+
import { Ramp } from "https://esm.sh/chromametry";
|
|
125
104
|
|
|
126
105
|
const ramp = new Ramp(["#ffffff", "#2378c3", "#000000"], "blue");
|
|
127
106
|
console.log(ramp.score);
|
|
@@ -138,16 +117,16 @@ console.log(shade.chroma);
|
|
|
138
117
|
```
|
|
139
118
|
|
|
140
119
|
### Class Reference
|
|
141
|
-
####
|
|
120
|
+
#### Swatch
|
|
142
121
|
| Property | Description |
|
|
143
122
|
| :--- | :--- |
|
|
144
|
-
| `constructor(hex)` | Create a
|
|
123
|
+
| `constructor(hex)` | Create a swatch from a hex color string. |
|
|
145
124
|
| `hex` | Original hex color. |
|
|
146
125
|
| `rgb` | Linear RGB values. |
|
|
147
126
|
| `lab` | CIELAB coordinates. |
|
|
148
127
|
| `lch` | LCH coordinates derived from LAB. |
|
|
149
128
|
| `lightness` | Perceptual lightness with Helmholtz-Kohlrausch correction. |
|
|
150
|
-
| `chroma` | Chroma of the
|
|
129
|
+
| `chroma` | Chroma of the swatch. |
|
|
151
130
|
| `hue` | Hue angle in degrees. |
|
|
152
131
|
| `luminance` | Relative luminance used for contrast. |
|
|
153
132
|
| `wcag` | WCAG contrast ratio against white. |
|
|
@@ -158,9 +137,10 @@ console.log(shade.chroma);
|
|
|
158
137
|
| :--- | :--- |
|
|
159
138
|
| `constructor(colors, name?)` | Create a sequential ramp from hex colors. |
|
|
160
139
|
| `name` | Ramp name. |
|
|
161
|
-
| `
|
|
140
|
+
| `swatches` | `Swatch[]` built from the input colors. |
|
|
162
141
|
| `colors` | Original ramp colors as hex strings. |
|
|
163
142
|
| `steps` | Number of steps in the ramp. |
|
|
143
|
+
| `direction` | Whether the ramp trends from light to dark or dark to light. |
|
|
164
144
|
| `peakChroma` | Hex color with the highest chroma in the inner ramp. |
|
|
165
145
|
| `baseColor` | Base color used as the ramp anchor. |
|
|
166
146
|
| `baseIndex` | Index of the base color. |
|
|
@@ -177,21 +157,6 @@ console.log(shade.chroma);
|
|
|
177
157
|
| `metrics` | Object containing the five ramp metrics. |
|
|
178
158
|
| `score` | Composite ramp score. |
|
|
179
159
|
|
|
180
|
-
#### Palette
|
|
181
|
-
| Property | Description |
|
|
182
|
-
| :--- | :--- |
|
|
183
|
-
| `constructor(colors, name?)` | Create a palette from named ramps. |
|
|
184
|
-
| `name` | Palette name. |
|
|
185
|
-
| `ramps` | `Ramp[]` built from the input record. |
|
|
186
|
-
| `colors` | Original palette colors as `Record<string, string[]>`. |
|
|
187
|
-
| `steps` | Number of steps shared by the ramps. |
|
|
188
|
-
| `direction` | Ramp direction inferred from the first ramp. |
|
|
189
|
-
| `wcag` | Palette-level WCAG contrast spans aggregated across ramps. |
|
|
190
|
-
| `apca` | Palette-level APCA contrast spans aggregated across ramps. |
|
|
191
|
-
| `contrasts` | Combined contrast object with `wcag` and `apca`. |
|
|
192
|
-
| `metrics` | Object containing the five palette metrics aggregated from ramps. |
|
|
193
|
-
| `score` | Composite palette score. |
|
|
194
|
-
|
|
195
160
|
## Reproducing Benchmarks
|
|
196
161
|
To run the benchmark generator locally:
|
|
197
162
|
```bash
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var v=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var O=Object.prototype.hasOwnProperty;var N=(m,t)=>{for(var s in t)v(m,s,{get:t[s],enumerable:!0})},V=(m,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of j(t))!O.call(m,e)&&e!==s&&v(m,e,{get:()=>t[e],enumerable:!(n=G(t,e))||n.enumerable});return m};var $=m=>V(v({},"__esModule",{value:!0}),m);var et={};N(et,{Palette:()=>T,Ramp:()=>q,Shade:()=>y,calcDeltaE2000:()=>P,calcScore:()=>L,calcStatistics:()=>nt,createMonotone:()=>E,cssRgbToRgb:()=>st,fromLightnessEAL:()=>J,hexToRgb:()=>C,labToLch:()=>k,labToRgb:()=>tt,lchToLab:()=>Q,rgbToHex:()=>Z,rgbToLab:()=>S,rootMeanSquare:()=>x,toLightnessEAL:()=>_});module.exports=$(et);var F=m=>{let t=s=>{let n=Math.max(0,Math.min(1,s)),e=n<=.0031308?12.92*n:1.055*Math.pow(n,1/2.4)-.055;return Math.max(0,Math.min(255,Math.round(e*255)))};return m.map(t)},K=m=>{let t=s=>s>.04045?Math.pow((s+.055)/1.055,2.4):s/12.92;return m.map(t)},Z=m=>{let[t,s,n]=F(m);return t=t.toString(16).padStart(2,"0"),s=s.toString(16).padStart(2,"0"),n=n.toString(16).padStart(2,"0"),`#${t}${s}${n}`},C=m=>{let t=parseInt(m.slice(1,3),16)/255,s=parseInt(m.slice(3,5),16)/255,n=parseInt(m.slice(5,7),16)/255;return K([t,s,n])},_=m=>{let[t,s,n]=m,e=Math.sqrt(s*s+n*n),a=(Math.atan2(n,s)*180/Math.PI+360)%360,h=.1644,u=.0603,r=.1307,i=.006,l=h*Math.abs(Math.sin((a-90)/2*(Math.PI/180)))+u,c=0;return(a<=90||a>=270)&&(c=r*Math.abs(Math.cos(a*(Math.PI/180)))+i),t+(l+c)*e},J=(m,t)=>{let[,s,n]=t,e=Math.sqrt(s*s+n*n),a=(Math.atan2(n,s)*180/Math.PI+360)%360,h=.1644,u=.0603,r=.1307,i=.006,l=h*Math.abs(Math.sin((a-90)/2*(Math.PI/180)))+u,c=0;return(a<=90||a>=270)&&(c=r*Math.abs(Math.cos(a*(Math.PI/180)))+i),Math.max(0,m-(l+c)*e)},Q=m=>{let[t,s,n]=m,e=n*Math.PI/180;return[t,s*Math.cos(e),s*Math.sin(e)]},S=m=>{let[t,s,n]=m,e=.4124564*t+.3575761*s+.1804375*n,o=.2126729*t+.7151522*s+.072175*n,a=.0193339*t+.119192*s+.9503041*n,h=.95047,u=1,r=1.08883,i=g=>g>.008856?Math.cbrt(g):7.787*g+16/116,l=i(e/h),c=i(o/u),p=i(a/r);return[116*c-16,500*(l-c),200*(c-p)]},tt=m=>{let[t,s,n]=m,e=(t+16)/116,o=s/500+e,a=e-n/200,h=g=>g**3>.008856?g**3:(g-16/116)/7.787,u=.95047,r=1,i=1.08883,l=h(o)*u,c=h(e)*r,p=h(a)*i;return[3.2404542*l-1.5371385*c-.4985314*p,-.969266*l+1.8760108*c+.041556*p,.0556434*l-.2040259*c+1.0572252*p]},k=m=>{let[t,s,n]=m,e=Math.sqrt(s*s+n*n);if(e<1e-4)return[t,0,0];let a=(Math.atan2(n,s)*180/Math.PI+360)%360;return a>=359.9999&&(a=0),[t,e,a]},P=(m,t)=>{let[s,n,e]=m,[o,a,h]=t,u=(s+o)/2,r=Math.sqrt(n*n+e*e),i=Math.sqrt(a*a+h*h),l=(r+i)/2,c=.5*(1-Math.sqrt(Math.pow(l,7)/(Math.pow(l,7)+Math.pow(25,7)))),p=n*(1+c),g=a*(1+c),M=Math.sqrt(p*p+e*e),b=Math.sqrt(g*g+h*h),w=(M+b)/2,d=Math.atan2(e,p)*180/Math.PI+(Math.atan2(e,p)<0?360:0),f=Math.atan2(h,g)*180/Math.PI+(Math.atan2(h,g)<0?360:0),R=f-d;Math.abs(R)>180&&(R+=f<=d?360:-360);let I=Math.abs(d-f)>180?(d+f+360)/2:(d+f)/2,U=1-.17*Math.cos((I-30)*Math.PI/180)+.24*Math.cos(2*I*Math.PI/180)+.32*Math.cos((3*I+6)*Math.PI/180)-.2*Math.cos((4*I-63)*Math.PI/180),W=o-s,A=b-M,D=2*Math.sqrt(M*b)*Math.sin(R/2*Math.PI/180),X=1+.015*Math.pow(u-50,2)/Math.sqrt(20+Math.pow(u-50,2)),H=1+.045*w,Y=1+.015*w*U,z=30*Math.exp(-Math.pow((I-275)/25,2)),B=-(2*Math.sqrt(Math.pow(w,7)/(Math.pow(w,7)+Math.pow(25,7))))*Math.sin(2*z*Math.PI/180);return Math.sqrt(Math.pow(W/X,2)+Math.pow(A/H,2)+Math.pow(D/Y,2)+B*(A/H)*(D/Y))},st=m=>{let t=m.match(/\d+(\.\d+)?/g);if(!t||t.length<3)throw new Error("Invalid CSS rgb()");let s=n=>{let e=n/255;return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)};return[s(Number(t[0])),s(Number(t[1])),s(Number(t[2]))]},E=m=>{if(m.length<1)return r=>0;let t=[...m].sort((r,i)=>r[0]-i[0]),s=[];for(let r=0;r<t.length;r++)(r===0||t[r][0]!==t[r-1][0])&&s.push(t[r]);let n=s.length;if(n===1)return r=>s[0][1];let e=s.map(r=>r[0]),o=s.map(r=>r[1]),a=[],h=[];for(let r=0;r<n-1;r++)a[r]=e[r+1]-e[r],h[r]=(o[r+1]-o[r])/a[r];let u=new Array(n);u[0]=h[0],u[n-1]=h[n-2];for(let r=1;r<n-1;r++){let i=h[r-1],l=h[r];if(i*l<=0)u[r]=0;else{let c=(1+a[r]/(a[r-1]+a[r]))/3;u[r]=i*l/((1-c)*i+c*l)}}return r=>{if(r<=e[0])return o[0];if(r>=e[n-1])return o[n-1];let i=0,l=n-2,c=0;for(;i<=l;){let f=Math.floor((i+l)/2);if(r>=e[f]&&r<=e[f+1]){c=f;break}r<e[f]?l=f-1:i=f+1}let p=a[c],g=(r-e[c])/p,M=g*g,b=M*g,w=u[c]*p,d=u[c+1]*p;return(2*b-3*M+1)*o[c]+(b-2*M+g)*w+(-2*b+3*M)*o[c+1]+(b-M)*d}};function x(m){let t=m.length;if(t===0)return 0;let s=0;for(let n=0;n<t;n++)s+=m[n]*m[n];return Math.sqrt(s/t)}var nt=m=>{let t=m.length;if(t===0)return{min:0,max:0,avg:0};let s=m[0],n=m[0],e=0;for(let o=0;o<t;o++){let a=m[o];a<s&&(s=a),a>n&&(n=a),e+=a}return{min:s,max:n,avg:e/t}},L=m=>{let t=m.length;if(t===0)return 0;let s=1e-6,n=m.reduce((a,h)=>a*(h+s),1),e=Math.pow(n,1/t),o=Math.max(0,Math.min(1,e));return parseFloat((o*100).toFixed(2))};var y=class{constructor(t){this.hex=t}get rgb(){return C(this.hex)}get lab(){return S(this.rgb)}get lch(){return k(this.lab)}get lightness(){let[t,s,n]=this.lab,e=Math.sqrt(s*s+n*n),a=(Math.atan2(n,s)*180/Math.PI+360)%360,h=.1644,u=.0603,r=.1307,i=.006,l=h*Math.abs(Math.sin((a-90)/2*(Math.PI/180)))+u,c=0;return(a<=90||a>=270)&&(c=r*Math.abs(Math.cos(a*(Math.PI/180)))+i),t+(l+c)*e}get chroma(){return this.lch[1]}get hue(){return this.lch[2]}get luminance(){let[t,s,n]=this.rgb;return .2126*t+.7152*s+.0722*n}get wcag(){return(Math.max(this.luminance,1)+.05)/(Math.min(this.luminance,1)+.05)}get apca(){let t=o=>o>5e-4?o:o+Math.pow(5e-4-o,.8),s=t(this.luminance),n=t(1),e=(Math.pow(s,.56)-Math.pow(n,.56))*100;return Math.abs(e)<.1?0:(e=e>0?e<1?0:e-.25:e>-1?0:e+.25,Math.round(e))}};var q=class{constructor(t=[],s="brand"){this.shades=t.map(n=>new y(n)),this.name=s}get colors(){return this.shades.map(t=>t.hex)}get peakChroma(){let t=this.colors.slice(2,-2),s="",n=-1/0;for(let e of t){let o=new y(e);o.chroma>n&&(n=o.chroma,s=e)}return s}get steps(){return this.colors.length}get baseColor(){return this.colors.length===0?"":this.peakChroma||this.colors[Math.floor(this.colors.length/2)]}get baseIndex(){return this.colors.length===0?-1:this.colors.findIndex(t=>t.toLowerCase()===this.baseColor.toLowerCase())}get wcag(){let t=this.shades,s=t.length,n=s-1,e={};for(let o of[30,45,70]){let a=o/10,h=n,u=0;for(let r=1;r<s;r++){let i=1/0;for(let l=0;l<s-r;l++){let c=t[l].luminance,p=t[l+r].luminance,g=(Math.max(c,p)+.05)/(Math.min(c,p)+.05);g<i&&(i=g)}if(i>=a){h=r,u=i;break}r===n&&(u=i)}e[o]={efficiency:h/n,target:a,span:h,value:u}}return e}get apca(){let t=this.shades,s=t.length,n=s-1,e={},o=(a,h)=>{let u=c=>c>5e-4?c:c+Math.pow(5e-4-c,.8),r=u(a),i=u(h),l=(Math.pow(r,.56)-Math.pow(i,.56))*100;return Math.abs(l)<.1?0:(l=l>0?l<1?0:l-.25:l>-1?0:l+.25,Math.round(l))};for(let a of[45,60,75]){let h=a,u=n,r=0;for(let i=1;i<s;i++){let l=1/0;for(let c=0;c<s-i;c++){let p=Math.max(Math.abs(o(t[c+i].luminance,t[c].luminance)),Math.abs(o(t[c].luminance,t[c+i].luminance)));p<l&&(l=p)}if(l>=h){u=i,r=l;break}i===n&&(r=l)}e[a]={efficiency:u/n,target:h,span:u,value:r}}return e}get contrasts(){return{wcag:this.wcag,apca:this.apca}}get deltaECurve(){let t=[0];for(let s=1;s<this.shades.length;s++){let n=P(this.shades[s-1].lab,this.shades[s].lab);t.push(t[s-1]+n)}return t}get unwrapHues(){let t=this.shades.map(n=>n.hue).slice(1,-1);if(t.length===0)return[];let s=[t[0]];for(let n=1;n<t.length;n++){let e=t[n]-t[n-1];e>180?e-=360:e<-180&&(e+=360),s.push(s[n-1]+e)}return s}get lightnessLinearity(){let t=this.shades.map(p=>p.lightness),s=t.length;if(s<2)return 1;let n=0,e=0,o=0,a=0;for(let p=0;p<s;p++)n+=p,e+=t[p],o+=p*t[p],a+=p*p;let h=s*a-n*n;if(Math.abs(h)<1e-10)return 1;let u=(s*o-n*e)/h,r=(e-u*n)/s;if(Math.abs(u*(s-1))<.001)return 1;let l=0,c=0;for(let p=0;p<s;p++){let g=u*p+r,M=t[p]-g;l+=M*M;let b=Math.max(g-Math.min(r,u*(s-1)+r),Math.max(r,u*(s-1)+r)-g);c+=b*b}return Math.max(0,Math.min(1,1-Math.sqrt(l/s)/Math.sqrt(c/s)))}get chromaSmoothness(){let t=this.shades.map(c=>c.chroma),s=t.length;if(s<3)return 1;let n=133.8,e=Math.max(...t);if(e<=.01)return 1;let o=t.map(c=>c/e*n),a=Math.min(...o),h=Math.max(...o),u=o.findIndex(c=>c===h),r=E([[0,o[0]],[u,h],[s-1,o[s-1]]]),i=0,l=0;for(let c=0;c<s;c++){let p=r(c),g=o[c]-p;i+=g*g,l+=Math.pow(Math.max(p-a,h-p),2)}return Math.max(0,Math.min(1,1-Math.sqrt(i/s)/Math.sqrt(l/s)))}get spacingUniformity(){let t=this.deltaECurve,s=t.length;if(s<2)return 1;let n=[];for(let h=1;h<s;h++){let u=t[h]-t[h-1];if(u<0)return 0;n.push(u)}let e=n.reduce((h,u)=>h+u,0)/n.length;if(e<=1e-6)return 0;let o=0;for(let h of n)o+=Math.pow(h-e,2);let a=Math.sqrt(o/n.length)/e;return Math.max(0,Math.min(1,1/(1+a)))}get hueStability(){var a,h,u;let t=this.unwrapHues,s=t.length;if(s<2)return 1;let n=(u=(h=t[this.baseIndex-1])!=null?h:(a=this.shades[this.baseIndex])==null?void 0:a.hue)!=null?u:0,e=0,o=0;for(let r=0;r<s;r++){let i=Math.abs(t[r]-n)%360;i>180&&(i=360-i),e+=i*i;let l=r/(s-1)*180;o+=l*l}return Math.max(0,Math.min(1,1-Math.sqrt(e/s)/(Math.sqrt(o/s)||1)))}get contrastEfficiency(){let t=this.wcag[45].span,s=this.steps;if(s<=1)return 1;let n=.5,e=t/s,o=n*((s-1)/s);return e<=o?1:e>=1?0:(1-e)/(1-o)}get metrics(){return{lightnessLinearity:this.lightnessLinearity,chromaSmoothness:this.chromaSmoothness,spacingUniformity:this.spacingUniformity,hueStability:this.hueStability,contrastEfficiency:this.contrastEfficiency}}get score(){return L(Object.values(this.metrics))}};var T=class{constructor(t={},s="palette"){this.ramps=Object.entries(t).map(([n,e])=>new q(e,n)),this.name=s}get colors(){return Object.fromEntries(this.ramps.map(t=>[t.name,t.colors]))}get steps(){var t;return((t=this.ramps[0])==null?void 0:t.steps)||0}get direction(){var e;let t=(e=this.ramps[0])==null?void 0:e.colors;if(!(t!=null&&t.length))return"lighten";let s=S(C(t[0])),n=S(C(t[t.length-1]));return s[0]>n[0]?"darken":"lighten"}get wcag(){var s;let t={};for(let n of[30,45,70]){let e=this.ramps.map(r=>r.wcag[n]),o=((s=this.ramps[0])==null?void 0:s.steps)||0,a=Math.max(...e.map(r=>(r==null?void 0:r.span)||0)),h=e.reduce((r,i)=>r+((i==null?void 0:i.value)||0),0),u=e[0];t[n]={target:(u==null?void 0:u.target)||0,span:a,value:h/(this.ramps.length||1),efficiency:a/(o-1||1)}}return t}get apca(){var s;let t={};for(let n of[45,60,75]){let e=this.ramps.map(r=>r.apca[n]),o=((s=this.ramps[0])==null?void 0:s.steps)||0,a=Math.max(...e.map(r=>(r==null?void 0:r.span)||0)),h=e.reduce((r,i)=>r+((i==null?void 0:i.value)||0),0),u=e[0];t[n]={target:(u==null?void 0:u.target)||0,span:a,value:h/(this.ramps.length||1),efficiency:a/(o-1||1)}}return t}get contrasts(){return{wcag:this.wcag,apca:this.apca}}get metrics(){return{contrastEfficiency:x(this.ramps.map(t=>t.contrastEfficiency)),lightnessLinearity:x(this.ramps.map(t=>t.lightnessLinearity)),chromaSmoothness:x(this.ramps.map(t=>t.chromaSmoothness)),hueStability:x(this.ramps.map(t=>t.hueStability)),spacingUniformity:x(this.ramps.map(t=>t.spacingUniformity))}}get score(){return L(Object.values(this.metrics))}};0&&(module.exports={Palette,Ramp,Shade,calcDeltaE2000,calcScore,calcStatistics,createMonotone,cssRgbToRgb,fromLightnessEAL,hexToRgb,labToLch,labToRgb,lchToLab,rgbToHex,rgbToLab,rootMeanSquare,toLightnessEAL});
|
|
1
|
+
"use strict";var L=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var U=Object.prototype.hasOwnProperty;var V=(u,n)=>{for(var t in n)L(u,t,{get:n[t],enumerable:!0})},W=(u,n,t,s)=>{if(n&&typeof n=="object"||typeof n=="function")for(let e of N(n))!U.call(u,e)&&e!==t&&L(u,e,{get:()=>n[e],enumerable:!(s=G(n,e))||s.enumerable});return u};var $=u=>W(L({},"__esModule",{value:!0}),u);var st={};V(st,{Ramp:()=>y,Swatch:()=>I,calcDeltaE2000:()=>v,calcScore:()=>P,calcStatistics:()=>nt,createMonotone:()=>k,cssRgbToRgb:()=>Q,fromLightnessEAL:()=>j,hexToRgb:()=>w,labToLch:()=>R,labToRgb:()=>J,lchToLab:()=>O,rgbToHex:()=>Z,rgbToLab:()=>C,rootMeanSquare:()=>tt,toLightnessEAL:()=>_});module.exports=$(st);var F=u=>{let n=t=>{let s=Math.max(0,Math.min(1,t)),e=s<=.0031308?12.92*s:1.055*Math.pow(s,1/2.4)-.055;return Math.max(0,Math.min(255,Math.round(e*255)))};return u.map(n)},K=u=>{let n=t=>t>.04045?Math.pow((t+.055)/1.055,2.4):t/12.92;return u.map(n)},Z=u=>{let[n,t,s]=F(u);return n=n.toString(16).padStart(2,"0"),t=t.toString(16).padStart(2,"0"),s=s.toString(16).padStart(2,"0"),`#${n}${t}${s}`},w=u=>{let n=parseInt(u.slice(1,3),16)/255,t=parseInt(u.slice(3,5),16)/255,s=parseInt(u.slice(5,7),16)/255;return K([n,t,s])},_=u=>{let[n,t,s]=u,e=Math.sqrt(t*t+s*s),a=(Math.atan2(s,t)*180/Math.PI+360)%360,c=.1644,m=.0603,r=.1307,i=.006,l=c*Math.abs(Math.sin((a-90)/2*(Math.PI/180)))+m,o=0;return(a<=90||a>=270)&&(o=r*Math.abs(Math.cos(a*(Math.PI/180)))+i),n+(l+o)*e},j=(u,n)=>{let[,t,s]=n,e=Math.sqrt(t*t+s*s),a=(Math.atan2(s,t)*180/Math.PI+360)%360,c=.1644,m=.0603,r=.1307,i=.006,l=c*Math.abs(Math.sin((a-90)/2*(Math.PI/180)))+m,o=0;return(a<=90||a>=270)&&(o=r*Math.abs(Math.cos(a*(Math.PI/180)))+i),Math.max(0,u-(l+o)*e)},O=u=>{let[n,t,s]=u,e=s*Math.PI/180;return[n,t*Math.cos(e),t*Math.sin(e)]},C=u=>{let[n,t,s]=u,e=.4124564*n+.3575761*t+.1804375*s,h=.2126729*n+.7151522*t+.072175*s,a=.0193339*n+.119192*t+.9503041*s,c=.95047,m=1,r=1.08883,i=b=>b>.008856?Math.cbrt(b):7.787*b+16/116,l=i(e/c),o=i(h/m),M=i(a/r);return[116*o-16,500*(l-o),200*(o-M)]},J=u=>{let[n,t,s]=u,e=(n+16)/116,h=t/500+e,a=e-s/200,c=b=>b**3>.008856?b**3:(b-16/116)/7.787,m=.95047,r=1,i=1.08883,l=c(h)*m,o=c(e)*r,M=c(a)*i;return[3.2404542*l-1.5371385*o-.4985314*M,-.969266*l+1.8760108*o+.041556*M,.0556434*l-.2040259*o+1.0572252*M]},R=u=>{let[n,t,s]=u,e=Math.sqrt(t*t+s*s);if(e<1e-4)return[n,0,0];let a=(Math.atan2(s,t)*180/Math.PI+360)%360;return a>=359.9999&&(a=0),[n,e,a]},v=(u,n)=>{let[t,s,e]=u,[h,a,c]=n,m=(t+h)/2,r=Math.sqrt(s*s+e*e),i=Math.sqrt(a*a+c*c),l=(r+i)/2,o=.5*(1-Math.sqrt(Math.pow(l,7)/(Math.pow(l,7)+Math.pow(25,7)))),M=s*(1+o),b=a*(1+o),f=Math.sqrt(M*M+e*e),p=Math.sqrt(b*b+c*c),d=(f+p)/2,x=Math.atan2(e,M)*180/Math.PI+(Math.atan2(e,M)<0?360:0),g=Math.atan2(c,b)*180/Math.PI+(Math.atan2(c,b)<0?360:0),q=g-x;Math.abs(q)>180&&(q+=g<=x?360:-360);let S=Math.abs(x-g)>180?(x+g+360)/2:(x+g)/2,H=1-.17*Math.cos((S-30)*Math.PI/180)+.24*Math.cos(2*S*Math.PI/180)+.32*Math.cos((3*S+6)*Math.PI/180)-.2*Math.cos((4*S-63)*Math.PI/180),Y=h-t,E=p-f,T=2*Math.sqrt(f*p)*Math.sin(q/2*Math.PI/180),A=1+.015*Math.pow(m-50,2)/Math.sqrt(20+Math.pow(m-50,2)),B=1+.045*d,D=1+.015*d*H,X=30*Math.exp(-Math.pow((S-275)/25,2)),z=-(2*Math.sqrt(Math.pow(d,7)/(Math.pow(d,7)+Math.pow(25,7))))*Math.sin(2*X*Math.PI/180);return Math.sqrt(Math.pow(Y/A,2)+Math.pow(E/B,2)+Math.pow(T/D,2)+z*(E/B)*(T/D))},Q=u=>{let n=u.match(/\d+(\.\d+)?/g);if(!n||n.length<3)throw new Error("Invalid CSS rgb()");let t=s=>{let e=s/255;return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)};return[t(Number(n[0])),t(Number(n[1])),t(Number(n[2]))]},k=u=>{if(u.length<1)return r=>0;let n=[...u].sort((r,i)=>r[0]-i[0]),t=[];for(let r=0;r<n.length;r++)(r===0||n[r][0]!==n[r-1][0])&&t.push(n[r]);let s=t.length;if(s===1)return r=>t[0][1];let e=t.map(r=>r[0]),h=t.map(r=>r[1]),a=[],c=[];for(let r=0;r<s-1;r++)a[r]=e[r+1]-e[r],c[r]=(h[r+1]-h[r])/a[r];let m=new Array(s);m[0]=c[0],m[s-1]=c[s-2];for(let r=1;r<s-1;r++){let i=c[r-1],l=c[r];if(i*l<=0)m[r]=0;else{let o=(1+a[r]/(a[r-1]+a[r]))/3;m[r]=i*l/((1-o)*i+o*l)}}return r=>{if(r<=e[0])return h[0];if(r>=e[s-1])return h[s-1];let i=0,l=s-2,o=0;for(;i<=l;){let g=Math.floor((i+l)/2);if(r>=e[g]&&r<=e[g+1]){o=g;break}r<e[g]?l=g-1:i=g+1}let M=a[o],b=(r-e[o])/M,f=b*b,p=f*b,d=m[o]*M,x=m[o+1]*M;return(2*p-3*f+1)*h[o]+(p-2*f+b)*d+(-2*p+3*f)*h[o+1]+(p-f)*x}};function tt(u){let n=u.length;if(n===0)return 0;let t=0;for(let s=0;s<n;s++)t+=u[s]*u[s];return Math.sqrt(t/n)}var nt=u=>{let n=u.length;if(n===0)return{min:0,max:0,avg:0};let t=u[0],s=u[0],e=0;for(let h=0;h<n;h++){let a=u[h];a<t&&(t=a),a>s&&(s=a),e+=a}return{min:t,max:s,avg:e/n}},P=u=>{let n=u.length;if(n===0)return 0;let t=1e-6,s=u.reduce((a,c)=>a*(c+t),1),e=Math.pow(s,1/n),h=Math.max(0,Math.min(1,e));return parseFloat((h*100).toFixed(2))};var I=class{constructor(n){this.hex=n}get rgb(){return w(this.hex)}get lab(){return C(this.rgb)}get lch(){return R(this.lab)}get lightness(){let[n,t,s]=this.lab,e=Math.sqrt(t*t+s*s),a=(Math.atan2(s,t)*180/Math.PI+360)%360,c=.1644,m=.0603,r=.1307,i=.006,l=c*Math.abs(Math.sin((a-90)/2*(Math.PI/180)))+m,o=0;return(a<=90||a>=270)&&(o=r*Math.abs(Math.cos(a*(Math.PI/180)))+i),n+(l+o)*e}get chroma(){return this.lch[1]}get hue(){return this.lch[2]}get luminance(){let[n,t,s]=this.rgb;return .2126*n+.7152*t+.0722*s}get wcag(){return(Math.max(this.luminance,1)+.05)/(Math.min(this.luminance,1)+.05)}get apca(){let n=h=>h>5e-4?h:h+Math.pow(5e-4-h,.8),t=n(this.luminance),s=n(1),e=(Math.pow(t,.56)-Math.pow(s,.56))*100;return Math.abs(e)<.1?0:(e=e>0?e<1?0:e-.25:e>-1?0:e+.25,Math.round(e))}};var y=class{constructor(n=[],t="brand"){this.swatches=n.map(s=>new I(s)),this.name=t}get colors(){return this.swatches.map(n=>n.hex)}get peakChroma(){let n=this.colors.slice(2,-2),t="",s=-1/0;for(let e of n){let h=new I(e);h.chroma>s&&(s=h.chroma,t=e)}return s<6?this.colors[Math.ceil(this.steps/2)]:t}get steps(){return this.colors.length}get direction(){if(this.colors.length===0)return"lighten";let n=C(w(this.colors[0])),t=C(w(this.colors[this.colors.length-1]));return n[0]>t[0]?"darken":"lighten"}get baseColor(){return this.colors.length===0?"":this.peakChroma||this.colors[Math.floor(this.colors.length/2)]}get baseIndex(){return this.colors.length===0?-1:this.colors.findIndex(n=>n.toLowerCase()===this.baseColor.toLowerCase())}get wcag(){let n=this.swatches,t=n.length,s=t-1,e={};for(let h of[30,45,70]){let a=h/10,c=s,m=0;for(let r=1;r<t;r++){let i=1/0;for(let l=0;l<t-r;l++){let o=n[l].luminance,M=n[l+r].luminance,b=(Math.max(o,M)+.05)/(Math.min(o,M)+.05);b<i&&(i=b)}if(i>=a){c=r,m=i;break}r===s&&(m=i)}e[h]={efficiency:c/s,target:a,span:c,value:m}}return e}get apca(){let n=this.swatches,t=n.length,s=t-1,e={},h=(a,c)=>{let i=a<.022?a+Math.pow(.022-a,1.414):a,l=c<.022?c+Math.pow(.022-c,1.414):c,o=l>=i?(Math.pow(l,.56)-Math.pow(i,.57))*114:(Math.pow(l,.65)-Math.pow(i,.62))*114;return Math.abs(o)<10?0:(o=o>0?o-2.7:o+2.7,Math.round(o))};for(let a of[45,60,75]){let c=a,m=s,r=0;for(let i=1;i<t;i++){let l=1/0;for(let o=0;o<t-i;o++){let M=n[o].luminance>n[o+i].luminance?n[o].luminance:n[o+i].luminance,b=n[o].luminance>n[o+i].luminance?n[o+i].luminance:n[o].luminance,f=Math.abs(h(b,M));f<l&&(l=f)}if(l>=c){m=i,r=l;break}i===s&&(r=l)}e[a]={efficiency:m/s,target:c,span:m,value:r}}return e}get contrasts(){return{wcag:this.wcag,apca:this.apca}}get deltaECurve(){let n=[0];for(let t=1;t<this.swatches.length;t++){let s=v(this.swatches[t-1].lab,this.swatches[t].lab);n.push(n[t-1]+s)}return n}get unwrapHues(){let n=this.swatches.map(s=>s.hue).slice(1,-1);if(n.length===0)return[];let t=[n[0]];for(let s=1;s<n.length;s++){let e=n[s]-n[s-1];e>180?e-=360:e<-180&&(e+=360),t.push(t[s-1]+e)}return t}get lightnessLinearity(){let n=this.swatches.map(M=>M.lightness),t=n.length;if(t<2)return 1;let s=0,e=0,h=0,a=0;for(let M=0;M<t;M++)s+=M,e+=n[M],h+=M*n[M],a+=M*M;let c=t*a-s*s;if(Math.abs(c)<1e-10)return 1;let m=(t*h-s*e)/c,r=(e-m*s)/t;if(Math.abs(m*(t-1))<.001)return 1;let l=0,o=0;for(let M=0;M<t;M++){let b=m*M+r,f=n[M]-b;l+=f*f;let p=Math.max(b-Math.min(r,m*(t-1)+r),Math.max(r,m*(t-1)+r)-b);o+=p*p}return Math.max(0,Math.min(1,1-Math.sqrt(l/t)/Math.sqrt(o/t)))}get chromaSmoothness(){let n=this.swatches.map(o=>o.chroma),t=n.length;if(t<3)return 1;let s=133.8,e=Math.max(...n);if(e<=.01)return 1;let h=n.map(o=>o/e*s),a=Math.min(...h),c=Math.max(...h),m=h.findIndex(o=>o===c),r=k([[0,h[0]],[m,c],[t-1,h[t-1]]]),i=0,l=0;for(let o=0;o<t;o++){let M=r(o),b=h[o]-M;i+=b*b,l+=Math.pow(Math.max(M-a,c-M),2)}return Math.max(0,Math.min(1,1-Math.sqrt(i/t)/Math.sqrt(l/t)))}get spacingUniformity(){let n=this.deltaECurve,t=n.length;if(t<2)return 1;let s=[];for(let c=1;c<t;c++){let m=n[c]-n[c-1];if(m<0)return 0;s.push(m)}let e=s.reduce((c,m)=>c+m,0)/s.length;if(e<=1e-6)return 0;let h=0;for(let c of s)h+=Math.pow(c-e,2);let a=Math.sqrt(h/s.length)/e;return Math.max(0,Math.min(1,1/(1+a)))}get hueStability(){var a,c,m;let n=this.unwrapHues,t=n.length;if(t<2)return 1;let s=(m=(c=n[this.baseIndex-1])!=null?c:(a=this.swatches[this.baseIndex])==null?void 0:a.hue)!=null?m:0,e=0,h=0;for(let r=0;r<t;r++){let i=Math.abs(n[r]-s)%360;i>180&&(i=360-i),e+=i*i;let l=r/(t-1)*180;h+=l*l}return Math.max(0,Math.min(1,1-Math.sqrt(e/t)/(Math.sqrt(h/t)||1)))}get contrastEfficiency(){let n=this.wcag[45].span,t=this.steps;if(t<=1)return 1;let s=.5,e=n/t,h=s*((t-1)/t);return e<=h?1:e>=1?0:(1-e)/(1-h)}get metrics(){return{lightnessLinearity:this.lightnessLinearity,chromaSmoothness:this.chromaSmoothness,spacingUniformity:this.spacingUniformity,hueStability:this.hueStability,contrastEfficiency:this.contrastEfficiency}}get score(){return P(Object.values(this.metrics))}};0&&(module.exports={Ramp,Swatch,calcDeltaE2000,calcScore,calcStatistics,createMonotone,cssRgbToRgb,fromLightnessEAL,hexToRgb,labToLch,labToRgb,lchToLab,rgbToHex,rgbToLab,rootMeanSquare,toLightnessEAL});
|
package/dist/index.d.cts
CHANGED
|
@@ -35,7 +35,7 @@ declare const calcStatistics: (array: number[]) => {
|
|
|
35
35
|
/** Calculate geometric mean score (0-100) from metrics. */
|
|
36
36
|
declare const calcScore: (metrics: number[]) => number;
|
|
37
37
|
|
|
38
|
-
declare class
|
|
38
|
+
declare class Swatch {
|
|
39
39
|
readonly hex: string;
|
|
40
40
|
constructor(hex: string);
|
|
41
41
|
get rgb(): number[];
|
|
@@ -58,12 +58,13 @@ type ContrastValue = {
|
|
|
58
58
|
type WcagContrasts = Record<30 | 45 | 70, ContrastValue>;
|
|
59
59
|
type ApcaContrasts = Record<45 | 60 | 75, ContrastValue>;
|
|
60
60
|
declare class Ramp {
|
|
61
|
-
|
|
61
|
+
swatches: Swatch[];
|
|
62
62
|
name: string;
|
|
63
63
|
constructor(colors?: string[], name?: string);
|
|
64
64
|
get colors(): string[];
|
|
65
65
|
get peakChroma(): string;
|
|
66
66
|
get steps(): number;
|
|
67
|
+
get direction(): "lighten" | "darken";
|
|
67
68
|
get baseColor(): string;
|
|
68
69
|
get baseIndex(): number;
|
|
69
70
|
get wcag(): WcagContrasts;
|
|
@@ -89,30 +90,4 @@ declare class Ramp {
|
|
|
89
90
|
get score(): number;
|
|
90
91
|
}
|
|
91
92
|
|
|
92
|
-
type
|
|
93
|
-
contrastEfficiency: number;
|
|
94
|
-
lightnessLinearity: number;
|
|
95
|
-
chromaSmoothness: number;
|
|
96
|
-
hueStability: number;
|
|
97
|
-
spacingUniformity: number;
|
|
98
|
-
};
|
|
99
|
-
declare class Palette {
|
|
100
|
-
ramps: Ramp[];
|
|
101
|
-
name: string;
|
|
102
|
-
constructor(colors?: Record<string, string[]>, name?: string);
|
|
103
|
-
get colors(): {
|
|
104
|
-
[k: string]: string[];
|
|
105
|
-
};
|
|
106
|
-
get steps(): number;
|
|
107
|
-
get direction(): "lighten" | "darken";
|
|
108
|
-
get wcag(): WcagContrasts;
|
|
109
|
-
get apca(): ApcaContrasts;
|
|
110
|
-
get contrasts(): {
|
|
111
|
-
wcag: WcagContrasts;
|
|
112
|
-
apca: ApcaContrasts;
|
|
113
|
-
};
|
|
114
|
-
get metrics(): PaletteMetrics;
|
|
115
|
-
get score(): number;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export { type ApcaContrasts, type ContrastValue, Palette, type PaletteMetrics, Ramp, Shade, type WcagContrasts, calcDeltaE2000, calcScore, calcStatistics, createMonotone, cssRgbToRgb, fromLightnessEAL, hexToRgb, labToLch, labToRgb, lchToLab, rgbToHex, rgbToLab, rootMeanSquare, toLightnessEAL };
|
|
93
|
+
export { type ApcaContrasts, type ContrastValue, Ramp, Swatch, type WcagContrasts, calcDeltaE2000, calcScore, calcStatistics, createMonotone, cssRgbToRgb, fromLightnessEAL, hexToRgb, labToLch, labToRgb, lchToLab, rgbToHex, rgbToLab, rootMeanSquare, toLightnessEAL };
|
package/dist/index.d.ts
CHANGED
|
@@ -35,7 +35,7 @@ declare const calcStatistics: (array: number[]) => {
|
|
|
35
35
|
/** Calculate geometric mean score (0-100) from metrics. */
|
|
36
36
|
declare const calcScore: (metrics: number[]) => number;
|
|
37
37
|
|
|
38
|
-
declare class
|
|
38
|
+
declare class Swatch {
|
|
39
39
|
readonly hex: string;
|
|
40
40
|
constructor(hex: string);
|
|
41
41
|
get rgb(): number[];
|
|
@@ -58,12 +58,13 @@ type ContrastValue = {
|
|
|
58
58
|
type WcagContrasts = Record<30 | 45 | 70, ContrastValue>;
|
|
59
59
|
type ApcaContrasts = Record<45 | 60 | 75, ContrastValue>;
|
|
60
60
|
declare class Ramp {
|
|
61
|
-
|
|
61
|
+
swatches: Swatch[];
|
|
62
62
|
name: string;
|
|
63
63
|
constructor(colors?: string[], name?: string);
|
|
64
64
|
get colors(): string[];
|
|
65
65
|
get peakChroma(): string;
|
|
66
66
|
get steps(): number;
|
|
67
|
+
get direction(): "lighten" | "darken";
|
|
67
68
|
get baseColor(): string;
|
|
68
69
|
get baseIndex(): number;
|
|
69
70
|
get wcag(): WcagContrasts;
|
|
@@ -89,30 +90,4 @@ declare class Ramp {
|
|
|
89
90
|
get score(): number;
|
|
90
91
|
}
|
|
91
92
|
|
|
92
|
-
type
|
|
93
|
-
contrastEfficiency: number;
|
|
94
|
-
lightnessLinearity: number;
|
|
95
|
-
chromaSmoothness: number;
|
|
96
|
-
hueStability: number;
|
|
97
|
-
spacingUniformity: number;
|
|
98
|
-
};
|
|
99
|
-
declare class Palette {
|
|
100
|
-
ramps: Ramp[];
|
|
101
|
-
name: string;
|
|
102
|
-
constructor(colors?: Record<string, string[]>, name?: string);
|
|
103
|
-
get colors(): {
|
|
104
|
-
[k: string]: string[];
|
|
105
|
-
};
|
|
106
|
-
get steps(): number;
|
|
107
|
-
get direction(): "lighten" | "darken";
|
|
108
|
-
get wcag(): WcagContrasts;
|
|
109
|
-
get apca(): ApcaContrasts;
|
|
110
|
-
get contrasts(): {
|
|
111
|
-
wcag: WcagContrasts;
|
|
112
|
-
apca: ApcaContrasts;
|
|
113
|
-
};
|
|
114
|
-
get metrics(): PaletteMetrics;
|
|
115
|
-
get score(): number;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export { type ApcaContrasts, type ContrastValue, Palette, type PaletteMetrics, Ramp, Shade, type WcagContrasts, calcDeltaE2000, calcScore, calcStatistics, createMonotone, cssRgbToRgb, fromLightnessEAL, hexToRgb, labToLch, labToRgb, lchToLab, rgbToHex, rgbToLab, rootMeanSquare, toLightnessEAL };
|
|
93
|
+
export { type ApcaContrasts, type ContrastValue, Ramp, Swatch, type WcagContrasts, calcDeltaE2000, calcScore, calcStatistics, createMonotone, cssRgbToRgb, fromLightnessEAL, hexToRgb, labToLch, labToRgb, lchToLab, rgbToHex, rgbToLab, rootMeanSquare, toLightnessEAL };
|
package/dist/index.global.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var Chromametry=(()=>{var v=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var O=Object.prototype.hasOwnProperty;var N=(m,t)=>{for(var s in t)v(m,s,{get:t[s],enumerable:!0})},V=(m,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of j(t))!O.call(m,e)&&e!==s&&v(m,e,{get:()=>t[e],enumerable:!(n=G(t,e))||n.enumerable});return m};var $=m=>V(v({},"__esModule",{value:!0}),m);var et={};N(et,{Palette:()=>T,Ramp:()=>q,Shade:()=>y,calcDeltaE2000:()=>P,calcScore:()=>L,calcStatistics:()=>nt,createMonotone:()=>E,cssRgbToRgb:()=>st,fromLightnessEAL:()=>J,hexToRgb:()=>C,labToLch:()=>k,labToRgb:()=>tt,lchToLab:()=>Q,rgbToHex:()=>Z,rgbToLab:()=>S,rootMeanSquare:()=>x,toLightnessEAL:()=>_});var F=m=>{let t=s=>{let n=Math.max(0,Math.min(1,s)),e=n<=.0031308?12.92*n:1.055*Math.pow(n,1/2.4)-.055;return Math.max(0,Math.min(255,Math.round(e*255)))};return m.map(t)},K=m=>{let t=s=>s>.04045?Math.pow((s+.055)/1.055,2.4):s/12.92;return m.map(t)},Z=m=>{let[t,s,n]=F(m);return t=t.toString(16).padStart(2,"0"),s=s.toString(16).padStart(2,"0"),n=n.toString(16).padStart(2,"0"),`#${t}${s}${n}`},C=m=>{let t=parseInt(m.slice(1,3),16)/255,s=parseInt(m.slice(3,5),16)/255,n=parseInt(m.slice(5,7),16)/255;return K([t,s,n])},_=m=>{let[t,s,n]=m,e=Math.sqrt(s*s+n*n),a=(Math.atan2(n,s)*180/Math.PI+360)%360,h=.1644,u=.0603,r=.1307,i=.006,l=h*Math.abs(Math.sin((a-90)/2*(Math.PI/180)))+u,c=0;return(a<=90||a>=270)&&(c=r*Math.abs(Math.cos(a*(Math.PI/180)))+i),t+(l+c)*e},J=(m,t)=>{let[,s,n]=t,e=Math.sqrt(s*s+n*n),a=(Math.atan2(n,s)*180/Math.PI+360)%360,h=.1644,u=.0603,r=.1307,i=.006,l=h*Math.abs(Math.sin((a-90)/2*(Math.PI/180)))+u,c=0;return(a<=90||a>=270)&&(c=r*Math.abs(Math.cos(a*(Math.PI/180)))+i),Math.max(0,m-(l+c)*e)},Q=m=>{let[t,s,n]=m,e=n*Math.PI/180;return[t,s*Math.cos(e),s*Math.sin(e)]},S=m=>{let[t,s,n]=m,e=.4124564*t+.3575761*s+.1804375*n,o=.2126729*t+.7151522*s+.072175*n,a=.0193339*t+.119192*s+.9503041*n,h=.95047,u=1,r=1.08883,i=g=>g>.008856?Math.cbrt(g):7.787*g+16/116,l=i(e/h),c=i(o/u),p=i(a/r);return[116*c-16,500*(l-c),200*(c-p)]},tt=m=>{let[t,s,n]=m,e=(t+16)/116,o=s/500+e,a=e-n/200,h=g=>g**3>.008856?g**3:(g-16/116)/7.787,u=.95047,r=1,i=1.08883,l=h(o)*u,c=h(e)*r,p=h(a)*i;return[3.2404542*l-1.5371385*c-.4985314*p,-.969266*l+1.8760108*c+.041556*p,.0556434*l-.2040259*c+1.0572252*p]},k=m=>{let[t,s,n]=m,e=Math.sqrt(s*s+n*n);if(e<1e-4)return[t,0,0];let a=(Math.atan2(n,s)*180/Math.PI+360)%360;return a>=359.9999&&(a=0),[t,e,a]},P=(m,t)=>{let[s,n,e]=m,[o,a,h]=t,u=(s+o)/2,r=Math.sqrt(n*n+e*e),i=Math.sqrt(a*a+h*h),l=(r+i)/2,c=.5*(1-Math.sqrt(Math.pow(l,7)/(Math.pow(l,7)+Math.pow(25,7)))),p=n*(1+c),g=a*(1+c),M=Math.sqrt(p*p+e*e),b=Math.sqrt(g*g+h*h),w=(M+b)/2,d=Math.atan2(e,p)*180/Math.PI+(Math.atan2(e,p)<0?360:0),f=Math.atan2(h,g)*180/Math.PI+(Math.atan2(h,g)<0?360:0),R=f-d;Math.abs(R)>180&&(R+=f<=d?360:-360);let I=Math.abs(d-f)>180?(d+f+360)/2:(d+f)/2,U=1-.17*Math.cos((I-30)*Math.PI/180)+.24*Math.cos(2*I*Math.PI/180)+.32*Math.cos((3*I+6)*Math.PI/180)-.2*Math.cos((4*I-63)*Math.PI/180),W=o-s,A=b-M,D=2*Math.sqrt(M*b)*Math.sin(R/2*Math.PI/180),X=1+.015*Math.pow(u-50,2)/Math.sqrt(20+Math.pow(u-50,2)),H=1+.045*w,Y=1+.015*w*U,z=30*Math.exp(-Math.pow((I-275)/25,2)),B=-(2*Math.sqrt(Math.pow(w,7)/(Math.pow(w,7)+Math.pow(25,7))))*Math.sin(2*z*Math.PI/180);return Math.sqrt(Math.pow(W/X,2)+Math.pow(A/H,2)+Math.pow(D/Y,2)+B*(A/H)*(D/Y))},st=m=>{let t=m.match(/\d+(\.\d+)?/g);if(!t||t.length<3)throw new Error("Invalid CSS rgb()");let s=n=>{let e=n/255;return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)};return[s(Number(t[0])),s(Number(t[1])),s(Number(t[2]))]},E=m=>{if(m.length<1)return r=>0;let t=[...m].sort((r,i)=>r[0]-i[0]),s=[];for(let r=0;r<t.length;r++)(r===0||t[r][0]!==t[r-1][0])&&s.push(t[r]);let n=s.length;if(n===1)return r=>s[0][1];let e=s.map(r=>r[0]),o=s.map(r=>r[1]),a=[],h=[];for(let r=0;r<n-1;r++)a[r]=e[r+1]-e[r],h[r]=(o[r+1]-o[r])/a[r];let u=new Array(n);u[0]=h[0],u[n-1]=h[n-2];for(let r=1;r<n-1;r++){let i=h[r-1],l=h[r];if(i*l<=0)u[r]=0;else{let c=(1+a[r]/(a[r-1]+a[r]))/3;u[r]=i*l/((1-c)*i+c*l)}}return r=>{if(r<=e[0])return o[0];if(r>=e[n-1])return o[n-1];let i=0,l=n-2,c=0;for(;i<=l;){let f=Math.floor((i+l)/2);if(r>=e[f]&&r<=e[f+1]){c=f;break}r<e[f]?l=f-1:i=f+1}let p=a[c],g=(r-e[c])/p,M=g*g,b=M*g,w=u[c]*p,d=u[c+1]*p;return(2*b-3*M+1)*o[c]+(b-2*M+g)*w+(-2*b+3*M)*o[c+1]+(b-M)*d}};function x(m){let t=m.length;if(t===0)return 0;let s=0;for(let n=0;n<t;n++)s+=m[n]*m[n];return Math.sqrt(s/t)}var nt=m=>{let t=m.length;if(t===0)return{min:0,max:0,avg:0};let s=m[0],n=m[0],e=0;for(let o=0;o<t;o++){let a=m[o];a<s&&(s=a),a>n&&(n=a),e+=a}return{min:s,max:n,avg:e/t}},L=m=>{let t=m.length;if(t===0)return 0;let s=1e-6,n=m.reduce((a,h)=>a*(h+s),1),e=Math.pow(n,1/t),o=Math.max(0,Math.min(1,e));return parseFloat((o*100).toFixed(2))};var y=class{constructor(t){this.hex=t}get rgb(){return C(this.hex)}get lab(){return S(this.rgb)}get lch(){return k(this.lab)}get lightness(){let[t,s,n]=this.lab,e=Math.sqrt(s*s+n*n),a=(Math.atan2(n,s)*180/Math.PI+360)%360,h=.1644,u=.0603,r=.1307,i=.006,l=h*Math.abs(Math.sin((a-90)/2*(Math.PI/180)))+u,c=0;return(a<=90||a>=270)&&(c=r*Math.abs(Math.cos(a*(Math.PI/180)))+i),t+(l+c)*e}get chroma(){return this.lch[1]}get hue(){return this.lch[2]}get luminance(){let[t,s,n]=this.rgb;return .2126*t+.7152*s+.0722*n}get wcag(){return(Math.max(this.luminance,1)+.05)/(Math.min(this.luminance,1)+.05)}get apca(){let t=o=>o>5e-4?o:o+Math.pow(5e-4-o,.8),s=t(this.luminance),n=t(1),e=(Math.pow(s,.56)-Math.pow(n,.56))*100;return Math.abs(e)<.1?0:(e=e>0?e<1?0:e-.25:e>-1?0:e+.25,Math.round(e))}};var q=class{constructor(t=[],s="brand"){this.shades=t.map(n=>new y(n)),this.name=s}get colors(){return this.shades.map(t=>t.hex)}get peakChroma(){let t=this.colors.slice(2,-2),s="",n=-1/0;for(let e of t){let o=new y(e);o.chroma>n&&(n=o.chroma,s=e)}return s}get steps(){return this.colors.length}get baseColor(){return this.colors.length===0?"":this.peakChroma||this.colors[Math.floor(this.colors.length/2)]}get baseIndex(){return this.colors.length===0?-1:this.colors.findIndex(t=>t.toLowerCase()===this.baseColor.toLowerCase())}get wcag(){let t=this.shades,s=t.length,n=s-1,e={};for(let o of[30,45,70]){let a=o/10,h=n,u=0;for(let r=1;r<s;r++){let i=1/0;for(let l=0;l<s-r;l++){let c=t[l].luminance,p=t[l+r].luminance,g=(Math.max(c,p)+.05)/(Math.min(c,p)+.05);g<i&&(i=g)}if(i>=a){h=r,u=i;break}r===n&&(u=i)}e[o]={efficiency:h/n,target:a,span:h,value:u}}return e}get apca(){let t=this.shades,s=t.length,n=s-1,e={},o=(a,h)=>{let u=c=>c>5e-4?c:c+Math.pow(5e-4-c,.8),r=u(a),i=u(h),l=(Math.pow(r,.56)-Math.pow(i,.56))*100;return Math.abs(l)<.1?0:(l=l>0?l<1?0:l-.25:l>-1?0:l+.25,Math.round(l))};for(let a of[45,60,75]){let h=a,u=n,r=0;for(let i=1;i<s;i++){let l=1/0;for(let c=0;c<s-i;c++){let p=Math.max(Math.abs(o(t[c+i].luminance,t[c].luminance)),Math.abs(o(t[c].luminance,t[c+i].luminance)));p<l&&(l=p)}if(l>=h){u=i,r=l;break}i===n&&(r=l)}e[a]={efficiency:u/n,target:h,span:u,value:r}}return e}get contrasts(){return{wcag:this.wcag,apca:this.apca}}get deltaECurve(){let t=[0];for(let s=1;s<this.shades.length;s++){let n=P(this.shades[s-1].lab,this.shades[s].lab);t.push(t[s-1]+n)}return t}get unwrapHues(){let t=this.shades.map(n=>n.hue).slice(1,-1);if(t.length===0)return[];let s=[t[0]];for(let n=1;n<t.length;n++){let e=t[n]-t[n-1];e>180?e-=360:e<-180&&(e+=360),s.push(s[n-1]+e)}return s}get lightnessLinearity(){let t=this.shades.map(p=>p.lightness),s=t.length;if(s<2)return 1;let n=0,e=0,o=0,a=0;for(let p=0;p<s;p++)n+=p,e+=t[p],o+=p*t[p],a+=p*p;let h=s*a-n*n;if(Math.abs(h)<1e-10)return 1;let u=(s*o-n*e)/h,r=(e-u*n)/s;if(Math.abs(u*(s-1))<.001)return 1;let l=0,c=0;for(let p=0;p<s;p++){let g=u*p+r,M=t[p]-g;l+=M*M;let b=Math.max(g-Math.min(r,u*(s-1)+r),Math.max(r,u*(s-1)+r)-g);c+=b*b}return Math.max(0,Math.min(1,1-Math.sqrt(l/s)/Math.sqrt(c/s)))}get chromaSmoothness(){let t=this.shades.map(c=>c.chroma),s=t.length;if(s<3)return 1;let n=133.8,e=Math.max(...t);if(e<=.01)return 1;let o=t.map(c=>c/e*n),a=Math.min(...o),h=Math.max(...o),u=o.findIndex(c=>c===h),r=E([[0,o[0]],[u,h],[s-1,o[s-1]]]),i=0,l=0;for(let c=0;c<s;c++){let p=r(c),g=o[c]-p;i+=g*g,l+=Math.pow(Math.max(p-a,h-p),2)}return Math.max(0,Math.min(1,1-Math.sqrt(i/s)/Math.sqrt(l/s)))}get spacingUniformity(){let t=this.deltaECurve,s=t.length;if(s<2)return 1;let n=[];for(let h=1;h<s;h++){let u=t[h]-t[h-1];if(u<0)return 0;n.push(u)}let e=n.reduce((h,u)=>h+u,0)/n.length;if(e<=1e-6)return 0;let o=0;for(let h of n)o+=Math.pow(h-e,2);let a=Math.sqrt(o/n.length)/e;return Math.max(0,Math.min(1,1/(1+a)))}get hueStability(){var a,h,u;let t=this.unwrapHues,s=t.length;if(s<2)return 1;let n=(u=(h=t[this.baseIndex-1])!=null?h:(a=this.shades[this.baseIndex])==null?void 0:a.hue)!=null?u:0,e=0,o=0;for(let r=0;r<s;r++){let i=Math.abs(t[r]-n)%360;i>180&&(i=360-i),e+=i*i;let l=r/(s-1)*180;o+=l*l}return Math.max(0,Math.min(1,1-Math.sqrt(e/s)/(Math.sqrt(o/s)||1)))}get contrastEfficiency(){let t=this.wcag[45].span,s=this.steps;if(s<=1)return 1;let n=.5,e=t/s,o=n*((s-1)/s);return e<=o?1:e>=1?0:(1-e)/(1-o)}get metrics(){return{lightnessLinearity:this.lightnessLinearity,chromaSmoothness:this.chromaSmoothness,spacingUniformity:this.spacingUniformity,hueStability:this.hueStability,contrastEfficiency:this.contrastEfficiency}}get score(){return L(Object.values(this.metrics))}};var T=class{constructor(t={},s="palette"){this.ramps=Object.entries(t).map(([n,e])=>new q(e,n)),this.name=s}get colors(){return Object.fromEntries(this.ramps.map(t=>[t.name,t.colors]))}get steps(){var t;return((t=this.ramps[0])==null?void 0:t.steps)||0}get direction(){var e;let t=(e=this.ramps[0])==null?void 0:e.colors;if(!(t!=null&&t.length))return"lighten";let s=S(C(t[0])),n=S(C(t[t.length-1]));return s[0]>n[0]?"darken":"lighten"}get wcag(){var s;let t={};for(let n of[30,45,70]){let e=this.ramps.map(r=>r.wcag[n]),o=((s=this.ramps[0])==null?void 0:s.steps)||0,a=Math.max(...e.map(r=>(r==null?void 0:r.span)||0)),h=e.reduce((r,i)=>r+((i==null?void 0:i.value)||0),0),u=e[0];t[n]={target:(u==null?void 0:u.target)||0,span:a,value:h/(this.ramps.length||1),efficiency:a/(o-1||1)}}return t}get apca(){var s;let t={};for(let n of[45,60,75]){let e=this.ramps.map(r=>r.apca[n]),o=((s=this.ramps[0])==null?void 0:s.steps)||0,a=Math.max(...e.map(r=>(r==null?void 0:r.span)||0)),h=e.reduce((r,i)=>r+((i==null?void 0:i.value)||0),0),u=e[0];t[n]={target:(u==null?void 0:u.target)||0,span:a,value:h/(this.ramps.length||1),efficiency:a/(o-1||1)}}return t}get contrasts(){return{wcag:this.wcag,apca:this.apca}}get metrics(){return{contrastEfficiency:x(this.ramps.map(t=>t.contrastEfficiency)),lightnessLinearity:x(this.ramps.map(t=>t.lightnessLinearity)),chromaSmoothness:x(this.ramps.map(t=>t.chromaSmoothness)),hueStability:x(this.ramps.map(t=>t.hueStability)),spacingUniformity:x(this.ramps.map(t=>t.spacingUniformity))}}get score(){return L(Object.values(this.metrics))}};return $(et);})();
|
|
1
|
+
"use strict";var Chromametry=(()=>{var L=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var U=Object.prototype.hasOwnProperty;var V=(u,n)=>{for(var t in n)L(u,t,{get:n[t],enumerable:!0})},W=(u,n,t,s)=>{if(n&&typeof n=="object"||typeof n=="function")for(let e of N(n))!U.call(u,e)&&e!==t&&L(u,e,{get:()=>n[e],enumerable:!(s=G(n,e))||s.enumerable});return u};var $=u=>W(L({},"__esModule",{value:!0}),u);var st={};V(st,{Ramp:()=>y,Swatch:()=>I,calcDeltaE2000:()=>v,calcScore:()=>P,calcStatistics:()=>nt,createMonotone:()=>k,cssRgbToRgb:()=>Q,fromLightnessEAL:()=>j,hexToRgb:()=>w,labToLch:()=>R,labToRgb:()=>J,lchToLab:()=>O,rgbToHex:()=>Z,rgbToLab:()=>C,rootMeanSquare:()=>tt,toLightnessEAL:()=>_});var F=u=>{let n=t=>{let s=Math.max(0,Math.min(1,t)),e=s<=.0031308?12.92*s:1.055*Math.pow(s,1/2.4)-.055;return Math.max(0,Math.min(255,Math.round(e*255)))};return u.map(n)},K=u=>{let n=t=>t>.04045?Math.pow((t+.055)/1.055,2.4):t/12.92;return u.map(n)},Z=u=>{let[n,t,s]=F(u);return n=n.toString(16).padStart(2,"0"),t=t.toString(16).padStart(2,"0"),s=s.toString(16).padStart(2,"0"),`#${n}${t}${s}`},w=u=>{let n=parseInt(u.slice(1,3),16)/255,t=parseInt(u.slice(3,5),16)/255,s=parseInt(u.slice(5,7),16)/255;return K([n,t,s])},_=u=>{let[n,t,s]=u,e=Math.sqrt(t*t+s*s),a=(Math.atan2(s,t)*180/Math.PI+360)%360,c=.1644,m=.0603,r=.1307,i=.006,l=c*Math.abs(Math.sin((a-90)/2*(Math.PI/180)))+m,o=0;return(a<=90||a>=270)&&(o=r*Math.abs(Math.cos(a*(Math.PI/180)))+i),n+(l+o)*e},j=(u,n)=>{let[,t,s]=n,e=Math.sqrt(t*t+s*s),a=(Math.atan2(s,t)*180/Math.PI+360)%360,c=.1644,m=.0603,r=.1307,i=.006,l=c*Math.abs(Math.sin((a-90)/2*(Math.PI/180)))+m,o=0;return(a<=90||a>=270)&&(o=r*Math.abs(Math.cos(a*(Math.PI/180)))+i),Math.max(0,u-(l+o)*e)},O=u=>{let[n,t,s]=u,e=s*Math.PI/180;return[n,t*Math.cos(e),t*Math.sin(e)]},C=u=>{let[n,t,s]=u,e=.4124564*n+.3575761*t+.1804375*s,h=.2126729*n+.7151522*t+.072175*s,a=.0193339*n+.119192*t+.9503041*s,c=.95047,m=1,r=1.08883,i=b=>b>.008856?Math.cbrt(b):7.787*b+16/116,l=i(e/c),o=i(h/m),M=i(a/r);return[116*o-16,500*(l-o),200*(o-M)]},J=u=>{let[n,t,s]=u,e=(n+16)/116,h=t/500+e,a=e-s/200,c=b=>b**3>.008856?b**3:(b-16/116)/7.787,m=.95047,r=1,i=1.08883,l=c(h)*m,o=c(e)*r,M=c(a)*i;return[3.2404542*l-1.5371385*o-.4985314*M,-.969266*l+1.8760108*o+.041556*M,.0556434*l-.2040259*o+1.0572252*M]},R=u=>{let[n,t,s]=u,e=Math.sqrt(t*t+s*s);if(e<1e-4)return[n,0,0];let a=(Math.atan2(s,t)*180/Math.PI+360)%360;return a>=359.9999&&(a=0),[n,e,a]},v=(u,n)=>{let[t,s,e]=u,[h,a,c]=n,m=(t+h)/2,r=Math.sqrt(s*s+e*e),i=Math.sqrt(a*a+c*c),l=(r+i)/2,o=.5*(1-Math.sqrt(Math.pow(l,7)/(Math.pow(l,7)+Math.pow(25,7)))),M=s*(1+o),b=a*(1+o),f=Math.sqrt(M*M+e*e),p=Math.sqrt(b*b+c*c),d=(f+p)/2,x=Math.atan2(e,M)*180/Math.PI+(Math.atan2(e,M)<0?360:0),g=Math.atan2(c,b)*180/Math.PI+(Math.atan2(c,b)<0?360:0),q=g-x;Math.abs(q)>180&&(q+=g<=x?360:-360);let S=Math.abs(x-g)>180?(x+g+360)/2:(x+g)/2,H=1-.17*Math.cos((S-30)*Math.PI/180)+.24*Math.cos(2*S*Math.PI/180)+.32*Math.cos((3*S+6)*Math.PI/180)-.2*Math.cos((4*S-63)*Math.PI/180),Y=h-t,E=p-f,T=2*Math.sqrt(f*p)*Math.sin(q/2*Math.PI/180),A=1+.015*Math.pow(m-50,2)/Math.sqrt(20+Math.pow(m-50,2)),B=1+.045*d,D=1+.015*d*H,X=30*Math.exp(-Math.pow((S-275)/25,2)),z=-(2*Math.sqrt(Math.pow(d,7)/(Math.pow(d,7)+Math.pow(25,7))))*Math.sin(2*X*Math.PI/180);return Math.sqrt(Math.pow(Y/A,2)+Math.pow(E/B,2)+Math.pow(T/D,2)+z*(E/B)*(T/D))},Q=u=>{let n=u.match(/\d+(\.\d+)?/g);if(!n||n.length<3)throw new Error("Invalid CSS rgb()");let t=s=>{let e=s/255;return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)};return[t(Number(n[0])),t(Number(n[1])),t(Number(n[2]))]},k=u=>{if(u.length<1)return r=>0;let n=[...u].sort((r,i)=>r[0]-i[0]),t=[];for(let r=0;r<n.length;r++)(r===0||n[r][0]!==n[r-1][0])&&t.push(n[r]);let s=t.length;if(s===1)return r=>t[0][1];let e=t.map(r=>r[0]),h=t.map(r=>r[1]),a=[],c=[];for(let r=0;r<s-1;r++)a[r]=e[r+1]-e[r],c[r]=(h[r+1]-h[r])/a[r];let m=new Array(s);m[0]=c[0],m[s-1]=c[s-2];for(let r=1;r<s-1;r++){let i=c[r-1],l=c[r];if(i*l<=0)m[r]=0;else{let o=(1+a[r]/(a[r-1]+a[r]))/3;m[r]=i*l/((1-o)*i+o*l)}}return r=>{if(r<=e[0])return h[0];if(r>=e[s-1])return h[s-1];let i=0,l=s-2,o=0;for(;i<=l;){let g=Math.floor((i+l)/2);if(r>=e[g]&&r<=e[g+1]){o=g;break}r<e[g]?l=g-1:i=g+1}let M=a[o],b=(r-e[o])/M,f=b*b,p=f*b,d=m[o]*M,x=m[o+1]*M;return(2*p-3*f+1)*h[o]+(p-2*f+b)*d+(-2*p+3*f)*h[o+1]+(p-f)*x}};function tt(u){let n=u.length;if(n===0)return 0;let t=0;for(let s=0;s<n;s++)t+=u[s]*u[s];return Math.sqrt(t/n)}var nt=u=>{let n=u.length;if(n===0)return{min:0,max:0,avg:0};let t=u[0],s=u[0],e=0;for(let h=0;h<n;h++){let a=u[h];a<t&&(t=a),a>s&&(s=a),e+=a}return{min:t,max:s,avg:e/n}},P=u=>{let n=u.length;if(n===0)return 0;let t=1e-6,s=u.reduce((a,c)=>a*(c+t),1),e=Math.pow(s,1/n),h=Math.max(0,Math.min(1,e));return parseFloat((h*100).toFixed(2))};var I=class{constructor(n){this.hex=n}get rgb(){return w(this.hex)}get lab(){return C(this.rgb)}get lch(){return R(this.lab)}get lightness(){let[n,t,s]=this.lab,e=Math.sqrt(t*t+s*s),a=(Math.atan2(s,t)*180/Math.PI+360)%360,c=.1644,m=.0603,r=.1307,i=.006,l=c*Math.abs(Math.sin((a-90)/2*(Math.PI/180)))+m,o=0;return(a<=90||a>=270)&&(o=r*Math.abs(Math.cos(a*(Math.PI/180)))+i),n+(l+o)*e}get chroma(){return this.lch[1]}get hue(){return this.lch[2]}get luminance(){let[n,t,s]=this.rgb;return .2126*n+.7152*t+.0722*s}get wcag(){return(Math.max(this.luminance,1)+.05)/(Math.min(this.luminance,1)+.05)}get apca(){let n=h=>h>5e-4?h:h+Math.pow(5e-4-h,.8),t=n(this.luminance),s=n(1),e=(Math.pow(t,.56)-Math.pow(s,.56))*100;return Math.abs(e)<.1?0:(e=e>0?e<1?0:e-.25:e>-1?0:e+.25,Math.round(e))}};var y=class{constructor(n=[],t="brand"){this.swatches=n.map(s=>new I(s)),this.name=t}get colors(){return this.swatches.map(n=>n.hex)}get peakChroma(){let n=this.colors.slice(2,-2),t="",s=-1/0;for(let e of n){let h=new I(e);h.chroma>s&&(s=h.chroma,t=e)}return s<6?this.colors[Math.ceil(this.steps/2)]:t}get steps(){return this.colors.length}get direction(){if(this.colors.length===0)return"lighten";let n=C(w(this.colors[0])),t=C(w(this.colors[this.colors.length-1]));return n[0]>t[0]?"darken":"lighten"}get baseColor(){return this.colors.length===0?"":this.peakChroma||this.colors[Math.floor(this.colors.length/2)]}get baseIndex(){return this.colors.length===0?-1:this.colors.findIndex(n=>n.toLowerCase()===this.baseColor.toLowerCase())}get wcag(){let n=this.swatches,t=n.length,s=t-1,e={};for(let h of[30,45,70]){let a=h/10,c=s,m=0;for(let r=1;r<t;r++){let i=1/0;for(let l=0;l<t-r;l++){let o=n[l].luminance,M=n[l+r].luminance,b=(Math.max(o,M)+.05)/(Math.min(o,M)+.05);b<i&&(i=b)}if(i>=a){c=r,m=i;break}r===s&&(m=i)}e[h]={efficiency:c/s,target:a,span:c,value:m}}return e}get apca(){let n=this.swatches,t=n.length,s=t-1,e={},h=(a,c)=>{let i=a<.022?a+Math.pow(.022-a,1.414):a,l=c<.022?c+Math.pow(.022-c,1.414):c,o=l>=i?(Math.pow(l,.56)-Math.pow(i,.57))*114:(Math.pow(l,.65)-Math.pow(i,.62))*114;return Math.abs(o)<10?0:(o=o>0?o-2.7:o+2.7,Math.round(o))};for(let a of[45,60,75]){let c=a,m=s,r=0;for(let i=1;i<t;i++){let l=1/0;for(let o=0;o<t-i;o++){let M=n[o].luminance>n[o+i].luminance?n[o].luminance:n[o+i].luminance,b=n[o].luminance>n[o+i].luminance?n[o+i].luminance:n[o].luminance,f=Math.abs(h(b,M));f<l&&(l=f)}if(l>=c){m=i,r=l;break}i===s&&(r=l)}e[a]={efficiency:m/s,target:c,span:m,value:r}}return e}get contrasts(){return{wcag:this.wcag,apca:this.apca}}get deltaECurve(){let n=[0];for(let t=1;t<this.swatches.length;t++){let s=v(this.swatches[t-1].lab,this.swatches[t].lab);n.push(n[t-1]+s)}return n}get unwrapHues(){let n=this.swatches.map(s=>s.hue).slice(1,-1);if(n.length===0)return[];let t=[n[0]];for(let s=1;s<n.length;s++){let e=n[s]-n[s-1];e>180?e-=360:e<-180&&(e+=360),t.push(t[s-1]+e)}return t}get lightnessLinearity(){let n=this.swatches.map(M=>M.lightness),t=n.length;if(t<2)return 1;let s=0,e=0,h=0,a=0;for(let M=0;M<t;M++)s+=M,e+=n[M],h+=M*n[M],a+=M*M;let c=t*a-s*s;if(Math.abs(c)<1e-10)return 1;let m=(t*h-s*e)/c,r=(e-m*s)/t;if(Math.abs(m*(t-1))<.001)return 1;let l=0,o=0;for(let M=0;M<t;M++){let b=m*M+r,f=n[M]-b;l+=f*f;let p=Math.max(b-Math.min(r,m*(t-1)+r),Math.max(r,m*(t-1)+r)-b);o+=p*p}return Math.max(0,Math.min(1,1-Math.sqrt(l/t)/Math.sqrt(o/t)))}get chromaSmoothness(){let n=this.swatches.map(o=>o.chroma),t=n.length;if(t<3)return 1;let s=133.8,e=Math.max(...n);if(e<=.01)return 1;let h=n.map(o=>o/e*s),a=Math.min(...h),c=Math.max(...h),m=h.findIndex(o=>o===c),r=k([[0,h[0]],[m,c],[t-1,h[t-1]]]),i=0,l=0;for(let o=0;o<t;o++){let M=r(o),b=h[o]-M;i+=b*b,l+=Math.pow(Math.max(M-a,c-M),2)}return Math.max(0,Math.min(1,1-Math.sqrt(i/t)/Math.sqrt(l/t)))}get spacingUniformity(){let n=this.deltaECurve,t=n.length;if(t<2)return 1;let s=[];for(let c=1;c<t;c++){let m=n[c]-n[c-1];if(m<0)return 0;s.push(m)}let e=s.reduce((c,m)=>c+m,0)/s.length;if(e<=1e-6)return 0;let h=0;for(let c of s)h+=Math.pow(c-e,2);let a=Math.sqrt(h/s.length)/e;return Math.max(0,Math.min(1,1/(1+a)))}get hueStability(){var a,c,m;let n=this.unwrapHues,t=n.length;if(t<2)return 1;let s=(m=(c=n[this.baseIndex-1])!=null?c:(a=this.swatches[this.baseIndex])==null?void 0:a.hue)!=null?m:0,e=0,h=0;for(let r=0;r<t;r++){let i=Math.abs(n[r]-s)%360;i>180&&(i=360-i),e+=i*i;let l=r/(t-1)*180;h+=l*l}return Math.max(0,Math.min(1,1-Math.sqrt(e/t)/(Math.sqrt(h/t)||1)))}get contrastEfficiency(){let n=this.wcag[45].span,t=this.steps;if(t<=1)return 1;let s=.5,e=n/t,h=s*((t-1)/t);return e<=h?1:e>=1?0:(1-e)/(1-h)}get metrics(){return{lightnessLinearity:this.lightnessLinearity,chromaSmoothness:this.chromaSmoothness,spacingUniformity:this.spacingUniformity,hueStability:this.hueStability,contrastEfficiency:this.contrastEfficiency}}get score(){return P(Object.values(this.metrics))}};return $(st);})();
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var B=l=>{let t=s=>{let n=Math.max(0,Math.min(1,s)),e=n<=.0031308?12.92*n:1.055*Math.pow(n,1/2.4)-.055;return Math.max(0,Math.min(255,Math.round(e*255)))};return l.map(t)},G=l=>{let t=s=>s>.04045?Math.pow((s+.055)/1.055,2.4):s/12.92;return l.map(t)},O=l=>{let[t,s,n]=B(l);return t=t.toString(16).padStart(2,"0"),s=s.toString(16).padStart(2,"0"),n=n.toString(16).padStart(2,"0"),`#${t}${s}${n}`},S=l=>{let t=parseInt(l.slice(1,3),16)/255,s=parseInt(l.slice(3,5),16)/255,n=parseInt(l.slice(5,7),16)/255;return G([t,s,n])},N=l=>{let[t,s,n]=l,e=Math.sqrt(s*s+n*n),a=(Math.atan2(n,s)*180/Math.PI+360)%360,h=.1644,u=.0603,r=.1307,i=.006,m=h*Math.abs(Math.sin((a-90)/2*(Math.PI/180)))+u,c=0;return(a<=90||a>=270)&&(c=r*Math.abs(Math.cos(a*(Math.PI/180)))+i),t+(m+c)*e},V=(l,t)=>{let[,s,n]=t,e=Math.sqrt(s*s+n*n),a=(Math.atan2(n,s)*180/Math.PI+360)%360,h=.1644,u=.0603,r=.1307,i=.006,m=h*Math.abs(Math.sin((a-90)/2*(Math.PI/180)))+u,c=0;return(a<=90||a>=270)&&(c=r*Math.abs(Math.cos(a*(Math.PI/180)))+i),Math.max(0,l-(m+c)*e)},$=l=>{let[t,s,n]=l,e=n*Math.PI/180;return[t,s*Math.cos(e),s*Math.sin(e)]},y=l=>{let[t,s,n]=l,e=.4124564*t+.3575761*s+.1804375*n,o=.2126729*t+.7151522*s+.072175*n,a=.0193339*t+.119192*s+.9503041*n,h=.95047,u=1,r=1.08883,i=g=>g>.008856?Math.cbrt(g):7.787*g+16/116,m=i(e/h),c=i(o/u),p=i(a/r);return[116*c-16,500*(m-c),200*(c-p)]},F=l=>{let[t,s,n]=l,e=(t+16)/116,o=s/500+e,a=e-n/200,h=g=>g**3>.008856?g**3:(g-16/116)/7.787,u=.95047,r=1,i=1.08883,m=h(o)*u,c=h(e)*r,p=h(a)*i;return[3.2404542*m-1.5371385*c-.4985314*p,-.969266*m+1.8760108*c+.041556*p,.0556434*m-.2040259*c+1.0572252*p]},T=l=>{let[t,s,n]=l,e=Math.sqrt(s*s+n*n);if(e<1e-4)return[t,0,0];let a=(Math.atan2(n,s)*180/Math.PI+360)%360;return a>=359.9999&&(a=0),[t,e,a]},A=(l,t)=>{let[s,n,e]=l,[o,a,h]=t,u=(s+o)/2,r=Math.sqrt(n*n+e*e),i=Math.sqrt(a*a+h*h),m=(r+i)/2,c=.5*(1-Math.sqrt(Math.pow(m,7)/(Math.pow(m,7)+Math.pow(25,7)))),p=n*(1+c),g=a*(1+c),M=Math.sqrt(p*p+e*e),b=Math.sqrt(g*g+h*h),x=(M+b)/2,d=Math.atan2(e,p)*180/Math.PI+(Math.atan2(e,p)<0?360:0),f=Math.atan2(h,g)*180/Math.PI+(Math.atan2(h,g)<0?360:0),R=f-d;Math.abs(R)>180&&(R+=f<=d?360:-360);let C=Math.abs(d-f)>180?(d+f+360)/2:(d+f)/2,Y=1-.17*Math.cos((C-30)*Math.PI/180)+.24*Math.cos(2*C*Math.PI/180)+.32*Math.cos((3*C+6)*Math.PI/180)-.2*Math.cos((4*C-63)*Math.PI/180),U=o-s,v=b-M,k=2*Math.sqrt(M*b)*Math.sin(R/2*Math.PI/180),W=1+.015*Math.pow(u-50,2)/Math.sqrt(20+Math.pow(u-50,2)),P=1+.045*x,E=1+.015*x*Y,X=30*Math.exp(-Math.pow((C-275)/25,2)),z=-(2*Math.sqrt(Math.pow(x,7)/(Math.pow(x,7)+Math.pow(25,7))))*Math.sin(2*X*Math.PI/180);return Math.sqrt(Math.pow(U/W,2)+Math.pow(v/P,2)+Math.pow(k/E,2)+z*(v/P)*(k/E))},K=l=>{let t=l.match(/\d+(\.\d+)?/g);if(!t||t.length<3)throw new Error("Invalid CSS rgb()");let s=n=>{let e=n/255;return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)};return[s(Number(t[0])),s(Number(t[1])),s(Number(t[2]))]},D=l=>{if(l.length<1)return r=>0;let t=[...l].sort((r,i)=>r[0]-i[0]),s=[];for(let r=0;r<t.length;r++)(r===0||t[r][0]!==t[r-1][0])&&s.push(t[r]);let n=s.length;if(n===1)return r=>s[0][1];let e=s.map(r=>r[0]),o=s.map(r=>r[1]),a=[],h=[];for(let r=0;r<n-1;r++)a[r]=e[r+1]-e[r],h[r]=(o[r+1]-o[r])/a[r];let u=new Array(n);u[0]=h[0],u[n-1]=h[n-2];for(let r=1;r<n-1;r++){let i=h[r-1],m=h[r];if(i*m<=0)u[r]=0;else{let c=(1+a[r]/(a[r-1]+a[r]))/3;u[r]=i*m/((1-c)*i+c*m)}}return r=>{if(r<=e[0])return o[0];if(r>=e[n-1])return o[n-1];let i=0,m=n-2,c=0;for(;i<=m;){let f=Math.floor((i+m)/2);if(r>=e[f]&&r<=e[f+1]){c=f;break}r<e[f]?m=f-1:i=f+1}let p=a[c],g=(r-e[c])/p,M=g*g,b=M*g,x=u[c]*p,d=u[c+1]*p;return(2*b-3*M+1)*o[c]+(b-2*M+g)*x+(-2*b+3*M)*o[c+1]+(b-M)*d}};function w(l){let t=l.length;if(t===0)return 0;let s=0;for(let n=0;n<t;n++)s+=l[n]*l[n];return Math.sqrt(s/t)}var Z=l=>{let t=l.length;if(t===0)return{min:0,max:0,avg:0};let s=l[0],n=l[0],e=0;for(let o=0;o<t;o++){let a=l[o];a<s&&(s=a),a>n&&(n=a),e+=a}return{min:s,max:n,avg:e/t}},L=l=>{let t=l.length;if(t===0)return 0;let s=1e-6,n=l.reduce((a,h)=>a*(h+s),1),e=Math.pow(n,1/t),o=Math.max(0,Math.min(1,e));return parseFloat((o*100).toFixed(2))};var I=class{constructor(t){this.hex=t}get rgb(){return S(this.hex)}get lab(){return y(this.rgb)}get lch(){return T(this.lab)}get lightness(){let[t,s,n]=this.lab,e=Math.sqrt(s*s+n*n),a=(Math.atan2(n,s)*180/Math.PI+360)%360,h=.1644,u=.0603,r=.1307,i=.006,m=h*Math.abs(Math.sin((a-90)/2*(Math.PI/180)))+u,c=0;return(a<=90||a>=270)&&(c=r*Math.abs(Math.cos(a*(Math.PI/180)))+i),t+(m+c)*e}get chroma(){return this.lch[1]}get hue(){return this.lch[2]}get luminance(){let[t,s,n]=this.rgb;return .2126*t+.7152*s+.0722*n}get wcag(){return(Math.max(this.luminance,1)+.05)/(Math.min(this.luminance,1)+.05)}get apca(){let t=o=>o>5e-4?o:o+Math.pow(5e-4-o,.8),s=t(this.luminance),n=t(1),e=(Math.pow(s,.56)-Math.pow(n,.56))*100;return Math.abs(e)<.1?0:(e=e>0?e<1?0:e-.25:e>-1?0:e+.25,Math.round(e))}};var q=class{constructor(t=[],s="brand"){this.shades=t.map(n=>new I(n)),this.name=s}get colors(){return this.shades.map(t=>t.hex)}get peakChroma(){let t=this.colors.slice(2,-2),s="",n=-1/0;for(let e of t){let o=new I(e);o.chroma>n&&(n=o.chroma,s=e)}return s}get steps(){return this.colors.length}get baseColor(){return this.colors.length===0?"":this.peakChroma||this.colors[Math.floor(this.colors.length/2)]}get baseIndex(){return this.colors.length===0?-1:this.colors.findIndex(t=>t.toLowerCase()===this.baseColor.toLowerCase())}get wcag(){let t=this.shades,s=t.length,n=s-1,e={};for(let o of[30,45,70]){let a=o/10,h=n,u=0;for(let r=1;r<s;r++){let i=1/0;for(let m=0;m<s-r;m++){let c=t[m].luminance,p=t[m+r].luminance,g=(Math.max(c,p)+.05)/(Math.min(c,p)+.05);g<i&&(i=g)}if(i>=a){h=r,u=i;break}r===n&&(u=i)}e[o]={efficiency:h/n,target:a,span:h,value:u}}return e}get apca(){let t=this.shades,s=t.length,n=s-1,e={},o=(a,h)=>{let u=c=>c>5e-4?c:c+Math.pow(5e-4-c,.8),r=u(a),i=u(h),m=(Math.pow(r,.56)-Math.pow(i,.56))*100;return Math.abs(m)<.1?0:(m=m>0?m<1?0:m-.25:m>-1?0:m+.25,Math.round(m))};for(let a of[45,60,75]){let h=a,u=n,r=0;for(let i=1;i<s;i++){let m=1/0;for(let c=0;c<s-i;c++){let p=Math.max(Math.abs(o(t[c+i].luminance,t[c].luminance)),Math.abs(o(t[c].luminance,t[c+i].luminance)));p<m&&(m=p)}if(m>=h){u=i,r=m;break}i===n&&(r=m)}e[a]={efficiency:u/n,target:h,span:u,value:r}}return e}get contrasts(){return{wcag:this.wcag,apca:this.apca}}get deltaECurve(){let t=[0];for(let s=1;s<this.shades.length;s++){let n=A(this.shades[s-1].lab,this.shades[s].lab);t.push(t[s-1]+n)}return t}get unwrapHues(){let t=this.shades.map(n=>n.hue).slice(1,-1);if(t.length===0)return[];let s=[t[0]];for(let n=1;n<t.length;n++){let e=t[n]-t[n-1];e>180?e-=360:e<-180&&(e+=360),s.push(s[n-1]+e)}return s}get lightnessLinearity(){let t=this.shades.map(p=>p.lightness),s=t.length;if(s<2)return 1;let n=0,e=0,o=0,a=0;for(let p=0;p<s;p++)n+=p,e+=t[p],o+=p*t[p],a+=p*p;let h=s*a-n*n;if(Math.abs(h)<1e-10)return 1;let u=(s*o-n*e)/h,r=(e-u*n)/s;if(Math.abs(u*(s-1))<.001)return 1;let m=0,c=0;for(let p=0;p<s;p++){let g=u*p+r,M=t[p]-g;m+=M*M;let b=Math.max(g-Math.min(r,u*(s-1)+r),Math.max(r,u*(s-1)+r)-g);c+=b*b}return Math.max(0,Math.min(1,1-Math.sqrt(m/s)/Math.sqrt(c/s)))}get chromaSmoothness(){let t=this.shades.map(c=>c.chroma),s=t.length;if(s<3)return 1;let n=133.8,e=Math.max(...t);if(e<=.01)return 1;let o=t.map(c=>c/e*n),a=Math.min(...o),h=Math.max(...o),u=o.findIndex(c=>c===h),r=D([[0,o[0]],[u,h],[s-1,o[s-1]]]),i=0,m=0;for(let c=0;c<s;c++){let p=r(c),g=o[c]-p;i+=g*g,m+=Math.pow(Math.max(p-a,h-p),2)}return Math.max(0,Math.min(1,1-Math.sqrt(i/s)/Math.sqrt(m/s)))}get spacingUniformity(){let t=this.deltaECurve,s=t.length;if(s<2)return 1;let n=[];for(let h=1;h<s;h++){let u=t[h]-t[h-1];if(u<0)return 0;n.push(u)}let e=n.reduce((h,u)=>h+u,0)/n.length;if(e<=1e-6)return 0;let o=0;for(let h of n)o+=Math.pow(h-e,2);let a=Math.sqrt(o/n.length)/e;return Math.max(0,Math.min(1,1/(1+a)))}get hueStability(){var a,h,u;let t=this.unwrapHues,s=t.length;if(s<2)return 1;let n=(u=(h=t[this.baseIndex-1])!=null?h:(a=this.shades[this.baseIndex])==null?void 0:a.hue)!=null?u:0,e=0,o=0;for(let r=0;r<s;r++){let i=Math.abs(t[r]-n)%360;i>180&&(i=360-i),e+=i*i;let m=r/(s-1)*180;o+=m*m}return Math.max(0,Math.min(1,1-Math.sqrt(e/s)/(Math.sqrt(o/s)||1)))}get contrastEfficiency(){let t=this.wcag[45].span,s=this.steps;if(s<=1)return 1;let n=.5,e=t/s,o=n*((s-1)/s);return e<=o?1:e>=1?0:(1-e)/(1-o)}get metrics(){return{lightnessLinearity:this.lightnessLinearity,chromaSmoothness:this.chromaSmoothness,spacingUniformity:this.spacingUniformity,hueStability:this.hueStability,contrastEfficiency:this.contrastEfficiency}}get score(){return L(Object.values(this.metrics))}};var H=class{constructor(t={},s="palette"){this.ramps=Object.entries(t).map(([n,e])=>new q(e,n)),this.name=s}get colors(){return Object.fromEntries(this.ramps.map(t=>[t.name,t.colors]))}get steps(){var t;return((t=this.ramps[0])==null?void 0:t.steps)||0}get direction(){var e;let t=(e=this.ramps[0])==null?void 0:e.colors;if(!(t!=null&&t.length))return"lighten";let s=y(S(t[0])),n=y(S(t[t.length-1]));return s[0]>n[0]?"darken":"lighten"}get wcag(){var s;let t={};for(let n of[30,45,70]){let e=this.ramps.map(r=>r.wcag[n]),o=((s=this.ramps[0])==null?void 0:s.steps)||0,a=Math.max(...e.map(r=>(r==null?void 0:r.span)||0)),h=e.reduce((r,i)=>r+((i==null?void 0:i.value)||0),0),u=e[0];t[n]={target:(u==null?void 0:u.target)||0,span:a,value:h/(this.ramps.length||1),efficiency:a/(o-1||1)}}return t}get apca(){var s;let t={};for(let n of[45,60,75]){let e=this.ramps.map(r=>r.apca[n]),o=((s=this.ramps[0])==null?void 0:s.steps)||0,a=Math.max(...e.map(r=>(r==null?void 0:r.span)||0)),h=e.reduce((r,i)=>r+((i==null?void 0:i.value)||0),0),u=e[0];t[n]={target:(u==null?void 0:u.target)||0,span:a,value:h/(this.ramps.length||1),efficiency:a/(o-1||1)}}return t}get contrasts(){return{wcag:this.wcag,apca:this.apca}}get metrics(){return{contrastEfficiency:w(this.ramps.map(t=>t.contrastEfficiency)),lightnessLinearity:w(this.ramps.map(t=>t.lightnessLinearity)),chromaSmoothness:w(this.ramps.map(t=>t.chromaSmoothness)),hueStability:w(this.ramps.map(t=>t.hueStability)),spacingUniformity:w(this.ramps.map(t=>t.spacingUniformity))}}get score(){return L(Object.values(this.metrics))}};export{H as Palette,q as Ramp,I as Shade,A as calcDeltaE2000,L as calcScore,Z as calcStatistics,D as createMonotone,K as cssRgbToRgb,V as fromLightnessEAL,S as hexToRgb,T as labToLch,F as labToRgb,$ as lchToLab,O as rgbToHex,y as rgbToLab,w as rootMeanSquare,N as toLightnessEAL};
|
|
1
|
+
var z=m=>{let n=t=>{let s=Math.max(0,Math.min(1,t)),e=s<=.0031308?12.92*s:1.055*Math.pow(s,1/2.4)-.055;return Math.max(0,Math.min(255,Math.round(e*255)))};return m.map(n)},G=m=>{let n=t=>t>.04045?Math.pow((t+.055)/1.055,2.4):t/12.92;return m.map(n)},U=m=>{let[n,t,s]=z(m);return n=n.toString(16).padStart(2,"0"),t=t.toString(16).padStart(2,"0"),s=s.toString(16).padStart(2,"0"),`#${n}${t}${s}`},C=m=>{let n=parseInt(m.slice(1,3),16)/255,t=parseInt(m.slice(3,5),16)/255,s=parseInt(m.slice(5,7),16)/255;return G([n,t,s])},V=m=>{let[n,t,s]=m,e=Math.sqrt(t*t+s*s),a=(Math.atan2(s,t)*180/Math.PI+360)%360,c=.1644,l=.0603,r=.1307,i=.006,u=c*Math.abs(Math.sin((a-90)/2*(Math.PI/180)))+l,o=0;return(a<=90||a>=270)&&(o=r*Math.abs(Math.cos(a*(Math.PI/180)))+i),n+(u+o)*e},W=(m,n)=>{let[,t,s]=n,e=Math.sqrt(t*t+s*s),a=(Math.atan2(s,t)*180/Math.PI+360)%360,c=.1644,l=.0603,r=.1307,i=.006,u=c*Math.abs(Math.sin((a-90)/2*(Math.PI/180)))+l,o=0;return(a<=90||a>=270)&&(o=r*Math.abs(Math.cos(a*(Math.PI/180)))+i),Math.max(0,m-(u+o)*e)},$=m=>{let[n,t,s]=m,e=s*Math.PI/180;return[n,t*Math.cos(e),t*Math.sin(e)]},I=m=>{let[n,t,s]=m,e=.4124564*n+.3575761*t+.1804375*s,h=.2126729*n+.7151522*t+.072175*s,a=.0193339*n+.119192*t+.9503041*s,c=.95047,l=1,r=1.08883,i=b=>b>.008856?Math.cbrt(b):7.787*b+16/116,u=i(e/c),o=i(h/l),M=i(a/r);return[116*o-16,500*(u-o),200*(o-M)]},F=m=>{let[n,t,s]=m,e=(n+16)/116,h=t/500+e,a=e-s/200,c=b=>b**3>.008856?b**3:(b-16/116)/7.787,l=.95047,r=1,i=1.08883,u=c(h)*l,o=c(e)*r,M=c(a)*i;return[3.2404542*u-1.5371385*o-.4985314*M,-.969266*u+1.8760108*o+.041556*M,.0556434*u-.2040259*o+1.0572252*M]},P=m=>{let[n,t,s]=m,e=Math.sqrt(t*t+s*s);if(e<1e-4)return[n,0,0];let a=(Math.atan2(s,t)*180/Math.PI+360)%360;return a>=359.9999&&(a=0),[n,e,a]},y=(m,n)=>{let[t,s,e]=m,[h,a,c]=n,l=(t+h)/2,r=Math.sqrt(s*s+e*e),i=Math.sqrt(a*a+c*c),u=(r+i)/2,o=.5*(1-Math.sqrt(Math.pow(u,7)/(Math.pow(u,7)+Math.pow(25,7)))),M=s*(1+o),b=a*(1+o),f=Math.sqrt(M*M+e*e),p=Math.sqrt(b*b+c*c),d=(f+p)/2,x=Math.atan2(e,M)*180/Math.PI+(Math.atan2(e,M)<0?360:0),g=Math.atan2(c,b)*180/Math.PI+(Math.atan2(c,b)<0?360:0),q=g-x;Math.abs(q)>180&&(q+=g<=x?360:-360);let w=Math.abs(x-g)>180?(x+g+360)/2:(x+g)/2,D=1-.17*Math.cos((w-30)*Math.PI/180)+.24*Math.cos(2*w*Math.PI/180)+.32*Math.cos((3*w+6)*Math.PI/180)-.2*Math.cos((4*w-63)*Math.PI/180),H=h-t,L=p-f,R=2*Math.sqrt(f*p)*Math.sin(q/2*Math.PI/180),Y=1+.015*Math.pow(l-50,2)/Math.sqrt(20+Math.pow(l-50,2)),v=1+.045*d,k=1+.015*d*D,A=30*Math.exp(-Math.pow((w-275)/25,2)),X=-(2*Math.sqrt(Math.pow(d,7)/(Math.pow(d,7)+Math.pow(25,7))))*Math.sin(2*A*Math.PI/180);return Math.sqrt(Math.pow(H/Y,2)+Math.pow(L/v,2)+Math.pow(R/k,2)+X*(L/v)*(R/k))},K=m=>{let n=m.match(/\d+(\.\d+)?/g);if(!n||n.length<3)throw new Error("Invalid CSS rgb()");let t=s=>{let e=s/255;return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)};return[t(Number(n[0])),t(Number(n[1])),t(Number(n[2]))]},E=m=>{if(m.length<1)return r=>0;let n=[...m].sort((r,i)=>r[0]-i[0]),t=[];for(let r=0;r<n.length;r++)(r===0||n[r][0]!==n[r-1][0])&&t.push(n[r]);let s=t.length;if(s===1)return r=>t[0][1];let e=t.map(r=>r[0]),h=t.map(r=>r[1]),a=[],c=[];for(let r=0;r<s-1;r++)a[r]=e[r+1]-e[r],c[r]=(h[r+1]-h[r])/a[r];let l=new Array(s);l[0]=c[0],l[s-1]=c[s-2];for(let r=1;r<s-1;r++){let i=c[r-1],u=c[r];if(i*u<=0)l[r]=0;else{let o=(1+a[r]/(a[r-1]+a[r]))/3;l[r]=i*u/((1-o)*i+o*u)}}return r=>{if(r<=e[0])return h[0];if(r>=e[s-1])return h[s-1];let i=0,u=s-2,o=0;for(;i<=u;){let g=Math.floor((i+u)/2);if(r>=e[g]&&r<=e[g+1]){o=g;break}r<e[g]?u=g-1:i=g+1}let M=a[o],b=(r-e[o])/M,f=b*b,p=f*b,d=l[o]*M,x=l[o+1]*M;return(2*p-3*f+1)*h[o]+(p-2*f+b)*d+(-2*p+3*f)*h[o+1]+(p-f)*x}};function Z(m){let n=m.length;if(n===0)return 0;let t=0;for(let s=0;s<n;s++)t+=m[s]*m[s];return Math.sqrt(t/n)}var _=m=>{let n=m.length;if(n===0)return{min:0,max:0,avg:0};let t=m[0],s=m[0],e=0;for(let h=0;h<n;h++){let a=m[h];a<t&&(t=a),a>s&&(s=a),e+=a}return{min:t,max:s,avg:e/n}},T=m=>{let n=m.length;if(n===0)return 0;let t=1e-6,s=m.reduce((a,c)=>a*(c+t),1),e=Math.pow(s,1/n),h=Math.max(0,Math.min(1,e));return parseFloat((h*100).toFixed(2))};var S=class{constructor(n){this.hex=n}get rgb(){return C(this.hex)}get lab(){return I(this.rgb)}get lch(){return P(this.lab)}get lightness(){let[n,t,s]=this.lab,e=Math.sqrt(t*t+s*s),a=(Math.atan2(s,t)*180/Math.PI+360)%360,c=.1644,l=.0603,r=.1307,i=.006,u=c*Math.abs(Math.sin((a-90)/2*(Math.PI/180)))+l,o=0;return(a<=90||a>=270)&&(o=r*Math.abs(Math.cos(a*(Math.PI/180)))+i),n+(u+o)*e}get chroma(){return this.lch[1]}get hue(){return this.lch[2]}get luminance(){let[n,t,s]=this.rgb;return .2126*n+.7152*t+.0722*s}get wcag(){return(Math.max(this.luminance,1)+.05)/(Math.min(this.luminance,1)+.05)}get apca(){let n=h=>h>5e-4?h:h+Math.pow(5e-4-h,.8),t=n(this.luminance),s=n(1),e=(Math.pow(t,.56)-Math.pow(s,.56))*100;return Math.abs(e)<.1?0:(e=e>0?e<1?0:e-.25:e>-1?0:e+.25,Math.round(e))}};var B=class{constructor(n=[],t="brand"){this.swatches=n.map(s=>new S(s)),this.name=t}get colors(){return this.swatches.map(n=>n.hex)}get peakChroma(){let n=this.colors.slice(2,-2),t="",s=-1/0;for(let e of n){let h=new S(e);h.chroma>s&&(s=h.chroma,t=e)}return s<6?this.colors[Math.ceil(this.steps/2)]:t}get steps(){return this.colors.length}get direction(){if(this.colors.length===0)return"lighten";let n=I(C(this.colors[0])),t=I(C(this.colors[this.colors.length-1]));return n[0]>t[0]?"darken":"lighten"}get baseColor(){return this.colors.length===0?"":this.peakChroma||this.colors[Math.floor(this.colors.length/2)]}get baseIndex(){return this.colors.length===0?-1:this.colors.findIndex(n=>n.toLowerCase()===this.baseColor.toLowerCase())}get wcag(){let n=this.swatches,t=n.length,s=t-1,e={};for(let h of[30,45,70]){let a=h/10,c=s,l=0;for(let r=1;r<t;r++){let i=1/0;for(let u=0;u<t-r;u++){let o=n[u].luminance,M=n[u+r].luminance,b=(Math.max(o,M)+.05)/(Math.min(o,M)+.05);b<i&&(i=b)}if(i>=a){c=r,l=i;break}r===s&&(l=i)}e[h]={efficiency:c/s,target:a,span:c,value:l}}return e}get apca(){let n=this.swatches,t=n.length,s=t-1,e={},h=(a,c)=>{let i=a<.022?a+Math.pow(.022-a,1.414):a,u=c<.022?c+Math.pow(.022-c,1.414):c,o=u>=i?(Math.pow(u,.56)-Math.pow(i,.57))*114:(Math.pow(u,.65)-Math.pow(i,.62))*114;return Math.abs(o)<10?0:(o=o>0?o-2.7:o+2.7,Math.round(o))};for(let a of[45,60,75]){let c=a,l=s,r=0;for(let i=1;i<t;i++){let u=1/0;for(let o=0;o<t-i;o++){let M=n[o].luminance>n[o+i].luminance?n[o].luminance:n[o+i].luminance,b=n[o].luminance>n[o+i].luminance?n[o+i].luminance:n[o].luminance,f=Math.abs(h(b,M));f<u&&(u=f)}if(u>=c){l=i,r=u;break}i===s&&(r=u)}e[a]={efficiency:l/s,target:c,span:l,value:r}}return e}get contrasts(){return{wcag:this.wcag,apca:this.apca}}get deltaECurve(){let n=[0];for(let t=1;t<this.swatches.length;t++){let s=y(this.swatches[t-1].lab,this.swatches[t].lab);n.push(n[t-1]+s)}return n}get unwrapHues(){let n=this.swatches.map(s=>s.hue).slice(1,-1);if(n.length===0)return[];let t=[n[0]];for(let s=1;s<n.length;s++){let e=n[s]-n[s-1];e>180?e-=360:e<-180&&(e+=360),t.push(t[s-1]+e)}return t}get lightnessLinearity(){let n=this.swatches.map(M=>M.lightness),t=n.length;if(t<2)return 1;let s=0,e=0,h=0,a=0;for(let M=0;M<t;M++)s+=M,e+=n[M],h+=M*n[M],a+=M*M;let c=t*a-s*s;if(Math.abs(c)<1e-10)return 1;let l=(t*h-s*e)/c,r=(e-l*s)/t;if(Math.abs(l*(t-1))<.001)return 1;let u=0,o=0;for(let M=0;M<t;M++){let b=l*M+r,f=n[M]-b;u+=f*f;let p=Math.max(b-Math.min(r,l*(t-1)+r),Math.max(r,l*(t-1)+r)-b);o+=p*p}return Math.max(0,Math.min(1,1-Math.sqrt(u/t)/Math.sqrt(o/t)))}get chromaSmoothness(){let n=this.swatches.map(o=>o.chroma),t=n.length;if(t<3)return 1;let s=133.8,e=Math.max(...n);if(e<=.01)return 1;let h=n.map(o=>o/e*s),a=Math.min(...h),c=Math.max(...h),l=h.findIndex(o=>o===c),r=E([[0,h[0]],[l,c],[t-1,h[t-1]]]),i=0,u=0;for(let o=0;o<t;o++){let M=r(o),b=h[o]-M;i+=b*b,u+=Math.pow(Math.max(M-a,c-M),2)}return Math.max(0,Math.min(1,1-Math.sqrt(i/t)/Math.sqrt(u/t)))}get spacingUniformity(){let n=this.deltaECurve,t=n.length;if(t<2)return 1;let s=[];for(let c=1;c<t;c++){let l=n[c]-n[c-1];if(l<0)return 0;s.push(l)}let e=s.reduce((c,l)=>c+l,0)/s.length;if(e<=1e-6)return 0;let h=0;for(let c of s)h+=Math.pow(c-e,2);let a=Math.sqrt(h/s.length)/e;return Math.max(0,Math.min(1,1/(1+a)))}get hueStability(){var a,c,l;let n=this.unwrapHues,t=n.length;if(t<2)return 1;let s=(l=(c=n[this.baseIndex-1])!=null?c:(a=this.swatches[this.baseIndex])==null?void 0:a.hue)!=null?l:0,e=0,h=0;for(let r=0;r<t;r++){let i=Math.abs(n[r]-s)%360;i>180&&(i=360-i),e+=i*i;let u=r/(t-1)*180;h+=u*u}return Math.max(0,Math.min(1,1-Math.sqrt(e/t)/(Math.sqrt(h/t)||1)))}get contrastEfficiency(){let n=this.wcag[45].span,t=this.steps;if(t<=1)return 1;let s=.5,e=n/t,h=s*((t-1)/t);return e<=h?1:e>=1?0:(1-e)/(1-h)}get metrics(){return{lightnessLinearity:this.lightnessLinearity,chromaSmoothness:this.chromaSmoothness,spacingUniformity:this.spacingUniformity,hueStability:this.hueStability,contrastEfficiency:this.contrastEfficiency}}get score(){return T(Object.values(this.metrics))}};export{B as Ramp,S as Swatch,y as calcDeltaE2000,T as calcScore,_ as calcStatistics,E as createMonotone,K as cssRgbToRgb,W as fromLightnessEAL,C as hexToRgb,P as labToLch,F as labToRgb,$ as lchToLab,U as rgbToHex,I as rgbToLab,Z as rootMeanSquare,V as toLightnessEAL};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chromametry",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Web-accessible Color Palette Metrics",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"test": "vitest",
|
|
11
11
|
"generate": "tsx scripts/generate.ts",
|
|
12
12
|
"build": "tsup",
|
|
13
|
-
"prepublishOnly": "npm run
|
|
13
|
+
"prepublishOnly": "npm run build"
|
|
14
14
|
},
|
|
15
15
|
"keywords": [
|
|
16
16
|
"color",
|