solfaces 2.2.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +45 -19
  2. package/SKILL.md +2 -3
  3. package/dist/agent/index.cjs +13 -14
  4. package/dist/agent/index.js +3 -4
  5. package/dist/agent/mcp-server.cjs +326 -333
  6. package/dist/{chunk-5DT27HMT.js → chunk-2KW35VRI.js} +3 -3
  7. package/dist/{chunk-5DT27HMT.js.map → chunk-2KW35VRI.js.map} +1 -1
  8. package/dist/{chunk-PVJR3SFG.cjs → chunk-BI3GHRKQ.cjs} +14 -15
  9. package/dist/chunk-BI3GHRKQ.cjs.map +1 -0
  10. package/dist/{chunk-DRUSCLEF.js → chunk-MYUSB4LA.js} +28 -8
  11. package/dist/chunk-MYUSB4LA.js.map +1 -0
  12. package/dist/{chunk-3CE7Q44S.js → chunk-N5GDLCCL.js} +324 -110
  13. package/dist/chunk-N5GDLCCL.js.map +1 -0
  14. package/dist/{chunk-74CSG63X.js → chunk-O2IIBSQH.js} +6 -7
  15. package/dist/chunk-O2IIBSQH.js.map +1 -0
  16. package/dist/{chunk-6QRDULAO.cjs → chunk-PCSRDAWQ.cjs} +28 -7
  17. package/dist/chunk-PCSRDAWQ.cjs.map +1 -0
  18. package/dist/{chunk-WIXGHS77.cjs → chunk-T7HEUW2O.cjs} +6 -6
  19. package/dist/{chunk-WIXGHS77.cjs.map → chunk-T7HEUW2O.cjs.map} +1 -1
  20. package/dist/{chunk-F54WHRCE.cjs → chunk-W2U6ITMR.cjs} +328 -110
  21. package/dist/chunk-W2U6ITMR.cjs.map +1 -0
  22. package/dist/core/index.cjs +43 -44
  23. package/dist/core/index.d.cts +39 -5
  24. package/dist/core/index.d.ts +39 -5
  25. package/dist/core/index.js +2 -3
  26. package/dist/index.cjs +53 -50
  27. package/dist/index.d.cts +3 -3
  28. package/dist/index.d.ts +3 -3
  29. package/dist/index.js +4 -5
  30. package/dist/react/index.cjs +107 -120
  31. package/dist/react/index.cjs.map +1 -1
  32. package/dist/react/index.d.cts +23 -1
  33. package/dist/react/index.d.ts +23 -1
  34. package/dist/react/index.js +95 -108
  35. package/dist/react/index.js.map +1 -1
  36. package/dist/solfaces.cdn.global.js +2 -2
  37. package/dist/solfaces.cdn.global.js.map +1 -1
  38. package/dist/themes/index.cjs +18 -14
  39. package/dist/themes/index.d.cts +30 -4
  40. package/dist/themes/index.d.ts +30 -4
  41. package/dist/themes/index.js +1 -1
  42. package/dist/traits-D4tbtZIr.d.cts +259 -0
  43. package/dist/traits-D4tbtZIr.d.ts +259 -0
  44. package/dist/vanilla/index.cjs +6 -7
  45. package/dist/vanilla/index.cjs.map +1 -1
  46. package/dist/vanilla/index.d.cts +1 -1
  47. package/dist/vanilla/index.d.ts +1 -1
  48. package/dist/vanilla/index.js +2 -3
  49. package/dist/vanilla/index.js.map +1 -1
  50. package/package.json +4 -1
  51. package/python/solfaces.py +103 -119
  52. package/reference/integrations.md +1 -1
  53. package/dist/chunk-3CE7Q44S.js.map +0 -1
  54. package/dist/chunk-6QRDULAO.cjs.map +0 -1
  55. package/dist/chunk-74CSG63X.js.map +0 -1
  56. package/dist/chunk-CKHLRORB.js +0 -239
  57. package/dist/chunk-CKHLRORB.js.map +0 -1
  58. package/dist/chunk-DRUSCLEF.js.map +0 -1
  59. package/dist/chunk-F54WHRCE.cjs.map +0 -1
  60. package/dist/chunk-PVJR3SFG.cjs.map +0 -1
  61. package/dist/chunk-TYTBYDQU.cjs +0 -244
  62. package/dist/chunk-TYTBYDQU.cjs.map +0 -1
  63. package/dist/traits-sfe7rM9C.d.cts +0 -106
  64. package/dist/traits-sfe7rM9C.d.ts +0 -106
@@ -26,15 +26,15 @@ import struct
26
26
  class SolFaceTraits:
27
27
  face_shape: int # 0-3 (consumed for PRNG ordering, all render as squircle)
28
28
  skin_color: int # 0-9
29
- eye_style: int # 0-7
30
- eye_color: int # 0-4
31
- eyebrows: int # 0-4
32
- nose: int # 0-3
29
+ eye_style: int # 0-8
30
+ eye_color: int # 0-7
31
+ eyebrows: int # 0-7
32
+ nose: int # 0-7
33
33
  mouth: int # 0-7
34
34
  hair_style: int # 0-9
35
35
  hair_color: int # 0-9
36
- accessory: int # 0-9
37
- bg_color: int # 0-9
36
+ accessory: int # 0-11
37
+ bg_color: int # 0-11
38
38
 
39
39
  def to_dict(self) -> Dict[str, int]:
40
40
  return {
@@ -58,7 +58,10 @@ SKIN_COLORS = [
58
58
  "#faeae5", "#efd6c8", "#e4c5aa", "#d5b590", "#c59e77",
59
59
  "#b4875f", "#9d6d4d", "#805742", "#654134", "#4b2d25",
60
60
  ]
61
- EYE_COLORS = ["#382414", "#3868A8", "#38784C", "#808838", "#586878"]
61
+ EYE_COLORS = [
62
+ "#382414", "#3868A8", "#38784C", "#808838", "#586878",
63
+ "#A06830", "#685898", "#889898",
64
+ ]
62
65
  HAIR_COLORS = [
63
66
  "#1A1A24", "#4C3428", "#887058", "#D4B868", "#A84830",
64
67
  "#C0C0CC", "#484858", "#783850", "#D8B0A0", "#C08048",
@@ -66,6 +69,7 @@ HAIR_COLORS = [
66
69
  BG_COLORS = [
67
70
  "#b98387", "#a9a360", "#9eb785", "#69ab79", "#81bbb0",
68
71
  "#6499af", "#7f8bbd", "#8869ab", "#b785b3", "#ab6984",
72
+ "#a07ab5", "#74b5a0",
69
73
  ]
70
74
 
71
75
 
@@ -105,6 +109,24 @@ def luminance(h: str) -> float:
105
109
  return (r + g + b) / 3
106
110
 
107
111
 
112
+ def _relative_luminance(h: str) -> float:
113
+ """WCAG 2.0 relative luminance."""
114
+ r, g, b = hex_to_rgb(h)
115
+ def _lin(c: float) -> float:
116
+ s = c / 255
117
+ return s / 12.92 if s <= 0.03928 else ((s + 0.055) / 1.055) ** 2.4
118
+ return 0.2126 * _lin(r) + 0.7152 * _lin(g) + 0.0722 * _lin(b)
119
+
120
+
121
+ def contrast_ratio(hex1: str, hex2: str) -> float:
122
+ """WCAG 2.0 contrast ratio between two hex colors (1-21)."""
123
+ l1 = _relative_luminance(hex1)
124
+ l2 = _relative_luminance(hex2)
125
+ lighter = max(l1, l2)
126
+ darker = min(l1, l2)
127
+ return (lighter + 0.05) / (darker + 0.05)
128
+
129
+
108
130
  def derive_skin_colors(skin: str) -> dict:
109
131
  sL = luminance(skin)
110
132
  is_dark = sL < 100
@@ -136,6 +158,11 @@ def derive_skin_colors(skin: str) -> dict:
136
158
  lr, lg, lb = hex_to_rgb(lip_raw)
137
159
  lip_d = abs(sr - lr) + abs(sg - lg) + abs(sb - lb)
138
160
  lip_color = blend(skin, lip_base, 0.78) if lip_d < 60 else lip_raw
161
+ # Ensure minimum lip/skin contrast for readability
162
+ attempts = 0
163
+ while contrast_ratio(lip_color, skin) < 1.8 and attempts < 12:
164
+ lip_color = darken(lip_color, 0.06)
165
+ attempts += 1
139
166
 
140
167
  brow_color = lighten(skin, 0.35 if sL < 80 else 0.25) if is_dark else darken(skin, 0.55)
141
168
  nose_fill = lighten(skin, 0.20) if is_dark else darken(skin, 0.20)
@@ -160,12 +187,6 @@ def derive_skin_colors(skin: str) -> dict:
160
187
  }
161
188
 
162
189
 
163
- def buzz_opacity(hair_col: str, skin: str) -> float:
164
- hr, hg, hb = hex_to_rgb(hair_col)
165
- sr, sg, sb = hex_to_rgb(skin)
166
- return 0.70 if abs(hr - sr) + abs(hg - sg) + abs(hb - sb) < 80 else 0.50
167
-
168
-
169
190
  # ─── Hashing (djb2) — exact JS parity ────────────────────────
170
191
 
171
192
  def _djb2(s: str) -> int:
@@ -215,23 +236,20 @@ def generate_traits(wallet_address: str) -> SolFaceTraits:
215
236
  return SolFaceTraits(
216
237
  face_shape=int(rand() * 4),
217
238
  skin_color=int(rand() * 10),
218
- eye_style=int(rand() * 8),
219
- eye_color=int(rand() * 5),
220
- eyebrows=int(rand() * 5),
221
- nose=int(rand() * 4),
239
+ eye_style=int(rand() * 9),
240
+ eye_color=int(rand() * 8),
241
+ eyebrows=int(rand() * 8),
242
+ nose=int(rand() * 8),
222
243
  mouth=int(rand() * 8),
223
244
  hair_style=int(rand() * 10),
224
245
  hair_color=int(rand() * 10),
225
- accessory=int(rand() * 10),
226
- bg_color=int(rand() * 10),
246
+ accessory=int(rand() * 12),
247
+ bg_color=int(rand() * 12),
227
248
  )
228
249
 
229
250
 
230
251
  def effective_accessory(t: SolFaceTraits) -> int:
231
- ai = t.accessory % 10
232
- hi = t.hair_style % 10
233
- if (ai == 4 or ai == 7) and (hi == 5 or hi == 6):
234
- return 0
252
+ ai = t.accessory % 12
235
253
  return ai
236
254
 
237
255
 
@@ -243,19 +261,21 @@ def trait_hash(wallet_address: str) -> str:
243
261
 
244
262
  SKIN_LABELS = ["Porcelain", "Ivory", "Fair", "Light", "Sand",
245
263
  "Golden", "Warm", "Caramel", "Brown", "Deep"]
246
- EYE_STYLE_LABELS = ["Round", "Minimal", "Almond", "Wide", "Relaxed", "Joyful", "Bright", "Gentle"]
247
- EYE_COLOR_LABELS = ["Chocolate", "Sky", "Emerald", "Hazel", "Storm"]
248
- BROW_LABELS = ["Wispy", "Straight", "Natural", "Arched", "Angled"]
249
- NOSE_LABELS = ["Shadow", "Button", "Soft", "Nostrils"]
264
+ EYE_STYLE_LABELS = ["Round", "Minimal", "Almond", "Wide", "Relaxed", "Joyful", "Bright", "Gentle", "Side-look"]
265
+ EYE_COLOR_LABELS = ["Chocolate", "Sky", "Emerald", "Hazel", "Storm", "Amber", "Violet", "Gray"]
266
+ BROW_LABELS = ["Wispy", "Straight", "Natural", "Arched", "Angled", "Worried", "Bushy", "Thin"]
267
+ NOSE_LABELS = ["Shadow", "Button", "Soft", "Nostrils", "Pointed", "Wide", "Bridge", "Snub"]
250
268
  MOUTH_LABELS = ["Smile", "Calm", "Happy", "Oh", "Smirk", "Grin", "Flat", "Pout"]
251
- HAIR_STYLE_LABELS = ["Bald", "Short", "Curly", "Side Sweep", "Puff",
252
- "Long", "Bob", "Buzz", "Wavy", "Topknot"]
269
+ HAIR_STYLE_LABELS = ["Bald", "Crew", "Curly", "Side Part", "Long",
270
+ "Buzz", "Beanie", "Cap", "Mohawk", "Bun"]
253
271
  HAIR_COLOR_LABELS = ["Black", "Espresso", "Walnut", "Honey", "Copper",
254
272
  "Silver", "Charcoal", "Burgundy", "Strawberry", "Ginger"]
255
273
  ACC_LABELS = ["None", "Beauty Mark", "Round Glasses", "Rect Glasses", "Earring",
256
- "Headband", "Freckles", "Stud Earrings", "Aviators", "Band-Aid"]
274
+ "Headband", "Freckles", "Stud Earrings", "Aviators", "Band-Aid",
275
+ "Left Eyebrow Slit", "Right Eyebrow Slit"]
257
276
  BG_COLOR_LABELS = ["Rose", "Olive", "Sage", "Fern", "Mint",
258
- "Ocean", "Sky", "Lavender", "Orchid", "Blush"]
277
+ "Ocean", "Sky", "Lavender", "Orchid", "Blush",
278
+ "Lilac", "Seafoam"]
259
279
 
260
280
 
261
281
  def get_trait_labels(t: SolFaceTraits) -> Dict[str, str]:
