@botharness/pixel-avatar 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/index.d.ts +82 -5
- package/dist/index.js +242 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,5 +20,7 @@ const svg = pixelAvatarSvg(recipe); // 32×32 viewBox, crisp edges, no ids or sc
|
|
|
20
20
|
- `AVATAR_HAIR_PARTS`, `AVATAR_RANGES`, `detailedRecipe(recipe)`: optional finer controls. A recipe may carry `bangs`, `sideHair`, `backHair`, `spacing`, `height` and `hairLength`, all six or none; `detailedRecipe` derives them from the plain `hair` so an editor can start from what is on screen. Recipes without them render exactly as before.
|
|
21
21
|
- `AVATAR_SPECIES`, `AVATAR_SPECIES_SWATCHES`, `AVATAR_PIECE_COLORS`, `withSpecies(recipe, species)`: Avatar Species (`human`, `goblin`) on the same rig, as asset version 2. `withSpecies` keeps every choice, splits side hair into `sideHair` (left) and `rightSideHair`, and accepts optional `leftSideHairColor`/`rightSideHairColor`, where left and right are as seen on screen. Consumers built before version 2 reject these recipes with `isPixelAvatarRecipe` and can show a saved snapshot instead.
|
|
22
22
|
- `AVATAR_PARTS_V2`, `AVATAR_EXTRA_PARTS`, `hiddenChoices(recipe)`: version 2 adds elf, dwarf, orc and flower species, armor/robe/tunic/cloak outfits, helmet/hood headwear, an optional `beard`, and a flower's `petals` and `flowerBase`. `hiddenChoices` names saved choices the current species or headwear keeps but does not draw, so an editor can say so instead of discarding them.
|
|
23
|
+
- `PixelCustomPart`, `withHeadpiece(recipe, part)`, `customPartId`, `isPixelCustomPart`: a Human-drawn Custom Part in the `headpiece` slot (the top 32×16 of the tile). Its back layer is drawn behind the hair and its front layer over it, and both follow the head through turns. Each cell is `[x, y, color, tone]`, where `color` is an appearance color slot (`hairColor`, `skinColor`, `eyeColor`, `shirtColor`), so the part recolors with the Avatar, or a fixed `#rrggbb`, and `tone` is a step from −2 to 2 on the rig's shade ramp (`partToneColor`). A recipe wearing a part embeds its own copy as asset version 3. `customPartId` is the SHA-256 of the canonical content; names, authors and origins belong to the consumer's library.
|
|
24
|
+
- `emptyPartLayer`, `paintPartLayer`, `fillPartLayer`, `mirrorPartX`, `partLayer`, `partCells`, `createCustomPart`: drawing on dense layers, with pencil and eraser strokes, 4-connected flood fill and mirroring across the Avatar centerline.
|
|
23
25
|
- `faceCells`, `pixelSymbolCells`, `symbolArtCells`: pixels for [`@botharness/pixel-morph`](../morph).
|
|
24
26
|
- `pixelAvatarSvg(recipe, { turns, classPrefix })`: optional pre-rendered head turns, and rig layer classes (`<prefix>-body`, `-head`, `-face`, `-gaze`, `-blink`) for CSS animation.
|
package/dist/index.d.ts
CHANGED
|
@@ -72,7 +72,9 @@ type PixelAvatarRecipeV1 = Meta & {
|
|
|
72
72
|
} & { [P in AvatarPart]: (typeof AVATAR_PARTS)[P][number] } & { [P in AvatarHairPart]?: (typeof AVATAR_PARTS)['hair'][number] } & { [P in AvatarRange]?: number } & {
|
|
73
73
|
species?: never;
|
|
74
74
|
rightSideHair?: never;
|
|
75
|
-
} & { [P in AvatarPieceColor | AvatarExtraPart]?: never }
|
|
75
|
+
} & { [P in AvatarPieceColor | AvatarExtraPart]?: never } & {
|
|
76
|
+
headpiece?: never;
|
|
77
|
+
};
|
|
76
78
|
/**
|
|
77
79
|
* Asset version 2: a species, the full split hair and geometry, a separate right side hair
|
|
78
80
|
* (`sideHair` is then the left side) and optional per-side hair colors.
|
|
@@ -82,8 +84,15 @@ type PixelAvatarRecipeV2 = Meta & {
|
|
|
82
84
|
} & { [P in AvatarPart]: (typeof AVATAR_PARTS_V2)[P][number] } & { [P in AvatarHairPart]: (typeof AVATAR_PARTS)['hair'][number] } & { [P in AvatarRange]: number } & {
|
|
83
85
|
species: AvatarSpecies;
|
|
84
86
|
rightSideHair: (typeof AVATAR_HAIR_PARTS)['sideHair'][number];
|
|
85
|
-
} & { [P in AvatarPieceColor]?: string } & { [P in AvatarExtraPart]?: (typeof AVATAR_EXTRA_PARTS)[P][number] }
|
|
86
|
-
|
|
87
|
+
} & { [P in AvatarPieceColor]?: string } & { [P in AvatarExtraPart]?: (typeof AVATAR_EXTRA_PARTS)[P][number] } & {
|
|
88
|
+
headpiece?: never;
|
|
89
|
+
};
|
|
90
|
+
/** Asset version 3: version 2 with an embedded Custom Part in the headpiece slot. */
|
|
91
|
+
type PixelAvatarRecipeV3 = Omit<PixelAvatarRecipeV2, 'assetVersion' | 'headpiece'> & {
|
|
92
|
+
assetVersion: 3;
|
|
93
|
+
headpiece: PixelCustomPart;
|
|
94
|
+
};
|
|
95
|
+
type PixelAvatarRecipe = PixelAvatarRecipeV1 | PixelAvatarRecipeV2 | PixelAvatarRecipeV3;
|
|
87
96
|
declare const DEFAULT_RECIPE: PixelAvatarRecipeV1;
|
|
88
97
|
declare function isPixelAvatarRecipe(value: unknown): value is PixelAvatarRecipe;
|
|
89
98
|
declare function canonicalRecipe(recipe: PixelAvatarRecipe): PixelAvatarRecipe;
|
|
@@ -99,7 +108,14 @@ declare function hiddenChoices(recipe: PixelAvatarRecipe): readonly string[];
|
|
|
99
108
|
* When the skin color is one of the previous species' suggested colors, it moves to the new
|
|
100
109
|
* species' first suggestion; a custom color is kept.
|
|
101
110
|
*/
|
|
102
|
-
declare function withSpecies(recipe:
|
|
111
|
+
declare function withSpecies(recipe: PixelAvatarRecipeV3, species: AvatarSpecies): PixelAvatarRecipeV3;
|
|
112
|
+
declare function withSpecies(recipe: PixelAvatarRecipeV1 | PixelAvatarRecipeV2, species: AvatarSpecies): PixelAvatarRecipeV2;
|
|
113
|
+
declare function withSpecies(recipe: PixelAvatarRecipe, species: AvatarSpecies): PixelAvatarRecipeV2 | PixelAvatarRecipeV3;
|
|
114
|
+
/**
|
|
115
|
+
* Returns the recipe wearing a Custom Part in the headpiece slot (asset version 3), or without
|
|
116
|
+
* one (asset version 2). The recipe embeds its own copy of the part.
|
|
117
|
+
*/
|
|
118
|
+
declare function withHeadpiece(recipe: PixelAvatarRecipe, part: PixelCustomPart | undefined): PixelAvatarRecipeV2 | PixelAvatarRecipeV3;
|
|
103
119
|
declare function detailedRecipe(recipe: PixelAvatarRecipe): PixelAvatarRecipe;
|
|
104
120
|
declare const AVATAR_SWATCHES: Record<AvatarColor, readonly string[]>;
|
|
105
121
|
/**
|
|
@@ -122,6 +138,65 @@ declare const seededRecipe: (seed: string) => PixelAvatarRecipe;
|
|
|
122
138
|
declare const AVATAR_SPECIES_SWATCHES: Record<AvatarSpecies, readonly string[]>;
|
|
123
139
|
declare const AVATAR_PRESETS: readonly PixelAvatarRecipe[];
|
|
124
140
|
//#endregion
|
|
141
|
+
//#region src/part.d.ts
|
|
142
|
+
/**
|
|
143
|
+
* Custom Part slots. A headpiece covers the top of the tile, around the hair: its back layer is
|
|
144
|
+
* drawn behind the hair and its front layer over it. Cells are in tile coordinates, so the
|
|
145
|
+
* Avatar centerline sits between x = 15 and x = 16.
|
|
146
|
+
*/
|
|
147
|
+
declare const PART_SLOTS: {
|
|
148
|
+
readonly headpiece: {
|
|
149
|
+
readonly width: 32;
|
|
150
|
+
readonly height: 16;
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
type PartSlot = keyof typeof PART_SLOTS;
|
|
154
|
+
/** Tone steps on the rig's shade ramp: two darker, the color itself, two lighter. */
|
|
155
|
+
declare const PART_TONES: readonly [-2, -1, 0, 1, 2];
|
|
156
|
+
type PartTone = (typeof PART_TONES)[number];
|
|
157
|
+
/** An appearance color slot (it follows the Avatar's color) or a fixed `#rrggbb` color. */
|
|
158
|
+
type PartColor = AvatarColor | `#${string}`;
|
|
159
|
+
/** One painted cell: `[x, y, color, tone]`. */
|
|
160
|
+
type PartCell = readonly [x: number, y: number, color: PartColor, tone: PartTone];
|
|
161
|
+
declare const PART_LAYERS: readonly ["front", "back"];
|
|
162
|
+
type PartLayerName = (typeof PART_LAYERS)[number];
|
|
163
|
+
/** Most fixed colors one part may use. */
|
|
164
|
+
declare const MAX_PART_FIXED_COLORS = 16;
|
|
165
|
+
/**
|
|
166
|
+
* A Human-drawn Custom Part. Its content is immutable and its identity is `customPartId`;
|
|
167
|
+
* name, author, origin and parent are metadata kept outside it.
|
|
168
|
+
*/
|
|
169
|
+
interface PixelCustomPart {
|
|
170
|
+
slot: PartSlot;
|
|
171
|
+
front: readonly PartCell[];
|
|
172
|
+
back: readonly PartCell[];
|
|
173
|
+
}
|
|
174
|
+
/** A dense layer for drawing: `layer[y][x]` is a color and tone, or `null` when empty. */
|
|
175
|
+
type PartInk = {
|
|
176
|
+
color: PartColor;
|
|
177
|
+
tone: PartTone;
|
|
178
|
+
};
|
|
179
|
+
type PartLayer = (PartInk | null)[][];
|
|
180
|
+
declare function isPixelCustomPart(value: unknown): value is PixelCustomPart;
|
|
181
|
+
/** The part with cells in row order and fixed colors in lowercase. */
|
|
182
|
+
declare function canonicalCustomPart(part: PixelCustomPart): PixelCustomPart;
|
|
183
|
+
/** Content identity: a SHA-256 of the canonical slot, cells and color references. */
|
|
184
|
+
declare function customPartId(part: PixelCustomPart): string;
|
|
185
|
+
declare function emptyPartLayer(slot: PartSlot): PartLayer;
|
|
186
|
+
declare function partLayer(slot: PartSlot, cells: readonly PartCell[]): PartLayer;
|
|
187
|
+
declare function partCells(layer: PartLayer): PartCell[];
|
|
188
|
+
/** Builds a canonical part from two drawn layers. */
|
|
189
|
+
declare function createCustomPart(slot: PartSlot, layers: Record<PartLayerName, PartLayer>): PixelCustomPart;
|
|
190
|
+
/** The column mirrored across the Avatar centerline. */
|
|
191
|
+
declare function mirrorPartX(slot: PartSlot, x: number): number;
|
|
192
|
+
/** Sets cells (pencil with ink, eraser with `null`), optionally mirrored across the centerline. */
|
|
193
|
+
declare function paintPartLayer(slot: PartSlot, layer: PartLayer, points: readonly (readonly [number, number])[], ink: PartInk | null, mirror?: boolean): PartLayer;
|
|
194
|
+
/**
|
|
195
|
+
* 4-connected flood fill from a cell: every cell reachable through cells equal to the start
|
|
196
|
+
* becomes `ink`. With `mirror`, the mirrored start is filled too.
|
|
197
|
+
*/
|
|
198
|
+
declare function fillPartLayer(slot: PartSlot, layer: PartLayer, x: number, y: number, ink: PartInk | null, mirror?: boolean): PartLayer;
|
|
199
|
+
//#endregion
|
|
125
200
|
//#region src/figure.d.ts
|
|
126
201
|
type Cell = string | undefined;
|
|
127
202
|
type Grid = Cell[][];
|
|
@@ -130,6 +205,8 @@ type PixelMouthState = 'saved' | 'closed' | 'half-open' | 'open';
|
|
|
130
205
|
interface PixelFigureOptions {
|
|
131
206
|
mouthLayers?: boolean;
|
|
132
207
|
}
|
|
208
|
+
/** The color a Custom Part cell shows at a tone step on the rig's shade ramp. */
|
|
209
|
+
declare function partToneColor(color: string, tone: PartTone): string;
|
|
133
210
|
type Recipe = PixelAvatarRecipe;
|
|
134
211
|
declare function pixelTileColor(hair: string): string;
|
|
135
212
|
declare function pixelFigure(recipe: Recipe, yawDeg: number, options?: PixelFigureOptions): {
|
|
@@ -187,5 +264,5 @@ declare function pixelSymbolCells(symbol: PixelSymbol, color: string): PixelCell
|
|
|
187
264
|
*/
|
|
188
265
|
declare function symbolArtCells(rows: readonly string[], color: string): PixelCell$1[];
|
|
189
266
|
//#endregion
|
|
190
|
-
export { AVATAR_COLORS, AVATAR_EXTRA_PARTS, AVATAR_HAIR_PARTS, AVATAR_PARTS, AVATAR_PARTS_V2, AVATAR_PIECE_COLORS, AVATAR_PRESETS, AVATAR_RANGES, AVATAR_SPECIES, AVATAR_SPECIES_SWATCHES, AVATAR_SWATCHES, AVATAR_TURNS, type AvatarColor, type AvatarExtraPart, type AvatarHairPart, type AvatarPart, type AvatarPieceColor, type AvatarRange, type AvatarSpecies, DEFAULT_RECIPE, PIXEL_SYMBOLS, type PixelAvatarRecipe, type PixelAvatarRecipeV1, type PixelAvatarRecipeV2, type PixelAvatarSvgOptions, type PixelCell, type PixelFigureOptions, type PixelGrid, type PixelMouthState, type PixelSymbol, canonicalRecipe, createSeededRecipe, createSeededRecipeV2, detailedRecipe, faceCells, hiddenChoices, isPixelAvatarRecipe, pixelAvatarSvg, pixelFigure, pixelSymbolCells, pixelTileColor, seededRandom, seededRecipe, seededRecipeV2, symbolArtCells, withSpecies };
|
|
267
|
+
export { AVATAR_COLORS, AVATAR_EXTRA_PARTS, AVATAR_HAIR_PARTS, AVATAR_PARTS, AVATAR_PARTS_V2, AVATAR_PIECE_COLORS, AVATAR_PRESETS, AVATAR_RANGES, AVATAR_SPECIES, AVATAR_SPECIES_SWATCHES, AVATAR_SWATCHES, AVATAR_TURNS, type AvatarColor, type AvatarExtraPart, type AvatarHairPart, type AvatarPart, type AvatarPieceColor, type AvatarRange, type AvatarSpecies, DEFAULT_RECIPE, MAX_PART_FIXED_COLORS, PART_LAYERS, PART_SLOTS, PART_TONES, PIXEL_SYMBOLS, type PartCell, type PartColor, type PartInk, type PartLayer, type PartLayerName, type PartSlot, type PartTone, type PixelAvatarRecipe, type PixelAvatarRecipeV1, type PixelAvatarRecipeV2, type PixelAvatarRecipeV3, type PixelAvatarSvgOptions, type PixelCell, type PixelCustomPart, type PixelFigureOptions, type PixelGrid, type PixelMouthState, type PixelSymbol, canonicalCustomPart, canonicalRecipe, createCustomPart, createSeededRecipe, createSeededRecipeV2, customPartId, detailedRecipe, emptyPartLayer, faceCells, fillPartLayer, hiddenChoices, isPixelAvatarRecipe, isPixelCustomPart, mirrorPartX, paintPartLayer, partCells, partLayer, partToneColor, pixelAvatarSvg, pixelFigure, pixelSymbolCells, pixelTileColor, seededRandom, seededRecipe, seededRecipeV2, symbolArtCells, withHeadpiece, withSpecies };
|
|
191
268
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,191 @@
|
|
|
1
1
|
import { escapeAttribute } from "@botharness/pixel-morph";
|
|
2
2
|
|
|
3
|
+
//#region src/part.ts
|
|
4
|
+
/**
|
|
5
|
+
* Custom Part slots. A headpiece covers the top of the tile, around the hair: its back layer is
|
|
6
|
+
* drawn behind the hair and its front layer over it. Cells are in tile coordinates, so the
|
|
7
|
+
* Avatar centerline sits between x = 15 and x = 16.
|
|
8
|
+
*/
|
|
9
|
+
const PART_SLOTS = { headpiece: {
|
|
10
|
+
width: 32,
|
|
11
|
+
height: 16
|
|
12
|
+
} };
|
|
13
|
+
/** Tone steps on the rig's shade ramp: two darker, the color itself, two lighter. */
|
|
14
|
+
const PART_TONES = [
|
|
15
|
+
-2,
|
|
16
|
+
-1,
|
|
17
|
+
0,
|
|
18
|
+
1,
|
|
19
|
+
2
|
|
20
|
+
];
|
|
21
|
+
const PART_LAYERS = ["front", "back"];
|
|
22
|
+
/** Most fixed colors one part may use. */
|
|
23
|
+
const MAX_PART_FIXED_COLORS = 16;
|
|
24
|
+
const FIXED = /^#[\da-f]{6}$/iu;
|
|
25
|
+
const isColor = (value) => typeof value === "string" && (AVATAR_COLORS.includes(value) || FIXED.test(value));
|
|
26
|
+
function isPixelCustomPart(value) {
|
|
27
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
28
|
+
const r = value;
|
|
29
|
+
if (Object.keys(r).length !== 3 || !Object.hasOwn(PART_SLOTS, r["slot"])) return false;
|
|
30
|
+
const { width, height } = PART_SLOTS[r["slot"]];
|
|
31
|
+
const fixed = /* @__PURE__ */ new Set();
|
|
32
|
+
for (const name of PART_LAYERS) {
|
|
33
|
+
const cells = r[name];
|
|
34
|
+
if (!Array.isArray(cells) || cells.length > width * height) return false;
|
|
35
|
+
const seen = /* @__PURE__ */ new Set();
|
|
36
|
+
for (const cell of cells) {
|
|
37
|
+
if (!Array.isArray(cell) || cell.length !== 4) return false;
|
|
38
|
+
const [x, y, color, tone] = cell;
|
|
39
|
+
if (!Number.isInteger(x) || !Number.isInteger(y) || x < 0 || x >= width || y < 0 || y >= height || !isColor(color) || !PART_TONES.includes(tone)) return false;
|
|
40
|
+
const key = y * width + x;
|
|
41
|
+
if (seen.has(key)) return false;
|
|
42
|
+
seen.add(key);
|
|
43
|
+
if (color.startsWith("#")) fixed.add(color.toLowerCase());
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return fixed.size <= MAX_PART_FIXED_COLORS;
|
|
47
|
+
}
|
|
48
|
+
const canonicalCells = (cells) => cells.map(([x, y, color, tone]) => [
|
|
49
|
+
x,
|
|
50
|
+
y,
|
|
51
|
+
color.startsWith("#") ? color.toLowerCase() : color,
|
|
52
|
+
tone
|
|
53
|
+
]).sort((a, b) => a[1] - b[1] || a[0] - b[0]);
|
|
54
|
+
/** The part with cells in row order and fixed colors in lowercase. */
|
|
55
|
+
function canonicalCustomPart(part) {
|
|
56
|
+
return {
|
|
57
|
+
slot: part.slot,
|
|
58
|
+
front: canonicalCells(part.front),
|
|
59
|
+
back: canonicalCells(part.back)
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/** Content identity: a SHA-256 of the canonical slot, cells and color references. */
|
|
63
|
+
function customPartId(part) {
|
|
64
|
+
return sha256(JSON.stringify(canonicalCustomPart(part)));
|
|
65
|
+
}
|
|
66
|
+
function emptyPartLayer(slot) {
|
|
67
|
+
const { width, height } = PART_SLOTS[slot];
|
|
68
|
+
return Array.from({ length: height }, () => Array(width).fill(null));
|
|
69
|
+
}
|
|
70
|
+
function partLayer(slot, cells) {
|
|
71
|
+
const layer = emptyPartLayer(slot);
|
|
72
|
+
for (const [x, y, color, tone] of cells) layer[y][x] = {
|
|
73
|
+
color,
|
|
74
|
+
tone
|
|
75
|
+
};
|
|
76
|
+
return layer;
|
|
77
|
+
}
|
|
78
|
+
function partCells(layer) {
|
|
79
|
+
return layer.flatMap((row, y) => row.flatMap((ink, x) => ink ? [[
|
|
80
|
+
x,
|
|
81
|
+
y,
|
|
82
|
+
ink.color,
|
|
83
|
+
ink.tone
|
|
84
|
+
]] : []));
|
|
85
|
+
}
|
|
86
|
+
/** Builds a canonical part from two drawn layers. */
|
|
87
|
+
function createCustomPart(slot, layers) {
|
|
88
|
+
return canonicalCustomPart({
|
|
89
|
+
slot,
|
|
90
|
+
front: partCells(layers.front),
|
|
91
|
+
back: partCells(layers.back)
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/** The column mirrored across the Avatar centerline. */
|
|
95
|
+
function mirrorPartX(slot, x) {
|
|
96
|
+
return PART_SLOTS[slot].width - 1 - x;
|
|
97
|
+
}
|
|
98
|
+
const same = (a, b) => a === b || a !== null && b !== null && a.color === b.color && a.tone === b.tone;
|
|
99
|
+
/** Sets cells (pencil with ink, eraser with `null`), optionally mirrored across the centerline. */
|
|
100
|
+
function paintPartLayer(slot, layer, points, ink, mirror = false) {
|
|
101
|
+
const out = layer.map((row) => [...row]);
|
|
102
|
+
const { width, height } = PART_SLOTS[slot];
|
|
103
|
+
for (const [x, y] of points) for (const px of mirror ? [x, mirrorPartX(slot, x)] : [x]) if (px >= 0 && px < width && y >= 0 && y < height) out[y][px] = ink;
|
|
104
|
+
return out;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 4-connected flood fill from a cell: every cell reachable through cells equal to the start
|
|
108
|
+
* becomes `ink`. With `mirror`, the mirrored start is filled too.
|
|
109
|
+
*/
|
|
110
|
+
function fillPartLayer(slot, layer, x, y, ink, mirror = false) {
|
|
111
|
+
const { width, height } = PART_SLOTS[slot];
|
|
112
|
+
let out = layer.map((row) => [...row]);
|
|
113
|
+
for (const sx of mirror ? [x, mirrorPartX(slot, x)] : [x]) {
|
|
114
|
+
if (sx < 0 || sx >= width || y < 0 || y >= height) continue;
|
|
115
|
+
const target = out[y][sx];
|
|
116
|
+
if (same(target, ink)) continue;
|
|
117
|
+
const next = out.map((row) => [...row]);
|
|
118
|
+
const stack = [[sx, y]];
|
|
119
|
+
while (stack.length) {
|
|
120
|
+
const [cx, cy] = stack.pop();
|
|
121
|
+
if (cx < 0 || cx >= width || cy < 0 || cy >= height) continue;
|
|
122
|
+
if (!same(next[cy][cx], target)) continue;
|
|
123
|
+
next[cy][cx] = ink;
|
|
124
|
+
stack.push([cx + 1, cy], [cx - 1, cy], [cx, cy + 1], [cx, cy - 1]);
|
|
125
|
+
}
|
|
126
|
+
out = next;
|
|
127
|
+
}
|
|
128
|
+
return out;
|
|
129
|
+
}
|
|
130
|
+
const K = Uint32Array.from("428a2f98 71374491 b5c0fbcf e9b5dba5 3956c25b 59f111f1 923f82a4 ab1c5ed5 d807aa98 12835b01 243185be 550c7dc3 72be5d74 80deb1fe 9bdc06a7 c19bf174 e49b69c1 efbe4786 0fc19dc6 240ca1cc 2de92c6f 4a7484aa 5cb0a9dc 76f988da 983e5152 a831c66d b00327c8 bf597fc7 c6e00bf3 d5a79147 06ca6351 14292967 27b70a85 2e1b2138 4d2c6dfc 53380d13 650a7354 766a0abb 81c2c92e 92722c85 a2bfe8a1 a81a664b c24b8b70 c76c51a3 d192e819 d6990624 f40e3585 106aa070 19a4c116 1e376c08 2748774c 34b0bcb5 391c0cb3 4ed8aa4a 5b9cca4f 682e6ff3 748f82ee 78a5636f 84c87814 8cc70208 90befffa a4506ceb bef9a3f7 c67178f2".split(" ").map((h) => Number.parseInt(h, 16)));
|
|
131
|
+
function sha256(text) {
|
|
132
|
+
const bytes = new TextEncoder().encode(text);
|
|
133
|
+
const length = Math.ceil((bytes.length + 9) / 64) * 64;
|
|
134
|
+
const data = new Uint8Array(length);
|
|
135
|
+
data.set(bytes);
|
|
136
|
+
data[bytes.length] = 128;
|
|
137
|
+
const view = new DataView(data.buffer);
|
|
138
|
+
view.setUint32(length - 8, Math.floor(bytes.length * 8 / 2 ** 32));
|
|
139
|
+
view.setUint32(length - 4, bytes.length * 8 >>> 0);
|
|
140
|
+
const h = Uint32Array.from([
|
|
141
|
+
1779033703,
|
|
142
|
+
3144134277,
|
|
143
|
+
1013904242,
|
|
144
|
+
2773480762,
|
|
145
|
+
1359893119,
|
|
146
|
+
2600822924,
|
|
147
|
+
528734635,
|
|
148
|
+
1541459225
|
|
149
|
+
]);
|
|
150
|
+
const w = new Uint32Array(64);
|
|
151
|
+
const rotr = (v, n) => v >>> n | v << 32 - n;
|
|
152
|
+
for (let offset = 0; offset < length; offset += 64) {
|
|
153
|
+
for (let i = 0; i < 16; i++) w[i] = view.getUint32(offset + i * 4);
|
|
154
|
+
for (let i = 16; i < 64; i++) {
|
|
155
|
+
const a = w[i - 15];
|
|
156
|
+
const b = w[i - 2];
|
|
157
|
+
const s0 = rotr(a, 7) ^ rotr(a, 18) ^ a >>> 3;
|
|
158
|
+
const s1 = rotr(b, 17) ^ rotr(b, 19) ^ b >>> 10;
|
|
159
|
+
w[i] = w[i - 16] + s0 + w[i - 7] + s1 >>> 0;
|
|
160
|
+
}
|
|
161
|
+
let [a, b, c, d, e, f, g, k] = h;
|
|
162
|
+
for (let i = 0; i < 64; i++) {
|
|
163
|
+
const t1 = k + (rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)) + (e & f ^ ~e & g) + K[i] + w[i] >>> 0;
|
|
164
|
+
const t2 = (rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) + (a & b ^ a & c ^ b & c) >>> 0;
|
|
165
|
+
k = g;
|
|
166
|
+
g = f;
|
|
167
|
+
f = e;
|
|
168
|
+
e = d + t1 >>> 0;
|
|
169
|
+
d = c;
|
|
170
|
+
c = b;
|
|
171
|
+
b = a;
|
|
172
|
+
a = t1 + t2 >>> 0;
|
|
173
|
+
}
|
|
174
|
+
[
|
|
175
|
+
a,
|
|
176
|
+
b,
|
|
177
|
+
c,
|
|
178
|
+
d,
|
|
179
|
+
e,
|
|
180
|
+
f,
|
|
181
|
+
g,
|
|
182
|
+
k
|
|
183
|
+
].forEach((v, i) => h[i] = h[i] + v >>> 0);
|
|
184
|
+
}
|
|
185
|
+
return [...h].map((v) => v.toString(16).padStart(8, "0")).join("");
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
//#endregion
|
|
3
189
|
//#region src/random.ts
|
|
4
190
|
function seededRandom(seed) {
|
|
5
191
|
let h = 2166136261;
|
|
@@ -393,10 +579,12 @@ function isPixelAvatarRecipe(value) {
|
|
|
393
579
|
const r = value;
|
|
394
580
|
const detailed = DETAIL_KEYS.filter((key) => Object.hasOwn(r, key)).length;
|
|
395
581
|
if (detailed !== 0 && detailed !== DETAIL_KEYS.length) return false;
|
|
396
|
-
const
|
|
582
|
+
const v3 = r["assetVersion"] === 3;
|
|
583
|
+
const v2 = r["assetVersion"] === 2 || v3;
|
|
584
|
+
if (v3 ? !isPixelCustomPart(r["headpiece"]) : Object.hasOwn(r, "headpiece")) return false;
|
|
397
585
|
const pieces = AVATAR_PIECE_COLORS.filter((key) => Object.hasOwn(r, key));
|
|
398
586
|
const extras = Object.keys(AVATAR_EXTRA_PARTS).filter((key) => Object.hasOwn(r, key));
|
|
399
|
-
const v2Keys = v2 ? 2 + pieces.length + extras.length : 0;
|
|
587
|
+
const v2Keys = v2 ? 2 + pieces.length + extras.length + (v3 ? 1 : 0) : 0;
|
|
400
588
|
if (Object.keys(r).length !== Object.keys(DEFAULT_RECIPE).length + detailed + v2Keys) return false;
|
|
401
589
|
if (v2 && (detailed === 0 || !AVATAR_SPECIES.includes(r["species"]) || !AVATAR_HAIR_PARTS.sideHair.includes(r["rightSideHair"]) || !pieces.every((key) => typeof r[key] === "string" && /^#[\da-f]{6}$/iu.test(r[key])) || !extras.every((key) => AVATAR_EXTRA_PARTS[key].includes(r[key])))) return false;
|
|
402
590
|
const catalog = v2 ? AVATAR_PARTS_V2 : AVATAR_PARTS;
|
|
@@ -416,11 +604,12 @@ function canonicalRecipe(recipe) {
|
|
|
416
604
|
for (const key of PART_KEYS) canonical[key] = recipe[key];
|
|
417
605
|
for (const key of AVATAR_COLORS) canonical[key] = recipe[key].toLowerCase();
|
|
418
606
|
if (recipe.bangs !== void 0) for (const key of DETAIL_KEYS) canonical[key] = recipe[key];
|
|
419
|
-
if (recipe.assetVersion
|
|
607
|
+
if (recipe.assetVersion !== 1) {
|
|
420
608
|
canonical["species"] = recipe.species;
|
|
421
609
|
canonical["rightSideHair"] = recipe.rightSideHair;
|
|
422
610
|
for (const key of AVATAR_PIECE_COLORS) if (recipe[key] !== void 0) canonical[key] = recipe[key].toLowerCase();
|
|
423
611
|
for (const key of Object.keys(AVATAR_EXTRA_PARTS)) if (recipe[key] !== void 0) canonical[key] = recipe[key];
|
|
612
|
+
if (recipe.assetVersion === 3) canonical["headpiece"] = canonicalCustomPart(recipe.headpiece);
|
|
424
613
|
}
|
|
425
614
|
return canonical;
|
|
426
615
|
}
|
|
@@ -452,24 +641,34 @@ function hiddenChoices(recipe) {
|
|
|
452
641
|
if (recipe.species === "dwarf") hidden.push("nose");
|
|
453
642
|
return hidden;
|
|
454
643
|
}
|
|
455
|
-
/**
|
|
456
|
-
* Returns the recipe as asset version 2 with the given species, keeping every other choice.
|
|
457
|
-
* Side hair splits into left (`sideHair`) and right (`rightSideHair`) pieces that start equal.
|
|
458
|
-
* When the skin color is one of the previous species' suggested colors, it moves to the new
|
|
459
|
-
* species' first suggestion; a custom color is kept.
|
|
460
|
-
*/
|
|
461
644
|
function withSpecies(recipe, species) {
|
|
462
645
|
const detailed = detailedRecipe(recipe);
|
|
463
646
|
const previous = recipe.species ?? "human";
|
|
464
647
|
const suggested = AVATAR_SPECIES_SWATCHES[previous].includes(recipe.skinColor.toLowerCase());
|
|
465
648
|
return {
|
|
466
649
|
...detailed,
|
|
467
|
-
assetVersion: 2,
|
|
650
|
+
assetVersion: recipe.assetVersion === 3 ? 3 : 2,
|
|
468
651
|
species,
|
|
469
652
|
rightSideHair: detailed.rightSideHair ?? detailed.sideHair,
|
|
470
653
|
skinColor: suggested && previous !== species ? AVATAR_SPECIES_SWATCHES[species][0] : recipe.skinColor
|
|
471
654
|
};
|
|
472
655
|
}
|
|
656
|
+
/**
|
|
657
|
+
* Returns the recipe wearing a Custom Part in the headpiece slot (asset version 3), or without
|
|
658
|
+
* one (asset version 2). The recipe embeds its own copy of the part.
|
|
659
|
+
*/
|
|
660
|
+
function withHeadpiece(recipe, part) {
|
|
661
|
+
const { headpiece: _, ...rest } = recipe.assetVersion === 1 ? withSpecies(recipe, "human") : recipe;
|
|
662
|
+
if (part === void 0) return {
|
|
663
|
+
...rest,
|
|
664
|
+
assetVersion: 2
|
|
665
|
+
};
|
|
666
|
+
return {
|
|
667
|
+
...rest,
|
|
668
|
+
assetVersion: 3,
|
|
669
|
+
headpiece: canonicalCustomPart(part)
|
|
670
|
+
};
|
|
671
|
+
}
|
|
473
672
|
function detailedRecipe(recipe) {
|
|
474
673
|
if (recipe.bangs !== void 0) return recipe;
|
|
475
674
|
const pick = (part) => AVATAR_HAIR_PARTS[part].includes(recipe.hair) ? recipe.hair : HAIR_SPLIT[recipe.hair][part];
|
|
@@ -856,6 +1055,17 @@ const mix$1 = (base, tint, k) => {
|
|
|
856
1055
|
const t = channels$1(tint);
|
|
857
1056
|
return hex(channels$1(base).map((v, i) => v * (1 - k) + t[i] * k));
|
|
858
1057
|
};
|
|
1058
|
+
const TONES = {
|
|
1059
|
+
[-2]: (c) => shade(c, .62),
|
|
1060
|
+
[-1]: (c) => shade(c, .8),
|
|
1061
|
+
0: (c) => c,
|
|
1062
|
+
1: (c) => mix$1(c, WHITE, .25),
|
|
1063
|
+
2: (c) => mix$1(c, WHITE, .5)
|
|
1064
|
+
};
|
|
1065
|
+
/** The color a Custom Part cell shows at a tone step on the rig's shade ramp. */
|
|
1066
|
+
function partToneColor(color, tone) {
|
|
1067
|
+
return TONES[tone](color.toLowerCase());
|
|
1068
|
+
}
|
|
859
1069
|
function paint(grid, test, color) {
|
|
860
1070
|
for (let y = 0; y < N; y++) for (let x = 0; x < N; x++) if (test(x, y)) grid[y][x] = color;
|
|
861
1071
|
}
|
|
@@ -1640,6 +1850,22 @@ function pixelFigure(recipe, yawDeg, options = {}) {
|
|
|
1640
1850
|
paint(back, (x, y) => petalRing(x, y) && x + .5 < C + s - 3 && y < 10, mix$1(hairColor, WHITE, .3));
|
|
1641
1851
|
} else paint(back, masks.back, shade(hairColor, .82));
|
|
1642
1852
|
if (masks.bands) paint(back, (x, y) => masks.back(x, y) && (y + Math.floor(x / 2)) % 4 === 0, shade(hairColor, .68));
|
|
1853
|
+
const headpiece = recipe.assetVersion === 3 ? recipe.headpiece : void 0;
|
|
1854
|
+
const placeCells = (grid, cells) => {
|
|
1855
|
+
const placed = cells.map(([x, y, color, tone]) => {
|
|
1856
|
+
const dx = x + .5 - C;
|
|
1857
|
+
const far = turned && d * dx < 0 && Math.abs(dx) >= 5;
|
|
1858
|
+
const base = color.startsWith("#") ? color.toLowerCase() : recipe[color];
|
|
1859
|
+
return {
|
|
1860
|
+
x: x + s + (far ? d : 0),
|
|
1861
|
+
y,
|
|
1862
|
+
c: TONES[tone](base),
|
|
1863
|
+
far
|
|
1864
|
+
};
|
|
1865
|
+
});
|
|
1866
|
+
for (const cell of [...placed.filter((p) => p.far), ...placed.filter((p) => !p.far)]) if (cell.x >= 0 && cell.x < N) grid[cell.y][cell.x] = cell.c;
|
|
1867
|
+
};
|
|
1868
|
+
if (headpiece) placeCells(back, headpiece.back);
|
|
1643
1869
|
const head = blank();
|
|
1644
1870
|
paint(head, face, skin);
|
|
1645
1871
|
const h = recipe.height ?? 0;
|
|
@@ -1728,11 +1954,14 @@ function pixelFigure(recipe, yawDeg, options = {}) {
|
|
|
1728
1954
|
}
|
|
1729
1955
|
return out;
|
|
1730
1956
|
};
|
|
1957
|
+
const crown = blank();
|
|
1958
|
+
if (headpiece) placeCells(crown, headpiece.front);
|
|
1731
1959
|
const figure = blank();
|
|
1732
1960
|
for (const layer of [
|
|
1733
1961
|
back,
|
|
1734
1962
|
body,
|
|
1735
|
-
shadeHair(head)
|
|
1963
|
+
shadeHair(head),
|
|
1964
|
+
crown
|
|
1736
1965
|
]) for (let y = 0; y < N; y++) for (let x = 0; x < N; x++) if (layer[y][x]) figure[y][x] = layer[y][x];
|
|
1737
1966
|
const features = blank();
|
|
1738
1967
|
const eyes = blank();
|
|
@@ -1879,7 +2108,7 @@ function pixelFigure(recipe, yawDeg, options = {}) {
|
|
|
1879
2108
|
for (let y = 0; y < N; y++) for (let x = 0; x < N; x++) {
|
|
1880
2109
|
const c = full[y][x];
|
|
1881
2110
|
if (!c) continue;
|
|
1882
|
-
if (y >= 22 && !head[y][x] && !back[y][x]) bodyCells[y][x] = c;
|
|
2111
|
+
if (y >= 22 && !head[y][x] && !back[y][x] && !crown[y][x]) bodyCells[y][x] = c;
|
|
1883
2112
|
else headCells[y][x] = c;
|
|
1884
2113
|
}
|
|
1885
2114
|
const cells = [];
|
|
@@ -2427,5 +2656,5 @@ function symbolArtCells(rows, color) {
|
|
|
2427
2656
|
}
|
|
2428
2657
|
|
|
2429
2658
|
//#endregion
|
|
2430
|
-
export { AVATAR_COLORS, AVATAR_EXTRA_PARTS, AVATAR_HAIR_PARTS, AVATAR_PARTS, AVATAR_PARTS_V2, AVATAR_PIECE_COLORS, AVATAR_PRESETS, AVATAR_RANGES, AVATAR_SPECIES, AVATAR_SPECIES_SWATCHES, AVATAR_SWATCHES, AVATAR_TURNS, DEFAULT_RECIPE, PIXEL_SYMBOLS, canonicalRecipe, createSeededRecipe, createSeededRecipeV2, detailedRecipe, faceCells, hiddenChoices, isPixelAvatarRecipe, pixelAvatarSvg, pixelFigure, pixelSymbolCells, pixelTileColor, seededRandom, seededRecipe, seededRecipeV2, symbolArtCells, withSpecies };
|
|
2659
|
+
export { AVATAR_COLORS, AVATAR_EXTRA_PARTS, AVATAR_HAIR_PARTS, AVATAR_PARTS, AVATAR_PARTS_V2, AVATAR_PIECE_COLORS, AVATAR_PRESETS, AVATAR_RANGES, AVATAR_SPECIES, AVATAR_SPECIES_SWATCHES, AVATAR_SWATCHES, AVATAR_TURNS, DEFAULT_RECIPE, MAX_PART_FIXED_COLORS, PART_LAYERS, PART_SLOTS, PART_TONES, PIXEL_SYMBOLS, canonicalCustomPart, canonicalRecipe, createCustomPart, createSeededRecipe, createSeededRecipeV2, customPartId, detailedRecipe, emptyPartLayer, faceCells, fillPartLayer, hiddenChoices, isPixelAvatarRecipe, isPixelCustomPart, mirrorPartX, paintPartLayer, partCells, partLayer, partToneColor, pixelAvatarSvg, pixelFigure, pixelSymbolCells, pixelTileColor, seededRandom, seededRecipe, seededRecipeV2, symbolArtCells, withHeadpiece, withSpecies };
|
|
2431
2660
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["INK","channels","mix"],"sources":["../src/random.ts","../src/recipe.ts","../src/figure.ts","../src/svg.ts","../src/symbols.ts"],"sourcesContent":["export function seededRandom(seed: string): () => number {\n let h = 2166136261;\n for (const char of seed) {\n h ^= char.codePointAt(0)!;\n h = Math.imul(h, 16777619);\n }\n return () => {\n h = Math.imul(h ^ (h >>> 15), 2246822507);\n h = Math.imul(h ^ (h >>> 13), 3266489909);\n h ^= h >>> 16;\n return (h >>> 0) / 4294967296;\n };\n}\n","import { seededRandom } from './random.js';\n\nexport const AVATAR_PARTS = {\n head: ['round', 'oval', 'square', 'long', 'heart', 'vchin', 'chubby', 'diamond'],\n pose: ['front', 'left', 'right'],\n hair: [\n 'crop',\n 'sweep',\n 'spiky',\n 'buzz',\n 'curly',\n 'mohawk',\n 'bob',\n 'long',\n 'bun',\n 'pigtails',\n 'afro',\n 'twintails',\n 'drills',\n 'ponytail',\n 'sidetail',\n 'hime',\n 'odango',\n 'messy',\n 'wavy',\n 'braids',\n 'wolf',\n 'ahoge',\n 'none',\n ],\n eyes: ['round', 'dot', 'sparkle', 'lashes', 'sleepy', 'happy', 'wink', 'sharp'],\n brows: ['soft', 'thick', 'raised', 'angry', 'worried', 'none'],\n nose: ['button', 'dot', 'line', 'none'],\n mouth: ['smile', 'grin', 'open', 'flat', 'smirk', 'cat', 'tongue', 'o'],\n cheeks: ['blush', 'freckles', 'none'],\n glasses: ['none', 'round', 'square', 'shades', 'monocle'],\n outfit: [\n 'tee',\n 'shirttie',\n 'hoodie',\n 'turtleneck',\n 'sailor',\n 'blazer',\n 'overalls',\n 'dress',\n 'kimono',\n 'cardigan',\n 'maid',\n 'jacket',\n ],\n backdrop: ['sparkles', 'hearts', 'stars', 'dots', 'none'],\n accessory: [\n 'none',\n 'beanie',\n 'cap',\n 'headphones',\n 'flower',\n 'bow',\n 'earring',\n 'crown',\n 'halo',\n 'catears',\n 'hairclip',\n 'horns',\n 'beret',\n 'ribbon',\n 'headband',\n 'bunnyears',\n 'horseears',\n 'flowercrown',\n 'witch',\n 'pins',\n ],\n} as const;\n\nexport const AVATAR_HAIR_PARTS = {\n bangs: [\n 'crop',\n 'bob',\n 'sweep',\n 'spiky',\n 'curly',\n 'messy',\n 'wolf',\n 'wavy',\n 'ahoge',\n 'hime',\n 'buzz',\n 'mohawk',\n 'none',\n ],\n sideHair: ['crop', 'bun', 'bob', 'long', 'hime', 'curly', 'braids', 'none'],\n backHair: [\n 'none',\n 'bob',\n 'long',\n 'wavy',\n 'wolf',\n 'bun',\n 'odango',\n 'pigtails',\n 'twintails',\n 'drills',\n 'ponytail',\n 'sidetail',\n 'afro',\n ],\n} as const satisfies Record<string, readonly (typeof AVATAR_PARTS)['hair'][number][]>;\nconst HAIR_SPLIT: Record<\n (typeof AVATAR_PARTS)['hair'][number],\n { [P in AvatarHairPart]: (typeof AVATAR_HAIR_PARTS)[P][number] }\n> = {\n crop: { bangs: 'crop', sideHair: 'crop', backHair: 'none' },\n sweep: { bangs: 'sweep', sideHair: 'crop', backHair: 'none' },\n spiky: { bangs: 'spiky', sideHair: 'crop', backHair: 'none' },\n buzz: { bangs: 'buzz', sideHair: 'none', backHair: 'none' },\n curly: { bangs: 'curly', sideHair: 'curly', backHair: 'none' },\n mohawk: { bangs: 'mohawk', sideHair: 'none', backHair: 'none' },\n bob: { bangs: 'bob', sideHair: 'bob', backHair: 'bob' },\n long: { bangs: 'bob', sideHair: 'long', backHair: 'long' },\n bun: { bangs: 'bob', sideHair: 'bun', backHair: 'bun' },\n pigtails: { bangs: 'bob', sideHair: 'bun', backHair: 'pigtails' },\n afro: { bangs: 'buzz', sideHair: 'none', backHair: 'afro' },\n twintails: { bangs: 'bob', sideHair: 'bob', backHair: 'twintails' },\n drills: { bangs: 'bob', sideHair: 'bob', backHair: 'drills' },\n ponytail: { bangs: 'bob', sideHair: 'bun', backHair: 'ponytail' },\n sidetail: { bangs: 'sweep', sideHair: 'bun', backHair: 'sidetail' },\n hime: { bangs: 'hime', sideHair: 'hime', backHair: 'long' },\n odango: { bangs: 'bob', sideHair: 'bun', backHair: 'odango' },\n messy: { bangs: 'messy', sideHair: 'bun', backHair: 'none' },\n wavy: { bangs: 'wavy', sideHair: 'long', backHair: 'wavy' },\n braids: { bangs: 'bob', sideHair: 'braids', backHair: 'none' },\n wolf: { bangs: 'wolf', sideHair: 'bun', backHair: 'wolf' },\n ahoge: { bangs: 'ahoge', sideHair: 'bob', backHair: 'bob' },\n none: { bangs: 'none', sideHair: 'none', backHair: 'none' },\n};\nexport const AVATAR_RANGES = {\n spacing: [-1, 1],\n height: [-1, 1],\n hairLength: [-2, 2],\n} as const;\nexport type AvatarHairPart = keyof typeof AVATAR_HAIR_PARTS;\nexport type AvatarRange = keyof typeof AVATAR_RANGES;\nconst DETAIL_KEYS = [\n ...(Object.keys(AVATAR_HAIR_PARTS) as AvatarHairPart[]),\n ...(Object.keys(AVATAR_RANGES) as AvatarRange[]),\n] as const;\n\nexport type AvatarPart = keyof typeof AVATAR_PARTS;\nexport const AVATAR_COLORS = ['skinColor', 'hairColor', 'eyeColor', 'shirtColor'] as const;\nexport type AvatarColor = (typeof AVATAR_COLORS)[number];\n\n/**\n * Avatar Species: a base on the pixel bust rig. Species share motion and anchors; each sets its\n * own ears, face details and suggested body colors. A recipe with a species is asset version 2.\n */\nexport const AVATAR_SPECIES = ['human', 'goblin', 'elf', 'dwarf', 'orc', 'flower'] as const;\nexport type AvatarSpecies = (typeof AVATAR_SPECIES)[number];\n/** Optional per-piece hair colors (asset version 2); an absent piece uses `hairColor`. */\nexport const AVATAR_PIECE_COLORS = ['leftSideHairColor', 'rightSideHairColor'] as const;\nexport type AvatarPieceColor = (typeof AVATAR_PIECE_COLORS)[number];\n\n/** Part choices that exist only in asset version 2, added after every version 1 choice. */\nexport const AVATAR_PARTS_V2 = {\n ...AVATAR_PARTS,\n outfit: [...AVATAR_PARTS.outfit, 'armor', 'robe', 'tunic', 'cloak'],\n accessory: [...AVATAR_PARTS.accessory, 'helmet', 'hood'],\n} as const satisfies { [P in AvatarPart]: readonly string[] };\n/** Optional asset version 2 parts; an absent part is not drawn (or uses the first choice). */\nexport const AVATAR_EXTRA_PARTS = {\n beard: ['short', 'full', 'braided'],\n petals: ['trumpet', 'daisy', 'sunflower', 'tulip', 'sakura'],\n flowerBase: ['leaves', 'pot'],\n} as const;\nexport type AvatarExtraPart = keyof typeof AVATAR_EXTRA_PARTS;\n\ntype Meta = { schemaVersion: 1; family: 'illustrated'; rigVersion: 1 } & Record<\n AvatarColor,\n string\n>;\n\n/** Asset version 1: optional split hair and geometry, all six or none. */\nexport type PixelAvatarRecipeV1 = Meta & { assetVersion: 1 } & {\n [P in AvatarPart]: (typeof AVATAR_PARTS)[P][number];\n} & {\n [P in AvatarHairPart]?: (typeof AVATAR_PARTS)['hair'][number];\n} & { [P in AvatarRange]?: number } & {\n species?: never;\n rightSideHair?: never;\n} & { [P in AvatarPieceColor | AvatarExtraPart]?: never };\n\n/**\n * Asset version 2: a species, the full split hair and geometry, a separate right side hair\n * (`sideHair` is then the left side) and optional per-side hair colors.\n */\nexport type PixelAvatarRecipeV2 = Meta & { assetVersion: 2 } & {\n [P in AvatarPart]: (typeof AVATAR_PARTS_V2)[P][number];\n} & {\n [P in AvatarHairPart]: (typeof AVATAR_PARTS)['hair'][number];\n} & { [P in AvatarRange]: number } & {\n species: AvatarSpecies;\n rightSideHair: (typeof AVATAR_HAIR_PARTS)['sideHair'][number];\n} & { [P in AvatarPieceColor]?: string } & {\n [P in AvatarExtraPart]?: (typeof AVATAR_EXTRA_PARTS)[P][number];\n};\n\nexport type PixelAvatarRecipe = PixelAvatarRecipeV1 | PixelAvatarRecipeV2;\n\nexport const DEFAULT_RECIPE: PixelAvatarRecipeV1 = {\n schemaVersion: 1,\n family: 'illustrated',\n assetVersion: 1,\n rigVersion: 1,\n head: 'round',\n pose: 'front',\n hair: 'crop',\n eyes: 'round',\n brows: 'soft',\n nose: 'button',\n mouth: 'smile',\n cheeks: 'blush',\n glasses: 'none',\n outfit: 'tee',\n backdrop: 'sparkles',\n accessory: 'none',\n skinColor: '#f2c9a8',\n hairColor: '#5a3a2a',\n eyeColor: '#3f7fbf',\n shirtColor: '#5b8bd6',\n};\n\nconst PART_KEYS = Object.keys(AVATAR_PARTS) as AvatarPart[];\n\nexport function isPixelAvatarRecipe(value: unknown): value is PixelAvatarRecipe {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const r = value as Record<string, unknown>;\n const detailed = DETAIL_KEYS.filter((key) => Object.hasOwn(r, key)).length;\n if (detailed !== 0 && detailed !== DETAIL_KEYS.length) return false;\n const v2 = r['assetVersion'] === 2;\n const pieces = AVATAR_PIECE_COLORS.filter((key) => Object.hasOwn(r, key));\n const extras = (Object.keys(AVATAR_EXTRA_PARTS) as AvatarExtraPart[]).filter((key) =>\n Object.hasOwn(r, key),\n );\n const v2Keys = v2 ? 2 + pieces.length + extras.length : 0;\n if (Object.keys(r).length !== Object.keys(DEFAULT_RECIPE).length + detailed + v2Keys)\n return false;\n if (\n v2 &&\n (detailed === 0 ||\n !(AVATAR_SPECIES as readonly unknown[]).includes(r['species']) ||\n !(AVATAR_HAIR_PARTS.sideHair as readonly unknown[]).includes(r['rightSideHair']) ||\n !pieces.every((key) => typeof r[key] === 'string' && /^#[\\da-f]{6}$/iu.test(r[key])) ||\n !extras.every((key) => (AVATAR_EXTRA_PARTS[key] as readonly unknown[]).includes(r[key])))\n )\n return false;\n const catalog: { [P in AvatarPart]: readonly string[] } = v2 ? AVATAR_PARTS_V2 : AVATAR_PARTS;\n return (\n (detailed === 0 ||\n ((Object.keys(AVATAR_HAIR_PARTS) as AvatarHairPart[]).every(\n (key) =>\n typeof r[key] === 'string' &&\n (AVATAR_HAIR_PARTS[key] as readonly string[]).includes(r[key]),\n ) &&\n (Object.keys(AVATAR_RANGES) as AvatarRange[]).every((key) => {\n const v = r[key];\n const [min, max] = AVATAR_RANGES[key];\n return typeof v === 'number' && Number.isInteger(v) && v >= min && v <= max;\n }))) &&\n r['schemaVersion'] === 1 &&\n r['family'] === 'illustrated' &&\n (r['assetVersion'] === 1 || v2) &&\n r['rigVersion'] === 1 &&\n PART_KEYS.every((key) => typeof r[key] === 'string' && catalog[key].includes(r[key])) &&\n AVATAR_COLORS.every((key) => typeof r[key] === 'string' && /^#[\\da-f]{6}$/iu.test(r[key]))\n );\n}\n\nexport function canonicalRecipe(recipe: PixelAvatarRecipe): PixelAvatarRecipe {\n const canonical: Record<string, unknown> = {\n schemaVersion: 1,\n family: 'illustrated',\n assetVersion: recipe.assetVersion,\n rigVersion: 1,\n };\n for (const key of PART_KEYS) canonical[key] = recipe[key];\n for (const key of AVATAR_COLORS) canonical[key] = recipe[key].toLowerCase();\n if (recipe.bangs !== undefined) for (const key of DETAIL_KEYS) canonical[key] = recipe[key];\n if (recipe.assetVersion === 2) {\n canonical['species'] = recipe.species;\n canonical['rightSideHair'] = recipe.rightSideHair;\n for (const key of AVATAR_PIECE_COLORS)\n if (recipe[key] !== undefined) canonical[key] = recipe[key].toLowerCase();\n for (const key of Object.keys(AVATAR_EXTRA_PARTS) as AvatarExtraPart[])\n if (recipe[key] !== undefined) canonical[key] = recipe[key];\n }\n return canonical as PixelAvatarRecipe;\n}\n\nconst HAIR_PIECES = ['bangs', 'sideHair', 'rightSideHair', 'backHair'] as const;\n\n/**\n * Saved choices the recipe keeps but does not draw: a flower shows petals and a stem instead of\n * hair, outfit, beard and headwear, and a helmet or hood covers the hair. The choices return when\n * the species or headwear changes back.\n */\nexport function hiddenChoices(recipe: PixelAvatarRecipe): readonly string[] {\n if (recipe.species === 'flower')\n return [\n ...HAIR_PIECES,\n 'outfit',\n 'accessory',\n 'eyes',\n 'brows',\n 'nose',\n 'cheeks',\n 'glasses',\n ...(recipe.beard ? ['beard'] : []),\n ];\n const hidden: string[] = [];\n if (recipe.accessory === 'helmet' || recipe.accessory === 'hood') hidden.push(...HAIR_PIECES);\n if (recipe.species === 'dwarf') hidden.push('nose');\n return hidden;\n}\n\n/**\n * Returns the recipe as asset version 2 with the given species, keeping every other choice.\n * Side hair splits into left (`sideHair`) and right (`rightSideHair`) pieces that start equal.\n * When the skin color is one of the previous species' suggested colors, it moves to the new\n * species' first suggestion; a custom color is kept.\n */\nexport function withSpecies(\n recipe: PixelAvatarRecipe,\n species: AvatarSpecies,\n): PixelAvatarRecipeV2 {\n const detailed = detailedRecipe(recipe);\n const previous = recipe.species ?? 'human';\n const suggested = AVATAR_SPECIES_SWATCHES[previous].includes(recipe.skinColor.toLowerCase());\n return {\n ...detailed,\n assetVersion: 2,\n species,\n rightSideHair: detailed.rightSideHair ?? detailed.sideHair!,\n skinColor:\n suggested && previous !== species ? AVATAR_SPECIES_SWATCHES[species][0]! : recipe.skinColor,\n } as PixelAvatarRecipeV2;\n}\n\nexport function detailedRecipe(recipe: PixelAvatarRecipe): PixelAvatarRecipe {\n if (recipe.bangs !== undefined) return recipe;\n const pick = <P extends AvatarHairPart>(part: P) =>\n (AVATAR_HAIR_PARTS[part] as readonly string[]).includes(recipe.hair)\n ? (recipe.hair as (typeof AVATAR_HAIR_PARTS)[P][number])\n : HAIR_SPLIT[recipe.hair][part];\n return {\n ...recipe,\n bangs: pick('bangs'),\n sideHair: pick('sideHair'),\n backHair: pick('backHair'),\n spacing: 0,\n height: 0,\n hairLength: 0,\n };\n}\n\nexport const AVATAR_SWATCHES: Record<AvatarColor, readonly string[]> = {\n skinColor: [\n '#ffe3cf',\n '#f2c9a8',\n '#e0a87e',\n '#c68863',\n '#9a6142',\n '#6e4129',\n '#4a2c1c',\n '#f4f1ec',\n ],\n hairColor: [\n '#1d1b22',\n '#5a3a2a',\n '#8a5a36',\n '#e2b04a',\n '#c4452f',\n '#d9475a',\n '#f06292',\n '#3fc1b8',\n '#5a7be0',\n '#9aa3ad',\n '#f4f1ec',\n ],\n eyeColor: [\n '#3f7fbf',\n '#5a3a2a',\n '#2f9e8f',\n '#4c8a3c',\n '#8a5ad0',\n '#d0533f',\n '#d9a13a',\n '#2a2230',\n ],\n shirtColor: [\n '#5b8bd6',\n '#e07a5f',\n '#3d9970',\n '#7a5cc7',\n '#f2c14e',\n '#2f3a4a',\n '#e2565f',\n '#9ad0c2',\n ],\n};\n\nconst SEEDED_CHOICES: { [P in AvatarPart]: readonly (typeof AVATAR_PARTS)[P][number][] } = {\n head: ['round', 'oval', 'square', 'long', 'heart', 'vchin', 'chubby', 'diamond'],\n pose: ['front'],\n hair: AVATAR_PARTS.hair.filter((hair) => hair !== 'none'),\n eyes: ['round', 'round', 'sparkle', 'lashes', 'dot', 'happy', 'sharp'],\n brows: ['soft', 'soft', 'thick', 'raised'],\n nose: ['button', 'dot', 'none'],\n mouth: ['smile', 'smile', 'grin', 'open', 'cat'],\n cheeks: ['blush', 'blush', 'freckles', 'none'],\n glasses: ['none', 'none', 'none', 'none', 'round', 'square'],\n accessory: [\n 'none',\n 'none',\n 'none',\n 'flower',\n 'bow',\n 'hairclip',\n 'catears',\n 'headphones',\n 'beanie',\n 'cap',\n ],\n outfit: AVATAR_PARTS.outfit,\n backdrop: ['sparkles', 'hearts', 'stars', 'dots'],\n};\n\n/**\n * Returns a name-seeded recipe factory. Different namespaces give different faces for the same\n * name; the factory takes the name only, so it is safe to pass straight to `Array.map`.\n */\nexport function createSeededRecipe(namespace: string): (seed: string) => PixelAvatarRecipe {\n return (seed) => {\n const random = seededRandom(`${namespace}:${seed.trim().toLowerCase()}`);\n const pick = <T>(values: readonly T[]) => values[Math.floor(random() * values.length)]!;\n const recipe: Record<string, unknown> = {\n schemaVersion: 1,\n family: 'illustrated',\n assetVersion: 1,\n rigVersion: 1,\n };\n for (const part of Object.keys(AVATAR_PARTS) as AvatarPart[])\n recipe[part] = pick(SEEDED_CHOICES[part]);\n for (const color of AVATAR_COLORS) recipe[color] = pick(AVATAR_SWATCHES[color].slice(0, 7));\n return recipe as PixelAvatarRecipe;\n };\n}\n\n/**\n * A version 2 name-seeded recipe factory over every species. Species are equally likely; a\n * person may get a beard or a version 2 outfit, and a flower gets petals and a base. Version 1\n * factories (`createSeededRecipe`) keep their faces, so a consumer chooses per identity which\n * seed version it was created with.\n */\nexport function createSeededRecipeV2(namespace: string): (seed: string) => PixelAvatarRecipeV2 {\n const base = createSeededRecipe(`${namespace}:base`);\n return (seed) => {\n const random = seededRandom(`${namespace}:${seed.trim().toLowerCase()}`);\n const pick = <T>(values: readonly T[]) => values[Math.floor(random() * values.length)]!;\n const species = pick(AVATAR_SPECIES);\n const recipe: PixelAvatarRecipeV2 = {\n ...withSpecies(base(seed), species),\n skinColor: pick(AVATAR_SPECIES_SWATCHES[species]),\n };\n if (species === 'flower')\n return {\n ...recipe,\n petals: pick(AVATAR_EXTRA_PARTS.petals),\n flowerBase: pick(AVATAR_EXTRA_PARTS.flowerBase),\n };\n const beard = random() < 0.3 ? pick(AVATAR_EXTRA_PARTS.beard) : undefined;\n const outfit = random() < 0.25 ? pick(AVATAR_PARTS_V2.outfit.slice(-4)) : recipe.outfit;\n return { ...recipe, outfit, ...(beard ? { beard } : {}) };\n };\n}\n\n/** Version 2 counterpart of `seededRecipe` (BotHarness's namespace). */\nexport const seededRecipeV2: (seed: string) => PixelAvatarRecipeV2 =\n createSeededRecipeV2('botharness-avatar-v2');\n\n/** The same name always gives the same face (BotHarness's namespace). */\nexport const seededRecipe: (seed: string) => PixelAvatarRecipe =\n createSeededRecipe('botharness-avatar');\n\n/** Suggested body colors per species; any color remains allowed. */\nexport const AVATAR_SPECIES_SWATCHES: Record<AvatarSpecies, readonly string[]> = {\n human: AVATAR_SWATCHES.skinColor,\n goblin: ['#9cc464', '#7fae4f', '#6a9a45', '#b3cf7a', '#5c8a4a', '#8fa86a'],\n elf: ['#fbe7d6', '#f2d3c0', '#e2c9b0', '#d9c7e8', '#b9c6dd', '#8f7fa8'],\n dwarf: ['#f2c4a0', '#e9b08a', '#e0a87e', '#c68863', '#f0b8a0', '#9a6142'],\n orc: ['#8a9a5b', '#6f8a4e', '#7d8c6a', '#5f6f4a', '#9aa070', '#6a7a7a'],\n flower: ['#f6d36b', '#f2b84b', '#ffe3cf', '#e8a85a', '#c98b4a', '#f4f1ec'],\n};\n\nconst preset = (parts: Partial<PixelAvatarRecipeV1>): PixelAvatarRecipeV1 => ({\n ...DEFAULT_RECIPE,\n ...parts,\n});\n\nexport const AVATAR_PRESETS: readonly PixelAvatarRecipe[] = [\n preset({\n hair: 'wavy',\n eyes: 'lashes',\n accessory: 'beret',\n outfit: 'dress',\n skinColor: '#ffe3cf',\n hairColor: '#e2b04a',\n eyeColor: '#3f7fbf',\n shirtColor: '#e2565f',\n backdrop: 'stars',\n }),\n preset({\n hair: 'braids',\n accessory: 'flowercrown',\n outfit: 'cardigan',\n skinColor: '#ffe3cf',\n hairColor: '#8a5a36',\n eyeColor: '#4c8a3c',\n shirtColor: '#9ad0c2',\n backdrop: 'hearts',\n }),\n preset({\n hair: 'twintails',\n eyes: 'sparkle',\n accessory: 'ribbon',\n outfit: 'maid',\n skinColor: '#ffe3cf',\n hairColor: '#3fc1b8',\n eyeColor: '#2f9e8f',\n shirtColor: '#e2565f',\n backdrop: 'stars',\n }),\n preset({\n hair: 'long',\n accessory: 'horseears',\n outfit: 'jacket',\n skinColor: '#ffe3cf',\n hairColor: '#8a5a36',\n eyeColor: '#d0533f',\n shirtColor: '#5b8bd6',\n backdrop: 'dots',\n }),\n preset({\n hair: 'hime',\n eyes: 'sleepy',\n accessory: 'pins',\n outfit: 'kimono',\n skinColor: '#f4f1ec',\n hairColor: '#1d1b22',\n eyeColor: '#d0533f',\n shirtColor: '#7a5cc7',\n backdrop: 'none',\n }),\n preset({\n hair: 'ahoge',\n accessory: 'headband',\n outfit: 'sailor',\n skinColor: '#ffe3cf',\n hairColor: '#f06292',\n eyeColor: '#2f9e8f',\n shirtColor: '#f4f1ec',\n backdrop: 'hearts',\n }),\n preset({\n hair: 'wolf',\n eyes: 'sharp',\n outfit: 'jacket',\n skinColor: '#e0a87e',\n hairColor: '#9aa3ad',\n eyeColor: '#5a7be0',\n shirtColor: '#2f3a4a',\n backdrop: 'stars',\n }),\n preset({\n hair: 'wavy',\n eyes: 'sparkle',\n accessory: 'witch',\n outfit: 'dress',\n skinColor: '#ffe3cf',\n hairColor: '#8a5ad0',\n eyeColor: '#d9a13a',\n shirtColor: '#2f3a4a',\n backdrop: 'sparkles',\n }),\n preset({\n hair: 'bob',\n eyes: 'happy',\n accessory: 'bunnyears',\n outfit: 'cardigan',\n skinColor: '#ffe3cf',\n hairColor: '#f4f1ec',\n eyeColor: '#d9475a',\n shirtColor: '#f2c14e',\n backdrop: 'hearts',\n }),\n preset({\n hair: 'spiky',\n glasses: 'round',\n accessory: 'headphones',\n outfit: 'hoodie',\n backdrop: 'dots',\n }),\n preset({\n hair: 'odango',\n eyes: 'lashes',\n accessory: 'bow',\n outfit: 'kimono',\n hairColor: '#e2b04a',\n shirtColor: '#5b8bd6',\n backdrop: 'sparkles',\n }),\n preset({\n hair: 'crop',\n accessory: 'cap',\n outfit: 'shirttie',\n skinColor: '#9a6142',\n hairColor: '#1d1b22',\n shirtColor: '#3d9970',\n backdrop: 'dots',\n }),\n];\n","import { escapeAttribute, type PixelCell } from '@botharness/pixel-morph';\nimport { AVATAR_PIECE_COLORS, type PixelAvatarRecipe } from './recipe.js';\n\ntype Cell = string | undefined;\ntype Grid = Cell[][];\ntype Mask = (x: number, y: number) => boolean;\ntype Point = readonly [number, number];\n\nconst N = 32;\nconst C = 16;\nconst INK = '#2a2230';\nconst WHITE = '#ffffff';\nconst BLUSH = '#f4879a';\nconst MOUTH = '#7a2a38';\nconst MOUTH_INSIDE = '#b8415a';\nconst TONGUE = '#ef6f84';\nconst GOLD = '#efb93f';\nconst TUSK = '#f6f0d8';\n\nexport type PixelGrid = Grid;\nexport type PixelMouthState = 'saved' | 'closed' | 'half-open' | 'open';\nexport interface PixelFigureOptions {\n mouthLayers?: boolean;\n}\nconst blank = (): Grid => Array.from({ length: N }, () => Array<Cell>(N).fill(undefined));\nconst ellipse =\n (cx: number, cy: number, rx: number, ry: number): Mask =>\n (x, y) =>\n ((x + 0.5 - cx) / rx) ** 2 + ((y + 0.5 - cy) / ry) ** 2 <= 1;\n\nfunction channels(color: string): number[] {\n const n = Number.parseInt(color.slice(1), 16);\n return [16, 8, 0].map((bit) => (n >> bit) & 255);\n}\nfunction hex(values: number[]): string {\n return `#${values\n .map((v) =>\n Math.min(255, Math.max(0, Math.round(v)))\n .toString(16)\n .padStart(2, '0'),\n )\n .join('')}`;\n}\nconst shade = (color: string, k: number) => hex(channels(color).map((v) => v * k));\nconst mix = (base: string, tint: string, k: number) => {\n const t = channels(tint);\n return hex(channels(base).map((v, i) => v * (1 - k) + t[i]! * k));\n};\nfunction paint(grid: Grid, test: Mask, color: string): void {\n for (let y = 0; y < N; y++) for (let x = 0; x < N; x++) if (test(x, y)) grid[y]![x] = color;\n}\nfunction sprite(\n grid: Grid,\n rows: readonly string[],\n ox: number,\n oy: number,\n pal: Record<string, string>,\n flip = false,\n): void {\n rows.forEach((row, y) =>\n [...row].forEach((code, i) => {\n const c = pal[code];\n const x = ox + (flip ? row.length - 1 - i : i);\n if (c && x >= 0 && x < N && oy + y >= 0 && oy + y < N) grid[oy + y]![x] = c;\n }),\n );\n}\nfunction outline(grid: Grid): Grid {\n const out = grid.map((row) => [...row]);\n for (let y = 0; y < N; y++)\n for (let x = 0; x < N; x++) {\n if (grid[y]![x]) continue;\n const n = [grid[y]?.[x - 1], grid[y]?.[x + 1], grid[y - 1]?.[x], grid[y + 1]?.[x]].find(\n Boolean,\n );\n if (n) out[y]![x] = mix(shade(n, 0.3), INK, 0.62);\n }\n return out;\n}\nconst R = 6;\nconst inTile: Mask = (x, y) => {\n const clamp = (v: number) => Math.min(Math.max(v, R), N - R);\n return (x + 0.5 - clamp(x + 0.5)) ** 2 + (y + 0.5 - clamp(y + 0.5)) ** 2 <= R * R;\n};\nconst clip = (g: Grid): Grid =>\n g.map((row, y) => row.map((c, x) => (inTile(x, y) ? c : undefined)));\nfunction rects(grid: Grid): string {\n let m = '';\n for (let y = 0; y < N; y++) {\n let x = 0;\n while (x < N) {\n const c = grid[y]![x];\n if (!c) {\n x++;\n continue;\n }\n let w = 1;\n while (x + w < N && grid[y]![x + w] === c) w++;\n m += `<rect x=\"${x}\" y=\"${y}\" width=\"${w}\" height=\"1\" fill=\"${escapeAttribute(c)}\"/>`;\n x += w;\n }\n }\n return m;\n}\n\ntype Recipe = PixelAvatarRecipe;\n\nconst FACE: Record<Recipe['head'], (s: number) => Mask> = {\n round: (s) => ellipse(C + s, 16.6, 8.6, 7.6),\n oval: (s) => ellipse(C + s, 16.6, 8, 8),\n chubby: (s) => ellipse(C + s, 17, 9.4, 7.2),\n long: (s) => ellipse(C + s, 16.6, 7.8, 8.4),\n square: (s) => (x, y) => {\n if (y < 8 || y > 23) return false;\n const dx = Math.abs(x + 0.5 - C - s);\n const r = 3;\n if (y <= 20) return dx <= 8.5;\n return dx <= 8.5 - (y - 20) ** 1.3 * 1.1 + 0.3 - (y === 23 ? 1 : 0) || dx <= 8.5 - r;\n },\n heart: (s) => taper(ellipse(C + s, 15.8, 9, 7.4), 16.5, 9, 2.6, 24.4, s),\n vchin: (s) => taper(ellipse(C + s, 15.8, 8.6, 7.4), 17.5, 8.6, 2.2, 24.4, s),\n diamond: (s) =>\n taper(\n (x, y) => y >= 9 && Math.abs(x + 0.5 - C - s) <= 6.4 + (y - 9) * 0.45,\n 15.8,\n 9.2,\n 2.6,\n 24.4,\n s,\n ),\n};\nfunction taper(top: Mask, from: number, width: number, end: number, chin: number, s: number): Mask {\n return (x, y) => {\n const cy = y + 0.5;\n if (cy <= from) return top(x, y);\n if (cy > chin) return false;\n const t = (cy - from) / (chin - from);\n return Math.abs(x + 0.5 - C - s) <= width - (width - end) * t ** 1.5;\n };\n}\n\nconst EYES: Record<Recipe['eyes'], readonly string[]> = {\n round: ['KKKK', 'DWDD', 'IDDI', 'LIIL'],\n dot: ['....', '.KK.', '.KK.', '....'],\n sparkle: ['KKKK', 'DWDW', 'IDDI', 'LIWL'],\n lashes: ['KKKKK', 'K.DWD', '..IDD', '..LII'],\n sleepy: ['....', 'KKKK', 'IDDI', 'LIIL'],\n happy: ['....', '.KK.', 'K..K', '....'],\n wink: ['KKKK', 'DWDD', 'IDDI', 'LIIL'],\n sharp: ['KK..', '.KKK', '.DWD', '..LI'],\n};\nconst CLOSED = ['....', '....', 'KKKK', '....'];\nconst BROWS: Record<Recipe['brows'], readonly string[]> = {\n soft: ['.BBB'],\n thick: ['BBBB'],\n raised: ['.BB.'],\n angry: ['BB..', '..BB'],\n worried: ['..BB', 'BB..'],\n none: [],\n};\nconst MOUTHS: Record<Recipe['mouth'], readonly string[]> = {\n smile: ['K..K', '.KK.'],\n grin: ['KWWK', '.KK.'],\n open: ['KKK', 'MTM'],\n flat: ['.KK.'],\n smirk: ['...K', '.KK.'],\n cat: ['K.K.K', '.K.K.'],\n tongue: ['KKKK', '.TT.'],\n o: ['.K.', 'KMK', '.K.'],\n};\n\nfunction hair(\n recipe: Recipe,\n s: number,\n b: number,\n): { back: Mask; front: Mask; ties?: Point[]; bands?: boolean } {\n const none: Mask = () => false;\n const cap = ellipse(C + s, 14, 11, 10.6);\n const tip = (x: number, depth = 1) => [0, depth, depth + 1, depth][(x + 40 - s) % 4]!;\n const bangs =\n (line: number, depth = 1, sides = 22): Mask =>\n (x, y) => {\n if (!cap(x, Math.min(y, 13))) return false;\n const dx = x + 0.5 - C - s;\n if (Math.abs(dx) >= 7) return y <= sides - [0, 1, 0, 2][(x + 40 - s) % 4]!;\n return y <= line + tip(x, depth) - (Math.abs(dx) > 6 ? 0 : 0);\n };\n const longBack =\n (bottom: number, width = 11.4): Mask =>\n (x, y) =>\n (ellipse(C + b, 14, width + 0.4, 11)(x, y) && y <= 16) ||\n (y > 15 && y <= bottom && Math.abs(x + 0.5 - C - b) <= width - (y > bottom - 2 ? 1 : 0));\n switch (recipe.hair) {\n case 'none':\n return { back: none, front: none };\n case 'buzz':\n return { back: none, front: (x, y) => cap(x, y) && y <= 7 };\n case 'crop':\n return { back: none, front: bangs(10, 1, 15) };\n case 'sweep':\n return {\n back: none,\n front: (x, y) =>\n cap(x, Math.min(y, 13)) &&\n (y <= 9 + Math.max(0, (x - 6 - s) * 0.45) || (Math.abs(x + 0.5 - C - s) >= 7 && y <= 16)),\n };\n case 'spiky':\n return {\n back: none,\n front: (x, y) =>\n cap(x, Math.max(y, 6)) &&\n y >= [1, 3, 5, 3][(x + 40 - s) % 4]! &&\n bangs(11, 2, 15)(x, Math.max(y, 6)),\n };\n case 'curly': {\n const bumps: Point[] = Array.from({ length: 9 }, (_, i) => {\n const a = Math.PI * (1.02 + (i * 0.96) / 8);\n return [C + s + 11.5 * Math.cos(a), 14 + 11 * Math.sin(a)] as Point;\n });\n return {\n back: none,\n front: (x, y) =>\n bangs(11, 1, 18)(x, y) ||\n (y <= 18 && bumps.some(([bx, by]) => (x + 0.5 - bx) ** 2 + (y + 0.5 - by) ** 2 <= 6.5)),\n };\n }\n case 'mohawk':\n return { back: none, front: (x, y) => Math.abs(x + 0.5 - C - s) <= 2 && y >= 1 && y <= 9 };\n case 'bob':\n return { back: longBack(25), front: bangs(13, 1, 24) };\n case 'long':\n return { back: longBack(31), front: bangs(13, 1, 26) };\n case 'bun':\n return {\n back: none,\n front: (x, y) => bangs(12, 1, 18)(x, y) || ellipse(C + s, 2.6, 4, 2.6)(x, y),\n };\n case 'pigtails':\n return {\n back: (x, y) =>\n ellipse(C + s - 11.5, 21, 3, 4.4)(x, y) || ellipse(C + s + 11.5, 21, 3, 4.4)(x, y),\n front: bangs(13, 1, 21),\n ties: [\n [C + s - 12, 16],\n [C + s + 11, 16],\n ],\n };\n case 'afro':\n return { back: ellipse(C + b, 12, 15, 11.5), front: (x, y) => cap(x, y) && y <= 8 };\n case 'twintails':\n case 'drills':\n return {\n back: (x, y) =>\n y >= 8 &&\n (ellipse(C + s - 13.2, 20, 2.3, 12)(x, y) || ellipse(C + s + 13.2, 20, 2.3, 12)(x, y)),\n front: bangs(13, 1, 24),\n ties: [\n [C + s - 13, 9],\n [C + s - 12, 9],\n [C + s + 11, 9],\n [C + s + 12, 9],\n ],\n bands: recipe.hair === 'drills',\n };\n case 'ponytail':\n return {\n back: (x, y) => ellipse(C + s + 11.5, 19, 3, 9)(x, y) && y >= 8,\n front: bangs(12, 1, 20),\n ties: [\n [C + s + 10, 9],\n [C + s + 11, 9],\n ],\n };\n case 'sidetail':\n return {\n back: (x, y) => ellipse(C + s - 11.5, 21, 3, 8)(x, y) && y >= 12,\n front: (x, y) =>\n cap(x, Math.min(y, 13)) &&\n (y <= 9 + Math.max(0, (C + s - x) * 0.45) || (Math.abs(x + 0.5 - C - s) >= 7 && y <= 18)),\n ties: [\n [C + s - 13, 13],\n [C + s - 12, 13],\n ],\n };\n case 'hime':\n return {\n back: longBack(31),\n front: (x, y) =>\n cap(x, Math.min(y, 13)) && (y <= 12 || (Math.abs(x + 0.5 - C - s) >= 6.5 && y <= 24)),\n };\n case 'odango':\n return {\n back: none,\n front: (x, y) =>\n bangs(12, 1, 18)(x, y) ||\n ellipse(C + s - 8, 3.5, 3.3, 3)(x, y) ||\n ellipse(C + s + 8, 3.5, 3.3, 3)(x, y),\n };\n case 'messy':\n return {\n back: none,\n front: (x, y) =>\n cap(x, Math.max(y, 4)) &&\n y >= [2, 0, 3, 1, 2][(x + 50 - s) % 5]! &&\n bangs(11, 2, 17)(x, Math.max(y, 4)),\n };\n case 'wavy':\n return {\n back: (x, y) =>\n longBack(30)(x, y) ||\n (y >= 16 && y <= 30 && Math.abs(x + 0.5 - C - b) <= 12.4 + Math.sin(y * 0.9) * 0.9),\n front: bangs(12, 2, 25),\n };\n case 'braids':\n return {\n back: none,\n front: (x, y) =>\n bangs(13, 1, 20)(x, y) ||\n [C + s - 9.5, C + s + 9.5].some(\n (bx) =>\n y >= 20 && y <= 30 && Math.abs(x + 0.5 - bx) <= 1.6 - ((y + 1) % 3 === 0 ? 0.6 : 0),\n ),\n ties: [\n [C + s - 10, 30],\n [C + s + 9, 30],\n ],\n };\n case 'wolf':\n return {\n back: (x, y) => longBack(24, 11.8)(x, y) && (y < 20 || (x + y) % 3 !== 0),\n front: (x, y) =>\n cap(x, Math.max(y, 5)) &&\n y >= [1, 2, 0, 2][(x + 40 - s) % 4]! &&\n bangs(12, 2, 21)(x, Math.max(y, 5)),\n };\n case 'ahoge':\n return {\n back: longBack(23),\n front: (x, y) =>\n bangs(13, 1, 22)(x, y) ||\n [\n [0, 0],\n [1, 0],\n [1, 1],\n [2, 1],\n [2, 2],\n [1, 2],\n ].some(([ax, ay]) => x === Math.round(C + s) + ax! && y === ay! + 1),\n };\n }\n}\n\nfunction detailedHair(\n recipe: Recipe,\n s: number,\n b: number,\n): { back: Mask; front: Mask; ties?: Point[]; bands?: boolean; sides?: [Mask, Mask] } {\n const of = (style: Recipe['hair'] | undefined) =>\n hair({ ...recipe, hair: style ?? 'none' }, s, b);\n const bangs = of(recipe.bangs);\n const side = of(recipe.sideHair);\n const right = recipe.rightSideHair === undefined ? side : of(recipe.rightSideHair);\n const back = of(recipe.backHair);\n const length = (recipe.hairLength ?? 0) * 2;\n const lengthen =\n (mask: Mask): Mask =>\n (x, y) =>\n mask(x, y > 18 ? Math.round(y - length) : y);\n // Side pieces cover |dx| >= 7 below the crown; with a right piece, each side has its own.\n const sideOf =\n (sign: -1 | 1): Mask =>\n (x, y) =>\n y > 7 && sign * (x + 0.5 - C - s) >= 7 && lengthen((sign < 0 ? side : right).front)(x, y);\n return {\n front: (x, y) =>\n y <= 7\n ? bangs.front(x, y) || back.front(x, y)\n : Math.abs(x + 0.5 - C - s) < 7\n ? bangs.front(x, y)\n : lengthen((x + 0.5 - C - s < 0 ? side : right).front)(x, y),\n sides: [sideOf(-1), sideOf(1)],\n back: length === 0 ? back.back : lengthen(back.back),\n ...(back.ties ? { ties: back.ties } : {}),\n ...(back.bands ? { bands: back.bands } : {}),\n };\n}\n\nfunction outfit(recipe: Recipe, g: Grid, s: number): void {\n const shirt = recipe.shirtColor;\n const skin = recipe.skinColor;\n const dark = shade(shirt, 0.75);\n const light = mix(shirt, WHITE, 0.8);\n const half = (y: number) => 6.5 + (y - 24) * 1.15;\n const torso: Mask = (x, y) => y >= 24 && Math.abs(x + 0.5 - C - s * 0.5) <= half(y);\n const dx = (x: number) => x + 0.5 - C - s * 0.5;\n paint(g, (x, y) => y >= 22 && y <= 25 && Math.abs(dx(x)) <= 2.5, shade(skin, 0.85));\n paint(g, torso, shirt);\n const v =\n (depth: number, w: number): Mask =>\n (x, y) =>\n y >= 24 && y <= 24 + depth && Math.abs(dx(x)) <= w - (y - 24) * (w / (depth + 1));\n switch (recipe.outfit) {\n case 'tee':\n paint(g, v(1, 2.5), shade(skin, 0.85));\n break;\n case 'shirttie':\n paint(g, v(3, 4), light);\n paint(g, (x, y) => y >= 24 && Math.abs(dx(x)) <= 0.5 && y <= 28, '#d22a5a');\n break;\n case 'hoodie':\n paint(g, (x, y) => torso(x, y) && y === 24 && Math.abs(dx(x)) >= 3, dark);\n paint(\n g,\n (x, y) =>\n y >= 25 && y <= 27 && (Math.abs(dx(x) + 1.5) <= 0.5 || Math.abs(dx(x) - 1.5) <= 0.5),\n WHITE,\n );\n break;\n case 'turtleneck':\n paint(g, (x, y) => y >= 22 && y <= 25 && Math.abs(dx(x)) <= 3, shade(shirt, 0.88));\n break;\n case 'sailor':\n paint(g, (x, y) => torso(x, y) && y <= 26 && Math.abs(dx(x)) >= 2, '#2f3a5a');\n paint(g, (x, y) => torso(x, y) && y === 26 && Math.abs(dx(x)) >= 3, WHITE);\n sprite(g, ['R.R', '.R.'], Math.round(C + s * 0.5) - 2, 26, { R: '#e2565f' });\n break;\n case 'blazer':\n paint(g, v(4, 4), light);\n paint(\n g,\n (x, y) => torso(x, y) && y >= 24 && Math.abs(Math.abs(dx(x)) - (4 - (y - 24) * 0.8)) <= 0.5,\n dark,\n );\n sprite(g, ['G'], Math.round(C + s * 0.5), 28, { G: GOLD });\n break;\n case 'overalls':\n paint(g, torso, light);\n paint(g, (x, y) => torso(x, y) && (y >= 27 || Math.abs(Math.abs(dx(x)) - 4) <= 0.6), shirt);\n sprite(g, ['G....G'], Math.round(C + s * 0.5) - 3, 27, { G: GOLD });\n break;\n case 'dress':\n paint(g, (x, y) => torso(x, y) && y <= 25 && Math.abs(dx(x)) <= 4.5, WHITE);\n paint(\n g,\n (x, y) => torso(x, y) && y === 25 && Math.abs(dx(x)) <= 4.5 && x % 2 === 0,\n shade(WHITE, 0.86),\n );\n sprite(g, ['RR.RR', '.RRR.', 'R...R'], Math.round(C + s * 0.5) - 2, 25, { R: '#e5566a' });\n paint(g, (x, y) => torso(x, y) && y === 29, mix(shirt, WHITE, 0.5));\n break;\n case 'kimono':\n paint(\n g,\n (x, y) => torso(x, y) && y <= 28 && Math.abs(Math.abs(dx(x)) - (y - 23.5)) <= 0.6,\n WHITE,\n );\n paint(g, (x, y) => torso(x, y) && y >= 28, '#e2565f');\n paint(g, (x, y) => torso(x, y) && y === 28 && x % 3 === 0, GOLD);\n paint(\n g,\n (x, y) => torso(x, y) && y <= 27 && (x * 3 + y * 2) % 7 === 0,\n mix(shirt, WHITE, 0.45),\n );\n break;\n case 'cardigan':\n paint(g, v(5, 3.5), light);\n paint(g, (x, y) => torso(x, y) && Math.abs(Math.abs(dx(x)) - 2) <= 0.5 && y >= 25, dark);\n sprite(g, ['W', '.', 'W', '.', 'W'], Math.round(C + s * 0.5) - 3, 25, { W: WHITE });\n paint(g, (x, y) => torso(x, y) && y === 29, dark);\n break;\n case 'maid':\n paint(g, (x, y) => torso(x, y), '#2f2a3a');\n paint(g, (x, y) => torso(x, y) && y >= 25 && Math.abs(dx(x)) <= 4 - (y - 25) * 0.2, WHITE);\n paint(g, (x, y) => y === 24 && Math.abs(dx(x)) <= 4.5, WHITE);\n sprite(g, ['RR.RR', '.RRR.'], Math.round(C + s * 0.5) - 2, 24, { R: shirt });\n break;\n case 'armor': {\n const metal = '#9aa3ad';\n paint(g, torso, metal);\n paint(g, (x, y) => torso(x, y) && y >= 26 && Math.abs(dx(x)) <= 2.5, shirt);\n paint(\n g,\n (x, y) => torso(x, y) && y <= 26 && Math.abs(dx(x)) >= half(y) - 3.5,\n mix(metal, WHITE, 0.35),\n );\n paint(\n g,\n (x, y) => torso(x, y) && y === 27 && Math.abs(dx(x)) >= half(y) - 3.5,\n shade(metal, 0.7),\n );\n paint(g, (x, y) => y === 24 && Math.abs(dx(x)) <= 3.5, shade(metal, 0.8));\n sprite(g, ['G'], Math.round(C + s * 0.5), 28, { G: GOLD });\n break;\n }\n case 'robe':\n paint(g, v(5, 4), mix(shirt, WHITE, 0.7));\n paint(\n g,\n (x, y) => torso(x, y) && y <= 29 && Math.abs(Math.abs(dx(x)) - (4 - (y - 24) * 0.8)) <= 0.5,\n GOLD,\n );\n paint(g, (x, y) => torso(x, y) && y >= 28 && Math.abs(dx(x)) >= half(y) - 1.5, dark);\n break;\n case 'tunic':\n paint(g, v(2, 2), shade(skin, 0.85));\n sprite(g, ['L.L', '.L.'], Math.round(C + s * 0.5) - 1, 25, { L: '#6b4a2b' });\n paint(g, (x, y) => torso(x, y) && y === 29, '#6b4a2b');\n sprite(g, ['G'], Math.round(C + s * 0.5), 29, { G: GOLD });\n break;\n case 'cloak': {\n const cloak = mix(shirt, '#2f3a4a', 0.55);\n paint(g, (x, y) => torso(x, y) && Math.abs(dx(x)) >= 2.5, cloak);\n paint(g, (x, y) => torso(x, y) && y === 24, shade(cloak, 0.8));\n sprite(g, ['G...G'], Math.round(C + s * 0.5) - 2, 25, { G: GOLD });\n break;\n }\n case 'jacket':\n paint(g, v(6, 4.5), WHITE);\n paint(\n g,\n (x, y) => torso(x, y) && Math.abs(Math.abs(dx(x)) - (4.5 - (y - 24) * 0.6)) <= 0.6,\n dark,\n );\n paint(g, (x, y) => torso(x, y) && y >= 27 && Math.abs(dx(x)) <= 0.5, '#9aa3ad');\n paint(\n g,\n (x, y) => torso(x, y) && y === 28 && Math.abs(dx(x)) >= half(y) - 2.5,\n mix(shirt, WHITE, 0.6),\n );\n break;\n }\n const neck = shade(skin, 0.85);\n for (let y = 24; y < N; y++)\n for (let x = 0; x < N; x++) {\n const cell = g[y]![x];\n if (!cell || cell === neck || !torso(x, y)) continue;\n const d = dx(x);\n const edge = half(y) - Math.abs(d);\n if (y === 24 && Math.abs(d) <= 4.5) g[y]![x] = shade(cell, 0.78);\n else if (y >= 26 && edge >= 1.6 && edge < 2.6) g[y]![x] = shade(cell, 0.82);\n else if (d > 0 && edge < 1.6) g[y]![x] = shade(cell, 0.84);\n else if (d < 0 && edge < 1.6 && y <= 26) g[y]![x] = mix(cell, WHITE, 0.28);\n else if (d < -2 && y <= 25) g[y]![x] = mix(cell, WHITE, 0.14);\n }\n}\n\nfunction accessory(recipe: Recipe, g: Grid, s: number, face: Mask): void {\n const shirt = recipe.shirtColor;\n const cap = ellipse(C + s, 14, 11.6, 11.2);\n switch (recipe.accessory) {\n case 'none':\n return;\n case 'beanie':\n paint(g, (x, y) => cap(x, y) && y <= 8, shirt);\n paint(g, (x, y) => cap(x, y) && (y === 8 || y === 9), shade(shirt, 0.78));\n paint(g, ellipse(C + s, 1.6, 2.2, 1.8), WHITE);\n return;\n case 'cap':\n paint(g, (x, y) => cap(x, y) && y <= 8, shirt);\n paint(\n g,\n (x, y) => y === 9 && x + 0.5 >= C + s - 10 && x + 0.5 <= C + s + 13,\n shade(shirt, 0.72),\n );\n return;\n case 'headphones': {\n const band = (x: number, y: number) =>\n ellipse(C + s, 14, 12, 11.6)(x, y) && !ellipse(C + s, 14, 10.8, 10.4)(x, y) && y <= 13;\n paint(g, band, '#5d5b66');\n paint(\n g,\n (x, y) =>\n y >= 12 &&\n y <= 19 &&\n (Math.abs(x + 0.5 - (C + s - 11)) <= 1.6 || Math.abs(x + 0.5 - (C + s + 11)) <= 1.6),\n '#e25d6a',\n );\n return;\n }\n case 'flower':\n sprite(g, ['.P.P.', 'PPYPP', '.PPP.'], Math.round(C + s) + 6, 3, { P: '#f59fba', Y: GOLD });\n return;\n case 'bow':\n sprite(g, ['RR.RR', 'RRrRR', 'RR.RR'], Math.round(C + s) + 6, 3, {\n R: '#e5566a',\n r: '#b83a50',\n });\n return;\n case 'earring': {\n const xs = [...Array(N).keys()].filter((x) => face(x, 19));\n if (xs.length) {\n sprite(g, ['G', 'G'], xs[0]! - 1, 20, { G: GOLD });\n sprite(g, ['G', 'G'], xs.at(-1)! + 1, 20, { G: GOLD });\n }\n return;\n }\n case 'crown':\n sprite(g, ['G.G.G.G', 'GGGGGGG', 'GrGbGrG'], Math.round(C + s) - 3, 0, {\n G: GOLD,\n r: '#e5566a',\n b: '#5a9be0',\n });\n return;\n case 'halo':\n paint(\n g,\n (x, y) => ellipse(C + s, 1.6, 6.5, 1.8)(x, y) && !ellipse(C + s, 1.6, 4.4, 0.8)(x, y),\n GOLD,\n );\n return;\n case 'catears': {\n const ear = ['X...', 'XX..', 'XPX.', 'XXXX'];\n sprite(g, ear, Math.round(C + s) - 9, 2, { X: recipe.hairColor, P: '#f4a3b5' });\n sprite(g, ear, Math.round(C + s) + 5, 2, { X: recipe.hairColor, P: '#f4a3b5' }, true);\n return;\n }\n case 'hairclip':\n sprite(g, ['CC.CC', '.CCC.'], Math.round(C + s) + 3, 9, { C: '#e5566a' });\n return;\n case 'horns': {\n const horn = ['.H', 'HH', 'Hh'];\n sprite(g, horn, Math.round(C + s) - 8, 1, { H: '#5b3a6e', h: '#7d5694' });\n sprite(g, horn, Math.round(C + s) + 6, 1, { H: '#5b3a6e', h: '#7d5694' }, true);\n return;\n }\n case 'helmet': {\n const metal = '#9aa3ad';\n paint(g, (x, y) => cap(x, y) && y <= 11, metal);\n paint(g, (x, y) => cap(x, y) && y === 11, shade(metal, 0.75));\n paint(\n g,\n (x, y) => cap(x, y) && y >= 12 && y <= 19 && Math.abs(x + 0.5 - C - s) >= 7.5,\n metal,\n );\n paint(g, (x, y) => Math.abs(x + 0.5 - C - s) <= 0.5 && y >= 11 && y <= 16, shade(metal, 0.7));\n paint(\n g,\n (x, y) => cap(x, y) && y >= 2 && y <= 5 && x + 0.5 < C + s - 2,\n mix(metal, WHITE, 0.4),\n );\n for (let x = Math.round(C + s) - 9; x <= Math.round(C + s) + 9; x += 3)\n sprite(g, ['G'], x, 10, { G: GOLD });\n return;\n }\n case 'hood': {\n const outer = ellipse(C + s, 15, 12.6, 12.4);\n paint(g, (x, y) => outer(x, y) && y <= 25 && !(face(x, y) && y >= 10), shirt);\n paint(\n g,\n (x, y) =>\n outer(x, y) &&\n !face(x, y) &&\n y >= 9 &&\n (face(x + 1, y) || face(x - 1, y) || face(x, y + 1)),\n shade(shirt, 0.7),\n );\n return;\n }\n case 'beret':\n paint(g, (x, y) => ellipse(C + s + 1.5, 4.6, 10.5, 3.6)(x, y), shirt);\n paint(g, (x, y) => ellipse(C + s + 1.5, 4.6, 10.5, 3.6)(x, y) && y >= 6, shade(shirt, 0.78));\n paint(\n g,\n (x, y) => ellipse(C + s + 1.5, 4.6, 10.5, 3.6)(x, y) && y <= 2 && x + 0.5 < C + s,\n mix(shirt, WHITE, 0.3),\n );\n sprite(g, ['S'], Math.round(C + s) + 1, 0, { S: shade(shirt, 0.6) });\n return;\n case 'ribbon':\n sprite(g, ['RRR.RRR', 'RrRRRrR', 'RRR.RRR', '.R...R.'], Math.round(C + s) - 3, 0, {\n R: '#e5566a',\n r: '#f49aa8',\n });\n return;\n case 'headband':\n paint(\n g,\n (x, y) =>\n ellipse(C + s, 14, 11.2, 10.8)(x, y) && !ellipse(C + s, 14.2, 10.2, 9.8)(x, y) && y <= 8,\n shirt,\n );\n paint(\n g,\n (x, y) =>\n ellipse(C + s, 14, 11.2, 10.8)(x, y) && !ellipse(C + s, 14.2, 10.2, 9.8)(x, y) && y <= 5,\n mix(shirt, WHITE, 0.35),\n );\n return;\n case 'bunnyears': {\n const ear = ['WW', 'WP', 'WP', 'WP', 'WW'];\n sprite(g, ear, Math.round(C + s) - 6, 0, { W: '#f4f1ec', P: '#f4a3b5' });\n sprite(g, ear, Math.round(C + s) + 4, 0, { W: '#f4f1ec', P: '#f4a3b5' }, true);\n return;\n }\n case 'horseears': {\n const ear = ['.X.', 'XPX', 'XPX', 'XXX'];\n sprite(g, ear, Math.round(C + s) - 9, 1, { X: shade(recipe.hairColor, 0.9), P: '#f4a3b5' });\n sprite(g, ear, Math.round(C + s) + 6, 1, { X: shade(recipe.hairColor, 0.9), P: '#f4a3b5' });\n sprite(g, ['BB', 'BB'], Math.round(C + s) + 3, 7, { B: '#5a9be0' });\n return;\n }\n case 'flowercrown':\n for (const [fx, color] of [\n [-8, '#f59fba'],\n [-4, GOLD],\n [0, '#f4f1ec'],\n [4, '#f59fba'],\n [8, GOLD],\n ] as const)\n sprite(\n g,\n ['.F.', 'FCF', '.F.'],\n Math.round(C + s) + fx - 1,\n 4 + Math.round(Math.abs(fx) / 4),\n {\n F: color,\n C: color === GOLD ? '#e2565f' : GOLD,\n },\n );\n paint(\n g,\n (x, y) =>\n y === 6 + Math.round(Math.abs(x + 0.5 - C - s) / 4) &&\n Math.abs(x + 0.5 - C - s) <= 9 &&\n x % 2 === 1,\n '#5aa36b',\n );\n return;\n case 'witch':\n paint(g, (x, y) => y >= 6 && y <= 7 && Math.abs(x + 0.5 - C - s) <= 13, '#3a2f52');\n paint(\n g,\n (x, y) => y <= 6 && Math.abs(x + 0.5 - C - s - (6 - y) * 0.5) <= 1 + y * 0.9,\n '#4b3d6b',\n );\n paint(g, (x, y) => y === 5 && Math.abs(x + 0.5 - C - s - 0.5) <= 5.2, '#efb93f');\n return;\n case 'pins':\n sprite(g, ['Y.Y', '.Y.', 'Y.Y', '...', 'B.B', '.B.', 'B.B'], Math.round(C + s) + 6, 7, {\n Y: GOLD,\n B: '#5a9be0',\n });\n return;\n }\n}\n\nconst POINTED_EARS: Partial<\n Record<NonNullable<Recipe['species']>, { rows: string[]; rise: number }>\n> = {\n goblin: { rows: ['E...', 'EE..', '.EiE', '..Ee'], rise: 2 },\n elf: { rows: ['E....', 'EE...', '.EE..', '..EiE', '...Ee'], rise: 3 },\n orc: { rows: ['E..', 'EE.', '.Ee'], rise: 1 },\n};\n\nconst leafShape =\n (cx: number, cy: number, long: number, wide: number, angle: number): Mask =>\n (x, y) => {\n const px = x + 0.5 - cx;\n const py = y + 0.5 - cy;\n const u = px * Math.cos(angle) + py * Math.sin(angle);\n const v = -px * Math.sin(angle) + py * Math.cos(angle);\n return (u / long) ** 2 + (v / wide) ** 2 <= 1;\n };\n\nfunction petals(style: NonNullable<Recipe['petals']>, s: number): Mask {\n const cx = C + s;\n const cy = 16.6;\n const ring =\n (n: number, radius: number, long: number, wide: number, phase = 0): Mask =>\n (x, y) =>\n Array.from({ length: n }, (_, k) => phase + (2 * Math.PI * k) / n).some((a) =>\n leafShape(cx + radius * Math.cos(a), cy + radius * Math.sin(a), long, wide, a)(x, y),\n );\n switch (style) {\n case 'daisy':\n return ring(14, 10.4, 3.4, 1.7, Math.PI / 14);\n case 'sunflower':\n return (x, y) => ring(16, 11.2, 2.6, 1.5)(x, y) || ellipse(cx, cy, 10.6, 10.2)(x, y);\n case 'tulip':\n return (x, y) =>\n y <= cy + 6 &&\n (ellipse(cx - 6.5, cy - 3, 4.5, 7.5)(x, y) ||\n ellipse(cx + 6.5, cy - 3, 4.5, 7.5)(x, y) ||\n ellipse(cx, cy - 6, 5, 8)(x, y));\n case 'trumpet':\n return (x, y) =>\n ellipse(cx, cy - 0.5, 11.6, 10.4)(x, y) ||\n (y <= cy - 6 && ellipse(cx, cy - 3, 13, 8.6)(x, y));\n case 'sakura':\n return (x, y) =>\n ring(5, 8.6, 4.6, 3.8, -Math.PI / 2)(x, y) && !ring(5, 13.4, 1.4, 1.4, -Math.PI / 2)(x, y);\n }\n}\n\nfunction flowerBase(recipe: Recipe, g: Grid, s: number): void {\n const leaf = '#5f9e4a';\n const stem = C + s * 0.5;\n paint(g, (x, y) => y >= 22 && Math.abs(x + 0.5 - stem) <= 1, shade(leaf, 0.82));\n if (recipe.flowerBase === 'pot') {\n const pot = recipe.shirtColor;\n const body: Mask = (x, y) => y >= 27 && Math.abs(x + 0.5 - stem) <= 6.5 - (y - 27) * 0.45;\n paint(g, leafShape(stem - 3, 25, 2.8, 1.2, -0.5), leaf);\n paint(g, leafShape(stem + 3, 24.5, 2.8, 1.2, 0.5), shade(leaf, 0.9));\n paint(g, body, pot);\n paint(g, (x, y) => body(x, y) && y === 27, mix(pot, WHITE, 0.3));\n paint(g, (x, y) => body(x, y) && y >= 28 && x + 0.5 > stem + 3, shade(pot, 0.8));\n return;\n }\n const left = leafShape(stem - 4.5, 27, 4.4, 1.9, -0.55);\n const right = leafShape(stem + 4.5, 25.5, 4.4, 1.9, 0.55);\n paint(g, left, leaf);\n paint(g, right, shade(leaf, 0.92));\n paint(g, leafShape(stem - 4.5, 27, 3.6, 0.5, -0.55), shade(leaf, 0.75));\n paint(g, leafShape(stem + 4.5, 25.5, 3.6, 0.5, 0.55), shade(leaf, 0.7));\n}\n\nexport function pixelTileColor(hair: string): string {\n const [r, g, b] = channels(hair).map((v) => v / 255) as [number, number, number];\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const lightness = (max + min) / 2;\n const chroma = max - min;\n const saturation = chroma === 0 ? 0 : chroma / (1 - Math.abs(2 * lightness - 1));\n if (saturation < 0.18 || lightness > 0.86 || lightness < 0.16) return '#ece8e1';\n const hue =\n max === r\n ? ((g - b) / chroma + 6) % 6\n : max === g\n ? (b - r) / chroma + 2\n : (r - g) / chroma + 4;\n const s = Math.min(0.55, Math.max(0.35, saturation * 0.6));\n const l = 0.88;\n const f = (n: number) => {\n const k = (n + hue * 2) % 12;\n return l - s * Math.min(l, 1 - l) * Math.max(-1, Math.min(k - 3, 9 - k, 1));\n };\n return hex([f(0), f(8), f(4)].map((v) => v * 255));\n}\n\nexport function pixelFigure(\n recipe: Recipe,\n yawDeg: number,\n options: PixelFigureOptions = {},\n): { tile: string; body: string; head: string; cells: PixelCell[] } {\n const yaw = (yawDeg * Math.PI) / 180;\n const sinY = Math.sin(yaw);\n const s = Math.round(sinY * 3);\n const fs = Math.round(sinY * 10);\n const b = -Math.round(sinY * 3.5);\n const turned = Math.abs(sinY) >= 0.3;\n const d = Math.sign(sinY);\n const skin = recipe.skinColor;\n const hairColor = recipe.hairColor;\n const front = FACE[recipe.head](s * 0.5);\n const face: Mask = turned\n ? (x, y) => {\n const dx = x + 0.5 - C;\n const tuck = y >= 17 && d * dx > 4 ? Math.min(2, (y - 16) * 0.35) : 0;\n return front(x - Math.round(d * (1 + Math.max(0, y - 20) * 0.4) - d * tuck), y);\n }\n : front;\n const flower = recipe.species === 'flower';\n const covered = recipe.accessory === 'helmet' || recipe.accessory === 'hood';\n const bare: Mask = () => false;\n const petalRing = flower ? petals(recipe.petals ?? 'trumpet', s) : bare;\n const masks: ReturnType<typeof detailedHair> = flower\n ? {\n back: petalRing,\n front: bare,\n sides: [\n (x, y) => petalRing(x, y) && x + 0.5 < C + s,\n (x, y) => petalRing(x, y) && x + 0.5 >= C + s,\n ],\n }\n : covered\n ? { back: bare, front: bare }\n : recipe.bangs === undefined\n ? hair(recipe, s, b)\n : detailedHair(recipe, s, b);\n\n const body = blank();\n if (flower) flowerBase(recipe, body, s);\n else outfit(recipe, body, s);\n\n const back = blank();\n if (flower) {\n paint(back, petalRing, hairColor);\n paint(\n back,\n (x, y) => petalRing(x, y) && (x + 0.5 - C - s) ** 2 + (y + 0.5 - 16.6) ** 2 < 90,\n shade(hairColor, 0.84),\n );\n paint(\n back,\n (x, y) => petalRing(x, y) && x + 0.5 < C + s - 3 && y < 10,\n mix(hairColor, WHITE, 0.3),\n );\n } else paint(back, masks.back, shade(hairColor, 0.82));\n if (masks.bands)\n paint(\n back,\n (x, y) => masks.back(x, y) && (y + Math.floor(x / 2)) % 4 === 0,\n shade(hairColor, 0.68),\n );\n\n const head = blank();\n paint(head, face, skin);\n const h = recipe.height ?? 0;\n if (recipe.beard && !flower) {\n const centre = C + fs * 0.6;\n const mouthX = Math.round(C - 0.5 + fs * 0.6);\n const chin: Mask = (x, y) => face(x, y) || face(x, y - 2);\n const open = (x: number, y: number) => y >= 20 + h && y <= 22 + h && Math.abs(x - mouthX) <= 3;\n const full: Mask = (x, y) =>\n chin(x, y) && (y >= 22 + h || (Math.abs(x + 0.5 - centre) >= 4 && y >= 17 + h));\n const shape: Mask =\n recipe.beard === 'short'\n ? (x, y) => chin(x, y) && y >= 22 + h\n : recipe.beard === 'full'\n ? full\n : (x, y) => full(x, y) || (Math.abs(x + 0.5 - centre) <= 1 && y >= 24 && y <= 30);\n paint(head, (x, y) => shape(x, y) && !open(x, y), shade(hairColor, 0.9));\n paint(\n head,\n (x, y) => shape(x, y) && !open(x, y) && (x + y * 2) % 5 === 0,\n shade(hairColor, 0.72),\n );\n }\n const earY = 15;\n const edge = (side: number) => {\n const xs = [...Array(N).keys()].filter((x) => face(x, earY));\n return side < 0 ? xs[0]! - 1 : xs.at(-1)! + 1;\n };\n const pointed = recipe.species ? POINTED_EARS[recipe.species] : undefined;\n if (flower) {\n // A flower has petals instead of ears.\n } else if (pointed) {\n // Pointed ears are drawn over hair: the outer tip rises above the ear line.\n const pal = { E: skin, e: shade(skin, 0.86), i: shade(skin, 0.74) };\n const width = pointed.rows[0]!.length;\n paint(head, masks.front, hairColor);\n for (const ex of turned ? [-d] : [-1, 1])\n sprite(\n head,\n pointed.rows,\n ex < 0 ? edge(ex) - (width - 1) : edge(ex),\n earY - pointed.rise,\n pal,\n ex > 0,\n );\n } else if (!turned)\n for (const ex of [-1, 1])\n sprite(head, ['E', 'E', 'e'], edge(ex), earY, { E: skin, e: shade(skin, 0.86) });\n else\n sprite(head, ['EE', 'Ee', 'Ee', 'E.'], d > 0 ? edge(-d) - 1 : edge(-d), earY, {\n E: skin,\n e: shade(skin, 0.8),\n });\n if (!pointed && !flower) paint(head, masks.front, hairColor);\n for (const [x, y] of masks.ties ?? [])\n sprite(back, ['T'], Math.round(x), y, { T: shade(recipe.shirtColor, 0.8) });\n if (!flower) accessory(recipe, head, s, face);\n\n const shadeHair = (g: Grid) => {\n const out = g.map((r) => [...r]);\n const cells = g.flatMap((row, y) => row.flatMap((c, x) => (c === hairColor ? [[x, y]] : [])));\n const xs = cells.map(([x]) => x!);\n const ys = cells.map(([, y]) => y!);\n const left = Math.min(...xs);\n const right = Math.max(...xs);\n const top = Math.min(...ys);\n const mid = (left + right) / 2;\n const span = Math.max(1, (right - left) / 2);\n const light = mix(hairColor, WHITE, 0.2);\n const dark = shade(hairColor, 0.8);\n const middle = shade(hairColor, 0.9);\n for (const [x, y] of cells) {\n const side = (x! + 0.5 - mid) / span + (y! - top) * 0.025;\n if (side > 0.72) out[y!]![x!] = dark;\n else if (side > 0.42) out[y!]![x!] = middle;\n else if (side < -0.2 && y! <= top + 4) out[y!]![x!] = light;\n }\n for (const [x, y] of cells) {\n const nearFace = g[y!]![x! - 1] === skin || g[y!]![x! + 1] === skin;\n if (nearFace && y! >= 14) out[y!]![x!] = shade(hairColor, 0.74);\n else if (Math.abs(x! + 0.5 - C - s) >= 7.5 && y! >= 14 && (x! + 40 - s) % 3 === 0)\n out[y!]![x!] = shade(out[y!]![x!]!, 0.86);\n }\n for (let y = 1; y < N; y++)\n for (let x = 0; x < N; x++) {\n if (g[y]![x] !== skin) continue;\n if (g[y - 1]![x] === hairColor) out[y]![x] = mix(shade(skin, 0.84), BLUSH, 0.12);\n else if (x + 1 < N && g[y]![x + 1] !== skin && g[y]![x + 1] !== undefined && x > C + s)\n out[y]![x] = shade(skin, 0.9);\n else if (x + 1 < N && g[y]![x + 1] === undefined && x > C + s)\n out[y]![x] = shade(skin, 0.9);\n }\n for (let y = 0; y < N - 1; y++)\n for (let x = 0; x < N; x++)\n if (g[y]![x] === hairColor && g[y + 1]![x] === skin) out[y]![x] = shade(hairColor, 0.62);\n for (let x = 0; x < N; x++)\n for (let y = 3; y < N; y++)\n if (g[y]![x] === hairColor && g[y + 1]?.[x] === skin && (x + 40 - s) % 4 === 0)\n for (let k = 1; k <= 3; k++)\n if (g[y - k]?.[x] === hairColor) out[y - k]![x] = shade(hairColor, 0.72);\n const ring = mix(hairColor, WHITE, 0.45);\n for (let x = Math.round(C + s) - 7; x <= Math.round(C + s) + 3; x++) {\n const first = g.findIndex((row) => row[x] === hairColor);\n if (first < 0) continue;\n const y = first + 2 + Math.round(Math.abs(x + 0.5 - (C + s - 2)) / 4);\n if (g[y]?.[x] === hairColor && x % 3 !== 0) out[y]![x] = ring;\n }\n return out;\n };\n\n const figure = blank();\n for (const layer of [back, body, shadeHair(head)])\n for (let y = 0; y < N; y++)\n for (let x = 0; x < N; x++) if (layer[y]![x]) figure[y]![x] = layer[y]![x];\n\n const features = blank();\n const eyes = blank();\n const closed = blank();\n const glasses = blank();\n const sp = recipe.spacing ?? 0;\n const eyeTop = 15 + h;\n const eyeW = (side: -1 | 1) => (turned && Math.sign(fs) === side ? 3 : 4);\n const eyeX = (side: -1 | 1) => {\n const w = eyeW(side);\n return side < 0\n ? Math.round(C + fs * 0.6) - 6 - sp - (w === 3 ? -1 : 0)\n : Math.round(C + fs * 0.6) + 2 + sp;\n };\n const left = { x: eyeX(-1), w: eyeW(-1) };\n const right = { x: eyeX(1), w: eyeW(1) };\n const fit = (rows: readonly string[], w: number) =>\n rows.map((r) => r.slice(Math.max(0, r.length - w)));\n const pal = {\n K: INK,\n W: WHITE,\n D: shade(recipe.eyeColor, 0.55),\n I: recipe.eyeColor,\n L: mix(recipe.eyeColor, WHITE, 0.45),\n };\n if (flower) {\n const centre = Math.round(C + fs * 0.6);\n const bead = { K: '#1d1b22', W: WHITE };\n for (const ex of [centre - 3, centre + 1]) {\n sprite(eyes, ['KK', 'KW', 'KK', 'KK'], ex, eyeTop - 1, bead);\n sprite(closed, ['..', '..', 'KK', '..'], ex, eyeTop - 1, bead);\n }\n } else {\n const style = EYES[recipe.eyes];\n const extra = style[0]!.length - 4;\n sprite(eyes, fit(style, left.w + extra), left.x - extra, eyeTop, pal);\n sprite(\n eyes,\n recipe.eyes === 'wink' ? fit(CLOSED, right.w) : fit(style, right.w + extra),\n right.x,\n eyeTop,\n pal,\n true,\n );\n sprite(closed, fit(CLOSED, left.w), left.x, eyeTop, pal);\n sprite(closed, fit(CLOSED, right.w), right.x, eyeTop, pal, true);\n }\n const browRows = flower ? [] : BROWS[recipe.brows];\n if (browRows.length) {\n sprite(features, fit(browRows, left.w), left.x, eyeTop - 2, { B: shade(hairColor, 0.55) });\n sprite(\n features,\n fit(browRows, right.w),\n right.x,\n eyeTop - 2,\n { B: shade(hairColor, 0.55) },\n true,\n );\n }\n const cx = Math.round(C + fs * (turned ? 0.85 : 0.6));\n if (flower) {\n // A flower's face is only its bead eyes and its mouth.\n } else if (recipe.species === 'dwarf')\n sprite(features, ['.N.', 'NnN'], cx - 1, 17 + h, {\n N: shade(skin, 0.84),\n n: shade(skin, 0.72),\n });\n else if (recipe.nose === 'dot') sprite(features, ['N'], cx, 18 + h, { N: shade(skin, 0.78) });\n else if (recipe.nose === 'button') sprite(features, ['N'], cx, 18 + h, { N: shade(skin, 0.88) });\n else if (recipe.nose === 'line')\n sprite(features, ['N', 'N'], cx, 17 + h, { N: shade(skin, 0.82) });\n const mx = C - 0.5 + fs * 0.6;\n const withMouth = (mouth: readonly string[]) => {\n const layer = features.map((row) => [...row]);\n sprite(layer, mouth, Math.round(mx - (mouth[0]!.length - 1) / 2), 20 + h, {\n K: MOUTH,\n M: MOUTH_INSIDE,\n T: TONGUE,\n W: WHITE,\n });\n if (recipe.species === 'goblin')\n for (const tx of [Math.round(mx - 2.5), Math.round(mx + 2.5)])\n sprite(layer, ['T'], tx, 21 + h, { T: TUSK });\n if (recipe.species === 'orc')\n for (const tx of [Math.round(mx - 2.5), Math.round(mx + 2.5)])\n sprite(layer, ['T', 'T'], tx, 20 + h, { T: TUSK });\n if (recipe.cheeks === 'blush' && !flower) {\n sprite(layer, ['PP'], left.x - 1, 19 + h, { P: mix(BLUSH, skin, 0.25) });\n sprite(layer, ['PP'], right.x + right.w - 1, 19 + h, { P: mix(BLUSH, skin, 0.25) });\n }\n if (recipe.cheeks === 'freckles' && !flower) {\n sprite(layer, ['F.F'], left.x, 19 + h, { F: shade(skin, 0.7) });\n sprite(layer, ['F.F'], right.x + 1, 19 + h, { F: shade(skin, 0.7) });\n }\n return layer;\n };\n const savedFeatures = withMouth(MOUTHS[recipe.mouth]);\n const featureMarkup = options.mouthLayers\n ? (\n [\n ['saved', MOUTHS[recipe.mouth]],\n ['closed', ['KKK']],\n ['half-open', ['KKK', 'MMM']],\n ['open', ['.K.', 'KMK', '.K.']],\n ] satisfies readonly [PixelMouthState, readonly string[]][]\n )\n .map(\n ([state, rows]) =>\n `<g data-avatar-mouth=\"${state}\" opacity=\"${state === 'saved' ? 1 : 0}\">${rects(withMouth(rows))}</g>`,\n )\n .join('')\n : rects(savedFeatures);\n const frame = (fx: number, w: number, round: boolean) =>\n paint(\n glasses,\n (x, y) => {\n const inside = x >= fx && x < fx + w && y >= eyeTop && y <= eyeTop + 3;\n const box = x >= fx - 1 && x <= fx + w && y >= eyeTop - 1 && y <= eyeTop + 4;\n const corner = (x === fx - 1 || x === fx + w) && (y === eyeTop - 1 || y === eyeTop + 4);\n return box && !inside && !(round && corner);\n },\n INK,\n );\n const lenses = flower ? 'none' : recipe.glasses;\n if (lenses === 'round' || lenses === 'square') {\n frame(left.x, left.w, lenses === 'round');\n frame(right.x, right.w, lenses === 'round');\n paint(glasses, (x, y) => y === eyeTop + 1 && x > left.x + left.w && x < right.x - 1, INK);\n }\n if (lenses === 'shades') {\n for (const e of [left, right])\n paint(\n glasses,\n (x, y) => x >= e.x - 1 && x <= e.x + e.w && y >= eyeTop && y <= eyeTop + 2,\n INK,\n );\n paint(glasses, (x, y) => y === eyeTop && x > left.x + left.w && x < right.x - 1, INK);\n for (const e of [left, right]) sprite(glasses, ['W'], e.x, eyeTop, { W: '#7d7b88' });\n }\n if (lenses === 'monocle') {\n frame(right.x, right.w, true);\n sprite(glasses, ['G', 'G', 'G'], right.x + right.w, eyeTop + 5, { G: GOLD });\n }\n\n const full = clip(outline(figure));\n AVATAR_PIECE_COLORS.forEach((key, i) => {\n const color = recipe[key];\n const mask = masks.sides?.[i];\n if (color === undefined || !mask || color.toLowerCase() === hairColor.toLowerCase()) return;\n const variant = blank();\n const plain = { ...recipe, hairColor: color };\n for (const k of AVATAR_PIECE_COLORS) delete plain[k];\n for (const cell of pixelFigure(plain, yawDeg).cells) variant[cell.y]![cell.x] = cell.c;\n const near = (x: number, y: number) =>\n mask(x, y) || mask(x - 1, y) || mask(x + 1, y) || mask(x, y - 1) || mask(x, y + 1);\n for (let y = 0; y < N; y++)\n for (let x = 0; x < N; x++)\n if (full[y]![x] && near(x, y) && !eyes[y]![x] && !glasses[y]![x])\n full[y]![x] = variant[y]![x];\n });\n const bodyCells = blank();\n const headCells = blank();\n for (let y = 0; y < N; y++)\n for (let x = 0; x < N; x++) {\n const c = full[y]![x];\n if (!c) continue;\n if (y >= 22 && !head[y]![x] && !back[y]![x]) bodyCells[y]![x] = c;\n else headCells[y]![x] = c;\n }\n const cells: PixelCell[] = [];\n for (let y = 0; y < N; y++)\n for (let x = 0; x < N; x++) {\n const c = glasses[y]![x] ?? eyes[y]![x] ?? savedFeatures[y]![x] ?? full[y]![x];\n if (c) cells.push({ x, y, c });\n }\n return {\n cells,\n tile: `<rect width=\"32\" height=\"32\" rx=\"6\" fill=\"${pixelTileColor(recipe.hairColor)}\"/>`,\n body: `<g class=\"bh-illustrated-body\">${rects(bodyCells)}</g>`,\n head: [\n `<g class=\"bh-illustrated-head\">${rects(headCells)}`,\n `<g class=\"bh-illustrated-face\">${featureMarkup}`,\n `<g class=\"bh-illustrated-gaze\">${rects(eyes)}</g>`,\n `<g class=\"bh-illustrated-blink\" opacity=\"0\">${rects(closed)}</g>`,\n `${rects(glasses)}</g></g>`,\n ].join(''),\n };\n}\n","import type { PixelCell } from '@botharness/pixel-morph';\nimport { pixelFigure } from './figure.js';\nimport { isPixelAvatarRecipe, type PixelAvatarRecipe } from './recipe.js';\n\nconst YAW = { front: 0, left: -25, right: 25 } as const;\n\n/** Head-turn offsets (degrees) the thinking animation cycles through. */\nexport const AVATAR_TURNS = [-14, -7, 7, 14] as const;\n\nexport interface PixelAvatarSvgOptions {\n mouthLayers?: boolean;\n /** Extra yaw offsets to pre-render as hidden `[data-avatar-turn]` layers. */\n turns?: readonly number[];\n /** Class prefix for the rig layers (`-body`, `-head`, `-face`, `-gaze`, `-blink`). */\n classPrefix?: string;\n}\n\n/** Every visible pixel of the face at its pose, in paint order, for morphing. */\nexport function faceCells(recipe: PixelAvatarRecipe): PixelCell[] {\n return pixelFigure(recipe, YAW[recipe.pose]).cells;\n}\n\n/** A 32×32 SVG of the avatar: tile, body, head rig, optional turn layers and an empty morph layer. */\nexport function pixelAvatarSvg(\n recipe: PixelAvatarRecipe,\n options: PixelAvatarSvgOptions = {},\n): string {\n if (!isPixelAvatarRecipe(recipe)) throw new Error('invalid Avatar recipe');\n const base = pixelFigure(recipe, YAW[recipe.pose], options);\n const turns = (options.turns ?? [])\n .map((delta) => {\n const figure = pixelFigure(recipe, YAW[recipe.pose] + delta, options);\n const layers = `${figure.body}${figure.head}`.replaceAll(\n 'class=\"bh-illustrated-',\n 'data-turn-part=\"',\n );\n return `<g data-avatar-turn=\"${delta}\" opacity=\"0\">${layers}</g>`;\n })\n .join('');\n const svg = [\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 32\" width=\"512\" height=\"512\" shape-rendering=\"crispEdges\" aria-hidden=\"true\">',\n base.tile,\n base.body,\n base.head,\n turns,\n '<g data-avatar-pixel-morph=\"\"></g>',\n '</svg>',\n ].join('');\n const prefix = options.classPrefix;\n return prefix === undefined || prefix === 'bh-illustrated'\n ? svg\n : svg.replaceAll('class=\"bh-illustrated-', `class=\"${prefix}-`);\n}\n","import type { PixelCell } from '@botharness/pixel-morph';\n\nconst SYMBOLS = {\n thinking: [\n '........................',\n '........................',\n '........................',\n '...........AAAA.........',\n '..........AAAAAA........',\n '.........AAAAAAAA.......',\n '.......AAAAAAAAAAA......',\n '.....AAAAAAAAAAAAA......',\n '....AAAAAAAAAAAAAAAA....',\n '....AAAAAAAAAAAAAAAAA...',\n '...AAAAAAAAAAAAAAAAAAA..',\n '...AAAAHHAAAHHAAAHHAAA..',\n '....AAAHHAAAHHAAAHHAAA..',\n '....AAAAAAAAAAAAAAAAAA..',\n '.....AAAAAAAAAAAAAAAA...',\n '.....AAAAAAAAAAAAAAA....',\n '.......AAAAAAAAAAA......',\n '........................',\n '....AA..................',\n '...AAAA.................',\n '...AAAA.................',\n '..A.AA..................',\n '.AAA....................',\n '..A.....................',\n ],\n ask: [\n '........................',\n '........................',\n '...........AAA..........',\n '........AAAAAAAA........',\n '.......AAAAAAAAAA.......',\n '.......AAAAAAAAAA.......',\n '......AAAAA...AAAA......',\n '......AAAA....AAAA......',\n '......AAA.....AAAA......',\n '......AAA.....AAAA......',\n '..............AAAA......',\n '.............AAAAA......',\n '............AAAAA.......',\n '...........AAAAA........',\n '...........AAA..........',\n '..........AAAA..........',\n '..........AAAA..........',\n '...........AA...........',\n '........................',\n '..........AAAA..........',\n '..........AAAA..........',\n '..........AAAA..........',\n '...........AA...........',\n '........................',\n ],\n read: [\n '........................',\n '........................',\n '........................',\n '........................',\n '..AAAAAAA......AAAAAAA..',\n '.AAAAAAAAAA..AAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAHHHHHAAAAAAHHHHHAAA.',\n '.AAAHHHHHAAAAAAHHHHHAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAHHHHHAAAAAAHHHHHAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '...........AA...........',\n '........................',\n '........................',\n '........................',\n '........................',\n '........................',\n ],\n write: [\n '........................',\n '.....AAAAAAAAAA.........',\n '....AAAAAAAAAAAA........',\n '....AAAAAAAAAAAAA.......',\n '....AAAAAAAAAAAAAA......',\n '....AAAAAAAAAAAAAAA.....',\n '....AAAAAAAAAAAAAAAA....',\n '....AAAAAAAAAAAAAAAA....',\n '....AAAAAAAAAAAAAAAA....',\n '....AAAAAAAHHAAAAAAA....',\n '....AAAAAAAHHAAAAAAA....',\n '....AAAAAAAHHAAAAAAA....',\n '....AAAAAAAHHAAAAAAA....',\n '....AAAHHHHHHHHHHAAA....',\n '....AAAAAAAHHAAAAAAA....',\n '....AAAAAAAHHAAAAAAA....',\n '....AAAAAAAHHAAAAAAA....',\n '....AAAAAAAHHAAAAAAA....',\n '....AAAAAAAAAAAAAAAA....',\n '....AAAAAAAAAAAAAAAA....',\n '....AAAAAAAAAAAAAAAA....',\n '....AAAAAAAAAAAAAAAA....',\n '.....AAAAAAAAAAAAAA.....',\n '........................',\n ],\n edit: [\n '........................',\n '........................',\n '........................',\n '...............AA.......',\n '.............HHAAA......',\n '.............HHHAAA.....',\n '............AAHHHAAA....',\n '...........AAAAHHHAAA...',\n '..........AAAAAAHHHAA...',\n '.........AAAAAAAAHHH....',\n '........AAAAAAAAAAHH....',\n '.......AAAAAAAAAAA......',\n '......AAAAAAAAAAA.......',\n '.....AAAAAAAAAAA........',\n '....AAAAAAAAAAA.........',\n '...AAAAAAAAAAA..........',\n '...AAHHAAAAAA...........',\n '...AAHHHAAAA............',\n '...AAAHHAAA.............',\n '...AAAAAAA..............',\n '...AAAAAA...............',\n '........................',\n '........................',\n '........................',\n ],\n bash: [\n '........................',\n '........................',\n '........................',\n '....AAAAAAAAAAAAAAAA....',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAHHAAAAAAAAAAAAAAAA.',\n '.AAAAHHHAAAAAAAAAAAAAAA.',\n '.AAAAAHHHAAAAAAAAAAAAAA.',\n '.AAAAAAHHHAAAAAAAAAAAAA.',\n '.AAAAAAHHHAAAAAAAAAAAAA.',\n '.AAAAAHHHAAAAAAAAAAAAAA.',\n '.AAAAHHHAAAAAAAAAAAAAAA.',\n '.AAAAHHAAAAHHHHHHHAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '....AAAAAAAAAAAAAAAA....',\n '........................',\n '........................',\n '........................',\n ],\n search: [\n '........................',\n '........................',\n '.......AAAAAA...........',\n '......AAAAAAAA..........',\n '....AAAAAAAAAAAA........',\n '....AAAAAAAAAAAA........',\n '...AAAA......AAAA.......',\n '..AAAA........AAAA......',\n '..AAAA........AAAA......',\n '..AAAA........AAAA......',\n '..AAAA........AAAA......',\n '..AAAA........AAAA......',\n '..AAAA........AAAA......',\n '...AAAA......AAAA.......',\n '....AAAAAAAAAAAAA.......',\n '....AAAAAAAAAAAAAA......',\n '......AAAAAAAAAAAAA.....',\n '.......AAAAAA..AAAAA....',\n '................AAAAA...',\n '.................AAAAA..',\n '..................AAAAA.',\n '...................AAAA.',\n '....................AA..',\n '........................',\n ],\n web: [\n '........................',\n '........................',\n '.........AHHHHA.........',\n '.......AAHHHHHHAA.......',\n '.....AAAAHHAAHHAAAA.....',\n '....AAAAHHAAAAHHAAAA....',\n '....HHHHHHHHHHHHHHHH....',\n '...AHHHHHHHHHHHHHHHHA...',\n '...AAAAAHAAAAAAHAAAAA...',\n '..AAAAAHHAAAAAAHAAAAAA..',\n '..AAAAAHHAAAAAAHHAAAAA..',\n '..HHHHHHHHHHHHHHHHHHHH..',\n '..HHHHHHHHHHHHHHHHHHHH..',\n '..AAAAAHHAAAAAAHHAAAAA..',\n '..AAAAAHHAAAAAAHAAAAAA..',\n '...AAAAAHAAAAAAHAAAAA...',\n '...AHHHHHHHHHHHHHHHHA...',\n '....HHHHHHHHHHHHHHHH....',\n '....AAAAHHAAAAHHAAAA....',\n '.....AAAAHHAAHHAAAA.....',\n '.......AAHHHHHHAA.......',\n '.........AHHHHA.........',\n '........................',\n '........................',\n ],\n fetch: [\n '........................',\n '..........AAA...........',\n '..........AAAA..........',\n '..........AAAA..........',\n '..........AAAA..........',\n '..........AAAA..........',\n '..........AAAA..........',\n '.....AA...AAAA...AA.....',\n '....AAAA..AAAA..AAAA....',\n '....AAAAA.AAAA.AAAAA....',\n '.....AAAAAAAAAAAAAA.....',\n '......AAAAAAAAAAAA......',\n '.......AAAAAAAAAA.......',\n '........AAAAAAAA........',\n '.........AAAAAA.........',\n '..AAA.....AAAA.....AAA..',\n '..AAA......AA......AAA..',\n '..AAA..............AAA..',\n '..AAA..............AAA..',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '...AAAAAAAAAAAAAAAAAA...',\n '........................',\n ],\n todo: [\n '........................',\n '........................',\n '....AAAAAAAAAAAAAAAA....',\n '....AAAAAAAAAAAAAAAA....',\n '...AAAAAAAAAAAAAAAAAA...',\n '...AAAAAAAAAAAAAAAAAA...',\n '...AAAAAAAAHAAAAAAAAA...',\n '...AAAAAAAHHAAAAAAAAA...',\n '...AAAHHAHHAAHHHHHAAA...',\n '...AAAAHHHAAAHHHHHAAA...',\n '...AAAAAHAAAAAAAAAAAA...',\n '...AAAAAAAAAAAAAAAAAA...',\n '...AAAAAAAAAAAAAAAAAA...',\n '...AAAAAAAAHAAAAAAAAA...',\n '...AAAAAAAHHAAAAAAAAA...',\n '...AAAHHAHHAAHHHHHAAA...',\n '...AAAAHHHAAAHHHHHAAA...',\n '...AAAAAHAAAAAAAAAAAA...',\n '...AAAAAAAAAAAAAAAAAA...',\n '...AAAAAAAAAAAAAAAAAA...',\n '...AAAAAAAAAAAAAAAAAA...',\n '....AAAAAAAAAAAAAAAA....',\n '.....AAAAAAAAAAAAAA.....',\n '........................',\n ],\n subagent: [\n '........................',\n '........................',\n '........................',\n '........................',\n '.....AAAA......AAAA.....',\n '....AAAAAA....AAAAAA....',\n '....AAAAAAA..AAAAAAA....',\n '....AAAAAAA..AAAAAAA....',\n '....AAAAAAA..AAAAAAA....',\n '....AAAAAA...AAAAAAA....',\n '.....AAAAA....AAAAA.....',\n '........................',\n '........................',\n '........................',\n '.......A................',\n '....AAAAAAA..AAAAAAA....',\n '...AAAAAAAAAAAAAAAAAA...',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '........................',\n '........................',\n '........................',\n ],\n workflow: [\n '........................',\n '........................',\n '........................',\n '..AAAAAA.........AAAAA..',\n '..AAAAAA........AAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAA....AAA.AAAAAAA.',\n '..AAAAAA....AAA..AAAAA..',\n '............AAA.........',\n '............AAA.........',\n '............AAA.........',\n '............AAA.........',\n '............AAA..AAAAA..',\n '............AAA.AAAAAAA.',\n '.............AAAAAAAAAA.',\n '.............AAAAAAAAAA.',\n '...............AAAAAAAA.',\n '................AAAAAAA.',\n '.................AAAAA..',\n '........................',\n '........................',\n '........................',\n ],\n goal: [\n '........................',\n '....AA..................',\n '...AAAA.................',\n '...AAAAAAAAAAAAAAAAA....',\n '...AAAAAAAAAAAAAAAA.....',\n '...AAAAAAAAAAAAAAA......',\n '...AAAAAAAAAAAAAAA......',\n '...AAAAAAAAAAAAAA.......',\n '...AAAAAAAAAAAAAA.......',\n '...AAAAAAAAAAAAAAA......',\n '...AAAAAAAAAAAAAAAA.....',\n '...AAAAAAAAAAAAAAAAA....',\n '...AAAA.................',\n '...AAAA.................',\n '...AAAA.................',\n '...AAAA.................',\n '...AAAA.................',\n '...AAAA.................',\n '...AAAA.................',\n '...AAAA.................',\n '...AAAA.................',\n '...AAAA.................',\n '...AAAA.................',\n '....AA..................',\n ],\n present: [\n '........................',\n '........................',\n '...AAAAAAAAAAAAAAAAAA...',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAHAAAA.',\n '.AAAAAAAAAAAAAAAAAHAAAA.',\n '.AAAAAAAAAHAAAAAAAHAAAA.',\n '.AAAAAAAAAHAAAHAAAHAAAA.',\n '.AAAAAHAAAHAAAHAAAHAAAA.',\n '.AAAAAHAAAHAAAHAAAHAAAA.',\n '.AAAAAHAAAHAAAHAAAHAAAA.',\n '.AAAAAHAAAHAAAHAAAHAAAA.',\n '.AAAAAHAAAHAAAHAAAHAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '...AAAAAAAAAAAAAAAAAA...',\n '.........AAAAAA.........',\n '........AAAAAAAA........',\n '........AAA..AAA........',\n '.......AAA....AAA.......',\n '.......AAA....AAA.......',\n '.......AA......AA.......',\n '........................',\n ],\n approval: [\n '........................',\n '........................',\n '.........AAAAAA.........',\n '......AAAAAAAAAAAA......',\n '....AAAAAAAAAAAAAAAA....',\n '...AAAAAAAAHHAAAAAAAA...',\n '...AAAAAAAAHHAAAAAAAA...',\n '...AAAAAAAAHHAAAAAAAA...',\n '...AAAAAAAAHHAAAAAAAA...',\n '...AAAAAAAAHHAAAAAAAA...',\n '...AAAAAAAAHHAAAAAAAA...',\n '...AAAAAAAAHHAAAAAAAA...',\n '...AAAAAAAAHHAAAAAAAA...',\n '....AAAAAAAHHAAAAAAA....',\n '....AAAAAAAAAAAAAAAA....',\n '....AAAAAAAAAAAAAAAA....',\n '.....AAAAAAHHAAAAAA.....',\n '.....AAAAAAHHAAAAAA.....',\n '......AAAAAAAAAAAA......',\n '.......AAAAAAAAAA.......',\n '........AAAAAAAA........',\n '.........AAAAA..........',\n '...........AA...........',\n '........................',\n ],\n other: [\n '........................',\n '........................',\n '........................',\n '...........AA...........',\n '...........AA...........',\n '..........AAAA..........',\n '..........AAAA..........',\n '..........AAAA..........',\n '.........AAAAAA.........',\n '........AAAAAAAA........',\n '.....AAAAAAAAAAAAAA.....',\n '...AAAAAAAAAAAAAAAAAA...',\n '...AAAAAAAAAAAAAAAAAA...',\n '.....AAAAAAAAAAAAAA.....',\n '........AAAAAAAA........',\n '.........AAAAAA.........',\n '..........AAAA..........',\n '..........AAAA..........',\n '..........AAAA..........',\n '...........AA...........',\n '...........AA...........',\n '........................',\n '........................',\n '........................',\n ],\n} as const satisfies Record<string, readonly string[]>;\n\nexport type PixelSymbol = keyof typeof SYMBOLS;\nexport const PIXEL_SYMBOLS = Object.keys(SYMBOLS) as PixelSymbol[];\n\nconst INK = '#2a2230';\nconst channels = (color: string) => {\n const n = Number.parseInt(color.slice(1), 16);\n return [16, 8, 0].map((bit) => (n >> bit) & 255);\n};\nconst mix = (base: string, tint: string, k: number) => {\n const t = channels(tint);\n return `#${channels(base)\n .map((v, i) =>\n Math.round(v * (1 - k) + t[i]! * k)\n .toString(16)\n .padStart(2, '0'),\n )\n .join('')}`;\n};\n\nexport function pixelSymbolCells(symbol: PixelSymbol, color: string): PixelCell[] {\n return symbolArtCells(SYMBOLS[symbol], color);\n}\n\n/**\n * Colours a 24×24 character-art symbol (`A` body, `H` highlight, anything else empty) into\n * cells on the 32 grid: the body in `color`, highlights lighter, the lower-right edge darker,\n * and a one-pixel ink outline. This is how every built-in symbol is drawn, so a host can add\n * its own symbols in the same style without touching the package.\n */\nexport function symbolArtCells(rows: readonly string[], color: string): PixelCell[] {\n const body = new Map<string, 'A' | 'H'>();\n rows.forEach((row, y) =>\n [...row].forEach((code, x) => {\n if (code === 'A' || code === 'H') body.set(`${x + 4},${y + 4}`, code);\n }),\n );\n const light = mix(color, '#ffffff', 0.75);\n const low = mix(color, INK, 0.25);\n const cells: PixelCell[] = [];\n for (const [key, code] of body) {\n const [x, y] = key.split(',').map(Number) as [number, number];\n const edge = x + y > 34 && !body.has(`${x + 1},${y + 1}`);\n cells.push({ x, y, c: code === 'H' ? light : edge ? low : color });\n }\n const outline = new Set<string>();\n for (const key of body.keys()) {\n const [x, y] = key.split(',').map(Number) as [number, number];\n for (const [dx, dy] of [\n [1, 0],\n [-1, 0],\n [0, 1],\n [0, -1],\n ] as const) {\n const next = `${x + dx},${y + dy}`;\n if (body.has(next) || outline.has(next)) continue;\n outline.add(next);\n cells.push({ x: x + dx, y: y + dy, c: INK });\n }\n }\n return cells;\n}\n"],"mappings":"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;CAAC;CAAK;CAAI;CAAG;CAAG;;AAW5C,SAAgB,UAAU,QAAwC;AAChE,QAAO,YAAY,QAAQ,IAAI,OAAO,MAAM,CAAC;;;AAI/C,SAAgB,eACd,QACA,UAAiC,EAAE,EAC3B;AACR,KAAI,CAAC,oBAAoB,OAAO,CAAE,OAAM,IAAI,MAAM,wBAAwB;CAC1E,MAAM,OAAO,YAAY,QAAQ,IAAI,OAAO,OAAO,QAAQ;CAC3D,MAAM,SAAS,QAAQ,SAAS,EAAE,EAC/B,KAAK,UAAU;EACd,MAAM,SAAS,YAAY,QAAQ,IAAI,OAAO,QAAQ,OAAO,QAAQ;AAKrE,SAAO,wBAAwB,MAAM,gBAJtB,GAAG,OAAO,OAAO,OAAO,OAAO,WAC5C,2BACA,oBACD,CAC2D;GAC5D,CACD,KAAK,GAAG;CACX,MAAM,MAAM;EACV;EACA,KAAK;EACL,KAAK;EACL,KAAK;EACL;EACA;EACA;EACD,CAAC,KAAK,GAAG;CACV,MAAM,SAAS,QAAQ;AACvB,QAAO,WAAW,UAAa,WAAW,mBACtC,MACA,IAAI,WAAW,2BAA0B,UAAU,OAAO,GAAG;;;;;ACjDnE,MAAM,UAAU;CACd,UAAU;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,KAAK;EACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,MAAM;EACJ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,MAAM;EACJ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,MAAM;EACJ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,QAAQ;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,KAAK;EACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,MAAM;EACJ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,UAAU;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,UAAU;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,MAAM;EACJ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,SAAS;EACP;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,UAAU;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACF;AAGD,MAAa,gBAAgB,OAAO,KAAK,QAAQ;AAEjD,MAAM,MAAM;AACZ,MAAM,YAAY,UAAkB;CAClC,MAAM,IAAI,OAAO,SAAS,MAAM,MAAM,EAAE,EAAE,GAAG;AAC7C,QAAO;EAAC;EAAI;EAAG;EAAE,CAAC,KAAK,QAAS,KAAK,MAAO,IAAI;;AAElD,MAAM,OAAO,MAAc,MAAc,MAAc;CACrD,MAAM,IAAI,SAAS,KAAK;AACxB,QAAO,IAAI,SAAS,KAAK,CACtB,KAAK,GAAG,MACP,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,KAAM,EAAE,CAChC,SAAS,GAAG,CACZ,SAAS,GAAG,IAAI,CACpB,CACA,KAAK,GAAG;;AAGb,SAAgB,iBAAiB,QAAqB,OAA4B;AAChF,QAAO,eAAe,QAAQ,SAAS,MAAM;;;;;;;;AAS/C,SAAgB,eAAe,MAAyB,OAA4B;CAClF,MAAM,uBAAO,IAAI,KAAwB;AACzC,MAAK,SAAS,KAAK,MACjB,CAAC,GAAG,IAAI,CAAC,SAAS,MAAM,MAAM;AAC5B,MAAI,SAAS,OAAO,SAAS,IAAK,MAAK,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,KAAK,KAAK;GACrE,CACH;CACD,MAAM,QAAQ,IAAI,OAAO,WAAW,IAAK;CACzC,MAAM,MAAM,IAAI,OAAO,KAAK,IAAK;CACjC,MAAM,QAAqB,EAAE;AAC7B,MAAK,MAAM,CAAC,KAAK,SAAS,MAAM;EAC9B,MAAM,CAAC,GAAG,KAAK,IAAI,MAAM,IAAI,CAAC,IAAI,OAAO;EACzC,MAAM,OAAO,IAAI,IAAI,MAAM,CAAC,KAAK,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,IAAI;AACzD,QAAM,KAAK;GAAE;GAAG;GAAG,GAAG,SAAS,MAAM,QAAQ,OAAO,MAAM;GAAO,CAAC;;CAEpE,MAAM,0BAAU,IAAI,KAAa;AACjC,MAAK,MAAM,OAAO,KAAK,MAAM,EAAE;EAC7B,MAAM,CAAC,GAAG,KAAK,IAAI,MAAM,IAAI,CAAC,IAAI,OAAO;AACzC,OAAK,MAAM,CAAC,IAAI,OAAO;GACrB,CAAC,GAAG,EAAE;GACN,CAAC,IAAI,EAAE;GACP,CAAC,GAAG,EAAE;GACN,CAAC,GAAG,GAAG;GACR,EAAW;GACV,MAAM,OAAO,GAAG,IAAI,GAAG,GAAG,IAAI;AAC9B,OAAI,KAAK,IAAI,KAAK,IAAI,QAAQ,IAAI,KAAK,CAAE;AACzC,WAAQ,IAAI,KAAK;AACjB,SAAM,KAAK;IAAE,GAAG,IAAI;IAAI,GAAG,IAAI;IAAI,GAAG;IAAK,CAAC;;;AAGhD,QAAO"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["INK","channels","mix"],"sources":["../src/part.ts","../src/random.ts","../src/recipe.ts","../src/figure.ts","../src/svg.ts","../src/symbols.ts"],"sourcesContent":["import { AVATAR_COLORS, type AvatarColor } from './recipe.js';\n\n/**\n * Custom Part slots. A headpiece covers the top of the tile, around the hair: its back layer is\n * drawn behind the hair and its front layer over it. Cells are in tile coordinates, so the\n * Avatar centerline sits between x = 15 and x = 16.\n */\nexport const PART_SLOTS = {\n headpiece: { width: 32, height: 16 },\n} as const;\nexport type PartSlot = keyof typeof PART_SLOTS;\n/** Tone steps on the rig's shade ramp: two darker, the color itself, two lighter. */\nexport const PART_TONES = [-2, -1, 0, 1, 2] as const;\nexport type PartTone = (typeof PART_TONES)[number];\n/** An appearance color slot (it follows the Avatar's color) or a fixed `#rrggbb` color. */\nexport type PartColor = AvatarColor | `#${string}`;\n/** One painted cell: `[x, y, color, tone]`. */\nexport type PartCell = readonly [x: number, y: number, color: PartColor, tone: PartTone];\nexport const PART_LAYERS = ['front', 'back'] as const;\nexport type PartLayerName = (typeof PART_LAYERS)[number];\n/** Most fixed colors one part may use. */\nexport const MAX_PART_FIXED_COLORS = 16;\n\n/**\n * A Human-drawn Custom Part. Its content is immutable and its identity is `customPartId`;\n * name, author, origin and parent are metadata kept outside it.\n */\nexport interface PixelCustomPart {\n slot: PartSlot;\n front: readonly PartCell[];\n back: readonly PartCell[];\n}\n\n/** A dense layer for drawing: `layer[y][x]` is a color and tone, or `null` when empty. */\nexport type PartInk = { color: PartColor; tone: PartTone };\nexport type PartLayer = (PartInk | null)[][];\n\nconst FIXED = /^#[\\da-f]{6}$/iu;\nconst isColor = (value: unknown): value is PartColor =>\n typeof value === 'string' &&\n ((AVATAR_COLORS as readonly string[]).includes(value) || FIXED.test(value));\n\nexport function isPixelCustomPart(value: unknown): value is PixelCustomPart {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const r = value as Record<string, unknown>;\n if (Object.keys(r).length !== 3 || !Object.hasOwn(PART_SLOTS, r['slot'] as string)) return false;\n const { width, height } = PART_SLOTS[r['slot'] as PartSlot];\n const fixed = new Set<string>();\n for (const name of PART_LAYERS) {\n const cells = r[name];\n if (!Array.isArray(cells) || cells.length > width * height) return false;\n const seen = new Set<number>();\n for (const cell of cells as unknown[]) {\n if (!Array.isArray(cell) || cell.length !== 4) return false;\n const [x, y, color, tone] = cell as unknown[];\n if (\n !Number.isInteger(x) ||\n !Number.isInteger(y) ||\n (x as number) < 0 ||\n (x as number) >= width ||\n (y as number) < 0 ||\n (y as number) >= height ||\n !isColor(color) ||\n !(PART_TONES as readonly unknown[]).includes(tone)\n )\n return false;\n const key = (y as number) * width + (x as number);\n if (seen.has(key)) return false;\n seen.add(key);\n if (color.startsWith('#')) fixed.add(color.toLowerCase());\n }\n }\n return fixed.size <= MAX_PART_FIXED_COLORS;\n}\n\nconst canonicalCells = (cells: readonly PartCell[]): PartCell[] =>\n cells\n .map(\n ([x, y, color, tone]) =>\n [x, y, color.startsWith('#') ? (color.toLowerCase() as PartColor) : color, tone] as const,\n )\n .sort((a, b) => a[1] - b[1] || a[0] - b[0]);\n\n/** The part with cells in row order and fixed colors in lowercase. */\nexport function canonicalCustomPart(part: PixelCustomPart): PixelCustomPart {\n return { slot: part.slot, front: canonicalCells(part.front), back: canonicalCells(part.back) };\n}\n\n/** Content identity: a SHA-256 of the canonical slot, cells and color references. */\nexport function customPartId(part: PixelCustomPart): string {\n return sha256(JSON.stringify(canonicalCustomPart(part)));\n}\n\nexport function emptyPartLayer(slot: PartSlot): PartLayer {\n const { width, height } = PART_SLOTS[slot];\n return Array.from({ length: height }, () => Array<PartInk | null>(width).fill(null));\n}\n\nexport function partLayer(slot: PartSlot, cells: readonly PartCell[]): PartLayer {\n const layer = emptyPartLayer(slot);\n for (const [x, y, color, tone] of cells) layer[y]![x] = { color, tone };\n return layer;\n}\n\nexport function partCells(layer: PartLayer): PartCell[] {\n return layer.flatMap((row, y) =>\n row.flatMap((ink, x) => (ink ? [[x, y, ink.color, ink.tone] as const] : [])),\n );\n}\n\n/** Builds a canonical part from two drawn layers. */\nexport function createCustomPart(\n slot: PartSlot,\n layers: Record<PartLayerName, PartLayer>,\n): PixelCustomPart {\n return canonicalCustomPart({\n slot,\n front: partCells(layers.front),\n back: partCells(layers.back),\n });\n}\n\n/** The column mirrored across the Avatar centerline. */\nexport function mirrorPartX(slot: PartSlot, x: number): number {\n return PART_SLOTS[slot].width - 1 - x;\n}\n\nconst same = (a: PartInk | null, b: PartInk | null) =>\n a === b || (a !== null && b !== null && a.color === b.color && a.tone === b.tone);\n\n/** Sets cells (pencil with ink, eraser with `null`), optionally mirrored across the centerline. */\nexport function paintPartLayer(\n slot: PartSlot,\n layer: PartLayer,\n points: readonly (readonly [number, number])[],\n ink: PartInk | null,\n mirror = false,\n): PartLayer {\n const out = layer.map((row) => [...row]);\n const { width, height } = PART_SLOTS[slot];\n for (const [x, y] of points)\n for (const px of mirror ? [x, mirrorPartX(slot, x)] : [x])\n if (px >= 0 && px < width && y >= 0 && y < height) out[y]![px] = ink;\n return out;\n}\n\n/**\n * 4-connected flood fill from a cell: every cell reachable through cells equal to the start\n * becomes `ink`. With `mirror`, the mirrored start is filled too.\n */\nexport function fillPartLayer(\n slot: PartSlot,\n layer: PartLayer,\n x: number,\n y: number,\n ink: PartInk | null,\n mirror = false,\n): PartLayer {\n const { width, height } = PART_SLOTS[slot];\n let out = layer.map((row) => [...row]);\n for (const sx of mirror ? [x, mirrorPartX(slot, x)] : [x]) {\n if (sx < 0 || sx >= width || y < 0 || y >= height) continue;\n const target = out[y]![sx]!;\n if (same(target, ink)) continue;\n const next = out.map((row) => [...row]);\n const stack: [number, number][] = [[sx, y]];\n while (stack.length) {\n const [cx, cy] = stack.pop()!;\n if (cx < 0 || cx >= width || cy < 0 || cy >= height) continue;\n if (!same(next[cy]![cx]!, target)) continue;\n next[cy]![cx] = ink;\n stack.push([cx + 1, cy], [cx - 1, cy], [cx, cy + 1], [cx, cy - 1]);\n }\n out = next;\n }\n return out;\n}\n\nconst K = Uint32Array.from(\n '428a2f98 71374491 b5c0fbcf e9b5dba5 3956c25b 59f111f1 923f82a4 ab1c5ed5 d807aa98 12835b01 243185be 550c7dc3 72be5d74 80deb1fe 9bdc06a7 c19bf174 e49b69c1 efbe4786 0fc19dc6 240ca1cc 2de92c6f 4a7484aa 5cb0a9dc 76f988da 983e5152 a831c66d b00327c8 bf597fc7 c6e00bf3 d5a79147 06ca6351 14292967 27b70a85 2e1b2138 4d2c6dfc 53380d13 650a7354 766a0abb 81c2c92e 92722c85 a2bfe8a1 a81a664b c24b8b70 c76c51a3 d192e819 d6990624 f40e3585 106aa070 19a4c116 1e376c08 2748774c 34b0bcb5 391c0cb3 4ed8aa4a 5b9cca4f 682e6ff3 748f82ee 78a5636f 84c87814 8cc70208 90befffa a4506ceb bef9a3f7 c67178f2'\n .split(' ')\n .map((h) => Number.parseInt(h, 16)),\n);\n\nfunction sha256(text: string): string {\n const bytes = new TextEncoder().encode(text);\n const length = Math.ceil((bytes.length + 9) / 64) * 64;\n const data = new Uint8Array(length);\n data.set(bytes);\n data[bytes.length] = 0x80;\n const view = new DataView(data.buffer);\n view.setUint32(length - 8, Math.floor((bytes.length * 8) / 2 ** 32));\n view.setUint32(length - 4, (bytes.length * 8) >>> 0);\n const h = Uint32Array.from([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n ]);\n const w = new Uint32Array(64);\n const rotr = (v: number, n: number) => (v >>> n) | (v << (32 - n));\n for (let offset = 0; offset < length; offset += 64) {\n for (let i = 0; i < 16; i++) w[i] = view.getUint32(offset + i * 4);\n for (let i = 16; i < 64; i++) {\n const a = w[i - 15]!;\n const b = w[i - 2]!;\n const s0 = rotr(a, 7) ^ rotr(a, 18) ^ (a >>> 3);\n const s1 = rotr(b, 17) ^ rotr(b, 19) ^ (b >>> 10);\n w[i] = (w[i - 16]! + s0 + w[i - 7]! + s1) >>> 0;\n }\n let [a, b, c, d, e, f, g, k] = h as unknown as number[];\n for (let i = 0; i < 64; i++) {\n const t1 =\n (k! +\n (rotr(e!, 6) ^ rotr(e!, 11) ^ rotr(e!, 25)) +\n ((e! & f!) ^ (~e! & g!)) +\n K[i]! +\n w[i]!) >>>\n 0;\n const t2 =\n ((rotr(a!, 2) ^ rotr(a!, 13) ^ rotr(a!, 22)) + ((a! & b!) ^ (a! & c!) ^ (b! & c!))) >>> 0;\n k = g;\n g = f;\n f = e;\n e = (d! + t1) >>> 0;\n d = c;\n c = b;\n b = a;\n a = (t1 + t2) >>> 0;\n }\n [a, b, c, d, e, f, g, k].forEach((v, i) => (h[i] = (h[i]! + v!) >>> 0));\n }\n return [...h].map((v) => v.toString(16).padStart(8, '0')).join('');\n}\n","export function seededRandom(seed: string): () => number {\n let h = 2166136261;\n for (const char of seed) {\n h ^= char.codePointAt(0)!;\n h = Math.imul(h, 16777619);\n }\n return () => {\n h = Math.imul(h ^ (h >>> 15), 2246822507);\n h = Math.imul(h ^ (h >>> 13), 3266489909);\n h ^= h >>> 16;\n return (h >>> 0) / 4294967296;\n };\n}\n","import { canonicalCustomPart, isPixelCustomPart, type PixelCustomPart } from './part.js';\nimport { seededRandom } from './random.js';\n\nexport const AVATAR_PARTS = {\n head: ['round', 'oval', 'square', 'long', 'heart', 'vchin', 'chubby', 'diamond'],\n pose: ['front', 'left', 'right'],\n hair: [\n 'crop',\n 'sweep',\n 'spiky',\n 'buzz',\n 'curly',\n 'mohawk',\n 'bob',\n 'long',\n 'bun',\n 'pigtails',\n 'afro',\n 'twintails',\n 'drills',\n 'ponytail',\n 'sidetail',\n 'hime',\n 'odango',\n 'messy',\n 'wavy',\n 'braids',\n 'wolf',\n 'ahoge',\n 'none',\n ],\n eyes: ['round', 'dot', 'sparkle', 'lashes', 'sleepy', 'happy', 'wink', 'sharp'],\n brows: ['soft', 'thick', 'raised', 'angry', 'worried', 'none'],\n nose: ['button', 'dot', 'line', 'none'],\n mouth: ['smile', 'grin', 'open', 'flat', 'smirk', 'cat', 'tongue', 'o'],\n cheeks: ['blush', 'freckles', 'none'],\n glasses: ['none', 'round', 'square', 'shades', 'monocle'],\n outfit: [\n 'tee',\n 'shirttie',\n 'hoodie',\n 'turtleneck',\n 'sailor',\n 'blazer',\n 'overalls',\n 'dress',\n 'kimono',\n 'cardigan',\n 'maid',\n 'jacket',\n ],\n backdrop: ['sparkles', 'hearts', 'stars', 'dots', 'none'],\n accessory: [\n 'none',\n 'beanie',\n 'cap',\n 'headphones',\n 'flower',\n 'bow',\n 'earring',\n 'crown',\n 'halo',\n 'catears',\n 'hairclip',\n 'horns',\n 'beret',\n 'ribbon',\n 'headband',\n 'bunnyears',\n 'horseears',\n 'flowercrown',\n 'witch',\n 'pins',\n ],\n} as const;\n\nexport const AVATAR_HAIR_PARTS = {\n bangs: [\n 'crop',\n 'bob',\n 'sweep',\n 'spiky',\n 'curly',\n 'messy',\n 'wolf',\n 'wavy',\n 'ahoge',\n 'hime',\n 'buzz',\n 'mohawk',\n 'none',\n ],\n sideHair: ['crop', 'bun', 'bob', 'long', 'hime', 'curly', 'braids', 'none'],\n backHair: [\n 'none',\n 'bob',\n 'long',\n 'wavy',\n 'wolf',\n 'bun',\n 'odango',\n 'pigtails',\n 'twintails',\n 'drills',\n 'ponytail',\n 'sidetail',\n 'afro',\n ],\n} as const satisfies Record<string, readonly (typeof AVATAR_PARTS)['hair'][number][]>;\nconst HAIR_SPLIT: Record<\n (typeof AVATAR_PARTS)['hair'][number],\n { [P in AvatarHairPart]: (typeof AVATAR_HAIR_PARTS)[P][number] }\n> = {\n crop: { bangs: 'crop', sideHair: 'crop', backHair: 'none' },\n sweep: { bangs: 'sweep', sideHair: 'crop', backHair: 'none' },\n spiky: { bangs: 'spiky', sideHair: 'crop', backHair: 'none' },\n buzz: { bangs: 'buzz', sideHair: 'none', backHair: 'none' },\n curly: { bangs: 'curly', sideHair: 'curly', backHair: 'none' },\n mohawk: { bangs: 'mohawk', sideHair: 'none', backHair: 'none' },\n bob: { bangs: 'bob', sideHair: 'bob', backHair: 'bob' },\n long: { bangs: 'bob', sideHair: 'long', backHair: 'long' },\n bun: { bangs: 'bob', sideHair: 'bun', backHair: 'bun' },\n pigtails: { bangs: 'bob', sideHair: 'bun', backHair: 'pigtails' },\n afro: { bangs: 'buzz', sideHair: 'none', backHair: 'afro' },\n twintails: { bangs: 'bob', sideHair: 'bob', backHair: 'twintails' },\n drills: { bangs: 'bob', sideHair: 'bob', backHair: 'drills' },\n ponytail: { bangs: 'bob', sideHair: 'bun', backHair: 'ponytail' },\n sidetail: { bangs: 'sweep', sideHair: 'bun', backHair: 'sidetail' },\n hime: { bangs: 'hime', sideHair: 'hime', backHair: 'long' },\n odango: { bangs: 'bob', sideHair: 'bun', backHair: 'odango' },\n messy: { bangs: 'messy', sideHair: 'bun', backHair: 'none' },\n wavy: { bangs: 'wavy', sideHair: 'long', backHair: 'wavy' },\n braids: { bangs: 'bob', sideHair: 'braids', backHair: 'none' },\n wolf: { bangs: 'wolf', sideHair: 'bun', backHair: 'wolf' },\n ahoge: { bangs: 'ahoge', sideHair: 'bob', backHair: 'bob' },\n none: { bangs: 'none', sideHair: 'none', backHair: 'none' },\n};\nexport const AVATAR_RANGES = {\n spacing: [-1, 1],\n height: [-1, 1],\n hairLength: [-2, 2],\n} as const;\nexport type AvatarHairPart = keyof typeof AVATAR_HAIR_PARTS;\nexport type AvatarRange = keyof typeof AVATAR_RANGES;\nconst DETAIL_KEYS = [\n ...(Object.keys(AVATAR_HAIR_PARTS) as AvatarHairPart[]),\n ...(Object.keys(AVATAR_RANGES) as AvatarRange[]),\n] as const;\n\nexport type AvatarPart = keyof typeof AVATAR_PARTS;\nexport const AVATAR_COLORS = ['skinColor', 'hairColor', 'eyeColor', 'shirtColor'] as const;\nexport type AvatarColor = (typeof AVATAR_COLORS)[number];\n\n/**\n * Avatar Species: a base on the pixel bust rig. Species share motion and anchors; each sets its\n * own ears, face details and suggested body colors. A recipe with a species is asset version 2.\n */\nexport const AVATAR_SPECIES = ['human', 'goblin', 'elf', 'dwarf', 'orc', 'flower'] as const;\nexport type AvatarSpecies = (typeof AVATAR_SPECIES)[number];\n/** Optional per-piece hair colors (asset version 2); an absent piece uses `hairColor`. */\nexport const AVATAR_PIECE_COLORS = ['leftSideHairColor', 'rightSideHairColor'] as const;\nexport type AvatarPieceColor = (typeof AVATAR_PIECE_COLORS)[number];\n\n/** Part choices that exist only in asset version 2, added after every version 1 choice. */\nexport const AVATAR_PARTS_V2 = {\n ...AVATAR_PARTS,\n outfit: [...AVATAR_PARTS.outfit, 'armor', 'robe', 'tunic', 'cloak'],\n accessory: [...AVATAR_PARTS.accessory, 'helmet', 'hood'],\n} as const satisfies { [P in AvatarPart]: readonly string[] };\n/** Optional asset version 2 parts; an absent part is not drawn (or uses the first choice). */\nexport const AVATAR_EXTRA_PARTS = {\n beard: ['short', 'full', 'braided'],\n petals: ['trumpet', 'daisy', 'sunflower', 'tulip', 'sakura'],\n flowerBase: ['leaves', 'pot'],\n} as const;\nexport type AvatarExtraPart = keyof typeof AVATAR_EXTRA_PARTS;\n\ntype Meta = { schemaVersion: 1; family: 'illustrated'; rigVersion: 1 } & Record<\n AvatarColor,\n string\n>;\n\n/** Asset version 1: optional split hair and geometry, all six or none. */\nexport type PixelAvatarRecipeV1 = Meta & { assetVersion: 1 } & {\n [P in AvatarPart]: (typeof AVATAR_PARTS)[P][number];\n} & {\n [P in AvatarHairPart]?: (typeof AVATAR_PARTS)['hair'][number];\n} & { [P in AvatarRange]?: number } & {\n species?: never;\n rightSideHair?: never;\n} & { [P in AvatarPieceColor | AvatarExtraPart]?: never } & { headpiece?: never };\n\n/**\n * Asset version 2: a species, the full split hair and geometry, a separate right side hair\n * (`sideHair` is then the left side) and optional per-side hair colors.\n */\nexport type PixelAvatarRecipeV2 = Meta & { assetVersion: 2 } & {\n [P in AvatarPart]: (typeof AVATAR_PARTS_V2)[P][number];\n} & {\n [P in AvatarHairPart]: (typeof AVATAR_PARTS)['hair'][number];\n} & { [P in AvatarRange]: number } & {\n species: AvatarSpecies;\n rightSideHair: (typeof AVATAR_HAIR_PARTS)['sideHair'][number];\n} & { [P in AvatarPieceColor]?: string } & {\n [P in AvatarExtraPart]?: (typeof AVATAR_EXTRA_PARTS)[P][number];\n} & { headpiece?: never };\n\n/** Asset version 3: version 2 with an embedded Custom Part in the headpiece slot. */\nexport type PixelAvatarRecipeV3 = Omit<PixelAvatarRecipeV2, 'assetVersion' | 'headpiece'> & {\n assetVersion: 3;\n headpiece: PixelCustomPart;\n};\n\nexport type PixelAvatarRecipe = PixelAvatarRecipeV1 | PixelAvatarRecipeV2 | PixelAvatarRecipeV3;\n\nexport const DEFAULT_RECIPE: PixelAvatarRecipeV1 = {\n schemaVersion: 1,\n family: 'illustrated',\n assetVersion: 1,\n rigVersion: 1,\n head: 'round',\n pose: 'front',\n hair: 'crop',\n eyes: 'round',\n brows: 'soft',\n nose: 'button',\n mouth: 'smile',\n cheeks: 'blush',\n glasses: 'none',\n outfit: 'tee',\n backdrop: 'sparkles',\n accessory: 'none',\n skinColor: '#f2c9a8',\n hairColor: '#5a3a2a',\n eyeColor: '#3f7fbf',\n shirtColor: '#5b8bd6',\n};\n\nconst PART_KEYS = Object.keys(AVATAR_PARTS) as AvatarPart[];\n\nexport function isPixelAvatarRecipe(value: unknown): value is PixelAvatarRecipe {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const r = value as Record<string, unknown>;\n const detailed = DETAIL_KEYS.filter((key) => Object.hasOwn(r, key)).length;\n if (detailed !== 0 && detailed !== DETAIL_KEYS.length) return false;\n const v3 = r['assetVersion'] === 3;\n const v2 = r['assetVersion'] === 2 || v3;\n if (v3 ? !isPixelCustomPart(r['headpiece']) : Object.hasOwn(r, 'headpiece')) return false;\n const pieces = AVATAR_PIECE_COLORS.filter((key) => Object.hasOwn(r, key));\n const extras = (Object.keys(AVATAR_EXTRA_PARTS) as AvatarExtraPart[]).filter((key) =>\n Object.hasOwn(r, key),\n );\n const v2Keys = v2 ? 2 + pieces.length + extras.length + (v3 ? 1 : 0) : 0;\n if (Object.keys(r).length !== Object.keys(DEFAULT_RECIPE).length + detailed + v2Keys)\n return false;\n if (\n v2 &&\n (detailed === 0 ||\n !(AVATAR_SPECIES as readonly unknown[]).includes(r['species']) ||\n !(AVATAR_HAIR_PARTS.sideHair as readonly unknown[]).includes(r['rightSideHair']) ||\n !pieces.every((key) => typeof r[key] === 'string' && /^#[\\da-f]{6}$/iu.test(r[key])) ||\n !extras.every((key) => (AVATAR_EXTRA_PARTS[key] as readonly unknown[]).includes(r[key])))\n )\n return false;\n const catalog: { [P in AvatarPart]: readonly string[] } = v2 ? AVATAR_PARTS_V2 : AVATAR_PARTS;\n return (\n (detailed === 0 ||\n ((Object.keys(AVATAR_HAIR_PARTS) as AvatarHairPart[]).every(\n (key) =>\n typeof r[key] === 'string' &&\n (AVATAR_HAIR_PARTS[key] as readonly string[]).includes(r[key]),\n ) &&\n (Object.keys(AVATAR_RANGES) as AvatarRange[]).every((key) => {\n const v = r[key];\n const [min, max] = AVATAR_RANGES[key];\n return typeof v === 'number' && Number.isInteger(v) && v >= min && v <= max;\n }))) &&\n r['schemaVersion'] === 1 &&\n r['family'] === 'illustrated' &&\n (r['assetVersion'] === 1 || v2) &&\n r['rigVersion'] === 1 &&\n PART_KEYS.every((key) => typeof r[key] === 'string' && catalog[key].includes(r[key])) &&\n AVATAR_COLORS.every((key) => typeof r[key] === 'string' && /^#[\\da-f]{6}$/iu.test(r[key]))\n );\n}\n\nexport function canonicalRecipe(recipe: PixelAvatarRecipe): PixelAvatarRecipe {\n const canonical: Record<string, unknown> = {\n schemaVersion: 1,\n family: 'illustrated',\n assetVersion: recipe.assetVersion,\n rigVersion: 1,\n };\n for (const key of PART_KEYS) canonical[key] = recipe[key];\n for (const key of AVATAR_COLORS) canonical[key] = recipe[key].toLowerCase();\n if (recipe.bangs !== undefined) for (const key of DETAIL_KEYS) canonical[key] = recipe[key];\n if (recipe.assetVersion !== 1) {\n canonical['species'] = recipe.species;\n canonical['rightSideHair'] = recipe.rightSideHair;\n for (const key of AVATAR_PIECE_COLORS)\n if (recipe[key] !== undefined) canonical[key] = recipe[key].toLowerCase();\n for (const key of Object.keys(AVATAR_EXTRA_PARTS) as AvatarExtraPart[])\n if (recipe[key] !== undefined) canonical[key] = recipe[key];\n if (recipe.assetVersion === 3) canonical['headpiece'] = canonicalCustomPart(recipe.headpiece);\n }\n return canonical as PixelAvatarRecipe;\n}\n\nconst HAIR_PIECES = ['bangs', 'sideHair', 'rightSideHair', 'backHair'] as const;\n\n/**\n * Saved choices the recipe keeps but does not draw: a flower shows petals and a stem instead of\n * hair, outfit, beard and headwear, and a helmet or hood covers the hair. The choices return when\n * the species or headwear changes back.\n */\nexport function hiddenChoices(recipe: PixelAvatarRecipe): readonly string[] {\n if (recipe.species === 'flower')\n return [\n ...HAIR_PIECES,\n 'outfit',\n 'accessory',\n 'eyes',\n 'brows',\n 'nose',\n 'cheeks',\n 'glasses',\n ...(recipe.beard ? ['beard'] : []),\n ];\n const hidden: string[] = [];\n if (recipe.accessory === 'helmet' || recipe.accessory === 'hood') hidden.push(...HAIR_PIECES);\n if (recipe.species === 'dwarf') hidden.push('nose');\n return hidden;\n}\n\n/**\n * Returns the recipe as asset version 2 with the given species, keeping every other choice.\n * Side hair splits into left (`sideHair`) and right (`rightSideHair`) pieces that start equal.\n * When the skin color is one of the previous species' suggested colors, it moves to the new\n * species' first suggestion; a custom color is kept.\n */\nexport function withSpecies(\n recipe: PixelAvatarRecipeV3,\n species: AvatarSpecies,\n): PixelAvatarRecipeV3;\nexport function withSpecies(\n recipe: PixelAvatarRecipeV1 | PixelAvatarRecipeV2,\n species: AvatarSpecies,\n): PixelAvatarRecipeV2;\nexport function withSpecies(\n recipe: PixelAvatarRecipe,\n species: AvatarSpecies,\n): PixelAvatarRecipeV2 | PixelAvatarRecipeV3;\nexport function withSpecies(\n recipe: PixelAvatarRecipe,\n species: AvatarSpecies,\n): PixelAvatarRecipeV2 | PixelAvatarRecipeV3 {\n const detailed = detailedRecipe(recipe);\n const previous = recipe.species ?? 'human';\n const suggested = AVATAR_SPECIES_SWATCHES[previous].includes(recipe.skinColor.toLowerCase());\n return {\n ...detailed,\n assetVersion: recipe.assetVersion === 3 ? 3 : 2,\n species,\n rightSideHair: detailed.rightSideHair ?? detailed.sideHair!,\n skinColor:\n suggested && previous !== species ? AVATAR_SPECIES_SWATCHES[species][0]! : recipe.skinColor,\n } as PixelAvatarRecipeV2 | PixelAvatarRecipeV3;\n}\n\n/**\n * Returns the recipe wearing a Custom Part in the headpiece slot (asset version 3), or without\n * one (asset version 2). The recipe embeds its own copy of the part.\n */\nexport function withHeadpiece(\n recipe: PixelAvatarRecipe,\n part: PixelCustomPart | undefined,\n): PixelAvatarRecipeV2 | PixelAvatarRecipeV3 {\n const base = recipe.assetVersion === 1 ? withSpecies(recipe, 'human') : recipe;\n const { headpiece: _, ...rest } = base;\n if (part === undefined) return { ...rest, assetVersion: 2 } as PixelAvatarRecipeV2;\n return {\n ...rest,\n assetVersion: 3,\n headpiece: canonicalCustomPart(part),\n } as PixelAvatarRecipeV3;\n}\n\nexport function detailedRecipe(recipe: PixelAvatarRecipe): PixelAvatarRecipe {\n if (recipe.bangs !== undefined) return recipe;\n const pick = <P extends AvatarHairPart>(part: P) =>\n (AVATAR_HAIR_PARTS[part] as readonly string[]).includes(recipe.hair)\n ? (recipe.hair as (typeof AVATAR_HAIR_PARTS)[P][number])\n : HAIR_SPLIT[recipe.hair][part];\n return {\n ...recipe,\n bangs: pick('bangs'),\n sideHair: pick('sideHair'),\n backHair: pick('backHair'),\n spacing: 0,\n height: 0,\n hairLength: 0,\n };\n}\n\nexport const AVATAR_SWATCHES: Record<AvatarColor, readonly string[]> = {\n skinColor: [\n '#ffe3cf',\n '#f2c9a8',\n '#e0a87e',\n '#c68863',\n '#9a6142',\n '#6e4129',\n '#4a2c1c',\n '#f4f1ec',\n ],\n hairColor: [\n '#1d1b22',\n '#5a3a2a',\n '#8a5a36',\n '#e2b04a',\n '#c4452f',\n '#d9475a',\n '#f06292',\n '#3fc1b8',\n '#5a7be0',\n '#9aa3ad',\n '#f4f1ec',\n ],\n eyeColor: [\n '#3f7fbf',\n '#5a3a2a',\n '#2f9e8f',\n '#4c8a3c',\n '#8a5ad0',\n '#d0533f',\n '#d9a13a',\n '#2a2230',\n ],\n shirtColor: [\n '#5b8bd6',\n '#e07a5f',\n '#3d9970',\n '#7a5cc7',\n '#f2c14e',\n '#2f3a4a',\n '#e2565f',\n '#9ad0c2',\n ],\n};\n\nconst SEEDED_CHOICES: { [P in AvatarPart]: readonly (typeof AVATAR_PARTS)[P][number][] } = {\n head: ['round', 'oval', 'square', 'long', 'heart', 'vchin', 'chubby', 'diamond'],\n pose: ['front'],\n hair: AVATAR_PARTS.hair.filter((hair) => hair !== 'none'),\n eyes: ['round', 'round', 'sparkle', 'lashes', 'dot', 'happy', 'sharp'],\n brows: ['soft', 'soft', 'thick', 'raised'],\n nose: ['button', 'dot', 'none'],\n mouth: ['smile', 'smile', 'grin', 'open', 'cat'],\n cheeks: ['blush', 'blush', 'freckles', 'none'],\n glasses: ['none', 'none', 'none', 'none', 'round', 'square'],\n accessory: [\n 'none',\n 'none',\n 'none',\n 'flower',\n 'bow',\n 'hairclip',\n 'catears',\n 'headphones',\n 'beanie',\n 'cap',\n ],\n outfit: AVATAR_PARTS.outfit,\n backdrop: ['sparkles', 'hearts', 'stars', 'dots'],\n};\n\n/**\n * Returns a name-seeded recipe factory. Different namespaces give different faces for the same\n * name; the factory takes the name only, so it is safe to pass straight to `Array.map`.\n */\nexport function createSeededRecipe(namespace: string): (seed: string) => PixelAvatarRecipe {\n return (seed) => {\n const random = seededRandom(`${namespace}:${seed.trim().toLowerCase()}`);\n const pick = <T>(values: readonly T[]) => values[Math.floor(random() * values.length)]!;\n const recipe: Record<string, unknown> = {\n schemaVersion: 1,\n family: 'illustrated',\n assetVersion: 1,\n rigVersion: 1,\n };\n for (const part of Object.keys(AVATAR_PARTS) as AvatarPart[])\n recipe[part] = pick(SEEDED_CHOICES[part]);\n for (const color of AVATAR_COLORS) recipe[color] = pick(AVATAR_SWATCHES[color].slice(0, 7));\n return recipe as PixelAvatarRecipe;\n };\n}\n\n/**\n * A version 2 name-seeded recipe factory over every species. Species are equally likely; a\n * person may get a beard or a version 2 outfit, and a flower gets petals and a base. Version 1\n * factories (`createSeededRecipe`) keep their faces, so a consumer chooses per identity which\n * seed version it was created with.\n */\nexport function createSeededRecipeV2(namespace: string): (seed: string) => PixelAvatarRecipeV2 {\n const base = createSeededRecipe(`${namespace}:base`);\n return (seed) => {\n const random = seededRandom(`${namespace}:${seed.trim().toLowerCase()}`);\n const pick = <T>(values: readonly T[]) => values[Math.floor(random() * values.length)]!;\n const species = pick(AVATAR_SPECIES);\n const recipe: PixelAvatarRecipeV2 = {\n ...withSpecies(base(seed) as PixelAvatarRecipeV1, species),\n skinColor: pick(AVATAR_SPECIES_SWATCHES[species]),\n };\n if (species === 'flower')\n return {\n ...recipe,\n petals: pick(AVATAR_EXTRA_PARTS.petals),\n flowerBase: pick(AVATAR_EXTRA_PARTS.flowerBase),\n };\n const beard = random() < 0.3 ? pick(AVATAR_EXTRA_PARTS.beard) : undefined;\n const outfit = random() < 0.25 ? pick(AVATAR_PARTS_V2.outfit.slice(-4)) : recipe.outfit;\n return { ...recipe, outfit, ...(beard ? { beard } : {}) };\n };\n}\n\n/** Version 2 counterpart of `seededRecipe` (BotHarness's namespace). */\nexport const seededRecipeV2: (seed: string) => PixelAvatarRecipeV2 =\n createSeededRecipeV2('botharness-avatar-v2');\n\n/** The same name always gives the same face (BotHarness's namespace). */\nexport const seededRecipe: (seed: string) => PixelAvatarRecipe =\n createSeededRecipe('botharness-avatar');\n\n/** Suggested body colors per species; any color remains allowed. */\nexport const AVATAR_SPECIES_SWATCHES: Record<AvatarSpecies, readonly string[]> = {\n human: AVATAR_SWATCHES.skinColor,\n goblin: ['#9cc464', '#7fae4f', '#6a9a45', '#b3cf7a', '#5c8a4a', '#8fa86a'],\n elf: ['#fbe7d6', '#f2d3c0', '#e2c9b0', '#d9c7e8', '#b9c6dd', '#8f7fa8'],\n dwarf: ['#f2c4a0', '#e9b08a', '#e0a87e', '#c68863', '#f0b8a0', '#9a6142'],\n orc: ['#8a9a5b', '#6f8a4e', '#7d8c6a', '#5f6f4a', '#9aa070', '#6a7a7a'],\n flower: ['#f6d36b', '#f2b84b', '#ffe3cf', '#e8a85a', '#c98b4a', '#f4f1ec'],\n};\n\nconst preset = (parts: Partial<PixelAvatarRecipeV1>): PixelAvatarRecipeV1 => ({\n ...DEFAULT_RECIPE,\n ...parts,\n});\n\nexport const AVATAR_PRESETS: readonly PixelAvatarRecipe[] = [\n preset({\n hair: 'wavy',\n eyes: 'lashes',\n accessory: 'beret',\n outfit: 'dress',\n skinColor: '#ffe3cf',\n hairColor: '#e2b04a',\n eyeColor: '#3f7fbf',\n shirtColor: '#e2565f',\n backdrop: 'stars',\n }),\n preset({\n hair: 'braids',\n accessory: 'flowercrown',\n outfit: 'cardigan',\n skinColor: '#ffe3cf',\n hairColor: '#8a5a36',\n eyeColor: '#4c8a3c',\n shirtColor: '#9ad0c2',\n backdrop: 'hearts',\n }),\n preset({\n hair: 'twintails',\n eyes: 'sparkle',\n accessory: 'ribbon',\n outfit: 'maid',\n skinColor: '#ffe3cf',\n hairColor: '#3fc1b8',\n eyeColor: '#2f9e8f',\n shirtColor: '#e2565f',\n backdrop: 'stars',\n }),\n preset({\n hair: 'long',\n accessory: 'horseears',\n outfit: 'jacket',\n skinColor: '#ffe3cf',\n hairColor: '#8a5a36',\n eyeColor: '#d0533f',\n shirtColor: '#5b8bd6',\n backdrop: 'dots',\n }),\n preset({\n hair: 'hime',\n eyes: 'sleepy',\n accessory: 'pins',\n outfit: 'kimono',\n skinColor: '#f4f1ec',\n hairColor: '#1d1b22',\n eyeColor: '#d0533f',\n shirtColor: '#7a5cc7',\n backdrop: 'none',\n }),\n preset({\n hair: 'ahoge',\n accessory: 'headband',\n outfit: 'sailor',\n skinColor: '#ffe3cf',\n hairColor: '#f06292',\n eyeColor: '#2f9e8f',\n shirtColor: '#f4f1ec',\n backdrop: 'hearts',\n }),\n preset({\n hair: 'wolf',\n eyes: 'sharp',\n outfit: 'jacket',\n skinColor: '#e0a87e',\n hairColor: '#9aa3ad',\n eyeColor: '#5a7be0',\n shirtColor: '#2f3a4a',\n backdrop: 'stars',\n }),\n preset({\n hair: 'wavy',\n eyes: 'sparkle',\n accessory: 'witch',\n outfit: 'dress',\n skinColor: '#ffe3cf',\n hairColor: '#8a5ad0',\n eyeColor: '#d9a13a',\n shirtColor: '#2f3a4a',\n backdrop: 'sparkles',\n }),\n preset({\n hair: 'bob',\n eyes: 'happy',\n accessory: 'bunnyears',\n outfit: 'cardigan',\n skinColor: '#ffe3cf',\n hairColor: '#f4f1ec',\n eyeColor: '#d9475a',\n shirtColor: '#f2c14e',\n backdrop: 'hearts',\n }),\n preset({\n hair: 'spiky',\n glasses: 'round',\n accessory: 'headphones',\n outfit: 'hoodie',\n backdrop: 'dots',\n }),\n preset({\n hair: 'odango',\n eyes: 'lashes',\n accessory: 'bow',\n outfit: 'kimono',\n hairColor: '#e2b04a',\n shirtColor: '#5b8bd6',\n backdrop: 'sparkles',\n }),\n preset({\n hair: 'crop',\n accessory: 'cap',\n outfit: 'shirttie',\n skinColor: '#9a6142',\n hairColor: '#1d1b22',\n shirtColor: '#3d9970',\n backdrop: 'dots',\n }),\n];\n","import { escapeAttribute, type PixelCell } from '@botharness/pixel-morph';\nimport type { PartCell, PartTone } from './part.js';\nimport { AVATAR_PIECE_COLORS, type PixelAvatarRecipe } from './recipe.js';\n\ntype Cell = string | undefined;\ntype Grid = Cell[][];\ntype Mask = (x: number, y: number) => boolean;\ntype Point = readonly [number, number];\n\nconst N = 32;\nconst C = 16;\nconst INK = '#2a2230';\nconst WHITE = '#ffffff';\nconst BLUSH = '#f4879a';\nconst MOUTH = '#7a2a38';\nconst MOUTH_INSIDE = '#b8415a';\nconst TONGUE = '#ef6f84';\nconst GOLD = '#efb93f';\nconst TUSK = '#f6f0d8';\n\nexport type PixelGrid = Grid;\nexport type PixelMouthState = 'saved' | 'closed' | 'half-open' | 'open';\nexport interface PixelFigureOptions {\n mouthLayers?: boolean;\n}\nconst blank = (): Grid => Array.from({ length: N }, () => Array<Cell>(N).fill(undefined));\nconst ellipse =\n (cx: number, cy: number, rx: number, ry: number): Mask =>\n (x, y) =>\n ((x + 0.5 - cx) / rx) ** 2 + ((y + 0.5 - cy) / ry) ** 2 <= 1;\n\nfunction channels(color: string): number[] {\n const n = Number.parseInt(color.slice(1), 16);\n return [16, 8, 0].map((bit) => (n >> bit) & 255);\n}\nfunction hex(values: number[]): string {\n return `#${values\n .map((v) =>\n Math.min(255, Math.max(0, Math.round(v)))\n .toString(16)\n .padStart(2, '0'),\n )\n .join('')}`;\n}\nconst shade = (color: string, k: number) => hex(channels(color).map((v) => v * k));\nconst mix = (base: string, tint: string, k: number) => {\n const t = channels(tint);\n return hex(channels(base).map((v, i) => v * (1 - k) + t[i]! * k));\n};\nconst TONES: Record<PartTone, (color: string) => string> = {\n [-2]: (c) => shade(c, 0.62),\n [-1]: (c) => shade(c, 0.8),\n 0: (c) => c,\n 1: (c) => mix(c, WHITE, 0.25),\n 2: (c) => mix(c, WHITE, 0.5),\n};\n/** The color a Custom Part cell shows at a tone step on the rig's shade ramp. */\nexport function partToneColor(color: string, tone: PartTone): string {\n return TONES[tone](color.toLowerCase());\n}\nfunction paint(grid: Grid, test: Mask, color: string): void {\n for (let y = 0; y < N; y++) for (let x = 0; x < N; x++) if (test(x, y)) grid[y]![x] = color;\n}\nfunction sprite(\n grid: Grid,\n rows: readonly string[],\n ox: number,\n oy: number,\n pal: Record<string, string>,\n flip = false,\n): void {\n rows.forEach((row, y) =>\n [...row].forEach((code, i) => {\n const c = pal[code];\n const x = ox + (flip ? row.length - 1 - i : i);\n if (c && x >= 0 && x < N && oy + y >= 0 && oy + y < N) grid[oy + y]![x] = c;\n }),\n );\n}\nfunction outline(grid: Grid): Grid {\n const out = grid.map((row) => [...row]);\n for (let y = 0; y < N; y++)\n for (let x = 0; x < N; x++) {\n if (grid[y]![x]) continue;\n const n = [grid[y]?.[x - 1], grid[y]?.[x + 1], grid[y - 1]?.[x], grid[y + 1]?.[x]].find(\n Boolean,\n );\n if (n) out[y]![x] = mix(shade(n, 0.3), INK, 0.62);\n }\n return out;\n}\nconst R = 6;\nconst inTile: Mask = (x, y) => {\n const clamp = (v: number) => Math.min(Math.max(v, R), N - R);\n return (x + 0.5 - clamp(x + 0.5)) ** 2 + (y + 0.5 - clamp(y + 0.5)) ** 2 <= R * R;\n};\nconst clip = (g: Grid): Grid =>\n g.map((row, y) => row.map((c, x) => (inTile(x, y) ? c : undefined)));\nfunction rects(grid: Grid): string {\n let m = '';\n for (let y = 0; y < N; y++) {\n let x = 0;\n while (x < N) {\n const c = grid[y]![x];\n if (!c) {\n x++;\n continue;\n }\n let w = 1;\n while (x + w < N && grid[y]![x + w] === c) w++;\n m += `<rect x=\"${x}\" y=\"${y}\" width=\"${w}\" height=\"1\" fill=\"${escapeAttribute(c)}\"/>`;\n x += w;\n }\n }\n return m;\n}\n\ntype Recipe = PixelAvatarRecipe;\n\nconst FACE: Record<Recipe['head'], (s: number) => Mask> = {\n round: (s) => ellipse(C + s, 16.6, 8.6, 7.6),\n oval: (s) => ellipse(C + s, 16.6, 8, 8),\n chubby: (s) => ellipse(C + s, 17, 9.4, 7.2),\n long: (s) => ellipse(C + s, 16.6, 7.8, 8.4),\n square: (s) => (x, y) => {\n if (y < 8 || y > 23) return false;\n const dx = Math.abs(x + 0.5 - C - s);\n const r = 3;\n if (y <= 20) return dx <= 8.5;\n return dx <= 8.5 - (y - 20) ** 1.3 * 1.1 + 0.3 - (y === 23 ? 1 : 0) || dx <= 8.5 - r;\n },\n heart: (s) => taper(ellipse(C + s, 15.8, 9, 7.4), 16.5, 9, 2.6, 24.4, s),\n vchin: (s) => taper(ellipse(C + s, 15.8, 8.6, 7.4), 17.5, 8.6, 2.2, 24.4, s),\n diamond: (s) =>\n taper(\n (x, y) => y >= 9 && Math.abs(x + 0.5 - C - s) <= 6.4 + (y - 9) * 0.45,\n 15.8,\n 9.2,\n 2.6,\n 24.4,\n s,\n ),\n};\nfunction taper(top: Mask, from: number, width: number, end: number, chin: number, s: number): Mask {\n return (x, y) => {\n const cy = y + 0.5;\n if (cy <= from) return top(x, y);\n if (cy > chin) return false;\n const t = (cy - from) / (chin - from);\n return Math.abs(x + 0.5 - C - s) <= width - (width - end) * t ** 1.5;\n };\n}\n\nconst EYES: Record<Recipe['eyes'], readonly string[]> = {\n round: ['KKKK', 'DWDD', 'IDDI', 'LIIL'],\n dot: ['....', '.KK.', '.KK.', '....'],\n sparkle: ['KKKK', 'DWDW', 'IDDI', 'LIWL'],\n lashes: ['KKKKK', 'K.DWD', '..IDD', '..LII'],\n sleepy: ['....', 'KKKK', 'IDDI', 'LIIL'],\n happy: ['....', '.KK.', 'K..K', '....'],\n wink: ['KKKK', 'DWDD', 'IDDI', 'LIIL'],\n sharp: ['KK..', '.KKK', '.DWD', '..LI'],\n};\nconst CLOSED = ['....', '....', 'KKKK', '....'];\nconst BROWS: Record<Recipe['brows'], readonly string[]> = {\n soft: ['.BBB'],\n thick: ['BBBB'],\n raised: ['.BB.'],\n angry: ['BB..', '..BB'],\n worried: ['..BB', 'BB..'],\n none: [],\n};\nconst MOUTHS: Record<Recipe['mouth'], readonly string[]> = {\n smile: ['K..K', '.KK.'],\n grin: ['KWWK', '.KK.'],\n open: ['KKK', 'MTM'],\n flat: ['.KK.'],\n smirk: ['...K', '.KK.'],\n cat: ['K.K.K', '.K.K.'],\n tongue: ['KKKK', '.TT.'],\n o: ['.K.', 'KMK', '.K.'],\n};\n\nfunction hair(\n recipe: Recipe,\n s: number,\n b: number,\n): { back: Mask; front: Mask; ties?: Point[]; bands?: boolean } {\n const none: Mask = () => false;\n const cap = ellipse(C + s, 14, 11, 10.6);\n const tip = (x: number, depth = 1) => [0, depth, depth + 1, depth][(x + 40 - s) % 4]!;\n const bangs =\n (line: number, depth = 1, sides = 22): Mask =>\n (x, y) => {\n if (!cap(x, Math.min(y, 13))) return false;\n const dx = x + 0.5 - C - s;\n if (Math.abs(dx) >= 7) return y <= sides - [0, 1, 0, 2][(x + 40 - s) % 4]!;\n return y <= line + tip(x, depth) - (Math.abs(dx) > 6 ? 0 : 0);\n };\n const longBack =\n (bottom: number, width = 11.4): Mask =>\n (x, y) =>\n (ellipse(C + b, 14, width + 0.4, 11)(x, y) && y <= 16) ||\n (y > 15 && y <= bottom && Math.abs(x + 0.5 - C - b) <= width - (y > bottom - 2 ? 1 : 0));\n switch (recipe.hair) {\n case 'none':\n return { back: none, front: none };\n case 'buzz':\n return { back: none, front: (x, y) => cap(x, y) && y <= 7 };\n case 'crop':\n return { back: none, front: bangs(10, 1, 15) };\n case 'sweep':\n return {\n back: none,\n front: (x, y) =>\n cap(x, Math.min(y, 13)) &&\n (y <= 9 + Math.max(0, (x - 6 - s) * 0.45) || (Math.abs(x + 0.5 - C - s) >= 7 && y <= 16)),\n };\n case 'spiky':\n return {\n back: none,\n front: (x, y) =>\n cap(x, Math.max(y, 6)) &&\n y >= [1, 3, 5, 3][(x + 40 - s) % 4]! &&\n bangs(11, 2, 15)(x, Math.max(y, 6)),\n };\n case 'curly': {\n const bumps: Point[] = Array.from({ length: 9 }, (_, i) => {\n const a = Math.PI * (1.02 + (i * 0.96) / 8);\n return [C + s + 11.5 * Math.cos(a), 14 + 11 * Math.sin(a)] as Point;\n });\n return {\n back: none,\n front: (x, y) =>\n bangs(11, 1, 18)(x, y) ||\n (y <= 18 && bumps.some(([bx, by]) => (x + 0.5 - bx) ** 2 + (y + 0.5 - by) ** 2 <= 6.5)),\n };\n }\n case 'mohawk':\n return { back: none, front: (x, y) => Math.abs(x + 0.5 - C - s) <= 2 && y >= 1 && y <= 9 };\n case 'bob':\n return { back: longBack(25), front: bangs(13, 1, 24) };\n case 'long':\n return { back: longBack(31), front: bangs(13, 1, 26) };\n case 'bun':\n return {\n back: none,\n front: (x, y) => bangs(12, 1, 18)(x, y) || ellipse(C + s, 2.6, 4, 2.6)(x, y),\n };\n case 'pigtails':\n return {\n back: (x, y) =>\n ellipse(C + s - 11.5, 21, 3, 4.4)(x, y) || ellipse(C + s + 11.5, 21, 3, 4.4)(x, y),\n front: bangs(13, 1, 21),\n ties: [\n [C + s - 12, 16],\n [C + s + 11, 16],\n ],\n };\n case 'afro':\n return { back: ellipse(C + b, 12, 15, 11.5), front: (x, y) => cap(x, y) && y <= 8 };\n case 'twintails':\n case 'drills':\n return {\n back: (x, y) =>\n y >= 8 &&\n (ellipse(C + s - 13.2, 20, 2.3, 12)(x, y) || ellipse(C + s + 13.2, 20, 2.3, 12)(x, y)),\n front: bangs(13, 1, 24),\n ties: [\n [C + s - 13, 9],\n [C + s - 12, 9],\n [C + s + 11, 9],\n [C + s + 12, 9],\n ],\n bands: recipe.hair === 'drills',\n };\n case 'ponytail':\n return {\n back: (x, y) => ellipse(C + s + 11.5, 19, 3, 9)(x, y) && y >= 8,\n front: bangs(12, 1, 20),\n ties: [\n [C + s + 10, 9],\n [C + s + 11, 9],\n ],\n };\n case 'sidetail':\n return {\n back: (x, y) => ellipse(C + s - 11.5, 21, 3, 8)(x, y) && y >= 12,\n front: (x, y) =>\n cap(x, Math.min(y, 13)) &&\n (y <= 9 + Math.max(0, (C + s - x) * 0.45) || (Math.abs(x + 0.5 - C - s) >= 7 && y <= 18)),\n ties: [\n [C + s - 13, 13],\n [C + s - 12, 13],\n ],\n };\n case 'hime':\n return {\n back: longBack(31),\n front: (x, y) =>\n cap(x, Math.min(y, 13)) && (y <= 12 || (Math.abs(x + 0.5 - C - s) >= 6.5 && y <= 24)),\n };\n case 'odango':\n return {\n back: none,\n front: (x, y) =>\n bangs(12, 1, 18)(x, y) ||\n ellipse(C + s - 8, 3.5, 3.3, 3)(x, y) ||\n ellipse(C + s + 8, 3.5, 3.3, 3)(x, y),\n };\n case 'messy':\n return {\n back: none,\n front: (x, y) =>\n cap(x, Math.max(y, 4)) &&\n y >= [2, 0, 3, 1, 2][(x + 50 - s) % 5]! &&\n bangs(11, 2, 17)(x, Math.max(y, 4)),\n };\n case 'wavy':\n return {\n back: (x, y) =>\n longBack(30)(x, y) ||\n (y >= 16 && y <= 30 && Math.abs(x + 0.5 - C - b) <= 12.4 + Math.sin(y * 0.9) * 0.9),\n front: bangs(12, 2, 25),\n };\n case 'braids':\n return {\n back: none,\n front: (x, y) =>\n bangs(13, 1, 20)(x, y) ||\n [C + s - 9.5, C + s + 9.5].some(\n (bx) =>\n y >= 20 && y <= 30 && Math.abs(x + 0.5 - bx) <= 1.6 - ((y + 1) % 3 === 0 ? 0.6 : 0),\n ),\n ties: [\n [C + s - 10, 30],\n [C + s + 9, 30],\n ],\n };\n case 'wolf':\n return {\n back: (x, y) => longBack(24, 11.8)(x, y) && (y < 20 || (x + y) % 3 !== 0),\n front: (x, y) =>\n cap(x, Math.max(y, 5)) &&\n y >= [1, 2, 0, 2][(x + 40 - s) % 4]! &&\n bangs(12, 2, 21)(x, Math.max(y, 5)),\n };\n case 'ahoge':\n return {\n back: longBack(23),\n front: (x, y) =>\n bangs(13, 1, 22)(x, y) ||\n [\n [0, 0],\n [1, 0],\n [1, 1],\n [2, 1],\n [2, 2],\n [1, 2],\n ].some(([ax, ay]) => x === Math.round(C + s) + ax! && y === ay! + 1),\n };\n }\n}\n\nfunction detailedHair(\n recipe: Recipe,\n s: number,\n b: number,\n): { back: Mask; front: Mask; ties?: Point[]; bands?: boolean; sides?: [Mask, Mask] } {\n const of = (style: Recipe['hair'] | undefined) =>\n hair({ ...recipe, hair: style ?? 'none' }, s, b);\n const bangs = of(recipe.bangs);\n const side = of(recipe.sideHair);\n const right = recipe.rightSideHair === undefined ? side : of(recipe.rightSideHair);\n const back = of(recipe.backHair);\n const length = (recipe.hairLength ?? 0) * 2;\n const lengthen =\n (mask: Mask): Mask =>\n (x, y) =>\n mask(x, y > 18 ? Math.round(y - length) : y);\n // Side pieces cover |dx| >= 7 below the crown; with a right piece, each side has its own.\n const sideOf =\n (sign: -1 | 1): Mask =>\n (x, y) =>\n y > 7 && sign * (x + 0.5 - C - s) >= 7 && lengthen((sign < 0 ? side : right).front)(x, y);\n return {\n front: (x, y) =>\n y <= 7\n ? bangs.front(x, y) || back.front(x, y)\n : Math.abs(x + 0.5 - C - s) < 7\n ? bangs.front(x, y)\n : lengthen((x + 0.5 - C - s < 0 ? side : right).front)(x, y),\n sides: [sideOf(-1), sideOf(1)],\n back: length === 0 ? back.back : lengthen(back.back),\n ...(back.ties ? { ties: back.ties } : {}),\n ...(back.bands ? { bands: back.bands } : {}),\n };\n}\n\nfunction outfit(recipe: Recipe, g: Grid, s: number): void {\n const shirt = recipe.shirtColor;\n const skin = recipe.skinColor;\n const dark = shade(shirt, 0.75);\n const light = mix(shirt, WHITE, 0.8);\n const half = (y: number) => 6.5 + (y - 24) * 1.15;\n const torso: Mask = (x, y) => y >= 24 && Math.abs(x + 0.5 - C - s * 0.5) <= half(y);\n const dx = (x: number) => x + 0.5 - C - s * 0.5;\n paint(g, (x, y) => y >= 22 && y <= 25 && Math.abs(dx(x)) <= 2.5, shade(skin, 0.85));\n paint(g, torso, shirt);\n const v =\n (depth: number, w: number): Mask =>\n (x, y) =>\n y >= 24 && y <= 24 + depth && Math.abs(dx(x)) <= w - (y - 24) * (w / (depth + 1));\n switch (recipe.outfit) {\n case 'tee':\n paint(g, v(1, 2.5), shade(skin, 0.85));\n break;\n case 'shirttie':\n paint(g, v(3, 4), light);\n paint(g, (x, y) => y >= 24 && Math.abs(dx(x)) <= 0.5 && y <= 28, '#d22a5a');\n break;\n case 'hoodie':\n paint(g, (x, y) => torso(x, y) && y === 24 && Math.abs(dx(x)) >= 3, dark);\n paint(\n g,\n (x, y) =>\n y >= 25 && y <= 27 && (Math.abs(dx(x) + 1.5) <= 0.5 || Math.abs(dx(x) - 1.5) <= 0.5),\n WHITE,\n );\n break;\n case 'turtleneck':\n paint(g, (x, y) => y >= 22 && y <= 25 && Math.abs(dx(x)) <= 3, shade(shirt, 0.88));\n break;\n case 'sailor':\n paint(g, (x, y) => torso(x, y) && y <= 26 && Math.abs(dx(x)) >= 2, '#2f3a5a');\n paint(g, (x, y) => torso(x, y) && y === 26 && Math.abs(dx(x)) >= 3, WHITE);\n sprite(g, ['R.R', '.R.'], Math.round(C + s * 0.5) - 2, 26, { R: '#e2565f' });\n break;\n case 'blazer':\n paint(g, v(4, 4), light);\n paint(\n g,\n (x, y) => torso(x, y) && y >= 24 && Math.abs(Math.abs(dx(x)) - (4 - (y - 24) * 0.8)) <= 0.5,\n dark,\n );\n sprite(g, ['G'], Math.round(C + s * 0.5), 28, { G: GOLD });\n break;\n case 'overalls':\n paint(g, torso, light);\n paint(g, (x, y) => torso(x, y) && (y >= 27 || Math.abs(Math.abs(dx(x)) - 4) <= 0.6), shirt);\n sprite(g, ['G....G'], Math.round(C + s * 0.5) - 3, 27, { G: GOLD });\n break;\n case 'dress':\n paint(g, (x, y) => torso(x, y) && y <= 25 && Math.abs(dx(x)) <= 4.5, WHITE);\n paint(\n g,\n (x, y) => torso(x, y) && y === 25 && Math.abs(dx(x)) <= 4.5 && x % 2 === 0,\n shade(WHITE, 0.86),\n );\n sprite(g, ['RR.RR', '.RRR.', 'R...R'], Math.round(C + s * 0.5) - 2, 25, { R: '#e5566a' });\n paint(g, (x, y) => torso(x, y) && y === 29, mix(shirt, WHITE, 0.5));\n break;\n case 'kimono':\n paint(\n g,\n (x, y) => torso(x, y) && y <= 28 && Math.abs(Math.abs(dx(x)) - (y - 23.5)) <= 0.6,\n WHITE,\n );\n paint(g, (x, y) => torso(x, y) && y >= 28, '#e2565f');\n paint(g, (x, y) => torso(x, y) && y === 28 && x % 3 === 0, GOLD);\n paint(\n g,\n (x, y) => torso(x, y) && y <= 27 && (x * 3 + y * 2) % 7 === 0,\n mix(shirt, WHITE, 0.45),\n );\n break;\n case 'cardigan':\n paint(g, v(5, 3.5), light);\n paint(g, (x, y) => torso(x, y) && Math.abs(Math.abs(dx(x)) - 2) <= 0.5 && y >= 25, dark);\n sprite(g, ['W', '.', 'W', '.', 'W'], Math.round(C + s * 0.5) - 3, 25, { W: WHITE });\n paint(g, (x, y) => torso(x, y) && y === 29, dark);\n break;\n case 'maid':\n paint(g, (x, y) => torso(x, y), '#2f2a3a');\n paint(g, (x, y) => torso(x, y) && y >= 25 && Math.abs(dx(x)) <= 4 - (y - 25) * 0.2, WHITE);\n paint(g, (x, y) => y === 24 && Math.abs(dx(x)) <= 4.5, WHITE);\n sprite(g, ['RR.RR', '.RRR.'], Math.round(C + s * 0.5) - 2, 24, { R: shirt });\n break;\n case 'armor': {\n const metal = '#9aa3ad';\n paint(g, torso, metal);\n paint(g, (x, y) => torso(x, y) && y >= 26 && Math.abs(dx(x)) <= 2.5, shirt);\n paint(\n g,\n (x, y) => torso(x, y) && y <= 26 && Math.abs(dx(x)) >= half(y) - 3.5,\n mix(metal, WHITE, 0.35),\n );\n paint(\n g,\n (x, y) => torso(x, y) && y === 27 && Math.abs(dx(x)) >= half(y) - 3.5,\n shade(metal, 0.7),\n );\n paint(g, (x, y) => y === 24 && Math.abs(dx(x)) <= 3.5, shade(metal, 0.8));\n sprite(g, ['G'], Math.round(C + s * 0.5), 28, { G: GOLD });\n break;\n }\n case 'robe':\n paint(g, v(5, 4), mix(shirt, WHITE, 0.7));\n paint(\n g,\n (x, y) => torso(x, y) && y <= 29 && Math.abs(Math.abs(dx(x)) - (4 - (y - 24) * 0.8)) <= 0.5,\n GOLD,\n );\n paint(g, (x, y) => torso(x, y) && y >= 28 && Math.abs(dx(x)) >= half(y) - 1.5, dark);\n break;\n case 'tunic':\n paint(g, v(2, 2), shade(skin, 0.85));\n sprite(g, ['L.L', '.L.'], Math.round(C + s * 0.5) - 1, 25, { L: '#6b4a2b' });\n paint(g, (x, y) => torso(x, y) && y === 29, '#6b4a2b');\n sprite(g, ['G'], Math.round(C + s * 0.5), 29, { G: GOLD });\n break;\n case 'cloak': {\n const cloak = mix(shirt, '#2f3a4a', 0.55);\n paint(g, (x, y) => torso(x, y) && Math.abs(dx(x)) >= 2.5, cloak);\n paint(g, (x, y) => torso(x, y) && y === 24, shade(cloak, 0.8));\n sprite(g, ['G...G'], Math.round(C + s * 0.5) - 2, 25, { G: GOLD });\n break;\n }\n case 'jacket':\n paint(g, v(6, 4.5), WHITE);\n paint(\n g,\n (x, y) => torso(x, y) && Math.abs(Math.abs(dx(x)) - (4.5 - (y - 24) * 0.6)) <= 0.6,\n dark,\n );\n paint(g, (x, y) => torso(x, y) && y >= 27 && Math.abs(dx(x)) <= 0.5, '#9aa3ad');\n paint(\n g,\n (x, y) => torso(x, y) && y === 28 && Math.abs(dx(x)) >= half(y) - 2.5,\n mix(shirt, WHITE, 0.6),\n );\n break;\n }\n const neck = shade(skin, 0.85);\n for (let y = 24; y < N; y++)\n for (let x = 0; x < N; x++) {\n const cell = g[y]![x];\n if (!cell || cell === neck || !torso(x, y)) continue;\n const d = dx(x);\n const edge = half(y) - Math.abs(d);\n if (y === 24 && Math.abs(d) <= 4.5) g[y]![x] = shade(cell, 0.78);\n else if (y >= 26 && edge >= 1.6 && edge < 2.6) g[y]![x] = shade(cell, 0.82);\n else if (d > 0 && edge < 1.6) g[y]![x] = shade(cell, 0.84);\n else if (d < 0 && edge < 1.6 && y <= 26) g[y]![x] = mix(cell, WHITE, 0.28);\n else if (d < -2 && y <= 25) g[y]![x] = mix(cell, WHITE, 0.14);\n }\n}\n\nfunction accessory(recipe: Recipe, g: Grid, s: number, face: Mask): void {\n const shirt = recipe.shirtColor;\n const cap = ellipse(C + s, 14, 11.6, 11.2);\n switch (recipe.accessory) {\n case 'none':\n return;\n case 'beanie':\n paint(g, (x, y) => cap(x, y) && y <= 8, shirt);\n paint(g, (x, y) => cap(x, y) && (y === 8 || y === 9), shade(shirt, 0.78));\n paint(g, ellipse(C + s, 1.6, 2.2, 1.8), WHITE);\n return;\n case 'cap':\n paint(g, (x, y) => cap(x, y) && y <= 8, shirt);\n paint(\n g,\n (x, y) => y === 9 && x + 0.5 >= C + s - 10 && x + 0.5 <= C + s + 13,\n shade(shirt, 0.72),\n );\n return;\n case 'headphones': {\n const band = (x: number, y: number) =>\n ellipse(C + s, 14, 12, 11.6)(x, y) && !ellipse(C + s, 14, 10.8, 10.4)(x, y) && y <= 13;\n paint(g, band, '#5d5b66');\n paint(\n g,\n (x, y) =>\n y >= 12 &&\n y <= 19 &&\n (Math.abs(x + 0.5 - (C + s - 11)) <= 1.6 || Math.abs(x + 0.5 - (C + s + 11)) <= 1.6),\n '#e25d6a',\n );\n return;\n }\n case 'flower':\n sprite(g, ['.P.P.', 'PPYPP', '.PPP.'], Math.round(C + s) + 6, 3, { P: '#f59fba', Y: GOLD });\n return;\n case 'bow':\n sprite(g, ['RR.RR', 'RRrRR', 'RR.RR'], Math.round(C + s) + 6, 3, {\n R: '#e5566a',\n r: '#b83a50',\n });\n return;\n case 'earring': {\n const xs = [...Array(N).keys()].filter((x) => face(x, 19));\n if (xs.length) {\n sprite(g, ['G', 'G'], xs[0]! - 1, 20, { G: GOLD });\n sprite(g, ['G', 'G'], xs.at(-1)! + 1, 20, { G: GOLD });\n }\n return;\n }\n case 'crown':\n sprite(g, ['G.G.G.G', 'GGGGGGG', 'GrGbGrG'], Math.round(C + s) - 3, 0, {\n G: GOLD,\n r: '#e5566a',\n b: '#5a9be0',\n });\n return;\n case 'halo':\n paint(\n g,\n (x, y) => ellipse(C + s, 1.6, 6.5, 1.8)(x, y) && !ellipse(C + s, 1.6, 4.4, 0.8)(x, y),\n GOLD,\n );\n return;\n case 'catears': {\n const ear = ['X...', 'XX..', 'XPX.', 'XXXX'];\n sprite(g, ear, Math.round(C + s) - 9, 2, { X: recipe.hairColor, P: '#f4a3b5' });\n sprite(g, ear, Math.round(C + s) + 5, 2, { X: recipe.hairColor, P: '#f4a3b5' }, true);\n return;\n }\n case 'hairclip':\n sprite(g, ['CC.CC', '.CCC.'], Math.round(C + s) + 3, 9, { C: '#e5566a' });\n return;\n case 'horns': {\n const horn = ['.H', 'HH', 'Hh'];\n sprite(g, horn, Math.round(C + s) - 8, 1, { H: '#5b3a6e', h: '#7d5694' });\n sprite(g, horn, Math.round(C + s) + 6, 1, { H: '#5b3a6e', h: '#7d5694' }, true);\n return;\n }\n case 'helmet': {\n const metal = '#9aa3ad';\n paint(g, (x, y) => cap(x, y) && y <= 11, metal);\n paint(g, (x, y) => cap(x, y) && y === 11, shade(metal, 0.75));\n paint(\n g,\n (x, y) => cap(x, y) && y >= 12 && y <= 19 && Math.abs(x + 0.5 - C - s) >= 7.5,\n metal,\n );\n paint(g, (x, y) => Math.abs(x + 0.5 - C - s) <= 0.5 && y >= 11 && y <= 16, shade(metal, 0.7));\n paint(\n g,\n (x, y) => cap(x, y) && y >= 2 && y <= 5 && x + 0.5 < C + s - 2,\n mix(metal, WHITE, 0.4),\n );\n for (let x = Math.round(C + s) - 9; x <= Math.round(C + s) + 9; x += 3)\n sprite(g, ['G'], x, 10, { G: GOLD });\n return;\n }\n case 'hood': {\n const outer = ellipse(C + s, 15, 12.6, 12.4);\n paint(g, (x, y) => outer(x, y) && y <= 25 && !(face(x, y) && y >= 10), shirt);\n paint(\n g,\n (x, y) =>\n outer(x, y) &&\n !face(x, y) &&\n y >= 9 &&\n (face(x + 1, y) || face(x - 1, y) || face(x, y + 1)),\n shade(shirt, 0.7),\n );\n return;\n }\n case 'beret':\n paint(g, (x, y) => ellipse(C + s + 1.5, 4.6, 10.5, 3.6)(x, y), shirt);\n paint(g, (x, y) => ellipse(C + s + 1.5, 4.6, 10.5, 3.6)(x, y) && y >= 6, shade(shirt, 0.78));\n paint(\n g,\n (x, y) => ellipse(C + s + 1.5, 4.6, 10.5, 3.6)(x, y) && y <= 2 && x + 0.5 < C + s,\n mix(shirt, WHITE, 0.3),\n );\n sprite(g, ['S'], Math.round(C + s) + 1, 0, { S: shade(shirt, 0.6) });\n return;\n case 'ribbon':\n sprite(g, ['RRR.RRR', 'RrRRRrR', 'RRR.RRR', '.R...R.'], Math.round(C + s) - 3, 0, {\n R: '#e5566a',\n r: '#f49aa8',\n });\n return;\n case 'headband':\n paint(\n g,\n (x, y) =>\n ellipse(C + s, 14, 11.2, 10.8)(x, y) && !ellipse(C + s, 14.2, 10.2, 9.8)(x, y) && y <= 8,\n shirt,\n );\n paint(\n g,\n (x, y) =>\n ellipse(C + s, 14, 11.2, 10.8)(x, y) && !ellipse(C + s, 14.2, 10.2, 9.8)(x, y) && y <= 5,\n mix(shirt, WHITE, 0.35),\n );\n return;\n case 'bunnyears': {\n const ear = ['WW', 'WP', 'WP', 'WP', 'WW'];\n sprite(g, ear, Math.round(C + s) - 6, 0, { W: '#f4f1ec', P: '#f4a3b5' });\n sprite(g, ear, Math.round(C + s) + 4, 0, { W: '#f4f1ec', P: '#f4a3b5' }, true);\n return;\n }\n case 'horseears': {\n const ear = ['.X.', 'XPX', 'XPX', 'XXX'];\n sprite(g, ear, Math.round(C + s) - 9, 1, { X: shade(recipe.hairColor, 0.9), P: '#f4a3b5' });\n sprite(g, ear, Math.round(C + s) + 6, 1, { X: shade(recipe.hairColor, 0.9), P: '#f4a3b5' });\n sprite(g, ['BB', 'BB'], Math.round(C + s) + 3, 7, { B: '#5a9be0' });\n return;\n }\n case 'flowercrown':\n for (const [fx, color] of [\n [-8, '#f59fba'],\n [-4, GOLD],\n [0, '#f4f1ec'],\n [4, '#f59fba'],\n [8, GOLD],\n ] as const)\n sprite(\n g,\n ['.F.', 'FCF', '.F.'],\n Math.round(C + s) + fx - 1,\n 4 + Math.round(Math.abs(fx) / 4),\n {\n F: color,\n C: color === GOLD ? '#e2565f' : GOLD,\n },\n );\n paint(\n g,\n (x, y) =>\n y === 6 + Math.round(Math.abs(x + 0.5 - C - s) / 4) &&\n Math.abs(x + 0.5 - C - s) <= 9 &&\n x % 2 === 1,\n '#5aa36b',\n );\n return;\n case 'witch':\n paint(g, (x, y) => y >= 6 && y <= 7 && Math.abs(x + 0.5 - C - s) <= 13, '#3a2f52');\n paint(\n g,\n (x, y) => y <= 6 && Math.abs(x + 0.5 - C - s - (6 - y) * 0.5) <= 1 + y * 0.9,\n '#4b3d6b',\n );\n paint(g, (x, y) => y === 5 && Math.abs(x + 0.5 - C - s - 0.5) <= 5.2, '#efb93f');\n return;\n case 'pins':\n sprite(g, ['Y.Y', '.Y.', 'Y.Y', '...', 'B.B', '.B.', 'B.B'], Math.round(C + s) + 6, 7, {\n Y: GOLD,\n B: '#5a9be0',\n });\n return;\n }\n}\n\nconst POINTED_EARS: Partial<\n Record<NonNullable<Recipe['species']>, { rows: string[]; rise: number }>\n> = {\n goblin: { rows: ['E...', 'EE..', '.EiE', '..Ee'], rise: 2 },\n elf: { rows: ['E....', 'EE...', '.EE..', '..EiE', '...Ee'], rise: 3 },\n orc: { rows: ['E..', 'EE.', '.Ee'], rise: 1 },\n};\n\nconst leafShape =\n (cx: number, cy: number, long: number, wide: number, angle: number): Mask =>\n (x, y) => {\n const px = x + 0.5 - cx;\n const py = y + 0.5 - cy;\n const u = px * Math.cos(angle) + py * Math.sin(angle);\n const v = -px * Math.sin(angle) + py * Math.cos(angle);\n return (u / long) ** 2 + (v / wide) ** 2 <= 1;\n };\n\nfunction petals(style: NonNullable<Recipe['petals']>, s: number): Mask {\n const cx = C + s;\n const cy = 16.6;\n const ring =\n (n: number, radius: number, long: number, wide: number, phase = 0): Mask =>\n (x, y) =>\n Array.from({ length: n }, (_, k) => phase + (2 * Math.PI * k) / n).some((a) =>\n leafShape(cx + radius * Math.cos(a), cy + radius * Math.sin(a), long, wide, a)(x, y),\n );\n switch (style) {\n case 'daisy':\n return ring(14, 10.4, 3.4, 1.7, Math.PI / 14);\n case 'sunflower':\n return (x, y) => ring(16, 11.2, 2.6, 1.5)(x, y) || ellipse(cx, cy, 10.6, 10.2)(x, y);\n case 'tulip':\n return (x, y) =>\n y <= cy + 6 &&\n (ellipse(cx - 6.5, cy - 3, 4.5, 7.5)(x, y) ||\n ellipse(cx + 6.5, cy - 3, 4.5, 7.5)(x, y) ||\n ellipse(cx, cy - 6, 5, 8)(x, y));\n case 'trumpet':\n return (x, y) =>\n ellipse(cx, cy - 0.5, 11.6, 10.4)(x, y) ||\n (y <= cy - 6 && ellipse(cx, cy - 3, 13, 8.6)(x, y));\n case 'sakura':\n return (x, y) =>\n ring(5, 8.6, 4.6, 3.8, -Math.PI / 2)(x, y) && !ring(5, 13.4, 1.4, 1.4, -Math.PI / 2)(x, y);\n }\n}\n\nfunction flowerBase(recipe: Recipe, g: Grid, s: number): void {\n const leaf = '#5f9e4a';\n const stem = C + s * 0.5;\n paint(g, (x, y) => y >= 22 && Math.abs(x + 0.5 - stem) <= 1, shade(leaf, 0.82));\n if (recipe.flowerBase === 'pot') {\n const pot = recipe.shirtColor;\n const body: Mask = (x, y) => y >= 27 && Math.abs(x + 0.5 - stem) <= 6.5 - (y - 27) * 0.45;\n paint(g, leafShape(stem - 3, 25, 2.8, 1.2, -0.5), leaf);\n paint(g, leafShape(stem + 3, 24.5, 2.8, 1.2, 0.5), shade(leaf, 0.9));\n paint(g, body, pot);\n paint(g, (x, y) => body(x, y) && y === 27, mix(pot, WHITE, 0.3));\n paint(g, (x, y) => body(x, y) && y >= 28 && x + 0.5 > stem + 3, shade(pot, 0.8));\n return;\n }\n const left = leafShape(stem - 4.5, 27, 4.4, 1.9, -0.55);\n const right = leafShape(stem + 4.5, 25.5, 4.4, 1.9, 0.55);\n paint(g, left, leaf);\n paint(g, right, shade(leaf, 0.92));\n paint(g, leafShape(stem - 4.5, 27, 3.6, 0.5, -0.55), shade(leaf, 0.75));\n paint(g, leafShape(stem + 4.5, 25.5, 3.6, 0.5, 0.55), shade(leaf, 0.7));\n}\n\nexport function pixelTileColor(hair: string): string {\n const [r, g, b] = channels(hair).map((v) => v / 255) as [number, number, number];\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const lightness = (max + min) / 2;\n const chroma = max - min;\n const saturation = chroma === 0 ? 0 : chroma / (1 - Math.abs(2 * lightness - 1));\n if (saturation < 0.18 || lightness > 0.86 || lightness < 0.16) return '#ece8e1';\n const hue =\n max === r\n ? ((g - b) / chroma + 6) % 6\n : max === g\n ? (b - r) / chroma + 2\n : (r - g) / chroma + 4;\n const s = Math.min(0.55, Math.max(0.35, saturation * 0.6));\n const l = 0.88;\n const f = (n: number) => {\n const k = (n + hue * 2) % 12;\n return l - s * Math.min(l, 1 - l) * Math.max(-1, Math.min(k - 3, 9 - k, 1));\n };\n return hex([f(0), f(8), f(4)].map((v) => v * 255));\n}\n\nexport function pixelFigure(\n recipe: Recipe,\n yawDeg: number,\n options: PixelFigureOptions = {},\n): { tile: string; body: string; head: string; cells: PixelCell[] } {\n const yaw = (yawDeg * Math.PI) / 180;\n const sinY = Math.sin(yaw);\n const s = Math.round(sinY * 3);\n const fs = Math.round(sinY * 10);\n const b = -Math.round(sinY * 3.5);\n const turned = Math.abs(sinY) >= 0.3;\n const d = Math.sign(sinY);\n const skin = recipe.skinColor;\n const hairColor = recipe.hairColor;\n const front = FACE[recipe.head](s * 0.5);\n const face: Mask = turned\n ? (x, y) => {\n const dx = x + 0.5 - C;\n const tuck = y >= 17 && d * dx > 4 ? Math.min(2, (y - 16) * 0.35) : 0;\n return front(x - Math.round(d * (1 + Math.max(0, y - 20) * 0.4) - d * tuck), y);\n }\n : front;\n const flower = recipe.species === 'flower';\n const covered = recipe.accessory === 'helmet' || recipe.accessory === 'hood';\n const bare: Mask = () => false;\n const petalRing = flower ? petals(recipe.petals ?? 'trumpet', s) : bare;\n const masks: ReturnType<typeof detailedHair> = flower\n ? {\n back: petalRing,\n front: bare,\n sides: [\n (x, y) => petalRing(x, y) && x + 0.5 < C + s,\n (x, y) => petalRing(x, y) && x + 0.5 >= C + s,\n ],\n }\n : covered\n ? { back: bare, front: bare }\n : recipe.bangs === undefined\n ? hair(recipe, s, b)\n : detailedHair(recipe, s, b);\n\n const body = blank();\n if (flower) flowerBase(recipe, body, s);\n else outfit(recipe, body, s);\n\n const back = blank();\n if (flower) {\n paint(back, petalRing, hairColor);\n paint(\n back,\n (x, y) => petalRing(x, y) && (x + 0.5 - C - s) ** 2 + (y + 0.5 - 16.6) ** 2 < 90,\n shade(hairColor, 0.84),\n );\n paint(\n back,\n (x, y) => petalRing(x, y) && x + 0.5 < C + s - 3 && y < 10,\n mix(hairColor, WHITE, 0.3),\n );\n } else paint(back, masks.back, shade(hairColor, 0.82));\n if (masks.bands)\n paint(\n back,\n (x, y) => masks.back(x, y) && (y + Math.floor(x / 2)) % 4 === 0,\n shade(hairColor, 0.68),\n );\n\n const headpiece = recipe.assetVersion === 3 ? recipe.headpiece : undefined;\n const placeCells = (grid: Grid, cells: readonly PartCell[]) => {\n const placed = cells.map(([x, y, color, tone]) => {\n const dx = x + 0.5 - C;\n const far = turned && d * dx < 0 && Math.abs(dx) >= 5;\n const base = color.startsWith('#') ? color.toLowerCase() : recipe[color as 'hairColor'];\n return { x: x + s + (far ? d : 0), y, c: TONES[tone](base), far };\n });\n for (const cell of [...placed.filter((p) => p.far), ...placed.filter((p) => !p.far)])\n if (cell.x >= 0 && cell.x < N) grid[cell.y]![cell.x] = cell.c;\n };\n if (headpiece) placeCells(back, headpiece.back);\n\n const head = blank();\n paint(head, face, skin);\n const h = recipe.height ?? 0;\n if (recipe.beard && !flower) {\n const centre = C + fs * 0.6;\n const mouthX = Math.round(C - 0.5 + fs * 0.6);\n const chin: Mask = (x, y) => face(x, y) || face(x, y - 2);\n const open = (x: number, y: number) => y >= 20 + h && y <= 22 + h && Math.abs(x - mouthX) <= 3;\n const full: Mask = (x, y) =>\n chin(x, y) && (y >= 22 + h || (Math.abs(x + 0.5 - centre) >= 4 && y >= 17 + h));\n const shape: Mask =\n recipe.beard === 'short'\n ? (x, y) => chin(x, y) && y >= 22 + h\n : recipe.beard === 'full'\n ? full\n : (x, y) => full(x, y) || (Math.abs(x + 0.5 - centre) <= 1 && y >= 24 && y <= 30);\n paint(head, (x, y) => shape(x, y) && !open(x, y), shade(hairColor, 0.9));\n paint(\n head,\n (x, y) => shape(x, y) && !open(x, y) && (x + y * 2) % 5 === 0,\n shade(hairColor, 0.72),\n );\n }\n const earY = 15;\n const edge = (side: number) => {\n const xs = [...Array(N).keys()].filter((x) => face(x, earY));\n return side < 0 ? xs[0]! - 1 : xs.at(-1)! + 1;\n };\n const pointed = recipe.species ? POINTED_EARS[recipe.species] : undefined;\n if (flower) {\n // A flower has petals instead of ears.\n } else if (pointed) {\n // Pointed ears are drawn over hair: the outer tip rises above the ear line.\n const pal = { E: skin, e: shade(skin, 0.86), i: shade(skin, 0.74) };\n const width = pointed.rows[0]!.length;\n paint(head, masks.front, hairColor);\n for (const ex of turned ? [-d] : [-1, 1])\n sprite(\n head,\n pointed.rows,\n ex < 0 ? edge(ex) - (width - 1) : edge(ex),\n earY - pointed.rise,\n pal,\n ex > 0,\n );\n } else if (!turned)\n for (const ex of [-1, 1])\n sprite(head, ['E', 'E', 'e'], edge(ex), earY, { E: skin, e: shade(skin, 0.86) });\n else\n sprite(head, ['EE', 'Ee', 'Ee', 'E.'], d > 0 ? edge(-d) - 1 : edge(-d), earY, {\n E: skin,\n e: shade(skin, 0.8),\n });\n if (!pointed && !flower) paint(head, masks.front, hairColor);\n for (const [x, y] of masks.ties ?? [])\n sprite(back, ['T'], Math.round(x), y, { T: shade(recipe.shirtColor, 0.8) });\n if (!flower) accessory(recipe, head, s, face);\n\n const shadeHair = (g: Grid) => {\n const out = g.map((r) => [...r]);\n const cells = g.flatMap((row, y) => row.flatMap((c, x) => (c === hairColor ? [[x, y]] : [])));\n const xs = cells.map(([x]) => x!);\n const ys = cells.map(([, y]) => y!);\n const left = Math.min(...xs);\n const right = Math.max(...xs);\n const top = Math.min(...ys);\n const mid = (left + right) / 2;\n const span = Math.max(1, (right - left) / 2);\n const light = mix(hairColor, WHITE, 0.2);\n const dark = shade(hairColor, 0.8);\n const middle = shade(hairColor, 0.9);\n for (const [x, y] of cells) {\n const side = (x! + 0.5 - mid) / span + (y! - top) * 0.025;\n if (side > 0.72) out[y!]![x!] = dark;\n else if (side > 0.42) out[y!]![x!] = middle;\n else if (side < -0.2 && y! <= top + 4) out[y!]![x!] = light;\n }\n for (const [x, y] of cells) {\n const nearFace = g[y!]![x! - 1] === skin || g[y!]![x! + 1] === skin;\n if (nearFace && y! >= 14) out[y!]![x!] = shade(hairColor, 0.74);\n else if (Math.abs(x! + 0.5 - C - s) >= 7.5 && y! >= 14 && (x! + 40 - s) % 3 === 0)\n out[y!]![x!] = shade(out[y!]![x!]!, 0.86);\n }\n for (let y = 1; y < N; y++)\n for (let x = 0; x < N; x++) {\n if (g[y]![x] !== skin) continue;\n if (g[y - 1]![x] === hairColor) out[y]![x] = mix(shade(skin, 0.84), BLUSH, 0.12);\n else if (x + 1 < N && g[y]![x + 1] !== skin && g[y]![x + 1] !== undefined && x > C + s)\n out[y]![x] = shade(skin, 0.9);\n else if (x + 1 < N && g[y]![x + 1] === undefined && x > C + s)\n out[y]![x] = shade(skin, 0.9);\n }\n for (let y = 0; y < N - 1; y++)\n for (let x = 0; x < N; x++)\n if (g[y]![x] === hairColor && g[y + 1]![x] === skin) out[y]![x] = shade(hairColor, 0.62);\n for (let x = 0; x < N; x++)\n for (let y = 3; y < N; y++)\n if (g[y]![x] === hairColor && g[y + 1]?.[x] === skin && (x + 40 - s) % 4 === 0)\n for (let k = 1; k <= 3; k++)\n if (g[y - k]?.[x] === hairColor) out[y - k]![x] = shade(hairColor, 0.72);\n const ring = mix(hairColor, WHITE, 0.45);\n for (let x = Math.round(C + s) - 7; x <= Math.round(C + s) + 3; x++) {\n const first = g.findIndex((row) => row[x] === hairColor);\n if (first < 0) continue;\n const y = first + 2 + Math.round(Math.abs(x + 0.5 - (C + s - 2)) / 4);\n if (g[y]?.[x] === hairColor && x % 3 !== 0) out[y]![x] = ring;\n }\n return out;\n };\n\n const crown = blank();\n if (headpiece) placeCells(crown, headpiece.front);\n const figure = blank();\n for (const layer of [back, body, shadeHair(head), crown])\n for (let y = 0; y < N; y++)\n for (let x = 0; x < N; x++) if (layer[y]![x]) figure[y]![x] = layer[y]![x];\n\n const features = blank();\n const eyes = blank();\n const closed = blank();\n const glasses = blank();\n const sp = recipe.spacing ?? 0;\n const eyeTop = 15 + h;\n const eyeW = (side: -1 | 1) => (turned && Math.sign(fs) === side ? 3 : 4);\n const eyeX = (side: -1 | 1) => {\n const w = eyeW(side);\n return side < 0\n ? Math.round(C + fs * 0.6) - 6 - sp - (w === 3 ? -1 : 0)\n : Math.round(C + fs * 0.6) + 2 + sp;\n };\n const left = { x: eyeX(-1), w: eyeW(-1) };\n const right = { x: eyeX(1), w: eyeW(1) };\n const fit = (rows: readonly string[], w: number) =>\n rows.map((r) => r.slice(Math.max(0, r.length - w)));\n const pal = {\n K: INK,\n W: WHITE,\n D: shade(recipe.eyeColor, 0.55),\n I: recipe.eyeColor,\n L: mix(recipe.eyeColor, WHITE, 0.45),\n };\n if (flower) {\n const centre = Math.round(C + fs * 0.6);\n const bead = { K: '#1d1b22', W: WHITE };\n for (const ex of [centre - 3, centre + 1]) {\n sprite(eyes, ['KK', 'KW', 'KK', 'KK'], ex, eyeTop - 1, bead);\n sprite(closed, ['..', '..', 'KK', '..'], ex, eyeTop - 1, bead);\n }\n } else {\n const style = EYES[recipe.eyes];\n const extra = style[0]!.length - 4;\n sprite(eyes, fit(style, left.w + extra), left.x - extra, eyeTop, pal);\n sprite(\n eyes,\n recipe.eyes === 'wink' ? fit(CLOSED, right.w) : fit(style, right.w + extra),\n right.x,\n eyeTop,\n pal,\n true,\n );\n sprite(closed, fit(CLOSED, left.w), left.x, eyeTop, pal);\n sprite(closed, fit(CLOSED, right.w), right.x, eyeTop, pal, true);\n }\n const browRows = flower ? [] : BROWS[recipe.brows];\n if (browRows.length) {\n sprite(features, fit(browRows, left.w), left.x, eyeTop - 2, { B: shade(hairColor, 0.55) });\n sprite(\n features,\n fit(browRows, right.w),\n right.x,\n eyeTop - 2,\n { B: shade(hairColor, 0.55) },\n true,\n );\n }\n const cx = Math.round(C + fs * (turned ? 0.85 : 0.6));\n if (flower) {\n // A flower's face is only its bead eyes and its mouth.\n } else if (recipe.species === 'dwarf')\n sprite(features, ['.N.', 'NnN'], cx - 1, 17 + h, {\n N: shade(skin, 0.84),\n n: shade(skin, 0.72),\n });\n else if (recipe.nose === 'dot') sprite(features, ['N'], cx, 18 + h, { N: shade(skin, 0.78) });\n else if (recipe.nose === 'button') sprite(features, ['N'], cx, 18 + h, { N: shade(skin, 0.88) });\n else if (recipe.nose === 'line')\n sprite(features, ['N', 'N'], cx, 17 + h, { N: shade(skin, 0.82) });\n const mx = C - 0.5 + fs * 0.6;\n const withMouth = (mouth: readonly string[]) => {\n const layer = features.map((row) => [...row]);\n sprite(layer, mouth, Math.round(mx - (mouth[0]!.length - 1) / 2), 20 + h, {\n K: MOUTH,\n M: MOUTH_INSIDE,\n T: TONGUE,\n W: WHITE,\n });\n if (recipe.species === 'goblin')\n for (const tx of [Math.round(mx - 2.5), Math.round(mx + 2.5)])\n sprite(layer, ['T'], tx, 21 + h, { T: TUSK });\n if (recipe.species === 'orc')\n for (const tx of [Math.round(mx - 2.5), Math.round(mx + 2.5)])\n sprite(layer, ['T', 'T'], tx, 20 + h, { T: TUSK });\n if (recipe.cheeks === 'blush' && !flower) {\n sprite(layer, ['PP'], left.x - 1, 19 + h, { P: mix(BLUSH, skin, 0.25) });\n sprite(layer, ['PP'], right.x + right.w - 1, 19 + h, { P: mix(BLUSH, skin, 0.25) });\n }\n if (recipe.cheeks === 'freckles' && !flower) {\n sprite(layer, ['F.F'], left.x, 19 + h, { F: shade(skin, 0.7) });\n sprite(layer, ['F.F'], right.x + 1, 19 + h, { F: shade(skin, 0.7) });\n }\n return layer;\n };\n const savedFeatures = withMouth(MOUTHS[recipe.mouth]);\n const featureMarkup = options.mouthLayers\n ? (\n [\n ['saved', MOUTHS[recipe.mouth]],\n ['closed', ['KKK']],\n ['half-open', ['KKK', 'MMM']],\n ['open', ['.K.', 'KMK', '.K.']],\n ] satisfies readonly [PixelMouthState, readonly string[]][]\n )\n .map(\n ([state, rows]) =>\n `<g data-avatar-mouth=\"${state}\" opacity=\"${state === 'saved' ? 1 : 0}\">${rects(withMouth(rows))}</g>`,\n )\n .join('')\n : rects(savedFeatures);\n const frame = (fx: number, w: number, round: boolean) =>\n paint(\n glasses,\n (x, y) => {\n const inside = x >= fx && x < fx + w && y >= eyeTop && y <= eyeTop + 3;\n const box = x >= fx - 1 && x <= fx + w && y >= eyeTop - 1 && y <= eyeTop + 4;\n const corner = (x === fx - 1 || x === fx + w) && (y === eyeTop - 1 || y === eyeTop + 4);\n return box && !inside && !(round && corner);\n },\n INK,\n );\n const lenses = flower ? 'none' : recipe.glasses;\n if (lenses === 'round' || lenses === 'square') {\n frame(left.x, left.w, lenses === 'round');\n frame(right.x, right.w, lenses === 'round');\n paint(glasses, (x, y) => y === eyeTop + 1 && x > left.x + left.w && x < right.x - 1, INK);\n }\n if (lenses === 'shades') {\n for (const e of [left, right])\n paint(\n glasses,\n (x, y) => x >= e.x - 1 && x <= e.x + e.w && y >= eyeTop && y <= eyeTop + 2,\n INK,\n );\n paint(glasses, (x, y) => y === eyeTop && x > left.x + left.w && x < right.x - 1, INK);\n for (const e of [left, right]) sprite(glasses, ['W'], e.x, eyeTop, { W: '#7d7b88' });\n }\n if (lenses === 'monocle') {\n frame(right.x, right.w, true);\n sprite(glasses, ['G', 'G', 'G'], right.x + right.w, eyeTop + 5, { G: GOLD });\n }\n\n const full = clip(outline(figure));\n AVATAR_PIECE_COLORS.forEach((key, i) => {\n const color = recipe[key];\n const mask = masks.sides?.[i];\n if (color === undefined || !mask || color.toLowerCase() === hairColor.toLowerCase()) return;\n const variant = blank();\n const plain = { ...recipe, hairColor: color };\n for (const k of AVATAR_PIECE_COLORS) delete plain[k];\n for (const cell of pixelFigure(plain, yawDeg).cells) variant[cell.y]![cell.x] = cell.c;\n const near = (x: number, y: number) =>\n mask(x, y) || mask(x - 1, y) || mask(x + 1, y) || mask(x, y - 1) || mask(x, y + 1);\n for (let y = 0; y < N; y++)\n for (let x = 0; x < N; x++)\n if (full[y]![x] && near(x, y) && !eyes[y]![x] && !glasses[y]![x])\n full[y]![x] = variant[y]![x];\n });\n const bodyCells = blank();\n const headCells = blank();\n for (let y = 0; y < N; y++)\n for (let x = 0; x < N; x++) {\n const c = full[y]![x];\n if (!c) continue;\n if (y >= 22 && !head[y]![x] && !back[y]![x] && !crown[y]![x]) bodyCells[y]![x] = c;\n else headCells[y]![x] = c;\n }\n const cells: PixelCell[] = [];\n for (let y = 0; y < N; y++)\n for (let x = 0; x < N; x++) {\n const c = glasses[y]![x] ?? eyes[y]![x] ?? savedFeatures[y]![x] ?? full[y]![x];\n if (c) cells.push({ x, y, c });\n }\n return {\n cells,\n tile: `<rect width=\"32\" height=\"32\" rx=\"6\" fill=\"${pixelTileColor(recipe.hairColor)}\"/>`,\n body: `<g class=\"bh-illustrated-body\">${rects(bodyCells)}</g>`,\n head: [\n `<g class=\"bh-illustrated-head\">${rects(headCells)}`,\n `<g class=\"bh-illustrated-face\">${featureMarkup}`,\n `<g class=\"bh-illustrated-gaze\">${rects(eyes)}</g>`,\n `<g class=\"bh-illustrated-blink\" opacity=\"0\">${rects(closed)}</g>`,\n `${rects(glasses)}</g></g>`,\n ].join(''),\n };\n}\n","import type { PixelCell } from '@botharness/pixel-morph';\nimport { pixelFigure } from './figure.js';\nimport { isPixelAvatarRecipe, type PixelAvatarRecipe } from './recipe.js';\n\nconst YAW = { front: 0, left: -25, right: 25 } as const;\n\n/** Head-turn offsets (degrees) the thinking animation cycles through. */\nexport const AVATAR_TURNS = [-14, -7, 7, 14] as const;\n\nexport interface PixelAvatarSvgOptions {\n mouthLayers?: boolean;\n /** Extra yaw offsets to pre-render as hidden `[data-avatar-turn]` layers. */\n turns?: readonly number[];\n /** Class prefix for the rig layers (`-body`, `-head`, `-face`, `-gaze`, `-blink`). */\n classPrefix?: string;\n}\n\n/** Every visible pixel of the face at its pose, in paint order, for morphing. */\nexport function faceCells(recipe: PixelAvatarRecipe): PixelCell[] {\n return pixelFigure(recipe, YAW[recipe.pose]).cells;\n}\n\n/** A 32×32 SVG of the avatar: tile, body, head rig, optional turn layers and an empty morph layer. */\nexport function pixelAvatarSvg(\n recipe: PixelAvatarRecipe,\n options: PixelAvatarSvgOptions = {},\n): string {\n if (!isPixelAvatarRecipe(recipe)) throw new Error('invalid Avatar recipe');\n const base = pixelFigure(recipe, YAW[recipe.pose], options);\n const turns = (options.turns ?? [])\n .map((delta) => {\n const figure = pixelFigure(recipe, YAW[recipe.pose] + delta, options);\n const layers = `${figure.body}${figure.head}`.replaceAll(\n 'class=\"bh-illustrated-',\n 'data-turn-part=\"',\n );\n return `<g data-avatar-turn=\"${delta}\" opacity=\"0\">${layers}</g>`;\n })\n .join('');\n const svg = [\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 32\" width=\"512\" height=\"512\" shape-rendering=\"crispEdges\" aria-hidden=\"true\">',\n base.tile,\n base.body,\n base.head,\n turns,\n '<g data-avatar-pixel-morph=\"\"></g>',\n '</svg>',\n ].join('');\n const prefix = options.classPrefix;\n return prefix === undefined || prefix === 'bh-illustrated'\n ? svg\n : svg.replaceAll('class=\"bh-illustrated-', `class=\"${prefix}-`);\n}\n","import type { PixelCell } from '@botharness/pixel-morph';\n\nconst SYMBOLS = {\n thinking: [\n '........................',\n '........................',\n '........................',\n '...........AAAA.........',\n '..........AAAAAA........',\n '.........AAAAAAAA.......',\n '.......AAAAAAAAAAA......',\n '.....AAAAAAAAAAAAA......',\n '....AAAAAAAAAAAAAAAA....',\n '....AAAAAAAAAAAAAAAAA...',\n '...AAAAAAAAAAAAAAAAAAA..',\n '...AAAAHHAAAHHAAAHHAAA..',\n '....AAAHHAAAHHAAAHHAAA..',\n '....AAAAAAAAAAAAAAAAAA..',\n '.....AAAAAAAAAAAAAAAA...',\n '.....AAAAAAAAAAAAAAA....',\n '.......AAAAAAAAAAA......',\n '........................',\n '....AA..................',\n '...AAAA.................',\n '...AAAA.................',\n '..A.AA..................',\n '.AAA....................',\n '..A.....................',\n ],\n ask: [\n '........................',\n '........................',\n '...........AAA..........',\n '........AAAAAAAA........',\n '.......AAAAAAAAAA.......',\n '.......AAAAAAAAAA.......',\n '......AAAAA...AAAA......',\n '......AAAA....AAAA......',\n '......AAA.....AAAA......',\n '......AAA.....AAAA......',\n '..............AAAA......',\n '.............AAAAA......',\n '............AAAAA.......',\n '...........AAAAA........',\n '...........AAA..........',\n '..........AAAA..........',\n '..........AAAA..........',\n '...........AA...........',\n '........................',\n '..........AAAA..........',\n '..........AAAA..........',\n '..........AAAA..........',\n '...........AA...........',\n '........................',\n ],\n read: [\n '........................',\n '........................',\n '........................',\n '........................',\n '..AAAAAAA......AAAAAAA..',\n '.AAAAAAAAAA..AAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAHHHHHAAAAAAHHHHHAAA.',\n '.AAAHHHHHAAAAAAHHHHHAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAHHHHHAAAAAAHHHHHAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '...........AA...........',\n '........................',\n '........................',\n '........................',\n '........................',\n '........................',\n ],\n write: [\n '........................',\n '.....AAAAAAAAAA.........',\n '....AAAAAAAAAAAA........',\n '....AAAAAAAAAAAAA.......',\n '....AAAAAAAAAAAAAA......',\n '....AAAAAAAAAAAAAAA.....',\n '....AAAAAAAAAAAAAAAA....',\n '....AAAAAAAAAAAAAAAA....',\n '....AAAAAAAAAAAAAAAA....',\n '....AAAAAAAHHAAAAAAA....',\n '....AAAAAAAHHAAAAAAA....',\n '....AAAAAAAHHAAAAAAA....',\n '....AAAAAAAHHAAAAAAA....',\n '....AAAHHHHHHHHHHAAA....',\n '....AAAAAAAHHAAAAAAA....',\n '....AAAAAAAHHAAAAAAA....',\n '....AAAAAAAHHAAAAAAA....',\n '....AAAAAAAHHAAAAAAA....',\n '....AAAAAAAAAAAAAAAA....',\n '....AAAAAAAAAAAAAAAA....',\n '....AAAAAAAAAAAAAAAA....',\n '....AAAAAAAAAAAAAAAA....',\n '.....AAAAAAAAAAAAAA.....',\n '........................',\n ],\n edit: [\n '........................',\n '........................',\n '........................',\n '...............AA.......',\n '.............HHAAA......',\n '.............HHHAAA.....',\n '............AAHHHAAA....',\n '...........AAAAHHHAAA...',\n '..........AAAAAAHHHAA...',\n '.........AAAAAAAAHHH....',\n '........AAAAAAAAAAHH....',\n '.......AAAAAAAAAAA......',\n '......AAAAAAAAAAA.......',\n '.....AAAAAAAAAAA........',\n '....AAAAAAAAAAA.........',\n '...AAAAAAAAAAA..........',\n '...AAHHAAAAAA...........',\n '...AAHHHAAAA............',\n '...AAAHHAAA.............',\n '...AAAAAAA..............',\n '...AAAAAA...............',\n '........................',\n '........................',\n '........................',\n ],\n bash: [\n '........................',\n '........................',\n '........................',\n '....AAAAAAAAAAAAAAAA....',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAHHAAAAAAAAAAAAAAAA.',\n '.AAAAHHHAAAAAAAAAAAAAAA.',\n '.AAAAAHHHAAAAAAAAAAAAAA.',\n '.AAAAAAHHHAAAAAAAAAAAAA.',\n '.AAAAAAHHHAAAAAAAAAAAAA.',\n '.AAAAAHHHAAAAAAAAAAAAAA.',\n '.AAAAHHHAAAAAAAAAAAAAAA.',\n '.AAAAHHAAAAHHHHHHHAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '....AAAAAAAAAAAAAAAA....',\n '........................',\n '........................',\n '........................',\n ],\n search: [\n '........................',\n '........................',\n '.......AAAAAA...........',\n '......AAAAAAAA..........',\n '....AAAAAAAAAAAA........',\n '....AAAAAAAAAAAA........',\n '...AAAA......AAAA.......',\n '..AAAA........AAAA......',\n '..AAAA........AAAA......',\n '..AAAA........AAAA......',\n '..AAAA........AAAA......',\n '..AAAA........AAAA......',\n '..AAAA........AAAA......',\n '...AAAA......AAAA.......',\n '....AAAAAAAAAAAAA.......',\n '....AAAAAAAAAAAAAA......',\n '......AAAAAAAAAAAAA.....',\n '.......AAAAAA..AAAAA....',\n '................AAAAA...',\n '.................AAAAA..',\n '..................AAAAA.',\n '...................AAAA.',\n '....................AA..',\n '........................',\n ],\n web: [\n '........................',\n '........................',\n '.........AHHHHA.........',\n '.......AAHHHHHHAA.......',\n '.....AAAAHHAAHHAAAA.....',\n '....AAAAHHAAAAHHAAAA....',\n '....HHHHHHHHHHHHHHHH....',\n '...AHHHHHHHHHHHHHHHHA...',\n '...AAAAAHAAAAAAHAAAAA...',\n '..AAAAAHHAAAAAAHAAAAAA..',\n '..AAAAAHHAAAAAAHHAAAAA..',\n '..HHHHHHHHHHHHHHHHHHHH..',\n '..HHHHHHHHHHHHHHHHHHHH..',\n '..AAAAAHHAAAAAAHHAAAAA..',\n '..AAAAAHHAAAAAAHAAAAAA..',\n '...AAAAAHAAAAAAHAAAAA...',\n '...AHHHHHHHHHHHHHHHHA...',\n '....HHHHHHHHHHHHHHHH....',\n '....AAAAHHAAAAHHAAAA....',\n '.....AAAAHHAAHHAAAA.....',\n '.......AAHHHHHHAA.......',\n '.........AHHHHA.........',\n '........................',\n '........................',\n ],\n fetch: [\n '........................',\n '..........AAA...........',\n '..........AAAA..........',\n '..........AAAA..........',\n '..........AAAA..........',\n '..........AAAA..........',\n '..........AAAA..........',\n '.....AA...AAAA...AA.....',\n '....AAAA..AAAA..AAAA....',\n '....AAAAA.AAAA.AAAAA....',\n '.....AAAAAAAAAAAAAA.....',\n '......AAAAAAAAAAAA......',\n '.......AAAAAAAAAA.......',\n '........AAAAAAAA........',\n '.........AAAAAA.........',\n '..AAA.....AAAA.....AAA..',\n '..AAA......AA......AAA..',\n '..AAA..............AAA..',\n '..AAA..............AAA..',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '...AAAAAAAAAAAAAAAAAA...',\n '........................',\n ],\n todo: [\n '........................',\n '........................',\n '....AAAAAAAAAAAAAAAA....',\n '....AAAAAAAAAAAAAAAA....',\n '...AAAAAAAAAAAAAAAAAA...',\n '...AAAAAAAAAAAAAAAAAA...',\n '...AAAAAAAAHAAAAAAAAA...',\n '...AAAAAAAHHAAAAAAAAA...',\n '...AAAHHAHHAAHHHHHAAA...',\n '...AAAAHHHAAAHHHHHAAA...',\n '...AAAAAHAAAAAAAAAAAA...',\n '...AAAAAAAAAAAAAAAAAA...',\n '...AAAAAAAAAAAAAAAAAA...',\n '...AAAAAAAAHAAAAAAAAA...',\n '...AAAAAAAHHAAAAAAAAA...',\n '...AAAHHAHHAAHHHHHAAA...',\n '...AAAAHHHAAAHHHHHAAA...',\n '...AAAAAHAAAAAAAAAAAA...',\n '...AAAAAAAAAAAAAAAAAA...',\n '...AAAAAAAAAAAAAAAAAA...',\n '...AAAAAAAAAAAAAAAAAA...',\n '....AAAAAAAAAAAAAAAA....',\n '.....AAAAAAAAAAAAAA.....',\n '........................',\n ],\n subagent: [\n '........................',\n '........................',\n '........................',\n '........................',\n '.....AAAA......AAAA.....',\n '....AAAAAA....AAAAAA....',\n '....AAAAAAA..AAAAAAA....',\n '....AAAAAAA..AAAAAAA....',\n '....AAAAAAA..AAAAAAA....',\n '....AAAAAA...AAAAAAA....',\n '.....AAAAA....AAAAA.....',\n '........................',\n '........................',\n '........................',\n '.......A................',\n '....AAAAAAA..AAAAAAA....',\n '...AAAAAAAAAAAAAAAAAA...',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '........................',\n '........................',\n '........................',\n ],\n workflow: [\n '........................',\n '........................',\n '........................',\n '..AAAAAA.........AAAAA..',\n '..AAAAAA........AAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAA....AAA.AAAAAAA.',\n '..AAAAAA....AAA..AAAAA..',\n '............AAA.........',\n '............AAA.........',\n '............AAA.........',\n '............AAA.........',\n '............AAA..AAAAA..',\n '............AAA.AAAAAAA.',\n '.............AAAAAAAAAA.',\n '.............AAAAAAAAAA.',\n '...............AAAAAAAA.',\n '................AAAAAAA.',\n '.................AAAAA..',\n '........................',\n '........................',\n '........................',\n ],\n goal: [\n '........................',\n '....AA..................',\n '...AAAA.................',\n '...AAAAAAAAAAAAAAAAA....',\n '...AAAAAAAAAAAAAAAA.....',\n '...AAAAAAAAAAAAAAA......',\n '...AAAAAAAAAAAAAAA......',\n '...AAAAAAAAAAAAAA.......',\n '...AAAAAAAAAAAAAA.......',\n '...AAAAAAAAAAAAAAA......',\n '...AAAAAAAAAAAAAAAA.....',\n '...AAAAAAAAAAAAAAAAA....',\n '...AAAA.................',\n '...AAAA.................',\n '...AAAA.................',\n '...AAAA.................',\n '...AAAA.................',\n '...AAAA.................',\n '...AAAA.................',\n '...AAAA.................',\n '...AAAA.................',\n '...AAAA.................',\n '...AAAA.................',\n '....AA..................',\n ],\n present: [\n '........................',\n '........................',\n '...AAAAAAAAAAAAAAAAAA...',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '.AAAAAAAAAAAAAAAAAHAAAA.',\n '.AAAAAAAAAAAAAAAAAHAAAA.',\n '.AAAAAAAAAHAAAAAAAHAAAA.',\n '.AAAAAAAAAHAAAHAAAHAAAA.',\n '.AAAAAHAAAHAAAHAAAHAAAA.',\n '.AAAAAHAAAHAAAHAAAHAAAA.',\n '.AAAAAHAAAHAAAHAAAHAAAA.',\n '.AAAAAHAAAHAAAHAAAHAAAA.',\n '.AAAAAHAAAHAAAHAAAHAAAA.',\n '.AAAAAAAAAAAAAAAAAAAAAA.',\n '..AAAAAAAAAAAAAAAAAAAA..',\n '...AAAAAAAAAAAAAAAAAA...',\n '.........AAAAAA.........',\n '........AAAAAAAA........',\n '........AAA..AAA........',\n '.......AAA....AAA.......',\n '.......AAA....AAA.......',\n '.......AA......AA.......',\n '........................',\n ],\n approval: [\n '........................',\n '........................',\n '.........AAAAAA.........',\n '......AAAAAAAAAAAA......',\n '....AAAAAAAAAAAAAAAA....',\n '...AAAAAAAAHHAAAAAAAA...',\n '...AAAAAAAAHHAAAAAAAA...',\n '...AAAAAAAAHHAAAAAAAA...',\n '...AAAAAAAAHHAAAAAAAA...',\n '...AAAAAAAAHHAAAAAAAA...',\n '...AAAAAAAAHHAAAAAAAA...',\n '...AAAAAAAAHHAAAAAAAA...',\n '...AAAAAAAAHHAAAAAAAA...',\n '....AAAAAAAHHAAAAAAA....',\n '....AAAAAAAAAAAAAAAA....',\n '....AAAAAAAAAAAAAAAA....',\n '.....AAAAAAHHAAAAAA.....',\n '.....AAAAAAHHAAAAAA.....',\n '......AAAAAAAAAAAA......',\n '.......AAAAAAAAAA.......',\n '........AAAAAAAA........',\n '.........AAAAA..........',\n '...........AA...........',\n '........................',\n ],\n other: [\n '........................',\n '........................',\n '........................',\n '...........AA...........',\n '...........AA...........',\n '..........AAAA..........',\n '..........AAAA..........',\n '..........AAAA..........',\n '.........AAAAAA.........',\n '........AAAAAAAA........',\n '.....AAAAAAAAAAAAAA.....',\n '...AAAAAAAAAAAAAAAAAA...',\n '...AAAAAAAAAAAAAAAAAA...',\n '.....AAAAAAAAAAAAAA.....',\n '........AAAAAAAA........',\n '.........AAAAAA.........',\n '..........AAAA..........',\n '..........AAAA..........',\n '..........AAAA..........',\n '...........AA...........',\n '...........AA...........',\n '........................',\n '........................',\n '........................',\n ],\n} as const satisfies Record<string, readonly string[]>;\n\nexport type PixelSymbol = keyof typeof SYMBOLS;\nexport const PIXEL_SYMBOLS = Object.keys(SYMBOLS) as PixelSymbol[];\n\nconst INK = '#2a2230';\nconst channels = (color: string) => {\n const n = Number.parseInt(color.slice(1), 16);\n return [16, 8, 0].map((bit) => (n >> bit) & 255);\n};\nconst mix = (base: string, tint: string, k: number) => {\n const t = channels(tint);\n return `#${channels(base)\n .map((v, i) =>\n Math.round(v * (1 - k) + t[i]! * k)\n .toString(16)\n .padStart(2, '0'),\n )\n .join('')}`;\n};\n\nexport function pixelSymbolCells(symbol: PixelSymbol, color: string): PixelCell[] {\n return symbolArtCells(SYMBOLS[symbol], color);\n}\n\n/**\n * Colours a 24×24 character-art symbol (`A` body, `H` highlight, anything else empty) into\n * cells on the 32 grid: the body in `color`, highlights lighter, the lower-right edge darker,\n * and a one-pixel ink outline. This is how every built-in symbol is drawn, so a host can add\n * its own symbols in the same style without touching the package.\n */\nexport function symbolArtCells(rows: readonly string[], color: string): PixelCell[] {\n const body = new Map<string, 'A' | 'H'>();\n rows.forEach((row, y) =>\n [...row].forEach((code, x) => {\n if (code === 'A' || code === 'H') body.set(`${x + 4},${y + 4}`, code);\n }),\n );\n const light = mix(color, '#ffffff', 0.75);\n const low = mix(color, INK, 0.25);\n const cells: PixelCell[] = [];\n for (const [key, code] of body) {\n const [x, y] = key.split(',').map(Number) as [number, number];\n const edge = x + y > 34 && !body.has(`${x + 1},${y + 1}`);\n cells.push({ x, y, c: code === 'H' ? light : edge ? low : color });\n }\n const outline = new Set<string>();\n for (const key of body.keys()) {\n const [x, y] = key.split(',').map(Number) as [number, number];\n for (const [dx, dy] of [\n [1, 0],\n [-1, 0],\n [0, 1],\n [0, -1],\n ] as const) {\n const next = `${x + dx},${y + dy}`;\n if (body.has(next) || outline.has(next)) continue;\n outline.add(next);\n cells.push({ x: x + dx, y: y + dy, c: INK });\n }\n }\n return cells;\n}\n"],"mappings":"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E,OAAO;CAAG,MAAM;CAAK,OAAO;CAAI;;AAG9C,MAAa,eAAe;CAAC;CAAK;CAAI;CAAG;CAAG;;AAW5C,SAAgB,UAAU,QAAwC;AAChE,QAAO,YAAY,QAAQ,IAAI,OAAO,MAAM,CAAC;;;AAI/C,SAAgB,eACd,QACA,UAAiC,EAAE,EAC3B;AACR,KAAI,CAAC,oBAAoB,OAAO,CAAE,OAAM,IAAI,MAAM,wBAAwB;CAC1E,MAAM,OAAO,YAAY,QAAQ,IAAI,OAAO,OAAO,QAAQ;CAC3D,MAAM,SAAS,QAAQ,SAAS,EAAE,EAC/B,KAAK,UAAU;EACd,MAAM,SAAS,YAAY,QAAQ,IAAI,OAAO,QAAQ,OAAO,QAAQ;AAKrE,SAAO,wBAAwB,MAAM,gBAJtB,GAAG,OAAO,OAAO,OAAO,OAAO,WAC5C,2BACA,oBACD,CAC2D;GAC5D,CACD,KAAK,GAAG;CACX,MAAM,MAAM;EACV;EACA,KAAK;EACL,KAAK;EACL,KAAK;EACL;EACA;EACA;EACD,CAAC,KAAK,GAAG;CACV,MAAM,SAAS,QAAQ;AACvB,QAAO,WAAW,UAAa,WAAW,mBACtC,MACA,IAAI,WAAW,2BAA0B,UAAU,OAAO,GAAG;;;;;ACjDnE,MAAM,UAAU;CACd,UAAU;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,KAAK;EACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,MAAM;EACJ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,MAAM;EACJ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,MAAM;EACJ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,QAAQ;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,KAAK;EACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,MAAM;EACJ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,UAAU;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,UAAU;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,MAAM;EACJ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,SAAS;EACP;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,UAAU;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACF;AAGD,MAAa,gBAAgB,OAAO,KAAK,QAAQ;AAEjD,MAAM,MAAM;AACZ,MAAM,YAAY,UAAkB;CAClC,MAAM,IAAI,OAAO,SAAS,MAAM,MAAM,EAAE,EAAE,GAAG;AAC7C,QAAO;EAAC;EAAI;EAAG;EAAE,CAAC,KAAK,QAAS,KAAK,MAAO,IAAI;;AAElD,MAAM,OAAO,MAAc,MAAc,MAAc;CACrD,MAAM,IAAI,SAAS,KAAK;AACxB,QAAO,IAAI,SAAS,KAAK,CACtB,KAAK,GAAG,MACP,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,KAAM,EAAE,CAChC,SAAS,GAAG,CACZ,SAAS,GAAG,IAAI,CACpB,CACA,KAAK,GAAG;;AAGb,SAAgB,iBAAiB,QAAqB,OAA4B;AAChF,QAAO,eAAe,QAAQ,SAAS,MAAM;;;;;;;;AAS/C,SAAgB,eAAe,MAAyB,OAA4B;CAClF,MAAM,uBAAO,IAAI,KAAwB;AACzC,MAAK,SAAS,KAAK,MACjB,CAAC,GAAG,IAAI,CAAC,SAAS,MAAM,MAAM;AAC5B,MAAI,SAAS,OAAO,SAAS,IAAK,MAAK,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,KAAK,KAAK;GACrE,CACH;CACD,MAAM,QAAQ,IAAI,OAAO,WAAW,IAAK;CACzC,MAAM,MAAM,IAAI,OAAO,KAAK,IAAK;CACjC,MAAM,QAAqB,EAAE;AAC7B,MAAK,MAAM,CAAC,KAAK,SAAS,MAAM;EAC9B,MAAM,CAAC,GAAG,KAAK,IAAI,MAAM,IAAI,CAAC,IAAI,OAAO;EACzC,MAAM,OAAO,IAAI,IAAI,MAAM,CAAC,KAAK,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,IAAI;AACzD,QAAM,KAAK;GAAE;GAAG;GAAG,GAAG,SAAS,MAAM,QAAQ,OAAO,MAAM;GAAO,CAAC;;CAEpE,MAAM,0BAAU,IAAI,KAAa;AACjC,MAAK,MAAM,OAAO,KAAK,MAAM,EAAE;EAC7B,MAAM,CAAC,GAAG,KAAK,IAAI,MAAM,IAAI,CAAC,IAAI,OAAO;AACzC,OAAK,MAAM,CAAC,IAAI,OAAO;GACrB,CAAC,GAAG,EAAE;GACN,CAAC,IAAI,EAAE;GACP,CAAC,GAAG,EAAE;GACN,CAAC,GAAG,GAAG;GACR,EAAW;GACV,MAAM,OAAO,GAAG,IAAI,GAAG,GAAG,IAAI;AAC9B,OAAI,KAAK,IAAI,KAAK,IAAI,QAAQ,IAAI,KAAK,CAAE;AACzC,WAAQ,IAAI,KAAK;AACjB,SAAM,KAAK;IAAE,GAAG,IAAI;IAAI,GAAG,IAAI;IAAI,GAAG;IAAK,CAAC;;;AAGhD,QAAO"}
|