@mkbabb/value.js 0.4.0 → 0.4.4

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.
Files changed (84) hide show
  1. package/README.md +128 -9
  2. package/dist/CNAME +1 -0
  3. package/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  4. package/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  5. package/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  6. package/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  7. package/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  8. package/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  9. package/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  10. package/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  11. package/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  12. package/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  13. package/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  14. package/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  15. package/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  16. package/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  17. package/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  18. package/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  19. package/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  20. package/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  21. package/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  22. package/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  23. package/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  24. package/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  25. package/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  26. package/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  27. package/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  28. package/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  29. package/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  30. package/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  31. package/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  32. package/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  33. package/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  34. package/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  35. package/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  36. package/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  37. package/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  38. package/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  39. package/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  40. package/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  41. package/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  42. package/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  43. package/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  44. package/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  45. package/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  46. package/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  47. package/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  48. package/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  49. package/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  50. package/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  51. package/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  52. package/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  53. package/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  54. package/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  55. package/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  56. package/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  57. package/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  58. package/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  59. package/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  60. package/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  61. package/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  62. package/dist/assets/Katex-ClrxLHTj.js +131 -0
  63. package/dist/assets/Katex-rb5Khf8S.css +1 -0
  64. package/dist/assets/favicon-BpOvZXpk.svg +20 -0
  65. package/dist/assets/hsl-hvHpFpJT.js +1 -0
  66. package/dist/assets/hsv-Dw3FShnj.js +1 -0
  67. package/dist/assets/hwb-pA6JoiNj.js +1 -0
  68. package/dist/assets/index-Q19pIqw1.js +32 -0
  69. package/dist/assets/index-VnEkwzsm.css +1 -0
  70. package/dist/assets/kelvin-Csjui27y.js +1 -0
  71. package/dist/assets/lab-DAj67vs8.js +1 -0
  72. package/dist/assets/lch-D_dY1vUG.js +1 -0
  73. package/dist/assets/oklab-BPM7MOIw.js +1 -0
  74. package/dist/assets/oklch-DwTrS_34.js +1 -0
  75. package/dist/assets/rgb-BLbQuf-A.js +1 -0
  76. package/dist/assets/vendor-highlight-sMWp9TLU.js +3 -0
  77. package/dist/assets/vendor-katex-Dehg5p_Y.js +261 -0
  78. package/dist/assets/vendor-prettier-wO8BBsoP.js +166 -0
  79. package/dist/assets/xyz-CX5zPyPG.js +3 -0
  80. package/dist/index.html +18 -0
  81. package/package.json +3 -3
  82. package/dist/value.cjs +0 -8
  83. package/dist/value.d.ts +0 -1995
  84. package/dist/value.js +0 -4917
package/README.md CHANGED
@@ -1,14 +1,18 @@
1
1
  # value.js ![image](demo/color-picker/cube.png)
2
2
 
3
- CSS value units for color, length, angles, & c. Create a moderately-typed value with a unit, like `deg`, `px`, etc.
3
+ CSS value parsing, color theory, and unit conversion. Typed values with units—`deg`, `px`, `rem`, `oklch()`—the core CSS value vocabulary.
4
4
 
