@xivdyetools/color-blending 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # @xivdyetools/color-blending
2
+
3
+ > Six color blending algorithms (RGB, LAB, OKLAB, RYB, HSL, Spectral/Kubelka-Munk) for the XIV Dye Tools ecosystem.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@xivdyetools/color-blending)](https://www.npmjs.com/package/@xivdyetools/color-blending)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Overview
9
+
10
+ `@xivdyetools/color-blending` provides six distinct color blending algorithms, each producing different results for the same pair of colors. Used by the Mixer command and gradient interpolation in XIV Dye Tools bots.
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ npm install @xivdyetools/color-blending
16
+ ```
17
+
18
+ ## Blending Modes
19
+
20
+ | Mode | Name | Description |
21
+ |------|------|-------------|
22
+ | `rgb` | RGB | Simple additive channel averaging (default) |
23
+ | `lab` | LAB | Perceptually uniform CIELAB blending |
24
+ | `oklab` | OKLAB | Modern perceptual — fixes LAB's blue→purple issue |
25
+ | `ryb` | RYB | Traditional artist's color wheel (blue + yellow = green) |
26
+ | `hsl` | HSL | Hue-Saturation-Lightness interpolation |
27
+ | `spectral` | Spectral | Kubelka-Munk physics simulation (paint-like mixing) |
28
+
29
+ ## Usage
30
+
31
+ ```typescript
32
+ import { blendColors, BLENDING_MODES, isValidBlendingMode } from '@xivdyetools/color-blending';
33
+
34
+ // Blend two colors (equal 50/50 mix)
35
+ const result = blendColors('#FF0000', '#0000FF', 'oklab');
36
+ console.log(result.hex); // → '#C2007E' (perceptually balanced purple)
37
+ console.log(result.rgb); // → { r: 194, g: 0, b: 126 }
38
+
39
+ // Adjust blend ratio (0.0 = all first, 1.0 = all second)
40
+ const mostly_red = blendColors('#FF0000', '#0000FF', 'oklab', 0.25);
41
+
42
+ // Compare all modes
43
+ for (const mode of BLENDING_MODES) {
44
+ const blend = blendColors('#FF0000', '#FFFF00', mode.value);
45
+ console.log(`${mode.name}: ${blend.hex} — ${mode.description}`);
46
+ }
47
+
48
+ // Validate user input
49
+ if (isValidBlendingMode(userInput)) {
50
+ const result = blendColors(color1, color2, userInput);
51
+ }
52
+ ```
53
+
54
+ ### Why Different Modes Produce Different Results
55
+
56
+ ```
57
+ Red (#FF0000) + Blue (#0000FF):
58
+ RGB: #7F007F (dark purple — channel averaging)
59
+ LAB: #CA0088 (magenta — perceptual, but blue bias)
60
+ OKLAB: #C2007E (magenta — perceptual, corrected)
61
+ RYB: #800080 (purple — artist color wheel)
62
+ HSL: #FF00FF (bright magenta — hue rotation)
63
+ Spectral: #6A1B9A (deep purple — physics-based paint mixing)
64
+ ```
65
+
66
+ ## API
67
+
68
+ ### Core
69
+
70
+ - `blendColors(hex1, hex2, mode, ratio?)` — Blend two colors. Returns `BlendResult` (`{ hex, rgb }`).
71
+ - `getBlendingModeDescription(mode)` — Returns human-readable description for a mode.
72
+
73
+ ### Validation
74
+
75
+ - `isValidBlendingMode(mode)` — Type guard: checks if a string is a valid `BlendingMode`.
76
+ - `BLENDING_MODES` — Array of `{ value, name, description }` for all modes.
77
+
78
+ ### Color Conversions
79
+
80
+ - `rgbToLab(rgb)` — Convert RGB to CIELAB color space.
81
+
82
+ ### Types
83
+
84
+ | Type | Description |
85
+ |------|-------------|
86
+ | `BlendingMode` | `'rgb' \| 'lab' \| 'oklab' \| 'ryb' \| 'hsl' \| 'spectral'` |
87
+ | `BlendResult` | `{ hex: string; rgb: RGB }` |
88
+ | `RGB` | `{ r: number; g: number; b: number }` (0–255) |
89
+ | `LAB` | `{ l: number; a: number; b: number }` (CIELAB) |
90
+ | `HSL` | `{ h: number; s: number; l: number }` (0–360, 0–1, 0–1) |
91
+
92
+ ## Dependencies
93
+
94
+ | Package | Purpose |
95
+ |---------|---------|
96
+ | `@xivdyetools/core` | `ColorService` for hex↔RGB conversions |
97
+
98
+ ## License
99
+
100
+ MIT
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Color Blending — Six algorithms for mixing two colors.
3
+ *
4
+ * Blending Modes:
5
+ * - RGB: Simple additive channel averaging
6
+ * - LAB: Perceptually uniform CIELAB blending
7
+ * - OKLAB: Modern perceptual (fixes LAB blue→purple issue)
8
+ * - RYB: Traditional artist's color wheel
9
+ * - HSL: Hue-Saturation-Lightness interpolation
10
+ * - Spectral: Kubelka-Munk physics simulation
11
+ */
12
+ import type { BlendResult, BlendingMode } from './types.js';
13
+ /**
14
+ * Blend two colors using the specified blending mode.
15
+ *
16
+ * @param hex1 - First color hex code (with or without #)
17
+ * @param hex2 - Second color hex code (with or without #)
18
+ * @param mode - Blending algorithm to use
19
+ * @param ratio - 0.0 = all hex1, 0.5 = equal mix, 1.0 = all hex2
20
+ */
21
+ export declare function blendColors(hex1: string, hex2: string, mode: BlendingMode, ratio?: number): BlendResult;
22
+ /**
23
+ * Get a human-readable description of a blending mode.
24
+ */
25
+ export declare function getBlendingModeDescription(mode: BlendingMode): string;
26
+ //# sourceMappingURL=blending.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blending.d.ts","sourceRoot":"","sources":["../src/blending.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAiB,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAqB3E;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,YAAY,EAClB,KAAK,GAAE,MAAY,GAClB,WAAW,CAkCb;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAUrE"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Color Blending — Six algorithms for mixing two colors.
3
+ *
4
+ * Blending Modes:
5
+ * - RGB: Simple additive channel averaging
6
+ * - LAB: Perceptually uniform CIELAB blending
7
+ * - OKLAB: Modern perceptual (fixes LAB blue→purple issue)
8
+ * - RYB: Traditional artist's color wheel
9
+ * - HSL: Hue-Saturation-Lightness interpolation
10
+ * - Spectral: Kubelka-Munk physics simulation
11
+ */
12
+ import { ColorService } from '@xivdyetools/core';
13
+ import { rgbToLab, labToRgb, rgbToOklab, oklabToRgb, rgbToRyb, rybToRgb, rgbToHsl, hslToRgb, rgbToReflectance, reflectanceToRgb, reflectanceToKS, ksToReflectance, rgbToHex, } from './conversions.js';
14
+ // ============================================================================
15
+ // Public API
16
+ // ============================================================================
17
+ /**
18
+ * Blend two colors using the specified blending mode.
19
+ *
20
+ * @param hex1 - First color hex code (with or without #)
21
+ * @param hex2 - Second color hex code (with or without #)
22
+ * @param mode - Blending algorithm to use
23
+ * @param ratio - 0.0 = all hex1, 0.5 = equal mix, 1.0 = all hex2
24
+ */
25
+ export function blendColors(hex1, hex2, mode, ratio = 0.5) {
26
+ const h1 = hex1.startsWith('#') ? hex1 : `#${hex1}`;
27
+ const h2 = hex2.startsWith('#') ? hex2 : `#${hex2}`;
28
+ const t = Math.max(0, Math.min(1, ratio));
29
+ const rgb1 = ColorService.hexToRgb(h1);
30
+ const rgb2 = ColorService.hexToRgb(h2);
31
+ let blendedRgb;
32
+ switch (mode) {
33
+ case 'rgb':
34
+ blendedRgb = blendRGB(rgb1, rgb2, t);
35
+ break;
36
+ case 'lab':
37
+ blendedRgb = blendLAB(rgb1, rgb2, t);
38
+ break;
39
+ case 'oklab':
40
+ blendedRgb = blendOKLAB(rgb1, rgb2, t);
41
+ break;
42
+ case 'ryb':
43
+ blendedRgb = blendRYB(rgb1, rgb2, t);
44
+ break;
45
+ case 'hsl':
46
+ blendedRgb = blendHSL(rgb1, rgb2, t);
47
+ break;
48
+ case 'spectral':
49
+ blendedRgb = blendSpectral(rgb1, rgb2, t);
50
+ break;
51
+ default:
52
+ blendedRgb = blendRGB(rgb1, rgb2, t);
53
+ }
54
+ return { hex: rgbToHex(blendedRgb), rgb: blendedRgb };
55
+ }
56
+ /**
57
+ * Get a human-readable description of a blending mode.
58
+ */
59
+ export function getBlendingModeDescription(mode) {
60
+ const descriptions = {
61
+ rgb: 'Simple additive channel averaging',
62
+ lab: 'Perceptually uniform CIELAB blending',
63
+ oklab: 'Modern perceptual (fixes LAB blue→purple)',
64
+ ryb: "Traditional artist's color wheel",
65
+ hsl: 'Hue-Saturation-Lightness interpolation',
66
+ spectral: 'Kubelka-Munk pigment simulation',
67
+ };
68
+ return descriptions[mode];
69
+ }
70
+ // ============================================================================
71
+ // Blend Implementations
72
+ // ============================================================================
73
+ function blendRGB(rgb1, rgb2, t) {
74
+ return {
75
+ r: Math.round(rgb1.r * (1 - t) + rgb2.r * t),
76
+ g: Math.round(rgb1.g * (1 - t) + rgb2.g * t),
77
+ b: Math.round(rgb1.b * (1 - t) + rgb2.b * t),
78
+ };
79
+ }
80
+ function blendLAB(rgb1, rgb2, t) {
81
+ const lab1 = rgbToLab(rgb1);
82
+ const lab2 = rgbToLab(rgb2);
83
+ const blended = {
84
+ l: lab1.l * (1 - t) + lab2.l * t,
85
+ a: lab1.a * (1 - t) + lab2.a * t,
86
+ b: lab1.b * (1 - t) + lab2.b * t,
87
+ };
88
+ return labToRgb(blended);
89
+ }
90
+ function blendOKLAB(rgb1, rgb2, t) {
91
+ const ok1 = rgbToOklab(rgb1);
92
+ const ok2 = rgbToOklab(rgb2);
93
+ return oklabToRgb({
94
+ L: ok1.L * (1 - t) + ok2.L * t,
95
+ a: ok1.a * (1 - t) + ok2.a * t,
96
+ b: ok1.b * (1 - t) + ok2.b * t,
97
+ });
98
+ }
99
+ function blendRYB(rgb1, rgb2, t) {
100
+ const ryb1 = rgbToRyb(rgb1);
101
+ const ryb2 = rgbToRyb(rgb2);
102
+ return rybToRgb({
103
+ r: ryb1.r * (1 - t) + ryb2.r * t,
104
+ y: ryb1.y * (1 - t) + ryb2.y * t,
105
+ b: ryb1.b * (1 - t) + ryb2.b * t,
106
+ });
107
+ }
108
+ function blendHSL(rgb1, rgb2, t) {
109
+ const hsl1 = rgbToHsl(rgb1);
110
+ const hsl2 = rgbToHsl(rgb2);
111
+ // Shortest-arc hue interpolation
112
+ let hueDiff = hsl2.h - hsl1.h;
113
+ if (hueDiff > 180)
114
+ hueDiff -= 360;
115
+ if (hueDiff < -180)
116
+ hueDiff += 360;
117
+ let blendedH = hsl1.h + hueDiff * t;
118
+ if (blendedH < 0)
119
+ blendedH += 360;
120
+ if (blendedH >= 360)
121
+ blendedH -= 360;
122
+ const blended = {
123
+ h: blendedH,
124
+ s: hsl1.s * (1 - t) + hsl2.s * t,
125
+ l: hsl1.l * (1 - t) + hsl2.l * t,
126
+ };
127
+ return hslToRgb(blended);
128
+ }
129
+ function blendSpectral(rgb1, rgb2, t) {
130
+ const ref1 = rgbToReflectance(rgb1);
131
+ const ref2 = rgbToReflectance(rgb2);
132
+ return reflectanceToRgb({
133
+ r: kubelkaMunkMix(ref1.r, ref2.r, t),
134
+ g: kubelkaMunkMix(ref1.g, ref2.g, t),
135
+ b: kubelkaMunkMix(ref1.b, ref2.b, t),
136
+ });
137
+ }
138
+ function kubelkaMunkMix(r1, r2, t) {
139
+ const ks1 = reflectanceToKS(r1);
140
+ const ks2 = reflectanceToKS(r2);
141
+ return ksToReflectance(ks1 * (1 - t) + ks2 * t);
142
+ }
143
+ //# sourceMappingURL=blending.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blending.js","sourceRoot":"","sources":["../src/blending.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,QAAQ,GACT,MAAM,kBAAkB,CAAC;AAE1B,+EAA+E;AAC/E,aAAa;AACb,+EAA+E;AAE/E;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CACzB,IAAY,EACZ,IAAY,EACZ,IAAkB,EAClB,QAAgB,GAAG;IAEnB,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;IACpD,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;IACpD,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAE1C,MAAM,IAAI,GAAG,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAEvC,IAAI,UAAe,CAAC;IAEpB,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,KAAK;YACR,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACrC,MAAM;QACR,KAAK,KAAK;YACR,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACrC,MAAM;QACR,KAAK,OAAO;YACV,UAAU,GAAG,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACvC,MAAM;QACR,KAAK,KAAK;YACR,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACrC,MAAM;QACR,KAAK,KAAK;YACR,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACrC,MAAM;QACR,KAAK,UAAU;YACb,UAAU,GAAG,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC1C,MAAM;QACR;YACE,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACzC,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;AACxD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,0BAA0B,CAAC,IAAkB;IAC3D,MAAM,YAAY,GAAiC;QACjD,GAAG,EAAE,mCAAmC;QACxC,GAAG,EAAE,sCAAsC;QAC3C,KAAK,EAAE,2CAA2C;QAClD,GAAG,EAAE,kCAAkC;QACvC,GAAG,EAAE,wCAAwC;QAC7C,QAAQ,EAAE,iCAAiC;KAC5C,CAAC;IACF,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED,+EAA+E;AAC/E,wBAAwB;AACxB,+EAA+E;AAE/E,SAAS,QAAQ,CAAC,IAAS,EAAE,IAAS,EAAE,CAAS;IAC/C,OAAO;QACL,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC5C,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC5C,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;KAC7C,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,IAAS,EAAE,IAAS,EAAE,CAAS;IAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,OAAO,GAAQ;QACnB,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC;QAChC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC;QAChC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC;KACjC,CAAC;IACF,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC;AAED,SAAS,UAAU,CAAC,IAAS,EAAE,IAAS,EAAE,CAAS;IACjD,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC7B,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,UAAU,CAAC;QAChB,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;QAC9B,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;QAC9B,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;KAC/B,CAAC,CAAC;AACL,CAAC;AAED,SAAS,QAAQ,CAAC,IAAS,EAAE,IAAS,EAAE,CAAS;IAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,OAAO,QAAQ,CAAC;QACd,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC;QAChC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC;QAChC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC;KACjC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,QAAQ,CAAC,IAAS,EAAE,IAAS,EAAE,CAAS;IAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAE5B,iCAAiC;IACjC,IAAI,OAAO,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC9B,IAAI,OAAO,GAAG,GAAG;QAAE,OAAO,IAAI,GAAG,CAAC;IAClC,IAAI,OAAO,GAAG,CAAC,GAAG;QAAE,OAAO,IAAI,GAAG,CAAC;IAEnC,IAAI,QAAQ,GAAG,IAAI,CAAC,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC;IACpC,IAAI,QAAQ,GAAG,CAAC;QAAE,QAAQ,IAAI,GAAG,CAAC;IAClC,IAAI,QAAQ,IAAI,GAAG;QAAE,QAAQ,IAAI,GAAG,CAAC;IAErC,MAAM,OAAO,GAAQ;QACnB,CAAC,EAAE,QAAQ;QACX,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC;QAChC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC;KACjC,CAAC;IACF,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC;AAED,SAAS,aAAa,CAAC,IAAS,EAAE,IAAS,EAAE,CAAS;IACpD,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACpC,OAAO,gBAAgB,CAAC;QACtB,CAAC,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;QACpC,CAAC,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;QACpC,CAAC,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;KACrC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,cAAc,CAAC,EAAU,EAAE,EAAU,EAAE,CAAS;IACvD,MAAM,GAAG,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;IAChC,MAAM,GAAG,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;IAChC,OAAO,eAAe,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC;AAClD,CAAC"}
@@ -0,0 +1,43 @@
1
+ import type { RGB, LAB, HSL } from './types.js';
2
+ /**
3
+ * RGB to CIELAB conversion.
4
+ * Exported for use in SVG generators that display LAB values.
5
+ */
6
+ export declare function rgbToLab(rgb: RGB): LAB;
7
+ export declare function labToRgb(lab: LAB): RGB;
8
+ export declare function rgbToOklab(rgb: RGB): {
9
+ L: number;
10
+ a: number;
11
+ b: number;
12
+ };
13
+ export declare function oklabToRgb(oklab: {
14
+ L: number;
15
+ a: number;
16
+ b: number;
17
+ }): RGB;
18
+ export declare function rgbToRyb(rgb: RGB): {
19
+ r: number;
20
+ y: number;
21
+ b: number;
22
+ };
23
+ export declare function rybToRgb(ryb: {
24
+ r: number;
25
+ y: number;
26
+ b: number;
27
+ }): RGB;
28
+ export declare function rgbToHsl(rgb: RGB): HSL;
29
+ export declare function hslToRgb(hsl: HSL): RGB;
30
+ export declare function rgbToReflectance(rgb: RGB): {
31
+ r: number;
32
+ g: number;
33
+ b: number;
34
+ };
35
+ export declare function reflectanceToRgb(ref: {
36
+ r: number;
37
+ g: number;
38
+ b: number;
39
+ }): RGB;
40
+ export declare function reflectanceToKS(r: number): number;
41
+ export declare function ksToReflectance(ks: number): number;
42
+ export declare function rgbToHex(rgb: RGB): string;
43
+ //# sourceMappingURL=conversions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversions.d.ts","sourceRoot":"","sources":["../src/conversions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAMhD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAyBtC;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CA8BtC;AAMD,wBAAgB,UAAU,CAAC,GAAG,EAAE,GAAG,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAwBxE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,GAAG,CAuB1E;AAMD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAwBtE;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,GAAG,CA0BtE;AAMD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CA8BtC;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CA2BtC;AAMD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAE9E;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,GAAG,CAM9E;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAIjD;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAGlD;AAMD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAGzC"}
@@ -0,0 +1,229 @@
1
+ // ============================================================================
2
+ // CIELAB (D65 illuminant)
3
+ // ============================================================================
4
+ /**
5
+ * RGB to CIELAB conversion.
6
+ * Exported for use in SVG generators that display LAB values.
7
+ */
8
+ export function rgbToLab(rgb) {
9
+ let r = rgb.r / 255;
10
+ let g = rgb.g / 255;
11
+ let b = rgb.b / 255;
12
+ // sRGB to linear
13
+ r = r > 0.04045 ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92;
14
+ g = g > 0.04045 ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92;
15
+ b = b > 0.04045 ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92;
16
+ // Convert to XYZ (D65 illuminant)
17
+ let x = (r * 0.4124564 + g * 0.3575761 + b * 0.1804375) / 0.95047;
18
+ let y = r * 0.2126729 + g * 0.7151522 + b * 0.072175;
19
+ let z = (r * 0.0193339 + g * 0.119192 + b * 0.9503041) / 1.08883;
20
+ // XYZ to LAB
21
+ x = x > 0.008856 ? Math.pow(x, 1 / 3) : 7.787 * x + 16 / 116;
22
+ y = y > 0.008856 ? Math.pow(y, 1 / 3) : 7.787 * y + 16 / 116;
23
+ z = z > 0.008856 ? Math.pow(z, 1 / 3) : 7.787 * z + 16 / 116;
24
+ return {
25
+ l: 116 * y - 16,
26
+ a: 500 * (x - y),
27
+ b: 200 * (y - z),
28
+ };
29
+ }
30
+ export function labToRgb(lab) {
31
+ let y = (lab.l + 16) / 116;
32
+ let x = lab.a / 500 + y;
33
+ let z = y - lab.b / 200;
34
+ const y3 = y * y * y;
35
+ const x3 = x * x * x;
36
+ const z3 = z * z * z;
37
+ y = y3 > 0.008856 ? y3 : (y - 16 / 116) / 7.787;
38
+ x = x3 > 0.008856 ? x3 : (x - 16 / 116) / 7.787;
39
+ z = z3 > 0.008856 ? z3 : (z - 16 / 116) / 7.787;
40
+ x *= 0.95047;
41
+ z *= 1.08883;
42
+ let r = x * 3.2404542 + y * -1.5371385 + z * -0.4985314;
43
+ let g = x * -0.969266 + y * 1.8760108 + z * 0.041556;
44
+ let b = x * 0.0556434 + y * -0.2040259 + z * 1.0572252;
45
+ // Linear to sRGB
46
+ r = r > 0.0031308 ? 1.055 * Math.pow(r, 1 / 2.4) - 0.055 : 12.92 * r;
47
+ g = g > 0.0031308 ? 1.055 * Math.pow(g, 1 / 2.4) - 0.055 : 12.92 * g;
48
+ b = b > 0.0031308 ? 1.055 * Math.pow(b, 1 / 2.4) - 0.055 : 12.92 * b;
49
+ return {
50
+ r: Math.round(Math.max(0, Math.min(255, r * 255))),
51
+ g: Math.round(Math.max(0, Math.min(255, g * 255))),
52
+ b: Math.round(Math.max(0, Math.min(255, b * 255))),
53
+ };
54
+ }
55
+ // ============================================================================
56
+ // OKLAB (Björn Ottosson, 2020)
57
+ // ============================================================================
58
+ export function rgbToOklab(rgb) {
59
+ let r = rgb.r / 255;
60
+ let g = rgb.g / 255;
61
+ let b = rgb.b / 255;
62
+ // sRGB to linear
63
+ r = r > 0.04045 ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92;
64
+ g = g > 0.04045 ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92;
65
+ b = b > 0.04045 ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92;
66
+ // Linear RGB to LMS
67
+ const l = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b;
68
+ const m = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b;
69
+ const s = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b;
70
+ const l_ = Math.cbrt(l);
71
+ const m_ = Math.cbrt(m);
72
+ const s_ = Math.cbrt(s);
73
+ return {
74
+ L: 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_,
75
+ a: 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_,
76
+ b: 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_,
77
+ };
78
+ }
79
+ export function oklabToRgb(oklab) {
80
+ const l_ = oklab.L + 0.3963377774 * oklab.a + 0.2158037573 * oklab.b;
81
+ const m_ = oklab.L - 0.1055613458 * oklab.a - 0.0638541728 * oklab.b;
82
+ const s_ = oklab.L - 0.0894841775 * oklab.a - 1.291485548 * oklab.b;
83
+ const l = l_ * l_ * l_;
84
+ const m = m_ * m_ * m_;
85
+ const s = s_ * s_ * s_;
86
+ let r = +4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s;
87
+ let g = -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s;
88
+ let b = -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s;
89
+ // Linear to sRGB
90
+ r = r > 0.0031308 ? 1.055 * Math.pow(r, 1 / 2.4) - 0.055 : 12.92 * r;
91
+ g = g > 0.0031308 ? 1.055 * Math.pow(g, 1 / 2.4) - 0.055 : 12.92 * g;
92
+ b = b > 0.0031308 ? 1.055 * Math.pow(b, 1 / 2.4) - 0.055 : 12.92 * b;
93
+ return {
94
+ r: Math.round(Math.max(0, Math.min(255, r * 255))),
95
+ g: Math.round(Math.max(0, Math.min(255, g * 255))),
96
+ b: Math.round(Math.max(0, Math.min(255, b * 255))),
97
+ };
98
+ }
99
+ // ============================================================================
100
+ // RYB (Red-Yellow-Blue, approximate)
101
+ // ============================================================================
102
+ export function rgbToRyb(rgb) {
103
+ const r = rgb.r / 255;
104
+ const g = rgb.g / 255;
105
+ const b = rgb.b / 255;
106
+ const w = Math.min(r, g, b);
107
+ const r_ = r - w;
108
+ const g_ = g - w;
109
+ const b_ = b - w;
110
+ const mg = Math.max(r_, g_, b_);
111
+ const y = Math.min(r_, g_);
112
+ const r__ = r_ - y;
113
+ const b__ = (b_ + (g_ - y)) / 2;
114
+ const n = Math.max(r__, y, b__) / Math.max(mg, 0.001);
115
+ return {
116
+ r: r__ / Math.max(n, 0.001) + w,
117
+ y: y / Math.max(n, 0.001) + w,
118
+ b: b__ / Math.max(n, 0.001) + w,
119
+ };
120
+ }
121
+ export function rybToRgb(ryb) {
122
+ const r = ryb.r;
123
+ const y = ryb.y;
124
+ const b = ryb.b;
125
+ const w = Math.min(r, y, b);
126
+ const r_ = r - w;
127
+ const y_ = y - w;
128
+ const b_ = b - w;
129
+ const my = Math.max(r_, y_, b_);
130
+ let g = Math.min(y_, b_);
131
+ const y__ = y_ - g;
132
+ const b__ = b_ - g;
133
+ const r__ = r_ + y__;
134
+ g = g + y__;
135
+ const n = Math.max(r__, g, b__) / Math.max(my, 0.001);
136
+ return {
137
+ r: Math.round(Math.max(0, Math.min(255, (r__ / Math.max(n, 0.001) + w) * 255))),
138
+ g: Math.round(Math.max(0, Math.min(255, (g / Math.max(n, 0.001) + w) * 255))),
139
+ b: Math.round(Math.max(0, Math.min(255, (b__ / Math.max(n, 0.001) + w) * 255))),
140
+ };
141
+ }
142
+ // ============================================================================
143
+ // HSL
144
+ // ============================================================================
145
+ export function rgbToHsl(rgb) {
146
+ const r = rgb.r / 255;
147
+ const g = rgb.g / 255;
148
+ const b = rgb.b / 255;
149
+ const max = Math.max(r, g, b);
150
+ const min = Math.min(r, g, b);
151
+ const l = (max + min) / 2;
152
+ if (max === min) {
153
+ return { h: 0, s: 0, l };
154
+ }
155
+ const d = max - min;
156
+ const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
157
+ let h = 0;
158
+ switch (max) {
159
+ case r:
160
+ h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
161
+ break;
162
+ case g:
163
+ h = ((b - r) / d + 2) / 6;
164
+ break;
165
+ case b:
166
+ h = ((r - g) / d + 4) / 6;
167
+ break;
168
+ }
169
+ return { h: h * 360, s, l };
170
+ }
171
+ export function hslToRgb(hsl) {
172
+ const h = hsl.h / 360;
173
+ const s = hsl.s;
174
+ const l = hsl.l;
175
+ if (s === 0) {
176
+ const v = Math.round(l * 255);
177
+ return { r: v, g: v, b: v };
178
+ }
179
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
180
+ const p = 2 * l - q;
181
+ const hue2rgb = (p, q, t) => {
182
+ if (t < 0)
183
+ t += 1;
184
+ if (t > 1)
185
+ t -= 1;
186
+ if (t < 1 / 6)
187
+ return p + (q - p) * 6 * t;
188
+ if (t < 1 / 2)
189
+ return q;
190
+ if (t < 2 / 3)
191
+ return p + (q - p) * (2 / 3 - t) * 6;
192
+ return p;
193
+ };
194
+ return {
195
+ r: Math.round(hue2rgb(p, q, h + 1 / 3) * 255),
196
+ g: Math.round(hue2rgb(p, q, h) * 255),
197
+ b: Math.round(hue2rgb(p, q, h - 1 / 3) * 255),
198
+ };
199
+ }
200
+ // ============================================================================
201
+ // Kubelka-Munk (Spectral)
202
+ // ============================================================================
203
+ export function rgbToReflectance(rgb) {
204
+ return { r: rgb.r / 255, g: rgb.g / 255, b: rgb.b / 255 };
205
+ }
206
+ export function reflectanceToRgb(ref) {
207
+ return {
208
+ r: Math.round(Math.max(0, Math.min(255, ref.r * 255))),
209
+ g: Math.round(Math.max(0, Math.min(255, ref.g * 255))),
210
+ b: Math.round(Math.max(0, Math.min(255, ref.b * 255))),
211
+ };
212
+ }
213
+ export function reflectanceToKS(r) {
214
+ // K/S = (1-R)² / (2R)
215
+ const R = Math.max(0.001, Math.min(0.999, r));
216
+ return ((1 - R) * (1 - R)) / (2 * R);
217
+ }
218
+ export function ksToReflectance(ks) {
219
+ // R = 1 + K/S - √((K/S)² + 2·K/S)
220
+ return 1 + ks - Math.sqrt(ks * ks + 2 * ks);
221
+ }
222
+ // ============================================================================
223
+ // Utility
224
+ // ============================================================================
225
+ export function rgbToHex(rgb) {
226
+ const toHex = (n) => n.toString(16).padStart(2, '0');
227
+ return `#${toHex(rgb.r)}${toHex(rgb.g)}${toHex(rgb.b)}`;
228
+ }
229
+ //# sourceMappingURL=conversions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversions.js","sourceRoot":"","sources":["../src/conversions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export type { RGB, LAB, HSL, BlendResult, BlendingMode } from './types.js';
2
+ export { BLENDING_MODES, isValidBlendingMode } from './types.js';
3
+ export { blendColors, getBlendingModeDescription } from './blending.js';
4
+ export { rgbToLab } from './conversions.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { BLENDING_MODES, isValidBlendingMode } from './types.js';
2
+ export { blendColors, getBlendingModeDescription } from './blending.js';
3
+ export { rgbToLab } from './conversions.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Available color blending algorithms.
3
+ */
4
+ export type BlendingMode = 'rgb' | 'lab' | 'oklab' | 'ryb' | 'hsl' | 'spectral';
5
+ /**
6
+ * All blending modes with display metadata.
7
+ */
8
+ export declare const BLENDING_MODES: Array<{
9
+ value: BlendingMode;
10
+ name: string;
11
+ description: string;
12
+ }>;
13
+ /**
14
+ * Type guard: check if a string is a valid blending mode.
15
+ */
16
+ export declare function isValidBlendingMode(mode: string): mode is BlendingMode;
17
+ export interface RGB {
18
+ r: number;
19
+ g: number;
20
+ b: number;
21
+ }
22
+ export interface LAB {
23
+ l: number;
24
+ a: number;
25
+ b: number;
26
+ }
27
+ export interface HSL {
28
+ h: number;
29
+ s: number;
30
+ l: number;
31
+ }
32
+ export interface BlendResult {
33
+ hex: string;
34
+ rgb: RGB;
35
+ }
36
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,UAAU,CAAC;AAEhF;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAO5F,CAAC;AAEF;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,YAAY,CAEtE;AAMD,MAAM,WAAW,GAAG;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,GAAG;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,GAAG;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,GAAG,CAAC;CACV"}
package/dist/types.js ADDED
@@ -0,0 +1,21 @@
1
+ // ============================================================================
2
+ // Blending Mode
3
+ // ============================================================================
4
+ /**
5
+ * All blending modes with display metadata.
6
+ */
7
+ export const BLENDING_MODES = [
8
+ { value: 'rgb', name: 'RGB', description: 'Additive channel averaging (default)' },
9
+ { value: 'lab', name: 'LAB', description: 'Perceptually uniform CIELAB blending' },
10
+ { value: 'oklab', name: 'OKLAB', description: 'Modern perceptual (fixes LAB blue→purple)' },
11
+ { value: 'ryb', name: 'RYB', description: "Traditional artist's color wheel" },
12
+ { value: 'hsl', name: 'HSL', description: 'Hue-Saturation-Lightness interpolation' },
13
+ { value: 'spectral', name: 'Spectral', description: 'Kubelka-Munk physics simulation' },
14
+ ];
15
+ /**
16
+ * Type guard: check if a string is a valid blending mode.
17
+ */
18
+ export function isValidBlendingMode(mode) {
19
+ return BLENDING_MODES.some((m) => m.value === mode);
20
+ }
21
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,gBAAgB;AAChB,+EAA+E;AAO/E;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAsE;IAC/F,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,sCAAsC,EAAE;IAClF,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,sCAAsC,EAAE;IAClF,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,2CAA2C,EAAE;IAC3F,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,kCAAkC,EAAE;IAC9E,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,wCAAwC,EAAE;IACpF,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,iCAAiC,EAAE;CACxF,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC;AACtD,CAAC"}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@xivdyetools/color-blending",
3
+ "version": "1.0.0",
4
+ "description": "Six color blending algorithms (RGB, LAB, OKLAB, RYB, HSL, Spectral/Kubelka-Munk) for the XIV Dye Tools ecosystem",
5
+ "author": "XIV Dye Tools",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "main": "dist/index.js",
9
+ "types": "dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md"
19
+ ],
20
+ "sideEffects": false,
21
+ "dependencies": {
22
+ "@xivdyetools/core": "1.17.0"
23
+ },
24
+ "devDependencies": {
25
+ "@vitest/coverage-v8": "^4.0.18",
26
+ "vitest": "^4.0.18"
27
+ },
28
+ "engines": {
29
+ "node": ">=18.0.0"
30
+ },
31
+ "keywords": [
32
+ "xivdyetools",
33
+ "color",
34
+ "blending",
35
+ "kubelka-munk",
36
+ "oklab",
37
+ "typescript"
38
+ ],
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "https://github.com/FlashGalatine/xivdyetools.git",
42
+ "directory": "packages/color-blending"
43
+ },
44
+ "scripts": {
45
+ "build": "tsc -p tsconfig.build.json",
46
+ "type-check": "tsc --noEmit",
47
+ "clean": "rimraf dist coverage",
48
+ "lint": "eslint src",
49
+ "test": "vitest run",
50
+ "test:watch": "vitest",
51
+ "test:coverage": "vitest run --coverage"
52
+ }
53
+ }