@@ -296,12 +316,9 @@ def _build_defs(gid: str, skin: str, skin_hi: str, skin_lo: str,
296
316
  d = "<defs>"
297
317
  d += f'<linearGradient id="{gid}sg" x1="0" y1="0" x2="0" y2="1">'
298
318
  d += f'<stop offset="0%" stop-color="{skin_hi}"/>'
319
+ d += f'<stop offset="50%" stop-color="{skin}"/>'
299
320
  d += f'<stop offset="100%" stop-color="{skin_lo}"/>'
300
321
  d += "</linearGradient>"
301
- d += f'<linearGradient id="{gid}hg" x1="0" y1="0" x2="0" y2="1">'
302
- d += f'<stop offset="0%" stop-color="{lighten(hair_col, 0.15)}"/>'
303
- d += f'<stop offset="100%" stop-color="{darken(hair_col, 0.15)}"/>'
304
- d += "</linearGradient>"
305
322
  d += f'<linearGradient id="{gid}bg" x1="0" y1="0" x2="1" y2="1">'
306
323
  d += f'<stop offset="0%" stop-color="{lighten(bg_col, 0.12)}"/>'
307
324
  d += f'<stop offset="100%" stop-color="{darken(bg_col, 0.12)}"/>'
@@ -328,10 +345,6 @@ def _build_defs(gid: str, skin: str, skin_hi: str, skin_lo: str,
328
345
 
329
346
 
330
347
  def _render_hair_back(hi: int, gid: str, flat: bool) -> str:
331
- fill = "currentColor" if flat else f"url(#{gid}hg)"
332
- if hi == 5: return f'<rect x="10" y="14" width="44" height="42" rx="6" fill="{fill}"/>'
333
- if hi == 6: return f'<rect x="12" y="14" width="40" height="32" rx="8" fill="{fill}"/>'
334
- if hi == 8: return f'<rect x="11" y="14" width="42" height="38" rx="8" fill="{fill}"/>'
335
348
  return ""
336
349
 
337
350
 
@@ -360,33 +373,6 @@ def _render_face_overlays(gid: str) -> str:
360
373
 
361
374
 
362
375
  def _render_hair_front(hi: int, gid: str, hair_col: str, skin: str, flat: bool) -> str:
363
- fill = hair_col if flat else f"url(#{gid}hg)"
364
- if hi == 0: return ""
365
- if hi == 1: return f'<path d="M14 28 Q14 14 32 12 Q50 14 50 28 L50 22 Q50 12 32 10 Q14 12 14 22 Z" fill="{fill}"/>'
366
- if hi == 2:
367
- return (f'<g fill="{fill}">'
368
- '<circle cx="20" cy="14" r="5"/><circle cx="28" cy="11" r="5.5"/>'
369
- '<circle cx="36" cy="11" r="5.5"/><circle cx="44" cy="14" r="5"/>'
370
- '<circle cx="16" cy="20" r="4"/><circle cx="48" cy="20" r="4"/></g>')
371
- if hi == 3:
372
- return (f'<path d="M14 26 Q14 12 32 10 Q50 12 50 26 L50 20 Q50 10 32 8 Q14 10 14 20 Z" fill="{fill}"/>'
373
- f'<path d="M14 20 Q8 16 10 8 Q14 10 20 16 Z" fill="{fill}"/>')
374
- if hi == 4: return f'<ellipse cx="32" cy="10" rx="14" ry="8" fill="{fill}"/>'
375
- if hi == 5: return f'<path d="M14 28 Q14 12 32 10 Q50 12 50 28 L50 20 Q50 10 32 8 Q14 10 14 20 Z" fill="{fill}"/>'
376
- if hi == 6:
377
- return (f'<path d="M14 28 Q14 12 32 10 Q50 12 50 28 L50 20 Q50 10 32 8 Q14 10 14 20 Z" fill="{fill}"/>'
378
- f'<rect x="10" y="28" width="8" height="14" rx="4" fill="{fill}"/>'
379
- f'<rect x="46" y="28" width="8" height="14" rx="4" fill="{fill}"/>')
380
- if hi == 7:
381
- bop = buzz_opacity(hair_col, skin)
382
- return f'<rect x="15" y="13" width="34" height="16" rx="10" ry="8" fill="{hair_col}" opacity="{bop:.2f}"/>'
383
- if hi == 8:
384
- return (f'<path d="M14 28 Q14 12 32 10 Q50 12 50 28 L50 20 Q50 10 32 8 Q14 10 14 20 Z" fill="{fill}"/>'
385
- f'<path d="M12 30 Q10 20 14 16" fill="none" stroke="{fill}" stroke-width="4" stroke-linecap="round"/>'
386
- f'<path d="M52 30 Q54 20 50 16" fill="none" stroke="{fill}" stroke-width="4" stroke-linecap="round"/>')
387
- if hi == 9:
388
- return (f'<path d="M14 28 Q14 14 32 12 Q50 14 50 28 L50 22 Q50 12 32 10 Q14 12 14 22 Z" fill="{fill}"/>'
389
- f'<ellipse cx="32" cy="6" rx="6" ry="5" fill="{fill}"/>')
390
376
  return ""
391
377
 
392
378
 
@@ -421,17 +407,16 @@ def _render_eyes(ei: int, eye_col: str, eye_white: str, lid_color: str, full: bo
421
407
  elif ei == 6:
422
408
  s += f'<circle cx="{lx}" cy="{y}" r="3.5" fill="{eye_white}"/><circle cx="{lx+0.5}" cy="{y}" r="2" fill="{eye_col}"/>'
423
409
  s += f'<circle cx="{lx+1.5}" cy="{y-1}" r="1" fill="white" opacity="0.9"/>'
424
- if full:
425
- s += f'<line x1="{lx+2.5}" y1="{y-3.5}" x2="{lx+4}" y2="{y-5}" stroke="{eye_col}" stroke-width="0.8" stroke-linecap="round"/>'
426
- s += f'<line x1="{lx+3.5}" y1="{y-2.5}" x2="{lx+5}" y2="{y-3.5}" stroke="{eye_col}" stroke-width="0.8" stroke-linecap="round"/>'
427
410
  s += f'<circle cx="{rx}" cy="{y}" r="3.5" fill="{eye_white}"/><circle cx="{rx+0.5}" cy="{y}" r="2" fill="{eye_col}"/>'
428
411
  s += f'<circle cx="{rx+1.5}" cy="{y-1}" r="1" fill="white" opacity="0.9"/>'
429
- if full:
430
- s += f'<line x1="{rx+2.5}" y1="{y-3.5}" x2="{rx+4}" y2="{y-5}" stroke="{eye_col}" stroke-width="0.8" stroke-linecap="round"/>'
431
- s += f'<line x1="{rx+3.5}" y1="{y-2.5}" x2="{rx+5}" y2="{y-3.5}" stroke="{eye_col}" stroke-width="0.8" stroke-linecap="round"/>'
432
412
  elif ei == 7:
433
413
  s += f'<ellipse cx="{lx}" cy="{y}" rx="4.5" ry="1.5" fill="{eye_white}"/><ellipse cx="{lx+0.5}" cy="{y}" rx="2.2" ry="1.2" fill="{eye_col}"/>'
434
414
  s += f'<ellipse cx="{rx}" cy="{y}" rx="4.5" ry="1.5" fill="{eye_white}"/><ellipse cx="{rx+0.5}" cy="{y}" rx="2.2" ry="1.2" fill="{eye_col}"/>'
415
+ elif ei == 8: # Side-look — pupils shifted left
416
+ s += f'<circle cx="{lx}" cy="{y}" r="3.5" fill="{eye_white}"/><circle cx="{lx-1}" cy="{y}" r="2" fill="{eye_col}"/>'
417
+ if full: s += f'<circle cx="{lx-0.3}" cy="{y-0.8}" r="0.7" fill="white" opacity="0.8"/>'
418
+ s += f'<circle cx="{rx}" cy="{y}" r="3.5" fill="{eye_white}"/><circle cx="{rx-1}" cy="{y}" r="2" fill="{eye_col}"/>'
419
+ if full: s += f'<circle cx="{rx-0.3}" cy="{y-0.8}" r="0.7" fill="white" opacity="0.8"/>'
435
420
  else:
436
421
  s += f'<circle cx="{lx}" cy="{y}" r="3.5" fill="{eye_white}"/><circle cx="{lx+0.8}" cy="{y}" r="2" fill="{eye_col}"/>'
437
422
  s += f'<circle cx="{rx}" cy="{y}" r="3.5" fill="{eye_white}"/><circle cx="{rx+0.8}" cy="{y}" r="2" fill="{eye_col}"/>'
@@ -459,6 +444,15 @@ def _render_eyebrows(bi: int, brow_color: str) -> str:
459
444
  if bi == 4:
460
445
  return (f'<polyline points="{lx-3},{y+1} {lx},{y-2} {lx+3},{y}" fill="none" stroke="{brow_color}" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>'
461
446
  f'<polyline points="{rx-3},{y} {rx},{y-2} {rx+3},{y+1}" fill="none" stroke="{brow_color}" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>')
447
+ if bi == 5: # Worried
448
+ return (f'<line x1="{lx-3}" y1="{y-1}" x2="{lx+3}" y2="{y+1}" stroke="{brow_color}" stroke-width="1.1" stroke-linecap="round"/>'
449
+ f'<line x1="{rx-3}" y1="{y+1}" x2="{rx+3}" y2="{y-1}" stroke="{brow_color}" stroke-width="1.1" stroke-linecap="round"/>')
450
+ if bi == 6: # Bushy
451
+ return (f'<path d="M{lx-4} {y+0.5} Q{lx} {y-2} {lx+4} {y+0.5}" fill="none" stroke="{brow_color}" stroke-width="2.0" stroke-linecap="round"/>'
452
+ f'<path d="M{rx-4} {y+0.5} Q{rx} {y-2} {rx+4} {y+0.5}" fill="none" stroke="{brow_color}" stroke-width="2.0" stroke-linecap="round"/>')
453
+ if bi == 7: # Thin
454
+ return (f'<path d="M{lx-3.5} {y} Q{lx} {y-1.5} {lx+3.5} {y}" fill="none" stroke="{brow_color}" stroke-width="0.5" stroke-linecap="round"/>'
455
+ f'<path d="M{rx-3.5} {y} Q{rx} {y-1.5} {rx+3.5} {y}" fill="none" stroke="{brow_color}" stroke-width="0.5" stroke-linecap="round"/>')
462
456
  return ""
463
457
 
464
458
 
@@ -468,6 +462,11 @@ def _render_nose(ni: int, nose_fill: str) -> str:
468
462
  if ni == 1: return f'<circle cx="{cx}" cy="{y}" r="1.8" fill="{nose_fill}" opacity="0.5"/>'
469
463
  if ni == 2: return f'<path d="M{cx-2} {y+1} Q{cx} {y-2} {cx+2} {y+1}" fill="none" stroke="{nose_fill}" stroke-width="1" stroke-linecap="round" opacity="0.5"/>'
470
464
  if ni == 3: return f'<circle cx="{cx-1.8}" cy="{y}" r="1.2" fill="{nose_fill}" opacity="0.4"/><circle cx="{cx+1.8}" cy="{y}" r="1.2" fill="{nose_fill}" opacity="0.4"/>'
465
+ if ni == 4: return f'<path d="M{cx} {y-2} L{cx-2} {y+1.5} L{cx+2} {y+1.5} Z" fill="{nose_fill}" opacity="0.4"/>'
466
+ if ni == 5: return f'<ellipse cx="{cx}" cy="{y}" rx="3.5" ry="1.5" fill="{nose_fill}" opacity="0.35"/>'
467
+ if ni == 6: return f'<line x1="{cx}" y1="{y-3}" x2="{cx}" y2="{y+1}" stroke="{nose_fill}" stroke-width="1.2" stroke-linecap="round" opacity="0.4"/>'
468
+ if ni == 7: return (f'<circle cx="{cx}" cy="{y+0.5}" r="2" fill="{nose_fill}" opacity="0.35"/>'
469
+ f'<ellipse cx="{cx}" cy="{y-0.5}" rx="1" ry="0.5" fill="{nose_fill}" opacity="0.15"/>')
471
470
  return f'<ellipse cx="{cx}" cy="{y}" rx="2" ry="1.2" fill="{nose_fill}" opacity="0.35"/>'
472
471
 
473
472
 
@@ -482,14 +481,14 @@ def _render_mouth(mi: int, lip_color: str, is_dark: bool) -> str:
482
481
  if mi == 5:
483
482
  return (f'<path d="M{cx-5} {y} Q{cx} {y+6} {cx+5} {y}" fill="{tc}" stroke="{lip_color}" stroke-width="1"/>'
484
483
  f'<line x1="{cx-4}" y1="{y+1.5}" x2="{cx+4}" y2="{y+1.5}" stroke="{lip_color}" stroke-width="0.3" opacity="0.3"/>')
485
- if mi == 6: return f'<line x1="{cx-4}" y1="{y+1}" x2="{cx+4}" y2="{y+1}" stroke="{lip_color}" stroke-width="1.5" stroke-linecap="round"/>'
484
+ if mi == 6: return f'<path d="M{cx-4} {y+0.5} Q{cx} {y+1.5} {cx+4} {y+0.5}" fill="none" stroke="{lip_color}" stroke-width="1.4" stroke-linecap="round"/>'
486
485
  if mi == 7:
487
486
  return (f'<ellipse cx="{cx}" cy="{y+1}" rx="3.5" ry="2" fill="{lip_color}" opacity="0.25"/>'
488
487
  f'<path d="M{cx-3} {y} Q{cx} {y+2.5} {cx+3} {y}" fill="none" stroke="{lip_color}" stroke-width="1.2" stroke-linecap="round"/>')
489
488
  return f'<path d="M{cx-4} {y} Q{cx} {y+4} {cx+4} {y}" fill="none" stroke="{lip_color}" stroke-width="1.4" stroke-linecap="round"/>'
490
489
 
491
490
 
492
- def _render_accessory(ai: int, acc_color: str, glasses_color: str, earring_color: str, headband_color: str) -> str:
491
+ def _render_accessory(ai: int, acc_color: str, glasses_color: str, earring_color: str, headband_color: str, skin_color: str = "#E8BA8B") -> str:
493
492
  if ai == 0: return ""
494
493
  if ai == 1: return '<circle cx="40" cy="44" r="0.8" fill="#3a2a2a"/>'
495
494
  if ai == 2:
@@ -527,10 +526,14 @@ def _render_accessory(ai: int, acc_color: str, glasses_color: str, earring_color
527
526
  '<line x1="45" y1="31" x2="50" y2="29"/></g>')
528
527
  if ai == 9:
529
528
  return ('<g>'
530
- '<rect x="38" y="38" width="8" height="4" rx="1" fill="#f0d0a0" transform="rotate(-15 42 40)"/>'
531
- '<line x1="40" y1="39" x2="40" y2="41" stroke="#c0a080" stroke-width="0.4" transform="rotate(-15 42 40)"/>'
532
- '<line x1="42" y1="39" x2="42" y2="41" stroke="#c0a080" stroke-width="0.4" transform="rotate(-15 42 40)"/>'
533
- '<line x1="44" y1="39" x2="44" y2="41" stroke="#c0a080" stroke-width="0.4" transform="rotate(-15 42 40)"/></g>')
529
+ '<rect x="38" y="38" width="9" height="4.5" rx="1.2" fill="#f0d0a0" transform="rotate(-15 42 40)"/>'
530
+ '<rect x="39.5" y="38.5" width="6" height="3.5" rx="0.8" fill="#f5ddb5" transform="rotate(-15 42 40)"/>'
531
+ '<circle cx="42.5" cy="40.25" r="0.5" fill="#d4b898" transform="rotate(-15 42 40)"/>'
532
+ '</g>')
533
+ if ai == 10: # Left Eyebrow Slit
534
+ return f'<line x1="23" y1="24.8" x2="23.8" y2="29.2" stroke="{skin_color}" stroke-width="1.3" stroke-linecap="butt"/>'
535
+ if ai == 11: # Right Eyebrow Slit
536
+ return f'<line x1="41" y1="24.8" x2="40.2" y2="29.2" stroke="{skin_color}" stroke-width="1.3" stroke-linecap="butt"/>'
534
537
  return ""
535
538
 
536
539
 
@@ -571,15 +574,15 @@ def render_svg(
571
574
  parts.append(_render_face(gid, skin, flat))
572
575
  if full:
573
576
  parts.append(_render_face_overlays(gid))
574
- if ai == 5:
575
- parts.append(_render_accessory(5, derived["acc_color"], glasses_color, earring_color, headband_color))
576
577
  parts.append(_render_hair_front(hi, gid, hair_col, skin, flat))
577
- parts.append(_render_eyes(t.eye_style % 8, eye_col, derived["eye_white"], derived["lid_color"], full))
578
- parts.append(_render_eyebrows(t.eyebrows % 5, derived["brow_color"]))
579
- parts.append(_render_nose(t.nose % 4, derived["nose_fill"]))
578
+ if ai == 5:
579
+ parts.append(_render_accessory(5, derived["acc_color"], glasses_color, earring_color, headband_color, skin))
580
+ parts.append(_render_eyes(t.eye_style % 9, eye_col, derived["eye_white"], derived["lid_color"], full))
581
+ parts.append(_render_eyebrows(t.eyebrows % 8, derived["brow_color"]))
582
+ parts.append(_render_nose(t.nose % 8, derived["nose_fill"]))
580
583
  parts.append(_render_mouth(t.mouth % 8, derived["lip_color"], derived["is_dark"]))
581
584
  if ai != 0 and ai != 5:
582
- parts.append(_render_accessory(ai, derived["acc_color"], glasses_color, earring_color, headband_color))
585
+ parts.append(_render_accessory(ai, derived["acc_color"], glasses_color, earring_color, headband_color, skin))
583
586
  parts.append("</svg>")
584
587
  return "".join(p for p in parts if p)
585
588
 
@@ -596,26 +599,25 @@ _SKIN_DESC = {0: "porcelain", 1: "ivory", 2: "fair", 3: "light", 4: "sand",
596
599
  5: "golden", 6: "warm", 7: "caramel", 8: "brown", 9: "deep"}
597
600
  _EYE_STYLE_DESC = {0: "round, wide-open", 1: "small and minimal", 2: "almond-shaped",
598
601
  3: "wide and expressive", 4: "relaxed, half-lidded", 5: "joyful, crescent-shaped",
599
- 6: "bright and sparkling", 7: "gentle and narrow"}
600
- _EYE_COLOR_DESC = {0: "dark brown", 1: "blue", 2: "green", 3: "hazel", 4: "gray"}
601
- _BROW_DESC = {0: "wispy", 1: "straight", 2: "natural", 3: "elegantly arched", 4: "sharply angled"}
602
+ 6: "bright and sparkling", 7: "gentle and narrow", 8: "side-looking, shifted"}
603
+ _EYE_COLOR_DESC = {0: "dark brown", 1: "blue", 2: "green", 3: "hazel", 4: "gray",
604
+ 5: "amber", 6: "violet", 7: "steel gray"}
605
+ _BROW_DESC = {0: "wispy", 1: "straight", 2: "natural", 3: "elegantly arched", 4: "sharply angled",
606
+ 5: "worried, furrowed", 6: "bushy", 7: "thin, delicate"}
602
607
  _NOSE_DESC = {0: "a subtle shadow nose", 1: "a small button nose", 2: "a soft curved nose",
603
- 3: "a button nose with visible nostrils"}
608
+ 3: "a button nose with visible nostrils", 4: "a pointed nose",
609
+ 5: "a wide, broad nose", 6: "a nose with a visible bridge",
610
+ 7: "a small snub nose"}
604
611
  _MOUTH_DESC = {0: "a gentle smile", 1: "a calm, neutral expression", 2: "a happy grin",
605
612
  3: "a surprised O-shaped mouth", 4: "a confident smirk", 5: "a wide, toothy grin",
606
613
  6: "a flat, straight expression", 7: "a soft pout"}
607
- _HAIR_STYLE_DESC = {0: "bald, with no hair", 1: "short, neatly cropped hair", 2: "bouncy, curly hair",
608
- 3: "side-swept hair", 4: "a voluminous puff",
609
- 5: "long hair that falls past the shoulders", 6: "a clean bob cut",
610
- 7: "a close buzz cut", 8: "flowing, wavy hair", 9: "a neat topknot"}
611
- _HAIR_COLOR_DESC = {0: "jet black", 1: "espresso brown", 2: "walnut", 3: "honey blonde",
612
- 4: "copper red", 5: "silver", 6: "charcoal", 7: "burgundy",
613
- 8: "strawberry", 9: "ginger"}
614
614
  _ACC_DESC = {0: "", 1: "a beauty mark", 2: "round glasses", 3: "rectangular glasses",
615
615
  4: "a dangling earring", 5: "a headband", 6: "freckles", 7: "stud earrings",
616
- 8: "aviator sunglasses", 9: "a band-aid"}
616
+ 8: "aviator sunglasses", 9: "a band-aid",
617
+ 10: "a left eyebrow slit", 11: "a right eyebrow slit"}
617
618
  _BG_DESC = {0: "rose", 1: "olive", 2: "sage", 3: "fern", 4: "mint",
618
- 5: "ocean", 6: "sky", 7: "lavender", 8: "orchid", 9: "blush"}
619
+ 5: "ocean", 6: "sky", 7: "lavender", 8: "orchid", 9: "blush",
620
+ 10: "lilac", 11: "seafoam"}
619
621
 
620
622
 
