@newtonedev/colors 1.1.1 → 1.1.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/dist/config.d.ts CHANGED
@@ -17,15 +17,25 @@ export declare const DEFAULT_SCALE_STEPS = 26;
17
17
  */
18
18
  export declare const DEFAULT_HUE = 0;
19
19
  /**
20
- * Lightest step's lightness when the whites slider is at 0.
20
+ * Lightest step's lightness when the whites slider is at 0 (Display P3).
21
+ * P3's wider gamut can reproduce near-whites that clip in sRGB.
22
+ */
23
+ export declare const MIN_LIGHTEST_L_P3 = 0.98;
24
+ /**
25
+ * Lightest step's lightness when the whites slider is at 0 (sRGB).
21
26
  * slider 0 → L = MIN_LIGHTEST_L, slider 1 → L = 1.0 (pure white).
22
27
  */
23
- export declare const MIN_LIGHTEST_L = 0.96;
28
+ export declare const MIN_LIGHTEST_L = 0.92;
24
29
  /**
25
- * Darkest step's lightness when the darks slider is at 0.
30
+ * Darkest step's lightness when the darks slider is at 0 (sRGB).
26
31
  * slider 0 → L = MAX_DARKEST_L, slider 1 → L = 0.0 (pure black).
27
32
  */
28
- export declare const MAX_DARKEST_L = 0.16;
33
+ export declare const MAX_DARKEST_L = 0.2;
34
+ /**
35
+ * Darkest step's lightness when the darks slider is at 0 (Display P3).
36
+ * P3's wider gamut can reproduce near-blacks that clip in sRGB.
37
+ */
38
+ export declare const MAX_DARKEST_L_P3 = 0.14;
29
39
  /**
30
40
  * How far global grading reaches into the scale from each end (0–1).
31
41
  * Light grading fades to zero at t = GRADING_REACH.
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC;;;;GAIG;AACH,eAAO,MAAM,WAAW,IAAI,CAAC;AAI7B;;;GAGG;AACH,eAAO,MAAM,cAAc,OAAO,CAAC;AAEnC;;;GAGG;AACH,eAAO,MAAM,aAAa,OAAO,CAAC;AAIlC;;;;GAIG;AACH,eAAO,MAAM,aAAa,QAAQ,CAAC;AAEnC,wEAAwE;AACxE,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC;;;GAGG;AACH,eAAO,MAAM,WAAW,QAAQ,CAAC;AAEjC,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAIpC;;;;GAIG;AACH,eAAO,MAAM,cAAc,OAAO,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC;;;;GAIG;AACH,eAAO,MAAM,WAAW,IAAI,CAAC;AAI7B;;;GAGG;AACH,eAAO,MAAM,iBAAiB,OAAO,CAAC;AAEtC;;;GAGG;AACH,eAAO,MAAM,cAAc,OAAO,CAAC;AAEnC;;;GAGG;AACH,eAAO,MAAM,aAAa,MAAO,CAAC;AAElC;;;GAGG;AACH,eAAO,MAAM,gBAAgB,OAAO,CAAC;AAIrC;;;;GAIG;AACH,eAAO,MAAM,aAAa,QAAQ,CAAC;AAEnC,wEAAwE;AACxE,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC;;;GAGG;AACH,eAAO,MAAM,WAAW,QAAQ,CAAC;AAEjC,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAIpC;;;;GAIG;AACH,eAAO,MAAM,cAAc,OAAO,CAAC"}
package/dist/index.cjs CHANGED
@@ -362,8 +362,10 @@ function mix(a, b, t) {
362
362
  // src/config.ts
363
363
  var DEFAULT_SCALE_STEPS = 26;
364
364
  var DEFAULT_HUE = 0;
365
- var MIN_LIGHTEST_L = 0.96;
366
- var MAX_DARKEST_L = 0.16;
365
+ var MIN_LIGHTEST_L_P3 = 0.98;
366
+ var MIN_LIGHTEST_L = 0.92;
367
+ var MAX_DARKEST_L = 0.2;
368
+ var MAX_DARKEST_L_P3 = 0.14;
367
369
  var GRADING_REACH = 3 / 5;
368
370
  var MAX_GRADING_AMOUNT = 0.25;
369
371
  var GRADING_CHROMA_RATIO = 0.5;
@@ -421,21 +423,6 @@ function buildOneSidedGrade(hue, amount, light = false) {
421
423
  return light ? { light: { hue, amount } } : { dark: { hue, amount } };
422
424
  }
423
425
 
424
- // src/scale/dynamic-range.ts
425
- function resolveLightest(slider) {
426
- const s = Math.max(0, Math.min(1, slider));
427
- return MIN_LIGHTEST_L + s * (1 - MIN_LIGHTEST_L);
428
- }
429
- function resolveDarkest(slider) {
430
- const s = Math.max(0, Math.min(1, slider));
431
- return MAX_DARKEST_L * (1 - s);
432
- }
433
- function lightnessToScaleT(L, lightestL, darkestL) {
434
- const range = lightestL - darkestL;
435
- if (range <= 0) return 0.5;
436
- return Math.max(0, Math.min(1, (lightestL - L) / range));
437
- }
438
-
439
426
  // src/scale/generate.ts
440
427
  var toRad = Math.PI / 180;
441
428
  function applyGradingOverlay(C, h, L, t, grading, gamut) {
@@ -486,8 +473,12 @@ function generateScale(options = {}) {
486
473
  const localHueGrade = shift ? buildOneSidedGrade(shift.hue, shift.amount, shift.light) : void 0;
487
474
  const ratio = Math.max(0, Math.min(1, chromaRatio));
488
475
  const peak = Math.max(0, Math.min(1, chromaPeak));
489
- const lightestL = resolveLightest(contrast?.light ?? 1);
490
- const darkestL = resolveDarkest(contrast?.dark ?? 1);
476
+ const capLight = isP3 ? MIN_LIGHTEST_L_P3 : 1;
477
+ const capDark = isP3 ? MAX_DARKEST_L_P3 : 0;
478
+ const lightSlider = Math.max(0, Math.min(1, contrast?.light ?? 1));
479
+ const darkSlider = Math.max(0, Math.min(1, contrast?.dark ?? 1));
480
+ const lightestL = MIN_LIGHTEST_L + lightSlider * (capLight - MIN_LIGHTEST_L);
481
+ const darkestL = MAX_DARKEST_L - darkSlider * (MAX_DARKEST_L - capDark);
491
482
  const hueAt = (t) => resolveGradedHue(hue, t, hueGrade, localHueGrade);
492
483
  if (peak === 0.5 || ratio === 0 || ratio >= 1) {
493
484
  const scale2 = [];
@@ -588,6 +579,21 @@ function resolveColor(input, isP3 = false) {
588
579
  };
589
580
  }
590
581
 
582
+ // src/scale/dynamic-range.ts
583
+ function resolveLightest(slider) {
584
+ const s = Math.max(0, Math.min(1, slider));
585
+ return MIN_LIGHTEST_L + s * (1 - MIN_LIGHTEST_L);
586
+ }
587
+ function resolveDarkest(slider) {
588
+ const s = Math.max(0, Math.min(1, slider));
589
+ return MAX_DARKEST_L * (1 - s);
590
+ }
591
+ function lightnessToScaleT(L, lightestL, darkestL) {
592
+ const range = lightestL - darkestL;
593
+ if (range <= 0) return 0.5;
594
+ return Math.max(0, Math.min(1, (lightestL - L) / range));
595
+ }
596
+
591
597
  // src/scale/key-color.ts
592
598
  function keyColor(color, options) {
593
599
  const { isP3 = false, contrast, steps = DEFAULT_SCALE_STEPS } = options ?? {};
@@ -613,9 +619,11 @@ exports.DEFAULT_SCALE_STEPS = DEFAULT_SCALE_STEPS;
613
619
  exports.GRADING_CHROMA_RATIO = GRADING_CHROMA_RATIO;
614
620
  exports.GRADING_REACH = GRADING_REACH;
615
621
  exports.MAX_DARKEST_L = MAX_DARKEST_L;
622
+ exports.MAX_DARKEST_L_P3 = MAX_DARKEST_L_P3;
616
623
  exports.MAX_GRADING_AMOUNT = MAX_GRADING_AMOUNT;
617
624
  exports.MAX_SHIFT_AMOUNT = MAX_SHIFT_AMOUNT;
618
625
  exports.MIN_LIGHTEST_L = MIN_LIGHTEST_L;
626
+ exports.MIN_LIGHTEST_L_P3 = MIN_LIGHTEST_L_P3;
619
627
  exports.PERCEPTUAL_JND = PERCEPTUAL_JND;
620
628
  exports.SHIFT_REACH = SHIFT_REACH;
621
629
  exports.apcaContrast = apcaContrast;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants.ts","../src/conversions/oklab.ts","../src/conversions/linear-srgb.ts","../src/conversions/linear-p3.ts","../src/conversions/srgb.ts","../src/conversions/hex.ts","../src/conversions/pipeline.ts","../src/gamut/check.ts","../src/color/difference.ts","../src/gamut/map.ts","../src/gamut/max-chroma.ts","../src/contrast/wcag.ts","../src/contrast/apca.ts","../src/color/interpolation.ts","../src/config.ts","../src/scale/hue-grade.ts","../src/scale/dynamic-range.ts","../src/scale/generate.ts","../src/scale/resolve-color.ts","../src/scale/key-color.ts"],"names":["toRad","scale"],"mappings":"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","file":"index.cjs","sourcesContent":["// ── sRGB Gamma Transfer (IEC 61966-2-1) ──\n\nexport const SRGB_GAMMA_THRESHOLD = 0.04045;\nexport const SRGB_GAMMA_THRESHOLD_LINEAR = 0.0031308;\nexport const SRGB_GAMMA_SLOPE = 12.92;\nexport const SRGB_GAMMA_EXPONENT = 2.4;\nexport const SRGB_GAMMA_OFFSET = 0.055;\nexport const SRGB_GAMMA_SCALE = 1.055;\n\n// ── Ottosson M1: Linear sRGB → LMS ──\n\nexport const LINEAR_SRGB_TO_LMS = [\n [0.4122214708, 0.5363325363, 0.0514459929],\n [0.2119034982, 0.6806995451, 0.1073969566],\n [0.0883024619, 0.2817188376, 0.6299787005],\n] as const;\n\n// ── Ottosson M2: LMS′ (cube-root) → OKLAB ──\n\nexport const LMS_PRIME_TO_OKLAB = [\n [+0.2104542553, +0.7936177850, -0.0040720468],\n [+1.9779984951, -2.4285922050, +0.4505937099],\n [+0.0259040371, +0.7827717662, -0.8086757660],\n] as const;\n\n// ── Inverse M2: OKLAB → LMS′ ──\n\nexport const OKLAB_TO_LMS_PRIME = [\n [1.0000000000, +0.3963377774, +0.2158037573],\n [1.0000000000, -0.1055613458, -0.0638541728],\n [1.0000000000, -0.0894841775, -1.2914855480],\n] as const;\n\n// ── Inverse M1: LMS → Linear sRGB ──\n\nexport const LMS_TO_LINEAR_SRGB = [\n [+4.0767416621, -3.3077115913, +0.2309699292],\n [-1.2684380046, +2.6097574011, -0.3413193965],\n [-0.0041960863, -0.7034186147, +1.7076147010],\n] as const;\n\n// ── Display P3 M1: Linear Display P3 → LMS ──\n// Derived: XYZ_to_LMS × P3_to_XYZ, where XYZ_to_LMS = M1_srgb × inv(sRGB_to_XYZ)\n\nexport const LINEAR_P3_TO_LMS = [\n [+0.4813791595, +0.4621155872, +0.0565406381],\n [+0.2288319169, +0.6532167007, +0.1179528072],\n [+0.0839457149, +0.2241651052, +0.6918912614],\n] as const;\n\n// ── Inverse P3 M1: LMS → Linear Display P3 ──\n\nexport const LMS_TO_LINEAR_P3 = [\n [+3.1277694390, -2.2570600176, +0.1291828502],\n [-1.0910091977, +2.4133065499, -0.3222615148],\n [-0.0260108068, -0.5080402362, +1.5340494942],\n] as const;\n\n// ── Gamut Mapping ──\n\nexport const GAMUT_EPSILON = 1e-6;\nexport const GAMUT_MAP_JND = 0.02;\nexport const GAMUT_MAP_EPSILON = 1e-4;\nexport const GAMUT_MAP_MAX_ITERATIONS = 50;\n\n// ── Achromatic Threshold ──\n\nexport const ACHROMATIC_THRESHOLD = 1e-10;\n\n// ── WCAG 2.x Luminance Coefficients ──\n\nexport const WCAG_R = 0.2126;\nexport const WCAG_G = 0.7152;\nexport const WCAG_B = 0.0722;\n\n// ── APCA-W3 (SA98G) Constants ──\n\nexport const APCA_MAIN_TRC = 2.4;\nexport const APCA_SRGB_R = 0.2126729;\nexport const APCA_SRGB_G = 0.7151522;\nexport const APCA_SRGB_B = 0.0721750;\nexport const APCA_NORM_BG = 0.56;\nexport const APCA_NORM_TXT = 0.57;\nexport const APCA_REV_TXT = 0.62;\nexport const APCA_REV_BG = 0.65;\nexport const APCA_BLK_THRS = 0.022;\nexport const APCA_BLK_CLMP = 1.414;\nexport const APCA_SCALE_BOW = 1.14;\nexport const APCA_SCALE_WOB = 1.14;\nexport const APCA_LO_BOW_OFFSET = 0.027;\nexport const APCA_LO_WOB_OFFSET = 0.027;\nexport const APCA_DELTA_Y_MIN = 0.0005;\nexport const APCA_LO_CLIP = 0.1;\n\n// ── Angle Math ──\n\nexport const DEG_TO_RAD = Math.PI / 180;\nexport const RAD_TO_DEG = 180 / Math.PI;\n","import type { Oklab, Oklch } from \"../types.js\";\nimport { ACHROMATIC_THRESHOLD, DEG_TO_RAD, RAD_TO_DEG } from \"../constants.js\";\n\n/** Convert OKLAB (cartesian) to OKLCH (cylindrical). Achromatic colors get h=0. */\nexport function oklabToOklch(lab: Oklab): Oklch {\n const C = Math.sqrt(lab.a * lab.a + lab.b * lab.b);\n\n if (C < ACHROMATIC_THRESHOLD) {\n return { L: lab.L, C: 0, h: 0 };\n }\n\n let h = Math.atan2(lab.b, lab.a) * RAD_TO_DEG;\n if (h < 0) h += 360;\n\n return { L: lab.L, C, h };\n}\n\n/** Convert OKLCH (cylindrical) to OKLAB (cartesian). */\nexport function oklchToOklab(lch: Oklch): Oklab {\n const hRad = lch.h * DEG_TO_RAD;\n return {\n L: lch.L,\n a: lch.C * Math.cos(hRad),\n b: lch.C * Math.sin(hRad),\n };\n}\n","import type { LinearSrgb, Oklab } from \"../types.js\";\nimport {\n LINEAR_SRGB_TO_LMS,\n LMS_PRIME_TO_OKLAB,\n LMS_TO_LINEAR_SRGB,\n OKLAB_TO_LMS_PRIME,\n} from \"../constants.js\";\n\n/** Convert Linear sRGB to OKLAB via Ottosson's direct M1/M2 matrices. */\nexport function linearSrgbToOklab(color: LinearSrgb): Oklab {\n // Step 1: Linear sRGB → LMS\n const l =\n LINEAR_SRGB_TO_LMS[0][0] * color.r +\n LINEAR_SRGB_TO_LMS[0][1] * color.g +\n LINEAR_SRGB_TO_LMS[0][2] * color.b;\n const m =\n LINEAR_SRGB_TO_LMS[1][0] * color.r +\n LINEAR_SRGB_TO_LMS[1][1] * color.g +\n LINEAR_SRGB_TO_LMS[1][2] * color.b;\n const s =\n LINEAR_SRGB_TO_LMS[2][0] * color.r +\n LINEAR_SRGB_TO_LMS[2][1] * color.g +\n LINEAR_SRGB_TO_LMS[2][2] * color.b;\n\n // Step 2: Cube root\n const lp = Math.cbrt(l);\n const mp = Math.cbrt(m);\n const sp = Math.cbrt(s);\n\n // Step 3: LMS′ → OKLAB\n return {\n L:\n LMS_PRIME_TO_OKLAB[0][0] * lp +\n LMS_PRIME_TO_OKLAB[0][1] * mp +\n LMS_PRIME_TO_OKLAB[0][2] * sp,\n a:\n LMS_PRIME_TO_OKLAB[1][0] * lp +\n LMS_PRIME_TO_OKLAB[1][1] * mp +\n LMS_PRIME_TO_OKLAB[1][2] * sp,\n b:\n LMS_PRIME_TO_OKLAB[2][0] * lp +\n LMS_PRIME_TO_OKLAB[2][1] * mp +\n LMS_PRIME_TO_OKLAB[2][2] * sp,\n };\n}\n\n/** Convert OKLAB to Linear sRGB via inverse M2/M1 matrices. */\nexport function oklabToLinearSrgb(color: Oklab): LinearSrgb {\n // Step 1: OKLAB → LMS′\n const lp =\n OKLAB_TO_LMS_PRIME[0][0] * color.L +\n OKLAB_TO_LMS_PRIME[0][1] * color.a +\n OKLAB_TO_LMS_PRIME[0][2] * color.b;\n const mp =\n OKLAB_TO_LMS_PRIME[1][0] * color.L +\n OKLAB_TO_LMS_PRIME[1][1] * color.a +\n OKLAB_TO_LMS_PRIME[1][2] * color.b;\n const sp =\n OKLAB_TO_LMS_PRIME[2][0] * color.L +\n OKLAB_TO_LMS_PRIME[2][1] * color.a +\n OKLAB_TO_LMS_PRIME[2][2] * color.b;\n\n // Step 2: Cube\n const l = lp * lp * lp;\n const m = mp * mp * mp;\n const s = sp * sp * sp;\n\n // Step 3: LMS → Linear sRGB\n return {\n r:\n LMS_TO_LINEAR_SRGB[0][0] * l +\n LMS_TO_LINEAR_SRGB[0][1] * m +\n LMS_TO_LINEAR_SRGB[0][2] * s,\n g:\n LMS_TO_LINEAR_SRGB[1][0] * l +\n LMS_TO_LINEAR_SRGB[1][1] * m +\n LMS_TO_LINEAR_SRGB[1][2] * s,\n b:\n LMS_TO_LINEAR_SRGB[2][0] * l +\n LMS_TO_LINEAR_SRGB[2][1] * m +\n LMS_TO_LINEAR_SRGB[2][2] * s,\n };\n}\n","import type { LinearSrgb, Oklab } from \"../types.js\";\nimport {\n LINEAR_P3_TO_LMS,\n LMS_PRIME_TO_OKLAB,\n LMS_TO_LINEAR_P3,\n OKLAB_TO_LMS_PRIME,\n} from \"../constants.js\";\n\n/** Convert Linear Display P3 to OKLAB via P3-specific M1 + shared M2. */\nexport function linearP3ToOklab(color: LinearSrgb): Oklab {\n // Step 1: Linear P3 → LMS\n const l =\n LINEAR_P3_TO_LMS[0][0] * color.r +\n LINEAR_P3_TO_LMS[0][1] * color.g +\n LINEAR_P3_TO_LMS[0][2] * color.b;\n const m =\n LINEAR_P3_TO_LMS[1][0] * color.r +\n LINEAR_P3_TO_LMS[1][1] * color.g +\n LINEAR_P3_TO_LMS[1][2] * color.b;\n const s =\n LINEAR_P3_TO_LMS[2][0] * color.r +\n LINEAR_P3_TO_LMS[2][1] * color.g +\n LINEAR_P3_TO_LMS[2][2] * color.b;\n\n // Step 2: Cube root\n const lp = Math.cbrt(l);\n const mp = Math.cbrt(m);\n const sp = Math.cbrt(s);\n\n // Step 3: LMS′ → OKLAB (shared M2)\n return {\n L:\n LMS_PRIME_TO_OKLAB[0][0] * lp +\n LMS_PRIME_TO_OKLAB[0][1] * mp +\n LMS_PRIME_TO_OKLAB[0][2] * sp,\n a:\n LMS_PRIME_TO_OKLAB[1][0] * lp +\n LMS_PRIME_TO_OKLAB[1][1] * mp +\n LMS_PRIME_TO_OKLAB[1][2] * sp,\n b:\n LMS_PRIME_TO_OKLAB[2][0] * lp +\n LMS_PRIME_TO_OKLAB[2][1] * mp +\n LMS_PRIME_TO_OKLAB[2][2] * sp,\n };\n}\n\n/** Convert OKLAB to Linear Display P3 via shared inverse M2 + P3-specific inverse M1. */\nexport function oklabToLinearP3(color: Oklab): LinearSrgb {\n // Step 1: OKLAB → LMS′ (shared inverse M2)\n const lp =\n OKLAB_TO_LMS_PRIME[0][0] * color.L +\n OKLAB_TO_LMS_PRIME[0][1] * color.a +\n OKLAB_TO_LMS_PRIME[0][2] * color.b;\n const mp =\n OKLAB_TO_LMS_PRIME[1][0] * color.L +\n OKLAB_TO_LMS_PRIME[1][1] * color.a +\n OKLAB_TO_LMS_PRIME[1][2] * color.b;\n const sp =\n OKLAB_TO_LMS_PRIME[2][0] * color.L +\n OKLAB_TO_LMS_PRIME[2][1] * color.a +\n OKLAB_TO_LMS_PRIME[2][2] * color.b;\n\n // Step 2: Cube\n const l = lp * lp * lp;\n const m = mp * mp * mp;\n const s = sp * sp * sp;\n\n // Step 3: LMS → Linear P3\n return {\n r:\n LMS_TO_LINEAR_P3[0][0] * l +\n LMS_TO_LINEAR_P3[0][1] * m +\n LMS_TO_LINEAR_P3[0][2] * s,\n g:\n LMS_TO_LINEAR_P3[1][0] * l +\n LMS_TO_LINEAR_P3[1][1] * m +\n LMS_TO_LINEAR_P3[1][2] * s,\n b:\n LMS_TO_LINEAR_P3[2][0] * l +\n LMS_TO_LINEAR_P3[2][1] * m +\n LMS_TO_LINEAR_P3[2][2] * s,\n };\n}\n","import type { LinearSrgb, Srgb } from \"../types.js\";\nimport {\n SRGB_GAMMA_EXPONENT,\n SRGB_GAMMA_OFFSET,\n SRGB_GAMMA_SCALE,\n SRGB_GAMMA_SLOPE,\n SRGB_GAMMA_THRESHOLD,\n SRGB_GAMMA_THRESHOLD_LINEAR,\n} from \"../constants.js\";\n\n/** Decode a single sRGB gamma-encoded channel to linear light. */\nexport function srgbChannelToLinear(value: number): number {\n return value <= SRGB_GAMMA_THRESHOLD\n ? value / SRGB_GAMMA_SLOPE\n : ((value + SRGB_GAMMA_OFFSET) / SRGB_GAMMA_SCALE) ** SRGB_GAMMA_EXPONENT;\n}\n\n/** Encode a single linear light channel to sRGB gamma. */\nexport function linearChannelToSrgb(value: number): number {\n return value <= SRGB_GAMMA_THRESHOLD_LINEAR\n ? value * SRGB_GAMMA_SLOPE\n : SRGB_GAMMA_SCALE * value ** (1 / SRGB_GAMMA_EXPONENT) - SRGB_GAMMA_OFFSET;\n}\n\n/** Convert an sRGB color to Linear sRGB. */\nexport function srgbToLinearSrgb(color: Srgb): LinearSrgb {\n return {\n r: srgbChannelToLinear(color.r),\n g: srgbChannelToLinear(color.g),\n b: srgbChannelToLinear(color.b),\n };\n}\n\n/** Convert a Linear sRGB color to sRGB. */\nexport function linearSrgbToSrgb(color: LinearSrgb): Srgb {\n return {\n r: linearChannelToSrgb(color.r),\n g: linearChannelToSrgb(color.g),\n b: linearChannelToSrgb(color.b),\n };\n}\n","import type { Hex, Srgb } from \"../types.js\";\n\n/** Parse a hex color string (#RGB, #RRGGBB, or bare) to sRGB [0,1]. */\nexport function hexToSrgb(hex: string): Srgb {\n let h = hex.startsWith(\"#\") ? hex.slice(1) : hex;\n\n if (h.length === 3) {\n h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];\n }\n\n const n = parseInt(h, 16);\n return {\n r: ((n >> 16) & 0xff) / 255,\n g: ((n >> 8) & 0xff) / 255,\n b: (n & 0xff) / 255,\n };\n}\n\n/** Convert sRGB [0,1] to lowercase hex string (#rrggbb). Clamps to [0,1]. */\nexport function srgbToHex(color: Srgb): Hex {\n const r = Math.round(Math.max(0, Math.min(1, color.r)) * 255);\n const g = Math.round(Math.max(0, Math.min(1, color.g)) * 255);\n const b = Math.round(Math.max(0, Math.min(1, color.b)) * 255);\n return `#${((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1)}` as Hex;\n}\n","import type { Hex, Oklab, Oklch, Srgb } from \"../types.js\";\nimport { oklabToOklch, oklchToOklab } from \"./oklab.js\";\nimport { linearSrgbToOklab, oklabToLinearSrgb } from \"./linear-srgb.js\";\nimport { linearP3ToOklab, oklabToLinearP3 } from \"./linear-p3.js\";\nimport { linearSrgbToSrgb, srgbToLinearSrgb } from \"./srgb.js\";\nimport { hexToSrgb, srgbToHex } from \"./hex.js\";\n\n/** Convert sRGB to OKLCH. */\nexport function srgbToOklch(color: Srgb): Oklch {\n return oklabToOklch(linearSrgbToOklab(srgbToLinearSrgb(color)));\n}\n\n/** Convert OKLCH to sRGB. May produce out-of-gamut values (channels outside [0,1]). */\nexport function oklchToSrgb(color: Oklch): Srgb {\n return linearSrgbToSrgb(oklabToLinearSrgb(oklchToOklab(color)));\n}\n\n/** Convert sRGB to OKLAB. */\nexport function srgbToOklab(color: Srgb): Oklab {\n return linearSrgbToOklab(srgbToLinearSrgb(color));\n}\n\n/** Convert OKLAB to sRGB. May produce out-of-gamut values. */\nexport function oklabToSrgb(color: Oklab): Srgb {\n return linearSrgbToSrgb(oklabToLinearSrgb(color));\n}\n\n/** Convert hex to OKLCH. */\nexport function hexToOklch(hex: string): Oklch {\n return srgbToOklch(hexToSrgb(hex));\n}\n\n/** Convert OKLCH to hex. Clamps to sRGB gamut before hex encoding. */\nexport function oklchToHex(color: Oklch): Hex {\n const srgb = oklchToSrgb(color);\n return srgbToHex({\n r: Math.max(0, Math.min(1, srgb.r)),\n g: Math.max(0, Math.min(1, srgb.g)),\n b: Math.max(0, Math.min(1, srgb.b)),\n });\n}\n\n/** Convert Display P3 to OKLCH. */\nexport function p3ToOklch(color: Srgb): Oklch {\n return oklabToOklch(linearP3ToOklab(srgbToLinearSrgb(color)));\n}\n\n/** Convert OKLCH to Display P3. May produce out-of-gamut values (channels outside [0,1]). */\nexport function oklchToP3(color: Oklch): Srgb {\n return linearSrgbToSrgb(oklabToLinearP3(oklchToOklab(color)));\n}\n\n/** Convert OKLCH to a CSS `color(display-p3 r g b)` string. Clamps channels to [0,1]. */\nexport function oklchToP3Css(color: Oklch): string {\n const p3 = oklchToP3(color);\n const r = Math.max(0, Math.min(1, p3.r)).toFixed(4);\n const g = Math.max(0, Math.min(1, p3.g)).toFixed(4);\n const b = Math.max(0, Math.min(1, p3.b)).toFixed(4);\n return `color(display-p3 ${r} ${g} ${b})`;\n}\n","import type { Srgb } from \"../types.js\";\nimport { GAMUT_EPSILON } from \"../constants.js\";\n\n/** Check if sRGB channels are within [0, 1] (with epsilon tolerance). */\nexport function isInGamut(color: Srgb): boolean {\n return (\n color.r >= -GAMUT_EPSILON &&\n color.r <= 1 + GAMUT_EPSILON &&\n color.g >= -GAMUT_EPSILON &&\n color.g <= 1 + GAMUT_EPSILON &&\n color.b >= -GAMUT_EPSILON &&\n color.b <= 1 + GAMUT_EPSILON\n );\n}\n\n/** Clamp sRGB channels to [0, 1]. */\nexport function clampSrgb(color: Srgb): Srgb {\n return {\n r: Math.max(0, Math.min(1, color.r)),\n g: Math.max(0, Math.min(1, color.g)),\n b: Math.max(0, Math.min(1, color.b)),\n };\n}\n\n/** Clamp Display P3 channels to [0, 1]. */\nexport const clampP3 = clampSrgb;\n","import type { Oklab, Oklch } from \"../types.js\";\nimport { oklchToOklab } from \"../conversions/oklab.js\";\n\n/** Compute deltaEOK (Euclidean distance in OKLAB) between two OKLCH colors. */\nexport function deltaEOK(a: Oklch, b: Oklch): number {\n return deltaEOKLab(oklchToOklab(a), oklchToOklab(b));\n}\n\n/** Compute deltaEOK directly from OKLAB values. */\nexport function deltaEOKLab(a: Oklab, b: Oklab): number {\n const dL = a.L - b.L;\n const da = a.a - b.a;\n const db = a.b - b.b;\n return Math.sqrt(dL * dL + da * da + db * db);\n}\n","import type { Gamut, Oklch, Srgb } from \"../types.js\";\nimport {\n GAMUT_EPSILON,\n GAMUT_MAP_EPSILON,\n GAMUT_MAP_JND,\n GAMUT_MAP_MAX_ITERATIONS,\n} from \"../constants.js\";\nimport { oklchToSrgb, oklchToP3 } from \"../conversions/pipeline.js\";\nimport { isInGamut, clampSrgb } from \"./check.js\";\nimport { deltaEOKLab } from \"../color/difference.js\";\nimport { oklchToOklab } from \"../conversions/oklab.js\";\nimport { linearSrgbToOklab } from \"../conversions/linear-srgb.js\";\nimport { linearP3ToOklab } from \"../conversions/linear-p3.js\";\nimport { srgbToLinearSrgb } from \"../conversions/srgb.js\";\n\n/**\n * Map an OKLCH color into the target gamut using the CSS Color Level 4 algorithm.\n * Reduces chroma at fixed L and h via binary search with deltaEOK JND check.\n * @param gamut Target gamut (default: 'srgb').\n */\nexport function gamutMap(color: Oklch, gamut: Gamut = \"srgb\"): Oklch {\n const toRgb = gamut === \"display-p3\" ? oklchToP3 : oklchToSrgb;\n const rgbToOklab =\n gamut === \"display-p3\"\n ? (c: Srgb) => linearP3ToOklab(srgbToLinearSrgb(c))\n : (c: Srgb) => linearSrgbToOklab(srgbToLinearSrgb(c));\n\n // Already in gamut\n const rgb = toRgb(color);\n if (isInGamut(rgb)) return color;\n\n // Edge cases: black and white\n if (color.L <= GAMUT_EPSILON) return { L: 0, C: 0, h: color.h };\n if (color.L >= 1 - GAMUT_EPSILON) return { L: 1, C: 0, h: color.h };\n\n let lo = 0;\n let hi = color.C;\n\n for (let i = 0; i < GAMUT_MAP_MAX_ITERATIONS; i++) {\n const midC = (lo + hi) / 2;\n const candidate: Oklch = { L: color.L, C: midC, h: color.h };\n const candidateRgb = toRgb(candidate);\n\n if (isInGamut(candidateRgb)) {\n lo = midC;\n } else {\n // Clip and check JND\n const clipped = clampSrgb(candidateRgb);\n const clippedLab = rgbToOklab(clipped);\n const candidateLab = oklchToOklab(candidate);\n const dE = deltaEOKLab(clippedLab, candidateLab);\n\n if (dE < GAMUT_MAP_JND) {\n // Clipped version is perceptually close enough — converge here.\n // Return lo (last confirmed in-gamut chroma) to guarantee gamut safety.\n break;\n }\n\n hi = midC;\n }\n\n if (hi - lo < GAMUT_MAP_EPSILON) break;\n }\n\n return { L: color.L, C: lo, h: color.h };\n}\n","import type { Gamut, Oklch } from \"../types.js\";\nimport { GAMUT_MAP_MAX_ITERATIONS } from \"../constants.js\";\nimport { oklchToSrgb, oklchToP3 } from \"../conversions/pipeline.js\";\nimport { isInGamut } from \"./check.js\";\n\n/**\n * Find the maximum in-gamut chroma for a given OKLCH lightness and hue.\n *\n * Binary search over [0, upperBound], converging to 1e-6 precision.\n * Upper bounds are empirically safe ceilings — no in-gamut color at any\n * lightness or hue exceeds C = 0.4 in sRGB or C = 0.5 in Display P3.\n * Searching beyond these would waste iterations with no benefit.\n *\n * Returns 0 for L ≤ 0 or L ≥ 1 (pure black and white carry no chroma).\n */\nexport function maxChroma(L: number, h: number, gamut: Gamut = \"srgb\"): number {\n if (L <= 0 || L >= 1) return 0;\n\n const toRgb = gamut === \"display-p3\" ? oklchToP3 : oklchToSrgb;\n let lo = 0;\n let hi = gamut === \"display-p3\" ? 0.5 : 0.4;\n\n for (let i = 0; i < GAMUT_MAP_MAX_ITERATIONS; i++) {\n const mid = (lo + hi) / 2;\n const color: Oklch = { L, C: mid, h };\n const rgb = toRgb(color);\n\n if (isInGamut(rgb)) {\n lo = mid;\n } else {\n hi = mid;\n }\n\n if (hi - lo < 1e-6) break;\n }\n\n return lo;\n}\n","import type { Srgb } from \"../types.js\";\nimport { WCAG_R, WCAG_G, WCAG_B } from \"../constants.js\";\nimport { srgbChannelToLinear } from \"../conversions/srgb.js\";\n\n/** Compute WCAG 2.x relative luminance [0, 1] from an sRGB color. */\nexport function wcagLuminance(color: Srgb): number {\n return (\n WCAG_R * srgbChannelToLinear(color.r) +\n WCAG_G * srgbChannelToLinear(color.g) +\n WCAG_B * srgbChannelToLinear(color.b)\n );\n}\n\n/**\n * Compute WCAG 2.x contrast ratio between two sRGB colors.\n * Returns a value in [1, 21]. Symmetric (order doesn't matter).\n */\nexport function wcagContrast(a: Srgb, b: Srgb): number {\n const lA = wcagLuminance(a);\n const lB = wcagLuminance(b);\n const lighter = Math.max(lA, lB);\n const darker = Math.min(lA, lB);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\n/**\n * Choose black or white text for maximum WCAG contrast against a background.\n * @returns `\"#000000\"` or `\"#ffffff\"`.\n */\nexport function contrastTextHex(background: Srgb): \"#000000\" | \"#ffffff\" {\n const white: Srgb = { r: 1, g: 1, b: 1 };\n const black: Srgb = { r: 0, g: 0, b: 0 };\n return wcagContrast(white, background) > wcagContrast(black, background)\n ? \"#ffffff\"\n : \"#000000\";\n}\n","import type { Srgb } from \"../types.js\";\nimport {\n APCA_MAIN_TRC,\n APCA_SRGB_R,\n APCA_SRGB_G,\n APCA_SRGB_B,\n APCA_NORM_BG,\n APCA_NORM_TXT,\n APCA_REV_TXT,\n APCA_REV_BG,\n APCA_BLK_THRS,\n APCA_BLK_CLMP,\n APCA_SCALE_BOW,\n APCA_SCALE_WOB,\n APCA_LO_BOW_OFFSET,\n APCA_LO_WOB_OFFSET,\n APCA_DELTA_Y_MIN,\n APCA_LO_CLIP,\n} from \"../constants.js\";\n\n/**\n * Compute APCA-W3 Lc (Lightness Contrast) between text and background.\n *\n * Returns a signed value in roughly [-108, +106]:\n * Positive = dark text on light background (BoW)\n * Negative = light text on dark background (WoB)\n * 0 = no meaningful contrast\n *\n * IMPORTANT: Uses its own linearization (simple 2.4 gamma),\n * NOT the IEC piecewise sRGB transfer function.\n */\n/**\n * Practical maximum APCA Lc magnitude used for normalization.\n * BoW tops out at ~+106, WoB at ~-108; we use 108 as a symmetric ceiling.\n */\nexport const APCA_LC_MAX = 108;\n\n/**\n * Normalize a raw APCA Lc value to the range [-1, +1].\n * +1 = maximum dark-on-light contrast (BoW)\n * -1 = maximum light-on-dark contrast (WoB)\n * 0 = no meaningful contrast\n */\nexport function apcaToNormalized(lc: number): number {\n return Math.max(-1, Math.min(1, lc / APCA_LC_MAX));\n}\n\n/**\n * Convert a normalized contrast value [-1, +1] back to a raw APCA Lc value.\n */\nexport function normalizedToApca(normalized: number): number {\n return normalized * APCA_LC_MAX;\n}\n\nexport function apcaContrast(textColor: Srgb, bgColor: Srgb): number {\n // Step 1: Linearize with simple 2.4 gamma and compute Y\n let txtY =\n APCA_SRGB_R * textColor.r ** APCA_MAIN_TRC +\n APCA_SRGB_G * textColor.g ** APCA_MAIN_TRC +\n APCA_SRGB_B * textColor.b ** APCA_MAIN_TRC;\n\n let bgY =\n APCA_SRGB_R * bgColor.r ** APCA_MAIN_TRC +\n APCA_SRGB_G * bgColor.g ** APCA_MAIN_TRC +\n APCA_SRGB_B * bgColor.b ** APCA_MAIN_TRC;\n\n // Step 2: Soft black clamp\n if (txtY < APCA_BLK_THRS) {\n txtY += (APCA_BLK_THRS - txtY) ** APCA_BLK_CLMP;\n }\n if (bgY < APCA_BLK_THRS) {\n bgY += (APCA_BLK_THRS - bgY) ** APCA_BLK_CLMP;\n }\n\n // Step 3: Delta Y check\n if (Math.abs(bgY - txtY) < APCA_DELTA_Y_MIN) return 0;\n\n // Step 4: Polarity-aware contrast\n let sapc: number;\n\n if (bgY > txtY) {\n // Dark text on light background (BoW)\n sapc = (bgY ** APCA_NORM_BG - txtY ** APCA_NORM_TXT) * APCA_SCALE_BOW;\n return sapc < APCA_LO_CLIP ? 0 : (sapc - APCA_LO_BOW_OFFSET) * 100;\n } else {\n // Light text on dark background (WoB)\n sapc = (bgY ** APCA_REV_BG - txtY ** APCA_REV_TXT) * APCA_SCALE_WOB;\n return sapc > -APCA_LO_CLIP ? 0 : (sapc + APCA_LO_WOB_OFFSET) * 100;\n }\n}\n","import type { Oklch } from \"../types.js\";\nimport { ACHROMATIC_THRESHOLD } from \"../constants.js\";\n\n/**\n * Linearly interpolate between two OKLCH colors.\n *\n * L and C are linearly interpolated. Hue uses shortest-arc interpolation.\n * Achromatic colors (C near zero) inherit the other color's hue to avoid\n * meaningless hue sweeps through the achromatic pole.\n */\nexport function mix(a: Oklch, b: Oklch, t: number): Oklch {\n const L = a.L + (b.L - a.L) * t;\n const C = a.C + (b.C - a.C) * t;\n\n // Resolve hue — handle achromatic inputs\n const aIsAchromatic = a.C < ACHROMATIC_THRESHOLD;\n const bIsAchromatic = b.C < ACHROMATIC_THRESHOLD;\n\n if (aIsAchromatic && bIsAchromatic) {\n return { L, C, h: 0 };\n }\n\n const hA = aIsAchromatic ? b.h : a.h;\n const hB = bIsAchromatic ? a.h : b.h;\n\n // Shortest-arc hue interpolation\n let delta = hB - hA;\n if (delta > 180) delta -= 360;\n if (delta < -180) delta += 360;\n\n let h = hA + delta * t;\n if (h < 0) h += 360;\n if (h >= 360) h -= 360;\n\n return { L, C, h };\n}\n","/**\n * Design constants — the values you tune by hand.\n *\n * Edit this file to adjust the perceptual behavior of every scale and\n * grading operation across the library.\n */\n\n// ── Scale defaults ────────────────────────────────────────────────────────────\n\n/**\n * Default number of steps in a generated scale.\n * Fixed at 26 — enough for a full design token set with fine lightness\n * increments without redundancy.\n */\nexport const DEFAULT_SCALE_STEPS = 26;\n\n/**\n * Default hue when none is provided.\n * 0° is the start of the OKLCH hue wheel (red region). Arbitrary but\n * deterministic — callers should always supply an explicit hue.\n */\nexport const DEFAULT_HUE = 0;\n\n// ── Dynamic range ─────────────────────────────────────────────────────────────\n\n/**\n * Lightest step's lightness when the whites slider is at 0.\n * slider 0 → L = MIN_LIGHTEST_L, slider 1 → L = 1.0 (pure white).\n */\nexport const MIN_LIGHTEST_L = 0.96;\n\n/**\n * Darkest step's lightness when the darks slider is at 0.\n * slider 0 → L = MAX_DARKEST_L, slider 1 → L = 0.0 (pure black).\n */\nexport const MAX_DARKEST_L = 0.16;\n\n// ── Hue grading ───────────────────────────────────────────────────────────────\n\n/**\n * How far global grading reaches into the scale from each end (0–1).\n * Light grading fades to zero at t = GRADING_REACH.\n * Dark grading fades to zero at t = 1 − GRADING_REACH.\n */\nexport const GRADING_REACH = 3 / 5;\n\n/** Maximum amount for global grading. Inputs above this are clamped. */\nexport const MAX_GRADING_AMOUNT = 0.25;\n\n/**\n * Fraction of the gamut boundary injected as chroma when global grading\n * is active. Ensures grading has a visible tinting effect even on\n * achromatic (chroma.amount = 0) palettes.\n *\n * Only global grading injects chroma — per-palette shift does not.\n */\nexport const GRADING_CHROMA_RATIO = 0.5;\n\n/**\n * How far per-palette hue shift reaches into the scale from each end (0–1).\n * Slightly wider than GRADING_REACH to give per-palette shifts more room.\n */\nexport const SHIFT_REACH = 2 / 3;\n\n/** Maximum amount for per-palette hue shift. Inputs above this are clamped. */\nexport const MAX_SHIFT_AMOUNT = 0.5;\n\n// ── Color difference ──────────────────────────────────────────────────────────\n\n/**\n * Just-noticeable difference threshold (deltaEOK).\n * Colors with distance below this are considered perceptually identical.\n * Used to classify color matches as exact vs. fallback.\n */\nexport const PERCEPTUAL_JND = 0.02;\n","/**\n * Global hue grading — shifts each palette's base hue toward shared\n * target hues at the light and dark scale endpoints.\n *\n * Light grading fades from full at the lightest step to zero at GRADING_REACH.\n * Dark grading fades from zero at (1 - GRADING_REACH) to full at the darkest step.\n * In the overlap zone, both shifts are additive (commutative).\n */\n\nimport {\n GRADING_REACH,\n MAX_GRADING_AMOUNT,\n SHIFT_REACH,\n MAX_SHIFT_AMOUNT,\n} from \"../config.js\";\n\nexport interface Grading {\n /** Hue grading for the light end of the scale. */\n readonly light?: { readonly hue: number; readonly amount: number };\n /** Hue grading for the dark end of the scale. */\n readonly dark?: { readonly hue: number; readonly amount: number };\n}\n\n/** Per-palette hue shift (one end only). */\nexport interface Shift {\n /** Target hue to shift toward (0–360°). */\n readonly hue: number;\n /** Blend strength (0–MAX_SHIFT_AMOUNT). */\n readonly amount: number;\n /** Which end to affect. `true` = light end, `false`/omitted = dark end (default). */\n readonly light?: boolean;\n}\n\n/**\n * Compute the graded hue at position `t` in the scale.\n *\n * Uses vector interpolation in Cartesian space rather than angular deltas\n * to avoid the shortest-arc discontinuity at 180° (where the direction\n * of rotation flips abruptly). Each grade's displacement is computed as\n * a vector offset from the base hue, and displacements are additive\n * (commutative — order doesn't matter).\n *\n * @param baseHue The palette's own hue (0–360°).\n * @param t Position in the scale: 0 = lightest, 1 = darkest.\n * @param grade Hue grade configuration.\n * @param reach How far each grade reaches into the scale (default: GRADING_REACH).\n * @param maxIntensity Maximum amount clamp (default: MAX_GRADING_AMOUNT).\n * @returns The graded hue in degrees (0–360).\n */\nexport function gradeHue(\n baseHue: number,\n t: number,\n grade: Grading,\n reach: number = GRADING_REACH,\n maxIntensity: number = MAX_GRADING_AMOUNT,\n): number {\n const li = Math.max(0, Math.min(maxIntensity, grade.light?.amount ?? 0));\n const di = Math.max(0, Math.min(maxIntensity, grade.dark?.amount ?? 0));\n\n // Early exit: no grading\n if (li === 0 && di === 0) return baseHue;\n\n // Light influence: cosine fade from 1 at t=0 to 0 at t=reach\n const lightInfluence =\n t <= reach ? 0.5 * (1 + Math.cos((Math.PI * t) / reach)) : 0;\n\n // Dark influence: cosine fade from 0 at t=(1-reach) to 1 at t=1\n const darkInfluence =\n t >= 1 - reach\n ? 0.5 * (1 + Math.cos((Math.PI * (1 - t)) / reach))\n : 0;\n\n // Base hue as unit vector\n const toRad = Math.PI / 180;\n const baseRad = baseHue * toRad;\n const bx = Math.cos(baseRad);\n const by = Math.sin(baseRad);\n\n // Accumulate displacements in Cartesian space\n let dx = 0;\n let dy = 0;\n\n if (lightInfluence > 0 && li > 0) {\n const blend = lightInfluence * li;\n const lRad = (grade.light!.hue) * toRad;\n dx += blend * (Math.cos(lRad) - bx);\n dy += blend * (Math.sin(lRad) - by);\n }\n\n if (darkInfluence > 0 && di > 0) {\n const blend = darkInfluence * di;\n const dRad = (grade.dark!.hue) * toRad;\n dx += blend * (Math.cos(dRad) - bx);\n dy += blend * (Math.sin(dRad) - by);\n }\n\n // Reconstruct hue from displaced vector\n const rx = bx + dx;\n const ry = by + dy;\n\n // Safety: collapsed vector (opposite hues at exactly 50% blend)\n if (rx * rx + ry * ry < 1e-20) return baseHue;\n\n return ((Math.atan2(ry, rx) / toRad) + 360) % 360;\n}\n\n/**\n * Compute the combined grading influence at position `t` (0–1).\n *\n * Returns a scalar in [0, 1] representing how strongly global grading\n * affects position `t`. This is the maximum of the light and dark\n * cosine-fade envelopes, each scaled by its respective amount.\n *\n * Used by the chroma injection system to tint achromatic palettes\n * proportionally to grading strength.\n */\nexport function gradingInfluence(t: number, grading: Grading): number {\n const li = Math.max(0, Math.min(MAX_GRADING_AMOUNT, grading.light?.amount ?? 0));\n const di = Math.max(0, Math.min(MAX_GRADING_AMOUNT, grading.dark?.amount ?? 0));\n\n if (li === 0 && di === 0) return 0;\n\n const lightInfluence =\n t <= GRADING_REACH ? 0.5 * (1 + Math.cos((Math.PI * t) / GRADING_REACH)) : 0;\n\n const darkInfluence =\n t >= 1 - GRADING_REACH\n ? 0.5 * (1 + Math.cos((Math.PI * (1 - t)) / GRADING_REACH))\n : 0;\n\n const lightBlend = lightInfluence * (li / MAX_GRADING_AMOUNT);\n const darkBlend = darkInfluence * (di / MAX_GRADING_AMOUNT);\n\n return Math.max(lightBlend, darkBlend);\n}\n\n/**\n * Resolve the final hue at position `t`, applying local shift first, then global grading.\n *\n * This is the canonical composition: per-palette shift (using SHIFT_REACH /\n * MAX_SHIFT_AMOUNT) first, then global grading (using GRADING_REACH /\n * MAX_GRADING_AMOUNT) on top — so grading's influence is preserved at full\n * strength across all palettes, keeping them visually coherent.\n *\n * @param baseHue The palette's own hue (0–360°).\n * @param t Position in the scale: 0 = lightest, 1 = darkest.\n * @param globalGrade Global grading (shared across palettes), or undefined.\n * @param localGrade Local grading (per-palette, expanded from Shift), or undefined.\n * @returns The fully graded hue in degrees (0–360).\n */\nexport function resolveGradedHue(\n baseHue: number,\n t: number,\n globalGrade?: Grading,\n localGrade?: Grading,\n): number {\n let h = baseHue;\n if (localGrade) h = gradeHue(h, t, localGrade, SHIFT_REACH, MAX_SHIFT_AMOUNT);\n if (globalGrade) h = gradeHue(h, t, globalGrade);\n return h;\n}\n\n/**\n * Adapt a Shift into a one-sided Grading so it can be passed to gradeHue.\n *\n * The Shift interface is flat (hue, amount, light?) for ergonomic API use,\n * but gradeHue operates on the Grading shape (light/dark sub-objects).\n * This function bridges the two, activating only the requested end.\n *\n * @param hue Target hue for the active side (0–360°).\n * @param amount Blend strength for the active side.\n * @param light `true` = light end, `false`/omitted = dark end (default).\n */\nexport function buildOneSidedGrade(\n hue: number,\n amount: number,\n light: boolean = false,\n): Grading {\n return light\n ? { light: { hue, amount } }\n : { dark: { hue, amount } };\n}\n","/**\n * Dynamic range resolution — maps slider values (0–1) to OKLCH lightness\n * bounds for the lightest and darkest steps of a color scale.\n */\n\nimport { MIN_LIGHTEST_L, MAX_DARKEST_L } from \"../config.js\";\n\n/**\n * Resolve a whites slider value (0–1) to an OKLCH lightness.\n * slider 0 → L = MIN_LIGHTEST_L (0.96), slider 1 → L = 1.0 (pure white)\n */\nexport function resolveLightest(slider: number): number {\n const s = Math.max(0, Math.min(1, slider));\n return MIN_LIGHTEST_L + s * (1.0 - MIN_LIGHTEST_L);\n}\n\n/**\n * Resolve a darks slider value (0–1) to an OKLCH lightness.\n * slider 0 → L = MAX_DARKEST_L (0.16), slider 1 → L = 0.0 (pure black)\n */\nexport function resolveDarkest(slider: number): number {\n const s = Math.max(0, Math.min(1, slider));\n return MAX_DARKEST_L * (1 - s);\n}\n\n/**\n * Map an OKLCH lightness to a normalized scale position (0–1).\n * 0 = lightest end, 1 = darkest end.\n *\n * Inverse of the lightness interpolation inside generateScale.\n * Useful for deriving chromaPeak from a key color's lightness.\n */\nexport function lightnessToScaleT(L: number, lightestL: number, darkestL: number): number {\n const range = lightestL - darkestL;\n if (range <= 0) return 0.5;\n return Math.max(0, Math.min(1, (lightestL - L) / range));\n}\n","import type { Oklch } from \"../types.js\";\nimport { maxChroma } from \"../gamut/max-chroma.js\";\nimport type { Grading, Shift } from \"./hue-grade.js\";\nimport { resolveGradedHue, buildOneSidedGrade } from \"./hue-grade.js\";\nimport { resolveLightest, resolveDarkest } from \"./dynamic-range.js\";\nimport {\n DEFAULT_SCALE_STEPS,\n DEFAULT_HUE,\n GRADING_CHROMA_RATIO,\n GRADING_REACH,\n MAX_GRADING_AMOUNT,\n} from \"../config.js\";\n\ntype Gamut = \"srgb\" | \"display-p3\";\nconst toRad = Math.PI / 180;\n\n/**\n * Apply grading as an additive chroma overlay.\n *\n * Builds per-side chroma vectors pointing at the grading TARGET hues\n * (not the palette's hue) and adds them to the palette's existing\n * chroma in Cartesian (a, b) space. This ensures grading tints even\n * fully achromatic palettes without the base hue leaking through.\n */\nfunction applyGradingOverlay(\n C: number, h: number, L: number, t: number,\n grading: Grading, gamut: Gamut,\n): { C: number; h: number } {\n const li = Math.max(0, Math.min(MAX_GRADING_AMOUNT, grading.light?.amount ?? 0));\n const di = Math.max(0, Math.min(MAX_GRADING_AMOUNT, grading.dark?.amount ?? 0));\n if (li === 0 && di === 0) return { C, h };\n\n // Per-side cosine-fade influences\n const lightFade = t <= GRADING_REACH\n ? 0.5 * (1 + Math.cos((Math.PI * t) / GRADING_REACH)) : 0;\n const darkFade = t >= 1 - GRADING_REACH\n ? 0.5 * (1 + Math.cos((Math.PI * (1 - t)) / GRADING_REACH)) : 0;\n\n const lightBlend = lightFade * (li / MAX_GRADING_AMOUNT);\n const darkBlend = darkFade * (di / MAX_GRADING_AMOUNT);\n if (lightBlend === 0 && darkBlend === 0) return { C, h };\n\n // Palette's existing chroma as Cartesian vector\n const hRad = h * toRad;\n let a = C * Math.cos(hRad);\n let b = C * Math.sin(hRad);\n\n // Add overlay vectors at grading TARGET hues\n if (lightBlend > 0) {\n const lh = grading.light!.hue;\n const lRad = lh * toRad;\n const lC = maxChroma(L, lh, gamut) * GRADING_CHROMA_RATIO * lightBlend;\n a += lC * Math.cos(lRad);\n b += lC * Math.sin(lRad);\n }\n if (darkBlend > 0) {\n const dh = grading.dark!.hue;\n const dRad = dh * toRad;\n const dC = maxChroma(L, dh, gamut) * GRADING_CHROMA_RATIO * darkBlend;\n a += dC * Math.cos(dRad);\n b += dC * Math.sin(dRad);\n }\n\n // Convert back to polar\n let newC = Math.sqrt(a * a + b * b);\n let newH = ((Math.atan2(b, a) / toRad) + 360) % 360;\n\n // Clamp to gamut at the resulting hue\n newC = Math.min(newC, maxChroma(L, newH, gamut));\n\n return { C: newC, h: newH };\n}\n\nexport interface ScaleOptions {\n /**\n * Tonal range of the scale.\n * - `light`: how light the lightest step is (0–1). Default: 1.\n * 0 → L = MIN_LIGHTEST_L (0.96), 1 → L = 1.0 (pure white).\n * - `dark`: how dark the darkest step is (0–1). Default: 1.\n * 0 → L = MAX_DARKEST_L (0.16), 1 → L = 0.0 (pure black).\n */\n readonly contrast?: { readonly light?: number; readonly dark?: number };\n /**\n * Hue angle in degrees (0–360). Default: DEFAULT_HUE (0).\n * Every step shares this base hue unless shifted by `grading` or `shift`.\n */\n readonly hue?: number;\n /**\n * Chroma shape of the scale.\n * - `amount`: how much of the available gamut to use (0–1). Default: 0.\n * 0 = fully achromatic (default), 1 = maximum in-gamut chroma at each lightness.\n * - `balance`: how chroma is distributed along the lightness range (0–1).\n * 0 = chroma concentrated toward the lightest end, 1 = toward the darkest end,\n * 0.5 = natural distribution (default, follows gamut boundary shape).\n */\n readonly chroma?: { readonly amount?: number; readonly balance?: number };\n /**\n * Global hue grading. When provided, the hue at each step is shifted\n * toward target hues based on position in the scale.\n * Light grading affects the lightest 3/5, dark grading affects the\n * darkest 3/5, with additive overlap in the middle fifth.\n */\n readonly grading?: Grading;\n /**\n * Per-palette hue shift. A one-sided grade applied before global\n * grading, with its own reach and strength limits (SHIFT_REACH,\n * MAX_SHIFT_AMOUNT). Defaults to the dark end; set `light: true` to target\n * the light end instead.\n */\n readonly shift?: Shift;\n /** Use Display P3 gamut instead of sRGB (default: false). */\n readonly isP3?: boolean;\n}\n\n/**\n * Generate an OKLCH color scale from lightest to darkest.\n *\n * Always produces DEFAULT_SCALE_STEPS colors. Chroma at each step is\n * proportional to the gamut boundary at that lightness, scaled by\n * `chroma.amount`. This guarantees every color is in-gamut — no fallbacks\n * needed — while producing a smooth, natural chroma curve.\n *\n * Use `contrast` to constrain the tonal range\n * (e.g. for scales that don't extend to pure white or pure black).\n *\n * Use `chroma.balance` to shift how chroma is distributed within the boundary.\n * The curve endpoints stay fixed while the distribution shifts smoothly.\n * The effective shift range is proportional to the headroom left by chroma.amount.\n */\nexport function generateScale(options: ScaleOptions = {}): Oklch[] {\n const {\n contrast,\n hue = DEFAULT_HUE,\n chroma,\n isP3 = false,\n grading,\n shift,\n } = options;\n const gamut = isP3 ? \"display-p3\" : \"srgb\";\n\n const steps = DEFAULT_SCALE_STEPS;\n const chromaRatio = chroma?.amount ?? 0;\n const chromaPeak = chroma?.balance ?? 0.5;\n const hueGrade = grading;\n const localHueGrade = shift ? buildOneSidedGrade(shift.hue, shift.amount, shift.light) : undefined;\n\n const ratio = Math.max(0, Math.min(1, chromaRatio));\n const peak = Math.max(0, Math.min(1, chromaPeak));\n const lightestL = resolveLightest(contrast?.light ?? 1);\n const darkestL = resolveDarkest(contrast?.dark ?? 1);\n\n // Helper: resolve hue at position t (applies local shift first, then global grading)\n const hueAt = (t: number) => resolveGradedHue(hue, t, hueGrade, localHueGrade);\n\n // Fast path: skip peak skew logic when balance has no effect.\n // - peak === 0.5: already at the natural gamut peak, nothing to shift\n // - ratio === 0: no chroma at all, boundary shape is irrelevant\n // - ratio >= 1: inner triangle equals the boundary triangle, no headroom to slide\n if (peak === 0.5 || ratio === 0 || ratio >= 1) {\n const scale: Oklch[] = [];\n for (let i = 0; i < steps; i++) {\n const t = i / (steps - 1);\n const L = lightestL - t * (lightestL - darkestL);\n let h = hueAt(t);\n // Chroma is shaped by the base hue's boundary to keep the curve smooth.\n // The shifted hue's boundary is used as a final in-gamut clamp only —\n // this prevents spikes when the shifted hue has more available chroma\n // than the base (e.g. blue → pink passing through the purple region).\n let C = Math.min(maxChroma(L, hue, gamut) * ratio, maxChroma(L, h, gamut));\n\n if (hueGrade) {\n const overlay = applyGradingOverlay(C, h, L, t, hueGrade, gamut);\n C = overlay.C;\n h = overlay.h;\n }\n\n scale.push({ L, C, h });\n }\n return scale;\n }\n\n // ── Peak skew logic ──\n // Warp the parameter t so the boundary peak appears at a shifted position.\n // Endpoints stay fixed (warp(0)=0, warp(1)=1), only the peak moves.\n\n // 1. Sample boundary to find natural peak and valid shift range\n const N = 100;\n let peakT = 0.5;\n let peakBoundaryC = 0;\n const boundarySamples: { t: number; C: number }[] = [];\n\n for (let i = 0; i <= N; i++) {\n const t = i / N;\n const L = lightestL - t * (lightestL - darkestL);\n // Sample the base hue's boundary — the same reference used when building\n // the warp below. Using the shifted hue here would skew peakT and the\n // valid range toward a hue-specific boundary shape, inconsistent with\n // how chroma is actually computed in step 4.\n const C = maxChroma(L, hue, gamut);\n boundarySamples.push({ t, C });\n if (C > peakBoundaryC) {\n peakBoundaryC = C;\n peakT = t;\n }\n }\n\n // 2. Find valid range: where boundary can accommodate the inner peak height\n const innerPeakC = peakBoundaryC * ratio;\n let validMinT = peakT;\n let validMaxT = peakT;\n\n for (const { t, C } of boundarySamples) {\n if (C >= innerPeakC - 1e-6) {\n if (t < validMinT) validMinT = t;\n if (t > validMaxT) validMaxT = t;\n }\n }\n\n // 3. Map chroma.balance (0–1) to valid range, normalized so 0.5 → peakT\n let targetT: number;\n if (peak <= 0.5) {\n targetT = validMinT + (peak / 0.5) * (peakT - validMinT);\n } else {\n targetT = peakT + ((peak - 0.5) / 0.5) * (validMaxT - peakT);\n }\n\n // Safety: if the piecewise mapping produces a degenerate targetT (outside\n // (0, 1)), fall back to the natural peak. This can occur at floating-point\n // boundaries rather than from any single expected input combination.\n if (targetT <= 0 || targetT >= 1) {\n targetT = peakT;\n }\n\n // 4. Build scale with piecewise-linear warp: targetT → peakT\n const scale: Oklch[] = [];\n for (let i = 0; i < steps; i++) {\n const t = i / (steps - 1);\n const L = lightestL - t * (lightestL - darkestL);\n let h = hueAt(t);\n\n // Piecewise-linear warp: maps 0→0, targetT→peakT, 1→1.\n // Two segments scale t independently so the boundary peak (at peakT in\n // warp space) lands at targetT in the output — endpoints stay fixed.\n let tWarped: number;\n if (t <= targetT) {\n tWarped = t * (peakT / targetT);\n } else {\n tWarped = peakT + (t - targetT) * ((1 - peakT) / (1 - targetT));\n }\n\n const Lwarped = lightestL - tWarped * (lightestL - darkestL);\n // Use the base hue for the warped chroma lookup — consistent with step 1\n // and the fast path. The warp is purely a lightness operation; mixing in\n // the shifted hue at tWarped would introduce cross-position hue artifacts.\n const warpedC = maxChroma(Lwarped, hue, gamut) * ratio;\n // Clamp to the shifted hue's actual boundary at this L: the in-gamut\n // guarantee for the final color { L, C, h }.\n const boundaryC = maxChroma(L, h, gamut);\n let C = Math.min(warpedC, boundaryC);\n\n if (hueGrade) {\n const overlay = applyGradingOverlay(C, h, L, t, hueGrade, gamut);\n C = overlay.C;\n h = overlay.h;\n }\n\n scale.push({ L, C, h });\n }\n\n return scale;\n}\n","import type { Hex, Oklch, Gamut } from \"../types.js\";\nimport {\n hexToOklch,\n oklchToSrgb,\n oklchToP3,\n oklchToHex,\n} from \"../conversions/pipeline.js\";\nimport { isInGamut } from \"../gamut/check.js\";\nimport { gamutMap } from \"../gamut/map.js\";\nimport { maxChroma } from \"../gamut/max-chroma.js\";\n\n/**\n * Result of resolving a color into scale-ready parameters.\n */\nexport interface ResolvedColor {\n /** The final OKLCH color, guaranteed in-gamut for the target gamut. */\n readonly oklch: Oklch;\n /** Hex representation (sRGB-clamped if the resolved color exceeds sRGB). */\n readonly hex: Hex;\n /** Whether the input was outside the target gamut and was remapped. */\n readonly wasRemapped: boolean;\n /** The original OKLCH before gamut mapping (identical to oklch if in-gamut). */\n readonly original: Oklch;\n /** Chroma lost during gamut mapping (0 if in-gamut). */\n readonly chromaShift: number;\n /** Hue from the resolved color. */\n readonly hue: number;\n /** Chroma as a fraction of the gamut boundary at this L/h (0–1). */\n readonly chromaRatio: number;\n}\n\n/**\n * Resolve a color (hex or OKLCH) into scale-ready parameters.\n *\n * If the color is outside the target gamut, it is perceptually mapped to the\n * nearest in-gamut color (chroma reduction at fixed L and h). The result\n * includes the derived hue and chromaRatio.\n *\n * Hex input is always valid sRGB, so `wasRemapped` will be false for hex\n * with gamut=\"srgb\". OKLCH input may be out of gamut and will be mapped.\n *\n * @param input A hex string (#RGB, #RRGGBB) or an OKLCH color.\n * @param isP3 Use Display P3 gamut instead of sRGB (default: false).\n */\nexport function resolveColor(\n input: Hex | Oklch,\n isP3: boolean = false,\n): ResolvedColor {\n const gamut: Gamut = isP3 ? \"display-p3\" : \"srgb\";\n const isHex = typeof input === \"string\";\n const original: Oklch = isHex ? hexToOklch(input) : input;\n\n // Hex encodes valid sRGB by definition, and sRGB ⊂ P3, so hex input\n // is always in-gamut for both supported gamuts. Skipping the round-trip\n // check avoids false negatives from floating-point drift.\n let inGamut: boolean;\n if (isHex) {\n inGamut = true;\n } else {\n const rgb =\n gamut === \"display-p3\" ? oklchToP3(original) : oklchToSrgb(original);\n inGamut = isInGamut(rgb);\n }\n\n const oklch = inGamut ? original : gamutMap(original, gamut);\n\n const boundary = maxChroma(oklch.L, oklch.h, gamut);\n const chromaRatio = boundary > 0 ? oklch.C / boundary : 0;\n\n return {\n oklch,\n hex: oklchToHex(oklch),\n wasRemapped: !inGamut,\n original,\n chromaShift: original.C - oklch.C,\n hue: oklch.h,\n chromaRatio: Math.min(1, chromaRatio),\n };\n}\n","import type { Hex, Oklch } from \"../types.js\";\nimport { resolveColor } from \"./resolve-color.js\";\nimport { lightnessToScaleT, resolveLightest, resolveDarkest } from \"./dynamic-range.js\";\nimport { DEFAULT_SCALE_STEPS } from \"../config.js\";\n\n/**\n * The result of deriving scale parameters from a key color.\n *\n * Spread `hue` and `chroma` directly into ScaleOptions, then use\n * `stepIndex` to locate the key color's position in the generated scale.\n */\nexport interface KeyColorResult {\n /** Derived hue angle — use directly as ScaleOptions.hue. */\n readonly hue: number;\n /**\n * Derived chroma shape — use directly as ScaleOptions.chroma.\n * - `amount`: how saturated the scale is (0–1, relative to gamut boundary).\n * - `balance`: where in the scale the key color's lightness falls (0 = lightest, 1 = darkest).\n */\n readonly chroma: { readonly amount: number; readonly balance: number };\n /** The step index in a scale of `steps` length where this color lands. */\n readonly stepIndex: number;\n /** Hex representation of the resolved color (sRGB-clamped if necessary). */\n readonly hex: Hex;\n /** The final OKLCH color, guaranteed in-gamut for the target gamut. */\n readonly oklch: Oklch;\n /** Whether the input was outside the target gamut and was remapped. */\n readonly wasRemapped: boolean;\n /** The original OKLCH before gamut mapping (identical to oklch if in-gamut). */\n readonly original: Oklch;\n}\n\n/**\n * Derive scale parameters from a known color.\n *\n * Given a hex or OKLCH color, returns the `hue` and `chroma` values\n * ready to spread into ScaleOptions. The chroma balance is derived from\n * where the color's lightness falls within the scale's lightness range,\n * so the chroma distribution is centered around the key color's position.\n *\n * @param color A hex string (#RGB or #RRGGBB) or an OKLCH color object.\n * @param options Scale context — must match the ScaleOptions you will use.\n * `contrast` values are slider values (0–1), same as ScaleOptions.contrast.\n * `steps` is the number of steps in the scale (default: 26).\n *\n * @example\n * const key = keyColor('#3B82F6');\n * const scale = generateScale({ hue: key.hue, chroma: key.chroma });\n * const matchedHex = oklchToHex(scale[key.stepIndex]);\n */\nexport function keyColor(\n color: Hex | Oklch,\n options?: {\n readonly isP3?: boolean;\n readonly contrast?: { readonly light?: number; readonly dark?: number };\n readonly steps?: number;\n },\n): KeyColorResult {\n const { isP3 = false, contrast, steps = DEFAULT_SCALE_STEPS } = options ?? {};\n const resolved = resolveColor(color, isP3);\n const lightestL = resolveLightest(contrast?.light ?? 1);\n const darkestL = resolveDarkest(contrast?.dark ?? 1);\n const balance = lightnessToScaleT(resolved.oklch.L, lightestL, darkestL);\n const stepIndex = Math.round(balance * Math.max(0, steps - 1));\n\n return {\n hue: resolved.hue,\n chroma: { amount: resolved.chromaRatio, balance },\n stepIndex,\n hex: resolved.hex,\n oklch: resolved.oklch,\n wasRemapped: resolved.wasRemapped,\n original: resolved.original,\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/constants.ts","../src/conversions/oklab.ts","../src/conversions/linear-srgb.ts","../src/conversions/linear-p3.ts","../src/conversions/srgb.ts","../src/conversions/hex.ts","../src/conversions/pipeline.ts","../src/gamut/check.ts","../src/color/difference.ts","../src/gamut/map.ts","../src/gamut/max-chroma.ts","../src/contrast/wcag.ts","../src/contrast/apca.ts","../src/color/interpolation.ts","../src/config.ts","../src/scale/hue-grade.ts","../src/scale/generate.ts","../src/scale/resolve-color.ts","../src/scale/dynamic-range.ts","../src/scale/key-color.ts"],"names":["toRad","scale"],"mappings":"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","file":"index.cjs","sourcesContent":["// ── sRGB Gamma Transfer (IEC 61966-2-1) ──\n\nexport const SRGB_GAMMA_THRESHOLD = 0.04045;\nexport const SRGB_GAMMA_THRESHOLD_LINEAR = 0.0031308;\nexport const SRGB_GAMMA_SLOPE = 12.92;\nexport const SRGB_GAMMA_EXPONENT = 2.4;\nexport const SRGB_GAMMA_OFFSET = 0.055;\nexport const SRGB_GAMMA_SCALE = 1.055;\n\n// ── Ottosson M1: Linear sRGB → LMS ──\n\nexport const LINEAR_SRGB_TO_LMS = [\n [0.4122214708, 0.5363325363, 0.0514459929],\n [0.2119034982, 0.6806995451, 0.1073969566],\n [0.0883024619, 0.2817188376, 0.6299787005],\n] as const;\n\n// ── Ottosson M2: LMS′ (cube-root) → OKLAB ──\n\nexport const LMS_PRIME_TO_OKLAB = [\n [+0.2104542553, +0.7936177850, -0.0040720468],\n [+1.9779984951, -2.4285922050, +0.4505937099],\n [+0.0259040371, +0.7827717662, -0.8086757660],\n] as const;\n\n// ── Inverse M2: OKLAB → LMS′ ──\n\nexport const OKLAB_TO_LMS_PRIME = [\n [1.0000000000, +0.3963377774, +0.2158037573],\n [1.0000000000, -0.1055613458, -0.0638541728],\n [1.0000000000, -0.0894841775, -1.2914855480],\n] as const;\n\n// ── Inverse M1: LMS → Linear sRGB ──\n\nexport const LMS_TO_LINEAR_SRGB = [\n [+4.0767416621, -3.3077115913, +0.2309699292],\n [-1.2684380046, +2.6097574011, -0.3413193965],\n [-0.0041960863, -0.7034186147, +1.7076147010],\n] as const;\n\n// ── Display P3 M1: Linear Display P3 → LMS ──\n// Derived: XYZ_to_LMS × P3_to_XYZ, where XYZ_to_LMS = M1_srgb × inv(sRGB_to_XYZ)\n\nexport const LINEAR_P3_TO_LMS = [\n [+0.4813791595, +0.4621155872, +0.0565406381],\n [+0.2288319169, +0.6532167007, +0.1179528072],\n [+0.0839457149, +0.2241651052, +0.6918912614],\n] as const;\n\n// ── Inverse P3 M1: LMS → Linear Display P3 ──\n\nexport const LMS_TO_LINEAR_P3 = [\n [+3.1277694390, -2.2570600176, +0.1291828502],\n [-1.0910091977, +2.4133065499, -0.3222615148],\n [-0.0260108068, -0.5080402362, +1.5340494942],\n] as const;\n\n// ── Gamut Mapping ──\n\nexport const GAMUT_EPSILON = 1e-6;\nexport const GAMUT_MAP_JND = 0.02;\nexport const GAMUT_MAP_EPSILON = 1e-4;\nexport const GAMUT_MAP_MAX_ITERATIONS = 50;\n\n// ── Achromatic Threshold ──\n\nexport const ACHROMATIC_THRESHOLD = 1e-10;\n\n// ── WCAG 2.x Luminance Coefficients ──\n\nexport const WCAG_R = 0.2126;\nexport const WCAG_G = 0.7152;\nexport const WCAG_B = 0.0722;\n\n// ── APCA-W3 (SA98G) Constants ──\n\nexport const APCA_MAIN_TRC = 2.4;\nexport const APCA_SRGB_R = 0.2126729;\nexport const APCA_SRGB_G = 0.7151522;\nexport const APCA_SRGB_B = 0.0721750;\nexport const APCA_NORM_BG = 0.56;\nexport const APCA_NORM_TXT = 0.57;\nexport const APCA_REV_TXT = 0.62;\nexport const APCA_REV_BG = 0.65;\nexport const APCA_BLK_THRS = 0.022;\nexport const APCA_BLK_CLMP = 1.414;\nexport const APCA_SCALE_BOW = 1.14;\nexport const APCA_SCALE_WOB = 1.14;\nexport const APCA_LO_BOW_OFFSET = 0.027;\nexport const APCA_LO_WOB_OFFSET = 0.027;\nexport const APCA_DELTA_Y_MIN = 0.0005;\nexport const APCA_LO_CLIP = 0.1;\n\n// ── Angle Math ──\n\nexport const DEG_TO_RAD = Math.PI / 180;\nexport const RAD_TO_DEG = 180 / Math.PI;\n","import type { Oklab, Oklch } from \"../types.js\";\nimport { ACHROMATIC_THRESHOLD, DEG_TO_RAD, RAD_TO_DEG } from \"../constants.js\";\n\n/** Convert OKLAB (cartesian) to OKLCH (cylindrical). Achromatic colors get h=0. */\nexport function oklabToOklch(lab: Oklab): Oklch {\n const C = Math.sqrt(lab.a * lab.a + lab.b * lab.b);\n\n if (C < ACHROMATIC_THRESHOLD) {\n return { L: lab.L, C: 0, h: 0 };\n }\n\n let h = Math.atan2(lab.b, lab.a) * RAD_TO_DEG;\n if (h < 0) h += 360;\n\n return { L: lab.L, C, h };\n}\n\n/** Convert OKLCH (cylindrical) to OKLAB (cartesian). */\nexport function oklchToOklab(lch: Oklch): Oklab {\n const hRad = lch.h * DEG_TO_RAD;\n return {\n L: lch.L,\n a: lch.C * Math.cos(hRad),\n b: lch.C * Math.sin(hRad),\n };\n}\n","import type { LinearSrgb, Oklab } from \"../types.js\";\nimport {\n LINEAR_SRGB_TO_LMS,\n LMS_PRIME_TO_OKLAB,\n LMS_TO_LINEAR_SRGB,\n OKLAB_TO_LMS_PRIME,\n} from \"../constants.js\";\n\n/** Convert Linear sRGB to OKLAB via Ottosson's direct M1/M2 matrices. */\nexport function linearSrgbToOklab(color: LinearSrgb): Oklab {\n // Step 1: Linear sRGB → LMS\n const l =\n LINEAR_SRGB_TO_LMS[0][0] * color.r +\n LINEAR_SRGB_TO_LMS[0][1] * color.g +\n LINEAR_SRGB_TO_LMS[0][2] * color.b;\n const m =\n LINEAR_SRGB_TO_LMS[1][0] * color.r +\n LINEAR_SRGB_TO_LMS[1][1] * color.g +\n LINEAR_SRGB_TO_LMS[1][2] * color.b;\n const s =\n LINEAR_SRGB_TO_LMS[2][0] * color.r +\n LINEAR_SRGB_TO_LMS[2][1] * color.g +\n LINEAR_SRGB_TO_LMS[2][2] * color.b;\n\n // Step 2: Cube root\n const lp = Math.cbrt(l);\n const mp = Math.cbrt(m);\n const sp = Math.cbrt(s);\n\n // Step 3: LMS′ → OKLAB\n return {\n L:\n LMS_PRIME_TO_OKLAB[0][0] * lp +\n LMS_PRIME_TO_OKLAB[0][1] * mp +\n LMS_PRIME_TO_OKLAB[0][2] * sp,\n a:\n LMS_PRIME_TO_OKLAB[1][0] * lp +\n LMS_PRIME_TO_OKLAB[1][1] * mp +\n LMS_PRIME_TO_OKLAB[1][2] * sp,\n b:\n LMS_PRIME_TO_OKLAB[2][0] * lp +\n LMS_PRIME_TO_OKLAB[2][1] * mp +\n LMS_PRIME_TO_OKLAB[2][2] * sp,\n };\n}\n\n/** Convert OKLAB to Linear sRGB via inverse M2/M1 matrices. */\nexport function oklabToLinearSrgb(color: Oklab): LinearSrgb {\n // Step 1: OKLAB → LMS′\n const lp =\n OKLAB_TO_LMS_PRIME[0][0] * color.L +\n OKLAB_TO_LMS_PRIME[0][1] * color.a +\n OKLAB_TO_LMS_PRIME[0][2] * color.b;\n const mp =\n OKLAB_TO_LMS_PRIME[1][0] * color.L +\n OKLAB_TO_LMS_PRIME[1][1] * color.a +\n OKLAB_TO_LMS_PRIME[1][2] * color.b;\n const sp =\n OKLAB_TO_LMS_PRIME[2][0] * color.L +\n OKLAB_TO_LMS_PRIME[2][1] * color.a +\n OKLAB_TO_LMS_PRIME[2][2] * color.b;\n\n // Step 2: Cube\n const l = lp * lp * lp;\n const m = mp * mp * mp;\n const s = sp * sp * sp;\n\n // Step 3: LMS → Linear sRGB\n return {\n r:\n LMS_TO_LINEAR_SRGB[0][0] * l +\n LMS_TO_LINEAR_SRGB[0][1] * m +\n LMS_TO_LINEAR_SRGB[0][2] * s,\n g:\n LMS_TO_LINEAR_SRGB[1][0] * l +\n LMS_TO_LINEAR_SRGB[1][1] * m +\n LMS_TO_LINEAR_SRGB[1][2] * s,\n b:\n LMS_TO_LINEAR_SRGB[2][0] * l +\n LMS_TO_LINEAR_SRGB[2][1] * m +\n LMS_TO_LINEAR_SRGB[2][2] * s,\n };\n}\n","import type { LinearSrgb, Oklab } from \"../types.js\";\nimport {\n LINEAR_P3_TO_LMS,\n LMS_PRIME_TO_OKLAB,\n LMS_TO_LINEAR_P3,\n OKLAB_TO_LMS_PRIME,\n} from \"../constants.js\";\n\n/** Convert Linear Display P3 to OKLAB via P3-specific M1 + shared M2. */\nexport function linearP3ToOklab(color: LinearSrgb): Oklab {\n // Step 1: Linear P3 → LMS\n const l =\n LINEAR_P3_TO_LMS[0][0] * color.r +\n LINEAR_P3_TO_LMS[0][1] * color.g +\n LINEAR_P3_TO_LMS[0][2] * color.b;\n const m =\n LINEAR_P3_TO_LMS[1][0] * color.r +\n LINEAR_P3_TO_LMS[1][1] * color.g +\n LINEAR_P3_TO_LMS[1][2] * color.b;\n const s =\n LINEAR_P3_TO_LMS[2][0] * color.r +\n LINEAR_P3_TO_LMS[2][1] * color.g +\n LINEAR_P3_TO_LMS[2][2] * color.b;\n\n // Step 2: Cube root\n const lp = Math.cbrt(l);\n const mp = Math.cbrt(m);\n const sp = Math.cbrt(s);\n\n // Step 3: LMS′ → OKLAB (shared M2)\n return {\n L:\n LMS_PRIME_TO_OKLAB[0][0] * lp +\n LMS_PRIME_TO_OKLAB[0][1] * mp +\n LMS_PRIME_TO_OKLAB[0][2] * sp,\n a:\n LMS_PRIME_TO_OKLAB[1][0] * lp +\n LMS_PRIME_TO_OKLAB[1][1] * mp +\n LMS_PRIME_TO_OKLAB[1][2] * sp,\n b:\n LMS_PRIME_TO_OKLAB[2][0] * lp +\n LMS_PRIME_TO_OKLAB[2][1] * mp +\n LMS_PRIME_TO_OKLAB[2][2] * sp,\n };\n}\n\n/** Convert OKLAB to Linear Display P3 via shared inverse M2 + P3-specific inverse M1. */\nexport function oklabToLinearP3(color: Oklab): LinearSrgb {\n // Step 1: OKLAB → LMS′ (shared inverse M2)\n const lp =\n OKLAB_TO_LMS_PRIME[0][0] * color.L +\n OKLAB_TO_LMS_PRIME[0][1] * color.a +\n OKLAB_TO_LMS_PRIME[0][2] * color.b;\n const mp =\n OKLAB_TO_LMS_PRIME[1][0] * color.L +\n OKLAB_TO_LMS_PRIME[1][1] * color.a +\n OKLAB_TO_LMS_PRIME[1][2] * color.b;\n const sp =\n OKLAB_TO_LMS_PRIME[2][0] * color.L +\n OKLAB_TO_LMS_PRIME[2][1] * color.a +\n OKLAB_TO_LMS_PRIME[2][2] * color.b;\n\n // Step 2: Cube\n const l = lp * lp * lp;\n const m = mp * mp * mp;\n const s = sp * sp * sp;\n\n // Step 3: LMS → Linear P3\n return {\n r:\n LMS_TO_LINEAR_P3[0][0] * l +\n LMS_TO_LINEAR_P3[0][1] * m +\n LMS_TO_LINEAR_P3[0][2] * s,\n g:\n LMS_TO_LINEAR_P3[1][0] * l +\n LMS_TO_LINEAR_P3[1][1] * m +\n LMS_TO_LINEAR_P3[1][2] * s,\n b:\n LMS_TO_LINEAR_P3[2][0] * l +\n LMS_TO_LINEAR_P3[2][1] * m +\n LMS_TO_LINEAR_P3[2][2] * s,\n };\n}\n","import type { LinearSrgb, Srgb } from \"../types.js\";\nimport {\n SRGB_GAMMA_EXPONENT,\n SRGB_GAMMA_OFFSET,\n SRGB_GAMMA_SCALE,\n SRGB_GAMMA_SLOPE,\n SRGB_GAMMA_THRESHOLD,\n SRGB_GAMMA_THRESHOLD_LINEAR,\n} from \"../constants.js\";\n\n/** Decode a single sRGB gamma-encoded channel to linear light. */\nexport function srgbChannelToLinear(value: number): number {\n return value <= SRGB_GAMMA_THRESHOLD\n ? value / SRGB_GAMMA_SLOPE\n : ((value + SRGB_GAMMA_OFFSET) / SRGB_GAMMA_SCALE) ** SRGB_GAMMA_EXPONENT;\n}\n\n/** Encode a single linear light channel to sRGB gamma. */\nexport function linearChannelToSrgb(value: number): number {\n return value <= SRGB_GAMMA_THRESHOLD_LINEAR\n ? value * SRGB_GAMMA_SLOPE\n : SRGB_GAMMA_SCALE * value ** (1 / SRGB_GAMMA_EXPONENT) - SRGB_GAMMA_OFFSET;\n}\n\n/** Convert an sRGB color to Linear sRGB. */\nexport function srgbToLinearSrgb(color: Srgb): LinearSrgb {\n return {\n r: srgbChannelToLinear(color.r),\n g: srgbChannelToLinear(color.g),\n b: srgbChannelToLinear(color.b),\n };\n}\n\n/** Convert a Linear sRGB color to sRGB. */\nexport function linearSrgbToSrgb(color: LinearSrgb): Srgb {\n return {\n r: linearChannelToSrgb(color.r),\n g: linearChannelToSrgb(color.g),\n b: linearChannelToSrgb(color.b),\n };\n}\n","import type { Hex, Srgb } from \"../types.js\";\n\n/** Parse a hex color string (#RGB, #RRGGBB, or bare) to sRGB [0,1]. */\nexport function hexToSrgb(hex: string): Srgb {\n let h = hex.startsWith(\"#\") ? hex.slice(1) : hex;\n\n if (h.length === 3) {\n h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];\n }\n\n const n = parseInt(h, 16);\n return {\n r: ((n >> 16) & 0xff) / 255,\n g: ((n >> 8) & 0xff) / 255,\n b: (n & 0xff) / 255,\n };\n}\n\n/** Convert sRGB [0,1] to lowercase hex string (#rrggbb). Clamps to [0,1]. */\nexport function srgbToHex(color: Srgb): Hex {\n const r = Math.round(Math.max(0, Math.min(1, color.r)) * 255);\n const g = Math.round(Math.max(0, Math.min(1, color.g)) * 255);\n const b = Math.round(Math.max(0, Math.min(1, color.b)) * 255);\n return `#${((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1)}` as Hex;\n}\n","import type { Hex, Oklab, Oklch, Srgb } from \"../types.js\";\nimport { oklabToOklch, oklchToOklab } from \"./oklab.js\";\nimport { linearSrgbToOklab, oklabToLinearSrgb } from \"./linear-srgb.js\";\nimport { linearP3ToOklab, oklabToLinearP3 } from \"./linear-p3.js\";\nimport { linearSrgbToSrgb, srgbToLinearSrgb } from \"./srgb.js\";\nimport { hexToSrgb, srgbToHex } from \"./hex.js\";\n\n/** Convert sRGB to OKLCH. */\nexport function srgbToOklch(color: Srgb): Oklch {\n return oklabToOklch(linearSrgbToOklab(srgbToLinearSrgb(color)));\n}\n\n/** Convert OKLCH to sRGB. May produce out-of-gamut values (channels outside [0,1]). */\nexport function oklchToSrgb(color: Oklch): Srgb {\n return linearSrgbToSrgb(oklabToLinearSrgb(oklchToOklab(color)));\n}\n\n/** Convert sRGB to OKLAB. */\nexport function srgbToOklab(color: Srgb): Oklab {\n return linearSrgbToOklab(srgbToLinearSrgb(color));\n}\n\n/** Convert OKLAB to sRGB. May produce out-of-gamut values. */\nexport function oklabToSrgb(color: Oklab): Srgb {\n return linearSrgbToSrgb(oklabToLinearSrgb(color));\n}\n\n/** Convert hex to OKLCH. */\nexport function hexToOklch(hex: string): Oklch {\n return srgbToOklch(hexToSrgb(hex));\n}\n\n/** Convert OKLCH to hex. Clamps to sRGB gamut before hex encoding. */\nexport function oklchToHex(color: Oklch): Hex {\n const srgb = oklchToSrgb(color);\n return srgbToHex({\n r: Math.max(0, Math.min(1, srgb.r)),\n g: Math.max(0, Math.min(1, srgb.g)),\n b: Math.max(0, Math.min(1, srgb.b)),\n });\n}\n\n/** Convert Display P3 to OKLCH. */\nexport function p3ToOklch(color: Srgb): Oklch {\n return oklabToOklch(linearP3ToOklab(srgbToLinearSrgb(color)));\n}\n\n/** Convert OKLCH to Display P3. May produce out-of-gamut values (channels outside [0,1]). */\nexport function oklchToP3(color: Oklch): Srgb {\n return linearSrgbToSrgb(oklabToLinearP3(oklchToOklab(color)));\n}\n\n/** Convert OKLCH to a CSS `color(display-p3 r g b)` string. Clamps channels to [0,1]. */\nexport function oklchToP3Css(color: Oklch): string {\n const p3 = oklchToP3(color);\n const r = Math.max(0, Math.min(1, p3.r)).toFixed(4);\n const g = Math.max(0, Math.min(1, p3.g)).toFixed(4);\n const b = Math.max(0, Math.min(1, p3.b)).toFixed(4);\n return `color(display-p3 ${r} ${g} ${b})`;\n}\n","import type { Srgb } from \"../types.js\";\nimport { GAMUT_EPSILON } from \"../constants.js\";\n\n/** Check if sRGB channels are within [0, 1] (with epsilon tolerance). */\nexport function isInGamut(color: Srgb): boolean {\n return (\n color.r >= -GAMUT_EPSILON &&\n color.r <= 1 + GAMUT_EPSILON &&\n color.g >= -GAMUT_EPSILON &&\n color.g <= 1 + GAMUT_EPSILON &&\n color.b >= -GAMUT_EPSILON &&\n color.b <= 1 + GAMUT_EPSILON\n );\n}\n\n/** Clamp sRGB channels to [0, 1]. */\nexport function clampSrgb(color: Srgb): Srgb {\n return {\n r: Math.max(0, Math.min(1, color.r)),\n g: Math.max(0, Math.min(1, color.g)),\n b: Math.max(0, Math.min(1, color.b)),\n };\n}\n\n/** Clamp Display P3 channels to [0, 1]. */\nexport const clampP3 = clampSrgb;\n","import type { Oklab, Oklch } from \"../types.js\";\nimport { oklchToOklab } from \"../conversions/oklab.js\";\n\n/** Compute deltaEOK (Euclidean distance in OKLAB) between two OKLCH colors. */\nexport function deltaEOK(a: Oklch, b: Oklch): number {\n return deltaEOKLab(oklchToOklab(a), oklchToOklab(b));\n}\n\n/** Compute deltaEOK directly from OKLAB values. */\nexport function deltaEOKLab(a: Oklab, b: Oklab): number {\n const dL = a.L - b.L;\n const da = a.a - b.a;\n const db = a.b - b.b;\n return Math.sqrt(dL * dL + da * da + db * db);\n}\n","import type { Gamut, Oklch, Srgb } from \"../types.js\";\nimport {\n GAMUT_EPSILON,\n GAMUT_MAP_EPSILON,\n GAMUT_MAP_JND,\n GAMUT_MAP_MAX_ITERATIONS,\n} from \"../constants.js\";\nimport { oklchToSrgb, oklchToP3 } from \"../conversions/pipeline.js\";\nimport { isInGamut, clampSrgb } from \"./check.js\";\nimport { deltaEOKLab } from \"../color/difference.js\";\nimport { oklchToOklab } from \"../conversions/oklab.js\";\nimport { linearSrgbToOklab } from \"../conversions/linear-srgb.js\";\nimport { linearP3ToOklab } from \"../conversions/linear-p3.js\";\nimport { srgbToLinearSrgb } from \"../conversions/srgb.js\";\n\n/**\n * Map an OKLCH color into the target gamut using the CSS Color Level 4 algorithm.\n * Reduces chroma at fixed L and h via binary search with deltaEOK JND check.\n * @param gamut Target gamut (default: 'srgb').\n */\nexport function gamutMap(color: Oklch, gamut: Gamut = \"srgb\"): Oklch {\n const toRgb = gamut === \"display-p3\" ? oklchToP3 : oklchToSrgb;\n const rgbToOklab =\n gamut === \"display-p3\"\n ? (c: Srgb) => linearP3ToOklab(srgbToLinearSrgb(c))\n : (c: Srgb) => linearSrgbToOklab(srgbToLinearSrgb(c));\n\n // Already in gamut\n const rgb = toRgb(color);\n if (isInGamut(rgb)) return color;\n\n // Edge cases: black and white\n if (color.L <= GAMUT_EPSILON) return { L: 0, C: 0, h: color.h };\n if (color.L >= 1 - GAMUT_EPSILON) return { L: 1, C: 0, h: color.h };\n\n let lo = 0;\n let hi = color.C;\n\n for (let i = 0; i < GAMUT_MAP_MAX_ITERATIONS; i++) {\n const midC = (lo + hi) / 2;\n const candidate: Oklch = { L: color.L, C: midC, h: color.h };\n const candidateRgb = toRgb(candidate);\n\n if (isInGamut(candidateRgb)) {\n lo = midC;\n } else {\n // Clip and check JND\n const clipped = clampSrgb(candidateRgb);\n const clippedLab = rgbToOklab(clipped);\n const candidateLab = oklchToOklab(candidate);\n const dE = deltaEOKLab(clippedLab, candidateLab);\n\n if (dE < GAMUT_MAP_JND) {\n // Clipped version is perceptually close enough — converge here.\n // Return lo (last confirmed in-gamut chroma) to guarantee gamut safety.\n break;\n }\n\n hi = midC;\n }\n\n if (hi - lo < GAMUT_MAP_EPSILON) break;\n }\n\n return { L: color.L, C: lo, h: color.h };\n}\n","import type { Gamut, Oklch } from \"../types.js\";\nimport { GAMUT_MAP_MAX_ITERATIONS } from \"../constants.js\";\nimport { oklchToSrgb, oklchToP3 } from \"../conversions/pipeline.js\";\nimport { isInGamut } from \"./check.js\";\n\n/**\n * Find the maximum in-gamut chroma for a given OKLCH lightness and hue.\n *\n * Binary search over [0, upperBound], converging to 1e-6 precision.\n * Upper bounds are empirically safe ceilings — no in-gamut color at any\n * lightness or hue exceeds C = 0.4 in sRGB or C = 0.5 in Display P3.\n * Searching beyond these would waste iterations with no benefit.\n *\n * Returns 0 for L ≤ 0 or L ≥ 1 (pure black and white carry no chroma).\n */\nexport function maxChroma(L: number, h: number, gamut: Gamut = \"srgb\"): number {\n if (L <= 0 || L >= 1) return 0;\n\n const toRgb = gamut === \"display-p3\" ? oklchToP3 : oklchToSrgb;\n let lo = 0;\n let hi = gamut === \"display-p3\" ? 0.5 : 0.4;\n\n for (let i = 0; i < GAMUT_MAP_MAX_ITERATIONS; i++) {\n const mid = (lo + hi) / 2;\n const color: Oklch = { L, C: mid, h };\n const rgb = toRgb(color);\n\n if (isInGamut(rgb)) {\n lo = mid;\n } else {\n hi = mid;\n }\n\n if (hi - lo < 1e-6) break;\n }\n\n return lo;\n}\n","import type { Srgb } from \"../types.js\";\nimport { WCAG_R, WCAG_G, WCAG_B } from \"../constants.js\";\nimport { srgbChannelToLinear } from \"../conversions/srgb.js\";\n\n/** Compute WCAG 2.x relative luminance [0, 1] from an sRGB color. */\nexport function wcagLuminance(color: Srgb): number {\n return (\n WCAG_R * srgbChannelToLinear(color.r) +\n WCAG_G * srgbChannelToLinear(color.g) +\n WCAG_B * srgbChannelToLinear(color.b)\n );\n}\n\n/**\n * Compute WCAG 2.x contrast ratio between two sRGB colors.\n * Returns a value in [1, 21]. Symmetric (order doesn't matter).\n */\nexport function wcagContrast(a: Srgb, b: Srgb): number {\n const lA = wcagLuminance(a);\n const lB = wcagLuminance(b);\n const lighter = Math.max(lA, lB);\n const darker = Math.min(lA, lB);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\n/**\n * Choose black or white text for maximum WCAG contrast against a background.\n * @returns `\"#000000\"` or `\"#ffffff\"`.\n */\nexport function contrastTextHex(background: Srgb): \"#000000\" | \"#ffffff\" {\n const white: Srgb = { r: 1, g: 1, b: 1 };\n const black: Srgb = { r: 0, g: 0, b: 0 };\n return wcagContrast(white, background) > wcagContrast(black, background)\n ? \"#ffffff\"\n : \"#000000\";\n}\n","import type { Srgb } from \"../types.js\";\nimport {\n APCA_MAIN_TRC,\n APCA_SRGB_R,\n APCA_SRGB_G,\n APCA_SRGB_B,\n APCA_NORM_BG,\n APCA_NORM_TXT,\n APCA_REV_TXT,\n APCA_REV_BG,\n APCA_BLK_THRS,\n APCA_BLK_CLMP,\n APCA_SCALE_BOW,\n APCA_SCALE_WOB,\n APCA_LO_BOW_OFFSET,\n APCA_LO_WOB_OFFSET,\n APCA_DELTA_Y_MIN,\n APCA_LO_CLIP,\n} from \"../constants.js\";\n\n/**\n * Compute APCA-W3 Lc (Lightness Contrast) between text and background.\n *\n * Returns a signed value in roughly [-108, +106]:\n * Positive = dark text on light background (BoW)\n * Negative = light text on dark background (WoB)\n * 0 = no meaningful contrast\n *\n * IMPORTANT: Uses its own linearization (simple 2.4 gamma),\n * NOT the IEC piecewise sRGB transfer function.\n */\n/**\n * Practical maximum APCA Lc magnitude used for normalization.\n * BoW tops out at ~+106, WoB at ~-108; we use 108 as a symmetric ceiling.\n */\nexport const APCA_LC_MAX = 108;\n\n/**\n * Normalize a raw APCA Lc value to the range [-1, +1].\n * +1 = maximum dark-on-light contrast (BoW)\n * -1 = maximum light-on-dark contrast (WoB)\n * 0 = no meaningful contrast\n */\nexport function apcaToNormalized(lc: number): number {\n return Math.max(-1, Math.min(1, lc / APCA_LC_MAX));\n}\n\n/**\n * Convert a normalized contrast value [-1, +1] back to a raw APCA Lc value.\n */\nexport function normalizedToApca(normalized: number): number {\n return normalized * APCA_LC_MAX;\n}\n\nexport function apcaContrast(textColor: Srgb, bgColor: Srgb): number {\n // Step 1: Linearize with simple 2.4 gamma and compute Y\n let txtY =\n APCA_SRGB_R * textColor.r ** APCA_MAIN_TRC +\n APCA_SRGB_G * textColor.g ** APCA_MAIN_TRC +\n APCA_SRGB_B * textColor.b ** APCA_MAIN_TRC;\n\n let bgY =\n APCA_SRGB_R * bgColor.r ** APCA_MAIN_TRC +\n APCA_SRGB_G * bgColor.g ** APCA_MAIN_TRC +\n APCA_SRGB_B * bgColor.b ** APCA_MAIN_TRC;\n\n // Step 2: Soft black clamp\n if (txtY < APCA_BLK_THRS) {\n txtY += (APCA_BLK_THRS - txtY) ** APCA_BLK_CLMP;\n }\n if (bgY < APCA_BLK_THRS) {\n bgY += (APCA_BLK_THRS - bgY) ** APCA_BLK_CLMP;\n }\n\n // Step 3: Delta Y check\n if (Math.abs(bgY - txtY) < APCA_DELTA_Y_MIN) return 0;\n\n // Step 4: Polarity-aware contrast\n let sapc: number;\n\n if (bgY > txtY) {\n // Dark text on light background (BoW)\n sapc = (bgY ** APCA_NORM_BG - txtY ** APCA_NORM_TXT) * APCA_SCALE_BOW;\n return sapc < APCA_LO_CLIP ? 0 : (sapc - APCA_LO_BOW_OFFSET) * 100;\n } else {\n // Light text on dark background (WoB)\n sapc = (bgY ** APCA_REV_BG - txtY ** APCA_REV_TXT) * APCA_SCALE_WOB;\n return sapc > -APCA_LO_CLIP ? 0 : (sapc + APCA_LO_WOB_OFFSET) * 100;\n }\n}\n","import type { Oklch } from \"../types.js\";\nimport { ACHROMATIC_THRESHOLD } from \"../constants.js\";\n\n/**\n * Linearly interpolate between two OKLCH colors.\n *\n * L and C are linearly interpolated. Hue uses shortest-arc interpolation.\n * Achromatic colors (C near zero) inherit the other color's hue to avoid\n * meaningless hue sweeps through the achromatic pole.\n */\nexport function mix(a: Oklch, b: Oklch, t: number): Oklch {\n const L = a.L + (b.L - a.L) * t;\n const C = a.C + (b.C - a.C) * t;\n\n // Resolve hue — handle achromatic inputs\n const aIsAchromatic = a.C < ACHROMATIC_THRESHOLD;\n const bIsAchromatic = b.C < ACHROMATIC_THRESHOLD;\n\n if (aIsAchromatic && bIsAchromatic) {\n return { L, C, h: 0 };\n }\n\n const hA = aIsAchromatic ? b.h : a.h;\n const hB = bIsAchromatic ? a.h : b.h;\n\n // Shortest-arc hue interpolation\n let delta = hB - hA;\n if (delta > 180) delta -= 360;\n if (delta < -180) delta += 360;\n\n let h = hA + delta * t;\n if (h < 0) h += 360;\n if (h >= 360) h -= 360;\n\n return { L, C, h };\n}\n","/**\n * Design constants — the values you tune by hand.\n *\n * Edit this file to adjust the perceptual behavior of every scale and\n * grading operation across the library.\n */\n\n// ── Scale defaults ────────────────────────────────────────────────────────────\n\n/**\n * Default number of steps in a generated scale.\n * Fixed at 26 — enough for a full design token set with fine lightness\n * increments without redundancy.\n */\nexport const DEFAULT_SCALE_STEPS = 26;\n\n/**\n * Default hue when none is provided.\n * 0° is the start of the OKLCH hue wheel (red region). Arbitrary but\n * deterministic — callers should always supply an explicit hue.\n */\nexport const DEFAULT_HUE = 0;\n\n// ── Dynamic range ─────────────────────────────────────────────────────────────\n\n/**\n * Lightest step's lightness when the whites slider is at 0 (Display P3).\n * P3's wider gamut can reproduce near-whites that clip in sRGB.\n */\nexport const MIN_LIGHTEST_L_P3 = 0.98;\n\n/**\n * Lightest step's lightness when the whites slider is at 0 (sRGB).\n * slider 0 → L = MIN_LIGHTEST_L, slider 1 → L = 1.0 (pure white).\n */\nexport const MIN_LIGHTEST_L = 0.92;\n\n/**\n * Darkest step's lightness when the darks slider is at 0 (sRGB).\n * slider 0 → L = MAX_DARKEST_L, slider 1 → L = 0.0 (pure black).\n */\nexport const MAX_DARKEST_L = 0.20;\n\n/**\n * Darkest step's lightness when the darks slider is at 0 (Display P3).\n * P3's wider gamut can reproduce near-blacks that clip in sRGB.\n */\nexport const MAX_DARKEST_L_P3 = 0.14;\n\n// ── Hue grading ───────────────────────────────────────────────────────────────\n\n/**\n * How far global grading reaches into the scale from each end (0–1).\n * Light grading fades to zero at t = GRADING_REACH.\n * Dark grading fades to zero at t = 1 − GRADING_REACH.\n */\nexport const GRADING_REACH = 3 / 5;\n\n/** Maximum amount for global grading. Inputs above this are clamped. */\nexport const MAX_GRADING_AMOUNT = 0.25;\n\n/**\n * Fraction of the gamut boundary injected as chroma when global grading\n * is active. Ensures grading has a visible tinting effect even on\n * achromatic (chroma.amount = 0) palettes.\n *\n * Only global grading injects chroma — per-palette shift does not.\n */\nexport const GRADING_CHROMA_RATIO = 0.5;\n\n/**\n * How far per-palette hue shift reaches into the scale from each end (0–1).\n * Slightly wider than GRADING_REACH to give per-palette shifts more room.\n */\nexport const SHIFT_REACH = 2 / 3;\n\n/** Maximum amount for per-palette hue shift. Inputs above this are clamped. */\nexport const MAX_SHIFT_AMOUNT = 0.5;\n\n// ── Color difference ──────────────────────────────────────────────────────────\n\n/**\n * Just-noticeable difference threshold (deltaEOK).\n * Colors with distance below this are considered perceptually identical.\n * Used to classify color matches as exact vs. fallback.\n */\nexport const PERCEPTUAL_JND = 0.02;\n","/**\n * Global hue grading — shifts each palette's base hue toward shared\n * target hues at the light and dark scale endpoints.\n *\n * Light grading fades from full at the lightest step to zero at GRADING_REACH.\n * Dark grading fades from zero at (1 - GRADING_REACH) to full at the darkest step.\n * In the overlap zone, both shifts are additive (commutative).\n */\n\nimport {\n GRADING_REACH,\n MAX_GRADING_AMOUNT,\n SHIFT_REACH,\n MAX_SHIFT_AMOUNT,\n} from \"../config.js\";\n\nexport interface Grading {\n /** Hue grading for the light end of the scale. */\n readonly light?: { readonly hue: number; readonly amount: number };\n /** Hue grading for the dark end of the scale. */\n readonly dark?: { readonly hue: number; readonly amount: number };\n}\n\n/** Per-palette hue shift (one end only). */\nexport interface Shift {\n /** Target hue to shift toward (0–360°). */\n readonly hue: number;\n /** Blend strength (0–MAX_SHIFT_AMOUNT). */\n readonly amount: number;\n /** Which end to affect. `true` = light end, `false`/omitted = dark end (default). */\n readonly light?: boolean;\n}\n\n/**\n * Compute the graded hue at position `t` in the scale.\n *\n * Uses vector interpolation in Cartesian space rather than angular deltas\n * to avoid the shortest-arc discontinuity at 180° (where the direction\n * of rotation flips abruptly). Each grade's displacement is computed as\n * a vector offset from the base hue, and displacements are additive\n * (commutative — order doesn't matter).\n *\n * @param baseHue The palette's own hue (0–360°).\n * @param t Position in the scale: 0 = lightest, 1 = darkest.\n * @param grade Hue grade configuration.\n * @param reach How far each grade reaches into the scale (default: GRADING_REACH).\n * @param maxIntensity Maximum amount clamp (default: MAX_GRADING_AMOUNT).\n * @returns The graded hue in degrees (0–360).\n */\nexport function gradeHue(\n baseHue: number,\n t: number,\n grade: Grading,\n reach: number = GRADING_REACH,\n maxIntensity: number = MAX_GRADING_AMOUNT,\n): number {\n const li = Math.max(0, Math.min(maxIntensity, grade.light?.amount ?? 0));\n const di = Math.max(0, Math.min(maxIntensity, grade.dark?.amount ?? 0));\n\n // Early exit: no grading\n if (li === 0 && di === 0) return baseHue;\n\n // Light influence: cosine fade from 1 at t=0 to 0 at t=reach\n const lightInfluence =\n t <= reach ? 0.5 * (1 + Math.cos((Math.PI * t) / reach)) : 0;\n\n // Dark influence: cosine fade from 0 at t=(1-reach) to 1 at t=1\n const darkInfluence =\n t >= 1 - reach\n ? 0.5 * (1 + Math.cos((Math.PI * (1 - t)) / reach))\n : 0;\n\n // Base hue as unit vector\n const toRad = Math.PI / 180;\n const baseRad = baseHue * toRad;\n const bx = Math.cos(baseRad);\n const by = Math.sin(baseRad);\n\n // Accumulate displacements in Cartesian space\n let dx = 0;\n let dy = 0;\n\n if (lightInfluence > 0 && li > 0) {\n const blend = lightInfluence * li;\n const lRad = (grade.light!.hue) * toRad;\n dx += blend * (Math.cos(lRad) - bx);\n dy += blend * (Math.sin(lRad) - by);\n }\n\n if (darkInfluence > 0 && di > 0) {\n const blend = darkInfluence * di;\n const dRad = (grade.dark!.hue) * toRad;\n dx += blend * (Math.cos(dRad) - bx);\n dy += blend * (Math.sin(dRad) - by);\n }\n\n // Reconstruct hue from displaced vector\n const rx = bx + dx;\n const ry = by + dy;\n\n // Safety: collapsed vector (opposite hues at exactly 50% blend)\n if (rx * rx + ry * ry < 1e-20) return baseHue;\n\n return ((Math.atan2(ry, rx) / toRad) + 360) % 360;\n}\n\n/**\n * Compute the combined grading influence at position `t` (0–1).\n *\n * Returns a scalar in [0, 1] representing how strongly global grading\n * affects position `t`. This is the maximum of the light and dark\n * cosine-fade envelopes, each scaled by its respective amount.\n *\n * Used by the chroma injection system to tint achromatic palettes\n * proportionally to grading strength.\n */\nexport function gradingInfluence(t: number, grading: Grading): number {\n const li = Math.max(0, Math.min(MAX_GRADING_AMOUNT, grading.light?.amount ?? 0));\n const di = Math.max(0, Math.min(MAX_GRADING_AMOUNT, grading.dark?.amount ?? 0));\n\n if (li === 0 && di === 0) return 0;\n\n const lightInfluence =\n t <= GRADING_REACH ? 0.5 * (1 + Math.cos((Math.PI * t) / GRADING_REACH)) : 0;\n\n const darkInfluence =\n t >= 1 - GRADING_REACH\n ? 0.5 * (1 + Math.cos((Math.PI * (1 - t)) / GRADING_REACH))\n : 0;\n\n const lightBlend = lightInfluence * (li / MAX_GRADING_AMOUNT);\n const darkBlend = darkInfluence * (di / MAX_GRADING_AMOUNT);\n\n return Math.max(lightBlend, darkBlend);\n}\n\n/**\n * Resolve the final hue at position `t`, applying local shift first, then global grading.\n *\n * This is the canonical composition: per-palette shift (using SHIFT_REACH /\n * MAX_SHIFT_AMOUNT) first, then global grading (using GRADING_REACH /\n * MAX_GRADING_AMOUNT) on top — so grading's influence is preserved at full\n * strength across all palettes, keeping them visually coherent.\n *\n * @param baseHue The palette's own hue (0–360°).\n * @param t Position in the scale: 0 = lightest, 1 = darkest.\n * @param globalGrade Global grading (shared across palettes), or undefined.\n * @param localGrade Local grading (per-palette, expanded from Shift), or undefined.\n * @returns The fully graded hue in degrees (0–360).\n */\nexport function resolveGradedHue(\n baseHue: number,\n t: number,\n globalGrade?: Grading,\n localGrade?: Grading,\n): number {\n let h = baseHue;\n if (localGrade) h = gradeHue(h, t, localGrade, SHIFT_REACH, MAX_SHIFT_AMOUNT);\n if (globalGrade) h = gradeHue(h, t, globalGrade);\n return h;\n}\n\n/**\n * Adapt a Shift into a one-sided Grading so it can be passed to gradeHue.\n *\n * The Shift interface is flat (hue, amount, light?) for ergonomic API use,\n * but gradeHue operates on the Grading shape (light/dark sub-objects).\n * This function bridges the two, activating only the requested end.\n *\n * @param hue Target hue for the active side (0–360°).\n * @param amount Blend strength for the active side.\n * @param light `true` = light end, `false`/omitted = dark end (default).\n */\nexport function buildOneSidedGrade(\n hue: number,\n amount: number,\n light: boolean = false,\n): Grading {\n return light\n ? { light: { hue, amount } }\n : { dark: { hue, amount } };\n}\n","import type { Oklch } from \"../types.js\";\nimport { maxChroma } from \"../gamut/max-chroma.js\";\nimport type { Grading, Shift } from \"./hue-grade.js\";\nimport { resolveGradedHue, buildOneSidedGrade } from \"./hue-grade.js\";\nimport {\n DEFAULT_SCALE_STEPS,\n DEFAULT_HUE,\n GRADING_CHROMA_RATIO,\n GRADING_REACH,\n MAX_GRADING_AMOUNT,\n MIN_LIGHTEST_L,\n MAX_DARKEST_L,\n MIN_LIGHTEST_L_P3,\n MAX_DARKEST_L_P3,\n} from \"../config.js\";\n\ntype Gamut = \"srgb\" | \"display-p3\";\nconst toRad = Math.PI / 180;\n\n/**\n * Apply grading as an additive chroma overlay.\n *\n * Builds per-side chroma vectors pointing at the grading TARGET hues\n * (not the palette's hue) and adds them to the palette's existing\n * chroma in Cartesian (a, b) space. This ensures grading tints even\n * fully achromatic palettes without the base hue leaking through.\n */\nfunction applyGradingOverlay(\n C: number, h: number, L: number, t: number,\n grading: Grading, gamut: Gamut,\n): { C: number; h: number } {\n const li = Math.max(0, Math.min(MAX_GRADING_AMOUNT, grading.light?.amount ?? 0));\n const di = Math.max(0, Math.min(MAX_GRADING_AMOUNT, grading.dark?.amount ?? 0));\n if (li === 0 && di === 0) return { C, h };\n\n // Per-side cosine-fade influences\n const lightFade = t <= GRADING_REACH\n ? 0.5 * (1 + Math.cos((Math.PI * t) / GRADING_REACH)) : 0;\n const darkFade = t >= 1 - GRADING_REACH\n ? 0.5 * (1 + Math.cos((Math.PI * (1 - t)) / GRADING_REACH)) : 0;\n\n const lightBlend = lightFade * (li / MAX_GRADING_AMOUNT);\n const darkBlend = darkFade * (di / MAX_GRADING_AMOUNT);\n if (lightBlend === 0 && darkBlend === 0) return { C, h };\n\n // Palette's existing chroma as Cartesian vector\n const hRad = h * toRad;\n let a = C * Math.cos(hRad);\n let b = C * Math.sin(hRad);\n\n // Add overlay vectors at grading TARGET hues\n if (lightBlend > 0) {\n const lh = grading.light!.hue;\n const lRad = lh * toRad;\n const lC = maxChroma(L, lh, gamut) * GRADING_CHROMA_RATIO * lightBlend;\n a += lC * Math.cos(lRad);\n b += lC * Math.sin(lRad);\n }\n if (darkBlend > 0) {\n const dh = grading.dark!.hue;\n const dRad = dh * toRad;\n const dC = maxChroma(L, dh, gamut) * GRADING_CHROMA_RATIO * darkBlend;\n a += dC * Math.cos(dRad);\n b += dC * Math.sin(dRad);\n }\n\n // Convert back to polar\n let newC = Math.sqrt(a * a + b * b);\n let newH = ((Math.atan2(b, a) / toRad) + 360) % 360;\n\n // Clamp to gamut at the resulting hue\n newC = Math.min(newC, maxChroma(L, newH, gamut));\n\n return { C: newC, h: newH };\n}\n\nexport interface ScaleOptions {\n /**\n * Tonal range of the scale.\n * - `light`: how light the lightest step is (0–1). Default: 1.\n * 0 → L = MIN_LIGHTEST_L (0.96), 1 → L = 1.0 (pure white).\n * - `dark`: how dark the darkest step is (0–1). Default: 1.\n * 0 → L = MAX_DARKEST_L (0.16), 1 → L = 0.0 (pure black).\n */\n readonly contrast?: { readonly light?: number; readonly dark?: number };\n /**\n * Hue angle in degrees (0–360). Default: DEFAULT_HUE (0).\n * Every step shares this base hue unless shifted by `grading` or `shift`.\n */\n readonly hue?: number;\n /**\n * Chroma shape of the scale.\n * - `amount`: how much of the available gamut to use (0–1). Default: 0.\n * 0 = fully achromatic (default), 1 = maximum in-gamut chroma at each lightness.\n * - `balance`: how chroma is distributed along the lightness range (0–1).\n * 0 = chroma concentrated toward the lightest end, 1 = toward the darkest end,\n * 0.5 = natural distribution (default, follows gamut boundary shape).\n */\n readonly chroma?: { readonly amount?: number; readonly balance?: number };\n /**\n * Global hue grading. When provided, the hue at each step is shifted\n * toward target hues based on position in the scale.\n * Light grading affects the lightest 3/5, dark grading affects the\n * darkest 3/5, with additive overlap in the middle fifth.\n */\n readonly grading?: Grading;\n /**\n * Per-palette hue shift. A one-sided grade applied before global\n * grading, with its own reach and strength limits (SHIFT_REACH,\n * MAX_SHIFT_AMOUNT). Defaults to the dark end; set `light: true` to target\n * the light end instead.\n */\n readonly shift?: Shift;\n /** Use Display P3 gamut instead of sRGB (default: false). */\n readonly isP3?: boolean;\n}\n\n/**\n * Generate an OKLCH color scale from lightest to darkest.\n *\n * Always produces DEFAULT_SCALE_STEPS colors. Chroma at each step is\n * proportional to the gamut boundary at that lightness, scaled by\n * `chroma.amount`. This guarantees every color is in-gamut — no fallbacks\n * needed — while producing a smooth, natural chroma curve.\n *\n * Use `contrast` to constrain the tonal range\n * (e.g. for scales that don't extend to pure white or pure black).\n *\n * Use `chroma.balance` to shift how chroma is distributed within the boundary.\n * The curve endpoints stay fixed while the distribution shifts smoothly.\n * The effective shift range is proportional to the headroom left by chroma.amount.\n */\nexport function generateScale(options: ScaleOptions = {}): Oklch[] {\n const {\n contrast,\n hue = DEFAULT_HUE,\n chroma,\n isP3 = false,\n grading,\n shift,\n } = options;\n const gamut = isP3 ? \"display-p3\" : \"srgb\";\n\n const steps = DEFAULT_SCALE_STEPS;\n const chromaRatio = chroma?.amount ?? 0;\n const chromaPeak = chroma?.balance ?? 0.5;\n const hueGrade = grading;\n const localHueGrade = shift ? buildOneSidedGrade(shift.hue, shift.amount, shift.light) : undefined;\n\n const ratio = Math.max(0, Math.min(1, chromaRatio));\n const peak = Math.max(0, Math.min(1, chromaPeak));\n // Slider interpolates from base (slider=0) to cap (slider=1).\n // P3 caps at 0.99/0.12 instead of 1.0/0.0 — extreme ends produce\n // clipping artifacts in P3 that don't occur in sRGB.\n const capLight = isP3 ? MIN_LIGHTEST_L_P3 : 1.0;\n const capDark = isP3 ? MAX_DARKEST_L_P3 : 0.0;\n const lightSlider = Math.max(0, Math.min(1, contrast?.light ?? 1));\n const darkSlider = Math.max(0, Math.min(1, contrast?.dark ?? 1));\n const lightestL = MIN_LIGHTEST_L + lightSlider * (capLight - MIN_LIGHTEST_L);\n const darkestL = MAX_DARKEST_L - darkSlider * (MAX_DARKEST_L - capDark);\n\n // Helper: resolve hue at position t (applies local shift first, then global grading)\n const hueAt = (t: number) => resolveGradedHue(hue, t, hueGrade, localHueGrade);\n\n // Fast path: skip peak skew logic when balance has no effect.\n // - peak === 0.5: already at the natural gamut peak, nothing to shift\n // - ratio === 0: no chroma at all, boundary shape is irrelevant\n // - ratio >= 1: inner triangle equals the boundary triangle, no headroom to slide\n if (peak === 0.5 || ratio === 0 || ratio >= 1) {\n const scale: Oklch[] = [];\n for (let i = 0; i < steps; i++) {\n const t = i / (steps - 1);\n const L = lightestL - t * (lightestL - darkestL);\n let h = hueAt(t);\n // Chroma is shaped by the base hue's boundary to keep the curve smooth.\n // The shifted hue's boundary is used as a final in-gamut clamp only —\n // this prevents spikes when the shifted hue has more available chroma\n // than the base (e.g. blue → pink passing through the purple region).\n let C = Math.min(maxChroma(L, hue, gamut) * ratio, maxChroma(L, h, gamut));\n\n if (hueGrade) {\n const overlay = applyGradingOverlay(C, h, L, t, hueGrade, gamut);\n C = overlay.C;\n h = overlay.h;\n }\n\n scale.push({ L, C, h });\n }\n return scale;\n }\n\n // ── Peak skew logic ──\n // Warp the parameter t so the boundary peak appears at a shifted position.\n // Endpoints stay fixed (warp(0)=0, warp(1)=1), only the peak moves.\n\n // 1. Sample boundary to find natural peak and valid shift range\n const N = 100;\n let peakT = 0.5;\n let peakBoundaryC = 0;\n const boundarySamples: { t: number; C: number }[] = [];\n\n for (let i = 0; i <= N; i++) {\n const t = i / N;\n const L = lightestL - t * (lightestL - darkestL);\n // Sample the base hue's boundary — the same reference used when building\n // the warp below. Using the shifted hue here would skew peakT and the\n // valid range toward a hue-specific boundary shape, inconsistent with\n // how chroma is actually computed in step 4.\n const C = maxChroma(L, hue, gamut);\n boundarySamples.push({ t, C });\n if (C > peakBoundaryC) {\n peakBoundaryC = C;\n peakT = t;\n }\n }\n\n // 2. Find valid range: where boundary can accommodate the inner peak height\n const innerPeakC = peakBoundaryC * ratio;\n let validMinT = peakT;\n let validMaxT = peakT;\n\n for (const { t, C } of boundarySamples) {\n if (C >= innerPeakC - 1e-6) {\n if (t < validMinT) validMinT = t;\n if (t > validMaxT) validMaxT = t;\n }\n }\n\n // 3. Map chroma.balance (0–1) to valid range, normalized so 0.5 → peakT\n let targetT: number;\n if (peak <= 0.5) {\n targetT = validMinT + (peak / 0.5) * (peakT - validMinT);\n } else {\n targetT = peakT + ((peak - 0.5) / 0.5) * (validMaxT - peakT);\n }\n\n // Safety: if the piecewise mapping produces a degenerate targetT (outside\n // (0, 1)), fall back to the natural peak. This can occur at floating-point\n // boundaries rather than from any single expected input combination.\n if (targetT <= 0 || targetT >= 1) {\n targetT = peakT;\n }\n\n // 4. Build scale with piecewise-linear warp: targetT → peakT\n const scale: Oklch[] = [];\n for (let i = 0; i < steps; i++) {\n const t = i / (steps - 1);\n const L = lightestL - t * (lightestL - darkestL);\n let h = hueAt(t);\n\n // Piecewise-linear warp: maps 0→0, targetT→peakT, 1→1.\n // Two segments scale t independently so the boundary peak (at peakT in\n // warp space) lands at targetT in the output — endpoints stay fixed.\n let tWarped: number;\n if (t <= targetT) {\n tWarped = t * (peakT / targetT);\n } else {\n tWarped = peakT + (t - targetT) * ((1 - peakT) / (1 - targetT));\n }\n\n const Lwarped = lightestL - tWarped * (lightestL - darkestL);\n // Use the base hue for the warped chroma lookup — consistent with step 1\n // and the fast path. The warp is purely a lightness operation; mixing in\n // the shifted hue at tWarped would introduce cross-position hue artifacts.\n const warpedC = maxChroma(Lwarped, hue, gamut) * ratio;\n // Clamp to the shifted hue's actual boundary at this L: the in-gamut\n // guarantee for the final color { L, C, h }.\n const boundaryC = maxChroma(L, h, gamut);\n let C = Math.min(warpedC, boundaryC);\n\n if (hueGrade) {\n const overlay = applyGradingOverlay(C, h, L, t, hueGrade, gamut);\n C = overlay.C;\n h = overlay.h;\n }\n\n scale.push({ L, C, h });\n }\n\n return scale;\n}\n","import type { Hex, Oklch, Gamut } from \"../types.js\";\nimport {\n hexToOklch,\n oklchToSrgb,\n oklchToP3,\n oklchToHex,\n} from \"../conversions/pipeline.js\";\nimport { isInGamut } from \"../gamut/check.js\";\nimport { gamutMap } from \"../gamut/map.js\";\nimport { maxChroma } from \"../gamut/max-chroma.js\";\n\n/**\n * Result of resolving a color into scale-ready parameters.\n */\nexport interface ResolvedColor {\n /** The final OKLCH color, guaranteed in-gamut for the target gamut. */\n readonly oklch: Oklch;\n /** Hex representation (sRGB-clamped if the resolved color exceeds sRGB). */\n readonly hex: Hex;\n /** Whether the input was outside the target gamut and was remapped. */\n readonly wasRemapped: boolean;\n /** The original OKLCH before gamut mapping (identical to oklch if in-gamut). */\n readonly original: Oklch;\n /** Chroma lost during gamut mapping (0 if in-gamut). */\n readonly chromaShift: number;\n /** Hue from the resolved color. */\n readonly hue: number;\n /** Chroma as a fraction of the gamut boundary at this L/h (0–1). */\n readonly chromaRatio: number;\n}\n\n/**\n * Resolve a color (hex or OKLCH) into scale-ready parameters.\n *\n * If the color is outside the target gamut, it is perceptually mapped to the\n * nearest in-gamut color (chroma reduction at fixed L and h). The result\n * includes the derived hue and chromaRatio.\n *\n * Hex input is always valid sRGB, so `wasRemapped` will be false for hex\n * with gamut=\"srgb\". OKLCH input may be out of gamut and will be mapped.\n *\n * @param input A hex string (#RGB, #RRGGBB) or an OKLCH color.\n * @param isP3 Use Display P3 gamut instead of sRGB (default: false).\n */\nexport function resolveColor(\n input: Hex | Oklch,\n isP3: boolean = false,\n): ResolvedColor {\n const gamut: Gamut = isP3 ? \"display-p3\" : \"srgb\";\n const isHex = typeof input === \"string\";\n const original: Oklch = isHex ? hexToOklch(input) : input;\n\n // Hex encodes valid sRGB by definition, and sRGB ⊂ P3, so hex input\n // is always in-gamut for both supported gamuts. Skipping the round-trip\n // check avoids false negatives from floating-point drift.\n let inGamut: boolean;\n if (isHex) {\n inGamut = true;\n } else {\n const rgb =\n gamut === \"display-p3\" ? oklchToP3(original) : oklchToSrgb(original);\n inGamut = isInGamut(rgb);\n }\n\n const oklch = inGamut ? original : gamutMap(original, gamut);\n\n const boundary = maxChroma(oklch.L, oklch.h, gamut);\n const chromaRatio = boundary > 0 ? oklch.C / boundary : 0;\n\n return {\n oklch,\n hex: oklchToHex(oklch),\n wasRemapped: !inGamut,\n original,\n chromaShift: original.C - oklch.C,\n hue: oklch.h,\n chromaRatio: Math.min(1, chromaRatio),\n };\n}\n","/**\n * Dynamic range resolution — maps slider values (0–1) to OKLCH lightness\n * bounds for the lightest and darkest steps of a color scale.\n */\n\nimport { MIN_LIGHTEST_L, MAX_DARKEST_L } from \"../config.js\";\n\n/**\n * Resolve a whites slider value (0–1) to an OKLCH lightness.\n * slider 0 → L = MIN_LIGHTEST_L (0.96), slider 1 → L = 1.0 (pure white)\n */\nexport function resolveLightest(slider: number): number {\n const s = Math.max(0, Math.min(1, slider));\n return MIN_LIGHTEST_L + s * (1.0 - MIN_LIGHTEST_L);\n}\n\n/**\n * Resolve a darks slider value (0–1) to an OKLCH lightness.\n * slider 0 → L = MAX_DARKEST_L (0.16), slider 1 → L = 0.0 (pure black)\n */\nexport function resolveDarkest(slider: number): number {\n const s = Math.max(0, Math.min(1, slider));\n return MAX_DARKEST_L * (1 - s);\n}\n\n/**\n * Map an OKLCH lightness to a normalized scale position (0–1).\n * 0 = lightest end, 1 = darkest end.\n *\n * Inverse of the lightness interpolation inside generateScale.\n * Useful for deriving chromaPeak from a key color's lightness.\n */\nexport function lightnessToScaleT(L: number, lightestL: number, darkestL: number): number {\n const range = lightestL - darkestL;\n if (range <= 0) return 0.5;\n return Math.max(0, Math.min(1, (lightestL - L) / range));\n}\n","import type { Hex, Oklch } from \"../types.js\";\nimport { resolveColor } from \"./resolve-color.js\";\nimport { lightnessToScaleT, resolveLightest, resolveDarkest } from \"./dynamic-range.js\";\nimport { DEFAULT_SCALE_STEPS } from \"../config.js\";\n\n/**\n * The result of deriving scale parameters from a key color.\n *\n * Spread `hue` and `chroma` directly into ScaleOptions, then use\n * `stepIndex` to locate the key color's position in the generated scale.\n */\nexport interface KeyColorResult {\n /** Derived hue angle — use directly as ScaleOptions.hue. */\n readonly hue: number;\n /**\n * Derived chroma shape — use directly as ScaleOptions.chroma.\n * - `amount`: how saturated the scale is (0–1, relative to gamut boundary).\n * - `balance`: where in the scale the key color's lightness falls (0 = lightest, 1 = darkest).\n */\n readonly chroma: { readonly amount: number; readonly balance: number };\n /** The step index in a scale of `steps` length where this color lands. */\n readonly stepIndex: number;\n /** Hex representation of the resolved color (sRGB-clamped if necessary). */\n readonly hex: Hex;\n /** The final OKLCH color, guaranteed in-gamut for the target gamut. */\n readonly oklch: Oklch;\n /** Whether the input was outside the target gamut and was remapped. */\n readonly wasRemapped: boolean;\n /** The original OKLCH before gamut mapping (identical to oklch if in-gamut). */\n readonly original: Oklch;\n}\n\n/**\n * Derive scale parameters from a known color.\n *\n * Given a hex or OKLCH color, returns the `hue` and `chroma` values\n * ready to spread into ScaleOptions. The chroma balance is derived from\n * where the color's lightness falls within the scale's lightness range,\n * so the chroma distribution is centered around the key color's position.\n *\n * @param color A hex string (#RGB or #RRGGBB) or an OKLCH color object.\n * @param options Scale context — must match the ScaleOptions you will use.\n * `contrast` values are slider values (0–1), same as ScaleOptions.contrast.\n * `steps` is the number of steps in the scale (default: 26).\n *\n * @example\n * const key = keyColor('#3B82F6');\n * const scale = generateScale({ hue: key.hue, chroma: key.chroma });\n * const matchedHex = oklchToHex(scale[key.stepIndex]);\n */\nexport function keyColor(\n color: Hex | Oklch,\n options?: {\n readonly isP3?: boolean;\n readonly contrast?: { readonly light?: number; readonly dark?: number };\n readonly steps?: number;\n },\n): KeyColorResult {\n const { isP3 = false, contrast, steps = DEFAULT_SCALE_STEPS } = options ?? {};\n const resolved = resolveColor(color, isP3);\n const lightestL = resolveLightest(contrast?.light ?? 1);\n const darkestL = resolveDarkest(contrast?.dark ?? 1);\n const balance = lightnessToScaleT(resolved.oklch.L, lightestL, darkestL);\n const stepIndex = Math.round(balance * Math.max(0, steps - 1));\n\n return {\n hue: resolved.hue,\n chroma: { amount: resolved.chromaRatio, balance },\n stepIndex,\n hex: resolved.hex,\n oklch: resolved.oklch,\n wasRemapped: resolved.wasRemapped,\n original: resolved.original,\n };\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -12,7 +12,7 @@ export { wcagLuminance, wcagContrast, contrastTextHex } from "./contrast/wcag.js
12
12
  export { apcaContrast, apcaToNormalized, normalizedToApca, APCA_LC_MAX } from "./contrast/apca.js";
13
13
  export { deltaEOK, deltaEOKLab } from "./color/difference.js";
14
14
  export { mix } from "./color/interpolation.js";
15
- export { DEFAULT_SCALE_STEPS, DEFAULT_HUE, MIN_LIGHTEST_L, MAX_DARKEST_L, GRADING_REACH, MAX_GRADING_AMOUNT, GRADING_CHROMA_RATIO, SHIFT_REACH, MAX_SHIFT_AMOUNT, PERCEPTUAL_JND, } from "./config.js";
15
+ export { DEFAULT_SCALE_STEPS, DEFAULT_HUE, MIN_LIGHTEST_L, MAX_DARKEST_L, MIN_LIGHTEST_L_P3, MAX_DARKEST_L_P3, GRADING_REACH, MAX_GRADING_AMOUNT, GRADING_CHROMA_RATIO, SHIFT_REACH, MAX_SHIFT_AMOUNT, PERCEPTUAL_JND, } from "./config.js";
16
16
  export { generateScale } from "./scale/generate.js";
17
17
  export type { ScaleOptions } from "./scale/generate.js";
18
18
  export { gradeHue, resolveGradedHue, buildOneSidedGrade, gradingInfluence } from "./scale/hue-grade.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAG7E,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAG5D,OAAO,EACL,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,EACX,UAAU,EACV,UAAU,EACV,SAAS,EACT,SAAS,EACT,YAAY,GACb,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGlD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGnG,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAG/C,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,EACX,gBAAgB,EAChB,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxG,YAAY,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAG7E,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAG5D,OAAO,EACL,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,EACX,UAAU,EACV,UAAU,EACV,SAAS,EACT,SAAS,EACT,YAAY,GACb,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGlD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGnG,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAG/C,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,EACX,gBAAgB,EAChB,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxG,YAAY,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC"}
package/dist/index.js CHANGED
@@ -360,8 +360,10 @@ function mix(a, b, t) {
360
360
  // src/config.ts
361
361
  var DEFAULT_SCALE_STEPS = 26;
362
362
  var DEFAULT_HUE = 0;
363
- var MIN_LIGHTEST_L = 0.96;
364
- var MAX_DARKEST_L = 0.16;
363
+ var MIN_LIGHTEST_L_P3 = 0.98;
364
+ var MIN_LIGHTEST_L = 0.92;
365
+ var MAX_DARKEST_L = 0.2;
366
+ var MAX_DARKEST_L_P3 = 0.14;
365
367
  var GRADING_REACH = 3 / 5;
366
368
  var MAX_GRADING_AMOUNT = 0.25;
367
369
  var GRADING_CHROMA_RATIO = 0.5;
@@ -419,21 +421,6 @@ function buildOneSidedGrade(hue, amount, light = false) {
419
421
  return light ? { light: { hue, amount } } : { dark: { hue, amount } };
420
422
  }
421
423
 
422
- // src/scale/dynamic-range.ts
423
- function resolveLightest(slider) {
424
- const s = Math.max(0, Math.min(1, slider));
425
- return MIN_LIGHTEST_L + s * (1 - MIN_LIGHTEST_L);
426
- }
427
- function resolveDarkest(slider) {
428
- const s = Math.max(0, Math.min(1, slider));
429
- return MAX_DARKEST_L * (1 - s);
430
- }
431
- function lightnessToScaleT(L, lightestL, darkestL) {
432
- const range = lightestL - darkestL;
433
- if (range <= 0) return 0.5;
434
- return Math.max(0, Math.min(1, (lightestL - L) / range));
435
- }
436
-
437
424
  // src/scale/generate.ts
438
425
  var toRad = Math.PI / 180;
439
426
  function applyGradingOverlay(C, h, L, t, grading, gamut) {
@@ -484,8 +471,12 @@ function generateScale(options = {}) {
484
471
  const localHueGrade = shift ? buildOneSidedGrade(shift.hue, shift.amount, shift.light) : void 0;
485
472
  const ratio = Math.max(0, Math.min(1, chromaRatio));
486
473
  const peak = Math.max(0, Math.min(1, chromaPeak));
487
- const lightestL = resolveLightest(contrast?.light ?? 1);
488
- const darkestL = resolveDarkest(contrast?.dark ?? 1);
474
+ const capLight = isP3 ? MIN_LIGHTEST_L_P3 : 1;
475
+ const capDark = isP3 ? MAX_DARKEST_L_P3 : 0;
476
+ const lightSlider = Math.max(0, Math.min(1, contrast?.light ?? 1));
477
+ const darkSlider = Math.max(0, Math.min(1, contrast?.dark ?? 1));
478
+ const lightestL = MIN_LIGHTEST_L + lightSlider * (capLight - MIN_LIGHTEST_L);
479
+ const darkestL = MAX_DARKEST_L - darkSlider * (MAX_DARKEST_L - capDark);
489
480
  const hueAt = (t) => resolveGradedHue(hue, t, hueGrade, localHueGrade);
490
481
  if (peak === 0.5 || ratio === 0 || ratio >= 1) {
491
482
  const scale2 = [];
@@ -586,6 +577,21 @@ function resolveColor(input, isP3 = false) {
586
577
  };
587
578
  }
588
579
 
580
+ // src/scale/dynamic-range.ts
581
+ function resolveLightest(slider) {
582
+ const s = Math.max(0, Math.min(1, slider));
583
+ return MIN_LIGHTEST_L + s * (1 - MIN_LIGHTEST_L);
584
+ }
585
+ function resolveDarkest(slider) {
586
+ const s = Math.max(0, Math.min(1, slider));
587
+ return MAX_DARKEST_L * (1 - s);
588
+ }
589
+ function lightnessToScaleT(L, lightestL, darkestL) {
590
+ const range = lightestL - darkestL;
591
+ if (range <= 0) return 0.5;
592
+ return Math.max(0, Math.min(1, (lightestL - L) / range));
593
+ }
594
+
589
595
  // src/scale/key-color.ts
590
596
  function keyColor(color, options) {
591
597
  const { isP3 = false, contrast, steps = DEFAULT_SCALE_STEPS } = options ?? {};
@@ -605,6 +611,6 @@ function keyColor(color, options) {
605
611
  };
606
612
  }
607
613
 
608
- export { APCA_LC_MAX, DEFAULT_HUE, DEFAULT_SCALE_STEPS, GRADING_CHROMA_RATIO, GRADING_REACH, MAX_DARKEST_L, MAX_GRADING_AMOUNT, MAX_SHIFT_AMOUNT, MIN_LIGHTEST_L, PERCEPTUAL_JND, SHIFT_REACH, apcaContrast, apcaToNormalized, buildOneSidedGrade, clampP3, clampSrgb, contrastTextHex, deltaEOK, deltaEOKLab, gamutMap, generateScale, gradeHue, gradingInfluence, hexToOklch, hexToSrgb, isInGamut, keyColor, lightnessToScaleT, linearChannelToSrgb, linearP3ToOklab, linearSrgbToOklab, linearSrgbToSrgb, maxChroma, mix, normalizedToApca, oklabToLinearP3, oklabToLinearSrgb, oklabToOklch, oklabToSrgb, oklchToHex, oklchToOklab, oklchToP3, oklchToP3Css, oklchToSrgb, p3ToOklch, resolveGradedHue, srgbChannelToLinear, srgbToHex, srgbToLinearSrgb, srgbToOklab, srgbToOklch, wcagContrast, wcagLuminance };
614
+ export { APCA_LC_MAX, DEFAULT_HUE, DEFAULT_SCALE_STEPS, GRADING_CHROMA_RATIO, GRADING_REACH, MAX_DARKEST_L, MAX_DARKEST_L_P3, MAX_GRADING_AMOUNT, MAX_SHIFT_AMOUNT, MIN_LIGHTEST_L, MIN_LIGHTEST_L_P3, PERCEPTUAL_JND, SHIFT_REACH, apcaContrast, apcaToNormalized, buildOneSidedGrade, clampP3, clampSrgb, contrastTextHex, deltaEOK, deltaEOKLab, gamutMap, generateScale, gradeHue, gradingInfluence, hexToOklch, hexToSrgb, isInGamut, keyColor, lightnessToScaleT, linearChannelToSrgb, linearP3ToOklab, linearSrgbToOklab, linearSrgbToSrgb, maxChroma, mix, normalizedToApca, oklabToLinearP3, oklabToLinearSrgb, oklabToOklch, oklabToSrgb, oklchToHex, oklchToOklab, oklchToP3, oklchToP3Css, oklchToSrgb, p3ToOklch, resolveGradedHue, srgbChannelToLinear, srgbToHex, srgbToLinearSrgb, srgbToOklab, srgbToOklch, wcagContrast, wcagLuminance };
609
615
  //# sourceMappingURL=index.js.map
610
616
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants.ts","../src/conversions/oklab.ts","../src/conversions/linear-srgb.ts","../src/conversions/linear-p3.ts","../src/conversions/srgb.ts","../src/conversions/hex.ts","../src/conversions/pipeline.ts","../src/gamut/check.ts","../src/color/difference.ts","../src/gamut/map.ts","../src/gamut/max-chroma.ts","../src/contrast/wcag.ts","../src/contrast/apca.ts","../src/color/interpolation.ts","../src/config.ts","../src/scale/hue-grade.ts","../src/scale/dynamic-range.ts","../src/scale/generate.ts","../src/scale/resolve-color.ts","../src/scale/key-color.ts"],"names":["toRad","scale"],"mappings":"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","file":"index.js","sourcesContent":["// ── sRGB Gamma Transfer (IEC 61966-2-1) ──\n\nexport const SRGB_GAMMA_THRESHOLD = 0.04045;\nexport const SRGB_GAMMA_THRESHOLD_LINEAR = 0.0031308;\nexport const SRGB_GAMMA_SLOPE = 12.92;\nexport const SRGB_GAMMA_EXPONENT = 2.4;\nexport const SRGB_GAMMA_OFFSET = 0.055;\nexport const SRGB_GAMMA_SCALE = 1.055;\n\n// ── Ottosson M1: Linear sRGB → LMS ──\n\nexport const LINEAR_SRGB_TO_LMS = [\n [0.4122214708, 0.5363325363, 0.0514459929],\n [0.2119034982, 0.6806995451, 0.1073969566],\n [0.0883024619, 0.2817188376, 0.6299787005],\n] as const;\n\n// ── Ottosson M2: LMS′ (cube-root) → OKLAB ──\n\nexport const LMS_PRIME_TO_OKLAB = [\n [+0.2104542553, +0.7936177850, -0.0040720468],\n [+1.9779984951, -2.4285922050, +0.4505937099],\n [+0.0259040371, +0.7827717662, -0.8086757660],\n] as const;\n\n// ── Inverse M2: OKLAB → LMS′ ──\n\nexport const OKLAB_TO_LMS_PRIME = [\n [1.0000000000, +0.3963377774, +0.2158037573],\n [1.0000000000, -0.1055613458, -0.0638541728],\n [1.0000000000, -0.0894841775, -1.2914855480],\n] as const;\n\n// ── Inverse M1: LMS → Linear sRGB ──\n\nexport const LMS_TO_LINEAR_SRGB = [\n [+4.0767416621, -3.3077115913, +0.2309699292],\n [-1.2684380046, +2.6097574011, -0.3413193965],\n [-0.0041960863, -0.7034186147, +1.7076147010],\n] as const;\n\n// ── Display P3 M1: Linear Display P3 → LMS ──\n// Derived: XYZ_to_LMS × P3_to_XYZ, where XYZ_to_LMS = M1_srgb × inv(sRGB_to_XYZ)\n\nexport const LINEAR_P3_TO_LMS = [\n [+0.4813791595, +0.4621155872, +0.0565406381],\n [+0.2288319169, +0.6532167007, +0.1179528072],\n [+0.0839457149, +0.2241651052, +0.6918912614],\n] as const;\n\n// ── Inverse P3 M1: LMS → Linear Display P3 ──\n\nexport const LMS_TO_LINEAR_P3 = [\n [+3.1277694390, -2.2570600176, +0.1291828502],\n [-1.0910091977, +2.4133065499, -0.3222615148],\n [-0.0260108068, -0.5080402362, +1.5340494942],\n] as const;\n\n// ── Gamut Mapping ──\n\nexport const GAMUT_EPSILON = 1e-6;\nexport const GAMUT_MAP_JND = 0.02;\nexport const GAMUT_MAP_EPSILON = 1e-4;\nexport const GAMUT_MAP_MAX_ITERATIONS = 50;\n\n// ── Achromatic Threshold ──\n\nexport const ACHROMATIC_THRESHOLD = 1e-10;\n\n// ── WCAG 2.x Luminance Coefficients ──\n\nexport const WCAG_R = 0.2126;\nexport const WCAG_G = 0.7152;\nexport const WCAG_B = 0.0722;\n\n// ── APCA-W3 (SA98G) Constants ──\n\nexport const APCA_MAIN_TRC = 2.4;\nexport const APCA_SRGB_R = 0.2126729;\nexport const APCA_SRGB_G = 0.7151522;\nexport const APCA_SRGB_B = 0.0721750;\nexport const APCA_NORM_BG = 0.56;\nexport const APCA_NORM_TXT = 0.57;\nexport const APCA_REV_TXT = 0.62;\nexport const APCA_REV_BG = 0.65;\nexport const APCA_BLK_THRS = 0.022;\nexport const APCA_BLK_CLMP = 1.414;\nexport const APCA_SCALE_BOW = 1.14;\nexport const APCA_SCALE_WOB = 1.14;\nexport const APCA_LO_BOW_OFFSET = 0.027;\nexport const APCA_LO_WOB_OFFSET = 0.027;\nexport const APCA_DELTA_Y_MIN = 0.0005;\nexport const APCA_LO_CLIP = 0.1;\n\n// ── Angle Math ──\n\nexport const DEG_TO_RAD = Math.PI / 180;\nexport const RAD_TO_DEG = 180 / Math.PI;\n","import type { Oklab, Oklch } from \"../types.js\";\nimport { ACHROMATIC_THRESHOLD, DEG_TO_RAD, RAD_TO_DEG } from \"../constants.js\";\n\n/** Convert OKLAB (cartesian) to OKLCH (cylindrical). Achromatic colors get h=0. */\nexport function oklabToOklch(lab: Oklab): Oklch {\n const C = Math.sqrt(lab.a * lab.a + lab.b * lab.b);\n\n if (C < ACHROMATIC_THRESHOLD) {\n return { L: lab.L, C: 0, h: 0 };\n }\n\n let h = Math.atan2(lab.b, lab.a) * RAD_TO_DEG;\n if (h < 0) h += 360;\n\n return { L: lab.L, C, h };\n}\n\n/** Convert OKLCH (cylindrical) to OKLAB (cartesian). */\nexport function oklchToOklab(lch: Oklch): Oklab {\n const hRad = lch.h * DEG_TO_RAD;\n return {\n L: lch.L,\n a: lch.C * Math.cos(hRad),\n b: lch.C * Math.sin(hRad),\n };\n}\n","import type { LinearSrgb, Oklab } from \"../types.js\";\nimport {\n LINEAR_SRGB_TO_LMS,\n LMS_PRIME_TO_OKLAB,\n LMS_TO_LINEAR_SRGB,\n OKLAB_TO_LMS_PRIME,\n} from \"../constants.js\";\n\n/** Convert Linear sRGB to OKLAB via Ottosson's direct M1/M2 matrices. */\nexport function linearSrgbToOklab(color: LinearSrgb): Oklab {\n // Step 1: Linear sRGB → LMS\n const l =\n LINEAR_SRGB_TO_LMS[0][0] * color.r +\n LINEAR_SRGB_TO_LMS[0][1] * color.g +\n LINEAR_SRGB_TO_LMS[0][2] * color.b;\n const m =\n LINEAR_SRGB_TO_LMS[1][0] * color.r +\n LINEAR_SRGB_TO_LMS[1][1] * color.g +\n LINEAR_SRGB_TO_LMS[1][2] * color.b;\n const s =\n LINEAR_SRGB_TO_LMS[2][0] * color.r +\n LINEAR_SRGB_TO_LMS[2][1] * color.g +\n LINEAR_SRGB_TO_LMS[2][2] * color.b;\n\n // Step 2: Cube root\n const lp = Math.cbrt(l);\n const mp = Math.cbrt(m);\n const sp = Math.cbrt(s);\n\n // Step 3: LMS′ → OKLAB\n return {\n L:\n LMS_PRIME_TO_OKLAB[0][0] * lp +\n LMS_PRIME_TO_OKLAB[0][1] * mp +\n LMS_PRIME_TO_OKLAB[0][2] * sp,\n a:\n LMS_PRIME_TO_OKLAB[1][0] * lp +\n LMS_PRIME_TO_OKLAB[1][1] * mp +\n LMS_PRIME_TO_OKLAB[1][2] * sp,\n b:\n LMS_PRIME_TO_OKLAB[2][0] * lp +\n LMS_PRIME_TO_OKLAB[2][1] * mp +\n LMS_PRIME_TO_OKLAB[2][2] * sp,\n };\n}\n\n/** Convert OKLAB to Linear sRGB via inverse M2/M1 matrices. */\nexport function oklabToLinearSrgb(color: Oklab): LinearSrgb {\n // Step 1: OKLAB → LMS′\n const lp =\n OKLAB_TO_LMS_PRIME[0][0] * color.L +\n OKLAB_TO_LMS_PRIME[0][1] * color.a +\n OKLAB_TO_LMS_PRIME[0][2] * color.b;\n const mp =\n OKLAB_TO_LMS_PRIME[1][0] * color.L +\n OKLAB_TO_LMS_PRIME[1][1] * color.a +\n OKLAB_TO_LMS_PRIME[1][2] * color.b;\n const sp =\n OKLAB_TO_LMS_PRIME[2][0] * color.L +\n OKLAB_TO_LMS_PRIME[2][1] * color.a +\n OKLAB_TO_LMS_PRIME[2][2] * color.b;\n\n // Step 2: Cube\n const l = lp * lp * lp;\n const m = mp * mp * mp;\n const s = sp * sp * sp;\n\n // Step 3: LMS → Linear sRGB\n return {\n r:\n LMS_TO_LINEAR_SRGB[0][0] * l +\n LMS_TO_LINEAR_SRGB[0][1] * m +\n LMS_TO_LINEAR_SRGB[0][2] * s,\n g:\n LMS_TO_LINEAR_SRGB[1][0] * l +\n LMS_TO_LINEAR_SRGB[1][1] * m +\n LMS_TO_LINEAR_SRGB[1][2] * s,\n b:\n LMS_TO_LINEAR_SRGB[2][0] * l +\n LMS_TO_LINEAR_SRGB[2][1] * m +\n LMS_TO_LINEAR_SRGB[2][2] * s,\n };\n}\n","import type { LinearSrgb, Oklab } from \"../types.js\";\nimport {\n LINEAR_P3_TO_LMS,\n LMS_PRIME_TO_OKLAB,\n LMS_TO_LINEAR_P3,\n OKLAB_TO_LMS_PRIME,\n} from \"../constants.js\";\n\n/** Convert Linear Display P3 to OKLAB via P3-specific M1 + shared M2. */\nexport function linearP3ToOklab(color: LinearSrgb): Oklab {\n // Step 1: Linear P3 → LMS\n const l =\n LINEAR_P3_TO_LMS[0][0] * color.r +\n LINEAR_P3_TO_LMS[0][1] * color.g +\n LINEAR_P3_TO_LMS[0][2] * color.b;\n const m =\n LINEAR_P3_TO_LMS[1][0] * color.r +\n LINEAR_P3_TO_LMS[1][1] * color.g +\n LINEAR_P3_TO_LMS[1][2] * color.b;\n const s =\n LINEAR_P3_TO_LMS[2][0] * color.r +\n LINEAR_P3_TO_LMS[2][1] * color.g +\n LINEAR_P3_TO_LMS[2][2] * color.b;\n\n // Step 2: Cube root\n const lp = Math.cbrt(l);\n const mp = Math.cbrt(m);\n const sp = Math.cbrt(s);\n\n // Step 3: LMS′ → OKLAB (shared M2)\n return {\n L:\n LMS_PRIME_TO_OKLAB[0][0] * lp +\n LMS_PRIME_TO_OKLAB[0][1] * mp +\n LMS_PRIME_TO_OKLAB[0][2] * sp,\n a:\n LMS_PRIME_TO_OKLAB[1][0] * lp +\n LMS_PRIME_TO_OKLAB[1][1] * mp +\n LMS_PRIME_TO_OKLAB[1][2] * sp,\n b:\n LMS_PRIME_TO_OKLAB[2][0] * lp +\n LMS_PRIME_TO_OKLAB[2][1] * mp +\n LMS_PRIME_TO_OKLAB[2][2] * sp,\n };\n}\n\n/** Convert OKLAB to Linear Display P3 via shared inverse M2 + P3-specific inverse M1. */\nexport function oklabToLinearP3(color: Oklab): LinearSrgb {\n // Step 1: OKLAB → LMS′ (shared inverse M2)\n const lp =\n OKLAB_TO_LMS_PRIME[0][0] * color.L +\n OKLAB_TO_LMS_PRIME[0][1] * color.a +\n OKLAB_TO_LMS_PRIME[0][2] * color.b;\n const mp =\n OKLAB_TO_LMS_PRIME[1][0] * color.L +\n OKLAB_TO_LMS_PRIME[1][1] * color.a +\n OKLAB_TO_LMS_PRIME[1][2] * color.b;\n const sp =\n OKLAB_TO_LMS_PRIME[2][0] * color.L +\n OKLAB_TO_LMS_PRIME[2][1] * color.a +\n OKLAB_TO_LMS_PRIME[2][2] * color.b;\n\n // Step 2: Cube\n const l = lp * lp * lp;\n const m = mp * mp * mp;\n const s = sp * sp * sp;\n\n // Step 3: LMS → Linear P3\n return {\n r:\n LMS_TO_LINEAR_P3[0][0] * l +\n LMS_TO_LINEAR_P3[0][1] * m +\n LMS_TO_LINEAR_P3[0][2] * s,\n g:\n LMS_TO_LINEAR_P3[1][0] * l +\n LMS_TO_LINEAR_P3[1][1] * m +\n LMS_TO_LINEAR_P3[1][2] * s,\n b:\n LMS_TO_LINEAR_P3[2][0] * l +\n LMS_TO_LINEAR_P3[2][1] * m +\n LMS_TO_LINEAR_P3[2][2] * s,\n };\n}\n","import type { LinearSrgb, Srgb } from \"../types.js\";\nimport {\n SRGB_GAMMA_EXPONENT,\n SRGB_GAMMA_OFFSET,\n SRGB_GAMMA_SCALE,\n SRGB_GAMMA_SLOPE,\n SRGB_GAMMA_THRESHOLD,\n SRGB_GAMMA_THRESHOLD_LINEAR,\n} from \"../constants.js\";\n\n/** Decode a single sRGB gamma-encoded channel to linear light. */\nexport function srgbChannelToLinear(value: number): number {\n return value <= SRGB_GAMMA_THRESHOLD\n ? value / SRGB_GAMMA_SLOPE\n : ((value + SRGB_GAMMA_OFFSET) / SRGB_GAMMA_SCALE) ** SRGB_GAMMA_EXPONENT;\n}\n\n/** Encode a single linear light channel to sRGB gamma. */\nexport function linearChannelToSrgb(value: number): number {\n return value <= SRGB_GAMMA_THRESHOLD_LINEAR\n ? value * SRGB_GAMMA_SLOPE\n : SRGB_GAMMA_SCALE * value ** (1 / SRGB_GAMMA_EXPONENT) - SRGB_GAMMA_OFFSET;\n}\n\n/** Convert an sRGB color to Linear sRGB. */\nexport function srgbToLinearSrgb(color: Srgb): LinearSrgb {\n return {\n r: srgbChannelToLinear(color.r),\n g: srgbChannelToLinear(color.g),\n b: srgbChannelToLinear(color.b),\n };\n}\n\n/** Convert a Linear sRGB color to sRGB. */\nexport function linearSrgbToSrgb(color: LinearSrgb): Srgb {\n return {\n r: linearChannelToSrgb(color.r),\n g: linearChannelToSrgb(color.g),\n b: linearChannelToSrgb(color.b),\n };\n}\n","import type { Hex, Srgb } from \"../types.js\";\n\n/** Parse a hex color string (#RGB, #RRGGBB, or bare) to sRGB [0,1]. */\nexport function hexToSrgb(hex: string): Srgb {\n let h = hex.startsWith(\"#\") ? hex.slice(1) : hex;\n\n if (h.length === 3) {\n h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];\n }\n\n const n = parseInt(h, 16);\n return {\n r: ((n >> 16) & 0xff) / 255,\n g: ((n >> 8) & 0xff) / 255,\n b: (n & 0xff) / 255,\n };\n}\n\n/** Convert sRGB [0,1] to lowercase hex string (#rrggbb). Clamps to [0,1]. */\nexport function srgbToHex(color: Srgb): Hex {\n const r = Math.round(Math.max(0, Math.min(1, color.r)) * 255);\n const g = Math.round(Math.max(0, Math.min(1, color.g)) * 255);\n const b = Math.round(Math.max(0, Math.min(1, color.b)) * 255);\n return `#${((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1)}` as Hex;\n}\n","import type { Hex, Oklab, Oklch, Srgb } from \"../types.js\";\nimport { oklabToOklch, oklchToOklab } from \"./oklab.js\";\nimport { linearSrgbToOklab, oklabToLinearSrgb } from \"./linear-srgb.js\";\nimport { linearP3ToOklab, oklabToLinearP3 } from \"./linear-p3.js\";\nimport { linearSrgbToSrgb, srgbToLinearSrgb } from \"./srgb.js\";\nimport { hexToSrgb, srgbToHex } from \"./hex.js\";\n\n/** Convert sRGB to OKLCH. */\nexport function srgbToOklch(color: Srgb): Oklch {\n return oklabToOklch(linearSrgbToOklab(srgbToLinearSrgb(color)));\n}\n\n/** Convert OKLCH to sRGB. May produce out-of-gamut values (channels outside [0,1]). */\nexport function oklchToSrgb(color: Oklch): Srgb {\n return linearSrgbToSrgb(oklabToLinearSrgb(oklchToOklab(color)));\n}\n\n/** Convert sRGB to OKLAB. */\nexport function srgbToOklab(color: Srgb): Oklab {\n return linearSrgbToOklab(srgbToLinearSrgb(color));\n}\n\n/** Convert OKLAB to sRGB. May produce out-of-gamut values. */\nexport function oklabToSrgb(color: Oklab): Srgb {\n return linearSrgbToSrgb(oklabToLinearSrgb(color));\n}\n\n/** Convert hex to OKLCH. */\nexport function hexToOklch(hex: string): Oklch {\n return srgbToOklch(hexToSrgb(hex));\n}\n\n/** Convert OKLCH to hex. Clamps to sRGB gamut before hex encoding. */\nexport function oklchToHex(color: Oklch): Hex {\n const srgb = oklchToSrgb(color);\n return srgbToHex({\n r: Math.max(0, Math.min(1, srgb.r)),\n g: Math.max(0, Math.min(1, srgb.g)),\n b: Math.max(0, Math.min(1, srgb.b)),\n });\n}\n\n/** Convert Display P3 to OKLCH. */\nexport function p3ToOklch(color: Srgb): Oklch {\n return oklabToOklch(linearP3ToOklab(srgbToLinearSrgb(color)));\n}\n\n/** Convert OKLCH to Display P3. May produce out-of-gamut values (channels outside [0,1]). */\nexport function oklchToP3(color: Oklch): Srgb {\n return linearSrgbToSrgb(oklabToLinearP3(oklchToOklab(color)));\n}\n\n/** Convert OKLCH to a CSS `color(display-p3 r g b)` string. Clamps channels to [0,1]. */\nexport function oklchToP3Css(color: Oklch): string {\n const p3 = oklchToP3(color);\n const r = Math.max(0, Math.min(1, p3.r)).toFixed(4);\n const g = Math.max(0, Math.min(1, p3.g)).toFixed(4);\n const b = Math.max(0, Math.min(1, p3.b)).toFixed(4);\n return `color(display-p3 ${r} ${g} ${b})`;\n}\n","import type { Srgb } from \"../types.js\";\nimport { GAMUT_EPSILON } from \"../constants.js\";\n\n/** Check if sRGB channels are within [0, 1] (with epsilon tolerance). */\nexport function isInGamut(color: Srgb): boolean {\n return (\n color.r >= -GAMUT_EPSILON &&\n color.r <= 1 + GAMUT_EPSILON &&\n color.g >= -GAMUT_EPSILON &&\n color.g <= 1 + GAMUT_EPSILON &&\n color.b >= -GAMUT_EPSILON &&\n color.b <= 1 + GAMUT_EPSILON\n );\n}\n\n/** Clamp sRGB channels to [0, 1]. */\nexport function clampSrgb(color: Srgb): Srgb {\n return {\n r: Math.max(0, Math.min(1, color.r)),\n g: Math.max(0, Math.min(1, color.g)),\n b: Math.max(0, Math.min(1, color.b)),\n };\n}\n\n/** Clamp Display P3 channels to [0, 1]. */\nexport const clampP3 = clampSrgb;\n","import type { Oklab, Oklch } from \"../types.js\";\nimport { oklchToOklab } from \"../conversions/oklab.js\";\n\n/** Compute deltaEOK (Euclidean distance in OKLAB) between two OKLCH colors. */\nexport function deltaEOK(a: Oklch, b: Oklch): number {\n return deltaEOKLab(oklchToOklab(a), oklchToOklab(b));\n}\n\n/** Compute deltaEOK directly from OKLAB values. */\nexport function deltaEOKLab(a: Oklab, b: Oklab): number {\n const dL = a.L - b.L;\n const da = a.a - b.a;\n const db = a.b - b.b;\n return Math.sqrt(dL * dL + da * da + db * db);\n}\n","import type { Gamut, Oklch, Srgb } from \"../types.js\";\nimport {\n GAMUT_EPSILON,\n GAMUT_MAP_EPSILON,\n GAMUT_MAP_JND,\n GAMUT_MAP_MAX_ITERATIONS,\n} from \"../constants.js\";\nimport { oklchToSrgb, oklchToP3 } from \"../conversions/pipeline.js\";\nimport { isInGamut, clampSrgb } from \"./check.js\";\nimport { deltaEOKLab } from \"../color/difference.js\";\nimport { oklchToOklab } from \"../conversions/oklab.js\";\nimport { linearSrgbToOklab } from \"../conversions/linear-srgb.js\";\nimport { linearP3ToOklab } from \"../conversions/linear-p3.js\";\nimport { srgbToLinearSrgb } from \"../conversions/srgb.js\";\n\n/**\n * Map an OKLCH color into the target gamut using the CSS Color Level 4 algorithm.\n * Reduces chroma at fixed L and h via binary search with deltaEOK JND check.\n * @param gamut Target gamut (default: 'srgb').\n */\nexport function gamutMap(color: Oklch, gamut: Gamut = \"srgb\"): Oklch {\n const toRgb = gamut === \"display-p3\" ? oklchToP3 : oklchToSrgb;\n const rgbToOklab =\n gamut === \"display-p3\"\n ? (c: Srgb) => linearP3ToOklab(srgbToLinearSrgb(c))\n : (c: Srgb) => linearSrgbToOklab(srgbToLinearSrgb(c));\n\n // Already in gamut\n const rgb = toRgb(color);\n if (isInGamut(rgb)) return color;\n\n // Edge cases: black and white\n if (color.L <= GAMUT_EPSILON) return { L: 0, C: 0, h: color.h };\n if (color.L >= 1 - GAMUT_EPSILON) return { L: 1, C: 0, h: color.h };\n\n let lo = 0;\n let hi = color.C;\n\n for (let i = 0; i < GAMUT_MAP_MAX_ITERATIONS; i++) {\n const midC = (lo + hi) / 2;\n const candidate: Oklch = { L: color.L, C: midC, h: color.h };\n const candidateRgb = toRgb(candidate);\n\n if (isInGamut(candidateRgb)) {\n lo = midC;\n } else {\n // Clip and check JND\n const clipped = clampSrgb(candidateRgb);\n const clippedLab = rgbToOklab(clipped);\n const candidateLab = oklchToOklab(candidate);\n const dE = deltaEOKLab(clippedLab, candidateLab);\n\n if (dE < GAMUT_MAP_JND) {\n // Clipped version is perceptually close enough — converge here.\n // Return lo (last confirmed in-gamut chroma) to guarantee gamut safety.\n break;\n }\n\n hi = midC;\n }\n\n if (hi - lo < GAMUT_MAP_EPSILON) break;\n }\n\n return { L: color.L, C: lo, h: color.h };\n}\n","import type { Gamut, Oklch } from \"../types.js\";\nimport { GAMUT_MAP_MAX_ITERATIONS } from \"../constants.js\";\nimport { oklchToSrgb, oklchToP3 } from \"../conversions/pipeline.js\";\nimport { isInGamut } from \"./check.js\";\n\n/**\n * Find the maximum in-gamut chroma for a given OKLCH lightness and hue.\n *\n * Binary search over [0, upperBound], converging to 1e-6 precision.\n * Upper bounds are empirically safe ceilings — no in-gamut color at any\n * lightness or hue exceeds C = 0.4 in sRGB or C = 0.5 in Display P3.\n * Searching beyond these would waste iterations with no benefit.\n *\n * Returns 0 for L ≤ 0 or L ≥ 1 (pure black and white carry no chroma).\n */\nexport function maxChroma(L: number, h: number, gamut: Gamut = \"srgb\"): number {\n if (L <= 0 || L >= 1) return 0;\n\n const toRgb = gamut === \"display-p3\" ? oklchToP3 : oklchToSrgb;\n let lo = 0;\n let hi = gamut === \"display-p3\" ? 0.5 : 0.4;\n\n for (let i = 0; i < GAMUT_MAP_MAX_ITERATIONS; i++) {\n const mid = (lo + hi) / 2;\n const color: Oklch = { L, C: mid, h };\n const rgb = toRgb(color);\n\n if (isInGamut(rgb)) {\n lo = mid;\n } else {\n hi = mid;\n }\n\n if (hi - lo < 1e-6) break;\n }\n\n return lo;\n}\n","import type { Srgb } from \"../types.js\";\nimport { WCAG_R, WCAG_G, WCAG_B } from \"../constants.js\";\nimport { srgbChannelToLinear } from \"../conversions/srgb.js\";\n\n/** Compute WCAG 2.x relative luminance [0, 1] from an sRGB color. */\nexport function wcagLuminance(color: Srgb): number {\n return (\n WCAG_R * srgbChannelToLinear(color.r) +\n WCAG_G * srgbChannelToLinear(color.g) +\n WCAG_B * srgbChannelToLinear(color.b)\n );\n}\n\n/**\n * Compute WCAG 2.x contrast ratio between two sRGB colors.\n * Returns a value in [1, 21]. Symmetric (order doesn't matter).\n */\nexport function wcagContrast(a: Srgb, b: Srgb): number {\n const lA = wcagLuminance(a);\n const lB = wcagLuminance(b);\n const lighter = Math.max(lA, lB);\n const darker = Math.min(lA, lB);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\n/**\n * Choose black or white text for maximum WCAG contrast against a background.\n * @returns `\"#000000\"` or `\"#ffffff\"`.\n */\nexport function contrastTextHex(background: Srgb): \"#000000\" | \"#ffffff\" {\n const white: Srgb = { r: 1, g: 1, b: 1 };\n const black: Srgb = { r: 0, g: 0, b: 0 };\n return wcagContrast(white, background) > wcagContrast(black, background)\n ? \"#ffffff\"\n : \"#000000\";\n}\n","import type { Srgb } from \"../types.js\";\nimport {\n APCA_MAIN_TRC,\n APCA_SRGB_R,\n APCA_SRGB_G,\n APCA_SRGB_B,\n APCA_NORM_BG,\n APCA_NORM_TXT,\n APCA_REV_TXT,\n APCA_REV_BG,\n APCA_BLK_THRS,\n APCA_BLK_CLMP,\n APCA_SCALE_BOW,\n APCA_SCALE_WOB,\n APCA_LO_BOW_OFFSET,\n APCA_LO_WOB_OFFSET,\n APCA_DELTA_Y_MIN,\n APCA_LO_CLIP,\n} from \"../constants.js\";\n\n/**\n * Compute APCA-W3 Lc (Lightness Contrast) between text and background.\n *\n * Returns a signed value in roughly [-108, +106]:\n * Positive = dark text on light background (BoW)\n * Negative = light text on dark background (WoB)\n * 0 = no meaningful contrast\n *\n * IMPORTANT: Uses its own linearization (simple 2.4 gamma),\n * NOT the IEC piecewise sRGB transfer function.\n */\n/**\n * Practical maximum APCA Lc magnitude used for normalization.\n * BoW tops out at ~+106, WoB at ~-108; we use 108 as a symmetric ceiling.\n */\nexport const APCA_LC_MAX = 108;\n\n/**\n * Normalize a raw APCA Lc value to the range [-1, +1].\n * +1 = maximum dark-on-light contrast (BoW)\n * -1 = maximum light-on-dark contrast (WoB)\n * 0 = no meaningful contrast\n */\nexport function apcaToNormalized(lc: number): number {\n return Math.max(-1, Math.min(1, lc / APCA_LC_MAX));\n}\n\n/**\n * Convert a normalized contrast value [-1, +1] back to a raw APCA Lc value.\n */\nexport function normalizedToApca(normalized: number): number {\n return normalized * APCA_LC_MAX;\n}\n\nexport function apcaContrast(textColor: Srgb, bgColor: Srgb): number {\n // Step 1: Linearize with simple 2.4 gamma and compute Y\n let txtY =\n APCA_SRGB_R * textColor.r ** APCA_MAIN_TRC +\n APCA_SRGB_G * textColor.g ** APCA_MAIN_TRC +\n APCA_SRGB_B * textColor.b ** APCA_MAIN_TRC;\n\n let bgY =\n APCA_SRGB_R * bgColor.r ** APCA_MAIN_TRC +\n APCA_SRGB_G * bgColor.g ** APCA_MAIN_TRC +\n APCA_SRGB_B * bgColor.b ** APCA_MAIN_TRC;\n\n // Step 2: Soft black clamp\n if (txtY < APCA_BLK_THRS) {\n txtY += (APCA_BLK_THRS - txtY) ** APCA_BLK_CLMP;\n }\n if (bgY < APCA_BLK_THRS) {\n bgY += (APCA_BLK_THRS - bgY) ** APCA_BLK_CLMP;\n }\n\n // Step 3: Delta Y check\n if (Math.abs(bgY - txtY) < APCA_DELTA_Y_MIN) return 0;\n\n // Step 4: Polarity-aware contrast\n let sapc: number;\n\n if (bgY > txtY) {\n // Dark text on light background (BoW)\n sapc = (bgY ** APCA_NORM_BG - txtY ** APCA_NORM_TXT) * APCA_SCALE_BOW;\n return sapc < APCA_LO_CLIP ? 0 : (sapc - APCA_LO_BOW_OFFSET) * 100;\n } else {\n // Light text on dark background (WoB)\n sapc = (bgY ** APCA_REV_BG - txtY ** APCA_REV_TXT) * APCA_SCALE_WOB;\n return sapc > -APCA_LO_CLIP ? 0 : (sapc + APCA_LO_WOB_OFFSET) * 100;\n }\n}\n","import type { Oklch } from \"../types.js\";\nimport { ACHROMATIC_THRESHOLD } from \"../constants.js\";\n\n/**\n * Linearly interpolate between two OKLCH colors.\n *\n * L and C are linearly interpolated. Hue uses shortest-arc interpolation.\n * Achromatic colors (C near zero) inherit the other color's hue to avoid\n * meaningless hue sweeps through the achromatic pole.\n */\nexport function mix(a: Oklch, b: Oklch, t: number): Oklch {\n const L = a.L + (b.L - a.L) * t;\n const C = a.C + (b.C - a.C) * t;\n\n // Resolve hue — handle achromatic inputs\n const aIsAchromatic = a.C < ACHROMATIC_THRESHOLD;\n const bIsAchromatic = b.C < ACHROMATIC_THRESHOLD;\n\n if (aIsAchromatic && bIsAchromatic) {\n return { L, C, h: 0 };\n }\n\n const hA = aIsAchromatic ? b.h : a.h;\n const hB = bIsAchromatic ? a.h : b.h;\n\n // Shortest-arc hue interpolation\n let delta = hB - hA;\n if (delta > 180) delta -= 360;\n if (delta < -180) delta += 360;\n\n let h = hA + delta * t;\n if (h < 0) h += 360;\n if (h >= 360) h -= 360;\n\n return { L, C, h };\n}\n","/**\n * Design constants — the values you tune by hand.\n *\n * Edit this file to adjust the perceptual behavior of every scale and\n * grading operation across the library.\n */\n\n// ── Scale defaults ────────────────────────────────────────────────────────────\n\n/**\n * Default number of steps in a generated scale.\n * Fixed at 26 — enough for a full design token set with fine lightness\n * increments without redundancy.\n */\nexport const DEFAULT_SCALE_STEPS = 26;\n\n/**\n * Default hue when none is provided.\n * 0° is the start of the OKLCH hue wheel (red region). Arbitrary but\n * deterministic — callers should always supply an explicit hue.\n */\nexport const DEFAULT_HUE = 0;\n\n// ── Dynamic range ─────────────────────────────────────────────────────────────\n\n/**\n * Lightest step's lightness when the whites slider is at 0.\n * slider 0 → L = MIN_LIGHTEST_L, slider 1 → L = 1.0 (pure white).\n */\nexport const MIN_LIGHTEST_L = 0.96;\n\n/**\n * Darkest step's lightness when the darks slider is at 0.\n * slider 0 → L = MAX_DARKEST_L, slider 1 → L = 0.0 (pure black).\n */\nexport const MAX_DARKEST_L = 0.16;\n\n// ── Hue grading ───────────────────────────────────────────────────────────────\n\n/**\n * How far global grading reaches into the scale from each end (0–1).\n * Light grading fades to zero at t = GRADING_REACH.\n * Dark grading fades to zero at t = 1 − GRADING_REACH.\n */\nexport const GRADING_REACH = 3 / 5;\n\n/** Maximum amount for global grading. Inputs above this are clamped. */\nexport const MAX_GRADING_AMOUNT = 0.25;\n\n/**\n * Fraction of the gamut boundary injected as chroma when global grading\n * is active. Ensures grading has a visible tinting effect even on\n * achromatic (chroma.amount = 0) palettes.\n *\n * Only global grading injects chroma — per-palette shift does not.\n */\nexport const GRADING_CHROMA_RATIO = 0.5;\n\n/**\n * How far per-palette hue shift reaches into the scale from each end (0–1).\n * Slightly wider than GRADING_REACH to give per-palette shifts more room.\n */\nexport const SHIFT_REACH = 2 / 3;\n\n/** Maximum amount for per-palette hue shift. Inputs above this are clamped. */\nexport const MAX_SHIFT_AMOUNT = 0.5;\n\n// ── Color difference ──────────────────────────────────────────────────────────\n\n/**\n * Just-noticeable difference threshold (deltaEOK).\n * Colors with distance below this are considered perceptually identical.\n * Used to classify color matches as exact vs. fallback.\n */\nexport const PERCEPTUAL_JND = 0.02;\n","/**\n * Global hue grading — shifts each palette's base hue toward shared\n * target hues at the light and dark scale endpoints.\n *\n * Light grading fades from full at the lightest step to zero at GRADING_REACH.\n * Dark grading fades from zero at (1 - GRADING_REACH) to full at the darkest step.\n * In the overlap zone, both shifts are additive (commutative).\n */\n\nimport {\n GRADING_REACH,\n MAX_GRADING_AMOUNT,\n SHIFT_REACH,\n MAX_SHIFT_AMOUNT,\n} from \"../config.js\";\n\nexport interface Grading {\n /** Hue grading for the light end of the scale. */\n readonly light?: { readonly hue: number; readonly amount: number };\n /** Hue grading for the dark end of the scale. */\n readonly dark?: { readonly hue: number; readonly amount: number };\n}\n\n/** Per-palette hue shift (one end only). */\nexport interface Shift {\n /** Target hue to shift toward (0–360°). */\n readonly hue: number;\n /** Blend strength (0–MAX_SHIFT_AMOUNT). */\n readonly amount: number;\n /** Which end to affect. `true` = light end, `false`/omitted = dark end (default). */\n readonly light?: boolean;\n}\n\n/**\n * Compute the graded hue at position `t` in the scale.\n *\n * Uses vector interpolation in Cartesian space rather than angular deltas\n * to avoid the shortest-arc discontinuity at 180° (where the direction\n * of rotation flips abruptly). Each grade's displacement is computed as\n * a vector offset from the base hue, and displacements are additive\n * (commutative — order doesn't matter).\n *\n * @param baseHue The palette's own hue (0–360°).\n * @param t Position in the scale: 0 = lightest, 1 = darkest.\n * @param grade Hue grade configuration.\n * @param reach How far each grade reaches into the scale (default: GRADING_REACH).\n * @param maxIntensity Maximum amount clamp (default: MAX_GRADING_AMOUNT).\n * @returns The graded hue in degrees (0–360).\n */\nexport function gradeHue(\n baseHue: number,\n t: number,\n grade: Grading,\n reach: number = GRADING_REACH,\n maxIntensity: number = MAX_GRADING_AMOUNT,\n): number {\n const li = Math.max(0, Math.min(maxIntensity, grade.light?.amount ?? 0));\n const di = Math.max(0, Math.min(maxIntensity, grade.dark?.amount ?? 0));\n\n // Early exit: no grading\n if (li === 0 && di === 0) return baseHue;\n\n // Light influence: cosine fade from 1 at t=0 to 0 at t=reach\n const lightInfluence =\n t <= reach ? 0.5 * (1 + Math.cos((Math.PI * t) / reach)) : 0;\n\n // Dark influence: cosine fade from 0 at t=(1-reach) to 1 at t=1\n const darkInfluence =\n t >= 1 - reach\n ? 0.5 * (1 + Math.cos((Math.PI * (1 - t)) / reach))\n : 0;\n\n // Base hue as unit vector\n const toRad = Math.PI / 180;\n const baseRad = baseHue * toRad;\n const bx = Math.cos(baseRad);\n const by = Math.sin(baseRad);\n\n // Accumulate displacements in Cartesian space\n let dx = 0;\n let dy = 0;\n\n if (lightInfluence > 0 && li > 0) {\n const blend = lightInfluence * li;\n const lRad = (grade.light!.hue) * toRad;\n dx += blend * (Math.cos(lRad) - bx);\n dy += blend * (Math.sin(lRad) - by);\n }\n\n if (darkInfluence > 0 && di > 0) {\n const blend = darkInfluence * di;\n const dRad = (grade.dark!.hue) * toRad;\n dx += blend * (Math.cos(dRad) - bx);\n dy += blend * (Math.sin(dRad) - by);\n }\n\n // Reconstruct hue from displaced vector\n const rx = bx + dx;\n const ry = by + dy;\n\n // Safety: collapsed vector (opposite hues at exactly 50% blend)\n if (rx * rx + ry * ry < 1e-20) return baseHue;\n\n return ((Math.atan2(ry, rx) / toRad) + 360) % 360;\n}\n\n/**\n * Compute the combined grading influence at position `t` (0–1).\n *\n * Returns a scalar in [0, 1] representing how strongly global grading\n * affects position `t`. This is the maximum of the light and dark\n * cosine-fade envelopes, each scaled by its respective amount.\n *\n * Used by the chroma injection system to tint achromatic palettes\n * proportionally to grading strength.\n */\nexport function gradingInfluence(t: number, grading: Grading): number {\n const li = Math.max(0, Math.min(MAX_GRADING_AMOUNT, grading.light?.amount ?? 0));\n const di = Math.max(0, Math.min(MAX_GRADING_AMOUNT, grading.dark?.amount ?? 0));\n\n if (li === 0 && di === 0) return 0;\n\n const lightInfluence =\n t <= GRADING_REACH ? 0.5 * (1 + Math.cos((Math.PI * t) / GRADING_REACH)) : 0;\n\n const darkInfluence =\n t >= 1 - GRADING_REACH\n ? 0.5 * (1 + Math.cos((Math.PI * (1 - t)) / GRADING_REACH))\n : 0;\n\n const lightBlend = lightInfluence * (li / MAX_GRADING_AMOUNT);\n const darkBlend = darkInfluence * (di / MAX_GRADING_AMOUNT);\n\n return Math.max(lightBlend, darkBlend);\n}\n\n/**\n * Resolve the final hue at position `t`, applying local shift first, then global grading.\n *\n * This is the canonical composition: per-palette shift (using SHIFT_REACH /\n * MAX_SHIFT_AMOUNT) first, then global grading (using GRADING_REACH /\n * MAX_GRADING_AMOUNT) on top — so grading's influence is preserved at full\n * strength across all palettes, keeping them visually coherent.\n *\n * @param baseHue The palette's own hue (0–360°).\n * @param t Position in the scale: 0 = lightest, 1 = darkest.\n * @param globalGrade Global grading (shared across palettes), or undefined.\n * @param localGrade Local grading (per-palette, expanded from Shift), or undefined.\n * @returns The fully graded hue in degrees (0–360).\n */\nexport function resolveGradedHue(\n baseHue: number,\n t: number,\n globalGrade?: Grading,\n localGrade?: Grading,\n): number {\n let h = baseHue;\n if (localGrade) h = gradeHue(h, t, localGrade, SHIFT_REACH, MAX_SHIFT_AMOUNT);\n if (globalGrade) h = gradeHue(h, t, globalGrade);\n return h;\n}\n\n/**\n * Adapt a Shift into a one-sided Grading so it can be passed to gradeHue.\n *\n * The Shift interface is flat (hue, amount, light?) for ergonomic API use,\n * but gradeHue operates on the Grading shape (light/dark sub-objects).\n * This function bridges the two, activating only the requested end.\n *\n * @param hue Target hue for the active side (0–360°).\n * @param amount Blend strength for the active side.\n * @param light `true` = light end, `false`/omitted = dark end (default).\n */\nexport function buildOneSidedGrade(\n hue: number,\n amount: number,\n light: boolean = false,\n): Grading {\n return light\n ? { light: { hue, amount } }\n : { dark: { hue, amount } };\n}\n","/**\n * Dynamic range resolution — maps slider values (0–1) to OKLCH lightness\n * bounds for the lightest and darkest steps of a color scale.\n */\n\nimport { MIN_LIGHTEST_L, MAX_DARKEST_L } from \"../config.js\";\n\n/**\n * Resolve a whites slider value (0–1) to an OKLCH lightness.\n * slider 0 → L = MIN_LIGHTEST_L (0.96), slider 1 → L = 1.0 (pure white)\n */\nexport function resolveLightest(slider: number): number {\n const s = Math.max(0, Math.min(1, slider));\n return MIN_LIGHTEST_L + s * (1.0 - MIN_LIGHTEST_L);\n}\n\n/**\n * Resolve a darks slider value (0–1) to an OKLCH lightness.\n * slider 0 → L = MAX_DARKEST_L (0.16), slider 1 → L = 0.0 (pure black)\n */\nexport function resolveDarkest(slider: number): number {\n const s = Math.max(0, Math.min(1, slider));\n return MAX_DARKEST_L * (1 - s);\n}\n\n/**\n * Map an OKLCH lightness to a normalized scale position (0–1).\n * 0 = lightest end, 1 = darkest end.\n *\n * Inverse of the lightness interpolation inside generateScale.\n * Useful for deriving chromaPeak from a key color's lightness.\n */\nexport function lightnessToScaleT(L: number, lightestL: number, darkestL: number): number {\n const range = lightestL - darkestL;\n if (range <= 0) return 0.5;\n return Math.max(0, Math.min(1, (lightestL - L) / range));\n}\n","import type { Oklch } from \"../types.js\";\nimport { maxChroma } from \"../gamut/max-chroma.js\";\nimport type { Grading, Shift } from \"./hue-grade.js\";\nimport { resolveGradedHue, buildOneSidedGrade } from \"./hue-grade.js\";\nimport { resolveLightest, resolveDarkest } from \"./dynamic-range.js\";\nimport {\n DEFAULT_SCALE_STEPS,\n DEFAULT_HUE,\n GRADING_CHROMA_RATIO,\n GRADING_REACH,\n MAX_GRADING_AMOUNT,\n} from \"../config.js\";\n\ntype Gamut = \"srgb\" | \"display-p3\";\nconst toRad = Math.PI / 180;\n\n/**\n * Apply grading as an additive chroma overlay.\n *\n * Builds per-side chroma vectors pointing at the grading TARGET hues\n * (not the palette's hue) and adds them to the palette's existing\n * chroma in Cartesian (a, b) space. This ensures grading tints even\n * fully achromatic palettes without the base hue leaking through.\n */\nfunction applyGradingOverlay(\n C: number, h: number, L: number, t: number,\n grading: Grading, gamut: Gamut,\n): { C: number; h: number } {\n const li = Math.max(0, Math.min(MAX_GRADING_AMOUNT, grading.light?.amount ?? 0));\n const di = Math.max(0, Math.min(MAX_GRADING_AMOUNT, grading.dark?.amount ?? 0));\n if (li === 0 && di === 0) return { C, h };\n\n // Per-side cosine-fade influences\n const lightFade = t <= GRADING_REACH\n ? 0.5 * (1 + Math.cos((Math.PI * t) / GRADING_REACH)) : 0;\n const darkFade = t >= 1 - GRADING_REACH\n ? 0.5 * (1 + Math.cos((Math.PI * (1 - t)) / GRADING_REACH)) : 0;\n\n const lightBlend = lightFade * (li / MAX_GRADING_AMOUNT);\n const darkBlend = darkFade * (di / MAX_GRADING_AMOUNT);\n if (lightBlend === 0 && darkBlend === 0) return { C, h };\n\n // Palette's existing chroma as Cartesian vector\n const hRad = h * toRad;\n let a = C * Math.cos(hRad);\n let b = C * Math.sin(hRad);\n\n // Add overlay vectors at grading TARGET hues\n if (lightBlend > 0) {\n const lh = grading.light!.hue;\n const lRad = lh * toRad;\n const lC = maxChroma(L, lh, gamut) * GRADING_CHROMA_RATIO * lightBlend;\n a += lC * Math.cos(lRad);\n b += lC * Math.sin(lRad);\n }\n if (darkBlend > 0) {\n const dh = grading.dark!.hue;\n const dRad = dh * toRad;\n const dC = maxChroma(L, dh, gamut) * GRADING_CHROMA_RATIO * darkBlend;\n a += dC * Math.cos(dRad);\n b += dC * Math.sin(dRad);\n }\n\n // Convert back to polar\n let newC = Math.sqrt(a * a + b * b);\n let newH = ((Math.atan2(b, a) / toRad) + 360) % 360;\n\n // Clamp to gamut at the resulting hue\n newC = Math.min(newC, maxChroma(L, newH, gamut));\n\n return { C: newC, h: newH };\n}\n\nexport interface ScaleOptions {\n /**\n * Tonal range of the scale.\n * - `light`: how light the lightest step is (0–1). Default: 1.\n * 0 → L = MIN_LIGHTEST_L (0.96), 1 → L = 1.0 (pure white).\n * - `dark`: how dark the darkest step is (0–1). Default: 1.\n * 0 → L = MAX_DARKEST_L (0.16), 1 → L = 0.0 (pure black).\n */\n readonly contrast?: { readonly light?: number; readonly dark?: number };\n /**\n * Hue angle in degrees (0–360). Default: DEFAULT_HUE (0).\n * Every step shares this base hue unless shifted by `grading` or `shift`.\n */\n readonly hue?: number;\n /**\n * Chroma shape of the scale.\n * - `amount`: how much of the available gamut to use (0–1). Default: 0.\n * 0 = fully achromatic (default), 1 = maximum in-gamut chroma at each lightness.\n * - `balance`: how chroma is distributed along the lightness range (0–1).\n * 0 = chroma concentrated toward the lightest end, 1 = toward the darkest end,\n * 0.5 = natural distribution (default, follows gamut boundary shape).\n */\n readonly chroma?: { readonly amount?: number; readonly balance?: number };\n /**\n * Global hue grading. When provided, the hue at each step is shifted\n * toward target hues based on position in the scale.\n * Light grading affects the lightest 3/5, dark grading affects the\n * darkest 3/5, with additive overlap in the middle fifth.\n */\n readonly grading?: Grading;\n /**\n * Per-palette hue shift. A one-sided grade applied before global\n * grading, with its own reach and strength limits (SHIFT_REACH,\n * MAX_SHIFT_AMOUNT). Defaults to the dark end; set `light: true` to target\n * the light end instead.\n */\n readonly shift?: Shift;\n /** Use Display P3 gamut instead of sRGB (default: false). */\n readonly isP3?: boolean;\n}\n\n/**\n * Generate an OKLCH color scale from lightest to darkest.\n *\n * Always produces DEFAULT_SCALE_STEPS colors. Chroma at each step is\n * proportional to the gamut boundary at that lightness, scaled by\n * `chroma.amount`. This guarantees every color is in-gamut — no fallbacks\n * needed — while producing a smooth, natural chroma curve.\n *\n * Use `contrast` to constrain the tonal range\n * (e.g. for scales that don't extend to pure white or pure black).\n *\n * Use `chroma.balance` to shift how chroma is distributed within the boundary.\n * The curve endpoints stay fixed while the distribution shifts smoothly.\n * The effective shift range is proportional to the headroom left by chroma.amount.\n */\nexport function generateScale(options: ScaleOptions = {}): Oklch[] {\n const {\n contrast,\n hue = DEFAULT_HUE,\n chroma,\n isP3 = false,\n grading,\n shift,\n } = options;\n const gamut = isP3 ? \"display-p3\" : \"srgb\";\n\n const steps = DEFAULT_SCALE_STEPS;\n const chromaRatio = chroma?.amount ?? 0;\n const chromaPeak = chroma?.balance ?? 0.5;\n const hueGrade = grading;\n const localHueGrade = shift ? buildOneSidedGrade(shift.hue, shift.amount, shift.light) : undefined;\n\n const ratio = Math.max(0, Math.min(1, chromaRatio));\n const peak = Math.max(0, Math.min(1, chromaPeak));\n const lightestL = resolveLightest(contrast?.light ?? 1);\n const darkestL = resolveDarkest(contrast?.dark ?? 1);\n\n // Helper: resolve hue at position t (applies local shift first, then global grading)\n const hueAt = (t: number) => resolveGradedHue(hue, t, hueGrade, localHueGrade);\n\n // Fast path: skip peak skew logic when balance has no effect.\n // - peak === 0.5: already at the natural gamut peak, nothing to shift\n // - ratio === 0: no chroma at all, boundary shape is irrelevant\n // - ratio >= 1: inner triangle equals the boundary triangle, no headroom to slide\n if (peak === 0.5 || ratio === 0 || ratio >= 1) {\n const scale: Oklch[] = [];\n for (let i = 0; i < steps; i++) {\n const t = i / (steps - 1);\n const L = lightestL - t * (lightestL - darkestL);\n let h = hueAt(t);\n // Chroma is shaped by the base hue's boundary to keep the curve smooth.\n // The shifted hue's boundary is used as a final in-gamut clamp only —\n // this prevents spikes when the shifted hue has more available chroma\n // than the base (e.g. blue → pink passing through the purple region).\n let C = Math.min(maxChroma(L, hue, gamut) * ratio, maxChroma(L, h, gamut));\n\n if (hueGrade) {\n const overlay = applyGradingOverlay(C, h, L, t, hueGrade, gamut);\n C = overlay.C;\n h = overlay.h;\n }\n\n scale.push({ L, C, h });\n }\n return scale;\n }\n\n // ── Peak skew logic ──\n // Warp the parameter t so the boundary peak appears at a shifted position.\n // Endpoints stay fixed (warp(0)=0, warp(1)=1), only the peak moves.\n\n // 1. Sample boundary to find natural peak and valid shift range\n const N = 100;\n let peakT = 0.5;\n let peakBoundaryC = 0;\n const boundarySamples: { t: number; C: number }[] = [];\n\n for (let i = 0; i <= N; i++) {\n const t = i / N;\n const L = lightestL - t * (lightestL - darkestL);\n // Sample the base hue's boundary — the same reference used when building\n // the warp below. Using the shifted hue here would skew peakT and the\n // valid range toward a hue-specific boundary shape, inconsistent with\n // how chroma is actually computed in step 4.\n const C = maxChroma(L, hue, gamut);\n boundarySamples.push({ t, C });\n if (C > peakBoundaryC) {\n peakBoundaryC = C;\n peakT = t;\n }\n }\n\n // 2. Find valid range: where boundary can accommodate the inner peak height\n const innerPeakC = peakBoundaryC * ratio;\n let validMinT = peakT;\n let validMaxT = peakT;\n\n for (const { t, C } of boundarySamples) {\n if (C >= innerPeakC - 1e-6) {\n if (t < validMinT) validMinT = t;\n if (t > validMaxT) validMaxT = t;\n }\n }\n\n // 3. Map chroma.balance (0–1) to valid range, normalized so 0.5 → peakT\n let targetT: number;\n if (peak <= 0.5) {\n targetT = validMinT + (peak / 0.5) * (peakT - validMinT);\n } else {\n targetT = peakT + ((peak - 0.5) / 0.5) * (validMaxT - peakT);\n }\n\n // Safety: if the piecewise mapping produces a degenerate targetT (outside\n // (0, 1)), fall back to the natural peak. This can occur at floating-point\n // boundaries rather than from any single expected input combination.\n if (targetT <= 0 || targetT >= 1) {\n targetT = peakT;\n }\n\n // 4. Build scale with piecewise-linear warp: targetT → peakT\n const scale: Oklch[] = [];\n for (let i = 0; i < steps; i++) {\n const t = i / (steps - 1);\n const L = lightestL - t * (lightestL - darkestL);\n let h = hueAt(t);\n\n // Piecewise-linear warp: maps 0→0, targetT→peakT, 1→1.\n // Two segments scale t independently so the boundary peak (at peakT in\n // warp space) lands at targetT in the output — endpoints stay fixed.\n let tWarped: number;\n if (t <= targetT) {\n tWarped = t * (peakT / targetT);\n } else {\n tWarped = peakT + (t - targetT) * ((1 - peakT) / (1 - targetT));\n }\n\n const Lwarped = lightestL - tWarped * (lightestL - darkestL);\n // Use the base hue for the warped chroma lookup — consistent with step 1\n // and the fast path. The warp is purely a lightness operation; mixing in\n // the shifted hue at tWarped would introduce cross-position hue artifacts.\n const warpedC = maxChroma(Lwarped, hue, gamut) * ratio;\n // Clamp to the shifted hue's actual boundary at this L: the in-gamut\n // guarantee for the final color { L, C, h }.\n const boundaryC = maxChroma(L, h, gamut);\n let C = Math.min(warpedC, boundaryC);\n\n if (hueGrade) {\n const overlay = applyGradingOverlay(C, h, L, t, hueGrade, gamut);\n C = overlay.C;\n h = overlay.h;\n }\n\n scale.push({ L, C, h });\n }\n\n return scale;\n}\n","import type { Hex, Oklch, Gamut } from \"../types.js\";\nimport {\n hexToOklch,\n oklchToSrgb,\n oklchToP3,\n oklchToHex,\n} from \"../conversions/pipeline.js\";\nimport { isInGamut } from \"../gamut/check.js\";\nimport { gamutMap } from \"../gamut/map.js\";\nimport { maxChroma } from \"../gamut/max-chroma.js\";\n\n/**\n * Result of resolving a color into scale-ready parameters.\n */\nexport interface ResolvedColor {\n /** The final OKLCH color, guaranteed in-gamut for the target gamut. */\n readonly oklch: Oklch;\n /** Hex representation (sRGB-clamped if the resolved color exceeds sRGB). */\n readonly hex: Hex;\n /** Whether the input was outside the target gamut and was remapped. */\n readonly wasRemapped: boolean;\n /** The original OKLCH before gamut mapping (identical to oklch if in-gamut). */\n readonly original: Oklch;\n /** Chroma lost during gamut mapping (0 if in-gamut). */\n readonly chromaShift: number;\n /** Hue from the resolved color. */\n readonly hue: number;\n /** Chroma as a fraction of the gamut boundary at this L/h (0–1). */\n readonly chromaRatio: number;\n}\n\n/**\n * Resolve a color (hex or OKLCH) into scale-ready parameters.\n *\n * If the color is outside the target gamut, it is perceptually mapped to the\n * nearest in-gamut color (chroma reduction at fixed L and h). The result\n * includes the derived hue and chromaRatio.\n *\n * Hex input is always valid sRGB, so `wasRemapped` will be false for hex\n * with gamut=\"srgb\". OKLCH input may be out of gamut and will be mapped.\n *\n * @param input A hex string (#RGB, #RRGGBB) or an OKLCH color.\n * @param isP3 Use Display P3 gamut instead of sRGB (default: false).\n */\nexport function resolveColor(\n input: Hex | Oklch,\n isP3: boolean = false,\n): ResolvedColor {\n const gamut: Gamut = isP3 ? \"display-p3\" : \"srgb\";\n const isHex = typeof input === \"string\";\n const original: Oklch = isHex ? hexToOklch(input) : input;\n\n // Hex encodes valid sRGB by definition, and sRGB ⊂ P3, so hex input\n // is always in-gamut for both supported gamuts. Skipping the round-trip\n // check avoids false negatives from floating-point drift.\n let inGamut: boolean;\n if (isHex) {\n inGamut = true;\n } else {\n const rgb =\n gamut === \"display-p3\" ? oklchToP3(original) : oklchToSrgb(original);\n inGamut = isInGamut(rgb);\n }\n\n const oklch = inGamut ? original : gamutMap(original, gamut);\n\n const boundary = maxChroma(oklch.L, oklch.h, gamut);\n const chromaRatio = boundary > 0 ? oklch.C / boundary : 0;\n\n return {\n oklch,\n hex: oklchToHex(oklch),\n wasRemapped: !inGamut,\n original,\n chromaShift: original.C - oklch.C,\n hue: oklch.h,\n chromaRatio: Math.min(1, chromaRatio),\n };\n}\n","import type { Hex, Oklch } from \"../types.js\";\nimport { resolveColor } from \"./resolve-color.js\";\nimport { lightnessToScaleT, resolveLightest, resolveDarkest } from \"./dynamic-range.js\";\nimport { DEFAULT_SCALE_STEPS } from \"../config.js\";\n\n/**\n * The result of deriving scale parameters from a key color.\n *\n * Spread `hue` and `chroma` directly into ScaleOptions, then use\n * `stepIndex` to locate the key color's position in the generated scale.\n */\nexport interface KeyColorResult {\n /** Derived hue angle — use directly as ScaleOptions.hue. */\n readonly hue: number;\n /**\n * Derived chroma shape — use directly as ScaleOptions.chroma.\n * - `amount`: how saturated the scale is (0–1, relative to gamut boundary).\n * - `balance`: where in the scale the key color's lightness falls (0 = lightest, 1 = darkest).\n */\n readonly chroma: { readonly amount: number; readonly balance: number };\n /** The step index in a scale of `steps` length where this color lands. */\n readonly stepIndex: number;\n /** Hex representation of the resolved color (sRGB-clamped if necessary). */\n readonly hex: Hex;\n /** The final OKLCH color, guaranteed in-gamut for the target gamut. */\n readonly oklch: Oklch;\n /** Whether the input was outside the target gamut and was remapped. */\n readonly wasRemapped: boolean;\n /** The original OKLCH before gamut mapping (identical to oklch if in-gamut). */\n readonly original: Oklch;\n}\n\n/**\n * Derive scale parameters from a known color.\n *\n * Given a hex or OKLCH color, returns the `hue` and `chroma` values\n * ready to spread into ScaleOptions. The chroma balance is derived from\n * where the color's lightness falls within the scale's lightness range,\n * so the chroma distribution is centered around the key color's position.\n *\n * @param color A hex string (#RGB or #RRGGBB) or an OKLCH color object.\n * @param options Scale context — must match the ScaleOptions you will use.\n * `contrast` values are slider values (0–1), same as ScaleOptions.contrast.\n * `steps` is the number of steps in the scale (default: 26).\n *\n * @example\n * const key = keyColor('#3B82F6');\n * const scale = generateScale({ hue: key.hue, chroma: key.chroma });\n * const matchedHex = oklchToHex(scale[key.stepIndex]);\n */\nexport function keyColor(\n color: Hex | Oklch,\n options?: {\n readonly isP3?: boolean;\n readonly contrast?: { readonly light?: number; readonly dark?: number };\n readonly steps?: number;\n },\n): KeyColorResult {\n const { isP3 = false, contrast, steps = DEFAULT_SCALE_STEPS } = options ?? {};\n const resolved = resolveColor(color, isP3);\n const lightestL = resolveLightest(contrast?.light ?? 1);\n const darkestL = resolveDarkest(contrast?.dark ?? 1);\n const balance = lightnessToScaleT(resolved.oklch.L, lightestL, darkestL);\n const stepIndex = Math.round(balance * Math.max(0, steps - 1));\n\n return {\n hue: resolved.hue,\n chroma: { amount: resolved.chromaRatio, balance },\n stepIndex,\n hex: resolved.hex,\n oklch: resolved.oklch,\n wasRemapped: resolved.wasRemapped,\n original: resolved.original,\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/constants.ts","../src/conversions/oklab.ts","../src/conversions/linear-srgb.ts","../src/conversions/linear-p3.ts","../src/conversions/srgb.ts","../src/conversions/hex.ts","../src/conversions/pipeline.ts","../src/gamut/check.ts","../src/color/difference.ts","../src/gamut/map.ts","../src/gamut/max-chroma.ts","../src/contrast/wcag.ts","../src/contrast/apca.ts","../src/color/interpolation.ts","../src/config.ts","../src/scale/hue-grade.ts","../src/scale/generate.ts","../src/scale/resolve-color.ts","../src/scale/dynamic-range.ts","../src/scale/key-color.ts"],"names":["toRad","scale"],"mappings":";AAEO,IAAM,oBAAA,GAAuB,OAAA;AAC7B,IAAM,2BAAA,GAA8B,QAAA;AACpC,IAAM,gBAAA,GAAmB,KAAA;AACzB,IAAM,mBAAA,GAAsB,GAAA;AAC5B,IAAM,iBAAA,GAAoB,KAAA;AAC1B,IAAM,gBAAA,GAAmB,KAAA;AAIzB,IAAM,kBAAA,GAAqB;AAAA,EAChC,CAAC,YAAA,EAAc,YAAA,EAAc,YAAY,CAAA;AAAA,EACzC,CAAC,YAAA,EAAc,YAAA,EAAc,YAAY,CAAA;AAAA,EACzC,CAAC,YAAA,EAAc,YAAA,EAAc,YAAY;AAC3C,CAAA;AAIO,IAAM,kBAAA,GAAqB;AAAA,EAChC,CAAC,YAAA,EAAe,WAAA,EAAe,aAAa,CAAA;AAAA,EAC5C,CAAC,YAAA,EAAe,YAAA,EAAe,YAAa,CAAA;AAAA,EAC5C,CAAC,YAAA,EAAe,YAAA,EAAe,YAAa;AAC9C,CAAA;AAIO,IAAM,kBAAA,GAAqB;AAAA,EAChC,CAAC,CAAA,EAAc,YAAA,EAAe,YAAa,CAAA;AAAA,EAC3C,CAAC,CAAA,EAAc,aAAA,EAAe,aAAa,CAAA;AAAA,EAC3C,CAAC,CAAA,EAAc,aAAA,EAAe,YAAa;AAC7C,CAAA;AAIO,IAAM,kBAAA,GAAqB;AAAA,EAChC,CAAC,YAAA,EAAe,aAAA,EAAe,YAAa,CAAA;AAAA,EAC5C,CAAC,aAAA,EAAe,YAAA,EAAe,aAAa,CAAA;AAAA,EAC5C,CAAC,aAAA,EAAe,aAAA,EAAe,WAAa;AAC9C,CAAA;AAKO,IAAM,gBAAA,GAAmB;AAAA,EAC9B,CAAC,YAAA,EAAe,YAAA,EAAe,YAAa,CAAA;AAAA,EAC5C,CAAC,YAAA,EAAe,YAAA,EAAe,YAAa,CAAA;AAAA,EAC5C,CAAC,YAAA,EAAe,YAAA,EAAe,YAAa;AAC9C,CAAA;AAIO,IAAM,gBAAA,GAAmB;AAAA,EAC9B,CAAC,WAAA,EAAe,aAAA,EAAe,YAAa,CAAA;AAAA,EAC5C,CAAC,aAAA,EAAe,YAAA,EAAe,aAAa,CAAA;AAAA,EAC5C,CAAC,aAAA,EAAe,aAAA,EAAe,YAAa;AAC9C,CAAA;AAIO,IAAM,aAAA,GAAgB,IAAA;AACtB,IAAM,aAAA,GAAgB,IAAA;AACtB,IAAM,iBAAA,GAAoB,IAAA;AAC1B,IAAM,wBAAA,GAA2B,EAAA;AAIjC,IAAM,oBAAA,GAAuB,KAAA;AAI7B,IAAM,MAAA,GAAS,MAAA;AACf,IAAM,MAAA,GAAS,MAAA;AACf,IAAM,MAAA,GAAS,MAAA;AAIf,IAAM,aAAA,GAAgB,GAAA;AACtB,IAAM,WAAA,GAAc,SAAA;AACpB,IAAM,WAAA,GAAc,SAAA;AACpB,IAAM,WAAA,GAAc,QAAA;AACpB,IAAM,YAAA,GAAe,IAAA;AACrB,IAAM,aAAA,GAAgB,IAAA;AACtB,IAAM,YAAA,GAAe,IAAA;AACrB,IAAM,WAAA,GAAc,IAAA;AACpB,IAAM,aAAA,GAAgB,KAAA;AACtB,IAAM,aAAA,GAAgB,KAAA;AACtB,IAAM,cAAA,GAAiB,IAAA;AACvB,IAAM,cAAA,GAAiB,IAAA;AACvB,IAAM,kBAAA,GAAqB,KAAA;AAC3B,IAAM,kBAAA,GAAqB,KAAA;AAC3B,IAAM,gBAAA,GAAmB,IAAA;AACzB,IAAM,YAAA,GAAe,GAAA;AAIrB,IAAM,UAAA,GAAa,KAAK,EAAA,GAAK,GAAA;AAC7B,IAAM,UAAA,GAAa,MAAM,IAAA,CAAK,EAAA;;;AC7F9B,SAAS,aAAa,GAAA,EAAmB;AAC9C,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,CAAA,GAAI,IAAI,CAAA,GAAI,GAAA,CAAI,CAAA,GAAI,GAAA,CAAI,CAAC,CAAA;AAEjD,EAAA,IAAI,IAAI,oBAAA,EAAsB;AAC5B,IAAA,OAAO,EAAE,CAAA,EAAG,GAAA,CAAI,GAAG,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAE;AAAA,EAChC;AAEA,EAAA,IAAI,IAAI,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA,EAAG,GAAA,CAAI,CAAC,CAAA,GAAI,UAAA;AACnC,EAAA,IAAI,CAAA,GAAI,GAAG,CAAA,IAAK,GAAA;AAEhB,EAAA,OAAO,EAAE,CAAA,EAAG,GAAA,CAAI,CAAA,EAAG,GAAG,CAAA,EAAE;AAC1B;AAGO,SAAS,aAAa,GAAA,EAAmB;AAC9C,EAAA,MAAM,IAAA,GAAO,IAAI,CAAA,GAAI,UAAA;AACrB,EAAA,OAAO;AAAA,IACL,GAAG,GAAA,CAAI,CAAA;AAAA,IACP,CAAA,EAAG,GAAA,CAAI,CAAA,GAAI,IAAA,CAAK,IAAI,IAAI,CAAA;AAAA,IACxB,CAAA,EAAG,GAAA,CAAI,CAAA,GAAI,IAAA,CAAK,IAAI,IAAI;AAAA,GAC1B;AACF;;;AChBO,SAAS,kBAAkB,KAAA,EAA0B;AAE1D,EAAA,MAAM,CAAA,GACJ,mBAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,KAAA,CAAM,IACjC,kBAAA,CAAmB,CAAC,EAAE,CAAC,CAAA,GAAI,MAAM,CAAA,GACjC,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,IAAI,KAAA,CAAM,CAAA;AACnC,EAAA,MAAM,CAAA,GACJ,mBAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,KAAA,CAAM,IACjC,kBAAA,CAAmB,CAAC,EAAE,CAAC,CAAA,GAAI,MAAM,CAAA,GACjC,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,IAAI,KAAA,CAAM,CAAA;AACnC,EAAA,MAAM,CAAA,GACJ,mBAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,KAAA,CAAM,IACjC,kBAAA,CAAmB,CAAC,EAAE,CAAC,CAAA,GAAI,MAAM,CAAA,GACjC,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,IAAI,KAAA,CAAM,CAAA;AAGnC,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA;AACtB,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA;AACtB,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA;AAGtB,EAAA,OAAO;AAAA,IACL,GACE,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,IAAI,EAAA,GAC3B,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,EAAA,GAC3B,mBAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,EAAA;AAAA,IAC7B,GACE,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,IAAI,EAAA,GAC3B,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,EAAA,GAC3B,mBAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,EAAA;AAAA,IAC7B,GACE,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,IAAI,EAAA,GAC3B,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,EAAA,GAC3B,mBAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI;AAAA,GAC/B;AACF;AAGO,SAAS,kBAAkB,KAAA,EAA0B;AAE1D,EAAA,MAAM,EAAA,GACJ,mBAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,KAAA,CAAM,IACjC,kBAAA,CAAmB,CAAC,EAAE,CAAC,CAAA,GAAI,MAAM,CAAA,GACjC,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,IAAI,KAAA,CAAM,CAAA;AACnC,EAAA,MAAM,EAAA,GACJ,mBAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,KAAA,CAAM,IACjC,kBAAA,CAAmB,CAAC,EAAE,CAAC,CAAA,GAAI,MAAM,CAAA,GACjC,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,IAAI,KAAA,CAAM,CAAA;AACnC,EAAA,MAAM,EAAA,GACJ,mBAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,KAAA,CAAM,IACjC,kBAAA,CAAmB,CAAC,EAAE,CAAC,CAAA,GAAI,MAAM,CAAA,GACjC,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,IAAI,KAAA,CAAM,CAAA;AAGnC,EAAA,MAAM,CAAA,GAAI,KAAK,EAAA,GAAK,EAAA;AACpB,EAAA,MAAM,CAAA,GAAI,KAAK,EAAA,GAAK,EAAA;AACpB,EAAA,MAAM,CAAA,GAAI,KAAK,EAAA,GAAK,EAAA;AAGpB,EAAA,OAAO;AAAA,IACL,GACE,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,IAAI,CAAA,GAC3B,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,GAC3B,mBAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA;AAAA,IAC7B,GACE,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,IAAI,CAAA,GAC3B,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,GAC3B,mBAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA;AAAA,IAC7B,GACE,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,IAAI,CAAA,GAC3B,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,GAC3B,mBAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI;AAAA,GAC/B;AACF;;;ACzEO,SAAS,gBAAgB,KAAA,EAA0B;AAExD,EAAA,MAAM,CAAA,GACJ,iBAAiB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,KAAA,CAAM,IAC/B,gBAAA,CAAiB,CAAC,EAAE,CAAC,CAAA,GAAI,MAAM,CAAA,GAC/B,gBAAA,CAAiB,CAAC,CAAA,CAAE,CAAC,IAAI,KAAA,CAAM,CAAA;AACjC,EAAA,MAAM,CAAA,GACJ,iBAAiB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,KAAA,CAAM,IAC/B,gBAAA,CAAiB,CAAC,EAAE,CAAC,CAAA,GAAI,MAAM,CAAA,GAC/B,gBAAA,CAAiB,CAAC,CAAA,CAAE,CAAC,IAAI,KAAA,CAAM,CAAA;AACjC,EAAA,MAAM,CAAA,GACJ,iBAAiB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,KAAA,CAAM,IAC/B,gBAAA,CAAiB,CAAC,EAAE,CAAC,CAAA,GAAI,MAAM,CAAA,GAC/B,gBAAA,CAAiB,CAAC,CAAA,CAAE,CAAC,IAAI,KAAA,CAAM,CAAA;AAGjC,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA;AACtB,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA;AACtB,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA;AAGtB,EAAA,OAAO;AAAA,IACL,GACE,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,IAAI,EAAA,GAC3B,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,EAAA,GAC3B,mBAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,EAAA;AAAA,IAC7B,GACE,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,IAAI,EAAA,GAC3B,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,EAAA,GAC3B,mBAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,EAAA;AAAA,IAC7B,GACE,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,IAAI,EAAA,GAC3B,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,EAAA,GAC3B,mBAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI;AAAA,GAC/B;AACF;AAGO,SAAS,gBAAgB,KAAA,EAA0B;AAExD,EAAA,MAAM,EAAA,GACJ,mBAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,KAAA,CAAM,IACjC,kBAAA,CAAmB,CAAC,EAAE,CAAC,CAAA,GAAI,MAAM,CAAA,GACjC,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,IAAI,KAAA,CAAM,CAAA;AACnC,EAAA,MAAM,EAAA,GACJ,mBAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,KAAA,CAAM,IACjC,kBAAA,CAAmB,CAAC,EAAE,CAAC,CAAA,GAAI,MAAM,CAAA,GACjC,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,IAAI,KAAA,CAAM,CAAA;AACnC,EAAA,MAAM,EAAA,GACJ,mBAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,KAAA,CAAM,IACjC,kBAAA,CAAmB,CAAC,EAAE,CAAC,CAAA,GAAI,MAAM,CAAA,GACjC,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,IAAI,KAAA,CAAM,CAAA;AAGnC,EAAA,MAAM,CAAA,GAAI,KAAK,EAAA,GAAK,EAAA;AACpB,EAAA,MAAM,CAAA,GAAI,KAAK,EAAA,GAAK,EAAA;AACpB,EAAA,MAAM,CAAA,GAAI,KAAK,EAAA,GAAK,EAAA;AAGpB,EAAA,OAAO;AAAA,IACL,GACE,gBAAA,CAAiB,CAAC,CAAA,CAAE,CAAC,IAAI,CAAA,GACzB,gBAAA,CAAiB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,GACzB,iBAAiB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA;AAAA,IAC3B,GACE,gBAAA,CAAiB,CAAC,CAAA,CAAE,CAAC,IAAI,CAAA,GACzB,gBAAA,CAAiB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,GACzB,iBAAiB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA;AAAA,IAC3B,GACE,gBAAA,CAAiB,CAAC,CAAA,CAAE,CAAC,IAAI,CAAA,GACzB,gBAAA,CAAiB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,GACzB,iBAAiB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI;AAAA,GAC7B;AACF;;;ACvEO,SAAS,oBAAoB,KAAA,EAAuB;AACzD,EAAA,OAAO,SAAS,oBAAA,GACZ,KAAA,GAAQ,gBAAA,GAAA,CAAA,CACN,KAAA,GAAQ,qBAAqB,gBAAA,KAAqB,mBAAA;AAC1D;AAGO,SAAS,oBAAoB,KAAA,EAAuB;AACzD,EAAA,OAAO,SAAS,2BAAA,GACZ,KAAA,GAAQ,mBACR,gBAAA,GAAmB,KAAA,KAAU,IAAI,mBAAA,CAAA,GAAuB,iBAAA;AAC9D;AAGO,SAAS,iBAAiB,KAAA,EAAyB;AACxD,EAAA,OAAO;AAAA,IACL,CAAA,EAAG,mBAAA,CAAoB,KAAA,CAAM,CAAC,CAAA;AAAA,IAC9B,CAAA,EAAG,mBAAA,CAAoB,KAAA,CAAM,CAAC,CAAA;AAAA,IAC9B,CAAA,EAAG,mBAAA,CAAoB,KAAA,CAAM,CAAC;AAAA,GAChC;AACF;AAGO,SAAS,iBAAiB,KAAA,EAAyB;AACxD,EAAA,OAAO;AAAA,IACL,CAAA,EAAG,mBAAA,CAAoB,KAAA,CAAM,CAAC,CAAA;AAAA,IAC9B,CAAA,EAAG,mBAAA,CAAoB,KAAA,CAAM,CAAC,CAAA;AAAA,IAC9B,CAAA,EAAG,mBAAA,CAAoB,KAAA,CAAM,CAAC;AAAA,GAChC;AACF;;;ACrCO,SAAS,UAAU,GAAA,EAAmB;AAC3C,EAAA,IAAI,CAAA,GAAI,IAAI,UAAA,CAAW,GAAG,IAAI,GAAA,CAAI,KAAA,CAAM,CAAC,CAAA,GAAI,GAAA;AAE7C,EAAA,IAAI,CAAA,CAAE,WAAW,CAAA,EAAG;AAClB,IAAA,CAAA,GAAI,EAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,IAAI,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,GAAI,EAAE,CAAC,CAAA;AAAA,EAC5C;AAEA,EAAA,MAAM,CAAA,GAAI,QAAA,CAAS,CAAA,EAAG,EAAE,CAAA;AACxB,EAAA,OAAO;AAAA,IACL,CAAA,EAAA,CAAK,CAAA,IAAK,EAAA,GAAM,GAAA,IAAQ,GAAA;AAAA,IACxB,CAAA,EAAA,CAAK,CAAA,IAAK,CAAA,GAAK,GAAA,IAAQ,GAAA;AAAA,IACvB,CAAA,EAAA,CAAI,IAAI,GAAA,IAAQ;AAAA,GAClB;AACF;AAGO,SAAS,UAAU,KAAA,EAAkB;AAC1C,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,CAAC,CAAC,IAAI,GAAG,CAAA;AAC5D,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,CAAC,CAAC,IAAI,GAAG,CAAA;AAC5D,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,CAAC,CAAC,IAAI,GAAG,CAAA;AAC5D,EAAA,OAAO,CAAA,CAAA,EAAA,CAAM,CAAA,IAAK,EAAA,GAAO,CAAA,IAAK,EAAA,GAAO,CAAA,IAAK,CAAA,GAAK,CAAA,EAAG,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AACzE;;;AChBO,SAAS,YAAY,KAAA,EAAoB;AAC9C,EAAA,OAAO,YAAA,CAAa,iBAAA,CAAkB,gBAAA,CAAiB,KAAK,CAAC,CAAC,CAAA;AAChE;AAGO,SAAS,YAAY,KAAA,EAAoB;AAC9C,EAAA,OAAO,gBAAA,CAAiB,iBAAA,CAAkB,YAAA,CAAa,KAAK,CAAC,CAAC,CAAA;AAChE;AAGO,SAAS,YAAY,KAAA,EAAoB;AAC9C,EAAA,OAAO,iBAAA,CAAkB,gBAAA,CAAiB,KAAK,CAAC,CAAA;AAClD;AAGO,SAAS,YAAY,KAAA,EAAoB;AAC9C,EAAA,OAAO,gBAAA,CAAiB,iBAAA,CAAkB,KAAK,CAAC,CAAA;AAClD;AAGO,SAAS,WAAW,GAAA,EAAoB;AAC7C,EAAA,OAAO,WAAA,CAAY,SAAA,CAAU,GAAG,CAAC,CAAA;AACnC;AAGO,SAAS,WAAW,KAAA,EAAmB;AAC5C,EAAA,MAAM,IAAA,GAAO,YAAY,KAAK,CAAA;AAC9B,EAAA,OAAO,SAAA,CAAU;AAAA,IACf,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,CAAC,CAAC,CAAA;AAAA,IAClC,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,CAAC,CAAC,CAAA;AAAA,IAClC,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,CAAC,CAAC;AAAA,GACnC,CAAA;AACH;AAGO,SAAS,UAAU,KAAA,EAAoB;AAC5C,EAAA,OAAO,YAAA,CAAa,eAAA,CAAgB,gBAAA,CAAiB,KAAK,CAAC,CAAC,CAAA;AAC9D;AAGO,SAAS,UAAU,KAAA,EAAoB;AAC5C,EAAA,OAAO,gBAAA,CAAiB,eAAA,CAAgB,YAAA,CAAa,KAAK,CAAC,CAAC,CAAA;AAC9D;AAGO,SAAS,aAAa,KAAA,EAAsB;AACjD,EAAA,MAAM,EAAA,GAAK,UAAU,KAAK,CAAA;AAC1B,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,EAAA,CAAG,CAAC,CAAC,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AAClD,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,EAAA,CAAG,CAAC,CAAC,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AAClD,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,EAAA,CAAG,CAAC,CAAC,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AAClD,EAAA,OAAO,CAAA,iBAAA,EAAoB,CAAC,CAAA,CAAA,EAAI,CAAC,IAAI,CAAC,CAAA,CAAA,CAAA;AACxC;;;ACvDO,SAAS,UAAU,KAAA,EAAsB;AAC9C,EAAA,OACE,KAAA,CAAM,KAAK,CAAC,aAAA,IACZ,MAAM,CAAA,IAAK,CAAA,GAAI,aAAA,IACf,KAAA,CAAM,CAAA,IAAK,CAAC,iBACZ,KAAA,CAAM,CAAA,IAAK,IAAI,aAAA,IACf,KAAA,CAAM,KAAK,CAAC,aAAA,IACZ,KAAA,CAAM,CAAA,IAAK,CAAA,GAAI,aAAA;AAEnB;AAGO,SAAS,UAAU,KAAA,EAAmB;AAC3C,EAAA,OAAO;AAAA,IACL,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,IACnC,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,IACnC,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,CAAC,CAAC;AAAA,GACrC;AACF;AAGO,IAAM,OAAA,GAAU;;;ACrBhB,SAAS,QAAA,CAAS,GAAU,CAAA,EAAkB;AACnD,EAAA,OAAO,YAAY,YAAA,CAAa,CAAC,CAAA,EAAG,YAAA,CAAa,CAAC,CAAC,CAAA;AACrD;AAGO,SAAS,WAAA,CAAY,GAAU,CAAA,EAAkB;AACtD,EAAA,MAAM,EAAA,GAAK,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA;AACnB,EAAA,MAAM,EAAA,GAAK,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA;AACnB,EAAA,MAAM,EAAA,GAAK,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA;AACnB,EAAA,OAAO,KAAK,IAAA,CAAK,EAAA,GAAK,KAAK,EAAA,GAAK,EAAA,GAAK,KAAK,EAAE,CAAA;AAC9C;;;ACMO,SAAS,QAAA,CAAS,KAAA,EAAc,KAAA,GAAe,MAAA,EAAe;AACnE,EAAA,MAAM,KAAA,GAAQ,KAAA,KAAU,YAAA,GAAe,SAAA,GAAY,WAAA;AACnD,EAAA,MAAM,UAAA,GACJ,KAAA,KAAU,YAAA,GACN,CAAC,MAAY,eAAA,CAAgB,gBAAA,CAAiB,CAAC,CAAC,IAChD,CAAC,CAAA,KAAY,iBAAA,CAAkB,gBAAA,CAAiB,CAAC,CAAC,CAAA;AAGxD,EAAA,MAAM,GAAA,GAAM,MAAM,KAAK,CAAA;AACvB,EAAA,IAAI,SAAA,CAAU,GAAG,CAAA,EAAG,OAAO,KAAA;AAG3B,EAAA,IAAI,KAAA,CAAM,CAAA,IAAK,aAAA,EAAe,OAAO,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,KAAA,CAAM,CAAA,EAAE;AAC9D,EAAA,IAAI,KAAA,CAAM,CAAA,IAAK,CAAA,GAAI,aAAA,EAAe,OAAO,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,KAAA,CAAM,CAAA,EAAE;AAElE,EAAA,IAAI,EAAA,GAAK,CAAA;AACT,EAAA,IAAI,KAAK,KAAA,CAAM,CAAA;AAEf,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,wBAAA,EAA0B,CAAA,EAAA,EAAK;AACjD,IAAA,MAAM,IAAA,GAAA,CAAQ,KAAK,EAAA,IAAM,CAAA;AACzB,IAAA,MAAM,SAAA,GAAmB,EAAE,CAAA,EAAG,KAAA,CAAM,GAAG,CAAA,EAAG,IAAA,EAAM,CAAA,EAAG,KAAA,CAAM,CAAA,EAAE;AAC3D,IAAA,MAAM,YAAA,GAAe,MAAM,SAAS,CAAA;AAEpC,IAAA,IAAI,SAAA,CAAU,YAAY,CAAA,EAAG;AAC3B,MAAA,EAAA,GAAK,IAAA;AAAA,IACP,CAAA,MAAO;AAEL,MAAA,MAAM,OAAA,GAAU,UAAU,YAAY,CAAA;AACtC,MAAA,MAAM,UAAA,GAAa,WAAW,OAAO,CAAA;AACrC,MAAA,MAAM,YAAA,GAAe,aAAa,SAAS,CAAA;AAC3C,MAAA,MAAM,EAAA,GAAK,WAAA,CAAY,UAAA,EAAY,YAAY,CAAA;AAE/C,MAAA,IAAI,KAAK,aAAA,EAAe;AAGtB,QAAA;AAAA,MACF;AAEA,MAAA,EAAA,GAAK,IAAA;AAAA,IACP;AAEA,IAAA,IAAI,EAAA,GAAK,KAAK,iBAAA,EAAmB;AAAA,EACnC;AAEA,EAAA,OAAO,EAAE,GAAG,KAAA,CAAM,CAAA,EAAG,GAAG,EAAA,EAAI,CAAA,EAAG,MAAM,CAAA,EAAE;AACzC;;;AClDO,SAAS,SAAA,CAAU,CAAA,EAAW,CAAA,EAAW,KAAA,GAAe,MAAA,EAAgB;AAC7E,EAAA,IAAI,CAAA,IAAK,CAAA,IAAK,CAAA,IAAK,CAAA,EAAG,OAAO,CAAA;AAE7B,EAAA,MAAM,KAAA,GAAQ,KAAA,KAAU,YAAA,GAAe,SAAA,GAAY,WAAA;AACnD,EAAA,IAAI,EAAA,GAAK,CAAA;AACT,EAAA,IAAI,EAAA,GAAK,KAAA,KAAU,YAAA,GAAe,GAAA,GAAM,GAAA;AAExC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,wBAAA,EAA0B,CAAA,EAAA,EAAK;AACjD,IAAA,MAAM,GAAA,GAAA,CAAO,KAAK,EAAA,IAAM,CAAA;AACxB,IAAA,MAAM,KAAA,GAAe,EAAE,CAAA,EAAG,CAAA,EAAG,KAAK,CAAA,EAAE;AACpC,IAAA,MAAM,GAAA,GAAM,MAAM,KAAK,CAAA;AAEvB,IAAA,IAAI,SAAA,CAAU,GAAG,CAAA,EAAG;AAClB,MAAA,EAAA,GAAK,GAAA;AAAA,IACP,CAAA,MAAO;AACL,MAAA,EAAA,GAAK,GAAA;AAAA,IACP;AAEA,IAAA,IAAI,EAAA,GAAK,KAAK,IAAA,EAAM;AAAA,EACtB;AAEA,EAAA,OAAO,EAAA;AACT;;;AChCO,SAAS,cAAc,KAAA,EAAqB;AACjD,EAAA,OACE,MAAA,GAAS,mBAAA,CAAoB,KAAA,CAAM,CAAC,CAAA,GACpC,MAAA,GAAS,mBAAA,CAAoB,KAAA,CAAM,CAAC,CAAA,GACpC,MAAA,GAAS,mBAAA,CAAoB,MAAM,CAAC,CAAA;AAExC;AAMO,SAAS,YAAA,CAAa,GAAS,CAAA,EAAiB;AACrD,EAAA,MAAM,EAAA,GAAK,cAAc,CAAC,CAAA;AAC1B,EAAA,MAAM,EAAA,GAAK,cAAc,CAAC,CAAA;AAC1B,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,EAAE,CAAA;AAC/B,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,EAAE,CAAA;AAC9B,EAAA,OAAA,CAAQ,OAAA,GAAU,SAAS,MAAA,GAAS,IAAA,CAAA;AACtC;AAMO,SAAS,gBAAgB,UAAA,EAAyC;AACvE,EAAA,MAAM,QAAc,EAAE,CAAA,EAAG,GAAG,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAE;AACvC,EAAA,MAAM,QAAc,EAAE,CAAA,EAAG,GAAG,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAE;AACvC,EAAA,OAAO,YAAA,CAAa,OAAO,UAAU,CAAA,GAAI,aAAa,KAAA,EAAO,UAAU,IACnE,SAAA,GACA,SAAA;AACN;;;ACAO,IAAM,WAAA,GAAc;AAQpB,SAAS,iBAAiB,EAAA,EAAoB;AACnD,EAAA,OAAO,IAAA,CAAK,IAAI,EAAA,EAAI,IAAA,CAAK,IAAI,CAAA,EAAG,EAAA,GAAK,WAAW,CAAC,CAAA;AACnD;AAKO,SAAS,iBAAiB,UAAA,EAA4B;AAC3D,EAAA,OAAO,UAAA,GAAa,WAAA;AACtB;AAEO,SAAS,YAAA,CAAa,WAAiB,OAAA,EAAuB;AAEnE,EAAA,IAAI,IAAA,GACF,WAAA,GAAc,SAAA,CAAU,CAAA,IAAK,aAAA,GAC7B,WAAA,GAAc,SAAA,CAAU,CAAA,IAAK,aAAA,GAC7B,WAAA,GAAc,SAAA,CAAU,CAAA,IAAK,aAAA;AAE/B,EAAA,IAAI,GAAA,GACF,WAAA,GAAc,OAAA,CAAQ,CAAA,IAAK,aAAA,GAC3B,WAAA,GAAc,OAAA,CAAQ,CAAA,IAAK,aAAA,GAC3B,WAAA,GAAc,OAAA,CAAQ,CAAA,IAAK,aAAA;AAG7B,EAAA,IAAI,OAAO,aAAA,EAAe;AACxB,IAAA,IAAA,IAAA,CAAS,gBAAgB,IAAA,KAAS,aAAA;AAAA,EACpC;AACA,EAAA,IAAI,MAAM,aAAA,EAAe;AACvB,IAAA,GAAA,IAAA,CAAQ,gBAAgB,GAAA,KAAQ,aAAA;AAAA,EAClC;AAGA,EAAA,IAAI,KAAK,GAAA,CAAI,GAAA,GAAM,IAAI,CAAA,GAAI,kBAAkB,OAAO,CAAA;AAGpD,EAAA,IAAI,IAAA;AAEJ,EAAA,IAAI,MAAM,IAAA,EAAM;AAEd,IAAA,IAAA,GAAA,CAAQ,GAAA,IAAO,YAAA,GAAe,IAAA,IAAQ,aAAA,IAAiB,cAAA;AACvD,IAAA,OAAO,IAAA,GAAO,YAAA,GAAe,CAAA,GAAA,CAAK,IAAA,GAAO,kBAAA,IAAsB,GAAA;AAAA,EACjE,CAAA,MAAO;AAEL,IAAA,IAAA,GAAA,CAAQ,GAAA,IAAO,WAAA,GAAc,IAAA,IAAQ,YAAA,IAAgB,cAAA;AACrD,IAAA,OAAO,IAAA,GAAO,CAAC,YAAA,GAAe,CAAA,GAAA,CAAK,OAAO,kBAAA,IAAsB,GAAA;AAAA,EAClE;AACF;;;AC/EO,SAAS,GAAA,CAAI,CAAA,EAAU,CAAA,EAAU,CAAA,EAAkB;AACxD,EAAA,MAAM,IAAI,CAAA,CAAE,CAAA,GAAA,CAAK,CAAA,CAAE,CAAA,GAAI,EAAE,CAAA,IAAK,CAAA;AAC9B,EAAA,MAAM,IAAI,CAAA,CAAE,CAAA,GAAA,CAAK,CAAA,CAAE,CAAA,GAAI,EAAE,CAAA,IAAK,CAAA;AAG9B,EAAA,MAAM,aAAA,GAAgB,EAAE,CAAA,GAAI,oBAAA;AAC5B,EAAA,MAAM,aAAA,GAAgB,EAAE,CAAA,GAAI,oBAAA;AAE5B,EAAA,IAAI,iBAAiB,aAAA,EAAe;AAClC,IAAA,OAAO,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAE;AAAA,EACtB;AAEA,EAAA,MAAM,EAAA,GAAK,aAAA,GAAgB,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA;AACnC,EAAA,MAAM,EAAA,GAAK,aAAA,GAAgB,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA;AAGnC,EAAA,IAAI,QAAQ,EAAA,GAAK,EAAA;AACjB,EAAA,IAAI,KAAA,GAAQ,KAAK,KAAA,IAAS,GAAA;AAC1B,EAAA,IAAI,KAAA,GAAQ,MAAM,KAAA,IAAS,GAAA;AAE3B,EAAA,IAAI,CAAA,GAAI,KAAK,KAAA,GAAQ,CAAA;AACrB,EAAA,IAAI,CAAA,GAAI,GAAG,CAAA,IAAK,GAAA;AAChB,EAAA,IAAI,CAAA,IAAK,KAAK,CAAA,IAAK,GAAA;AAEnB,EAAA,OAAO,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAE;AACnB;;;ACrBO,IAAM,mBAAA,GAAsB;AAO5B,IAAM,WAAA,GAAc;AAQpB,IAAM,iBAAA,GAAoB;AAM1B,IAAM,cAAA,GAAiB;AAMvB,IAAM,aAAA,GAAgB;AAMtB,IAAM,gBAAA,GAAmB;AASzB,IAAM,gBAAgB,CAAA,GAAI;AAG1B,IAAM,kBAAA,GAAqB;AAS3B,IAAM,oBAAA,GAAuB;AAM7B,IAAM,cAAc,CAAA,GAAI;AAGxB,IAAM,gBAAA,GAAmB;AASzB,IAAM,cAAA,GAAiB;;;ACrCvB,SAAS,SACd,OAAA,EACA,CAAA,EACA,OACA,KAAA,GAAgB,aAAA,EAChB,eAAuB,kBAAA,EACf;AACR,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,YAAA,EAAc,KAAA,CAAM,KAAA,EAAO,MAAA,IAAU,CAAC,CAAC,CAAA;AACvE,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,YAAA,EAAc,KAAA,CAAM,IAAA,EAAM,MAAA,IAAU,CAAC,CAAC,CAAA;AAGtE,EAAA,IAAI,EAAA,KAAO,CAAA,IAAK,EAAA,KAAO,CAAA,EAAG,OAAO,OAAA;AAGjC,EAAA,MAAM,cAAA,GACJ,CAAA,IAAK,KAAA,GAAQ,GAAA,IAAO,CAAA,GAAI,IAAA,CAAK,GAAA,CAAK,IAAA,CAAK,EAAA,GAAK,CAAA,GAAK,KAAK,CAAA,CAAA,GAAK,CAAA;AAG7D,EAAA,MAAM,aAAA,GACJ,CAAA,IAAK,CAAA,GAAI,KAAA,GACL,GAAA,IAAO,CAAA,GAAI,IAAA,CAAK,GAAA,CAAK,IAAA,CAAK,EAAA,IAAM,CAAA,GAAI,CAAA,CAAA,GAAM,KAAK,CAAA,CAAA,GAC/C,CAAA;AAGN,EAAA,MAAMA,MAAAA,GAAQ,KAAK,EAAA,GAAK,GAAA;AACxB,EAAA,MAAM,UAAU,OAAA,GAAUA,MAAAA;AAC1B,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA;AAC3B,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA;AAG3B,EAAA,IAAI,EAAA,GAAK,CAAA;AACT,EAAA,IAAI,EAAA,GAAK,CAAA;AAET,EAAA,IAAI,cAAA,GAAiB,CAAA,IAAK,EAAA,GAAK,CAAA,EAAG;AAChC,IAAA,MAAM,QAAQ,cAAA,GAAiB,EAAA;AAC/B,IAAA,MAAM,IAAA,GAAQ,KAAA,CAAM,KAAA,CAAO,GAAA,GAAOA,MAAAA;AAClC,IAAA,EAAA,IAAM,KAAA,IAAS,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,GAAI,EAAA,CAAA;AAChC,IAAA,EAAA,IAAM,KAAA,IAAS,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,GAAI,EAAA,CAAA;AAAA,EAClC;AAEA,EAAA,IAAI,aAAA,GAAgB,CAAA,IAAK,EAAA,GAAK,CAAA,EAAG;AAC/B,IAAA,MAAM,QAAQ,aAAA,GAAgB,EAAA;AAC9B,IAAA,MAAM,IAAA,GAAQ,KAAA,CAAM,IAAA,CAAM,GAAA,GAAOA,MAAAA;AACjC,IAAA,EAAA,IAAM,KAAA,IAAS,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,GAAI,EAAA,CAAA;AAChC,IAAA,EAAA,IAAM,KAAA,IAAS,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,GAAI,EAAA,CAAA;AAAA,EAClC;AAGA,EAAA,MAAM,KAAK,EAAA,GAAK,EAAA;AAChB,EAAA,MAAM,KAAK,EAAA,GAAK,EAAA;AAGhB,EAAA,IAAI,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,OAAO,OAAO,OAAA;AAEtC,EAAA,OAAA,CAAS,KAAK,KAAA,CAAM,EAAA,EAAI,EAAE,CAAA,GAAIA,SAAS,GAAA,IAAO,GAAA;AAChD;AAYO,SAAS,gBAAA,CAAiB,GAAW,OAAA,EAA0B;AACpE,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,kBAAA,EAAoB,OAAA,CAAQ,KAAA,EAAO,MAAA,IAAU,CAAC,CAAC,CAAA;AAC/E,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,kBAAA,EAAoB,OAAA,CAAQ,IAAA,EAAM,MAAA,IAAU,CAAC,CAAC,CAAA;AAE9E,EAAA,IAAI,EAAA,KAAO,CAAA,IAAK,EAAA,KAAO,CAAA,EAAG,OAAO,CAAA;AAEjC,EAAA,MAAM,cAAA,GACJ,CAAA,IAAK,aAAA,GAAgB,GAAA,IAAO,CAAA,GAAI,IAAA,CAAK,GAAA,CAAK,IAAA,CAAK,EAAA,GAAK,CAAA,GAAK,aAAa,CAAA,CAAA,GAAK,CAAA;AAE7E,EAAA,MAAM,aAAA,GACJ,CAAA,IAAK,CAAA,GAAI,aAAA,GACL,GAAA,IAAO,CAAA,GAAI,IAAA,CAAK,GAAA,CAAK,IAAA,CAAK,EAAA,IAAM,CAAA,GAAI,CAAA,CAAA,GAAM,aAAa,CAAA,CAAA,GACvD,CAAA;AAEN,EAAA,MAAM,UAAA,GAAa,kBAAkB,EAAA,GAAK,kBAAA,CAAA;AAC1C,EAAA,MAAM,SAAA,GAAY,iBAAiB,EAAA,GAAK,kBAAA,CAAA;AAExC,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,UAAA,EAAY,SAAS,CAAA;AACvC;AAgBO,SAAS,gBAAA,CACd,OAAA,EACA,CAAA,EACA,WAAA,EACA,UAAA,EACQ;AACR,EAAA,IAAI,CAAA,GAAI,OAAA;AACR,EAAA,IAAI,YAAY,CAAA,GAAI,QAAA,CAAS,GAAG,CAAA,EAAG,UAAA,EAAY,aAAa,gBAAgB,CAAA;AAC5E,EAAA,IAAI,WAAA,EAAa,CAAA,GAAI,QAAA,CAAS,CAAA,EAAG,GAAG,WAAW,CAAA;AAC/C,EAAA,OAAO,CAAA;AACT;AAaO,SAAS,kBAAA,CACd,GAAA,EACA,MAAA,EACA,KAAA,GAAiB,KAAA,EACR;AACT,EAAA,OAAO,KAAA,GACH,EAAE,KAAA,EAAO,EAAE,GAAA,EAAK,MAAA,EAAO,EAAE,GACzB,EAAE,IAAA,EAAM,EAAE,GAAA,EAAK,QAAO,EAAE;AAC9B;;;ACpKA,IAAM,KAAA,GAAQ,KAAK,EAAA,GAAK,GAAA;AAUxB,SAAS,oBACP,CAAA,EAAW,CAAA,EAAW,CAAA,EAAW,CAAA,EACjC,SAAkB,KAAA,EACQ;AAC1B,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,kBAAA,EAAoB,OAAA,CAAQ,KAAA,EAAO,MAAA,IAAU,CAAC,CAAC,CAAA;AAC/E,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,kBAAA,EAAoB,OAAA,CAAQ,IAAA,EAAM,MAAA,IAAU,CAAC,CAAC,CAAA;AAC9E,EAAA,IAAI,OAAO,CAAA,IAAK,EAAA,KAAO,GAAG,OAAO,EAAE,GAAG,CAAA,EAAE;AAGxC,EAAA,MAAM,SAAA,GAAY,CAAA,IAAK,aAAA,GACnB,GAAA,IAAO,CAAA,GAAI,IAAA,CAAK,GAAA,CAAK,IAAA,CAAK,EAAA,GAAK,CAAA,GAAK,aAAa,CAAA,CAAA,GAAK,CAAA;AAC1D,EAAA,MAAM,QAAA,GAAW,CAAA,IAAK,CAAA,GAAI,aAAA,GACtB,GAAA,IAAO,CAAA,GAAI,IAAA,CAAK,GAAA,CAAK,IAAA,CAAK,EAAA,IAAM,CAAA,GAAI,CAAA,CAAA,GAAM,aAAa,CAAA,CAAA,GAAK,CAAA;AAEhE,EAAA,MAAM,UAAA,GAAa,aAAa,EAAA,GAAK,kBAAA,CAAA;AACrC,EAAA,MAAM,SAAA,GAAY,YAAY,EAAA,GAAK,kBAAA,CAAA;AACnC,EAAA,IAAI,eAAe,CAAA,IAAK,SAAA,KAAc,GAAG,OAAO,EAAE,GAAG,CAAA,EAAE;AAGvD,EAAA,MAAM,OAAO,CAAA,GAAI,KAAA;AACjB,EAAA,IAAI,CAAA,GAAI,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA;AACzB,EAAA,IAAI,CAAA,GAAI,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA;AAGzB,EAAA,IAAI,aAAa,CAAA,EAAG;AAClB,IAAA,MAAM,EAAA,GAAK,QAAQ,KAAA,CAAO,GAAA;AAC1B,IAAA,MAAM,OAAO,EAAA,GAAK,KAAA;AAClB,IAAA,MAAM,KAAK,SAAA,CAAU,CAAA,EAAG,EAAA,EAAI,KAAK,IAAI,oBAAA,GAAuB,UAAA;AAC5D,IAAA,CAAA,IAAK,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA;AACvB,IAAA,CAAA,IAAK,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA;AAAA,EACzB;AACA,EAAA,IAAI,YAAY,CAAA,EAAG;AACjB,IAAA,MAAM,EAAA,GAAK,QAAQ,IAAA,CAAM,GAAA;AACzB,IAAA,MAAM,OAAO,EAAA,GAAK,KAAA;AAClB,IAAA,MAAM,KAAK,SAAA,CAAU,CAAA,EAAG,EAAA,EAAI,KAAK,IAAI,oBAAA,GAAuB,SAAA;AAC5D,IAAA,CAAA,IAAK,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA;AACvB,IAAA,CAAA,IAAK,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA;AAAA,EACzB;AAGA,EAAA,IAAI,OAAO,IAAA,CAAK,IAAA,CAAK,CAAA,GAAI,CAAA,GAAI,IAAI,CAAC,CAAA;AAClC,EAAA,IAAI,QAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAA,GAAI,QAAS,GAAA,IAAO,GAAA;AAGhD,EAAA,IAAA,GAAO,KAAK,GAAA,CAAI,IAAA,EAAM,UAAU,CAAA,EAAG,IAAA,EAAM,KAAK,CAAC,CAAA;AAE/C,EAAA,OAAO,EAAE,CAAA,EAAG,IAAA,EAAM,CAAA,EAAG,IAAA,EAAK;AAC5B;AA0DO,SAAS,aAAA,CAAc,OAAA,GAAwB,EAAC,EAAY;AACjE,EAAA,MAAM;AAAA,IACJ,QAAA;AAAA,IACA,GAAA,GAAM,WAAA;AAAA,IACN,MAAA;AAAA,IACA,IAAA,GAAO,KAAA;AAAA,IACP,OAAA;AAAA,IACA;AAAA,GACF,GAAI,OAAA;AACJ,EAAA,MAAM,KAAA,GAAQ,OAAO,YAAA,GAAe,MAAA;AAEpC,EAAA,MAAM,KAAA,GAAQ,mBAAA;AACd,EAAA,MAAM,WAAA,GAAc,QAAQ,MAAA,IAAU,CAAA;AACtC,EAAA,MAAM,UAAA,GAAa,QAAQ,OAAA,IAAW,GAAA;AACtC,EAAA,MAAM,QAAA,GAAW,OAAA;AACjB,EAAA,MAAM,aAAA,GAAgB,QAAQ,kBAAA,CAAmB,KAAA,CAAM,KAAK,KAAA,CAAM,MAAA,EAAQ,KAAA,CAAM,KAAK,CAAA,GAAI,MAAA;AAEzF,EAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,WAAW,CAAC,CAAA;AAClD,EAAA,MAAM,IAAA,GAAO,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,UAAU,CAAC,CAAA;AAIhD,EAAA,MAAM,QAAA,GAAW,OAAO,iBAAA,GAAoB,CAAA;AAC5C,EAAA,MAAM,OAAA,GAAU,OAAO,gBAAA,GAAmB,CAAA;AAC1C,EAAA,MAAM,WAAA,GAAc,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAG,QAAA,EAAU,KAAA,IAAS,CAAC,CAAC,CAAA;AACjE,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAG,QAAA,EAAU,IAAA,IAAQ,CAAC,CAAC,CAAA;AAC/D,EAAA,MAAM,SAAA,GAAY,cAAA,GAAiB,WAAA,IAAe,QAAA,GAAW,cAAA,CAAA;AAC7D,EAAA,MAAM,QAAA,GAAW,aAAA,GAAgB,UAAA,IAAc,aAAA,GAAgB,OAAA,CAAA;AAG/D,EAAA,MAAM,QAAQ,CAAC,CAAA,KAAc,iBAAiB,GAAA,EAAK,CAAA,EAAG,UAAU,aAAa,CAAA;AAM7E,EAAA,IAAI,IAAA,KAAS,GAAA,IAAO,KAAA,KAAU,CAAA,IAAK,SAAS,CAAA,EAAG;AAC7C,IAAA,MAAMC,SAAiB,EAAC;AACxB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,EAAO,CAAA,EAAA,EAAK;AAC9B,MAAA,MAAM,CAAA,GAAI,KAAK,KAAA,GAAQ,CAAA,CAAA;AACvB,MAAA,MAAM,CAAA,GAAI,SAAA,GAAY,CAAA,IAAK,SAAA,GAAY,QAAA,CAAA;AACvC,MAAA,IAAI,CAAA,GAAI,MAAM,CAAC,CAAA;AAKf,MAAA,IAAI,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,SAAA,CAAU,CAAA,EAAG,GAAA,EAAK,KAAK,CAAA,GAAI,KAAA,EAAO,SAAA,CAAU,CAAA,EAAG,CAAA,EAAG,KAAK,CAAC,CAAA;AAEzE,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,MAAM,UAAU,mBAAA,CAAoB,CAAA,EAAG,GAAG,CAAA,EAAG,CAAA,EAAG,UAAU,KAAK,CAAA;AAC/D,QAAA,CAAA,GAAI,OAAA,CAAQ,CAAA;AACZ,QAAA,CAAA,GAAI,OAAA,CAAQ,CAAA;AAAA,MACd;AAEA,MAAAA,OAAM,IAAA,CAAK,EAAE,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA;AAAA,IACxB;AACA,IAAA,OAAOA,MAAAA;AAAA,EACT;AAOA,EAAA,MAAM,CAAA,GAAI,GAAA;AACV,EAAA,IAAI,KAAA,GAAQ,GAAA;AACZ,EAAA,IAAI,aAAA,GAAgB,CAAA;AACpB,EAAA,MAAM,kBAA8C,EAAC;AAErD,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,CAAA,EAAG,CAAA,EAAA,EAAK;AAC3B,IAAA,MAAM,IAAI,CAAA,GAAI,CAAA;AACd,IAAA,MAAM,CAAA,GAAI,SAAA,GAAY,CAAA,IAAK,SAAA,GAAY,QAAA,CAAA;AAKvC,IAAA,MAAM,CAAA,GAAI,SAAA,CAAU,CAAA,EAAG,GAAA,EAAK,KAAK,CAAA;AACjC,IAAA,eAAA,CAAgB,IAAA,CAAK,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA;AAC7B,IAAA,IAAI,IAAI,aAAA,EAAe;AACrB,MAAA,aAAA,GAAgB,CAAA;AAChB,MAAA,KAAA,GAAQ,CAAA;AAAA,IACV;AAAA,EACF;AAGA,EAAA,MAAM,aAAa,aAAA,GAAgB,KAAA;AACnC,EAAA,IAAI,SAAA,GAAY,KAAA;AAChB,EAAA,IAAI,SAAA,GAAY,KAAA;AAEhB,EAAA,KAAA,MAAW,EAAE,CAAA,EAAG,CAAA,EAAE,IAAK,eAAA,EAAiB;AACtC,IAAA,IAAI,CAAA,IAAK,aAAa,IAAA,EAAM;AAC1B,MAAA,IAAI,CAAA,GAAI,WAAW,SAAA,GAAY,CAAA;AAC/B,MAAA,IAAI,CAAA,GAAI,WAAW,SAAA,GAAY,CAAA;AAAA,IACjC;AAAA,EACF;AAGA,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,QAAQ,GAAA,EAAK;AACf,IAAA,OAAA,GAAU,SAAA,GAAa,IAAA,GAAO,GAAA,IAAQ,KAAA,GAAQ,SAAA,CAAA;AAAA,EAChD,CAAA,MAAO;AACL,IAAA,OAAA,GAAU,KAAA,GAAA,CAAU,IAAA,GAAO,GAAA,IAAO,GAAA,IAAQ,SAAA,GAAY,KAAA,CAAA;AAAA,EACxD;AAKA,EAAA,IAAI,OAAA,IAAW,CAAA,IAAK,OAAA,IAAW,CAAA,EAAG;AAChC,IAAA,OAAA,GAAU,KAAA;AAAA,EACZ;AAGA,EAAA,MAAM,QAAiB,EAAC;AACxB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,EAAO,CAAA,EAAA,EAAK;AAC9B,IAAA,MAAM,CAAA,GAAI,KAAK,KAAA,GAAQ,CAAA,CAAA;AACvB,IAAA,MAAM,CAAA,GAAI,SAAA,GAAY,CAAA,IAAK,SAAA,GAAY,QAAA,CAAA;AACvC,IAAA,IAAI,CAAA,GAAI,MAAM,CAAC,CAAA;AAKf,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI,KAAK,OAAA,EAAS;AAChB,MAAA,OAAA,GAAU,KAAK,KAAA,GAAQ,OAAA,CAAA;AAAA,IACzB,CAAA,MAAO;AACL,MAAA,OAAA,GAAU,KAAA,GAAA,CAAS,CAAA,GAAI,OAAA,KAAA,CAAa,CAAA,GAAI,UAAU,CAAA,GAAI,OAAA,CAAA,CAAA;AAAA,IACxD;AAEA,IAAA,MAAM,OAAA,GAAU,SAAA,GAAY,OAAA,IAAW,SAAA,GAAY,QAAA,CAAA;AAInD,IAAA,MAAM,OAAA,GAAU,SAAA,CAAU,OAAA,EAAS,GAAA,EAAK,KAAK,CAAA,GAAI,KAAA;AAGjD,IAAA,MAAM,SAAA,GAAY,SAAA,CAAU,CAAA,EAAG,CAAA,EAAG,KAAK,CAAA;AACvC,IAAA,IAAI,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,SAAS,CAAA;AAEnC,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,MAAM,UAAU,mBAAA,CAAoB,CAAA,EAAG,GAAG,CAAA,EAAG,CAAA,EAAG,UAAU,KAAK,CAAA;AAC/D,MAAA,CAAA,GAAI,OAAA,CAAQ,CAAA;AACZ,MAAA,CAAA,GAAI,OAAA,CAAQ,CAAA;AAAA,IACd;AAEA,IAAA,KAAA,CAAM,IAAA,CAAK,EAAE,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA;AAAA,EACxB;AAEA,EAAA,OAAO,KAAA;AACT;;;AC5OO,SAAS,YAAA,CACd,KAAA,EACA,IAAA,GAAgB,KAAA,EACD;AACf,EAAA,MAAM,KAAA,GAAe,OAAO,YAAA,GAAe,MAAA;AAC3C,EAAA,MAAM,KAAA,GAAQ,OAAO,KAAA,KAAU,QAAA;AAC/B,EAAA,MAAM,QAAA,GAAkB,KAAA,GAAQ,UAAA,CAAW,KAAK,CAAA,GAAI,KAAA;AAKpD,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,OAAA,GAAU,IAAA;AAAA,EACZ,CAAA,MAAO;AACL,IAAA,MAAM,MACJ,KAAA,KAAU,YAAA,GAAe,UAAU,QAAQ,CAAA,GAAI,YAAY,QAAQ,CAAA;AACrE,IAAA,OAAA,GAAU,UAAU,GAAG,CAAA;AAAA,EACzB;AAEA,EAAA,MAAM,KAAA,GAAQ,OAAA,GAAU,QAAA,GAAW,QAAA,CAAS,UAAU,KAAK,CAAA;AAE3D,EAAA,MAAM,WAAW,SAAA,CAAU,KAAA,CAAM,CAAA,EAAG,KAAA,CAAM,GAAG,KAAK,CAAA;AAClD,EAAA,MAAM,WAAA,GAAc,QAAA,GAAW,CAAA,GAAI,KAAA,CAAM,IAAI,QAAA,GAAW,CAAA;AAExD,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,GAAA,EAAK,WAAW,KAAK,CAAA;AAAA,IACrB,aAAa,CAAC,OAAA;AAAA,IACd,QAAA;AAAA,IACA,WAAA,EAAa,QAAA,CAAS,CAAA,GAAI,KAAA,CAAM,CAAA;AAAA,IAChC,KAAK,KAAA,CAAM,CAAA;AAAA,IACX,WAAA,EAAa,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,WAAW;AAAA,GACtC;AACF;;;ACnEO,SAAS,gBAAgB,MAAA,EAAwB;AACtD,EAAA,MAAM,CAAA,GAAI,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,MAAM,CAAC,CAAA;AACzC,EAAA,OAAO,cAAA,GAAiB,KAAK,CAAA,GAAM,cAAA,CAAA;AACrC;AAMO,SAAS,eAAe,MAAA,EAAwB;AACrD,EAAA,MAAM,CAAA,GAAI,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,MAAM,CAAC,CAAA;AACzC,EAAA,OAAO,iBAAiB,CAAA,GAAI,CAAA,CAAA;AAC9B;AASO,SAAS,iBAAA,CAAkB,CAAA,EAAW,SAAA,EAAmB,QAAA,EAA0B;AACxF,EAAA,MAAM,QAAQ,SAAA,GAAY,QAAA;AAC1B,EAAA,IAAI,KAAA,IAAS,GAAG,OAAO,GAAA;AACvB,EAAA,OAAO,IAAA,CAAK,IAAI,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAA,CAAI,SAAA,GAAY,CAAA,IAAK,KAAK,CAAC,CAAA;AACzD;;;ACcO,SAAS,QAAA,CACd,OACA,OAAA,EAKgB;AAChB,EAAA,MAAM,EAAE,OAAO,KAAA,EAAO,QAAA,EAAU,QAAQ,mBAAA,EAAoB,GAAI,WAAW,EAAC;AAC5E,EAAA,MAAM,QAAA,GAAW,YAAA,CAAa,KAAA,EAAO,IAAI,CAAA;AACzC,EAAA,MAAM,SAAA,GAAY,eAAA,CAAgB,QAAA,EAAU,KAAA,IAAS,CAAC,CAAA;AACtD,EAAA,MAAM,QAAA,GAAW,cAAA,CAAe,QAAA,EAAU,IAAA,IAAQ,CAAC,CAAA;AACnD,EAAA,MAAM,UAAU,iBAAA,CAAkB,QAAA,CAAS,KAAA,CAAM,CAAA,EAAG,WAAW,QAAQ,CAAA;AACvE,EAAA,MAAM,SAAA,GAAY,KAAK,KAAA,CAAM,OAAA,GAAU,KAAK,GAAA,CAAI,CAAA,EAAG,KAAA,GAAQ,CAAC,CAAC,CAAA;AAE7D,EAAA,OAAO;AAAA,IACL,KAAK,QAAA,CAAS,GAAA;AAAA,IACd,MAAA,EAAQ,EAAE,MAAA,EAAQ,QAAA,CAAS,aAAa,OAAA,EAAQ;AAAA,IAChD,SAAA;AAAA,IACA,KAAK,QAAA,CAAS,GAAA;AAAA,IACd,OAAO,QAAA,CAAS,KAAA;AAAA,IAChB,aAAa,QAAA,CAAS,WAAA;AAAA,IACtB,UAAU,QAAA,CAAS;AAAA,GACrB;AACF","file":"index.js","sourcesContent":["// ── sRGB Gamma Transfer (IEC 61966-2-1) ──\n\nexport const SRGB_GAMMA_THRESHOLD = 0.04045;\nexport const SRGB_GAMMA_THRESHOLD_LINEAR = 0.0031308;\nexport const SRGB_GAMMA_SLOPE = 12.92;\nexport const SRGB_GAMMA_EXPONENT = 2.4;\nexport const SRGB_GAMMA_OFFSET = 0.055;\nexport const SRGB_GAMMA_SCALE = 1.055;\n\n// ── Ottosson M1: Linear sRGB → LMS ──\n\nexport const LINEAR_SRGB_TO_LMS = [\n [0.4122214708, 0.5363325363, 0.0514459929],\n [0.2119034982, 0.6806995451, 0.1073969566],\n [0.0883024619, 0.2817188376, 0.6299787005],\n] as const;\n\n// ── Ottosson M2: LMS′ (cube-root) → OKLAB ──\n\nexport const LMS_PRIME_TO_OKLAB = [\n [+0.2104542553, +0.7936177850, -0.0040720468],\n [+1.9779984951, -2.4285922050, +0.4505937099],\n [+0.0259040371, +0.7827717662, -0.8086757660],\n] as const;\n\n// ── Inverse M2: OKLAB → LMS′ ──\n\nexport const OKLAB_TO_LMS_PRIME = [\n [1.0000000000, +0.3963377774, +0.2158037573],\n [1.0000000000, -0.1055613458, -0.0638541728],\n [1.0000000000, -0.0894841775, -1.2914855480],\n] as const;\n\n// ── Inverse M1: LMS → Linear sRGB ──\n\nexport const LMS_TO_LINEAR_SRGB = [\n [+4.0767416621, -3.3077115913, +0.2309699292],\n [-1.2684380046, +2.6097574011, -0.3413193965],\n [-0.0041960863, -0.7034186147, +1.7076147010],\n] as const;\n\n// ── Display P3 M1: Linear Display P3 → LMS ──\n// Derived: XYZ_to_LMS × P3_to_XYZ, where XYZ_to_LMS = M1_srgb × inv(sRGB_to_XYZ)\n\nexport const LINEAR_P3_TO_LMS = [\n [+0.4813791595, +0.4621155872, +0.0565406381],\n [+0.2288319169, +0.6532167007, +0.1179528072],\n [+0.0839457149, +0.2241651052, +0.6918912614],\n] as const;\n\n// ── Inverse P3 M1: LMS → Linear Display P3 ──\n\nexport const LMS_TO_LINEAR_P3 = [\n [+3.1277694390, -2.2570600176, +0.1291828502],\n [-1.0910091977, +2.4133065499, -0.3222615148],\n [-0.0260108068, -0.5080402362, +1.5340494942],\n] as const;\n\n// ── Gamut Mapping ──\n\nexport const GAMUT_EPSILON = 1e-6;\nexport const GAMUT_MAP_JND = 0.02;\nexport const GAMUT_MAP_EPSILON = 1e-4;\nexport const GAMUT_MAP_MAX_ITERATIONS = 50;\n\n// ── Achromatic Threshold ──\n\nexport const ACHROMATIC_THRESHOLD = 1e-10;\n\n// ── WCAG 2.x Luminance Coefficients ──\n\nexport const WCAG_R = 0.2126;\nexport const WCAG_G = 0.7152;\nexport const WCAG_B = 0.0722;\n\n// ── APCA-W3 (SA98G) Constants ──\n\nexport const APCA_MAIN_TRC = 2.4;\nexport const APCA_SRGB_R = 0.2126729;\nexport const APCA_SRGB_G = 0.7151522;\nexport const APCA_SRGB_B = 0.0721750;\nexport const APCA_NORM_BG = 0.56;\nexport const APCA_NORM_TXT = 0.57;\nexport const APCA_REV_TXT = 0.62;\nexport const APCA_REV_BG = 0.65;\nexport const APCA_BLK_THRS = 0.022;\nexport const APCA_BLK_CLMP = 1.414;\nexport const APCA_SCALE_BOW = 1.14;\nexport const APCA_SCALE_WOB = 1.14;\nexport const APCA_LO_BOW_OFFSET = 0.027;\nexport const APCA_LO_WOB_OFFSET = 0.027;\nexport const APCA_DELTA_Y_MIN = 0.0005;\nexport const APCA_LO_CLIP = 0.1;\n\n// ── Angle Math ──\n\nexport const DEG_TO_RAD = Math.PI / 180;\nexport const RAD_TO_DEG = 180 / Math.PI;\n","import type { Oklab, Oklch } from \"../types.js\";\nimport { ACHROMATIC_THRESHOLD, DEG_TO_RAD, RAD_TO_DEG } from \"../constants.js\";\n\n/** Convert OKLAB (cartesian) to OKLCH (cylindrical). Achromatic colors get h=0. */\nexport function oklabToOklch(lab: Oklab): Oklch {\n const C = Math.sqrt(lab.a * lab.a + lab.b * lab.b);\n\n if (C < ACHROMATIC_THRESHOLD) {\n return { L: lab.L, C: 0, h: 0 };\n }\n\n let h = Math.atan2(lab.b, lab.a) * RAD_TO_DEG;\n if (h < 0) h += 360;\n\n return { L: lab.L, C, h };\n}\n\n/** Convert OKLCH (cylindrical) to OKLAB (cartesian). */\nexport function oklchToOklab(lch: Oklch): Oklab {\n const hRad = lch.h * DEG_TO_RAD;\n return {\n L: lch.L,\n a: lch.C * Math.cos(hRad),\n b: lch.C * Math.sin(hRad),\n };\n}\n","import type { LinearSrgb, Oklab } from \"../types.js\";\nimport {\n LINEAR_SRGB_TO_LMS,\n LMS_PRIME_TO_OKLAB,\n LMS_TO_LINEAR_SRGB,\n OKLAB_TO_LMS_PRIME,\n} from \"../constants.js\";\n\n/** Convert Linear sRGB to OKLAB via Ottosson's direct M1/M2 matrices. */\nexport function linearSrgbToOklab(color: LinearSrgb): Oklab {\n // Step 1: Linear sRGB → LMS\n const l =\n LINEAR_SRGB_TO_LMS[0][0] * color.r +\n LINEAR_SRGB_TO_LMS[0][1] * color.g +\n LINEAR_SRGB_TO_LMS[0][2] * color.b;\n const m =\n LINEAR_SRGB_TO_LMS[1][0] * color.r +\n LINEAR_SRGB_TO_LMS[1][1] * color.g +\n LINEAR_SRGB_TO_LMS[1][2] * color.b;\n const s =\n LINEAR_SRGB_TO_LMS[2][0] * color.r +\n LINEAR_SRGB_TO_LMS[2][1] * color.g +\n LINEAR_SRGB_TO_LMS[2][2] * color.b;\n\n // Step 2: Cube root\n const lp = Math.cbrt(l);\n const mp = Math.cbrt(m);\n const sp = Math.cbrt(s);\n\n // Step 3: LMS′ → OKLAB\n return {\n L:\n LMS_PRIME_TO_OKLAB[0][0] * lp +\n LMS_PRIME_TO_OKLAB[0][1] * mp +\n LMS_PRIME_TO_OKLAB[0][2] * sp,\n a:\n LMS_PRIME_TO_OKLAB[1][0] * lp +\n LMS_PRIME_TO_OKLAB[1][1] * mp +\n LMS_PRIME_TO_OKLAB[1][2] * sp,\n b:\n LMS_PRIME_TO_OKLAB[2][0] * lp +\n LMS_PRIME_TO_OKLAB[2][1] * mp +\n LMS_PRIME_TO_OKLAB[2][2] * sp,\n };\n}\n\n/** Convert OKLAB to Linear sRGB via inverse M2/M1 matrices. */\nexport function oklabToLinearSrgb(color: Oklab): LinearSrgb {\n // Step 1: OKLAB → LMS′\n const lp =\n OKLAB_TO_LMS_PRIME[0][0] * color.L +\n OKLAB_TO_LMS_PRIME[0][1] * color.a +\n OKLAB_TO_LMS_PRIME[0][2] * color.b;\n const mp =\n OKLAB_TO_LMS_PRIME[1][0] * color.L +\n OKLAB_TO_LMS_PRIME[1][1] * color.a +\n OKLAB_TO_LMS_PRIME[1][2] * color.b;\n const sp =\n OKLAB_TO_LMS_PRIME[2][0] * color.L +\n OKLAB_TO_LMS_PRIME[2][1] * color.a +\n OKLAB_TO_LMS_PRIME[2][2] * color.b;\n\n // Step 2: Cube\n const l = lp * lp * lp;\n const m = mp * mp * mp;\n const s = sp * sp * sp;\n\n // Step 3: LMS → Linear sRGB\n return {\n r:\n LMS_TO_LINEAR_SRGB[0][0] * l +\n LMS_TO_LINEAR_SRGB[0][1] * m +\n LMS_TO_LINEAR_SRGB[0][2] * s,\n g:\n LMS_TO_LINEAR_SRGB[1][0] * l +\n LMS_TO_LINEAR_SRGB[1][1] * m +\n LMS_TO_LINEAR_SRGB[1][2] * s,\n b:\n LMS_TO_LINEAR_SRGB[2][0] * l +\n LMS_TO_LINEAR_SRGB[2][1] * m +\n LMS_TO_LINEAR_SRGB[2][2] * s,\n };\n}\n","import type { LinearSrgb, Oklab } from \"../types.js\";\nimport {\n LINEAR_P3_TO_LMS,\n LMS_PRIME_TO_OKLAB,\n LMS_TO_LINEAR_P3,\n OKLAB_TO_LMS_PRIME,\n} from \"../constants.js\";\n\n/** Convert Linear Display P3 to OKLAB via P3-specific M1 + shared M2. */\nexport function linearP3ToOklab(color: LinearSrgb): Oklab {\n // Step 1: Linear P3 → LMS\n const l =\n LINEAR_P3_TO_LMS[0][0] * color.r +\n LINEAR_P3_TO_LMS[0][1] * color.g +\n LINEAR_P3_TO_LMS[0][2] * color.b;\n const m =\n LINEAR_P3_TO_LMS[1][0] * color.r +\n LINEAR_P3_TO_LMS[1][1] * color.g +\n LINEAR_P3_TO_LMS[1][2] * color.b;\n const s =\n LINEAR_P3_TO_LMS[2][0] * color.r +\n LINEAR_P3_TO_LMS[2][1] * color.g +\n LINEAR_P3_TO_LMS[2][2] * color.b;\n\n // Step 2: Cube root\n const lp = Math.cbrt(l);\n const mp = Math.cbrt(m);\n const sp = Math.cbrt(s);\n\n // Step 3: LMS′ → OKLAB (shared M2)\n return {\n L:\n LMS_PRIME_TO_OKLAB[0][0] * lp +\n LMS_PRIME_TO_OKLAB[0][1] * mp +\n LMS_PRIME_TO_OKLAB[0][2] * sp,\n a:\n LMS_PRIME_TO_OKLAB[1][0] * lp +\n LMS_PRIME_TO_OKLAB[1][1] * mp +\n LMS_PRIME_TO_OKLAB[1][2] * sp,\n b:\n LMS_PRIME_TO_OKLAB[2][0] * lp +\n LMS_PRIME_TO_OKLAB[2][1] * mp +\n LMS_PRIME_TO_OKLAB[2][2] * sp,\n };\n}\n\n/** Convert OKLAB to Linear Display P3 via shared inverse M2 + P3-specific inverse M1. */\nexport function oklabToLinearP3(color: Oklab): LinearSrgb {\n // Step 1: OKLAB → LMS′ (shared inverse M2)\n const lp =\n OKLAB_TO_LMS_PRIME[0][0] * color.L +\n OKLAB_TO_LMS_PRIME[0][1] * color.a +\n OKLAB_TO_LMS_PRIME[0][2] * color.b;\n const mp =\n OKLAB_TO_LMS_PRIME[1][0] * color.L +\n OKLAB_TO_LMS_PRIME[1][1] * color.a +\n OKLAB_TO_LMS_PRIME[1][2] * color.b;\n const sp =\n OKLAB_TO_LMS_PRIME[2][0] * color.L +\n OKLAB_TO_LMS_PRIME[2][1] * color.a +\n OKLAB_TO_LMS_PRIME[2][2] * color.b;\n\n // Step 2: Cube\n const l = lp * lp * lp;\n const m = mp * mp * mp;\n const s = sp * sp * sp;\n\n // Step 3: LMS → Linear P3\n return {\n r:\n LMS_TO_LINEAR_P3[0][0] * l +\n LMS_TO_LINEAR_P3[0][1] * m +\n LMS_TO_LINEAR_P3[0][2] * s,\n g:\n LMS_TO_LINEAR_P3[1][0] * l +\n LMS_TO_LINEAR_P3[1][1] * m +\n LMS_TO_LINEAR_P3[1][2] * s,\n b:\n LMS_TO_LINEAR_P3[2][0] * l +\n LMS_TO_LINEAR_P3[2][1] * m +\n LMS_TO_LINEAR_P3[2][2] * s,\n };\n}\n","import type { LinearSrgb, Srgb } from \"../types.js\";\nimport {\n SRGB_GAMMA_EXPONENT,\n SRGB_GAMMA_OFFSET,\n SRGB_GAMMA_SCALE,\n SRGB_GAMMA_SLOPE,\n SRGB_GAMMA_THRESHOLD,\n SRGB_GAMMA_THRESHOLD_LINEAR,\n} from \"../constants.js\";\n\n/** Decode a single sRGB gamma-encoded channel to linear light. */\nexport function srgbChannelToLinear(value: number): number {\n return value <= SRGB_GAMMA_THRESHOLD\n ? value / SRGB_GAMMA_SLOPE\n : ((value + SRGB_GAMMA_OFFSET) / SRGB_GAMMA_SCALE) ** SRGB_GAMMA_EXPONENT;\n}\n\n/** Encode a single linear light channel to sRGB gamma. */\nexport function linearChannelToSrgb(value: number): number {\n return value <= SRGB_GAMMA_THRESHOLD_LINEAR\n ? value * SRGB_GAMMA_SLOPE\n : SRGB_GAMMA_SCALE * value ** (1 / SRGB_GAMMA_EXPONENT) - SRGB_GAMMA_OFFSET;\n}\n\n/** Convert an sRGB color to Linear sRGB. */\nexport function srgbToLinearSrgb(color: Srgb): LinearSrgb {\n return {\n r: srgbChannelToLinear(color.r),\n g: srgbChannelToLinear(color.g),\n b: srgbChannelToLinear(color.b),\n };\n}\n\n/** Convert a Linear sRGB color to sRGB. */\nexport function linearSrgbToSrgb(color: LinearSrgb): Srgb {\n return {\n r: linearChannelToSrgb(color.r),\n g: linearChannelToSrgb(color.g),\n b: linearChannelToSrgb(color.b),\n };\n}\n","import type { Hex, Srgb } from \"../types.js\";\n\n/** Parse a hex color string (#RGB, #RRGGBB, or bare) to sRGB [0,1]. */\nexport function hexToSrgb(hex: string): Srgb {\n let h = hex.startsWith(\"#\") ? hex.slice(1) : hex;\n\n if (h.length === 3) {\n h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];\n }\n\n const n = parseInt(h, 16);\n return {\n r: ((n >> 16) & 0xff) / 255,\n g: ((n >> 8) & 0xff) / 255,\n b: (n & 0xff) / 255,\n };\n}\n\n/** Convert sRGB [0,1] to lowercase hex string (#rrggbb). Clamps to [0,1]. */\nexport function srgbToHex(color: Srgb): Hex {\n const r = Math.round(Math.max(0, Math.min(1, color.r)) * 255);\n const g = Math.round(Math.max(0, Math.min(1, color.g)) * 255);\n const b = Math.round(Math.max(0, Math.min(1, color.b)) * 255);\n return `#${((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1)}` as Hex;\n}\n","import type { Hex, Oklab, Oklch, Srgb } from \"../types.js\";\nimport { oklabToOklch, oklchToOklab } from \"./oklab.js\";\nimport { linearSrgbToOklab, oklabToLinearSrgb } from \"./linear-srgb.js\";\nimport { linearP3ToOklab, oklabToLinearP3 } from \"./linear-p3.js\";\nimport { linearSrgbToSrgb, srgbToLinearSrgb } from \"./srgb.js\";\nimport { hexToSrgb, srgbToHex } from \"./hex.js\";\n\n/** Convert sRGB to OKLCH. */\nexport function srgbToOklch(color: Srgb): Oklch {\n return oklabToOklch(linearSrgbToOklab(srgbToLinearSrgb(color)));\n}\n\n/** Convert OKLCH to sRGB. May produce out-of-gamut values (channels outside [0,1]). */\nexport function oklchToSrgb(color: Oklch): Srgb {\n return linearSrgbToSrgb(oklabToLinearSrgb(oklchToOklab(color)));\n}\n\n/** Convert sRGB to OKLAB. */\nexport function srgbToOklab(color: Srgb): Oklab {\n return linearSrgbToOklab(srgbToLinearSrgb(color));\n}\n\n/** Convert OKLAB to sRGB. May produce out-of-gamut values. */\nexport function oklabToSrgb(color: Oklab): Srgb {\n return linearSrgbToSrgb(oklabToLinearSrgb(color));\n}\n\n/** Convert hex to OKLCH. */\nexport function hexToOklch(hex: string): Oklch {\n return srgbToOklch(hexToSrgb(hex));\n}\n\n/** Convert OKLCH to hex. Clamps to sRGB gamut before hex encoding. */\nexport function oklchToHex(color: Oklch): Hex {\n const srgb = oklchToSrgb(color);\n return srgbToHex({\n r: Math.max(0, Math.min(1, srgb.r)),\n g: Math.max(0, Math.min(1, srgb.g)),\n b: Math.max(0, Math.min(1, srgb.b)),\n });\n}\n\n/** Convert Display P3 to OKLCH. */\nexport function p3ToOklch(color: Srgb): Oklch {\n return oklabToOklch(linearP3ToOklab(srgbToLinearSrgb(color)));\n}\n\n/** Convert OKLCH to Display P3. May produce out-of-gamut values (channels outside [0,1]). */\nexport function oklchToP3(color: Oklch): Srgb {\n return linearSrgbToSrgb(oklabToLinearP3(oklchToOklab(color)));\n}\n\n/** Convert OKLCH to a CSS `color(display-p3 r g b)` string. Clamps channels to [0,1]. */\nexport function oklchToP3Css(color: Oklch): string {\n const p3 = oklchToP3(color);\n const r = Math.max(0, Math.min(1, p3.r)).toFixed(4);\n const g = Math.max(0, Math.min(1, p3.g)).toFixed(4);\n const b = Math.max(0, Math.min(1, p3.b)).toFixed(4);\n return `color(display-p3 ${r} ${g} ${b})`;\n}\n","import type { Srgb } from \"../types.js\";\nimport { GAMUT_EPSILON } from \"../constants.js\";\n\n/** Check if sRGB channels are within [0, 1] (with epsilon tolerance). */\nexport function isInGamut(color: Srgb): boolean {\n return (\n color.r >= -GAMUT_EPSILON &&\n color.r <= 1 + GAMUT_EPSILON &&\n color.g >= -GAMUT_EPSILON &&\n color.g <= 1 + GAMUT_EPSILON &&\n color.b >= -GAMUT_EPSILON &&\n color.b <= 1 + GAMUT_EPSILON\n );\n}\n\n/** Clamp sRGB channels to [0, 1]. */\nexport function clampSrgb(color: Srgb): Srgb {\n return {\n r: Math.max(0, Math.min(1, color.r)),\n g: Math.max(0, Math.min(1, color.g)),\n b: Math.max(0, Math.min(1, color.b)),\n };\n}\n\n/** Clamp Display P3 channels to [0, 1]. */\nexport const clampP3 = clampSrgb;\n","import type { Oklab, Oklch } from \"../types.js\";\nimport { oklchToOklab } from \"../conversions/oklab.js\";\n\n/** Compute deltaEOK (Euclidean distance in OKLAB) between two OKLCH colors. */\nexport function deltaEOK(a: Oklch, b: Oklch): number {\n return deltaEOKLab(oklchToOklab(a), oklchToOklab(b));\n}\n\n/** Compute deltaEOK directly from OKLAB values. */\nexport function deltaEOKLab(a: Oklab, b: Oklab): number {\n const dL = a.L - b.L;\n const da = a.a - b.a;\n const db = a.b - b.b;\n return Math.sqrt(dL * dL + da * da + db * db);\n}\n","import type { Gamut, Oklch, Srgb } from \"../types.js\";\nimport {\n GAMUT_EPSILON,\n GAMUT_MAP_EPSILON,\n GAMUT_MAP_JND,\n GAMUT_MAP_MAX_ITERATIONS,\n} from \"../constants.js\";\nimport { oklchToSrgb, oklchToP3 } from \"../conversions/pipeline.js\";\nimport { isInGamut, clampSrgb } from \"./check.js\";\nimport { deltaEOKLab } from \"../color/difference.js\";\nimport { oklchToOklab } from \"../conversions/oklab.js\";\nimport { linearSrgbToOklab } from \"../conversions/linear-srgb.js\";\nimport { linearP3ToOklab } from \"../conversions/linear-p3.js\";\nimport { srgbToLinearSrgb } from \"../conversions/srgb.js\";\n\n/**\n * Map an OKLCH color into the target gamut using the CSS Color Level 4 algorithm.\n * Reduces chroma at fixed L and h via binary search with deltaEOK JND check.\n * @param gamut Target gamut (default: 'srgb').\n */\nexport function gamutMap(color: Oklch, gamut: Gamut = \"srgb\"): Oklch {\n const toRgb = gamut === \"display-p3\" ? oklchToP3 : oklchToSrgb;\n const rgbToOklab =\n gamut === \"display-p3\"\n ? (c: Srgb) => linearP3ToOklab(srgbToLinearSrgb(c))\n : (c: Srgb) => linearSrgbToOklab(srgbToLinearSrgb(c));\n\n // Already in gamut\n const rgb = toRgb(color);\n if (isInGamut(rgb)) return color;\n\n // Edge cases: black and white\n if (color.L <= GAMUT_EPSILON) return { L: 0, C: 0, h: color.h };\n if (color.L >= 1 - GAMUT_EPSILON) return { L: 1, C: 0, h: color.h };\n\n let lo = 0;\n let hi = color.C;\n\n for (let i = 0; i < GAMUT_MAP_MAX_ITERATIONS; i++) {\n const midC = (lo + hi) / 2;\n const candidate: Oklch = { L: color.L, C: midC, h: color.h };\n const candidateRgb = toRgb(candidate);\n\n if (isInGamut(candidateRgb)) {\n lo = midC;\n } else {\n // Clip and check JND\n const clipped = clampSrgb(candidateRgb);\n const clippedLab = rgbToOklab(clipped);\n const candidateLab = oklchToOklab(candidate);\n const dE = deltaEOKLab(clippedLab, candidateLab);\n\n if (dE < GAMUT_MAP_JND) {\n // Clipped version is perceptually close enough — converge here.\n // Return lo (last confirmed in-gamut chroma) to guarantee gamut safety.\n break;\n }\n\n hi = midC;\n }\n\n if (hi - lo < GAMUT_MAP_EPSILON) break;\n }\n\n return { L: color.L, C: lo, h: color.h };\n}\n","import type { Gamut, Oklch } from \"../types.js\";\nimport { GAMUT_MAP_MAX_ITERATIONS } from \"../constants.js\";\nimport { oklchToSrgb, oklchToP3 } from \"../conversions/pipeline.js\";\nimport { isInGamut } from \"./check.js\";\n\n/**\n * Find the maximum in-gamut chroma for a given OKLCH lightness and hue.\n *\n * Binary search over [0, upperBound], converging to 1e-6 precision.\n * Upper bounds are empirically safe ceilings — no in-gamut color at any\n * lightness or hue exceeds C = 0.4 in sRGB or C = 0.5 in Display P3.\n * Searching beyond these would waste iterations with no benefit.\n *\n * Returns 0 for L ≤ 0 or L ≥ 1 (pure black and white carry no chroma).\n */\nexport function maxChroma(L: number, h: number, gamut: Gamut = \"srgb\"): number {\n if (L <= 0 || L >= 1) return 0;\n\n const toRgb = gamut === \"display-p3\" ? oklchToP3 : oklchToSrgb;\n let lo = 0;\n let hi = gamut === \"display-p3\" ? 0.5 : 0.4;\n\n for (let i = 0; i < GAMUT_MAP_MAX_ITERATIONS; i++) {\n const mid = (lo + hi) / 2;\n const color: Oklch = { L, C: mid, h };\n const rgb = toRgb(color);\n\n if (isInGamut(rgb)) {\n lo = mid;\n } else {\n hi = mid;\n }\n\n if (hi - lo < 1e-6) break;\n }\n\n return lo;\n}\n","import type { Srgb } from \"../types.js\";\nimport { WCAG_R, WCAG_G, WCAG_B } from \"../constants.js\";\nimport { srgbChannelToLinear } from \"../conversions/srgb.js\";\n\n/** Compute WCAG 2.x relative luminance [0, 1] from an sRGB color. */\nexport function wcagLuminance(color: Srgb): number {\n return (\n WCAG_R * srgbChannelToLinear(color.r) +\n WCAG_G * srgbChannelToLinear(color.g) +\n WCAG_B * srgbChannelToLinear(color.b)\n );\n}\n\n/**\n * Compute WCAG 2.x contrast ratio between two sRGB colors.\n * Returns a value in [1, 21]. Symmetric (order doesn't matter).\n */\nexport function wcagContrast(a: Srgb, b: Srgb): number {\n const lA = wcagLuminance(a);\n const lB = wcagLuminance(b);\n const lighter = Math.max(lA, lB);\n const darker = Math.min(lA, lB);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\n/**\n * Choose black or white text for maximum WCAG contrast against a background.\n * @returns `\"#000000\"` or `\"#ffffff\"`.\n */\nexport function contrastTextHex(background: Srgb): \"#000000\" | \"#ffffff\" {\n const white: Srgb = { r: 1, g: 1, b: 1 };\n const black: Srgb = { r: 0, g: 0, b: 0 };\n return wcagContrast(white, background) > wcagContrast(black, background)\n ? \"#ffffff\"\n : \"#000000\";\n}\n","import type { Srgb } from \"../types.js\";\nimport {\n APCA_MAIN_TRC,\n APCA_SRGB_R,\n APCA_SRGB_G,\n APCA_SRGB_B,\n APCA_NORM_BG,\n APCA_NORM_TXT,\n APCA_REV_TXT,\n APCA_REV_BG,\n APCA_BLK_THRS,\n APCA_BLK_CLMP,\n APCA_SCALE_BOW,\n APCA_SCALE_WOB,\n APCA_LO_BOW_OFFSET,\n APCA_LO_WOB_OFFSET,\n APCA_DELTA_Y_MIN,\n APCA_LO_CLIP,\n} from \"../constants.js\";\n\n/**\n * Compute APCA-W3 Lc (Lightness Contrast) between text and background.\n *\n * Returns a signed value in roughly [-108, +106]:\n * Positive = dark text on light background (BoW)\n * Negative = light text on dark background (WoB)\n * 0 = no meaningful contrast\n *\n * IMPORTANT: Uses its own linearization (simple 2.4 gamma),\n * NOT the IEC piecewise sRGB transfer function.\n */\n/**\n * Practical maximum APCA Lc magnitude used for normalization.\n * BoW tops out at ~+106, WoB at ~-108; we use 108 as a symmetric ceiling.\n */\nexport const APCA_LC_MAX = 108;\n\n/**\n * Normalize a raw APCA Lc value to the range [-1, +1].\n * +1 = maximum dark-on-light contrast (BoW)\n * -1 = maximum light-on-dark contrast (WoB)\n * 0 = no meaningful contrast\n */\nexport function apcaToNormalized(lc: number): number {\n return Math.max(-1, Math.min(1, lc / APCA_LC_MAX));\n}\n\n/**\n * Convert a normalized contrast value [-1, +1] back to a raw APCA Lc value.\n */\nexport function normalizedToApca(normalized: number): number {\n return normalized * APCA_LC_MAX;\n}\n\nexport function apcaContrast(textColor: Srgb, bgColor: Srgb): number {\n // Step 1: Linearize with simple 2.4 gamma and compute Y\n let txtY =\n APCA_SRGB_R * textColor.r ** APCA_MAIN_TRC +\n APCA_SRGB_G * textColor.g ** APCA_MAIN_TRC +\n APCA_SRGB_B * textColor.b ** APCA_MAIN_TRC;\n\n let bgY =\n APCA_SRGB_R * bgColor.r ** APCA_MAIN_TRC +\n APCA_SRGB_G * bgColor.g ** APCA_MAIN_TRC +\n APCA_SRGB_B * bgColor.b ** APCA_MAIN_TRC;\n\n // Step 2: Soft black clamp\n if (txtY < APCA_BLK_THRS) {\n txtY += (APCA_BLK_THRS - txtY) ** APCA_BLK_CLMP;\n }\n if (bgY < APCA_BLK_THRS) {\n bgY += (APCA_BLK_THRS - bgY) ** APCA_BLK_CLMP;\n }\n\n // Step 3: Delta Y check\n if (Math.abs(bgY - txtY) < APCA_DELTA_Y_MIN) return 0;\n\n // Step 4: Polarity-aware contrast\n let sapc: number;\n\n if (bgY > txtY) {\n // Dark text on light background (BoW)\n sapc = (bgY ** APCA_NORM_BG - txtY ** APCA_NORM_TXT) * APCA_SCALE_BOW;\n return sapc < APCA_LO_CLIP ? 0 : (sapc - APCA_LO_BOW_OFFSET) * 100;\n } else {\n // Light text on dark background (WoB)\n sapc = (bgY ** APCA_REV_BG - txtY ** APCA_REV_TXT) * APCA_SCALE_WOB;\n return sapc > -APCA_LO_CLIP ? 0 : (sapc + APCA_LO_WOB_OFFSET) * 100;\n }\n}\n","import type { Oklch } from \"../types.js\";\nimport { ACHROMATIC_THRESHOLD } from \"../constants.js\";\n\n/**\n * Linearly interpolate between two OKLCH colors.\n *\n * L and C are linearly interpolated. Hue uses shortest-arc interpolation.\n * Achromatic colors (C near zero) inherit the other color's hue to avoid\n * meaningless hue sweeps through the achromatic pole.\n */\nexport function mix(a: Oklch, b: Oklch, t: number): Oklch {\n const L = a.L + (b.L - a.L) * t;\n const C = a.C + (b.C - a.C) * t;\n\n // Resolve hue — handle achromatic inputs\n const aIsAchromatic = a.C < ACHROMATIC_THRESHOLD;\n const bIsAchromatic = b.C < ACHROMATIC_THRESHOLD;\n\n if (aIsAchromatic && bIsAchromatic) {\n return { L, C, h: 0 };\n }\n\n const hA = aIsAchromatic ? b.h : a.h;\n const hB = bIsAchromatic ? a.h : b.h;\n\n // Shortest-arc hue interpolation\n let delta = hB - hA;\n if (delta > 180) delta -= 360;\n if (delta < -180) delta += 360;\n\n let h = hA + delta * t;\n if (h < 0) h += 360;\n if (h >= 360) h -= 360;\n\n return { L, C, h };\n}\n","/**\n * Design constants — the values you tune by hand.\n *\n * Edit this file to adjust the perceptual behavior of every scale and\n * grading operation across the library.\n */\n\n// ── Scale defaults ────────────────────────────────────────────────────────────\n\n/**\n * Default number of steps in a generated scale.\n * Fixed at 26 — enough for a full design token set with fine lightness\n * increments without redundancy.\n */\nexport const DEFAULT_SCALE_STEPS = 26;\n\n/**\n * Default hue when none is provided.\n * 0° is the start of the OKLCH hue wheel (red region). Arbitrary but\n * deterministic — callers should always supply an explicit hue.\n */\nexport const DEFAULT_HUE = 0;\n\n// ── Dynamic range ─────────────────────────────────────────────────────────────\n\n/**\n * Lightest step's lightness when the whites slider is at 0 (Display P3).\n * P3's wider gamut can reproduce near-whites that clip in sRGB.\n */\nexport const MIN_LIGHTEST_L_P3 = 0.98;\n\n/**\n * Lightest step's lightness when the whites slider is at 0 (sRGB).\n * slider 0 → L = MIN_LIGHTEST_L, slider 1 → L = 1.0 (pure white).\n */\nexport const MIN_LIGHTEST_L = 0.92;\n\n/**\n * Darkest step's lightness when the darks slider is at 0 (sRGB).\n * slider 0 → L = MAX_DARKEST_L, slider 1 → L = 0.0 (pure black).\n */\nexport const MAX_DARKEST_L = 0.20;\n\n/**\n * Darkest step's lightness when the darks slider is at 0 (Display P3).\n * P3's wider gamut can reproduce near-blacks that clip in sRGB.\n */\nexport const MAX_DARKEST_L_P3 = 0.14;\n\n// ── Hue grading ───────────────────────────────────────────────────────────────\n\n/**\n * How far global grading reaches into the scale from each end (0–1).\n * Light grading fades to zero at t = GRADING_REACH.\n * Dark grading fades to zero at t = 1 − GRADING_REACH.\n */\nexport const GRADING_REACH = 3 / 5;\n\n/** Maximum amount for global grading. Inputs above this are clamped. */\nexport const MAX_GRADING_AMOUNT = 0.25;\n\n/**\n * Fraction of the gamut boundary injected as chroma when global grading\n * is active. Ensures grading has a visible tinting effect even on\n * achromatic (chroma.amount = 0) palettes.\n *\n * Only global grading injects chroma — per-palette shift does not.\n */\nexport const GRADING_CHROMA_RATIO = 0.5;\n\n/**\n * How far per-palette hue shift reaches into the scale from each end (0–1).\n * Slightly wider than GRADING_REACH to give per-palette shifts more room.\n */\nexport const SHIFT_REACH = 2 / 3;\n\n/** Maximum amount for per-palette hue shift. Inputs above this are clamped. */\nexport const MAX_SHIFT_AMOUNT = 0.5;\n\n// ── Color difference ──────────────────────────────────────────────────────────\n\n/**\n * Just-noticeable difference threshold (deltaEOK).\n * Colors with distance below this are considered perceptually identical.\n * Used to classify color matches as exact vs. fallback.\n */\nexport const PERCEPTUAL_JND = 0.02;\n","/**\n * Global hue grading — shifts each palette's base hue toward shared\n * target hues at the light and dark scale endpoints.\n *\n * Light grading fades from full at the lightest step to zero at GRADING_REACH.\n * Dark grading fades from zero at (1 - GRADING_REACH) to full at the darkest step.\n * In the overlap zone, both shifts are additive (commutative).\n */\n\nimport {\n GRADING_REACH,\n MAX_GRADING_AMOUNT,\n SHIFT_REACH,\n MAX_SHIFT_AMOUNT,\n} from \"../config.js\";\n\nexport interface Grading {\n /** Hue grading for the light end of the scale. */\n readonly light?: { readonly hue: number; readonly amount: number };\n /** Hue grading for the dark end of the scale. */\n readonly dark?: { readonly hue: number; readonly amount: number };\n}\n\n/** Per-palette hue shift (one end only). */\nexport interface Shift {\n /** Target hue to shift toward (0–360°). */\n readonly hue: number;\n /** Blend strength (0–MAX_SHIFT_AMOUNT). */\n readonly amount: number;\n /** Which end to affect. `true` = light end, `false`/omitted = dark end (default). */\n readonly light?: boolean;\n}\n\n/**\n * Compute the graded hue at position `t` in the scale.\n *\n * Uses vector interpolation in Cartesian space rather than angular deltas\n * to avoid the shortest-arc discontinuity at 180° (where the direction\n * of rotation flips abruptly). Each grade's displacement is computed as\n * a vector offset from the base hue, and displacements are additive\n * (commutative — order doesn't matter).\n *\n * @param baseHue The palette's own hue (0–360°).\n * @param t Position in the scale: 0 = lightest, 1 = darkest.\n * @param grade Hue grade configuration.\n * @param reach How far each grade reaches into the scale (default: GRADING_REACH).\n * @param maxIntensity Maximum amount clamp (default: MAX_GRADING_AMOUNT).\n * @returns The graded hue in degrees (0–360).\n */\nexport function gradeHue(\n baseHue: number,\n t: number,\n grade: Grading,\n reach: number = GRADING_REACH,\n maxIntensity: number = MAX_GRADING_AMOUNT,\n): number {\n const li = Math.max(0, Math.min(maxIntensity, grade.light?.amount ?? 0));\n const di = Math.max(0, Math.min(maxIntensity, grade.dark?.amount ?? 0));\n\n // Early exit: no grading\n if (li === 0 && di === 0) return baseHue;\n\n // Light influence: cosine fade from 1 at t=0 to 0 at t=reach\n const lightInfluence =\n t <= reach ? 0.5 * (1 + Math.cos((Math.PI * t) / reach)) : 0;\n\n // Dark influence: cosine fade from 0 at t=(1-reach) to 1 at t=1\n const darkInfluence =\n t >= 1 - reach\n ? 0.5 * (1 + Math.cos((Math.PI * (1 - t)) / reach))\n : 0;\n\n // Base hue as unit vector\n const toRad = Math.PI / 180;\n const baseRad = baseHue * toRad;\n const bx = Math.cos(baseRad);\n const by = Math.sin(baseRad);\n\n // Accumulate displacements in Cartesian space\n let dx = 0;\n let dy = 0;\n\n if (lightInfluence > 0 && li > 0) {\n const blend = lightInfluence * li;\n const lRad = (grade.light!.hue) * toRad;\n dx += blend * (Math.cos(lRad) - bx);\n dy += blend * (Math.sin(lRad) - by);\n }\n\n if (darkInfluence > 0 && di > 0) {\n const blend = darkInfluence * di;\n const dRad = (grade.dark!.hue) * toRad;\n dx += blend * (Math.cos(dRad) - bx);\n dy += blend * (Math.sin(dRad) - by);\n }\n\n // Reconstruct hue from displaced vector\n const rx = bx + dx;\n const ry = by + dy;\n\n // Safety: collapsed vector (opposite hues at exactly 50% blend)\n if (rx * rx + ry * ry < 1e-20) return baseHue;\n\n return ((Math.atan2(ry, rx) / toRad) + 360) % 360;\n}\n\n/**\n * Compute the combined grading influence at position `t` (0–1).\n *\n * Returns a scalar in [0, 1] representing how strongly global grading\n * affects position `t`. This is the maximum of the light and dark\n * cosine-fade envelopes, each scaled by its respective amount.\n *\n * Used by the chroma injection system to tint achromatic palettes\n * proportionally to grading strength.\n */\nexport function gradingInfluence(t: number, grading: Grading): number {\n const li = Math.max(0, Math.min(MAX_GRADING_AMOUNT, grading.light?.amount ?? 0));\n const di = Math.max(0, Math.min(MAX_GRADING_AMOUNT, grading.dark?.amount ?? 0));\n\n if (li === 0 && di === 0) return 0;\n\n const lightInfluence =\n t <= GRADING_REACH ? 0.5 * (1 + Math.cos((Math.PI * t) / GRADING_REACH)) : 0;\n\n const darkInfluence =\n t >= 1 - GRADING_REACH\n ? 0.5 * (1 + Math.cos((Math.PI * (1 - t)) / GRADING_REACH))\n : 0;\n\n const lightBlend = lightInfluence * (li / MAX_GRADING_AMOUNT);\n const darkBlend = darkInfluence * (di / MAX_GRADING_AMOUNT);\n\n return Math.max(lightBlend, darkBlend);\n}\n\n/**\n * Resolve the final hue at position `t`, applying local shift first, then global grading.\n *\n * This is the canonical composition: per-palette shift (using SHIFT_REACH /\n * MAX_SHIFT_AMOUNT) first, then global grading (using GRADING_REACH /\n * MAX_GRADING_AMOUNT) on top — so grading's influence is preserved at full\n * strength across all palettes, keeping them visually coherent.\n *\n * @param baseHue The palette's own hue (0–360°).\n * @param t Position in the scale: 0 = lightest, 1 = darkest.\n * @param globalGrade Global grading (shared across palettes), or undefined.\n * @param localGrade Local grading (per-palette, expanded from Shift), or undefined.\n * @returns The fully graded hue in degrees (0–360).\n */\nexport function resolveGradedHue(\n baseHue: number,\n t: number,\n globalGrade?: Grading,\n localGrade?: Grading,\n): number {\n let h = baseHue;\n if (localGrade) h = gradeHue(h, t, localGrade, SHIFT_REACH, MAX_SHIFT_AMOUNT);\n if (globalGrade) h = gradeHue(h, t, globalGrade);\n return h;\n}\n\n/**\n * Adapt a Shift into a one-sided Grading so it can be passed to gradeHue.\n *\n * The Shift interface is flat (hue, amount, light?) for ergonomic API use,\n * but gradeHue operates on the Grading shape (light/dark sub-objects).\n * This function bridges the two, activating only the requested end.\n *\n * @param hue Target hue for the active side (0–360°).\n * @param amount Blend strength for the active side.\n * @param light `true` = light end, `false`/omitted = dark end (default).\n */\nexport function buildOneSidedGrade(\n hue: number,\n amount: number,\n light: boolean = false,\n): Grading {\n return light\n ? { light: { hue, amount } }\n : { dark: { hue, amount } };\n}\n","import type { Oklch } from \"../types.js\";\nimport { maxChroma } from \"../gamut/max-chroma.js\";\nimport type { Grading, Shift } from \"./hue-grade.js\";\nimport { resolveGradedHue, buildOneSidedGrade } from \"./hue-grade.js\";\nimport {\n DEFAULT_SCALE_STEPS,\n DEFAULT_HUE,\n GRADING_CHROMA_RATIO,\n GRADING_REACH,\n MAX_GRADING_AMOUNT,\n MIN_LIGHTEST_L,\n MAX_DARKEST_L,\n MIN_LIGHTEST_L_P3,\n MAX_DARKEST_L_P3,\n} from \"../config.js\";\n\ntype Gamut = \"srgb\" | \"display-p3\";\nconst toRad = Math.PI / 180;\n\n/**\n * Apply grading as an additive chroma overlay.\n *\n * Builds per-side chroma vectors pointing at the grading TARGET hues\n * (not the palette's hue) and adds them to the palette's existing\n * chroma in Cartesian (a, b) space. This ensures grading tints even\n * fully achromatic palettes without the base hue leaking through.\n */\nfunction applyGradingOverlay(\n C: number, h: number, L: number, t: number,\n grading: Grading, gamut: Gamut,\n): { C: number; h: number } {\n const li = Math.max(0, Math.min(MAX_GRADING_AMOUNT, grading.light?.amount ?? 0));\n const di = Math.max(0, Math.min(MAX_GRADING_AMOUNT, grading.dark?.amount ?? 0));\n if (li === 0 && di === 0) return { C, h };\n\n // Per-side cosine-fade influences\n const lightFade = t <= GRADING_REACH\n ? 0.5 * (1 + Math.cos((Math.PI * t) / GRADING_REACH)) : 0;\n const darkFade = t >= 1 - GRADING_REACH\n ? 0.5 * (1 + Math.cos((Math.PI * (1 - t)) / GRADING_REACH)) : 0;\n\n const lightBlend = lightFade * (li / MAX_GRADING_AMOUNT);\n const darkBlend = darkFade * (di / MAX_GRADING_AMOUNT);\n if (lightBlend === 0 && darkBlend === 0) return { C, h };\n\n // Palette's existing chroma as Cartesian vector\n const hRad = h * toRad;\n let a = C * Math.cos(hRad);\n let b = C * Math.sin(hRad);\n\n // Add overlay vectors at grading TARGET hues\n if (lightBlend > 0) {\n const lh = grading.light!.hue;\n const lRad = lh * toRad;\n const lC = maxChroma(L, lh, gamut) * GRADING_CHROMA_RATIO * lightBlend;\n a += lC * Math.cos(lRad);\n b += lC * Math.sin(lRad);\n }\n if (darkBlend > 0) {\n const dh = grading.dark!.hue;\n const dRad = dh * toRad;\n const dC = maxChroma(L, dh, gamut) * GRADING_CHROMA_RATIO * darkBlend;\n a += dC * Math.cos(dRad);\n b += dC * Math.sin(dRad);\n }\n\n // Convert back to polar\n let newC = Math.sqrt(a * a + b * b);\n let newH = ((Math.atan2(b, a) / toRad) + 360) % 360;\n\n // Clamp to gamut at the resulting hue\n newC = Math.min(newC, maxChroma(L, newH, gamut));\n\n return { C: newC, h: newH };\n}\n\nexport interface ScaleOptions {\n /**\n * Tonal range of the scale.\n * - `light`: how light the lightest step is (0–1). Default: 1.\n * 0 → L = MIN_LIGHTEST_L (0.96), 1 → L = 1.0 (pure white).\n * - `dark`: how dark the darkest step is (0–1). Default: 1.\n * 0 → L = MAX_DARKEST_L (0.16), 1 → L = 0.0 (pure black).\n */\n readonly contrast?: { readonly light?: number; readonly dark?: number };\n /**\n * Hue angle in degrees (0–360). Default: DEFAULT_HUE (0).\n * Every step shares this base hue unless shifted by `grading` or `shift`.\n */\n readonly hue?: number;\n /**\n * Chroma shape of the scale.\n * - `amount`: how much of the available gamut to use (0–1). Default: 0.\n * 0 = fully achromatic (default), 1 = maximum in-gamut chroma at each lightness.\n * - `balance`: how chroma is distributed along the lightness range (0–1).\n * 0 = chroma concentrated toward the lightest end, 1 = toward the darkest end,\n * 0.5 = natural distribution (default, follows gamut boundary shape).\n */\n readonly chroma?: { readonly amount?: number; readonly balance?: number };\n /**\n * Global hue grading. When provided, the hue at each step is shifted\n * toward target hues based on position in the scale.\n * Light grading affects the lightest 3/5, dark grading affects the\n * darkest 3/5, with additive overlap in the middle fifth.\n */\n readonly grading?: Grading;\n /**\n * Per-palette hue shift. A one-sided grade applied before global\n * grading, with its own reach and strength limits (SHIFT_REACH,\n * MAX_SHIFT_AMOUNT). Defaults to the dark end; set `light: true` to target\n * the light end instead.\n */\n readonly shift?: Shift;\n /** Use Display P3 gamut instead of sRGB (default: false). */\n readonly isP3?: boolean;\n}\n\n/**\n * Generate an OKLCH color scale from lightest to darkest.\n *\n * Always produces DEFAULT_SCALE_STEPS colors. Chroma at each step is\n * proportional to the gamut boundary at that lightness, scaled by\n * `chroma.amount`. This guarantees every color is in-gamut — no fallbacks\n * needed — while producing a smooth, natural chroma curve.\n *\n * Use `contrast` to constrain the tonal range\n * (e.g. for scales that don't extend to pure white or pure black).\n *\n * Use `chroma.balance` to shift how chroma is distributed within the boundary.\n * The curve endpoints stay fixed while the distribution shifts smoothly.\n * The effective shift range is proportional to the headroom left by chroma.amount.\n */\nexport function generateScale(options: ScaleOptions = {}): Oklch[] {\n const {\n contrast,\n hue = DEFAULT_HUE,\n chroma,\n isP3 = false,\n grading,\n shift,\n } = options;\n const gamut = isP3 ? \"display-p3\" : \"srgb\";\n\n const steps = DEFAULT_SCALE_STEPS;\n const chromaRatio = chroma?.amount ?? 0;\n const chromaPeak = chroma?.balance ?? 0.5;\n const hueGrade = grading;\n const localHueGrade = shift ? buildOneSidedGrade(shift.hue, shift.amount, shift.light) : undefined;\n\n const ratio = Math.max(0, Math.min(1, chromaRatio));\n const peak = Math.max(0, Math.min(1, chromaPeak));\n // Slider interpolates from base (slider=0) to cap (slider=1).\n // P3 caps at 0.99/0.12 instead of 1.0/0.0 — extreme ends produce\n // clipping artifacts in P3 that don't occur in sRGB.\n const capLight = isP3 ? MIN_LIGHTEST_L_P3 : 1.0;\n const capDark = isP3 ? MAX_DARKEST_L_P3 : 0.0;\n const lightSlider = Math.max(0, Math.min(1, contrast?.light ?? 1));\n const darkSlider = Math.max(0, Math.min(1, contrast?.dark ?? 1));\n const lightestL = MIN_LIGHTEST_L + lightSlider * (capLight - MIN_LIGHTEST_L);\n const darkestL = MAX_DARKEST_L - darkSlider * (MAX_DARKEST_L - capDark);\n\n // Helper: resolve hue at position t (applies local shift first, then global grading)\n const hueAt = (t: number) => resolveGradedHue(hue, t, hueGrade, localHueGrade);\n\n // Fast path: skip peak skew logic when balance has no effect.\n // - peak === 0.5: already at the natural gamut peak, nothing to shift\n // - ratio === 0: no chroma at all, boundary shape is irrelevant\n // - ratio >= 1: inner triangle equals the boundary triangle, no headroom to slide\n if (peak === 0.5 || ratio === 0 || ratio >= 1) {\n const scale: Oklch[] = [];\n for (let i = 0; i < steps; i++) {\n const t = i / (steps - 1);\n const L = lightestL - t * (lightestL - darkestL);\n let h = hueAt(t);\n // Chroma is shaped by the base hue's boundary to keep the curve smooth.\n // The shifted hue's boundary is used as a final in-gamut clamp only —\n // this prevents spikes when the shifted hue has more available chroma\n // than the base (e.g. blue → pink passing through the purple region).\n let C = Math.min(maxChroma(L, hue, gamut) * ratio, maxChroma(L, h, gamut));\n\n if (hueGrade) {\n const overlay = applyGradingOverlay(C, h, L, t, hueGrade, gamut);\n C = overlay.C;\n h = overlay.h;\n }\n\n scale.push({ L, C, h });\n }\n return scale;\n }\n\n // ── Peak skew logic ──\n // Warp the parameter t so the boundary peak appears at a shifted position.\n // Endpoints stay fixed (warp(0)=0, warp(1)=1), only the peak moves.\n\n // 1. Sample boundary to find natural peak and valid shift range\n const N = 100;\n let peakT = 0.5;\n let peakBoundaryC = 0;\n const boundarySamples: { t: number; C: number }[] = [];\n\n for (let i = 0; i <= N; i++) {\n const t = i / N;\n const L = lightestL - t * (lightestL - darkestL);\n // Sample the base hue's boundary — the same reference used when building\n // the warp below. Using the shifted hue here would skew peakT and the\n // valid range toward a hue-specific boundary shape, inconsistent with\n // how chroma is actually computed in step 4.\n const C = maxChroma(L, hue, gamut);\n boundarySamples.push({ t, C });\n if (C > peakBoundaryC) {\n peakBoundaryC = C;\n peakT = t;\n }\n }\n\n // 2. Find valid range: where boundary can accommodate the inner peak height\n const innerPeakC = peakBoundaryC * ratio;\n let validMinT = peakT;\n let validMaxT = peakT;\n\n for (const { t, C } of boundarySamples) {\n if (C >= innerPeakC - 1e-6) {\n if (t < validMinT) validMinT = t;\n if (t > validMaxT) validMaxT = t;\n }\n }\n\n // 3. Map chroma.balance (0–1) to valid range, normalized so 0.5 → peakT\n let targetT: number;\n if (peak <= 0.5) {\n targetT = validMinT + (peak / 0.5) * (peakT - validMinT);\n } else {\n targetT = peakT + ((peak - 0.5) / 0.5) * (validMaxT - peakT);\n }\n\n // Safety: if the piecewise mapping produces a degenerate targetT (outside\n // (0, 1)), fall back to the natural peak. This can occur at floating-point\n // boundaries rather than from any single expected input combination.\n if (targetT <= 0 || targetT >= 1) {\n targetT = peakT;\n }\n\n // 4. Build scale with piecewise-linear warp: targetT → peakT\n const scale: Oklch[] = [];\n for (let i = 0; i < steps; i++) {\n const t = i / (steps - 1);\n const L = lightestL - t * (lightestL - darkestL);\n let h = hueAt(t);\n\n // Piecewise-linear warp: maps 0→0, targetT→peakT, 1→1.\n // Two segments scale t independently so the boundary peak (at peakT in\n // warp space) lands at targetT in the output — endpoints stay fixed.\n let tWarped: number;\n if (t <= targetT) {\n tWarped = t * (peakT / targetT);\n } else {\n tWarped = peakT + (t - targetT) * ((1 - peakT) / (1 - targetT));\n }\n\n const Lwarped = lightestL - tWarped * (lightestL - darkestL);\n // Use the base hue for the warped chroma lookup — consistent with step 1\n // and the fast path. The warp is purely a lightness operation; mixing in\n // the shifted hue at tWarped would introduce cross-position hue artifacts.\n const warpedC = maxChroma(Lwarped, hue, gamut) * ratio;\n // Clamp to the shifted hue's actual boundary at this L: the in-gamut\n // guarantee for the final color { L, C, h }.\n const boundaryC = maxChroma(L, h, gamut);\n let C = Math.min(warpedC, boundaryC);\n\n if (hueGrade) {\n const overlay = applyGradingOverlay(C, h, L, t, hueGrade, gamut);\n C = overlay.C;\n h = overlay.h;\n }\n\n scale.push({ L, C, h });\n }\n\n return scale;\n}\n","import type { Hex, Oklch, Gamut } from \"../types.js\";\nimport {\n hexToOklch,\n oklchToSrgb,\n oklchToP3,\n oklchToHex,\n} from \"../conversions/pipeline.js\";\nimport { isInGamut } from \"../gamut/check.js\";\nimport { gamutMap } from \"../gamut/map.js\";\nimport { maxChroma } from \"../gamut/max-chroma.js\";\n\n/**\n * Result of resolving a color into scale-ready parameters.\n */\nexport interface ResolvedColor {\n /** The final OKLCH color, guaranteed in-gamut for the target gamut. */\n readonly oklch: Oklch;\n /** Hex representation (sRGB-clamped if the resolved color exceeds sRGB). */\n readonly hex: Hex;\n /** Whether the input was outside the target gamut and was remapped. */\n readonly wasRemapped: boolean;\n /** The original OKLCH before gamut mapping (identical to oklch if in-gamut). */\n readonly original: Oklch;\n /** Chroma lost during gamut mapping (0 if in-gamut). */\n readonly chromaShift: number;\n /** Hue from the resolved color. */\n readonly hue: number;\n /** Chroma as a fraction of the gamut boundary at this L/h (0–1). */\n readonly chromaRatio: number;\n}\n\n/**\n * Resolve a color (hex or OKLCH) into scale-ready parameters.\n *\n * If the color is outside the target gamut, it is perceptually mapped to the\n * nearest in-gamut color (chroma reduction at fixed L and h). The result\n * includes the derived hue and chromaRatio.\n *\n * Hex input is always valid sRGB, so `wasRemapped` will be false for hex\n * with gamut=\"srgb\". OKLCH input may be out of gamut and will be mapped.\n *\n * @param input A hex string (#RGB, #RRGGBB) or an OKLCH color.\n * @param isP3 Use Display P3 gamut instead of sRGB (default: false).\n */\nexport function resolveColor(\n input: Hex | Oklch,\n isP3: boolean = false,\n): ResolvedColor {\n const gamut: Gamut = isP3 ? \"display-p3\" : \"srgb\";\n const isHex = typeof input === \"string\";\n const original: Oklch = isHex ? hexToOklch(input) : input;\n\n // Hex encodes valid sRGB by definition, and sRGB ⊂ P3, so hex input\n // is always in-gamut for both supported gamuts. Skipping the round-trip\n // check avoids false negatives from floating-point drift.\n let inGamut: boolean;\n if (isHex) {\n inGamut = true;\n } else {\n const rgb =\n gamut === \"display-p3\" ? oklchToP3(original) : oklchToSrgb(original);\n inGamut = isInGamut(rgb);\n }\n\n const oklch = inGamut ? original : gamutMap(original, gamut);\n\n const boundary = maxChroma(oklch.L, oklch.h, gamut);\n const chromaRatio = boundary > 0 ? oklch.C / boundary : 0;\n\n return {\n oklch,\n hex: oklchToHex(oklch),\n wasRemapped: !inGamut,\n original,\n chromaShift: original.C - oklch.C,\n hue: oklch.h,\n chromaRatio: Math.min(1, chromaRatio),\n };\n}\n","/**\n * Dynamic range resolution — maps slider values (0–1) to OKLCH lightness\n * bounds for the lightest and darkest steps of a color scale.\n */\n\nimport { MIN_LIGHTEST_L, MAX_DARKEST_L } from \"../config.js\";\n\n/**\n * Resolve a whites slider value (0–1) to an OKLCH lightness.\n * slider 0 → L = MIN_LIGHTEST_L (0.96), slider 1 → L = 1.0 (pure white)\n */\nexport function resolveLightest(slider: number): number {\n const s = Math.max(0, Math.min(1, slider));\n return MIN_LIGHTEST_L + s * (1.0 - MIN_LIGHTEST_L);\n}\n\n/**\n * Resolve a darks slider value (0–1) to an OKLCH lightness.\n * slider 0 → L = MAX_DARKEST_L (0.16), slider 1 → L = 0.0 (pure black)\n */\nexport function resolveDarkest(slider: number): number {\n const s = Math.max(0, Math.min(1, slider));\n return MAX_DARKEST_L * (1 - s);\n}\n\n/**\n * Map an OKLCH lightness to a normalized scale position (0–1).\n * 0 = lightest end, 1 = darkest end.\n *\n * Inverse of the lightness interpolation inside generateScale.\n * Useful for deriving chromaPeak from a key color's lightness.\n */\nexport function lightnessToScaleT(L: number, lightestL: number, darkestL: number): number {\n const range = lightestL - darkestL;\n if (range <= 0) return 0.5;\n return Math.max(0, Math.min(1, (lightestL - L) / range));\n}\n","import type { Hex, Oklch } from \"../types.js\";\nimport { resolveColor } from \"./resolve-color.js\";\nimport { lightnessToScaleT, resolveLightest, resolveDarkest } from \"./dynamic-range.js\";\nimport { DEFAULT_SCALE_STEPS } from \"../config.js\";\n\n/**\n * The result of deriving scale parameters from a key color.\n *\n * Spread `hue` and `chroma` directly into ScaleOptions, then use\n * `stepIndex` to locate the key color's position in the generated scale.\n */\nexport interface KeyColorResult {\n /** Derived hue angle — use directly as ScaleOptions.hue. */\n readonly hue: number;\n /**\n * Derived chroma shape — use directly as ScaleOptions.chroma.\n * - `amount`: how saturated the scale is (0–1, relative to gamut boundary).\n * - `balance`: where in the scale the key color's lightness falls (0 = lightest, 1 = darkest).\n */\n readonly chroma: { readonly amount: number; readonly balance: number };\n /** The step index in a scale of `steps` length where this color lands. */\n readonly stepIndex: number;\n /** Hex representation of the resolved color (sRGB-clamped if necessary). */\n readonly hex: Hex;\n /** The final OKLCH color, guaranteed in-gamut for the target gamut. */\n readonly oklch: Oklch;\n /** Whether the input was outside the target gamut and was remapped. */\n readonly wasRemapped: boolean;\n /** The original OKLCH before gamut mapping (identical to oklch if in-gamut). */\n readonly original: Oklch;\n}\n\n/**\n * Derive scale parameters from a known color.\n *\n * Given a hex or OKLCH color, returns the `hue` and `chroma` values\n * ready to spread into ScaleOptions. The chroma balance is derived from\n * where the color's lightness falls within the scale's lightness range,\n * so the chroma distribution is centered around the key color's position.\n *\n * @param color A hex string (#RGB or #RRGGBB) or an OKLCH color object.\n * @param options Scale context — must match the ScaleOptions you will use.\n * `contrast` values are slider values (0–1), same as ScaleOptions.contrast.\n * `steps` is the number of steps in the scale (default: 26).\n *\n * @example\n * const key = keyColor('#3B82F6');\n * const scale = generateScale({ hue: key.hue, chroma: key.chroma });\n * const matchedHex = oklchToHex(scale[key.stepIndex]);\n */\nexport function keyColor(\n color: Hex | Oklch,\n options?: {\n readonly isP3?: boolean;\n readonly contrast?: { readonly light?: number; readonly dark?: number };\n readonly steps?: number;\n },\n): KeyColorResult {\n const { isP3 = false, contrast, steps = DEFAULT_SCALE_STEPS } = options ?? {};\n const resolved = resolveColor(color, isP3);\n const lightestL = resolveLightest(contrast?.light ?? 1);\n const darkestL = resolveDarkest(contrast?.dark ?? 1);\n const balance = lightnessToScaleT(resolved.oklch.L, lightestL, darkestL);\n const stepIndex = Math.round(balance * Math.max(0, steps - 1));\n\n return {\n hue: resolved.hue,\n chroma: { amount: resolved.chromaRatio, balance },\n stepIndex,\n hex: resolved.hex,\n oklch: resolved.oklch,\n wasRemapped: resolved.wasRemapped,\n original: resolved.original,\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/scale/generate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAuErD,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxE;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,YAAiB,GAAG,KAAK,EAAE,CA6IjE"}
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/scale/generate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AA0ErD,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxE;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,YAAiB,GAAG,KAAK,EAAE,CAoJjE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newtonedev/colors",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "Color scale engine — produces accessible color scales from declarative parameters",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",