@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.
- package/README.md +128 -9
- package/dist/CNAME +1 -0
- package/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/dist/assets/Katex-ClrxLHTj.js +131 -0
- package/dist/assets/Katex-rb5Khf8S.css +1 -0
- package/dist/assets/favicon-BpOvZXpk.svg +20 -0
- package/dist/assets/hsl-hvHpFpJT.js +1 -0
- package/dist/assets/hsv-Dw3FShnj.js +1 -0
- package/dist/assets/hwb-pA6JoiNj.js +1 -0
- package/dist/assets/index-Q19pIqw1.js +32 -0
- package/dist/assets/index-VnEkwzsm.css +1 -0
- package/dist/assets/kelvin-Csjui27y.js +1 -0
- package/dist/assets/lab-DAj67vs8.js +1 -0
- package/dist/assets/lch-D_dY1vUG.js +1 -0
- package/dist/assets/oklab-BPM7MOIw.js +1 -0
- package/dist/assets/oklch-DwTrS_34.js +1 -0
- package/dist/assets/rgb-BLbQuf-A.js +1 -0
- package/dist/assets/vendor-highlight-sMWp9TLU.js +3 -0
- package/dist/assets/vendor-katex-Dehg5p_Y.js +261 -0
- package/dist/assets/vendor-prettier-wO8BBsoP.js +166 -0
- package/dist/assets/xyz-CX5zPyPG.js +3 -0
- package/dist/index.html +18 -0
- package/package.json +3 -3
- package/dist/value.cjs +0 -8
- package/dist/value.d.ts +0 -1995
- package/dist/value.js +0 -4917
package/README.md
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
# value.js 
|
|
2
2
|
|
|
3
|
-
CSS value
|
|
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
|
|
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
|
-
-
|
|
11
|
-
-
|
|
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 {
|
|
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
|
|
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
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -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};
|