621
623
  def _build_paragraph(
@@ -642,15 +644,8 @@ def _build_paragraph(
642
644
  if brows:
643
645
  parts.append(f"{brows} eyebrows")
644
646
 
645
- if t.hair_style == 0:
646
- parts.append("and am bald" if perspective == "first" else "and is bald")
647
- else:
648
- hc = _HAIR_COLOR_DESC.get(t.hair_color, "")
649
- hs = _HAIR_STYLE_DESC.get(t.hair_style, "")
650
- if hs.startswith("a "):
651
- parts.append(f"and a {hc} {hs[2:]}")
652
- else:
653
- parts.append(f"and {hc} {hs}")
647
+ # All styles render as bald
648
+ parts.append("and am bald" if perspective == "first" else "and is bald")
654
649
 
655
650
  desc = parts[0]
656
651
  if len(parts) > 2:
@@ -690,12 +685,7 @@ def _build_structured(t, ai: int, include_background: bool = True) -> str:
690
685
  if nose:
691
686
  lines.append(f"Nose: {nose.lstrip('a ')}")
692
687
  lines.append(f"Mouth: {_MOUTH_DESC.get(t.mouth, 'smile')}")
693
- if t.hair_style == 0:
694
- lines.append("Hair: bald")
695
- else:
696
- hs = _HAIR_STYLE_DESC.get(t.hair_style, "")
697
- hc = _HAIR_COLOR_DESC.get(t.hair_color, "")
698
- lines.append(f"Hair: {hc} {hs[2:] if hs.startswith('a ') else hs}")
688
+ lines.append("Hair: bald")
699
689
  acc = _ACC_DESC.get(ai, "")
700
690
  if acc:
701
691
  lines.append(f"Accessory: {acc}")
@@ -709,13 +699,7 @@ def _build_compact(t, ai: int) -> str:
709
699
  parts.append("squircle face")
710
700
  parts.append(f"{_SKIN_DESC.get(t.skin_color, 'warm')} skin")
711
701
  parts.append(f"{_EYE_COLOR_DESC.get(t.eye_color, 'dark')} {_EYE_STYLE_DESC.get(t.eye_style, 'round')} eyes")
712
- if t.hair_style == 0:
713
- parts.append("bald")
714
- else:
715
- raw = _HAIR_STYLE_DESC.get(t.hair_style, "hair")
716
- hs = raw.split(",")[-1].strip() if "," in raw else raw
717
- hc = _HAIR_COLOR_DESC.get(t.hair_color, "")
718
- parts.append(f"{hc} {hs[2:] if hs.startswith('a ') else hs}")
702
+ parts.append("bald")
719
703
  acc = _ACC_DESC.get(ai, "")
720
704
  if acc:
721
705
  parts.append(acc)
@@ -36,7 +36,7 @@ import {
36
36
  "mcpServers": {
37
37
  "solfaces": {
38
38
  "command": "npx",
39
- "args": ["-y", "solfaces"]
39
+ "args": ["-y", "solfaces-mcp"]
40
40
  }
41
41
  }
42
42
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/traits.ts","../src/core/colors.ts","../src/core/renderer.ts"],"names":["djb2"],"mappings":";AAiHO,IAAM,WAAA,GAAc;AAAA,EACzB,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,SAAA;AAAA,EAC5C,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW;AAC9C;AAEO,IAAM,UAAA,GAAa;AAAA,EACxB,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW;AAC9C;AAEO,IAAM,WAAA,GAAc;AAAA,EACzB,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,SAAA;AAAA,EAC5C,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW;AAC9C;AAEO,IAAM,SAAA,GAAY;AAAA,EACvB,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,SAAA;AAAA,EAC5C,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW;AAC9C;AAIA,SAAS,KAAK,GAAA,EAAqB;AACjC,EAAA,IAAI,IAAA,GAAO,IAAA;AACX,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK;AACnC,IAAA,IAAA,GAAA,CAAS,QAAQ,CAAA,IAAK,IAAA,GAAO,GAAA,CAAI,UAAA,CAAW,CAAC,CAAA,GAAK,CAAA;AAAA,EACpD;AACA,EAAA,OAAO,IAAA,KAAS,CAAA;AAClB;AAIA,SAAS,WAAW,IAAA,EAA4B;AAC9C,EAAA,IAAI,IAAI,IAAA,GAAO,CAAA;AACf,EAAA,OAAO,MAAM;AACX,IAAA,CAAA,GAAK,IAAI,UAAA,GAAc,CAAA;AACvB,IAAA,IAAI,IAAI,IAAA,CAAK,IAAA,CAAK,IAAK,CAAA,KAAM,EAAA,EAAK,IAAI,CAAC,CAAA;AACvC,IAAA,CAAA,GAAK,CAAA,GAAI,KAAK,IAAA,CAAK,CAAA,GAAK,MAAM,CAAA,EAAI,EAAA,GAAK,CAAC,CAAA,GAAK,CAAA;AAC7C,IAAA,OAAA,CAAA,CAAS,CAAA,GAAK,CAAA,KAAM,EAAA,MAAS,CAAA,IAAK,UAAA;AAAA,EACpC,CAAA;AACF;AAIO,SAAS,cAAA,CACd,eACA,SAAA,EACe;AACf,EAAA,MAAM,IAAA,GAAO,KAAK,aAAa,CAAA;AAC/B,EAAA,MAAM,IAAA,GAAO,WAAW,IAAI,CAAA;AAI5B,EAAA,MAAM,MAAA,GAAwB;AAAA,IAC5B,SAAA,EAAY,IAAA,CAAK,KAAA,CAAM,IAAA,KAAS,CAAC,CAAA;AAAA,IACjC,SAAA,EAAY,IAAA,CAAK,KAAA,CAAM,IAAA,KAAS,EAAE,CAAA;AAAA,IAClC,QAAA,EAAY,IAAA,CAAK,KAAA,CAAM,IAAA,KAAS,CAAC,CAAA;AAAA,IACjC,QAAA,EAAY,IAAA,CAAK,KAAA,CAAM,IAAA,KAAS,CAAC,CAAA;AAAA,IACjC,QAAA,EAAY,IAAA,CAAK,KAAA,CAAM,IAAA,KAAS,CAAC,CAAA;AAAA,IACjC,IAAA,EAAY,IAAA,CAAK,KAAA,CAAM,IAAA,KAAS,CAAC,CAAA;AAAA,IACjC,KAAA,EAAY,IAAA,CAAK,KAAA,CAAM,IAAA,KAAS,CAAC,CAAA;AAAA,IACjC,SAAA,EAAY,IAAA,CAAK,KAAA,CAAM,IAAA,KAAS,EAAE,CAAA;AAAA,IAClC,SAAA,EAAY,IAAA,CAAK,KAAA,CAAM,IAAA,KAAS,EAAE,CAAA;AAAA,IAClC,SAAA,EAAY,IAAA,CAAK,KAAA,CAAM,IAAA,KAAS,EAAE,CAAA;AAAA,IAClC,OAAA,EAAY,IAAA,CAAK,KAAA,CAAM,IAAA,KAAS,EAAE;AAAA,GACpC;AAEA,EAAA,OAAO,YAAY,EAAE,GAAG,MAAA,EAAQ,GAAG,WAAU,GAAI,MAAA;AACnD;AAKO,SAAS,mBAAmB,MAAA,EAA+B;AAChE,EAAA,MAAM,EAAA,GAAK,OAAO,SAAA,GAAY,EAAA;AAC9B,EAAA,MAAM,EAAA,GAAK,OAAO,SAAA,GAAY,EAAA;AAC9B,EAAA,IAAA,CAAK,EAAA,KAAO,KAAK,EAAA,KAAO,CAAA,MAAO,OAAO,CAAA,IAAK,EAAA,KAAO,IAAI,OAAO,CAAA;AAC7D,EAAA,OAAO,EAAA;AACT;AAIA,IAAM,WAAA,GAAc,CAAC,UAAU,CAAA;AAC/B,IAAM,WAAA,GAAc;AAAA,EAClB,WAAA;AAAA,EAAa,OAAA;AAAA,EAAS,MAAA;AAAA,EAAQ,OAAA;AAAA,EAAS,MAAA;AAAA,EACvC,QAAA;AAAA,EAAU,MAAA;AAAA,EAAQ,SAAA;AAAA,EAAW,OAAA;AAAA,EAAS;AACxC,CAAA;AACA,IAAM,gBAAA,GAAmB,CAAC,OAAA,EAAS,SAAA,EAAW,UAAU,MAAA,EAAQ,SAAA,EAAW,QAAA,EAAU,QAAA,EAAU,QAAQ,CAAA;AACvG,IAAM,mBAAmB,CAAC,WAAA,EAAa,KAAA,EAAO,SAAA,EAAW,SAAS,OAAO,CAAA;AACzE,IAAM,cAAc,CAAC,OAAA,EAAS,UAAA,EAAY,SAAA,EAAW,UAAU,QAAQ,CAAA;AACvE,IAAM,WAAA,GAAc,CAAC,QAAA,EAAU,QAAA,EAAU,QAAQ,UAAU,CAAA;AAC3D,IAAM,YAAA,GAAe,CAAC,OAAA,EAAS,MAAA,EAAQ,SAAS,IAAA,EAAM,OAAA,EAAS,MAAA,EAAQ,MAAA,EAAQ,MAAM,CAAA;AACrF,IAAM,iBAAA,GAAoB;AAAA,EACxB,MAAA;AAAA,EAAQ,OAAA;AAAA,EAAS,OAAA;AAAA,EAAS,YAAA;AAAA,EAAc,MAAA;AAAA,EACxC,MAAA;AAAA,EAAQ,KAAA;AAAA,EAAO,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ;AACjC,CAAA;AACA,IAAM,iBAAA,GAAoB;AAAA,EACxB,OAAA;AAAA,EAAS,UAAA;AAAA,EAAY,QAAA;AAAA,EAAU,OAAA;AAAA,EAAS,QAAA;AAAA,EACxC,QAAA;AAAA,EAAU,UAAA;AAAA,EAAY,UAAA;AAAA,EAAY,YAAA;AAAA,EAAc;AAClD,CAAA;AACA,IAAM,gBAAA,GAAmB;AAAA,EACvB,MAAA;AAAA,EAAQ,aAAA;AAAA,EAAe,eAAA;AAAA,EAAiB,cAAA;AAAA,EAAgB,SAAA;AAAA,EACxD,UAAA;AAAA,EAAY,UAAA;AAAA,EAAY,eAAA;AAAA,EAAiB,UAAA;AAAA,EAAY;AACvD,CAAA;AACA,IAAM,eAAA,GAAkB;AAAA,EACtB,MAAA;AAAA,EAAQ,OAAA;AAAA,EAAS,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EACjC,OAAA;AAAA,EAAS,KAAA;AAAA,EAAO,UAAA;AAAA,EAAY,QAAA;AAAA,EAAU;AACxC,CAAA;AAEO,SAAS,eAAe,MAAA,EAA+C;AAC5E,EAAA,OAAO;AAAA,IACL,SAAA,EAAW,YAAY,CAAC,CAAA;AAAA,IACxB,SAAA,EAAW,WAAA,CAAY,MAAA,CAAO,SAAS,CAAA,IAAK,MAAA;AAAA,IAC5C,QAAA,EAAU,gBAAA,CAAiB,MAAA,CAAO,QAAQ,CAAA,IAAK,OAAA;AAAA,IAC/C,QAAA,EAAU,gBAAA,CAAiB,MAAA,CAAO,QAAQ,CAAA,IAAK,WAAA;AAAA,IAC/C,QAAA,EAAU,WAAA,CAAY,MAAA,CAAO,QAAQ,CAAA,IAAK,OAAA;AAAA,IAC1C,IAAA,EAAM,WAAA,CAAY,MAAA,CAAO,IAAI,CAAA,IAAK,QAAA;AAAA,IAClC,KAAA,EAAO,YAAA,CAAa,MAAA,CAAO,KAAK,CAAA,IAAK,OAAA;AAAA,IACrC,SAAA,EAAW,iBAAA,CAAkB,MAAA,CAAO,SAAS,CAAA,IAAK,MAAA;AAAA,IAClD,SAAA,EAAW,iBAAA,CAAkB,MAAA,CAAO,SAAS,CAAA,IAAK,OAAA;AAAA,IAClD,SAAA,EAAW,gBAAA,CAAiB,kBAAA,CAAmB,MAAM,CAAC,CAAA,IAAK,MAAA;AAAA,IAC3D,OAAA,EAAS,eAAA,CAAgB,MAAA,CAAO,OAAO,CAAA,IAAK;AAAA,GAC9C;AACF;AAIO,SAAS,UAAU,aAAA,EAA+B;AACvD,EAAA,OAAA,CAAQ,IAAA,CAAK,aAAa,CAAA,KAAM,CAAA,EAAG,SAAS,EAAE,CAAA,CAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAA;AACjE;AAIO,SAAS,YAAA,CACd,WACA,MAAA,EAC0B;AAC1B,EAAA,IAAI,CAAC,SAAA,IAAa,CAAC,MAAA,EAAQ,OAAO,MAAA;AAClC,EAAA,OAAO,OAAO,SAAS,CAAA;AACzB;AAEO,SAAS,UAAA,CACd,MACA,SAAA,EACqB;AACrB,EAAA,IAAI,CAAC,IAAA,EAAM,OAAO,SAAA,IAAa,IAAA;AAC/B,EAAA,IAAI,CAAC,WAAW,OAAO,IAAA;AACvB,EAAA,OAAO,EAAE,GAAG,IAAA,EAAM,GAAG,SAAA,EAAU;AACjC;;;AC/PO,SAAS,SAAS,GAAA,EAAuC;AAC9D,EAAA,MAAM,CAAA,GAAI,GAAA,CAAI,OAAA,CAAQ,GAAA,EAAK,EAAE,CAAA;AAC7B,EAAA,OAAO;AAAA,IACL,SAAS,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,GAAG,EAAE,CAAA;AAAA,IAC1B,SAAS,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,GAAG,EAAE,CAAA;AAAA,IAC1B,SAAS,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,GAAG,EAAE;AAAA,GAC5B;AACF;AAEO,SAAS,QAAA,CAAS,CAAA,EAAW,CAAA,EAAW,CAAA,EAAmB;AAChE,EAAA,OACE,GAAA,GACA,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,CACL,GAAA;AAAA,IAAI,CAAC,CAAA,KACJ,IAAA,CAAK,IAAI,CAAA,EAAG,IAAA,CAAK,IAAI,GAAA,EAAK,IAAA,CAAK,MAAM,CAAC,CAAC,CAAC,CAAA,CACrC,QAAA,CAAS,EAAE,CAAA,CACX,QAAA,CAAS,GAAG,GAAG;AAAA,GACpB,CACC,KAAK,EAAE,CAAA;AAEd;AAEO,SAAS,MAAA,CAAO,GAAA,EAAa,GAAA,GAAM,IAAA,EAAc;AACtD,EAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,SAAS,GAAG,CAAA;AAC9B,EAAA,OAAO,QAAA,CAAS,KAAK,CAAA,GAAI,GAAA,CAAA,EAAM,KAAK,CAAA,GAAI,GAAA,CAAA,EAAM,CAAA,IAAK,CAAA,GAAI,GAAA,CAAI,CAAA;AAC7D;AAEO,SAAS,OAAA,CAAQ,GAAA,EAAa,GAAA,GAAM,IAAA,EAAc;AACvD,EAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,SAAS,GAAG,CAAA;AAC9B,EAAA,OAAO,QAAA,CAAS,CAAA,GAAA,CAAK,GAAA,GAAM,CAAA,IAAK,GAAA,EAAK,CAAA,GAAA,CAAK,GAAA,GAAM,CAAA,IAAK,GAAA,EAAK,CAAA,GAAA,CAAK,GAAA,GAAM,CAAA,IAAK,GAAG,CAAA;AAC/E;AAEO,SAAS,KAAA,CAAM,CAAA,EAAW,CAAA,EAAW,CAAA,GAAI,GAAA,EAAa;AAC3D,EAAA,MAAM,CAAC,EAAA,EAAI,EAAA,EAAI,EAAE,CAAA,GAAI,SAAS,CAAC,CAAA;AAC/B,EAAA,MAAM,CAAC,EAAA,EAAI,EAAA,EAAI,EAAE,CAAA,GAAI,SAAS,CAAC,CAAA;AAC/B,EAAA,OAAO,QAAA;AAAA,IACL,EAAA,GAAA,CAAM,KAAK,EAAA,IAAM,CAAA;AAAA,IACjB,EAAA,GAAA,CAAM,KAAK,EAAA,IAAM,CAAA;AAAA,IACjB,EAAA,GAAA,CAAM,KAAK,EAAA,IAAM;AAAA,GACnB;AACF;AAEO,SAAS,UAAU,GAAA,EAAqB;AAC7C,EAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,SAAS,GAAG,CAAA;AAC9B,EAAA,OAAA,CAAQ,CAAA,GAAI,IAAI,CAAA,IAAK,CAAA;AACvB;AAmBO,SAAS,iBAAiB,IAAA,EAA6B;AAC5D,EAAA,MAAM,EAAA,GAAK,UAAU,IAAI,CAAA;AACzB,EAAA,MAAM,SAAS,EAAA,GAAK,GAAA;AAEpB,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,IAAA,EAAM,GAAI,CAAA;AACjC,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,IAAA,EAAM,IAAI,CAAA;AAChC,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,IAAA,EAAM,IAAI,CAAA;AAGjC,EAAA,MAAM,CAAC,EAAA,EAAI,EAAA,EAAI,EAAE,CAAA,GAAI,SAAS,IAAI,CAAA;AAClC,EAAA,IAAI,UAAA;AACJ,EAAA,IAAI,KAAK,GAAA,EAAK;AACZ,IAAA,MAAM,EAAA,GAAK,EAAA,GAAK,GAAA,GAAM,IAAA,GAAO,IAAA;AAC7B,IAAA,MAAM,EAAA,GAAK,EAAA,GAAK,GAAA,GAAM,GAAA,GAAO,IAAA;AAC7B,IAAA,MAAM,EAAA,GAAK,EAAA,GAAK,GAAA,GAAM,IAAA,GAAO,IAAA;AAC7B,IAAA,UAAA,GAAa,QAAA;AAAA,MACX,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,EAAA,GAAK,KAAK,EAAE,CAAA;AAAA,MAC1B,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,EAAA,GAAK,KAAK,EAAE,CAAA;AAAA,MACxB,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,EAAA,GAAK,KAAK,EAAE;AAAA,KAC1B;AAAA,EACF,CAAA,MAAO;AACL,IAAA,UAAA,GAAa,QAAA;AAAA,MACX,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,EAAA,GAAK,EAAE,CAAA;AAAA,MACrB,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,EAAA,GAAK,EAAE,CAAA;AAAA,MACnB,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,EAAA,GAAK,CAAC;AAAA,KACpB;AAAA,EACF;AACA,EAAA,MAAM,YAAA,GAAe,OAAO,IAAA,IAAQ,CAAA,GAAI,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAG,CAAA,CAAA;AAG5D,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAA,CAAI,EAAA,GAAK,EAAA,IAAM,GAAG,CAAC,CAAA;AACrD,EAAA,MAAM,OAAA,GAAU,KAAA,CAAM,SAAA,EAAW,SAAA,EAAW,IAAI,CAAA;AAChD,EAAA,MAAM,WAAW,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,EAAA,GAAK,GAAG,CAAA,GAAI,EAAA;AAC1C,EAAA,MAAM,QAAA,GAAA,CAAY,SAAS,GAAA,GAAO,IAAA,IAAQ,KAAK,GAAA,CAAI,CAAA,EAAG,QAAQ,CAAA,GAAI,IAAA;AAClE,EAAA,MAAM,MAAA,GAAS,MAAM,IAAA,EAAM,OAAA,EAAS,KAAK,GAAA,CAAI,IAAA,EAAM,QAAQ,CAAC,CAAA;AAC5D,EAAA,MAAM,CAAC,EAAA,EAAI,EAAA,EAAI,EAAE,CAAA,GAAI,SAAS,MAAM,CAAA;AACpC,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,EAAA,GAAK,EAAE,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,EAAA,GAAK,EAAE,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,KAAK,EAAE,CAAA;AACrE,EAAA,MAAM,WAAW,IAAA,GAAO,EAAA,GAAK,MAAM,IAAA,EAAM,OAAA,EAAS,IAAI,CAAA,GAAI,MAAA;AAG1D,EAAA,MAAM,SAAA,GAAY,MAAA,GAAS,OAAA,CAAQ,IAAA,EAAM,EAAA,GAAK,EAAA,GAAK,IAAA,GAAO,IAAI,CAAA,GAAI,MAAA,CAAO,IAAA,EAAM,IAAI,CAAA;AACnF,EAAA,MAAM,QAAA,GAAW,SAAS,OAAA,CAAQ,IAAA,EAAM,GAAI,CAAA,GAAI,MAAA,CAAO,MAAM,GAAI,CAAA;AACjE,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAA,CAAI,EAAA,GAAK,GAAA,IAAO,EAAE,CAAC,CAAA;AACrD,EAAA,MAAM,UAAU,KAAA,CAAM,OAAA,CAAQ,MAAM,IAAI,CAAA,EAAG,SAAS,IAAI,CAAA;AACxD,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,IAAA,EAAM,GAAA,GAAO,IAAA,IAAQ,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,EAAA,GAAK,GAAG,CAAA,CAAE,CAAA;AACxE,EAAA,MAAM,QAAA,GAAW,SAAS,OAAA,CAAQ,IAAA,EAAM,IAAI,CAAA,GAAI,MAAA,CAAO,MAAM,IAAI,CAAA;AAGjE,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAA,CAAI,EAAA,GAAK,EAAA,IAAM,GAAG,CAAC,CAAA;AACpD,EAAA,MAAM,eAAA,GAAkB,KAAA,CAAM,SAAA,EAAW,SAAA,EAAW,GAAG,CAAA;AAGvD,EAAA,MAAM,SAAS,EAAA,GAAK,GAAA,GAAM,GAAA,GAAM,EAAA,GAAK,MAAM,GAAA,GAAM,GAAA;AACjD,EAAA,MAAM,cAAA,GAAiB,MAAM,SAAA,EAAW,KAAA,CAAM,MAAM,SAAA,EAAW,GAAG,GAAG,MAAM,CAAA;AAE3E,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IAAQ,MAAA;AAAA,IAAQ,OAAA;AAAA,IAAS,MAAA;AAAA,IACzB,UAAA;AAAA,IAAY,YAAA;AAAA,IACZ,QAAA;AAAA,IAAU,QAAA;AAAA,IAAU,SAAA;AAAA,IACpB,OAAA;AAAA,IAAS,SAAA;AAAA,IACT,eAAA;AAAA,IAAiB,QAAA;AAAA,IACjB;AAAA,GACF;AACF;AAGO,SAAS,WAAA,CAAY,SAAiB,IAAA,EAAsB;AACjE,EAAA,MAAM,CAAC,EAAA,EAAI,EAAA,EAAI,EAAE,CAAA,GAAI,SAAS,OAAO,CAAA;AACrC,EAAA,MAAM,CAAC,EAAA,EAAI,EAAA,EAAI,EAAE,CAAA,GAAI,SAAS,IAAI,CAAA;AAClC,EAAA,OAAO,KAAK,GAAA,CAAI,EAAA,GAAK,EAAE,CAAA,GAAI,KAAK,GAAA,CAAI,EAAA,GAAK,EAAE,CAAA,GAAI,KAAK,GAAA,CAAI,EAAA,GAAK,EAAE,CAAA,GAAI,KAC/D,GAAA,GACA,GAAA;AACN;;;ACxHA,SAASA,MAAK,GAAA,EAAqB;AACjC,EAAA,IAAI,IAAA,GAAO,IAAA;AACX,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK;AACnC,IAAA,IAAA,GAAA,CAAS,QAAQ,CAAA,IAAK,IAAA,GAAO,GAAA,CAAI,UAAA,CAAW,CAAC,CAAA,GAAK,CAAA;AAAA,EACpD;AACA,EAAA,OAAO,IAAA,KAAS,CAAA;AAClB;AAIA,SAAS,SAAA,CACP,EAAA,EACA,IAAA,EACA,MAAA,EACA,MAAA,EACA,OAAA,EACA,KAAA,EACA,UAAA,EACA,YAAA,EACA,IAAA,EACA,IAAA,EACA,aAAA,EACQ;AACR,EAAA,IAAI,MAAM,OAAO,EAAA;AAEjB,EAAA,IAAI,CAAA,GAAI,QAAA;AAGR,EAAA,CAAA,IAAK,uBAAuB,EAAE,CAAA,gCAAA,CAAA;AAC9B,EAAA,CAAA,IAAK,iCAAiC,MAAM,CAAA,GAAA,CAAA;AAC5C,EAAA,CAAA,IAAK,mCAAmC,MAAM,CAAA,GAAA,CAAA;AAC9C,EAAA,CAAA,IAAK,CAAA,iBAAA,CAAA;AAGL,EAAA,CAAA,IAAK,uBAAuB,EAAE,CAAA,gCAAA,CAAA;AAC9B,EAAA,CAAA,IAAK,CAAA,8BAAA,EAAiC,OAAA,CAAQ,OAAA,EAAS,IAAI,CAAC,CAAA,GAAA,CAAA;AAC5D,EAAA,CAAA,IAAK,CAAA,gCAAA,EAAmC,MAAA,CAAO,OAAA,EAAS,IAAI,CAAC,CAAA,GAAA,CAAA;AAC7D,EAAA,CAAA,IAAK,CAAA,iBAAA,CAAA;AAGL,EAAA,CAAA,IAAK,uBAAuB,EAAE,CAAA,gCAAA,CAAA;AAC9B,EAAA,CAAA,IAAK,CAAA,8BAAA,EAAiC,OAAA,CAAQ,KAAA,EAAO,IAAI,CAAC,CAAA,GAAA,CAAA;AAC1D,EAAA,CAAA,IAAK,CAAA,gCAAA,EAAmC,MAAA,CAAO,KAAA,EAAO,IAAI,CAAC,CAAA,GAAA,CAAA;AAC3D,EAAA,CAAA,IAAK,CAAA,iBAAA,CAAA;AAEL,EAAA,IAAI,IAAA,EAAM;AAER,IAAA,CAAA,IAAK,uBAAuB,EAAE,CAAA,kCAAA,CAAA;AAC9B,IAAA,CAAA,IAAK,wDAAwD,aAAa,CAAA,GAAA,CAAA;AAC1E,IAAA,CAAA,IAAK,CAAA,2DAAA,CAAA;AACL,IAAA,CAAA,IAAK,CAAA,iBAAA,CAAA;AAGL,IAAA,CAAA,IAAK,uBAAuB,EAAE,CAAA,kCAAA,CAAA;AAC9B,IAAA,CAAA,IAAK,iCAAiC,MAAM,CAAA,uBAAA,CAAA;AAC5C,IAAA,CAAA,IAAK,mCAAmC,MAAM,CAAA,oBAAA,CAAA;AAC9C,IAAA,CAAA,IAAK,CAAA,iBAAA,CAAA;AAGL,IAAA,CAAA,IAAK,uBAAuB,EAAE,CAAA,8BAAA,CAAA;AAC9B,IAAA,CAAA,IAAK,iCAAiC,UAAU,CAAA,gBAAA,EAAmB,YAAA,CAAa,OAAA,CAAQ,CAAC,CAAC,CAAA,GAAA,CAAA;AAC1F,IAAA,CAAA,IAAK,mCAAmC,UAAU,CAAA,oBAAA,CAAA;AAClD,IAAA,CAAA,IAAK,CAAA,iBAAA,CAAA;AAGL,IAAA,CAAA,IAAK,uBAAuB,EAAE,CAAA,8BAAA,CAAA;AAC9B,IAAA,CAAA,IAAK,iCAAiC,UAAU,CAAA,gBAAA,EAAmB,YAAA,CAAa,OAAA,CAAQ,CAAC,CAAC,CAAA,GAAA,CAAA;AAC1F,IAAA,CAAA,IAAK,mCAAmC,UAAU,CAAA,oBAAA,CAAA;AAClD,IAAA,CAAA,IAAK,CAAA,iBAAA,CAAA;AAAA,EACP;AAEA,EAAA,CAAA,IAAK,SAAA;AACL,EAAA,OAAO,CAAA;AACT;AAIA,SAAS,cAAA,CAAe,EAAA,EAAY,EAAA,EAAY,IAAA,EAAuB;AACrE,EAAA,MAAM,IAAA,GAAO,IAAA,GAAO,cAAA,GAAiB,CAAA,KAAA,EAAQ,EAAE,CAAA,GAAA,CAAA;AAC/C,EAAA,QAAQ,EAAA;AAAI,IACV,KAAK,CAAA;AACH,MAAA,OAAO,YAAY,IAAI,CAAA,yDAAA,CAAA;AAAA,IACzB,KAAK,CAAA;AACH,MAAA,OAAO,YAAY,IAAI,CAAA,yDAAA,CAAA;AAAA,IACzB,KAAK,CAAA;AACH,MAAA,OAAO,YAAY,IAAI,CAAA,yDAAA,CAAA;AAAA,IACzB;AACE,MAAA,OAAO,EAAA;AAAA;AAEb;AAIA,SAAS,UAAA,CAAW,SAAiB,SAAA,EAA2B;AAC9D,EAAA,OACE,gDAAgD,OAAO,CAAA,oDAAA,EACH,SAAS,CAAA,8DAAA,EACb,OAAO,uDACH,SAAS,CAAA,iBAAA,CAAA;AAEjE;AAIA,SAAS,UAAA,CAAW,EAAA,EAAY,IAAA,EAAc,IAAA,EAAe,UAAkB,CAAA,EAAW;AACxF,EAAA,MAAM,IAAA,GAAO,IAAA,GAAO,IAAA,GAAO,CAAA,KAAA,EAAQ,EAAE,CAAA,GAAA,CAAA;AACrC,EAAA,MAAM,MAAA,GAAS,OAAA,GAAU,CAAA,GAAI,CAAA,UAAA,EAAa,OAAO,CAAA,CAAA,CAAA,GAAM,EAAA;AACvD,EAAA,OAAO,CAAA,iEAAA,EAAoE,IAAI,CAAA,CAAA,EAAI,MAAM,CAAA,EAAA,CAAA;AAC3F;AAIA,SAAS,kBAAA,CAAmB,IAAY,IAAA,EAAuB;AAC7D,EAAA,IAAI,MAAM,OAAO,EAAA;AACjB,EAAA,OACE,yEAAyE,EAAE,CAAA,8EAAA,EACF,EAAE,CAAA,4DAAA,EACpB,EAAE,6DACF,EAAE,CAAA,4HAAA,CAAA;AAG7D;AAIA,SAAS,eAAA,CAAgB,EAAA,EAAY,EAAA,EAAY,OAAA,EAAiB,MAAc,IAAA,EAAuB;AACrG,EAAA,MAAM,IAAA,GAAO,IAAA,GAAO,OAAA,GAAU,CAAA,KAAA,EAAQ,EAAE,CAAA,GAAA,CAAA;AACxC,EAAA,QAAQ,EAAA;AAAI,IACV,KAAK,CAAA;AAAG,MAAA,OAAO,EAAA;AAAA;AAAA,IACf,KAAK,CAAA;AACH,MAAA,OAAO,uFAAuF,IAAI,CAAA,GAAA,CAAA;AAAA,IACpG,KAAK,CAAA;AACH,MAAA,OACE,YAAY,IAAI,CAAA,oMAAA,CAAA;AAAA,IASpB,KAAK,CAAA;AACH,MAAA,OACE,CAAA,mFAAA,EAAsF,IAAI,CAAA,oDAAA,EACtC,IAAI,CAAA,GAAA,CAAA;AAAA,IAE5D,KAAK,CAAA;AACH,MAAA,OAAO,iDAAiD,IAAI,CAAA,GAAA,CAAA;AAAA,IAC9D,KAAK,CAAA;AACH,MAAA,OAAO,sFAAsF,IAAI,CAAA,GAAA,CAAA;AAAA,IACnG,KAAK,CAAA;AACH,MAAA,OACE,CAAA,mFAAA,EAAsF,IAAI,CAAA,0DAAA,EAChC,IAAI,6DACJ,IAAI,CAAA,GAAA,CAAA;AAAA,IAElE,KAAK,CAAA,EAAG;AACN,MAAA,MAAM,GAAA,GAAM,WAAA,CAAY,OAAA,EAAS,IAAI,CAAA;AACrC,MAAA,OAAO,mEAAmE,OAAO,CAAA,WAAA,EAAc,GAAA,CAAI,OAAA,CAAQ,CAAC,CAAC,CAAA,GAAA,CAAA;AAAA,IAC/G;AAAA,IACA,KAAK,CAAA;AACH,MAAA,OACE,CAAA,mFAAA,EAAsF,IAAI,CAAA,qDAAA,EACrC,IAAI,gGACJ,IAAI,CAAA,2CAAA,CAAA;AAAA,IAE7D,KAAK,CAAA;AACH,MAAA,OACE,CAAA,oFAAA,EAAuF,IAAI,CAAA,+CAAA,EAC5C,IAAI,CAAA,GAAA,CAAA;AAAA,IAEvD;AAAS,MAAA,OAAO,EAAA;AAAA;AAEpB;AAIA,SAAS,UAAA,CACP,EAAA,EACA,MAAA,EACA,QAAA,EACA,UACA,IAAA,EACQ;AACR,EAAA,MAAM,EAAA,GAAK,EAAA,EAAI,EAAA,GAAK,EAAA,EAAI,CAAA,GAAI,EAAA;AAC5B,EAAA,IAAI,CAAA,GAAI,EAAA;AAER,EAAA,QAAQ,EAAA;AAAI,IACV,KAAK,CAAA;AACH,MAAA,CAAA,IAAK,CAAA,YAAA,EAAe,EAAE,CAAA,MAAA,EAAS,CAAC,iBAAiB,QAAQ,CAAA,GAAA,CAAA;AACzD,MAAA,CAAA,IAAK,eAAe,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAC,mBAAmB,MAAM,CAAA,GAAA,CAAA;AAC/D,MAAA,IAAI,MAAM,CAAA,IAAK,CAAA,YAAA,EAAe,KAAK,GAAG,CAAA,MAAA,EAAS,IAAI,CAAC,CAAA,sCAAA,CAAA;AACpD,MAAA,CAAA,IAAK,CAAA,YAAA,EAAe,EAAE,CAAA,MAAA,EAAS,CAAC,iBAAiB,QAAQ,CAAA,GAAA,CAAA;AACzD,MAAA,CAAA,IAAK,eAAe,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAC,mBAAmB,MAAM,CAAA,GAAA,CAAA;AAC/D,MAAA,IAAI,MAAM,CAAA,IAAK,CAAA,YAAA,EAAe,KAAK,GAAG,CAAA,MAAA,EAAS,IAAI,CAAC,CAAA,sCAAA,CAAA;AACpD,MAAA;AAAA,IACF,KAAK,CAAA;AACH,MAAA,CAAA,IAAK,CAAA,YAAA,EAAe,EAAE,CAAA,MAAA,EAAS,CAAC,iBAAiB,MAAM,CAAA,GAAA,CAAA;AACvD,MAAA,CAAA,IAAK,CAAA,YAAA,EAAe,EAAE,CAAA,MAAA,EAAS,CAAC,iBAAiB,MAAM,CAAA,GAAA,CAAA;AACvD,MAAA;AAAA,IACF,KAAK,CAAA;AACH,MAAA,CAAA,IAAK,CAAA,aAAA,EAAgB,EAAE,CAAA,MAAA,EAAS,CAAC,6BAA6B,QAAQ,CAAA,GAAA,CAAA;AACtE,MAAA,CAAA,IAAK,eAAe,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAC,mBAAmB,MAAM,CAAA,GAAA,CAAA;AAC/D,MAAA,IAAI,MAAM,CAAA,IAAK,CAAA,YAAA,EAAe,KAAK,GAAG,CAAA,MAAA,EAAS,IAAI,GAAG,CAAA,sCAAA,CAAA;AACtD,MAAA,CAAA,IAAK,CAAA,aAAA,EAAgB,EAAE,CAAA,MAAA,EAAS,CAAC,6BAA6B,QAAQ,CAAA,GAAA,CAAA;AACtE,MAAA,CAAA,IAAK,eAAe,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAC,mBAAmB,MAAM,CAAA,GAAA,CAAA;AAC/D,MAAA,IAAI,MAAM,CAAA,IAAK,CAAA,YAAA,EAAe,KAAK,GAAG,CAAA,MAAA,EAAS,IAAI,GAAG,CAAA,sCAAA,CAAA;AACtD,MAAA;AAAA,IACF,KAAK,CAAA;AACH,MAAA,CAAA,IAAK,CAAA,YAAA,EAAe,EAAE,CAAA,MAAA,EAAS,CAAC,iBAAiB,QAAQ,CAAA,GAAA,CAAA;AACzD,MAAA,CAAA,IAAK,eAAe,EAAE,CAAA,MAAA,EAAS,CAAA,GAAI,GAAG,mBAAmB,MAAM,CAAA,GAAA,CAAA;AAC/D,MAAA,IAAI,MAAM,CAAA,IAAK,CAAA,YAAA,EAAe,KAAK,GAAG,CAAA,MAAA,EAAS,IAAI,CAAC,CAAA,sCAAA,CAAA;AACpD,MAAA,CAAA,IAAK,CAAA,YAAA,EAAe,EAAE,CAAA,MAAA,EAAS,CAAC,iBAAiB,QAAQ,CAAA,GAAA,CAAA;AACzD,MAAA,CAAA,IAAK,eAAe,EAAE,CAAA,MAAA,EAAS,CAAA,GAAI,GAAG,mBAAmB,MAAM,CAAA,GAAA,CAAA;AAC/D,MAAA,IAAI,MAAM,CAAA,IAAK,CAAA,YAAA,EAAe,KAAK,GAAG,CAAA,MAAA,EAAS,IAAI,CAAC,CAAA,sCAAA,CAAA;AACpD,MAAA;AAAA,IACF,KAAK,CAAA;AACH,MAAA,CAAA,IAAK,gBAAgB,EAAE,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,2BAA2B,QAAQ,CAAA,GAAA,CAAA;AACxE,MAAA,CAAA,IAAK,eAAe,EAAE,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,mBAAmB,MAAM,CAAA,GAAA,CAAA;AAC7D,MAAA,IAAI,IAAA,EAAM,CAAA,IAAK,CAAA,UAAA,EAAa,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAA,GAAI,GAAG,CAAA,MAAA,EAAS,KAAK,GAAG,CAAA,MAAA,EAAS,CAAA,GAAI,GAAG,aAAa,QAAQ,CAAA,6CAAA,CAAA;AAC1G,MAAA,CAAA,IAAK,gBAAgB,EAAE,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,2BAA2B,QAAQ,CAAA,GAAA,CAAA;AACxE,MAAA,CAAA,IAAK,eAAe,EAAE,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,mBAAmB,MAAM,CAAA,GAAA,CAAA;AAC7D,MAAA,IAAI,IAAA,EAAM,CAAA,IAAK,CAAA,UAAA,EAAa,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAA,GAAI,GAAG,CAAA,MAAA,EAAS,KAAK,GAAG,CAAA,MAAA,EAAS,CAAA,GAAI,GAAG,aAAa,QAAQ,CAAA,6CAAA,CAAA;AAC1G,MAAA;AAAA,IACF,KAAK,CAAA;AACH,MAAA,CAAA,IAAK,aAAa,EAAA,GAAK,CAAC,CAAA,CAAA,EAAI,CAAC,KAAK,EAAE,CAAA,CAAA,EAAI,CAAA,GAAI,CAAC,IAAI,EAAA,GAAK,CAAC,CAAA,CAAA,EAAI,CAAC,yBAAyB,MAAM,CAAA,6CAAA,CAAA;AAC3F,MAAA,CAAA,IAAK,aAAa,EAAA,GAAK,CAAC,CAAA,CAAA,EAAI,CAAC,KAAK,EAAE,CAAA,CAAA,EAAI,CAAA,GAAI,CAAC,IAAI,EAAA,GAAK,CAAC,CAAA,CAAA,EAAI,CAAC,yBAAyB,MAAM,CAAA,6CAAA,CAAA;AAC3F,MAAA;AAAA,IACF,KAAK,CAAA;AACH,MAAA,CAAA,IAAK,CAAA,YAAA,EAAe,EAAE,CAAA,MAAA,EAAS,CAAC,mBAAmB,QAAQ,CAAA,GAAA,CAAA;AAC3D,MAAA,CAAA,IAAK,eAAe,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAC,iBAAiB,MAAM,CAAA,GAAA,CAAA;AAC7D,MAAA,CAAA,IAAK,CAAA,YAAA,EAAe,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,IAAI,CAAC,CAAA,oCAAA,CAAA;AAC1C,MAAA,IAAI,IAAA,EAAM;AACR,QAAA,CAAA,IAAK,CAAA,UAAA,EAAa,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAA,GAAI,GAAG,CAAA,MAAA,EAAS,EAAA,GAAK,CAAC,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,aAAa,MAAM,CAAA,6CAAA,CAAA;AAC1F,QAAA,CAAA,IAAK,CAAA,UAAA,EAAa,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAA,GAAI,GAAG,CAAA,MAAA,EAAS,EAAA,GAAK,CAAC,CAAA,MAAA,EAAS,CAAA,GAAI,GAAG,aAAa,MAAM,CAAA,6CAAA,CAAA;AAAA,MAC9F;AACA,MAAA,CAAA,IAAK,CAAA,YAAA,EAAe,EAAE,CAAA,MAAA,EAAS,CAAC,mBAAmB,QAAQ,CAAA,GAAA,CAAA;AAC3D,MAAA,CAAA,IAAK,eAAe,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAC,iBAAiB,MAAM,CAAA,GAAA,CAAA;AAC7D,MAAA,CAAA,IAAK,CAAA,YAAA,EAAe,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,IAAI,CAAC,CAAA,oCAAA,CAAA;AAC1C,MAAA,IAAI,IAAA,EAAM;AACR,QAAA,CAAA,IAAK,CAAA,UAAA,EAAa,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAA,GAAI,GAAG,CAAA,MAAA,EAAS,EAAA,GAAK,CAAC,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,aAAa,MAAM,CAAA,6CAAA,CAAA;AAC1F,QAAA,CAAA,IAAK,CAAA,UAAA,EAAa,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAA,GAAI,GAAG,CAAA,MAAA,EAAS,EAAA,GAAK,CAAC,CAAA,MAAA,EAAS,CAAA,GAAI,GAAG,aAAa,MAAM,CAAA,6CAAA,CAAA;AAAA,MAC9F;AACA,MAAA;AAAA,IACF,KAAK,CAAA;AACH,MAAA,CAAA,IAAK,CAAA,aAAA,EAAgB,EAAE,CAAA,MAAA,EAAS,CAAC,6BAA6B,QAAQ,CAAA,GAAA,CAAA;AACtE,MAAA,CAAA,IAAK,gBAAgB,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAC,6BAA6B,MAAM,CAAA,GAAA,CAAA;AAC1E,MAAA,CAAA,IAAK,CAAA,aAAA,EAAgB,EAAE,CAAA,MAAA,EAAS,CAAC,6BAA6B,QAAQ,CAAA,GAAA,CAAA;AACtE,MAAA,CAAA,IAAK,gBAAgB,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAC,6BAA6B,MAAM,CAAA,GAAA,CAAA;AAC1E,MAAA;AAAA,IACF;AACE,MAAA,CAAA,IAAK,CAAA,YAAA,EAAe,EAAE,CAAA,MAAA,EAAS,CAAC,mBAAmB,QAAQ,CAAA,GAAA,CAAA;AAC3D,MAAA,CAAA,IAAK,eAAe,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAC,iBAAiB,MAAM,CAAA,GAAA,CAAA;AAC7D,MAAA,CAAA,IAAK,CAAA,YAAA,EAAe,EAAE,CAAA,MAAA,EAAS,CAAC,mBAAmB,QAAQ,CAAA,GAAA,CAAA;AAC3D,MAAA,CAAA,IAAK,eAAe,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAC,iBAAiB,MAAM,CAAA,GAAA,CAAA;AAAA;AAIjE,EAAA,IAAI,IAAA,IAAQ,EAAA,KAAO,CAAA,IAAK,EAAA,KAAO,CAAA,EAAG;AAChC,IAAA,CAAA,IAAK,aAAa,EAAA,GAAK,CAAC,IAAI,CAAA,GAAI,GAAG,KAAK,EAAE,CAAA,CAAA,EAAI,CAAA,GAAI,CAAC,IAAI,EAAA,GAAK,CAAC,IAAI,CAAA,GAAI,GAAG,yBAAyB,QAAQ,CAAA,oCAAA,CAAA;AACzG,IAAA,CAAA,IAAK,aAAa,EAAA,GAAK,CAAC,IAAI,CAAA,GAAI,GAAG,KAAK,EAAE,CAAA,CAAA,EAAI,CAAA,GAAI,CAAC,IAAI,EAAA,GAAK,CAAC,IAAI,CAAA,GAAI,GAAG,yBAAyB,QAAQ,CAAA,oCAAA,CAAA;AAAA,EAC3G;AAEA,EAAA,OAAO,CAAA;AACT;AAIA,SAAS,cAAA,CAAe,IAAY,SAAA,EAA2B;AAC7D,EAAA,MAAM,EAAA,GAAK,EAAA,EAAI,EAAA,GAAK,EAAA,EAAI,CAAA,GAAI,EAAA;AAC5B,EAAA,QAAQ,EAAA;AAAI,IACV,KAAK,CAAA;AACH,MAAA,OACE,CAAA,UAAA,EAAa,EAAA,GAAK,CAAC,CAAA,MAAA,EAAS,CAAC,SAAS,EAAA,GAAK,CAAC,CAAA,MAAA,EAAS,CAAA,GAAI,GAAG,CAAA,UAAA,EAAa,SAAS,CAAA,uDAAA,EACrE,EAAA,GAAK,CAAC,CAAA,MAAA,EAAS,CAAA,GAAI,GAAG,CAAA,MAAA,EAAS,EAAA,GAAK,CAAC,CAAA,MAAA,EAAS,CAAC,CAAA,UAAA,EAAa,SAAS,CAAA,6CAAA,CAAA;AAAA,IAEtF,KAAK,CAAA;AACH,MAAA,OACE,CAAA,UAAA,EAAa,KAAK,GAAG,CAAA,MAAA,EAAS,CAAC,CAAA,MAAA,EAAS,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAC,CAAA,UAAA,EAAa,SAAS,CAAA,uDAAA,EACnE,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAC,CAAA,MAAA,EAAS,KAAK,GAAG,CAAA,MAAA,EAAS,CAAC,CAAA,UAAA,EAAa,SAAS,CAAA,6CAAA,CAAA;AAAA,IAEpF,KAAK,CAAA;AACH,MAAA,OACE,aAAa,EAAA,GAAK,GAAG,CAAA,CAAA,EAAI,CAAA,GAAI,GAAG,CAAA,EAAA,EAAK,EAAE,CAAA,CAAA,EAAI,CAAA,GAAI,GAAG,CAAA,CAAA,EAAI,EAAA,GAAK,GAAG,CAAA,CAAA,EAAI,IAAI,GAAG,CAAA,sBAAA,EAAyB,SAAS,CAAA,uDAAA,EAC9F,KAAK,GAAG,CAAA,CAAA,EAAI,CAAA,GAAI,GAAG,KAAK,EAAE,CAAA,CAAA,EAAI,CAAA,GAAI,GAAG,IAAI,EAAA,GAAK,GAAG,IAAI,CAAA,GAAI,GAAG,yBAAyB,SAAS,CAAA,6CAAA,CAAA;AAAA,IAE/G,KAAK,CAAA;AACH,MAAA,OACE,aAAa,EAAA,GAAK,CAAC,CAAA,CAAA,EAAI,CAAA,GAAI,CAAC,CAAA,EAAA,EAAK,EAAE,CAAA,CAAA,EAAI,CAAA,GAAI,CAAC,CAAA,CAAA,EAAI,EAAA,GAAK,CAAC,CAAA,CAAA,EAAI,IAAI,CAAC,CAAA,sBAAA,EAAyB,SAAS,CAAA,qDAAA,EACpF,KAAK,CAAC,CAAA,CAAA,EAAI,CAAA,GAAI,CAAC,KAAK,EAAE,CAAA,CAAA,EAAI,CAAA,GAAI,CAAC,IAAI,EAAA,GAAK,CAAC,IAAI,CAAA,GAAI,CAAC,yBAAyB,SAAS,CAAA,2CAAA,CAAA;AAAA,IAErG,KAAK,CAAA;AACH,MAAA,OACE,CAAA,kBAAA,EAAqB,EAAA,GAAK,CAAC,CAAA,CAAA,EAAI,IAAI,CAAC,CAAA,CAAA,EAAI,EAAE,CAAA,CAAA,EAAI,IAAI,CAAC,CAAA,CAAA,EAAI,EAAA,GAAK,CAAC,IAAI,CAAC,CAAA,sBAAA,EAAyB,SAAS,CAAA,uFAAA,EAC/E,KAAK,CAAC,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA,EAAI,EAAE,CAAA,CAAA,EAAI,CAAA,GAAI,CAAC,CAAA,CAAA,EAAI,KAAK,CAAC,CAAA,CAAA,EAAI,CAAA,GAAI,CAAC,yBAAyB,SAAS,CAAA,qEAAA,CAAA;AAAA,IAExG;AACE,MAAA,OAAO,EAAA;AAAA;AAEb;AAIA,SAAS,UAAA,CAAW,IAAY,QAAA,EAA0B;AACxD,EAAA,MAAM,EAAA,GAAK,IAAI,CAAA,GAAI,EAAA;AACnB,EAAA,QAAQ,EAAA;AAAI,IACV,KAAK,CAAA;AACH,MAAA,OAAO,CAAA,aAAA,EAAgB,EAAE,CAAA,MAAA,EAAS,CAAC,2BAA2B,QAAQ,CAAA,kBAAA,CAAA;AAAA,IACxE,KAAK,CAAA;AACH,MAAA,OAAO,CAAA,YAAA,EAAe,EAAE,CAAA,MAAA,EAAS,CAAC,mBAAmB,QAAQ,CAAA,iBAAA,CAAA;AAAA,IAC/D,KAAK,CAAA;AACH,MAAA,OAAO,aAAa,EAAA,GAAK,CAAC,IAAI,CAAA,GAAI,CAAC,KAAK,EAAE,CAAA,CAAA,EAAI,CAAA,GAAI,CAAC,IAAI,EAAA,GAAK,CAAC,IAAI,CAAA,GAAI,CAAC,yBAAyB,QAAQ,CAAA,yDAAA,CAAA;AAAA,IACzG,KAAK,CAAA;AACH,MAAA,OACE,CAAA,YAAA,EAAe,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAC,CAAA,gBAAA,EAAmB,QAAQ,CAAA,6BAAA,EAC7C,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,CAAC,mBAAmB,QAAQ,CAAA,iBAAA,CAAA;AAAA,IAEhE;AACE,MAAA,OAAO,CAAA,aAAA,EAAgB,EAAE,CAAA,MAAA,EAAS,CAAC,2BAA2B,QAAQ,CAAA,kBAAA,CAAA;AAAA;AAE5E;AAIA,SAAS,WAAA,CAAY,EAAA,EAAY,QAAA,EAAkB,MAAA,EAAyB;AAC1E,EAAA,MAAM,EAAA,GAAK,IAAI,CAAA,GAAI,EAAA;AACnB,EAAA,MAAM,QAAA,GAAW,SAAS,SAAA,GAAY,SAAA;AACtC,EAAA,QAAQ,EAAA;AAAI,IACV,KAAK,CAAA;AACH,MAAA,OAAO,aAAa,EAAA,GAAK,CAAC,CAAA,CAAA,EAAI,CAAC,KAAK,EAAE,CAAA,CAAA,EAAI,CAAA,GAAI,CAAC,IAAI,EAAA,GAAK,CAAC,CAAA,CAAA,EAAI,CAAC,yBAAyB,QAAQ,CAAA,6CAAA,CAAA;AAAA,IACjG,KAAK,CAAA;AACH,MAAA,OAAO,CAAA,UAAA,EAAa,EAAA,GAAK,CAAC,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,CAAA,MAAA,EAAS,EAAA,GAAK,CAAC,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,aAAa,QAAQ,CAAA,6CAAA,CAAA;AAAA,IAC5F,KAAK,CAAA;AACH,MAAA,OAAO,aAAa,EAAA,GAAK,CAAC,CAAA,CAAA,EAAI,CAAC,KAAK,EAAE,CAAA,CAAA,EAAI,CAAA,GAAI,CAAC,IAAI,EAAA,GAAK,CAAC,CAAA,CAAA,EAAI,CAAC,yBAAyB,QAAQ,CAAA,6CAAA,CAAA;AAAA,IACjG,KAAK,CAAA;AACH,MAAA,OAAO,gBAAgB,EAAE,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,2BAA2B,QAAQ,CAAA,iBAAA,CAAA;AAAA,IAC5E,KAAK,CAAA;AACH,MAAA,OAAO,aAAa,EAAA,GAAK,CAAC,IAAI,CAAA,GAAI,CAAC,KAAK,EAAA,GAAK,CAAC,IAAI,CAAA,GAAI,CAAC,IAAI,EAAA,GAAK,CAAC,IAAI,CAAA,GAAI,GAAG,yBAAyB,QAAQ,CAAA,6CAAA,CAAA;AAAA,IAC/G,KAAK,CAAA;AACH,MAAA,OACE,CAAA,UAAA,EAAa,EAAA,GAAK,CAAC,CAAA,CAAA,EAAI,CAAC,CAAA,EAAA,EAAK,EAAE,CAAA,CAAA,EAAI,CAAA,GAAI,CAAC,CAAA,CAAA,EAAI,EAAA,GAAK,CAAC,IAAI,CAAC,CAAA,QAAA,EAAW,QAAQ,CAAA,UAAA,EAAa,QAAQ,CAAA,8BAAA,EAClF,EAAA,GAAK,CAAC,SAAS,CAAA,GAAI,GAAG,CAAA,MAAA,EAAS,EAAA,GAAK,CAAC,CAAA,MAAA,EAAS,CAAA,GAAI,GAAG,aAAa,QAAQ,CAAA,oCAAA,CAAA;AAAA,IAE3F,KAAK,CAAA;AACH,MAAA,OAAO,CAAA,UAAA,EAAa,EAAA,GAAK,CAAC,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,CAAA,MAAA,EAAS,EAAA,GAAK,CAAC,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,aAAa,QAAQ,CAAA,6CAAA,CAAA;AAAA,IAC5F,KAAK,CAAA;AACH,MAAA,OACE,CAAA,aAAA,EAAgB,EAAE,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,CAAA,wBAAA,EAA2B,QAAQ,CAAA,4BAAA,EACtD,EAAA,GAAK,CAAC,CAAA,CAAA,EAAI,CAAC,CAAA,EAAA,EAAK,EAAE,CAAA,CAAA,EAAI,CAAA,GAAI,GAAG,CAAA,CAAA,EAAI,KAAK,CAAC,CAAA,CAAA,EAAI,CAAC,CAAA,sBAAA,EAAyB,QAAQ,CAAA,6CAAA,CAAA;AAAA,IAE9F;AACE,MAAA,OAAO,aAAa,EAAA,GAAK,CAAC,CAAA,CAAA,EAAI,CAAC,KAAK,EAAE,CAAA,CAAA,EAAI,CAAA,GAAI,CAAC,IAAI,EAAA,GAAK,CAAC,CAAA,CAAA,EAAI,CAAC,yBAAyB,QAAQ,CAAA,6CAAA,CAAA;AAAA;AAErG;AAIA,SAAS,eAAA,CACP,EAAA,EACA,cAAA,EACA,YAAA,EACA,cACA,aAAA,EACQ;AACR,EAAA,QAAQ,EAAA;AAAI,IACV,KAAK,CAAA;AAAG,MAAA,OAAO,EAAA;AAAA;AAAA,IACf,KAAK,CAAA;AACH,MAAA,OAAO,CAAA,gDAAA,CAAA;AAAA,IACT,KAAK,CAAA;AACH,MAAA,OACE,0BAA0B,YAAY,CAAA,sNAAA,CAAA;AAAA,IAQ1C,KAAK,CAAA;AACH,MAAA,OACE,0BAA0B,YAAY,CAAA,oPAAA,CAAA;AAAA,IAQ1C,KAAK,CAAA;AACH,MAAA,OACE,CAAA,sCAAA,EAAyC,YAAY,CAAA,uCAAA,EACd,YAAY,CAAA,iBAAA,CAAA;AAAA,IAEvD,KAAK,CAAA;AACH,MAAA,OAAO,8DAA8D,aAAa,CAAA,kBAAA,CAAA;AAAA,IACpF,KAAK,CAAA;AACH,MAAA,OACE,CAAA,+OAAA,CAAA;AAAA,IASJ,KAAK,CAAA;AACH,MAAA,OACE,CAAA,sCAAA,EAAyC,YAAY,CAAA,yCAAA,EACZ,YAAY,CAAA,GAAA,CAAA;AAAA,IAEzD,KAAK,CAAA;AACH,MAAA,OACE,CAAA,uBAAA,EAA0B,YAAY,CAAA,kGAAA,EAC0C,YAAY,uGACZ,YAAY,CAAA,gJAAA,CAAA;AAAA,IAMhG,KAAK,CAAA;AACH,MAAA,OACE,CAAA,gaAAA,CAAA;AAAA,IAOJ;AACE,MAAA,OAAO,EAAA;AAAA;AAEb;AAIO,SAAS,gBAAA,CACd,eACA,OAAA,EACQ;AACR,EAAA,MAAM,EAAE,IAAA,GAAO,EAAA,EAAI,KAAA,EAAO,cAAA,EAAgB,aAAa,SAAA,EAAW,cAAA,EAAe,GAAI,OAAA,IAAW,EAAC;AACjG,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,aAAA,EAAe,cAAc,CAAA;AAG3D,EAAA,MAAM,SAAA,GAAY,SAAS,MAAA,IAAU,MAAA;AACrC,EAAA,MAAM,IAAA,GAAO,SAAA,KAAc,MAAA,IAAW,SAAA,KAAc,UAAU,IAAA,IAAQ,EAAA;AACtE,EAAA,MAAM,IAAA,GAAO,OAAO,IAAA,IAAQ,KAAA;AAG5B,EAAA,MAAM,UAAA,GAAa,OAAO,UAAA,IAAc,WAAA;AACxC,EAAA,MAAM,SAAA,GAAY,OAAO,SAAA,IAAa,UAAA;AACtC,EAAA,MAAM,UAAA,GAAa,OAAO,UAAA,IAAc,WAAA;AACxC,EAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAY,SAAA;AAEpC,EAAA,MAAM,OAAO,cAAA,EAAgB,IAAA,IAAQ,WAAW,MAAA,CAAO,SAAA,GAAY,WAAW,MAAM,CAAA;AACpF,EAAA,MAAM,SAAS,cAAA,EAAgB,IAAA,IAAQ,UAAU,MAAA,CAAO,QAAA,GAAW,UAAU,MAAM,CAAA;AACnF,EAAA,MAAM,UAAU,cAAA,EAAgB,IAAA,IAAQ,WAAW,MAAA,CAAO,SAAA,GAAY,WAAW,MAAM,CAAA;AACvF,EAAA,MAAM,QAAQ,cAAA,EAAgB,EAAA,IAAM,SAAS,MAAA,CAAO,OAAA,GAAU,SAAS,MAAM,CAAA;AAG7E,EAAA,MAAM,OAAA,GAAU,iBAAiB,IAAI,CAAA;AAErC,EAAA,MAAM,SAAA,GAAY,OAAO,SAAA,IAAa,CAAA;AACtC,EAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAY,CAAA;AACpC,EAAA,MAAM,SAAA,GAAY,cAAA,EAAgB,OAAA,IAAW,KAAA,EAAO,gBAAgB,OAAA,CAAQ,SAAA;AAC5E,EAAA,MAAM,QAAA,GAAW,cAAA,EAAgB,IAAA,IAAQ,KAAA,EAAO,aAAa,OAAA,CAAQ,QAAA;AACrE,EAAA,MAAM,QAAA,GAAW,cAAA,EAAgB,KAAA,IAAS,KAAA,EAAO,cAAc,OAAA,CAAQ,QAAA;AACvE,EAAA,MAAM,QAAA,GAAW,cAAA,EAAgB,SAAA,IAAa,KAAA,EAAO,kBAAkB,OAAA,CAAQ,cAAA;AAC/E,EAAA,MAAM,QAAA,GAAW,cAAA,EAAgB,QAAA,IAAY,KAAA,EAAO,iBAAiB,OAAA,CAAQ,eAAA;AAC7E,EAAA,MAAM,YAAA,GAAe,OAAO,YAAA,IAAgB,SAAA;AAC5C,EAAA,MAAM,eAAe,KAAA,EAAO,YAAA,IAAgB,KAAA,CAAM,IAAA,EAAM,WAAW,GAAG,CAAA;AACtE,EAAA,MAAM,gBAAgB,KAAA,EAAO,aAAA,IAAiB,KAAA,CAAM,OAAA,EAAS,WAAW,GAAG,CAAA;AAG3E,EAAA,MAAM,KAAK,IAAA,GAAOA,KAAAA,CAAK,aAAa,CAAA,CAAE,SAAS,EAAE,CAAA;AAGjD,EAAA,MAAM,YAAA,GAAe,OAAO,YAAA,IAAgB,IAAA;AAC5C,EAAA,MAAM,UAAA,GAAa,KAAA,EAAO,UAAA,IAAc,OAAA,CAAQ,UAAA;AAChD,EAAA,MAAM,YAAA,GAAe,KAAA,EAAO,YAAA,IAAgB,OAAA,CAAQ,YAAA;AAEpD,EAAA,MAAM,EAAA,GAAK,OAAO,SAAA,GAAY,EAAA;AAC9B,EAAA,MAAM,EAAA,GAAK,mBAAmB,MAAM,CAAA;AAEpC,EAAA,MAAM,SAAA,GAAY,SAAA,GAAY,CAAA,QAAA,EAAW,SAAS,CAAA,CAAA,CAAA,GAAM,EAAA;AACxD,EAAA,IAAI,MAAM,CAAA,mEAAA,EAAsE,IAAI,CAAA,UAAA,EAAa,IAAI,IAAI,SAAS,CAAA,CAAA,CAAA;AAGlH,EAAA,MAAM,aAAA,GAAgB,OAAO,aAAA,IAAiB,GAAA;AAC9C,EAAA,GAAA,IAAO,SAAA,CAAU,EAAA,EAAI,IAAA,EAAM,OAAA,CAAQ,QAAQ,OAAA,CAAQ,MAAA,EAAQ,OAAA,EAAS,KAAA,EAAO,UAAA,EAAY,YAAA,EAAc,IAAA,EAAM,IAAA,IAAQ,cAAc,aAAa,CAAA;AAG9I,EAAA,MAAM,YAAA,GAAe,CAAC,CAAC,WAAA;AACvB,EAAA,MAAM,gBAAgB,OAAO,WAAA,KAAgB,QAAA,GAAY,WAAA,CAAY,YAAY,CAAA,GAAK,CAAA;AACtF,EAAA,MAAM,aAAa,OAAO,WAAA,KAAgB,QAAA,GAAY,WAAA,CAAY,SAAS,CAAA,GAAK,CAAA;AAChF,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,MAAM,MAAM,CAAA,GAAA,EAAM,aAAA,CAAc,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA;AAC3C,IAAA,MAAM,QAAA,GAAW,UAAA,GAAa,CAAA,CAAA,EAAI,UAAU,CAAA,CAAA,CAAA,GAAM,EAAA;AAClD,IAAA,GAAA,IAAO,CAAA,kBAAA,EAAqB,GAAG,CAAA,mEAAA,EAAsE,GAAG,mBAAmB,GAAG,CAAA,OAAA,EAAU,aAAa,CAAA,aAAA,EAAgB,QAAQ,CAAA,6CAAA,CAAA;AAAA,EAC/K;AAGA,EAAA,MAAM,MAAA,GAAS,IAAA,GAAO,KAAA,GAAQ,CAAA,KAAA,EAAQ,EAAE,CAAA,GAAA,CAAA;AACxC,EAAA,GAAA,IAAO,CAAA,+CAAA,EAAkD,MAAM,CAAA,WAAA,EAAc,SAAS,SAAS,QAAQ,CAAA,GAAA,CAAA;AAGvG,EAAA,GAAA,IAAO,cAAA,CAAe,EAAA,EAAI,EAAA,EAAI,IAAI,CAAA;AAGlC,EAAA,GAAA,IAAO,UAAA,CAAW,OAAA,CAAQ,OAAA,EAAS,OAAA,CAAQ,SAAS,CAAA;AAGpD,EAAA,MAAM,WAAA,GAAc,OAAO,WAAA,IAAe,CAAA;AAC1C,EAAA,GAAA,IAAO,UAAA,CAAW,EAAA,EAAI,IAAA,EAAM,IAAA,EAAM,WAAW,CAAA;AAG7C,EAAA,MAAM,aAAA,GAAgB,OAAO,aAAA,IAAiB,IAAA;AAC9C,EAAA,IAAI,IAAA,IAAQ,gBAAgB,aAAA,EAAe;AACzC,IAAA,GAAA,IAAO,kBAAA,CAAmB,IAAI,IAAI,CAAA;AAAA,EACpC;AAGA,EAAA,IAAI,OAAO,CAAA,EAAG;AACZ,IAAA,GAAA,IAAO,eAAA,CAAgB,CAAA,EAAG,QAAA,EAAU,YAAA,EAAc,cAAc,aAAa,CAAA;AAAA,EAC/E;AAGA,EAAA,GAAA,IAAO,eAAA,CAAgB,EAAA,EAAI,EAAA,EAAI,OAAA,EAAS,MAAM,IAAI,CAAA;AAGlD,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,MAAM,MAAM,CAAA,GAAA,EAAM,aAAA,CAAc,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA;AAC3C,IAAA,GAAA,IAAO,aAAa,GAAG,CAAA,OAAA,CAAA;AAAA,EACzB;AACA,EAAA,GAAA,IAAO,UAAA,CAAW,OAAO,QAAA,GAAW,CAAA,EAAG,QAAQ,QAAA,EAAU,OAAA,CAAQ,UAAU,IAAI,CAAA;AAC/E,EAAA,IAAI,cAAc,GAAA,IAAO,CAAA,IAAA,CAAA;AAGzB,EAAA,GAAA,IAAO,cAAA,CAAe,MAAA,CAAO,QAAA,GAAW,CAAA,EAAG,SAAS,CAAA;AAGpD,EAAA,GAAA,IAAO,UAAA,CAAW,MAAA,CAAO,IAAA,GAAO,CAAA,EAAG,QAAQ,CAAA;AAG3C,EAAA,GAAA,IAAO,YAAY,MAAA,CAAO,KAAA,GAAQ,CAAA,EAAG,QAAA,EAAU,QAAQ,MAAM,CAAA;AAG7D,EAAA,IAAI,EAAA,KAAO,CAAA,IAAK,EAAA,KAAO,CAAA,EAAG;AACxB,IAAA,GAAA,IAAO,eAAA,CAAgB,EAAA,EAAI,QAAA,EAAU,YAAA,EAAc,cAAc,aAAa,CAAA;AAAA,EAChF;AAGA,EAAA,IAAI,OAAO,MAAA,EAAQ;AACjB,IAAA,GAAA,IAAO,CAAA,6DAAA,EAAgE,MAAM,MAAA,CAAO,KAAK,mBAAmB,KAAA,CAAM,MAAA,CAAO,KAAK,CAAA,MAAA,EAAS,QAAQ,CAAA,GAAA,CAAA;AAAA,EACjJ;AAEA,EAAA,GAAA,IAAO,CAAA,MAAA,CAAA;AACP,EAAA,OAAO,GAAA;AACT;AAEO,SAAS,oBAAA,CACd,eACA,OAAA,EACQ;AACR,EAAA,MAAM,GAAA,GAAM,gBAAA,CAAiB,aAAA,EAAe,OAAO,CAAA;AACnD,EAAA,OAAO,CAAA,iCAAA,EAAoC,kBAAA,CAAmB,GAAG,CAAC,CAAA,CAAA;AACpE;AAEO,SAAS,mBAAA,CACd,eACA,OAAA,EACQ;AACR,EAAA,MAAM,GAAA,GAAM,gBAAA,CAAiB,aAAA,EAAe,OAAO,CAAA;AACnD,EAAA,OAAO,CAAA,0BAAA,EAA6B,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA;AAC/C","file":"chunk-3CE7Q44S.js","sourcesContent":["// ═══════════════════════════════════════════════════\n// SOLFACES v2 — Deterministic avatar trait engine\n// ═══════════════════════════════════════════════════\n\n// ─── Types ────────────────────────────────────────\n\nexport interface SolFaceTraits {\n faceShape: number; // 0-3 (consumed for PRNG ordering, all render as squircle)\n skinColor: number; // 0-9\n eyeStyle: number; // 0-7\n eyeColor: number; // 0-4\n eyebrows: number; // 0-4\n nose: number; // 0-3\n mouth: number; // 0-7\n hairStyle: number; // 0-9\n hairColor: number; // 0-9\n accessory: number; // 0-9\n bgColor: number; // 0-9\n}\n\nexport interface SolFaceTheme {\n // Palette overrides\n skinColors?: string[];\n eyeColors?: string[];\n hairColors?: string[];\n bgColors?: string[];\n\n // Single-color overrides\n mouthColor?: string;\n eyebrowColor?: string;\n accessoryColor?: string;\n eyeWhiteColor?: string;\n noseColor?: string;\n glassesColor?: string;\n earringColor?: string;\n headbandColor?: string;\n\n // Layout\n bgOpacity?: number;\n bgRadius?: number;\n border?: { color: string; width: number };\n\n // Rendering options\n flat?: boolean;\n cheekEnabled?: boolean;\n cheekColor?: string;\n cheekOpacity?: number;\n skinOpacity?: number;\n shadowEnabled?: boolean;\n glowIntensity?: number;\n\n // React-only: pixel art mode\n _pixel?: boolean;\n _pixelDensity?: number;\n _pixelRounded?: boolean;\n _pixelOutline?: boolean;\n _pixelOutlineColor?: string;\n _pixelOutlineWidth?: number;\n _pixelContrast?: number;\n _pixelSaturation?: number;\n _pixelBrightness?: number;\n _pixelScanlines?: boolean;\n _pixelScanlineOpacity?: number;\n _pixelScanlineSpacing?: number;\n _pixelGrid?: boolean;\n _pixelGridOpacity?: number;\n _pixelGridColor?: string;\n _pixelShadow?: boolean;\n _pixelShadowColor?: string;\n _pixelShadowOffset?: number;\n\n // React-only: liquid glass mode\n _glass?: boolean;\n _blurRadius?: number;\n _saturate?: number;\n _tintOpacity?: number;\n _tintColor?: string;\n _borderOpacity?: number;\n _borderWidth?: number;\n _borderColor?: string;\n _specularOpacity?: number;\n _specularColor?: string;\n _specularEnd?: number;\n _lightAngle?: number;\n _rimIntensity?: number;\n _shadow?: string;\n}\n\nexport interface RenderOptions {\n size?: number;\n theme?: SolFaceTheme;\n traitOverrides?: Partial<SolFaceTraits>;\n enableBlink?: boolean | {\n duration?: number;\n delay?: number;\n };\n className?: string;\n detail?: \"full\" | \"simplified\" | \"auto\";\n colorOverrides?: {\n skin?: string;\n eyes?: string;\n hair?: string;\n bg?: string;\n mouth?: string;\n eyebrow?: string;\n accessory?: string;\n nose?: string;\n eyeWhite?: string;\n };\n}\n\n// ─── Color Palettes ──────────────────────────────\n\nexport const SKIN_COLORS = [\n \"#faeae5\", \"#efd6c8\", \"#e4c5aa\", \"#d5b590\", \"#c59e77\",\n \"#b4875f\", \"#9d6d4d\", \"#805742\", \"#654134\", \"#4b2d25\",\n];\n\nexport const EYE_COLORS = [\n \"#382414\", \"#3868A8\", \"#38784C\", \"#808838\", \"#586878\",\n];\n\nexport const HAIR_COLORS = [\n \"#1A1A24\", \"#4C3428\", \"#887058\", \"#D4B868\", \"#A84830\",\n \"#C0C0CC\", \"#484858\", \"#783850\", \"#D8B0A0\", \"#C08048\",\n];\n\nexport const BG_COLORS = [\n \"#b98387\", \"#a9a360\", \"#9eb785\", \"#69ab79\", \"#81bbb0\",\n \"#6499af\", \"#7f8bbd\", \"#8869ab\", \"#b785b3\", \"#ab6984\",\n];\n\n// ─── Hashing (djb2) ─────────────────────────────\n\nfunction djb2(str: string): number {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) + hash + str.charCodeAt(i)) | 0;\n }\n return hash >>> 0;\n}\n\n// ─── PRNG (mulberry32) ──────────────────────────\n\nfunction mulberry32(seed: number): () => number {\n let s = seed | 0;\n return () => {\n s = (s + 0x6d2b79f5) | 0;\n let t = Math.imul(s ^ (s >>> 15), 1 | s);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\n// ─── Trait Generation ───────────────────────────\n\nexport function generateTraits(\n walletAddress: string,\n overrides?: Partial<SolFaceTraits>\n): SolFaceTraits {\n const seed = djb2(walletAddress);\n const rand = mulberry32(seed);\n\n // IMPORTANT: Order must NEVER change — shifts all downstream values.\n // faceShape is consumed for PRNG ordering but unused in rendering (all squircle).\n const traits: SolFaceTraits = {\n faceShape: Math.floor(rand() * 4),\n skinColor: Math.floor(rand() * 10),\n eyeStyle: Math.floor(rand() * 8),\n eyeColor: Math.floor(rand() * 5),\n eyebrows: Math.floor(rand() * 5),\n nose: Math.floor(rand() * 4),\n mouth: Math.floor(rand() * 8),\n hairStyle: Math.floor(rand() * 10),\n hairColor: Math.floor(rand() * 10),\n accessory: Math.floor(rand() * 10),\n bgColor: Math.floor(rand() * 10),\n };\n\n return overrides ? { ...traits, ...overrides } : traits;\n}\n\n// ─── Effective Accessory ────────────────────────\n// Earrings/studs are suppressed on long/bob hair\n\nexport function effectiveAccessory(traits: SolFaceTraits): number {\n const ai = traits.accessory % 10;\n const hi = traits.hairStyle % 10;\n if ((ai === 4 || ai === 7) && (hi === 5 || hi === 6)) return 0;\n return ai;\n}\n\n// ─── Trait Labels ───────────────────────────────\n\nconst FACE_LABELS = [\"Squircle\"];\nconst SKIN_LABELS = [\n \"Porcelain\", \"Ivory\", \"Fair\", \"Light\", \"Sand\",\n \"Golden\", \"Warm\", \"Caramel\", \"Brown\", \"Deep\",\n];\nconst EYE_STYLE_LABELS = [\"Round\", \"Minimal\", \"Almond\", \"Wide\", \"Relaxed\", \"Joyful\", \"Bright\", \"Gentle\"];\nconst EYE_COLOR_LABELS = [\"Chocolate\", \"Sky\", \"Emerald\", \"Hazel\", \"Storm\"];\nconst BROW_LABELS = [\"Wispy\", \"Straight\", \"Natural\", \"Arched\", \"Angled\"];\nconst NOSE_LABELS = [\"Shadow\", \"Button\", \"Soft\", \"Nostrils\"];\nconst MOUTH_LABELS = [\"Smile\", \"Calm\", \"Happy\", \"Oh\", \"Smirk\", \"Grin\", \"Flat\", \"Pout\"];\nconst HAIR_STYLE_LABELS = [\n \"Bald\", \"Short\", \"Curly\", \"Side Sweep\", \"Puff\",\n \"Long\", \"Bob\", \"Buzz\", \"Wavy\", \"Topknot\",\n];\nconst HAIR_COLOR_LABELS = [\n \"Black\", \"Espresso\", \"Walnut\", \"Honey\", \"Copper\",\n \"Silver\", \"Charcoal\", \"Burgundy\", \"Strawberry\", \"Ginger\",\n];\nconst ACCESSORY_LABELS = [\n \"None\", \"Beauty Mark\", \"Round Glasses\", \"Rect Glasses\", \"Earring\",\n \"Headband\", \"Freckles\", \"Stud Earrings\", \"Aviators\", \"Band-Aid\",\n];\nconst BG_COLOR_LABELS = [\n \"Rose\", \"Olive\", \"Sage\", \"Fern\", \"Mint\",\n \"Ocean\", \"Sky\", \"Lavender\", \"Orchid\", \"Blush\",\n];\n\nexport function getTraitLabels(traits: SolFaceTraits): Record<string, string> {\n return {\n faceShape: FACE_LABELS[0],\n skinColor: SKIN_LABELS[traits.skinColor] ?? \"Fair\",\n eyeStyle: EYE_STYLE_LABELS[traits.eyeStyle] ?? \"Round\",\n eyeColor: EYE_COLOR_LABELS[traits.eyeColor] ?? \"Chocolate\",\n eyebrows: BROW_LABELS[traits.eyebrows] ?? \"Wispy\",\n nose: NOSE_LABELS[traits.nose] ?? \"Shadow\",\n mouth: MOUTH_LABELS[traits.mouth] ?? \"Smile\",\n hairStyle: HAIR_STYLE_LABELS[traits.hairStyle] ?? \"Bald\",\n hairColor: HAIR_COLOR_LABELS[traits.hairColor] ?? \"Black\",\n accessory: ACCESSORY_LABELS[effectiveAccessory(traits)] ?? \"None\",\n bgColor: BG_COLOR_LABELS[traits.bgColor] ?? \"Rose\",\n };\n}\n\n// ─── Trait Hash ─────────────────────────────────\n\nexport function traitHash(walletAddress: string): string {\n return (djb2(walletAddress) >>> 0).toString(16).padStart(8, \"0\");\n}\n\n// ─── Theme Utilities ────────────────────────────\n\nexport function resolveTheme(\n themeName?: string,\n themes?: Record<string, SolFaceTheme>\n): SolFaceTheme | undefined {\n if (!themeName || !themes) return undefined;\n return themes[themeName];\n}\n\nexport function mergeTheme(\n base: SolFaceTheme | null | undefined,\n overrides: SolFaceTheme | null | undefined\n): SolFaceTheme | null {\n if (!base) return overrides || null;\n if (!overrides) return base;\n return { ...base, ...overrides };\n}\n","// ═══════════════════════════════════════════════════════════════\n// Color math utilities for SolFaces v2\n// Shared by renderer.ts (string) and SolFace.tsx (React)\n// ═══════════════════════════════════════════════════════════════\n\nexport function hexToRgb(hex: string): [number, number, number] {\n const h = hex.replace(\"#\", \"\");\n return [\n parseInt(h.slice(0, 2), 16),\n parseInt(h.slice(2, 4), 16),\n parseInt(h.slice(4, 6), 16),\n ];\n}\n\nexport function rgbToHex(r: number, g: number, b: number): string {\n return (\n \"#\" +\n [r, g, b]\n .map((v) =>\n Math.max(0, Math.min(255, Math.round(v)))\n .toString(16)\n .padStart(2, \"0\")\n )\n .join(\"\")\n );\n}\n\nexport function darken(hex: string, pct = 0.12): string {\n const [r, g, b] = hexToRgb(hex);\n return rgbToHex(r * (1 - pct), g * (1 - pct), b * (1 - pct));\n}\n\nexport function lighten(hex: string, pct = 0.15): string {\n const [r, g, b] = hexToRgb(hex);\n return rgbToHex(r + (255 - r) * pct, g + (255 - g) * pct, b + (255 - b) * pct);\n}\n\nexport function blend(a: string, b: string, t = 0.5): string {\n const [r1, g1, b1] = hexToRgb(a);\n const [r2, g2, b2] = hexToRgb(b);\n return rgbToHex(\n r1 + (r2 - r1) * t,\n g1 + (g2 - g1) * t,\n b1 + (b2 - b1) * t\n );\n}\n\nexport function luminance(hex: string): number {\n const [r, g, b] = hexToRgb(hex);\n return (r + g + b) / 3;\n}\n\nexport interface DerivedColors {\n skinHi: string;\n skinLo: string;\n skinMid: string;\n isDark: boolean;\n cheekColor: string;\n cheekOpacity: number;\n lipColor: string;\n noseFill: string;\n browColor: string;\n earFill: string;\n earShadow: string;\n eyeWhiteAdapted: string;\n lidColor: string;\n accessoryColor: string;\n}\n\nexport function deriveSkinColors(skin: string): DerivedColors {\n const sL = luminance(skin);\n const isDark = sL < 100;\n\n const skinHi = lighten(skin, 0.10);\n const skinLo = darken(skin, 0.22);\n const skinMid = darken(skin, 0.05);\n\n // Cheek: warm blush relative to skin\n const [sr, sg, sb] = hexToRgb(skin);\n let cheekColor: string;\n if (sL > 120) {\n const rB = sL > 180 ? 0.03 : 0.06;\n const gD = sL > 180 ? 0.30 : 0.28;\n const bD = sL > 180 ? 0.25 : 0.22;\n cheekColor = rgbToHex(\n Math.min(255, sr + sr * rB),\n Math.max(0, sg - sg * gD),\n Math.max(0, sb - sb * bD)\n );\n } else {\n cheekColor = rgbToHex(\n Math.min(255, sr + 50),\n Math.max(0, sg - 10),\n Math.max(0, sb - 5)\n );\n }\n const cheekOpacity = 0.15 + 0.18 * (1 - Math.min(1, sL / 240));\n\n // Lips: smooth skin-relative gradient\n const lipT = Math.max(0, Math.min(1, (sL - 60) / 180));\n const lipBase = blend(\"#D89090\", \"#A83848\", lipT);\n const midBoost = 1 - Math.abs(sL - 140) / 80;\n const lipBlend = (isDark ? 0.70 : 0.62) + Math.max(0, midBoost) * 0.12;\n const lipRaw = blend(skin, lipBase, Math.min(0.82, lipBlend));\n const [lr, lg, lb] = hexToRgb(lipRaw);\n const lipD = Math.abs(sr - lr) + Math.abs(sg - lg) + Math.abs(sb - lb);\n const lipColor = lipD < 60 ? blend(skin, lipBase, 0.78) : lipRaw;\n\n // Features\n const browColor = isDark ? lighten(skin, sL < 80 ? 0.35 : 0.25) : darken(skin, 0.55);\n const noseFill = isDark ? lighten(skin, 0.20) : darken(skin, 0.20);\n const earT = Math.max(0, Math.min(1, (sL - 100) / 60));\n const earFill = blend(lighten(skin, 0.08), skinMid, earT);\n const earShadow = darken(skin, 0.10 + 0.06 * (1 - Math.min(1, sL / 160)));\n const lidColor = isDark ? lighten(skin, 0.18) : darken(skin, 0.15);\n\n // Eye white: adapted to skin luminance\n const ewT = Math.max(0, Math.min(1, (sL - 60) / 180));\n const eyeWhiteAdapted = blend(\"#EDE8E0\", \"#FBF8F2\", ewT);\n\n // Accessory color: skin-warm neutral\n const warmth = sL > 140 ? 0.3 : sL > 100 ? 0.5 : 0.7;\n const accessoryColor = blend(\"#808890\", blend(skin, \"#B0A898\", 0.3), warmth);\n\n return {\n skinHi, skinLo, skinMid, isDark,\n cheekColor, cheekOpacity,\n lipColor, noseFill, browColor,\n earFill, earShadow,\n eyeWhiteAdapted, lidColor,\n accessoryColor,\n };\n}\n\n/** Compute buzz cut opacity — higher when hair/skin contrast is low */\nexport function buzzOpacity(hairCol: string, skin: string): number {\n const [hr, hg, hb] = hexToRgb(hairCol);\n const [sr, sg, sb] = hexToRgb(skin);\n return Math.abs(hr - sr) + Math.abs(hg - sg) + Math.abs(hb - sb) < 80\n ? 0.70\n : 0.50;\n}\n","// ═══════════════════════════════════════════════════════════════\n// SOLFACES v2 — SVG String Renderer\n// Gradient-rich, skin-luminance-driven avatar rendering.\n// Generates SVG markup as strings for server-side and non-React use.\n// ═══════════════════════════════════════════════════════════════\n\nimport {\n generateTraits,\n effectiveAccessory,\n SKIN_COLORS,\n EYE_COLORS,\n HAIR_COLORS,\n BG_COLORS,\n type RenderOptions,\n} from \"./traits\";\nimport { deriveSkinColors, darken, lighten, blend, buzzOpacity } from \"./colors\";\n\nexport type { RenderOptions } from \"./traits\";\n\n// ─── Helpers ────────────────────────────────────\n\nfunction djb2(str: string): number {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) + hash + str.charCodeAt(i)) | 0;\n }\n return hash >>> 0;\n}\n\n// ─── Gradient Defs ──────────────────────────────\n\nfunction buildDefs(\n id: string,\n skin: string,\n skinHi: string,\n skinLo: string,\n hairCol: string,\n bgCol: string,\n cheekColor: string,\n cheekOpacity: number,\n flat: boolean,\n full: boolean,\n glowIntensity: number,\n): string {\n if (flat) return \"\";\n\n let d = \"<defs>\";\n\n // Skin gradient (top → bottom)\n d += `<linearGradient id=\"${id}sg\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">`;\n d += `<stop offset=\"0%\" stop-color=\"${skinHi}\"/>`;\n d += `<stop offset=\"100%\" stop-color=\"${skinLo}\"/>`;\n d += `</linearGradient>`;\n\n // Hair gradient\n d += `<linearGradient id=\"${id}hg\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">`;\n d += `<stop offset=\"0%\" stop-color=\"${lighten(hairCol, 0.15)}\"/>`;\n d += `<stop offset=\"100%\" stop-color=\"${darken(hairCol, 0.15)}\"/>`;\n d += `</linearGradient>`;\n\n // BG gradient\n d += `<linearGradient id=\"${id}bg\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">`;\n d += `<stop offset=\"0%\" stop-color=\"${lighten(bgCol, 0.12)}\"/>`;\n d += `<stop offset=\"100%\" stop-color=\"${darken(bgCol, 0.12)}\"/>`;\n d += `</linearGradient>`;\n\n if (full) {\n // Glow (radial, top center)\n d += `<radialGradient id=\"${id}glow\" cx=\"0.5\" cy=\"0.28\" r=\"0.45\">`;\n d += `<stop offset=\"0%\" stop-color=\"#ffffff\" stop-opacity=\"${glowIntensity}\"/>`;\n d += `<stop offset=\"100%\" stop-color=\"#ffffff\" stop-opacity=\"0\"/>`;\n d += `</radialGradient>`;\n\n // Chin shadow\n d += `<radialGradient id=\"${id}chin\" cx=\"0.5\" cy=\"0.85\" r=\"0.35\">`;\n d += `<stop offset=\"0%\" stop-color=\"${skinLo}\" stop-opacity=\"0.30\"/>`;\n d += `<stop offset=\"100%\" stop-color=\"${skinLo}\" stop-opacity=\"0\"/>`;\n d += `</radialGradient>`;\n\n // Cheek L\n d += `<radialGradient id=\"${id}cL\" cx=\"0.5\" cy=\"0.5\" r=\"0.5\">`;\n d += `<stop offset=\"0%\" stop-color=\"${cheekColor}\" stop-opacity=\"${cheekOpacity.toFixed(2)}\"/>`;\n d += `<stop offset=\"100%\" stop-color=\"${cheekColor}\" stop-opacity=\"0\"/>`;\n d += `</radialGradient>`;\n\n // Cheek R\n d += `<radialGradient id=\"${id}cR\" cx=\"0.5\" cy=\"0.5\" r=\"0.5\">`;\n d += `<stop offset=\"0%\" stop-color=\"${cheekColor}\" stop-opacity=\"${cheekOpacity.toFixed(2)}\"/>`;\n d += `<stop offset=\"100%\" stop-color=\"${cheekColor}\" stop-opacity=\"0\"/>`;\n d += `</radialGradient>`;\n }\n\n d += \"</defs>\";\n return d;\n}\n\n// ─── Hair Back (behind face) ────────────────────\n\nfunction renderHairBack(hi: number, id: string, flat: boolean): string {\n const fill = flat ? \"currentColor\" : `url(#${id}hg)`;\n switch (hi) {\n case 5: // Long\n return `<g fill=\"${fill}\"><rect x=\"10\" y=\"14\" width=\"44\" height=\"42\" rx=\"6\"/></g>`;\n case 6: // Bob\n return `<g fill=\"${fill}\"><rect x=\"12\" y=\"14\" width=\"40\" height=\"32\" rx=\"8\"/></g>`;\n case 8: // Wavy\n return `<g fill=\"${fill}\"><rect x=\"11\" y=\"14\" width=\"42\" height=\"38\" rx=\"8\"/></g>`;\n default:\n return \"\";\n }\n}\n\n// ─── Ears ───────────────────────────────────────\n\nfunction renderEars(earFill: string, earShadow: string): string {\n return (\n `<ellipse cx=\"11\" cy=\"34\" rx=\"4\" ry=\"5\" fill=\"${earFill}\"/>` +\n `<ellipse cx=\"11\" cy=\"34\" rx=\"2.5\" ry=\"3.5\" fill=\"${earShadow}\" opacity=\"0.3\"/>` +\n `<ellipse cx=\"53\" cy=\"34\" rx=\"4\" ry=\"5\" fill=\"${earFill}\"/>` +\n `<ellipse cx=\"53\" cy=\"34\" rx=\"2.5\" ry=\"3.5\" fill=\"${earShadow}\" opacity=\"0.3\"/>`\n );\n}\n\n// ─── Face ───────────────────────────────────────\n\nfunction renderFace(id: string, skin: string, flat: boolean, opacity: number = 1): string {\n const fill = flat ? skin : `url(#${id}sg)`;\n const opAttr = opacity < 1 ? ` opacity=\"${opacity}\"` : \"\";\n return `<rect x=\"14\" y=\"16\" width=\"36\" height=\"38\" rx=\"12\" ry=\"12\" fill=\"${fill}\"${opAttr}/>`;\n}\n\n// ─── Face Overlays (full detail) ────────────────\n\nfunction renderFaceOverlays(id: string, flat: boolean): string {\n if (flat) return \"\";\n return (\n `<rect x=\"14\" y=\"16\" width=\"36\" height=\"38\" rx=\"12\" ry=\"12\" fill=\"url(#${id}glow)\"/>` +\n `<rect x=\"14\" y=\"16\" width=\"36\" height=\"38\" rx=\"12\" ry=\"12\" fill=\"url(#${id}chin)\"/>` +\n `<ellipse cx=\"22\" cy=\"42\" rx=\"5\" ry=\"3.5\" fill=\"url(#${id}cL)\"/>` +\n `<ellipse cx=\"42\" cy=\"42\" rx=\"5\" ry=\"3.5\" fill=\"url(#${id}cR)\"/>` +\n `<line x1=\"20\" y1=\"50\" x2=\"44\" y2=\"50\" stroke=\"currentColor\" stroke-width=\"0.3\" opacity=\"0.08\" stroke-linecap=\"round\"/>`\n );\n}\n\n// ─── Hair Front ─────────────────────────────────\n\nfunction renderHairFront(hi: number, id: string, hairCol: string, skin: string, flat: boolean): string {\n const fill = flat ? hairCol : `url(#${id}hg)`;\n switch (hi) {\n case 0: return \"\"; // Bald\n case 1: // Short\n return `<path d=\"M14 28 Q14 14 32 12 Q50 14 50 28 L50 22 Q50 12 32 10 Q14 12 14 22 Z\" fill=\"${fill}\"/>`;\n case 2: // Curly\n return (\n `<g fill=\"${fill}\">` +\n `<circle cx=\"20\" cy=\"14\" r=\"5\"/>` +\n `<circle cx=\"28\" cy=\"11\" r=\"5.5\"/>` +\n `<circle cx=\"36\" cy=\"11\" r=\"5.5\"/>` +\n `<circle cx=\"44\" cy=\"14\" r=\"5\"/>` +\n `<circle cx=\"16\" cy=\"20\" r=\"4\"/>` +\n `<circle cx=\"48\" cy=\"20\" r=\"4\"/>` +\n `</g>`\n );\n case 3: // Side sweep\n return (\n `<path d=\"M14 26 Q14 12 32 10 Q50 12 50 26 L50 20 Q50 10 32 8 Q14 10 14 20 Z\" fill=\"${fill}\"/>` +\n `<path d=\"M14 20 Q8 16 10 8 Q14 10 20 16 Z\" fill=\"${fill}\"/>`\n );\n case 4: // Puff\n return `<ellipse cx=\"32\" cy=\"10\" rx=\"14\" ry=\"8\" fill=\"${fill}\"/>`;\n case 5: // Long\n return `<path d=\"M14 28 Q14 12 32 10 Q50 12 50 28 L50 20 Q50 10 32 8 Q14 10 14 20 Z\" fill=\"${fill}\"/>`;\n case 6: // Bob\n return (\n `<path d=\"M14 28 Q14 12 32 10 Q50 12 50 28 L50 20 Q50 10 32 8 Q14 10 14 20 Z\" fill=\"${fill}\"/>` +\n `<rect x=\"10\" y=\"28\" width=\"8\" height=\"14\" rx=\"4\" fill=\"${fill}\"/>` +\n `<rect x=\"46\" y=\"28\" width=\"8\" height=\"14\" rx=\"4\" fill=\"${fill}\"/>`\n );\n case 7: { // Buzz\n const bOp = buzzOpacity(hairCol, skin);\n return `<rect x=\"15\" y=\"13\" width=\"34\" height=\"16\" rx=\"10\" ry=\"8\" fill=\"${hairCol}\" opacity=\"${bOp.toFixed(2)}\"/>`;\n }\n case 8: // Wavy\n return (\n `<path d=\"M14 28 Q14 12 32 10 Q50 12 50 28 L50 20 Q50 10 32 8 Q14 10 14 20 Z\" fill=\"${fill}\"/>` +\n `<path d=\"M12 30 Q10 20 14 16\" fill=\"none\" stroke=\"${fill}\" stroke-width=\"4\" stroke-linecap=\"round\"/>` +\n `<path d=\"M52 30 Q54 20 50 16\" fill=\"none\" stroke=\"${fill}\" stroke-width=\"4\" stroke-linecap=\"round\"/>`\n );\n case 9: // Topknot\n return (\n `<path d=\"M14 28 Q14 14 32 12 Q50 14 50 28 L50 22 Q50 12 32 10 Q14 12 14 22 Z\" fill=\"${fill}\"/>` +\n `<ellipse cx=\"32\" cy=\"6\" rx=\"6\" ry=\"5\" fill=\"${fill}\"/>`\n );\n default: return \"\";\n }\n}\n\n// ─── Eyes ───────────────────────────────────────\n\nfunction renderEyes(\n ei: number,\n eyeCol: string,\n eyeWhite: string,\n lidColor: string,\n full: boolean,\n): string {\n const lx = 25, rx = 39, y = 33;\n let s = \"\";\n\n switch (ei) {\n case 0: // Round\n s += `<circle cx=\"${lx}\" cy=\"${y}\" r=\"4\" fill=\"${eyeWhite}\"/>`;\n s += `<circle cx=\"${lx + 0.8}\" cy=\"${y}\" r=\"2.2\" fill=\"${eyeCol}\"/>`;\n if (full) s += `<circle cx=\"${lx + 1.5}\" cy=\"${y - 1}\" r=\"0.7\" fill=\"white\" opacity=\"0.8\"/>`;\n s += `<circle cx=\"${rx}\" cy=\"${y}\" r=\"4\" fill=\"${eyeWhite}\"/>`;\n s += `<circle cx=\"${rx + 0.8}\" cy=\"${y}\" r=\"2.2\" fill=\"${eyeCol}\"/>`;\n if (full) s += `<circle cx=\"${rx + 1.5}\" cy=\"${y - 1}\" r=\"0.7\" fill=\"white\" opacity=\"0.8\"/>`;\n break;\n case 1: // Minimal\n s += `<circle cx=\"${lx}\" cy=\"${y}\" r=\"2\" fill=\"${eyeCol}\"/>`;\n s += `<circle cx=\"${rx}\" cy=\"${y}\" r=\"2\" fill=\"${eyeCol}\"/>`;\n break;\n case 2: // Almond\n s += `<ellipse cx=\"${lx}\" cy=\"${y}\" rx=\"4.5\" ry=\"2.8\" fill=\"${eyeWhite}\"/>`;\n s += `<circle cx=\"${lx + 0.5}\" cy=\"${y}\" r=\"1.8\" fill=\"${eyeCol}\"/>`;\n if (full) s += `<circle cx=\"${lx + 1.2}\" cy=\"${y - 0.8}\" r=\"0.6\" fill=\"white\" opacity=\"0.7\"/>`;\n s += `<ellipse cx=\"${rx}\" cy=\"${y}\" rx=\"4.5\" ry=\"2.8\" fill=\"${eyeWhite}\"/>`;\n s += `<circle cx=\"${rx + 0.5}\" cy=\"${y}\" r=\"1.8\" fill=\"${eyeCol}\"/>`;\n if (full) s += `<circle cx=\"${rx + 1.2}\" cy=\"${y - 0.8}\" r=\"0.6\" fill=\"white\" opacity=\"0.7\"/>`;\n break;\n case 3: // Wide\n s += `<circle cx=\"${lx}\" cy=\"${y}\" r=\"5\" fill=\"${eyeWhite}\"/>`;\n s += `<circle cx=\"${lx}\" cy=\"${y + 0.5}\" r=\"2.8\" fill=\"${eyeCol}\"/>`;\n if (full) s += `<circle cx=\"${lx + 1.5}\" cy=\"${y - 1}\" r=\"0.8\" fill=\"white\" opacity=\"0.8\"/>`;\n s += `<circle cx=\"${rx}\" cy=\"${y}\" r=\"5\" fill=\"${eyeWhite}\"/>`;\n s += `<circle cx=\"${rx}\" cy=\"${y + 0.5}\" r=\"2.8\" fill=\"${eyeCol}\"/>`;\n if (full) s += `<circle cx=\"${rx + 1.5}\" cy=\"${y - 1}\" r=\"0.8\" fill=\"white\" opacity=\"0.8\"/>`;\n break;\n case 4: // Relaxed\n s += `<ellipse cx=\"${lx}\" cy=\"${y + 1}\" rx=\"4\" ry=\"2.2\" fill=\"${eyeWhite}\"/>`;\n s += `<circle cx=\"${lx}\" cy=\"${y + 1}\" r=\"1.5\" fill=\"${eyeCol}\"/>`;\n if (full) s += `<line x1=\"${lx - 4.5}\" y1=\"${y - 0.5}\" x2=\"${lx + 4.5}\" y2=\"${y - 0.5}\" stroke=\"${lidColor}\" stroke-width=\"0.8\" stroke-linecap=\"round\"/>`;\n s += `<ellipse cx=\"${rx}\" cy=\"${y + 1}\" rx=\"4\" ry=\"2.2\" fill=\"${eyeWhite}\"/>`;\n s += `<circle cx=\"${rx}\" cy=\"${y + 1}\" r=\"1.5\" fill=\"${eyeCol}\"/>`;\n if (full) s += `<line x1=\"${rx - 4.5}\" y1=\"${y - 0.5}\" x2=\"${rx + 4.5}\" y2=\"${y - 0.5}\" stroke=\"${lidColor}\" stroke-width=\"0.8\" stroke-linecap=\"round\"/>`;\n break;\n case 5: // Joyful\n s += `<path d=\"M${lx - 4} ${y} Q${lx} ${y + 4} ${lx + 4} ${y}\" fill=\"none\" stroke=\"${eyeCol}\" stroke-width=\"1.8\" stroke-linecap=\"round\"/>`;\n s += `<path d=\"M${rx - 4} ${y} Q${rx} ${y + 4} ${rx + 4} ${y}\" fill=\"none\" stroke=\"${eyeCol}\" stroke-width=\"1.8\" stroke-linecap=\"round\"/>`;\n break;\n case 6: // Bright\n s += `<circle cx=\"${lx}\" cy=\"${y}\" r=\"3.5\" fill=\"${eyeWhite}\"/>`;\n s += `<circle cx=\"${lx + 0.5}\" cy=\"${y}\" r=\"2\" fill=\"${eyeCol}\"/>`;\n s += `<circle cx=\"${lx + 1.5}\" cy=\"${y - 1}\" r=\"1\" fill=\"white\" opacity=\"0.9\"/>`;\n if (full) {\n s += `<line x1=\"${lx + 2.5}\" y1=\"${y - 3.5}\" x2=\"${lx + 4}\" y2=\"${y - 5}\" stroke=\"${eyeCol}\" stroke-width=\"0.8\" stroke-linecap=\"round\"/>`;\n s += `<line x1=\"${lx + 3.5}\" y1=\"${y - 2.5}\" x2=\"${lx + 5}\" y2=\"${y - 3.5}\" stroke=\"${eyeCol}\" stroke-width=\"0.8\" stroke-linecap=\"round\"/>`;\n }\n s += `<circle cx=\"${rx}\" cy=\"${y}\" r=\"3.5\" fill=\"${eyeWhite}\"/>`;\n s += `<circle cx=\"${rx + 0.5}\" cy=\"${y}\" r=\"2\" fill=\"${eyeCol}\"/>`;\n s += `<circle cx=\"${rx + 1.5}\" cy=\"${y - 1}\" r=\"1\" fill=\"white\" opacity=\"0.9\"/>`;\n if (full) {\n s += `<line x1=\"${rx + 2.5}\" y1=\"${y - 3.5}\" x2=\"${rx + 4}\" y2=\"${y - 5}\" stroke=\"${eyeCol}\" stroke-width=\"0.8\" stroke-linecap=\"round\"/>`;\n s += `<line x1=\"${rx + 3.5}\" y1=\"${y - 2.5}\" x2=\"${rx + 5}\" y2=\"${y - 3.5}\" stroke=\"${eyeCol}\" stroke-width=\"0.8\" stroke-linecap=\"round\"/>`;\n }\n break;\n case 7: // Gentle\n s += `<ellipse cx=\"${lx}\" cy=\"${y}\" rx=\"4.5\" ry=\"1.5\" fill=\"${eyeWhite}\"/>`;\n s += `<ellipse cx=\"${lx + 0.5}\" cy=\"${y}\" rx=\"2.2\" ry=\"1.2\" fill=\"${eyeCol}\"/>`;\n s += `<ellipse cx=\"${rx}\" cy=\"${y}\" rx=\"4.5\" ry=\"1.5\" fill=\"${eyeWhite}\"/>`;\n s += `<ellipse cx=\"${rx + 0.5}\" cy=\"${y}\" rx=\"2.2\" ry=\"1.2\" fill=\"${eyeCol}\"/>`;\n break;\n default:\n s += `<circle cx=\"${lx}\" cy=\"${y}\" r=\"3.5\" fill=\"${eyeWhite}\"/>`;\n s += `<circle cx=\"${lx + 0.8}\" cy=\"${y}\" r=\"2\" fill=\"${eyeCol}\"/>`;\n s += `<circle cx=\"${rx}\" cy=\"${y}\" r=\"3.5\" fill=\"${eyeWhite}\"/>`;\n s += `<circle cx=\"${rx + 0.8}\" cy=\"${y}\" r=\"2\" fill=\"${eyeCol}\"/>`;\n }\n\n // Eyelid strokes in full detail (except joyful/minimal)\n if (full && ei !== 1 && ei !== 5) {\n s += `<path d=\"M${lx - 4} ${y - 1.5} Q${lx} ${y - 4} ${lx + 4} ${y - 1.5}\" fill=\"none\" stroke=\"${lidColor}\" stroke-width=\"0.5\" opacity=\"0.4\"/>`;\n s += `<path d=\"M${rx - 4} ${y - 1.5} Q${rx} ${y - 4} ${rx + 4} ${y - 1.5}\" fill=\"none\" stroke=\"${lidColor}\" stroke-width=\"0.5\" opacity=\"0.4\"/>`;\n }\n\n return s;\n}\n\n// ─── Eyebrows ───────────────────────────────────\n\nfunction renderEyebrows(bi: number, browColor: string): string {\n const lx = 25, rx = 39, y = 27;\n switch (bi) {\n case 0: // Wispy\n return (\n `<line x1=\"${lx - 3}\" y1=\"${y}\" x2=\"${lx + 3}\" y2=\"${y - 0.5}\" stroke=\"${browColor}\" stroke-width=\"0.7\" stroke-linecap=\"round\"/>` +\n `<line x1=\"${rx - 3}\" y1=\"${y - 0.5}\" x2=\"${rx + 3}\" y2=\"${y}\" stroke=\"${browColor}\" stroke-width=\"0.7\" stroke-linecap=\"round\"/>`\n );\n case 1: // Straight\n return (\n `<line x1=\"${lx - 3.5}\" y1=\"${y}\" x2=\"${lx + 3.5}\" y2=\"${y}\" stroke=\"${browColor}\" stroke-width=\"1.2\" stroke-linecap=\"round\"/>` +\n `<line x1=\"${rx - 3.5}\" y1=\"${y}\" x2=\"${rx + 3.5}\" y2=\"${y}\" stroke=\"${browColor}\" stroke-width=\"1.2\" stroke-linecap=\"round\"/>`\n );\n case 2: // Natural\n return (\n `<path d=\"M${lx - 3.5} ${y + 0.5} Q${lx} ${y - 1.5} ${lx + 3.5} ${y + 0.5}\" fill=\"none\" stroke=\"${browColor}\" stroke-width=\"1.2\" stroke-linecap=\"round\"/>` +\n `<path d=\"M${rx - 3.5} ${y + 0.5} Q${rx} ${y - 1.5} ${rx + 3.5} ${y + 0.5}\" fill=\"none\" stroke=\"${browColor}\" stroke-width=\"1.2\" stroke-linecap=\"round\"/>`\n );\n case 3: // Arched\n return (\n `<path d=\"M${lx - 4} ${y + 1} Q${lx} ${y - 3} ${lx + 4} ${y + 1}\" fill=\"none\" stroke=\"${browColor}\" stroke-width=\"1\" stroke-linecap=\"round\"/>` +\n `<path d=\"M${rx - 4} ${y + 1} Q${rx} ${y - 3} ${rx + 4} ${y + 1}\" fill=\"none\" stroke=\"${browColor}\" stroke-width=\"1\" stroke-linecap=\"round\"/>`\n );\n case 4: // Angled\n return (\n `<polyline points=\"${lx - 3},${y + 1} ${lx},${y - 2} ${lx + 3},${y}\" fill=\"none\" stroke=\"${browColor}\" stroke-width=\"1.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>` +\n `<polyline points=\"${rx - 3},${y} ${rx},${y - 2} ${rx + 3},${y + 1}\" fill=\"none\" stroke=\"${browColor}\" stroke-width=\"1.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`\n );\n default:\n return \"\";\n }\n}\n\n// ─── Nose ───────────────────────────────────────\n\nfunction renderNose(ni: number, noseFill: string): string {\n const cx = 32, y = 39;\n switch (ni) {\n case 0: // Shadow\n return `<ellipse cx=\"${cx}\" cy=\"${y}\" rx=\"2\" ry=\"1.2\" fill=\"${noseFill}\" opacity=\"0.35\"/>`;\n case 1: // Button\n return `<circle cx=\"${cx}\" cy=\"${y}\" r=\"1.8\" fill=\"${noseFill}\" opacity=\"0.5\"/>`;\n case 2: // Soft\n return `<path d=\"M${cx - 2} ${y + 1} Q${cx} ${y - 2} ${cx + 2} ${y + 1}\" fill=\"none\" stroke=\"${noseFill}\" stroke-width=\"1\" stroke-linecap=\"round\" opacity=\"0.5\"/>`;\n case 3: // Nostrils\n return (\n `<circle cx=\"${cx - 1.8}\" cy=\"${y}\" r=\"1.2\" fill=\"${noseFill}\" opacity=\"0.4\"/>` +\n `<circle cx=\"${cx + 1.8}\" cy=\"${y}\" r=\"1.2\" fill=\"${noseFill}\" opacity=\"0.4\"/>`\n );\n default:\n return `<ellipse cx=\"${cx}\" cy=\"${y}\" rx=\"2\" ry=\"1.2\" fill=\"${noseFill}\" opacity=\"0.35\"/>`;\n }\n}\n\n// ─── Mouth ──────────────────────────────────────\n\nfunction renderMouth(mi: number, lipColor: string, isDark: boolean): string {\n const cx = 32, y = 45;\n const teethCol = isDark ? \"#e8e0d8\" : \"#ffffff\";\n switch (mi) {\n case 0: // Smile\n return `<path d=\"M${cx - 4} ${y} Q${cx} ${y + 4} ${cx + 4} ${y}\" fill=\"none\" stroke=\"${lipColor}\" stroke-width=\"1.4\" stroke-linecap=\"round\"/>`;\n case 1: // Calm\n return `<line x1=\"${cx - 3}\" y1=\"${y + 1}\" x2=\"${cx + 3}\" y2=\"${y + 1}\" stroke=\"${lipColor}\" stroke-width=\"1.2\" stroke-linecap=\"round\"/>`;\n case 2: // Happy\n return `<path d=\"M${cx - 5} ${y} Q${cx} ${y + 5} ${cx + 5} ${y}\" fill=\"none\" stroke=\"${lipColor}\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>`;\n case 3: // Oh\n return `<ellipse cx=\"${cx}\" cy=\"${y + 1}\" rx=\"2.5\" ry=\"3\" fill=\"${lipColor}\" opacity=\"0.7\"/>`;\n case 4: // Smirk\n return `<path d=\"M${cx - 4} ${y + 1} Q${cx + 1} ${y + 1} ${cx + 4} ${y - 1.5}\" fill=\"none\" stroke=\"${lipColor}\" stroke-width=\"1.3\" stroke-linecap=\"round\"/>`;\n case 5: // Grin\n return (\n `<path d=\"M${cx - 5} ${y} Q${cx} ${y + 6} ${cx + 5} ${y}\" fill=\"${teethCol}\" stroke=\"${lipColor}\" stroke-width=\"1\"/>` +\n `<line x1=\"${cx - 4}\" y1=\"${y + 1.5}\" x2=\"${cx + 4}\" y2=\"${y + 1.5}\" stroke=\"${lipColor}\" stroke-width=\"0.3\" opacity=\"0.3\"/>`\n );\n case 6: // Flat\n return `<line x1=\"${cx - 4}\" y1=\"${y + 1}\" x2=\"${cx + 4}\" y2=\"${y + 1}\" stroke=\"${lipColor}\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>`;\n case 7: // Pout\n return (\n `<ellipse cx=\"${cx}\" cy=\"${y + 1}\" rx=\"3.5\" ry=\"2\" fill=\"${lipColor}\" opacity=\"0.25\"/>` +\n `<path d=\"M${cx - 3} ${y} Q${cx} ${y + 2.5} ${cx + 3} ${y}\" fill=\"none\" stroke=\"${lipColor}\" stroke-width=\"1.2\" stroke-linecap=\"round\"/>`\n );\n default:\n return `<path d=\"M${cx - 4} ${y} Q${cx} ${y + 4} ${cx + 4} ${y}\" fill=\"none\" stroke=\"${lipColor}\" stroke-width=\"1.4\" stroke-linecap=\"round\"/>`;\n }\n}\n\n// ─── Accessories ────────────────────────────────\n\nfunction renderAccessory(\n ai: number,\n accessoryColor: string,\n glassesColor: string,\n earringColor: string,\n headbandColor: string,\n): string {\n switch (ai) {\n case 0: return \"\"; // None\n case 1: // Beauty mark\n return `<circle cx=\"40\" cy=\"44\" r=\"0.8\" fill=\"#3a2a2a\"/>`;\n case 2: // Round glasses\n return (\n `<g fill=\"none\" stroke=\"${glassesColor}\" stroke-width=\"1\">` +\n `<circle cx=\"25\" cy=\"33\" r=\"5.5\"/>` +\n `<circle cx=\"39\" cy=\"33\" r=\"5.5\"/>` +\n `<line x1=\"30.5\" y1=\"33\" x2=\"33.5\" y2=\"33\"/>` +\n `<line x1=\"19.5\" y1=\"33\" x2=\"14\" y2=\"31\"/>` +\n `<line x1=\"44.5\" y1=\"33\" x2=\"50\" y2=\"31\"/>` +\n `</g>`\n );\n case 3: // Rect glasses\n return (\n `<g fill=\"none\" stroke=\"${glassesColor}\" stroke-width=\"1\">` +\n `<rect x=\"19\" y=\"29\" width=\"12\" height=\"8\" rx=\"1.5\"/>` +\n `<rect x=\"33\" y=\"29\" width=\"12\" height=\"8\" rx=\"1.5\"/>` +\n `<line x1=\"31\" y1=\"33\" x2=\"33\" y2=\"33\"/>` +\n `<line x1=\"19\" y1=\"33\" x2=\"14\" y2=\"31\"/>` +\n `<line x1=\"45\" y1=\"33\" x2=\"50\" y2=\"31\"/>` +\n `</g>`\n );\n case 4: // Earring\n return (\n `<circle cx=\"10\" cy=\"38\" r=\"1.5\" fill=\"${earringColor}\"/>` +\n `<circle cx=\"10\" cy=\"41\" r=\"2\" fill=\"${earringColor}\" opacity=\"0.8\"/>`\n );\n case 5: // Headband\n return `<rect x=\"13\" y=\"20\" width=\"38\" height=\"3.5\" rx=\"1.5\" fill=\"${headbandColor}\" opacity=\"0.85\"/>`;\n case 6: // Freckles\n return (\n `<g fill=\"#a0785a\" opacity=\"0.35\">` +\n `<circle cx=\"21\" cy=\"40\" r=\"0.6\"/>` +\n `<circle cx=\"23\" cy=\"42\" r=\"0.5\"/>` +\n `<circle cx=\"19\" cy=\"41.5\" r=\"0.5\"/>` +\n `<circle cx=\"43\" cy=\"40\" r=\"0.6\"/>` +\n `<circle cx=\"41\" cy=\"42\" r=\"0.5\"/>` +\n `<circle cx=\"45\" cy=\"41.5\" r=\"0.5\"/>` +\n `</g>`\n );\n case 7: // Stud earrings\n return (\n `<circle cx=\"10\" cy=\"37\" r=\"1.2\" fill=\"${earringColor}\"/>` +\n `<circle cx=\"54\" cy=\"37\" r=\"1.2\" fill=\"${earringColor}\"/>`\n );\n case 8: // Aviators\n return (\n `<g fill=\"none\" stroke=\"${glassesColor}\" stroke-width=\"1.2\">` +\n `<path d=\"M19 30 Q19 28 25 28 Q31 28 31 33 Q31 38 25 38 Q19 38 19 33 Z\" fill=\"${glassesColor}\" fill-opacity=\"0.15\"/>` +\n `<path d=\"M33 30 Q33 28 39 28 Q45 28 45 33 Q45 38 39 38 Q33 38 33 33 Z\" fill=\"${glassesColor}\" fill-opacity=\"0.15\"/>` +\n `<line x1=\"31\" y1=\"32\" x2=\"33\" y2=\"32\"/>` +\n `<line x1=\"19\" y1=\"31\" x2=\"14\" y2=\"29\"/>` +\n `<line x1=\"45\" y1=\"31\" x2=\"50\" y2=\"29\"/>` +\n `</g>`\n );\n case 9: // Band-Aid\n return (\n `<g>` +\n `<rect x=\"38\" y=\"38\" width=\"8\" height=\"4\" rx=\"1\" fill=\"#f0d0a0\" transform=\"rotate(-15 42 40)\"/>` +\n `<line x1=\"40\" y1=\"39\" x2=\"40\" y2=\"41\" stroke=\"#c0a080\" stroke-width=\"0.4\" transform=\"rotate(-15 42 40)\"/>` +\n `<line x1=\"42\" y1=\"39\" x2=\"42\" y2=\"41\" stroke=\"#c0a080\" stroke-width=\"0.4\" transform=\"rotate(-15 42 40)\"/>` +\n `<line x1=\"44\" y1=\"39\" x2=\"44\" y2=\"41\" stroke=\"#c0a080\" stroke-width=\"0.4\" transform=\"rotate(-15 42 40)\"/>` +\n `</g>`\n );\n default:\n return \"\";\n }\n}\n\n// ─── Main Render Functions ──────────────────────\n\nexport function renderSolFaceSVG(\n walletAddress: string,\n options?: RenderOptions,\n): string {\n const { size = 64, theme, traitOverrides, enableBlink, className, colorOverrides } = options ?? {};\n const traits = generateTraits(walletAddress, traitOverrides);\n\n // Resolve detail level\n const detailOpt = options?.detail ?? \"auto\";\n const full = detailOpt === \"full\" || (detailOpt === \"auto\" && size >= 48);\n const flat = theme?.flat ?? false;\n\n // Color palettes\n const skinColors = theme?.skinColors ?? SKIN_COLORS;\n const eyeColors = theme?.eyeColors ?? EYE_COLORS;\n const hairColors = theme?.hairColors ?? HAIR_COLORS;\n const bgColors = theme?.bgColors ?? BG_COLORS;\n\n const skin = colorOverrides?.skin ?? skinColors[traits.skinColor % skinColors.length];\n const eyeCol = colorOverrides?.eyes ?? eyeColors[traits.eyeColor % eyeColors.length];\n const hairCol = colorOverrides?.hair ?? hairColors[traits.hairColor % hairColors.length];\n const bgCol = colorOverrides?.bg ?? bgColors[traits.bgColor % bgColors.length];\n\n // Derived skin colors\n const derived = deriveSkinColors(skin);\n\n const bgOpacity = theme?.bgOpacity ?? 1;\n const bgRadius = theme?.bgRadius ?? 4;\n const browColor = colorOverrides?.eyebrow ?? theme?.eyebrowColor ?? derived.browColor;\n const noseFill = colorOverrides?.nose ?? theme?.noseColor ?? derived.noseFill;\n const lipColor = colorOverrides?.mouth ?? theme?.mouthColor ?? derived.lipColor;\n const accColor = colorOverrides?.accessory ?? theme?.accessoryColor ?? derived.accessoryColor;\n const eyeWhite = colorOverrides?.eyeWhite ?? theme?.eyeWhiteColor ?? derived.eyeWhiteAdapted;\n const glassesColor = theme?.glassesColor ?? \"#4a4a5a\";\n const earringColor = theme?.earringColor ?? blend(skin, \"#d4a840\", 0.4);\n const headbandColor = theme?.headbandColor ?? blend(hairCol, \"#c04040\", 0.5);\n\n // Unique gradient ID prefix (collision-resistant)\n const id = \"sf\" + djb2(walletAddress).toString(36);\n\n // Cheek\n const cheekEnabled = theme?.cheekEnabled ?? true;\n const cheekColor = theme?.cheekColor ?? derived.cheekColor;\n const cheekOpacity = theme?.cheekOpacity ?? derived.cheekOpacity;\n\n const hi = traits.hairStyle % 10;\n const ai = effectiveAccessory(traits);\n\n const classAttr = className ? ` class=\"${className}\"` : \"\";\n let svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\" width=\"${size}\" height=\"${size}\"${classAttr}>`;\n\n // Defs\n const glowIntensity = theme?.glowIntensity ?? 0.10;\n svg += buildDefs(id, skin, derived.skinHi, derived.skinLo, hairCol, bgCol, cheekColor, cheekOpacity, flat, full && cheekEnabled, glowIntensity);\n\n // Blink animation\n const blinkEnabled = !!enableBlink;\n const blinkDuration = typeof enableBlink === \"object\" ? (enableBlink.duration ?? 4) : 4;\n const blinkDelay = typeof enableBlink === \"object\" ? (enableBlink.delay ?? 0) : 0;\n if (blinkEnabled) {\n const uid = `sf-${walletAddress.slice(0, 8)}`;\n const delayStr = blinkDelay ? ` ${blinkDelay}s` : \"\";\n svg += `<style>@keyframes ${uid}-blink{0%,90%,100%{transform:scaleY(1)}95%{transform:scaleY(0.1)}}.${uid}-eyes{animation:${uid}-blink ${blinkDuration}s ease-in-out${delayStr} infinite;transform-origin:32px 33px}</style>`;\n }\n\n // Background\n const bgFill = flat ? bgCol : `url(#${id}bg)`;\n svg += `<rect x=\"0\" y=\"0\" width=\"64\" height=\"64\" fill=\"${bgFill}\" opacity=\"${bgOpacity}\" rx=\"${bgRadius}\"/>`;\n\n // Hair back (Long, Bob, Wavy — behind face)\n svg += renderHairBack(hi, id, flat);\n\n // Ears\n svg += renderEars(derived.earFill, derived.earShadow);\n\n // Face\n const skinOpacity = theme?.skinOpacity ?? 1;\n svg += renderFace(id, skin, flat, skinOpacity);\n\n // Face overlays (glow, chin shadow, cheeks, jawline) — full detail only\n const shadowEnabled = theme?.shadowEnabled ?? true;\n if (full && cheekEnabled && shadowEnabled) {\n svg += renderFaceOverlays(id, flat);\n }\n\n // Headband (renders before eyes, after face)\n if (ai === 5) {\n svg += renderAccessory(5, accColor, glassesColor, earringColor, headbandColor);\n }\n\n // Hair front\n svg += renderHairFront(hi, id, hairCol, skin, flat);\n\n // Eyes\n if (blinkEnabled) {\n const uid = `sf-${walletAddress.slice(0, 8)}`;\n svg += `<g class=\"${uid}-eyes\">`;\n }\n svg += renderEyes(traits.eyeStyle % 8, eyeCol, eyeWhite, derived.lidColor, full);\n if (blinkEnabled) svg += `</g>`;\n\n // Eyebrows\n svg += renderEyebrows(traits.eyebrows % 5, browColor);\n\n // Nose\n svg += renderNose(traits.nose % 4, noseFill);\n\n // Mouth\n svg += renderMouth(traits.mouth % 8, lipColor, derived.isDark);\n\n // Accessories (except headband, already rendered)\n if (ai !== 0 && ai !== 5) {\n svg += renderAccessory(ai, accColor, glassesColor, earringColor, headbandColor);\n }\n\n // Border\n if (theme?.border) {\n svg += `<rect x=\"0\" y=\"0\" width=\"64\" height=\"64\" fill=\"none\" stroke=\"${theme.border.color}\" stroke-width=\"${theme.border.width}\" rx=\"${bgRadius}\"/>`;\n }\n\n svg += `</svg>`;\n return svg;\n}\n\nexport function renderSolFaceDataURI(\n walletAddress: string,\n options?: RenderOptions,\n): string {\n const svg = renderSolFaceSVG(walletAddress, options);\n return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;\n}\n\nexport function renderSolFaceBase64(\n walletAddress: string,\n options?: RenderOptions,\n): string {\n const svg = renderSolFaceSVG(walletAddress, options);\n return `data:image/svg+xml;base64,${btoa(svg)}`;\n}\n"]}