5
- [demo 🌈](https://color.babb.dev)
5
+ [demo](https://color.babb.dev)
6
6
 
7
7
  ## Features
8
8
 
9
- - Parse any CSS value: lengths, angles, times, colors, `calc()`, `var()`, gradients
10
- - 10 color spaces: RGB, HSL, HSV, HWB, Lab, LCh, OKLab, OKLCh, XYZ, Kelvin
11
- - Full color space conversion via XYZ hub with gamut mapping
9
+ - Parse any CSS value: lengths, angles, times, colors, `calc()`, `var()`, gradients, transforms
10
+ - **15 color spaces**: RGB, HSL, HSV, HWB, Lab, LCh, OKLab, OKLCh, XYZ, Kelvin, sRGB-linear, Display P3, Adobe RGB, ProPhoto RGB, Rec. 2020
11
+ - Color space conversion via **XYZ hub** with analytical gamut mapping (Ottosson's algorithm)
12
+ - CSS Color Level 4 support: `color()`, `color-mix()`, relative color syntax
13
+ - CSS math functions: `calc()`, `min()`, `max()`, `clamp()`, trig, exponential
14
+ - 30+ easing functions: cubic-bezier, stepped, linear(), bounce, sine, expo
15
+ - 2D/3D matrix decomposition with quaternion slerp interpolation
12
16
  - Normalize, interpolate, and convert between units
13
17
 
14
18
  ## Install
@@ -20,14 +24,129 @@ npm install @mkbabb/value.js
20
24
  ## Usage
21
25
 
22
26
  ```ts
23
- import { ValueUnit, FunctionValue } from "@mkbabb/value.js";
27
+ import {
28
+ parseCSSValue,
29
+ parseCSSColor,
30
+ ValueUnit,
31
+ FunctionValue,
32
+ } from "@mkbabb/value.js";
24
33
  ```
25
34
 
26
35
  ## Build
27
36
 
28
37
  ```bash
29
- npm run build # library → dist/
38
+ npm run build # library → dist/value.js + value.cjs + value.d.ts
30
39
  npm run gh-pages # demo → dist/
31
- npm run dev # dev server on :8080
32
- npm test # vitest
40
+ npm run dev # dev server (Vite default port)
41
+ npm test # vitest (1372 tests)
42
+ npm run test:e2e # playwright (desktop + mobile)
33
43
  ```
44
+
45
+ ## Structure
46
+
47
+ ```
48
+ src/
49
+ ├── index.ts # barrel exports (~200 symbols)
50
+ ├── math.ts # lerp, bezier, clamp, scale, deCasteljau
51
+ ├── easing.ts # CSS timing functions (cubic-bezier, stepped, linear())
52
+ ├── utils.ts # clone, memoize, debounce, RAF, case conversion
53
+ ├── parsing/ # @mkbabb/parse-that combinators for CSS values
54
+ │ ├── index.ts # parseCSSValue, gradients, transforms, var()
55
+ │ ├── units.ts # length, angle, time, frequency, resolution, flex, %
56
+ │ ├── color.ts # 15 spaces, hex, named, color-mix(), relative syntax
57
+ │ ├── math.ts # calc() AST, min/max/clamp, trig, exp
58
+ │ ├── utils.ts # istring, number, none, tryParse helpers
59
+ │ └── grammars/ # BBNF spec grammars (used in equivalence tests)
60
+ ├── units/ # core value classes + unit definitions
61
+ │ ├── index.ts # ValueUnit, FunctionValue, ValueArray
62
+ │ ├── constants.ts # unit arrays, 630+ CSS property names
63
+ │ ├── utils.ts # unit conversion (px, deg, ms, Hz, dpi)
64
+ │ ├── normalize.ts # value normalization + interpolation setup
65
+ │ └── color/ # 15 color spaces, conversion, gamut mapping
66
+ │ ├── index.ts # Color<T> base + space classes
67
+ │ ├── constants.ts # ranges, matrices, white points, named colors
68
+ │ ├── matrix.ts # Vec3/Mat3 (row-major, replaces gl-matrix)
69
+ │ ├── utils.ts # conversions via XYZ, mixColors, gamutMap
70
+ │ ├── normalize.ts # color normalization to [0,1], space conversion
71
+ │ ├── gamut.ts # Ottosson analytical sRGB gamut mapping
72
+ │ └── colorFilter.ts # CSS filter solver (SPSA)
73
+ └── transform/
74
+ └── decompose.ts # 2D/3D matrix decomposition, quaternion slerp
75
+
76
+ test/ # vitest unit tests (24 files)
77
+ e2e/ # playwright E2E (14 specs)
78
+ demo/ # Vue 3.5 color picker (reka-ui, Tailwind)
79
+ api/ # Hono + MongoDB palette API (Docker)
80
+ docs/ # color-theory.md, gamut-mapping.md
81
+ assets/docs/ # 10 color space reference pages
82
+ ```
83
+
84
+ ## Color Spaces
85
+
86
+ All conversions route through the **XYZ D65** hub, enabling any-to-any conversion. Perceptual spaces (OKLab, Lab) use D50 natively with Bradford chromatic adaptation where needed.
87
+
88
+ Each color space is documented in [`assets/docs/`](assets/docs/)—historical context, component ranges, conversion functions, and practical applications.
89
+
90
+ ### Gamut Mapping
91
+
92
+ Out-of-gamut colors are mapped using Björn Ottosson's analytical sRGB algorithm: a polynomial initial guess refined by a single Halley's method step (cubic convergence). Significantly faster than CSS Color 4's iterative binary search. Hue is preserved exactly; an adaptive `L0` formula blends between chroma reduction and mid-gray anchoring.
93
+
94
+ See [`docs/gamut-mapping.md`](docs/gamut-mapping.md) for the full treatment.
95
+
96
+ ## Easing
97
+
98
+ 30+ timing functions covering the CSS `<easing-function>` grammar plus bounce and back. `CSSCubicBezier` solves via Newton-Raphson with bisection fallback; `cssLinear()` implements CSS Easing Level 2 piecewise-linear with gap filling per spec; stepped easings support all four jump terms.
99
+
100
+ ## Transforms
101
+
102
+ CSS `matrix()` and `matrix3d()` decomposition per the CSSOM View and CSS Transforms specs. 3D uses Gram-Schmidt orthogonalization + quaternion extraction. `slerp` for rotation interpolation. `interpolateDecomposed()` for full transform blending.
103
+
104
+ ## Palette API
105
+
106
+ The [demo](https://color.babb.dev) is backed by a palette API for saving, sharing, and voting on color palettes. Users register via `POST /sessions`, which mints a UUID token and a four-word slug—no accounts required. Palettes are slug-addressed, votable (atomic toggle), and sortable by popularity or recency. A color name registry lets users propose names for CSS colors; admins approve or reject through a moderation queue.
107
+
108
+ Hono + MongoDB, Dockerized. See [`api/README.md`](api/README.md) for endpoints, schema, and deployment.
109
+
110
+ | Feature | Mechanism |
111
+ | ----------------- | ------------------------------------------------------------------------------------------------------------ |
112
+ | **Sessions** | `POST /sessions` → UUID token + user slug; stored with hashed IP; 30-day TTL |
113
+ | **Palettes** | CRUD by slug; 1–50 color stops with CSS string + optional name + position |
114
+ | **Voting** | `POST /palettes/:slug/vote` — idempotent toggle; unique composite index on `{userSlug, paletteSlug}` |
115
+ | **Color names** | `POST /colors/propose` → admin approval queue → `GET /colors/approved` feeds the demo's custom name registry |
116
+ | **Rate limiting** | 60 reads/min, 10 writes/min per IP (in-memory, rightmost X-Forwarded-For) |
117
+
118
+ ### Palette System Flow (Frontend + API)
119
+
120
+ 1. **Save locally** (`PaletteForm` / `usePaletteStore`): stores palettes in browser storage (`color-palettes`) for instant local recall.
121
+ 2. **Publish** (`PaletteDialog`): ensures a session (`POST /sessions`), then publishes via `POST /palettes` with `X-Session-Token`.
122
+ 3. **Browse + vote** (`Browse` tab): fetches `GET /palettes` and toggles votes with `POST /palettes/:slug/vote` (server maintains atomic vote counts).
123
+ 4. **Suggest color names** (`ColorInput` propose form): ensures session, then submits `POST /colors/propose` for moderation.
124
+ 5. **Admin moderation** (`AdminPanel`): token login (`Authorization: Bearer ...`), queue from `GET /admin/queue`, actions for approve/reject + feature/delete.
125
+
126
+ ### Validation
127
+
128
+ - **API smoke (live backend)**: session creation, publish/list/get, vote toggle, rename, propose, admin queue, approve, feature, delete.
129
+ - **Playwright live integration**: [`e2e/palette-api-live.spec.ts`](e2e/palette-api-live.spec.ts) validates save/publish/vote/propose/admin end-to-end against a real API.
130
+
131
+ ```bash
132
+ # 1) Start API (example)
133
+ MONGODB_URI=mongodb://127.0.0.1:27019/palette-e2e ADMIN_TOKEN=test-admin-token PORT=3100 npm --prefix api run dev
134
+
135
+ # 2) Run live frontend + backend integration
136
+ PALETTE_API_E2E=1 VITE_API_URL=http://127.0.0.1:3100 npx playwright test e2e/palette-api-live.spec.ts --project=desktop
137
+ ```
138
+
139
+ ## Sources, acknowledgements, &c.
140
+
141
+ - Ottosson, B. (2020). [A perceptual color space for image processing](https://bottosson.github.io/posts/oklab/). — OKLab: the perceptual color space used for `color-mix()` and gamut mapping.
142
+ - Ottosson, B. (2021). [sRGB gamut clipping](https://bottosson.github.io/posts/gamutclipping/). — Analytical gamut mapping algorithm (cubic boundary + Halley's method).
143
+ - Atkins Jr., T., Lilley, C., & Verou, L. (2025). [CSS Color Module Level 4](https://www.w3.org/TR/css-color-4/). W3C CRD. — The spec governing all CSS color functions.
144
+ - [CSS Filter Effects Module Level 1](https://www.w3.org/TR/filter-effects/#feColorMatrixElement). W3C. — `feColorMatrix`; basis for the CSS filter solver.
145
+ - Lindbloom, B. [XYZ to Correlated Color Temperature](http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_T.html). — CCT conversion reference.
146
+ - [`@mkbabb/parse-that`](https://github.com/mkbabb/parse-that) — Parser combinators powering the CSS value grammar.
147
+
148
+ See [`docs/color-theory.md`](docs/color-theory.md) for the full bibliography.
149
+
150
+ ## License
151
+
152
+ GPL-3.0-only
package/dist/CNAME ADDED
@@ -0,0 +1 @@
1
+ color.babb.dev
@@ -0,0 +1,131 @@
1
+ import{k as t}from"./vendor-katex-Dehg5p_Y.js";import{C as o,ad as e,o as s,w as b,J as r,V as c}from"./vendor-highlight-sMWp9TLU.js";import{_ as i}from"./index-Q19pIqw1.js";const m="const kelvin2rgb = ({ kelvin, alpha }",y="const rgb2kelvin = ({ r, g, b, alpha }",S="const hsv2hsl = ({ h, s, v, alpha }",E="const hsl2hsv = ({ h, s, l, alpha }",C="const hwb2hsl = ({ h, w, b, alpha }",f="const hsl2hwb = ({ h, s, l, alpha }",z="const rgb2hsl = ({ r, g, b, alpha }",O="function hsl2rgb({ h, s, l, alpha }",P=`function xyz2lab(xyz: XYZColor, toWhitePoint: WhitePoint = "D50"): LABColor {
2
+ const labFunction = (value: number) =>
3
+ value > LAB_EPSILON
4
+ ? Math.cbrt(value)
5
+ : (LAB_KAPPA * value + LAB_OFFSET) / LAB_SCALE_L;
6
+
7
+ const whitePoint = WHITE_POINTS[toWhitePoint];
8
+
9
+ const [x, y, z] = xyzToD50(xyz);
10
+
11
+ // Normalize XYZ values relative to the given white point
12
+ const xr = x / whitePoint[0], yr = y / whitePoint[1], zr = z / whitePoint[2];
13
+
14
+ const fx = labFunction(xr), fy = labFunction(yr), fz = labFunction(zr);
15
+
16
+ // Calculate L*, a*, and b* values
17
+ const l = LAB_SCALE_L * fy - LAB_OFFSET; // L* = 116 * f(Y/Yn) - 16
18
+ const a = LAB_SCALE_A * (fx - fy); // a* = 500 * [f(X/Xn) - f(Y/Yn)]
19
+ const b = LAB_SCALE_B * (fy - fz); // b* = 200 * [f(Y/Yn) - f(Z/Zn)]
20
+
21
+ const lab = new LABColor(
22
+ scale(
23
+ l,
24
+ COLOR_SPACE_RANGES.lab.l.number.min,
25
+ COLOR_SPACE_RANGES.lab.l.number.max,
26
+ ),
27
+ scale(
28
+ a,
29
+ COLOR_SPACE_RANGES.lab.a.number.min,
30
+ COLOR_SPACE_RANGES.lab.a.number.max,
31
+ ),
32
+ scale(
33
+ b,
34
+ COLOR_SPACE_RANGES.lab.b.number.min,
35
+ COLOR_SPACE_RANGES.lab.b.number.max,
36
+ ),
37
+ xyz.alpha,
38
+ );
39
+
40
+ lab.whitePoint = toWhitePoint;
41
+
42
+ return lab;
43
+ }`,p=`function lab2xyz(lab: LABColor): XYZColor {
44
+ const labFunctionXZ = (value: number) =>
45
+ value > LAB_EPSILON_3
46
+ ? value ** 3
47
+ : (LAB_SCALE_L * value - LAB_OFFSET) / LAB_KAPPA;
48
+
49
+ const labFunctionY = (value: number) =>
50
+ value > LAB_KAPPA_EPSILON
51
+ ? ((value + LAB_OFFSET) / LAB_SCALE_L) ** 3
52
+ : value / LAB_KAPPA;
53
+
54
+ const whitePoint = WHITE_POINTS[lab.whitePoint];
55
+
56
+ let { l, a, b, alpha } = lab;
57
+
58
+ l = scale(
59
+ l,
60
+ 0,
61
+ 1,
62
+ COLOR_SPACE_RANGES.lab.l.number.min,
63
+ COLOR_SPACE_RANGES.lab.l.number.max,
64
+ );
65
+ a = scale(
66
+ a,
67
+ 0,
68
+ 1,
69
+ COLOR_SPACE_RANGES.lab.a.number.min,
70
+ COLOR_SPACE_RANGES.lab.a.number.max,
71
+ );
72
+ b = scale(
73
+ b,
74
+ 0,
75
+ 1,
76
+ COLOR_SPACE_RANGES.lab.b.number.min,
77
+ COLOR_SPACE_RANGES.lab.b.number.max,
78
+ );
79
+
80
+ // Inverse of the xyz2lab function
81
+ const fy = (l + LAB_OFFSET) / LAB_SCALE_L; // f(Y/Yn) = (L* + 16) / 116
82
+ const fx = a / LAB_SCALE_A + fy; // f(X/Xn) = a* / 500 + f(Y/Yn)
83
+ const fz = fy - b / LAB_SCALE_B; // f(Z/Zn) = f(Y/Yn) - b* / 200
84
+
85
+ // Apply the inverse lab function to each value
86
+ const [xr, yr, zr] = [labFunctionXZ(fx), labFunctionY(l), labFunctionXZ(fz)];
87
+
88
+ // Denormalize XYZ values relative to the given white point
89
+ let x = xr * whitePoint[0], y = yr * whitePoint[1], z = zr * whitePoint[2];
90
+
91
+ const xyz = new XYZColor(x, y, z, alpha);
92
+ xyz.whitePoint = lab.whitePoint;
93
+
94
+ // All XYZ outputs are relative to D65:
95
+ [x, y, z] = xyzToD65(xyz);
96
+
97
+ xyz.whitePoint = "D65";
98
+
99
+ xyz.x = x;
100
+ xyz.y = y;
101
+ xyz.z = z;
102
+
103
+ return xyz;
104
+ }`,v="function rgb2xyz({ r, g, b, alpha }",R=`const xyz2rgb = (
105
+ { x, y, z, alpha }`,k="function lch2lab({ l, c, h, alpha }",B="function lab2lch({ l, a, b, alpha }",w="function oklab2xyz({ l, a, b, alpha }",Y=`function xyz2oklab(xyz: XYZColor): OKLABColor {
106
+ const { x, y, z } = xyz;
107
+
108
+ // Convert XYZ to linear LMS
109
+ const lmsLinear = transformMat3([x, y, z] as Vec3, XYZ_TO_LMS_MATRIX);
110
+
111
+ // Apply non-linearity (linear LMS to LMS)
112
+ const lms: Vec3 = [Math.cbrt(lmsLinear[0]), Math.cbrt(lmsLinear[1]), Math.cbrt(lmsLinear[2])];
113
+
114
+ // Convert LMS to OKLab
115
+ const [l, a, b] = transformMat3(lms, LMS_TO_OKLAB_MATRIX);
116
+
117
+ return new OKLABColor(
118
+ l,
119
+ scale(
120
+ a,
121
+ COLOR_SPACE_RANGES.oklab.a.number.min,
122
+ COLOR_SPACE_RANGES.oklab.a.number.max,
123
+ ),
124
+ scale(
125
+ b,
126
+ COLOR_SPACE_RANGES.oklab.b.number.min,
127
+ COLOR_SPACE_RANGES.oklab.b.number.max,
128
+ ),
129
+ xyz.alpha,
130
+ );
131
+ }`,N="function oklab2oklch({ l, a, b, alpha }",F="function oklch2oklab({ l, c, h, alpha }",h=o({__name:"Katex",props:{expression:{},displayMode:{type:Boolean,default:!0}},setup(n){const a=e("katexElement"),l=()=>{a.value&&t.render(n.expression,a.value,{displayMode:n.displayMode,throwOnError:!1,output:"mathml"})};return s(l),b(()=>n.expression,l),(A,_)=>(r(),c("div",{class:"inline-block",ref_key:"katexElement",ref:a},null,512))}}),d=i(h,[["__scopeId","data-v-aaeb860d"]]);export{d as K,z as a,S as b,E as c,f as d,C as e,P as f,B as g,O as h,k as i,Y as j,F as k,p as l,N as m,m as n,w as o,y as p,v as r,R as x};
@@ -0,0 +1 @@
1
+ @font-face{font-display:block;font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(./KaTeX_AMS-Regular-BQhdFMY1.woff2) format("woff2"),url(./KaTeX_AMS-Regular-DMm9YOAa.woff) format("woff"),url(./KaTeX_AMS-Regular-DRggAlZN.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(./KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2) format("woff2"),url(./KaTeX_Caligraphic-Bold-BEiXGLvX.woff) format("woff"),url(./KaTeX_Caligraphic-Bold-ATXxdsX0.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(./KaTeX_Caligraphic-Regular-Di6jR-x-.woff2) format("woff2"),url(./KaTeX_Caligraphic-Regular-CTRA-rTL.woff) format("woff"),url(./KaTeX_Caligraphic-Regular-wX97UBjC.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(./KaTeX_Fraktur-Bold-CL6g_b3V.woff2) format("woff2"),url(./KaTeX_Fraktur-Bold-BsDP51OF.woff) format("woff"),url(./KaTeX_Fraktur-Bold-BdnERNNW.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(./KaTeX_Fraktur-Regular-CTYiF6lA.woff2) format("woff2"),url(./KaTeX_Fraktur-Regular-Dxdc4cR9.woff) format("woff"),url(./KaTeX_Fraktur-Regular-CB_wures.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(./KaTeX_Main-Bold-Cx986IdX.woff2) format("woff2"),url(./KaTeX_Main-Bold-Jm3AIy58.woff) format("woff"),url(./KaTeX_Main-Bold-waoOVXN0.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(./KaTeX_Main-BoldItalic-DxDJ3AOS.woff2) format("woff2"),url(./KaTeX_Main-BoldItalic-SpSLRI95.woff) format("woff"),url(./KaTeX_Main-BoldItalic-DzxPMmG6.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(./KaTeX_Main-Italic-NWA7e6Wa.woff2) format("woff2"),url(./KaTeX_Main-Italic-BMLOBm91.woff) format("woff"),url(./KaTeX_Main-Italic-3WenGoN9.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(./KaTeX_Main-Regular-B22Nviop.woff2) format("woff2"),url(./KaTeX_Main-Regular-Dr94JaBh.woff) format("woff"),url(./KaTeX_Main-Regular-ypZvNtVU.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(./KaTeX_Math-BoldItalic-CZnvNsCZ.woff2) format("woff2"),url(./KaTeX_Math-BoldItalic-iY-2wyZ7.woff) format("woff"),url(./KaTeX_Math-BoldItalic-B3XSjfu4.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(./KaTeX_Math-Italic-t53AETM-.woff2) format("woff2"),url(./KaTeX_Math-Italic-DA0__PXp.woff) format("woff"),url(./KaTeX_Math-Italic-flOr_0UB.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_SansSerif;font-style:normal;font-weight:700;src:url(./KaTeX_SansSerif-Bold-D1sUS0GD.woff2) format("woff2"),url(./KaTeX_SansSerif-Bold-DbIhKOiC.woff) format("woff"),url(./KaTeX_SansSerif-Bold-CFMepnvq.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_SansSerif;font-style:italic;font-weight:400;src:url(./KaTeX_SansSerif-Italic-C3H0VqGB.woff2) format("woff2"),url(./KaTeX_SansSerif-Italic-DN2j7dab.woff) format("woff"),url(./KaTeX_SansSerif-Italic-YYjJ1zSn.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_SansSerif;font-style:normal;font-weight:400;src:url(./KaTeX_SansSerif-Regular-DDBCnlJ7.woff2) format("woff2"),url(./KaTeX_SansSerif-Regular-CS6fqUqJ.woff) format("woff"),url(./KaTeX_SansSerif-Regular-BNo7hRIc.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(./KaTeX_Script-Regular-D3wIWfF6.woff2) format("woff2"),url(./KaTeX_Script-Regular-D5yQViql.woff) format("woff"),url(./KaTeX_Script-Regular-C5JkGWo-.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(./KaTeX_Size1-Regular-mCD8mA8B.woff2) format("woff2"),url(./KaTeX_Size1-Regular-C195tn64.woff) format("woff"),url(./KaTeX_Size1-Regular-Dbsnue_I.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(./KaTeX_Size2-Regular-Dy4dx90m.woff2) format("woff2"),url(./KaTeX_Size2-Regular-oD1tc_U0.woff) format("woff"),url(./KaTeX_Size2-Regular-B7gKUWhC.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(data:font/woff2;base64,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) format("woff2"),url(./KaTeX_Size3-Regular-CTq5MqoE.woff) format("woff"),url(./KaTeX_Size3-Regular-DgpXs0kz.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(./KaTeX_Size4-Regular-Dl5lxZxV.woff2) format("woff2"),url(./KaTeX_Size4-Regular-BF-4gkZK.woff) format("woff"),url(./KaTeX_Size4-Regular-DWFBv043.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(./KaTeX_Typewriter-Regular-CO6r4hn1.woff2) format("woff2"),url(./KaTeX_Typewriter-Regular-C0xS9mPB.woff) format("woff"),url(./KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf) format("truetype")}.katex[data-v-aaeb860d]{font: 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0;text-rendering:auto}.katex[data-v-aaeb860d] *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version[data-v-aaeb860d]:after{content:"0.16.33"}.katex .katex-mathml[data-v-aaeb860d]{clip:rect(1px,1px,1px,1px);border:0;height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline[data-v-aaeb860d]{display:block}.katex .base[data-v-aaeb860d]{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base[data-v-aaeb860d],.katex .strut[data-v-aaeb860d]{display:inline-block}.katex .textbf[data-v-aaeb860d]{font-weight:700}.katex .textit[data-v-aaeb860d]{font-style:italic}.katex .textrm[data-v-aaeb860d]{font-family:KaTeX_Main}.katex .textsf[data-v-aaeb860d]{font-family:KaTeX_SansSerif}.katex .texttt[data-v-aaeb860d]{font-family:KaTeX_Typewriter}.katex .mathnormal[data-v-aaeb860d]{font-family:KaTeX_Math;font-style:italic}.katex .mathit[data-v-aaeb860d]{font-family:KaTeX_Main;font-style:italic}.katex .mathrm[data-v-aaeb860d]{font-style:normal}.katex .mathbf[data-v-aaeb860d]{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol[data-v-aaeb860d]{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm[data-v-aaeb860d],.katex .mathbb[data-v-aaeb860d],.katex .textbb[data-v-aaeb860d]{font-family:KaTeX_AMS}.katex .mathcal[data-v-aaeb860d]{font-family:KaTeX_Caligraphic}.katex .mathfrak[data-v-aaeb860d],.katex .textfrak[data-v-aaeb860d]{font-family:KaTeX_Fraktur}.katex .mathboldfrak[data-v-aaeb860d],.katex .textboldfrak[data-v-aaeb860d]{font-family:KaTeX_Fraktur;font-weight:700}.katex .mathtt[data-v-aaeb860d]{font-family:KaTeX_Typewriter}.katex .mathscr[data-v-aaeb860d],.katex .textscr[data-v-aaeb860d]{font-family:KaTeX_Script}.katex .mathsf[data-v-aaeb860d],.katex .textsf[data-v-aaeb860d]{font-family:KaTeX_SansSerif}.katex .mathboldsf[data-v-aaeb860d],.katex .textboldsf[data-v-aaeb860d]{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf[data-v-aaeb860d],.katex .mathsfit[data-v-aaeb860d],.katex .textitsf[data-v-aaeb860d]{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm[data-v-aaeb860d]{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t[data-v-aaeb860d]{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r[data-v-aaeb860d]{display:table-row}.katex .vlist[data-v-aaeb860d]{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span[data-v-aaeb860d]{display:block;height:0;position:relative}.katex .vlist>span>span[data-v-aaeb860d]{display:inline-block}.katex .vlist>span>.pstrut[data-v-aaeb860d]{overflow:hidden;width:0}.katex .vlist-t2[data-v-aaeb860d]{margin-right:-2px}.katex .vlist-s[data-v-aaeb860d]{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox[data-v-aaeb860d]{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox[data-v-aaeb860d]{width:100%}.katex .hbox[data-v-aaeb860d],.katex .thinbox[data-v-aaeb860d]{display:inline-flex;flex-direction:row}.katex .thinbox[data-v-aaeb860d]{max-width:0;width:0}.katex .msupsub[data-v-aaeb860d]{text-align:left}.katex .mfrac>span>span[data-v-aaeb860d]{text-align:center}.katex .mfrac .frac-line[data-v-aaeb860d]{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline[data-v-aaeb860d],.katex .hline[data-v-aaeb860d],.katex .mfrac .frac-line[data-v-aaeb860d],.katex .overline .overline-line[data-v-aaeb860d],.katex .rule[data-v-aaeb860d],.katex .underline .underline-line[data-v-aaeb860d]{min-height:1px}.katex .mspace[data-v-aaeb860d]{display:inline-block}.katex .clap[data-v-aaeb860d],.katex .llap[data-v-aaeb860d],.katex .rlap[data-v-aaeb860d]{position:relative;width:0}.katex .clap>.inner[data-v-aaeb860d],.katex .llap>.inner[data-v-aaeb860d],.katex .rlap>.inner[data-v-aaeb860d]{position:absolute}.katex .clap>.fix[data-v-aaeb860d],.katex .llap>.fix[data-v-aaeb860d],.katex .rlap>.fix[data-v-aaeb860d]{display:inline-block}.katex .llap>.inner[data-v-aaeb860d]{right:0}.katex .clap>.inner[data-v-aaeb860d],.katex .rlap>.inner[data-v-aaeb860d]{left:0}.katex .clap>.inner>span[data-v-aaeb860d]{margin-left:-50%;margin-right:50%}.katex .rule[data-v-aaeb860d]{border:0 solid;display:inline-block;position:relative}.katex .hline[data-v-aaeb860d],.katex .overline .overline-line[data-v-aaeb860d],.katex .underline .underline-line[data-v-aaeb860d]{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline[data-v-aaeb860d]{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root[data-v-aaeb860d]{margin-left:.2777777778em;margin-right:-.5555555556em}.katex .fontsize-ensurer.reset-size1.size1[data-v-aaeb860d],.katex .sizing.reset-size1.size1[data-v-aaeb860d]{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2[data-v-aaeb860d],.katex .sizing.reset-size1.size2[data-v-aaeb860d]{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3[data-v-aaeb860d],.katex .sizing.reset-size1.size3[data-v-aaeb860d]{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4[data-v-aaeb860d],.katex .sizing.reset-size1.size4[data-v-aaeb860d]{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5[data-v-aaeb860d],.katex .sizing.reset-size1.size5[data-v-aaeb860d]{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6[data-v-aaeb860d],.katex .sizing.reset-size1.size6[data-v-aaeb860d]{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7[data-v-aaeb860d],.katex .sizing.reset-size1.size7[data-v-aaeb860d]{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8[data-v-aaeb860d],.katex .sizing.reset-size1.size8[data-v-aaeb860d]{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9[data-v-aaeb860d],.katex .sizing.reset-size1.size9[data-v-aaeb860d]{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10[data-v-aaeb860d],.katex .sizing.reset-size1.size10[data-v-aaeb860d]{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11[data-v-aaeb860d],.katex .sizing.reset-size1.size11[data-v-aaeb860d]{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1[data-v-aaeb860d],.katex .sizing.reset-size2.size1[data-v-aaeb860d]{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size2.size2[data-v-aaeb860d],.katex .sizing.reset-size2.size2[data-v-aaeb860d]{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3[data-v-aaeb860d],.katex .sizing.reset-size2.size3[data-v-aaeb860d]{font-size:1.1666666667em}.katex .fontsize-ensurer.reset-size2.size4[data-v-aaeb860d],.katex .sizing.reset-size2.size4[data-v-aaeb860d]{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size2.size5[data-v-aaeb860d],.katex .sizing.reset-size2.size5[data-v-aaeb860d]{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6[data-v-aaeb860d],.katex .sizing.reset-size2.size6[data-v-aaeb860d]{font-size:1.6666666667em}.katex .fontsize-ensurer.reset-size2.size7[data-v-aaeb860d],.katex .sizing.reset-size2.size7[data-v-aaeb860d]{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8[data-v-aaeb860d],.katex .sizing.reset-size2.size8[data-v-aaeb860d]{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9[data-v-aaeb860d],.katex .sizing.reset-size2.size9[data-v-aaeb860d]{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10[data-v-aaeb860d],.katex .sizing.reset-size2.size10[data-v-aaeb860d]{font-size:3.4566666667em}.katex .fontsize-ensurer.reset-size2.size11[data-v-aaeb860d],.katex .sizing.reset-size2.size11[data-v-aaeb860d]{font-size:4.1466666667em}.katex .fontsize-ensurer.reset-size3.size1[data-v-aaeb860d],.katex .sizing.reset-size3.size1[data-v-aaeb860d]{font-size:.7142857143em}.katex .fontsize-ensurer.reset-size3.size2[data-v-aaeb860d],.katex .sizing.reset-size3.size2[data-v-aaeb860d]{font-size:.8571428571em}.katex .fontsize-ensurer.reset-size3.size3[data-v-aaeb860d],.katex .sizing.reset-size3.size3[data-v-aaeb860d]{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4[data-v-aaeb860d],.katex .sizing.reset-size3.size4[data-v-aaeb860d]{font-size:1.1428571429em}.katex .fontsize-ensurer.reset-size3.size5[data-v-aaeb860d],.katex .sizing.reset-size3.size5[data-v-aaeb860d]{font-size:1.2857142857em}.katex .fontsize-ensurer.reset-size3.size6[data-v-aaeb860d],.katex .sizing.reset-size3.size6[data-v-aaeb860d]{font-size:1.4285714286em}.katex .fontsize-ensurer.reset-size3.size7[data-v-aaeb860d],.katex .sizing.reset-size3.size7[data-v-aaeb860d]{font-size:1.7142857143em}.katex .fontsize-ensurer.reset-size3.size8[data-v-aaeb860d],.katex .sizing.reset-size3.size8[data-v-aaeb860d]{font-size:2.0571428571em}.katex .fontsize-ensurer.reset-size3.size9[data-v-aaeb860d],.katex .sizing.reset-size3.size9[data-v-aaeb860d]{font-size:2.4685714286em}.katex .fontsize-ensurer.reset-size3.size10[data-v-aaeb860d],.katex .sizing.reset-size3.size10[data-v-aaeb860d]{font-size:2.9628571429em}.katex .fontsize-ensurer.reset-size3.size11[data-v-aaeb860d],.katex .sizing.reset-size3.size11[data-v-aaeb860d]{font-size:3.5542857143em}.katex .fontsize-ensurer.reset-size4.size1[data-v-aaeb860d],.katex .sizing.reset-size4.size1[data-v-aaeb860d]{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2[data-v-aaeb860d],.katex .sizing.reset-size4.size2[data-v-aaeb860d]{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3[data-v-aaeb860d],.katex .sizing.reset-size4.size3[data-v-aaeb860d]{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4[data-v-aaeb860d],.katex .sizing.reset-size4.size4[data-v-aaeb860d]{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5[data-v-aaeb860d],.katex .sizing.reset-size4.size5[data-v-aaeb860d]{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6[data-v-aaeb860d],.katex .sizing.reset-size4.size6[data-v-aaeb860d]{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7[data-v-aaeb860d],.katex .sizing.reset-size4.size7[data-v-aaeb860d]{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8[data-v-aaeb860d],.katex .sizing.reset-size4.size8[data-v-aaeb860d]{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9[data-v-aaeb860d],.katex .sizing.reset-size4.size9[data-v-aaeb860d]{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10[data-v-aaeb860d],.katex .sizing.reset-size4.size10[data-v-aaeb860d]{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11[data-v-aaeb860d],.katex .sizing.reset-size4.size11[data-v-aaeb860d]{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1[data-v-aaeb860d],.katex .sizing.reset-size5.size1[data-v-aaeb860d]{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size5.size2[data-v-aaeb860d],.katex .sizing.reset-size5.size2[data-v-aaeb860d]{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size5.size3[data-v-aaeb860d],.katex .sizing.reset-size5.size3[data-v-aaeb860d]{font-size:.7777777778em}.katex .fontsize-ensurer.reset-size5.size4[data-v-aaeb860d],.katex .sizing.reset-size5.size4[data-v-aaeb860d]{font-size:.8888888889em}.katex .fontsize-ensurer.reset-size5.size5[data-v-aaeb860d],.katex .sizing.reset-size5.size5[data-v-aaeb860d]{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6[data-v-aaeb860d],.katex .sizing.reset-size5.size6[data-v-aaeb860d]{font-size:1.1111111111em}.katex .fontsize-ensurer.reset-size5.size7[data-v-aaeb860d],.katex .sizing.reset-size5.size7[data-v-aaeb860d]{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size5.size8[data-v-aaeb860d],.katex .sizing.reset-size5.size8[data-v-aaeb860d]{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9[data-v-aaeb860d],.katex .sizing.reset-size5.size9[data-v-aaeb860d]{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10[data-v-aaeb860d],.katex .sizing.reset-size5.size10[data-v-aaeb860d]{font-size:2.3044444444em}.katex .fontsize-ensurer.reset-size5.size11[data-v-aaeb860d],.katex .sizing.reset-size5.size11[data-v-aaeb860d]{font-size:2.7644444444em}.katex .fontsize-ensurer.reset-size6.size1[data-v-aaeb860d],.katex .sizing.reset-size6.size1[data-v-aaeb860d]{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2[data-v-aaeb860d],.katex .sizing.reset-size6.size2[data-v-aaeb860d]{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3[data-v-aaeb860d],.katex .sizing.reset-size6.size3[data-v-aaeb860d]{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4[data-v-aaeb860d],.katex .sizing.reset-size6.size4[data-v-aaeb860d]{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5[data-v-aaeb860d],.katex .sizing.reset-size6.size5[data-v-aaeb860d]{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6[data-v-aaeb860d],.katex .sizing.reset-size6.size6[data-v-aaeb860d]{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7[data-v-aaeb860d],.katex .sizing.reset-size6.size7[data-v-aaeb860d]{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8[data-v-aaeb860d],.katex .sizing.reset-size6.size8[data-v-aaeb860d]{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9[data-v-aaeb860d],.katex .sizing.reset-size6.size9[data-v-aaeb860d]{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10[data-v-aaeb860d],.katex .sizing.reset-size6.size10[data-v-aaeb860d]{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11[data-v-aaeb860d],.katex .sizing.reset-size6.size11[data-v-aaeb860d]{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1[data-v-aaeb860d],.katex .sizing.reset-size7.size1[data-v-aaeb860d]{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size7.size2[data-v-aaeb860d],.katex .sizing.reset-size7.size2[data-v-aaeb860d]{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3[data-v-aaeb860d],.katex .sizing.reset-size7.size3[data-v-aaeb860d]{font-size:.5833333333em}.katex .fontsize-ensurer.reset-size7.size4[data-v-aaeb860d],.katex .sizing.reset-size7.size4[data-v-aaeb860d]{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size7.size5[data-v-aaeb860d],.katex .sizing.reset-size7.size5[data-v-aaeb860d]{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6[data-v-aaeb860d],.katex .sizing.reset-size7.size6[data-v-aaeb860d]{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size7.size7[data-v-aaeb860d],.katex .sizing.reset-size7.size7[data-v-aaeb860d]{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8[data-v-aaeb860d],.katex .sizing.reset-size7.size8[data-v-aaeb860d]{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9[data-v-aaeb860d],.katex .sizing.reset-size7.size9[data-v-aaeb860d]{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10[data-v-aaeb860d],.katex .sizing.reset-size7.size10[data-v-aaeb860d]{font-size:1.7283333333em}.katex .fontsize-ensurer.reset-size7.size11[data-v-aaeb860d],.katex .sizing.reset-size7.size11[data-v-aaeb860d]{font-size:2.0733333333em}.katex .fontsize-ensurer.reset-size8.size1[data-v-aaeb860d],.katex .sizing.reset-size8.size1[data-v-aaeb860d]{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size8.size2[data-v-aaeb860d],.katex .sizing.reset-size8.size2[data-v-aaeb860d]{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size8.size3[data-v-aaeb860d],.katex .sizing.reset-size8.size3[data-v-aaeb860d]{font-size:.4861111111em}.katex .fontsize-ensurer.reset-size8.size4[data-v-aaeb860d],.katex .sizing.reset-size8.size4[data-v-aaeb860d]{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size8.size5[data-v-aaeb860d],.katex .sizing.reset-size8.size5[data-v-aaeb860d]{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6[data-v-aaeb860d],.katex .sizing.reset-size8.size6[data-v-aaeb860d]{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size8.size7[data-v-aaeb860d],.katex .sizing.reset-size8.size7[data-v-aaeb860d]{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size8.size8[data-v-aaeb860d],.katex .sizing.reset-size8.size8[data-v-aaeb860d]{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9[data-v-aaeb860d],.katex .sizing.reset-size8.size9[data-v-aaeb860d]{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10[data-v-aaeb860d],.katex .sizing.reset-size8.size10[data-v-aaeb860d]{font-size:1.4402777778em}.katex .fontsize-ensurer.reset-size8.size11[data-v-aaeb860d],.katex .sizing.reset-size8.size11[data-v-aaeb860d]{font-size:1.7277777778em}.katex .fontsize-ensurer.reset-size9.size1[data-v-aaeb860d],.katex .sizing.reset-size9.size1[data-v-aaeb860d]{font-size:.2893518519em}.katex .fontsize-ensurer.reset-size9.size2[data-v-aaeb860d],.katex .sizing.reset-size9.size2[data-v-aaeb860d]{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size9.size3[data-v-aaeb860d],.katex .sizing.reset-size9.size3[data-v-aaeb860d]{font-size:.4050925926em}.katex .fontsize-ensurer.reset-size9.size4[data-v-aaeb860d],.katex .sizing.reset-size9.size4[data-v-aaeb860d]{font-size:.462962963em}.katex .fontsize-ensurer.reset-size9.size5[data-v-aaeb860d],.katex .sizing.reset-size9.size5[data-v-aaeb860d]{font-size:.5208333333em}.katex .fontsize-ensurer.reset-size9.size6[data-v-aaeb860d],.katex .sizing.reset-size9.size6[data-v-aaeb860d]{font-size:.5787037037em}.katex .fontsize-ensurer.reset-size9.size7[data-v-aaeb860d],.katex .sizing.reset-size9.size7[data-v-aaeb860d]{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size9.size8[data-v-aaeb860d],.katex .sizing.reset-size9.size8[data-v-aaeb860d]{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size9.size9[data-v-aaeb860d],.katex .sizing.reset-size9.size9[data-v-aaeb860d]{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10[data-v-aaeb860d],.katex .sizing.reset-size9.size10[data-v-aaeb860d]{font-size:1.2002314815em}.katex .fontsize-ensurer.reset-size9.size11[data-v-aaeb860d],.katex .sizing.reset-size9.size11[data-v-aaeb860d]{font-size:1.4398148148em}.katex .fontsize-ensurer.reset-size10.size1[data-v-aaeb860d],.katex .sizing.reset-size10.size1[data-v-aaeb860d]{font-size:.2410800386em}.katex .fontsize-ensurer.reset-size10.size2[data-v-aaeb860d],.katex .sizing.reset-size10.size2[data-v-aaeb860d]{font-size:.2892960463em}.katex .fontsize-ensurer.reset-size10.size3[data-v-aaeb860d],.katex .sizing.reset-size10.size3[data-v-aaeb860d]{font-size:.337512054em}.katex .fontsize-ensurer.reset-size10.size4[data-v-aaeb860d],.katex .sizing.reset-size10.size4[data-v-aaeb860d]{font-size:.3857280617em}.katex .fontsize-ensurer.reset-size10.size5[data-v-aaeb860d],.katex .sizing.reset-size10.size5[data-v-aaeb860d]{font-size:.4339440694em}.katex .fontsize-ensurer.reset-size10.size6[data-v-aaeb860d],.katex .sizing.reset-size10.size6[data-v-aaeb860d]{font-size:.4821600771em}.katex .fontsize-ensurer.reset-size10.size7[data-v-aaeb860d],.katex .sizing.reset-size10.size7[data-v-aaeb860d]{font-size:.5785920926em}.katex .fontsize-ensurer.reset-size10.size8[data-v-aaeb860d],.katex .sizing.reset-size10.size8[data-v-aaeb860d]{font-size:.6943105111em}.katex .fontsize-ensurer.reset-size10.size9[data-v-aaeb860d],.katex .sizing.reset-size10.size9[data-v-aaeb860d]{font-size:.8331726133em}.katex .fontsize-ensurer.reset-size10.size10[data-v-aaeb860d],.katex .sizing.reset-size10.size10[data-v-aaeb860d]{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11[data-v-aaeb860d],.katex .sizing.reset-size10.size11[data-v-aaeb860d]{font-size:1.1996142719em}.katex .fontsize-ensurer.reset-size11.size1[data-v-aaeb860d],.katex .sizing.reset-size11.size1[data-v-aaeb860d]{font-size:.2009646302em}.katex .fontsize-ensurer.reset-size11.size2[data-v-aaeb860d],.katex .sizing.reset-size11.size2[data-v-aaeb860d]{font-size:.2411575563em}.katex .fontsize-ensurer.reset-size11.size3[data-v-aaeb860d],.katex .sizing.reset-size11.size3[data-v-aaeb860d]{font-size:.2813504823em}.katex .fontsize-ensurer.reset-size11.size4[data-v-aaeb860d],.katex .sizing.reset-size11.size4[data-v-aaeb860d]{font-size:.3215434084em}.katex .fontsize-ensurer.reset-size11.size5[data-v-aaeb860d],.katex .sizing.reset-size11.size5[data-v-aaeb860d]{font-size:.3617363344em}.katex .fontsize-ensurer.reset-size11.size6[data-v-aaeb860d],.katex .sizing.reset-size11.size6[data-v-aaeb860d]{font-size:.4019292605em}.katex .fontsize-ensurer.reset-size11.size7[data-v-aaeb860d],.katex .sizing.reset-size11.size7[data-v-aaeb860d]{font-size:.4823151125em}.katex .fontsize-ensurer.reset-size11.size8[data-v-aaeb860d],.katex .sizing.reset-size11.size8[data-v-aaeb860d]{font-size:.578778135em}.katex .fontsize-ensurer.reset-size11.size9[data-v-aaeb860d],.katex .sizing.reset-size11.size9[data-v-aaeb860d]{font-size:.6945337621em}.katex .fontsize-ensurer.reset-size11.size10[data-v-aaeb860d],.katex .sizing.reset-size11.size10[data-v-aaeb860d]{font-size:.8336012862em}.katex .fontsize-ensurer.reset-size11.size11[data-v-aaeb860d],.katex .sizing.reset-size11.size11[data-v-aaeb860d]{font-size:1em}.katex .delimsizing.size1[data-v-aaeb860d]{font-family:KaTeX_Size1}.katex .delimsizing.size2[data-v-aaeb860d]{font-family:KaTeX_Size2}.katex .delimsizing.size3[data-v-aaeb860d]{font-family:KaTeX_Size3}.katex .delimsizing.size4[data-v-aaeb860d]{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span[data-v-aaeb860d]{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span[data-v-aaeb860d]{font-family:KaTeX_Size4}.katex .nulldelimiter[data-v-aaeb860d]{display:inline-block;width:.12em}.katex .delimcenter[data-v-aaeb860d],.katex .op-symbol[data-v-aaeb860d]{position:relative}.katex .op-symbol.small-op[data-v-aaeb860d]{font-family:KaTeX_Size1}.katex .op-symbol.large-op[data-v-aaeb860d]{font-family:KaTeX_Size2}.katex .accent>.vlist-t[data-v-aaeb860d],.katex .op-limits>.vlist-t[data-v-aaeb860d]{text-align:center}.katex .accent .accent-body[data-v-aaeb860d]{position:relative}.katex .accent .accent-body[data-v-aaeb860d]:not(.accent-full){width:0}.katex .overlay[data-v-aaeb860d]{display:block}.katex .mtable .vertical-separator[data-v-aaeb860d]{display:inline-block;min-width:1px}.katex .mtable .arraycolsep[data-v-aaeb860d]{display:inline-block}.katex .mtable .col-align-c>.vlist-t[data-v-aaeb860d]{text-align:center}.katex .mtable .col-align-l>.vlist-t[data-v-aaeb860d]{text-align:left}.katex .mtable .col-align-r>.vlist-t[data-v-aaeb860d]{text-align:right}.katex .svg-align[data-v-aaeb860d]{text-align:left}.katex svg[data-v-aaeb860d]{fill:currentColor;stroke:currentColor;display:block;height:inherit;position:absolute;width:100%}.katex svg path[data-v-aaeb860d]{stroke:none}.katex svg[data-v-aaeb860d]{fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1}.katex img[data-v-aaeb860d]{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy[data-v-aaeb860d]{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy[data-v-aaeb860d]:after,.katex .stretchy[data-v-aaeb860d]:before{content:""}.katex .hide-tail[data-v-aaeb860d]{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left[data-v-aaeb860d]{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right[data-v-aaeb860d]{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left[data-v-aaeb860d]{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center[data-v-aaeb860d]{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right[data-v-aaeb860d]{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad[data-v-aaeb860d]{padding:0 .5em}.katex .cd-arrow-pad[data-v-aaeb860d]{padding:0 .55556em 0 .27778em}.katex .mover[data-v-aaeb860d],.katex .munder[data-v-aaeb860d],.katex .x-arrow[data-v-aaeb860d]{text-align:center}.katex .boxpad[data-v-aaeb860d]{padding:0 .3em}.katex .fbox[data-v-aaeb860d],.katex .fcolorbox[data-v-aaeb860d]{border:.04em solid;box-sizing:border-box}.katex .cancel-pad[data-v-aaeb860d]{padding:0 .2em}.katex .cancel-lap[data-v-aaeb860d]{margin-left:-.2em;margin-right:-.2em}.katex .sout[data-v-aaeb860d]{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl[data-v-aaeb860d]{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad[data-v-aaeb860d]{padding:0 .03889em}.katex .eqn-num[data-v-aaeb860d]:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num[data-v-aaeb860d]:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue[data-v-aaeb860d]{width:50%}.katex .cd-vert-arrow[data-v-aaeb860d]{display:inline-block;position:relative}.katex .cd-label-left[data-v-aaeb860d]{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right[data-v-aaeb860d]{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display[data-v-aaeb860d]{display:block;margin:1em 0;text-align:center}.katex-display>.katex[data-v-aaeb860d]{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html[data-v-aaeb860d]{display:block;position:relative}.katex-display>.katex>.katex-html>.tag[data-v-aaeb860d]{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag[data-v-aaeb860d]{left:0;right:auto}.katex-display.fleqn>.katex[data-v-aaeb860d]{padding-left:2em;text-align:left}body[data-v-aaeb860d]{counter-reset:katexEqnNo mmlEqnNo}
@@ -0,0 +1,20 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
2
+ <defs>
3
+ <filter id="wc" x="-20%" y="-20%" width="140%" height="140%" color-interpolation-filters="sRGB">
4
+ <feTurbulence type="fractalNoise" baseFrequency="0.06" numOctaves="5" seed="7" result="noise"/>
5
+ <feDisplacementMap in="SourceGraphic" in2="noise" scale="5" xChannelSelector="R" yChannelSelector="G"/>
6
+ </filter>
7
+ <filter id="ds" x="-10%" y="-10%" width="130%" height="130%">
8
+ <feGaussianBlur stdDeviation="2.5"/>
9
+ </filter>
10
+ <radialGradient id="hl" cx="36%" cy="32%" r="42%">
11
+ <stop offset="0%" stop-color="white" stop-opacity="0.35"/>
12
+ <stop offset="100%" stop-color="white" stop-opacity="0"/>
13
+ </radialGradient>
14
+ </defs>
15
+ <ellipse cx="33" cy="35" rx="20" ry="19" fill="black" opacity="0.08" filter="url(#ds)"/>
16
+ <g filter="url(#wc)">
17
+ <path d="M33,9 L46.4,9 A10.6,13.7 0 0,1 57,22.7 L57,33 A14.8,24 0 0,1 42.2,57 L26.6,57 A17.6,24 0 0,1 9,33 A24,24 0 0,1 33,9 Z" fill="oklch(95.83% 0.27 9.83deg / 82.70%)"/>
18
+ <ellipse cx="29" cy="27" rx="14" ry="12" fill="url(#hl)"/>
19
+ </g>
20
+ </svg>
@@ -0,0 +1 @@
1
+ import{K as n,a as h,h as m}from"./Katex-ClrxLHTj.js";import{g}from"./index-Q19pIqw1.js";import{J as c,V as f,a0 as o,a1 as a,a2 as s,u as t,a6 as u,N as i}from"./vendor-highlight-sMWp9TLU.js";import"./vendor-katex-Dehg5p_Y.js";import"./vendor-prettier-wO8BBsoP.js";const x={class:"markdown-body"},y={class:"language-typescript"},b={class:"language-typescript"},G={__name:"hsl",setup(S,{expose:p}){p({frontmatter:{}});const{h:r,s:l,l:d}=g("hsl");return(C,e)=>(c(),f("div",x,[e[6]||(e[6]=o("h3",null,"Attributes",-1)),o("ul",null,[o("li",null,[e[0]||(e[0]=o("code",null,"H",-1)),a(": Hue ("+s(t(r).min)+" to "+s(t(r).max)+")",1)]),o("li",null,[e[1]||(e[1]=o("code",null,"S",-1)),a(": Saturation ("+s(t(l).min)+" to "+s(t(l).max)+")",1)]),o("li",null,[e[2]||(e[2]=o("code",null,"L",-1)),a(": Lightness ("+s(t(d).min)+" to "+s(t(d).max)+")",1)])]),e[7]||(e[7]=u("<h3>Historical Context</h3><p>HSL was developed in the 1970s as part of computer graphics research—an attempt to give humans a more intuitive handle on color than raw RGB triplets. It separates <strong>hue</strong> (the color itself) from <strong>saturation</strong> (intensity) and <strong>lightness</strong> (brightness), mapping neatly onto how people talk about color in practice.</p><hr><h2>Key Characteristics</h2><ol><li><strong>Cylindrical representation</strong>: hue as angle, saturation as radius, lightness as height. Visualized as a double-cone or cylinder.</li><li><strong>Intuitive adjustment</strong>: changing one component produces predictable variations—useful for deriving palettes and tints/shades.</li><li><strong>Same gamut as sRGB</strong>: HSL is a coordinate transform of RGB, not an expansion.</li></ol><h3>Advantages</h3><ul><li>Intuitive for color selection and palette generation</li><li>Easy to create tints (raise L), shades (lower L), and tones (lower S)</li><li>Native CSS support via <code>hsl()</code></li><li>Simple to generate distinguishable color sequences by varying hue</li></ul><h3>Disadvantages</h3><ul><li>Not perceptually uniform—colors at the same <code>L</code> can appear drastically different in brightness (blue vs. yellow)</li><li>The lightness model is a poor approximation of human luminance perception</li><li>Hue shifts can occur during saturation changes</li></ul><hr><h2>Color Model</h2><h3>Components</h3><ol><li><p><strong><code>H</code> (Hue)</strong>: <code>H = 0° \\text{ to } 360°</code> (normalized to 0–1)</p><p>The color wheel: 0°/360° red, 60° yellow, 120° green, 180° cyan, 240° blue, 300° magenta.</p></li><li><p><strong><code>S</code> (Saturation)</strong>: <code>S = 0 \\text{ (grayscale) to } 1 \\text{ (fully saturated)}</code></p></li><li><p><strong><code>L</code> (Lightness)</strong>: <code>L = 0 \\text{ (black) to } 1 \\text{ (white)}</code></p><p>0.5 is the “pure” color—fully saturated at medium brightness.</p></li></ol><hr><h2>Color Conversions</h2><h3>RGB to HSL</h3><p>Compute lightness from the min/max of the RGB channels, derive chroma and saturation, then determine hue from whichever channel dominates:</p>",17)),i(t(n),{expression:"L = \\frac{\\max + \\min}{2}, \\quad C = \\max - \\min, \\quad S = \\frac{C}{1 - |2L - 1|}"}),i(t(n),{expression:"H = \\begin{cases} \\frac{G - B}{C} & \\text{if } \\max = R \\\\ \\frac{B - R}{C} + 2 & \\text{if } \\max = G \\\\ \\frac{R - G}{C} + 4 & \\text{if } \\max = B \\end{cases} \\quad (\\text{then } H = H / 6)"}),o("div",y,s(t(h)),1),e[8]||(e[8]=o("h3",null,"HSL to RGB",-1)),e[9]||(e[9]=o("p",null,"Recover chroma from saturation and lightness, determine the RGB triple by hue sector, then shift by the lightness offset:",-1)),i(t(n),{expression:"C = (1 - |2L - 1|) \\cdot S, \\quad X = C(1 - |(H \\cdot 6) \\bmod 2 - 1|), \\quad m = L - C/2"}),i(t(n),{expression:"(R,\\, G,\\, B) = (r_1 + m,\\; g_1 + m,\\; b_1 + m)"}),o("p",null,[e[3]||(e[3]=a("where ",-1)),i(t(n),{expression:"(r_1, g_1, b_1)","display-mode":!1}),e[4]||(e[4]=a(" is selected from ",-1)),i(t(n),{expression:"(C, X, 0)","display-mode":!1}),e[5]||(e[5]=a(" and its permutations based on the hue sector.",-1))]),o("div",b,s(t(m)),1),e[10]||(e[10]=u("<hr><h2>Applications</h2><ol><li><strong>CSS color specification</strong>: <code>hsl()</code> is widely used in stylesheets for readable color declarations.</li><li><strong>UI color pickers</strong>: the cylindrical model maps naturally to sliders and wheels.</li><li><strong>Palette generation</strong>: systematic hue rotation with fixed S and L produces harmonious schemes.</li><li><strong>Image processing</strong>: hue rotation and saturation adjustment are straightforward operations.</li></ol>",3))]))}};export{G as default};
@@ -0,0 +1 @@
1
+ import{K as l,b as g,c as p,h as c,a as m}from"./Katex-ClrxLHTj.js";import{g as S}from"./index-Q19pIqw1.js";import{J as f,V as v,a0 as e,a1 as a,a2 as s,u as o,a6 as d,N as u}from"./vendor-highlight-sMWp9TLU.js";import"./vendor-katex-Dehg5p_Y.js";import"./vendor-prettier-wO8BBsoP.js";const y={class:"markdown-body"},V={class:"language-typescript"},H={class:"language-typescript"},b={class:"language-typescript"},w={class:"language-typescript"},A={__name:"hsv",setup(x,{expose:h}){h({frontmatter:{}});const{h:i,s:n,v:r}=S("hsv");return(B,t)=>(f(),v("div",y,[t[3]||(t[3]=e("h3",null,"Attributes",-1)),e("ul",null,[e("li",null,[t[0]||(t[0]=e("code",null,"H",-1)),a(": Hue ("+s(o(i).min)+" to "+s(o(i).max)+")",1)]),e("li",null,[t[1]||(t[1]=e("code",null,"S",-1)),a(": Saturation ("+s(o(n).min)+" to "+s(o(n).max)+")",1)]),e("li",null,[t[2]||(t[2]=e("code",null,"V",-1)),a(": Value/Brightness ("+s(o(r).min)+" to "+s(o(r).max)+")",1)])]),t[4]||(t[4]=d("<h3>Background</h3><p>HSV (Hue, Saturation, Value) was developed by Alvy Ray Smith in 1978 as a way to select color by perceptual attributes rather than by RGB channel. It’s also called <strong>HSB</strong> (Hue, Saturation, Brightness) in some applications—same thing, different name.</p><p>The model is cylindrical: hue is an angle around the wheel, saturation is radial distance from the center axis, and value is height. Its gamut is identical to sRGB—it’s a reorganization, not an expansion.</p><hr><h2>Color Model</h2><h3>Components</h3><ol><li><p><strong><code>H</code> (Hue)</strong>: <code>H = 0 \\text{ to } 1 \\text{ (representing 0° to 360°)}</code></p><p>Position on the color wheel. <code>0</code> and <code>1</code> both map to red.</p></li><li><p><strong><code>S</code> (Saturation)</strong>: <code>S = 0 \\text{ (grayscale) to } 1 \\text{ (fully saturated color)}</code></p><p>Purity of the color. At <code>S=0</code>, the result is grayscale regardless of hue.</p></li><li><p><strong><code>V</code> (Value)</strong>: <code>V = 0 \\text{ (black) to } 1 \\text{ (full brightness)}</code></p><p>Brightness. <strong><code>V=0</code> is always black</strong>, no matter what hue or saturation are set to.</p></li></ol><h3>Relationship to HSL</h3><p>HSV and HSL share a hue channel but diverge on the other two axes. In HSV, <code>V=1</code> with varying saturation moves from white to fully saturated color. In HSL, <code>L=0.5</code> with varying saturation moves from gray to fully saturated color. HSL’s lightness axis is symmetric (black at 0, white at 1); HSV’s value axis isn’t—there’s no way to reach pure white without also reducing saturation.</p><hr><h2>Advantages</h2><ul><li>Intuitive for color selection—hue, purity, and brightness are independent controls</li><li>Easy to generate systematic color variations (e.g., darken by lowering <code>V</code>)</li><li>Ubiquitous in color pickers across design software</li></ul><h2>Disadvantages</h2><ul><li>Not perceptually uniform—equal numeric steps don’t look like equal steps</li><li>Mathematical discontinuities at low saturation and brightness</li><li>Doesn’t account for human sensitivity differences across the spectrum</li></ul><hr><h2>Color Conversions</h2><h3>HSV to HSL</h3><p>Derive lightness from value and saturation, then recompute saturation for the HSL model:</p>",18)),u(o(l),{expression:"L = V - \\frac{V \\cdot S}{2}, \\quad S_L = \\begin{cases} 0 & L = 0 \\text{ or } L = 1 \\\\ \\frac{V - L}{\\min(L,\\; 1 - L)} & \\text{otherwise} \\end{cases}"}),e("div",V,s(o(g)),1),t[5]||(t[5]=e("h3",null,"HSL to HSV",-1)),t[6]||(t[6]=e("p",null,"The inverse—recover value and saturation in the HSV model:",-1)),u(o(l),{expression:"V = L + S \\cdot \\min(L,\\; 1 - L), \\quad S_V = \\begin{cases} 0 & V = 0 \\\\ 2\\left(1 - \\frac{L}{V}\\right) & \\text{otherwise} \\end{cases}"}),e("div",H,s(o(p)),1),t[7]||(t[7]=e("h3",null,"HSL to RGB",-1)),t[8]||(t[8]=e("p",null,"The intermediate step when converting HSV to display-ready sRGB (HSV → HSL → RGB):",-1)),e("div",b,s(o(c)),1),t[9]||(t[9]=e("h3",null,"RGB to HSL",-1)),t[10]||(t[10]=e("p",null,"The intermediate step when converting from sRGB back to HSV (RGB → HSL → HSV):",-1)),e("div",w,s(o(m)),1),t[11]||(t[11]=d("<hr><h2>Common Applications</h2><ol><li><strong>Color pickers</strong>: The dominant model in Photoshop, Illustrator, Figma, and most design tools.</li><li><strong>Computer vision</strong>: Used for image segmentation and object detection where hue separation matters.</li><li><strong>Data visualization</strong>: Systematic variation of saturation or value for encoding data.</li><li><strong>Digital painting</strong>: Artists adjust brightness and saturation independently of hue.</li><li><strong>UI/UX design</strong>: Palette generation from a base hue by sweeping saturation and value.</li></ol>",3))]))}};export{A as default};
@@ -0,0 +1 @@
1
+ import{K as n,d as h,e as p}from"./Katex-ClrxLHTj.js";import{g as m}from"./index-Q19pIqw1.js";import{J as g,V as w,a0 as o,a1 as s,a2 as i,u as t,a6 as u,N as l}from"./vendor-highlight-sMWp9TLU.js";import"./vendor-katex-Dehg5p_Y.js";import"./vendor-prettier-wO8BBsoP.js";const v={class:"markdown-body"},b={class:"language-typescript"},f={class:"language-typescript"},C={__name:"hwb",setup(B,{expose:c}){c({frontmatter:{}});const{h:r,w:a,b:d}=m("hwb");return(y,e)=>(g(),w("div",v,[e[6]||(e[6]=o("h3",null,"Attributes",-1)),o("ul",null,[o("li",null,[e[0]||(e[0]=o("code",null,"H",-1)),s(": Hue ("+i(t(r).min)+" to "+i(t(r).max)+")",1)]),o("li",null,[e[1]||(e[1]=o("code",null,"W",-1)),s(": Whiteness ("+i(t(a).min)+" to "+i(t(a).max)+")",1)]),o("li",null,[e[2]||(e[2]=o("code",null,"B",-1)),s(": Blackness ("+i(t(d).min)+" to "+i(t(d).max)+")",1)])]),e[7]||(e[7]=u("<h3>Background</h3><p>HWB (Hue, Whiteness, Blackness) was proposed by Alvy Ray Smith in 1996 to match how painters actually think: pick a hue, then mix in white or black. It’s derived from HSV but replaces saturation and value with two more direct controls—how much white and how much black to add. HWB is part of <strong>CSS Color Level 4</strong>, so it’s natively available in modern browsers via <code>hwb()</code>.</p><p>The gamut is the same as sRGB. It’s a reorganization of the same color cube, not a new one.</p><hr><h2>Color Model</h2><h3>Components</h3><ol><li><p><strong><code>H</code> (Hue)</strong>: <code>H = 0° \\text{ to } 360°</code> (often normalized to 0–1)</p><p>Base color on the wheel:</p><ul><li>0°/360° = Red</li><li>60° = Yellow</li><li>120° = Green</li><li>180° = Cyan</li><li>240° = Blue</li><li>300° = Magenta</li></ul></li><li><p><strong><code>W</code> (Whiteness)</strong>: <code>W = 0 \\text{ (no white) to } 1 \\text{ (pure white)}</code></p><p>How much white is mixed into the hue. Higher values produce tints.</p></li><li><p><strong><code>B</code> (Blackness)</strong>: <code>B = 0 \\text{ (no black) to } 1 \\text{ (pure black)}</code></p><p>How much black is mixed into the hue. Higher values produce shades.</p></li></ol><p><strong><code>W + B</code> should not exceed <code>1</code>.</strong> When it does, the color collapses to a grayscale value determined by the ratio <code>W / (W + B)</code>, and hue is effectively ignored.</p><hr><h2>Advantages</h2><ul><li>Mirrors the artist’s mental model—tint and shade are first-class operations</li><li>Easy to create systematic tint/shade ramps from a single hue</li><li>Native CSS support via <code>hwb()</code> in Color Level 4</li><li>Simpler to reason about than HSL’s lightness/saturation interaction</li></ul><h2>Disadvantages</h2><ul><li>Not perceptually uniform—equal numeric steps don’t produce equal visual steps</li><li><code>W</code> and <code>B</code> aren’t independent (their sum is constrained)</li><li>Less widely supported in design tools than HSL or HSV</li></ul><hr><h2>Color Conversions</h2><h3>HSL to HWB</h3><p>Convert through HSV as an intermediate—whiteness and blackness derive directly from HSV’s saturation and value:</p>",17)),l(t(n),{expression:"W = V(1 - S_V), \\quad B = 1 - V"}),o("div",b,i(t(h)),1),e[8]||(e[8]=o("h3",null,"HWB to HSL",-1)),e[9]||(e[9]=o("p",null,[s("Recover HSV saturation and value from whiteness and blackness (normalizing when "),o("code",null,"W + B ≥ 1"),s("), then convert HSV → HSL:")],-1)),l(t(n),{expression:"V = 1 - B, \\quad S_V = \\begin{cases} 0 & V = 0 \\\\ 1 - W/V & \\text{otherwise} \\end{cases}"}),o("p",null,[e[3]||(e[3]=s("When ",-1)),l(t(n),{expression:"W + B \\geq 1","display-mode":!1}),e[4]||(e[4]=s(", the color collapses to gray: ",-1)),l(t(n),{expression:"V = W/(W+B),\\; S_V = 0","display-mode":!1}),e[5]||(e[5]=s(".",-1))]),o("div",f,i(t(p)),1),e[10]||(e[10]=u("<hr><h2>Common Applications</h2><ol><li><strong>Web design</strong>: First-class CSS function (<code>hwb()</code>), useful for declaring tints and shades directly in stylesheets.</li><li><strong>Color pickers</strong>: Some modern pickers expose HWB as a triangle or square selector—whiteness on one axis, blackness on the other.</li><li><strong>Palette generation</strong>: Sweep <code>W</code> and <code>B</code> for a given hue to produce coherent tint/shade ramps.</li><li><strong>Accessibility</strong>: Straightforward to create high-contrast variants—push <code>B</code> up for darker, <code>W</code> up for lighter.</li><li><strong>Education</strong>: The tint-shade-tone model maps directly to traditional color theory vocabulary.</li></ol>",3))]))}};export{C as default};